commit b43a0c2713171d62154098fe34d8afbfabc6f702 Author: wehub-resource-sync Date: Mon Jul 13 12:32:02 2026 +0800 chore: import upstream snapshot with attribution diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..2fa621c --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +.idea +runtime +.git + +**/node_modules/** \ No newline at end of file diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..3966754 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,11 @@ +node_modules +.next +dist +lib + +**/.next/** +**/dist/** +**/static/** +**/build/** +**/public/** +**/diagram.js diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1a659da --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# 第三方依赖太多,导致项目主语言被冲散 +*.js linguist-language=typescript \ No newline at end of file diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..9ea56ed --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,13 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry +custom: ['https://think-1256095494.cos.ap-shanghai.myqcloud.com/think-wechat.jpg', 'https://think-1256095494.cos.ap-shanghai.myqcloud.com/think-alipay.jpg'] diff --git a/.github/ISSUE_TEMPLATE/----.md b/.github/ISSUE_TEMPLATE/----.md new file mode 100644 index 0000000..aa12d98 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/----.md @@ -0,0 +1,12 @@ +--- +name: 功能请求 +about: 为项目提供想法 +title: "[FEATURE]" +labels: '' +assignees: '' + +--- + +## 请描述功能点 + +## 也可提供功能的实现方案 diff --git a/.github/ISSUE_TEMPLATE/bug---.md b/.github/ISSUE_TEMPLATE/bug---.md new file mode 100644 index 0000000..5f1879c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug---.md @@ -0,0 +1,14 @@ +--- +name: Bug 反馈 +about: 反馈 Bug 以改善项目 +title: "[BUG]" +labels: '' +assignees: '' + +--- + +## 1. 问题的表现是怎样的? + +## 2. 问题的复现路径 + +## 3. 预期是什么? diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..44719a1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +node_modules +.DS_Store +.idea + +dist +dist-ssr +coverage +test-results +.pnpm-store +tsconfig.tsbuildinfo + +.env +*.local +*.cache +*error.log +*debug.log +*.conf + +**/prod.yaml + +scripts/update.sh + +output +runtime diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..799c304 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +pnpm run precommit diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..fa4e095 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +strict-peer-dependencies=false \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..46f82f1 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,9 @@ +node_modules +.next +dist +lib + +**/.next/** +**/dist/** +**/build/** +**/public/** diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..0a2f166 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,12 @@ +{ + "singleQuote": true, + "quoteProps": "consistent", + "bracketSpacing": true, + "jsxBracketSameLine": false, + "arrowParens": "always", + "trailingComma": "es5", + "tabWidth": 2, + "semi": true, + "printWidth": 120, + "endOfLine": "lf" +} \ No newline at end of file diff --git a/.stylelintrc.js b/.stylelintrc.js new file mode 100644 index 0000000..d640c2f --- /dev/null +++ b/.stylelintrc.js @@ -0,0 +1,110 @@ +module.exports = { + processors: [], + plugins: ['stylelint-order'], + extends: ['stylelint-config-standard', 'stylelint-config-css-modules'], + rules: { + 'selector-class-pattern': [ + // 命名规范 - + '(.)+$', + { + message: 'Expected class selector to be kebab-case', + }, + ], + 'string-quotes': 'single', // 单引号 + 'at-rule-empty-line-before': null, + 'at-rule-no-unknown': null, + 'at-rule-name-case': 'lower', // 指定@规则名的大小写 + 'length-zero-no-unit': true, // 禁止零长度的单位(可自动修复) + 'shorthand-property-no-redundant-values': true, // 简写属性 + 'number-leading-zero': 'always', // 小数不带0 + 'declaration-block-no-duplicate-properties': true, // 禁止声明快重复属性 + 'no-descending-specificity': true, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器。 + 'selector-max-id': 3, // 限制一个选择器中 ID 选择器的数量 + 'max-nesting-depth': 5, + 'indentation': [ + 2, + { + // 指定缩进 warning 提醒 + severity: 'warning', + }, + ], + 'order/properties-order': [ + // 规则顺序 + 'position', + 'top', + 'right', + 'bottom', + 'left', + 'z-index', + 'display', + 'float', + 'width', + 'height', + 'max-width', + 'max-height', + 'min-width', + 'min-height', + 'padding', + 'padding-top', + 'padding-right', + 'padding-bottom', + 'padding-left', + 'margin', + 'margin-top', + 'margin-right', + 'margin-bottom', + 'margin-left', + 'margin-collapse', + 'margin-top-collapse', + 'margin-right-collapse', + 'margin-bottom-collapse', + 'margin-left-collapse', + 'overflow', + 'overflow-x', + 'overflow-y', + 'clip', + 'clear', + 'font', + 'font-family', + 'font-size', + 'font-smoothing', + 'osx-font-smoothing', + 'font-style', + 'font-weight', + 'line-height', + 'letter-spacing', + 'word-spacing', + 'color', + 'text-align', + 'text-decoration', + 'text-indent', + 'text-overflow', + 'text-rendering', + 'text-size-adjust', + 'text-shadow', + 'text-transform', + 'word-break', + 'word-wrap', + 'white-space', + 'vertical-align', + 'list-style', + 'list-style-type', + 'list-style-position', + 'list-style-image', + 'pointer-events', + 'cursor', + 'background', + 'background-color', + 'border', + 'border-radius', + 'content', + 'outline', + 'outline-offset', + 'opacity', + 'filter', + 'visibility', + 'size', + 'transform', + ], + }, +}; diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..45bd75a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,26 @@ +FROM node:18-alpine as builder +COPY . /app/ +WORKDIR /app +RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories +RUN npm config set registry http://mirrors.cloud.tencent.com/npm/ +RUN npm i -g pm2 @nestjs/cli pnpm +RUN apk --no-cache add bash dos2unix \ + && find . -name "*.sh" -exec dos2unix {} \; \ + && apk del dos2unix +RUN bash build-output.sh + +FROM node:18-alpine as prod +ENV TZ=Asia/Shanghai +COPY --from=builder /app/docker/* /app/docker/ +COPY --from=builder /app/output/ /app/ +WORKDIR /app +RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories +RUN npm config set registry http://mirrors.cloud.tencent.com/npm/ +RUN set -x \ + && apk update \ + && apk add --no-cache tzdata redis \ + && chmod +x /app/docker/start.sh \ + && npm i -g pm2 @nestjs/cli pnpm \ + && rm -rf /var/cache/apk/* + +ENTRYPOINT sh /app/docker/start.sh diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..debeabf --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 fantasticit + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..f1dfb5c --- /dev/null +++ b/README.md @@ -0,0 +1,56 @@ +# think + +## 声明 + +1. 请先阅读[提问的智慧](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md) +2. 如果希望参与独立编辑器开发,可以到[这个仓库](https://github.com/fantasticit/sailkit)参与 +3. 由于服务器成本和免费的 SSL 证书也没了,网站不定期会挂,敬请谅解 + +## 简介 + +Think 是一款开源知识管理工具。通过独立的知识库空间,结构化地组织在线协作文档,实现知识的积累与沉淀,促进知识的复用与流通。同时支持多人协作文档。使用的技术如下: + +- `MySQL`:数据存储 +- `next.js`:前端页面框架 +- `nest.js`:服务端框架 +- `tiptap`:编辑器及文档协作 + +可访问[云策文档帮助中心](https://think.codingit.cn/share/wiki/WoiR8N5uj4i7),查看更多功能文档。 + +## 链接 + +[云策文档](https://think.codingit.cn)已经部署上线,可前往注册使用。 + +## 预览 + +
+ 查看预览图 + 知识库 + 新建文档 + 编辑器 +
+ +## 项目开发 + +[项目开发说明](./let-us-start.md)。 + +## 自动化部署 + +> 思路:在服务器部署 webhook,然后在 github setting 中配置相应钩子,实现自动化部署 + +参考:[webhook](https://github.com/adnanh/webhook/blob/master/docs/Hook-Examples.md#incoming-github-webhook) + +## 赞助 + +如果这个项目对您有帮助,并且您希望支持该项目的开发和维护,请随时扫描一下二维码进行捐赠。非常感谢您的捐款,谢谢! + +
+ alipay + wechat +
+ +## 贡献者 + +感谢所有为本项目作出贡献的同学! + + diff --git a/README.wehub.md b/README.wehub.md new file mode 100644 index 0000000..89332b8 --- /dev/null +++ b/README.wehub.md @@ -0,0 +1,7 @@ +# WeHub 来源说明 + +- 原始项目:`fantasticit/think` +- 原始仓库:https://github.com/fantasticit/think +- 导入方式:上游默认分支的最新快照 +- 原作者、版权和许可证信息以原始仓库及本仓库 LICENSE 为准 +- 本文件仅用于记录来源,不代表 WeHub 是原项目作者 diff --git a/build-output.sh b/build-output.sh new file mode 100755 index 0000000..ed23432 --- /dev/null +++ b/build-output.sh @@ -0,0 +1,82 @@ +#! /bin/bash +# 该脚本只保留生产环境运行所需文件到统一目录 +if [ ! -f './config/prod.yaml' ]; then + echo "缺少 config/prod.yaml 文件,可参考 docker-prod-sample.yaml 进行配置" + exit 1 +fi + +# 构建 +pnpm fetch --prod +pnpm install +pnpm run build + +outputDir="output" + +# 新建输出目录 +if [ -d ${outputDir} ]; then + rm -rfv ${outputDir} +fi +mkdir -p ${outputDir} +cd ${outputDir} +mkdir -p packages +mkdir -p packages/config +mkdir -p packages/constants +mkdir -p packages/domains +mkdir -p packages/client +mkdir -p packages/server +cd ../ + +# 复制文件 +cp -v -L -r config ${outputDir} +cd ${outputDir}/config +rm -f dev.yaml +cd ../../ +cp -v -L package.json ${outputDir} +cp -v -L pnpm-lock.yaml ${outputDir} +cp -v -L pnpm-workspace.yaml ${outputDir} + +# packages/config +cd packages/config +configOutput="../../${outputDir}/packages/config" +cp -v -L package.json ${configOutput} +cp -v -L -r lib ${configOutput} +cd ../../ + +# packages/constants +cd packages/constants +constantsOutput="../../${outputDir}/packages/constants" +cp -v -L package.json ${constantsOutput} +cp -v -L -r lib ${constantsOutput} +cd ../../ + +# packages/domains +cd packages/domains +domainsOutput="../../${outputDir}/packages/domains" +cp -v -L package.json ${domainsOutput} +cp -v -L -r lib ${domainsOutput} +cd ../../ + +# packages/client +cd packages/client +clientOutput="../../${outputDir}/packages/client" +cp -v -L package.json ${clientOutput} +cp -v -L prod-server.js ${clientOutput} +cp -v -L -r public ${clientOutput} +cp -v -L -r .next ${clientOutput} +cd ../../ + +# packages/server +cd packages/server +serverOutput="../../${outputDir}/packages/server" +cp -v -L package.json ${serverOutput} +cp -v -L nest-cli.json ${serverOutput} +cp -v -L -r dist ${serverOutput} +cd ../../ + +# @see https://github.com/typicode/husky/issues/914#issuecomment-826768549 +cd ${outputDir} +npm set-script prepare "" +pnpm install -r --offline --prod +cd ../ + +echo "${outputDir} 打包完成" diff --git a/config/dev.yaml b/config/dev.yaml new file mode 100644 index 0000000..b0e3900 --- /dev/null +++ b/config/dev.yaml @@ -0,0 +1,74 @@ +# 开发环境配置 +client: + port: 5001 + assetPrefix: '/' + apiUrl: 'http://localhost:5002/api' + collaborationUrl: 'ws://localhost:5003' + # 预先连接的来源,空格分割(比如图片存储服务器) + dnsPrefetch: '//wipi.oss-cn-shanghai.aliyuncs.com' + # 站点地址(如:https://think.codingit.cn/),一定要设置,否则会出现 cookie、跨域等问题 + siteUrl: + 'http://localhost:5001' + # 一定要设置,否则会出现 cookie、跨域等问题,注意如果网页部署在 https://think.codingit.cn,那这里的值应当为 .codingit.cn(没有 think) + siteDomain: '' + +server: + prefix: '/api' + port: 5002 + collaborationPort: 5003 + maxDocumentVersion: 20 # 最大版本记录数 + logRetainDays: 3 # 日志保留天数,比如只保留近三天日志 + enableRateLimit: true # 是否限流 + rateLimitWindowMs: 60000 # 限流时间 + rateLimitMax: 1000 # 单位限流时间内单个 ip 最大访问数量 + email: # 邮箱服务,参考 http://help.163.com/09/1223/14/5R7P6CJ600753VB8.html?servCode=6010376 获取 SMTP 配置 + host: '' + port: 465 + user: '' + password: '' + admin: + name: 'admin' # 注意修改 + password: 'admin' # 注意修改 + email: 'admin@think.com' # 注意修改为真实邮箱地址 + +# 数据库配置 +db: + mysql: + host: '127.0.0.1' + username: 'think' + password: 'think' + database: 'think' + port: 3306 + charset: 'utf8mb4' + timezone: '+08:00' + synchronize: true + redis: + host: '127.0.0.1' + port: '6379' + password: 'root' + db: 0 + +# oss 文件存储服务 +oss: + local: + enable: true + # 线上更改为服务端地址(如:https://api.codingit.cn) + server: 'http://localhost:5002' + s3: + enable: false + config: + # isp 提供商,可选 minio,s3,aliyun,tencent + cloudisp: 'minio' + accessKeyId: '' + secretAccessKey: '' + bucket: '' + region: '' + # 仅cloudisp 的值为 minio/s3 时配置,其它提供商为空 + forcePathStyle: false + # 仅cloudisp 的值为 minio 时配置,其它提供商为空 + endpoint: '' + +# jwt 配置 +jwt: + secretkey: 'zA_Think+KNOWLEDGE+WIKI+DOCUMENTS@2022' + expiresIn: '6h' diff --git a/config/docker-prod-sample.yaml b/config/docker-prod-sample.yaml new file mode 100644 index 0000000..e60c2c9 --- /dev/null +++ b/config/docker-prod-sample.yaml @@ -0,0 +1,75 @@ +# 开发环境配置 +client: + port: 5001 + assetPrefix: '/' + apiUrl: 'http://localhost:5002/api' + collaborationUrl: 'ws://localhost:5003' + # 以下为页面 meta 配置 + seoAppName: '云策文档' + seoDescription: '云策文档是一款开源知识管理工具。通过独立的知识库空间,结构化地组织在线协作文档,实现知识的积累与沉淀,促进知识的复用与流通。' + seoKeywords: '云策文档,协作,文档,fantasticit,https://github.com/fantasticit/think' + # 预先连接的来源,空格分割(比如图片存储服务器) + dnsPrefetch: '//wipi.oss-cn-shanghai.aliyuncs.com' + # 站点地址(如:http://think.codingit.cn/),一定要设置,否则会出现 cookie、跨域等问题 + siteUrl: 'http://localhost:5001' + siteDomain: '' + +server: + prefix: '/api' + port: 5002 + collaborationPort: 5003 + maxDocumentVersion: 20 # 最大版本记录数 + logRetainDays: 3 # 日志保留天数,比如只保留近三天日志 + enableRateLimit: true # 是否限流 + rateLimitWindowMs: 60000 # 限流时间 + rateLimitMax: 1000 # 单位限流时间内单个 ip 最大访问数量 + email: # 邮箱服务,参考 http://help.163.com/09/1223/14/5R7P6CJ600753VB8.html?servCode=6010376 获取 SMTP 配置 + host: '' + port: 465 + user: '' + password: '' + admin: + name: 'admin' # 注意修改 + password: 'admin' # 注意修改 + email: 'admin@think.com' # 注意修改为真实邮箱地址 + +# 数据库配置 +db: + mysql: + host: 'mysql-for-think' + username: 'think' + password: 'think' + database: 'think' + port: 3306 + charset: 'utf8mb4' + timezone: '+08:00' + synchronize: true + redis: + host: 'redis-for-think' + port: '6379' + password: 'root' + +# oss 文件存储服务 +oss: + local: + enable: true + # 线上更改为服务端地址(如:https://api.codingit.cn) + server: 'http://localhost:5002' + s3: + enable: true + config: + # isp 提供商,可选 minio,s3,aliyun,tencent + cloudisp: 'minio' + accessKeyId: '' + secretAccessKey: '' + bucket: '' + region: '' + # 仅cloudisp 的值为 minio/s3 时配置,其它提供商为空 + forcePathStyle: false + # 仅cloudisp 的值为 minio 时配置,其它提供商为空 + endpoint: '' + +# jwt 配置 +jwt: + secretkey: 'zA_Think+KNOWLEDGE+WIKI+DOCUMENTS@2022' + expiresIn: '6h' diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..488956b --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,60 @@ +version: '3' +services: + think: + build: + context: . + image: think + container_name: think + volumes: + - ./config:/app/config + - ./runtime/static:/app/packages/server/static + environment: + - TZ=Asia/Shanghai + expose: + - '5001-5003' + ports: + - '5001-5003:5001-5003' + depends_on: + - mysql + - redis + networks: + - think + mysql: + image: mysql:5.7 + restart: always + container_name: mysql-for-think + volumes: + - ./runtime/mysql:/var/lib/mysql + environment: + - TZ=Asia/Shanghai + - MYSQL_ROOT_PASSWORD=root + - MYSQL_DATABASE=think + - MYSQL_USER=think + - MYSQL_PASSWORD=think + expose: + - '3306' + ports: + - '3306:3306' + command: + - '--character-set-server=utf8mb4' + - '--collation-server=utf8mb4_unicode_ci' + networks: + - think + redis: + image: redis:latest + restart: always + container_name: redis-for-think + command: > + --requirepass root + expose: + - '6379' + ports: + - '6379:6379' + volumes: + - ./runtime/redis:/data + privileged: true + networks: + - think +networks: + think: + driver: bridge diff --git a/docker/start.sh b/docker/start.sh new file mode 100644 index 0000000..821e6cc --- /dev/null +++ b/docker/start.sh @@ -0,0 +1,8 @@ +#!/bin/sh +### Author:jonnyan404 +### date:2022年5月22日 + +pnpm run pm2 +pm2 startup +pm2 save +pm2 logs diff --git a/dynamic.yaml b/dynamic.yaml new file mode 100644 index 0000000..d3d3434 --- /dev/null +++ b/dynamic.yaml @@ -0,0 +1,12 @@ +# 以下为前台动态渲染的配置,修改后,无需打包,重启服务即可 +dynamic: + # 输入 logo 的图片地址 + logo: '' + appName: '云策文档' + appDescription: '云策文档是一款开源知识管理工具。通过独立的知识库空间,结构化地组织在线协作文档,实现知识的积累与沉淀,促进知识的复用与流通。' + appKeywords: '云策文档,协作,文档,fantasticit,https://github.com/fantasticit/think' + # 版权信息,可以是 HTML + copyrightInformation: '

Develop by fantasticit

' + # 外部跳转按钮配置 + externalButtonText: 'Github' + externalButtonURL: 'https://github.com/fantasticit/think' diff --git a/how-to-use-docker.md b/how-to-use-docker.md new file mode 100644 index 0000000..97e82b8 --- /dev/null +++ b/how-to-use-docker.md @@ -0,0 +1,178 @@ +# 使用 docker-compose 进行项目部署 + +> 目标:使用 http://dev.think.codingit.cn 访问客户端;使用 http://dev.api.codingit.cn 访问服务端。 + +## 1. 新建 config/prod.yaml + +```yaml +# 开发环境配置 +client: + port: 5001 + assetPrefix: '/' + apiUrl: 'http://dev.api.codingit.cn/api' + collaborationUrl: 'ws://dev.api.codingit.cn/think/wss' + # 以下为页面 meta 配置 + seoAppName: '云策文档' + seoDescription: '云策文档是一款开源知识管理工具。通过独立的知识库空间,结构化地组织在线协作文档,实现知识的积累与沉淀,促进知识的复用与流通。' + seoKeywords: '云策文档,协作,文档,fantasticit,https://github.com/fantasticit/think' + # 预先连接的来源,空格分割(比如图片存储服务器) + dnsPrefetch: '//wipi.oss-cn-shanghai.aliyuncs.com' + # 站点地址(如:http://think.codingit.cn/),一定要设置,否则会出现 cookie、跨域等问题 + siteUrl: 'http://dev.think.codingit.cn' + siteDomain: '' + +server: + prefix: '/api' + port: 5002 + collaborationPort: 5003 + maxDocumentVersion: 20 # 最大版本记录数 + logRetainDays: 3 # 日志保留天数,比如只保留近三天日志 + enableRateLimit: true # 是否限流 + rateLimitWindowMs: 60000 # 限流时间 + rateLimitMax: 1000 # 单位限流时间内单个 ip 最大访问数量 + email: # 邮箱服务,参考 http://help.163.com/09/1223/14/5R7P6CJ600753VB8.html?servCode=6010376 获取 SMTP 配置 + host: '' + port: 465 + user: '' + password: '' + admin: + name: 'admin' # 注意修改 + password: 'admin' # 注意修改 + email: 'admin@think.com' # 注意修改为真实邮箱地址 + +# 数据库配置 +db: + mysql: + host: 'mysql-for-think' + username: 'think' + password: 'think' + database: 'think' + port: 3306 + charset: 'utf8mb4' + timezone: '+08:00' + synchronize: true + redis: + host: 'redis-for-think' + port: '6379' + password: 'root' + +# oss 文件存储服务 +oss: + local: + enable: true + # 线上更改为服务端地址(如:https://api.codingit.cn) + server: 'http://dev.api.codingit.cn' + # 以下为各厂商 sdk 配置,不要修改字段,填入值即可 + tencent: + enable: false + config: + SecretId: '' + SecretKey: '' + Bucket: '' + Region: '' + aliyun: + enable: false + config: + accessKeyId: '' + accessKeySecret: '' + bucket: '' + https: true + region: '' + +# jwt 配置 +jwt: + secretkey: 'zA_Think+KNOWLEDGE+WIKI+DOCUMENTS@2022' + expiresIn: '6h' +``` + +## 2. 新建 nginx.conf + +```shell +upstream think_client { + server 127.0.0.1:5001; + keepalive 64; +} + +upstream think_server { + server 127.0.0.1:5002; + keepalive 64; +} + +upstream think_wss { + server 127.0.0.1:5003; + keepalive 64; +} + +server { + listen 80; + server_name dev.api.codingit.cn; + + client_max_body_size 100m; + + location /api { + proxy_pass http://think_server; + proxy_read_timeout 300s; + proxy_send_timeout 300s; + + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + } + + location /think/wss { + proxy_pass http://think_wss; + proxy_read_timeout 300s; + proxy_send_timeout 300s; + + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + } + + location /static/ { + proxy_pass http://think_server; + } +} + +server { + listen 80; + server_name dev.think.codingit.cn; + + location / { + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header X-Nginx-Proxy true; + proxy_cache_bypass $http_upgrade; + proxy_pass http://think_client; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } +} +``` + +3. 构建项目 + +```shell +cd think +docker-compose up -d +``` + +4. 可选:配置 hosts + +```shell +127.0.0.1 dev.api.codingit.cn +127.0.0.1 dev.think.codingit.cn +``` + +5. 访问 + +浏览器访问:http://dev.think.codingit.cn。 diff --git a/let-us-start.md b/let-us-start.md new file mode 100644 index 0000000..5dbce13 --- /dev/null +++ b/let-us-start.md @@ -0,0 +1,126 @@ +# think + +## 项目结构 + +本项目依赖 pnpm 使用 monorepo 形式进行代码组织,分包如下: + +- `@think/config`: 客户端、服务端、OSS、MySQL、Redis 等配置管理 +- `@think/domains`:领域模型数据定义 +- `@think/constants`:常量配置 +- `@think/server`:服务端 +- `@think/client`:客户端 + +## 项目依赖 + +为了将项目运行起来,至少需要以下依赖。 + +- nodejs >=16.5.0:推荐使用 nvm 安装 +- pnpm:安装 nodejs 后,运行 `npm i -g pnpm` 即可安装 +- pm2:安装 nodejs 后,运行 `npm i -g pm2` 即可安装 +- MySQL 5.7 +- Redis + +## 配置文件 + +项目所有的配置文件都在 `config` 目录下,其中 `dev.yaml` 中各字段均有解释,生产环境打包依赖 `prod.yaml`(需要自行修改为所需配置)。如果运行不起来,请对比 `dev.yaml` 检查配置。 + +**如果部署遇到问题,首先请确认相应配置是否正确!** + +## 项目运行 + +无论是开发环境,还是生产环境,项目运行成功后会在 3 个端口启动相应服务(默认 5001、5002、5003),具体端口号由 `config` 文件夹下的配置文件决定。 + +- 前台页面地址:`http://localhost:5001` +- 服务接口地址:`http://localhost:5002` +- 协作接口地址:`http://localhost:5003` + +### 本地开发 + +1. 安装数据库 + +首先安装 `MySQL` 和 `Redis`,推荐使用 docker 进行安装。 + +```bash +docker image pull mysql:5.7 +# m1 的 mac 可以用:docker image pull --platform linux/x86_64 mysql:5.7 +docker run -d --restart=always --name mysql-for-think-dev -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -e MYSQL_USER=think -e MYSQL_PASSWORD=think -e MYSQL_DATABASE=think mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci + +docker pull redis:latest +docker run --name redis-for-think-dev -p 6379:6379 -d redis --appendonly yes --requirepass "root" +``` + +2. 安装依赖并运行 + +```bash +git clone https://github.com/fantasticit/think.git +cd think +pnpm install +pnpm run build:dep +pnpm run dev +``` + +### 生产部署 + +首先确认在 `config` 文件夹下新建 `prod.yaml` 配置文件,然后运行以下命令。 + +**编译打包过程比较吃内存(大约 2G),小内存服务器建议本地构建后上传,可以在配置文件完成后,运行 build-output.sh,将打包后的 output 压缩发送到服务器后运行**。 + +```bash +git clone https://github.com/fantasticit/think.git +cd think +pnpm install # 安装依赖 +pnpm run build # 项目打包 + +# 以下如果没有安装 pm2,直接 pnpm run start,推荐使用 pm2 +pnpm run pm2 +pm2 startup +pm2 save +``` + +#### swc 导致打包失败 + +要么根据报错安装相关系统环境依赖,要么在`think/packages/client`目录下加入 **.babelrc** 文件。 + +文件内容: + +``` +{ + "presets": ["next/babel"] +} +``` + +### docker-compose + +也可以使用 docker-compose 进行项目部署。首先,根据需要修改 `docker-compose.yml` 中的数据库、Redis 相关用户名、密码等配置,然后,从 `config/docker-prod-sample.yaml` 复制出 `config/prod.yaml` 并修改其中对应的配置。 + +```bash +# 首次安装 +git clone https://github.com/fantasticit/think.git +cd think +docker-compose up -d + +# 二次更新升级 +cd think +git pull +docker-compose build +docker-compose up -d + +# 如果二次更新有问题 +docker-compose kill +docker-compose rm +docker image rm think # 删掉构建的镜像 +docker-compose up -d +``` + +更多细节可以查看 [how-to-use-docker.md](./how-to-use-docker.md)。 + +### nginx 配置参考 + +无论以何种方式进行项目部署,项目运行成功后会在 3 个端口启动服务(默认 5001、5002、5003,具体由配置文件决定)。`nginx` 配置参考 <[think/nginx.conf.sample](https://github.com/fantasticit/think/blob/main/nginx.conf.sample)>。 + +特别强调,在 `config` 文件夹的配置中 `client.siteUrl` 一定要配置正确,否则客户端可能无法正常运行。 + +```yaml +# 站点地址(如:http://think.codingit.cn/),一定要设置,否则会出现 cookie、跨域等问题 +siteUrl: 'http://localhost:5001' +``` diff --git a/nginx.conf.sample b/nginx.conf.sample new file mode 100644 index 0000000..4a9ba25 --- /dev/null +++ b/nginx.conf.sample @@ -0,0 +1,69 @@ +upstream think_client { + server 127.0.0.1:5001; + keepalive 64; +} + +upstream think_server { + server 127.0.0.1:5002; + keepalive 64; +} + +upstream think_wss { + server 127.0.0.1:5003; + keepalive 64; +} + +server { + listen 80; + server_name dev.api.codingit.cn; + + client_max_body_size 100m; + + location /api { + proxy_pass http://think_server; + proxy_read_timeout 300s; + proxy_send_timeout 300s; + + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + } + + location /think/wss { + proxy_pass http://think_wss; + proxy_read_timeout 300s; + proxy_send_timeout 300s; + + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + } + + location /static/ { + proxy_pass http://think_server; + } +} + +server { + listen 80; + server_name dev.think.codingit.cn; + + location / { + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header X-Nginx-Proxy true; + proxy_cache_bypass $http_upgrade; + proxy_pass http://think_client; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..e02235f --- /dev/null +++ b/package.json @@ -0,0 +1,65 @@ +{ + "name": "think", + "private": true, + "author": "fantasticit", + "scripts": { + "clean": "npx rimraf ./node_modules ./packages/**/node_modules ./packages/**/.next", + "dev": "concurrently 'pnpm:dev:*'", + "dev:server": "pnpm run --dir packages/server dev", + "dev:client": "pnpm run --dir packages/client dev", + "build": "pnpm build:dep && pnpm build:server && pnpm build:client", + "build:dep": "pnpm build:constants && pnpm build:domains && pnpm build:config", + "build:constants": "pnpm run --dir packages/constants build", + "build:domains": "pnpm run --dir packages/domains build", + "build:config": "pnpm run --dir packages/config build", + "build:server": "pnpm run --dir packages/server build", + "build:client": "pnpm run --dir packages/client build", + "start": "concurrently 'pnpm:start:*'", + "start:server": "pnpm run --dir packages/server start", + "start:client": "pnpm run --dir packages/client start", + "pm2": "pnpm run pm2:server && pnpm run pm2:client", + "pm2:server": "pnpm run --dir packages/server pm2", + "pm2:client": "pnpm run --dir packages/client pm2", + "lint": "concurrently 'pnpm:lint:*'", + "lint:client": "eslint --fix './packages/client/**/*.{ts,tsx,js,jsx}'", + "lint:server": "eslint --fix './packages/server/**/*.{ts,js}'", + "format": "concurrently 'pnpm:format:*'", + "format:ts": "prettier --write --parser typescript 'packages/**/*.{ts,tsx,js,jsx}'", + "format:css": "stylelint --fix --formatter verbose --allow-empty-input 'packages/**/*.{css,scss,sass}'", + "prepare": "husky install", + "precommit": "lint-staged" + }, + "dependencies": { + "concurrently": "^7.0.0", + "cross-env": "^7.0.3", + "fs-extra": "^10.0.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=16.5.0" + }, + "devDependencies": { + "@types/node": "^17.0.35", + "husky": "^7.0.4", + "lint-staged": "^12.4.1", + "prettier": "^2.3.2", + "stylelint": "^14.6.1", + "stylelint-config-css-modules": "^4.1.0", + "stylelint-config-prettier": "^9.0.3", + "stylelint-config-standard": "^25.0.0", + "stylelint-config-standard-scss": "^3.0.0", + "stylelint-order": "^5.0.0", + "stylelint-prettier": "^2.0.0", + "typescript": "^4.5.5" + }, + "lint-staged": { + "*.{ts,tsx,js,jsx}": "prettier --write", + "./packages/client/**/*.{ts,tsx,js,jsx}": [ + "eslint --fix" + ], + "./packages/server/src/*.{ts,js}": [ + "eslint --fix" + ], + "*.{css,scss,sass}": "stylelint --fix --formatter verbose --allow-empty-input" + } +} \ No newline at end of file diff --git a/packages/client/.eslintrc.js b/packages/client/.eslintrc.js new file mode 100644 index 0000000..1646ab3 --- /dev/null +++ b/packages/client/.eslintrc.js @@ -0,0 +1,75 @@ +module.exports = { + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint', 'react-hooks', 'simple-import-sort', 'prettier'], + extends: [ + 'eslint:recommended', + 'plugin:react/recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:prettier/recommended', + ], + overrides: [ + { + files: ['*.ts', '*.tsx', '.js', '.jsx'], + parserOptions: { + project: ['./tsconfig.json'], + tsconfigRootDir: __dirname, + sourceType: 'module', + }, + }, + ], + settings: { + 'react': { + version: 'detect', + }, + 'import/resolver': { + node: { + paths: ['src'], + extensions: ['.js', '.jsx', '.ts', '.tsx'], + }, + }, + }, + env: { + es6: true, + browser: true, + node: true, + }, + rules: { + 'func-names': 0, + 'no-shadow': 0, + '@typescript-eslint/no-shadow': 0, + '@typescript-eslint/no-unused-vars': [0, { argsIgnorePattern: '^_' }], + '@typescript-eslint/no-use-before-define': 0, + '@typescript-eslint/ban-ts-ignore': 0, + '@typescript-eslint/no-empty-function': 0, + '@typescript-eslint/ban-ts-comment': 0, + '@typescript-eslint/no-var-requires': 0, + '@typescript-eslint/no-explicit-any': 0, + '@typescript-eslint/no-this-alias': 0, + '@typescript-eslint/explicit-module-boundary-types': 0, + '@typescript-eslint/ban-types': 0, + 'react-hooks/rules-of-hooks': 2, + 'react-hooks/exhaustive-deps': 2, + 'testing-library/no-unnecessary-act': 0, + 'prettier/prettier': ['error', {}, { usePrettierrc: true }], + 'react/react-in-jsx-scope': 'off', + 'react/prop-types': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + 'simple-import-sort/imports': [ + 'error', + { + groups: [ + ['react'], + ['@douyinfe(.*)$'], + ['(@)?think(.*)$'], + ['(@)?tiptap(.*)$'], + ['^@?\\w'], + ['@/(.*)'], + ['^[./]'], + ['(.*).module.scss'], + ], + }, + ], + 'simple-import-sort/exports': 'error', + }, + ignorePatterns: ['dist/', 'node_modules', 'scripts', 'examples'], +}; diff --git a/packages/client/.gitignore b/packages/client/.gitignore new file mode 100644 index 0000000..a6e11c6 --- /dev/null +++ b/packages/client/.gitignore @@ -0,0 +1,42 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env.local +.env.development.local +.env.test.local +.env.production.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo + +# service-worker.js +/public/manifest.json +/public/service-worker.js +/public/workbox-*.js diff --git a/packages/client/README.md b/packages/client/README.md new file mode 100644 index 0000000..b5d08bd --- /dev/null +++ b/packages/client/README.md @@ -0,0 +1,3 @@ +# @think/client + +> 客户端。 diff --git a/packages/client/copy-diagram-resources.js b/packages/client/copy-diagram-resources.js new file mode 100755 index 0000000..581ab16 --- /dev/null +++ b/packages/client/copy-diagram-resources.js @@ -0,0 +1,85 @@ +/** + * 将流程图编辑器所需的资源拷贝到 .next 目录中,配合 nginx 运行 + */ +const fs = require('fs-extra'); +const { getConfig } = require('@think/config'); +const config = getConfig(); + +const buildManifestJson = () => { + return JSON.stringify({ + name: config.client.seoAppName, + short_name: config.client.seoAppName, + display: 'standalone', + start_url: '/', + theme_color: '#ffffff', + background_color: '#ffffff', + icons: [ + { + src: '/icon72.png', + sizes: '72x72', + type: 'image/png', + }, + { + src: '/icon96.png', + sizes: '96x96', + type: 'image/png', + }, + { + src: '/icon120.png', + sizes: '120x120', + type: 'image/png', + }, + { + src: '/icon128.png', + sizes: '128x128', + type: 'image/png', + }, + { + src: '/icon144.png', + sizes: '144x144', + type: 'image/png', + }, + { + src: '/icon152.png', + sizes: '152x152', + type: 'image/png', + }, + { + src: '/icon180.png', + sizes: '180x180', + type: 'image/png', + }, + { + src: '/icon192.png', + sizes: '192x192', + type: 'image/png', + }, + { + src: '/icon384.png', + sizes: '384x384', + type: 'image/png', + }, + { + src: '/icon512.png', + sizes: '512x512', + type: 'image/png', + }, + { + src: '/maskable.png', + sizes: '192x192', + type: 'image/png', + purpose: 'maskable', + }, + ], + }); +}; + +fs.copySync('./public', './.next', { + filter: (src) => { + // 生产环境使用 diagram.min.js + return !/diagram.js$/.test(src); + }, +}); + +fs.outputFileSync('./.next/manifest.json', buildManifestJson()); +fs.outputFileSync('./public/manifest.json', buildManifestJson()); diff --git a/packages/client/dev-server.js b/packages/client/dev-server.js new file mode 100755 index 0000000..bb30baa --- /dev/null +++ b/packages/client/dev-server.js @@ -0,0 +1,12 @@ +const { getConfig } = require('@think/config'); +const config = getConfig(); +const cli = require('next/dist/cli/next-dev'); + +const port = (config.client && config.client.port) || 5001; + +try { + cli.nextDev(['-p', port]); + console.log(`[think] 客户端已启动,端口:${port}`); +} catch (err) { + console.log(`[think] 客户端启动失败!${err.message || err}`); +} diff --git a/packages/client/global.d.ts b/packages/client/global.d.ts new file mode 100644 index 0000000..c449ed4 --- /dev/null +++ b/packages/client/global.d.ts @@ -0,0 +1,6 @@ +interface Window { + // drawio 绘图 + GraphViewer: any; + // 百度脑图 + kityminder: any; +} diff --git a/packages/client/next-env.d.ts b/packages/client/next-env.d.ts new file mode 100644 index 0000000..4f11a03 --- /dev/null +++ b/packages/client/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/packages/client/next.config.js b/packages/client/next.config.js new file mode 100644 index 0000000..35dd319 --- /dev/null +++ b/packages/client/next.config.js @@ -0,0 +1,43 @@ +const semi = require('@douyinfe/semi-next').default({}); +const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); + +const { getConfig } = require('@think/config'); +const config = getConfig(); + +const pwaRuntimeCaching = require('./pwa-cache'); +const withPWA = require('next-pwa')({ + disable: process.env.NODE_ENV !== 'production', + dest: 'public', + sw: 'service-worker.js', + runtimeCaching: pwaRuntimeCaching, +}); + +/** @type {import('next').NextConfig} */ +const nextConfig = semi({ + experimental: { + scrollRestoration: true, + legacyBrowsers: false, + browsersListForSwc: true, + }, + assetPrefix: config.assetPrefix, + env: { + SERVER_API_URL: config.client.apiUrl, + COLLABORATION_API_URL: config.client.collaborationUrl, + ENABLE_OSS_S3: config.oss.s3?.enable, + DNS_PREFETCH: (config.client.dnsPrefetch || '').split(' '), + SITE_URL: config.client.siteUrl, + }, + webpack: (config, { dev, isServer }) => { + config.resolve.plugins.push(new TsconfigPathsPlugin()); + return config; + }, + eslint: { + ignoreDuringBuilds: true, + }, + // FIXME: douyinfe 的第三方包存在 ts 类型错误! + typescript: { + ignoreBuildErrors: true, + }, +}); + +module.exports = withPWA(nextConfig); diff --git a/packages/client/package.json b/packages/client/package.json new file mode 100644 index 0000000..0975bc4 --- /dev/null +++ b/packages/client/package.json @@ -0,0 +1,133 @@ +{ + "name": "@think/client", + "private": true, + "scripts": { + "build": "rimraf .next && npx next telemetry disable && next build && node copy-diagram-resources.js", + "dev": "node dev-server.js", + "start": "cross-env NODE_ENV=production node prod-server.js", + "pm2": "pm2 start npm --name @think/client -- start" + }, + "dependencies": { + "@douyinfe/semi-icons": "^2.18.0", + "@douyinfe/semi-next": "^2.18.0", + "@douyinfe/semi-ui": "^2.18.0", + "@excalidraw/excalidraw": "^0.12.0", + "@hocuspocus/provider": "^1.0.0-alpha.29", + "@react-pdf-viewer/core": "3.9.0", + "@react-pdf-viewer/default-layout": "3.9.0", + "@react-pdf-viewer/locales": "^1.0.0", + "@think/config": "workspace:^1.0.0", + "@think/constants": "workspace:^1.0.0", + "@think/domains": "workspace:^1.0.0", + "@tiptap/core": "^2.0.0-beta.171", + "@tiptap/extension-blockquote": "^2.0.0-beta.26", + "@tiptap/extension-bold": "^2.0.0-beta.25", + "@tiptap/extension-bullet-list": "^2.0.0-beta.26", + "@tiptap/extension-code": "^2.0.0-beta.26", + "@tiptap/extension-code-block": "^2.0.0-beta.37", + "@tiptap/extension-code-block-lowlight": "^2.0.0-beta.68", + "@tiptap/extension-color": "^2.0.0-beta.9", + "@tiptap/extension-document": "^2.0.0-beta.15", + "@tiptap/extension-dropcursor": "^2.0.0-beta.25", + "@tiptap/extension-gapcursor": "^2.0.0-beta.34", + "@tiptap/extension-hard-break": "^2.0.0-beta.30", + "@tiptap/extension-heading": "^2.0.0-beta.26", + "@tiptap/extension-highlight": "^2.0.0-beta.33", + "@tiptap/extension-history": "^2.0.0-beta.21", + "@tiptap/extension-image": "^2.0.0-beta.25", + "@tiptap/extension-italic": "^2.0.0-beta.25", + "@tiptap/extension-link": "^2.0.0-beta.36", + "@tiptap/extension-list-item": "^2.0.0-beta.20", + "@tiptap/extension-mention": "^2.0.0-beta.95", + "@tiptap/extension-ordered-list": "^2.0.0-beta.27", + "@tiptap/extension-paragraph": "^2.0.0-beta.23", + "@tiptap/extension-placeholder": "^2.0.0-beta.47", + "@tiptap/extension-strike": "^2.0.0-beta.27", + "@tiptap/extension-subscript": "^2.0.0-beta.10", + "@tiptap/extension-superscript": "^2.0.0-beta.10", + "@tiptap/extension-table": "^2.0.0-beta.48", + "@tiptap/extension-table-cell": "^2.0.0-beta.20", + "@tiptap/extension-table-header": "^2.0.0-beta.22", + "@tiptap/extension-table-row": "^2.0.0-beta.19", + "@tiptap/extension-task-item": "^2.0.0-beta.31", + "@tiptap/extension-task-list": "^2.0.0-beta.26", + "@tiptap/extension-text": "^2.0.0-beta.15", + "@tiptap/extension-text-align": "^2.0.0-beta.29", + "@tiptap/extension-text-style": "^2.0.0-beta.23", + "@tiptap/extension-underline": "^2.0.0-beta.23", + "@tiptap/react": "^2.0.0-beta.107", + "@tiptap/suggestion": "^2.0.0-beta.90", + "axios": "^0.25.0", + "buffer-image-size": "^0.6.4", + "classnames": "^2.3.1", + "clone": "^2.1.2", + "cross-env": "^7.0.3", + "deep-equal": "^2.0.5", + "dompurify": "^2.3.5", + "file-saver": "^2.0.5", + "htmldiff-js": "^1.0.5", + "interactjs": "^1.10.11", + "katex": "^0.15.2", + "kity": "^2.0.4", + "lib0": "^0.2.47", + "lodash.pick": "^4.4.0", + "lowlight": "^2.5.0", + "markdown-it": "^12.3.2", + "markdown-it-anchor": "^8.4.1", + "markdown-it-container": "^3.0.0", + "markdown-it-emoji": "^2.0.0", + "markdown-it-sub": "^1.0.0", + "markdown-it-sup": "^1.0.0", + "next": "12.1.0", + "next-pwa": "^5.6.0", + "pdfjs-dist": "3.1.81", + "prosemirror-codemark": "^0.4.2", + "prosemirror-commands": "^1.3.0", + "prosemirror-markdown": "^1.7.0", + "prosemirror-model": "^1.16.1", + "prosemirror-schema-list": "^1.1.6", + "prosemirror-state": "^1.3.4", + "prosemirror-tables": "^1.1.1", + "prosemirror-utils": "^0.9.6", + "prosemirror-view": "^1.23.6", + "react": "17.0.2", + "react-countdown": "^2.3.2", + "react-dom": "17.0.2", + "react-full-screen": "^1.1.1", + "react-helmet": "^6.1.0", + "react-lazy-load-image-component": "^1.5.4", + "react-query": "^3.39.0", + "react-split-pane": "^0.1.92", + "react-visibility-sensor": "^5.1.1", + "requestidlecallback-polyfill": "^1.0.2", + "resize-observer-polyfill": "^1.5.1", + "scroll-into-view-if-needed": "^2.2.29", + "spark-md5": "^3.0.2", + "timeago.js": "^4.0.2", + "tippy.js": "^6.3.7", + "toggle-selection": "^1.0.6", + "viewerjs": "^1.10.4", + "yjs": "^13.5.24" + }, + "devDependencies": { + "@types/deep-equal": "^1.0.4", + "@types/lodash.pick": "^4.4.9", + "@types/node": "17.0.13", + "@types/react": "17.0.38", + "@types/react-dom": "17.0.11", + "@types/react-lazy-load-image-component": "^1.6.3", + "@typescript-eslint/eslint-plugin": "^5.21.0", + "@typescript-eslint/parser": "^5.21.0", + "copy-webpack-plugin": "11.0.0", + "eslint": "^8.14.0", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-prettier": "^4.0.0", + "eslint-plugin-react": "^7.29.4", + "eslint-plugin-react-hooks": "^4.5.0", + "eslint-plugin-simple-import-sort": "^7.0.0", + "fs-extra": "^10.0.0", + "tsconfig-paths-webpack-plugin": "^3.5.2", + "typescript": "^4.8.4" + } +} diff --git a/packages/client/prod-server.js b/packages/client/prod-server.js new file mode 100755 index 0000000..88dbd11 --- /dev/null +++ b/packages/client/prod-server.js @@ -0,0 +1,12 @@ +const { getConfig } = require('@think/config'); +const config = getConfig(); +const cli = require('next/dist/cli/next-start'); + +const port = (config.client && config.client.port) || 5001; + +try { + cli.nextStart(['-p', port]); + console.log(`[think] 客户端已启动,端口:${port}`); +} catch (err) { + console.log(`[think] 客户端启动失败!${err.message || err}`); +} diff --git a/packages/client/public/diagram.min.js b/packages/client/public/diagram.min.js new file mode 100644 index 0000000..5be0237 --- /dev/null +++ b/packages/client/public/diagram.min.js @@ -0,0 +1,3 @@ +window.urlParams=window.urlParams||{},window.MAX_REQUEST_SIZE=window.MAX_REQUEST_SIZE||10485760,window.MAX_AREA=window.MAX_AREA||225e6,window.mxBasePath="/diagram",window.RESOURCES_PATH="/diagram/resources",window.STENCIL_PATH="/diagram/stencils",window.IMAGE_PATH="/diagram/images",window.STYLE_PATH="/diagram/styles",window.CSS_PATH="/diagram/styles";var HoverIcons=function(){},mxCellEditorGetInitialValue=function(){},mxCellEditorGetCurrentValue=function(){},mxGraphHandlerIsValidDropTarget=function(){},Format=function(){},BaseFormatPanel=function(){},ArrangePanel=function(){},TextFormatPanel=function(){},StyleFormatPanel=function(){},DiagramStylePanel=function(){},DiagramFormatPanel=function(){},Menus=function(){},mxJSColor={dir:"",bindClass:"color",binding:!0,preloading:!0,install:function(){},init:function(){mxJSColor.preloading&&mxJSColor.preload()},getDir:function(){var t;return mxJSColor.dir||(t=mxJSColor.detectDir(),mxJSColor.dir=!1!==t?t:"jscolor/"),mxJSColor.dir},detectDir:function(){for(var t=location.href,e=document.getElementsByTagName("base"),n=0;no[t]&&-s[t]+i[t]+l[t]/2>o[t]/2&&0<=i[t]+l[t]-r[t]?(i[t],l[t],r[t]):i[t],-s[e]+i[e]+l[e]+r[e]-a+a*n>o[e]?-s[e]+i[e]+l[e]/2>o[e]/2&&0<=i[e]+l[e]-a-a*n?(i[e],l[e]):(i[e],l[e]):0<=i[e]+l[e]-a+a*n?(i[e],l[e]):(i[e],l[e])):(i[t],i[e],l[e]),drawPicker(0,0)}},this.importColor=function(){valueElement?this.adjust?!this.required&&/^\s*$/.test(valueElement.value)?(valueElement.value="",styleElement.style.backgroundImage=styleElement.jscStyle.backgroundImage,styleElement.style.backgroundColor=styleElement.jscStyle.backgroundColor,styleElement.style.color=styleElement.jscStyle.color,this.exportColor(leaveValue|leaveStyle)):this.fromString(valueElement.value)||this.exportColor():this.fromString(valueElement.value,leaveValue)||(styleElement.style.backgroundImage=styleElement.jscStyle.backgroundImage,styleElement.style.backgroundColor=styleElement.jscStyle.backgroundColor,styleElement.style.color=styleElement.jscStyle.color,this.exportColor(leaveValue|leaveStyle)):this.exportColor()},this.exportColor=function(t){var e;t&leaveValue||!valueElement||(e=this.toString(),this.caps&&(e=e.toUpperCase()),this.hash&&(e="#"+e),valueElement.value=e),t&leaveStyle||!styleElement||(styleElement.style.backgroundImage="none",styleElement.style.backgroundColor="#"+this.toString(),styleElement.style.color=.213*this.rgb[0]+.715*this.rgb[1]+.072*this.rgb[2]<.5?"#FFF":"#000"),t&leavePad||!isPickerOwner()||redrawPad(),t&leaveSld||!isPickerOwner()||redrawSld()},this.fromHSV=function(t,e,n,i){t<0&&(t=0)||6>>6:(n<65536?e[l++]=224|n>>>12:(e[l++]=240|n>>>18,e[l++]=128|n>>>12&63),e[l++]=128|n>>>6&63),e[l++]=128|63&n);return e},n.buf2binstring=function(t){return d(t,t.length)},n.binstring2buf=function(t){for(var e=new a.Buf8(t.length),n=0,i=e.length;n>10&1023,o[n++]=56320|1023&i)}return d(o,n)},n.utf8border=function(t,e){var n;for((e=e||t.length)>t.length&&(e=t.length),n=e-1;0<=n&&128==(192&t[n]);)n--;return!(n<0)&&0!==n&&n+h[t[n]]>e?n:e}},{"./common":3}],5:[function(t,e,n){"use strict";e.exports=function(t,e,n,i){for(var l=65535&t|0,s=t>>>16&65535|0,o=0;0!==n;){for(n-=o=2e3>>1:t>>>1;e[n]=t}return e}();e.exports=function(t,e,n,i){var l=r,s=i+n;t^=-1;for(var o=i;o>>8^l[255&(t^e[o])];return-1^t}},{}],8:[function(t,e,n){"use strict";var r,u=t("../utils/common"),a=t("./trees"),p=t("./adler32"),m=t("./crc32"),i=t("./messages"),h=0,d=0,c=-2,l=2,g=8,s=286,o=30,x=19,y=2*s+1,f=15,C=3,v=258,E=v+C+1,S=42,w=113;function b(t,e){return t.msg=i[e],e}function T(t){return(t<<1)-(4t.avail_out&&(n=t.avail_out),0!==n&&(u.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 I(t,e){a._tr_flush_block(t,0<=t.block_start?t.block_start:-1,t.strstart-t.block_start,e),t.block_start=t.strstart,L(t.strm)}function M(t,e){t.pending_buf[t.pending++]=e}function R(t,e){t.pending_buf[t.pending++]=e>>>8&255,t.pending_buf[t.pending++]=255&e}function P(t,e){var n,i,l=t.max_chain_length,s=t.strstart,o=t.prev_length,r=t.nice_match,a=t.strstart>t.w_size-E?t.strstart-(t.w_size-E):0,h=t.window,d=t.w_mask,u=t.prev,p=t.strstart+v,m=h[s+o-1],c=h[s+o];t.prev_length>=t.good_match&&(l>>=2),r>t.lookahead&&(r=t.lookahead);do{if(h[(n=e)+o]===c&&h[n+o-1]===m&&h[n]===h[s]&&h[++n]===h[s+1]){for(s+=2,n++;h[++s]===h[++n]&&h[++s]===h[++n]&&h[++s]===h[++n]&&h[++s]===h[++n]&&h[++s]===h[++n]&&h[++s]===h[++n]&&h[++s]===h[++n]&&h[++s]===h[++n]&&sa&&0!=--l);return o<=t.lookahead?o:t.lookahead}function U(t){var e,n,i,l,s,o,r,a,h,d=t.w_size;do{if(l=t.window_size-t.lookahead-t.strstart,t.strstart>=d+(d-E)){for(u.arraySet(t.window,t.window,d,d,0),t.match_start-=d,t.strstart-=d,t.block_start-=d,e=n=t.hash_size;i=t.head[--e],t.head[e]=d<=i?i-d:0,--n;);for(e=n=d;i=t.prev[--e],t.prev[e]=d<=i?i-d:0,--n;);l+=d}if(0===t.strm.avail_in)break;if(o=t.strm,r=t.window,a=t.strstart+t.lookahead,h=void 0,l<(h=o.avail_in)&&(h=l),n=0===h?0:(o.avail_in-=h,u.arraySet(r,o.input,o.next_in,h,a),1===o.state.wrap?o.adler=p(o.adler,r,h,a):2===o.state.wrap&&(o.adler=m(o.adler,r,h,a)),o.next_in+=h,o.total_in+=h,h),t.lookahead+=n,t.lookahead+t.insert>=C)for(s=t.strstart-t.insert,t.ins_h=t.window[s],t.ins_h=(t.ins_h<=C&&(t.ins_h=(t.ins_h<=C)if(i=a._tr_tally(t,t.strstart-t.match_start,t.match_length-C),t.lookahead-=t.match_length,t.match_length<=t.max_lazy_match&&t.lookahead>=C){for(t.match_length--;t.strstart++,t.ins_h=(t.ins_h<=C&&(t.ins_h=(t.ins_h<=C&&t.match_length<=t.prev_length){for(l=t.strstart+t.lookahead-C,i=a._tr_tally(t,t.strstart-1-t.prev_match,t.prev_length-C),t.lookahead-=t.prev_length-1,t.prev_length-=2;++t.strstart<=l&&(t.ins_h=(t.ins_h<t.pending_buf_size-5&&(n=t.pending_buf_size-5);;){if(t.lookahead<=1){if(U(t),0===t.lookahead&&e===h)return 1;if(0===t.lookahead)break}t.strstart+=t.lookahead,t.lookahead=0;var i=t.block_start+n;if((0===t.strstart||t.strstart>=i)&&(t.lookahead=t.strstart-i,t.strstart=i,I(t,!1),0===t.strm.avail_out))return 1;if(t.strstart-t.block_start>=t.w_size-E&&(I(t,!1),0===t.strm.avail_out))return 1}return t.insert=0,4===e?(I(t,!0),0===t.strm.avail_out?3:4):(t.strstart>t.block_start&&(I(t,!1),t.strm.avail_out),1)}),new H(4,4,8,4,O),new H(4,5,16,8,O),new H(4,6,32,32,O),new H(4,4,16,16,N),new H(8,16,32,32,N),new H(8,16,128,128,N),new H(8,32,128,256,N),new H(32,128,258,1024,N),new H(32,258,258,4096,N)],n.deflateInit=function(t,e){return k(t,e,g,15,8,0)},n.deflateInit2=k,n.deflateReset=G,n.deflateResetKeep=D,n.deflateSetHeader=function(t,e){return!t||!t.state||2!==t.state.wrap?c:(t.state.gzhead=e,d)},n.deflate=function(t,e){var n,i,l,s;if(!t||!t.state||5>8&255),M(n,n.gzhead.time>>16&255),M(n,n.gzhead.time>>24&255),M(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),M(n,255&n.gzhead.os),n.gzhead.extra&&n.gzhead.extra.length&&(M(n,255&n.gzhead.extra.length),M(n,n.gzhead.extra.length>>8&255)),n.gzhead.hcrc&&(t.adler=m(t.adler,n.pending_buf,n.pending,0)),n.gzindex=0,n.status=69):(M(n,0),M(n,0),M(n,0),M(n,0),M(n,0),M(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),M(n,3),n.status=w)):(s=g+(n.w_bits-8<<4)<<8,s|=(2<=n.strategy||n.level<2?0:n.level<6?1:6===n.level?2:3)<<6,0!==n.strstart&&(s|=32),s+=31-s%31,n.status=w,R(n,s),0!==n.strstart&&(R(n,t.adler>>>16),R(n,65535&t.adler)),t.adler=1)),69===n.status)if(n.gzhead.extra){for(i=n.pending;n.gzindex<(65535&n.gzhead.extra.length)&&(n.pending!==n.pending_buf_size||(n.gzhead.hcrc&&n.pending>i&&(t.adler=m(t.adler,n.pending_buf,n.pending-i,i)),L(t),i=n.pending,n.pending!==n.pending_buf_size));)M(n,255&n.gzhead.extra[n.gzindex]),n.gzindex++;n.gzhead.hcrc&&n.pending>i&&(t.adler=m(t.adler,n.pending_buf,n.pending-i,i)),n.gzindex===n.gzhead.extra.length&&(n.gzindex=0,n.status=73)}else n.status=73;if(73===n.status)if(n.gzhead.name){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(t.adler=m(t.adler,n.pending_buf,n.pending-i,i)),L(t),i=n.pending,n.pending===n.pending_buf_size)){l=1;break}}while(M(n,l=n.gzindexi&&(t.adler=m(t.adler,n.pending_buf,n.pending-i,i)),0===l&&(n.gzindex=0,n.status=91)}else n.status=91;if(91===n.status)if(n.gzhead.comment){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(t.adler=m(t.adler,n.pending_buf,n.pending-i,i)),L(t),i=n.pending,n.pending===n.pending_buf_size)){l=1;break}}while(M(n,l=n.gzindexi&&(t.adler=m(t.adler,n.pending_buf,n.pending-i,i)),0===l&&(n.status=103)}else n.status=103;if(103===n.status&&(n.gzhead.hcrc?(n.pending+2>n.pending_buf_size&&L(t),n.pending+2<=n.pending_buf_size&&(M(n,255&t.adler),M(n,t.adler>>8&255),t.adler=0,n.status=w)):n.status=w),0!==n.pending){if(L(t),0===t.avail_out)return n.last_flush=-1,d}else if(0===t.avail_in&&T(e)<=T(o)&&4!==e)return b(t,-5);if(666===n.status&&0!==t.avail_in)return b(t,-5);if(0!==t.avail_in||0!==n.lookahead||e!==h&&666!==n.status){var o=2===n.strategy?function(t,e){for(var n;;){if(0===t.lookahead&&(U(t),0===t.lookahead)){if(e===h)return 1;break}if(t.match_length=0,n=a._tr_tally(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++,n&&(I(t,!1),0===t.strm.avail_out))return 1}return t.insert=0,4===e?(I(t,!0),0===t.strm.avail_out?3:4):t.last_lit&&(I(t,!1),0===t.strm.avail_out)?1:2}(n,e):3===n.strategy?function(t,e){for(var n,i,l,s,o=t.window;;){if(t.lookahead<=v){if(U(t),t.lookahead<=v&&e===h)return 1;if(0===t.lookahead)break}if(t.match_length=0,t.lookahead>=C&&0t.lookahead&&(t.match_length=t.lookahead)}if(t.match_length>=C?(n=a._tr_tally(t,1,t.match_length-C),t.lookahead-=t.match_length,t.strstart+=t.match_length,t.match_length=0):(n=a._tr_tally(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++),n&&(I(t,!1),0===t.strm.avail_out))return 1}return t.insert=0,4===e?(I(t,!0),0===t.strm.avail_out?3:4):t.last_lit&&(I(t,!1),0===t.strm.avail_out)?1:2}(n,e):r[n.level].func(n,e);if(3!==o&&4!==o||(n.status=666),1===o||3===o)return 0===t.avail_out&&(n.last_flush=-1),d;if(2===o&&(1===e?a._tr_align(n):5!==e&&(a._tr_stored_block(n,0,0,!1),3===e&&(A(n.head),0===n.lookahead&&(n.strstart=0,n.block_start=0,n.insert=0))),L(t),0===t.avail_out))return n.last_flush=-1,d}return 4!==e?d:n.wrap<=0?1:(2===n.wrap?(M(n,255&t.adler),M(n,t.adler>>8&255),M(n,t.adler>>16&255),M(n,t.adler>>24&255),M(n,255&t.total_in),M(n,t.total_in>>8&255),M(n,t.total_in>>16&255),M(n,t.total_in>>24&255)):(R(n,t.adler>>>16),R(n,65535&t.adler)),L(t),0=n.w_size&&(0===s&&(A(n.head),n.strstart=0,n.block_start=0,n.insert=0),a=new u.Buf8(n.w_size),u.arraySet(a,e,h-n.w_size,n.w_size,0),e=a,h=n.w_size),o=t.avail_in,r=t.next_in,a=t.input,t.avail_in=h,t.next_in=0,t.input=e,U(n);n.lookahead>=C;){for(i=n.strstart,l=n.lookahead-(C-1);n.ins_h=(n.ins_h<>>=i=n>>>24,S-=i,0==(i=n>>>16&255))m[p++]=65535&n;else{if(!(16&i)){if(0==(64&i)){n=w[(65535&n)+(E&(1<>>=i,S-=i),S<15&&(E+=d[h++]<>>=i=n>>>24,S-=i,!(16&(i=n>>>16&255))){if(0==(64&i)){n=b[(65535&n)+(E&(1<>>=i,S-=i,(i=p-c)>3,E&=(1<<(S-=l<<3))-1,t.next_in=h,t.next_out=p,t.avail_in=h>>24&255)+(t>>>8&65280)+((65280&t)<<8)+((255&t)<<24)}function s(){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 M.Buf16(320),this.work=new M.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function o(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=G,e.last=0,e.havedict=0,e.dmax=32768,e.head=null,e.hold=0,e.bits=0,e.lencode=e.lendyn=new M.Buf32(i),e.distcode=e.distdyn=new M.Buf32(l),e.sane=1,e.back=-1,_):D}function r(t){var e;return t&&t.state?((e=t.state).wsize=0,e.whave=0,e.wnext=0,o(t)):D}function a(t,e){var n,i;return t&&t.state?(i=t.state,e<0?(n=0,e=-e):(n=1+(e>>4),e<48&&(e&=15)),e&&(e<8||15=l.wsize?(M.arraySet(l.window,e,n-l.wsize,l.wsize,0),l.wnext=0,l.whave=l.wsize):(i<(t=l.wsize-l.wnext)&&(t=i),M.arraySet(l.window,e,n-i,t,l.wnext),(i-=t)?(M.arraySet(l.window,e,n-i,i,0),l.wnext=i,l.whave=l.wsize):(l.wnext+=t,l.wnext===l.wsize&&(l.wnext=0),l.whave>>8&255,n.check=P(n.check,L,2,0),d=h=0,n.mode=2;break}if(n.flags=0,n.head&&(n.head.done=!1),!(1&n.wrap)||(((255&h)<<8)+(h>>8))%31){t.msg="incorrect header check",n.mode=30;break}if(8!=(15&h)){t.msg="unknown compression method",n.mode=30;break}if(d-=4,S=8+(15&(h>>>=4)),0===n.wbits)n.wbits=S;else if(S>n.wbits){t.msg="invalid window size",n.mode=30;break}n.dmax=1<>8&1),512&n.flags&&(L[0]=255&h,L[1]=h>>>8&255,n.check=P(n.check,L,2,0)),d=h=0,n.mode=3;case 3:for(;d<32;){if(0===r)break t;r--,h+=i[s++]<>>8&255,L[2]=h>>>16&255,L[3]=h>>>24&255,n.check=P(n.check,L,4,0)),d=h=0,n.mode=4;case 4:for(;d<16;){if(0===r)break t;r--,h+=i[s++]<>8),512&n.flags&&(L[0]=255&h,L[1]=h>>>8&255,n.check=P(n.check,L,2,0)),d=h=0,n.mode=5;case 5:if(1024&n.flags){for(;d<16;){if(0===r)break t;r--,h+=i[s++]<>>8&255,n.check=P(n.check,L,2,0)),d=h=0}else n.head&&(n.head.extra=null);n.mode=6;case 6:if(1024&n.flags&&(r<(m=n.length)&&(m=r),m&&(n.head&&(S=n.head.extra_len-n.length,n.head.extra||(n.head.extra=new Array(n.head.extra_len)),M.arraySet(n.head.extra,i,s,m,S)),512&n.flags&&(n.check=P(n.check,i,m,s)),r-=m,s+=m,n.length-=m),n.length))break t;n.length=0,n.mode=7;case 7:if(2048&n.flags){if(0===r)break t;for(m=0;S=i[s+m++],n.head&&S&&n.length<65536&&(n.head.name+=String.fromCharCode(S)),S&&m>9&1,n.head.done=!0),t.adler=n.check=0,n.mode=12;break;case 10:for(;d<32;){if(0===r)break t;r--,h+=i[s++]<>>=7&d,d-=7&d,n.mode=27;break}for(;d<3;){if(0===r)break t;r--,h+=i[s++]<>>=1)){case 0:n.mode=14;break;case 1:if(function(t){if(B){var e;for(V=new M.Buf32(512),F=new M.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(O(N,t.lens,0,288,V,0,t.work,{bits:9}),e=0;e<32;)t.lens[e++]=5;O(H,t.lens,0,32,F,0,t.work,{bits:5}),B=!1}t.lencode=V,t.lenbits=9,t.distcode=F,t.distbits=5}(n),n.mode=20,6!==e)break;h>>>=2,d-=2;break t;case 2:n.mode=17;break;case 3:t.msg="invalid block type",n.mode=30}h>>>=2,d-=2;break;case 14:for(h>>>=7&d,d-=7&d;d<32;){if(0===r)break t;r--,h+=i[s++]<>>16^65535)){t.msg="invalid stored block lengths",n.mode=30;break}if(n.length=65535&h,d=h=0,n.mode=15,6===e)break t;case 15:n.mode=16;case 16:if(m=n.length){if(r>>=5,d-=5,n.ndist=1+(31&h),h>>>=5,d-=5,n.ncode=4+(15&h),h>>>=4,d-=4,286>>=3,d-=3}for(;n.have<19;)n.lens[I[n.have++]]=0;if(n.lencode=n.lendyn,n.lenbits=7,b={bits:n.lenbits},w=O(0,n.lens,0,19,n.lencode,0,n.work,b),n.lenbits=b.bits,w){t.msg="invalid code lengths set",n.mode=30;break}n.have=0,n.mode=19;case 19:for(;n.have>>16&255,f=65535&A,!((x=A>>>24)<=d);){if(0===r)break t;r--,h+=i[s++]<>>=x,d-=x,n.lens[n.have++]=f;else{if(16===f){for(T=x+2;d>>=x,d-=x,0===n.have){t.msg="invalid bit length repeat",n.mode=30;break}S=n.lens[n.have-1],m=3+(3&h),h>>>=2,d-=2}else if(17===f){for(T=x+3;d>>=x)),h>>>=3,d-=3}else{for(T=x+7;d>>=x)),h>>>=7,d-=7}if(n.have+m>n.nlen+n.ndist){t.msg="invalid bit length repeat",n.mode=30;break}for(;m--;)n.lens[n.have++]=S}}if(30===n.mode)break;if(0===n.lens[256]){t.msg="invalid code -- missing end-of-block",n.mode=30;break}if(n.lenbits=9,b={bits:n.lenbits},w=O(N,n.lens,0,n.nlen,n.lencode,0,n.work,b),n.lenbits=b.bits,w){t.msg="invalid literal/lengths set",n.mode=30;break}if(n.distbits=6,n.distcode=n.distdyn,b={bits:n.distbits},w=O(H,n.lens,n.nlen,n.ndist,n.distcode,0,n.work,b),n.distbits=b.bits,w){t.msg="invalid distances set",n.mode=30;break}if(n.mode=20,6===e)break t;case 20:n.mode=21;case 21:if(6<=r&&258<=a){t.next_out=o,t.avail_out=a,t.next_in=s,t.avail_in=r,n.hold=h,n.bits=d,U(t,p),o=t.next_out,l=t.output,a=t.avail_out,s=t.next_in,i=t.input,r=t.avail_in,h=n.hold,d=n.bits,12===n.mode&&(n.back=-1);break}for(n.back=0;y=(A=n.lencode[h&(1<>>16&255,f=65535&A,!((x=A>>>24)<=d);){if(0===r)break t;r--,h+=i[s++]<>C)])>>>16&255,f=65535&A,!(C+(x=A>>>24)<=d);){if(0===r)break t;r--,h+=i[s++]<>>=C,d-=C,n.back+=C}if(h>>>=x,d-=x,n.back+=x,n.length=f,0===y){n.mode=26;break}if(32&y){n.back=-1,n.mode=12;break}if(64&y){t.msg="invalid literal/length code",n.mode=30;break}n.extra=15&y,n.mode=22;case 22:if(n.extra){for(T=n.extra;d>>=n.extra,d-=n.extra,n.back+=n.extra}n.was=n.length,n.mode=23;case 23:for(;y=(A=n.distcode[h&(1<>>16&255,f=65535&A,!((x=A>>>24)<=d);){if(0===r)break t;r--,h+=i[s++]<>C)])>>>16&255,f=65535&A,!(C+(x=A>>>24)<=d);){if(0===r)break t;r--,h+=i[s++]<>>=C,d-=C,n.back+=C}if(h>>>=x,d-=x,n.back+=x,64&y){t.msg="invalid distance code",n.mode=30;break}n.offset=f,n.extra=15&y,n.mode=24;case 24:if(n.extra){for(T=n.extra;d>>=n.extra,d-=n.extra,n.back+=n.extra}if(n.offset>n.dmax){t.msg="invalid distance too far back",n.mode=30;break}n.mode=25;case 25:if(0===a)break t;if(m=p-a,n.offset>m){if((m=n.offset-m)>n.whave&&n.sane){t.msg="invalid distance too far back",n.mode=30;break}c=m>n.wnext?(m-=n.wnext,n.wsize-m):n.wnext-m,m>n.length&&(m=n.length),g=n.window}else g=l,c=o-n.offset,m=n.length;for(am?(g=U[O+o[C]],I[M+o[C]]):(g=96,0),a=1<>b)+(h-=a)]=c<<24|g<<16|x|0,0!==h;);for(a=1<>=1;if(0!==a?(L&=a-1,L+=a):L=0,C++,0==--R[f]){if(f===E)break;f=e[n+o[C]]}if(S>>7)]}function w(t,e){t.pending_buf[t.pending++]=255&e,t.pending_buf[t.pending++]=e>>>8&255}function b(t,e,n){t.bi_valid>s-n?(t.bi_buf|=e<>s-t.bi_valid,t.bi_valid+=n-s):(t.bi_buf|=e<>>=1,n<<=1,0<--e;);return n>>>1}function L(t,e,n){for(var i,l=new Array(x+1),s=0,o=1;o<=x;o++)l[o]=s=s+n[o-1]<<1;for(i=0;i<=e;i++){var r=t[2*i+1];0!==r&&(t[2*i]=A(l[r]++,r))}}function I(t){for(var e=0;e<286;e++)t.dyn_ltree[2*e]=0;for(e=0;e<30;e++)t.dyn_dtree[2*e]=0;for(e=0;e<19;e++)t.bl_tree[2*e]=0;t.dyn_ltree[512]=1,t.opt_len=t.static_len=0,t.last_lit=t.matches=0}function M(t){8>1;1<=e;e--)P(t,l,e);for(i=r;e=t.heap[1],t.heap[1]=t.heap[t.heap_len--],P(t,l,1),n=t.heap[1],t.heap[--t.heap_max]=e,t.heap[--t.heap_max]=n,l[2*i]=l[2*e]+l[2*n],t.depth[i]=(t.depth[e]>=t.depth[n]?t.depth[e]:t.depth[n])+1,l[2*e+1]=l[2*n+1]=i,t.heap[1]=i++,P(t,l,1),2<=t.heap_len;);t.heap[--t.heap_max]=t.heap[1],function(t){for(var e,n,i,l,s,o=g.dyn_tree,r=g.max_code,a=g.stat_desc.static_tree,h=g.stat_desc.has_stree,d=g.stat_desc.extra_bits,u=g.stat_desc.extra_base,p=g.stat_desc.max_length,m=0,c=0;c<=x;c++)t.bl_count[c]=0;for(o[2*t.heap[t.heap_max]+1]=0,e=t.heap_max+1;e<573;e++)p<(c=o[2*o[2*(n=t.heap[e])+1]+1]+1)&&(c=p,m++),o[2*n+1]=c,r>=7;s<30;s++)for(C[s]=i<<7,t=0;t<1<>>=1)if(1&e&&0!==t.dyn_ltree[2*n])return 0;if(0!==t.dyn_ltree[18]||0!==t.dyn_ltree[20]||0!==t.dyn_ltree[26])return 1;for(n=32;n<256;n++)if(0!==t.dyn_ltree[2*n])return 1;return 0}(t)),O(t,t.l_desc),O(t,t.d_desc),o=function(t){var e;for(N(t,t.dyn_ltree,t.l_desc.max_code),N(t,t.dyn_dtree,t.d_desc.max_code),O(t,t.bl_desc),e=18;3<=e&&0===t.bl_tree[2*r[e]+1];e--);return t.opt_len+=3*(e+1)+5+5+4,e}(t),l=t.opt_len+3+7>>>3,(s=t.static_len+3+7>>>3)<=l&&(l=s)):l=s=n+5,n+4<=l&&-1!==e?D(t,e,n,i):4===t.strategy||s===l?(b(t,2+(i?1:0),3),U(t,d,u)):(b(t,4+(i?1:0),3),function(t,e,n,i){var l;for(b(t,e-257,5),b(t,n-1,5),b(t,i-4,4),l=0;l>>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*(m[n]+256+1)]++,t.dyn_dtree[2*S(e)]++),t.last_lit===t.lit_bufsize-1},n._tr_align=function(t){b(t,2,3),T(t,256,d),16===(t=t).bi_valid?(w(t,t.bi_buf),t.bi_buf=0,t.bi_valid=0):8<=t.bi_valid&&(t.pending_buf[t.pending++]=255&t.bi_buf,t.bi_buf>>=8,t.bi_valid-=8)}},{"../utils/common":3}],15:[function(t,e,n){"use strict";e.exports=function(){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}},{}],"/":[function(t,e,n){"use strict";var i={};(0,t("./lib/utils/common").assign)(i,t("./lib/deflate"),t("./lib/inflate"),t("./lib/zlib/constants")),e.exports=i},{"./lib/deflate":1,"./lib/inflate":2,"./lib/utils/common":3,"./lib/zlib/constants":6}]},{},[])("/")});var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(t,e){var n,i,l,s,o,r,a="",h=0;for((e=null!=e&&e)||(t=Base64._utf8_encode(t));h>2,s=(3&r)<<4|(n=t.charCodeAt(h++))>>4,o=(15&n)<<2|(i=t.charCodeAt(h++))>>6,r=63&i,isNaN(n)?o=r=64:isNaN(i)&&(r=64),a=a+this._keyStr.charAt(l)+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(r);return a},decode:function(t,e){e=null!=e&&e;var n,i,l,s,o,r="",a=0;for(t=t.replace(/[^A-Za-z0-9\+\/\=]/g,"");a>4,i=(15&l)<<4|(s=this._keyStr.indexOf(t.charAt(a++)))>>2,l=(3&s)<<6|(o=this._keyStr.indexOf(t.charAt(a++))),r+=String.fromCharCode(n),64!=s&&(r+=String.fromCharCode(i)),64!=o&&(r+=String.fromCharCode(l));return e||(r=Base64._utf8_decode(r)),r},_utf8_encode:function(t){t=t.replace(/\r\n/g,"\n");for(var e="",n=0;n>6|192):(e+=String.fromCharCode(i>>12|224),e+=String.fromCharCode(i>>6&63|128)),e+=String.fromCharCode(63&i|128))}return e},_utf8_decode:function(t){for(var e="",n=0,i=c1=c2=0;n>10),56320+(1023&e))):e==e?String.fromCharCode(e):t[1]<" "?"":t[1]}function d(t,e){return'"'+t.replace(/[\u0000-\u001f\\\"<>]/g,e)+'"'}function u(t){return e[t]||(e[t]="\\"+t.charCodeAt(0).toString(16)+" ")}function p(t){return n[t]||(n[t]=(t<""?"%0":"%")+t.charCodeAt(0).toString(16))}"undefined"!=typeof window&&(window.cssSchema=M),e={"\\":"\\\\"},n={"\\":"%5c"},a=RegExp("\\uFEFF|U[+][0-9A-F?]{1,6}(?:-[0-9A-F]{1,6})?|url[(][\\t\\n\\f ]*(?:\"(?:'|[^'\"\\n\\f\\\\]|\\\\[\\s\\S])*\"|'(?:\"|[^'\"\\n\\f\\\\]|\\\\[\\s\\S])*'|(?:[\\t\\x21\\x23-\\x26\\x28-\\x5b\\x5d-\\x7e]|[\\u0080-\\ud7ff\\ue000-\\ufffd]|[\\ud800-\\udbff][\\udc00-\\udfff]|\\\\(?:[0-9a-fA-F]{1,6}[\\t\\n\\f ]?|[\\u0020-\\u007e\\u0080-\\ud7ff\\ue000\\ufffd]|[\\ud800-\\udbff][\\udc00-\\udfff]))*)[\\t\\n\\f ]*[)]|(?!url[(])-?(?:[a-zA-Z_]|[\\u0080-\\ud7ff\\ue000-\\ufffd]|[\\ud800-\\udbff][\\udc00-\\udfff]|\\\\(?:[0-9a-fA-F]{1,6}[\\t\\n\\f ]?|[\\u0020-\\u007e\\u0080-\\ud7ff\\ue000\\ufffd]|[\\ud800-\\udbff][\\udc00-\\udfff]))(?:[a-zA-Z0-9_-]|[\\u0080-\\ud7ff\\ue000-\\ufffd]|[\\ud800-\\udbff][\\udc00-\\udfff]|\\\\(?:[0-9a-fA-F]{1,6}[\\t\\n\\f ]?|[\\u0020-\\u007e\\u0080-\\ud7ff\\ue000\\ufffd]|[\\ud800-\\udbff][\\udc00-\\udfff]))*[(]|(?:@?-?(?:[a-zA-Z_]|[\\u0080-\\ud7ff\\ue000-\\ufffd]|[\\ud800-\\udbff][\\udc00-\\udfff]|\\\\(?:[0-9a-fA-F]{1,6}[\\t\\n\\f ]?|[\\u0020-\\u007e\\u0080-\\ud7ff\\ue000\\ufffd]|[\\ud800-\\udbff][\\udc00-\\udfff]))|#)(?:[a-zA-Z0-9_-]|[\\u0080-\\ud7ff\\ue000-\\ufffd]|[\\ud800-\\udbff][\\udc00-\\udfff]|\\\\(?:[0-9a-fA-F]{1,6}[\\t\\n\\f ]?|[\\u0020-\\u007e\\u0080-\\ud7ff\\ue000\\ufffd]|[\\ud800-\\udbff][\\udc00-\\udfff]))*|\"(?:'|[^'\"\\n\\f\\\\]|\\\\[\\s\\S])*\"|'(?:\"|[^'\"\\n\\f\\\\]|\\\\[\\s\\S])*'|[-+]?(?:[0-9]+(?:[.][0-9]+)?|[.][0-9]+)(?:%|-?(?:[a-zA-Z_]|[\\u0080-\\ud7ff\\ue000-\\ufffd]|[\\ud800-\\udbff][\\udc00-\\udfff]|\\\\(?:[0-9a-fA-F]{1,6}[\\t\\n\\f ]?|[\\u0020-\\u007e\\u0080-\\ud7ff\\ue000\\ufffd]|[\\ud800-\\udbff][\\udc00-\\udfff]))(?:[a-zA-Z0-9_-]|[\\u0080-\\ud7ff\\ue000-\\ufffd]|[\\ud800-\\udbff][\\udc00-\\udfff]|\\\\(?:[0-9a-fA-F]{1,6}[\\t\\n\\f ]?|[\\u0020-\\u007e\\u0080-\\ud7ff\\ue000\\ufffd]|[\\ud800-\\udbff][\\udc00-\\udfff]))*)?|\x3c!--|--\x3e|[\\t\\n\\f ]+|/(?:[*][^*]*[*]+(?:[^/][^*]*[*]+)*/|/[^\\n\\f]*)|[~|^$*]=|[^\"'\\\\/]|/(?![/*])","gi"),i=RegExp("\\\\(?:(?:[0-9a-fA-F]{1,6}[\\t\\n\\f ]?|[\\u0020-\\u007e\\u0080-\\ud7ff\\ue000\\ufffd]|[\\ud800-\\udbff][\\udc00-\\udfff])|[\\n\\f])","g"),h=RegExp("^url\\([\\t\\n\\f ]*[\"']?|[\"']?[\\t\\n\\f ]*\\)$","gi"),I=function(t){return t.replace(i,l)},s=function(t){for(var e=0,n=" ",i=0,l=(t=(""+t).replace(/\r\n?/g,"\n").match(a)||[]).length;i>4&15)+"0123456789ABCDEF".charAt(15&t)}function o(t){if(t===F)return F;for(var e,t=t.replace(/(^|\/)\.(?:\/|$)/g,"$1").replace(/\/{2,}/g,"/"),n=l;(e=t.replace(n,"$1"))!=t;t=e);return t}function i(t,e){var n=t.T(),i=e.K();i?n.ga(e.j):i=e.X(),i?n.da(e.n):i=e.Y(),i?n.ea(e.k):i=e.$();var l=e.g,s=o(l);return i?(n.ca(e.V()),s=s&&s.replace(d,"")):(i=!!l)?47!==s.charCodeAt(0)&&(s=o(n.g||"").replace(d,""),s=o(((t=s.lastIndexOf("/")+1)?s.substring(0,t):"")+o(l)).replace(d,"")):(s=s&&s.replace(d,""))!==l&&n.G(s),i?n.G(s):i=e.aa(),i?n.O(e.l):i=e.Z(),i&&n.fa(e.o),n}function h(t,e,n,i,l,s,o){this.j=t,this.n=e,this.k=n,this.h=i,this.g=l,this.l=s,this.o=o}function e(t){return"string"==typeof t&&0]/g,i={"\n":"%0a","\f":"%0c","\r":"%0d",'"':"%22","'":"%27","(":"%28",")":"%29","*":"%2a","<":"%3c",">":"%3e"},l=/^(?:([^:/?# ]+):)?/,s=/^(?:https?|mailto|data)$/i;L={},C=function t(e,n,i,l,s){var e=A(e),o=M[e];if(o&&"object"==typeof o){for(var r=o.cssPropBits,a=80&r,h=1536&r,d=NaN,u=0,p=0;u"]=d["+"]=d["~"]=d,v=function(c,g,r){function t(t,e){function n(t,e,n){var i,l,s,o=V,r="";t])/g,i=t+"";if(N)i=i.split(n);else{for(var l,s=[],o=0;(l=n.exec(i))!==F;)s.push(i.substring(o,l.index)),s.push(l[0]),o=l.index+l[0].length;s.push(i.substring(o)),i=s}a(r,i,0,{r:B,C:B},e)}}function v(t,e,n,i,l){return function(){a(t,e,n,i,l)}}function a(t,e,n,i,l){try{t.H&&0==n&&t.H(l);for(var s,o,r,a=e.length;n"===e[n+1]?(n+=2,r=s[1].toLowerCase(),t.t&&t.t(r,l,_,v(t,e,n,i,l))):(m=t,c=l,g=_,h=i,n=(d=S(u=e,p=n))?(m.t&&m.t(d.name,c,g,v(m,u,p,h,c)),d.next):u.length):t.e&&t.e("</",l,_,v(t,e,n,i,l));break;case"<":(s=/^([-\w:]+)\s*\/?/.exec(f))?s[0].length===f.length&&">"===e[n+1]?(n+=2,r=s[1].toLowerCase(),t.w&&t.w(r,[],l,_,v(t,e,n,i,l)),(d=C.f[r])&H&&(n=E(e,{name:r,next:n,c:d},t,l,_,i))):(p=t,m=l,c=_,g=i,n=(x=S(u=e,n))?(p.w&&p.w(x.name,x.R,m,c,v(p,u,x.next,g,m)),x.c&H?E(u,x,p,m,c,g):x.next):u.length):t.e&&t.e("<",l,_,v(t,e,n,i,l));break;case"\x3c!--":if(!i.C){for(o=n+1;o"!==e[o]||!/--$/.test(e[o-1]));o++);o"!==e[o];o++);o"!==e[o];o++);o":t.e&&t.e(">",l,_,v(t,e,n,i,l));break;case"":break;default:t.e&&t.e(y,l,_,v(t,e,n,i,l))}}t.B&&t.B(l)}catch(t){if(t!==_)throw t}}function E(t,e,n,i,l,s){var o=t.length;D.hasOwnProperty(e.name)||(D[e.name]=RegExp("^"+e.name+"(?:[\\s\\/]|$)","i"));for(var r=D[e.name],a=e.next,h=e.next+1;h"!==t[s];s++)l+=t[s];if(!(o<=s)){for(var r=[];""!==l;)if(n=O.exec(l))if(n[4]&&!n[5]||n[6]&&!n[7]){for(var n=n[4]||n[6],a=B,l=[l,t[s++]];s"===t[s])break}else 0<=t[s].indexOf(n)&&(a=V);l.push(t[s])}if(o<=s)break;l=l.join("")}else{var h,a=n[1].toLowerCase(),d=n[2]?(34!==(h=(d=n[3]).charCodeAt(0))&&39!==h||(d=d.substr(1,d.length-2)),u(d.replace(T,""))):"";r.push(a,d),l=l.substr(n[0].length)}else l=l.replace(/^[\s\S][^a-z\s]*/,"");return i.R=r,i.next=s+1,i}}function i(h){function t(t,e){u||e.push(t)}var d,u;return n({startDoc:function(){d=[],u=B},startTag:function(t,e,n){if(!u&&C.f.hasOwnProperty(t)){var i=C.f[t];if(!(i&C.c.FOLDABLE)){var l,s,o=h(t,e);if(o){if("object"!=typeof o)throw Error("tagPolicy did not return object (old API?)");if(!("attribs"in o))throw Error("tagPolicy gave no attribs");e=o.attribs,o="tagName"in o?(l=o.tagName,C.f[l]):(l=t,i),i&C.c.OPTIONAL_ENDTAG&&(!(s=d[d.length-1])||s.D!==t||s.v===l&&t===l||n.push("")),i&C.c.EMPTY||d.push({D:t,v:l}),n.push("<",l),t=0;for(s=e.length;t"),i&C.c.EMPTY&&!(o&C.c.EMPTY)&&n.push("")}else u=!(i&C.c.EMPTY)}}},endTag:function(t,e){if(u)u=B;else if(C.f.hasOwnProperty(t)){var n=C.f[t];if(!(n&(C.c.EMPTY|C.c.FOLDABLE))){if(n&C.c.OPTIONAL_ENDTAG)for(n=d.length;0<=--n;){var i=d[n].D;if(i===t)break;if(!(C.f[i]&C.c.OPTIONAL_ENDTAG))return}else for(n=d.length;0<=--n&&d[n].D!==t;);if(!(n<0)){for(i=d.length;--i>n;){var l=d[i].v;C.f[l]&C.c.OPTIONAL_ENDTAG||e.push("")}n")}}}},pcdata:t,rcdata:t,cdata:t,endDoc:function(t){for(;d.length;d.length--)t.push("")}})}function m(t,e,n,i,l){if(!l)return F;try{var s=z.parse(""+t);if(s&&(!s.K()||G.test(s.W()))){s=l(s,e,n,i);return s?s.toString():F}}catch(t){}return F}function c(t,e,n,i,l){var s;n||t(e+" removed",{S:"removed",tagName:e}),i!==l&&(s="changed",i&&!l?s="removed":!i&&l&&(s="added"),t(e+"."+n+" "+s,{S:s,tagName:e,la:n,oldValue:i,newValue:l}))}function g(t,e,n){return e=e+"::"+n,t.hasOwnProperty(e)?t[e]:(e="*::"+n,t.hasOwnProperty(e)?t[e]:void 0)}function s(t,e,i,n,l){for(var s=0;s",GT:">",amp:"&",AMP:"&",quot:'"',apos:"'",nbsp:" "},h=/^#(\d+)$/,f=/^#x([0-9A-Fa-f]+)$/,w=/^[A-Za-z][A-za-z0-9]+$/,b="undefined"!=typeof window&&window.document?window.document.createElement("textarea"):F,T=/\0/g,A=/&(#[0-9]+|#[xX][0-9A-Fa-f]+|\w+);/g,L=/^(#[0-9]+|#[xX][0-9A-Fa-f]+|\w+);/,I=/&/g,M=/&([^a-z#]|#(?:[^0-9x]|x(?:[^0-9a-f]|$)|$)|$)/gi,R=/[<]/g,P=/>/g,U=/\"/g,O=/^\s*([-.:\w]+)(?:\s*(=)\s*((")[^"]*("|$)|(')[^']*('|$)|(?=[a-z][-\w]*\s*=)|[^"'\s]*))?/i,N=3==="a,b".split(/(,)/).length,H=C.c.CDATA|C.c.RCDATA,_={},D={},G=/^(?:https?|mailto|data)$/i,t={};return t.pa=t.escapeAttrib=p,t.ra=t.makeHtmlSanitizer=i,t.sa=t.makeSaxParser=n,t.ta=t.makeTagPolicy=l,t.wa=t.normalizeRCData=d,t.xa=t.sanitize=function(t,e,n,i){return o(t,l(e,n,i))},t.ya=t.sanitizeAttribs=s,t.za=t.sanitizeWithPolicy=o,t.Ba=t.unescapeEntities=u,t}(S),c=r.sanitize;"undefined"!=typeof window&&(window.html=r,window.html_sanitize=c)}();var mxClient={VERSION:"4.2.2",IS_IE:null!=navigator.userAgent&&0<=navigator.userAgent.indexOf("MSIE"),IS_IE6:null!=navigator.userAgent&&0<=navigator.userAgent.indexOf("MSIE 6"),IS_IE11:null!=navigator.userAgent&&!!navigator.userAgent.match(/Trident\/7\./),IS_EDGE:null!=navigator.userAgent&&!!navigator.userAgent.match(/Edge\//),IS_QUIRKS:null!=navigator.userAgent&&0<=navigator.userAgent.indexOf("MSIE")&&(null==document.documentMode||5==document.documentMode),IS_EM:"spellcheck"in document.createElement("textarea")&&8==document.documentMode,VML_PREFIX:"v",OFFICE_PREFIX:"o",IS_NS:null!=navigator.userAgent&&0<=navigator.userAgent.indexOf("Mozilla/")&&navigator.userAgent.indexOf("MSIE")<0&&navigator.userAgent.indexOf("Edge/")<0,IS_OP:null!=navigator.userAgent&&(0<=navigator.userAgent.indexOf("Opera/")||0<=navigator.userAgent.indexOf("OPR/")),IS_OT:null!=navigator.userAgent&&0<=navigator.userAgent.indexOf("Presto/")&&navigator.userAgent.indexOf("Presto/2.4.")<0&&navigator.userAgent.indexOf("Presto/2.3.")<0&&navigator.userAgent.indexOf("Presto/2.2.")<0&&navigator.userAgent.indexOf("Presto/2.1.")<0&&navigator.userAgent.indexOf("Presto/2.0.")<0&&navigator.userAgent.indexOf("Presto/1.")<0,IS_SF:/Apple Computer, Inc/.test(navigator.vendor),IS_ANDROID:0<=navigator.appVersion.indexOf("Android"),IS_IOS:/iP(hone|od|ad)/.test(navigator.platform),IS_GC:/Google Inc/.test(navigator.vendor),IS_CHROMEAPP:null!=window.chrome&&null!=chrome.app&&null!=chrome.app.runtime,IS_FF:"undefined"!=typeof InstallTrigger,IS_MT:0<=navigator.userAgent.indexOf("Firefox/")&&navigator.userAgent.indexOf("Firefox/1.")<0&&navigator.userAgent.indexOf("Firefox/2.")<0||0<=navigator.userAgent.indexOf("Iceweasel/")&&navigator.userAgent.indexOf("Iceweasel/1.")<0&&navigator.userAgent.indexOf("Iceweasel/2.")<0||0<=navigator.userAgent.indexOf("SeaMonkey/")&&navigator.userAgent.indexOf("SeaMonkey/1.")<0||0<=navigator.userAgent.indexOf("Iceape/")&&navigator.userAgent.indexOf("Iceape/1.")<0,IS_VML:"MICROSOFT INTERNET EXPLORER"==navigator.appName.toUpperCase(),IS_SVG:"MICROSOFT INTERNET EXPLORER"!=navigator.appName.toUpperCase(),NO_FO:!document.createElementNS||"[object SVGForeignObjectElement]"!=document.createElementNS("http://www.w3.org/2000/svg","foreignObject")||0<=navigator.userAgent.indexOf("Opera/"),IS_WIN:0'):((l=n.createElement("link")).setAttribute("rel",t),l.setAttribute("href",e),l.setAttribute("charset","UTF-8"),l.setAttribute("type","text/css"),i&&l.setAttribute("id",i),n.getElementsByTagName("head")[0].appendChild(l))},loadResources:function(t,e){var n=mxClient.defaultBundles.length;function i(){0==--n&&t()}for(var l=0;l<\/script>')}};"undefined"==typeof mxLoadResources&&(window.mxLoadResources=!0),"undefined"==typeof mxForceIncludes&&(window.mxForceIncludes=!1),"undefined"==typeof mxResourceExtension&&(window.mxResourceExtension=".txt"),"undefined"==typeof mxLoadStylesheets&&(window.mxLoadStylesheets=!0),mxClient.basePath=window.mxBasePath||".","undefined"!=typeof mxImageBasePath&&0/g,">"),null!=e&&!e||(t=t.replace(/\n/g," ")),t},isVml:function(t){return null!=t&&"urn:schemas-microsoft-com:vml"==t.tagUrn},getXml:function(t,e){var n="";return mxClient.IS_IE||mxClient.IS_IE11?n=mxUtils.getPrettyXml(t,"","",""):null!=window.XMLSerializer?n=(new XMLSerializer).serializeToString(t):null!=t.xml&&(n=t.xml.replace(/\r\n\t[\t]*/g,"").replace(/>\r\n/g,">").replace(/\r\n/g,"\n")),e=e||" ",n=n.replace(/\n/g,e)},getPrettyXml:function(t,e,n,i,l){var s,o=[];if(null!=t)if(e=null!=e?e:" ",n=null!=n?n:"",i=null!=i?i:"\n",null!=t.namespaceURI&&t.namespaceURI!=l&&(l=t.namespaceURI,null==t.getAttribute("xmlns")&&t.setAttribute("xmlns",t.namespaceURI)),t.nodeType==mxConstants.NODETYPE_DOCUMENT)o.push(mxUtils.getPrettyXml(t.documentElement,e,n,i,l));else if(t.nodeType==mxConstants.NODETYPE_DOCUMENT_FRAGMENT){if(null!=(r=t.firstChild))for(;null!=r;)o.push(mxUtils.getPrettyXml(r,e,n,i,l)),r=r.nextSibling}else if(t.nodeType==mxConstants.NODETYPE_COMMENT)0<(s=mxUtils.getTextContent(t)).length&&o.push(n+"\x3c!--"+s+"--\x3e"+i);else if(t.nodeType==mxConstants.NODETYPE_TEXT)0<(s=mxUtils.trim(mxUtils.getTextContent(t))).length&&o.push(n+mxUtils.htmlEntities(s,!1)+i);else if(t.nodeType==mxConstants.NODETYPE_CDATA)0<(s=mxUtils.getTextContent(t)).length&&o.push(n+""+i);null!=r;)o.push(mxUtils.getPrettyXml(r,e,n+e,i,l)),r=r.nextSibling;o.push(n+""+i)}else o.push(" />"+i)}return o.join("")},extractTextWithWhitespace:function(t){var l=["BLOCKQUOTE","DIV","H1","H2","H3","H4","H5","H6","OL","P","PRE","TABLE","UL"],s=[];return function t(e){if(1!=e.length||"BR"!=e[0].nodeName&&"\n"!=e[0].innerHTML)for(var n=0;n"==i.innerHTML.toLowerCase()?s.push("\n"):(3===i.nodeType||4===i.nodeType?0"):(e.push(">"),e.push(t.innerHTML),e.push("")),e.join("")}:function(t){return null==t?"":(new XMLSerializer).serializeToString(t)},write:function(t,e){e=t.ownerDocument.createTextNode(e);return null!=t&&t.appendChild(e),e},writeln:function(t,e){e=t.ownerDocument.createTextNode(e);return null!=t&&(t.appendChild(e),t.appendChild(document.createElement("br"))),e},br:function(t,e){e=e||1;for(var n=null,i=0;i [Function]\n":"object"==typeof t[e]?n+=e+" => ["+mxUtils.getFunctionName(t[e].constructor)+"]\n":n+=e+" = "+t[e]+"\n"}catch(t){n+=e+"="+t.message}return n},toRadians:function(t){return Math.PI*t/180},toDegree:function(t){return 180*t/Math.PI},arcToCurves:function(t,e,n,i,l,s,o,r,a){if(r-=t,a-=e,0===n||0===i)return O;var h=o,d=l;n=Math.abs(n),i=Math.abs(i);var u=-r/2,p=-a/2,m=Math.cos(d*Math.PI/180),c=Math.sin(d*Math.PI/180),g=m*u+c*p,x=-1*c*u+m*p,o=g*g,l=x*x,d=n*n,u=i*i,p=o/d+l/u,o=(u=1>1,e|=(t&mxConstants.DIRECTION_MASK_EAST)>>3},findNearestSegment:function(t,e,n){var i=-1;if(0s.distSq)&&(i=s))}return null!=i?i.p:null},rectangleIntersectsSegment:function(t,e,n){var i=t.y,l=t.x,s=i+t.height,o=l+t.width,r=e.x,a=n.x;if(e.x>n.x&&(r=n.x,a=e.x),o=e&&t.y<=n&&t.y+t.height>=n},intersects:function(t,e){var n=t.width,i=t.height,l=e.width,s=e.height;if(l<=0||s<=0||n<=0||i<=0)return!1;var o=t.x,r=t.y,t=e.x,e=e.y;return s+=e,n+=o,i+=r,((l+=t)",d=document.getElementsByTagName("base"),u=0;u";for(u=0;u',h+='
',h+=t.container.innerHTML,h+="
",e.writeln(h),e.close()}else{e.writeln("");for(d=document.getElementsByTagName("base"),u=0;u'),e.close();var c=e.createElement("div");c.position="absolute",c.overflow="hidden",c.style.width=l+"px",c.style.height=s+"px";var g=e.createElement("div");g.style.position="absolute",g.style.left=r+"px",g.style.top=a+"px";for(var x=t.container.firstChild,y=null;null!=x;){var f=x.cloneNode(!0);x==t.view.drawPane.ownerSVGElement?(c.appendChild(f),y=f):g.appendChild(f),x=x.nextSibling}e.body.appendChild(c),null!=g.firstChild&&e.body.appendChild(g),null!=y&&(y.style.minWidth="",y.style.minHeight="",y.firstChild.setAttribute("transform","translate("+r+","+a+")"))}return mxUtils.removeCursors(e.body),e},printScreen:function(t){var e=window.open();t.getGraphBounds();mxUtils.show(t,e.document);t=function(){e.focus(),e.print(),e.close()};mxClient.IS_GC?e.setTimeout(t,500):t()},popup:function(t,e){var n,i;e?((n=document.createElement("div")).style.overflow="scroll",n.style.width="636px",n.style.height="460px",(i=document.createElement("pre")).innerHTML=mxUtils.htmlEntities(t,!1).replace(/\n/g,"
").replace(/ /g," "),n.appendChild(i),(n=new mxWindow("Popup Window",n,document.body.clientWidth/2-320,Math.max(document.body.clientHeight||0,document.documentElement.clientHeight)/2-240,640,480,!1,!0)).setClosable(!0),n.setVisible(!0)):mxClient.IS_NS?((n=window.open()).document.writeln("
"+mxUtils.htmlEntities(t)+"").replace(/ /g," "),n.document.body.appendChild(i))},alert:function(t){alert(t)},prompt:function(t,e){return prompt(t,null!=e?e:"")},confirm:function(t){return confirm(t)},error:function(t,e,n,i){var l=document.createElement("div");l.style.padding="20px";var s=document.createElement("img");s.setAttribute("src",i||mxUtils.errorImage),s.setAttribute("valign","bottom"),s.style.verticalAlign="middle",l.appendChild(s),l.appendChild(document.createTextNode(" ")),l.appendChild(document.createTextNode(" ")),l.appendChild(document.createTextNode(" ")),mxUtils.write(l,t);var s=document.body.clientWidth,t=document.body.clientHeight||document.documentElement.clientHeight,o=new mxWindow(mxResources.get(mxUtils.errorResource)||mxUtils.errorResource,l,(s-e)/2,t/4,e,null,!1,!0);return n&&(mxUtils.br(l),e=document.createElement("p"),n=document.createElement("button"),mxClient.IS_IE?n.style.cssText="float:right":n.setAttribute("style","float:right"),mxEvent.addListener(n,"click",function(t){o.destroy()}),mxUtils.write(n,mxResources.get(mxUtils.closeResource)||mxUtils.closeResource),e.appendChild(n),l.appendChild(e),mxUtils.br(l),o.setClosable(!0)),o.setVisible(!0),o},makeDraggable:function(t,e,n,l,i,s,o,r,a,h){n=new mxDragSource(t,n);return n.dragOffset=new mxPoint(null!=i?i:0,null!=s?s:mxConstants.TOOLTIP_VERTICAL_OFFSET),n.autoscroll=o,n.setGuidesEnabled(!1),null!=a&&(n.highlightDropTargets=a),null!=h&&(n.getDropTarget=h),n.getGraphForEvent=function(t){return"function"==typeof e?e(t):e},null!=l&&(n.createDragElement=function(){return l.cloneNode(!0)},r&&(n.createPreviewElement=function(t){var e=l.cloneNode(!0),n=parseInt(e.style.width),i=parseInt(e.style.height);return e.style.width=Math.round(n*t.view.scale)+"px",e.style.height=Math.round(i*t.view.scale)+"px",e})),n}},mxConstants={DEFAULT_HOTSPOT:.3,MIN_HOTSPOT_SIZE:8,MAX_HOTSPOT_SIZE:0,RENDERING_HINT_EXACT:"exact",RENDERING_HINT_FASTER:"faster",RENDERING_HINT_FASTEST:"fastest",DIALECT_SVG:"svg",DIALECT_VML:"vml",DIALECT_MIXEDHTML:"mixedHtml",DIALECT_PREFERHTML:"preferHtml",DIALECT_STRICTHTML:"strictHtml",NS_SVG:"http://www.w3.org/2000/svg",NS_XHTML:"http://www.w3.org/1999/xhtml",NS_XLINK:"http://www.w3.org/1999/xlink",SHADOWCOLOR:"gray",VML_SHADOWCOLOR:"gray",SHADOW_OFFSET_X:2,SHADOW_OFFSET_Y:3,SHADOW_OPACITY:1,NODETYPE_ELEMENT:1,NODETYPE_ATTRIBUTE:2,NODETYPE_TEXT:3,NODETYPE_CDATA:4,NODETYPE_ENTITY_REFERENCE:5,NODETYPE_ENTITY:6,NODETYPE_PROCESSING_INSTRUCTION:7,NODETYPE_COMMENT:8,NODETYPE_DOCUMENT:9,NODETYPE_DOCUMENTTYPE:10,NODETYPE_DOCUMENT_FRAGMENT:11,NODETYPE_NOTATION:12,TOOLTIP_VERTICAL_OFFSET:16,DEFAULT_VALID_COLOR:"#00FF00",DEFAULT_INVALID_COLOR:"#FF0000",OUTLINE_HIGHLIGHT_COLOR:"#00FF00",OUTLINE_HIGHLIGHT_STROKEWIDTH:5,HIGHLIGHT_STROKEWIDTH:3,HIGHLIGHT_SIZE:2,HIGHLIGHT_OPACITY:100,CURSOR_MOVABLE_VERTEX:"move",CURSOR_MOVABLE_EDGE:"move",CURSOR_LABEL_HANDLE:"default",CURSOR_TERMINAL_HANDLE:"pointer",CURSOR_BEND_HANDLE:"crosshair",CURSOR_VIRTUAL_BEND_HANDLE:"crosshair",CURSOR_CONNECT:"pointer",HIGHLIGHT_COLOR:"#00FF00",CONNECT_TARGET_COLOR:"#0000FF",INVALID_CONNECT_TARGET_COLOR:"#FF0000",DROP_TARGET_COLOR:"#0000FF",VALID_COLOR:"#00FF00",INVALID_COLOR:"#FF0000",EDGE_SELECTION_COLOR:"#00FF00",VERTEX_SELECTION_COLOR:"#00FF00",VERTEX_SELECTION_STROKEWIDTH:1,EDGE_SELECTION_STROKEWIDTH:1,VERTEX_SELECTION_DASHED:!0,EDGE_SELECTION_DASHED:!0,GUIDE_COLOR:"#FF0000",GUIDE_STROKEWIDTH:1,OUTLINE_COLOR:"#0099FF",OUTLINE_STROKEWIDTH:mxClient.IS_IE?2:3,HANDLE_SIZE:6,LABEL_HANDLE_SIZE:4,HANDLE_FILLCOLOR:"#00FF00",HANDLE_STROKECOLOR:"black",LABEL_HANDLE_FILLCOLOR:"yellow",CONNECT_HANDLE_FILLCOLOR:"#0000FF",LOCKED_HANDLE_FILLCOLOR:"#FF0000",OUTLINE_HANDLE_FILLCOLOR:"#00FFFF",OUTLINE_HANDLE_STROKECOLOR:"#0033FF",DEFAULT_FONTFAMILY:"Arial,Helvetica",DEFAULT_FONTSIZE:11,DEFAULT_TEXT_DIRECTION:"",LINE_HEIGHT:1.2,WORD_WRAP:"normal",ABSOLUTE_LINE_HEIGHT:!1,DEFAULT_FONTSTYLE:0,DEFAULT_STARTSIZE:40,DEFAULT_MARKERSIZE:6,DEFAULT_IMAGESIZE:24,ENTITY_SEGMENT:30,RECTANGLE_ROUNDING_FACTOR:.15,LINE_ARCSIZE:20,ARROW_SPACING:0,ARROW_WIDTH:30,ARROW_SIZE:30,PAGE_FORMAT_A4_PORTRAIT:new mxRectangle(0,0,827,1169),PAGE_FORMAT_A4_LANDSCAPE:new mxRectangle(0,0,1169,827),PAGE_FORMAT_LETTER_PORTRAIT:new mxRectangle(0,0,850,1100),PAGE_FORMAT_LETTER_LANDSCAPE:new mxRectangle(0,0,1100,850),NONE:"none",STYLE_PERIMETER:"perimeter",STYLE_SOURCE_PORT:"sourcePort",STYLE_TARGET_PORT:"targetPort",STYLE_PORT_CONSTRAINT:"portConstraint",STYLE_PORT_CONSTRAINT_ROTATION:"portConstraintRotation",STYLE_SOURCE_PORT_CONSTRAINT:"sourcePortConstraint",STYLE_TARGET_PORT_CONSTRAINT:"targetPortConstraint",STYLE_OPACITY:"opacity",STYLE_FILL_OPACITY:"fillOpacity",STYLE_STROKE_OPACITY:"strokeOpacity",STYLE_TEXT_OPACITY:"textOpacity",STYLE_TEXT_DIRECTION:"textDirection",STYLE_OVERFLOW:"overflow",STYLE_ORTHOGONAL:"orthogonal",STYLE_EXIT_X:"exitX",STYLE_EXIT_Y:"exitY",STYLE_EXIT_DX:"exitDx",STYLE_EXIT_DY:"exitDy",STYLE_EXIT_PERIMETER:"exitPerimeter",STYLE_ENTRY_X:"entryX",STYLE_ENTRY_Y:"entryY",STYLE_ENTRY_DX:"entryDx",STYLE_ENTRY_DY:"entryDy",STYLE_ENTRY_PERIMETER:"entryPerimeter",STYLE_WHITE_SPACE:"whiteSpace",STYLE_ROTATION:"rotation",STYLE_FILLCOLOR:"fillColor",STYLE_POINTER_EVENTS:"pointerEvents",STYLE_SWIMLANE_FILLCOLOR:"swimlaneFillColor",STYLE_MARGIN:"margin",STYLE_GRADIENTCOLOR:"gradientColor",STYLE_GRADIENT_DIRECTION:"gradientDirection",STYLE_STROKECOLOR:"strokeColor",STYLE_SEPARATORCOLOR:"separatorColor",STYLE_STROKEWIDTH:"strokeWidth",STYLE_ALIGN:"align",STYLE_VERTICAL_ALIGN:"verticalAlign",STYLE_LABEL_WIDTH:"labelWidth",STYLE_LABEL_POSITION:"labelPosition",STYLE_VERTICAL_LABEL_POSITION:"verticalLabelPosition",STYLE_IMAGE_ASPECT:"imageAspect",STYLE_IMAGE_ALIGN:"imageAlign",STYLE_IMAGE_VERTICAL_ALIGN:"imageVerticalAlign",STYLE_GLASS:"glass",STYLE_IMAGE:"image",STYLE_IMAGE_WIDTH:"imageWidth",STYLE_IMAGE_HEIGHT:"imageHeight",STYLE_IMAGE_BACKGROUND:"imageBackground",STYLE_IMAGE_BORDER:"imageBorder",STYLE_FLIPH:"flipH",STYLE_FLIPV:"flipV",STYLE_NOLABEL:"noLabel",STYLE_NOEDGESTYLE:"noEdgeStyle",STYLE_LABEL_BACKGROUNDCOLOR:"labelBackgroundColor",STYLE_LABEL_BORDERCOLOR:"labelBorderColor",STYLE_LABEL_PADDING:"labelPadding",STYLE_INDICATOR_SHAPE:"indicatorShape",STYLE_INDICATOR_IMAGE:"indicatorImage",STYLE_INDICATOR_COLOR:"indicatorColor",STYLE_INDICATOR_STROKECOLOR:"indicatorStrokeColor",STYLE_INDICATOR_GRADIENTCOLOR:"indicatorGradientColor",STYLE_INDICATOR_SPACING:"indicatorSpacing",STYLE_INDICATOR_WIDTH:"indicatorWidth",STYLE_INDICATOR_HEIGHT:"indicatorHeight",STYLE_INDICATOR_DIRECTION:"indicatorDirection",STYLE_SHADOW:"shadow",STYLE_SEGMENT:"segment",STYLE_ENDARROW:"endArrow",STYLE_STARTARROW:"startArrow",STYLE_ENDSIZE:"endSize",STYLE_STARTSIZE:"startSize",STYLE_SWIMLANE_LINE:"swimlaneLine",STYLE_ENDFILL:"endFill",STYLE_STARTFILL:"startFill",STYLE_DASHED:"dashed",STYLE_DASH_PATTERN:"dashPattern",STYLE_FIX_DASH:"fixDash",STYLE_ROUNDED:"rounded",STYLE_CURVED:"curved",STYLE_ARCSIZE:"arcSize",STYLE_ABSOLUTE_ARCSIZE:"absoluteArcSize",STYLE_SOURCE_PERIMETER_SPACING:"sourcePerimeterSpacing",STYLE_TARGET_PERIMETER_SPACING:"targetPerimeterSpacing",STYLE_PERIMETER_SPACING:"perimeterSpacing",STYLE_SPACING:"spacing",STYLE_SPACING_TOP:"spacingTop",STYLE_SPACING_LEFT:"spacingLeft",STYLE_SPACING_BOTTOM:"spacingBottom",STYLE_SPACING_RIGHT:"spacingRight",STYLE_HORIZONTAL:"horizontal",STYLE_DIRECTION:"direction",STYLE_ANCHOR_POINT_DIRECTION:"anchorPointDirection",STYLE_ELBOW:"elbow",STYLE_FONTCOLOR:"fontColor",STYLE_FONTFAMILY:"fontFamily",STYLE_FONTSIZE:"fontSize",STYLE_FONTSTYLE:"fontStyle",STYLE_ASPECT:"aspect",STYLE_AUTOSIZE:"autosize",STYLE_FOLDABLE:"foldable",STYLE_EDITABLE:"editable",STYLE_BACKGROUND_OUTLINE:"backgroundOutline",STYLE_BENDABLE:"bendable",STYLE_MOVABLE:"movable",STYLE_RESIZABLE:"resizable",STYLE_RESIZE_WIDTH:"resizeWidth",STYLE_RESIZE_HEIGHT:"resizeHeight",STYLE_ROTATABLE:"rotatable",STYLE_CLONEABLE:"cloneable",STYLE_DELETABLE:"deletable",STYLE_SHAPE:"shape",STYLE_EDGE:"edgeStyle",STYLE_JETTY_SIZE:"jettySize",STYLE_SOURCE_JETTY_SIZE:"sourceJettySize",STYLE_TARGET_JETTY_SIZE:"targetJettySize",STYLE_LOOP:"loopStyle",STYLE_ORTHOGONAL_LOOP:"orthogonalLoop",STYLE_ROUTING_CENTER_X:"routingCenterX",STYLE_ROUTING_CENTER_Y:"routingCenterY",FONT_BOLD:1,FONT_ITALIC:2,FONT_UNDERLINE:4,FONT_STRIKETHROUGH:8,SHAPE_RECTANGLE:"rectangle",SHAPE_ELLIPSE:"ellipse",SHAPE_DOUBLE_ELLIPSE:"doubleEllipse",SHAPE_RHOMBUS:"rhombus",SHAPE_LINE:"line",SHAPE_IMAGE:"image",SHAPE_ARROW:"arrow",SHAPE_ARROW_CONNECTOR:"arrowConnector",SHAPE_LABEL:"label",SHAPE_CYLINDER:"cylinder",SHAPE_SWIMLANE:"swimlane",SHAPE_CONNECTOR:"connector",SHAPE_ACTOR:"actor",SHAPE_CLOUD:"cloud",SHAPE_TRIANGLE:"triangle",SHAPE_HEXAGON:"hexagon",ARROW_CLASSIC:"classic",ARROW_CLASSIC_THIN:"classicThin",ARROW_BLOCK:"block",ARROW_BLOCK_THIN:"blockThin",ARROW_OPEN:"open",ARROW_OPEN_THIN:"openThin",ARROW_OVAL:"oval",ARROW_DIAMOND:"diamond",ARROW_DIAMOND_THIN:"diamondThin",ALIGN_LEFT:"left",ALIGN_CENTER:"center",ALIGN_RIGHT:"right",ALIGN_TOP:"top",ALIGN_MIDDLE:"middle",ALIGN_BOTTOM:"bottom",DIRECTION_NORTH:"north",DIRECTION_SOUTH:"south",DIRECTION_EAST:"east",DIRECTION_WEST:"west",TEXT_DIRECTION_DEFAULT:"",TEXT_DIRECTION_AUTO:"auto",TEXT_DIRECTION_LTR:"ltr",TEXT_DIRECTION_RTL:"rtl",DIRECTION_MASK_NONE:0,DIRECTION_MASK_WEST:1,DIRECTION_MASK_NORTH:2,DIRECTION_MASK_SOUTH:4,DIRECTION_MASK_EAST:8,DIRECTION_MASK_ALL:15,ELBOW_VERTICAL:"vertical",ELBOW_HORIZONTAL:"horizontal",EDGESTYLE_ELBOW:"elbowEdgeStyle",EDGESTYLE_ENTITY_RELATION:"entityRelationEdgeStyle",EDGESTYLE_LOOP:"loopEdgeStyle",EDGESTYLE_SIDETOSIDE:"sideToSideEdgeStyle",EDGESTYLE_TOPTOBOTTOM:"topToBottomEdgeStyle",EDGESTYLE_ORTHOGONAL:"orthogonalEdgeStyle",EDGESTYLE_SEGMENT:"segmentEdgeStyle",PERIMETER_ELLIPSE:"ellipsePerimeter",PERIMETER_RECTANGLE:"rectanglePerimeter",PERIMETER_RHOMBUS:"rhombusPerimeter",PERIMETER_HEXAGON:"hexagonPerimeter",PERIMETER_TRIANGLE:"trianglePerimeter"};function mxEventObject(t){this.name=t,this.properties=[];for(var e=1;emxEvent.PINCH_THRESHOLD||r>mxEvent.PINCH_THRESHOLD)&&(n=h[0].clientX+(h[1].clientX-h[0].clientX)/2,i=h[0].clientY+(h[1].clientY-h[0].clientY)/2,a(h[0],r=l.x-s.x&&i>=l.y-s.y&&n<=l.x-s.x+t.container.offsetWidth&&i<=l.y-s.y+t.container.offsetHeight},mxDragSource.prototype.mouseMove=function(t){var e,n,i=this.getGraphForEvent(t);null==i||this.graphContainsEvent(i,t)||(i=null),i!=this.currentGraph&&(null!=this.currentGraph&&this.dragExit(this.currentGraph,t),this.currentGraph=i,null!=this.currentGraph&&this.dragEnter(this.currentGraph,t)),null!=this.currentGraph&&this.dragOver(this.currentGraph,t),null==this.dragElement||null!=this.previewElement&&"visible"==this.previewElement.style.visibility?null!=this.dragElement&&(this.dragElement.style.visibility="hidden"):(e=mxEvent.getClientX(t),n=mxEvent.getClientY(t),null==this.dragElement.parentNode&&document.body.appendChild(this.dragElement),this.dragElement.style.visibility="visible",null!=this.dragOffset&&(e+=this.dragOffset.x,n+=this.dragOffset.y),i=mxUtils.getDocumentScrollOrigin(document),this.dragElement.style.left=e+i.x+"px",this.dragElement.style.top=n+i.y+"px"),mxEvent.consume(t)},mxDragSource.prototype.mouseUp=function(t){var e,n,i;null!=this.currentGraph&&(null==this.currentPoint||null!=this.previewElement&&"hidden"==this.previewElement.style.visibility||(e=this.currentGraph.view.scale,i=this.currentGraph.view.translate,n=this.currentPoint.x/e-i.x,i=this.currentPoint.y/e-i.y,this.drop(this.currentGraph,t,this.currentDropTarget,n,i)),this.dragExit(this.currentGraph),this.currentGraph=null),this.stopDrag(),this.removeListeners(),mxEvent.consume(t)},mxDragSource.prototype.removeListeners=function(){null!=this.eventSource&&(mxEvent.removeGestureListeners(this.eventSource,null,this.mouseMoveHandler,this.mouseUpHandler),this.eventSource=null),mxEvent.removeGestureListeners(document,null,this.mouseMoveHandler,this.mouseUpHandler),this.mouseMoveHandler=null,this.mouseUpHandler=null},mxDragSource.prototype.dragEnter=function(t,e){t.isMouseDown=!0,t.isMouseTrigger=mxEvent.isMouseEvent(e),this.previewElement=this.createPreviewElement(t),null!=this.previewElement&&this.checkEventSource&&mxClient.IS_SVG&&(this.previewElement.style.pointerEvents="none"),this.isGuidesEnabled()&&null!=this.previewElement&&(this.currentGuide=new mxGuide(t,t.graphHandler.getGuideStates())),this.highlightDropTargets&&(this.currentHighlight=new mxCellHighlight(t,mxConstants.DROP_TARGET_COLOR)),t.addListener(mxEvent.FIRE_MOUSE_EVENT,this.eventConsumer)},mxDragSource.prototype.dragExit=function(t,e){this.currentDropTarget=null,this.currentPoint=null,t.isMouseDown=!1,t.removeListener(this.eventConsumer),null!=this.previewElement&&(null!=this.previewElement.parentNode&&this.previewElement.parentNode.removeChild(this.previewElement),this.previewElement=null),null!=this.currentGuide&&(this.currentGuide.destroy(),this.currentGuide=null),null!=this.currentHighlight&&(this.currentHighlight.destroy(),this.currentHighlight=null)},mxDragSource.prototype.dragOver=function(t,e){var n,i,l,s=mxUtils.getOffset(t.container),o=mxUtils.getScrollOrigin(t.container),r=mxEvent.getClientX(e)-s.x+o.x-t.panDx,s=mxEvent.getClientY(e)-s.y+o.y-t.panDy;t.autoScroll&&(null==this.autoscroll||this.autoscroll)&&t.scrollPointToVisible(r,s,t.autoExtend),null!=this.currentHighlight&&t.isDropEnabled()&&(this.currentDropTarget=this.getDropTarget(t,r,s,e),n=t.getView().getState(this.currentDropTarget),this.currentHighlight.highlight(n)),null!=this.previewElement&&(null==this.previewElement.parentNode&&(t.container.appendChild(this.previewElement),this.previewElement.style.zIndex="3",this.previewElement.style.position="absolute"),o=this.isGridEnabled()&&t.isGridEnabledEvent(e),n=!0,null!=this.currentGuide&&this.currentGuide.isEnabledForEvent(e)?(i=new mxRectangle(0,0,parseInt(this.previewElement.style.width),parseInt(this.previewElement.style.height)),l=new mxPoint(r,s),n=!1,r=(l=this.currentGuide.move(i,l,o,!0)).x,s=l.y):o&&(i=t.view.scale,l=t.view.translate,o=t.gridSize/2,r=(t.snap(r/i-l.x-o)+l.x)*i,s=(t.snap(s/i-l.y-o)+l.y)*i),null!=this.currentGuide&&n&&this.currentGuide.hide(),null!=this.previewOffset&&(r+=this.previewOffset.x,s+=this.previewOffset.y),this.previewElement.style.left=Math.round(r)+"px",this.previewElement.style.top=Math.round(s)+"px",this.previewElement.style.visibility="visible"),this.currentPoint=new mxPoint(r,s)},mxDragSource.prototype.drop=function(t,e,n,i,l){this.dropHandler.apply(this,arguments),"hidden"!=t.container.style.visibility&&t.container.focus()},mxToolbar.prototype=new mxEventSource,mxToolbar.prototype.constructor=mxToolbar,mxToolbar.prototype.container=null,mxToolbar.prototype.enabled=!0,mxToolbar.prototype.noReset=!1,mxToolbar.prototype.updateDefaultMode=!0,mxToolbar.prototype.addItem=function(t,e,n,i,l,s){var o=document.createElement(null!=e?"img":"button"),r=l||(null!=s?"mxToolbarMode":"mxToolbarItem");o.className=r,o.setAttribute("src",e),null!=t&&(null!=e?o.setAttribute("title",t):mxUtils.write(o,t)),this.container.appendChild(o),null!=n&&(mxEvent.addListener(o,"click",n),mxClient.IS_TOUCH&&mxEvent.addListener(o,"touchend",n));n=mxUtils.bind(this,function(t){null!=i?o.setAttribute("src",e):o.style.backgroundColor=""});return mxEvent.addGestureListeners(o,mxUtils.bind(this,function(t){var e;null!=i?o.setAttribute("src",i):o.style.backgroundColor="gray",null!=s&&(null==this.menu&&(this.menu=new mxPopupMenu,this.menu.init()),e=this.currentImg,this.menu.isMenuShowing()&&this.menu.hideMenu(),e!=o&&(this.currentImg=o,this.menu.factoryMethod=s,e=new mxPoint(o.offsetLeft,o.offsetTop+o.offsetHeight),this.menu.popup(e.x,e.y,null,t),this.menu.isMenuShowing()&&(o.className=r+"Selected",this.menu.hideMenu=function(){mxPopupMenu.prototype.hideMenu.apply(this),o.className=r,this.currentImg=null})))}),null,n),mxEvent.addListener(o,"mouseout",n),o},mxToolbar.prototype.addCombo=function(t){var e=document.createElement("div");e.style.display="inline",e.className="mxToolbarComboContainer";var n=document.createElement("select");return n.className=t||"mxToolbarCombo",e.appendChild(n),this.container.appendChild(e),n},mxToolbar.prototype.addActionCombo=function(t,e){var n=document.createElement("select");return n.className=e||"mxToolbarCombo",this.addOption(n,t,null),mxEvent.addListener(n,"change",function(t){var e=n.options[n.selectedIndex];n.selectedIndex=0,null!=e.funct&&e.funct(t)}),this.container.appendChild(n),n},mxToolbar.prototype.addOption=function(t,e,n){var i=document.createElement("option");return mxUtils.writeln(i,e),"function"==typeof n?i.funct=n:i.setAttribute("value",n),t.appendChild(i),i},mxToolbar.prototype.addSwitchMode=function(t,e,n,i,l){var s=document.createElement("img");return s.initialClassName=l||"mxToolbarMode",s.className=s.initialClassName,s.setAttribute("src",e),s.altIcon=i,null!=t&&s.setAttribute("title",t),mxEvent.addListener(s,"click",mxUtils.bind(this,function(t){var e=this.selectedMode.altIcon;null!=e?(this.selectedMode.altIcon=this.selectedMode.getAttribute("src"),this.selectedMode.setAttribute("src",e)):this.selectedMode.className=this.selectedMode.initialClassName,this.updateDefaultMode&&(this.defaultMode=s),null!=(e=(this.selectedMode=s).altIcon)?(s.altIcon=s.getAttribute("src"),s.setAttribute("src",e)):s.className=s.initialClassName+"Selected",this.fireEvent(new mxEventObject(mxEvent.SELECT)),n()})),this.container.appendChild(s),null==this.defaultMode&&(this.defaultMode=s,this.selectMode(s),n()),s},mxToolbar.prototype.addMode=function(t,e,n,i,l,s){s=null==s||s;var o=document.createElement(null!=e?"img":"button");return o.initialClassName=l||"mxToolbarMode",o.className=o.initialClassName,o.setAttribute("src",e),o.altIcon=i,null!=t&&o.setAttribute("title",t),this.enabled&&s&&(mxEvent.addListener(o,"click",mxUtils.bind(this,function(t){this.selectMode(o,n),this.noReset=!1})),mxEvent.addListener(o,"dblclick",mxUtils.bind(this,function(t){this.selectMode(o,n),this.noReset=!0})),null==this.defaultMode&&(this.defaultMode=o,this.defaultFunction=n,this.selectMode(o,n))),this.container.appendChild(o),o},mxToolbar.prototype.selectMode=function(t,e){var n;this.selectedMode!=t&&(null!=this.selectedMode&&(null!=(n=this.selectedMode.altIcon)?(this.selectedMode.altIcon=this.selectedMode.getAttribute("src"),this.selectedMode.setAttribute("src",n)):this.selectedMode.className=this.selectedMode.initialClassName),this.selectedMode=t,null!=(n=this.selectedMode.altIcon)?(this.selectedMode.altIcon=this.selectedMode.getAttribute("src"),this.selectedMode.setAttribute("src",n)):this.selectedMode.className=this.selectedMode.initialClassName+"Selected",this.fireEvent(new mxEventObject(mxEvent.SELECT,"function",e)))},mxToolbar.prototype.resetMode=function(t){!t&&this.noReset||this.selectedMode==this.defaultMode||this.selectMode(this.defaultMode,this.defaultFunction)},mxToolbar.prototype.addSeparator=function(t){return this.addItem(null,t,null)},mxToolbar.prototype.addBreak=function(){mxUtils.br(this.container)},mxToolbar.prototype.addLine=function(){var t=document.createElement("hr");t.style.marginRight="6px",t.setAttribute("size","1"),this.container.appendChild(t)},mxToolbar.prototype.destroy=function(){mxEvent.release(this.container),this.container=null,this.defaultMode=null,this.defaultFunction=null,(this.selectedMode=null)!=this.menu&&this.menu.destroy()},mxUndoableEdit.prototype.source=null,mxUndoableEdit.prototype.changes=null,mxUndoableEdit.prototype.significant=null,mxUndoableEdit.prototype.undone=!1,mxUndoableEdit.prototype.redone=!1,mxUndoableEdit.prototype.isEmpty=function(){return 0==this.changes.length},mxUndoableEdit.prototype.isSignificant=function(){return this.significant},mxUndoableEdit.prototype.add=function(t){this.changes.push(t)},mxUndoableEdit.prototype.notify=function(){},mxUndoableEdit.prototype.die=function(){},mxUndoableEdit.prototype.undo=function(){if(!this.undone){this.source.fireEvent(new mxEventObject(mxEvent.START_EDIT));for(var t=this.changes.length-1;0<=t;t--){var e=this.changes[t];null!=e.execute?e.execute():null!=e.undo&&e.undo(),this.source.fireEvent(new mxEventObject(mxEvent.EXECUTED,"change",e))}this.undone=!0,this.redone=!1,this.source.fireEvent(new mxEventObject(mxEvent.END_EDIT))}this.notify()},mxUndoableEdit.prototype.redo=function(){if(!this.redone){this.source.fireEvent(new mxEventObject(mxEvent.START_EDIT));for(var t=this.changes.length,e=0;ethis.indexOfNextAdd)for(var t=this.history.splice(this.indexOfNextAdd,this.history.length-this.indexOfNextAdd),e=0;ethis.autoSaveDelay||this.ignoredChanges>=this.autoSaveThreshold&&e>this.autoSaveThrottle?(this.save(),this.reset()):this.ignoredChanges++},mxAutoSaveManager.prototype.reset=function(){this.lastSnapshot=(new Date).getTime(),this.ignoredChanges=0},mxAutoSaveManager.prototype.destroy=function(){this.setGraph(null)},mxAnimation.prototype=new mxEventSource,mxAnimation.prototype.constructor=mxAnimation,mxAnimation.prototype.delay=null,mxAnimation.prototype.thread=null,mxAnimation.prototype.isRunning=function(){return null!=this.thread},mxAnimation.prototype.startAnimation=function(){null==this.thread&&(this.thread=window.setInterval(mxUtils.bind(this,this.updateAnimation),this.delay))},mxAnimation.prototype.updateAnimation=function(){this.fireEvent(new mxEventObject(mxEvent.EXECUTE))},mxAnimation.prototype.stopAnimation=function(){null!=this.thread&&(window.clearInterval(this.thread),this.thread=null,this.fireEvent(new mxEventObject(mxEvent.DONE)))},mxMorphing.prototype=new mxAnimation,mxMorphing.prototype.constructor=mxMorphing,mxMorphing.prototype.graph=null,mxMorphing.prototype.steps=null,mxMorphing.prototype.step=0,mxMorphing.prototype.ease=null,mxMorphing.prototype.cells=null,mxMorphing.prototype.updateAnimation=function(){mxAnimation.prototype.updateAnimation.apply(this,arguments);var t=new mxCellStatePreview(this.graph);if(null!=this.cells)for(var e=0;e=this.steps)&&this.stopAnimation()},mxMorphing.prototype.show=function(t){t.show()},mxMorphing.prototype.animateCell=function(t,e,n){var i,l,s=this.graph.getView().getState(t),o=null;if(null!=s&&(o=this.getDelta(s),!this.graph.getModel().isVertex(t)||0==o.x&&0==o.y||(i=this.graph.view.getTranslate(),l=this.graph.view.getScale(),o.x+=i.x*l,o.y+=i.y*l,e.moveState(s,-o.x/this.ease,-o.y/this.ease))),n&&!this.stopRecursion(s,o))for(var r=this.graph.getModel().getChildCount(t),a=0;a",5)+1)),""==t.substring(t.length-7,t.length)&&(t=t.substring(0,t.length-7)))}else{if(null!=document.implementation&&null!=document.implementation.createDocument){var n=document.implementation.createDocument("http://www.w3.org/1999/xhtml","html",null),i=n.createElement("body");n.documentElement.appendChild(i);var l=document.createElement("div");l.innerHTML=t;for(var s=l.firstChild;null!=s;){var o=s.nextSibling;i.appendChild(n.adoptNode(s)),s=o}return i.innerHTML}l=document.createElement("textarea");l.innerHTML=t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(//g,">"),t=l.value.replace(/&/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&amp;/g,"&").replace(/
/g,"
").replace(/
/g,"
").replace(/(]+)>/gm,"$1 />")}return t},mxSvgCanvas2D.prototype.createDiv=function(t){var e=t;if(mxUtils.isNode(e)||(e="
"+this.convertHtml(e)+"
"),mxClient.IS_IE||mxClient.IS_IE11||!document.createElementNS)return mxUtils.isNode(e)&&(e="
"+mxUtils.getXml(e)+"
"),e='
'+e+"
",mxUtils.parseXml(e).documentElement;var n,i=document.createElementNS("http://www.w3.org/1999/xhtml","div");return mxUtils.isNode(e)?(t=(n=document.createElement("div")).cloneNode(!1),this.root.ownerDocument!=document?n.appendChild(e.cloneNode(!0)):n.appendChild(e),t.appendChild(n),i.appendChild(t)):i.innerHTML=e,i},mxSvgCanvas2D.prototype.updateText=function(t,e,n,i,l,s,o,r,a,h,d){null!=d&&null!=d.firstChild&&null!=d.firstChild.firstChild&&this.updateTextNodes(t,e,n,i,l,s,o,r,a,h,d.firstChild)},mxSvgCanvas2D.prototype.addForeignObject=function(t,e,n,i,l,s,o,r,a,h,d,u,p,m,c){var g=this.createElement("g"),x=this.createElement("foreignObject");x.setAttribute("style","overflow: visible; text-align: left;"),x.setAttribute("pointer-events","none"),m.ownerDocument!=document&&(m=mxUtils.importNodeImplementation(x.ownerDocument,m,!0)),x.appendChild(m),g.appendChild(x),this.updateTextNodes(t,e,n,i,s,o,r,h,d,u,g),this.root.ownerDocument==document||null!=(d=this.createAlternateContent(x,t,e,n,i,l,s,o,r,a,h,d,u))&&(x.setAttribute("requiredFeatures","http://www.w3.org/TR/SVG11/feature#Extensibility"),(u=this.createElement("switch")).appendChild(x),u.appendChild(d),g.appendChild(u)),c.appendChild(g)},mxSvgCanvas2D.prototype.updateTextNodes=function(u,p,t,e,n,i,l,s,o,m,c){var g=this.state.scale;mxSvgCanvas2D.createCss(t+2,e,n,i,l,s,o,null!=this.state.fontBackgroundColor?this.state.fontBackgroundColor:null,null!=this.state.fontBorderColor?this.state.fontBorderColor:null,"display: flex; align-items: unsafe "+(i==mxConstants.ALIGN_TOP?"flex-start":i==mxConstants.ALIGN_BOTTOM?"flex-end":"center")+"; justify-content: unsafe "+(n==mxConstants.ALIGN_LEFT?"flex-start":n==mxConstants.ALIGN_RIGHT?"flex-end":"center")+"; ",this.getTextCss(),g,mxUtils.bind(this,function(t,e,n,i,l){u+=this.state.dx,p+=this.state.dy;var s=c.firstChild,o=s.firstChild,r=o.firstChild,a=r.firstChild,h=(this.rotateHtml?this.state.rotation:0)+(null!=m?m:0),d=(0!=this.foOffset?"translate("+this.foOffset+" "+this.foOffset+")":"")+(1!=g?"scale("+g+")":"");a.setAttribute("style",l),r.setAttribute("style",i),s.setAttribute("width",Math.ceil(1/Math.min(1,g)*100)+"%"),s.setAttribute("height",Math.ceil(1/Math.min(1,g)*100)+"%");e=Math.round(p+e);e<0?s.setAttribute("y",e):(s.removeAttribute("y"),n+="padding-top: "+e+"px; "),o.setAttribute("style",n+"margin-left: "+Math.round(u+t)+"px;"),(d+=0!=h?"rotate("+h+" "+u+" "+p+")":"")?c.setAttribute("transform",d):c.removeAttribute("transform"),1!=this.state.alpha?c.setAttribute("opacity",this.state.alpha):c.removeAttribute("opacity")}))},mxSvgCanvas2D.createCss=function(t,e,n,i,l,s,o,r,a,h,d,u,p){var m="box-sizing: border-box; font-size: 0; text-align: "+(n==mxConstants.ALIGN_LEFT?"left":n==mxConstants.ALIGN_RIGHT?"right":"center")+"; ",c=mxUtils.getAlignmentAsPoint(n,i),g="overflow: hidden; ",x="width: 1px; ",n="height: 1px; ",i=c.x*t,c=c.y*e;o?(x="width: "+Math.round(t)+"px; ",m+="max-height: "+Math.round(e)+"px; ",c=0):"fill"==s?(d+="width: 100%; height: 100%; ",m+=(x="width: "+Math.round(t)+"px; ")+(n="height: "+Math.round(e)+"px; ")):"width"==s?(d+="width: 100%; ",m+=x="width: "+Math.round(t)+"px; ",(c=0)"),document.body.appendChild(a),l=a.offsetWidth,s=a.offsetHeight,a.parentNode.removeChild(a),o==mxConstants.ALIGN_CENTER?n-=l/2:o==mxConstants.ALIGN_RIGHT&&(n-=l),r==mxConstants.ALIGN_MIDDLE?i-=s/2:r==mxConstants.ALIGN_BOTTOM&&(i-=s),d=new mxRectangle((n+1)*h.scale,(i+2)*h.scale,l*h.scale,(s+1)*h.scale)),null!=d&&((s=this.createElement("rect")).setAttribute("fill",h.fontBackgroundColor||"none"),s.setAttribute("stroke",h.fontBorderColor||"none"),s.setAttribute("x",Math.floor(d.x-1)),s.setAttribute("y",Math.floor(d.y-1)),s.setAttribute("width",Math.ceil(d.width+2)),s.setAttribute("height",Math.ceil(d.height)),h=null!=h.fontBorderColor?Math.max(1,this.format(h.scale)):0,s.setAttribute("stroke-width",h),this.root.ownerDocument==document&&1==mxUtils.mod(h,2)&&s.setAttribute("transform","translate(0.5, 0.5)"),t.insertBefore(s,t.firstChild))}},mxSvgCanvas2D.prototype.stroke=function(){this.addNode(!1,!0)},mxSvgCanvas2D.prototype.fill=function(){this.addNode(!0,!1)},mxSvgCanvas2D.prototype.fillAndStroke=function(){this.addNode(!0,!0)};var mxVmlCanvas2D=function(t){mxAbstractCanvas2D.call(this),this.root=t};function mxGuide(t,e){this.graph=t,this.setStates(e)}function mxShape(t){this.stencil=t,this.initStyles()}function mxStencil(t){this.desc=t,this.parseDescription(),this.parseConstraints()}mxUtils.extend(mxVmlCanvas2D,mxAbstractCanvas2D),mxVmlCanvas2D.prototype.node=null,mxVmlCanvas2D.prototype.textEnabled=!0,mxVmlCanvas2D.prototype.moveOp="m",mxVmlCanvas2D.prototype.lineOp="l",mxVmlCanvas2D.prototype.curveOp="c",mxVmlCanvas2D.prototype.closeOp="x",mxVmlCanvas2D.prototype.rotatedHtmlBackground="",mxVmlCanvas2D.prototype.vmlScale=1,mxVmlCanvas2D.prototype.createElement=function(t){return document.createElement(t)},mxVmlCanvas2D.prototype.createVmlElement=function(t){return this.createElement(mxClient.VML_PREFIX+":"+t)},mxVmlCanvas2D.prototype.addNode=function(t,e){var n=this.node,i=this.state;if(null!=n){if("shape"==n.nodeName){if(!(null!=this.path&&0Math.PI/2&&(T=Math.PI-T),E=Math.cos(T),S=Math.sin(T),8!=document.documentMode||mxClient.IS_EM||(y.style.display="inline-block",b.style.display="inline-block",c.style.display="inline-block"),y.style.visibility="hidden",y.style.position="absolute",document.body.appendChild(y),null!=(T=y).firstChild&&"DIV"==T.firstChild.nodeName&&(T=T.firstChild),v=T.offsetWidth+3,T=T.offsetHeight,d?(n=Math.min(n,v),T=Math.min(T,i)):n=v,r&&(y.style.width=n+"px"),mxClient.IS_QUIRKS&&(d||"width"==h)&&i
")),l=!mxUtils.isNode(this.value)&&this.replaceLinefeeds&&"html"==i?l.replace(/\n/g,"
"):l,(e=this.textDirection)!=mxConstants.TEXT_DIRECTION_AUTO||n||(e=this.getAutoDirection()),e!=mxConstants.TEXT_DIRECTION_LTR&&e!=mxConstants.TEXT_DIRECTION_RTL&&(e=null),t.text(s,o,r,a,l,this.align,this.valign,this.wrap,i,this.overflow,this.clipped,this.getTextRotation(),e))},mxText.prototype.redraw=function(){var t;this.visible&&this.checkBounds()&&this.cacheEnabled&&this.lastValue==this.value&&(mxUtils.isNode(this.value)||this.dialect==mxConstants.DIALECT_STRICTHTML)?"DIV"!=this.node.nodeName||!this.isHtmlAllowed()&&mxClient.IS_VML?null!=(t=this.createCanvas())&&null!=t.updateText?(t.pointerEvents=this.pointerEvents,this.paint(t,!0),this.destroyCanvas(t),this.updateBoundingBox()):mxShape.prototype.redraw.apply(this,arguments):(mxClient.IS_SVG?this.redrawHtmlShapeWithCss3():(this.updateSize(this.node,null==this.state||null==this.state.view.textDiv),mxClient.IS_IE&&(null==document.documentMode||document.documentMode<=8)?this.updateHtmlFilter():this.updateHtmlTransform()),this.updateBoundingBox()):(mxShape.prototype.redraw.apply(this,arguments),mxUtils.isNode(this.value)||this.dialect==mxConstants.DIALECT_STRICTHTML?this.lastValue=this.value:this.lastValue=null)},mxText.prototype.resetStyles=function(){mxShape.prototype.resetStyles.apply(this,arguments),this.color="black",this.align=mxConstants.ALIGN_CENTER,this.valign=mxConstants.ALIGN_MIDDLE,this.family=mxConstants.DEFAULT_FONTFAMILY,this.size=mxConstants.DEFAULT_FONTSIZE,this.fontStyle=mxConstants.DEFAULT_FONTSTYLE,this.spacing=2,this.spacingTop=2,this.spacingRight=2,this.spacingBottom=2,this.spacingLeft=2,this.horizontal=!0,delete this.background,delete this.border,this.textDirection=mxConstants.DEFAULT_TEXT_DIRECTION,delete this.margin},mxText.prototype.apply=function(t){var e=this.spacing;mxShape.prototype.apply.apply(this,arguments),null!=this.style&&(this.fontStyle=mxUtils.getValue(this.style,mxConstants.STYLE_FONTSTYLE,this.fontStyle),this.family=mxUtils.getValue(this.style,mxConstants.STYLE_FONTFAMILY,this.family),this.size=mxUtils.getValue(this.style,mxConstants.STYLE_FONTSIZE,this.size),this.color=mxUtils.getValue(this.style,mxConstants.STYLE_FONTCOLOR,this.color),this.align=mxUtils.getValue(this.style,mxConstants.STYLE_ALIGN,this.align),this.valign=mxUtils.getValue(this.style,mxConstants.STYLE_VERTICAL_ALIGN,this.valign),this.spacing=parseInt(mxUtils.getValue(this.style,mxConstants.STYLE_SPACING,this.spacing)),this.spacingTop=parseInt(mxUtils.getValue(this.style,mxConstants.STYLE_SPACING_TOP,this.spacingTop-e))+this.spacing,this.spacingRight=parseInt(mxUtils.getValue(this.style,mxConstants.STYLE_SPACING_RIGHT,this.spacingRight-e))+this.spacing,this.spacingBottom=parseInt(mxUtils.getValue(this.style,mxConstants.STYLE_SPACING_BOTTOM,this.spacingBottom-e))+this.spacing,this.spacingLeft=parseInt(mxUtils.getValue(this.style,mxConstants.STYLE_SPACING_LEFT,this.spacingLeft-e))+this.spacing,this.horizontal=mxUtils.getValue(this.style,mxConstants.STYLE_HORIZONTAL,this.horizontal),this.background=mxUtils.getValue(this.style,mxConstants.STYLE_LABEL_BACKGROUNDCOLOR,this.background),this.border=mxUtils.getValue(this.style,mxConstants.STYLE_LABEL_BORDERCOLOR,this.border),this.textDirection=mxUtils.getValue(this.style,mxConstants.STYLE_TEXT_DIRECTION,mxConstants.DEFAULT_TEXT_DIRECTION),this.opacity=mxUtils.getValue(this.style,mxConstants.STYLE_TEXT_OPACITY,100),this.updateMargin()),this.flipV=null,this.flipH=null},mxText.prototype.getAutoDirection=function(){var t=/[A-Za-z\u05d0-\u065f\u066a-\u06ef\u06fa-\u07ff\ufb1d-\ufdff\ufe70-\ufefc]/.exec(this.value);return null!=t&&0
"),t=this.replaceLinefeeds?t.replace(/\n/g,"
"):t},mxText.prototype.getTextCss=function(){var t=mxConstants.ABSOLUTE_LINE_HEIGHT?this.size*mxConstants.LINE_HEIGHT+"px":mxConstants.LINE_HEIGHT,e="display: inline-block; font-size: "+this.size+"px; font-family: "+this.family+"; color: "+this.color+"; line-height: "+t+"; pointer-events: "+(this.pointerEvents?"all":"none")+"; ";(this.fontStyle&mxConstants.FONT_BOLD)==mxConstants.FONT_BOLD&&(e+="font-weight: bold; "),(this.fontStyle&mxConstants.FONT_ITALIC)==mxConstants.FONT_ITALIC&&(e+="font-style: italic; ");t=[];return(this.fontStyle&mxConstants.FONT_UNDERLINE)==mxConstants.FONT_UNDERLINE&&t.push("underline"),(this.fontStyle&mxConstants.FONT_STRIKETHROUGH)==mxConstants.FONT_STRIKETHROUGH&&t.push("line-through"),0
"+n+"
"),this.node.firstChild.firstChild.setAttribute("style",l),this.node.firstChild.setAttribute("style",i)}))},mxText.prototype.updateHtmlTransform=function(){var t=this.getTextRotation(),e=this.node.style,n=this.margin.x,i=this.margin.y;0!=t?(mxUtils.setPrefixedStyle(e,"transformOrigin",100*-n+"% "+100*-i+"%"),mxUtils.setPrefixedStyle(e,"transform","translate("+100*n+"%,"+100*i+"%) scale("+this.scale+") rotate("+t+"deg)")):(mxUtils.setPrefixedStyle(e,"transformOrigin","0% 0%"),mxUtils.setPrefixedStyle(e,"transform","scale("+this.scale+") translate("+100*n+"%,"+100*i+"%)")),e.left=Math.round(this.bounds.x-Math.ceil(n*("fill"!=this.overflow&&"width"!=this.overflow?3:1)))+"px",e.top=Math.round(this.bounds.y-i*("fill"!=this.overflow?3:1))+"px",this.opacity<100?e.opacity=this.opacity/100:e.opacity=""},mxText.prototype.updateInnerHtml=function(t){var e;mxUtils.isNode(this.value)?t.innerHTML=this.value.outerHTML:(e=this.value,this.dialect!=mxConstants.DIALECT_STRICTHTML&&(e=mxUtils.htmlEntities(e,!1)),e=mxUtils.replaceTrailingNewlines(e,"
 
"),e='
'+(e=this.replaceLinefeeds?e.replace(/\n/g,"
"):e)+"
",t.innerHTML=e)},mxText.prototype.updateHtmlFilter=function(){var t=this.node.style,e=this.margin.x,n=this.margin.y,i=this.scale;mxUtils.setOpacity(this.node,this.opacity);var l=0,s=0,o=null!=this.state?this.state.view.textDiv:null,r=this.node;null!=o?(o.style.overflow="",o.style.height="",o.style.width="",this.updateFont(o),this.updateSize(o,!1),this.updateInnerHtml(o),a=Math.round(this.bounds.width/this.scale),this.wrap&&0Math.PI/2&&(d=Math.PI-d);o=Math.cos(d),r=Math.sin(-d),s=a*-(e+.5),l=h*-(n+.5),e=(h-h*o+a*r)/2+p*s-u*l,l=(a-a*o+h*r)/2-u*s-p*l;0!=d&&(u="progid:DXImageTransform.Microsoft.Matrix(M11="+u+", M12="+p+", M21="+-p+", M22="+u+", sizingMethod='auto expand')",null!=t.filter&&0
"),i=this.replaceLinefeeds?i.replace(/\n/g,"
"):i,t=null!=this.background&&this.background!=mxConstants.NONE?this.background:null,e=null!=this.border&&this.border!=mxConstants.NONE?this.border:null,"fill"==this.overflow||"width"==this.overflow?(null!=t&&(this.node.style.backgroundColor=t),null!=e&&(this.node.style.border="1px solid "+e)):(n="",null!=t&&(n+="background-color:"+mxUtils.htmlEntities(t)+";"),null!=e&&(n+="border:1px solid "+mxUtils.htmlEntities(e)+";"),i='
'+i+"
"),this.node.innerHTML=i,0<(n=this.node.getElementsByTagName("div")).length&&((i=this.textDirection)==mxConstants.TEXT_DIRECTION_AUTO&&this.dialect!=mxConstants.DIALECT_STRICTHTML&&(i=this.getAutoDirection()),i==mxConstants.TEXT_DIRECTION_LTR||i==mxConstants.TEXT_DIRECTION_RTL?n[n.length-1].setAttribute("dir",i):n[n.length-1].removeAttribute("dir")))},mxText.prototype.updateFont=function(t){var e=t.style;e.lineHeight=mxConstants.ABSOLUTE_LINE_HEIGHT?this.size*mxConstants.LINE_HEIGHT+"px":mxConstants.LINE_HEIGHT,e.fontSize=this.size+"px",e.fontFamily=this.family,e.verticalAlign="top",e.color=this.color,(this.fontStyle&mxConstants.FONT_BOLD)==mxConstants.FONT_BOLD?e.fontWeight="bold":e.fontWeight="",(this.fontStyle&mxConstants.FONT_ITALIC)==mxConstants.FONT_ITALIC?e.fontStyle="italic":e.fontStyle="";t=[];(this.fontStyle&mxConstants.FONT_UNDERLINE)==mxConstants.FONT_UNDERLINE&&t.push("underline"),(this.fontStyle&mxConstants.FONT_STRIKETHROUGH)==mxConstants.FONT_STRIKETHROUGH&&t.push("line-through"),e.textDecoration=t.join(" "),this.align==mxConstants.ALIGN_CENTER?e.textAlign="center":this.align==mxConstants.ALIGN_RIGHT?e.textAlign="right":e.textAlign="left"},mxText.prototype.updateSize=function(t,e){var n,i=Math.max(0,Math.round(this.bounds.width/this.scale)),l=Math.max(0,Math.round(this.bounds.height/this.scale)),s=t.style;this.clipped?(s.overflow="hidden",mxClient.IS_QUIRKS?s.width=i+"px":(s.maxHeight=l+"px",s.maxWidth=i+"px")):"fill"==this.overflow?(s.width=i+1+"px",s.height=l+1+"px",s.overflow="hidden"):"width"==this.overflow&&(s.width=i+1+"px",s.maxHeight=l+1+"px",s.overflow="hidden"),this.wrap&&0t.weightedValue||!(e.weightedValuee.x)?1:-1:t.y==e.y?0:0<(t.y>e.y)?1:-1})),i},mxStackLayout.prototype.snap=function(t){var e;return null!=this.gridSize&&0this.gridSize/2?this.gridSize-e:-e),t},mxStackLayout.prototype.execute=function(t){if(null!=t){var e=this.getParentSize(t),n=this.isHorizontal(),i=this.graph.getModel(),l=null;null!=e&&(l=n?e.height-this.marginTop-this.marginBottom:e.width-this.marginLeft-this.marginRight),l-=2*this.border;var s,o,r=this.x0+this.border+this.marginLeft,a=this.y0+this.border+this.marginTop;this.graph.isSwimlane(t)&&(o=this.graph.getCellStyle(t),s=mxUtils.getNumber(o,mxConstants.STYLE_STARTSIZE,mxConstants.DEFAULT_STARTSIZE),o=1==mxUtils.getValue(o,mxConstants.STYLE_HORIZONTAL,!0),null!=e&&(s=o?Math.min(s,e.height):Math.min(s,e.width)),n==o&&(l-=s),o?a+=s:r+=s),i.beginUpdate();try{for(var h=0,d=null,u=0,p=null,m=this.getLayoutCells(t),c=0;cthis.wrap||!n&&d.y+d.height+f.height+2*this.spacing>this.wrap)&&(d=null,n?a+=h+this.spacing:r+=h+this.spacing,h=0),h=Math.max(h,n?f.height:f.width),g=0,this.borderCollapse||(x=this.graph.getCellStyle(y),g=mxUtils.getNumber(x,mxConstants.STYLE_STROKEWIDTH,1)),null!=d?(x=u+this.spacing+Math.floor(g/2),n?f.x=this.snap((this.allowGaps?Math.max(x,f.x):x)-this.marginLeft)+this.marginLeft:f.y=this.snap((this.allowGaps?Math.max(x,f.y):x)-this.marginTop)+this.marginTop):this.keepFirstLocation||(n?f.x=this.allowGaps&&f.x>r?Math.max(this.snap(f.x-this.marginLeft)+this.marginLeft,r):r:f.y=this.allowGaps&&f.y>a?Math.max(this.snap(f.y-this.marginTop)+this.marginTop,a):a),n?f.y=a:f.x=r,this.fill&&null!=l&&(n?f.height=l:f.width=l),n?f.width=this.snap(f.width):f.height=this.snap(f.height),this.setChildGeometry(y,f),p=y,d=f,u=n?d.x+d.width+Math.floor(g/2):d.y+d.height+Math.floor(g/2))}this.resizeParent&&null!=e&&null!=d&&!this.graph.isCellCollapsed(t)?this.updateParentGeometry(t,e,d):this.resizeLast&&null!=e&&null!=d&&null!=p&&(n?d.width=e.width-d.x-this.spacing-this.marginRight-this.marginLeft:d.height=e.height-d.y-this.spacing-this.marginBottom,this.setChildGeometry(p,d))}finally{i.endUpdate()}}},mxStackLayout.prototype.setChildGeometry=function(t,e){var n=this.graph.getCellGeometry(t);null!=n&&e.x==n.x&&e.y==n.y&&e.width==n.width&&e.height==n.height||this.graph.getModel().setGeometry(t,e)},mxStackLayout.prototype.updateParentGeometry=function(t,e,n){var i,l=this.isHorizontal(),s=this.graph.getModel(),o=e.clone();l?(i=n.x+n.width+this.marginRight+this.border,this.resizeParentMax?o.width=Math.max(o.width,i):o.width=i):(i=n.y+n.height+this.marginBottom+this.border,this.resizeParentMax?o.height=Math.max(o.height,i):o.height=i),e.x==o.x&&e.y==o.y&&e.width==o.width&&e.height==o.height||s.setGeometry(t,o)},mxPartitionLayout.prototype=new mxGraphLayout,mxPartitionLayout.prototype.constructor=mxPartitionLayout,mxPartitionLayout.prototype.horizontal=null,mxPartitionLayout.prototype.spacing=null,mxPartitionLayout.prototype.border=null,mxPartitionLayout.prototype.resizeVertices=!0,mxPartitionLayout.prototype.isHorizontal=function(){return this.horizontal},mxPartitionLayout.prototype.moveCell=function(t,e,n){var i=this.graph.getModel(),l=i.getParent(t);if(null!=t&&null!=l){for(var s=0,o=0,r=i.getChildCount(l),s=0;st.height&&(t.height=this.maxRankHeight[e]);for(var n=t.child;null!=n;)this.setCellHeights(n,e+1),n=n.next},mxCompactTreeLayout.prototype.dfs=function(t,e){var n=mxCellPath.create(t),i=null;if(null!=t&&null==this.visited[n]&&!this.isVertexIgnored(t)){this.visited[n]=t,i=this.createNode(t);var l=this.graph.getModel(),s=null,o=this.graph.getEdges(t,e,this.invert,!this.invert,!1,!0),r=this.graph.getView();this.sortEdges&&this.sortOutgoingEdges(t,o);for(var a=0;ar+2*this.prefHozEdgeSep&&(o-=2*this.prefHozEdgeSep);var a=o/i,h=a/2;o>r+2*this.prefHozEdgeSep&&(h+=this.prefHozEdgeSep);for(var d=this.minEdgeJetty-this.prefVertEdgeOff,u=0,p=this.getVertexBounds(n),e=t.child,m=0;mc.theta&&mthis.maxDistanceLimit||(l=a.length){for(var h=new mxGraphHierarchyEdge(a),d=0;d=d.length){for(var u=new mxGraphHierarchyEdge(d),p=0;ps[i.swimlaneIndex]&&(d=s[i.swimlaneIndex]),i.temp[0]=d,null!=a)for(var p,n=0;n>1]}return n},mxMedianHybridCrossingReduction.prototype.transpose=function(t,e){for(var n=!0,i=0;n&&i++<10;)for(var l=t%2==1&&i%2==1,n=!1,s=0;sy[b]&&S++,g[E]f[b]&&S++,x[E]t.medianValue?-1:e.medianValueu.getGeneralPurposeVariable(p)+1&&(u.setGeneralPurposeVariable(p,b),y=!0)),y){for(l=0;lthis.widestRankValue&&(this.widestRankValue=r,this.widestRank=l),this.rankWidths[l]=r}1==a&&mxLog.warn("At least one cell has no bounds"),this.rankY[l]=n;var p=s/2+i/2+this.interRankCellSpacing,i=s;this.orientation==mxConstants.DIRECTION_NORTH||this.orientation==mxConstants.DIRECTION_WEST?n+=p:n-=p;for(h=0;hl.minRank+1;a--)c==(g=l.getX(a-1))||this.repositionValid(e,l,a-1,c)?(m[a-l.minRank-2]=c,u++):(m[a-l.minRank-2]=l.getX(a-1),c=g);if(rl.minRank;a--)l.setX(a,m[a-l.minRank-1]);else if(uf+2*this.prefHozEdgeSep&&(u+=this.prefHozEdgeSep,p-=this.prefHozEdgeSep);for(var C=(p-u)/m,v=u+C/2,E=this.minEdgeJetty-this.prefVertEdgeOff,S=0,h=0;h=this.swimlanes.length||(re[o]?1:-1:(n=parseInt(t[o]))==(i=parseInt(e[o]))?0:i=t.x&&n.x<=t.x+t.width?h.x=n.x:n.y>=t.y&&n.y<=t.y+t.height&&(h.y=n.y),n.xt.x+t.width&&(h.x=t.x+t.width),n.yt.y+t.height&&(h.y=t.y+t.height)),h},EllipsePerimeter:function(t,e,n,i){var l=t.x,s=t.y,o=t.width/2,r=t.height/2,a=l+o,h=s+r,d=n.x,u=n.y,p=parseInt(d-a),n=parseInt(u-h);if(0==p&&0!=n)return new mxPoint(a,h+r*n/Math.abs(n));if(0==p&&0==n)return new mxPoint(d,u);if(i){if(s<=u&&u<=s+t.height){var m=u-h,c=Math.sqrt(o*o*(1-m*m/(r*r)))||0;return d<=l&&(c=-c),new mxPoint(a+c,u)}if(l<=d&&d<=l+t.width){c=d-a,m=Math.sqrt(r*r*(1-c*c/(o*o)))||0;return u<=s&&(m=-m),new mxPoint(d,h+m)}}m=n/p,n=h-m*a,p=o*o*m*m+r*r,h=-2*a*p,o=o*o*m*m*a*a+r*r*a*a-o*o*r*r,r=Math.sqrt(h*h-4*p*o),o=(-h+r)/(2*p),h=(-h-r)/(2*p),r=m*o+n,p=m*h+n,m=0,n=0,n=Math.sqrt(Math.pow(o-d,2)+Math.pow(r-u,2))Math.PI-e)?i&&(s&&n.x>=p.x&&n.x<=c.x||!s&&n.y>=p.y&&n.y<=c.y)?s?new mxPoint(n.x,p.y):new mxPoint(p.x,n.y):l==mxConstants.DIRECTION_NORTH?new mxPoint(o+a/2+h*Math.tan(y)/2,r+h):l==mxConstants.DIRECTION_SOUTH?new mxPoint(o+a/2-h*Math.tan(y)/2,r):l==mxConstants.DIRECTION_WEST?new mxPoint(o+a,r+h/2+a*Math.tan(y)/2):new mxPoint(o,r+h/2-a*Math.tan(y)/2):(i&&(i=new mxPoint(d,u),n.y>=r&&n.y<=r+h?(i.x=s?d:l==mxConstants.DIRECTION_WEST?o+a:o,i.y=n.y):n.x>=o&&n.x<=o+a&&(i.x=n.x,i.y=s?l==mxConstants.DIRECTION_NORTH?r+h:r:u),g=n.x-i.x,x=n.y-i.y,d=i.x,u=i.y),s&&n.x<=o+a/2||!s&&n.y<=r+h/2?mxUtils.intersection(n.x,n.y,d,u,p.x,p.y,m.x,m.y):mxUtils.intersection(n.x,n.y,d,u,m.x,m.y,c.x,c.y)))&&(t=new mxPoint(d,u)),t},HexagonPerimeter:function(t,e,n,i){var l,s=t.x,o=t.y,r=t.width,a=t.height,h=t.getCenterX(),d=t.getCenterY(),u=n.x,p=n.y,m=u-h,c=p-d,g=-Math.atan2(c,m),x=Math.PI,y=Math.PI/2,f=new mxPoint(h,d),t=null!=e?mxUtils.getValue(e.style,mxConstants.STYLE_DIRECTION,mxConstants.DIRECTION_EAST):mxConstants.DIRECTION_EAST,c=t==mxConstants.DIRECTION_NORTH||t==mxConstants.DIRECTION_SOUTH,m=new mxPoint,e=new mxPoint;if((u':8==document.documentMode?t='':8'):("CSS1Compat"===document.compatMode&&r.writeln(""),r.writeln("")),r.writeln(""),this.writeHead(r,t),r.writeln(""),r.writeln(''));var a=this.graph.getGraphBounds().clone(),h=this.graph.getView().getScale(),d=h/this.scale,u=this.graph.getView().getTranslate();this.autoOrigin||(this.x0-=u.x*this.scale,this.y0-=u.y*this.scale,a.width+=a.x,a.height+=a.y,a.x=0,a.y=0,this.border=0);var p=this.pageFormat.width-2*this.border,m=this.pageFormat.height-2*this.border;this.pageFormat.height+=this.marginTop+this.marginBottom,a.width/=d,a.height/=d;var c=Math.max(1,Math.ceil((a.width+this.x0)/p)),g=Math.max(1,Math.ceil((a.height+this.y0)/m));this.pageCount=c*g;var d=mxUtils.bind(this,function(){var t,e;this.pageSelector&&(1"),t.writeln(""),t.close(),mxEvent.release(t.body))}catch(t){}},mxPrintPreview.prototype.writeHead=function(t,e){null!=this.title&&t.writeln(""+this.title+""),mxClient.IS_VML&&t.writeln(''),t.writeln('")},mxPrintPreview.prototype.writePostfix=function(t){},mxPrintPreview.prototype.createPageSelector=function(t,e){var n=this.wnd.document,i=n.createElement("table");i.className="mxPageSelector",i.setAttribute("border","0");for(var l=n.createElement("tbody"),s=0;s":"",mxCellEditor.prototype.escapeCancelsEditing=!0,mxCellEditor.prototype.textNode="",mxCellEditor.prototype.zIndex=5,mxCellEditor.prototype.minResize=new mxRectangle(0,20),mxCellEditor.prototype.wordWrapPadding=mxClient.IS_QUIRKS?2:mxClient.IS_IE11?0:1,mxCellEditor.prototype.blurEnabled=!1,mxCellEditor.prototype.initialValue=null,mxCellEditor.prototype.align=null,mxCellEditor.prototype.init=function(){this.textarea=document.createElement("div"),this.textarea.className="mxCellEditor mxPlainTextEditor",this.textarea.contentEditable=!0,mxClient.IS_GC&&(this.textarea.style.minHeight="1em"),this.textarea.style.position=this.isLegacyEditor()?"absolute":"relative",this.installListeners(this.textarea)},mxCellEditor.prototype.applyValue=function(t,e){this.graph.labelChanged(t.cell,e,this.trigger)},mxCellEditor.prototype.setAlign=function(t){null!=this.textarea&&(this.textarea.style.textAlign=t),this.align=t,this.resize()},mxCellEditor.prototype.getInitialValue=function(t,e){e=mxUtils.htmlEntities(this.graph.getEditingValue(t.cell,e),!1);return mxClient.IS_QUIRKS||8==document.documentMode||9==document.documentMode||10==document.documentMode||(e=mxUtils.replaceTrailingNewlines(e,"

")),e.replace(/\n/g,"
")},mxCellEditor.prototype.getCurrentValue=function(t){return mxUtils.extractTextWithWhitespace(this.textarea.childNodes)},mxCellEditor.prototype.isCancelEditingKeyEvent=function(t){return this.escapeCancelsEditing||mxEvent.isShiftDown(t)||mxEvent.isControlDown(t)||mxEvent.isMetaDown(t)},mxCellEditor.prototype.installListeners=function(e){mxEvent.addListener(e,"dragstart",mxUtils.bind(this,function(t){this.graph.stopEditing(!1),mxEvent.consume(t)})),mxEvent.addListener(e,"blur",mxUtils.bind(this,function(t){this.blurEnabled&&this.focusLost(t)})),mxEvent.addListener(e,"keydown",mxUtils.bind(this,function(t){mxEvent.isConsumed(t)||(this.isStopEditingEvent(t)?(this.graph.stopEditing(!1),mxEvent.consume(t)):27==t.keyCode&&(this.graph.stopEditing(this.isCancelEditingKeyEvent(t)),mxEvent.consume(t)))}));var t=mxUtils.bind(this,function(t){null!=this.editingCell&&this.clearOnChange&&e.innerHTML==this.getEmptyLabelText()&&(!mxClient.IS_FF||8!=t.keyCode&&46!=t.keyCode)&&(this.clearOnChange=!1,e.innerHTML="")});mxEvent.addListener(e,"keypress",t),mxEvent.addListener(e,"paste",t);var n=mxUtils.bind(this,function(t){null!=this.editingCell&&(0==this.textarea.innerHTML.length||"
"==this.textarea.innerHTML?(this.textarea.innerHTML=this.getEmptyLabelText(),this.clearOnChange=0d&&(this.textarea.style.width=this.textarea.scrollWidth+"px")):this.textarea.style.maxWidth=d+"px"):(this.textarea.style.whiteSpace="nowrap",this.textarea.style.width=""),8==document.documentMode&&(this.textarea.style.zoom="1",this.textarea.style.height="auto"),h=this.textarea.scrollWidth,d=this.textarea.scrollHeight,8==document.documentMode?(this.textarea.style.left=Math.max(0,Math.ceil((this.bounds.x-a.x*(this.bounds.width-(h+1)*t)+h*(t-1)*0+2*(a.x+.5))/t))+"px",this.textarea.style.top=Math.max(0,Math.ceil((this.bounds.y-a.y*(this.bounds.height-(d+.5)*t)+d*(t-1)*0+ +Math.abs(a.y+.5))/t))+"px",this.textarea.style.width=Math.round(h*t)+"px",this.textarea.style.height=Math.round(d*t)+"px"):mxClient.IS_QUIRKS?(this.textarea.style.left=Math.max(0,Math.ceil(this.bounds.x-a.x*(this.bounds.width-(h+1)*t)+h*(t-1)*0+2*(a.x+.5)))+"px",this.textarea.style.top=Math.max(0,Math.ceil(this.bounds.y-a.y*(this.bounds.height-(d+.5)*t)+d*(t-1)*0+ +Math.abs(a.y+.5)))+"px"):(this.textarea.style.left=Math.max(0,Math.round(this.bounds.x-a.x*(this.bounds.width-2))+1)+"px",this.textarea.style.top=Math.max(0,Math.round(this.bounds.y-a.y*(this.bounds.height-4)+(-1==a.y?3:0))+1)+"px")):(this.bounds=this.getEditorBounds(u),this.textarea.style.width=Math.round(this.bounds.width/t)+"px",this.textarea.style.height=Math.round(this.bounds.height/t)+"px",8==document.documentMode||mxClient.IS_QUIRKS?(this.textarea.style.left=Math.round(this.bounds.x)+"px",this.textarea.style.top=Math.round(this.bounds.y)+"px"):(this.textarea.style.left=Math.max(0,Math.round(this.bounds.x+1))+"px",this.textarea.style.top=Math.max(0,Math.round(this.bounds.y+1))+"px"),this.graph.isWrapping(u.cell)&&(2<=this.bounds.width||2<=this.bounds.height)&&this.textarea.innerHTML!=this.getEmptyLabelText()?(this.textarea.style.wordWrap=mxConstants.WORD_WRAP,this.textarea.style.whiteSpace="normal","fill"!=u.style[mxConstants.STYLE_OVERFLOW]&&(this.textarea.style.width=Math.round(this.bounds.width/t)+this.wordWrapPadding+"px")):(this.textarea.style.whiteSpace="nowrap","fill"!=u.style[mxConstants.STYLE_OVERFLOW]&&(this.textarea.style.width=""))),mxClient.IS_VML?this.textarea.style.zoom=t:(mxUtils.setPrefixedStyle(this.textarea.style,"transformOrigin","0px 0px"),mxUtils.setPrefixedStyle(this.textarea.style,"transform","scale("+t+","+t+")"+(null==a?"":" translate("+100*a.x+"%,"+100*a.y+"%)"))))},mxCellEditor.prototype.focusLost=function(){this.stopEditing(!this.graph.isInvokesStopCellEditing())},mxCellEditor.prototype.getBackgroundColor=function(t){return null},mxCellEditor.prototype.isLegacyEditor=function(){if(mxClient.IS_VML)return!0;var t,e=!1;return mxClient.IS_SVG&&(null==(t=this.graph.view.getDrawPane().ownerSVGElement)||null!=(t=mxUtils.getCurrentStyle(t))&&(e="absolute"==t.position)),!e},mxCellEditor.prototype.startEditing=function(t,e){this.stopEditing(!0),(this.align=null)==this.textarea&&this.init(),null!=this.graph.tooltipHandler&&this.graph.tooltipHandler.hideTooltip();var n=this.graph.getView().getState(t);if(null!=n){this.graph.getView().scale;var i=mxUtils.getValue(n.style,mxConstants.STYLE_FONTSIZE,mxConstants.DEFAULT_FONTSIZE),l=mxUtils.getValue(n.style,mxConstants.STYLE_FONTFAMILY,mxConstants.DEFAULT_FONTFAMILY),s=mxUtils.getValue(n.style,mxConstants.STYLE_FONTCOLOR,"black"),o=mxUtils.getValue(n.style,mxConstants.STYLE_ALIGN,mxConstants.ALIGN_LEFT),r=(mxUtils.getValue(n.style,mxConstants.STYLE_FONTSTYLE,0)&mxConstants.FONT_BOLD)==mxConstants.FONT_BOLD,a=(mxUtils.getValue(n.style,mxConstants.STYLE_FONTSTYLE,0)&mxConstants.FONT_ITALIC)==mxConstants.FONT_ITALIC,h=[];(mxUtils.getValue(n.style,mxConstants.STYLE_FONTSTYLE,0)&mxConstants.FONT_UNDERLINE)==mxConstants.FONT_UNDERLINE&&h.push("underline"),(mxUtils.getValue(n.style,mxConstants.STYLE_FONTSTYLE,0)&mxConstants.FONT_STRIKETHROUGH)==mxConstants.FONT_STRIKETHROUGH&&h.push("line-through"),this.textarea.style.lineHeight=mxConstants.ABSOLUTE_LINE_HEIGHT?Math.round(i*mxConstants.LINE_HEIGHT)+"px":mxConstants.LINE_HEIGHT,this.textarea.style.backgroundColor=this.getBackgroundColor(n),this.textarea.style.textDecoration=h.join(" "),this.textarea.style.fontWeight=r?"bold":"normal",this.textarea.style.fontStyle=a?"italic":"",this.textarea.style.fontSize=Math.round(i)+"px",this.textarea.style.zIndex=this.zIndex,this.textarea.style.fontFamily=l,this.textarea.style.textAlign=o,this.textarea.style.outline="none",this.textarea.style.color=s;s=this.textDirection=mxUtils.getValue(n.style,mxConstants.STYLE_TEXT_DIRECTION,mxConstants.DEFAULT_TEXT_DIRECTION);s==mxConstants.TEXT_DIRECTION_AUTO&&(null==n||null==n.text||n.text.dialect==mxConstants.DIALECT_STRICTHTML||mxUtils.isNode(n.text.value)||(s=n.text.getAutoDirection())),s==mxConstants.TEXT_DIRECTION_LTR||s==mxConstants.TEXT_DIRECTION_RTL?this.textarea.setAttribute("dir",s):this.textarea.removeAttribute("dir"),this.textarea.innerHTML=this.getInitialValue(n,e)||"",this.initialValue=this.textarea.innerHTML,0==this.textarea.innerHTML.length||"
"==this.textarea.innerHTML?(this.textarea.innerHTML=this.getEmptyLabelText(),this.clearOnChange=!0):this.clearOnChange=this.textarea.innerHTML==this.getEmptyLabelText(),this.graph.container.appendChild(this.textarea),this.editingCell=t,this.trigger=e,(this.textNode=null)!=n.text&&this.isHideLabel(n)&&(this.textNode=n.text.node,this.textNode.style.visibility="hidden"),this.autoSize&&(this.graph.model.isEdge(n.cell)||"fill"!=n.style[mxConstants.STYLE_OVERFLOW])&&window.setTimeout(mxUtils.bind(this,function(){this.resize()}),0),this.resize();try{this.textarea.focus(),this.isSelectText()&&0e.x+e.width?null!=m?(o=m.x,d=Math.max(Math.abs(h-m.y),d)):a==mxConstants.DIRECTION_NORTH?h=e.y-2*r:a==mxConstants.DIRECTION_SOUTH?h=e.y+e.height+2*r:o=a==mxConstants.DIRECTION_EAST?e.x-2*d:e.x+e.width+2*d:null!=m&&(o=s.getRoutingCenterX(e),r=Math.max(Math.abs(o-m.x),d),h=m.y,d=0),l.push(new mxPoint(o-r,h-d)),l.push(new mxPoint(o+r,h+d)));else if(null!=i&&0a,u=h.xo):(d=(s=Math.max(e.x,n.x))==(o=Math.min(e.x+e.width,n.x+n.width)))||(u=(r=Math.max(e.y,n.y))==(a=Math.min(e.y+e.height,n.y+n.height)))),u||!d&&t.style[mxConstants.STYLE_ELBOW]!=mxConstants.ELBOW_VERTICAL?mxEdgeStyle.SideToSide(t,e,n,i,l):mxEdgeStyle.TopToBottom(t,e,n,i,l)},SideToSide:function(t,e,n,i,l){var s=t.view,o=null!=i&&0=e.y&&o.y<=e.y+e.height&&(r=o.y),o.y>=n.y&&o.y<=n.y+n.height&&(s=o.y)),mxUtils.contains(n,i,r)||mxUtils.contains(e,i,r)||l.push(new mxPoint(i,r)),mxUtils.contains(n,i,s)||mxUtils.contains(e,i,s)||l.push(new mxPoint(i,s)),1==l.length&&(null!=o?mxUtils.contains(n,i,o.y)||mxUtils.contains(e,i,o.y)||l.push(new mxPoint(i,o.y)):(o=Math.max(e.y,n.y),n=Math.min(e.y+e.height,n.y+n.height),l.push(new mxPoint(i,o+(n-o)/2)))))},TopToBottom:function(t,e,n,i,l){var s=t.view,o=null!=i&&0=e.x&&o.x<=e.x+e.width&&(r=o.x),i=null!=o?o.y:Math.round(i+(t-i)/2),mxUtils.contains(n,r,i)||mxUtils.contains(e,r,i)||l.push(new mxPoint(r,i)),r=null!=o&&o.x>=n.x&&o.x<=n.x+n.width?o.x:s.getRoutingCenterX(n),mxUtils.contains(n,r,i)||mxUtils.contains(e,r,i)||l.push(new mxPoint(r,i)),1==l.length&&(null!=o&&1==l.length?mxUtils.contains(n,o.x,i)||mxUtils.contains(e,o.x,i)||l.push(new mxPoint(o.x,i)):(o=Math.max(e.x,n.x),n=Math.min(e.x+e.width,n.x+n.width),l.push(new mxPoint(o+(n-o)/2,i)))))},SegmentConnector:function(e,t,n,i,l){var s=mxEdgeStyle.scalePointArray(e.absolutePoints,e.view.scale),o=mxEdgeStyle.scaleCellState(t,e.view.scale),r=mxEdgeStyle.scaleCellState(n,e.view.scale),a=0=Math.max(1,e.view.scale))&&(l.push(t),a=t),a}var p=s[0];null==p&&null!=o?p=new mxPoint(e.view.getRoutingCenterX(o),e.view.getRoutingCenterY(o)):null!=p&&(p=p.clone());var m=s.length-1;if(null!=i&&0=f.y&&v.y<=f.y+f.height,b=null!=f&&v.x>=f.x&&v.x<=f.x+f.width,T=S||null==C&&w,A=E||null==C&&b;if(0!=g||!(T&&A||E&&S)){if(null!=C&&!S&&!E&&(w||b)){h=!w;break}if(A||T){h=T,1==g&&(h=c.length%2==0?T:A);break}}f=r,null!=(C=s[m])&&(f=null),v=c[c.length-1],E&&S&&(c=c.slice(1))}h&&(null!=s[0]&&s[0].y!=d.y||null==s[0]&&null!=o&&(d.yo.y+o.height))?u(new mxPoint(p.x,d.y)):!h&&(null!=s[0]&&s[0].x!=d.x||null==s[0]&&null!=o&&(d.xo.x+o.width))&&u(new mxPoint(d.x,p.y)),h?p.y=d.y:p.x=d.x;for(g=0;gr.y+r.height))?u(new mxPoint(p.x,d.y)):!h&&(null!=s[m]&&s[m].x!=d.x||null==s[m]&&null!=r&&(d.xr.x+r.width))&&u(new mxPoint(d.x,p.y))),null==s[0]&&null!=o)for(;1>8),0==(983040&N[I])&&(N[I]=65535&N[I]|(251658240&N[I])>>8),T[I]=15&N[I],b[I]!=mxConstants.DIRECTION_MASK_WEST&&b[I]!=mxConstants.DIRECTION_MASK_NORTH&&b[I]!=mxConstants.DIRECTION_MASK_EAST&&b[I]!=mxConstants.DIRECTION_MASK_SOUTH||(T[I]=b[I]));u=T[0]==mxConstants.DIRECTION_MASK_EAST?3:T[0],h=T[1]==mxConstants.DIRECTION_MASK_EAST?3:T[1];(u-=R)<1&&(u+=4),(h-=R)<1&&(h+=4);var G=mxEdgeStyle.routePatterns[u-1][h-1];switch(mxEdgeStyle.wayPoints1[0][0]=A[0][0],mxEdgeStyle.wayPoints1[0][1]=A[0][1],T[0]){case mxConstants.DIRECTION_MASK_WEST:mxEdgeStyle.wayPoints1[0][0]-=E,mxEdgeStyle.wayPoints1[0][1]+=U[0][1]*A[0][3];break;case mxConstants.DIRECTION_MASK_SOUTH:mxEdgeStyle.wayPoints1[0][0]+=U[0][0]*A[0][2],mxEdgeStyle.wayPoints1[0][1]+=A[0][3]+E;break;case mxConstants.DIRECTION_MASK_EAST:mxEdgeStyle.wayPoints1[0][0]+=A[0][2]+E,mxEdgeStyle.wayPoints1[0][1]+=U[0][1]*A[0][3];break;case mxConstants.DIRECTION_MASK_NORTH:mxEdgeStyle.wayPoints1[0][0]+=U[0][0]*A[0][2],mxEdgeStyle.wayPoints1[0][1]-=E}for(var k=0,V=0<(T[0]&(mxConstants.DIRECTION_MASK_EAST|mxConstants.DIRECTION_MASK_WEST))?0:1,F=V,B=0,I=0;I>5;15<(Z<<=R)&&(Z>>=4);z=0<(G[I]&mxEdgeStyle.CENTER_MASK);(X||j)&&Z<9?(j=0,X=X?0:1,j=z&&0==B?A[X][0]+U[X][0]*A[X][2]:z?A[X][1]+U[X][1]*A[X][3]:mxEdgeStyle.limits[X][Z],0==B?0<(Z=(j-mxEdgeStyle.wayPoints1[k][0])*W[0])&&(mxEdgeStyle.wayPoints1[k][0]+=W[0]*Z):0<(j=(j-mxEdgeStyle.wayPoints1[k][1])*W[1])&&(mxEdgeStyle.wayPoints1[k][1]+=W[1]*j)):z&&(mxEdgeStyle.wayPoints1[k][0]+=W[0]*Math.abs(mxEdgeStyle.vertexSeperations[Y]/2),mxEdgeStyle.wayPoints1[k][1]+=W[1]*Math.abs(mxEdgeStyle.vertexSeperations[Y]/2)),0=Math.round(a+r)&&he+2&&n.x<=t)return!0;e=this.graph.container.offsetHeight,t=this.graph.container.clientHeight;return tt+2&&n.y<=e},mxGraphView.prototype.init=function(){this.installListeners();var t=this.graph;t.dialect==mxConstants.DIALECT_SVG?this.createSvg():t.dialect==mxConstants.DIALECT_VML?this.createVml():this.createHtml()},mxGraphView.prototype.installListeners=function(){var e,i=this.graph,l=i.container;null!=l&&(mxClient.IS_TOUCH&&(mxEvent.addListener(l,"gesturestart",mxUtils.bind(this,function(t){i.fireGestureEvent(t),mxEvent.consume(t)})),mxEvent.addListener(l,"gesturechange",mxUtils.bind(this,function(t){i.fireGestureEvent(t),mxEvent.consume(t)})),mxEvent.addListener(l,"gestureend",mxUtils.bind(this,function(t){i.fireGestureEvent(t),mxEvent.consume(t)}))),e=null,mxEvent.addGestureListeners(l,mxUtils.bind(this,function(t){!this.isContainerEvent(t)||(mxClient.IS_IE||mxClient.IS_IE11||mxClient.IS_GC||mxClient.IS_OP||mxClient.IS_SF)&&this.isScrollEvent(t)||(i.fireMouseEvent(mxEvent.MOUSE_DOWN,new mxMouseEvent(t)),e=t.pointerId)}),mxUtils.bind(this,function(t){!this.isContainerEvent(t)||null!=e&&t.pointerId!=e||i.fireMouseEvent(mxEvent.MOUSE_MOVE,new mxMouseEvent(t))}),mxUtils.bind(this,function(t){this.isContainerEvent(t)&&i.fireMouseEvent(mxEvent.MOUSE_UP,new mxMouseEvent(t)),e=null})),mxEvent.addListener(l,"dblclick",mxUtils.bind(this,function(t){this.isContainerEvent(t)&&i.dblClick(t)})),i.addMouseListener({mouseDown:function(t,e){i.popupMenuHandler.hideMenu()},mouseMove:function(){},mouseUp:function(){}}),this.moveHandler=mxUtils.bind(this,function(t){var e,n;null!=i.tooltipHandler&&i.tooltipHandler.isHideOnHover()&&i.tooltipHandler.hide(),this.captureDocumentGesture&&i.isMouseDown&&null!=i.container&&!this.isContainerEvent(t)&&"none"!=i.container.style.display&&"hidden"!=i.container.style.visibility&&!mxEvent.isConsumed(t)&&i.fireMouseEvent(mxEvent.MOUSE_MOVE,new mxMouseEvent(t,(e=t,n=null,mxClient.IS_TOUCH&&(t=mxEvent.getClientX(e),e=mxEvent.getClientY(e),e=mxUtils.convertPoint(l,t,e),n=i.view.getState(i.getCellAt(e.x,e.y))),n)))}),this.endHandler=mxUtils.bind(this,function(t){this.captureDocumentGesture&&i.isMouseDown&&null!=i.container&&!this.isContainerEvent(t)&&"none"!=i.container.style.display&&"hidden"!=i.container.style.visibility&&i.fireMouseEvent(mxEvent.MOUSE_UP,new mxMouseEvent(t))}),mxEvent.addGestureListeners(document,null,this.moveHandler,this.endHandler))},mxGraphView.prototype.createHtml=function(){var t=this.graph.container;null!=t&&(this.canvas=this.createHtmlPane("100%","100%"),this.canvas.style.overflow="hidden",this.backgroundPane=this.createHtmlPane("1px","1px"),this.drawPane=this.createHtmlPane("1px","1px"),this.overlayPane=this.createHtmlPane("1px","1px"),this.decoratorPane=this.createHtmlPane("1px","1px"),this.canvas.appendChild(this.backgroundPane),this.canvas.appendChild(this.drawPane),this.canvas.appendChild(this.overlayPane),this.canvas.appendChild(this.decoratorPane),t.appendChild(this.canvas),this.updateContainerStyle(t),mxClient.IS_QUIRKS&&(t=mxUtils.bind(this,function(t){var e=this.getGraphBounds(),n=e.x+e.width+this.graph.border,e=e.y+e.height+this.graph.border;this.updateHtmlCanvasSize(n,e)}),mxEvent.addListener(window,"resize",t)))},mxGraphView.prototype.updateHtmlCanvasSize=function(t,e){var n,i;null!=this.graph.container&&(n=this.graph.container.offsetWidth,i=this.graph.container.offsetHeight,this.canvas.style.width=n")},mxGraph.prototype.createHandlers=function(){this.tooltipHandler=this.createTooltipHandler(),this.tooltipHandler.setEnabled(!1),this.selectionCellsHandler=this.createSelectionCellsHandler(),this.connectionHandler=this.createConnectionHandler(),this.connectionHandler.setEnabled(!1),this.graphHandler=this.createGraphHandler(),this.panningHandler=this.createPanningHandler(),this.panningHandler.panningEnabled=!1,this.popupMenuHandler=this.createPopupMenuHandler()},mxGraph.prototype.createTooltipHandler=function(){return new mxTooltipHandler(this)},mxGraph.prototype.createSelectionCellsHandler=function(){return new mxSelectionCellsHandler(this)},mxGraph.prototype.createConnectionHandler=function(){return new mxConnectionHandler(this)},mxGraph.prototype.createGraphHandler=function(){return new mxGraphHandler(this)},mxGraph.prototype.createPanningHandler=function(){return new mxPanningHandler(this)},mxGraph.prototype.createPopupMenuHandler=function(){return new mxPopupMenuHandler(this)},mxGraph.prototype.createSelectionModel=function(){return new mxGraphSelectionModel(this)},mxGraph.prototype.createStylesheet=function(){return new mxStylesheet},mxGraph.prototype.createGraphView=function(){return new mxGraphView(this)},mxGraph.prototype.createCellRenderer=function(){return new mxCellRenderer},mxGraph.prototype.createCellEditor=function(){return new mxCellEditor(this)},mxGraph.prototype.getModel=function(){return this.model},mxGraph.prototype.getView=function(){return this.view},mxGraph.prototype.getStylesheet=function(){return this.stylesheet},mxGraph.prototype.setStylesheet=function(t){this.stylesheet=t},mxGraph.prototype.getSelectionModel=function(){return this.selectionModel},mxGraph.prototype.setSelectionModel=function(t){this.selectionModel=t},mxGraph.prototype.getSelectionCellsForChanges=function(t,e){for(var i=new mxDictionary,l=[],s=mxUtils.bind(this,function(t){if(!i.get(t)&&this.model.contains(t))if(this.model.isEdge(t)||this.model.isVertex(t))i.put(t,!0),l.push(t);else for(var e=this.model.getChildCount(t),n=0;n"+t+"");return i&&t.addListener(mxEvent.CLICK,mxUtils.bind(this,function(t,e){this.isEnabled()&&this.setSelectionCell(n)})),this.addCellOverlay(n,t)}return this.removeCellOverlays(n),null},mxGraph.prototype.startEditing=function(t){this.startEditingAtCell(null,t)},mxGraph.prototype.startEditingAtCell=function(t,e){null!=e&&mxEvent.isMultiTouchEvent(e)||(null==t&&(null==(t=this.getSelectionCell())||this.isCellEditable(t)||(t=null)),null!=t&&(this.fireEvent(new mxEventObject(mxEvent.START_EDITING,"cell",t,"event",e)),this.cellEditor.startEditing(t,e),this.fireEvent(new mxEventObject(mxEvent.EDITING_STARTED,"cell",t,"event",e))))},mxGraph.prototype.getEditingValue=function(t,e){return this.convertValueToString(t)},mxGraph.prototype.stopEditing=function(t){this.cellEditor.stopEditing(t),this.fireEvent(new mxEventObject(mxEvent.EDITING_STOPPED,"cancel",t))},mxGraph.prototype.labelChanged=function(t,e,n){this.model.beginUpdate();try{var i=t.value;this.cellLabelChanged(t,e,this.isAutoSizeCell(t)),this.fireEvent(new mxEventObject(mxEvent.LABEL_CHANGED,"cell",t,"value",e,"old",i,"event",n))}finally{this.model.endUpdate()}return t},mxGraph.prototype.cellLabelChanged=function(t,e,n){this.model.beginUpdate();try{this.model.setValue(t,e),n&&this.cellSizeUpdated(t,!1)}finally{this.model.endUpdate()}},mxGraph.prototype.escape=function(t){this.fireEvent(new mxEventObject(mxEvent.ESCAPE,"event",t))},mxGraph.prototype.click=function(t){var n,e=t.getEvent(),i=t.getCell(),l=new mxEventObject(mxEvent.CLICK,"event",e,"cell",i);if(t.isConsumed()&&l.consume(),this.fireEvent(l),this.isEnabled()&&!mxEvent.isConsumed(e)&&!l.isConsumed()){if(null!=i)this.isTransparentClickEvent(e)&&(n=!1,null!=(l=this.getCellAt(t.graphX,t.graphY,null,null,null,mxUtils.bind(this,function(t){var e=this.isCellSelected(t.cell);return!(n=n||e)||e||t.cell!=i&&this.model.isAncestor(t.cell,i)})))&&(i=l));else if(this.isSwimlaneSelectionEnabled()&&!(null==(i=this.getSwimlaneAt(t.getGraphX(),t.getGraphY()))||this.isToggleEvent(e)&&mxEvent.isAltDown(e))){for(var s=i,o=[];null!=s;){s=this.model.getParent(s);var r=this.view.getState(s);this.isSwimlane(s)&&null!=r&&o.push(s)}if(0=(l=this.container).scrollLeft&&e>=l.scrollTop&&t<=l.scrollLeft+l.clientWidth&&e<=l.scrollTop+l.clientHeight&&((o=l.scrollLeft+l.clientWidth-t)this.minPageBreakDist)?Math.ceil(o.height/r.height)+1:0,h=t?Math.ceil(o.width/r.width)+1:0,d=(h-1)*r.width,u=(a-1)*r.height;null==this.horizontalPageBreaks&&0this.model.getChildCount(e)&&n--,this.model.add(e,t[g],n+g),this.autoSizeCellsOnAdd&&this.autoSizeCell(t[g],!0),(null==r||r)&&this.isExtendParentsOnAdd(t[g])&&this.isExtendParent(t[g])&&this.extendParent(t[g]),null!=o&&!o||this.constrainChild(t[g]),null!=i&&this.cellConnected(t[g],i,!0),null!=l&&this.cellConnected(t[g],l,!1));this.fireEvent(new mxEventObject(mxEvent.CELLS_ADDED,"cells",t,"parent",e,"index",n,"source",i,"target",l,"absolute",s))}finally{this.model.endUpdate()}}},mxGraph.prototype.autoSizeCell=function(t,e){if(e=null==e||e)for(var n=this.model.getChildCount(t),i=0;i"),o=(r=mxUtils.getSizeForString(t,i,s[mxConstants.STYLE_FONTFAMILY],e,s[mxConstants.STYLE_FONTSTYLE])).width+o,r=r.height+l,mxUtils.getValue(s,mxConstants.STYLE_HORIZONTAL,!0)||(s=r,r=o,o=s),this.gridEnabled&&(o=this.snap(o+this.gridSize/2),r=this.snap(r+this.gridSize/2)),new mxRectangle(0,0,o,r)):new mxRectangle(0,0,r=4*this.gridSize,r))),a},mxGraph.prototype.resizeCell=function(t,e,n){return this.resizeCells([t],[e],n)[0]},mxGraph.prototype.resizeCells=function(t,e,n){n=null!=n?n:this.isRecursiveResize(),this.model.beginUpdate();try{var i=this.cellsResized(t,e,n);this.fireEvent(new mxEventObject(mxEvent.RESIZE_CELLS,"cells",t,"bounds",e,"previous",i))}finally{this.model.endUpdate()}return t},mxGraph.prototype.cellsResized=function(t,e,n){n=null!=n&&n;var i=[];if(null!=t&&null!=e&&t.length==e.length){this.model.beginUpdate();try{for(var l=0;le.width&&(r=n.width-e.width,n.width-=r),h.x+h.width>e.x+e.width&&(r-=h.x+h.width-e.x-e.width-r),a=0,n.height>e.height&&(a=n.height-e.height,n.height-=a),h.y+h.height>e.y+e.height&&(a-=h.y+h.height-e.y-e.height-a),h.xo+e&&(this.view.translate.x-=(t.x+i-e-o)/a,h=!0),t.y+l>r+n&&(this.view.translate.y-=(t.y+l-n-r)/a,h=!0),t.x")):this.setCellWarning(s,null),n=n&&null==o}var r="";this.isCellCollapsed(t)&&!n&&(r+=(mxResources.get(this.containsValidationErrorsResource)||this.containsValidationErrorsResource)+"\n"),this.model.isEdge(t)?r+=this.getEdgeValidationError(t,this.model.getTerminal(t,!0),this.model.getTerminal(t,!1))||"":r+=this.getCellValidationError(t)||"";var a=this.validateCell(t,e);return null!=a&&(r+=a),null==this.model.getParent(t)&&this.view.validate(),0o.max||eo.max||n")),null==s&&null!=t.overlays&&t.overlays.visit(function(t,e){null!=s||n!=e.node&&n.parentNode!=e.node||(s=e.overlay.toString())}),null!=s||null!=(l=this.selectionCellsHandler.getHandler(t.cell))&&"function"==typeof l.getTooltipForNode&&(s=l.getTooltipForNode(n)),null==s&&(s=this.getTooltipForCell(t.cell))),s},mxGraph.prototype.getTooltipForCell=function(t){return null!=t&&null!=t.getTooltip?t.getTooltip():this.convertValueToString(t)},mxGraph.prototype.getLinkForCell=function(t){return null},mxGraph.prototype.getCursorForMouseEvent=function(t){return this.getCursorForCell(t.getCell())},mxGraph.prototype.getCursorForCell=function(t){return null},mxGraph.prototype.getStartSize=function(t,e){var n=new mxRectangle,t=this.getCurrentCellStyle(t,e),e=parseInt(mxUtils.getValue(t,mxConstants.STYLE_STARTSIZE,mxConstants.DEFAULT_STARTSIZE));return mxUtils.getValue(t,mxConstants.STYLE_HORIZONTAL,!0)?n.height=e:n.width=e,n},mxGraph.prototype.getSwimlaneDirection=function(t){var e=mxUtils.getValue(t,mxConstants.STYLE_DIRECTION,mxConstants.DIRECTION_EAST),n=1==mxUtils.getValue(t,mxConstants.STYLE_FLIPH,0),i=1==mxUtils.getValue(t,mxConstants.STYLE_FLIPV,0),t=mxUtils.getValue(t,mxConstants.STYLE_HORIZONTAL,!0)?0:3;e==mxConstants.DIRECTION_NORTH?t--:e==mxConstants.DIRECTION_WEST?t+=2:e==mxConstants.DIRECTION_SOUTH&&(t+=1);e=mxUtils.mod(t,2);return n&&1==e&&(t+=2),i&&0==e&&(t+=2),[mxConstants.DIRECTION_NORTH,mxConstants.DIRECTION_EAST,mxConstants.DIRECTION_SOUTH,mxConstants.DIRECTION_WEST][mxUtils.mod(t,4)]},mxGraph.prototype.getActualStartSize=function(t,e){var n=new mxRectangle;return this.isSwimlane(t,e)&&(t=this.getCurrentCellStyle(t,e),e=parseInt(mxUtils.getValue(t,mxConstants.STYLE_STARTSIZE,mxConstants.DEFAULT_STARTSIZE)),(t=this.getSwimlaneDirection(t))==mxConstants.DIRECTION_NORTH?n.y=e:t==mxConstants.DIRECTION_WEST?n.x=e:t==mxConstants.DIRECTION_SOUTH?n.height=e:n.width=e),n},mxGraph.prototype.getImage=function(t){return null!=t&&null!=t.style?t.style[mxConstants.STYLE_IMAGE]:null},mxGraph.prototype.isTransparentState=function(t){var e,n,i=!1;return null!=t&&(e=mxUtils.getValue(t.style,mxConstants.STYLE_STROKECOLOR,mxConstants.NONE),n=mxUtils.getValue(t.style,mxConstants.STYLE_FILLCOLOR,mxConstants.NONE),i=e==mxConstants.NONE&&n==mxConstants.NONE&&null==this.getImage(t)),i},mxGraph.prototype.getVerticalAlign=function(t){return null!=t&&null!=t.style?t.style[mxConstants.STYLE_VERTICAL_ALIGN]||mxConstants.ALIGN_MIDDLE:null},mxGraph.prototype.getIndicatorColor=function(t){return null!=t&&null!=t.style?t.style[mxConstants.STYLE_INDICATOR_COLOR]:null},mxGraph.prototype.getIndicatorGradientColor=function(t){return null!=t&&null!=t.style?t.style[mxConstants.STYLE_INDICATOR_GRADIENTCOLOR]:null},mxGraph.prototype.getIndicatorShape=function(t){return null!=t&&null!=t.style?t.style[mxConstants.STYLE_INDICATOR_SHAPE]:null},mxGraph.prototype.getIndicatorImage=function(t){return null!=t&&null!=t.style?t.style[mxConstants.STYLE_INDICATOR_IMAGE]:null},mxGraph.prototype.getBorder=function(){return this.border},mxGraph.prototype.setBorder=function(t){this.border=t},mxGraph.prototype.isSwimlane=function(t,e){return null!=t&&this.model.getParent(t)!=this.model.getRoot()&&!this.model.isEdge(t)&&this.getCurrentCellStyle(t,e)[mxConstants.STYLE_SHAPE]==mxConstants.SHAPE_SWIMLANE},mxGraph.prototype.isResizeContainer=function(){return this.resizeContainer},mxGraph.prototype.setResizeContainer=function(t){this.resizeContainer=t},mxGraph.prototype.isEnabled=function(){return this.enabled},mxGraph.prototype.setEnabled=function(t){this.enabled=t},mxGraph.prototype.isEscapeEnabled=function(){return this.escapeEnabled},mxGraph.prototype.setEscapeEnabled=function(t){this.escapeEnabled=t},mxGraph.prototype.isInvokesStopCellEditing=function(){return this.invokesStopCellEditing},mxGraph.prototype.setInvokesStopCellEditing=function(t){this.invokesStopCellEditing=t},mxGraph.prototype.isEnterStopsCellEditing=function(){return this.enterStopsCellEditing},mxGraph.prototype.setEnterStopsCellEditing=function(t){this.enterStopsCellEditing=t},mxGraph.prototype.isCellLocked=function(t){var e=this.model.getGeometry(t);return this.isCellsLocked()||null!=e&&this.model.isVertex(t)&&e.relative},mxGraph.prototype.isCellsLocked=function(){return this.cellsLocked},mxGraph.prototype.setCellsLocked=function(t){this.cellsLocked=t},mxGraph.prototype.getCloneableCells=function(t){return this.model.filterCells(t,mxUtils.bind(this,function(t){return this.isCellCloneable(t)}))},mxGraph.prototype.isCellCloneable=function(t){t=this.getCurrentCellStyle(t);return this.isCellsCloneable()&&0!=t[mxConstants.STYLE_CLONEABLE]},mxGraph.prototype.isCellsCloneable=function(){return this.cellsCloneable},mxGraph.prototype.setCellsCloneable=function(t){this.cellsCloneable=t},mxGraph.prototype.getExportableCells=function(t){return this.model.filterCells(t,mxUtils.bind(this,function(t){return this.canExportCell(t)}))},mxGraph.prototype.canExportCell=function(t){return this.exportEnabled},mxGraph.prototype.getImportableCells=function(t){return this.model.filterCells(t,mxUtils.bind(this,function(t){return this.canImportCell(t)}))},mxGraph.prototype.canImportCell=function(t){return this.importEnabled},mxGraph.prototype.isCellSelectable=function(t){return this.isCellsSelectable()},mxGraph.prototype.isCellsSelectable=function(){return this.cellsSelectable},mxGraph.prototype.setCellsSelectable=function(t){this.cellsSelectable=t},mxGraph.prototype.getDeletableCells=function(t){return this.model.filterCells(t,mxUtils.bind(this,function(t){return this.isCellDeletable(t)}))},mxGraph.prototype.isCellDeletable=function(t){t=this.getCurrentCellStyle(t);return this.isCellsDeletable()&&0!=t[mxConstants.STYLE_DELETABLE]},mxGraph.prototype.isCellsDeletable=function(){return this.cellsDeletable},mxGraph.prototype.setCellsDeletable=function(t){this.cellsDeletable=t},mxGraph.prototype.isLabelMovable=function(t){return!this.isCellLocked(t)&&(this.model.isEdge(t)&&this.edgeLabelsMovable||this.model.isVertex(t)&&this.vertexLabelsMovable)},mxGraph.prototype.isCellRotatable=function(t){return 0!=this.getCurrentCellStyle(t)[mxConstants.STYLE_ROTATABLE]},mxGraph.prototype.getMovableCells=function(t){return this.model.filterCells(t,mxUtils.bind(this,function(t){return this.isCellMovable(t)}))},mxGraph.prototype.isCellMovable=function(t){var e=this.getCurrentCellStyle(t);return this.isCellsMovable()&&!this.isCellLocked(t)&&0!=e[mxConstants.STYLE_MOVABLE]},mxGraph.prototype.isCellsMovable=function(){return this.cellsMovable},mxGraph.prototype.setCellsMovable=function(t){this.cellsMovable=t},mxGraph.prototype.isGridEnabled=function(){return this.gridEnabled},mxGraph.prototype.setGridEnabled=function(t){this.gridEnabled=t},mxGraph.prototype.isPortsEnabled=function(){return this.portsEnabled},mxGraph.prototype.setPortsEnabled=function(t){this.portsEnabled=t},mxGraph.prototype.getGridSize=function(){return this.gridSize},mxGraph.prototype.setGridSize=function(t){this.gridSize=t},mxGraph.prototype.getTolerance=function(){return this.tolerance},mxGraph.prototype.setTolerance=function(t){this.tolerance=t},mxGraph.prototype.isVertexLabelsMovable=function(){return this.vertexLabelsMovable},mxGraph.prototype.setVertexLabelsMovable=function(t){this.vertexLabelsMovable=t},mxGraph.prototype.isEdgeLabelsMovable=function(){return this.edgeLabelsMovable},mxGraph.prototype.setEdgeLabelsMovable=function(t){this.edgeLabelsMovable=t},mxGraph.prototype.isSwimlaneNesting=function(){return this.swimlaneNesting},mxGraph.prototype.setSwimlaneNesting=function(t){this.swimlaneNesting=t},mxGraph.prototype.isSwimlaneSelectionEnabled=function(){return this.swimlaneSelectionEnabled},mxGraph.prototype.setSwimlaneSelectionEnabled=function(t){this.swimlaneSelectionEnabled=t},mxGraph.prototype.isMultigraph=function(){return this.multigraph},mxGraph.prototype.setMultigraph=function(t){this.multigraph=t},mxGraph.prototype.isAllowLoops=function(){return this.allowLoops},mxGraph.prototype.setAllowDanglingEdges=function(t){this.allowDanglingEdges=t},mxGraph.prototype.isAllowDanglingEdges=function(){return this.allowDanglingEdges},mxGraph.prototype.setConnectableEdges=function(t){this.connectableEdges=t},mxGraph.prototype.isConnectableEdges=function(){return this.connectableEdges},mxGraph.prototype.setCloneInvalidEdges=function(t){this.cloneInvalidEdges=t},mxGraph.prototype.isCloneInvalidEdges=function(){return this.cloneInvalidEdges},mxGraph.prototype.setAllowLoops=function(t){this.allowLoops=t},mxGraph.prototype.isDisconnectOnMove=function(){return this.disconnectOnMove},mxGraph.prototype.setDisconnectOnMove=function(t){this.disconnectOnMove=t},mxGraph.prototype.isDropEnabled=function(){return this.dropEnabled},mxGraph.prototype.setDropEnabled=function(t){this.dropEnabled=t},mxGraph.prototype.isSplitEnabled=function(){return this.splitEnabled},mxGraph.prototype.setSplitEnabled=function(t){this.splitEnabled=t},mxGraph.prototype.isCellResizable=function(t){var e=this.getCurrentCellStyle(t);return this.isCellsResizable()&&!this.isCellLocked(t)&&"0"!=mxUtils.getValue(e,mxConstants.STYLE_RESIZABLE,"1")},mxGraph.prototype.isCellsResizable=function(){return this.cellsResizable},mxGraph.prototype.setCellsResizable=function(t){this.cellsResizable=t},mxGraph.prototype.isTerminalPointMovable=function(t,e){return!0},mxGraph.prototype.isCellBendable=function(t){var e=this.getCurrentCellStyle(t);return this.isCellsBendable()&&!this.isCellLocked(t)&&0!=e[mxConstants.STYLE_BENDABLE]},mxGraph.prototype.isCellsBendable=function(){return this.cellsBendable},mxGraph.prototype.setCellsBendable=function(t){this.cellsBendable=t},mxGraph.prototype.isCellEditable=function(t){var e=this.getCurrentCellStyle(t);return this.isCellsEditable()&&!this.isCellLocked(t)&&0!=e[mxConstants.STYLE_EDITABLE]},mxGraph.prototype.isCellsEditable=function(){return this.cellsEditable},mxGraph.prototype.setCellsEditable=function(t){this.cellsEditable=t},mxGraph.prototype.isCellDisconnectable=function(t,e,n){return this.isCellsDisconnectable()&&!this.isCellLocked(t)},mxGraph.prototype.isCellsDisconnectable=function(){return this.cellsDisconnectable},mxGraph.prototype.setCellsDisconnectable=function(t){this.cellsDisconnectable=t},mxGraph.prototype.isValidSource=function(t){return null==t&&this.allowDanglingEdges||null!=t&&(!this.model.isEdge(t)||this.connectableEdges)&&this.isCellConnectable(t)},mxGraph.prototype.isValidTarget=function(t){return this.isValidSource(t)},mxGraph.prototype.isValidConnection=function(t,e){return this.isValidSource(t)&&this.isValidTarget(e)},mxGraph.prototype.setConnectable=function(t){this.connectionHandler.setEnabled(t)},mxGraph.prototype.isConnectable=function(){return this.connectionHandler.isEnabled()},mxGraph.prototype.setTooltips=function(t){this.tooltipHandler.setEnabled(t)},mxGraph.prototype.setPanning=function(t){this.panningHandler.panningEnabled=t},mxGraph.prototype.isEditing=function(t){if(null==this.cellEditor)return!1;var e=this.cellEditor.getEditingCell();return null==t?null!=e:t==e},mxGraph.prototype.isAutoSizeCell=function(t){t=this.getCurrentCellStyle(t);return this.isAutoSizeCells()||1==t[mxConstants.STYLE_AUTOSIZE]},mxGraph.prototype.isAutoSizeCells=function(){return this.autoSizeCells},mxGraph.prototype.setAutoSizeCells=function(t){this.autoSizeCells=t},mxGraph.prototype.isExtendParent=function(t){return!this.getModel().isEdge(t)&&this.isExtendParents()},mxGraph.prototype.isExtendParents=function(){return this.extendParents},mxGraph.prototype.setExtendParents=function(t){this.extendParents=t},mxGraph.prototype.isExtendParentsOnAdd=function(t){return this.extendParentsOnAdd},mxGraph.prototype.setExtendParentsOnAdd=function(t){this.extendParentsOnAdd=t},mxGraph.prototype.isExtendParentsOnMove=function(){return this.extendParentsOnMove},mxGraph.prototype.setExtendParentsOnMove=function(t){this.extendParentsOnMove=t},mxGraph.prototype.isRecursiveResize=function(t){return this.recursiveResize},mxGraph.prototype.setRecursiveResize=function(t){this.recursiveResize=t},mxGraph.prototype.isConstrainChild=function(t){return this.isConstrainChildren()&&!this.getModel().isEdge(this.getModel().getParent(t))},mxGraph.prototype.isConstrainChildren=function(){return this.constrainChildren},mxGraph.prototype.setConstrainChildren=function(t){this.constrainChildren=t},mxGraph.prototype.isConstrainRelativeChildren=function(){return this.constrainRelativeChildren},mxGraph.prototype.setConstrainRelativeChildren=function(t){this.constrainRelativeChildren=t},mxGraph.prototype.isAllowNegativeCoordinates=function(){return this.allowNegativeCoordinates},mxGraph.prototype.setAllowNegativeCoordinates=function(t){this.allowNegativeCoordinates=t},mxGraph.prototype.getOverlap=function(t){return this.isAllowOverlapParent(t)?this.defaultOverlap:0},mxGraph.prototype.isAllowOverlapParent=function(t){return!1},mxGraph.prototype.getFoldableCells=function(t,e){return this.model.filterCells(t,mxUtils.bind(this,function(t){return this.isCellFoldable(t,e)}))},mxGraph.prototype.isCellFoldable=function(t,e){var n=this.getCurrentCellStyle(t);return 0l.width*t)return!0;if(0l.height*t)return!0}return!1},mxGraph.prototype.getChildVertices=function(t){return this.getChildCells(t,!0,!1)},mxGraph.prototype.getChildEdges=function(t){return this.getChildCells(t,!1,!0)},mxGraph.prototype.getChildCells=function(t,e,n){t=null!=t?t:this.getDefaultParent(),e=null!=e&&e,n=null!=n&&n;for(var i=this.model.getChildCells(t,e,n),l=[],s=0;s=t&&c.y+c.height<=u&&c.y>=e&&c.x+c.width<=d)&&s.push(g),c&&!a||this.getCells(t,e,n,i,g,s,o,r,a))}}return s},mxGraph.prototype.getCellsBeyond=function(t,e,n,i,l){var s=[];if((i||l)&&(null==n&&(n=this.getDefaultParent()),null!=n))for(var o=this.model.getChildCount(n),r=0;r=t)&&(!l||h.y>=e)&&s.push(a)}return s},mxGraph.prototype.findTreeRoots=function(t,e,n){e=null!=e&&e,n=null!=n&&n;var i=[];if(null!=t){for(var l=this.getModel(),s=l.getChildCount(t),o=null,r=0,a=0;a=this.max)||!this.source&&(0==this.max||s>=this.max))&&(o+=this.countError+"\n"),null!=this.validNeighbors&&null!=this.typeError&&0=this.cellCount&&!this.livePreviewActive&&this.allowLivePreview?this.cloning&&this.livePreviewActive||(this.livePreviewActive=!0,this.livePreviewUsed=!0):this.livePreviewUsed||null!=this.shape||(this.shape=this.createPreviewShape(this.bounds))},mxGraphHandler.prototype.mouseMove=function(t,e){var n,i,l,s,o,r,a,h,d=this.graph;e.isConsumed()||!d.isMouseDown||null==this.cell||null==this.first||null==this.bounds||this.suspended?!this.isMoveEnabled()&&!this.isCloneEnabled()||!this.updateCursor||e.isConsumed()||null==e.getState()&&null==e.sourceState||d.isMouseDown||(null==(r=d.getCursorForMouseEvent(e))&&d.isEnabled()&&d.isCellMovable(e.getCell())&&(r=d.getModel().isEdge(e.getCell())?mxConstants.CURSOR_MOVABLE_EDGE:mxConstants.CURSOR_MOVABLE_VERTEX),null!=r&&null!=e.sourceState&&e.sourceState.setCursor(r)):mxEvent.isMultiTouchEvent(e.getEvent())?this.reset():(n=this.getDelta(e),h=d.tolerance,(null!=this.shape||this.livePreviewActive||Math.abs(n.x)>h||Math.abs(n.y)>h)&&(null==this.highlight&&(this.highlight=new mxCellHighlight(this.graph,mxConstants.DROP_TARGET_COLOR,3)),i=d.isCloneEvent(e.getEvent())&&d.isCellsCloneable()&&this.isCloneEnabled(),l=d.isGridEnabledEvent(e.getEvent()),a=e.getCell(),s=!0,o=null,this.cloning=i,d.isDropEnabled()&&this.highlightEnabled&&(o=d.getDropTarget(this.cells,e.getEvent(),a,i)),r=!1,null!=(h=d.getView().getState(o))&&(i||this.isValidDropTarget(o,e))?(this.target!=o&&(this.target=o,this.setHighlightColor(mxConstants.DROP_TARGET_COLOR)),r=!0):(this.target=null,this.connectOnDrop&&null!=a&&1==this.cells.length&&d.getModel().isVertex(a)&&d.isCellConnectable(a)&&null!=(h=d.getView().getState(a))&&(a=null==d.getEdgeValidationError(null,this.cell,a)?mxConstants.VALID_COLOR:mxConstants.INVALID_CONNECT_TARGET_COLOR,this.setHighlightColor(a),r=!0)),null!=h&&r?this.highlight.highlight(h):this.highlight.hide(),null!=this.guide&&this.useGuidesForEvent(e)?(n=this.guide.move(this.bounds,n,l,i),s=!1):n=this.graph.snapDelta(n,this.bounds,!l,!1,!1),null!=this.guide&&s&&this.guide.hide(),d.isConstrainedEvent(e.getEvent())&&(Math.abs(n.x)>Math.abs(n.y)?n.y=0:n.x=0),this.checkPreview(),this.currentDx==n.x&&this.currentDy==n.y||(this.currentDx=n.x,this.currentDy=n.y,this.updatePreview())),this.updateHint(e),this.consumeMouseEvent(mxEvent.MOUSE_MOVE,e),mxEvent.consume(e.getEvent()))},mxGraphHandler.prototype.updatePreview=function(t){this.livePreviewUsed&&!t?null!=this.cells&&(this.setHandlesVisibleForCells(this.graph.selectionCellsHandler.getHandledSelectionCells(),!1),this.updateLivePreview(this.currentDx,this.currentDy)):this.updatePreviewShape()},mxGraphHandler.prototype.updatePreviewShape=function(){null!=this.shape&&null!=this.pBounds&&(this.shape.bounds=new mxRectangle(Math.round(this.pBounds.x+this.currentDx),Math.round(this.pBounds.y+this.currentDy),this.pBounds.width,this.pBounds.height),this.shape.redraw())},mxGraphHandler.prototype.updateLivePreview=function(i,l){if(!this.suspended){var s=[];if(null!=this.allCells&&this.allCells.visit(mxUtils.bind(this,function(t,e){var n=this.graph.view.getState(e.cell);n!=e&&(e.destroy(),null!=n?this.allCells.put(e.cell,n):this.allCells.remove(e.cell),e=n),null!=e&&(n=e.clone(),s.push([e,n]),null!=e.shape&&(null==e.shape.originalPointerEvents&&(e.shape.originalPointerEvents=e.shape.pointerEvents),e.shape.pointerEvents=!1,null!=e.text&&(null==e.text.originalPointerEvents&&(e.text.originalPointerEvents=e.text.pointerEvents),e.text.pointerEvents=!1)),this.graph.model.isVertex(e.cell)&&(e.x+=i,e.y+=l,this.cloning?null!=e.text&&(e.text.updateBoundingBox(),null!=e.text.boundingBox&&(e.text.boundingBox.x+=i,e.text.boundingBox.y+=l),null!=e.text.unrotatedBoundingBox&&(e.text.unrotatedBoundingBox.x+=i,e.text.unrotatedBoundingBox.y+=l)):(e.view.graph.cellRenderer.redraw(e,!0),e.view.invalidate(e.cell),e.invalid=!1,null!=e.control&&null!=e.control.node&&(e.control.node.style.visibility="hidden"))))})),0==s.length)this.reset();else{for(var t=this.graph.view.scale,e=0;ethis.graph.tolerance||Math.abs(this.dy)>this.graph.tolerance,!n&&this.active&&this.fireEvent(new mxEventObject(mxEvent.PAN_START,"event",e))),(this.active||this.panningTrigger)&&e.consume()},mxPanningHandler.prototype.mouseUp=function(t,e){var n,i;this.active&&(null!=this.dx&&null!=this.dy&&(this.graph.useScrollbarsForPanning&&mxUtils.hasScrollbars(this.graph.container)||(n=this.graph.getView().scale,i=this.graph.getView().translate,this.graph.panGraph(0,0),this.panGraph(i.x+this.dx/n,i.y+this.dy/n)),e.consume()),this.fireEvent(new mxEventObject(mxEvent.PAN_END,"event",e))),this.reset()},mxPanningHandler.prototype.zoomGraph=function(t){var e=Math.round(this.initialScale*t.scale*100)/100;null!=this.minScale&&(e=Math.max(this.minScale,e)),null!=this.maxScale&&(e=Math.min(this.maxScale,e)),this.graph.view.scale!=e&&(this.graph.zoomTo(e),mxEvent.consume(t))},mxPanningHandler.prototype.reset=function(){this.panningTrigger=!1,this.mouseDownEvent=null,this.active=!1,this.dx=null,this.dy=null},mxPanningHandler.prototype.panGraph=function(t,e){this.graph.getView().setTranslate(t,e)},mxPanningHandler.prototype.destroy=function(){this.graph.removeMouseListener(this),this.graph.removeListener(this.forcePanningHandler),this.graph.removeListener(this.gestureHandler),mxEvent.removeListener(document,"mouseup",this.mouseUpListener)},mxPopupMenuHandler.prototype=new mxPopupMenu,mxPopupMenuHandler.prototype.constructor=mxPopupMenuHandler,mxPopupMenuHandler.prototype.graph=null,mxPopupMenuHandler.prototype.selectOnPopup=!0,mxPopupMenuHandler.prototype.clearSelectionOnBackground=!0,mxPopupMenuHandler.prototype.triggerX=null,mxPopupMenuHandler.prototype.triggerY=null,mxPopupMenuHandler.prototype.screenX=null,mxPopupMenuHandler.prototype.screenY=null,mxPopupMenuHandler.prototype.init=function(){mxPopupMenu.prototype.init.apply(this),mxEvent.addGestureListeners(this.div,mxUtils.bind(this,function(t){this.graph.tooltipHandler.hide()}))},mxPopupMenuHandler.prototype.isSelectOnPopup=function(t){return this.selectOnPopup},mxPopupMenuHandler.prototype.mouseDown=function(t,e){this.isEnabled()&&!mxEvent.isMultiTouchEvent(e.getEvent())&&(this.hideMenu(),this.triggerX=e.getGraphX(),this.triggerY=e.getGraphY(),this.screenX=mxEvent.getMainEvent(e.getEvent()).screenX,this.screenY=mxEvent.getMainEvent(e.getEvent()).screenY,this.popupTrigger=this.isPopupTrigger(e),this.inTolerance=!0)},mxPopupMenuHandler.prototype.mouseMove=function(t,e){this.inTolerance&&null!=this.screenX&&null!=this.screenY&&(Math.abs(mxEvent.getMainEvent(e.getEvent()).screenX-this.screenX)>this.graph.tolerance||Math.abs(mxEvent.getMainEvent(e.getEvent()).screenY-this.screenY)>this.graph.tolerance)&&(this.inTolerance=!1)},mxPopupMenuHandler.prototype.mouseUp=function(t,e){var n,i;this.popupTrigger&&this.inTolerance&&null!=this.triggerX&&null!=this.triggerY&&(n=this.getCellForPopupEvent(e),this.graph.isEnabled()&&this.isSelectOnPopup(e)&&null!=n&&!this.graph.isCellSelected(n)?this.graph.setSelectionCell(n):this.clearSelectionOnBackground&&null==n&&this.graph.clearSelection(),this.graph.tooltipHandler.hide(),i=mxUtils.getScrollOrigin(),this.popup(e.getX()+i.x+1,e.getY()+i.y+1,n,e.getEvent()),e.consume()),this.popupTrigger=!1,this.inTolerance=!1},mxPopupMenuHandler.prototype.getCellForPopupEvent=function(t){return t.getCell()},mxPopupMenuHandler.prototype.destroy=function(){this.graph.removeMouseListener(this),this.graph.removeListener(this.gestureHandler),mxPopupMenu.prototype.destroy.apply(this)},mxUtils.extend(mxCellMarker,mxEventSource),mxCellMarker.prototype.graph=null,mxCellMarker.prototype.enabled=!0,mxCellMarker.prototype.hotspot=mxConstants.DEFAULT_HOTSPOT,mxCellMarker.prototype.hotspotEnabled=!1,mxCellMarker.prototype.validColor=null,mxCellMarker.prototype.invalidColor=null,mxCellMarker.prototype.currentColor=null,mxCellMarker.prototype.validState=null,mxCellMarker.prototype.markedState=null,mxCellMarker.prototype.setEnabled=function(t){this.enabled=t},mxCellMarker.prototype.isEnabled=function(){return this.enabled},mxCellMarker.prototype.setHotspot=function(t){this.hotspot=t},mxCellMarker.prototype.getHotspot=function(){return this.hotspot},mxCellMarker.prototype.setHotspotEnabled=function(t){this.hotspotEnabled=t},mxCellMarker.prototype.isHotspotEnabled=function(){return this.hotspotEnabled},mxCellMarker.prototype.hasValidState=function(){return null!=this.validState},mxCellMarker.prototype.getValidState=function(){return this.validState},mxCellMarker.prototype.getMarkedState=function(){return this.markedState},mxCellMarker.prototype.reset=function(){(this.validState=null)!=this.markedState&&(this.markedState=null,this.unmark())},mxCellMarker.prototype.process=function(t){var e=null;return this.isEnabled()&&(e=this.getState(t),this.setCurrentState(e,t)),e},mxCellMarker.prototype.setCurrentState=function(t,e,n){var i=null!=t&&this.isValidState(t);n=null!=n?n:this.getMarkerColor(e.getEvent(),t,i),this.validState=i?t:null,t==this.markedState&&n==this.currentColor||(this.currentColor=n,null!=t&&null!=this.currentColor?(this.markedState=t,this.mark()):null!=this.markedState&&(this.markedState=null,this.unmark()))},mxCellMarker.prototype.markCell=function(t,e){t=this.graph.getView().getState(t);null!=t&&(this.currentColor=null!=e?e:this.validColor,this.markedState=t,this.mark())},mxCellMarker.prototype.mark=function(){this.highlight.setHighlightColor(this.currentColor),this.highlight.highlight(this.markedState),this.fireEvent(new mxEventObject(mxEvent.MARK,"state",this.markedState))},mxCellMarker.prototype.unmark=function(){this.mark()},mxCellMarker.prototype.isValidState=function(t){return!0},mxCellMarker.prototype.getMarkerColor=function(t,e,n){return n?this.validColor:this.invalidColor},mxCellMarker.prototype.getState=function(t){var e=this.graph.getView(),n=this.getCell(t),n=this.getStateToMark(e.getState(n));return null!=n&&this.intersects(n,t)?n:null},mxCellMarker.prototype.getCell=function(t){return t.getCell()},mxCellMarker.prototype.getStateToMark=function(t){return t},mxCellMarker.prototype.intersects=function(t,e){return!this.hotspotEnabled||mxUtils.intersectsHotspot(t,e.getGraphX(),e.getGraphY(),this.hotspot,mxConstants.MIN_HOTSPOT_SIZE,mxConstants.MAX_HOTSPOT_SIZE)},mxCellMarker.prototype.destroy=function(){this.graph.getView().removeListener(this.resetHandler),this.graph.getModel().removeListener(this.resetHandler),this.highlight.destroy()},mxUtils.extend(mxSelectionCellsHandler,mxEventSource),mxSelectionCellsHandler.prototype.graph=null,mxSelectionCellsHandler.prototype.enabled=!0,mxSelectionCellsHandler.prototype.refreshHandler=null,mxSelectionCellsHandler.prototype.maxHandlers=100,mxSelectionCellsHandler.prototype.handlers=null,mxSelectionCellsHandler.prototype.isEnabled=function(){return this.enabled},mxSelectionCellsHandler.prototype.setEnabled=function(t){this.enabled=t},mxSelectionCellsHandler.prototype.getHandler=function(t){return this.handlers.get(t)},mxSelectionCellsHandler.prototype.isHandled=function(t){return null!=this.getHandler(t)},mxSelectionCellsHandler.prototype.reset=function(){this.handlers.visit(function(t,e){e.reset.apply(e)})},mxSelectionCellsHandler.prototype.getHandledSelectionCells=function(){return this.graph.getSelectionCells()},mxSelectionCellsHandler.prototype.refresh=function(){var t=this.handlers;this.handlers=new mxDictionary;for(var e=mxUtils.sortCells(this.getHandledSelectionCells(),!1),n=0;nthis.graph.tolerance||Math.abs(e.getGraphY()-this.first.y)>this.graph.tolerance)&&this.updateCurrentState(e,s),null!=this.first){var o=null,r=s;null!=this.constraintHandler.currentConstraint&&null!=this.constraintHandler.currentFocus&&null!=this.constraintHandler.currentPoint?(o=this.constraintHandler.currentConstraint,r=this.constraintHandler.currentPoint.clone()):null!=this.previous&&!this.graph.isIgnoreTerminalEvent(e.getEvent())&&mxEvent.isShiftDown(e.getEvent())&&(Math.abs(this.previous.getCenterX()-s.x)this.graph.tolerance||u>this.graph.tolerance)&&(this.shape=this.createShape(),null!=this.edgeState&&this.shape.apply(this.edgeState),this.updateCurrentState(e,s))),null!=this.shape&&(null!=this.edgeState?this.shape.points=this.edgeState.absolutePoints:(a=[a],null!=this.waypoints&&(a=a.concat(this.waypoints)),a.push(r),this.shape.points=a),this.drawPreview()),null!=this.cursor&&(this.graph.container.style.cursor=this.cursor),mxEvent.consume(e.getEvent()),e.consume()}else this.isEnabled()&&this.graph.isEnabled()?this.previous!=this.currentState&&null==this.edgeState?(this.destroyIcons(),null!=this.currentState&&null==this.error&&null==this.constraintHandler.currentConstraint&&(this.icons=this.createIcons(this.currentState),null==this.icons&&(this.currentState.setCursor(mxConstants.CURSOR_CONNECT),e.consume())),this.previous=this.currentState):this.previous!=this.currentState||null==this.currentState||null!=this.icons||this.graph.isMouseDown||e.consume():this.constraintHandler.reset();if(!this.graph.isMouseDown&&null!=this.currentState&&null!=this.icons){for(var p=!1,m=e.getSource(),c=0;cthis.graph.tolerance||i>this.graph.tolerance))&&(null==this.waypoints&&(this.waypoints=[]),i=this.graph.view.scale,e=new mxPoint(this.graph.snap(t.getGraphX()/i)*i,this.graph.snap(t.getGraphY()/i)*i),this.waypoints.push(e))},mxConnectionHandler.prototype.checkConstraints=function(t,e){return null==t||null==e||null==t.point||null==e.point||!t.point.equals(e.point)||t.dx!=e.dx||t.dy!=e.dy||t.perimeter!=e.perimeter},mxConnectionHandler.prototype.mouseUp=function(t,e){if(!e.isConsumed()&&this.isConnecting()){if(this.waypointsEnabled&&!this.isStopEvent(e))return this.addWaypointForEvent(e),void e.consume();var n=this.sourceConstraint,i=this.constraintHandler.currentConstraint,l=null!=this.previous?this.previous.cell:null,s=null;null!=this.constraintHandler.currentConstraint&&null!=this.constraintHandler.currentFocus&&(s=this.constraintHandler.currentFocus.cell),null==s&&null!=this.currentState&&(s=this.currentState.cell),null!=this.error||null!=l&&null!=s&&l==s&&!this.checkConstraints(n,i)?(null!=this.previous&&null!=this.marker.validState&&this.previous.cell==this.marker.validState.cell&&this.graph.selectCellForEvent(this.marker.source,e.getEvent()),null!=this.error&&0o||Math.abs(s)>o)&&(null==this.div&&(this.div=this.createShape()),mxUtils.clearSelection(),this.update(n,i),e.consume()))},mxRubberband.prototype.createShape=function(){null==this.sharedDiv&&(this.sharedDiv=document.createElement("div"),this.sharedDiv.className="mxRubberband",mxUtils.setOpacity(this.sharedDiv,this.defaultOpacity)),this.graph.container.appendChild(this.sharedDiv);var t=this.sharedDiv;return mxClient.IS_SVG&&(!mxClient.IS_IE||10<=document.documentMode)&&this.fadeOut&&(this.sharedDiv=null),t},mxRubberband.prototype.isActive=function(t,e){return null!=this.div&&"none"!=this.div.style.display},mxRubberband.prototype.mouseUp=function(t,e){var n=this.isActive();this.reset(),n&&(this.execute(e.getEvent()),e.consume())},mxRubberband.prototype.execute=function(t){var e=new mxRectangle(this.x,this.y,this.width,this.height);this.graph.selectRegion(e,t)},mxRubberband.prototype.reset=function(){var t;null!=this.div&&(mxClient.IS_SVG&&(!mxClient.IS_IE||10<=document.documentMode)&&this.fadeOut?(t=this.div,mxUtils.setPrefixedStyle(t.style,"transition","all 0.2s linear"),t.style.pointerEvents="none",t.style.opacity=0,window.setTimeout(function(){t.parentNode.removeChild(t)},200)):this.div.parentNode.removeChild(this.div)),mxEvent.removeGestureListeners(document,null,this.dragHandler,this.dropHandler),this.dragHandler=null,this.dropHandler=null,this.currentX=0,this.currentY=0,this.first=null,this.div=null},mxRubberband.prototype.update=function(t,e){this.currentX=t,this.currentY=e,this.repaint()},mxRubberband.prototype.repaint=function(){var t,e;null!=this.div&&(t=this.currentX-this.graph.panDx,e=this.currentY-this.graph.panDy,this.x=Math.min(this.first.x,t),this.y=Math.min(this.first.y,e),this.width=Math.max(this.first.x,t)-this.x,this.height=Math.max(this.first.y,e)-this.y,t=mxClient.IS_VML?this.graph.panDx:0,e=mxClient.IS_VML?this.graph.panDy:0,this.div.style.left=this.x+t+"px",this.div.style.top=this.y+e+"px",this.div.style.width=Math.max(1,this.width)+"px",this.div.style.height=Math.max(1,this.height)+"px")},mxRubberband.prototype.destroy=function(){this.destroyed||(this.destroyed=!0,this.graph.removeMouseListener(this),this.graph.removeListener(this.forceRubberbandHandler),this.graph.removeListener(this.panHandler),this.reset(),null!=this.sharedDiv&&(this.sharedDiv=null))},mxHandle.prototype.cursor="default",mxHandle.prototype.image=null,mxHandle.prototype.ignoreGrid=!1,mxHandle.prototype.getPosition=function(t){},mxHandle.prototype.setPosition=function(t,e,n){},mxHandle.prototype.execute=function(t){},mxHandle.prototype.copyStyle=function(t){this.graph.setCellStyles(t,this.state.style[t],[this.state.cell])},mxHandle.prototype.processEvent=function(t){var e=this.graph.view.scale,n=this.graph.view.translate,i=new mxPoint(t.getGraphX()/e-n.x,t.getGraphY()/e-n.y);null!=this.shape&&null!=this.shape.bounds&&(i.x-=this.shape.bounds.width/e/4,i.y-=this.shape.bounds.height/e/4);n=-mxUtils.toRadians(this.getRotation()),e=-mxUtils.toRadians(this.getTotalRotation())-n,i=this.flipPoint(this.rotatePoint(this.snapPoint(this.rotatePoint(i,n),this.ignoreGrid||!this.graph.isGridEnabledEvent(t.getEvent())),e));this.setPosition(this.state.getPaintBounds(),i,t),this.redraw()},mxHandle.prototype.positionChanged=function(){null!=this.state.text&&this.state.text.apply(this.state),null!=this.state.shape&&this.state.shape.apply(this.state),this.graph.cellRenderer.redraw(this.state,!0)},mxHandle.prototype.getRotation=function(){return null!=this.state.shape?this.state.shape.getRotation():0},mxHandle.prototype.getTotalRotation=function(){return null!=this.state.shape?this.state.shape.getShapeRotation():0},mxHandle.prototype.init=function(){var t=this.isHtmlRequired();null!=this.image?(this.shape=new mxImageShape(new mxRectangle(0,0,this.image.width,this.image.height),this.image.src),this.shape.preserveImageAspect=!1):null==this.shape&&(this.shape=this.createShape(t)),this.initShape(t)},mxHandle.prototype.createShape=function(t){return new mxRectangleShape(new mxRectangle(0,0,mxConstants.HANDLE_SIZE,mxConstants.HANDLE_SIZE),mxConstants.HANDLE_FILLCOLOR,mxConstants.HANDLE_STROKECOLOR)},mxHandle.prototype.initShape=function(t){t&&this.shape.isHtmlAllowed()?(this.shape.dialect=mxConstants.DIALECT_STRICTHTML,this.shape.init(this.graph.container)):(this.shape.dialect=this.graph.dialect!=mxConstants.DIALECT_SVG?mxConstants.DIALECT_MIXEDHTML:mxConstants.DIALECT_SVG,null!=this.cursor&&this.shape.init(this.graph.getView().getOverlayPane())),mxEvent.redirectMouseEvents(this.shape.node,this.graph,this.state),this.shape.node.style.cursor=this.cursor},mxHandle.prototype.redraw=function(){var t,e,n;null==this.shape||null==this.state.shape||null!=(t=this.getPosition(this.state.getPaintBounds()))&&(n=mxUtils.toRadians(this.getTotalRotation()),t=this.rotatePoint(this.flipPoint(t),n),e=this.graph.view.scale,n=this.graph.view.translate,this.shape.bounds.x=Math.floor((t.x+n.x)*e-this.shape.bounds.width/2),this.shape.bounds.y=Math.floor((t.y+n.y)*e-this.shape.bounds.height/2),this.shape.redraw())},mxHandle.prototype.isHtmlRequired=function(){return null!=this.state.text&&this.state.text.node.parentNode==this.graph.container},mxHandle.prototype.rotatePoint=function(t,e){var n=this.state.getCellBounds(),i=new mxPoint(n.getCenterX(),n.getCenterY()),n=Math.cos(e),e=Math.sin(e);return mxUtils.getRotatedPoint(t,n,e,i)},mxHandle.prototype.flipPoint=function(t){var e;return null!=this.state.shape&&(e=this.state.getCellBounds(),this.state.shape.flipH&&(t.x=2*e.x+e.width-t.x),this.state.shape.flipV&&(t.y=2*e.y+e.height-t.y)),t},mxHandle.prototype.snapPoint=function(t,e){return e||(t.x=this.graph.snap(t.x),t.y=this.graph.snap(t.y)),t},mxHandle.prototype.setVisible=function(t){null!=this.shape&&null!=this.shape.node&&(this.shape.node.style.display=t?"":"none")},mxHandle.prototype.reset=function(){this.setVisible(!0),this.state.style=this.graph.getCellStyle(this.state.cell),this.positionChanged()},mxHandle.prototype.destroy=function(){null!=this.shape&&(this.shape.destroy(),this.shape=null)},mxVertexHandler.prototype.graph=null,mxVertexHandler.prototype.state=null,mxVertexHandler.prototype.singleSizer=!1,mxVertexHandler.prototype.index=null,mxVertexHandler.prototype.allowHandleBoundsCheck=!0,mxVertexHandler.prototype.handleImage=null,mxVertexHandler.prototype.handlesVisible=!0,mxVertexHandler.prototype.tolerance=0,mxVertexHandler.prototype.rotationEnabled=!1,mxVertexHandler.prototype.parentHighlightEnabled=!1,mxVertexHandler.prototype.rotationRaster=!0,mxVertexHandler.prototype.rotationCursor="crosshair",mxVertexHandler.prototype.livePreview=!1,mxVertexHandler.prototype.movePreviewToFront=!1,mxVertexHandler.prototype.manageSizers=!1,mxVertexHandler.prototype.constrainGroupByChildren=!1,mxVertexHandler.prototype.rotationHandleVSpacing=-16,mxVertexHandler.prototype.horizontalOffset=0,mxVertexHandler.prototype.verticalOffset=0,mxVertexHandler.prototype.init=function(){var t,e;this.graph=this.state.view.graph,this.selectionBounds=this.getSelectionBounds(this.state),this.bounds=new mxRectangle(this.selectionBounds.x,this.selectionBounds.y,this.selectionBounds.width,this.selectionBounds.height),this.selectionBorder=this.createSelectionShape(this.bounds),this.selectionBorder.dialect=this.graph.dialect!=mxConstants.DIALECT_SVG?mxConstants.DIALECT_VML:mxConstants.DIALECT_SVG,this.selectionBorder.pointerEvents=!1,this.selectionBorder.rotation=Number(this.state.style[mxConstants.STYLE_ROTATION]||"0"),this.selectionBorder.init(this.graph.getView().getOverlayPane()),mxEvent.redirectMouseEvents(this.selectionBorder.node,this.graph,this.state),this.graph.isCellMovable(this.state.cell)&&this.selectionBorder.setCursor(mxConstants.CURSOR_MOVABLE_VERTEX),(mxGraphHandler.prototype.maxCells<=0||this.graph.getSelectionCount()this.graph.tolerance||Math.abs(t.getGraphY()-this.startY)>this.graph.tolerance)&&(this.inTolerance=!1)},mxVertexHandler.prototype.updateHint=function(t){},mxVertexHandler.prototype.removeHint=function(){},mxVertexHandler.prototype.roundAngle=function(t){return Math.round(10*t)/10},mxVertexHandler.prototype.roundLength=function(t){return Math.round(100*t)/100},mxVertexHandler.prototype.mouseMove=function(t,e){e.isConsumed()||null==this.index?this.graph.isMouseDown||null==this.getHandleForEvent(e)||e.consume(!1):(this.checkTolerance(e),this.inTolerance||(this.index<=mxEvent.CUSTOM_HANDLE?null!=this.customHandles&&(this.customHandles[mxEvent.CUSTOM_HANDLE-this.index].processEvent(e),this.customHandles[mxEvent.CUSTOM_HANDLE-this.index].active=!0,null!=this.ghostPreview?(this.ghostPreview.apply(this.state),this.ghostPreview.strokewidth=this.getSelectionStrokeWidth()/this.ghostPreview.scale/this.ghostPreview.scale,this.ghostPreview.isDashed=this.isSelectionDashed(),this.ghostPreview.stroke=this.getSelectionColor(),this.ghostPreview.redraw(),null!=this.selectionBounds&&(this.selectionBorder.node.style.display="none")):(this.movePreviewToFront&&this.moveToFront(),this.customHandles[mxEvent.CUSTOM_HANDLE-this.index].positionChanged())):this.index==mxEvent.LABEL_HANDLE?this.moveLabel(e):(this.index==mxEvent.ROTATION_HANDLE?this.rotateVertex(e):this.resizeVertex(e),this.updateHint(e))),e.consume())},mxVertexHandler.prototype.isGhostPreview=function(){return 0p.x+p.width&&(this.unscaledBounds.width-=this.unscaledBounds.x+this.unscaledBounds.width-p.x-p.width),this.unscaledBounds.y+this.unscaledBounds.height>p.y+p.height&&(this.unscaledBounds.height-=this.unscaledBounds.y+this.unscaledBounds.height-p.y-p.height)));var p=this.bounds;this.bounds=new mxRectangle((null!=this.parentState?this.parentState.x:l.x*s)+this.unscaledBounds.x*s,(null!=this.parentState?this.parentState.y:l.y*s)+this.unscaledBounds.y*s,this.unscaledBounds.width*s,this.unscaledBounds.height*s),u.relative&&null!=this.parentState&&(this.bounds.x+=this.state.x-this.parentState.x,this.bounds.y+=this.state.y-this.parentState.y),o=Math.cos(n),r=Math.sin(n);u=new mxPoint(this.bounds.getCenterX(),this.bounds.getCenterY()),n=o*(a=u.x-e.x)-r*(h=u.y-e.y)-a,u=r*a+o*h-h,e=this.bounds.x-this.state.x,a=this.bounds.y-this.state.y,h=o*e-r*a,a=r*e+o*a;this.bounds.x+=n,this.bounds.y+=u,this.unscaledBounds.x=this.roundLength(this.unscaledBounds.x+n/s),this.unscaledBounds.y=this.roundLength(this.unscaledBounds.y+u/s),this.unscaledBounds.width=this.roundLength(this.unscaledBounds.width),this.unscaledBounds.height=this.roundLength(this.unscaledBounds.height),this.graph.isCellCollapsed(this.state.cell)||0==n&&0==u?(this.childOffsetX=0,this.childOffsetY=0):(this.childOffsetX=this.state.x-this.bounds.x+h,this.childOffsetY=this.state.y-this.bounds.y+a),p.equals(this.bounds)||(this.livePreviewActive&&this.updateLivePreview(t),null!=this.preview?this.drawPreview():this.updateParentHighlight())},mxVertexHandler.prototype.updateLivePreview=function(t){var e=this.graph.view.scale,n=this.graph.view.translate,i=this.state.clone();this.state.x=this.bounds.x,this.state.y=this.bounds.y,this.state.origin=new mxPoint(this.state.x/e-n.x,this.state.y/e-n.y),this.state.width=this.bounds.width,this.state.height=this.bounds.height;e=new mxPoint((e=this.state.absoluteOffset).x,e.y);this.state.absoluteOffset.x=0,this.state.absoluteOffset.y=0;n=this.graph.getCellGeometry(this.state.cell);null!=n&&(null==(e=n.offset||this.EMPTY_POINT)||n.relative||(this.state.absoluteOffset.x=this.state.view.scale*e.x,this.state.absoluteOffset.y=this.state.view.scale*e.y),this.state.view.updateVertexLabelOffset(this.state)),this.state.view.graph.cellRenderer.redraw(this.state,!0),this.state.view.invalidate(this.state.cell),this.state.invalid=!1,this.state.view.validate(),this.redrawHandles(),this.movePreviewToFront&&this.moveToFront(),null!=this.state.control&&null!=this.state.control.node&&(this.state.control.node.style.visibility="hidden"),this.state.setState(i)},mxVertexHandler.prototype.moveToFront=function(){(null!=this.state.text&&null!=this.state.text.node&&null!=this.state.text.node.nextSibling||null!=this.state.shape&&null!=this.state.shape.node&&null!=this.state.shape.node.nextSibling&&(null==this.state.text||this.state.shape.node.nextSibling!=this.state.text.node))&&(null!=this.state.shape&&null!=this.state.shape.node&&this.state.shape.node.parentNode.appendChild(this.state.shape.node),null!=this.state.text&&null!=this.state.text.node&&this.state.text.node.parentNode.appendChild(this.state.text.node))},mxVertexHandler.prototype.mouseUp=function(t,e){if(null!=this.index&&null!=this.state){var n,i,l,s,o,r,a=new mxPoint(e.getGraphX(),e.getGraphY()),h=this.index;(this.index=null)==this.ghostPreview&&(this.state.view.invalidate(this.state.cell,!1,!1),this.state.view.validate()),this.graph.getModel().beginUpdate();try{h<=mxEvent.CUSTOM_HANDLE?null!=this.customHandles&&(l=this.state.view.graph.getCellStyle(this.state.cell),this.customHandles[mxEvent.CUSTOM_HANDLE-h].active=!1,this.customHandles[mxEvent.CUSTOM_HANDLE-h].execute(e),null!=this.customHandles&&null!=this.customHandles[mxEvent.CUSTOM_HANDLE-h]&&(this.state.style=l,this.customHandles[mxEvent.CUSTOM_HANDLE-h].positionChanged())):h==mxEvent.ROTATION_HANDLE?null!=this.currentAlpha?0!=(s=this.currentAlpha-(this.state.style[mxConstants.STYLE_ROTATION]||0))&&this.rotateCell(this.state.cell,s):this.rotateClick():(n=this.graph.isGridEnabledEvent(e.getEvent()),r=mxUtils.toRadians(this.state.style[mxConstants.STYLE_ROTATION]||"0"),i=Math.cos(-r),r=(o=Math.sin(-r))*(l=a.x-this.startX)+i*(s=a.y-this.startY),l=i*l-o*s,s=r,o=this.graph.view.scale,r=this.isRecursiveResize(this.state,e),this.resizeCell(this.state.cell,this.roundLength(l/o),this.roundLength(s/o),h,n,this.isConstrainedEvent(e),r))}finally{this.graph.getModel().endUpdate()}e.consume(),this.reset(),this.redrawHandles()}},mxVertexHandler.prototype.isRecursiveResize=function(t,e){return this.graph.isRecursiveResize(this.state)},mxVertexHandler.prototype.rotateClick=function(){},mxVertexHandler.prototype.rotateCell=function(t,e,n){if(0!=e){var i=this.graph.getModel();if(i.isVertex(t)||i.isEdge(t)){i.isEdge(t)||(s=(this.graph.getCurrentCellStyle(t)[mxConstants.STYLE_ROTATION]||0)+e,this.graph.setCellStyles(mxConstants.STYLE_ROTATION,s,[t]));var l=this.graph.getCellGeometry(t);if(null!=l){var s=this.graph.getCellGeometry(n);if(null==s||i.isEdge(n)||((l=l.clone()).rotate(e,new mxPoint(s.width/2,s.height/2)),i.setGeometry(t,l)),i.isVertex(t)&&!l.relative||i.isEdge(t))for(var o=i.getChildCount(t),r=0;rmxEvent.VIRTUAL_HANDLE&&null!=this.customHandles)for(var i=0;imxEvent.VIRTUAL_HANDLE&&(s[this.index-1]=l)}return null!=o?o:s},mxEdgeHandler.prototype.isOutlineConnectEvent=function(t){var e=mxUtils.getOffset(this.graph.container),n=t.getEvent(),i=mxEvent.getClientX(n),l=mxEvent.getClientY(n),s=document.documentElement,n=(window.pageXOffset||s.scrollLeft)-(s.clientLeft||0),s=(window.pageYOffset||s.scrollTop)-(s.clientTop||0),n=this.currentPoint.x-this.graph.container.scrollLeft+e.x-n,s=this.currentPoint.y-this.graph.container.scrollTop+e.y-s;return this.outlineConnect&&!mxEvent.isShiftDown(t.getEvent())&&(t.isSource(this.marker.highlight.shape)||mxEvent.isAltDown(t.getEvent())&&null!=t.getState()||this.marker.highlight.isHighlightAt(i,l)||(n!=i||s!=l)&&null==t.getState()&&this.marker.highlight.isHighlightAt(n,s))},mxEdgeHandler.prototype.updatePreviewState=function(t,e,n,i,l){var s,o=this.isSource?n:this.state.getVisibleTerminalState(!0),r=this.isTarget?n:this.state.getVisibleTerminalState(!1),a=this.graph.getConnectionConstraint(t,o,!0),h=this.graph.getConnectionConstraint(t,r,!1),d=this.constraintHandler.currentConstraint;null==d&&l&&(null!=n?(i.isSource(this.marker.highlight.shape)&&(e=new mxPoint(i.getGraphX(),i.getGraphY())),d=this.graph.getOutlineConstraint(e,n,i),this.constraintHandler.setFocus(i,n,this.isSource),this.constraintHandler.currentConstraint=d,this.constraintHandler.currentPoint=e):d=new mxConnectionConstraint),this.outlineConnect&&null!=this.marker.highlight&&null!=this.marker.highlight.shape&&(s=this.graph.view.scale,null!=this.constraintHandler.currentConstraint&&null!=this.constraintHandler.currentFocus?(this.marker.highlight.shape.stroke=l?mxConstants.OUTLINE_HIGHLIGHT_COLOR:"transparent",this.marker.highlight.shape.strokewidth=mxConstants.OUTLINE_HIGHLIGHT_STROKEWIDTH/s/s,this.marker.highlight.repaint()):this.marker.hasValidState()&&(this.marker.highlight.shape.stroke=this.graph.isCellConnectable(i.getCell())&&this.marker.getValidState()!=i.getState()?"transparent":mxConstants.DEFAULT_VALID_COLOR,this.marker.highlight.shape.strokewidth=mxConstants.HIGHLIGHT_STROKEWIDTH/s/s,this.marker.highlight.repaint())),this.isSource?a=d:this.isTarget&&(h=d),(this.isSource||this.isTarget)&&(null!=d&&null!=d.point?(t.style[this.isSource?mxConstants.STYLE_EXIT_X:mxConstants.STYLE_ENTRY_X]=d.point.x,t.style[this.isSource?mxConstants.STYLE_EXIT_Y:mxConstants.STYLE_ENTRY_Y]=d.point.y):(delete t.style[this.isSource?mxConstants.STYLE_EXIT_X:mxConstants.STYLE_ENTRY_X],delete t.style[this.isSource?mxConstants.STYLE_EXIT_Y:mxConstants.STYLE_ENTRY_Y])),t.setVisibleTerminalState(o,!0),t.setVisibleTerminalState(r,!1),this.isSource&&null==o||t.view.updateFixedTerminalPoint(t,o,!0,a),this.isTarget&&null==r||t.view.updateFixedTerminalPoint(t,r,!1,h),(this.isSource||this.isTarget)&&null==n&&(t.setAbsoluteTerminalPoint(e,this.isSource),null==this.marker.getMarkedState()&&(this.error=this.graph.allowDanglingEdges?null:"")),t.view.updatePoints(t,this.points,o,r),t.view.updateFloatingTerminalPoints(t,o,r)},mxEdgeHandler.prototype.mouseMove=function(t,e){var n,i,l;null!=this.index&&null!=this.marker?(this.currentPoint=this.getPointForEvent(e),this.error=null,!this.graph.isIgnoreTerminalEvent(e.getEvent())&&mxEvent.isShiftDown(e.getEvent())&&null!=this.snapPoint&&(Math.abs(this.snapPoint.x-this.currentPoint.x)mxEvent.VIRTUAL_HANDLE?null!=this.customHandles&&(this.customHandles[mxEvent.CUSTOM_HANDLE-this.index].processEvent(e),this.customHandles[mxEvent.CUSTOM_HANDLE-this.index].positionChanged(),null!=this.shape&&null!=this.shape.node&&(this.shape.node.style.display="none")):this.isLabel?(this.label.x=this.currentPoint.x,this.label.y=this.currentPoint.y):(this.points=this.getPreviewPoints(this.currentPoint,e),n=this.isSource||this.isTarget?this.getPreviewTerminalState(e):null,null!=this.constraintHandler.currentConstraint&&null!=this.constraintHandler.currentFocus&&null!=this.constraintHandler.currentPoint?this.currentPoint=this.constraintHandler.currentPoint.clone():this.outlineConnect&&((l=!(!this.isSource&&!this.isTarget)&&this.isOutlineConnectEvent(e))?n=this.marker.highlight.state:null!=n&&n!=e.getState()&&this.graph.isCellConnectable(e.getCell())&&null!=this.marker.highlight.shape&&(this.marker.highlight.shape.stroke="transparent",this.marker.highlight.repaint(),n=null)),null==n||this.isCellEnabled(n.cell)||(n=null,this.marker.reset()),i=this.clonePreviewState(this.currentPoint,null!=n?n.cell:null),this.updatePreviewState(i,this.currentPoint,n,e,l),l=null==this.error?this.marker.validColor:this.marker.invalidColor,this.setPreviewColor(l),this.abspoints=i.absolutePoints,this.active=!0,this.updateHint(e,this.currentPoint)),this.drawPreview(),mxEvent.consume(e.getEvent()),e.consume()):mxClient.IS_IE&&null!=this.getHandleForEvent(e)&&e.consume(!1)},mxEdgeHandler.prototype.mouseUp=function(t,e){if(null!=this.index&&null!=this.marker){null!=this.shape&&null!=this.shape.node&&(this.shape.node.style.display="");var n=this.state.cell,i=this.index;if(this.index=null,e.getX()!=this.startX||e.getY()!=this.startY){var l=!this.graph.isIgnoreTerminalEvent(e.getEvent())&&this.graph.isCloneEvent(e.getEvent())&&this.cloneEnabled&&this.graph.isCellsCloneable();if(null!=this.error)0mxEvent.VIRTUAL_HANDLE){if(null!=this.customHandles){(a=this.graph.getModel()).beginUpdate();try{this.customHandles[mxEvent.CUSTOM_HANDLE-i].execute(e),null!=this.shape&&null!=this.shape.node&&(this.shape.apply(this.state),this.shape.redraw())}finally{a.endUpdate()}}}else if(this.isLabel)this.moveLabel(this.state,this.label.x,this.label.y);else if(this.isSource||this.isTarget){var s,o,r=null;if(null!=this.constraintHandler.currentConstraint&&null!=this.constraintHandler.currentFocus&&(r=this.constraintHandler.currentFocus.cell),null==r&&this.marker.hasValidState()&&null!=this.marker.highlight&&null!=this.marker.highlight.shape&&"transparent"!=this.marker.highlight.shape.stroke&&"white"!=this.marker.highlight.shape.stroke&&(r=this.marker.validState.cell),null!=r){var a,h,d=(a=this.graph.getModel()).getParent(n);a.beginUpdate();try{l&&(h=a.getGeometry(n),l=this.graph.cloneCell(n),a.add(d,l,a.getChildCount(d)),null!=h&&(h=h.clone(),a.setGeometry(l,h)),h=a.getTerminal(n,!this.isSource),this.graph.connectCell(l,h,!this.isSource),n=l),n=this.connect(n,r,this.isSource,l,e)}finally{a.endUpdate()}}else this.graph.isAllowDanglingEdges()&&((s=this.abspoints[this.isSource?0:this.abspoints.length-1]).x=this.roundLength(s.x/this.graph.view.scale-this.graph.view.translate.x),s.y=this.roundLength(s.y/this.graph.view.scale-this.graph.view.translate.y),null!=(o=this.graph.getView().getState(this.graph.getModel().getParent(n)))&&(s.x-=o.origin.x,s.y-=o.origin.y),s.x-=this.graph.panDx/this.graph.view.scale,s.y-=this.graph.panDy/this.graph.view.scale,n=this.changeTerminalPoint(n,s,this.isSource,l))}else this.active?n=this.changePoints(n,this.points,l):(this.graph.getView().invalidate(this.state.cell),this.graph.getView().validate(this.state.cell))}else this.graph.isToggleEvent(e.getEvent())&&this.graph.selectCellForEvent(this.state.cell,e.getEvent());null!=this.marker&&(this.reset(),n!=this.state.cell&&this.graph.setSelectionCell(n)),e.consume()}},mxEdgeHandler.prototype.reset=function(){if(this.active&&this.refresh(),this.error=null,this.index=null,this.label=null,this.points=null,this.snapPoint=null,this.isLabel=!1,this.isSource=!1,this.isTarget=!1,this.active=!1,this.livePreview&&null!=this.sizers)for(var t=0;t"),this.div.style.visibility="",mxUtils.fit(this.div))},mxTooltipHandler.prototype.destroy=function(){this.destroyed||(this.graph.removeMouseListener(this),mxEvent.release(this.div),null!=this.div&&null!=this.div.parentNode&&this.div.parentNode.removeChild(this.div),this.destroyed=!0,this.div=null)},mxUtils.extend(mxCellTracker,mxCellMarker),mxCellTracker.prototype.mouseDown=function(t,e){},mxCellTracker.prototype.mouseMove=function(t,e){this.isEnabled()&&this.process(e)},mxCellTracker.prototype.mouseUp=function(t,e){},mxCellTracker.prototype.destroy=function(){this.destroyed||(this.destroyed=!0,this.graph.removeMouseListener(this),mxCellMarker.prototype.destroy.apply(this))},mxCellHighlight.prototype.keepOnTop=!1,mxCellHighlight.prototype.graph=null,mxCellHighlight.prototype.state=null,mxCellHighlight.prototype.spacing=2,mxCellHighlight.prototype.resetHandler=null,mxCellHighlight.prototype.setHighlightColor=function(t){this.highlightColor=t,null!=this.shape&&(this.shape.stroke=t)},mxCellHighlight.prototype.drawHighlight=function(){this.shape=this.createShape(),this.repaint(),this.keepOnTop||this.shape.node.parentNode.firstChild==this.shape.node||this.shape.node.parentNode.insertBefore(this.shape.node,this.shape.node.parentNode.firstChild)},mxCellHighlight.prototype.createShape=function(){var t=this.graph.cellRenderer.createShape(this.state);return t.svgStrokeTolerance=this.graph.tolerance,t.points=this.state.absolutePoints,t.apply(this.state),t.stroke=this.highlightColor,t.opacity=this.opacity,t.isDashed=this.dashed,t.isShadow=!1,t.dialect=this.graph.dialect!=mxConstants.DIALECT_SVG?mxConstants.DIALECT_VML:mxConstants.DIALECT_SVG,t.init(this.graph.getView().getOverlayPane()),mxEvent.redirectMouseEvents(t.node,this.graph,this.state),this.graph.dialect!=mxConstants.DIALECT_SVG?t.pointerEvents=!1:t.svgPointerEvents="stroke",t},mxCellHighlight.prototype.getStrokeWidth=function(t){return this.strokeWidth},mxCellHighlight.prototype.repaint=function(){null!=this.state&&null!=this.shape&&(this.shape.scale=this.state.view.scale,this.graph.model.isEdge(this.state.cell)?(this.shape.strokewidth=this.getStrokeWidth(),this.shape.points=this.state.absolutePoints,this.shape.outline=!1):(this.shape.bounds=new mxRectangle(this.state.x-this.spacing,this.state.y-this.spacing,this.state.width+2*this.spacing,this.state.height+2*this.spacing),this.shape.rotation=Number(this.state.style[mxConstants.STYLE_ROTATION]||"0"),this.shape.strokewidth=this.getStrokeWidth()/this.state.view.scale,this.shape.outline=!0),null!=this.state.shape&&this.shape.setCursor(this.state.shape.getCursor()),!mxClient.IS_QUIRKS&&8!=document.documentMode||("transparent"==this.shape.stroke?(this.shape.stroke="white",this.shape.opacity=1):this.shape.opacity=this.opacity),this.shape.redraw())},mxCellHighlight.prototype.hide=function(){this.highlight(null)},mxCellHighlight.prototype.highlight=function(t){this.state!=t&&(null!=this.shape&&(this.shape.destroy(),this.shape=null),this.state=t,null!=this.state&&this.drawHighlight())},mxCellHighlight.prototype.isHighlightAt=function(t,e){var n=!1;if(null!=this.shape&&null!=document.elementFromPoint&&!mxClient.IS_QUIRKS)for(var i=document.elementFromPoint(t,e);null!=i;){if(i==this.shape.node){n=!0;break}i=i.parentNode}return n},mxCellHighlight.prototype.destroy=function(){this.graph.getView().removeListener(this.resetHandler),this.graph.getView().removeListener(this.repaintHandler),this.graph.getModel().removeListener(this.repaintHandler),null!=this.shape&&(this.shape.destroy(),this.shape=null)},mxDefaultKeyHandler.prototype.editor=null,mxDefaultKeyHandler.prototype.handler=null,mxDefaultKeyHandler.prototype.bindAction=function(t,e,n){var i=mxUtils.bind(this,function(){this.editor.execute(e)});n?this.handler.bindControlKey(t,i):this.handler.bindKey(t,i)},mxDefaultKeyHandler.prototype.destroy=function(){this.handler.destroy(),this.handler=null},mxDefaultPopupMenu.prototype.imageBasePath=null,mxDefaultPopupMenu.prototype.config=null,mxDefaultPopupMenu.prototype.createMenu=function(t,e,n,i){var l,s;null!=this.config&&(l=this.createConditions(t,n,i),s=this.config.firstChild,this.addItems(t,e,n,i,l,s,null))},mxDefaultPopupMenu.prototype.addItems=function(t,e,n,i,l,s,o){for(var r,a,h,d,u,p,m=!1;null!=s;)"add"==s.nodeName?null!=(p=s.getAttribute("if"))&&!l[p]||(r=s.getAttribute("as"),r=mxResources.get(r)||r,a=mxUtils.eval(mxUtils.getTextContent(s)),h=s.getAttribute("action"),d=s.getAttribute("icon"),u=s.getAttribute("iconCls"),p=null==(p=s.getAttribute("enabled-if"))||l[p],m&&(e.addSeparator(o),m=!1),null!=d&&this.imageBasePath&&(d=this.imageBasePath+d),p=this.addAction(e,t,r,d,a,h,n,o,u,p),this.addItems(t,e,n,i,l,s.firstChild,p)):"separator"==s.nodeName&&(m=!0),s=s.nextSibling},mxDefaultPopupMenu.prototype.addAction=function(t,e,n,i,l,s,o,r,a,h){return t.addItem(n,i,function(t){"function"==typeof l&&l.call(e,e,o,t),null!=s&&e.execute(s,o,t)},r,a,h)},mxDefaultPopupMenu.prototype.createConditions=function(t,e,n){var i=t.graph.getModel(),l=i.getChildCount(e),s=[];s.nocell=null==e,s.ncells=1 "+e.convertValueToString(n)+t),n=e.getModel().getParent(n);return this.getRootTitle()+t},mxEditor.prototype.getRootTitle=function(){var t=this.graph.getModel().getRoot();return this.graph.convertValueToString(t)},mxEditor.prototype.undo=function(){this.undoManager.undo()},mxEditor.prototype.redo=function(){this.undoManager.redo()},mxEditor.prototype.groupCells=function(){var t=null!=this.groupBorderSize?this.groupBorderSize:this.graph.gridSize;return this.graph.groupCells(this.createGroup(),t)},mxEditor.prototype.createGroup=function(){return this.graph.getModel().cloneCell(this.defaultGroup)},mxEditor.prototype.open=function(t){var e;null!=t&&(e=mxUtils.load(t).getXml(),this.readGraphModel(e.documentElement),this.filename=t,this.fireEvent(new mxEventObject(mxEvent.OPEN,"filename",t)))},mxEditor.prototype.readGraphModel=function(t){new mxCodec(t.ownerDocument).decode(t,this.graph.getModel()),this.resetHistory()},mxEditor.prototype.save=function(t,e){null!=(t=t||this.getUrlPost())&&0C.clientHeight-64&&(n.style.overflowY="auto"),s&&((s=document.createElement("img")).setAttribute("src",Dialog.prototype.closeImage),s.setAttribute("title",mxResources.get("close")),s.className="geDialogClose",s.style.top=y+14+"px",s.style.left=x+i+38-u+"px",s.style.zIndex=this.zIndex,mxEvent.addListener(s,"click",mxUtils.bind(this,function(){e.hideDialog(!0)})),document.body.appendChild(s),this.dialogImg=s,d||(f=!1,mxEvent.addGestureListeners(this.bg,mxUtils.bind(this,function(t){f=!0}),null,mxUtils.bind(this,function(t){f&&(e.hideDialog(!0),f=!1)})))),this.resizeListener=mxUtils.bind(this,function(){null==h||null!=(t=h())&&(p=i=t.w,m=l=t.h);var t=mxUtils.getDocumentSize();g=t.height,this.bg.style.height=g+"px",x=Math.max(1,Math.round((t.width-i-64)/2)),y=Math.max(1,Math.round((g-l-e.footerHeight)/3)),i=null!=document.body?Math.min(p,document.body.scrollWidth-64):p,l=Math.min(m,g-64);t=this.getPosition(x,y,i,l);x=t.x,y=t.y,C.style.left=x+"px",C.style.top=y+"px",C.style.width=i+"px",C.style.height=l+"px",!r&&n.clientHeight>C.clientHeight-64&&(n.style.overflowY="auto"),null!=this.dialogImg&&(this.dialogImg.style.top=y+14+"px",this.dialogImg.style.left=x+i+38-u+"px")}),mxEvent.addListener(window,"resize",this.resizeListener),this.onDialogClose=o,this.container=C,e.editor.fireEvent(new mxEventObject("showDialog"))}mxDefaultToolbarCodec.allowEval=!0,mxCodecRegistry.register(function(){var t=new mxObjectCodec(new mxDefaultPopupMenu);return t.encode=function(t,e){return null},t.decode=function(t,e,n){var i=e.getElementsByTagName("include")[0];return null!=i?this.processInclude(t,i,n):null!=n&&(n.config=e),n},t}()),mxCodecRegistry.register(function(){var t=new mxObjectCodec(new mxEditor,["modified","lastSnapshot","ignoredChanges","undoManager","graphContainer","toolbarContainer"]);return t.afterDecode=function(t,e,n){var i=e.getAttribute("defaultEdge");null!=i&&(e.removeAttribute("defaultEdge"),n.defaultEdge=n.templates[i]);i=e.getAttribute("defaultGroup");return null!=i&&(e.removeAttribute("defaultGroup"),n.defaultGroup=n.templates[i]),n},t.decodeChild=function(t,e,n){if("Array"==e.nodeName){if("templates"==e.getAttribute("as"))return void this.decodeTemplates(t,e,n)}else if("ui"==e.nodeName)return void this.decodeUi(t,e,n);mxObjectCodec.prototype.decodeChild.apply(this,arguments)},t.decodeUi=function(t,e,n){for(var i,l,s,o,r,a,h,d=e.firstChild;null!=d;)"add"==d.nodeName?(i=d.getAttribute("as"),a=d.getAttribute("element"),l=d.getAttribute("style"),(h=null)!=a?null!=(h=document.getElementById(a))&&null!=l&&(h.style.cssText+=";"+l):(s=parseInt(d.getAttribute("x")),o=parseInt(d.getAttribute("y")),r=d.getAttribute("width"),a=d.getAttribute("height"),(h=document.createElement("div")).style.cssText=l,new mxWindow(mxResources.get(i)||i,h,s,o,r,a,!1,!0).setVisible(!0)),"graph"==i?n.setGraphContainer(h):"toolbar"==i?n.setToolbarContainer(h):"title"==i?n.setTitleContainer(h):"status"==i?n.setStatusContainer(h):"map"==i&&n.setMapContainer(h)):"resource"==d.nodeName?mxResources.add(d.getAttribute("basename")):"stylesheet"==d.nodeName&&mxClient.link("stylesheet",d.getAttribute("name")),d=d.nextSibling},t.decodeTemplates=function(t,e,n){null==n.templates&&(n.templates=[]);for(var i=mxUtils.getChildNodes(e),l=0;li.container.scrollLeft+.9*i.container.clientWidth&&(i.container.scrollLeft=Math.min(e.x+e.width-i.container.clientWidth,e.x-10)),e.y>i.container.scrollTop+.9*i.container.clientHeight&&(i.container.scrollTop=Math.min(e.y+e.height-i.container.clientHeight,e.y-10)))):(e=i.getGraphBounds(),n=Math.max(e.width,i.scrollTileSize.width*i.view.scale),t=Math.max(e.height,i.scrollTileSize.height*i.view.scale),i.container.scrollTop=Math.floor(Math.max(0,e.y-Math.max(20,(i.container.clientHeight-t)/4))),i.container.scrollLeft=Math.floor(Math.max(0,e.x-Math.max(0,(i.container.clientWidth-n)/2)))):(t=mxRectangle.fromRectangle(i.pageVisible?i.view.getBackgroundPageBounds():i.getGraphBounds()),e=i.view.translate,n=i.view.scale,t.x=t.x/n-e.x,t.y=t.y/n-e.y,t.width/=n,t.height/=n,n=i.pageVisible?0:Math.max(0,(i.container.clientHeight-t.height)/4),i.view.setTranslate(Math.floor(Math.max(0,(i.container.clientWidth-t.width)/2)-t.x+2),Math.floor(n-t.y+1)))):(i.container.scrollTop=0,i.container.scrollLeft=0,mxUtils.hasScrollbars(i.container)||i.view.setTranslate(0,0))},EditorUi.prototype.setPageVisible=function(t){var e=this.editor.graph,n=mxUtils.hasScrollbars(e.container),i=0,l=0;n&&(i=e.view.translate.x*e.view.scale-e.container.scrollLeft,l=e.view.translate.y*e.view.scale-e.container.scrollTop),e.pageVisible=t,e.pageBreaksVisible=t,e.preferPageSize=t,e.view.validateBackground(),n&&(t=e.getSelectionCells(),e.clearSelection(),e.setSelectionCells(t)),e.sizeDidChange(),n&&(e.container.scrollLeft=e.view.translate.x*e.view.scale-i,e.container.scrollTop=e.view.translate.y*e.view.scale-l),this.fireEvent(new mxEventObject("pageViewChanged"))},ChangeGridColor.prototype.execute=function(){var t=this.ui.editor.graph.view.gridColor;this.ui.setGridColor(this.color),this.color=t},function(){var t=new mxObjectCodec(new ChangeGridColor,["ui"]);mxCodecRegistry.register(t)}(),ChangePageSetup.prototype.execute=function(){var t,e=this.ui.editor.graph;this.ignoreColor||(this.color=this.previousColor,t=e.background,this.ui.setBackgroundColor(this.previousColor),this.previousColor=t),this.ignoreImage||(this.image=this.previousImage,t=e.backgroundImage,this.ui.setBackgroundImage(this.previousImage),this.previousImage=t),null!=this.previousFormat&&(this.format=this.previousFormat,t=e.pageFormat,this.previousFormat.width==t.width&&this.previousFormat.height==t.height||(this.ui.setPageFormat(this.previousFormat),this.previousFormat=t)),null!=this.foldingEnabled&&this.foldingEnabled!=this.ui.editor.graph.foldingEnabled&&(this.ui.setFoldingEnabled(this.foldingEnabled),this.foldingEnabled=!this.foldingEnabled),null!=this.previousPageScale&&(t=this.ui.editor.graph.pageScale,this.previousPageScale!=t&&(this.ui.setPageScale(this.previousPageScale),this.previousPageScale=t))},function(){var t=new mxObjectCodec(new ChangePageSetup,["ui","previousColor","previousImage","previousFormat","previousPageScale"]);t.afterDecode=function(t,e,n){return n.previousColor=n.color,n.previousImage=n.image,n.previousFormat=n.format,n.previousPageScale=n.pageScale,null!=n.foldingEnabled&&(n.foldingEnabled=!n.foldingEnabled),n},mxCodecRegistry.register(t)}(),EditorUi.prototype.setBackgroundColor=function(t){this.editor.graph.background=t,this.editor.graph.view.validateBackground(),this.fireEvent(new mxEventObject("backgroundColorChanged"))},EditorUi.prototype.setFoldingEnabled=function(t){this.editor.graph.foldingEnabled=t,this.editor.graph.view.revalidate(),this.fireEvent(new mxEventObject("foldingEnabledChanged"))},EditorUi.prototype.setPageFormat=function(t){this.editor.graph.pageFormat=t,this.editor.graph.pageVisible?(this.editor.graph.view.validateBackground(),this.editor.graph.sizeDidChange()):this.actions.get("pageView").funct(),this.fireEvent(new mxEventObject("pageFormatChanged"))},EditorUi.prototype.setPageScale=function(t){this.editor.graph.pageScale=t,this.editor.graph.pageVisible?(this.editor.graph.view.validateBackground(),this.editor.graph.sizeDidChange()):this.actions.get("pageView").funct(),this.fireEvent(new mxEventObject("pageScaleChanged"))},EditorUi.prototype.setGridColor=function(t){this.editor.graph.view.gridColor=t,this.editor.graph.view.validateBackground(),this.fireEvent(new mxEventObject("gridColorChanged"))},EditorUi.prototype.addUndoListener=function(){var t=this.actions.get("undo"),e=this.actions.get("redo"),n=this.editor.undoManager,i=mxUtils.bind(this,function(){t.setEnabled(this.canUndo()),e.setEnabled(this.canRedo())});n.addListener(mxEvent.ADD,i),n.addListener(mxEvent.UNDO,i),n.addListener(mxEvent.REDO,i),n.addListener(mxEvent.CLEAR,i);var l=this.editor.graph.cellEditor.startEditing;this.editor.graph.cellEditor.startEditing=function(){l.apply(this,arguments),i()};var s=this.editor.graph.cellEditor.stopEditing;this.editor.graph.cellEditor.stopEditing=function(t,e){s.apply(this,arguments),i()},i()},EditorUi.prototype.updateActionStates=function(){var t=this.editor.graph,e=!t.isSelectionEmpty(),n=!1,i=!1,l=!1,s=t.getSelectionCells();if(null!=s)for(var o=0;o").replace(/</g,"<").replace(/\\"/g,'"').replace(/\n/g,"")))}catch(t){}return e},EditorUi.prototype.extractGraphModelFromEvent=function(t){var e=null,n=null;return null==t||null!=(t=null!=t.dataTransfer?t.dataTransfer:t.clipboardData)&&(10==document.documentMode||11==document.documentMode?n=t.getData("Text"):(n=0<=mxUtils.indexOf(t.types,"text/html")?t.getData("text/html"):null,mxUtils.indexOf(t.types,null==n||0==n.length)&&(n=t.getData("text/plain"))),null!=n&&(n=Graph.zapGremlins(mxUtils.trim(n)),null!=(t=this.extractGraphModelFromHtml(n))&&(n=t))),null!=n&&this.isCompatibleString(n)&&(e=n),e},EditorUi.prototype.isCompatibleString=function(t){return!1},EditorUi.prototype.saveFile=function(t){t||null==this.editor.filename?(t=new FilenameDialog(this,this.editor.getOrCreateFilename(),mxResources.get("save"),mxUtils.bind(this,function(t){this.save(t)}),null,mxUtils.bind(this,function(t){return null!=t&&0'),t.writeln("@media screen {"),t.writeln(" body > div { padding:30px;box-sizing:content-box; }"),t.writeln("}"),t.writeln("")},s},PrintDialog.previewEnabled=!0;var PageSetupDialog=function(i){var l=i.editor.graph,t=document.createElement("table");t.style.width="100%",t.style.height="100%";var e,n=document.createElement("tbody"),s=document.createElement("tr");(e=document.createElement("td")).style.verticalAlign="top",e.style.fontSize="10pt",mxUtils.write(e,mxResources.get("paperSize")+":"),s.appendChild(e),(e=document.createElement("td")).style.verticalAlign="top",e.style.fontSize="10pt";var o=PageSetupDialog.addPageFormatPanel(e,"pagesetupdialog",l.pageFormat);s.appendChild(e),n.appendChild(s),s=document.createElement("tr"),e=document.createElement("td"),mxUtils.write(e,mxResources.get("background")+":"),s.appendChild(e),(e=document.createElement("td")).style.whiteSpace="nowrap",document.createElement("input").setAttribute("type","text");var r=document.createElement("button");r.style.width="18px",r.style.height="18px",r.style.marginRight="20px",r.style.backgroundPosition="center center",r.style.backgroundRepeat="no-repeat";var a=l.background;function h(){null==a||a==mxConstants.NONE?(r.style.backgroundColor="",r.style.backgroundImage="url('"+Dialog.prototype.noColorImage+"')"):(r.style.backgroundColor=a,r.style.backgroundImage="")}h(),mxEvent.addListener(r,"click",function(t){i.pickColor(a||"none",function(t){a=t,h()}),mxEvent.consume(t)}),e.appendChild(r),mxUtils.write(e,mxResources.get("gridSize")+":");var d=document.createElement("input");d.setAttribute("type","number"),d.setAttribute("min","0"),d.style.width="40px",d.style.marginLeft="6px",d.value=l.getGridSize(),e.appendChild(d),mxEvent.addListener(d,"change",function(){var t=parseInt(d.value);d.value=Math.max(1,isNaN(t)?l.getGridSize():t)}),s.appendChild(e),n.appendChild(s),s=document.createElement("tr"),e=document.createElement("td"),mxUtils.write(e,mxResources.get("image")+":"),s.appendChild(e),e=document.createElement("td");var u=document.createElement("a");u.style.textDecoration="underline",u.style.cursor="pointer",u.style.color="#a0a0a0";var p=l.backgroundImage;function m(){null==p?(u.removeAttribute("title"),u.style.fontSize="",u.innerHTML=mxUtils.htmlEntities(mxResources.get("change"))+"..."):(u.setAttribute("title",p.src),u.style.fontSize="11px",u.innerHTML=mxUtils.htmlEntities(p.src.substring(0,42))+"...")}mxEvent.addListener(u,"click",function(t){i.showBackgroundImageDialog(function(t,e){e||(p=t,m())},p),mxEvent.consume(t)}),m(),e.appendChild(u),s.appendChild(e),n.appendChild(s),s=document.createElement("tr"),(e=document.createElement("td")).colSpan=2,e.style.paddingTop="16px",e.setAttribute("align","right");var c=mxUtils.button(mxResources.get("cancel"),function(){i.hideDialog()});c.className="geBtn",i.editor.cancelFirst&&e.appendChild(c);var g=mxUtils.button(mxResources.get("apply"),function(){i.hideDialog();var t=parseInt(d.value);isNaN(t)||l.gridSize===t||l.setGridSize(t);var e=new ChangePageSetup(i,a,p,o.get());e.ignoreColor=l.background==a;var n=null!=l.backgroundImage?l.backgroundImage.src:null,t=null!=p?p.src:null;e.ignoreImage=n===t,l.pageFormat.width==e.previousFormat.width&&l.pageFormat.height==e.previousFormat.height&&e.ignoreColor&&e.ignoreImage||l.model.execute(e)});g.className="geBtn gePrimaryBtn",e.appendChild(g),i.editor.cancelFirst||e.appendChild(c),s.appendChild(e),n.appendChild(s),t.appendChild(n),this.container=t};PageSetupDialog.addPageFormatPanel=function(t,e,o,i){var n="format-"+e,r=document.createElement("input");r.setAttribute("name",n),r.setAttribute("type","radio"),r.setAttribute("value","portrait");var a=document.createElement("input");a.setAttribute("name",n),a.setAttribute("type","radio"),a.setAttribute("value","landscape");var h=document.createElement("select");h.style.marginBottom="8px",h.style.width="202px";var d=document.createElement("div");d.style.marginLeft="4px",d.style.width="210px",d.style.height="24px",r.style.marginRight="6px",d.appendChild(r);e=document.createElement("span");e.style.maxWidth="100px",mxUtils.write(e,mxResources.get("portrait")),d.appendChild(e),a.style.marginLeft="10px",a.style.marginRight="6px",d.appendChild(a);n=document.createElement("span");n.style.width="100px",mxUtils.write(n,mxResources.get("landscape")),d.appendChild(n);var u=document.createElement("div");u.style.marginLeft="4px",u.style.width="210px",u.style.height="24px";var p=document.createElement("input");p.setAttribute("size","7"),p.style.textAlign="right",u.appendChild(p),mxUtils.write(u," in x ");var m=document.createElement("input");m.setAttribute("size","7"),m.style.textAlign="right",u.appendChild(m),mxUtils.write(u," in"),d.style.display="none",u.style.display="none";for(var l=new Object,c=PageSetupDialog.getFormats(),s=0;s'};var l=mxGraph.prototype.panGraph;mxGraph.prototype.panGraph=function(t,e){var n,i;l.apply(this,arguments),null!=this.shiftPreview1&&(null!=(n=this.view.canvas).ownerSVGElement&&(n=n.ownerSVGElement),i=this.gridSize*this.view.scale*this.view.gridSteps,i=-Math.round(i-mxUtils.mod(this.view.translate.x*this.view.scale+t,i))+"px "+-Math.round(i-mxUtils.mod(this.view.translate.y*this.view.scale+e,i))+"px",n.style.backgroundPosition=i)},mxGraph.prototype.updatePageBreaks=function(t,e,n){var i=this.view.scale,l=this.view.translate,s=this.pageFormat,o=i*this.pageScale,r=this.view.getBackgroundPageBounds();e=r.width,n=r.height;var a=new mxRectangle(i*l.x,i*l.y,s.width*o,s.height*o),h=(t=t&&Math.min(a.width,a.height)>this.minPageBreakDist)?Math.ceil(n/a.height)-1:0,d=t?Math.ceil(e/a.width)-1:0,u=r.x+e,p=r.y+n;null==this.horizontalPageBreaks&&0this.maxTooltipWidth||h>this.maxTooltipHeight?this.graph2.view.scale=Math.round(100*Math.min(this.maxTooltipWidth/a,this.maxTooltipHeight/h))/100:this.graph2.view.scale=1,this.tooltip.style.display="block",this.graph2.labelsVisible=null==u||u;var t=mxClient.NO_FO;mxClient.NO_FO=Editor.prototype.originalNoForeignObject;var e=this.graph2.cloneCells(r);this.editorUi.insertHandler(e,null,this.graph2.model),this.graph2.addCells(e),mxClient.NO_FO=t;var n=this.graph2.getGraphBounds(),i=n.width+2*this.tooltipBorder+4,l=n.height+2*this.tooltipBorder;mxClient.IS_QUIRKS?(l+=4,this.tooltip.style.overflow="hidden"):this.tooltip.style.overflow="visible",this.tooltip.style.width=i+"px";e=i;this.tooltipTitles&&null!=d&&0Heading

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

","Textbox",null,null,"text textbox textarea"),this.createVertexTemplateEntry("ellipse;shape=ellipse;whiteSpace=wrap;html=1;aspect=fixed;",120,80,"","Ellipse",null,null,"oval ellipse state"),this.createVertexTemplateEntry("whiteSpace=wrap;html=1;aspect=fixed;",80,80,"","Square",null,null,"square"),this.createVertexTemplateEntry("ellipse;shape=ellipse;whiteSpace=wrap;html=1;aspect=fixed;",80,80,"","Circle",null,null,"circle"),this.createVertexTemplateEntry("shape=process;whiteSpace=wrap;html=1;backgroundOutline=1;",120,60,"","Process",null,null,"process task"),this.createVertexTemplateEntry("html=1;whiteSpace=wrap;aspect=fixed;shape=isoRectangle;",80,80,"","Diamond",null,null,"diamond rhombus if condition decision conditional question test"),this.createVertexTemplateEntry("shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;",120,60,"","Parallelogram"),this.createVertexTemplateEntry("shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;",120,80,"","Hexagon",null,null,"hexagon preparation"),this.createVertexTemplateEntry("triangle;shape=triangle;whiteSpace=wrap;html=1;",60,80,"","Triangle",null,null,"triangle logic inverter buffer"),this.createVertexTemplateEntry("shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;",60,80,"","Cylinder",null,null,"cylinder data database"),this.createVertexTemplateEntry("ellipse;shape=cloud;whiteSpace=wrap;html=1;",120,80,"","Cloud",null,null,"cloud network"),this.createVertexTemplateEntry("shape=document;whiteSpace=wrap;html=1;boundedLbl=1;",120,80,"","Document"),this.createVertexTemplateEntry("shape=internalStorage;whiteSpace=wrap;html=1;backgroundOutline=1;",80,80,"","Internal Storage"),this.createVertexTemplateEntry("shape=cube;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;darkOpacity=0.05;darkOpacity2=0.1;",120,80,"","Cube"),this.createVertexTemplateEntry("shape=step;perimeter=stepPerimeter;whiteSpace=wrap;html=1;fixedSize=1;",120,80,"","Step"),this.createVertexTemplateEntry("shape=trapezoid;perimeter=trapezoidPerimeter;whiteSpace=wrap;html=1;fixedSize=1;",120,60,"","Trapezoid"),this.createVertexTemplateEntry("shape=tape;whiteSpace=wrap;html=1;",120,100,"","Tape"),this.createVertexTemplateEntry("shape=note;whiteSpace=wrap;html=1;backgroundOutline=1;darkOpacity=0.05;",80,100,"","Note"),this.createVertexTemplateEntry("shape=card;whiteSpace=wrap;html=1;",80,100,"","Card"),this.createVertexTemplateEntry("shape=callout;whiteSpace=wrap;html=1;perimeter=calloutPerimeter;",120,80,"","Callout",null,null,"bubble chat thought speech message"),this.createVertexTemplateEntry("shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;",30,60,"Actor","Actor",!1,null,"user person human stickman"),this.createVertexTemplateEntry("shape=xor;whiteSpace=wrap;html=1;",60,80,"","Or",null,null,"logic or"),this.createVertexTemplateEntry("shape=or;whiteSpace=wrap;html=1;",60,80,"","And",null,null,"logic and"),this.createVertexTemplateEntry("shape=dataStorage;whiteSpace=wrap;html=1;fixedSize=1;",100,80,"","Data Storage"),this.createVertexTemplateEntry("swimlane;startSize=0;",200,200,"","Container",null,null,"container swimlane lane pool group"),this.createVertexTemplateEntry("swimlane;",200,200,"Vertical Container","Container",null,null,"container swimlane lane pool group"),this.createVertexTemplateEntry("swimlane;horizontal=0;",200,200,"Horizontal Container","Horizontal Container",null,null,"container swimlane lane pool group"),this.addEntry("list group erd table",function(){var t=new mxCell("List",new mxGeometry(0,0,140,120),"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;");return t.vertex=!0,t.insert(n.cloneCell(l,"Item 1")),t.insert(n.cloneCell(l,"Item 2")),t.insert(n.cloneCell(l,"Item 3")),n.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"List")}),this.addEntry("list item entry value group erd table",function(){return n.createVertexTemplateFromCells([n.cloneCell(l,"List Item")],l.geometry.width,l.geometry.height,"List Item")}),this.addEntry("curve",mxUtils.bind(this,function(){var t=new mxCell("",new mxGeometry(0,0,50,50),"curved=1;endArrow=classic;html=1;");return t.geometry.setTerminalPoint(new mxPoint(0,50),!0),t.geometry.setTerminalPoint(new mxPoint(50,0),!1),t.geometry.points=[new mxPoint(50,50),new mxPoint(0,0)],t.geometry.relative=!0,t.edge=!0,this.createEdgeTemplateFromCells([t],t.geometry.width,t.geometry.height,"Curve")})),this.createEdgeTemplateEntry("shape=flexArrow;endArrow=classic;startArrow=classic;html=1;",100,100,"","Bidirectional Arrow",null,e+"bidirectional"),this.createEdgeTemplateEntry("shape=flexArrow;endArrow=classic;html=1;",50,50,"","Arrow",null,e+"directional directed"),this.createEdgeTemplateEntry("endArrow=none;dashed=1;html=1;",50,50,"","Dashed Line",null,e+"dashed undirected no"),this.createEdgeTemplateEntry("endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;",50,50,"","Dotted Line",null,e+"dotted undirected no"),this.createEdgeTemplateEntry("endArrow=none;html=1;",50,50,"","Line",null,e+"simple undirected plain blank no"),this.createEdgeTemplateEntry("endArrow=classic;startArrow=classic;html=1;",50,50,"","Bidirectional Connector",null,e+"bidirectional"),this.createEdgeTemplateEntry("endArrow=classic;html=1;",50,50,"","Directional Connector",null,e+"directional directed"),this.createEdgeTemplateEntry("shape=link;html=1;",100,0,"","Link",null,e+"link"),this.addEntry(e+"edge title",mxUtils.bind(this,function(){var t=new mxCell("",new mxGeometry(0,0,0,0),"endArrow=classic;html=1;");t.geometry.setTerminalPoint(new mxPoint(0,0),!0),t.geometry.setTerminalPoint(new mxPoint(100,0),!1),t.geometry.relative=!0,t.edge=!0;var e=new mxCell("Label",new mxGeometry(0,0,0,0),"edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;");return e.geometry.relative=!0,e.setConnectable(!1),e.vertex=!0,t.insert(e),this.createEdgeTemplateFromCells([t],100,0,"Connector with Label")})),this.addEntry(e+"edge title multiplicity",mxUtils.bind(this,function(){var t=new mxCell("",new mxGeometry(0,0,0,0),"endArrow=classic;html=1;");t.geometry.setTerminalPoint(new mxPoint(0,0),!0),t.geometry.setTerminalPoint(new mxPoint(160,0),!1),t.geometry.relative=!0,t.edge=!0;var e=new mxCell("Label",new mxGeometry(0,0,0,0),"edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;");e.geometry.relative=!0,e.setConnectable(!1),e.vertex=!0,t.insert(e);e=new mxCell("Source",new mxGeometry(-1,0,0,0),"edgeLabel;resizable=0;html=1;align=left;verticalAlign=bottom;");return e.geometry.relative=!0,e.setConnectable(!1),e.vertex=!0,t.insert(e),this.createEdgeTemplateFromCells([t],160,0,"Connector with 2 Labels")})),this.addEntry(e+"edge title multiplicity",mxUtils.bind(this,function(){var t=new mxCell("",new mxGeometry(0,0,0,0),"endArrow=classic;html=1;");t.geometry.setTerminalPoint(new mxPoint(0,0),!0),t.geometry.setTerminalPoint(new mxPoint(160,0),!1),t.geometry.relative=!0,t.edge=!0;var e=new mxCell("Label",new mxGeometry(0,0,0,0),"edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;");e.geometry.relative=!0,e.setConnectable(!1),e.vertex=!0,t.insert(e);e=new mxCell("Source",new mxGeometry(-1,0,0,0),"edgeLabel;resizable=0;html=1;align=left;verticalAlign=bottom;");e.geometry.relative=!0,e.setConnectable(!1),e.vertex=!0,t.insert(e);e=new mxCell("Target",new mxGeometry(1,0,0,0),"edgeLabel;resizable=0;html=1;align=right;verticalAlign=bottom;");return e.geometry.relative=!0,e.setConnectable(!1),e.vertex=!0,t.insert(e),this.createEdgeTemplateFromCells([t],160,0,"Connector with 3 Labels")})),this.addEntry(e+"edge shape symbol message mail email",mxUtils.bind(this,function(){var t=new mxCell("",new mxGeometry(0,0,0,0),"endArrow=classic;html=1;");t.geometry.setTerminalPoint(new mxPoint(0,0),!0),t.geometry.setTerminalPoint(new mxPoint(100,0),!1),t.geometry.relative=!0,t.edge=!0;var e=new mxCell("",new mxGeometry(0,0,20,14),"shape=message;html=1;outlineConnect=0;");return e.geometry.relative=!0,e.vertex=!0,e.geometry.offset=new mxPoint(-10,-7),t.insert(e),this.createEdgeTemplateFromCells([t],100,0,"Connector with Symbol")}))];this.addPaletteFunctions("general",mxResources.get("general"),null==t||t,e),this.setCurrentSearchEntryLibrary()},Sidebar.prototype.addMiscPalette=function(t){var n=this,e="line lines connector connectors connection connections arrow arrows ";this.setCurrentSearchEntryLibrary("general","misc");e=[this.createVertexTemplateEntry("text;strokeColor=none;fillColor=none;html=1;fontSize=24;fontStyle=1;verticalAlign=middle;align=center;",100,40,"Title","Title",null,null,"text heading title"),this.createVertexTemplateEntry("text;strokeColor=none;fillColor=none;html=1;whiteSpace=wrap;verticalAlign=middle;overflow=hidden;",100,80,"
  • Value 1
  • Value 2
  • Value 3
","Unordered List"),this.createVertexTemplateEntry("text;strokeColor=none;fillColor=none;html=1;whiteSpace=wrap;verticalAlign=middle;overflow=hidden;",100,80,"
  1. Value 1
  2. Value 2
  3. Value 3
","Ordered List"),this.addDataEntry("table",180,120,"Table 1","7ZjBTuMwEIafJteVnVDoXpuycGAvsC9g6mltyfFE9kAann7txN2qqIgU0aCllRJpZjxO7G9i/3KyoqzWN07U6jdKMFlxnRWlQ6TeqtYlGJPlTMusmGd5zsKd5b/eaOVdK6uFA0tDOuR9h2dhnqCP9AFPrUkBr0QdTRKPMTRTVIVhznkwG6UJHmqxiO1NmESIeRKOHvRLDLHgL9CS0BZc6rNAY0TtdfewPkNpI+9Ei0+0ec3Gm6XhgSNYvznFLpTmdwNYAbk2pDRakkoZ0x4DU6BXatMtsWHC94HVv75bYsFI0PYDLA4EeI9NZIhOv0QwJjF4Tc03ujLCwi0I+So0Q9mmEGGdLANLSuYjEmGVHJemy/aSlw7rP8KtYJOy1MaUaDAWy6KN5a5RW+oATWbhCshK9mOSTcLMyuDzrR+umO6oROvJhaLHx4Lw1IAfXMz8Y8W8+IRaXgyvZRgxaWHuYUHCroasi7AObMze0t8D+7CCYkC5NPGDmistJdihjIt3GV8eCfHkxBGvd/GOQPzyTHxnsx8B+dVZE0bRhHa3ZGNIxPRUVtPVl0nEzxNHPL5EcHZGPrZGcH4WiTFFYjqiSPADTtX/93ri7x+9j7aADjh5f0/IXyAU3+GE3O1L4K6fod+e+CfV4YjqEdztL8GubeeP4V8="),this.addDataEntry("table",180,120,"Table 2","7ZhRb5swEMc/Da+TDSFJX0O27qF7aae9u8EJlowP2ZcR+ulng1maJlbTaaEPIBHpfL5z8O/v0wlHSVYe7jWrih+QcxklX6Mk0wDYWeUh41JGMRF5lKyjOCb2F8XfArO0nSUV01zhNQlxl/CbyT3vPJ3DYCO9wxSsciayZ+daFVja11xTa9aFQP5UsY2br+0mrM8g0/gkXpyL2PEGFDKhuPY5G5CSVUa0i3URhZD5A2tgj/3f9CMXvS/Vg803PlpD/Xro359r5Icgg9blAdxzKDnqxobUIsfCRyw7TqTgYlf0aR4eYaZz7P7mHpFaw1O9TDj5IOFHqB1k0OLFkZN+n2+xmlqUkin+nbP8jWsFeeNdCJW3JN+iN58BEcoep98uuShNrqH6yfSO9yFbIWUGEpyaCpQ7DxUIhS2gdGUfiywjX9IotTvL7Jgex/Zx4RozUAa1PRVuWc4M1tzgtWLG/ybm7D9oOTvT8ldrxoQGRbWvjoLJR75BpnbXVJCtGOWijzJcoP4xZcEy3Up3staFyHOu3KL2ePkDReNr4Sfvwp/fiH0aZB8uqFGwP5xyH0CKeVCKZJLidd8YQIvF1F4GaS/NqWRDdJtlsMxmIymzxad1m7sg+3Tc7IfvNpQEtZhPWgzcbiid+s2Q/WY5YL+h55cBfaEtRlJo9P2bgptV1vlFQU9/OXL6n9Bzwl/6d5MYN246dni8AG3nTu5H/wA="),this.addDataEntry("table title",180,150,"Table with Title 1","7ZjBbtswDEC/xtfBsuumu8bZusN2afoDasxYAmjJkNk57tePkpVlXdMlBRYXaAI4AEmRcvgogpCTvGw2t0626oetAJP8S5KXzloapWZTAmKSpbpK8kWSZSn/kuzrK6sirKatdGDomIBsDPgp8RFGy718QBitHQ0YrZ2SrRcprObzjqSjpX7ytjxlw8oaktqAY4MIOqJsOx3cF8FDaay+y8E+0najrTZfc/Qyvs1HS9S1YXnFafgt5/FvgiPYvJpqMMU8b8E2QG5gl15XpKLHzYgjVaBrtQ0rolF2o6H+Hbsjx0KEtx9k/gLkvxne2Z7TUtbpJ08OI6Q/uQa91w1KA99AVn+Z5rYaoolsGyWENUXxwRLZJiouppvuLU3lbHsvXQ1bl7VGLC1aX01jja94a7WhAKiY88PIyvRTkRScWcm62On8eHdHpTUdOT4VfluQHfXQ0bHFzPYXc4i4Y8kO1fbqP5T26vjScgKkJd7BiqSpQ6coajCe6l5pgmUrV961554f+8Z4710x9rB/W30tk12jP18LpasKzLHI84P9c30ixMWZI948xzsB8esL8RCQTYd8dhkRU46I2YQj4uZcumn2biPi85kjnn5EiPSCfOoZIcRlSEw5JISYcEqIl7ftD9pQ4vBV/GQd9Iab+MeE/A6T4myuyAeYn3BUsLr7LBjWnn01/AU="),this.addDataEntry("table title",180,150,"Table with Title 2","7VhLc5swEP41XDs8ghtfwWl6cC9xpnfFLKAZITHSJpj8+q6EqJPaJG5aPw6ZwTP7lNnv034HgiRvNreatfUPVYAIkpsgybVSOFjNJgchgjjkRZAsgjgO6RfE3yaykcuGLdMg8ZCGeGh4YuIRhsg9exAwRA32wkdNzVprossmmUGmccWfbSwJKbBWEhmXoCkQOV8I1hruyheuouaiWLJePeJ40OhlJd9Acac647u16pZ0mPGtJR2+8i9j0/6lQSNsJgd3IT/1LagGUPdU0vECa19xPYAT1sCremxLfZCZIVD97t3iSIaHcj+syQ6sbyNKo9NYtdL82eIo/NwvUXZ+xxvBJHwHVvwRylTR+xCq1lsCSvTmg0JUjXe0HzfcS1ShVXvPdAVjScmFyJVQlluppOW/VVyiAyjN6CHI8vBLGqQ0WU5+tPXpseUacyUNaroj9lhgBjsweCiZ8X4yew+3p+w9bpP/QO3VDrXRJLc0AXIm7mCNTFZucWpshL/FXc0RVi1b29KOJGBYI2mrt2zsAf/vCFYEbSnsBVvUvChAjvSBvnmCgcWDlyp5d6mujoR7uoP7T2fG4YXjzwSvCPPFUJsZ+kMuq+XQOZsg6F/I2Lwm4uVSHIuc2afenVLvZifUu6871E5zexH79uF1mp1N264nte3CsT6etk2QcQZtm39q2ym1bX5CbYvCHW6Ty164D+/T/GziFkWT6nbhYB9P3SbYOL66kbv9uOByr749/AI="),this.addDataEntry("crossfunctional cross-functional cross functional flowchart swimlane table",400,400,"Cross-Functional Flowchart","7ZjRatswFIafxpcDy87a7nJJlvZig9HuBVT7JBLIOkZSGrtPPymS2622Gwc6z6WGXBz9HBnxfxz+cKJ0VVTXipbsB+YgovRblMTul64Uonk+N2pRrUAIW/M8StdR4vQkSjYDOsmxMy6pAmnOvZz4yw9U7MEr9oFaf9rsZWY4SuqaNwIPGaPK+GZtahGaNaOlKw29d9IyY1zk32mNe9OozWmpjf3CHX90/YvYNaMQtNT8eHXtFAXZXmn+ALegfaNToSqpzMNhi9LchQcQew7vB2Wg6vXjKL0w49mSa8ACjKrt+cBzw/ydRexdjBnwHTMvRKq9sHu62224FYPnp1mkLRZfM4PKSuR142/xYJ1gqPijdcci81a1DNcHXggq4QZoY2cjLTGvg2SwDJWArQnlPRqDRYMpGOLqXGH5i6odNMKWC7FCYd+driVKGBV0MhR03fD03zjFnST/kPuixf0noxq6uQdeg2n+aaMfOikhC/PaB+w/jmo6lGDVS/AJ1mgEP/cSTGaCpwiSiykgvOhFmM4ITyFMrqaA8LI3PzumcM7Pt8jPrtkdP0CvWuAnMLLjTuzle4zNLzO3c7lNIyxJPJM7l9w0MpKQ3pDs+J8zh+RbhGQX+fFDkrRXPR9uZsngRdCUYpK0F0MzuXcSlO3dzoxuUkl5FJudfOj4a3H/Gw=="),this.createVertexTemplateEntry("text;html=1;strokeColor=#c0c0c0;fillColor=#ffffff;overflow=fill;rounded=0;",280,160,'
Title 1Title 2Title 3
Value 1Value 2Value 3
Value 4Value 5Value 6
Value 7Value 8Value 9
Value 10Value 11Value 12
',"HTML Table 1"),this.createVertexTemplateEntry("text;html=1;strokeColor=#c0c0c0;fillColor=none;overflow=fill;",180,140,'
Value 1Value 2Value 3
Value 4Value 5Value 6
Value 7Value 8Value 9
',"HTML Table 2"),this.createVertexTemplateEntry("text;html=1;strokeColor=none;fillColor=none;overflow=fill;",180,140,'
Value 1Value 2Value 3
Value 4Value 5Value 6
Value 7Value 8Value 9
',"HTML Table 3"),this.createVertexTemplateEntry("text;html=1;strokeColor=none;fillColor=none;overflow=fill;",160,140,'
Title
Section 1.1\nSection 1.2\nSection 1.3
Section 2.1\nSection 2.2\nSection 2.3
',"HTML Table 4"),this.addEntry("link hyperlink",mxUtils.bind(this,function(){var t=new mxCell("Link",new mxGeometry(0,0,60,40),"text;html=1;strokeColor=none;fillColor=none;whiteSpace=wrap;align=center;verticalAlign=middle;fontColor=#0000EE;fontStyle=4;");return t.vertex=!0,this.graph.setLinkForCell(t,"https://www.draw.io"),this.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Link")})),this.addEntry("timestamp date time text label",mxUtils.bind(this,function(){var t=new mxCell("%date{ddd mmm dd yyyy HH:MM:ss}%",new mxGeometry(0,0,160,20),"text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;");return t.vertex=!0,this.graph.setAttributeForCell(t,"placeholders","1"),this.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Timestamp")})),this.addEntry("variable placeholder metadata hello world text label",mxUtils.bind(this,function(){var t=new mxCell("%name% Text",new mxGeometry(0,0,80,20),"text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;");return t.vertex=!0,this.graph.setAttributeForCell(t,"placeholders","1"),this.graph.setAttributeForCell(t,"name","Variable"),this.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Variable")})),this.createVertexTemplateEntry("shape=ext;double=1;rounded=0;whiteSpace=wrap;html=1;",120,80,"","Double Rectangle",null,null,"rect rectangle box double"),this.createVertexTemplateEntry("shape=ext;double=1;rounded=1;whiteSpace=wrap;html=1;",120,80,"","Double Rounded Rectangle",null,null,"rounded rect rectangle box double"),this.createVertexTemplateEntry("ellipse;shape=doubleEllipse;whiteSpace=wrap;html=1;",100,60,"","Double Ellipse",null,null,"oval ellipse start end state double"),this.createVertexTemplateEntry("shape=ext;double=1;whiteSpace=wrap;html=1;aspect=fixed;",80,80,"","Double Square",null,null,"double square"),this.createVertexTemplateEntry("ellipse;shape=doubleEllipse;whiteSpace=wrap;html=1;aspect=fixed;",80,80,"","Double Circle",null,null,"double circle"),this.createVertexTemplateEntry("rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillWeight=4;hachureGap=8;hachureAngle=45;fillColor=#1ba1e2;sketch=1;",120,60,"","Rectangle Sketch",!0,null,"rectangle rect box text sketch comic retro"),this.createVertexTemplateEntry("ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillWeight=2;hachureGap=8;fillColor=#990000;fillStyle=dots;sketch=1;",120,60,"","Ellipse Sketch",!0,null,"ellipse oval sketch comic retro"),this.createVertexTemplateEntry("rhombus;whiteSpace=wrap;html=1;strokeWidth=2;fillWeight=-1;hachureGap=8;fillStyle=cross-hatch;fillColor=#006600;sketch=1;",120,60,"","Diamond Sketch",!0,null,"diamond sketch comic retro"),this.createVertexTemplateEntry("html=1;whiteSpace=wrap;shape=isoCube2;backgroundOutline=1;isoAngle=15;",90,100,"","Isometric Cube",!0,null,"cube box iso isometric"),this.createVertexTemplateEntry("html=1;whiteSpace=wrap;aspect=fixed;shape=isoRectangle;",150,90,"","Isometric Square",!0,null,"rectangle rect box iso isometric"),this.createEdgeTemplateEntry("edgeStyle=isometricEdgeStyle;endArrow=none;html=1;",50,100,"","Isometric Edge 1"),this.createEdgeTemplateEntry("edgeStyle=isometricEdgeStyle;endArrow=none;html=1;elbow=vertical;",50,100,"","Isometric Edge 2"),this.createVertexTemplateEntry("shape=curlyBracket;whiteSpace=wrap;html=1;rounded=1;",20,120,"","Left Curly Bracket"),this.createVertexTemplateEntry("shape=curlyBracket;whiteSpace=wrap;html=1;rounded=1;flipH=1;",20,120,"","Right Curly Bracket"),this.createVertexTemplateEntry("line;strokeWidth=2;html=1;",160,10,"","Horizontal Line"),this.createVertexTemplateEntry("line;strokeWidth=2;direction=south;html=1;",10,160,"","Vertical Line"),this.createVertexTemplateEntry("line;strokeWidth=4;html=1;perimeter=backbonePerimeter;points=[];outlineConnect=0;",160,10,"","Horizontal Backbone",!1,null,"backbone bus network"),this.createVertexTemplateEntry("line;strokeWidth=4;direction=south;html=1;perimeter=backbonePerimeter;points=[];outlineConnect=0;",10,160,"","Vertical Backbone",!1,null,"backbone bus network"),this.createVertexTemplateEntry("shape=crossbar;whiteSpace=wrap;html=1;rounded=1;",120,20,"","Horizontal Crossbar",!1,null,"crossbar distance measure dimension unit"),this.createVertexTemplateEntry("shape=crossbar;whiteSpace=wrap;html=1;rounded=1;direction=south;",20,120,"","Vertical Crossbar",!1,null,"crossbar distance measure dimension unit"),this.createVertexTemplateEntry("shape=image;html=1;verticalLabelPosition=bottom;verticalAlign=top;imageAspect=1;aspect=fixed;image="+this.gearImage,52,61,"","Image (Fixed Aspect)",!1,null,"fixed image icon symbol"),this.createVertexTemplateEntry("shape=image;html=1;verticalLabelPosition=bottom;verticalAlign=top;imageAspect=0;image="+this.gearImage,50,60,"","Image (Variable Aspect)",!1,null,"strechted image icon symbol"),this.createVertexTemplateEntry("icon;html=1;image="+this.gearImage,60,60,"Icon","Icon",!1,null,"icon image symbol"),this.createVertexTemplateEntry("label;whiteSpace=wrap;html=1;image="+this.gearImage,140,60,"Label","Label 1",null,null,"label image icon symbol"),this.createVertexTemplateEntry("label;whiteSpace=wrap;html=1;align=center;verticalAlign=bottom;spacingLeft=0;spacingBottom=4;imageAlign=center;imageVerticalAlign=top;image="+this.gearImage,120,80,"Label","Label 2",null,null,"label image icon symbol"),this.addEntry("shape group container",function(){var t=new mxCell("Label",new mxGeometry(0,0,160,70),"html=1;whiteSpace=wrap;container=1;recursiveResize=0;collapsible=0;");t.vertex=!0;var e=new mxCell("",new mxGeometry(20,20,20,30),"triangle;html=1;whiteSpace=wrap;");return e.vertex=!0,t.insert(e),n.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Shape Group")}),this.createVertexTemplateEntry("shape=partialRectangle;whiteSpace=wrap;html=1;left=0;right=0;fillColor=none;",120,60,"","Partial Rectangle"),this.createVertexTemplateEntry("shape=partialRectangle;whiteSpace=wrap;html=1;bottom=0;top=0;fillColor=none;",120,60,"","Partial Rectangle"),this.createVertexTemplateEntry("shape=partialRectangle;whiteSpace=wrap;html=1;bottom=0;right=0;fillColor=none;",120,60,"","Partial Rectangle"),this.createVertexTemplateEntry("shape=partialRectangle;whiteSpace=wrap;html=1;bottom=1;right=1;left=1;top=0;fillColor=none;routingCenterX=-0.5;",120,60,"","Partial Rectangle"),this.createVertexTemplateEntry("shape=waypoint;sketch=0;fillStyle=solid;size=6;pointerEvents=1;points=[];fillColor=none;resizable=0;rotatable=0;perimeter=centerPerimeter;snapToPoint=1;",40,40,"","Waypoint"),this.createEdgeTemplateEntry("edgeStyle=segmentEdgeStyle;endArrow=classic;html=1;",50,50,"","Manual Line",null,e+"manual"),this.createEdgeTemplateEntry("shape=filledEdge;rounded=0;fixDash=1;endArrow=none;strokeWidth=10;fillColor=#ffffff;edgeStyle=orthogonalEdgeStyle;",60,40,"","Filled Edge"),this.createEdgeTemplateEntry("edgeStyle=elbowEdgeStyle;elbow=horizontal;endArrow=classic;html=1;",50,50,"","Horizontal Elbow",null,e+"elbow horizontal"),this.createEdgeTemplateEntry("edgeStyle=elbowEdgeStyle;elbow=vertical;endArrow=classic;html=1;",50,50,"","Vertical Elbow",null,e+"elbow vertical")];this.addPaletteFunctions("misc",mxResources.get("misc"),null==t||t,e),this.setCurrentSearchEntryLibrary()},Sidebar.prototype.addAdvancedPalette=function(t){this.setCurrentSearchEntryLibrary("general","advanced"),this.addPaletteFunctions("advanced",mxResources.get("advanced"),null!=t&&t,this.createAdvancedShapes()),this.setCurrentSearchEntryLibrary()},Sidebar.prototype.addBasicPalette=function(t){this.setCurrentSearchEntryLibrary("basic"),this.addStencilPalette("basic",mxResources.get("basic"),t+"/basic.xml",";whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;strokeWidth=2",null,null,null,null,[this.createVertexTemplateEntry("shape=partialRectangle;whiteSpace=wrap;html=1;top=0;bottom=0;fillColor=none;",120,60,"","Partial Rectangle"),this.createVertexTemplateEntry("shape=partialRectangle;whiteSpace=wrap;html=1;right=0;top=0;bottom=0;fillColor=none;routingCenterX=-0.5;",120,60,"","Partial Rectangle"),this.createVertexTemplateEntry("shape=partialRectangle;whiteSpace=wrap;html=1;bottom=0;right=0;fillColor=none;",120,60,"","Partial Rectangle"),this.createVertexTemplateEntry("shape=partialRectangle;whiteSpace=wrap;html=1;top=0;left=0;fillColor=none;",120,60,"","Partial Rectangle")]),this.setCurrentSearchEntryLibrary()},Sidebar.prototype.createAdvancedShapes=function(){var e=this,n=new mxCell("List Item",new mxGeometry(0,0,60,26),"text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;");return n.vertex=!0,[this.createVertexTemplateEntry("shape=tapeData;whiteSpace=wrap;html=1;perimeter=ellipsePerimeter;",80,80,"","Tape Data"),this.createVertexTemplateEntry("shape=manualInput;whiteSpace=wrap;html=1;",80,80,"","Manual Input"),this.createVertexTemplateEntry("shape=loopLimit;whiteSpace=wrap;html=1;",100,80,"","Loop Limit"),this.createVertexTemplateEntry("shape=offPageConnector;whiteSpace=wrap;html=1;",80,80,"","Off Page Connector"),this.createVertexTemplateEntry("shape=delay;whiteSpace=wrap;html=1;",80,40,"","Delay"),this.createVertexTemplateEntry("shape=display;whiteSpace=wrap;html=1;",80,40,"","Display"),this.createVertexTemplateEntry("shape=singleArrow;direction=west;whiteSpace=wrap;html=1;",100,60,"","Arrow Left"),this.createVertexTemplateEntry("shape=singleArrow;whiteSpace=wrap;html=1;",100,60,"","Arrow Right"),this.createVertexTemplateEntry("shape=singleArrow;direction=north;whiteSpace=wrap;html=1;",60,100,"","Arrow Up"),this.createVertexTemplateEntry("shape=singleArrow;direction=south;whiteSpace=wrap;html=1;",60,100,"","Arrow Down"),this.createVertexTemplateEntry("shape=doubleArrow;whiteSpace=wrap;html=1;",100,60,"","Double Arrow"),this.createVertexTemplateEntry("shape=doubleArrow;direction=south;whiteSpace=wrap;html=1;",60,100,"","Double Arrow Vertical",null,null,"double arrow"),this.createVertexTemplateEntry("shape=actor;whiteSpace=wrap;html=1;",40,60,"","User",null,null,"user person human"),this.createVertexTemplateEntry("shape=cross;whiteSpace=wrap;html=1;",80,80,"","Cross"),this.createVertexTemplateEntry("shape=corner;whiteSpace=wrap;html=1;",80,80,"","Corner"),this.createVertexTemplateEntry("shape=tee;whiteSpace=wrap;html=1;",80,80,"","Tee"),this.createVertexTemplateEntry("shape=datastore;whiteSpace=wrap;html=1;",60,60,"","Data Store",null,null,"data store cylinder database"),this.createVertexTemplateEntry("shape=orEllipse;perimeter=ellipsePerimeter;whiteSpace=wrap;html=1;backgroundOutline=1;",80,80,"","Or",null,null,"or circle oval ellipse"),this.createVertexTemplateEntry("shape=sumEllipse;perimeter=ellipsePerimeter;whiteSpace=wrap;html=1;backgroundOutline=1;",80,80,"","Sum",null,null,"sum circle oval ellipse"),this.createVertexTemplateEntry("shape=lineEllipse;perimeter=ellipsePerimeter;whiteSpace=wrap;html=1;backgroundOutline=1;",80,80,"","Ellipse with horizontal divider",null,null,"circle oval ellipse"),this.createVertexTemplateEntry("shape=lineEllipse;line=vertical;perimeter=ellipsePerimeter;whiteSpace=wrap;html=1;backgroundOutline=1;",80,80,"","Ellipse with vertical divider",null,null,"circle oval ellipse"),this.createVertexTemplateEntry("shape=sortShape;perimeter=rhombusPerimeter;whiteSpace=wrap;html=1;",80,80,"","Sort",null,null,"sort"),this.createVertexTemplateEntry("shape=collate;whiteSpace=wrap;html=1;",80,80,"","Collate",null,null,"collate"),this.createVertexTemplateEntry("shape=switch;whiteSpace=wrap;html=1;",60,60,"","Switch",null,null,"switch router"),this.addEntry("process bar",function(){return e.createVertexTemplateFromData("zZXRaoMwFIafJpcDjbNrb2233rRQ8AkyPdPQaCRJV+3T7yTG2rUVBoOtgpDzn/xJzncCIdGyateKNeVW5iBI9EqipZLS9KOqXYIQhAY8J9GKUBrgT+jbRDZ02aBhCmrzEwPtDZ9MHKBXdkpmoDWKCVN9VptO+Kw+8kqwGqMkK7nIN6yTB7uTNizbD1FSSsVPsjYMC1qFKHxwIZZSSIVxLZ1/nJNar5+oQPMT7IYCrqUta1ENzuqGaeOFTArBGs3f3Vmtoo2Se7ja1h00kSoHK4bBIKUNy3hdoPYU0mF91i9mT8EEL2ocZ3gKa00ayWujLZY4IfHKFonVDLsRGgXuQ90zBmWgneyTk3yT1iArMKrDKUeem9L3ajHrbSXwohxsQd/ggOleKM7ese048J2/fwuim1uQGmhQCW8vQMkacP3GCQgBFMftHEsr7cYYe95CnmKTPMFbYD8CQ++DGQy+/M5X4ku5wHYmdIktfvk9tecpavThqS3m/0YtnqIWPTy1cD77K2wYjo+Ay317I74A",296,100,"Process Bar")}),this.createVertexTemplateEntry("swimlane;",200,200,"Container","Container",null,null,"container swimlane lane pool group"),this.addEntry("list group erd table",function(){var t=new mxCell("List",new mxGeometry(0,0,140,110),"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;fillColor=none;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;");return t.vertex=!0,t.insert(e.cloneCell(n,"Item 1")),t.insert(e.cloneCell(n,"Item 2")),t.insert(e.cloneCell(n,"Item 3")),e.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"List")}),this.addEntry("list item entry value group erd table",function(){return e.createVertexTemplateFromCells([e.cloneCell(n,"List Item")],n.geometry.width,n.geometry.height,"List Item")})]},Sidebar.prototype.addUmlPalette=function(t){var s=this,e=new mxCell("+ field: type",new mxGeometry(0,0,100,26),"text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;");e.vertex=!0;var i=new mxCell("",new mxGeometry(0,0,40,8),"line;strokeWidth=1;fillColor=none;align=left;verticalAlign=middle;spacingTop=-1;spacingLeft=3;spacingRight=3;rotatable=0;labelPosition=right;points=[];portConstraint=eastwest;");i.vertex=!0;var n="uml static class ";this.setCurrentSearchEntryLibrary("uml");n=[this.createVertexTemplateEntry("html=1;",110,50,"Object","Object",null,null,n+"object instance"),this.createVertexTemplateEntry("html=1;",110,50,"«interface»
Name","Interface",null,null,n+"interface object instance annotated annotation"),this.addEntry(n+"object instance",function(){var t=new mxCell("Classname",new mxGeometry(0,0,160,90),"swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;");return t.vertex=!0,t.insert(e.clone()),t.insert(i.clone()),t.insert(s.cloneCell(e,"+ method(type): type")),s.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Class")}),this.addEntry(n+"section subsection",function(){var t=new mxCell("Classname",new mxGeometry(0,0,140,110),"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;fillColor=none;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;");return t.vertex=!0,t.insert(e.clone()),t.insert(e.clone()),t.insert(e.clone()),s.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Class 2")}),this.addEntry(n+"item member method function variable field attribute label",function(){return s.createVertexTemplateFromCells([s.cloneCell(e,"+ item: attribute")],e.geometry.width,e.geometry.height,"Item 1")}),this.addEntry(n+"item member method function variable field attribute label",function(){var t=new mxCell("item: attribute",new mxGeometry(0,0,120,e.geometry.height),"label;fontStyle=0;strokeColor=none;fillColor=none;align=left;verticalAlign=top;overflow=hidden;spacingLeft=28;spacingRight=4;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;imageWidth=16;imageHeight=16;image="+s.gearImage);return t.vertex=!0,s.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Item 2")}),this.addEntry(n+"divider hline line separator",function(){return s.createVertexTemplateFromCells([i.clone()],i.geometry.width,i.geometry.height,"Divider")}),this.addEntry(n+"spacer space gap separator",function(){var t=new mxCell("",new mxGeometry(0,0,20,14),"text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingTop=-1;spacingLeft=4;spacingRight=4;rotatable=0;labelPosition=right;points=[];portConstraint=eastwest;");return t.vertex=!0,s.createVertexTemplateFromCells([t.clone()],t.geometry.width,t.geometry.height,"Spacer")}),this.createVertexTemplateEntry("text;align=center;fontStyle=1;verticalAlign=middle;spacingLeft=3;spacingRight=3;strokeColor=none;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;",80,26,"Title","Title",null,null,n+"title label"),this.addEntry(n+"component",function(){var t=new mxCell("«Annotation»
Component",new mxGeometry(0,0,180,90),"html=1;dropTarget=0;");t.vertex=!0;var e=new mxCell("",new mxGeometry(1,0,20,20),"shape=module;jettyWidth=8;jettyHeight=4;");return e.vertex=!0,e.geometry.relative=!0,e.geometry.offset=new mxPoint(-27,7),t.insert(e),s.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Component")}),this.addEntry(n+"component",function(){var t=new mxCell('

Component


+ Attribute1: Type
+ Attribute2: Type

',new mxGeometry(0,0,180,90),"align=left;overflow=fill;html=1;dropTarget=0;");t.vertex=!0;var e=new mxCell("",new mxGeometry(1,0,20,20),"shape=component;jettyWidth=8;jettyHeight=4;");return e.vertex=!0,e.geometry.relative=!0,e.geometry.offset=new mxPoint(-24,4),t.insert(e),s.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Component with Attributes")}),this.createVertexTemplateEntry("verticalAlign=top;align=left;spacingTop=8;spacingLeft=2;spacingRight=12;shape=cube;size=10;direction=south;fontStyle=4;html=1;",180,120,"Block","Block",null,null,n+"block"),this.createVertexTemplateEntry("shape=module;align=left;spacingLeft=20;align=center;verticalAlign=top;",100,50,"Module","Module",null,null,n+"module component"),this.createVertexTemplateEntry("shape=folder;fontStyle=1;spacingTop=10;tabWidth=40;tabHeight=14;tabPosition=left;html=1;",70,50,"package","Package",null,null,n+"package"),this.createVertexTemplateEntry("verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;",160,90,'

Object:Type


field1 = value1
field2 = value2
field3 = value3

',"Object",null,null,n+"object instance"),this.createVertexTemplateEntry("verticalAlign=top;align=left;overflow=fill;html=1;",180,90,'
Tablename
PKuniqueId
FK1foreignKey
fieldname
',"Entity",null,null,"er entity table"),this.addEntry(n+"object instance",function(){var t=new mxCell('

Class


',new mxGeometry(0,0,140,60),"verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;");return t.vertex=!0,s.createVertexTemplateFromCells([t.clone()],t.geometry.width,t.geometry.height,"Class 3")}),this.addEntry(n+"object instance",function(){var t=new mxCell('

Class



',new mxGeometry(0,0,140,60),"verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;");return t.vertex=!0,s.createVertexTemplateFromCells([t.clone()],t.geometry.width,t.geometry.height,"Class 4")}),this.addEntry(n+"object instance",function(){var t=new mxCell('

Class


+ field: Type


+ method(): Type

',new mxGeometry(0,0,160,90),"verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;");return t.vertex=!0,s.createVertexTemplateFromCells([t.clone()],t.geometry.width,t.geometry.height,"Class 5")}),this.addEntry(n+"object instance",function(){var t=new mxCell('

<<Interface>>
Interface


+ field1: Type
+ field2: Type


+ method1(Type): Type
+ method2(Type, Type): Type

',new mxGeometry(0,0,190,140),"verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;");return t.vertex=!0,s.createVertexTemplateFromCells([t.clone()],t.geometry.width,t.geometry.height,"Interface 2")}),this.createVertexTemplateEntry("shape=providedRequiredInterface;html=1;verticalLabelPosition=bottom;",20,20,"","Provided/Required Interface",null,null,"uml provided required interface lollipop notation"),this.createVertexTemplateEntry("shape=requiredInterface;html=1;verticalLabelPosition=bottom;",10,20,"","Required Interface",null,null,"uml required interface lollipop notation"),this.addEntry("uml lollipop notation provided required interface",function(){return s.createVertexTemplateFromData("zVTBrptADPyavVYEkt4b0uQd3pMq5dD2uAUD27dgZJwE8vX1spsQlETtpVWRIjFjex3PmFVJWvc70m31hjlYlXxWSUqI7N/qPgVrVRyZXCUbFceR/FS8fRJdjNGo1QQN/0lB7AuO2h7AM57oeLCBIDw0Obj8SCVrJK6wxEbbV8RWyIWQP4F52Juzq9AHRqEqrm2IQpN/IsKTwAYb8MzWWBuO9B0hL2E2BGsqIQyxvJ9rzApD7QBrYBokhcBqNsf5UbrzsLzmXUu/oJET42jwGat5QYcHyiDkTDLKy03TiRrFfSx08m+FrrQtUkOZvZdbFKThmwMfVhf4fQ43/W3uZriiPPT+KKhjwnf4anKuQv//wsg+NPJ7/9d9Xf7eVykwbeeMOFWGYd/qzEVO8tHP/Suw4a2ujXV/+gXsEdhkOgSC8os44BQt0tggicZHeG1N2QiXibhAV48epRayEDd8MT7Ct06TUaXVWq027tCuhcx5VZjebeeaoDNn/WMcb/p+j0AM/dNr6InLl4Lgzylsk6OCgRWYsuI592gNZh5OhgmcblPv7+1l+ws=",40,10,"Lollipop Notation")}),this.createVertexTemplateEntry("shape=umlBoundary;whiteSpace=wrap;html=1;",100,80,"Boundary Object","Boundary Object",null,null,"uml boundary object"),this.createVertexTemplateEntry("ellipse;shape=umlEntity;whiteSpace=wrap;html=1;",80,80,"Entity Object","Entity Object",null,null,"uml entity object"),this.createVertexTemplateEntry("ellipse;shape=umlControl;whiteSpace=wrap;html=1;",70,80,"Control Object","Control Object",null,null,"uml control object"),this.createVertexTemplateEntry("shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;",30,60,"Actor","Actor",!1,null,"uml actor"),this.createVertexTemplateEntry("ellipse;whiteSpace=wrap;html=1;",140,70,"Use Case","Use Case",null,null,"uml use case usecase"),this.addEntry("uml activity state start",function(){var t=new mxCell("",new mxGeometry(0,0,30,30),"ellipse;html=1;shape=startState;fillColor=#000000;strokeColor=#ff0000;");t.vertex=!0;var e=new mxCell("",new mxGeometry(0,0,0,0),"edgeStyle=orthogonalEdgeStyle;html=1;verticalAlign=bottom;endArrow=open;endSize=8;strokeColor=#ff0000;");return e.geometry.setTerminalPoint(new mxPoint(15,90),!1),e.geometry.relative=!0,e.edge=!0,t.insertEdge(e,!0),s.createVertexTemplateFromCells([t,e],30,90,"Start")}),this.addEntry("uml activity state",function(){var t=new mxCell("Activity",new mxGeometry(0,0,120,40),"rounded=1;whiteSpace=wrap;html=1;arcSize=40;fontColor=#000000;fillColor=#ffffc0;strokeColor=#ff0000;");t.vertex=!0;var e=new mxCell("",new mxGeometry(0,0,0,0),"edgeStyle=orthogonalEdgeStyle;html=1;verticalAlign=bottom;endArrow=open;endSize=8;strokeColor=#ff0000;");return e.geometry.setTerminalPoint(new mxPoint(60,100),!1),e.geometry.relative=!0,e.edge=!0,t.insertEdge(e,!0),s.createVertexTemplateFromCells([t,e],120,100,"Activity")}),this.addEntry("uml activity composite state",function(){var t=new mxCell("Composite State",new mxGeometry(0,0,160,60),"swimlane;html=1;fontStyle=1;align=center;verticalAlign=middle;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=0;resizeLast=1;container=0;fontColor=#000000;collapsible=0;rounded=1;arcSize=30;strokeColor=#ff0000;fillColor=#ffffc0;swimlaneFillColor=#ffffc0;dropTarget=0;");t.vertex=!0;var e=new mxCell("Subtitle",new mxGeometry(0,0,200,26),"text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;spacingLeft=4;spacingRight=4;whiteSpace=wrap;overflow=hidden;rotatable=0;fontColor=#000000;");e.vertex=!0,t.insert(e);e=new mxCell("",new mxGeometry(0,0,0,0),"edgeStyle=orthogonalEdgeStyle;html=1;verticalAlign=bottom;endArrow=open;endSize=8;strokeColor=#ff0000;");return e.geometry.setTerminalPoint(new mxPoint(80,120),!1),e.geometry.relative=!0,e.edge=!0,t.insertEdge(e,!0),s.createVertexTemplateFromCells([t,e],160,120,"Composite State")}),this.addEntry("uml activity condition",function(){var t=new mxCell("Condition",new mxGeometry(0,0,80,40),"rhombus;whiteSpace=wrap;html=1;fillColor=#ffffc0;strokeColor=#ff0000;");t.vertex=!0;var e=new mxCell("no",new mxGeometry(0,0,0,0),"edgeStyle=orthogonalEdgeStyle;html=1;align=left;verticalAlign=bottom;endArrow=open;endSize=8;strokeColor=#ff0000;");e.geometry.setTerminalPoint(new mxPoint(180,20),!1),e.geometry.relative=!0,e.geometry.x=-1,e.edge=!0,t.insertEdge(e,!0);var n=new mxCell("yes",new mxGeometry(0,0,0,0),"edgeStyle=orthogonalEdgeStyle;html=1;align=left;verticalAlign=top;endArrow=open;endSize=8;strokeColor=#ff0000;");return n.geometry.setTerminalPoint(new mxPoint(40,100),!1),n.geometry.relative=!0,n.geometry.x=-1,n.edge=!0,t.insertEdge(n,!0),s.createVertexTemplateFromCells([t,e,n],180,100,"Condition")}),this.addEntry("uml activity fork join",function(){var t=new mxCell("",new mxGeometry(0,0,200,10),"shape=line;html=1;strokeWidth=6;strokeColor=#ff0000;");t.vertex=!0;var e=new mxCell("",new mxGeometry(0,0,0,0),"edgeStyle=orthogonalEdgeStyle;html=1;verticalAlign=bottom;endArrow=open;endSize=8;strokeColor=#ff0000;");return e.geometry.setTerminalPoint(new mxPoint(100,80),!1),e.geometry.relative=!0,e.edge=!0,t.insertEdge(e,!0),s.createVertexTemplateFromCells([t,e],200,80,"Fork/Join")}),this.createVertexTemplateEntry("ellipse;html=1;shape=endState;fillColor=#000000;strokeColor=#ff0000;",30,30,"","End",null,null,"uml activity state end"),this.createVertexTemplateEntry("shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;collapsible=0;recursiveResize=0;outlineConnect=0;",100,300,":Object","Lifeline",null,null,"uml sequence participant lifeline"),this.createVertexTemplateEntry("shape=umlLifeline;participant=umlActor;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;collapsible=0;recursiveResize=0;verticalAlign=top;spacingTop=36;outlineConnect=0;",20,300,"","Actor Lifeline",null,null,"uml sequence participant lifeline actor"),this.createVertexTemplateEntry("shape=umlLifeline;participant=umlBoundary;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;collapsible=0;recursiveResize=0;verticalAlign=top;spacingTop=36;outlineConnect=0;",50,300,"","Boundary Lifeline",null,null,"uml sequence participant lifeline boundary"),this.createVertexTemplateEntry("shape=umlLifeline;participant=umlEntity;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;collapsible=0;recursiveResize=0;verticalAlign=top;spacingTop=36;outlineConnect=0;",40,300,"","Entity Lifeline",null,null,"uml sequence participant lifeline entity"),this.createVertexTemplateEntry("shape=umlLifeline;participant=umlControl;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;collapsible=0;recursiveResize=0;verticalAlign=top;spacingTop=36;outlineConnect=0;",40,300,"","Control Lifeline",null,null,"uml sequence participant lifeline control"),this.createVertexTemplateEntry("shape=umlFrame;whiteSpace=wrap;html=1;",300,200,"frame","Frame",null,null,"uml sequence frame"),this.createVertexTemplateEntry("shape=umlDestroy;whiteSpace=wrap;html=1;strokeWidth=3;",30,30,"","Destruction",null,null,"uml sequence destruction destroy"),this.addEntry("uml sequence invoke invocation call activation",function(){var t=new mxCell("",new mxGeometry(0,0,10,80),"html=1;points=[];perimeter=orthogonalPerimeter;");t.vertex=!0;var e=new mxCell("dispatch",new mxGeometry(0,0,0,0),"html=1;verticalAlign=bottom;startArrow=oval;endArrow=block;startSize=8;");return e.geometry.setTerminalPoint(new mxPoint(-60,0),!0),e.geometry.relative=!0,e.edge=!0,t.insertEdge(e,!1),s.createVertexTemplateFromCells([t,e],10,80,"Found Message")}),this.addEntry("uml sequence invoke call delegation synchronous invocation activation",function(){var t=new mxCell("",new mxGeometry(0,0,10,80),"html=1;points=[];perimeter=orthogonalPerimeter;");t.vertex=!0;var e=new mxCell("dispatch",new mxGeometry(0,0,0,0),"html=1;verticalAlign=bottom;endArrow=block;entryX=0;entryY=0;");e.geometry.setTerminalPoint(new mxPoint(-70,0),!0),e.geometry.relative=!0,e.edge=!0,t.insertEdge(e,!1);var n=new mxCell("return",new mxGeometry(0,0,0,0),"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;exitX=0;exitY=0.95;");return n.geometry.setTerminalPoint(new mxPoint(-70,76),!1),n.geometry.relative=!0,n.edge=!0,t.insertEdge(n,!0),s.createVertexTemplateFromCells([t,e,n],10,80,"Synchronous Invocation")}),this.addEntry("uml sequence self call recursion delegation activation",function(){var t=new mxCell("",new mxGeometry(0,20,10,40),"html=1;points=[];perimeter=orthogonalPerimeter;");t.vertex=!0;var e=new mxCell("self call",new mxGeometry(0,0,0,0),"edgeStyle=orthogonalEdgeStyle;html=1;align=left;spacingLeft=2;endArrow=block;rounded=0;entryX=1;entryY=0;");return e.geometry.setTerminalPoint(new mxPoint(5,0),!0),e.geometry.points=[new mxPoint(30,0)],e.geometry.relative=!0,e.edge=!0,t.insertEdge(e,!1),s.createVertexTemplateFromCells([t,e],10,60,"Self Call")}),this.addEntry("uml sequence invoke call delegation callback activation",function(){return s.createVertexTemplateFromData("xZRNT8MwDIZ/Ta6oaymD47rBTkiTuMAxW6wmIm0q19s6fj1OE3V0Y2iCA4dK8euP2I+riGxedUuUjX52CqzIHkU2R+conKpuDtaKNDFKZAuRpgl/In264J303qSRCDVdk5CGhJ20WwhKEFo62ChoqritxURkReNMTa2X80LkC68AmgoIkEWHpF3pamlXR7WIFwASdBeb7KXY4RIc5+KBQ/ZGkY4RYY5Egyl1zLqLmmyDXQ6Zx4n5EIf+HkB2BmAjrV3LzftPIPw4hgNn1pQ1a2tH5Cp2QK1miG7vNeu4iJe4pdeY2BtvbCQDGlAljMCQxBJotJ8rWCFYSWY3LvUdmZi68rvkkLiU6QnL1m1xAzHoBOdw61WEb88II9AW67/ydQ2wq1Cy1aAGvOrFfPh6997qDA3g+dxzv3nIL6MPU/8T+kMw8+m4QPgdfrEJNo8PSQj/+s58Ag==",10,60,"Callback")}),this.createVertexTemplateEntry("html=1;points=[];perimeter=orthogonalPerimeter;",10,80,"","Activation",null,null,"uml sequence activation"),this.createVertexTemplateEntry("shape=partialRectangle;html=1;top=1;align=left;dashed=1;",200,20,"Template1 signature","Template signature",null,null,"template signature"),this.createVertexTemplateEntry("shape=partialRectangle;html=1;top=1;align=left;dashed=1;",200,50,"Template parameter 1\nTemplate parameter 2","Template signature",null,null,"template signature"),this.createVertexTemplateEntry("shape=note2;boundedLbl=1;whiteSpace=wrap;html=1;size=25;verticalAlign=top;align=center;",120,60,"Comment1 body","Note",null,null,"uml note"),this.addEntry("uml sequence self call recursion delegation activation",function(){var t=new mxCell("Constraint1 specification",new mxGeometry(0,0,160,60),"shape=note2;boundedLbl=1;whiteSpace=wrap;html=1;size=25;verticalAlign=top;align=center;");t.vertex=!0;var e=new mxCell("<>",new mxGeometry(0,0,t.geometry.width,25),"resizeWidth=1;part=1;strokeColor=none;fillColor=none;align=left;spacingLeft=5;");return e.geometry.relative=!0,e.vertex=!0,t.insert(e),s.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Note")}),this.addEntry(n+"classifier",function(){var t=new mxCell("<<keyword>>
Classifier1
{abstract}",new mxGeometry(0,0,140,183),"swimlane;fontStyle=0;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=55;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=0;marginBottom=0;html=1;");t.vertex=!0;var e=new mxCell("attributes",new mxGeometry(0,0,140,20),"text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;");e.vertex=!0,t.insert(e);e=new mxCell("attribute1",new mxGeometry(0,0,140,20),"text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;");e.vertex=!0,t.insert(e);e=new mxCell("inherited attribute2",new mxGeometry(0,0,140,20),"text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontColor=#808080;");e.vertex=!0,t.insert(e);e=new mxCell("...",new mxGeometry(0,0,140,20),"text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;");e.vertex=!0,t.insert(e),t.insert(i.clone());e=new mxCell("operations",new mxGeometry(0,0,140,20),"text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;");e.vertex=!0,t.insert(e);e=new mxCell("operation1",new mxGeometry(0,0,140,20),"text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;");return e.vertex=!0,t.insert(e),s.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Classifier")}),this.createVertexTemplateEntry("shape=process;fixedSize=1;size=5;fontStyle=1;",140,40,"Classifier1","Classifier",null,null,"classifier"),this.addEntry(n+"classifier",function(){var t=new mxCell("Classifier1",new mxGeometry(0,0,140,183),"swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=0;marginBottom=0;html=1;");t.vertex=!0;var e=new mxCell("internal structure",new mxGeometry(0,0,140,30),"html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;spacingLeft=4;spacingRight=4;rotatable=0;points=[[0,0.5],[1,0.5]];resizeWidth=1;");e.vertex=!0,t.insert(e);var n=new mxCell("",new mxGeometry(0,0,140,140),"strokeColor=none;fillColor=none;");n.vertex=!0,t.insert(n);var i=new mxCell("property1",new mxGeometry(0,0,100,30),"html=1;align=center;verticalAlign=middle;rotatable=0;");i.geometry.relative=!0,i.geometry.offset=new mxPoint(20,20),i.vertex=!0,n.insert(i);var l=new mxCell("property2",new mxGeometry(0,0,100,30),"html=1;align=center;verticalAlign=middle;rotatable=0;");l.geometry.relative=!0,l.geometry.offset=new mxPoint(20,90),l.vertex=!0,n.insert(l);e=new mxCell("connector1",new mxGeometry(0,0,0,0),"edgeStyle=none;endArrow=none;verticalAlign=middle;labelBackgroundColor=none;endSize=12;html=1;align=left;endFill=0;exitX=0.15;exitY=1;entryX=0.15;entryY=0;spacingLeft=4;");return e.geometry.relative=!0,e.edge=!0,i.insertEdge(e,!0),l.insertEdge(e,!1),n.insert(e),s.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Classifier")}),this.createVertexTemplateEntry("fontStyle=1;",140,30,"Association1","Association",null,null,"association"),this.addEntry(n+"classifier",function(){var t=new mxCell("Instance1",new mxGeometry(0,0,140,138),"swimlane;fontStyle=4;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=0;marginBottom=0;html=1;");t.vertex=!0;var e=new mxCell("slot1",new mxGeometry(0,0,140,30),"html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;rotatable=0;points=[[0,0.5],[1,0.5]];resizeWidth=1;");e.vertex=!0,t.insert(e),t.insert(i.clone());var n=new mxCell("internal structure",new mxGeometry(0,0,140,20),"html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;spacingLeft=4;spacingRight=4;rotatable=0;points=[[0,0.5],[1,0.5]];resizeWidth=1;");n.vertex=!0,t.insert(n);e=new mxCell("",new mxGeometry(0,0,140,50),"strokeColor=none;fillColor=none;");e.vertex=!0,t.insert(e);n=new mxCell("instance2",new mxGeometry(0,0,80,30),"html=1;align=center;verticalAlign=middle;rotatable=0;");return n.geometry.relative=!0,n.geometry.offset=new mxPoint(30,10),n.vertex=!0,e.insert(n),s.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Classifier")}),this.createVertexTemplateEntry("fontStyle=0;",120,40,"Instance1 value","Instance",null,null,"instance"),this.addEntry(n+"classifier",function(){var t=new mxCell("<<enumeration>>
Enum1",new mxGeometry(0,0,140,70),"swimlane;fontStyle=0;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=40;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=0;marginBottom=0;html=1;");t.vertex=!0;var e=new mxCell("literal1",new mxGeometry(0,0,140,30),"text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;");return e.vertex=!0,t.insert(e),s.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Classifier")}),this.addEntry(n+"classifier",function(){var t=new mxCell("0..1",new mxGeometry(0,0,120,50),"align=right;verticalAlign=top;spacingRight=2;");t.vertex=!0;var e=new mxCell("Property1",new mxGeometry(0,1,120,30),"text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;resizeWidth=1;");return e.geometry.relative=!0,e.geometry.offset=new mxPoint(0,-30),e.vertex=!0,t.insert(e),s.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Classifier")}),this.createVertexTemplateEntry("fontStyle=0;dashed=1;",140,30,"Property1","Property",null,null,"property"),this.createVertexTemplateEntry("fontStyle=0;labelPosition=right;verticalLabelPosition=middle;align=left;verticalAlign=middle;spacingLeft=2;",30,30,"port1","Port",null,null,"port"),this.addEntry(n+"component",function(){var t=new mxCell("",new mxGeometry(0,0,140,200),"fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;marginBottom=0;");t.vertex=!0;var e=new mxCell("Component",new mxGeometry(0,0,140,40),"html=1;align=left;spacingLeft=4;verticalAlign=top;strokeColor=none;fillColor=none;");e.vertex=!0,t.insert(e);var n=new mxCell("",new mxGeometry(1,0,16,20),"shape=module;jettyWidth=10;jettyHeight=4;");n.vertex=!0,n.geometry.relative=!0,n.geometry.offset=new mxPoint(-25,9),e.insert(n),t.insert(i.clone());n=new mxCell("provided interfaces",new mxGeometry(0,0,140,25),"html=1;align=center;spacingLeft=4;verticalAlign=top;strokeColor=none;fillColor=none;");n.vertex=!0,t.insert(n);n=new mxCell("Interface1",new mxGeometry(0,0,140,25),"html=1;align=left;spacingLeft=4;verticalAlign=top;strokeColor=none;fillColor=none;");n.vertex=!0,t.insert(n),t.insert(i.clone());n=new mxCell("required interfaces",new mxGeometry(0,0,140,25),"html=1;align=center;spacingLeft=4;verticalAlign=top;strokeColor=none;fillColor=none;");n.vertex=!0,t.insert(n);n=new mxCell("Interface2",new mxGeometry(0,0,140,30),"html=1;align=left;spacingLeft=4;verticalAlign=top;strokeColor=none;fillColor=none;");return n.vertex=!0,t.insert(n),s.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Component")}),this.addEntry(n+"classifier",function(){var t=new mxCell("",new mxGeometry(0,0,270,230),"shape=ellipse;container=1;horizontal=1;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;html=1;dashed=1;collapsible=0;");t.vertex=!0;var e=new mxCell("Collaboration1",new mxGeometry(0,0,270,30),"html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;spacingLeft=4;spacingRight=4;rotatable=0;points=[[0,0.5],[1,0.5]];resizeWidth=1;");e.vertex=!0,t.insert(e);var n=new mxCell("",new mxGeometry(.145,0,192,8),"line;strokeWidth=1;fillColor=none;rotatable=0;labelPosition=right;points=[];portConstraint=eastwest;dashed=1;resizeWidth=1;");n.geometry.relative=!0,n.geometry.offset=new mxPoint(0,30),n.vertex=!0,t.insert(n);var i=new mxCell("Classifier1",new mxGeometry(0,0,100,30),"html=1;align=center;verticalAlign=middle;rotatable=0;");i.geometry.relative=!0,i.geometry.offset=new mxPoint(85,50),i.vertex=!0,t.insert(i);e=new mxCell("Collaboration use 1",new mxGeometry(0,0,140,30),"shape=ellipse;html=1;align=center;verticalAlign=middle;rotatable=0;dashed=1;");e.geometry.relative=!0,e.geometry.offset=new mxPoint(65,110),e.vertex=!0,t.insert(e);n=new mxCell("property1",new mxGeometry(0,0,0,0),"edgeStyle=none;endArrow=none;verticalAlign=middle;labelBackgroundColor=none;endSize=12;html=1;align=left;endFill=0;spacingLeft=4;");n.geometry.relative=!0,n.edge=!0,i.insertEdge(n,!0),e.insertEdge(n,!1),t.insert(n);i=new mxCell("Classifier2",new mxGeometry(0,0,100,30),"html=1;align=center;verticalAlign=middle;rotatable=0;");i.geometry.relative=!0,i.geometry.offset=new mxPoint(85,170),i.vertex=!0,t.insert(i);n=new mxCell("property1",new mxGeometry(0,0,0,0),"edgeStyle=none;endArrow=none;verticalAlign=middle;labelBackgroundColor=none;endSize=12;html=1;align=left;endFill=0;spacingLeft=4;");return n.geometry.relative=!0,n.edge=!0,e.insertEdge(n,!0),i.insertEdge(n,!1),t.insert(n),s.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Classifier")}),this.createVertexTemplateEntry("shape=folder;fontStyle=1;tabWidth=80;tabHeight=30;tabPosition=left;html=1;boundedLbl=1;",150,80,"Package1","Package",null,null,n+"package"),this.addEntry(n+"package",function(){var t=new mxCell("Package1",new mxGeometry(0,0,150,100),"shape=folder;fontStyle=1;tabWidth=110;tabHeight=30;tabPosition=left;html=1;boundedLbl=1;labelInHeader=1;");t.vertex=!0;var e=new mxCell("Packaged element1",new mxGeometry(0,0,110,30),"html=1;");return e.geometry.relative=!0,e.geometry.offset=new mxPoint(20,50),e.vertex=!0,t.insert(e),s.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Classifier")}),this.addEntry(n+"package",function(){var t=new mxCell("Model1",new mxGeometry(0,0,150,80),"shape=folder;fontStyle=1;tabWidth=110;tabHeight=30;tabPosition=left;html=1;boundedLbl=1;folderSymbol=triangle;");return t.vertex=!0,s.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Package")}),this.addEntry(n+"stereotype",function(){var t=new mxCell("",new mxGeometry(0,0,160,75),"shape=note2;size=25;childLayout=stackLayout;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=0;marginBottom=0;html=1;container=1;");t.vertex=!0;var e=new mxCell("<<stereotype1>>",new mxGeometry(0,0,160,25),"text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;");e.vertex=!0,t.insert(e);e=new mxCell("stereotype property 1",new mxGeometry(0,0,160,25),"text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;");e.vertex=!0,t.insert(e);e=new mxCell("stereotype property 2",new mxGeometry(0,0,160,25),"text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;");return e.vertex=!0,t.insert(e),s.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Stereotype")}),this.addEntry(n+"class",function(){var t=new mxCell("Class1",new mxGeometry(0,0,140,79),"swimlane;fontStyle=1;align=center;verticalAlign=middle;childLayout=stackLayout;horizontal=1;startSize=29;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=0;marginBottom=0;html=1;");t.vertex=!0;var e=new mxCell("<<stereotype1>>",new mxGeometry(0,0,140,25),"text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;");e.vertex=!0,t.insert(e);e=new mxCell("stereotype property 1",new mxGeometry(0,0,140,25),"text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;");return e.vertex=!0,t.insert(e),s.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Class")}),this.createVertexTemplateEntry("text;html=1;align=center;",200,25,"<<stereotype1, stereotype2...>>","Label",null,null,n+"label"),this.createVertexTemplateEntry("ellipse;",50,25,"icon","Icon",null,null,n+"icon"),this.addEntry(n+"region",function(){var t=new mxCell("",new mxGeometry(60,0,10,100),"line;strokeWidth=1;direction=south;html=1;dashed=1;dashPattern=20 20;");t.vertex=!0;var e=new mxCell("Region 1",new mxGeometry(0,40,60,20),"text;align=right;");e.vertex=!0;var n=new mxCell("Region 2",new mxGeometry(70,40,60,20),"text;align=left;");return n.vertex=!0,s.createVertexTemplateFromCells([t,e,n],130,t.geometry.height,"Region")}),this.addEntry(n+"State",function(){var t=new mxCell("State1
[invariant1]
<<extended/final>>",new mxGeometry(0,0,140,176),"swimlane;fontStyle=4;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=60;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=0;marginBottom=0;html=1;rounded=1;absoluteArcSize=1;arcSize=50;");t.vertex=!0;var e=new mxCell("",new mxGeometry(0,0,140,50),"fillColor=none;strokeColor=none;container=1;collapsible=0;");e.vertex=!0,t.insert(e);var n=new mxCell("State2",new mxGeometry(30,10,80,30),"html=1;align=center;verticalAlign=middle;rounded=1;absoluteArcSize=1;arcSize=10;");n.vertex=!0,e.insert(n),t.insert(i.clone());n=new mxCell("behavior1",new mxGeometry(0,0,140,25),"fillColor=none;strokeColor=none;align=left;verticalAlign=middle;spacingLeft=5;");n.vertex=!0,t.insert(n),t.insert(i.clone());n=new mxCell("transition1",new mxGeometry(0,0,140,25),"fillColor=none;strokeColor=none;align=left;verticalAlign=middle;spacingLeft=5;");return n.vertex=!0,t.insert(n),s.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"State")}),this.createVertexTemplateEntry("html=1;align=center;verticalAlign=top;rounded=1;absoluteArcSize=1;arcSize=10;dashed=1;",140,40,"State1","State",null,null,n+"state"),this.createVertexTemplateEntry("html=1;align=center;verticalAlign=top;rounded=1;absoluteArcSize=1;arcSize=10;dashed=0;",140,40,"State","State",null,null,n+"state"),this.createVertexTemplateEntry("shape=folder;align=center;verticalAlign=middle;fontStyle=0;tabWidth=100;tabHeight=30;tabPosition=left;html=1;boundedLbl=1;labelInHeader=1;rounded=1;absoluteArcSize=1;arcSize=10;",140,90,"State1","State",null,null,n+"state"),this.createVertexTemplateEntry("html=1;align=center;verticalAlign=top;rounded=1;absoluteArcSize=1;arcSize=10;dashed=0;",140,40,"State1, State2, ...","State",null,null,n+"state"),this.createVertexTemplateEntry("shape=umlState;rounded=1;verticalAlign=top;spacingTop=5;umlStateSymbol=collapseState;absoluteArcSize=1;arcSize=10;",140,60,"State1","State",null,null,n+"state"),this.addEntry(n+"State",function(){var t=new mxCell("State1",new mxGeometry(40,0,140,50),"shape=umlState;rounded=1;verticalAlign=middle;align=center;absoluteArcSize=1;arcSize=10;umlStateConnection=connPointRefEntry;boundedLbl=1;");t.vertex=!0;var e=new mxCell("Entry1",new mxGeometry(0,40,50,20),"text;verticalAlign=middle;align=center;");return e.vertex=!0,t.insert(e),s.createVertexTemplateFromCells([t,e],180,60,"State")}),this.addEntry(n+"State",function(){var t=new mxCell("State1",new mxGeometry(40,0,140,50),"shape=umlState;rounded=1;verticalAlign=middle;spacingTop=0;absoluteArcSize=1;arcSize=10;umlStateConnection=connPointRefExit;boundedLbl=1;");t.vertex=!0;var e=new mxCell("Exit1",new mxGeometry(0,40,50,20),"text;verticalAlign=middle;align=center;");return e.vertex=!0,t.insert(e),s.createVertexTemplateFromCells([t,e],180,60,"State")}),this.createVertexTemplateEntry("ellipse;fillColor=#000000;strokeColor=none;",30,30,"","Initial state",null,null,n+"initial state"),this.createVertexTemplateEntry("ellipse;html=1;shape=endState;fillColor=#000000;strokeColor=#000000;",30,30,"","Final state",null,null,n+"final state"),this.createVertexTemplateEntry("ellipse;fillColor=#ffffff;strokeColor=#000000;",30,30,"H","Shallow History",null,null,n+"shallow history"),this.createVertexTemplateEntry("ellipse;fillColor=#ffffff;strokeColor=#000000;",30,30,"H*","Deep History",null,null,n+"deep history"),this.createVertexTemplateEntry("ellipse;fillColor=#ffffff;strokeColor=#000000;",30,30,"","Entry Point",null,null,n+"entry point"),this.createVertexTemplateEntry("shape=sumEllipse;perimeter=ellipsePerimeter;whiteSpace=wrap;html=1;backgroundOutline=1;",30,30,"","Exit Point",null,null,n+"exit point"),this.createVertexTemplateEntry("ellipse;fillColor=#000000;strokeColor=none;",20,20,"","Junction",null,null,n+"junction"),this.createVertexTemplateEntry("rhombus;",30,30,"","Choice",null,null,n+"choice"),this.createVertexTemplateEntry("shape=umlDestroy;",30,30,"","Terminate",null,null,n+"terminate"),this.createVertexTemplateEntry("html=1;points=[];perimeter=orthogonalPerimeter;fillColor=#000000;strokeColor=none;",5,80,"","Join/Fork",null,null,n+"join fork"),this.createVertexTemplateEntry("text;align=center;verticalAlign=middle;dashed=0;fillColor=#ffffff;strokeColor=#000000;",140,40,"OpaqueAction1 spec.","Opaque Action",null,null,n+"opaque action"),this.createEdgeTemplateEntry("html=1;verticalAlign=bottom;startArrow=oval;startFill=1;endArrow=block;startSize=8;",60,0,"dispatch","Found Message 1",null,"uml sequence message call invoke dispatch"),this.createEdgeTemplateEntry("html=1;verticalAlign=bottom;startArrow=circle;startFill=1;endArrow=open;startSize=6;endSize=8;",80,0,"dispatch","Found Message 2",null,"uml sequence message call invoke dispatch"),this.createEdgeTemplateEntry("html=1;verticalAlign=bottom;endArrow=block;",80,0,"dispatch","Message",null,"uml sequence message call invoke dispatch"),this.addEntry("uml sequence return message",function(){var t=new mxCell("return",new mxGeometry(0,0,0,0),"html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;");return t.geometry.setTerminalPoint(new mxPoint(80,0),!0),t.geometry.setTerminalPoint(new mxPoint(0,0),!1),t.geometry.relative=!0,t.edge=!0,s.createEdgeTemplateFromCells([t],80,0,"Return")}),this.addEntry("uml relation",function(){var t=new mxCell("name",new mxGeometry(0,0,0,0),"endArrow=block;endFill=1;html=1;edgeStyle=orthogonalEdgeStyle;align=left;verticalAlign=top;");t.geometry.setTerminalPoint(new mxPoint(0,0),!0),t.geometry.setTerminalPoint(new mxPoint(160,0),!1),t.geometry.relative=!0,t.geometry.x=-1,t.edge=!0;var e=new mxCell("1",new mxGeometry(-1,0,0,0),"edgeLabel;resizable=0;html=1;align=left;verticalAlign=bottom;");return e.geometry.relative=!0,e.setConnectable(!1),e.vertex=!0,t.insert(e),s.createEdgeTemplateFromCells([t],160,0,"Relation 1")}),this.addEntry("uml association",function(){var t=new mxCell("",new mxGeometry(0,0,0,0),"endArrow=none;html=1;edgeStyle=orthogonalEdgeStyle;");t.geometry.setTerminalPoint(new mxPoint(0,0),!0),t.geometry.setTerminalPoint(new mxPoint(160,0),!1),t.geometry.relative=!0,t.edge=!0;var e=new mxCell("parent",new mxGeometry(-1,0,0,0),"edgeLabel;resizable=0;html=1;align=left;verticalAlign=bottom;");e.geometry.relative=!0,e.setConnectable(!1),e.vertex=!0,t.insert(e);e=new mxCell("child",new mxGeometry(1,0,0,0),"edgeLabel;resizable=0;html=1;align=right;verticalAlign=bottom;");return e.geometry.relative=!0,e.setConnectable(!1),e.vertex=!0,t.insert(e),s.createEdgeTemplateFromCells([t],160,0,"Association 1")}),this.addEntry("uml aggregation",function(){var t=new mxCell("1",new mxGeometry(0,0,0,0),"endArrow=open;html=1;endSize=12;startArrow=diamondThin;startSize=14;startFill=0;edgeStyle=orthogonalEdgeStyle;align=left;verticalAlign=bottom;");return t.geometry.setTerminalPoint(new mxPoint(0,0),!0),t.geometry.setTerminalPoint(new mxPoint(160,0),!1),t.geometry.relative=!0,t.geometry.x=-1,t.geometry.y=3,t.edge=!0,s.createEdgeTemplateFromCells([t],160,0,"Aggregation 1")}),this.addEntry("uml composition",function(){var t=new mxCell("1",new mxGeometry(0,0,0,0),"endArrow=open;html=1;endSize=12;startArrow=diamondThin;startSize=14;startFill=1;edgeStyle=orthogonalEdgeStyle;align=left;verticalAlign=bottom;");return t.geometry.setTerminalPoint(new mxPoint(0,0),!0),t.geometry.setTerminalPoint(new mxPoint(160,0),!1),t.geometry.relative=!0,t.geometry.x=-1,t.geometry.y=3,t.edge=!0,s.createEdgeTemplateFromCells([t],160,0,"Composition 1")}),this.addEntry("uml relation",function(){var t=new mxCell("Relation",new mxGeometry(0,0,0,0),"endArrow=open;html=1;endSize=12;startArrow=diamondThin;startSize=14;startFill=0;edgeStyle=orthogonalEdgeStyle;");t.geometry.setTerminalPoint(new mxPoint(0,0),!0),t.geometry.setTerminalPoint(new mxPoint(160,0),!1),t.geometry.relative=!0,t.edge=!0;var e=new mxCell("0..n",new mxGeometry(-1,0,0,0),"edgeLabel;resizable=0;html=1;align=left;verticalAlign=top;");e.geometry.relative=!0,e.setConnectable(!1),e.vertex=!0,t.insert(e);e=new mxCell("1",new mxGeometry(1,0,0,0),"edgeLabel;resizable=0;html=1;align=right;verticalAlign=top;");return e.geometry.relative=!0,e.setConnectable(!1),e.vertex=!0,t.insert(e),s.createEdgeTemplateFromCells([t],160,0,"Relation 2")}),this.createEdgeTemplateEntry("endArrow=open;endSize=12;dashed=1;html=1;",160,0,"Use","Dependency",null,"uml dependency use"),this.createEdgeTemplateEntry("endArrow=block;endSize=16;endFill=0;html=1;",160,0,"Extends","Generalization",null,"uml generalization extend"),this.createEdgeTemplateEntry("endArrow=block;startArrow=block;endFill=1;startFill=1;html=1;",160,0,"","Association 2",null,"uml association"),this.createEdgeTemplateEntry("endArrow=open;startArrow=circlePlus;endFill=0;startFill=0;endSize=8;html=1;",160,0,"","Inner Class",null,"uml inner class"),this.createEdgeTemplateEntry("endArrow=open;startArrow=cross;endFill=0;startFill=0;endSize=8;startSize=10;html=1;",160,0,"","Terminate",null,"uml terminate"),this.createEdgeTemplateEntry("endArrow=block;dashed=1;endFill=0;endSize=12;html=1;",160,0,"","Implementation",null,"uml realization implementation"),this.createEdgeTemplateEntry("endArrow=diamondThin;endFill=0;endSize=24;html=1;",160,0,"","Aggregation 2",null,"uml aggregation"),this.createEdgeTemplateEntry("endArrow=diamondThin;endFill=1;endSize=24;html=1;",160,0,"","Composition 2",null,"uml composition"),this.createEdgeTemplateEntry("endArrow=open;endFill=1;endSize=12;html=1;",160,0,"","Association 3",null,"uml association")];this.addPaletteFunctions("uml",mxResources.get("uml"),t||!1,n),this.setCurrentSearchEntryLibrary()},Sidebar.prototype.addBpmnPalette=function(t,e){var n=this;this.setCurrentSearchEntryLibrary("bpmn");var i=[this.createVertexTemplateEntry("shape=ext;rounded=1;html=1;whiteSpace=wrap;",120,80,"Task","Process",null,null,"bpmn task process"),this.createVertexTemplateEntry("shape=ext;rounded=1;html=1;whiteSpace=wrap;double=1;",120,80,"Transaction","Transaction",null,null,"bpmn transaction"),this.createVertexTemplateEntry("shape=ext;rounded=1;html=1;whiteSpace=wrap;dashed=1;dashPattern=1 4;",120,80,"Event\nSub-Process","Event Sub-Process",null,null,"bpmn event subprocess sub process sub-process"),this.createVertexTemplateEntry("shape=ext;rounded=1;html=1;whiteSpace=wrap;strokeWidth=3;",120,80,"Call Activity","Call Activity",null,null,"bpmn call activity"),this.addEntry("bpmn subprocess sub process sub-process",function(){var t=new mxCell("Sub-Process",new mxGeometry(0,0,120,80),"html=1;whiteSpace=wrap;rounded=1;dropTarget=0;");t.vertex=!0;var e=new mxCell("",new mxGeometry(.5,1,14,14),"html=1;shape=plus;outlineConnect=0;");return e.vertex=!0,e.geometry.relative=!0,e.geometry.offset=new mxPoint(-7,-14),t.insert(e),n.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Sub-Process")}),this.addEntry(this.getTagsForStencil("mxgraph.bpmn","loop","subprocess sub process sub-process looped").join(" "),function(){var t=new mxCell("Looped\nSub-Process",new mxGeometry(0,0,120,80),"html=1;whiteSpace=wrap;rounded=1;dropTarget=0;");t.vertex=!0;var e=new mxCell("",new mxGeometry(.5,1,14,14),"html=1;shape=mxgraph.bpmn.loop;outlineConnect=0;");e.vertex=!0,e.geometry.relative=!0,e.geometry.offset=new mxPoint(-15,-14),t.insert(e);e=new mxCell("",new mxGeometry(.5,1,14,14),"html=1;shape=plus;");return e.vertex=!0,e.geometry.relative=!0,e.geometry.offset=new mxPoint(1,-14),t.insert(e),n.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Looped Sub-Process")}),this.addEntry("bpmn receive task",function(){var t=new mxCell("Receive",new mxGeometry(0,0,120,80),"html=1;whiteSpace=wrap;rounded=1;dropTarget=0;");t.vertex=!0;var e=new mxCell("",new mxGeometry(0,0,20,14),"html=1;shape=message;outlineConnect=0;");return e.vertex=!0,e.geometry.relative=!0,e.geometry.offset=new mxPoint(7,7),t.insert(e),n.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Receive Task")}),this.addEntry(this.getTagsForStencil("mxgraph.bpmn","user_task").join(" "),function(){var t=new mxCell("User",new mxGeometry(0,0,120,80),"html=1;whiteSpace=wrap;rounded=1;dropTarget=0;");t.vertex=!0;var e=new mxCell("",new mxGeometry(0,0,14,14),"html=1;shape=mxgraph.bpmn.user_task;outlineConnect=0;");e.vertex=!0,e.geometry.relative=!0,e.geometry.offset=new mxPoint(7,7),t.insert(e);e=new mxCell("",new mxGeometry(.5,1,14,14),"html=1;shape=plus;outlineConnect=0;");return e.vertex=!0,e.geometry.relative=!0,e.geometry.offset=new mxPoint(-7,-14),t.insert(e),n.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"User Task")}),this.addEntry(this.getTagsForStencil("mxgraph.bpmn","timer_start","attached").join(" "),function(){var t=new mxCell("Process",new mxGeometry(0,0,120,80),"html=1;whiteSpace=wrap;rounded=1;dropTarget=0;");t.vertex=!0;var e=new mxCell("",new mxGeometry(1,1,30,30),"shape=mxgraph.bpmn.timer_start;perimeter=ellipsePerimeter;html=1;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;");return e.vertex=!0,e.geometry.relative=!0,e.geometry.offset=new mxPoint(-40,-15),t.insert(e),n.createVertexTemplateFromCells([t],120,95,"Attached Timer Event 1")}),this.addEntry(this.getTagsForStencil("mxgraph.bpmn","timer_start","attached").join(" "),function(){var t=new mxCell("Process",new mxGeometry(0,0,120,80),"html=1;whiteSpace=wrap;rounded=1;dropTarget=0;");t.vertex=!0;var e=new mxCell("",new mxGeometry(1,0,30,30),"shape=mxgraph.bpmn.timer_start;perimeter=ellipsePerimeter;html=1;labelPosition=right;align=left;outlineConnect=0;");return e.vertex=!0,e.geometry.relative=!0,e.geometry.offset=new mxPoint(-15,10),t.insert(e),n.createVertexTemplateFromCells([t],135,80,"Attached Timer Event 2")}),this.createVertexTemplateEntry("swimlane;html=1;horizontal=0;startSize=20;",320,240,"Pool","Pool",null,null,"bpmn pool"),this.createVertexTemplateEntry("swimlane;html=1;horizontal=0;swimlaneLine=0;",300,120,"Lane","Lane",null,null,"bpmn lane"),this.createVertexTemplateEntry("shape=hexagon;html=1;whiteSpace=wrap;perimeter=hexagonPerimeter;rounded=0;",60,50,"","Conversation",null,null,"bpmn conversation"),this.createVertexTemplateEntry("shape=hexagon;html=1;whiteSpace=wrap;perimeter=hexagonPerimeter;strokeWidth=4;rounded=0;",60,50,"","Call Conversation",null,null,"bpmn call conversation"),this.addEntry("bpmn subconversation sub conversation sub-conversation",function(){var t=new mxCell("",new mxGeometry(0,0,60,50),"shape=hexagon;whiteSpace=wrap;html=1;perimeter=hexagonPerimeter;rounded=0;dropTarget=0;");t.vertex=!0;var e=new mxCell("",new mxGeometry(.5,1,14,14),"html=1;shape=plus;");return e.vertex=!0,e.geometry.relative=!0,e.geometry.offset=new mxPoint(-7,-14),t.insert(e),n.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Sub-Conversation")}),this.addEntry("bpmn data object",function(){var t=new mxCell("",new mxGeometry(0,0,40,60),"shape=note;whiteSpace=wrap;size=16;html=1;dropTarget=0;");t.vertex=!0;var e=new mxCell("",new mxGeometry(0,0,14,14),"html=1;shape=singleArrow;arrowWidth=0.4;arrowSize=0.4;outlineConnect=0;");e.vertex=!0,e.geometry.relative=!0,e.geometry.offset=new mxPoint(2,2),t.insert(e);e=new mxCell("",new mxGeometry(.5,1,14,14),"html=1;whiteSpace=wrap;shape=parallelMarker;outlineConnect=0;");return e.vertex=!0,e.geometry.relative=!0,e.geometry.offset=new mxPoint(-7,-14),t.insert(e),n.createVertexTemplateFromCells([t],t.geometry.width,t.geometry.height,"Data Object")}),this.createVertexTemplateEntry("shape=datastore;whiteSpace=wrap;html=1;",60,60,"","Data Store",null,null,"bpmn data store"),this.createVertexTemplateEntry("shape=plus;html=1;outlineConnect=0;",14,14,"","Sub-Process Marker",null,null,"bpmn subprocess sub process sub-process marker"),this.createVertexTemplateEntry("shape=mxgraph.bpmn.loop;html=1;outlineConnect=0;",14,14,"","Loop Marker",null,null,"bpmn loop marker"),this.createVertexTemplateEntry("shape=parallelMarker;html=1;outlineConnect=0;",14,14,"","Parallel MI Marker",null,null,"bpmn parallel mi marker"),this.createVertexTemplateEntry("shape=parallelMarker;direction=south;html=1;outlineConnect=0;",14,14,"","Sequential MI Marker",null,null,"bpmn sequential mi marker"),this.createVertexTemplateEntry("shape=mxgraph.bpmn.ad_hoc;fillColor=#000000;html=1;outlineConnect=0;",14,14,"","Ad Hoc Marker",null,null,"bpmn ad hoc marker"),this.createVertexTemplateEntry("shape=mxgraph.bpmn.compensation;html=1;outlineConnect=0;",14,14,"","Compensation Marker",null,null,"bpmn compensation marker"),this.createVertexTemplateEntry("shape=message;whiteSpace=wrap;html=1;outlineConnect=0;fillColor=#000000;strokeColor=#ffffff;strokeWidth=2;",40,30,"","Send Task",null,null,"bpmn send task"),this.createVertexTemplateEntry("shape=message;whiteSpace=wrap;html=1;outlineConnect=0;",40,30,"","Receive Task",null,null,"bpmn receive task"),this.createVertexTemplateEntry("shape=mxgraph.bpmn.user_task;html=1;outlineConnect=0;",14,14,"","User Task",null,null,this.getTagsForStencil("mxgraph.bpmn","user_task").join(" ")),this.createVertexTemplateEntry("shape=mxgraph.bpmn.manual_task;html=1;outlineConnect=0;",14,14,"","Manual Task",null,null,this.getTagsForStencil("mxgraph.bpmn","user_task").join(" ")),this.createVertexTemplateEntry("shape=mxgraph.bpmn.business_rule_task;html=1;outlineConnect=0;",14,14,"","Business Rule Task",null,null,this.getTagsForStencil("mxgraph.bpmn","business_rule_task").join(" ")),this.createVertexTemplateEntry("shape=mxgraph.bpmn.service_task;html=1;outlineConnect=0;",14,14,"","Service Task",null,null,this.getTagsForStencil("mxgraph.bpmn","service_task").join(" ")),this.createVertexTemplateEntry("shape=mxgraph.bpmn.script_task;html=1;outlineConnect=0;",14,14,"","Script Task",null,null,this.getTagsForStencil("mxgraph.bpmn","script_task").join(" ")),this.createVertexTemplateEntry("html=1;shape=mxgraph.flowchart.annotation_2;align=left;labelPosition=right;",50,100,"","Annotation",null,null,this.getTagsForStencil("bpmn","annotation_1","bpmn business process model ").join(" ")),this.addDataEntry("crossfunctional cross-functional cross functional flowchart swimlane table",400,400,"Cross-Functional Flowchart","7ZhRb5swEMc/DY+bMCRt97jQpi+tVC2fwINbbMnYyD4C6aefjaHpBrTRlNCoTALJPp9t+P25O5kgTvL6XtOCPaoMRBDfBXGilULfyusEhAiikGdBfBtEUWjvIFqPjJJmNCyoBonHTIj8hB0VJXiL3dyYL+tSpsiVpM55LVSVMqrROxvci9bZMFq4JtKfzrRKGRfZA92rEjtr11tpVT1wCcYOhM5ViTKXry0G7RYb/uwWXDgDw9wCuSW2WTGOsClo6gYri8uvIGhheLN1s4KGtNSG7+AHGL+Os0JdUJm1nUJxiaDvdhZQt/EvJXHTvpTbjAq+lbadgnO1hhYSaIR6FHRjainfg8oB9d66VDxD5j0WoRcjZMC3DP8yUuMN25e5B91so5VuWMa4J+P3FJW2JtLXrOK5oNLJxZTmz/blqXhNp3mO5cpe9smS8OsyWNp5ie2TQ99ezl1joqRBTXmDAajBCgxejprHKBcNK7fvBPIz3hOSRCcQctET8olRA+8JmSopIW2j8GOD6Sji8TDxepT4C9yTE1+OEo/mQ5xcTYn8ahR5PB/k0c2UyK9HC8SbX/mnLBAnqAlD8XK+onDTE+/fw+TiQF9fTin4Nl/O0xYAEs6X9LR5n5Ae6S7xv1lr/yf+4cQ/pN75Ej/pH88/UZyQkRPzR6R+0j9Bz4f0xMm/f8adD+qzZn/bPfw5bMb++LH4Gw=="),this.addDataEntry("container swimlane pool horizontal",480,380,"Horizontal Pool 1","zZRLbsIwEIZP4709TlHXhJYNSEicwCIjbNWJkWNKwumZxA6IlrRUaisWlmb+eX8LM5mXzdyrnV66Ai2TL0zm3rkQrbLJ0VoG3BRMzhgAp8fgdSQq+ijfKY9VuKcAYsG7snuMyso5G8U6tDaJ9cGUVlXkTXUoacuZIHOjjS0WqnX7blYd1OZt8KYea3PE1bCI+CAtVUMq7/o5b46uCmroSn18WFMm+XCdse5GpLq0OPqAzejxvZQun6MrMfiWUg6mCDpmZM8RENdotjqVyUFUdRS259oLSzISztto5Se0i44gcHEn3i9A/IQB3GbQpmi69DskAn4BSTaGBB4Jicj+k8nTGBP5SExg8odMyL38eH3s6kM8AQ=="),this.addDataEntry("container swimlane pool horizontal",480,360,"Horizontal Pool 2","zZTBbsIwDIafJvfU6dDOlI0LSEg8QUQtEi1tUBJGy9PPbcJQWTsxaZs4VLJ//07sT1WYKKpm6eRBrW2JhokXJgpnbYhR1RRoDAOuSyYWDIDTx+B1opr1VX6QDutwTwPEhndpjhiVjbUmij60Jon+pCsja8rmKlQ05SKjcKe0KVeytcfuLh/k7u2SzR16fcbNZZDsRlrLhlTenWedPts6SJMEOseFLTkph6Fj212RbGlwdAGbyeV7KW2+RFthcC1ZTroMKjry5wiIK9R7ldrELInSR2H/2XtlSUHCOY5WfEG76ggCz+7E+w2InzCAcQapIf0fAySzESQZ/AKSfAoJPCKS9mbzf0H0NIVIPDAiyP8QEaXX97CvDZ7LDw=="),this.createVertexTemplateEntry("swimlane;startSize=20;horizontal=0;",320,120,"Lane","Horizontal Swimlane",null,null,"swimlane lane pool"),this.addDataEntry("container swimlane pool horizontal",360,480,"Vertical Pool 1","xZRBbsIwEEVP4709ThFrQssGJKSewCIjbNXGyDEl4fSdxKa0NJFQVTULSzP/e+T5b2EmS9esgjrqja/QMvnMZBm8j6lyTYnWMuCmYnLJADgdBi8jruhdflQBD/GRAUgD78qeMClb720S69jaLNZn46w6ULfQ0dGWS0HlThtbrVXrT91bdVS7t2u3CFibC26vi4g7aaMaUjmpNBbiKxnUQyfkjTBEbEZT9VKOtELvMIaWrpxNFXW6IWcpOddo9jqPFfMsqjoJ+8/ZGyQqMqdhZvIHs3WHBrh4kNvvIsNw5Da7OdgXAgKGCMz+gEAxRgCmINDcxZ2CyNMYETkhESj+jwi1t1+r9759ah8="),this.addDataEntry("container swimlane pool vertical",380,480,"Vertical Pool 2","xZTPbsIwDMafJvf86dDOlI0LSEg8QUQtEi1pUBJGy9PPbdJ1G1TqhXGoZH/219g/RSGitM3ay5PaugoMEW9ElN65mCLblGAM4VRXRKwI5xQ/wt8nqqyv0pP0UMc5Bp4Mn9KcISk750wSQ2xNFsNFWyNrzJYqWpxyxTA8KG2qjWzduTsrRHn4GLKlh6CvsBsGYX+krWxQpaiizcc9FjDnnaCc11dXR2lyxyjsuyPy3/Lg4CM0k8v3Ut58Dc5C9C22XHQVVeoQrwkQVaCPKtuKQZQhCcdv78gSg4zzPlpxg3bTEeSUzcR7Q2bWyvz+ytmQr8NPAow/ikAxRYA/kQAr/hPByxQC8cxLsHggAkzH56uv/XrdvgA="),this.createVertexTemplateEntry("swimlane;startSize=20;",120,320,"Lane","Vertical Swimlane",null,null,"swimlane lane pool"),this.createVertexTemplateEntry("rounded=1;arcSize=10;dashed=1;strokeColor=#000000;fillColor=none;gradientColor=none;dashPattern=8 3 1 3;strokeWidth=2;",200,200,"","Group",null,null,this.getTagsForStencil("bpmn","group","bpmn business process model ").join(" ")),this.createEdgeTemplateEntry("endArrow=block;endFill=1;endSize=6;html=1;",100,0,"","Sequence Flow",null,"bpmn sequence flow"),this.createEdgeTemplateEntry("startArrow=dash;startSize=8;endArrow=block;endFill=1;endSize=6;html=1;",100,0,"","Default Flow",null,"bpmn default flow"),this.createEdgeTemplateEntry("startArrow=diamondThin;startFill=0;startSize=14;endArrow=block;endFill=1;endSize=6;html=1;",100,0,"","Conditional Flow",null,"bpmn conditional flow"),this.createEdgeTemplateEntry("startArrow=oval;startFill=0;startSize=7;endArrow=block;endFill=0;endSize=10;dashed=1;html=1;",100,0,"","Message Flow 1",null,"bpmn message flow"),this.addEntry("bpmn message flow",function(){var t=new mxCell("",new mxGeometry(0,0,0,0),"startArrow=oval;startFill=0;startSize=7;endArrow=block;endFill=0;endSize=10;dashed=1;html=1;");t.geometry.setTerminalPoint(new mxPoint(0,0),!0),t.geometry.setTerminalPoint(new mxPoint(100,0),!1),t.geometry.relative=!0,t.edge=!0;var e=new mxCell("",new mxGeometry(0,0,20,14),"shape=message;html=1;outlineConnect=0;");return e.geometry.relative=!0,e.vertex=!0,e.geometry.offset=new mxPoint(-10,-7),t.insert(e),n.createEdgeTemplateFromCells([t],100,0,"Message Flow 2")}),this.createEdgeTemplateEntry("shape=link;html=1;",100,0,"","Link",null,"bpmn link")];this.addPaletteFunctions("bpmn","BPMN "+mxResources.get("general"),!1,i),this.setCurrentSearchEntryLibrary()},Sidebar.prototype.createTitle=function(t){var e=document.createElement("a");return e.setAttribute("title",mxResources.get("sidebarTooltip")),e.className="geTitle",mxUtils.write(e,t),e},Sidebar.prototype.createThumb=function(t,e,n,i,l,s,o,r,a){this.graph.labelsVisible=null==s||s;var h=mxClient.NO_FO;mxClient.NO_FO=Editor.prototype.originalNoForeignObject,this.graph.view.scaleAndTranslate(1,0,0),this.graph.addCells(t);s=this.graph.getGraphBounds(),t=Math.floor(100*Math.min((e-2*this.thumbBorder)/s.width,(n-2*this.thumbBorder)/s.height))/100;this.graph.view.scaleAndTranslate(t,Math.floor((e-s.width*t)/2/t-s.x),Math.floor((n-s.height*t)/2/t-s.y));t=null;return this.graph.dialect!=mxConstants.DIALECT_SVG||mxClient.NO_FO||null==this.graph.view.getCanvas().ownerSVGElement?((t=this.graph.container.cloneNode(!1)).innerHTML=this.graph.container.innerHTML,!mxClient.IS_QUIRKS&&8!=document.documentMode||(t.firstChild.style.overflow="visible")):t=this.graph.view.getCanvas().ownerSVGElement.cloneNode(!0),this.graph.getModel().clear(),mxClient.NO_FO=h,mxClient.IS_IE6&&(i.style.backgroundImage="url("+this.editorUi.editor.transparentImage+")"),t.style.position="relative",t.style.overflow="hidden",t.style.left=this.thumbBorder+"px",t.style.top=this.thumbBorder+"px",t.style.width=e+"px",t.style.height=n+"px",t.style.visibility="",t.style.minWidth="",t.style.minHeight="",i.appendChild(t),this.sidebarTitles&&null!=l&&0!=o&&(o=mxClient.IS_QUIRKS?2*this.thumbPadding+2:0,i.style.height=this.thumbHeight+o+this.sidebarTitleSize+8+"px",(o=document.createElement("div")).style.fontSize=this.sidebarTitleSize+"px",o.style.color="#303030",o.style.textAlign="center",o.style.whiteSpace="nowrap",mxClient.IS_IE&&(o.style.height=this.sidebarTitleSize+12+"px"),o.style.paddingTop="4px",mxUtils.write(o,l),i.appendChild(o)),s},Sidebar.prototype.createItem=function(e,n,i,t,l,s,o){var r=document.createElement("a");r.className="geItem",r.style.overflow="hidden";var a=mxClient.IS_QUIRKS?8+2*this.thumbPadding:2*this.thumbBorder;r.style.width=this.thumbWidth+a+"px",r.style.height=this.thumbHeight+a+"px",r.style.padding=this.thumbPadding+"px",mxClient.IS_IE6&&(r.style.border="none"),mxEvent.addListener(r,"click",function(t){mxEvent.consume(t)}),this.createThumb(e,this.thumbWidth,this.thumbHeight,r,n,i,t,l,s);var h,d=new mxRectangle(0,0,l,s);return 1this.dropTargetDelay&&!this.isDropStyleTargetIgnored(s)&&(i.model.isVertex(s.cell)&&null!=f||i.model.isEdge(s.cell)&&i.model.isEdge(y[0]))?(w=s,r=new mxRectangle((r=i.model.isEdge(s.cell)?i.view.getPoint(s):new mxPoint(s.getCenterX(),s.getCenterY())).x-this.refreshTarget.width/2,r.y-this.refreshTarget.height/2,this.refreshTarget.width,this.refreshTarget.height),M.style.left=Math.floor(r.x)+"px",M.style.top=Math.floor(r.y)+"px",null==R&&(i.container.appendChild(M),R=M.parentNode),H(t,e,r,M)):null==w||!mxUtils.contains(w,t,e)||1500this.dropTargetDelay||i.model.isEdge(l)?s:null)&&r){for(var a,h,d,u,p,m=[P,U,T,A,L,I],c=0;cr||Math.abs(a.y-mxEvent.getClientY(t))>r)&&(this.dragElement.style.display="",mxUtils.setOpacity(e,100)),s.apply(this,arguments)},n.mouseUp=function(t){try{mxEvent.isPopupTrigger(t)||null!=this.currentGraph||null==this.dragElement||"none"!=this.dragElement.style.display||h.itemClicked(i,n,t,e),o.apply(n,arguments),mxUtils.setOpacity(e,100),a=null,h.currentElt=e}catch(t){n.reset(),h.editorUi.handleError(t)}}},Sidebar.prototype.createVertexTemplateEntry=function(t,e,n,i,l,s,o,r){return r=null!=r&&0l||Math.abs(x.point.y-e.getGraphY())>l)&&(null==(s=this.selectionCellsHandler.getHandler(a.cell))&&this.model.isEdge(a.cell)&&(s=this.createHandler(a)),null!=s&&null!=s.bends&&0'+n+""));return new mxImage("data:image/svg+xml;base64,"+(window.btoa?btoa(n):Base64.encode(n,!0)),t,e)},Graph.zapGremlins=function(t){for(var e=0,n=[],i=0;is&&"%"==e.charAt(match.index-1))r=o.substring(1);else{var a=o.substring(1,o.length-1);if("id"==a)r=t.id;else if(a.indexOf("{")<0)for(var h=t;null==r&&null!=h;)null!=h.value&&"object"==typeof h.value&&(Graph.translateDiagram&&null!=Graph.diagramLanguage&&(r=h.getAttribute(a+"_"+Graph.diagramLanguage)),null==r&&(r=h.hasAttribute(a)?null!=h.getAttribute(a)?h.getAttribute(a):"":null)),h=this.model.getParent(h);null==r&&(r=this.getGlobalVariable(a)),null==r&&null!=n&&(r=n[a])}l.push(e.substring(s,match.index)+(null!=r?r:o)),s=match.index+o.length}}l.push(e.substring(s))}return l.join("")},Graph.prototype.restoreSelection=function(t){if(null!=t&&0e.name?1:0});for(o=0;o"+s[o].name+": ":"")+mxUtils.htmlEntities(s[o].value)+"\n");0'+e+""))}}return e},Graph.prototype.stringToBytes=function(t){return Graph.stringToBytes(t)},Graph.prototype.bytesToString=function(t){return Graph.bytesToString(t)},Graph.prototype.compressNode=function(t){return Graph.compressNode(t)},Graph.prototype.compress=function(t,e){return Graph.compress(t,e)},Graph.prototype.decompress=function(t,e){return Graph.decompress(t,e)},Graph.prototype.zapGremlins=function(t){return Graph.zapGremlins(t)},HoverIcons=function(t){this.graph=t,this.init()},HoverIcons.prototype.arrowSpacing=2,HoverIcons.prototype.updateDelay=500,HoverIcons.prototype.activationDelay=140,HoverIcons.prototype.currentState=null,HoverIcons.prototype.activeArrow=null,HoverIcons.prototype.inactiveOpacity=15,HoverIcons.prototype.cssCursor="copy",HoverIcons.prototype.checkCollisions=!0,HoverIcons.prototype.arrowFill="#29b6f2",HoverIcons.prototype.triangleUp=mxClient.IS_SVG?Graph.createSvgImage(18,28,''):new mxImage(IMAGE_PATH+"/triangle-up.png",26,14),HoverIcons.prototype.triangleRight=mxClient.IS_SVG?Graph.createSvgImage(26,18,''):new mxImage(IMAGE_PATH+"/triangle-right.png",14,26),HoverIcons.prototype.triangleDown=mxClient.IS_SVG?Graph.createSvgImage(18,26,''):new mxImage(IMAGE_PATH+"/triangle-down.png",26,14),HoverIcons.prototype.triangleLeft=mxClient.IS_SVG?Graph.createSvgImage(28,18,''):new mxImage(IMAGE_PATH+"/triangle-left.png",14,26),HoverIcons.prototype.roundDrop=mxClient.IS_SVG?Graph.createSvgImage(26,26,''):new mxImage(IMAGE_PATH+"/round-drop.png",26,26),HoverIcons.prototype.refreshTarget=new mxImage(mxClient.IS_SVG?"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjM2cHgiIGhlaWdodD0iMzZweCI+PGVsbGlwc2UgZmlsbD0iIzI5YjZmMiIgY3g9IjEyIiBjeT0iMTIiIHJ4PSIxMiIgcnk9IjEyIi8+PHBhdGggdHJhbnNmb3JtPSJzY2FsZSgwLjgpIHRyYW5zbGF0ZSgyLjQsIDIuNCkiIHN0cm9rZT0iI2ZmZiIgZmlsbD0iI2ZmZiIgZD0iTTEyIDZ2M2w0LTQtNC00djNjLTQuNDIgMC04IDMuNTgtOCA4IDAgMS41Ny40NiAzLjAzIDEuMjQgNC4yNkw2LjcgMTQuOGMtLjQ1LS44My0uNy0xLjc5LS43LTIuOCAwLTMuMzEgMi42OS02IDYtNnptNi43NiAxLjc0TDE3LjMgOS4yYy40NC44NC43IDEuNzkuNyAyLjggMCAzLjMxLTIuNjkgNi02IDZ2LTNsLTQgNCA0IDR2LTNjNC40MiAwIDgtMy41OCA4LTggMC0xLjU3LS40Ni0zLjAzLTEuMjQtNC4yNnoiLz48cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+PC9zdmc+Cg==":IMAGE_PATH+"/refresh.png",38,38),HoverIcons.prototype.tolerance=mxClient.IS_TOUCH?6:0,HoverIcons.prototype.init=function(){this.arrowUp=this.createArrow(this.triangleUp,mxResources.get("plusTooltip")),this.arrowRight=this.createArrow(this.triangleRight,mxResources.get("plusTooltip")),this.arrowDown=this.createArrow(this.triangleDown,mxResources.get("plusTooltip")),this.arrowLeft=this.createArrow(this.triangleLeft,mxResources.get("plusTooltip")),this.elts=[this.arrowUp,this.arrowRight,this.arrowDown,this.arrowLeft],this.resetHandler=mxUtils.bind(this,function(){this.reset()}),this.repaintHandler=mxUtils.bind(this,function(){this.repaint()}),this.graph.selectionModel.addListener(mxEvent.CHANGE,this.resetHandler),this.graph.model.addListener(mxEvent.CHANGE,this.repaintHandler),this.graph.view.addListener(mxEvent.SCALE_AND_TRANSLATE,this.repaintHandler),this.graph.view.addListener(mxEvent.TRANSLATE,this.repaintHandler),this.graph.view.addListener(mxEvent.SCALE,this.repaintHandler),this.graph.view.addListener(mxEvent.DOWN,this.repaintHandler),this.graph.view.addListener(mxEvent.UP,this.repaintHandler),this.graph.addListener(mxEvent.ROOT,this.repaintHandler),this.graph.addListener(mxEvent.ESCAPE,this.resetHandler),mxEvent.addListener(this.graph.container,"scroll",this.resetHandler),this.graph.addListener(mxEvent.ESCAPE,mxUtils.bind(this,function(){this.mouseDownPoint=null})),mxEvent.addListener(this.graph.container,"mouseleave",mxUtils.bind(this,function(t){null!=t.relatedTarget&&mxEvent.getSource(t)==this.graph.container&&this.setDisplay("none")})),this.graph.addListener(mxEvent.START_EDITING,mxUtils.bind(this,function(t){this.reset()}));var e=this.graph.click;this.graph.click=mxUtils.bind(this,function(t){e.apply(this.graph,arguments),null==this.currentState||this.graph.isCellSelected(this.currentState.cell)||!mxEvent.isTouchEvent(t.getEvent())||this.graph.model.isVertex(t.getCell())||this.reset()});var i=!1;this.graph.addMouseListener({mouseDown:mxUtils.bind(this,function(t,e){i=!1;var n=e.getEvent();this.isResetEvent(n)?this.reset():this.isActive()||(null==(e=this.getState(e.getState()))&&mxEvent.isTouchEvent(n)||this.update(e)),this.setDisplay("none")}),mouseMove:mxUtils.bind(this,function(t,e){var n=e.getEvent();this.isResetEvent(n)?this.reset():this.graph.isMouseDown||mxEvent.isTouchEvent(n)||this.update(this.getState(e.getState()),e.getGraphX(),e.getGraphY()),null!=this.graph.connectionHandler&&null!=this.graph.connectionHandler.shape&&(i=!0)}),mouseUp:mxUtils.bind(this,function(t,e){var n=e.getEvent();mxUtils.convertPoint(this.graph.container,mxEvent.getClientX(n),mxEvent.getClientY(n));this.isResetEvent(n)?this.reset():this.isActive()&&!i&&null!=this.mouseDownPoint?this.click(this.currentState,this.getDirection(),e):this.isActive()?1==this.graph.getSelectionCount()&&this.graph.model.isEdge(this.graph.getSelectionCell())?this.reset():this.update(this.getState(this.graph.view.getState(this.graph.getCellAt(e.getGraphX(),e.getGraphY())))):mxEvent.isTouchEvent(n)||null!=this.bbox&&mxUtils.contains(this.bbox,e.getGraphX(),e.getGraphY())?(this.setDisplay(""),this.repaint()):mxEvent.isTouchEvent(n)||this.reset(),i=!1,this.resetActiveArrow()})})},HoverIcons.prototype.isResetEvent=function(t,e){return mxEvent.isAltDown(t)||null==this.activeArrow&&mxEvent.isShiftDown(t)||mxEvent.isPopupTrigger(t)&&!this.graph.isCloneEvent(t)},HoverIcons.prototype.createArrow=function(t,e){var n=null;return mxClient.IS_IE&&!mxClient.IS_SVG?(mxClient.IS_IE6&&"CSS1Compat"!=document.compatMode?((n=document.createElement(mxClient.VML_PREFIX+":image")).setAttribute("src",t.src),n.style.borderStyle="none"):((n=document.createElement("div")).style.backgroundImage="url("+t.src+")",n.style.backgroundPosition="center",n.style.backgroundRepeat="no-repeat"),n.style.width=t.width+4+"px",n.style.height=t.height+4+"px",n.style.display=mxClient.IS_QUIRKS?"inline":"inline-block"):((n=mxUtils.createImage(t.src)).style.width=t.width+"px",n.style.height=t.height+"px",n.style.padding=this.tolerance+"px"),null!=e&&n.setAttribute("title",e),n.style.position="absolute",n.style.cursor=this.cssCursor,mxEvent.addGestureListeners(n,mxUtils.bind(this,function(t){null==this.currentState||this.isResetEvent(t)||(this.mouseDownPoint=mxUtils.convertPoint(this.graph.container,mxEvent.getClientX(t),mxEvent.getClientY(t)),this.drag(t,this.mouseDownPoint.x,this.mouseDownPoint.y),this.activeArrow=n,this.setDisplay("none"),mxEvent.consume(t))})),mxEvent.redirectMouseEvents(n,this.graph,this.currentState),mxEvent.addListener(n,"mouseenter",mxUtils.bind(this,function(t){mxEvent.isMouseEvent(t)&&(null!=this.activeArrow&&this.activeArrow!=n&&mxUtils.setOpacity(this.activeArrow,this.inactiveOpacity),this.graph.connectionHandler.constraintHandler.reset(),mxUtils.setOpacity(n,100),this.activeArrow=n)})),mxEvent.addListener(n,"mouseleave",mxUtils.bind(this,function(t){this.graph.isMouseDown||this.resetActiveArrow()})),n},HoverIcons.prototype.resetActiveArrow=function(){null!=this.activeArrow&&(mxUtils.setOpacity(this.activeArrow,this.inactiveOpacity),this.activeArrow=null)},HoverIcons.prototype.getDirection=function(){var t=mxConstants.DIRECTION_EAST;return this.activeArrow==this.arrowUp?t=mxConstants.DIRECTION_NORTH:this.activeArrow==this.arrowDown?t=mxConstants.DIRECTION_SOUTH:this.activeArrow==this.arrowLeft&&(t=mxConstants.DIRECTION_WEST),t},HoverIcons.prototype.visitNodes=function(t){for(var e=0;ethis.activationDelay)&&this.currentState!=t&&(i>this.updateDelay&&null!=t||null==this.bbox||null==e||null==n||!mxUtils.contains(this.bbox,e,n))&&(null!=t&&this.graph.isEnabled()?(this.removeNodes(),this.setCurrentState(t),this.repaint(),this.graph.connectionHandler.constraintHandler.currentFocus!=t&&this.graph.connectionHandler.constraintHandler.reset()):this.reset()))},HoverIcons.prototype.setCurrentState=function(t){"eastwest"!=t.style.portConstraint&&(this.graph.container.appendChild(this.arrowUp),this.graph.container.appendChild(this.arrowDown)),this.graph.container.appendChild(this.arrowRight),this.graph.container.appendChild(this.arrowLeft),this.currentState=t},Graph.prototype.createParent=function(t,e,n,i,l){t=this.cloneCell(t);for(var s=0;sn||Math.abs(E.y-a.y)>n)&&(Math.abs(E.x-r.x)>n||Math.abs(E.y-r.y)>n)&&(Math.abs(E.x-x.x)>n||Math.abs(E.y-x.y)>n)&&(Math.abs(E.x-g.x)>n||Math.abs(E.y-g.y)>n)){for(var y=E.x-a.x,f=E.y-a.y,C={distSq:y*y+f*f,x:E.x,y:E.y},v=0;vC.distSq){h.splice(v,0,C),C=null;break}null==C||0!=h.length&&h[h.length-1].x===C.x&&h[h.length-1].y===C.y||h.push(C)}}}for(c=0;cl||!n&&0e&&n[i].deleteCell(e)},Graph.prototype.pasteHtmlAtCaret=function(t){var e,n;if(window.getSelection){if((e=window.getSelection()).getRangeAt&&e.rangeCount){(n=e.getRangeAt(0)).deleteContents();var i=document.createElement("div");i.innerHTML=t;for(var l,s=document.createDocumentFragment();l=i.firstChild;)lastNode=s.appendChild(l);n.insertNode(s)}}else(e=document.selection)&&"Control"!=e.type&&e.createRange().pasteHTML(t)},Graph.prototype.createLinkForHint=function(e,t){function n(t,e){return t.length>e&&(t=t.substring(0,Math.round(e/2))+"..."+t.substring(t.length-Math.round(e/4))),t}e=null!=e?e:"javascript:void(0);",null!=t&&0!=t.length||(t=this.isCustomLink(e)?this.getLinkTitle(e):e);var i=document.createElement("a");return i.setAttribute("rel",this.linkRelation),i.setAttribute("href",this.getAbsoluteUrl(e)),i.setAttribute("title",n(this.isCustomLink(e)?this.getLinkTitle(e):e,80)),null!=this.linkTarget&&i.setAttribute("target",this.linkTarget),mxUtils.write(i,n(t,40)),this.isCustomLink(e)&&mxEvent.addListener(i,"click",mxUtils.bind(this,function(t){this.customLinkClicked(e),mxEvent.consume(t)})),i},Graph.prototype.initTouch=function(){this.connectionHandler.marker.isEnabled=function(){return null!=this.graph.connectionHandler.first},this.addListener(mxEvent.START_EDITING,function(t,e){this.popupMenuHandler.hideMenu()});var n=this.updateMouseEvent,i=!(this.updateMouseEvent=function(t){var e;return t=n.apply(this,arguments),mxEvent.isTouchEvent(t.getEvent())&&null==t.getState()&&(null!=(e=this.getCellAt(t.graphX,t.graphY))&&this.isSwimlane(e)&&this.hitsSwimlaneContent(e,t.graphX,t.graphY)?e=null:(t.state=this.view.getState(e),null!=t.state&&null!=t.state.shape&&(this.container.style.cursor=t.state.shape.node.style.cursor))),null==t.getState()&&this.isEnabled()&&(this.container.style.cursor="default"),t}),l=!1,s=!1,o=this.fireMouseEvent;this.fireMouseEvent=function(t,e,n){t==mxEvent.MOUSE_DOWN&&(e=this.updateMouseEvent(e),i=this.isCellSelected(e.getCell()),l=this.isSelectionEmpty(),s=this.popupMenuHandler.isMenuShowing()),o.apply(this,arguments)},this.popupMenuHandler.mouseUp=mxUtils.bind(this,function(t,e){this.popupMenuHandler.popupTrigger=!this.isEditing()&&this.isEnabled()&&(null==e.getState()||!e.isSource(e.getState().control))&&(this.popupMenuHandler.popupTrigger||!s&&!mxEvent.isMouseEvent(e.getEvent())&&(l&&null==e.getCell()&&this.isSelectionEmpty()||i&&this.isCellSelected(e.getCell()))),mxPopupMenuHandler.prototype.mouseUp.apply(this.popupMenuHandler,arguments)})},mxCellEditor.prototype.isContentEditing=function(){var t=this.graph.view.getState(this.editingCell);return null!=t&&1==t.style.html},mxCellEditor.prototype.isTableSelected=function(){return null!=this.graph.getParentByName(this.graph.getSelectedElement(),"TABLE",this.textarea)},mxCellEditor.prototype.alignText=function(t,e){var n,i=null!=e&&mxEvent.isShiftDown(e);(i||null!=window.getSelection&&null!=window.getSelection().containsNode)&&(n=!0,this.graph.processElements(this.textarea,function(t){i||window.getSelection().containsNode(t,!0)?(t.removeAttribute("align"),t.style.textAlign=null):n=!1}),n&&this.graph.cellEditor.setAlign(t)),document.execCommand("justify"+t.toLowerCase(),!1,null)},mxCellEditor.prototype.saveSelection=function(){if(window.getSelection){var t=window.getSelection();if(t.getRangeAt&&t.rangeCount){for(var e=[],n=0,i=t.rangeCount;n")||0<=this.textarea.innerHTML.indexOf("\x3c!--[if !mso]>")?function t(e,n){if(null!=e)if(n.originalNode!=e)l(e);else for(e=e.firstChild,n=n.firstChild;null!=e;){var i=e.nextSibling;null==n?l(e):(t(e,n),n=n.nextSibling),e=i}}(this.textarea,e):Graph.removePasteFormatting(this.textarea))}),0)}))},mxCellEditor.prototype.toggleViewMode=function(){var t,e,n,i,l,s,o,r,a,h=this.graph.view.getState(this.editingCell);null!=h&&(t=null!=h&&"0"!=mxUtils.getValue(h.style,"nl2Br","1"),e=this.saveSelection(),this.codeViewMode?(0<(r=mxUtils.extractTextWithWhitespace(this.textarea.childNodes)).length&&"\n"==r.charAt(r.length-1)&&(r=r.substring(0,r.length-1)),r=this.graph.sanitizeHtml(t?r.replace(/\n/g,"
"):r,!0),this.textarea.className="mxCellEditor geContentEditable",a=mxUtils.getValue(h.style,mxConstants.STYLE_FONTSIZE,mxConstants.DEFAULT_FONTSIZE),n=mxUtils.getValue(h.style,mxConstants.STYLE_FONTFAMILY,mxConstants.DEFAULT_FONTFAMILY),i=mxUtils.getValue(h.style,mxConstants.STYLE_ALIGN,mxConstants.ALIGN_LEFT),l=(mxUtils.getValue(h.style,mxConstants.STYLE_FONTSTYLE,0)&mxConstants.FONT_BOLD)==mxConstants.FONT_BOLD,s=(mxUtils.getValue(h.style,mxConstants.STYLE_FONTSTYLE,0)&mxConstants.FONT_ITALIC)==mxConstants.FONT_ITALIC,o=[],(mxUtils.getValue(h.style,mxConstants.STYLE_FONTSTYLE,0)&mxConstants.FONT_UNDERLINE)==mxConstants.FONT_UNDERLINE&&o.push("underline"),(mxUtils.getValue(h.style,mxConstants.STYLE_FONTSTYLE,0)&mxConstants.FONT_STRIKETHROUGH)==mxConstants.FONT_STRIKETHROUGH&&o.push("line-through"),this.textarea.style.lineHeight=mxConstants.ABSOLUTE_LINE_HEIGHT?Math.round(a*mxConstants.LINE_HEIGHT)+"px":mxConstants.LINE_HEIGHT,this.textarea.style.fontSize=Math.round(a)+"px",this.textarea.style.textDecoration=o.join(" "),this.textarea.style.fontWeight=l?"bold":"normal",this.textarea.style.fontStyle=s?"italic":"",this.textarea.style.fontFamily=n,this.textarea.style.textAlign=i,this.textarea.style.padding="0px",this.textarea.innerHTML!=r&&(this.textarea.innerHTML=r,0==this.textarea.innerHTML.length&&(this.textarea.innerHTML=this.getEmptyLabelText(),this.clearOnChange=0
")),r=this.graph.sanitizeHtml(t?r.replace(/\n/g,"").replace(/<br\s*.?>/g,"
"):r,!0),this.textarea.className="mxCellEditor mxPlainTextEditor",a=mxConstants.DEFAULT_FONTSIZE,this.textarea.style.lineHeight=mxConstants.ABSOLUTE_LINE_HEIGHT?Math.round(a*mxConstants.LINE_HEIGHT)+"px":mxConstants.LINE_HEIGHT,this.textarea.style.fontSize=Math.round(a)+"px",this.textarea.style.textDecoration="",this.textarea.style.fontWeight="normal",this.textarea.style.fontStyle="",this.textarea.style.fontFamily=mxConstants.DEFAULT_FONTFAMILY,this.textarea.style.textAlign="left",this.textarea.style.padding="2px",this.textarea.innerHTML!=r&&(this.textarea.innerHTML=r),this.codeViewMode=!0),this.textarea.focus(),null!=this.switchSelectionState&&this.restoreSelection(this.switchSelectionState),this.switchSelectionState=e,this.resize())};var g=mxCellEditor.prototype.resize;mxCellEditor.prototype.resize=function(t,e){var n,i;null!=this.textarea&&(t=this.graph.getView().getState(this.editingCell),this.codeViewMode&&null!=t?(n=t.view.scale,this.bounds=mxRectangle.fromRectangle(t),0==this.bounds.width&&0==this.bounds.height&&(this.bounds.width=160*n,this.bounds.height=60*n,null==(i=null!=t.text?t.text.margin:null)&&(i=mxUtils.getAlignmentAsPoint(mxUtils.getValue(t.style,mxConstants.STYLE_ALIGN,mxConstants.ALIGN_CENTER),mxUtils.getValue(t.style,mxConstants.STYLE_VERTICAL_ALIGN,mxConstants.ALIGN_MIDDLE))),this.bounds.x+=i.x*this.bounds.width,this.bounds.y+=i.y*this.bounds.height),this.textarea.style.width=Math.round((this.bounds.width-4)/n)+"px",this.textarea.style.height=Math.round((this.bounds.height-4)/n)+"px",this.textarea.style.overflow="auto",this.textarea.clientHeight")),n=this.graph.sanitizeHtml(n,!0)},mxCellEditorGetCurrentValue=mxCellEditor.prototype.getCurrentValue,mxCellEditor.prototype.getCurrentValue=function(t){if("0"==mxUtils.getValue(t.style,"html","0"))return mxCellEditorGetCurrentValue.apply(this,arguments);var e=this.graph.sanitizeHtml(this.textarea.innerHTML,!0);return e="1"==mxUtils.getValue(t.style,"nl2Br","1")?e.replace(/\r\n/g,"
").replace(/\n/g,"
"):e.replace(/\r\n/g,"").replace(/\n/g,"")};var x=mxCellEditor.prototype.stopEditing;mxCellEditor.prototype.stopEditing=function(t){this.codeViewMode&&this.toggleViewMode(),x.apply(this,arguments),this.focusContainer()},mxCellEditor.prototype.focusContainer=function(){try{this.graph.container.focus()}catch(t){}};var y=mxCellEditor.prototype.applyValue;function f(){var t=document.createElement("div");return t.className="geHint",t.style.whiteSpace="nowrap",t.style.position="absolute",t}function C(t,e){switch(e){case mxConstants.POINTS:return t;case mxConstants.MILLIMETERS:return(t/mxConstants.PIXELS_PER_MM).toFixed(1);case mxConstants.INCHES:return(t/mxConstants.PIXELS_PER_INCH).toFixed(2)}}mxCellEditor.prototype.applyValue=function(t,e){this.graph.getModel().beginUpdate();try{y.apply(this,arguments),""==e&&this.graph.isCellDeletable(t.cell)&&0==this.graph.model.getChildCount(t.cell)&&this.graph.isTransparentState(t)&&this.graph.removeCells([t.cell],!1)}finally{this.graph.getModel().endUpdate()}},mxCellEditor.prototype.getBackgroundColor=function(t){var e=mxUtils.getValue(t.style,mxConstants.STYLE_LABEL_BACKGROUNDCOLOR,null);return null!=e&&e!=mxConstants.NONE||null==t.cell.geometry||!(0'):new mxImage(IMAGE_PATH+"/handle-main.png",17,17),HoverIcons.prototype.secondaryHandle=mxClient.IS_SVG?Graph.createSvgImage(16,16,''):new mxImage(IMAGE_PATH+"/handle-secondary.png",17,17),HoverIcons.prototype.fixedHandle=mxClient.IS_SVG?Graph.createSvgImage(18,18,''):new mxImage(IMAGE_PATH+"/handle-fixed.png",17,17),HoverIcons.prototype.terminalHandle=mxClient.IS_SVG?Graph.createSvgImage(18,18,''):new mxImage(IMAGE_PATH+"/handle-terminal.png",17,17),HoverIcons.prototype.rotationHandle=mxClient.IS_SVG?Graph.createSvgImage(16,16,'',24,24):new mxImage(IMAGE_PATH+"/handle-rotate.png",16,16),mxClient.IS_SVG&&(mxConstraintHandler.prototype.pointImage=Graph.createSvgImage(5,5,'')),mxVertexHandler.TABLE_HANDLE_COLOR="#fca000",mxVertexHandler.prototype.handleImage=HoverIcons.prototype.mainHandle,mxVertexHandler.prototype.secondaryHandleImage=HoverIcons.prototype.secondaryHandle,mxEdgeHandler.prototype.handleImage=HoverIcons.prototype.mainHandle,mxEdgeHandler.prototype.terminalHandleImage=HoverIcons.prototype.terminalHandle,mxEdgeHandler.prototype.fixedHandleImage=HoverIcons.prototype.fixedHandle,mxEdgeHandler.prototype.labelHandleImage=HoverIcons.prototype.secondaryHandle,mxOutline.prototype.sizerImage=HoverIcons.prototype.mainHandle,null!=window.Sidebar&&(Sidebar.prototype.triangleUp=HoverIcons.prototype.triangleUp,Sidebar.prototype.triangleRight=HoverIcons.prototype.triangleRight,Sidebar.prototype.triangleDown=HoverIcons.prototype.triangleDown,Sidebar.prototype.triangleLeft=HoverIcons.prototype.triangleLeft,Sidebar.prototype.refreshTarget=HoverIcons.prototype.refreshTarget,Sidebar.prototype.roundDrop=HoverIcons.prototype.roundDrop),mxClient.IS_SVG||((new Image).src=HoverIcons.prototype.mainHandle.src,(new Image).src=HoverIcons.prototype.fixedHandle.src,(new Image).src=HoverIcons.prototype.terminalHandle.src,(new Image).src=HoverIcons.prototype.secondaryHandle.src,(new Image).src=HoverIcons.prototype.rotationHandle.src,(new Image).src=HoverIcons.prototype.triangleUp.src,(new Image).src=HoverIcons.prototype.triangleRight.src,(new Image).src=HoverIcons.prototype.triangleDown.src,(new Image).src=HoverIcons.prototype.triangleLeft.src,(new Image).src=HoverIcons.prototype.refreshTarget.src,(new Image).src=HoverIcons.prototype.roundDrop.src),mxVertexHandler.prototype.rotationEnabled=!0,mxVertexHandler.prototype.manageSizers=!0,mxVertexHandler.prototype.livePreview=!0,mxGraphHandler.prototype.maxLivePreview=16,mxRubberband.prototype.defaultOpacity=30,mxConnectionHandler.prototype.outlineConnect=!0,mxCellHighlight.prototype.keepOnTop=!0,mxVertexHandler.prototype.parentHighlightEnabled=!0,mxEdgeHandler.prototype.parentHighlightEnabled=!0,mxEdgeHandler.prototype.dblClickRemoveEnabled=!0,mxEdgeHandler.prototype.straightRemoveEnabled=!0,mxEdgeHandler.prototype.virtualBendsEnabled=!0,mxEdgeHandler.prototype.mergeRemoveEnabled=!0,mxEdgeHandler.prototype.manageLabelHandle=!0,mxEdgeHandler.prototype.outlineConnect=!0,mxEdgeHandler.prototype.isAddVirtualBendEvent=function(t){return!mxEvent.isShiftDown(t.getEvent())},mxEdgeHandler.prototype.isCustomHandleEvent=function(t){return!mxEvent.isShiftDown(t.getEvent())},Graph.touchStyle?((mxClient.IS_TOUCH||0l||Math.abs(i)>l)&&(null==this.div&&(this.div=this.createShape()),mxUtils.clearSelection(),this.update(s,o),this.isSpaceEvent(e)?(l=this.x+this.width,s=this.y+this.height,o=this.graph.view.scale,mxEvent.isAltDown(e.getEvent())||(this.width=this.graph.snap(this.width/o)*o,this.height=this.graph.snap(this.height/o)*o,this.graph.isGridEnabled()||(this.width=this.state.absolutePoints.length-1||this.constructor==mxElbowEdgeHandler&&2==t)?this.graph.getConnectionConstraint(this.state,i,n):null,i=null!=(null!=t?this.graph.getConnectionPoint(this.state.getVisibleTerminalState(n),t):null)?this.fixedHandleImage:null!=t&&null!=i?this.terminalHandleImage:this.handleImage;if(null!=i){var l=new mxImageShape(new mxRectangle(0,0,i.width,i.height),i.src);return l.preserveImageAspect=!1,l}l=mxConstants.HANDLE_SIZE;return this.preferHtml&&--l,new mxRectangleShape(new mxRectangle(0,0,l,l),mxConstants.HANDLE_FILLCOLOR,mxConstants.HANDLE_STROKECOLOR)};var k=mxVertexHandler.prototype.createSizerShape;mxVertexHandler.prototype.createSizerShape=function(t,e,n){return this.handleImage=e==mxEvent.ROTATION_HANDLE?HoverIcons.prototype.rotationHandle:e==mxEvent.LABEL_HANDLE?this.secondaryHandleImage:this.handleImage,k.apply(this,arguments)};var V=mxGraphHandler.prototype.getBoundingBox;mxGraphHandler.prototype.getBoundingBox=function(t){if(null!=t&&1==t.length){var e=this.graph.getModel(),n=e.getParent(t[0]),i=this.graph.getCellGeometry(t[0]);if(e.isEdge(n)&&null!=i&&i.relative){i=this.graph.view.getState(t[0]);if(null!=i&&i.width<2&&i.height<2&&null!=i.text&&null!=i.text.boundingBox)return mxRectangle.fromRectangle(i.text.boundingBox)}}return V.apply(this,arguments)};var F=mxGraphHandler.prototype.getGuideStates;mxGraphHandler.prototype.getGuideStates=function(){for(var t=F.apply(this,arguments),e=[],n=0;n',!mxClient.IS_QUIRKS&&8!=document.documentMode||(m.firstChild.style.margin="0px"),null!=t&&t!=mxConstants.NONE?(a.setAttribute("checked","checked"),a.defaultChecked=!0,a.checked=!0):(a.removeAttribute("checked"),a.defaultChecked=!1,a.checked=!1),m.style.display=a.checked||r?"":"none",null!=o&&o(t),e||(u=t,(n||r||i()!=u)&&l(u)),p=!1)}var u=i(),p=!1,m=null;return(m=mxUtils.button("",mxUtils.bind(this,function(t){this.editorUi.pickColor(u,function(t){d(t,null,!0)}),mxEvent.consume(t)}))).style.position="absolute",m.style.marginTop="-4px",m.style.right=mxClient.IS_QUIRKS?"0px":"20px",m.style.height="22px",m.className="geColorBtn",m.style.display=a.checked||r?"":"none",n.appendChild(m),mxEvent.addListener(n,"click",function(t){t=mxEvent.getSource(t);t!=a&&"INPUT"==t.nodeName||(t!=a&&(a.checked=!a.checked),a.checked||null==u||u==mxConstants.NONE||s==mxConstants.NONE||(s=u),d(a.checked?s:mxConstants.NONE))}),d(u,!0),null!=e&&(e.install(d),this.listeners.push(e)),n},BaseFormatPanel.prototype.createCellColorOption=function(t,n,e,i,l){var s=this.editorUi,o=s.editor.graph;return this.createColorOption(t,function(){var t=o.view.getState(o.getSelectionCell());return null!=t?mxUtils.getValue(t.style,n,null):null},function(t){o.getModel().beginUpdate();try{o.setCellStyles(n,t,o.getSelectionCells()),null!=l&&l(t),s.fireEvent(new mxEventObject("styleChanged","keys",[n],"values",[t],"cells",o.getSelectionCells()))}finally{o.getModel().endUpdate()}},e||mxConstants.NONE,{install:function(e){this.listener=function(){var t=o.view.getState(o.getSelectionCell());null!=t&&e(mxUtils.getValue(t.style,n,null))},o.getModel().addListener(mxEvent.CHANGE,this.listener)},destroy:function(){o.getModel().removeListener(this.listener)}},i)},BaseFormatPanel.prototype.addArrow=function(t,e){e=null!=e?e:10;var n=document.createElement("div");n.style.display=mxClient.IS_QUIRKS?"inline":"inline-block",n.style.padding="6px",n.style.paddingRight="4px";var i=10-e;2==i?n.style.paddingTop="6px":0',mxUtils.setOpacity(n,70);e=t.getElementsByTagName("div")[0];return null!=e&&(e.style.paddingRight="6px",e.style.marginLeft="4px",e.style.marginTop="-1px",e.style.display=mxClient.IS_QUIRKS?"inline":"inline-block",mxUtils.setOpacity(e,60)),mxUtils.setOpacity(t,100),t.style.border="1px solid #a0a0a0",t.style.backgroundColor=this.buttonBackgroundColor,t.style.backgroundImage="none",t.style.width="auto",t.className+=" geColorBtn",mxUtils.setPrefixedStyle(t.style,"borderRadius","3px"),t.appendChild(n),e},BaseFormatPanel.prototype.addUnitInput=function(t,e,n,i,l,s,o,r,a){o=null!=o?o:0;var h=document.createElement("input");h.style.position="absolute",h.style.textAlign="right",h.style.marginTop="-2px",h.style.right=n+12+"px",h.style.width=i+"px",t.appendChild(h);a=this.createStepper(h,l,s,null,r,null,a);return a.style.marginTop=o-2+"px",a.style.right=n+"px",t.appendChild(a),h},BaseFormatPanel.prototype.createRelativeOption=function(t,i,e,l,n){e=null!=e?e:44;var s=this.editorUi.editor.graph,o=this.createPanel();o.style.paddingTop="10px",o.style.paddingBottom="10px",mxUtils.write(o,t),o.style.fontWeight="bold";var r,t=mxUtils.bind(this,function(t){var e,n;null!=l?l(a):(e=parseInt(a.value),e=Math.min(100,Math.max(0,isNaN(e)?100:e)),null!=(n=s.view.getState(s.getSelectionCell()))&&e!=mxUtils.getValue(n.style,i,100)&&(100==e&&(e=null),s.setCellStyles(i,e,s.getSelectionCells()),this.editorUi.fireEvent(new mxEventObject("styleChanged","keys",[i],"values",[e],"cells",s.getSelectionCells()))),a.value=(null!=e?e:"100")+" %"),mxEvent.consume(t)}),a=this.addUnitInput(o,"%",20,e,t,10,-15,null!=l);return null!=i&&(r=mxUtils.bind(this,function(t,e,n){!n&&a==document.activeElement||(n=this.format.getSelectionState(),n=parseInt(mxUtils.getValue(n.style,i,100)),a.value=isNaN(n)?"":n+" %")}),mxEvent.addListener(a,"keydown",function(t){13==t.keyCode?(s.container.focus(),mxEvent.consume(t)):27==t.keyCode&&(r(null,null,!0),s.container.focus(),mxEvent.consume(t))}),s.getModel().addListener(mxEvent.CHANGE,r),this.listeners.push({destroy:function(){s.getModel().removeListener(r)}}),r()),mxEvent.addListener(a,"blur",t),mxEvent.addListener(a,"change",t),null!=n&&n(a),o},BaseFormatPanel.prototype.addLabel=function(t,e,n,i){i=null!=i?i:61;var l=document.createElement("div");mxUtils.write(l,e),l.style.position="absolute",l.style.right=n+"px",l.style.width=i+"px",l.style.marginTop="6px",l.style.textAlign="center",t.appendChild(l)},BaseFormatPanel.prototype.addKeyHandler=function(t,e){mxEvent.addListener(t,"keydown",mxUtils.bind(this,function(t){13==t.keyCode?(this.editorUi.editor.graph.container.focus(),mxEvent.consume(t)):27==t.keyCode&&(null!=e&&e(null,null,!0),this.editorUi.editor.graph.container.focus(),mxEvent.consume(t))}))},BaseFormatPanel.prototype.styleButtons=function(t){for(var e=0;e=n.length||l[i]!=n[i].node||l[i]==n[i].node&&l[i].getAttribute("color")!=n[i].color){var s=l[i].firstChild;if(null!=s&&"A"==s.nodeName&&null==s.nextSibling&&null!=s.firstChild){l[i].parentNode.insertBefore(s,l[i]);for(e=s.firstChild;null!=e;){var o=e.nextSibling;l[i].appendChild(e),e=o}s.appendChild(l[i])}break}}else document.execCommand("forecolor",!1,t!=mxConstants.NONE?t:"transparent")},null!=n[mxConstants.STYLE_FONTCOLOR]?n[mxConstants.STYLE_FONTCOLOR]:"#000000",{install:function(t){V=t},destroy:function(){V=null}},null,!0):this.createCellColorOption(mxResources.get("fontColor"),mxConstants.STYLE_FONTCOLOR,null!=n[mxConstants.STYLE_FONTCOLOR]?n[mxConstants.STYLE_FONTCOLOR]:"#000000",function(t){t==mxConstants.NONE?B.style.display="none":B.style.display="",z.style.display=B.style.display},function(t){t==mxConstants.NONE?c.setCellStyles(mxConstants.STYLE_NOLABEL,"1",c.getSelectionCells()):c.setCellStyles(mxConstants.STYLE_NOLABEL,null,c.getSelectionCells()),c.updateCellStyles(mxConstants.STYLE_FONTCOLOR,t,c.getSelectionCells()),c.updateLabelElements(c.getSelectionCells(),function(t){t.removeAttribute("color"),t.style.color=null})});s.style.fontWeight="bold",l.appendChild(s),l.appendChild(B),c.cellEditor.isContentEditing()||l.appendChild(z),t.appendChild(l);P=this.createPanel();P.style.paddingTop="2px",P.style.paddingBottom="4px";n=this.createCellOption(mxResources.get("wordWrap"),mxConstants.STYLE_WHITE_SPACE,null,"wrap","null",null,null,!0);n.style.fontWeight="bold",g.containsLabel||g.autoSize||0!=g.edges.length||P.appendChild(n);s=this.createCellOption(mxResources.get("formattedText"),"html","0",null,null,null,e.actions.get("formattedText"));s.style.fontWeight="bold",P.appendChild(s);l=this.createPanel();l.style.paddingTop="10px",l.style.paddingBottom="28px",l.style.fontWeight="normal";n=document.createElement("div");n.style.position="absolute",n.style.width="70px",n.style.marginTop="0px",n.style.fontWeight="bold",mxUtils.write(n,mxResources.get("spacing")),l.appendChild(n);var Y=this.addUnitInput(l,"pt",91,44,function(){nt.apply(this,arguments)}),W=this.addUnitInput(l,"pt",20,44,function(){et.apply(this,arguments)});mxUtils.br(l),this.addLabel(l,mxResources.get("top"),91),this.addLabel(l,mxResources.get("global"),20),mxUtils.br(l),mxUtils.br(l);var j,X,Z,K=this.addUnitInput(l,"pt",162,44,function(){st.apply(this,arguments)}),Q=this.addUnitInput(l,"pt",91,44,function(){lt.apply(this,arguments)}),J=this.addUnitInput(l,"pt",20,44,function(){it.apply(this,arguments)});function q(t,e){mxClient.IS_IE&&(mxClient.IS_QUIRKS||document.documentMode<10)?t.style.filter=e?"progid:DXImageTransform.Microsoft.Gradient(StartColorStr='#c5ecff', EndColorStr='#87d4fb', GradientType=0)":"":t.style.backgroundImage=e?"linear-gradient(#c5ecff 0px,#87d4fb 100%)":""}mxUtils.br(l),this.addLabel(l,mxResources.get("left"),162),this.addLabel(l,mxResources.get("bottom"),91),this.addLabel(l,mxResources.get("right"),20),c.cellEditor.isContentEditing()?(X=j=null,t.appendChild(this.createRelativeOption(mxResources.get("lineheight"),null,null,function(t){var e=""==t.value?120:parseInt(t.value),e=Math.max(0,isNaN(e)?120:e);null!=j&&(c.cellEditor.restoreSelection(j),j=null);for(var n=c.getSelectedElement();null!=n&&n.nodeType!=mxConstants.NODETYPE_ELEMENT;)n=n.parentNode;null!=n&&n==c.cellEditor.textarea&&null!=c.cellEditor.textarea.firstChild&&("P"!=c.cellEditor.textarea.firstChild.nodeName&&(c.cellEditor.textarea.innerHTML="

"+c.cellEditor.textarea.innerHTML+"

"),n=c.cellEditor.textarea.firstChild),null!=n&&null!=c.cellEditor.textarea&&n!=c.cellEditor.textarea&&c.cellEditor.textarea.contains(n)&&(n.style.lineHeight=e+"%"),t.value=e+" %"},function(t){X=t,mxEvent.addListener(t,"mousedown",function(){document.activeElement==c.cellEditor.textarea&&(j=c.cellEditor.saveSelection())}),mxEvent.addListener(t,"touchstart",function(){document.activeElement==c.cellEditor.textarea&&(j=c.cellEditor.saveSelection())}),t.value="120 %"})),(s=i.cloneNode(!1)).style.paddingLeft="0px",n=this.editorUi.toolbar.addItems(["link","image"],s,!0),Z=[this.editorUi.toolbar.addButton("geSprite-horizontalrule",mxResources.get("insertHorizontalRule"),function(){document.execCommand("inserthorizontalrule",!1)},s),this.editorUi.toolbar.addMenuFunctionInContainer(s,"geSprite-table",mxResources.get("table"),!1,mxUtils.bind(this,function(t){this.editorUi.menus.addInsertTableItem(t)}))],this.styleButtons(n),this.styleButtons(Z),(n=this.createPanel()).style.paddingTop="10px",n.style.paddingBottom="10px",n.appendChild(this.createTitle(mxResources.get("insert"))),n.appendChild(s),t.appendChild(n),mxClient.IS_QUIRKS&&(n.style.height="70"),(s=i.cloneNode(!1)).style.paddingLeft="0px",Z=[this.editorUi.toolbar.addButton("geSprite-insertcolumnbefore",mxResources.get("insertColumnBefore"),mxUtils.bind(this,function(){try{null!=T&&c.insertColumn(T,null!=A?A.cellIndex:0)}catch(t){this.editorUi.handleError(t)}}),s),this.editorUi.toolbar.addButton("geSprite-insertcolumnafter",mxResources.get("insertColumnAfter"),mxUtils.bind(this,function(){try{null!=T&&c.insertColumn(T,null!=A?A.cellIndex+1:-1)}catch(t){this.editorUi.handleError(t)}}),s),this.editorUi.toolbar.addButton("geSprite-deletecolumn",mxResources.get("deleteColumn"),mxUtils.bind(this,function(){try{null!=T&&null!=A&&c.deleteColumn(T,A.cellIndex)}catch(t){this.editorUi.handleError(t)}}),s),this.editorUi.toolbar.addButton("geSprite-insertrowbefore",mxResources.get("insertRowBefore"),mxUtils.bind(this,function(){try{null!=T&&null!=L&&c.insertRow(T,L.sectionRowIndex)}catch(t){this.editorUi.handleError(t)}}),s),this.editorUi.toolbar.addButton("geSprite-insertrowafter",mxResources.get("insertRowAfter"),mxUtils.bind(this,function(){try{null!=T&&null!=L&&c.insertRow(T,L.sectionRowIndex+1)}catch(t){this.editorUi.handleError(t)}}),s),this.editorUi.toolbar.addButton("geSprite-deleterow",mxResources.get("deleteRow"),mxUtils.bind(this,function(){try{null!=T&&null!=L&&c.deleteRow(T,L.sectionRowIndex)}catch(t){this.editorUi.handleError(t)}}),s)],this.styleButtons(Z),Z[2].style.marginRight="9px",(n=this.createPanel()).style.paddingTop="10px",n.style.paddingBottom="10px",n.appendChild(this.createTitle(mxResources.get("table"))),n.appendChild(s),mxClient.IS_QUIRKS&&(mxUtils.br(t),n.style.height="70"),(i=i.cloneNode(!1)).style.paddingLeft="0px",Z=[this.editorUi.toolbar.addButton("geSprite-strokecolor",mxResources.get("borderColor"),mxUtils.bind(this,function(n){var t;null!=T&&(t=T.style.borderColor.replace(/\brgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/g,function(t,e,n,i){return"#"+("0"+Number(e).toString(16)).substr(-2)+("0"+Number(n).toString(16)).substr(-2)+("0"+Number(i).toString(16)).substr(-2)}),this.editorUi.pickColor(t,function(t){var e=null==A||null!=n&&mxEvent.isShiftDown(n)?T:A;c.processElements(e,function(t){t.style.border=null}),null==t||t==mxConstants.NONE?(e.removeAttribute("border"),e.style.border="",e.style.borderCollapse=""):(e.setAttribute("border","1"),e.style.border="1px solid "+t,e.style.borderCollapse="collapse")}))}),i),this.editorUi.toolbar.addButton("geSprite-fillcolor",mxResources.get("backgroundColor"),mxUtils.bind(this,function(n){var t;null!=T&&(t=T.style.backgroundColor.replace(/\brgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/g,function(t,e,n,i){return"#"+("0"+Number(e).toString(16)).substr(-2)+("0"+Number(n).toString(16)).substr(-2)+("0"+Number(i).toString(16)).substr(-2)}),this.editorUi.pickColor(t,function(t){var e=null==A||null!=n&&mxEvent.isShiftDown(n)?T:A;c.processElements(e,function(t){t.style.backgroundColor=null}),null==t||t==mxConstants.NONE?e.style.backgroundColor="":e.style.backgroundColor=t}))}),i),this.editorUi.toolbar.addButton("geSprite-fit",mxResources.get("spacing"),function(){var t;null!=T&&(t=T.getAttribute("cellPadding")||0,t=new FilenameDialog(e,t,mxResources.get("apply"),mxUtils.bind(this,function(t){null!=t&&0e.length+1)return t.substring(t.length-e.length-1,t.length)=="-"+e}return!1}null!=s&&(q(y[0],"bold"==s.fontWeight||400'+mxUtils.htmlEntities(mxResources.get("none"))+"","connector"==h.style.shape||"filledEdge"==h.style.shape?(this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],[mxConstants.ARROW_CLASSIC,1],"geIcon geSprite geSprite-startclassic",null,!1).setAttribute("title",mxResources.get("classic")),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],[mxConstants.ARROW_CLASSIC_THIN,1],"geIcon geSprite geSprite-startclassicthin",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],[mxConstants.ARROW_OPEN,0],"geIcon geSprite geSprite-startopen",null,!1).setAttribute("title",mxResources.get("openArrow")),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],[mxConstants.ARROW_OPEN_THIN,0],"geIcon geSprite geSprite-startopenthin",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],["openAsync",0],"geIcon geSprite geSprite-startopenasync",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],[mxConstants.ARROW_BLOCK,1],"geIcon geSprite geSprite-startblock",null,!1).setAttribute("title",mxResources.get("block")),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],[mxConstants.ARROW_BLOCK_THIN,1],"geIcon geSprite geSprite-startblockthin",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],["async",1],"geIcon geSprite geSprite-startasync",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],[mxConstants.ARROW_OVAL,1],"geIcon geSprite geSprite-startoval",null,!1).setAttribute("title",mxResources.get("oval")),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],[mxConstants.ARROW_DIAMOND,1],"geIcon geSprite geSprite-startdiamond",null,!1).setAttribute("title",mxResources.get("diamond")),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],[mxConstants.ARROW_DIAMOND_THIN,1],"geIcon geSprite geSprite-startthindiamond",null,!1).setAttribute("title",mxResources.get("diamondThin")),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],[mxConstants.ARROW_CLASSIC,0],"geIcon geSprite geSprite-startclassictrans",null,!1).setAttribute("title",mxResources.get("classic")),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],[mxConstants.ARROW_CLASSIC_THIN,0],"geIcon geSprite geSprite-startclassicthintrans",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],[mxConstants.ARROW_BLOCK,0],"geIcon geSprite geSprite-startblocktrans",null,!1).setAttribute("title",mxResources.get("block")),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],[mxConstants.ARROW_BLOCK_THIN,0],"geIcon geSprite geSprite-startblockthintrans",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],["async",0],"geIcon geSprite geSprite-startasynctrans",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],[mxConstants.ARROW_OVAL,0],"geIcon geSprite geSprite-startovaltrans",null,!1).setAttribute("title",mxResources.get("oval")),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],[mxConstants.ARROW_DIAMOND,0],"geIcon geSprite geSprite-startdiamondtrans",null,!1).setAttribute("title",mxResources.get("diamond")),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],[mxConstants.ARROW_DIAMOND_THIN,0],"geIcon geSprite geSprite-startthindiamondtrans",null,!1).setAttribute("title",mxResources.get("diamondThin")),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],["box",0],"geIcon geSprite geSvgSprite geSprite-box",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],["halfCircle",0],"geIcon geSprite geSvgSprite geSprite-halfCircle",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],["dash",0],"geIcon geSprite geSprite-startdash",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],["cross",0],"geIcon geSprite geSprite-startcross",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],["circlePlus",0],"geIcon geSprite geSprite-startcircleplus",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],["circle",1],"geIcon geSprite geSprite-startcircle",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],["ERone",0],"geIcon geSprite geSprite-starterone",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],["ERmandOne",0],"geIcon geSprite geSprite-starteronetoone",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],["ERmany",0],"geIcon geSprite geSprite-startermany",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],["ERoneToMany",0],"geIcon geSprite geSprite-starteronetomany",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],["ERzeroToOne",1],"geIcon geSprite geSprite-starteroneopt",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW,"startFill"],["ERzeroToMany",1],"geIcon geSprite geSprite-startermanyopt",null,!1)):this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_STARTARROW],[mxConstants.ARROW_BLOCK],"geIcon geSprite geSprite-startblocktrans",null,!1).setAttribute("title",mxResources.get("block")))})),T=this.editorUi.toolbar.addMenuFunctionInContainer(s,"geSprite-endclassic",mxResources.get("lineend"),!1,mxUtils.bind(this,function(t){var e;"connector"!=h.style.shape&&"flexArrow"!=h.style.shape&&"filledEdge"!=h.style.shape||((e=this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],[mxConstants.NONE,0],"geIcon",null,!1)).setAttribute("title",mxResources.get("none")),e.firstChild.firstChild.innerHTML=''+mxUtils.htmlEntities(mxResources.get("none"))+"","connector"==h.style.shape||"filledEdge"==h.style.shape?(this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],[mxConstants.ARROW_CLASSIC,1],"geIcon geSprite geSprite-endclassic",null,!1).setAttribute("title",mxResources.get("classic")),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],[mxConstants.ARROW_CLASSIC_THIN,1],"geIcon geSprite geSprite-endclassicthin",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],[mxConstants.ARROW_OPEN,0],"geIcon geSprite geSprite-endopen",null,!1).setAttribute("title",mxResources.get("openArrow")),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],[mxConstants.ARROW_OPEN_THIN,0],"geIcon geSprite geSprite-endopenthin",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],["openAsync",0],"geIcon geSprite geSprite-endopenasync",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],[mxConstants.ARROW_BLOCK,1],"geIcon geSprite geSprite-endblock",null,!1).setAttribute("title",mxResources.get("block")),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],[mxConstants.ARROW_BLOCK_THIN,1],"geIcon geSprite geSprite-endblockthin",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],["async",1],"geIcon geSprite geSprite-endasync",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],[mxConstants.ARROW_OVAL,1],"geIcon geSprite geSprite-endoval",null,!1).setAttribute("title",mxResources.get("oval")),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],[mxConstants.ARROW_DIAMOND,1],"geIcon geSprite geSprite-enddiamond",null,!1).setAttribute("title",mxResources.get("diamond")),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],[mxConstants.ARROW_DIAMOND_THIN,1],"geIcon geSprite geSprite-endthindiamond",null,!1).setAttribute("title",mxResources.get("diamondThin")),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],[mxConstants.ARROW_CLASSIC,0],"geIcon geSprite geSprite-endclassictrans",null,!1).setAttribute("title",mxResources.get("classic")),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],[mxConstants.ARROW_CLASSIC_THIN,0],"geIcon geSprite geSprite-endclassicthintrans",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],[mxConstants.ARROW_BLOCK,0],"geIcon geSprite geSprite-endblocktrans",null,!1).setAttribute("title",mxResources.get("block")),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],[mxConstants.ARROW_BLOCK_THIN,0],"geIcon geSprite geSprite-endblockthintrans",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],["async",0],"geIcon geSprite geSprite-endasynctrans",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],[mxConstants.ARROW_OVAL,0],"geIcon geSprite geSprite-endovaltrans",null,!1).setAttribute("title",mxResources.get("oval")),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],[mxConstants.ARROW_DIAMOND,0],"geIcon geSprite geSprite-enddiamondtrans",null,!1).setAttribute("title",mxResources.get("diamond")),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],[mxConstants.ARROW_DIAMOND_THIN,0],"geIcon geSprite geSprite-endthindiamondtrans",null,!1).setAttribute("title",mxResources.get("diamondThin")),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],["box",0],"geIcon geSprite geSvgSprite geFlipSprite geSprite-box",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],["halfCircle",0],"geIcon geSprite geSvgSprite geFlipSprite geSprite-halfCircle",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],["dash",0],"geIcon geSprite geSprite-enddash",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],["cross",0],"geIcon geSprite geSprite-endcross",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],["circlePlus",0],"geIcon geSprite geSprite-endcircleplus",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],["circle",1],"geIcon geSprite geSprite-endcircle",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],["ERone",0],"geIcon geSprite geSprite-enderone",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],["ERmandOne",0],"geIcon geSprite geSprite-enderonetoone",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],["ERmany",0],"geIcon geSprite geSprite-endermany",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],["ERoneToMany",0],"geIcon geSprite geSprite-enderonetomany",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],["ERzeroToOne",1],"geIcon geSprite geSprite-enderoneopt",null,!1),this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW,"endFill"],["ERzeroToMany",1],"geIcon geSprite geSprite-endermanyopt",null,!1)):this.editorUi.menus.edgeStyleChange(t,"",[mxConstants.STYLE_ENDARROW],[mxConstants.ARROW_BLOCK],"geIcon geSprite geSprite-endblocktrans",null,!1).setAttribute("title",mxResources.get("block")))}));this.addArrow(y,8),this.addArrow(w),this.addArrow(b),this.addArrow(T);o=this.addArrow(g,9);o.className="geIcon",o.style.width="auto";p=this.addArrow(f,9);p.className="geIcon",p.style.width="22px";var A=document.createElement("div");A.style.width="85px",A.style.height="1px",A.style.borderBottom="1px solid "+this.defaultStrokeColor,A.style.marginBottom="9px",o.appendChild(A);var L=document.createElement("div");L.style.width="23px",L.style.height="1px",L.style.borderBottom="1px solid "+this.defaultStrokeColor,L.style.marginBottom="9px",p.appendChild(L),g.style.height="15px",f.style.height="15px",y.style.height="15px",w.style.height="17px",b.style.marginLeft="3px",b.style.height="17px",T.style.marginLeft="3px",T.style.height="17px",t.appendChild(e),t.appendChild(x),t.appendChild(m);p=m.cloneNode(!1);p.style.paddingBottom="6px",p.style.paddingTop="4px",p.style.fontWeight="normal";g=document.createElement("div");g.style.position="absolute",g.style.marginLeft="3px",g.style.marginBottom="12px",g.style.marginTop="2px",g.style.fontWeight="normal",g.style.width="76px",mxUtils.write(g,mxResources.get("lineend")),p.appendChild(g);var I=this.addUnitInput(p,"pt",74,33,function(){D.apply(this,arguments)}),M=this.addUnitInput(p,"pt",20,33,function(){_.apply(this,arguments)});mxUtils.br(p);f=document.createElement("div");f.style.height="8px",p.appendChild(f),g=g.cloneNode(!1),mxUtils.write(g,mxResources.get("linestart")),p.appendChild(g);var R=this.addUnitInput(p,"pt",74,33,function(){H.apply(this,arguments)}),P=this.addUnitInput(p,"pt",20,33,function(){N.apply(this,arguments)});mxUtils.br(p),this.addLabel(p,mxResources.get("spacing"),74,50),this.addLabel(p,mxResources.get("size"),20,50),mxUtils.br(p);e=e.cloneNode(!1);e.style.fontWeight="normal",e.style.position="relative",e.style.paddingLeft="16px",e.style.marginBottom="2px",e.style.marginTop="6px",e.style.borderWidth="0px",e.style.paddingBottom="18px",(g=document.createElement("div")).style.position="absolute",g.style.marginLeft="3px",g.style.marginBottom="12px",g.style.marginTop="1px",g.style.fontWeight="normal",g.style.width="120px",mxUtils.write(g,mxResources.get("perimeter")),e.appendChild(g);var U=this.addUnitInput(e,"pt",20,41,function(){G.apply(this,arguments)});h.edges.length==a.getSelectionCount()?(t.appendChild(s),mxClient.IS_QUIRKS&&(mxUtils.br(t),mxUtils.br(t)),t.appendChild(p)):h.vertices.length==a.getSelectionCount()&&(mxClient.IS_QUIRKS&&mxUtils.br(t),t.appendChild(e));var O=mxUtils.bind(this,function(t,e,n){h=this.format.getSelectionState();mxUtils.getValue(h.style,u,null);!n&&document.activeElement==C||(s=parseInt(mxUtils.getValue(h.style,mxConstants.STYLE_STROKEWIDTH,1)),C.value=isNaN(s)?"":s+" pt"),!n&&document.activeElement==v||(s=parseInt(mxUtils.getValue(h.style,mxConstants.STYLE_STROKEWIDTH,1)),v.value=isNaN(s)?"":s+" pt"),d.style.visibility="connector"==h.style.shape||"filledEdge"==h.style.shape?"":"hidden","1"==mxUtils.getValue(h.style,mxConstants.STYLE_CURVED,null)?d.value="curved":"1"==mxUtils.getValue(h.style,mxConstants.STYLE_ROUNDED,null)&&(d.value="rounded"),"1"==mxUtils.getValue(h.style,mxConstants.STYLE_DASHED,null)?null==mxUtils.getValue(h.style,mxConstants.STYLE_DASH_PATTERN,null)?A.style.borderBottom="1px dashed "+this.defaultStrokeColor:A.style.borderBottom="1px dotted "+this.defaultStrokeColor:A.style.borderBottom="1px solid "+this.defaultStrokeColor,L.style.borderBottom=A.style.borderBottom;var i=w.getElementsByTagName("div")[0];null!=i&&(o=mxUtils.getValue(h.style,mxConstants.STYLE_EDGE,null),"1"==mxUtils.getValue(h.style,mxConstants.STYLE_NOEDGESTYLE,null)&&(o=null),"orthogonalEdgeStyle"==o&&"1"==mxUtils.getValue(h.style,mxConstants.STYLE_CURVED,null)?i.className="geSprite geSprite-curved":i.className="straight"==o||"none"==o||null==o?"geSprite geSprite-straight":"entityRelationEdgeStyle"==o?"geSprite geSprite-entity":"elbowEdgeStyle"==o?"geSprite "+("vertical"==mxUtils.getValue(h.style,mxConstants.STYLE_ELBOW,null)?"geSprite-verticalelbow":"geSprite-horizontalelbow"):"isometricEdgeStyle"==o?"geSprite "+("vertical"==mxUtils.getValue(h.style,mxConstants.STYLE_ELBOW,null)?"geSprite-verticalisometric":"geSprite-horizontalisometric"):"geSprite geSprite-orthogonal");i=y.getElementsByTagName("div")[0];function l(t,e,n,i){n=n.getElementsByTagName("div")[0];return null!=n&&(n.className=r.getCssClassForMarker(i,h.style.shape,t,e),"geSprite geSprite-noarrow"==n.className&&(n.innerHTML=mxUtils.htmlEntities(mxResources.get("none")),n.style.backgroundImage="none",n.style.verticalAlign="top",n.style.marginTop="5px",n.style.fontSize="10px",n.style.filter="none",n.style.color=this.defaultStrokeColor,n.nextSibling.style.marginTop="0px")),n}null!=i&&("link"==h.style.shape?i.className="geSprite geSprite-linkedge":"flexArrow"==h.style.shape?i.className="geSprite geSprite-arrow":"arrow"==h.style.shape?i.className="geSprite geSprite-simplearrow":i.className="geSprite geSprite-connection"),h.edges.length==a.getSelectionCount()?(x.style.display="",m.style.display="none"):(x.style.display="none",m.style.display="");var s,o=l(mxUtils.getValue(h.style,mxConstants.STYLE_STARTARROW,null),mxUtils.getValue(h.style,"startFill","1"),b,"start"),i=l(mxUtils.getValue(h.style,mxConstants.STYLE_ENDARROW,null),mxUtils.getValue(h.style,"endFill","1"),T,"end");null!=o&&null!=i&&("arrow"==h.style.shape?(o.className="geSprite geSprite-noarrow",i.className="geSprite geSprite-endblocktrans"):"link"==h.style.shape&&(o.className="geSprite geSprite-noarrow",i.className="geSprite geSprite-noarrow")),mxUtils.setOpacity(w,"arrow"==h.style.shape?30:100),"connector"!=h.style.shape&&"flexArrow"!=h.style.shape&&"filledEdge"!=h.style.shape?(mxUtils.setOpacity(b,30),mxUtils.setOpacity(T,30)):(mxUtils.setOpacity(b,100),mxUtils.setOpacity(T,100)),!n&&document.activeElement==P||(s=parseInt(mxUtils.getValue(h.style,mxConstants.STYLE_STARTSIZE,mxConstants.DEFAULT_MARKERSIZE)),P.value=isNaN(s)?"":s+" pt"),!n&&document.activeElement==R||(s=parseInt(mxUtils.getValue(h.style,mxConstants.STYLE_SOURCE_PERIMETER_SPACING,0)),R.value=isNaN(s)?"":s+" pt"),!n&&document.activeElement==M||(s=parseInt(mxUtils.getValue(h.style,mxConstants.STYLE_ENDSIZE,mxConstants.DEFAULT_MARKERSIZE)),M.value=isNaN(s)?"":s+" pt"),!n&&document.activeElement==R||(s=parseInt(mxUtils.getValue(h.style,mxConstants.STYLE_TARGET_PERIMETER_SPACING,0)),I.value=isNaN(s)?"":s+" pt"),!n&&document.activeElement==U||(s=parseInt(mxUtils.getValue(h.style,mxConstants.STYLE_PERIMETER_SPACING,0)),U.value=isNaN(s)?"":s+" pt")}),N=this.installInputHandler(P,mxConstants.STYLE_STARTSIZE,mxConstants.DEFAULT_MARKERSIZE,0,999," pt"),H=this.installInputHandler(R,mxConstants.STYLE_SOURCE_PERIMETER_SPACING,0,-999,999," pt"),_=this.installInputHandler(M,mxConstants.STYLE_ENDSIZE,mxConstants.DEFAULT_MARKERSIZE,0,999," pt"),D=this.installInputHandler(I,mxConstants.STYLE_TARGET_PERIMETER_SPACING,0,-999,999," pt"),G=this.installInputHandler(U,mxConstants.STYLE_PERIMETER_SPACING,0,0,999," pt");return this.addKeyHandler(C,O),this.addKeyHandler(P,O),this.addKeyHandler(R,O),this.addKeyHandler(M,O),this.addKeyHandler(I,O),this.addKeyHandler(U,O),a.getModel().addListener(mxEvent.CHANGE,O),this.listeners.push({destroy:function(){a.getModel().removeListener(O)}}),O(),t},StyleFormatPanel.prototype.addLineJumps=function(t){var i=this.format.getSelectionState();if(Graph.lineJumpsEnabled&&0o+a?t.y=n.y:t.x=n.x),mxUtils.getPerimeterPoint(r,t,n)},mxStyleRegistry.putValue("parallelogramPerimeter",mxPerimeter.ParallelogramPerimeter),mxPerimeter.TrapezoidPerimeter=function(t,e,n,i){var l="0"!=mxUtils.getValue(e.style,"fixedSize","0"),s=l?E.prototype.fixedSize:E.prototype.size;null!=e&&(s=mxUtils.getValue(e.style,"size",s)),l&&(s*=e.view.scale);var o,r,a=t.x,h=t.y,d=t.width,u=t.height,p=null!=e?mxUtils.getValue(e.style,mxConstants.STYLE_DIRECTION,mxConstants.DIRECTION_EAST):mxConstants.DIRECTION_EAST,e=[];e=p==mxConstants.DIRECTION_EAST?[new mxPoint(a+(o=l?Math.max(0,Math.min(.5*d,s)):d*Math.max(0,Math.min(1,s))),h),new mxPoint(a+d-o,h),new mxPoint(a+d,h+u),new mxPoint(a,h+u),new mxPoint(a+o,h)]:p==mxConstants.DIRECTION_WEST?(o=l?Math.max(0,Math.min(d,s)):d*Math.max(0,Math.min(1,s)),[new mxPoint(a,h),new mxPoint(a+d,h),new mxPoint(a+d-o,h+u),new mxPoint(a+o,h+u),new mxPoint(a,h)]):p==mxConstants.DIRECTION_NORTH?[new mxPoint(a,h+(r=l?Math.max(0,Math.min(u,s)):u*Math.max(0,Math.min(1,s)))),new mxPoint(a+d,h),new mxPoint(a+d,h+u),new mxPoint(a,h+u-r),new mxPoint(a,h+r)]:(r=l?Math.max(0,Math.min(u,s)):u*Math.max(0,Math.min(1,s)),[new mxPoint(a,h),new mxPoint(a+d,h+r),new mxPoint(a+d,h+u-r),new mxPoint(a,h+u),new mxPoint(a,h)]);t=new mxPoint(t.getCenterX(),t.getCenterY());return i&&(n.xa+d?t.y=n.y:t.x=n.x),mxUtils.getPerimeterPoint(e,t,n)},mxStyleRegistry.putValue("trapezoidPerimeter",mxPerimeter.TrapezoidPerimeter),mxPerimeter.StepPerimeter=function(t,e,n,i){var l="0"!=mxUtils.getValue(e.style,"fixedSize","0"),s=l?O.prototype.fixedSize:O.prototype.size;null!=e&&(s=mxUtils.getValue(e.style,"size",s)),l&&(s*=e.view.scale);var o,r,a=t.x,h=t.y,d=t.width,u=t.height,p=t.getCenterX(),t=t.getCenterY(),e=null!=e?mxUtils.getValue(e.style,mxConstants.STYLE_DIRECTION,mxConstants.DIRECTION_EAST):mxConstants.DIRECTION_EAST;h=e==mxConstants.DIRECTION_EAST?(o=l?Math.max(0,Math.min(d,s)):d*Math.max(0,Math.min(1,s)),[new mxPoint(a,h),new mxPoint(a+d-o,h),new mxPoint(a+d,t),new mxPoint(a+d-o,h+u),new mxPoint(a,h+u),new mxPoint(a+o,t),new mxPoint(a,h)]):e==mxConstants.DIRECTION_WEST?[new mxPoint(a+(o=l?Math.max(0,Math.min(d,s)):d*Math.max(0,Math.min(1,s))),h),new mxPoint(a+d,h),new mxPoint(a+d-o,t),new mxPoint(a+d,h+u),new mxPoint(a+o,h+u),new mxPoint(a,t),new mxPoint(a+o,h)]:e==mxConstants.DIRECTION_NORTH?[new mxPoint(a,h+(r=l?Math.max(0,Math.min(u,s)):u*Math.max(0,Math.min(1,s)))),new mxPoint(p,h),new mxPoint(a+d,h+r),new mxPoint(a+d,h+u),new mxPoint(p,h+u-r),new mxPoint(a,h+u),new mxPoint(a,h+r)]:(r=l?Math.max(0,Math.min(u,s)):u*Math.max(0,Math.min(1,s)),[new mxPoint(a,h),new mxPoint(p,h+r),new mxPoint(a+d,h),new mxPoint(a+d,h+u-r),new mxPoint(p,h+u),new mxPoint(a,h+u-r),new mxPoint(a,h)]);t=new mxPoint(p,t);return i&&(n.xa+d?t.y=n.y:t.x=n.x),mxUtils.getPerimeterPoint(h,t,n)},mxStyleRegistry.putValue("stepPerimeter",mxPerimeter.StepPerimeter),mxPerimeter.HexagonPerimeter2=function(t,e,n,i){var l="0"!=mxUtils.getValue(e.style,"fixedSize","0"),s=l?N.prototype.fixedSize:N.prototype.size;null!=e&&(s=mxUtils.getValue(e.style,"size",s)),l&&(s*=e.view.scale);var o=t.x,r=t.y,a=t.width,h=t.height,d=t.getCenterX(),t=t.getCenterY(),e=null!=e?mxUtils.getValue(e.style,mxConstants.STYLE_DIRECTION,mxConstants.DIRECTION_EAST):mxConstants.DIRECTION_EAST;r=e==mxConstants.DIRECTION_NORTH||e==mxConstants.DIRECTION_SOUTH?(e=l?Math.max(0,Math.min(h,s)):h*Math.max(0,Math.min(1,s)),[new mxPoint(d,r),new mxPoint(o+a,r+e),new mxPoint(o+a,r+h-e),new mxPoint(d,r+h),new mxPoint(o,r+h-e),new mxPoint(o,r+e),new mxPoint(d,r)]):[new mxPoint(o+(s=l?Math.max(0,Math.min(a,s)):a*Math.max(0,Math.min(1,s))),r),new mxPoint(o+a-s,r),new mxPoint(o+a,t),new mxPoint(o+a-s,r+h),new mxPoint(o+s,r+h),new mxPoint(o,t),new mxPoint(o+s,r)];t=new mxPoint(d,t);return i&&(n.xo+a?t.y=n.y:t.x=n.x),mxUtils.getPerimeterPoint(r,t,n)},mxStyleRegistry.putValue("hexagonPerimeter2",mxPerimeter.HexagonPerimeter2),mxUtils.extend(Q,mxShape),Q.prototype.size=10,Q.prototype.paintBackground=function(t,e,n,i,l){var s=parseFloat(mxUtils.getValue(this.style,"size",this.size));t.translate(e,n),t.ellipse((i-s)/2,0,s,s),t.fillAndStroke(),t.begin(),t.moveTo(i/2,s),t.lineTo(i/2,l),t.end(),t.stroke()},mxCellRenderer.registerShape("lollipop",Q),mxUtils.extend(J,mxShape),J.prototype.size=10,J.prototype.inset=2,J.prototype.paintBackground=function(t,e,n,i,l){var s=parseFloat(mxUtils.getValue(this.style,"size",this.size)),o=parseFloat(mxUtils.getValue(this.style,"inset",this.inset))+this.strokewidth;t.translate(e,n),t.begin(),t.moveTo(i/2,s+o),t.lineTo(i/2,l),t.end(),t.stroke(),t.begin(),t.moveTo((i-s)/2-o,s/2),t.quadTo((i-s)/2-o,s+o,i/2,s+o),t.quadTo((i+s)/2+o,s+o,(i+s)/2+o,s/2),t.end(),t.stroke()},mxCellRenderer.registerShape("requires",J),mxUtils.extend(q,mxShape),q.prototype.paintBackground=function(t,e,n,i,l){t.translate(e,n),t.begin(),t.moveTo(0,0),t.quadTo(i,0,i,l/2),t.quadTo(i,l,0,l),t.end(),t.stroke()},mxCellRenderer.registerShape("requiredInterface",q),mxUtils.extend($,mxShape),$.prototype.inset=2,$.prototype.paintBackground=function(t,e,n,i,l){var s=parseFloat(mxUtils.getValue(this.style,"inset",this.inset))+this.strokewidth;t.translate(e,n),t.ellipse(0,s,i-2*s,l-2*s),t.fillAndStroke(),t.begin(),t.moveTo(i/2,0),t.quadTo(i,0,i,l/2),t.quadTo(i,l,i/2,l),t.end(),t.stroke()},mxCellRenderer.registerShape("providedRequiredInterface",$),mxUtils.extend(tt,mxCylinder),tt.prototype.jettyWidth=20,tt.prototype.jettyHeight=10,tt.prototype.redrawPath=function(t,e,n,i,l,s){var o=parseFloat(mxUtils.getValue(this.style,"jettyWidth",this.jettyWidth)),r=parseFloat(mxUtils.getValue(this.style,"jettyHeight",this.jettyHeight)),a=o/2,h=a+o/2,d=Math.min(r,l-r),o=Math.min(d+2*r,l-r);s?(t.moveTo(a,d),t.lineTo(h,d),t.lineTo(h,d+r),t.lineTo(a,d+r),t.moveTo(a,o),t.lineTo(h,o),t.lineTo(h,o+r),t.lineTo(a,o+r)):(t.moveTo(a,0),t.lineTo(i,0),t.lineTo(i,l),t.lineTo(a,l),t.lineTo(a,o+r),t.lineTo(0,o+r),t.lineTo(0,o),t.lineTo(a,o),t.lineTo(a,d+r),t.lineTo(0,d+r),t.lineTo(0,d),t.lineTo(a,d),t.close()),t.end()},mxCellRenderer.registerShape("module",tt),mxUtils.extend(et,mxCylinder),et.prototype.jettyWidth=32,et.prototype.jettyHeight=12,et.prototype.redrawPath=function(t,e,n,i,l,s){var o=parseFloat(mxUtils.getValue(this.style,"jettyWidth",this.jettyWidth)),r=parseFloat(mxUtils.getValue(this.style,"jettyHeight",this.jettyHeight)),a=o/2,h=a+o/2,d=.3*l-r/2,o=.7*l-r/2;s?(t.moveTo(a,d),t.lineTo(h,d),t.lineTo(h,d+r),t.lineTo(a,d+r),t.moveTo(a,o),t.lineTo(h,o),t.lineTo(h,o+r),t.lineTo(a,o+r)):(t.moveTo(a,0),t.lineTo(i,0),t.lineTo(i,l),t.lineTo(a,l),t.lineTo(a,o+r),t.lineTo(0,o+r),t.lineTo(0,o),t.lineTo(a,o),t.lineTo(a,d+r),t.lineTo(0,d+r),t.lineTo(0,d),t.lineTo(a,d),t.close()),t.end()},mxCellRenderer.registerShape("component",et),mxUtils.extend(nt,mxRectangleShape),nt.prototype.paintForeground=function(t,e,n,i,l){var s=i/2,o=l/2,r=mxUtils.getValue(this.style,mxConstants.STYLE_ARCSIZE,mxConstants.LINE_ARCSIZE)/2;t.begin(),this.addPoints(t,[new mxPoint(e+s,n),new mxPoint(e+i,n+o),new mxPoint(e+s,n+l),new mxPoint(e,n+o)],this.isRounded,r,!0),t.stroke(),mxRectangleShape.prototype.paintForeground.apply(this,arguments)},mxCellRenderer.registerShape("associativeEntity",nt),mxUtils.extend(it,mxDoubleEllipse),it.prototype.outerStroke=!0,it.prototype.paintVertexShape=function(t,e,n,i,l){var s=Math.min(4,Math.min(i/5,l/5));0/g,"\n")),(i=document.createElement("div")).innerHTML=d.sanitizeHtml(l),l=mxUtils.extractTextWithWhitespace(i.childNodes),d.cellLabelChanged(state.cell,l),d.setCellStyles("html",e,[s[o]])):"0"==n&&"1"==e&&(l=mxUtils.htmlEntities(d.convertValueToString(state.cell),!1),"0"!=mxUtils.getValue(state.style,"nl2Br","1")&&(l=l.replace(/\n/g,"
")),d.cellLabelChanged(state.cell,d.sanitizeHtml(l)),d.setCellStyles("html",e,[s[o]])));a.fireEvent(new mxEventObject("styleChanged","keys",["html"],"values",[null!=e?e:"0"],"cells",s))}finally{d.getModel().endUpdate()}}}),this.addAction("wordWrap",function(){var t=d.getView().getState(d.getSelectionCell()),e="wrap";d.stopEditing(),null!=t&&"wrap"==t.style[mxConstants.STYLE_WHITE_SPACE]&&(e=null),d.setCellStyles(mxConstants.STYLE_WHITE_SPACE,e)}),this.addAction("rotation",function(){var t="0",e=d.getView().getState(d.getSelectionCell());null!=e&&(t=e.style[mxConstants.STYLE_ROTATION]||t);t=new FilenameDialog(a,t,mxResources.get("apply"),function(t){null!=t&&0"))}),i)}t(mxResources.get("normal"),"p"),t("","h1").firstChild.nextSibling.innerHTML='

'+mxResources.get("heading")+" 1

",t("","h2").firstChild.nextSibling.innerHTML='

'+mxResources.get("heading")+" 2

",t("","h3").firstChild.nextSibling.innerHTML='

'+mxResources.get("heading")+" 3

",t("","h4").firstChild.nextSibling.innerHTML='

'+mxResources.get("heading")+" 4

",t("","h5").firstChild.nextSibling.innerHTML='
'+mxResources.get("heading")+" 5
",t("","h6").firstChild.nextSibling.innerHTML='
'+mxResources.get("heading")+" 6
",t("","pre").firstChild.nextSibling.innerHTML='
'+mxResources.get("formatted")+"
",t("","blockquote").firstChild.nextSibling.innerHTML='
'+mxResources.get("blockquote")+"
"}))),this.put("fontSize",new Menu(mxUtils.bind(this,function(t,e){for(var n=[6,8,9,10,11,12,14,18,24,36,48,72],i=mxUtils.bind(this,function(n){this.styleChange(t,n,[mxConstants.STYLE_FONTSIZE],[n],null,e,function(){if(null!=s.cellEditor.textarea){document.execCommand("fontSize",!1,"3");for(var t=s.cellEditor.textarea.getElementsByTagName("font"),e=0;e"],i=0;i");for(var l=0;l
");n.push("")}return n.push(""),n.join("")}(e,n));var r=i.cellEditor.textarea.getElementsByTagName("table");if(r.length==s.length+1)for(o=r.length-1;0<=o;o--)if(0==o||r[o]!=s[o-1]){i.selectNode(r[o].rows[0].cells[0]);break}}});var r=this.editorUi.editor.graph,a=null,h=null;var e=t.addItem("",null,null,e,null,null,null,!0),d='';e.firstChild.innerHTML="";var u=function(t,e){var n=document.createElement("table");n.setAttribute("border","1"),n.style.borderCollapse="collapse",n.style.borderStyle="solid",mxClient.IS_QUIRKS||n.setAttribute("cellPadding","8");for(var i=0;i',Toolbar.prototype.selectedBackground="#d0d0d0",Toolbar.prototype.unselectedBackground="none",Toolbar.prototype.staticElements=null,Toolbar.prototype.init=function(){var t,e=screen.width;700<=(e-=740'+this.dropdownImageHtml,t.style.width=mxClient.IS_QUIRKS?i+"px":i-o+"px",mxClient.IS_QUIRKS&&(t.style.height=EditorUi.compactUi?"24px":"26px"),EditorUi.compactUi&&(t.getElementsByTagName("img")[0].style.left="24px",t.getElementsByTagName("img")[0].style.top="5px",t.style.width=mxClient.IS_QUIRKS?n+"px":n-10+"px")},Toolbar.prototype.setFontName=function(t){null!=this.fontMenu&&(this.fontMenu.innerHTML='
'+mxUtils.htmlEntities(t)+"
"+this.dropdownImageHtml)},Toolbar.prototype.setFontSize=function(t){null!=this.sizeMenu&&(this.sizeMenu.innerHTML='
'+mxUtils.htmlEntities(t)+"
"+this.dropdownImageHtml)},Toolbar.prototype.createTextToolbar=function(){var s=this.editorUi.editor.graph,t=this.addMenu("",mxResources.get("style"),!0,"formatBlock");t.style.position="relative",t.style.whiteSpace="nowrap",t.style.overflow="hidden",t.innerHTML=mxResources.get("style")+this.dropdownImageHtml,EditorUi.compactUi&&(t.style.paddingRight="18px",t.getElementsByTagName("img")[0].style.right="1px",t.getElementsByTagName("img")[0].style.top="5px"),this.addSeparator(),this.fontMenu=this.addMenu("",mxResources.get("fontFamily"),!0,"fontFamily"),this.fontMenu.style.position="relative",this.fontMenu.style.whiteSpace="nowrap",this.fontMenu.style.overflow="hidden",this.fontMenu.style.width=mxClient.IS_QUIRKS?"80px":"60px",this.setFontName(Menus.prototype.defaultFont),EditorUi.compactUi&&(this.fontMenu.style.paddingRight="18px",this.fontMenu.getElementsByTagName("img")[0].style.right="1px",this.fontMenu.getElementsByTagName("img")[0].style.top="5px"),this.addSeparator(),this.sizeMenu=this.addMenu(Menus.prototype.defaultFontSize,mxResources.get("fontSize"),!0,"fontSize"),this.sizeMenu.style.position="relative",this.sizeMenu.style.whiteSpace="nowrap",this.sizeMenu.style.overflow="hidden",this.sizeMenu.style.width=mxClient.IS_QUIRKS?"44px":"24px",this.setFontSize(Menus.prototype.defaultFontSize),EditorUi.compactUi&&(this.sizeMenu.style.paddingRight="18px",this.sizeMenu.getElementsByTagName("img")[0].style.right="1px",this.sizeMenu.getElementsByTagName("img")[0].style.top="5px");t=this.addItems(["-","undo","redo","-","bold","italic","underline"]);t[1].setAttribute("title",mxResources.get("undo")+" ("+this.editorUi.actions.get("undo").shortcut+")"),t[2].setAttribute("title",mxResources.get("redo")+" ("+this.editorUi.actions.get("redo").shortcut+")"),t[4].setAttribute("title",mxResources.get("bold")+" ("+this.editorUi.actions.get("bold").shortcut+")"),t[5].setAttribute("title",mxResources.get("italic")+" ("+this.editorUi.actions.get("italic").shortcut+")"),t[6].setAttribute("title",mxResources.get("underline")+" ("+this.editorUi.actions.get("underline").shortcut+")");t=this.addMenuFunction("",mxResources.get("align"),!1,mxUtils.bind(this,function(t){(e=t.addItem("",null,mxUtils.bind(this,function(t){s.cellEditor.alignText(mxConstants.ALIGN_LEFT,t)}),null,"geIcon geSprite geSprite-left")).setAttribute("title",mxResources.get("left")),(e=t.addItem("",null,mxUtils.bind(this,function(t){s.cellEditor.alignText(mxConstants.ALIGN_CENTER,t)}),null,"geIcon geSprite geSprite-center")).setAttribute("title",mxResources.get("center")),(e=t.addItem("",null,mxUtils.bind(this,function(t){s.cellEditor.alignText(mxConstants.ALIGN_RIGHT,t)}),null,"geIcon geSprite geSprite-right")).setAttribute("title",mxResources.get("right")),(e=t.addItem("",null,mxUtils.bind(this,function(){document.execCommand("justifyfull",!1,null)}),null,"geIcon geSprite geSprite-justifyfull")).setAttribute("title",mxResources.get("justifyfull")),(e=t.addItem("",null,mxUtils.bind(this,function(){document.execCommand("insertorderedlist",!1,null)}),null,"geIcon geSprite geSprite-orderedlist")).setAttribute("title",mxResources.get("numberedList")),(e=t.addItem("",null,mxUtils.bind(this,function(){document.execCommand("insertunorderedlist",!1,null)}),null,"geIcon geSprite geSprite-unorderedlist")).setAttribute("title",mxResources.get("bulletedList")),(e=t.addItem("",null,mxUtils.bind(this,function(){document.execCommand("outdent",!1,null)}),null,"geIcon geSprite geSprite-outdent")).setAttribute("title",mxResources.get("decreaseIndent")),(e=t.addItem("",null,mxUtils.bind(this,function(){document.execCommand("indent",!1,null)}),null,"geIcon geSprite geSprite-indent")).setAttribute("title",mxResources.get("increaseIndent"))}));t.style.position="relative",t.style.whiteSpace="nowrap",t.style.overflow="hidden",t.innerHTML='
'+this.dropdownImageHtml,t.style.width=mxClient.IS_QUIRKS?"50px":"30px",EditorUi.compactUi&&(t.getElementsByTagName("img")[0].style.left="22px",t.getElementsByTagName("img")[0].style.top="5px");t=this.addMenuFunction("",mxResources.get("format"),!1,mxUtils.bind(this,function(t){(e=t.addItem("",null,this.editorUi.actions.get("subscript").funct,null,"geIcon geSprite geSprite-subscript")).setAttribute("title",mxResources.get("subscript")+" ("+Editor.ctrlKey+"+,)"),(e=t.addItem("",null,this.editorUi.actions.get("superscript").funct,null,"geIcon geSprite geSprite-superscript")).setAttribute("title",mxResources.get("superscript")+" ("+Editor.ctrlKey+"+.)"),(e=t.addItem("",null,this.editorUi.actions.get("fontColor").funct,null,"geIcon geSprite geSprite-fontcolor")).setAttribute("title",mxResources.get("fontColor")),(e=t.addItem("",null,this.editorUi.actions.get("backgroundColor").funct,null,"geIcon geSprite geSprite-fontbackground")).setAttribute("title",mxResources.get("backgroundColor")),(e=t.addItem("",null,mxUtils.bind(this,function(){document.execCommand("removeformat",!1,null)}),null,"geIcon geSprite geSprite-removeformat")).setAttribute("title",mxResources.get("removeFormat"))}));t.style.position="relative",t.style.whiteSpace="nowrap",t.style.overflow="hidden",t.innerHTML='
'+this.dropdownImageHtml,t.style.width=mxClient.IS_QUIRKS?"50px":"30px",EditorUi.compactUi&&(t.getElementsByTagName("img")[0].style.left="22px",t.getElementsByTagName("img")[0].style.top="5px"),this.addSeparator(),this.addButton("geIcon geSprite geSprite-code",mxResources.get("html"),function(){s.cellEditor.toggleViewMode(),0'+this.dropdownImageHtml,t.style.width=mxClient.IS_QUIRKS?"36px":"16px",EditorUi.compactUi&&(t.getElementsByTagName("img")[0].style.left="24px",t.getElementsByTagName("img")[0].style.top="5px",t.style.width=mxClient.IS_QUIRKS?"50px":"30px"),this.addSeparator();var e=this.addMenuFunction("geIcon geSprite geSprite-table",mxResources.get("table"),!1,mxUtils.bind(this,function(t){var e,n=s.getSelectedElement(),i=s.getParentByNames(n,["TD","TH"],s.cellEditor.text2),l=s.getParentByName(n,"TR",s.cellEditor.text2);null==l?this.editorUi.menus.addInsertTableItem(t):(e=s.getParentByName(l,"TABLE",s.cellEditor.text2),(n=t.addItem("",null,mxUtils.bind(this,function(){try{s.selectNode(s.insertColumn(e,null!=i?i.cellIndex:0))}catch(t){this.editorUi.handleError(t)}}),null,"geIcon geSprite geSprite-insertcolumnbefore")).setAttribute("title",mxResources.get("insertColumnBefore")),(n=t.addItem("",null,mxUtils.bind(this,function(){try{s.selectNode(s.insertColumn(e,null!=i?i.cellIndex+1:-1))}catch(t){this.editorUi.handleError(t)}}),null,"geIcon geSprite geSprite-insertcolumnafter")).setAttribute("title",mxResources.get("insertColumnAfter")),(n=t.addItem("Delete column",null,mxUtils.bind(this,function(){if(null!=i)try{s.deleteColumn(e,i.cellIndex)}catch(t){this.editorUi.handleError(t)}}),null,"geIcon geSprite geSprite-deletecolumn")).setAttribute("title",mxResources.get("deleteColumn")),(n=t.addItem("",null,mxUtils.bind(this,function(){try{s.selectNode(s.insertRow(e,l.sectionRowIndex))}catch(t){this.editorUi.handleError(t)}}),null,"geIcon geSprite geSprite-insertrowbefore")).setAttribute("title",mxResources.get("insertRowBefore")),(n=t.addItem("",null,mxUtils.bind(this,function(){try{s.selectNode(s.insertRow(e,l.sectionRowIndex+1))}catch(t){this.editorUi.handleError(t)}}),null,"geIcon geSprite geSprite-insertrowafter")).setAttribute("title",mxResources.get("insertRowAfter")),(n=t.addItem("",null,mxUtils.bind(this,function(){try{s.deleteRow(e,l.sectionRowIndex)}catch(t){this.editorUi.handleError(t)}}),null,"geIcon geSprite geSprite-deleterow")).setAttribute("title",mxResources.get("deleteRow")),(n=t.addItem("",null,mxUtils.bind(this,function(){var t=e.style.borderColor.replace(/\brgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/g,function(t,e,n,i){return"#"+("0"+Number(e).toString(16)).substr(-2)+("0"+Number(n).toString(16)).substr(-2)+("0"+Number(i).toString(16)).substr(-2)});this.editorUi.pickColor(t,function(t){null==t||t==mxConstants.NONE?(e.removeAttribute("border"),e.style.border="",e.style.borderCollapse=""):(e.setAttribute("border","1"),e.style.border="1px solid "+t,e.style.borderCollapse="collapse")})}),null,"geIcon geSprite geSprite-strokecolor")).setAttribute("title",mxResources.get("borderColor")),(n=t.addItem("",null,mxUtils.bind(this,function(){var t=e.style.backgroundColor.replace(/\brgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/g,function(t,e,n,i){return"#"+("0"+Number(e).toString(16)).substr(-2)+("0"+Number(n).toString(16)).substr(-2)+("0"+Number(i).toString(16)).substr(-2)});this.editorUi.pickColor(t,function(t){null==t||t==mxConstants.NONE?e.style.backgroundColor="":e.style.backgroundColor=t})}),null,"geIcon geSprite geSprite-fillcolor")).setAttribute("title",mxResources.get("backgroundColor")),(n=t.addItem("",null,mxUtils.bind(this,function(){var t=e.getAttribute("cellPadding")||0,t=new FilenameDialog(this.editorUi,t,mxResources.get("apply"),mxUtils.bind(this,function(t){null!=t&&0r.div.clientHeight&&(r.div.style.width="40px"),r.hideMenu=mxUtils.bind(this,function(){mxPopupMenu.prototype.hideMenu.apply(r,arguments),this.editorUi.resetCurrentMenu(),r.destroy()}),r.addListener(mxEvent.EVENT_HIDE,mxUtils.bind(this,function(){this.currentElt=null}))),a=!0,mxEvent.consume(t)})),mxEvent.addListener(n,mxClient.IS_POINTER?"pointerdown":"mousedown",mxUtils.bind(this,function(t){a=this.currentElt!=n,t.preventDefault()})))},Toolbar.prototype.destroy=function(){null!=this.gestureHandler&&(mxEvent.removeGestureListeners(document,this.gestureHandler),this.gestureHandler=null)};var OpenDialog=function(){var t=document.createElement("iframe");t.style.backgroundColor="transparent",t.allowTransparency="true",t.style.borderStyle="none",t.style.borderWidth="0px",t.style.overflow="hidden",t.frameBorder="0";var e=mxClient.IS_VML&&(null==document.documentMode||document.documentMode<8)?20:0;t.setAttribute("width",(Editor.useLocalStorage?640:320)+e+"px"),t.setAttribute("height",(Editor.useLocalStorage?480:220)+e+"px"),t.setAttribute("src",OPEN_FORM),this.container=t},ColorDialog=function(e,t,n,i){this.editorUi=e;var d=document.createElement("input");d.style.marginBottom="10px",d.style.width="216px",mxClient.IS_IE&&(d.style.marginTop="10px",document.body.appendChild(d));var l=null!=n?n:this.createApplyFunction();function u(){var t=d.value;/(^#?[a-zA-Z0-9]*$)/.test(t)?("none"!=t&&"#"!=t.charAt(0)&&(t="#"+t),ColorDialog.addRecentColor("none"!=t?t.substring(1):t,12),l(t),e.hideDialog()):e.handleError({message:mxResources.get("invalidInput")})}this.init=function(){mxClient.IS_TOUCH||d.focus()};var p=new mxJSColor.color(d);p.pickerOnfocus=!1,p.showPicker();var s=document.createElement("div");mxJSColor.picker.box.style.position="relative",mxJSColor.picker.box.style.width="230px",mxJSColor.picker.box.style.height="100px",mxJSColor.picker.box.style.paddingBottom="10px",s.appendChild(mxJSColor.picker.box);var m=document.createElement("center");function c(){var t=o(0==ColorDialog.recentColors.length?["FFFFFF"]:ColorDialog.recentColors,11,"FFFFFF",!0);return t.style.marginBottom="8px",t}function o(t,e,n,i){e=null!=e?e:12;var l=document.createElement("table");l.style.borderCollapse="collapse",l.setAttribute("cellspacing","0"),l.style.marginBottom="20px",l.style.cellSpacing="0px";var s=document.createElement("tbody");l.appendChild(s);for(var o=t.length/e,r=0;r=e&&ColorDialog.recentColors.pop())},ColorDialog.resetRecentColors=function(){ColorDialog.recentColors=[]};var AboutDialog=function(t){var e=document.createElement("div");e.setAttribute("align","center");var n=document.createElement("h3");mxUtils.write(n,mxResources.get("about")+" GraphEditor"),e.appendChild(n);n=document.createElement("img");n.style.border="0px",n.setAttribute("width","176"),n.setAttribute("width","151"),n.setAttribute("src",IMAGE_PATH+"/logo.png"),e.appendChild(n),mxUtils.br(e),mxUtils.write(e,"Powered by mxGraph "+mxClient.VERSION),mxUtils.br(e);n=document.createElement("a");n.setAttribute("href","http://www.jgraph.com/"),n.setAttribute("target","_blank"),mxUtils.write(n,"www.jgraph.com"),e.appendChild(n),mxUtils.br(e),mxUtils.br(e);n=mxUtils.button(mxResources.get("close"),function(){t.hideDialog()});n.className="geBtn gePrimaryBtn",e.appendChild(n),this.container=e},TextareaDialog=function(t,e,n,i,l,s,o,r,a,h,d,u,p,m){o=null!=o?o:300,r=null!=r?r:120,h=null!=h&&h;var c,g=document.createElement("table"),x=document.createElement("tbody"),y=document.createElement("tr");(c=document.createElement("td")).style.fontSize="10pt",c.style.width="100px",mxUtils.write(c,e),y.appendChild(c),x.appendChild(y),y=document.createElement("tr"),c=document.createElement("td");var f=document.createElement("textarea");if(d&&f.setAttribute("wrap","off"),f.setAttribute("spellcheck","false"),f.setAttribute("autocorrect","off"),f.setAttribute("autocomplete","off"),f.setAttribute("autocapitalize","off"),mxUtils.write(f,n||""),f.style.resize="none",f.style.width=o+"px",f.style.height=r+"px",this.textarea=f,this.init=function(){f.focus(),f.scrollTop=0},c.appendChild(f),y.appendChild(c),x.appendChild(y),y=document.createElement("tr"),(c=document.createElement("td")).style.paddingTop="14px",c.style.whiteSpace="nowrap",c.setAttribute("align","right"),null!=p&&((r=mxUtils.button(mxResources.get("help"),function(){t.editor.graph.openLink(p)})).className="geBtn",c.appendChild(r)),null!=m)for(var C=0;CMAX_AREA||p.value<=0?p.style.backgroundColor="red":p.style.backgroundColor="",p.value*m.value>MAX_AREA||m.value<=0?m.style.backgroundColor="red":m.style.backgroundColor=""}C.setAttribute("type","number"),C.setAttribute("value",ExportDialog.lastBorderValue),C.style.width="180px",(e=document.createElement("td")).appendChild(C),t.appendChild(e),a.appendChild(t),s.appendChild(a),mxEvent.addListener(d,"change",v),v(),mxEvent.addListener(u,"change",function(){y=!0;var t=Math.max(0,parseFloat(u.value)||100)/100;u.value=parseFloat((100*t).toFixed(2)),0e.name?1:0}),null!=p&&((A=document.createElement("div")).style.width="100%",A.style.fontSize="11px",A.style.textAlign="center",mxUtils.write(A,p),o.addField(mxResources.get("id")+":",A));for(var x,y,f,g=0;g',mxEvent.addListener(r,"click",function(t){if(d.isEnabled()){d.model.beginUpdate();try{var e=d.model.root.getIndex(g);d.removeCells([g],!1),0==d.model.getChildCount(d.model.root)?(d.model.add(d.model.root,new mxCell),d.setDefaultParent(null)):0',mxEvent.addListener(a,"click",function(t){var e;d.isEnabled()&&!d.isSelectionEmpty()&&(e=mxUtils.getOffset(a),h.showPopupMenu(mxUtils.bind(this,function(n,i){for(var t=c-1;0<=t;t--)mxUtils.bind(this,function(t){var e=n.addItem(d.convertValueToString(t)||mxResources.get("background"),null,mxUtils.bind(this,function(){d.moveCells(d.getSelectionCells(),0,0,!1,t)}),i);1==d.getSelectionCount()&&d.model.isAncestor(t,d.getSelectionCell())&&n.addCheckmark(e,Editor.checkmarkImage)})(d.model.getChildAt(d.model.root,t))}),e.x,e.y+a.offsetHeight,t))}),o.appendChild(a);var x=s.cloneNode();x.innerHTML='
',x.setAttribute("title",mxResources.get("rename")),mxEvent.addListener(x,"click",function(t){d.isEnabled()&&h.showDataDialog(g),mxEvent.consume(t)}),d.isEnabled()||(x.className="geButton mxDisabled"),o.appendChild(x);var y=s.cloneNode();y.innerHTML='
',mxEvent.addListener(y,"click",function(t){if(d.isEnabled()){var e=null;d.model.beginUpdate();try{e=d.cloneCell(g),d.cellLabelChanged(e,mxResources.get("untitledLayer")),e.setVisible(!0),e=d.addCell(e,d.model.root),d.setDefaultParent(e)}finally{d.model.endUpdate()}null==e||d.isCellLocked(e)||d.selectAll(e)}}),d.isEnabled()||(y.className="geButton mxDisabled"),o.appendChild(y);s=s.cloneNode();function f(){function e(e,t,n,i){var l=document.createElement("div");l.className="geToolbarContainer",l.style.overflow="hidden",l.style.position="relative",l.style.padding="4px",l.style.height="22px",l.style.display="block",l.style.backgroundColor="white"==Dialog.backdropColor?"whiteSmoke":Dialog.backdropColor,l.style.borderWidth="0px 0px 1px 0px",l.style.borderColor="#c3c3c3",l.style.borderStyle="solid",l.style.whiteSpace="nowrap",l.setAttribute("title",t);var s=document.createElement("div");s.style.display="inline-block",s.style.width="100%",s.style.textOverflow="ellipsis",s.style.overflow="hidden",mxEvent.addListener(l,"dragover",function(t){t.dataTransfer.dropEffect="move",m=e,t.stopPropagation(),t.preventDefault()}),mxEvent.addListener(l,"dragstart",function(t){p=l,mxClient.IS_FF&&t.dataTransfer.setData("Text","")}),mxEvent.addListener(l,"dragend",function(t){null!=p&&null!=m&&d.addCell(n,d.model.root,m),m=p=null,t.stopPropagation(),t.preventDefault()});var o=document.createElement("img");o.setAttribute("draggable","false"),o.setAttribute("align","top"),o.setAttribute("border","0"),o.style.padding="4px",o.setAttribute("title",mxResources.get("lockUnlock"));var r=d.getCurrentCellStyle(n);"1"==mxUtils.getValue(r,"locked","0")?o.setAttribute("src",Dialog.prototype.lockedImage):o.setAttribute("src",Dialog.prototype.unlockedImage),d.isEnabled()&&(o.style.cursor="pointer"),mxEvent.addListener(o,"click",function(t){if(d.isEnabled()){var e=null;d.getModel().beginUpdate();try{e="1"==mxUtils.getValue(r,"locked","0")?null:"1",d.setCellStyles("locked",e,[n])}finally{d.getModel().endUpdate()}"1"==e&&d.removeSelectionCells(d.getModel().getDescendants(n)),mxEvent.consume(t)}}),s.appendChild(o);var a,o=document.createElement("input");o.setAttribute("type","checkbox"),o.setAttribute("title",mxResources.get("hideIt",[n.value||mxResources.get("background")])),o.style.marginLeft="4px",o.style.marginRight="6px",o.style.marginTop="4px",s.appendChild(o),d.model.isVisible(n)&&(o.setAttribute("checked","checked"),o.defaultChecked=!0),mxEvent.addListener(o,"click",function(t){d.model.setVisible(n,!d.model.isVisible(n)),mxEvent.consume(t)}),mxUtils.write(s,t),l.appendChild(s),d.isEnabled()&&((mxClient.IS_TOUCH||mxClient.IS_POINTER||mxClient.IS_VML||mxClient.IS_IE&&document.documentMode<10)&&((s=document.createElement("div")).style.display="block",s.style.textAlign="right",s.style.whiteSpace="nowrap",s.style.position="absolute",s.style.right="6px",s.style.top="6px",0{const[t,s]=e;e[0]=(t-a)*o-(s-l)*i+a,e[1]=(t-a)*i+(s-l)*o+l})}}function y(e,t,s){const a=[];e.forEach(e=>a.push(...e)),c(a,t,s)}function k(e){const t=e[0],s=e[1];return u(r(t[0]-s[0],2)+r(t[1]-s[1],2))}function m(e,t){const s=t.hachureAngle+90;let a=t.hachureGap;0>a&&(a=4*t.strokeWidth),a=n(a,.1);const l=[0,0];if(s)for(const t of e)c(t,l,s);const h=S(e,a);if(s){for(const t of e)c(t,l,-s);y(h,l,-s)}return h}function S(e,t){const s=[];for(const a of e){const e=[...a];e[0].join(",")!==e[e.length-1].join(",")&&e.push([e[0][0],e[0][1]]),2e.ymint.ymin?1:e.xt.x?1:e.ymax===t.ymax?0:(e.ymax-t.ymax)/l(e.ymax-t.ymax)),!o.length)return h;let p=[],u=o[0].ymin;for(;p.length||o.length;){if(o.length){let e=-1;for(let t=0;tu);t++)e=t;const t=o.splice(0,e+1);t.forEach(e=>{p.push({s:u,edge:e})})}if(p=p.filter(e=>!(e.edge.ymax<=u)),p.sort((e,t)=>e.edge.x===t.edge.x?0:(e.edge.x-t.edge.x)/l(e.edge.x-t.edge.x)),1=p.length)break;const s=p[e].edge,l=p[t].edge;h.push([[a(s.x),u],[a(l.x),u]])}u+=t,p.forEach(e=>{e.edge.x+=t*e.edge.islope})}return h}function T(e,t){let s=e.fillStyle||"hachure";if(!Oe[s])switch(s){case"zigzag":Oe[s]||(Oe[s]=new me(t));break;case"cross-hatch":Oe[s]||(Oe[s]=new Se(t));break;case"dots":Oe[s]||(Oe[s]=new Te(t));break;case"dashed":Oe[s]||(Oe[s]=new xe(t));break;case"zigzag-line":Oe[s]||(Oe[s]=new ve(t));break;case"hachure":default:s="hachure",Oe[s]||(Oe[s]=new ke(t));}return Oe[s]}function x(){return s(Math.random()*2147483648)}function v(e){const t=[];for(;""!==e;)if(e.match(/^([ \t\r\n,]+)/))e=e.substr(RegExp.$1.length);else if(e.match(/^([aAcChHlLmMqQsStTvVzZ])/))t[t.length]={type:_e,text:RegExp.$1},e=e.substr(RegExp.$1.length);else if(e.match(/^(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)/))t[t.length]={type:Ce,text:`${parseFloat(RegExp.$1)}`},e=e.substr(RegExp.$1.length);else return[];return t[t.length]={type:Ee,text:""},t}function O(e,t){return e.type===t}function b(e){const t=[],s=v(e);let a="BOD",l=0,h=s[l];for(;!O(h,Ee);){let o=0;const p=[];if(!("BOD"===a))O(h,Ce)?o=Ve[a]:(l++,o=Ve[h.text],a=h.text);else if("M"===h.text||"m"===h.text)l++,o=Ve[h.text],a=h.text;else return b("M0,0"+e);if(l+oa%2?e+s:e+t);h.push({key:"C",data:e}),t=e[4],s=e[5];break}case"Q":h.push({key:"Q",data:[...i]}),t=i[2],s=i[3];break;case"q":{const e=i.map((e,a)=>a%2?e+s:e+t);h.push({key:"Q",data:e}),t=e[2],s=e[3];break}case"A":h.push({key:"A",data:[...i]}),t=i[5],s=i[6];break;case"a":t+=i[5],s+=i[6],h.push({key:"A",data:[i[0],i[1],i[2],i[3],i[4],t,s]});break;case"H":h.push({key:"H",data:[...i]}),t=i[0];break;case"h":t+=i[0],h.push({key:"H",data:[t]});break;case"V":h.push({key:"V",data:[...i]}),s=i[0];break;case"v":s+=i[0],h.push({key:"V",data:[s]});break;case"S":h.push({key:"S",data:[...i]}),t=i[2],s=i[3];break;case"s":{const e=i.map((e,a)=>a%2?e+s:e+t);h.push({key:"S",data:e}),t=e[2],s=e[3];break}case"T":h.push({key:"T",data:[...i]}),t=i[0],s=i[1];break;case"t":t+=i[0],s+=i[1],h.push({key:"T",data:[t,s]});break;case"Z":case"z":h.push({key:"Z",data:[]}),t=a,s=l;}return h}function C(e){const t=[];let s="",a=0,h=0,o=0,i=0,p=0,n=0;for(const{key:u,data:r}of e){switch(u){case"M":t.push({key:"M",data:[...r]}),[a,h]=r,[o,i]=r;break;case"C":t.push({key:"C",data:[...r]}),a=r[4],h=r[5],p=r[2],n=r[3];break;case"L":t.push({key:"L",data:[...r]}),[a,h]=r;break;case"H":a=r[0],t.push({key:"L",data:[a,h]});break;case"V":h=r[0],t.push({key:"L",data:[a,h]});break;case"S":{let e=0,l=0;"C"===s||"S"===s?(e=a+(a-p),l=h+(h-n)):(e=a,l=h),t.push({key:"C",data:[e,l,...r]}),p=r[0],n=r[1],a=r[2],h=r[3];break}case"T":{const[e,l]=r;let o=0,i=0;"Q"===s||"T"===s?(o=a+(a-p),i=h+(h-n)):(o=a,i=h);const u=a+2*(o-a)/3,d=h+2*(i-h)/3,g=e+2*(o-e)/3,f=l+2*(i-l)/3;t.push({key:"C",data:[u,d,g,f,e,l]}),p=o,n=i,a=e,h=l;break}case"Q":{const[e,s,l,o]=r,i=a+2*(e-a)/3,u=h+2*(s-h)/3;t.push({key:"C",data:[i,u,l+2*(e-l)/3,o+2*(s-o)/3,l,o]}),p=e,n=s,a=l,h=o;break}case"A":{const e=l(r[0]),s=l(r[1]),o=r[2],i=r[3],p=r[4],n=r[5],u=r[6];if(0===e||0===s)t.push({key:"C",data:[a,h,n,u,n,u]}),a=n,h=u;else if(a!==n||h!==u){const l=A(a,h,n,u,e,s,o,i,p);l.forEach(function(e){t.push({key:"C",data:e})}),a=n,h=u}break}case"Z":t.push({key:"Z",data:[]}),a=o,h=i;}s=u}return t}function E(e){return f*e/180}function V(e,t,s){const a=e*g(s)-t*d(s),l=e*d(s)+t*g(s);return[a,l]}function A(e,s,a,o,i,p,h,n,r,c){var y=Math.tan,m=Math.asin;const S=E(h);let T=[],v=0,O=0,b=0,_=0;if(c)[v,O,b,_]=c;else{[e,s]=V(e,s,-S),[a,o]=V(a,o,-S);const t=(e-a)/2,d=(s-o)/2;let g=t*t/(i*i)+d*d/(p*p);1v&&(v=2*f+v),0>O&&(O=2*f+O),r&&v>O&&(v-=2*f),!r&&O>v&&(O-=2*f)}let k=O-v;if(l(k)>120*f/180){const e=O,t=a,s=o;O=r&&O>v?v+1*(120*f/180):v+-1*(120*f/180),a=b+i*g(O),o=_+p*d(O),T=A(a,o,t,s,i,p,h,0,r,[O,e,b,_])}k=O-v;const x=g(v),C=d(v),N=g(O),L=d(O),W=y(k/4),t=4/3*i*W,M=4/3*p*W,P=[e,s],z=[e+t*C,s-M*x],G=[a+t*L,o-M*N],R=[a,o];if(z[0]=2*P[0]-z[0],z[1]=2*P[1]-z[1],c)return[z,G,R].concat(T);else{T=[z,G,R].concat(T);const e=[];for(let t=0;tm;)m+=2*f,S+=2*f;S-m>2*f&&(m=0,S=2*f);const T=2*f/r.curveStepCount,x=i(T/2,(S-m)/2),v=X(x,o,c,y,k,m,S,1,r);if(!r.disableMultiStroke){const e=X(x,o,c,y,k,m,S,1.5,r);v.push(...e)}return n&&(u?v.push(...J(o,c,o+y*g(m),c+k*d(m),r),...J(o,c,o+y*g(S),c+k*d(S),r)):v.push({op:"lineTo",data:[o,c]},{op:"lineTo",data:[o+y*g(m),c+k*d(m)]})),{type:"path",ops:v}}function F(e,t){const s=C(_(b(e))),a=[];let l=[0,0],h=[0,0];for(const{key:o,data:i}of s)switch(o){case"M":{const e=1*(t.maxRandomnessOffset||0),s=t.preserveVertices;a.push({op:"move",data:i.map(a=>a+(s?0:B(e,t)))}),h=[i[0],i[1]],l=[i[0],i[1]];break}case"L":a.push(...J(h[0],h[1],i[0],i[1],t)),h=[i[0],i[1]];break;case"C":{const[e,s,l,o,p,n]=i;a.push(...U(e,s,l,o,p,n,h,t)),h=[p,n];break}case"Z":a.push(...J(h[0],h[1],l[0],l[1],t)),h=[l[0],l[1]];}return{type:"path",ops:a}}function w(e,t){const s=[];for(const a of e)if(a.length){const e=t.maxRandomnessOffset||0,l=a.length;if(2c;)c+=2*f,y+=2*f;y-c>2*f&&(c=0,y=2*f);const k=(y-c)/p.curveStepCount,m=[];for(let l=c;l<=y;l+=k)m.push([o+u*g(l),n+r*d(l)]);return m.push([o+u*g(y),n+r*d(y)]),m.push([o,n]),q([m],p)}function I(e){const t=Object.assign({},e);return t.randomizer=void 0,e.seed&&(t.seed=e.seed+1),t}function D(e){return e.randomizer||(e.randomizer=new be(e.seed||0)),e.randomizer.next()}function Y(e,t,s,a=1){return s.roughness*a*(D(s)*(t-e)+e)}function B(e,t,s=1){return Y(-e,e,t,s)}function J(e,t,s,a,l,h=!1){const o=h?l.disableMultiStrokeFill:l.disableMultiStroke,i=Q(e,t,s,a,l,!0,!1);if(o)return i;const p=Q(e,t,s,a,l,!0,!0);return i.concat(p)}function Q(e,t,s,a,l,h,o){const i=r(e-s,2)+r(t-a,2),p=u(i);let n=1;n=200>p?1:500i&&(d=p/10);const g=d/2,f=.2+.2*D(l);let c=l.bowing*l.maxRandomnessOffset*(a-t)/200,y=l.bowing*l.maxRandomnessOffset*(e-s)/200;c=B(c,l,n),y=B(y,l,n);const k=[],m=()=>B(g,l,n),S=()=>B(d,l,n),T=l.preserveVertices;return h&&(o?k.push({op:"move",data:[e+(T?0:m()),t+(T?0:m())]}):k.push({op:"move",data:[e+(T?0:B(d,l,n)),t+(T?0:B(d,l,n))]})),o?k.push({op:"bcurveTo",data:[c+e+(s-e)*f+m(),y+t+(a-t)*f+m(),c+e+2*(s-e)*f+m(),y+t+2*(a-t)*f+m(),s+(T?0:m()),a+(T?0:m())]}):k.push({op:"bcurveTo",data:[c+e+(s-e)*f+S(),y+t+(a-t)*f+S(),c+e+2*(s-e)*f+S(),y+t+2*(a-t)*f+S(),s+(T?0:S()),a+(T?0:S())]}),k}function H(e,t,s){const a=[[e[0][0]+B(t,s),e[0][1]+B(t,s)],[e[0][0]+B(t,s),e[0][1]+B(t,s)]];for(let l=1;ls)throw new Error("A curve must have at least three points.");const a=[];if(3===s)a.push(K(e[0]),K(e[1]),K(e[2]),K(e[2]));else{const l=[e[0],e[0]];for(let t=1;te&&(e=a,n=u)}return u(e)>h?(pe(t,a,n+1,h,i),pe(t,n,l,h,i)):(!i.length&&i.push(p),i.push(s)),i}function ne(e,t=.15,s){const a=[],l=(e.length-1)/3;for(let h=0;h{4<=p.length&&o.push(...ne(p,t)),p=[]},u=()=>{n(),o.length&&(h.push(o),o=[])};for(const{key:a,data:h}of l)switch(a){case"M":u(),i=[h[0],h[1]],o.push(i);break;case"L":n(),o.push([h[0],h[1]]);break;case"C":if(!p.length){const e=o.length?o[o.length-1]:i;p.push([e[0],e[1]])}p.push([h[0],h[1]]),p.push([h[2],h[3]]),p.push([h[4],h[5]]);break;case"Z":n(),o.push([i[0],i[1]]);}if(u(),!s)return h;const r=[];for(const a of h){const e=ie(a,s);e.length&&r.push(e)}return r}function re(){mxShape.prototype.createSvgCanvas=function(){const e=ge(this.node,this);e.strokeTolerance=this.pointerEvents?this.svgStrokeTolerance:0,e.pointerEventsValue=this.svgPointerEvents;const t=this.getSvgScreenOffset();return 0==t?this.node.removeAttribute("transform"):this.node.setAttribute("transform","translate("+t+","+t+")"),e.minStrokeWidth=this.minSvgStrokeWidth,this.antiAlias||(e.format=function(e){return a(parseFloat(e))}),e}}function de(e){return!e.outline&&!0==mxUtils.getValue(e.style,"sketch",!1)}function ge(e,t){return de(t)?new Me(e,t):new mxSvgCanvas2D(e,!1)}function fe(e){if(!e)return;const t=mxShape.prototype.paint;mxShape.prototype.paint=function(e){let s=null,a=!0;if(null!=this.style&&(a="1"==mxUtils.getValue(this.style,mxConstants.STYLE_POINTER_EVENTS,"1"),s=mxUtils.getValue(this.style,"fillStyle","auto"),null!=this.state&&"auto"==s&&null!=this.style.fill&&null!=this.gradient&&(s="solid")),a&&e instanceof Me&&!this.outline&&(null==this.fill||this.fill==mxConstants.NONE||"solid"!=s)){e.save();const s=this.fill,a=this.stroke;this.fill=null,this.stroke=null,e.passThrough=!0,t.apply(this,[e]),e.passThrough=!1,this.fill=s,this.stroke=a,e.restore()}t.apply(this,[e])}}function ce(e){if(!e)return;const t=mxRectangleShape.prototype.paintBackground;mxRectangleShape.prototype.paintBackground=function(e,s,a,l,o){if(!(e instanceof Me))t.apply(this,[e,s,a,l,o]);else{let t=!0;if(null!=this.style&&(t="1"==mxUtils.getValue(this.style,mxConstants.STYLE_POINTER_EVENTS,"1")),t||null!=this.fill&&this.fill!=mxConstants.NONE||null!=this.stroke&&this.stroke!=mxConstants.NONE){if(t||null!=this.fill&&this.fill!=mxConstants.NONE||(e.pointerEvents=!1),e.begin(),this.isRounded){let t=0;if("1"==mxUtils.getValue(this.style,mxConstants.STYLE_ABSOLUTE_ARCSIZE,0))t=i(l/2,i(o/2,mxUtils.getValue(this.style,mxConstants.STYLE_ARCSIZE,mxConstants.LINE_ARCSIZE)/2));else{const e=mxUtils.getValue(this.style,mxConstants.STYLE_ARCSIZE,100*mxConstants.RECTANGLE_ROUNDING_FACTOR)/100;t=i(l*e,o*e)}e.moveTo(s+t,a),e.lineTo(s+l-t,a),e.quadTo(s+l,a,s+l,a+t),e.lineTo(s+l,a+o-t),e.quadTo(s+l,a+o,s+l-t,a+o),e.lineTo(s+t,a+o),e.quadTo(s,a+o,s,a+o-t),e.lineTo(s,a+t),e.quadTo(s,a,s+t,a)}else e.moveTo(s,a),e.lineTo(s+l,a),e.lineTo(s+l,a+o),e.lineTo(s,a+o),e.lineTo(s,a);e.close(),e.end(),e.fillAndStroke()}}}}function ye(e){if(!e)return;const t=mxRectangleShape.prototype.paintForeground;mxRectangleShape.prototype.paintForeground=function(e,s,a,l,o){e instanceof Me||t.apply(this,[e,s,a,l,o])}}class ke{constructor(e){this.helper=e}fillPolygons(e,t){return this._fillPolygons(e,t)}_fillPolygons(e,t){const s=m(e,t),a=this.renderLines(s,t);return{type:"fillSketch",ops:a}}renderLines(e,t){const s=[];for(const a of e)s.push(...this.helper.doubleLineOps(a[0][0],a[0][1],a[1][0],a[1][1],t));return s}}class me extends ke{fillPolygons(e,t){let s=t.hachureGap;0>s&&(s=4*t.strokeWidth),s=n(s,.1);const a=Object.assign({},t,{hachureGap:s}),l=m(e,a),h=f/180*t.hachureAngle,o=[],i=.5*s*g(h),p=.5*s*d(h);for(const[s,a]of l)k([s,a])&&o.push([[s[0]-i,s[1]+p],[...a]],[[s[0]+i,s[1]-p],[...a]]);const u=this.renderLines(o,t);return{type:"fillSketch",ops:u}}}class Se extends ke{fillPolygons(e,t){const s=this._fillPolygons(e,t),a=Object.assign({},t,{hachureAngle:t.hachureAngle+90}),l=this._fillPolygons(e,a);return s.ops=s.ops.concat(l.ops),s}}class Te{constructor(e){this.helper=e}fillPolygons(e,t){t=Object.assign({},t,{hachureAngle:0});const s=m(e,t);return this.dotsOnLines(s,t)}dotsOnLines(e,s){const a=[];let l=s.hachureGap;0>l&&(l=4*s.strokeWidth),l=n(l,.1);let h=s.fillWeight;0>h&&(h=s.strokeWidth/2);const o=l/4;for(const p of e){const e=k(p),n=e/l,u=t(n)-1,r=e-u*l,d=(p[0][0]+p[1][0])/2-l/4,g=i(p[0][1],p[1][1]);for(let e=0;ea.dashOffset?0>a.hachureGap?4*a.strokeWidth:a.hachureGap:a.dashOffset,h=0>a.dashGap?0>a.hachureGap?4*a.strokeWidth:a.hachureGap:a.dashGap,o=[];return t.forEach(t=>{const i=k(t),p=s(i/(l+h)),n=(i+h-p*(l+h))/2;let u=t[0],r=t[1];u[0]>r[0]&&(u=t[1],r=t[0]);const f=e((r[1]-u[1])/(r[0]-u[0]));for(let e=0;et.hachureGap?4*t.strokeWidth:t.hachureGap,a=0>t.zigzagOffset?s:t.zigzagOffset;t=Object.assign({},t,{hachureGap:s+a});const l=m(e,t);return{type:"fillSketch",ops:this.zigzagLines(l,a,t)}}zigzagLines(t,s,l){const h=[];return t.forEach(t=>{const o=k(t),p=a(o/(2*s));let n=t[0],i=t[1];n[0]>i[0]&&(n=t[1],i=t[0]);const c=e((i[1]-n[1])/(i[0]-n[0]));for(let e=0;es.simplification),i=o?4-4*s.simplification:(1+s.roughness)/2,p=ue(e,1,i);return l&&("solid"===s.fillStyle?a.push(w(p,s)):a.push(q(p,s))),h&&(o?p.forEach(e=>{a.push(L(e,!1,s))}):a.push(F(e,s))),this._d("path",a,s)}opsToPath(e,t){let s="";for(const a of e.ops){const e="number"==typeof t&&0<=t?a.data.map(e=>+e.toFixed(t)):a.data;switch(a.op){case"move":s+=`M${e[0]} ${e[1]} `;break;case"bcurveTo":s+=`C${e[0]} ${e[1]}, ${e[2]} ${e[3]}, ${e[4]} ${e[5]} `;break;case"lineTo":s+=`L${e[0]} ${e[1]} `;}}return s.trim()}toPaths(e){const t=e.sets||[],s=e.options||this.defaultOptions,a=[];for(const l of t){let e=null;switch(l.type){case"path":e={d:this.opsToPath(l),stroke:s.stroke,strokeWidth:s.strokeWidth,fill:Ne};break;case"fillPath":e={d:this.opsToPath(l),stroke:Ne,strokeWidth:0,fill:s.fill||Ne};break;case"fillSketch":e=this.fillSketch(l,s);}e&&a.push(e)}return a}fillSketch(e,t){let s=t.fillWeight;return 0>s&&(s=t.strokeWidth/2),{d:this.opsToPath(e),stroke:t.fill||Ne,strokeWidth:s,fill:Ne}}}class We{constructor(e,t){this.c=e,this.config=t,this.gen=new Le(t)}draw(e){const t=e.sets||[],s=e.options||this.getDefaultOptions();for(let a=0;ai&&(i=t.strokeWidth/2),this.c.setStrokeAlpha(this.c.state.fillAlpha),this.c.setStrokeColor(t.fill||""),this.c.setStrokeWidth(i),this.c.setDashed(!1,o),this._drawToContext(e,t),this.c.setDashed(h,o),this.c.setStrokeWidth(a),this.c.setStrokeColor(s),this.c.setStrokeAlpha(l)}_drawToContext(e,t){this.c.begin();for(let s=0;s + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/client/public/diagram/ styles/sprites.png b/packages/client/public/diagram/ styles/sprites.png new file mode 100644 index 0000000..23e1b49 Binary files /dev/null and b/packages/client/public/diagram/ styles/sprites.png differ diff --git a/packages/client/public/diagram/images/button.gif b/packages/client/public/diagram/images/button.gif new file mode 100644 index 0000000..ad55cab Binary files /dev/null and b/packages/client/public/diagram/images/button.gif differ diff --git a/packages/client/public/diagram/images/checkmark.gif b/packages/client/public/diagram/images/checkmark.gif new file mode 100644 index 0000000..d79444d Binary files /dev/null and b/packages/client/public/diagram/images/checkmark.gif differ diff --git a/packages/client/public/diagram/images/clear.gif b/packages/client/public/diagram/images/clear.gif new file mode 100644 index 0000000..c6acf0a Binary files /dev/null and b/packages/client/public/diagram/images/clear.gif differ diff --git a/packages/client/public/diagram/images/close.gif b/packages/client/public/diagram/images/close.gif new file mode 100644 index 0000000..1069e94 Binary files /dev/null and b/packages/client/public/diagram/images/close.gif differ diff --git a/packages/client/public/diagram/images/close.png b/packages/client/public/diagram/images/close.png new file mode 100644 index 0000000..d319efb Binary files /dev/null and b/packages/client/public/diagram/images/close.png differ diff --git a/packages/client/public/diagram/images/collapsed.gif b/packages/client/public/diagram/images/collapsed.gif new file mode 100644 index 0000000..0276444 Binary files /dev/null and b/packages/client/public/diagram/images/collapsed.gif differ diff --git a/packages/client/public/diagram/images/dropdown.gif b/packages/client/public/diagram/images/dropdown.gif new file mode 100644 index 0000000..9c94ea5 Binary files /dev/null and b/packages/client/public/diagram/images/dropdown.gif differ diff --git a/packages/client/public/diagram/images/dropdown.png b/packages/client/public/diagram/images/dropdown.png new file mode 100644 index 0000000..0aeac2d Binary files /dev/null and b/packages/client/public/diagram/images/dropdown.png differ diff --git a/packages/client/public/diagram/images/edit.gif b/packages/client/public/diagram/images/edit.gif new file mode 100644 index 0000000..3c07607 Binary files /dev/null and b/packages/client/public/diagram/images/edit.gif differ diff --git a/packages/client/public/diagram/images/error.gif b/packages/client/public/diagram/images/error.gif new file mode 100644 index 0000000..14e1aee Binary files /dev/null and b/packages/client/public/diagram/images/error.gif differ diff --git a/packages/client/public/diagram/images/expanded.gif b/packages/client/public/diagram/images/expanded.gif new file mode 100644 index 0000000..3767b0b Binary files /dev/null and b/packages/client/public/diagram/images/expanded.gif differ diff --git a/packages/client/public/diagram/images/grid.gif b/packages/client/public/diagram/images/grid.gif new file mode 100644 index 0000000..f4e7063 Binary files /dev/null and b/packages/client/public/diagram/images/grid.gif differ diff --git a/packages/client/public/diagram/images/handle-fixed.png b/packages/client/public/diagram/images/handle-fixed.png new file mode 100644 index 0000000..b4b600b Binary files /dev/null and b/packages/client/public/diagram/images/handle-fixed.png differ diff --git a/packages/client/public/diagram/images/handle-main.png b/packages/client/public/diagram/images/handle-main.png new file mode 100644 index 0000000..ee067ff Binary files /dev/null and b/packages/client/public/diagram/images/handle-main.png differ diff --git a/packages/client/public/diagram/images/handle-rotate.png b/packages/client/public/diagram/images/handle-rotate.png new file mode 100644 index 0000000..dcb0e5e Binary files /dev/null and b/packages/client/public/diagram/images/handle-rotate.png differ diff --git a/packages/client/public/diagram/images/handle-secondary.png b/packages/client/public/diagram/images/handle-secondary.png new file mode 100644 index 0000000..b4a3090 Binary files /dev/null and b/packages/client/public/diagram/images/handle-secondary.png differ diff --git a/packages/client/public/diagram/images/handle-terminal.png b/packages/client/public/diagram/images/handle-terminal.png new file mode 100644 index 0000000..ec03b31 Binary files /dev/null and b/packages/client/public/diagram/images/handle-terminal.png differ diff --git a/packages/client/public/diagram/images/help.png b/packages/client/public/diagram/images/help.png new file mode 100644 index 0000000..17ee2eb Binary files /dev/null and b/packages/client/public/diagram/images/help.png differ diff --git a/packages/client/public/diagram/images/locked.png b/packages/client/public/diagram/images/locked.png new file mode 100644 index 0000000..8dbac82 Binary files /dev/null and b/packages/client/public/diagram/images/locked.png differ diff --git a/packages/client/public/diagram/images/logo.png b/packages/client/public/diagram/images/logo.png new file mode 100644 index 0000000..053a1eb Binary files /dev/null and b/packages/client/public/diagram/images/logo.png differ diff --git a/packages/client/public/diagram/images/maximize.gif b/packages/client/public/diagram/images/maximize.gif new file mode 100644 index 0000000..e27cf3e Binary files /dev/null and b/packages/client/public/diagram/images/maximize.gif differ diff --git a/packages/client/public/diagram/images/minimize.gif b/packages/client/public/diagram/images/minimize.gif new file mode 100644 index 0000000..1e95e7c Binary files /dev/null and b/packages/client/public/diagram/images/minimize.gif differ diff --git a/packages/client/public/diagram/images/move.png b/packages/client/public/diagram/images/move.png new file mode 100644 index 0000000..9f4bc91 Binary files /dev/null and b/packages/client/public/diagram/images/move.png differ diff --git a/packages/client/public/diagram/images/nocolor.png b/packages/client/public/diagram/images/nocolor.png new file mode 100644 index 0000000..aec4534 Binary files /dev/null and b/packages/client/public/diagram/images/nocolor.png differ diff --git a/packages/client/public/diagram/images/normalize.gif b/packages/client/public/diagram/images/normalize.gif new file mode 100644 index 0000000..34a8d30 Binary files /dev/null and b/packages/client/public/diagram/images/normalize.gif differ diff --git a/packages/client/public/diagram/images/point.gif b/packages/client/public/diagram/images/point.gif new file mode 100644 index 0000000..9074c39 Binary files /dev/null and b/packages/client/public/diagram/images/point.gif differ diff --git a/packages/client/public/diagram/images/refresh.png b/packages/client/public/diagram/images/refresh.png new file mode 100644 index 0000000..e1d0c6a Binary files /dev/null and b/packages/client/public/diagram/images/refresh.png differ diff --git a/packages/client/public/diagram/images/resize.gif b/packages/client/public/diagram/images/resize.gif new file mode 100644 index 0000000..ff558db Binary files /dev/null and b/packages/client/public/diagram/images/resize.gif differ diff --git a/packages/client/public/diagram/images/round-drop.png b/packages/client/public/diagram/images/round-drop.png new file mode 100644 index 0000000..b5e2fb6 Binary files /dev/null and b/packages/client/public/diagram/images/round-drop.png differ diff --git a/packages/client/public/diagram/images/search.png b/packages/client/public/diagram/images/search.png new file mode 100644 index 0000000..d763a72 Binary files /dev/null and b/packages/client/public/diagram/images/search.png differ diff --git a/packages/client/public/diagram/images/separator.gif b/packages/client/public/diagram/images/separator.gif new file mode 100644 index 0000000..5c1b895 Binary files /dev/null and b/packages/client/public/diagram/images/separator.gif differ diff --git a/packages/client/public/diagram/images/submenu.gif b/packages/client/public/diagram/images/submenu.gif new file mode 100644 index 0000000..ffe7617 Binary files /dev/null and b/packages/client/public/diagram/images/submenu.gif differ diff --git a/packages/client/public/diagram/images/transparent.gif b/packages/client/public/diagram/images/transparent.gif new file mode 100644 index 0000000..76040f2 Binary files /dev/null and b/packages/client/public/diagram/images/transparent.gif differ diff --git a/packages/client/public/diagram/images/triangle-down.png b/packages/client/public/diagram/images/triangle-down.png new file mode 100644 index 0000000..d03b98f Binary files /dev/null and b/packages/client/public/diagram/images/triangle-down.png differ diff --git a/packages/client/public/diagram/images/triangle-left.png b/packages/client/public/diagram/images/triangle-left.png new file mode 100644 index 0000000..44b8425 Binary files /dev/null and b/packages/client/public/diagram/images/triangle-left.png differ diff --git a/packages/client/public/diagram/images/triangle-right.png b/packages/client/public/diagram/images/triangle-right.png new file mode 100644 index 0000000..9865628 Binary files /dev/null and b/packages/client/public/diagram/images/triangle-right.png differ diff --git a/packages/client/public/diagram/images/triangle-up.png b/packages/client/public/diagram/images/triangle-up.png new file mode 100644 index 0000000..6d93676 Binary files /dev/null and b/packages/client/public/diagram/images/triangle-up.png differ diff --git a/packages/client/public/diagram/images/unlocked.png b/packages/client/public/diagram/images/unlocked.png new file mode 100644 index 0000000..5ea44c1 Binary files /dev/null and b/packages/client/public/diagram/images/unlocked.png differ diff --git a/packages/client/public/diagram/images/warning.gif b/packages/client/public/diagram/images/warning.gif new file mode 100644 index 0000000..705235f Binary files /dev/null and b/packages/client/public/diagram/images/warning.gif differ diff --git a/packages/client/public/diagram/images/warning.png b/packages/client/public/diagram/images/warning.png new file mode 100644 index 0000000..2f78789 Binary files /dev/null and b/packages/client/public/diagram/images/warning.png differ diff --git a/packages/client/public/diagram/images/window-title.gif b/packages/client/public/diagram/images/window-title.gif new file mode 100644 index 0000000..231def8 Binary files /dev/null and b/packages/client/public/diagram/images/window-title.gif differ diff --git a/packages/client/public/diagram/images/window.gif b/packages/client/public/diagram/images/window.gif new file mode 100644 index 0000000..6631c4f Binary files /dev/null and b/packages/client/public/diagram/images/window.gif differ diff --git a/packages/client/public/diagram/resources/editor.txt b/packages/client/public/diagram/resources/editor.txt new file mode 100644 index 0000000..53e8712 --- /dev/null +++ b/packages/client/public/diagram/resources/editor.txt @@ -0,0 +1,5 @@ +askZoom=Enter zoom (%) +properties=Properties +outline=Outline +tasks=Tasks +help=Help diff --git a/packages/client/public/diagram/resources/graph.txt b/packages/client/public/diagram/resources/graph.txt new file mode 100644 index 0000000..66e85d4 --- /dev/null +++ b/packages/client/public/diagram/resources/graph.txt @@ -0,0 +1,1200 @@ +about=关于 +aboutDrawio=关于 draw.io +accessDenied=没有权限访问 +action=操作 +actualSize=实际尺寸 +add=添加 +addAccount=添加账户 +addedFile=已添加 {1} +addImages=添加图片 +addImageUrl=添加图片地址 +addLayer=添加图层 +addProperty=添加属性 +address=地址 +addToExistingDrawing=添加至当前绘图 +addWaypoint=添加航点 +adjustTo=调整到 +advanced=高级 +align=对齐 +alignment=对齐 +allChangesLost=所有修改均将会丢失! +allPages=所有页面 +allProjects=所有方案 +allSpaces=所有部分 +allTags=所有标签 +anchor=锚 +android=Android +angle=角度 +arc=圆弧 +areYouSure=是否确定? +ensureDataSaved=关闭前请确保您的数据已保存。 +allChangesSaved=所有更改均已保存 +allChangesSavedInDrive=所有更改均保存至 Google Drive 中 +allowPopups=允许弹出式窗口以阻止此对话框 +allowRelativeUrl=允许相对地址 +alreadyConnected=节点已连接 +apply=应用 +archiMate21=ArchiMate 2.1 +arrange=调整图形 +arrow=箭头 +arrows=箭头 +asNew=作为新绘图 +atlas=Atlas +author=作者 +authorizationRequired=需要授权 +authorizeThisAppIn=在 {1} 里授权此应用: +authorize=授权 +authorizing=正在授权 +automatic=自动 +autosave=自动保存 +autosize=自动调整 +attachments=附件 +aws=AWS +aws3d=AWS 3D +azure=Azure +back=后退 +background=背景 +backgroundColor=背景色 +backgroundImage=背景图片 +basic=基本 +beta=beta +blankDrawing=空白绘图 +blankDiagram=空白框图 +block=区块 +blockquote=区块引言 +blog=博客 +bold=粗体 +bootstrap=Bootstrap +border=边框 +borderColor=边框颜色 +borderWidth=边框宽度 +bottom=下 +bottomAlign=向下对齐 +bottomLeft=左下 +bottomRight=右下 +bpmn=BPMN +bringForward=上移一层 +browser=浏览器 +bulletedList=项目符号列表 +business=商务 +busy=处理中 +cabinets=机箱 +cancel=取消 +center=水平居中 +cannotLoad=载入失败。请稍后重试。 +cannotLogin=登录失败。请稍后重试。 +cannotOpenFile=无法打开文件 +change=更改 +changeOrientation=改变方向 +changeUser=更改用户 +changeStorage=修改存储方式 +changesNotSaved=更改尚未保存 +classDiagram=类图 +userJoined={1} 已加入 +userLeft={1} 已离开 +chatWindowTitle=聊天 +chooseAnOption=请选择一项 +chromeApp=Chrome 应用 +collaborativeEditingNotice=协同编辑的重要通知 +compare=比较 +compressed=已压缩 +commitMessage=提交信息 +configLinkWarn=该链接将配置 draw.io. 仅当您信任提供给你链接的人时点击确定. +configLinkConfirm=点击确定配置并重启 draw.io +container=容器 +csv=CSV +dark=深色 +diagramXmlDesc=XML 文件 +diagramHtmlDesc=HTML 文件 +diagramPngDesc=可编辑位图文件 +diagramSvgDesc=可编辑矢量图文件 +didYouMeanToExportToPdf=是否要导出到 PDF? +draftFound={1} 的草稿已经找到。将其加载到编辑器或将其丢弃以继续。 +draftRevisionMismatch=此页面上的共享草稿有一个不同的版本。请从草稿编辑以确保您正在使用最新版本。 +selectDraft=选择一个草稿继续编辑: +dragAndDropNotSupported=暂不支持图片拖放功能。是否要使用导入? +dropboxCharsNotAllowed=系统不允许使用下列字符:\ / : ? * " | +check=核查 +checksum=校验码 +circle=圆形 +cisco=Cisco +classic=经典 +clearDefaultStyle=清除默认风格 +clearWaypoints=清除航点 +clipart=剪贴画 +close=关闭 +closingFile=正在关闭文件 +realtimeCollaboration=Real-Time Collaboration +collaborator=合作者 +collaborators=合作者 +collapse=折叠 +collapseExpand=折叠 / 展开 +collapse-expand=点击折叠 / 展开\nShift-点击以移动周边图形 \nAlt-点击以保护组别尺寸 +collapsible=可折叠 +comic=手绘 +comment=评论 +commentsNotes=评论 / 备注 +compress=压缩 +configuration=配置 +connect=连接 +connecting=正在连接 +connectWithDrive=连接 Google Drive +connection=连接 +connectionArrows=连接箭头 +connectionPoints=连接点 +constrainProportions=限制比例 +containsValidationErrors=包含验证错误 +copiedToClipboard=已复制到剪贴板 +copy=复制 +copyConnect=连接时复制 +copyCreated=已经创建文件的副本。 +copyData=复制数据 +copyOf={1} 的副本 +copyOfDrawing=绘图副本 +copySize=复制大小 +copyStyle=复制样式 +create=创建 +createNewDiagram=创建新绘图 +createRevision=创建修订版本 +createShape=创建图形 +crop=导出单页 +curved=曲线 +custom=自定义 +current=当前 +currentPage=当前页 +cut=剪切 +dashed=虚线 +decideLater=稍后再决定 +default=默认值 +delete=删除 +deleteColumn=删除列 +deleteLibrary401=没有权限删除此图库 +deleteLibrary404=未找到所选图库 +deleteLibrary500=删除图库时出错 +deleteLibraryConfirm=您即将永久删除此图库。您确定要这样操作吗? +deleteRow=删除行 +description=描述 +device=设备 +diagram=绘图 +diagramContent=绘图内容 +diagramLocked=绘图已经锁定以避免进一步的数据丢失。 +diagramLockedBySince=绘图已经在 {2} 之前被 {1} 锁定 +diagramName=绘图名称 +diagramIsPublic=绘图为公开状态 +diagramIsNotPublic=绘图为未公开状态 +diamond=方块 +diamondThin=方块(细) +didYouKnow=您知道吗...... +direction=方向 +discard=丢弃 +discardChangesAndReconnect=取消更改并重新连接 +googleDriveMissingClickHere=找不到 Google Drive?请点击这里! +discardChanges=放弃更改 +disconnected=未连接 +distribute=等距分布 +done=完成 +doNotShowAgain=不再显示 +dotted=点线 +doubleClickOrientation=双击以改变方向 +doubleClickTooltip=双击以插入文字 +doubleClickChangeProperty=双击以更改属性名 +download=下载 +downloadDesktop=获取桌面版 +downloadAs=下载为 +clickHereToSave=点击此处保存。 +dpi=DPI +draftDiscarded=草稿已丢弃 +draftSaved=草稿已保存 +dragElementsHere=把元素拖至此处 +dragImagesHere=把图像或网络链接拖至此处 +dragUrlsHere=将 URL 地址拖至此处 +draw.io=draw.io +drawing=绘图 {1} +drawingEmpty=绘图空白 +drawingTooLarge=绘图过大 +drawioForWork=Draw.io for GSuite +dropbox=Dropbox +duplicate=创建副本 +duplicateIt=复制 {1} +divider=分隔线 +dx=Dx +dy=Dy +east=向右 +edit=编辑 +editData=编辑数据 +editDiagram=编辑绘图 +editGeometry=编辑几何图形 +editImage=编辑图片 +editImageUrl=编辑图片 URL 地址 +editLink=编辑链接 +editShape=编辑图形 +editStyle=编辑样式 +editText=编辑文字 +editTooltip=编辑提示 +glass=玻璃 +googleImages=Google 图片 +imageSearch=图片搜索 +eip=EIP +embed=嵌入 +embedFonts=嵌入字体 +embedImages=嵌入图片 +mainEmbedNotice=将此粘贴至页面上 +electrical=电路 +ellipse=椭圆形 +embedNotice=将此一次性粘贴至本页页尾 +enterGroup=进入组进行编辑 +enterName=输入名称 +enterPropertyName=输入属性名 +enterValue=输入值 +entityRelation=实体关系 +entityRelationshipDiagram=E-R图 +error=出错 +errorDeletingFile=删除文件出错 +errorLoadingFile=加载文件出错 +errorRenamingFile=文件修改名称出错 +errorRenamingFileNotFound=文件修改名称出错。找不到文件。 +errorRenamingFileForbidden=文件修改名称出错。没有足够的访问权限。 +errorSavingDraft=保存草稿出错 +errorSavingFile=保存文件出错 +errorSavingFileUnknown=Google 服务器授权出错。请刷新页面,然后重试。 +errorSavingFileForbidden=保存文件时出错。没有足够的访问权限。 +errorSavingFileNameConflict=无法保存此绘图。当前页面已经包含名为 '{1}' 的文件。 +errorSavingFileNotFound=保存文件时出错,文件未找到。 +errorSavingFileReadOnlyMode=只读模式开启时无法保存绘图。 +errorSavingFileSessionTimeout=您的会话已经结束。请 {2},然后返回此标签以尝试再次保存。 +errorSendingFeedback=发送反馈出错。 +errorUpdatingPreview=更新预览出错。 +exit=退出 +exitGroup=退出编辑组 +expand=展开 +export=导出 +exporting=正在导出 +exportAs=导出为 +exportOptionsDisabled=已禁止导出 +exportOptionsDisabledDetails=所有者已禁止评论者及浏览者下载、打印或复制该文件。 +externalChanges=外部修改 +extras=其它 +facebook=Facebook +failedToSaveTryReconnect=保存失败,正在尝试重新连接 +featureRequest=增加功能请求 +feedback=反馈 +feedbackSent=反馈发送成功 +floorplans=平面图 +file=文件 +fileChangedOverwriteDialog=文件已经被修改。是否保存文件并覆盖这些更改? +fileChangedSyncDialog=文件已经被修改。是否要同步这些修改? +fileChangedSync=文件已经被修改。点击这里进行同步。 +overwrite=覆盖 +synchronize=同步 +filename=文件名 +fileExists=文件已存在 +fileMovedToTrash=文件已经移到垃圾箱 +fileNearlyFullSeeFaq=文件即将达到上限,请参阅常见问题 +fileNotFound=未找到文件 +repositoryNotFound=未找到资源库 +fileNotFoundOrDenied=文件未找到。其不存在或您没有查阅权限。 +fileNotLoaded=文件无法加载 +fileNotSaved=文件无法保存 +fileOpenLocation=你想如何打开这些文件? +filetypeHtml=.html 会保存文件为 HTML 格式并重定向到云端 URL +filetypePng=.png 会保存文件为 PNG 格式并包含嵌入数据 +filetypeSvg=.svg 会保存文件为 SVG 格式并包含嵌入数据 +fileWillBeSavedInAppFolder={1} 将保存至应用软件文件夹 +fill=填充 +fillColor=填充色 +filterCards=卡片筛选 +find=查找 +fit=适应大小 +fitContainer=调整容器尺寸 +fitIntoContainer=适应容器尺寸 +fitPage=整页显示 +fitPageWidth=适应页面宽度 +fitTo=适应 +fitToSheetsAcross=横向页数 +fitToBy=按 +fitToSheetsDown=纵向页数 +fitTwoPages=双页 +fitWindow=适应窗口大小 +flip=翻转 +flipH=水平翻转 +flipV=垂直翻转 +flowchart=流程图 +folder=文件夹 +font=字体 +fontColor=字体颜色 +fontFamily=字体 +fontSize=字体大小 +forbidden=您没有该文件的访问权限 +format=格式 +formatPanel=格式面板 +formatted=格式化 +formattedText=格式化文本 +formatPng=PNG +formatGif=GIF +formatJpg=JPEG +formatPdf=PDF +formatSql=SQL +formatSvg=SVG +formatHtmlEmbedded=HTML +formatSvgEmbedded=SVG(XML) +formatVsdx=VSDX +formatVssx=VSSX +formatXmlPlain=XML(文本文件) +formatXml=XML +forum=讨论组 / 帮助论坛 +freehand=自由绘图 +fromTemplate=从模板 +fromTemplateUrl=从模板 URL 地址 +fromText=从文本 +fromUrl=从 URL 地址 +fromThisPage=从当前页 +fullscreen=全屏 +gap=间隙 +gcp=GCP +general=通用 +getNotionChromeExtension=获取 Notion Chrome 扩展程序 +github=GitHub +gitlab=GitLab +gliffy=Gliffy +global=全局 +googleDocs=Google 文档 +googleDrive=Google Drive +googleGadget=Google Gadget +googlePlus=Google+ +googleSharingNotAvailable=分享只有使用 Google Drive 时可用. 请点击下方的打开, 从更多操作菜单中分享. +googleSlides=Google 幻灯片 +googleSites=Google 协作平台 +googleSheets=Google 表格 +gradient=渐变 +gradientColor=颜色 +grid=网格 +gridColor=网格线颜色 +gridSize=网格大小 +group=组合 +guides=参考线 +hateApp=我讨厌 draw.io +heading=标题 +height=高 +help=帮助 +helpTranslate=帮助我们翻译此应用 +hide=隐藏 +hideIt=隐藏 {1} +hidden=已隐藏 +home=首页 +horizontal=水平 +horizontalFlow=水平流 +horizontalTree=水平树 +howTranslate=你所选语言的翻译质量如何? +html=HTML +htmlText=HTML 文本 +id=ID +iframe=IFrame +ignore=忽略 +image=图片 +imageUrl=图片 URL 地址 +images=图片 +imagePreviewError=无法预览图片。请检查 URL 地址。 +imageTooBig=图片太大 +imgur=Imgur +import=导入 +importFrom=从...导入 +includeCopyOfMyDiagram=包含绘图副本 +increaseIndent=增加缩进 +decreaseIndent=减少缩进 +insert=插入 +insertColumnBefore=左边插入列 +insertColumnAfter=右边插入列 +insertEllipse=插入椭圆 +insertImage=插入图片 +insertHorizontalRule=插入水平标尺 +insertLink=插入链接 +insertPage=插入页面 +insertRectangle=插入矩形 +insertRhombus=插入菱形 +insertRowBefore=上方插入行 +insertRowAfter=下方插入行 +insertText=插入文本 +inserting=正在插入 +installApp=安装应用 +invalidFilename=绘图名称不能包含以下特殊字符: \ / | : ; { } < > & + ? = " +invalidLicenseSeeThisPage=您的许可无效,请参阅此页面。 +invalidInput=无效输入 +invalidName=无效名称 +invalidOrMissingFile=无效或丢失的文件 +invalidPublicUrl=无效的公开 URL 地址 +isometric=等尺寸 +ios=iOS +italic=斜体 +kennedy=Kennedy +keyboardShortcuts=快捷键 +labels=标签 +layers=图层 +landscape=横向 +language=语言 +leanMapping=价值流图 +lastChange={1}以前最新更改 +lessThanAMinute=一分钟以内 +licensingError=授权出错 +licenseHasExpired={1} 的许可证已于 {2} 过期。请点击此处。 +licenseRequired=该功能需要 draw.io 被授权 +licenseWillExpire={1} 的许可证将于 {2} 过期。请点击此处。 +lineJumps=跨线 +linkAccountRequired=如果绘图未公开,则需要提供谷歌账户才能查看该链接。 +linkText=链接文本 +list=列表 +minute=分钟 +minutes=分钟 +hours=小时 +days=天 +months=月 +years=年 +restartForChangeRequired=更改将在页面刷新后生效。 +laneColor=泳道颜色 +lastModified=最近修改 +layout=布局 +left=左 +leftAlign=左对齐 +leftToRight=右对齐 +libraryTooltip=将图形拖放至此或单击+以插入。双击进行编辑。 +lightbox=灯箱特效 +line=线条 +lineend=线末端 +lineheight=行高 +linestart=线始端 +linewidth=线宽 +link=连接 +links=连接 +loading=加载中 +lockUnlock=锁定 / 解锁 +loggedOut=注销 +logIn=登录 +loveIt=我爱 {1} +lucidchart=Lucidchart +maps=地图 +mathematicalTypesetting=数学排版 +makeCopy=创建副本 +manual=手册 +merge=合并 +mermaid=Mermaid +microsoftOffice=Microsoft Office +microsoftExcel=Microsoft Excel +microsoftPowerPoint=Microsoft PowerPoint +microsoftWord=Microsoft Word +middle=垂直居中 +minimal=Minimal +misc=杂项 +mockups=实体模型 +modificationDate=修改日期 +modifiedBy=修改者 +more=更多 +moreResults=更多结果 +moreShapes=更多图形 +move=移动 +moveToFolder=移动至文件夹 +moving=移动中 +moveSelectionTo=将所选移至 {1} +name=名称 +navigation=导航 +network=网络 +networking=网络 +new=新建 +newLibrary=新增图库 +nextPage=下一页 +no=否 +noPickFolder=不,选择文件夹 +noAttachments=未找到附件 +noColor=无颜色 +noFiles=无文件 +noFileSelected=未选择文件 +noLibraries=未找到图库 +noMoreResults=无其他结果 +none=无 +noOtherViewers=无其他查阅者 +noPlugins=无插件 +noPreview=无预览 +noResponse=服务器无响应 +noResultsFor=未找到 '{1}' 的相关结果 +noRevisions=无修订 +noSearchResults=查询无结果 +noPageContentOrNotSaved=此页面上找不到锚点,或尚未保存 +normal=正常 +north=向上 +notADiagramFile=非绘图文件 +notALibraryFile=非图库文件 +notAvailable=不可用 +notAUtf8File=非 UTF-8 格式文件 +notConnected=未连接 +note=备注 +notion=Notion +notSatisfiedWithImport=对导入不满意? +notUsingService=未使用 {1}? +numberedList=编号列表 +offline=离线 +ok=确定 +oneDrive=OneDrive +online=线上 +opacity=不透明度 +open=打开 +openArrow=开放的箭头 +openExistingDiagram=打开现有绘图 +openFile=打开文件 +openFrom=从...打开 +openLibrary=打开图库 +openLibraryFrom=从...打开图库 +openLink=打开链接 +openInNewWindow=在新窗口打开 +openInThisWindow=在当前窗口打开 +openIt=打开{1} +openRecent=打开最近使用的文件 +openSupported=支持的格式有本软件保存的文件 (.xml), .vsdx 及 .gliffy +options=选项 +organic=力导向图 +orgChart=组织结构图 +orthogonal=正交 +otherViewer=其他查阅者 +otherViewers=其他查阅者 +outline=缩略图 +oval=椭圆形 +page=页面 +pageContent=页面内容 +pageNotFound=未找到页面 +pageWithNumber=第 {1} 页 +pages=页面 +pageView=页面视图 +pageSetup=页面设置 +pageScale=页面比例 +pan=移动画布 +panTooltip=按住空格键并拖拽以移动画布 +paperSize=页面尺寸 +pattern=样式 +parallels=Parallels +paste=粘贴 +pasteData=粘贴数据 +pasteHere=在这粘贴 +pasteSize=粘贴大小 +pasteStyle=粘贴样式 +perimeter=周长 +permissionAnyone=任何人均可编辑 +permissionAuthor=只有本人可编辑 +pickFolder=选择文件夹 +pickLibraryDialogTitle=选择图库 +publicDiagramUrl=绘图的公共 URL 地址 +placeholders=占位符 +plantUml=PlantUML +plugins=插件 +pluginUrl=插件 URL 地址 +pluginWarning=本页面已要求载入以下插件:\n \n {1}\n \n 是否现在载入这些插件?\n \n 备注:确保在完全理解与此相关的安全问题的情况下再允许这些插件运行。\n +plusTooltip=单击进行连接与复制(ctrl+单击进行复制,shift+单击进行连接)。拖拽进行连接(ctrl+拖拽进行复制)。 +portrait=竖向 +position=位置 +posterPrint=海报样式 +preferences=喜好 +preview=预览 +previousPage=上一页 +print=打印 +printAllPages=打印所有页 +procEng=工艺流程 +project=方案 +priority=优先级 +properties=属性 +publish=发布 +quickStart=快速入门视频 +rack=机架 +radial=Radial +radialTree=径向树 +readOnly=只读 +reconnecting=重新连接 +recentlyUpdated=最近更新 +recentlyViewed=最近阅览 +rectangle=矩形 +redirectToNewApp=该文件是在此应用软件的新版本中所创建或修改的。正在重新定向。 +realtimeTimeout=似乎您在离线状态下做过更改。对不起,这些更改不予保存。 +redo=重做 +refresh=刷新 +regularExpression=正则表达式 +relative=相对 +relativeUrlNotAllowed=不允许使用相对 URL 地址 +rememberMe=记住我 +rememberThisSetting=记住此设置 +removeFormat=清除格式 +removeFromGroup=移出组合 +removeIt=删除 {1} +removeWaypoint=删除航点 +rename=重命名 +renamed=已重命名 +renameIt=重命名 {1} +renaming=正在重命名 +replace=替换 +replaceIt={1} 已经存在了。确定要替换它吗? +replaceExistingDrawing=替换当前绘图 +required=必填 +reset=重置 +resetView=重置视图 +resize=调整大小 +resizeLargeImages=您是否想调整大图片的大小使应用运行更快? +retina=Retina +responsive=响应式 +restore=恢复 +restoring=正在恢复 +retryingIn={1} 秒后重试 +retryingLoad=载入失败,正在重试... +retryingLogin=登录超时,正在重试... +reverse=翻转 +revision=修订 +revisionHistory=修订历史 +rhombus=菱形 +right=右 +rightAlign=右对齐 +rightToLeft=由右至左 +rotate=旋转 +rotateTooltip=点选拖拽旋转,或点击选择90度 +rotation=旋转 +rounded=圆角 +save=保存 +saveAndExit=保存并退出 +saveAs=另存为 +saveAsXmlFile=另存为XML文件? +saved=已保存 +saveDiagramFirst=请先保存绘图 +saveDiagramsTo=保存绘图到 +saveLibrary403=没有足够的权限编辑此图库 +saveLibrary500=保存图库时出错 +saveLibraryReadOnly=只读模式开启时无法保存图库 +saving=正在保存 +scratchpad=便笺本 +scrollbars=滚动条 +search=搜索 +searchShapes=搜索图形 +selectAll=全选 +selectionOnly=仅所选内容 +selectCard=选择卡片 +selectEdges=选择边线 +selectFile=选择文件 +selectFolder=选择文件夹 +selectFont=选择字体 +selectNone=全不选 +selectTemplate=选择模板 +selectVertices=选择顶点 +sendBackward=下移一层 +sendMessage=发送 +sendYourFeedback=发送您的反馈 +serviceUnavailableOrBlocked=服务无法使用或已被屏蔽 +sessionExpired=会话已过期,请刷新浏览器窗口。 +sessionTimeoutOnSave=会话已超时,您的 Google Drive 连接已断开。按确定键登录并保存。 +setAsDefaultStyle=设置为默认样式 +shadow=阴影 +shape=形状 +shapes=形状 +share=共享 +shareCursor=Share Mouse Cursor +shareLink=共享编辑的链接 +sharingAvailable=共享可用于 Google Drive 和 OneDrive 文件. +sharp=锐利 +show=显示 +showRemoteCursors=Show Remote Mouse Cursors +showStartScreen=显示开始画面 +sidebarTooltip=单击以展开。将图形拖拽至绘图中。Shift+单击以改变所选内容。Alt+单击以插入及连接。 +signs=标识 +signOut=注销 +simple=简单 +simpleArrow=简单箭头 +simpleViewer=Simple Viewer +size=大小 +sketch=草图 +snapToGrid=对齐到网格 +solid=实线 +sourceSpacing=源距 +south=向下 +software=软件 +space=空间 +spacing=间距 +specialLink=特殊链接 +standard=标准 +startDrawing=开始绘图 +stopDrawing=结束绘图 +starting=开启中 +straight=直线 +strikethrough=删除线 +strokeColor=线条颜色 +style=样式 +subscript=下标 +summary=概要 +superscript=上标 +support=支持 +swimlaneDiagram=泳道图 +sysml=SysML +tags=标签 +table=表格 +tables=表格 +takeOver=Take Over +targetSpacing=目标间距 +template=模板 +templates=模板 +text=文本 +textAlignment=文本对齐 +textOpacity=字体不透明度 +theme=主题 +timeout=超时 +title=标题 +to=至 +toBack=移至最后 +toFront=移至最前 +tooLargeUseDownload=Too large, use download instead. +toolbar=工具栏 +tooltips=提示 +top=上 +topAlign=向上对齐 +topLeft=左上 +topRight=右上 +transparent=透明 +transparentBackground=透明背景 +trello=Trello +tryAgain=重试 +tryOpeningViaThisPage=尝试通过此页面开启 +turn=旋转90° +type=类型 +twitter=Twitter +uml=UML +underline=下划线 +undo=撤销 +ungroup=取消组合 +unmerge=取消合并 +unsavedChanges=未保存的更改 +unsavedChangesClickHereToSave=修改未保存。点击此处保存。 +untitled=未命名 +untitledDiagram=未命名绘图 +untitledLayer=未命名图层 +untitledLibrary=未命名图库 +unknownError=未知错误 +updateFile=更新{1} +updatingDocument=文件更新中。请稍候... +updatingPreview=预览更新中。请稍候... +updatingSelection=选择更新中。请稍候... +upload=上传 +url=URL +useOffline=离线使用 +useRootFolder=要使用根目录吗? +userManual=用户手册 +vertical=垂直 +verticalFlow=垂直流 +verticalTree=垂直树 +view=查看 +viewerSettings=Viewer Settings +viewUrl=用于查看的链接:{1} +voiceAssistant=语音助手(测试版) +warning=警告 +waypoints=航点 +west=向左 +width=宽 +wiki=Wiki +wordWrap=自动换行 +writingDirection=书写方向 +yes=是 +yourEmailAddress=您的电子邮件地址 +zoom=缩放 +zoomIn=放大 +zoomOut=缩小 +basic=基本 +businessprocess=业务流程图 +charts=图表 +engineering=工程 +flowcharts=流程图 +gmdl=材料设计 +mindmaps=思维导图 +mockups=模型图 +networkdiagrams=网络结构图 +nothingIsSelected=未选择 +other=其他 +softwaredesign=软件设计图 +venndiagrams=维恩图 +webEmailOrOther=网站、电子邮件或其他网络地址 +webLink=Web链接 +wireframes=线框图 +property=属性 +value=值 +showMore=显示更多 +showLess=显示更少 +myDiagrams=我的绘图 +allDiagrams=全部绘图 +recentlyUsed=最近使用 +listView=列表视图 +gridView=网格视图 +resultsFor={1}' 的结果 +oneDriveCharsNotAllowed=不允许下列字符: ~ " # % * : < > ? / \ { | } +oneDriveInvalidDeviceName=指定的设备名称无效 +officeNotLoggedOD=您没有登录到 OneDrive. 请先打开 draw.io 任务栏并登录. +officeSelectSingleDiag=请选择一个没有其他内容的 draw.io 绘图 +officeSelectDiag=请选择 draw.io 绘图 +officeCannotFindDiagram=在选择中无法找到 draw.io 绘图 +noDiagrams=没有找到绘图 +authFailed=认证失败 +officeFailedAuthMsg=无法成功认证用户或认证应用 +convertingDiagramFailed=转换绘图失败 +officeCopyImgErrMsg=由于主机应用的一些限制, 图片无法被插入. 请手动赋值图片然后粘贴到文档中. +insertingImageFailed=插入图片失败 +officeCopyImgInst=说明: 右键点击下方的图片. 在上下文菜单中选择 "复制图片". 然后在文档中, 右键点击并在上下文菜单中选择 "粘贴" +folderEmpty=文件夹为空 +recent=最近 +sharedWithMe=与我分享 +sharepointSites=Sharepoint 站点 +errorFetchingFolder=获取文件夹项目出错 +errorAuthOD=OneDrive 认证出错 +officeMainHeader=添加 draw.io 绘图到您的文档 +officeStepsHeader=该加载项执行以下步骤: +officeStep1=连接到 Microsoft OneDrive, Google Drive 或您的设备 +officeStep2=选择 draw.io 绘图 +officeStep3=插入绘图到文档 +officeAuthPopupInfo=请在弹出的窗口中完成认证 +officeSelDiag=选择 draw.io 绘图 +files=文件 +shared=已分享 +sharepoint=Sharepoint +officeManualUpdateInst=说明: 从文档中复制 draw.io 绘图. 然后在下方的框中右键点击然后在上下文菜单中选择 "粘贴". +officeClickToEdit=点击图标开始编辑 +pasteDiagram=在这里粘贴 draw.io 绘图 +connectOD=连接到 OneDrive +selectChildren=选择子元素 +selectSiblings=选择同级元素 +selectParent=选择父元素 +selectDescendants=选择后续元素 +lastSaved=上次保存 {1} 之前 +resolve=解决 +reopen=重新打开 +showResolved=显示已解决 +reply=回复 +objectNotFound=找不到对象 +reOpened=重新打开的 +markedAsResolved=标记为已解决 +noCommentsFound=找不到评论 +comments=评论 +timeAgo={1} 之前 +confluenceCloud=Confluence 云 +libraries=库 +confAnchor=Confluence 页面锚点 +confTimeout=连接超时 +confSrvTakeTooLong={1} 服务器响应时间过长 +confCannotInsertNew=无法在新的 Confluence 页中插入 draw.io 绘图 +confSaveTry=请保存页面并重试 +confCannotGetID=无法确定页面ID +confContactAdmin=请联系您的 Confluence 管理员 +readErr=读取错误 +editingErr=编辑错误 +confExtEditNotPossible=绘图无法在外部编辑. 请尝试在编辑页面时编辑它. +confEditedExt=绘图/页面 已在外部编辑 +diagNotFound=绘图找不到 +confEditedExtRefresh=绘图/页面 已在外部编辑. 请刷新页面. +confCannotEditDraftDelOrExt=无法在草稿页面中进行编辑, 该绘图已经在其他页面删除或外部编辑. 请检查页面. +retBack=Return back +confDiagNotPublished=改绘图不属于已发布的页面 +createdByDraw=使用 draw.io 创建 +filenameShort=文件名太短 +invalidChars=无效的字符 +alreadyExst={1} 已经存在 +draftReadErr=草稿读取错误 +diagCantLoad=无法加载绘图 +draftWriteErr=草稿写入错误 +draftCantCreate=无法创建草稿 +confDuplName=检测到重复的绘图名. 请重新选择. +confSessionExpired=似乎登陆已经过期. 重新登录以避免中断. +login=登录 +drawPrev=draw.io 预览 +drawDiag=draw.io 绘图 +invalidCallFnNotFound=无效调用: 无法找到 {1} +invalidCallErrOccured=无效调用: 检测到错误, {1} +anonymous=匿名 +confGotoPage=Go to containing page +showComments=显示评论 +confError=错误: {1} +gliffyImport=导入 Gliffy +gliffyImportInst1=点击 "开始导入" 按钮导入所有 Gliffy 绘图到 draw.io。 +gliffyImportInst2=请注意,导入过程需要一些时间,导入完成前浏览器窗口必须保持打开状态。 +startImport=开始导入 +drawConfig=draw.io 配置 +customLib=自定义库 +customTemp=自定义模板 +pageIdsExp=导出页面 ID +drawReindex=draw.io re-indexing (beta) +working=Working +drawConfigNotFoundInst=draw.io 配置空间 (DRAWIOCONFIG) 不存在. 存储 draw.io 配置文件和自定义库/模板时需要该空间. +createConfSp=创建配置空间 +unexpErrRefresh=发生意外错误, 请刷新页面, 然后重试. +configJSONInst=在下方编辑器填写 draw.io JSON 配置内容然后点击保存. 如果需要帮助, 请参考 +thisPage=this page +curCustLib=Current Custom Libraries +libName=Library Name +action=操作 +drawConfID=draw.io 配置 ID +addLibInst=Click the "Add Library" button to upload a new library. +addLib=Add Library +customTempInst1=Custom templates are draw.io diagrams saved in children pages of +customTempInst2=For more details, please refer to +tempsPage=Templates page +pageIdsExpInst1=Select export target, then click the "Start Export" button to export all pages IDs. +pageIdsExpInst2=Please note that the export procedure will take some time and the browser window must remain open until the export is completed. +startExp=开始导出 +refreshDrawIndex=Refresh draw.io Diagrams Index +reindexInst1=Click the "Start Indexing" button to refresh draw.io diagrams index. +reindexInst2=Please note that the indexing procedure will take some time and the browser window must remain open until the indexing is completed. +startIndexing=Start Indexing +confAPageFoundFetch=Page "{1}" found. Fetching +confAAllDiagDone=All {1} diagrams processed. Process finished. +confAStartedProcessing=Started processing page "{1}" +confAAllDiagInPageDone=All {1} diagrams in page "{2}" processed successfully. +confAPartialDiagDone={1} out of {2} {3} diagrams in page "{4}" processed successfully. +confAUpdatePageFailed=Updating page "{1}" failed. +confANoDiagFoundInPage=No {1} diagrams found in page "{2}". +confAFetchPageFailed=Fetching the page failed. +confANoDiagFound=No {1} diagrams found. Process finished. +confASearchFailed=Searching for {1} diagrams failed. Please try again later. +confAGliffyDiagFound={2} diagram "{1}" found. Importing +confAGliffyDiagImported={2} diagram "{1}" imported successfully. +confASavingImpGliffyFailed=Saving imported {2} diagram "{1}" failed. +confAImportedFromByDraw=Imported from "{1}" by draw.io +confAImportGliffyFailed=Importing {2} diagram "{1}" failed. +confAFetchGliffyFailed=Fetching {2} diagram "{1}" failed. +confACheckBrokenDiagLnk=Checking for broken diagrams links. +confADelDiagLinkOf=Deleting diagram link of "{1}" +confADupLnk=(duplicate link) +confADelDiagLnkFailed=Deleting diagram link of "{1}" failed. +confAUnexpErrProcessPage=Unexpected error during processing the page with id: {1} +confADiagFoundIndex=Diagram "{1}" found. Indexing +confADiagIndexSucc=Diagram "{1}" indexed successfully. +confAIndexDiagFailed=Indexing diagram "{1}" failed. +confASkipDiagOtherPage=Skipped "{1}" as it belongs to another page! +confADiagUptoDate=Diagram "{1}" is up to date. +confACheckPagesWDraw=Checking pages having draw.io diagrams. +confAErrOccured=An error occurred! +savedSucc=保存成功 +confASaveFailedErr=Saving Failed (Unexpected Error) +character=字符 +confAConfPageDesc=This page contains draw.io configuration file (configuration.json) as attachment +confALibPageDesc=This page contains draw.io custom libraries as attachments +confATempPageDesc=This page contains draw.io custom templates as attachments +working=Working +confAConfSpaceDesc=This space is used to store draw.io configuration files and custom libraries/templates +confANoCustLib=No Custom Libraries +delFailed=删除失败! +showID=Show ID +confAIncorrectLibFileType=Incorrect file type. Libraries should be XML files. +uploading=正在上传 +confALibExist=This library already exists +confAUploadSucc=Uploaded successfully +confAUploadFailErr=Upload Failed (Unexpected Error) +hiResPreview=高分辨率预览 +officeNotLoggedGD=You are not logged in to Google Drive. Please open draw.io task pane and login first. +officePopupInfo=Please complete the process in the pop-up window. +pickODFile=选择 OneDrive 文件 +createODFile=Create OneDrive File +pickGDriveFile=选择 Google Drive 文件 +createGDriveFile=Create Google Drive File +pickDeviceFile=选择设备文件 +vsdNoConfig="vsdurl" is not configured +ruler=标尺 +units=单位 +points=点 +inches=英寸 +millimeters=毫米 +confEditDraftDelOrExt=This diagram is in a draft page, is deleted from the page, or is edited externally. It will be saved as a new attachment version and may not be reflected in the page. +confDiagEditedExt=Diagram is edited in another session. It will be saved as a new attachment version but the page will show other session's modifications. +macroNotFound=Macro Not Found +confAInvalidPageIdsFormat=Incorrect Page IDs file format +confACollectingCurPages=Collecting current pages +confABuildingPagesMap=Building pages mapping +confAProcessDrawDiag=Started processing imported draw.io diagrams +confAProcessDrawDiagDone=Finished processing imported draw.io diagrams +confAProcessImpPages=Started processing imported pages +confAErrPrcsDiagInPage=Error processing draw.io diagrams in page "{1}" +confAPrcsDiagInPage=Processing draw.io diagrams in page "{1}" +confAImpDiagram=Importing diagram "{1}" +confAImpDiagramFailed=Importing diagram "{1}" failed. Cannot find its new page ID. Maybe it points to a page that is not imported. +confAImpDiagramError=Error importing diagram "{1}". Cannot fetch or save the diagram. Cannot fix this diagram links. +confAUpdateDgrmCCFailed=Updating link to diagram "{1}" failed. +confImpDiagramSuccess=Updating diagram "{1}" done successfully. +confANoLnksInDrgm=No links to update in: {1} +confAUpdateLnkToPg=Updated link to page: "{1}" in diagram: "{2}" +confAUpdateLBLnkToPg=Updated lightbox link to page: "{1}" in diagram: "{2}" +confAUpdateLnkBase=Updated base URL from: "{1}" to: "{2}" in diagram: "{3}" +confAPageIdsImpDone=Page IDs Import finished +confAPrcsMacrosInPage=Processing draw.io macros in page "{1}" +confAErrFetchPage=Error fetching page "{1}" +confAFixingMacro=Fixing macro of diagram "{1}" +confAErrReadingExpFile=Error reading export file +confAPrcsDiagInPageDone=Processing draw.io diagrams in page "{1}" finished +confAFixingMacroSkipped=Fixing macro of diagram "{1}" failed. Cannot find its new page ID. Maybe it points to a page that is not imported. +pageIdsExpTrg=Export target +confALucidDiagImgImported={2} diagram "{1}" image extracted successfully +confASavingLucidDiagImgFailed=Extracting {2} diagram "{1}" image failed +confGetInfoFailed=Fetching file info from {1} failed. +confCheckCacheFailed=Cannot get cached file info. +confReadFileErr=Cannot read "{1}" file from {2}. +confSaveCacheFailed=Unexpected error. Cannot save cached file +orgChartType=组织结构图类型 +linear=线性 +hanger2=Hanger 2 +hanger4=Hanger 4 +fishbone1=Fishbone 1 +fishbone2=Fishbone 2 +1ColumnLeft=单列居左 +1ColumnRight=单列居右 +smart=智能 +parentChildSpacing=父子间距 +siblingSpacing=兄弟间距 +confNoPermErr=Sorry, you don't have enough permissions to view this embedded diagram from page {1} +copyAsImage=复制为图像 +lucidImport=导入 Lucidchart +lucidImportInst1=点击 "开始导入" 按钮导入所有 Lucidchart 图表 +installFirst=请先安装 {1} +drawioChromeExt=draw.io Chrome 扩展 +loginFirstThen=请先登录 {1},然后 {2} +errFetchDocList=错误: 无法获取文档列表 +builtinPlugins=内置插件 +extPlugins=扩展插件 +backupFound=Backup file found +chromeOnly=该功能只适用于 Google Chrome +msgDeleted=消息已经删除 +confAErrFetchDrawList=Error fetching diagrams list. Some diagrams are skipped. +confAErrCheckDrawDiag=Cannot check diagram {1} +confAErrFetchPageList=Error fetching pages list +confADiagImportIncom={1} diagram "{2}" is imported partially and may have missing shapes +invalidSel=Invalid selection +diagNameEmptyErr=Diagram name cannot be empty +openDiagram=打开绘图 +newDiagram=新绘图 +editable=可编辑 +confAReimportStarted=Re-import {1} diagrams started... +spaceFilter=Filter by spaces +curViewState=Current Viewer State +pageLayers=页面和图层 +customize=自定义 +firstPage=第一页 (所有图层) +curEditorState=Current Editor State +noAnchorsFound=No anchors found +attachment=附件 +curDiagram=当前绘图 +recentDiags=最近绘图 +csvImport=导入 CSV +chooseFile=选择文件... +choose=选择 +gdriveFname=Google Drive 文件名 +widthOfViewer=Width of the viewer (px) +heightOfViewer=Height of the viewer (px) +autoSetViewerSize=Automatically set the size of the viewer +thumbnail=缩略图 +prevInDraw=在 draw.io 中预览 +onedriveFname=OneDrive 文件名 +diagFname=绘图文件名 +diagUrl=绘图地址 +showDiag=显示绘图 +diagPreview=绘图预览 +csvFileUrl=CSV 文件 URL +generate=生成 +selectDiag2Insert=Please select a diagram to insert it. +errShowingDiag=Unexpected error. Cannot show diagram +noRecentDiags=No recent diagrams found +fetchingRecentFailed=Failed to fetch recent diagrams +useSrch2FindDiags=Use the search box to find draw.io diagrams +cantReadChckPerms=Cannot read the specified diagram. Please check you have read permission on that file. +cantFetchChckPerms=Cannot fetch diagram info. Please check you have read permission on that file. +searchFailed=Searching failed. Please try again later. +plsTypeStr=Please type a search string. +unsupportedFileChckUrl=Unsupported file. Please check the specified URL +diagNotFoundChckUrl=Diagram not found or cannot be accessed. Please check the specified URL +csvNotFoundChckUrl=CSV file not found or cannot be accessed. Please check the specified URL +cantReadUpload=Cannot read the uploaded diagram +select=Select +errCantGetIdType=Unexpected Error: Cannot get content id or type. +errGAuthWinBlocked=Error: Google Authentication window blocked +authDrawAccess=Authorize draw.io to access {1} +connTimeout=The connection has timed out +errAuthSrvc=Error authenticating to {1} +plsSelectFile=Please select a file +mustBgtZ={1} must be greater than zero +cantLoadPrev=Cannot load file preview. +errAccessFile=Error: Access Denied. You do not have permission to access "{1}". +noPrevAvail=No preview is available. +personalAccNotSup=Personal accounts are not supported. +errSavingTryLater=Error occurred during saving, please try again later. +plsEnterFld=Please enter {1} +invalidDiagUrl=Invalid Diagram URL +unsupportedVsdx=Unsupported vsdx file +unsupportedImg=Unsupported image file +unsupportedFormat=Unsupported file format +plsSelectSingleFile=Please select a single file only +attCorrupt=Attachment file "{1}" is corrupted +loadAttFailed=Failed to load attachment "{1}" +embedDrawDiag=Embed draw.io Diagram +addDiagram=Add Diagram +embedDiagram=嵌入绘图 +editOwningPg=Edit owning page +deepIndexing=Deep Indexing (Index diagrams that aren't used in any page also) +confADeepIndexStarted=Deep Indexing Started +confADeepIndexDone=Deep Indexing Done +officeNoDiagramsSelected=No diagrams found in the selection +officeNoDiagramsInDoc=No diagrams found in the document +officeNotSupported=This feature is not supported in this host application +someImagesFailed={1} out of {2} failed due to the following errors +importingNoUsedDiagrams=Importing {1} Diagrams not used in pages +importingDrafts=Importing {1} Diagrams in drafts +processingDrafts=Processing drafts +updatingDrafts=Updating drafts +updateDrafts=Update drafts +notifications=Notifications +drawioImp=draw.io Import +confALibsImp=Importing draw.io Libraries +confALibsImpFailed=Importing {1} library failed +contributors=贡献者 +drawDiagrams=draw.io 绘图 +errFileNotFoundOrNoPer=Error: Access Denied. File not found or you do not have permission to access "{1}" on {2}. +confACheckPagesWEmbed=Checking pages having embedded draw.io diagrams. +confADelBrokenEmbedDiagLnk=Removing broken embedded diagram links +replaceWith=替换为 +replaceAll=全部替换 +confASkipDiagModified=Skipped "{1}" as it was modified after initial import +replFind=替换 / 查找 +matchesRepl={1} 个匹配已替换 +draftErrDataLoss=An error occurred while reading the draft file. The diagram cannot be edited now to prevent any possible data loss. Please try again later or contact support. +ibm=IBM +linkToDiagramHint=Add a link to this diagram. The diagram can only be edited from the page that owns it. +linkToDiagram=Link to Diagram +changedBy=Changed By +lastModifiedOn=最后修改于 +searchResults=搜索结果 +showAllTemps=显示所有模板 +notionToken=Notion 令牌 +selectDB=Select Database +noDBs=No Databases +diagramEdited={1} diagram "{2}" edited +confDraftPermissionErr=Draft cannot be written. Do you have attachment write/read permission on this page? +confDraftTooBigErr=Draft size is too large. Pease check "Attachment Maximum Size" of "Attachment Settings" in Confluence Configuration? +owner=所有者 +repository=仓库 +branch=分支 +meters=米 +teamsNoEditingMsg=Editor functionality is only available in Desktop environment (in MS Teams App or a web browser) +contactOwner=联系所有者 +viewerOnlyMsg=You cannot edit the diagrams in the mobile platform, please use the desktop client or a web browser. +website=网站 +check4Updates=检查更新 +attWriteFailedRetry={1}: Attachment write failed, trying again in {2} seconds... +confPartialPageList=We couldn't fetch all pages due to an error in Confluence. Continuing using {1} pages only. +spellCheck=拼写检查 +noChange=无变化 +lblToSvg=转换标签为 SVG +txtSettings=文本设置 +LinksLost=连接将会丢失 +arcSize=弧度 +editConnectionPoints=编辑连接点 +notInOffline=离线时不支持 +notInDesktop=桌面应用中不支持 +confConfigSpaceArchived=draw.io Configuration space (DRAWIOCONFIG) is archived. Please restore it first. +confACleanOldVerStarted=Cleaning old diagram draft versions started +confACleanOldVerDone=Cleaning old diagram draft versions finished +confACleaningFile=Cleaning diagram draft "{1}" old versions +confAFileCleaned=Cleaning diagram draft "{1}" done +confAFileCleanFailed=Cleaning diagram draft "{1}" failed +confACleanOnly=Clean Diagram Drafts Only +brush=Brush +openDevTools=Open Developer Tools +autoBkp=Automatic Backup +atlassian=Atlassian +citrix=Citrix \ No newline at end of file diff --git a/packages/client/public/diagram/stencils/arrows.xml b/packages/client/public/diagram/stencils/arrows.xml new file mode 100644 index 0000000..5e39b3c --- /dev/null +++ b/packages/client/public/diagram/stencils/arrows.xml @@ -0,0 +1,849 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/client/public/diagram/stencils/atlassian.xml b/packages/client/public/diagram/stencils/atlassian.xml new file mode 100644 index 0000000..9c01671 --- /dev/null +++ b/packages/client/public/diagram/stencils/atlassian.xml @@ -0,0 +1,713 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/client/public/diagram/stencils/basic.xml b/packages/client/public/diagram/stencils/basic.xml new file mode 100644 index 0000000..39dbaed --- /dev/null +++ b/packages/client/public/diagram/stencils/basic.xml @@ -0,0 +1,1028 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/client/public/diagram/stencils/bpmn.xml b/packages/client/public/diagram/stencils/bpmn.xml new file mode 100644 index 0000000..af8918d --- /dev/null +++ b/packages/client/public/diagram/stencils/bpmn.xml @@ -0,0 +1,1162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/client/public/diagram/stencils/citrix.xml b/packages/client/public/diagram/stencils/citrix.xml new file mode 100644 index 0000000..ac11ab1 --- /dev/null +++ b/packages/client/public/diagram/stencils/citrix.xml @@ -0,0 +1,19709 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/client/public/diagram/stencils/clipart/Credit_Card_128x128.png b/packages/client/public/diagram/stencils/clipart/Credit_Card_128x128.png new file mode 100644 index 0000000..d280580 Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Credit_Card_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Database_128x128.png b/packages/client/public/diagram/stencils/clipart/Database_128x128.png new file mode 100644 index 0000000..4add714 Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Database_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Doctor1_128x128.png b/packages/client/public/diagram/stencils/clipart/Doctor1_128x128.png new file mode 100644 index 0000000..d5a4bb7 Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Doctor1_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Earth_globe_128x128.png b/packages/client/public/diagram/stencils/clipart/Earth_globe_128x128.png new file mode 100644 index 0000000..438d414 Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Earth_globe_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Email_128x128.png b/packages/client/public/diagram/stencils/clipart/Email_128x128.png new file mode 100644 index 0000000..af81e0b Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Email_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Empty_Folder_128x128.png b/packages/client/public/diagram/stencils/clipart/Empty_Folder_128x128.png new file mode 100644 index 0000000..85d5b0f Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Empty_Folder_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Firewall_02_128x128.png b/packages/client/public/diagram/stencils/clipart/Firewall_02_128x128.png new file mode 100644 index 0000000..0cf90fd Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Firewall_02_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Full_Folder_128x128.png b/packages/client/public/diagram/stencils/clipart/Full_Folder_128x128.png new file mode 100644 index 0000000..6a6496e Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Full_Folder_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Gear_128x128.png b/packages/client/public/diagram/stencils/clipart/Gear_128x128.png new file mode 100644 index 0000000..a44e376 Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Gear_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Graph_128x128.png b/packages/client/public/diagram/stencils/clipart/Graph_128x128.png new file mode 100644 index 0000000..7f20b4e Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Graph_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Laptop_128x128.png b/packages/client/public/diagram/stencils/clipart/Laptop_128x128.png new file mode 100644 index 0000000..ab7ea65 Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Laptop_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Lock_128x128.png b/packages/client/public/diagram/stencils/clipart/Lock_128x128.png new file mode 100644 index 0000000..d815f0e Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Lock_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/MacBook_128x128.png b/packages/client/public/diagram/stencils/clipart/MacBook_128x128.png new file mode 100644 index 0000000..0f6802c Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/MacBook_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Monitor_Tower_128x128.png b/packages/client/public/diagram/stencils/clipart/Monitor_Tower_128x128.png new file mode 100644 index 0000000..223b27a Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Monitor_Tower_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Piggy_Bank_128x128.png b/packages/client/public/diagram/stencils/clipart/Piggy_Bank_128x128.png new file mode 100644 index 0000000..89f51c1 Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Piggy_Bank_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Pilot1_128x128.png b/packages/client/public/diagram/stencils/clipart/Pilot1_128x128.png new file mode 100644 index 0000000..5b7dea0 Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Pilot1_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Printer_128x128.png b/packages/client/public/diagram/stencils/clipart/Printer_128x128.png new file mode 100644 index 0000000..3cee042 Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Printer_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Router_Icon_128x128.png b/packages/client/public/diagram/stencils/clipart/Router_Icon_128x128.png new file mode 100644 index 0000000..49345e5 Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Router_Icon_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Safe_128x128.png b/packages/client/public/diagram/stencils/clipart/Safe_128x128.png new file mode 100644 index 0000000..51115e8 Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Safe_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Security1_128x128.png b/packages/client/public/diagram/stencils/clipart/Security1_128x128.png new file mode 100644 index 0000000..9cf20a2 Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Security1_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Server_Tower_128x128.png b/packages/client/public/diagram/stencils/clipart/Server_Tower_128x128.png new file mode 100644 index 0000000..a0ec7b1 Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Server_Tower_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Shopping_Cart_128x128.png b/packages/client/public/diagram/stencils/clipart/Shopping_Cart_128x128.png new file mode 100644 index 0000000..ec1e184 Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Shopping_Cart_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Software_128x128.png b/packages/client/public/diagram/stencils/clipart/Software_128x128.png new file mode 100644 index 0000000..a3deb93 Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Software_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Soldier1_128x128.png b/packages/client/public/diagram/stencils/clipart/Soldier1_128x128.png new file mode 100644 index 0000000..27f4b4b Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Soldier1_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Suit1_128x128.png b/packages/client/public/diagram/stencils/clipart/Suit1_128x128.png new file mode 100644 index 0000000..f6c0a8d Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Suit1_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Suit2_128x128.png b/packages/client/public/diagram/stencils/clipart/Suit2_128x128.png new file mode 100644 index 0000000..a8b714d Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Suit2_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Suit3_128x128.png b/packages/client/public/diagram/stencils/clipart/Suit3_128x128.png new file mode 100644 index 0000000..68a1f1c Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Suit3_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Tech1_128x128.png b/packages/client/public/diagram/stencils/clipart/Tech1_128x128.png new file mode 100644 index 0000000..95e4110 Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Tech1_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Telesales1_128x128.png b/packages/client/public/diagram/stencils/clipart/Telesales1_128x128.png new file mode 100644 index 0000000..6ef7b8a Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Telesales1_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Virtual_Machine_128x128.png b/packages/client/public/diagram/stencils/clipart/Virtual_Machine_128x128.png new file mode 100644 index 0000000..75895ea Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Virtual_Machine_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Virus_128x128.png b/packages/client/public/diagram/stencils/clipart/Virus_128x128.png new file mode 100644 index 0000000..f0dfbcb Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Virus_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Wireless_Router_N_128x128.png b/packages/client/public/diagram/stencils/clipart/Wireless_Router_N_128x128.png new file mode 100644 index 0000000..9bace31 Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Wireless_Router_N_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Worker1_128x128.png b/packages/client/public/diagram/stencils/clipart/Worker1_128x128.png new file mode 100644 index 0000000..c69c9bd Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Worker1_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/Workstation_128x128.png b/packages/client/public/diagram/stencils/clipart/Workstation_128x128.png new file mode 100644 index 0000000..9aeef9e Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/Workstation_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/iMac_128x128.png b/packages/client/public/diagram/stencils/clipart/iMac_128x128.png new file mode 100644 index 0000000..ccdb514 Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/iMac_128x128.png differ diff --git a/packages/client/public/diagram/stencils/clipart/iPad_128x128.png b/packages/client/public/diagram/stencils/clipart/iPad_128x128.png new file mode 100644 index 0000000..88dc807 Binary files /dev/null and b/packages/client/public/diagram/stencils/clipart/iPad_128x128.png differ diff --git a/packages/client/public/diagram/stencils/flowchart.xml b/packages/client/public/diagram/stencils/flowchart.xml new file mode 100644 index 0000000..e6ec9d2 --- /dev/null +++ b/packages/client/public/diagram/stencils/flowchart.xml @@ -0,0 +1,920 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/client/public/diagram/styles/default.xml b/packages/client/public/diagram/styles/default.xml new file mode 100644 index 0000000..82fb1b2 --- /dev/null +++ b/packages/client/public/diagram/styles/default.xml @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/client/public/diagram/styles/sprites.png b/packages/client/public/diagram/styles/sprites.png new file mode 100644 index 0000000..23e1b49 Binary files /dev/null and b/packages/client/public/diagram/styles/sprites.png differ diff --git a/packages/client/public/favicon.ico b/packages/client/public/favicon.ico new file mode 100644 index 0000000..7c6b60c Binary files /dev/null and b/packages/client/public/favicon.ico differ diff --git a/packages/client/public/icon120.png b/packages/client/public/icon120.png new file mode 100644 index 0000000..005f8a8 Binary files /dev/null and b/packages/client/public/icon120.png differ diff --git a/packages/client/public/icon128.png b/packages/client/public/icon128.png new file mode 100644 index 0000000..d5abf29 Binary files /dev/null and b/packages/client/public/icon128.png differ diff --git a/packages/client/public/icon144.png b/packages/client/public/icon144.png new file mode 100644 index 0000000..3200d16 Binary files /dev/null and b/packages/client/public/icon144.png differ diff --git a/packages/client/public/icon152.png b/packages/client/public/icon152.png new file mode 100644 index 0000000..7531f37 Binary files /dev/null and b/packages/client/public/icon152.png differ diff --git a/packages/client/public/icon180.png b/packages/client/public/icon180.png new file mode 100644 index 0000000..6fffbeb Binary files /dev/null and b/packages/client/public/icon180.png differ diff --git a/packages/client/public/icon192.png b/packages/client/public/icon192.png new file mode 100644 index 0000000..6d9a6b2 Binary files /dev/null and b/packages/client/public/icon192.png differ diff --git a/packages/client/public/icon384.png b/packages/client/public/icon384.png new file mode 100644 index 0000000..39664fc Binary files /dev/null and b/packages/client/public/icon384.png differ diff --git a/packages/client/public/icon512.png b/packages/client/public/icon512.png new file mode 100644 index 0000000..7a8c142 Binary files /dev/null and b/packages/client/public/icon512.png differ diff --git a/packages/client/public/icon72.png b/packages/client/public/icon72.png new file mode 100644 index 0000000..0cf2396 Binary files /dev/null and b/packages/client/public/icon72.png differ diff --git a/packages/client/public/icon96.png b/packages/client/public/icon96.png new file mode 100644 index 0000000..f969aa4 Binary files /dev/null and b/packages/client/public/icon96.png differ diff --git a/packages/client/public/maskable.png b/packages/client/public/maskable.png new file mode 100644 index 0000000..5b76c8f Binary files /dev/null and b/packages/client/public/maskable.png differ diff --git a/packages/client/pwa-cache.js b/packages/client/pwa-cache.js new file mode 100644 index 0000000..a5117db --- /dev/null +++ b/packages/client/pwa-cache.js @@ -0,0 +1,143 @@ +module.exports = [ + { + urlPattern: /^https:\/\/fonts\.(?:gstatic)\.com\/.*/i, + handler: 'CacheFirst', + options: { + cacheName: 'google-fonts-webfonts', + expiration: { + maxEntries: 4, + maxAgeSeconds: 365 * 24 * 60 * 60, // 365 days + }, + }, + }, + { + urlPattern: /^https:\/\/fonts\.(?:googleapis)\.com\/.*/i, + handler: 'StaleWhileRevalidate', + options: { + cacheName: 'google-fonts-stylesheets', + expiration: { + maxEntries: 4, + maxAgeSeconds: 7 * 24 * 60 * 60, // 7 days + }, + }, + }, + { + urlPattern: /\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i, + handler: 'StaleWhileRevalidate', + options: { + cacheName: 'static-font-assets', + expiration: { + maxEntries: 4, + maxAgeSeconds: 7 * 24 * 60 * 60, // 7 days + }, + }, + }, + { + urlPattern: /\.(?:jpg|jpeg|gif|png|svg|ico|webp)$/i, + handler: 'StaleWhileRevalidate', + options: { + cacheName: 'static-image-assets', + expiration: { + maxEntries: 64, + maxAgeSeconds: 24 * 60 * 60, // 24 hours + }, + }, + }, + { + urlPattern: /\/_next\/image\?url=.+$/i, + handler: 'StaleWhileRevalidate', + options: { + cacheName: 'next-image', + expiration: { + maxEntries: 64, + maxAgeSeconds: 24 * 60 * 60, // 24 hours + }, + }, + }, + { + urlPattern: /\.(?:mp3|wav|ogg)$/i, + handler: 'CacheFirst', + options: { + rangeRequests: true, + cacheName: 'static-audio-assets', + expiration: { + maxEntries: 32, + maxAgeSeconds: 24 * 60 * 60, // 24 hours + }, + }, + }, + { + urlPattern: /\.(?:mp4)$/i, + handler: 'CacheFirst', + options: { + rangeRequests: true, + cacheName: 'static-video-assets', + expiration: { + maxEntries: 32, + maxAgeSeconds: 24 * 60 * 60, // 24 hours + }, + }, + }, + { + urlPattern: /\.(?:js)$/i, + handler: 'StaleWhileRevalidate', + options: { + cacheName: 'static-js-assets', + expiration: { + maxEntries: 32, + maxAgeSeconds: 24 * 60 * 60, // 24 hours + }, + }, + }, + { + urlPattern: /\.(?:css|less)$/i, + handler: 'StaleWhileRevalidate', + options: { + cacheName: 'static-style-assets', + expiration: { + maxEntries: 32, + maxAgeSeconds: 24 * 60 * 60, // 24 hours + }, + }, + }, + { + urlPattern: /\/_next\/data\/.+\/.+\.json$/i, + handler: 'StaleWhileRevalidate', + options: { + cacheName: 'next-data', + expiration: { + maxEntries: 32, + maxAgeSeconds: 24 * 60 * 60, // 24 hours + }, + }, + }, + { + urlPattern: /\.(?:json|xml|csv)$/i, + handler: 'NetworkFirst', + options: { + cacheName: 'static-data-assets', + expiration: { + maxEntries: 32, + maxAgeSeconds: 24 * 60 * 60, // 24 hours + }, + }, + }, + { + urlPattern: ({ url }) => { + const isSameOrigin = self.origin === url.origin; + if (!isSameOrigin) return false; + const pathname = url.pathname; + if (pathname.startsWith('/api/')) return false; + return true; + }, + handler: 'NetworkFirst', + options: { + cacheName: 'others', + expiration: { + maxEntries: 32, + maxAgeSeconds: 24 * 60 * 60, // 24 hours + }, + networkTimeoutSeconds: 10, + }, + }, +]; diff --git a/packages/client/src/components/admin/system-config/ad/index.tsx b/packages/client/src/components/admin/system-config/ad/index.tsx new file mode 100644 index 0000000..4e34fe3 --- /dev/null +++ b/packages/client/src/components/admin/system-config/ad/index.tsx @@ -0,0 +1,141 @@ +import React, { useCallback, useMemo, useRef, useState } from 'react'; + +import { Avatar, Button, Form, Image, Modal, Space, Table } from '@douyinfe/semi-ui'; +import { FormApi } from '@douyinfe/semi-ui/lib/es/form'; + +import { AdType } from '@think/domains'; + +import { DataRender } from 'components/data-render'; +import { Upload } from 'components/upload'; +import { useAd } from 'data/ad'; + +const { Option } = Form.Select; + +const AdTypeTextMap = { + [AdType.shareDocCover]: '分享文档主图位', + [AdType.shareDocAside]: '分享文档侧边位', +}; + +const columns0 = [ + { + title: '类型', + dataIndex: 'type', + render: (type) => { + return AdTypeTextMap[type]; + }, + }, + { + title: '广告图', + dataIndex: 'cover', + render: (url) => { + return ( +
+ +
+ ); + }, + }, + { + title: '广告链接', + dataIndex: 'url', + }, +]; + +export const Ad = () => { + const { data, loading, error, createAd, deleteAd } = useAd(); + const [visible, toggleVisible] = useState(false); + const $form = useRef(); + const [currentCover, setCurrentCover] = useState(''); + + const columns = useMemo(() => { + return [ + ...columns0, + { + title: '操作', + dataIndex: 'id', + render: (id) => { + return ( + + ); + }, + }, + ]; + }, [deleteAd]); + + const setCover = useCallback((url) => { + $form.current.setValue('cover', url); + setCurrentCover(url); + }, []); + + const handleOk = useCallback(() => { + $form.current.validate().then((values) => { + if (!values.email) { + delete values.email; + } + createAd(values).then(() => { + $form.current.reset(); + setCover(''); + toggleVisible(false); + }); + }); + }, [createAd, setCover, toggleVisible]); + + return ( + ( +
+ + { + toggleVisible(false); + }} + style={{ maxWidth: '96vw' }} + onOk={handleOk} + > +
($form.current = formApi)} + labelPosition="left" + > + + + + + + + + + + + + + +
+
+ + + )} + /> + ); +}; diff --git a/packages/client/src/components/admin/system-config/index.tsx b/packages/client/src/components/admin/system-config/index.tsx new file mode 100644 index 0000000..11b7b81 --- /dev/null +++ b/packages/client/src/components/admin/system-config/index.tsx @@ -0,0 +1,36 @@ +import React from 'react'; + +import { TabPane, Tabs } from '@douyinfe/semi-ui'; + +import { Ad } from './ad'; +import { Mail } from './mail'; +import { System } from './system'; + +interface IProps { + tab?: string; + onNavigate: (arg: string) => void; +} + +const TitleMap = { + base: '系统管理', + mail: '邮箱服务', + ad: '广告管理', +}; + +export const SystemConfig: React.FC = ({ tab, onNavigate }) => { + return ( + + + + + + + + + + + + + + ); +}; diff --git a/packages/client/src/components/admin/system-config/mail/index.tsx b/packages/client/src/components/admin/system-config/mail/index.tsx new file mode 100644 index 0000000..dc0a9d0 --- /dev/null +++ b/packages/client/src/components/admin/system-config/mail/index.tsx @@ -0,0 +1,92 @@ +import React, { useCallback } from 'react'; + +import { Banner, Button, Form, Toast } from '@douyinfe/semi-ui'; + +import { DataRender } from 'components/data-render'; +import { useSystemConfig } from 'data/user'; +import { useToggle } from 'hooks/use-toggle'; + +export const Mail = () => { + const { data, loading, error, sendTestEmail, updateSystemConfig } = useSystemConfig(); + const [changed, toggleChanged] = useToggle(false); + + const onFormChange = useCallback(() => { + toggleChanged(true); + }, [toggleChanged]); + + const onFinish = useCallback( + (values) => { + updateSystemConfig(values).then(() => { + Toast.success('操作成功'); + }); + }, + [updateSystemConfig] + ); + + return ( + ( +
+ + + {/* + // @ts-ignore */} +
+ + + + + + + + + + + + +
+ )} + /> + ); +}; diff --git a/packages/client/src/components/admin/system-config/system/index.tsx b/packages/client/src/components/admin/system-config/system/index.tsx new file mode 100644 index 0000000..03f2023 --- /dev/null +++ b/packages/client/src/components/admin/system-config/system/index.tsx @@ -0,0 +1,74 @@ +import React, { useCallback } from 'react'; + +import { IconHelpCircle } from '@douyinfe/semi-icons'; +import { Banner, Button, Form, Toast, Tooltip } from '@douyinfe/semi-ui'; + +import { DataRender } from 'components/data-render'; +import { useSystemConfig } from 'data/user'; +import { useToggle } from 'hooks/use-toggle'; + +export const System = () => { + const { data, loading, error, updateSystemConfig } = useSystemConfig(); + const [changed, toggleChanged] = useToggle(false); + + const onFormChange = useCallback(() => { + toggleChanged(true); + }, [toggleChanged]); + + const onFinish = useCallback( + (values) => { + updateSystemConfig(values).then(() => { + Toast.success('操作成功'); + }); + }, + [updateSystemConfig] + ); + + return ( + ( +
+ {/* + // @ts-ignore */} +
+ + + + ), + }} + /> + + + + ), + }} + /> + + + +
+ )} + /> + ); +}; diff --git a/packages/client/src/components/author.tsx b/packages/client/src/components/author.tsx new file mode 100644 index 0000000..ba1c3fd --- /dev/null +++ b/packages/client/src/components/author.tsx @@ -0,0 +1,26 @@ +import { IconLikeHeart } from '@douyinfe/semi-icons'; +import { Space, Typography } from '@douyinfe/semi-ui'; + +import { RuntimeConfig } from 'hooks/use-runtime-config'; + +const { Text } = Typography; + +export const Author = () => { + const config = RuntimeConfig.useHook(); + + return ( +
+ {config.copyrightInformation ? ( +
+ ) : ( + + + Develop by + fantasticit + with + + + )} +
+ ); +}; diff --git a/packages/client/src/components/banner/index.tsx b/packages/client/src/components/banner/index.tsx new file mode 100644 index 0000000..b5b1288 --- /dev/null +++ b/packages/client/src/components/banner/index.tsx @@ -0,0 +1,34 @@ +import React, { useEffect, useRef } from 'react'; + +import { IconClose } from '@douyinfe/semi-icons'; +import { Banner as SemiBanner } from '@douyinfe/semi-ui'; +import { BannerProps } from '@douyinfe/semi-ui/banner'; + +import { useToggle } from 'hooks/use-toggle'; + +interface IProps extends BannerProps { + duration?: number; + closeable?: boolean; +} + +export const Banner: React.FC = ({ type, description, duration = 0, closeable = true }) => { + const timer = useRef>(); + const [visible, toggleVisible] = useToggle(true); + + useEffect(() => { + clearTimeout(timer.current); + if (duration <= 0) return; + + timer.current = setTimeout(() => { + toggleVisible(false); + }, duration); + + return () => { + clearTimeout(timer.current); + }; + }, [duration, toggleVisible]); + + if (!visible) return null; + + return : null} />; +}; diff --git a/packages/client/src/components/color-picker/index.tsx b/packages/client/src/components/color-picker/index.tsx new file mode 100644 index 0000000..e510e47 --- /dev/null +++ b/packages/client/src/components/color-picker/index.tsx @@ -0,0 +1,151 @@ +import React, { useMemo } from 'react'; + +import { Dropdown, SideSheet, Typography } from '@douyinfe/semi-ui'; + +import { IsOnMobile } from 'hooks/use-on-mobile'; +import { useToggle } from 'hooks/use-toggle'; + +import styles from './style.module.scss'; + +const { Text } = Typography; + +const colors = [ + '#000000', + '#262626', + '#595959', + '#8C8C8C', + '#BFBFBF', + '#D9D9D9', + '#E9E9E9', + '#F5F5F5', + '#FAFAFA', + '#FFFFFF', + '#F5222D', + '#FA541C', + '#FA8C16', + '#FADB14', + '#52C41A', + '#13C2C2', + '#1890FF', + '#2F54EB', + '#722ED1', + '#EB2F96', + '#FFE8E6', + '#FFECE0', + '#FFEFD1', + '#FCFCCA', + '#E4F7D2', + '#D3F5F0', + '#D4EEFC', + '#DEE8FC', + '#EFE1FA', + '#FAE1EB', + '#FFA39E', + '#FFBB96', + '#FFD591', + '#FFFB8F', + '#B7EB8F', + '#87E8DE', + '#91D5FF', + '#ADC6FF', + '#D3ADF7', + '#FFADD2', + '#FF4D4F', + '#FF7A45', + '#FFA940', + '#FFEC3D', + '#73D13D', + '#36CFC9', + '#40A9FF', + '#597EF7', + '#9254DE', + '#F759AB', + '#CF1322', + '#D4380D', + '#D46B08', + '#D4B106', + '#389E0D', + '#08979C', + '#096DD9', + '#1D39C4', + '#531DAB', + '#C41D7F', + '#820014', + '#871400', + '#873800', + '#614700', + '#135200', + '#00474F', + '#003A8C', + '#061178', + '#22075E', + '#780650', +]; + +export const ColorPicker: React.FC<{ + title?: string; + onSetColor: (arg: string) => void; + disabled?: boolean; +}> = ({ children, title = '颜色管理', onSetColor, disabled = false }) => { + const { isMobile } = IsOnMobile.useHook(); + const [visible, toggleVisible] = useToggle(false); + + const content = useMemo( + () => + !visible ? null : ( +
+
onSetColor(null)}> + + 无颜色 +
+ +
+ {colors.map((color) => { + return ( +
onSetColor(color)}> + +
+ ); + })} +
+
+ ), + [onSetColor, isMobile, visible] + ); + + if (disabled) return {children}; + + return ( + + {isMobile ? ( + <> + + {content} + + toggleVisible(true)}> + {children} + + + ) : ( + + {children} + + )} + + ); +}; diff --git a/packages/client/src/components/color-picker/style.module.scss b/packages/client/src/components/color-picker/style.module.scss new file mode 100644 index 0000000..adce77c --- /dev/null +++ b/packages/client/src/components/color-picker/style.module.scss @@ -0,0 +1,73 @@ +.emptyWrap { + display: flex; + cursor: pointer; + border: 1px solid transparent; + flex-wrap: nowrap; + + &:hover { + background-color: var(--semi-color-fill-1); + } + + > span:first-child { + position: relative; + display: block; + width: 20px; + height: 20px; + margin: 0 8px 0 1px; + border: 1px solid #e8e8e8; + border-radius: 2px; + + &::after { + position: absolute; + top: 8px; + left: 0; + display: block; + width: 17px; + height: 0; + content: ''; + transform: rotate(45deg); + border-bottom: 2px solid #ff5151; + } + } +} + +.colorWrap { + display: flex; + flex-wrap: wrap; + margin-top: 8px; + + .colorItem { + display: flex; + width: 24px; + height: 24px; + cursor: pointer; + border: 1px solid transparent; + border-radius: 4px; + justify-content: center; + align-items: center; + + &:nth-of-type(n + 11) { + margin-top: 4px; + } + + &:hover { + border-color: rgb(193 199 208); + } + + > span { + display: block; + width: 20px; + height: 20px; + border: 1px solid var(--semi-color-border); + border-radius: 2px; + } + } +} + +.visible { + display: block; +} + +.hidden { + display: none; +} diff --git a/packages/client/src/components/data-render/constant.tsx b/packages/client/src/components/data-render/constant.tsx new file mode 100644 index 0000000..1e43698 --- /dev/null +++ b/packages/client/src/components/data-render/constant.tsx @@ -0,0 +1,47 @@ +import React, { useMemo } from 'react'; + +import { Spin, Typography } from '@douyinfe/semi-ui'; + +import { Empty } from 'illustrations/empty'; + +const { Text } = Typography; + +export const defaultLoading = ( +
+ +
+); + +export const defaultRenderError = (error) => { + return {(error && error.message) || '未知错误'}; +}; + +const emptyStyle: React.CSSProperties = { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + flexDirection: 'column', + position: 'relative', + top: '50%', + left: '50%', + transform: 'translate(-50%, -50%)', +}; + +export const defaultEmpty = ( +
+
+ +
+ 暂无数据 +
+); + +export const Render: React.FC<{ fn: ((arg: unknown) => React.ReactNode) | React.ReactNode; args?: unknown[] }> = ({ + fn, + args = [], +}) => { + // eslint-disable-next-line react-hooks/exhaustive-deps + const content = useMemo(() => (typeof fn === 'function' ? fn.apply(null, ...args) : fn), [args]); + + return <>{content}; +}; diff --git a/packages/client/src/components/data-render/index.tsx b/packages/client/src/components/data-render/index.tsx new file mode 100644 index 0000000..9f1179a --- /dev/null +++ b/packages/client/src/components/data-render/index.tsx @@ -0,0 +1,44 @@ +import React from 'react'; + +import deepEqual from 'deep-equal'; + +import { defaultEmpty, defaultLoading, defaultRenderError, Render } from './constant'; +import { LoadingWrap } from './loading'; + +type RenderProps = React.ReactNode | (() => React.ReactNode); + +interface IProps { + loading: boolean; + error: Error | null | unknown; + empty?: boolean; + loadingContent?: RenderProps; + errorContent?: RenderProps; + emptyContent?: RenderProps; + normalContent: RenderProps; +} + +export const _DataRender: React.FC = ({ + loading, + error, + empty, + loadingContent = defaultLoading, + errorContent = defaultRenderError, + emptyContent = defaultEmpty, + normalContent, +}) => { + if (error) { + return ; + } + + if (empty) { + return ; + } + + return ( + + ); +}; + +export const DataRender = React.memo(_DataRender, (prevProps, nextProps) => { + return deepEqual(prevProps, nextProps); +}); diff --git a/packages/client/src/components/data-render/loading.tsx b/packages/client/src/components/data-render/loading.tsx new file mode 100644 index 0000000..c696342 --- /dev/null +++ b/packages/client/src/components/data-render/loading.tsx @@ -0,0 +1,34 @@ +import React, { useEffect, useRef } from 'react'; + +import { useToggle } from 'hooks/use-toggle'; + +import { Render } from './constant'; + +export const LoadingWrap = ({ loading, delay = 200, loadingContent, normalContent }) => { + const timer = useRef>(null); + const [showLoading, toggleShowLoading] = useToggle(false); + + useEffect(() => { + clearTimeout(timer.current); + + if (!loading) return; + + timer.current = setTimeout(() => { + if (loading) { + toggleShowLoading(true); + } else { + toggleShowLoading(false); + } + }, delay); + + return () => { + clearTimeout(timer.current); + }; + }, [delay, loading, toggleShowLoading]); + + if (loading) { + return showLoading ? : null; + } + + return ; +}; diff --git a/packages/client/src/components/divider.tsx b/packages/client/src/components/divider.tsx new file mode 100644 index 0000000..0915b01 --- /dev/null +++ b/packages/client/src/components/divider.tsx @@ -0,0 +1,20 @@ +import React from 'react'; + +export const _Divider = ({ vertical = false, margin = 6 }) => { + return ( +
+ ); +}; + +export const Divider = React.memo(_Divider, (prevProps, nextProps) => { + return prevProps.vertical === nextProps.vertical; +}); diff --git a/packages/client/src/components/document-creator/index.tsx b/packages/client/src/components/document-creator/index.tsx new file mode 100644 index 0000000..fa1b073 --- /dev/null +++ b/packages/client/src/components/document-creator/index.tsx @@ -0,0 +1,35 @@ +import React from 'react'; + +import { Button } from '@douyinfe/semi-ui'; + +import { DocumentCreator as DocumenCreatorForm } from 'components/document/create'; +import { useRouterQuery } from 'hooks/use-router-query'; +import { useToggle } from 'hooks/use-toggle'; + +interface IProps { + onCreateDocument?: () => void; +} + +export const DocumentCreator: React.FC = ({ onCreateDocument, children }) => { + const { wikiId, documentId } = useRouterQuery<{ wikiId?: string; documentId?: string }>(); + const [visible, toggleVisible] = useToggle(false); + + return ( + <> + {children || ( + + )} + {wikiId && ( + + )} + + ); +}; diff --git a/packages/client/src/components/document/actions/index.module.scss b/packages/client/src/components/document/actions/index.module.scss new file mode 100644 index 0000000..6030de9 --- /dev/null +++ b/packages/client/src/components/document/actions/index.module.scss @@ -0,0 +1,8 @@ +.hoverVisible { + opacity: 0; + + &:hover, + &.isActive { + opacity: 1; + } +} diff --git a/packages/client/src/components/document/actions/index.tsx b/packages/client/src/components/document/actions/index.tsx new file mode 100644 index 0000000..1fd9130 --- /dev/null +++ b/packages/client/src/components/document/actions/index.tsx @@ -0,0 +1,229 @@ +import React, { useCallback } from 'react'; + +import { IconArticle, IconBranch, IconExport, IconHistory, IconMore, IconPlus, IconStar } from '@douyinfe/semi-icons'; +import { Button, Dropdown, Space, Typography } from '@douyinfe/semi-ui'; +import { ButtonProps } from '@douyinfe/semi-ui/button/Button'; + +import { IDocument, IOrganization, IWiki } from '@think/domains'; + +import cls from 'classnames'; +import { DocumentCreator } from 'components/document/create'; +import { DocumentDeletor } from 'components/document/delete'; +import { DocumentExporter } from 'components/document/export'; +import { DocumentLinkCopyer } from 'components/document/link'; +import { DocumentShare } from 'components/document/share'; +import { DocumentStar } from 'components/document/star'; +import { DocumentStyle } from 'components/document/style'; +import { DocumentVersionTrigger } from 'components/document/version'; +import { useToggle } from 'hooks/use-toggle'; + +import styles from './index.module.scss'; + +interface IProps { + organizationId: IOrganization['id']; + wikiId: IWiki['id']; + documentId: IDocument['id']; + document?: IDocument; + hoverVisible?: boolean; + onStar?: () => void; + onCreate?: () => void; + onDelete?: () => void; + onVisibleChange?: () => void; + showCreateDocument?: boolean; + size?: ButtonProps['size']; + hideDocumentVersion?: boolean; + hideDocumentStyle?: boolean; +} + +const { Text } = Typography; + +export const DocumentActions: React.FC = ({ + organizationId, + wikiId, + documentId, + hoverVisible, + document, + onStar, + onCreate, + onDelete, + onVisibleChange, + showCreateDocument, + size = 'default', + hideDocumentVersion = false, + hideDocumentStyle = false, +}) => { + const [popoverVisible, togglePopoverVisible] = useToggle(false); + const [createVisible, toggleCreateVisible] = useToggle(false); + + const create = useCallback(() => { + togglePopoverVisible(false); + toggleCreateVisible(true); + }, [togglePopoverVisible, toggleCreateVisible]); + + const wrapedOnDelete = useCallback(() => { + togglePopoverVisible(false); + onDelete && onDelete(); + }, [onDelete, togglePopoverVisible]); + + const wrapOnVisibleChange = useCallback( + (visible) => { + togglePopoverVisible(visible); + onVisibleChange && onVisibleChange(); + }, + [onVisibleChange, togglePopoverVisible] + ); + + return ( + <> + + {showCreateDocument && ( + + + + + 新建子文档 + + + + )} + + { + return ( + + + + + {isPublic ? '分享中' : '分享'} + + + + ); + }} + /> + + ( + { + toggleStar().then(onStar); + }} + > + + + + {text} + + + + )} + /> + + { + return ( + + {children} + + ); + }} + /> + + {!hideDocumentVersion && ( + { + return ( + { + togglePopoverVisible(false); + onClick(); + }} + > + + + + 历史记录 + + + + ); + }} + /> + )} + + {document && ( + { + return ( + toggleVisible(true)}> + + + + 文档导出 + + + + ); + }} + /> + )} + + + + { + return {children}; + }} + /> + + } + > + + + + + + ) : ( +
+ 写下评论... +
+ )} + + + + ); +}; diff --git a/packages/client/src/components/document/create/index.module.scss b/packages/client/src/components/document/create/index.module.scss new file mode 100644 index 0000000..f6ca037 --- /dev/null +++ b/packages/client/src/components/document/create/index.module.scss @@ -0,0 +1,3 @@ +.isActive { + border: 1px solid var(--semi-color-link); +} diff --git a/packages/client/src/components/document/create/index.tsx b/packages/client/src/components/document/create/index.tsx new file mode 100644 index 0000000..d392158 --- /dev/null +++ b/packages/client/src/components/document/create/index.tsx @@ -0,0 +1,111 @@ +import { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react'; + +import { Checkbox, Modal, TabPane, Tabs } from '@douyinfe/semi-ui'; + +import { IDocument, IWiki } from '@think/domains'; + +import { TemplateCardEmpty } from 'components/template/card'; +import { TemplateList } from 'components/template/list'; +import { useCreateDocument } from 'data/document'; +import { useOwnTemplates, usePublicTemplates } from 'data/template'; +import { useRouterQuery } from 'hooks/use-router-query'; +import Router from 'next/router'; + +import styles from './index.module.scss'; + +interface IProps { + wikiId: IWiki['id']; + parentDocumentId?: IDocument['id']; + visible: boolean; + toggleVisible: Dispatch>; + onCreate?: () => void; +} + +export const DocumentCreator: React.FC = ({ parentDocumentId, wikiId, visible, toggleVisible, onCreate }) => { + const { organizationId } = useRouterQuery<{ organizationId?: string }>(); + const { loading, create } = useCreateDocument(); + const [createChildDoc, setCreateChildDoc] = useState(false); + const [templateId, setTemplateId] = useState(''); + + const handleOk = () => { + const data = { + organizationId, + wikiId, + parentDocumentId: createChildDoc ? parentDocumentId : null, + templateId, + }; + create(data).then((res) => { + toggleVisible(false); + onCreate && onCreate(); + setTemplateId(''); + Router.push({ + pathname: `/app/org/[organizationId]/wiki/[wikiId]/doc/[documentId]/edit`, + query: { organizationId, wikiId, documentId: res.id }, + }); + }); + }; + const handleCancel = useCallback(() => { + toggleVisible(false); + }, [toggleVisible]); + + useEffect(() => { + setCreateChildDoc(!!parentDocumentId); + }, [parentDocumentId]); + + return ( + + setCreateChildDoc(e.target.checked)}> + 为该文档创建子文档 + + ) + } + > + + setTemplateId(id)} + getClassNames={(id) => id === templateId && styles.isActive} + firstListItem={ + !templateId && styles.isActive} + onClick={() => setTemplateId('')} + /> + } + /> + + + setTemplateId(id)} + getClassNames={(id) => id === templateId && styles.isActive} + firstListItem={ + !templateId && styles.isActive} + onClick={() => setTemplateId('')} + /> + } + /> + + + + ); +}; diff --git a/packages/client/src/components/document/delete/index.tsx b/packages/client/src/components/document/delete/index.tsx new file mode 100644 index 0000000..9f92329 --- /dev/null +++ b/packages/client/src/components/document/delete/index.tsx @@ -0,0 +1,67 @@ +import React, { useCallback, useMemo } from 'react'; + +import { IconDelete } from '@douyinfe/semi-icons'; +import { Popconfirm, Space, Typography } from '@douyinfe/semi-ui'; + +import { useDeleteDocument } from 'data/document'; +import { useRouterQuery } from 'hooks/use-router-query'; +import Router from 'next/router'; + +interface IProps { + wikiId: string; + documentId: string; + onDelete?: () => void; + render?: (arg: { children: React.ReactNode }) => React.ReactNode; +} + +const { Text } = Typography; + +export const DocumentDeletor: React.FC = ({ wikiId, documentId, render, onDelete }) => { + const { + organizationId, + wikiId: currentWikiId, + documentId: currentDocumentId, + } = useRouterQuery<{ organizationId: string; wikiId?: string; documentId?: string }>(); + const { deleteDocument: api, loading } = useDeleteDocument(documentId); + + const deleteAction = useCallback(() => { + api().then(() => { + const navigate = () => { + if (wikiId !== currentWikiId || documentId !== currentDocumentId) { + return; + } + Router.push({ + pathname: `/app/org/[organizationId]/wiki/[wikiId]`, + query: { organizationId, wikiId }, + }); + }; + + navigate(); + onDelete && onDelete(); + }); + }, [organizationId, wikiId, documentId, api, onDelete, currentWikiId, currentDocumentId]); + + const content = useMemo( + () => ( + + + + 删除 + + + ), + [] + ); + + return ( + + {render ? render({ children: content }) : content} + + ); +}; diff --git a/packages/client/src/components/document/editor/editor.tsx b/packages/client/src/components/document/editor/editor.tsx new file mode 100644 index 0000000..fd1899c --- /dev/null +++ b/packages/client/src/components/document/editor/editor.tsx @@ -0,0 +1,53 @@ +import React, { useEffect, useRef } from 'react'; + +import { IAuthority, ILoginUser } from '@think/domains'; + +import { CollaborationEditor, ICollaborationRefProps } from 'tiptap/editor'; + +import cls from 'classnames'; +import { event, triggerChangeDocumentTitle, triggerJoinUser, USE_DOCUMENT_VERSION } from 'event'; +import { useMount } from 'hooks/use-mount'; + +import styles from './index.module.scss'; + +interface IProps { + user: ILoginUser; + documentId: string; + authority: IAuthority; +} + +export const Editor: React.FC = ({ user: currentUser, documentId, authority }) => { + const $editor = useRef(); + const mounted = useMount(); + + useEffect(() => { + const handler = (data) => { + const editor = $editor.current && $editor.current.getEditor(); + if (!editor) return; + editor.commands.setContent(data); + }; + + event.on(USE_DOCUMENT_VERSION, handler); + + return () => { + event.off(USE_DOCUMENT_VERSION, handler); + }; + }, []); + + return ( +
+ {mounted && ( + + )} +
+ ); +}; diff --git a/packages/client/src/components/document/editor/index.module.scss b/packages/client/src/components/document/editor/index.module.scss new file mode 100644 index 0000000..e23330f --- /dev/null +++ b/packages/client/src/components/document/editor/index.module.scss @@ -0,0 +1,33 @@ +/* stylelint-disable no-descending-specificity */ +.wrap { + display: flex; + flex-direction: column; + height: 100%; + overflow: hidden; + + > header { + position: relative; + z-index: 110; + background-color: var(--semi-color-nav-bg); + user-select: none; + + .mobileToolbar { + padding: 12px 16px; + overflow: auto; + text-align: center; + border-bottom: 1px solid var(--semi-color-border); + } + } + + > main { + height: calc(100% - 60px); + overflow: hidden; + background-color: var(--semi-color-nav-bg); + flex: 1; + } +} + +.editorWrap { + height: 100%; + overflow: hidden; +} diff --git a/packages/client/src/components/document/editor/index.tsx b/packages/client/src/components/document/editor/index.tsx new file mode 100644 index 0000000..642e04f --- /dev/null +++ b/packages/client/src/components/document/editor/index.tsx @@ -0,0 +1,150 @@ +import React, { useCallback, useEffect, useMemo, useState } from 'react'; + +import { IconChevronLeft } from '@douyinfe/semi-icons'; +import { Button, Nav, Skeleton, Space, Tooltip, Typography } from '@douyinfe/semi-ui'; + +import { DataRender } from 'components/data-render'; +import { Divider } from 'components/divider'; +import { DocumentCollaboration } from 'components/document/collaboration'; +import { DocumentStar } from 'components/document/star'; +import { DocumentVersion } from 'components/document/version'; +import { Seo } from 'components/seo'; +import { Theme } from 'components/theme'; +import { User } from 'components/user'; +import { useDocumentDetail } from 'data/document'; +import { useUser } from 'data/user'; +import { CHANGE_DOCUMENT_TITLE, event, triggerUseDocumentVersion } from 'event'; +import { triggerRefreshTocs } from 'event'; +import { IsOnMobile } from 'hooks/use-on-mobile'; +import { useWindowSize } from 'hooks/use-window-size'; +import { SecureDocumentIllustration } from 'illustrations/secure-document'; +import Router from 'next/router'; + +import { DocumentActions } from '../actions'; +import { Editor } from './editor'; + +import styles from './index.module.scss'; + +const { Text } = Typography; + +interface IProps { + documentId: string; +} + +const ErrorContent = () => { + return ( +
+ +
+ ); +}; + +export const DocumentEditor: React.FC = ({ documentId }) => { + const { isMobile } = IsOnMobile.useHook(); + const { width: windowWith } = useWindowSize(); + const [title, setTitle] = useState(''); + const { user } = useUser(); + const { data: documentAndAuth, loading: docAuthLoading, error: docAuthError } = useDocumentDetail(documentId); + const { document, authority } = documentAndAuth || {}; + + const goback = useCallback(() => { + Router.push({ + pathname: `/app/org/[organizationId]/wiki/[wikiId]/doc/[documentId]`, + query: { organizationId: document.organizationId, wikiId: document.wikiId, documentId: document.id }, + }).then(() => { + triggerRefreshTocs(); + }); + }, [document]); + + const actions = useMemo( + () => ( + + {document && authority.readable && ( + + )} + {document && ( + + )} + {document && ( + + )} + + + ), + [documentId, document, authority] + ); + + useEffect(() => { + event.on(CHANGE_DOCUMENT_TITLE, setTitle); + + return () => { + event.off(CHANGE_DOCUMENT_TITLE, setTitle); + }; + }, []); + + return ( +
+
+
+
+ } + normalContent={() => { + return ( + <> + {document && } + {user && } + + ); + }} + /> +
+
+ ); +}; diff --git a/packages/client/src/components/document/export/index.module.scss b/packages/client/src/components/document/export/index.module.scss new file mode 100644 index 0000000..6956c8e --- /dev/null +++ b/packages/client/src/components/document/export/index.module.scss @@ -0,0 +1,16 @@ +.templateItem { + display: flex; + width: 118px; + padding: 12px; + cursor: pointer; + border: 1px solid transparent; + border-radius: var(--border-radius); + justify-content: center; + align-items: center; + flex-direction: column; + + &:hover { + border-color: var(--semi-color-border); + box-shadow: var(--box-shadow); + } +} diff --git a/packages/client/src/components/document/export/index.tsx b/packages/client/src/components/document/export/index.tsx new file mode 100644 index 0000000..00f6577 --- /dev/null +++ b/packages/client/src/components/document/export/index.tsx @@ -0,0 +1,186 @@ +import React, { useCallback, useEffect, useMemo } from 'react'; + +import { Badge, Button, Dropdown, Modal, Space, Typography } from '@douyinfe/semi-ui'; + +import { IDocument } from '@think/domains'; + +import { createEditor } from 'tiptap/core'; +import { AllExtensions } from 'tiptap/core/all-kit'; +import { prosemirrorToMarkdown } from 'tiptap/markdown/prosemirror-to-markdown'; + +import { IconJSON, IconMarkdown, IconPDF, IconWord } from 'components/icons'; +import { useDocumentDetail } from 'data/document'; +import FileSaver from 'file-saver'; +import { safeJSONParse, safeJSONStringify } from 'helpers/json'; +import { IsOnMobile } from 'hooks/use-on-mobile'; +import { useToggle } from 'hooks/use-toggle'; + +import { printEditorContent } from './pdf'; + +import styles from './index.module.scss'; + +const { Text } = Typography; + +interface IProps { + document: IDocument; + render?: (arg: { toggleVisible: (arg: boolean) => void }) => React.ReactNode; +} + +export const DocumentExporter: React.FC = ({ document, render }) => { + const { isMobile } = IsOnMobile.useHook(); + const [visible, toggleVisible] = useToggle(false); + const { exportDocx } = useDocumentDetail(document.id); + + const editor = useMemo(() => { + return createEditor({ + editable: false, + extensions: AllExtensions, + content: '', + editorProps: { + // @ts-ignore + print: true, + }, + }); + }, []); + + const exportMarkdown = useCallback(() => { + const md = prosemirrorToMarkdown({ content: editor.state.doc.slice(0).content }); + const blob = new Blob([md], { type: 'text/plain;charset=utf-8' }); + FileSaver.saveAs(blob, `${document.title}.md`); + }, [document, editor]); + + const exportJSON = useCallback(() => { + const blob = new Blob([safeJSONStringify(editor.getJSON())], { type: 'text/plain;charset=utf-8' }); + FileSaver.saveAs(blob, `${document.title}.json`); + }, [document, editor]); + + const exportWord = useCallback(() => { + const editorContent = editor.view.dom.closest('.ProseMirror'); + if (editorContent) { + exportDocx(editorContent.outerHTML).then((res) => { + const blob = new Blob([Buffer.from(res as Buffer)], { type: 'text/plain;charset=utf-8' }); + FileSaver.saveAs(blob, `${document.title}.docx`); + }); + } + }, [editor, exportDocx, document]); + + const exportPDF = useCallback(() => { + printEditorContent(editor.view); + }, [editor]); + + const content = useMemo( + () => ( +
+ +
+
+ +
+
+ Markdown +
+
+ .md +
+
+ +
+
+ +
+
+ JSON +
+
+ .json +
+
+ +
+
+ + + +
+
+ Word +
+
+ .docx +
+
+ +
+
+ + + +
+
+ PDF +
+
+ .pdf +
+
+
+
+ ), + [exportMarkdown, exportJSON, exportWord, exportPDF] + ); + + const btn = useMemo( + () => + render ? ( + render({ toggleVisible }) + ) : ( + + ), + [render, toggleVisible] + ); + + useEffect(() => { + const c = safeJSONParse(document && document.content); + const json = c.default || c; + editor.commands.setContent(json); + }, [editor, document]); + + return ( + <> + {isMobile ? ( + <> + + {content} + + {btn} + + ) : ( + {content}} + > + {btn} + + )} + + ); +}; diff --git a/packages/client/src/components/document/export/pdf.ts b/packages/client/src/components/document/export/pdf.ts new file mode 100644 index 0000000..69d1689 --- /dev/null +++ b/packages/client/src/components/document/export/pdf.ts @@ -0,0 +1,56 @@ +import { EditorView } from 'prosemirror-view'; + +function printHtml(dom: Element) { + const style: string = Array.from(document.querySelectorAll('style, link')).reduce( + (str, style) => str + style.outerHTML, + '' + ); + + const content: string = style + dom.outerHTML; + + const iframe: HTMLIFrameElement = document.createElement('iframe'); + iframe.setAttribute('style', 'position: absolute; width: 0; height: 0; top: 0; left: 0;'); + document.body.appendChild(iframe); + + const frameWindow = iframe.contentWindow; + const doc = iframe.contentDocument || (iframe.contentWindow && iframe.contentWindow.document); + + if (doc) { + doc.open(); + doc.write(content); + doc.close(); + } + + if (frameWindow) { + iframe.onload = function () { + try { + setTimeout(() => { + frameWindow.focus(); + try { + if (!frameWindow.document.execCommand('print', false)) { + frameWindow.print(); + } + } catch (e) { + frameWindow.print(); + } + frameWindow.close(); + }, 10); + } catch (err) { + console.error(err); + } + + setTimeout(function () { + document.body.removeChild(iframe); + }, 100); + }; + } +} + +export function printEditorContent(view: EditorView) { + const editorContent = view.dom.closest('.ProseMirror'); + if (editorContent) { + printHtml(editorContent); + return true; + } + return false; +} diff --git a/packages/client/src/components/document/fullscreen/index.module.scss b/packages/client/src/components/document/fullscreen/index.module.scss new file mode 100644 index 0000000..0d65f6b --- /dev/null +++ b/packages/client/src/components/document/fullscreen/index.module.scss @@ -0,0 +1,143 @@ +.wrap { + width: 100vw; + height: 100vh; + overflow: auto; + background-color: var(--semi-color-bg-0); +} + +.fullscreenContainer { + position: fixed; + background: var(--semi-color-bg-0); + + .show { + z-index: 2; + opacity: 1; + } + + .hidden { + z-index: -1; + opacity: 0; + } + + .fullscreenContent { + position: relative; + min-width: 100%; + min-height: 100%; + + .header { + position: fixed; + z-index: 2; + display: flex; + width: 100%; + height: 60px; + padding: 0 24px; + background-color: var(--semi-color-bg-0); + opacity: 0.9; + align-items: center; + } + + .content { + position: relative; + z-index: 1; + width: auto; + height: 100vh; + min-height: 680px; + padding: 60px 120px 0; + margin: 0 auto; + overflow: auto; + letter-spacing: 0.05em; + background: var(--semi-color-bg-1); + transition: width 0.3s linear, padding 0.3s linear; + + .title { + display: flex; + align-items: flex-start; + flex-direction: column; + justify-content: center; + height: 100vh; + font-size: 4rem; + line-height: 4.6rem; + color: var(--semi-color-text-0); + text-align: left; + word-wrap: break-word; + vertical-align: middle; + overflow-wrap: break-word; + + .imgCover { + position: relative; + width: 100%; + height: 62.5%; + margin-bottom: 16px; + overflow: hidden; + + > img { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + object-position: center 50%; + object-fit: cover; + } + } + } + + .node-title.is-empty { + display: none !important; + } + } + } +} + +.fullScreenToolbar { + position: fixed; + bottom: 40px; + left: 50%; + z-index: 2; + padding: 12px; + background-color: rgb(var(--semi-grey-9)); + border-radius: var(--semi-border-radius-medium); + opacity: 0; + transform: translateX(-50%); + transition: opacity 0.5s ease-in-out; + + &.isVisible { + opacity: 1; + } + + .selected { + background-color: rgb(var(--semi-grey-8)) !important; + } + + .customButton { + display: flex; + height: 32px; + min-width: 32px; + padding: 0 8px; + font-size: 14px; + color: rgb(var(--semi-grey-0)); + cursor: pointer; + background: none; + border: none; + border-radius: 2px; + outline: none; + align-items: center; + + &:hover { + background-color: rgb(var(--semi-grey-8)); + } + } + + .divider { + width: 1px; + height: 1em; + background: rgb(var(--semi-grey-0)); + } +} + +.drawingCursor { + position: fixed; + top: 0; + left: 0; + z-index: 999999; +} diff --git a/packages/client/src/components/document/fullscreen/index.tsx b/packages/client/src/components/document/fullscreen/index.tsx new file mode 100644 index 0000000..82ef869 --- /dev/null +++ b/packages/client/src/components/document/fullscreen/index.tsx @@ -0,0 +1,156 @@ +import React, { useCallback, useEffect, useRef, useState } from 'react'; +import { FullScreen, useFullScreenHandle } from 'react-full-screen'; + +import { IconShrinkScreenStroked } from '@douyinfe/semi-icons'; +import { Button, Space, Tooltip, Typography } from '@douyinfe/semi-ui'; + +import { EditorContent, useEditor } from '@tiptap/react'; +import { CollaborationKit, Document } from 'tiptap/editor'; + +import cls from 'classnames'; +import { IconFullscreen } from 'components/icons/IconFullscreen'; +import { IconPencil } from 'components/icons/IconPencil'; +import { safeJSONParse } from 'helpers/json'; +import { useDrawingCursor } from 'hooks/use-cursor'; +import { useToggle } from 'hooks/use-toggle'; + +import styles from './index.module.scss'; + +const { Title } = Typography; + +// 控制器 +const FullscreenController = ({ handle: fullscreenHandler, isDrawing, toggleDrawing }) => { + const timerRef = useRef>(null); + const [visible, toggleVisible] = useState(true); + + const startDrawing = useCallback(() => { + toggleDrawing(!isDrawing); + }, [isDrawing, toggleDrawing]); + + const close = useCallback(() => { + fullscreenHandler.exit(); + toggleDrawing(false); + }, [fullscreenHandler, toggleDrawing]); + + useEffect(() => { + timerRef.current = setTimeout(() => { + toggleVisible(false); + }, 2000); + }, [toggleVisible]); + + return ( +
{ + clearTimeout(timerRef.current); + toggleVisible(true); + }} + onMouseLeave={() => toggleVisible(false)} + > + + +
+ +
+
+ ); +}; + +// 画笔 +const DrawingCursor = ({ isDrawing }) => { + useDrawingCursor(isDrawing); + return isDrawing &&
; +}; + +interface IProps { + data?: any; +} + +// 全屏按钮 +export const DocumentFullscreen: React.FC = ({ data }) => { + const fullscreenHandler = useFullScreenHandle(); + const [visible, toggleVisible] = useToggle(false); + const [isDrawing, toggleDrawing] = useToggle(false); + const [cover, setCover] = useState(''); + + const editor = useEditor( + { + editable: false, + extensions: CollaborationKit.filter((ext) => ['title', 'doc'].indexOf(ext.name) < 0).concat(Document), + content: { type: 'doc', content: [] }, + }, + [] + ); + + const startPowerpoint = useCallback(() => { + toggleVisible(true); + fullscreenHandler.enter(); + }, [toggleVisible, fullscreenHandler]); + + const fullscreenChange = useCallback( + (state) => { + if (!state) { + toggleVisible(false); + toggleDrawing(false); + } + }, + [toggleVisible, toggleDrawing] + ); + + useEffect(() => { + if (!editor || !visible) return; + const docJSON = safeJSONParse(data.content, { default: {} }).default; + const titleNode = docJSON.content.find((item) => item.type === 'title'); + docJSON.content = docJSON.content.filter((item) => item.type !== 'title'); + setCover(titleNode?.attrs?.cover ?? ''); + editor.commands.setContent(docJSON); + }, [editor, data, visible]); + + return ( + + + + + ); + } + // @ts-ignore + return ( +
+ + + {(error && (error as Error).message) || "未知错误"} + +
+ ); + } + + return ( + <> + {data && } + {mounted && ( + + )} + + ); + }, [error, data, mounted, documentId, renderAuthor, handleOk]); + + return ( + +
+ +
+
+ {(ads || []) + .filter((ad) => ad.type === AdType.shareDocCover) + .map((ad) => { + return ( +
+ + + +
+ ); + })} +
+
+ {content} +
+ +
+ + {(ads || []) + .filter((ad) => ad.type === AdType.shareDocAside) + .map((ad) => { + return ( +
+ + + +
+ ); + })} +
+
+
+ ); +}; diff --git a/packages/client/src/components/document/share/index.tsx b/packages/client/src/components/document/share/index.tsx new file mode 100644 index 0000000..e223024 --- /dev/null +++ b/packages/client/src/components/document/share/index.tsx @@ -0,0 +1,169 @@ +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; + +import { IconLink } from '@douyinfe/semi-icons'; +import { Button, Dropdown, Input, Modal, Space, Toast, Typography } from '@douyinfe/semi-ui'; + +import { isPublicDocument } from '@think/domains'; + +import { useDocumentDetail } from 'data/document'; +import { getDocumentShareURL } from 'helpers/url'; +import { IsOnMobile } from 'hooks/use-on-mobile'; +import { useToggle } from 'hooks/use-toggle'; +import { ShareIllustration } from 'illustrations/share'; + +interface IProps { + documentId: string; + disabled?: boolean; + render?: (arg: { isPublic: boolean; disabled: boolean; toggleVisible: () => void }) => React.ReactNode; +} + +const { Text } = Typography; + +export const DocumentShare: React.FC = ({ documentId, disabled = false, render }) => { + const { isMobile } = IsOnMobile.useHook(); + const ref = useRef(); + const [visible, toggleVisible] = useToggle(false); + const { data, loading, toggleStatus } = useDocumentDetail(documentId, { enabled: visible }); + const [sharePassword, setSharePassword] = useState(''); + const isPublic = useMemo(() => data && isPublicDocument(data.document.status), [data]); + const shareUrl = useMemo(() => data && getDocumentShareURL(data.document.id), [data]); + + const copyable = useMemo( + () => ({ + onCopy: () => Toast.success({ content: '复制文本成功' }), + successTip: '已复制', + }), + [] + ); + + const prevent = useCallback((e) => { + e.stopPropagation(); + }, []); + + const viewUrl = useCallback(() => { + window.open(shareUrl, '_blank'); + }, [shareUrl]); + + const handleOk = useCallback(() => { + toggleStatus({ sharePassword: isPublic ? '' : sharePassword }); + }, [isPublic, sharePassword, toggleStatus]); + + const content = useMemo( + () => ( +
+
+ +
+ {isPublic ? ( + } + copyable={copyable} + style={{ + width: 280, + }} + > + {shareUrl} + + ) : ( + + )} +
+ + {isPublic + ? '分享开启后,该页面包含的所有内容均可访问,请谨慎开启' + : ' 分享关闭后,非协作成员将不能继续访问该页面'} + +
+ + + + {isPublic && ( + + )} + +
+ ), + [copyable, handleOk, isPublic, prevent, sharePassword, shareUrl, toggleVisible, viewUrl] + ); + + const btn = useMemo( + () => + render ? ( + render({ isPublic, disabled, toggleVisible }) + ) : ( + + ), + [disabled, isPublic, render, toggleVisible] + ); + + useEffect(() => { + if (loading || !data) return; + setSharePassword(data.document && data.document.sharePassword); + }, [loading, data]); + + useEffect(() => { + if (visible) { + setTimeout(() => ref.current?.focus(), 100); + } + }, [visible]); + + return ( + <> + {isMobile ? ( + <> + + {content} + + {btn} + + ) : ( + + {content} + + } + > + {btn} + + )} + + ); +}; diff --git a/packages/client/src/components/document/star/index.tsx b/packages/client/src/components/document/star/index.tsx new file mode 100644 index 0000000..d21f1ff --- /dev/null +++ b/packages/client/src/components/document/star/index.tsx @@ -0,0 +1,67 @@ +import React, { useCallback } from 'react'; +import VisibilitySensor from 'react-visibility-sensor'; + +import { IconStar } from '@douyinfe/semi-icons'; +import { Button, Tooltip } from '@douyinfe/semi-ui'; + +import { IDocument, IOrganization, IWiki } from '@think/domains'; + +import { useDocumentStarToggle } from 'data/star'; +import { useToggle } from 'hooks/use-toggle'; + +interface IProps { + organizationId: IOrganization['id']; + wikiId: IWiki['id']; + documentId: IDocument['id']; + disabled?: boolean; + render?: (arg: { + star: boolean; + disabled: boolean; + text: string; + toggleStar: () => Promise; + }) => React.ReactNode; +} + +export const DocumentStar: React.FC = ({ organizationId, wikiId, documentId, disabled = false, render }) => { + const [visible, toggleVisible] = useToggle(false); + const { data, toggle: toggleStar } = useDocumentStarToggle(organizationId, wikiId, documentId, { enabled: visible }); + const text = data ? '取消收藏' : '收藏文档'; + + const onViewportChange = useCallback( + (visible) => { + if (visible) { + toggleVisible(true); + } + }, + [toggleVisible] + ); + + const toggleStarAction = useCallback( + (e) => { + e.stopPropagation(); + e.preventDefault(); + toggleStar(); + }, + [toggleStar] + ); + + return ( + + {render ? ( + render({ star: data, disabled, toggleStar, text }) + ) : ( + + + + + + } + footer={null} + > + ( +
+
+
+ {diffVersion ? ( +
+ ) : ( + + )} +
+
+ +
+ )} + /> + + + ); +}; + +export const DocumentVersionTrigger: React.FC> = ({ render, disabled }) => { + const { toggleVisible } = DocumentVersionControl.useHook(); + + return ( + <> + {render ? ( + render({ onClick: toggleVisible, disabled }) + ) : ( + <> + + + )} + + ); +}; diff --git a/packages/client/src/components/emoji-picker/constants.ts b/packages/client/src/components/emoji-picker/constants.ts new file mode 100644 index 0000000..fde80d3 --- /dev/null +++ b/packages/client/src/components/emoji-picker/constants.ts @@ -0,0 +1,562 @@ +export const EXPRESSIONES = [ + '😀', + '😃', + '😄', + '😁', + '😆', + '😅', + '😂', + '🤣', + '🥲', + '😊', + '😇', + '🙂', + '🙃', + '😉', + '😌', + '😍', + '🥰', + '😘', + '😗', + '😙', + '😚', + '😋', + '😛', + '😝', + '😜', + '🤪', + '🤨', + '🧐', + '🤓', + '😎', + '🥸', + '🤩', + '🥳', + '😏', + '😒', + '😞', + '😔', + '😟', + '😕', + '🙁', + '😣', + '😖', + '😫', + '😩', + '🥺', + '😢', + '😭', + '😤', + '😠', + '😡', + '🤬', + '🤯', + '😳', + '🥵', + '🥶', + '😱', + '😨', + '😰', + '😥', + '😓', + '🤗', + '🤔', + '🤭', + '🤫', + '🤥', + '😶', + '😐', + '😑', + '😬', + '🙄', + '😯', + '😦', + '😧', + '😮', + '😲', + '🥱', + '😴', + '🤤', + '😪', + '😵', + '🤐', + '🥴', + '🤢', + '🤮', + '🤧', + '😷', + '🤒', + '🤕', + '🤑', + '🤠', + '😈', + '👿', + '👹', + '👺', + '🤡', + '💩', + '👻', + '💀', + '☠️', + '👽', + '👾', + '🤖', + '🎃', + '😺', + '😸', + '😹', + '😻', + '😼', + '😽', + '🙀', + '😿', + '😾', +]; + +export const GESTURES = [ + '👋', + '🤚', + '🖐', + '✋', + '🖖', + '👌', + '🤌', + '🤏', + '✌️', + '🤞', + '🤟', + '🤘', + '🤙', + '👈', + '👉', + '👆', + '🖕', + '👇', + '☝️', + '👍', + '👎', + '✊', + '👊', + '🤛', + '🤜', + '👏', + '🙌', + '👐', + '🤲', + '🤝', + '🙏', + '✍️', + '💅', + '🤳', + '💪', + '🦾', + '🦵', + '🦿', + '🦶', + '👣', + '👂', + '🦻', + '👃', + '🫀', + '🫁', + '🧠', + '🦷', + '🦴', + '👀', + '👁', + '👅', + '👄', + '💋', + '🩸', +]; + +export const SYMBOLS = [ + '✅', + '❎', + '✳️', + '♻️', + '❇️', + '✴️', + '❓', + '❗', + '❌', + '⭕', + '❔', + '❕', + '☑️', + '#️⃣', + '*️⃣', + '0️⃣', + '1️⃣', + '2️⃣', + '3️⃣', + '4️⃣', + '5️⃣', + '6️⃣', + '7️⃣', + '8️⃣', + '9️⃣', + '🔟', + '🆗', + '🔠', + '🔡', + '🔢', + '🔣', + '🔤', + '🆕', + '🆖', + '🆒', + '🆓', + 'ℹ️', + '🆎', + '🆑', + '🆘', + '🆙', + '🆚', + '🈁', + '⛔', + '🚫', + '🚳', + '🚭', + '🚯', + '🚱', + '🚷', + '📵', + '🔞', + '☢️', + '☣️', + '↩️', + '↪️', + '⤴️', + '⤵️', + '🔃', + '🔄', + '♈', + '♉', + '♊', + '♋', + '♌', + '♍', + '♎', + '♏', + '♐', + '♑', + '♒', + '♓', + '⛎', + '🛐', + '⚛️', + '🕉️', + '🕉', + '✡️', + '☸️', + '☯️', + '✝️', + '☦️', + '☪️', + '☮️', + '🕎', + '🔯', + '🔀', + '🔁', + '🔂', + '⏩', + '⏭️', + '⏭', + '⏯️', + '⏯', + '⏪', + '⏮️', + '⏮', + '🔼', + '⏫', + '🔽', + '⏬', + '⏸️', + '⏸', + '⏹️', + '⏹', + '⏺️', + '⏺', + '⏏️', + '🎦', + '📶', + '📳', + '📴', + '🏧', + '🚮', + '♿', + '🚹', + '🚺', + '🚻', + '🚼', + '🚾', + '🛂', + '🛃', + '🛄', + '🛅', + '🚸', +]; + +export const OBJECTS = [ + '🔒', + '🔓', + '🔏', + '🔐', + '🔑', + '💼', + '📁', + '📂', + '🗂️', + '🗂', + '📅', + '📆', + '🗒️', + '🗒', + '🗓️', + '🗓', + '📇', + '📈', + '📉', + '📊', + '📋', + '📌', + '📍', + '✏️', + '✏', + '✒️', + '✒', + '🖋️', + '🖋', + '🖊️', + '🖊', + '🖌️', + '🖌', + '🖍️', + '🖍', + '📝', + '✉️', + '📧', + '📨', + '📩', + '📤', + '📥', + '📦', + '📫', + '📪', + '📬', + '📭', + '📮', + '🗳️', + '🗳', + '💰', + '🪙', + '💴', + '💵', + '💶', + '💷', + '💸', + '💳', + '🧾', + '💹', + '📔', + '📕', + '📖', + '📗', + '📘', + '📙', + '📚', + '📓', + '📒', + '📃', + '📜', + '📄', + '📰', + '🗞️', + '🗞', + '📑', + '🔖', + '🏷️', + '🏷', + '👓', + '🕶️', + '🕶', + '🥽', + '🥼', + '🦺', + '👔', + '👕', + '👖', + '🧣', + '🧤', + '🧥', + '🧦', + '👗', + '👘', + '🥻', + '🩱', + '🩲', + '🩳', + '👙', + '👚', + '👛', + '👜', + '👝', + '🛍️', + '🛍', + '🎒', + '🩴', + '👞', + '👟', + '🥾', + '🥿', + '👠', + '👡', + '🩰', + '👢', + '👑', + '👒', + '🎩', + '🎓', + '🧢', + '🪖', + '⛑️', + '⛑', + '📿', + '💄', + '💍', + '💎', +]; + +export const ACTIVITIES = [ + '⚽', + '⚾', + '🥎', + '🏀', + '🏐', + '🏈', + '🏉', + '🎾', + '🥏', + '🎳', + '🏏', + '🏑', + '🏒', + '🥍', + '🏓', + '🏸', + '🥊', + '🥋', + '🥅', + '⛳', + '⛸️', + '⛸', + '🎣', + '🤿', + '🎽', + '🎿', + '🛷', + '🥌', + '🎯', + '🪀', + '🪁', + '🎱', + '🔮', + '🪄', + '🧿', + '🎮', + '🕹️', + '🕹', + '🎰', + '🎲', + '🧩', + '🧸', + '🪅', + '🪆', + '♠️', + '♠', + '♥️', + '♥', + '♦️', + '♦', + '♣️', + '♣', + '🃏', + '🀄', + '🎴', + '🎖️', + '🎖', + '🏆', + '🏅', + '🥇', + '🥈', + '🥉', +]; + +export const SKY_WEATHER = [ + '🌑', + '🌒', + '🌓', + '🌔', + '🌕', + '🌖', + '🌗', + '🌘', + '🌙', + '🌚', + '🌛', + '🌜', + '🌡️', + '🌡', + '☀️', + '☀', + '🌝', + '🌞', + '🪐', + '⭐', + '🌟', + '🌠', + '🌌', + '☁️', + '☁', + '⛅', + '⛈️', + '⛈', + '🌤️', + '🌤', + '🌥️', + '🌥', + '🌦️', + '🌦', + '🌧️', + '🌧', + '🌨️', + '🌨', + '🌩️', + '🌩', + '🌪️', + '🌪', + '🌫️', + '🌫', + '🌬️', + '🌬', + '🌀', + '🌈', + '🌂', + '☂️', + '☂', + '☔', + '⛱️', + '⛱', + '⚡', + '❄️', + '❄', + '☃️', + '☃', + '⛄', + '☄️', + '☄', + '🔥', + '💧', + '🌊', +]; diff --git a/packages/client/src/components/emoji-picker/emoji.json b/packages/client/src/components/emoji-picker/emoji.json new file mode 100644 index 0000000..7b9747c --- /dev/null +++ b/packages/client/src/components/emoji-picker/emoji.json @@ -0,0 +1,4792 @@ +{ + "Smileys & Emotion (face-smiling)": [ + "😀", + "😃", + "😄", + "😁", + "😆", + "😅", + "🤣", + "😂", + "🙂", + "🙃", + "😉", + "😊", + "😇" + ], + "Smileys & Emotion (face-affection)": [ + "🥰", + "😍", + "🤩", + "😘", + "😗", + "☺️", + "☺", + "😚", + "😙", + "🥲" + ], + "Smileys & Emotion (face-tongue)": [ + "😋", + "😛", + "😜", + "🤪", + "😝", + "🤑" + ], + "Smileys & Emotion (face-hand)": [ + "🤗", + "🤭", + "🤫", + "🤔" + ], + "Smileys & Emotion (face-neutral-skeptical)": [ + "🤐", + "🤨", + "😐", + "😑", + "😶", + "😶‍🌫️", + "😶‍🌫", + "😏", + "😒", + "🙄", + "😬", + "😮‍💨", + "🤥" + ], + "Smileys & Emotion (face-sleepy)": [ + "😌", + "😔", + "😪", + "🤤", + "😴" + ], + "Smileys & Emotion (face-unwell)": [ + "😷", + "🤒", + "🤕", + "🤢", + "🤮", + "🤧", + "🥵", + "🥶", + "🥴", + "😵", + "😵‍💫", + "🤯" + ], + "Smileys & Emotion (face-hat)": [ + "🤠", + "🥳", + "🥸" + ], + "Smileys & Emotion (face-glasses)": [ + "😎", + "🤓", + "🧐" + ], + "Smileys & Emotion (face-concerned)": [ + "😕", + "😟", + "🙁", + "☹️", + "☹", + "😮", + "😯", + "😲", + "😳", + "🥺", + "😦", + "😧", + "😨", + "😰", + "😥", + "😢", + "😭", + "😱", + "😖", + "😣", + "😞", + "😓", + "😩", + "😫", + "🥱" + ], + "Smileys & Emotion (face-negative)": [ + "😤", + "😡", + "😠", + "🤬", + "😈", + "👿", + "💀", + "☠️", + "☠" + ], + "Smileys & Emotion (face-costume)": [ + "💩", + "🤡", + "👹", + "👺", + "👻", + "👽", + "👾", + "🤖" + ], + "Smileys & Emotion (cat-face)": [ + "😺", + "😸", + "😹", + "😻", + "😼", + "😽", + "🙀", + "😿", + "😾" + ], + "Smileys & Emotion (monkey-face)": [ + "🙈", + "🙉", + "🙊" + ], + "Smileys & Emotion (emotion)": [ + "💋", + "💌", + "💘", + "💝", + "💖", + "💗", + "💓", + "💞", + "💕", + "💟", + "❣️", + "❣", + "💔", + "❤️‍🔥", + "❤‍🔥", + "❤️‍🩹", + "❤‍🩹", + "❤️", + "❤", + "🧡", + "💛", + "💚", + "💙", + "💜", + "🤎", + "🖤", + "🤍", + "💯", + "💢", + "💥", + "💫", + "💦", + "💨", + "🕳️", + "🕳", + "💣", + "💬", + "👁️‍🗨️", + "👁‍🗨️", + "👁️‍🗨", + "👁‍🗨", + "🗨️", + "🗨", + "🗯️", + "🗯", + "💭", + "💤" + ], + "People & Body (hand-fingers-open)": [ + "👋", + "👋🏻", + "👋🏼", + "👋🏽", + "👋🏾", + "👋🏿", + "🤚", + "🤚🏻", + "🤚🏼", + "🤚🏽", + "🤚🏾", + "🤚🏿", + "🖐️", + "🖐", + "🖐🏻", + "🖐🏼", + "🖐🏽", + "🖐🏾", + "🖐🏿", + "✋", + "✋🏻", + "✋🏼", + "✋🏽", + "✋🏾", + "✋🏿", + "🖖", + "🖖🏻", + "🖖🏼", + "🖖🏽", + "🖖🏾", + "🖖🏿" + ], + "People & Body (hand-fingers-partial)": [ + "👌", + "👌🏻", + "👌🏼", + "👌🏽", + "👌🏾", + "👌🏿", + "🤌", + "🤌🏻", + "🤌🏼", + "🤌🏽", + "🤌🏾", + "🤌🏿", + "🤏", + "🤏🏻", + "🤏🏼", + "🤏🏽", + "🤏🏾", + "🤏🏿", + "✌️", + "✌", + "✌🏻", + "✌🏼", + "✌🏽", + "✌🏾", + "✌🏿", + "🤞", + "🤞🏻", + "🤞🏼", + "🤞🏽", + "🤞🏾", + "🤞🏿", + "🤟", + "🤟🏻", + "🤟🏼", + "🤟🏽", + "🤟🏾", + "🤟🏿", + "🤘", + "🤘🏻", + "🤘🏼", + "🤘🏽", + "🤘🏾", + "🤘🏿", + "🤙", + "🤙🏻", + "🤙🏼", + "🤙🏽", + "🤙🏾", + "🤙🏿" + ], + "People & Body (hand-single-finger)": [ + "👈", + "👈🏻", + "👈🏼", + "👈🏽", + "👈🏾", + "👈🏿", + "👉", + "👉🏻", + "👉🏼", + "👉🏽", + "👉🏾", + "👉🏿", + "👆", + "👆🏻", + "👆🏼", + "👆🏽", + "👆🏾", + "👆🏿", + "🖕", + "🖕🏻", + "🖕🏼", + "🖕🏽", + "🖕🏾", + "🖕🏿", + "👇", + "👇🏻", + "👇🏼", + "👇🏽", + "👇🏾", + "👇🏿", + "☝️", + "☝", + "☝🏻", + "☝🏼", + "☝🏽", + "☝🏾", + "☝🏿" + ], + "People & Body (hand-fingers-closed)": [ + "👍", + "👍🏻", + "👍🏼", + "👍🏽", + "👍🏾", + "👍🏿", + "👎", + "👎🏻", + "👎🏼", + "👎🏽", + "👎🏾", + "👎🏿", + "✊", + "✊🏻", + "✊🏼", + "✊🏽", + "✊🏾", + "✊🏿", + "👊", + "👊🏻", + "👊🏼", + "👊🏽", + "👊🏾", + "👊🏿", + "🤛", + "🤛🏻", + "🤛🏼", + "🤛🏽", + "🤛🏾", + "🤛🏿", + "🤜", + "🤜🏻", + "🤜🏼", + "🤜🏽", + "🤜🏾", + "🤜🏿" + ], + "People & Body (hands)": [ + "👏", + "👏🏻", + "👏🏼", + "👏🏽", + "👏🏾", + "👏🏿", + "🙌", + "🙌🏻", + "🙌🏼", + "🙌🏽", + "🙌🏾", + "🙌🏿", + "👐", + "👐🏻", + "👐🏼", + "👐🏽", + "👐🏾", + "👐🏿", + "🤲", + "🤲🏻", + "🤲🏼", + "🤲🏽", + "🤲🏾", + "🤲🏿", + "🤝", + "🙏", + "🙏🏻", + "🙏🏼", + "🙏🏽", + "🙏🏾", + "🙏🏿" + ], + "People & Body (hand-prop)": [ + "✍️", + "✍", + "✍🏻", + "✍🏼", + "✍🏽", + "✍🏾", + "✍🏿", + "💅", + "💅🏻", + "💅🏼", + "💅🏽", + "💅🏾", + "💅🏿", + "🤳", + "🤳🏻", + "🤳🏼", + "🤳🏽", + "🤳🏾", + "🤳🏿" + ], + "People & Body (body-parts)": [ + "💪", + "💪🏻", + "💪🏼", + "💪🏽", + "💪🏾", + "💪🏿", + "🦾", + "🦿", + "🦵", + "🦵🏻", + "🦵🏼", + "🦵🏽", + "🦵🏾", + "🦵🏿", + "🦶", + "🦶🏻", + "🦶🏼", + "🦶🏽", + "🦶🏾", + "🦶🏿", + "👂", + "👂🏻", + "👂🏼", + "👂🏽", + "👂🏾", + "👂🏿", + "🦻", + "🦻🏻", + "🦻🏼", + "🦻🏽", + "🦻🏾", + "🦻🏿", + "👃", + "👃🏻", + "👃🏼", + "👃🏽", + "👃🏾", + "👃🏿", + "🧠", + "🫀", + "🫁", + "🦷", + "🦴", + "👀", + "👁️", + "👁", + "👅", + "👄" + ], + "People & Body (person)": [ + "👶", + "👶🏻", + "👶🏼", + "👶🏽", + "👶🏾", + "👶🏿", + "🧒", + "🧒🏻", + "🧒🏼", + "🧒🏽", + "🧒🏾", + "🧒🏿", + "👦", + "👦🏻", + "👦🏼", + "👦🏽", + "👦🏾", + "👦🏿", + "👧", + "👧🏻", + "👧🏼", + "👧🏽", + "👧🏾", + "👧🏿", + "🧑", + "🧑🏻", + "🧑🏼", + "🧑🏽", + "🧑🏾", + "🧑🏿", + "👱", + "👱🏻", + "👱🏼", + "👱🏽", + "👱🏾", + "👱🏿", + "👨", + "👨🏻", + "👨🏼", + "👨🏽", + "👨🏾", + "👨🏿", + "🧔", + "🧔🏻", + "🧔🏼", + "🧔🏽", + "🧔🏾", + "🧔🏿", + "🧔‍♂️", + "🧔‍♂", + "🧔🏻‍♂️", + "🧔🏻‍♂", + "🧔🏼‍♂️", + "🧔🏼‍♂", + "🧔🏽‍♂️", + "🧔🏽‍♂", + "🧔🏾‍♂️", + "🧔🏾‍♂", + "🧔🏿‍♂️", + "🧔🏿‍♂", + "🧔‍♀️", + "🧔‍♀", + "🧔🏻‍♀️", + "🧔🏻‍♀", + "🧔🏼‍♀️", + "🧔🏼‍♀", + "🧔🏽‍♀️", + "🧔🏽‍♀", + "🧔🏾‍♀️", + "🧔🏾‍♀", + "🧔🏿‍♀️", + "🧔🏿‍♀", + "👨‍🦰", + "👨🏻‍🦰", + "👨🏼‍🦰", + "👨🏽‍🦰", + "👨🏾‍🦰", + "👨🏿‍🦰", + "👨‍🦱", + "👨🏻‍🦱", + "👨🏼‍🦱", + "👨🏽‍🦱", + "👨🏾‍🦱", + "👨🏿‍🦱", + "👨‍🦳", + "👨🏻‍🦳", + "👨🏼‍🦳", + "👨🏽‍🦳", + "👨🏾‍🦳", + "👨🏿‍🦳", + "👨‍🦲", + "👨🏻‍🦲", + "👨🏼‍🦲", + "👨🏽‍🦲", + "👨🏾‍🦲", + "👨🏿‍🦲", + "👩", + "👩🏻", + "👩🏼", + "👩🏽", + "👩🏾", + "👩🏿", + "👩‍🦰", + "👩🏻‍🦰", + "👩🏼‍🦰", + "👩🏽‍🦰", + "👩🏾‍🦰", + "👩🏿‍🦰", + "🧑‍🦰", + "🧑🏻‍🦰", + "🧑🏼‍🦰", + "🧑🏽‍🦰", + "🧑🏾‍🦰", + "🧑🏿‍🦰", + "👩‍🦱", + "👩🏻‍🦱", + "👩🏼‍🦱", + "👩🏽‍🦱", + "👩🏾‍🦱", + "👩🏿‍🦱", + "🧑‍🦱", + "🧑🏻‍🦱", + "🧑🏼‍🦱", + "🧑🏽‍🦱", + "🧑🏾‍🦱", + "🧑🏿‍🦱", + "👩‍🦳", + "👩🏻‍🦳", + "👩🏼‍🦳", + "👩🏽‍🦳", + "👩🏾‍🦳", + "👩🏿‍🦳", + "🧑‍🦳", + "🧑🏻‍🦳", + "🧑🏼‍🦳", + "🧑🏽‍🦳", + "🧑🏾‍🦳", + "🧑🏿‍🦳", + "👩‍🦲", + "👩🏻‍🦲", + "👩🏼‍🦲", + "👩🏽‍🦲", + "👩🏾‍🦲", + "👩🏿‍🦲", + "🧑‍🦲", + "🧑🏻‍🦲", + "🧑🏼‍🦲", + "🧑🏽‍🦲", + "🧑🏾‍🦲", + "🧑🏿‍🦲", + "👱‍♀️", + "👱‍♀", + "👱🏻‍♀️", + "👱🏻‍♀", + "👱🏼‍♀️", + "👱🏼‍♀", + "👱🏽‍♀️", + "👱🏽‍♀", + "👱🏾‍♀️", + "👱🏾‍♀", + "👱🏿‍♀️", + "👱🏿‍♀", + "👱‍♂️", + "👱‍♂", + "👱🏻‍♂️", + "👱🏻‍♂", + "👱🏼‍♂️", + "👱🏼‍♂", + "👱🏽‍♂️", + "👱🏽‍♂", + "👱🏾‍♂️", + "👱🏾‍♂", + "👱🏿‍♂️", + "👱🏿‍♂", + "🧓", + "🧓🏻", + "🧓🏼", + "🧓🏽", + "🧓🏾", + "🧓🏿", + "👴", + "👴🏻", + "👴🏼", + "👴🏽", + "👴🏾", + "👴🏿", + "👵", + "👵🏻", + "👵🏼", + "👵🏽", + "👵🏾", + "👵🏿" + ], + "People & Body (person-gesture)": [ + "🙍", + "🙍🏻", + "🙍🏼", + "🙍🏽", + "🙍🏾", + "🙍🏿", + "🙍‍♂️", + "🙍‍♂", + "🙍🏻‍♂️", + "🙍🏻‍♂", + "🙍🏼‍♂️", + "🙍🏼‍♂", + "🙍🏽‍♂️", + "🙍🏽‍♂", + "🙍🏾‍♂️", + "🙍🏾‍♂", + "🙍🏿‍♂️", + "🙍🏿‍♂", + "🙍‍♀️", + "🙍‍♀", + "🙍🏻‍♀️", + "🙍🏻‍♀", + "🙍🏼‍♀️", + "🙍🏼‍♀", + "🙍🏽‍♀️", + "🙍🏽‍♀", + "🙍🏾‍♀️", + "🙍🏾‍♀", + "🙍🏿‍♀️", + "🙍🏿‍♀", + "🙎", + "🙎🏻", + "🙎🏼", + "🙎🏽", + "🙎🏾", + "🙎🏿", + "🙎‍♂️", + "🙎‍♂", + "🙎🏻‍♂️", + "🙎🏻‍♂", + "🙎🏼‍♂️", + "🙎🏼‍♂", + "🙎🏽‍♂️", + "🙎🏽‍♂", + "🙎🏾‍♂️", + "🙎🏾‍♂", + "🙎🏿‍♂️", + "🙎🏿‍♂", + "🙎‍♀️", + "🙎‍♀", + "🙎🏻‍♀️", + "🙎🏻‍♀", + "🙎🏼‍♀️", + "🙎🏼‍♀", + "🙎🏽‍♀️", + "🙎🏽‍♀", + "🙎🏾‍♀️", + "🙎🏾‍♀", + "🙎🏿‍♀️", + "🙎🏿‍♀", + "🙅", + "🙅🏻", + "🙅🏼", + "🙅🏽", + "🙅🏾", + "🙅🏿", + "🙅‍♂️", + "🙅‍♂", + "🙅🏻‍♂️", + "🙅🏻‍♂", + "🙅🏼‍♂️", + "🙅🏼‍♂", + "🙅🏽‍♂️", + "🙅🏽‍♂", + "🙅🏾‍♂️", + "🙅🏾‍♂", + "🙅🏿‍♂️", + "🙅🏿‍♂", + "🙅‍♀️", + "🙅‍♀", + "🙅🏻‍♀️", + "🙅🏻‍♀", + "🙅🏼‍♀️", + "🙅🏼‍♀", + "🙅🏽‍♀️", + "🙅🏽‍♀", + "🙅🏾‍♀️", + "🙅🏾‍♀", + "🙅🏿‍♀️", + "🙅🏿‍♀", + "🙆", + "🙆🏻", + "🙆🏼", + "🙆🏽", + "🙆🏾", + "🙆🏿", + "🙆‍♂️", + "🙆‍♂", + "🙆🏻‍♂️", + "🙆🏻‍♂", + "🙆🏼‍♂️", + "🙆🏼‍♂", + "🙆🏽‍♂️", + "🙆🏽‍♂", + "🙆🏾‍♂️", + "🙆🏾‍♂", + "🙆🏿‍♂️", + "🙆🏿‍♂", + "🙆‍♀️", + "🙆‍♀", + "🙆🏻‍♀️", + "🙆🏻‍♀", + "🙆🏼‍♀️", + "🙆🏼‍♀", + "🙆🏽‍♀️", + "🙆🏽‍♀", + "🙆🏾‍♀️", + "🙆🏾‍♀", + "🙆🏿‍♀️", + "🙆🏿‍♀", + "💁", + "💁🏻", + "💁🏼", + "💁🏽", + "💁🏾", + "💁🏿", + "💁‍♂️", + "💁‍♂", + "💁🏻‍♂️", + "💁🏻‍♂", + "💁🏼‍♂️", + "💁🏼‍♂", + "💁🏽‍♂️", + "💁🏽‍♂", + "💁🏾‍♂️", + "💁🏾‍♂", + "💁🏿‍♂️", + "💁🏿‍♂", + "💁‍♀️", + "💁‍♀", + "💁🏻‍♀️", + "💁🏻‍♀", + "💁🏼‍♀️", + "💁🏼‍♀", + "💁🏽‍♀️", + "💁🏽‍♀", + "💁🏾‍♀️", + "💁🏾‍♀", + "💁🏿‍♀️", + "💁🏿‍♀", + "🙋", + "🙋🏻", + "🙋🏼", + "🙋🏽", + "🙋🏾", + "🙋🏿", + "🙋‍♂️", + "🙋‍♂", + "🙋🏻‍♂️", + "🙋🏻‍♂", + "🙋🏼‍♂️", + "🙋🏼‍♂", + "🙋🏽‍♂️", + "🙋🏽‍♂", + "🙋🏾‍♂️", + "🙋🏾‍♂", + "🙋🏿‍♂️", + "🙋🏿‍♂", + "🙋‍♀️", + "🙋‍♀", + "🙋🏻‍♀️", + "🙋🏻‍♀", + "🙋🏼‍♀️", + "🙋🏼‍♀", + "🙋🏽‍♀️", + "🙋🏽‍♀", + "🙋🏾‍♀️", + "🙋🏾‍♀", + "🙋🏿‍♀️", + "🙋🏿‍♀", + "🧏", + "🧏🏻", + "🧏🏼", + "🧏🏽", + "🧏🏾", + "🧏🏿", + "🧏‍♂️", + "🧏‍♂", + "🧏🏻‍♂️", + "🧏🏻‍♂", + "🧏🏼‍♂️", + "🧏🏼‍♂", + "🧏🏽‍♂️", + "🧏🏽‍♂", + "🧏🏾‍♂️", + "🧏🏾‍♂", + "🧏🏿‍♂️", + "🧏🏿‍♂", + "🧏‍♀️", + "🧏‍♀", + "🧏🏻‍♀️", + "🧏🏻‍♀", + "🧏🏼‍♀️", + "🧏🏼‍♀", + "🧏🏽‍♀️", + "🧏🏽‍♀", + "🧏🏾‍♀️", + "🧏🏾‍♀", + "🧏🏿‍♀️", + "🧏🏿‍♀", + "🙇", + "🙇🏻", + "🙇🏼", + "🙇🏽", + "🙇🏾", + "🙇🏿", + "🙇‍♂️", + "🙇‍♂", + "🙇🏻‍♂️", + "🙇🏻‍♂", + "🙇🏼‍♂️", + "🙇🏼‍♂", + "🙇🏽‍♂️", + "🙇🏽‍♂", + "🙇🏾‍♂️", + "🙇🏾‍♂", + "🙇🏿‍♂️", + "🙇🏿‍♂", + "🙇‍♀️", + "🙇‍♀", + "🙇🏻‍♀️", + "🙇🏻‍♀", + "🙇🏼‍♀️", + "🙇🏼‍♀", + "🙇🏽‍♀️", + "🙇🏽‍♀", + "🙇🏾‍♀️", + "🙇🏾‍♀", + "🙇🏿‍♀️", + "🙇🏿‍♀", + "🤦", + "🤦🏻", + "🤦🏼", + "🤦🏽", + "🤦🏾", + "🤦🏿", + "🤦‍♂️", + "🤦‍♂", + "🤦🏻‍♂️", + "🤦🏻‍♂", + "🤦🏼‍♂️", + "🤦🏼‍♂", + "🤦🏽‍♂️", + "🤦🏽‍♂", + "🤦🏾‍♂️", + "🤦🏾‍♂", + "🤦🏿‍♂️", + "🤦🏿‍♂", + "🤦‍♀️", + "🤦‍♀", + "🤦🏻‍♀️", + "🤦🏻‍♀", + "🤦🏼‍♀️", + "🤦🏼‍♀", + "🤦🏽‍♀️", + "🤦🏽‍♀", + "🤦🏾‍♀️", + "🤦🏾‍♀", + "🤦🏿‍♀️", + "🤦🏿‍♀", + "🤷", + "🤷🏻", + "🤷🏼", + "🤷🏽", + "🤷🏾", + "🤷🏿", + "🤷‍♂️", + "🤷‍♂", + "🤷🏻‍♂️", + "🤷🏻‍♂", + "🤷🏼‍♂️", + "🤷🏼‍♂", + "🤷🏽‍♂️", + "🤷🏽‍♂", + "🤷🏾‍♂️", + "🤷🏾‍♂", + "🤷🏿‍♂️", + "🤷🏿‍♂", + "🤷‍♀️", + "🤷‍♀", + "🤷🏻‍♀️", + "🤷🏻‍♀", + "🤷🏼‍♀️", + "🤷🏼‍♀", + "🤷🏽‍♀️", + "🤷🏽‍♀", + "🤷🏾‍♀️", + "🤷🏾‍♀", + "🤷🏿‍♀️", + "🤷🏿‍♀" + ], + "People & Body (person-role)": [ + "🧑‍⚕️", + "🧑‍⚕", + "🧑🏻‍⚕️", + "🧑🏻‍⚕", + "🧑🏼‍⚕️", + "🧑🏼‍⚕", + "🧑🏽‍⚕️", + "🧑🏽‍⚕", + "🧑🏾‍⚕️", + "🧑🏾‍⚕", + "🧑🏿‍⚕️", + "🧑🏿‍⚕", + "👨‍⚕️", + "👨‍⚕", + "👨🏻‍⚕️", + "👨🏻‍⚕", + "👨🏼‍⚕️", + "👨🏼‍⚕", + "👨🏽‍⚕️", + "👨🏽‍⚕", + "👨🏾‍⚕️", + "👨🏾‍⚕", + "👨🏿‍⚕️", + "👨🏿‍⚕", + "👩‍⚕️", + "👩‍⚕", + "👩🏻‍⚕️", + "👩🏻‍⚕", + "👩🏼‍⚕️", + "👩🏼‍⚕", + "👩🏽‍⚕️", + "👩🏽‍⚕", + "👩🏾‍⚕️", + "👩🏾‍⚕", + "👩🏿‍⚕️", + "👩🏿‍⚕", + "🧑‍🎓", + "🧑🏻‍🎓", + "🧑🏼‍🎓", + "🧑🏽‍🎓", + "🧑🏾‍🎓", + "🧑🏿‍🎓", + "👨‍🎓", + "👨🏻‍🎓", + "👨🏼‍🎓", + "👨🏽‍🎓", + "👨🏾‍🎓", + "👨🏿‍🎓", + "👩‍🎓", + "👩🏻‍🎓", + "👩🏼‍🎓", + "👩🏽‍🎓", + "👩🏾‍🎓", + "👩🏿‍🎓", + "🧑‍🏫", + "🧑🏻‍🏫", + "🧑🏼‍🏫", + "🧑🏽‍🏫", + "🧑🏾‍🏫", + "🧑🏿‍🏫", + "👨‍🏫", + "👨🏻‍🏫", + "👨🏼‍🏫", + "👨🏽‍🏫", + "👨🏾‍🏫", + "👨🏿‍🏫", + "👩‍🏫", + "👩🏻‍🏫", + "👩🏼‍🏫", + "👩🏽‍🏫", + "👩🏾‍🏫", + "👩🏿‍🏫", + "🧑‍⚖️", + "🧑‍⚖", + "🧑🏻‍⚖️", + "🧑🏻‍⚖", + "🧑🏼‍⚖️", + "🧑🏼‍⚖", + "🧑🏽‍⚖️", + "🧑🏽‍⚖", + "🧑🏾‍⚖️", + "🧑🏾‍⚖", + "🧑🏿‍⚖️", + "🧑🏿‍⚖", + "👨‍⚖️", + "👨‍⚖", + "👨🏻‍⚖️", + "👨🏻‍⚖", + "👨🏼‍⚖️", + "👨🏼‍⚖", + "👨🏽‍⚖️", + "👨🏽‍⚖", + "👨🏾‍⚖️", + "👨🏾‍⚖", + "👨🏿‍⚖️", + "👨🏿‍⚖", + "👩‍⚖️", + "👩‍⚖", + "👩🏻‍⚖️", + "👩🏻‍⚖", + "👩🏼‍⚖️", + "👩🏼‍⚖", + "👩🏽‍⚖️", + "👩🏽‍⚖", + "👩🏾‍⚖️", + "👩🏾‍⚖", + "👩🏿‍⚖️", + "👩🏿‍⚖", + "🧑‍🌾", + "🧑🏻‍🌾", + "🧑🏼‍🌾", + "🧑🏽‍🌾", + "🧑🏾‍🌾", + "🧑🏿‍🌾", + "👨‍🌾", + "👨🏻‍🌾", + "👨🏼‍🌾", + "👨🏽‍🌾", + "👨🏾‍🌾", + "👨🏿‍🌾", + "👩‍🌾", + "👩🏻‍🌾", + "👩🏼‍🌾", + "👩🏽‍🌾", + "👩🏾‍🌾", + "👩🏿‍🌾", + "🧑‍🍳", + "🧑🏻‍🍳", + "🧑🏼‍🍳", + "🧑🏽‍🍳", + "🧑🏾‍🍳", + "🧑🏿‍🍳", + "👨‍🍳", + "👨🏻‍🍳", + "👨🏼‍🍳", + "👨🏽‍🍳", + "👨🏾‍🍳", + "👨🏿‍🍳", + "👩‍🍳", + "👩🏻‍🍳", + "👩🏼‍🍳", + "👩🏽‍🍳", + "👩🏾‍🍳", + "👩🏿‍🍳", + "🧑‍🔧", + "🧑🏻‍🔧", + "🧑🏼‍🔧", + "🧑🏽‍🔧", + "🧑🏾‍🔧", + "🧑🏿‍🔧", + "👨‍🔧", + "👨🏻‍🔧", + "👨🏼‍🔧", + "👨🏽‍🔧", + "👨🏾‍🔧", + "👨🏿‍🔧", + "👩‍🔧", + "👩🏻‍🔧", + "👩🏼‍🔧", + "👩🏽‍🔧", + "👩🏾‍🔧", + "👩🏿‍🔧", + "🧑‍🏭", + "🧑🏻‍🏭", + "🧑🏼‍🏭", + "🧑🏽‍🏭", + "🧑🏾‍🏭", + "🧑🏿‍🏭", + "👨‍🏭", + "👨🏻‍🏭", + "👨🏼‍🏭", + "👨🏽‍🏭", + "👨🏾‍🏭", + "👨🏿‍🏭", + "👩‍🏭", + "👩🏻‍🏭", + "👩🏼‍🏭", + "👩🏽‍🏭", + "👩🏾‍🏭", + "👩🏿‍🏭", + "🧑‍💼", + "🧑🏻‍💼", + "🧑🏼‍💼", + "🧑🏽‍💼", + "🧑🏾‍💼", + "🧑🏿‍💼", + "👨‍💼", + "👨🏻‍💼", + "👨🏼‍💼", + "👨🏽‍💼", + "👨🏾‍💼", + "👨🏿‍💼", + "👩‍💼", + "👩🏻‍💼", + "👩🏼‍💼", + "👩🏽‍💼", + "👩🏾‍💼", + "👩🏿‍💼", + "🧑‍🔬", + "🧑🏻‍🔬", + "🧑🏼‍🔬", + "🧑🏽‍🔬", + "🧑🏾‍🔬", + "🧑🏿‍🔬", + "👨‍🔬", + "👨🏻‍🔬", + "👨🏼‍🔬", + "👨🏽‍🔬", + "👨🏾‍🔬", + "👨🏿‍🔬", + "👩‍🔬", + "👩🏻‍🔬", + "👩🏼‍🔬", + "👩🏽‍🔬", + "👩🏾‍🔬", + "👩🏿‍🔬", + "🧑‍💻", + "🧑🏻‍💻", + "🧑🏼‍💻", + "🧑🏽‍💻", + "🧑🏾‍💻", + "🧑🏿‍💻", + "👨‍💻", + "👨🏻‍💻", + "👨🏼‍💻", + "👨🏽‍💻", + "👨🏾‍💻", + "👨🏿‍💻", + "👩‍💻", + "👩🏻‍💻", + "👩🏼‍💻", + "👩🏽‍💻", + "👩🏾‍💻", + "👩🏿‍💻", + "🧑‍🎤", + "🧑🏻‍🎤", + "🧑🏼‍🎤", + "🧑🏽‍🎤", + "🧑🏾‍🎤", + "🧑🏿‍🎤", + "👨‍🎤", + "👨🏻‍🎤", + "👨🏼‍🎤", + "👨🏽‍🎤", + "👨🏾‍🎤", + "👨🏿‍🎤", + "👩‍🎤", + "👩🏻‍🎤", + "👩🏼‍🎤", + "👩🏽‍🎤", + "👩🏾‍🎤", + "👩🏿‍🎤", + "🧑‍🎨", + "🧑🏻‍🎨", + "🧑🏼‍🎨", + "🧑🏽‍🎨", + "🧑🏾‍🎨", + "🧑🏿‍🎨", + "👨‍🎨", + "👨🏻‍🎨", + "👨🏼‍🎨", + "👨🏽‍🎨", + "👨🏾‍🎨", + "👨🏿‍🎨", + "👩‍🎨", + "👩🏻‍🎨", + "👩🏼‍🎨", + "👩🏽‍🎨", + "👩🏾‍🎨", + "👩🏿‍🎨", + "🧑‍✈️", + "🧑‍✈", + "🧑🏻‍✈️", + "🧑🏻‍✈", + "🧑🏼‍✈️", + "🧑🏼‍✈", + "🧑🏽‍✈️", + "🧑🏽‍✈", + "🧑🏾‍✈️", + "🧑🏾‍✈", + "🧑🏿‍✈️", + "🧑🏿‍✈", + "👨‍✈️", + "👨‍✈", + "👨🏻‍✈️", + "👨🏻‍✈", + "👨🏼‍✈️", + "👨🏼‍✈", + "👨🏽‍✈️", + "👨🏽‍✈", + "👨🏾‍✈️", + "👨🏾‍✈", + "👨🏿‍✈️", + "👨🏿‍✈", + "👩‍✈️", + "👩‍✈", + "👩🏻‍✈️", + "👩🏻‍✈", + "👩🏼‍✈️", + "👩🏼‍✈", + "👩🏽‍✈️", + "👩🏽‍✈", + "👩🏾‍✈️", + "👩🏾‍✈", + "👩🏿‍✈️", + "👩🏿‍✈", + "🧑‍🚀", + "🧑🏻‍🚀", + "🧑🏼‍🚀", + "🧑🏽‍🚀", + "🧑🏾‍🚀", + "🧑🏿‍🚀", + "👨‍🚀", + "👨🏻‍🚀", + "👨🏼‍🚀", + "👨🏽‍🚀", + "👨🏾‍🚀", + "👨🏿‍🚀", + "👩‍🚀", + "👩🏻‍🚀", + "👩🏼‍🚀", + "👩🏽‍🚀", + "👩🏾‍🚀", + "👩🏿‍🚀", + "🧑‍🚒", + "🧑🏻‍🚒", + "🧑🏼‍🚒", + "🧑🏽‍🚒", + "🧑🏾‍🚒", + "🧑🏿‍🚒", + "👨‍🚒", + "👨🏻‍🚒", + "👨🏼‍🚒", + "👨🏽‍🚒", + "👨🏾‍🚒", + "👨🏿‍🚒", + "👩‍🚒", + "👩🏻‍🚒", + "👩🏼‍🚒", + "👩🏽‍🚒", + "👩🏾‍🚒", + "👩🏿‍🚒", + "👮", + "👮🏻", + "👮🏼", + "👮🏽", + "👮🏾", + "👮🏿", + "👮‍♂️", + "👮‍♂", + "👮🏻‍♂️", + "👮🏻‍♂", + "👮🏼‍♂️", + "👮🏼‍♂", + "👮🏽‍♂️", + "👮🏽‍♂", + "👮🏾‍♂️", + "👮🏾‍♂", + "👮🏿‍♂️", + "👮🏿‍♂", + "👮‍♀️", + "👮‍♀", + "👮🏻‍♀️", + "👮🏻‍♀", + "👮🏼‍♀️", + "👮🏼‍♀", + "👮🏽‍♀️", + "👮🏽‍♀", + "👮🏾‍♀️", + "👮🏾‍♀", + "👮🏿‍♀️", + "👮🏿‍♀", + "🕵️", + "🕵", + "🕵🏻", + "🕵🏼", + "🕵🏽", + "🕵🏾", + "🕵🏿", + "🕵️‍♂️", + "🕵‍♂️", + "🕵️‍♂", + "🕵‍♂", + "🕵🏻‍♂️", + "🕵🏻‍♂", + "🕵🏼‍♂️", + "🕵🏼‍♂", + "🕵🏽‍♂️", + "🕵🏽‍♂", + "🕵🏾‍♂️", + "🕵🏾‍♂", + "🕵🏿‍♂️", + "🕵🏿‍♂", + "🕵️‍♀️", + "🕵‍♀️", + "🕵️‍♀", + "🕵‍♀", + "🕵🏻‍♀️", + "🕵🏻‍♀", + "🕵🏼‍♀️", + "🕵🏼‍♀", + "🕵🏽‍♀️", + "🕵🏽‍♀", + "🕵🏾‍♀️", + "🕵🏾‍♀", + "🕵🏿‍♀️", + "🕵🏿‍♀", + "💂", + "💂🏻", + "💂🏼", + "💂🏽", + "💂🏾", + "💂🏿", + "💂‍♂️", + "💂‍♂", + "💂🏻‍♂️", + "💂🏻‍♂", + "💂🏼‍♂️", + "💂🏼‍♂", + "💂🏽‍♂️", + "💂🏽‍♂", + "💂🏾‍♂️", + "💂🏾‍♂", + "💂🏿‍♂️", + "💂🏿‍♂", + "💂‍♀️", + "💂‍♀", + "💂🏻‍♀️", + "💂🏻‍♀", + "💂🏼‍♀️", + "💂🏼‍♀", + "💂🏽‍♀️", + "💂🏽‍♀", + "💂🏾‍♀️", + "💂🏾‍♀", + "💂🏿‍♀️", + "💂🏿‍♀", + "🥷", + "🥷🏻", + "🥷🏼", + "🥷🏽", + "🥷🏾", + "🥷🏿", + "👷", + "👷🏻", + "👷🏼", + "👷🏽", + "👷🏾", + "👷🏿", + "👷‍♂️", + "👷‍♂", + "👷🏻‍♂️", + "👷🏻‍♂", + "👷🏼‍♂️", + "👷🏼‍♂", + "👷🏽‍♂️", + "👷🏽‍♂", + "👷🏾‍♂️", + "👷🏾‍♂", + "👷🏿‍♂️", + "👷🏿‍♂", + "👷‍♀️", + "👷‍♀", + "👷🏻‍♀️", + "👷🏻‍♀", + "👷🏼‍♀️", + "👷🏼‍♀", + "👷🏽‍♀️", + "👷🏽‍♀", + "👷🏾‍♀️", + "👷🏾‍♀", + "👷🏿‍♀️", + "👷🏿‍♀", + "🤴", + "🤴🏻", + "🤴🏼", + "🤴🏽", + "🤴🏾", + "🤴🏿", + "👸", + "👸🏻", + "👸🏼", + "👸🏽", + "👸🏾", + "👸🏿", + "👳", + "👳🏻", + "👳🏼", + "👳🏽", + "👳🏾", + "👳🏿", + "👳‍♂️", + "👳‍♂", + "👳🏻‍♂️", + "👳🏻‍♂", + "👳🏼‍♂️", + "👳🏼‍♂", + "👳🏽‍♂️", + "👳🏽‍♂", + "👳🏾‍♂️", + "👳🏾‍♂", + "👳🏿‍♂️", + "👳🏿‍♂", + "👳‍♀️", + "👳‍♀", + "👳🏻‍♀️", + "👳🏻‍♀", + "👳🏼‍♀️", + "👳🏼‍♀", + "👳🏽‍♀️", + "👳🏽‍♀", + "👳🏾‍♀️", + "👳🏾‍♀", + "👳🏿‍♀️", + "👳🏿‍♀", + "👲", + "👲🏻", + "👲🏼", + "👲🏽", + "👲🏾", + "👲🏿", + "🧕", + "🧕🏻", + "🧕🏼", + "🧕🏽", + "🧕🏾", + "🧕🏿", + "🤵", + "🤵🏻", + "🤵🏼", + "🤵🏽", + "🤵🏾", + "🤵🏿", + "🤵‍♂️", + "🤵‍♂", + "🤵🏻‍♂️", + "🤵🏻‍♂", + "🤵🏼‍♂️", + "🤵🏼‍♂", + "🤵🏽‍♂️", + "🤵🏽‍♂", + "🤵🏾‍♂️", + "🤵🏾‍♂", + "🤵🏿‍♂️", + "🤵🏿‍♂", + "🤵‍♀️", + "🤵‍♀", + "🤵🏻‍♀️", + "🤵🏻‍♀", + "🤵🏼‍♀️", + "🤵🏼‍♀", + "🤵🏽‍♀️", + "🤵🏽‍♀", + "🤵🏾‍♀️", + "🤵🏾‍♀", + "🤵🏿‍♀️", + "🤵🏿‍♀", + "👰", + "👰🏻", + "👰🏼", + "👰🏽", + "👰🏾", + "👰🏿", + "👰‍♂️", + "👰‍♂", + "👰🏻‍♂️", + "👰🏻‍♂", + "👰🏼‍♂️", + "👰🏼‍♂", + "👰🏽‍♂️", + "👰🏽‍♂", + "👰🏾‍♂️", + "👰🏾‍♂", + "👰🏿‍♂️", + "👰🏿‍♂", + "👰‍♀️", + "👰‍♀", + "👰🏻‍♀️", + "👰🏻‍♀", + "👰🏼‍♀️", + "👰🏼‍♀", + "👰🏽‍♀️", + "👰🏽‍♀", + "👰🏾‍♀️", + "👰🏾‍♀", + "👰🏿‍♀️", + "👰🏿‍♀", + "🤰", + "🤰🏻", + "🤰🏼", + "🤰🏽", + "🤰🏾", + "🤰🏿", + "🤱", + "🤱🏻", + "🤱🏼", + "🤱🏽", + "🤱🏾", + "🤱🏿", + "👩‍🍼", + "👩🏻‍🍼", + "👩🏼‍🍼", + "👩🏽‍🍼", + "👩🏾‍🍼", + "👩🏿‍🍼", + "👨‍🍼", + "👨🏻‍🍼", + "👨🏼‍🍼", + "👨🏽‍🍼", + "👨🏾‍🍼", + "👨🏿‍🍼", + "🧑‍🍼", + "🧑🏻‍🍼", + "🧑🏼‍🍼", + "🧑🏽‍🍼", + "🧑🏾‍🍼", + "🧑🏿‍🍼" + ], + "People & Body (person-fantasy)": [ + "👼", + "👼🏻", + "👼🏼", + "👼🏽", + "👼🏾", + "👼🏿", + "🎅", + "🎅🏻", + "🎅🏼", + "🎅🏽", + "🎅🏾", + "🎅🏿", + "🤶", + "🤶🏻", + "🤶🏼", + "🤶🏽", + "🤶🏾", + "🤶🏿", + "🧑‍🎄", + "🧑🏻‍🎄", + "🧑🏼‍🎄", + "🧑🏽‍🎄", + "🧑🏾‍🎄", + "🧑🏿‍🎄", + "🦸", + "🦸🏻", + "🦸🏼", + "🦸🏽", + "🦸🏾", + "🦸🏿", + "🦸‍♂️", + "🦸‍♂", + "🦸🏻‍♂️", + "🦸🏻‍♂", + "🦸🏼‍♂️", + "🦸🏼‍♂", + "🦸🏽‍♂️", + "🦸🏽‍♂", + "🦸🏾‍♂️", + "🦸🏾‍♂", + "🦸🏿‍♂️", + "🦸🏿‍♂", + "🦸‍♀️", + "🦸‍♀", + "🦸🏻‍♀️", + "🦸🏻‍♀", + "🦸🏼‍♀️", + "🦸🏼‍♀", + "🦸🏽‍♀️", + "🦸🏽‍♀", + "🦸🏾‍♀️", + "🦸🏾‍♀", + "🦸🏿‍♀️", + "🦸🏿‍♀", + "🦹", + "🦹🏻", + "🦹🏼", + "🦹🏽", + "🦹🏾", + "🦹🏿", + "🦹‍♂️", + "🦹‍♂", + "🦹🏻‍♂️", + "🦹🏻‍♂", + "🦹🏼‍♂️", + "🦹🏼‍♂", + "🦹🏽‍♂️", + "🦹🏽‍♂", + "🦹🏾‍♂️", + "🦹🏾‍♂", + "🦹🏿‍♂️", + "🦹🏿‍♂", + "🦹‍♀️", + "🦹‍♀", + "🦹🏻‍♀️", + "🦹🏻‍♀", + "🦹🏼‍♀️", + "🦹🏼‍♀", + "🦹🏽‍♀️", + "🦹🏽‍♀", + "🦹🏾‍♀️", + "🦹🏾‍♀", + "🦹🏿‍♀️", + "🦹🏿‍♀", + "🧙", + "🧙🏻", + "🧙🏼", + "🧙🏽", + "🧙🏾", + "🧙🏿", + "🧙‍♂️", + "🧙‍♂", + "🧙🏻‍♂️", + "🧙🏻‍♂", + "🧙🏼‍♂️", + "🧙🏼‍♂", + "🧙🏽‍♂️", + "🧙🏽‍♂", + "🧙🏾‍♂️", + "🧙🏾‍♂", + "🧙🏿‍♂️", + "🧙🏿‍♂", + "🧙‍♀️", + "🧙‍♀", + "🧙🏻‍♀️", + "🧙🏻‍♀", + "🧙🏼‍♀️", + "🧙🏼‍♀", + "🧙🏽‍♀️", + "🧙🏽‍♀", + "🧙🏾‍♀️", + "🧙🏾‍♀", + "🧙🏿‍♀️", + "🧙🏿‍♀", + "🧚", + "🧚🏻", + "🧚🏼", + "🧚🏽", + "🧚🏾", + "🧚🏿", + "🧚‍♂️", + "🧚‍♂", + "🧚🏻‍♂️", + "🧚🏻‍♂", + "🧚🏼‍♂️", + "🧚🏼‍♂", + "🧚🏽‍♂️", + "🧚🏽‍♂", + "🧚🏾‍♂️", + "🧚🏾‍♂", + "🧚🏿‍♂️", + "🧚🏿‍♂", + "🧚‍♀️", + "🧚‍♀", + "🧚🏻‍♀️", + "🧚🏻‍♀", + "🧚🏼‍♀️", + "🧚🏼‍♀", + "🧚🏽‍♀️", + "🧚🏽‍♀", + "🧚🏾‍♀️", + "🧚🏾‍♀", + "🧚🏿‍♀️", + "🧚🏿‍♀", + "🧛", + "🧛🏻", + "🧛🏼", + "🧛🏽", + "🧛🏾", + "🧛🏿", + "🧛‍♂️", + "🧛‍♂", + "🧛🏻‍♂️", + "🧛🏻‍♂", + "🧛🏼‍♂️", + "🧛🏼‍♂", + "🧛🏽‍♂️", + "🧛🏽‍♂", + "🧛🏾‍♂️", + "🧛🏾‍♂", + "🧛🏿‍♂️", + "🧛🏿‍♂", + "🧛‍♀️", + "🧛‍♀", + "🧛🏻‍♀️", + "🧛🏻‍♀", + "🧛🏼‍♀️", + "🧛🏼‍♀", + "🧛🏽‍♀️", + "🧛🏽‍♀", + "🧛🏾‍♀️", + "🧛🏾‍♀", + "🧛🏿‍♀️", + "🧛🏿‍♀", + "🧜", + "🧜🏻", + "🧜🏼", + "🧜🏽", + "🧜🏾", + "🧜🏿", + "🧜‍♂️", + "🧜‍♂", + "🧜🏻‍♂️", + "🧜🏻‍♂", + "🧜🏼‍♂️", + "🧜🏼‍♂", + "🧜🏽‍♂️", + "🧜🏽‍♂", + "🧜🏾‍♂️", + "🧜🏾‍♂", + "🧜🏿‍♂️", + "🧜🏿‍♂", + "🧜‍♀️", + "🧜‍♀", + "🧜🏻‍♀️", + "🧜🏻‍♀", + "🧜🏼‍♀️", + "🧜🏼‍♀", + "🧜🏽‍♀️", + "🧜🏽‍♀", + "🧜🏾‍♀️", + "🧜🏾‍♀", + "🧜🏿‍♀️", + "🧜🏿‍♀", + "🧝", + "🧝🏻", + "🧝🏼", + "🧝🏽", + "🧝🏾", + "🧝🏿", + "🧝‍♂️", + "🧝‍♂", + "🧝🏻‍♂️", + "🧝🏻‍♂", + "🧝🏼‍♂️", + "🧝🏼‍♂", + "🧝🏽‍♂️", + "🧝🏽‍♂", + "🧝🏾‍♂️", + "🧝🏾‍♂", + "🧝🏿‍♂️", + "🧝🏿‍♂", + "🧝‍♀️", + "🧝‍♀", + "🧝🏻‍♀️", + "🧝🏻‍♀", + "🧝🏼‍♀️", + "🧝🏼‍♀", + "🧝🏽‍♀️", + "🧝🏽‍♀", + "🧝🏾‍♀️", + "🧝🏾‍♀", + "🧝🏿‍♀️", + "🧝🏿‍♀", + "🧞", + "🧞‍♂️", + "🧞‍♂", + "🧞‍♀️", + "🧞‍♀", + "🧟", + "🧟‍♂️", + "🧟‍♂", + "🧟‍♀️", + "🧟‍♀" + ], + "People & Body (person-activity)": [ + "💆", + "💆🏻", + "💆🏼", + "💆🏽", + "💆🏾", + "💆🏿", + "💆‍♂️", + "💆‍♂", + "💆🏻‍♂️", + "💆🏻‍♂", + "💆🏼‍♂️", + "💆🏼‍♂", + "💆🏽‍♂️", + "💆🏽‍♂", + "💆🏾‍♂️", + "💆🏾‍♂", + "💆🏿‍♂️", + "💆🏿‍♂", + "💆‍♀️", + "💆‍♀", + "💆🏻‍♀️", + "💆🏻‍♀", + "💆🏼‍♀️", + "💆🏼‍♀", + "💆🏽‍♀️", + "💆🏽‍♀", + "💆🏾‍♀️", + "💆🏾‍♀", + "💆🏿‍♀️", + "💆🏿‍♀", + "💇", + "💇🏻", + "💇🏼", + "💇🏽", + "💇🏾", + "💇🏿", + "💇‍♂️", + "💇‍♂", + "💇🏻‍♂️", + "💇🏻‍♂", + "💇🏼‍♂️", + "💇🏼‍♂", + "💇🏽‍♂️", + "💇🏽‍♂", + "💇🏾‍♂️", + "💇🏾‍♂", + "💇🏿‍♂️", + "💇🏿‍♂", + "💇‍♀️", + "💇‍♀", + "💇🏻‍♀️", + "💇🏻‍♀", + "💇🏼‍♀️", + "💇🏼‍♀", + "💇🏽‍♀️", + "💇🏽‍♀", + "💇🏾‍♀️", + "💇🏾‍♀", + "💇🏿‍♀️", + "💇🏿‍♀", + "🚶", + "🚶🏻", + "🚶🏼", + "🚶🏽", + "🚶🏾", + "🚶🏿", + "🚶‍♂️", + "🚶‍♂", + "🚶🏻‍♂️", + "🚶🏻‍♂", + "🚶🏼‍♂️", + "🚶🏼‍♂", + "🚶🏽‍♂️", + "🚶🏽‍♂", + "🚶🏾‍♂️", + "🚶🏾‍♂", + "🚶🏿‍♂️", + "🚶🏿‍♂", + "🚶‍♀️", + "🚶‍♀", + "🚶🏻‍♀️", + "🚶🏻‍♀", + "🚶🏼‍♀️", + "🚶🏼‍♀", + "🚶🏽‍♀️", + "🚶🏽‍♀", + "🚶🏾‍♀️", + "🚶🏾‍♀", + "🚶🏿‍♀️", + "🚶🏿‍♀", + "🧍", + "🧍🏻", + "🧍🏼", + "🧍🏽", + "🧍🏾", + "🧍🏿", + "🧍‍♂️", + "🧍‍♂", + "🧍🏻‍♂️", + "🧍🏻‍♂", + "🧍🏼‍♂️", + "🧍🏼‍♂", + "🧍🏽‍♂️", + "🧍🏽‍♂", + "🧍🏾‍♂️", + "🧍🏾‍♂", + "🧍🏿‍♂️", + "🧍🏿‍♂", + "🧍‍♀️", + "🧍‍♀", + "🧍🏻‍♀️", + "🧍🏻‍♀", + "🧍🏼‍♀️", + "🧍🏼‍♀", + "🧍🏽‍♀️", + "🧍🏽‍♀", + "🧍🏾‍♀️", + "🧍🏾‍♀", + "🧍🏿‍♀️", + "🧍🏿‍♀", + "🧎", + "🧎🏻", + "🧎🏼", + "🧎🏽", + "🧎🏾", + "🧎🏿", + "🧎‍♂️", + "🧎‍♂", + "🧎🏻‍♂️", + "🧎🏻‍♂", + "🧎🏼‍♂️", + "🧎🏼‍♂", + "🧎🏽‍♂️", + "🧎🏽‍♂", + "🧎🏾‍♂️", + "🧎🏾‍♂", + "🧎🏿‍♂️", + "🧎🏿‍♂", + "🧎‍♀️", + "🧎‍♀", + "🧎🏻‍♀️", + "🧎🏻‍♀", + "🧎🏼‍♀️", + "🧎🏼‍♀", + "🧎🏽‍♀️", + "🧎🏽‍♀", + "🧎🏾‍♀️", + "🧎🏾‍♀", + "🧎🏿‍♀️", + "🧎🏿‍♀", + "🧑‍🦯", + "🧑🏻‍🦯", + "🧑🏼‍🦯", + "🧑🏽‍🦯", + "🧑🏾‍🦯", + "🧑🏿‍🦯", + "👨‍🦯", + "👨🏻‍🦯", + "👨🏼‍🦯", + "👨🏽‍🦯", + "👨🏾‍🦯", + "👨🏿‍🦯", + "👩‍🦯", + "👩🏻‍🦯", + "👩🏼‍🦯", + "👩🏽‍🦯", + "👩🏾‍🦯", + "👩🏿‍🦯", + "🧑‍🦼", + "🧑🏻‍🦼", + "🧑🏼‍🦼", + "🧑🏽‍🦼", + "🧑🏾‍🦼", + "🧑🏿‍🦼", + "👨‍🦼", + "👨🏻‍🦼", + "👨🏼‍🦼", + "👨🏽‍🦼", + "👨🏾‍🦼", + "👨🏿‍🦼", + "👩‍🦼", + "👩🏻‍🦼", + "👩🏼‍🦼", + "👩🏽‍🦼", + "👩🏾‍🦼", + "👩🏿‍🦼", + "🧑‍🦽", + "🧑🏻‍🦽", + "🧑🏼‍🦽", + "🧑🏽‍🦽", + "🧑🏾‍🦽", + "🧑🏿‍🦽", + "👨‍🦽", + "👨🏻‍🦽", + "👨🏼‍🦽", + "👨🏽‍🦽", + "👨🏾‍🦽", + "👨🏿‍🦽", + "👩‍🦽", + "👩🏻‍🦽", + "👩🏼‍🦽", + "👩🏽‍🦽", + "👩🏾‍🦽", + "👩🏿‍🦽", + "🏃", + "🏃🏻", + "🏃🏼", + "🏃🏽", + "🏃🏾", + "🏃🏿", + "🏃‍♂️", + "🏃‍♂", + "🏃🏻‍♂️", + "🏃🏻‍♂", + "🏃🏼‍♂️", + "🏃🏼‍♂", + "🏃🏽‍♂️", + "🏃🏽‍♂", + "🏃🏾‍♂️", + "🏃🏾‍♂", + "🏃🏿‍♂️", + "🏃🏿‍♂", + "🏃‍♀️", + "🏃‍♀", + "🏃🏻‍♀️", + "🏃🏻‍♀", + "🏃🏼‍♀️", + "🏃🏼‍♀", + "🏃🏽‍♀️", + "🏃🏽‍♀", + "🏃🏾‍♀️", + "🏃🏾‍♀", + "🏃🏿‍♀️", + "🏃🏿‍♀", + "💃", + "💃🏻", + "💃🏼", + "💃🏽", + "💃🏾", + "💃🏿", + "🕺", + "🕺🏻", + "🕺🏼", + "🕺🏽", + "🕺🏾", + "🕺🏿", + "🕴️", + "🕴", + "🕴🏻", + "🕴🏼", + "🕴🏽", + "🕴🏾", + "🕴🏿", + "👯", + "👯‍♂️", + "👯‍♂", + "👯‍♀️", + "👯‍♀", + "🧖", + "🧖🏻", + "🧖🏼", + "🧖🏽", + "🧖🏾", + "🧖🏿", + "🧖‍♂️", + "🧖‍♂", + "🧖🏻‍♂️", + "🧖🏻‍♂", + "🧖🏼‍♂️", + "🧖🏼‍♂", + "🧖🏽‍♂️", + "🧖🏽‍♂", + "🧖🏾‍♂️", + "🧖🏾‍♂", + "🧖🏿‍♂️", + "🧖🏿‍♂", + "🧖‍♀️", + "🧖‍♀", + "🧖🏻‍♀️", + "🧖🏻‍♀", + "🧖🏼‍♀️", + "🧖🏼‍♀", + "🧖🏽‍♀️", + "🧖🏽‍♀", + "🧖🏾‍♀️", + "🧖🏾‍♀", + "🧖🏿‍♀️", + "🧖🏿‍♀", + "🧗", + "🧗🏻", + "🧗🏼", + "🧗🏽", + "🧗🏾", + "🧗🏿", + "🧗‍♂️", + "🧗‍♂", + "🧗🏻‍♂️", + "🧗🏻‍♂", + "🧗🏼‍♂️", + "🧗🏼‍♂", + "🧗🏽‍♂️", + "🧗🏽‍♂", + "🧗🏾‍♂️", + "🧗🏾‍♂", + "🧗🏿‍♂️", + "🧗🏿‍♂", + "🧗‍♀️", + "🧗‍♀", + "🧗🏻‍♀️", + "🧗🏻‍♀", + "🧗🏼‍♀️", + "🧗🏼‍♀", + "🧗🏽‍♀️", + "🧗🏽‍♀", + "🧗🏾‍♀️", + "🧗🏾‍♀", + "🧗🏿‍♀️", + "🧗🏿‍♀" + ], + "People & Body (person-sport)": [ + "🤺", + "🏇", + "🏇🏻", + "🏇🏼", + "🏇🏽", + "🏇🏾", + "🏇🏿", + "⛷️", + "⛷", + "🏂", + "🏂🏻", + "🏂🏼", + "🏂🏽", + "🏂🏾", + "🏂🏿", + "🏌️", + "🏌", + "🏌🏻", + "🏌🏼", + "🏌🏽", + "🏌🏾", + "🏌🏿", + "🏌️‍♂️", + "🏌‍♂️", + "🏌️‍♂", + "🏌‍♂", + "🏌🏻‍♂️", + "🏌🏻‍♂", + "🏌🏼‍♂️", + "🏌🏼‍♂", + "🏌🏽‍♂️", + "🏌🏽‍♂", + "🏌🏾‍♂️", + "🏌🏾‍♂", + "🏌🏿‍♂️", + "🏌🏿‍♂", + "🏌️‍♀️", + "🏌‍♀️", + "🏌️‍♀", + "🏌‍♀", + "🏌🏻‍♀️", + "🏌🏻‍♀", + "🏌🏼‍♀️", + "🏌🏼‍♀", + "🏌🏽‍♀️", + "🏌🏽‍♀", + "🏌🏾‍♀️", + "🏌🏾‍♀", + "🏌🏿‍♀️", + "🏌🏿‍♀", + "🏄", + "🏄🏻", + "🏄🏼", + "🏄🏽", + "🏄🏾", + "🏄🏿", + "🏄‍♂️", + "🏄‍♂", + "🏄🏻‍♂️", + "🏄🏻‍♂", + "🏄🏼‍♂️", + "🏄🏼‍♂", + "🏄🏽‍♂️", + "🏄🏽‍♂", + "🏄🏾‍♂️", + "🏄🏾‍♂", + "🏄🏿‍♂️", + "🏄🏿‍♂", + "🏄‍♀️", + "🏄‍♀", + "🏄🏻‍♀️", + "🏄🏻‍♀", + "🏄🏼‍♀️", + "🏄🏼‍♀", + "🏄🏽‍♀️", + "🏄🏽‍♀", + "🏄🏾‍♀️", + "🏄🏾‍♀", + "🏄🏿‍♀️", + "🏄🏿‍♀", + "🚣", + "🚣🏻", + "🚣🏼", + "🚣🏽", + "🚣🏾", + "🚣🏿", + "🚣‍♂️", + "🚣‍♂", + "🚣🏻‍♂️", + "🚣🏻‍♂", + "🚣🏼‍♂️", + "🚣🏼‍♂", + "🚣🏽‍♂️", + "🚣🏽‍♂", + "🚣🏾‍♂️", + "🚣🏾‍♂", + "🚣🏿‍♂️", + "🚣🏿‍♂", + "🚣‍♀️", + "🚣‍♀", + "🚣🏻‍♀️", + "🚣🏻‍♀", + "🚣🏼‍♀️", + "🚣🏼‍♀", + "🚣🏽‍♀️", + "🚣🏽‍♀", + "🚣🏾‍♀️", + "🚣🏾‍♀", + "🚣🏿‍♀️", + "🚣🏿‍♀", + "🏊", + "🏊🏻", + "🏊🏼", + "🏊🏽", + "🏊🏾", + "🏊🏿", + "🏊‍♂️", + "🏊‍♂", + "🏊🏻‍♂️", + "🏊🏻‍♂", + "🏊🏼‍♂️", + "🏊🏼‍♂", + "🏊🏽‍♂️", + "🏊🏽‍♂", + "🏊🏾‍♂️", + "🏊🏾‍♂", + "🏊🏿‍♂️", + "🏊🏿‍♂", + "🏊‍♀️", + "🏊‍♀", + "🏊🏻‍♀️", + "🏊🏻‍♀", + "🏊🏼‍♀️", + "🏊🏼‍♀", + "🏊🏽‍♀️", + "🏊🏽‍♀", + "🏊🏾‍♀️", + "🏊🏾‍♀", + "🏊🏿‍♀️", + "🏊🏿‍♀", + "⛹️", + "⛹", + "⛹🏻", + "⛹🏼", + "⛹🏽", + "⛹🏾", + "⛹🏿", + "⛹️‍♂️", + "⛹‍♂️", + "⛹️‍♂", + "⛹‍♂", + "⛹🏻‍♂️", + "⛹🏻‍♂", + "⛹🏼‍♂️", + "⛹🏼‍♂", + "⛹🏽‍♂️", + "⛹🏽‍♂", + "⛹🏾‍♂️", + "⛹🏾‍♂", + "⛹🏿‍♂️", + "⛹🏿‍♂", + "⛹️‍♀️", + "⛹‍♀️", + "⛹️‍♀", + "⛹‍♀", + "⛹🏻‍♀️", + "⛹🏻‍♀", + "⛹🏼‍♀️", + "⛹🏼‍♀", + "⛹🏽‍♀️", + "⛹🏽‍♀", + "⛹🏾‍♀️", + "⛹🏾‍♀", + "⛹🏿‍♀️", + "⛹🏿‍♀", + "🏋️", + "🏋", + "🏋🏻", + "🏋🏼", + "🏋🏽", + "🏋🏾", + "🏋🏿", + "🏋️‍♂️", + "🏋‍♂️", + "🏋️‍♂", + "🏋‍♂", + "🏋🏻‍♂️", + "🏋🏻‍♂", + "🏋🏼‍♂️", + "🏋🏼‍♂", + "🏋🏽‍♂️", + "🏋🏽‍♂", + "🏋🏾‍♂️", + "🏋🏾‍♂", + "🏋🏿‍♂️", + "🏋🏿‍♂", + "🏋️‍♀️", + "🏋‍♀️", + "🏋️‍♀", + "🏋‍♀", + "🏋🏻‍♀️", + "🏋🏻‍♀", + "🏋🏼‍♀️", + "🏋🏼‍♀", + "🏋🏽‍♀️", + "🏋🏽‍♀", + "🏋🏾‍♀️", + "🏋🏾‍♀", + "🏋🏿‍♀️", + "🏋🏿‍♀", + "🚴", + "🚴🏻", + "🚴🏼", + "🚴🏽", + "🚴🏾", + "🚴🏿", + "🚴‍♂️", + "🚴‍♂", + "🚴🏻‍♂️", + "🚴🏻‍♂", + "🚴🏼‍♂️", + "🚴🏼‍♂", + "🚴🏽‍♂️", + "🚴🏽‍♂", + "🚴🏾‍♂️", + "🚴🏾‍♂", + "🚴🏿‍♂️", + "🚴🏿‍♂", + "🚴‍♀️", + "🚴‍♀", + "🚴🏻‍♀️", + "🚴🏻‍♀", + "🚴🏼‍♀️", + "🚴🏼‍♀", + "🚴🏽‍♀️", + "🚴🏽‍♀", + "🚴🏾‍♀️", + "🚴🏾‍♀", + "🚴🏿‍♀️", + "🚴🏿‍♀", + "🚵", + "🚵🏻", + "🚵🏼", + "🚵🏽", + "🚵🏾", + "🚵🏿", + "🚵‍♂️", + "🚵‍♂", + "🚵🏻‍♂️", + "🚵🏻‍♂", + "🚵🏼‍♂️", + "🚵🏼‍♂", + "🚵🏽‍♂️", + "🚵🏽‍♂", + "🚵🏾‍♂️", + "🚵🏾‍♂", + "🚵🏿‍♂️", + "🚵🏿‍♂", + "🚵‍♀️", + "🚵‍♀", + "🚵🏻‍♀️", + "🚵🏻‍♀", + "🚵🏼‍♀️", + "🚵🏼‍♀", + "🚵🏽‍♀️", + "🚵🏽‍♀", + "🚵🏾‍♀️", + "🚵🏾‍♀", + "🚵🏿‍♀️", + "🚵🏿‍♀", + "🤸", + "🤸🏻", + "🤸🏼", + "🤸🏽", + "🤸🏾", + "🤸🏿", + "🤸‍♂️", + "🤸‍♂", + "🤸🏻‍♂️", + "🤸🏻‍♂", + "🤸🏼‍♂️", + "🤸🏼‍♂", + "🤸🏽‍♂️", + "🤸🏽‍♂", + "🤸🏾‍♂️", + "🤸🏾‍♂", + "🤸🏿‍♂️", + "🤸🏿‍♂", + "🤸‍♀️", + "🤸‍♀", + "🤸🏻‍♀️", + "🤸🏻‍♀", + "🤸🏼‍♀️", + "🤸🏼‍♀", + "🤸🏽‍♀️", + "🤸🏽‍♀", + "🤸🏾‍♀️", + "🤸🏾‍♀", + "🤸🏿‍♀️", + "🤸🏿‍♀", + "🤼", + "🤼‍♂️", + "🤼‍♂", + "🤼‍♀️", + "🤼‍♀", + "🤽", + "🤽🏻", + "🤽🏼", + "🤽🏽", + "🤽🏾", + "🤽🏿", + "🤽‍♂️", + "🤽‍♂", + "🤽🏻‍♂️", + "🤽🏻‍♂", + "🤽🏼‍♂️", + "🤽🏼‍♂", + "🤽🏽‍♂️", + "🤽🏽‍♂", + "🤽🏾‍♂️", + "🤽🏾‍♂", + "🤽🏿‍♂️", + "🤽🏿‍♂", + "🤽‍♀️", + "🤽‍♀", + "🤽🏻‍♀️", + "🤽🏻‍♀", + "🤽🏼‍♀️", + "🤽🏼‍♀", + "🤽🏽‍♀️", + "🤽🏽‍♀", + "🤽🏾‍♀️", + "🤽🏾‍♀", + "🤽🏿‍♀️", + "🤽🏿‍♀", + "🤾", + "🤾🏻", + "🤾🏼", + "🤾🏽", + "🤾🏾", + "🤾🏿", + "🤾‍♂️", + "🤾‍♂", + "🤾🏻‍♂️", + "🤾🏻‍♂", + "🤾🏼‍♂️", + "🤾🏼‍♂", + "🤾🏽‍♂️", + "🤾🏽‍♂", + "🤾🏾‍♂️", + "🤾🏾‍♂", + "🤾🏿‍♂️", + "🤾🏿‍♂", + "🤾‍♀️", + "🤾‍♀", + "🤾🏻‍♀️", + "🤾🏻‍♀", + "🤾🏼‍♀️", + "🤾🏼‍♀", + "🤾🏽‍♀️", + "🤾🏽‍♀", + "🤾🏾‍♀️", + "🤾🏾‍♀", + "🤾🏿‍♀️", + "🤾🏿‍♀", + "🤹", + "🤹🏻", + "🤹🏼", + "🤹🏽", + "🤹🏾", + "🤹🏿", + "🤹‍♂️", + "🤹‍♂", + "🤹🏻‍♂️", + "🤹🏻‍♂", + "🤹🏼‍♂️", + "🤹🏼‍♂", + "🤹🏽‍♂️", + "🤹🏽‍♂", + "🤹🏾‍♂️", + "🤹🏾‍♂", + "🤹🏿‍♂️", + "🤹🏿‍♂", + "🤹‍♀️", + "🤹‍♀", + "🤹🏻‍♀️", + "🤹🏻‍♀", + "🤹🏼‍♀️", + "🤹🏼‍♀", + "🤹🏽‍♀️", + "🤹🏽‍♀", + "🤹🏾‍♀️", + "🤹🏾‍♀", + "🤹🏿‍♀️", + "🤹🏿‍♀" + ], + "People & Body (person-resting)": [ + "🧘", + "🧘🏻", + "🧘🏼", + "🧘🏽", + "🧘🏾", + "🧘🏿", + "🧘‍♂️", + "🧘‍♂", + "🧘🏻‍♂️", + "🧘🏻‍♂", + "🧘🏼‍♂️", + "🧘🏼‍♂", + "🧘🏽‍♂️", + "🧘🏽‍♂", + "🧘🏾‍♂️", + "🧘🏾‍♂", + "🧘🏿‍♂️", + "🧘🏿‍♂", + "🧘‍♀️", + "🧘‍♀", + "🧘🏻‍♀️", + "🧘🏻‍♀", + "🧘🏼‍♀️", + "🧘🏼‍♀", + "🧘🏽‍♀️", + "🧘🏽‍♀", + "🧘🏾‍♀️", + "🧘🏾‍♀", + "🧘🏿‍♀️", + "🧘🏿‍♀", + "🛀", + "🛀🏻", + "🛀🏼", + "🛀🏽", + "🛀🏾", + "🛀🏿", + "🛌", + "🛌🏻", + "🛌🏼", + "🛌🏽", + "🛌🏾", + "🛌🏿" + ], + "People & Body (family)": [ + "🧑‍🤝‍🧑", + "🧑🏻‍🤝‍🧑🏻", + "🧑🏻‍🤝‍🧑🏼", + "🧑🏻‍🤝‍🧑🏽", + "🧑🏻‍🤝‍🧑🏾", + "🧑🏻‍🤝‍🧑🏿", + "🧑🏼‍🤝‍🧑🏻", + "🧑🏼‍🤝‍🧑🏼", + "🧑🏼‍🤝‍🧑🏽", + "🧑🏼‍🤝‍🧑🏾", + "🧑🏼‍🤝‍🧑🏿", + "🧑🏽‍🤝‍🧑🏻", + "🧑🏽‍🤝‍🧑🏼", + "🧑🏽‍🤝‍🧑🏽", + "🧑🏽‍🤝‍🧑🏾", + "🧑🏽‍🤝‍🧑🏿", + "🧑🏾‍🤝‍🧑🏻", + "🧑🏾‍🤝‍🧑🏼", + "🧑🏾‍🤝‍🧑🏽", + "🧑🏾‍🤝‍🧑🏾", + "🧑🏾‍🤝‍🧑🏿", + "🧑🏿‍🤝‍🧑🏻", + "🧑🏿‍🤝‍🧑🏼", + "🧑🏿‍🤝‍🧑🏽", + "🧑🏿‍🤝‍🧑🏾", + "🧑🏿‍🤝‍🧑🏿", + "👭", + "👭🏻", + "👩🏻‍🤝‍👩🏼", + "👩🏻‍🤝‍👩🏽", + "👩🏻‍🤝‍👩🏾", + "👩🏻‍🤝‍👩🏿", + "👩🏼‍🤝‍👩🏻", + "👭🏼", + "👩🏼‍🤝‍👩🏽", + "👩🏼‍🤝‍👩🏾", + "👩🏼‍🤝‍👩🏿", + "👩🏽‍🤝‍👩🏻", + "👩🏽‍🤝‍👩🏼", + "👭🏽", + "👩🏽‍🤝‍👩🏾", + "👩🏽‍🤝‍👩🏿", + "👩🏾‍🤝‍👩🏻", + "👩🏾‍🤝‍👩🏼", + "👩🏾‍🤝‍👩🏽", + "👭🏾", + "👩🏾‍🤝‍👩🏿", + "👩🏿‍🤝‍👩🏻", + "👩🏿‍🤝‍👩🏼", + "👩🏿‍🤝‍👩🏽", + "👩🏿‍🤝‍👩🏾", + "👭🏿", + "👫", + "👫🏻", + "👩🏻‍🤝‍👨🏼", + "👩🏻‍🤝‍👨🏽", + "👩🏻‍🤝‍👨🏾", + "👩🏻‍🤝‍👨🏿", + "👩🏼‍🤝‍👨🏻", + "👫🏼", + "👩🏼‍🤝‍👨🏽", + "👩🏼‍🤝‍👨🏾", + "👩🏼‍🤝‍👨🏿", + "👩🏽‍🤝‍👨🏻", + "👩🏽‍🤝‍👨🏼", + "👫🏽", + "👩🏽‍🤝‍👨🏾", + "👩🏽‍🤝‍👨🏿", + "👩🏾‍🤝‍👨🏻", + "👩🏾‍🤝‍👨🏼", + "👩🏾‍🤝‍👨🏽", + "👫🏾", + "👩🏾‍🤝‍👨🏿", + "👩🏿‍🤝‍👨🏻", + "👩🏿‍🤝‍👨🏼", + "👩🏿‍🤝‍👨🏽", + "👩🏿‍🤝‍👨🏾", + "👫🏿", + "👬", + "👬🏻", + "👨🏻‍🤝‍👨🏼", + "👨🏻‍🤝‍👨🏽", + "👨🏻‍🤝‍👨🏾", + "👨🏻‍🤝‍👨🏿", + "👨🏼‍🤝‍👨🏻", + "👬🏼", + "👨🏼‍🤝‍👨🏽", + "👨🏼‍🤝‍👨🏾", + "👨🏼‍🤝‍👨🏿", + "👨🏽‍🤝‍👨🏻", + "👨🏽‍🤝‍👨🏼", + "👬🏽", + "👨🏽‍🤝‍👨🏾", + "👨🏽‍🤝‍👨🏿", + "👨🏾‍🤝‍👨🏻", + "👨🏾‍🤝‍👨🏼", + "👨🏾‍🤝‍👨🏽", + "👬🏾", + "👨🏾‍🤝‍👨🏿", + "👨🏿‍🤝‍👨🏻", + "👨🏿‍🤝‍👨🏼", + "👨🏿‍🤝‍👨🏽", + "👨🏿‍🤝‍👨🏾", + "👬🏿", + "💏", + "💏🏻", + "💏🏼", + "💏🏽", + "💏🏾", + "💏🏿", + "🧑🏻‍❤️‍💋‍🧑🏼", + "🧑🏻‍❤‍💋‍🧑🏼", + "🧑🏻‍❤️‍💋‍🧑🏽", + "🧑🏻‍❤‍💋‍🧑🏽", + "🧑🏻‍❤️‍💋‍🧑🏾", + "🧑🏻‍❤‍💋‍🧑🏾", + "🧑🏻‍❤️‍💋‍🧑🏿", + "🧑🏻‍❤‍💋‍🧑🏿", + "🧑🏼‍❤️‍💋‍🧑🏻", + "🧑🏼‍❤‍💋‍🧑🏻", + "🧑🏼‍❤️‍💋‍🧑🏽", + "🧑🏼‍❤‍💋‍🧑🏽", + "🧑🏼‍❤️‍💋‍🧑🏾", + "🧑🏼‍❤‍💋‍🧑🏾", + "🧑🏼‍❤️‍💋‍🧑🏿", + "🧑🏼‍❤‍💋‍🧑🏿", + "🧑🏽‍❤️‍💋‍🧑🏻", + "🧑🏽‍❤‍💋‍🧑🏻", + "🧑🏽‍❤️‍💋‍🧑🏼", + "🧑🏽‍❤‍💋‍🧑🏼", + "🧑🏽‍❤️‍💋‍🧑🏾", + "🧑🏽‍❤‍💋‍🧑🏾", + "🧑🏽‍❤️‍💋‍🧑🏿", + "🧑🏽‍❤‍💋‍🧑🏿", + "🧑🏾‍❤️‍💋‍🧑🏻", + "🧑🏾‍❤‍💋‍🧑🏻", + "🧑🏾‍❤️‍💋‍🧑🏼", + "🧑🏾‍❤‍💋‍🧑🏼", + "🧑🏾‍❤️‍💋‍🧑🏽", + "🧑🏾‍❤‍💋‍🧑🏽", + "🧑🏾‍❤️‍💋‍🧑🏿", + "🧑🏾‍❤‍💋‍🧑🏿", + "🧑🏿‍❤️‍💋‍🧑🏻", + "🧑🏿‍❤‍💋‍🧑🏻", + "🧑🏿‍❤️‍💋‍🧑🏼", + "🧑🏿‍❤‍💋‍🧑🏼", + "🧑🏿‍❤️‍💋‍🧑🏽", + "🧑🏿‍❤‍💋‍🧑🏽", + "🧑🏿‍❤️‍💋‍🧑🏾", + "🧑🏿‍❤‍💋‍🧑🏾", + "👩‍❤️‍💋‍👨", + "👩‍❤‍💋‍👨", + "👩🏻‍❤️‍💋‍👨🏻", + "👩🏻‍❤‍💋‍👨🏻", + "👩🏻‍❤️‍💋‍👨🏼", + "👩🏻‍❤‍💋‍👨🏼", + "👩🏻‍❤️‍💋‍👨🏽", + "👩🏻‍❤‍💋‍👨🏽", + "👩🏻‍❤️‍💋‍👨🏾", + "👩🏻‍❤‍💋‍👨🏾", + "👩🏻‍❤️‍💋‍👨🏿", + "👩🏻‍❤‍💋‍👨🏿", + "👩🏼‍❤️‍💋‍👨🏻", + "👩🏼‍❤‍💋‍👨🏻", + "👩🏼‍❤️‍💋‍👨🏼", + "👩🏼‍❤‍💋‍👨🏼", + "👩🏼‍❤️‍💋‍👨🏽", + "👩🏼‍❤‍💋‍👨🏽", + "👩🏼‍❤️‍💋‍👨🏾", + "👩🏼‍❤‍💋‍👨🏾", + "👩🏼‍❤️‍💋‍👨🏿", + "👩🏼‍❤‍💋‍👨🏿", + "👩🏽‍❤️‍💋‍👨🏻", + "👩🏽‍❤‍💋‍👨🏻", + "👩🏽‍❤️‍💋‍👨🏼", + "👩🏽‍❤‍💋‍👨🏼", + "👩🏽‍❤️‍💋‍👨🏽", + "👩🏽‍❤‍💋‍👨🏽", + "👩🏽‍❤️‍💋‍👨🏾", + "👩🏽‍❤‍💋‍👨🏾", + "👩🏽‍❤️‍💋‍👨🏿", + "👩🏽‍❤‍💋‍👨🏿", + "👩🏾‍❤️‍💋‍👨🏻", + "👩🏾‍❤‍💋‍👨🏻", + "👩🏾‍❤️‍💋‍👨🏼", + "👩🏾‍❤‍💋‍👨🏼", + "👩🏾‍❤️‍💋‍👨🏽", + "👩🏾‍❤‍💋‍👨🏽", + "👩🏾‍❤️‍💋‍👨🏾", + "👩🏾‍❤‍💋‍👨🏾", + "👩🏾‍❤️‍💋‍👨🏿", + "👩🏾‍❤‍💋‍👨🏿", + "👩🏿‍❤️‍💋‍👨🏻", + "👩🏿‍❤‍💋‍👨🏻", + "👩🏿‍❤️‍💋‍👨🏼", + "👩🏿‍❤‍💋‍👨🏼", + "👩🏿‍❤️‍💋‍👨🏽", + "👩🏿‍❤‍💋‍👨🏽", + "👩🏿‍❤️‍💋‍👨🏾", + "👩🏿‍❤‍💋‍👨🏾", + "👩🏿‍❤️‍💋‍👨🏿", + "👩🏿‍❤‍💋‍👨🏿", + "👨‍❤️‍💋‍👨", + "👨‍❤‍💋‍👨", + "👨🏻‍❤️‍💋‍👨🏻", + "👨🏻‍❤‍💋‍👨🏻", + "👨🏻‍❤️‍💋‍👨🏼", + "👨🏻‍❤‍💋‍👨🏼", + "👨🏻‍❤️‍💋‍👨🏽", + "👨🏻‍❤‍💋‍👨🏽", + "👨🏻‍❤️‍💋‍👨🏾", + "👨🏻‍❤‍💋‍👨🏾", + "👨🏻‍❤️‍💋‍👨🏿", + "👨🏻‍❤‍💋‍👨🏿", + "👨🏼‍❤️‍💋‍👨🏻", + "👨🏼‍❤‍💋‍👨🏻", + "👨🏼‍❤️‍💋‍👨🏼", + "👨🏼‍❤‍💋‍👨🏼", + "👨🏼‍❤️‍💋‍👨🏽", + "👨🏼‍❤‍💋‍👨🏽", + "👨🏼‍❤️‍💋‍👨🏾", + "👨🏼‍❤‍💋‍👨🏾", + "👨🏼‍❤️‍💋‍👨🏿", + "👨🏼‍❤‍💋‍👨🏿", + "👨🏽‍❤️‍💋‍👨🏻", + "👨🏽‍❤‍💋‍👨🏻", + "👨🏽‍❤️‍💋‍👨🏼", + "👨🏽‍❤‍💋‍👨🏼", + "👨🏽‍❤️‍💋‍👨🏽", + "👨🏽‍❤‍💋‍👨🏽", + "👨🏽‍❤️‍💋‍👨🏾", + "👨🏽‍❤‍💋‍👨🏾", + "👨🏽‍❤️‍💋‍👨🏿", + "👨🏽‍❤‍💋‍👨🏿", + "👨🏾‍❤️‍💋‍👨🏻", + "👨🏾‍❤‍💋‍👨🏻", + "👨🏾‍❤️‍💋‍👨🏼", + "👨🏾‍❤‍💋‍👨🏼", + "👨🏾‍❤️‍💋‍👨🏽", + "👨🏾‍❤‍💋‍👨🏽", + "👨🏾‍❤️‍💋‍👨🏾", + "👨🏾‍❤‍💋‍👨🏾", + "👨🏾‍❤️‍💋‍👨🏿", + "👨🏾‍❤‍💋‍👨🏿", + "👨🏿‍❤️‍💋‍👨🏻", + "👨🏿‍❤‍💋‍👨🏻", + "👨🏿‍❤️‍💋‍👨🏼", + "👨🏿‍❤‍💋‍👨🏼", + "👨🏿‍❤️‍💋‍👨🏽", + "👨🏿‍❤‍💋‍👨🏽", + "👨🏿‍❤️‍💋‍👨🏾", + "👨🏿‍❤‍💋‍👨🏾", + "👨🏿‍❤️‍💋‍👨🏿", + "👨🏿‍❤‍💋‍👨🏿", + "👩‍❤️‍💋‍👩", + "👩‍❤‍💋‍👩", + "👩🏻‍❤️‍💋‍👩🏻", + "👩🏻‍❤‍💋‍👩🏻", + "👩🏻‍❤️‍💋‍👩🏼", + "👩🏻‍❤‍💋‍👩🏼", + "👩🏻‍❤️‍💋‍👩🏽", + "👩🏻‍❤‍💋‍👩🏽", + "👩🏻‍❤️‍💋‍👩🏾", + "👩🏻‍❤‍💋‍👩🏾", + "👩🏻‍❤️‍💋‍👩🏿", + "👩🏻‍❤‍💋‍👩🏿", + "👩🏼‍❤️‍💋‍👩🏻", + "👩🏼‍❤‍💋‍👩🏻", + "👩🏼‍❤️‍💋‍👩🏼", + "👩🏼‍❤‍💋‍👩🏼", + "👩🏼‍❤️‍💋‍👩🏽", + "👩🏼‍❤‍💋‍👩🏽", + "👩🏼‍❤️‍💋‍👩🏾", + "👩🏼‍❤‍💋‍👩🏾", + "👩🏼‍❤️‍💋‍👩🏿", + "👩🏼‍❤‍💋‍👩🏿", + "👩🏽‍❤️‍💋‍👩🏻", + "👩🏽‍❤‍💋‍👩🏻", + "👩🏽‍❤️‍💋‍👩🏼", + "👩🏽‍❤‍💋‍👩🏼", + "👩🏽‍❤️‍💋‍👩🏽", + "👩🏽‍❤‍💋‍👩🏽", + "👩🏽‍❤️‍💋‍👩🏾", + "👩🏽‍❤‍💋‍👩🏾", + "👩🏽‍❤️‍💋‍👩🏿", + "👩🏽‍❤‍💋‍👩🏿", + "👩🏾‍❤️‍💋‍👩🏻", + "👩🏾‍❤‍💋‍👩🏻", + "👩🏾‍❤️‍💋‍👩🏼", + "👩🏾‍❤‍💋‍👩🏼", + "👩🏾‍❤️‍💋‍👩🏽", + "👩🏾‍❤‍💋‍👩🏽", + "👩🏾‍❤️‍💋‍👩🏾", + "👩🏾‍❤‍💋‍👩🏾", + "👩🏾‍❤️‍💋‍👩🏿", + "👩🏾‍❤‍💋‍👩🏿", + "👩🏿‍❤️‍💋‍👩🏻", + "👩🏿‍❤‍💋‍👩🏻", + "👩🏿‍❤️‍💋‍👩🏼", + "👩🏿‍❤‍💋‍👩🏼", + "👩🏿‍❤️‍💋‍👩🏽", + "👩🏿‍❤‍💋‍👩🏽", + "👩🏿‍❤️‍💋‍👩🏾", + "👩🏿‍❤‍💋‍👩🏾", + "👩🏿‍❤️‍💋‍👩🏿", + "👩🏿‍❤‍💋‍👩🏿", + "💑", + "💑🏻", + "💑🏼", + "💑🏽", + "💑🏾", + "💑🏿", + "🧑🏻‍❤️‍🧑🏼", + "🧑🏻‍❤‍🧑🏼", + "🧑🏻‍❤️‍🧑🏽", + "🧑🏻‍❤‍🧑🏽", + "🧑🏻‍❤️‍🧑🏾", + "🧑🏻‍❤‍🧑🏾", + "🧑🏻‍❤️‍🧑🏿", + "🧑🏻‍❤‍🧑🏿", + "🧑🏼‍❤️‍🧑🏻", + "🧑🏼‍❤‍🧑🏻", + "🧑🏼‍❤️‍🧑🏽", + "🧑🏼‍❤‍🧑🏽", + "🧑🏼‍❤️‍🧑🏾", + "🧑🏼‍❤‍🧑🏾", + "🧑🏼‍❤️‍🧑🏿", + "🧑🏼‍❤‍🧑🏿", + "🧑🏽‍❤️‍🧑🏻", + "🧑🏽‍❤‍🧑🏻", + "🧑🏽‍❤️‍🧑🏼", + "🧑🏽‍❤‍🧑🏼", + "🧑🏽‍❤️‍🧑🏾", + "🧑🏽‍❤‍🧑🏾", + "🧑🏽‍❤️‍🧑🏿", + "🧑🏽‍❤‍🧑🏿", + "🧑🏾‍❤️‍🧑🏻", + "🧑🏾‍❤‍🧑🏻", + "🧑🏾‍❤️‍🧑🏼", + "🧑🏾‍❤‍🧑🏼", + "🧑🏾‍❤️‍🧑🏽", + "🧑🏾‍❤‍🧑🏽", + "🧑🏾‍❤️‍🧑🏿", + "🧑🏾‍❤‍🧑🏿", + "🧑🏿‍❤️‍🧑🏻", + "🧑🏿‍❤‍🧑🏻", + "🧑🏿‍❤️‍🧑🏼", + "🧑🏿‍❤‍🧑🏼", + "🧑🏿‍❤️‍🧑🏽", + "🧑🏿‍❤‍🧑🏽", + "🧑🏿‍❤️‍🧑🏾", + "🧑🏿‍❤‍🧑🏾", + "👩‍❤️‍👨", + "👩‍❤‍👨", + "👩🏻‍❤️‍👨🏻", + "👩🏻‍❤‍👨🏻", + "👩🏻‍❤️‍👨🏼", + "👩🏻‍❤‍👨🏼", + "👩🏻‍❤️‍👨🏽", + "👩🏻‍❤‍👨🏽", + "👩🏻‍❤️‍👨🏾", + "👩🏻‍❤‍👨🏾", + "👩🏻‍❤️‍👨🏿", + "👩🏻‍❤‍👨🏿", + "👩🏼‍❤️‍👨🏻", + "👩🏼‍❤‍👨🏻", + "👩🏼‍❤️‍👨🏼", + "👩🏼‍❤‍👨🏼", + "👩🏼‍❤️‍👨🏽", + "👩🏼‍❤‍👨🏽", + "👩🏼‍❤️‍👨🏾", + "👩🏼‍❤‍👨🏾", + "👩🏼‍❤️‍👨🏿", + "👩🏼‍❤‍👨🏿", + "👩🏽‍❤️‍👨🏻", + "👩🏽‍❤‍👨🏻", + "👩🏽‍❤️‍👨🏼", + "👩🏽‍❤‍👨🏼", + "👩🏽‍❤️‍👨🏽", + "👩🏽‍❤‍👨🏽", + "👩🏽‍❤️‍👨🏾", + "👩🏽‍❤‍👨🏾", + "👩🏽‍❤️‍👨🏿", + "👩🏽‍❤‍👨🏿", + "👩🏾‍❤️‍👨🏻", + "👩🏾‍❤‍👨🏻", + "👩🏾‍❤️‍👨🏼", + "👩🏾‍❤‍👨🏼", + "👩🏾‍❤️‍👨🏽", + "👩🏾‍❤‍👨🏽", + "👩🏾‍❤️‍👨🏾", + "👩🏾‍❤‍👨🏾", + "👩🏾‍❤️‍👨🏿", + "👩🏾‍❤‍👨🏿", + "👩🏿‍❤️‍👨🏻", + "👩🏿‍❤‍👨🏻", + "👩🏿‍❤️‍👨🏼", + "👩🏿‍❤‍👨🏼", + "👩🏿‍❤️‍👨🏽", + "👩🏿‍❤‍👨🏽", + "👩🏿‍❤️‍👨🏾", + "👩🏿‍❤‍👨🏾", + "👩🏿‍❤️‍👨🏿", + "👩🏿‍❤‍👨🏿", + "👨‍❤️‍👨", + "👨‍❤‍👨", + "👨🏻‍❤️‍👨🏻", + "👨🏻‍❤‍👨🏻", + "👨🏻‍❤️‍👨🏼", + "👨🏻‍❤‍👨🏼", + "👨🏻‍❤️‍👨🏽", + "👨🏻‍❤‍👨🏽", + "👨🏻‍❤️‍👨🏾", + "👨🏻‍❤‍👨🏾", + "👨🏻‍❤️‍👨🏿", + "👨🏻‍❤‍👨🏿", + "👨🏼‍❤️‍👨🏻", + "👨🏼‍❤‍👨🏻", + "👨🏼‍❤️‍👨🏼", + "👨🏼‍❤‍👨🏼", + "👨🏼‍❤️‍👨🏽", + "👨🏼‍❤‍👨🏽", + "👨🏼‍❤️‍👨🏾", + "👨🏼‍❤‍👨🏾", + "👨🏼‍❤️‍👨🏿", + "👨🏼‍❤‍👨🏿", + "👨🏽‍❤️‍👨🏻", + "👨🏽‍❤‍👨🏻", + "👨🏽‍❤️‍👨🏼", + "👨🏽‍❤‍👨🏼", + "👨🏽‍❤️‍👨🏽", + "👨🏽‍❤‍👨🏽", + "👨🏽‍❤️‍👨🏾", + "👨🏽‍❤‍👨🏾", + "👨🏽‍❤️‍👨🏿", + "👨🏽‍❤‍👨🏿", + "👨🏾‍❤️‍👨🏻", + "👨🏾‍❤‍👨🏻", + "👨🏾‍❤️‍👨🏼", + "👨🏾‍❤‍👨🏼", + "👨🏾‍❤️‍👨🏽", + "👨🏾‍❤‍👨🏽", + "👨🏾‍❤️‍👨🏾", + "👨🏾‍❤‍👨🏾", + "👨🏾‍❤️‍👨🏿", + "👨🏾‍❤‍👨🏿", + "👨🏿‍❤️‍👨🏻", + "👨🏿‍❤‍👨🏻", + "👨🏿‍❤️‍👨🏼", + "👨🏿‍❤‍👨🏼", + "👨🏿‍❤️‍👨🏽", + "👨🏿‍❤‍👨🏽", + "👨🏿‍❤️‍👨🏾", + "👨🏿‍❤‍👨🏾", + "👨🏿‍❤️‍👨🏿", + "👨🏿‍❤‍👨🏿", + "👩‍❤️‍👩", + "👩‍❤‍👩", + "👩🏻‍❤️‍👩🏻", + "👩🏻‍❤‍👩🏻", + "👩🏻‍❤️‍👩🏼", + "👩🏻‍❤‍👩🏼", + "👩🏻‍❤️‍👩🏽", + "👩🏻‍❤‍👩🏽", + "👩🏻‍❤️‍👩🏾", + "👩🏻‍❤‍👩🏾", + "👩🏻‍❤️‍👩🏿", + "👩🏻‍❤‍👩🏿", + "👩🏼‍❤️‍👩🏻", + "👩🏼‍❤‍👩🏻", + "👩🏼‍❤️‍👩🏼", + "👩🏼‍❤‍👩🏼", + "👩🏼‍❤️‍👩🏽", + "👩🏼‍❤‍👩🏽", + "👩🏼‍❤️‍👩🏾", + "👩🏼‍❤‍👩🏾", + "👩🏼‍❤️‍👩🏿", + "👩🏼‍❤‍👩🏿", + "👩🏽‍❤️‍👩🏻", + "👩🏽‍❤‍👩🏻", + "👩🏽‍❤️‍👩🏼", + "👩🏽‍❤‍👩🏼", + "👩🏽‍❤️‍👩🏽", + "👩🏽‍❤‍👩🏽", + "👩🏽‍❤️‍👩🏾", + "👩🏽‍❤‍👩🏾", + "👩🏽‍❤️‍👩🏿", + "👩🏽‍❤‍👩🏿", + "👩🏾‍❤️‍👩🏻", + "👩🏾‍❤‍👩🏻", + "👩🏾‍❤️‍👩🏼", + "👩🏾‍❤‍👩🏼", + "👩🏾‍❤️‍👩🏽", + "👩🏾‍❤‍👩🏽", + "👩🏾‍❤️‍👩🏾", + "👩🏾‍❤‍👩🏾", + "👩🏾‍❤️‍👩🏿", + "👩🏾‍❤‍👩🏿", + "👩🏿‍❤️‍👩🏻", + "👩🏿‍❤‍👩🏻", + "👩🏿‍❤️‍👩🏼", + "👩🏿‍❤‍👩🏼", + "👩🏿‍❤️‍👩🏽", + "👩🏿‍❤‍👩🏽", + "👩🏿‍❤️‍👩🏾", + "👩🏿‍❤‍👩🏾", + "👩🏿‍❤️‍👩🏿", + "👩🏿‍❤‍👩🏿", + "👪", + "👨‍👩‍👦", + "👨‍👩‍👧", + "👨‍👩‍👧‍👦", + "👨‍👩‍👦‍👦", + "👨‍👩‍👧‍👧", + "👨‍👨‍👦", + "👨‍👨‍👧", + "👨‍👨‍👧‍👦", + "👨‍👨‍👦‍👦", + "👨‍👨‍👧‍👧", + "👩‍👩‍👦", + "👩‍👩‍👧", + "👩‍👩‍👧‍👦", + "👩‍👩‍👦‍👦", + "👩‍👩‍👧‍👧", + "👨‍👦", + "👨‍👦‍👦", + "👨‍👧", + "👨‍👧‍👦", + "👨‍👧‍👧", + "👩‍👦", + "👩‍👦‍👦", + "👩‍👧", + "👩‍👧‍👦", + "👩‍👧‍👧" + ], + "People & Body (person-symbol)": [ + "🗣️", + "🗣", + "👤", + "👥", + "🫂", + "👣" + ], + "Component (skin-tone)": [ + "🏻", + "🏼", + "🏽", + "🏾", + "🏿" + ], + "Component (hair-style)": [ + "🦰", + "🦱", + "🦳", + "🦲" + ], + "Animals & Nature (animal-mammal)": [ + "🐵", + "🐒", + "🦍", + "🦧", + "🐶", + "🐕", + "🦮", + "🐕‍🦺", + "🐩", + "🐺", + "🦊", + "🦝", + "🐱", + "🐈", + "🐈‍⬛", + "🦁", + "🐯", + "🐅", + "🐆", + "🐴", + "🐎", + "🦄", + "🦓", + "🦌", + "🦬", + "🐮", + "🐂", + "🐃", + "🐄", + "🐷", + "🐖", + "🐗", + "🐽", + "🐏", + "🐑", + "🐐", + "🐪", + "🐫", + "🦙", + "🦒", + "🐘", + "🦣", + "🦏", + "🦛", + "🐭", + "🐁", + "🐀", + "🐹", + "🐰", + "🐇", + "🐿️", + "🐿", + "🦫", + "🦔", + "🦇", + "🐻", + "🐻‍❄️", + "🐻‍❄", + "🐨", + "🐼", + "🦥", + "🦦", + "🦨", + "🦘", + "🦡", + "🐾" + ], + "Animals & Nature (animal-bird)": [ + "🦃", + "🐔", + "🐓", + "🐣", + "🐤", + "🐥", + "🐦", + "🐧", + "🕊️", + "🕊", + "🦅", + "🦆", + "🦢", + "🦉", + "🦤", + "🪶", + "🦩", + "🦚", + "🦜" + ], + "Animals & Nature (animal-amphibian)": [ + "🐸" + ], + "Animals & Nature (animal-reptile)": [ + "🐊", + "🐢", + "🦎", + "🐍", + "🐲", + "🐉", + "🦕", + "🦖" + ], + "Animals & Nature (animal-marine)": [ + "🐳", + "🐋", + "🐬", + "🦭", + "🐟", + "🐠", + "🐡", + "🦈", + "🐙", + "🐚" + ], + "Animals & Nature (animal-bug)": [ + "🐌", + "🦋", + "🐛", + "🐜", + "🐝", + "🪲", + "🐞", + "🦗", + "🪳", + "🕷️", + "🕷", + "🕸️", + "🕸", + "🦂", + "🦟", + "🪰", + "🪱", + "🦠" + ], + "Animals & Nature (plant-flower)": [ + "💐", + "🌸", + "💮", + "🏵️", + "🏵", + "🌹", + "🥀", + "🌺", + "🌻", + "🌼", + "🌷" + ], + "Animals & Nature (plant-other)": [ + "🌱", + "🪴", + "🌲", + "🌳", + "🌴", + "🌵", + "🌾", + "🌿", + "☘️", + "☘", + "🍀", + "🍁", + "🍂", + "🍃" + ], + "Food & Drink (food-fruit)": [ + "🍇", + "🍈", + "🍉", + "🍊", + "🍋", + "🍌", + "🍍", + "🥭", + "🍎", + "🍏", + "🍐", + "🍑", + "🍒", + "🍓", + "🫐", + "🥝", + "🍅", + "🫒", + "🥥" + ], + "Food & Drink (food-vegetable)": [ + "🥑", + "🍆", + "🥔", + "🥕", + "🌽", + "🌶️", + "🌶", + "🫑", + "🥒", + "🥬", + "🥦", + "🧄", + "🧅", + "🍄", + "🥜", + "🌰" + ], + "Food & Drink (food-prepared)": [ + "🍞", + "🥐", + "🥖", + "🫓", + "🥨", + "🥯", + "🥞", + "🧇", + "🧀", + "🍖", + "🍗", + "🥩", + "🥓", + "🍔", + "🍟", + "🍕", + "🌭", + "🥪", + "🌮", + "🌯", + "🫔", + "🥙", + "🧆", + "🥚", + "🍳", + "🥘", + "🍲", + "🫕", + "🥣", + "🥗", + "🍿", + "🧈", + "🧂", + "🥫" + ], + "Food & Drink (food-asian)": [ + "🍱", + "🍘", + "🍙", + "🍚", + "🍛", + "🍜", + "🍝", + "🍠", + "🍢", + "🍣", + "🍤", + "🍥", + "🥮", + "🍡", + "🥟", + "🥠", + "🥡" + ], + "Food & Drink (food-marine)": [ + "🦀", + "🦞", + "🦐", + "🦑", + "🦪" + ], + "Food & Drink (food-sweet)": [ + "🍦", + "🍧", + "🍨", + "🍩", + "🍪", + "🎂", + "🍰", + "🧁", + "🥧", + "🍫", + "🍬", + "🍭", + "🍮", + "🍯" + ], + "Food & Drink (drink)": [ + "🍼", + "🥛", + "☕", + "🫖", + "🍵", + "🍶", + "🍾", + "🍷", + "🍸", + "🍹", + "🍺", + "🍻", + "🥂", + "🥃", + "🥤", + "🧋", + "🧃", + "🧉", + "🧊" + ], + "Food & Drink (dishware)": [ + "🥢", + "🍽️", + "🍽", + "🍴", + "🥄", + "🔪", + "🏺" + ], + "Travel & Places (place-map)": [ + "🌍", + "🌎", + "🌏", + "🌐", + "🗺️", + "🗺", + "🗾", + "🧭" + ], + "Travel & Places (place-geographic)": [ + "🏔️", + "🏔", + "⛰️", + "⛰", + "🌋", + "🗻", + "🏕️", + "🏕", + "🏖️", + "🏖", + "🏜️", + "🏜", + "🏝️", + "🏝", + "🏞️", + "🏞" + ], + "Travel & Places (place-building)": [ + "🏟️", + "🏟", + "🏛️", + "🏛", + "🏗️", + "🏗", + "🧱", + "🪨", + "🪵", + "🛖", + "🏘️", + "🏘", + "🏚️", + "🏚", + "🏠", + "🏡", + "🏢", + "🏣", + "🏤", + "🏥", + "🏦", + "🏨", + "🏩", + "🏪", + "🏫", + "🏬", + "🏭", + "🏯", + "🏰", + "💒", + "🗼", + "🗽" + ], + "Travel & Places (place-religious)": [ + "⛪", + "🕌", + "🛕", + "🕍", + "⛩️", + "⛩", + "🕋" + ], + "Travel & Places (place-other)": [ + "⛲", + "⛺", + "🌁", + "🌃", + "🏙️", + "🏙", + "🌄", + "🌅", + "🌆", + "🌇", + "🌉", + "♨️", + "♨", + "🎠", + "🎡", + "🎢", + "💈", + "🎪" + ], + "Travel & Places (transport-ground)": [ + "🚂", + "🚃", + "🚄", + "🚅", + "🚆", + "🚇", + "🚈", + "🚉", + "🚊", + "🚝", + "🚞", + "🚋", + "🚌", + "🚍", + "🚎", + "🚐", + "🚑", + "🚒", + "🚓", + "🚔", + "🚕", + "🚖", + "🚗", + "🚘", + "🚙", + "🛻", + "🚚", + "🚛", + "🚜", + "🏎️", + "🏎", + "🏍️", + "🏍", + "🛵", + "🦽", + "🦼", + "🛺", + "🚲", + "🛴", + "🛹", + "🛼", + "🚏", + "🛣️", + "🛣", + "🛤️", + "🛤", + "🛢️", + "🛢", + "⛽", + "🚨", + "🚥", + "🚦", + "🛑", + "🚧" + ], + "Travel & Places (transport-water)": [ + "⚓", + "⛵", + "🛶", + "🚤", + "🛳️", + "🛳", + "⛴️", + "⛴", + "🛥️", + "🛥", + "🚢" + ], + "Travel & Places (transport-air)": [ + "✈️", + "✈", + "🛩️", + "🛩", + "🛫", + "🛬", + "🪂", + "💺", + "🚁", + "🚟", + "🚠", + "🚡", + "🛰️", + "🛰", + "🚀", + "🛸" + ], + "Travel & Places (hotel)": [ + "🛎️", + "🛎", + "🧳" + ], + "Travel & Places (time)": [ + "⌛", + "⏳", + "⌚", + "⏰", + "⏱️", + "⏱", + "⏲️", + "⏲", + "🕰️", + "🕰", + "🕛", + "🕧", + "🕐", + "🕜", + "🕑", + "🕝", + "🕒", + "🕞", + "🕓", + "🕟", + "🕔", + "🕠", + "🕕", + "🕡", + "🕖", + "🕢", + "🕗", + "🕣", + "🕘", + "🕤", + "🕙", + "🕥", + "🕚", + "🕦" + ], + "Travel & Places (sky & weather)": [ + "🌑", + "🌒", + "🌓", + "🌔", + "🌕", + "🌖", + "🌗", + "🌘", + "🌙", + "🌚", + "🌛", + "🌜", + "🌡️", + "🌡", + "☀️", + "☀", + "🌝", + "🌞", + "🪐", + "⭐", + "🌟", + "🌠", + "🌌", + "☁️", + "☁", + "⛅", + "⛈️", + "⛈", + "🌤️", + "🌤", + "🌥️", + "🌥", + "🌦️", + "🌦", + "🌧️", + "🌧", + "🌨️", + "🌨", + "🌩️", + "🌩", + "🌪️", + "🌪", + "🌫️", + "🌫", + "🌬️", + "🌬", + "🌀", + "🌈", + "🌂", + "☂️", + "☂", + "☔", + "⛱️", + "⛱", + "⚡", + "❄️", + "❄", + "☃️", + "☃", + "⛄", + "☄️", + "☄", + "🔥", + "💧", + "🌊" + ], + "Activities (event)": [ + "🎃", + "🎄", + "🎆", + "🎇", + "🧨", + "✨", + "🎈", + "🎉", + "🎊", + "🎋", + "🎍", + "🎎", + "🎏", + "🎐", + "🎑", + "🧧", + "🎀", + "🎁", + "🎗️", + "🎗", + "🎟️", + "🎟", + "🎫" + ], + "Activities (award-medal)": [ + "🎖️", + "🎖", + "🏆", + "🏅", + "🥇", + "🥈", + "🥉" + ], + "Activities (sport)": [ + "⚽", + "⚾", + "🥎", + "🏀", + "🏐", + "🏈", + "🏉", + "🎾", + "🥏", + "🎳", + "🏏", + "🏑", + "🏒", + "🥍", + "🏓", + "🏸", + "🥊", + "🥋", + "🥅", + "⛳", + "⛸️", + "⛸", + "🎣", + "🤿", + "🎽", + "🎿", + "🛷", + "🥌" + ], + "Activities (game)": [ + "🎯", + "🪀", + "🪁", + "🎱", + "🔮", + "🪄", + "🧿", + "🎮", + "🕹️", + "🕹", + "🎰", + "🎲", + "🧩", + "🧸", + "🪅", + "🪆", + "♠️", + "♠", + "♥️", + "♥", + "♦️", + "♦", + "♣️", + "♣", + "♟️", + "♟", + "🃏", + "🀄", + "🎴" + ], + "Activities (arts & crafts)": [ + "🎭", + "🖼️", + "🖼", + "🎨", + "🧵", + "🪡", + "🧶", + "🪢" + ], + "Objects (clothing)": [ + "👓", + "🕶️", + "🕶", + "🥽", + "🥼", + "🦺", + "👔", + "👕", + "👖", + "🧣", + "🧤", + "🧥", + "🧦", + "👗", + "👘", + "🥻", + "🩱", + "🩲", + "🩳", + "👙", + "👚", + "👛", + "👜", + "👝", + "🛍️", + "🛍", + "🎒", + "🩴", + "👞", + "👟", + "🥾", + "🥿", + "👠", + "👡", + "🩰", + "👢", + "👑", + "👒", + "🎩", + "🎓", + "🧢", + "🪖", + "⛑️", + "⛑", + "📿", + "💄", + "💍", + "💎" + ], + "Objects (sound)": [ + "🔇", + "🔈", + "🔉", + "🔊", + "📢", + "📣", + "📯", + "🔔", + "🔕" + ], + "Objects (music)": [ + "🎼", + "🎵", + "🎶", + "🎙️", + "🎙", + "🎚️", + "🎚", + "🎛️", + "🎛", + "🎤", + "🎧", + "📻" + ], + "Objects (musical-instrument)": [ + "🎷", + "🪗", + "🎸", + "🎹", + "🎺", + "🎻", + "🪕", + "🥁", + "🪘" + ], + "Objects (phone)": [ + "📱", + "📲", + "☎️", + "☎", + "📞", + "📟", + "📠" + ], + "Objects (computer)": [ + "🔋", + "🔌", + "💻", + "🖥️", + "🖥", + "🖨️", + "🖨", + "⌨️", + "⌨", + "🖱️", + "🖱", + "🖲️", + "🖲", + "💽", + "💾", + "💿", + "📀", + "🧮" + ], + "Objects (light & video)": [ + "🎥", + "🎞️", + "🎞", + "📽️", + "📽", + "🎬", + "📺", + "📷", + "📸", + "📹", + "📼", + "🔍", + "🔎", + "🕯️", + "🕯", + "💡", + "🔦", + "🏮", + "🪔" + ], + "Objects (book-paper)": [ + "📔", + "📕", + "📖", + "📗", + "📘", + "📙", + "📚", + "📓", + "📒", + "📃", + "📜", + "📄", + "📰", + "🗞️", + "🗞", + "📑", + "🔖", + "🏷️", + "🏷" + ], + "Objects (money)": [ + "💰", + "🪙", + "💴", + "💵", + "💶", + "💷", + "💸", + "💳", + "🧾", + "💹" + ], + "Objects (mail)": [ + "✉️", + "✉", + "📧", + "📨", + "📩", + "📤", + "📥", + "📦", + "📫", + "📪", + "📬", + "📭", + "📮", + "🗳️", + "🗳" + ], + "Objects (writing)": [ + "✏️", + "✏", + "✒️", + "✒", + "🖋️", + "🖋", + "🖊️", + "🖊", + "🖌️", + "🖌", + "🖍️", + "🖍", + "📝" + ], + "Objects (office)": [ + "💼", + "📁", + "📂", + "🗂️", + "🗂", + "📅", + "📆", + "🗒️", + "🗒", + "🗓️", + "🗓", + "📇", + "📈", + "📉", + "📊", + "📋", + "📌", + "📍", + "📎", + "🖇️", + "🖇", + "📏", + "📐", + "✂️", + "✂", + "🗃️", + "🗃", + "🗄️", + "🗄", + "🗑️", + "🗑" + ], + "Objects (lock)": [ + "🔒", + "🔓", + "🔏", + "🔐", + "🔑", + "🗝️", + "🗝" + ], + "Objects (tool)": [ + "🔨", + "🪓", + "⛏️", + "⛏", + "⚒️", + "⚒", + "🛠️", + "🛠", + "🗡️", + "🗡", + "⚔️", + "⚔", + "🔫", + "🪃", + "🏹", + "🛡️", + "🛡", + "🪚", + "🔧", + "🪛", + "🔩", + "⚙️", + "⚙", + "🗜️", + "🗜", + "⚖️", + "⚖", + "🦯", + "🔗", + "⛓️", + "⛓", + "🪝", + "🧰", + "🧲", + "🪜" + ], + "Objects (science)": [ + "⚗️", + "⚗", + "🧪", + "🧫", + "🧬", + "🔬", + "🔭", + "📡" + ], + "Objects (medical)": [ + "💉", + "🩸", + "💊", + "🩹", + "🩺" + ], + "Objects (household)": [ + "🚪", + "🛗", + "🪞", + "🪟", + "🛏️", + "🛏", + "🛋️", + "🛋", + "🪑", + "🚽", + "🪠", + "🚿", + "🛁", + "🪤", + "🪒", + "🧴", + "🧷", + "🧹", + "🧺", + "🧻", + "🪣", + "🧼", + "🪥", + "🧽", + "🧯", + "🛒" + ], + "Objects (other-object)": [ + "🚬", + "⚰️", + "⚰", + "🪦", + "⚱️", + "⚱", + "🗿", + "🪧" + ], + "Symbols (transport-sign)": [ + "🏧", + "🚮", + "🚰", + "♿", + "🚹", + "🚺", + "🚻", + "🚼", + "🚾", + "🛂", + "🛃", + "🛄", + "🛅" + ], + "Symbols (warning)": [ + "⚠️", + "⚠", + "🚸", + "⛔", + "🚫", + "🚳", + "🚭", + "🚯", + "🚱", + "🚷", + "📵", + "🔞", + "☢️", + "☢", + "☣️", + "☣" + ], + "Symbols (arrow)": [ + "⬆️", + "⬆", + "↗️", + "↗", + "➡️", + "➡", + "↘️", + "↘", + "⬇️", + "⬇", + "↙️", + "↙", + "⬅️", + "⬅", + "↖️", + "↖", + "↕️", + "↕", + "↔️", + "↔", + "↩️", + "↩", + "↪️", + "↪", + "⤴️", + "⤴", + "⤵️", + "⤵", + "🔃", + "🔄", + "🔙", + "🔚", + "🔛", + "🔜", + "🔝" + ], + "Symbols (religion)": [ + "🛐", + "⚛️", + "⚛", + "🕉️", + "🕉", + "✡️", + "✡", + "☸️", + "☸", + "☯️", + "☯", + "✝️", + "✝", + "☦️", + "☦", + "☪️", + "☪", + "☮️", + "☮", + "🕎", + "🔯" + ], + "Symbols (zodiac)": [ + "♈", + "♉", + "♊", + "♋", + "♌", + "♍", + "♎", + "♏", + "♐", + "♑", + "♒", + "♓", + "⛎" + ], + "Symbols (av-symbol)": [ + "🔀", + "🔁", + "🔂", + "▶️", + "▶", + "⏩", + "⏭️", + "⏭", + "⏯️", + "⏯", + "◀️", + "◀", + "⏪", + "⏮️", + "⏮", + "🔼", + "⏫", + "🔽", + "⏬", + "⏸️", + "⏸", + "⏹️", + "⏹", + "⏺️", + "⏺", + "⏏️", + "⏏", + "🎦", + "🔅", + "🔆", + "📶", + "📳", + "📴" + ], + "Symbols (gender)": [ + "♀️", + "♀", + "♂️", + "♂", + "⚧️", + "⚧" + ], + "Symbols (math)": [ + "✖️", + "✖", + "➕", + "➖", + "➗", + "♾️", + "♾" + ], + "Symbols (punctuation)": [ + "‼️", + "‼", + "⁉️", + "⁉", + "❓", + "❔", + "❕", + "❗", + "〰️", + "〰" + ], + "Symbols (currency)": [ + "💱", + "💲" + ], + "Symbols (other-symbol)": [ + "⚕️", + "⚕", + "♻️", + "♻", + "⚜️", + "⚜", + "🔱", + "📛", + "🔰", + "⭕", + "✅", + "☑️", + "☑", + "✔️", + "✔", + "❌", + "❎", + "➰", + "➿", + "〽️", + "〽", + "✳️", + "✳", + "✴️", + "✴", + "❇️", + "❇", + "©️", + "©", + "®️", + "®", + "™️", + "™" + ], + "Symbols (keycap)": [ + "#️⃣", + "#⃣", + "*️⃣", + "*⃣", + "0️⃣", + "0⃣", + "1️⃣", + "1⃣", + "2️⃣", + "2⃣", + "3️⃣", + "3⃣", + "4️⃣", + "4⃣", + "5️⃣", + "5⃣", + "6️⃣", + "6⃣", + "7️⃣", + "7⃣", + "8️⃣", + "8⃣", + "9️⃣", + "9⃣", + "🔟" + ], + "Symbols (alphanum)": [ + "🔠", + "🔡", + "🔢", + "🔣", + "🔤", + "🅰️", + "🅰", + "🆎", + "🅱️", + "🅱", + "🆑", + "🆒", + "🆓", + "ℹ️", + "ℹ", + "🆔", + "Ⓜ️", + "Ⓜ", + "🆕", + "🆖", + "🅾️", + "🅾", + "🆗", + "🅿️", + "🅿", + "🆘", + "🆙", + "🆚", + "🈁", + "🈂️", + "🈂", + "🈷️", + "🈷", + "🈶", + "🈯", + "🉐", + "🈹", + "🈚", + "🈲", + "🉑", + "🈸", + "🈴", + "🈳", + "㊗️", + "㊗", + "㊙️", + "㊙", + "🈺", + "🈵" + ], + "Symbols (geometric)": [ + "🔴", + "🟠", + "🟡", + "🟢", + "🔵", + "🟣", + "🟤", + "⚫", + "⚪", + "🟥", + "🟧", + "🟨", + "🟩", + "🟦", + "🟪", + "🟫", + "⬛", + "⬜", + "◼️", + "◼", + "◻️", + "◻", + "◾", + "◽", + "▪️", + "▪", + "▫️", + "▫", + "🔶", + "🔷", + "🔸", + "🔹", + "🔺", + "🔻", + "💠", + "🔘", + "🔳", + "🔲" + ], + "Flags (flag)": [ + "🏁", + "🚩", + "🎌", + "🏴", + "🏳️", + "🏳", + "🏳️‍🌈", + "🏳‍🌈", + "🏳️‍⚧️", + "🏳‍⚧️", + "🏳️‍⚧", + "🏳‍⚧", + "🏴‍☠️", + "🏴‍☠" + ], + "Flags (country-flag)": [ + "🇦🇨", + "🇦🇩", + "🇦🇪", + "🇦🇫", + "🇦🇬", + "🇦🇮", + "🇦🇱", + "🇦🇲", + "🇦🇴", + "🇦🇶", + "🇦🇷", + "🇦🇸", + "🇦🇹", + "🇦🇺", + "🇦🇼", + "🇦🇽", + "🇦🇿", + "🇧🇦", + "🇧🇧", + "🇧🇩", + "🇧🇪", + "🇧🇫", + "🇧🇬", + "🇧🇭", + "🇧🇮", + "🇧🇯", + "🇧🇱", + "🇧🇲", + "🇧🇳", + "🇧🇴", + "🇧🇶", + "🇧🇷", + "🇧🇸", + "🇧🇹", + "🇧🇻", + "🇧🇼", + "🇧🇾", + "🇧🇿", + "🇨🇦", + "🇨🇨", + "🇨🇩", + "🇨🇫", + "🇨🇬", + "🇨🇭", + "🇨🇮", + "🇨🇰", + "🇨🇱", + "🇨🇲", + "🇨🇳", + "🇨🇴", + "🇨🇵", + "🇨🇷", + "🇨🇺", + "🇨🇻", + "🇨🇼", + "🇨🇽", + "🇨🇾", + "🇨🇿", + "🇩🇪", + "🇩🇬", + "🇩🇯", + "🇩🇰", + "🇩🇲", + "🇩🇴", + "🇩🇿", + "🇪🇦", + "🇪🇨", + "🇪🇪", + "🇪🇬", + "🇪🇭", + "🇪🇷", + "🇪🇸", + "🇪🇹", + "🇪🇺", + "🇫🇮", + "🇫🇯", + "🇫🇰", + "🇫🇲", + "🇫🇴", + "🇫🇷", + "🇬🇦", + "🇬🇧", + "🇬🇩", + "🇬🇪", + "🇬🇫", + "🇬🇬", + "🇬🇭", + "🇬🇮", + "🇬🇱", + "🇬🇲", + "🇬🇳", + "🇬🇵", + "🇬🇶", + "🇬🇷", + "🇬🇸", + "🇬🇹", + "🇬🇺", + "🇬🇼", + "🇬🇾", + "🇭🇰", + "🇭🇲", + "🇭🇳", + "🇭🇷", + "🇭🇹", + "🇭🇺", + "🇮🇨", + "🇮🇩", + "🇮🇪", + "🇮🇱", + "🇮🇲", + "🇮🇳", + "🇮🇴", + "🇮🇶", + "🇮🇷", + "🇮🇸", + "🇮🇹", + "🇯🇪", + "🇯🇲", + "🇯🇴", + "🇯🇵", + "🇰🇪", + "🇰🇬", + "🇰🇭", + "🇰🇮", + "🇰🇲", + "🇰🇳", + "🇰🇵", + "🇰🇷", + "🇰🇼", + "🇰🇾", + "🇰🇿", + "🇱🇦", + "🇱🇧", + "🇱🇨", + "🇱🇮", + "🇱🇰", + "🇱🇷", + "🇱🇸", + "🇱🇹", + "🇱🇺", + "🇱🇻", + "🇱🇾", + "🇲🇦", + "🇲🇨", + "🇲🇩", + "🇲🇪", + "🇲🇫", + "🇲🇬", + "🇲🇭", + "🇲🇰", + "🇲🇱", + "🇲🇲", + "🇲🇳", + "🇲🇴", + "🇲🇵", + "🇲🇶", + "🇲🇷", + "🇲🇸", + "🇲🇹", + "🇲🇺", + "🇲🇻", + "🇲🇼", + "🇲🇽", + "🇲🇾", + "🇲🇿", + "🇳🇦", + "🇳🇨", + "🇳🇪", + "🇳🇫", + "🇳🇬", + "🇳🇮", + "🇳🇱", + "🇳🇴", + "🇳🇵", + "🇳🇷", + "🇳🇺", + "🇳🇿", + "🇴🇲", + "🇵🇦", + "🇵🇪", + "🇵🇫", + "🇵🇬", + "🇵🇭", + "🇵🇰", + "🇵🇱", + "🇵🇲", + "🇵🇳", + "🇵🇷", + "🇵🇸", + "🇵🇹", + "🇵🇼", + "🇵🇾", + "🇶🇦", + "🇷🇪", + "🇷🇴", + "🇷🇸", + "🇷🇺", + "🇷🇼", + "🇸🇦", + "🇸🇧", + "🇸🇨", + "🇸🇩", + "🇸🇪", + "🇸🇬", + "🇸🇭", + "🇸🇮", + "🇸🇯", + "🇸🇰", + "🇸🇱", + "🇸🇲", + "🇸🇳", + "🇸🇴", + "🇸🇷", + "🇸🇸", + "🇸🇹", + "🇸🇻", + "🇸🇽", + "🇸🇾", + "🇸🇿", + "🇹🇦", + "🇹🇨", + "🇹🇩", + "🇹🇫", + "🇹🇬", + "🇹🇭", + "🇹🇯", + "🇹🇰", + "🇹🇱", + "🇹🇲", + "🇹🇳", + "🇹🇴", + "🇹🇷", + "🇹🇹", + "🇹🇻", + "🇹🇼", + "🇹🇿", + "🇺🇦", + "🇺🇬", + "🇺🇲", + "🇺🇳", + "🇺🇸", + "🇺🇾", + "🇺🇿", + "🇻🇦", + "🇻🇨", + "🇻🇪", + "🇻🇬", + "🇻🇮", + "🇻🇳", + "🇻🇺", + "🇼🇫", + "🇼🇸", + "🇽🇰", + "🇾🇪", + "🇾🇹", + "🇿🇦", + "🇿🇲", + "🇿🇼" + ], + "Flags (subdivision-flag)": [ + "🏴󠁧󠁢󠁥󠁮󠁧󠁿", + "🏴󠁧󠁢󠁳󠁣󠁴󠁿", + "🏴󠁧󠁢󠁷󠁬󠁳󠁿" + ] +} \ No newline at end of file diff --git a/packages/client/src/components/emoji-picker/index.module.scss b/packages/client/src/components/emoji-picker/index.module.scss new file mode 100644 index 0000000..03791d8 --- /dev/null +++ b/packages/client/src/components/emoji-picker/index.module.scss @@ -0,0 +1,19 @@ +.listWrap { + display: flex; + padding: 0; + margin: 0; + overflow: auto; + list-style: none; + flex-wrap: wrap; + + > div { + display: flex; + justify-content: center; + align-items: center; + width: 32px; + height: 32px; + padding: 4px; + font-size: 24px; + cursor: pointer; + } +} diff --git a/packages/client/src/components/emoji-picker/index.tsx b/packages/client/src/components/emoji-picker/index.tsx new file mode 100644 index 0000000..473be36 --- /dev/null +++ b/packages/client/src/components/emoji-picker/index.tsx @@ -0,0 +1,148 @@ +import React, { useCallback, useEffect, useMemo, useState } from 'react'; + +import { Button, Popover, SideSheet, TabPane, Tabs } from '@douyinfe/semi-ui'; + +import { createKeysLocalStorageLRUCache } from 'helpers/lru-cache'; +import { IsOnMobile } from 'hooks/use-on-mobile'; +import { useToggle } from 'hooks/use-toggle'; + +import { ACTIVITIES, EXPRESSIONES, GESTURES, OBJECTS, SKY_WEATHER, SYMBOLS } from './constants'; + +import styles from './index.module.scss'; + +const emojiLocalStorageLRUCache = createKeysLocalStorageLRUCache('EMOJI_PICKER', 20); + +const LIST = [ + { + title: '表情', + data: EXPRESSIONES, + }, + { + title: '天气', + data: SKY_WEATHER, + }, + { + title: '手势', + data: GESTURES, + }, + { + title: '符号', + data: SYMBOLS, + }, + { + title: '物体', + data: OBJECTS, + }, + { + title: '运动', + data: ACTIVITIES, + }, +]; + +interface IProps { + showClear?: boolean; + onSelectEmoji: (arg: string) => void; +} + +export const EmojiPicker: React.FC = ({ showClear = false, onSelectEmoji, children }) => { + const { isMobile } = IsOnMobile.useHook(); + const [recentUsed, setRecentUsed] = useState([]); + const [visible, toggleVisible] = useToggle(false); + const renderedList = useMemo( + () => (recentUsed.length ? [{ title: '最近使用', data: recentUsed }, ...LIST] : LIST), + [recentUsed] + ); + + const selectEmoji = useCallback( + (emoji) => { + emojiLocalStorageLRUCache.put(emoji); + setRecentUsed(emojiLocalStorageLRUCache.get() as string[]); + onSelectEmoji && onSelectEmoji(emoji); + }, + [onSelectEmoji] + ); + + const clear = useCallback(() => { + onSelectEmoji(''); + }, [onSelectEmoji]); + + const content = useMemo( + () => + !visible ? null : ( +
+ + 清除 + + ) : null + } + collapsible + > + {renderedList.map((list) => { + return ( + +
+ {(list.data || []).map((ex) => ( +
selectEmoji(ex)}> + {ex} +
+ ))} +
+
+ ); + })} +
+
+ ), + [visible, showClear, renderedList, selectEmoji, clear] + ); + + useEffect(() => { + if (!visible) return; + emojiLocalStorageLRUCache.syncFromStorage(); + setRecentUsed(emojiLocalStorageLRUCache.get() as string[]); + }, [visible]); + + return ( + + {isMobile ? ( + <> + + {content} + + toggleVisible(true)}>{children} + + ) : ( + {content}} + > + {children} + + )} + + ); +}; diff --git a/packages/client/src/components/empty.tsx b/packages/client/src/components/empty.tsx new file mode 100644 index 0000000..de3f0df --- /dev/null +++ b/packages/client/src/components/empty.tsx @@ -0,0 +1,28 @@ +import React from 'react'; + +import { Typography } from '@douyinfe/semi-ui'; + +interface IProps { + illustration?: React.ReactNode; + message: React.ReactNode; +} + +const { Text } = Typography; + +export const Empty: React.FC = ({ illustration = null, message }) => { + return ( +
+ {illustration &&
{illustration}
} +
+ {message} +
+
+ ); +}; diff --git a/packages/client/src/components/grid-select/grid-cell.tsx b/packages/client/src/components/grid-select/grid-cell.tsx new file mode 100644 index 0000000..a472e2c --- /dev/null +++ b/packages/client/src/components/grid-select/grid-cell.tsx @@ -0,0 +1,61 @@ +import React, { MouseEventHandler } from 'react'; + +type CellProperties = { + hover: boolean; + disabled: boolean; + cellSize: number; + onMouseDown: MouseEventHandler; + onMouseEnter: MouseEventHandler; + styles: Record; + id: string; +}; + +const getBaseStyles = (cellSize) => ({ + cell: { + width: cellSize, + height: cellSize, + background: '#fff', + cursor: 'pointer', + borderRadius: 3, + border: '1px solid #bababa', + }, + active: { + border: '1px solid #4d6cdd', + background: '#4d6cdd', + }, + hover: { + border: '1px solid #fff', + background: '#4d6cdd', + }, + disabled: { + filter: 'brightness(0.7)', + }, +}); + +const getMergedStyle = (baseStyles, styles, styleClass) => ({ + ...baseStyles[styleClass], + ...(styles && styles[styleClass] ? styles[styleClass] : {}), +}); + +export const GridCell = ({ hover, disabled, onMouseDown, onMouseEnter, cellSize, styles, id }: CellProperties) => { + const baseStyles = getBaseStyles(cellSize); + const cellStyles = { + cell: getMergedStyle(baseStyles, styles, 'cell'), + active: getMergedStyle(baseStyles, styles, 'active'), + hover: getMergedStyle(baseStyles, styles, 'hover'), + disabled: getMergedStyle(baseStyles, styles, 'disabled'), + }; + + return ( +
+ ); +}; diff --git a/packages/client/src/components/grid-select/grid-select.tsx b/packages/client/src/components/grid-select/grid-select.tsx new file mode 100644 index 0000000..52105c2 --- /dev/null +++ b/packages/client/src/components/grid-select/grid-select.tsx @@ -0,0 +1,122 @@ +import React, { useCallback, useMemo, useState } from 'react'; + +import { Typography } from '@douyinfe/semi-ui'; + +import { GridCell } from './grid-cell'; + +const { Text } = Typography; + +export type RegionSelectionProps = { + rows?: number; + cols?: number; + onSelect: (arg: { rows: number; cols: number }) => void; + cellSize?: number; + disabled?: boolean; + styles?: { + active?: React.CSSProperties; + hover?: React.CSSProperties; + cell?: React.CSSProperties; + grid?: React.CSSProperties; + disabled?: React.CSSProperties; + }; +}; + +type CoordsType = { + x: number; + y: number; +}; + +const getBaseStyles = (cols, cellSize) => ({ + grid: { + position: 'relative', + display: 'grid', + color: '#444', + margin: '8px 0', + gridGap: '4px 6px', + gridTemplateColumns: Array(cols).fill(`${cellSize}px`).join(' '), + }, +}); + +export const GridSelect = ({ + onSelect, + rows = 10, + cols = 10, + disabled = false, + cellSize = 16, + styles, +}: RegionSelectionProps) => { + const [hoverCell, setHoverCell] = useState(null); + + const onClick = useCallback( + ({ x, y, isCellDisabled }) => { + onSelect({ + rows: y + 1, + cols: x + 1, + }); + }, + [onSelect] + ); + + const onClickPanel = useCallback(() => { + if (hoverCell.x + 1 > 0 && hoverCell.y + 1 > 0) { + onSelect({ + rows: hoverCell.y + 1, + cols: hoverCell.x + 1, + }); + } + }, [hoverCell, onSelect]); + + const onHover = useCallback(({ x, y, isCellDisabled }) => { + if (isCellDisabled) { + return setHoverCell(null); + } + setHoverCell({ x, y }); + }, []); + + const cells = useMemo(() => { + const cells = []; + for (let y = 0; y < rows; y++) { + for (let x = 0; x < cols; x++) { + const isHover = hoverCell && x <= hoverCell.x && y <= hoverCell.y; + const isCellDisabled = disabled; + cells.push( + { + e.stopPropagation(); + onClick({ x, y, isCellDisabled }); + }} + onMouseEnter={onHover.bind(null, { x, y, isCellDisabled })} + hover={isHover} + disabled={isCellDisabled} + styles={styles} + cellSize={cellSize} + /> + ); + } + } + return cells; + }, [rows, cols, disabled, cellSize, hoverCell, styles, onClick, onHover]); + + const baseStyles = useMemo(() => getBaseStyles(cols, cellSize), [cols, cellSize]); + + return ( +
+
setHoverCell(null)} + > + {cells} +
+
+ {hoverCell ? `${hoverCell.y + 1} x ${hoverCell.x + 1}` : null} +
+
+ ); +}; diff --git a/packages/client/src/components/grid-select/index.tsx b/packages/client/src/components/grid-select/index.tsx new file mode 100644 index 0000000..7ea5444 --- /dev/null +++ b/packages/client/src/components/grid-select/index.tsx @@ -0,0 +1 @@ +export * from './grid-select'; diff --git a/packages/client/src/components/icons/IconAddColumnAfter.tsx b/packages/client/src/components/icons/IconAddColumnAfter.tsx new file mode 100644 index 0000000..c4e53c7 --- /dev/null +++ b/packages/client/src/components/icons/IconAddColumnAfter.tsx @@ -0,0 +1,14 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconAddColumnAfter: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconAddColumnBefore.tsx b/packages/client/src/components/icons/IconAddColumnBefore.tsx new file mode 100644 index 0000000..571733f --- /dev/null +++ b/packages/client/src/components/icons/IconAddColumnBefore.tsx @@ -0,0 +1,14 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconAddColumnBefore: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconAddRowAfter.tsx b/packages/client/src/components/icons/IconAddRowAfter.tsx new file mode 100644 index 0000000..64e52d9 --- /dev/null +++ b/packages/client/src/components/icons/IconAddRowAfter.tsx @@ -0,0 +1,17 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconAddRowAfter: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconAddRowBefore.tsx b/packages/client/src/components/icons/IconAddRowBefore.tsx new file mode 100644 index 0000000..9a4c314 --- /dev/null +++ b/packages/client/src/components/icons/IconAddRowBefore.tsx @@ -0,0 +1,17 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconAddRowBefore: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconAttachment.tsx b/packages/client/src/components/icons/IconAttachment.tsx new file mode 100644 index 0000000..596f9f2 --- /dev/null +++ b/packages/client/src/components/icons/IconAttachment.tsx @@ -0,0 +1,18 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconAttachment: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconCallout.tsx b/packages/client/src/components/icons/IconCallout.tsx new file mode 100644 index 0000000..3191a66 --- /dev/null +++ b/packages/client/src/components/icons/IconCallout.tsx @@ -0,0 +1,14 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconCallout: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconCenter.tsx b/packages/client/src/components/icons/IconCenter.tsx new file mode 100644 index 0000000..1bd335b --- /dev/null +++ b/packages/client/src/components/icons/IconCenter.tsx @@ -0,0 +1,18 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconCenter: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconClear.tsx b/packages/client/src/components/icons/IconClear.tsx new file mode 100644 index 0000000..fedc988 --- /dev/null +++ b/packages/client/src/components/icons/IconClear.tsx @@ -0,0 +1,17 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconClear: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconCodeBlock.tsx b/packages/client/src/components/icons/IconCodeBlock.tsx new file mode 100644 index 0000000..4aa90dc --- /dev/null +++ b/packages/client/src/components/icons/IconCodeBlock.tsx @@ -0,0 +1,21 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconCodeBlock: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconColumns.tsx b/packages/client/src/components/icons/IconColumns.tsx new file mode 100644 index 0000000..1530419 --- /dev/null +++ b/packages/client/src/components/icons/IconColumns.tsx @@ -0,0 +1,43 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconAddColBefore: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + + } + /> + ); +}; + +export const IconAddColAfter: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + + } + /> + ); +}; + +export const IconDeleteCol: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconCountdown.tsx b/packages/client/src/components/icons/IconCountdown.tsx new file mode 100644 index 0000000..477e62b --- /dev/null +++ b/packages/client/src/components/icons/IconCountdown.tsx @@ -0,0 +1,16 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconCountdown: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconDeleteColumn.tsx b/packages/client/src/components/icons/IconDeleteColumn.tsx new file mode 100644 index 0000000..3b49076 --- /dev/null +++ b/packages/client/src/components/icons/IconDeleteColumn.tsx @@ -0,0 +1,14 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconDeleteColumn: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconDeleteRow.tsx b/packages/client/src/components/icons/IconDeleteRow.tsx new file mode 100644 index 0000000..9e526cf --- /dev/null +++ b/packages/client/src/components/icons/IconDeleteRow.tsx @@ -0,0 +1,14 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconDeleteRow: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconDeleteTable.tsx b/packages/client/src/components/icons/IconDeleteTable.tsx new file mode 100644 index 0000000..4c3c3ff --- /dev/null +++ b/packages/client/src/components/icons/IconDeleteTable.tsx @@ -0,0 +1,14 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconDeleteTable: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconDocument.tsx b/packages/client/src/components/icons/IconDocument.tsx new file mode 100644 index 0000000..7a50f24 --- /dev/null +++ b/packages/client/src/components/icons/IconDocument.tsx @@ -0,0 +1,21 @@ +import React from 'react'; + +import { Icon } from '@douyinfe/semi-ui'; + +export const IconDocument: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconDocumentFill.tsx b/packages/client/src/components/icons/IconDocumentFill.tsx new file mode 100644 index 0000000..f8e26c3 --- /dev/null +++ b/packages/client/src/components/icons/IconDocumentFill.tsx @@ -0,0 +1,20 @@ +import React from 'react'; + +import { Icon } from '@douyinfe/semi-ui'; + +export const IconDocumentFill: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconDrawBoard.tsx b/packages/client/src/components/icons/IconDrawBoard.tsx new file mode 100644 index 0000000..fd63167 --- /dev/null +++ b/packages/client/src/components/icons/IconDrawBoard.tsx @@ -0,0 +1,32 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconDrawBoard: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconEmoji.tsx b/packages/client/src/components/icons/IconEmoji.tsx new file mode 100644 index 0000000..61901eb --- /dev/null +++ b/packages/client/src/components/icons/IconEmoji.tsx @@ -0,0 +1,18 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconEmoji: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconFlow.tsx b/packages/client/src/components/icons/IconFlow.tsx new file mode 100644 index 0000000..b4d49c1 --- /dev/null +++ b/packages/client/src/components/icons/IconFlow.tsx @@ -0,0 +1,17 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconFlow: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconFont.tsx b/packages/client/src/components/icons/IconFont.tsx new file mode 100644 index 0000000..8b6a085 --- /dev/null +++ b/packages/client/src/components/icons/IconFont.tsx @@ -0,0 +1,18 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconFont: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconFull.tsx b/packages/client/src/components/icons/IconFull.tsx new file mode 100644 index 0000000..e7fb71d --- /dev/null +++ b/packages/client/src/components/icons/IconFull.tsx @@ -0,0 +1,17 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconFull: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconFullscreen.tsx b/packages/client/src/components/icons/IconFullscreen.tsx new file mode 100644 index 0000000..8337943 --- /dev/null +++ b/packages/client/src/components/icons/IconFullscreen.tsx @@ -0,0 +1,18 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconFullscreen: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconGlobe.tsx b/packages/client/src/components/icons/IconGlobe.tsx new file mode 100644 index 0000000..de90c67 --- /dev/null +++ b/packages/client/src/components/icons/IconGlobe.tsx @@ -0,0 +1,27 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconGlobe: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( +
+
+ } />} + onClick={setImage(url)} + /> +
+ + ); + })} + + ); + })} + + ); + }), + [images, setImage] + ); + + const content = useMemo( + () => ( +
+ + 清除 + + } + > + {imageTabs} + + selectImage(url)} /> + + +
+ ), + [imageTabs, selectImage, clear] + ); + + return ( + + {isMobile ? ( + <> + + {content} + + toggleVisible(true)}>{children} + + ) : ( + {content}} + > + {children} + + )} + + ); +}; diff --git a/packages/client/src/components/image-viewer.tsx b/packages/client/src/components/image-viewer.tsx new file mode 100644 index 0000000..721b69c --- /dev/null +++ b/packages/client/src/components/image-viewer.tsx @@ -0,0 +1,32 @@ +import { useEffect } from 'react'; + +import Viewer from 'viewerjs'; + +interface IProps { + containerSelector?: string; + container?: HTMLElement; +} + +export const ImageViewer: React.FC = ({ container, containerSelector }) => { + useEffect(() => { + const el = container || document.querySelector(containerSelector); + if (!el) { + return null; + } + const viewer = new Viewer(el, { inline: false }); + const io = new MutationObserver(() => { + viewer.update(); + }); + io.observe(el, { + childList: true, + subtree: true, + }); + + return () => { + io.disconnect(); + viewer.destroy(); + }; + }, [container, containerSelector]); + + return null; +}; diff --git a/packages/client/src/components/locale-time/index.tsx b/packages/client/src/components/locale-time/index.tsx new file mode 100644 index 0000000..372ea2f --- /dev/null +++ b/packages/client/src/components/locale-time/index.tsx @@ -0,0 +1,45 @@ +import React, { useEffect, useMemo, useRef, useState } from 'react'; + +import * as timeagojs from 'timeago.js'; + +type Props = { + date: string | number | Date; +}; + +let callbacks: Array<() => void> = []; + +setInterval(() => { + callbacks.forEach((cb) => cb()); +}, 1000 * 60); + +function eachMinute(fn: () => void) { + callbacks.push(fn); + + return () => { + callbacks = callbacks.filter((cb) => cb !== fn); + }; +} + +const getTimeago = (date: number | string | Date) => { + return timeagojs.format(date, 'zh_CN'); +}; + +export const LocaleTime: React.FC = ({ date }) => { + const [, setMinutesMounted] = useState(0); + const callback = useRef<() => void>(); + const formatDate = useMemo(() => new Date(date).toLocaleDateString(), [date]); + + useEffect(() => { + callback.current = eachMinute(() => { + setMinutesMounted((state) => ++state); + }); + + return () => { + if (callback.current) { + callback.current(); + } + }; + }, []); + + return ; +}; diff --git a/packages/client/src/components/logo/index.module.scss b/packages/client/src/components/logo/index.module.scss new file mode 100644 index 0000000..e720445 --- /dev/null +++ b/packages/client/src/components/logo/index.module.scss @@ -0,0 +1,16 @@ +.wrap { + display: inline-flex !important; + flex-wrap: nowrap; + align-items: center; + + > svg { + width: 32px; + height: 32px; + } + + > span { + margin-left: 4px; + font-size: 1.2rem; + font-weight: 500; + } +} diff --git a/packages/client/src/components/logo/index.tsx b/packages/client/src/components/logo/index.tsx new file mode 100644 index 0000000..2cc1d24 --- /dev/null +++ b/packages/client/src/components/logo/index.tsx @@ -0,0 +1,51 @@ +import { Typography } from '@douyinfe/semi-ui'; + +import { RuntimeConfig } from 'hooks/use-runtime-config'; +import Link from 'next/link'; + +import styles from './index.module.scss'; + +const { Text } = Typography; + +export const LogoImage = () => { + const config = RuntimeConfig.useHook(); + + return ( + + + {config.logo ? ( + + ) : ( + + + + + + )} + + + ); +}; + +export const LogoText = () => { + const config = RuntimeConfig.useHook(); + + return ( + + + {config?.appName} + + + ); +}; diff --git a/packages/client/src/components/members/add.tsx b/packages/client/src/components/members/add.tsx new file mode 100644 index 0000000..6712e27 --- /dev/null +++ b/packages/client/src/components/members/add.tsx @@ -0,0 +1,62 @@ +import React, { useCallback, useState } from 'react'; + +import { Banner, Input, Popconfirm, Select, Space } from '@douyinfe/semi-ui'; + +import { AuthEnum, AuthEnumArray } from '@think/domains'; + +interface IProps { + onOk: (arg) => any; +} + +export const AddUser: React.FC = ({ onOk, children }) => { + const [userAuth, setUserAuth] = useState(AuthEnum.noAccess); + const [userName, setUserName] = useState(''); + + const handleOk = useCallback(() => { + onOk({ userName, userAuth }).then(() => { + setUserAuth(AuthEnum.noAccess); + setUserName(''); + }); + }, [onOk, userName, userAuth]); + + return ( + + {[AuthEnum.creator, AuthEnum.admin].includes(userAuth) ? ( + + ) : null} + + + + + + } + > + {children} + + ); +}; diff --git a/packages/client/src/components/members/edit.tsx b/packages/client/src/components/members/edit.tsx new file mode 100644 index 0000000..34b702d --- /dev/null +++ b/packages/client/src/components/members/edit.tsx @@ -0,0 +1,49 @@ +import React, { useCallback, useState } from 'react'; + +import { Banner, Popconfirm, Select, Toast } from '@douyinfe/semi-ui'; + +import { AuthEnum, AuthEnumArray, IAuth, IUser } from '@think/domains'; + +interface IProps { + userWithAuth: { user: IUser; auth: IAuth }; + updateUser: (arg) => any; +} + +export const EditUser: React.FC = ({ userWithAuth, updateUser, children }) => { + const [userAuth, setUserAuth] = useState(AuthEnum.noAccess); + + const handleOk = useCallback(() => { + return updateUser({ userName: userWithAuth.user.name, userAuth }).then(() => { + Toast.success('操作成功'); + }); + }, [updateUser, userAuth, userWithAuth]); + + return ( + + {[AuthEnum.creator, AuthEnum.admin].includes(userAuth) ? ( + + ) : null} + {} + + + } + onConfirm={handleOk} + > + {children} + + ); +}; diff --git a/packages/client/src/components/members/index.module.scss b/packages/client/src/components/members/index.module.scss new file mode 100644 index 0000000..7eb36ff --- /dev/null +++ b/packages/client/src/components/members/index.module.scss @@ -0,0 +1,6 @@ +.wrap { + > header { + display: flex; + justify-content: flex-end; + } +} diff --git a/packages/client/src/components/members/index.tsx b/packages/client/src/components/members/index.tsx new file mode 100644 index 0000000..0cefa7b --- /dev/null +++ b/packages/client/src/components/members/index.tsx @@ -0,0 +1,117 @@ +import React from 'react'; + +import { IconDelete, IconEdit } from '@douyinfe/semi-icons'; +import { Banner, Button, Popconfirm, Table, Typography } from '@douyinfe/semi-ui'; + +import { AuthEnumTextMap } from '@think/domains'; + +import { DataRender } from 'components/data-render'; +import { LocaleTime } from 'components/locale-time'; + +import { AddUser } from './add'; +import { EditUser } from './edit'; + +import styles from './index.module.scss'; + +interface IProps { + id: string; + hook: any; + descriptions?: Array; +} + +const { Title, Paragraph } = Typography; +const { Column } = Table; + +export const Members: React.FC = ({ id, hook, descriptions }) => { + const { data, loading, error, page, pageSize, setPage, addUser, updateUser, deleteUser } = hook(id); + + return ( +
+ ( +
+ 权限说明} + description={ +
+ {descriptions && descriptions.length ? ( + descriptions.map((desc) => { + return {desc}; + }) + ) : ( + <> + 超级管理员:管理组织内所有知识库、文档,可删除组织,默认创建者 + 管理员:管理组织内所有知识库、文档,不可删除组织 + 成员:可访问组织内所有知识库、文档,不可删除组织 + + )} +
+ } + /> +
+ + + +
+
+ + AuthEnumTextMap[auth]} + /> + } + /> + ( + <> + +
+
+ )} + /> + + ); +}; diff --git a/packages/client/src/components/message/index.module.scss b/packages/client/src/components/message/index.module.scss new file mode 100644 index 0000000..34d9e96 --- /dev/null +++ b/packages/client/src/components/message/index.module.scss @@ -0,0 +1,54 @@ +.titleWrap { + padding: 8px 16px; +} + +.itemsWrap { + max-height: 240px; + overflow: auto; +} + +.itemWrap { + border-radius: var(--semi-border-radius-small); + + &:hover { + color: var(--semi-color-text-0); + background-color: var(--semi-color-fill-0); + } + + .item { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + height: 32px; + padding: 4px 16px; + + .leftWrap { + display: flex; + overflow: hidden; + color: var(--semi-color-primary); + text-overflow: ellipsis; + white-space: nowrap; + align-items: center; + + > span { + word-break: break-all; + } + + svg { + fill: var(--semi-color-primary); + color: var(--semi-color-primary); + } + + > div { + display: flex; + flex-direction: column; + } + } + } +} + +.paginationWrap { + display: flex; + justify-content: center; +} diff --git a/packages/client/src/components/message/index.tsx b/packages/client/src/components/message/index.tsx new file mode 100644 index 0000000..50ebd5c --- /dev/null +++ b/packages/client/src/components/message/index.tsx @@ -0,0 +1,247 @@ +import React, { useCallback, useMemo } from 'react'; + +import { Badge, Button, Dropdown, Modal, Pagination, TabPane, Tabs, Typography } from '@douyinfe/semi-ui'; + +import { DataRender } from 'components/data-render'; +import { Empty } from 'components/empty'; +import { IconMessage } from 'components/icons/IconMessage'; +import { useAllMessages, useReadMessages, useUnreadMessages } from 'data/message'; +import { useUser } from 'data/user'; +import { IsOnMobile } from 'hooks/use-on-mobile'; +import { useToggle } from 'hooks/use-toggle'; +import { EmptyBoxIllustration } from 'illustrations/empty-box'; +import Link from 'next/link'; + +import { Placeholder } from './placeholder'; + +import styles from './index.module.scss'; + +const { Text } = Typography; +const PAGE_SIZE = 6; + +const MessagesRender = ({ messageData, loading, error, onClick = null, page = 1, onPageChange = null }) => { + const [messages, total] = useMemo( + () => [(messageData && messageData.data) || [], (messageData && messageData.total) || 0], + [messageData] + ); + + const handleRead = useCallback( + (messageId) => { + onClick && onClick(messageId); + }, + [onClick] + ); + + const renderNormalContent = useCallback(() => { + return ( +
{ + e.preventDefault(); + e.stopPropagation(); + }} + > + {messages.length ? ( + <> + {messages.map((msg) => { + return ( +
handleRead(msg.id)}> + + +
+ + {msg.title} + +
+
+ +
+ ); + })} + {total > PAGE_SIZE && ( +
+ +
+ )} + + ) : ( + } message="暂无消息" /> + )} +
+ ); + }, [handleRead, messages, onPageChange, page, total]); + + return ( + } error={error} normalContent={renderNormalContent} /> + ); +}; + +const MessageBox = () => { + const { isMobile } = IsOnMobile.useHook(); + const [visible, toggleVisible] = useToggle(false); + const { data: allMsgs, loading: allLoading, error: allError, page: allPage, setPage: allSetPage } = useAllMessages(); + const { + data: readMsgs, + loading: readLoading, + error: readError, + page: readPage, + setPage: readSetPage, + } = useReadMessages(); + const { + data: unreadMsgs, + loading: unreadLoading, + error: unreadError, + readMessage, + page: unreadPage, + setPage: unreadSetPage, + } = useUnreadMessages(); + + const clearAll = useCallback(() => { + Promise.all( + (unreadMsgs.data || []).map((msg) => { + return readMessage(msg.id); + }) + ); + }, [readMessage, unreadMsgs]); + + const openModalOnMobile = useCallback(() => { + if (!isMobile) return; + toggleVisible(true); + }, [isMobile, toggleVisible]); + + const content = useMemo( + () => + visible ? ( + 0 ? ( + + 全部已读 + + ) : null + } + > + + + + + + + + + + + ) : null, + [ + allError, + allLoading, + allMsgs, + allPage, + allSetPage, + clearAll, + readError, + readLoading, + readMessage, + readMsgs, + readPage, + readSetPage, + unreadError, + unreadLoading, + unreadMsgs, + unreadPage, + unreadSetPage, + visible, + ] + ); + + const btn = ( + + + + + + + + + +
+ +
+ + )} + /> + ); +}; diff --git a/packages/client/src/components/organization/setting/index.tsx b/packages/client/src/components/organization/setting/index.tsx new file mode 100644 index 0000000..39b55b8 --- /dev/null +++ b/packages/client/src/components/organization/setting/index.tsx @@ -0,0 +1,44 @@ +import React from 'react'; + +import { TabPane, Tabs } from '@douyinfe/semi-ui'; + +import { IOrganization } from '@think/domains'; + +import { Seo } from 'components/seo'; + +import { Base } from './base'; +import { OrganizationMembers } from './members'; +import { More } from './more'; + +interface IProps { + organizationId: IOrganization['id']; + tab?: string; + onNavigate: (arg: string) => void; +} + +const TitleMap = { + base: '基础信息', + members: '成员管理', + more: '更多', +}; + +export const OrganizationSetting: React.FC = ({ organizationId, tab, onNavigate }) => { + return ( + <> + + + + + + + + + + + + + + + + ); +}; diff --git a/packages/client/src/components/organization/setting/members/index.tsx b/packages/client/src/components/organization/setting/members/index.tsx new file mode 100644 index 0000000..121cabf --- /dev/null +++ b/packages/client/src/components/organization/setting/members/index.tsx @@ -0,0 +1,14 @@ +import React from 'react'; + +import { IOrganization } from '@think/domains'; + +import { Members } from 'components/members'; +import { useOrganizationMembers } from 'data/organization'; + +interface IProps { + organizationId: IOrganization['id']; +} + +export const OrganizationMembers: React.FC = ({ organizationId }) => { + return ; +}; diff --git a/packages/client/src/components/organization/setting/more/index.tsx b/packages/client/src/components/organization/setting/more/index.tsx new file mode 100644 index 0000000..339a515 --- /dev/null +++ b/packages/client/src/components/organization/setting/more/index.tsx @@ -0,0 +1,24 @@ +import { Banner, Button, Typography } from '@douyinfe/semi-ui'; + +import { OrganizationDeletor } from 'components/organization/delete'; + +const { Paragraph } = Typography; + +export const More = ({ organizationId }) => { + return ( +
+ 删除组织及内部所有知识库以及文档,不可恢复!} + style={{ marginBottom: 16 }} + /> + + + +
+ ); +}; diff --git a/packages/client/src/components/organization/switcher/index.module.scss b/packages/client/src/components/organization/switcher/index.module.scss new file mode 100644 index 0000000..5458e72 --- /dev/null +++ b/packages/client/src/components/organization/switcher/index.module.scss @@ -0,0 +1,4 @@ +.nameWrap { + display: flex; + align-items: center; +} diff --git a/packages/client/src/components/organization/switcher/index.tsx b/packages/client/src/components/organization/switcher/index.tsx new file mode 100644 index 0000000..7ce7e1c --- /dev/null +++ b/packages/client/src/components/organization/switcher/index.tsx @@ -0,0 +1,163 @@ +import { useMemo } from 'react'; + +import { IconAppCenter, IconApps, IconSmallTriangleDown } from '@douyinfe/semi-icons'; +import { Button, Dropdown, Space, Typography } from '@douyinfe/semi-ui'; +import { Avatar } from '@douyinfe/semi-ui'; + +import { DataRender } from 'components/data-render'; +import { useOrganizationDetail, useUserOrganizations } from 'data/organization'; +import { useRouterQuery } from 'hooks/use-router-query'; +import Link from 'next/link'; + +import styles from './index.module.scss'; + +const { Text, Paragraph } = Typography; + +export const UserOrganizationsSwitcher = () => { + const { organizationId } = useRouterQuery<{ organizationId: string }>(); + const { + data: userOrganizations, + loading: userOrganizationsLoading, + error: userOrganizationsError, + } = useUserOrganizations(); + const filterUserOrganizations = useMemo(() => { + return userOrganizations && userOrganizations.length + ? userOrganizations.filter((org) => org.id !== organizationId) + : []; + }, [userOrganizations, organizationId]); + + return ( + { + return ( + + {filterUserOrganizations.length ? ( + <> + {filterUserOrganizations.map((org) => { + return ( + + + + + + {org.name} + + + + + ); + })} + + + ) : null} + + + + + + + + + + 前往广场 + + + + + + + + + + + + + + + 新建组织 + + + + + + + ); + }} + /> + } + > + + + } + > + {children} + + ); +}; diff --git a/packages/client/src/components/template/card/index.module.scss b/packages/client/src/components/template/card/index.module.scss new file mode 100644 index 0000000..1cc5e7d --- /dev/null +++ b/packages/client/src/components/template/card/index.module.scss @@ -0,0 +1,64 @@ +.cardWrap { + position: relative; + display: flex; + width: 100%; + height: 161px; + padding: 12px 16px 16px; + margin: 8px 0; + overflow: hidden; + cursor: pointer; + border: 1px solid var(--semi-color-border); + border-radius: var(--border-radius); + transform: translateZ(0); + flex-direction: column; + + header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 12px; + color: var(--semi-color-primary); + + .rightWrap { + opacity: 0; + } + } + + .actions { + position: absolute; + bottom: -1px; + left: 0; + z-index: 10; + display: flex; + width: 100%; + padding: 8px; + background-color: var(--semi-color-fill-2); + border-radius: 0 0 var(--border-radius) var(--border-radius); + opacity: 0; + justify-content: space-around; + transition: all ease-in-out 0.2s; + + button { + width: 40%; + } + } + + &:hover { + box-shadow: var(--semi-color-shadow); + + header .rightWrap { + opacity: 1; + } + + .actions { + opacity: 1; + } + } + + footer { + margin-top: 12px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } +} diff --git a/packages/client/src/components/template/card/index.tsx b/packages/client/src/components/template/card/index.tsx new file mode 100644 index 0000000..e194aac --- /dev/null +++ b/packages/client/src/components/template/card/index.tsx @@ -0,0 +1,196 @@ +import { useCallback } from 'react'; + +import { IconEdit, IconPlus, IconUser } from '@douyinfe/semi-icons'; +import { Avatar, Button, Modal, Skeleton, Space, Tooltip, Typography } from '@douyinfe/semi-ui'; + +import type { ITemplate } from '@think/domains'; + +import cls from 'classnames'; +import { IconDocument } from 'components/icons/IconDocument'; +import { TemplateReader } from 'components/template/reader'; +import { useUser } from 'data/user'; +import { useToggle } from 'hooks/use-toggle'; +import Router from 'next/router'; + +import styles from './index.module.scss'; + +const { Text } = Typography; + +export interface IProps { + template: ITemplate; + onClick?: (id: string) => void; + getClassNames?: (id: string) => string; + onOpenPreview?: () => void; + onClosePreview?: () => void; +} + +const bodyStyle = { + overflow: 'auto', +}; +const titleContainerStyle = { + marginBottom: 12, + whiteSpace: 'nowrap', + textOverflow: 'ellipsis', + overflow: 'hidden', +} as React.CSSProperties; +const flexStyle = { display: 'flex' }; + +export const TemplateCard: React.FC = ({ + template, + onClick, + getClassNames = (id) => '', + onOpenPreview, + onClosePreview, +}) => { + const { user } = useUser(); + const [visible, toggleVisible] = useToggle(false); + + const gotoEdit = useCallback(() => { + Router.push(`/template/${template.id}/`); + }, [template]); + + const cancel = useCallback(() => { + toggleVisible(false); + onClosePreview && onClosePreview(); + }, [toggleVisible, onClosePreview]); + + const preview = useCallback(() => { + toggleVisible(true); + onOpenPreview && onOpenPreview(); + }, [toggleVisible, onOpenPreview]); + + const useTemplate = useCallback(() => { + onClick && onClick(template.id); + }, [onClick, template.id]); + + return ( + <> + + + +
+
+ +
+ {template.createUser && user && template.createUser.id === user.id && ( + + +
+
+
+
+ {template.title} +
+
+ + + + + + 创建者: + {template.createUser && template.createUser.name} + + +
+
+
+ +
+ 已使用 + {template.usageAmount}次 +
+
+
+
+ +
+
+ + ); +}; + +export const TemplateCardPlaceholder = () => { + return ( +
+
+ +
+
+
+ +
+
+ + + + + + 创建者: + + + +
+
+
+ +
+ 更新时间: + +
+
+
+
+ ); +}; + +export const TemplateCardEmpty = ({ getClassNames = () => '', onClick = () => {} }) => { + return ( +
+
+
+ + + + 空白文档 +
+
+
+ ); +}; diff --git a/packages/client/src/components/template/editor/index.module.scss b/packages/client/src/components/template/editor/index.module.scss new file mode 100644 index 0000000..f8eee49 --- /dev/null +++ b/packages/client/src/components/template/editor/index.module.scss @@ -0,0 +1,26 @@ +/* stylelint-disable no-descending-specificity */ +.wrap { + display: flex; + flex-direction: column; + height: 100%; + overflow: hidden; + + > header { + position: relative; + z-index: 110; + height: 60px; + background-color: var(--semi-color-nav-bg); + user-select: none; + + > div { + overflow: auto; + } + } + + > main { + height: calc(100% - 60px); + overflow: hidden; + background-color: var(--semi-color-nav-bg); + flex: 1; + } +} diff --git a/packages/client/src/components/template/editor/index.tsx b/packages/client/src/components/template/editor/index.tsx new file mode 100644 index 0000000..f0a6e13 --- /dev/null +++ b/packages/client/src/components/template/editor/index.tsx @@ -0,0 +1,101 @@ +import React, { useCallback, useEffect, useMemo, useState } from 'react'; + +import { IconChevronLeft } from '@douyinfe/semi-icons'; +import { Button, Nav, Popconfirm, Space, Switch, Tooltip, Typography } from '@douyinfe/semi-ui'; + +import { CollaborationEditor } from 'tiptap/editor'; + +import { DocumentStyle } from 'components/document/style'; +import { Seo } from 'components/seo'; +import { Theme } from 'components/theme'; +import { User } from 'components/user'; +import { useTemplate } from 'data/template'; +import { useUser } from 'data/user'; +import { useDocumentStyle } from 'hooks/use-document-style'; +import { useMount } from 'hooks/use-mount'; +import { useWindowSize } from 'hooks/use-window-size'; +import Router from 'next/router'; + +import styles from './index.module.scss'; + +interface IProps { + templateId: string; +} + +const { Text } = Typography; + +export const TemplateEditor: React.FC = ({ templateId }) => { + const { user } = useUser(); + const mounted = useMount(); + const { data, loading, error, updateTemplate, deleteTemplate } = useTemplate(templateId); + const { width: windowWidth } = useWindowSize(); + const [title, setTitle] = useState(data && data.title); + const [isPublic, setPublic] = useState(false); + const { width, fontSize } = useDocumentStyle(); + const editorWrapClassNames = useMemo(() => { + return width === 'standardWidth' ? styles.isStandardWidth : styles.isFullWidth; + }, [width]); + + const goback = useCallback(() => { + Router.back(); + }, []); + + const handleDelte = useCallback(() => { + deleteTemplate().then(() => { + goback(); + }); + }, [deleteTemplate, goback]); + + useEffect(() => { + if (!data) return; + setPublic(data.isPublic); + setTitle(data.title); + }, [data]); + + return ( + <> + {data && } +
+
+ +
+
+ {mounted && data && ( + + )} +
+
+ + ); +}; diff --git a/packages/client/src/components/template/list/index.tsx b/packages/client/src/components/template/list/index.tsx new file mode 100644 index 0000000..122bc0c --- /dev/null +++ b/packages/client/src/components/template/list/index.tsx @@ -0,0 +1,99 @@ +import React, { useEffect } from 'react'; + +import { List, Pagination } from '@douyinfe/semi-ui'; + +import { DataRender } from 'components/data-render'; +import { Empty } from 'components/empty'; +import { IProps as ITemplateCardProps, TemplateCard, TemplateCardPlaceholder } from 'components/template/card'; + +const grid = { + gutter: 16, + xs: 24, + sm: 12, + md: 12, + lg: 8, + xl: 8, +}; + +interface IProps extends Omit { + // TODO: 修复类型 + hook: any; + firstListItem?: React.ReactNode; + pageSize?: number; +} + +export const TemplateList: React.FC = ({ + hook, + onClick, + getClassNames, + firstListItem, + onOpenPreview, + onClosePreview, + pageSize = 5, +}) => { + const { data, loading, error, page, setPage, refresh } = hook(pageSize); + const list = (data && data.data) || []; + const total = (data && data.total) || 0; + + useEffect(() => { + refresh(); + }, [refresh]); + + return ( + ( + ( + + + + )} + /> + )} + error={error} + normalContent={() => ( + <> + { + if (idx === 0 && firstListItem) { + return {firstListItem}; + } + + return ( + + + + ); + }} + emptyContent={} + > + {total > pageSize ? ( + setPage(cPage)} + /> + ) : null} + + )} + /> + ); +}; diff --git a/packages/client/src/components/template/reader/index.tsx b/packages/client/src/components/template/reader/index.tsx new file mode 100644 index 0000000..8266ff3 --- /dev/null +++ b/packages/client/src/components/template/reader/index.tsx @@ -0,0 +1,37 @@ +import React from 'react'; + +import { Spin } from '@douyinfe/semi-ui'; + +import { ReaderEditor } from 'tiptap/editor'; + +import { DataRender } from 'components/data-render'; +import { Seo } from 'components/seo'; +import { useTemplate } from 'data/template'; + +interface IProps { + templateId: string; +} + +export const TemplateReader: React.FC = ({ templateId }) => { + const { data, loading, error } = useTemplate(templateId); + + return ( + + + + } + error={error} + normalContent={() => { + return ( +
+ + +
+ ); + }} + /> + ); +}; diff --git a/packages/client/src/components/theme/index.tsx b/packages/client/src/components/theme/index.tsx new file mode 100644 index 0000000..0e568f9 --- /dev/null +++ b/packages/client/src/components/theme/index.tsx @@ -0,0 +1,49 @@ +import React, { useCallback } from 'react'; + +import { IconDesktop, IconMoon, IconSun } from '@douyinfe/semi-icons'; +import { Button, Dropdown } from '@douyinfe/semi-ui'; + +import { Theme as ThemeState, ThemeEnum } from 'hooks/use-theme'; + +export const Theme = () => { + const { userPrefer, theme, toggle } = ThemeState.useHook(); + const Icon = theme === 'dark' ? IconMoon : IconSun; + + const setLight = useCallback(() => { + toggle(ThemeEnum.light); + }, [toggle]); + + const setDark = useCallback(() => { + toggle(ThemeEnum.dark); + }, [toggle]); + + const setSystem = useCallback(() => { + toggle(ThemeEnum.system); + }, [toggle]); + + return ( + + + + 亮色 + + + + 夜色 + + + + 系统 + + + } + > + + + ); +}; diff --git a/packages/client/src/components/tooltip/index.tsx b/packages/client/src/components/tooltip/index.tsx new file mode 100644 index 0000000..2cc80eb --- /dev/null +++ b/packages/client/src/components/tooltip/index.tsx @@ -0,0 +1,34 @@ +import React from 'react'; + +import { Tooltip as SemiTooltip } from '@douyinfe/semi-ui'; +import { Position } from '@douyinfe/semi-ui/tooltip'; + +import { useToggle } from 'hooks/use-toggle'; + +interface IProps { + content: React.ReactNode; + hideOnClick?: boolean; + position?: Position; +} + +export const Tooltip: React.FC = ({ content, hideOnClick = false, position = 'top', children }) => { + const [visible, toggleVisible] = useToggle(false); + + return ( + + { + toggleVisible(true); + }} + onMouseLeave={() => { + toggleVisible(false); + }} + onMouseDown={() => { + hideOnClick && toggleVisible(false); + }} + > + {children} + + + ); +}; diff --git a/packages/client/src/components/upload/index.tsx b/packages/client/src/components/upload/index.tsx new file mode 100644 index 0000000..98cbb07 --- /dev/null +++ b/packages/client/src/components/upload/index.tsx @@ -0,0 +1,47 @@ +import React from 'react'; + +import { IconUpload } from '@douyinfe/semi-icons'; +import { Button, Toast, Upload as SemiUpload } from '@douyinfe/semi-ui'; + +import { useAsyncLoading } from 'hooks/use-async-loading'; +import { uploadFile } from 'services/file'; + +interface IProps { + onOK: (arg: string, fileName: string, fileSize: number) => void; + style?: React.CSSProperties; + accept?: string; + children?: (loading: boolean) => React.ReactNode; +} + +export const Upload: React.FC = ({ onOK, accept, style = {}, children }) => { + const [uploadFileWithLoading, loading] = useAsyncLoading(uploadFile); + + const beforeUpload = ({ file }) => { + uploadFileWithLoading(file.fileInstance).then((res: string) => { + Toast.success('上传成功'); + onOK && onOK(res, file.name, file.size); + }); + return false; + }; + + return ( + null} + fileList={[]} + style={{ + display: 'flex', + justifyContent: 'center', + ...style, + }} + action={''} + accept={accept} + > + {(children && children(loading)) || ( + + )} + + ); +}; diff --git a/packages/client/src/components/user/index.tsx b/packages/client/src/components/user/index.tsx new file mode 100644 index 0000000..1c943e8 --- /dev/null +++ b/packages/client/src/components/user/index.tsx @@ -0,0 +1,84 @@ +import React, { useCallback } from 'react'; + +import { IconSpin } from '@douyinfe/semi-icons'; +import { Avatar, Button, Dropdown, Modal, Toast, Typography } from '@douyinfe/semi-ui'; + +import { useUser } from 'data/user'; +import { useToggle } from 'hooks/use-toggle'; +import Router from 'next/router'; + +import { ResetPassword } from './reset-password'; +import { UserSetting } from './setting'; + +const { Text } = Typography; + +export const User: React.FC = () => { + const { user, loading, error, toLogin, logout } = useUser(); + const [visible, toggleVisible] = useToggle(false); + const [resetVisible, toggleResetVisible] = useToggle(false); + + const toAdmin = useCallback(() => { + Router.push('/admin'); + }, []); + + const onResetSuccess = useCallback(() => { + Toast.success('请重新登录'); + Router.replace(`/login?redirect=${Router.asPath}`); + }, []); + + if (loading) return + ); + } + + return ( + <> + + toggleVisible(true)}> + 账户设置 + + + 重置密码 + + {user.isSystemAdmin ? ( + + 管理后台 + + ) : null} + + + 退出登录 + + + } + > + + + + ) : null} + + + + + + + + ); +}; diff --git a/packages/client/src/components/user/setting/index.tsx b/packages/client/src/components/user/setting/index.tsx new file mode 100644 index 0000000..17912b6 --- /dev/null +++ b/packages/client/src/components/user/setting/index.tsx @@ -0,0 +1,142 @@ +import { Dispatch, SetStateAction, useCallback, useEffect, useRef, useState } from 'react'; + +import { Avatar, Button, Col, Form, Modal, Row, Space, Toast } from '@douyinfe/semi-ui'; +import { FormApi } from '@douyinfe/semi-ui/lib/es/form'; + +import { Upload } from 'components/upload'; +import { useSystemPublicConfig, useUser, useVerifyCode } from 'data/user'; +import { useInterval } from 'hooks/use-interval'; +import { useToggle } from 'hooks/use-toggle'; + +interface IProps { + visible: boolean; + toggleVisible: Dispatch>; +} + +export const UserSetting: React.FC = ({ visible, toggleVisible }) => { + const $form = useRef(); + const { user, loading, updateUser } = useUser(); + const [currentAvatar, setCurrentAvatar] = useState(''); + const [email, setEmail] = useState(''); + const { data: systemConfig } = useSystemPublicConfig(); + const { sendVerifyCode, loading: sendVerifyCodeLoading } = useVerifyCode(); + const [hasSendVerifyCode, toggleHasSendVerifyCode] = useToggle(false); + const [countDown, setCountDown] = useState(0); + + const setAvatar = useCallback((url) => { + $form.current.setValue('avatar', url); + setCurrentAvatar(url); + }, []); + + const handleOk = useCallback(() => { + $form.current.validate().then((values) => { + if (!values.email) { + delete values.email; + } + updateUser(values).then(() => { + Toast.success('账户信息已更新'); + toggleVisible(false); + }); + }); + }, [toggleVisible, updateUser]); + + const handleCancel = useCallback(() => { + toggleVisible(false); + }, [toggleVisible]); + + const onFormChange = useCallback((formState) => { + setEmail(formState.values.email); + }, []); + + const { start, stop } = useInterval(() => { + setCountDown((v) => { + if (v - 1 <= 0) { + stop(); + toggleHasSendVerifyCode(false); + return 0; + } + return v - 1; + }); + }, 1000); + + const getVerifyCode = useCallback(() => { + stop(); + sendVerifyCode({ email }) + .then(() => { + Toast.success('请前往邮箱查收验证码'); + setCountDown(60); + start(); + toggleHasSendVerifyCode(true); + }) + .catch(() => { + toggleHasSendVerifyCode(false); + }); + }, [email, toggleHasSendVerifyCode, sendVerifyCode, start, stop]); + + useEffect(() => { + if (!user || !$form.current) return; + $form.current.setValues(user); + setCurrentAvatar(user.avatar); + }, [user]); + + return ( + +
($form.current = formApi)} + labelPosition="left" + onChange={onFormChange} + > + + + + + + + + + + + + {systemConfig && systemConfig.enableEmailVerify && email && email !== user.email ? ( + + + + + + + + + + + ) : null} +
+
+ ); +}; diff --git a/packages/client/src/components/wiki-creator/index.tsx b/packages/client/src/components/wiki-creator/index.tsx new file mode 100644 index 0000000..b616458 --- /dev/null +++ b/packages/client/src/components/wiki-creator/index.tsx @@ -0,0 +1,21 @@ +import React from 'react'; + +import { Button } from '@douyinfe/semi-ui'; + +import { WikiCreator as WikiCreatorForm } from 'components/wiki/create'; +import { useToggle } from 'hooks/use-toggle'; + +export const WikiCreator: React.FC = ({ children }) => { + const [visible, toggleVisible] = useToggle(false); + + return ( + <> + {children || ( + + )} + + + ); +}; diff --git a/packages/client/src/components/wiki-or-document-creator/index.tsx b/packages/client/src/components/wiki-or-document-creator/index.tsx new file mode 100644 index 0000000..92d38af --- /dev/null +++ b/packages/client/src/components/wiki-or-document-creator/index.tsx @@ -0,0 +1,55 @@ +import React from 'react'; + +import { IconPlus } from '@douyinfe/semi-icons'; +import { Button, Dropdown } from '@douyinfe/semi-ui'; + +import { DocumentCreator } from 'components/document/create'; +import { WikiCreator } from 'components/wiki/create'; +import { useRouterQuery } from 'hooks/use-router-query'; +import { useToggle } from 'hooks/use-toggle'; + +interface IProps { + onCreateDocument?: () => void; +} + +export const WikiOrDocumentCreator: React.FC = ({ onCreateDocument, children }) => { + const { wikiId, documentId } = useRouterQuery<{ wikiId?: string; documentId?: string }>(); + const [dropdownVisible, toggleDropdownVisible] = useToggle(false); + const [visible, toggleVisible] = useToggle(false); + const [createDocumentModalVisible, toggleCreateDocumentModalVisible] = useToggle(false); + + return ( + <> + + 知识库 + {wikiId && 文档} + + } + > + + {children || ( + + )} + + + + {wikiId && ( + + )} + + ); +}; diff --git a/packages/client/src/components/wiki/card/index.module.scss b/packages/client/src/components/wiki/card/index.module.scss new file mode 100644 index 0000000..69d25f4 --- /dev/null +++ b/packages/client/src/components/wiki/card/index.module.scss @@ -0,0 +1,39 @@ +.cardWrap { + width: 100%; + + > a { + display: flex; + width: 100%; + max-height: 260px; + padding: 12px 16px 16px; + margin: 8px 0; + cursor: pointer; + border: 1px solid var(--semi-color-border); + border-radius: 5px; + flex-direction: column; + + > header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 12px; + color: var(--semi-color-primary); + + .rightWrap { + opacity: 0; + } + } + + &:hover { + box-shadow: var(--box-shadow); + + > header .rightWrap { + opacity: 1; + } + } + + > footer { + margin-top: 12px; + } + } +} diff --git a/packages/client/src/components/wiki/card/index.tsx b/packages/client/src/components/wiki/card/index.tsx new file mode 100644 index 0000000..9b5ff66 --- /dev/null +++ b/packages/client/src/components/wiki/card/index.tsx @@ -0,0 +1,111 @@ +import { IconUser } from '@douyinfe/semi-icons'; +import { Avatar, Skeleton, Space, Typography } from '@douyinfe/semi-ui'; + +import { IconDocument } from 'components/icons/IconDocument'; +import { LocaleTime } from 'components/locale-time'; +import { WikiStar } from 'components/wiki/star'; +import { IWikiWithIsMember } from 'data/star'; +import Link from 'next/link'; + +import styles from './index.module.scss'; + +const { Text, Paragraph } = Typography; + +export const WikiCard: React.FC<{ wiki: IWikiWithIsMember; shareMode?: boolean }> = ({ wiki, shareMode = false }) => { + return ( + + ); +}; + +export const WikiCardPlaceholder = () => { + return ( + + ); +}; diff --git a/packages/client/src/components/wiki/create/index.tsx b/packages/client/src/components/wiki/create/index.tsx new file mode 100644 index 0000000..02d8d50 --- /dev/null +++ b/packages/client/src/components/wiki/create/index.tsx @@ -0,0 +1,61 @@ +import { Dispatch, SetStateAction, useRef } from 'react'; + +import { Form, Modal } from '@douyinfe/semi-ui'; +import { FormApi } from '@douyinfe/semi-ui/lib/es/form'; + +import type { IWiki } from '@think/domains'; + +import { ICreateWiki, useOwnWikis } from 'data/wiki'; +import { useRouterQuery } from 'hooks/use-router-query'; +import Router from 'next/router'; + +interface IProps { + visible: boolean; + toggleVisible: Dispatch>; +} + +export const WikiCreator: React.FC = ({ visible, toggleVisible }) => { + const $form = useRef(); + const { organizationId } = useRouterQuery<{ organizationId: string }>(); + const { createWiki } = useOwnWikis(organizationId); + + const handleOk = () => { + $form.current.validate().then((values) => { + createWiki(values as ICreateWiki).then((res) => { + toggleVisible(false); + Router.push({ + pathname: `/app/org/[organizationId]/wiki/[wikiId]`, + query: { organizationId: res.organizationId, wikiId: res.id }, + }); + }); + }); + }; + + const handleCancel = () => { + toggleVisible(false); + }; + + return ( + +
($form.current = formApi)}> + + +
+
+ ); +}; diff --git a/packages/client/src/components/wiki/delete/index.tsx b/packages/client/src/components/wiki/delete/index.tsx new file mode 100644 index 0000000..4ba29f8 --- /dev/null +++ b/packages/client/src/components/wiki/delete/index.tsx @@ -0,0 +1,52 @@ +import React, { useCallback } from 'react'; + +import { IconDelete } from '@douyinfe/semi-icons'; +import { Modal, Space, Typography } from '@douyinfe/semi-ui'; + +import { useOwnWikis } from 'data/wiki'; +import { useRouterQuery } from 'hooks/use-router-query'; +import Router from 'next/router'; + +interface IProps { + wikiId: string; + onDelete?: () => void; +} + +const { Text } = Typography; + +export const WikiDeletor: React.FC = ({ wikiId, onDelete, children }) => { + const { organizationId } = useRouterQuery<{ organizationId: string }>(); + const { deletWiki } = useOwnWikis(organizationId); + + const deleteAction = useCallback(() => { + Modal.error({ + title: '确定删除吗?', + content: 删除后不可恢复!, + onOk: () => { + deletWiki(wikiId).then(() => { + onDelete + ? onDelete() + : Router.push({ + pathname: `/app/org/[organizationId]`, + query: { organizationId }, + }); + }); + }, + okButtonProps: { + type: 'danger', + }, + style: { maxWidth: '96vw' }, + }); + }, [organizationId, wikiId, deletWiki, onDelete]); + + return ( + + {children || ( + + + 删除 + + )} + + ); +}; diff --git a/packages/client/src/components/wiki/documents-share/index.module.scss b/packages/client/src/components/wiki/documents-share/index.module.scss new file mode 100644 index 0000000..84d7972 --- /dev/null +++ b/packages/client/src/components/wiki/documents-share/index.module.scss @@ -0,0 +1,58 @@ +/* stylelint-disable */ +.wrap { + margin-top: 5px; +} + +.selectedItem, +.sourceItem { + display: flex; + justify-content: space-between; + align-items: center; + box-sizing: border-box; + height: 36px; + padding: 10px 12px; + + &:hover { + background-color: var(--semi-color-fill-0); + } + + .info { + flex-grow: 1; + margin-left: 8px; + } + + .name { + font-size: 14px; + line-height: 20px; + } + + .email { + font-size: 12px; + line-height: 16px; + color: var(--semi-color-text-2); + } +} + +.selectedItem { + :global { + .semi-icon-close { + color: var(--semi-color-tertiary); + visibility: hidden; + } + } + + &:hover { + :global { + .semi-icon-close { + visibility: visible; + } + } + } +} + +.transferWrap { + margin-top: 16px; + width: 100%; + height: calc(100vh - 268px); + overflow: auto; +} diff --git a/packages/client/src/components/wiki/documents-share/index.tsx b/packages/client/src/components/wiki/documents-share/index.tsx new file mode 100644 index 0000000..388c3c5 --- /dev/null +++ b/packages/client/src/components/wiki/documents-share/index.tsx @@ -0,0 +1,107 @@ +import React, { useCallback, useEffect, useMemo, useState } from 'react'; + +import { IconClose } from '@douyinfe/semi-icons'; +import { Banner, Button, Checkbox, Toast, Transfer, Typography } from '@douyinfe/semi-ui'; + +import { isPublicDocument } from '@think/domains'; + +import { flattenTree2Array } from 'components/wiki/tocs/utils'; +import { useWikiDetail, useWikiTocs } from 'data/wiki'; + +import styles from './index.module.scss'; + +const { Title, Text } = Typography; + +interface IProps { + wikiId: string; +} + +export const WikiDocumentsShare: React.FC = ({ wikiId }) => { + const { toggleStatus: toggleWorkspaceStatus } = useWikiDetail(wikiId); + const { data: tocs } = useWikiTocs(wikiId); + const documents = useMemo( + () => + flattenTree2Array(tocs).map((d) => { + d.label = d.title; + d.value = d.id; + return d; + }), + [tocs] + ); + const [publicDocumentIds, setPublicDocumentIds] = useState([]); // 公开的 + const privateDocumentIds = useMemo(() => { + return documents.filter((doc) => !publicDocumentIds.includes(doc.id)).map((doc) => doc.id); + }, [documents, publicDocumentIds]); + + const submit = () => { + const data = { publicDocumentIds, privateDocumentIds }; + toggleWorkspaceStatus(data).then((res) => { + const ret = res as unknown as any & { + documentOperateMessage?: string; + }; + Toast.success(ret.documentOperateMessage || '操作成功'); + }); + }; + + const renderSourceItem = useCallback((item) => { + return ( +
+ { + item.onChange(); + }} + key={item.label} + checked={item.checked} + > + {item.title} + +
+ ); + }, []); + + const renderSelectedItem = useCallback((item) => { + return ( +
+ {item.title} + +
+ ); + }, []); + + const customFilter = useCallback((sugInput, item) => { + return item.title.includes(sugInput); + }, []); + + useEffect(() => { + if (!documents.length) return; + const activeIds = documents.filter((doc) => isPublicDocument(doc.status)).map((doc) => doc.id); + setPublicDocumentIds(activeIds); + }, [documents]); + + return ( +
+ 在下方进行选择以公开(或取消)文档} + /> +
+ setPublicDocumentIds(values.map((v) => v.id))} + /> +
+ +
+ ); +}; diff --git a/packages/client/src/components/wiki/pin-card/index.module.scss b/packages/client/src/components/wiki/pin-card/index.module.scss new file mode 100644 index 0000000..69d25f4 --- /dev/null +++ b/packages/client/src/components/wiki/pin-card/index.module.scss @@ -0,0 +1,39 @@ +.cardWrap { + width: 100%; + + > a { + display: flex; + width: 100%; + max-height: 260px; + padding: 12px 16px 16px; + margin: 8px 0; + cursor: pointer; + border: 1px solid var(--semi-color-border); + border-radius: 5px; + flex-direction: column; + + > header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 12px; + color: var(--semi-color-primary); + + .rightWrap { + opacity: 0; + } + } + + &:hover { + box-shadow: var(--box-shadow); + + > header .rightWrap { + opacity: 1; + } + } + + > footer { + margin-top: 12px; + } + } +} diff --git a/packages/client/src/components/wiki/pin-card/index.tsx b/packages/client/src/components/wiki/pin-card/index.tsx new file mode 100644 index 0000000..6497466 --- /dev/null +++ b/packages/client/src/components/wiki/pin-card/index.tsx @@ -0,0 +1,82 @@ +import { Avatar, Skeleton, Space, Typography } from '@douyinfe/semi-ui'; + +import { IWiki } from '@think/domains'; + +import { IconDocument } from 'components/icons/IconDocument'; +import { LocaleTime } from 'components/locale-time'; +import { WikiStar } from 'components/wiki/star'; +import Link from 'next/link'; + +import styles from './index.module.scss'; + +const { Text, Paragraph } = Typography; + +export const WikiPinCard: React.FC<{ wiki: IWiki }> = ({ wiki }) => { + return ( + + ); +}; + +export const WikiPinCardPlaceholder = () => { + return ( + + ); +}; diff --git a/packages/client/src/components/wiki/placeholder/index.tsx b/packages/client/src/components/wiki/placeholder/index.tsx new file mode 100644 index 0000000..4a107c3 --- /dev/null +++ b/packages/client/src/components/wiki/placeholder/index.tsx @@ -0,0 +1,22 @@ +import React from 'react'; + +import { Skeleton } from '@douyinfe/semi-ui'; + +export const WorkspacePlaceholder = () => { + const placeholder = ( +
+ + +
+ ); + + return ; +}; diff --git a/packages/client/src/components/wiki/setting/base/index.module.scss b/packages/client/src/components/wiki/setting/base/index.module.scss new file mode 100644 index 0000000..28866ae --- /dev/null +++ b/packages/client/src/components/wiki/setting/base/index.module.scss @@ -0,0 +1,15 @@ +.cover { + margin-bottom: 12px; + + img { + width: 104px; + height: 96px; + border-radius: 4px; + } +} + +@media (max-width: 768px) { + .cover { + width: 100%; + } +} diff --git a/packages/client/src/components/wiki/setting/base/index.tsx b/packages/client/src/components/wiki/setting/base/index.tsx new file mode 100644 index 0000000..42d7f11 --- /dev/null +++ b/packages/client/src/components/wiki/setting/base/index.tsx @@ -0,0 +1,109 @@ +import { useCallback, useEffect, useRef, useState } from 'react'; + +import { Avatar, Button, Form, Toast } from '@douyinfe/semi-ui'; +import { FormApi } from '@douyinfe/semi-ui/lib/es/form'; + +import { WIKI_AVATARS } from '@think/constants'; +import type { IWiki } from '@think/domains'; + +import { ImageUploader } from 'components/image-uploader'; +import { pick } from 'helpers/pick'; + +import styles from './index.module.scss'; + +const images = [ + { + key: 'placeholers', + title: '图库', + images: WIKI_AVATARS, + }, +]; + +type IUpdateWIKI = Partial; + +interface IProps { + wiki: IWiki; + update: (arg: IUpdateWIKI) => Promise; +} + +const getFormValueFromWiki = (wiki) => { + return pick(wiki, ['name', 'description', 'avatar']); +}; + +export const Base: React.FC = ({ wiki, update }) => { + const $form = useRef(); + const [currentCover, setCurrentCover] = useState(''); + + const onSubmit = useCallback(() => { + $form.current.validate().then((values) => { + update(values).then(() => { + Toast.success('操作成功'); + }); + }); + }, [update]); + + const setCover = useCallback((url) => { + $form.current.setValue('avatar', url); + setCurrentCover(url); + }, []); + + useEffect(() => { + if (!wiki) return; + $form.current.setValues(getFormValueFromWiki(wiki)); + setCurrentCover(wiki.avatar); + }, [wiki]); + + return ( +
($form.current = formApi)} + onSubmit={onSubmit} + > + + + +
+ + {wiki && wiki.name.charAt(0)} + +
+ + + +
+
+ +
+
+ ); +}; diff --git a/packages/client/src/components/wiki/setting/import/index.tsx b/packages/client/src/components/wiki/setting/import/index.tsx new file mode 100644 index 0000000..f74b0ee --- /dev/null +++ b/packages/client/src/components/wiki/setting/import/index.tsx @@ -0,0 +1,121 @@ +import { useCallback, useEffect, useRef, useState } from 'react'; + +import { Button, Toast, Typography, Upload } from '@douyinfe/semi-ui'; + +import type { IWiki } from '@think/domains'; + +import { useCreateDocument } from 'data/document'; +import { useRouterQuery } from 'hooks/use-router-query'; +import { useToggle } from 'hooks/use-toggle'; + +import { createMarkdownParser, MarkdownParse } from './parser'; + +interface IProps { + wikiId: IWiki['id']; +} + +const { Text } = Typography; + +export const Import: React.FC = ({ wikiId }) => { + const { create } = useCreateDocument(); + const { organizationId } = useRouterQuery<{ organizationId: string }>(); + const $upload = useRef(); + const [loading, toggleLoading] = useToggle(false); + const [markdownParser, setMarkdownParser] = useState(); + const [fileList, setFileList] = useState([]); + + const handleFile = useCallback(({ fileList: files }) => { + if (!files.length) return; + + files.forEach((file) => { + const fileName = file.fileInstance.name; + + const fileReader = new FileReader(); + fileReader.onload = function () { + setFileList((fileList) => { + if (fileList.find((file) => file.name === fileName)) return fileList; + return fileList.concat({ ...file, text: fileReader.result }); + }); + }; + + fileReader.readAsText(file.fileInstance); + }); + + return false; + }, []); + + const removeFile = useCallback((currentFile) => { + setFileList((fileList) => { + return fileList.filter((file) => file.name !== currentFile.name); + }); + }, []); + + const importFile = useCallback(() => { + if (!markdownParser) return; + + const total = fileList.length; + let success = 0; + let failed = 0; + + toggleLoading(true); + + for (const file of fileList) { + const payload = markdownParser.parse(file.name, file.text); + create({ ...payload, organizationId, wikiId }) + .then(() => { + success += 1; + }) + .catch(() => { + failed += 1; + }) + .finally(() => { + if (success + failed === total) { + $upload.current.clear(); + toggleLoading(false); + setFileList([]); + + if (failed > 0) { + Toast.error('部分文件导入失败,请重新尝试导入!'); + } else { + Toast.success('导入成功'); + } + } + }); + } + }, [markdownParser, fileList, toggleLoading, create, organizationId, wikiId]); + + useEffect(() => { + const markdownParser = createMarkdownParser(); + setMarkdownParser(markdownParser); + + return () => { + markdownParser.destroy(); + }; + }, []); + + return ( +
+ 点击上传文件或拖拽文件到这里} + dragSubText={仅支持 Markdown 文件导入} + onRemove={removeFile} + /> + + +
+ ); +}; diff --git a/packages/client/src/components/wiki/setting/import/parser.tsx b/packages/client/src/components/wiki/setting/import/parser.tsx new file mode 100644 index 0000000..324a795 --- /dev/null +++ b/packages/client/src/components/wiki/setting/import/parser.tsx @@ -0,0 +1,58 @@ +import { Toast } from '@douyinfe/semi-ui'; + +import { createEditor } from 'tiptap/core'; +import { AllExtensions } from 'tiptap/core/all-kit'; +import { Collaboration } from 'tiptap/core/extensions/collaboration'; +import { prosemirrorJSONToYDoc } from 'tiptap/core/thritypart/y-prosemirror/y-prosemirror'; +import { markdownToProsemirror } from 'tiptap/markdown/markdown-to-prosemirror'; + +import { safeJSONStringify } from 'helpers/json'; +import * as Y from 'yjs'; + +export interface MarkdownParse { + parse: (filename: string, markdown: string) => { title: string; content: string; state: Buffer }; + destroy: () => void; +} + +export const createMarkdownParser = () => { + const ydoc = new Y.Doc(); + const editor = createEditor({ + editable: false, + extensions: AllExtensions.concat(Collaboration.configure({ document: ydoc })), + content: '', + }); + + const parse = (filename: string, markdown: string) => { + try { + const prosemirrorNode = markdownToProsemirror({ + editor, + schema: editor.schema, + content: markdown, + needTitle: true, + defaultTitle: filename.replace(/\.md$/gi, ''), + }); + + const title = prosemirrorNode.content[0].content[0].text; + editor.commands.setContent(prosemirrorNode); + Y.applyUpdate(ydoc, Y.encodeStateAsUpdate(prosemirrorJSONToYDoc(editor.schema, prosemirrorNode))); + const state = Y.encodeStateAsUpdate(ydoc); + + return { + title, + content: safeJSONStringify({ default: prosemirrorNode }), + state: Buffer.from(state), + }; + } catch (e) { + console.error(e.message, e.stack); + Toast.error('文件内容解析失败,请打开控制台,截图错误信息,请到 Github 提 issue 寻求解决!'); + throw e; + } + }; + + const destroy = () => { + ydoc.destroy(); + editor.destroy(); + }; + + return { parse, destroy } as MarkdownParse; +}; diff --git a/packages/client/src/components/wiki/setting/index.tsx b/packages/client/src/components/wiki/setting/index.tsx new file mode 100644 index 0000000..ba86e6a --- /dev/null +++ b/packages/client/src/components/wiki/setting/index.tsx @@ -0,0 +1,67 @@ +import React from 'react'; + +import { TabPane, Tabs } from '@douyinfe/semi-ui'; + +import { IWiki } from '@think/domains'; + +import { Seo } from 'components/seo'; +import { WikiTocsManager } from 'components/wiki/tocs/manager'; +import { useWikiDetail } from 'data/wiki'; + +import { Base } from './base'; +import { Import } from './import'; +import { More } from './more'; +import { Privacy } from './privacy'; +import { Users } from './users'; + +interface IProps { + wikiId: IWiki['id']; + tab?: string; + onNavigate: (arg: string) => void; +} + +const TitleMap = { + base: '基础信息', + privacy: '隐私管理', + tocs: '目录管理', + share: '隐私管理', + documents: '全部文档', + users: '成员管理', + import: '导入文档', + more: '更多', +}; + +export const WikiSetting: React.FC = ({ wikiId, tab, onNavigate }) => { + const { data, update } = useWikiDetail(wikiId); + + return ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/packages/client/src/components/wiki/setting/more/index.tsx b/packages/client/src/components/wiki/setting/more/index.tsx new file mode 100644 index 0000000..3d15480 --- /dev/null +++ b/packages/client/src/components/wiki/setting/more/index.tsx @@ -0,0 +1,28 @@ +import { Banner, Button, Typography } from '@douyinfe/semi-ui'; + +import { WikiDeletor } from 'components/wiki/delete'; + +interface IProps { + wikiId: string; +} + +const { Paragraph } = Typography; + +export const More: React.FC = ({ wikiId }) => { + return ( +
+ 删除知识库及内部所有文档,不可恢复!} + style={{ marginBottom: 16 }} + /> + + + +
+ ); +}; diff --git a/packages/client/src/components/wiki/setting/privacy/index.module.scss b/packages/client/src/components/wiki/setting/privacy/index.module.scss new file mode 100644 index 0000000..7e0411e --- /dev/null +++ b/packages/client/src/components/wiki/setting/privacy/index.module.scss @@ -0,0 +1,64 @@ +/* stylelint-disable */ +.statusWrap { + padding: 10px 12px; + margin-top: 16px; + border: 1px solid var(--semi-color-border); + border-radius: 4px; + + .title { + margin-bottom: 16px; + } +} + +.selectedItem { + :global { + .semi-icon-close { + color: var(--semi-color-tertiary); + visibility: hidden; + } + } + + &:hover { + :global { + .semi-icon-close { + visibility: visible; + } + } + } +} + +.selectedItem, +.sourceItem { + display: flex; + height: 36px; + padding: 10px 12px; + box-sizing: border-box; + align-items: center; + justify-content: space-between; + + &:hover { + background-color: var(--semi-color-fill-0); + } + + .info { + margin-left: 8px; + flex-grow: 1; + } + + .name { + font-size: 14px; + line-height: 20px; + } + + .email { + font-size: 12px; + line-height: 16px; + color: var(--semi-color-text-2); + } +} + +.transferWrap { + width: 100%; + margin-top: 16px; + overflow: auto; +} diff --git a/packages/client/src/components/wiki/setting/privacy/index.tsx b/packages/client/src/components/wiki/setting/privacy/index.tsx new file mode 100644 index 0000000..aa523b5 --- /dev/null +++ b/packages/client/src/components/wiki/setting/privacy/index.tsx @@ -0,0 +1,163 @@ +import React, { useCallback, useEffect, useMemo, useState } from 'react'; + +import { IconClose } from '@douyinfe/semi-icons'; +import { Banner, Button, Checkbox, Radio, RadioGroup, Toast, Transfer, Typography } from '@douyinfe/semi-ui'; + +import { isPublicDocument, isPublicWiki, WIKI_STATUS_LIST } from '@think/domains'; + +import { flattenTree2Array } from 'components/wiki/tocs/utils'; +import { useWikiDetail, useWikiTocs } from 'data/wiki'; +import { buildUrl } from 'helpers/url'; + +import styles from './index.module.scss'; + +const { Text, Title } = Typography; + +interface IProps { + wikiId: string; +} + +export const Privacy: React.FC = ({ wikiId }) => { + const { data: wiki, toggleStatus: toggleWorkspaceStatus } = useWikiDetail(wikiId); + const { data: tocs } = useWikiTocs(wikiId); + + const [nextStatus, setNextStatus] = useState(''); + const isPublic = useMemo(() => wiki && isPublicWiki(wiki.status), [wiki]); + + const documents = useMemo( + () => + flattenTree2Array(tocs) + .sort((a, b) => a.index - b.index) + .map((d) => { + d.label = d.title; + d.value = d.id; + return d; + }), + [tocs] + ); + const [publicDocumentIds, setPublicDocumentIds] = useState([]); // 公开的 + const privateDocumentIds = useMemo(() => { + return documents.filter((doc) => !publicDocumentIds.includes(doc.id)).map((doc) => doc.id); + }, [documents, publicDocumentIds]); + + const renderSourceItem = useCallback((item) => { + return ( +
+ { + item.onChange(); + }} + key={item.label} + checked={item.checked} + > + {item.title} + +
+ ); + }, []); + + const renderSelectedItem = useCallback((item) => { + return ( +
+ {item.title} + +
+ ); + }, []); + + const customFilter = useCallback((sugInput, item) => { + return item.title.includes(sugInput); + }, []); + + useEffect(() => { + if (!documents.length) return; + const activeIds = documents.filter((doc) => isPublicDocument(doc.status)).map((doc) => doc.id); + setPublicDocumentIds(activeIds); + }, [documents]); + + const submit = () => { + const data = { nextStatus, publicDocumentIds, privateDocumentIds }; + + toggleWorkspaceStatus(data).then((res) => { + const ret = res as unknown as any & { + documentOperateMessage?: string; + }; + Toast.success(ret.documentOperateMessage || '操作成功'); + }); + }; + + useEffect(() => { + if (!wiki) return; + setNextStatus(wiki.status); + }, [wiki]); + + return ( +
+ {isPublic && ( + 当前知识库已经公开
} + description={ + isPublic && ( +
+ 您可以点击该链接进行查看: + + 知识库 + +
+ ) + } + /> + )} + +
+ + 是否公开知识库? + + setNextStatus(e.target.value)}> + {WIKI_STATUS_LIST.map((status) => { + return ( + + {status.label} + + ); + })} + +
+ +
+ setPublicDocumentIds(values.map((v) => v.id))} + /> +
+ + + + ); +}; diff --git a/packages/client/src/components/wiki/setting/users/index.tsx b/packages/client/src/components/wiki/setting/users/index.tsx new file mode 100644 index 0000000..71f0219 --- /dev/null +++ b/packages/client/src/components/wiki/setting/users/index.tsx @@ -0,0 +1,18 @@ +import React from 'react'; + +import { Members } from 'components/members'; +import { useWikiMembers } from 'data/wiki'; + +interface IProps { + wikiId: string; +} + +export const Users: React.FC = ({ wikiId }) => { + return ( + + ); +}; diff --git a/packages/client/src/components/wiki/star/index.tsx b/packages/client/src/components/wiki/star/index.tsx new file mode 100644 index 0000000..286a201 --- /dev/null +++ b/packages/client/src/components/wiki/star/index.tsx @@ -0,0 +1,43 @@ +import React from 'react'; + +import { IconStar } from '@douyinfe/semi-icons'; +import { Button, Tooltip } from '@douyinfe/semi-ui'; + +import { IOrganization, IWiki } from '@think/domains'; + +import { useWikiStarToggle } from 'data/star'; + +interface IProps { + organizationId: IOrganization['id']; + wikiId: IWiki['id']; + render?: (arg: { star: boolean; text: string; toggleStar: () => Promise }) => React.ReactNode; + onChange?: () => void; +} + +export const WikiStar: React.FC = ({ organizationId, wikiId, render, onChange }) => { + const { data, toggle } = useWikiStarToggle(organizationId, wikiId); + const text = data ? '取消收藏' : '收藏知识库'; + + return ( + <> + {render ? ( + render({ star: data, toggleStar: toggle, text }) + ) : ( + + + + + ); +}; diff --git a/packages/client/src/components/wiki/tocs/nav-item.tsx b/packages/client/src/components/wiki/tocs/nav-item.tsx new file mode 100644 index 0000000..ba5d2c8 --- /dev/null +++ b/packages/client/src/components/wiki/tocs/nav-item.tsx @@ -0,0 +1,58 @@ +import React from 'react'; + +import cls from 'classnames'; +import Link from 'next/link'; +import type { UrlObject } from 'url'; + +import styles from './index.module.scss'; + +interface IProps { + icon: React.ReactNode; + text: React.ReactNode; + rightNode?: React.ReactNode; + href?: { + pathname: string; + query: Record; + }; + isActive?: boolean; + hoverable?: boolean; + openNewTab?: boolean; +} + +const marginTopStyle = { marginTop: 4 }; + +export const NavItem: React.FC = ({ + icon, + text, + rightNode, + href, + isActive = false, + hoverable = true, + openNewTab = false, +}) => { + const right = rightNode ? {rightNode} : null; + const content = ( + <> + {icon} + {text} + + ); + + return ( +
+ {href ? ( + + + {content} + + + ) : ( +
{content}
+ )} + {right} +
+ ); +}; diff --git a/packages/client/src/components/wiki/tocs/public.tsx b/packages/client/src/components/wiki/tocs/public.tsx new file mode 100644 index 0000000..9094cb0 --- /dev/null +++ b/packages/client/src/components/wiki/tocs/public.tsx @@ -0,0 +1,136 @@ +import React from 'react'; + +import { IconPlus } from '@douyinfe/semi-icons'; +import { Avatar, Skeleton, Space, Typography } from '@douyinfe/semi-ui'; + +import { IDocument } from '@think/domains'; + +import { DataRender } from 'components/data-render'; +import { IconOverview } from 'components/icons'; +import { LogoImage, LogoText } from 'components/logo'; +import { Seo } from 'components/seo'; +import { usePublicWikiDetail, usePublicWikiTocs } from 'data/wiki'; +import { useRouter } from 'next/router'; + +import { NavItem } from './nav-item'; +import { Tree } from './tree'; + +import styles from './index.module.scss'; + +interface IProps { + wikiId: string; + docAsLink?: string; + getDocLink?: (arg: IDocument) => string; + pageTitle: string; +} + +const { Text } = Typography; + +const defaultGetDocLink = (document) => `/share/wiki/${document.wikiId}/document/${document.id}`; + +export const WikiPublicTocs: React.FC = ({ + pageTitle, + wikiId, + docAsLink = '/share/wiki/[wikiId]/document/[documentId]', + getDocLink = defaultGetDocLink, +}) => { + const { pathname } = useRouter(); + const { data: wiki, loading: wikiLoading, error: wikiError } = usePublicWikiDetail(wikiId); + const { data: tocs, loading: tocsLoading, error: tocsError } = usePublicWikiTocs(wikiId); + + return ( +
+
+
+
+ + + +
+
+ + + } + text={} + /> + } + error={wikiError} + normalContent={() => ( + <> + + + {wiki.name.charAt(0)} + + } + text={{wiki.name}} + hoverable={false} + /> + + )} + /> + + } + text={'概述'} + href={{ + pathname: `/share/wiki/[wikiId]`, + query: { wikiId }, + }} + isActive={pathname === '/share/wiki/[wikiId]'} + /> +
+ +
+
+ + } + text={} + rightNode={} + /> + } + error={tocsError} + normalContent={() => } + /> +
+
+
+ ); +}; diff --git a/packages/client/src/components/wiki/tocs/tree.tsx b/packages/client/src/components/wiki/tocs/tree.tsx new file mode 100644 index 0000000..32d936a --- /dev/null +++ b/packages/client/src/components/wiki/tocs/tree.tsx @@ -0,0 +1,160 @@ +import React, { useCallback, useEffect, useRef, useState } from 'react'; + +import { IconPlus } from '@douyinfe/semi-icons'; +import { Button, Tree as SemiTree, Typography } from '@douyinfe/semi-ui'; + +import { DocumentActions } from 'components/document/actions'; +import { DocumentCreator as DocumentCreatorForm } from 'components/document/create'; +import deepEqual from 'deep-equal'; +import { CREATE_DOCUMENT, event, triggerCreateDocument } from 'event'; +import { useToggle } from 'hooks/use-toggle'; +import Link from 'next/link'; +import { useRouter } from 'next/router'; +import scrollIntoView from 'scroll-into-view-if-needed'; + +import { findParents } from './utils'; + +import styles from './index.module.scss'; + +const Actions = ({ node }) => { + const createDocument = useCallback( + (e) => { + e.stopPropagation(); + triggerCreateDocument({ wikiId: node.wikiId, documentId: node.id }); + }, + [node.wikiId, node.id] + ); + + return ( + + + + )} + + + + } + > + ) : ( + + )} + + ); +}; diff --git a/packages/client/src/layouts/single-column/index.module.scss b/packages/client/src/layouts/single-column/index.module.scss new file mode 100644 index 0000000..b6baeac --- /dev/null +++ b/packages/client/src/layouts/single-column/index.module.scss @@ -0,0 +1,11 @@ +.wrap { + display: flex; + flex-direction: column; + height: 100%; + background-color: var(--semi-color-nav-bg); + + .contentWrap { + flex: 1; + overflow: auto; + } +} diff --git a/packages/client/src/layouts/single-column/index.tsx b/packages/client/src/layouts/single-column/index.tsx new file mode 100644 index 0000000..4ec319e --- /dev/null +++ b/packages/client/src/layouts/single-column/index.tsx @@ -0,0 +1,27 @@ +import React from 'react'; + +import { Layout as SemiLayout } from '@douyinfe/semi-ui'; + +import { RouterHeader } from '../router-header'; + +import styles from './index.module.scss'; + +const { Content } = SemiLayout; + +const style = { + padding: '16px 24px', + backgroundColor: 'var(--semi-color-bg-0)', +}; + +export const SingleColumnLayout: React.FC = ({ children }) => { + return ( + + + + +
{children}
+
+
+
+ ); +}; diff --git a/packages/client/src/pages/_app.tsx b/packages/client/src/pages/_app.tsx new file mode 100644 index 0000000..444df2e --- /dev/null +++ b/packages/client/src/pages/_app.tsx @@ -0,0 +1,119 @@ +import '@react-pdf-viewer/core/lib/styles/index.css'; +import '@react-pdf-viewer/default-layout/lib/styles/index.css'; +import { Worker } from '@react-pdf-viewer/core'; +import React from 'react'; +import { Hydrate, QueryClient, QueryClientProvider } from 'react-query'; + +import 'tiptap/fix-match-nodes'; +import 'tiptap/core/styles/index.scss'; +import { preloadTiptapResources } from 'tiptap/preload'; + +import { isMobile } from 'helpers/env'; +import { DocumentVersionControl } from 'hooks/use-document-version'; +import { IsOnMobile } from 'hooks/use-on-mobile'; +import { IRuntimeConfig, RuntimeConfig } from 'hooks/use-runtime-config'; +import { Theme } from 'hooks/use-theme'; +import App from 'next/app'; +import Head from 'next/head'; + +import 'viewerjs/dist/viewer.css'; +import 'styles/globals.scss'; +import 'thirtypart/array-prototype-at'; + +class MyApp extends App<{ isMobile: boolean; runtimeConfig: IRuntimeConfig }> { + state = { + queryClient: new QueryClient({ + defaultOptions: { + queries: { + refetchOnMount: true, + refetchOnWindowFocus: true, + retry: false, + staleTime: 10 * 1000, // 默认 10s 数据过期 + }, + }, + }), + }; + + static getInitialProps = async ({ Component, ctx }) => { + const request = ctx?.req; + const getPagePropsPromise = Component.getInitialProps ? Component.getInitialProps(ctx) : Promise.resolve({}); + const [pageProps, runtimeConfig] = await Promise.all([ + getPagePropsPromise, + fetch(`${process.env.SITE_URL}/api/config`).then((res) => { + return res.json(); + }), + ]).catch((err) => { + return [{}, {}]; + }); + + return { + pageProps, + isMobile: isMobile(request?.headers['user-agent']), + runtimeConfig, + }; + }; + + componentDidMount() { + Promise.all([ + import('resize-observer-polyfill'), + // @ts-ignore + import('requestidlecallback-polyfill'), + ]).then(() => { + preloadTiptapResources(); + }); + } + + render() { + const { Component, pageProps, isMobile, runtimeConfig } = this.props; + const { queryClient } = this.state; + + return ( + <> + + + + + + + + + + + + + + + + + + + + + {((process.env.DNS_PREFETCH || []) as string[]).map((url) => ( + + ))} + + + + + + + + + + + + + + + + + + ); + } +} + +export default MyApp; diff --git a/packages/client/src/pages/admin/index.module.scss b/packages/client/src/pages/admin/index.module.scss new file mode 100644 index 0000000..4708e1b --- /dev/null +++ b/packages/client/src/pages/admin/index.module.scss @@ -0,0 +1,12 @@ +.wikiItemWrap { + padding: 12px 16px !important; + margin: 8px 2px; + cursor: pointer; + background-color: var(--semi-color-bg-2); + border: 1px solid var(--semi-color-border) !important; +} + +.titleWrap { + display: flex; + justify-content: space-between; +} diff --git a/packages/client/src/pages/admin/index.tsx b/packages/client/src/pages/admin/index.tsx new file mode 100644 index 0000000..da72ebf --- /dev/null +++ b/packages/client/src/pages/admin/index.tsx @@ -0,0 +1,58 @@ +import React, { useCallback } from 'react'; + +import { Banner, Typography } from '@douyinfe/semi-ui'; + +import { SystemConfig } from 'components/admin/system-config'; +import { Seo } from 'components/seo'; +import { useUser } from 'data/user'; +import { Forbidden } from 'illustrations/forbidden'; +import { SingleColumnLayout } from 'layouts/single-column'; +import type { NextPage } from 'next'; +import Router, { useRouter } from 'next/router'; + +import styles from './index.module.scss'; + +const { Title, Text } = Typography; + +const Page: NextPage = () => { + const { user } = useUser(); + const { query = {} } = useRouter(); + const { tab = 'base' } = query as { + tab?: string; + }; + + const navigate = useCallback((tab = 'base') => { + Router.push({ + pathname: `/admin`, + query: { tab }, + }); + }, []); + + return ( + + +
+ {user && user.isSystemAdmin ? ( + <> +
+ + 管理后台 + +
+ + + + ) : ( +
+ + + 无权限查看 + +
+ )} +
+
+ ); +}; + +export default Page; diff --git a/packages/client/src/pages/api/config.ts b/packages/client/src/pages/api/config.ts new file mode 100644 index 0000000..a281daa --- /dev/null +++ b/packages/client/src/pages/api/config.ts @@ -0,0 +1,7 @@ +import { getRuntimeConfig } from '@think/config'; + +import type { NextApiRequest, NextApiResponse } from 'next'; + +export default function handler(req: NextApiRequest, res: NextApiResponse>) { + res.status(200).json(getRuntimeConfig() as Record); +} diff --git a/packages/client/src/pages/app/index.tsx b/packages/client/src/pages/app/index.tsx new file mode 100644 index 0000000..fd4f5ea --- /dev/null +++ b/packages/client/src/pages/app/index.tsx @@ -0,0 +1,109 @@ +import { useCallback, useEffect } from 'react'; + +import { Avatar, Button, Table, Typography } from '@douyinfe/semi-ui'; + +import { IOrganization } from '@think/domains'; + +import { DataRender } from 'components/data-render'; +import { LocaleTime } from 'components/locale-time'; +import { Seo } from 'components/seo'; +import { usePeronalOrganization, useUserOrganizations } from 'data/organization'; +import { SingleColumnLayout } from 'layouts/single-column'; +import Link from 'next/link'; +import Router from 'next/router'; + +const { Title, Paragraph } = Typography; +const { Column } = Table; + +const Page = () => { + const { data: organization } = usePeronalOrganization(); + const { + data: userOrganizations, + loading: userOrganizationsLoading, + error: userOrganizationsError, + } = useUserOrganizations(); + + const gotoCreate = useCallback(() => { + Router.push({ + pathname: '/app/org/create', + }); + }, []); + + useEffect(() => { + if (userOrganizations && userOrganizations.length) return; + if (!organization) return; + + Router.replace({ + pathname: `/app/org/[organizationId]`, + query: { organizationId: organization.id }, + }); + }, [organization, userOrganizations]); + + return ( + + +
+
+ + 组织列表 + + +
+ ( + <> + + { + return ( + + + + + + {org.name} + + + + + ); + }} + /> + } + /> +
+ + )} + /> +
+
+ ); +}; + +export default Page; diff --git a/packages/client/src/pages/app/org/[organizationId]/index.module.scss b/packages/client/src/pages/app/org/[organizationId]/index.module.scss new file mode 100644 index 0000000..4708e1b --- /dev/null +++ b/packages/client/src/pages/app/org/[organizationId]/index.module.scss @@ -0,0 +1,12 @@ +.wikiItemWrap { + padding: 12px 16px !important; + margin: 8px 2px; + cursor: pointer; + background-color: var(--semi-color-bg-2); + border: 1px solid var(--semi-color-border) !important; +} + +.titleWrap { + display: flex; + justify-content: space-between; +} diff --git a/packages/client/src/pages/app/org/[organizationId]/index.tsx b/packages/client/src/pages/app/org/[organizationId]/index.tsx new file mode 100644 index 0000000..b047ceb --- /dev/null +++ b/packages/client/src/pages/app/org/[organizationId]/index.tsx @@ -0,0 +1,203 @@ +import React, { useEffect, useMemo } from 'react'; + +import { Avatar, Button, List, Table, Typography } from '@douyinfe/semi-ui'; + +import { DocumentApiDefinition, IDocument, IOrganization, StarApiDefinition } from '@think/domains'; + +import { DataRender } from 'components/data-render'; +import { DocumentActions } from 'components/document/actions'; +import { Empty } from 'components/empty'; +import { LocaleTime } from 'components/locale-time'; +import { Seo } from 'components/seo'; +import { WikiCreator } from 'components/wiki/create'; +import { WikiPinCard, WikiPinCardPlaceholder } from 'components/wiki/pin-card'; +import { getRecentVisitedDocuments, useRecentDocuments } from 'data/document'; +import { getStarWikisInOrganization, useStarWikisInOrganization } from 'data/star'; +import { useRouterQuery } from 'hooks/use-router-query'; +import { useToggle } from 'hooks/use-toggle'; +import { AppSingleColumnLayout } from 'layouts/app-single-column'; +import type { NextPage } from 'next'; +import Link from 'next/link'; +import { serverPrefetcher } from 'services/server-prefetcher'; + +import styles from './index.module.scss'; + +const { Title } = Typography; +const { Column } = Table; + +const grid = { + gutter: 16, + xs: 24, + sm: 12, + md: 12, + lg: 8, + xl: 8, +}; + +const RecentDocs = () => { + const { organizationId } = useRouterQuery<{ organizationId: string }>(); + const { data, error, loading, refresh } = useRecentDocuments(organizationId); + + const columns = useMemo( + () => [ + { + return ( + + {document.title} + + ); + }} + />, + , + { + return ( + + + {createUser.name.slice(0, 1)} + + {createUser.name} + + ); + }} + />, + } + />, + ( + + )} + />, + ], + [refresh] + ); + + useEffect(() => { + refresh(); + }, [refresh]); + + return ( + <> + + 最近访问 + + + {columns} + + } + error={error} + normalContent={() => + data && data.length ? ( + + {columns} +
+ ) : ( + + ) + } + /> + + ); +}; + +const Page: NextPage<{ organizationId: IOrganization['id'] }> = ({ organizationId }) => { + const [visible, toggleVisible] = useToggle(false); + const { data: staredWikis, loading, error, refresh } = useStarWikisInOrganization(organizationId); + + return ( + + +
+
+ + 快捷访问 + + <> + + + +
+ ( + ( + + + + )} + /> + )} + error={error} + normalContent={() => ( + ( + + + + )} + emptyContent={} + /> + )} + /> + +
+
+ ); +}; + +Page.getInitialProps = async (ctx) => { + const { organizationId } = ctx.query; + + const props = await serverPrefetcher(ctx, [ + { + url: StarApiDefinition.getStarWikisInOrganization.client(organizationId), + action: (cookie) => getStarWikisInOrganization(organizationId, cookie), + }, + { + url: DocumentApiDefinition.recent.client(organizationId), + action: (cookie) => getRecentVisitedDocuments(organizationId, cookie), + }, + ]); + return { ...props, organizationId } as any; +}; + +export default Page; diff --git a/packages/client/src/pages/app/org/[organizationId]/setting/index.tsx b/packages/client/src/pages/app/org/[organizationId]/setting/index.tsx new file mode 100644 index 0000000..29813dd --- /dev/null +++ b/packages/client/src/pages/app/org/[organizationId]/setting/index.tsx @@ -0,0 +1,53 @@ +import React, { useCallback } from 'react'; + +import { Typography } from '@douyinfe/semi-ui'; + +import { IOrganization } from '@think/domains'; + +import { OrganizationSetting } from 'components/organization/setting'; +import { AppSingleColumnLayout } from 'layouts/app-single-column'; +import { NextPage } from 'next'; +import Router, { useRouter } from 'next/router'; + +interface IProps { + organizationId: IOrganization['id']; +} + +const { Title } = Typography; + +const Page: NextPage = ({ organizationId }) => { + const { query = {} } = useRouter(); + const { tab = 'base' } = query as { + tab?: string; + }; + + const navigate = useCallback( + (tab = 'base') => { + Router.push({ + pathname: `/app/org/[organizationId]/setting`, + query: { organizationId, tab }, + }); + }, + [organizationId] + ); + + return ( + +
+
+ + 组织设置 + +
+ +
+
+ ); +}; + +Page.getInitialProps = async (ctx) => { + const { organizationId } = ctx.query; + return { organizationId } as IProps; +}; + +export default Page; diff --git a/packages/client/src/pages/app/org/[organizationId]/star/index.module.scss b/packages/client/src/pages/app/org/[organizationId]/star/index.module.scss new file mode 100644 index 0000000..4708e1b --- /dev/null +++ b/packages/client/src/pages/app/org/[organizationId]/star/index.module.scss @@ -0,0 +1,12 @@ +.wikiItemWrap { + padding: 12px 16px !important; + margin: 8px 2px; + cursor: pointer; + background-color: var(--semi-color-bg-2); + border: 1px solid var(--semi-color-border) !important; +} + +.titleWrap { + display: flex; + justify-content: space-between; +} diff --git a/packages/client/src/pages/app/org/[organizationId]/star/index.tsx b/packages/client/src/pages/app/org/[organizationId]/star/index.tsx new file mode 100644 index 0000000..ab4df03 --- /dev/null +++ b/packages/client/src/pages/app/org/[organizationId]/star/index.tsx @@ -0,0 +1,145 @@ +import React from 'react'; + +import { List, Typography } from '@douyinfe/semi-ui'; + +import { StarApiDefinition } from '@think/domains'; + +import { DataRender } from 'components/data-render'; +import { DocumentCard, DocumentCardPlaceholder } from 'components/document/card'; +import { Empty } from 'components/empty'; +import { Seo } from 'components/seo'; +import { WikiCard, WikiCardPlaceholder } from 'components/wiki/card'; +import { + getStarDocumentsInOrganization, + getStarWikisInOrganization, + useStarDocumentsInOrganization, + useStarWikisInOrganization, +} from 'data/star'; +import { useRouterQuery } from 'hooks/use-router-query'; +import { AppSingleColumnLayout } from 'layouts/app-single-column'; +import type { NextPage } from 'next'; +import { serverPrefetcher } from 'services/server-prefetcher'; + +import styles from './index.module.scss'; + +const { Title } = Typography; + +const grid = { + gutter: 16, + xs: 24, + sm: 12, + md: 12, + lg: 8, + xl: 8, +}; + +const StarDocs = () => { + const { organizationId } = useRouterQuery<{ organizationId: string }>(); + const { data: docs, loading, error } = useStarDocumentsInOrganization(organizationId); + + return ( + ( + ( + + + + )} + /> + )} + error={error} + normalContent={() => ( + ( + + + + )} + emptyContent={} + /> + )} + /> + ); +}; + +const StarWikis = () => { + const { organizationId } = useRouterQuery<{ organizationId: string }>(); + const { data, loading, error } = useStarWikisInOrganization(organizationId); + + return ( + ( + ( + + + + )} + /> + )} + error={error} + normalContent={() => ( + ( + + + + )} + emptyContent={} + /> + )} + /> + ); +}; + +const Page: NextPage = () => { + return ( + + +
+
+ + 知识库 + +
+ + +
+ + 文档 + +
+ +
+
+ ); +}; + +Page.getInitialProps = async (ctx) => { + const { organizationId } = ctx.query; + + const props = await serverPrefetcher(ctx, [ + { + url: StarApiDefinition.getStarWikisInOrganization.client(organizationId), + action: (cookie) => getStarWikisInOrganization(organizationId, cookie), + }, + { + url: StarApiDefinition.getStarDocumentsInOrganization.client(organizationId), + action: (cookie) => getStarDocumentsInOrganization(organizationId, cookie), + }, + ]); + return props; +}; + +export default Page; diff --git a/packages/client/src/pages/app/org/[organizationId]/wiki/[wikiId]/doc/[documentId]/edit/index.tsx b/packages/client/src/pages/app/org/[organizationId]/wiki/[wikiId]/doc/[documentId]/edit/index.tsx new file mode 100644 index 0000000..846159c --- /dev/null +++ b/packages/client/src/pages/app/org/[organizationId]/wiki/[wikiId]/doc/[documentId]/edit/index.tsx @@ -0,0 +1,31 @@ +import React from 'react'; + +import { DocumentApiDefinition, IDocument } from '@think/domains'; + +import { DocumentEditor } from 'components/document/editor'; +import { getDocumentDetail } from 'data/document'; +import { NextPage } from 'next'; +import { serverPrefetcher } from 'services/server-prefetcher'; + +interface IProps { + wikiId: string; + documentId: string; +} + +const Page: NextPage = ({ wikiId, documentId }) => { + return ; +}; + +Page.getInitialProps = async (ctx) => { + const { wikiId, documentId } = ctx.query; + + const res = await serverPrefetcher(ctx, [ + { + url: DocumentApiDefinition.getDetailById.client(documentId as IDocument['id']), + action: (cookie) => getDocumentDetail(documentId, cookie), + }, + ]); + return { ...res, wikiId, documentId } as IProps; +}; + +export default Page; diff --git a/packages/client/src/pages/app/org/[organizationId]/wiki/[wikiId]/doc/[documentId]/index.tsx b/packages/client/src/pages/app/org/[organizationId]/wiki/[wikiId]/doc/[documentId]/index.tsx new file mode 100644 index 0000000..083746b --- /dev/null +++ b/packages/client/src/pages/app/org/[organizationId]/wiki/[wikiId]/doc/[documentId]/index.tsx @@ -0,0 +1,43 @@ +import React from 'react'; + +import { DocumentApiDefinition, IDocument, IWiki, WikiApiDefinition } from '@think/domains'; + +import { DocumentReader } from 'components/document/reader'; +import { WikiTocs } from 'components/wiki/tocs'; +import { getDocumentDetail } from 'data/document'; +import { getWikiTocs } from 'data/wiki'; +import { AppDoubleColumnLayout } from 'layouts/app-double-column'; +import { NextPage } from 'next'; +import { serverPrefetcher } from 'services/server-prefetcher'; + +interface IProps { + wikiId: string; + documentId: string; +} + +const Page: NextPage = ({ wikiId, documentId }) => { + return ( + } + rightNode={} + /> + ); +}; + +Page.getInitialProps = async (ctx) => { + const { wikiId, documentId } = ctx.query; + + const res = await serverPrefetcher(ctx, [ + { + url: WikiApiDefinition.getTocsById.client(wikiId as IWiki['id']), + action: (cookie) => getWikiTocs(wikiId, cookie), + }, + { + url: DocumentApiDefinition.getDetailById.client(documentId as IDocument['id']), + action: (cookie) => getDocumentDetail(documentId, cookie), + }, + ]); + return { ...res, wikiId, documentId } as IProps; +}; + +export default Page; diff --git a/packages/client/src/pages/app/org/[organizationId]/wiki/[wikiId]/index.module.scss b/packages/client/src/pages/app/org/[organizationId]/wiki/[wikiId]/index.module.scss new file mode 100644 index 0000000..e619ac7 --- /dev/null +++ b/packages/client/src/pages/app/org/[organizationId]/wiki/[wikiId]/index.module.scss @@ -0,0 +1,41 @@ +.navItemWrap { + padding: 0 0.5rem; + + .navItem { + display: flex; + width: 100%; + height: 36px; + font-size: 14px; + color: var(--semi-color-text-0); + cursor: pointer; + border-radius: var(--semi-border-radius-small); + align-items: center; + + &:hover { + color: var(--semi-color-text-0); + background-color: var(--semi-color-fill-0); + } + + &.isActive { + color: var(--semi-color-text-0); + background-color: var(--semi-color-primary-light-default); + } + + > span { + display: flex; + align-items: center; + } + + .icon { + margin: 0 6px 0 4px; + } + + .title { + overflow: hidden; + color: var(--semi-color-text-0); + text-overflow: ellipsis; + white-space: nowrap; + flex: 1; + } + } +} diff --git a/packages/client/src/pages/app/org/[organizationId]/wiki/[wikiId]/index.tsx b/packages/client/src/pages/app/org/[organizationId]/wiki/[wikiId]/index.tsx new file mode 100644 index 0000000..a89b129 --- /dev/null +++ b/packages/client/src/pages/app/org/[organizationId]/wiki/[wikiId]/index.tsx @@ -0,0 +1,64 @@ +import React from 'react'; + +import { Spin } from '@douyinfe/semi-ui'; + +import { IWiki, WikiApiDefinition } from '@think/domains'; + +import { DataRender } from 'components/data-render'; +import { DocumentReader } from 'components/document/reader'; +import { WikiTocs } from 'components/wiki/tocs'; +import { getWikiDetail, getWikiTocs, useWikiDetail } from 'data/wiki'; +import { AppDoubleColumnLayout } from 'layouts/app-double-column'; +import { NextPage } from 'next'; +import { serverPrefetcher } from 'services/server-prefetcher'; + +interface IProps { + wikiId: string; +} + +const Page: NextPage = ({ wikiId }) => { + const { data: wiki, loading, error } = useWikiDetail(wikiId); + + return ( + } + rightNode={ + + + + } + error={error} + normalContent={() => } + /> + } + /> + ); +}; + +Page.getInitialProps = async (ctx) => { + const { wikiId } = ctx.query; + const res = await serverPrefetcher(ctx, [ + { + url: WikiApiDefinition.getDetailById.client(wikiId as IWiki['id']), + action: (cookie) => getWikiDetail(wikiId, cookie), + }, + { + url: WikiApiDefinition.getTocsById.client(wikiId as IWiki['id']), + action: (cookie) => getWikiTocs(wikiId, cookie), + }, + ]); + return { ...res, wikiId } as IProps; +}; + +export default Page; diff --git a/packages/client/src/pages/app/org/[organizationId]/wiki/[wikiId]/setting/index.tsx b/packages/client/src/pages/app/org/[organizationId]/wiki/[wikiId]/setting/index.tsx new file mode 100644 index 0000000..f7da019 --- /dev/null +++ b/packages/client/src/pages/app/org/[organizationId]/wiki/[wikiId]/setting/index.tsx @@ -0,0 +1,62 @@ +import React, { useCallback } from 'react'; + +import { IWiki, WikiApiDefinition } from '@think/domains'; + +import { WikiSetting } from 'components/wiki/setting'; +import { WikiTocs } from 'components/wiki/tocs'; +import { getWikiMembers, getWikiTocs } from 'data/wiki'; +import { AppDoubleColumnLayout } from 'layouts/app-double-column'; +import { NextPage } from 'next'; +import Router, { useRouter } from 'next/router'; +import { serverPrefetcher } from 'services/server-prefetcher'; + +interface IProps { + wikiId: string; +} + +const Page: NextPage = ({ wikiId }) => { + const { query = {} } = useRouter(); + const { tab = 'recent' } = query as { + tab?: string; + }; + + const navigate = useCallback( + (tab = 'base') => { + return () => { + Router.push({ + pathname: `/app/org/[organizationId]/wiki/[wikiId]/setting`, + query: { organizationId: query.organizationId, wikiId, tab }, + }); + }; + }, + [query, wikiId] + ); + + return ( + } + rightNode={ +
+ navigate(tab)()} /> +
+ } + /> + ); +}; + +Page.getInitialProps = async (ctx) => { + const { wikiId } = ctx.query; + const res = await serverPrefetcher(ctx, [ + { + url: WikiApiDefinition.getTocsById.client(wikiId as IWiki['id']), + action: (cookie) => getWikiTocs(wikiId, cookie), + }, + { + url: WikiApiDefinition.getMemberById.client(wikiId as IWiki['id']), + action: (cookie) => getWikiMembers(wikiId, cookie), + }, + ]); + return { ...res, wikiId } as IProps; +}; + +export default Page; diff --git a/packages/client/src/pages/app/org/[organizationId]/wiki/index.module.scss b/packages/client/src/pages/app/org/[organizationId]/wiki/index.module.scss new file mode 100644 index 0000000..4708e1b --- /dev/null +++ b/packages/client/src/pages/app/org/[organizationId]/wiki/index.module.scss @@ -0,0 +1,12 @@ +.wikiItemWrap { + padding: 12px 16px !important; + margin: 8px 2px; + cursor: pointer; + background-color: var(--semi-color-bg-2); + border: 1px solid var(--semi-color-border) !important; +} + +.titleWrap { + display: flex; + justify-content: space-between; +} diff --git a/packages/client/src/pages/app/org/[organizationId]/wiki/index.tsx b/packages/client/src/pages/app/org/[organizationId]/wiki/index.tsx new file mode 100644 index 0000000..88fb217 --- /dev/null +++ b/packages/client/src/pages/app/org/[organizationId]/wiki/index.tsx @@ -0,0 +1,100 @@ +import React from 'react'; + +import { List, TabPane, Tabs, Typography } from '@douyinfe/semi-ui'; + +import { WikiApiDefinition } from '@think/domains'; + +import { DataRender } from 'components/data-render'; +import { Empty } from 'components/empty'; +import { Seo } from 'components/seo'; +import { WikiCard, WikiCardPlaceholder } from 'components/wiki/card'; +import { WikiCreator } from 'components/wiki-creator'; +import { getAllWikis, getJoinWikis, getOwnWikis, useAllWikis, useJoinWikis, useOwnWikis } from 'data/wiki'; +import { useRouterQuery } from 'hooks/use-router-query'; +import { CreateWikiIllustration } from 'illustrations/create-wiki'; +import { AppSingleColumnLayout } from 'layouts/app-single-column'; +import type { NextPage } from 'next'; +import { serverPrefetcher } from 'services/server-prefetcher'; + +const grid = { + gutter: 16, + xs: 24, + sm: 12, + md: 12, + lg: 8, + xl: 8, +}; + +const { Title } = Typography; + +const Wikis = ({ hook }) => { + const { organizationId } = useRouterQuery<{ organizationId: string }>(); + const { data, loading, error } = hook(organizationId); + + return ( + ( + ( + + + + )} + /> + )} + error={error} + normalContent={() => ( + ( + + + + )} + emptyContent={} message={} />} + /> + )} + /> + ); +}; + +const Page: NextPage = () => { + return ( + + +
+ + 知识库 + + + + + + + + + + + + +
+
+ ); +}; + +Page.getInitialProps = async (ctx) => { + const { orgId: organizationId } = ctx.query; + + const props = await serverPrefetcher(ctx, [ + { url: WikiApiDefinition.getAllWikis.client(organizationId), action: (cookie) => getAllWikis(cookie) }, + { url: WikiApiDefinition.getJoinWikis.client(organizationId), action: (cookie) => getJoinWikis(cookie) }, + { url: WikiApiDefinition.getOwnWikis.client(organizationId), action: (cookie) => getOwnWikis(cookie) }, + ]); + return props; +}; + +export default Page; diff --git a/packages/client/src/pages/app/org/create/index.module.scss b/packages/client/src/pages/app/org/create/index.module.scss new file mode 100644 index 0000000..c58f36b --- /dev/null +++ b/packages/client/src/pages/app/org/create/index.module.scss @@ -0,0 +1,9 @@ +.cover { + margin-right: 12px; +} + +@media (max-width: 768px) { + .cover { + width: 100%; + } +} diff --git a/packages/client/src/pages/app/org/create/index.tsx b/packages/client/src/pages/app/org/create/index.tsx new file mode 100644 index 0000000..9cd66b7 --- /dev/null +++ b/packages/client/src/pages/app/org/create/index.tsx @@ -0,0 +1,124 @@ +import { useCallback, useRef, useState } from 'react'; + +import { Avatar, Button, Form, Typography } from '@douyinfe/semi-ui'; +import { FormApi } from '@douyinfe/semi-ui/lib/es/form'; + +import { ORGANIZATION_LOGOS } from '@think/constants'; + +import { ImageUploader } from 'components/image-uploader'; +import { Seo } from 'components/seo'; +import { useCreateOrganization } from 'data/organization'; +import { useToggle } from 'hooks/use-toggle'; +import { SingleColumnLayout } from 'layouts/single-column'; +import Router from 'next/router'; + +import styles from './index.module.scss'; + +const images = [ + { + key: 'placeholers', + title: '图库', + images: ORGANIZATION_LOGOS, + }, +]; + +const { Title } = Typography; + +const Page: React.FC = () => { + const $form = useRef(); + const [changed, toggleChanged] = useToggle(false); + const [currentCover, setCurrentCover] = useState(''); + const { create, loading } = useCreateOrganization(); + + const setCover = useCallback((url) => { + $form.current.setValue('logo', url); + setCurrentCover(url); + }, []); + + const onFormChange = useCallback(() => { + toggleChanged(true); + }, [toggleChanged]); + + const onSubmit = useCallback(() => { + $form.current.validate().then((values) => { + create(values).then((res) => { + Router.push({ + pathname: `/app/org/[organizationId]`, + query: { organizationId: res.id }, + }); + }); + }); + }, [create]); + + return ( + + +
+
+ + 新建组织 + +
+
($form.current = formApi)} + onChange={onFormChange} + onSubmit={onSubmit} + > + +
+
+ +
+ + + +
+
+ + + + + +
+ +
+ +
+
+ ); +}; + +export default Page; diff --git a/packages/client/src/pages/feature/csrf/index.tsx b/packages/client/src/pages/feature/csrf/index.tsx new file mode 100644 index 0000000..d6b4edf --- /dev/null +++ b/packages/client/src/pages/feature/csrf/index.tsx @@ -0,0 +1,22 @@ +import React, { useRef, useState } from 'react'; + +import { SingleColumnLayout } from 'layouts/single-column'; +import { useRouter } from 'next/router'; + +const Page = () => { + const $container = useRef(); + const { query } = useRouter(); + const { id } = query as { id: string }; + const [v, setV] = useState(false); + + return ( + +
+ {id ? : null} + {id && v ? +
+ ) : ( +
+ 请设置外链地址 +
+ )} + + + + ); +}; diff --git a/packages/client/src/tiptap/core/wrappers/image/index.module.scss b/packages/client/src/tiptap/core/wrappers/image/index.module.scss new file mode 100644 index 0000000..5f062ec --- /dev/null +++ b/packages/client/src/tiptap/core/wrappers/image/index.module.scss @@ -0,0 +1,23 @@ +.wrap { + position: relative; + display: flex; + height: 100%; + padding: 8px 16px; + cursor: pointer; + border: 1px solid var(--node-border-color); + border-radius: var(--border-radius); + justify-content: space-between; + align-items: center; + + .handlerWrap { + position: absolute; + right: 10px; + bottom: 10px; + z-index: 2; + padding: 2px 4px; + background-color: var(--semi-color-bg-2); + border: 1px solid var(--node-border-color); + border-radius: var(--border-radius); + box-shadow: var(--box-shadow); + } +} diff --git a/packages/client/src/tiptap/core/wrappers/image/index.tsx b/packages/client/src/tiptap/core/wrappers/image/index.tsx new file mode 100644 index 0000000..98cc90b --- /dev/null +++ b/packages/client/src/tiptap/core/wrappers/image/index.tsx @@ -0,0 +1,148 @@ +import { useCallback, useEffect, useRef, useState } from 'react'; +import { LazyLoadImage } from 'react-lazy-load-image-component'; + +import { Button, Spin, Typography } from '@douyinfe/semi-ui'; + +import { NodeViewWrapper } from '@tiptap/react'; +import { MAX_ZOOM, MIN_ZOOM, ZOOM_STEP } from 'tiptap/core/menus/mind/constant'; +import { + clamp, + extractFileExtension, + extractFilename, + getEditorContainerDOMSize, + getImageWidthHeight, +} from 'tiptap/prose-utils'; + +import { IconZoomIn, IconZoomOut } from 'components/icons'; +import { Resizeable } from 'components/resizeable'; +import { Tooltip } from 'components/tooltip'; +import { useToggle } from 'hooks/use-toggle'; +import { uploadFile } from 'services/file'; + +import styles from './index.module.scss'; + +const { Text } = Typography; + +export const ImageWrapper = ({ editor, node, updateAttributes }) => { + const isEditable = editor.isEditable; + const { hasTrigger, error, src, alt, title, width, height, textAlign } = node.attrs; + const { width: maxWidth } = getEditorContainerDOMSize(editor); + const $upload = useRef(); + const [loading, toggleLoading] = useToggle(false); + const [zoom, setZoomState] = useState(100); + + const onResize = useCallback( + (size) => { + updateAttributes({ height: size.height, width: size.width }); + }, + [updateAttributes] + ); + + const selectFile = useCallback(() => { + if (!isEditable || error || src) return; + isEditable && $upload.current.click(); + }, [isEditable, error, src]); + + const handleFile = useCallback( + async (e) => { + const file = e.target.files && e.target.files[0]; + + const fileInfo = { + fileName: extractFilename(file.name), + fileSize: file.size, + fileType: file.type, + fileExt: extractFileExtension(file.name), + }; + + toggleLoading(true); + + try { + const src = await uploadFile(file); + const size = await getImageWidthHeight(src); + updateAttributes({ ...fileInfo, ...size, src }); + toggleLoading(false); + } catch (error) { + updateAttributes({ error: '图片上传失败:' + (error && error.message) || '未知错误' }); + toggleLoading(false); + } + }, + [updateAttributes, toggleLoading] + ); + + const setZoom = useCallback((type: 'minus' | 'plus') => { + return () => { + setZoomState((currentZoom) => + clamp(type === 'minus' ? currentZoom - ZOOM_STEP : currentZoom + ZOOM_STEP, MIN_ZOOM, MAX_ZOOM) + ); + }; + }, []); + + useEffect(() => { + if (!src && !hasTrigger) { + selectFile(); + updateAttributes({ hasTrigger: true }); + } + }, [src, hasTrigger, selectFile, updateAttributes]); + + return ( + + + {error ? ( +
+ {error} +
+ ) : !src ? ( +
+ + {loading ? '正在上传中' : '请选择图片'} + + +
+ ) : ( +
+
+ +
+ +
+ +
+
+ )} +
+
+ ); +}; diff --git a/packages/client/src/tiptap/core/wrappers/katex/index.module.scss b/packages/client/src/tiptap/core/wrappers/katex/index.module.scss new file mode 100644 index 0000000..2519453 --- /dev/null +++ b/packages/client/src/tiptap/core/wrappers/katex/index.module.scss @@ -0,0 +1,8 @@ +.wrap { + display: flex; + padding: 1rem 4px; + font-size: 1em; + color: #000; + cursor: pointer; + justify-content: center; +} diff --git a/packages/client/src/tiptap/core/wrappers/katex/index.tsx b/packages/client/src/tiptap/core/wrappers/katex/index.tsx new file mode 100644 index 0000000..9dd782e --- /dev/null +++ b/packages/client/src/tiptap/core/wrappers/katex/index.tsx @@ -0,0 +1,48 @@ +import { useMemo } from 'react'; + +import { NodeViewWrapper } from '@tiptap/react'; + +import { convertColorToRGBA } from 'helpers/color'; +import { Theme, ThemeEnum } from 'hooks/use-theme'; +import katex from 'katex'; + +import styles from './index.module.scss'; + +export const KatexWrapper = ({ node, editor }) => { + const { text } = node.attrs; + const { theme } = Theme.useHook(); + const backgroundColor = useMemo(() => { + const color = `rgb(254, 242, 237)`; + if (theme === ThemeEnum.dark) return convertColorToRGBA(color, 0.75); + return color; + }, [theme]); + + const formatText = useMemo(() => { + try { + return katex.renderToString(`${text}`); + } catch (e) { + return text; + } + }, [text]); + + const content = useMemo( + () => + text.trim() ? ( + + ) : ( + 用户未输入公式 + ), + [text, formatText] + ); + + return ( + +
{content}
+
+ ); +}; diff --git a/packages/client/src/tiptap/core/wrappers/loading.tsx b/packages/client/src/tiptap/core/wrappers/loading.tsx new file mode 100644 index 0000000..22428d7 --- /dev/null +++ b/packages/client/src/tiptap/core/wrappers/loading.tsx @@ -0,0 +1,27 @@ +import { Spin } from '@douyinfe/semi-ui'; + +import { NodeViewWrapper } from '@tiptap/react'; + +export const LoadingWrapper = ({ editor, node }) => { + const isEditable = editor.isEditable; + const { text } = node.attrs; + + if (!isEditable) return ; + + return ( + +
+ +
+
+ ); +}; diff --git a/packages/client/src/tiptap/core/wrappers/mention-list/index.module.scss b/packages/client/src/tiptap/core/wrappers/mention-list/index.module.scss new file mode 100644 index 0000000..31c57c1 --- /dev/null +++ b/packages/client/src/tiptap/core/wrappers/mention-list/index.module.scss @@ -0,0 +1,38 @@ +.items { + width: 160px; + max-height: 320px; + overflow-x: hidden; + overflow-y: auto; + border-radius: var(--border-radius); + box-shadow: rgb(9 30 66 / 31%) 0 0 1px, rgb(9 30 66 / 25%) 0 4px 8px -2px; +} + +.item { + display: flex; + width: 100%; + padding: 12px 12px 11px; + color: rgb(9 30 66); + text-decoration: none; + cursor: pointer; + background-color: rgb(255 255 255); + border: 0; + border-radius: 0; + flex: 0 0 auto; + align-items: center; + + &:hover { + background-color: #f4f5f7; + } + + &.is-selected { + color: rgb(0 82 204); + text-decoration: none; + background-color: rgb(222 235 255); + fill: rgb(222 235 255); + } + + img { + width: 1em; + height: 1em; + } +} diff --git a/packages/client/src/tiptap/core/wrappers/mention-list/index.tsx b/packages/client/src/tiptap/core/wrappers/mention-list/index.tsx new file mode 100644 index 0000000..4e156b7 --- /dev/null +++ b/packages/client/src/tiptap/core/wrappers/mention-list/index.tsx @@ -0,0 +1,88 @@ +import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react'; + +import { Editor } from '@tiptap/core'; + +import cls from 'classnames'; +import scrollIntoView from 'scroll-into-view-if-needed'; + +import styles from './index.module.scss'; + +interface IProps { + editor: Editor; + items: Array; + command: any; +} + +export const MentionList: React.FC = forwardRef((props, ref) => { + const $container = useRef(); + const [selectedIndex, setSelectedIndex] = useState(0); + + const selectItem = (index) => { + const userName = props.items[index]; + if (!userName) return; + props.command({ id: userName, label: userName }); + }; + + const upHandler = () => { + setSelectedIndex((selectedIndex + props.items.length - 1) % props.items.length); + }; + + const downHandler = () => { + setSelectedIndex((selectedIndex + 1) % props.items.length); + }; + + const enterHandler = () => { + selectItem(selectedIndex); + }; + + useEffect(() => setSelectedIndex(0), [props.items]); + + useEffect(() => { + if (Number.isNaN(selectedIndex + 1)) return; + const el = $container.current.querySelector(`span:nth-of-type(${selectedIndex + 1})`); + el && scrollIntoView(el, { behavior: 'smooth', scrollMode: 'if-needed' }); + }, [selectedIndex]); + + useImperativeHandle(ref, () => ({ + onKeyDown: ({ event }) => { + if (event.key === 'ArrowUp') { + upHandler(); + return true; + } + + if (event.key === 'ArrowDown') { + downHandler(); + return true; + } + + if (event.key === 'Enter') { + enterHandler(); + return true; + } + + return false; + }, + })); + + return ( +
+
+ {props.items.length ? ( + props.items.map((item, index) => ( + selectItem(index)} + > + {item} + + )) + ) : ( +
没有找到结果
+ )} +
+
+ ); +}); + +MentionList.displayName = 'MentionList'; diff --git a/packages/client/src/tiptap/core/wrappers/menu-list/index.module.scss b/packages/client/src/tiptap/core/wrappers/menu-list/index.module.scss new file mode 100644 index 0000000..88c3fd8 --- /dev/null +++ b/packages/client/src/tiptap/core/wrappers/menu-list/index.module.scss @@ -0,0 +1,38 @@ +.items { + width: 200px; + max-height: 320px; + overflow-x: hidden; + overflow-y: auto; + border-radius: var(--border-radius); + box-shadow: rgb(9 30 66 / 31%) 0 0 1px, rgb(9 30 66 / 25%) 0 4px 8px -2px; +} + +.item { + display: flex; + width: 100%; + padding: 12px 12px 11px; + color: rgb(9 30 66); + text-decoration: none; + cursor: pointer; + background-color: rgb(255 255 255); + border: 0; + border-radius: 0; + flex: 0 0 auto; + align-items: center; + + &:hover { + background-color: #f4f5f7; + } + + &.is-selected { + color: rgb(0 82 204); + text-decoration: none; + background-color: rgb(222 235 255); + fill: rgb(222 235 255); + } + + img { + width: 1em; + height: 1em; + } +} diff --git a/packages/client/src/tiptap/core/wrappers/menu-list/index.tsx b/packages/client/src/tiptap/core/wrappers/menu-list/index.tsx new file mode 100644 index 0000000..9b2f3b7 --- /dev/null +++ b/packages/client/src/tiptap/core/wrappers/menu-list/index.tsx @@ -0,0 +1,102 @@ +import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react'; + +import { Space } from '@douyinfe/semi-ui'; + +import { Editor } from '@tiptap/core'; +import { ILabelRenderCommand } from 'tiptap/core/menus/commands'; + +import cls from 'classnames'; +import { useUser } from 'data/user'; +import scrollIntoView from 'scroll-into-view-if-needed'; + +import styles from './index.module.scss'; + +interface IProps { + editor: Editor; + items: ILabelRenderCommand[]; + command: (command: ILabelRenderCommand) => void; +} + +export const MenuList: React.FC = forwardRef((props, ref) => { + const { user } = useUser(); + const $container = useRef(); + const [selectedIndex, setSelectedIndex] = useState(0); + + const selectItem = (index) => { + const command = props.items[index]; + + if (command) { + // 注入用户信息 + command.user = user; + props.command(command); + } + }; + + const upHandler = () => { + setSelectedIndex((selectedIndex + props.items.length - 1) % props.items.length); + }; + + const downHandler = () => { + setSelectedIndex((selectedIndex + 1) % props.items.length); + }; + + const enterHandler = () => { + selectItem(selectedIndex); + }; + + useEffect(() => setSelectedIndex(0), [props.items]); + + useEffect(() => { + if (Number.isNaN(selectedIndex + 1)) return; + const el = $container.current.querySelector(`span:nth-of-type(${selectedIndex + 1})`); + el && scrollIntoView(el, { behavior: 'smooth', scrollMode: 'if-needed' }); + }, [selectedIndex]); + + useImperativeHandle(ref, () => ({ + onKeyDown: ({ event }) => { + if (event.key === 'ArrowUp') { + upHandler(); + return true; + } + + if (event.key === 'ArrowDown') { + downHandler(); + return true; + } + + if (event.key === 'Enter') { + enterHandler(); + return true; + } + + return false; + }, + })); + + return ( +
+
+ {props.items.length ? ( + props.items.map((item, index) => { + return ( + selectItem(index)} + > + + {item.icon} + {item.label} + + + ); + }) + ) : ( +
没有找到结果
+ )} +
+
+ ); +}); + +MenuList.displayName = 'MenuList'; diff --git a/packages/client/src/tiptap/core/wrappers/mind/index.module.scss b/packages/client/src/tiptap/core/wrappers/mind/index.module.scss new file mode 100644 index 0000000..a94678c --- /dev/null +++ b/packages/client/src/tiptap/core/wrappers/mind/index.module.scss @@ -0,0 +1,45 @@ +.wrap { + position: relative; + max-width: 100%; + overflow: visible; + line-height: 0; + + .renderWrap { + border: 1px solid var(--node-border-color); + border-radius: var(--border-radius); + + &::after { + background-color: transparent !important; + } + } + + .title { + position: absolute; + top: 10px; + left: 10px; + z-index: 2; + + .icon { + display: flex; + width: 18px; + height: 18px; + color: #fff; + background-color: #f80; + border-radius: 2px; + justify-content: center; + align-items: center; + } + } + + .mindHandlerWrap { + position: absolute; + right: 10px; + bottom: 10px; + z-index: 2; + padding: 2px 4px; + background-color: var(--semi-color-bg-2); + border: 1px solid var(--node-border-color); + border-radius: var(--border-radius); + box-shadow: var(--box-shadow); + } +} diff --git a/packages/client/src/tiptap/core/wrappers/mind/index.tsx b/packages/client/src/tiptap/core/wrappers/mind/index.tsx new file mode 100644 index 0000000..641ff5e --- /dev/null +++ b/packages/client/src/tiptap/core/wrappers/mind/index.tsx @@ -0,0 +1,189 @@ +import React, { useCallback, useEffect, useRef, useState } from 'react'; +import VisibilitySensor from 'react-visibility-sensor'; + +import { Button, Space, Spin, Typography } from '@douyinfe/semi-ui'; + +import { NodeViewWrapper } from '@tiptap/react'; +import { MAX_ZOOM, MIN_ZOOM, ZOOM_STEP } from 'tiptap/core/menus/mind/constant'; +import { clamp, getEditorContainerDOMSize } from 'tiptap/prose-utils'; + +import cls from 'classnames'; +import { IconMind, IconMindCenter, IconZoomIn, IconZoomOut } from 'components/icons'; +import { Resizeable } from 'components/resizeable'; +import { Tooltip } from 'components/tooltip'; +import deepEqual from 'deep-equal'; +import { useToggle } from 'hooks/use-toggle'; +import { load, renderMind } from 'thirtypart/kityminder'; + +import styles from './index.module.scss'; + +const { Text } = Typography; + +const INHERIT_SIZE_STYLE = { width: '100%', height: '100%', maxWidth: '100%' }; + +export const _MindWrapper = ({ editor, node, updateAttributes }) => { + const $mind = useRef(null); + const $centerTimer = useRef>(null); + const isEditable = editor.isEditable; + const { width: maxWidth } = getEditorContainerDOMSize(editor); + const { data, width, height } = node.attrs; + const [visible, toggleVisible] = useToggle(false); + const [loading, toggleLoading] = useToggle(true); + const [error, setError] = useState(null); + + const setCenter = useCallback(() => { + const mind = $mind.current; + if (!mind) return; + mind.execCommand('camera'); + }, []); + + const setZoom = useCallback((type: 'minus' | 'plus') => { + return () => { + const mind = $mind.current; + if (!mind) return; + const currentZoom = mind.getZoomValue(); + const nextZoom = clamp(type === 'minus' ? currentZoom - ZOOM_STEP : currentZoom + ZOOM_STEP, MIN_ZOOM, MAX_ZOOM); + mind.execCommand('zoom', nextZoom); + }; + }, []); + + const onResize = useCallback( + (size) => { + updateAttributes({ width: size.width, height: size.height }); + $centerTimer.current = setTimeout(() => { + setCenter(); + }); + }, + [updateAttributes, setCenter] + ); + + const render = useCallback( + (div) => { + if (!div) return; + + if (!$mind.current) { + const graph = renderMind({ + container: div, + data, + isEditable: false, + }); + $mind.current = graph; + } + }, + [data] + ); + + const setMind = useCallback( + (div) => { + render(div); + }, + [render] + ); + + const onViewportChange = useCallback( + (visible) => { + if (visible && !$mind.current) { + toggleVisible(true); + } + }, + [toggleVisible] + ); + + useEffect(() => { + let isUnmount = false; + + load() + .catch((err) => !isUnmount && setError(err)) + .finally(() => !isUnmount && toggleLoading(false)); + + return () => { + isUnmount = true; + }; + }, [toggleLoading]); + + // 数据同步渲染 + useEffect(() => { + const mind = $mind.current; + if (!mind) return; + const currentData = mind.exportJson(); + const isEqual = deepEqual(currentData, data); + if (isEqual) return; + mind.importJson(data); + }, [data]); + + useEffect(() => { + setCenter(); + }, [width, height, setCenter]); + + useEffect(() => { + return () => { + clearTimeout($centerTimer.current); + }; + }, []); + + return ( + + + +
+ {error && ( +
+ {error.message || error} +
+ )} + + {loading && } + + {!loading && !error && ( +
+ )} + +
+ + + + + 思维导图 + +
+ +
+ +
+
+
+
+
+ ); +}; + +export const MindWrapper = React.memo(_MindWrapper, (prevProps, nextProps) => { + if (deepEqual(prevProps.node.attrs, nextProps.node.attrs)) { + return true; + } + + return false; +}); diff --git a/packages/client/src/tiptap/core/wrappers/status/index.module.scss b/packages/client/src/tiptap/core/wrappers/status/index.module.scss new file mode 100644 index 0000000..9fdbfae --- /dev/null +++ b/packages/client/src/tiptap/core/wrappers/status/index.module.scss @@ -0,0 +1,6 @@ +.wrap { + display: inline-block; + font-size: 0; + vertical-align: middle; + cursor: pointer; +} diff --git a/packages/client/src/tiptap/core/wrappers/status/index.tsx b/packages/client/src/tiptap/core/wrappers/status/index.tsx new file mode 100644 index 0000000..f0978a5 --- /dev/null +++ b/packages/client/src/tiptap/core/wrappers/status/index.tsx @@ -0,0 +1,134 @@ +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; + +import { IconTick } from '@douyinfe/semi-icons'; +import { Input, Popover, Space, Tag } from '@douyinfe/semi-ui'; + +import { NodeViewWrapper } from '@tiptap/react'; + +import cls from 'classnames'; +import { useUser } from 'data/user'; +import { useToggle } from 'hooks/use-toggle'; + +import styles from './index.module.scss'; + +export const STATUS_COLORS = [ + // 按钮背景 文字颜色 背景颜色 边框颜色 + ['rgb(223, 225, 230)', '#42526E', '#DFE1E6', 'rgb(80, 95, 121)'], + ['rgb(234, 230, 255)', '#403294', '#EAE6FF', 'rgb(82, 67, 170)'], + ['rgb(222, 235, 255)', '#0747A6', '#DEEBFF', 'rgb(0, 82, 204)'], + ['rgb(255, 235, 230)', '#BF2600', '#FFECE6', 'rgb(222, 53, 11)'], + ['rgb(255, 240, 179)', '#172B4D', '#FFF0B3', 'rgb(255, 153, 31)'], + ['rgb(227, 252, 239)', '#006644', '#E3FCEF', 'rgb(0, 135, 90)'], +]; + +export const StatusWrapper = ({ editor, node, updateAttributes }) => { + const isEditable = editor.isEditable; + const { color: currentTextColor, bgcolor, borderColor, text, defaultShowPicker, createUser } = node.attrs; + const { user } = useUser(); + const ref = useRef(); + const [visible, toggleVisible] = useToggle(false); + const [currentText, setCurrentText] = useState(text); + + const content = useMemo( + () => ( + + {currentText || '点击设置状态'} + + ), + [bgcolor, borderColor, currentTextColor, currentText] + ); + + const onVisibleChange = useCallback( + (value) => { + toggleVisible(value); + if (defaultShowPicker && user && user.id === createUser) { + updateAttributes({ defaultShowPicker: false }); + } + }, + [defaultShowPicker, toggleVisible, updateAttributes, createUser, user] + ); + + const setColor = useCallback( + (color) => () => { + updateAttributes({ + color: color[1], + bgcolor: color[2], + }); + }, + [updateAttributes] + ); + + useEffect(() => { + let timer: ReturnType = null; + + if (defaultShowPicker && user && user.id === createUser) { + toggleVisible(true); + timer = setTimeout(() => ref.current?.focus(), 200); + } + + return () => { + clearTimeout(timer); + }; + }, [defaultShowPicker, toggleVisible, createUser, user]); + + useEffect(() => { + let timer: ReturnType = null; + + if (visible) { + timer = setTimeout(() => { + ref.current?.focus(); + }, 200); + } else { + updateAttributes({ text: currentText }); + } + + return () => { + clearTimeout(timer); + }; + }, [visible, updateAttributes, currentText]); + + return ( + + {isEditable ? ( + +
+ +
+ + {STATUS_COLORS.map((color) => { + return ( + + {currentTextColor === color[1] ? : null} + + ); + })} + + + } + trigger="click" + > + {content} +
+ ) : ( + content + )} +
+ ); +}; diff --git a/packages/client/src/tiptap/core/wrappers/table-of-contents/index.module.scss b/packages/client/src/tiptap/core/wrappers/table-of-contents/index.module.scss new file mode 100644 index 0000000..77569bf --- /dev/null +++ b/packages/client/src/tiptap/core/wrappers/table-of-contents/index.module.scss @@ -0,0 +1,50 @@ +.toc { + width: max-content; + max-width: 100%; + background: var(--semi-color-fill-1); + border-radius: 0.5rem; + opacity: 0.75; + + &.visible { + padding: 0.75rem; + margin: 0.75em 0; + } + + .list { + padding: 0; + margin: 0 0 12px; + list-style: none; + + &::before { + display: block; + font-size: 0.75rem; + font-weight: 700; + letter-spacing: 0.025rem; + text-transform: uppercase; + content: '目录'; + opacity: 0.5; + } + } + + .item { + a:hover { + opacity: 0.5; + } + + &--3 { + padding-left: 1rem; + } + + &--4 { + padding-left: 2rem; + } + + &--5 { + padding-left: 3rem; + } + + &--6 { + padding-left: 4rem; + } + } +} diff --git a/packages/client/src/tiptap/core/wrappers/table-of-contents/index.tsx b/packages/client/src/tiptap/core/wrappers/table-of-contents/index.tsx new file mode 100644 index 0000000..be2f63d --- /dev/null +++ b/packages/client/src/tiptap/core/wrappers/table-of-contents/index.tsx @@ -0,0 +1,100 @@ +import { useCallback, useEffect, useState } from 'react'; + +import { NodeViewWrapper } from '@tiptap/react'; + +import cls from 'classnames'; + +import styles from './index.module.scss'; + +const arrToTree = (tocs) => { + const result = []; + const levels = [result]; + + tocs.forEach((o) => { + let offset = -1; + let parent = levels[o.level + offset]; + + while (!parent) { + offset -= 1; + parent = levels[o.level + offset]; + } + + parent.push({ ...o, children: (levels[o.level] = []) }); + }); + + return result; +}; + +export const TableOfContentsWrapper = ({ editor }) => { + const isEditable = editor.isEditable; + const [items, setItems] = useState([]); + + const handleUpdate = useCallback(() => { + const headings = []; + const transaction = editor.state.tr; + + editor.state.doc.descendants((node, pos) => { + if (node.type.name === 'heading') { + const id = `heading-${headings.length + 1}`; + + if (node.attrs.id !== id) { + transaction.setNodeMarkup(pos, undefined, { + ...node.attrs, + id, + }); + } + + headings.push({ + level: node.attrs.level, + text: node.textContent, + id, + }); + } + }); + + transaction.setMeta('addToHistory', false); + transaction.setMeta('preventUpdate', true); + editor.view.dispatch(transaction); + + setItems(headings); + editor.eventEmitter && editor.eventEmitter.emit('TableOfContents', arrToTree(headings)); + }, [editor]); + + useEffect(() => { + if (!editor) { + return; + } + + if (!editor.options.editable) { + handleUpdate(); + return; + } + + editor.on('update', handleUpdate); + + return () => { + editor.off('update', handleUpdate); + }; + }, [editor, handleUpdate]); + + useEffect(() => { + handleUpdate(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return ( + + {isEditable ? ( +
+
    + {items.map((item, index) => ( +
  • + {item.text} +
  • + ))} +
+
+ ) : null} +
+ ); +}; diff --git a/packages/client/src/tiptap/core/wrappers/task-item/index.module.scss b/packages/client/src/tiptap/core/wrappers/task-item/index.module.scss new file mode 100644 index 0000000..f797c8d --- /dev/null +++ b/packages/client/src/tiptap/core/wrappers/task-item/index.module.scss @@ -0,0 +1,5 @@ +.wrap { + display: inline-flex; + justify-content: center; + margin: 8px 0; +} diff --git a/packages/client/src/tiptap/core/wrappers/task-item/index.tsx b/packages/client/src/tiptap/core/wrappers/task-item/index.tsx new file mode 100644 index 0000000..512147b --- /dev/null +++ b/packages/client/src/tiptap/core/wrappers/task-item/index.tsx @@ -0,0 +1,16 @@ +import { Checkbox } from '@douyinfe/semi-ui'; + +import { NodeViewContent, NodeViewWrapper } from '@tiptap/react'; + +import styles from './index.module.scss'; + +export const TaskItemWrapper = ({ editor, node, updateAttributes }) => { + const { checked } = node.attrs; + + return ( + + updateAttributes({ checked: e.target.checked })} /> + + + ); +}; diff --git a/packages/client/src/tiptap/core/wrappers/title/index.module.scss b/packages/client/src/tiptap/core/wrappers/title/index.module.scss new file mode 100644 index 0000000..4d117c3 --- /dev/null +++ b/packages/client/src/tiptap/core/wrappers/title/index.module.scss @@ -0,0 +1,38 @@ +.wrap { + position: relative; + margin-top: 24px; + + .coverWrap { + position: relative; + height: 280px; + margin-top: 14px; + margin-bottom: 12px; + overflow: hidden; + + img { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + object-position: center 50%; + object-fit: cover; + } + + .toolbar { + position: absolute; + right: 12px; + bottom: 12px; + z-index: 2; + font-size: 1rem; + } + } + + .emptyToolbarWrap { + position: absolute; + top: 0; + left: 0; + height: 0; + pointer-events: none; + } +} diff --git a/packages/client/src/tiptap/core/wrappers/title/index.tsx b/packages/client/src/tiptap/core/wrappers/title/index.tsx new file mode 100644 index 0000000..d19eb3e --- /dev/null +++ b/packages/client/src/tiptap/core/wrappers/title/index.tsx @@ -0,0 +1,105 @@ +import { useCallback, useEffect, useRef } from 'react'; +import { createPortal } from 'react-dom'; + +import { Button } from '@douyinfe/semi-ui'; + +import { DOCUMENT_COVERS } from '@think/constants'; + +import { NodeViewContent, NodeViewWrapper } from '@tiptap/react'; + +import cls from 'classnames'; +import { ImageUploader } from 'components/image-uploader'; + +import styles from './index.module.scss'; + +const images = [ + { + key: 'placeholers', + title: '图库', + images: DOCUMENT_COVERS, + }, +]; + +export const TitleWrapper = ({ editor, node }) => { + const toolbarRef = useRef(null); + const isEditable = editor.isEditable; + const { cover } = node.attrs; + + const setCover = useCallback( + (cover) => { + editor.commands.command(({ tr }) => { + const pos = 0; + tr.setNodeMarkup(pos, undefined, { + ...node.attrs, + cover, + }); + tr.setMeta('scrollIntoView', false); + return true; + }); + }, + [editor, node] + ); + + const addRandomCover = useCallback(() => { + setCover(DOCUMENT_COVERS[~~(Math.random() * DOCUMENT_COVERS.length)]); + }, [setCover]); + + const createAddCoverUIControl = useCallback(() => { + if (!editor.isEditable) return null; + + if (!toolbarRef.current) { + const editorDOM = editor.view.dom as HTMLDivElement; + const parent = editorDOM.parentElement; + const el = window.document.createElement('div'); + + parent.style.position = 'relative'; + editorDOM.parentNode.insertBefore(el, editorDOM); + toolbarRef.current = el; + } + + return createPortal( +
+ +
, + toolbarRef.current + ); + }, [editor, addRandomCover]); + + useEffect(() => { + const remove = () => { + if (cover && toolbarRef.current) { + toolbarRef.current?.remove(); + toolbarRef.current = null; + } + }; + + remove(); + + return () => { + remove(); + }; + }, [cover, createAddCoverUIControl]); + + return ( + + {cover ? ( +
+ 请选择或移除封面 + {isEditable ? ( +
+ + + +
+ ) : null} +
+ ) : null} + {isEditable ? createAddCoverUIControl() : null} + +
+ ); +}; diff --git a/packages/client/src/tiptap/editor/collaboration/collaboration/editor.tsx b/packages/client/src/tiptap/editor/collaboration/collaboration/editor.tsx new file mode 100644 index 0000000..903fd70 --- /dev/null +++ b/packages/client/src/tiptap/editor/collaboration/collaboration/editor.tsx @@ -0,0 +1,228 @@ +import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'; + +import { BackTop, Toast } from '@douyinfe/semi-ui'; + +import { EditorContent, useEditor } from 'tiptap/core'; +import { Collaboration } from 'tiptap/core/extensions/collaboration'; +import { CollaborationCursor } from 'tiptap/core/extensions/collaboration-cursor'; +import { Tocs } from 'tiptap/editor/tocs'; + +import { HocuspocusProvider } from '@hocuspocus/provider'; +import cls from 'classnames'; +import { Banner } from 'components/banner'; +import { CommentEditor } from 'components/document/comments'; +import { ImageViewer } from 'components/image-viewer'; +import { getRandomColor } from 'helpers/color'; +import { isAndroid, isIOS } from 'helpers/env'; +import { useDocumentStyle } from 'hooks/use-document-style'; +import { useNetwork } from 'hooks/use-network'; +import { IsOnMobile } from 'hooks/use-on-mobile'; +import { RuntimeConfig } from 'hooks/use-runtime-config'; +import { useToggle } from 'hooks/use-toggle'; + +import { CollaborationKit } from '../kit'; +import { MenuBar } from './menubar'; +import { ICollaborationEditorProps, ProviderStatus } from './type'; + +import styles from './index.module.scss'; + +type IProps = Pick< + ICollaborationEditorProps, + 'editable' | 'user' | 'onTitleUpdate' | 'menubar' | 'renderInEditorPortal' | 'hideComment' +> & { + hocuspocusProvider: HocuspocusProvider; + status: ProviderStatus; + documentId: string; +}; + +export const EditorInstance = forwardRef((props: IProps, ref) => { + const { + hocuspocusProvider, + documentId, + editable, + user, + hideComment, + status, + menubar, + renderInEditorPortal, + onTitleUpdate, + } = props; + const config = RuntimeConfig.useHook(); + const $headerContainer = useRef(); + const $mainContainer = useRef(); + const { isMobile } = IsOnMobile.useHook(); + const { online } = useNetwork(); + const [created, toggleCreated] = useToggle(false); + const editor = useEditor( + { + editable, + editorProps: { + // @ts-ignore + taskItemClickable: true, + attributes: { + class: 'is-withauthor', + }, + }, + extensions: [ + ...CollaborationKit, + Collaboration.configure({ + document: hocuspocusProvider.document, + }), + CollaborationCursor.configure({ + provider: hocuspocusProvider, + user: { + ...(user || { + name: '访客', + }), + color: getRandomColor(), + }, + }), + ].filter(Boolean), + onUpdate({ transaction }) { + try { + const title = transaction.doc.content.firstChild.content.firstChild?.textContent; + onTitleUpdate(title || '未命名文档'); + } catch (e) { + // + } + }, + onCreate() { + toggleCreated(true); + }, + onDestroy() {}, + }, + [editable, user, onTitleUpdate, hocuspocusProvider] + ); + const { width, fontSize } = useDocumentStyle(); + const editorWrapClassNames = useMemo(() => { + return width === 'standardWidth' ? styles.isStandardWidth : styles.isFullWidth; + }, [width]); + const getTocsContainer = useCallback(() => $mainContainer.current, []); + + useImperativeHandle(ref, () => editor); + + const protals = useMemo(() => { + if (!created || !renderInEditorPortal) return; + return renderInEditorPortal($mainContainer.current); + }, [created, renderInEditorPortal]); + + // 监听 ctrl+s + useEffect(() => { + const listener = (event: KeyboardEvent) => { + if ((event.ctrlKey || event.metaKey) && event.keyCode == 83) { + event.preventDefault(); + Toast.info(`${config.appName}会实时保存你的数据,无需手动保存。`); + return false; + } + }; + + window.document.addEventListener('keydown', listener); + + return () => { + window.document.removeEventListener('keydown', listener); + }; + }, [config.appName]); + + // 监听键盘收起、打开 + useEffect(() => { + if (!isMobile) return; + + let cleanUp = () => {}; + const focusIn = () => { + setTimeout(() => { + if (!$headerContainer.current) return; + $headerContainer.current.classList.add(styles.keyUp); + $headerContainer.current.scrollIntoView(); + }, 200); + }; + const focusOut = () => { + if (!$headerContainer.current) return; + $headerContainer.current.classList.remove(styles.iOSKeyUp); + }; + + if (isIOS()) { + document.body.addEventListener('focusin', focusIn); + document.body.addEventListener('focusout', focusOut); + cleanUp = () => { + document.body.removeEventListener('focusin', focusIn); + document.body.removeEventListener('focusout', focusOut); + }; + } else if (isAndroid) { + const originalHeight = document.documentElement.clientHeight || document.body.clientHeight; + window.onresize = function () { + //键盘弹起与隐藏都会引起窗口的高度发生变化 + const resizeHeight = document.documentElement.clientHeight || document.body.clientHeight; + if (resizeHeight < originalHeight) { + focusIn(); + } else { + focusOut(); + } + }; + } + + return () => { + cleanUp(); + }; + }, [isMobile]); + + return ( + <> + {(!online || status === 'disconnected') && ( + + )} + + {/* FIXME:需要菜单栏但是无法编辑,则认为进入了编辑模式但是没有编辑权限,也许有更好的判断 */} + {!editable && menubar && ( + // @ts-ignore + + )} + + {menubar && ( +
+ +
+ )} + +
+
+
+ +
+ {!editable && !hideComment && ( +
+ +
+ )} +
+ {!isMobile && ( +
+ +
+ )} + {protals} + {!editable && } +
+ $mainContainer.current} + style={{ right: isMobile ? 16 : 36, bottom: 65 }} + visibilityHeight={200} + /> + + ); +}); + +EditorInstance.displayName = 'EditorInstance'; diff --git a/packages/client/src/tiptap/editor/collaboration/collaboration/index.module.scss b/packages/client/src/tiptap/editor/collaboration/collaboration/index.module.scss new file mode 100644 index 0000000..1da0c86 --- /dev/null +++ b/packages/client/src/tiptap/editor/collaboration/collaboration/index.module.scss @@ -0,0 +1,76 @@ +.wrap { + display: flex; + width: 100%; + height: 100%; + min-height: 240px; + overflow: hidden; + flex-direction: column; + + > header { + z-index: 110; + display: flex; + justify-content: center; + height: 50px; + padding: 0 24px; + overflow: hidden; + background-color: var(--semi-color-nav-bg); + align-items: center; + border-bottom: 1px solid var(--semi-color-border); + user-select: none; + + &.mobileToolbar { + position: fixed; + right: 0; + bottom: 0; + left: 0; + z-index: 999; + display: flex; + height: 49px; + padding-right: env(safe-area-inset-right); + padding-bottom: env(safe-area-inset-bottom); + padding-left: env(safe-area-inset-left); + background: var(--semi-color-bg-1); + box-sizing: content-box; + justify-content: space-around; + align-items: center; + border-top: 1px solid var(--semi-color-border); + + &.keyUp { + position: absolute; + } + } + } + + > main { + position: relative; + display: flex; + overflow: auto; + /* stylelint-disable-next-line */ + overflow: overlay; + flex: 1; + justify-content: center; + flex-wrap: nowrap; + scroll-behavior: smooth; + + .contentWrap { + width: 100%; + + &.isStandardWidth { + max-width: 750px; + } + + &.isFullWidth { + max-width: 100%; + } + + .commentWrap { + padding: 16px 0 64px; + border-top: 1px solid var(--semi-color-border); + } + } + + .tocsWrap { + position: relative; + } + } +} diff --git a/packages/client/src/tiptap/editor/collaboration/collaboration/index.tsx b/packages/client/src/tiptap/editor/collaboration/collaboration/index.tsx new file mode 100644 index 0000000..5f0b404 --- /dev/null +++ b/packages/client/src/tiptap/editor/collaboration/collaboration/index.tsx @@ -0,0 +1,150 @@ +import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'; + +import { Spin, Typography } from '@douyinfe/semi-ui'; + +import { Editor } from 'tiptap/core'; +import { IndexeddbPersistence } from 'tiptap/core/thritypart/y-indexeddb'; + +import { HocuspocusProvider } from '@hocuspocus/provider'; +import { DataRender } from 'components/data-render'; +import deepEqual from 'deep-equal'; +import { useToggle } from 'hooks/use-toggle'; +import { SecureDocumentIllustration } from 'illustrations/secure-document'; + +import { EditorInstance } from './editor'; +import { ICollaborationEditorProps, ProviderStatus } from './type'; + +import styles from './index.module.scss'; + +const { Text } = Typography; + +export type ICollaborationRefProps = { + getEditor: () => Editor; +}; + +const errorContainerStyle = { + margin: '10%', + display: 'flex', + justifyContent: 'center', + flexDirection: 'column', + alignItems: 'center', +} as React.CSSProperties; + +export const CollaborationEditor = forwardRef((props: ICollaborationEditorProps, ref) => { + const { + id: documentId, + type, + editable, + onTitleUpdate, + user, + menubar, + hideComment, + renderInEditorPortal, + onAwarenessUpdate, + } = props; + const $editor = useRef(); + const [loading, toggleLoading] = useToggle(true); + const [error, setError] = useState(null); + const [status, setStatus] = useState('connecting'); + const lastAwarenessRef = useRef([]); + + const hocuspocusProvider = useMemo(() => { + return new HocuspocusProvider({ + url: process.env.COLLABORATION_API_URL, + name: documentId, + token: (user && user.token) || 'read-public', + parameters: { + targetId: documentId, + userId: user && user.id, + docType: type, + editable, + }, + maxAttempts: 1, + onAwarenessUpdate: ({ states }) => { + const users = states.map((state) => ({ clientId: state.clientId, user: state.user })); + if (deepEqual(user, lastAwarenessRef.current)) { + return; + } + onAwarenessUpdate && onAwarenessUpdate(users); + lastAwarenessRef.current = users; + }, + onAuthenticationFailed(e) { + toggleLoading(false); + setError(e || new Error('鉴权失败!暂时无法提供服务')); + }, + onSynced() { + toggleLoading(false); + }, + onStatus({ status }) { + setStatus(status); + }, + } as any); + }, [documentId, user, type, editable, onAwarenessUpdate, toggleLoading]); + + const renderEditor = useCallback( + () => ( + + ), + [documentId, editable, hideComment, hocuspocusProvider, menubar, onTitleUpdate, renderInEditorPortal, status, user] + ); + + const renderError = useCallback( + (error) => ( +
+ + {(error && error.message) || '未知错误'} +
+ ), + [] + ); + + useImperativeHandle( + ref, + () => + ({ + getEditor: () => $editor.current, + } as ICollaborationRefProps) + ); + + // 离线缓存 + useEffect(() => { + if (!editable) return; + const indexdbProvider = new IndexeddbPersistence(documentId, hocuspocusProvider.document); + indexdbProvider.on('synced', () => { + setStatus('loadCacheSuccess'); + }); + + return () => { + if (indexdbProvider) { + indexdbProvider.destroy(); + } + }; + }, [editable, documentId, hocuspocusProvider]); + + useEffect(() => { + return () => { + if (hocuspocusProvider) { + hocuspocusProvider.destroy(); + } + }; + }, [hocuspocusProvider]); + + return ( +
+ +
+ ); +}); + +CollaborationEditor.displayName = 'CollaborationEditor'; diff --git a/packages/client/src/tiptap/editor/collaboration/collaboration/menubar.tsx b/packages/client/src/tiptap/editor/collaboration/collaboration/menubar.tsx new file mode 100644 index 0000000..7844e56 --- /dev/null +++ b/packages/client/src/tiptap/editor/collaboration/collaboration/menubar.tsx @@ -0,0 +1,131 @@ +import React, { useMemo } from 'react'; + +import { Space } from '@douyinfe/semi-ui'; + +import { Editor } from 'tiptap/core'; +import { Align } from 'tiptap/core/menus/align'; +import { Attachment } from 'tiptap/core/menus/attachment'; +import { BackgroundColor } from 'tiptap/core/menus/background-color'; +import { Blockquote } from 'tiptap/core/menus/blockquote'; +import { Bold } from 'tiptap/core/menus/bold'; +import { BulletList } from 'tiptap/core/menus/bullet-list'; +import { Callout } from 'tiptap/core/menus/callout'; +import { CleadrNodeAndMarks } from 'tiptap/core/menus/clear-node-and-marks'; +import { Code } from 'tiptap/core/menus/code'; +import { CodeBlock } from 'tiptap/core/menus/code-block'; +import { Columns } from 'tiptap/core/menus/columns'; +import { Countdonw } from 'tiptap/core/menus/countdown'; +import { DocumentChildren } from 'tiptap/core/menus/document-children'; +import { DocumentReference } from 'tiptap/core/menus/document-reference'; +import { Emoji } from 'tiptap/core/menus/emoji'; +import { Excalidraw } from 'tiptap/core/menus/excalidraw'; +import { Flow } from 'tiptap/core/menus/flow'; +import { FontFamily } from 'tiptap/core/menus/fontfamily'; +import { FontSize } from 'tiptap/core/menus/fontsize'; +import { Heading } from 'tiptap/core/menus/heading'; +import { HorizontalRule } from 'tiptap/core/menus/horizontal-rule'; +import { Ident } from 'tiptap/core/menus/ident'; +import { Iframe } from 'tiptap/core/menus/iframe'; +import { Image } from 'tiptap/core/menus/image'; +import { Insert } from 'tiptap/core/menus/insert'; +import { Italic } from 'tiptap/core/menus/italic'; +import { Katex } from 'tiptap/core/menus/katex'; +import { LineHeight } from 'tiptap/core/menus/lineheight'; +import { Link } from 'tiptap/core/menus/link'; +import { Mind } from 'tiptap/core/menus/mind'; +import { OrderedList } from 'tiptap/core/menus/ordered-list'; +import { Redo } from 'tiptap/core/menus/redo'; +import { Search } from 'tiptap/core/menus/search'; +import { Strike } from 'tiptap/core/menus/strike'; +import { Subscript } from 'tiptap/core/menus/subscript'; +import { Superscript } from 'tiptap/core/menus/superscript'; +import { Table } from 'tiptap/core/menus/table'; +import { TaskList } from 'tiptap/core/menus/task-list'; +import { Text } from 'tiptap/core/menus/text'; +import { TextColor } from 'tiptap/core/menus/text-color'; +import { Underline } from 'tiptap/core/menus/underline'; +import { Undo } from 'tiptap/core/menus/undo'; + +import { Divider } from 'components/divider'; + +const _MenuBar: React.FC<{ editor: Editor }> = ({ editor }) => { + const isEditable = useMemo(() => editor && editor.isEditable, [editor]); + + if (!editor) return null; + + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + +