Commit 5a7a7a12bde268c104610d3e81a08df06ccab5eb
Merge branch 'wvp-28181-2.0' into main-dev
# Conflicts: # src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java # src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java # src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java # src/main/java/com/genersoft/iot/vmp/service/IPlayService.java # src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java # src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java # src/main/resources/all-application.yml # web_src/config/index.js # web_src/src/components/dialog/devicePlayer.vue
Showing
95 changed files
with
2211 additions
and
1154 deletions
Too many changes to show.
To preserve performance only 95 of 162 files are displayed.
README.md
| ... | ... | @@ -27,7 +27,7 @@ wvp使用文档 [https://doc.wvp-pro.cn](https://doc.wvp-pro.cn) |
| 27 | 27 | ZLM使用文档 [https://github.com/ZLMediaKit/ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit) |
| 28 | 28 | > wvp文档由gitee提供服务,如果遇到打不开请多刷新几次。 |
| 29 | 29 | |
| 30 | -# 社群地址 | |
| 30 | +# 付费社群 | |
| 31 | 31 | [](https://t.zsxq.com/0d8VAD3Dm) |
| 32 | 32 | > 收费是为了提供更好的服务,也是对作者更大的激励。加入星球的用户三天后可以私信我留下微信号,我会拉大家入群。加入三天内不满意可以直接退款,大家不需要有顾虑,来白嫖三天也不是不可以。 |
| 33 | 33 | |
| ... | ... | @@ -104,6 +104,8 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git |
| 104 | 104 | - [X] 云端录像,推流/代理/国标视频均可以录制在云端服务器,支持预览和下载 |
| 105 | 105 | - [X] 支持打包可执行jar和war |
| 106 | 106 | - [X] 支持跨域请求,支持前后端分离部署 |
| 107 | +- [X] 支持Mysql,Postgresql,金仓等数据库 | |
| 108 | +- [X] 支持Onvif(目前在onvif分支,需要安装onvif服务,服务请在知识星球获取) | |
| 107 | 109 | |
| 108 | 110 | # 授权协议 |
| 109 | 111 | 本项目自有代码使用宽松的MIT协议,在保留版权信息的情况下可以自由应用于各自商用、非商业的项目。 但是本项目也零碎的使用了一些其他的开源代码,在商用的情况下请自行替代或剔除; 由于使用本项目而产生的商业纠纷或侵权行为一概与本项目及开发者无关,请自行承担法律风险。 在使用本项目代码时,也应该在授权协议中同时表明本项目依赖的第三方库的协议 | ... | ... |
doc/README.md
| ... | ... | @@ -14,7 +14,7 @@ |
| 14 | 14 | - 完全开源,且使用MIT许可协议。保留版权的情况下可以用于商业项目。 |
| 15 | 15 | - 支持多流媒体节点负载均衡。 |
| 16 | 16 | |
| 17 | -# 社群 | |
| 17 | +# 付费社群 | |
| 18 | 18 | [](https://t.zsxq.com/0d8VAD3Dm) |
| 19 | 19 | > 收费是为了提供更好的服务,也是对作者更大的激励。加入星球的用户三天后可以私信我留下微信号,我会拉大家入群。加入三天内不满意可以直接退款,大家不需要有顾虑,来白嫖三天也不是不可以。 |
| 20 | 20 | |
| ... | ... | @@ -62,16 +62,16 @@ |
| 62 | 62 | - [X] 注册 |
| 63 | 63 | - [X] 注销 |
| 64 | 64 | - [X] 实时视音频点播 |
| 65 | -- [ ] 设备控制 | |
| 66 | - - [ ] 云台控制 | |
| 65 | +- [X] 设备控制 | |
| 66 | + - [X] 云台控制 | |
| 67 | 67 | - [ ] 远程启动 |
| 68 | - - [ ] 录像控制 | |
| 69 | - - [ ] 报警布防/撤防 | |
| 70 | - - [ ] 报警复位 | |
| 71 | - - [ ] 强制关键帧 | |
| 72 | - - [ ] 拉框放大 | |
| 73 | - - [ ] 拉框缩小 | |
| 74 | - - [ ] 看守位控制 | |
| 68 | + - [X] 录像控制 | |
| 69 | + - [X] 报警布防/撤防 | |
| 70 | + - [X] 报警复位 | |
| 71 | + - [X] 强制关键帧 | |
| 72 | + - [X] 拉框放大 | |
| 73 | + - [X] 拉框缩小 | |
| 74 | + - [X] 看守位控制 | |
| 75 | 75 | - [ ] 设备配置 |
| 76 | 76 | - [ ] 报警事件通知和分发 |
| 77 | 77 | - [X] 设备目录订阅 |
| ... | ... | @@ -79,7 +79,7 @@ |
| 79 | 79 | - [X] 设备目录查询 |
| 80 | 80 | - [X] 设备状态查询 |
| 81 | 81 | - [ ] 设备配置查询 |
| 82 | - - [ ] 设备预置位查询 | |
| 82 | + - [X] 设备预置位查询 | |
| 83 | 83 | - [X] 状态信息报送 |
| 84 | 84 | - [X] 设备视音频文件检索 |
| 85 | 85 | - [X] 历史视音频的回放 |
| ... | ... | @@ -87,7 +87,7 @@ |
| 87 | 87 | - [x] 暂停 |
| 88 | 88 | - [x] 进/退 |
| 89 | 89 | - [x] 停止 |
| 90 | -- [ ] 视音频文件下载 | |
| 90 | +- [X] 视音频文件下载 | |
| 91 | 91 | - [ ] ~~校时~~ |
| 92 | 92 | - [X] 订阅和通知 |
| 93 | 93 | - [X] 事件订阅 | ... | ... |
doc/_content/introduction/config.md
| ... | ... | @@ -29,10 +29,53 @@ java -jar wvp-pro-*.jar |
| 29 | 29 | ``` |
| 30 | 30 | 这也是我自己最常用的方式。 |
| 31 | 31 | ## 2 配置WVP-PRO |
| 32 | -### 2.1 Mysql数据库配置 | |
| 33 | -首先你需要创建一个名为wvp(也可使用其他名字)的数据库,并使用sql/mysql.sql导入数据库,初始化数据库结构。 | |
| 34 | -(这里注意,取决于版本,新版的sql文件夹下有update.sql,补丁包,一定要注意运行导入) | |
| 35 | -在application-dev.yml中配置(使用1.2方式的是在jar包的同级目录的application.yml)配置数据库连接,包括数据库连接信息,密码。 | |
| 32 | +wvp支持多种数据库,包括Mysql,Postgresql,金仓等,配置任选一种即可。 | |
| 33 | +### 2.1 数据库配置 | |
| 34 | +#### 2.1.1 初始化数据库 | |
| 35 | +首先使用创建数据库,然后使用sql/初始化.sql初始化数据库,如果是从旧版升级上来的,使用升级sql更新。 | |
| 36 | +#### 2.1.2 Mysql数据库配置 | |
| 37 | +数据库名称以wvp为例 | |
| 38 | +```yaml | |
| 39 | +spring: | |
| 40 | + datasource: | |
| 41 | + type: com.zaxxer.hikari.HikariDataSource | |
| 42 | + driver-class-name: com.mysql.cj.jdbc.Driver | |
| 43 | + url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true&allowPublicKeyRetrieval=true | |
| 44 | + username: root | |
| 45 | + password: 12345678 | |
| 46 | + | |
| 47 | +mybatis: | |
| 48 | + configuration: | |
| 49 | + map-underscore-to-camel-case: true | |
| 50 | +``` | |
| 51 | +#### 2.1.3 Postgresql数据库配置 | |
| 52 | +数据库名称以wvp为例 | |
| 53 | +```yaml | |
| 54 | +spring: | |
| 55 | + datasource: | |
| 56 | + type: com.zaxxer.hikari.HikariDataSource | |
| 57 | + driver-class-name: org.postgresql.Driver | |
| 58 | + url: jdbc:postgresql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true&allowPublicKeyRetrieval=true | |
| 59 | + username: root | |
| 60 | + password: 12345678 | |
| 61 | + | |
| 62 | +pagehelper: | |
| 63 | + helper-dialect: postgresql | |
| 64 | +``` | |
| 65 | +#### 2.1.4 金仓数据库配置 | |
| 66 | +数据库名称以wvp为例 | |
| 67 | +```yaml | |
| 68 | +spring: | |
| 69 | + datasource: | |
| 70 | + type: com.zaxxer.hikari.HikariDataSource | |
| 71 | + driver-class-name: com.kingbase8.Driver | |
| 72 | + url: jdbc:kingbase8://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=utf8 | |
| 73 | + username: root | |
| 74 | + password: 12345678 | |
| 75 | + | |
| 76 | +pagehelper: | |
| 77 | + helper-dialect: postgresql | |
| 78 | +``` | |
| 36 | 79 | ### 2.2 Redis数据库配置 |
| 37 | 80 | 配置wvp中的redis连接信息,建议wvp自己单独使用一个db。 |
| 38 | 81 | ### 2.3 配置服务启动端口(可直接使用默认配置) | ... | ... |
doc/_media/1372762149.jpg
0 → 100644
126 KB
doc/_media/903207146.jpg
0 → 100644
131 KB
doc/_media/logo.jpg
0 → 100644
102 KB
doc/index.html
| ... | ... | @@ -7,7 +7,7 @@ |
| 7 | 7 | <meta name="description" content="Description"> |
| 8 | 8 | <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0"> |
| 9 | 9 | <link rel="icon" href="_media/favicon.ico" type="image/x-icon" /> |
| 10 | - <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4/lib/themes/vue.css"> | |
| 10 | + <link rel="stylesheet" href="./lib/css/vue.css"> | |
| 11 | 11 | <!-- <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify/lib/themes/dark.css">--> |
| 12 | 12 | <style> |
| 13 | 13 | .cover{ |
| ... | ... | @@ -47,11 +47,11 @@ |
| 47 | 47 | } |
| 48 | 48 | </script> |
| 49 | 49 | <!-- Docsify v4 --> |
| 50 | - <script src="//cdn.jsdelivr.net/npm/docsify@4"></script> | |
| 51 | - <script src="//unpkg.com/docsify-plantuml/dist/docsify-plantuml.min.js"></script> | |
| 52 | - <script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/search.min.js"></script> | |
| 53 | - <script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/zoom-image.min.js"></script> | |
| 54 | - <script src="//cdn.jsdelivr.net/npm/docsify-copy-code/dist/docsify-copy-code.min.js"></script> | |
| 50 | + <script src="./lib/js/docsify@4.js"></script> | |
| 51 | + <script src="./lib/js/docsify-plantuml.min.js"></script> | |
| 52 | + <script src="./lib/js/search.min.js"></script> | |
| 53 | + <script src="./lib/js/zoom-image.min.js"></script> | |
| 54 | + <script src="./lib/js/docsify-copy-code.min.js"></script> | |
| 55 | 55 | |
| 56 | 56 | </script> |
| 57 | 57 | <!-- <script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/disqus.min.js"></script>--> | ... | ... |
doc/lib/css/vue.css
0 → 100644
| 1 | +@import url("https://fonts.googleapis.com/css?family=Roboto+Mono|Source+Sans+Pro:300,400,600");*{-webkit-font-smoothing:antialiased;-webkit-overflow-scrolling:touch;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-text-size-adjust:none;-webkit-touch-callout:none;box-sizing:border-box}body:not(.ready){overflow:hidden}body:not(.ready) .app-nav,body:not(.ready)>nav,body:not(.ready) [data-cloak]{display:none}div#app{font-size:30px;font-weight:lighter;margin:40vh auto;text-align:center}div#app:empty:before{content:"Loading..."}img.emoji{height:1.2em}img.emoji,span.emoji{vertical-align:middle}span.emoji{font-family:Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-size:1.2em}.progress{background-color:#42b983;background-color:var(--theme-color,#42b983);height:2px;left:0;position:fixed;right:0;top:0;transition:width .2s,opacity .4s;width:0;z-index:999999}.search .search-keyword,.search a:hover{color:#42b983;color:var(--theme-color,#42b983)}.search .search-keyword{font-style:normal;font-weight:700}body,html{height:100%}body{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;color:#34495e;font-family:Source Sans Pro,Helvetica Neue,Arial,sans-serif;font-size:15px;letter-spacing:0;margin:0;overflow-x:hidden}img{max-width:100%}a[disabled]{cursor:not-allowed;opacity:.6}kbd{border:1px solid #ccc;border-radius:3px;display:inline-block;font-size:12px!important;line-height:12px;margin-bottom:3px;padding:3px 5px;vertical-align:middle}li input[type=checkbox]{margin:0 .2em .25em 0;vertical-align:middle}.app-nav{margin:25px 60px 0 0;position:absolute;right:0;text-align:right;z-index:10}.app-nav.no-badge{margin-right:25px}.app-nav p{margin:0}.app-nav>a{margin:0 1rem;padding:5px 0}.app-nav li,.app-nav ul{display:inline-block;list-style:none;margin:0}.app-nav a{color:inherit;font-size:16px;text-decoration:none;transition:color .3s}.app-nav a.active,.app-nav a:hover{color:#42b983;color:var(--theme-color,#42b983)}.app-nav a.active{border-bottom:2px solid #42b983;border-bottom:2px solid var(--theme-color,#42b983)}.app-nav li{display:inline-block;margin:0 1rem;padding:5px 0;position:relative;cursor:pointer}.app-nav li ul{background-color:#fff;border:1px solid;border-color:#ddd #ddd #ccc;border-radius:4px;box-sizing:border-box;display:none;max-height:calc(100vh - 61px);overflow-y:auto;padding:10px 0;position:absolute;right:-15px;text-align:left;top:100%;white-space:nowrap}.app-nav li ul li{display:block;font-size:14px;line-height:1rem;margin:8px 14px;white-space:nowrap}.app-nav li ul a{display:block;font-size:inherit;margin:0;padding:0}.app-nav li ul a.active{border-bottom:0}.app-nav li:hover ul{display:block}.github-corner{border-bottom:0;position:fixed;right:0;text-decoration:none;top:0;z-index:1}.github-corner:hover .octo-arm{animation:octocat-wave .56s ease-in-out}.github-corner svg{color:#fff;fill:#42b983;fill:var(--theme-color,#42b983);height:80px;width:80px}main{display:block;position:relative;width:100vw;height:100%;z-index:0}main.hidden{display:none}.anchor{display:inline-block;text-decoration:none;transition:all .3s}.anchor span{color:#34495e}.anchor:hover{text-decoration:underline}.sidebar{border-right:1px solid rgba(0,0,0,.07);overflow-y:auto;padding:40px 0 0;position:absolute;top:0;bottom:0;left:0;transition:transform .25s ease-out;width:300px;z-index:20}.sidebar>h1{margin:0 auto 1rem;font-size:1.5rem;font-weight:300;text-align:center}.sidebar>h1 a{color:inherit;text-decoration:none}.sidebar>h1 .app-nav{display:block;position:static}.sidebar .sidebar-nav{line-height:2em;padding-bottom:40px}.sidebar li.collapse .app-sub-sidebar{display:none}.sidebar ul{margin:0 0 0 15px;padding:0}.sidebar li>p{font-weight:700;margin:0}.sidebar ul,.sidebar ul li{list-style:none}.sidebar ul li a{border-bottom:none;display:block}.sidebar ul li ul{padding-left:20px}.sidebar::-webkit-scrollbar{width:4px}.sidebar::-webkit-scrollbar-thumb{background:transparent;border-radius:4px}.sidebar:hover::-webkit-scrollbar-thumb{background:hsla(0,0%,53.3%,.4)}.sidebar:hover::-webkit-scrollbar-track{background:hsla(0,0%,53.3%,.1)}.sidebar-toggle{background-color:transparent;background-color:hsla(0,0%,100%,.8);border:0;outline:none;padding:10px;position:absolute;bottom:0;left:0;text-align:center;transition:opacity .3s;width:284px;z-index:30;cursor:pointer}.sidebar-toggle:hover .sidebar-toggle-button{opacity:.4}.sidebar-toggle span{background-color:#42b983;background-color:var(--theme-color,#42b983);display:block;margin-bottom:4px;width:16px;height:2px}body.sticky .sidebar,body.sticky .sidebar-toggle{position:fixed}.content{padding-top:60px;position:absolute;top:0;right:0;bottom:0;left:300px;transition:left .25s ease}.markdown-section{margin:0 auto;max-width:80%;padding:30px 15px 40px;position:relative}.markdown-section>*{box-sizing:border-box;font-size:inherit}.markdown-section>:first-child{margin-top:0!important}.markdown-section hr{border:none;border-bottom:1px solid #eee;margin:2em 0}.markdown-section iframe{border:1px solid #eee;width:1px;min-width:100%}.markdown-section table{border-collapse:collapse;border-spacing:0;display:block;margin-bottom:1rem;overflow:auto;width:100%}.markdown-section th{font-weight:700}.markdown-section td,.markdown-section th{border:1px solid #ddd;padding:6px 13px}.markdown-section tr{border-top:1px solid #ccc}.markdown-section p.tip,.markdown-section tr:nth-child(2n){background-color:#f8f8f8}.markdown-section p.tip{border-bottom-right-radius:2px;border-left:4px solid #f66;border-top-right-radius:2px;margin:2em 0;padding:12px 24px 12px 30px;position:relative}.markdown-section p.tip:before{background-color:#f66;border-radius:100%;color:#fff;content:"!";font-family:Dosis,Source Sans Pro,Helvetica Neue,Arial,sans-serif;font-size:14px;font-weight:700;left:-12px;line-height:20px;position:absolute;height:20px;width:20px;text-align:center;top:14px}.markdown-section p.tip code{background-color:#efefef}.markdown-section p.tip em{color:#34495e}.markdown-section p.warn{background:rgba(66,185,131,.1);border-radius:2px;padding:1rem}.markdown-section ul.task-list>li{list-style-type:none}body.close .sidebar{transform:translateX(-300px)}body.close .sidebar-toggle{width:auto}body.close .content{left:0}@media print{.app-nav,.github-corner,.sidebar,.sidebar-toggle{display:none}}@media screen and (max-width:768px){.github-corner,.sidebar,.sidebar-toggle{position:fixed}.app-nav{margin-top:16px}.app-nav li ul{top:30px}main{height:auto;min-height:100vh;overflow-x:hidden}.sidebar{left:-300px;transition:transform .25s ease-out}.content{left:0;max-width:100vw;position:static;padding-top:20px;transition:transform .25s ease}.app-nav,.github-corner{transition:transform .25s ease-out}.sidebar-toggle{background-color:transparent;width:auto;padding:30px 30px 10px 10px}body.close .sidebar{transform:translateX(300px)}body.close .sidebar-toggle{background-color:hsla(0,0%,100%,.8);transition:background-color 1s;width:284px;padding:10px}body.close .content{transform:translateX(300px)}body.close .app-nav,body.close .github-corner{display:none}.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave .56s ease-in-out}}@keyframes octocat-wave{0%,to{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}section.cover{position:relative;align-items:center;background-position:50%;background-repeat:no-repeat;background-size:cover;min-height:100vh;width:100%;display:none}section.cover.show{display:flex}section.cover.has-mask .mask{background-color:#fff;opacity:.8;position:absolute;top:0;bottom:0;width:100%}section.cover .cover-main{flex:1;margin:0 16px;text-align:center;position:relative}section.cover a{color:inherit}section.cover a,section.cover a:hover{text-decoration:none}section.cover p{line-height:1.5rem;margin:1em 0}section.cover h1{color:inherit;font-size:2.5rem;font-weight:300;margin:.625rem 0 2.5rem;position:relative;text-align:center}section.cover h1 a{display:block}section.cover h1 small{bottom:-.4375rem;font-size:1rem;position:absolute}section.cover blockquote{font-size:1.5rem;text-align:center}section.cover ul{line-height:1.8;list-style-type:none;margin:1em auto;max-width:500px;padding:0}section.cover .cover-main>p:last-child a{border-radius:2rem;border:1px solid #42b983;border-color:var(--theme-color,#42b983);box-sizing:border-box;color:#42b983;color:var(--theme-color,#42b983);display:inline-block;font-size:1.05rem;letter-spacing:.1rem;margin:.5rem 1rem;padding:.75em 2rem;text-decoration:none;transition:all .15s ease}section.cover .cover-main>p:last-child a:last-child{background-color:#42b983;background-color:var(--theme-color,#42b983);color:#fff}section.cover .cover-main>p:last-child a:last-child:hover{color:inherit;opacity:.8}section.cover .cover-main>p:last-child a:hover{color:inherit}section.cover blockquote>p>a{border-bottom:2px solid #42b983;border-bottom:2px solid var(--theme-color,#42b983);transition:color .3s}section.cover blockquote>p>a:hover{color:#42b983;color:var(--theme-color,#42b983)}.sidebar,body{background-color:#fff}.sidebar{color:#364149}.sidebar li{margin:6px 0}.sidebar ul li a{color:#505d6b;font-size:14px;font-weight:400;overflow:hidden;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.sidebar ul li a:hover{text-decoration:underline}.sidebar ul li ul{padding:0}.sidebar ul li.active>a{border-right:2px solid;color:#42b983;color:var(--theme-color,#42b983);font-weight:600}.app-sub-sidebar li:before{content:"-";padding-right:4px;float:left}.markdown-section h1,.markdown-section h2,.markdown-section h3,.markdown-section h4,.markdown-section strong{color:#2c3e50;font-weight:600}.markdown-section a{color:#42b983;color:var(--theme-color,#42b983);font-weight:600}.markdown-section h1{font-size:2rem;margin:0 0 1rem}.markdown-section h2{font-size:1.75rem;margin:45px 0 .8rem}.markdown-section h3{font-size:1.5rem;margin:40px 0 .6rem}.markdown-section h4{font-size:1.25rem}.markdown-section h5{font-size:1rem}.markdown-section h6{color:#777;font-size:1rem}.markdown-section figure,.markdown-section p{margin:1.2em 0}.markdown-section ol,.markdown-section p,.markdown-section ul{line-height:1.6rem;word-spacing:.05rem}.markdown-section ol,.markdown-section ul{padding-left:1.5rem}.markdown-section blockquote{border-left:4px solid #42b983;border-left:4px solid var(--theme-color,#42b983);color:#858585;margin:2em 0;padding-left:20px}.markdown-section blockquote p{font-weight:600;margin-left:0}.markdown-section iframe{margin:1em 0}.markdown-section em{color:#7f8c8d}.markdown-section code,.markdown-section output:after,.markdown-section pre{font-family:Roboto Mono,Monaco,courier,monospace}.markdown-section code,.markdown-section pre{background-color:#f8f8f8}.markdown-section output,.markdown-section pre{margin:1.2em 0;position:relative}.markdown-section output,.markdown-section pre>code{border-radius:2px;display:block}.markdown-section output:after,.markdown-section pre>code{-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial}.markdown-section code{border-radius:2px;color:#e96900;margin:0 2px;padding:3px 5px;white-space:pre-wrap}.markdown-section>:not(h1):not(h2):not(h3):not(h4):not(h5):not(h6) code{font-size:.8rem}.markdown-section pre{padding:0 1.4rem;line-height:1.5rem;overflow:auto;word-wrap:normal}.markdown-section pre>code{color:#525252;font-size:.8rem;padding:2.2em 5px;line-height:inherit;margin:0 2px;max-width:inherit;overflow:inherit;white-space:inherit}.markdown-section output{padding:1.7rem 1.4rem;border:1px dotted #ccc}.markdown-section output>:first-child{margin-top:0}.markdown-section output>:last-child{margin-bottom:0}.markdown-section code:after,.markdown-section code:before,.markdown-section output:after,.markdown-section output:before{letter-spacing:.05rem}.markdown-section output:after,.markdown-section pre:after{color:#ccc;font-size:.6rem;font-weight:600;height:15px;line-height:15px;padding:5px 10px 0;position:absolute;right:0;text-align:right;top:0;content:attr(data-lang)}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#8e908c}.token.namespace{opacity:.7}.token.boolean,.token.number{color:#c76b29}.token.punctuation{color:#525252}.token.property{color:#c08b30}.token.tag{color:#2973b7}.token.string{color:#42b983;color:var(--theme-color,#42b983)}.token.selector{color:#6679cc}.token.attr-name{color:#2973b7}.language-css .token.string,.style .token.string,.token.entity,.token.url{color:#22a2c9}.token.attr-value,.token.control,.token.directive,.token.unit{color:#42b983;color:var(--theme-color,#42b983)}.token.function,.token.keyword{color:#e96900}.token.atrule,.token.regex,.token.statement{color:#22a2c9}.token.placeholder,.token.variable{color:#3d8fd1}.token.deleted{text-decoration:line-through}.token.inserted{border-bottom:1px dotted #202746;text-decoration:none}.token.italic{font-style:italic}.token.bold,.token.important{font-weight:700}.token.important{color:#c94922}.token.entity{cursor:help}code .token{-moz-osx-font-smoothing:initial;-webkit-font-smoothing:initial;min-height:1.5rem;position:relative;left:auto} | |
| 0 | 2 | \ No newline at end of file | ... | ... |
doc/lib/js/docsify-copy-code.min.js
0 → 100644
| 1 | +/*! | |
| 2 | + * docsify-copy-code | |
| 3 | + * v2.1.1 | |
| 4 | + * https://github.com/jperasmus/docsify-copy-code | |
| 5 | + * (c) 2017-2020 JP Erasmus <jperasmus11@gmail.com> | |
| 6 | + * MIT license | |
| 7 | + */ | |
| 8 | +!function(){"use strict";function s(o){return(s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(o){return typeof o}:function(o){return o&&"function"==typeof Symbol&&o.constructor===Symbol&&o!==Symbol.prototype?"symbol":typeof o})(o)}!function(o,e){void 0===e&&(e={});var t=e.insertAt;if(o&&"undefined"!=typeof document){var n=document.head||document.getElementsByTagName("head")[0],c=document.createElement("style");c.type="text/css","top"===t&&n.firstChild?n.insertBefore(c,n.firstChild):n.appendChild(c),c.styleSheet?c.styleSheet.cssText=o:c.appendChild(document.createTextNode(o))}}(".docsify-copy-code-button,.docsify-copy-code-button span{cursor:pointer;transition:all .25s ease}.docsify-copy-code-button{position:absolute;z-index:1;top:0;right:0;overflow:visible;padding:.65em .8em;border:0;border-radius:0;outline:0;font-size:1em;background:grey;background:var(--theme-color,grey);color:#fff;opacity:0}.docsify-copy-code-button span{border-radius:3px;background:inherit;pointer-events:none}.docsify-copy-code-button .error,.docsify-copy-code-button .success{position:absolute;z-index:-100;top:50%;right:0;padding:.5em .65em;font-size:.825em;opacity:0;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.docsify-copy-code-button.error .error,.docsify-copy-code-button.success .success{right:100%;opacity:1;-webkit-transform:translate(-115%,-50%);transform:translate(-115%,-50%)}.docsify-copy-code-button:focus,pre:hover .docsify-copy-code-button{opacity:1}"),document.querySelector('link[href*="docsify-copy-code"]')&&console.warn("[Deprecation] Link to external docsify-copy-code stylesheet is no longer necessary."),window.DocsifyCopyCodePlugin={init:function(){return function(o,e){o.ready(function(){console.warn("[Deprecation] Manually initializing docsify-copy-code using window.DocsifyCopyCodePlugin.init() is no longer necessary.")})}}},window.$docsify=window.$docsify||{},window.$docsify.plugins=[function(o,r){o.doneEach(function(){var o=Array.apply(null,document.querySelectorAll("pre[data-lang]")),c={buttonText:"Copy to clipboard",errorText:"Error",successText:"Copied"};r.config.copyCode&&Object.keys(c).forEach(function(t){var n=r.config.copyCode[t];"string"==typeof n?c[t]=n:"object"===s(n)&&Object.keys(n).some(function(o){var e=-1<location.href.indexOf(o);return c[t]=e?n[o]:c[t],e})});var e=['<button class="docsify-copy-code-button">','<span class="label">'.concat(c.buttonText,"</span>"),'<span class="error">'.concat(c.errorText,"</span>"),'<span class="success">'.concat(c.successText,"</span>"),"</button>"].join("");o.forEach(function(o){o.insertAdjacentHTML("beforeend",e)})}),o.mounted(function(){document.querySelector(".content").addEventListener("click",function(o){if(o.target.classList.contains("docsify-copy-code-button")){var e="BUTTON"===o.target.tagName?o.target:o.target.parentNode,t=document.createRange(),n=e.parentNode.querySelector("code"),c=window.getSelection();t.selectNode(n),c.removeAllRanges(),c.addRange(t);try{document.execCommand("copy")&&(e.classList.add("success"),setTimeout(function(){e.classList.remove("success")},1e3))}catch(o){console.error("docsify-copy-code: ".concat(o)),e.classList.add("error"),setTimeout(function(){e.classList.remove("error")},1e3)}"function"==typeof(c=window.getSelection()).removeRange?c.removeRange(t):"function"==typeof c.removeAllRanges&&c.removeAllRanges()}})})}].concat(window.$docsify.plugins||[])}(); | |
| 9 | +//# sourceMappingURL=docsify-copy-code.min.js.map | ... | ... |
doc/lib/js/docsify-plantuml.min.js
0 → 100644
| 1 | +!function(t){function e(a){if(n[a])return n[a].exports;var r=n[a]={i:a,l:!1,exports:{}};return t[a].call(r.exports,r,r.exports,e),r.l=!0,r.exports}var n={};e.m=t,e.c=n,e.d=function(t,n,a){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:a})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=0)}([function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=n(1);window.$docsify||(window.$docsify={}),window.$docsify.plugins=(window.$docsify.plugins||[]).concat(a.a)},function(t,e,n){"use strict";function a(t,e){var t=Object(o.a)(e.skin)+t,n=e.serverPath||"//www.plantuml.com/plantuml/svg/";if(e.renderSvgAsObject){var a=n+Object(l.encode)(r(t));return'<object type="image/svg+xml" data="'+a+'" />'}var a=n+Object(l.encode)(t);return'<img src="'+a+'" />'}function r(t){function e(t,e){for(var n=(a+e).split("/"),r=[],i=0,s=n.length;i<s;i++){var o=n[i];".."===o?r.pop():"."!==o&&r.push(o)}return"[["+r.join("/")}var n=window.location.toString(),a=n.substring(0,n.lastIndexOf("/")+1);return t.replace(/\[\[\$((?:\.?\.\/)*)/g,e)}function i(t,e,n){var r=window.Docsify.dom,i=r.create("span",t);return i.querySelectorAll?((r.findAll(i,e)||[]).forEach(function(t){var e=t.parentNode,i=r.create("p",a(t.innerText,n));e&&(i.dataset.lang=h,t.parentNode.replaceChild(i,t))}),i.innerHTML):t}function s(t,e){const n=Object.assign({},{skin:"default",renderSvgAsObject:!1},e.config.plantuml);t.afterEach(function(t){return i(t,d,n)})}e.a=s;var o=n(2),l=n(5),h=(n.n(l),"plantuml"),d='pre[data-lang="'+h+'"]'},function(t,e,n){"use strict";function a(t){return t in l?l[t]:(console.warn("[Docsify-PlantUML] Invalid skin name: "+t),l[h])}e.a=a;var r=n(3),i=n.n(r),s=n(4),o=n.n(s);const l={default:i.a,classic:o.a},h="default"},function(t,e){t.exports="' fork from https://github.com/matthewjosephtaylor/plantuml-style/blob/master/style.pu\n' Not-ugly plantuml style defaults\n\nskinparam defaultFontName Helvetica\nskinparam defaultFontSize 12\nskinparam sequenceMessageAlign center\nskinparam monochrome true\nskinparam shadowing false\n\nskinparam activity {\n\tArrowColor Black\n\tBackgroundColor White\n\tBorderColor Black\n\tBorderThickness 1\n}\n\nskinparam actor {\n\tBackgroundColor White\n\tBorderColor Black\n}\n\nskinparam usecase {\n\tArrowColor Black\n\tBackgroundColor White\n\tBorderColor Black\n\tBorderThickness 1\n}\n\nskinparam class {\n\tArrowColor Black\n\tBackgroundColor White\n\tBorderColor Black\n\tBorderThickness 1\n}\n\n\nskinparam object {\n\tArrowColor Black\n\tBackgroundColor White\n\tBorderColor Black\n}\n\nskinparam package {\n\tBackgroundColor White\n\tBorderColor Black\n}\n\n'TODO stereotype\n\nskinparam component {\n\tBackgroundColor White\n\tInterfaceBackgroundColor White\n\tBorderColor Black\n\tInterfaceBorderColor Black\n}\n\nskinparam note {\n\tBackgroundColor White\n\tBorderColor Black\n}\n\nskinparam state {\n\tArrowColor Black\n\tBackgroundColor White\n\tBorderColor Black\n}\n\nskinparam sequence {\n\tArrowColor Black\n\tBackgroundColor White\n\tParticipantBackgroundColor White\n\tBorderColor Black\n\tLifeLineBorderColor Black\n\tParticipantBorderColor Black\n\tBoxLineColor Black\n}\n\nskinparam interface {\n\tBackgroundColor White\n\tBorderColor Black\n}\n"},function(t,e){t.exports=""},function(t,e,n){t.exports={encode:n(6).encode,decode:n(7).decode}},function(t,e,n){var a,a;!function(e){t.exports=e()}(function(){return function(){function t(e,n,r){function i(o,l){if(!n[o]){if(!e[o]){var h="function"==typeof a&&a;if(!l&&h)return a(o,!0);if(s)return s(o,!0);var d=new Error("Cannot find module '"+o+"'");throw d.code="MODULE_NOT_FOUND",d}var f=n[o]={exports:{}};e[o][0].call(f.exports,function(t){return i(e[o][1][t]||t)},f,f.exports,t,e,n,r)}return n[o].exports}for(var s="function"==typeof a&&a,o=0;o<r.length;o++)i(r[o]);return i}return t}()({1:[function(t,e,n){"use strict";var a=t("pako/lib/deflate.js");e.exports=function(t){return a.deflateRaw(t,{level:9,to:"string"})}},{"pako/lib/deflate.js":4}],2:[function(t,e,n){"use strict";function a(t){return t<10?String.fromCharCode(48+t):(t-=10)<26?String.fromCharCode(65+t):(t-=26)<26?String.fromCharCode(97+t):(t-=26,0===t?"-":1===t?"_":"?")}function r(t,e,n){var r=t>>2,i=(3&t)<<4|e>>4,s=(15&e)<<2|n>>6,o=63&n,l="";return l+=a(63&r),l+=a(63&i),l+=a(63&s),l+=a(63&o)}e.exports=function(t){for(var e="",n=0;n<t.length;n+=3)n+2===t.length?e+=r(t.charCodeAt(n),t.charCodeAt(n+1),0):n+1===t.length?e+=r(t.charCodeAt(n),0,0):e+=r(t.charCodeAt(n),t.charCodeAt(n+1),t.charCodeAt(n+2));return e}},{}],3:[function(t,e,n){"use strict";var a=t("./deflate"),r=t("./encode64");e.exports.encode=function(t){var e=a(t);return r(e)}},{"./deflate":1,"./encode64":2}],4:[function(t,e,n){"use strict";function a(t){if(!(this instanceof a))return new a(t);this.options=l.assign({level:_,method:p,chunkSize:16384,windowBits:15,memLevel:8,strategy:g,to:""},t||{});var e=this.options;e.raw&&e.windowBits>0?e.windowBits=-e.windowBits:e.gzip&&e.windowBits>0&&e.windowBits<16&&(e.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new f,this.strm.avail_out=0;var n=o.deflateInit2(this.strm,e.level,e.method,e.windowBits,e.memLevel,e.strategy);if(n!==c)throw new Error(d[n]);if(e.header&&o.deflateSetHeader(this.strm,e.header),e.dictionary){var r;if(r="string"==typeof e.dictionary?h.string2buf(e.dictionary):"[object ArrayBuffer]"===u.call(e.dictionary)?new Uint8Array(e.dictionary):e.dictionary,(n=o.deflateSetDictionary(this.strm,r))!==c)throw new Error(d[n]);this._dict_set=!0}}function r(t,e){var n=new a(e);if(n.push(t,!0),n.err)throw n.msg||d[n.err];return n.result}function i(t,e){return e=e||{},e.raw=!0,r(t,e)}function s(t,e){return e=e||{},e.gzip=!0,r(t,e)}var o=t("./zlib/deflate"),l=t("./utils/common"),h=t("./utils/strings"),d=t("./zlib/messages"),f=t("./zlib/zstream"),u=Object.prototype.toString,c=0,_=-1,g=0,p=8;a.prototype.push=function(t,e){var n,a,r=this.strm,i=this.options.chunkSize;if(this.ended)return!1;a=e===~~e?e:!0===e?4:0,"string"==typeof t?r.input=h.string2buf(t):"[object ArrayBuffer]"===u.call(t)?r.input=new Uint8Array(t):r.input=t,r.next_in=0,r.avail_in=r.input.length;do{if(0===r.avail_out&&(r.output=new l.Buf8(i),r.next_out=0,r.avail_out=i),1!==(n=o.deflate(r,a))&&n!==c)return this.onEnd(n),this.ended=!0,!1;0!==r.avail_out&&(0!==r.avail_in||4!==a&&2!==a)||("string"===this.options.to?this.onData(h.buf2binstring(l.shrinkBuf(r.output,r.next_out))):this.onData(l.shrinkBuf(r.output,r.next_out)))}while((r.avail_in>0||0===r.avail_out)&&1!==n);return 4===a?(n=o.deflateEnd(this.strm),this.onEnd(n),this.ended=!0,n===c):2!==a||(this.onEnd(c),r.avail_out=0,!0)},a.prototype.onData=function(t){this.chunks.push(t)},a.prototype.onEnd=function(t){t===c&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=l.flattenChunks(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg},n.Deflate=a,n.deflate=r,n.deflateRaw=i,n.gzip=s},{"./utils/common":5,"./utils/strings":6,"./zlib/deflate":9,"./zlib/messages":10,"./zlib/zstream":12}],5:[function(t,e,n){"use strict";function a(t,e){return Object.prototype.hasOwnProperty.call(t,e)}var r="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;n.assign=function(t){for(var e=Array.prototype.slice.call(arguments,1);e.length;){var n=e.shift();if(n){if("object"!=typeof n)throw new TypeError(n+"must be non-object");for(var r in n)a(n,r)&&(t[r]=n[r])}}return t},n.shrinkBuf=function(t,e){return t.length===e?t:t.subarray?t.subarray(0,e):(t.length=e,t)};var i={arraySet:function(t,e,n,a,r){if(e.subarray&&t.subarray)return void t.set(e.subarray(n,n+a),r);for(var i=0;i<a;i++)t[r+i]=e[n+i]},flattenChunks:function(t){var e,n,a,r,i,s;for(a=0,e=0,n=t.length;e<n;e++)a+=t[e].length;for(s=new Uint8Array(a),r=0,e=0,n=t.length;e<n;e++)i=t[e],s.set(i,r),r+=i.length;return s}},s={arraySet:function(t,e,n,a,r){for(var i=0;i<a;i++)t[r+i]=e[n+i]},flattenChunks:function(t){return[].concat.apply([],t)}};n.setTyped=function(t){t?(n.Buf8=Uint8Array,n.Buf16=Uint16Array,n.Buf32=Int32Array,n.assign(n,i)):(n.Buf8=Array,n.Buf16=Array,n.Buf32=Array,n.assign(n,s))},n.setTyped(r)},{}],6:[function(t,e,n){"use strict";function a(t,e){if(e<65534&&(t.subarray&&s||!t.subarray&&i))return String.fromCharCode.apply(null,r.shrinkBuf(t,e));for(var n="",a=0;a<e;a++)n+=String.fromCharCode(t[a]);return n}var r=t("./common"),i=!0,s=!0;try{String.fromCharCode.apply(null,[0])}catch(t){i=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(t){s=!1}for(var o=new r.Buf8(256),l=0;l<256;l++)o[l]=l>=252?6:l>=248?5:l>=240?4:l>=224?3:l>=192?2:1;o[254]=o[254]=1,n.string2buf=function(t){var e,n,a,i,s,o=t.length,l=0;for(i=0;i<o;i++)n=t.charCodeAt(i),55296==(64512&n)&&i+1<o&&56320==(64512&(a=t.charCodeAt(i+1)))&&(n=65536+(n-55296<<10)+(a-56320),i++),l+=n<128?1:n<2048?2:n<65536?3:4;for(e=new r.Buf8(l),s=0,i=0;s<l;i++)n=t.charCodeAt(i),55296==(64512&n)&&i+1<o&&56320==(64512&(a=t.charCodeAt(i+1)))&&(n=65536+(n-55296<<10)+(a-56320),i++),n<128?e[s++]=n:n<2048?(e[s++]=192|n>>>6,e[s++]=128|63&n):n<65536?(e[s++]=224|n>>>12,e[s++]=128|n>>>6&63,e[s++]=128|63&n):(e[s++]=240|n>>>18,e[s++]=128|n>>>12&63,e[s++]=128|n>>>6&63,e[s++]=128|63&n);return e},n.buf2binstring=function(t){return a(t,t.length)},n.binstring2buf=function(t){for(var e=new r.Buf8(t.length),n=0,a=e.length;n<a;n++)e[n]=t.charCodeAt(n);return e},n.buf2string=function(t,e){var n,r,i,s,l=e||t.length,h=new Array(2*l);for(r=0,n=0;n<l;)if((i=t[n++])<128)h[r++]=i;else if((s=o[i])>4)h[r++]=65533,n+=s-1;else{for(i&=2===s?31:3===s?15:7;s>1&&n<l;)i=i<<6|63&t[n++],s--;s>1?h[r++]=65533:i<65536?h[r++]=i:(i-=65536,h[r++]=55296|i>>10&1023,h[r++]=56320|1023&i)}return a(h,r)},n.utf8border=function(t,e){var n;for(e=e||t.length,e>t.length&&(e=t.length),n=e-1;n>=0&&128==(192&t[n]);)n--;return n<0?e:0===n?e:n+o[t[n]]>e?n:e}},{"./common":5}],7:[function(t,e,n){"use strict";function a(t,e,n,a){for(var r=65535&t|0,i=t>>>16&65535|0,s=0;0!==n;){s=n>2e3?2e3:n,n-=s;do{r=r+e[a++]|0,i=i+r|0}while(--s);r%=65521,i%=65521}return r|i<<16|0}e.exports=a},{}],8:[function(t,e,n){"use strict";function a(t,e,n,a){var i=r,s=a+n;t^=-1;for(var o=a;o<s;o++)t=t>>>8^i[255&(t^e[o])];return-1^t}var r=function(){for(var t,e=[],n=0;n<256;n++){t=n;for(var a=0;a<8;a++)t=1&t?3988292384^t>>>1:t>>>1;e[n]=t}return e}();e.exports=a},{}],9:[function(t,e,n){"use strict";function a(t,e){return t.msg=D[e],e}function r(t){return(t<<1)-(t>4?9:0)}function i(t){for(var e=t.length;--e>=0;)t[e]=0}function s(t){var e=t.state,n=e.pending;n>t.avail_out&&(n=t.avail_out),0!==n&&(O.arraySet(t.output,e.pending_buf,e.pending_out,n,t.next_out),t.next_out+=n,e.pending_out+=n,t.total_out+=n,t.avail_out-=n,e.pending-=n,0===e.pending&&(e.pending_out=0))}function o(t,e){Z._tr_flush_block(t,t.block_start>=0?t.block_start:-1,t.strstart-t.block_start,e),t.block_start=t.strstart,s(t.strm)}function l(t,e){t.pending_buf[t.pending++]=e}function h(t,e){t.pending_buf[t.pending++]=e>>>8&255,t.pending_buf[t.pending++]=255&e}function d(t,e,n,a){var r=t.avail_in;return r>a&&(r=a),0===r?0:(t.avail_in-=r,O.arraySet(e,t.input,t.next_in,r,n),1===t.state.wrap?t.adler=N(t.adler,e,r,n):2===t.state.wrap&&(t.adler=R(t.adler,e,r,n)),t.next_in+=r,t.total_in+=r,r)}function f(t,e){var n,a,r=t.max_chain_length,i=t.strstart,s=t.prev_length,o=t.nice_match,l=t.strstart>t.w_size-ht?t.strstart-(t.w_size-ht):0,h=t.window,d=t.w_mask,f=t.prev,u=t.strstart+lt,c=h[i+s-1],_=h[i+s];t.prev_length>=t.good_match&&(r>>=2),o>t.lookahead&&(o=t.lookahead);do{if(n=e,h[n+s]===_&&h[n+s-1]===c&&h[n]===h[i]&&h[++n]===h[i+1]){i+=2,n++;do{}while(h[++i]===h[++n]&&h[++i]===h[++n]&&h[++i]===h[++n]&&h[++i]===h[++n]&&h[++i]===h[++n]&&h[++i]===h[++n]&&h[++i]===h[++n]&&h[++i]===h[++n]&&i<u);if(a=lt-(u-i),i=u-lt,a>s){if(t.match_start=e,s=a,a>=o)break;c=h[i+s-1],_=h[i+s]}}}while((e=f[e&d])>l&&0!=--r);return s<=t.lookahead?s:t.lookahead}function u(t){var e,n,a,r,i,s=t.w_size;do{if(r=t.window_size-t.lookahead-t.strstart,t.strstart>=s+(s-ht)){O.arraySet(t.window,t.window,s,s,0),t.match_start-=s,t.strstart-=s,t.block_start-=s,n=t.hash_size,e=n;do{a=t.head[--e],t.head[e]=a>=s?a-s:0}while(--n);n=s,e=n;do{a=t.prev[--e],t.prev[e]=a>=s?a-s:0}while(--n);r+=s}if(0===t.strm.avail_in)break;if(n=d(t.strm,t.window,t.strstart+t.lookahead,r),t.lookahead+=n,t.lookahead+t.insert>=ot)for(i=t.strstart-t.insert,t.ins_h=t.window[i],t.ins_h=(t.ins_h<<t.hash_shift^t.window[i+1])&t.hash_mask;t.insert&&(t.ins_h=(t.ins_h<<t.hash_shift^t.window[i+ot-1])&t.hash_mask,t.prev[i&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=i,i++,t.insert--,!(t.lookahead+t.insert<ot)););}while(t.lookahead<ht&&0!==t.strm.avail_in)}function c(t,e){var n=65535;for(n>t.pending_buf_size-5&&(n=t.pending_buf_size-5);;){if(t.lookahead<=1){if(u(t),0===t.lookahead&&e===I)return bt;if(0===t.lookahead)break}t.strstart+=t.lookahead,t.lookahead=0;var a=t.block_start+n;if((0===t.strstart||t.strstart>=a)&&(t.lookahead=t.strstart-a,t.strstart=a,o(t,!1),0===t.strm.avail_out))return bt;if(t.strstart-t.block_start>=t.w_size-ht&&(o(t,!1),0===t.strm.avail_out))return bt}return t.insert=0,e===j?(o(t,!0),0===t.strm.avail_out?vt:kt):(t.strstart>t.block_start&&(o(t,!1),t.strm.avail_out),bt)}function _(t,e){for(var n,a;;){if(t.lookahead<ht){if(u(t),t.lookahead<ht&&e===I)return bt;if(0===t.lookahead)break}if(n=0,t.lookahead>=ot&&(t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+ot-1])&t.hash_mask,n=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),0!==n&&t.strstart-n<=t.w_size-ht&&(t.match_length=f(t,n)),t.match_length>=ot)if(a=Z._tr_tally(t,t.strstart-t.match_start,t.match_length-ot),t.lookahead-=t.match_length,t.match_length<=t.max_lazy_match&&t.lookahead>=ot){t.match_length--;do{t.strstart++,t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+ot-1])&t.hash_mask,n=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart}while(0!=--t.match_length);t.strstart++}else t.strstart+=t.match_length,t.match_length=0,t.ins_h=t.window[t.strstart],t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+1])&t.hash_mask;else a=Z._tr_tally(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++;if(a&&(o(t,!1),0===t.strm.avail_out))return bt}return t.insert=t.strstart<ot-1?t.strstart:ot-1,e===j?(o(t,!0),0===t.strm.avail_out?vt:kt):t.last_lit&&(o(t,!1),0===t.strm.avail_out)?bt:wt}function g(t,e){for(var n,a,r;;){if(t.lookahead<ht){if(u(t),t.lookahead<ht&&e===I)return bt;if(0===t.lookahead)break}if(n=0,t.lookahead>=ot&&(t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+ot-1])&t.hash_mask,n=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),t.prev_length=t.match_length,t.prev_match=t.match_start,t.match_length=ot-1,0!==n&&t.prev_length<t.max_lazy_match&&t.strstart-n<=t.w_size-ht&&(t.match_length=f(t,n),t.match_length<=5&&(t.strategy===Y||t.match_length===ot&&t.strstart-t.match_start>4096)&&(t.match_length=ot-1)),t.prev_length>=ot&&t.match_length<=t.prev_length){r=t.strstart+t.lookahead-ot,a=Z._tr_tally(t,t.strstart-1-t.prev_match,t.prev_length-ot),t.lookahead-=t.prev_length-1,t.prev_length-=2;do{++t.strstart<=r&&(t.ins_h=(t.ins_h<<t.hash_shift^t.window[t.strstart+ot-1])&t.hash_mask,n=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart)}while(0!=--t.prev_length);if(t.match_available=0,t.match_length=ot-1,t.strstart++,a&&(o(t,!1),0===t.strm.avail_out))return bt}else if(t.match_available){if(a=Z._tr_tally(t,0,t.window[t.strstart-1]),a&&o(t,!1),t.strstart++,t.lookahead--,0===t.strm.avail_out)return bt}else t.match_available=1,t.strstart++,t.lookahead--}return t.match_available&&(a=Z._tr_tally(t,0,t.window[t.strstart-1]),t.match_available=0),t.insert=t.strstart<ot-1?t.strstart:ot-1,e===j?(o(t,!0),0===t.strm.avail_out?vt:kt):t.last_lit&&(o(t,!1),0===t.strm.avail_out)?bt:wt}function p(t,e){for(var n,a,r,i,s=t.window;;){if(t.lookahead<=lt){if(u(t),t.lookahead<=lt&&e===I)return bt;if(0===t.lookahead)break}if(t.match_length=0,t.lookahead>=ot&&t.strstart>0&&(r=t.strstart-1,(a=s[r])===s[++r]&&a===s[++r]&&a===s[++r])){i=t.strstart+lt;do{}while(a===s[++r]&&a===s[++r]&&a===s[++r]&&a===s[++r]&&a===s[++r]&&a===s[++r]&&a===s[++r]&&a===s[++r]&&r<i);t.match_length=lt-(i-r),t.match_length>t.lookahead&&(t.match_length=t.lookahead)}if(t.match_length>=ot?(n=Z._tr_tally(t,1,t.match_length-ot),t.lookahead-=t.match_length,t.strstart+=t.match_length,t.match_length=0):(n=Z._tr_tally(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++),n&&(o(t,!1),0===t.strm.avail_out))return bt}return t.insert=0,e===j?(o(t,!0),0===t.strm.avail_out?vt:kt):t.last_lit&&(o(t,!1),0===t.strm.avail_out)?bt:wt}function m(t,e){for(var n;;){if(0===t.lookahead&&(u(t),0===t.lookahead)){if(e===I)return bt;break}if(t.match_length=0,n=Z._tr_tally(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++,n&&(o(t,!1),0===t.strm.avail_out))return bt}return t.insert=0,e===j?(o(t,!0),0===t.strm.avail_out?vt:kt):t.last_lit&&(o(t,!1),0===t.strm.avail_out)?bt:wt}function b(t,e,n,a,r){this.good_length=t,this.max_lazy=e,this.nice_length=n,this.max_chain=a,this.func=r}function w(t){t.window_size=2*t.w_size,i(t.head),t.max_lazy_match=E[t.level].max_lazy,t.good_match=E[t.level].good_length,t.nice_match=E[t.level].nice_length,t.max_chain_length=E[t.level].max_chain,t.strstart=0,t.block_start=0,t.lookahead=0,t.insert=0,t.match_length=t.prev_length=ot-1,t.match_available=0,t.ins_h=0}function v(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=Q,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new O.Buf16(2*it),this.dyn_dtree=new O.Buf16(2*(2*at+1)),this.bl_tree=new O.Buf16(2*(2*rt+1)),i(this.dyn_ltree),i(this.dyn_dtree),i(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new O.Buf16(st+1),this.heap=new O.Buf16(2*nt+1),i(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new O.Buf16(2*nt+1),i(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function k(t){var e;return t&&t.state?(t.total_in=t.total_out=0,t.data_type=J,e=t.state,e.pending=0,e.pending_out=0,e.wrap<0&&(e.wrap=-e.wrap),e.status=e.wrap?ft:pt,t.adler=2===e.wrap?0:1,e.last_flush=I,Z._tr_init(e),L):a(t,M)}function y(t){var e=k(t);return e===L&&w(t.state),e}function x(t,e){return t&&t.state?2!==t.state.wrap?M:(t.state.gzhead=e,L):M}function z(t,e,n,r,i,s){if(!t)return M;var o=1;if(e===K&&(e=6),r<0?(o=0,r=-r):r>15&&(o=2,r-=16),i<1||i>V||n!==Q||r<8||r>15||e<0||e>9||s<0||s>G)return a(t,M);8===r&&(r=9);var l=new v;return t.state=l,l.strm=t,l.wrap=o,l.gzhead=null,l.w_bits=r,l.w_size=1<<l.w_bits,l.w_mask=l.w_size-1,l.hash_bits=i+7,l.hash_size=1<<l.hash_bits,l.hash_mask=l.hash_size-1,l.hash_shift=~~((l.hash_bits+ot-1)/ot),l.window=new O.Buf8(2*l.w_size),l.head=new O.Buf16(l.hash_size),l.prev=new O.Buf16(l.w_size),l.lit_bufsize=1<<i+6,l.pending_buf_size=4*l.lit_bufsize,l.pending_buf=new O.Buf8(l.pending_buf_size),l.d_buf=1*l.lit_bufsize,l.l_buf=3*l.lit_bufsize,l.level=e,l.strategy=s,l.method=n,y(t)}function B(t,e){return z(t,e,Q,tt,et,X)}function C(t,e){var n,o,d,f;if(!t||!t.state||e>F||e<0)return t?a(t,M):M;if(o=t.state,!t.output||!t.input&&0!==t.avail_in||o.status===mt&&e!==j)return a(t,0===t.avail_out?W:M);if(o.strm=t,n=o.last_flush,o.last_flush=e,o.status===ft)if(2===o.wrap)t.adler=0,l(o,31),l(o,139),l(o,8),o.gzhead?(l(o,(o.gzhead.text?1:0)+(o.gzhead.hcrc?2:0)+(o.gzhead.extra?4:0)+(o.gzhead.name?8:0)+(o.gzhead.comment?16:0)),l(o,255&o.gzhead.time),l(o,o.gzhead.time>>8&255),l(o,o.gzhead.time>>16&255),l(o,o.gzhead.time>>24&255),l(o,9===o.level?2:o.strategy>=$||o.level<2?4:0),l(o,255&o.gzhead.os),o.gzhead.extra&&o.gzhead.extra.length&&(l(o,255&o.gzhead.extra.length),l(o,o.gzhead.extra.length>>8&255)),o.gzhead.hcrc&&(t.adler=R(t.adler,o.pending_buf,o.pending,0)),o.gzindex=0,o.status=ut):(l(o,0),l(o,0),l(o,0),l(o,0),l(o,0),l(o,9===o.level?2:o.strategy>=$||o.level<2?4:0),l(o,yt),o.status=pt);else{var u=Q+(o.w_bits-8<<4)<<8,c=-1;c=o.strategy>=$||o.level<2?0:o.level<6?1:6===o.level?2:3,u|=c<<6,0!==o.strstart&&(u|=dt),u+=31-u%31,o.status=pt,h(o,u),0!==o.strstart&&(h(o,t.adler>>>16),h(o,65535&t.adler)),t.adler=1}if(o.status===ut)if(o.gzhead.extra){for(d=o.pending;o.gzindex<(65535&o.gzhead.extra.length)&&(o.pending!==o.pending_buf_size||(o.gzhead.hcrc&&o.pending>d&&(t.adler=R(t.adler,o.pending_buf,o.pending-d,d)),s(t),d=o.pending,o.pending!==o.pending_buf_size));)l(o,255&o.gzhead.extra[o.gzindex]),o.gzindex++;o.gzhead.hcrc&&o.pending>d&&(t.adler=R(t.adler,o.pending_buf,o.pending-d,d)),o.gzindex===o.gzhead.extra.length&&(o.gzindex=0,o.status=ct)}else o.status=ct;if(o.status===ct)if(o.gzhead.name){d=o.pending;do{if(o.pending===o.pending_buf_size&&(o.gzhead.hcrc&&o.pending>d&&(t.adler=R(t.adler,o.pending_buf,o.pending-d,d)),s(t),d=o.pending,o.pending===o.pending_buf_size)){f=1;break}f=o.gzindex<o.gzhead.name.length?255&o.gzhead.name.charCodeAt(o.gzindex++):0,l(o,f)}while(0!==f);o.gzhead.hcrc&&o.pending>d&&(t.adler=R(t.adler,o.pending_buf,o.pending-d,d)),0===f&&(o.gzindex=0,o.status=_t)}else o.status=_t;if(o.status===_t)if(o.gzhead.comment){d=o.pending;do{if(o.pending===o.pending_buf_size&&(o.gzhead.hcrc&&o.pending>d&&(t.adler=R(t.adler,o.pending_buf,o.pending-d,d)),s(t),d=o.pending,o.pending===o.pending_buf_size)){f=1;break}f=o.gzindex<o.gzhead.comment.length?255&o.gzhead.comment.charCodeAt(o.gzindex++):0,l(o,f)}while(0!==f);o.gzhead.hcrc&&o.pending>d&&(t.adler=R(t.adler,o.pending_buf,o.pending-d,d)),0===f&&(o.status=gt)}else o.status=gt;if(o.status===gt&&(o.gzhead.hcrc?(o.pending+2>o.pending_buf_size&&s(t),o.pending+2<=o.pending_buf_size&&(l(o,255&t.adler),l(o,t.adler>>8&255),t.adler=0,o.status=pt)):o.status=pt),0!==o.pending){if(s(t),0===t.avail_out)return o.last_flush=-1,L}else if(0===t.avail_in&&r(e)<=r(n)&&e!==j)return a(t,W);if(o.status===mt&&0!==t.avail_in)return a(t,W);if(0!==t.avail_in||0!==o.lookahead||e!==I&&o.status!==mt){var _=o.strategy===$?m(o,e):o.strategy===q?p(o,e):E[o.level].func(o,e);if(_!==vt&&_!==kt||(o.status=mt),_===bt||_===vt)return 0===t.avail_out&&(o.last_flush=-1),L;if(_===wt&&(e===U?Z._tr_align(o):e!==F&&(Z._tr_stored_block(o,0,0,!1),e===T&&(i(o.head),0===o.lookahead&&(o.strstart=0,o.block_start=0,o.insert=0))),s(t),0===t.avail_out))return o.last_flush=-1,L}return e!==j?L:o.wrap<=0?H:(2===o.wrap?(l(o,255&t.adler),l(o,t.adler>>8&255),l(o,t.adler>>16&255),l(o,t.adler>>24&255),l(o,255&t.total_in),l(o,t.total_in>>8&255),l(o,t.total_in>>16&255),l(o,t.total_in>>24&255)):(h(o,t.adler>>>16),h(o,65535&t.adler)),s(t),o.wrap>0&&(o.wrap=-o.wrap),0!==o.pending?L:H)}function A(t){var e;return t&&t.state?(e=t.state.status)!==ft&&e!==ut&&e!==ct&&e!==_t&&e!==gt&&e!==pt&&e!==mt?a(t,M):(t.state=null,e===pt?a(t,P):L):M}function S(t,e){var n,a,r,s,o,l,h,d,f=e.length;if(!t||!t.state)return M;if(n=t.state,2===(s=n.wrap)||1===s&&n.status!==ft||n.lookahead)return M;for(1===s&&(t.adler=N(t.adler,e,f,0)),n.wrap=0,f>=n.w_size&&(0===s&&(i(n.head),n.strstart=0,n.block_start=0,n.insert=0),d=new O.Buf8(n.w_size),O.arraySet(d,e,f-n.w_size,n.w_size,0),e=d,f=n.w_size),o=t.avail_in,l=t.next_in,h=t.input,t.avail_in=f,t.next_in=0,t.input=e,u(n);n.lookahead>=ot;){a=n.strstart,r=n.lookahead-(ot-1);do{n.ins_h=(n.ins_h<<n.hash_shift^n.window[a+ot-1])&n.hash_mask,n.prev[a&n.w_mask]=n.head[n.ins_h],n.head[n.ins_h]=a,a++}while(--r);n.strstart=a,n.lookahead=ot-1,u(n)}return n.strstart+=n.lookahead,n.block_start=n.strstart,n.insert=n.lookahead,n.lookahead=0,n.match_length=n.prev_length=ot-1,n.match_available=0,t.next_in=l,t.input=h,t.avail_in=o,n.wrap=s,L}var E,O=t("../utils/common"),Z=t("./trees"),N=t("./adler32"),R=t("./crc32"),D=t("./messages"),I=0,U=1,T=3,j=4,F=5,L=0,H=1,M=-2,P=-3,W=-5,K=-1,Y=1,$=2,q=3,G=4,X=0,J=2,Q=8,V=9,tt=15,et=8,nt=286,at=30,rt=19,it=2*nt+1,st=15,ot=3,lt=258,ht=lt+ot+1,dt=32,ft=42,ut=69,ct=73,_t=91,gt=103,pt=113,mt=666,bt=1,wt=2,vt=3,kt=4,yt=3;E=[new b(0,0,0,0,c),new b(4,4,8,4,_),new b(4,5,16,8,_),new b(4,6,32,32,_),new b(4,4,16,16,g),new b(8,16,32,32,g),new b(8,16,128,128,g),new b(8,32,128,256,g),new b(32,128,258,1024,g),new b(32,258,258,4096,g)],n.deflateInit=B,n.deflateInit2=z,n.deflateReset=y,n.deflateResetKeep=k,n.deflateSetHeader=x,n.deflate=C,n.deflateEnd=A,n.deflateSetDictionary=S,n.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":5,"./adler32":7,"./crc32":8,"./messages":10,"./trees":11}],10:[function(t,e,n){"use strict";e.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],11:[function(t,e,n){"use strict";function a(t){for(var e=t.length;--e>=0;)t[e]=0}function r(t,e,n,a,r){this.static_tree=t,this.extra_bits=e,this.extra_base=n,this.elems=a,this.max_length=r,this.has_stree=t&&t.length}function i(t,e){this.dyn_tree=t,this.max_code=0,this.stat_desc=e}function s(t){return t<256?it[t]:it[256+(t>>>7)]}function o(t,e){t.pending_buf[t.pending++]=255&e,t.pending_buf[t.pending++]=e>>>8&255}function l(t,e,n){t.bi_valid>$-n?(t.bi_buf|=e<<t.bi_valid&65535,o(t,t.bi_buf),t.bi_buf=e>>$-t.bi_valid,t.bi_valid+=n-$):(t.bi_buf|=e<<t.bi_valid&65535,t.bi_valid+=n)}function h(t,e,n){l(t,n[2*e],n[2*e+1])}function d(t,e){var n=0;do{n|=1&t,t>>>=1,n<<=1}while(--e>0);return n>>>1}function f(t){16===t.bi_valid?(o(t,t.bi_buf),t.bi_buf=0,t.bi_valid=0):t.bi_valid>=8&&(t.pending_buf[t.pending++]=255&t.bi_buf,t.bi_buf>>=8,t.bi_valid-=8)}function u(t,e){var n,a,r,i,s,o,l=e.dyn_tree,h=e.max_code,d=e.stat_desc.static_tree,f=e.stat_desc.has_stree,u=e.stat_desc.extra_bits,c=e.stat_desc.extra_base,_=e.stat_desc.max_length,g=0;for(i=0;i<=Y;i++)t.bl_count[i]=0;for(l[2*t.heap[t.heap_max]+1]=0,n=t.heap_max+1;n<K;n++)a=t.heap[n],i=l[2*l[2*a+1]+1]+1,i>_&&(i=_,g++),l[2*a+1]=i,a>h||(t.bl_count[i]++,s=0,a>=c&&(s=u[a-c]),o=l[2*a],t.opt_len+=o*(i+s),f&&(t.static_len+=o*(d[2*a+1]+s)));if(0!==g){do{for(i=_-1;0===t.bl_count[i];)i--;t.bl_count[i]--,t.bl_count[i+1]+=2,t.bl_count[_]--,g-=2}while(g>0);for(i=_;0!==i;i--)for(a=t.bl_count[i];0!==a;)(r=t.heap[--n])>h||(l[2*r+1]!==i&&(t.opt_len+=(i-l[2*r+1])*l[2*r],l[2*r+1]=i),a--)}}function c(t,e,n){var a,r,i=new Array(Y+1),s=0;for(a=1;a<=Y;a++)i[a]=s=s+n[a-1]<<1;for(r=0;r<=e;r++){var o=t[2*r+1];0!==o&&(t[2*r]=d(i[o]++,o))}}function _(){var t,e,n,a,i,s=new Array(Y+1);for(n=0,a=0;a<L-1;a++)for(ot[a]=n,t=0;t<1<<V[a];t++)st[n++]=a;for(st[n-1]=a,i=0,a=0;a<16;a++)for(lt[a]=i,t=0;t<1<<tt[a];t++)it[i++]=a;for(i>>=7;a<P;a++)for(lt[a]=i<<7,t=0;t<1<<tt[a]-7;t++)it[256+i++]=a;for(e=0;e<=Y;e++)s[e]=0;for(t=0;t<=143;)at[2*t+1]=8,t++,s[8]++;for(;t<=255;)at[2*t+1]=9,t++,s[9]++;for(;t<=279;)at[2*t+1]=7,t++,s[7]++;for(;t<=287;)at[2*t+1]=8,t++,s[8]++;for(c(at,M+1,s),t=0;t<P;t++)rt[2*t+1]=5,rt[2*t]=d(t,5);ht=new r(at,V,H+1,M,Y),dt=new r(rt,tt,0,P,Y),ft=new r(new Array(0),et,0,W,q)}function g(t){var e;for(e=0;e<M;e++)t.dyn_ltree[2*e]=0;for(e=0;e<P;e++)t.dyn_dtree[2*e]=0;for(e=0;e<W;e++)t.bl_tree[2*e]=0;t.dyn_ltree[2*G]=1,t.opt_len=t.static_len=0,t.last_lit=t.matches=0}function p(t){t.bi_valid>8?o(t,t.bi_buf):t.bi_valid>0&&(t.pending_buf[t.pending++]=t.bi_buf),t.bi_buf=0,t.bi_valid=0}function m(t,e,n,a){p(t),a&&(o(t,n),o(t,~n)),N.arraySet(t.pending_buf,t.window,e,n,t.pending),t.pending+=n}function b(t,e,n,a){var r=2*e,i=2*n;return t[r]<t[i]||t[r]===t[i]&&a[e]<=a[n]}function w(t,e,n){for(var a=t.heap[n],r=n<<1;r<=t.heap_len&&(r<t.heap_len&&b(e,t.heap[r+1],t.heap[r],t.depth)&&r++,!b(e,a,t.heap[r],t.depth));)t.heap[n]=t.heap[r],n=r,r<<=1;t.heap[n]=a}function v(t,e,n){var a,r,i,o,d=0;if(0!==t.last_lit)do{a=t.pending_buf[t.d_buf+2*d]<<8|t.pending_buf[t.d_buf+2*d+1],r=t.pending_buf[t.l_buf+d],d++,0===a?h(t,r,e):(i=st[r],h(t,i+H+1,e),o=V[i],0!==o&&(r-=ot[i],l(t,r,o)),a--,i=s(a),h(t,i,n),0!==(o=tt[i])&&(a-=lt[i],l(t,a,o)))}while(d<t.last_lit);h(t,G,e)}function k(t,e){var n,a,r,i=e.dyn_tree,s=e.stat_desc.static_tree,o=e.stat_desc.has_stree,l=e.stat_desc.elems,h=-1;for(t.heap_len=0,t.heap_max=K,n=0;n<l;n++)0!==i[2*n]?(t.heap[++t.heap_len]=h=n,t.depth[n]=0):i[2*n+1]=0;for(;t.heap_len<2;)r=t.heap[++t.heap_len]=h<2?++h:0,i[2*r]=1,t.depth[r]=0,t.opt_len--,o&&(t.static_len-=s[2*r+1]);for(e.max_code=h,n=t.heap_len>>1;n>=1;n--)w(t,i,n);r=l;do{n=t.heap[1],t.heap[1]=t.heap[t.heap_len--],w(t,i,1),a=t.heap[1],t.heap[--t.heap_max]=n,t.heap[--t.heap_max]=a,i[2*r]=i[2*n]+i[2*a],t.depth[r]=(t.depth[n]>=t.depth[a]?t.depth[n]:t.depth[a])+1,i[2*n+1]=i[2*a+1]=r,t.heap[1]=r++,w(t,i,1)}while(t.heap_len>=2);t.heap[--t.heap_max]=t.heap[1],u(t,e),c(i,h,t.bl_count)}function y(t,e,n){var a,r,i=-1,s=e[1],o=0,l=7,h=4;for(0===s&&(l=138,h=3),e[2*(n+1)+1]=65535,a=0;a<=n;a++)r=s,s=e[2*(a+1)+1],++o<l&&r===s||(o<h?t.bl_tree[2*r]+=o:0!==r?(r!==i&&t.bl_tree[2*r]++,t.bl_tree[2*X]++):o<=10?t.bl_tree[2*J]++:t.bl_tree[2*Q]++,o=0,i=r,0===s?(l=138,h=3):r===s?(l=6,h=3):(l=7,h=4))}function x(t,e,n){var a,r,i=-1,s=e[1],o=0,d=7,f=4;for(0===s&&(d=138,f=3),a=0;a<=n;a++)if(r=s,s=e[2*(a+1)+1],!(++o<d&&r===s)){if(o<f)do{h(t,r,t.bl_tree)}while(0!=--o);else 0!==r?(r!==i&&(h(t,r,t.bl_tree),o--),h(t,X,t.bl_tree),l(t,o-3,2)):o<=10?(h(t,J,t.bl_tree),l(t,o-3,3)):(h(t,Q,t.bl_tree),l(t,o-11,7));o=0,i=r,0===s?(d=138,f=3):r===s?(d=6,f=3):(d=7,f=4)}}function z(t){var e;for(y(t,t.dyn_ltree,t.l_desc.max_code),y(t,t.dyn_dtree,t.d_desc.max_code),k(t,t.bl_desc),e=W-1;e>=3&&0===t.bl_tree[2*nt[e]+1];e--);return t.opt_len+=3*(e+1)+5+5+4,e}function B(t,e,n,a){var r;for(l(t,e-257,5),l(t,n-1,5),l(t,a-4,4),r=0;r<a;r++)l(t,t.bl_tree[2*nt[r]+1],3);x(t,t.dyn_ltree,e-1),x(t,t.dyn_dtree,n-1)}function C(t){var e,n=4093624447;for(e=0;e<=31;e++,n>>>=1)if(1&n&&0!==t.dyn_ltree[2*e])return D;if(0!==t.dyn_ltree[18]||0!==t.dyn_ltree[20]||0!==t.dyn_ltree[26])return I;for(e=32;e<H;e++)if(0!==t.dyn_ltree[2*e])return I;return D}function A(t){ut||(_(),ut=!0),t.l_desc=new i(t.dyn_ltree,ht),t.d_desc=new i(t.dyn_dtree,dt),t.bl_desc=new i(t.bl_tree,ft),t.bi_buf=0,t.bi_valid=0,g(t)}function S(t,e,n,a){l(t,(T<<1)+(a?1:0),3),m(t,e,n,!0)}function E(t){l(t,j<<1,3),h(t,G,at),f(t)}function O(t,e,n,a){var r,i,s=0;t.level>0?(t.strm.data_type===U&&(t.strm.data_type=C(t)),k(t,t.l_desc),k(t,t.d_desc),s=z(t),r=t.opt_len+3+7>>>3,(i=t.static_len+3+7>>>3)<=r&&(r=i)):r=i=n+5,n+4<=r&&-1!==e?S(t,e,n,a):t.strategy===R||i===r?(l(t,(j<<1)+(a?1:0),3),v(t,at,rt)):(l(t,(F<<1)+(a?1:0),3),B(t,t.l_desc.max_code+1,t.d_desc.max_code+1,s+1),v(t,t.dyn_ltree,t.dyn_dtree)),g(t),a&&p(t)}function Z(t,e,n){return t.pending_buf[t.d_buf+2*t.last_lit]=e>>>8&255,t.pending_buf[t.d_buf+2*t.last_lit+1]=255&e,t.pending_buf[t.l_buf+t.last_lit]=255&n,t.last_lit++,0===e?t.dyn_ltree[2*n]++:(t.matches++,e--,t.dyn_ltree[2*(st[n]+H+1)]++,t.dyn_dtree[2*s(e)]++),t.last_lit===t.lit_bufsize-1}var N=t("../utils/common"),R=4,D=0,I=1,U=2,T=0,j=1,F=2,L=29,H=256,M=H+1+L,P=30,W=19,K=2*M+1,Y=15,$=16,q=7,G=256,X=16,J=17,Q=18,V=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],tt=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],et=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],nt=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],at=new Array(2*(M+2));a(at);var rt=new Array(2*P);a(rt);var it=new Array(512);a(it);var st=new Array(256);a(st);var ot=new Array(L);a(ot);var lt=new Array(P);a(lt);var ht,dt,ft,ut=!1;n._tr_init=A,n._tr_stored_block=S,n._tr_flush_block=O,n._tr_tally=Z,n._tr_align=E},{"../utils/common":5}],12:[function(t,e,n){"use strict";function a(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}e.exports=a},{}]},{},[3])(3)})},function(t,e,n){var a,a;!function(e){t.exports=e()}(function(){return function(){function t(e,n,r){function i(o,l){if(!n[o]){if(!e[o]){var h="function"==typeof a&&a;if(!l&&h)return a(o,!0);if(s)return s(o,!0);var d=new Error("Cannot find module '"+o+"'");throw d.code="MODULE_NOT_FOUND",d}var f=n[o]={exports:{}};e[o][0].call(f.exports,function(t){return i(e[o][1][t]||t)},f,f.exports,t,e,n,r)}return n[o].exports}for(var s="function"==typeof a&&a,o=0;o<r.length;o++)i(r[o]);return i}return t}()({1:[function(t,e,n){"use strict";var a=t("pako/lib/inflate.js");e.exports=function(t){return a.inflateRaw(t,{to:"string"})}},{"pako/lib/inflate.js":4}],2:[function(t,e,n){"use strict";function a(t){var e=t.charCodeAt(0);return"_"===t?63:"-"===t?62:e>=97?e-61:e>=65?e-55:e>=48?e-48:"?"}function r(t){var e=a(t[0]),n=a(t[1]),r=a(t[2]);return[e<<2|n>>4&63,n<<4&240|r>>2&15,r<<6&192|63&a(t[3])]}e.exports=function(t){var e="",n=0;for(n=0;n<t.length;n+=4){var a=r(t.substring(n,n+4));e+=String.fromCharCode(a[0]),e+=String.fromCharCode(a[1]),e+=String.fromCharCode(a[2])}return e}},{}],3:[function(t,e,n){"use strict";var a=t("./inflate"),r=t("./decode64");e.exports.decode=function(t){var e=r(t);return a(e)}},{"./decode64":2,"./inflate":1}],4:[function(t,e,n){"use strict";function a(t){if(!(this instanceof a))return new a(t);this.options=o.assign({chunkSize:16384,windowBits:0,to:""},t||{});var e=this.options;e.raw&&e.windowBits>=0&&e.windowBits<16&&(e.windowBits=-e.windowBits,0===e.windowBits&&(e.windowBits=-15)),!(e.windowBits>=0&&e.windowBits<16)||t&&t.windowBits||(e.windowBits+=32),e.windowBits>15&&e.windowBits<48&&0==(15&e.windowBits)&&(e.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new f,this.strm.avail_out=0;var n=s.inflateInit2(this.strm,e.windowBits);if(n!==h.Z_OK)throw new Error(d[n]);if(this.header=new u,s.inflateGetHeader(this.strm,this.header),e.dictionary&&("string"==typeof e.dictionary?e.dictionary=l.string2buf(e.dictionary):"[object ArrayBuffer]"===c.call(e.dictionary)&&(e.dictionary=new Uint8Array(e.dictionary)),e.raw&&(n=s.inflateSetDictionary(this.strm,e.dictionary))!==h.Z_OK))throw new Error(d[n])}function r(t,e){var n=new a(e);if(n.push(t,!0),n.err)throw n.msg||d[n.err];return n.result}function i(t,e){return e=e||{},e.raw=!0,r(t,e)}var s=t("./zlib/inflate"),o=t("./utils/common"),l=t("./utils/strings"),h=t("./zlib/constants"),d=t("./zlib/messages"),f=t("./zlib/zstream"),u=t("./zlib/gzheader"),c=Object.prototype.toString;a.prototype.push=function(t,e){var n,a,r,i,d,f=this.strm,u=this.options.chunkSize,_=this.options.dictionary,g=!1;if(this.ended)return!1;a=e===~~e?e:!0===e?h.Z_FINISH:h.Z_NO_FLUSH,"string"==typeof t?f.input=l.binstring2buf(t):"[object ArrayBuffer]"===c.call(t)?f.input=new Uint8Array(t):f.input=t,f.next_in=0,f.avail_in=f.input.length;do{if(0===f.avail_out&&(f.output=new o.Buf8(u),f.next_out=0,f.avail_out=u),n=s.inflate(f,h.Z_NO_FLUSH),n===h.Z_NEED_DICT&&_&&(n=s.inflateSetDictionary(this.strm,_)),n===h.Z_BUF_ERROR&&!0===g&&(n=h.Z_OK,g=!1),n!==h.Z_STREAM_END&&n!==h.Z_OK)return this.onEnd(n),this.ended=!0,!1;f.next_out&&(0!==f.avail_out&&n!==h.Z_STREAM_END&&(0!==f.avail_in||a!==h.Z_FINISH&&a!==h.Z_SYNC_FLUSH)||("string"===this.options.to?(r=l.utf8border(f.output,f.next_out),i=f.next_out-r,d=l.buf2string(f.output,r),f.next_out=i,f.avail_out=u-i,i&&o.arraySet(f.output,f.output,r,i,0),this.onData(d)):this.onData(o.shrinkBuf(f.output,f.next_out)))),0===f.avail_in&&0===f.avail_out&&(g=!0)}while((f.avail_in>0||0===f.avail_out)&&n!==h.Z_STREAM_END);return n===h.Z_STREAM_END&&(a=h.Z_FINISH),a===h.Z_FINISH?(n=s.inflateEnd(this.strm),this.onEnd(n),this.ended=!0,n===h.Z_OK):a!==h.Z_SYNC_FLUSH||(this.onEnd(h.Z_OK),f.avail_out=0,!0)},a.prototype.onData=function(t){this.chunks.push(t)},a.prototype.onEnd=function(t){t===h.Z_OK&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=o.flattenChunks(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg},n.Inflate=a,n.inflate=r,n.inflateRaw=i,n.ungzip=r},{"./utils/common":5,"./utils/strings":6,"./zlib/constants":8,"./zlib/gzheader":10,"./zlib/inflate":12,"./zlib/messages":14,"./zlib/zstream":15}],5:[function(t,e,n){"use strict";function a(t,e){return Object.prototype.hasOwnProperty.call(t,e)}var r="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;n.assign=function(t){for(var e=Array.prototype.slice.call(arguments,1);e.length;){var n=e.shift();if(n){if("object"!=typeof n)throw new TypeError(n+"must be non-object");for(var r in n)a(n,r)&&(t[r]=n[r])}}return t},n.shrinkBuf=function(t,e){return t.length===e?t:t.subarray?t.subarray(0,e):(t.length=e,t)};var i={arraySet:function(t,e,n,a,r){if(e.subarray&&t.subarray)return void t.set(e.subarray(n,n+a),r);for(var i=0;i<a;i++)t[r+i]=e[n+i]},flattenChunks:function(t){var e,n,a,r,i,s;for(a=0,e=0,n=t.length;e<n;e++)a+=t[e].length;for(s=new Uint8Array(a),r=0,e=0,n=t.length;e<n;e++)i=t[e],s.set(i,r),r+=i.length;return s}},s={arraySet:function(t,e,n,a,r){for(var i=0;i<a;i++)t[r+i]=e[n+i]},flattenChunks:function(t){return[].concat.apply([],t)}};n.setTyped=function(t){t?(n.Buf8=Uint8Array,n.Buf16=Uint16Array,n.Buf32=Int32Array,n.assign(n,i)):(n.Buf8=Array,n.Buf16=Array,n.Buf32=Array,n.assign(n,s))},n.setTyped(r)},{}],6:[function(t,e,n){"use strict";function a(t,e){if(e<65534&&(t.subarray&&s||!t.subarray&&i))return String.fromCharCode.apply(null,r.shrinkBuf(t,e));for(var n="",a=0;a<e;a++)n+=String.fromCharCode(t[a]);return n}var r=t("./common"),i=!0,s=!0;try{String.fromCharCode.apply(null,[0])}catch(t){i=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(t){s=!1}for(var o=new r.Buf8(256),l=0;l<256;l++)o[l]=l>=252?6:l>=248?5:l>=240?4:l>=224?3:l>=192?2:1;o[254]=o[254]=1,n.string2buf=function(t){var e,n,a,i,s,o=t.length,l=0;for(i=0;i<o;i++)n=t.charCodeAt(i),55296==(64512&n)&&i+1<o&&56320==(64512&(a=t.charCodeAt(i+1)))&&(n=65536+(n-55296<<10)+(a-56320),i++),l+=n<128?1:n<2048?2:n<65536?3:4;for(e=new r.Buf8(l),s=0,i=0;s<l;i++)n=t.charCodeAt(i),55296==(64512&n)&&i+1<o&&56320==(64512&(a=t.charCodeAt(i+1)))&&(n=65536+(n-55296<<10)+(a-56320),i++),n<128?e[s++]=n:n<2048?(e[s++]=192|n>>>6,e[s++]=128|63&n):n<65536?(e[s++]=224|n>>>12,e[s++]=128|n>>>6&63,e[s++]=128|63&n):(e[s++]=240|n>>>18,e[s++]=128|n>>>12&63,e[s++]=128|n>>>6&63,e[s++]=128|63&n);return e},n.buf2binstring=function(t){return a(t,t.length)},n.binstring2buf=function(t){for(var e=new r.Buf8(t.length),n=0,a=e.length;n<a;n++)e[n]=t.charCodeAt(n);return e},n.buf2string=function(t,e){var n,r,i,s,l=e||t.length,h=new Array(2*l);for(r=0,n=0;n<l;)if((i=t[n++])<128)h[r++]=i;else if((s=o[i])>4)h[r++]=65533,n+=s-1;else{for(i&=2===s?31:3===s?15:7;s>1&&n<l;)i=i<<6|63&t[n++],s--;s>1?h[r++]=65533:i<65536?h[r++]=i:(i-=65536,h[r++]=55296|i>>10&1023,h[r++]=56320|1023&i)}return a(h,r)},n.utf8border=function(t,e){var n;for(e=e||t.length,e>t.length&&(e=t.length),n=e-1;n>=0&&128==(192&t[n]);)n--;return n<0?e:0===n?e:n+o[t[n]]>e?n:e}},{"./common":5}],7:[function(t,e,n){"use strict";function a(t,e,n,a){for(var r=65535&t|0,i=t>>>16&65535|0,s=0;0!==n;){s=n>2e3?2e3:n,n-=s;do{r=r+e[a++]|0,i=i+r|0}while(--s);r%=65521,i%=65521}return r|i<<16|0}e.exports=a},{}],8:[function(t,e,n){"use strict";e.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],9:[function(t,e,n){"use strict";function a(t,e,n,a){var i=r,s=a+n;t^=-1;for(var o=a;o<s;o++)t=t>>>8^i[255&(t^e[o])];return-1^t}var r=function(){for(var t,e=[],n=0;n<256;n++){t=n;for(var a=0;a<8;a++)t=1&t?3988292384^t>>>1:t>>>1;e[n]=t}return e}();e.exports=a},{}],10:[function(t,e,n){"use strict";function a(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}e.exports=a},{}],11:[function(t,e,n){"use strict";e.exports=function(t,e){var n,a,r,i,s,o,l,h,d,f,u,c,_,g,p,m,b,w,v,k,y,x,z,B,C;n=t.state,a=t.next_in,B=t.input,r=a+(t.avail_in-5),i=t.next_out,C=t.output,s=i-(e-t.avail_out),o=i+(t.avail_out-257),l=n.dmax,h=n.wsize,d=n.whave,f=n.wnext,u=n.window,c=n.hold,_=n.bits,g=n.lencode,p=n.distcode,m=(1<<n.lenbits)-1,b=(1<<n.distbits)-1;t:do{_<15&&(c+=B[a++]<<_,_+=8,c+=B[a++]<<_,_+=8),w=g[c&m];e:for(;;){if(v=w>>>24,c>>>=v,_-=v,0===(v=w>>>16&255))C[i++]=65535&w;else{if(!(16&v)){if(0==(64&v)){w=g[(65535&w)+(c&(1<<v)-1)];continue e}if(32&v){n.mode=12;break t}t.msg="invalid literal/length code",n.mode=30;break t}k=65535&w,v&=15,v&&(_<v&&(c+=B[a++]<<_,_+=8),k+=c&(1<<v)-1,c>>>=v,_-=v),_<15&&(c+=B[a++]<<_,_+=8,c+=B[a++]<<_,_+=8),w=p[c&b];n:for(;;){if(v=w>>>24,c>>>=v,_-=v,!(16&(v=w>>>16&255))){if(0==(64&v)){w=p[(65535&w)+(c&(1<<v)-1)];continue n}t.msg="invalid distance code",n.mode=30;break t}if(y=65535&w,v&=15,_<v&&(c+=B[a++]<<_,(_+=8)<v&&(c+=B[a++]<<_,_+=8)),(y+=c&(1<<v)-1)>l){t.msg="invalid distance too far back",n.mode=30;break t}if(c>>>=v,_-=v,v=i-s,y>v){if((v=y-v)>d&&n.sane){t.msg="invalid distance too far back",n.mode=30;break t}if(x=0,z=u,0===f){if(x+=h-v,v<k){k-=v;do{C[i++]=u[x++]}while(--v);x=i-y,z=C}}else if(f<v){if(x+=h+f-v,(v-=f)<k){k-=v;do{C[i++]=u[x++]}while(--v);if(x=0,f<k){v=f,k-=v;do{C[i++]=u[x++]}while(--v);x=i-y,z=C}}}else if(x+=f-v,v<k){k-=v;do{C[i++]=u[x++]}while(--v);x=i-y,z=C}for(;k>2;)C[i++]=z[x++],C[i++]=z[x++],C[i++]=z[x++],k-=3;k&&(C[i++]=z[x++],k>1&&(C[i++]=z[x++]))}else{x=i-y;do{C[i++]=C[x++],C[i++]=C[x++],C[i++]=C[x++],k-=3}while(k>2);k&&(C[i++]=C[x++],k>1&&(C[i++]=C[x++]))}break}}break}}while(a<r&&i<o);k=_>>3,a-=k,_-=k<<3,c&=(1<<_)-1,t.next_in=a,t.next_out=i,t.avail_in=a<r?r-a+5:5-(a-r),t.avail_out=i<o?o-i+257:257-(i-o),n.hold=c,n.bits=_}},{}],12:[function(t,e,n){"use strict";function a(t){return(t>>>24&255)+(t>>>8&65280)+((65280&t)<<8)+((255&t)<<24)}function r(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new b.Buf16(320),this.work=new b.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function i(t){var e;return t&&t.state?(e=t.state,t.total_in=t.total_out=e.total=0,t.msg="",e.wrap&&(t.adler=1&e.wrap),e.mode=T,e.last=0,e.havedict=0,e.dmax=32768,e.head=null,e.hold=0,e.bits=0,e.lencode=e.lendyn=new b.Buf32(gt),e.distcode=e.distdyn=new b.Buf32(pt),e.sane=1,e.back=-1,E):N}function s(t){var e;return t&&t.state?(e=t.state,e.wsize=0,e.whave=0,e.wnext=0,i(t)):N}function o(t,e){var n,a;return t&&t.state?(a=t.state,e<0?(n=0,e=-e):(n=1+(e>>4),e<48&&(e&=15)),e&&(e<8||e>15)?N:(null!==a.window&&a.wbits!==e&&(a.window=null),a.wrap=n,a.wbits=e,s(t))):N}function l(t,e){var n,a;return t?(a=new r,t.state=a,a.window=null,n=o(t,e),n!==E&&(t.state=null),n):N}function h(t){return l(t,mt)}function d(t){if(bt){var e;for(p=new b.Buf32(512),m=new b.Buf32(32),e=0;e<144;)t.lens[e++]=8;for(;e<256;)t.lens[e++]=9;for(;e<280;)t.lens[e++]=7;for(;e<288;)t.lens[e++]=8;for(y(z,t.lens,0,288,p,0,t.work,{bits:9}),e=0;e<32;)t.lens[e++]=5;y(B,t.lens,0,32,m,0,t.work,{bits:5}),bt=!1}t.lencode=p,t.lenbits=9,t.distcode=m,t.distbits=5}function f(t,e,n,a){var r,i=t.state;return null===i.window&&(i.wsize=1<<i.wbits,i.wnext=0,i.whave=0,i.window=new b.Buf8(i.wsize)),a>=i.wsize?(b.arraySet(i.window,e,n-i.wsize,i.wsize,0),i.wnext=0,i.whave=i.wsize):(r=i.wsize-i.wnext,r>a&&(r=a),b.arraySet(i.window,e,n-a,r,i.wnext),a-=r,a?(b.arraySet(i.window,e,n-a,a,0),i.wnext=a,i.whave=i.wsize):(i.wnext+=r,i.wnext===i.wsize&&(i.wnext=0),i.whave<i.wsize&&(i.whave+=r))),0}function u(t,e){var n,r,i,s,o,l,h,u,c,_,g,p,m,gt,pt,mt,bt,wt,vt,kt,yt,xt,zt,Bt,Ct=0,At=new b.Buf8(4),St=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!t||!t.state||!t.output||!t.input&&0!==t.avail_in)return N;n=t.state,n.mode===q&&(n.mode=G),o=t.next_out,i=t.output,h=t.avail_out,s=t.next_in,r=t.input,l=t.avail_in,u=n.hold,c=n.bits,_=l,g=h,xt=E;t:for(;;)switch(n.mode){case T:if(0===n.wrap){n.mode=G;break}for(;c<16;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}if(2&n.wrap&&35615===u){n.check=0,At[0]=255&u,At[1]=u>>>8&255,n.check=v(n.check,At,2,0),u=0,c=0,n.mode=j;break}if(n.flags=0,n.head&&(n.head.done=!1),!(1&n.wrap)||(((255&u)<<8)+(u>>8))%31){t.msg="incorrect header check",n.mode=ut;break}if((15&u)!==U){t.msg="unknown compression method",n.mode=ut;break}if(u>>>=4,c-=4,yt=8+(15&u),0===n.wbits)n.wbits=yt;else if(yt>n.wbits){t.msg="invalid window size",n.mode=ut;break}n.dmax=1<<yt,t.adler=n.check=1,n.mode=512&u?Y:q,u=0,c=0;break;case j:for(;c<16;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}if(n.flags=u,(255&n.flags)!==U){t.msg="unknown compression method",n.mode=ut;break}if(57344&n.flags){t.msg="unknown header flags set",n.mode=ut;break}n.head&&(n.head.text=u>>8&1),512&n.flags&&(At[0]=255&u,At[1]=u>>>8&255,n.check=v(n.check,At,2,0)),u=0,c=0,n.mode=F;case F:for(;c<32;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}n.head&&(n.head.time=u),512&n.flags&&(At[0]=255&u,At[1]=u>>>8&255,At[2]=u>>>16&255,At[3]=u>>>24&255,n.check=v(n.check,At,4,0)),u=0,c=0,n.mode=L;case L:for(;c<16;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}n.head&&(n.head.xflags=255&u,n.head.os=u>>8),512&n.flags&&(At[0]=255&u,At[1]=u>>>8&255,n.check=v(n.check,At,2,0)),u=0,c=0,n.mode=H;case H:if(1024&n.flags){for(;c<16;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}n.length=u,n.head&&(n.head.extra_len=u),512&n.flags&&(At[0]=255&u,At[1]=u>>>8&255,n.check=v(n.check,At,2,0)),u=0,c=0}else n.head&&(n.head.extra=null);n.mode=M;case M:if(1024&n.flags&&(p=n.length,p>l&&(p=l),p&&(n.head&&(yt=n.head.extra_len-n.length,n.head.extra||(n.head.extra=new Array(n.head.extra_len)),b.arraySet(n.head.extra,r,s,p,yt)),512&n.flags&&(n.check=v(n.check,r,p,s)),l-=p,s+=p,n.length-=p),n.length))break t;n.length=0,n.mode=P;case P:if(2048&n.flags){if(0===l)break t;p=0;do{yt=r[s+p++],n.head&&yt&&n.length<65536&&(n.head.name+=String.fromCharCode(yt))}while(yt&&p<l);if(512&n.flags&&(n.check=v(n.check,r,p,s)),l-=p,s+=p,yt)break t}else n.head&&(n.head.name=null);n.length=0,n.mode=W;case W:if(4096&n.flags){if(0===l)break t;p=0;do{yt=r[s+p++],n.head&&yt&&n.length<65536&&(n.head.comment+=String.fromCharCode(yt))}while(yt&&p<l);if(512&n.flags&&(n.check=v(n.check,r,p,s)),l-=p,s+=p,yt)break t}else n.head&&(n.head.comment=null);n.mode=K;case K:if(512&n.flags){for(;c<16;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}if(u!==(65535&n.check)){t.msg="header crc mismatch",n.mode=ut;break}u=0,c=0}n.head&&(n.head.hcrc=n.flags>>9&1,n.head.done=!0),t.adler=n.check=0,n.mode=q;break;case Y:for(;c<32;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}t.adler=n.check=a(u),u=0,c=0,n.mode=$;case $:if(0===n.havedict)return t.next_out=o,t.avail_out=h,t.next_in=s,t.avail_in=l,n.hold=u,n.bits=c,Z;t.adler=n.check=1,n.mode=q;case q:if(e===A||e===S)break t;case G:if(n.last){u>>>=7&c,c-=7&c,n.mode=ht;break}for(;c<3;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}switch(n.last=1&u,u>>>=1,c-=1,3&u){case 0:n.mode=X;break;case 1:if(d(n),n.mode=nt,e===S){u>>>=2,c-=2;break t}break;case 2:n.mode=V;break;case 3:t.msg="invalid block type",n.mode=ut}u>>>=2,c-=2;break;case X:for(u>>>=7&c,c-=7&c;c<32;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}if((65535&u)!=(u>>>16^65535)){t.msg="invalid stored block lengths",n.mode=ut;break}if(n.length=65535&u,u=0,c=0,n.mode=J,e===S)break t;case J:n.mode=Q;case Q:if(p=n.length){if(p>l&&(p=l),p>h&&(p=h),0===p)break t;b.arraySet(i,r,s,p,o),l-=p,s+=p,h-=p,o+=p,n.length-=p;break}n.mode=q;break;case V:for(;c<14;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}if(n.nlen=257+(31&u),u>>>=5,c-=5,n.ndist=1+(31&u),u>>>=5,c-=5,n.ncode=4+(15&u),u>>>=4,c-=4,n.nlen>286||n.ndist>30){t.msg="too many length or distance symbols",n.mode=ut;break}n.have=0,n.mode=tt;case tt:for(;n.have<n.ncode;){for(;c<3;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}n.lens[St[n.have++]]=7&u,u>>>=3,c-=3}for(;n.have<19;)n.lens[St[n.have++]]=0;if(n.lencode=n.lendyn,n.lenbits=7,zt={bits:n.lenbits},xt=y(x,n.lens,0,19,n.lencode,0,n.work,zt),n.lenbits=zt.bits,xt){t.msg="invalid code lengths set",n.mode=ut;break}n.have=0,n.mode=et;case et:for(;n.have<n.nlen+n.ndist;){for(;Ct=n.lencode[u&(1<<n.lenbits)-1],pt=Ct>>>24,mt=Ct>>>16&255,bt=65535&Ct,!(pt<=c);){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}if(bt<16)u>>>=pt,c-=pt,n.lens[n.have++]=bt;else{if(16===bt){for(Bt=pt+2;c<Bt;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}if(u>>>=pt,c-=pt,0===n.have){t.msg="invalid bit length repeat",n.mode=ut;break}yt=n.lens[n.have-1],p=3+(3&u),u>>>=2,c-=2}else if(17===bt){for(Bt=pt+3;c<Bt;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}u>>>=pt,c-=pt,yt=0,p=3+(7&u),u>>>=3,c-=3}else{for(Bt=pt+7;c<Bt;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}u>>>=pt,c-=pt,yt=0,p=11+(127&u),u>>>=7,c-=7}if(n.have+p>n.nlen+n.ndist){t.msg="invalid bit length repeat",n.mode=ut;break}for(;p--;)n.lens[n.have++]=yt}}if(n.mode===ut)break;if(0===n.lens[256]){t.msg="invalid code -- missing end-of-block",n.mode=ut;break}if(n.lenbits=9,zt={bits:n.lenbits},xt=y(z,n.lens,0,n.nlen,n.lencode,0,n.work,zt),n.lenbits=zt.bits,xt){t.msg="invalid literal/lengths set",n.mode=ut;break}if(n.distbits=6,n.distcode=n.distdyn,zt={bits:n.distbits},xt=y(B,n.lens,n.nlen,n.ndist,n.distcode,0,n.work,zt),n.distbits=zt.bits,xt){t.msg="invalid distances set",n.mode=ut;break}if(n.mode=nt,e===S)break t;case nt:n.mode=at;case at:if(l>=6&&h>=258){t.next_out=o,t.avail_out=h,t.next_in=s,t.avail_in=l,n.hold=u,n.bits=c,k(t,g),o=t.next_out,i=t.output,h=t.avail_out,s=t.next_in,r=t.input,l=t.avail_in,u=n.hold,c=n.bits,n.mode===q&&(n.back=-1);break}for(n.back=0;Ct=n.lencode[u&(1<<n.lenbits)-1],pt=Ct>>>24,mt=Ct>>>16&255,bt=65535&Ct,!(pt<=c);){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}if(mt&&0==(240&mt)){for(wt=pt,vt=mt,kt=bt;Ct=n.lencode[kt+((u&(1<<wt+vt)-1)>>wt)],pt=Ct>>>24,mt=Ct>>>16&255,bt=65535&Ct,!(wt+pt<=c);){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}u>>>=wt,c-=wt,n.back+=wt}if(u>>>=pt,c-=pt,n.back+=pt,n.length=bt,0===mt){n.mode=lt;break}if(32&mt){n.back=-1,n.mode=q;break}if(64&mt){t.msg="invalid literal/length code",n.mode=ut;break}n.extra=15&mt,n.mode=rt;case rt:if(n.extra){for(Bt=n.extra;c<Bt;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}n.length+=u&(1<<n.extra)-1,u>>>=n.extra,c-=n.extra,n.back+=n.extra}n.was=n.length,n.mode=it;case it:for(;Ct=n.distcode[u&(1<<n.distbits)-1],pt=Ct>>>24,mt=Ct>>>16&255,bt=65535&Ct,!(pt<=c);){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}if(0==(240&mt)){for(wt=pt,vt=mt,kt=bt;Ct=n.distcode[kt+((u&(1<<wt+vt)-1)>>wt)],pt=Ct>>>24,mt=Ct>>>16&255,bt=65535&Ct,!(wt+pt<=c);){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}u>>>=wt,c-=wt,n.back+=wt}if(u>>>=pt,c-=pt,n.back+=pt,64&mt){t.msg="invalid distance code",n.mode=ut;break}n.offset=bt,n.extra=15&mt,n.mode=st;case st:if(n.extra){for(Bt=n.extra;c<Bt;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}n.offset+=u&(1<<n.extra)-1,u>>>=n.extra,c-=n.extra,n.back+=n.extra}if(n.offset>n.dmax){t.msg="invalid distance too far back",n.mode=ut;break}n.mode=ot;case ot:if(0===h)break t;if(p=g-h,n.offset>p){if((p=n.offset-p)>n.whave&&n.sane){t.msg="invalid distance too far back",n.mode=ut;break}p>n.wnext?(p-=n.wnext,m=n.wsize-p):m=n.wnext-p,p>n.length&&(p=n.length),gt=n.window}else gt=i,m=o-n.offset,p=n.length;p>h&&(p=h),h-=p,n.length-=p;do{i[o++]=gt[m++]}while(--p);0===n.length&&(n.mode=at);break;case lt:if(0===h)break t;i[o++]=n.length,h--,n.mode=at;break;case ht:if(n.wrap){for(;c<32;){if(0===l)break t;l--,u|=r[s++]<<c,c+=8}if(g-=h,t.total_out+=g,n.total+=g,g&&(t.adler=n.check=n.flags?v(n.check,i,g,o-g):w(n.check,i,g,o-g)),g=h,(n.flags?u:a(u))!==n.check){t.msg="incorrect data check",n.mode=ut;break}u=0,c=0}n.mode=dt;case dt:if(n.wrap&&n.flags){for(;c<32;){if(0===l)break t;l--,u+=r[s++]<<c,c+=8}if(u!==(4294967295&n.total)){t.msg="incorrect length check",n.mode=ut;break}u=0,c=0}n.mode=ft;case ft:xt=O;break t;case ut:xt=R;break t;case ct:return D;case _t:default:return N}return t.next_out=o,t.avail_out=h,t.next_in=s,t.avail_in=l,n.hold=u,n.bits=c,(n.wsize||g!==t.avail_out&&n.mode<ut&&(n.mode<ht||e!==C))&&f(t,t.output,t.next_out,g-t.avail_out)?(n.mode=ct,D):(_-=t.avail_in,g-=t.avail_out,t.total_in+=_,t.total_out+=g,n.total+=g,n.wrap&&g&&(t.adler=n.check=n.flags?v(n.check,i,g,t.next_out-g):w(n.check,i,g,t.next_out-g)),t.data_type=n.bits+(n.last?64:0)+(n.mode===q?128:0)+(n.mode===nt||n.mode===J?256:0),(0===_&&0===g||e===C)&&xt===E&&(xt=I),xt)}function c(t){if(!t||!t.state)return N;var e=t.state;return e.window&&(e.window=null),t.state=null,E}function _(t,e){var n;return t&&t.state?(n=t.state,0==(2&n.wrap)?N:(n.head=e,e.done=!1,E)):N}function g(t,e){var n,a,r=e.length;return t&&t.state?(n=t.state,0!==n.wrap&&n.mode!==$?N:n.mode===$&&(a=1,(a=w(a,e,r,0))!==n.check)?R:f(t,e,r,r)?(n.mode=ct,D):(n.havedict=1,E)):N}var p,m,b=t("../utils/common"),w=t("./adler32"),v=t("./crc32"),k=t("./inffast"),y=t("./inftrees"),x=0,z=1,B=2,C=4,A=5,S=6,E=0,O=1,Z=2,N=-2,R=-3,D=-4,I=-5,U=8,T=1,j=2,F=3,L=4,H=5,M=6,P=7,W=8,K=9,Y=10,$=11,q=12,G=13,X=14,J=15,Q=16,V=17,tt=18,et=19,nt=20,at=21,rt=22,it=23,st=24,ot=25,lt=26,ht=27,dt=28,ft=29,ut=30,ct=31,_t=32,gt=852,pt=592,mt=15,bt=!0;n.inflateReset=s,n.inflateReset2=o,n.inflateResetKeep=i,n.inflateInit=h,n.inflateInit2=l,n.inflate=u,n.inflateEnd=c,n.inflateGetHeader=_,n.inflateSetDictionary=g,n.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":5,"./adler32":7,"./crc32":9,"./inffast":11,"./inftrees":13}],13:[function(t,e,n){"use strict";var a=t("../utils/common"),r=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],i=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],s=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],o=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];e.exports=function(t,e,n,l,h,d,f,u){var c,_,g,p,m,b,w,v,k,y=u.bits,x=0,z=0,B=0,C=0,A=0,S=0,E=0,O=0,Z=0,N=0,R=null,D=0,I=new a.Buf16(16),U=new a.Buf16(16),T=null,j=0;for(x=0;x<=15;x++)I[x]=0;for(z=0;z<l;z++)I[e[n+z]]++;for(A=y,C=15;C>=1&&0===I[C];C--);if(A>C&&(A=C),0===C)return h[d++]=20971520,h[d++]=20971520,u.bits=1,0;for(B=1;B<C&&0===I[B];B++);for(A<B&&(A=B),O=1,x=1;x<=15;x++)if(O<<=1,(O-=I[x])<0)return-1;if(O>0&&(0===t||1!==C))return-1;for(U[1]=0,x=1;x<15;x++)U[x+1]=U[x]+I[x];for(z=0;z<l;z++)0!==e[n+z]&&(f[U[e[n+z]]++]=z);if(0===t?(R=T=f,b=19):1===t?(R=r,D-=257,T=i,j-=257,b=256):(R=s,T=o,b=-1),N=0,z=0,x=B,m=d,S=A,E=0,g=-1,Z=1<<A,p=Z-1,1===t&&Z>852||2===t&&Z>592)return 1;for(;;){w=x-E,f[z]<b?(v=0,k=f[z]):f[z]>b?(v=T[j+f[z]],k=R[D+f[z]]):(v=96,k=0),c=1<<x-E,_=1<<S,B=_;do{_-=c,h[m+(N>>E)+_]=w<<24|v<<16|k|0}while(0!==_);for(c=1<<x-1;N&c;)c>>=1;if(0!==c?(N&=c-1,N+=c):N=0,z++,0==--I[x]){if(x===C)break;x=e[n+f[z]]}if(x>A&&(N&p)!==g){for(0===E&&(E=A),m+=B,S=x-E,O=1<<S;S+E<C&&!((O-=I[S+E])<=0);)S++,O<<=1;if(Z+=1<<S,1===t&&Z>852||2===t&&Z>592)return 1;g=N&p,h[g]=A<<24|S<<16|m-d|0}}return 0!==N&&(h[m+N]=x-E<<24|64<<16|0),u.bits=A,0}},{"../utils/common":5}],14:[function(t,e,n){"use strict";e.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],15:[function(t,e,n){"use strict";function a(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}e.exports=a},{}]},{},[3])(3)})}]); | |
| 0 | 2 | \ No newline at end of file | ... | ... |
doc/lib/js/docsify@4.js
0 → 100644
| 1 | +!function(){function c(i){var o=Object.create(null);return function(e){var n=f(e)?e:JSON.stringify(e);return o[n]||(o[n]=i(e))}}var a=c(function(e){return e.replace(/([A-Z])/g,function(e){return"-"+e.toLowerCase()})}),u=Object.prototype.hasOwnProperty,m=Object.assign||function(e){for(var n=arguments,i=1;i<arguments.length;i++){var o,t=Object(n[i]);for(o in t)u.call(t,o)&&(e[o]=t[o])}return e};function f(e){return"string"==typeof e||"number"==typeof e}function d(){}function o(e){return"function"==typeof e}function g(e){e=e.match(/^([^:/?#]+:)?(?:\/{2,}([^/?#]*))?([^?#]+)?(\?[^#]*)?(#.*)?/);return"string"==typeof e[1]&&0<e[1].length&&e[1].toLowerCase()!==location.protocol||"string"==typeof e[2]&&0<e[2].length&&e[2].replace(new RegExp(":("+{"http:":80,"https:":443}[location.protocol]+")?$"),"")!==location.host}var s=document.body.clientWidth<=600,t=window.history&&window.history.pushState&&window.history.replaceState&&!navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/),i={};function l(e,n){if(void 0===n&&(n=!1),"string"==typeof e){if(void 0!==window.Vue)return b(e);e=n?b(e):i[e]||(i[e]=b(e))}return e}var v=document,h=v.body,_=v.head;function b(e,n){return n?e.querySelector(n):v.querySelector(e)}function k(e,n){return[].slice.call(n?e.querySelectorAll(n):v.querySelectorAll(e))}function w(e,n){return e=v.createElement(e),n&&(e.innerHTML=n),e}function r(e,n){return e.appendChild(n)}function y(e,n){return e.insertBefore(n,e.children[0])}function p(e,n,i){o(n)?window.addEventListener(e,n):e.addEventListener(n,i)}function x(e,n,i){o(n)?window.removeEventListener(e,n):e.removeEventListener(n,i)}function S(e,n,i){e&&e.classList[i?n:"toggle"](i||n)}function e(e,n){var i=(n=void 0===n?document:n).readyState;if("complete"===i||"interactive"===i)return setTimeout(e,0);n.addEventListener("DOMContentLoaded",e)}var n=Object.freeze({__proto__:null,getNode:l,$:v,body:h,head:_,find:b,findAll:k,create:w,appendTo:r,before:y,on:p,off:x,toggleClass:S,style:function(e){r(_,w("style",e))},documentReady:e});function A(e,n){return-1!==e.indexOf(n,e.length-n.length)}var $=decodeURIComponent,z=encodeURIComponent;function F(e){var n={};return(e=e.trim().replace(/^(\?|#|&)/,""))&&e.split("&").forEach(function(e){e=e.replace(/\+/g," ").split("=");n[e[0]]=e[1]&&$(e[1])}),n}function E(e,n){void 0===n&&(n=[]);var i,o=[];for(i in e)-1<n.indexOf(i)||o.push(e[i]?(z(i)+"="+z(e[i])).toLowerCase():z(i));return o.length?"?"+o.join("&"):""}var T=c(function(e){return/(:|(\/{2}))/g.test(e)}),C=c(function(e){return e.split(/[?#]/)[0]}),R=c(function(e){if(/\/$/g.test(e))return e;e=e.match(/(\S*\/)[^/]+$/);return e?e[1]:""}),j=c(function(e){return e.replace(/^\/+/,"/").replace(/([^:])\/{2,}/g,"$1/")}),O=c(function(e){for(var n=e.replace(/^\//,"").split("/"),i=[],o=0,t=n.length;o<t;o++){var a=n[o];".."===a?i.pop():"."!==a&&i.push(a)}return"/"+i.join("/")});function L(e){return e.split("/").filter(function(e){return-1===e.indexOf("#")}).join("/")}function q(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];return j(e.map(L).join("/"))}var P=c(function(e){return e.replace("#","?id=")}),M={};function I(e){this.config=e}function N(e){var n=location.href.indexOf("#");location.replace(location.href.slice(0,0<=n?n:0)+"#"+e)}I.prototype.getBasePath=function(){return this.config.basePath},I.prototype.getFile=function(e,n){void 0===e&&(e=this.getCurrentPath());var i,o,t=this.config,a=this.getBasePath(),r="string"==typeof t.ext?t.ext:".md";return e=t.alias?function e(n,i,o){var t=Object.keys(i).filter(function(e){return(M[e]||(M[e]=new RegExp("^"+e+"$"))).test(n)&&n!==o})[0];return t?e(n.replace(M[t],i[t]),i,n):n}(e,t.alias):e,i=e,o=r,e=(e=new RegExp("\\.("+o.replace(/^\./,"")+"|html)$","g").test(i)?i:/\/$/g.test(i)?i+"README"+o:""+i+o)==="/README"+r&&t.homepage||e,e=T(e)?e:q(a,e),e=n?e.replace(new RegExp("^"+a),""):e},I.prototype.onchange=function(e){(e=void 0===e?d:e)()},I.prototype.getCurrentPath=function(){},I.prototype.normalize=function(){},I.prototype.parse=function(){},I.prototype.toURL=function(e,n,i){var o=i&&"#"===e[0],t=this.parse(P(e));if(t.query=m({},t.query,n),e=(e=t.path+E(t.query)).replace(/\.md(\?)|\.md$/,"$1"),o&&(e=(0<(o=i.indexOf("?"))?i.substring(0,o):i)+e),this.config.relativePath&&0!==e.indexOf("/")){i=i.substring(0,i.lastIndexOf("/")+1);return j(O(i+e))}return j("/"+e)};var H=function(o){function e(e){o.call(this,e),this.mode="hash"}return o&&(e.__proto__=o),((e.prototype=Object.create(o&&o.prototype)).constructor=e).prototype.getBasePath=function(){var e=window.location.pathname||"",n=this.config.basePath,e=A(e,".html")?e+"#/"+n:e+"/"+n;return/^(\/|https?:)/g.test(n)?n:j(e)},e.prototype.getCurrentPath=function(){var e=location.href,n=e.indexOf("#");return-1===n?"":e.slice(n+1)},e.prototype.onchange=function(i){void 0===i&&(i=d);var o=!1;p("click",function(e){e="A"===e.target.tagName?e.target:e.target.parentNode;e&&"A"===e.tagName&&!/_blank/.test(e.target)&&(o=!0)}),p("hashchange",function(e){var n=o?"navigate":"history";o=!1,i({event:e,source:n})})},e.prototype.normalize=function(){var e=this.getCurrentPath();if("/"===(e=P(e)).charAt(0))return N(e);N("/"+e)},e.prototype.parse=function(e){var n="",i=(e=void 0===e?location.href:e).indexOf("#"),i=(e=0<=i?e.slice(i+1):e).indexOf("?");return 0<=i&&(n=e.slice(i+1),e=e.slice(0,i)),{path:e,file:this.getFile(e,!0),query:F(n)}},e.prototype.toURL=function(e,n,i){return"#"+o.prototype.toURL.call(this,e,n,i)},e}(I),D=function(n){function e(e){n.call(this,e),this.mode="history"}return n&&(e.__proto__=n),((e.prototype=Object.create(n&&n.prototype)).constructor=e).prototype.getCurrentPath=function(){var e=this.getBasePath(),n=window.location.pathname;return((n=e&&0===n.indexOf(e)?n.slice(e.length):n)||"/")+window.location.search+window.location.hash},e.prototype.onchange=function(i){var o=this;void 0===i&&(i=d),p("click",function(e){var n="A"===e.target.tagName?e.target:e.target.parentNode;n&&"A"===n.tagName&&!/_blank/.test(n.target)&&(e.preventDefault(),n=n.href,-1!==o.config.crossOriginLinks.indexOf(n)?window.open(n,"_self"):window.history.pushState({key:n},"",n),i({event:e,source:"navigate"}))}),p("popstate",function(e){i({event:e,source:"history"})})},e.prototype.parse=function(e){var n="",i=(e=void 0===e?location.href:e).indexOf("?");0<=i&&(n=e.slice(i+1),e=e.slice(0,i));var o=q(location.origin),i=e.indexOf(o);return{path:e=-1<i?e.slice(i+o.length):e,file:this.getFile(e),query:F(n)}},e}(I),U={};var Z,B,V=/([^{]*?)\w(?=\})/g,Y={YYYY:"getFullYear",YY:"getYear",MM:function(e){return e.getMonth()+1},DD:"getDate",HH:"getHours",mm:"getMinutes",ss:"getSeconds",fff:"getMilliseconds"};function G(e){var n,i=e.loaded,o=e.total,t=e.step;Z||((e=w("div")).classList.add("progress"),r(h,e),Z=e),n=t?80<(n=parseInt(Z.style.width||0,10)+t)?80:n:Math.floor(i/o*100),Z.style.opacity=1,Z.style.width=95<=n?"100%":n+"%",95<=n&&(clearTimeout(B),B=setTimeout(function(e){Z.style.opacity=0,Z.style.width="0%"},200))}var W={};function X(t,e,n){void 0===e&&(e=!1),void 0===n&&(n={});function a(){r.addEventListener.apply(r,arguments)}var i,r=new XMLHttpRequest,o=W[t];if(o)return{then:function(e){return e(o.content,o.opt)},abort:d};for(i in r.open("GET",t),n)u.call(n,i)&&r.setRequestHeader(i,n[i]);return r.send(),{then:function(n,i){var o;void 0===i&&(i=d),e&&(o=setInterval(function(e){return G({step:Math.floor(5*Math.random()+1)})},500),a("progress",G),a("loadend",function(e){G(e),clearInterval(o)})),a("error",i),a("load",function(e){var e=e.target;400<=e.status?i(e):(e=W[t]={content:e.response,opt:{updatedAt:r.getResponseHeader("last-modified")}},n(e.content,e.opt))})},abort:function(e){return 4!==r.readyState&&r.abort()}}}function Q(e,n){e.innerHTML=e.innerHTML.replace(/var\(\s*--theme-color.*?\)/g,n)}var J=v.title;function K(){var e,n=l("section.cover");n&&(e=n.getBoundingClientRect().height,window.pageYOffset>=e||n.classList.contains("hidden")?S(h,"add","sticky"):S(h,"remove","sticky"))}function ee(e,n,o,i){var t=[];null!=(n=l(n))&&(t=k(n,"a"));var a,r=decodeURI(e.toURL(e.getCurrentPath()));return t.sort(function(e,n){return n.href.length-e.href.length}).forEach(function(e){var n=decodeURI(e.getAttribute("href")),i=o?e.parentNode:e;e.title=e.title||e.innerText,0!==r.indexOf(n)||a?S(i,"remove","active"):(a=e,S(i,"add","active"))}),i&&(v.title=a?a.title||a.innerText+" - "+J:J),a}function ne(e,n){for(var i=0;i<n.length;i++){var o=n[i];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}var ie=(function(e,n,i){return n&&ne(e.prototype,n),i&&ne(e,i),e}(oe,[{key:"getIntermediateValue",value:function(e){return this.decimal?e:Math.round(e)}},{key:"getFinalValue",value:function(){return this.end}}]),oe);function oe(){var e=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};!function(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}(this,oe),this.start=e.start,this.end=e.end,this.decimal=e.decimal}function te(e,n){for(var i=0;i<n.length;i++){var o=n[i];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}var ae=(function(e,n,i){return n&&te(e.prototype,n),i&&te(e,i),e}(re,[{key:"begin",value:function(){return this.isRunning||this.next===this.end||(this.frame=window.requestAnimationFrame(this._tick.bind(this))),this}},{key:"stop",value:function(){return window.cancelAnimationFrame(this.frame),this.isRunning=!1,this.frame=null,this.timeStart=null,this.next=null,this}},{key:"on",value:function(e,n){return this.events[e]=this.events[e]||[],this.events[e].push(n),this}},{key:"_emit",value:function(e,n){var i=this,e=this.events[e];e&&e.forEach(function(e){return e.call(i,n)})}},{key:"_tick",value:function(e){this.isRunning=!0;var n=this.next||this.start;this.timeStart||(this.timeStart=e),this.timeElapsed=e-this.timeStart,this.next=this.ease(this.timeElapsed,this.start,this.end-this.start,this.duration),this._shouldTick(n)?(this._emit("tick",this.tweener.getIntermediateValue(this.next)),this.frame=window.requestAnimationFrame(this._tick.bind(this))):(this._emit("tick",this.tweener.getFinalValue()),this._emit("done",null))}},{key:"_shouldTick",value:function(e){return{up:this.next<this.end&&e<=this.next,down:this.next>this.end&&e>=this.next}[this.direction]}},{key:"_defaultEase",value:function(e,n,i,o){return(e/=o/2)<1?i/2*e*e+n:-i/2*(--e*(e-2)-1)+n}}]),re);function re(){var e=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};!function(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}(this,re),this.duration=e.duration||1e3,this.ease=e.easing||this._defaultEase,this.tweener=e.tweener||new ie(e),this.start=this.tweener.start,this.end=this.tweener.end,this.frame=null,this.next=null,this.isRunning=!1,this.events={},this.direction=this.start<this.end?"up":"down"}var ce=document.currentScript;function ue(e){var n,i=m({auto2top:!1,autoHeader:!1,basePath:"",catchPluginErrors:!0,cornerExternalLinkTarget:"_blank",coverpage:"",crossOriginLinks:[],el:"#app",executeScript:null,ext:".md",externalLinkRel:"noopener",externalLinkTarget:"_blank",formatUpdated:"",ga:"",homepage:"README.md",loadNavbar:null,loadSidebar:null,maxLevel:6,mergeNavbar:!1,name:"",nameLink:window.location.pathname,nativeEmoji:!1,noCompileLinks:[],noEmoji:!1,notFoundPage:!0,relativePath:!1,repo:"",routes:{},routerMode:"hash",subMaxLevel:0,themeColor:"",topMargin:0},"function"==typeof window.$docsify?window.$docsify(e):window.$docsify),o=ce||[].slice.call(document.getElementsByTagName("script")).filter(function(e){return/docsify\./.test(e.src)})[0];if(o)for(var t in i)!u.call(i,t)||f(n=o.getAttribute("data-"+a(t)))&&(i[t]=""===n||n);return!0===i.loadSidebar&&(i.loadSidebar="_sidebar"+i.ext),!0===i.loadNavbar&&(i.loadNavbar="_navbar"+i.ext),!0===i.coverpage&&(i.coverpage="_coverpage"+i.ext),!0===i.repo&&(i.repo=""),!0===i.name&&(i.name=""),window.$docsify=i}var fe={},pe=!1,de=null,ge=!0,se=0;function le(e){if(ge){for(var n,i=l(".sidebar"),o=k(".anchor"),t=b(i,".sidebar-nav"),a=b(i,"li.active"),r=document.documentElement,c=(r&&r.scrollTop||document.body.scrollTop)-se,u=0,f=o.length;u<f;u+=1){var p=o[u];if(p.offsetTop>c){n=n||p;break}n=p}!n||(r=fe[ve(e,n.getAttribute("data-id"))])&&r!==a&&(a&&a.classList.remove("active"),r.classList.add("active"),a=r,!pe&&h.classList.contains("sticky")&&(e=i.clientHeight,r=a.offsetTop+a.clientHeight+40,a=a.offsetTop>=t.scrollTop&&r<=t.scrollTop+e,i.scrollTop=a?t.scrollTop:+r<e?0:r-e))}}function ve(e,n){return decodeURIComponent(e)+"?id="+decodeURIComponent(n)}function he(e,n){var i,o;n&&(o=ue().topMargin,(i=b("#"+n))&&(i=i,void 0===(o=o)&&(o=0),de&&de.stop(),ge=!1,de=new ae({start:window.pageYOffset,end:Math.round(i.getBoundingClientRect().top)+window.pageYOffset-o,duration:500}).on("tick",function(e){return window.scrollTo(0,e)}).on("done",function(){ge=!0,de=null}).begin()),e=fe[ve(e,n)],(n=b(l(".sidebar"),"li.active"))&&n.classList.remove("active"),e&&e.classList.add("active"))}var _e=v.scrollingElement||v.documentElement;var me="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function be(e,n){return e(n={exports:{}},n.exports),n.exports}function ke(e){return $e[e]}var we=be(function(n){function e(){return{baseUrl:null,breaks:!1,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:null,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tokenizer:null,walkTokens:null,xhtml:!1}}n.exports={defaults:e(),getDefaults:e,changeDefaults:function(e){n.exports.defaults=e}}}),ye=(we.defaults,we.getDefaults,we.changeDefaults,/[&<>"']/),xe=/[&<>"']/g,Se=/[<>"']|&(?!#?\w+;)/,Ae=/[<>"']|&(?!#?\w+;)/g,$e={"&":"&","<":"<",">":">",'"':""","'":"'"};var ze=/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi;function Fe(e){return e.replace(ze,function(e,n){return"colon"===(n=n.toLowerCase())?":":"#"===n.charAt(0)?"x"===n.charAt(1)?String.fromCharCode(parseInt(n.substring(2),16)):String.fromCharCode(+n.substring(1)):""})}var Ee=/(^|[^\[])\^/g;var Te=/[^\w:]/g,Ce=/^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;var Re={},je=/^[^:]+:\/*[^/]*$/,Oe=/^([^:]+:)[\s\S]*$/,Le=/^([^:]+:\/*[^/]*)[\s\S]*$/;function qe(e,n){Re[" "+e]||(je.test(e)?Re[" "+e]=e+"/":Re[" "+e]=Pe(e,"/",!0));var i=-1===(e=Re[" "+e]).indexOf(":");return"//"===n.substring(0,2)?i?n:e.replace(Oe,"$1")+n:"/"===n.charAt(0)?i?n:e.replace(Le,"$1")+n:e+n}function Pe(e,n,i){var o=e.length;if(0===o)return"";for(var t=0;t<o;){var a=e.charAt(o-t-1);if(a!==n||i){if(a===n||!i)break;t++}else t++}return e.substr(0,o-t)}var Me=function(e,n){if(n){if(ye.test(e))return e.replace(xe,ke)}else if(Se.test(e))return e.replace(Ae,ke);return e},Ie=Fe,Ne=function(i,e){i=i.source||i,e=e||"";var o={replace:function(e,n){return n=(n=n.source||n).replace(Ee,"$1"),i=i.replace(e,n),o},getRegex:function(){return new RegExp(i,e)}};return o},He=function(e,n,i){if(e){var o;try{o=decodeURIComponent(Fe(i)).replace(Te,"").toLowerCase()}catch(e){return null}if(0===o.indexOf("javascript:")||0===o.indexOf("vbscript:")||0===o.indexOf("data:"))return null}n&&!Ce.test(i)&&(i=qe(n,i));try{i=encodeURI(i).replace(/%25/g,"%")}catch(e){return null}return i},De={exec:function(){}},Ue=function(e){for(var n,i,o=arguments,t=1;t<arguments.length;t++)for(i in n=o[t])Object.prototype.hasOwnProperty.call(n,i)&&(e[i]=n[i]);return e},Ze=function(e,n){var i=e.replace(/\|/g,function(e,n,i){for(var o=!1,t=n;0<=--t&&"\\"===i[t];)o=!o;return o?"|":" |"}).split(/ \|/),o=0;if(i.length>n)i.splice(n);else for(;i.length<n;)i.push("");for(;o<i.length;o++)i[o]=i[o].trim().replace(/\\\|/g,"|");return i},Be=Pe,Ve=function(e,n){if(-1===e.indexOf(n[1]))return-1;for(var i=e.length,o=0,t=0;t<i;t++)if("\\"===e[t])t++;else if(e[t]===n[0])o++;else if(e[t]===n[1]&&--o<0)return t;return-1},Ye=function(e){e&&e.sanitize&&!e.silent&&console.warn("marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options")},Ge=function(e,n){if(n<1)return"";for(var i="";1<n;)1&n&&(i+=e),n>>=1,e+=e;return i+e},We=we.defaults,Xe=Be,Qe=Ze,Je=Me,Ke=Ve;function en(e,n,i){var o=n.href,t=n.title?Je(n.title):null,n=e[1].replace(/\\([\[\]])/g,"$1");return"!"!==e[0].charAt(0)?{type:"link",raw:i,href:o,title:t,text:n}:{type:"image",raw:i,href:o,title:t,text:Je(n)}}var nn=function(){function e(e){this.options=e||We}return e.prototype.space=function(e){e=this.rules.block.newline.exec(e);if(e)return 1<e[0].length?{type:"space",raw:e[0]}:{raw:"\n"}},e.prototype.code=function(e,n){e=this.rules.block.code.exec(e);if(e){n=n[n.length-1];if(n&&"paragraph"===n.type)return{raw:e[0],text:e[0].trimRight()};n=e[0].replace(/^ {1,4}/gm,"");return{type:"code",raw:e[0],codeBlockStyle:"indented",text:this.options.pedantic?n:Xe(n,"\n")}}},e.prototype.fences=function(e){var n=this.rules.block.fences.exec(e);if(n){var i=n[0],e=function(e,n){if(null===(e=e.match(/^(\s+)(?:```)/)))return n;var i=e[1];return n.split("\n").map(function(e){var n=e.match(/^\s+/);return null!==n&&n[0].length>=i.length?e.slice(i.length):e}).join("\n")}(i,n[3]||"");return{type:"code",raw:i,lang:n[2]&&n[2].trim(),text:e}}},e.prototype.heading=function(e){var n=this.rules.block.heading.exec(e);if(n){var i=n[2].trim();return/#$/.test(i)&&(e=Xe(i,"#"),!this.options.pedantic&&e&&!/ $/.test(e)||(i=e.trim())),{type:"heading",raw:n[0],depth:n[1].length,text:i}}},e.prototype.nptable=function(e){e=this.rules.block.nptable.exec(e);if(e){var n={type:"table",header:Qe(e[1].replace(/^ *| *\| *$/g,"")),align:e[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:e[3]?e[3].replace(/\n$/,"").split("\n"):[],raw:e[0]};if(n.header.length===n.align.length){for(var i=n.align.length,o=0;o<i;o++)/^ *-+: *$/.test(n.align[o])?n.align[o]="right":/^ *:-+: *$/.test(n.align[o])?n.align[o]="center":/^ *:-+ *$/.test(n.align[o])?n.align[o]="left":n.align[o]=null;for(i=n.cells.length,o=0;o<i;o++)n.cells[o]=Qe(n.cells[o],n.header.length);return n}}},e.prototype.hr=function(e){e=this.rules.block.hr.exec(e);if(e)return{type:"hr",raw:e[0]}},e.prototype.blockquote=function(e){var n=this.rules.block.blockquote.exec(e);if(n){e=n[0].replace(/^ *> ?/gm,"");return{type:"blockquote",raw:n[0],text:e}}},e.prototype.list=function(e){e=this.rules.block.list.exec(e);if(e){for(var n,i,o,t,a,r=e[0],c=e[2],u=1<c.length,f={type:"list",raw:r,ordered:u,start:u?+c.slice(0,-1):"",loose:!1,items:[]},p=e[0].match(this.rules.block.item),d=!1,g=p.length,s=this.rules.block.listItemStart.exec(p[0]),l=0;l<g;l++){if(r=n=p[l],l!==g-1){if(o=this.rules.block.listItemStart.exec(p[l+1]),this.options.pedantic?o[1].length>s[1].length:o[1].length>s[0].length||3<o[1].length){p.splice(l,2,p[l]+"\n"+p[l+1]),l--,g--;continue}(!this.options.pedantic||this.options.smartLists?o[2][o[2].length-1]!==c[c.length-1]:u==(1===o[2].length))&&(i=p.slice(l+1).join("\n"),f.raw=f.raw.substring(0,f.raw.length-i.length),l=g-1),s=o}o=n.length,~(n=n.replace(/^ *([*+-]|\d+[.)]) ?/,"")).indexOf("\n ")&&(o-=n.length,n=this.options.pedantic?n.replace(/^ {1,4}/gm,""):n.replace(new RegExp("^ {1,"+o+"}","gm"),"")),o=d||/\n\n(?!\s*$)/.test(n),l!==g-1&&(d="\n"===n.charAt(n.length-1),o=o||d),o&&(f.loose=!0),this.options.gfm&&(a=void 0,(t=/^\[[ xX]\] /.test(n))&&(a=" "!==n[1],n=n.replace(/^\[[ xX]\] +/,""))),f.items.push({type:"list_item",raw:r,task:t,checked:a,loose:o,text:n})}return f}},e.prototype.html=function(e){e=this.rules.block.html.exec(e);if(e)return{type:this.options.sanitize?"paragraph":"html",raw:e[0],pre:!this.options.sanitizer&&("pre"===e[1]||"script"===e[1]||"style"===e[1]),text:this.options.sanitize?this.options.sanitizer?this.options.sanitizer(e[0]):Je(e[0]):e[0]}},e.prototype.def=function(e){e=this.rules.block.def.exec(e);if(e)return e[3]&&(e[3]=e[3].substring(1,e[3].length-1)),{tag:e[1].toLowerCase().replace(/\s+/g," "),raw:e[0],href:e[2],title:e[3]}},e.prototype.table=function(e){e=this.rules.block.table.exec(e);if(e){var n={type:"table",header:Qe(e[1].replace(/^ *| *\| *$/g,"")),align:e[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:e[3]?e[3].replace(/\n$/,"").split("\n"):[]};if(n.header.length===n.align.length){n.raw=e[0];for(var i=n.align.length,o=0;o<i;o++)/^ *-+: *$/.test(n.align[o])?n.align[o]="right":/^ *:-+: *$/.test(n.align[o])?n.align[o]="center":/^ *:-+ *$/.test(n.align[o])?n.align[o]="left":n.align[o]=null;for(i=n.cells.length,o=0;o<i;o++)n.cells[o]=Qe(n.cells[o].replace(/^ *\| *| *\| *$/g,""),n.header.length);return n}}},e.prototype.lheading=function(e){e=this.rules.block.lheading.exec(e);if(e)return{type:"heading",raw:e[0],depth:"="===e[2].charAt(0)?1:2,text:e[1]}},e.prototype.paragraph=function(e){e=this.rules.block.paragraph.exec(e);if(e)return{type:"paragraph",raw:e[0],text:"\n"===e[1].charAt(e[1].length-1)?e[1].slice(0,-1):e[1]}},e.prototype.text=function(e,n){e=this.rules.block.text.exec(e);if(e){n=n[n.length-1];return n&&"text"===n.type?{raw:e[0],text:e[0]}:{type:"text",raw:e[0],text:e[0]}}},e.prototype.escape=function(e){e=this.rules.inline.escape.exec(e);if(e)return{type:"escape",raw:e[0],text:Je(e[1])}},e.prototype.tag=function(e,n,i){e=this.rules.inline.tag.exec(e);if(e)return!n&&/^<a /i.test(e[0])?n=!0:n&&/^<\/a>/i.test(e[0])&&(n=!1),!i&&/^<(pre|code|kbd|script)(\s|>)/i.test(e[0])?i=!0:i&&/^<\/(pre|code|kbd|script)(\s|>)/i.test(e[0])&&(i=!1),{type:this.options.sanitize?"text":"html",raw:e[0],inLink:n,inRawBlock:i,text:this.options.sanitize?this.options.sanitizer?this.options.sanitizer(e[0]):Je(e[0]):e[0]}},e.prototype.link=function(e){var n=this.rules.inline.link.exec(e);if(n){e=n[2].trim();if(!this.options.pedantic&&/^</.test(e)){if(!/>$/.test(e))return;var i=Xe(e.slice(0,-1),"\\");if((e.length-i.length)%2==0)return}else{var o=Ke(n[2],"()");-1<o&&(t=(0===n[0].indexOf("!")?5:4)+n[1].length+o,n[2]=n[2].substring(0,o),n[0]=n[0].substring(0,t).trim(),n[3]="")}var t,i=n[2],o="";return this.options.pedantic?(t=/^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(i))&&(i=t[1],o=t[3]):o=n[3]?n[3].slice(1,-1):"",i=i.trim(),en(n,{href:(i=/^</.test(i)?this.options.pedantic&&!/>$/.test(e)?i.slice(1):i.slice(1,-1):i)&&i.replace(this.rules.inline._escapes,"$1"),title:o&&o.replace(this.rules.inline._escapes,"$1")},n[0])}},e.prototype.reflink=function(e,n){if((i=this.rules.inline.reflink.exec(e))||(i=this.rules.inline.nolink.exec(e))){var e=(i[2]||i[1]).replace(/\s+/g," ");if((e=n[e.toLowerCase()])&&e.href)return en(i,e,i[0]);var i=i[0].charAt(0);return{type:"text",raw:i,text:i}}},e.prototype.strong=function(e,n,i){void 0===i&&(i="");var o=this.rules.inline.strong.start.exec(e);if(o&&(!o[1]||o[1]&&(""===i||this.rules.inline.punctuation.exec(i)))){n=n.slice(-1*e.length);var t,a="**"===o[0]?this.rules.inline.strong.endAst:this.rules.inline.strong.endUnd;for(a.lastIndex=0;null!=(o=a.exec(n));)if(t=this.rules.inline.strong.middle.exec(n.slice(0,o.index+3)))return{type:"strong",raw:e.slice(0,t[0].length),text:e.slice(2,t[0].length-2)}}},e.prototype.em=function(e,n,i){void 0===i&&(i="");var o=this.rules.inline.em.start.exec(e);if(o&&(!o[1]||o[1]&&(""===i||this.rules.inline.punctuation.exec(i)))){n=n.slice(-1*e.length);var t,a="*"===o[0]?this.rules.inline.em.endAst:this.rules.inline.em.endUnd;for(a.lastIndex=0;null!=(o=a.exec(n));)if(t=this.rules.inline.em.middle.exec(n.slice(0,o.index+2)))return{type:"em",raw:e.slice(0,t[0].length),text:e.slice(1,t[0].length-1)}}},e.prototype.codespan=function(e){var n=this.rules.inline.code.exec(e);if(n){var i=n[2].replace(/\n/g," "),o=/[^ ]/.test(i),e=/^ /.test(i)&&/ $/.test(i);return o&&e&&(i=i.substring(1,i.length-1)),i=Je(i,!0),{type:"codespan",raw:n[0],text:i}}},e.prototype.br=function(e){e=this.rules.inline.br.exec(e);if(e)return{type:"br",raw:e[0]}},e.prototype.del=function(e){e=this.rules.inline.del.exec(e);if(e)return{type:"del",raw:e[0],text:e[2]}},e.prototype.autolink=function(e,n){e=this.rules.inline.autolink.exec(e);if(e){var i,n="@"===e[2]?"mailto:"+(i=Je(this.options.mangle?n(e[1]):e[1])):i=Je(e[1]);return{type:"link",raw:e[0],text:i,href:n,tokens:[{type:"text",raw:i,text:i}]}}},e.prototype.url=function(e,n){var i,o,t,a;if(i=this.rules.inline.url.exec(e)){if("@"===i[2])t="mailto:"+(o=Je(this.options.mangle?n(i[0]):i[0]));else{for(;a=i[0],i[0]=this.rules.inline._backpedal.exec(i[0])[0],a!==i[0];);o=Je(i[0]),t="www."===i[1]?"http://"+o:o}return{type:"link",raw:i[0],text:o,href:t,tokens:[{type:"text",raw:o,text:o}]}}},e.prototype.inlineText=function(e,n,i){e=this.rules.inline.text.exec(e);if(e){i=n?this.options.sanitize?this.options.sanitizer?this.options.sanitizer(e[0]):Je(e[0]):e[0]:Je(this.options.smartypants?i(e[0]):e[0]);return{type:"text",raw:e[0],text:i}}},e}(),Ze=De,Ve=Ne,De=Ue,Ne={newline:/^(?: *(?:\n|$))+/,code:/^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,fences:/^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?:\n+|$)|$)/,hr:/^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,heading:/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,blockquote:/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,list:/^( {0,3})(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?! {0,3}bull )\n*|\s*$)/,html:"^ {0,3}(?:<(script|pre|style)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:\\n{2,}|$)|<(?!script|pre|style)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:\\n{2,}|$)|</(?!script|pre|style)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:\\n{2,}|$))",def:/^ {0,3}\[(label)\]: *\n? *<?([^\s>]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/,nptable:Ze,table:Ze,lheading:/^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/,_paragraph:/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html| +\n)[^\n]+)*)/,text:/^[^\n]+/,_label:/(?!\s*\])(?:\\[\[\]]|[^\[\]])+/,_title:/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/};Ne.def=Ve(Ne.def).replace("label",Ne._label).replace("title",Ne._title).getRegex(),Ne.bullet=/(?:[*+-]|\d{1,9}[.)])/,Ne.item=/^( *)(bull) ?[^\n]*(?:\n(?! *bull ?)[^\n]*)*/,Ne.item=Ve(Ne.item,"gm").replace(/bull/g,Ne.bullet).getRegex(),Ne.listItemStart=Ve(/^( *)(bull)/).replace("bull",Ne.bullet).getRegex(),Ne.list=Ve(Ne.list).replace(/bull/g,Ne.bullet).replace("hr","\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def","\\n+(?="+Ne.def.source+")").getRegex(),Ne._tag="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",Ne._comment=/<!--(?!-?>)[\s\S]*?(?:-->|$)/,Ne.html=Ve(Ne.html,"i").replace("comment",Ne._comment).replace("tag",Ne._tag).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),Ne.paragraph=Ve(Ne._paragraph).replace("hr",Ne.hr).replace("heading"," {0,3}#{1,6} ").replace("|lheading","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|!--)").replace("tag",Ne._tag).getRegex(),Ne.blockquote=Ve(Ne.blockquote).replace("paragraph",Ne.paragraph).getRegex(),Ne.normal=De({},Ne),Ne.gfm=De({},Ne.normal,{nptable:"^ *([^|\\n ].*\\|.*)\\n {0,3}([-:]+ *\\|[-| :]*)(?:\\n((?:(?!\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)",table:"^ *\\|(.+)\\n {0,3}\\|?( *[-:]+[-| :]*)(?:\\n *((?:(?!\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)"}),Ne.gfm.nptable=Ve(Ne.gfm.nptable).replace("hr",Ne.hr).replace("heading"," {0,3}#{1,6} ").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|!--)").replace("tag",Ne._tag).getRegex(),Ne.gfm.table=Ve(Ne.gfm.table).replace("hr",Ne.hr).replace("heading"," {0,3}#{1,6} ").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|!--)").replace("tag",Ne._tag).getRegex(),Ne.pedantic=De({},Ne.normal,{html:Ve("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:\"[^\"]*\"|'[^']*'|\\s[^'\"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",Ne._comment).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:Ze,paragraph:Ve(Ne.normal._paragraph).replace("hr",Ne.hr).replace("heading"," *#{1,6} *[^\n]").replace("lheading",Ne.lheading).replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").getRegex()});Ze={escape:/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,autolink:/^<(scheme:[^\s\x00-\x1f<>]*|email)>/,url:Ze,tag:"^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>",link:/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,reflink:/^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,nolink:/^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,reflinkSearch:"reflink|nolink(?!\\()",strong:{start:/^(?:(\*\*(?=[*punctuation]))|\*\*)(?![\s])|__/,middle:/^\*\*(?:(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)|\*(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)*?\*)+?\*\*$|^__(?![\s])((?:(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)|_(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)*?_)+?)__$/,endAst:/[^punctuation\s]\*\*(?!\*)|[punctuation]\*\*(?!\*)(?:(?=[punctuation_\s]|$))/,endUnd:/[^\s]__(?!_)(?:(?=[punctuation*\s])|$)/},em:{start:/^(?:(\*(?=[punctuation]))|\*)(?![*\s])|_/,middle:/^\*(?:(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)|\*(?:(?!overlapSkip)(?:[^*]|\\\*)|overlapSkip)*?\*)+?\*$|^_(?![_\s])(?:(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)|_(?:(?!overlapSkip)(?:[^_]|\\_)|overlapSkip)*?_)+?_$/,endAst:/[^punctuation\s]\*(?!\*)|[punctuation]\*(?!\*)(?:(?=[punctuation_\s]|$))/,endUnd:/[^\s]_(?!_)(?:(?=[punctuation*\s])|$)/},code:/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,br:/^( {2,}|\\)\n(?!\s*$)/,del:Ze,text:/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*]|\b_|$)|[^ ](?= {2,}\n)))/,punctuation:/^([\s*punctuation])/,_punctuation:"!\"#$%&'()+\\-.,/:;<=>?@\\[\\]`^{|}~"};Ze.punctuation=Ve(Ze.punctuation).replace(/punctuation/g,Ze._punctuation).getRegex(),Ze._blockSkip="\\[[^\\]]*?\\]\\([^\\)]*?\\)|`[^`]*?`|<[^>]*?>",Ze._overlapSkip="__[^_]*?__|\\*\\*\\[^\\*\\]*?\\*\\*",Ze._comment=Ve(Ne._comment).replace("(?:--\x3e|$)","--\x3e").getRegex(),Ze.em.start=Ve(Ze.em.start).replace(/punctuation/g,Ze._punctuation).getRegex(),Ze.em.middle=Ve(Ze.em.middle).replace(/punctuation/g,Ze._punctuation).replace(/overlapSkip/g,Ze._overlapSkip).getRegex(),Ze.em.endAst=Ve(Ze.em.endAst,"g").replace(/punctuation/g,Ze._punctuation).getRegex(),Ze.em.endUnd=Ve(Ze.em.endUnd,"g").replace(/punctuation/g,Ze._punctuation).getRegex(),Ze.strong.start=Ve(Ze.strong.start).replace(/punctuation/g,Ze._punctuation).getRegex(),Ze.strong.middle=Ve(Ze.strong.middle).replace(/punctuation/g,Ze._punctuation).replace(/overlapSkip/g,Ze._overlapSkip).getRegex(),Ze.strong.endAst=Ve(Ze.strong.endAst,"g").replace(/punctuation/g,Ze._punctuation).getRegex(),Ze.strong.endUnd=Ve(Ze.strong.endUnd,"g").replace(/punctuation/g,Ze._punctuation).getRegex(),Ze.blockSkip=Ve(Ze._blockSkip,"g").getRegex(),Ze.overlapSkip=Ve(Ze._overlapSkip,"g").getRegex(),Ze._escapes=/\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g,Ze._scheme=/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/,Ze._email=/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/,Ze.autolink=Ve(Ze.autolink).replace("scheme",Ze._scheme).replace("email",Ze._email).getRegex(),Ze._attribute=/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/,Ze.tag=Ve(Ze.tag).replace("comment",Ze._comment).replace("attribute",Ze._attribute).getRegex(),Ze._label=/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/,Ze._href=/<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/,Ze._title=/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/,Ze.link=Ve(Ze.link).replace("label",Ze._label).replace("href",Ze._href).replace("title",Ze._title).getRegex(),Ze.reflink=Ve(Ze.reflink).replace("label",Ze._label).getRegex(),Ze.reflinkSearch=Ve(Ze.reflinkSearch,"g").replace("reflink",Ze.reflink).replace("nolink",Ze.nolink).getRegex(),Ze.normal=De({},Ze),Ze.pedantic=De({},Ze.normal,{strong:{start:/^__|\*\*/,middle:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,endAst:/\*\*(?!\*)/g,endUnd:/__(?!_)/g},em:{start:/^_|\*/,middle:/^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,endAst:/\*(?!\*)/g,endUnd:/_(?!_)/g},link:Ve(/^!?\[(label)\]\((.*?)\)/).replace("label",Ze._label).getRegex(),reflink:Ve(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",Ze._label).getRegex()}),Ze.gfm=De({},Ze.normal,{escape:Ve(Ze.escape).replace("])","~|])").getRegex(),_extended_email:/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,url:/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,_backpedal:/(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,text:/^([`~]+|[^`~])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*~]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@))/}),Ze.gfm.url=Ve(Ze.gfm.url,"i").replace("email",Ze.gfm._extended_email).getRegex(),Ze.breaks=De({},Ze.gfm,{br:Ve(Ze.br).replace("{2,}","*").getRegex(),text:Ve(Ze.gfm.text).replace("\\b_","\\b_| {2,}\\n").replace(/\{2,\}/g,"*").getRegex()});var Ze={block:Ne,inline:Ze},on=we.defaults,tn=Ze.block,an=Ze.inline,rn=Ge;function cn(e){return e.replace(/---/g,"—").replace(/--/g,"–").replace(/(^|[-\u2014/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…")}function un(e){for(var n,i="",o=e.length,t=0;t<o;t++)n=e.charCodeAt(t),i+="&#"+(n=.5<Math.random()?"x"+n.toString(16):n)+";";return i}var fn=function(){function i(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||on,this.options.tokenizer=this.options.tokenizer||new nn,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options;e={block:tn.normal,inline:an.normal};this.options.pedantic?(e.block=tn.pedantic,e.inline=an.pedantic):this.options.gfm&&(e.block=tn.gfm,this.options.breaks?e.inline=an.breaks:e.inline=an.gfm),this.tokenizer.rules=e}var e={rules:{configurable:!0}};return e.rules.get=function(){return{block:tn,inline:an}},i.lex=function(e,n){return new i(n).lex(e)},i.lexInline=function(e,n){return new i(n).inlineTokens(e)},i.prototype.lex=function(e){return e=e.replace(/\r\n|\r/g,"\n").replace(/\t/g," "),this.blockTokens(e,this.tokens,!0),this.inline(this.tokens),this.tokens},i.prototype.blockTokens=function(e,n,i){var o,t,a,r;for(void 0===n&&(n=[]),void 0===i&&(i=!0),this.options.pedantic&&(e=e.replace(/^ +$/gm,""));e;)if(o=this.tokenizer.space(e))e=e.substring(o.raw.length),o.type&&n.push(o);else if(o=this.tokenizer.code(e,n))e=e.substring(o.raw.length),o.type?n.push(o):((r=n[n.length-1]).raw+="\n"+o.raw,r.text+="\n"+o.text);else if(o=this.tokenizer.fences(e))e=e.substring(o.raw.length),n.push(o);else if(o=this.tokenizer.heading(e))e=e.substring(o.raw.length),n.push(o);else if(o=this.tokenizer.nptable(e))e=e.substring(o.raw.length),n.push(o);else if(o=this.tokenizer.hr(e))e=e.substring(o.raw.length),n.push(o);else if(o=this.tokenizer.blockquote(e))e=e.substring(o.raw.length),o.tokens=this.blockTokens(o.text,[],i),n.push(o);else if(o=this.tokenizer.list(e)){for(e=e.substring(o.raw.length),a=o.items.length,t=0;t<a;t++)o.items[t].tokens=this.blockTokens(o.items[t].text,[],!1);n.push(o)}else if(o=this.tokenizer.html(e))e=e.substring(o.raw.length),n.push(o);else if(i&&(o=this.tokenizer.def(e)))e=e.substring(o.raw.length),this.tokens.links[o.tag]||(this.tokens.links[o.tag]={href:o.href,title:o.title});else if(o=this.tokenizer.table(e))e=e.substring(o.raw.length),n.push(o);else if(o=this.tokenizer.lheading(e))e=e.substring(o.raw.length),n.push(o);else if(i&&(o=this.tokenizer.paragraph(e)))e=e.substring(o.raw.length),n.push(o);else if(o=this.tokenizer.text(e,n))e=e.substring(o.raw.length),o.type?n.push(o):((r=n[n.length-1]).raw+="\n"+o.raw,r.text+="\n"+o.text);else if(e){var c="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(c);break}throw new Error(c)}return n},i.prototype.inline=function(e){for(var n,i,o,t,a,r=e.length,c=0;c<r;c++)switch((a=e[c]).type){case"paragraph":case"text":case"heading":a.tokens=[],this.inlineTokens(a.text,a.tokens);break;case"table":for(a.tokens={header:[],cells:[]},o=a.header.length,n=0;n<o;n++)a.tokens.header[n]=[],this.inlineTokens(a.header[n],a.tokens.header[n]);for(o=a.cells.length,n=0;n<o;n++)for(t=a.cells[n],a.tokens.cells[n]=[],i=0;i<t.length;i++)a.tokens.cells[n][i]=[],this.inlineTokens(t[i],a.tokens.cells[n][i]);break;case"blockquote":this.inline(a.tokens);break;case"list":for(o=a.items.length,n=0;n<o;n++)this.inline(a.items[n].tokens)}return e},i.prototype.inlineTokens=function(e,n,i,o){var t;void 0===n&&(n=[]),void 0===i&&(i=!1),void 0===o&&(o=!1);var a,r,c,u=e;if(this.tokens.links){var f=Object.keys(this.tokens.links);if(0<f.length)for(;null!=(a=this.tokenizer.rules.inline.reflinkSearch.exec(u));)f.includes(a[0].slice(a[0].lastIndexOf("[")+1,-1))&&(u=u.slice(0,a.index)+"["+rn("a",a[0].length-2)+"]"+u.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;null!=(a=this.tokenizer.rules.inline.blockSkip.exec(u));)u=u.slice(0,a.index)+"["+rn("a",a[0].length-2)+"]"+u.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);for(;e;)if(r||(c=""),r=!1,t=this.tokenizer.escape(e))e=e.substring(t.raw.length),n.push(t);else if(t=this.tokenizer.tag(e,i,o))e=e.substring(t.raw.length),i=t.inLink,o=t.inRawBlock,n.push(t);else if(t=this.tokenizer.link(e))e=e.substring(t.raw.length),"link"===t.type&&(t.tokens=this.inlineTokens(t.text,[],!0,o)),n.push(t);else if(t=this.tokenizer.reflink(e,this.tokens.links))e=e.substring(t.raw.length),"link"===t.type&&(t.tokens=this.inlineTokens(t.text,[],!0,o)),n.push(t);else if(t=this.tokenizer.strong(e,u,c))e=e.substring(t.raw.length),t.tokens=this.inlineTokens(t.text,[],i,o),n.push(t);else if(t=this.tokenizer.em(e,u,c))e=e.substring(t.raw.length),t.tokens=this.inlineTokens(t.text,[],i,o),n.push(t);else if(t=this.tokenizer.codespan(e))e=e.substring(t.raw.length),n.push(t);else if(t=this.tokenizer.br(e))e=e.substring(t.raw.length),n.push(t);else if(t=this.tokenizer.del(e))e=e.substring(t.raw.length),t.tokens=this.inlineTokens(t.text,[],i,o),n.push(t);else if(t=this.tokenizer.autolink(e,un))e=e.substring(t.raw.length),n.push(t);else if(i||!(t=this.tokenizer.url(e,un))){if(t=this.tokenizer.inlineText(e,o,cn))e=e.substring(t.raw.length),c=t.raw.slice(-1),r=!0,n.push(t);else if(e){var p="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(p);break}throw new Error(p)}}else e=e.substring(t.raw.length),n.push(t);return n},Object.defineProperties(i,e),i}(),pn=we.defaults,dn=He,gn=Me,sn=function(){function e(e){this.options=e||pn}return e.prototype.code=function(e,n,i){var o=(n||"").match(/\S*/)[0];return!this.options.highlight||null!=(n=this.options.highlight(e,o))&&n!==e&&(i=!0,e=n),e=e.replace(/\n$/,"")+"\n",o?'<pre><code class="'+this.options.langPrefix+gn(o,!0)+'">'+(i?e:gn(e,!0))+"</code></pre>\n":"<pre><code>"+(i?e:gn(e,!0))+"</code></pre>\n"},e.prototype.blockquote=function(e){return"<blockquote>\n"+e+"</blockquote>\n"},e.prototype.html=function(e){return e},e.prototype.heading=function(e,n,i,o){return this.options.headerIds?"<h"+n+' id="'+this.options.headerPrefix+o.slug(i)+'">'+e+"</h"+n+">\n":"<h"+n+">"+e+"</h"+n+">\n"},e.prototype.hr=function(){return this.options.xhtml?"<hr/>\n":"<hr>\n"},e.prototype.list=function(e,n,i){var o=n?"ol":"ul";return"<"+o+(n&&1!==i?' start="'+i+'"':"")+">\n"+e+"</"+o+">\n"},e.prototype.listitem=function(e){return"<li>"+e+"</li>\n"},e.prototype.checkbox=function(e){return"<input "+(e?'checked="" ':"")+'disabled="" type="checkbox"'+(this.options.xhtml?" /":"")+"> "},e.prototype.paragraph=function(e){return"<p>"+e+"</p>\n"},e.prototype.table=function(e,n){return"<table>\n<thead>\n"+e+"</thead>\n"+(n=n&&"<tbody>"+n+"</tbody>")+"</table>\n"},e.prototype.tablerow=function(e){return"<tr>\n"+e+"</tr>\n"},e.prototype.tablecell=function(e,n){var i=n.header?"th":"td";return(n.align?"<"+i+' align="'+n.align+'">':"<"+i+">")+e+"</"+i+">\n"},e.prototype.strong=function(e){return"<strong>"+e+"</strong>"},e.prototype.em=function(e){return"<em>"+e+"</em>"},e.prototype.codespan=function(e){return"<code>"+e+"</code>"},e.prototype.br=function(){return this.options.xhtml?"<br/>":"<br>"},e.prototype.del=function(e){return"<del>"+e+"</del>"},e.prototype.link=function(e,n,i){if(null===(e=dn(this.options.sanitize,this.options.baseUrl,e)))return i;e='<a href="'+gn(e)+'"';return n&&(e+=' title="'+n+'"'),e+=">"+i+"</a>"},e.prototype.image=function(e,n,i){if(null===(e=dn(this.options.sanitize,this.options.baseUrl,e)))return i;i='<img src="'+e+'" alt="'+i+'"';return n&&(i+=' title="'+n+'"'),i+=this.options.xhtml?"/>":">"},e.prototype.text=function(e){return e},e}(),ln=function(){function e(){}return e.prototype.strong=function(e){return e},e.prototype.em=function(e){return e},e.prototype.codespan=function(e){return e},e.prototype.del=function(e){return e},e.prototype.html=function(e){return e},e.prototype.text=function(e){return e},e.prototype.link=function(e,n,i){return""+i},e.prototype.image=function(e,n,i){return""+i},e.prototype.br=function(){return""},e}(),vn=function(){function e(){this.seen={}}return e.prototype.serialize=function(e){return e.toLowerCase().trim().replace(/<[!\/a-z].*?>/gi,"").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g,"").replace(/\s/g,"-")},e.prototype.getNextSafeSlug=function(e,n){var i=e,o=0;if(this.seen.hasOwnProperty(i))for(o=this.seen[e];i=e+"-"+ ++o,this.seen.hasOwnProperty(i););return n||(this.seen[e]=o,this.seen[i]=0),i},e.prototype.slug=function(e,n){void 0===n&&(n={});e=this.serialize(e);return this.getNextSafeSlug(e,n.dryrun)},e}(),hn=we.defaults,_n=Ie,mn=function(){function i(e){this.options=e||hn,this.options.renderer=this.options.renderer||new sn,this.renderer=this.options.renderer,this.renderer.options=this.options,this.textRenderer=new ln,this.slugger=new vn}return i.parse=function(e,n){return new i(n).parse(e)},i.parseInline=function(e,n){return new i(n).parseInline(e)},i.prototype.parse=function(e,n){void 0===n&&(n=!0);for(var i,o,t,a,r,c,u,f,p,d,g,s,l,v,h,_="",m=e.length,b=0;b<m;b++)switch((f=e[b]).type){case"space":continue;case"hr":_+=this.renderer.hr();continue;case"heading":_+=this.renderer.heading(this.parseInline(f.tokens),f.depth,_n(this.parseInline(f.tokens,this.textRenderer)),this.slugger);continue;case"code":_+=this.renderer.code(f.text,f.lang,f.escaped);continue;case"table":for(c=p="",t=f.header.length,i=0;i<t;i++)c+=this.renderer.tablecell(this.parseInline(f.tokens.header[i]),{header:!0,align:f.align[i]});for(p+=this.renderer.tablerow(c),u="",t=f.cells.length,i=0;i<t;i++){for(c="",a=(r=f.tokens.cells[i]).length,o=0;o<a;o++)c+=this.renderer.tablecell(this.parseInline(r[o]),{header:!1,align:f.align[o]});u+=this.renderer.tablerow(c)}_+=this.renderer.table(p,u);continue;case"blockquote":u=this.parse(f.tokens),_+=this.renderer.blockquote(u);continue;case"list":for(p=f.ordered,k=f.start,d=f.loose,t=f.items.length,u="",i=0;i<t;i++)l=(s=f.items[i]).checked,v=s.task,g="",s.task&&(h=this.renderer.checkbox(l),d?0<s.tokens.length&&"text"===s.tokens[0].type?(s.tokens[0].text=h+" "+s.tokens[0].text,s.tokens[0].tokens&&0<s.tokens[0].tokens.length&&"text"===s.tokens[0].tokens[0].type&&(s.tokens[0].tokens[0].text=h+" "+s.tokens[0].tokens[0].text)):s.tokens.unshift({type:"text",text:h}):g+=h),g+=this.parse(s.tokens,d),u+=this.renderer.listitem(g,v,l);_+=this.renderer.list(u,p,k);continue;case"html":_+=this.renderer.html(f.text);continue;case"paragraph":_+=this.renderer.paragraph(this.parseInline(f.tokens));continue;case"text":for(u=f.tokens?this.parseInline(f.tokens):f.text;b+1<m&&"text"===e[b+1].type;)u+="\n"+((f=e[++b]).tokens?this.parseInline(f.tokens):f.text);_+=n?this.renderer.paragraph(u):u;continue;default:var k='Token with "'+f.type+'" type was not found.';if(this.options.silent)return void console.error(k);throw new Error(k)}return _},i.prototype.parseInline=function(e,n){n=n||this.renderer;for(var i,o="",t=e.length,a=0;a<t;a++)switch((i=e[a]).type){case"escape":o+=n.text(i.text);break;case"html":o+=n.html(i.text);break;case"link":o+=n.link(i.href,i.title,this.parseInline(i.tokens,n));break;case"image":o+=n.image(i.href,i.title,i.text);break;case"strong":o+=n.strong(this.parseInline(i.tokens,n));break;case"em":o+=n.em(this.parseInline(i.tokens,n));break;case"codespan":o+=n.codespan(i.text);break;case"br":o+=n.br();break;case"del":o+=n.del(this.parseInline(i.tokens,n));break;case"text":o+=n.text(i.text);break;default:var r='Token with "'+i.type+'" type was not found.';if(this.options.silent)return void console.error(r);throw new Error(r)}return o},i}(),bn=Ue,kn=Ye,wn=Me,Me=we.getDefaults,yn=we.changeDefaults,we=we.defaults;function xn(e,i,o){if(null==e)throw new Error("marked(): input parameter is undefined or null");if("string"!=typeof e)throw new Error("marked(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected");if("function"==typeof i&&(o=i,i=null),i=bn({},xn.defaults,i||{}),kn(i),o){var t,a=i.highlight;try{t=fn.lex(e,i)}catch(e){return o(e)}function r(n){var e;if(!n)try{e=mn.parse(t,i)}catch(e){n=e}return i.highlight=a,n?o(n):o(null,e)}if(!a||a.length<3)return r();if(delete i.highlight,!t.length)return r();var c=0;return xn.walkTokens(t,function(i){"code"===i.type&&(c++,setTimeout(function(){a(i.text,i.lang,function(e,n){return e?r(e):(null!=n&&n!==i.text&&(i.text=n,i.escaped=!0),void(0===--c&&r()))})},0))}),void(0===c&&r())}try{var n=fn.lex(e,i);return i.walkTokens&&xn.walkTokens(n,i.walkTokens),mn.parse(n,i)}catch(e){if(e.message+="\nPlease report this to https://github.com/markedjs/marked.",i.silent)return"<p>An error occurred:</p><pre>"+wn(e.message+"",!0)+"</pre>";throw e}}xn.options=xn.setOptions=function(e){return bn(xn.defaults,e),yn(xn.defaults),xn},xn.getDefaults=Me,xn.defaults=we,xn.use=function(a){var n,e=bn({},a);if(a.renderer){var i,r=xn.defaults.renderer||new sn;for(i in a.renderer)!function(o){var t=r[o];r[o]=function(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];var i=a.renderer[o].apply(r,e);return i=!1===i?t.apply(r,e):i}}(i);e.renderer=r}if(a.tokenizer){var t,c=xn.defaults.tokenizer||new nn;for(t in a.tokenizer)!function(){var o=c[t];c[t]=function(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];var i=a.tokenizer[t].apply(c,e);return i=!1===i?o.apply(c,e):i}}();e.tokenizer=c}a.walkTokens&&(n=xn.defaults.walkTokens,e.walkTokens=function(e){a.walkTokens(e),n&&n(e)}),xn.setOptions(e)},xn.walkTokens=function(e,n){for(var i=0,o=e;i<o.length;i+=1){var t=o[i];switch(n(t),t.type){case"table":for(var a=0,r=t.tokens.header;a<r.length;a+=1){var c=r[a];xn.walkTokens(c,n)}for(var u=0,f=t.tokens.cells;u<f.length;u+=1)for(var p=0,d=f[u];p<d.length;p+=1){var g=d[p];xn.walkTokens(g,n)}break;case"list":xn.walkTokens(t.items,n);break;default:t.tokens&&xn.walkTokens(t.tokens,n)}}},xn.parseInline=function(e,n){if(null==e)throw new Error("marked.parseInline(): input parameter is undefined or null");if("string"!=typeof e)throw new Error("marked.parseInline(): input parameter is of type "+Object.prototype.toString.call(e)+", string expected");n=bn({},xn.defaults,n||{}),kn(n);try{var i=fn.lexInline(e,n);return n.walkTokens&&xn.walkTokens(i,n.walkTokens),mn.parseInline(i,n)}catch(e){if(e.message+="\nPlease report this to https://github.com/markedjs/marked.",n.silent)return"<p>An error occurred:</p><pre>"+wn(e.message+"",!0)+"</pre>";throw e}},xn.Parser=mn,xn.parser=mn.parse,xn.Renderer=sn,xn.TextRenderer=ln,xn.Lexer=fn,xn.lexer=fn.lex,xn.Tokenizer=nn,xn.Slugger=vn;var Sn=xn.parse=xn;function An(e,i){if(void 0===i&&(i='<ul class="app-sub-sidebar">{inner}</ul>'),!e||!e.length)return"";var o="";return e.forEach(function(e){var n=e.title.replace(/(<([^>]+)>)/g,"");o+='<li><a class="section-link" href="'+e.slug+'" title="'+n+'">'+e.title+"</a></li>",e.children&&(o+=An(e.children,i))}),i.replace("{inner}",o)}function $n(e,n){return'<p class="'+e+'">'+n.slice(5).trim()+"</p>"}function zn(e,o){var t=[],a={};return e.forEach(function(e){var n=e.level||1,i=n-1;o<n||(a[i]?a[i].children=(a[i].children||[]).concat(e):t.push(e),a[n]=e)}),t}var Fn={},En=/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g;function Tn(e){return e.toLowerCase()}function Cn(e){if("string"!=typeof e)return"";var n=e.trim().replace(/[A-Z]+/g,Tn).replace(/<[^>]+>/g,"").replace(En,"").replace(/\s/g,"-").replace(/-+/g,"-").replace(/^(\d)/,"_$1"),e=Fn[n],e=u.call(Fn,n)?e+1:0;return n=(Fn[n]=e)?n+"-"+e:n}Cn.clear=function(){Fn={}};var Rn={baseURL:"https://github.githubassets.com/images/icons/emoji/",data:{100:"unicode/1f4af.png?v8",1234:"unicode/1f522.png?v8","+1":"unicode/1f44d.png?v8","-1":"unicode/1f44e.png?v8","1st_place_medal":"unicode/1f947.png?v8","2nd_place_medal":"unicode/1f948.png?v8","3rd_place_medal":"unicode/1f949.png?v8","8ball":"unicode/1f3b1.png?v8",a:"unicode/1f170.png?v8",ab:"unicode/1f18e.png?v8",abacus:"unicode/1f9ee.png?v8",abc:"unicode/1f524.png?v8",abcd:"unicode/1f521.png?v8",accept:"unicode/1f251.png?v8",accordion:"unicode/1fa97.png?v8",adhesive_bandage:"unicode/1fa79.png?v8",adult:"unicode/1f9d1.png?v8",aerial_tramway:"unicode/1f6a1.png?v8",afghanistan:"unicode/1f1e6-1f1eb.png?v8",airplane:"unicode/2708.png?v8",aland_islands:"unicode/1f1e6-1f1fd.png?v8",alarm_clock:"unicode/23f0.png?v8",albania:"unicode/1f1e6-1f1f1.png?v8",alembic:"unicode/2697.png?v8",algeria:"unicode/1f1e9-1f1ff.png?v8",alien:"unicode/1f47d.png?v8",ambulance:"unicode/1f691.png?v8",american_samoa:"unicode/1f1e6-1f1f8.png?v8",amphora:"unicode/1f3fa.png?v8",anatomical_heart:"unicode/1fac0.png?v8",anchor:"unicode/2693.png?v8",andorra:"unicode/1f1e6-1f1e9.png?v8",angel:"unicode/1f47c.png?v8",anger:"unicode/1f4a2.png?v8",angola:"unicode/1f1e6-1f1f4.png?v8",angry:"unicode/1f620.png?v8",anguilla:"unicode/1f1e6-1f1ee.png?v8",anguished:"unicode/1f627.png?v8",ant:"unicode/1f41c.png?v8",antarctica:"unicode/1f1e6-1f1f6.png?v8",antigua_barbuda:"unicode/1f1e6-1f1ec.png?v8",apple:"unicode/1f34e.png?v8",aquarius:"unicode/2652.png?v8",argentina:"unicode/1f1e6-1f1f7.png?v8",aries:"unicode/2648.png?v8",armenia:"unicode/1f1e6-1f1f2.png?v8",arrow_backward:"unicode/25c0.png?v8",arrow_double_down:"unicode/23ec.png?v8",arrow_double_up:"unicode/23eb.png?v8",arrow_down:"unicode/2b07.png?v8",arrow_down_small:"unicode/1f53d.png?v8",arrow_forward:"unicode/25b6.png?v8",arrow_heading_down:"unicode/2935.png?v8",arrow_heading_up:"unicode/2934.png?v8",arrow_left:"unicode/2b05.png?v8",arrow_lower_left:"unicode/2199.png?v8",arrow_lower_right:"unicode/2198.png?v8",arrow_right:"unicode/27a1.png?v8",arrow_right_hook:"unicode/21aa.png?v8",arrow_up:"unicode/2b06.png?v8",arrow_up_down:"unicode/2195.png?v8",arrow_up_small:"unicode/1f53c.png?v8",arrow_upper_left:"unicode/2196.png?v8",arrow_upper_right:"unicode/2197.png?v8",arrows_clockwise:"unicode/1f503.png?v8",arrows_counterclockwise:"unicode/1f504.png?v8",art:"unicode/1f3a8.png?v8",articulated_lorry:"unicode/1f69b.png?v8",artificial_satellite:"unicode/1f6f0.png?v8",artist:"unicode/1f9d1-1f3a8.png?v8",aruba:"unicode/1f1e6-1f1fc.png?v8",ascension_island:"unicode/1f1e6-1f1e8.png?v8",asterisk:"unicode/002a-20e3.png?v8",astonished:"unicode/1f632.png?v8",astronaut:"unicode/1f9d1-1f680.png?v8",athletic_shoe:"unicode/1f45f.png?v8",atm:"unicode/1f3e7.png?v8",atom:"atom.png?v8",atom_symbol:"unicode/269b.png?v8",australia:"unicode/1f1e6-1f1fa.png?v8",austria:"unicode/1f1e6-1f1f9.png?v8",auto_rickshaw:"unicode/1f6fa.png?v8",avocado:"unicode/1f951.png?v8",axe:"unicode/1fa93.png?v8",azerbaijan:"unicode/1f1e6-1f1ff.png?v8",b:"unicode/1f171.png?v8",baby:"unicode/1f476.png?v8",baby_bottle:"unicode/1f37c.png?v8",baby_chick:"unicode/1f424.png?v8",baby_symbol:"unicode/1f6bc.png?v8",back:"unicode/1f519.png?v8",bacon:"unicode/1f953.png?v8",badger:"unicode/1f9a1.png?v8",badminton:"unicode/1f3f8.png?v8",bagel:"unicode/1f96f.png?v8",baggage_claim:"unicode/1f6c4.png?v8",baguette_bread:"unicode/1f956.png?v8",bahamas:"unicode/1f1e7-1f1f8.png?v8",bahrain:"unicode/1f1e7-1f1ed.png?v8",balance_scale:"unicode/2696.png?v8",bald_man:"unicode/1f468-1f9b2.png?v8",bald_woman:"unicode/1f469-1f9b2.png?v8",ballet_shoes:"unicode/1fa70.png?v8",balloon:"unicode/1f388.png?v8",ballot_box:"unicode/1f5f3.png?v8",ballot_box_with_check:"unicode/2611.png?v8",bamboo:"unicode/1f38d.png?v8",banana:"unicode/1f34c.png?v8",bangbang:"unicode/203c.png?v8",bangladesh:"unicode/1f1e7-1f1e9.png?v8",banjo:"unicode/1fa95.png?v8",bank:"unicode/1f3e6.png?v8",bar_chart:"unicode/1f4ca.png?v8",barbados:"unicode/1f1e7-1f1e7.png?v8",barber:"unicode/1f488.png?v8",baseball:"unicode/26be.png?v8",basecamp:"basecamp.png?v8",basecampy:"basecampy.png?v8",basket:"unicode/1f9fa.png?v8",basketball:"unicode/1f3c0.png?v8",basketball_man:"unicode/26f9-2642.png?v8",basketball_woman:"unicode/26f9-2640.png?v8",bat:"unicode/1f987.png?v8",bath:"unicode/1f6c0.png?v8",bathtub:"unicode/1f6c1.png?v8",battery:"unicode/1f50b.png?v8",beach_umbrella:"unicode/1f3d6.png?v8",bear:"unicode/1f43b.png?v8",bearded_person:"unicode/1f9d4.png?v8",beaver:"unicode/1f9ab.png?v8",bed:"unicode/1f6cf.png?v8",bee:"unicode/1f41d.png?v8",beer:"unicode/1f37a.png?v8",beers:"unicode/1f37b.png?v8",beetle:"unicode/1fab2.png?v8",beginner:"unicode/1f530.png?v8",belarus:"unicode/1f1e7-1f1fe.png?v8",belgium:"unicode/1f1e7-1f1ea.png?v8",belize:"unicode/1f1e7-1f1ff.png?v8",bell:"unicode/1f514.png?v8",bell_pepper:"unicode/1fad1.png?v8",bellhop_bell:"unicode/1f6ce.png?v8",benin:"unicode/1f1e7-1f1ef.png?v8",bento:"unicode/1f371.png?v8",bermuda:"unicode/1f1e7-1f1f2.png?v8",beverage_box:"unicode/1f9c3.png?v8",bhutan:"unicode/1f1e7-1f1f9.png?v8",bicyclist:"unicode/1f6b4.png?v8",bike:"unicode/1f6b2.png?v8",biking_man:"unicode/1f6b4-2642.png?v8",biking_woman:"unicode/1f6b4-2640.png?v8",bikini:"unicode/1f459.png?v8",billed_cap:"unicode/1f9e2.png?v8",biohazard:"unicode/2623.png?v8",bird:"unicode/1f426.png?v8",birthday:"unicode/1f382.png?v8",bison:"unicode/1f9ac.png?v8",black_cat:"unicode/1f408-2b1b.png?v8",black_circle:"unicode/26ab.png?v8",black_flag:"unicode/1f3f4.png?v8",black_heart:"unicode/1f5a4.png?v8",black_joker:"unicode/1f0cf.png?v8",black_large_square:"unicode/2b1b.png?v8",black_medium_small_square:"unicode/25fe.png?v8",black_medium_square:"unicode/25fc.png?v8",black_nib:"unicode/2712.png?v8",black_small_square:"unicode/25aa.png?v8",black_square_button:"unicode/1f532.png?v8",blond_haired_man:"unicode/1f471-2642.png?v8",blond_haired_person:"unicode/1f471.png?v8",blond_haired_woman:"unicode/1f471-2640.png?v8",blonde_woman:"unicode/1f471-2640.png?v8",blossom:"unicode/1f33c.png?v8",blowfish:"unicode/1f421.png?v8",blue_book:"unicode/1f4d8.png?v8",blue_car:"unicode/1f699.png?v8",blue_heart:"unicode/1f499.png?v8",blue_square:"unicode/1f7e6.png?v8",blueberries:"unicode/1fad0.png?v8",blush:"unicode/1f60a.png?v8",boar:"unicode/1f417.png?v8",boat:"unicode/26f5.png?v8",bolivia:"unicode/1f1e7-1f1f4.png?v8",bomb:"unicode/1f4a3.png?v8",bone:"unicode/1f9b4.png?v8",book:"unicode/1f4d6.png?v8",bookmark:"unicode/1f516.png?v8",bookmark_tabs:"unicode/1f4d1.png?v8",books:"unicode/1f4da.png?v8",boom:"unicode/1f4a5.png?v8",boomerang:"unicode/1fa83.png?v8",boot:"unicode/1f462.png?v8",bosnia_herzegovina:"unicode/1f1e7-1f1e6.png?v8",botswana:"unicode/1f1e7-1f1fc.png?v8",bouncing_ball_man:"unicode/26f9-2642.png?v8",bouncing_ball_person:"unicode/26f9.png?v8",bouncing_ball_woman:"unicode/26f9-2640.png?v8",bouquet:"unicode/1f490.png?v8",bouvet_island:"unicode/1f1e7-1f1fb.png?v8",bow:"unicode/1f647.png?v8",bow_and_arrow:"unicode/1f3f9.png?v8",bowing_man:"unicode/1f647-2642.png?v8",bowing_woman:"unicode/1f647-2640.png?v8",bowl_with_spoon:"unicode/1f963.png?v8",bowling:"unicode/1f3b3.png?v8",bowtie:"bowtie.png?v8",boxing_glove:"unicode/1f94a.png?v8",boy:"unicode/1f466.png?v8",brain:"unicode/1f9e0.png?v8",brazil:"unicode/1f1e7-1f1f7.png?v8",bread:"unicode/1f35e.png?v8",breast_feeding:"unicode/1f931.png?v8",bricks:"unicode/1f9f1.png?v8",bride_with_veil:"unicode/1f470-2640.png?v8",bridge_at_night:"unicode/1f309.png?v8",briefcase:"unicode/1f4bc.png?v8",british_indian_ocean_territory:"unicode/1f1ee-1f1f4.png?v8",british_virgin_islands:"unicode/1f1fb-1f1ec.png?v8",broccoli:"unicode/1f966.png?v8",broken_heart:"unicode/1f494.png?v8",broom:"unicode/1f9f9.png?v8",brown_circle:"unicode/1f7e4.png?v8",brown_heart:"unicode/1f90e.png?v8",brown_square:"unicode/1f7eb.png?v8",brunei:"unicode/1f1e7-1f1f3.png?v8",bubble_tea:"unicode/1f9cb.png?v8",bucket:"unicode/1faa3.png?v8",bug:"unicode/1f41b.png?v8",building_construction:"unicode/1f3d7.png?v8",bulb:"unicode/1f4a1.png?v8",bulgaria:"unicode/1f1e7-1f1ec.png?v8",bullettrain_front:"unicode/1f685.png?v8",bullettrain_side:"unicode/1f684.png?v8",burkina_faso:"unicode/1f1e7-1f1eb.png?v8",burrito:"unicode/1f32f.png?v8",burundi:"unicode/1f1e7-1f1ee.png?v8",bus:"unicode/1f68c.png?v8",business_suit_levitating:"unicode/1f574.png?v8",busstop:"unicode/1f68f.png?v8",bust_in_silhouette:"unicode/1f464.png?v8",busts_in_silhouette:"unicode/1f465.png?v8",butter:"unicode/1f9c8.png?v8",butterfly:"unicode/1f98b.png?v8",cactus:"unicode/1f335.png?v8",cake:"unicode/1f370.png?v8",calendar:"unicode/1f4c6.png?v8",call_me_hand:"unicode/1f919.png?v8",calling:"unicode/1f4f2.png?v8",cambodia:"unicode/1f1f0-1f1ed.png?v8",camel:"unicode/1f42b.png?v8",camera:"unicode/1f4f7.png?v8",camera_flash:"unicode/1f4f8.png?v8",cameroon:"unicode/1f1e8-1f1f2.png?v8",camping:"unicode/1f3d5.png?v8",canada:"unicode/1f1e8-1f1e6.png?v8",canary_islands:"unicode/1f1ee-1f1e8.png?v8",cancer:"unicode/264b.png?v8",candle:"unicode/1f56f.png?v8",candy:"unicode/1f36c.png?v8",canned_food:"unicode/1f96b.png?v8",canoe:"unicode/1f6f6.png?v8",cape_verde:"unicode/1f1e8-1f1fb.png?v8",capital_abcd:"unicode/1f520.png?v8",capricorn:"unicode/2651.png?v8",car:"unicode/1f697.png?v8",card_file_box:"unicode/1f5c3.png?v8",card_index:"unicode/1f4c7.png?v8",card_index_dividers:"unicode/1f5c2.png?v8",caribbean_netherlands:"unicode/1f1e7-1f1f6.png?v8",carousel_horse:"unicode/1f3a0.png?v8",carpentry_saw:"unicode/1fa9a.png?v8",carrot:"unicode/1f955.png?v8",cartwheeling:"unicode/1f938.png?v8",cat:"unicode/1f431.png?v8",cat2:"unicode/1f408.png?v8",cayman_islands:"unicode/1f1f0-1f1fe.png?v8",cd:"unicode/1f4bf.png?v8",central_african_republic:"unicode/1f1e8-1f1eb.png?v8",ceuta_melilla:"unicode/1f1ea-1f1e6.png?v8",chad:"unicode/1f1f9-1f1e9.png?v8",chains:"unicode/26d3.png?v8",chair:"unicode/1fa91.png?v8",champagne:"unicode/1f37e.png?v8",chart:"unicode/1f4b9.png?v8",chart_with_downwards_trend:"unicode/1f4c9.png?v8",chart_with_upwards_trend:"unicode/1f4c8.png?v8",checkered_flag:"unicode/1f3c1.png?v8",cheese:"unicode/1f9c0.png?v8",cherries:"unicode/1f352.png?v8",cherry_blossom:"unicode/1f338.png?v8",chess_pawn:"unicode/265f.png?v8",chestnut:"unicode/1f330.png?v8",chicken:"unicode/1f414.png?v8",child:"unicode/1f9d2.png?v8",children_crossing:"unicode/1f6b8.png?v8",chile:"unicode/1f1e8-1f1f1.png?v8",chipmunk:"unicode/1f43f.png?v8",chocolate_bar:"unicode/1f36b.png?v8",chopsticks:"unicode/1f962.png?v8",christmas_island:"unicode/1f1e8-1f1fd.png?v8",christmas_tree:"unicode/1f384.png?v8",church:"unicode/26ea.png?v8",cinema:"unicode/1f3a6.png?v8",circus_tent:"unicode/1f3aa.png?v8",city_sunrise:"unicode/1f307.png?v8",city_sunset:"unicode/1f306.png?v8",cityscape:"unicode/1f3d9.png?v8",cl:"unicode/1f191.png?v8",clamp:"unicode/1f5dc.png?v8",clap:"unicode/1f44f.png?v8",clapper:"unicode/1f3ac.png?v8",classical_building:"unicode/1f3db.png?v8",climbing:"unicode/1f9d7.png?v8",climbing_man:"unicode/1f9d7-2642.png?v8",climbing_woman:"unicode/1f9d7-2640.png?v8",clinking_glasses:"unicode/1f942.png?v8",clipboard:"unicode/1f4cb.png?v8",clipperton_island:"unicode/1f1e8-1f1f5.png?v8",clock1:"unicode/1f550.png?v8",clock10:"unicode/1f559.png?v8",clock1030:"unicode/1f565.png?v8",clock11:"unicode/1f55a.png?v8",clock1130:"unicode/1f566.png?v8",clock12:"unicode/1f55b.png?v8",clock1230:"unicode/1f567.png?v8",clock130:"unicode/1f55c.png?v8",clock2:"unicode/1f551.png?v8",clock230:"unicode/1f55d.png?v8",clock3:"unicode/1f552.png?v8",clock330:"unicode/1f55e.png?v8",clock4:"unicode/1f553.png?v8",clock430:"unicode/1f55f.png?v8",clock5:"unicode/1f554.png?v8",clock530:"unicode/1f560.png?v8",clock6:"unicode/1f555.png?v8",clock630:"unicode/1f561.png?v8",clock7:"unicode/1f556.png?v8",clock730:"unicode/1f562.png?v8",clock8:"unicode/1f557.png?v8",clock830:"unicode/1f563.png?v8",clock9:"unicode/1f558.png?v8",clock930:"unicode/1f564.png?v8",closed_book:"unicode/1f4d5.png?v8",closed_lock_with_key:"unicode/1f510.png?v8",closed_umbrella:"unicode/1f302.png?v8",cloud:"unicode/2601.png?v8",cloud_with_lightning:"unicode/1f329.png?v8",cloud_with_lightning_and_rain:"unicode/26c8.png?v8",cloud_with_rain:"unicode/1f327.png?v8",cloud_with_snow:"unicode/1f328.png?v8",clown_face:"unicode/1f921.png?v8",clubs:"unicode/2663.png?v8",cn:"unicode/1f1e8-1f1f3.png?v8",coat:"unicode/1f9e5.png?v8",cockroach:"unicode/1fab3.png?v8",cocktail:"unicode/1f378.png?v8",coconut:"unicode/1f965.png?v8",cocos_islands:"unicode/1f1e8-1f1e8.png?v8",coffee:"unicode/2615.png?v8",coffin:"unicode/26b0.png?v8",coin:"unicode/1fa99.png?v8",cold_face:"unicode/1f976.png?v8",cold_sweat:"unicode/1f630.png?v8",collision:"unicode/1f4a5.png?v8",colombia:"unicode/1f1e8-1f1f4.png?v8",comet:"unicode/2604.png?v8",comoros:"unicode/1f1f0-1f1f2.png?v8",compass:"unicode/1f9ed.png?v8",computer:"unicode/1f4bb.png?v8",computer_mouse:"unicode/1f5b1.png?v8",confetti_ball:"unicode/1f38a.png?v8",confounded:"unicode/1f616.png?v8",confused:"unicode/1f615.png?v8",congo_brazzaville:"unicode/1f1e8-1f1ec.png?v8",congo_kinshasa:"unicode/1f1e8-1f1e9.png?v8",congratulations:"unicode/3297.png?v8",construction:"unicode/1f6a7.png?v8",construction_worker:"unicode/1f477.png?v8",construction_worker_man:"unicode/1f477-2642.png?v8",construction_worker_woman:"unicode/1f477-2640.png?v8",control_knobs:"unicode/1f39b.png?v8",convenience_store:"unicode/1f3ea.png?v8",cook:"unicode/1f9d1-1f373.png?v8",cook_islands:"unicode/1f1e8-1f1f0.png?v8",cookie:"unicode/1f36a.png?v8",cool:"unicode/1f192.png?v8",cop:"unicode/1f46e.png?v8",copyright:"unicode/00a9.png?v8",corn:"unicode/1f33d.png?v8",costa_rica:"unicode/1f1e8-1f1f7.png?v8",cote_divoire:"unicode/1f1e8-1f1ee.png?v8",couch_and_lamp:"unicode/1f6cb.png?v8",couple:"unicode/1f46b.png?v8",couple_with_heart:"unicode/1f491.png?v8",couple_with_heart_man_man:"unicode/1f468-2764-1f468.png?v8",couple_with_heart_woman_man:"unicode/1f469-2764-1f468.png?v8",couple_with_heart_woman_woman:"unicode/1f469-2764-1f469.png?v8",couplekiss:"unicode/1f48f.png?v8",couplekiss_man_man:"unicode/1f468-2764-1f48b-1f468.png?v8",couplekiss_man_woman:"unicode/1f469-2764-1f48b-1f468.png?v8",couplekiss_woman_woman:"unicode/1f469-2764-1f48b-1f469.png?v8",cow:"unicode/1f42e.png?v8",cow2:"unicode/1f404.png?v8",cowboy_hat_face:"unicode/1f920.png?v8",crab:"unicode/1f980.png?v8",crayon:"unicode/1f58d.png?v8",credit_card:"unicode/1f4b3.png?v8",crescent_moon:"unicode/1f319.png?v8",cricket:"unicode/1f997.png?v8",cricket_game:"unicode/1f3cf.png?v8",croatia:"unicode/1f1ed-1f1f7.png?v8",crocodile:"unicode/1f40a.png?v8",croissant:"unicode/1f950.png?v8",crossed_fingers:"unicode/1f91e.png?v8",crossed_flags:"unicode/1f38c.png?v8",crossed_swords:"unicode/2694.png?v8",crown:"unicode/1f451.png?v8",cry:"unicode/1f622.png?v8",crying_cat_face:"unicode/1f63f.png?v8",crystal_ball:"unicode/1f52e.png?v8",cuba:"unicode/1f1e8-1f1fa.png?v8",cucumber:"unicode/1f952.png?v8",cup_with_straw:"unicode/1f964.png?v8",cupcake:"unicode/1f9c1.png?v8",cupid:"unicode/1f498.png?v8",curacao:"unicode/1f1e8-1f1fc.png?v8",curling_stone:"unicode/1f94c.png?v8",curly_haired_man:"unicode/1f468-1f9b1.png?v8",curly_haired_woman:"unicode/1f469-1f9b1.png?v8",curly_loop:"unicode/27b0.png?v8",currency_exchange:"unicode/1f4b1.png?v8",curry:"unicode/1f35b.png?v8",cursing_face:"unicode/1f92c.png?v8",custard:"unicode/1f36e.png?v8",customs:"unicode/1f6c3.png?v8",cut_of_meat:"unicode/1f969.png?v8",cyclone:"unicode/1f300.png?v8",cyprus:"unicode/1f1e8-1f1fe.png?v8",czech_republic:"unicode/1f1e8-1f1ff.png?v8",dagger:"unicode/1f5e1.png?v8",dancer:"unicode/1f483.png?v8",dancers:"unicode/1f46f.png?v8",dancing_men:"unicode/1f46f-2642.png?v8",dancing_women:"unicode/1f46f-2640.png?v8",dango:"unicode/1f361.png?v8",dark_sunglasses:"unicode/1f576.png?v8",dart:"unicode/1f3af.png?v8",dash:"unicode/1f4a8.png?v8",date:"unicode/1f4c5.png?v8",de:"unicode/1f1e9-1f1ea.png?v8",deaf_man:"unicode/1f9cf-2642.png?v8",deaf_person:"unicode/1f9cf.png?v8",deaf_woman:"unicode/1f9cf-2640.png?v8",deciduous_tree:"unicode/1f333.png?v8",deer:"unicode/1f98c.png?v8",denmark:"unicode/1f1e9-1f1f0.png?v8",department_store:"unicode/1f3ec.png?v8",derelict_house:"unicode/1f3da.png?v8",desert:"unicode/1f3dc.png?v8",desert_island:"unicode/1f3dd.png?v8",desktop_computer:"unicode/1f5a5.png?v8",detective:"unicode/1f575.png?v8",diamond_shape_with_a_dot_inside:"unicode/1f4a0.png?v8",diamonds:"unicode/2666.png?v8",diego_garcia:"unicode/1f1e9-1f1ec.png?v8",disappointed:"unicode/1f61e.png?v8",disappointed_relieved:"unicode/1f625.png?v8",disguised_face:"unicode/1f978.png?v8",diving_mask:"unicode/1f93f.png?v8",diya_lamp:"unicode/1fa94.png?v8",dizzy:"unicode/1f4ab.png?v8",dizzy_face:"unicode/1f635.png?v8",djibouti:"unicode/1f1e9-1f1ef.png?v8",dna:"unicode/1f9ec.png?v8",do_not_litter:"unicode/1f6af.png?v8",dodo:"unicode/1f9a4.png?v8",dog:"unicode/1f436.png?v8",dog2:"unicode/1f415.png?v8",dollar:"unicode/1f4b5.png?v8",dolls:"unicode/1f38e.png?v8",dolphin:"unicode/1f42c.png?v8",dominica:"unicode/1f1e9-1f1f2.png?v8",dominican_republic:"unicode/1f1e9-1f1f4.png?v8",door:"unicode/1f6aa.png?v8",doughnut:"unicode/1f369.png?v8",dove:"unicode/1f54a.png?v8",dragon:"unicode/1f409.png?v8",dragon_face:"unicode/1f432.png?v8",dress:"unicode/1f457.png?v8",dromedary_camel:"unicode/1f42a.png?v8",drooling_face:"unicode/1f924.png?v8",drop_of_blood:"unicode/1fa78.png?v8",droplet:"unicode/1f4a7.png?v8",drum:"unicode/1f941.png?v8",duck:"unicode/1f986.png?v8",dumpling:"unicode/1f95f.png?v8",dvd:"unicode/1f4c0.png?v8","e-mail":"unicode/1f4e7.png?v8",eagle:"unicode/1f985.png?v8",ear:"unicode/1f442.png?v8",ear_of_rice:"unicode/1f33e.png?v8",ear_with_hearing_aid:"unicode/1f9bb.png?v8",earth_africa:"unicode/1f30d.png?v8",earth_americas:"unicode/1f30e.png?v8",earth_asia:"unicode/1f30f.png?v8",ecuador:"unicode/1f1ea-1f1e8.png?v8",egg:"unicode/1f95a.png?v8",eggplant:"unicode/1f346.png?v8",egypt:"unicode/1f1ea-1f1ec.png?v8",eight:"unicode/0038-20e3.png?v8",eight_pointed_black_star:"unicode/2734.png?v8",eight_spoked_asterisk:"unicode/2733.png?v8",eject_button:"unicode/23cf.png?v8",el_salvador:"unicode/1f1f8-1f1fb.png?v8",electric_plug:"unicode/1f50c.png?v8",electron:"electron.png?v8",elephant:"unicode/1f418.png?v8",elevator:"unicode/1f6d7.png?v8",elf:"unicode/1f9dd.png?v8",elf_man:"unicode/1f9dd-2642.png?v8",elf_woman:"unicode/1f9dd-2640.png?v8",email:"unicode/1f4e7.png?v8",end:"unicode/1f51a.png?v8",england:"unicode/1f3f4-e0067-e0062-e0065-e006e-e0067-e007f.png?v8",envelope:"unicode/2709.png?v8",envelope_with_arrow:"unicode/1f4e9.png?v8",equatorial_guinea:"unicode/1f1ec-1f1f6.png?v8",eritrea:"unicode/1f1ea-1f1f7.png?v8",es:"unicode/1f1ea-1f1f8.png?v8",estonia:"unicode/1f1ea-1f1ea.png?v8",ethiopia:"unicode/1f1ea-1f1f9.png?v8",eu:"unicode/1f1ea-1f1fa.png?v8",euro:"unicode/1f4b6.png?v8",european_castle:"unicode/1f3f0.png?v8",european_post_office:"unicode/1f3e4.png?v8",european_union:"unicode/1f1ea-1f1fa.png?v8",evergreen_tree:"unicode/1f332.png?v8",exclamation:"unicode/2757.png?v8",exploding_head:"unicode/1f92f.png?v8",expressionless:"unicode/1f611.png?v8",eye:"unicode/1f441.png?v8",eye_speech_bubble:"unicode/1f441-1f5e8.png?v8",eyeglasses:"unicode/1f453.png?v8",eyes:"unicode/1f440.png?v8",face_exhaling:"unicode/1f62e-1f4a8.png?v8",face_in_clouds:"unicode/1f636-1f32b.png?v8",face_with_head_bandage:"unicode/1f915.png?v8",face_with_spiral_eyes:"unicode/1f635-1f4ab.png?v8",face_with_thermometer:"unicode/1f912.png?v8",facepalm:"unicode/1f926.png?v8",facepunch:"unicode/1f44a.png?v8",factory:"unicode/1f3ed.png?v8",factory_worker:"unicode/1f9d1-1f3ed.png?v8",fairy:"unicode/1f9da.png?v8",fairy_man:"unicode/1f9da-2642.png?v8",fairy_woman:"unicode/1f9da-2640.png?v8",falafel:"unicode/1f9c6.png?v8",falkland_islands:"unicode/1f1eb-1f1f0.png?v8",fallen_leaf:"unicode/1f342.png?v8",family:"unicode/1f46a.png?v8",family_man_boy:"unicode/1f468-1f466.png?v8",family_man_boy_boy:"unicode/1f468-1f466-1f466.png?v8",family_man_girl:"unicode/1f468-1f467.png?v8",family_man_girl_boy:"unicode/1f468-1f467-1f466.png?v8",family_man_girl_girl:"unicode/1f468-1f467-1f467.png?v8",family_man_man_boy:"unicode/1f468-1f468-1f466.png?v8",family_man_man_boy_boy:"unicode/1f468-1f468-1f466-1f466.png?v8",family_man_man_girl:"unicode/1f468-1f468-1f467.png?v8",family_man_man_girl_boy:"unicode/1f468-1f468-1f467-1f466.png?v8",family_man_man_girl_girl:"unicode/1f468-1f468-1f467-1f467.png?v8",family_man_woman_boy:"unicode/1f468-1f469-1f466.png?v8",family_man_woman_boy_boy:"unicode/1f468-1f469-1f466-1f466.png?v8",family_man_woman_girl:"unicode/1f468-1f469-1f467.png?v8",family_man_woman_girl_boy:"unicode/1f468-1f469-1f467-1f466.png?v8",family_man_woman_girl_girl:"unicode/1f468-1f469-1f467-1f467.png?v8",family_woman_boy:"unicode/1f469-1f466.png?v8",family_woman_boy_boy:"unicode/1f469-1f466-1f466.png?v8",family_woman_girl:"unicode/1f469-1f467.png?v8",family_woman_girl_boy:"unicode/1f469-1f467-1f466.png?v8",family_woman_girl_girl:"unicode/1f469-1f467-1f467.png?v8",family_woman_woman_boy:"unicode/1f469-1f469-1f466.png?v8",family_woman_woman_boy_boy:"unicode/1f469-1f469-1f466-1f466.png?v8",family_woman_woman_girl:"unicode/1f469-1f469-1f467.png?v8",family_woman_woman_girl_boy:"unicode/1f469-1f469-1f467-1f466.png?v8",family_woman_woman_girl_girl:"unicode/1f469-1f469-1f467-1f467.png?v8",farmer:"unicode/1f9d1-1f33e.png?v8",faroe_islands:"unicode/1f1eb-1f1f4.png?v8",fast_forward:"unicode/23e9.png?v8",fax:"unicode/1f4e0.png?v8",fearful:"unicode/1f628.png?v8",feather:"unicode/1fab6.png?v8",feelsgood:"feelsgood.png?v8",feet:"unicode/1f43e.png?v8",female_detective:"unicode/1f575-2640.png?v8",female_sign:"unicode/2640.png?v8",ferris_wheel:"unicode/1f3a1.png?v8",ferry:"unicode/26f4.png?v8",field_hockey:"unicode/1f3d1.png?v8",fiji:"unicode/1f1eb-1f1ef.png?v8",file_cabinet:"unicode/1f5c4.png?v8",file_folder:"unicode/1f4c1.png?v8",film_projector:"unicode/1f4fd.png?v8",film_strip:"unicode/1f39e.png?v8",finland:"unicode/1f1eb-1f1ee.png?v8",finnadie:"finnadie.png?v8",fire:"unicode/1f525.png?v8",fire_engine:"unicode/1f692.png?v8",fire_extinguisher:"unicode/1f9ef.png?v8",firecracker:"unicode/1f9e8.png?v8",firefighter:"unicode/1f9d1-1f692.png?v8",fireworks:"unicode/1f386.png?v8",first_quarter_moon:"unicode/1f313.png?v8",first_quarter_moon_with_face:"unicode/1f31b.png?v8",fish:"unicode/1f41f.png?v8",fish_cake:"unicode/1f365.png?v8",fishing_pole_and_fish:"unicode/1f3a3.png?v8",fist:"unicode/270a.png?v8",fist_left:"unicode/1f91b.png?v8",fist_oncoming:"unicode/1f44a.png?v8",fist_raised:"unicode/270a.png?v8",fist_right:"unicode/1f91c.png?v8",five:"unicode/0035-20e3.png?v8",flags:"unicode/1f38f.png?v8",flamingo:"unicode/1f9a9.png?v8",flashlight:"unicode/1f526.png?v8",flat_shoe:"unicode/1f97f.png?v8",flatbread:"unicode/1fad3.png?v8",fleur_de_lis:"unicode/269c.png?v8",flight_arrival:"unicode/1f6ec.png?v8",flight_departure:"unicode/1f6eb.png?v8",flipper:"unicode/1f42c.png?v8",floppy_disk:"unicode/1f4be.png?v8",flower_playing_cards:"unicode/1f3b4.png?v8",flushed:"unicode/1f633.png?v8",fly:"unicode/1fab0.png?v8",flying_disc:"unicode/1f94f.png?v8",flying_saucer:"unicode/1f6f8.png?v8",fog:"unicode/1f32b.png?v8",foggy:"unicode/1f301.png?v8",fondue:"unicode/1fad5.png?v8",foot:"unicode/1f9b6.png?v8",football:"unicode/1f3c8.png?v8",footprints:"unicode/1f463.png?v8",fork_and_knife:"unicode/1f374.png?v8",fortune_cookie:"unicode/1f960.png?v8",fountain:"unicode/26f2.png?v8",fountain_pen:"unicode/1f58b.png?v8",four:"unicode/0034-20e3.png?v8",four_leaf_clover:"unicode/1f340.png?v8",fox_face:"unicode/1f98a.png?v8",fr:"unicode/1f1eb-1f1f7.png?v8",framed_picture:"unicode/1f5bc.png?v8",free:"unicode/1f193.png?v8",french_guiana:"unicode/1f1ec-1f1eb.png?v8",french_polynesia:"unicode/1f1f5-1f1eb.png?v8",french_southern_territories:"unicode/1f1f9-1f1eb.png?v8",fried_egg:"unicode/1f373.png?v8",fried_shrimp:"unicode/1f364.png?v8",fries:"unicode/1f35f.png?v8",frog:"unicode/1f438.png?v8",frowning:"unicode/1f626.png?v8",frowning_face:"unicode/2639.png?v8",frowning_man:"unicode/1f64d-2642.png?v8",frowning_person:"unicode/1f64d.png?v8",frowning_woman:"unicode/1f64d-2640.png?v8",fu:"unicode/1f595.png?v8",fuelpump:"unicode/26fd.png?v8",full_moon:"unicode/1f315.png?v8",full_moon_with_face:"unicode/1f31d.png?v8",funeral_urn:"unicode/26b1.png?v8",gabon:"unicode/1f1ec-1f1e6.png?v8",gambia:"unicode/1f1ec-1f1f2.png?v8",game_die:"unicode/1f3b2.png?v8",garlic:"unicode/1f9c4.png?v8",gb:"unicode/1f1ec-1f1e7.png?v8",gear:"unicode/2699.png?v8",gem:"unicode/1f48e.png?v8",gemini:"unicode/264a.png?v8",genie:"unicode/1f9de.png?v8",genie_man:"unicode/1f9de-2642.png?v8",genie_woman:"unicode/1f9de-2640.png?v8",georgia:"unicode/1f1ec-1f1ea.png?v8",ghana:"unicode/1f1ec-1f1ed.png?v8",ghost:"unicode/1f47b.png?v8",gibraltar:"unicode/1f1ec-1f1ee.png?v8",gift:"unicode/1f381.png?v8",gift_heart:"unicode/1f49d.png?v8",giraffe:"unicode/1f992.png?v8",girl:"unicode/1f467.png?v8",globe_with_meridians:"unicode/1f310.png?v8",gloves:"unicode/1f9e4.png?v8",goal_net:"unicode/1f945.png?v8",goat:"unicode/1f410.png?v8",goberserk:"goberserk.png?v8",godmode:"godmode.png?v8",goggles:"unicode/1f97d.png?v8",golf:"unicode/26f3.png?v8",golfing:"unicode/1f3cc.png?v8",golfing_man:"unicode/1f3cc-2642.png?v8",golfing_woman:"unicode/1f3cc-2640.png?v8",gorilla:"unicode/1f98d.png?v8",grapes:"unicode/1f347.png?v8",greece:"unicode/1f1ec-1f1f7.png?v8",green_apple:"unicode/1f34f.png?v8",green_book:"unicode/1f4d7.png?v8",green_circle:"unicode/1f7e2.png?v8",green_heart:"unicode/1f49a.png?v8",green_salad:"unicode/1f957.png?v8",green_square:"unicode/1f7e9.png?v8",greenland:"unicode/1f1ec-1f1f1.png?v8",grenada:"unicode/1f1ec-1f1e9.png?v8",grey_exclamation:"unicode/2755.png?v8",grey_question:"unicode/2754.png?v8",grimacing:"unicode/1f62c.png?v8",grin:"unicode/1f601.png?v8",grinning:"unicode/1f600.png?v8",guadeloupe:"unicode/1f1ec-1f1f5.png?v8",guam:"unicode/1f1ec-1f1fa.png?v8",guard:"unicode/1f482.png?v8",guardsman:"unicode/1f482-2642.png?v8",guardswoman:"unicode/1f482-2640.png?v8",guatemala:"unicode/1f1ec-1f1f9.png?v8",guernsey:"unicode/1f1ec-1f1ec.png?v8",guide_dog:"unicode/1f9ae.png?v8",guinea:"unicode/1f1ec-1f1f3.png?v8",guinea_bissau:"unicode/1f1ec-1f1fc.png?v8",guitar:"unicode/1f3b8.png?v8",gun:"unicode/1f52b.png?v8",guyana:"unicode/1f1ec-1f1fe.png?v8",haircut:"unicode/1f487.png?v8",haircut_man:"unicode/1f487-2642.png?v8",haircut_woman:"unicode/1f487-2640.png?v8",haiti:"unicode/1f1ed-1f1f9.png?v8",hamburger:"unicode/1f354.png?v8",hammer:"unicode/1f528.png?v8",hammer_and_pick:"unicode/2692.png?v8",hammer_and_wrench:"unicode/1f6e0.png?v8",hamster:"unicode/1f439.png?v8",hand:"unicode/270b.png?v8",hand_over_mouth:"unicode/1f92d.png?v8",handbag:"unicode/1f45c.png?v8",handball_person:"unicode/1f93e.png?v8",handshake:"unicode/1f91d.png?v8",hankey:"unicode/1f4a9.png?v8",hash:"unicode/0023-20e3.png?v8",hatched_chick:"unicode/1f425.png?v8",hatching_chick:"unicode/1f423.png?v8",headphones:"unicode/1f3a7.png?v8",headstone:"unicode/1faa6.png?v8",health_worker:"unicode/1f9d1-2695.png?v8",hear_no_evil:"unicode/1f649.png?v8",heard_mcdonald_islands:"unicode/1f1ed-1f1f2.png?v8",heart:"unicode/2764.png?v8",heart_decoration:"unicode/1f49f.png?v8",heart_eyes:"unicode/1f60d.png?v8",heart_eyes_cat:"unicode/1f63b.png?v8",heart_on_fire:"unicode/2764-1f525.png?v8",heartbeat:"unicode/1f493.png?v8",heartpulse:"unicode/1f497.png?v8",hearts:"unicode/2665.png?v8",heavy_check_mark:"unicode/2714.png?v8",heavy_division_sign:"unicode/2797.png?v8",heavy_dollar_sign:"unicode/1f4b2.png?v8",heavy_exclamation_mark:"unicode/2757.png?v8",heavy_heart_exclamation:"unicode/2763.png?v8",heavy_minus_sign:"unicode/2796.png?v8",heavy_multiplication_x:"unicode/2716.png?v8",heavy_plus_sign:"unicode/2795.png?v8",hedgehog:"unicode/1f994.png?v8",helicopter:"unicode/1f681.png?v8",herb:"unicode/1f33f.png?v8",hibiscus:"unicode/1f33a.png?v8",high_brightness:"unicode/1f506.png?v8",high_heel:"unicode/1f460.png?v8",hiking_boot:"unicode/1f97e.png?v8",hindu_temple:"unicode/1f6d5.png?v8",hippopotamus:"unicode/1f99b.png?v8",hocho:"unicode/1f52a.png?v8",hole:"unicode/1f573.png?v8",honduras:"unicode/1f1ed-1f1f3.png?v8",honey_pot:"unicode/1f36f.png?v8",honeybee:"unicode/1f41d.png?v8",hong_kong:"unicode/1f1ed-1f1f0.png?v8",hook:"unicode/1fa9d.png?v8",horse:"unicode/1f434.png?v8",horse_racing:"unicode/1f3c7.png?v8",hospital:"unicode/1f3e5.png?v8",hot_face:"unicode/1f975.png?v8",hot_pepper:"unicode/1f336.png?v8",hotdog:"unicode/1f32d.png?v8",hotel:"unicode/1f3e8.png?v8",hotsprings:"unicode/2668.png?v8",hourglass:"unicode/231b.png?v8",hourglass_flowing_sand:"unicode/23f3.png?v8",house:"unicode/1f3e0.png?v8",house_with_garden:"unicode/1f3e1.png?v8",houses:"unicode/1f3d8.png?v8",hugs:"unicode/1f917.png?v8",hungary:"unicode/1f1ed-1f1fa.png?v8",hurtrealbad:"hurtrealbad.png?v8",hushed:"unicode/1f62f.png?v8",hut:"unicode/1f6d6.png?v8",ice_cream:"unicode/1f368.png?v8",ice_cube:"unicode/1f9ca.png?v8",ice_hockey:"unicode/1f3d2.png?v8",ice_skate:"unicode/26f8.png?v8",icecream:"unicode/1f366.png?v8",iceland:"unicode/1f1ee-1f1f8.png?v8",id:"unicode/1f194.png?v8",ideograph_advantage:"unicode/1f250.png?v8",imp:"unicode/1f47f.png?v8",inbox_tray:"unicode/1f4e5.png?v8",incoming_envelope:"unicode/1f4e8.png?v8",india:"unicode/1f1ee-1f1f3.png?v8",indonesia:"unicode/1f1ee-1f1e9.png?v8",infinity:"unicode/267e.png?v8",information_desk_person:"unicode/1f481.png?v8",information_source:"unicode/2139.png?v8",innocent:"unicode/1f607.png?v8",interrobang:"unicode/2049.png?v8",iphone:"unicode/1f4f1.png?v8",iran:"unicode/1f1ee-1f1f7.png?v8",iraq:"unicode/1f1ee-1f1f6.png?v8",ireland:"unicode/1f1ee-1f1ea.png?v8",isle_of_man:"unicode/1f1ee-1f1f2.png?v8",israel:"unicode/1f1ee-1f1f1.png?v8",it:"unicode/1f1ee-1f1f9.png?v8",izakaya_lantern:"unicode/1f3ee.png?v8",jack_o_lantern:"unicode/1f383.png?v8",jamaica:"unicode/1f1ef-1f1f2.png?v8",japan:"unicode/1f5fe.png?v8",japanese_castle:"unicode/1f3ef.png?v8",japanese_goblin:"unicode/1f47a.png?v8",japanese_ogre:"unicode/1f479.png?v8",jeans:"unicode/1f456.png?v8",jersey:"unicode/1f1ef-1f1ea.png?v8",jigsaw:"unicode/1f9e9.png?v8",jordan:"unicode/1f1ef-1f1f4.png?v8",joy:"unicode/1f602.png?v8",joy_cat:"unicode/1f639.png?v8",joystick:"unicode/1f579.png?v8",jp:"unicode/1f1ef-1f1f5.png?v8",judge:"unicode/1f9d1-2696.png?v8",juggling_person:"unicode/1f939.png?v8",kaaba:"unicode/1f54b.png?v8",kangaroo:"unicode/1f998.png?v8",kazakhstan:"unicode/1f1f0-1f1ff.png?v8",kenya:"unicode/1f1f0-1f1ea.png?v8",key:"unicode/1f511.png?v8",keyboard:"unicode/2328.png?v8",keycap_ten:"unicode/1f51f.png?v8",kick_scooter:"unicode/1f6f4.png?v8",kimono:"unicode/1f458.png?v8",kiribati:"unicode/1f1f0-1f1ee.png?v8",kiss:"unicode/1f48b.png?v8",kissing:"unicode/1f617.png?v8",kissing_cat:"unicode/1f63d.png?v8",kissing_closed_eyes:"unicode/1f61a.png?v8",kissing_heart:"unicode/1f618.png?v8",kissing_smiling_eyes:"unicode/1f619.png?v8",kite:"unicode/1fa81.png?v8",kiwi_fruit:"unicode/1f95d.png?v8",kneeling_man:"unicode/1f9ce-2642.png?v8",kneeling_person:"unicode/1f9ce.png?v8",kneeling_woman:"unicode/1f9ce-2640.png?v8",knife:"unicode/1f52a.png?v8",knot:"unicode/1faa2.png?v8",koala:"unicode/1f428.png?v8",koko:"unicode/1f201.png?v8",kosovo:"unicode/1f1fd-1f1f0.png?v8",kr:"unicode/1f1f0-1f1f7.png?v8",kuwait:"unicode/1f1f0-1f1fc.png?v8",kyrgyzstan:"unicode/1f1f0-1f1ec.png?v8",lab_coat:"unicode/1f97c.png?v8",label:"unicode/1f3f7.png?v8",lacrosse:"unicode/1f94d.png?v8",ladder:"unicode/1fa9c.png?v8",lady_beetle:"unicode/1f41e.png?v8",lantern:"unicode/1f3ee.png?v8",laos:"unicode/1f1f1-1f1e6.png?v8",large_blue_circle:"unicode/1f535.png?v8",large_blue_diamond:"unicode/1f537.png?v8",large_orange_diamond:"unicode/1f536.png?v8",last_quarter_moon:"unicode/1f317.png?v8",last_quarter_moon_with_face:"unicode/1f31c.png?v8",latin_cross:"unicode/271d.png?v8",latvia:"unicode/1f1f1-1f1fb.png?v8",laughing:"unicode/1f606.png?v8",leafy_green:"unicode/1f96c.png?v8",leaves:"unicode/1f343.png?v8",lebanon:"unicode/1f1f1-1f1e7.png?v8",ledger:"unicode/1f4d2.png?v8",left_luggage:"unicode/1f6c5.png?v8",left_right_arrow:"unicode/2194.png?v8",left_speech_bubble:"unicode/1f5e8.png?v8",leftwards_arrow_with_hook:"unicode/21a9.png?v8",leg:"unicode/1f9b5.png?v8",lemon:"unicode/1f34b.png?v8",leo:"unicode/264c.png?v8",leopard:"unicode/1f406.png?v8",lesotho:"unicode/1f1f1-1f1f8.png?v8",level_slider:"unicode/1f39a.png?v8",liberia:"unicode/1f1f1-1f1f7.png?v8",libra:"unicode/264e.png?v8",libya:"unicode/1f1f1-1f1fe.png?v8",liechtenstein:"unicode/1f1f1-1f1ee.png?v8",light_rail:"unicode/1f688.png?v8",link:"unicode/1f517.png?v8",lion:"unicode/1f981.png?v8",lips:"unicode/1f444.png?v8",lipstick:"unicode/1f484.png?v8",lithuania:"unicode/1f1f1-1f1f9.png?v8",lizard:"unicode/1f98e.png?v8",llama:"unicode/1f999.png?v8",lobster:"unicode/1f99e.png?v8",lock:"unicode/1f512.png?v8",lock_with_ink_pen:"unicode/1f50f.png?v8",lollipop:"unicode/1f36d.png?v8",long_drum:"unicode/1fa98.png?v8",loop:"unicode/27bf.png?v8",lotion_bottle:"unicode/1f9f4.png?v8",lotus_position:"unicode/1f9d8.png?v8",lotus_position_man:"unicode/1f9d8-2642.png?v8",lotus_position_woman:"unicode/1f9d8-2640.png?v8",loud_sound:"unicode/1f50a.png?v8",loudspeaker:"unicode/1f4e2.png?v8",love_hotel:"unicode/1f3e9.png?v8",love_letter:"unicode/1f48c.png?v8",love_you_gesture:"unicode/1f91f.png?v8",low_brightness:"unicode/1f505.png?v8",luggage:"unicode/1f9f3.png?v8",lungs:"unicode/1fac1.png?v8",luxembourg:"unicode/1f1f1-1f1fa.png?v8",lying_face:"unicode/1f925.png?v8",m:"unicode/24c2.png?v8",macau:"unicode/1f1f2-1f1f4.png?v8",macedonia:"unicode/1f1f2-1f1f0.png?v8",madagascar:"unicode/1f1f2-1f1ec.png?v8",mag:"unicode/1f50d.png?v8",mag_right:"unicode/1f50e.png?v8",mage:"unicode/1f9d9.png?v8",mage_man:"unicode/1f9d9-2642.png?v8",mage_woman:"unicode/1f9d9-2640.png?v8",magic_wand:"unicode/1fa84.png?v8",magnet:"unicode/1f9f2.png?v8",mahjong:"unicode/1f004.png?v8",mailbox:"unicode/1f4eb.png?v8",mailbox_closed:"unicode/1f4ea.png?v8",mailbox_with_mail:"unicode/1f4ec.png?v8",mailbox_with_no_mail:"unicode/1f4ed.png?v8",malawi:"unicode/1f1f2-1f1fc.png?v8",malaysia:"unicode/1f1f2-1f1fe.png?v8",maldives:"unicode/1f1f2-1f1fb.png?v8",male_detective:"unicode/1f575-2642.png?v8",male_sign:"unicode/2642.png?v8",mali:"unicode/1f1f2-1f1f1.png?v8",malta:"unicode/1f1f2-1f1f9.png?v8",mammoth:"unicode/1f9a3.png?v8",man:"unicode/1f468.png?v8",man_artist:"unicode/1f468-1f3a8.png?v8",man_astronaut:"unicode/1f468-1f680.png?v8",man_beard:"unicode/1f9d4-2642.png?v8",man_cartwheeling:"unicode/1f938-2642.png?v8",man_cook:"unicode/1f468-1f373.png?v8",man_dancing:"unicode/1f57a.png?v8",man_facepalming:"unicode/1f926-2642.png?v8",man_factory_worker:"unicode/1f468-1f3ed.png?v8",man_farmer:"unicode/1f468-1f33e.png?v8",man_feeding_baby:"unicode/1f468-1f37c.png?v8",man_firefighter:"unicode/1f468-1f692.png?v8",man_health_worker:"unicode/1f468-2695.png?v8",man_in_manual_wheelchair:"unicode/1f468-1f9bd.png?v8",man_in_motorized_wheelchair:"unicode/1f468-1f9bc.png?v8",man_in_tuxedo:"unicode/1f935-2642.png?v8",man_judge:"unicode/1f468-2696.png?v8",man_juggling:"unicode/1f939-2642.png?v8",man_mechanic:"unicode/1f468-1f527.png?v8",man_office_worker:"unicode/1f468-1f4bc.png?v8",man_pilot:"unicode/1f468-2708.png?v8",man_playing_handball:"unicode/1f93e-2642.png?v8",man_playing_water_polo:"unicode/1f93d-2642.png?v8",man_scientist:"unicode/1f468-1f52c.png?v8",man_shrugging:"unicode/1f937-2642.png?v8",man_singer:"unicode/1f468-1f3a4.png?v8",man_student:"unicode/1f468-1f393.png?v8",man_teacher:"unicode/1f468-1f3eb.png?v8",man_technologist:"unicode/1f468-1f4bb.png?v8",man_with_gua_pi_mao:"unicode/1f472.png?v8",man_with_probing_cane:"unicode/1f468-1f9af.png?v8",man_with_turban:"unicode/1f473-2642.png?v8",man_with_veil:"unicode/1f470-2642.png?v8",mandarin:"unicode/1f34a.png?v8",mango:"unicode/1f96d.png?v8",mans_shoe:"unicode/1f45e.png?v8",mantelpiece_clock:"unicode/1f570.png?v8",manual_wheelchair:"unicode/1f9bd.png?v8",maple_leaf:"unicode/1f341.png?v8",marshall_islands:"unicode/1f1f2-1f1ed.png?v8",martial_arts_uniform:"unicode/1f94b.png?v8",martinique:"unicode/1f1f2-1f1f6.png?v8",mask:"unicode/1f637.png?v8",massage:"unicode/1f486.png?v8",massage_man:"unicode/1f486-2642.png?v8",massage_woman:"unicode/1f486-2640.png?v8",mate:"unicode/1f9c9.png?v8",mauritania:"unicode/1f1f2-1f1f7.png?v8",mauritius:"unicode/1f1f2-1f1fa.png?v8",mayotte:"unicode/1f1fe-1f1f9.png?v8",meat_on_bone:"unicode/1f356.png?v8",mechanic:"unicode/1f9d1-1f527.png?v8",mechanical_arm:"unicode/1f9be.png?v8",mechanical_leg:"unicode/1f9bf.png?v8",medal_military:"unicode/1f396.png?v8",medal_sports:"unicode/1f3c5.png?v8",medical_symbol:"unicode/2695.png?v8",mega:"unicode/1f4e3.png?v8",melon:"unicode/1f348.png?v8",memo:"unicode/1f4dd.png?v8",men_wrestling:"unicode/1f93c-2642.png?v8",mending_heart:"unicode/2764-1fa79.png?v8",menorah:"unicode/1f54e.png?v8",mens:"unicode/1f6b9.png?v8",mermaid:"unicode/1f9dc-2640.png?v8",merman:"unicode/1f9dc-2642.png?v8",merperson:"unicode/1f9dc.png?v8",metal:"unicode/1f918.png?v8",metro:"unicode/1f687.png?v8",mexico:"unicode/1f1f2-1f1fd.png?v8",microbe:"unicode/1f9a0.png?v8",micronesia:"unicode/1f1eb-1f1f2.png?v8",microphone:"unicode/1f3a4.png?v8",microscope:"unicode/1f52c.png?v8",middle_finger:"unicode/1f595.png?v8",military_helmet:"unicode/1fa96.png?v8",milk_glass:"unicode/1f95b.png?v8",milky_way:"unicode/1f30c.png?v8",minibus:"unicode/1f690.png?v8",minidisc:"unicode/1f4bd.png?v8",mirror:"unicode/1fa9e.png?v8",mobile_phone_off:"unicode/1f4f4.png?v8",moldova:"unicode/1f1f2-1f1e9.png?v8",monaco:"unicode/1f1f2-1f1e8.png?v8",money_mouth_face:"unicode/1f911.png?v8",money_with_wings:"unicode/1f4b8.png?v8",moneybag:"unicode/1f4b0.png?v8",mongolia:"unicode/1f1f2-1f1f3.png?v8",monkey:"unicode/1f412.png?v8",monkey_face:"unicode/1f435.png?v8",monocle_face:"unicode/1f9d0.png?v8",monorail:"unicode/1f69d.png?v8",montenegro:"unicode/1f1f2-1f1ea.png?v8",montserrat:"unicode/1f1f2-1f1f8.png?v8",moon:"unicode/1f314.png?v8",moon_cake:"unicode/1f96e.png?v8",morocco:"unicode/1f1f2-1f1e6.png?v8",mortar_board:"unicode/1f393.png?v8",mosque:"unicode/1f54c.png?v8",mosquito:"unicode/1f99f.png?v8",motor_boat:"unicode/1f6e5.png?v8",motor_scooter:"unicode/1f6f5.png?v8",motorcycle:"unicode/1f3cd.png?v8",motorized_wheelchair:"unicode/1f9bc.png?v8",motorway:"unicode/1f6e3.png?v8",mount_fuji:"unicode/1f5fb.png?v8",mountain:"unicode/26f0.png?v8",mountain_bicyclist:"unicode/1f6b5.png?v8",mountain_biking_man:"unicode/1f6b5-2642.png?v8",mountain_biking_woman:"unicode/1f6b5-2640.png?v8",mountain_cableway:"unicode/1f6a0.png?v8",mountain_railway:"unicode/1f69e.png?v8",mountain_snow:"unicode/1f3d4.png?v8",mouse:"unicode/1f42d.png?v8",mouse2:"unicode/1f401.png?v8",mouse_trap:"unicode/1faa4.png?v8",movie_camera:"unicode/1f3a5.png?v8",moyai:"unicode/1f5ff.png?v8",mozambique:"unicode/1f1f2-1f1ff.png?v8",mrs_claus:"unicode/1f936.png?v8",muscle:"unicode/1f4aa.png?v8",mushroom:"unicode/1f344.png?v8",musical_keyboard:"unicode/1f3b9.png?v8",musical_note:"unicode/1f3b5.png?v8",musical_score:"unicode/1f3bc.png?v8",mute:"unicode/1f507.png?v8",mx_claus:"unicode/1f9d1-1f384.png?v8",myanmar:"unicode/1f1f2-1f1f2.png?v8",nail_care:"unicode/1f485.png?v8",name_badge:"unicode/1f4db.png?v8",namibia:"unicode/1f1f3-1f1e6.png?v8",national_park:"unicode/1f3de.png?v8",nauru:"unicode/1f1f3-1f1f7.png?v8",nauseated_face:"unicode/1f922.png?v8",nazar_amulet:"unicode/1f9ff.png?v8",neckbeard:"neckbeard.png?v8",necktie:"unicode/1f454.png?v8",negative_squared_cross_mark:"unicode/274e.png?v8",nepal:"unicode/1f1f3-1f1f5.png?v8",nerd_face:"unicode/1f913.png?v8",nesting_dolls:"unicode/1fa86.png?v8",netherlands:"unicode/1f1f3-1f1f1.png?v8",neutral_face:"unicode/1f610.png?v8",new:"unicode/1f195.png?v8",new_caledonia:"unicode/1f1f3-1f1e8.png?v8",new_moon:"unicode/1f311.png?v8",new_moon_with_face:"unicode/1f31a.png?v8",new_zealand:"unicode/1f1f3-1f1ff.png?v8",newspaper:"unicode/1f4f0.png?v8",newspaper_roll:"unicode/1f5de.png?v8",next_track_button:"unicode/23ed.png?v8",ng:"unicode/1f196.png?v8",ng_man:"unicode/1f645-2642.png?v8",ng_woman:"unicode/1f645-2640.png?v8",nicaragua:"unicode/1f1f3-1f1ee.png?v8",niger:"unicode/1f1f3-1f1ea.png?v8",nigeria:"unicode/1f1f3-1f1ec.png?v8",night_with_stars:"unicode/1f303.png?v8",nine:"unicode/0039-20e3.png?v8",ninja:"unicode/1f977.png?v8",niue:"unicode/1f1f3-1f1fa.png?v8",no_bell:"unicode/1f515.png?v8",no_bicycles:"unicode/1f6b3.png?v8",no_entry:"unicode/26d4.png?v8",no_entry_sign:"unicode/1f6ab.png?v8",no_good:"unicode/1f645.png?v8",no_good_man:"unicode/1f645-2642.png?v8",no_good_woman:"unicode/1f645-2640.png?v8",no_mobile_phones:"unicode/1f4f5.png?v8",no_mouth:"unicode/1f636.png?v8",no_pedestrians:"unicode/1f6b7.png?v8",no_smoking:"unicode/1f6ad.png?v8","non-potable_water":"unicode/1f6b1.png?v8",norfolk_island:"unicode/1f1f3-1f1eb.png?v8",north_korea:"unicode/1f1f0-1f1f5.png?v8",northern_mariana_islands:"unicode/1f1f2-1f1f5.png?v8",norway:"unicode/1f1f3-1f1f4.png?v8",nose:"unicode/1f443.png?v8",notebook:"unicode/1f4d3.png?v8",notebook_with_decorative_cover:"unicode/1f4d4.png?v8",notes:"unicode/1f3b6.png?v8",nut_and_bolt:"unicode/1f529.png?v8",o:"unicode/2b55.png?v8",o2:"unicode/1f17e.png?v8",ocean:"unicode/1f30a.png?v8",octocat:"octocat.png?v8",octopus:"unicode/1f419.png?v8",oden:"unicode/1f362.png?v8",office:"unicode/1f3e2.png?v8",office_worker:"unicode/1f9d1-1f4bc.png?v8",oil_drum:"unicode/1f6e2.png?v8",ok:"unicode/1f197.png?v8",ok_hand:"unicode/1f44c.png?v8",ok_man:"unicode/1f646-2642.png?v8",ok_person:"unicode/1f646.png?v8",ok_woman:"unicode/1f646-2640.png?v8",old_key:"unicode/1f5dd.png?v8",older_adult:"unicode/1f9d3.png?v8",older_man:"unicode/1f474.png?v8",older_woman:"unicode/1f475.png?v8",olive:"unicode/1fad2.png?v8",om:"unicode/1f549.png?v8",oman:"unicode/1f1f4-1f1f2.png?v8",on:"unicode/1f51b.png?v8",oncoming_automobile:"unicode/1f698.png?v8",oncoming_bus:"unicode/1f68d.png?v8",oncoming_police_car:"unicode/1f694.png?v8",oncoming_taxi:"unicode/1f696.png?v8",one:"unicode/0031-20e3.png?v8",one_piece_swimsuit:"unicode/1fa71.png?v8",onion:"unicode/1f9c5.png?v8",open_book:"unicode/1f4d6.png?v8",open_file_folder:"unicode/1f4c2.png?v8",open_hands:"unicode/1f450.png?v8",open_mouth:"unicode/1f62e.png?v8",open_umbrella:"unicode/2602.png?v8",ophiuchus:"unicode/26ce.png?v8",orange:"unicode/1f34a.png?v8",orange_book:"unicode/1f4d9.png?v8",orange_circle:"unicode/1f7e0.png?v8",orange_heart:"unicode/1f9e1.png?v8",orange_square:"unicode/1f7e7.png?v8",orangutan:"unicode/1f9a7.png?v8",orthodox_cross:"unicode/2626.png?v8",otter:"unicode/1f9a6.png?v8",outbox_tray:"unicode/1f4e4.png?v8",owl:"unicode/1f989.png?v8",ox:"unicode/1f402.png?v8",oyster:"unicode/1f9aa.png?v8",package:"unicode/1f4e6.png?v8",page_facing_up:"unicode/1f4c4.png?v8",page_with_curl:"unicode/1f4c3.png?v8",pager:"unicode/1f4df.png?v8",paintbrush:"unicode/1f58c.png?v8",pakistan:"unicode/1f1f5-1f1f0.png?v8",palau:"unicode/1f1f5-1f1fc.png?v8",palestinian_territories:"unicode/1f1f5-1f1f8.png?v8",palm_tree:"unicode/1f334.png?v8",palms_up_together:"unicode/1f932.png?v8",panama:"unicode/1f1f5-1f1e6.png?v8",pancakes:"unicode/1f95e.png?v8",panda_face:"unicode/1f43c.png?v8",paperclip:"unicode/1f4ce.png?v8",paperclips:"unicode/1f587.png?v8",papua_new_guinea:"unicode/1f1f5-1f1ec.png?v8",parachute:"unicode/1fa82.png?v8",paraguay:"unicode/1f1f5-1f1fe.png?v8",parasol_on_ground:"unicode/26f1.png?v8",parking:"unicode/1f17f.png?v8",parrot:"unicode/1f99c.png?v8",part_alternation_mark:"unicode/303d.png?v8",partly_sunny:"unicode/26c5.png?v8",partying_face:"unicode/1f973.png?v8",passenger_ship:"unicode/1f6f3.png?v8",passport_control:"unicode/1f6c2.png?v8",pause_button:"unicode/23f8.png?v8",paw_prints:"unicode/1f43e.png?v8",peace_symbol:"unicode/262e.png?v8",peach:"unicode/1f351.png?v8",peacock:"unicode/1f99a.png?v8",peanuts:"unicode/1f95c.png?v8",pear:"unicode/1f350.png?v8",pen:"unicode/1f58a.png?v8",pencil:"unicode/1f4dd.png?v8",pencil2:"unicode/270f.png?v8",penguin:"unicode/1f427.png?v8",pensive:"unicode/1f614.png?v8",people_holding_hands:"unicode/1f9d1-1f91d-1f9d1.png?v8",people_hugging:"unicode/1fac2.png?v8",performing_arts:"unicode/1f3ad.png?v8",persevere:"unicode/1f623.png?v8",person_bald:"unicode/1f9d1-1f9b2.png?v8",person_curly_hair:"unicode/1f9d1-1f9b1.png?v8",person_feeding_baby:"unicode/1f9d1-1f37c.png?v8",person_fencing:"unicode/1f93a.png?v8",person_in_manual_wheelchair:"unicode/1f9d1-1f9bd.png?v8",person_in_motorized_wheelchair:"unicode/1f9d1-1f9bc.png?v8",person_in_tuxedo:"unicode/1f935.png?v8",person_red_hair:"unicode/1f9d1-1f9b0.png?v8",person_white_hair:"unicode/1f9d1-1f9b3.png?v8",person_with_probing_cane:"unicode/1f9d1-1f9af.png?v8",person_with_turban:"unicode/1f473.png?v8",person_with_veil:"unicode/1f470.png?v8",peru:"unicode/1f1f5-1f1ea.png?v8",petri_dish:"unicode/1f9eb.png?v8",philippines:"unicode/1f1f5-1f1ed.png?v8",phone:"unicode/260e.png?v8",pick:"unicode/26cf.png?v8",pickup_truck:"unicode/1f6fb.png?v8",pie:"unicode/1f967.png?v8",pig:"unicode/1f437.png?v8",pig2:"unicode/1f416.png?v8",pig_nose:"unicode/1f43d.png?v8",pill:"unicode/1f48a.png?v8",pilot:"unicode/1f9d1-2708.png?v8",pinata:"unicode/1fa85.png?v8",pinched_fingers:"unicode/1f90c.png?v8",pinching_hand:"unicode/1f90f.png?v8",pineapple:"unicode/1f34d.png?v8",ping_pong:"unicode/1f3d3.png?v8",pirate_flag:"unicode/1f3f4-2620.png?v8",pisces:"unicode/2653.png?v8",pitcairn_islands:"unicode/1f1f5-1f1f3.png?v8",pizza:"unicode/1f355.png?v8",placard:"unicode/1faa7.png?v8",place_of_worship:"unicode/1f6d0.png?v8",plate_with_cutlery:"unicode/1f37d.png?v8",play_or_pause_button:"unicode/23ef.png?v8",pleading_face:"unicode/1f97a.png?v8",plunger:"unicode/1faa0.png?v8",point_down:"unicode/1f447.png?v8",point_left:"unicode/1f448.png?v8",point_right:"unicode/1f449.png?v8",point_up:"unicode/261d.png?v8",point_up_2:"unicode/1f446.png?v8",poland:"unicode/1f1f5-1f1f1.png?v8",polar_bear:"unicode/1f43b-2744.png?v8",police_car:"unicode/1f693.png?v8",police_officer:"unicode/1f46e.png?v8",policeman:"unicode/1f46e-2642.png?v8",policewoman:"unicode/1f46e-2640.png?v8",poodle:"unicode/1f429.png?v8",poop:"unicode/1f4a9.png?v8",popcorn:"unicode/1f37f.png?v8",portugal:"unicode/1f1f5-1f1f9.png?v8",post_office:"unicode/1f3e3.png?v8",postal_horn:"unicode/1f4ef.png?v8",postbox:"unicode/1f4ee.png?v8",potable_water:"unicode/1f6b0.png?v8",potato:"unicode/1f954.png?v8",potted_plant:"unicode/1fab4.png?v8",pouch:"unicode/1f45d.png?v8",poultry_leg:"unicode/1f357.png?v8",pound:"unicode/1f4b7.png?v8",pout:"unicode/1f621.png?v8",pouting_cat:"unicode/1f63e.png?v8",pouting_face:"unicode/1f64e.png?v8",pouting_man:"unicode/1f64e-2642.png?v8",pouting_woman:"unicode/1f64e-2640.png?v8",pray:"unicode/1f64f.png?v8",prayer_beads:"unicode/1f4ff.png?v8",pregnant_woman:"unicode/1f930.png?v8",pretzel:"unicode/1f968.png?v8",previous_track_button:"unicode/23ee.png?v8",prince:"unicode/1f934.png?v8",princess:"unicode/1f478.png?v8",printer:"unicode/1f5a8.png?v8",probing_cane:"unicode/1f9af.png?v8",puerto_rico:"unicode/1f1f5-1f1f7.png?v8",punch:"unicode/1f44a.png?v8",purple_circle:"unicode/1f7e3.png?v8",purple_heart:"unicode/1f49c.png?v8",purple_square:"unicode/1f7ea.png?v8",purse:"unicode/1f45b.png?v8",pushpin:"unicode/1f4cc.png?v8",put_litter_in_its_place:"unicode/1f6ae.png?v8",qatar:"unicode/1f1f6-1f1e6.png?v8",question:"unicode/2753.png?v8",rabbit:"unicode/1f430.png?v8",rabbit2:"unicode/1f407.png?v8",raccoon:"unicode/1f99d.png?v8",racehorse:"unicode/1f40e.png?v8",racing_car:"unicode/1f3ce.png?v8",radio:"unicode/1f4fb.png?v8",radio_button:"unicode/1f518.png?v8",radioactive:"unicode/2622.png?v8",rage:"unicode/1f621.png?v8",rage1:"rage1.png?v8",rage2:"rage2.png?v8",rage3:"rage3.png?v8",rage4:"rage4.png?v8",railway_car:"unicode/1f683.png?v8",railway_track:"unicode/1f6e4.png?v8",rainbow:"unicode/1f308.png?v8",rainbow_flag:"unicode/1f3f3-1f308.png?v8",raised_back_of_hand:"unicode/1f91a.png?v8",raised_eyebrow:"unicode/1f928.png?v8",raised_hand:"unicode/270b.png?v8",raised_hand_with_fingers_splayed:"unicode/1f590.png?v8",raised_hands:"unicode/1f64c.png?v8",raising_hand:"unicode/1f64b.png?v8",raising_hand_man:"unicode/1f64b-2642.png?v8",raising_hand_woman:"unicode/1f64b-2640.png?v8",ram:"unicode/1f40f.png?v8",ramen:"unicode/1f35c.png?v8",rat:"unicode/1f400.png?v8",razor:"unicode/1fa92.png?v8",receipt:"unicode/1f9fe.png?v8",record_button:"unicode/23fa.png?v8",recycle:"unicode/267b.png?v8",red_car:"unicode/1f697.png?v8",red_circle:"unicode/1f534.png?v8",red_envelope:"unicode/1f9e7.png?v8",red_haired_man:"unicode/1f468-1f9b0.png?v8",red_haired_woman:"unicode/1f469-1f9b0.png?v8",red_square:"unicode/1f7e5.png?v8",registered:"unicode/00ae.png?v8",relaxed:"unicode/263a.png?v8",relieved:"unicode/1f60c.png?v8",reminder_ribbon:"unicode/1f397.png?v8",repeat:"unicode/1f501.png?v8",repeat_one:"unicode/1f502.png?v8",rescue_worker_helmet:"unicode/26d1.png?v8",restroom:"unicode/1f6bb.png?v8",reunion:"unicode/1f1f7-1f1ea.png?v8",revolving_hearts:"unicode/1f49e.png?v8",rewind:"unicode/23ea.png?v8",rhinoceros:"unicode/1f98f.png?v8",ribbon:"unicode/1f380.png?v8",rice:"unicode/1f35a.png?v8",rice_ball:"unicode/1f359.png?v8",rice_cracker:"unicode/1f358.png?v8",rice_scene:"unicode/1f391.png?v8",right_anger_bubble:"unicode/1f5ef.png?v8",ring:"unicode/1f48d.png?v8",ringed_planet:"unicode/1fa90.png?v8",robot:"unicode/1f916.png?v8",rock:"unicode/1faa8.png?v8",rocket:"unicode/1f680.png?v8",rofl:"unicode/1f923.png?v8",roll_eyes:"unicode/1f644.png?v8",roll_of_paper:"unicode/1f9fb.png?v8",roller_coaster:"unicode/1f3a2.png?v8",roller_skate:"unicode/1f6fc.png?v8",romania:"unicode/1f1f7-1f1f4.png?v8",rooster:"unicode/1f413.png?v8",rose:"unicode/1f339.png?v8",rosette:"unicode/1f3f5.png?v8",rotating_light:"unicode/1f6a8.png?v8",round_pushpin:"unicode/1f4cd.png?v8",rowboat:"unicode/1f6a3.png?v8",rowing_man:"unicode/1f6a3-2642.png?v8",rowing_woman:"unicode/1f6a3-2640.png?v8",ru:"unicode/1f1f7-1f1fa.png?v8",rugby_football:"unicode/1f3c9.png?v8",runner:"unicode/1f3c3.png?v8",running:"unicode/1f3c3.png?v8",running_man:"unicode/1f3c3-2642.png?v8",running_shirt_with_sash:"unicode/1f3bd.png?v8",running_woman:"unicode/1f3c3-2640.png?v8",rwanda:"unicode/1f1f7-1f1fc.png?v8",sa:"unicode/1f202.png?v8",safety_pin:"unicode/1f9f7.png?v8",safety_vest:"unicode/1f9ba.png?v8",sagittarius:"unicode/2650.png?v8",sailboat:"unicode/26f5.png?v8",sake:"unicode/1f376.png?v8",salt:"unicode/1f9c2.png?v8",samoa:"unicode/1f1fc-1f1f8.png?v8",san_marino:"unicode/1f1f8-1f1f2.png?v8",sandal:"unicode/1f461.png?v8",sandwich:"unicode/1f96a.png?v8",santa:"unicode/1f385.png?v8",sao_tome_principe:"unicode/1f1f8-1f1f9.png?v8",sari:"unicode/1f97b.png?v8",sassy_man:"unicode/1f481-2642.png?v8",sassy_woman:"unicode/1f481-2640.png?v8",satellite:"unicode/1f4e1.png?v8",satisfied:"unicode/1f606.png?v8",saudi_arabia:"unicode/1f1f8-1f1e6.png?v8",sauna_man:"unicode/1f9d6-2642.png?v8",sauna_person:"unicode/1f9d6.png?v8",sauna_woman:"unicode/1f9d6-2640.png?v8",sauropod:"unicode/1f995.png?v8",saxophone:"unicode/1f3b7.png?v8",scarf:"unicode/1f9e3.png?v8",school:"unicode/1f3eb.png?v8",school_satchel:"unicode/1f392.png?v8",scientist:"unicode/1f9d1-1f52c.png?v8",scissors:"unicode/2702.png?v8",scorpion:"unicode/1f982.png?v8",scorpius:"unicode/264f.png?v8",scotland:"unicode/1f3f4-e0067-e0062-e0073-e0063-e0074-e007f.png?v8",scream:"unicode/1f631.png?v8",scream_cat:"unicode/1f640.png?v8",screwdriver:"unicode/1fa9b.png?v8",scroll:"unicode/1f4dc.png?v8",seal:"unicode/1f9ad.png?v8",seat:"unicode/1f4ba.png?v8",secret:"unicode/3299.png?v8",see_no_evil:"unicode/1f648.png?v8",seedling:"unicode/1f331.png?v8",selfie:"unicode/1f933.png?v8",senegal:"unicode/1f1f8-1f1f3.png?v8",serbia:"unicode/1f1f7-1f1f8.png?v8",service_dog:"unicode/1f415-1f9ba.png?v8",seven:"unicode/0037-20e3.png?v8",sewing_needle:"unicode/1faa1.png?v8",seychelles:"unicode/1f1f8-1f1e8.png?v8",shallow_pan_of_food:"unicode/1f958.png?v8",shamrock:"unicode/2618.png?v8",shark:"unicode/1f988.png?v8",shaved_ice:"unicode/1f367.png?v8",sheep:"unicode/1f411.png?v8",shell:"unicode/1f41a.png?v8",shield:"unicode/1f6e1.png?v8",shinto_shrine:"unicode/26e9.png?v8",ship:"unicode/1f6a2.png?v8",shipit:"shipit.png?v8",shirt:"unicode/1f455.png?v8",shit:"unicode/1f4a9.png?v8",shoe:"unicode/1f45e.png?v8",shopping:"unicode/1f6cd.png?v8",shopping_cart:"unicode/1f6d2.png?v8",shorts:"unicode/1fa73.png?v8",shower:"unicode/1f6bf.png?v8",shrimp:"unicode/1f990.png?v8",shrug:"unicode/1f937.png?v8",shushing_face:"unicode/1f92b.png?v8",sierra_leone:"unicode/1f1f8-1f1f1.png?v8",signal_strength:"unicode/1f4f6.png?v8",singapore:"unicode/1f1f8-1f1ec.png?v8",singer:"unicode/1f9d1-1f3a4.png?v8",sint_maarten:"unicode/1f1f8-1f1fd.png?v8",six:"unicode/0036-20e3.png?v8",six_pointed_star:"unicode/1f52f.png?v8",skateboard:"unicode/1f6f9.png?v8",ski:"unicode/1f3bf.png?v8",skier:"unicode/26f7.png?v8",skull:"unicode/1f480.png?v8",skull_and_crossbones:"unicode/2620.png?v8",skunk:"unicode/1f9a8.png?v8",sled:"unicode/1f6f7.png?v8",sleeping:"unicode/1f634.png?v8",sleeping_bed:"unicode/1f6cc.png?v8",sleepy:"unicode/1f62a.png?v8",slightly_frowning_face:"unicode/1f641.png?v8",slightly_smiling_face:"unicode/1f642.png?v8",slot_machine:"unicode/1f3b0.png?v8",sloth:"unicode/1f9a5.png?v8",slovakia:"unicode/1f1f8-1f1f0.png?v8",slovenia:"unicode/1f1f8-1f1ee.png?v8",small_airplane:"unicode/1f6e9.png?v8",small_blue_diamond:"unicode/1f539.png?v8",small_orange_diamond:"unicode/1f538.png?v8",small_red_triangle:"unicode/1f53a.png?v8",small_red_triangle_down:"unicode/1f53b.png?v8",smile:"unicode/1f604.png?v8",smile_cat:"unicode/1f638.png?v8",smiley:"unicode/1f603.png?v8",smiley_cat:"unicode/1f63a.png?v8",smiling_face_with_tear:"unicode/1f972.png?v8",smiling_face_with_three_hearts:"unicode/1f970.png?v8",smiling_imp:"unicode/1f608.png?v8",smirk:"unicode/1f60f.png?v8",smirk_cat:"unicode/1f63c.png?v8",smoking:"unicode/1f6ac.png?v8",snail:"unicode/1f40c.png?v8",snake:"unicode/1f40d.png?v8",sneezing_face:"unicode/1f927.png?v8",snowboarder:"unicode/1f3c2.png?v8",snowflake:"unicode/2744.png?v8",snowman:"unicode/26c4.png?v8",snowman_with_snow:"unicode/2603.png?v8",soap:"unicode/1f9fc.png?v8",sob:"unicode/1f62d.png?v8",soccer:"unicode/26bd.png?v8",socks:"unicode/1f9e6.png?v8",softball:"unicode/1f94e.png?v8",solomon_islands:"unicode/1f1f8-1f1e7.png?v8",somalia:"unicode/1f1f8-1f1f4.png?v8",soon:"unicode/1f51c.png?v8",sos:"unicode/1f198.png?v8",sound:"unicode/1f509.png?v8",south_africa:"unicode/1f1ff-1f1e6.png?v8",south_georgia_south_sandwich_islands:"unicode/1f1ec-1f1f8.png?v8",south_sudan:"unicode/1f1f8-1f1f8.png?v8",space_invader:"unicode/1f47e.png?v8",spades:"unicode/2660.png?v8",spaghetti:"unicode/1f35d.png?v8",sparkle:"unicode/2747.png?v8",sparkler:"unicode/1f387.png?v8",sparkles:"unicode/2728.png?v8",sparkling_heart:"unicode/1f496.png?v8",speak_no_evil:"unicode/1f64a.png?v8",speaker:"unicode/1f508.png?v8",speaking_head:"unicode/1f5e3.png?v8",speech_balloon:"unicode/1f4ac.png?v8",speedboat:"unicode/1f6a4.png?v8",spider:"unicode/1f577.png?v8",spider_web:"unicode/1f578.png?v8",spiral_calendar:"unicode/1f5d3.png?v8",spiral_notepad:"unicode/1f5d2.png?v8",sponge:"unicode/1f9fd.png?v8",spoon:"unicode/1f944.png?v8",squid:"unicode/1f991.png?v8",sri_lanka:"unicode/1f1f1-1f1f0.png?v8",st_barthelemy:"unicode/1f1e7-1f1f1.png?v8",st_helena:"unicode/1f1f8-1f1ed.png?v8",st_kitts_nevis:"unicode/1f1f0-1f1f3.png?v8",st_lucia:"unicode/1f1f1-1f1e8.png?v8",st_martin:"unicode/1f1f2-1f1eb.png?v8",st_pierre_miquelon:"unicode/1f1f5-1f1f2.png?v8",st_vincent_grenadines:"unicode/1f1fb-1f1e8.png?v8",stadium:"unicode/1f3df.png?v8",standing_man:"unicode/1f9cd-2642.png?v8",standing_person:"unicode/1f9cd.png?v8",standing_woman:"unicode/1f9cd-2640.png?v8",star:"unicode/2b50.png?v8",star2:"unicode/1f31f.png?v8",star_and_crescent:"unicode/262a.png?v8",star_of_david:"unicode/2721.png?v8",star_struck:"unicode/1f929.png?v8",stars:"unicode/1f320.png?v8",station:"unicode/1f689.png?v8",statue_of_liberty:"unicode/1f5fd.png?v8",steam_locomotive:"unicode/1f682.png?v8",stethoscope:"unicode/1fa7a.png?v8",stew:"unicode/1f372.png?v8",stop_button:"unicode/23f9.png?v8",stop_sign:"unicode/1f6d1.png?v8",stopwatch:"unicode/23f1.png?v8",straight_ruler:"unicode/1f4cf.png?v8",strawberry:"unicode/1f353.png?v8",stuck_out_tongue:"unicode/1f61b.png?v8",stuck_out_tongue_closed_eyes:"unicode/1f61d.png?v8",stuck_out_tongue_winking_eye:"unicode/1f61c.png?v8",student:"unicode/1f9d1-1f393.png?v8",studio_microphone:"unicode/1f399.png?v8",stuffed_flatbread:"unicode/1f959.png?v8",sudan:"unicode/1f1f8-1f1e9.png?v8",sun_behind_large_cloud:"unicode/1f325.png?v8",sun_behind_rain_cloud:"unicode/1f326.png?v8",sun_behind_small_cloud:"unicode/1f324.png?v8",sun_with_face:"unicode/1f31e.png?v8",sunflower:"unicode/1f33b.png?v8",sunglasses:"unicode/1f60e.png?v8",sunny:"unicode/2600.png?v8",sunrise:"unicode/1f305.png?v8",sunrise_over_mountains:"unicode/1f304.png?v8",superhero:"unicode/1f9b8.png?v8",superhero_man:"unicode/1f9b8-2642.png?v8",superhero_woman:"unicode/1f9b8-2640.png?v8",supervillain:"unicode/1f9b9.png?v8",supervillain_man:"unicode/1f9b9-2642.png?v8",supervillain_woman:"unicode/1f9b9-2640.png?v8",surfer:"unicode/1f3c4.png?v8",surfing_man:"unicode/1f3c4-2642.png?v8",surfing_woman:"unicode/1f3c4-2640.png?v8",suriname:"unicode/1f1f8-1f1f7.png?v8",sushi:"unicode/1f363.png?v8",suspect:"suspect.png?v8",suspension_railway:"unicode/1f69f.png?v8",svalbard_jan_mayen:"unicode/1f1f8-1f1ef.png?v8",swan:"unicode/1f9a2.png?v8",swaziland:"unicode/1f1f8-1f1ff.png?v8",sweat:"unicode/1f613.png?v8",sweat_drops:"unicode/1f4a6.png?v8",sweat_smile:"unicode/1f605.png?v8",sweden:"unicode/1f1f8-1f1ea.png?v8",sweet_potato:"unicode/1f360.png?v8",swim_brief:"unicode/1fa72.png?v8",swimmer:"unicode/1f3ca.png?v8",swimming_man:"unicode/1f3ca-2642.png?v8",swimming_woman:"unicode/1f3ca-2640.png?v8",switzerland:"unicode/1f1e8-1f1ed.png?v8",symbols:"unicode/1f523.png?v8",synagogue:"unicode/1f54d.png?v8",syria:"unicode/1f1f8-1f1fe.png?v8",syringe:"unicode/1f489.png?v8","t-rex":"unicode/1f996.png?v8",taco:"unicode/1f32e.png?v8",tada:"unicode/1f389.png?v8",taiwan:"unicode/1f1f9-1f1fc.png?v8",tajikistan:"unicode/1f1f9-1f1ef.png?v8",takeout_box:"unicode/1f961.png?v8",tamale:"unicode/1fad4.png?v8",tanabata_tree:"unicode/1f38b.png?v8",tangerine:"unicode/1f34a.png?v8",tanzania:"unicode/1f1f9-1f1ff.png?v8",taurus:"unicode/2649.png?v8",taxi:"unicode/1f695.png?v8",tea:"unicode/1f375.png?v8",teacher:"unicode/1f9d1-1f3eb.png?v8",teapot:"unicode/1fad6.png?v8",technologist:"unicode/1f9d1-1f4bb.png?v8",teddy_bear:"unicode/1f9f8.png?v8",telephone:"unicode/260e.png?v8",telephone_receiver:"unicode/1f4de.png?v8",telescope:"unicode/1f52d.png?v8",tennis:"unicode/1f3be.png?v8",tent:"unicode/26fa.png?v8",test_tube:"unicode/1f9ea.png?v8",thailand:"unicode/1f1f9-1f1ed.png?v8",thermometer:"unicode/1f321.png?v8",thinking:"unicode/1f914.png?v8",thong_sandal:"unicode/1fa74.png?v8",thought_balloon:"unicode/1f4ad.png?v8",thread:"unicode/1f9f5.png?v8",three:"unicode/0033-20e3.png?v8",thumbsdown:"unicode/1f44e.png?v8",thumbsup:"unicode/1f44d.png?v8",ticket:"unicode/1f3ab.png?v8",tickets:"unicode/1f39f.png?v8",tiger:"unicode/1f42f.png?v8",tiger2:"unicode/1f405.png?v8",timer_clock:"unicode/23f2.png?v8",timor_leste:"unicode/1f1f9-1f1f1.png?v8",tipping_hand_man:"unicode/1f481-2642.png?v8",tipping_hand_person:"unicode/1f481.png?v8",tipping_hand_woman:"unicode/1f481-2640.png?v8",tired_face:"unicode/1f62b.png?v8",tm:"unicode/2122.png?v8",togo:"unicode/1f1f9-1f1ec.png?v8",toilet:"unicode/1f6bd.png?v8",tokelau:"unicode/1f1f9-1f1f0.png?v8",tokyo_tower:"unicode/1f5fc.png?v8",tomato:"unicode/1f345.png?v8",tonga:"unicode/1f1f9-1f1f4.png?v8",tongue:"unicode/1f445.png?v8",toolbox:"unicode/1f9f0.png?v8",tooth:"unicode/1f9b7.png?v8",toothbrush:"unicode/1faa5.png?v8",top:"unicode/1f51d.png?v8",tophat:"unicode/1f3a9.png?v8",tornado:"unicode/1f32a.png?v8",tr:"unicode/1f1f9-1f1f7.png?v8",trackball:"unicode/1f5b2.png?v8",tractor:"unicode/1f69c.png?v8",traffic_light:"unicode/1f6a5.png?v8",train:"unicode/1f68b.png?v8",train2:"unicode/1f686.png?v8",tram:"unicode/1f68a.png?v8",transgender_flag:"unicode/1f3f3-26a7.png?v8",transgender_symbol:"unicode/26a7.png?v8",triangular_flag_on_post:"unicode/1f6a9.png?v8",triangular_ruler:"unicode/1f4d0.png?v8",trident:"unicode/1f531.png?v8",trinidad_tobago:"unicode/1f1f9-1f1f9.png?v8",tristan_da_cunha:"unicode/1f1f9-1f1e6.png?v8",triumph:"unicode/1f624.png?v8",trolleybus:"unicode/1f68e.png?v8",trollface:"trollface.png?v8",trophy:"unicode/1f3c6.png?v8",tropical_drink:"unicode/1f379.png?v8",tropical_fish:"unicode/1f420.png?v8",truck:"unicode/1f69a.png?v8",trumpet:"unicode/1f3ba.png?v8",tshirt:"unicode/1f455.png?v8",tulip:"unicode/1f337.png?v8",tumbler_glass:"unicode/1f943.png?v8",tunisia:"unicode/1f1f9-1f1f3.png?v8",turkey:"unicode/1f983.png?v8",turkmenistan:"unicode/1f1f9-1f1f2.png?v8",turks_caicos_islands:"unicode/1f1f9-1f1e8.png?v8",turtle:"unicode/1f422.png?v8",tuvalu:"unicode/1f1f9-1f1fb.png?v8",tv:"unicode/1f4fa.png?v8",twisted_rightwards_arrows:"unicode/1f500.png?v8",two:"unicode/0032-20e3.png?v8",two_hearts:"unicode/1f495.png?v8",two_men_holding_hands:"unicode/1f46c.png?v8",two_women_holding_hands:"unicode/1f46d.png?v8",u5272:"unicode/1f239.png?v8",u5408:"unicode/1f234.png?v8",u55b6:"unicode/1f23a.png?v8",u6307:"unicode/1f22f.png?v8",u6708:"unicode/1f237.png?v8",u6709:"unicode/1f236.png?v8",u6e80:"unicode/1f235.png?v8",u7121:"unicode/1f21a.png?v8",u7533:"unicode/1f238.png?v8",u7981:"unicode/1f232.png?v8",u7a7a:"unicode/1f233.png?v8",uganda:"unicode/1f1fa-1f1ec.png?v8",uk:"unicode/1f1ec-1f1e7.png?v8",ukraine:"unicode/1f1fa-1f1e6.png?v8",umbrella:"unicode/2614.png?v8",unamused:"unicode/1f612.png?v8",underage:"unicode/1f51e.png?v8",unicorn:"unicode/1f984.png?v8",united_arab_emirates:"unicode/1f1e6-1f1ea.png?v8",united_nations:"unicode/1f1fa-1f1f3.png?v8",unlock:"unicode/1f513.png?v8",up:"unicode/1f199.png?v8",upside_down_face:"unicode/1f643.png?v8",uruguay:"unicode/1f1fa-1f1fe.png?v8",us:"unicode/1f1fa-1f1f8.png?v8",us_outlying_islands:"unicode/1f1fa-1f1f2.png?v8",us_virgin_islands:"unicode/1f1fb-1f1ee.png?v8",uzbekistan:"unicode/1f1fa-1f1ff.png?v8",v:"unicode/270c.png?v8",vampire:"unicode/1f9db.png?v8",vampire_man:"unicode/1f9db-2642.png?v8",vampire_woman:"unicode/1f9db-2640.png?v8",vanuatu:"unicode/1f1fb-1f1fa.png?v8",vatican_city:"unicode/1f1fb-1f1e6.png?v8",venezuela:"unicode/1f1fb-1f1ea.png?v8",vertical_traffic_light:"unicode/1f6a6.png?v8",vhs:"unicode/1f4fc.png?v8",vibration_mode:"unicode/1f4f3.png?v8",video_camera:"unicode/1f4f9.png?v8",video_game:"unicode/1f3ae.png?v8",vietnam:"unicode/1f1fb-1f1f3.png?v8",violin:"unicode/1f3bb.png?v8",virgo:"unicode/264d.png?v8",volcano:"unicode/1f30b.png?v8",volleyball:"unicode/1f3d0.png?v8",vomiting_face:"unicode/1f92e.png?v8",vs:"unicode/1f19a.png?v8",vulcan_salute:"unicode/1f596.png?v8",waffle:"unicode/1f9c7.png?v8",wales:"unicode/1f3f4-e0067-e0062-e0077-e006c-e0073-e007f.png?v8",walking:"unicode/1f6b6.png?v8",walking_man:"unicode/1f6b6-2642.png?v8",walking_woman:"unicode/1f6b6-2640.png?v8",wallis_futuna:"unicode/1f1fc-1f1eb.png?v8",waning_crescent_moon:"unicode/1f318.png?v8",waning_gibbous_moon:"unicode/1f316.png?v8",warning:"unicode/26a0.png?v8",wastebasket:"unicode/1f5d1.png?v8",watch:"unicode/231a.png?v8",water_buffalo:"unicode/1f403.png?v8",water_polo:"unicode/1f93d.png?v8",watermelon:"unicode/1f349.png?v8",wave:"unicode/1f44b.png?v8",wavy_dash:"unicode/3030.png?v8",waxing_crescent_moon:"unicode/1f312.png?v8",waxing_gibbous_moon:"unicode/1f314.png?v8",wc:"unicode/1f6be.png?v8",weary:"unicode/1f629.png?v8",wedding:"unicode/1f492.png?v8",weight_lifting:"unicode/1f3cb.png?v8",weight_lifting_man:"unicode/1f3cb-2642.png?v8",weight_lifting_woman:"unicode/1f3cb-2640.png?v8",western_sahara:"unicode/1f1ea-1f1ed.png?v8",whale:"unicode/1f433.png?v8",whale2:"unicode/1f40b.png?v8",wheel_of_dharma:"unicode/2638.png?v8",wheelchair:"unicode/267f.png?v8",white_check_mark:"unicode/2705.png?v8",white_circle:"unicode/26aa.png?v8",white_flag:"unicode/1f3f3.png?v8",white_flower:"unicode/1f4ae.png?v8",white_haired_man:"unicode/1f468-1f9b3.png?v8",white_haired_woman:"unicode/1f469-1f9b3.png?v8",white_heart:"unicode/1f90d.png?v8",white_large_square:"unicode/2b1c.png?v8",white_medium_small_square:"unicode/25fd.png?v8",white_medium_square:"unicode/25fb.png?v8",white_small_square:"unicode/25ab.png?v8",white_square_button:"unicode/1f533.png?v8",wilted_flower:"unicode/1f940.png?v8",wind_chime:"unicode/1f390.png?v8",wind_face:"unicode/1f32c.png?v8",window:"unicode/1fa9f.png?v8",wine_glass:"unicode/1f377.png?v8",wink:"unicode/1f609.png?v8",wolf:"unicode/1f43a.png?v8",woman:"unicode/1f469.png?v8",woman_artist:"unicode/1f469-1f3a8.png?v8",woman_astronaut:"unicode/1f469-1f680.png?v8",woman_beard:"unicode/1f9d4-2640.png?v8",woman_cartwheeling:"unicode/1f938-2640.png?v8",woman_cook:"unicode/1f469-1f373.png?v8",woman_dancing:"unicode/1f483.png?v8",woman_facepalming:"unicode/1f926-2640.png?v8",woman_factory_worker:"unicode/1f469-1f3ed.png?v8",woman_farmer:"unicode/1f469-1f33e.png?v8",woman_feeding_baby:"unicode/1f469-1f37c.png?v8",woman_firefighter:"unicode/1f469-1f692.png?v8",woman_health_worker:"unicode/1f469-2695.png?v8",woman_in_manual_wheelchair:"unicode/1f469-1f9bd.png?v8",woman_in_motorized_wheelchair:"unicode/1f469-1f9bc.png?v8",woman_in_tuxedo:"unicode/1f935-2640.png?v8",woman_judge:"unicode/1f469-2696.png?v8",woman_juggling:"unicode/1f939-2640.png?v8",woman_mechanic:"unicode/1f469-1f527.png?v8",woman_office_worker:"unicode/1f469-1f4bc.png?v8",woman_pilot:"unicode/1f469-2708.png?v8",woman_playing_handball:"unicode/1f93e-2640.png?v8",woman_playing_water_polo:"unicode/1f93d-2640.png?v8",woman_scientist:"unicode/1f469-1f52c.png?v8",woman_shrugging:"unicode/1f937-2640.png?v8",woman_singer:"unicode/1f469-1f3a4.png?v8",woman_student:"unicode/1f469-1f393.png?v8",woman_teacher:"unicode/1f469-1f3eb.png?v8",woman_technologist:"unicode/1f469-1f4bb.png?v8",woman_with_headscarf:"unicode/1f9d5.png?v8",woman_with_probing_cane:"unicode/1f469-1f9af.png?v8",woman_with_turban:"unicode/1f473-2640.png?v8",woman_with_veil:"unicode/1f470-2640.png?v8",womans_clothes:"unicode/1f45a.png?v8",womans_hat:"unicode/1f452.png?v8",women_wrestling:"unicode/1f93c-2640.png?v8",womens:"unicode/1f6ba.png?v8",wood:"unicode/1fab5.png?v8",woozy_face:"unicode/1f974.png?v8",world_map:"unicode/1f5fa.png?v8",worm:"unicode/1fab1.png?v8",worried:"unicode/1f61f.png?v8",wrench:"unicode/1f527.png?v8",wrestling:"unicode/1f93c.png?v8",writing_hand:"unicode/270d.png?v8",x:"unicode/274c.png?v8",yarn:"unicode/1f9f6.png?v8",yawning_face:"unicode/1f971.png?v8",yellow_circle:"unicode/1f7e1.png?v8",yellow_heart:"unicode/1f49b.png?v8",yellow_square:"unicode/1f7e8.png?v8",yemen:"unicode/1f1fe-1f1ea.png?v8",yen:"unicode/1f4b4.png?v8",yin_yang:"unicode/262f.png?v8",yo_yo:"unicode/1fa80.png?v8",yum:"unicode/1f60b.png?v8",zambia:"unicode/1f1ff-1f1f2.png?v8",zany_face:"unicode/1f92a.png?v8",zap:"unicode/26a1.png?v8",zebra:"unicode/1f993.png?v8",zero:"unicode/0030-20e3.png?v8",zimbabwe:"unicode/1f1ff-1f1fc.png?v8",zipper_mouth_face:"unicode/1f910.png?v8",zombie:"unicode/1f9df.png?v8",zombie_man:"unicode/1f9df-2642.png?v8",zombie_woman:"unicode/1f9df-2640.png?v8",zzz:"unicode/1f4a4.png?v8"}};function jn(e,t){return e.replace(/<(code|pre|script|template)[^>]*?>[\s\S]+?<\/(code|pre|script|template)>/g,function(e){return e.replace(/:/g,"__colon__")}).replace(/<!--[\s\S]+?-->/g,function(e){return e.replace(/:/g,"__colon__")}).replace(/([a-z]{2,}:)?\/\/[^\s'">)]+/gi,function(e){return e.replace(/:/g,"__colon__")}).replace(/:([a-z0-9_\-+]+?):/g,function(e,n){return i=e,o=n,e=t,n=Rn.data[o],i,i=n?e&&/unicode/.test(n)?'<span class="emoji">'+n.replace("unicode/","").replace(/\.png.*/,"").split("-").map(function(e){return"&#x"+e+";"}).join("‍").concat("︎")+"</span>":'<img src="'+Rn.baseURL+n+'.png" alt="'+o+'" class="emoji" loading="lazy">':i;var i,o}).replace(/__colon__/g,":")}function On(e){var o={};return{str:e=(e=void 0===e?"":e)&&e.replace(/^('|")/,"").replace(/('|")$/,"").replace(/(?:^|\s):([\w-]+:?)=?([\w-%]+)?/g,function(e,n,i){return-1===n.indexOf(":")?(o[n]=i&&i.replace(/"/g,"")||!0,""):e}).trim(),config:o}}function Ln(e){return(e=void 0===e?"":e).replace(/(<\/?a.*?>)/gi,"")}var qn,Pn=be(function(e){var u,f,p,d,n,g=function(u){var i=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,n=0,e={},T={manual:u.Prism&&u.Prism.manual,disableWorkerMessageHandler:u.Prism&&u.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof C?new C(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++n}),e.__id},clone:function i(e,o){var t,n;switch(o=o||{},T.util.type(e)){case"Object":if(n=T.util.objId(e),o[n])return o[n];for(var a in t={},o[n]=t,e)e.hasOwnProperty(a)&&(t[a]=i(e[a],o));return t;case"Array":return(n=T.util.objId(e),o[n])?o[n]:(t=[],o[n]=t,e.forEach(function(e,n){t[n]=i(e,o)}),t);default:return e}},getLanguage:function(e){for(;e;){var n=i.exec(e.className);if(n)return n[1].toLowerCase();e=e.parentElement}return"none"},setLanguage:function(e,n){e.className=e.className.replace(RegExp(i,"gi"),""),e.classList.add("language-"+n)},currentScript:function(){if("undefined"==typeof document)return null;if("currentScript"in document)return document.currentScript;try{throw new Error}catch(e){var n=(/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(e.stack)||[])[1];if(n){var i,o=document.getElementsByTagName("script");for(i in o)if(o[i].src==n)return o[i]}return null}},isActive:function(e,n,i){for(var o="no-"+n;e;){var t=e.classList;if(t.contains(n))return!0;if(t.contains(o))return!1;e=e.parentElement}return!!i}},languages:{plain:e,plaintext:e,text:e,txt:e,extend:function(e,n){var i,o=T.util.clone(T.languages[e]);for(i in n)o[i]=n[i];return o},insertBefore:function(i,e,n,o){var t,a=(o=o||T.languages)[i],r={};for(t in a)if(a.hasOwnProperty(t)){if(t==e)for(var c in n)n.hasOwnProperty(c)&&(r[c]=n[c]);n.hasOwnProperty(t)||(r[t]=a[t])}var u=o[i];return o[i]=r,T.languages.DFS(T.languages,function(e,n){n===u&&e!=i&&(this[e]=r)}),r},DFS:function e(n,i,o,t){t=t||{};var a,r,c,u=T.util.objId;for(a in n)n.hasOwnProperty(a)&&(i.call(n,a,n[a],o||a),r=n[a],"Object"!==(c=T.util.type(r))||t[u(r)]?"Array"!==c||t[u(r)]||(t[u(r)]=!0,e(r,i,a,t)):(t[u(r)]=!0,e(r,i,null,t)))}},plugins:{},highlightAll:function(e,n){T.highlightAllUnder(document,e,n)},highlightAllUnder:function(e,n,i){var o={callback:i,container:e,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};T.hooks.run("before-highlightall",o),o.elements=Array.prototype.slice.apply(o.container.querySelectorAll(o.selector)),T.hooks.run("before-all-elements-highlight",o);for(var t,a=0;t=o.elements[a++];)T.highlightElement(t,!0===n,o.callback)},highlightElement:function(e,n,i){var o=T.util.getLanguage(e),t=T.languages[o];T.util.setLanguage(e,o);var a=e.parentElement;a&&"pre"===a.nodeName.toLowerCase()&&T.util.setLanguage(a,o);var r={element:e,language:o,grammar:t,code:e.textContent};function c(e){r.highlightedCode=e,T.hooks.run("before-insert",r),r.element.innerHTML=r.highlightedCode,T.hooks.run("after-highlight",r),T.hooks.run("complete",r),i&&i.call(r.element)}if(T.hooks.run("before-sanity-check",r),(a=r.element.parentElement)&&"pre"===a.nodeName.toLowerCase()&&!a.hasAttribute("tabindex")&&a.setAttribute("tabindex","0"),!r.code)return T.hooks.run("complete",r),void(i&&i.call(r.element));T.hooks.run("before-highlight",r),r.grammar?n&&u.Worker?((n=new Worker(T.filename)).onmessage=function(e){c(e.data)},n.postMessage(JSON.stringify({language:r.language,code:r.code,immediateClose:!0}))):c(T.highlight(r.code,r.grammar,r.language)):c(T.util.encode(r.code))},highlight:function(e,n,i){i={code:e,grammar:n,language:i};if(T.hooks.run("before-tokenize",i),!i.grammar)throw new Error('The language "'+i.language+'" has no grammar.');return i.tokens=T.tokenize(i.code,i.grammar),T.hooks.run("after-tokenize",i),C.stringify(T.util.encode(i.tokens),i.language)},tokenize:function(e,n){var i=n.rest;if(i){for(var o in i)n[o]=i[o];delete n.rest}var t=new a;return j(t,t.head,e),function e(n,i,o,t,a,r){for(var c in o)if(o.hasOwnProperty(c)&&o[c]){var u=o[c];u=Array.isArray(u)?u:[u];for(var f=0;f<u.length;++f){if(r&&r.cause==c+","+f)return;var p,d=u[f],g=d.inside,s=!!d.lookbehind,l=!!d.greedy,v=d.alias;l&&!d.pattern.global&&(p=d.pattern.toString().match(/[imsuy]*$/)[0],d.pattern=RegExp(d.pattern.source,p+"g"));for(var h=d.pattern||d,_=t.next,m=a;_!==i.tail&&!(r&&m>=r.reach);m+=_.value.length,_=_.next){var b=_.value;if(i.length>n.length)return;if(!(b instanceof C)){var k,w=1;if(l){if(!(k=R(h,m,n,s))||k.index>=n.length)break;var y=k.index,x=k.index+k[0].length,S=m;for(S+=_.value.length;S<=y;)_=_.next,S+=_.value.length;if(S-=_.value.length,m=S,_.value instanceof C)continue;for(var A=_;A!==i.tail&&(S<x||"string"==typeof A.value);A=A.next)w++,S+=A.value.length;w--,b=n.slice(m,S),k.index-=m}else if(!(k=R(h,0,b,s)))continue;var y=k.index,$=k[0],z=b.slice(0,y),F=b.slice(y+$.length),E=m+b.length;r&&E>r.reach&&(r.reach=E);b=_.prev;z&&(b=j(i,b,z),m+=z.length),O(i,b,w);$=new C(c,g?T.tokenize($,g):$,v,$);_=j(i,b,$),F&&j(i,_,F),1<w&&(E={cause:c+","+f,reach:E},e(n,i,o,_.prev,m,E),r&&E.reach>r.reach&&(r.reach=E.reach))}}}}}(e,t,n,t.head,0),function(e){var n=[],i=e.head.next;for(;i!==e.tail;)n.push(i.value),i=i.next;return n}(t)},hooks:{all:{},add:function(e,n){var i=T.hooks.all;i[e]=i[e]||[],i[e].push(n)},run:function(e,n){var i=T.hooks.all[e];if(i&&i.length)for(var o,t=0;o=i[t++];)o(n)}},Token:C};function C(e,n,i,o){this.type=e,this.content=n,this.alias=i,this.length=0|(o||"").length}function R(e,n,i,o){e.lastIndex=n;i=e.exec(i);return i&&o&&i[1]&&(o=i[1].length,i.index+=o,i[0]=i[0].slice(o)),i}function a(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function j(e,n,i){var o=n.next,i={value:i,prev:n,next:o};return n.next=i,o.prev=i,e.length++,i}function O(e,n,i){for(var o=n.next,t=0;t<i&&o!==e.tail;t++)o=o.next;(n.next=o).prev=n,e.length-=t}if(u.Prism=T,C.stringify=function n(e,i){if("string"==typeof e)return e;if(Array.isArray(e)){var o="";return e.forEach(function(e){o+=n(e,i)}),o}var t={type:e.type,content:n(e.content,i),tag:"span",classes:["token",e.type],attributes:{},language:i},e=e.alias;e&&(Array.isArray(e)?Array.prototype.push.apply(t.classes,e):t.classes.push(e)),T.hooks.run("wrap",t);var a,r="";for(a in t.attributes)r+=" "+a+'="'+(t.attributes[a]||"").replace(/"/g,""")+'"';return"<"+t.tag+' class="'+t.classes.join(" ")+'"'+r+">"+t.content+"</"+t.tag+">"},!u.document)return u.addEventListener&&(T.disableWorkerMessageHandler||u.addEventListener("message",function(e){var n=JSON.parse(e.data),i=n.language,e=n.code,n=n.immediateClose;u.postMessage(T.highlight(e,T.languages[i],i)),n&&u.close()},!1)),T;var o=T.util.currentScript();function t(){T.manual||T.highlightAll()}return o&&(T.filename=o.src,o.hasAttribute("data-manual")&&(T.manual=!0)),T.manual||("loading"===(e=document.readyState)||"interactive"===e&&o&&o.defer?document.addEventListener("DOMContentLoaded",t):window.requestAnimationFrame?window.requestAnimationFrame(t):window.setTimeout(t,16)),T}("undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{});e.exports&&(e.exports=g),void 0!==me&&(me.Prism=g),g.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},g.languages.markup.tag.inside["attr-value"].inside.entity=g.languages.markup.entity,g.languages.markup.doctype.inside["internal-subset"].inside=g.languages.markup,g.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))}),Object.defineProperty(g.languages.markup.tag,"addInlined",{value:function(e,n){var i={};i["language-"+n]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:g.languages[n]},i.cdata=/^<!\[CDATA\[|\]\]>$/i;i={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:i}};i["language-"+n]={pattern:/[\s\S]+/,inside:g.languages[n]};n={};n[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,function(){return e}),"i"),lookbehind:!0,greedy:!0,inside:i},g.languages.insertBefore("markup","cdata",n)}}),Object.defineProperty(g.languages.markup.tag,"addAttribute",{value:function(e,n){g.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[n,"language-"+n],inside:g.languages[n]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),g.languages.html=g.languages.markup,g.languages.mathml=g.languages.markup,g.languages.svg=g.languages.markup,g.languages.xml=g.languages.extend("markup",{}),g.languages.ssml=g.languages.xml,g.languages.atom=g.languages.xml,g.languages.rss=g.languages.xml,function(e){var n=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+n.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+n.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+n.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:n,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;e=e.languages.markup;e&&(e.tag.addInlined("style","css"),e.tag.addAttribute("style","css"))}(g),g.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},g.languages.javascript=g.languages.extend("clike",{"class-name":[g.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),g.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,g.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:g.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:g.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:g.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:g.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:g.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),g.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:g.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),g.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),g.languages.markup&&(g.languages.markup.tag.addInlined("script","javascript"),g.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),g.languages.js=g.languages.javascript,void 0!==g&&"undefined"!=typeof document&&(Element.prototype.matches||(Element.prototype.matches=Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector),u={js:"javascript",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell",sh:"bash",bat:"batch",h:"c",tex:"latex"},d="pre[data-src]:not(["+(f="data-src-status")+'="loaded"]):not(['+f+'="'+(p="loading")+'"])',g.hooks.add("before-highlightall",function(e){e.selector+=", "+d}),g.hooks.add("before-sanity-check",function(e){var t,n,i,o,a,r,c=e.element;c.matches(d)&&(e.code="",c.setAttribute(f,p),(t=c.appendChild(document.createElement("CODE"))).textContent="Loading…",i=c.getAttribute("data-src"),"none"===(e=e.language)&&(n=(/\.(\w+)$/.exec(i)||[,"none"])[1],e=u[n]||n),g.util.setLanguage(t,e),g.util.setLanguage(c,e),(n=g.plugins.autoloader)&&n.loadLanguages(e),i=i,o=function(e){c.setAttribute(f,"loaded");var n,i,o=function(e){if(i=/^\s*(\d+)\s*(?:(,)\s*(?:(\d+)\s*)?)?$/.exec(e||"")){var n=Number(i[1]),e=i[2],i=i[3];return e?i?[n,Number(i)]:[n,void 0]:[n,n]}}(c.getAttribute("data-range"));o&&(n=e.split(/\r\n?|\n/g),i=o[0],o=null==o[1]?n.length:o[1],i<0&&(i+=n.length),i=Math.max(0,Math.min(i-1,n.length)),o<0&&(o+=n.length),o=Math.max(0,Math.min(o,n.length)),e=n.slice(i,o).join("\n"),c.hasAttribute("data-start")||c.setAttribute("data-start",String(i+1))),t.textContent=e,g.highlightElement(t)},a=function(e){c.setAttribute(f,"failed"),t.textContent=e},(r=new XMLHttpRequest).open("GET",i,!0),r.onreadystatechange=function(){4==r.readyState&&(r.status<400&&r.responseText?o(r.responseText):400<=r.status?a("✖ Error "+r.status+" while fetching file: "+r.statusText):a("✖ Error: File does not exist or is empty"))},r.send(null))}),n=!(g.plugins.fileHighlight={highlight:function(e){for(var n,i=(e||document).querySelectorAll(d),o=0;n=i[o++];)g.highlightElement(n)}}),g.fileHighlight=function(){n||(console.warn("Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead."),n=!0),g.plugins.fileHighlight.highlight.apply(this,arguments)})});function Mn(e,n){return"___"+e.toUpperCase()+n+"___"}qn=Prism,Object.defineProperties(qn.languages["markup-templating"]={},{buildPlaceholders:{value:function(o,t,e,a){var r;o.language===t&&(r=o.tokenStack=[],o.code=o.code.replace(e,function(e){if("function"==typeof a&&!a(e))return e;for(var n,i=r.length;-1!==o.code.indexOf(n=Mn(t,i));)++i;return r[i]=e,n}),o.grammar=qn.languages.markup)}},tokenizePlaceholders:{value:function(f,p){var d,g;f.language===p&&f.tokenStack&&(f.grammar=qn.languages[p],d=0,g=Object.keys(f.tokenStack),function e(n){for(var i=0;i<n.length&&!(d>=g.length);i++){var o,t,a,r,c,u=n[i];"string"==typeof u||u.content&&"string"==typeof u.content?(t=g[d],a=f.tokenStack[t],o="string"==typeof u?u:u.content,c=Mn(p,t),-1<(r=o.indexOf(c))&&(++d,t=o.substring(0,r),a=new qn.Token(p,qn.tokenize(a,f.grammar),"language-"+p,a),r=o.substring(r+c.length),c=[],t&&c.push.apply(c,e([t])),c.push(a),r&&c.push.apply(c,e([r])),"string"==typeof u?n.splice.apply(n,[i,1].concat(c)):u.content=c)):u.content&&e(u.content)}return n}(f.tokens))}}});function In(t,e){var a=this;this.config=t,this.router=e,this.cacheTree={},this.toc=[],this.cacheTOC={},this.linkTarget=t.externalLinkTarget||"_blank",this.linkRel="_blank"===this.linkTarget?t.externalLinkRel||"noopener":"",this.contentBase=e.getBasePath();var n=this._initRenderer();this.heading=n.heading;var r=o(e=t.markdown||{})?e(Sn,n):(Sn.setOptions(m(e,{renderer:m(n,e.renderer)})),Sn);this._marked=r,this.compile=function(i){var o=!0,e=c(function(e){o=!1;var n="";return i&&(n=f(i)?r(i):r.parser(i),n=t.noEmoji?n:jn(n,t.nativeEmoji),Cn.clear(),n)})(i),n=a.router.parse().file;return o?a.toc=a.cacheTOC[n]:a.cacheTOC[n]=[].concat(a.toc),e}}var Nn={},Hn={markdown:function(e){return{url:e}},mermaid:function(e){return{url:e}},iframe:function(e,n){return{html:'<iframe src="'+e+'" '+(n||"width=100% height=400")+"></iframe>"}},video:function(e,n){return{html:'<video src="'+e+'" '+(n||"controls")+">Not Support</video>"}},audio:function(e,n){return{html:'<audio src="'+e+'" '+(n||"controls")+">Not Support</audio>"}},code:function(e,n){var i=e.match(/\.(\w+)$/);return{url:e,lang:i="md"===(i=n||i&&i[1])?"markdown":i}}};In.prototype.compileEmbed=function(e,n){var i,o,t=On(n),a=t.str,t=t.config;if(n=a,t.include)return T(e)||(e=q(this.contentBase,R(this.router.getCurrentPath()),e)),t.type&&(o=Hn[t.type])?(i=o.call(this,e,n)).type=t.type:(o="code",/\.(md|markdown)/.test(e)?o="markdown":/\.mmd/.test(e)?o="mermaid":/\.html?/.test(e)?o="iframe":/\.(mp4|ogg)/.test(e)?o="video":/\.mp3/.test(e)&&(o="audio"),(i=Hn[o].call(this,e,n)).type=o),i.fragment=t.fragment,i},In.prototype._matchNotCompileLink=function(e){for(var n=this.config.noCompileLinks||[],i=0;i<n.length;i++){var o=n[i];if((Nn[o]||(Nn[o]=new RegExp("^"+o+"$"))).test(e))return e}},In.prototype._initRenderer=function(){var r,c,u,f,p,d,e=new Sn.Renderer,n=this.linkTarget,i=this.linkRel,a=this.router,o=this.contentBase,g=this,t={};return t.heading=e.heading=function(e,n){var i=On(e),o=i.str,t=i.config,e={level:n,title:Ln(o)};/<!-- {docsify-ignore} -->/g.test(o)&&(o=o.replace("\x3c!-- {docsify-ignore} --\x3e",""),e.title=Ln(o),e.ignoreSubHeading=!0),/{docsify-ignore}/g.test(o)&&(o=o.replace("{docsify-ignore}",""),e.title=Ln(o),e.ignoreSubHeading=!0),/<!-- {docsify-ignore-all} -->/g.test(o)&&(o=o.replace("\x3c!-- {docsify-ignore-all} --\x3e",""),e.title=Ln(o),e.ignoreAllSubs=!0),/{docsify-ignore-all}/g.test(o)&&(o=o.replace("{docsify-ignore-all}",""),e.title=Ln(o),e.ignoreAllSubs=!0);i=Cn(t.id||o),t=a.toURL(a.getCurrentPath(),{id:i});return e.slug=t,g.toc.push(e),"<h"+n+' id="'+i+'"><a href="'+t+'" data-id="'+i+'" class="anchor"><span>'+o+"</span></a></h"+n+">"},t.code={renderer:e}.renderer.code=function(e,n){var i=Pn.languages[n=void 0===n?"markup":n]||Pn.languages.markup;return'<pre v-pre data-lang="'+n+'"><code class="lang-'+n+'">'+Pn.highlight(e.replace(/@DOCSIFY_QM@/g,"`"),i,n)+"</code></pre>"},t.link=(i=(n={renderer:e,router:a,linkTarget:n,linkRel:i,compilerClass:g}).renderer,c=n.router,u=n.linkTarget,n.linkRel,f=n.compilerClass,i.link=function(e,n,i){var o=[],t=On(n=void 0===n?"":n),a=t.str,t=t.config;return u=t.target||u,r="_blank"===u?f.config.externalLinkRel||"noopener":"",n=a,T(e)||f._matchNotCompileLink(e)||t.ignore?(T(e)||"./"!==e.slice(0,2)||(e=document.URL.replace(/\/(?!.*\/).*/,"/").replace("#/./","")+e),o.push(0===e.indexOf("mailto:")?"":'target="'+u+'"'),o.push(0!==e.indexOf("mailto:")&&""!==r?' rel="'+r+'"':"")):(e===f.config.homepage&&(e="README"),e=c.toURL(e,null,c.getCurrentPath())),t.crossorgin&&"_self"===u&&"history"===f.config.routerMode&&-1===f.config.crossOriginLinks.indexOf(e)&&f.config.crossOriginLinks.push(e),t.disabled&&(o.push("disabled"),e="javascript:void(0)"),t.class&&o.push('class="'+t.class+'"'),t.id&&o.push('id="'+t.id+'"'),n&&o.push('title="'+n+'"'),'<a href="'+e+'" '+o.join(" ")+">"+i+"</a>"}),t.paragraph={renderer:e}.renderer.paragraph=function(e){e=/^!>/.test(e)?$n("tip",e):/^\?>/.test(e)?$n("warn",e):"<p>"+e+"</p>";return e},t.image=(o=(i={renderer:e,contentBase:o,router:a}).renderer,p=i.contentBase,d=i.router,o.image=function(e,n,i){var o=e,t=[],a=On(n),r=a.str,a=a.config;return n=r,a["no-zoom"]&&t.push("data-no-zoom"),n&&t.push('title="'+n+'"'),a.size&&(n=(r=a.size.split("x"))[0],(r=r[1])?t.push('width="'+n+'" height="'+r+'"'):t.push('width="'+n+'"')),a.class&&t.push('class="'+a.class+'"'),a.id&&t.push('id="'+a.id+'"'),T(e)||(o=q(p,R(d.getCurrentPath()),e)),0<t.length?'<img src="'+o+'" data-origin="'+e+'" alt="'+i+'" '+t.join(" ")+" />":'<img src="'+o+'" data-origin="'+e+'" alt="'+i+'"'+t+">"}),t.list={renderer:e}.renderer.list=function(e,n,i){n=n?"ol":"ul";return"<"+n+" "+[/<li class="task-list-item">/.test(e.split('class="task-list"')[0])?'class="task-list"':"",i&&1<i?'start="'+i+'"':""].join(" ").trim()+">"+e+"</"+n+">"},t.listitem={renderer:e}.renderer.listitem=function(e){return/^(<input.*type="checkbox"[^>]*>)/.test(e)?'<li class="task-list-item"><label>'+e+"</label></li>":"<li>"+e+"</li>"},e.origin=t,e},In.prototype.sidebar=function(e,n){var i=this.toc,o=this.router.getCurrentPath(),t="";if(e)t=this.compile(e);else{for(var a=0;a<i.length;a++)if(i[a].ignoreSubHeading){var r=i[a].level;i.splice(a,1);for(var c=a;c<i.length&&r<i[c].level;c++)i.splice(c,1)&&c--&&a++;a--}n=this.cacheTree[o]||zn(i,n),t=An(n,"<ul>{inner}</ul>");this.cacheTree[o]=n}return t},In.prototype.subSidebar=function(e){if(e){var n=this.router.getCurrentPath(),i=this.cacheTree,o=this.toc;o[0]&&o[0].ignoreAllSubs&&o.splice(0),o[0]&&1===o[0].level&&o.shift();for(var t=0;t<o.length;t++)o[t].ignoreSubHeading&&o.splice(t,1)&&t--;e=i[n]||zn(o,e);return i[n]=e,this.toc=[],An(e)}this.toc=[]},In.prototype.header=function(e,n){return this.heading(e,n)},In.prototype.article=function(e){return this.compile(e)},In.prototype.cover=function(e){var n=this.toc.slice(),e=this.compile(e);return this.toc=n.slice(),e};function Dn(e){var n=Zn(e);return 0===n?e:(n=new RegExp("^[ \\t]{"+n+"}","gm"),e.replace(n,""))}var Un,Zn=function(e){e=e.match(/^[ \t]*(?=\S)/gm);return e?e.reduce(function(e,n){return Math.min(e,n.length)},1/0):0},Bn={};function Vn(e,o){var a=e.compiler,t=e.raw;void 0===t&&(t="");var n=e.fetch,e=Bn[t];if(e){var i=e.slice();return i.links=e.links,o(i)}var i=a._marked,r=i.lexer(t),c=[],u=i.Lexer.rules.inline.link,f=r.links;r.forEach(function(e,t){"paragraph"===e.type&&(e.text=e.text.replace(new RegExp(u.source,"g"),function(e,n,i,o){o=a.compileEmbed(i,o);return o&&c.push({index:t,embed:o}),e}))});var p=[];!function(e,a){var n,i=e.embedTokens,r=e.compile,c=(e.fetch,0),u=1;if(!i.length)return a({});for(;n=i[c++];){var o=function(t){return function(e){var n,i,o;e&&("markdown"===t.embed.type?((i=t.embed.url.split("/")).pop(),i=i.join("/"),e=e.replace(/\[([^[\]]+)\]\(([^)]+)\)/g,function(e){var n=e.indexOf("(");return"(."===e.slice(n,n+2)?e.substring(0,n)+"("+window.location.protocol+"//"+window.location.host+i+"/"+e.substring(n+1,e.length-1)+")":e}),!0===(($docsify.frontMatter||{}).installed||!1)&&(e=$docsify.frontMatter.parseMarkdown(e)),n=r.lexer(e)):"code"===t.embed.type?(t.embed.fragment&&(o=t.embed.fragment,o=new RegExp("(?:###|\\/\\/\\/)\\s*\\["+o+"\\]([\\s\\S]*)(?:###|\\/\\/\\/)\\s*\\["+o+"\\]"),e=Dn((e.match(o)||[])[1]||"").trim()),n=r.lexer("```"+t.embed.lang+"\n"+e.replace(/`/g,"@DOCSIFY_QM@")+"\n```\n")):"mermaid"===t.embed.type?(n=[{type:"html",text:'<div class="mermaid">\n'+e+"\n</div>"}]).links={}:(n=[{type:"html",text:e}]).links={}),a({token:t,embedToken:n}),++u>=c&&a({})}}(n);n.embed.url?X(n.embed.url).then(o):o(n.embed.html)}}({compile:i,embedTokens:c,fetch:n},function(e){var n,i=e.embedToken,e=e.token;e?(n=e.index,p.forEach(function(e){n>e.start&&(n+=e.length)}),m(f,i.links),r=r.slice(0,n).concat(i,r.slice(n+1)),p.push({start:n,length:i.length-1})):(Bn[t]=r.concat(),r.links=Bn[t].links=f,o(r))})}function Yn(e,n,i){var o,t,a,r;return n="function"==typeof i?i(n):"string"==typeof i?(a=[],r=0,(o=i).replace(V,function(n,e,i){a.push(o.substring(r,i-1)),r=i+=n.length+1,a.push(t&&t[n]||function(e){return("00"+("string"==typeof Y[n]?e[Y[n]]():Y[n](e))).slice(-n.length)})}),r!==o.length&&a.push(o.substring(r)),function(e){for(var n="",i=0,o=e||new Date;i<a.length;i++)n+="string"==typeof a[i]?a[i]:a[i](o);return n}(new Date(n))):n,e.replace(/{docsify-updated}/g,n)}function Gn(e){function n(e){var n=Boolean(e.__vue__&&e.__vue__._isVue),e=Boolean(e._vnode&&e._vnode.__v_skip);return n||e}var i=this.config,o=b(".markdown-section"),t="Vue"in window&&window.Vue.version&&Number(window.Vue.version.charAt(0));if(e=e||"<h1>404 - Not found</h1>","Vue"in window)for(var a=0,r=k(".markdown-section > *").filter(n);a<r.length;a+=1){var c=r[a];2===t?c.__vue__.$destroy():3===t&&c.__vue_app__.unmount()}if(this._renderTo(o,e),i.loadSidebar||this._renderSidebar(),(i.executeScript||"Vue"in window&&!1!==i.executeScript)&&(!(e=k(".markdown-section>script").filter(function(e){return!/template/.test(e.type)})[0])||(e=e.innerText.trim())&&new Function(e)()),"Vue"in window){var u,f,p=[],d=Object.keys(i.vueComponents||{});2===t&&d.length&&d.forEach(function(e){window.Vue.options.components[e]||window.Vue.component(e,i.vueComponents[e])}),!Un&&i.vueGlobalOptions&&"function"==typeof i.vueGlobalOptions.data&&(Un=i.vueGlobalOptions.data()),p.push.apply(p,Object.keys(i.vueMounts||{}).map(function(e){return[b(o,e),i.vueMounts[e]]}).filter(function(e){var n=e[0];e[1];return n})),(i.vueGlobalOptions||d.length)&&(u=/{{2}[^{}]*}{2}/,f=/<[^>/]+\s([@:]|v-)[\w-:.[\]]+[=>\s]/,p.push.apply(p,k(".markdown-section > *").filter(function(i){return!p.some(function(e){var n=e[0];e[1];return n===i})}).filter(function(e){return e.tagName.toLowerCase()in(i.vueComponents||{})||e.querySelector(d.join(",")||null)||u.test(e.outerHTML)||f.test(e.outerHTML)}).map(function(e){var n=m({},i.vueGlobalOptions||{});return Un&&(n.data=function(){return Un}),[e,n]})));for(var g=0,s=p;g<s.length;g+=1){var l,v=s[g],h=v[0],_=v[1],v="data-isvue";h.matches("pre, script")||n(h)||h.querySelector("["+v+"]")||(h.setAttribute(v,""),2===t?(_.el=void 0,new window.Vue(_).$mount(h)):3===t&&(l=window.Vue.createApp(_),d.forEach(function(e){var n=i.vueComponents[e];l.component(e,n)}),l.mount(h)))}}}function Wn(n,i,o,t,a,e){n=e?n:n.replace(/\/$/,""),(n=R(n))&&X(a.router.getFile(n+o)+i,!1,a.config.requestHeaders).then(t,function(e){return Wn(n,i,o,t,a)})}function Xn(){var n=function(){return null};return[function(e){n(e)},function(e){n=e}]}Me=Object.freeze({__proto__:null,cached:c,hyphenate:a,hasOwn:u,merge:m,isPrimitive:f,noop:d,isFn:o,isExternal:g,inBrowser:!0,isMobile:s,supportsPushState:t,parseQuery:F,stringifyQuery:E,isAbsolutePath:T,removeParams:C,getParentPath:R,cleanPath:j,resolvePath:O,getPath:q,replaceSlug:P});var Qn,Jn=function(e){function n(){e.call(this),this.config=ue(this),this.initLifecycle(),this.initPlugin(),this.callHook("init"),this.initRouter(),this.initRender(),this.initEvent(),this.initFetch(),this.callHook("mounted")}return e&&(n.__proto__=e),((n.prototype=Object.create(e&&e.prototype)).constructor=n).prototype.initPlugin=function(){var n=this;[].concat(this.config.plugins).forEach(function(e){try{o(e)&&e(n._lifecycle,n)}catch(e){if(!n.config.catchPluginErrors)throw e;console.error("Docsify plugin error",e)}})},n}((we=Object,function(e){function n(){e.apply(this,arguments)}return e&&(n.__proto__=e),((n.prototype=Object.create(e&&e.prototype)).constructor=n).prototype._loadSideAndNav=function(e,n,i,o){var t=this;return function(){if(!i)return o();Wn(e,n,i,function(e){t._renderSidebar(e),o()},t,!0)}},n.prototype._fetch=function(i){var o=this;void 0===i&&(i=d);var t,e,n,a,r,c,u,f=this.route.query,p=this.route.path;g(p)?(history.replaceState(null,"","#"),this.router.normalize()):(t=E(f,["id"]),f=(e=this.config).loadNavbar,n=e.requestHeaders,a=e.loadSidebar,r=this.router.getFile(p),this.isRemoteUrl=g(r),this.isHTML=/\.html$/g.test(r),c=function(e,n){o._renderMain(e,n,o._loadSideAndNav(p,t,a,i))},u=function(e){o._fetchFallbackPage(p,t,i)||o._fetch404(r,t,i)},this.isRemoteUrl?Kn(r+t,0,n).then(c,u):this.matchVirtualRoute(p).then(function(e){"string"==typeof e?c(e):Kn(r+t,0,n).then(c,u)}),f&&Wn(p,t,f,function(e){return o._renderNav(e)},this,!0))},n.prototype._fetchCover=function(){var n=this,e=this.config,i=e.coverpage,o=e.requestHeaders,t=this.route.query,a=R(this.route.path);if(i){var r=null,e=this.route.path;"string"==typeof i?"/"===e&&(r=i):r=Array.isArray(i)?-1<i.indexOf(e)&&"_coverpage":!0===(e=i[e])?"_coverpage":e;var c=Boolean(r)&&this.config.onlyCover;return r?(r=this.router.getFile(a+r),this.coverIsHTML=/\.html$/g.test(r),X(r+E(t,["id"]),!1,o).then(function(e){return n._renderCover(e,c)})):this._renderCover(null,c),c}},n.prototype.$fetch=function(e,n){var i=this;void 0===e&&(e=d),void 0===n&&(n=this.$resetEvents.bind(this));function o(){i.callHook("doneEach"),e()}this._fetchCover()?o():this._fetch(function(){n(),o()})},n.prototype._fetchFallbackPage=function(i,o,t){var a=this;void 0===t&&(t=d);var e=this.config,n=e.requestHeaders,r=e.fallbackLanguages,c=e.loadSidebar;if(!r)return!1;e=i.split("/")[1];if(-1===r.indexOf(e))return!1;e=this.router.getFile(i.replace(new RegExp("^/"+e),""));return Kn(e+o,0,n).then(function(e,n){return a._renderMain(e,n,a._loadSideAndNav(i,o,c,t))},function(){return a._fetch404(i,o,t)}),!0},n.prototype._fetch404=function(e,n,i){var o=this,t=this.config,a=t.loadSidebar,r=t.requestHeaders,t=t.notFoundPage,c=this._loadSideAndNav(e,n,a,i=void 0===i?d:i);if(t){e=function(n,e){var i,o,t=e.notFoundPage,a="_404"+(e.ext||".md");switch(typeof t){case"boolean":o=a;break;case"string":o=t;break;case"object":o=(i=Object.keys(t).sort(function(e,n){return n.length-e.length}).filter(function(e){return n.match(new RegExp("^"+e))})[0])&&t[i]||a}return o}(e,this.config);return Kn(this.router.getFile(e),0,r).then(function(e,n){return o._renderMain(e,n,c)},function(){return o._renderMain(null,{},c)}),!0}return this._renderMain(null,{},c),!1},n.prototype.initFetch=function(){var e,n=this,i=this.config.loadSidebar;this.rendered?(e=ee(this.router,".sidebar-nav",!0,!0),i&&e&&(e.parentNode.innerHTML+=window.__SUB_SIDEBAR__),this._bindEventOnRendered(e),this.$resetEvents(),this.callHook("doneEach"),this.callHook("ready")):this.$fetch(function(e){return n.callHook("ready")})},n}(function(e){function n(){e.apply(this,arguments)}return e&&(n.__proto__=e),((n.prototype=Object.create(e&&e.prototype)).constructor=n).prototype.$resetEvents=function(e){var n=this,i=this.config.auto2top;"history"!==e&&(n.route.query.id&&he(n.route.path,n.route.query.id),"navigate"===e&&i&&(i=i,_e.scrollTop=!0===(i=void 0===i?0:i)?0:Number(i))),this.config.loadNavbar&&ee(this.router,"nav")},n.prototype.initEvent=function(){function n(e){return h.classList.toggle("close")}var e;e="button.sidebar-toggle",this.router,null!=(e=l(e))&&(p(e,"click",function(e){e.stopPropagation(),n()}),s&&p(h,"click",function(e){return h.classList.contains("close")&&n()})),e=".sidebar",this.router,null!=(e=l(e))&&p(e,"click",function(e){e=e.target;"A"===e.nodeName&&e.nextSibling&&e.nextSibling.classList&&e.nextSibling.classList.contains("app-sub-sidebar")&&S(e.parentNode,"collapse")}),this.config.coverpage?s||p("scroll",K):h.classList.add("sticky")},n}(function(e){function n(){e.apply(this,arguments)}return e&&(n.__proto__=e),((n.prototype=Object.create(e&&e.prototype)).constructor=n).prototype._renderTo=function(e,n,i){e=l(e);e&&(e[i?"outerHTML":"innerHTML"]=n)},n.prototype._renderSidebar=function(e){var n=this.config,i=n.maxLevel,o=n.subMaxLevel,t=n.loadSidebar;if(n.hideSidebar)return[document.querySelector("aside.sidebar"),document.querySelector("button.sidebar-toggle")].filter(function(e){return!!e}).forEach(function(e){return e.parentNode.removeChild(e)}),document.querySelector("section.content").style.right="unset",document.querySelector("section.content").style.left="unset",document.querySelector("section.content").style.position="relative",document.querySelector("section.content").style.width="100%",null;this._renderTo(".sidebar-nav",this.compiler.sidebar(e,i));i=ee(this.router,".sidebar-nav",!0,!0);t&&i?i.parentNode.innerHTML+=this.compiler.subSidebar(o)||"":this.compiler.subSidebar(),this._bindEventOnRendered(i)},n.prototype._bindEventOnRendered=function(e){var n,i=this.config.autoHeader;!function(e){var n=b(".cover.show");se=n?n.offsetHeight:0;for(var i,n=l(".sidebar"),o=[],t=0,a=(o=null!=n?k(n,"li"):o).length;t<a;t+=1){var r,c,u=o[t],f=u.querySelector("a");f&&("/"!==(r=f.getAttribute("href"))&&(f=(c=e.parse(r)).query.id,c=c.path,f&&(r=ve(c,f))),r&&(fe[decodeURIComponent(r)]=u))}s||(i=C(e.getCurrentPath()),x("scroll",function(){return le(i)}),p("scroll",function(){return le(i)}),p(n,"mouseover",function(){pe=!0}),p(n,"mouseleave",function(){pe=!1}))}(this.router),i&&e&&((i=(n=l("#main")).children[0])&&"H1"!==i.tagName&&y(n,w("div",this.compiler.header(e.innerText,1)).children[0]))},n.prototype._renderNav=function(e){e&&this._renderTo("nav",this.compiler.compile(e)),this.config.loadNavbar&&ee(this.router,"nav")},n.prototype._renderMain=function(o,t,a){var r=this;if(void 0===t&&(t={}),!o)return Gn.call(this,o);this.callHook("beforeEach",o,function(e){function n(){t.updatedAt&&(i=Yn(i,t.updatedAt,r.config.formatUpdated)),r.callHook("afterEach",i,function(e){Gn.call(r,e),a()})}var i;r.isHTML?(i=r.result=o,n()):Vn({compiler:r.compiler,raw:e},function(e){i=r.compiler.compile(e),n()})})},n.prototype._renderCover=function(e,n){var i,o=l(".cover");S(l("main"),n?"add":"remove","hidden"),e?(S(o,"add","show"),(n=(i=this.coverIsHTML?e:this.compiler.cover(e)).trim().match('<p><img.*?data-origin="(.*?)"[^a]+alt="(.*?)">([^<]*?)</p>$'))&&("color"===n[2]?o.style.background=n[1]+(n[3]||""):(e=n[1],S(o,"add","has-mask"),T(n[1])||(e=q(this.router.getBasePath(),n[1])),o.style.backgroundImage="url("+e+")",o.style.backgroundSize="cover",o.style.backgroundPosition="center center"),i=i.replace(n[0],"")),this._renderTo(".cover-main",i),K()):S(o,"remove","show")},n.prototype._updateRender=function(){var e,n,i,o;e=this,n=l(".app-name-link"),i=e.config.nameLink,o=e.route.path,n&&(f(e.config.nameLink)?n.setAttribute("href",i):"object"==typeof i&&(e=Object.keys(i).filter(function(e){return-1<o.indexOf(e)})[0],n.setAttribute("href",i[e])))},n.prototype.initRender=function(){var e=this.config;this.compiler=new In(e,this.router),window.__current_docsify_compiler__=this.compiler;var n,i,o,t,a,r=e.el||"#app",c=b("nav")||w("nav"),u=b(r),f="",p=h;u?(e.repo&&(f+=(t=e.repo,r=e.cornerExternalLinkTarget,t?'<a href="'+(t=(t=!/\/\//.test(t)?"https://github.com/"+t:t).replace(/^git\+/,""))+'" target="'+(r=r||"_blank")+'" class="github-corner" aria-label="View source on Github"><svg viewBox="0 0 250 250" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a>':"")),e.coverpage&&(f+=(o=", 100%, 85%",'<section class="cover show" style="background: '+("linear-gradient(to left bottom, hsl("+Math.floor(255*Math.random())+o+") 0%,hsl("+Math.floor(255*Math.random())+o+") 100%)")+'"><div class="mask"></div><div class="cover-main">\x3c!--cover--\x3e</div></section>')),e.logo&&(o=/^data:image/.test(e.logo),n=/(?:http[s]?:)?\/\//.test(e.logo),i=/^\./.test(e.logo),o||n||i||(e.logo=q(this.router.getBasePath(),e.logo))),f+=(i=(n=e).name||"","<main>"+('<button class="sidebar-toggle" aria-label="Menu"><div class="sidebar-toggle-button"><span></span><span></span><span></span></div></button><aside class="sidebar">'+(n.name?'<h1 class="app-name"><a class="app-name-link" data-nosearch>'+(n.logo?'<img alt="'+i+'" src='+n.logo+">":i)+"</a></h1>":"")+'<div class="sidebar-nav">\x3c!--sidebar--\x3e</div></aside>')+'<section class="content"><article class="markdown-section" id="main">\x3c!--main--\x3e</article></section></main>'),this._renderTo(u,f,!0)):this.rendered=!0,e.mergeNavbar&&s?p=b(".sidebar"):(c.classList.add("app-nav"),e.repo||c.classList.add("no-badge")),e.loadNavbar&&y(p,c),e.themeColor&&(v.head.appendChild(w("div","<style>:root{--theme-color: "+e.themeColor+";}</style>").firstElementChild),a=e.themeColor,window.CSS&&window.CSS.supports&&window.CSS.supports("(--v:red)")||(e=k("style:not(.inserted),link"),[].forEach.call(e,function(e){"STYLE"===e.nodeName?Q(e,a):"LINK"===e.nodeName&&(e=e.getAttribute("href"),/\.css$/.test(e)&&X(e).then(function(e){e=w("style",e);_.appendChild(e),Q(e,a)}))}))),this._updateRender(),S(h,"ready")},n}(function(e){function n(){e.apply(this,arguments)}return e&&(n.__proto__=e),((n.prototype=Object.create(e&&e.prototype)).constructor=n).prototype.routes=function(){return this.config.routes||{}},n.prototype.matchVirtualRoute=function(t){var a=this.routes(),r=Object.keys(a),c=function(){return null};function u(){var e=r.shift();if(!e)return c(null);var n=A(o=(i="^",0===(o=e).indexOf(i)?o:"^"+o),"$")?o:o+"$",i=t.match(n);if(!i)return u();var o=a[e];if("string"==typeof o)return c(o);if("function"!=typeof o)return u();n=o,e=Xn(),o=e[0];return(0,e[1])(function(e){return"string"==typeof e?c(e):!1===e?c(null):u()}),n.length<=2?o(n(t,i)):n(t,i,o)}return{then:function(e){c=e,u()}}},n}(function(i){function e(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];i.apply(this,e),this.route={}}return i&&(e.__proto__=i),((e.prototype=Object.create(i&&i.prototype)).constructor=e).prototype.updateRender=function(){this.router.normalize(),this.route=this.router.parse(),h.setAttribute("data-page",this.route.file)},e.prototype.initRouter=function(){var n=this,e=this.config,e=new("history"===(e.routerMode||"hash")&&t?D:H)(e);this.router=e,this.updateRender(),U=this.route,e.onchange(function(e){n.updateRender(),n._updateRender(),U.path!==n.route.path?(n.$fetch(d,n.$resetEvents.bind(n,e.source)),U=n.route):n.$resetEvents(e.source)})},e}(function(e){function n(){e.apply(this,arguments)}return e&&(n.__proto__=e),((n.prototype=Object.create(e&&e.prototype)).constructor=n).prototype.initLifecycle=function(){var i=this;this._hooks={},this._lifecycle={},["init","mounted","beforeEach","afterEach","doneEach","ready"].forEach(function(e){var n=i._hooks[e]=[];i._lifecycle[e]=function(e){return n.push(e)}})},n.prototype.callHook=function(e,t,a){void 0===a&&(a=d);var r=this._hooks[e],c=this.config.catchPluginErrors,u=function(n){var e=r[n];if(n>=r.length)a(t);else if("function"==typeof e){var i="Docsify plugin error";if(2===e.length)try{e(t,function(e){t=e,u(n+1)})}catch(e){if(!c)throw e;console.error(i,e),u(n+1)}else try{var o=e(t);t=void 0===o?t:o,u(n+1)}catch(e){if(!c)throw e;console.error(i,e),u(n+1)}}else u(n+1)};u(0)},n}(we))))))));function Kn(e,n,i){return Qn&&Qn.abort&&Qn.abort(),Qn=X(e,!0,i)}window.Docsify={util:Me,dom:n,get:X,slugify:Cn,version:"4.13.0"},window.DocsifyCompiler=In,window.marked=Sn,window.Prism=Pn,e(function(e){return new Jn})}(); | ... | ... |
doc/lib/js/search.min.js
0 → 100644
| 1 | +!function(){function u(e){return e.replace(/<!-- {docsify-ignore} -->/,"").replace(/{docsify-ignore}/,"").replace(/<!-- {docsify-ignore-all} -->/,"").replace(/{docsify-ignore-all}/,"").trim()}var f={},m={EXPIRE_KEY:"docsify.search.expires",INDEX_KEY:"docsify.search.index"};function g(e){var n={"&":"&","<":"<",">":">",'"':""","'":"'"};return String(e).replace(/[&<>"']/g,function(e){return n[e]})}function y(e){return e.text||"table"!==e.type||(e.cells.unshift(e.header),e.text=e.cells.map(function(e){return e.join(" | ")}).join(" |\n ")),e.text}function v(e){return e.text||"list"!==e.type||(e.text=e.raw),e.text}function b(o,e,s,c){void 0===e&&(e="");var d,e=window.marked.lexer(e),l=window.Docsify.slugify,p={},h="";return e.forEach(function(e,n){var t,a,i,r;"heading"===e.type&&e.depth<=c?(t=(a=(i=e.text,r={},{str:i=(i=void 0===i?"":i)&&i.replace(/^('|")/,"").replace(/('|")$/,"").replace(/(?:^|\s):([\w-]+:?)=?([\w-%]+)?/g,function(e,n,t){return-1===n.indexOf(":")?(r[n]=t&&t.replace(/"/g,"")||!0,""):e}).trim(),config:r})).str,i=a.config,a=u(e.text),d=i.id?s.toURL(o,{id:l(i.id)}):s.toURL(o,{id:l(g(a))}),t&&(h=u(t)),p[d]={slug:d,title:h,body:""}):(0===n&&(d=s.toURL(o),p[d]={slug:d,title:"/"!==o?o.slice(1):"Home Page",body:e.text||""}),d&&(p[d]?p[d].body?(e.text=y(e),e.text=v(e),p[d].body+="\n"+(e.text||"")):(e.text=y(e),e.text=v(e),p[d].body=p[d].body?p[d].body+e.text:e.text):p[d]={slug:d,title:"",body:""}))}),l.clear(),p}function p(e){return e&&e.normalize?e.normalize("NFD").replace(/[\u0300-\u036f]/g,""):e}function o(e){var n=[],t=[];Object.keys(f).forEach(function(n){t=t.concat(Object.keys(f[n]).map(function(e){return f[n][e]}))});var a=(e=e.trim()).split(/[\s\-,\\/]+/);1!==a.length&&(a=[].concat(e,a));for(var i=0;i<t.length;i++)!function(e){var e=t[e],r=0,o="",s="",c="",d=e.title&&e.title.trim(),l=e.body&&e.body.trim(),e=e.slug||"";d&&(a.forEach(function(e){var n,t,a=new RegExp(g(p(e)).replace(/[|\\{}()[\]^$+*?.]/g,"\\$&"),"gi"),i=-1;s=d&&g(p(d)),c=l&&g(p(l)),t=d?s.search(a):-1,i=l?c.search(a):-1,(0<=t||0<=i)&&(r+=0<=t?3:0<=i?2:0,t=(t=n=0)==(n=(i=i<0?0:i)<11?0:i-10)?70:i+e.length+60,l&&t>l.length&&(t=l.length),a=c&&"..."+c.substring(n,t).replace(a,function(e){return'<em class="search-keyword">'+e+"</em>"})+"...",o+=a)}),0<r&&(e={title:s,content:l?o:"",url:e,score:r},n.push(e)))}(i);return n.sort(function(e,n){return n.score-e.score})}function r(a,i){var t,r,n,e,o="auto"===a.paths,s=o?(t=i.router,r=[],Docsify.dom.findAll(".sidebar-nav a:not(.section-link):not([data-nosearch])").forEach(function(e){var n=e.href,e=e.getAttribute("href"),n=t.parse(n).path;n&&-1===r.indexOf(n)&&!Docsify.util.isAbsolutePath(e)&&r.push(n)}),r):a.paths,c="";s.length&&o&&a.pathNamespaces?(n=s[0],Array.isArray(a.pathNamespaces)?c=a.pathNamespaces.filter(function(e){return n.slice(0,e.length)===e})[0]||c:a.pathNamespaces instanceof RegExp&&((d=n.match(a.pathNamespaces))&&(c=d[0])),e=-1===s.indexOf(c+"/"),d=-1===s.indexOf(c+"/README"),e&&d&&s.unshift(c+"/")):-1===s.indexOf("/")&&-1===s.indexOf("/README")&&s.unshift("/");var d,l=((d=a.namespace)?m.EXPIRE_KEY+"/"+d:m.EXPIRE_KEY)+c,p=((d=a.namespace)?m.INDEX_KEY+"/"+d:m.INDEX_KEY)+c,c=localStorage.getItem(l)<Date.now();if(f=JSON.parse(localStorage.getItem(p)),c)f={};else if(!o)return;var h=s.length,u=0;s.forEach(function(t){return f[t]?u++:void Docsify.get(i.router.getFile(t),!1,i.config.requestHeaders).then(function(e){var n;f[t]=b(t,e,i.router,a.depth),h===++u&&(n=a.maxAge,e=p,localStorage.setItem(l,Date.now()+n),localStorage.setItem(e,JSON.stringify(f)))})})}var s,c="";function d(e){var n=Docsify.dom.find("div.search"),t=Docsify.dom.find(n,".results-panel"),a=Docsify.dom.find(n,".clear-button"),i=Docsify.dom.find(".sidebar-nav"),n=Docsify.dom.find(".app-name");if(!e)return t.classList.remove("show"),a.classList.remove("show"),t.innerHTML="",void(s.hideOtherSidebarContent&&(i&&i.classList.remove("hide"),n&&n.classList.remove("hide")));var e=o(e),r="";e.forEach(function(e){r+='<div class="matching-post">\n<a href="'+e.url+'">\n<h2>'+e.title+"</h2>\n<p>"+e.content+"</p>\n</a>\n</div>"}),t.classList.add("show"),a.classList.add("show"),t.innerHTML=r||'<p class="empty">'+c+"</p>",s.hideOtherSidebarContent&&(i&&i.classList.add("hide"),n&&n.classList.add("hide"))}function l(e){s=e}function h(e,n){var t,a,i=n.router.parse().query.s;l(e),Docsify.dom.style("\n.sidebar {\n padding-top: 0;\n}\n\n.search {\n margin-bottom: 20px;\n padding: 6px;\n border-bottom: 1px solid #eee;\n}\n\n.search .input-wrap {\n display: flex;\n align-items: center;\n}\n\n.search .results-panel {\n display: none;\n}\n\n.search .results-panel.show {\n display: block;\n}\n\n.search input {\n outline: none;\n border: none;\n width: 100%;\n padding: 0.6em 7px;\n font-size: inherit;\n border: 1px solid transparent;\n}\n\n.search input:focus {\n box-shadow: 0 0 5px var(--theme-color, #42b983);\n border: 1px solid var(--theme-color, #42b983);\n}\n\n.search input::-webkit-search-decoration,\n.search input::-webkit-search-cancel-button,\n.search input {\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n\n.search input::-ms-clear {\n display: none;\n height: 0;\n width: 0;\n}\n\n.search .clear-button {\n cursor: pointer;\n width: 36px;\n text-align: right;\n display: none;\n}\n\n.search .clear-button.show {\n display: block;\n}\n\n.search .clear-button svg {\n transform: scale(.5);\n}\n\n.search h2 {\n font-size: 17px;\n margin: 10px 0;\n}\n\n.search a {\n text-decoration: none;\n color: inherit;\n}\n\n.search .matching-post {\n border-bottom: 1px solid #eee;\n}\n\n.search .matching-post:last-child {\n border-bottom: 0;\n}\n\n.search p {\n font-size: 14px;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n\n.search p.empty {\n text-align: center;\n}\n\n.app-name.hide, .sidebar-nav.hide {\n display: none;\n}"),function(e){void 0===e&&(e="");var n=Docsify.dom.create("div",'<div class="input-wrap">\n <input type="search" value="'+e+'" aria-label="Search text" />\n <div class="clear-button">\n <svg width="26" height="24">\n <circle cx="12" cy="12" r="11" fill="#ccc" />\n <path stroke="white" stroke-width="2" d="M8.25,8.25,15.75,15.75" />\n <path stroke="white" stroke-width="2"d="M8.25,15.75,15.75,8.25" />\n </svg>\n </div>\n </div>\n <div class="results-panel"></div>\n </div>'),e=Docsify.dom.find("aside");Docsify.dom.toggleClass(n,"search"),Docsify.dom.before(e,n)}(i),n=Docsify.dom.find("div.search"),a=Docsify.dom.find(n,"input"),e=Docsify.dom.find(n,".input-wrap"),Docsify.dom.on(n,"click",function(e){return-1===["A","H2","P","EM"].indexOf(e.target.tagName)&&e.stopPropagation()}),Docsify.dom.on(a,"input",function(n){clearTimeout(t),t=setTimeout(function(e){return d(n.target.value.trim())},100)}),Docsify.dom.on(e,"click",function(e){"INPUT"!==e.target.tagName&&(a.value="",d())}),i&&setTimeout(function(e){return d(i)},500)}function x(e,n){var t,a,i,r,o;l(e),t=e.placeholder,a=n.route.path,(r=Docsify.dom.getNode('.search input[type="search"]'))&&("string"==typeof t?r.placeholder=t:(i=Object.keys(t).filter(function(e){return-1<a.indexOf(e)})[0],r.placeholder=t[i])),e=e.noData,o=n.route.path,c="string"==typeof e?e:e[Object.keys(e).filter(function(e){return-1<o.indexOf(e)})[0]]}var w={placeholder:"Type to search",noData:"No Results!",paths:"auto",depth:2,maxAge:864e5,hideOtherSidebarContent:!1,namespace:void 0,pathNamespaces:void 0};$docsify.plugins=[].concat(function(e,n){var t=Docsify.util,a=n.config.search||w;Array.isArray(a)?w.paths=a:"object"==typeof a&&(w.paths=Array.isArray(a.paths)?a.paths:"auto",w.maxAge=(t.isPrimitive(a.maxAge)?a:w).maxAge,w.placeholder=a.placeholder||w.placeholder,w.noData=a.noData||w.noData,w.depth=a.depth||w.depth,w.hideOtherSidebarContent=a.hideOtherSidebarContent||w.hideOtherSidebarContent,w.namespace=a.namespace||w.namespace,w.pathNamespaces=a.pathNamespaces||w.pathNamespaces);var i="auto"===w.paths;e.mounted(function(e){h(w,n),i||r(w,n)}),e.doneEach(function(e){x(w,n),i&&r(w,n)})},$docsify.plugins)}(); | ... | ... |
doc/lib/js/zoom-image.min.js
0 → 100644
| 1 | +!function(){function t(e){return"IMG"===e.tagName}function d(e){function t(){for(var e=arguments,t=arguments.length,o=Array(t),n=0;n<t;n++)o[n]=e[n];var i=o.reduce(function(e,t){return[].concat(e,z(t))},[]);return i.filter(function(e){return-1===m.indexOf(e)}).forEach(function(e){m.push(e),e.classList.add("medium-zoom-image")}),r.forEach(function(e){var t=e.type,o=e.listener,n=e.options;i.forEach(function(e){e.addEventListener(t,o,n)})}),f}function o(){var e=(0<arguments.length&&void 0!==arguments[0]?arguments[0]:{}).target;return s.original?a():i({target:e})}var n=window.Promise||function(e){function t(){}e(t,t)},i=function(){function r(){var e={width:document.documentElement.clientWidth,height:document.documentElement.clientHeight,left:0,top:0,right:0,bottom:0},t=void 0,o=void 0;u.container&&(u.container instanceof Object?(t=(e=g({},e,u.container)).width-e.left-e.right-2*u.margin,o=e.height-e.top-e.bottom-2*u.margin):(r=(i=(h(u.container)?u.container:document.querySelector(u.container)).getBoundingClientRect()).width,m=i.height,d=i.left,a=i.top,e=g({},e,{width:r,height:m,left:d,top:a})));var t=t||e.width-2*u.margin,o=o||e.height-2*u.margin,n=s.zoomedHd||s.original,i=!v(n)&&n.naturalWidth||t,r=!v(n)&&n.naturalHeight||o,d=(m=n.getBoundingClientRect()).top,a=m.left,n=m.width,m=m.height,i=Math.min(i,t)/n,r=Math.min(r,o)/m,r="scale("+(r=Math.min(i,r))+") translate3d("+((t-n)/2-a+u.margin+e.left)/r+"px, "+((o-m)/2-d+u.margin+e.top)/r+"px, 0)";s.zoomed.style.transform=r,s.zoomedHd&&(s.zoomedHd.style.transform=r)}var d=(0<arguments.length&&void 0!==arguments[0]?arguments[0]:{}).target;return new n(function(e){if(d&&-1===m.indexOf(d))e(f);else{function t(){c=!1,s.zoomed.removeEventListener("transitionend",t),s.original.dispatchEvent(E("medium-zoom:opened",{detail:{zoom:f}})),e(f)}var o,n;if(s.zoomed)e(f);else{if(d)s.original=d;else{if(!(0<m.length))return void e(f);var i=m;s.original=i[0]}s.original.dispatchEvent(E("medium-zoom:open",{detail:{zoom:f}})),l=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,c=!0,s.zoomed=b(s.original),document.body.appendChild(p),u.template&&(i=h(u.template)?u.template:document.querySelector(u.template),s.template=document.createElement("div"),s.template.appendChild(i.content.cloneNode(!0)),document.body.appendChild(s.template)),document.body.appendChild(s.zoomed),window.requestAnimationFrame(function(){document.body.classList.add("medium-zoom--opened")}),s.original.classList.add("medium-zoom-image--hidden"),s.zoomed.classList.add("medium-zoom-image--opened"),s.zoomed.addEventListener("click",a),s.zoomed.addEventListener("transitionend",t),s.original.getAttribute("data-zoom-src")?(s.zoomedHd=s.zoomed.cloneNode(),s.zoomedHd.removeAttribute("srcset"),s.zoomedHd.removeAttribute("sizes"),s.zoomedHd.src=s.zoomed.getAttribute("data-zoom-src"),s.zoomedHd.onerror=function(){clearInterval(o),console.warn("Unable to reach the zoom image target "+s.zoomedHd.src),s.zoomedHd=null,r()},o=setInterval(function(){s.zoomedHd.complete&&(clearInterval(o),s.zoomedHd.classList.add("medium-zoom-image--opened"),s.zoomedHd.addEventListener("click",a),document.body.appendChild(s.zoomedHd),r())},10)):s.original.hasAttribute("srcset")?(s.zoomedHd=s.zoomed.cloneNode(),s.zoomedHd.removeAttribute("sizes"),s.zoomedHd.removeAttribute("loading"),n=s.zoomedHd.addEventListener("load",function(){s.zoomedHd.removeEventListener("load",n),s.zoomedHd.classList.add("medium-zoom-image--opened"),s.zoomedHd.addEventListener("click",a),document.body.appendChild(s.zoomedHd),r()})):r()}}})},a=function(){return new n(function(t){var e;!c&&s.original?(e=function e(){s.original.classList.remove("medium-zoom-image--hidden"),document.body.removeChild(s.zoomed),s.zoomedHd&&document.body.removeChild(s.zoomedHd),document.body.removeChild(p),s.zoomed.classList.remove("medium-zoom-image--opened"),s.template&&document.body.removeChild(s.template),c=!1,s.zoomed.removeEventListener("transitionend",e),s.original.dispatchEvent(E("medium-zoom:closed",{detail:{zoom:f}})),s.original=null,s.zoomed=null,s.zoomedHd=null,s.template=null,t(f)},c=!0,document.body.classList.remove("medium-zoom--opened"),s.zoomed.style.transform="",s.zoomedHd&&(s.zoomedHd.style.transform=""),s.template&&(s.template.style.transition="opacity 150ms",s.template.style.opacity=0),s.original.dispatchEvent(E("medium-zoom:close",{detail:{zoom:f}})),s.zoomed.addEventListener("transitionend",e)):t(f)})},m=[],r=[],c=!1,l=0,u=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},s={original:null,zoomed:null,zoomedHd:null,template:null};"[object Object]"===Object.prototype.toString.call(e)?u=e:!e&&"string"!=typeof e||t(e);var u=g({margin:0,background:"#fff",scrollOffset:40,container:null,template:null},u),p=y(u.background);document.addEventListener("click",function(e){e=e.target;e!==p?-1!==m.indexOf(e)&&o({target:e}):a()}),document.addEventListener("keyup",function(e){e=e.key||e.keyCode;"Escape"!==e&&"Esc"!==e&&27!==e||a()}),document.addEventListener("scroll",function(){var e;!c&&s.original&&(e=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,Math.abs(l-e)>u.scrollOffset&&setTimeout(a,150))}),window.addEventListener("resize",a);var f={open:i,close:a,toggle:o,update:function(){var e=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{},t=e;return e.background&&(p.style.background=e.background),e.container&&e.container instanceof Object&&(t.container=g({},u.container,e.container)),e.template&&(e=h(e.template)?e.template:document.querySelector(e.template),t.template=e),u=g({},u,t),m.forEach(function(e){e.dispatchEvent(E("medium-zoom:update",{detail:{zoom:f}}))}),f},clone:function(){return d(g({},u,0<arguments.length&&void 0!==arguments[0]?arguments[0]:{}))},attach:t,detach:function(){for(var e=arguments,t=arguments.length,o=Array(t),n=0;n<t;n++)o[n]=e[n];s.zoomed&&a();var i=0<o.length?o.reduce(function(e,t){return[].concat(e,z(t))},[]):m;return i.forEach(function(e){e.classList.remove("medium-zoom-image"),e.dispatchEvent(E("medium-zoom:detach",{detail:{zoom:f}}))}),m=m.filter(function(e){return-1===i.indexOf(e)}),f},on:function(t,o){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};return m.forEach(function(e){e.addEventListener("medium-zoom:"+t,o,n)}),r.push({type:"medium-zoom:"+t,listener:o,options:n}),f},off:function(t,o){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};return m.forEach(function(e){e.removeEventListener("medium-zoom:"+t,o,n)}),r=r.filter(function(e){return!(e.type==="medium-zoom:"+t&&e.listener.toString()===o.toString())}),f},getOptions:function(){return u},getImages:function(){return m},getZoomedImage:function(){return s.original}};return f}var g=Object.assign||function(e){for(var t=arguments,o=1;o<arguments.length;o++){var n,i=t[o];for(n in i)Object.prototype.hasOwnProperty.call(i,n)&&(e[n]=i[n])}return e},h=function(e){return e&&1===e.nodeType},v=function(e){return".svg"===(e.currentSrc||e.src).substr(-4).toLowerCase()},z=function(e){try{return Array.isArray(e)?e.filter(t):NodeList.prototype.isPrototypeOf(e)?[].slice.call(e).filter(t):h(e)?[e].filter(t):"string"==typeof e?[].slice.call(document.querySelectorAll(e)).filter(t):[]}catch(e){throw new TypeError("The provided selector is invalid.\nExpects a CSS selector, a Node element, a NodeList or an array.\nSee: https://github.com/francoischalifour/medium-zoom")}},y=function(e){var t=document.createElement("div");return t.classList.add("medium-zoom-overlay"),t.style.background=e,t},b=function(e){var t=e.getBoundingClientRect(),o=t.top,n=t.left,i=t.width,r=t.height,d=e.cloneNode(),t=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,e=window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft||0;return d.removeAttribute("id"),d.style.position="absolute",d.style.top=o+t+"px",d.style.left=n+e+"px",d.style.width=i+"px",d.style.height=r+"px",d.style.transform="",d},E=function(e,t){var o=g({bubbles:!1,cancelable:!1,detail:void 0},t);if("function"==typeof window.CustomEvent)return new CustomEvent(e,o);t=document.createEvent("CustomEvent");return t.initCustomEvent(e,o.bubbles,o.cancelable,o.detail),t};var e,o,n,i;e=".medium-zoom-overlay{position:fixed;top:0;right:0;bottom:0;left:0;opacity:0;transition:opacity .3s;will-change:opacity}.medium-zoom--opened .medium-zoom-overlay{cursor:pointer;cursor:zoom-out;opacity:1}.medium-zoom-image{cursor:pointer;cursor:zoom-in;transition:transform .3s cubic-bezier(.2,0,.2,1)!important}.medium-zoom-image--hidden{visibility:hidden}.medium-zoom-image--opened{position:relative;cursor:pointer;cursor:zoom-out;will-change:transform}",i=(o=void 0===o?{}:o).insertAt,e&&"undefined"!=typeof document&&(n=document.head||document.getElementsByTagName("head")[0],(o=document.createElement("style")).type="text/css","top"===i&&n.firstChild?n.insertBefore(o,n.firstChild):n.appendChild(o),o.styleSheet?o.styleSheet.cssText=e:o.appendChild(document.createTextNode(e)));var r=Element.prototype.matches||Element.prototype.webkitMatchesSelector||Element.prototype.msMatchesSelector;$docsify.plugins=[].concat(function(e){var o;e.doneEach(function(e){var t=(t=Array.apply(null,document.querySelectorAll(".markdown-section img:not(.emoji):not([data-no-zoom])"))).filter(function(e){return!1===r.call(e,"a img")});o&&o.detach(),o=d(t)})},$docsify.plugins)}(); | ... | ... |
libs/jdbc-aarch/kingbase8-8.6.0.jar
0 → 100644
No preview for this file type
libs/jdbc-aarch/kingbase8-8.6.0.jre7.jar
0 → 100644
No preview for this file type
libs/jdbc-aarch/postgresql-42.2.9.jar
0 → 100644
No preview for this file type
libs/jdbc-aarch/postgresql-42.2.9.jre7.jar
0 → 100644
No preview for this file type
pom.xml
| ... | ... | @@ -11,7 +11,7 @@ |
| 11 | 11 | |
| 12 | 12 | <groupId>com.genersoft</groupId> |
| 13 | 13 | <artifactId>wvp-pro</artifactId> |
| 14 | - <version>2.6.8</version> | |
| 14 | + <version>2.6.9</version> | |
| 15 | 15 | <name>web video platform</name> |
| 16 | 16 | <description>国标28181视频平台</description> |
| 17 | 17 | <packaging>${project.packaging}</packaging> |
| ... | ... | @@ -135,11 +135,30 @@ |
| 135 | 135 | <version>8.0.30</version> |
| 136 | 136 | </dependency> |
| 137 | 137 | |
| 138 | + <!--postgresql--> | |
| 139 | + <dependency> | |
| 140 | + <groupId>org.postgresql</groupId> | |
| 141 | + <artifactId>postgresql</artifactId> | |
| 142 | + <version>42.5.1</version> | |
| 143 | + </dependency> | |
| 144 | + | |
| 145 | + <!-- kingbase人大金仓 --> | |
| 146 | + <!-- 手动下载驱动后安装 --> | |
| 147 | + <!-- mvn install:install-file -Dfile=/home/lin/soft/kingbase/jdbc-aarch/kingbase8-8.6.0.jar -DgroupId=com.kingbase -DartifactId=kingbase8 -Dversion=8.6.0 -Dpackaging=jar | |
| 148 | + --> | |
| 149 | + <dependency> | |
| 150 | + <groupId>com.kingbase</groupId> | |
| 151 | + <artifactId>kingbase8</artifactId> | |
| 152 | + <version>8.6.0</version> | |
| 153 | + <scope>system</scope> | |
| 154 | + <systemPath>${basedir}/libs/jdbc-aarch/kingbase8-8.6.0.jar</systemPath> | |
| 155 | + </dependency> | |
| 156 | + | |
| 138 | 157 | <!--Mybatis分页插件 --> |
| 139 | 158 | <dependency> |
| 140 | 159 | <groupId>com.github.pagehelper</groupId> |
| 141 | 160 | <artifactId>pagehelper-spring-boot-starter</artifactId> |
| 142 | - <version>1.4.3</version> | |
| 161 | + <version>1.4.6</version> | |
| 143 | 162 | </dependency> |
| 144 | 163 | |
| 145 | 164 | <!--在线文档 --> | ... | ... |
sql/2.6.6-2.6.7更新.sql
| ... | ... | @@ -7,6 +7,7 @@ alter table parent_platform |
| 7 | 7 | alter table device |
| 8 | 8 | add mediaServerId varchar(50) default null; |
| 9 | 9 | |
| 10 | - | |
| 10 | +ALTER TABLE device | |
| 11 | + ADD COLUMN `switchPrimarySubStream` bit(1) NOT NULL DEFAULT b'0' COMMENT '开启主子码流切换的开关(0-不开启,1-开启)现在已知支持设备为 大华、TP——LINK全系设备' AFTER `keepalive_interval_time` | |
| 11 | 12 | |
| 12 | 13 | ... | ... |
sql/2.6.8升级2.6.9.sql
0 → 100644
| 1 | +alter table device | |
| 2 | + change deviceId device_id varchar(50) not null; | |
| 3 | + | |
| 4 | +alter table device | |
| 5 | + change streamMode stream_mode varchar(50) null; | |
| 6 | + | |
| 7 | +alter table device | |
| 8 | + change registerTime register_time varchar(50) null; | |
| 9 | + | |
| 10 | +alter table device | |
| 11 | + change keepaliveTime keepalive_time varchar(50) null; | |
| 12 | + | |
| 13 | +alter table device | |
| 14 | + change createTime create_time varchar(50) not null; | |
| 15 | + | |
| 16 | +alter table device | |
| 17 | + change updateTime update_time varchar(50) not null; | |
| 18 | + | |
| 19 | +alter table device | |
| 20 | + change subscribeCycleForCatalog subscribe_cycle_for_catalog bool default false; | |
| 21 | + | |
| 22 | +alter table device | |
| 23 | + change subscribeCycleForMobilePosition subscribe_cycle_for_mobile_position bool default false; | |
| 24 | + | |
| 25 | +alter table device | |
| 26 | + change mobilePositionSubmissionInterval mobile_position_submission_interval int default 5 not null; | |
| 27 | + | |
| 28 | +alter table device | |
| 29 | + change subscribeCycleForAlarm subscribe_cycle_for_alarm bool default false; | |
| 30 | + | |
| 31 | +alter table device | |
| 32 | + change hostAddress host_address varchar(50) null; | |
| 33 | + | |
| 34 | +alter table device | |
| 35 | + change ssrcCheck ssrc_check bool default false; | |
| 36 | + | |
| 37 | +alter table device | |
| 38 | + change geoCoordSys geo_coord_sys varchar(50) not null; | |
| 39 | + | |
| 40 | +alter table device | |
| 41 | + drop column treeType; | |
| 42 | + | |
| 43 | +alter table device | |
| 44 | + change mediaServerId media_server_id varchar(50) default 'auto' null; | |
| 45 | + | |
| 46 | +alter table device | |
| 47 | + change sdpIp sdp_ip varchar(50) null; | |
| 48 | + | |
| 49 | +alter table device | |
| 50 | + change localIp local_ip varchar(50) null; | |
| 51 | + | |
| 52 | +alter table device | |
| 53 | + change asMessageChannel as_message_channel bool default false; | |
| 54 | + | |
| 55 | +alter table device | |
| 56 | + change keepaliveIntervalTime keepalive_interval_time int null; | |
| 57 | + | |
| 58 | +alter table device | |
| 59 | + change online on_line varchar(50) null; | |
| 60 | + | |
| 61 | +alter table device | |
| 62 | + add COLUMN switch_primary_sub_stream bool default false comment '开启主子码流切换的开关(0-不开启,1-开启)现在已知支持设备为 大华、TP——LINK全系设备' | |
| 63 | + | |
| 64 | + | |
| 65 | +alter table device_alarm | |
| 66 | + change deviceId device_id varchar(50) not null; | |
| 67 | + | |
| 68 | +alter table device_alarm | |
| 69 | + change channelId channel_id varchar(50) not null; | |
| 70 | + | |
| 71 | +alter table device_alarm | |
| 72 | + change alarmPriority alarm_priority varchar(50) not null; | |
| 73 | + | |
| 74 | +alter table device_alarm | |
| 75 | + change alarmMethod alarm_method varchar(50) null; | |
| 76 | + | |
| 77 | +alter table device_alarm | |
| 78 | + change alarmTime alarm_time varchar(50) not null; | |
| 79 | + | |
| 80 | +alter table device_alarm | |
| 81 | + change alarmDescription alarm_description varchar(255) null; | |
| 82 | + | |
| 83 | +alter table device_alarm | |
| 84 | + change alarmType alarm_type varchar(50) null; | |
| 85 | + | |
| 86 | +alter table device_alarm | |
| 87 | + change createTime create_time varchar(50) null; | |
| 88 | + | |
| 89 | +alter table device_channel | |
| 90 | + change channelId channel_id varchar(50) not null; | |
| 91 | + | |
| 92 | +alter table device_channel | |
| 93 | + change civilCode civil_code varchar(50) null; | |
| 94 | + | |
| 95 | +alter table device_channel | |
| 96 | + change parentId parent_id varchar(50) null; | |
| 97 | + | |
| 98 | +alter table device_channel | |
| 99 | + change safetyWay safety_way int null; | |
| 100 | + | |
| 101 | +alter table device_channel | |
| 102 | + change registerWay register_way int null; | |
| 103 | + | |
| 104 | +alter table device_channel | |
| 105 | + change certNum cert_num varchar(50) null; | |
| 106 | + | |
| 107 | +alter table device_channel | |
| 108 | + change errCode err_code int null; | |
| 109 | + | |
| 110 | +alter table device_channel | |
| 111 | + change endTime end_time varchar(50) null; | |
| 112 | + | |
| 113 | +alter table device_channel | |
| 114 | + change ipAddress ip_address varchar(50) null; | |
| 115 | + | |
| 116 | +alter table device_channel | |
| 117 | + change PTZType ptz_type int null; | |
| 118 | + | |
| 119 | +alter table device_channel | |
| 120 | + change status status bool default false; | |
| 121 | + | |
| 122 | +alter table device_channel | |
| 123 | + change streamId stream_id varchar(50) null; | |
| 124 | + | |
| 125 | +alter table device_channel | |
| 126 | + change deviceId device_id varchar(50) not null; | |
| 127 | + | |
| 128 | + | |
| 129 | +alter table device_channel | |
| 130 | + change hasAudio has_audio bool default false; | |
| 131 | + | |
| 132 | +alter table device_channel | |
| 133 | + change createTime create_time varchar(50) not null; | |
| 134 | + | |
| 135 | +alter table device_channel | |
| 136 | + change updateTime update_time varchar(50) not null; | |
| 137 | + | |
| 138 | +alter table device_channel | |
| 139 | + change subCount sub_count int default 0 null; | |
| 140 | + | |
| 141 | +alter table device_channel | |
| 142 | + change longitudeGcj02 longitude_gcj02 double null; | |
| 143 | + | |
| 144 | +alter table device_channel | |
| 145 | + change latitudeGcj02 latitude_gcj02 double null; | |
| 146 | + | |
| 147 | +alter table device_channel | |
| 148 | + change longitudeWgs84 longitude_wgs84 double null; | |
| 149 | + | |
| 150 | +alter table device_channel | |
| 151 | + change latitudeWgs84 latitude_wgs84 double null; | |
| 152 | + | |
| 153 | +alter table device_channel | |
| 154 | + change businessGroupId business_group_id varchar(50) null; | |
| 155 | + | |
| 156 | +alter table device_channel | |
| 157 | + change gpsTime gps_time varchar(50) null; | |
| 158 | + | |
| 159 | +alter table device_mobile_position | |
| 160 | + change deviceId device_id varchar(50) not null; | |
| 161 | + | |
| 162 | +alter table device_mobile_position | |
| 163 | + change channelId channel_id varchar(50) not null; | |
| 164 | + | |
| 165 | +alter table device_mobile_position | |
| 166 | + change deviceName device_name varchar(255) null; | |
| 167 | + | |
| 168 | +alter table device_mobile_position | |
| 169 | + change reportSource report_source varchar(50) null; | |
| 170 | + | |
| 171 | +alter table device_mobile_position | |
| 172 | + change longitudeGcj02 longitude_gcj02 double null; | |
| 173 | + | |
| 174 | +alter table device_mobile_position | |
| 175 | + change latitudeGcj02 latitude_gcj02 double null; | |
| 176 | + | |
| 177 | +alter table device_mobile_position | |
| 178 | + change longitudeWgs84 longitude_wgs84 double null; | |
| 179 | + | |
| 180 | +alter table device_mobile_position | |
| 181 | + change latitudeWgs84 latitude_wgs84 double null; | |
| 182 | + | |
| 183 | +alter table device_mobile_position | |
| 184 | + change createTime create_time varchar(50) null; | |
| 185 | + | |
| 186 | +alter table gb_stream | |
| 187 | + change gbStreamId gb_stream_id int auto_increment; | |
| 188 | + | |
| 189 | +alter table gb_stream | |
| 190 | + change gbId gb_id varchar(50) not null; | |
| 191 | + | |
| 192 | +alter table gb_stream | |
| 193 | + change streamType stream_type varchar(50) null; | |
| 194 | + | |
| 195 | +alter table gb_stream | |
| 196 | + change mediaServerId media_server_id varchar(50) null; | |
| 197 | + | |
| 198 | +alter table gb_stream | |
| 199 | + change createTime create_time varchar(50) null; | |
| 200 | + | |
| 201 | +alter table log | |
| 202 | + change createTime create_time varchar(50) not null; | |
| 203 | + | |
| 204 | +alter table media_server | |
| 205 | + change hookIp hook_ip varchar(50) not null; | |
| 206 | + | |
| 207 | +alter table media_server | |
| 208 | + change sdpIp sdp_ip varchar(50) not null; | |
| 209 | + | |
| 210 | +alter table media_server | |
| 211 | + change streamIp stream_ip varchar(50) not null; | |
| 212 | + | |
| 213 | +alter table media_server | |
| 214 | + change httpPort http_port int not null; | |
| 215 | + | |
| 216 | +alter table media_server | |
| 217 | + change httpSSlPort http_ssl_port int not null; | |
| 218 | + | |
| 219 | +alter table media_server | |
| 220 | + change rtmpPort rtmp_port int not null; | |
| 221 | + | |
| 222 | +alter table media_server | |
| 223 | + change rtmpSSlPort rtmp_ssl_port int not null; | |
| 224 | + | |
| 225 | +alter table media_server | |
| 226 | + change rtpProxyPort rtp_proxy_port int not null; | |
| 227 | + | |
| 228 | +alter table media_server | |
| 229 | + change rtspPort rtsp_port int not null; | |
| 230 | + | |
| 231 | +alter table media_server | |
| 232 | + change rtspSSLPort rtsp_ssl_port int not null; | |
| 233 | + | |
| 234 | +alter table media_server | |
| 235 | + change autoConfig auto_config bool default true; | |
| 236 | + | |
| 237 | +alter table media_server | |
| 238 | + change rtpEnable rtp_enable bool default false; | |
| 239 | + | |
| 240 | +alter table media_server | |
| 241 | + change rtpPortRange rtp_port_range varchar(50) not null; | |
| 242 | + | |
| 243 | +alter table media_server | |
| 244 | + change recordAssistPort record_assist_port int not null; | |
| 245 | + | |
| 246 | +alter table media_server | |
| 247 | + change defaultServer default_server bool default false; | |
| 248 | + | |
| 249 | +alter table media_server | |
| 250 | + change createTime create_time varchar(50) not null; | |
| 251 | + | |
| 252 | +alter table media_server | |
| 253 | + change updateTime update_time varchar(50) not null; | |
| 254 | + | |
| 255 | +alter table media_server | |
| 256 | + change hookAliveInterval hook_alive_interval int not null; | |
| 257 | + | |
| 258 | +alter table parent_platform | |
| 259 | + change serverGBId server_gb_id varchar(50) not null; | |
| 260 | + | |
| 261 | +alter table parent_platform | |
| 262 | + change serverGBDomain server_gb_domain varchar(50) null; | |
| 263 | + | |
| 264 | +alter table parent_platform | |
| 265 | + change serverIP server_ip varchar(50) null; | |
| 266 | + | |
| 267 | +alter table parent_platform | |
| 268 | + change serverPort server_port int null; | |
| 269 | + | |
| 270 | +alter table parent_platform | |
| 271 | + change deviceGBId device_gb_id varchar(50) not null; | |
| 272 | + | |
| 273 | +alter table parent_platform | |
| 274 | + change deviceIp device_ip varchar(50) null; | |
| 275 | + | |
| 276 | +alter table parent_platform | |
| 277 | + change devicePort device_port varchar(50) null; | |
| 278 | + | |
| 279 | +alter table parent_platform | |
| 280 | + change keepTimeout keep_timeout varchar(50) null; | |
| 281 | + | |
| 282 | +alter table parent_platform | |
| 283 | + change characterSet character_set varchar(50) null; | |
| 284 | + | |
| 285 | +alter table parent_platform | |
| 286 | + change catalogId catalog_id varchar(50) not null; | |
| 287 | + | |
| 288 | +alter table parent_platform | |
| 289 | + change startOfflinePush start_offline_push bool default false; | |
| 290 | + | |
| 291 | +alter table parent_platform | |
| 292 | + change administrativeDivision administrative_division varchar(50) not null; | |
| 293 | + | |
| 294 | +alter table parent_platform | |
| 295 | + change catalogGroup catalog_group int default 1 null; | |
| 296 | + | |
| 297 | +alter table parent_platform | |
| 298 | + change createTime create_time varchar(50) null; | |
| 299 | + | |
| 300 | +alter table parent_platform | |
| 301 | + change updateTime update_time varchar(50) null; | |
| 302 | + | |
| 303 | +alter table parent_platform | |
| 304 | + drop column treeType; | |
| 305 | + | |
| 306 | +alter table parent_platform | |
| 307 | + change asMessageChannel as_message_channel bool default false; | |
| 308 | + | |
| 309 | +alter table parent_platform | |
| 310 | + change enable enable bool default false; | |
| 311 | + | |
| 312 | +alter table parent_platform | |
| 313 | + change ptz ptz bool default false; | |
| 314 | + | |
| 315 | +alter table parent_platform | |
| 316 | + change rtcp rtcp bool default false; | |
| 317 | + | |
| 318 | +alter table parent_platform | |
| 319 | + change status status bool default false; | |
| 320 | + | |
| 321 | +alter table parent_platform | |
| 322 | + change status status bool default false; | |
| 323 | + | |
| 324 | +alter table platform_catalog | |
| 325 | + change platformId platform_id varchar(50) not null; | |
| 326 | + | |
| 327 | +alter table platform_catalog | |
| 328 | + change parentId parent_id varchar(50) null; | |
| 329 | + | |
| 330 | +alter table platform_catalog | |
| 331 | + change civilCode civil_code varchar(50) null; | |
| 332 | + | |
| 333 | +alter table platform_catalog | |
| 334 | + change businessGroupId business_group_id varchar(50) null; | |
| 335 | + | |
| 336 | +alter table platform_gb_channel | |
| 337 | + change platformId platform_id varchar(50) not null; | |
| 338 | + | |
| 339 | +alter table platform_gb_channel | |
| 340 | + change catalogId catalog_id varchar(50) not null; | |
| 341 | + | |
| 342 | +alter table platform_gb_channel | |
| 343 | + change deviceChannelId device_channel_id int not null; | |
| 344 | + | |
| 345 | +alter table platform_gb_stream | |
| 346 | + change platformId platform_id varchar(50) not null; | |
| 347 | + | |
| 348 | +alter table platform_gb_stream | |
| 349 | + change catalogId catalog_id varchar(50) not null; | |
| 350 | + | |
| 351 | +alter table platform_gb_stream | |
| 352 | + change gbStreamId gb_stream_id int not null; | |
| 353 | + | |
| 354 | +alter table stream_proxy | |
| 355 | + change mediaServerId media_server_id varchar(50) null; | |
| 356 | + | |
| 357 | +alter table stream_proxy | |
| 358 | + change createTime create_time varchar(50) not null; | |
| 359 | + | |
| 360 | +alter table stream_proxy | |
| 361 | + change updateTime update_time varchar(50) null; | |
| 362 | + | |
| 363 | +alter table stream_proxy | |
| 364 | + change enable_remove_none_reader enable_remove_none_reader bool default false; | |
| 365 | + | |
| 366 | +alter table stream_proxy | |
| 367 | + change enable_disable_none_reader enable_disable_none_reader bool default false; | |
| 368 | + | |
| 369 | +alter table stream_proxy | |
| 370 | + change enable_audio enable_audio bool default false; | |
| 371 | + | |
| 372 | +alter table stream_proxy | |
| 373 | + change enable_mp4 enable_mp4 bool default false; | |
| 374 | + | |
| 375 | +alter table stream_proxy | |
| 376 | + change enable enable bool default false; | |
| 377 | + | |
| 378 | +alter table stream_push | |
| 379 | + change totalReaderCount total_reader_count varchar(50) null; | |
| 380 | + | |
| 381 | +alter table stream_push | |
| 382 | + change originType origin_type int null; | |
| 383 | + | |
| 384 | +alter table stream_push | |
| 385 | + change originTypeStr origin_type_str varchar(50) null; | |
| 386 | + | |
| 387 | +alter table stream_push | |
| 388 | + change createTime create_time varchar(50) null; | |
| 389 | + | |
| 390 | +alter table stream_push | |
| 391 | + change aliveSecond alive_second int null; | |
| 392 | + | |
| 393 | +alter table stream_push | |
| 394 | + change mediaServerId media_server_id varchar(50) null; | |
| 395 | + | |
| 396 | +alter table stream_push | |
| 397 | + change status status bool default false; | |
| 398 | + | |
| 399 | +alter table stream_push | |
| 400 | + change pushTime push_time varchar(50) null; | |
| 401 | + | |
| 402 | +alter table stream_push | |
| 403 | + change updateTime update_time varchar(50) null; | |
| 404 | + | |
| 405 | +alter table stream_push | |
| 406 | + change pushIng push_ing bool default false; | |
| 407 | + | |
| 408 | +alter table stream_push | |
| 409 | + change status status bool default false; | |
| 410 | + | |
| 411 | +alter table stream_push | |
| 412 | + change self self bool default false; | |
| 413 | + | |
| 414 | +alter table stream_push | |
| 415 | + drop column serverId; | |
| 416 | + | |
| 417 | + | |
| 418 | +alter table user | |
| 419 | + change roleId role_id int not null; | |
| 420 | + | |
| 421 | +alter table user | |
| 422 | + change createTime create_time varchar(50) not null; | |
| 423 | + | |
| 424 | +alter table user | |
| 425 | + change updateTime update_time varchar(50) not null; | |
| 426 | + | |
| 427 | +alter table user | |
| 428 | + change pushKey push_key varchar(50) null; | |
| 429 | + | |
| 430 | +alter table user_role | |
| 431 | + change createTime create_time varchar(50) not null; | |
| 432 | + | |
| 433 | +alter table user_role | |
| 434 | + change updateTime update_time varchar(50) not null; | |
| 435 | + | |
| 436 | +rename table device to wvp_device; | |
| 437 | +rename table device_alarm to wvp_device_alarm; | |
| 438 | +rename table device_channel to wvp_device_channel; | |
| 439 | +rename table device_mobile_position to wvp_device_mobile_position; | |
| 440 | +rename table gb_stream to wvp_gb_stream; | |
| 441 | +rename table log to wvp_log; | |
| 442 | +rename table media_server to wvp_media_server; | |
| 443 | +rename table parent_platform to wvp_platform; | |
| 444 | +rename table platform_catalog to wvp_platform_catalog; | |
| 445 | +rename table platform_gb_channel to wvp_platform_gb_channel; | |
| 446 | +rename table platform_gb_stream to wvp_platform_gb_stream; | |
| 447 | +rename table stream_proxy to wvp_stream_proxy; | |
| 448 | +rename table stream_push to wvp_stream_push; | |
| 449 | +rename table user to wvp_user; | |
| 450 | +rename table user_role to wvp_user_role; | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | ... | ... |
sql/clean.sql
| 1 | -delete from device; | |
| 2 | -delete from device_alarm; | |
| 3 | -delete from device_channel; | |
| 4 | -delete from device_mobile_position; | |
| 5 | -delete from gb_stream; | |
| 6 | -delete from log; | |
| 7 | -delete from media_server; | |
| 8 | -delete from parent_platform; | |
| 9 | -delete from platform_catalog; | |
| 10 | -delete from platform_gb_channel; | |
| 11 | -delete from platform_gb_stream; | |
| 12 | -delete from stream_proxy; | |
| 13 | -delete from stream_push; | |
| 14 | 1 | \ No newline at end of file |
| 2 | +delete from wvp-device; | |
| 3 | +delete from wvp-device_alarm; | |
| 4 | +delete from wvp-device_channel; | |
| 5 | +delete from wvp-device_mobile_position; | |
| 6 | +delete from wvp-gb_stream; | |
| 7 | +delete from wvp-log; | |
| 8 | +delete from wvp-media_server; | |
| 9 | +delete from wvp-parent_platform; | |
| 10 | +delete from wvp-platform_catalog; | |
| 11 | +delete from wvp-platform_gb_channel; | |
| 12 | +delete from wvp-platform_gb_stream; | |
| 13 | +delete from wvp-stream_proxy; | |
| 14 | +delete from wvp-stream_push; | |
| 15 | 15 | \ No newline at end of file | ... | ... |
sql/初始化.sql
| 1 | --- MySQL dump 10.13 Distrib 8.0.31, for Linux (x86_64) | |
| 2 | --- | |
| 3 | --- Host: 127.0.0.1 Database: wvp | |
| 4 | --- ------------------------------------------------------ | |
| 5 | --- Server version 8.0.30 | |
| 1 | +/*建表*/ | |
| 2 | +create table wvp_device ( | |
| 3 | + id serial primary key , | |
| 4 | + device_id character varying(50) not null , | |
| 5 | + name character varying(255), | |
| 6 | + manufacturer character varying(255), | |
| 7 | + model character varying(255), | |
| 8 | + firmware character varying(255), | |
| 9 | + transport character varying(50), | |
| 10 | + stream_mode character varying(50), | |
| 11 | + on_line bool default false, | |
| 12 | + register_time character varying(50), | |
| 13 | + keepalive_time character varying(50), | |
| 14 | + ip character varying(50), | |
| 15 | + create_time character varying(50), | |
| 16 | + update_time character varying(50), | |
| 17 | + port integer, | |
| 18 | + expires integer, | |
| 19 | + subscribe_cycle_for_catalog integer DEFAULT 0, | |
| 20 | + subscribe_cycle_for_mobile_position integer DEFAULT 0, | |
| 21 | + mobile_position_submission_interval integer DEFAULT 5, | |
| 22 | + subscribe_cycle_for_alarm integer DEFAULT 0, | |
| 23 | + host_address character varying(50), | |
| 24 | + charset character varying(50), | |
| 25 | + ssrc_check bool default false, | |
| 26 | + geo_coord_sys character varying(50), | |
| 27 | + media_server_id character varying(50), | |
| 28 | + custom_name character varying(255), | |
| 29 | + sdp_ip character varying(50), | |
| 30 | + local_ip character varying(50), | |
| 31 | + password character varying(255), | |
| 32 | + as_message_channel bool default false, | |
| 33 | + keepalive_interval_time integer, | |
| 34 | + switch_primary_sub_stream bool default false, | |
| 35 | + constraint uk_device_device unique (device_id) | |
| 36 | +); | |
| 37 | + | |
| 38 | +create table wvp_device_alarm ( | |
| 39 | + id serial primary key , | |
| 40 | + device_id character varying(50) not null, | |
| 41 | + channel_id character varying(50) not null, | |
| 42 | + alarm_priority character varying(50), | |
| 43 | + alarm_method character varying(50), | |
| 44 | + alarm_time character varying(50), | |
| 45 | + alarm_description character varying(255), | |
| 46 | + longitude double precision, | |
| 47 | + latitude double precision, | |
| 48 | + alarm_type character varying(50), | |
| 49 | + create_time character varying(50) not null | |
| 50 | +); | |
| 51 | + | |
| 52 | +create table wvp_device_channel ( | |
| 53 | + id serial primary key , | |
| 54 | + channel_id character varying(50) not null, | |
| 55 | + name character varying(255), | |
| 56 | + manufacture character varying(50), | |
| 57 | + model character varying(50), | |
| 58 | + owner character varying(50), | |
| 59 | + civil_code character varying(50), | |
| 60 | + block character varying(50), | |
| 61 | + address character varying(50), | |
| 62 | + parent_id character varying(50), | |
| 63 | + safety_way integer, | |
| 64 | + register_way integer, | |
| 65 | + cert_num character varying(50), | |
| 66 | + certifiable integer, | |
| 67 | + err_code integer, | |
| 68 | + end_time character varying(50), | |
| 69 | + secrecy character varying(50), | |
| 70 | + ip_address character varying(50), | |
| 71 | + port integer, | |
| 72 | + password character varying(255), | |
| 73 | + ptz_type integer, | |
| 74 | + status bool default false, | |
| 75 | + longitude double precision, | |
| 76 | + latitude double precision, | |
| 77 | + stream_id character varying(50), | |
| 78 | + device_id character varying(50) not null, | |
| 79 | + parental character varying(50), | |
| 80 | + has_audio bool default false, | |
| 81 | + create_time character varying(50) not null, | |
| 82 | + update_time character varying(50) not null, | |
| 83 | + sub_count integer, | |
| 84 | + longitude_gcj02 double precision, | |
| 85 | + latitude_gcj02 double precision, | |
| 86 | + longitude_wgs84 double precision, | |
| 87 | + latitude_wgs84 double precision, | |
| 88 | + business_group_id character varying(50), | |
| 89 | + gps_time character varying(50), | |
| 90 | + constraint uk_wvp_device_channel_unique_device_channel unique (device_id, channel_id) | |
| 91 | +); | |
| 92 | + | |
| 93 | +create table wvp_device_mobile_position ( | |
| 94 | + id serial primary key, | |
| 95 | + device_id character varying(50) not null, | |
| 96 | + channel_id character varying(50) not null, | |
| 97 | + device_name character varying(255), | |
| 98 | + time character varying(50), | |
| 99 | + longitude double precision, | |
| 100 | + latitude double precision, | |
| 101 | + altitude double precision, | |
| 102 | + speed double precision, | |
| 103 | + direction double precision, | |
| 104 | + report_source character varying(50), | |
| 105 | + longitude_gcj02 double precision, | |
| 106 | + latitude_gcj02 double precision, | |
| 107 | + longitude_wgs84 double precision, | |
| 108 | + latitude_wgs84 double precision, | |
| 109 | + create_time character varying(50) | |
| 110 | +); | |
| 111 | + | |
| 112 | +create table wvp_gb_stream ( | |
| 113 | + gb_stream_id serial primary key, | |
| 114 | + app character varying(255) not null, | |
| 115 | + stream character varying(255) not null, | |
| 116 | + gb_id character varying(50) not null, | |
| 117 | + name character varying(255), | |
| 118 | + longitude double precision, | |
| 119 | + latitude double precision, | |
| 120 | + stream_type character varying(50), | |
| 121 | + media_server_id character varying(50), | |
| 122 | + create_time character varying(50), | |
| 123 | + constraint uk_gb_stream_unique_gb_id unique (gb_id), | |
| 124 | + constraint uk_gb_stream_unique_app_stream unique (app, stream) | |
| 125 | +); | |
| 126 | + | |
| 127 | +create table wvp_log ( | |
| 128 | + id serial primary key , | |
| 129 | + name character varying(50), | |
| 130 | + type character varying(50), | |
| 131 | + uri character varying(200), | |
| 132 | + address character varying(50), | |
| 133 | + result character varying(50), | |
| 134 | + timing bigint, | |
| 135 | + username character varying(50), | |
| 136 | + create_time character varying(50) | |
| 137 | +); | |
| 138 | + | |
| 139 | +create table wvp_media_server ( | |
| 140 | + id character varying(255) primary key , | |
| 141 | + ip character varying(50), | |
| 142 | + hook_ip character varying(50), | |
| 143 | + sdp_ip character varying(50), | |
| 144 | + stream_ip character varying(50), | |
| 145 | + http_port integer, | |
| 146 | + http_ssl_port integer, | |
| 147 | + rtmp_port integer, | |
| 148 | + rtmp_ssl_port integer, | |
| 149 | + rtp_proxy_port integer, | |
| 150 | + rtsp_port integer, | |
| 151 | + rtsp_ssl_port integer, | |
| 152 | + auto_config bool default false, | |
| 153 | + secret character varying(50), | |
| 154 | + rtp_enable bool default false, | |
| 155 | + rtp_port_range character varying(50), | |
| 156 | + record_assist_port integer, | |
| 157 | + default_server bool default false, | |
| 158 | + create_time character varying(50), | |
| 159 | + update_time character varying(50), | |
| 160 | + hook_alive_interval integer, | |
| 161 | + constraint uk_media_server_unique_ip_http_port unique (ip, http_port) | |
| 162 | +); | |
| 163 | + | |
| 164 | +create table wvp_platform ( | |
| 165 | + id serial primary key , | |
| 166 | + enable bool default false, | |
| 167 | + name character varying(255), | |
| 168 | + server_gb_id character varying(50), | |
| 169 | + server_gb_domain character varying(50), | |
| 170 | + server_ip character varying(50), | |
| 171 | + server_port integer, | |
| 172 | + device_gb_id character varying(50), | |
| 173 | + device_ip character varying(50), | |
| 174 | + device_port character varying(50), | |
| 175 | + username character varying(255), | |
| 176 | + password character varying(50), | |
| 177 | + expires character varying(50), | |
| 178 | + keep_timeout character varying(50), | |
| 179 | + transport character varying(50), | |
| 180 | + character_set character varying(50), | |
| 181 | + catalog_id character varying(50), | |
| 182 | + ptz bool default false, | |
| 183 | + rtcp bool default false, | |
| 184 | + status bool default false, | |
| 185 | + start_offline_push bool default false, | |
| 186 | + administrative_division character varying(50), | |
| 187 | + catalog_group integer, | |
| 188 | + create_time character varying(50), | |
| 189 | + update_time character varying(50), | |
| 190 | + as_message_channel bool default false, | |
| 191 | + constraint uk_platform_unique_server_gb_id unique (server_gb_id) | |
| 192 | +); | |
| 193 | + | |
| 194 | +create table wvp_platform_catalog ( | |
| 195 | + id character varying(50), | |
| 196 | + platform_id character varying(50), | |
| 197 | + name character varying(255), | |
| 198 | + parent_id character varying(50), | |
| 199 | + civil_code character varying(50), | |
| 200 | + business_group_id character varying(50), | |
| 201 | + constraint uk_platform_catalog_id_platform_id unique (id, platform_id) | |
| 202 | +); | |
| 203 | + | |
| 204 | +create table wvp_platform_gb_channel ( | |
| 205 | + id serial primary key , | |
| 206 | + platform_id character varying(50), | |
| 207 | + catalog_id character varying(50), | |
| 208 | + device_channel_id integer, | |
| 209 | + constraint uk_platform_gb_channel_platform_id_catalog_id_device_channel_id unique (platform_id, catalog_id, device_channel_id) | |
| 210 | +); | |
| 211 | + | |
| 212 | +create table wvp_platform_gb_stream ( | |
| 213 | + id serial primary key, | |
| 214 | + platform_id character varying(50), | |
| 215 | + catalog_id character varying(50), | |
| 216 | + gb_stream_id integer, | |
| 217 | + constraint uk_platform_gb_stream_platform_id_catalog_id_gb_stream_id unique (platform_id, catalog_id, gb_stream_id) | |
| 218 | +); | |
| 219 | + | |
| 220 | +create table wvp_stream_proxy ( | |
| 221 | + id serial primary key, | |
| 222 | + type character varying(50), | |
| 223 | + app character varying(255), | |
| 224 | + stream character varying(255), | |
| 225 | + url character varying(255), | |
| 226 | + src_url character varying(255), | |
| 227 | + dst_url character varying(255), | |
| 228 | + timeout_ms integer, | |
| 229 | + ffmpeg_cmd_key character varying(255), | |
| 230 | + rtp_type character varying(50), | |
| 231 | + media_server_id character varying(50), | |
| 232 | + enable_audio bool default false, | |
| 233 | + enable_mp4 bool default false, | |
| 234 | + enable bool default false, | |
| 235 | + status boolean, | |
| 236 | + enable_remove_none_reader bool default false, | |
| 237 | + create_time character varying(50), | |
| 238 | + name character varying(255), | |
| 239 | + update_time character varying(50), | |
| 240 | + enable_disable_none_reader bool default false, | |
| 241 | + constraint uk_stream_proxy_app_stream unique (app, stream) | |
| 242 | +); | |
| 243 | + | |
| 244 | +create table wvp_stream_push ( | |
| 245 | + id serial primary key, | |
| 246 | + app character varying(255), | |
| 247 | + stream character varying(255), | |
| 248 | + total_reader_count character varying(50), | |
| 249 | + origin_type integer, | |
| 250 | + origin_type_str character varying(50), | |
| 251 | + create_time character varying(50), | |
| 252 | + alive_second integer, | |
| 253 | + media_server_id character varying(50), | |
| 254 | + push_time character varying(50), | |
| 255 | + status bool default false, | |
| 256 | + update_time character varying(50), | |
| 257 | + push_ing bool default false, | |
| 258 | + self bool default false, | |
| 259 | + constraint uk_stream_push_app_stream unique (app, stream) | |
| 260 | +); | |
| 261 | + | |
| 262 | +create table wvp_user ( | |
| 263 | + id serial primary key, | |
| 264 | + username character varying(255), | |
| 265 | + password character varying(255), | |
| 266 | + role_id integer, | |
| 267 | + create_time character varying(50), | |
| 268 | + update_time character varying(50), | |
| 269 | + push_key character varying(50), | |
| 270 | + constraint uk_user_username unique (username) | |
| 271 | +); | |
| 272 | + | |
| 273 | +create table wvp_user_role ( | |
| 274 | + id serial primary key, | |
| 275 | + name character varying(50), | |
| 276 | + authority character varying(50), | |
| 277 | + create_time character varying(50), | |
| 278 | + update_time character varying(50) | |
| 279 | +); | |
| 280 | + | |
| 281 | +/*初始数据*/ | |
| 282 | +INSERT INTO wvp_user VALUES (1, 'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021-04-13 14:14:57','2021-04-13 14:14:57','3e80d1762a324d5b0ff636e0bd16f1e3'); | |
| 283 | +INSERT INTO wvp_user_role VALUES (1, 'admin','0','2021-04-13 14:14:57','2021-04-13 14:14:57'); | |
| 6 | 284 | |
| 7 | -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; | |
| 8 | -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; | |
| 9 | -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; | |
| 10 | -/*!50503 SET NAMES utf8mb4 */; | |
| 11 | -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; | |
| 12 | -/*!40103 SET TIME_ZONE='+00:00' */; | |
| 13 | -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; | |
| 14 | -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; | |
| 15 | -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; | |
| 16 | -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; | |
| 17 | 285 | |
| 18 | --- | |
| 19 | --- Table structure for table `device` | |
| 20 | --- | |
| 21 | 286 | |
| 22 | -DROP TABLE IF EXISTS `device`; | |
| 23 | -/*!40101 SET @saved_cs_client = @@character_set_client */; | |
| 24 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 25 | -CREATE TABLE `device` ( | |
| 26 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 27 | - `deviceId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 28 | - `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 29 | - `manufacturer` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 30 | - `model` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 31 | - `firmware` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 32 | - `transport` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 33 | - `streamMode` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 34 | - `online` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 35 | - `mediaServerId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 36 | - `registerTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 37 | - `keepaliveTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 38 | - `ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 39 | - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 40 | - `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 41 | - `port` int DEFAULT NULL, | |
| 42 | - `expires` int DEFAULT NULL, | |
| 43 | - `keepaliveIntervalTime` int DEFAULT NULL, | |
| 44 | - `subscribeCycleForCatalog` int DEFAULT NULL, | |
| 45 | - `hostAddress` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 46 | - `charset` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 47 | - `subscribeCycleForMobilePosition` int DEFAULT NULL, | |
| 48 | - `mobilePositionSubmissionInterval` int DEFAULT '5', | |
| 49 | - `subscribeCycleForAlarm` int DEFAULT NULL, | |
| 50 | - `ssrcCheck` int DEFAULT '0', | |
| 51 | - `asMessageChannel` int DEFAULT '0', | |
| 52 | - `geoCoordSys` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 53 | - `treeType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 54 | - `custom_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 55 | - `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 56 | - `sdpIp` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 57 | - `localIp` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 58 | - PRIMARY KEY (`id`), | |
| 59 | - UNIQUE KEY `device_deviceId_uindex` (`deviceId`) | |
| 60 | -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; | |
| 61 | -/*!40101 SET character_set_client = @saved_cs_client */; | |
| 62 | - | |
| 63 | --- | |
| 64 | --- Dumping data for table `device` | |
| 65 | --- | |
| 66 | - | |
| 67 | -LOCK TABLES `device` WRITE; | |
| 68 | -/*!40000 ALTER TABLE `device` DISABLE KEYS */; | |
| 69 | -/*!40000 ALTER TABLE `device` ENABLE KEYS */; | |
| 70 | -UNLOCK TABLES; | |
| 71 | - | |
| 72 | --- | |
| 73 | --- Table structure for table `device_alarm` | |
| 74 | --- | |
| 75 | - | |
| 76 | -DROP TABLE IF EXISTS `device_alarm`; | |
| 77 | -/*!40101 SET @saved_cs_client = @@character_set_client */; | |
| 78 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 79 | -CREATE TABLE `device_alarm` ( | |
| 80 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 81 | - `deviceId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 82 | - `channelId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 83 | - `alarmPriority` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 84 | - `alarmMethod` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 85 | - `alarmTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 86 | - `alarmDescription` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 87 | - `longitude` double DEFAULT NULL, | |
| 88 | - `latitude` double DEFAULT NULL, | |
| 89 | - `alarmType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 90 | - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 91 | - PRIMARY KEY (`id`) USING BTREE | |
| 92 | -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; | |
| 93 | -/*!40101 SET character_set_client = @saved_cs_client */; | |
| 94 | - | |
| 95 | --- | |
| 96 | --- Dumping data for table `device_alarm` | |
| 97 | --- | |
| 98 | - | |
| 99 | -LOCK TABLES `device_alarm` WRITE; | |
| 100 | -/*!40000 ALTER TABLE `device_alarm` DISABLE KEYS */; | |
| 101 | -/*!40000 ALTER TABLE `device_alarm` ENABLE KEYS */; | |
| 102 | -UNLOCK TABLES; | |
| 103 | - | |
| 104 | --- | |
| 105 | --- Table structure for table `device_channel` | |
| 106 | --- | |
| 107 | - | |
| 108 | -DROP TABLE IF EXISTS `device_channel`; | |
| 109 | -/*!40101 SET @saved_cs_client = @@character_set_client */; | |
| 110 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 111 | -CREATE TABLE `device_channel` ( | |
| 112 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 113 | - `channelId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 114 | - `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 115 | - `manufacture` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 116 | - `model` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 117 | - `owner` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 118 | - `civilCode` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 119 | - `block` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 120 | - `address` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 121 | - `parentId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 122 | - `safetyWay` int DEFAULT NULL, | |
| 123 | - `registerWay` int DEFAULT NULL, | |
| 124 | - `certNum` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 125 | - `certifiable` int DEFAULT NULL, | |
| 126 | - `errCode` int DEFAULT NULL, | |
| 127 | - `endTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 128 | - `secrecy` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 129 | - `ipAddress` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 130 | - `port` int DEFAULT NULL, | |
| 131 | - `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 132 | - `PTZType` int DEFAULT NULL, | |
| 133 | - `status` int DEFAULT NULL, | |
| 134 | - `longitude` double DEFAULT NULL, | |
| 135 | - `latitude` double DEFAULT NULL, | |
| 136 | - `streamId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 137 | - `deviceId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 138 | - `parental` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 139 | - `hasAudio` bit(1) DEFAULT NULL, | |
| 140 | - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 141 | - `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 142 | - `subCount` int DEFAULT '0', | |
| 143 | - `longitudeGcj02` double DEFAULT NULL, | |
| 144 | - `latitudeGcj02` double DEFAULT NULL, | |
| 145 | - `longitudeWgs84` double DEFAULT NULL, | |
| 146 | - `latitudeWgs84` double DEFAULT NULL, | |
| 147 | - `businessGroupId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 148 | - `gpsTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 149 | - PRIMARY KEY (`id`), | |
| 150 | - UNIQUE KEY `device_channel_id_uindex` (`id`), | |
| 151 | - UNIQUE KEY `device_channel_pk` (`channelId`,`deviceId`) | |
| 152 | -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; | |
| 153 | -/*!40101 SET character_set_client = @saved_cs_client */; | |
| 154 | - | |
| 155 | --- | |
| 156 | --- Dumping data for table `device_channel` | |
| 157 | --- | |
| 158 | - | |
| 159 | -LOCK TABLES `device_channel` WRITE; | |
| 160 | -/*!40000 ALTER TABLE `device_channel` DISABLE KEYS */; | |
| 161 | -/*!40000 ALTER TABLE `device_channel` ENABLE KEYS */; | |
| 162 | -UNLOCK TABLES; | |
| 163 | - | |
| 164 | --- | |
| 165 | --- Table structure for table `device_mobile_position` | |
| 166 | --- | |
| 167 | - | |
| 168 | -DROP TABLE IF EXISTS `device_mobile_position`; | |
| 169 | -/*!40101 SET @saved_cs_client = @@character_set_client */; | |
| 170 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 171 | -CREATE TABLE `device_mobile_position` ( | |
| 172 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 173 | - `deviceId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 174 | - `channelId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 175 | - `deviceName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 176 | - `time` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 177 | - `longitude` double NOT NULL, | |
| 178 | - `latitude` double NOT NULL, | |
| 179 | - `altitude` double DEFAULT NULL, | |
| 180 | - `speed` double DEFAULT NULL, | |
| 181 | - `direction` double DEFAULT NULL, | |
| 182 | - `reportSource` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 183 | - `longitudeGcj02` double DEFAULT NULL, | |
| 184 | - `latitudeGcj02` double DEFAULT NULL, | |
| 185 | - `longitudeWgs84` double DEFAULT NULL, | |
| 186 | - `latitudeWgs84` double DEFAULT NULL, | |
| 187 | - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 188 | - PRIMARY KEY (`id`) | |
| 189 | -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; | |
| 190 | -/*!40101 SET character_set_client = @saved_cs_client */; | |
| 191 | - | |
| 192 | --- | |
| 193 | --- Dumping data for table `device_mobile_position` | |
| 194 | --- | |
| 195 | - | |
| 196 | -LOCK TABLES `device_mobile_position` WRITE; | |
| 197 | -/*!40000 ALTER TABLE `device_mobile_position` DISABLE KEYS */; | |
| 198 | -/*!40000 ALTER TABLE `device_mobile_position` ENABLE KEYS */; | |
| 199 | -UNLOCK TABLES; | |
| 200 | - | |
| 201 | --- | |
| 202 | --- Table structure for table `gb_stream` | |
| 203 | --- | |
| 204 | - | |
| 205 | -DROP TABLE IF EXISTS `gb_stream`; | |
| 206 | -/*!40101 SET @saved_cs_client = @@character_set_client */; | |
| 207 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 208 | -CREATE TABLE `gb_stream` ( | |
| 209 | - `gbStreamId` int NOT NULL AUTO_INCREMENT, | |
| 210 | - `app` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 211 | - `stream` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 212 | - `gbId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 213 | - `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 214 | - `longitude` double DEFAULT NULL, | |
| 215 | - `latitude` double DEFAULT NULL, | |
| 216 | - `streamType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 217 | - `mediaServerId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 218 | - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 219 | - PRIMARY KEY (`gbStreamId`) USING BTREE, | |
| 220 | - UNIQUE KEY `app` (`app`,`stream`) USING BTREE, | |
| 221 | - UNIQUE KEY `gbId` (`gbId`) USING BTREE | |
| 222 | -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; | |
| 223 | -/*!40101 SET character_set_client = @saved_cs_client */; | |
| 224 | - | |
| 225 | --- | |
| 226 | --- Dumping data for table `gb_stream` | |
| 227 | --- | |
| 228 | - | |
| 229 | -LOCK TABLES `gb_stream` WRITE; | |
| 230 | -/*!40000 ALTER TABLE `gb_stream` DISABLE KEYS */; | |
| 231 | -/*!40000 ALTER TABLE `gb_stream` ENABLE KEYS */; | |
| 232 | -UNLOCK TABLES; | |
| 233 | - | |
| 234 | --- | |
| 235 | --- Table structure for table `log` | |
| 236 | --- | |
| 237 | - | |
| 238 | -DROP TABLE IF EXISTS `log`; | |
| 239 | -/*!40101 SET @saved_cs_client = @@character_set_client */; | |
| 240 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 241 | -CREATE TABLE `log` ( | |
| 242 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 243 | - `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 244 | - `type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 245 | - `uri` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 246 | - `address` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 247 | - `result` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 248 | - `timing` bigint NOT NULL, | |
| 249 | - `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 250 | - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 251 | - PRIMARY KEY (`id`) USING BTREE | |
| 252 | -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; | |
| 253 | -/*!40101 SET character_set_client = @saved_cs_client */; | |
| 254 | - | |
| 255 | --- | |
| 256 | --- Dumping data for table `log` | |
| 257 | --- | |
| 258 | - | |
| 259 | -LOCK TABLES `log` WRITE; | |
| 260 | -/*!40000 ALTER TABLE `log` DISABLE KEYS */; | |
| 261 | -/*!40000 ALTER TABLE `log` ENABLE KEYS */; | |
| 262 | -UNLOCK TABLES; | |
| 263 | - | |
| 264 | --- | |
| 265 | --- Table structure for table `media_server` | |
| 266 | --- | |
| 267 | - | |
| 268 | -DROP TABLE IF EXISTS `media_server`; | |
| 269 | -/*!40101 SET @saved_cs_client = @@character_set_client */; | |
| 270 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 271 | -CREATE TABLE `media_server` ( | |
| 272 | - `id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 273 | - `ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 274 | - `hookIp` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 275 | - `sdpIp` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 276 | - `streamIp` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 277 | - `httpPort` int NOT NULL, | |
| 278 | - `httpSSlPort` int NOT NULL, | |
| 279 | - `rtmpPort` int NOT NULL, | |
| 280 | - `rtmpSSlPort` int NOT NULL, | |
| 281 | - `rtpProxyPort` int NOT NULL, | |
| 282 | - `rtspPort` int NOT NULL, | |
| 283 | - `rtspSSLPort` int NOT NULL, | |
| 284 | - `autoConfig` int NOT NULL, | |
| 285 | - `secret` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 286 | - `rtpEnable` int NOT NULL, | |
| 287 | - `rtpPortRange` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 288 | - `recordAssistPort` int NOT NULL, | |
| 289 | - `defaultServer` int NOT NULL, | |
| 290 | - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 291 | - `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 292 | - `hookAliveInterval` int NOT NULL, | |
| 293 | - PRIMARY KEY (`id`) USING BTREE, | |
| 294 | - UNIQUE KEY `media_server_i` (`ip`,`httpPort`) USING BTREE | |
| 295 | -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; | |
| 296 | -/*!40101 SET character_set_client = @saved_cs_client */; | |
| 297 | - | |
| 298 | --- | |
| 299 | --- Dumping data for table `media_server` | |
| 300 | --- | |
| 301 | - | |
| 302 | -LOCK TABLES `media_server` WRITE; | |
| 303 | -/*!40000 ALTER TABLE `media_server` DISABLE KEYS */; | |
| 304 | -/*!40000 ALTER TABLE `media_server` ENABLE KEYS */; | |
| 305 | -UNLOCK TABLES; | |
| 306 | - | |
| 307 | --- | |
| 308 | --- Table structure for table `parent_platform` | |
| 309 | --- | |
| 310 | - | |
| 311 | -DROP TABLE IF EXISTS `parent_platform`; | |
| 312 | -/*!40101 SET @saved_cs_client = @@character_set_client */; | |
| 313 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 314 | -CREATE TABLE `parent_platform` ( | |
| 315 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 316 | - `enable` int DEFAULT NULL, | |
| 317 | - `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 318 | - `serverGBId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 319 | - `serverGBDomain` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 320 | - `serverIP` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 321 | - `serverPort` int DEFAULT NULL, | |
| 322 | - `deviceGBId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 323 | - `deviceIp` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 324 | - `devicePort` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 325 | - `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 326 | - `password` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 327 | - `expires` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 328 | - `keepTimeout` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 329 | - `transport` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 330 | - `characterSet` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 331 | - `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 332 | - `ptz` int DEFAULT NULL, | |
| 333 | - `rtcp` int DEFAULT NULL, | |
| 334 | - `asMessageChannel` int DEFAULT '0', | |
| 335 | - `status` bit(1) DEFAULT NULL, | |
| 336 | - `startOfflinePush` int DEFAULT '0', | |
| 337 | - `administrativeDivision` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 338 | - `catalogGroup` int DEFAULT '1', | |
| 339 | - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 340 | - `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 341 | - `treeType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 342 | - PRIMARY KEY (`id`), | |
| 343 | - UNIQUE KEY `parent_platform_id_uindex` (`id`), | |
| 344 | - UNIQUE KEY `parent_platform_pk` (`serverGBId`) | |
| 345 | -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; | |
| 346 | -/*!40101 SET character_set_client = @saved_cs_client */; | |
| 347 | - | |
| 348 | --- | |
| 349 | --- Dumping data for table `parent_platform` | |
| 350 | --- | |
| 351 | - | |
| 352 | -LOCK TABLES `parent_platform` WRITE; | |
| 353 | -/*!40000 ALTER TABLE `parent_platform` DISABLE KEYS */; | |
| 354 | -/*!40000 ALTER TABLE `parent_platform` ENABLE KEYS */; | |
| 355 | -UNLOCK TABLES; | |
| 356 | - | |
| 357 | --- | |
| 358 | --- Table structure for table `platform_catalog` | |
| 359 | --- | |
| 360 | - | |
| 361 | -DROP TABLE IF EXISTS `platform_catalog`; | |
| 362 | -/*!40101 SET @saved_cs_client = @@character_set_client */; | |
| 363 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 364 | -CREATE TABLE `platform_catalog` ( | |
| 365 | - `id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 366 | - `platformId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 367 | - `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 368 | - `parentId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 369 | - `civilCode` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 370 | - `businessGroupId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 371 | - PRIMARY KEY (`id`) USING BTREE | |
| 372 | -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; | |
| 373 | -/*!40101 SET character_set_client = @saved_cs_client */; | |
| 374 | - | |
| 375 | --- | |
| 376 | --- Dumping data for table `platform_catalog` | |
| 377 | --- | |
| 378 | - | |
| 379 | -LOCK TABLES `platform_catalog` WRITE; | |
| 380 | -/*!40000 ALTER TABLE `platform_catalog` DISABLE KEYS */; | |
| 381 | -/*!40000 ALTER TABLE `platform_catalog` ENABLE KEYS */; | |
| 382 | -UNLOCK TABLES; | |
| 383 | - | |
| 384 | --- | |
| 385 | --- Table structure for table `platform_gb_channel` | |
| 386 | --- | |
| 387 | - | |
| 388 | -DROP TABLE IF EXISTS `platform_gb_channel`; | |
| 389 | -/*!40101 SET @saved_cs_client = @@character_set_client */; | |
| 390 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 391 | -CREATE TABLE `platform_gb_channel` ( | |
| 392 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 393 | - `platformId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 394 | - `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 395 | - `deviceChannelId` int NOT NULL, | |
| 396 | - PRIMARY KEY (`id`) | |
| 397 | -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; | |
| 398 | -/*!40101 SET character_set_client = @saved_cs_client */; | |
| 399 | - | |
| 400 | --- | |
| 401 | --- Dumping data for table `platform_gb_channel` | |
| 402 | --- | |
| 403 | - | |
| 404 | -LOCK TABLES `platform_gb_channel` WRITE; | |
| 405 | -/*!40000 ALTER TABLE `platform_gb_channel` DISABLE KEYS */; | |
| 406 | -/*!40000 ALTER TABLE `platform_gb_channel` ENABLE KEYS */; | |
| 407 | -UNLOCK TABLES; | |
| 408 | - | |
| 409 | --- | |
| 410 | --- Table structure for table `platform_gb_stream` | |
| 411 | --- | |
| 412 | - | |
| 413 | -DROP TABLE IF EXISTS `platform_gb_stream`; | |
| 414 | -/*!40101 SET @saved_cs_client = @@character_set_client */; | |
| 415 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 416 | -CREATE TABLE `platform_gb_stream` ( | |
| 417 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 418 | - `platformId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 419 | - `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 420 | - `gbStreamId` int NOT NULL, | |
| 421 | - PRIMARY KEY (`id`), | |
| 422 | - UNIQUE KEY `platform_gb_stream_pk` (`platformId`,`catalogId`,`gbStreamId`) | |
| 423 | -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; | |
| 424 | -/*!40101 SET character_set_client = @saved_cs_client */; | |
| 425 | - | |
| 426 | --- | |
| 427 | --- Dumping data for table `platform_gb_stream` | |
| 428 | --- | |
| 429 | - | |
| 430 | -LOCK TABLES `platform_gb_stream` WRITE; | |
| 431 | -/*!40000 ALTER TABLE `platform_gb_stream` DISABLE KEYS */; | |
| 432 | -/*!40000 ALTER TABLE `platform_gb_stream` ENABLE KEYS */; | |
| 433 | -UNLOCK TABLES; | |
| 434 | - | |
| 435 | --- | |
| 436 | --- Table structure for table `stream_proxy` | |
| 437 | --- | |
| 438 | - | |
| 439 | -DROP TABLE IF EXISTS `stream_proxy`; | |
| 440 | -/*!40101 SET @saved_cs_client = @@character_set_client */; | |
| 441 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 442 | -CREATE TABLE `stream_proxy` ( | |
| 443 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 444 | - `type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 445 | - `app` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 446 | - `stream` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 447 | - `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 448 | - `src_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 449 | - `dst_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 450 | - `timeout_ms` int DEFAULT NULL, | |
| 451 | - `ffmpeg_cmd_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 452 | - `rtp_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 453 | - `mediaServerId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 454 | - `enable_audio` bit(1) DEFAULT NULL, | |
| 455 | - `enable_mp4` bit(1) DEFAULT NULL, | |
| 456 | - `enable` bit(1) NOT NULL, | |
| 457 | - `status` bit(1) NOT NULL, | |
| 458 | - `enable_remove_none_reader` bit(1) NOT NULL, | |
| 459 | - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 460 | - `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 461 | - `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 462 | - `enable_disable_none_reader` bit(1) DEFAULT NULL, | |
| 463 | - PRIMARY KEY (`id`), | |
| 464 | - UNIQUE KEY `stream_proxy_pk` (`app`,`stream`) | |
| 465 | -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; | |
| 466 | -/*!40101 SET character_set_client = @saved_cs_client */; | |
| 467 | - | |
| 468 | --- | |
| 469 | --- Dumping data for table `stream_proxy` | |
| 470 | --- | |
| 471 | - | |
| 472 | -LOCK TABLES `stream_proxy` WRITE; | |
| 473 | -/*!40000 ALTER TABLE `stream_proxy` DISABLE KEYS */; | |
| 474 | -/*!40000 ALTER TABLE `stream_proxy` ENABLE KEYS */; | |
| 475 | -UNLOCK TABLES; | |
| 476 | - | |
| 477 | --- | |
| 478 | --- Table structure for table `stream_push` | |
| 479 | --- | |
| 480 | - | |
| 481 | -DROP TABLE IF EXISTS `stream_push`; | |
| 482 | -/*!40101 SET @saved_cs_client = @@character_set_client */; | |
| 483 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 484 | -CREATE TABLE `stream_push` ( | |
| 485 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 486 | - `app` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 487 | - `stream` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 488 | - `totalReaderCount` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 489 | - `originType` int DEFAULT NULL, | |
| 490 | - `originTypeStr` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 491 | - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 492 | - `aliveSecond` int DEFAULT NULL, | |
| 493 | - `mediaServerId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 494 | - `serverId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 495 | - `pushTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 496 | - `status` int DEFAULT NULL, | |
| 497 | - `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 498 | - `pushIng` int DEFAULT NULL, | |
| 499 | - `self` int DEFAULT NULL, | |
| 500 | - PRIMARY KEY (`id`), | |
| 501 | - UNIQUE KEY `stream_push_pk` (`app`,`stream`) | |
| 502 | -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; | |
| 503 | -/*!40101 SET character_set_client = @saved_cs_client */; | |
| 504 | - | |
| 505 | --- | |
| 506 | --- Dumping data for table `stream_push` | |
| 507 | --- | |
| 508 | - | |
| 509 | -LOCK TABLES `stream_push` WRITE; | |
| 510 | -/*!40000 ALTER TABLE `stream_push` DISABLE KEYS */; | |
| 511 | -/*!40000 ALTER TABLE `stream_push` ENABLE KEYS */; | |
| 512 | -UNLOCK TABLES; | |
| 513 | - | |
| 514 | --- | |
| 515 | --- Table structure for table `user` | |
| 516 | --- | |
| 517 | - | |
| 518 | -DROP TABLE IF EXISTS `user`; | |
| 519 | -/*!40101 SET @saved_cs_client = @@character_set_client */; | |
| 520 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 521 | -CREATE TABLE `user` ( | |
| 522 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 523 | - `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 524 | - `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 525 | - `roleId` int NOT NULL, | |
| 526 | - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 527 | - `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 528 | - `pushKey` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, | |
| 529 | - PRIMARY KEY (`id`) USING BTREE, | |
| 530 | - UNIQUE KEY `user_username_uindex` (`username`) USING BTREE | |
| 531 | -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; | |
| 532 | -/*!40101 SET character_set_client = @saved_cs_client */; | |
| 533 | - | |
| 534 | --- | |
| 535 | --- Dumping data for table `user` | |
| 536 | --- | |
| 537 | - | |
| 538 | -LOCK TABLES `user` WRITE; | |
| 539 | -/*!40000 ALTER TABLE `user` DISABLE KEYS */; | |
| 540 | -INSERT INTO `user` VALUES (1,'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021-04-13 14:14:57','2021-04-13 14:14:57','3e80d1762a324d5b0ff636e0bd16f1e3'); | |
| 541 | -/*!40000 ALTER TABLE `user` ENABLE KEYS */; | |
| 542 | -UNLOCK TABLES; | |
| 543 | - | |
| 544 | --- | |
| 545 | --- Table structure for table `user_role` | |
| 546 | --- | |
| 547 | - | |
| 548 | -DROP TABLE IF EXISTS `user_role`; | |
| 549 | -/*!40101 SET @saved_cs_client = @@character_set_client */; | |
| 550 | -/*!50503 SET character_set_client = utf8mb4 */; | |
| 551 | -CREATE TABLE `user_role` ( | |
| 552 | - `id` int NOT NULL AUTO_INCREMENT, | |
| 553 | - `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 554 | - `authority` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 555 | - `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 556 | - `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, | |
| 557 | - PRIMARY KEY (`id`) USING BTREE | |
| 558 | -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; | |
| 559 | -/*!40101 SET character_set_client = @saved_cs_client */; | |
| 560 | - | |
| 561 | --- | |
| 562 | --- Dumping data for table `user_role` | |
| 563 | --- | |
| 564 | - | |
| 565 | -LOCK TABLES `user_role` WRITE; | |
| 566 | -/*!40000 ALTER TABLE `user_role` DISABLE KEYS */; | |
| 567 | -INSERT INTO `user_role` VALUES (1,'admin','0','2021-04-13 14:14:57','2021-04-13 14:14:57'); | |
| 568 | -/*!40000 ALTER TABLE `user_role` ENABLE KEYS */; | |
| 569 | -UNLOCK TABLES; | |
| 570 | -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; | |
| 571 | - | |
| 572 | -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; | |
| 573 | -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; | |
| 574 | -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; | |
| 575 | -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; | |
| 576 | -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; | |
| 577 | -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; | |
| 578 | -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; | |
| 579 | - | |
| 580 | --- Dump completed on 2022-11-29 11:47:46 | |
| 581 | 287 | \ No newline at end of file | ... | ... |
src/main/java/com/genersoft/iot/vmp/common/CivilCodePo.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.common; | |
| 2 | + | |
| 3 | +public class CivilCodePo { | |
| 4 | + | |
| 5 | + private String code; | |
| 6 | + | |
| 7 | + private String name; | |
| 8 | + | |
| 9 | + private String parentCode; | |
| 10 | + | |
| 11 | + public static CivilCodePo getInstance(String[] infoArray) { | |
| 12 | + CivilCodePo civilCodePo = new CivilCodePo(); | |
| 13 | + civilCodePo.setCode(infoArray[0]); | |
| 14 | + civilCodePo.setName(infoArray[1]); | |
| 15 | + civilCodePo.setParentCode(infoArray[2]); | |
| 16 | + return civilCodePo; | |
| 17 | + } | |
| 18 | + | |
| 19 | + public String getCode() { | |
| 20 | + return code; | |
| 21 | + } | |
| 22 | + | |
| 23 | + public void setCode(String code) { | |
| 24 | + this.code = code; | |
| 25 | + } | |
| 26 | + | |
| 27 | + public String getName() { | |
| 28 | + return name; | |
| 29 | + } | |
| 30 | + | |
| 31 | + public void setName(String name) { | |
| 32 | + this.name = name; | |
| 33 | + } | |
| 34 | + | |
| 35 | + public String getParentCode() { | |
| 36 | + return parentCode; | |
| 37 | + } | |
| 38 | + | |
| 39 | + public void setParentCode(String parentCode) { | |
| 40 | + this.parentCode = parentCode; | |
| 41 | + } | |
| 42 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/common/GeneralCallback.java
0 → 100644
src/main/java/com/genersoft/iot/vmp/common/InviteInfo.java
| 1 | 1 | package com.genersoft.iot.vmp.common; |
| 2 | 2 | |
| 3 | 3 | import com.genersoft.iot.vmp.service.bean.SSRCInfo; |
| 4 | +import io.swagger.v3.oas.annotations.media.Schema; | |
| 4 | 5 | |
| 5 | 6 | /** |
| 6 | 7 | * 记录每次发送invite消息的状态 |
| ... | ... | @@ -28,7 +29,7 @@ public class InviteInfo { |
| 28 | 29 | private StreamInfo streamInfo; |
| 29 | 30 | |
| 30 | 31 | |
| 31 | - public static InviteInfo getinviteInfo(String deviceId, String channelId, String stream, SSRCInfo ssrcInfo, | |
| 32 | + public static InviteInfo getInviteInfo(String deviceId, String channelId, String stream, SSRCInfo ssrcInfo, | |
| 32 | 33 | String receiveIp, Integer receivePort, String streamMode, |
| 33 | 34 | InviteSessionType type, InviteSessionStatus status) { |
| 34 | 35 | InviteInfo inviteInfo = new InviteInfo(); |
| ... | ... | @@ -123,4 +124,21 @@ public class InviteInfo { |
| 123 | 124 | public void setStreamMode(String streamMode) { |
| 124 | 125 | this.streamMode = streamMode; |
| 125 | 126 | } |
| 127 | + | |
| 128 | + | |
| 129 | + /*=========================设备主子码流逻辑START====================*/ | |
| 130 | + @Schema(description = "是否为子码流(true-是,false-主码流)") | |
| 131 | + private boolean subStream; | |
| 132 | + | |
| 133 | + public boolean isSubStream() { | |
| 134 | + return subStream; | |
| 135 | + } | |
| 136 | + | |
| 137 | + public void setSubStream(boolean subStream) { | |
| 138 | + this.subStream = subStream; | |
| 139 | + } | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 126 | 144 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
| ... | ... | @@ -528,4 +528,19 @@ public class StreamInfo implements Serializable, Cloneable{ |
| 528 | 528 | } |
| 529 | 529 | return instance; |
| 530 | 530 | } |
| 531 | + | |
| 532 | + | |
| 533 | + /*=========================设备主子码流逻辑START====================*/ | |
| 534 | + @Schema(description = "是否为子码流(true-是,false-主码流)") | |
| 535 | + private boolean subStream; | |
| 536 | + | |
| 537 | + public boolean isSubStream() { | |
| 538 | + return subStream; | |
| 539 | + } | |
| 540 | + | |
| 541 | + public void setSubStream(boolean subStream) { | |
| 542 | + this.subStream = subStream; | |
| 543 | + } | |
| 544 | + | |
| 545 | + | |
| 531 | 546 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
| ... | ... | @@ -108,6 +108,11 @@ public class VideoManagerConstants { |
| 108 | 108 | public static final String VM_MSG_STREAM_PUSH_RESPONSE = "VM_MSG_STREAM_PUSH_RESPONSE"; |
| 109 | 109 | |
| 110 | 110 | /** |
| 111 | + * redis 通知平台关闭推流 | |
| 112 | + */ | |
| 113 | + public static final String VM_MSG_STREAM_PUSH_CLOSE = "VM_MSG_STREAM_PUSH_CLOSE"; | |
| 114 | + | |
| 115 | + /** | |
| 111 | 116 | * redis 消息请求所有的在线通道 |
| 112 | 117 | */ |
| 113 | 118 | public static final String VM_MSG_GET_ALL_ONLINE_REQUESTED = "VM_MSG_GET_ALL_ONLINE_REQUESTED"; | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/CivilCodeFileConf.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.conf; | |
| 2 | + | |
| 3 | +import com.genersoft.iot.vmp.common.CivilCodePo; | |
| 4 | +import org.ehcache.impl.internal.concurrent.ConcurrentHashMap; | |
| 5 | +import org.slf4j.Logger; | |
| 6 | +import org.slf4j.LoggerFactory; | |
| 7 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 8 | +import org.springframework.boot.CommandLineRunner; | |
| 9 | +import org.springframework.context.annotation.Configuration; | |
| 10 | +import org.springframework.context.annotation.Lazy; | |
| 11 | +import org.springframework.core.annotation.Order; | |
| 12 | +import org.springframework.core.io.ClassPathResource; | |
| 13 | +import org.springframework.util.ObjectUtils; | |
| 14 | + | |
| 15 | +import java.io.*; | |
| 16 | +import java.nio.file.Files; | |
| 17 | +import java.util.Map; | |
| 18 | + | |
| 19 | +/** | |
| 20 | + * 启动时读取行政区划表 | |
| 21 | + */ | |
| 22 | +@Configuration | |
| 23 | +@Order(value=14) | |
| 24 | +public class CivilCodeFileConf implements CommandLineRunner { | |
| 25 | + | |
| 26 | + private final static Logger logger = LoggerFactory.getLogger(CivilCodeFileConf.class); | |
| 27 | + | |
| 28 | + private final Map<String, CivilCodePo> civilCodeMap= new ConcurrentHashMap<>(); | |
| 29 | + | |
| 30 | + @Autowired | |
| 31 | + @Lazy | |
| 32 | + private UserSetting userSetting; | |
| 33 | + | |
| 34 | + @Override | |
| 35 | + public void run(String... args) throws Exception { | |
| 36 | + if (ObjectUtils.isEmpty(userSetting.getCivilCodeFile())) { | |
| 37 | + logger.warn("[行政区划] 文件未设置,可能造成目录刷新结果不完整"); | |
| 38 | + return; | |
| 39 | + } | |
| 40 | + InputStream inputStream; | |
| 41 | + if (userSetting.getCivilCodeFile().startsWith("classpath:")){ | |
| 42 | + String filePath = userSetting.getCivilCodeFile().substring("classpath:".length()); | |
| 43 | + ClassPathResource civilCodeFile = new ClassPathResource(filePath); | |
| 44 | + if (!civilCodeFile.exists()) { | |
| 45 | + logger.warn("[行政区划] 文件<{}>不存在,可能造成目录刷新结果不完整", userSetting.getCivilCodeFile()); | |
| 46 | + return; | |
| 47 | + } | |
| 48 | + inputStream = civilCodeFile.getInputStream(); | |
| 49 | + | |
| 50 | + }else { | |
| 51 | + File civilCodeFile = new File(userSetting.getCivilCodeFile()); | |
| 52 | + if (!civilCodeFile.exists()) { | |
| 53 | + logger.warn("[行政区划] 文件<{}>不存在,可能造成目录刷新结果不完整", userSetting.getCivilCodeFile()); | |
| 54 | + return; | |
| 55 | + } | |
| 56 | + inputStream = Files.newInputStream(civilCodeFile.toPath()); | |
| 57 | + } | |
| 58 | + | |
| 59 | + BufferedReader inputStreamReader = new BufferedReader(new InputStreamReader(inputStream)); | |
| 60 | + int index = -1; | |
| 61 | + String line; | |
| 62 | + while ((line = inputStreamReader.readLine()) != null) { | |
| 63 | + index ++; | |
| 64 | + if (index == 0) { | |
| 65 | + continue; | |
| 66 | + } | |
| 67 | + String[] infoArray = line.split(","); | |
| 68 | + CivilCodePo civilCodePo = CivilCodePo.getInstance(infoArray); | |
| 69 | + civilCodeMap.put(civilCodePo.getCode(), civilCodePo); | |
| 70 | + } | |
| 71 | + inputStreamReader.close(); | |
| 72 | + inputStream.close(); | |
| 73 | + if (civilCodeMap.size() == 0) { | |
| 74 | + logger.warn("[行政区划] 文件内容为空,可能造成目录刷新结果不完整"); | |
| 75 | + }else { | |
| 76 | + logger.info("[行政区划] 加载成功,共加载数据{}条", civilCodeMap.size()); | |
| 77 | + } | |
| 78 | + } | |
| 79 | + | |
| 80 | + public CivilCodePo getParentCode(String code) { | |
| 81 | + if (code.length() > 8) { | |
| 82 | + return null; | |
| 83 | + } | |
| 84 | + if (code.length() == 8) { | |
| 85 | + String parentCode = code.substring(0, 6); | |
| 86 | + return civilCodeMap.get(parentCode); | |
| 87 | + }else { | |
| 88 | + CivilCodePo civilCodePo = civilCodeMap.get(code); | |
| 89 | + if (civilCodePo == null){ | |
| 90 | + return null; | |
| 91 | + } | |
| 92 | + String parentCode = civilCodePo.getParentCode(); | |
| 93 | + if (parentCode == null) { | |
| 94 | + return null; | |
| 95 | + } | |
| 96 | + return civilCodeMap.get(parentCode); | |
| 97 | + } | |
| 98 | + | |
| 99 | + } | |
| 100 | + | |
| 101 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java
| ... | ... | @@ -2,11 +2,11 @@ package com.genersoft.iot.vmp.conf; |
| 2 | 2 | |
| 3 | 3 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 4 | 4 | import com.genersoft.iot.vmp.utils.DateUtil; |
| 5 | -import org.junit.jupiter.api.Order; | |
| 6 | 5 | import org.slf4j.Logger; |
| 7 | 6 | import org.slf4j.LoggerFactory; |
| 8 | 7 | import org.springframework.beans.factory.annotation.Value; |
| 9 | 8 | import org.springframework.context.annotation.Configuration; |
| 9 | +import org.springframework.core.annotation.Order; | |
| 10 | 10 | import org.springframework.util.ObjectUtils; |
| 11 | 11 | |
| 12 | 12 | import java.net.InetAddress; | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/MybatisConfig.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.conf; | |
| 2 | + | |
| 3 | +import org.apache.ibatis.logging.stdout.StdOutImpl; | |
| 4 | +import org.apache.ibatis.session.SqlSessionFactory; | |
| 5 | +import org.mybatis.spring.SqlSessionFactoryBean; | |
| 6 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 7 | +import org.springframework.context.annotation.Bean; | |
| 8 | +import org.springframework.context.annotation.Configuration; | |
| 9 | +import org.springframework.core.annotation.Order; | |
| 10 | + | |
| 11 | +import javax.sql.DataSource; | |
| 12 | + | |
| 13 | +/** | |
| 14 | + * 配置mybatis | |
| 15 | + */ | |
| 16 | +@Configuration | |
| 17 | +@Order(value=1) | |
| 18 | +public class MybatisConfig { | |
| 19 | + | |
| 20 | + @Autowired | |
| 21 | + private UserSetting userSetting; | |
| 22 | + | |
| 23 | + @Bean | |
| 24 | + public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { | |
| 25 | + final SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean(); | |
| 26 | + sqlSessionFactory.setDataSource(dataSource); | |
| 27 | + org.apache.ibatis.session.Configuration config = new org.apache.ibatis.session.Configuration(); | |
| 28 | + if (userSetting.getSqlLog()){ | |
| 29 | + config.setLogImpl(StdOutImpl.class); | |
| 30 | + } | |
| 31 | + config.setMapUnderscoreToCamelCase(true); | |
| 32 | + sqlSessionFactory.setConfiguration(config); | |
| 33 | + return sqlSessionFactory.getObject(); | |
| 34 | + } | |
| 35 | + | |
| 36 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/ProxyServletConfig.java
| ... | ... | @@ -5,7 +5,7 @@ import com.genersoft.iot.vmp.service.IMediaServerService; |
| 5 | 5 | import org.apache.http.HttpHost; |
| 6 | 6 | import org.apache.http.HttpRequest; |
| 7 | 7 | import org.apache.http.HttpResponse; |
| 8 | -import org.junit.jupiter.api.Order; | |
| 8 | +import org.springframework.core.annotation.Order; | |
| 9 | 9 | import org.mitre.dsmiley.httpproxy.ProxyServlet; |
| 10 | 10 | import org.slf4j.Logger; |
| 11 | 11 | import org.slf4j.LoggerFactory; | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/SipConfig.java
src/main/java/com/genersoft/iot/vmp/conf/SipPlatformRunner.java
src/main/java/com/genersoft/iot/vmp/conf/SpringDocConfig.java
| ... | ... | @@ -4,7 +4,7 @@ import io.swagger.v3.oas.models.OpenAPI; |
| 4 | 4 | import io.swagger.v3.oas.models.info.Contact; |
| 5 | 5 | import io.swagger.v3.oas.models.info.Info; |
| 6 | 6 | import io.swagger.v3.oas.models.info.License; |
| 7 | -import org.junit.jupiter.api.Order; | |
| 7 | +import org.springframework.core.annotation.Order; | |
| 8 | 8 | import org.springdoc.core.GroupedOpenApi; |
| 9 | 9 | import org.springframework.beans.factory.annotation.Value; |
| 10 | 10 | import org.springframework.context.annotation.Bean; | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/ThreadPoolTaskConfig.java
| 1 | 1 | package com.genersoft.iot.vmp.conf; |
| 2 | 2 | |
| 3 | -import org.junit.jupiter.api.Order; | |
| 4 | 3 | import org.springframework.context.annotation.Bean; |
| 5 | 4 | import org.springframework.context.annotation.Configuration; |
| 5 | +import org.springframework.core.annotation.Order; | |
| 6 | 6 | import org.springframework.scheduling.annotation.EnableAsync; |
| 7 | 7 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
| 8 | 8 | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
| 1 | 1 | package com.genersoft.iot.vmp.conf; |
| 2 | 2 | |
| 3 | -import org.junit.jupiter.api.Order; | |
| 4 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; |
| 4 | +import org.springframework.core.annotation.Order; | |
| 5 | 5 | import org.springframework.stereotype.Component; |
| 6 | 6 | |
| 7 | 7 | import java.util.ArrayList; |
| ... | ... | @@ -50,6 +50,7 @@ public class UserSetting { |
| 50 | 50 | private Boolean pushStreamAfterAck = Boolean.FALSE; |
| 51 | 51 | |
| 52 | 52 | private Boolean sipLog = Boolean.FALSE; |
| 53 | + private Boolean sqlLog = Boolean.FALSE; | |
| 53 | 54 | private Boolean sendToPlatformsWhenIdLost = Boolean.FALSE; |
| 54 | 55 | |
| 55 | 56 | private Boolean refuseChannelStatusChannelFormNotify = Boolean.FALSE; |
| ... | ... | @@ -65,12 +66,18 @@ public class UserSetting { |
| 65 | 66 | |
| 66 | 67 | private String broadcastForPlatform = "UDP"; |
| 67 | 68 | |
| 69 | + private String civilCodeFile = "classpath:civilCode.csv"; | |
| 70 | + | |
| 68 | 71 | private List<String> interfaceAuthenticationExcludes = new ArrayList<>(); |
| 69 | 72 | |
| 70 | 73 | private List<String> allowedOrigins = new ArrayList<>(); |
| 71 | 74 | |
| 72 | 75 | private int maxNotifyCountQueue = 10000; |
| 73 | 76 | |
| 77 | + private int registerAgainAfterTime = 60; | |
| 78 | + | |
| 79 | + private boolean registerKeepIntDialog = false; | |
| 80 | + | |
| 74 | 81 | public Boolean getSavePositionHistory() { |
| 75 | 82 | return savePositionHistory; |
| 76 | 83 | } |
| ... | ... | @@ -306,4 +313,36 @@ public class UserSetting { |
| 306 | 313 | public void setUseCustomSsrcForParentInvite(Boolean useCustomSsrcForParentInvite) { |
| 307 | 314 | this.useCustomSsrcForParentInvite = useCustomSsrcForParentInvite; |
| 308 | 315 | } |
| 316 | + | |
| 317 | + public Boolean getSqlLog() { | |
| 318 | + return sqlLog; | |
| 319 | + } | |
| 320 | + | |
| 321 | + public void setSqlLog(Boolean sqlLog) { | |
| 322 | + this.sqlLog = sqlLog; | |
| 323 | + } | |
| 324 | + | |
| 325 | + public String getCivilCodeFile() { | |
| 326 | + return civilCodeFile; | |
| 327 | + } | |
| 328 | + | |
| 329 | + public void setCivilCodeFile(String civilCodeFile) { | |
| 330 | + this.civilCodeFile = civilCodeFile; | |
| 331 | + } | |
| 332 | + | |
| 333 | + public int getRegisterAgainAfterTime() { | |
| 334 | + return registerAgainAfterTime; | |
| 335 | + } | |
| 336 | + | |
| 337 | + public void setRegisterAgainAfterTime(int registerAgainAfterTime) { | |
| 338 | + this.registerAgainAfterTime = registerAgainAfterTime; | |
| 339 | + } | |
| 340 | + | |
| 341 | + public boolean isRegisterKeepIntDialog() { | |
| 342 | + return registerKeepIntDialog; | |
| 343 | + } | |
| 344 | + | |
| 345 | + public void setRegisterKeepIntDialog(boolean registerKeepIntDialog) { | |
| 346 | + this.registerKeepIntDialog = registerKeepIntDialog; | |
| 347 | + } | |
| 309 | 348 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/VersionConfig.java
src/main/java/com/genersoft/iot/vmp/conf/redis/RedisMsgListenConfig.java
| ... | ... | @@ -43,6 +43,9 @@ public class RedisMsgListenConfig { |
| 43 | 43 | @Autowired |
| 44 | 44 | private RedisPushStreamResponseListener redisPushStreamResponseListener; |
| 45 | 45 | |
| 46 | + @Autowired | |
| 47 | + private RedisCloseStreamMsgListener redisCloseStreamMsgListener; | |
| 48 | + | |
| 46 | 49 | |
| 47 | 50 | /** |
| 48 | 51 | * redis消息监听器容器 可以添加多个监听不同话题的redis监听器,只需要把消息监听器和相应的消息订阅处理器绑定,该消息监听器 |
| ... | ... | @@ -63,6 +66,7 @@ public class RedisMsgListenConfig { |
| 63 | 66 | container.addMessageListener(redisPushStreamStatusMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_PUSH_STREAM_STATUS_CHANGE)); |
| 64 | 67 | container.addMessageListener(redisPushStreamListMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_PUSH_STREAM_LIST_CHANGE)); |
| 65 | 68 | container.addMessageListener(redisPushStreamResponseListener, new PatternTopic(VideoManagerConstants.VM_MSG_STREAM_PUSH_RESPONSE)); |
| 69 | + container.addMessageListener(redisCloseStreamMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_STREAM_PUSH_CLOSE)); | |
| 66 | 70 | return container; |
| 67 | 71 | } |
| 68 | 72 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/security/AnonymousAuthenticationEntryPoint.java
| ... | ... | @@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.conf.security; |
| 3 | 3 | import com.alibaba.fastjson2.JSONObject; |
| 4 | 4 | import com.genersoft.iot.vmp.conf.security.dto.JwtUser; |
| 5 | 5 | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| 6 | +import org.springframework.http.MediaType; | |
| 6 | 7 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
| 7 | 8 | import org.springframework.security.core.AuthenticationException; |
| 8 | 9 | import org.springframework.security.core.context.SecurityContextHolder; |
| ... | ... | @@ -12,6 +13,7 @@ import org.springframework.stereotype.Component; |
| 12 | 13 | import javax.servlet.http.HttpServletRequest; |
| 13 | 14 | import javax.servlet.http.HttpServletResponse; |
| 14 | 15 | import java.io.IOException; |
| 16 | +import java.nio.charset.StandardCharsets; | |
| 15 | 17 | |
| 16 | 18 | /** |
| 17 | 19 | * 处理匿名用户访问逻辑 |
| ... | ... | @@ -35,6 +37,8 @@ public class AnonymousAuthenticationEntryPoint implements AuthenticationEntry |
| 35 | 37 | jsonObject.put("msg", e.getMessage()); |
| 36 | 38 | } |
| 37 | 39 | response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); |
| 40 | + response.setContentType(MediaType.APPLICATION_JSON_VALUE); | |
| 41 | + response.setCharacterEncoding(StandardCharsets.UTF_8.name()); | |
| 38 | 42 | try { |
| 39 | 43 | response.getWriter().print(jsonObject.toJSONString()); |
| 40 | 44 | } catch (IOException ioException) { | ... | ... |
src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java
| 1 | 1 | package com.genersoft.iot.vmp.conf.security; |
| 2 | 2 | |
| 3 | 3 | import com.genersoft.iot.vmp.conf.UserSetting; |
| 4 | -import org.junit.jupiter.api.Order; | |
| 4 | +import org.springframework.core.annotation.Order; | |
| 5 | 5 | import org.slf4j.Logger; |
| 6 | 6 | import org.slf4j.LoggerFactory; |
| 7 | 7 | import org.springframework.beans.factory.annotation.Autowired; | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Device.java
| ... | ... | @@ -77,8 +77,8 @@ public class Device { |
| 77 | 77 | /** |
| 78 | 78 | * 在线 |
| 79 | 79 | */ |
| 80 | - @Schema(description = "是否在线,1为在线,0为离线") | |
| 81 | - private int online; | |
| 80 | + @Schema(description = "是否在线,true为在线,false为离线") | |
| 81 | + private boolean onLine; | |
| 82 | 82 | |
| 83 | 83 | |
| 84 | 84 | /** |
| ... | ... | @@ -140,7 +140,7 @@ public class Device { |
| 140 | 140 | /** |
| 141 | 141 | * 目录订阅周期,0为不订阅 |
| 142 | 142 | */ |
| 143 | - @Schema(description = "目录订阅周期,0为不订阅") | |
| 143 | + @Schema(description = "目录订阅周期,o为不订阅") | |
| 144 | 144 | private int subscribeCycleForCatalog; |
| 145 | 145 | |
| 146 | 146 | /** |
| ... | ... | @@ -173,12 +173,6 @@ public class Device { |
| 173 | 173 | @Schema(description = "地理坐标系, 目前支持 WGS84,GCJ02") |
| 174 | 174 | private String geoCoordSys; |
| 175 | 175 | |
| 176 | - /** | |
| 177 | - * 树类型 国标规定了两种树的展现方式 行政区划:CivilCode 和业务分组:BusinessGroup | |
| 178 | - */ | |
| 179 | - @Schema(description = "树类型 国标规定了两种树的展现方式 行政区划:CivilCode 和业务分组:BusinessGroup") | |
| 180 | - private String treeType; | |
| 181 | - | |
| 182 | 176 | @Schema(description = "密码") |
| 183 | 177 | private String password; |
| 184 | 178 | |
| ... | ... | @@ -195,6 +189,8 @@ public class Device { |
| 195 | 189 | private SipTransactionInfo sipTransactionInfo; |
| 196 | 190 | |
| 197 | 191 | |
| 192 | + | |
| 193 | + | |
| 198 | 194 | public String getDeviceId() { |
| 199 | 195 | return deviceId; |
| 200 | 196 | } |
| ... | ... | @@ -286,12 +282,12 @@ public class Device { |
| 286 | 282 | this.hostAddress = hostAddress; |
| 287 | 283 | } |
| 288 | 284 | |
| 289 | - public int getOnline() { | |
| 290 | - return online; | |
| 285 | + public boolean isOnLine() { | |
| 286 | + return onLine; | |
| 291 | 287 | } |
| 292 | 288 | |
| 293 | - public void setOnline(int online) { | |
| 294 | - this.online = online; | |
| 289 | + public void setOnLine(boolean onLine) { | |
| 290 | + this.onLine = onLine; | |
| 295 | 291 | } |
| 296 | 292 | |
| 297 | 293 | public int getChannelCount() { |
| ... | ... | @@ -406,15 +402,6 @@ public class Device { |
| 406 | 402 | this.geoCoordSys = geoCoordSys; |
| 407 | 403 | } |
| 408 | 404 | |
| 409 | - | |
| 410 | - public String getTreeType() { | |
| 411 | - return treeType; | |
| 412 | - } | |
| 413 | - | |
| 414 | - public void setTreeType(String treeType) { | |
| 415 | - this.treeType = treeType; | |
| 416 | - } | |
| 417 | - | |
| 418 | 405 | public String getPassword() { |
| 419 | 406 | return password; |
| 420 | 407 | } |
| ... | ... | @@ -462,4 +449,20 @@ public class Device { |
| 462 | 449 | public void setSipTransactionInfo(SipTransactionInfo sipTransactionInfo) { |
| 463 | 450 | this.sipTransactionInfo = sipTransactionInfo; |
| 464 | 451 | } |
| 452 | + | |
| 453 | + /*======================设备主子码流逻辑START=========================*/ | |
| 454 | + @Schema(description = "开启主子码流切换的开关(false-不开启,true-开启)") | |
| 455 | + private boolean switchPrimarySubStream; | |
| 456 | + | |
| 457 | + public boolean isSwitchPrimarySubStream() { | |
| 458 | + return switchPrimarySubStream; | |
| 459 | + } | |
| 460 | + | |
| 461 | + public void setSwitchPrimarySubStream(boolean switchPrimarySubStream) { | |
| 462 | + this.switchPrimarySubStream = switchPrimarySubStream; | |
| 463 | + } | |
| 464 | + | |
| 465 | + /*======================设备主子码流逻辑END=========================*/ | |
| 466 | + | |
| 467 | + | |
| 465 | 468 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java
| ... | ... | @@ -172,7 +172,7 @@ public class DeviceChannel { |
| 172 | 172 | * 遇到过NVR下的IPC下发信令可以推流, 但是 Status 响应 OFF |
| 173 | 173 | */ |
| 174 | 174 | @Schema(description = "在线/离线, 1在线,0离线") |
| 175 | - private int status; | |
| 175 | + private boolean status; | |
| 176 | 176 | |
| 177 | 177 | /** |
| 178 | 178 | * 经度 |
| ... | ... | @@ -455,11 +455,11 @@ public class DeviceChannel { |
| 455 | 455 | this.PTZTypeText = PTZTypeText; |
| 456 | 456 | } |
| 457 | 457 | |
| 458 | - public int getStatus() { | |
| 458 | + public boolean isStatus() { | |
| 459 | 459 | return status; |
| 460 | 460 | } |
| 461 | 461 | |
| 462 | - public void setStatus(int status) { | |
| 462 | + public void setStatus(boolean status) { | |
| 463 | 463 | this.status = status; |
| 464 | 464 | } |
| 465 | 465 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Gb28181Sdp.java
0 → 100644
| 1 | +package com.genersoft.iot.vmp.gb28181.bean; | |
| 2 | + | |
| 3 | +import javax.sdp.SessionDescription; | |
| 4 | + | |
| 5 | +/** | |
| 6 | + * 28181 的SDP解析器 | |
| 7 | + */ | |
| 8 | +public class Gb28181Sdp { | |
| 9 | + private SessionDescription baseSdb; | |
| 10 | + private String ssrc; | |
| 11 | + | |
| 12 | + private String mediaDescription; | |
| 13 | + | |
| 14 | + public static Gb28181Sdp getInstance(SessionDescription baseSdb, String ssrc, String mediaDescription) { | |
| 15 | + Gb28181Sdp gb28181Sdp = new Gb28181Sdp(); | |
| 16 | + gb28181Sdp.setBaseSdb(baseSdb); | |
| 17 | + gb28181Sdp.setSsrc(ssrc); | |
| 18 | + gb28181Sdp.setMediaDescription(mediaDescription); | |
| 19 | + return gb28181Sdp; | |
| 20 | + } | |
| 21 | + | |
| 22 | + | |
| 23 | + public SessionDescription getBaseSdb() { | |
| 24 | + return baseSdb; | |
| 25 | + } | |
| 26 | + | |
| 27 | + public void setBaseSdb(SessionDescription baseSdb) { | |
| 28 | + this.baseSdb = baseSdb; | |
| 29 | + } | |
| 30 | + | |
| 31 | + public String getSsrc() { | |
| 32 | + return ssrc; | |
| 33 | + } | |
| 34 | + | |
| 35 | + public void setSsrc(String ssrc) { | |
| 36 | + this.ssrc = ssrc; | |
| 37 | + } | |
| 38 | + | |
| 39 | + public String getMediaDescription() { | |
| 40 | + return mediaDescription; | |
| 41 | + } | |
| 42 | + | |
| 43 | + public void setMediaDescription(String mediaDescription) { | |
| 44 | + this.mediaDescription = mediaDescription; | |
| 45 | + } | |
| 46 | +} | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/GbStream.java
| ... | ... | @@ -10,7 +10,7 @@ import io.swagger.v3.oas.annotations.media.Schema; |
| 10 | 10 | public class GbStream extends PlatformGbStream{ |
| 11 | 11 | |
| 12 | 12 | @Schema(description = "ID") |
| 13 | - private Integer gbStreamId; | |
| 13 | + private int gbStreamId; | |
| 14 | 14 | @Schema(description = "应用名") |
| 15 | 15 | private String app; |
| 16 | 16 | @Schema(description = "流ID") | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java
| ... | ... | @@ -183,12 +183,6 @@ public class ParentPlatform { |
| 183 | 183 | @Schema(description = "创建时间") |
| 184 | 184 | private String createTime; |
| 185 | 185 | |
| 186 | - /** | |
| 187 | - * 树类型 国标规定了两种树的展现方式 行政区划 CivilCode 和业务分组:BusinessGroup | |
| 188 | - */ | |
| 189 | - @Schema(description = "树类型 国标规定了两种树的展现方式 行政区划 CivilCode 和业务分组:BusinessGrou") | |
| 190 | - private String treeType; | |
| 191 | - | |
| 192 | 186 | @Schema(description = "是否作为消息通道") |
| 193 | 187 | private boolean asMessageChannel; |
| 194 | 188 | |
| ... | ... | @@ -424,14 +418,6 @@ public class ParentPlatform { |
| 424 | 418 | this.createTime = createTime; |
| 425 | 419 | } |
| 426 | 420 | |
| 427 | - public String getTreeType() { | |
| 428 | - return treeType; | |
| 429 | - } | |
| 430 | - | |
| 431 | - public void setTreeType(String treeType) { | |
| 432 | - this.treeType = treeType; | |
| 433 | - } | |
| 434 | - | |
| 435 | 421 | public boolean isAsMessageChannel() { |
| 436 | 422 | return asMessageChannel; |
| 437 | 423 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/bean/PlatformGbStream.java
src/main/java/com/genersoft/iot/vmp/gb28181/bean/TreeType.java deleted
100644 → 0
src/main/java/com/genersoft/iot/vmp/gb28181/session/SSRCFactory.java
| 1 | 1 | package com.genersoft.iot.vmp.gb28181.session; |
| 2 | 2 | |
| 3 | 3 | import com.genersoft.iot.vmp.conf.SipConfig; |
| 4 | +import com.genersoft.iot.vmp.conf.UserSetting; | |
| 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; |
| 5 | 6 | import org.springframework.data.redis.core.StringRedisTemplate; |
| 6 | 7 | import org.springframework.stereotype.Component; |
| ... | ... | @@ -31,10 +32,13 @@ public class SSRCFactory { |
| 31 | 32 | @Autowired |
| 32 | 33 | private SipConfig sipConfig; |
| 33 | 34 | |
| 35 | + @Autowired | |
| 36 | + private UserSetting userSetting; | |
| 37 | + | |
| 34 | 38 | |
| 35 | 39 | public void initMediaServerSSRC(String mediaServerId, Set<String> usedSet) { |
| 36 | 40 | String ssrcPrefix = sipConfig.getDomain().substring(3, 8); |
| 37 | - String redisKey = SSRC_INFO_KEY + mediaServerId; | |
| 41 | + String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId; | |
| 38 | 42 | List<String> ssrcList = new ArrayList<>(); |
| 39 | 43 | for (int i = 1; i < MAX_STREAM_COUNT; i++) { |
| 40 | 44 | String ssrc = String.format("%s%04d", ssrcPrefix, i); |
| ... | ... | @@ -77,7 +81,7 @@ public class SSRCFactory { |
| 77 | 81 | return; |
| 78 | 82 | } |
| 79 | 83 | String sn = ssrc.substring(1); |
| 80 | - String redisKey = SSRC_INFO_KEY + mediaServerId; | |
| 84 | + String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId; | |
| 81 | 85 | redisTemplate.opsForSet().add(redisKey, sn); |
| 82 | 86 | } |
| 83 | 87 | |
| ... | ... | @@ -86,7 +90,7 @@ public class SSRCFactory { |
| 86 | 90 | */ |
| 87 | 91 | private String getSN(String mediaServerId) { |
| 88 | 92 | String sn = null; |
| 89 | - String redisKey = SSRC_INFO_KEY + mediaServerId; | |
| 93 | + String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId; | |
| 90 | 94 | Long size = redisTemplate.opsForSet().size(redisKey); |
| 91 | 95 | if (size == null || size == 0) { |
| 92 | 96 | throw new RuntimeException("ssrc已经用完"); |
| ... | ... | @@ -113,20 +117,8 @@ public class SSRCFactory { |
| 113 | 117 | * @param mediaServerId 流媒体服务ID |
| 114 | 118 | */ |
| 115 | 119 | public boolean hasMediaServerSSRC(String mediaServerId) { |
| 116 | - String redisKey = SSRC_INFO_KEY + mediaServerId; | |
| 120 | + String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId; | |
| 117 | 121 | return redisTemplate.opsForSet().members(redisKey) != null; |
| 118 | 122 | } |
| 119 | 123 | |
| 120 | - /** | |
| 121 | - * 查询ssrc是否可用 | |
| 122 | - * | |
| 123 | - * @param mediaServerId | |
| 124 | - * @param ssrc | |
| 125 | - * @return | |
| 126 | - */ | |
| 127 | - public boolean checkSsrc(String mediaServerId, String ssrc) { | |
| 128 | - String sn = ssrc.substring(1); | |
| 129 | - String redisKey = SSRC_INFO_KEY + mediaServerId; | |
| 130 | - return redisTemplate.opsForSet().isMember(redisKey, sn) != null; | |
| 131 | - } | |
| 132 | 124 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
| ... | ... | @@ -39,16 +39,22 @@ public class DeferredResultHolder { |
| 39 | 39 | |
| 40 | 40 | public static final String CALLBACK_CMD_DOWNLOAD = "CALLBACK_DOWNLOAD"; |
| 41 | 41 | |
| 42 | + public static final String CALLBACK_CMD_PROXY = "CALLBACK_PROXY"; | |
| 43 | + | |
| 42 | 44 | public static final String CALLBACK_CMD_STOP = "CALLBACK_STOP"; |
| 43 | 45 | |
| 44 | 46 | public static final String UPLOAD_FILE_CHANNEL = "UPLOAD_FILE_CHANNEL"; |
| 45 | 47 | |
| 46 | - public static final String CALLBACK_CMD_MOBILEPOSITION = "CALLBACK_MOBILEPOSITION"; | |
| 48 | + public static final String CALLBACK_CMD_MOBILE_POSITION = "CALLBACK_CMD_MOBILE_POSITION"; | |
| 47 | 49 | |
| 48 | 50 | public static final String CALLBACK_CMD_PRESETQUERY = "CALLBACK_PRESETQUERY"; |
| 49 | 51 | |
| 50 | 52 | public static final String CALLBACK_CMD_ALARM = "CALLBACK_ALARM"; |
| 51 | 53 | |
| 54 | + public static final String CALLBACK_CMD_BROADCAST = "CALLBACK_BROADCAST"; | |
| 55 | + | |
| 56 | + public static final String CALLBACK_CMD_SNAP= "CALLBACK_SNAP"; | |
| 57 | + | |
| 52 | 58 | private Map<String, Map<String, DeferredResultEx>> map = new ConcurrentHashMap<>(); |
| 53 | 59 | |
| 54 | 60 | |
| ... | ... | @@ -149,4 +155,6 @@ public class DeferredResultHolder { |
| 149 | 155 | map.remove(msg.getKey()); |
| 150 | 156 | } |
| 151 | 157 | } |
| 158 | + | |
| 159 | + | |
| 152 | 160 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
| ... | ... | @@ -80,7 +80,7 @@ public interface ISIPCommanderForPlatform { |
| 80 | 80 | * @param fromTag |
| 81 | 81 | * @return |
| 82 | 82 | */ |
| 83 | - void deviceStatusResponse(ParentPlatform parentPlatform,String channelId, String sn, String fromTag,int status) throws SipException, InvalidArgumentException, ParseException ; | |
| 83 | + void deviceStatusResponse(ParentPlatform parentPlatform,String channelId, String sn, String fromTag,boolean status) throws SipException, InvalidArgumentException, ParseException; | |
| 84 | 84 | |
| 85 | 85 | /** |
| 86 | 86 | * 向上级回复移动位置订阅消息 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
| ... | ... | @@ -55,8 +55,8 @@ public class SIPRequestHeaderPlarformProvider { |
| 55 | 55 | parentPlatform.getServerIP() + ":" + parentPlatform.getServerPort()); |
| 56 | 56 | //via |
| 57 | 57 | ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); |
| 58 | - ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(parentPlatform.getServerIP(), | |
| 59 | - parentPlatform.getServerPort(), parentPlatform.getTransport(), SipUtils.getNewViaTag()); | |
| 58 | + ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(parentPlatform.getDeviceIp(), | |
| 59 | + Integer.parseInt(parentPlatform.getDevicePort()), parentPlatform.getTransport(), SipUtils.getNewViaTag()); | |
| 60 | 60 | viaHeader.setRPort(); |
| 61 | 61 | viaHeaders.add(viaHeader); |
| 62 | 62 | //from | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
| 1 | 1 | package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl; |
| 2 | 2 | |
| 3 | -import com.alibaba.fastjson2.JSONObject; | |
| 4 | 3 | import com.genersoft.iot.vmp.common.InviteSessionType; |
| 5 | 4 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 6 | 5 | import com.genersoft.iot.vmp.conf.SipConfig; |
| 7 | 6 | import com.genersoft.iot.vmp.conf.UserSetting; |
| 8 | 7 | import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; |
| 9 | 8 | import com.genersoft.iot.vmp.gb28181.SipLayer; |
| 10 | -import com.genersoft.iot.vmp.gb28181.bean.*; | |
| 9 | +import com.genersoft.iot.vmp.gb28181.bean.Device; | |
| 10 | +import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm; | |
| 11 | +import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction; | |
| 11 | 12 | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; |
| 12 | 13 | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| 13 | 14 | import com.genersoft.iot.vmp.gb28181.transmit.SIPSender; |
| ... | ... | @@ -21,6 +22,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; |
| 21 | 22 | import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; |
| 22 | 23 | import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamPush; |
| 23 | 24 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 25 | +import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; | |
| 24 | 26 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 25 | 27 | import com.genersoft.iot.vmp.service.bean.SSRCInfo; |
| 26 | 28 | import com.genersoft.iot.vmp.utils.DateUtil; |
| ... | ... | @@ -155,6 +157,11 @@ public class SIPCommander implements ISIPCommander { |
| 155 | 157 | builder.append(strTmp, 0, 2); |
| 156 | 158 | strTmp = String.format("%02X", parameter2); |
| 157 | 159 | builder.append(strTmp, 0, 2); |
| 160 | + //优化zoom变倍速率 | |
| 161 | + if ((combineCode2 > 0) && (combineCode2 <16)) | |
| 162 | + { | |
| 163 | + combineCode2 = 16; | |
| 164 | + } | |
| 158 | 165 | strTmp = String.format("%X", combineCode2); |
| 159 | 166 | builder.append(strTmp, 0, 1).append("0"); |
| 160 | 167 | //计算校验码 |
| ... | ... | @@ -280,9 +287,9 @@ public class SIPCommander implements ISIPCommander { |
| 280 | 287 | |
| 281 | 288 | logger.info("{} 分配的ZLM为: {} [{}:{}]", stream, mediaServerItem.getId(), mediaServerItem.getSdpIp(), ssrcInfo.getPort()); |
| 282 | 289 | HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId()); |
| 283 | - subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject json) -> { | |
| 290 | + subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, HookParam hookParam) -> { | |
| 284 | 291 | if (event != null) { |
| 285 | - event.response(mediaServerItemInUse, json); | |
| 292 | + event.response(mediaServerItemInUse, hookParam); | |
| 286 | 293 | subscribe.removeSubscribe(hookSubscribe); |
| 287 | 294 | } |
| 288 | 295 | }); |
| ... | ... | @@ -345,6 +352,22 @@ public class SIPCommander implements ISIPCommander { |
| 345 | 352 | } |
| 346 | 353 | } |
| 347 | 354 | |
| 355 | + if( device.isSwitchPrimarySubStream() ){ | |
| 356 | + if("TP-LINK".equals(device.getManufacturer())){ | |
| 357 | + if (device.isSwitchPrimarySubStream()){ | |
| 358 | + content.append("a=streamMode:sub\r\n"); | |
| 359 | + }else { | |
| 360 | + content.append("a=streamMode:main\r\n"); | |
| 361 | + } | |
| 362 | + }else { | |
| 363 | + if (device.isSwitchPrimarySubStream()){ | |
| 364 | + content.append("a=streamprofile:1\r\n"); | |
| 365 | + }else { | |
| 366 | + content.append("a=streamprofile:0\r\n"); | |
| 367 | + } | |
| 368 | + } | |
| 369 | + } | |
| 370 | + | |
| 348 | 371 | content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc |
| 349 | 372 | // f字段:f= v/编码格式/分辨率/帧率/码率类型/码率大小a/编码格式/码率大小/采样率 |
| 350 | 373 | // content.append("f=v/2/5/25/1/4000a/1/8/1" + "\r\n"); // 未发现支持此特性的设备 |
| ... | ... | @@ -360,7 +383,8 @@ public class SIPCommander implements ISIPCommander { |
| 360 | 383 | // 这里为例避免一个通道的点播只有一个callID这个参数使用一个固定值 |
| 361 | 384 | ResponseEvent responseEvent = (ResponseEvent) e.event; |
| 362 | 385 | SIPResponse response = (SIPResponse) responseEvent.getResponse(); |
| 363 | - streamSession.put(device.getDeviceId(), channelId, "play", stream, ssrcInfo.getSsrc(), mediaServerItem.getId(), response, InviteSessionType.PLAY); | |
| 386 | + streamSession.put(device.getDeviceId(), channelId, "play", stream, ssrcInfo.getSsrc(), mediaServerItem.getId(), response, | |
| 387 | + InviteSessionType.PLAY); | |
| 364 | 388 | okEvent.response(e); |
| 365 | 389 | }); |
| 366 | 390 | } |
| ... | ... | @@ -450,13 +474,13 @@ public class SIPCommander implements ISIPCommander { |
| 450 | 474 | |
| 451 | 475 | HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId()); |
| 452 | 476 | // 添加订阅 |
| 453 | - subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject json) -> { | |
| 477 | + subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, HookParam hookParam) -> { | |
| 454 | 478 | if (hookEvent != null) { |
| 455 | - hookEvent.response(mediaServerItemInUse, json); | |
| 479 | + hookEvent.response(mediaServerItemInUse, hookParam); | |
| 456 | 480 | } |
| 457 | 481 | subscribe.removeSubscribe(hookSubscribe); |
| 458 | 482 | }); |
| 459 | - Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()), ssrcInfo.getSsrc()); | |
| 483 | + Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()), ssrcInfo.getSsrc()); | |
| 460 | 484 | |
| 461 | 485 | sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent, event -> { |
| 462 | 486 | ResponseEvent responseEvent = (ResponseEvent) event.event; |
| ... | ... | @@ -553,15 +577,15 @@ public class SIPCommander implements ISIPCommander { |
| 553 | 577 | // 添加订阅 |
| 554 | 578 | CallIdHeader newCallIdHeader = sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()), device.getTransport()); |
| 555 | 579 | String callId= newCallIdHeader.getCallId(); |
| 556 | - subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject json) -> { | |
| 580 | + subscribe.addSubscribe(hookSubscribe, (mediaServerItemInUse, hookParam) -> { | |
| 557 | 581 | logger.debug("sipc 添加订阅===callId {}",callId); |
| 558 | - hookEvent.response(mediaServerItemInUse, json); | |
| 582 | + hookEvent.response(mediaServerItemInUse, hookParam); | |
| 559 | 583 | subscribe.removeSubscribe(hookSubscribe); |
| 560 | 584 | hookSubscribe.getContent().put("regist", false); |
| 561 | 585 | hookSubscribe.getContent().put("schema", "rtsp"); |
| 562 | 586 | // 添加流注销的订阅,注销了后向设备发送bye |
| 563 | 587 | subscribe.addSubscribe(hookSubscribe, |
| 564 | - (MediaServerItem mediaServerItemForEnd, JSONObject jsonForEnd) -> { | |
| 588 | + (mediaServerItemForEnd, hookParam1) -> { | |
| 565 | 589 | logger.info("[录像]下载结束, 发送BYE"); |
| 566 | 590 | try { |
| 567 | 591 | streamByeCmd(device, channelId, ssrcInfo.getStream(), callId); |
| ... | ... | @@ -572,17 +596,13 @@ public class SIPCommander implements ISIPCommander { |
| 572 | 596 | }); |
| 573 | 597 | }); |
| 574 | 598 | |
| 575 | - Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, SipUtils.getNewFromTag(), null,newCallIdHeader, ssrcInfo.getSsrc()); | |
| 599 | + Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null,newCallIdHeader, ssrcInfo.getSsrc()); | |
| 576 | 600 | |
| 577 | 601 | sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent, event -> { |
| 578 | 602 | ResponseEvent responseEvent = (ResponseEvent) event.event; |
| 579 | 603 | SIPResponse response = (SIPResponse) responseEvent.getResponse(); |
| 580 | 604 | String contentString =new String(response.getRawContent()); |
| 581 | - int ssrcIndex = contentString.indexOf("y="); | |
| 582 | - String ssrc=ssrcInfo.getSsrc(); | |
| 583 | - if (ssrcIndex >= 0) { | |
| 584 | - ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); | |
| 585 | - } | |
| 605 | + String ssrc = SipUtils.getSsrcFromSdp(contentString); | |
| 586 | 606 | streamSession.put(device.getDeviceId(), channelId, response.getCallIdHeader().getCallId(), ssrcInfo.getStream(), ssrc, mediaServerItem.getId(), response, InviteSessionType.DOWNLOAD); |
| 587 | 607 | okEvent.response(event); |
| 588 | 608 | }); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
| ... | ... | @@ -230,59 +230,150 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 230 | 230 | // 行政区划分组只需要这两项就可以 |
| 231 | 231 | catalogXml.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n"); |
| 232 | 232 | catalogXml.append("<Name>" + channel.getName() + "</Name>\r\n"); |
| 233 | - if (channel.getParentId() != null) { | |
| 234 | - // 业务分组加上这一项即可,提高兼容性, | |
| 235 | - catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n"); | |
| 236 | -// catalogXml.append("<ParentID>" + parentPlatform.getDeviceGBId() + "/" + channel.getParentId() + "</ParentID>\r\n"); | |
| 237 | - } | |
| 238 | - if (channel.getChannelId().length() == 20 && Integer.parseInt(channel.getChannelId().substring(10, 13)) == 216) { | |
| 239 | - // 虚拟组织增加BusinessGroupID字段 | |
| 240 | - catalogXml.append("<BusinessGroupID>" + channel.getParentId() + "</BusinessGroupID>\r\n"); | |
| 241 | - } | |
| 242 | - if (!channel.getChannelId().equals(parentPlatform.getDeviceGBId())) { | |
| 243 | - catalogXml.append("<Parental>" + channel.getParental() + "</Parental>\r\n"); | |
| 244 | - if (channel.getParental() == 0) { | |
| 245 | - catalogXml.append("<Status>" + (channel.getStatus() == 0 ? "OFF" : "ON") + "</Status>\r\n"); | |
| 233 | + if (channel.getChannelId().length() <= 8) { | |
| 234 | + catalogXml.append("</Item>\r\n"); | |
| 235 | + continue; | |
| 236 | + }else { | |
| 237 | + if (channel.getChannelId().length() != 20) { | |
| 238 | + catalogXml.append("</Item>\r\n"); | |
| 239 | + continue; | |
| 246 | 240 | } |
| 247 | - } | |
| 248 | - if (channel.getParental() == 0) { | |
| 249 | - // 通道项 | |
| 250 | - catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n"); | |
| 251 | - catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n"); | |
| 252 | - catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n"); | |
| 253 | - String civilCode = channel.getCivilCode() == null?parentPlatform.getAdministrativeDivision() : channel.getCivilCode(); | |
| 254 | - if (channel.getChannelType() != 2) { // 业务分组/虚拟组织/行政区划 不设置以下属性 | |
| 255 | - catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n"); | |
| 256 | - catalogXml.append("<Owner>" + parentPlatform.getDeviceGBId()+ "</Owner>\r\n"); | |
| 257 | - catalogXml.append("<CivilCode>" + civilCode + "</CivilCode>\r\n"); | |
| 258 | - if (channel.getAddress() == null) { | |
| 259 | - catalogXml.append("<Address></Address>\r\n"); | |
| 260 | - }else { | |
| 261 | - catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n"); | |
| 262 | - } | |
| 263 | - catalogXml.append("<Block>" + channel.getBlock() + "</Block>\r\n"); | |
| 264 | - catalogXml.append("<SafetyWay>" + channel.getSafetyWay() + "</SafetyWay>\r\n"); | |
| 265 | - catalogXml.append("<CertNum>" + channel.getCertNum() + "</CertNum>\r\n"); | |
| 266 | - catalogXml.append("<Certifiable>" + channel.getCertifiable() + "</Certifiable>\r\n"); | |
| 267 | - catalogXml.append("<ErrCode>" + channel.getErrCode() + "</ErrCode>\r\n"); | |
| 268 | - catalogXml.append("<EndTime>" + channel.getEndTime() + "</EndTime>\r\n"); | |
| 269 | - catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n"); | |
| 270 | - catalogXml.append("<IPAddress>" + channel.getIpAddress() + "</IPAddress>\r\n"); | |
| 271 | - catalogXml.append("<Port>" + channel.getPort() + "</Port>\r\n"); | |
| 272 | - catalogXml.append("<Password>" + channel.getPort() + "</Password>\r\n"); | |
| 273 | - catalogXml.append("<PTZType>" + channel.getPTZType() + "</PTZType>\r\n"); | |
| 274 | - catalogXml.append("<Status>" + (channel.getStatus() == 1?"ON":"OFF") + "</Status>\r\n"); | |
| 275 | - catalogXml.append("<Longitude>" + | |
| 276 | - (channel.getLongitudeWgs84() != 0? channel.getLongitudeWgs84():channel.getLongitude()) | |
| 277 | - + "</Longitude>\r\n"); | |
| 278 | - catalogXml.append("<Latitude>" + | |
| 279 | - (channel.getLatitudeWgs84() != 0? channel.getLatitudeWgs84():channel.getLatitude()) | |
| 280 | - + "</Latitude>\r\n"); | |
| 281 | - | |
| 241 | + switch (Integer.parseInt(channel.getChannelId().substring(10, 13))){ | |
| 242 | + case 200: | |
| 243 | +// catalogXml.append("<Manufacturer>三永华通</Manufacturer>\r\n"); | |
| 244 | +// GitUtil gitUtil = SpringBeanFactory.getBean("gitUtil"); | |
| 245 | +// String model = (gitUtil == null || gitUtil.getBuildVersion() == null)?"1.0": gitUtil.getBuildVersion(); | |
| 246 | +// catalogXml.append("<Model>" + model + "</Manufacturer>\r\n"); | |
| 247 | +// catalogXml.append("<Owner>三永华通</Owner>\r\n"); | |
| 248 | + if (channel.getCivilCode() != null) { | |
| 249 | + catalogXml.append("<CivilCode>"+channel.getCivilCode()+"</CivilCode>\r\n"); | |
| 250 | + }else { | |
| 251 | + catalogXml.append("<CivilCode></CivilCode>\r\n"); | |
| 252 | + } | |
| 253 | + | |
| 254 | + catalogXml.append("<RegisterWay>1</RegisterWay>\r\n"); | |
| 255 | + catalogXml.append("<Secrecy>0</Secrecy>\r\n"); | |
| 256 | + break; | |
| 257 | + case 215: | |
| 258 | + if (!ObjectUtils.isEmpty(channel.getParentId())) { | |
| 259 | + catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n"); | |
| 260 | + } | |
| 261 | + | |
| 262 | + break; | |
| 263 | + case 216: | |
| 264 | + if (!ObjectUtils.isEmpty(channel.getParentId())) { | |
| 265 | + catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n"); | |
| 266 | + }else { | |
| 267 | + catalogXml.append("<ParentID></ParentID>\r\n"); | |
| 268 | + } | |
| 269 | + if (!ObjectUtils.isEmpty(channel.getBusinessGroupId())) { | |
| 270 | + catalogXml.append("<BusinessGroupID>" + channel.getBusinessGroupId() + "</BusinessGroupID>\r\n"); | |
| 271 | + }else { | |
| 272 | + catalogXml.append("<BusinessGroupID></BusinessGroupID>\r\n"); | |
| 273 | + } | |
| 274 | + break; | |
| 275 | + default: | |
| 276 | + // 通道项 | |
| 277 | + if (channel.getManufacture() != null) { | |
| 278 | + catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n"); | |
| 279 | + }else { | |
| 280 | + catalogXml.append("<Manufacturer></Manufacturer>\r\n"); | |
| 281 | + } | |
| 282 | + if (channel.getSecrecy() != null) { | |
| 283 | + catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n"); | |
| 284 | + }else { | |
| 285 | + catalogXml.append("<Secrecy></Secrecy>\r\n"); | |
| 286 | + } | |
| 287 | + catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n"); | |
| 288 | + if (channel.getModel() != null) { | |
| 289 | + catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n"); | |
| 290 | + }else { | |
| 291 | + catalogXml.append("<Model></Model>\r\n"); | |
| 292 | + } | |
| 293 | + if (channel.getOwner() != null) { | |
| 294 | + catalogXml.append("<Owner>" + channel.getOwner()+ "</Owner>\r\n"); | |
| 295 | + }else { | |
| 296 | + catalogXml.append("<Owner></Owner>\r\n"); | |
| 297 | + } | |
| 298 | + if (channel.getCivilCode() != null) { | |
| 299 | + catalogXml.append("<CivilCode>" + channel.getCivilCode() + "</CivilCode>\r\n"); | |
| 300 | + }else { | |
| 301 | + catalogXml.append("<CivilCode></CivilCode>\r\n"); | |
| 302 | + } | |
| 303 | + if (channel.getAddress() == null) { | |
| 304 | + catalogXml.append("<Address></Address>\r\n"); | |
| 305 | + }else { | |
| 306 | + catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n"); | |
| 307 | + } | |
| 308 | + if (!ObjectUtils.isEmpty(channel.getParentId())) { | |
| 309 | + catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n"); | |
| 310 | + }else { | |
| 311 | + catalogXml.append("<ParentID></ParentID>\r\n"); | |
| 312 | + } | |
| 313 | + if (!ObjectUtils.isEmpty(channel.getBlock())) { | |
| 314 | + catalogXml.append("<Block>" + channel.getBlock() + "</Block>\r\n"); | |
| 315 | + }else { | |
| 316 | + catalogXml.append("<Block></Block>\r\n"); | |
| 317 | + } | |
| 318 | + if (!ObjectUtils.isEmpty(channel.getSafetyWay())) { | |
| 319 | + catalogXml.append("<SafetyWay>" + channel.getSafetyWay() + "</SafetyWay>\r\n"); | |
| 320 | + }else { | |
| 321 | + catalogXml.append("<SafetyWay></SafetyWay>\r\n"); | |
| 322 | + } | |
| 323 | + if (!ObjectUtils.isEmpty(channel.getCertNum())) { | |
| 324 | + catalogXml.append("<CertNum>" + channel.getCertNum() + "</CertNum>\r\n"); | |
| 325 | + }else { | |
| 326 | + catalogXml.append("<CertNum></CertNum>\r\n"); | |
| 327 | + } | |
| 328 | + if (!ObjectUtils.isEmpty(channel.getCertifiable())) { | |
| 329 | + catalogXml.append("<Certifiable>" + channel.getCertifiable() + "</Certifiable>\r\n"); | |
| 330 | + }else { | |
| 331 | + catalogXml.append("<Certifiable></Certifiable>\r\n"); | |
| 332 | + } | |
| 333 | + if (!ObjectUtils.isEmpty(channel.getErrCode())) { | |
| 334 | + catalogXml.append("<ErrCode>" + channel.getErrCode() + "</ErrCode>\r\n"); | |
| 335 | + }else { | |
| 336 | + catalogXml.append("<ErrCode></ErrCode>\r\n"); | |
| 337 | + } | |
| 338 | + if (!ObjectUtils.isEmpty(channel.getEndTime())) { | |
| 339 | + catalogXml.append("<EndTime>" + channel.getEndTime() + "</EndTime>\r\n"); | |
| 340 | + }else { | |
| 341 | + catalogXml.append("<EndTime></EndTime>\r\n"); | |
| 342 | + } | |
| 343 | + if (!ObjectUtils.isEmpty(channel.getSecrecy())) { | |
| 344 | + catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n"); | |
| 345 | + }else { | |
| 346 | + catalogXml.append("<Secrecy></Secrecy>\r\n"); | |
| 347 | + } | |
| 348 | + if (!ObjectUtils.isEmpty(channel.getIpAddress())) { | |
| 349 | + catalogXml.append("<IPAddress>" + channel.getIpAddress() + "</IPAddress>\r\n"); | |
| 350 | + }else { | |
| 351 | + catalogXml.append("<IPAddress></IPAddress>\r\n"); | |
| 352 | + } | |
| 353 | + catalogXml.append("<Port>" + channel.getPort() + "</Port>\r\n"); | |
| 354 | + if (!ObjectUtils.isEmpty(channel.getPassword())) { | |
| 355 | + catalogXml.append("<Password>" + channel.getPassword() + "</Password>\r\n"); | |
| 356 | + }else { | |
| 357 | + catalogXml.append("<Password></Password>\r\n"); | |
| 358 | + } | |
| 359 | + if (!ObjectUtils.isEmpty(channel.getPTZType())) { | |
| 360 | + catalogXml.append("<PTZType>" + channel.getPTZType() + "</PTZType>\r\n"); | |
| 361 | + }else { | |
| 362 | + catalogXml.append("<PTZType></PTZType>\r\n"); | |
| 363 | + } | |
| 364 | + catalogXml.append("<Status>" + (channel.isStatus() ?"ON":"OFF") + "</Status>\r\n"); | |
| 365 | + | |
| 366 | + catalogXml.append("<Longitude>" + | |
| 367 | + (channel.getLongitudeWgs84() != 0? channel.getLongitudeWgs84():channel.getLongitude()) | |
| 368 | + + "</Longitude>\r\n"); | |
| 369 | + catalogXml.append("<Latitude>" + | |
| 370 | + (channel.getLatitudeWgs84() != 0? channel.getLatitudeWgs84():channel.getLatitude()) | |
| 371 | + + "</Latitude>\r\n"); | |
| 372 | + break; | |
| 282 | 373 | |
| 283 | 374 | } |
| 375 | + catalogXml.append("</Item>\r\n"); | |
| 284 | 376 | } |
| 285 | - catalogXml.append("</Item>\r\n"); | |
| 286 | 377 | } |
| 287 | 378 | } |
| 288 | 379 | |
| ... | ... | @@ -399,11 +490,11 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 399 | 490 | * @return |
| 400 | 491 | */ |
| 401 | 492 | @Override |
| 402 | - public void deviceStatusResponse(ParentPlatform parentPlatform,String channelId, String sn, String fromTag,int status) throws SipException, InvalidArgumentException, ParseException { | |
| 493 | + public void deviceStatusResponse(ParentPlatform parentPlatform,String channelId, String sn, String fromTag,boolean status) throws SipException, InvalidArgumentException, ParseException { | |
| 403 | 494 | if (parentPlatform == null) { |
| 404 | 495 | return ; |
| 405 | 496 | } |
| 406 | - String statusStr = (status==1)?"ONLINE":"OFFLINE"; | |
| 497 | + String statusStr = (status)?"ONLINE":"OFFLINE"; | |
| 407 | 498 | String characterSet = parentPlatform.getCharacterSet(); |
| 408 | 499 | StringBuffer deviceStatusXml = new StringBuffer(600); |
| 409 | 500 | deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n") |
| ... | ... | @@ -564,7 +655,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { |
| 564 | 655 | catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n") |
| 565 | 656 | .append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n") |
| 566 | 657 | .append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n") |
| 567 | - .append("<Status>" + (channel.getStatus() == 0 ? "OFF" : "ON") + "</Status>\r\n"); | |
| 658 | + .append("<Status>" + (channel.isStatus() ? "ON" : "OFF") + "</Status>\r\n"); | |
| 568 | 659 | |
| 569 | 660 | if (channel.getChannelType() != 2) { // 业务分组/虚拟组织/行政区划 不设置以下属性 |
| 570 | 661 | catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n") | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
| ... | ... | @@ -166,9 +166,8 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In |
| 166 | 166 | streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlay.getStream()); |
| 167 | 167 | } |
| 168 | 168 | InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId); |
| 169 | - | |
| 169 | + inviteStreamService.removeInviteInfo(inviteInfo); | |
| 170 | 170 | if (inviteInfo != null) { |
| 171 | - inviteStreamService.removeInviteInfo(inviteInfo); | |
| 172 | 171 | if (inviteInfo.getStreamInfo() != null) { |
| 173 | 172 | mediaServerService.closeRTPServer(inviteInfo.getStreamInfo().getMediaServerId(), inviteInfo.getStream()); |
| 174 | 173 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java
| ... | ... | @@ -22,11 +22,12 @@ import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| 22 | 22 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| 23 | 23 | import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; |
| 24 | 24 | import com.genersoft.iot.vmp.media.zlm.dto.*; |
| 25 | +import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; | |
| 25 | 26 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 26 | 27 | import com.genersoft.iot.vmp.service.IPlayService; |
| 27 | 28 | import com.genersoft.iot.vmp.service.IStreamProxyService; |
| 28 | 29 | import com.genersoft.iot.vmp.service.IStreamPushService; |
| 29 | -import com.genersoft.iot.vmp.service.bean.InviteErrorCallback; | |
| 30 | +import com.genersoft.iot.vmp.service.bean.ErrorCallback; | |
| 30 | 31 | import com.genersoft.iot.vmp.service.bean.InviteErrorCode; |
| 31 | 32 | import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; |
| 32 | 33 | import com.genersoft.iot.vmp.service.bean.SSRCInfo; |
| ... | ... | @@ -217,6 +218,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 217 | 218 | logger.error("[命令发送失败] invite GONE: {}", e.getMessage()); |
| 218 | 219 | } |
| 219 | 220 | return; |
| 221 | + }else { | |
| 222 | + // TODO 可能漏回复消息 | |
| 220 | 223 | } |
| 221 | 224 | } |
| 222 | 225 | } else { |
| ... | ... | @@ -270,18 +273,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 270 | 273 | // 解析sdp消息, 使用jainsip 自带的sdp解析方式 |
| 271 | 274 | String contentString = new String(request.getRawContent()); |
| 272 | 275 | |
| 273 | - // jainSip不支持y=字段, 移除以解析。 | |
| 274 | - // 检查是否有y字段 | |
| 275 | - int ssrcIndex = contentString.indexOf("y="); | |
| 276 | - | |
| 277 | - SessionDescription sdp; | |
| 278 | - if (ssrcIndex >= 0) { | |
| 279 | - //ssrc规定长度为10个字节,不取余下长度以避免后续还有“f=”字段 | |
| 280 | - String substring = contentString.substring(0, ssrcIndex); | |
| 281 | - sdp = SdpFactory.getInstance().createSessionDescription(substring); | |
| 282 | - } else { | |
| 283 | - sdp = SdpFactory.getInstance().createSessionDescription(contentString); | |
| 284 | - } | |
| 276 | + Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString); | |
| 277 | + SessionDescription sdp = gb28181Sdp.getBaseSdb(); | |
| 285 | 278 | String sessionName = sdp.getSessionName().getValue(); |
| 286 | 279 | |
| 287 | 280 | Long startTime = null; |
| ... | ... | @@ -369,11 +362,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 369 | 362 | } |
| 370 | 363 | |
| 371 | 364 | String ssrc; |
| 372 | - if (userSetting.getUseCustomSsrcForParentInvite() || ssrcIndex < 0) { | |
| 365 | + if (userSetting.getUseCustomSsrcForParentInvite() || gb28181Sdp.getSsrc() == null) { | |
| 373 | 366 | // 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 |
| 374 | 367 | ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId()); |
| 375 | - } else { | |
| 376 | - ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); | |
| 368 | + }else { | |
| 369 | + ssrc = gb28181Sdp.getSsrc(); | |
| 377 | 370 | } |
| 378 | 371 | String streamTypeStr = null; |
| 379 | 372 | if (mediaTransmissionTCP) { |
| ... | ... | @@ -406,8 +399,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 406 | 399 | |
| 407 | 400 | Long finalStartTime = startTime; |
| 408 | 401 | Long finalStopTime = stopTime; |
| 409 | - InviteErrorCallback<Object> hookEvent = (code, msg, data) -> { | |
| 410 | - StreamInfo streamInfo = (StreamInfo) data; | |
| 402 | + ErrorCallback<Object> hookEvent = (code, msg, data) -> { | |
| 403 | + StreamInfo streamInfo = (StreamInfo)data; | |
| 411 | 404 | MediaServerItem mediaServerItemInUSe = mediaServerService.getOne(streamInfo.getMediaServerId()); |
| 412 | 405 | logger.info("[上级Invite]下级已经开始推流。 回复200OK(SDP), {}/{}", streamInfo.getApp(), streamInfo.getStream()); |
| 413 | 406 | // * 0 等待设备推流上来 |
| ... | ... | @@ -460,7 +453,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 460 | 453 | logger.error("[命令发送失败] 国标级联 回复SdpAck", e); |
| 461 | 454 | } |
| 462 | 455 | }; |
| 463 | - InviteErrorCallback<Object> errorEvent = ((statusCode, msg, data) -> { | |
| 456 | + ErrorCallback<Object> errorEvent = ((statusCode, msg, data) -> { | |
| 464 | 457 | // 未知错误。直接转发设备点播的错误 |
| 465 | 458 | try { |
| 466 | 459 | if (statusCode > 0) { |
| ... | ... | @@ -547,11 +540,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 547 | 540 | } else if (gbStream != null) { |
| 548 | 541 | |
| 549 | 542 | String ssrc; |
| 550 | - if (userSetting.getUseCustomSsrcForParentInvite() || ssrcIndex < 0) { | |
| 543 | + if (userSetting.getUseCustomSsrcForParentInvite() || gb28181Sdp.getSsrc() == null) { | |
| 551 | 544 | // 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 |
| 552 | 545 | ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId()); |
| 553 | - } else { | |
| 554 | - ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); | |
| 546 | + }else { | |
| 547 | + ssrc = gb28181Sdp.getSsrc(); | |
| 555 | 548 | } |
| 556 | 549 | |
| 557 | 550 | if ("push".equals(gbStream.getStreamType())) { |
| ... | ... | @@ -690,10 +683,9 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 690 | 683 | logger.info("[ app={}, stream={} ]通道未推流,启用流后开始推流", gbStream.getApp(), gbStream.getStream()); |
| 691 | 684 | // 监听流上线 |
| 692 | 685 | HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed(gbStream.getApp(), gbStream.getStream(), true, "rtsp", mediaServerItem.getId()); |
| 693 | - zlmHttpHookSubscribe.addSubscribe(hookSubscribe, (mediaServerItemInUSe, responseJSON) -> { | |
| 694 | - String app = responseJSON.getString("app"); | |
| 695 | - String stream = responseJSON.getString("stream"); | |
| 696 | - logger.info("[上级点播]拉流代理已经就绪, {}/{}", app, stream); | |
| 686 | + zlmHttpHookSubscribe.addSubscribe(hookSubscribe, (mediaServerItemInUSe, hookParam) -> { | |
| 687 | + OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam)hookParam; | |
| 688 | + logger.info("[上级点播]拉流代理已经就绪, {}/{}", streamChangedHookParam.getApp(), streamChangedHookParam.getStream()); | |
| 697 | 689 | dynamicTask.stop(callIdHeader.getCallId()); |
| 698 | 690 | pushProxyStream(evt, request, gbStream, platform, callIdHeader, mediaServerItem, port, tcpActive, |
| 699 | 691 | mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId); |
| ... | ... | @@ -971,20 +963,11 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements |
| 971 | 963 | } |
| 972 | 964 | String contentString = new String(request.getRawContent()); |
| 973 | 965 | // jainSip不支持y=字段, 移除移除以解析。 |
| 974 | - String substring = contentString; | |
| 975 | 966 | String ssrc = "0000000404"; |
| 976 | - int ssrcIndex = contentString.indexOf("y="); | |
| 977 | - if (ssrcIndex > 0) { | |
| 978 | - substring = contentString.substring(0, ssrcIndex); | |
| 979 | - ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12).trim(); | |
| 980 | - } | |
| 981 | - ssrcIndex = substring.indexOf("f="); | |
| 982 | - if (ssrcIndex > 0) { | |
| 983 | - substring = contentString.substring(0, ssrcIndex); | |
| 984 | - } | |
| 985 | - try { | |
| 986 | - SessionDescription sdp = SdpFactory.getInstance().createSessionDescription(substring); | |
| 987 | 967 | |
| 968 | + try { | |
| 969 | + Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString); | |
| 970 | + SessionDescription sdp = gb28181Sdp.getBaseSdb(); | |
| 988 | 971 | // 获取支持的格式 |
| 989 | 972 | Vector mediaDescriptions = sdp.getMediaDescriptions(true); |
| 990 | 973 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestForCatalogProcessor.java
| 1 | 1 | package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; |
| 2 | 2 | |
| 3 | +import com.genersoft.iot.vmp.conf.CivilCodeFileConf; | |
| 3 | 4 | import com.genersoft.iot.vmp.conf.DynamicTask; |
| 4 | 5 | import com.genersoft.iot.vmp.conf.UserSetting; |
| 5 | 6 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| ... | ... | @@ -20,7 +21,10 @@ import org.springframework.stereotype.Component; |
| 20 | 21 | |
| 21 | 22 | import javax.sip.RequestEvent; |
| 22 | 23 | import javax.sip.header.FromHeader; |
| 23 | -import java.util.*; | |
| 24 | +import java.util.ArrayList; | |
| 25 | +import java.util.Iterator; | |
| 26 | +import java.util.List; | |
| 27 | +import java.util.Map; | |
| 24 | 28 | import java.util.concurrent.ConcurrentHashMap; |
| 25 | 29 | import java.util.concurrent.CopyOnWriteArrayList; |
| 26 | 30 | |
| ... | ... | @@ -56,6 +60,9 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent |
| 56 | 60 | @Autowired |
| 57 | 61 | private DynamicTask dynamicTask; |
| 58 | 62 | |
| 63 | + @Autowired | |
| 64 | + private CivilCodeFileConf civilCodeFileConf; | |
| 65 | + | |
| 59 | 66 | private final static String talkKey = "notify-request-for-catalog-task"; |
| 60 | 67 | |
| 61 | 68 | public void process(RequestEvent evt) { |
| ... | ... | @@ -65,7 +72,7 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent |
| 65 | 72 | String deviceId = SipUtils.getUserIdFromFromHeader(fromHeader); |
| 66 | 73 | |
| 67 | 74 | Device device = redisCatchStorage.getDevice(deviceId); |
| 68 | - if (device == null || device.getOnline() == 0) { | |
| 75 | + if (device == null || !device.isOnLine()) { | |
| 69 | 76 | logger.warn("[收到目录订阅]:{}, 但是设备已经离线", (device != null ? device.getDeviceId():"" )); |
| 70 | 77 | return; |
| 71 | 78 | } |
| ... | ... | @@ -96,7 +103,7 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent |
| 96 | 103 | }else { |
| 97 | 104 | event = eventElement.getText().toUpperCase(); |
| 98 | 105 | } |
| 99 | - DeviceChannel channel = XmlUtil.channelContentHander(itemDevice, device, event); | |
| 106 | + DeviceChannel channel = XmlUtil.channelContentHandler(itemDevice, device, event, civilCodeFileConf); | |
| 100 | 107 | |
| 101 | 108 | channel.setDeviceId(device.getDeviceId()); |
| 102 | 109 | logger.info("[收到目录订阅]:{}/{}", device.getDeviceId(), channel.getChannelId()); |
| ... | ... | @@ -175,6 +182,11 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent |
| 175 | 182 | } |
| 176 | 183 | }else { |
| 177 | 184 | addChannelMap.put(channel.getChannelId(), channel); |
| 185 | + if (userSetting.getDeviceStatusNotify()) { | |
| 186 | + // 发送redis消息 | |
| 187 | + redisCatchStorage.sendChannelAddOrDelete(device.getDeviceId(), channel.getChannelId(), true); | |
| 188 | + } | |
| 189 | + | |
| 178 | 190 | if (addChannelMap.keySet().size() > 300) { |
| 179 | 191 | executeSaveForAdd(); |
| 180 | 192 | } |
| ... | ... | @@ -185,6 +197,10 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent |
| 185 | 197 | // 删除 |
| 186 | 198 | logger.info("[收到删除通道通知] 来自设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId()); |
| 187 | 199 | deleteChannelList.add(channel); |
| 200 | + if (userSetting.getDeviceStatusNotify()) { | |
| 201 | + // 发送redis消息 | |
| 202 | + redisCatchStorage.sendChannelAddOrDelete(device.getDeviceId(), channel.getChannelId(), false); | |
| 203 | + } | |
| 188 | 204 | if (deleteChannelList.size() > 300) { |
| 189 | 205 | executeSaveForDelete(); |
| 190 | 206 | } |
| ... | ... | @@ -205,6 +221,10 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent |
| 205 | 221 | if (addChannelMap.keySet().size() > 300) { |
| 206 | 222 | executeSaveForAdd(); |
| 207 | 223 | } |
| 224 | + if (userSetting.getDeviceStatusNotify()) { | |
| 225 | + // 发送redis消息 | |
| 226 | + redisCatchStorage.sendChannelAddOrDelete(device.getDeviceId(), channel.getChannelId(), true); | |
| 227 | + } | |
| 208 | 228 | } |
| 209 | 229 | break; |
| 210 | 230 | default: |
| ... | ... | @@ -232,7 +252,6 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent |
| 232 | 252 | } |
| 233 | 253 | |
| 234 | 254 | private void executeSave(){ |
| 235 | - System.out.println("定时存储数据"); | |
| 236 | 255 | executeSaveForUpdate(); |
| 237 | 256 | executeSaveForDelete(); |
| 238 | 257 | executeSaveForOnline(); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java
| 1 | 1 | package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; |
| 2 | 2 | |
| 3 | 3 | import com.alibaba.fastjson2.JSONObject; |
| 4 | +import com.genersoft.iot.vmp.conf.CivilCodeFileConf; | |
| 4 | 5 | import com.genersoft.iot.vmp.conf.SipConfig; |
| 5 | 6 | import com.genersoft.iot.vmp.conf.UserSetting; |
| 6 | 7 | import com.genersoft.iot.vmp.gb28181.bean.*; |
| ... | ... | @@ -79,6 +80,9 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements |
| 79 | 80 | @Autowired |
| 80 | 81 | private NotifyRequestForCatalogProcessor notifyRequestForCatalogProcessor; |
| 81 | 82 | |
| 83 | + @Autowired | |
| 84 | + private CivilCodeFileConf civilCodeFileConf; | |
| 85 | + | |
| 82 | 86 | private ConcurrentLinkedQueue<HandlerCatchData> taskQueue = new ConcurrentLinkedQueue<>(); |
| 83 | 87 | |
| 84 | 88 | @Qualifier("taskExecutor") |
| ... | ... | @@ -192,7 +196,12 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements |
| 192 | 196 | mobilePosition.setDeviceId(device.getDeviceId()); |
| 193 | 197 | mobilePosition.setChannelId(channelId); |
| 194 | 198 | String time = XmlUtil.getText(rootElement, "Time"); |
| 195 | - mobilePosition.setTime(time); | |
| 199 | + if (ObjectUtils.isEmpty(time)){ | |
| 200 | + mobilePosition.setTime(DateUtil.getNow()); | |
| 201 | + }else { | |
| 202 | + mobilePosition.setTime(SipUtils.parseTime(time)); | |
| 203 | + } | |
| 204 | + | |
| 196 | 205 | mobilePosition.setLongitude(Double.parseDouble(XmlUtil.getText(rootElement, "Longitude"))); |
| 197 | 206 | mobilePosition.setLatitude(Double.parseDouble(XmlUtil.getText(rootElement, "Latitude"))); |
| 198 | 207 | if (NumericUtil.isDouble(XmlUtil.getText(rootElement, "Speed"))) { |
| ... | ... | @@ -237,7 +246,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements |
| 237 | 246 | |
| 238 | 247 | // 发送redis消息。 通知位置信息的变化 |
| 239 | 248 | JSONObject jsonObject = new JSONObject(); |
| 240 | - jsonObject.put("time", time); | |
| 249 | + jsonObject.put("time", DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(mobilePosition.getTime())); | |
| 241 | 250 | jsonObject.put("serial", deviceId); |
| 242 | 251 | jsonObject.put("code", channelId); |
| 243 | 252 | jsonObject.put("longitude", mobilePosition.getLongitude()); |
| ... | ... | @@ -339,7 +348,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements |
| 339 | 348 | storager.updateChannelPosition(deviceChannel); |
| 340 | 349 | // 发送redis消息。 通知位置信息的变化 |
| 341 | 350 | JSONObject jsonObject = new JSONObject(); |
| 342 | - jsonObject.put("time", mobilePosition.getTime()); | |
| 351 | + jsonObject.put("time", DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(mobilePosition.getTime())); | |
| 343 | 352 | jsonObject.put("serial", deviceChannel.getDeviceId()); |
| 344 | 353 | jsonObject.put("code", deviceChannel.getChannelId()); |
| 345 | 354 | jsonObject.put("longitude", mobilePosition.getLongitude()); |
| ... | ... | @@ -372,7 +381,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements |
| 372 | 381 | String deviceId = SipUtils.getUserIdFromFromHeader(fromHeader); |
| 373 | 382 | |
| 374 | 383 | Device device = redisCatchStorage.getDevice(deviceId); |
| 375 | - if (device == null || device.getOnline() == 0) { | |
| 384 | + if (device == null || !device.isOnLine()) { | |
| 376 | 385 | logger.warn("[收到目录订阅]:{}, 但是设备已经离线", (device != null ? device.getDeviceId():"" )); |
| 377 | 386 | return; |
| 378 | 387 | } |
| ... | ... | @@ -403,7 +412,7 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements |
| 403 | 412 | }else { |
| 404 | 413 | event = eventElement.getText().toUpperCase(); |
| 405 | 414 | } |
| 406 | - DeviceChannel channel = XmlUtil.channelContentHander(itemDevice, device, event); | |
| 415 | + DeviceChannel channel = XmlUtil.channelContentHandler(itemDevice, device, event, civilCodeFileConf); | |
| 407 | 416 | channel.setDeviceId(device.getDeviceId()); |
| 408 | 417 | logger.info("[收到目录订阅]:{}/{}", device.getDeviceId(), channel.getChannelId()); |
| 409 | 418 | switch (event) { | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java
| ... | ... | @@ -167,9 +167,8 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen |
| 167 | 167 | device.setStreamMode("UDP"); |
| 168 | 168 | device.setCharset("GB2312"); |
| 169 | 169 | device.setGeoCoordSys("WGS84"); |
| 170 | - device.setTreeType("CivilCode"); | |
| 171 | 170 | device.setDeviceId(deviceId); |
| 172 | - device.setOnline(0); | |
| 171 | + device.setOnLine(false); | |
| 173 | 172 | } |
| 174 | 173 | device.setIp(remoteAddressInfo.getIp()); |
| 175 | 174 | device.setPort(remoteAddressInfo.getPort()); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java
| ... | ... | @@ -164,7 +164,7 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme |
| 164 | 164 | |
| 165 | 165 | // 发送redis消息。 通知位置信息的变化 |
| 166 | 166 | JSONObject jsonObject = new JSONObject(); |
| 167 | - jsonObject.put("time", mobilePosition.getTime()); | |
| 167 | + jsonObject.put("time", DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(mobilePosition.getTime())); | |
| 168 | 168 | jsonObject.put("serial", deviceChannel.getDeviceId()); |
| 169 | 169 | jsonObject.put("code", deviceChannel.getChannelId()); |
| 170 | 170 | jsonObject.put("longitude", mobilePosition.getLongitude()); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java
| ... | ... | @@ -83,12 +83,12 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp |
| 83 | 83 | |
| 84 | 84 | device.setKeepaliveTime(DateUtil.getNow()); |
| 85 | 85 | |
| 86 | - if (device.getOnline() == 1) { | |
| 86 | + if (device.isOnLine()) { | |
| 87 | 87 | deviceService.updateDevice(device); |
| 88 | 88 | }else { |
| 89 | 89 | // 对于已经离线的设备判断他的注册是否已经过期 |
| 90 | 90 | if (!deviceService.expire(device)){ |
| 91 | - device.setOnline(0); | |
| 91 | + device.setOnLine(false); | |
| 92 | 92 | deviceService.online(device, null); |
| 93 | 93 | } |
| 94 | 94 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MobilePositionNotifyMessageHandler.java
| ... | ... | @@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorP |
| 7 | 7 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; |
| 8 | 8 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; |
| 9 | 9 | import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; |
| 10 | +import com.genersoft.iot.vmp.gb28181.utils.SipUtils; | |
| 10 | 11 | import com.genersoft.iot.vmp.service.IDeviceChannelService; |
| 11 | 12 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 12 | 13 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| ... | ... | @@ -95,7 +96,12 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen |
| 95 | 96 | } |
| 96 | 97 | mobilePosition.setDeviceId(sipMsgInfo.getDevice().getDeviceId()); |
| 97 | 98 | mobilePosition.setChannelId(getText(rootElementAfterCharset, "DeviceID")); |
| 98 | - mobilePosition.setTime(getText(rootElementAfterCharset, "Time")); | |
| 99 | + String time = getText(rootElementAfterCharset, "Time"); | |
| 100 | + if (ObjectUtils.isEmpty(time)){ | |
| 101 | + mobilePosition.setTime(DateUtil.getNow()); | |
| 102 | + }else { | |
| 103 | + mobilePosition.setTime(SipUtils.parseTime(time)); | |
| 104 | + } | |
| 99 | 105 | mobilePosition.setLongitude(Double.parseDouble(getText(rootElementAfterCharset, "Longitude"))); |
| 100 | 106 | mobilePosition.setLatitude(Double.parseDouble(getText(rootElementAfterCharset, "Latitude"))); |
| 101 | 107 | if (NumericUtil.isDouble(getText(rootElementAfterCharset, "Speed"))) { |
| ... | ... | @@ -138,7 +144,7 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen |
| 138 | 144 | |
| 139 | 145 | // 发送redis消息。 通知位置信息的变化 |
| 140 | 146 | JSONObject jsonObject = new JSONObject(); |
| 141 | - jsonObject.put("time", mobilePosition.getTime()); | |
| 147 | + jsonObject.put("time", DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(mobilePosition.getTime())); | |
| 142 | 148 | jsonObject.put("serial", deviceChannel.getDeviceId()); |
| 143 | 149 | jsonObject.put("code", deviceChannel.getChannelId()); |
| 144 | 150 | jsonObject.put("longitude", mobilePosition.getLongitude()); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/DeviceStatusQueryMessageHandler.java
| ... | ... | @@ -77,7 +77,7 @@ public class DeviceStatusQueryMessageHandler extends SIPRequestProcessorParent i |
| 77 | 77 | return; |
| 78 | 78 | } |
| 79 | 79 | try { |
| 80 | - cmderFroPlatform.deviceStatusResponse(parentPlatform,channelId, sn, fromHeader.getTag(),deviceChannel.getStatus()); | |
| 80 | + cmderFroPlatform.deviceStatusResponse(parentPlatform,channelId, sn, fromHeader.getTag(),deviceChannel.isStatus()); | |
| 81 | 81 | } catch (SipException | InvalidArgumentException | ParseException e) { |
| 82 | 82 | logger.error("[命令发送失败] 国标级联 DeviceStatus查询回复: {}", e.getMessage()); |
| 83 | 83 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java
| 1 | 1 | package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd; |
| 2 | 2 | |
| 3 | +import com.genersoft.iot.vmp.conf.CivilCodeFileConf; | |
| 3 | 4 | import com.genersoft.iot.vmp.gb28181.bean.*; |
| 4 | 5 | import com.genersoft.iot.vmp.gb28181.session.CatalogDataCatch; |
| 5 | 6 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; |
| ... | ... | @@ -54,6 +55,9 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp |
| 54 | 55 | @Autowired |
| 55 | 56 | private ThreadPoolTaskExecutor taskExecutor; |
| 56 | 57 | |
| 58 | + @Autowired | |
| 59 | + private CivilCodeFileConf civilCodeFileConf; | |
| 60 | + | |
| 57 | 61 | @Override |
| 58 | 62 | public void afterPropertiesSet() throws Exception { |
| 59 | 63 | responseMessageHandler.addHandler(cmdType, this); |
| ... | ... | @@ -101,6 +105,7 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp |
| 101 | 105 | Iterator<Element> deviceListIterator = deviceListElement.elementIterator(); |
| 102 | 106 | if (deviceListIterator != null) { |
| 103 | 107 | List<DeviceChannel> channelList = new ArrayList<>(); |
| 108 | + List<String> parentChannelIds = new ArrayList<>(); | |
| 104 | 109 | // 遍历DeviceList |
| 105 | 110 | while (deviceListIterator.hasNext()) { |
| 106 | 111 | Element itemDevice = deviceListIterator.next(); |
| ... | ... | @@ -108,7 +113,7 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp |
| 108 | 113 | if (channelDeviceElement == null) { |
| 109 | 114 | continue; |
| 110 | 115 | } |
| 111 | - DeviceChannel deviceChannel = XmlUtil.channelContentHander(itemDevice, device, null); | |
| 116 | + DeviceChannel deviceChannel = XmlUtil.channelContentHandler(itemDevice, device, null, civilCodeFileConf); | |
| 112 | 117 | deviceChannel = SipUtils.updateGps(deviceChannel, device.getGeoCoordSys()); |
| 113 | 118 | deviceChannel.setDeviceId(take.getDevice().getDeviceId()); |
| 114 | 119 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/DeviceInfoResponseMessageHandler.java
| 1 | 1 | package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd; |
| 2 | 2 | |
| 3 | -import com.genersoft.iot.vmp.common.VideoManagerConstants; | |
| 4 | -import com.genersoft.iot.vmp.conf.SipConfig; | |
| 5 | 3 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 6 | 4 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 7 | -import com.genersoft.iot.vmp.gb28181.event.EventPublisher; | |
| 8 | 5 | import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; |
| 9 | 6 | import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; |
| 10 | 7 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; |
| 11 | 8 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; |
| 12 | 9 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler; |
| 13 | 10 | import com.genersoft.iot.vmp.service.IDeviceService; |
| 14 | -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; | |
| 15 | -import com.genersoft.iot.vmp.storager.IVideoManagerStorage; | |
| 16 | 11 | import gov.nist.javax.sip.message.SIPRequest; |
| 17 | 12 | import org.dom4j.DocumentException; |
| 18 | 13 | import org.dom4j.Element; |
| ... | ... | @@ -59,7 +54,7 @@ public class DeviceInfoResponseMessageHandler extends SIPRequestProcessorParent |
| 59 | 54 | public void handForDevice(RequestEvent evt, Device device, Element rootElement) { |
| 60 | 55 | logger.debug("接收到DeviceInfo应答消息"); |
| 61 | 56 | // 检查设备是否存在, 不存在则不回复 |
| 62 | - if (device == null || device.getOnline() == 0) { | |
| 57 | + if (device == null || !device.isOnLine()) { | |
| 63 | 58 | logger.warn("[接收到DeviceInfo应答消息,但是设备已经离线]:" + (device != null ? device.getDeviceId():"" )); |
| 64 | 59 | return; |
| 65 | 60 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/MobilePositionResponseMessageHandler.java
| ... | ... | @@ -2,17 +2,21 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.respon |
| 2 | 2 | |
| 3 | 3 | import com.alibaba.fastjson2.JSONObject; |
| 4 | 4 | import com.genersoft.iot.vmp.conf.UserSetting; |
| 5 | -import com.genersoft.iot.vmp.gb28181.bean.*; | |
| 5 | +import com.genersoft.iot.vmp.gb28181.bean.Device; | |
| 6 | +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; | |
| 7 | +import com.genersoft.iot.vmp.gb28181.bean.MobilePosition; | |
| 8 | +import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; | |
| 9 | +import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; | |
| 10 | +import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; | |
| 6 | 11 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; |
| 7 | 12 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; |
| 8 | 13 | import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler; |
| 9 | -import com.genersoft.iot.vmp.gb28181.utils.Coordtransform; | |
| 10 | 14 | import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; |
| 15 | +import com.genersoft.iot.vmp.gb28181.utils.SipUtils; | |
| 11 | 16 | import com.genersoft.iot.vmp.service.IDeviceChannelService; |
| 12 | 17 | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| 13 | 18 | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| 14 | 19 | import com.genersoft.iot.vmp.utils.DateUtil; |
| 15 | -import com.genersoft.iot.vmp.utils.GpsUtil; | |
| 16 | 20 | import gov.nist.javax.sip.message.SIPRequest; |
| 17 | 21 | import org.dom4j.DocumentException; |
| 18 | 22 | import org.dom4j.Element; |
| ... | ... | @@ -56,6 +60,9 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar |
| 56 | 60 | @Autowired |
| 57 | 61 | private IDeviceChannelService deviceChannelService; |
| 58 | 62 | |
| 63 | + @Autowired | |
| 64 | + private DeferredResultHolder resultHolder; | |
| 65 | + | |
| 59 | 66 | @Override |
| 60 | 67 | public void afterPropertiesSet() throws Exception { |
| 61 | 68 | responseMessageHandler.addHandler(cmdType, this); |
| ... | ... | @@ -83,7 +90,13 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar |
| 83 | 90 | } |
| 84 | 91 | mobilePosition.setDeviceId(device.getDeviceId()); |
| 85 | 92 | mobilePosition.setChannelId(getText(rootElement, "DeviceID")); |
| 86 | - mobilePosition.setTime(getText(rootElement, "Time")); | |
| 93 | + //兼容ISO 8601格式时间 | |
| 94 | + String time = getText(rootElement, "Time"); | |
| 95 | + if (ObjectUtils.isEmpty(time)){ | |
| 96 | + mobilePosition.setTime(DateUtil.getNow()); | |
| 97 | + }else { | |
| 98 | + mobilePosition.setTime(SipUtils.parseTime(time)); | |
| 99 | + } | |
| 87 | 100 | mobilePosition.setLongitude(Double.parseDouble(getText(rootElement, "Longitude"))); |
| 88 | 101 | mobilePosition.setLatitude(Double.parseDouble(getText(rootElement, "Latitude"))); |
| 89 | 102 | if (NumericUtil.isDouble(getText(rootElement, "Speed"))) { |
| ... | ... | @@ -121,11 +134,18 @@ public class MobilePositionResponseMessageHandler extends SIPRequestProcessorPar |
| 121 | 134 | if (userSetting.getSavePositionHistory()) { |
| 122 | 135 | storager.insertMobilePosition(mobilePosition); |
| 123 | 136 | } |
| 137 | + | |
| 124 | 138 | storager.updateChannelPosition(deviceChannel); |
| 125 | 139 | |
| 140 | + String key = DeferredResultHolder.CALLBACK_CMD_MOBILE_POSITION + device.getDeviceId(); | |
| 141 | + RequestMessage msg = new RequestMessage(); | |
| 142 | + msg.setKey(key); | |
| 143 | + msg.setData(mobilePosition); | |
| 144 | + resultHolder.invokeAllResult(msg); | |
| 145 | + | |
| 126 | 146 | // 发送redis消息。 通知位置信息的变化 |
| 127 | 147 | JSONObject jsonObject = new JSONObject(); |
| 128 | - jsonObject.put("time", mobilePosition.getTime()); | |
| 148 | + jsonObject.put("time", DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(mobilePosition.getTime())); | |
| 129 | 149 | jsonObject.put("serial", deviceChannel.getDeviceId()); |
| 130 | 150 | jsonObject.put("code", deviceChannel.getChannelId()); |
| 131 | 151 | jsonObject.put("longitude", mobilePosition.getLongitude()); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/InviteResponseProcessor.java
| 1 | 1 | package com.genersoft.iot.vmp.gb28181.transmit.event.response.impl; |
| 2 | 2 | |
| 3 | 3 | import com.genersoft.iot.vmp.gb28181.SipLayer; |
| 4 | +import com.genersoft.iot.vmp.gb28181.bean.Gb28181Sdp; | |
| 4 | 5 | import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; |
| 5 | 6 | import com.genersoft.iot.vmp.gb28181.transmit.SIPSender; |
| 6 | 7 | import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; |
| 7 | 8 | import com.genersoft.iot.vmp.gb28181.transmit.event.response.SIPResponseProcessorAbstract; |
| 9 | +import com.genersoft.iot.vmp.gb28181.utils.SipUtils; | |
| 8 | 10 | import gov.nist.javax.sip.ResponseEventExt; |
| 9 | 11 | import gov.nist.javax.sip.message.SIPResponse; |
| 10 | 12 | import org.slf4j.Logger; |
| ... | ... | @@ -12,7 +14,6 @@ import org.slf4j.LoggerFactory; |
| 12 | 14 | import org.springframework.beans.factory.annotation.Autowired; |
| 13 | 15 | import org.springframework.stereotype.Component; |
| 14 | 16 | |
| 15 | -import javax.sdp.SdpFactory; | |
| 16 | 17 | import javax.sdp.SdpParseException; |
| 17 | 18 | import javax.sdp.SessionDescription; |
| 18 | 19 | import javax.sip.InvalidArgumentException; |
| ... | ... | @@ -82,19 +83,8 @@ public class InviteResponseProcessor extends SIPResponseProcessorAbstract { |
| 82 | 83 | ResponseEventExt event = (ResponseEventExt)evt; |
| 83 | 84 | |
| 84 | 85 | String contentString = new String(response.getRawContent()); |
| 85 | - // jainSip不支持y=字段, 移除以解析。 | |
| 86 | - int ssrcIndex = contentString.indexOf("y="); | |
| 87 | - // 检查是否有y字段 | |
| 88 | - SessionDescription sdp; | |
| 89 | - if (ssrcIndex >= 0) { | |
| 90 | - //ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段 | |
| 91 | - String substring = contentString.substring(0, contentString.indexOf("y=")); | |
| 92 | - sdp = SdpFactory.getInstance().createSessionDescription(substring); | |
| 93 | - } else { | |
| 94 | - sdp = SdpFactory.getInstance().createSessionDescription(contentString); | |
| 95 | - } | |
| 96 | - // 查看是否是来自设备的,此是回复 | |
| 97 | - | |
| 86 | + Gb28181Sdp gb28181Sdp = SipUtils.parseSDP(contentString); | |
| 87 | + SessionDescription sdp = gb28181Sdp.getBaseSdb(); | |
| 98 | 88 | SipURI requestUri = SipFactory.getInstance().createAddressFactory().createSipURI(sdp.getOrigin().getUsername(), event.getRemoteIpAddress() + ":" + event.getRemotePort()); |
| 99 | 89 | Request reqAck = headerProvider.createAckRequest(response.getLocalAddress().getHostAddress(), requestUri, response); |
| 100 | 90 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/response/impl/RegisterResponseProcessor.java
| ... | ... | @@ -102,7 +102,7 @@ public class RegisterResponseProcessor extends SIPResponseProcessorAbstract { |
| 102 | 102 | SipTransactionInfo sipTransactionInfo = new SipTransactionInfo(response); |
| 103 | 103 | platformService.online(parentPlatform, sipTransactionInfo); |
| 104 | 104 | }else { |
| 105 | - platformService.offline(parentPlatform, false); | |
| 105 | + platformService.offline(parentPlatform, true); | |
| 106 | 106 | } |
| 107 | 107 | |
| 108 | 108 | // 注册/注销成功移除缓存的信息 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java
| 1 | 1 | package com.genersoft.iot.vmp.gb28181.utils; |
| 2 | 2 | |
| 3 | 3 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| 4 | +import com.genersoft.iot.vmp.gb28181.bean.Gb28181Sdp; | |
| 4 | 5 | import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo; |
| 6 | +import com.genersoft.iot.vmp.utils.DateUtil; | |
| 5 | 7 | import com.genersoft.iot.vmp.utils.GitUtil; |
| 6 | 8 | import gov.nist.javax.sip.address.AddressImpl; |
| 7 | 9 | import gov.nist.javax.sip.address.SipUri; |
| 8 | 10 | import gov.nist.javax.sip.header.Subject; |
| 9 | 11 | import gov.nist.javax.sip.message.SIPRequest; |
| 12 | +import org.apache.commons.lang3.RandomStringUtils; | |
| 13 | +import org.slf4j.Logger; | |
| 14 | +import org.slf4j.LoggerFactory; | |
| 10 | 15 | import org.springframework.util.ObjectUtils; |
| 11 | 16 | |
| 17 | +import javax.sdp.SdpFactory; | |
| 18 | +import javax.sdp.SdpParseException; | |
| 19 | +import javax.sdp.SessionDescription; | |
| 12 | 20 | import javax.sip.PeerUnavailableException; |
| 13 | 21 | import javax.sip.SipFactory; |
| 14 | 22 | import javax.sip.header.FromHeader; |
| ... | ... | @@ -16,6 +24,8 @@ import javax.sip.header.Header; |
| 16 | 24 | import javax.sip.header.UserAgentHeader; |
| 17 | 25 | import javax.sip.message.Request; |
| 18 | 26 | import java.text.ParseException; |
| 27 | +import java.time.LocalDateTime; | |
| 28 | +import java.time.format.DateTimeParseException; | |
| 19 | 29 | import java.util.ArrayList; |
| 20 | 30 | import java.util.List; |
| 21 | 31 | import java.util.UUID; |
| ... | ... | @@ -28,6 +38,8 @@ import java.util.UUID; |
| 28 | 38 | */ |
| 29 | 39 | public class SipUtils { |
| 30 | 40 | |
| 41 | + private final static Logger logger = LoggerFactory.getLogger(SipUtils.class); | |
| 42 | + | |
| 31 | 43 | public static String getUserIdFromFromHeader(Request request) { |
| 32 | 44 | FromHeader fromHeader = (FromHeader)request.getHeader(FromHeader.NAME); |
| 33 | 45 | return getUserIdFromFromHeader(fromHeader); |
| ... | ... | @@ -51,7 +63,7 @@ public class SipUtils { |
| 51 | 63 | } |
| 52 | 64 | |
| 53 | 65 | public static String getNewViaTag() { |
| 54 | - return "z9hG4bK" + System.currentTimeMillis(); | |
| 66 | + return "z9hG4bK" + RandomStringUtils.randomNumeric(10); | |
| 55 | 67 | } |
| 56 | 68 | |
| 57 | 69 | public static UserAgentHeader createUserAgentHeader(GitUtil gitUtil) throws PeerUnavailableException, ParseException { |
| ... | ... | @@ -113,6 +125,12 @@ public class SipUtils { |
| 113 | 125 | strTmp = String.format("%02X", moveSpeed); |
| 114 | 126 | builder.append(strTmp, 0, 2); |
| 115 | 127 | builder.append(strTmp, 0, 2); |
| 128 | + | |
| 129 | + //优化zoom低倍速下的变倍速率 | |
| 130 | + if ((zoomSpeed > 0) && (zoomSpeed <16)) | |
| 131 | + { | |
| 132 | + zoomSpeed = 16; | |
| 133 | + } | |
| 116 | 134 | strTmp = String.format("%X", zoomSpeed); |
| 117 | 135 | builder.append(strTmp, 0, 1).append("0"); |
| 118 | 136 | //计算校验码 |
| ... | ... | @@ -203,4 +221,66 @@ public class SipUtils { |
| 203 | 221 | } |
| 204 | 222 | return deviceChannel; |
| 205 | 223 | } |
| 224 | + | |
| 225 | + public static Gb28181Sdp parseSDP(String sdpStr) throws SdpParseException { | |
| 226 | + | |
| 227 | + // jainSip不支持y= f=字段, 移除以解析。 | |
| 228 | + int ssrcIndex = sdpStr.indexOf("y="); | |
| 229 | + int mediaDescriptionIndex = sdpStr.indexOf("f="); | |
| 230 | + // 检查是否有y字段 | |
| 231 | + SessionDescription sdp; | |
| 232 | + String ssrc = null; | |
| 233 | + String mediaDescription = null; | |
| 234 | + if (mediaDescriptionIndex == 0 && ssrcIndex == 0) { | |
| 235 | + sdp = SdpFactory.getInstance().createSessionDescription(sdpStr); | |
| 236 | + }else { | |
| 237 | + String lines[] = sdpStr.split("\\r?\\n"); | |
| 238 | + StringBuilder sdpBuffer = new StringBuilder(); | |
| 239 | + for (String line : lines) { | |
| 240 | + if (line.trim().startsWith("y=")) { | |
| 241 | + ssrc = line.substring(2); | |
| 242 | + }else if (line.trim().startsWith("f=")) { | |
| 243 | + mediaDescription = line.substring(2); | |
| 244 | + }else { | |
| 245 | + sdpBuffer.append(line.trim()).append("\r\n"); | |
| 246 | + } | |
| 247 | + } | |
| 248 | + sdp = SdpFactory.getInstance().createSessionDescription(sdpBuffer.toString()); | |
| 249 | + } | |
| 250 | + return Gb28181Sdp.getInstance(sdp, ssrc, mediaDescription); | |
| 251 | + } | |
| 252 | + | |
| 253 | + public static String getSsrcFromSdp(String sdpStr) { | |
| 254 | + | |
| 255 | + // jainSip不支持y= f=字段, 移除以解析。 | |
| 256 | + int ssrcIndex = sdpStr.indexOf("y="); | |
| 257 | + if (ssrcIndex == 0) { | |
| 258 | + return null; | |
| 259 | + } | |
| 260 | + String lines[] = sdpStr.split("\\r?\\n"); | |
| 261 | + for (String line : lines) { | |
| 262 | + if (line.trim().startsWith("y=")) { | |
| 263 | + return line.substring(2); | |
| 264 | + } | |
| 265 | + } | |
| 266 | + return null; | |
| 267 | + } | |
| 268 | + | |
| 269 | + public static String parseTime(String timeStr) { | |
| 270 | + if (ObjectUtils.isEmpty(timeStr)){ | |
| 271 | + return null; | |
| 272 | + } | |
| 273 | + LocalDateTime localDateTime; | |
| 274 | + try { | |
| 275 | + localDateTime = LocalDateTime.parse(timeStr); | |
| 276 | + }catch (DateTimeParseException e) { | |
| 277 | + try { | |
| 278 | + localDateTime = LocalDateTime.parse(timeStr, DateUtil.formatterISO8601); | |
| 279 | + }catch (DateTimeParseException e2) { | |
| 280 | + logger.error("[格式化时间] 无法格式化时间: {}", timeStr); | |
| 281 | + return null; | |
| 282 | + } | |
| 283 | + } | |
| 284 | + return localDateTime.format(DateUtil.formatterISO8601); | |
| 285 | + } | |
| 206 | 286 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/utils/XmlUtil.java
| ... | ... | @@ -2,6 +2,8 @@ package com.genersoft.iot.vmp.gb28181.utils; |
| 2 | 2 | |
| 3 | 3 | import com.alibaba.fastjson2.JSONArray; |
| 4 | 4 | import com.alibaba.fastjson2.JSONObject; |
| 5 | +import com.genersoft.iot.vmp.common.CivilCodePo; | |
| 6 | +import com.genersoft.iot.vmp.conf.CivilCodeFileConf; | |
| 5 | 7 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 6 | 8 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| 7 | 9 | import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; |
| ... | ... | @@ -192,7 +194,7 @@ public class XmlUtil { |
| 192 | 194 | CivilCode, BusinessGroup,VirtualOrganization,Other |
| 193 | 195 | } |
| 194 | 196 | |
| 195 | - public static DeviceChannel channelContentHander(Element itemDevice, Device device, String event){ | |
| 197 | + public static DeviceChannel channelContentHandler(Element itemDevice, Device device, String event, CivilCodeFileConf civilCodeFileConf){ | |
| 196 | 198 | DeviceChannel deviceChannel = new DeviceChannel(); |
| 197 | 199 | deviceChannel.setDeviceId(device.getDeviceId()); |
| 198 | 200 | Element channdelIdElement = itemDevice.element("DeviceID"); |
| ... | ... | @@ -210,208 +212,353 @@ public class XmlUtil { |
| 210 | 212 | // 除了ADD和update情况下需要识别全部内容, |
| 211 | 213 | return deviceChannel; |
| 212 | 214 | } |
| 213 | - | |
| 214 | - ChannelType channelType = ChannelType.Other; | |
| 215 | - if (channelId.length() <= 8) { | |
| 216 | - channelType = ChannelType.CivilCode; | |
| 215 | + Element nameElement = itemDevice.element("Name"); | |
| 216 | + if (nameElement != null) { | |
| 217 | + deviceChannel.setName(nameElement.getText()); | |
| 218 | + } | |
| 219 | + if(channelId.length() <= 8) { | |
| 217 | 220 | deviceChannel.setHasAudio(false); |
| 221 | + CivilCodePo parentCode = civilCodeFileConf.getParentCode(channelId); | |
| 222 | + if (parentCode != null) { | |
| 223 | + deviceChannel.setParentId(parentCode.getCode()); | |
| 224 | + deviceChannel.setCivilCode(parentCode.getCode()); | |
| 225 | + }else { | |
| 226 | + logger.warn("[xml解析] 无法确定行政区划{}的上级行政区划", channelId); | |
| 227 | + } | |
| 228 | + deviceChannel.setStatus(true); | |
| 229 | + return deviceChannel; | |
| 218 | 230 | }else { |
| 219 | - if (channelId.length() == 20) { | |
| 220 | - int code = Integer.parseInt(channelId.substring(10, 13)); | |
| 221 | - switch (code){ | |
| 222 | - case 215: | |
| 223 | - channelType = ChannelType.BusinessGroup; | |
| 224 | - deviceChannel.setHasAudio(false); | |
| 225 | - break; | |
| 226 | - case 216: | |
| 227 | - channelType = ChannelType.VirtualOrganization; | |
| 228 | - deviceChannel.setHasAudio(false); | |
| 229 | - break; | |
| 230 | - case 136: | |
| 231 | - case 137: | |
| 232 | - case 138: | |
| 233 | - deviceChannel.setHasAudio(true); | |
| 234 | - break; | |
| 235 | - default: | |
| 236 | - deviceChannel.setHasAudio(false); | |
| 237 | - break; | |
| 238 | - | |
| 239 | - } | |
| 231 | + if(channelId.length() != 20) { | |
| 232 | + logger.warn("[xml解析] 失败,编号不符合国标28181定义: {}", channelId); | |
| 233 | + return null; | |
| 240 | 234 | } |
| 241 | - } | |
| 242 | 235 | |
| 243 | - Element channdelNameElement = itemDevice.element("Name"); | |
| 244 | - String channelName = channdelNameElement != null ? channdelNameElement.getTextTrim() : ""; | |
| 245 | - deviceChannel.setName(channelName); | |
| 246 | - | |
| 247 | - String civilCode = XmlUtil.getText(itemDevice, "CivilCode"); | |
| 248 | - deviceChannel.setCivilCode(civilCode); | |
| 249 | - if (channelType == ChannelType.CivilCode && civilCode == null) { | |
| 250 | - deviceChannel.setParental(1); | |
| 251 | - // 行政区划如果没有传递具体值,则推测一个 | |
| 252 | - if (channelId.length() > 2) { | |
| 253 | - deviceChannel.setCivilCode(channelId.substring(0, channelId.length() - 2)); | |
| 254 | - } | |
| 255 | - } | |
| 256 | - if (channelType.equals(ChannelType.CivilCode)) { | |
| 257 | - // 行政区划其他字段没必要识别了,默认在线即可 | |
| 258 | - deviceChannel.setStatus(1); | |
| 259 | - deviceChannel.setParental(1); | |
| 260 | - deviceChannel.setCreateTime(DateUtil.getNow()); | |
| 261 | - deviceChannel.setUpdateTime(DateUtil.getNow()); | |
| 262 | - return deviceChannel; | |
| 263 | - } | |
| 264 | - /** | |
| 265 | - * 行政区划展示设备树与业务分组展示设备树是两种不同的模式 | |
| 266 | - * 行政区划展示设备树 各个目录之间主要靠deviceId做关联,摄像头通过CivilCode指定其属于那个行政区划;都是不超过十位的编号; 结构如下: | |
| 267 | - * 河北省 | |
| 268 | - * --> 石家庄市 | |
| 269 | - * --> 摄像头 | |
| 270 | - *String parentId = XmlUtil.getText(itemDevice, "ParentID"); | |
| 271 | - if (parentId != null) { | |
| 272 | - if (parentId.contains("/")) { | |
| 273 | - String lastParentId = parentId.substring(parentId.lastIndexOf("/") + 1); | |
| 274 | - String businessGroup = parentId.substring(0, parentId.indexOf("/")); | |
| 275 | - deviceChannel.setParentId(lastParentId); | |
| 276 | - }else { | |
| 277 | - deviceChannel.setParentId(parentId); | |
| 278 | - } | |
| 279 | - } | |
| 280 | - deviceCh --> 正定县 | |
| 281 | - * --> 摄像头 | |
| 282 | - * --> 摄像头 | |
| 283 | - * | |
| 284 | - * 业务分组展示设备树是顶级是业务分组,其下的虚拟组织靠BusinessGroupID指定其所属的业务分组;摄像头通过ParentId来指定其所属于的虚拟组织: | |
| 285 | - * 业务分组 | |
| 286 | - * --> 虚拟组织 | |
| 287 | - * --> 摄像头 | |
| 288 | - * --> 虚拟组织 | |
| 289 | - * --> 摄像头 | |
| 290 | - * --> 摄像头 | |
| 291 | - */ | |
| 292 | - String parentId = XmlUtil.getText(itemDevice, "ParentID"); | |
| 293 | - String businessGroupID = XmlUtil.getText(itemDevice, "BusinessGroupID"); | |
| 294 | - if (parentId != null) { | |
| 295 | - if (parentId.contains("/")) { | |
| 296 | - String lastParentId = parentId.substring(parentId.lastIndexOf("/") + 1); | |
| 297 | - if (businessGroupID == null) { | |
| 298 | - businessGroupID = parentId.substring(0, parentId.indexOf("/")); | |
| 299 | - } | |
| 300 | - deviceChannel.setParentId(lastParentId); | |
| 236 | + int code = Integer.parseInt(channelId.substring(10, 13)); | |
| 237 | + if (code == 136 || code == 137 || code == 138) { | |
| 238 | + deviceChannel.setHasAudio(true); | |
| 301 | 239 | }else { |
| 302 | - deviceChannel.setParentId(parentId); | |
| 240 | + deviceChannel.setHasAudio(false); | |
| 303 | 241 | } |
| 304 | - // 兼容设备通道信息中自己为自己父节点的情况 | |
| 305 | - if (deviceChannel.getParentId().equals(deviceChannel.getChannelId())) { | |
| 306 | - deviceChannel.setParentId(null); | |
| 242 | + // 设备厂商 | |
| 243 | + String manufacturer = getText(itemDevice, "Manufacturer"); | |
| 244 | + // 设备型号 | |
| 245 | + String model = getText(itemDevice, "Model"); | |
| 246 | + // 设备归属 | |
| 247 | + String owner = getText(itemDevice, "Owner"); | |
| 248 | + // 行政区域 | |
| 249 | + String civilCode = getText(itemDevice, "CivilCode"); | |
| 250 | + // 虚拟组织所属的业务分组ID,业务分组根据特定的业务需求制定,一个业务分组包含一组特定的虚拟组织 | |
| 251 | + String businessGroupID = getText(itemDevice, "BusinessGroupID"); | |
| 252 | + // 父设备/区域/系统ID | |
| 253 | + String parentID = getText(itemDevice, "ParentID"); | |
| 254 | + if (parentID != null && parentID.equalsIgnoreCase("null")) { | |
| 255 | + parentID = null; | |
| 307 | 256 | } |
| 308 | - } | |
| 309 | - deviceChannel.setBusinessGroupId(businessGroupID); | |
| 310 | - if (channelType.equals(ChannelType.BusinessGroup) || channelType.equals(ChannelType.VirtualOrganization)) { | |
| 311 | - // 业务分组和虚拟组织 其他字段没必要识别了,默认在线即可 | |
| 312 | - deviceChannel.setStatus(1); | |
| 313 | - deviceChannel.setParental(1); | |
| 314 | - deviceChannel.setCreateTime(DateUtil.getNow()); | |
| 315 | - deviceChannel.setUpdateTime(DateUtil.getNow()); | |
| 316 | - return deviceChannel; | |
| 317 | - } | |
| 257 | + // 注册方式(必选)缺省为1;1:符合IETFRFC3261标准的认证注册模式;2:基于口令的双向认证注册模式;3:基于数字证书的双向认证注册模式 | |
| 258 | + String registerWay = getText(itemDevice, "RegisterWay"); | |
| 259 | + // 保密属性(必选)缺省为0;0:不涉密,1:涉密 | |
| 260 | + String secrecy = getText(itemDevice, "Secrecy"); | |
| 261 | + // 安装地址 | |
| 262 | + String address = getText(itemDevice, "Address"); | |
| 263 | + | |
| 264 | + switch (code){ | |
| 265 | + case 200: | |
| 266 | + // 系统目录 | |
| 267 | + if (!ObjectUtils.isEmpty(manufacturer)) { | |
| 268 | + deviceChannel.setManufacture(manufacturer); | |
| 269 | + } | |
| 270 | + if (!ObjectUtils.isEmpty(model)) { | |
| 271 | + deviceChannel.setModel(model); | |
| 272 | + } | |
| 273 | + if (!ObjectUtils.isEmpty(owner)) { | |
| 274 | + deviceChannel.setOwner(owner); | |
| 275 | + } | |
| 276 | + if (!ObjectUtils.isEmpty(civilCode)) { | |
| 277 | + deviceChannel.setCivilCode(civilCode); | |
| 278 | + deviceChannel.setParentId(civilCode); | |
| 279 | + }else { | |
| 280 | + if (!ObjectUtils.isEmpty(parentID)) { | |
| 281 | + deviceChannel.setParentId(parentID); | |
| 282 | + } | |
| 283 | + } | |
| 284 | + if (!ObjectUtils.isEmpty(address)) { | |
| 285 | + deviceChannel.setAddress(address); | |
| 286 | + } | |
| 287 | + deviceChannel.setStatus(true); | |
| 288 | + if (!ObjectUtils.isEmpty(registerWay)) { | |
| 289 | + try { | |
| 290 | + deviceChannel.setRegisterWay(Integer.parseInt(registerWay)); | |
| 291 | + }catch (NumberFormatException exception) { | |
| 292 | + logger.warn("[xml解析] 从通道数据获取registerWay失败: {}", registerWay); | |
| 293 | + } | |
| 294 | + } | |
| 295 | + if (!ObjectUtils.isEmpty(secrecy)) { | |
| 296 | + deviceChannel.setSecrecy(secrecy); | |
| 297 | + } | |
| 298 | + return deviceChannel; | |
| 299 | + case 215: | |
| 300 | + // 业务分组 | |
| 301 | + deviceChannel.setStatus(true); | |
| 302 | + if (!ObjectUtils.isEmpty(parentID)) { | |
| 303 | + if (!parentID.trim().equalsIgnoreCase(device.getDeviceId())) { | |
| 304 | + deviceChannel.setParentId(parentID); | |
| 305 | + } | |
| 306 | + }else { | |
| 307 | + logger.warn("[xml解析] 业务分组数据中缺少关键信息->ParentId"); | |
| 308 | + if (!ObjectUtils.isEmpty(civilCode)) { | |
| 309 | + deviceChannel.setCivilCode(civilCode); | |
| 310 | + } | |
| 311 | + } | |
| 312 | + break; | |
| 313 | + case 216: | |
| 314 | + // 虚拟组织 | |
| 315 | + deviceChannel.setStatus(true); | |
| 316 | + if (!ObjectUtils.isEmpty(businessGroupID)) { | |
| 317 | + deviceChannel.setBusinessGroupId(businessGroupID); | |
| 318 | + } | |
| 318 | 319 | |
| 319 | - Element statusElement = itemDevice.element("Status"); | |
| 320 | 320 | |
| 321 | - if (statusElement != null) { | |
| 322 | - String status = statusElement.getTextTrim().trim(); | |
| 323 | - // ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理 | |
| 324 | - if (status.equals("ON") || status.equals("On") || status.equals("ONLINE") || status.equals("OK")) { | |
| 325 | - deviceChannel.setStatus(1); | |
| 326 | - } | |
| 327 | - if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) { | |
| 328 | - deviceChannel.setStatus(0); | |
| 329 | - } | |
| 330 | - }else { | |
| 331 | - deviceChannel.setStatus(1); | |
| 332 | - } | |
| 333 | - // 识别自带的目录标识 | |
| 334 | - String parental = XmlUtil.getText(itemDevice, "Parental"); | |
| 335 | - // 由于海康会错误的发送65535作为这里的取值,所以这里除非是0否则认为是1 | |
| 336 | - if (!ObjectUtils.isEmpty(parental) && parental.length() == 1 && Integer.parseInt(parental) == 0) { | |
| 337 | - deviceChannel.setParental(0); | |
| 338 | - }else { | |
| 339 | - deviceChannel.setParental(1); | |
| 340 | - } | |
| 321 | + if (!ObjectUtils.isEmpty(parentID)) { | |
| 322 | + if (parentID.contains("/")) { | |
| 323 | + String[] parentIdArray = parentID.split("/"); | |
| 324 | + parentID = parentIdArray[parentIdArray.length - 1]; | |
| 325 | + } | |
| 326 | + deviceChannel.setParentId(parentID); | |
| 327 | + }else { | |
| 328 | + if (!ObjectUtils.isEmpty(businessGroupID)) { | |
| 329 | + deviceChannel.setParentId(businessGroupID); | |
| 330 | + } | |
| 331 | + } | |
| 332 | + break; | |
| 333 | + default: | |
| 334 | + // 设备目录 | |
| 335 | + if (!ObjectUtils.isEmpty(manufacturer)) { | |
| 336 | + deviceChannel.setManufacture(manufacturer); | |
| 337 | + } | |
| 338 | + if (!ObjectUtils.isEmpty(model)) { | |
| 339 | + deviceChannel.setModel(model); | |
| 340 | + } | |
| 341 | + if (!ObjectUtils.isEmpty(owner)) { | |
| 342 | + deviceChannel.setOwner(owner); | |
| 343 | + } | |
| 344 | + if (!ObjectUtils.isEmpty(civilCode)) { | |
| 345 | + deviceChannel.setCivilCode(civilCode); | |
| 346 | + } | |
| 347 | + if (!ObjectUtils.isEmpty(businessGroupID)) { | |
| 348 | + deviceChannel.setBusinessGroupId(businessGroupID); | |
| 349 | + } | |
| 341 | 350 | |
| 351 | + // 警区 | |
| 352 | + String block = getText(itemDevice, "Block"); | |
| 353 | + if (!ObjectUtils.isEmpty(block)) { | |
| 354 | + deviceChannel.setBlock(block); | |
| 355 | + } | |
| 356 | + if (!ObjectUtils.isEmpty(address)) { | |
| 357 | + deviceChannel.setAddress(address); | |
| 358 | + } | |
| 342 | 359 | |
| 343 | - deviceChannel.setManufacture(XmlUtil.getText(itemDevice, "Manufacturer")); | |
| 344 | - deviceChannel.setModel(XmlUtil.getText(itemDevice, "Model")); | |
| 345 | - deviceChannel.setOwner(XmlUtil.getText(itemDevice, "Owner")); | |
| 346 | - deviceChannel.setCertNum(XmlUtil.getText(itemDevice, "CertNum")); | |
| 347 | - deviceChannel.setBlock(XmlUtil.getText(itemDevice, "Block")); | |
| 348 | - deviceChannel.setAddress(XmlUtil.getText(itemDevice, "Address")); | |
| 349 | - deviceChannel.setPassword(XmlUtil.getText(itemDevice, "Password")); | |
| 360 | + if (!ObjectUtils.isEmpty(secrecy)) { | |
| 361 | + deviceChannel.setSecrecy(secrecy); | |
| 362 | + } | |
| 350 | 363 | |
| 351 | - String safetyWay = XmlUtil.getText(itemDevice, "SafetyWay"); | |
| 352 | - if (ObjectUtils.isEmpty(safetyWay)) { | |
| 353 | - deviceChannel.setSafetyWay(0); | |
| 354 | - } else { | |
| 355 | - deviceChannel.setSafetyWay(Integer.parseInt(safetyWay)); | |
| 356 | - } | |
| 364 | + // 当为设备时,是否有子设备(必选)1有,0没有 | |
| 365 | + String parental = getText(itemDevice, "Parental"); | |
| 366 | + if (!ObjectUtils.isEmpty(parental)) { | |
| 367 | + try { | |
| 368 | + // 由于海康会错误的发送65535作为这里的取值,所以这里除非是0否则认为是1 | |
| 369 | + if (!ObjectUtils.isEmpty(parental) && parental.length() == 1 && Integer.parseInt(parental) == 0) { | |
| 370 | + deviceChannel.setParental(0); | |
| 371 | + }else { | |
| 372 | + deviceChannel.setParental(1); | |
| 373 | + } | |
| 374 | + }catch (NumberFormatException e) { | |
| 375 | + logger.warn("[xml解析] 从通道数据获取 parental失败: {}", parental); | |
| 376 | + } | |
| 377 | + } | |
| 378 | + // 父设备/区域/系统ID | |
| 379 | + String realParentId = parentID; | |
| 380 | + if (!ObjectUtils.isEmpty(parentID)) { | |
| 381 | + if (parentID.contains("/")) { | |
| 382 | + String[] parentIdArray = parentID.split("/"); | |
| 383 | + realParentId = parentIdArray[parentIdArray.length - 1]; | |
| 384 | + } | |
| 385 | + deviceChannel.setParentId(realParentId); | |
| 386 | + }else { | |
| 387 | + if (!ObjectUtils.isEmpty(businessGroupID)) { | |
| 388 | + deviceChannel.setParentId(businessGroupID); | |
| 389 | + }else { | |
| 390 | + if (!ObjectUtils.isEmpty(civilCode)) { | |
| 391 | + deviceChannel.setParentId(civilCode); | |
| 392 | + } | |
| 393 | + } | |
| 394 | + } | |
| 395 | + // 注册方式 | |
| 396 | + if (!ObjectUtils.isEmpty(registerWay)) { | |
| 397 | + try { | |
| 398 | + int registerWayInt = Integer.parseInt(registerWay); | |
| 399 | + deviceChannel.setRegisterWay(registerWayInt); | |
| 400 | + }catch (NumberFormatException exception) { | |
| 401 | + logger.warn("[xml解析] 从通道数据获取registerWay失败: {}", registerWay); | |
| 402 | + deviceChannel.setRegisterWay(1); | |
| 403 | + } | |
| 404 | + }else { | |
| 405 | + deviceChannel.setRegisterWay(1); | |
| 406 | + } | |
| 357 | 407 | |
| 358 | - String registerWay = XmlUtil.getText(itemDevice, "RegisterWay"); | |
| 359 | - if (ObjectUtils.isEmpty(registerWay)) { | |
| 360 | - deviceChannel.setRegisterWay(1); | |
| 361 | - } else { | |
| 362 | - deviceChannel.setRegisterWay(Integer.parseInt(registerWay)); | |
| 363 | - } | |
| 408 | + // 信令安全模式(可选)缺省为0; 0:不采用;2:S/MIME 签名方式;3:S/MIME加密签名同时采用方式;4:数字摘要方式 | |
| 409 | + String safetyWay = getText(itemDevice, "SafetyWay"); | |
| 410 | + if (!ObjectUtils.isEmpty(safetyWay)) { | |
| 411 | + try { | |
| 412 | + deviceChannel.setSafetyWay(Integer.parseInt(safetyWay)); | |
| 413 | + }catch (NumberFormatException e) { | |
| 414 | + logger.warn("[xml解析] 从通道数据获取 safetyWay失败: {}", safetyWay); | |
| 415 | + } | |
| 416 | + } | |
| 364 | 417 | |
| 365 | - if (XmlUtil.getText(itemDevice, "Certifiable") == null | |
| 366 | - || XmlUtil.getText(itemDevice, "Certifiable") == "") { | |
| 367 | - deviceChannel.setCertifiable(0); | |
| 368 | - } else { | |
| 369 | - deviceChannel.setCertifiable(Integer.parseInt(XmlUtil.getText(itemDevice, "Certifiable"))); | |
| 370 | - } | |
| 418 | + // 证书序列号(有证书的设备必选) | |
| 419 | + String certNum = getText(itemDevice, "CertNum"); | |
| 420 | + if (!ObjectUtils.isEmpty(certNum)) { | |
| 421 | + deviceChannel.setCertNum(certNum); | |
| 422 | + } | |
| 371 | 423 | |
| 372 | - if (XmlUtil.getText(itemDevice, "ErrCode") == null | |
| 373 | - || XmlUtil.getText(itemDevice, "ErrCode") == "") { | |
| 374 | - deviceChannel.setErrCode(0); | |
| 375 | - } else { | |
| 376 | - deviceChannel.setErrCode(Integer.parseInt(XmlUtil.getText(itemDevice, "ErrCode"))); | |
| 377 | - } | |
| 424 | + // 证书有效标识(有证书的设备必选)缺省为0;证书有效标识:0:无效 1:有效 | |
| 425 | + String certifiable = getText(itemDevice, "Certifiable"); | |
| 426 | + if (!ObjectUtils.isEmpty(certifiable)) { | |
| 427 | + try { | |
| 428 | + deviceChannel.setCertifiable(Integer.parseInt(certifiable)); | |
| 429 | + }catch (NumberFormatException e) { | |
| 430 | + logger.warn("[xml解析] 从通道数据获取 Certifiable失败: {}", certifiable); | |
| 431 | + } | |
| 432 | + } | |
| 378 | 433 | |
| 379 | - deviceChannel.setEndTime(XmlUtil.getText(itemDevice, "EndTime")); | |
| 380 | - deviceChannel.setSecrecy(XmlUtil.getText(itemDevice, "Secrecy")); | |
| 381 | - deviceChannel.setIpAddress(XmlUtil.getText(itemDevice, "IPAddress")); | |
| 382 | - if (XmlUtil.getText(itemDevice, "Port") == null || XmlUtil.getText(itemDevice, "Port") == "") { | |
| 383 | - deviceChannel.setPort(0); | |
| 384 | - } else { | |
| 385 | - deviceChannel.setPort(Integer.parseInt(XmlUtil.getText(itemDevice, "Port"))); | |
| 386 | - } | |
| 434 | + // 无效原因码(有证书且证书无效的设备必选) | |
| 435 | + String errCode = getText(itemDevice, "ErrCode"); | |
| 436 | + if (!ObjectUtils.isEmpty(errCode)) { | |
| 437 | + try { | |
| 438 | + deviceChannel.setErrCode(Integer.parseInt(errCode)); | |
| 439 | + }catch (NumberFormatException e) { | |
| 440 | + logger.warn("[xml解析] 从通道数据获取 ErrCode失败: {}", errCode); | |
| 441 | + } | |
| 442 | + } | |
| 387 | 443 | |
| 444 | + // 证书终止有效期(有证书的设备必选) | |
| 445 | + String endTime = getText(itemDevice, "EndTime"); | |
| 446 | + if (!ObjectUtils.isEmpty(endTime)) { | |
| 447 | + deviceChannel.setEndTime(endTime); | |
| 448 | + } | |
| 388 | 449 | |
| 389 | - String longitude = XmlUtil.getText(itemDevice, "Longitude"); | |
| 390 | - if (NumericUtil.isDouble(longitude)) { | |
| 391 | - deviceChannel.setLongitude(Double.parseDouble(longitude)); | |
| 392 | - } else { | |
| 393 | - deviceChannel.setLongitude(0.00); | |
| 394 | - } | |
| 395 | - String latitude = XmlUtil.getText(itemDevice, "Latitude"); | |
| 396 | - if (NumericUtil.isDouble(latitude)) { | |
| 397 | - deviceChannel.setLatitude(Double.parseDouble(latitude)); | |
| 398 | - } else { | |
| 399 | - deviceChannel.setLatitude(0.00); | |
| 400 | - } | |
| 401 | 450 | |
| 402 | - deviceChannel.setGpsTime(DateUtil.getNow()); | |
| 451 | + // 设备/区域/系统IP地址 | |
| 452 | + String ipAddress = getText(itemDevice, "IPAddress"); | |
| 453 | + if (!ObjectUtils.isEmpty(ipAddress)) { | |
| 454 | + deviceChannel.setIpAddress(ipAddress); | |
| 455 | + } | |
| 456 | + | |
| 457 | + // 设备/区域/系统端口 | |
| 458 | + String port = getText(itemDevice, "Port"); | |
| 459 | + if (!ObjectUtils.isEmpty(port)) { | |
| 460 | + try { | |
| 461 | + deviceChannel.setPort(Integer.parseInt(port)); | |
| 462 | + }catch (NumberFormatException e) { | |
| 463 | + logger.warn("[xml解析] 从通道数据获取 Port失败: {}", port); | |
| 464 | + } | |
| 465 | + } | |
| 466 | + | |
| 467 | + // 设备口令 | |
| 468 | + String password = getText(itemDevice, "Password"); | |
| 469 | + if (!ObjectUtils.isEmpty(password)) { | |
| 470 | + deviceChannel.setPassword(password); | |
| 471 | + } | |
| 403 | 472 | |
| 404 | 473 | |
| 405 | - if (XmlUtil.getText(itemDevice, "PTZType") == null || "".equals(XmlUtil.getText(itemDevice, "PTZType"))) { | |
| 406 | - //兼容INFO中的信息 | |
| 407 | - Element info = itemDevice.element("Info"); | |
| 408 | - if(XmlUtil.getText(info, "PTZType") == null || "".equals(XmlUtil.getText(info, "PTZType"))){ | |
| 409 | - deviceChannel.setPTZType(0); | |
| 410 | - }else{ | |
| 411 | - deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(info, "PTZType"))); | |
| 474 | + // 设备状态 | |
| 475 | + String status = getText(itemDevice, "Status"); | |
| 476 | + if (status != null) { | |
| 477 | + // ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理 | |
| 478 | + if (status.equals("ON") || status.equals("On") || status.equals("ONLINE") || status.equals("OK")) { | |
| 479 | + deviceChannel.setStatus(true); | |
| 480 | + } | |
| 481 | + if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) { | |
| 482 | + deviceChannel.setStatus(false); | |
| 483 | + } | |
| 484 | + }else { | |
| 485 | + deviceChannel.setStatus(true); | |
| 486 | + } | |
| 487 | + | |
| 488 | + // 经度 | |
| 489 | + String longitude = getText(itemDevice, "Longitude"); | |
| 490 | + if (NumericUtil.isDouble(longitude)) { | |
| 491 | + deviceChannel.setLongitude(Double.parseDouble(longitude)); | |
| 492 | + } else { | |
| 493 | + deviceChannel.setLongitude(0.00); | |
| 494 | + } | |
| 495 | + | |
| 496 | + // 纬度 | |
| 497 | + String latitude = getText(itemDevice, "Latitude"); | |
| 498 | + if (NumericUtil.isDouble(latitude)) { | |
| 499 | + deviceChannel.setLatitude(Double.parseDouble(latitude)); | |
| 500 | + } else { | |
| 501 | + deviceChannel.setLatitude(0.00); | |
| 502 | + } | |
| 503 | + | |
| 504 | + deviceChannel.setGpsTime(DateUtil.getNow()); | |
| 505 | + | |
| 506 | + // -摄像机类型扩展,标识摄像机类型:1-球机;2-半球;3-固定枪机;4-遥控枪机。当目录项为摄像机时可选 | |
| 507 | + String ptzType = getText(itemDevice, "PTZType"); | |
| 508 | + if (ObjectUtils.isEmpty(ptzType)) { | |
| 509 | + //兼容INFO中的信息 | |
| 510 | + Element info = itemDevice.element("Info"); | |
| 511 | + String ptzTypeFromInfo = XmlUtil.getText(info, "PTZType"); | |
| 512 | + if(!ObjectUtils.isEmpty(ptzTypeFromInfo)){ | |
| 513 | + try { | |
| 514 | + deviceChannel.setPTZType(Integer.parseInt(ptzTypeFromInfo)); | |
| 515 | + }catch (NumberFormatException e){ | |
| 516 | + logger.warn("[xml解析] 从通道数据info中获取PTZType失败: {}", ptzTypeFromInfo); | |
| 517 | + } | |
| 518 | + } | |
| 519 | + } else { | |
| 520 | + try { | |
| 521 | + deviceChannel.setPTZType(Integer.parseInt(ptzType)); | |
| 522 | + }catch (NumberFormatException e){ | |
| 523 | + logger.warn("[xml解析] 从通道数据中获取PTZType失败: {}", ptzType); | |
| 524 | + } | |
| 525 | + } | |
| 526 | + | |
| 527 | + // TODO 摄像机位置类型扩展。 | |
| 528 | + // 1-省际检查站、 | |
| 529 | + // 2-党政机关、 | |
| 530 | + // 3-车站码头、 | |
| 531 | + // 4-中心广场、 | |
| 532 | + // 5-体育场馆、 | |
| 533 | + // 6-商业中心、 | |
| 534 | + // 7-宗教场所、 | |
| 535 | + // 8-校园周边、 | |
| 536 | + // 9-治安复杂区域、 | |
| 537 | + // 10-交通干线。 | |
| 538 | + // String positionType = getText(itemDevice, "PositionType"); | |
| 539 | + | |
| 540 | + // TODO 摄像机安装位置室外、室内属性。1-室外、2-室内。 | |
| 541 | + // String roomType = getText(itemDevice, "RoomType"); | |
| 542 | + // TODO 摄像机用途属性 | |
| 543 | + // String useType = getText(itemDevice, "UseType"); | |
| 544 | + // TODO 摄像机补光属性。1-无补光、2-红外补光、3-白光补光 | |
| 545 | + // String supplyLightType = getText(itemDevice, "SupplyLightType"); | |
| 546 | + // TODO 摄像机监视方位属性。1-东、2-西、3-南、4-北、5-东南、6-东北、7-西南、8-西北。 | |
| 547 | + // String directionType = getText(itemDevice, "DirectionType"); | |
| 548 | + // TODO 摄像机支持的分辨率,可有多个分辨率值,各个取值间以“/”分隔。分辨率取值参见附录 F中SDPf字段规定 | |
| 549 | + // String resolution = getText(itemDevice, "Resolution"); | |
| 550 | + | |
| 551 | + // TODO 下载倍速范围(可选),各可选参数以“/”分隔,如设备支持1,2,4倍速下载则应写为“1/2/4 | |
| 552 | + // String downloadSpeed = getText(itemDevice, "DownloadSpeed"); | |
| 553 | + // TODO 空域编码能力,取值0:不支持;1:1级增强(1个增强层);2:2级增强(2个增强层);3:3级增强(3个增强层) | |
| 554 | + // String svcSpaceSupportMode = getText(itemDevice, "SVCSpaceSupportMode"); | |
| 555 | + // TODO 时域编码能力,取值0:不支持;1:1级增强;2:2级增强;3:3级增强 | |
| 556 | + // String svcTimeSupportMode = getText(itemDevice, "SVCTimeSupportMode"); | |
| 557 | + | |
| 558 | + | |
| 559 | + deviceChannel.setSecrecy(secrecy); | |
| 560 | + break; | |
| 412 | 561 | } |
| 413 | - } else { | |
| 414 | - deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType"))); | |
| 415 | 562 | } |
| 416 | 563 | |
| 417 | 564 | return deviceChannel; | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
| ... | ... | @@ -131,14 +131,12 @@ public class ZLMHttpHookListener { |
| 131 | 131 | @PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8") |
| 132 | 132 | public HookResult onServerKeepalive(@RequestBody OnServerKeepaliveHookParam param) { |
| 133 | 133 | |
| 134 | -// logger.info("[ZLM HOOK] 收到zlm心跳:" + param.getMediaServerId()); | |
| 135 | 134 | |
| 136 | 135 | taskExecutor.execute(() -> { |
| 137 | 136 | List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_keepalive); |
| 138 | - JSONObject json = (JSONObject) JSON.toJSON(param); | |
| 139 | 137 | if (subscribes != null && subscribes.size() > 0) { |
| 140 | 138 | for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { |
| 141 | - subscribe.response(null, json); | |
| 139 | + subscribe.response(null, param); | |
| 142 | 140 | } |
| 143 | 141 | } |
| 144 | 142 | }); |
| ... | ... | @@ -165,7 +163,7 @@ public class ZLMHttpHookListener { |
| 165 | 163 | if (subscribe != null) { |
| 166 | 164 | MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); |
| 167 | 165 | if (mediaInfo != null) { |
| 168 | - subscribe.response(mediaInfo, json); | |
| 166 | + subscribe.response(mediaInfo, param); | |
| 169 | 167 | } |
| 170 | 168 | } |
| 171 | 169 | }); |
| ... | ... | @@ -198,13 +196,13 @@ public class ZLMHttpHookListener { |
| 198 | 196 | if (userSetting.getPushAuthority()) { |
| 199 | 197 | // 推流鉴权 |
| 200 | 198 | if (param.getParams() == null) { |
| 201 | - logger.info("推流鉴权失败: 缺少不要参数:sign=md5(user表的pushKey)"); | |
| 199 | + logger.info("推流鉴权失败: 缺少必要参数:sign=md5(user表的pushKey)"); | |
| 202 | 200 | return new HookResultForOnPublish(401, "Unauthorized"); |
| 203 | 201 | } |
| 204 | 202 | Map<String, String> paramMap = urlParamToMap(param.getParams()); |
| 205 | 203 | String sign = paramMap.get("sign"); |
| 206 | 204 | if (sign == null) { |
| 207 | - logger.info("推流鉴权失败: 缺少不要参数:sign=md5(user表的pushKey)"); | |
| 205 | + logger.info("推流鉴权失败: 缺少必要参数:sign=md5(user表的pushKey)"); | |
| 208 | 206 | return new HookResultForOnPublish(401, "Unauthorized"); |
| 209 | 207 | } |
| 210 | 208 | // 推流自定义播放鉴权码 |
| ... | ... | @@ -241,7 +239,7 @@ public class ZLMHttpHookListener { |
| 241 | 239 | ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_publish, json); |
| 242 | 240 | if (subscribe != null) { |
| 243 | 241 | if (mediaInfo != null) { |
| 244 | - subscribe.response(mediaInfo, json); | |
| 242 | + subscribe.response(mediaInfo, param); | |
| 245 | 243 | } else { |
| 246 | 244 | new HookResultForOnPublish(1, "zlm not register"); |
| 247 | 245 | } |
| ... | ... | @@ -321,7 +319,7 @@ public class ZLMHttpHookListener { |
| 321 | 319 | return; |
| 322 | 320 | } |
| 323 | 321 | if (subscribe != null) { |
| 324 | - subscribe.response(mediaInfo, json); | |
| 322 | + subscribe.response(mediaInfo, param); | |
| 325 | 323 | } |
| 326 | 324 | |
| 327 | 325 | List<OnStreamChangedHookParam.MediaTrack> tracks = param.getTracks(); |
| ... | ... | @@ -551,7 +549,9 @@ public class ZLMHttpHookListener { |
| 551 | 549 | Device device = deviceService.getDevice(inviteInfo.getDeviceId()); |
| 552 | 550 | if (device != null) { |
| 553 | 551 | try { |
| 554 | - if (inviteStreamService.getInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId(), inviteInfo.getChannelId(), inviteInfo.getStream()) != null) { | |
| 552 | + InviteInfo info = inviteStreamService.getInviteInfo(inviteInfo.getType(), | |
| 553 | + inviteInfo.getDeviceId(), inviteInfo.getChannelId(), inviteInfo.getStream()); | |
| 554 | + if (info != null) { | |
| 555 | 555 | cmder.streamByeCmd(device, inviteInfo.getChannelId(), |
| 556 | 556 | inviteInfo.getStream(), null); |
| 557 | 557 | } |
| ... | ... | @@ -578,13 +578,13 @@ public class ZLMHttpHookListener { |
| 578 | 578 | // 拉流代理 |
| 579 | 579 | StreamProxyItem streamProxyItem = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream()); |
| 580 | 580 | if (streamProxyItem != null) { |
| 581 | - if (streamProxyItem.isEnable_remove_none_reader()) { | |
| 581 | + if (streamProxyItem.isEnableDisableNoneReader()) { | |
| 582 | 582 | // 无人观看自动移除 |
| 583 | 583 | ret.put("close", true); |
| 584 | 584 | streamProxyService.del(param.getApp(), param.getStream()); |
| 585 | - String url = streamProxyItem.getUrl() != null ? streamProxyItem.getUrl() : streamProxyItem.getSrc_url(); | |
| 585 | + String url = streamProxyItem.getUrl() != null ? streamProxyItem.getUrl() : streamProxyItem.getSrcUrl(); | |
| 586 | 586 | logger.info("[{}/{}]<-[{}] 拉流代理无人观看已经移除", param.getApp(), param.getStream(), url); |
| 587 | - } else if (streamProxyItem.isEnable_disable_none_reader()) { | |
| 587 | + } else if (streamProxyItem.isEnableDisableNoneReader()) { | |
| 588 | 588 | // 无人观看停用 |
| 589 | 589 | ret.put("close", true); |
| 590 | 590 | // 修改数据 |
| ... | ... | @@ -669,7 +669,7 @@ public class ZLMHttpHookListener { |
| 669 | 669 | } else { |
| 670 | 670 | // 拉流代理 |
| 671 | 671 | StreamProxyItem streamProxyByAppAndStream = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream()); |
| 672 | - if (streamProxyByAppAndStream != null && streamProxyByAppAndStream.isEnable_disable_none_reader()) { | |
| 672 | + if (streamProxyByAppAndStream != null && streamProxyByAppAndStream.isEnableDisableNoneReader()) { | |
| 673 | 673 | streamProxyService.start(param.getApp(), param.getStream()); |
| 674 | 674 | } |
| 675 | 675 | DeferredResult<HookResult> result = new DeferredResult<>(); |
| ... | ... | @@ -693,7 +693,7 @@ public class ZLMHttpHookListener { |
| 693 | 693 | List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_started); |
| 694 | 694 | if (subscribes != null && subscribes.size() > 0) { |
| 695 | 695 | for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { |
| 696 | - subscribe.response(null, jsonObject); | |
| 696 | + subscribe.response(null, zlmServerConfig); | |
| 697 | 697 | } |
| 698 | 698 | } |
| 699 | 699 | mediaServerService.zlmServerOnline(zlmServerConfig); |
| ... | ... | @@ -749,7 +749,7 @@ public class ZLMHttpHookListener { |
| 749 | 749 | List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_rtp_server_timeout); |
| 750 | 750 | if (subscribes != null && subscribes.size() > 0) { |
| 751 | 751 | for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { |
| 752 | - subscribe.response(null, json); | |
| 752 | + subscribe.response(null, param); | |
| 753 | 753 | } |
| 754 | 754 | } |
| 755 | 755 | }); | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java
| ... | ... | @@ -157,7 +157,6 @@ public class ZLMRESTfulUtils { |
| 157 | 157 | |
| 158 | 158 | public void sendGetForImg(MediaServerItem mediaServerItem, String api, Map<String, Object> params, String targetPath, String fileName) { |
| 159 | 159 | String url = String.format("http://%s:%s/index/api/%s", mediaServerItem.getIp(), mediaServerItem.getHttpPort(), api); |
| 160 | - logger.debug(url); | |
| 161 | 160 | HttpUrl parseUrl = HttpUrl.parse(url); |
| 162 | 161 | if (parseUrl == null) { |
| 163 | 162 | return; | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
| ... | ... | @@ -9,6 +9,11 @@ import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
| 9 | 9 | import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; |
| 10 | 10 | import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRtpServerTimeout; |
| 11 | 11 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 12 | +import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; | |
| 13 | +import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRtpServerTimeoutHookParam; | |
| 14 | +import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; | |
| 15 | +import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRtpServerTimeout; | |
| 16 | +import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; | |
| 12 | 17 | import org.slf4j.Logger; |
| 13 | 18 | import org.slf4j.LoggerFactory; |
| 14 | 19 | import org.springframework.beans.factory.annotation.Autowired; |
| ... | ... | @@ -228,7 +233,7 @@ public class ZLMRTPServerFactory { |
| 228 | 233 | int localPort = 0; |
| 229 | 234 | if (userSetting.getGbSendStreamStrict()) { |
| 230 | 235 | if (userSetting.getGbSendStreamStrict()) { |
| 231 | - localPort = keepPort(serverItem, ssrc, null); | |
| 236 | + localPort = keepPort(serverItem, ssrc, localPort); | |
| 232 | 237 | if (localPort == 0) { |
| 233 | 238 | return null; |
| 234 | 239 | } |
| ... | ... | @@ -264,7 +269,7 @@ public class ZLMRTPServerFactory { |
| 264 | 269 | // 默认为随机端口 |
| 265 | 270 | int localPort = 0; |
| 266 | 271 | if (userSetting.getGbSendStreamStrict()) { |
| 267 | - localPort = keepPort(serverItem, ssrc, null); | |
| 272 | + localPort = keepPort(serverItem, ssrc, localPort); | |
| 268 | 273 | if (localPort == 0) { |
| 269 | 274 | return null; |
| 270 | 275 | } |
| ... | ... | @@ -290,9 +295,6 @@ public class ZLMRTPServerFactory { |
| 290 | 295 | */ |
| 291 | 296 | public int keepPort(MediaServerItem serverItem, String ssrc, Integer localPort) { |
| 292 | 297 | Map<String, Object> param = new HashMap<>(3); |
| 293 | - if (localPort == null) { | |
| 294 | - localPort = 0; | |
| 295 | - } | |
| 296 | 298 | param.put("port", localPort); |
| 297 | 299 | param.put("enable_tcp", 1); |
| 298 | 300 | param.put("stream_id", ssrc); |
| ... | ... | @@ -302,22 +304,24 @@ public class ZLMRTPServerFactory { |
| 302 | 304 | HookSubscribeForRtpServerTimeout hookSubscribeForRtpServerTimeout = HookSubscribeFactory.on_rtp_server_timeout(ssrc, null, serverItem.getId()); |
| 303 | 305 | Integer finalLocalPort = localPort; |
| 304 | 306 | hookSubscribe.addSubscribe(hookSubscribeForRtpServerTimeout, |
| 305 | - (MediaServerItem mediaServerItem, JSONObject response)->{ | |
| 306 | - if (ssrc.equals(response.getString("ssrc"))) { | |
| 307 | - logger.info("[上级点播] {}->监听端口到期继续保持监听", ssrc); | |
| 308 | - int port = keepPort(serverItem, ssrc, finalLocalPort); | |
| 309 | - if (port == 0) { | |
| 310 | - logger.info("[上级点播] {}->监听端口失败,移除监听", ssrc); | |
| 311 | - hookSubscribe.removeSubscribe(hookSubscribeForRtpServerTimeout); | |
| 312 | - } | |
| 307 | + (MediaServerItem mediaServerItem, HookParam hookParam)->{ | |
| 308 | + logger.info("[上级点播] {}->监听端口到期继续保持监听: {}", ssrc, finalLocalPort); | |
| 309 | + OnRtpServerTimeoutHookParam rtpServerTimeoutHookParam = (OnRtpServerTimeoutHookParam) hookParam; | |
| 310 | + if (!ssrc.equals(rtpServerTimeoutHookParam.getSsrc())) { | |
| 311 | + return; | |
| 312 | + } | |
| 313 | + int port = keepPort(serverItem, ssrc, finalLocalPort); | |
| 314 | + if (port == 0) { | |
| 315 | + logger.info("[上级点播] {}->监听端口失败,移除监听", ssrc); | |
| 316 | + hookSubscribe.removeSubscribe(hookSubscribeForRtpServerTimeout); | |
| 313 | 317 | } |
| 314 | 318 | }); |
| 315 | - logger.info("[保持端口] {}->监听端口: {}", ssrc, localPort); | |
| 316 | - logger.info("[保持端口] {}->监听端口: {}", ssrc, localPort); | |
| 319 | + logger.info("[上级点播] {}->监听端口: {}", ssrc, localPort); | |
| 320 | + return localPort; | |
| 317 | 321 | }else { |
| 318 | - logger.info("[保持端口] 监听端口失败: {}", ssrc); | |
| 322 | + logger.info("[上级点播] 监听端口失败: {}->{}", ssrc, localPort); | |
| 323 | + return 0; | |
| 319 | 324 | } |
| 320 | - return localPort; | |
| 321 | 325 | } |
| 322 | 326 | |
| 323 | 327 | /** | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
| ... | ... | @@ -65,8 +65,8 @@ public class ZLMRunner implements CommandLineRunner { |
| 65 | 65 | HookSubscribeForServerStarted hookSubscribeForServerStarted = HookSubscribeFactory.on_server_started(); |
| 66 | 66 | // 订阅 zlm启动事件, 新的zlm也会从这里进入系统 |
| 67 | 67 | hookSubscribe.addSubscribe(hookSubscribeForServerStarted, |
| 68 | - (MediaServerItem mediaServerItem, JSONObject response)->{ | |
| 69 | - ZLMServerConfig zlmServerConfig = response.to(ZLMServerConfig.class); | |
| 68 | + (mediaServerItem, hookParam)->{ | |
| 69 | + ZLMServerConfig zlmServerConfig = (ZLMServerConfig)hookParam; | |
| 70 | 70 | if (zlmServerConfig !=null ) { |
| 71 | 71 | if (startGetMedia != null) { |
| 72 | 72 | startGetMedia.remove(zlmServerConfig.getGeneralMediaServerId()); | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerConfig.java
| 1 | 1 | package com.genersoft.iot.vmp.media.zlm; |
| 2 | 2 | |
| 3 | 3 | import com.alibaba.fastjson2.annotation.JSONField; |
| 4 | +import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; | |
| 4 | 5 | |
| 5 | -public class ZLMServerConfig { | |
| 6 | +public class ZLMServerConfig extends HookParam { | |
| 6 | 7 | |
| 7 | 8 | @JSONField(name = "api.apiDebug") |
| 8 | 9 | private String apiDebug; | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZlmHttpHookSubscribe.java
| ... | ... | @@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSONObject; |
| 4 | 4 | import com.genersoft.iot.vmp.media.zlm.dto.HookType; |
| 5 | 5 | import com.genersoft.iot.vmp.media.zlm.dto.IHookSubscribe; |
| 6 | 6 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 7 | +import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; | |
| 7 | 8 | import org.slf4j.Logger; |
| 8 | 9 | import org.slf4j.LoggerFactory; |
| 9 | 10 | import org.springframework.scheduling.annotation.Scheduled; |
| ... | ... | @@ -26,7 +27,7 @@ public class ZlmHttpHookSubscribe { |
| 26 | 27 | |
| 27 | 28 | @FunctionalInterface |
| 28 | 29 | public interface Event{ |
| 29 | - void response(MediaServerItem mediaServerItem, JSONObject response); | |
| 30 | + void response(MediaServerItem mediaServerItem, HookParam hookParam); | |
| 30 | 31 | } |
| 31 | 32 | |
| 32 | 33 | private Map<HookType, Map<IHookSubscribe, ZlmHttpHookSubscribe.Event>> allSubscribes = new ConcurrentHashMap<>(); | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyItem.java
| ... | ... | @@ -20,28 +20,26 @@ public class StreamProxyItem extends GbStream { |
| 20 | 20 | @Schema(description = "拉流地址") |
| 21 | 21 | private String url; |
| 22 | 22 | @Schema(description = "拉流地址") |
| 23 | - private String src_url; | |
| 23 | + private String srcUrl; | |
| 24 | 24 | @Schema(description = "目标地址") |
| 25 | - private String dst_url; | |
| 25 | + private String dstUrl; | |
| 26 | 26 | @Schema(description = "超时时间") |
| 27 | - private int timeout_ms; | |
| 27 | + private int timeoutMs; | |
| 28 | 28 | @Schema(description = "ffmpeg模板KEY") |
| 29 | - private String ffmpeg_cmd_key; | |
| 29 | + private String ffmpegCmdKey; | |
| 30 | 30 | @Schema(description = "rtsp拉流时,拉流方式,0:tcp,1:udp,2:组播") |
| 31 | - private String rtp_type; | |
| 31 | + private String rtpType; | |
| 32 | 32 | @Schema(description = "是否启用") |
| 33 | 33 | private boolean enable; |
| 34 | 34 | @Schema(description = "是否启用音频") |
| 35 | - private boolean enable_audio; | |
| 35 | + private boolean enableAudio; | |
| 36 | 36 | @Schema(description = "是否启用MP4") |
| 37 | - private boolean enable_mp4; | |
| 37 | + private boolean enableMp4; | |
| 38 | 38 | @Schema(description = "是否 无人观看时删除") |
| 39 | - private boolean enable_remove_none_reader; | |
| 39 | + private boolean enableRemoveNoneReader; | |
| 40 | 40 | |
| 41 | 41 | @Schema(description = "是否 无人观看时自动停用") |
| 42 | - private boolean enable_disable_none_reader; | |
| 43 | - @Schema(description = "创建时间") | |
| 44 | - private String createTime; | |
| 42 | + private boolean enableDisableNoneReader; | |
| 45 | 43 | |
| 46 | 44 | public String getType() { |
| 47 | 45 | return type; |
| ... | ... | @@ -89,44 +87,44 @@ public class StreamProxyItem extends GbStream { |
| 89 | 87 | this.url = url; |
| 90 | 88 | } |
| 91 | 89 | |
| 92 | - public String getSrc_url() { | |
| 93 | - return src_url; | |
| 90 | + public String getSrcUrl() { | |
| 91 | + return srcUrl; | |
| 94 | 92 | } |
| 95 | 93 | |
| 96 | - public void setSrc_url(String src_url) { | |
| 97 | - this.src_url = src_url; | |
| 94 | + public void setSrcUrl(String src_url) { | |
| 95 | + this.srcUrl = src_url; | |
| 98 | 96 | } |
| 99 | 97 | |
| 100 | - public String getDst_url() { | |
| 101 | - return dst_url; | |
| 98 | + public String getDstUrl() { | |
| 99 | + return dstUrl; | |
| 102 | 100 | } |
| 103 | 101 | |
| 104 | - public void setDst_url(String dst_url) { | |
| 105 | - this.dst_url = dst_url; | |
| 102 | + public void setDstUrl(String dst_url) { | |
| 103 | + this.dstUrl = dst_url; | |
| 106 | 104 | } |
| 107 | 105 | |
| 108 | - public int getTimeout_ms() { | |
| 109 | - return timeout_ms; | |
| 106 | + public int getTimeoutMs() { | |
| 107 | + return timeoutMs; | |
| 110 | 108 | } |
| 111 | 109 | |
| 112 | - public void setTimeout_ms(int timeout_ms) { | |
| 113 | - this.timeout_ms = timeout_ms; | |
| 110 | + public void setTimeoutMs(int timeout_ms) { | |
| 111 | + this.timeoutMs = timeout_ms; | |
| 114 | 112 | } |
| 115 | 113 | |
| 116 | - public String getFfmpeg_cmd_key() { | |
| 117 | - return ffmpeg_cmd_key; | |
| 114 | + public String getFfmpegCmdKey() { | |
| 115 | + return ffmpegCmdKey; | |
| 118 | 116 | } |
| 119 | 117 | |
| 120 | - public void setFfmpeg_cmd_key(String ffmpeg_cmd_key) { | |
| 121 | - this.ffmpeg_cmd_key = ffmpeg_cmd_key; | |
| 118 | + public void setFfmpegCmdKey(String ffmpeg_cmd_key) { | |
| 119 | + this.ffmpegCmdKey = ffmpeg_cmd_key; | |
| 122 | 120 | } |
| 123 | 121 | |
| 124 | - public String getRtp_type() { | |
| 125 | - return rtp_type; | |
| 122 | + public String getRtpType() { | |
| 123 | + return rtpType; | |
| 126 | 124 | } |
| 127 | 125 | |
| 128 | - public void setRtp_type(String rtp_type) { | |
| 129 | - this.rtp_type = rtp_type; | |
| 126 | + public void setRtpType(String rtp_type) { | |
| 127 | + this.rtpType = rtp_type; | |
| 130 | 128 | } |
| 131 | 129 | |
| 132 | 130 | public boolean isEnable() { |
| ... | ... | @@ -137,45 +135,37 @@ public class StreamProxyItem extends GbStream { |
| 137 | 135 | this.enable = enable; |
| 138 | 136 | } |
| 139 | 137 | |
| 140 | - public boolean isEnable_mp4() { | |
| 141 | - return enable_mp4; | |
| 138 | + public boolean isEnableMp4() { | |
| 139 | + return enableMp4; | |
| 142 | 140 | } |
| 143 | 141 | |
| 144 | - public void setEnable_mp4(boolean enable_mp4) { | |
| 145 | - this.enable_mp4 = enable_mp4; | |
| 142 | + public void setEnableMp4(boolean enable_mp4) { | |
| 143 | + this.enableMp4 = enable_mp4; | |
| 146 | 144 | } |
| 147 | 145 | |
| 148 | - @Override | |
| 149 | - public String getCreateTime() { | |
| 150 | - return createTime; | |
| 146 | + public boolean isEnableRemoveNoneReader() { | |
| 147 | + return enableRemoveNoneReader; | |
| 151 | 148 | } |
| 152 | 149 | |
| 153 | - @Override | |
| 154 | - public void setCreateTime(String createTime) { | |
| 155 | - this.createTime = createTime; | |
| 150 | + public void setEnableRemoveNoneReader(boolean enable_remove_none_reader) { | |
| 151 | + this.enableRemoveNoneReader = enable_remove_none_reader; | |
| 156 | 152 | } |
| 157 | 153 | |
| 158 | - public boolean isEnable_remove_none_reader() { | |
| 159 | - return enable_remove_none_reader; | |
| 154 | + public boolean isEnableDisableNoneReader() { | |
| 155 | + return enableDisableNoneReader; | |
| 160 | 156 | } |
| 161 | 157 | |
| 162 | - public void setEnable_remove_none_reader(boolean enable_remove_none_reader) { | |
| 163 | - this.enable_remove_none_reader = enable_remove_none_reader; | |
| 158 | + public void setEnableDisableNoneReader(boolean enable_disable_none_reader) { | |
| 159 | + this.enableDisableNoneReader = enable_disable_none_reader; | |
| 164 | 160 | } |
| 165 | 161 | |
| 166 | - public boolean isEnable_disable_none_reader() { | |
| 167 | - return enable_disable_none_reader; | |
| 162 | + public boolean isEnableAudio() { | |
| 163 | + return enableAudio; | |
| 168 | 164 | } |
| 169 | 165 | |
| 170 | - public void setEnable_disable_none_reader(boolean enable_disable_none_reader) { | |
| 171 | - this.enable_disable_none_reader = enable_disable_none_reader; | |
| 166 | + public void setEnableAudio(boolean enable_audio) { | |
| 167 | + this.enableAudio = enable_audio; | |
| 172 | 168 | } |
| 173 | 169 | |
| 174 | - public boolean isEnable_audio() { | |
| 175 | - return enable_audio; | |
| 176 | - } | |
| 177 | 170 | |
| 178 | - public void setEnable_audio(boolean enable_audio) { | |
| 179 | - this.enable_audio = enable_audio; | |
| 180 | - } | |
| 181 | 171 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java
| ... | ... | @@ -325,5 +325,65 @@ public class StreamPushItem extends GbStream implements Comparable<StreamPushIte |
| 325 | 325 | public void setSelf(boolean self) { |
| 326 | 326 | this.self = self; |
| 327 | 327 | } |
| 328 | + | |
| 329 | +// @Override | |
| 330 | +// public Integer getGbStreamId() { | |
| 331 | +// return super.getGbStreamId(); | |
| 332 | +// } | |
| 333 | +// | |
| 334 | +// @Override | |
| 335 | +// public void setGbStreamId(Integer gbStreamId) { | |
| 336 | +// super.setGbStreamId(gbStreamId); | |
| 337 | +// } | |
| 338 | +// | |
| 339 | +// | |
| 340 | +// public String getGbId() { | |
| 341 | +// return super.getGbId(); | |
| 342 | +// } | |
| 343 | +// | |
| 344 | +// public void setGbId(String gbId) { | |
| 345 | +// super.setGbId(gbId); | |
| 346 | +// } | |
| 347 | +// | |
| 348 | +// public String getName() { | |
| 349 | +// return super.getName(); | |
| 350 | +// } | |
| 351 | +// | |
| 352 | +// public void setName(String name) { | |
| 353 | +// super.setName(name); | |
| 354 | +// } | |
| 355 | +// | |
| 356 | +// public double getLongitude() { | |
| 357 | +// return super.getLongitude(); | |
| 358 | +// } | |
| 359 | +// | |
| 360 | +// public void setLongitude(double longitude) { | |
| 361 | +// super.setLongitude(longitude); | |
| 362 | +// } | |
| 363 | +// | |
| 364 | +// public double getLatitude() { | |
| 365 | +// return super.getLatitude(); | |
| 366 | +// } | |
| 367 | +// | |
| 368 | +// public void setLatitude(double latitude) { | |
| 369 | +// super.setLatitude(latitude); | |
| 370 | +// } | |
| 371 | +// | |
| 372 | +// public String getStreamType() { | |
| 373 | +// return super.getStreamType(); | |
| 374 | +// } | |
| 375 | +// | |
| 376 | +// public void setStreamType(String streamType) { | |
| 377 | +// super.setStreamType(streamType); | |
| 378 | +// } | |
| 379 | +// | |
| 380 | +// public boolean isStatus() { | |
| 381 | +// return super.isStatus(); | |
| 382 | +// } | |
| 383 | +// | |
| 384 | +// public void setStatus(boolean status) { | |
| 385 | +// super.setStatus(status); | |
| 386 | +// } | |
| 387 | + | |
| 328 | 388 | } |
| 329 | 389 | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookResultForOnPublish.java
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnPlayHookParam.java
| ... | ... | @@ -81,6 +81,15 @@ public class OnPlayHookParam extends HookParam{ |
| 81 | 81 | |
| 82 | 82 | @Override |
| 83 | 83 | public String toString() { |
| 84 | - return String.format("%s://%s:%s/%s/%s?%s", schema, ip, port, app, stream, params); | |
| 84 | + return "OnPlayHookParam{" + | |
| 85 | + "id='" + id + '\'' + | |
| 86 | + ", app='" + app + '\'' + | |
| 87 | + ", stream='" + stream + '\'' + | |
| 88 | + ", ip='" + ip + '\'' + | |
| 89 | + ", params='" + params + '\'' + | |
| 90 | + ", port=" + port + | |
| 91 | + ", schema='" + schema + '\'' + | |
| 92 | + ", vhost='" + vhost + '\'' + | |
| 93 | + '}'; | |
| 85 | 94 | } |
| 86 | 95 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnPublishHookParam.java
| ... | ... | @@ -81,6 +81,15 @@ public class OnPublishHookParam extends HookParam{ |
| 81 | 81 | |
| 82 | 82 | @Override |
| 83 | 83 | public String toString() { |
| 84 | - return String.format("%s://%s:%s/%s/%s?%s", schema, ip, port, app, stream, params); | |
| 84 | + return "OnPublishHookParam{" + | |
| 85 | + "id='" + id + '\'' + | |
| 86 | + ", app='" + app + '\'' + | |
| 87 | + ", stream='" + stream + '\'' + | |
| 88 | + ", ip='" + ip + '\'' + | |
| 89 | + ", params='" + params + '\'' + | |
| 90 | + ", port=" + port + | |
| 91 | + ", schema='" + schema + '\'' + | |
| 92 | + ", vhost='" + vhost + '\'' + | |
| 93 | + '}'; | |
| 85 | 94 | } |
| 86 | 95 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnRtpServerTimeoutHookParam.java
| ... | ... | @@ -50,4 +50,15 @@ public class OnRtpServerTimeoutHookParam extends HookParam{ |
| 50 | 50 | public void setSsrc(String ssrc) { |
| 51 | 51 | this.ssrc = ssrc; |
| 52 | 52 | } |
| 53 | + | |
| 54 | + @Override | |
| 55 | + public String toString() { | |
| 56 | + return "OnRtpServerTimeoutHookParam{" + | |
| 57 | + "local_port=" + local_port + | |
| 58 | + ", stream_id='" + stream_id + '\'' + | |
| 59 | + ", tcpMode=" + tcpMode + | |
| 60 | + ", re_use_port=" + re_use_port + | |
| 61 | + ", ssrc='" + ssrc + '\'' + | |
| 62 | + '}'; | |
| 63 | + } | |
| 53 | 64 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnSendRtpStoppedHookParam.java
| ... | ... | @@ -24,4 +24,12 @@ public class OnSendRtpStoppedHookParam extends HookParam{ |
| 24 | 24 | public void setStream(String stream) { |
| 25 | 25 | this.stream = stream; |
| 26 | 26 | } |
| 27 | + | |
| 28 | + @Override | |
| 29 | + public String toString() { | |
| 30 | + return "OnSendRtpStoppedHookParam{" + | |
| 31 | + "app='" + app + '\'' + | |
| 32 | + ", stream='" + stream + '\'' + | |
| 33 | + '}'; | |
| 34 | + } | |
| 27 | 35 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnServerKeepaliveHookParam.java
| ... | ... | @@ -17,4 +17,11 @@ public class OnServerKeepaliveHookParam extends HookParam{ |
| 17 | 17 | public void setData(ServerKeepaliveData data) { |
| 18 | 18 | this.data = data; |
| 19 | 19 | } |
| 20 | + | |
| 21 | + @Override | |
| 22 | + public String toString() { | |
| 23 | + return "OnServerKeepaliveHookParam{" + | |
| 24 | + "data=" + data + | |
| 25 | + '}'; | |
| 26 | + } | |
| 20 | 27 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamChangedHookParam.java
| ... | ... | @@ -430,4 +430,14 @@ public class OnStreamChangedHookParam extends HookParam{ |
| 430 | 430 | public void setCallId(String callId) { |
| 431 | 431 | this.callId = callId; |
| 432 | 432 | } |
| 433 | + | |
| 434 | + @Override | |
| 435 | + public String toString() { | |
| 436 | + return "OnStreamChangedHookParam{" + | |
| 437 | + "regist=" + regist + | |
| 438 | + ", app='" + app + '\'' + | |
| 439 | + ", stream='" + stream + '\'' + | |
| 440 | + ", severId='" + severId + '\'' + | |
| 441 | + '}'; | |
| 442 | + } | |
| 433 | 443 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamNoneReaderHookParam.java
| ... | ... | @@ -38,4 +38,14 @@ public class OnStreamNoneReaderHookParam extends HookParam{ |
| 38 | 38 | public void setVhost(String vhost) { |
| 39 | 39 | this.vhost = vhost; |
| 40 | 40 | } |
| 41 | + | |
| 42 | + @Override | |
| 43 | + public String toString() { | |
| 44 | + return "OnStreamNoneReaderHookParam{" + | |
| 45 | + "schema='" + schema + '\'' + | |
| 46 | + ", app='" + app + '\'' + | |
| 47 | + ", stream='" + stream + '\'' + | |
| 48 | + ", vhost='" + vhost + '\'' + | |
| 49 | + '}'; | |
| 50 | + } | |
| 41 | 51 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamNotFoundHookParam.java
| ... | ... | @@ -81,6 +81,15 @@ public class OnStreamNotFoundHookParam extends HookParam{ |
| 81 | 81 | |
| 82 | 82 | @Override |
| 83 | 83 | public String toString() { |
| 84 | - return String.format("%s://%s:%s/%s/%s?%s", schema, ip, port, app, stream, params); | |
| 84 | + return "OnStreamNotFoundHookParam{" + | |
| 85 | + "id='" + id + '\'' + | |
| 86 | + ", app='" + app + '\'' + | |
| 87 | + ", stream='" + stream + '\'' + | |
| 88 | + ", ip='" + ip + '\'' + | |
| 89 | + ", params='" + params + '\'' + | |
| 90 | + ", port=" + port + | |
| 91 | + ", schema='" + schema + '\'' + | |
| 92 | + ", vhost='" + vhost + '\'' + | |
| 93 | + '}'; | |
| 85 | 94 | } |
| 86 | 95 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/IDeviceChannelService.java
| ... | ... | @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.service; |
| 2 | 2 | |
| 3 | 3 | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 4 | 4 | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| 5 | -import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; | |
| 5 | +import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo; | |
| 6 | 6 | import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; |
| 7 | 7 | |
| 8 | 8 | import java.util.List; |
| ... | ... | @@ -38,7 +38,7 @@ public interface IDeviceChannelService { |
| 38 | 38 | * 获取统计信息 |
| 39 | 39 | * @return |
| 40 | 40 | */ |
| 41 | - ResourceBaceInfo getOverview(); | |
| 41 | + ResourceBaseInfo getOverview(); | |
| 42 | 42 | |
| 43 | 43 | /** |
| 44 | 44 | * 查询所有未分配的通道 | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/IDeviceService.java
| ... | ... | @@ -5,7 +5,7 @@ import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| 5 | 5 | import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo; |
| 6 | 6 | import com.genersoft.iot.vmp.gb28181.bean.SyncStatus; |
| 7 | 7 | import com.genersoft.iot.vmp.vmanager.bean.BaseTree; |
| 8 | -import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; | |
| 8 | +import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo; | |
| 9 | 9 | |
| 10 | 10 | import java.util.List; |
| 11 | 11 | |
| ... | ... | @@ -162,7 +162,7 @@ public interface IDeviceService { |
| 162 | 162 | * 获取统计信息 |
| 163 | 163 | * @return |
| 164 | 164 | */ |
| 165 | - ResourceBaceInfo getOverview(); | |
| 165 | + ResourceBaseInfo getOverview(); | |
| 166 | 166 | |
| 167 | 167 | /** |
| 168 | 168 | * 获取所有设备 | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/IInviteStreamService.java
| ... | ... | @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.service; |
| 2 | 2 | |
| 3 | 3 | import com.genersoft.iot.vmp.common.InviteInfo; |
| 4 | 4 | import com.genersoft.iot.vmp.common.InviteSessionType; |
| 5 | -import com.genersoft.iot.vmp.service.bean.InviteErrorCallback; | |
| 5 | +import com.genersoft.iot.vmp.service.bean.ErrorCallback; | |
| 6 | 6 | |
| 7 | 7 | /** |
| 8 | 8 | * 记录国标点播的状态,包括实时预览,下载,录像回放 |
| ... | ... | @@ -14,6 +14,8 @@ public interface IInviteStreamService { |
| 14 | 14 | */ |
| 15 | 15 | void updateInviteInfo(InviteInfo inviteInfo); |
| 16 | 16 | |
| 17 | + InviteInfo updateInviteInfoForStream(InviteInfo inviteInfo, String stream); | |
| 18 | + | |
| 17 | 19 | /** |
| 18 | 20 | * 获取点播的状态信息 |
| 19 | 21 | */ |
| ... | ... | @@ -54,7 +56,7 @@ public interface IInviteStreamService { |
| 54 | 56 | /** |
| 55 | 57 | * 添加一个invite回调 |
| 56 | 58 | */ |
| 57 | - void once(InviteSessionType type, String deviceId, String channelId, String stream, InviteErrorCallback<Object> callback); | |
| 59 | + void once(InviteSessionType type, String deviceId, String channelId, String stream, ErrorCallback<Object> callback); | |
| 58 | 60 | |
| 59 | 61 | /** |
| 60 | 62 | * 调用一个invite回调 |
| ... | ... | @@ -65,4 +67,12 @@ public interface IInviteStreamService { |
| 65 | 67 | * 清空一个设备的所有invite信息 |
| 66 | 68 | */ |
| 67 | 69 | void clearInviteInfo(String deviceId); |
| 70 | + | |
| 71 | + /** | |
| 72 | + * 统计同一个zlm下的国标收流个数 | |
| 73 | + */ | |
| 74 | + int getStreamInfoCount(String mediaServerId); | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 68 | 78 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
| ... | ... | @@ -7,7 +7,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; |
| 7 | 7 | import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; |
| 8 | 8 | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
| 9 | 9 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 10 | -import com.genersoft.iot.vmp.service.bean.InviteErrorCallback; | |
| 10 | +import com.genersoft.iot.vmp.service.bean.ErrorCallback; | |
| 11 | 11 | import com.genersoft.iot.vmp.service.bean.SSRCInfo; |
| 12 | 12 | import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult; |
| 13 | 13 | import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.AudioBroadcastEvent; |
| ... | ... | @@ -25,8 +25,8 @@ import java.util.Map; |
| 25 | 25 | public interface IPlayService { |
| 26 | 26 | |
| 27 | 27 | void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, |
| 28 | - InviteErrorCallback<Object> callback); | |
| 29 | - SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId, InviteErrorCallback<Object> callback); | |
| 28 | + ErrorCallback<Object> callback); | |
| 29 | + SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId, ErrorCallback<Object> callback); | |
| 30 | 30 | |
| 31 | 31 | StreamInfo onPublishHandlerForPlay(MediaServerItem mediaServerItem, JSONObject response, String deviceId, String channelId); |
| 32 | 32 | |
| ... | ... | @@ -37,13 +37,13 @@ public interface IPlayService { |
| 37 | 37 | */ |
| 38 | 38 | MediaServerItem getNewMediaServerItemHasAssist(Device device); |
| 39 | 39 | |
| 40 | - void playBack(String deviceId, String channelId, String startTime, String endTime, InviteErrorCallback<Object> callback); | |
| 41 | - void playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, InviteErrorCallback<Object> callback); | |
| 40 | + void playBack(String deviceId, String channelId, String startTime, String endTime, ErrorCallback<Object> callback); | |
| 41 | + void playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, ErrorCallback<Object> callback); | |
| 42 | 42 | |
| 43 | 43 | void zlmServerOffline(String mediaServerId); |
| 44 | 44 | |
| 45 | - void download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteErrorCallback<Object> callback); | |
| 46 | - void download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, InviteErrorCallback<Object> callback); | |
| 45 | + void download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, ErrorCallback<Object> callback); | |
| 46 | + void download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, ErrorCallback<Object> callback); | |
| 47 | 47 | |
| 48 | 48 | StreamInfo getDownLoadInfo(String deviceId, String channelId, String stream); |
| 49 | 49 | |
| ... | ... | @@ -69,4 +69,6 @@ public interface IPlayService { |
| 69 | 69 | void talkCmd(Device device, String channelId, MediaServerItem mediaServerItem, String stream, AudioBroadcastEvent event); |
| 70 | 70 | |
| 71 | 71 | void stopTalk(Device device, String channelId, Boolean streamIsReady); |
| 72 | + | |
| 73 | + void getSnap(String deviceId, String channelId, String fileName, ErrorCallback errorCallback); | |
| 72 | 74 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/IRecordInfoServer.java deleted
100644 → 0
src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java
| 1 | 1 | package com.genersoft.iot.vmp.service; |
| 2 | 2 | |
| 3 | 3 | import com.alibaba.fastjson2.JSONObject; |
| 4 | +import com.genersoft.iot.vmp.common.GeneralCallback; | |
| 4 | 5 | import com.genersoft.iot.vmp.common.StreamInfo; |
| 5 | 6 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 6 | 7 | import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; |
| 7 | -import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; | |
| 8 | +import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo; | |
| 8 | 9 | import com.github.pagehelper.PageInfo; |
| 9 | 10 | |
| 10 | 11 | public interface IStreamProxyService { |
| ... | ... | @@ -13,7 +14,7 @@ public interface IStreamProxyService { |
| 13 | 14 | * 保存视频代理 |
| 14 | 15 | * @param param |
| 15 | 16 | */ |
| 16 | - StreamInfo save(StreamProxyItem param); | |
| 17 | + void save(StreamProxyItem param, GeneralCallback<StreamInfo> callback); | |
| 17 | 18 | |
| 18 | 19 | /** |
| 19 | 20 | * 添加视频代理到zlm |
| ... | ... | @@ -108,6 +109,6 @@ public interface IStreamProxyService { |
| 108 | 109 | * 获取统计信息 |
| 109 | 110 | * @return |
| 110 | 111 | */ |
| 111 | - ResourceBaceInfo getOverview(); | |
| 112 | + ResourceBaseInfo getOverview(); | |
| 112 | 113 | |
| 113 | 114 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java
| ... | ... | @@ -5,7 +5,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; |
| 5 | 5 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 6 | 6 | import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; |
| 7 | 7 | import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis; |
| 8 | -import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; | |
| 8 | +import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo; | |
| 9 | 9 | import com.github.pagehelper.PageInfo; |
| 10 | 10 | |
| 11 | 11 | import java.util.List; |
| ... | ... | @@ -113,5 +113,5 @@ public interface IStreamPushService { |
| 113 | 113 | * 获取统计信息 |
| 114 | 114 | * @return |
| 115 | 115 | */ |
| 116 | - ResourceBaceInfo getOverview(); | |
| 116 | + ResourceBaseInfo getOverview(); | |
| 117 | 117 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/service/bean/InviteErrorCallback.java renamed to src/main/java/com/genersoft/iot/vmp/service/bean/ErrorCallback.java
src/main/java/com/genersoft/iot/vmp/service/bean/InviteErrorCode.java