diff --git a/README.en.md b/README.en.md deleted file mode 100644 index f00a0eb35deb1d1d3b8a9a213b7f437938c6f3d2..0000000000000000000000000000000000000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# Dash-FastAPI - -#### Description -基于Dash+FastAPI开发的一个通用中后台管理系统 - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md index 98783591bb4f81e1daf07f22dcf0cbbdc5d09c4b..a47b72c78e072f5f02ed92f4f8475d1aced85073 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,127 @@ -# Dash-FastAPI +

+ logo +

+

Dash-FastAPI-Admin v1.0.0

+

基于Dash+FastAPI前后端分离的纯Python快速开发框架

+

+ + + +

-#### 介绍 -基于Dash+FastAPI开发的一个通用中后台管理系统 +## 平台简介 -#### 软件架构 -软件架构说明 +Dash-FastAPI-Admin是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。 +* 前端采用Dash、feffery-antd-components、feffery-utils-components。 +* 后端采用FastAPI、sqlalchemy、MySQL、Redis、OAuth2 & Jwt。 +* 权限认证使用OAuth2 & Jwt,支持多终端认证系统。 +* 支持加载动态权限菜单,多方式轻松权限控制。 +* 特别鸣谢:[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue)[feffery-antd-components](https://github.com/CNFeffery/feffery-antd-components)[feffery-utils-components](https://github.com/CNFeffery/feffery-utils-components)。 -#### 安装教程 +## 内置功能 -1. xxxx -2. xxxx -3. xxxx +1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。 +2. 角色管理:角色菜单权限分配。 +3. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。 +4. 部门管理:配置系统组织机构(公司、部门、小组)。 +5. 岗位管理:配置系统用户所属担任职务。 +6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。 +7. 参数管理:对系统动态配置常用参数。 +8. 通知公告:系统通知公告信息发布维护。 +9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。 +10. 登录日志:系统登录日志记录查询包含登录异常。 +11. 在线用户:当前系统中活跃用户状态监控。 +12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。 +13. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。 +14. 缓存监控:对系统的缓存信息查询,命令统计等。 +15. 系统接口:根据业务代码自动生成相关的api接口文档。 -#### 使用说明 +## 演示图 -1. xxxx -2. xxxx -3. xxxx + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-#### 参与贡献 +## 项目运行相关 -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request +```bash +# 克隆项目 +git clone https://gitee.com/insistence2022/dash-fastapi-admin.git +# 进入项目根目录 +cd Dash-FastAPI-Admin -#### 特技 +# 安装项目依赖环境 +pip3 install -r requirements.txt +``` -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +### 前端 +```bash +# 进入前端目录 +cd dash-fastapi-frontend + +# 运行前端 +python3 wsgi.py +``` + +### 后端 +```bash +# 进入后端目录 +cd dash-fastapi-backend + +# 配置环境 +1.在config/env.py的DataBaseConfig类中配置数据库环境 +2.在config/env.py的RedisConfig类中配置redis环境 + +# 运行sql文件 +1.新建数据库dash-fastapi(默认,可修改) +2.使用命令或数据库连接工具运行sql文件夹下的dash-fastapi.sql + +# 运行后端 +python3 app.py +``` + +### 访问 +```bash +# 默认账号密码 +账号:admin +密码:admin123 + +# 浏览器访问 +地址:http://127.0.0.1:8088 +``` \ No newline at end of file diff --git a/dash-fastapi-backend/app.py b/dash-fastapi-backend/app.py index 9ceb84f482fc457a268d6bb11e16cef350c489d9..da016c5c401aead81e7ce801c83b636509ddd426 100644 --- a/dash-fastapi-backend/app.py +++ b/dash-fastapi-backend/app.py @@ -1,25 +1,40 @@ from fastapi import FastAPI, Request import uvicorn -import aioredis -from fastapi.responses import JSONResponse -from fastapi.encoders import jsonable_encoder from fastapi.exceptions import HTTPException from fastapi.middleware.cors import CORSMiddleware from module_admin.controller.login_controller import loginController +from module_admin.controller.captcha_controller import captchaController from module_admin.controller.user_controller import userController from module_admin.controller.menu_controller import menuController from module_admin.controller.dept_controller import deptController from module_admin.controller.role_controller import roleController from module_admin.controller.post_controler import postController -from config.env import RedisConfig -from module_admin.utils.response_util import response_401, AuthException - - -app = FastAPI() +from module_admin.controller.dict_controller import dictController +from module_admin.controller.config_controller import configController +from module_admin.controller.notice_controller import noticeController +from module_admin.controller.log_controller import logController +from module_admin.controller.online_controller import onlineController +from module_admin.controller.job_controller import jobController +from module_admin.controller.server_controller import serverController +from module_admin.controller.cache_controller import cacheController +from module_admin.controller.common_controller import commonController +from config.get_redis import RedisUtil +from config.get_db import init_create_table +from config.get_scheduler import SchedulerUtil +from utils.response_util import * +from utils.log_util import logger +from utils.common_util import worship + +app = FastAPI( + title='Dash-FastAPI', + description='Dash-FastAPI接口文档', + version='1.0.0', +) # 前端页面url origins = [ "http://localhost:8088", + "http://127.0.0.1:8088", ] # 后台api允许跨域 @@ -32,29 +47,24 @@ app.add_middleware( ) -async def create_redis_pool() -> aioredis.Redis: - redis = await aioredis.from_url( - url=f"redis://{RedisConfig.HOST}", - port=RedisConfig.PORT, - username=RedisConfig.USERNAME, - password=RedisConfig.PASSWORD, - db=RedisConfig.DB, - encoding="utf-8", - decode_responses=True - ) - return redis - - @app.on_event("startup") async def startup_event(): - app.state.redis = await create_redis_pool() + logger.info("Dash-FastAPI开始启动") + worship() + await init_create_table() + app.state.redis = await RedisUtil.create_redis_pool() + await RedisUtil.init_sys_dict(app.state.redis) + await RedisUtil.init_sys_config(app.state.redis) + await SchedulerUtil.init_system_scheduler() + logger.info("Dash-FastAPI启动成功") @app.on_event("shutdown") async def shutdown_event(): - await app.state.redis.close() - - + await RedisUtil.close_redis_pool(app) + await SchedulerUtil.close_system_scheduler() + + # 自定义token检验异常 @app.exception_handler(AuthException) async def auth_exception_handler(request: Request, exc: AuthException): @@ -69,13 +79,22 @@ async def http_exception_handler(request: Request, exc: HTTPException): ) -app.include_router(loginController, prefix="/login", tags=['login']) -app.include_router(userController, prefix="/system", tags=['system/user']) -app.include_router(menuController, prefix="/system", tags=['system/menu']) -app.include_router(deptController, prefix="/system", tags=['system/dept']) -app.include_router(roleController, prefix="/system", tags=['system/role']) -app.include_router(postController, prefix="/system", tags=['system/post']) - +app.include_router(loginController, prefix="/login", tags=['登录模块']) +app.include_router(captchaController, prefix="/captcha", tags=['验证码模块']) +app.include_router(userController, prefix="/system", tags=['系统管理-用户管理']) +app.include_router(menuController, prefix="/system", tags=['系统管理-菜单管理']) +app.include_router(deptController, prefix="/system", tags=['系统管理-部门管理']) +app.include_router(roleController, prefix="/system", tags=['系统管理-角色管理']) +app.include_router(postController, prefix="/system", tags=['系统管理-岗位管理']) +app.include_router(dictController, prefix="/system", tags=['系统管理-字典管理']) +app.include_router(configController, prefix="/system", tags=['系统管理-参数管理']) +app.include_router(noticeController, prefix="/system", tags=['系统管理-通知公告管理']) +app.include_router(logController, prefix="/system", tags=['系统管理-日志管理']) +app.include_router(onlineController, prefix="/monitor", tags=['系统监控-在线用户']) +app.include_router(jobController, prefix="/monitor", tags=['系统监控-定时任务']) +app.include_router(serverController, prefix="/monitor", tags=['系统监控-服务监控']) +app.include_router(cacheController, prefix="/monitor", tags=['系统监控-缓存监控']) +app.include_router(commonController, prefix="/common", tags=['通用模块']) if __name__ == '__main__': uvicorn.run(app='app:app', host="127.0.0.1", port=9099, reload=True) diff --git a/dash-fastapi-backend/assets/font/Arial.ttf b/dash-fastapi-backend/assets/font/Arial.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9512aea86467504e94d97ddd6396955e1e6786f7 Binary files /dev/null and b/dash-fastapi-backend/assets/font/Arial.ttf differ diff --git a/dash-fastapi-backend/caches/avatar/admin_avatar.jpeg b/dash-fastapi-backend/caches/avatar/admin_avatar.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..58c3e92376f97cd5da3a16e1380210a365fc6c61 Binary files /dev/null and b/dash-fastapi-backend/caches/avatar/admin_avatar.jpeg differ diff --git a/dash-fastapi-backend/caches/avatar/ry_avatar.jpeg b/dash-fastapi-backend/caches/avatar/ry_avatar.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..7a683af3b9fceb35b19a74c94ce5da212b2b89e9 Binary files /dev/null and b/dash-fastapi-backend/caches/avatar/ry_avatar.jpeg differ diff --git a/dash-fastapi-backend/config/env.py b/dash-fastapi-backend/config/env.py index d6021630d26243abab17656a8f189ffcd557f167..ab9ddc2dfc2aed73498b728dc93ac4bec11b652f 100644 --- a/dash-fastapi-backend/config/env.py +++ b/dash-fastapi-backend/config/env.py @@ -1,3 +1,6 @@ +import os + + class JwtConfig: """ Jwt配置 @@ -5,6 +8,7 @@ class JwtConfig: SECRET_KEY = "b01c66dc2c58dc6a0aabfe2144256be36226de378bf87f72c0c795dda67f4d55" ALGORITHM = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES = 1440 + REDIS_TOKEN_EXPIRE_MINUTES = 30 class DataBaseConfig: @@ -27,3 +31,11 @@ class RedisConfig: USERNAME = '' PASSWORD = '' DB = 2 + + +class CachePathConfig: + """ + 缓存目录配置 + """ + PATH = os.path.join(os.path.abspath(os.getcwd()), 'caches') + PATHSTR = 'caches' diff --git a/dash-fastapi-backend/config/get_db.py b/dash-fastapi-backend/config/get_db.py index 391cf7f0bcfaba9710de8551c10f5f18770d4a2f..6d3a9cf40ff2f03fc33c327063fdaeb784825071 100644 --- a/dash-fastapi-backend/config/get_db.py +++ b/dash-fastapi-backend/config/get_db.py @@ -1,4 +1,5 @@ from config.database import * +from utils.log_util import logger def get_db_pro(): @@ -13,4 +14,14 @@ def get_db_pro(): current_db.close() +async def init_create_table(): + """ + 应用启动时初始化数据库连接 + :return: + """ + logger.info("初始化数据库连接...") + Base.metadata.create_all(bind=engine) + logger.info("数据库连接成功") + + get_db = get_db_pro diff --git a/dash-fastapi-backend/config/get_redis.py b/dash-fastapi-backend/config/get_redis.py new file mode 100644 index 0000000000000000000000000000000000000000..c7bc8ec6dfdca02c4670df43e2c4e55699ad8cb0 --- /dev/null +++ b/dash-fastapi-backend/config/get_redis.py @@ -0,0 +1,65 @@ +import aioredis +from module_admin.service.dict_service import DictDataService +from module_admin.service.config_service import ConfigService +from config.env import RedisConfig +from config.database import SessionLocal +from utils.log_util import logger + + +class RedisUtil: + """ + Redis相关方法 + """ + + @classmethod + async def create_redis_pool(cls) -> aioredis.Redis: + """ + 应用启动时初始化redis连接 + :return: Redis连接对象 + """ + logger.info("开始连接redis...") + redis = await aioredis.from_url( + url=f"redis://{RedisConfig.HOST}", + port=RedisConfig.PORT, + username=RedisConfig.USERNAME, + password=RedisConfig.PASSWORD, + db=RedisConfig.DB, + encoding="utf-8", + decode_responses=True + ) + logger.info("redis连接成功") + return redis + + @classmethod + async def close_redis_pool(cls, app): + """ + 应用关闭时关闭redis连接 + :param app: fastapi对象 + :return: + """ + await app.state.redis.close() + logger.info("关闭redis连接成功") + + @classmethod + async def init_sys_dict(cls, redis): + """ + 应用启动时缓存字典表 + :param redis: redis对象 + :return: + """ + session = SessionLocal() + await DictDataService.init_cache_sys_dict_services(session, redis) + + session.close() + + @classmethod + async def init_sys_config(cls, redis): + """ + 应用启动时缓存参数配置表 + :param redis: redis对象 + :return: + """ + session = SessionLocal() + await ConfigService.init_cache_sys_config_services(session, redis) + + session.close() diff --git a/dash-fastapi-backend/config/get_scheduler.py b/dash-fastapi-backend/config/get_scheduler.py new file mode 100644 index 0000000000000000000000000000000000000000..8ecad29f0957ce7efedf00da70cf7a2d05364a07 --- /dev/null +++ b/dash-fastapi-backend/config/get_scheduler.py @@ -0,0 +1,194 @@ +from apscheduler.schedulers.background import BackgroundScheduler +from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore +from apscheduler.jobstores.memory import MemoryJobStore +from apscheduler.jobstores.redis import RedisJobStore +from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor +from apscheduler.triggers.cron import CronTrigger +from apscheduler.events import EVENT_ALL +import json +from datetime import datetime, timedelta +from config.database import engine, SQLALCHEMY_DATABASE_URL, SessionLocal +from config.env import RedisConfig +from module_admin.service.job_log_service import JobLogService, JobLogModel +from module_admin.dao.job_dao import Session, JobDao +from utils.log_util import logger +import module_task + + +# 重写Cron定时 +class MyCronTrigger(CronTrigger): + @classmethod + def from_crontab(cls, expr, timezone=None): + values = expr.split() + if len(values) != 7: + raise ValueError('Wrong number of fields; got {}, expected 7'.format(len(values))) + + return cls(second=values[0], minute=values[1], hour=values[2], day=values[3], month=values[4], + day_of_week=values[5], year=values[6], timezone=timezone) + + +job_stores = { + 'default': MemoryJobStore(), + 'sqlalchemy': SQLAlchemyJobStore(url=SQLALCHEMY_DATABASE_URL, engine=engine), + 'redis': RedisJobStore( + **dict( + host=RedisConfig.HOST, + port=RedisConfig.PORT, + username=RedisConfig.USERNAME, + password=RedisConfig.PASSWORD, + db=RedisConfig.DB + ) + ) +} +executors = { + 'default': ThreadPoolExecutor(20), + 'processpool': ProcessPoolExecutor(5) +} +job_defaults = { + 'coalesce': False, + 'max_instance': 1 +} +scheduler = BackgroundScheduler() +scheduler.configure(jobstores=job_stores, executors=executors, job_defaults=job_defaults) + + +class SchedulerUtil: + """ + 定时任务相关方法 + """ + + @classmethod + async def init_system_scheduler(cls, result_db: Session = SessionLocal()): + """ + 应用启动时初始化定时任务 + :return: + """ + logger.info("开始启动定时任务...") + scheduler.start() + job_list = JobDao.get_job_list_for_scheduler(result_db) + for item in job_list: + query_job = cls.get_scheduler_job(job_id=str(item.job_id)) + if query_job: + cls.remove_scheduler_job(job_id=str(item.job_id)) + cls.add_scheduler_job(item) + result_db.close() + scheduler.add_listener(cls.scheduler_event_listener, EVENT_ALL) + logger.info("系统初始定时任务加载成功") + + @classmethod + async def close_system_scheduler(cls): + """ + 应用关闭时关闭定时任务 + :return: + """ + scheduler.shutdown() + logger.info("关闭定时任务成功") + + @classmethod + def get_scheduler_job(cls, job_id): + """ + 根据任务id获取任务对象 + :param job_id: 任务id + :return: 任务对象 + """ + query_job = scheduler.get_job(job_id=str(job_id)) + + return query_job + + @classmethod + def add_scheduler_job(cls, job_info): + """ + 根据输入的任务对象信息添加任务 + :param job_info: 任务对象信息 + :return: + """ + scheduler.add_job( + func=eval(job_info.invoke_target), + trigger=MyCronTrigger.from_crontab(job_info.cron_expression), + args=job_info.job_args.split(',') if job_info.job_args else None, + kwargs=json.loads(job_info.job_kwargs) if job_info.job_kwargs else None, + id=str(job_info.job_id), + name=job_info.job_name, + misfire_grace_time=1000000000000 if job_info.misfire_policy == '3' else None, + coalesce=True if job_info.misfire_policy == '2' else False, + max_instances=3 if job_info.concurrent == '0' else 1, + jobstore=job_info.job_group, + executor=job_info.job_executor + ) + + @classmethod + def execute_scheduler_job_once(cls, job_info): + """ + 根据输入的任务对象执行一次任务 + :param job_info: 任务对象信息 + :return: + """ + scheduler.add_job( + func=eval(job_info.invoke_target), + trigger='date', + run_date=datetime.now() + timedelta(seconds=1), + args=job_info.job_args.split(',') if job_info.job_args else None, + kwargs=json.loads(job_info.job_kwargs) if job_info.job_kwargs else None, + id=str(job_info.job_id), + name=job_info.job_name, + misfire_grace_time=1000000000000 if job_info.misfire_policy == '3' else None, + coalesce=True if job_info.misfire_policy == '2' else False, + max_instances=3 if job_info.concurrent == '0' else 1, + jobstore=job_info.job_group, + executor=job_info.job_executor + ) + + @classmethod + def remove_scheduler_job(cls, job_id): + """ + 根据任务id移除任务 + :param job_id: 任务id + :return: + """ + scheduler.remove_job(job_id=str(job_id)) + + @classmethod + def scheduler_event_listener(cls, event): + # 获取事件类型和任务ID + event_type = event.__class__.__name__ + # 获取任务执行异常信息 + status = '0' + exception_info = '' + if event_type == 'JobExecutionEvent' and event.exception: + exception_info = str(event.exception) + status = '1' + job_id = event.job_id + query_job = cls.get_scheduler_job(job_id=job_id) + if query_job: + query_job_info = query_job.__getstate__() + # 获取任务名称 + job_name = query_job_info.get('name') + # 获取任务组名 + job_group = query_job._jobstore_alias + # 获取任务执行器 + job_executor = query_job_info.get('executor') + # 获取调用目标字符串 + invoke_target = query_job_info.get('func') + # 获取调用函数位置参数 + job_args = ','.join(query_job_info.get('args')) + # 获取调用函数关键字参数 + job_kwargs = json.dumps(query_job_info.get('kwargs')) + # 获取任务触发器 + job_trigger = str(query_job_info.get('trigger')) + # 构造日志消息 + job_message = f"事件类型: {event_type}, 任务ID: {job_id}, 任务名称: {job_name}, 执行于{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}" + job_log = dict( + job_name=job_name, + job_group=job_group, + job_executor=job_executor, + invoke_target=invoke_target, + job_args=job_args, + job_kwargs=job_kwargs, + job_trigger=job_trigger, + job_message=job_message, + status=status, + exception_info=exception_info + ) + session = SessionLocal() + JobLogService.add_job_log_services(session, JobLogModel(**job_log)) + session.close() diff --git a/dash-fastapi-backend/module_admin/annotation/log_annotation.py b/dash-fastapi-backend/module_admin/annotation/log_annotation.py new file mode 100644 index 0000000000000000000000000000000000000000..37dc894045c9df84b5c67c316e09b4b767565879 --- /dev/null +++ b/dash-fastapi-backend/module_admin/annotation/log_annotation.py @@ -0,0 +1,164 @@ +from functools import wraps +from fastapi import Request +from fastapi.responses import JSONResponse, ORJSONResponse, UJSONResponse +import inspect +import os +import json +import time +from datetime import datetime +import requests +from user_agents import parse +from typing import Optional +from module_admin.service.login_service import get_current_user +from module_admin.service.log_service import OperationLogService, LoginLogService +from module_admin.entity.vo.log_vo import OperLogModel, LogininforModel + + +def log_decorator(title: str, business_type: int, log_type: Optional[str] = 'operation'): + """ + 日志装饰器 + :param log_type: 日志类型(login表示登录日志,为空表示为操作日志) + :param title: 当前日志装饰器装饰的模块标题 + :param business_type: 业务类型(0其它 1新增 2修改 3删除 4授权 5导出 6导入 7强退 8生成代码 9清空数据) + :return: + """ + def decorator(func): + @wraps(func) + async def wrapper(*args, **kwargs): + start_time = time.time() + # 获取被装饰函数的文件路径 + file_path = inspect.getfile(func) + # 获取项目根路径 + project_root = os.getcwd() + # 处理文件路径,去除项目根路径部分 + relative_path = os.path.relpath(file_path, start=project_root)[0:-2].replace('\\', '.') + # 获取当前被装饰函数所在路径 + func_path = f'{relative_path}{func.__name__}()' + # 获取上下文信息 + request: Request = kwargs.get('request') + token = request.headers.get('Authorization') + query_db = kwargs.get('query_db') + request_method = request.method + operator_type = 0 + user_agent = request.headers.get('User-Agent') + if "Windows" in user_agent or "Macintosh" in user_agent or "Linux" in user_agent: + operator_type = 1 + if "Mobile" in user_agent or "Android" in user_agent or "iPhone" in user_agent: + operator_type = 2 + # 获取请求的url + oper_url = request.url.path + # 获取请求的ip及ip归属区域 + oper_ip = request.headers.get('remote_addr') + oper_location = '内网IP' + try: + if oper_ip != '127.0.0.1' and oper_ip != 'localhost': + ip_result = requests.get(f'https://qifu-api.baidubce.com/ip/geo/v1/district?ip={oper_ip}') + if ip_result.status_code == 200: + prov = ip_result.json().get('data').get('prov') + city = ip_result.json().get('data').get('city') + if prov or city: + oper_location = f'{prov}-{city}' + else: + oper_location = '未知' + else: + oper_location = '未知' + except Exception as e: + oper_location = '未知' + print(e) + finally: + # 根据不同的请求类型使用不同的方法获取请求参数 + content_type = request.headers.get("Content-Type") + if content_type and ("multipart/form-data" in content_type or 'application/x-www-form-urlencoded' in content_type): + payload = await request.form() + oper_param = "\n".join([f"{key}: {value}" for key, value in payload.items()]) + else: + payload = await request.body() + oper_param = json.dumps(json.loads(str(payload, 'utf-8')), ensure_ascii=False) + # 日志表请求参数字段长度最大为2000,因此在此处判断长度 + if len(oper_param) > 2000: + oper_param = '请求参数过长' + + # 获取操作时间 + oper_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + # 此处在登录之前向原始函数传递一些登录信息,用于监测在线用户的相关信息 + login_log = {} + if log_type == 'login': + user_agent_info = parse(user_agent) + browser = f'{user_agent_info.browser.family} {user_agent_info.browser.version[0]}' + system_os = f'{user_agent_info.os.family} {user_agent_info.os.version[0]}' + login_log = dict( + ipaddr=oper_ip, + login_location=oper_location, + browser=browser, + os=system_os, + login_time=oper_time + ) + kwargs['form_data'].login_info = login_log + # 调用原始函数 + result = await func(*args, **kwargs) + # 获取请求耗时 + cost_time = float(time.time() - start_time) * 100 + # 判断请求是否来自api文档 + request_from_swagger = request.headers.get('referer').endswith('docs') if request.headers.get('referer') else False + request_from_redoc = request.headers.get('referer').endswith('redoc') if request.headers.get('referer') else False + # 根据响应结果的类型使用不同的方法获取响应结果参数 + if isinstance(result, JSONResponse) or isinstance(result, ORJSONResponse) or isinstance(result, UJSONResponse): + result_dict = json.loads(str(result.body, 'utf-8')) + else: + if request_from_swagger or request_from_redoc: + result_dict = {} + else: + if result.status_code == 200: + result_dict = {'code': result.status_code, 'message': '获取成功'} + else: + result_dict = {'code': result.status_code, 'message': '获取失败'} + json_result = json.dumps(dict(code=result_dict.get('code'), message=result_dict.get('message')), ensure_ascii=False) + # 根据响应结果获取响应状态及异常信息 + status = 1 + error_msg = '' + if result_dict.get('code') == 200: + status = 0 + else: + error_msg = result_dict.get('message') + # 根据日志类型向对应的日志表插入数据 + if log_type == 'login': + # 登录请求来自于api文档时不记录登录日志,其余情况则记录 + if request_from_swagger or request_from_redoc: + pass + else: + user = kwargs.get('form_data') + user_name = user.username + login_log['user_name'] = user_name + login_log['status'] = str(status) + login_log['msg'] = result_dict.get('message') + + LoginLogService.add_login_log_services(query_db, LogininforModel(**login_log)) + else: + current_user = await get_current_user(request, token, query_db) + oper_name = current_user.user.user_name + dept_name = current_user.dept.dept_name + operation_log = dict( + title=title, + business_type=business_type, + method=func_path, + request_method=request_method, + operator_type=operator_type, + oper_name=oper_name, + dept_name=dept_name, + oper_url=oper_url, + oper_ip=oper_ip, + oper_location=oper_location, + oper_param=oper_param, + json_result=json_result, + status=status, + error_msg=error_msg, + oper_time=oper_time, + cost_time=cost_time + ) + OperationLogService.add_operation_log_services(query_db, OperLogModel(**operation_log)) + + return result + + return wrapper + + return decorator diff --git a/dash-fastapi-backend/module_admin/aspect/interface_auth.py b/dash-fastapi-backend/module_admin/aspect/interface_auth.py new file mode 100644 index 0000000000000000000000000000000000000000..ebaaf14e2766aedf9f52c8a46e5484666a1ff08c --- /dev/null +++ b/dash-fastapi-backend/module_admin/aspect/interface_auth.py @@ -0,0 +1,19 @@ +from fastapi import Depends +from module_admin.entity.vo.user_vo import CurrentUserInfoServiceResponse +from module_admin.service.login_service import get_current_user +from utils.response_util import AuthException + + +class CheckUserInterfaceAuth: + """ + 校验当前用户是否具有相应的接口权限 + """ + def __init__(self, perm_str: str = 'common'): + self.perm_str = perm_str + + def __call__(self, current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): + user_auth_list = [item.perms for item in current_user.menu] + user_auth_list.append('common') + if self.perm_str in user_auth_list: + return True + raise AuthException(data="", message="该用户无此接口权限") diff --git a/dash-fastapi-backend/module_admin/controller/cache_controller.py b/dash-fastapi-backend/module_admin/controller/cache_controller.py new file mode 100644 index 0000000000000000000000000000000000000000..e18696b2af8d4993671dcd0b132fd01350884b87 --- /dev/null +++ b/dash-fastapi-backend/module_admin/controller/cache_controller.py @@ -0,0 +1,22 @@ +from fastapi import APIRouter +from fastapi import Depends +from module_admin.service.login_service import get_current_user +from module_admin.service.cache_service import * +from utils.response_util import * +from utils.log_util import * +from module_admin.aspect.interface_auth import CheckUserInterfaceAuth + + +cacheController = APIRouter(prefix='/cache', dependencies=[Depends(get_current_user)]) + + +@cacheController.post("/statisticalInfo", response_model=CacheMonitorModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:cache:list'))]) +async def get_monitor_cache_info(request: Request): + try: + # 获取全量数据 + cache_info_query_result = await CacheService.get_cache_monitor_statistical_info_services(request) + logger.info('获取成功') + return response_200(data=cache_info_query_result, message="获取成功") + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) diff --git a/dash-fastapi-backend/module_admin/controller/captcha_controller.py b/dash-fastapi-backend/module_admin/controller/captcha_controller.py new file mode 100644 index 0000000000000000000000000000000000000000..d6a28840228cce907ebe43161b79f62bc1532a9e --- /dev/null +++ b/dash-fastapi-backend/module_admin/controller/captcha_controller.py @@ -0,0 +1,24 @@ +import uuid +from fastapi import APIRouter, Request +from module_admin.service.captcha_service import * +from utils.response_util import * +from utils.log_util import * +from datetime import timedelta + + +captchaController = APIRouter() + + +@captchaController.post("/captchaImage") +async def get_captcha_image(request: Request): + try: + session_id = str(uuid.uuid4()) + captcha_result = CaptchaService.create_captcha_image_service() + image = captcha_result[0] + computed_result = captcha_result[1] + await request.app.state.redis.set(f'captcha_codes:{session_id}', computed_result, ex=timedelta(minutes=2)) + logger.info(f'编号为{session_id}的会话获取图片验证码成功') + return response_200(data={'image': image, 'session_id': session_id}, message='获取验证码成功') + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) diff --git a/dash-fastapi-backend/module_admin/controller/common_controller.py b/dash-fastapi-backend/module_admin/controller/common_controller.py new file mode 100644 index 0000000000000000000000000000000000000000..7844e0c3a6edc3814f49f09fefcb1d84518fe147 --- /dev/null +++ b/dash-fastapi-backend/module_admin/controller/common_controller.py @@ -0,0 +1,85 @@ +from fastapi import APIRouter, Request +from fastapi import Depends, File, Form +from config.env import CachePathConfig +from module_admin.service.login_service import get_current_user +from module_admin.service.common_service import * +from module_admin.service.config_service import ConfigService +from utils.response_util import * +from utils.log_util import * +from module_admin.aspect.interface_auth import CheckUserInterfaceAuth + + +commonController = APIRouter() + + +@commonController.post("/upload", dependencies=[Depends(get_current_user), Depends(CheckUserInterfaceAuth('common'))]) +async def common_upload(request: Request, uploadId: str = Form(), file: UploadFile = File(...)): + try: + try: + os.makedirs(os.path.join(CachePathConfig.PATH, uploadId)) + except FileExistsError: + pass + CommonService.upload_service(CachePathConfig.PATH, uploadId, file) + logger.info('上传成功') + return response_200(data={'filename': file.filename}, message="上传成功") + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@commonController.post("/uploadForEditor", dependencies=[Depends(get_current_user), Depends(CheckUserInterfaceAuth('common'))]) +async def editor_upload(request: Request, uploadId: str = Form(), file: UploadFile = File(...)): + try: + try: + os.makedirs(os.path.join(CachePathConfig.PATH, uploadId)) + except FileExistsError: + pass + CommonService.upload_service(CachePathConfig.PATH, uploadId, file) + logger.info('上传成功') + return JSONResponse( + status_code=status.HTTP_200_OK, + content=jsonable_encoder( + { + 'errno': 0, + 'data': { + 'url': f'{request.base_url}common/{CachePathConfig.PATHSTR}?taskId={uploadId}&filename={file.filename}' + }, + } + ) + ) + except Exception as e: + logger.exception(e) + return JSONResponse( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + content=jsonable_encoder( + { + 'errno': 1, + 'message': str(e), + } + ) + ) + + +@commonController.get(f"/{CachePathConfig.PATHSTR}") +def common_download(request: Request, taskId: str, filename: str): + try: + def generate_file(): + with open(os.path.join(CachePathConfig.PATH, taskId, filename), 'rb') as response_file: + yield from response_file + logger.info('获取成功') + return streaming_response_200(data=generate_file()) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@commonController.get("/config/query/{config_key}") +async def query_system_config(request: Request, config_key: str): + try: + # 获取全量数据 + config_query_result = await ConfigService.query_config_list_from_cache_services(request.app.state.redis, config_key) + logger.info('获取成功') + return response_200(data=config_query_result, message="获取成功") + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) diff --git a/dash-fastapi-backend/module_admin/controller/config_controller.py b/dash-fastapi-backend/module_admin/controller/config_controller.py new file mode 100644 index 0000000000000000000000000000000000000000..a8286e6217d76d1de602311330b51b0698c5eced --- /dev/null +++ b/dash-fastapi-backend/module_admin/controller/config_controller.py @@ -0,0 +1,123 @@ +from fastapi import APIRouter +from fastapi import Depends +from config.get_db import get_db +from module_admin.service.login_service import get_current_user, CurrentUserInfoServiceResponse +from module_admin.service.config_service import * +from module_admin.entity.vo.config_vo import * +from utils.response_util import * +from utils.log_util import * +from utils.page_util import get_page_obj +from utils.common_util import bytes2file_response +from module_admin.aspect.interface_auth import CheckUserInterfaceAuth +from module_admin.annotation.log_annotation import log_decorator + + +configController = APIRouter(dependencies=[Depends(get_current_user)]) + + +@configController.post("/config/get", response_model=ConfigPageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:config:list'))]) +async def get_system_config_list(request: Request, config_page_query: ConfigPageObject, query_db: Session = Depends(get_db)): + try: + config_query = ConfigQueryModel(**config_page_query.dict()) + # 获取全量数据 + config_query_result = ConfigService.get_config_list_services(query_db, config_query) + # 分页操作 + config_page_query_result = get_page_obj(config_query_result, config_page_query.page_num, config_page_query.page_size) + logger.info('获取成功') + return response_200(data=config_page_query_result, message="获取成功") + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@configController.post("/config/add", response_model=CrudConfigResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:config:add'))]) +@log_decorator(title='参数管理', business_type=1) +async def add_system_config(request: Request, add_config: ConfigModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): + try: + add_config.create_by = current_user.user.user_name + add_config.update_by = current_user.user.user_name + add_config_result = await ConfigService.add_config_services(request, query_db, add_config) + if add_config_result.is_success: + logger.info(add_config_result.message) + return response_200(data=add_config_result, message=add_config_result.message) + else: + logger.warning(add_config_result.message) + return response_400(data="", message=add_config_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@configController.patch("/config/edit", response_model=CrudConfigResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:config:edit'))]) +@log_decorator(title='参数管理', business_type=2) +async def edit_system_config(request: Request, edit_config: ConfigModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): + try: + edit_config.update_by = current_user.user.user_name + edit_config.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + edit_config_result = await ConfigService.edit_config_services(request, query_db, edit_config) + if edit_config_result.is_success: + logger.info(edit_config_result.message) + return response_200(data=edit_config_result, message=edit_config_result.message) + else: + logger.warning(edit_config_result.message) + return response_400(data="", message=edit_config_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@configController.post("/config/delete", response_model=CrudConfigResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:config:remove'))]) +@log_decorator(title='参数管理', business_type=3) +async def delete_system_config(request: Request, delete_config: DeleteConfigModel, query_db: Session = Depends(get_db)): + try: + delete_config_result = await ConfigService.delete_config_services(request, query_db, delete_config) + if delete_config_result.is_success: + logger.info(delete_config_result.message) + return response_200(data=delete_config_result, message=delete_config_result.message) + else: + logger.warning(delete_config_result.message) + return response_400(data="", message=delete_config_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@configController.get("/config/{config_id}", response_model=ConfigModel, dependencies=[Depends(CheckUserInterfaceAuth('system:config:query'))]) +async def query_detail_system_config(request: Request, config_id: int, query_db: Session = Depends(get_db)): + try: + detail_config_result = ConfigService.detail_config_services(query_db, config_id) + logger.info(f'获取config_id为{config_id}的信息成功') + return response_200(data=detail_config_result, message='获取成功') + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@configController.post("/config/export", dependencies=[Depends(CheckUserInterfaceAuth('system:config:export'))]) +@log_decorator(title='参数管理', business_type=5) +async def export_system_config_list(request: Request, config_query: ConfigQueryModel, query_db: Session = Depends(get_db)): + try: + # 获取全量数据 + config_query_result = ConfigService.get_config_list_services(query_db, config_query) + config_export_result = ConfigService.export_config_list_services(config_query_result) + logger.info('导出成功') + return streaming_response_200(data=bytes2file_response(config_export_result)) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@configController.post("/config/refresh", response_model=CrudConfigResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:config:edit'))]) +@log_decorator(title='参数管理', business_type=2) +async def refresh_system_config(request: Request, query_db: Session = Depends(get_db)): + try: + refresh_config_result = await ConfigService.refresh_sys_config_services(request, query_db) + if refresh_config_result.is_success: + logger.info(refresh_config_result.message) + return response_200(data=refresh_config_result, message=refresh_config_result.message) + else: + logger.warning(refresh_config_result.message) + return response_400(data="", message=refresh_config_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) diff --git a/dash-fastapi-backend/module_admin/controller/dept_controller.py b/dash-fastapi-backend/module_admin/controller/dept_controller.py index 69c87a50bfe941e77953c8d21d616e06ff7605e5..4103a9b3deccc167a6835014c48028535e4c46a1 100644 --- a/dash-fastapi-backend/module_admin/controller/dept_controller.py +++ b/dash-fastapi-backend/module_admin/controller/dept_controller.py @@ -1,74 +1,77 @@ from fastapi import APIRouter, Request -from fastapi import Depends, Header +from fastapi import Depends from config.get_db import get_db -from module_admin.service.login_service import get_current_user +from module_admin.service.login_service import get_current_user, CurrentUserInfoServiceResponse from module_admin.service.dept_service import * -from module_admin.entity.vo.dept_schema import * -from module_admin.mapper.dept_crud import * -from module_admin.utils.response_tool import * -from module_admin.utils.log_tool import * +from module_admin.entity.vo.dept_vo import * +from module_admin.dao.dept_dao import * +from utils.response_util import * +from utils.log_util import * +from module_admin.aspect.interface_auth import CheckUserInterfaceAuth +from module_admin.annotation.log_annotation import log_decorator deptController = APIRouter(dependencies=[Depends(get_current_user)]) -@deptController.post("/dept/tree", response_model=DeptTree) -async def get_system_dept_tree(dept_query: DeptModel, query_db: Session = Depends(get_db)): +@deptController.post("/dept/tree", response_model=DeptTree, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) +async def get_system_dept_tree(request: Request, dept_query: DeptModel, query_db: Session = Depends(get_db)): try: - dept_query_result = get_dept_tree_services(query_db, dept_query) + dept_query_result = DeptService.get_dept_tree_services(query_db, dept_query) logger.info('获取成功') return response_200(data=dept_query_result, message="获取成功") except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@deptController.post("/dept/forEditOption", response_model=DeptTree) -async def get_system_dept_tree_for_edit_option(dept_query: DeptModel, query_db: Session = Depends(get_db)): +@deptController.post("/dept/forEditOption", response_model=DeptTree, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) +async def get_system_dept_tree_for_edit_option(request: Request, dept_query: DeptModel, query_db: Session = Depends(get_db)): try: - dept_query_result = get_dept_tree_for_edit_option_services(query_db, dept_query) + dept_query_result = DeptService.get_dept_tree_for_edit_option_services(query_db, dept_query) logger.info('获取成功') return response_200(data=dept_query_result, message="获取成功") except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@deptController.post("/dept/get", response_model=DeptResponse) -async def get_system_dept_list(dept_query: DeptModel, query_db: Session = Depends(get_db)): +@deptController.post("/dept/get", response_model=DeptResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dept:list'))]) +async def get_system_dept_list(request: Request, dept_query: DeptModel, query_db: Session = Depends(get_db)): try: - dept_query_result = get_dept_list_services(query_db, dept_query) + dept_query_result = DeptService.get_dept_list_services(query_db, dept_query) logger.info('获取成功') return response_200(data=dept_query_result, message="获取成功") except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@deptController.post("/dept/add", response_model=CrudDeptResponse) -async def add_system_dept(request: Request, add_dept: DeptModel, token: Optional[str] = Header(...), query_db: Session = Depends(get_db)): +@deptController.post("/dept/add", response_model=CrudDeptResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dept:add'))]) +@log_decorator(title='部门管理', business_type=1) +async def add_system_dept(request: Request, add_dept: DeptModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): try: - current_user = await get_current_user(request, token, query_db) add_dept.create_by = current_user.user.user_name add_dept.update_by = current_user.user.user_name - add_dept_result = add_dept_services(query_db, add_dept) - logger.info(add_dept_result.message) + add_dept_result = DeptService.add_dept_services(query_db, add_dept) if add_dept_result.is_success: + logger.info(add_dept_result.message) return response_200(data=add_dept_result, message=add_dept_result.message) else: + logger.warning(add_dept_result.message) return response_400(data="", message=add_dept_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@deptController.patch("/dept/edit", response_model=CrudDeptResponse) -async def edit_system_dept(request: Request, edit_dept: DeptModel, token: Optional[str] = Header(...), query_db: Session = Depends(get_db)): +@deptController.patch("/dept/edit", response_model=CrudDeptResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dept:edit'))]) +@log_decorator(title='部门管理', business_type=2) +async def edit_system_dept(request: Request, edit_dept: DeptModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): try: - current_user = await get_current_user(request, token, query_db) edit_dept.update_by = current_user.user.user_name edit_dept.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - edit_dept_result = edit_dept_services(query_db, edit_dept) + edit_dept_result = DeptService.edit_dept_services(query_db, edit_dept) if edit_dept_result.is_success: logger.info(edit_dept_result.message) return response_200(data=edit_dept_result, message=edit_dept_result.message) @@ -77,16 +80,16 @@ async def edit_system_dept(request: Request, edit_dept: DeptModel, token: Option return response_400(data="", message=edit_dept_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@deptController.post("/dept/delete", response_model=CrudDeptResponse) -async def delete_system_dept(request: Request, delete_dept: DeleteDeptModel, token: Optional[str] = Header(...), query_db: Session = Depends(get_db)): +@deptController.post("/dept/delete", response_model=CrudDeptResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dept:remove'))]) +@log_decorator(title='部门管理', business_type=3) +async def delete_system_dept(request: Request, delete_dept: DeleteDeptModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): try: - current_user = await get_current_user(request, token, query_db) delete_dept.update_by = current_user.user.user_name delete_dept.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - delete_dept_result = delete_dept_services(query_db, delete_dept) + delete_dept_result = DeptService.delete_dept_services(query_db, delete_dept) if delete_dept_result.is_success: logger.info(delete_dept_result.message) return response_200(data=delete_dept_result, message=delete_dept_result.message) @@ -95,15 +98,15 @@ async def delete_system_dept(request: Request, delete_dept: DeleteDeptModel, tok return response_400(data="", message=delete_dept_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@deptController.get("/dept/{dept_id}", response_model=DeptModel) -async def query_detail_system_dept(dept_id: int, query_db: Session = Depends(get_db)): +@deptController.get("/dept/{dept_id}", response_model=DeptModel, dependencies=[Depends(CheckUserInterfaceAuth('system:dept:query'))]) +async def query_detail_system_dept(request: Request, dept_id: int, query_db: Session = Depends(get_db)): try: - detail_dept_result = detail_dept_services(query_db, dept_id) + detail_dept_result = DeptService.detail_dept_services(query_db, dept_id) logger.info(f'获取dept_id为{dept_id}的信息成功') return response_200(data=detail_dept_result, message='获取成功') except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) diff --git a/dash-fastapi-backend/module_admin/controller/dict_controller.py b/dash-fastapi-backend/module_admin/controller/dict_controller.py new file mode 100644 index 0000000000000000000000000000000000000000..dcb090626fcdbb24f0ed694728b2a5ec2fb45041 --- /dev/null +++ b/dash-fastapi-backend/module_admin/controller/dict_controller.py @@ -0,0 +1,238 @@ +from fastapi import APIRouter +from fastapi import Depends +from config.get_db import get_db +from module_admin.service.login_service import get_current_user, CurrentUserInfoServiceResponse +from module_admin.service.dict_service import * +from module_admin.entity.vo.dict_vo import * +from utils.response_util import * +from utils.log_util import * +from utils.page_util import get_page_obj +from utils.common_util import bytes2file_response +from module_admin.aspect.interface_auth import CheckUserInterfaceAuth +from module_admin.annotation.log_annotation import log_decorator + + +dictController = APIRouter(dependencies=[Depends(get_current_user)]) + + +@dictController.post("/dictType/get", response_model=DictTypePageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:list'))]) +async def get_system_dict_type_list(request: Request, dict_type_page_query: DictTypePageObject, query_db: Session = Depends(get_db)): + try: + dict_type_query = DictTypeQueryModel(**dict_type_page_query.dict()) + # 获取全量数据 + dict_type_query_result = DictTypeService.get_dict_type_list_services(query_db, dict_type_query) + # 分页操作 + dict_type_page_query_result = get_page_obj(dict_type_query_result, dict_type_page_query.page_num, dict_type_page_query.page_size) + logger.info('获取成功') + return response_200(data=dict_type_page_query_result, message="获取成功") + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@dictController.post("/dictType/all", dependencies=[Depends(CheckUserInterfaceAuth('system:dict:list'))]) +async def get_system_all_dict_type(request: Request, dict_type_query: DictTypeQueryModel, query_db: Session = Depends(get_db)): + try: + dict_type_query_result = DictTypeService.get_all_dict_type_services(query_db) + logger.info('获取成功') + return response_200(data=dict_type_query_result, message="获取成功") + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@dictController.post("/dictType/add", response_model=CrudDictResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:add'))]) +@log_decorator(title='字典管理', business_type=1) +async def add_system_dict_type(request: Request, add_dict_type: DictTypeModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): + try: + add_dict_type.create_by = current_user.user.user_name + add_dict_type.update_by = current_user.user.user_name + add_dict_type_result = await DictTypeService.add_dict_type_services(request, query_db, add_dict_type) + if add_dict_type_result.is_success: + logger.info(add_dict_type_result.message) + return response_200(data=add_dict_type_result, message=add_dict_type_result.message) + else: + logger.warning(add_dict_type_result.message) + return response_400(data="", message=add_dict_type_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@dictController.patch("/dictType/edit", response_model=CrudDictResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:edit'))]) +@log_decorator(title='字典管理', business_type=2) +async def edit_system_dict_type(request: Request, edit_dict_type: DictTypeModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): + try: + edit_dict_type.update_by = current_user.user.user_name + edit_dict_type.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + edit_dict_type_result = await DictTypeService.edit_dict_type_services(request, query_db, edit_dict_type) + if edit_dict_type_result.is_success: + logger.info(edit_dict_type_result.message) + return response_200(data=edit_dict_type_result, message=edit_dict_type_result.message) + else: + logger.warning(edit_dict_type_result.message) + return response_400(data="", message=edit_dict_type_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@dictController.post("/dictType/delete", response_model=CrudDictResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:remove'))]) +@log_decorator(title='字典管理', business_type=3) +async def delete_system_dict_type(request: Request, delete_dict_type: DeleteDictTypeModel, query_db: Session = Depends(get_db)): + try: + delete_dict_type_result = await DictTypeService.delete_dict_type_services(request, query_db, delete_dict_type) + if delete_dict_type_result.is_success: + logger.info(delete_dict_type_result.message) + return response_200(data=delete_dict_type_result, message=delete_dict_type_result.message) + else: + logger.warning(delete_dict_type_result.message) + return response_400(data="", message=delete_dict_type_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@dictController.get("/dictType/{dict_id}", response_model=DictTypeModel, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:query'))]) +async def query_detail_system_dict_type(request: Request, dict_id: int, query_db: Session = Depends(get_db)): + try: + detail_dict_type_result = DictTypeService.detail_dict_type_services(query_db, dict_id) + logger.info(f'获取dict_id为{dict_id}的信息成功') + return response_200(data=detail_dict_type_result, message='获取成功') + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@dictController.post("/dictType/export", dependencies=[Depends(CheckUserInterfaceAuth('system:dict:export'))]) +@log_decorator(title='字典管理', business_type=5) +async def export_system_dict_type_list(request: Request, dict_type_query: DictTypeQueryModel, query_db: Session = Depends(get_db)): + try: + # 获取全量数据 + dict_type_query_result = DictTypeService.get_dict_type_list_services(query_db, dict_type_query) + dict_type_export_result = DictTypeService.export_dict_type_list_services(dict_type_query_result) + logger.info('导出成功') + return streaming_response_200(data=bytes2file_response(dict_type_export_result)) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@dictController.post("/dictType/refresh", response_model=CrudDictResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:edit'))]) +@log_decorator(title='字典管理', business_type=2) +async def refresh_system_dict(request: Request, query_db: Session = Depends(get_db)): + try: + refresh_dict_result = await DictTypeService.refresh_sys_dict_services(request, query_db) + if refresh_dict_result.is_success: + logger.info(refresh_dict_result.message) + return response_200(data=refresh_dict_result, message=refresh_dict_result.message) + else: + logger.warning(refresh_dict_result.message) + return response_400(data="", message=refresh_dict_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@dictController.post("/dictData/get", response_model=DictDataPageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:list'))]) +async def get_system_dict_data_list(request: Request, dict_data_page_query: DictDataPageObject, query_db: Session = Depends(get_db)): + try: + dict_data_query = DictDataModel(**dict_data_page_query.dict()) + # 获取全量数据 + dict_data_query_result = DictDataService.get_dict_data_list_services(query_db, dict_data_query) + # 分页操作 + dict_data_page_query_result = get_page_obj(dict_data_query_result, dict_data_page_query.page_num, dict_data_page_query.page_size) + logger.info('获取成功') + return response_200(data=dict_data_page_query_result, message="获取成功") + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@dictController.get("/dictData/query/{dict_type}", dependencies=[Depends(CheckUserInterfaceAuth('system:dict:list'))]) +async def query_system_dict_data_list(request: Request, dict_type: str, query_db: Session = Depends(get_db)): + try: + # 获取全量数据 + dict_data_query_result = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type) + logger.info('获取成功') + return response_200(data=dict_data_query_result, message="获取成功") + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@dictController.post("/dictData/add", response_model=CrudDictResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:add'))]) +@log_decorator(title='字典管理', business_type=1) +async def add_system_dict_data(request: Request, add_dict_data: DictDataModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): + try: + add_dict_data.create_by = current_user.user.user_name + add_dict_data.update_by = current_user.user.user_name + add_dict_data_result = await DictDataService.add_dict_data_services(request, query_db, add_dict_data) + if add_dict_data_result.is_success: + logger.info(add_dict_data_result.message) + return response_200(data=add_dict_data_result, message=add_dict_data_result.message) + else: + logger.warning(add_dict_data_result.message) + return response_400(data="", message=add_dict_data_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@dictController.patch("/dictData/edit", response_model=CrudDictResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:edit'))]) +@log_decorator(title='字典管理', business_type=2) +async def edit_system_dict_data(request: Request, edit_dict_data: DictDataModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): + try: + edit_dict_data.update_by = current_user.user.user_name + edit_dict_data.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + edit_dict_data_result = await DictDataService.edit_dict_data_services(request, query_db, edit_dict_data) + if edit_dict_data_result.is_success: + logger.info(edit_dict_data_result.message) + return response_200(data=edit_dict_data_result, message=edit_dict_data_result.message) + else: + logger.warning(edit_dict_data_result.message) + return response_400(data="", message=edit_dict_data_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@dictController.post("/dictData/delete", response_model=CrudDictResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:remove'))]) +@log_decorator(title='字典管理', business_type=3) +async def delete_system_dict_data(request: Request, delete_dict_data: DeleteDictDataModel, query_db: Session = Depends(get_db)): + try: + delete_dict_data_result = await DictDataService.delete_dict_data_services(request, query_db, delete_dict_data) + if delete_dict_data_result.is_success: + logger.info(delete_dict_data_result.message) + return response_200(data=delete_dict_data_result, message=delete_dict_data_result.message) + else: + logger.warning(delete_dict_data_result.message) + return response_400(data="", message=delete_dict_data_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@dictController.get("/dictData/{dict_code}", response_model=DictDataModel, dependencies=[Depends(CheckUserInterfaceAuth('system:dict:query'))]) +async def query_detail_system_dict_data(request: Request, dict_code: int, query_db: Session = Depends(get_db)): + try: + detail_dict_data_result = DictDataService.detail_dict_data_services(query_db, dict_code) + logger.info(f'获取dict_code为{dict_code}的信息成功') + return response_200(data=detail_dict_data_result, message='获取成功') + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@dictController.post("/dictData/export", dependencies=[Depends(CheckUserInterfaceAuth('system:dict:export'))]) +@log_decorator(title='字典管理', business_type=5) +async def export_system_dict_data_list(request: Request, dict_data_query: DictDataModel, query_db: Session = Depends(get_db)): + try: + # 获取全量数据 + dict_data_query_result = DictDataService.get_dict_data_list_services(query_db, dict_data_query) + dict_data_export_result = DictDataService.export_dict_data_list_services(dict_data_query_result) + logger.info('导出成功') + return streaming_response_200(data=bytes2file_response(dict_data_export_result)) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) diff --git a/dash-fastapi-backend/module_admin/controller/job_controller.py b/dash-fastapi-backend/module_admin/controller/job_controller.py new file mode 100644 index 0000000000000000000000000000000000000000..adf7ec54c0c27057b2c0ece672cbe9d09c33ebb2 --- /dev/null +++ b/dash-fastapi-backend/module_admin/controller/job_controller.py @@ -0,0 +1,196 @@ +from fastapi import APIRouter +from fastapi import Depends +from config.get_db import get_db +from module_admin.service.login_service import get_current_user, CurrentUserInfoServiceResponse +from module_admin.service.job_service import * +from module_admin.service.job_log_service import * +from module_admin.entity.vo.job_vo import * +from utils.response_util import * +from utils.log_util import * +from utils.page_util import get_page_obj +from utils.common_util import bytes2file_response +from module_admin.aspect.interface_auth import CheckUserInterfaceAuth +from module_admin.annotation.log_annotation import log_decorator + + +jobController = APIRouter(dependencies=[Depends(get_current_user)]) + + +@jobController.post("/job/get", response_model=JobPageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:list'))]) +async def get_system_job_list(request: Request, job_page_query: JobPageObject, query_db: Session = Depends(get_db)): + try: + job_query = JobModel(**job_page_query.dict()) + # 获取全量数据 + job_query_result = JobService.get_job_list_services(query_db, job_query) + # 分页操作 + notice_page_query_result = get_page_obj(job_query_result, job_page_query.page_num, job_page_query.page_size) + logger.info('获取成功') + return response_200(data=notice_page_query_result, message="获取成功") + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@jobController.post("/job/add", response_model=CrudJobResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:add'))]) +@log_decorator(title='定时任务管理', business_type=1) +async def add_system_job(request: Request, add_job: JobModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): + try: + add_job.create_by = current_user.user.user_name + add_job.update_by = current_user.user.user_name + add_job_result = JobService.add_job_services(query_db, add_job) + if add_job_result.is_success: + logger.info(add_job_result.message) + return response_200(data=add_job_result, message=add_job_result.message) + else: + logger.warning(add_job_result.message) + return response_400(data="", message=add_job_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@jobController.patch("/job/edit", response_model=CrudJobResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:edit'))]) +@log_decorator(title='定时任务管理', business_type=2) +async def edit_system_job(request: Request, edit_job: EditJobModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): + try: + edit_job.update_by = current_user.user.user_name + edit_job.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + edit_job_result = JobService.edit_job_services(query_db, edit_job) + if edit_job_result.is_success: + logger.info(edit_job_result.message) + return response_200(data=edit_job_result, message=edit_job_result.message) + else: + logger.warning(edit_job_result.message) + return response_400(data="", message=edit_job_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@jobController.post("/job/changeStatus", response_model=CrudJobResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:changeStatus'))]) +@log_decorator(title='定时任务管理', business_type=2) +async def execute_system_job(request: Request, execute_job: JobModel, query_db: Session = Depends(get_db)): + try: + execute_job_result = JobService.execute_job_once_services(query_db, execute_job) + if execute_job_result.is_success: + logger.info(execute_job_result.message) + return response_200(data=execute_job_result, message=execute_job_result.message) + else: + logger.warning(execute_job_result.message) + return response_400(data="", message=execute_job_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@jobController.post("/job/delete", response_model=CrudJobResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))]) +@log_decorator(title='定时任务管理', business_type=3) +async def delete_system_job(request: Request, delete_job: DeleteJobModel, query_db: Session = Depends(get_db)): + try: + delete_job_result = JobService.delete_job_services(query_db, delete_job) + if delete_job_result.is_success: + logger.info(delete_job_result.message) + return response_200(data=delete_job_result, message=delete_job_result.message) + else: + logger.warning(delete_job_result.message) + return response_400(data="", message=delete_job_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@jobController.get("/job/{job_id}", response_model=JobModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:query'))]) +async def query_detail_system_job(request: Request, job_id: int, query_db: Session = Depends(get_db)): + try: + detail_job_result = JobService.detail_job_services(query_db, job_id) + logger.info(f'获取job_id为{job_id}的信息成功') + return response_200(data=detail_job_result, message='获取成功') + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@jobController.post("/job/export", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:export'))]) +@log_decorator(title='定时任务管理', business_type=5) +async def export_system_job_list(request: Request, job_query: JobModel, query_db: Session = Depends(get_db)): + try: + # 获取全量数据 + job_query_result = JobService.get_job_list_services(query_db, job_query) + job_export_result = await JobService.export_job_list_services(request, job_query_result) + logger.info('导出成功') + return streaming_response_200(data=bytes2file_response(job_export_result)) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@jobController.post("/jobLog/get", response_model=JobLogPageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:list'))]) +async def get_system_job_log_list(request: Request, job_log_page_query: JobLogPageObject, query_db: Session = Depends(get_db)): + try: + job_log_query = JobLogQueryModel(**job_log_page_query.dict()) + # 获取全量数据 + job_log_query_result = JobLogService.get_job_log_list_services(query_db, job_log_query) + # 分页操作 + notice_page_query_result = get_page_obj(job_log_query_result, job_log_page_query.page_num, job_log_page_query.page_size) + logger.info('获取成功') + return response_200(data=notice_page_query_result, message="获取成功") + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@jobController.post("/jobLog/delete", response_model=CrudJobResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))]) +@log_decorator(title='定时任务日志管理', business_type=3) +async def delete_system_job_log(request: Request, delete_job_log: DeleteJobLogModel, query_db: Session = Depends(get_db)): + try: + delete_job_log_result = JobLogService.delete_job_log_services(query_db, delete_job_log) + if delete_job_log_result.is_success: + logger.info(delete_job_log_result.message) + return response_200(data=delete_job_log_result, message=delete_job_log_result.message) + else: + logger.warning(delete_job_log_result.message) + return response_400(data="", message=delete_job_log_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@jobController.post("/jobLog/clear", response_model=CrudJobResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:remove'))]) +@log_decorator(title='定时任务日志管理', business_type=9) +async def clear_system_job_log(request: Request, clear_job_log: ClearJobLogModel, query_db: Session = Depends(get_db)): + try: + clear_job_log_result = JobLogService.clear_job_log_services(query_db, clear_job_log) + if clear_job_log_result.is_success: + logger.info(clear_job_log_result.message) + return response_200(data=clear_job_log_result, message=clear_job_log_result.message) + else: + logger.warning(clear_job_log_result.message) + return response_400(data="", message=clear_job_log_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@jobController.get("/jobLog/{job_log_id}", response_model=JobLogModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:query'))]) +async def query_detail_system_job_log(request: Request, job_log_id: int, query_db: Session = Depends(get_db)): + try: + detail_job_log_result = JobLogService.detail_job_log_services(query_db, job_log_id) + logger.info(f'获取job_log_id为{job_log_id}的信息成功') + return response_200(data=detail_job_log_result, message='获取成功') + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@jobController.post("/jobLog/export", dependencies=[Depends(CheckUserInterfaceAuth('monitor:job:export'))]) +@log_decorator(title='定时任务日志管理', business_type=5) +async def export_system_job_log_list(request: Request, job_log_query: JobLogQueryModel, query_db: Session = Depends(get_db)): + try: + # 获取全量数据 + job_log_query_result = JobLogService.get_job_log_list_services(query_db, job_log_query) + job_log_export_result = JobLogService.export_job_log_list_services(query_db, job_log_query_result) + logger.info('导出成功') + return streaming_response_200(data=bytes2file_response(job_log_export_result)) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) diff --git a/dash-fastapi-backend/module_admin/controller/log_controller.py b/dash-fastapi-backend/module_admin/controller/log_controller.py new file mode 100644 index 0000000000000000000000000000000000000000..3e7175c29dd1ce07989751641964376f52f9423c --- /dev/null +++ b/dash-fastapi-backend/module_admin/controller/log_controller.py @@ -0,0 +1,164 @@ +from fastapi import APIRouter +from fastapi import Depends +from config.get_db import get_db +from module_admin.service.login_service import get_current_user +from module_admin.service.log_service import * +from module_admin.entity.vo.log_vo import * +from utils.response_util import * +from utils.log_util import * +from utils.page_util import get_page_obj +from utils.common_util import bytes2file_response +from module_admin.aspect.interface_auth import CheckUserInterfaceAuth +from module_admin.annotation.log_annotation import log_decorator + + +logController = APIRouter(prefix='/log', dependencies=[Depends(get_current_user)]) + + +@logController.post("/operation/get", response_model=OperLogPageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:list'))]) +async def get_system_operation_log_list(request: Request, operation_log_page_query: OperLogPageObject, query_db: Session = Depends(get_db)): + try: + operation_log_query = OperLogQueryModel(**operation_log_page_query.dict()) + # 获取全量数据 + operation_log_query_result = OperationLogService.get_operation_log_list_services(query_db, operation_log_query) + # 分页操作 + operation_log_page_query_result = get_page_obj(operation_log_query_result, operation_log_page_query.page_num, operation_log_page_query.page_size) + logger.info('获取成功') + return response_200(data=operation_log_page_query_result, message="获取成功") + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@logController.post("/operation/delete", response_model=CrudLogResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:remove'))]) +@log_decorator(title='操作日志管理', business_type=3) +async def delete_system_operation_log(request: Request, delete_operation_log: DeleteOperLogModel, query_db: Session = Depends(get_db)): + try: + delete_operation_log_result = OperationLogService.delete_operation_log_services(query_db, delete_operation_log) + if delete_operation_log_result.is_success: + logger.info(delete_operation_log_result.message) + return response_200(data=delete_operation_log_result, message=delete_operation_log_result.message) + else: + logger.warning(delete_operation_log_result.message) + return response_400(data="", message=delete_operation_log_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@logController.post("/operation/clear", response_model=CrudLogResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:remove'))]) +@log_decorator(title='操作日志管理', business_type=9) +async def clear_system_operation_log(request: Request, clear_operation_log: ClearOperLogModel, query_db: Session = Depends(get_db)): + try: + clear_operation_log_result = OperationLogService.clear_operation_log_services(query_db, clear_operation_log) + if clear_operation_log_result.is_success: + logger.info(clear_operation_log_result.message) + return response_200(data=clear_operation_log_result, message=clear_operation_log_result.message) + else: + logger.warning(clear_operation_log_result.message) + return response_400(data="", message=clear_operation_log_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@logController.get("/operation/{oper_id}", response_model=OperLogModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:query'))]) +async def query_detail_system_operation_log(request: Request, oper_id: int, query_db: Session = Depends(get_db)): + try: + detail_operation_log_result = OperationLogService.detail_operation_log_services(query_db, oper_id) + logger.info(f'获取oper_id为{oper_id}的信息成功') + return response_200(data=detail_operation_log_result, message='获取成功') + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@logController.post("/operation/export", dependencies=[Depends(CheckUserInterfaceAuth('monitor:operlog:export'))]) +@log_decorator(title='操作日志管理', business_type=5) +async def export_system_operation_log_list(request: Request, operation_log_query: OperLogQueryModel, query_db: Session = Depends(get_db)): + try: + # 获取全量数据 + operation_log_query_result = OperationLogService.get_operation_log_list_services(query_db, operation_log_query) + operation_log_export_result = await OperationLogService.export_operation_log_list_services(request, operation_log_query_result) + logger.info('导出成功') + return streaming_response_200(data=bytes2file_response(operation_log_export_result)) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@logController.post("/login/get", response_model=LoginLogPageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:list'))]) +async def get_system_login_log_list(request: Request, login_log_page_query: LoginLogPageObject, query_db: Session = Depends(get_db)): + try: + login_log_query = LoginLogQueryModel(**login_log_page_query.dict()) + # 获取全量数据 + login_log_query_result = LoginLogService.get_login_log_list_services(query_db, login_log_query) + # 分页操作 + login_log_page_query_result = get_page_obj(login_log_query_result, login_log_page_query.page_num, login_log_page_query.page_size) + logger.info('获取成功') + return response_200(data=login_log_page_query_result, message="获取成功") + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@logController.post("/login/delete", response_model=CrudLogResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:remove'))]) +@log_decorator(title='登录日志管理', business_type=3) +async def delete_system_login_log(request: Request, delete_login_log: DeleteLoginLogModel, query_db: Session = Depends(get_db)): + try: + delete_login_log_result = LoginLogService.delete_login_log_services(query_db, delete_login_log) + if delete_login_log_result.is_success: + logger.info(delete_login_log_result.message) + return response_200(data=delete_login_log_result, message=delete_login_log_result.message) + else: + logger.warning(delete_login_log_result.message) + return response_400(data="", message=delete_login_log_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@logController.post("/login/clear", response_model=CrudLogResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:remove'))]) +@log_decorator(title='登录日志管理', business_type=9) +async def clear_system_login_log(request: Request, clear_login_log: ClearLoginLogModel, query_db: Session = Depends(get_db)): + try: + clear_login_log_result = LoginLogService.clear_login_log_services(query_db, clear_login_log) + if clear_login_log_result.is_success: + logger.info(clear_login_log_result.message) + return response_200(data=clear_login_log_result, message=clear_login_log_result.message) + else: + logger.warning(clear_login_log_result.message) + return response_400(data="", message=clear_login_log_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@logController.post("/login/unlock", response_model=CrudLogResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:unlock'))]) +@log_decorator(title='登录日志管理', business_type=0) +async def clear_system_login_log(request: Request, unlock_user: UnlockUser, query_db: Session = Depends(get_db)): + try: + unlock_user_result = await LoginLogService.unlock_user_services(request, unlock_user) + if unlock_user_result.is_success: + logger.info(unlock_user_result.message) + return response_200(data=unlock_user_result, message=unlock_user_result.message) + else: + logger.warning(unlock_user_result.message) + return response_400(data="", message=unlock_user_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@logController.post("/login/export", dependencies=[Depends(CheckUserInterfaceAuth('monitor:logininfor:export'))]) +@log_decorator(title='登录日志管理', business_type=5) +async def export_system_login_log_list(request: Request, login_log_query: LoginLogQueryModel, query_db: Session = Depends(get_db)): + try: + # 获取全量数据 + login_log_query_result = LoginLogService.get_login_log_list_services(query_db, login_log_query) + login_log_export_result = LoginLogService.export_login_log_list_services(login_log_query_result) + logger.info('导出成功') + return streaming_response_200(data=bytes2file_response(login_log_export_result)) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) diff --git a/dash-fastapi-backend/module_admin/controller/login_controller.py b/dash-fastapi-backend/module_admin/controller/login_controller.py index c934add26ab599bd338415209d44131b8a70748b..3a88f9d2ae9619b676933a9a7e43a6655b3ed36e 100644 --- a/dash-fastapi-backend/module_admin/controller/login_controller.py +++ b/dash-fastapi-backend/module_admin/controller/login_controller.py @@ -1,11 +1,12 @@ -import uuid from fastapi import APIRouter from module_admin.service.login_service import * -from module_admin.entity.vo.login_schema import * -from module_admin.mapper.login_crud import * +from module_admin.entity.vo.login_vo import * +from module_admin.dao.login_dao import * from config.env import JwtConfig -from module_admin.utils.response_tool import * -from module_admin.utils.log_tool import * +from utils.response_util import * +from utils.log_util import * +from module_admin.aspect.interface_auth import CheckUserInterfaceAuth +from module_admin.annotation.log_annotation import log_decorator from datetime import timedelta @@ -13,56 +14,104 @@ loginController = APIRouter() @loginController.post("/loginByAccount", response_model=Token) -async def login(request: Request, user: UserLogin, query_db: Session = Depends(get_db)): +@log_decorator(title='用户登录', business_type=0, log_type='login') +async def login(request: Request, form_data: CustomOAuth2PasswordRequestForm = Depends(), query_db: Session = Depends(get_db)): + captcha_enabled = True if await request.app.state.redis.get(f'sys_config:sys.account.captchaEnabled') == 'true' else False + user = UserLogin( + **dict( + user_name=form_data.username, + password=form_data.password, + captcha=form_data.captcha, + session_id=form_data.session_id, + login_info=form_data.login_info, + captcha_enabled=captcha_enabled + ) + ) try: - result = authenticate_user(query_db, user.user_name, user.password) - if result == '用户不存在' or result == '密码错误' or result == '用户已停用': - logger.warning(result) - return response_400(data="", message=result) + result = await authenticate_user(request, query_db, user) + except LoginException as e: + return response_400(data="", message=e.message) + try: + access_token_expires = timedelta(minutes=JwtConfig.ACCESS_TOKEN_EXPIRE_MINUTES) + session_id = str(uuid.uuid4()) + access_token = create_access_token( + data={ + "user_id": str(result[0].user_id), + "user_name": result[0].user_name, + "dept_name": result[1].dept_name, + "session_id": session_id, + "login_info": user.login_info + }, + expires_delta=access_token_expires + ) + await request.app.state.redis.set(f'access_token:{session_id}', access_token, + ex=timedelta(minutes=JwtConfig.REDIS_TOKEN_EXPIRE_MINUTES)) + # 此方法可实现同一账号同一时间只能登录一次 + # await request.app.state.redis.set(f'{result.user_id}_access_token', access_token, ex=timedelta(minutes=30)) + # await request.app.state.redis.set(f'{result.user_id}_session_id', session_id, ex=timedelta(minutes=30)) + logger.info('登录成功') + # 判断请求是否来自于api文档,如果是返回指定格式的结果,用于修复api文档认证成功后token显示undefined的bug + request_from_swagger = request.headers.get('referer').endswith('docs') if request.headers.get('referer') else False + request_from_redoc = request.headers.get('referer').endswith('redoc') if request.headers.get('referer') else False + if request_from_swagger or request_from_redoc: + return {'access_token': access_token, 'token_type': 'Bearer'} + return response_200( + data={'access_token': access_token, 'token_type': 'Bearer'}, + message='登录成功' + ) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + +@loginController.post("/getSmsCode", response_model=SmsCode) +async def get_sms_code(request: Request, user: ResetUserModel, query_db: Session = Depends(get_db)): + try: + sms_result = await get_sms_code_services(request, query_db, user) + if sms_result.is_success: + logger.info('获取成功') + return response_200(data=sms_result, message='获取成功') + else: + logger.warning(sms_result.message) + return response_400(data='', message=sms_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@loginController.post("/forgetPwd", response_model=CrudUserResponse) +async def forget_user_pwd(request: Request, forget_user: ResetUserModel, query_db: Session = Depends(get_db)): + try: + forget_user_result = await forget_user_services(request, query_db, forget_user) + if forget_user_result.is_success: + logger.info(forget_user_result.message) + return response_200(data=forget_user_result, message=forget_user_result.message) else: - access_token_expires = timedelta(minutes=JwtConfig.ACCESS_TOKEN_EXPIRE_MINUTES) - try: - session_id = str(uuid.uuid4()) - access_token = create_access_token( - data={"user_id": str(result.user_id), "session_id": session_id}, expires_delta=access_token_expires - ) - await request.app.state.redis.set(f'{result.user_id}_access_token', access_token, ex=timedelta(minutes=30)) - await request.app.state.redis.set(f'{result.user_id}_session_id', session_id, ex=timedelta(minutes=30)) - logger.info('登录成功') - return response_200( - data={ - 'token': access_token, - 'session_id': session_id, - }, - message='登录成功' - ) - except Exception as e: - logger.exception(e) - return response_500(data="", message="生成token失败") + logger.warning(forget_user_result.message) + return response_400(data="", message=forget_user_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@loginController.post("/getLoginUserInfo", response_model=CurrentUserInfoServiceResponse, dependencies=[Depends(get_current_user)]) -async def get_login_user_info(request: Request, token: Optional[str] = Header(...), query_db: Session = Depends(get_db)): +@loginController.post("/getLoginUserInfo", response_model=CurrentUserInfoServiceResponse, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) +async def get_login_user_info(request: Request, current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): try: - current_user = await get_current_user(request, token, query_db) logger.info('获取成功') return response_200(data=current_user, message="获取成功") except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@loginController.post("/logout", dependencies=[Depends(get_current_user)]) -async def logout(request: Request, token: Optional[str] = Header(...), query_db: Session = Depends(get_db)): +@loginController.post("/logout", dependencies=[Depends(get_current_user), Depends(CheckUserInterfaceAuth('common'))]) +async def logout(request: Request, token: Optional[str] = Depends(oauth2_scheme), query_db: Session = Depends(get_db)): try: - current_user = await get_current_user(request, token, query_db) - await logout_services(request, current_user) + payload = jwt.decode(token, JwtConfig.SECRET_KEY, algorithms=[JwtConfig.ALGORITHM]) + session_id: str = payload.get("session_id") + await logout_services(request, session_id) logger.info('退出成功') return response_200(data="", message="退出成功") except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) diff --git a/dash-fastapi-backend/module_admin/controller/menu_controller.py b/dash-fastapi-backend/module_admin/controller/menu_controller.py index 70e273a33524bad78224057b862497105a83bd17..51c13220c47b5099fb7f93c54f4b42023b29f21d 100644 --- a/dash-fastapi-backend/module_admin/controller/menu_controller.py +++ b/dash-fastapi-backend/module_admin/controller/menu_controller.py @@ -1,74 +1,77 @@ from fastapi import APIRouter, Request -from fastapi import Depends, Header +from fastapi import Depends from config.get_db import get_db from module_admin.service.login_service import get_current_user from module_admin.service.menu_service import * -from module_admin.entity.vo.menu_schema import * -from module_admin.mapper.menu_crud import * -from module_admin.utils.response_tool import * -from module_admin.utils.log_tool import * +from module_admin.entity.vo.menu_vo import * +from module_admin.dao.menu_dao import * +from utils.response_util import * +from utils.log_util import * +from module_admin.aspect.interface_auth import CheckUserInterfaceAuth +from module_admin.annotation.log_annotation import log_decorator menuController = APIRouter(dependencies=[Depends(get_current_user)]) -@menuController.post("/menu/tree", response_model=MenuTree) -async def get_system_menu_tree(menu_query: MenuTreeModel, query_db: Session = Depends(get_db)): +@menuController.post("/menu/tree", response_model=MenuTree, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) +async def get_system_menu_tree(request: Request, menu_query: MenuTreeModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): try: - menu_query_result = get_menu_tree_services(query_db, menu_query) + menu_query_result = MenuService.get_menu_tree_services(query_db, menu_query, current_user) logger.info('获取成功') return response_200(data=menu_query_result, message="获取成功") except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@menuController.post("/menu/forEditOption", response_model=MenuTree) -async def get_system_menu_tree_for_edit_option(menu_query: MenuModel, query_db: Session = Depends(get_db)): +@menuController.post("/menu/forEditOption", response_model=MenuTree, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) +async def get_system_menu_tree_for_edit_option(request: Request, menu_query: MenuModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): try: - menu_query_result = get_menu_tree_for_edit_option_services(query_db, menu_query) + menu_query_result = MenuService.get_menu_tree_for_edit_option_services(query_db, menu_query, current_user) logger.info('获取成功') return response_200(data=menu_query_result, message="获取成功") except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@menuController.post("/menu/get", response_model=MenuResponse) -async def get_system_menu_list(menu_query: MenuModel, query_db: Session = Depends(get_db)): +@menuController.post("/menu/get", response_model=MenuResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:menu:list'))]) +async def get_system_menu_list(request: Request, menu_query: MenuModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): try: - menu_query_result = get_menu_list_services(query_db, menu_query) + menu_query_result = MenuService.get_menu_list_services(query_db, menu_query, current_user) logger.info('获取成功') return response_200(data=menu_query_result, message="获取成功") except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@menuController.post("/menu/add", response_model=CrudMenuResponse) -async def add_system_menu(request: Request, add_menu: MenuModel, token: Optional[str] = Header(...), query_db: Session = Depends(get_db)): +@menuController.post("/menu/add", response_model=CrudMenuResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:menu:add'))]) +@log_decorator(title='菜单管理', business_type=1) +async def add_system_menu(request: Request, add_menu: MenuModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): try: - current_user = await get_current_user(request, token, query_db) add_menu.create_by = current_user.user.user_name add_menu.update_by = current_user.user.user_name - add_menu_result = add_menu_services(query_db, add_menu) - logger.info(add_menu_result.message) + add_menu_result = MenuService.add_menu_services(query_db, add_menu) if add_menu_result.is_success: + logger.info(add_menu_result.message) return response_200(data=add_menu_result, message=add_menu_result.message) else: + logger.warning(add_menu_result.message) return response_400(data="", message=add_menu_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@menuController.patch("/menu/edit", response_model=CrudMenuResponse) -async def edit_system_menu(request: Request, edit_menu: MenuModel, token: Optional[str] = Header(...), query_db: Session = Depends(get_db)): +@menuController.patch("/menu/edit", response_model=CrudMenuResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:menu:edit'))]) +@log_decorator(title='菜单管理', business_type=2) +async def edit_system_menu(request: Request, edit_menu: MenuModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): try: - current_user = await get_current_user(request, token, query_db) edit_menu.update_by = current_user.user.user_name edit_menu.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - edit_menu_result = edit_menu_services(query_db, edit_menu) + edit_menu_result = MenuService.edit_menu_services(query_db, edit_menu) if edit_menu_result.is_success: logger.info(edit_menu_result.message) return response_200(data=edit_menu_result, message=edit_menu_result.message) @@ -77,13 +80,14 @@ async def edit_system_menu(request: Request, edit_menu: MenuModel, token: Option return response_400(data="", message=edit_menu_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@menuController.post("/menu/delete", response_model=CrudMenuResponse) -async def delete_system_menu(delete_menu: DeleteMenuModel, query_db: Session = Depends(get_db)): +@menuController.post("/menu/delete", response_model=CrudMenuResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:menu:remove'))]) +@log_decorator(title='菜单管理', business_type=3) +async def delete_system_menu(request: Request, delete_menu: DeleteMenuModel, query_db: Session = Depends(get_db)): try: - delete_menu_result = delete_menu_services(query_db, delete_menu) + delete_menu_result = MenuService.delete_menu_services(query_db, delete_menu) if delete_menu_result.is_success: logger.info(delete_menu_result.message) return response_200(data=delete_menu_result, message=delete_menu_result.message) @@ -92,15 +96,15 @@ async def delete_system_menu(delete_menu: DeleteMenuModel, query_db: Session = D return response_400(data="", message=delete_menu_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@menuController.get("/menu/{menu_id}", response_model=MenuModel) -async def query_detail_system_menu(menu_id: int, query_db: Session = Depends(get_db)): +@menuController.get("/menu/{menu_id}", response_model=MenuModel, dependencies=[Depends(CheckUserInterfaceAuth('system:menu:query'))]) +async def query_detail_system_menu(request: Request, menu_id: int, query_db: Session = Depends(get_db)): try: - detail_menu_result = detail_menu_services(query_db, menu_id) + detail_menu_result = MenuService.detail_menu_services(query_db, menu_id) logger.info(f'获取menu_id为{menu_id}的信息成功') return response_200(data=detail_menu_result, message='获取成功') except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) diff --git a/dash-fastapi-backend/module_admin/controller/notice_controller.py b/dash-fastapi-backend/module_admin/controller/notice_controller.py new file mode 100644 index 0000000000000000000000000000000000000000..cbda2de2fd2baba1e2ea0ae4113b8fed5970b363 --- /dev/null +++ b/dash-fastapi-backend/module_admin/controller/notice_controller.py @@ -0,0 +1,92 @@ +from fastapi import APIRouter, Request +from fastapi import Depends +from config.get_db import get_db +from module_admin.service.login_service import get_current_user, CurrentUserInfoServiceResponse +from module_admin.service.notice_service import * +from module_admin.entity.vo.notice_vo import * +from utils.response_util import * +from utils.log_util import * +from utils.page_util import get_page_obj +from module_admin.aspect.interface_auth import CheckUserInterfaceAuth +from module_admin.annotation.log_annotation import log_decorator + + +noticeController = APIRouter(dependencies=[Depends(get_current_user)]) + + +@noticeController.post("/notice/get", response_model=NoticePageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:notice:list'))]) +async def get_system_notice_list(request: Request, notice_page_query: NoticePageObject, query_db: Session = Depends(get_db)): + try: + notice_query = NoticeQueryModel(**notice_page_query.dict()) + # 获取全量数据 + notice_query_result = NoticeService.get_notice_list_services(query_db, notice_query) + # 分页操作 + notice_page_query_result = get_page_obj(notice_query_result, notice_page_query.page_num, notice_page_query.page_size) + logger.info('获取成功') + return response_200(data=notice_page_query_result, message="获取成功") + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@noticeController.post("/notice/add", response_model=CrudNoticeResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:notice:add'))]) +@log_decorator(title='通知公告管理', business_type=1) +async def add_system_notice(request: Request, add_notice: NoticeModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): + try: + add_notice.create_by = current_user.user.user_name + add_notice.update_by = current_user.user.user_name + add_notice_result = NoticeService.add_notice_services(query_db, add_notice) + if add_notice_result.is_success: + logger.info(add_notice_result.message) + return response_200(data=add_notice_result, message=add_notice_result.message) + else: + logger.warning(add_notice_result.message) + return response_400(data="", message=add_notice_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@noticeController.patch("/notice/edit", response_model=CrudNoticeResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:notice:edit'))]) +@log_decorator(title='通知公告管理', business_type=2) +async def edit_system_notice(request: Request, edit_notice: NoticeModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): + try: + edit_notice.update_by = current_user.user.user_name + edit_notice.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + edit_notice_result = NoticeService.edit_notice_services(query_db, edit_notice) + if edit_notice_result.is_success: + logger.info(edit_notice_result.message) + return response_200(data=edit_notice_result, message=edit_notice_result.message) + else: + logger.warning(edit_notice_result.message) + return response_400(data="", message=edit_notice_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@noticeController.post("/notice/delete", response_model=CrudNoticeResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:notice:remove'))]) +@log_decorator(title='通知公告管理', business_type=3) +async def delete_system_notice(request: Request, delete_notice: DeleteNoticeModel, query_db: Session = Depends(get_db)): + try: + delete_notice_result = NoticeService.delete_notice_services(query_db, delete_notice) + if delete_notice_result.is_success: + logger.info(delete_notice_result.message) + return response_200(data=delete_notice_result, message=delete_notice_result.message) + else: + logger.warning(delete_notice_result.message) + return response_400(data="", message=delete_notice_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@noticeController.get("/notice/{notice_id}", response_model=NoticeModel, dependencies=[Depends(CheckUserInterfaceAuth('system:notice:query'))]) +async def query_detail_system_post(request: Request, notice_id: int, query_db: Session = Depends(get_db)): + try: + detail_notice_result = NoticeService.detail_notice_services(query_db, notice_id) + logger.info(f'获取notice_id为{notice_id}的信息成功') + return response_200(data=detail_notice_result, message='获取成功') + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) diff --git a/dash-fastapi-backend/module_admin/controller/online_controller.py b/dash-fastapi-backend/module_admin/controller/online_controller.py new file mode 100644 index 0000000000000000000000000000000000000000..9390c8b0e15e12cfc88fe10047a72b41b0fe4276 --- /dev/null +++ b/dash-fastapi-backend/module_admin/controller/online_controller.py @@ -0,0 +1,59 @@ +from fastapi import APIRouter +from fastapi import Depends +from config.get_db import get_db +from module_admin.service.login_service import get_current_user, Session +from module_admin.service.online_service import * +from utils.response_util import * +from utils.log_util import * +from utils.page_util import get_page_obj +from module_admin.aspect.interface_auth import CheckUserInterfaceAuth +from module_admin.annotation.log_annotation import log_decorator + + +onlineController = APIRouter(prefix='/online', dependencies=[Depends(get_current_user)]) + + +@onlineController.post("/get", response_model=OnlinePageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:online:list'))]) +async def get_monitor_online_list(request: Request, online_page_query: OnlinePageObject): + try: + # 获取全量数据 + online_query_result = await OnlineService.get_online_list_services(request, online_page_query) + # 分页操作 + online_page_query_result = get_page_obj(online_query_result, online_page_query.page_num, online_page_query.page_size) + logger.info('获取成功') + return response_200(data=online_page_query_result, message="获取成功") + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@onlineController.post("/forceLogout", response_model=CrudOnlineResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:online:forceLogout'))]) +@log_decorator(title='在线用户', business_type=7) +async def delete_monitor_online(request: Request, delete_online: DeleteOnlineModel, query_db: Session = Depends(get_db)): + try: + delete_online_result = await OnlineService.delete_online_services(request, delete_online) + if delete_online_result.is_success: + logger.info(delete_online_result.message) + return response_200(data=delete_online_result, message=delete_online_result.message) + else: + logger.warning(delete_online_result.message) + return response_400(data="", message=delete_online_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@onlineController.post("/batchLogout", response_model=CrudOnlineResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:online:batchLogout'))]) +@log_decorator(title='在线用户', business_type=7) +async def delete_monitor_online(request: Request, delete_online: DeleteOnlineModel, query_db: Session = Depends(get_db)): + try: + delete_online_result = await OnlineService.delete_online_services(request, delete_online) + if delete_online_result.is_success: + logger.info(delete_online_result.message) + return response_200(data=delete_online_result, message=delete_online_result.message) + else: + logger.warning(delete_online_result.message) + return response_400(data="", message=delete_online_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) diff --git a/dash-fastapi-backend/module_admin/controller/post_controler.py b/dash-fastapi-backend/module_admin/controller/post_controler.py index c6d9614173529a1585da466749e79a6d709188d3..e917826c67b3be0df04844c95203a14d4805a975 100644 --- a/dash-fastapi-backend/module_admin/controller/post_controler.py +++ b/dash-fastapi-backend/module_admin/controller/post_controler.py @@ -1,62 +1,71 @@ from fastapi import APIRouter, Request -from fastapi import Depends, Header +from fastapi import Depends from config.get_db import get_db -from module_admin.service.login_service import get_current_user +from module_admin.service.login_service import get_current_user, CurrentUserInfoServiceResponse from module_admin.service.post_service import * -from module_admin.entity.vo.post_schema import * -from module_admin.utils.response_tool import * -from module_admin.utils.log_tool import * +from module_admin.entity.vo.post_vo import * +from utils.response_util import * +from utils.log_util import * +from utils.page_util import get_page_obj +from utils.common_util import bytes2file_response +from module_admin.aspect.interface_auth import CheckUserInterfaceAuth +from module_admin.annotation.log_annotation import log_decorator postController = APIRouter(dependencies=[Depends(get_current_user)]) -@postController.post("/post/forSelectOption", response_model=PostSelectOptionResponseModel) -async def get_system_post_select(query_db: Session = Depends(get_db)): +@postController.post("/post/forSelectOption", response_model=PostSelectOptionResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) +async def get_system_post_select(request: Request, query_db: Session = Depends(get_db)): try: - role_query_result = get_post_select_option_services(query_db) + role_query_result = PostService.get_post_select_option_services(query_db) logger.info('获取成功') return response_200(data=role_query_result, message="获取成功") except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@postController.post("/post/get", response_model=PostPageObjectResponse) -async def get_system_post_list(post_query: PostPageObject, query_db: Session = Depends(get_db)): +@postController.post("/post/get", response_model=PostPageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:post:list'))]) +async def get_system_post_list(request: Request, post_page_query: PostPageObject, query_db: Session = Depends(get_db)): try: - post_query_result = get_post_list_services(query_db, post_query) + post_query = PostModel(**post_page_query.dict()) + # 获取全量数据 + post_query_result = PostService.get_post_list_services(query_db, post_query) + # 分页操作 + post_page_query_result = get_page_obj(post_query_result, post_page_query.page_num, post_page_query.page_size) logger.info('获取成功') - return response_200(data=post_query_result, message="获取成功") + return response_200(data=post_page_query_result, message="获取成功") except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@postController.post("/post/add", response_model=CrudPostResponse) -async def add_system_post(request: Request, add_post: PostModel, token: Optional[str] = Header(...), query_db: Session = Depends(get_db)): +@postController.post("/post/add", response_model=CrudPostResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:post:add'))]) +@log_decorator(title='岗位管理', business_type=1) +async def add_system_post(request: Request, add_post: PostModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): try: - current_user = await get_current_user(request, token, query_db) add_post.create_by = current_user.user.user_name add_post.update_by = current_user.user.user_name - add_post_result = add_post_services(query_db, add_post) - logger.info(add_post_result.message) + add_post_result = PostService.add_post_services(query_db, add_post) if add_post_result.is_success: + logger.info(add_post_result.message) return response_200(data=add_post_result, message=add_post_result.message) else: + logger.warning(add_post_result.message) return response_400(data="", message=add_post_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@postController.patch("/post/edit", response_model=CrudPostResponse) -async def edit_system_post(request: Request, edit_post: PostModel, token: Optional[str] = Header(...), query_db: Session = Depends(get_db)): +@postController.patch("/post/edit", response_model=CrudPostResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:post:edit'))]) +@log_decorator(title='岗位管理', business_type=2) +async def edit_system_post(request: Request, edit_post: PostModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): try: - current_user = await get_current_user(request, token, query_db) edit_post.update_by = current_user.user.user_name edit_post.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - edit_post_result = edit_post_services(query_db, edit_post) + edit_post_result = PostService.edit_post_services(query_db, edit_post) if edit_post_result.is_success: logger.info(edit_post_result.message) return response_200(data=edit_post_result, message=edit_post_result.message) @@ -65,13 +74,14 @@ async def edit_system_post(request: Request, edit_post: PostModel, token: Option return response_400(data="", message=edit_post_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@postController.post("/post/delete", response_model=CrudPostResponse) -async def delete_system_post(delete_post: DeletePostModel, query_db: Session = Depends(get_db)): +@postController.post("/post/delete", response_model=CrudPostResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:post:remove'))]) +@log_decorator(title='岗位管理', business_type=3) +async def delete_system_post(request: Request, delete_post: DeletePostModel, query_db: Session = Depends(get_db)): try: - delete_post_result = delete_post_services(query_db, delete_post) + delete_post_result = PostService.delete_post_services(query_db, delete_post) if delete_post_result.is_success: logger.info(delete_post_result.message) return response_200(data=delete_post_result, message=delete_post_result.message) @@ -80,15 +90,29 @@ async def delete_system_post(delete_post: DeletePostModel, query_db: Session = D return response_400(data="", message=delete_post_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@postController.get("/post/{post_id}", response_model=PostModel) -async def query_detail_system_post(post_id: int, query_db: Session = Depends(get_db)): +@postController.get("/post/{post_id}", response_model=PostModel, dependencies=[Depends(CheckUserInterfaceAuth('system:post:query'))]) +async def query_detail_system_post(request: Request, post_id: int, query_db: Session = Depends(get_db)): try: - detail_post_result = detail_post_services(query_db, post_id) + detail_post_result = PostService.detail_post_services(query_db, post_id) logger.info(f'获取post_id为{post_id}的信息成功') return response_200(data=detail_post_result, message='获取成功') except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) + + +@postController.post("/post/export", dependencies=[Depends(CheckUserInterfaceAuth('system:post:export'))]) +@log_decorator(title='岗位管理', business_type=5) +async def export_system_post_list(request: Request, post_query: PostModel, query_db: Session = Depends(get_db)): + try: + # 获取全量数据 + post_query_result = PostService.get_post_list_services(query_db, post_query) + post_export_result = PostService.export_post_list_services(post_query_result) + logger.info('导出成功') + return streaming_response_200(data=bytes2file_response(post_export_result)) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) diff --git a/dash-fastapi-backend/module_admin/controller/role_controller.py b/dash-fastapi-backend/module_admin/controller/role_controller.py index 7d53d83c423d5b369fb8e4108aa80beba97013ba..348ab9d526c1d18913e5f27d56dd6c1f90b87607 100644 --- a/dash-fastapi-backend/module_admin/controller/role_controller.py +++ b/dash-fastapi-backend/module_admin/controller/role_controller.py @@ -1,62 +1,70 @@ from fastapi import APIRouter, Request -from fastapi import Depends, Header +from fastapi import Depends from config.get_db import get_db -from module_admin.service.login_service import get_current_user +from module_admin.service.login_service import get_current_user, CurrentUserInfoServiceResponse from module_admin.service.role_service import * -from module_admin.entity.vo.role_schema import * -from module_admin.utils.response_tool import * -from module_admin.utils.log_tool import * +from module_admin.entity.vo.role_vo import * +from utils.response_util import * +from utils.log_util import * +from utils.page_util import get_page_obj +from utils.common_util import bytes2file_response +from module_admin.aspect.interface_auth import CheckUserInterfaceAuth +from module_admin.annotation.log_annotation import log_decorator roleController = APIRouter(dependencies=[Depends(get_current_user)]) -@roleController.post("/role/forSelectOption", response_model=RoleSelectOptionResponseModel) -async def get_system_role_select(query_db: Session = Depends(get_db)): +@roleController.post("/role/forSelectOption", response_model=RoleSelectOptionResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) +async def get_system_role_select(request: Request, query_db: Session = Depends(get_db)): try: - role_query_result = get_role_select_option_services(query_db) + role_query_result = RoleService.get_role_select_option_services(query_db) logger.info('获取成功') return response_200(data=role_query_result, message="获取成功") except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@roleController.post("/role/get", response_model=RolePageObjectResponse) -async def get_system_role_list(role_query: RolePageObject, query_db: Session = Depends(get_db)): +@roleController.post("/role/get", response_model=RolePageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:role:list'))]) +async def get_system_role_list(request: Request, role_page_query: RolePageObject, query_db: Session = Depends(get_db)): try: - role_query_result = get_role_list_services(query_db, role_query) + role_query = RoleQueryModel(**role_page_query.dict()) + role_query_result = RoleService.get_role_list_services(query_db, role_query) + # 分页操作 + role_page_query_result = get_page_obj(role_query_result, role_page_query.page_num, role_page_query.page_size) logger.info('获取成功') - return response_200(data=role_query_result, message="获取成功") + return response_200(data=role_page_query_result, message="获取成功") except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@roleController.post("/role/add", response_model=CrudRoleResponse) -async def add_system_role(request: Request, add_role: AddRoleModel, token: Optional[str] = Header(...), query_db: Session = Depends(get_db)): +@roleController.post("/role/add", response_model=CrudRoleResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:role:add'))]) +@log_decorator(title='角色管理', business_type=1) +async def add_system_role(request: Request, add_role: AddRoleModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): try: - current_user = await get_current_user(request, token, query_db) add_role.create_by = current_user.user.user_name add_role.update_by = current_user.user.user_name - add_role_result = add_role_services(query_db, add_role) - logger.info(add_role_result.message) + add_role_result = RoleService.add_role_services(query_db, add_role) if add_role_result.is_success: + logger.info(add_role_result.message) return response_200(data=add_role_result, message=add_role_result.message) else: + logger.warning(add_role_result.message) return response_400(data="", message=add_role_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@roleController.patch("/role/edit", response_model=CrudRoleResponse) -async def edit_system_role(request: Request, edit_role: AddRoleModel, token: Optional[str] = Header(...), query_db: Session = Depends(get_db)): +@roleController.patch("/role/edit", response_model=CrudRoleResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:role:edit'))]) +@log_decorator(title='角色管理', business_type=2) +async def edit_system_role(request: Request, edit_role: AddRoleModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): try: - current_user = await get_current_user(request, token, query_db) edit_role.update_by = current_user.user.user_name edit_role.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - edit_role_result = edit_role_services(query_db, edit_role) + edit_role_result = RoleService.edit_role_services(query_db, edit_role) if edit_role_result.is_success: logger.info(edit_role_result.message) return response_200(data=edit_role_result, message=edit_role_result.message) @@ -65,16 +73,16 @@ async def edit_system_role(request: Request, edit_role: AddRoleModel, token: Opt return response_400(data="", message=edit_role_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@roleController.post("/role/delete", response_model=CrudRoleResponse) -async def delete_system_role(request: Request, delete_role: DeleteRoleModel, token: Optional[str] = Header(...), query_db: Session = Depends(get_db)): +@roleController.post("/role/delete", response_model=CrudRoleResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:role:remove'))]) +@log_decorator(title='角色管理', business_type=3) +async def delete_system_role(request: Request, delete_role: DeleteRoleModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): try: - current_user = await get_current_user(request, token, query_db) delete_role.update_by = current_user.user.user_name delete_role.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - delete_role_result = delete_role_services(query_db, delete_role) + delete_role_result = RoleService.delete_role_services(query_db, delete_role) if delete_role_result.is_success: logger.info(delete_role_result.message) return response_200(data=delete_role_result, message=delete_role_result.message) @@ -83,15 +91,29 @@ async def delete_system_role(request: Request, delete_role: DeleteRoleModel, tok return response_400(data="", message=delete_role_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@roleController.get("/role/{role_id}", response_model=RoleDetailModel) -async def query_detail_system_role(role_id: int, query_db: Session = Depends(get_db)): +@roleController.get("/role/{role_id}", response_model=RoleDetailModel, dependencies=[Depends(CheckUserInterfaceAuth('system:role:query'))]) +async def query_detail_system_role(request: Request, role_id: int, query_db: Session = Depends(get_db)): try: - delete_role_result = detail_role_services(query_db, role_id) + delete_role_result = RoleService.detail_role_services(query_db, role_id) logger.info(f'获取role_id为{role_id}的信息成功') return response_200(data=delete_role_result, message='获取成功') except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) + + +@roleController.post("/role/export", dependencies=[Depends(CheckUserInterfaceAuth('system:role:export'))]) +@log_decorator(title='角色管理', business_type=5) +async def export_system_role_list(request: Request, role_query: RoleQueryModel, query_db: Session = Depends(get_db)): + try: + # 获取全量数据 + role_query_result = RoleService.get_role_list_services(query_db, role_query) + role_export_result = RoleService.export_role_list_services(role_query_result) + logger.info('导出成功') + return streaming_response_200(data=bytes2file_response(role_export_result)) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) diff --git a/dash-fastapi-backend/module_admin/controller/server_controller.py b/dash-fastapi-backend/module_admin/controller/server_controller.py new file mode 100644 index 0000000000000000000000000000000000000000..0119f9fb44e00fed9248b5303e1bbba2fc255810 --- /dev/null +++ b/dash-fastapi-backend/module_admin/controller/server_controller.py @@ -0,0 +1,22 @@ +from fastapi import APIRouter, Request +from fastapi import Depends +from module_admin.service.login_service import get_current_user +from module_admin.service.server_service import * +from utils.response_util import * +from utils.log_util import * +from module_admin.aspect.interface_auth import CheckUserInterfaceAuth + + +serverController = APIRouter(prefix='/server', dependencies=[Depends(get_current_user)]) + + +@serverController.post("/statisticalInfo", response_model=ServerMonitorModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:server:list'))]) +async def get_monitor_server_info(request: Request): + try: + # 获取全量数据 + server_info_query_result = ServerService.get_server_monitor_info() + logger.info('获取成功') + return response_200(data=server_info_query_result, message="获取成功") + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) diff --git a/dash-fastapi-backend/module_admin/controller/user_controller.py b/dash-fastapi-backend/module_admin/controller/user_controller.py index dbaf2545293b55cb220e51ae1e3889a442121be5..65e251c42ccdaf79a8bfdf0a0ffdcece4d193d64 100644 --- a/dash-fastapi-backend/module_admin/controller/user_controller.py +++ b/dash-fastapi-backend/module_admin/controller/user_controller.py @@ -1,53 +1,64 @@ from fastapi import APIRouter, Request -from fastapi import Depends, Header +from fastapi import Depends +import base64 from config.get_db import get_db -from module_admin.service.login_service import get_current_user, get_password_hash +from config.env import CachePathConfig +from module_admin.service.login_service import get_current_user from module_admin.service.user_service import * -from module_admin.entity.vo.user_schema import * -from module_admin.mapper.user_crud import * -from module_admin.utils.response_tool import * -from module_admin.utils.log_tool import * +from module_admin.entity.vo.user_vo import * +from module_admin.dao.user_dao import * +from utils.page_util import get_page_obj +from utils.response_util import * +from utils.log_util import * +from utils.common_util import bytes2file_response +from module_admin.aspect.interface_auth import CheckUserInterfaceAuth +from module_admin.annotation.log_annotation import log_decorator userController = APIRouter(dependencies=[Depends(get_current_user)]) -@userController.post("/user/get", response_model=UserPageObjectResponse) -async def get_system_user_list(user_query: UserPageObject, query_db: Session = Depends(get_db)): +@userController.post("/user/get", response_model=UserPageObjectResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:user:list'))]) +async def get_system_user_list(request: Request, user_page_query: UserPageObject, query_db: Session = Depends(get_db)): try: - user_query_result = get_user_list_services(query_db, user_query) + user_query = UserQueryModel(**user_page_query.dict()) + # 获取全量数据 + user_query_result = UserService.get_user_list_services(query_db, user_query) + # 分页操作 + user_page_query_result = get_page_obj(user_query_result, user_page_query.page_num, user_page_query.page_size) logger.info('获取成功') - return response_200(data=user_query_result, message="获取成功") + return response_200(data=user_page_query_result, message="获取成功") except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@userController.post("/user/add", response_model=CrudUserResponse) -async def add_system_user(request: Request, add_user: AddUserModel, token: Optional[str] = Header(...), query_db: Session = Depends(get_db)): +@userController.post("/user/add", response_model=CrudUserResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:user:add'))]) +@log_decorator(title='用户管理', business_type=1) +async def add_system_user(request: Request, add_user: AddUserModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): try: - current_user = await get_current_user(request, token, query_db) - add_user.password = get_password_hash(add_user.password) + add_user.password = PwdUtil.get_password_hash(add_user.password) add_user.create_by = current_user.user.user_name add_user.update_by = current_user.user.user_name - add_user_result = add_user_services(query_db, add_user) - logger.info(add_user_result.message) + add_user_result = UserService.add_user_services(query_db, add_user) if add_user_result.is_success: + logger.info(add_user_result.message) return response_200(data=add_user_result, message=add_user_result.message) else: + logger.warning(add_user_result.message) return response_400(data="", message=add_user_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@userController.patch("/user/edit", response_model=CrudUserResponse) -async def edit_system_user(request: Request, edit_user: AddUserModel, token: Optional[str] = Header(...), query_db: Session = Depends(get_db)): +@userController.patch("/user/edit", response_model=CrudUserResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:user:edit'))]) +@log_decorator(title='用户管理', business_type=2) +async def edit_system_user(request: Request, edit_user: AddUserModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): try: - current_user = await get_current_user(request, token, query_db) edit_user.update_by = current_user.user.user_name edit_user.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - edit_user_result = edit_user_services(query_db, edit_user) + edit_user_result = UserService.edit_user_services(query_db, edit_user) if edit_user_result.is_success: logger.info(edit_user_result.message) return response_200(data=edit_user_result, message=edit_user_result.message) @@ -56,16 +67,16 @@ async def edit_system_user(request: Request, edit_user: AddUserModel, token: Opt return response_400(data="", message=edit_user_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@userController.post("/user/delete", response_model=CrudUserResponse) -async def delete_system_user(request: Request, delete_user: DeleteUserModel, token: Optional[str] = Header(...), query_db: Session = Depends(get_db)): +@userController.post("/user/delete", response_model=CrudUserResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:user:remove'))]) +@log_decorator(title='用户管理', business_type=3) +async def delete_system_user(request: Request, delete_user: DeleteUserModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): try: - current_user = await get_current_user(request, token, query_db) delete_user.update_by = current_user.user.user_name delete_user.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - delete_user_result = delete_user_services(query_db, delete_user) + delete_user_result = UserService.delete_user_services(query_db, delete_user) if delete_user_result.is_success: logger.info(delete_user_result.message) return response_200(data=delete_user_result, message=delete_user_result.message) @@ -74,15 +85,102 @@ async def delete_system_user(request: Request, delete_user: DeleteUserModel, tok return response_400(data="", message=delete_user_result.message) except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) -@userController.get("/user/{user_id}", response_model=UserDetailModel) -async def query_detail_system_user(user_id: int, query_db: Session = Depends(get_db)): +@userController.get("/user/{user_id}", response_model=UserDetailModel, dependencies=[Depends(CheckUserInterfaceAuth('system:user:query'))]) +async def query_detail_system_user(request: Request, user_id: int, query_db: Session = Depends(get_db)): try: - delete_user_result = detail_user_services(query_db, user_id) + delete_user_result = UserService.detail_user_services(query_db, user_id) logger.info(f'获取user_id为{user_id}的信息成功') return response_200(data=delete_user_result, message='获取成功') except Exception as e: logger.exception(e) - return response_500(data="", message="接口异常") + return response_500(data="", message=str(e)) + + +@userController.patch("/user/profile/changeAvatar", response_model=CrudUserResponse, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) +@log_decorator(title='个人信息', business_type=2) +async def change_system_user_profile_avatar(request: Request, edit_user: AddUserModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): + try: + avatar = edit_user.avatar + # 去除 base64 字符串中的头部信息(data:image/jpeg;base64, 等等) + base64_string = avatar.split(',', 1)[1] + # 解码 base64 字符串 + file_data = base64.b64decode(base64_string) + dir_path = os.path.join(CachePathConfig.PATH, 'avatar') + try: + os.makedirs(dir_path) + except FileExistsError: + pass + filepath = os.path.join(dir_path, f'{current_user.user.user_name}_avatar.jpeg') + with open(filepath, 'wb') as f: + f.write(file_data) + edit_user.user_id = current_user.user.user_id + edit_user.avatar = f'{request.base_url}common/{CachePathConfig.PATHSTR}?taskId=avatar&filename={current_user.user.user_name}_avatar.jpeg' + edit_user.update_by = current_user.user.user_name + edit_user.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + edit_user_result = UserService.edit_user_services(query_db, edit_user) + if edit_user_result.is_success: + logger.info(edit_user_result.message) + return response_200(data=edit_user_result, message=edit_user_result.message) + else: + logger.warning(edit_user_result.message) + return response_400(data="", message=edit_user_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@userController.patch("/user/profile/changeInfo", response_model=CrudUserResponse, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) +@log_decorator(title='个人信息', business_type=2) +async def change_system_user_profile_info(request: Request, edit_user: AddUserModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): + try: + edit_user.user_id = current_user.user.user_id + edit_user.update_by = current_user.user.user_name + edit_user.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + edit_user_result = UserService.edit_user_services(query_db, edit_user) + if edit_user_result.is_success: + logger.info(edit_user_result.message) + return response_200(data=edit_user_result, message=edit_user_result.message) + else: + logger.warning(edit_user_result.message) + return response_400(data="", message=edit_user_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@userController.patch("/user/profile/resetPwd", response_model=CrudUserResponse, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) +@log_decorator(title='个人信息', business_type=2) +async def reset_system_user_password(request: Request, reset_user: ResetUserModel, query_db: Session = Depends(get_db), current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): + try: + if not reset_user.user_id and reset_user.old_password: + reset_user.user_id = current_user.user.user_id + reset_user.password = PwdUtil.get_password_hash(reset_user.password) + reset_user.update_by = current_user.user.user_name + reset_user.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + reset_user_result = UserService.reset_user_services(query_db, reset_user) + if reset_user_result.is_success: + logger.info(reset_user_result.message) + return response_200(data=reset_user_result, message=reset_user_result.message) + else: + logger.warning(reset_user_result.message) + return response_400(data="", message=reset_user_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@userController.post("/user/export", dependencies=[Depends(CheckUserInterfaceAuth('system:user:export'))]) +@log_decorator(title='用户管理', business_type=5) +async def export_system_user_list(request: Request, user_query: UserQueryModel, query_db: Session = Depends(get_db)): + try: + # 获取全量数据 + user_query_result = UserService.get_user_list_services(query_db, user_query) + user_export_result = UserService.export_user_list_services(user_query_result) + logger.info('导出成功') + return streaming_response_200(data=bytes2file_response(user_export_result)) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) diff --git a/dash-fastapi-backend/module_admin/dao/config_dao.py b/dash-fastapi-backend/module_admin/dao/config_dao.py new file mode 100644 index 0000000000000000000000000000000000000000..a7fb473c973a48c23950f69279020b62f5f5b19c --- /dev/null +++ b/dash-fastapi-backend/module_admin/dao/config_dao.py @@ -0,0 +1,110 @@ +from sqlalchemy.orm import Session +from module_admin.entity.do.config_do import SysConfig +from module_admin.entity.vo.config_vo import ConfigModel, ConfigQueryModel +from utils.time_format_util import list_format_datetime +from datetime import datetime, time + + +class ConfigDao: + """ + 参数配置管理模块数据库操作层 + """ + + @classmethod + def get_config_detail_by_id(cls, db: Session, config_id: int): + """ + 根据参数配置id获取参数配置详细信息 + :param db: orm对象 + :param config_id: 参数配置id + :return: 参数配置信息对象 + """ + config_info = db.query(SysConfig) \ + .filter(SysConfig.config_id == config_id) \ + .first() + + return config_info + + @classmethod + def get_config_detail_by_info(cls, db: Session, config: ConfigModel): + """ + 根据参数配置参数获取参数配置信息 + :param db: orm对象 + :param config: 参数配置参数对象 + :return: 参数配置信息对象 + """ + config_info = db.query(SysConfig) \ + .filter(SysConfig.config_key == config.config_key if config.config_key else True, + SysConfig.config_value == config.config_value if config.config_value else True) \ + .first() + + return config_info + + @classmethod + def get_all_config(cls, db: Session): + """ + 获取所有的参数配置信息 + :param db: orm对象 + :return: 参数配置信息列表对象 + """ + config_info = db.query(SysConfig).all() + + return list_format_datetime(config_info) + + @classmethod + def get_config_list(cls, db: Session, query_object: ConfigQueryModel): + """ + 根据查询参数获取参数配置列表信息 + :param db: orm对象 + :param query_object: 查询参数对象 + :return: 参数配置列表信息对象 + """ + config_list = db.query(SysConfig) \ + .filter(SysConfig.config_name.like(f'%{query_object.config_name}%') if query_object.config_name else True, + SysConfig.config_key.like(f'%{query_object.config_key}%') if query_object.config_key else True, + SysConfig.config_type == query_object.config_type if query_object.config_type else True, + SysConfig.create_time.between( + datetime.combine(datetime.strptime(query_object.create_time_start, '%Y-%m-%d'), time(00, 00, 00)), + datetime.combine(datetime.strptime(query_object.create_time_end, '%Y-%m-%d'), time(23, 59, 59))) + if query_object.create_time_start and query_object.create_time_end else True + ) \ + .distinct().all() + + return list_format_datetime(config_list) + + @classmethod + def add_config_dao(cls, db: Session, config: ConfigModel): + """ + 新增参数配置数据库操作 + :param db: orm对象 + :param config: 参数配置对象 + :return: + """ + db_config = SysConfig(**config.dict()) + db.add(db_config) + db.flush() + + return db_config + + @classmethod + def edit_config_dao(cls, db: Session, config: dict): + """ + 编辑参数配置数据库操作 + :param db: orm对象 + :param config: 需要更新的参数配置字典 + :return: + """ + db.query(SysConfig) \ + .filter(SysConfig.config_id == config.get('config_id')) \ + .update(config) + + @classmethod + def delete_config_dao(cls, db: Session, config: ConfigModel): + """ + 删除参数配置数据库操作 + :param db: orm对象 + :param config: 参数配置对象 + :return: + """ + db.query(SysConfig) \ + .filter(SysConfig.config_id == config.config_id) \ + .delete() diff --git a/dash-fastapi-backend/module_admin/dao/dept_dao.py b/dash-fastapi-backend/module_admin/dao/dept_dao.py index e2ce754ceffda28a427e655f010686749aa85e8c..e08f85922ee4185da1a0ddcd16855452c111df34 100644 --- a/dash-fastapi-backend/module_admin/dao/dept_dao.py +++ b/dash-fastapi-backend/module_admin/dao/dept_dao.py @@ -1,175 +1,226 @@ from sqlalchemy.orm import Session -from module_admin.entity.do.dept_entity import SysDept -from module_admin.entity.vo.dept_schema import DeptModel, DeptResponse, CrudDeptResponse -from module_admin.utils.time_format_tool import list_format_datetime +from module_admin.entity.do.dept_do import SysDept +from module_admin.entity.vo.dept_vo import DeptModel, DeptResponse, CrudDeptResponse +from utils.time_format_util import list_format_datetime -def get_dept_by_id(db: Session, dept_id: int): - dept_info = db.query(SysDept) \ - .filter(SysDept.dept_id == dept_id, - SysDept.status == 0, - SysDept.del_flag == 0) \ - .first() - - return dept_info - - -def get_dept_by_id_for_list(db: Session, dept_id: int): - dept_info = db.query(SysDept) \ - .filter(SysDept.dept_id == dept_id, - SysDept.del_flag == 0) \ - .first() - - return dept_info - - -def get_dept_detail_by_id(db: Session, dept_id: int): - dept_info = db.query(SysDept) \ - .filter(SysDept.dept_id == dept_id, - SysDept.del_flag == 0) \ - .first() - - return dept_info - - -def get_dept_info_for_edit_option(db: Session, dept_info: DeptModel): - dept_result = db.query(SysDept) \ - .filter(SysDept.dept_id != dept_info.dept_id, SysDept.parent_id != dept_info.dept_id, - SysDept.del_flag == 0, SysDept.status == 0) \ - .all() - - return list_format_datetime(dept_result) - - -def get_children_dept(db: Session, dept_id: int): - dept_result = db.query(SysDept) \ - .filter(SysDept.parent_id == dept_id, - SysDept.del_flag == 0) \ - .all() - - return list_format_datetime(dept_result) - - -def get_dept_all_ancestors(db: Session): - ancestors = db.query(SysDept.ancestors)\ - .filter(SysDept.del_flag == 0)\ - .all() - - return ancestors - - -def get_dept_list_for_tree(db: Session, dept_info: DeptModel): - if dept_info.dept_name: - dept_query_all = db.query(SysDept) \ - .filter(SysDept.status == 0, - SysDept.del_flag == 0, - SysDept.dept_name.like(f'%{dept_info.dept_name}%') if dept_info.dept_name else True) \ - .order_by(SysDept.order_num) \ - .distinct().all() - - dept = [] - if dept_query_all: - for dept_query in dept_query_all: - ancestor_info = dept_query.ancestors.split(',') - ancestor_info.append(dept_query.dept_id) - for ancestor in ancestor_info: - dept_item = get_dept_by_id(db, int(ancestor)) - if dept_item: - dept.append(dept_item) - # 去重 - dept_result = list(set(dept)) - else: - dept_result = db.query(SysDept) \ - .filter(SysDept.status == 0, SysDept.del_flag == 0) \ - .order_by(SysDept.order_num) \ - .distinct().all() - - return list_format_datetime(dept_result) - - -def get_dept_list(db: Session, page_object: DeptModel): - """ - 根据查询参数获取部门列表信息 - :param db: orm对象 - :param page_object: 不分页查询参数对象 - :return: 部门列表信息对象 - """ - if page_object.dept_name or page_object.status: - dept_query_all = db.query(SysDept) \ - .filter(SysDept.del_flag == 0, - SysDept.status == page_object.status if page_object.status else True, - SysDept.dept_name.like(f'%{page_object.dept_name}%') if page_object.dept_name else True) \ - .order_by(SysDept.order_num)\ - .distinct().all() - - dept = [] - if dept_query_all: - for dept_query in dept_query_all: - ancestor_info = dept_query.ancestors.split(',') - ancestor_info.append(dept_query.dept_id) - for ancestor in ancestor_info: - dept_item = get_dept_by_id_for_list(db, int(ancestor)) - if dept_item: - dept.append(dept_item) - # 去重 - dept_result = list(set(dept)) - else: - dept_result = db.query(SysDept) \ - .filter(SysDept.del_flag == 0) \ - .order_by(SysDept.order_num) \ - .distinct().all() - - result = dict( - rows=list_format_datetime(dept_result), - ) - - return DeptResponse(**result) - - -def add_dept_crud(db: Session, dept: DeptModel): +class DeptDao: """ - 新增部门数据库操作 - :param db: orm对象 - :param dept: 部门对象 - :return: 新增校验结果 + 部门管理模块数据库操作层 """ - db_dept = SysDept(**dept.dict()) - db.add(db_dept) - db.commit() # 提交保存到数据库中 - db.refresh(db_dept) # 刷新 - result = dict(is_success=True, message='新增成功') - - return CrudDeptResponse(**result) - -def edit_dept_crud(db: Session, dept: dict): - """ - 编辑部门数据库操作 - :param db: orm对象 - :param dept: 需要更新的部门字典 - :return: 编辑校验结果 - """ - is_dept_id = db.query(SysDept).filter(SysDept.dept_id == dept.get('dept_id')).all() - if not is_dept_id: - result = dict(is_success=False, message='部门不存在') - else: + @classmethod + def get_dept_by_id(cls, db: Session, dept_id: int): + """ + 根据部门id获取在用部门信息 + :param db: orm对象 + :param dept_id: 部门id + :return: 在用部门信息对象 + """ + dept_info = db.query(SysDept) \ + .filter(SysDept.dept_id == dept_id, + SysDept.status == 0, + SysDept.del_flag == 0) \ + .first() + + return dept_info + + @classmethod + def get_dept_by_id_for_list(cls, db: Session, dept_id: int): + """ + 用于获取部门列表的工具方法 + :param db: orm对象 + :param dept_id: 部门id + :return: 部门id对应的信息对象 + """ + dept_info = db.query(SysDept) \ + .filter(SysDept.dept_id == dept_id, + SysDept.del_flag == 0) \ + .first() + + return dept_info + + @classmethod + def get_dept_detail_by_id(cls, db: Session, dept_id: int): + """ + 根据部门id获取部门详细信息 + :param db: orm对象 + :param dept_id: 部门id + :return: 部门信息对象 + """ + dept_info = db.query(SysDept) \ + .filter(SysDept.dept_id == dept_id, + SysDept.del_flag == 0) \ + .first() + + return dept_info + + @classmethod + def get_dept_detail_by_info(cls, db: Session, dept: DeptModel): + """ + 根据部门参数获取部门信息 + :param db: orm对象 + :param dept: 部门参数对象 + :return: 部门信息对象 + """ + dept_info = db.query(SysDept) \ + .filter(SysDept.parent_id == dept.parent_id if dept.parent_id else True, + SysDept.dept_name == dept.dept_name if dept.dept_name else True) \ + .first() + + return dept_info + + @classmethod + def get_dept_info_for_edit_option(cls, db: Session, dept_info: DeptModel): + """ + 获取部门编辑对应的在用部门列表信息 + :param db: orm对象 + :param dept_info: 部门对象 + :return: 部门列表信息 + """ + dept_result = db.query(SysDept) \ + .filter(SysDept.dept_id != dept_info.dept_id, SysDept.parent_id != dept_info.dept_id, + SysDept.del_flag == 0, SysDept.status == 0) \ + .all() + + return list_format_datetime(dept_result) + + @classmethod + def get_children_dept(cls, db: Session, dept_id: int): + """ + 根据部门id查询当前部门的子部门列表信息 + :param db: orm对象 + :param dept_id: 部门id + :return: 子部门信息列表 + """ + dept_result = db.query(SysDept) \ + .filter(SysDept.parent_id == dept_id, + SysDept.del_flag == 0) \ + .all() + + return list_format_datetime(dept_result) + + @classmethod + def get_dept_all_ancestors(cls, db: Session): + """ + 获取所有部门的ancestors信息 + :param db: orm对象 + :return: ancestors信息列表 + """ + ancestors = db.query(SysDept.ancestors)\ + .filter(SysDept.del_flag == 0)\ + .all() + + return ancestors + + @classmethod + def get_dept_list_for_tree(cls, db: Session, dept_info: DeptModel): + """ + 获取所有在用部门列表信息 + :param db: orm对象 + :param dept_info: 部门对象 + :return: 在用部门列表信息 + """ + if dept_info.dept_name: + dept_query_all = db.query(SysDept) \ + .filter(SysDept.status == 0, + SysDept.del_flag == 0, + SysDept.dept_name.like(f'%{dept_info.dept_name}%') if dept_info.dept_name else True) \ + .order_by(SysDept.order_num) \ + .distinct().all() + + dept = [] + if dept_query_all: + for dept_query in dept_query_all: + ancestor_info = dept_query.ancestors.split(',') + ancestor_info.append(dept_query.dept_id) + for ancestor in ancestor_info: + dept_item = cls.get_dept_by_id(db, int(ancestor)) + if dept_item: + dept.append(dept_item) + # 去重 + dept_result = list(set(dept)) + else: + dept_result = db.query(SysDept) \ + .filter(SysDept.status == 0, SysDept.del_flag == 0) \ + .order_by(SysDept.order_num) \ + .distinct().all() + + return list_format_datetime(dept_result) + + @classmethod + def get_dept_list(cls, db: Session, page_object: DeptModel): + """ + 根据查询参数获取部门列表信息 + :param db: orm对象 + :param page_object: 不分页查询参数对象 + :return: 部门列表信息对象 + """ + if page_object.dept_name or page_object.status: + dept_query_all = db.query(SysDept) \ + .filter(SysDept.del_flag == 0, + SysDept.status == page_object.status if page_object.status else True, + SysDept.dept_name.like(f'%{page_object.dept_name}%') if page_object.dept_name else True) \ + .order_by(SysDept.order_num)\ + .distinct().all() + + dept = [] + if dept_query_all: + for dept_query in dept_query_all: + ancestor_info = dept_query.ancestors.split(',') + ancestor_info.append(dept_query.dept_id) + for ancestor in ancestor_info: + dept_item = cls.get_dept_by_id_for_list(db, int(ancestor)) + if dept_item: + dept.append(dept_item) + # 去重 + dept_result = list(set(dept)) + else: + dept_result = db.query(SysDept) \ + .filter(SysDept.del_flag == 0) \ + .order_by(SysDept.order_num) \ + .distinct().all() + + result = dict( + rows=list_format_datetime(dept_result), + ) + + return DeptResponse(**result) + + @classmethod + def add_dept_dao(cls, db: Session, dept: DeptModel): + """ + 新增部门数据库操作 + :param db: orm对象 + :param dept: 部门对象 + :return: 新增校验结果 + """ + db_dept = SysDept(**dept.dict()) + db.add(db_dept) + db.refresh(db_dept) # 刷新 + + return db_dept + + @classmethod + def edit_dept_dao(cls, db: Session, dept: dict): + """ + 编辑部门数据库操作 + :param db: orm对象 + :param dept: 需要更新的部门字典 + :return: 编辑校验结果 + """ db.query(SysDept) \ .filter(SysDept.dept_id == dept.get('dept_id')) \ .update(dept) - db.commit() # 提交保存到数据库中 - result = dict(is_success=True, message='更新成功') - return CrudDeptResponse(**result) - - -def delete_dept_crud(db: Session, dept: DeptModel): - """ - 删除部门数据库操作 - :param db: orm对象 - :param dept: 部门对象 - :return: - """ - db.query(SysDept) \ - .filter(SysDept.dept_id == dept.dept_id) \ - .update({SysDept.del_flag: '2', SysDept.update_by: dept.update_by, SysDept.update_time: dept.update_time}) - db.commit() # 提交保存到数据库中 + @classmethod + def delete_dept_dao(cls, db: Session, dept: DeptModel): + """ + 删除部门数据库操作 + :param db: orm对象 + :param dept: 部门对象 + :return: + """ + db.query(SysDept) \ + .filter(SysDept.dept_id == dept.dept_id) \ + .update({SysDept.del_flag: '2', SysDept.update_by: dept.update_by, SysDept.update_time: dept.update_time}) diff --git a/dash-fastapi-backend/module_admin/dao/dict_dao.py b/dash-fastapi-backend/module_admin/dao/dict_dao.py new file mode 100644 index 0000000000000000000000000000000000000000..30312fd9dad7fa09ef858a208500d09f0472ccd8 --- /dev/null +++ b/dash-fastapi-backend/module_admin/dao/dict_dao.py @@ -0,0 +1,219 @@ +from sqlalchemy import and_ +from sqlalchemy.orm import Session +from module_admin.entity.do.dict_do import SysDictType, SysDictData +from module_admin.entity.vo.dict_vo import DictTypeModel, DictTypeQueryModel, DictDataModel +from utils.time_format_util import list_format_datetime +from datetime import datetime, time + + +class DictTypeDao: + """ + 字典类型管理模块数据库操作层 + """ + + @classmethod + def get_dict_type_detail_by_id(cls, db: Session, dict_id: int): + """ + 根据字典类型id获取字典类型详细信息 + :param db: orm对象 + :param dict_id: 字典类型id + :return: 字典类型信息对象 + """ + dict_type_info = db.query(SysDictType) \ + .filter(SysDictType.dict_id == dict_id) \ + .first() + + return dict_type_info + + @classmethod + def get_dict_type_detail_by_info(cls, db: Session, dict_type: DictTypeModel): + """ + 根据字典类型参数获取字典类型信息 + :param db: orm对象 + :param dict_type: 字典类型参数对象 + :return: 字典类型信息对象 + """ + dict_type_info = db.query(SysDictType) \ + .filter(SysDictType.dict_type == dict_type.dict_type if dict_type.dict_type else True, + SysDictType.dict_name == dict_type.dict_name if dict_type.dict_name else True) \ + .first() + + return dict_type_info + + @classmethod + def get_all_dict_type(cls, db: Session): + """ + 获取所有的字典类型信息 + :param db: orm对象 + :return: 字典类型信息列表对象 + """ + dict_type_info = db.query(SysDictType).all() + + return list_format_datetime(dict_type_info) + + @classmethod + def get_dict_type_list(cls, db: Session, query_object: DictTypeQueryModel): + """ + 根据查询参数获取字典类型列表信息 + :param db: orm对象 + :param query_object: 查询参数对象 + :return: 字典类型列表信息对象 + """ + dict_type_list = db.query(SysDictType) \ + .filter(SysDictType.dict_name.like(f'%{query_object.dict_name}%') if query_object.dict_name else True, + SysDictType.dict_type.like(f'%{query_object.dict_type}%') if query_object.dict_type else True, + SysDictType.status == query_object.status if query_object.status else True, + SysDictType.create_time.between( + datetime.combine(datetime.strptime(query_object.create_time_start, '%Y-%m-%d'), time(00, 00, 00)), + datetime.combine(datetime.strptime(query_object.create_time_end, '%Y-%m-%d'), time(23, 59, 59))) + if query_object.create_time_start and query_object.create_time_end else True + ) \ + .distinct().all() + + return list_format_datetime(dict_type_list) + + @classmethod + def add_dict_type_dao(cls, db: Session, dict_type: DictTypeModel): + """ + 新增字典类型数据库操作 + :param db: orm对象 + :param dict_type: 字典类型对象 + :return: + """ + db_dict_type = SysDictType(**dict_type.dict()) + db.add(db_dict_type) + db.flush() + + return db_dict_type + + @classmethod + def edit_dict_type_dao(cls, db: Session, dict_type: dict): + """ + 编辑字典类型数据库操作 + :param db: orm对象 + :param dict_type: 需要更新的字典类型字典 + :return: + """ + db.query(SysDictType) \ + .filter(SysDictType.dict_id == dict_type.get('dict_id')) \ + .update(dict_type) + + @classmethod + def delete_dict_type_dao(cls, db: Session, dict_type: DictTypeModel): + """ + 删除字典类型数据库操作 + :param db: orm对象 + :param dict_type: 字典类型对象 + :return: + """ + db.query(SysDictType) \ + .filter(SysDictType.dict_id == dict_type.dict_id) \ + .delete() + + +class DictDataDao: + """ + 字典数据管理模块数据库操作层 + """ + + @classmethod + def get_dict_data_detail_by_id(cls, db: Session, dict_code: int): + """ + 根据字典数据id获取字典数据详细信息 + :param db: orm对象 + :param dict_code: 字典数据id + :return: 字典数据信息对象 + """ + dict_data_info = db.query(SysDictData) \ + .filter(SysDictData.dict_code == dict_code) \ + .first() + + return dict_data_info + + @classmethod + def get_dict_data_detail_by_info(cls, db: Session, dict_data: DictDataModel): + """ + 根据字典数据参数获取字典数据信息 + :param db: orm对象 + :param dict_data: 字典数据参数对象 + :return: 字典数据信息对象 + """ + dict_data_info = db.query(SysDictData) \ + .filter(SysDictData.dict_type == dict_data.dict_type if dict_data.dict_type else True, + SysDictData.dict_label == dict_data.dict_label if dict_data.dict_label else True, + SysDictData.dict_value == dict_data.dict_value if dict_data.dict_value else True) \ + .first() + + return dict_data_info + + @classmethod + def get_dict_data_list(cls, db: Session, query_object: DictDataModel): + """ + 根据查询参数获取字典数据列表信息 + :param db: orm对象 + :param query_object: 查询参数对象 + :return: 字典数据列表信息对象 + """ + dict_data_list = db.query(SysDictData) \ + .filter(SysDictData.dict_type == query_object.dict_type if query_object.dict_type else True, + SysDictData.dict_label.like(f'%{query_object.dict_label}%') if query_object.dict_label else True, + SysDictData.status == query_object.status if query_object.status else True + ) \ + .order_by(SysDictData.dict_sort) \ + .distinct().all() + + return list_format_datetime(dict_data_list) + + @classmethod + def query_dict_data_list(cls, db: Session, dict_type: str): + """ + 根据查询参数获取字典数据列表信息 + :param db: orm对象 + :param dict_type: 字典类型 + :return: 字典数据列表信息对象 + """ + dict_data_list = db.query(SysDictData).select_from(SysDictType) \ + .filter(SysDictType.dict_type == dict_type if dict_type else True, SysDictType.status == 0) \ + .outerjoin(SysDictData, and_(SysDictType.dict_type == SysDictData.dict_type, SysDictData.status == 0)) \ + .order_by(SysDictData.dict_sort) \ + .distinct().all() + + return list_format_datetime(dict_data_list) + + @classmethod + def add_dict_data_dao(cls, db: Session, dict_data: DictDataModel): + """ + 新增字典数据数据库操作 + :param db: orm对象 + :param dict_data: 字典数据对象 + :return: + """ + db_data_type = SysDictData(**dict_data.dict()) + db.add(db_data_type) + db.flush() + + return db_data_type + + @classmethod + def edit_dict_data_dao(cls, db: Session, dict_data: dict): + """ + 编辑字典数据数据库操作 + :param db: orm对象 + :param dict_data: 需要更新的字典数据字典 + :return: + """ + db.query(SysDictData) \ + .filter(SysDictData.dict_code == dict_data.get('dict_code')) \ + .update(dict_data) + + @classmethod + def delete_dict_data_dao(cls, db: Session, dict_data: DictDataModel): + """ + 删除字典数据数据库操作 + :param db: orm对象 + :param dict_data: 字典数据对象 + :return: + """ + db.query(SysDictData) \ + .filter(SysDictData.dict_code == dict_data.dict_code) \ + .delete() diff --git a/dash-fastapi-backend/module_admin/dao/job_dao.py b/dash-fastapi-backend/module_admin/dao/job_dao.py new file mode 100644 index 0000000000000000000000000000000000000000..ca318c8c0eb942f591a14a608ba1cffbc8a62c2f --- /dev/null +++ b/dash-fastapi-backend/module_admin/dao/job_dao.py @@ -0,0 +1,109 @@ +from sqlalchemy.orm import Session +from module_admin.entity.do.job_do import SysJob +from module_admin.entity.vo.job_vo import JobModel +from utils.time_format_util import list_format_datetime, object_format_datetime + + +class JobDao: + """ + 定时任务管理模块数据库操作层 + """ + + @classmethod + def get_job_detail_by_id(cls, db: Session, job_id: int): + """ + 根据定时任务id获取定时任务详细信息 + :param db: orm对象 + :param job_id: 定时任务id + :return: 定时任务信息对象 + """ + job_info = db.query(SysJob) \ + .filter(SysJob.job_id == job_id) \ + .first() + + return object_format_datetime(job_info) + + @classmethod + def get_job_detail_by_info(cls, db: Session, job: JobModel): + """ + 根据定时任务参数获取定时任务信息 + :param db: orm对象 + :param job: 定时任务参数对象 + :return: 定时任务信息对象 + """ + job_info = db.query(SysJob) \ + .filter(SysJob.job_name == job.job_name if job.job_name else True, + SysJob.job_group == job.job_group if job.job_group else True, + SysJob.invoke_target == job.invoke_target if job.invoke_target else True, + SysJob.cron_expression == job.cron_expression if job.cron_expression else True) \ + .first() + + return job_info + + @classmethod + def get_job_list(cls, db: Session, query_object: JobModel): + """ + 根据查询参数获取定时任务列表信息 + :param db: orm对象 + :param query_object: 查询参数对象 + :return: 定时任务列表信息对象 + """ + job_list = db.query(SysJob) \ + .filter(SysJob.job_name.like(f'%{query_object.job_name}%') if query_object.job_name else True, + SysJob.job_group == query_object.job_group if query_object.job_group else True, + SysJob.status == query_object.status if query_object.status else True + ) \ + .distinct().all() + + return list_format_datetime(job_list) + + @classmethod + def get_job_list_for_scheduler(cls, db: Session): + """ + 获取定时任务列表信息 + :param db: orm对象 + :return: 定时任务列表信息对象 + """ + job_list = db.query(SysJob) \ + .filter(SysJob.status == 0) \ + .distinct().all() + + return list_format_datetime(job_list) + + @classmethod + def add_job_dao(cls, db: Session, job: JobModel): + """ + 新增定时任务数据库操作 + :param db: orm对象 + :param job: 定时任务对象 + :return: + """ + db_job = SysJob(**job.dict()) + db.add(db_job) + db.flush() + + return db_job + + @classmethod + def edit_job_dao(cls, db: Session, job: dict): + """ + 编辑定时任务数据库操作 + :param db: orm对象 + :param job: 需要更新的定时任务字典 + :return: + """ + db.query(SysJob) \ + .filter(SysJob.job_id == job.get('job_id')) \ + .update(job) + + @classmethod + def delete_job_dao(cls, db: Session, job: JobModel): + """ + 删除定时任务数据库操作 + :param db: orm对象 + :param job: 定时任务对象 + :return: + """ + db.query(SysJob) \ + .filter(SysJob.job_id == job.job_id) \ + .delete() diff --git a/dash-fastapi-backend/module_admin/dao/job_log_dao.py b/dash-fastapi-backend/module_admin/dao/job_log_dao.py new file mode 100644 index 0000000000000000000000000000000000000000..b3cd75c830f72448039639f1e240c9e060c27ef1 --- /dev/null +++ b/dash-fastapi-backend/module_admin/dao/job_log_dao.py @@ -0,0 +1,82 @@ +from sqlalchemy.orm import Session +from module_admin.entity.do.job_do import SysJobLog +from module_admin.entity.vo.job_vo import JobLogModel, JobLogQueryModel +from utils.time_format_util import list_format_datetime, object_format_datetime +from datetime import datetime, time + + +class JobLogDao: + """ + 定时任务日志管理模块数据库操作层 + """ + + @classmethod + def get_job_log_detail_by_id(cls, db: Session, job_log_id: int): + """ + 根据定时任务日志id获取定时任务日志详细信息 + :param db: orm对象 + :param job_log_id: 定时任务日志id + :return: 定时任务日志信息对象 + """ + job_log_info = db.query(SysJobLog) \ + .filter(SysJobLog.job_log_id == job_log_id) \ + .first() + + return object_format_datetime(job_log_info) + + @classmethod + def get_job_log_list(cls, db: Session, query_object: JobLogQueryModel): + """ + 根据查询参数获取定时任务日志列表信息 + :param db: orm对象 + :param query_object: 查询参数对象 + :return: 定时任务日志列表信息对象 + """ + job_log_list = db.query(SysJobLog) \ + .filter(SysJobLog.job_name.like(f'%{query_object.job_name}%') if query_object.job_name else True, + SysJobLog.job_group == query_object.job_group if query_object.job_group else True, + SysJobLog.status == query_object.status if query_object.status else True, + SysJobLog.create_time.between( + datetime.combine(datetime.strptime(query_object.create_time_start, '%Y-%m-%d'), time(00, 00, 00)), + datetime.combine(datetime.strptime(query_object.create_time_end, '%Y-%m-%d'), time(23, 59, 59))) + if query_object.create_time_start and query_object.create_time_end else True + ) \ + .distinct().all() + + return list_format_datetime(job_log_list) + + @classmethod + def add_job_log_dao(cls, db: Session, job_log: JobLogModel): + """ + 新增定时任务日志数据库操作 + :param db: orm对象 + :param job_log: 定时任务日志对象 + :return: + """ + db_job_log = SysJobLog(**job_log.dict()) + db.add(db_job_log) + db.flush() + + return db_job_log + + @classmethod + def delete_job_log_dao(cls, db: Session, job_log: JobLogModel): + """ + 删除定时任务日志数据库操作 + :param db: orm对象 + :param job_log: 定时任务日志对象 + :return: + """ + db.query(SysJobLog) \ + .filter(SysJobLog.job_log_id == job_log.job_log_id) \ + .delete() + + @classmethod + def clear_job_log_dao(cls, db: Session): + """ + 清除定时任务日志数据库操作 + :param db: orm对象 + :return: + """ + db.query(SysJobLog) \ + .delete() diff --git a/dash-fastapi-backend/module_admin/dao/log_dao.py b/dash-fastapi-backend/module_admin/dao/log_dao.py new file mode 100644 index 0000000000000000000000000000000000000000..92d347d7640bd52cceb4a775e07b6c40c1c97463 --- /dev/null +++ b/dash-fastapi-backend/module_admin/dao/log_dao.py @@ -0,0 +1,146 @@ +from sqlalchemy.orm import Session +from module_admin.entity.do.log_do import SysOperLog, SysLogininfor +from module_admin.entity.vo.log_vo import OperLogModel, LogininforModel, OperLogQueryModel, LoginLogQueryModel +from utils.time_format_util import object_format_datetime, list_format_datetime +from datetime import datetime, time + + +class OperationLogDao: + """ + 操作日志管理模块数据库操作层 + """ + + @classmethod + def get_operation_log_detail_by_id(cls, db: Session, oper_id: int): + """ + 根据操作日志id获取操作日志详细信息 + :param db: orm对象 + :param oper_id: 操作日志id + :return: 操作日志信息对象 + """ + operation_log_info = db.query(SysOperLog) \ + .filter(SysOperLog.oper_id == oper_id) \ + .first() + + return object_format_datetime(operation_log_info) + + @classmethod + def get_operation_log_list(cls, db: Session, query_object: OperLogQueryModel): + """ + 根据查询参数获取操作日志列表信息 + :param db: orm对象 + :param query_object: 查询参数对象 + :return: 操作日志列表信息对象 + """ + operation_log_list = db.query(SysOperLog) \ + .filter(SysOperLog.title.like(f'%{query_object.title}%') if query_object.title else True, + SysOperLog.oper_name.like(f'%{query_object.oper_name}%') if query_object.oper_name else True, + SysOperLog.business_type == query_object.business_type if query_object.business_type else True, + SysOperLog.status == query_object.status if query_object.status else True, + SysOperLog.oper_time.between( + datetime.combine(datetime.strptime(query_object.oper_time_start, '%Y-%m-%d'), time(00, 00, 00)), + datetime.combine(datetime.strptime(query_object.oper_time_end, '%Y-%m-%d'), time(23, 59, 59))) + if query_object.oper_time_start and query_object.oper_time_end else True + )\ + .distinct().all() + + return list_format_datetime(operation_log_list) + + @classmethod + def add_operation_log_dao(cls, db: Session, operation_log: OperLogModel): + """ + 新增操作日志数据库操作 + :param db: orm对象 + :param operation_log: 操作日志对象 + :return: 新增校验结果 + """ + db_operation_log = SysOperLog(**operation_log.dict()) + db.add(db_operation_log) + db.flush() + + return db_operation_log + + @classmethod + def delete_operation_log_dao(cls, db: Session, operation_log: OperLogModel): + """ + 删除操作日志数据库操作 + :param db: orm对象 + :param operation_log: 操作日志对象 + :return: + """ + db.query(SysOperLog) \ + .filter(SysOperLog.oper_id == operation_log.oper_id) \ + .delete() + + @classmethod + def clear_operation_log_dao(cls, db: Session): + """ + 清除操作日志数据库操作 + :param db: orm对象 + :return: + """ + db.query(SysOperLog) \ + .delete() + + +class LoginLogDao: + """ + 登录日志管理模块数据库操作层 + """ + + @classmethod + def get_login_log_list(cls, db: Session, query_object: LoginLogQueryModel): + """ + 根据查询参数获取登录日志列表信息 + :param db: orm对象 + :param query_object: 查询参数对象 + :return: 登录日志列表信息对象 + """ + login_log_list = db.query(SysLogininfor) \ + .filter(SysLogininfor.ipaddr.like(f'%{query_object.ipaddr}%') if query_object.ipaddr else True, + SysLogininfor.user_name.like(f'%{query_object.user_name}%') if query_object.user_name else True, + SysLogininfor.status == query_object.status if query_object.status else True, + SysLogininfor.login_time.between( + datetime.combine(datetime.strptime(query_object.login_time_start, '%Y-%m-%d'), time(00, 00, 00)), + datetime.combine(datetime.strptime(query_object.login_time_end, '%Y-%m-%d'), time(23, 59, 59))) + if query_object.login_time_start and query_object.login_time_end else True + )\ + .distinct().all() + + return list_format_datetime(login_log_list) + + @classmethod + def add_login_log_dao(cls, db: Session, login_log: LogininforModel): + """ + 新增登录日志数据库操作 + :param db: orm对象 + :param login_log: 登录日志对象 + :return: 新增校验结果 + """ + db_login_log = SysLogininfor(**login_log.dict()) + db.add(db_login_log) + db.flush() + + return db_login_log + + @classmethod + def delete_login_log_dao(cls, db: Session, login_log: LogininforModel): + """ + 删除登录日志数据库操作 + :param db: orm对象 + :param login_log: 登录日志对象 + :return: + """ + db.query(SysLogininfor) \ + .filter(SysLogininfor.info_id == login_log.info_id) \ + .delete() + + @classmethod + def clear_login_log_dao(cls, db: Session): + """ + 清除登录日志数据库操作 + :param db: orm对象 + :return: + """ + db.query(SysLogininfor) \ + .delete() diff --git a/dash-fastapi-backend/module_admin/dao/login_dao.py b/dash-fastapi-backend/module_admin/dao/login_dao.py index 0e39974e8600a42c84c3c7e024fc75af88f96468..b932bc1793139f0174cd40bf89a29252acf89248 100644 --- a/dash-fastapi-backend/module_admin/dao/login_dao.py +++ b/dash-fastapi-backend/module_admin/dao/login_dao.py @@ -1,6 +1,7 @@ from sqlalchemy.orm import Session -from module_admin.entity.do.user_entity import SysUser -from module_admin.utils.time_format_tool import object_format_datetime +from sqlalchemy import and_ +from module_admin.entity.do.user_do import SysUser +from module_admin.entity.do.dept_do import SysDept def login_by_account(db: Session, user_name: str): @@ -10,9 +11,10 @@ def login_by_account(db: Session, user_name: str): :param user_name: 用户名 :return: 用户对象 """ - user = db.query(SysUser).\ - filter(SysUser.user_name == user_name, SysUser.del_flag == '0').\ - distinct().\ - first() + user = db.query(SysUser, SysDept)\ + .filter(SysUser.user_name == user_name, SysUser.del_flag == '0') \ + .outerjoin(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \ + .distinct() \ + .first() - return object_format_datetime(user) + return user diff --git a/dash-fastapi-backend/module_admin/dao/menu_dao.py b/dash-fastapi-backend/module_admin/dao/menu_dao.py index 50749e837d9d3d4be2cf147ea109f7fb0d5bfb0d..486b9d623e57f1e8e998eb6fa59ae3b716fd3fee 100644 --- a/dash-fastapi-backend/module_admin/dao/menu_dao.py +++ b/dash-fastapi-backend/module_admin/dao/menu_dao.py @@ -1,105 +1,188 @@ +from sqlalchemy import and_ from sqlalchemy.orm import Session -from module_admin.entity.do.menu_entity import SysMenu -from module_admin.entity.vo.menu_schema import MenuModel, MenuResponse, CrudMenuResponse -from module_admin.utils.time_format_tool import list_format_datetime +from module_admin.entity.do.menu_do import SysMenu +from module_admin.entity.do.user_do import SysUser, SysUserRole +from module_admin.entity.do.role_do import SysRole, SysRoleMenu +from module_admin.entity.vo.menu_vo import MenuModel, MenuResponse +from utils.time_format_util import list_format_datetime -def get_menu_detail_by_id(db: Session, menu_id: int): - menu_info = db.query(SysMenu) \ - .filter(SysMenu.menu_id == menu_id) \ - .first() - - return menu_info - - -def get_menu_info_for_edit_option(db: Session, menu_info: MenuModel): - menu_result = db.query(SysMenu) \ - .filter(SysMenu.menu_id != menu_info.menu_id, SysMenu.parent_id != menu_info.menu_id, - SysMenu.status == 0) \ - .all() - - return list_format_datetime(menu_result) - - -def get_menu_list_for_tree(db: Session, menu_info: MenuModel): - menu_query_all = db.query(SysMenu) \ - .filter(SysMenu.status == 0, - SysMenu.menu_name.like(f'%{menu_info.menu_name}%') if menu_info.menu_name else True) \ - .order_by(SysMenu.order_num) \ - .distinct().all() - - return list_format_datetime(menu_query_all) - - -def get_menu_list(db: Session, page_object: MenuModel): - """ - 根据查询参数获取菜单列表信息 - :param db: orm对象 - :param page_object: 不分页查询参数对象 - :return: 菜单列表信息对象 - """ - if page_object.menu_name or page_object.status: - menu_query_all = db.query(SysMenu) \ - .filter(SysMenu.status == page_object.status if page_object.status else True, - SysMenu.menu_name.like(f'%{page_object.menu_name}%') if page_object.menu_name else True) \ - .order_by(SysMenu.order_num)\ - .distinct().all() - else: - menu_query_all = db.query(SysMenu) \ - .order_by(SysMenu.order_num) \ - .distinct().all() - - result = dict( - rows=list_format_datetime(menu_query_all), - ) - - return MenuResponse(**result) - - -def add_menu_crud(db: Session, menu: MenuModel): +class MenuDao: """ - 新增菜单数据库操作 - :param db: orm对象 - :param menu: 菜单对象 - :return: 新增校验结果 + 菜单管理模块数据库操作层 """ - db_menu = SysMenu(**menu.dict()) - db.add(db_menu) - db.commit() # 提交保存到数据库中 - db.refresh(db_menu) # 刷新 - result = dict(is_success=True, message='新增成功') - return CrudMenuResponse(**result) - - -def edit_menu_crud(db: Session, menu: dict): - """ - 编辑菜单数据库操作 - :param db: orm对象 - :param menu: 需要更新的菜单字典 - :return: 编辑校验结果 - """ - is_menu_id = db.query(SysMenu).filter(SysMenu.menu_id == menu.get('menu_id')).all() - if not is_menu_id: - result = dict(is_success=False, message='菜单不存在') - else: + @classmethod + def get_menu_detail_by_id(cls, db: Session, menu_id: int): + """ + 根据菜单id获取菜单详细信息 + :param db: orm对象 + :param menu_id: 菜单id + :return: 菜单信息对象 + """ + menu_info = db.query(SysMenu) \ + .filter(SysMenu.menu_id == menu_id) \ + .first() + + return menu_info + + @classmethod + def get_menu_detail_by_info(cls, db: Session, menu: MenuModel): + """ + 根据菜单参数获取菜单信息 + :param db: orm对象 + :param menu: 菜单参数对象 + :return: 菜单信息对象 + """ + menu_info = db.query(SysMenu) \ + .filter(SysMenu.parent_id == menu.parent_id if menu.parent_id else True, + SysMenu.menu_name == menu.menu_name if menu.menu_name else True, + SysMenu.menu_type == menu.menu_type if menu.menu_type else True) \ + .first() + + return menu_info + + @classmethod + def get_menu_info_for_edit_option(cls, db: Session, menu_info: MenuModel, user_id: int, role: list): + """ + 根据角色信息获取菜单编辑对应的在用菜单列表信息 + :param db: orm对象 + :param menu_info: 菜单对象 + :param user_id: 用户id + :param role: 用户角色列表信息 + :return: 菜单列表信息 + """ + menu_result = [] + for item in role: + if item.role_id == 1: + menu_result = db.query(SysMenu) \ + .filter(SysMenu.menu_id != menu_info.menu_id, SysMenu.parent_id != menu_info.menu_id, + SysMenu.status == 0) \ + .all() + else: + menu_result = db.query(SysMenu).select_from(SysUser) \ + .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ + .outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \ + .outerjoin(SysRole, + and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ + .outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \ + .outerjoin(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, + SysMenu.menu_id != menu_info.menu_id, SysMenu.parent_id != menu_info.menu_id, + SysMenu.status == 0)) \ + .order_by(SysMenu.order_num) \ + .distinct().all() + + return list_format_datetime(menu_result) + + @classmethod + def get_menu_list_for_tree(cls, db: Session, menu_info: MenuModel, user_id: int, role: list): + """ + 根据角色信息获取所有在用菜单列表信息 + :param db: orm对象 + :param menu_info: 菜单对象 + :param user_id: 用户id + :param role: 用户角色列表信息 + :return: 菜单列表信息 + """ + menu_query_all = [] + for item in role: + if item.role_id == 1: + menu_query_all = db.query(SysMenu) \ + .filter(SysMenu.status == 0, + SysMenu.menu_name.like(f'%{menu_info.menu_name}%') if menu_info.menu_name else True) \ + .order_by(SysMenu.order_num) \ + .distinct().all() + break + else: + menu_query_all = db.query(SysMenu).select_from(SysUser) \ + .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ + .outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \ + .outerjoin(SysRole, + and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ + .outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \ + .outerjoin(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, + SysMenu.status == 0, + SysMenu.menu_name.like( + f'%{menu_info.menu_name}%') if menu_info.menu_name else True)) \ + .order_by(SysMenu.order_num) \ + .distinct().all() + + return list_format_datetime(menu_query_all) + + @classmethod + def get_menu_list(cls, db: Session, page_object: MenuModel, user_id: int, role: list): + """ + 根据查询参数获取菜单列表信息 + :param db: orm对象 + :param page_object: 不分页查询参数对象 + :param user_id: 用户id + :param role: 用户角色列表 + :return: 菜单列表信息对象 + """ + menu_query_all = [] + for item in role: + if item.role_id == 1: + menu_query_all = db.query(SysMenu) \ + .filter(SysMenu.status == page_object.status if page_object.status else True, + SysMenu.menu_name.like( + f'%{page_object.menu_name}%') if page_object.menu_name else True) \ + .order_by(SysMenu.order_num) \ + .distinct().all() + break + else: + menu_query_all = db.query(SysMenu).select_from(SysUser) \ + .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ + .outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \ + .outerjoin(SysRole, + and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ + .outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \ + .outerjoin(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, + SysMenu.status == page_object.status if page_object.status else True, + SysMenu.menu_name.like( + f'%{page_object.menu_name}%') if page_object.menu_name else True)) \ + .order_by(SysMenu.order_num) \ + .distinct().all() + + result = dict( + rows=list_format_datetime(menu_query_all), + ) + + return MenuResponse(**result) + + @classmethod + def add_menu_dao(cls, db: Session, menu: MenuModel): + """ + 新增菜单数据库操作 + :param db: orm对象 + :param menu: 菜单对象 + :return: + """ + db_menu = SysMenu(**menu.dict()) + db.add(db_menu) + db.flush() + + return db_menu + + @classmethod + def edit_menu_dao(cls, db: Session, menu: dict): + """ + 编辑菜单数据库操作 + :param db: orm对象 + :param menu: 需要更新的菜单字典 + :return: + """ db.query(SysMenu) \ .filter(SysMenu.menu_id == menu.get('menu_id')) \ .update(menu) - db.commit() # 提交保存到数据库中 - result = dict(is_success=True, message='更新成功') - - return CrudMenuResponse(**result) - -def delete_menu_crud(db: Session, menu: MenuModel): - """ - 删除菜单数据库操作 - :param db: orm对象 - :param menu: 菜单对象 - :return: - """ - db.query(SysMenu) \ - .filter(SysMenu.menu_id == menu.menu_id) \ - .delete() - db.commit() # 提交保存到数据库中 + @classmethod + def delete_menu_dao(cls, db: Session, menu: MenuModel): + """ + 删除菜单数据库操作 + :param db: orm对象 + :param menu: 菜单对象 + :return: + """ + db.query(SysMenu) \ + .filter(SysMenu.menu_id == menu.menu_id) \ + .delete() diff --git a/dash-fastapi-backend/module_admin/dao/notice_dao.py b/dash-fastapi-backend/module_admin/dao/notice_dao.py new file mode 100644 index 0000000000000000000000000000000000000000..b72d59f28e20b1e237a19bc72581c6da20e32621 --- /dev/null +++ b/dash-fastapi-backend/module_admin/dao/notice_dao.py @@ -0,0 +1,100 @@ +from sqlalchemy.orm import Session +from module_admin.entity.do.notice_do import SysNotice +from module_admin.entity.vo.notice_vo import NoticeModel, NoticeQueryModel, CrudNoticeResponse +from utils.time_format_util import list_format_datetime, object_format_datetime +from datetime import datetime, time + + +class NoticeDao: + """ + 通知公告管理模块数据库操作层 + """ + + @classmethod + def get_notice_detail_by_id(cls, db: Session, notice_id: int): + """ + 根据通知公告id获取通知公告详细信息 + :param db: orm对象 + :param notice_id: 通知公告id + :return: 通知公告信息对象 + """ + notice_info = db.query(SysNotice) \ + .filter(SysNotice.notice_id == notice_id) \ + .first() + + return object_format_datetime(notice_info) + + @classmethod + def get_notice_detail_by_info(cls, db: Session, notice: NoticeModel): + """ + 根据通知公告参数获取通知公告信息 + :param db: orm对象 + :param notice: 通知公告参数对象 + :return: 通知公告信息对象 + """ + notice_info = db.query(SysNotice) \ + .filter(SysNotice.notice_title == notice.notice_title if notice.notice_title else True, + SysNotice.notice_type == notice.notice_type if notice.notice_type else True, + SysNotice.notice_content == notice.notice_content if notice.notice_content else True) \ + .first() + + return notice_info + + @classmethod + def get_notice_list(cls, db: Session, query_object: NoticeQueryModel): + """ + 根据查询参数获取通知公告列表信息 + :param db: orm对象 + :param query_object: 查询参数对象 + :return: 通知公告列表信息对象 + """ + notice_list = db.query(SysNotice) \ + .filter(SysNotice.notice_title.like(f'%{query_object.notice_title}%') if query_object.notice_title else True, + SysNotice.update_by.like(f'%{query_object.update_by}%') if query_object.update_by else True, + SysNotice.notice_type == query_object.notice_type if query_object.notice_type else True, + SysNotice.create_time.between( + datetime.combine(datetime.strptime(query_object.create_time_start, '%Y-%m-%d'), time(00, 00, 00)), + datetime.combine(datetime.strptime(query_object.create_time_end, '%Y-%m-%d'), time(23, 59, 59))) + if query_object.create_time_start and query_object.create_time_end else True + ) \ + .distinct().all() + + return list_format_datetime(notice_list) + + @classmethod + def add_notice_dao(cls, db: Session, notice: NoticeModel): + """ + 新增通知公告数据库操作 + :param db: orm对象 + :param notice: 通知公告对象 + :return: + """ + db_notice = SysNotice(**notice.dict()) + db.add(db_notice) + db.flush() + + return db_notice + + @classmethod + def edit_notice_dao(cls, db: Session, notice: dict): + """ + 编辑通知公告数据库操作 + :param db: orm对象 + :param notice: 需要更新的通知公告字典 + :return: + """ + db.query(SysNotice) \ + .filter(SysNotice.notice_id == notice.get('notice_id')) \ + .update(notice) + + @classmethod + def delete_notice_dao(cls, db: Session, notice: NoticeModel): + """ + 删除通知公告数据库操作 + :param db: orm对象 + :param notice: 通知公告对象 + :return: + """ + db.query(SysNotice) \ + .filter(SysNotice.notice_id == notice.notice_id) \ + .delete() diff --git a/dash-fastapi-backend/module_admin/dao/post_dao.py b/dash-fastapi-backend/module_admin/dao/post_dao.py index 8b04c4f2731bcd91e69f2aa7b3eb8547b1400915..11fbdc1592ff5b34a472e23830846df06f3e87d9 100644 --- a/dash-fastapi-backend/module_admin/dao/post_dao.py +++ b/dash-fastapi-backend/module_admin/dao/post_dao.py @@ -1,116 +1,124 @@ from sqlalchemy.orm import Session -from module_admin.entity.do.post_entity import SysPost -from module_admin.entity.vo.post_schema import PostModel, PostPageObject, PostPageObjectResponse, CrudPostResponse -from module_admin.utils.time_format_tool import list_format_datetime -from module_admin.utils.page_tool import get_page_info +from module_admin.entity.do.post_do import SysPost +from module_admin.entity.vo.post_vo import PostModel +from utils.time_format_util import list_format_datetime -def get_post_by_id(db: Session, post_id: int): - post_info = db.query(SysPost) \ - .filter(SysPost.post_id == post_id, - SysPost.status == 0) \ - .first() - - return post_info - - -def get_post_detail_by_id(db: Session, post_id: int): - post_info = db.query(SysPost) \ - .filter(SysPost.post_id == post_id) \ - .first() - - return post_info - - -def get_post_select_option_crud(db: Session): - post_info = db.query(SysPost) \ - .filter(SysPost.status == 0) \ - .all() - - return post_info - - -def get_post_list(db: Session, page_object: PostPageObject): - """ - 根据查询参数获取岗位列表信息 - :param db: orm对象 - :param page_object: 分页查询参数对象 - :return: 岗位列表信息对象 +class PostDao: """ - count = db.query(SysPost) \ - .filter(SysPost.post_code.like(f'%{page_object.post_code}%') if page_object.post_code else True, - SysPost.post_name.like(f'%{page_object.post_name}%') if page_object.post_name else True, - SysPost.status == page_object.status if page_object.status else True - )\ - .order_by(SysPost.post_sort)\ - .distinct().count() - offset_com = (page_object.page_num - 1) * page_object.page_size - page_info = get_page_info(offset_com, page_object.page_num, page_object.page_size, count) - post_list = db.query(SysPost) \ - .filter(SysPost.post_code.like(f'%{page_object.post_code}%') if page_object.post_code else True, - SysPost.post_name.like(f'%{page_object.post_name}%') if page_object.post_name else True, - SysPost.status == page_object.status if page_object.status else True - ) \ - .order_by(SysPost.post_sort) \ - .offset(page_info.offset) \ - .limit(page_object.page_size) \ - .distinct().all() - - result = dict( - rows=list_format_datetime(post_list), - page_num=page_info.page_num, - page_size=page_info.page_size, - total=page_info.total, - has_next=page_info.has_next - ) - - return PostPageObjectResponse(**result) - - -def add_post_crud(db: Session, post: PostModel): + 岗位管理模块数据库操作层 """ - 新增岗位数据库操作 - :param db: orm对象 - :param post: 岗位对象 - :return: 新增校验结果 - """ - db_post = SysPost(**post.dict()) - db.add(db_post) - db.commit() # 提交保存到数据库中 - db.refresh(db_post) # 刷新 - result = dict(is_success=True, message='新增成功') - - return CrudPostResponse(**result) - -def edit_post_crud(db: Session, post: dict): - """ - 编辑岗位数据库操作 - :param db: orm对象 - :param post: 需要更新的岗位字典 - :return: 编辑校验结果 - """ - is_post_id = db.query(SysPost).filter(SysPost.post_id == post.get('post_id')).all() - if not is_post_id: - result = dict(is_success=False, message='岗位不存在') - else: + @classmethod + def get_post_by_id(cls, db: Session, post_id: int): + """ + 根据岗位id获取在用岗位详细信息 + :param db: orm对象 + :param post_id: 岗位id + :return: 在用岗位信息对象 + """ + post_info = db.query(SysPost) \ + .filter(SysPost.post_id == post_id, + SysPost.status == 0) \ + .first() + + return post_info + + @classmethod + def get_post_detail_by_id(cls, db: Session, post_id: int): + """ + 根据岗位id获取岗位详细信息 + :param db: orm对象 + :param post_id: 岗位id + :return: 岗位信息对象 + """ + post_info = db.query(SysPost) \ + .filter(SysPost.post_id == post_id) \ + .first() + + return post_info + + @classmethod + def get_post_detail_by_info(cls, db: Session, post: PostModel): + """ + 根据岗位参数获取岗位信息 + :param db: orm对象 + :param post: 岗位参数对象 + :return: 岗位信息对象 + """ + post_info = db.query(SysPost) \ + .filter(SysPost.post_name == post.post_name if post.post_name else True, + SysPost.post_code == post.post_code if post.post_code else True, + SysPost.post_sort == post.post_sort if post.post_sort else True) \ + .first() + + return post_info + + @classmethod + def get_post_select_option_dao(cls, db: Session): + """ + 获取所有在用岗位信息 + :param db: orm对象 + :return: 在用岗位信息列表 + """ + post_info = db.query(SysPost) \ + .filter(SysPost.status == 0) \ + .all() + + return post_info + + @classmethod + def get_post_list(cls, db: Session, query_object: PostModel): + """ + 根据查询参数获取岗位列表信息 + :param db: orm对象 + :param query_object: 查询参数对象 + :return: 岗位列表信息对象 + """ + post_list = db.query(SysPost) \ + .filter(SysPost.post_code.like(f'%{query_object.post_code}%') if query_object.post_code else True, + SysPost.post_name.like(f'%{query_object.post_name}%') if query_object.post_name else True, + SysPost.status == query_object.status if query_object.status else True + ) \ + .order_by(SysPost.post_sort) \ + .distinct().all() + + return list_format_datetime(post_list) + + @classmethod + def add_post_dao(cls, db: Session, post: PostModel): + """ + 新增岗位数据库操作 + :param db: orm对象 + :param post: 岗位对象 + :return: + """ + db_post = SysPost(**post.dict()) + db.add(db_post) + db.flush() + + return db_post + + @classmethod + def edit_post_dao(cls, db: Session, post: dict): + """ + 编辑岗位数据库操作 + :param db: orm对象 + :param post: 需要更新的岗位字典 + :return: + """ db.query(SysPost) \ .filter(SysPost.post_id == post.get('post_id')) \ .update(post) - db.commit() # 提交保存到数据库中 - result = dict(is_success=True, message='更新成功') - return CrudPostResponse(**result) - - -def delete_post_crud(db: Session, post: PostModel): - """ - 删除岗位数据库操作 - :param db: orm对象 - :param post: 岗位对象 - :return: - """ - db.query(SysPost) \ - .filter(SysPost.post_id == post.post_id) \ - .delete() - db.commit() # 提交保存到数据库中 + @classmethod + def delete_post_dao(cls, db: Session, post: PostModel): + """ + 删除岗位数据库操作 + :param db: orm对象 + :param post: 岗位对象 + :return: + """ + db.query(SysPost) \ + .filter(SysPost.post_id == post.post_id) \ + .delete() diff --git a/dash-fastapi-backend/module_admin/dao/role_dao.py b/dash-fastapi-backend/module_admin/dao/role_dao.py index 6923dd510399d5bead4d9c3f643f38a86c213a4a..52f13f691db2e58b3973d3b949aa5f9cdcf9f5a4 100644 --- a/dash-fastapi-backend/module_admin/dao/role_dao.py +++ b/dash-fastapi-backend/module_admin/dao/role_dao.py @@ -1,185 +1,179 @@ from sqlalchemy import and_, desc from sqlalchemy.orm import Session -from module_admin.entity.do.role_entity import SysRole, SysRoleMenu -from module_admin.entity.do.menu_entity import SysMenu -from module_admin.entity.vo.role_schema import RoleModel, RoleMenuModel, RolePageObject, RolePageObjectResponse, CrudRoleResponse, RoleDetailModel -from module_admin.utils.time_format_tool import list_format_datetime, object_format_datetime -from module_admin.utils.page_tool import get_page_info +from module_admin.entity.do.role_do import SysRole, SysRoleMenu +from module_admin.entity.do.menu_do import SysMenu +from module_admin.entity.vo.role_vo import RoleModel, RoleMenuModel, RoleQueryModel, RoleDetailModel +from utils.time_format_util import list_format_datetime, object_format_datetime from datetime import datetime, time -def get_role_by_name(db: Session, role_name: str): - """ - 根据角色名获取角色信息 - :param db: orm对象 - :param role_name: 角色名 - :return: 当前角色名的角色信息对象 - """ - query_role_info = db.query(SysRole) \ - .filter(SysRole.status == 0, SysRole.del_flag == 0, SysRole.role_name == role_name) \ - .order_by(desc(SysRole.create_time)).distinct().first() - - return query_role_info - - -def get_role_by_id(db: Session, role_id: int): - role_info = db.query(SysRole) \ - .filter(SysRole.role_id == role_id, - SysRole.status == 0, - SysRole.del_flag == 0) \ - .first() - - return role_info - - -def get_role_detail_by_id(db: Session, role_id: int): - """ - 根据role_id获取角色详细信息 - :param db: orm对象 - :param role_id: 角色id - :return: 当前role_id的角色信息对象 - """ - query_role_basic_info = db.query(SysRole) \ - .filter(SysRole.del_flag == 0, SysRole.role_id == role_id) \ - .distinct().first() - query_role_menu_info = db.query(SysMenu).select_from(SysRole) \ - .filter(SysRole.del_flag == 0, SysRole.role_id == role_id) \ - .outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \ - .outerjoin(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysMenu.status == 0)) \ - .distinct().all() - results = dict( - role=object_format_datetime(query_role_basic_info), - menu=list_format_datetime(query_role_menu_info), - ) - - return RoleDetailModel(**results) - - -def get_role_select_option_crud(db: Session): - role_info = db.query(SysRole) \ - .filter(SysRole.status == 0, SysRole.del_flag == 0) \ - .all() - - return role_info - - -def get_role_list(db: Session, page_object: RolePageObject): - """ - 根据查询参数获取角色列表信息 - :param db: orm对象 - :param page_object: 分页查询参数对象 - :return: 角色列表信息对象 - """ - count = db.query(SysRole) \ - .filter(SysRole.del_flag == 0, - SysRole.role_name.like(f'%{page_object.role_name}%') if page_object.role_name else True, - SysRole.role_key.like(f'%{page_object.role_key}%') if page_object.role_key else True, - SysRole.status == page_object.status if page_object.status else True, - SysRole.create_time.between( - datetime.combine(datetime.strptime(page_object.create_time_start, '%Y-%m-%d'), time(00, 00, 00)), - datetime.combine(datetime.strptime(page_object.create_time_end, '%Y-%m-%d'), time(23, 59, 59))) - if page_object.create_time_start and page_object.create_time_end else True - )\ - .order_by(SysRole.role_sort)\ - .distinct().count() - offset_com = (page_object.page_num - 1) * page_object.page_size - page_info = get_page_info(offset_com, page_object.page_num, page_object.page_size, count) - role_list = db.query(SysRole) \ - .filter(SysRole.del_flag == 0, - SysRole.role_name.like(f'%{page_object.role_name}%') if page_object.role_name else True, - SysRole.role_key.like(f'%{page_object.role_key}%') if page_object.role_key else True, - SysRole.status == page_object.status if page_object.status else True, - SysRole.create_time.between( - datetime.combine(datetime.strptime(page_object.create_time_start, '%Y-%m-%d'), time(00, 00, 00)), - datetime.combine(datetime.strptime(page_object.create_time_end, '%Y-%m-%d'), time(23, 59, 59))) - if page_object.create_time_start and page_object.create_time_end else True - ) \ - .order_by(SysRole.role_sort) \ - .offset(page_info.offset) \ - .limit(page_object.page_size) \ - .distinct().all() - - result = dict( - rows=list_format_datetime(role_list), - page_num=page_info.page_num, - page_size=page_info.page_size, - total=page_info.total, - has_next=page_info.has_next - ) - - return RolePageObjectResponse(**result) - - -def add_role_crud(db: Session, role: RoleModel): - """ - 新增角色数据库操作 - :param db: orm对象 - :param role: 角色对象 - :return: 新增校验结果 - """ - db_role = SysRole(**role.dict()) - db.add(db_role) - db.commit() # 提交保存到数据库中 - db.refresh(db_role) # 刷新 - result = dict(is_success=True, message='新增成功') - - return CrudRoleResponse(**result) - - -def edit_role_crud(db: Session, role: dict): - """ - 编辑角色数据库操作 - :param db: orm对象 - :param role: 需要更新的角色字典 - :return: 编辑校验结果 - """ - is_role_id = db.query(SysRole).filter(SysRole.role_id == role.get('role_id')).all() - if not is_role_id: - result = dict(is_success=False, message='角色不存在') - else: +class RoleDao: + """ + 角色管理模块数据库操作层 + """ + + @classmethod + def get_role_by_name(cls, db: Session, role_name: str): + """ + 根据角色名获取在用角色信息 + :param db: orm对象 + :param role_name: 角色名 + :return: 当前角色名的角色信息对象 + """ + query_role_info = db.query(SysRole) \ + .filter(SysRole.status == 0, SysRole.del_flag == 0, SysRole.role_name == role_name) \ + .order_by(desc(SysRole.create_time)).distinct().first() + + return query_role_info + + @classmethod + def get_role_by_info(cls, db: Session, role: RoleModel): + """ + 根据角色参数获取角色信息 + :param db: orm对象 + :param role: 角色参数 + :return: 当前角色参数的角色信息对象 + """ + query_role_info = db.query(SysRole) \ + .filter(SysRole.del_flag == 0, + SysRole.role_name == role.role_name if role.role_name else True, + SysRole.role_key == role.role_key if role.role_key else True) \ + .order_by(desc(SysRole.create_time)).distinct().first() + + return query_role_info + + @classmethod + def get_role_by_id(cls, db: Session, role_id: int): + """ + 根据角色id获取在用角色信息 + :param db: orm对象 + :param role_id: 角色id + :return: 当前角色id的角色信息对象 + """ + role_info = db.query(SysRole) \ + .filter(SysRole.role_id == role_id, + SysRole.status == 0, + SysRole.del_flag == 0) \ + .first() + + return role_info + + @classmethod + def get_role_detail_by_id(cls, db: Session, role_id: int): + """ + 根据role_id获取角色详细信息 + :param db: orm对象 + :param role_id: 角色id + :return: 当前role_id的角色信息对象 + """ + query_role_basic_info = db.query(SysRole) \ + .filter(SysRole.del_flag == 0, SysRole.role_id == role_id) \ + .distinct().first() + query_role_menu_info = db.query(SysMenu).select_from(SysRole) \ + .filter(SysRole.del_flag == 0, SysRole.role_id == role_id) \ + .outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \ + .outerjoin(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysMenu.status == 0)) \ + .distinct().all() + results = dict( + role=object_format_datetime(query_role_basic_info), + menu=list_format_datetime(query_role_menu_info), + ) + + return RoleDetailModel(**results) + + @classmethod + def get_role_select_option_dao(cls, db: Session): + """ + 获取编辑页面对应的在用角色列表信息 + :param db: orm对象 + :return: 角色列表信息 + """ + role_info = db.query(SysRole) \ + .filter(SysRole.role_id != 1, SysRole.status == 0, SysRole.del_flag == 0) \ + .all() + + return role_info + + @classmethod + def get_role_list(cls, db: Session, query_object: RoleQueryModel): + """ + 根据查询参数获取角色列表信息 + :param db: orm对象 + :param query_object: 查询参数对象 + :return: 角色列表信息对象 + """ + role_list = db.query(SysRole) \ + .filter(SysRole.del_flag == 0, + SysRole.role_name.like(f'%{query_object.role_name}%') if query_object.role_name else True, + SysRole.role_key.like(f'%{query_object.role_key}%') if query_object.role_key else True, + SysRole.status == query_object.status if query_object.status else True, + SysRole.create_time.between( + datetime.combine(datetime.strptime(query_object.create_time_start, '%Y-%m-%d'), time(00, 00, 00)), + datetime.combine(datetime.strptime(query_object.create_time_end, '%Y-%m-%d'), time(23, 59, 59))) + if query_object.create_time_start and query_object.create_time_end else True + ) \ + .order_by(SysRole.role_sort) \ + .distinct().all() + + return list_format_datetime(role_list) + + @classmethod + def add_role_dao(cls, db: Session, role: RoleModel): + """ + 新增角色数据库操作 + :param db: orm对象 + :param role: 角色对象 + :return: + """ + db_role = SysRole(**role.dict()) + db.add(db_role) + db.flush() + + return db_role + + @classmethod + def edit_role_dao(cls, db: Session, role: dict): + """ + 编辑角色数据库操作 + :param db: orm对象 + :param role: 需要更新的角色字典 + :return: + """ db.query(SysRole) \ .filter(SysRole.role_id == role.get('role_id')) \ .update(role) - db.commit() # 提交保存到数据库中 - result = dict(is_success=True, message='更新成功') - - return CrudRoleResponse(**result) - -def delete_role_crud(db: Session, role: RoleModel): - """ - 删除角色数据库操作 - :param db: orm对象 - :param user: 角色对象 - :return: - """ - db.query(SysRole) \ - .filter(SysRole.role_id == role.role_id) \ - .update({SysRole.del_flag: '2', SysRole.update_by: role.update_by, SysRole.update_time: role.update_time}) - db.commit() # 提交保存到数据库中 - - -def add_role_menu_crud(db: Session, role_menu: RoleMenuModel): - """ - 新增角色菜单关联信息数据库操作 - :param db: orm对象 - :param role_menu: 用户角色菜单关联对象 - :return: - """ - db_role_menu = SysRoleMenu(**role_menu.dict()) - db.add(db_role_menu) - db.commit() # 提交保存到数据库中 - db.refresh(db_role_menu) # 刷新 - - -def delete_role_menu_crud(db: Session, role_menu: RoleMenuModel): - """ - 删除角色菜单关联信息数据库操作 - :param db: orm对象 - :param role_menu: 角色菜单关联对象 - :return: - """ - db.query(SysRoleMenu) \ - .filter(SysRoleMenu.role_id == role_menu.role_id) \ - .delete() - db.commit() # 提交保存到数据库中 + @classmethod + def delete_role_dao(cls, db: Session, role: RoleModel): + """ + 删除角色数据库操作 + :param db: orm对象 + :param role: 角色对象 + :return: + """ + db.query(SysRole) \ + .filter(SysRole.role_id == role.role_id) \ + .update({SysRole.del_flag: '2', SysRole.update_by: role.update_by, SysRole.update_time: role.update_time}) + + @classmethod + def add_role_menu_dao(cls, db: Session, role_menu: RoleMenuModel): + """ + 新增角色菜单关联信息数据库操作 + :param db: orm对象 + :param role_menu: 用户角色菜单关联对象 + :return: + """ + db_role_menu = SysRoleMenu(**role_menu.dict()) + db.add(db_role_menu) + + @classmethod + def delete_role_menu_dao(cls, db: Session, role_menu: RoleMenuModel): + """ + 删除角色菜单关联信息数据库操作 + :param db: orm对象 + :param role_menu: 角色菜单关联对象 + :return: + """ + db.query(SysRoleMenu) \ + .filter(SysRoleMenu.role_id == role_menu.role_id) \ + .delete() diff --git a/dash-fastapi-backend/module_admin/dao/user_dao.py b/dash-fastapi-backend/module_admin/dao/user_dao.py index 81da5384a01e22cdfca80c0ab0ec6db33b48a2ec..818823fb61304cb910fe877fcbdd3a4f92a8e1d3 100644 --- a/dash-fastapi-backend/module_admin/dao/user_dao.py +++ b/dash-fastapi-backend/module_admin/dao/user_dao.py @@ -1,308 +1,287 @@ -from sqlalchemy import and_, desc +from sqlalchemy import and_, or_, desc, func from sqlalchemy.orm import Session -from module_admin.entity.do.user_entity import SysUser, SysUserRole, SysUserPost -from module_admin.entity.do.role_entity import SysRole, SysRoleMenu -from module_admin.entity.do.dept_entity import SysDept -from module_admin.entity.do.post_entity import SysPost -from module_admin.entity.do.menu_entity import SysMenu -from module_admin.entity.vo.user_schema import UserModel, UserRoleModel, UserPostModel, CurrentUserInfo, UserPageObject, \ - UserPageObjectResponse, CrudUserResponse -from module_admin.utils.time_format_tool import list_format_datetime, format_datetime_dict_list -from module_admin.utils.page_tool import get_page_info +from module_admin.entity.do.user_do import SysUser, SysUserRole, SysUserPost +from module_admin.entity.do.role_do import SysRole, SysRoleMenu +from module_admin.entity.do.dept_do import SysDept +from module_admin.entity.do.post_do import SysPost +from module_admin.entity.do.menu_do import SysMenu +from module_admin.entity.vo.user_vo import UserModel, UserRoleModel, UserPostModel, CurrentUserInfo, UserQueryModel +from utils.time_format_util import list_format_datetime, format_datetime_dict_list from datetime import datetime, time +from typing import Union, List -def get_user_by_name(db: Session, user_name: str): +class UserDao: """ - 根据用户名获取用户信息 - :param db: orm对象 - :param user_name: 用户名 - :return: 当前用户名的用户信息对象 + 用户管理模块数据库操作层 """ - query_user_info = db.query(SysUser) \ - .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_name == user_name) \ - .order_by(desc(SysUser.create_time)).distinct().first() - return query_user_info - - -def get_user_by_id(db: Session, user_id: int): - """ - 根据user_id获取用户信息 - :param db: orm对象 - :param user_id: 用户id - :return: 当前user_id的用户信息对象 - """ - query_user_basic_info = db.query(SysUser) \ - .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ - .distinct().all() - query_user_dept_info = db.query(SysDept).select_from(SysUser) \ - .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ - .outerjoin(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \ - .distinct().all() - query_user_role_info = db.query(SysRole).select_from(SysUser) \ - .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ - .outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \ - .outerjoin(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ - .distinct().all() - query_user_post_info = db.query(SysPost).select_from(SysUser) \ - .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ - .outerjoin(SysUserPost, SysUser.user_id == SysUserPost.user_id) \ - .outerjoin(SysPost, and_(SysUserPost.post_id == SysPost.post_id, SysPost.status == 0)) \ - .distinct().all() - query_user_menu_info = db.query(SysMenu).select_from(SysUser) \ - .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ - .outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \ - .outerjoin(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ - .outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \ - .outerjoin(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysMenu.status == 0)) \ - .distinct().all() - results = dict( - user_basic_info=list_format_datetime(query_user_basic_info), - user_dept_info=list_format_datetime(query_user_dept_info), - user_role_info=list_format_datetime(query_user_role_info), - user_post_info=list_format_datetime(query_user_post_info), - user_menu_info=list_format_datetime(query_user_menu_info) - ) - - return CurrentUserInfo(**results) - - -def get_user_detail_by_id(db: Session, user_id: int): - """ - 根据user_id获取用户详细信息 - :param db: orm对象 - :param user_id: 用户id - :return: 当前user_id的用户信息对象 - """ - query_user_basic_info = db.query(SysUser) \ - .filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \ - .distinct().all() - query_user_dept_info = db.query(SysDept).select_from(SysUser) \ - .filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \ - .outerjoin(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \ - .distinct().all() - query_user_role_info = db.query(SysRole).select_from(SysUser) \ - .filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \ - .outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \ - .outerjoin(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ - .distinct().all() - query_user_post_info = db.query(SysPost).select_from(SysUser) \ - .filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \ - .outerjoin(SysUserPost, SysUser.user_id == SysUserPost.user_id) \ - .outerjoin(SysPost, and_(SysUserPost.post_id == SysPost.post_id, SysPost.status == 0)) \ - .distinct().all() - query_user_menu_info = db.query(SysMenu).select_from(SysUser) \ - .filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \ - .outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \ - .outerjoin(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ - .outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \ - .outerjoin(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysMenu.status == 0)) \ - .distinct().all() - results = dict( - user_basic_info=list_format_datetime(query_user_basic_info), - user_dept_info=list_format_datetime(query_user_dept_info), - user_role_info=list_format_datetime(query_user_role_info), - user_post_info=list_format_datetime(query_user_post_info), - user_menu_info=list_format_datetime(query_user_menu_info) - ) - - return CurrentUserInfo(**results) - - -def get_user_list(db: Session, page_object: UserPageObject): - """ - 根据查询参数获取用户列表信息 - :param db: orm对象 - :param page_object: 分页查询参数对象 - :return: 用户列表信息对象 - """ - count = db.query(SysUser, SysDept) \ - .filter(SysUser.del_flag == 0, - SysUser.dept_id == page_object.dept_id if page_object.dept_id else True, - SysUser.user_name.like(f'%{page_object.user_name}%') if page_object.user_name else True, - SysUser.nick_name.like(f'%{page_object.nick_name}%') if page_object.nick_name else True, - SysUser.email.like(f'%{page_object.email}%') if page_object.email else True, - SysUser.phonenumber.like(f'%{page_object.phonenumber}%') if page_object.phonenumber else True, - SysUser.status == page_object.status if page_object.status else True, - SysUser.sex == page_object.sex if page_object.sex else True, - SysUser.create_time.between( - datetime.combine(datetime.strptime(page_object.create_time_start, '%Y-%m-%d'), time(00, 00, 00)), - datetime.combine(datetime.strptime(page_object.create_time_end, '%Y-%m-%d'), time(23, 59, 59))) - if page_object.create_time_start and page_object.create_time_end else True - ) \ - .outerjoin(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \ - .distinct().count() - offset_com = (page_object.page_num - 1) * page_object.page_size - page_info = get_page_info(offset_com, page_object.page_num, page_object.page_size, count) - user_list = db.query(SysUser, SysDept) \ - .filter(SysUser.del_flag == 0, - SysUser.dept_id == page_object.dept_id if page_object.dept_id else True, - SysUser.user_name.like(f'%{page_object.user_name}%') if page_object.user_name else True, - SysUser.nick_name.like(f'%{page_object.nick_name}%') if page_object.nick_name else True, - SysUser.email.like(f'%{page_object.email}%') if page_object.email else True, - SysUser.phonenumber.like(f'%{page_object.phonenumber}%') if page_object.phonenumber else True, - SysUser.status == page_object.status if page_object.status else True, - SysUser.sex == page_object.sex if page_object.sex else True, - SysUser.create_time.between( - datetime.combine(datetime.strptime(page_object.create_time_start, '%Y-%m-%d'), time(00, 00, 00)), - datetime.combine(datetime.strptime(page_object.create_time_end, '%Y-%m-%d'), time(23, 59, 59))) - if page_object.create_time_start and page_object.create_time_end else True - ) \ - .outerjoin(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \ - .offset(page_info.offset) \ - .limit(page_object.page_size) \ - .distinct().all() - - result_list = [] - if user_list: - for item in user_list: - obj = dict( - user_id=item[0].user_id, - dept_id=item[0].dept_id, - dept_name=item[1].dept_name if item[1] else '', - user_name=item[0].user_name, - nick_name=item[0].nick_name, - user_type=item[0].user_type, - email=item[0].email, - phonenumber=item[0].phonenumber, - sex=item[0].sex, - avatar=item[0].avatar, - status=item[0].status, - del_flag=item[0].del_flag, - login_ip=item[0].login_ip, - login_date=item[0].login_date, - create_by=item[0].create_by, - create_time=item[0].create_time, - update_by=item[0].update_by, - update_time=item[0].update_time, - remark=item[0].remark - ) - result_list.append(obj) - - result = dict( - rows=format_datetime_dict_list(result_list), - page_num=page_info.page_num, - page_size=page_info.page_size, - total=page_info.total, - has_next=page_info.has_next - ) - - return UserPageObjectResponse(**result) - - -def add_user_crud(db: Session, user: UserModel): - """ - 新增用户数据库操作 - :param db: orm对象 - :param user: 用户对象 - :return: 新增校验结果 - """ - is_user = db.query(SysUser).filter(SysUser.user_name == user.user_name, SysUser.del_flag == 0).all() - if is_user: - result = dict(is_success=False, message='用户名已存在') - else: + @classmethod + def get_user_by_name(cls, db: Session, user_name: str): + """ + 根据用户名获取用户信息 + :param db: orm对象 + :param user_name: 用户名 + :return: 当前用户名的用户信息对象 + """ + query_user_info = db.query(SysUser) \ + .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_name == user_name) \ + .order_by(desc(SysUser.create_time)).distinct().first() + + return query_user_info + + @classmethod + def get_user_by_info(cls, db: Session, user: UserModel): + """ + 根据用户参数获取用户信息 + :param db: orm对象 + :param user: 用户参数 + :return: 当前用户参数的用户信息对象 + """ + query_user_info = db.query(SysUser) \ + .filter(SysUser.del_flag == 0, + SysUser.user_name == user.user_name) \ + .order_by(desc(SysUser.create_time)).distinct().first() + + return query_user_info + + @classmethod + def get_user_by_id(cls, db: Session, user_id: int): + """ + 根据user_id获取用户信息 + :param db: orm对象 + :param user_id: 用户id + :return: 当前user_id的用户信息对象 + """ + query_user_basic_info = db.query(SysUser) \ + .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ + .distinct().all() + query_user_dept_info = db.query(SysDept).select_from(SysUser) \ + .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ + .outerjoin(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \ + .distinct().all() + query_user_role_info = db.query(SysRole).select_from(SysUser) \ + .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ + .outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \ + .outerjoin(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ + .distinct().all() + query_user_post_info = db.query(SysPost).select_from(SysUser) \ + .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ + .outerjoin(SysUserPost, SysUser.user_id == SysUserPost.user_id) \ + .outerjoin(SysPost, and_(SysUserPost.post_id == SysPost.post_id, SysPost.status == 0)) \ + .distinct().all() + query_user_menu_info = [] + for item in query_user_role_info: + if item.role_id == 1: + query_user_menu_info = db.query(SysMenu) \ + .filter(SysMenu.status == 0) \ + .distinct().all() + break + else: + query_user_menu_info = db.query(SysMenu).select_from(SysUser) \ + .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ + .outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \ + .outerjoin(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ + .outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \ + .outerjoin(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysMenu.status == 0)) \ + .order_by(SysMenu.order_num) \ + .distinct().all() + results = dict( + user_basic_info=list_format_datetime(query_user_basic_info), + user_dept_info=list_format_datetime(query_user_dept_info), + user_role_info=list_format_datetime(query_user_role_info), + user_post_info=list_format_datetime(query_user_post_info), + user_menu_info=list_format_datetime(query_user_menu_info) + ) + + return CurrentUserInfo(**results) + + @classmethod + def get_user_detail_by_id(cls, db: Session, user_id: int): + """ + 根据user_id获取用户详细信息 + :param db: orm对象 + :param user_id: 用户id + :return: 当前user_id的用户信息对象 + """ + query_user_basic_info = db.query(SysUser) \ + .filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \ + .distinct().all() + query_user_dept_info = db.query(SysDept).select_from(SysUser) \ + .filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \ + .outerjoin(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \ + .distinct().all() + query_user_role_info = db.query(SysRole).select_from(SysUser) \ + .filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \ + .outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \ + .outerjoin(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ + .distinct().all() + query_user_post_info = db.query(SysPost).select_from(SysUser) \ + .filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \ + .outerjoin(SysUserPost, SysUser.user_id == SysUserPost.user_id) \ + .outerjoin(SysPost, and_(SysUserPost.post_id == SysPost.post_id, SysPost.status == 0)) \ + .distinct().all() + query_user_menu_info = db.query(SysMenu).select_from(SysUser) \ + .filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \ + .outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \ + .outerjoin(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ + .outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \ + .outerjoin(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysMenu.status == 0)) \ + .distinct().all() + results = dict( + user_basic_info=list_format_datetime(query_user_basic_info), + user_dept_info=list_format_datetime(query_user_dept_info), + user_role_info=list_format_datetime(query_user_role_info), + user_post_info=list_format_datetime(query_user_post_info), + user_menu_info=list_format_datetime(query_user_menu_info) + ) + + return CurrentUserInfo(**results) + + @classmethod + def get_user_list(cls, db: Session, query_object: UserQueryModel): + """ + 根据查询参数获取用户列表信息 + :param db: orm对象 + :param query_object: 查询参数对象 + :return: 用户列表信息对象 + """ + user_list = db.query(SysUser, SysDept) \ + .filter(SysUser.del_flag == 0, + or_(SysUser.dept_id == query_object.dept_id, SysUser.dept_id.in_( + db.query(SysDept.dept_id).filter(func.find_in_set(query_object.dept_id, SysDept.ancestors)) + )) if query_object.dept_id else True, + SysUser.user_name.like(f'%{query_object.user_name}%') if query_object.user_name else True, + SysUser.nick_name.like(f'%{query_object.nick_name}%') if query_object.nick_name else True, + SysUser.email.like(f'%{query_object.email}%') if query_object.email else True, + SysUser.phonenumber.like(f'%{query_object.phonenumber}%') if query_object.phonenumber else True, + SysUser.status == query_object.status if query_object.status else True, + SysUser.sex == query_object.sex if query_object.sex else True, + SysUser.create_time.between( + datetime.combine(datetime.strptime(query_object.create_time_start, '%Y-%m-%d'), time(00, 00, 00)), + datetime.combine(datetime.strptime(query_object.create_time_end, '%Y-%m-%d'), time(23, 59, 59))) + if query_object.create_time_start and query_object.create_time_end else True + ) \ + .outerjoin(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \ + .distinct().all() + + result_list: List[Union[dict, None]] = [] + if user_list: + for item in user_list: + obj = dict( + user_id=item[0].user_id, + dept_id=item[0].dept_id, + dept_name=item[1].dept_name if item[1] else '', + user_name=item[0].user_name, + nick_name=item[0].nick_name, + user_type=item[0].user_type, + email=item[0].email, + phonenumber=item[0].phonenumber, + sex=item[0].sex, + avatar=item[0].avatar, + status=item[0].status, + del_flag=item[0].del_flag, + login_ip=item[0].login_ip, + login_date=item[0].login_date, + create_by=item[0].create_by, + create_time=item[0].create_time, + update_by=item[0].update_by, + update_time=item[0].update_time, + remark=item[0].remark + ) + result_list.append(obj) + + return format_datetime_dict_list(result_list) + + @classmethod + def add_user_dao(cls, db: Session, user: UserModel): + """ + 新增用户数据库操作 + :param db: orm对象 + :param user: 用户对象 + :return: 新增校验结果 + """ db_user = SysUser(**user.dict()) db.add(db_user) - db.commit() # 提交保存到数据库中 - db.refresh(db_user) # 刷新 - result = dict(is_success=True, message='新增成功') - - return CrudUserResponse(**result) - - -def edit_user_crud(db: Session, user: dict): - """ - 编辑用户数据库操作 - :param db: orm对象 - :param user: 需要更新的用户字典 - :return: 编辑校验结果 - """ - is_user_id = db.query(SysUser).filter(SysUser.user_id == user.get('user_id'), SysUser.del_flag == 0).all() - is_user_name = db.query(SysUser).filter(SysUser.user_name == user.get('user_name'), SysUser.del_flag == 0).all() - if not is_user_id: - result = dict(is_success=False, message='用户不存在') - elif is_user_name: - result = dict(is_success=False, message='用户名已存在,不允许修改') - else: + db.flush() + + return db_user + + @classmethod + def edit_user_dao(cls, db: Session, user: dict): + """ + 编辑用户数据库操作 + :param db: orm对象 + :param user: 需要更新的用户字典 + :return: 编辑校验结果 + """ db.query(SysUser) \ .filter(SysUser.user_id == user.get('user_id')) \ .update(user) - db.commit() # 提交保存到数据库中 - result = dict(is_success=True, message='更新成功') - - return CrudUserResponse(**result) - - -def delete_user_crud(db: Session, user: UserModel): - """ - 删除用户数据库操作 - :param db: orm对象 - :param user: 用户对象 - :return: - """ - db.query(SysUser) \ - .filter(SysUser.user_id == user.user_id) \ - .update({SysUser.del_flag: '2', SysUser.update_by: user.update_by, SysUser.update_time: user.update_time}) - db.commit() # 提交保存到数据库中 - - -def add_user_role_crud(db: Session, user_role: UserRoleModel): - """ - 新增用户角色关联信息数据库操作 - :param db: orm对象 - :param user_role: 用户角色关联对象 - :return: - """ - db_user_role = SysUserRole(**user_role.dict()) - db.add(db_user_role) - db.commit() # 提交保存到数据库中 - db.refresh(db_user_role) # 刷新 - - -def delete_user_role_crud(db: Session, user_role: UserRoleModel): - """ - 删除用户角色关联信息数据库操作 - :param db: orm对象 - :param user_role: 用户角色关联对象 - :return: - """ - db.query(SysUserRole) \ - .filter(SysUserRole.user_id == user_role.user_id) \ - .delete() - db.commit() # 提交保存到数据库中 - - -def add_user_post_crud(db: Session, user_post: UserPostModel): - """ - 新增用户岗位关联信息数据库操作 - :param db: orm对象 - :param user_post: 用户岗位关联对象 - :return: - """ - db_user_post = SysUserPost(**user_post.dict()) - db.add(db_user_post) - db.commit() # 提交保存到数据库中 - db.refresh(db_user_post) # 刷新 - -def delete_user_post_crud(db: Session, user_post: UserPostModel): - """ - 删除用户岗位关联信息数据库操作 - :param db: orm对象 - :param user_post: 用户岗位关联对象 - :return: - """ - db.query(SysUserPost) \ - .filter(SysUserPost.user_id == user_post.user_id) \ - .delete() - db.commit() # 提交保存到数据库中 - - -def get_user_dept_info(db: Session, dept_id: int): - dept_basic_info = db.query(SysDept) \ - .filter(SysDept.dept_id == dept_id, - SysDept.status == 0, - SysDept.del_flag == 0) \ - .first() - return dept_basic_info + @classmethod + def delete_user_dao(cls, db: Session, user: UserModel): + """ + 删除用户数据库操作 + :param db: orm对象 + :param user: 用户对象 + :return: + """ + db.query(SysUser) \ + .filter(SysUser.user_id == user.user_id) \ + .update({SysUser.del_flag: '2', SysUser.update_by: user.update_by, SysUser.update_time: user.update_time}) + + @classmethod + def add_user_role_dao(cls, db: Session, user_role: UserRoleModel): + """ + 新增用户角色关联信息数据库操作 + :param db: orm对象 + :param user_role: 用户角色关联对象 + :return: + """ + db_user_role = SysUserRole(**user_role.dict()) + db.add(db_user_role) + + @classmethod + def delete_user_role_dao(cls, db: Session, user_role: UserRoleModel): + """ + 删除用户角色关联信息数据库操作 + :param db: orm对象 + :param user_role: 用户角色关联对象 + :return: + """ + db.query(SysUserRole) \ + .filter(SysUserRole.user_id == user_role.user_id) \ + .delete() + + @classmethod + def add_user_post_dao(cls, db: Session, user_post: UserPostModel): + """ + 新增用户岗位关联信息数据库操作 + :param db: orm对象 + :param user_post: 用户岗位关联对象 + :return: + """ + db_user_post = SysUserPost(**user_post.dict()) + db.add(db_user_post) + + @classmethod + def delete_user_post_dao(cls, db: Session, user_post: UserPostModel): + """ + 删除用户岗位关联信息数据库操作 + :param db: orm对象 + :param user_post: 用户岗位关联对象 + :return: + """ + db.query(SysUserPost) \ + .filter(SysUserPost.user_id == user_post.user_id) \ + .delete() + + @classmethod + def get_user_dept_info(cls, db: Session, dept_id: int): + dept_basic_info = db.query(SysDept) \ + .filter(SysDept.dept_id == dept_id, + SysDept.status == 0, + SysDept.del_flag == 0) \ + .first() + return dept_basic_info diff --git a/dash-fastapi-backend/module_admin/entity/do/config_do.py b/dash-fastapi-backend/module_admin/entity/do/config_do.py new file mode 100644 index 0000000000000000000000000000000000000000..5fb6476005cd3f45aeed01c695e30fc8f5609fd6 --- /dev/null +++ b/dash-fastapi-backend/module_admin/entity/do/config_do.py @@ -0,0 +1,21 @@ +from sqlalchemy import Column, Integer, String, DateTime +from config.database import Base +from datetime import datetime + + +class SysConfig(Base): + """ + 参数配置表 + """ + __tablename__ = 'sys_config' + + config_id = Column(Integer, primary_key=True, autoincrement=True, comment='参数主键') + config_name = Column(String(100), nullable=True, default='', comment='参数名称') + config_key = Column(String(100), nullable=True, default='', comment='参数键名') + config_value = Column(String(500), nullable=True, default='', comment='参数键值') + config_type = Column(String(1), nullable=True, default='N', comment='系统内置(Y是 N否)') + create_by = Column(String(64), nullable=True, default='', comment='创建者') + create_time = Column(DateTime, nullable=True, default=datetime.now(), comment='创建时间') + update_by = Column(String(64), nullable=True, default='', comment='更新者') + update_time = Column(DateTime, nullable=True, default=datetime.now(), comment='更新时间') + remark = Column(String(500), nullable=True, default='', comment='备注') \ No newline at end of file diff --git a/dash-fastapi-backend/module_admin/entity/do/dept_do.py b/dash-fastapi-backend/module_admin/entity/do/dept_do.py index 283c2fc2b7d63b00305d980abee39aee7404fa6e..05729270974100678e662fbb1d7689309677e0bc 100644 --- a/dash-fastapi-backend/module_admin/entity/do/dept_do.py +++ b/dash-fastapi-backend/module_admin/entity/do/dept_do.py @@ -1,5 +1,5 @@ from sqlalchemy import Column, Integer, String, DateTime -from config.database import Base, engine +from config.database import Base from datetime import datetime @@ -23,6 +23,3 @@ class SysDept(Base): create_time = Column(DateTime, nullable=True, default=datetime.now(), comment='创建时间') update_by = Column(String(64), nullable=True, default='', comment='更新者') update_time = Column(DateTime, nullable=True, default=datetime.now(), comment='更新时间') - - -Base.metadata.create_all(bind=engine) \ No newline at end of file diff --git a/dash-fastapi-backend/module_admin/entity/do/dict_do.py b/dash-fastapi-backend/module_admin/entity/do/dict_do.py index 4e4d995f05f344d0c9eb8db16bfbd9b11cdacb21..a7d630efad527c3748133ba961f4bc9027805280 100644 --- a/dash-fastapi-backend/module_admin/entity/do/dict_do.py +++ b/dash-fastapi-backend/module_admin/entity/do/dict_do.py @@ -1,5 +1,5 @@ from sqlalchemy import Column, Integer, String, DateTime, UniqueConstraint -from config.database import Base, engine +from config.database import Base from datetime import datetime @@ -44,6 +44,3 @@ class SysDictData(Base): update_by = Column(String(64), nullable=True, default='', comment='更新者') update_time = Column(DateTime, nullable=True, default=datetime.now(), comment='更新时间') remark = Column(String(500), nullable=True, default='', comment='备注') - - -Base.metadata.create_all(bind=engine) diff --git a/dash-fastapi-backend/module_admin/entity/do/job_do.py b/dash-fastapi-backend/module_admin/entity/do/job_do.py new file mode 100644 index 0000000000000000000000000000000000000000..aef168faca0943a40797944c9c9b1c63e7fc8f11 --- /dev/null +++ b/dash-fastapi-backend/module_admin/entity/do/job_do.py @@ -0,0 +1,47 @@ +from sqlalchemy import Column, Integer, String, DateTime +from config.database import Base +from datetime import datetime + + +class SysJob(Base): + """ + 定时任务调度表 + """ + __tablename__ = 'sys_job' + + job_id = Column(Integer, primary_key=True, autoincrement=True, comment='任务ID') + job_name = Column(String(64, collation='utf8_general_ci'), nullable=False, comment='任务名称') + job_group = Column(String(64, collation='utf8_general_ci'), nullable=False, default='default', comment='任务组名') + job_executor = Column(String(64, collation='utf8_general_ci'), nullable=False, default='default', comment='任务执行器') + invoke_target = Column(String(500, collation='utf8_general_ci'), nullable=False, comment='调用目标字符串') + job_args = Column(String(255, collation='utf8_general_ci'), nullable=True, comment='位置参数') + job_kwargs = Column(String(255, collation='utf8_general_ci'), nullable=True, comment='关键字参数') + cron_expression = Column(String(255, collation='utf8_general_ci'), nullable=True, default='', comment='cron执行表达式') + misfire_policy = Column(String(20, collation='utf8_general_ci'), nullable=True, default='3', comment='计划执行错误策略(1立即执行 2执行一次 3放弃执行)') + concurrent = Column(String(1, collation='utf8_general_ci'), nullable=True, default='1', comment='是否并发执行(0允许 1禁止)') + status = Column(String(1, collation='utf8_general_ci'), nullable=True, default='0', comment='状态(0正常 1暂停)') + create_by = Column(String(64, collation='utf8_general_ci'), nullable=True, default='', comment='创建者') + create_time = Column(DateTime, nullable=True, default=datetime.now(), comment='创建时间') + update_by = Column(String(64, collation='utf8_general_ci'), nullable=True, default='', comment='更新者') + update_time = Column(DateTime, nullable=True, default=datetime.now(), comment='更新时间') + remark = Column(String(500, collation='utf8_general_ci'), nullable=True, default='', comment='备注信息') + + +class SysJobLog(Base): + """ + 定时任务调度日志表 + """ + __tablename__ = 'sys_job_log' + + job_log_id = Column(Integer, primary_key=True, autoincrement=True, comment='任务日志ID') + job_name = Column(String(64, collation='utf8_general_ci'), nullable=False, comment='任务名称') + job_group = Column(String(64, collation='utf8_general_ci'), nullable=False, comment='任务组名') + job_executor = Column(String(64, collation='utf8_general_ci'), nullable=False, default='default', comment='任务执行器') + invoke_target = Column(String(500, collation='utf8_general_ci'), nullable=False, comment='调用目标字符串') + job_args = Column(String(255, collation='utf8_general_ci'), nullable=True, comment='位置参数') + job_kwargs = Column(String(255, collation='utf8_general_ci'), nullable=True, comment='关键字参数') + job_trigger = Column(String(255, collation='utf8_general_ci'), nullable=True, comment='任务触发器') + job_message = Column(String(500, collation='utf8_general_ci'), nullable=True, default='', comment='日志信息') + status = Column(String(1, collation='utf8_general_ci'), nullable=True, default='0', comment='执行状态(0正常 1失败)') + exception_info = Column(String(2000, collation='utf8_general_ci'), nullable=True, default='', comment='异常信息') + create_time = Column(DateTime, nullable=True, default=datetime.now(), comment='创建时间') diff --git a/dash-fastapi-backend/module_admin/entity/do/log_do.py b/dash-fastapi-backend/module_admin/entity/do/log_do.py index 090e408a8994f9175fb774729f5679c64b3dd6fe..19d2b187d8c579777fec80b996a29ab51ec3714a 100644 --- a/dash-fastapi-backend/module_admin/entity/do/log_do.py +++ b/dash-fastapi-backend/module_admin/entity/do/log_do.py @@ -1,5 +1,5 @@ from sqlalchemy import Column, Integer, String, DateTime, Text, BigInteger, Index -from config.database import Base, engine +from config.database import Base from datetime import datetime @@ -50,6 +50,3 @@ class SysOperLog(Base): idx_sys_oper_log_bt = Index('idx_sys_oper_log_bt', business_type) idx_sys_oper_log_s = Index('idx_sys_oper_log_s', status) idx_sys_oper_log_ot = Index('idx_sys_oper_log_ot', oper_time) - - -Base.metadata.create_all(bind=engine) diff --git a/dash-fastapi-backend/module_admin/entity/do/menu_do.py b/dash-fastapi-backend/module_admin/entity/do/menu_do.py index 74438b98a906adfd86fda4120b6377dea4efb6af..8f98be48e0b75542fe209893747cce903506503e 100644 --- a/dash-fastapi-backend/module_admin/entity/do/menu_do.py +++ b/dash-fastapi-backend/module_admin/entity/do/menu_do.py @@ -1,5 +1,5 @@ from sqlalchemy import Column, Integer, String, DateTime -from config.database import Base, engine +from config.database import Base from datetime import datetime @@ -28,6 +28,3 @@ class SysMenu(Base): update_by = Column(String(64), nullable=True, default='', comment='更新者') update_time = Column(DateTime, nullable=True, default=datetime.now(), comment='更新时间') remark = Column(String(500), nullable=True, default='', comment='备注') - - -Base.metadata.create_all(bind=engine) diff --git a/dash-fastapi-backend/module_admin/entity/do/notice_do.py b/dash-fastapi-backend/module_admin/entity/do/notice_do.py new file mode 100644 index 0000000000000000000000000000000000000000..38566584178aaa0a3105e497bc7159ea3935c839 --- /dev/null +++ b/dash-fastapi-backend/module_admin/entity/do/notice_do.py @@ -0,0 +1,21 @@ +from sqlalchemy import Column, Integer, String, DateTime, LargeBinary +from config.database import Base +from datetime import datetime + + +class SysNotice(Base): + """ + 通知公告表 + """ + __tablename__ = 'sys_notice' + + notice_id = Column(Integer, primary_key=True, autoincrement=True, comment='公告ID') + notice_title = Column(String(50, collation='utf8_general_ci'), nullable=False, comment='公告标题') + notice_type = Column(String(1, collation='utf8_general_ci'), nullable=False, comment='公告类型(1通知 2公告)') + notice_content = Column(LargeBinary, comment='公告内容') + status = Column(String(1, collation='utf8_general_ci'), default='0', comment='公告状态(0正常 1关闭)') + create_by = Column(String(64, collation='utf8_general_ci'), default='', comment='创建者') + create_time = Column(DateTime, comment='创建时间', default=datetime.now()) + update_by = Column(String(64, collation='utf8_general_ci'), default='', comment='更新者') + update_time = Column(DateTime, comment='更新时间', default=datetime.now()) + remark = Column(String(255, collation='utf8_general_ci'), comment='备注') diff --git a/dash-fastapi-backend/module_admin/entity/do/post_do.py b/dash-fastapi-backend/module_admin/entity/do/post_do.py index 78a491a8fa486190ec1039c8bad74c801eedcc72..c6b189b6cd9fe1d5adcf6a8e02e30979a85c3cb4 100644 --- a/dash-fastapi-backend/module_admin/entity/do/post_do.py +++ b/dash-fastapi-backend/module_admin/entity/do/post_do.py @@ -1,5 +1,5 @@ from sqlalchemy import Column, Integer, String, DateTime -from config.database import Base, engine +from config.database import Base from datetime import datetime @@ -19,6 +19,3 @@ class SysPost(Base): update_by = Column(String(64), default='', comment='更新者') update_time = Column(DateTime, nullable=True, default=datetime.now(), comment='更新时间') remark = Column(String(500), nullable=True, default='', comment='备注') - - -Base.metadata.create_all(bind=engine) diff --git a/dash-fastapi-backend/module_admin/entity/do/role_do.py b/dash-fastapi-backend/module_admin/entity/do/role_do.py index 68a13dace51aa443008051b482f76556a41ef4cd..db29244e11f24e330683b8e10d992b9c4318593c 100644 --- a/dash-fastapi-backend/module_admin/entity/do/role_do.py +++ b/dash-fastapi-backend/module_admin/entity/do/role_do.py @@ -1,5 +1,5 @@ from sqlalchemy import Column, Integer, String, DateTime -from config.database import Base, engine +from config.database import Base from datetime import datetime @@ -43,6 +43,3 @@ class SysRoleMenu(Base): role_id = Column(Integer, primary_key=True, nullable=False, comment='角色ID') menu_id = Column(Integer, primary_key=True, nullable=False, comment='菜单ID') - - -Base.metadata.create_all(bind=engine) diff --git a/dash-fastapi-backend/module_admin/entity/do/user_do.py b/dash-fastapi-backend/module_admin/entity/do/user_do.py index d11ef9d181d3ce61bced8758409c427565714621..93515472f905e58d79b28ccc3f0aa9ffa24779ed 100644 --- a/dash-fastapi-backend/module_admin/entity/do/user_do.py +++ b/dash-fastapi-backend/module_admin/entity/do/user_do.py @@ -1,5 +1,5 @@ from sqlalchemy import Column, Integer, String, DateTime -from config.database import Base, engine +from config.database import Base from datetime import datetime @@ -48,6 +48,3 @@ class SysUserPost(Base): user_id = Column(Integer, primary_key=True, nullable=False, comment='用户ID') post_id = Column(Integer, primary_key=True, nullable=False, comment='岗位ID') - - -Base.metadata.create_all(bind=engine) diff --git a/dash-fastapi-backend/module_admin/entity/vo/cache_vo.py b/dash-fastapi-backend/module_admin/entity/vo/cache_vo.py new file mode 100644 index 0000000000000000000000000000000000000000..1b2b4a1a7c21c7859f195b11beb36740d61f9952 --- /dev/null +++ b/dash-fastapi-backend/module_admin/entity/vo/cache_vo.py @@ -0,0 +1,11 @@ +from pydantic import BaseModel +from typing import Optional, List + + +class CacheMonitorModel(BaseModel): + """ + 缓存监控信息对应pydantic模型 + """ + command_stats: Optional[List] + db_size: Optional[int] + info: Optional[dict] diff --git a/dash-fastapi-backend/module_admin/entity/vo/config_vo.py b/dash-fastapi-backend/module_admin/entity/vo/config_vo.py new file mode 100644 index 0000000000000000000000000000000000000000..6ad9c95bec38e8aa4c6c8c226679a21cc04cf448 --- /dev/null +++ b/dash-fastapi-backend/module_admin/entity/vo/config_vo.py @@ -0,0 +1,63 @@ +from pydantic import BaseModel +from typing import Union, Optional, List + + +class ConfigModel(BaseModel): + """ + 参数配置表对应pydantic模型 + """ + config_id: Optional[int] + config_name: Optional[str] + config_key: Optional[str] + config_value: Optional[str] + config_type: Optional[str] + create_by: Optional[str] + create_time: Optional[str] + update_by: Optional[str] + update_time: Optional[str] + remark: Optional[str] + + class Config: + orm_mode = True + + +class ConfigQueryModel(ConfigModel): + """ + 参数配置管理不分页查询模型 + """ + create_time_start: Optional[str] + create_time_end: Optional[str] + + +class ConfigPageObject(ConfigQueryModel): + """ + 参数配置管理分页查询模型 + """ + page_num: int + page_size: int + + +class ConfigPageObjectResponse(BaseModel): + """ + 参数配置管理列表分页查询返回模型 + """ + rows: List[Union[ConfigModel, None]] = [] + page_num: int + page_size: int + total: int + has_next: bool + + +class DeleteConfigModel(BaseModel): + """ + 删除参数配置模型 + """ + config_ids: str + + +class CrudConfigResponse(BaseModel): + """ + 操作参数配置响应模型 + """ + is_success: bool + message: str diff --git a/dash-fastapi-backend/module_admin/entity/vo/dept_vo.py b/dash-fastapi-backend/module_admin/entity/vo/dept_vo.py index 2a72eb0eaca2cfe383c9b8488c5dd9d952ae57f5..a2cf22879287f8c1ab65c2ed4fec3516c5fc4c81 100644 --- a/dash-fastapi-backend/module_admin/entity/vo/dept_vo.py +++ b/dash-fastapi-backend/module_admin/entity/vo/dept_vo.py @@ -1,6 +1,6 @@ from pydantic import BaseModel from typing import Union, Optional, List -from module_admin.entity.vo.user_schema import DeptModel +from module_admin.entity.vo.user_vo import DeptModel class DeptPageObject(DeptModel): diff --git a/dash-fastapi-backend/module_admin/entity/vo/dict_vo.py b/dash-fastapi-backend/module_admin/entity/vo/dict_vo.py new file mode 100644 index 0000000000000000000000000000000000000000..6de3d7431dae20c886afa0fad9b08ab916af17cf --- /dev/null +++ b/dash-fastapi-backend/module_admin/entity/vo/dict_vo.py @@ -0,0 +1,111 @@ +from pydantic import BaseModel +from typing import Union, Optional, List + + +class DictTypeModel(BaseModel): + """ + 字典类型表对应pydantic模型 + """ + dict_id: Optional[int] + dict_name: Optional[str] + dict_type: Optional[str] + status: Optional[str] + create_by: Optional[str] + create_time: Optional[str] + update_by: Optional[str] + update_time: Optional[str] + remark: Optional[str] + + class Config: + orm_mode = True + + +class DictDataModel(BaseModel): + """ + 字典数据表对应pydantic模型 + """ + dict_code: Optional[int] + dict_sort: Optional[int] + dict_label: Optional[str] + dict_value: Optional[str] + dict_type: Optional[str] + css_class: Optional[str] + list_class: Optional[str] + is_default: Optional[str] + status: Optional[str] + create_by: Optional[str] + create_time: Optional[str] + update_by: Optional[str] + update_time: Optional[str] + remark: Optional[str] + + class Config: + orm_mode = True + + +class DictTypeQueryModel(DictTypeModel): + """ + 字典类型管理不分页查询模型 + """ + create_time_start: Optional[str] + create_time_end: Optional[str] + + +class DictTypePageObject(DictTypeQueryModel): + """ + 字典类型管理分页查询模型 + """ + page_num: int + page_size: int + + +class DictTypePageObjectResponse(BaseModel): + """ + 字典类型管理列表分页查询返回模型 + """ + rows: List[Union[DictTypeModel, None]] = [] + page_num: int + page_size: int + total: int + has_next: bool + + +class DeleteDictTypeModel(BaseModel): + """ + 删除字典类型模型 + """ + dict_ids: str + + +class DictDataPageObject(DictDataModel): + """ + 字典数据管理分页查询模型 + """ + page_num: int + page_size: int + + +class DictDataPageObjectResponse(BaseModel): + """ + 字典数据管理列表分页查询返回模型 + """ + rows: List[Union[DictDataModel, None]] = [] + page_num: int + page_size: int + total: int + has_next: bool + + +class DeleteDictDataModel(BaseModel): + """ + 删除字典数据模型 + """ + dict_codes: str + + +class CrudDictResponse(BaseModel): + """ + 操作字典响应模型 + """ + is_success: bool + message: str diff --git a/dash-fastapi-backend/module_admin/entity/vo/job_vo.py b/dash-fastapi-backend/module_admin/entity/vo/job_vo.py new file mode 100644 index 0000000000000000000000000000000000000000..0283b1fe0cd3f8cfbd2dd36fdf86216729d4f0ed --- /dev/null +++ b/dash-fastapi-backend/module_admin/entity/vo/job_vo.py @@ -0,0 +1,130 @@ +from pydantic import BaseModel +from typing import Union, Optional, List + + +class JobModel(BaseModel): + """ + 定时任务调度表对应pydantic模型 + """ + job_id: Optional[int] + job_name: Optional[str] + job_group: Optional[str] + job_executor: Optional[str] + invoke_target: Optional[str] + job_args: Optional[str] + job_kwargs: Optional[str] + cron_expression: Optional[str] + misfire_policy: Optional[str] + concurrent: Optional[str] + status: Optional[str] + create_by: Optional[str] + create_time: Optional[str] + update_by: Optional[str] + update_time: Optional[str] + remark: Optional[str] + + class Config: + orm_mode = True + + +class JobLogModel(BaseModel): + """ + 定时任务调度日志表对应pydantic模型 + """ + job_log_id: Optional[int] + job_name: Optional[str] + job_group: Optional[str] + job_executor: Optional[str] + invoke_target: Optional[str] + job_args: Optional[str] + job_kwargs: Optional[str] + job_trigger: Optional[str] + job_message: Optional[str] + status: Optional[str] + exception_info: Optional[str] + create_time: Optional[str] + + class Config: + orm_mode = True + + +class JobPageObject(JobModel): + """ + 定时任务管理分页查询模型 + """ + page_num: int + page_size: int + + +class JobPageObjectResponse(BaseModel): + """ + 定时任务管理列表分页查询返回模型 + """ + rows: List[Union[JobModel, None]] = [] + page_num: int + page_size: int + total: int + has_next: bool + + +class CrudJobResponse(BaseModel): + """ + 操作定时任务及日志响应模型 + """ + is_success: bool + message: str + + +class EditJobModel(JobModel): + """ + 编辑定时任务模型 + """ + type: Optional[str] + + +class DeleteJobModel(BaseModel): + """ + 删除定时任务模型 + """ + job_ids: str + + +class JobLogQueryModel(JobLogModel): + """ + 定时任务日志不分页查询模型 + """ + create_time_start: Optional[str] + create_time_end: Optional[str] + + +class JobLogPageObject(JobLogQueryModel): + """ + 定时任务日志管理分页查询模型 + """ + page_num: int + page_size: int + + +class JobLogPageObjectResponse(BaseModel): + """ + 定时任务日志管理列表分页查询返回模型 + """ + rows: List[Union[JobLogModel, None]] = [] + page_num: int + page_size: int + total: int + has_next: bool + + +class DeleteJobLogModel(BaseModel): + """ + 删除定时任务日志模型 + """ + job_log_ids: str + + +class ClearJobLogModel(BaseModel): + """ + 清除定时任务日志模型 + """ + oper_type: str diff --git a/dash-fastapi-backend/module_admin/entity/vo/log_vo.py b/dash-fastapi-backend/module_admin/entity/vo/log_vo.py new file mode 100644 index 0000000000000000000000000000000000000000..64a999ec1c22b7f7b50589288bb33cf2efceb8ed --- /dev/null +++ b/dash-fastapi-backend/module_admin/entity/vo/log_vo.py @@ -0,0 +1,143 @@ +from pydantic import BaseModel +from typing import Union, Optional, List + + +class OperLogModel(BaseModel): + """ + 操作日志表对应pydantic模型 + """ + oper_id: Optional[int] + title: Optional[str] + business_type: Optional[int] + method: Optional[str] + request_method: Optional[str] + operator_type: Optional[int] + oper_name: Optional[str] + dept_name: Optional[str] + oper_url: Optional[str] + oper_ip: Optional[str] + oper_location: Optional[str] + oper_param: Optional[str] + json_result: Optional[str] + status: Optional[int] + error_msg: Optional[str] + oper_time: Optional[str] + cost_time: Optional[int] + + class Config: + orm_mode = True + + +class LogininforModel(BaseModel): + """ + 登录日志表对应pydantic模型 + """ + info_id: Optional[int] + user_name: Optional[str] + ipaddr: Optional[str] + login_location: Optional[str] + browser: Optional[str] + os: Optional[str] + status: Optional[str] + msg: Optional[str] + login_time: Optional[str] + + class Config: + orm_mode = True + + +class OperLogQueryModel(OperLogModel): + """ + 操作日志管理不分页查询模型 + """ + oper_time_start: Optional[str] + oper_time_end: Optional[str] + + +class OperLogPageObject(OperLogQueryModel): + """ + 操作日志管理分页查询模型 + """ + page_num: int + page_size: int + + +class OperLogPageObjectResponse(BaseModel): + """ + 操作日志列表分页查询返回模型 + """ + rows: List[Union[OperLogModel, None]] = [] + page_num: int + page_size: int + total: int + has_next: bool + + +class DeleteOperLogModel(BaseModel): + """ + 删除操作日志模型 + """ + oper_ids: str + + +class ClearOperLogModel(BaseModel): + """ + 清除操作日志模型 + """ + oper_type: str + + +class LoginLogQueryModel(LogininforModel): + """ + 登录日志管理不分页查询模型 + """ + login_time_start: Optional[str] + login_time_end: Optional[str] + + +class LoginLogPageObject(LoginLogQueryModel): + """ + 登录日志管理分页查询模型 + """ + page_num: int + page_size: int + + +class LoginLogPageObjectResponse(BaseModel): + """ + 登录日志列表分页查询返回模型 + """ + rows: List[Union[LogininforModel, None]] = [] + page_num: int + page_size: int + total: int + has_next: bool + + +class DeleteLoginLogModel(BaseModel): + """ + 删除登录日志模型 + """ + info_ids: str + + +class ClearLoginLogModel(BaseModel): + """ + 清除登录日志模型 + """ + oper_type: str + + +class UnlockUser(BaseModel): + """ + 解锁用户模型 + """ + user_name: str + + +class CrudLogResponse(BaseModel): + """ + 操作各类日志响应模型 + """ + is_success: bool + message: str diff --git a/dash-fastapi-backend/module_admin/entity/vo/login_vo.py b/dash-fastapi-backend/module_admin/entity/vo/login_vo.py index d7b30565b036d3c7b86d66a68cef3e946a4f81fa..528b3b2680362cc73a4f92d72608eccf1b2c2499 100644 --- a/dash-fastapi-backend/module_admin/entity/vo/login_vo.py +++ b/dash-fastapi-backend/module_admin/entity/vo/login_vo.py @@ -5,12 +5,19 @@ from typing import Optional class UserLogin(BaseModel): user_name: str password: str - user_request: Optional[str] = None + captcha: Optional[str] + session_id: Optional[str] + login_info: Optional[dict] + captcha_enabled: Optional[bool] class Token(BaseModel): - token: str - account: str - phone: str - name: str + access_token: str + token_type: str + +class SmsCode(BaseModel): + is_success: Optional[bool] + sms_code: str + session_id: str + message: Optional[str] diff --git a/dash-fastapi-backend/module_admin/entity/vo/notice_vo.py b/dash-fastapi-backend/module_admin/entity/vo/notice_vo.py new file mode 100644 index 0000000000000000000000000000000000000000..7abb8c8ca0ebc071298f16c11d25af0653c38b9e --- /dev/null +++ b/dash-fastapi-backend/module_admin/entity/vo/notice_vo.py @@ -0,0 +1,63 @@ +from pydantic import BaseModel +from typing import Union, Optional, List + + +class NoticeModel(BaseModel): + """ + 通知公告表对应pydantic模型 + """ + notice_id: Optional[int] + notice_title: Optional[str] + notice_type: Optional[str] + notice_content: Optional[bytes] + status: Optional[str] + create_by: Optional[str] + create_time: Optional[str] + update_by: Optional[str] + update_time: Optional[str] + remark: Optional[str] + + class Config: + orm_mode = True + + +class NoticeQueryModel(NoticeModel): + """ + 通知公告管理不分页查询模型 + """ + create_time_start: Optional[str] + create_time_end: Optional[str] + + +class NoticePageObject(NoticeQueryModel): + """ + 通知公告管理分页查询模型 + """ + page_num: int + page_size: int + + +class NoticePageObjectResponse(BaseModel): + """ + 通知公告管理列表分页查询返回模型 + """ + rows: List[Union[NoticeModel, None]] = [] + page_num: int + page_size: int + total: int + has_next: bool + + +class CrudNoticeResponse(BaseModel): + """ + 操作通知公告响应模型 + """ + is_success: bool + message: str + + +class DeleteNoticeModel(BaseModel): + """ + 删除通知公告模型 + """ + notice_ids: str diff --git a/dash-fastapi-backend/module_admin/entity/vo/online_vo.py b/dash-fastapi-backend/module_admin/entity/vo/online_vo.py new file mode 100644 index 0000000000000000000000000000000000000000..eeef4d371d5c26fe88de1b802ccc0c29bdc01d6d --- /dev/null +++ b/dash-fastapi-backend/module_admin/entity/vo/online_vo.py @@ -0,0 +1,50 @@ +from pydantic import BaseModel +from typing import Union, Optional, List + + +class OnlineModel(BaseModel): + """ + 在线用户对应pydantic模型 + """ + session_id: Optional[str] + user_name: Optional[str] + dept_name: Optional[str] + ipaddr: Optional[str] + login_location: Optional[str] + browser: Optional[str] + os: Optional[str] + login_time: Optional[str] + + +class OnlinePageObject(OnlineModel): + """ + 在线用户分页查询模型 + """ + page_num: int + page_size: int + + +class OnlinePageObjectResponse(BaseModel): + """ + 在线用户列表分页查询返回模型 + """ + rows: List[Union[OnlineModel, None]] = [] + page_num: int + page_size: int + total: int + has_next: bool + + +class CrudOnlineResponse(BaseModel): + """ + 操作在线用户响应模型 + """ + is_success: bool + message: str + + +class DeleteOnlineModel(BaseModel): + """ + 强退在线用户模型 + """ + session_ids: str diff --git a/dash-fastapi-backend/module_admin/entity/vo/post_vo.py b/dash-fastapi-backend/module_admin/entity/vo/post_vo.py index c2edd8958821fe11ea03960254bfdcbe3a0f2498..a7a7abecc7990a26c527e0779039eecf8027fb9d 100644 --- a/dash-fastapi-backend/module_admin/entity/vo/post_vo.py +++ b/dash-fastapi-backend/module_admin/entity/vo/post_vo.py @@ -1,14 +1,14 @@ from pydantic import BaseModel -from typing import Union, Optional, List -from module_admin.entity.vo.user_schema import PostModel +from typing import Union, List +from module_admin.entity.vo.user_vo import PostModel class PostPageObject(PostModel): """ 岗位管理分页查询模型 """ - page_num: Optional[int] - page_size: Optional[int] + page_num: int + page_size: int class PostPageObjectResponse(BaseModel): diff --git a/dash-fastapi-backend/module_admin/entity/vo/role_vo.py b/dash-fastapi-backend/module_admin/entity/vo/role_vo.py index 68a7d9e078e7ebd151920c9f64596fc709e6d58e..6532c5815a41a79a478c0d3249e5e09d61bf765c 100644 --- a/dash-fastapi-backend/module_admin/entity/vo/role_vo.py +++ b/dash-fastapi-backend/module_admin/entity/vo/role_vo.py @@ -1,7 +1,7 @@ from pydantic import BaseModel from typing import Union, Optional, List -from module_admin.entity.vo.user_schema import RoleModel -from module_admin.entity.vo.menu_schema import MenuModel +from module_admin.entity.vo.user_vo import RoleModel +from module_admin.entity.vo.menu_vo import MenuModel class RoleMenuModel(BaseModel): @@ -15,14 +15,20 @@ class RoleMenuModel(BaseModel): orm_mode = True -class RolePageObject(RoleModel): +class RoleQueryModel(RoleModel): """ - 角色管理分页查询模型 + 角色管理不分页查询模型 """ create_time_start: Optional[str] create_time_end: Optional[str] - page_num: Optional[int] - page_size: Optional[int] + + +class RolePageObject(RoleQueryModel): + """ + 角色管理分页查询模型 + """ + page_num: int + page_size: int class RolePageObjectResponse(BaseModel): diff --git a/dash-fastapi-backend/module_admin/entity/vo/server_vo.py b/dash-fastapi-backend/module_admin/entity/vo/server_vo.py new file mode 100644 index 0000000000000000000000000000000000000000..36715968510aff174737cf82a97844bc62efb505 --- /dev/null +++ b/dash-fastapi-backend/module_admin/entity/vo/server_vo.py @@ -0,0 +1,53 @@ +from pydantic import BaseModel +from typing import Optional, List + + +class CpuInfo(BaseModel): + cpu_num: Optional[int] + used: Optional[str] + sys: Optional[str] + free: Optional[str] + + +class MemoryInfo(BaseModel): + total: Optional[str] + used: Optional[str] + free: Optional[str] + usage: Optional[str] + + +class SysInfo(BaseModel): + computer_ip: Optional[str] + computer_name: Optional[str] + os_arch: Optional[str] + os_name: Optional[str] + + +class PyInfo(BaseModel): + name: Optional[str] + version: Optional[str] + start_time: Optional[str] + run_time: Optional[str] + home: Optional[str] + project_dir: Optional[str] + + +class SysFiles(BaseModel): + dir_name: Optional[str] + sys_type_name: Optional[str] + disk_name: Optional[str] + total: Optional[str] + used: Optional[str] + free: Optional[str] + usage: Optional[str] + + +class ServerMonitorModel(BaseModel): + """ + 服务监控对应pydantic模型 + """ + cpu: Optional[CpuInfo] + py: Optional[PyInfo] + mem: Optional[MemoryInfo] + sys: Optional[SysInfo] + sys_files: Optional[List[SysFiles]] diff --git a/dash-fastapi-backend/module_admin/entity/vo/user_vo.py b/dash-fastapi-backend/module_admin/entity/vo/user_vo.py index 7c9c7006e2535e49d116dcf7a27bd96f3cac769d..31b52c979cb39b6983bc61ce00efb5e7062169bf 100644 --- a/dash-fastapi-backend/module_admin/entity/vo/user_vo.py +++ b/dash-fastapi-backend/module_admin/entity/vo/user_vo.py @@ -152,39 +152,27 @@ class CurrentUserInfoServiceResponse(UserDetailModel): menu: Union[List, None] -class UserPageObject(UserModel): +class UserQueryModel(UserModel): """ - 用户管理分页查询模型 + 用户管理不分页查询模型 """ create_time_start: Optional[str] create_time_end: Optional[str] + + +class UserPageObject(UserQueryModel): + """ + 用户管理分页查询模型 + """ page_num: int page_size: int -class UserInfoJoinDept(BaseModel): +class UserInfoJoinDept(UserModel): """ 数据库查询用户列表返回模型 """ - user_id: Optional[int] - dept_id: Optional[int] dept_name: Optional[str] - user_name: Optional[str] - nick_name: Optional[str] - user_type: Optional[str] - email: Optional[str] - phonenumber: Optional[str] - sex: Optional[str] - avatar: Optional[str] - status: Optional[str] - del_flag: Optional[str] - login_ip: Optional[str] - login_date: Optional[str] - create_by: Optional[str] - create_time: Optional[str] - update_by: Optional[str] - update_time: Optional[str] - remark: Optional[str] class UserPageObjectResponse(BaseModel): @@ -207,6 +195,15 @@ class AddUserModel(UserModel): type: Optional[str] +class ResetUserModel(UserModel): + """ + 重置用户密码模型 + """ + old_password: Optional[str] + sms_code: Optional[str] + session_id: Optional[str] + + class DeleteUserModel(BaseModel): """ 删除用户模型 diff --git a/dash-fastapi-backend/module_admin/service/cache_service.py b/dash-fastapi-backend/module_admin/service/cache_service.py new file mode 100644 index 0000000000000000000000000000000000000000..08c4254f34b41327ed8e2869a82aeb7e8d6be314 --- /dev/null +++ b/dash-fastapi-backend/module_admin/service/cache_service.py @@ -0,0 +1,24 @@ +from fastapi import Request +from module_admin.entity.vo.cache_vo import * + + +class CacheService: + """ + 缓存监控模块服务层 + """ + + @classmethod + async def get_cache_monitor_statistical_info_services(cls, request: Request): + """ + 获取缓存监控信息service + :param request: Request对象 + :return: 缓存监控信息 + """ + info = await request.app.state.redis.info() + db_size = await request.app.state.redis.dbsize() + command_stats_dict = await request.app.state.redis.info('commandstats') + command_stats = [dict(name=key.split('_')[1], value=str(value.get('calls'))) for key, value in + command_stats_dict.items()] + result = dict(command_stats=command_stats, db_size=db_size, info=info) + + return CacheMonitorModel(**result) diff --git a/dash-fastapi-backend/module_admin/service/captcha_service.py b/dash-fastapi-backend/module_admin/service/captcha_service.py new file mode 100644 index 0000000000000000000000000000000000000000..bcad42c92886d5c44dac19a1a1a190d32c2680ff --- /dev/null +++ b/dash-fastapi-backend/module_admin/service/captcha_service.py @@ -0,0 +1,48 @@ +from PIL import Image, ImageDraw, ImageFont +import io +import os +import random +import base64 + + +class CaptchaService: + """ + 验证码模块服务层 + """ + + @classmethod + def create_captcha_image_service(cls): + # 创建空白图像 + image = Image.new('RGB', (400, 300), color='#EAEAEA') + + # 创建绘图对象 + draw = ImageDraw.Draw(image) + + # 设置字体 + font = ImageFont.truetype(os.path.join(os.path.abspath(os.getcwd()), 'assets', 'font', 'Arial.ttf'), size=100) + + # 生成两个0-9之间的随机整数 + num1 = random.randint(0, 9) + num2 = random.randint(0, 9) + # 从运算符列表中随机选择一个 + operational_character_list = ['+', '-', '*'] + operational_character = random.choice(operational_character_list) + # 根据选择的运算符进行计算 + if operational_character == '+': + result = num1 + num2 + elif operational_character == '-': + result = num1 - num2 + else: + result = num1 * num2 + # 绘制文本 + text = f"{num1} {operational_character} {num2} = ?" + draw.text((10, 120), text, fill='blue', font=font) + + # 将图像数据保存到内存中 + buffer = io.BytesIO() + image.save(buffer, format='PNG') + + # 将图像数据转换为base64字符串 + base64_string = f'data:image/png;base64,{base64.b64encode(buffer.getvalue()).decode()}' + + return [base64_string, result] diff --git a/dash-fastapi-backend/module_admin/service/common_service.py b/dash-fastapi-backend/module_admin/service/common_service.py new file mode 100644 index 0000000000000000000000000000000000000000..790b7f3eadf1f38f751b53b4f983200a1a77eb35 --- /dev/null +++ b/dash-fastapi-backend/module_admin/service/common_service.py @@ -0,0 +1,18 @@ +import os +from fastapi import UploadFile + + +class CommonService: + """ + 通用模块服务层 + """ + + @classmethod + def upload_service(cls, path: str, upload_id: str, file: UploadFile): + + filepath = os.path.join(path, upload_id, f'{file.filename}') + with open(filepath, 'wb') as f: + # 流式写出大型文件,这里的10代表10MB + for chunk in iter(lambda: file.file.read(1024 * 1024 * 10), b''): + f.write(chunk) + diff --git a/dash-fastapi-backend/module_admin/service/config_service.py b/dash-fastapi-backend/module_admin/service/config_service.py new file mode 100644 index 0000000000000000000000000000000000000000..1b3c48ebf34e244359d29dd843dc1c4947641a5e --- /dev/null +++ b/dash-fastapi-backend/module_admin/service/config_service.py @@ -0,0 +1,189 @@ +from fastapi import Request +from module_admin.entity.vo.config_vo import * +from module_admin.dao.config_dao import * +from utils.common_util import export_list2excel + + +class ConfigService: + """ + 参数配置管理模块服务层 + """ + + @classmethod + def get_config_list_services(cls, result_db: Session, query_object: ConfigQueryModel): + """ + 获取参数配置列表信息service + :param result_db: orm对象 + :param query_object: 查询参数对象 + :return: 参数配置列表信息对象 + """ + config_list_result = ConfigDao.get_config_list(result_db, query_object) + + return config_list_result + + @classmethod + async def init_cache_sys_config_services(cls, result_db: Session, redis): + """ + 应用初始化:获取所有参数配置对应的键值对信息并缓存service + :param result_db: orm对象 + :param redis: redis对象 + :return: + """ + # 获取以sys_config:开头的键列表 + keys = await redis.keys('sys_config:*') + # 删除匹配的键 + if keys: + await redis.delete(*keys) + config_all = ConfigDao.get_config_list(result_db, ConfigQueryModel(**dict())) + for config_obj in config_all: + if config_obj.config_type == 'Y': + await redis.set(f'sys_config:{config_obj.config_key}', config_obj.config_value) + + @classmethod + async def query_config_list_from_cache_services(cls, redis, config_key: str): + """ + 从缓存获取参数键名对应值service + :param redis: redis对象 + :param config_key: 参数键名 + :return: 参数键名对应值 + """ + result = await redis.get(f'sys_config:{config_key}') + + return result + + @classmethod + async def add_config_services(cls, request: Request, result_db: Session, page_object: ConfigModel): + """ + 新增参数配置信息service + :param request: Request对象 + :param result_db: orm对象 + :param page_object: 新增参数配置对象 + :return: 新增参数配置校验结果 + """ + config = ConfigDao.get_config_detail_by_info(result_db, ConfigModel(**dict(config_key=page_object.config_key))) + if config: + result = dict(is_success=False, message='参数键名已存在') + else: + try: + ConfigDao.add_config_dao(result_db, page_object) + result_db.commit() + await cls.init_cache_sys_config_services(result_db, request.app.state.redis) + result = dict(is_success=True, message='新增成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + + return CrudConfigResponse(**result) + + @classmethod + async def edit_config_services(cls, request: Request, result_db: Session, page_object: ConfigModel): + """ + 编辑参数配置信息service + :param request: Request对象 + :param result_db: orm对象 + :param page_object: 编辑参数配置对象 + :return: 编辑参数配置校验结果 + """ + edit_config = page_object.dict(exclude_unset=True) + config_info = cls.detail_config_services(result_db, edit_config.get('config_id')) + if config_info: + if config_info.config_key != page_object.config_key or config_info.config_value != page_object.config_value: + config = ConfigDao.get_config_detail_by_info(result_db, page_object) + if config: + result = dict(is_success=False, message='参数配置已存在') + return CrudConfigResponse(**result) + try: + ConfigDao.edit_config_dao(result_db, edit_config) + result_db.commit() + await cls.init_cache_sys_config_services(result_db, request.app.state.redis) + result = dict(is_success=True, message='更新成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='参数配置不存在') + + return CrudConfigResponse(**result) + + @classmethod + async def delete_config_services(cls, request: Request, result_db: Session, page_object: DeleteConfigModel): + """ + 删除参数配置信息service + :param request: Request对象 + :param result_db: orm对象 + :param page_object: 删除参数配置对象 + :return: 删除参数配置校验结果 + """ + if page_object.config_ids.split(','): + config_id_list = page_object.config_ids.split(',') + try: + for config_id in config_id_list: + config_id_dict = dict(config_id=config_id) + ConfigDao.delete_config_dao(result_db, ConfigModel(**config_id_dict)) + result_db.commit() + await cls.init_cache_sys_config_services(result_db, request.app.state.redis) + result = dict(is_success=True, message='删除成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='传入字典数据id为空') + return CrudConfigResponse(**result) + + @classmethod + def detail_config_services(cls, result_db: Session, config_id: int): + """ + 获取参数配置详细信息service + :param result_db: orm对象 + :param config_id: 参数配置id + :return: 参数配置id对应的信息 + """ + config = ConfigDao.get_config_detail_by_id(result_db, config_id=config_id) + + return config + + @staticmethod + def export_config_list_services(config_list: List): + """ + 导出参数配置信息service + :param config_list: 参数配置信息列表 + :return: 参数配置信息对应excel的二进制数据 + """ + # 创建一个映射字典,将英文键映射到中文键 + mapping_dict = { + "config_id": "参数主键", + "config_name": "参数名称", + "config_key": "参数键名", + "config_value": "参数键值", + "config_type": "系统内置", + "create_by": "创建者", + "create_time": "创建时间", + "update_by": "更新者", + "update_time": "更新时间", + "remark": "备注", + } + + data = [ConfigModel(**vars(row)).dict() for row in config_list] + + for item in data: + if item.get('config_type') == 'Y': + item['config_type'] = '是' + else: + item['config_type'] = '否' + new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data] + binary_data = export_list2excel(new_data) + + return binary_data + + @classmethod + async def refresh_sys_config_services(cls, request: Request, result_db: Session): + """ + 刷新字典缓存信息service + :param request: Request对象 + :param result_db: orm对象 + :return: 刷新字典缓存校验结果 + """ + await cls.init_cache_sys_config_services(result_db, request.app.state.redis) + result = dict(is_success=True, message='刷新成功') + + return CrudConfigResponse(**result) diff --git a/dash-fastapi-backend/module_admin/service/dept_service.py b/dash-fastapi-backend/module_admin/service/dept_service.py index c86ad400f567f93a5157b2274ab29f0d9739548c..d2ca651429ccdbe265dfa90ba42b173548376bda 100644 --- a/dash-fastapi-backend/module_admin/service/dept_service.py +++ b/dash-fastapi-backend/module_admin/service/dept_service.py @@ -1,169 +1,206 @@ -from module_admin.entity.vo.dept_schema import * -from module_admin.mapper.dept_crud import * - - -def get_dept_tree_services(result_db: Session, page_object: DeptModel): - """ - 获取部门树信息service - :param result_db: orm对象 - :param page_object: 查询参数对象 - :return: 部门树信息对象 - """ - dept_list_result = get_dept_list_for_tree(result_db, page_object) - dept_tree_result = get_dept_tree(0, DeptTree(dept_tree=dept_list_result)) - - return dept_tree_result - - -def get_dept_tree_for_edit_option_services(result_db: Session, page_object: DeptModel): - """ - 获取部门编辑部门树信息service - :param result_db: orm对象 - :param page_object: 查询参数对象 - :return: 部门树信息对象 - """ - dept_list_result = get_dept_info_for_edit_option(result_db, page_object) - dept_tree_result = get_dept_tree(0, DeptTree(dept_tree=dept_list_result)) - - return dept_tree_result - - -def get_dept_list_services(result_db: Session, page_object: DeptModel): - """ - 获取部门列表信息service - :param result_db: orm对象 - :param page_object: 分页查询参数对象 - :return: 部门列表信息对象 - """ - dept_list_result = get_dept_list(result_db, page_object) - - return dept_list_result - - -def add_dept_services(result_db: Session, page_object: DeptModel): - """ - 新增部门信息service - :param result_db: orm对象 - :param page_object: 新增部门对象 - :return: 新增部门校验结果 - """ - parent_info = get_dept_by_id(result_db, page_object.parent_id) - if parent_info: - page_object.ancestors = f'{parent_info.ancestors},{page_object.parent_id}' - else: - page_object.ancestors = '0' - add_dept_result = add_dept_crud(result_db, page_object) - - return add_dept_result - - -def edit_dept_services(result_db: Session, page_object: DeptModel): - """ - 编辑部门信息service - :param result_db: orm对象 - :param page_object: 编辑部门对象 - :return: 编辑部门校验结果 - """ - parent_info = get_dept_by_id(result_db, page_object.parent_id) - if parent_info: - page_object.ancestors = f'{parent_info.ancestors},{page_object.parent_id}' - else: - page_object.ancestors = '0' - edit_dept = page_object.dict(exclude_unset=True) - edit_dept_result = edit_dept_crud(result_db, edit_dept) - update_children_info(result_db, DeptModel(dept_id=page_object.dept_id, - ancestors=page_object.ancestors, - update_by=page_object.update_by, - update_time=page_object.update_time - ) - ) - - return edit_dept_result - - -def delete_dept_services(result_db: Session, page_object: DeleteDeptModel): - """ - 删除部门信息service - :param result_db: orm对象 - :param page_object: 删除部门对象 - :return: 删除部门校验结果 - """ - if page_object.dept_ids.split(','): - dept_id_list = page_object.dept_ids.split(',') - ancestors = get_dept_all_ancestors(result_db) - for dept_id in dept_id_list: - for ancestor in ancestors: - if dept_id in ancestor[0]: - result = dict(is_success=False, message='该部门下有子部门,不允许删除') - +from module_admin.entity.vo.dept_vo import * +from module_admin.dao.dept_dao import * + + +class DeptService: + """ + 部门管理模块服务层 + """ + + @classmethod + def get_dept_tree_services(cls, result_db: Session, page_object: DeptModel): + """ + 获取部门树信息service + :param result_db: orm对象 + :param page_object: 查询参数对象 + :return: 部门树信息对象 + """ + dept_list_result = DeptDao.get_dept_list_for_tree(result_db, page_object) + dept_tree_result = cls.get_dept_tree(0, DeptTree(dept_tree=dept_list_result)) + + return dept_tree_result + + @classmethod + def get_dept_tree_for_edit_option_services(cls, result_db: Session, page_object: DeptModel): + """ + 获取部门编辑部门树信息service + :param result_db: orm对象 + :param page_object: 查询参数对象 + :return: 部门树信息对象 + """ + dept_list_result = DeptDao.get_dept_info_for_edit_option(result_db, page_object) + dept_tree_result = cls.get_dept_tree(0, DeptTree(dept_tree=dept_list_result)) + + return dept_tree_result + + @classmethod + def get_dept_list_services(cls, result_db: Session, page_object: DeptModel): + """ + 获取部门列表信息service + :param result_db: orm对象 + :param page_object: 分页查询参数对象 + :return: 部门列表信息对象 + """ + dept_list_result = DeptDao.get_dept_list(result_db, page_object) + + return dept_list_result + + @classmethod + def add_dept_services(cls, result_db: Session, page_object: DeptModel): + """ + 新增部门信息service + :param result_db: orm对象 + :param page_object: 新增部门对象 + :return: 新增部门校验结果 + """ + parent_info = DeptDao.get_dept_by_id(result_db, page_object.parent_id) + if parent_info: + page_object.ancestors = f'{parent_info.ancestors},{page_object.parent_id}' + else: + page_object.ancestors = '0' + dept = DeptDao.get_dept_detail_by_info(result_db, DeptModel(**dict(parent_id=page_object.parent_id, dept_name=page_object.dept_name))) + if dept: + result = dict(is_success=False, message='同一部门下不允许存在同名的部门') + else: + try: + DeptDao.add_dept_dao(result_db, page_object) + result_db.commit() + result = dict(is_success=True, message='新增成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + + return CrudDeptResponse(**result) + + @classmethod + def edit_dept_services(cls, result_db: Session, page_object: DeptModel): + """ + 编辑部门信息service + :param result_db: orm对象 + :param page_object: 编辑部门对象 + :return: 编辑部门校验结果 + """ + parent_info = DeptDao.get_dept_by_id(result_db, page_object.parent_id) + if parent_info: + page_object.ancestors = f'{parent_info.ancestors},{page_object.parent_id}' + else: + page_object.ancestors = '0' + edit_dept = page_object.dict(exclude_unset=True) + dept_info = cls.detail_dept_services(result_db, edit_dept.get('dept_id')) + if dept_info: + if dept_info.parent_id != page_object.parent_id or dept_info.dept_name != page_object.dept_name: + dept = DeptDao.get_dept_detail_by_info(result_db, DeptModel( + **dict(parent_id=page_object.parent_id, dept_name=page_object.dept_name))) + if dept: + result = dict(is_success=False, message='同一部门下不允许存在同名的部门') return CrudDeptResponse(**result) - - dept_id_dict = dict(dept_id=dept_id) - delete_dept_crud(result_db, DeptModel(**dept_id_dict)) - result = dict(is_success=True, message='删除成功') - else: - result = dict(is_success=False, message='传入用户id为空') - return CrudDeptResponse(**result) - - -def detail_dept_services(result_db: Session, dept_id: int): - """ - 获取部门详细信息service - :param result_db: orm对象 - :param dept_id: 部门id - :return: 部门id对应的信息 - """ - post = get_dept_detail_by_id(result_db, dept_id=dept_id) - - return post - - -def get_dept_tree(pid: int, permission_list: DeptTree): - """ - 工具方法:根据部门信息生成树形嵌套数据 - :param pid: 部门id - :param permission_list: 部门列表信息 - :return: 部门树形嵌套数据 - """ - dept_list = [] - for permission in permission_list.dept_tree: - if permission.parent_id == pid: - children = get_dept_tree(permission.dept_id, permission_list) - dept_list_data = {} - if children: - dept_list_data['title'] = permission.dept_name - dept_list_data['key'] = str(permission.dept_id) - dept_list_data['value'] = str(permission.dept_id) - dept_list_data['children'] = children - else: - dept_list_data['title'] = permission.dept_name - dept_list_data['key'] = str(permission.dept_id) - dept_list_data['value'] = str(permission.dept_id) - dept_list.append(dept_list_data) - - return dept_list - - -def update_children_info(result_db, page_object): - """ - 工具方法:递归更新子部门信息 - :param result_db: orm对象 - :param page_object: 编辑部门对象 - :return: - """ - children_info = get_children_dept(result_db, page_object.dept_id) - if children_info: - for child in children_info: - child.ancestors = f'{page_object.ancestors},{page_object.dept_id}' - edit_dept_crud(result_db, - dict(dept_id=child.dept_id, - ancestors=child.ancestors, - update_by=page_object.update_by, - update_time=page_object.update_time - ) - ) - update_children_info(result_db, DeptModel(dept_id=child.dept_id, - ancestors=child.ancestors, - update_by=page_object.update_by, - update_time=page_object.update_time - )) + try: + DeptDao.edit_dept_dao(result_db, edit_dept) + cls.update_children_info(result_db, DeptModel(dept_id=page_object.dept_id, + ancestors=page_object.ancestors, + update_by=page_object.update_by, + update_time=page_object.update_time + ) + ) + result_db.commit() + result = dict(is_success=True, message='更新成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='部门不存在') + + return CrudDeptResponse(**result) + + @classmethod + def delete_dept_services(cls, result_db: Session, page_object: DeleteDeptModel): + """ + 删除部门信息service + :param result_db: orm对象 + :param page_object: 删除部门对象 + :return: 删除部门校验结果 + """ + if page_object.dept_ids.split(','): + dept_id_list = page_object.dept_ids.split(',') + ancestors = DeptDao.get_dept_all_ancestors(result_db) + try: + for dept_id in dept_id_list: + for ancestor in ancestors: + if dept_id in ancestor[0]: + result = dict(is_success=False, message='该部门下有子部门,不允许删除') + + return CrudDeptResponse(**result) + + dept_id_dict = dict(dept_id=dept_id) + DeptDao.delete_dept_dao(result_db, DeptModel(**dept_id_dict)) + result_db.commit() + result = dict(is_success=True, message='删除成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='传入部门id为空') + return CrudDeptResponse(**result) + + @classmethod + def detail_dept_services(cls, result_db: Session, dept_id: int): + """ + 获取部门详细信息service + :param result_db: orm对象 + :param dept_id: 部门id + :return: 部门id对应的信息 + """ + dept = DeptDao.get_dept_detail_by_id(result_db, dept_id=dept_id) + + return dept + + @classmethod + def get_dept_tree(cls, pid: int, permission_list: DeptTree): + """ + 工具方法:根据部门信息生成树形嵌套数据 + :param pid: 部门id + :param permission_list: 部门列表信息 + :return: 部门树形嵌套数据 + """ + dept_list = [] + for permission in permission_list.dept_tree: + if permission.parent_id == pid: + children = cls.get_dept_tree(permission.dept_id, permission_list) + dept_list_data = {} + if children: + dept_list_data['title'] = permission.dept_name + dept_list_data['key'] = str(permission.dept_id) + dept_list_data['value'] = str(permission.dept_id) + dept_list_data['children'] = children + else: + dept_list_data['title'] = permission.dept_name + dept_list_data['key'] = str(permission.dept_id) + dept_list_data['value'] = str(permission.dept_id) + dept_list.append(dept_list_data) + + return dept_list + + @classmethod + def update_children_info(cls, result_db, page_object): + """ + 工具方法:递归更新子部门信息 + :param result_db: orm对象 + :param page_object: 编辑部门对象 + :return: + """ + children_info = DeptDao.get_children_dept(result_db, page_object.dept_id) + if children_info: + for child in children_info: + child.ancestors = f'{page_object.ancestors},{page_object.dept_id}' + DeptDao.edit_dept_dao(result_db, + dict(dept_id=child.dept_id, + ancestors=child.ancestors, + update_by=page_object.update_by, + update_time=page_object.update_time + ) + ) + cls.update_children_info(result_db, DeptModel(dept_id=child.dept_id, + ancestors=child.ancestors, + update_by=page_object.update_by, + update_time=page_object.update_time + )) diff --git a/dash-fastapi-backend/module_admin/service/dict_service.py b/dash-fastapi-backend/module_admin/service/dict_service.py new file mode 100644 index 0000000000000000000000000000000000000000..e201a04d251625064d275054750a0564cfedcf70 --- /dev/null +++ b/dash-fastapi-backend/module_admin/service/dict_service.py @@ -0,0 +1,374 @@ +from fastapi import Request +import json +from module_admin.entity.vo.dict_vo import * +from module_admin.dao.dict_dao import * +from utils.common_util import export_list2excel + + +class DictTypeService: + """ + 字典类型管理模块服务层 + """ + + @classmethod + def get_dict_type_list_services(cls, result_db: Session, query_object: DictTypeQueryModel): + """ + 获取字典类型列表信息service + :param result_db: orm对象 + :param query_object: 查询参数对象 + :return: 字典类型列表信息对象 + """ + dict_type_list_result = DictTypeDao.get_dict_type_list(result_db, query_object) + + return dict_type_list_result + + @classmethod + def get_all_dict_type_services(cls, result_db: Session): + """ + 获取字所有典类型列表信息service + :param result_db: orm对象 + :return: 字典类型列表信息对象 + """ + dict_type_list_result = DictTypeDao.get_all_dict_type(result_db) + + return dict_type_list_result + + @classmethod + async def add_dict_type_services(cls, request: Request, result_db: Session, page_object: DictTypeModel): + """ + 新增字典类型信息service + :param request: Request对象 + :param result_db: orm对象 + :param page_object: 新增岗位对象 + :return: 新增字典类型校验结果 + """ + dict_type = DictTypeDao.get_dict_type_detail_by_info(result_db, DictTypeModel(**dict(dict_type=page_object.dict_type))) + if dict_type: + result = dict(is_success=False, message='字典类型已存在') + else: + try: + DictTypeDao.add_dict_type_dao(result_db, page_object) + result_db.commit() + await DictDataService.init_cache_sys_dict_services(result_db, request.app.state.redis) + result = dict(is_success=True, message='新增成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + + return CrudDictResponse(**result) + + @classmethod + async def edit_dict_type_services(cls, request: Request, result_db: Session, page_object: DictTypeModel): + """ + 编辑字典类型信息service + :param request: Request对象 + :param result_db: orm对象 + :param page_object: 编辑字典类型对象 + :return: 编辑字典类型校验结果 + """ + edit_dict_type = page_object.dict(exclude_unset=True) + dict_type_info = cls.detail_dict_type_services(result_db, edit_dict_type.get('dict_id')) + if dict_type_info: + if dict_type_info.dict_type != page_object.dict_type or dict_type_info.dict_name != page_object.dict_name: + dict_type = DictTypeDao.get_dict_type_detail_by_info(result_db, DictTypeModel( + **dict(dict_type=page_object.dict_type))) + if dict_type: + result = dict(is_success=False, message='字典类型已存在') + return CrudDictResponse(**result) + try: + if dict_type_info.dict_type != page_object.dict_type: + query_dict_data = DictDataModel(**(dict(dict_type=dict_type_info.dict_type))) + dict_data_list = DictDataDao.get_dict_data_list(result_db, query_dict_data) + for dict_data in dict_data_list: + edit_dict_data = DictDataModel(**(dict(dict_code=dict_data.dict_code, dict_type=page_object.dict_type, update_by=page_object.update_by))).dict(exclude_unset=True) + DictDataDao.edit_dict_data_dao(result_db, edit_dict_data) + DictTypeDao.edit_dict_type_dao(result_db, edit_dict_type) + result_db.commit() + await DictDataService.init_cache_sys_dict_services(result_db, request.app.state.redis) + result = dict(is_success=True, message='更新成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='字典类型不存在') + + return CrudDictResponse(**result) + + @classmethod + async def delete_dict_type_services(cls, request: Request, result_db: Session, page_object: DeleteDictTypeModel): + """ + 删除字典类型信息service + :param request: Request对象 + :param result_db: orm对象 + :param page_object: 删除字典类型对象 + :return: 删除字典类型校验结果 + """ + if page_object.dict_ids.split(','): + dict_id_list = page_object.dict_ids.split(',') + try: + for dict_id in dict_id_list: + dict_id_dict = dict(dict_id=dict_id) + DictTypeDao.delete_dict_type_dao(result_db, DictTypeModel(**dict_id_dict)) + result_db.commit() + await DictDataService.init_cache_sys_dict_services(result_db, request.app.state.redis) + result = dict(is_success=True, message='删除成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='传入字典类型id为空') + return CrudDictResponse(**result) + + @classmethod + def detail_dict_type_services(cls, result_db: Session, dict_id: int): + """ + 获取字典类型详细信息service + :param result_db: orm对象 + :param dict_id: 字典类型id + :return: 字典类型id对应的信息 + """ + dict_type = DictTypeDao.get_dict_type_detail_by_id(result_db, dict_id=dict_id) + + return dict_type + + @staticmethod + def export_dict_type_list_services(dict_type_list: List): + """ + 导出字典类型信息service + :param dict_type_list: 字典信息列表 + :return: 字典信息对应excel的二进制数据 + """ + # 创建一个映射字典,将英文键映射到中文键 + mapping_dict = { + "dict_id": "字典编号", + "dict_name": "字典名称", + "dict_type": "字典类型", + "status": "状态", + "create_by": "创建者", + "create_time": "创建时间", + "update_by": "更新者", + "update_time": "更新时间", + "remark": "备注", + } + + data = [DictTypeModel(**vars(row)).dict() for row in dict_type_list] + + for item in data: + if item.get('status') == '0': + item['status'] = '正常' + else: + item['status'] = '停用' + new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data] + binary_data = export_list2excel(new_data) + + return binary_data + + @classmethod + async def refresh_sys_dict_services(cls, request: Request, result_db: Session): + """ + 刷新字典缓存信息service + :param request: Request对象 + :param result_db: orm对象 + :return: 刷新字典缓存校验结果 + """ + await DictDataService.init_cache_sys_dict_services(result_db, request.app.state.redis) + result = dict(is_success=True, message='刷新成功') + + return CrudDictResponse(**result) + + +class DictDataService: + """ + 字典数据管理模块服务层 + """ + + @classmethod + def get_dict_data_list_services(cls, result_db: Session, query_object: DictDataModel): + """ + 获取字典数据列表信息service + :param result_db: orm对象 + :param query_object: 查询参数对象 + :return: 字典数据列表信息对象 + """ + dict_data_list_result = DictDataDao.get_dict_data_list(result_db, query_object) + + return dict_data_list_result + + @classmethod + def query_dict_data_list_services(cls, result_db: Session, dict_type: str): + """ + 获取字典数据列表信息service + :param result_db: orm对象 + :param dict_type: 字典类型 + :return: 字典数据列表信息对象 + """ + dict_data_list_result = DictDataDao.query_dict_data_list(result_db, dict_type) + + return dict_data_list_result + + @classmethod + async def init_cache_sys_dict_services(cls, result_db: Session, redis): + """ + 应用初始化:获取所有字典类型对应的字典数据信息并缓存service + :param result_db: orm对象 + :param redis: redis对象 + :return: + """ + # 获取以sys_dict:开头的键列表 + keys = await redis.keys('sys_dict:*') + # 删除匹配的键 + if keys: + await redis.delete(*keys) + dict_type_all = DictTypeDao.get_all_dict_type(result_db) + for dict_type_obj in [item for item in dict_type_all if item.status == '0']: + dict_type = dict_type_obj.dict_type + dict_data_list = DictDataDao.query_dict_data_list(result_db, dict_type) + dict_data = [DictDataModel(**vars(row)).dict() for row in dict_data_list if row] + await redis.set(f'sys_dict:{dict_type}', json.dumps(dict_data, ensure_ascii=False)) + + @classmethod + async def query_dict_data_list_from_cache_services(cls, redis, dict_type: str): + """ + 从缓存获取字典数据列表信息service + :param redis: redis对象 + :param dict_type: 字典类型 + :return: 字典数据列表信息对象 + """ + result = [] + dict_data_list_result = await redis.get(f'sys_dict:{dict_type}') + if dict_data_list_result: + result = json.loads(dict_data_list_result) + + return result + + @classmethod + async def add_dict_data_services(cls, request: Request, result_db: Session, page_object: DictDataModel): + """ + 新增字典数据信息service + :param request: Request对象 + :param result_db: orm对象 + :param page_object: 新增岗位对象 + :return: 新增字典数据校验结果 + """ + dict_data = DictDataDao.get_dict_data_detail_by_info(result_db, page_object) + if dict_data: + result = dict(is_success=False, message='字典数据已存在') + else: + try: + DictDataDao.add_dict_data_dao(result_db, page_object) + result_db.commit() + await cls.init_cache_sys_dict_services(result_db, request.app.state.redis) + result = dict(is_success=True, message='新增成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + + return CrudDictResponse(**result) + + @classmethod + async def edit_dict_data_services(cls, request: Request, result_db: Session, page_object: DictDataModel): + """ + 编辑字典数据信息service + :param request: Request对象 + :param result_db: orm对象 + :param page_object: 编辑字典数据对象 + :return: 编辑字典数据校验结果 + """ + edit_data_type = page_object.dict(exclude_unset=True) + dict_data_info = cls.detail_dict_data_services(result_db, edit_data_type.get('dict_code')) + if dict_data_info: + if dict_data_info.dict_type != page_object.dict_type or dict_data_info.dict_label != page_object.dict_label or dict_data_info.dict_value != page_object.dict_value: + dict_data = DictDataDao.get_dict_data_detail_by_info(result_db, page_object) + if dict_data: + result = dict(is_success=False, message='字典数据已存在') + return CrudDictResponse(**result) + try: + DictDataDao.edit_dict_data_dao(result_db, edit_data_type) + result_db.commit() + await cls.init_cache_sys_dict_services(result_db, request.app.state.redis) + result = dict(is_success=True, message='更新成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='字典数据不存在') + + return CrudDictResponse(**result) + + @classmethod + async def delete_dict_data_services(cls, request: Request, result_db: Session, page_object: DeleteDictDataModel): + """ + 删除字典数据信息service + :param request: Request对象 + :param result_db: orm对象 + :param page_object: 删除字典数据对象 + :return: 删除字典数据校验结果 + """ + if page_object.dict_codes.split(','): + dict_code_list = page_object.dict_codes.split(',') + try: + for dict_code in dict_code_list: + dict_code_dict = dict(dict_code=dict_code) + DictDataDao.delete_dict_data_dao(result_db, DictDataModel(**dict_code_dict)) + result_db.commit() + await cls.init_cache_sys_dict_services(result_db, request.app.state.redis) + result = dict(is_success=True, message='删除成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='传入字典数据id为空') + return CrudDictResponse(**result) + + @classmethod + def detail_dict_data_services(cls, result_db: Session, dict_code: int): + """ + 获取字典数据详细信息service + :param result_db: orm对象 + :param dict_code: 字典数据id + :return: 字典数据id对应的信息 + """ + dict_data = DictDataDao.get_dict_data_detail_by_id(result_db, dict_code=dict_code) + + return dict_data + + @staticmethod + def export_dict_data_list_services(dict_data_list: List): + """ + 导出字典数据信息service + :param dict_data_list: 字典数据信息列表 + :return: 字典数据信息对应excel的二进制数据 + """ + # 创建一个映射字典,将英文键映射到中文键 + mapping_dict = { + "dict_code": "字典编码", + "dict_sort": "字典标签", + "dict_label": "字典键值", + "dict_value": "字典排序", + "dict_type": "字典类型", + "css_class": "样式属性", + "list_class": "表格回显样式", + "is_default": "是否默认", + "status": "状态", + "create_by": "创建者", + "create_time": "创建时间", + "update_by": "更新者", + "update_time": "更新时间", + "remark": "备注", + } + + data = [DictDataModel(**vars(row)).dict() for row in dict_data_list] + + for item in data: + if item.get('status') == '0': + item['status'] = '正常' + else: + item['status'] = '停用' + if item.get('is_default') == 'Y': + item['is_default'] = '是' + else: + item['is_default'] = '否' + new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data] + binary_data = export_list2excel(new_data) + + return binary_data diff --git a/dash-fastapi-backend/module_admin/service/job_log_service.py b/dash-fastapi-backend/module_admin/service/job_log_service.py new file mode 100644 index 0000000000000000000000000000000000000000..f022559886e168f6c8d62d3bc074ac138d04da3b --- /dev/null +++ b/dash-fastapi-backend/module_admin/service/job_log_service.py @@ -0,0 +1,138 @@ +from module_admin.entity.vo.job_vo import * +from module_admin.dao.job_log_dao import * +from module_admin.dao.dict_dao import DictDataDao +from utils.common_util import export_list2excel + + +class JobLogService: + """ + 定时任务日志管理模块服务层 + """ + + @classmethod + def get_job_log_list_services(cls, result_db: Session, query_object: JobLogQueryModel): + """ + 获取定时任务日志列表信息service + :param result_db: orm对象 + :param query_object: 查询参数对象 + :return: 定时任务日志列表信息对象 + """ + job_log_list_result = JobLogDao.get_job_log_list(result_db, query_object) + + return job_log_list_result + + @classmethod + def add_job_log_services(cls, result_db: Session, page_object: JobLogModel): + """ + 新增定时任务日志信息service + :param result_db: orm对象 + :param page_object: 新增定时任务日志对象 + :return: 新增定时任务日志校验结果 + """ + try: + JobLogDao.add_job_log_dao(result_db, page_object) + result_db.commit() + result = dict(is_success=True, message='新增成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + + return CrudJobResponse(**result) + + @classmethod + def delete_job_log_services(cls, result_db: Session, page_object: DeleteJobLogModel): + """ + 删除定时任务日志信息service + :param result_db: orm对象 + :param page_object: 删除定时任务日志对象 + :return: 删除定时任务日志校验结果 + """ + if page_object.job_log_ids.split(','): + job_log_id_list = page_object.job_log_ids.split(',') + try: + for job_log_id in job_log_id_list: + job_log_id_dict = dict(job_log_id=job_log_id) + JobLogDao.delete_job_log_dao(result_db, JobLogModel(**job_log_id_dict)) + result_db.commit() + result = dict(is_success=True, message='删除成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='传入定时任务日志id为空') + return CrudJobResponse(**result) + + @classmethod + def detail_job_log_services(cls, result_db: Session, job_log_id: int): + """ + 获取定时任务日志详细信息service + :param result_db: orm对象 + :param job_log_id: 定时任务日志id + :return: 定时任务日志id对应的信息 + """ + job_log = JobLogDao.get_job_log_detail_by_id(result_db, job_log_id=job_log_id) + + return job_log + + @classmethod + def clear_job_log_services(cls, result_db: Session, page_object: ClearJobLogModel): + """ + 清除定时任务日志信息service + :param result_db: orm对象 + :param page_object: 清除定时任务日志对象 + :return: 清除定时任务日志校验结果 + """ + if page_object.oper_type == 'clear': + try: + JobLogDao.clear_job_log_dao(result_db) + result_db.commit() + result = dict(is_success=True, message='清除成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='清除标识不合法') + + return CrudJobResponse(**result) + + @staticmethod + def export_job_log_list_services(result_db, job_log_list: List): + """ + 导出定时任务日志信息service + :param result_db: orm对象 + :param job_log_list: 定时任务日志信息列表 + :return: 定时任务日志信息对应excel的二进制数据 + """ + # 创建一个映射字典,将英文键映射到中文键 + mapping_dict = { + "job_log_id": "任务日志编码", + "job_name": "任务名称", + "job_group": "任务组名", + "job_executor": "任务执行器", + "invoke_target": "调用目标字符串", + "job_args": "位置参数", + "job_kwargs": "关键字参数", + "job_trigger": "任务触发器", + "job_message": "日志信息", + "status": "执行状态", + "exception_info": "异常信息", + "create_time": "创建时间", + } + + data = [JobLogModel(**vars(row)).dict() for row in job_log_list] + job_group_list = DictDataDao.query_dict_data_list(result_db, dict_type='sys_job_group') + job_group_option = [dict(label=item.dict_label, value=item.dict_value) for item in job_group_list] + job_group_option_dict = {item.get('value'): item for item in job_group_option} + + for item in data: + if item.get('status') == '0': + item['status'] = '正常' + else: + item['status'] = '暂停' + if str(item.get('job_group')) in job_group_option_dict.keys(): + item['job_group'] = job_group_option_dict.get(str(item.get('job_group'))).get('label') + new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in + data] + binary_data = export_list2excel(new_data) + + return binary_data diff --git a/dash-fastapi-backend/module_admin/service/job_service.py b/dash-fastapi-backend/module_admin/service/job_service.py new file mode 100644 index 0000000000000000000000000000000000000000..571c18fa861125c770cbbf1a0f04a10904a55049 --- /dev/null +++ b/dash-fastapi-backend/module_admin/service/job_service.py @@ -0,0 +1,193 @@ +from module_admin.entity.vo.job_vo import * +from module_admin.dao.job_dao import * +from module_admin.service.dict_service import Request, DictDataService +from utils.common_util import export_list2excel +from config.get_scheduler import SchedulerUtil + + +class JobService: + """ + 定时任务管理模块服务层 + """ + + @classmethod + def get_job_list_services(cls, result_db: Session, query_object: JobModel): + """ + 获取定时任务列表信息service + :param result_db: orm对象 + :param query_object: 查询参数对象 + :return: 定时任务列表信息对象 + """ + job_list_result = JobDao.get_job_list(result_db, query_object) + + return job_list_result + + @classmethod + def add_job_services(cls, result_db: Session, page_object: JobModel): + """ + 新增定时任务信息service + :param result_db: orm对象 + :param page_object: 新增定时任务对象 + :return: 新增定时任务校验结果 + """ + job = JobDao.get_job_detail_by_info(result_db, page_object) + if job: + result = dict(is_success=False, message='定时任务已存在') + else: + try: + JobDao.add_job_dao(result_db, page_object) + job_info = JobDao.get_job_detail_by_info(result_db, page_object) + if job_info.status == '0': + SchedulerUtil.add_scheduler_job(job_info=job_info) + result_db.commit() + result = dict(is_success=True, message='新增成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + + return CrudJobResponse(**result) + + @classmethod + def edit_job_services(cls, result_db: Session, page_object: EditJobModel): + """ + 编辑定时任务信息service + :param result_db: orm对象 + :param page_object: 编辑定时任务对象 + :return: 编辑定时任务校验结果 + """ + edit_job = page_object.dict(exclude_unset=True) + if page_object.type == 'status': + del edit_job['type'] + job_info = cls.detail_job_services(result_db, edit_job.get('job_id')) + if job_info: + if page_object.type != 'status' and (job_info.job_name != page_object.job_name or job_info.job_group != page_object.job_group or job_info.invoke_target != page_object.invoke_target or job_info.cron_expression != page_object.cron_expression): + job = JobDao.get_job_detail_by_info(result_db, page_object) + if job: + result = dict(is_success=False, message='定时任务已存在') + return CrudJobResponse(**result) + try: + JobDao.edit_job_dao(result_db, edit_job) + query_job = SchedulerUtil.get_scheduler_job(job_id=edit_job.get('job_id')) + if query_job: + SchedulerUtil.remove_scheduler_job(job_id=edit_job.get('job_id')) + if edit_job.get('status') == '0': + SchedulerUtil.add_scheduler_job(job_info=job_info) + result_db.commit() + result = dict(is_success=True, message='更新成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='定时任务不存在') + + return CrudJobResponse(**result) + + @classmethod + def execute_job_once_services(cls, result_db: Session, page_object: JobModel): + """ + 执行一次定时任务service + :param result_db: orm对象 + :param page_object: 定时任务对象 + :return: 执行一次定时任务结果 + """ + query_job = SchedulerUtil.get_scheduler_job(job_id=page_object.job_id) + if query_job: + SchedulerUtil.remove_scheduler_job(job_id=page_object.job_id) + job_info = cls.detail_job_services(result_db, page_object.job_id) + if job_info: + SchedulerUtil.execute_scheduler_job_once(job_info=job_info) + result = dict(is_success=True, message='执行成功') + else: + result = dict(is_success=False, message='定时任务不存在') + + return CrudJobResponse(**result) + + @classmethod + def delete_job_services(cls, result_db: Session, page_object: DeleteJobModel): + """ + 删除定时任务信息service + :param result_db: orm对象 + :param page_object: 删除定时任务对象 + :return: 删除定时任务校验结果 + """ + if page_object.job_ids.split(','): + job_id_list = page_object.job_ids.split(',') + try: + for job_id in job_id_list: + job_id_dict = dict(job_id=job_id) + JobDao.delete_job_dao(result_db, JobModel(**job_id_dict)) + result_db.commit() + result = dict(is_success=True, message='删除成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='传入定时任务id为空') + return CrudJobResponse(**result) + + @classmethod + def detail_job_services(cls, result_db: Session, job_id: int): + """ + 获取定时任务详细信息service + :param result_db: orm对象 + :param job_id: 定时任务id + :return: 定时任务id对应的信息 + """ + job = JobDao.get_job_detail_by_id(result_db, job_id=job_id) + + return job + + @staticmethod + async def export_job_list_services(request: Request, job_list: List): + """ + 导出定时任务信息service + :param request: Request对象 + :param job_list: 定时任务信息列表 + :return: 定时任务信息对应excel的二进制数据 + """ + # 创建一个映射字典,将英文键映射到中文键 + mapping_dict = { + "job_id": "任务编码", + "job_name": "任务名称", + "job_group": "任务组名", + "job_executor": "任务执行器", + "invoke_target": "调用目标字符串", + "job_args": "位置参数", + "job_kwargs": "关键字参数", + "cron_expression": "cron执行表达式", + "misfire_policy": "计划执行错误策略", + "concurrent": "是否并发执行", + "status": "状态", + "create_by": "创建者", + "create_time": "创建时间", + "update_by": "更新者", + "update_time": "更新时间", + "remark": "备注", + } + + data = [JobModel(**vars(row)).dict() for row in job_list] + job_group_list = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type='sys_job_group') + job_group_option = [dict(label=item.dict_label, value=item.dict_value) for item in job_group_list] + job_group_option_dict = {item.get('value'): item for item in job_group_option} + + for item in data: + if item.get('status') == '0': + item['status'] = '正常' + else: + item['status'] = '暂停' + if str(item.get('job_group')) in job_group_option_dict.keys(): + item['job_group'] = job_group_option_dict.get(str(item.get('job_group'))).get('label') + if item.get('misfire_policy') == '1': + item['misfire_policy'] = '立即执行' + elif item.get('misfire_policy') == '2': + item['misfire_policy'] = '执行一次' + else: + item['misfire_policy'] = '放弃执行' + if item.get('concurrent') == '0': + item['concurrent'] = '允许' + else: + item['concurrent'] = '禁止' + new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data] + binary_data = export_list2excel(new_data) + + return binary_data diff --git a/dash-fastapi-backend/module_admin/service/log_service.py b/dash-fastapi-backend/module_admin/service/log_service.py new file mode 100644 index 0000000000000000000000000000000000000000..6783c54a941eabfe0fc850f204ca048d61b688e1 --- /dev/null +++ b/dash-fastapi-backend/module_admin/service/log_service.py @@ -0,0 +1,264 @@ +from module_admin.entity.vo.log_vo import * +from module_admin.dao.log_dao import * +from module_admin.service.dict_service import Request, DictDataService +from utils.common_util import export_list2excel + + +class OperationLogService: + """ + 操作日志管理模块服务层 + """ + + @classmethod + def get_operation_log_list_services(cls, result_db: Session, query_object: OperLogQueryModel): + """ + 获取操作日志列表信息service + :param result_db: orm对象 + :param query_object: 查询参数对象 + :return: 操作日志列表信息对象 + """ + operation_log_list_result = OperationLogDao.get_operation_log_list(result_db, query_object) + + return operation_log_list_result + + @classmethod + def add_operation_log_services(cls, result_db: Session, page_object: OperLogModel): + """ + 新增操作日志service + :param result_db: orm对象 + :param page_object: 新增操作日志对象 + :return: 新增操作日志校验结果 + """ + try: + OperationLogDao.add_operation_log_dao(result_db, page_object) + result_db.commit() + result = dict(is_success=True, message='新增成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + + return CrudLogResponse(**result) + + @classmethod + def delete_operation_log_services(cls, result_db: Session, page_object: DeleteOperLogModel): + """ + 删除操作日志信息service + :param result_db: orm对象 + :param page_object: 删除操作日志对象 + :return: 删除操作日志校验结果 + """ + if page_object.oper_ids.split(','): + oper_id_list = page_object.oper_ids.split(',') + try: + for oper_id in oper_id_list: + oper_id_dict = dict(oper_id=oper_id) + OperationLogDao.delete_operation_log_dao(result_db, OperLogModel(**oper_id_dict)) + result_db.commit() + result = dict(is_success=True, message='删除成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='传入操作日志id为空') + return CrudLogResponse(**result) + + @classmethod + def clear_operation_log_services(cls, result_db: Session, page_object: ClearOperLogModel): + """ + 清除操作日志信息service + :param result_db: orm对象 + :param page_object: 清除操作日志对象 + :return: 清除操作日志校验结果 + """ + if page_object.oper_type == 'clear': + try: + OperationLogDao.clear_operation_log_dao(result_db) + result_db.commit() + result = dict(is_success=True, message='清除成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='清除标识不合法') + + return CrudLogResponse(**result) + + @classmethod + def detail_operation_log_services(cls, result_db: Session, oper_id: int): + """ + 获取操作日志详细信息service + :param result_db: orm对象 + :param oper_id: 操作日志id + :return: 操作日志id对应的信息 + """ + operation_log = OperationLogDao.get_operation_log_detail_by_id(result_db, oper_id=oper_id) + + return operation_log + + @classmethod + async def export_operation_log_list_services(cls, request: Request, operation_log_list: List): + """ + 导出操作日志信息service + :param request: Request对象 + :param operation_log_list: 操作日志信息列表 + :return: 操作日志信息对应excel的二进制数据 + """ + # 创建一个映射字典,将英文键映射到中文键 + mapping_dict = { + "oper_id": "日志编号", + "title": "系统模块", + "business_type": "操作类型", + "method": "方法名称", + "request_method": "请求方式", + "oper_name": "操作人员", + "dept_name": "部门名称", + "oper_url": "请求URL", + "oper_ip": "操作地址", + "oper_location": "操作地点", + "oper_param": "请求参数", + "json_result": "返回参数", + "status": "操作状态", + "error_msg": "错误消息", + "oper_time": "操作日期", + "cost_time": "消耗时间(毫秒)" + } + + data = [OperLogModel(**vars(row)).dict() for row in operation_log_list] + operation_type_list = await DictDataService.query_dict_data_list_from_cache_services(request.app.state.redis, dict_type='sys_oper_type') + operation_type_option = [dict(label=item.get('dict_label'), value=item.get('dict_value')) for item in operation_type_list] + operation_type_option_dict = {item.get('value'): item for item in operation_type_option} + + for item in data: + if item.get('status') == 0: + item['status'] = '成功' + else: + item['status'] = '失败' + if str(item.get('business_type')) in operation_type_option_dict.keys(): + item['business_type'] = operation_type_option_dict.get(str(item.get('business_type'))).get('label') + + new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data] + binary_data = export_list2excel(new_data) + + return binary_data + + +class LoginLogService: + """ + 登录日志管理模块服务层 + """ + + @classmethod + def get_login_log_list_services(cls, result_db: Session, query_object: LoginLogQueryModel): + """ + 获取登录日志列表信息service + :param result_db: orm对象 + :param query_object: 查询参数对象 + :return: 登录日志列表信息对象 + """ + operation_log_list_result = LoginLogDao.get_login_log_list(result_db, query_object) + + return operation_log_list_result + + @classmethod + def add_login_log_services(cls, result_db: Session, page_object: LogininforModel): + """ + 新增登录日志service + :param result_db: orm对象 + :param page_object: 新增登录日志对象 + :return: 新增登录日志校验结果 + """ + try: + LoginLogDao.add_login_log_dao(result_db, page_object) + result_db.commit() + result = dict(is_success=True, message='新增成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + + return CrudLogResponse(**result) + + @classmethod + def delete_login_log_services(cls, result_db: Session, page_object: DeleteLoginLogModel): + """ + 删除操作日志信息service + :param result_db: orm对象 + :param page_object: 删除操作日志对象 + :return: 删除操作日志校验结果 + """ + if page_object.info_ids.split(','): + info_id_list = page_object.info_ids.split(',') + try: + for info_id in info_id_list: + info_id_dict = dict(info_id=info_id) + LoginLogDao.delete_login_log_dao(result_db, LogininforModel(**info_id_dict)) + result_db.commit() + result = dict(is_success=True, message='删除成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='传入登录日志id为空') + return CrudLogResponse(**result) + + @classmethod + def clear_login_log_services(cls, result_db: Session, page_object: ClearLoginLogModel): + """ + 清除操作日志信息service + :param result_db: orm对象 + :param page_object: 清除操作日志对象 + :return: 清除操作日志校验结果 + """ + if page_object.oper_type == 'clear': + try: + LoginLogDao.clear_login_log_dao(result_db) + result_db.commit() + result = dict(is_success=True, message='清除成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='清除标识不合法') + + return CrudLogResponse(**result) + + @classmethod + async def unlock_user_services(cls, request: Request, unlock_user: UnlockUser): + locked_user = await request.app.state.redis.get(f"account_lock:{unlock_user.user_name}") + if locked_user: + await request.app.state.redis.delete(f"account_lock:{unlock_user.user_name}") + result = dict(is_success=True, message='解锁成功') + else: + result = dict(is_success=False, message='该用户未锁定') + return CrudLogResponse(**result) + + @staticmethod + def export_login_log_list_services(login_log_list: List): + """ + 导出登录日志信息service + :param login_log_list: 登录日志信息列表 + :return: 登录日志信息对应excel的二进制数据 + """ + # 创建一个映射字典,将英文键映射到中文键 + mapping_dict = { + "info_id": "访问编号", + "user_name": "用户名称", + "ipaddr": "登录地址", + "login_location": "登录地点", + "browser": "浏览器", + "os": "操作系统", + "status": "登录状态", + "msg": "操作信息", + "login_time": "登录日期" + } + + data = [LogininforModel(**vars(row)).dict() for row in login_log_list] + + for item in data: + if item.get('status') == '0': + item['status'] = '成功' + else: + item['status'] = '失败' + new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data] + binary_data = export_list2excel(new_data) + + return binary_data diff --git a/dash-fastapi-backend/module_admin/service/login_service.py b/dash-fastapi-backend/module_admin/service/login_service.py index 29deaefcd73b7019dd925f46496f28289f369b47..f6b54a0b0bb1fe283af8f159a03c22bef95e9067 100644 --- a/dash-fastapi-backend/module_admin/service/login_service.py +++ b/dash-fastapi-backend/module_admin/service/login_service.py @@ -1,20 +1,50 @@ -from module_admin.entity.vo.user_schema import * -from module_admin.mapper.login_crud import * -from module_admin.mapper.user_crud import * +from fastapi import Request, Form +from fastapi import Depends +from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from jose import JWTError, jwt -from passlib.context import CryptContext +import random +import uuid +from datetime import timedelta +from typing import Dict +from module_admin.entity.vo.user_vo import * +from module_admin.entity.vo.login_vo import * +from module_admin.dao.login_dao import * +from module_admin.service.user_service import UserService +from module_admin.dao.user_dao import * from config.env import JwtConfig -from module_admin.utils.response_tool import * -from module_admin.utils.log_tool import * -from datetime import datetime, timedelta -from fastapi import Request -from fastapi import Depends, Header +from utils.pwd_util import * +from utils.response_util import * +from utils.message_util import * from config.get_db import get_db -pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") +oauth2_scheme = OAuth2PasswordBearer(tokenUrl="login/loginByAccount") -async def get_current_user(request: Request = Request, token: str = Header(...), result_db: Session = Depends(get_db)): +class CustomOAuth2PasswordRequestForm(OAuth2PasswordRequestForm): + """ + 自定义OAuth2PasswordRequestForm类,增加验证码及会话编号参数 + """ + def __init__( + self, + grant_type: str = Form(default=None, regex="password"), + username: str = Form(), + password: str = Form(), + scope: str = Form(default=""), + client_id: Optional[str] = Form(default=None), + client_secret: Optional[str] = Form(default=None), + captcha: Optional[str] = Form(default=""), + session_id: Optional[str] = Form(default=""), + login_info: Optional[Dict[str, str]] = Form(default=None) + ): + super().__init__(grant_type=grant_type, username=username, password=password, + scope=scope, client_id=client_id, client_secret=client_secret) + self.captcha = captcha + self.session_id = session_id + self.login_info = login_info + + +async def get_current_user(request: Request = Request, token: str = Depends(oauth2_scheme), + result_db: Session = Depends(get_db)): """ 根据token获取当前用户信息 :param request: Request对象 @@ -23,12 +53,15 @@ async def get_current_user(request: Request = Request, token: str = Header(...), :return: 当前用户信息对象 :raise: 令牌异常AuthException """ - if token[:6] != 'Bearer': - logger.warning("用户token不合法") - raise AuthException(data="", message="用户token不合法") + # if token[:6] != 'Bearer': + # logger.warning("用户token不合法") + # raise AuthException(data="", message="用户token不合法") try: - payload = jwt.decode(token[6:], JwtConfig.SECRET_KEY, algorithms=[JwtConfig.ALGORITHM]) + if token.startswith('Bearer'): + token = token.split(' ')[1] + payload = jwt.decode(token, JwtConfig.SECRET_KEY, algorithms=[JwtConfig.ALGORITHM]) user_id: str = payload.get("user_id") + session_id: str = payload.get("session_id") if user_id is None: logger.warning("用户token不合法") raise AuthException(data="", message="用户token不合法") @@ -36,82 +69,151 @@ async def get_current_user(request: Request = Request, token: str = Header(...), except JWTError: logger.warning("用户token已失效,请重新登录") raise AuthException(data="", message="用户token已失效,请重新登录") - user = get_user_by_id(result_db, user_id=token_data.user_id) + user = UserDao.get_user_by_id(result_db, user_id=token_data.user_id) if user is None: logger.warning("用户token不合法") raise AuthException(data="", message="用户token不合法") - redis_token = await request.app.state.redis.get(f'{user.user_basic_info[0].user_id}_access_token') - redis_session = await request.app.state.redis.get(f'{user.user_basic_info[0].user_id}_session_id') - if token[6:] == redis_token: - await request.app.state.redis.set(f'{user.user_basic_info[0].user_id}_access_token', redis_token, - ex=timedelta(minutes=30)) - await request.app.state.redis.set(f'{user.user_basic_info[0].user_id}_session_id', redis_session, - ex=timedelta(minutes=30)) - # user_dept_info = deal_user_dept_info(result_db, DeptInfo(dept_id=user.user_dept_info[0].dept_id, - # dept_name=user.user_dept_info[0].dept_name, - # ancestors=user.user_dept_info[0].ancestors)) - # user_role_info = deal_user_role_info(RoleInfo(role_info=user.user_role_info)) - user_menu_info = deal_user_menu_info(0, MenuList(menu_info=user.user_menu_info)) + redis_token = await request.app.state.redis.get(f'access_token:{session_id}') + # 此方法可实现同一账号同一时间只能登录一次 + # redis_token = await request.app.state.redis.get(f'{user.user_basic_info[0].user_id}_access_token') + # redis_session = await request.app.state.redis.get(f'{user.user_basic_info[0].user_id}_session_id') + if token == redis_token: + await request.app.state.redis.set(f'access_token:{session_id}', redis_token, + ex=timedelta(minutes=JwtConfig.REDIS_TOKEN_EXPIRE_MINUTES)) + # await request.app.state.redis.set(f'{user.user_basic_info[0].user_id}_access_token', redis_token, + # ex=timedelta(minutes=30)) + # await request.app.state.redis.set(f'{user.user_basic_info[0].user_id}_session_id', redis_session, + # ex=timedelta(minutes=30)) return CurrentUserInfoServiceResponse( user=user.user_basic_info[0], dept=user.user_dept_info[0], role=user.user_role_info, post=user.user_post_info, - menu=user_menu_info + menu=user.user_menu_info ) else: logger.warning("用户token已失效,请重新登录") raise AuthException(data="", message="用户token已失效,请重新登录") -async def logout_services(request: Request, current_user: CurrentUserInfoServiceResponse): +async def get_sms_code_services(request: Request, result_db: Session, user: ResetUserModel): """ - 退出登录services + 获取短信验证码service :param request: Request对象 - :param current_user: 用户用户 - :return: 退出登录结果 + :param result_db: orm对象 + :param user: 用户对象 + :return: 短信验证码对象 """ - await request.app.state.redis.delete(f'{current_user.user.user_id}_access_token') - await request.app.state.redis.delete(f'{current_user.user.user_id}_session_id') + redis_sms_result = await request.app.state.redis.get(f"sms_code:{user.session_id}") + if redis_sms_result: + return SmsCode(**dict(is_success=False, sms_code='', session_id='', message='短信验证码仍在有效期内')) + is_user = UserDao.get_user_by_name(result_db, user.user_name) + if is_user: + sms_code = str(random.randint(100000, 999999)) + session_id = str(uuid.uuid4()) + await request.app.state.redis.set(f"sms_code:{session_id}", sms_code, ex=timedelta(minutes=2)) + # 此处模拟调用短信服务 + message_service(sms_code) - return True + return SmsCode(**dict(is_success=True, sms_code=sms_code, session_id=session_id, message='获取成功')) + return SmsCode(**dict(is_success=False, sms_code='', session_id='', message='用户不存在')) -def verify_password(plain_password, hashed_password): + +async def forget_user_services(request: Request, result_db: Session, forget_user: ResetUserModel): """ - 工具方法:校验当前输入的密码与数据库存储的密码是否一致 - :param plain_password: 当前输入的密码 - :param hashed_password: 数据库存储的密码 - :return: 校验结果 + 用户忘记密码services + :param request: Request对象 + :param result_db: orm对象 + :param forget_user: 重置用户对象 + :return: 重置结果 """ - return pwd_context.verify(plain_password, hashed_password) + redis_sms_result = await request.app.state.redis.get(f"sms_code:{forget_user.session_id}") + if forget_user.sms_code == redis_sms_result: + forget_user.password = PwdUtil.get_password_hash(forget_user.password) + forget_user.user_id = UserDao.get_user_by_name(result_db, forget_user.user_name).user_id + edit_result = UserService.reset_user_services(result_db, forget_user) + result = edit_result.dict() + elif not redis_sms_result: + result = dict(is_success=False, message='短信验证码已过期') + else: + await request.app.state.redis.delete(f"sms_code:{forget_user.session_id}") + result = dict(is_success=False, message='短信验证码不正确') + return CrudUserResponse(**result) -def get_password_hash(input_password): + +async def logout_services(request: Request, session_id: str): + """ + 退出登录services + :param request: Request对象 + :param session_id: 会话编号 + :return: 退出登录结果 + """ + await request.app.state.redis.delete(f'access_token:{session_id}') + # await request.app.state.redis.delete(f'{current_user.user.user_id}_access_token') + # await request.app.state.redis.delete(f'{current_user.user.user_id}_session_id') + + return True + + +async def check_login_captcha(request: Request, login_user: UserLogin): """ - 工具方法:对当前输入的密码进行加密 - :param input_password: 输入的密码 - :return: 加密成功的密码 + 校验用户登录验证码 + :param request: Request对象 + :param login_user: 登录用户对象 + :return: 校验结果 """ - return pwd_context.hash(input_password) + captcha_value = await request.app.state.redis.get(f'captcha_codes:{login_user.session_id}') + if not captcha_value: + logger.warning("验证码已失效") + raise LoginException(data="", message="验证码已失效") + if login_user.captcha != str(captcha_value): + logger.warning("验证码错误") + raise LoginException(data="", message="验证码错误") + return True -def authenticate_user(query_db: Session, user_name: str, input_password: str): +async def authenticate_user(request: Request, query_db: Session, login_user: UserLogin): """ 根据用户名密码校验用户登录 + :param request: Request对象 :param query_db: orm对象 - :param user_name: 用户名 - :param input_password: 用户密码 + :param login_user: 登录用户对象 :return: 校验结果 """ - user = login_by_account(query_db, user_name) + account_lock = await request.app.state.redis.get(f"account_lock:{login_user.user_name}") + if login_user.user_name == account_lock: + logger.warning("账号已锁定,请稍后再试") + raise LoginException(data="", message="账号已锁定,请稍后再试") + # 判断是否开启验证码,开启则验证,否则不验证 + if login_user.captcha_enabled: + await check_login_captcha(request, login_user) + user = login_by_account(query_db, login_user.user_name) if not user: - return '用户不存在' - if not verify_password(input_password, user.password): - return '密码错误' - if user.status == '1': - return '用户已停用' + logger.warning("用户不存在") + raise LoginException(data="", message="用户不存在") + if not PwdUtil.verify_password(login_user.password, user[0].password): + cache_password_error_count = await request.app.state.redis.get(f"password_error_count:{login_user.user_name}") + password_error_counted = 0 + if cache_password_error_count: + password_error_counted = cache_password_error_count + password_error_count = int(password_error_counted) + 1 + await request.app.state.redis.set(f"password_error_count:{login_user.user_name}", password_error_count, + ex=timedelta(minutes=10)) + if password_error_count > 5: + await request.app.state.redis.delete(f"password_error_count:{login_user.user_name}") + await request.app.state.redis.set(f"account_lock:{login_user.user_name}", login_user.user_name, + ex=timedelta(minutes=10)) + logger.warning("10分钟内密码已输错超过5次,账号已锁定,请10分钟后再试") + raise LoginException(data="", message="10分钟内密码已输错超过5次,账号已锁定,请10分钟后再试") + logger.warning("密码错误") + raise LoginException(data="", message="密码错误") + if user[0].status == '1': + logger.warning("用户已停用") + raise LoginException(data="", message="用户已停用") + await request.app.state.redis.delete(f"password_error_count:{login_user.user_name}") return user @@ -137,7 +239,7 @@ def deal_user_dept_info(db: Session, dept_info: DeptInfo): dept_ancestors = dept_info.ancestors.split(',') tmp_dept_list = [] for item in dept_ancestors: - dept_obj = get_user_dept_info(db, int(item)) + dept_obj = UserDao.get_user_dept_info(db, int(item)) if dept_obj: tmp_dept_list.append(dept_obj.dept_name) tmp_dept_list.append(tmp_dept_name) diff --git a/dash-fastapi-backend/module_admin/service/menu_service.py b/dash-fastapi-backend/module_admin/service/menu_service.py index f3465ecd6daf4a4c3d4d0bdaf894e4e4a0db1ce7..203495d32d9203470046f5381f782333330894d3 100644 --- a/dash-fastapi-backend/module_admin/service/menu_service.py +++ b/dash-fastapi-backend/module_admin/service/menu_service.py @@ -1,128 +1,170 @@ -from module_admin.entity.vo.menu_schema import * -from module_admin.mapper.menu_crud import * - - -def get_menu_tree_services(result_db: Session, page_object: MenuTreeModel): - """ - 获取菜单树信息service - :param result_db: orm对象 - :param page_object: 查询参数对象 - :return: 菜单树信息对象 - """ - menu_tree_option = [] - menu_list_result = get_menu_list_for_tree(result_db, MenuModel(**page_object.dict())) - menu_tree_result = get_menu_tree(0, MenuTree(menu_tree=menu_list_result)) - if page_object.type != 'role': +from module_admin.entity.vo.menu_vo import * +from module_admin.dao.menu_dao import * +from module_admin.entity.vo.user_vo import CurrentUserInfoServiceResponse + + +class MenuService: + """ + 菜单管理模块服务层 + """ + + @classmethod + def get_menu_tree_services(cls, result_db: Session, page_object: MenuTreeModel, current_user: Optional[CurrentUserInfoServiceResponse] = None): + """ + 获取菜单树信息service + :param result_db: orm对象 + :param page_object: 查询参数对象 + :param current_user: 当前用户对象 + :return: 菜单树信息对象 + """ + menu_tree_option = [] + menu_list_result = MenuDao.get_menu_list_for_tree(result_db, MenuModel(**page_object.dict()), current_user.user.user_id, current_user.role) + menu_tree_result = cls.get_menu_tree(0, MenuTree(menu_tree=menu_list_result)) + if page_object.type != 'role': + menu_tree_option.append(dict(title='主类目', value='0', key='0', children=menu_tree_result)) + else: + menu_tree_option = [menu_tree_result, menu_list_result] + + return menu_tree_option + + @classmethod + def get_menu_tree_for_edit_option_services(cls, result_db: Session, page_object: MenuModel, current_user: Optional[CurrentUserInfoServiceResponse] = None): + """ + 获取菜单编辑菜单树信息service + :param result_db: orm对象 + :param page_object: 查询参数对象 + :param current_user: 当前用户 + :return: 菜单树信息对象 + """ + menu_tree_option = [] + menu_list_result = MenuDao.get_menu_info_for_edit_option(result_db, page_object, current_user.user.user_id, current_user.role) + menu_tree_result = cls.get_menu_tree(0, MenuTree(menu_tree=menu_list_result)) menu_tree_option.append(dict(title='主类目', value='0', key='0', children=menu_tree_result)) - else: - menu_tree_option = [menu_tree_result, menu_list_result] - - return menu_tree_option - - -def get_menu_tree_for_edit_option_services(result_db: Session, page_object: MenuModel): - """ - 获取菜单编辑菜单树信息service - :param result_db: orm对象 - :param page_object: 查询参数对象 - :return: 菜单树信息对象 - """ - menu_tree_option = [] - menu_list_result = get_menu_info_for_edit_option(result_db, page_object) - menu_tree_result = get_menu_tree(0, MenuTree(menu_tree=menu_list_result)) - menu_tree_option.append(dict(title='主类目', value='0', key='0', children=menu_tree_result)) - return menu_tree_option - - -def get_menu_list_services(result_db: Session, page_object: MenuModel): - """ - 获取菜单列表信息service - :param result_db: orm对象 - :param page_object: 分页查询参数对象 - :return: 菜单列表信息对象 - """ - menu_list_result = get_menu_list(result_db, page_object) - - return menu_list_result - - -def add_menu_services(result_db: Session, page_object: MenuModel): - """ - 新增菜单信息service - :param result_db: orm对象 - :param page_object: 新增菜单对象 - :return: 新增菜单校验结果 - """ - add_menu_result = add_menu_crud(result_db, page_object) - - return add_menu_result - - -def edit_menu_services(result_db: Session, page_object: MenuModel): - """ - 编辑菜单信息service - :param result_db: orm对象 - :param page_object: 编辑部门对象 - :return: 编辑菜单校验结果 - """ - edit_menu = page_object.dict(exclude_unset=True) - edit_menu_result = edit_menu_crud(result_db, edit_menu) - - return edit_menu_result - - -def delete_menu_services(result_db: Session, page_object: DeleteMenuModel): - """ - 删除菜单信息service - :param result_db: orm对象 - :param page_object: 删除菜单对象 - :return: 删除菜单校验结果 - """ - if page_object.menu_ids.split(','): - menu_id_list = page_object.menu_ids.split(',') - for menu_id in menu_id_list: - menu_id_dict = dict(menu_id=menu_id) - delete_menu_crud(result_db, MenuModel(**menu_id_dict)) - result = dict(is_success=True, message='删除成功') - else: - result = dict(is_success=False, message='传入用户id为空') - return CrudMenuResponse(**result) - - -def detail_menu_services(result_db: Session, menu_id: int): - """ - 获取菜单详细信息service - :param result_db: orm对象 - :param menu_id: 菜单id - :return: 菜单id对应的信息 - """ - menu = get_menu_detail_by_id(result_db, menu_id=menu_id) - - return menu - - -def get_menu_tree(pid: int, permission_list: MenuTree): - """ - 工具方法:根据菜单信息生成树形嵌套数据 - :param pid: 菜单id - :param permission_list: 菜单列表信息 - :return: 菜单树形嵌套数据 - """ - menu_list = [] - for permission in permission_list.menu_tree: - if permission.parent_id == pid: - children = get_menu_tree(permission.menu_id, permission_list) - menu_list_data = {} - if children: - menu_list_data['title'] = permission.menu_name - menu_list_data['key'] = str(permission.menu_id) - menu_list_data['value'] = str(permission.menu_id) - menu_list_data['children'] = children - else: - menu_list_data['title'] = permission.menu_name - menu_list_data['key'] = str(permission.menu_id) - menu_list_data['value'] = str(permission.menu_id) - menu_list.append(menu_list_data) - - return menu_list + return menu_tree_option + + @classmethod + def get_menu_list_services(cls, result_db: Session, page_object: MenuModel, current_user: Optional[CurrentUserInfoServiceResponse] = None): + """ + 获取菜单列表信息service + :param result_db: orm对象 + :param page_object: 分页查询参数对象 + :param current_user: 当前用户对象 + :return: 菜单列表信息对象 + """ + menu_list_result = MenuDao.get_menu_list(result_db, page_object, current_user.user.user_id, current_user.role) + + return menu_list_result + + @classmethod + def add_menu_services(cls, result_db: Session, page_object: MenuModel): + """ + 新增菜单信息service + :param result_db: orm对象 + :param page_object: 新增菜单对象 + :return: 新增菜单校验结果 + """ + menu = MenuDao.get_menu_detail_by_info(result_db, MenuModel( + **dict(parent_id=page_object.parent_id, menu_name=page_object.menu_name, menu_type=page_object.menu_type))) + if menu: + result = dict(is_success=False, message='同一目录下不允许存在同名同类型的菜单') + else: + try: + MenuDao.add_menu_dao(result_db, page_object) + result_db.commit() + result = dict(is_success=True, message='新增成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + + return CrudMenuResponse(**result) + + @classmethod + def edit_menu_services(cls, result_db: Session, page_object: MenuModel): + """ + 编辑菜单信息service + :param result_db: orm对象 + :param page_object: 编辑部门对象 + :return: 编辑菜单校验结果 + """ + edit_menu = page_object.dict(exclude_unset=True) + menu_info = cls.detail_menu_services(result_db, edit_menu.get('menu_id')) + if menu_info: + if menu_info.parent_id != page_object.parent_id or menu_info.menu_name != page_object.menu_name or menu_info.menu_type != page_object.menu_type: + menu = MenuDao.get_menu_detail_by_info(result_db, MenuModel( + **dict(parent_id=page_object.parent_id, menu_name=page_object.menu_name, menu_type=page_object.menu_type))) + if menu: + result = dict(is_success=False, message='同一目录下不允许存在同名同类型的菜单') + return CrudMenuResponse(**result) + try: + MenuDao.edit_menu_dao(result_db, edit_menu) + result_db.commit() + result = dict(is_success=True, message='更新成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='菜单不存在') + + return CrudMenuResponse(**result) + + @classmethod + def delete_menu_services(cls, result_db: Session, page_object: DeleteMenuModel): + """ + 删除菜单信息service + :param result_db: orm对象 + :param page_object: 删除菜单对象 + :return: 删除菜单校验结果 + """ + if page_object.menu_ids.split(','): + menu_id_list = page_object.menu_ids.split(',') + try: + for menu_id in menu_id_list: + menu_id_dict = dict(menu_id=menu_id) + MenuDao.delete_menu_dao(result_db, MenuModel(**menu_id_dict)) + result_db.commit() + result = dict(is_success=True, message='删除成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='传入菜单id为空') + return CrudMenuResponse(**result) + + @classmethod + def detail_menu_services(cls, result_db: Session, menu_id: int): + """ + 获取菜单详细信息service + :param result_db: orm对象 + :param menu_id: 菜单id + :return: 菜单id对应的信息 + """ + menu = MenuDao.get_menu_detail_by_id(result_db, menu_id=menu_id) + + return menu + + @classmethod + def get_menu_tree(cls, pid: int, permission_list: MenuTree): + """ + 工具方法:根据菜单信息生成树形嵌套数据 + :param pid: 菜单id + :param permission_list: 菜单列表信息 + :return: 菜单树形嵌套数据 + """ + menu_list = [] + for permission in permission_list.menu_tree: + if permission.parent_id == pid: + children = cls.get_menu_tree(permission.menu_id, permission_list) + menu_list_data = {} + if children: + menu_list_data['title'] = permission.menu_name + menu_list_data['key'] = str(permission.menu_id) + menu_list_data['value'] = str(permission.menu_id) + menu_list_data['children'] = children + else: + menu_list_data['title'] = permission.menu_name + menu_list_data['key'] = str(permission.menu_id) + menu_list_data['value'] = str(permission.menu_id) + menu_list.append(menu_list_data) + + return menu_list diff --git a/dash-fastapi-backend/module_admin/service/notice_service.py b/dash-fastapi-backend/module_admin/service/notice_service.py new file mode 100644 index 0000000000000000000000000000000000000000..a96c9a984e5dd7654d844dbbe798f4a1b75003a6 --- /dev/null +++ b/dash-fastapi-backend/module_admin/service/notice_service.py @@ -0,0 +1,105 @@ +from module_admin.entity.vo.notice_vo import * +from module_admin.dao.notice_dao import * + + +class NoticeService: + """ + 通知公告管理模块服务层 + """ + + @classmethod + def get_notice_list_services(cls, result_db: Session, query_object: NoticeQueryModel): + """ + 获取通知公告列表信息service + :param result_db: orm对象 + :param query_object: 查询参数对象 + :return: 通知公告列表信息对象 + """ + notice_list_result = NoticeDao.get_notice_list(result_db, query_object) + + return notice_list_result + + @classmethod + def add_notice_services(cls, result_db: Session, page_object: NoticeModel): + """ + 新增通知公告信息service + :param result_db: orm对象 + :param page_object: 新增通知公告对象 + :return: 新增通知公告校验结果 + """ + notice = NoticeDao.get_notice_detail_by_info(result_db, page_object) + if notice: + result = dict(is_success=False, message='通知公告已存在') + else: + try: + NoticeDao.add_notice_dao(result_db, page_object) + result_db.commit() + result = dict(is_success=True, message='新增成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + + return CrudNoticeResponse(**result) + + @classmethod + def edit_notice_services(cls, result_db: Session, page_object: NoticeModel): + """ + 编辑通知公告信息service + :param result_db: orm对象 + :param page_object: 编辑通知公告对象 + :return: 编辑通知公告校验结果 + """ + edit_notice = page_object.dict(exclude_unset=True) + notice_info = cls.detail_notice_services(result_db, edit_notice.get('notice_id')) + if notice_info: + if notice_info.notice_title != page_object.notice_title or notice_info.notice_type != page_object.notice_type or notice_info.notice_content != page_object.notice_content: + notice = NoticeDao.get_notice_detail_by_info(result_db, page_object) + if notice: + result = dict(is_success=False, message='通知公告已存在') + return CrudNoticeResponse(**result) + try: + NoticeDao.edit_notice_dao(result_db, edit_notice) + result_db.commit() + result = dict(is_success=True, message='更新成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='通知公告不存在') + + return CrudNoticeResponse(**result) + + @classmethod + def delete_notice_services(cls, result_db: Session, page_object: DeleteNoticeModel): + """ + 删除通知公告信息service + :param result_db: orm对象 + :param page_object: 删除通知公告对象 + :return: 删除通知公告校验结果 + """ + if page_object.notice_ids.split(','): + notice_id_list = page_object.notice_ids.split(',') + try: + for notice_id in notice_id_list: + notice_id_dict = dict(notice_id=notice_id) + NoticeDao.delete_notice_dao(result_db, NoticeModel(**notice_id_dict)) + result_db.commit() + result = dict(is_success=True, message='删除成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='传入通知公告id为空') + return CrudNoticeResponse(**result) + + @classmethod + def detail_notice_services(cls, result_db: Session, notice_id: int): + """ + 获取通知公告详细信息service + :param result_db: orm对象 + :param notice_id: 通知公告id + :return: 通知公告id对应的信息 + """ + notice = NoticeDao.get_notice_detail_by_id(result_db, notice_id=notice_id) + + return notice diff --git a/dash-fastapi-backend/module_admin/service/online_service.py b/dash-fastapi-backend/module_admin/service/online_service.py new file mode 100644 index 0000000000000000000000000000000000000000..902acdffabd5c2d5fafb333857e744d8219fdfa8 --- /dev/null +++ b/dash-fastapi-backend/module_admin/service/online_service.py @@ -0,0 +1,69 @@ +from fastapi import Request +from jose import jwt +from config.env import JwtConfig +from module_admin.entity.vo.online_vo import * + + +class OnlineService: + """ + 在线用户管理模块服务层 + """ + + @classmethod + async def get_online_list_services(cls, request: Request, query_object: OnlinePageObject): + """ + 获取在线用户表信息service + :param request: Request对象 + :param query_object: 查询参数对象 + :return: 在线用户列表信息 + """ + access_token_keys = await request.app.state.redis.keys('access_token*') + if not access_token_keys: + access_token_keys = [] + access_token_values_list = [await request.app.state.redis.get(key) for key in access_token_keys] + online_info_list = [] + for item in access_token_values_list: + payload = jwt.decode(item, JwtConfig.SECRET_KEY, algorithms=[JwtConfig.ALGORITHM]) + online_dict = dict( + session_id=payload.get('session_id'), + user_name=payload.get('user_name'), + dept_name=payload.get('dept_name'), + ipaddr=payload.get('login_info').get('ipaddr'), + login_location=payload.get('login_info').get('login_location'), + browser=payload.get('login_info').get('browser'), + os=payload.get('login_info').get('os'), + login_time=payload.get('login_info').get('login_time') + ) + if query_object.user_name and not query_object.ipaddr: + if query_object.user_name == payload.get('user_name'): + online_info_list = [online_dict] + break + elif not query_object.user_name and query_object.ipaddr: + if query_object.ipaddr == payload.get('ipaddr'): + online_info_list = [online_dict] + break + elif query_object.user_name and query_object.ipaddr: + if query_object.user_name == payload.get('user_name') and query_object.ipaddr == payload.get('ipaddr'): + online_info_list = [online_dict] + break + else: + online_info_list.append(online_dict) + + return online_info_list + + @classmethod + async def delete_online_services(cls, request: Request, page_object: DeleteOnlineModel): + """ + 强退在线用户信息service + :param request: Request对象 + :param page_object: 强退在线用户对象 + :return: 强退在线用户校验结果 + """ + if page_object.session_ids.split(','): + session_id_list = page_object.session_ids.split(',') + for session_id in session_id_list: + await request.app.state.redis.delete(f'access_token:{session_id}') + result = dict(is_success=True, message='强退成功') + else: + result = dict(is_success=False, message='传入session_id为空') + return CrudOnlineResponse(**result) diff --git a/dash-fastapi-backend/module_admin/service/post_service.py b/dash-fastapi-backend/module_admin/service/post_service.py index 6151ed89c0343100667c5b4ffabb1c554209c7a9..16e954fb24f908688d0672f1232e8331fe79ec9c 100644 --- a/dash-fastapi-backend/module_admin/service/post_service.py +++ b/dash-fastapi-backend/module_admin/service/post_service.py @@ -1,80 +1,150 @@ -from module_admin.entity.vo.post_schema import * -from module_admin.mapper.post_crud import * +from module_admin.entity.vo.post_vo import * +from module_admin.dao.post_dao import * +from utils.common_util import export_list2excel -def get_post_select_option_services(result_db: Session): +class PostService: """ - 获取岗位列表不分页信息service - :param result_db: orm对象 - :return: 岗位列表不分页信息对象 + 岗位管理模块服务层 """ - post_list_result = get_post_select_option_crud(result_db) - return post_list_result - - -def get_post_list_services(result_db: Session, page_object: PostPageObject): - """ - 获取岗位列表信息service - :param result_db: orm对象 - :param page_object: 分页查询参数对象 - :return: 岗位列表信息对象 - """ - post_list_result = get_post_list(result_db, page_object) - - return post_list_result - - -def add_post_services(result_db: Session, page_object: PostModel): - """ - 新增岗位信息service - :param result_db: orm对象 - :param page_object: 新增岗位对象 - :return: 新增岗位校验结果 - """ - add_post_result = add_post_crud(result_db, page_object) - - return add_post_result - - -def edit_post_services(result_db: Session, page_object: PostModel): - """ - 编辑岗位信息service - :param result_db: orm对象 - :param page_object: 编辑岗位对象 - :return: 编辑岗位校验结果 - """ - edit_post = page_object.dict(exclude_unset=True) - edit_post_result = edit_post_crud(result_db, edit_post) - - return edit_post_result - - -def delete_post_services(result_db: Session, page_object: DeletePostModel): - """ - 删除岗位信息service - :param result_db: orm对象 - :param page_object: 删除岗位对象 - :return: 删除岗位校验结果 - """ - if page_object.post_ids.split(','): - post_id_list = page_object.post_ids.split(',') - for post_id in post_id_list: - post_id_dict = dict(post_id=post_id) - delete_post_crud(result_db, PostModel(**post_id_dict)) - result = dict(is_success=True, message='删除成功') - else: - result = dict(is_success=False, message='传入用户id为空') - return CrudPostResponse(**result) - - -def detail_post_services(result_db: Session, post_id: int): - """ - 获取岗位详细信息service - :param result_db: orm对象 - :param post_id: 岗位id - :return: 岗位id对应的信息 - """ - post = get_post_detail_by_id(result_db, post_id=post_id) - - return post + @classmethod + def get_post_select_option_services(cls, result_db: Session): + """ + 获取岗位列表不分页信息service + :param result_db: orm对象 + :return: 岗位列表不分页信息对象 + """ + post_list_result = PostDao.get_post_select_option_dao(result_db) + + return post_list_result + + @classmethod + def get_post_list_services(cls, result_db: Session, query_object: PostModel): + """ + 获取岗位列表信息service + :param result_db: orm对象 + :param query_object: 查询参数对象 + :return: 岗位列表信息对象 + """ + post_list_result = PostDao.get_post_list(result_db, query_object) + + return post_list_result + + @classmethod + def add_post_services(cls, result_db: Session, page_object: PostModel): + """ + 新增岗位信息service + :param result_db: orm对象 + :param page_object: 新增岗位对象 + :return: 新增岗位校验结果 + """ + post = PostDao.get_post_detail_by_info(result_db, PostModel(**dict(post_name=page_object.post_name))) + if post: + result = dict(is_success=False, message='岗位名称已存在') + else: + try: + PostDao.add_post_dao(result_db, page_object) + result_db.commit() + result = dict(is_success=True, message='新增成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + + return CrudPostResponse(**result) + + @classmethod + def edit_post_services(cls, result_db: Session, page_object: PostModel): + """ + 编辑岗位信息service + :param result_db: orm对象 + :param page_object: 编辑岗位对象 + :return: 编辑岗位校验结果 + """ + edit_post = page_object.dict(exclude_unset=True) + post_info = cls.detail_post_services(result_db, edit_post.get('post_id')) + if post_info: + if post_info.post_name != page_object.post_name: + post = PostDao.get_post_detail_by_info(result_db, PostModel(**dict(post_name=page_object.post_name))) + if post: + result = dict(is_success=False, message='岗位名称已存在') + return CrudPostResponse(**result) + try: + PostDao.edit_post_dao(result_db, edit_post) + result_db.commit() + result = dict(is_success=True, message='更新成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='岗位不存在') + + return CrudPostResponse(**result) + + @classmethod + def delete_post_services(cls, result_db: Session, page_object: DeletePostModel): + """ + 删除岗位信息service + :param result_db: orm对象 + :param page_object: 删除岗位对象 + :return: 删除岗位校验结果 + """ + if page_object.post_ids.split(','): + post_id_list = page_object.post_ids.split(',') + try: + for post_id in post_id_list: + post_id_dict = dict(post_id=post_id) + PostDao.delete_post_dao(result_db, PostModel(**post_id_dict)) + result_db.commit() + result = dict(is_success=True, message='删除成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='传入岗位id为空') + return CrudPostResponse(**result) + + @classmethod + def detail_post_services(cls, result_db: Session, post_id: int): + """ + 获取岗位详细信息service + :param result_db: orm对象 + :param post_id: 岗位id + :return: 岗位id对应的信息 + """ + post = PostDao.get_post_detail_by_id(result_db, post_id=post_id) + + return post + + @staticmethod + def export_post_list_services(post_list: List): + """ + 导出岗位信息service + :param post_list: 岗位信息列表 + :return: 岗位信息对应excel的二进制数据 + """ + # 创建一个映射字典,将英文键映射到中文键 + mapping_dict = { + "post_id": "岗位编号", + "post_code": "岗位编码", + "post_name": "岗位名称", + "post_sort": "显示顺序", + "status": "状态", + "create_by": "创建者", + "create_time": "创建时间", + "update_by": "更新者", + "update_time": "更新时间", + "remark": "备注", + } + + data = [PostModel(**vars(row)).dict() for row in post_list] + + for item in data: + if item.get('status') == '0': + item['status'] = '正常' + else: + item['status'] = '停用' + new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data] + binary_data = export_list2excel(new_data) + + return binary_data diff --git a/dash-fastapi-backend/module_admin/service/role_service.py b/dash-fastapi-backend/module_admin/service/role_service.py index ff0b1e9c9058085a2adba8a0a4ce0cee46e1ee91..06a98677d6d8b9d64f7d4f08a9d2e61d7648f583 100644 --- a/dash-fastapi-backend/module_admin/service/role_service.py +++ b/dash-fastapi-backend/module_admin/service/role_service.py @@ -1,101 +1,170 @@ -from module_admin.entity.vo.role_schema import * -from module_admin.mapper.role_crud import * +from module_admin.entity.vo.role_vo import * +from module_admin.dao.role_dao import * +from utils.common_util import export_list2excel -def get_role_select_option_services(result_db: Session): +class RoleService: """ - 获取角色列表不分页信息service - :param result_db: orm对象 - :return: 角色列表不分页信息对象 + 角色管理模块服务层 """ - role_list_result = get_role_select_option_crud(result_db) - return role_list_result - - -def get_role_list_services(result_db: Session, page_object: RolePageObject): - """ - 获取角色列表信息service - :param result_db: orm对象 - :param page_object: 分页查询参数对象 - :return: 角色列表信息对象 - """ - role_list_result = get_role_list(result_db, page_object) - - return role_list_result - - -def add_role_services(result_db: Session, page_object: AddRoleModel): - """ - 新增角色信息service - :param result_db: orm对象 - :param page_object: 新增角色对象 - :return: 新增角色校验结果 - """ - add_role = RoleModel(**page_object.dict()) - add_role_result = add_role_crud(result_db, add_role) - if add_role_result.is_success: - role_id = get_role_by_name(result_db, page_object.role_name).role_id - if page_object.menu_id: - menu_id_list = page_object.menu_id.split(',') - for menu in menu_id_list: - menu_dict = dict(role_id=role_id, menu_id=menu) - add_role_menu_crud(result_db, RoleMenuModel(**menu_dict)) - - return add_role_result - - -def edit_role_services(result_db: Session, page_object: AddRoleModel): - """ - 编辑角色信息service - :param result_db: orm对象 - :param page_object: 编辑角色对象 - :return: 编辑角色校验结果 - """ - edit_role = page_object.dict(exclude_unset=True) - if page_object.type != 'status': - del edit_role['menu_id'] - if page_object.type == 'status': - del edit_role['type'] - edit_role_result = edit_role_crud(result_db, edit_role) - if edit_role_result.is_success and page_object.type != 'status': - role_id_dict = dict(role_id=page_object.role_id) - delete_role_menu_crud(result_db, RoleMenuModel(**role_id_dict)) - if page_object.menu_id: - menu_id_list = page_object.menu_id.split(',') - for menu in menu_id_list: - menu_dict = dict(role_id=page_object.role_id, menu_id=menu) - add_role_menu_crud(result_db, RoleMenuModel(**menu_dict)) - - return edit_role_result - - -def delete_role_services(result_db: Session, page_object: DeleteRoleModel): - """ - 删除角色信息service - :param result_db: orm对象 - :param page_object: 删除角色对象 - :return: 删除角色校验结果 - """ - if page_object.role_ids.split(','): - role_id_list = page_object.role_ids.split(',') - for role_id in role_id_list: - role_id_dict = dict(role_id=role_id, update_by=page_object.update_by, update_time=page_object.update_time) - delete_role_menu_crud(result_db, RoleMenuModel(**role_id_dict)) - delete_role_crud(result_db, RoleModel(**role_id_dict)) - result = dict(is_success=True, message='删除成功') - else: - result = dict(is_success=False, message='传入角色id为空') - return CrudRoleResponse(**result) - - -def detail_role_services(result_db: Session, role_id: int): - """ - 获取角色详细信息service - :param result_db: orm对象 - :param role_id: 角色id - :return: 角色id对应的信息 - """ - role = get_role_detail_by_id(result_db, role_id=role_id) - - return role + @classmethod + def get_role_select_option_services(cls, result_db: Session): + """ + 获取角色列表不分页信息service + :param result_db: orm对象 + :return: 角色列表不分页信息对象 + """ + role_list_result = RoleDao.get_role_select_option_dao(result_db) + + return role_list_result + + @classmethod + def get_role_list_services(cls, result_db: Session, query_object: RoleQueryModel): + """ + 获取角色列表信息service + :param result_db: orm对象 + :param query_object: 查询参数对象 + :return: 角色列表信息对象 + """ + role_list_result = RoleDao.get_role_list(result_db, query_object) + + return role_list_result + + @classmethod + def add_role_services(cls, result_db: Session, page_object: AddRoleModel): + """ + 新增角色信息service + :param result_db: orm对象 + :param page_object: 新增角色对象 + :return: 新增角色校验结果 + """ + add_role = RoleModel(**page_object.dict()) + role = RoleDao.get_role_by_info(result_db, RoleModel(**dict(role_name=page_object.role_name))) + if role: + result = dict(is_success=False, message='角色名称已存在') + else: + try: + add_result = RoleDao.add_role_dao(result_db, add_role) + role_id = add_result.role_id + if page_object.menu_id: + menu_id_list = page_object.menu_id.split(',') + for menu in menu_id_list: + menu_dict = dict(role_id=role_id, menu_id=menu) + RoleDao.add_role_menu_dao(result_db, RoleMenuModel(**menu_dict)) + result_db.commit() + result = dict(is_success=True, message='新增成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + + return CrudRoleResponse(**result) + + @classmethod + def edit_role_services(cls, result_db: Session, page_object: AddRoleModel): + """ + 编辑角色信息service + :param result_db: orm对象 + :param page_object: 编辑角色对象 + :return: 编辑角色校验结果 + """ + edit_role = page_object.dict(exclude_unset=True) + if page_object.type != 'status': + del edit_role['menu_id'] + if page_object.type == 'status': + del edit_role['type'] + role_info = cls.detail_role_services(result_db, edit_role.get('role_id')) + if role_info: + if page_object.type != 'status' and role_info.role.role_name != page_object.role_name: + role = RoleDao.get_role_by_info(result_db, RoleModel(**dict(role_name=page_object.role_name))) + if role: + result = dict(is_success=False, message='角色名称已存在') + return CrudRoleResponse(**result) + try: + RoleDao.edit_role_dao(result_db, edit_role) + if page_object.type != 'status': + role_id_dict = dict(role_id=page_object.role_id) + RoleDao.delete_role_menu_dao(result_db, RoleMenuModel(**role_id_dict)) + if page_object.menu_id: + menu_id_list = page_object.menu_id.split(',') + for menu in menu_id_list: + menu_dict = dict(role_id=page_object.role_id, menu_id=menu) + RoleDao.add_role_menu_dao(result_db, RoleMenuModel(**menu_dict)) + result_db.commit() + result = dict(is_success=True, message='更新成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='角色不存在') + + return CrudRoleResponse(**result) + + @classmethod + def delete_role_services(cls, result_db: Session, page_object: DeleteRoleModel): + """ + 删除角色信息service + :param result_db: orm对象 + :param page_object: 删除角色对象 + :return: 删除角色校验结果 + """ + if page_object.role_ids.split(','): + role_id_list = page_object.role_ids.split(',') + try: + for role_id in role_id_list: + role_id_dict = dict(role_id=role_id, update_by=page_object.update_by, update_time=page_object.update_time) + RoleDao.delete_role_menu_dao(result_db, RoleMenuModel(**role_id_dict)) + RoleDao.delete_role_dao(result_db, RoleModel(**role_id_dict)) + result_db.commit() + result = dict(is_success=True, message='删除成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='传入角色id为空') + return CrudRoleResponse(**result) + + @classmethod + def detail_role_services(cls, result_db: Session, role_id: int): + """ + 获取角色详细信息service + :param result_db: orm对象 + :param role_id: 角色id + :return: 角色id对应的信息 + """ + role = RoleDao.get_role_detail_by_id(result_db, role_id=role_id) + + return role + + @staticmethod + def export_role_list_services(role_list: List): + """ + 导出角色列表信息service + :param role_list: 角色信息列表 + :return: 角色列表信息对象 + """ + # 创建一个映射字典,将英文键映射到中文键 + mapping_dict = { + "role_id": "角色编号", + "role_name": "角色名称", + "role_key": "权限字符", + "role_sort": "显示顺序", + "status": "状态", + "create_by": "创建者", + "create_time": "创建时间", + "update_by": "更新者", + "update_time": "更新时间", + "remark": "备注", + } + + data = [RoleModel(**vars(row)).dict() for row in role_list] + + for item in data: + if item.get('status') == '0': + item['status'] = '正常' + else: + item['status'] = '停用' + new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data] + binary_data = export_list2excel(new_data) + + return binary_data diff --git a/dash-fastapi-backend/module_admin/service/server_service.py b/dash-fastapi-backend/module_admin/service/server_service.py new file mode 100644 index 0000000000000000000000000000000000000000..0c41c8eb864f152c31f2478d43cd865fd32f328c --- /dev/null +++ b/dash-fastapi-backend/module_admin/service/server_service.py @@ -0,0 +1,89 @@ +import psutil +from utils.common_util import bytes2human +import platform +import socket +import os +import time +from module_admin.entity.vo.server_vo import * + + +class ServerService: + """ + 服务监控模块服务层 + """ + + @staticmethod + def get_server_monitor_info(): + # CPU信息 + # 获取CPU总核心数 + cpu_num = psutil.cpu_count(logical=True) + cpu_usage_percent = psutil.cpu_times_percent() + cpu_used = f'{cpu_usage_percent.user}%' + cpu_sys = f'{cpu_usage_percent.system}%' + cpu_free = f'{cpu_usage_percent.idle}%' + cpu = CpuInfo(**dict(cpu_num=cpu_num, used=cpu_used, sys=cpu_sys, free=cpu_free)) + + # 内存信息 + memory_info = psutil.virtual_memory() + memory_total = bytes2human(memory_info.total) + memory_used = bytes2human(memory_info.used) + memory_free = bytes2human(memory_info.free) + memory_usage = f'{memory_info.percent}%' + mem = MemoryInfo(**dict(total=memory_total, used=memory_used, free=memory_free, usage=memory_usage)) + + # 主机信息 + # 获取主机名 + hostname = socket.gethostname() + # 获取IP + computer_ip = socket.gethostbyname(hostname) + os_name = platform.platform() + computer_name = platform.node() + os_arch = platform.machine() + sys = SysInfo(**dict(computer_ip=computer_ip, computer_name=computer_name, os_arch=os_arch, os_name=os_name)) + + # python解释器信息 + current_pid = os.getpid() + current_process = psutil.Process(current_pid) + python_name = current_process.name() + python_version = platform.python_version() + python_home = current_process.exe() + start_time_stamp = current_process.create_time() + start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(start_time_stamp)) + current_time_stamp = time.time() + difference = current_time_stamp - start_time_stamp + # 将时间差转换为天、小时和分钟数 + days = int(difference // (24 * 60 * 60)) # 每天的秒数 + hours = int((difference % (24 * 60 * 60)) // (60 * 60)) # 每小时的秒数 + minutes = int((difference % (60 * 60)) // 60) # 每分钟的秒数 + run_time = f"{days}天{hours}小时{minutes}分钟" + project_dir = os.path.abspath(os.getcwd()) + py = PyInfo( + **dict( + name=python_name, + version=python_version, + start_time=start_time, + run_time=run_time, + home=python_home, + project_dir=project_dir + ) + ) + + # 磁盘信息 + io = psutil.disk_partitions() + sys_files = [] + for i in io: + o = psutil.disk_usage(i.device) + disk_data = { + "dir_name": i.device, + "sys_type_name": i.fstype, + "disk_name": "本地固定磁盘(" + i.mountpoint.replace('\\', '') + ")", + "total": bytes2human(o.total), + "used": bytes2human(o.used), + "free": bytes2human(o.free), + "usage": f'{psutil.disk_usage(i.device).percent}%' + } + sys_files.append(SysFiles(**disk_data)) + + result = dict(cpu=cpu, mem=mem, sys=sys, py=py, sys_files=sys_files) + + return ServerMonitorModel(**result) diff --git a/dash-fastapi-backend/module_admin/service/user_service.py b/dash-fastapi-backend/module_admin/service/user_service.py index 909f5b3dc46eb4e52d9259fc94cf541099272588..f42a3bc834298697caa82a0d78f760a2d5abb7b2 100644 --- a/dash-fastapi-backend/module_admin/service/user_service.py +++ b/dash-fastapi-backend/module_admin/service/user_service.py @@ -1,108 +1,216 @@ -from module_admin.entity.vo.user_schema import * -from module_admin.mapper.user_crud import * +from module_admin.entity.vo.user_vo import * +from module_admin.dao.user_dao import * +from utils.pwd_util import * +from utils.common_util import export_list2excel -def get_user_list_services(result_db: Session, page_object: UserPageObject): +class UserService: """ - 获取用户列表信息service - :param result_db: orm对象 - :param page_object: 分页查询参数对象 - :return: 用户列表信息对象 + 用户管理模块服务层 """ - user_list_result = get_user_list(result_db, page_object) - return user_list_result + @classmethod + def get_user_list_services(cls, result_db: Session, query_object: UserQueryModel): + """ + 获取用户列表信息service + :param result_db: orm对象 + :param query_object: 查询参数对象 + :return: 用户列表信息对象 + """ + user_list_result = UserDao.get_user_list(result_db, query_object) + return user_list_result -def add_user_services(result_db: Session, page_object: AddUserModel): - """ - 新增用户信息service - :param result_db: orm对象 - :param page_object: 新增用户对象 - :return: 新增用户校验结果 - """ - add_user = UserModel(**page_object.dict()) - add_user_result = add_user_crud(result_db, add_user) - if add_user_result.is_success: - user_id = get_user_by_name(result_db, page_object.user_name).user_id - if page_object.role_id: - role_id_list = page_object.role_id.split(',') - for role in role_id_list: - role_dict = dict(user_id=user_id, role_id=role) - add_user_role_crud(result_db, UserRoleModel(**role_dict)) - if page_object.post_id: - post_id_list = page_object.post_id.split(',') - for post in post_id_list: - post_dict = dict(user_id=user_id, post_id=post) - add_user_post_crud(result_db, UserPostModel(**post_dict)) - - return add_user_result - - -def edit_user_services(result_db: Session, page_object: AddUserModel): - """ - 编辑用户信息service - :param result_db: orm对象 - :param page_object: 编辑用户对象 - :return: 编辑用户校验结果 - """ - edit_user = page_object.dict(exclude_unset=True) - if page_object.type != 'status': - del edit_user['role_id'] - del edit_user['post_id'] - if page_object.type == 'status': - del edit_user['type'] - edit_user_result = edit_user_crud(result_db, edit_user) - if edit_user_result.is_success and page_object.type != 'status': - user_id_dict = dict(user_id=page_object.user_id) - delete_user_role_crud(result_db, UserRoleModel(**user_id_dict)) - delete_user_post_crud(result_db, UserPostModel(**user_id_dict)) - if page_object.role_id: - role_id_list = page_object.role_id.split(',') - for role in role_id_list: - role_dict = dict(user_id=page_object.user_id, role_id=role) - add_user_role_crud(result_db, UserRoleModel(**role_dict)) - if page_object.post_id: - post_id_list = page_object.post_id.split(',') - for post in post_id_list: - post_dict = dict(user_id=page_object.user_id, post_id=post) - add_user_post_crud(result_db, UserPostModel(**post_dict)) - - return edit_user_result - - -def delete_user_services(result_db: Session, page_object: DeleteUserModel): - """ - 删除用户信息service - :param result_db: orm对象 - :param page_object: 删除用户对象 - :return: 删除用户校验结果 - """ - if page_object.user_ids.split(','): - user_id_list = page_object.user_ids.split(',') - for user_id in user_id_list: - user_id_dict = dict(user_id=user_id, update_by=page_object.update_by, update_time=page_object.update_time) - delete_user_role_crud(result_db, UserRoleModel(**user_id_dict)) - delete_user_post_crud(result_db, UserPostModel(**user_id_dict)) - delete_user_crud(result_db, UserModel(**user_id_dict)) - result = dict(is_success=True, message='删除成功') - else: - result = dict(is_success=False, message='传入用户id为空') - return CrudUserResponse(**result) - - -def detail_user_services(result_db: Session, user_id: int): - """ - 获取用户详细信息service - :param result_db: orm对象 - :param user_id: 用户id - :return: 用户id对应的信息 - """ - user = get_user_detail_by_id(result_db, user_id=user_id) - - return UserDetailModel( - user=user.user_basic_info[0], - dept=user.user_dept_info[0], - role=user.user_role_info, - post=user.user_post_info - ) + @classmethod + def add_user_services(cls, result_db: Session, page_object: AddUserModel): + """ + 新增用户信息service + :param result_db: orm对象 + :param page_object: 新增用户对象 + :return: 新增用户校验结果 + """ + add_user = UserModel(**page_object.dict()) + user = UserDao.get_user_by_info(result_db, UserModel(**dict(user_name=page_object.user_name))) + if user: + result = dict(is_success=False, message='用户名已存在') + else: + try: + add_result = UserDao.add_user_dao(result_db, add_user) + user_id = add_result.user_id + if page_object.role_id: + role_id_list = page_object.role_id.split(',') + for role in role_id_list: + role_dict = dict(user_id=user_id, role_id=role) + UserDao.add_user_role_dao(result_db, UserRoleModel(**role_dict)) + if page_object.post_id: + post_id_list = page_object.post_id.split(',') + for post in post_id_list: + post_dict = dict(user_id=user_id, post_id=post) + UserDao.add_user_post_dao(result_db, UserPostModel(**post_dict)) + result_db.commit() + result = dict(is_success=True, message='新增成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + + return CrudUserResponse(**result) + + @classmethod + def edit_user_services(cls, result_db: Session, page_object: AddUserModel): + """ + 编辑用户信息service + :param result_db: orm对象 + :param page_object: 编辑用户对象 + :return: 编辑用户校验结果 + """ + edit_user = page_object.dict(exclude_unset=True) + if page_object.type != 'status' and page_object.type != 'avatar': + del edit_user['role_id'] + del edit_user['post_id'] + if page_object.type == 'status' or page_object.type == 'avatar': + del edit_user['type'] + user_info = cls.detail_user_services(result_db, edit_user.get('user_id')) + if user_info: + if page_object.type != 'status' and page_object.type != 'avatar' and user_info.user.user_name != page_object.user_name: + user = UserDao.get_user_by_info(result_db, UserModel(**dict(user_name=page_object.user_name))) + if user: + result = dict(is_success=False, message='用户名已存在') + return CrudUserResponse(**result) + try: + UserDao.edit_user_dao(result_db, edit_user) + if page_object.type != 'status' and page_object.type != 'avatar': + user_id_dict = dict(user_id=page_object.user_id) + UserDao.delete_user_role_dao(result_db, UserRoleModel(**user_id_dict)) + UserDao.delete_user_post_dao(result_db, UserPostModel(**user_id_dict)) + if page_object.role_id: + role_id_list = page_object.role_id.split(',') + for role in role_id_list: + role_dict = dict(user_id=page_object.user_id, role_id=role) + UserDao.add_user_role_dao(result_db, UserRoleModel(**role_dict)) + if page_object.post_id: + post_id_list = page_object.post_id.split(',') + for post in post_id_list: + post_dict = dict(user_id=page_object.user_id, post_id=post) + UserDao.add_user_post_dao(result_db, UserPostModel(**post_dict)) + result_db.commit() + result = dict(is_success=True, message='更新成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='用户不存在') + + return CrudUserResponse(**result) + + @classmethod + def delete_user_services(cls, result_db: Session, page_object: DeleteUserModel): + """ + 删除用户信息service + :param result_db: orm对象 + :param page_object: 删除用户对象 + :return: 删除用户校验结果 + """ + if page_object.user_ids.split(','): + user_id_list = page_object.user_ids.split(',') + try: + for user_id in user_id_list: + user_id_dict = dict(user_id=user_id, update_by=page_object.update_by, update_time=page_object.update_time) + UserDao.delete_user_role_dao(result_db, UserRoleModel(**user_id_dict)) + UserDao.delete_user_post_dao(result_db, UserPostModel(**user_id_dict)) + UserDao.delete_user_dao(result_db, UserModel(**user_id_dict)) + result_db.commit() + result = dict(is_success=True, message='删除成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + else: + result = dict(is_success=False, message='传入用户id为空') + return CrudUserResponse(**result) + + @classmethod + def detail_user_services(cls, result_db: Session, user_id: int): + """ + 获取用户详细信息service + :param result_db: orm对象 + :param user_id: 用户id + :return: 用户id对应的信息 + """ + user = UserDao.get_user_detail_by_id(result_db, user_id=user_id) + + return UserDetailModel( + user=user.user_basic_info[0], + dept=user.user_dept_info[0], + role=user.user_role_info, + post=user.user_post_info + ) + + @classmethod + def reset_user_services(cls, result_db: Session, page_object: ResetUserModel): + """ + 重置用户密码service + :param result_db: orm对象 + :param page_object: 重置用户对象 + :return: 重置用户校验结果 + """ + reset_user = page_object.dict(exclude_unset=True) + if page_object.old_password: + user = UserDao.get_user_detail_by_id(result_db, user_id=page_object.user_id).user_basic_info[0] + if not PwdUtil.verify_password(page_object.old_password, user.password): + result = dict(is_success=False, message='旧密码不正确') + return CrudUserResponse(**result) + else: + del reset_user['old_password'] + if page_object.sms_code and page_object.session_id: + del reset_user['sms_code'] + del reset_user['session_id'] + try: + UserDao.edit_user_dao(result_db, reset_user) + result_db.commit() + result = dict(is_success=True, message='重置成功') + except Exception as e: + result_db.rollback() + result = dict(is_success=False, message=str(e)) + + return CrudUserResponse(**result) + + @staticmethod + def export_user_list_services(user_list: List): + """ + 导出用户信息service + :param user_list: 用户信息列表 + :return: 用户信息对应excel的二进制数据 + """ + # 创建一个映射字典,将英文键映射到中文键 + mapping_dict = { + "user_id": "用户编号", + "user_name": "用户名称", + "nick_name": "用户昵称", + "dept_name": "部门", + "email": "邮箱地址", + "phonenumber": "手机号码", + "sex": "性别", + "status": "状态", + "create_by": "创建者", + "create_time": "创建时间", + "update_by": "更新者", + "update_time": "更新时间", + "remark": "备注", + } + + data = user_list + + for item in data: + if item.get('status') == '0': + item['status'] = '正常' + else: + item['status'] = '停用' + if item.get('sex') == '0': + item['sex'] = '男' + elif item.get('sex') == '1': + item['sex'] = '女' + else: + item['sex'] = '未知' + new_data = [{mapping_dict.get(key): value for key, value in item.items() if mapping_dict.get(key)} for item in data] + binary_data = export_list2excel(new_data) + + return binary_data diff --git a/dash-fastapi-backend/module_task/__init__.py b/dash-fastapi-backend/module_task/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..36fefe9bdc99a4966a3627472fb980bff6c96a39 --- /dev/null +++ b/dash-fastapi-backend/module_task/__init__.py @@ -0,0 +1 @@ +from . import scheduler_test diff --git a/dash-fastapi-backend/module_task/scheduler_test.py b/dash-fastapi-backend/module_task/scheduler_test.py new file mode 100644 index 0000000000000000000000000000000000000000..b22dc6fc37a56bd4c4ae2d95b47d767a7bf62a8b --- /dev/null +++ b/dash-fastapi-backend/module_task/scheduler_test.py @@ -0,0 +1,7 @@ +from datetime import datetime + + +def job(*args, **kwargs): + print(args) + print(kwargs) + print(f"{datetime.now()}执行了") diff --git a/dash-fastapi-backend/sql/dash-fastapi.sql b/dash-fastapi-backend/sql/dash-fastapi.sql new file mode 100644 index 0000000000000000000000000000000000000000..f6d12d489654e4799f368564a45bdefac54d00df --- /dev/null +++ b/dash-fastapi-backend/sql/dash-fastapi.sql @@ -0,0 +1,720 @@ +/* + Navicat Premium Data Transfer + + Source Server : 本机mysql + Source Server Type : MySQL + Source Server Version : 80013 + Source Host : localhost:3306 + Source Schema : dash-fastapi + + Target Server Type : MySQL + Target Server Version : 80013 + File Encoding : 65001 + + Date: 09/03/2023 14:30:35 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for gen_table +-- ---------------------------- +DROP TABLE IF EXISTS `gen_table`; +CREATE TABLE `gen_table` ( + `table_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号', + `table_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '表名称', + `table_comment` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '表描述', + `sub_table_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '关联子表的表名', + `sub_table_fk_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '子表关联的外键名', + `class_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '实体类名称', + `tpl_category` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT 'crud' COMMENT '使用的模板(crud单表操作 tree树表操作)', + `package_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '生成包路径', + `module_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '生成模块名', + `business_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '生成业务名', + `function_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '生成功能名', + `function_author` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '生成功能作者', + `gen_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '生成代码方式(0zip压缩包 1自定义路径)', + `gen_path` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '/' COMMENT '生成路径(不填默认项目路径)', + `options` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '其它生成选项', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`table_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '代码生成业务表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of gen_table +-- ---------------------------- + +-- ---------------------------- +-- Table structure for gen_table_column +-- ---------------------------- +DROP TABLE IF EXISTS `gen_table_column`; +CREATE TABLE `gen_table_column` ( + `column_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号', + `table_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '归属表编号', + `column_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '列名称', + `column_comment` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '列描述', + `column_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '列类型', + `java_type` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'JAVA类型', + `java_field` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'JAVA字段名', + `is_pk` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否主键(1是)', + `is_increment` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否自增(1是)', + `is_required` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否必填(1是)', + `is_insert` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否为插入字段(1是)', + `is_edit` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否编辑字段(1是)', + `is_list` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否列表字段(1是)', + `is_query` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否查询字段(1是)', + `query_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT 'EQ' COMMENT '查询方式(等于、不等于、大于、小于、范围)', + `html_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)', + `dict_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '字典类型', + `sort` int(11) NULL DEFAULT NULL COMMENT '排序', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`column_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 26 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '代码生成业务表字段' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of gen_table_column +-- ---------------------------- + +-- ---------------------------- +-- Table structure for sys_config +-- ---------------------------- +DROP TABLE IF EXISTS `sys_config`; +CREATE TABLE `sys_config` ( + `config_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '参数主键', + `config_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '参数名称', + `config_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '参数键名', + `config_value` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '参数键值', + `config_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT 'N' COMMENT '系统内置(Y是 N否)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`config_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 101 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '参数配置表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_config +-- ---------------------------- +INSERT INTO `sys_config` VALUES (1, '主框架页-默认皮肤样式名称', 'sys.index.skinName', '#1890ff', 'Y', 'admin', '2023-05-23 16:13:34', 'admin', '2023-05-23 16:13:34', '蓝色 #1890ff'); +INSERT INTO `sys_config` VALUES (2, '账号自助-验证码开关', 'sys.account.captchaEnabled', 'true', 'Y', 'admin', '2023-05-23 16:13:34', 'admin', '2023-05-23 16:13:34', '是否开启验证码功能(true开启,false关闭)'); +INSERT INTO `sys_config` VALUES (3, '用户登录-黑名单列表', 'sys.login.blackIPList', '', 'Y', 'admin', '2023-05-23 16:13:34', '', NULL, '设置登录IP黑名单限制,多个匹配项以;分隔,支持匹配(*通配、网段)'); + +-- ---------------------------- +-- Table structure for sys_dept +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dept`; +CREATE TABLE `sys_dept` ( + `dept_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '部门id', + `parent_id` bigint(20) NULL DEFAULT 0 COMMENT '父部门id', + `ancestors` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '祖级列表', + `dept_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '部门名称', + `order_num` int(11) NULL DEFAULT 0 COMMENT '显示顺序', + `leader` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '负责人', + `phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '联系电话', + `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '邮箱', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '部门状态(0正常 1停用)', + `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`dept_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 201 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '部门表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_dept +-- ---------------------------- +INSERT INTO `sys_dept` VALUES (100, 0, '0', '集团总公司', 1, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', '2023-05-23 16:13:33', 'admin', '2023-08-08 15:57:58'); +INSERT INTO `sys_dept` VALUES (101, 100, '0,100', '上海分公司', 1, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', '2023-05-23 16:13:33', 'admin', '2023-08-08 15:57:58'); +INSERT INTO `sys_dept` VALUES (102, 100, '0,100', '广东分公司', 2, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', '2023-05-23 16:13:33', 'admin', '2023-08-08 15:57:58'); +INSERT INTO `sys_dept` VALUES (103, 101, '0,100,101', '研发部门', 1, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', '2023-05-23 16:13:33', 'admin', '2023-08-08 15:57:58'); +INSERT INTO `sys_dept` VALUES (104, 101, '0,100,101', '市场部门', 2, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', '2023-05-23 16:13:33', 'admin', '2023-08-08 15:57:58'); +INSERT INTO `sys_dept` VALUES (105, 101, '0,100,101', '测试部门', 3, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', '2023-05-23 16:13:33', 'admin', '2023-08-08 15:57:58'); +INSERT INTO `sys_dept` VALUES (106, 101, '0,100,101', '财务部门', 4, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', '2023-05-23 16:13:33', 'admin', '2023-08-08 15:57:58'); +INSERT INTO `sys_dept` VALUES (107, 101, '0,100,101', '运维部门', 5, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', '2023-05-23 16:13:33', 'admin', '2023-08-08 15:57:58'); +INSERT INTO `sys_dept` VALUES (108, 102, '0,100,102', '市场部门', 1, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', '2023-05-23 16:13:33', 'admin', '2023-08-08 15:57:58'); +INSERT INTO `sys_dept` VALUES (109, 102, '0,100,102', '财务部门', 2, '年糕', '15888888888', 'niangao@qq.com', '0', '0', 'admin', '2023-05-23 16:13:33', 'admin', '2023-08-08 15:57:58'); + +-- ---------------------------- +-- Table structure for sys_dict_data +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dict_data`; +CREATE TABLE `sys_dict_data` ( + `dict_code` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '字典编码', + `dict_sort` int(11) NULL DEFAULT 0 COMMENT '字典排序', + `dict_label` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '字典标签', + `dict_value` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '字典键值', + `dict_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '字典类型', + `css_class` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '样式属性(其他样式扩展)', + `list_class` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '表格回显样式', + `is_default` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'N' COMMENT '是否默认(Y是 N否)', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '状态(0正常 1停用)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`dict_code`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 101 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '字典数据表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_dict_data +-- ---------------------------- +INSERT INTO `sys_dict_data` VALUES (1, 1, '男', '0', 'sys_user_sex', '', '', 'Y', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '性别男'); +INSERT INTO `sys_dict_data` VALUES (2, 2, '女', '1', 'sys_user_sex', '', '', 'N', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '性别女'); +INSERT INTO `sys_dict_data` VALUES (3, 3, '未知', '2', 'sys_user_sex', '', '', 'N', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '性别未知'); +INSERT INTO `sys_dict_data` VALUES (4, 1, '显示', '0', 'sys_show_hide', '', 'primary', 'Y', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '显示菜单'); +INSERT INTO `sys_dict_data` VALUES (5, 2, '隐藏', '1', 'sys_show_hide', '', 'danger', 'N', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '隐藏菜单'); +INSERT INTO `sys_dict_data` VALUES (6, 1, '正常', '0', 'sys_normal_disable', '{\"color\": \"blue\"}', 'primary', 'Y', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '正常状态'); +INSERT INTO `sys_dict_data` VALUES (7, 2, '停用', '1', 'sys_normal_disable', '{\"color\": \"volcano\"}', 'danger', 'N', '0', 'admin', '2023-02-11 22:23:38', 'admin', '2023-08-18 11:24:23', '停用状态'); +INSERT INTO `sys_dict_data` VALUES (8, 1, '正常', '0', 'sys_job_status', '', 'primary', 'Y', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '正常状态'); +INSERT INTO `sys_dict_data` VALUES (9, 2, '暂停', '1', 'sys_job_status', '', 'danger', 'N', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '停用状态'); +INSERT INTO `sys_dict_data` VALUES (10, 1, '默认', 'default', 'sys_job_group', '{\"color\": \"blue\"}', '', 'Y', '0', 'admin', '2023-02-11 22:23:38', 'admin', '2023-08-20 16:33:32', '默认分组'); +INSERT INTO `sys_dict_data` VALUES (11, 2, '数据库', 'sqlalchemy', 'sys_job_group', '{\"color\": \"green\"}', '', 'N', '0', 'admin', '2023-02-11 22:23:38', 'admin', '2023-08-27 22:54:40', '数据库分组'); +INSERT INTO `sys_dict_data` VALUES (12, 1, '是', 'Y', 'sys_yes_no', '', 'primary', 'Y', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '系统默认是'); +INSERT INTO `sys_dict_data` VALUES (13, 2, '否', 'N', 'sys_yes_no', '', 'danger', 'N', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '系统默认否'); +INSERT INTO `sys_dict_data` VALUES (14, 1, '通知', '1', 'sys_notice_type', '{\"color\": \"gold\"}', 'warning', 'Y', '0', 'admin', '2023-02-11 22:23:38', 'admin', '2023-08-20 16:12:53', '通知'); +INSERT INTO `sys_dict_data` VALUES (15, 2, '公告', '2', 'sys_notice_type', '{\"color\": \"green\"}', 'success', 'N', '0', 'admin', '2023-02-11 22:23:38', 'admin', '2023-08-20 16:13:03', '公告'); +INSERT INTO `sys_dict_data` VALUES (16, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '正常状态'); +INSERT INTO `sys_dict_data` VALUES (17, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '关闭状态'); +INSERT INTO `sys_dict_data` VALUES (18, 99, '其他', '0', 'sys_oper_type', '{\"color\": \"purple\"}', 'info', 'N', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '其他操作'); +INSERT INTO `sys_dict_data` VALUES (19, 1, '新增', '1', 'sys_oper_type', '{\"color\": \"green\"}', 'info', 'N', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '新增操作'); +INSERT INTO `sys_dict_data` VALUES (20, 2, '修改', '2', 'sys_oper_type', '{\"color\": \"orange\"}', 'info', 'N', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '修改操作'); +INSERT INTO `sys_dict_data` VALUES (21, 3, '删除', '3', 'sys_oper_type', '{\"color\": \"red\"}', 'danger', 'N', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '删除操作'); +INSERT INTO `sys_dict_data` VALUES (22, 4, '授权', '4', 'sys_oper_type', '{\"color\": \"lime\"}', 'primary', 'N', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '授权操作'); +INSERT INTO `sys_dict_data` VALUES (23, 5, '导出', '5', 'sys_oper_type', '{\"color\": \"geekblue\"}', 'warning', 'N', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '导出操作'); +INSERT INTO `sys_dict_data` VALUES (24, 6, '导入', '6', 'sys_oper_type', '{\"color\": \"blue\"}', 'warning', 'N', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '导入操作'); +INSERT INTO `sys_dict_data` VALUES (25, 7, '强退', '7', 'sys_oper_type', '{\"color\": \"magenta\"}', 'danger', 'N', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '强退操作'); +INSERT INTO `sys_dict_data` VALUES (26, 8, '生成代码', '8', 'sys_oper_type', '{\"color\": \"cyan\"}', 'warning', 'N', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '生成操作'); +INSERT INTO `sys_dict_data` VALUES (27, 9, '清空数据', '9', 'sys_oper_type', '{\"color\": \"volcano\"}', 'danger', 'N', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '清空操作'); +INSERT INTO `sys_dict_data` VALUES (28, 1, '成功', '0', 'sys_common_status', '', 'primary', 'N', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '正常状态'); +INSERT INTO `sys_dict_data` VALUES (29, 2, '失败', '1', 'sys_common_status', '', 'danger', 'N', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '停用状态'); +INSERT INTO `sys_dict_data` VALUES (100, 3, 'Redis', 'redis', 'sys_job_group', '{\"color\": \"gold\"}', 'default', 'N', '0', 'admin', '2023-08-27 22:52:05', 'admin', '2023-08-27 22:52:05', 'redis分组'); + +-- ---------------------------- +-- Table structure for sys_dict_type +-- ---------------------------- +DROP TABLE IF EXISTS `sys_dict_type`; +CREATE TABLE `sys_dict_type` ( + `dict_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '字典主键', + `dict_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '字典名称', + `dict_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '字典类型', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '状态(0正常 1停用)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`dict_id`) USING BTREE, + UNIQUE INDEX `dict_type`(`dict_type`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '字典类型表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_dict_type +-- ---------------------------- +INSERT INTO `sys_dict_type` VALUES (1, '用户性别', 'sys_user_sex', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '用户性别列表'); +INSERT INTO `sys_dict_type` VALUES (2, '菜单状态', 'sys_show_hide', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '菜单状态列表'); +INSERT INTO `sys_dict_type` VALUES (3, '系统开关', 'sys_normal_disable', '0', 'admin', '2023-02-11 22:23:38', 'admin', '2023-08-18 11:23:39', '系统开关列表'); +INSERT INTO `sys_dict_type` VALUES (4, '任务状态', 'sys_job_status', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '任务状态列表'); +INSERT INTO `sys_dict_type` VALUES (5, '任务分组', 'sys_job_group', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '任务分组列表'); +INSERT INTO `sys_dict_type` VALUES (6, '系统是否', 'sys_yes_no', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '系统是否列表'); +INSERT INTO `sys_dict_type` VALUES (7, '通知类型', 'sys_notice_type', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '通知类型列表'); +INSERT INTO `sys_dict_type` VALUES (8, '通知状态', 'sys_notice_status', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '通知状态列表'); +INSERT INTO `sys_dict_type` VALUES (9, '操作类型', 'sys_oper_type', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '操作类型列表'); +INSERT INTO `sys_dict_type` VALUES (10, '系统状态', 'sys_common_status', '0', 'admin', '2023-02-11 22:23:38', '', NULL, '登录状态列表'); + +-- ---------------------------- +-- Table structure for sys_job +-- ---------------------------- +DROP TABLE IF EXISTS `sys_job`; +CREATE TABLE `sys_job` ( + `job_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '任务ID', + `job_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '任务名称', + `job_group` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'default' COMMENT '任务组名', + `job_executor` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'default' COMMENT '任务执行器', + `invoke_target` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调用目标字符串', + `job_args` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '位置参数', + `job_kwargs` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '关键字参数', + `cron_expression` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT 'cron执行表达式', + `misfire_policy` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '3' COMMENT '计划执行错误策略(1立即执行 2执行一次 3放弃执行)', + `concurrent` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '1' COMMENT '是否并发执行(0允许 1禁止)', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '状态(0正常 1暂停)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '备注信息', + PRIMARY KEY (`job_id`, `job_name`, `job_group`, `job_executor`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '定时任务调度表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_job +-- ---------------------------- +INSERT INTO `sys_job` VALUES (1, '系统默认(无参)', 'default', 'default', 'module_task.scheduler_test.job', 'test', NULL, '0/10 * * * * ?', '2', '0', '1', 'admin', '2023-05-23 16:13:34', 'admin', '2023-05-23 16:13:34', ''); +INSERT INTO `sys_job` VALUES (2, '系统默认(有参)', 'sqlalchemy', 'default', 'module_task.scheduler_test.job', 'new', '{\"test\": 111}', '0/15 * * * * ?', '1', '1', '1', 'admin', '2023-05-23 16:13:34', 'admin', '2023-05-23 16:13:34', ''); +INSERT INTO `sys_job` VALUES (3, '系统默认(多参)', 'redis', 'default', 'module_task.scheduler_test.job', NULL, NULL, '0/20 * * * * ?', '3', '1', '1', 'admin', '2023-05-23 16:13:34', '', NULL, ''); + +-- ---------------------------- +-- Table structure for sys_job_log +-- ---------------------------- +DROP TABLE IF EXISTS `sys_job_log`; +CREATE TABLE `sys_job_log` ( + `job_log_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '任务日志ID', + `job_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '任务名称', + `job_group` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '任务组名', + `job_executor` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '任务执行器', + `invoke_target` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调用目标字符串', + `job_args` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '位置参数', + `job_kwargs` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '关键字参数', + `job_trigger` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '任务触发器', + `job_message` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '日志信息', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '执行状态(0正常 1失败)', + `exception_info` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '异常信息', + `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (`job_log_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '定时任务调度日志表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_job_log +-- ---------------------------- + +-- ---------------------------- +-- Table structure for sys_logininfor +-- ---------------------------- +DROP TABLE IF EXISTS `sys_logininfor`; +CREATE TABLE `sys_logininfor` ( + `info_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '访问ID', + `user_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '用户账号', + `ipaddr` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '登录IP地址', + `login_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '登录地点', + `browser` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '浏览器类型', + `os` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '操作系统', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '登录状态(0成功 1失败)', + `msg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '提示消息', + `login_time` datetime(0) NULL DEFAULT NULL COMMENT '访问时间', + PRIMARY KEY (`info_id`) USING BTREE, + INDEX `idx_sys_logininfor_s`(`status`) USING BTREE, + INDEX `idx_sys_logininfor_lt`(`login_time`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统访问记录' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_logininfor +-- ---------------------------- + +-- ---------------------------- +-- Table structure for sys_menu +-- ---------------------------- +DROP TABLE IF EXISTS `sys_menu`; +CREATE TABLE `sys_menu` ( + `menu_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '菜单ID', + `menu_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '菜单名称', + `parent_id` bigint(20) NULL DEFAULT 0 COMMENT '父菜单ID', + `order_num` int(11) NULL DEFAULT 0 COMMENT '显示顺序', + `path` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '路由地址', + `component` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '组件路径', + `query` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '路由参数', + `is_frame` int(11) NULL DEFAULT 1 COMMENT '是否为外链(0是 1否)', + `is_cache` int(11) NULL DEFAULT 0 COMMENT '是否缓存(0缓存 1不缓存)', + `menu_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '菜单类型(M目录 C菜单 F按钮)', + `visible` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '菜单状态(0显示 1隐藏)', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '菜单状态(0正常 1停用)', + `perms` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '权限标识', + `icon` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '#' COMMENT '菜单图标', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '备注', + PRIMARY KEY (`menu_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 2000 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '菜单权限表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_menu +-- ---------------------------- +INSERT INTO `sys_menu` VALUES (1, '系统管理', 0, 1, '/system', NULL, '', 1, 0, 'M', '0', '0', '', 'antd-setting', 'admin', '2023-05-23 16:13:33', '', NULL, '系统管理目录'); +INSERT INTO `sys_menu` VALUES (2, '系统监控', 0, 2, '/monitor', NULL, '', 1, 0, 'M', '0', '0', '', 'antd-fund-projection-screen', 'admin', '2023-05-23 16:13:33', '', NULL, '系统监控目录'); +INSERT INTO `sys_menu` VALUES (3, '系统工具', 0, 3, '/tool', NULL, '', 1, 0, 'M', '0', '0', '', 'antd-repair', 'admin', '2023-05-23 16:13:33', '', NULL, '系统工具目录'); +INSERT INTO `sys_menu` VALUES (4, '若依官网', 0, 4, 'http://ruoyi.vip', NULL, NULL, 0, 0, 'M', '0', '0', '', 'antd-send', 'admin', '2023-05-23 16:13:33', '', NULL, '若依官网地址'); +INSERT INTO `sys_menu` VALUES (100, '用户管理', 1, 1, '/system/user', 'system.user', '', 1, 0, 'C', '0', '0', 'system:user:list', 'antd-user', 'admin', '2023-05-23 16:13:33', '', NULL, '用户管理菜单'); +INSERT INTO `sys_menu` VALUES (101, '角色管理', 1, 2, '/system/role', 'system.role', '', 1, 0, 'C', '0', '0', 'system:role:list', 'antd-team', 'admin', '2023-05-23 16:13:33', '', NULL, '角色管理菜单'); +INSERT INTO `sys_menu` VALUES (102, '菜单管理', 1, 3, '/system/menu', 'system.menu', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'antd-app-store-add', 'admin', '2023-05-23 16:13:33', '', NULL, '菜单管理菜单'); +INSERT INTO `sys_menu` VALUES (103, '部门管理', 1, 4, '/system/dept', 'system.dept', '', 1, 0, 'C', '0', '0', 'system:dept:list', 'antd-cluster', 'admin', '2023-05-23 16:13:33', '', NULL, '部门管理菜单'); +INSERT INTO `sys_menu` VALUES (104, '岗位管理', 1, 5, '/system/post', 'system.post', '', 1, 0, 'C', '0', '0', 'system:post:list', 'antd-idcard', 'admin', '2023-05-23 16:13:33', 'ry', '2023-07-06 09:47:26', '岗位管理菜单'); +INSERT INTO `sys_menu` VALUES (105, '字典管理', 1, 6, '/system/dict', 'system.dict', '', 1, 0, 'C', '0', '0', 'system:dict:list', 'antd-read', 'admin', '2023-05-23 16:13:33', 'ry', '2023-07-06 16:25:44', '字典管理菜单'); +INSERT INTO `sys_menu` VALUES (106, '参数设置', 1, 7, '/system/config', 'system.config', '', 1, 0, 'C', '0', '0', 'system:config:list', 'antd-calculator', 'admin', '2023-05-23 16:13:33', '', NULL, '参数设置菜单'); +INSERT INTO `sys_menu` VALUES (107, '通知公告', 1, 8, '/system/notice', 'system.notice', '', 1, 0, 'C', '0', '0', 'system:notice:list', 'antd-notification', 'admin', '2023-05-23 16:13:33', '', NULL, '通知公告菜单'); +INSERT INTO `sys_menu` VALUES (108, '日志管理', 1, 9, '/log', '', '', 1, 0, 'M', '0', '0', '', 'antd-bug', 'admin', '2023-05-23 16:13:33', '', NULL, '日志管理菜单'); +INSERT INTO `sys_menu` VALUES (109, '在线用户', 2, 1, '/monitor/online', 'monitor.online', '', 1, 0, 'C', '0', '0', 'monitor:online:list', 'antd-desktop', 'admin', '2023-05-23 16:13:33', '', NULL, '在线用户菜单'); +INSERT INTO `sys_menu` VALUES (110, '定时任务', 2, 2, '/monitor/job', 'monitor.job', '', 1, 0, 'C', '0', '0', 'monitor:job:list', 'antd-deployment-unit', 'admin', '2023-05-23 16:13:33', '', NULL, '定时任务菜单'); +INSERT INTO `sys_menu` VALUES (111, '数据监控', 2, 3, '/monitor/druid', 'monitor.druid', '', 1, 0, 'C', '0', '0', 'monitor:druid:list', 'antd-database', 'admin', '2023-05-23 16:13:33', '', NULL, '数据监控菜单'); +INSERT INTO `sys_menu` VALUES (112, '服务监控', 2, 4, '/monitor/server', 'monitor.server', '', 1, 0, 'C', '0', '0', 'monitor:server:list', 'antd-cloud-server', 'admin', '2023-05-23 16:13:33', '', NULL, '服务监控菜单'); +INSERT INTO `sys_menu` VALUES (113, '缓存监控', 2, 5, '/monitor/cache/control', 'monitor.cache.control', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'antd-cloud-sync', 'admin', '2023-05-23 16:13:33', 'admin', '2023-08-11 10:52:56', '缓存监控菜单'); +INSERT INTO `sys_menu` VALUES (114, '缓存列表', 2, 6, '/monitor/cache/list', 'monitor.cache.list', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'antd-table', 'admin', '2023-05-23 16:13:33', 'admin', '2023-08-11 10:53:11', '缓存列表菜单'); +INSERT INTO `sys_menu` VALUES (115, '表单构建', 3, 1, '/tool/build', 'tool.build', '', 1, 0, 'C', '0', '0', 'tool:build:list', 'antd-build', 'admin', '2023-05-23 16:13:33', '', NULL, '表单构建菜单'); +INSERT INTO `sys_menu` VALUES (116, '代码生成', 3, 2, '/tool/gen', 'tool.gen', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'antd-console-sql', 'admin', '2023-05-23 16:13:33', '', NULL, '代码生成菜单'); +INSERT INTO `sys_menu` VALUES (117, '系统接口', 3, 3, '/tool/swagger', 'tool.swagger', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'antd-api', 'admin', '2023-05-23 16:13:33', '', NULL, '系统接口菜单'); +INSERT INTO `sys_menu` VALUES (500, '操作日志', 108, 1, '/monitor/operlog', 'monitor.operlog', '', 1, 0, 'C', '0', '0', 'monitor:operlog:list', 'antd-clear', 'admin', '2023-05-23 16:13:33', '', NULL, '操作日志菜单'); +INSERT INTO `sys_menu` VALUES (501, '登录日志', 108, 2, '/monitor/logininfor', 'monitor.logininfor', '', 1, 0, 'C', '0', '0', 'monitor:logininfor:list', 'antd-control', 'admin', '2023-05-23 16:13:33', '', NULL, '登录日志菜单'); +INSERT INTO `sys_menu` VALUES (1000, '用户查询', 100, 1, '', '', '', 1, 0, 'F', '0', '0', 'system:user:query', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1001, '用户新增', 100, 2, '', '', '', 1, 0, 'F', '0', '0', 'system:user:add', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1002, '用户修改', 100, 3, '', '', '', 1, 0, 'F', '0', '0', 'system:user:edit', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1003, '用户删除', 100, 4, '', '', '', 1, 0, 'F', '0', '0', 'system:user:remove', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1004, '用户导出', 100, 5, '', '', '', 1, 0, 'F', '0', '0', 'system:user:export', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1005, '用户导入', 100, 6, '', '', '', 1, 0, 'F', '0', '0', 'system:user:import', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1006, '重置密码', 100, 7, '', '', '', 1, 0, 'F', '0', '0', 'system:user:resetPwd', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1007, '角色查询', 101, 1, '', '', '', 1, 0, 'F', '0', '0', 'system:role:query', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1008, '角色新增', 101, 2, '', '', '', 1, 0, 'F', '0', '0', 'system:role:add', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1009, '角色修改', 101, 3, '', '', '', 1, 0, 'F', '0', '0', 'system:role:edit', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1010, '角色删除', 101, 4, '', '', '', 1, 0, 'F', '0', '0', 'system:role:remove', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1011, '角色导出', 101, 5, '', '', '', 1, 0, 'F', '0', '0', 'system:role:export', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1012, '菜单查询', 102, 1, '', '', '', 1, 0, 'F', '0', '0', 'system:menu:query', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1013, '菜单新增', 102, 2, '', '', '', 1, 0, 'F', '0', '0', 'system:menu:add', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1014, '菜单修改', 102, 3, '', '', '', 1, 0, 'F', '0', '0', 'system:menu:edit', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1015, '菜单删除', 102, 4, '', '', '', 1, 0, 'F', '0', '0', 'system:menu:remove', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1016, '部门查询', 103, 1, '', '', '', 1, 0, 'F', '0', '0', 'system:dept:query', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1017, '部门新增', 103, 2, '', '', '', 1, 0, 'F', '0', '0', 'system:dept:add', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1018, '部门修改', 103, 3, '', '', '', 1, 0, 'F', '0', '0', 'system:dept:edit', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1019, '部门删除', 103, 4, '', '', '', 1, 0, 'F', '0', '0', 'system:dept:remove', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1020, '岗位查询', 104, 1, '', '', '', 1, 0, 'F', '0', '0', 'system:post:query', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1021, '岗位新增', 104, 2, '', '', '', 1, 0, 'F', '0', '0', 'system:post:add', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1022, '岗位修改', 104, 3, '', '', '', 1, 0, 'F', '0', '0', 'system:post:edit', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1023, '岗位删除', 104, 4, '', '', '', 1, 0, 'F', '0', '0', 'system:post:remove', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1024, '岗位导出', 104, 5, '', '', '', 1, 0, 'F', '0', '0', 'system:post:export', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1025, '字典查询', 105, 1, '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:query', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1026, '字典新增', 105, 2, '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:add', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1027, '字典修改', 105, 3, '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:edit', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1028, '字典删除', 105, 4, '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:remove', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1029, '字典导出', 105, 5, '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:export', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1030, '参数查询', 106, 1, '#', '', '', 1, 0, 'F', '0', '0', 'system:config:query', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1031, '参数新增', 106, 2, '#', '', '', 1, 0, 'F', '0', '0', 'system:config:add', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1032, '参数修改', 106, 3, '#', '', '', 1, 0, 'F', '0', '0', 'system:config:edit', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1033, '参数删除', 106, 4, '#', '', '', 1, 0, 'F', '0', '0', 'system:config:remove', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1034, '参数导出', 106, 5, '#', '', '', 1, 0, 'F', '0', '0', 'system:config:export', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1035, '公告查询', 107, 1, '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:query', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1036, '公告新增', 107, 2, '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:add', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1037, '公告修改', 107, 3, '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:edit', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1038, '公告删除', 107, 4, '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:remove', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1039, '操作查询', 500, 1, '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:query', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1040, '操作删除', 500, 2, '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:remove', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1041, '日志导出', 500, 3, '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:export', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1042, '登录查询', 501, 1, '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:query', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1043, '登录删除', 501, 2, '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:remove', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1044, '日志导出', 501, 3, '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:export', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1045, '账户解锁', 501, 4, '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1046, '在线查询', 109, 1, '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1047, '批量强退', 109, 2, '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1048, '单条强退', 109, 3, '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1049, '任务查询', 110, 1, '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:query', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1050, '任务新增', 110, 2, '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:add', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1051, '任务修改', 110, 3, '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:edit', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1052, '任务删除', 110, 4, '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:remove', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1053, '状态修改', 110, 5, '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:changeStatus', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1054, '任务导出', 110, 6, '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:export', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1055, '生成查询', 116, 1, '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:query', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1056, '生成修改', 116, 2, '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:edit', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1057, '生成删除', 116, 3, '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:remove', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1058, '导入代码', 116, 4, '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1059, '预览代码', 116, 5, '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_menu` VALUES (1060, '生成代码', 116, 6, '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', '2023-05-23 16:13:33', '', NULL, ''); + +-- ---------------------------- +-- Table structure for sys_notice +-- ---------------------------- +DROP TABLE IF EXISTS `sys_notice`; +CREATE TABLE `sys_notice` ( + `notice_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '公告ID', + `notice_title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '公告标题', + `notice_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '公告类型(1通知 2公告)', + `notice_content` longblob NULL COMMENT '公告内容', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '公告状态(0正常 1关闭)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`notice_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '通知公告表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_notice +-- ---------------------------- +INSERT INTO `sys_notice` VALUES (1, '温馨提醒:2018-07-01 若依新版本发布啦', '2', 0xE696B0E78988E69CACE58685E5AEB9, '0', 'admin', '2023-05-23 16:13:34', '', NULL, '管理员'); +INSERT INTO `sys_notice` VALUES (2, '维护通知:2018-07-01 若依系统凌晨维护', '1', 0xE7BBB4E68AA4E58685E5AEB9, '0', 'admin', '2023-05-23 16:13:34', '', NULL, '管理员'); + +-- ---------------------------- +-- Table structure for sys_oper_log +-- ---------------------------- +DROP TABLE IF EXISTS `sys_oper_log`; +CREATE TABLE `sys_oper_log` ( + `oper_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '日志主键', + `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '模块标题', + `business_type` int(11) NULL DEFAULT 0 COMMENT '业务类型(0其它 1新增 2修改 3删除)', + `method` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '方法名称', + `request_method` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '请求方式', + `operator_type` int(11) NULL DEFAULT 0 COMMENT '操作类别(0其它 1后台用户 2手机端用户)', + `oper_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '操作人员', + `dept_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '部门名称', + `oper_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '请求URL', + `oper_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '主机地址', + `oper_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '操作地点', + `oper_param` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '请求参数', + `json_result` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '返回参数', + `status` int(11) NULL DEFAULT 0 COMMENT '操作状态(0正常 1异常)', + `error_msg` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '错误消息', + `oper_time` datetime(0) NULL DEFAULT NULL COMMENT '操作时间', + `cost_time` bigint(20) NULL DEFAULT 0 COMMENT '消耗时间', + PRIMARY KEY (`oper_id`) USING BTREE, + INDEX `idx_sys_oper_log_bt`(`business_type`) USING BTREE, + INDEX `idx_sys_oper_log_s`(`status`) USING BTREE, + INDEX `idx_sys_oper_log_ot`(`oper_time`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '操作日志记录' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_oper_log +-- ---------------------------- + +-- ---------------------------- +-- Table structure for sys_post +-- ---------------------------- +DROP TABLE IF EXISTS `sys_post`; +CREATE TABLE `sys_post` ( + `post_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '岗位ID', + `post_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '岗位编码', + `post_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '岗位名称', + `post_sort` int(11) NOT NULL COMMENT '显示顺序', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '状态(0正常 1停用)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`post_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '岗位信息表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_post +-- ---------------------------- +INSERT INTO `sys_post` VALUES (1, 'ceo', '董事长', 1, '0', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_post` VALUES (2, 'se', '项目经理', 2, '0', 'admin', '2023-05-23 16:13:33', '', NULL, ''); +INSERT INTO `sys_post` VALUES (3, 'hr', '人力资源', 3, '0', 'admin', '2023-05-23 16:13:33', 'ry', '2023-06-05 15:49:31', ''); +INSERT INTO `sys_post` VALUES (4, 'user', '普通员工', 4, '0', 'admin', '2023-05-23 16:13:33', '', NULL, ''); + +-- ---------------------------- +-- Table structure for sys_role +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role`; +CREATE TABLE `sys_role` ( + `role_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '角色ID', + `role_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色名称', + `role_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色权限字符串', + `role_sort` int(11) NOT NULL COMMENT '显示顺序', + `data_scope` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '1' COMMENT '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)', + `menu_check_strictly` tinyint(1) NULL DEFAULT 1 COMMENT '菜单树选择项是否关联显示', + `dept_check_strictly` tinyint(1) NULL DEFAULT 1 COMMENT '部门树选择项是否关联显示', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色状态(0正常 1停用)', + `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`role_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '角色信息表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_role +-- ---------------------------- +INSERT INTO `sys_role` VALUES (1, '超级管理员', 'admin', 1, '1', 1, 1, '0', '0', 'admin', '2023-05-23 16:13:33', '', NULL, '超级管理员'); +INSERT INTO `sys_role` VALUES (2, '普通角色', 'common', 2, '2', 1, 1, '0', '0', 'admin', '2023-05-23 16:13:33', 'admin', '2023-09-01 15:53:26', '普通角色'); + +-- ---------------------------- +-- Table structure for sys_role_dept +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role_dept`; +CREATE TABLE `sys_role_dept` ( + `role_id` bigint(20) NOT NULL COMMENT '角色ID', + `dept_id` bigint(20) NOT NULL COMMENT '部门ID', + PRIMARY KEY (`role_id`, `dept_id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '角色和部门关联表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_role_dept +-- ---------------------------- +INSERT INTO `sys_role_dept` VALUES (2, 100); +INSERT INTO `sys_role_dept` VALUES (2, 101); +INSERT INTO `sys_role_dept` VALUES (2, 105); + +-- ---------------------------- +-- Table structure for sys_role_menu +-- ---------------------------- +DROP TABLE IF EXISTS `sys_role_menu`; +CREATE TABLE `sys_role_menu` ( + `role_id` bigint(20) NOT NULL COMMENT '角色ID', + `menu_id` bigint(20) NOT NULL COMMENT '菜单ID', + PRIMARY KEY (`role_id`, `menu_id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '角色和菜单关联表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_role_menu +-- ---------------------------- +INSERT INTO `sys_role_menu` VALUES (2, 1); +INSERT INTO `sys_role_menu` VALUES (2, 2); +INSERT INTO `sys_role_menu` VALUES (2, 3); +INSERT INTO `sys_role_menu` VALUES (2, 4); +INSERT INTO `sys_role_menu` VALUES (2, 100); +INSERT INTO `sys_role_menu` VALUES (2, 101); +INSERT INTO `sys_role_menu` VALUES (2, 102); +INSERT INTO `sys_role_menu` VALUES (2, 103); +INSERT INTO `sys_role_menu` VALUES (2, 104); +INSERT INTO `sys_role_menu` VALUES (2, 105); +INSERT INTO `sys_role_menu` VALUES (2, 106); +INSERT INTO `sys_role_menu` VALUES (2, 107); +INSERT INTO `sys_role_menu` VALUES (2, 108); +INSERT INTO `sys_role_menu` VALUES (2, 109); +INSERT INTO `sys_role_menu` VALUES (2, 110); +INSERT INTO `sys_role_menu` VALUES (2, 111); +INSERT INTO `sys_role_menu` VALUES (2, 112); +INSERT INTO `sys_role_menu` VALUES (2, 113); +INSERT INTO `sys_role_menu` VALUES (2, 114); +INSERT INTO `sys_role_menu` VALUES (2, 115); +INSERT INTO `sys_role_menu` VALUES (2, 116); +INSERT INTO `sys_role_menu` VALUES (2, 117); +INSERT INTO `sys_role_menu` VALUES (2, 500); +INSERT INTO `sys_role_menu` VALUES (2, 501); +INSERT INTO `sys_role_menu` VALUES (2, 1000); +INSERT INTO `sys_role_menu` VALUES (2, 1001); +INSERT INTO `sys_role_menu` VALUES (2, 1002); +INSERT INTO `sys_role_menu` VALUES (2, 1003); +INSERT INTO `sys_role_menu` VALUES (2, 1004); +INSERT INTO `sys_role_menu` VALUES (2, 1005); +INSERT INTO `sys_role_menu` VALUES (2, 1006); +INSERT INTO `sys_role_menu` VALUES (2, 1007); +INSERT INTO `sys_role_menu` VALUES (2, 1008); +INSERT INTO `sys_role_menu` VALUES (2, 1009); +INSERT INTO `sys_role_menu` VALUES (2, 1010); +INSERT INTO `sys_role_menu` VALUES (2, 1011); +INSERT INTO `sys_role_menu` VALUES (2, 1012); +INSERT INTO `sys_role_menu` VALUES (2, 1013); +INSERT INTO `sys_role_menu` VALUES (2, 1014); +INSERT INTO `sys_role_menu` VALUES (2, 1015); +INSERT INTO `sys_role_menu` VALUES (2, 1016); +INSERT INTO `sys_role_menu` VALUES (2, 1017); +INSERT INTO `sys_role_menu` VALUES (2, 1018); +INSERT INTO `sys_role_menu` VALUES (2, 1019); +INSERT INTO `sys_role_menu` VALUES (2, 1020); +INSERT INTO `sys_role_menu` VALUES (2, 1021); +INSERT INTO `sys_role_menu` VALUES (2, 1022); +INSERT INTO `sys_role_menu` VALUES (2, 1023); +INSERT INTO `sys_role_menu` VALUES (2, 1024); +INSERT INTO `sys_role_menu` VALUES (2, 1025); +INSERT INTO `sys_role_menu` VALUES (2, 1026); +INSERT INTO `sys_role_menu` VALUES (2, 1027); +INSERT INTO `sys_role_menu` VALUES (2, 1028); +INSERT INTO `sys_role_menu` VALUES (2, 1029); +INSERT INTO `sys_role_menu` VALUES (2, 1030); +INSERT INTO `sys_role_menu` VALUES (2, 1031); +INSERT INTO `sys_role_menu` VALUES (2, 1032); +INSERT INTO `sys_role_menu` VALUES (2, 1033); +INSERT INTO `sys_role_menu` VALUES (2, 1034); +INSERT INTO `sys_role_menu` VALUES (2, 1035); +INSERT INTO `sys_role_menu` VALUES (2, 1036); +INSERT INTO `sys_role_menu` VALUES (2, 1037); +INSERT INTO `sys_role_menu` VALUES (2, 1038); +INSERT INTO `sys_role_menu` VALUES (2, 1039); +INSERT INTO `sys_role_menu` VALUES (2, 1040); +INSERT INTO `sys_role_menu` VALUES (2, 1041); +INSERT INTO `sys_role_menu` VALUES (2, 1042); +INSERT INTO `sys_role_menu` VALUES (2, 1043); +INSERT INTO `sys_role_menu` VALUES (2, 1044); +INSERT INTO `sys_role_menu` VALUES (2, 1045); +INSERT INTO `sys_role_menu` VALUES (2, 1046); +INSERT INTO `sys_role_menu` VALUES (2, 1047); +INSERT INTO `sys_role_menu` VALUES (2, 1048); +INSERT INTO `sys_role_menu` VALUES (2, 1049); +INSERT INTO `sys_role_menu` VALUES (2, 1050); +INSERT INTO `sys_role_menu` VALUES (2, 1051); +INSERT INTO `sys_role_menu` VALUES (2, 1052); +INSERT INTO `sys_role_menu` VALUES (2, 1053); +INSERT INTO `sys_role_menu` VALUES (2, 1054); +INSERT INTO `sys_role_menu` VALUES (2, 1055); +INSERT INTO `sys_role_menu` VALUES (2, 1056); +INSERT INTO `sys_role_menu` VALUES (2, 1057); +INSERT INTO `sys_role_menu` VALUES (2, 1058); +INSERT INTO `sys_role_menu` VALUES (2, 1059); +INSERT INTO `sys_role_menu` VALUES (2, 1060); + +-- ---------------------------- +-- Table structure for sys_user +-- ---------------------------- +DROP TABLE IF EXISTS `sys_user`; +CREATE TABLE `sys_user` ( + `user_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID', + `dept_id` bigint(20) NULL DEFAULT NULL COMMENT '部门ID', + `user_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户账号', + `nick_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户昵称', + `user_type` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '00' COMMENT '用户类型(00系统用户)', + `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '用户邮箱', + `phonenumber` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '手机号码', + `sex` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '用户性别(0男 1女 2未知)', + `avatar` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '头像地址', + `password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '密码', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '帐号状态(0正常 1停用)', + `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', + `login_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '最后登录IP', + `login_date` datetime(0) NULL DEFAULT NULL COMMENT '最后登录时间', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + PRIMARY KEY (`user_id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '用户信息表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_user +-- ---------------------------- +INSERT INTO `sys_user` VALUES (1, 103, 'admin', '超级管理员', '00', 'niangao@163.com', '18888888888', '1', 'http://127.0.0.1:9099/common/caches?taskId=avatar&filename=admin_avatar.jpeg', '$2b$12$dW/S5ummJs3Z5fMXqsesWuJgTimgtpK85L0zFhUAuFmHDznII/F66', '0', '0', '127.0.0.1', '2023-05-23 16:13:33', 'admin', '2023-05-23 16:13:33', 'admin', '2023-05-23 16:13:33', '管理员'); +INSERT INTO `sys_user` VALUES (2, 105, 'niangao', '年糕', '00', 'niangao@qq.com', '16688888888', '0', 'http://127.0.0.1:9099/common/caches?taskId=avatar&filename=ry_avatar.jpeg', '$2b$12$UkNwXNmyQ2RbS1BROXmCRelWLkEgKWQmVsY1S9O1/nZpUSPud1Oz2', '0', '0', '127.0.0.1', '2023-05-23 16:13:33', 'admin', '2023-05-23 16:13:33', 'admin', '2023-05-23 16:13:33', '测试员'); + +-- ---------------------------- +-- Table structure for sys_user_post +-- ---------------------------- +DROP TABLE IF EXISTS `sys_user_post`; +CREATE TABLE `sys_user_post` ( + `user_id` bigint(20) NOT NULL COMMENT '用户ID', + `post_id` bigint(20) NOT NULL COMMENT '岗位ID', + PRIMARY KEY (`user_id`, `post_id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '用户与岗位关联表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_user_post +-- ---------------------------- +INSERT INTO `sys_user_post` VALUES (1, 1); +INSERT INTO `sys_user_post` VALUES (2, 1); + +-- ---------------------------- +-- Table structure for sys_user_role +-- ---------------------------- +DROP TABLE IF EXISTS `sys_user_role`; +CREATE TABLE `sys_user_role` ( + `user_id` bigint(20) NOT NULL COMMENT '用户ID', + `role_id` bigint(20) NOT NULL COMMENT '角色ID', + PRIMARY KEY (`user_id`, `role_id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '用户和角色关联表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sys_user_role +-- ---------------------------- +INSERT INTO `sys_user_role` VALUES (1, 1); +INSERT INTO `sys_user_role` VALUES (2, 2); + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/dash-fastapi-backend/utils/common_util.py b/dash-fastapi-backend/utils/common_util.py new file mode 100644 index 0000000000000000000000000000000000000000..3715a76de207e8ca9879da8924b6acd279bb0c79 --- /dev/null +++ b/dash-fastapi-backend/utils/common_util.py @@ -0,0 +1,67 @@ +import pandas as pd +import io + + +def worship(): + print(""" +//////////////////////////////////////////////////////////////////// +// _ooOoo_ // +// o8888888o // +// 88" . "88 // +// (| ^_^ |) // +// O\ = /O // +// ____/`---'\____ // +// .' \\| |// `. // +// / \\||| : |||// \ // +// / _||||| -:- |||||- \ // +// | | \\\ - /// | | // +// | \_| ''\---/'' | | // +// \ .-\__ `-` ___/-. / // +// ___`. .' /--.--\ `. . ___ // +// ."" '< `.___\_<|>_/___.' >'"". // +// | | : `- \`.;`\ _ /`;.`/ - ` : | | // +// \ \ `-. \_ __\ /__ _/ .-` / / // +// ========`-.____`-.___\_____/___.-`____.-'======== // +// `=---=' // +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // +// 佛祖保佑 永不宕机 永无BUG // +//////////////////////////////////////////////////////////////////// + """) + + +def bytes2human(n, format_str="%(value).1f%(symbol)s"): + """Used by various scripts. See: + http://goo.gl/zeJZl + + >>> bytes2human(10000) + '9.8K' + >>> bytes2human(100001221) + '95.4M' + """ + symbols = ('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB') + prefix = {} + for i, s in enumerate(symbols[1:]): + prefix[s] = 1 << (i + 1) * 10 + for symbol in reversed(symbols[1:]): + if n >= prefix[symbol]: + value = float(n) / prefix[symbol] + return format_str % locals() + return format_str % dict(symbol=symbols[0], value=n) + + +def bytes2file_response(bytes_info): + yield bytes_info + + +def export_list2excel(list_data: list): + """ + 工具方法:将需要导出的list数据转化为对应excel的二进制数据 + :param list_data: 数据列表 + :return: 字典信息对应excel的二进制数据 + """ + df = pd.DataFrame(list_data) + binary_data = io.BytesIO() + df.to_excel(binary_data, index=False, engine='openpyxl') + binary_data = binary_data.getvalue() + + return binary_data diff --git a/dash-fastapi-backend/module_admin/utils/log_util.py b/dash-fastapi-backend/utils/log_util.py similarity index 100% rename from dash-fastapi-backend/module_admin/utils/log_util.py rename to dash-fastapi-backend/utils/log_util.py diff --git a/dash-fastapi-backend/utils/message_util.py b/dash-fastapi-backend/utils/message_util.py new file mode 100644 index 0000000000000000000000000000000000000000..6a21f88d0e714cd89425c011150122301f9d4e19 --- /dev/null +++ b/dash-fastapi-backend/utils/message_util.py @@ -0,0 +1,5 @@ +from utils.log_util import logger + + +def message_service(sms_code: str): + logger.info(f"短信验证码为{sms_code}") diff --git a/dash-fastapi-backend/module_admin/utils/page_util.py b/dash-fastapi-backend/utils/page_util.py similarity index 49% rename from dash-fastapi-backend/module_admin/utils/page_util.py rename to dash-fastapi-backend/utils/page_util.py index 21ef67e6cead15bdb9912285f21be196c08817a9..dd780214ee1b070e103a64c06e4461e6f0b07a6a 100644 --- a/dash-fastapi-backend/module_admin/utils/page_util.py +++ b/dash-fastapi-backend/utils/page_util.py @@ -1,3 +1,6 @@ +import math +from typing import List + from pydantic import BaseModel @@ -12,6 +15,17 @@ class PageModel(BaseModel): has_next: bool +class PageObjectResponse(BaseModel): + """ + 用户管理列表分页查询返回模型 + """ + rows: List = [] + page_num: int + page_size: int + total: int + has_next: bool + + def get_page_info(offset: int, page_num: int, page_size: int, count: int): """ 根据分页参数获取分页信息 @@ -39,3 +53,32 @@ def get_page_info(offset: int, page_num: int, page_size: int, count: int): result = dict(offset=res_offset, page_num=res_page_num, page_size=page_size, total=count, has_next=has_next) return PageModel(**result) + + +def get_page_obj(data_list: List, page_num: int, page_size: int): + """ + 输入数据列表data_list和分页信息,返回分页数据列表结果 + :param data_list: 原始数据列表 + :param page_num: 当前页码 + :param page_size: 当前页面数据量 + :return: 分页数据对象 + """ + # 计算起始索引和结束索引 + start = (page_num - 1) * page_size + end = page_num * page_size + + # 根据计算得到的起始索引和结束索引对数据列表进行切片 + paginated_data = data_list[start:end] + has_next = True if math.ceil(len(data_list) / page_size) > page_num else False + + result = dict( + rows=paginated_data, + page_num=page_num, + page_size=page_size, + total=len(data_list), + has_next=has_next + ) + + return PageObjectResponse(**result) + + diff --git a/dash-fastapi-backend/utils/pwd_util.py b/dash-fastapi-backend/utils/pwd_util.py new file mode 100644 index 0000000000000000000000000000000000000000..2e9a2f9a72f69f20e819c206ea8eb61258d5de54 --- /dev/null +++ b/dash-fastapi-backend/utils/pwd_util.py @@ -0,0 +1,28 @@ +from passlib.context import CryptContext + +pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") + + +class PwdUtil: + """ + 密码工具类 + """ + + @classmethod + def verify_password(cls, plain_password, hashed_password): + """ + 工具方法:校验当前输入的密码与数据库存储的密码是否一致 + :param plain_password: 当前输入的密码 + :param hashed_password: 数据库存储的密码 + :return: 校验结果 + """ + return pwd_context.verify(plain_password, hashed_password) + + @classmethod + def get_password_hash(cls, input_password): + """ + 工具方法:对当前输入的密码进行加密 + :param input_password: 输入的密码 + :return: 加密成功的密码 + """ + return pwd_context.hash(input_password) diff --git a/dash-fastapi-backend/module_admin/utils/response_util.py b/dash-fastapi-backend/utils/response_util.py similarity index 67% rename from dash-fastapi-backend/module_admin/utils/response_util.py rename to dash-fastapi-backend/utils/response_util.py index 614061153dec2a17618c96d7b258baa3400d32dd..cf0e8ba904fe041a958d7d31c717c3ca0dc6130f 100644 --- a/dash-fastapi-backend/module_admin/utils/response_util.py +++ b/dash-fastapi-backend/utils/response_util.py @@ -1,11 +1,11 @@ from fastapi import status -from fastapi.responses import JSONResponse, Response +from fastapi.responses import JSONResponse, Response, StreamingResponse from fastapi.encoders import jsonable_encoder -from typing import Union +from typing import Any from datetime import datetime -def response_200(*, data: Union[list, dict, str], message="获取成功") -> Response: +def response_200(*, data: Any = None, message="获取成功") -> Response: return JSONResponse( status_code=status.HTTP_200_OK, content=jsonable_encoder( @@ -20,10 +20,10 @@ def response_200(*, data: Union[list, dict, str], message="获取成功") -> Res ) -def response_400(*, data: str = None, message: str = "获取失败") -> Response: +def response_400(*, data: Any = None, message: str = "获取失败") -> Response: return JSONResponse( status_code=status.HTTP_400_BAD_REQUEST, - content=( + content=jsonable_encoder( { 'code': 400, 'message': message, @@ -35,10 +35,10 @@ def response_400(*, data: str = None, message: str = "获取失败") -> Response ) -def response_401(*, data: str = None, message: str = "获取失败") -> Response: +def response_401(*, data: Any = None, message: str = "获取失败") -> Response: return JSONResponse( status_code=status.HTTP_401_UNAUTHORIZED, - content=( + content=jsonable_encoder( { 'code': 401, 'message': message, @@ -50,10 +50,10 @@ def response_401(*, data: str = None, message: str = "获取失败") -> Response ) -def response_500(*, data: str = None, message: str = "接口异常") -> Response: +def response_500(*, data: Any = None, message: str = "接口异常") -> Response: return JSONResponse( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - content=( + content=jsonable_encoder( { 'code': 500, 'message': message, @@ -63,6 +63,13 @@ def response_500(*, data: str = None, message: str = "接口异常") -> Response } ) ) + + +def streaming_response_200(*, data: Any = None): + return StreamingResponse( + status_code=status.HTTP_200_OK, + content=data, + ) class AuthException(Exception): @@ -72,3 +79,12 @@ class AuthException(Exception): def __init__(self, data: str = None, message: str = None): self.data = data self.message = message + + +class LoginException(Exception): + """ + 自定义登录异常LoginException + """ + def __init__(self, data: str = None, message: str = None): + self.data = data + self.message = message diff --git a/dash-fastapi-backend/module_admin/utils/time_format_util.py b/dash-fastapi-backend/utils/time_format_util.py similarity index 100% rename from dash-fastapi-backend/module_admin/utils/time_format_util.py rename to dash-fastapi-backend/utils/time_format_util.py diff --git a/dash-fastapi-frontend/api/cache.py b/dash-fastapi-frontend/api/cache.py new file mode 100644 index 0000000000000000000000000000000000000000..2cb2d2bbd8e2d380dfc6a129c6b4bae2fdf21ce8 --- /dev/null +++ b/dash-fastapi-frontend/api/cache.py @@ -0,0 +1,6 @@ +from utils.request import api_request + + +def get_cache_statistical_info_api(): + + return api_request(method='post', url='/monitor/cache/statisticalInfo', is_headers=True) diff --git a/dash-fastapi-frontend/api/config.py b/dash-fastapi-frontend/api/config.py new file mode 100644 index 0000000000000000000000000000000000000000..f092b8d1fe427b6da1df3633722e9f49183cbabd --- /dev/null +++ b/dash-fastapi-frontend/api/config.py @@ -0,0 +1,41 @@ +from utils.request import api_request + + +def get_config_list_api(page_obj: dict): + + return api_request(method='post', url='/system/config/get', is_headers=True, json=page_obj) + + +def query_config_list_api(config_key: str): + + return api_request(method='get', url=f'/common/config/query/{config_key}', is_headers=False) + + +def add_config_api(page_obj: dict): + + return api_request(method='post', url='/system/config/add', is_headers=True, json=page_obj) + + +def edit_config_api(page_obj: dict): + + return api_request(method='patch', url='/system/config/edit', is_headers=True, json=page_obj) + + +def delete_config_api(page_obj: dict): + + return api_request(method='post', url='/system/config/delete', is_headers=True, json=page_obj) + + +def get_config_detail_api(config_id: int): + + return api_request(method='get', url=f'/system/config/{config_id}', is_headers=True) + + +def export_config_list_api(page_obj: dict): + + return api_request(method='post', url='/system/config/export', is_headers=True, json=page_obj, stream=True) + + +def refresh_config_api(page_obj: dict): + + return api_request(method='post', url='/system/config/refresh', is_headers=True, json=page_obj) diff --git a/dash-fastapi-frontend/api/dict.py b/dash-fastapi-frontend/api/dict.py new file mode 100644 index 0000000000000000000000000000000000000000..92eca5f1801041847d90776fe17ee22556dbaa37 --- /dev/null +++ b/dash-fastapi-frontend/api/dict.py @@ -0,0 +1,76 @@ +from utils.request import api_request + + +def get_dict_type_list_api(page_obj: dict): + + return api_request(method='post', url='/system/dictType/get', is_headers=True, json=page_obj) + + +def get_all_dict_type_api(page_obj: dict): + + return api_request(method='post', url='/system/dictType/all', is_headers=True, json=page_obj) + + +def add_dict_type_api(page_obj: dict): + + return api_request(method='post', url='/system/dictType/add', is_headers=True, json=page_obj) + + +def edit_dict_type_api(page_obj: dict): + + return api_request(method='patch', url='/system/dictType/edit', is_headers=True, json=page_obj) + + +def delete_dict_type_api(page_obj: dict): + + return api_request(method='post', url='/system/dictType/delete', is_headers=True, json=page_obj) + + +def get_dict_type_detail_api(dict_id: int): + + return api_request(method='get', url=f'/system/dictType/{dict_id}', is_headers=True) + + +def export_dict_type_list_api(page_obj: dict): + + return api_request(method='post', url='/system/dictType/export', is_headers=True, json=page_obj, stream=True) + + +def refresh_dict_api(page_obj: dict): + + return api_request(method='post', url='/system/dictType/refresh', is_headers=True, json=page_obj) + + +def get_dict_data_list_api(page_obj: dict): + + return api_request(method='post', url='/system/dictData/get', is_headers=True, json=page_obj) + + +def query_dict_data_list_api(dict_type: str): + + return api_request(method='get', url=f'/system/dictData/query/{dict_type}', is_headers=True) + + +def add_dict_data_api(page_obj: dict): + + return api_request(method='post', url='/system/dictData/add', is_headers=True, json=page_obj) + + +def edit_dict_data_api(page_obj: dict): + + return api_request(method='patch', url='/system/dictData/edit', is_headers=True, json=page_obj) + + +def delete_dict_data_api(page_obj: dict): + + return api_request(method='post', url='/system/dictData/delete', is_headers=True, json=page_obj) + + +def get_dict_data_detail_api(dict_code: int): + + return api_request(method='get', url=f'/system/dictData/{dict_code}', is_headers=True) + + +def export_dict_data_list_api(page_obj: dict): + + return api_request(method='post', url='/system/dictData/export', is_headers=True, json=page_obj, stream=True) diff --git a/dash-fastapi-frontend/api/job.py b/dash-fastapi-frontend/api/job.py new file mode 100644 index 0000000000000000000000000000000000000000..5c125c95e641f75e511079f755a4bd789b67c08a --- /dev/null +++ b/dash-fastapi-frontend/api/job.py @@ -0,0 +1,61 @@ +from utils.request import api_request + + +def get_job_list_api(page_obj: dict): + + return api_request(method='post', url='/monitor/job/get', is_headers=True, json=page_obj) + + +def add_job_api(page_obj: dict): + + return api_request(method='post', url='/monitor/job/add', is_headers=True, json=page_obj) + + +def edit_job_api(page_obj: dict): + + return api_request(method='patch', url='/monitor/job/edit', is_headers=True, json=page_obj) + + +def execute_job_api(page_obj: dict): + + return api_request(method='post', url='/monitor/job/changeStatus', is_headers=True, json=page_obj) + + +def delete_job_api(page_obj: dict): + + return api_request(method='post', url='/monitor/job/delete', is_headers=True, json=page_obj) + + +def get_job_detail_api(job_id: int): + + return api_request(method='get', url=f'/monitor/job/{job_id}', is_headers=True) + + +def export_job_list_api(page_obj: dict): + + return api_request(method='post', url='/monitor/job/export', is_headers=True, json=page_obj, stream=True) + + +def get_job_log_list_api(page_obj: dict): + + return api_request(method='post', url='/monitor/jobLog/get', is_headers=True, json=page_obj) + + +def delete_job_log_api(page_obj: dict): + + return api_request(method='post', url='/monitor/jobLog/delete', is_headers=True, json=page_obj) + + +def clear_job_log_api(page_obj: dict): + + return api_request(method='post', url='/monitor/jobLog/clear', is_headers=True, json=page_obj) + + +def get_job_log_detail_api(job_log_id: int): + + return api_request(method='get', url=f'/monitor/jobLog/{job_log_id}', is_headers=True) + + +def export_job_log_list_api(page_obj: dict): + + return api_request(method='post', url='/monitor/jobLog/export', is_headers=True, json=page_obj, stream=True) diff --git a/dash-fastapi-frontend/api/log.py b/dash-fastapi-frontend/api/log.py new file mode 100644 index 0000000000000000000000000000000000000000..a58704e8c668244687a2f0d80075b2adc7940b2f --- /dev/null +++ b/dash-fastapi-frontend/api/log.py @@ -0,0 +1,51 @@ +from utils.request import api_request + + +def get_operation_log_list_api(page_obj: dict): + + return api_request(method='post', url='/system/log/operation/get', is_headers=True, json=page_obj) + + +def delete_operation_log_api(page_obj: dict): + + return api_request(method='post', url='/system/log/operation/delete', is_headers=True, json=page_obj) + + +def clear_operation_log_api(page_obj: dict): + + return api_request(method='post', url='/system/log/operation/clear', is_headers=True, json=page_obj) + + +def export_operation_log_list_api(page_obj: dict): + + return api_request(method='post', url='/system/log/operation/export', is_headers=True, json=page_obj, stream=True) + + +def get_operation_log_detail_api(oper_id: int): + + return api_request(method='get', url=f'/system/log/operation/{oper_id}', is_headers=True) + + +def get_login_log_list_api(page_obj: dict): + + return api_request(method='post', url='/system/log/login/get', is_headers=True, json=page_obj) + + +def delete_login_log_api(page_obj: dict): + + return api_request(method='post', url='/system/log/login/delete', is_headers=True, json=page_obj) + + +def clear_login_log_api(page_obj: dict): + + return api_request(method='post', url='/system/log/login/clear', is_headers=True, json=page_obj) + + +def unlock_user_api(page_obj: dict): + + return api_request(method='post', url='/system/log/login/unlock', is_headers=True, json=page_obj) + + +def export_login_log_list_api(page_obj: dict): + + return api_request(method='post', url='/system/log/login/export', is_headers=True, json=page_obj, stream=True) diff --git a/dash-fastapi-frontend/api/login.py b/dash-fastapi-frontend/api/login.py index 0dcaf0d730ccac96da94e14799e684c117625152..fd642f28ded29062ca5977ef58b10b1fa72b1c2d 100644 --- a/dash-fastapi-frontend/api/login.py +++ b/dash-fastapi-frontend/api/login.py @@ -3,7 +3,12 @@ from utils.request import api_request def login_api(page_obj: dict): - return api_request(method='post', url='/login/loginByAccount', is_headers=False, json=page_obj) + return api_request(method='post', url='/login/loginByAccount', is_headers=False, data=page_obj) + + +def get_captcha_image_api(): + + return api_request(method='post', url='/captcha/captchaImage', is_headers=False) def get_current_user_info_api(): diff --git a/dash-fastapi-frontend/api/message.py b/dash-fastapi-frontend/api/message.py index 72b80d924aab5cfe50e89fc59edb50501f878831..8257f7635c01f4342baf3c7c51326f598c443a72 100644 --- a/dash-fastapi-frontend/api/message.py +++ b/dash-fastapi-frontend/api/message.py @@ -3,4 +3,4 @@ from utils.request import api_request def send_message_api(page_obj: dict): - return api_request(method='post', url='/login/loginByAccount', is_headers=False, json=page_obj) \ No newline at end of file + return api_request(method='post', url='/login/getSmsCode', is_headers=False, json=page_obj) \ No newline at end of file diff --git a/dash-fastapi-frontend/api/notice.py b/dash-fastapi-frontend/api/notice.py new file mode 100644 index 0000000000000000000000000000000000000000..af972ed12c16c7eaae7755b58b2be7f5e7b5233f --- /dev/null +++ b/dash-fastapi-frontend/api/notice.py @@ -0,0 +1,26 @@ +from utils.request import api_request + + +def get_notice_list_api(page_obj: dict): + + return api_request(method='post', url='/system/notice/get', is_headers=True, json=page_obj) + + +def add_notice_api(page_obj: dict): + + return api_request(method='post', url='/system/notice/add', is_headers=True, json=page_obj) + + +def edit_notice_api(page_obj: dict): + + return api_request(method='patch', url='/system/notice/edit', is_headers=True, json=page_obj) + + +def delete_notice_api(page_obj: dict): + + return api_request(method='post', url='/system/notice/delete', is_headers=True, json=page_obj) + + +def get_notice_detail_api(notice_id: int): + + return api_request(method='get', url=f'/system/notice/{notice_id}', is_headers=True) diff --git a/dash-fastapi-frontend/api/online.py b/dash-fastapi-frontend/api/online.py new file mode 100644 index 0000000000000000000000000000000000000000..0504b36774ca4f625f9e082e30eb30f56fc01ad9 --- /dev/null +++ b/dash-fastapi-frontend/api/online.py @@ -0,0 +1,16 @@ +from utils.request import api_request + + +def get_online_list_api(page_obj: dict): + + return api_request(method='post', url='/monitor/online/get', is_headers=True, json=page_obj) + + +def force_logout_online_api(page_obj: dict): + + return api_request(method='post', url='/monitor/online/forceLogout', is_headers=True, json=page_obj) + + +def batch_logout_online_api(page_obj: dict): + + return api_request(method='post', url='/monitor/online/batchLogout', is_headers=True, json=page_obj) diff --git a/dash-fastapi-frontend/api/post.py b/dash-fastapi-frontend/api/post.py index 42277c7ce427d0e8b733f8ffba7fe2f1c83b9ef5..8c058512cf34ea16597a00c829ffcd2a441ef61f 100644 --- a/dash-fastapi-frontend/api/post.py +++ b/dash-fastapi-frontend/api/post.py @@ -29,3 +29,8 @@ def delete_post_api(page_obj: dict): def get_post_detail_api(post_id: int): return api_request(method='get', url=f'/system/post/{post_id}', is_headers=True) + + +def export_post_list_api(page_obj: dict): + + return api_request(method='post', url='/system/post/export', is_headers=True, json=page_obj, stream=True) diff --git a/dash-fastapi-frontend/api/role.py b/dash-fastapi-frontend/api/role.py index 9cafd615253d3cc183109a9e7e65a62dd6b798d9..8526d2bfae1af6a565c045f29113c06f8fb3aeac 100644 --- a/dash-fastapi-frontend/api/role.py +++ b/dash-fastapi-frontend/api/role.py @@ -29,3 +29,8 @@ def delete_role_api(page_obj: dict): def get_role_detail_api(role_id: int): return api_request(method='get', url=f'/system/role/{role_id}', is_headers=True) + + +def export_role_list_api(page_obj: dict): + + return api_request(method='post', url='/system/role/export', is_headers=True, json=page_obj, stream=True) diff --git a/dash-fastapi-frontend/api/server.py b/dash-fastapi-frontend/api/server.py new file mode 100644 index 0000000000000000000000000000000000000000..9e8e3eb83ad468d37f7d06d0900e0978a240e6d8 --- /dev/null +++ b/dash-fastapi-frontend/api/server.py @@ -0,0 +1,6 @@ +from utils.request import api_request + + +def get_server_statistical_info_api(): + + return api_request(method='post', url='/monitor/server/statisticalInfo', is_headers=True) diff --git a/dash-fastapi-frontend/api/user.py b/dash-fastapi-frontend/api/user.py index 2edf88d837484bcc542e99abd77e7c98cc6e0ec2..e931802ab5bf4fb016b5684cebd6b4d4d2909e8e 100644 --- a/dash-fastapi-frontend/api/user.py +++ b/dash-fastapi-frontend/api/user.py @@ -1,9 +1,9 @@ from utils.request import api_request -def change_password_api(page_obj: dict): +def forget_user_pwd_api(page_obj: dict): - return api_request(method='post', url='/login/loginByAccount', is_headers=False, json=page_obj) + return api_request(method='post', url='/login/forgetPwd', is_headers=False, json=page_obj) def get_user_list_api(page_obj: dict): @@ -29,3 +29,24 @@ def delete_user_api(page_obj: dict): def get_user_detail_api(user_id: int): return api_request(method='get', url=f'/system/user/{user_id}', is_headers=True) + + +def change_user_avatar_api(page_obj: dict): + + return api_request(method='patch', url='/system/user/profile/changeAvatar', is_headers=True, json=page_obj) + + +def change_user_info_api(page_obj: dict): + + return api_request(method='patch', url='/system/user/profile/changeInfo', is_headers=True, json=page_obj) + + +def reset_user_password_api(page_obj: dict): + + return api_request(method='patch', url='/system/user/profile/resetPwd', is_headers=True, json=page_obj) + + +def export_user_list_api(page_obj: dict): + + return api_request(method='post', url='/system/user/export', is_headers=True, json=page_obj, stream=True) + diff --git a/dash-fastapi-frontend/app.py b/dash-fastapi-frontend/app.py index 6c5a23a7bcf838afcb6e8b2f1a326015da7b0d04..dd9d815c9b4872028ca9f1165d584d6a0d3b8966 100644 --- a/dash-fastapi-frontend/app.py +++ b/dash-fastapi-frontend/app.py @@ -4,9 +4,9 @@ from dash import html, dcc from dash.dependencies import Input, Output, State import feffery_antd_components as fac import feffery_utils_components as fuc -from flask import session, request, json +from flask import session -from server import app, logger, server +from server import app from config.global_config import RouterConfig from store.store import render_store_container @@ -15,7 +15,7 @@ import views from callbacks import app_c from api.login import get_current_user_info_api -from utils.tree_tool import find_node_values, find_key_by_href +from utils.tree_tool import find_node_values, find_key_by_href, deal_user_menu_info, get_search_panel_data app.layout = html.Div( [ @@ -32,6 +32,20 @@ app.layout = html.Div( # 注入页面内容挂载点 html.Div(id='app-mount'), + # 注入全局配置容器 + fac.AntdConfigProvider(id='app-config-provider'), + + # 注入快捷搜索面板 + fuc.FefferyShortcutPanel( + id='search-panel', + data=[], + placeholder='输入你想要搜索的菜单...', + panelStyles={ + 'accentColor': '#1890ff', + 'zIndex': 99999 + } + ), + # 辅助处理多输入 -> 存储接口返回token校验信息 render_store_container(), @@ -66,38 +80,44 @@ app.layout = html.Div( Output('redirect-container', 'children', allow_duplicate=True), Output('global-message-container', 'children', allow_duplicate=True), Output('api-check-token', 'data', allow_duplicate=True), - Output('current-key-container', 'data')], + Output('current-key-container', 'data'), + Output('menu-info-store-container', 'data'), + Output('menu-list-store-container', 'data'), + Output('search-panel', 'data')], Input('url-container', 'pathname'), - State('url-container', 'trigger'), + [State('url-container', 'trigger'), + State('token-container', 'data')], prevent_initial_call=True ) -def router(pathname, trigger): +def router(pathname, trigger, session_token): # 检查当前会话是否已经登录 - token_result = session.get('token') + token_result = session.get('Authorization') # 若已登录 - if token_result: + if token_result and session_token and token_result == session_token: try: current_user_result = get_current_user_info_api() if current_user_result['code'] == 200: current_user = current_user_result['data'] - user_name = current_user['user']['user_name'] - nick_name = current_user['user']['nick_name'] - phone_number = current_user['user']['phonenumber'] - menu_info = current_user['menu'] + menu_list = current_user['menu'] + user_menu_list = [item for item in menu_list if item.get('visible') == '0'] + menu_info = deal_user_menu_info(0, menu_list) + user_menu_info = deal_user_menu_info(0, user_menu_list) + search_panel_data = get_search_panel_data(user_menu_list) session['user_info'] = current_user['user'] session['dept_info'] = current_user['dept'] session['role_info'] = current_user['role'] session['post_info'] = current_user['post'] - session['menu_info'] = menu_info - valid_href_list = find_node_values(menu_info, 'href') - valid_href_list.append('/') + dynamic_valid_pathname_list = find_node_values(menu_info, 'href') + valid_href_list = dynamic_valid_pathname_list + RouterConfig.STATIC_VALID_PATHNAME if pathname in valid_href_list: current_key = find_key_by_href(menu_info, pathname) + if pathname == '/': + current_key = '首页' + if pathname == '/user/profile': + current_key = '个人资料' if trigger == 'load': # 根据pathname控制渲染行为 - if pathname == '/': - current_key = '首页' if pathname == '/login' or pathname == '/forget': # 重定向到主页面 return [ @@ -107,40 +127,37 @@ def router(pathname, trigger): id='router-redirect' ), None, - {'timestamp': time.time()} + {'timestamp': time.time()}, + {'current_key': current_key}, + {'menu_info': menu_info}, + {'menu_list': menu_list}, + search_panel_data ] # 否则正常渲染主页面 return [ - views.layout.render_content(user_name, nick_name, phone_number, menu_info), + views.layout.render_content(user_menu_info), None, fuc.FefferyFancyNotification('进入主页面', type='success', autoClose=2000), {'timestamp': time.time()}, - {'current_key': current_key} + {'current_key': current_key}, + {'menu_info': menu_info}, + {'menu_list': menu_list}, + search_panel_data ] - # elif trigger == 'pushstate': else: - if pathname == '/': - current_key = '首页' return [ dash.no_update, None, None, {'timestamp': time.time()}, - {'current_key': current_key} + {'current_key': current_key}, + {'menu_info': menu_info}, + {'menu_list': menu_list}, + search_panel_data ] - # else: - # - # return [ - # dash.no_update, - # dash.no_update, - # dash.no_update, - # {'timestamp': time.time()}, - # dash.no_update - # ] - else: # 渲染404状态页 return [ @@ -148,6 +165,9 @@ def router(pathname, trigger): None, None, {'timestamp': time.time()}, + dash.no_update, + dash.no_update, + dash.no_update, dash.no_update ] @@ -157,6 +177,9 @@ def router(pathname, trigger): dash.no_update, dash.no_update, {'timestamp': time.time()}, + dash.no_update, + dash.no_update, + dash.no_update, dash.no_update ] @@ -168,6 +191,9 @@ def router(pathname, trigger): None, fuc.FefferyFancyNotification('接口异常', type='error', autoClose=2000), {'timestamp': time.time()}, + dash.no_update, + dash.no_update, + dash.no_update, dash.no_update ] else: @@ -181,6 +207,9 @@ def router(pathname, trigger): None, None, {'timestamp': time.time()}, + dash.no_update, + dash.no_update, + dash.no_update, dash.no_update ] @@ -190,6 +219,9 @@ def router(pathname, trigger): None, None, {'timestamp': time.time()}, + dash.no_update, + dash.no_update, + dash.no_update, dash.no_update ] @@ -199,6 +231,9 @@ def router(pathname, trigger): None, None, {'timestamp': time.time()}, + dash.no_update, + dash.no_update, + dash.no_update, dash.no_update ] @@ -211,6 +246,9 @@ def router(pathname, trigger): ), None, {'timestamp': time.time()}, + dash.no_update, + dash.no_update, + dash.no_update, dash.no_update ] diff --git a/dash-fastapi-frontend/assets/css/cropper.min.css b/dash-fastapi-frontend/assets/css/cropper.min.css new file mode 100644 index 0000000000000000000000000000000000000000..e97743ad00e3ee2f10eed53e9c1acb3257422531 --- /dev/null +++ b/dash-fastapi-frontend/assets/css/cropper.min.css @@ -0,0 +1,9 @@ +/*! + * Cropper.js v1.5.13 + * https://fengyuanchen.github.io/cropperjs + * + * Copyright 2015-present Chen Fengyuan + * Released under the MIT license + * + * Date: 2022-11-20T05:30:43.444Z + */.cropper-container{direction:ltr;font-size:0;line-height:0;position:relative;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.cropper-container img{-webkit-backface-visibility:hidden;backface-visibility:hidden;display:block;height:100%;image-orientation:0deg;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;width:100%}.cropper-canvas,.cropper-crop-box,.cropper-drag-box,.cropper-modal,.cropper-wrap-box{bottom:0;left:0;position:absolute;right:0;top:0}.cropper-canvas,.cropper-wrap-box{overflow:hidden}.cropper-drag-box{background-color:#fff;opacity:0}.cropper-modal{background-color:#000;opacity:.5}.cropper-view-box{display:block;height:100%;outline:1px solid #39f;outline-color:rgba(51,153,255,.75);overflow:hidden;width:100%}.cropper-dashed{border:0 dashed #eee;display:block;opacity:.5;position:absolute}.cropper-dashed.dashed-h{border-bottom-width:1px;border-top-width:1px;height:33.33333%;left:0;top:33.33333%;width:100%}.cropper-dashed.dashed-v{border-left-width:1px;border-right-width:1px;height:100%;left:33.33333%;top:0;width:33.33333%}.cropper-center{display:block;height:0;left:50%;opacity:.75;position:absolute;top:50%;width:0}.cropper-center:after,.cropper-center:before{background-color:#eee;content:" ";display:block;position:absolute}.cropper-center:before{height:1px;left:-3px;top:0;width:7px}.cropper-center:after{height:7px;left:0;top:-3px;width:1px}.cropper-face,.cropper-line,.cropper-point{display:block;height:100%;opacity:.1;position:absolute;width:100%}.cropper-face{background-color:#fff;left:0;top:0}.cropper-line{background-color:#39f}.cropper-line.line-e{cursor:ew-resize;right:-3px;top:0;width:5px}.cropper-line.line-n{cursor:ns-resize;height:5px;left:0;top:-3px}.cropper-line.line-w{cursor:ew-resize;left:-3px;top:0;width:5px}.cropper-line.line-s{bottom:-3px;cursor:ns-resize;height:5px;left:0}.cropper-point{background-color:#39f;height:5px;opacity:.75;width:5px}.cropper-point.point-e{cursor:ew-resize;margin-top:-3px;right:-3px;top:50%}.cropper-point.point-n{cursor:ns-resize;left:50%;margin-left:-3px;top:-3px}.cropper-point.point-w{cursor:ew-resize;left:-3px;margin-top:-3px;top:50%}.cropper-point.point-s{bottom:-3px;cursor:s-resize;left:50%;margin-left:-3px}.cropper-point.point-ne{cursor:nesw-resize;right:-3px;top:-3px}.cropper-point.point-nw{cursor:nwse-resize;left:-3px;top:-3px}.cropper-point.point-sw{bottom:-3px;cursor:nesw-resize;left:-3px}.cropper-point.point-se{bottom:-3px;cursor:nwse-resize;height:20px;opacity:1;right:-3px;width:20px}@media (min-width:768px){.cropper-point.point-se{height:15px;width:15px}}@media (min-width:992px){.cropper-point.point-se{height:10px;width:10px}}@media (min-width:1200px){.cropper-point.point-se{height:5px;opacity:.75;width:5px}}.cropper-point.point-se:before{background-color:#39f;bottom:-50%;content:" ";display:block;height:200%;opacity:0;position:absolute;right:-50%;width:200%}.cropper-invisible{opacity:0}.cropper-bg{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC")}.cropper-hide{display:block;height:0;position:absolute;width:0}.cropper-hidden{display:none!important}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed} \ No newline at end of file diff --git a/dash-fastapi-frontend/assets/favicon.ico b/dash-fastapi-frontend/assets/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..e26376026420542212ed58d90d0ed34f554fa4ae Binary files /dev/null and b/dash-fastapi-frontend/assets/favicon.ico differ diff --git a/dash-fastapi-frontend/assets/imgs/logo.png b/dash-fastapi-frontend/assets/imgs/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e26376026420542212ed58d90d0ed34f554fa4ae Binary files /dev/null and b/dash-fastapi-frontend/assets/imgs/logo.png differ diff --git a/dash-fastapi-frontend/assets/js/cache_control_echarts_callbacks.js b/dash-fastapi-frontend/assets/js/cache_control_echarts_callbacks.js new file mode 100644 index 0000000000000000000000000000000000000000..5a466cbd0ed9f3d3927e6ed6282dc558a28a32af --- /dev/null +++ b/dash-fastapi-frontend/assets/js/cache_control_echarts_callbacks.js @@ -0,0 +1,75 @@ +// 在独立js脚本中定义比较长的回调函数 +window.dash_clientside = Object.assign({}, window.dash_clientside, { + clientside_command_stats: { + render_command_stats_chart: function (data) { + + // 根据id初始化绑定图表 + var commandStatsChart = echarts.init(document.getElementById('command-stats-charts-container'), "macarons"); + + const commandStatsOption = { + tooltip: { + trigger: "item", + formatter: "{a}
{b} : {c} ({d}%)", + }, + series: [ + { + name: "命令", + type: "pie", + roseType: "radius", + radius: [35, 115], + center: ["50%", "50%"], + data: data['command_stats'], + animationEasing: "cubicInOut", + animationDuration: 1000, + } + ] + }; + + // 渲染 + commandStatsChart.setOption(commandStatsOption); + window.addEventListener("resize", () => { + commandStatsChart.resize(); + }); + } + } +}); + + +window.dash_clientside = Object.assign({}, window.dash_clientside, { + clientside_memory: { + render_memory_chart: function (data) { + + // 根据id初始化绑定图表 + var memoryChart = echarts.init(document.getElementById('memory-charts-container'), "macarons"); + + const memoryOption = { + tooltip: { + formatter: "{b}
{a} : " + data['used_memory_human'], + }, + series: [ + { + name: "峰值", + type: "gauge", + min: 0, + max: 1000, + detail: { + formatter: data['used_memory_human'], + }, + data: [ + { + value: parseFloat(data['used_memory_human']), + name: "内存消耗", + } + ] + } + ] + }; + + // 渲染 + memoryChart.setOption(memoryOption); + window.addEventListener("resize", () => { + memoryChart.resize(); + }); + } + } +}); \ No newline at end of file diff --git a/dash-fastapi-frontend/assets/js/cropper.min.js b/dash-fastapi-frontend/assets/js/cropper.min.js new file mode 100644 index 0000000000000000000000000000000000000000..03aed4cc9e787b1f75b1cf70d7d30d6787bf5996 --- /dev/null +++ b/dash-fastapi-frontend/assets/js/cropper.min.js @@ -0,0 +1,10 @@ +/*! + * Cropper.js v1.5.13 + * https://fengyuanchen.github.io/cropperjs + * + * Copyright 2015-present Chen Fengyuan + * Released under the MIT license + * + * Date: 2022-11-20T05:30:46.114Z + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Cropper=e()}(this,function(){"use strict";function C(e,t){var i,a=Object.keys(e);return Object.getOwnPropertySymbols&&(i=Object.getOwnPropertySymbols(e),t&&(i=i.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),a.push.apply(a,i)),a}function S(a){for(var t=1;tt.length)&&(e=t.length);for(var i=0,a=new Array(e);it.width?3===i?o=t.height*e:h=t.width/e:3===i?h=t.width/e:o=t.height*e,{aspectRatio:e,naturalWidth:n,naturalHeight:a,width:o,height:h});this.canvasData=e,this.limited=1===i||2===i,this.limitCanvas(!0,!0),e.width=Math.min(Math.max(e.width,e.minWidth),e.maxWidth),e.height=Math.min(Math.max(e.height,e.minHeight),e.maxHeight),e.left=(t.width-e.width)/2,e.top=(t.height-e.height)/2,e.oldLeft=e.left,e.oldTop=e.top,this.initialCanvasData=g({},e)},limitCanvas:function(t,e){var i=this.options,a=this.containerData,n=this.canvasData,o=this.cropBoxData,h=i.viewMode,r=n.aspectRatio,s=this.cropped&&o;t&&(t=Number(i.minCanvasWidth)||0,i=Number(i.minCanvasHeight)||0,1=a.width&&(n.minLeft=Math.min(0,r),n.maxLeft=Math.max(0,r)),n.height>=a.height)&&(n.minTop=Math.min(0,t),n.maxTop=Math.max(0,t))):(n.minLeft=-n.width,n.minTop=-n.height,n.maxLeft=a.width,n.maxTop=a.height))},renderCanvas:function(t,e){var i,a,n,o,h=this.canvasData,r=this.imageData;e&&(e={width:r.naturalWidth*Math.abs(r.scaleX||1),height:r.naturalHeight*Math.abs(r.scaleY||1),degree:r.rotate||0},r=e.width,o=e.height,e=e.degree,i=90==(e=Math.abs(e)%180)?{width:o,height:r}:(a=e%90*Math.PI/180,i=Math.sin(a),n=r*(a=Math.cos(a))+o*i,r=r*i+o*a,90h.maxWidth||h.widthh.maxHeight||h.heighte.width?a.height=a.width/i:a.width=a.height*i),this.cropBoxData=a,this.limitCropBox(!0,!0),a.width=Math.min(Math.max(a.width,a.minWidth),a.maxWidth),a.height=Math.min(Math.max(a.height,a.minHeight),a.maxHeight),a.width=Math.max(a.minWidth,a.width*t),a.height=Math.max(a.minHeight,a.height*t),a.left=e.left+(e.width-a.width)/2,a.top=e.top+(e.height-a.height)/2,a.oldLeft=a.left,a.oldTop=a.top,this.initialCropBoxData=g({},a)},limitCropBox:function(t,e){var i,a,n=this.options,o=this.containerData,h=this.canvasData,r=this.cropBoxData,s=this.limited,c=n.aspectRatio;t&&(t=Number(n.minCropBoxWidth)||0,n=Number(n.minCropBoxHeight)||0,i=s?Math.min(o.width,h.width,h.width+h.left,o.width-h.left):o.width,a=s?Math.min(o.height,h.height,h.height+h.top,o.height-h.top):o.height,t=Math.min(t,o.width),n=Math.min(n,o.height),c&&(t&&n?ti.maxWidth||i.widthi.maxHeight||i.height=e.width&&i.height>=e.height?U:P),f(this.cropBox,g({width:i.width,height:i.height},x({translateX:i.left,translateY:i.top}))),this.cropped&&this.limited&&this.limitCanvas(!0,!0),this.disabled||this.output()},output:function(){this.preview(),y(this.element,_,this.getData())}},i={initPreview:function(){var t=this.element,i=this.crossOrigin,e=this.options.preview,a=i?this.crossOriginUrl:this.url,n=t.alt||"The image to preview",o=document.createElement("img");i&&(o.crossOrigin=i),o.src=a,o.alt=n,this.viewBox.appendChild(o),this.viewBoxImage=o,e&&("string"==typeof(o=e)?o=t.ownerDocument.querySelectorAll(e):e.querySelector&&(o=[e]),z(this.previews=o,function(t){var e=document.createElement("img");w(t,m,{width:t.offsetWidth,height:t.offsetHeight,html:t.innerHTML}),i&&(e.crossOrigin=i),e.src=a,e.alt=n,e.style.cssText='display:block;width:100%;height:auto;min-width:0!important;min-height:0!important;max-width:none!important;max-height:none!important;image-orientation:0deg!important;"',t.innerHTML="",t.appendChild(e)}))},resetPreview:function(){z(this.previews,function(e){var i=Dt(e,m),i=(f(e,{width:i.width,height:i.height}),e.innerHTML=i.html,e),e=m;if(o(i[e]))try{delete i[e]}catch(t){i[e]=void 0}else if(i.dataset)try{delete i.dataset[e]}catch(t){i.dataset[e]=void 0}else i.removeAttribute("data-".concat(Ct(e)))})},preview:function(){var h=this.imageData,t=this.canvasData,e=this.cropBoxData,r=e.width,s=e.height,c=h.width,d=h.height,l=e.left-t.left-h.left,p=e.top-t.top-h.top;this.cropped&&!this.disabled&&(f(this.viewBoxImage,g({width:c,height:d},x(g({translateX:-l,translateY:-p},h)))),z(this.previews,function(t){var e=Dt(t,m),i=e.width,e=e.height,a=i,n=e,o=1;r&&(n=s*(o=i/r)),s&&eMath.abs(a-1)?i:a)&&(t.restore&&(o=this.getCanvasData(),h=this.getCropBoxData()),this.render(),t.restore)&&(this.setCanvasData(z(o,function(t,e){o[e]=t*n})),this.setCropBoxData(z(h,function(t,e){h[e]=t*n}))))},dblclick:function(){var t,e;this.disabled||this.options.dragMode===J||this.setDragMode((t=this.dragBox,e=$,(t.classList?t.classList.contains(e):-1y&&(D.x=y-f);break;case k:p+D.xx&&(D.y=x-v)}}var i,a,o,n=this.options,h=this.canvasData,r=this.containerData,s=this.cropBoxData,c=this.pointers,d=this.action,l=n.aspectRatio,p=s.left,m=s.top,u=s.width,g=s.height,f=p+u,v=m+g,w=0,b=0,y=r.width,x=r.height,M=!0,C=(!l&&t.shiftKey&&(l=u&&g?u/g:1),this.limited&&(w=s.minLeft,b=s.minTop,y=w+Math.min(r.width,h.width,h.left+h.width),x=b+Math.min(r.height,h.height,h.top+h.height)),c[Object.keys(c)[0]]),D={x:C.endX-C.startX,y:C.endY-C.startY};switch(d){case P:p+=D.x,m+=D.y;break;case B:0<=D.x&&(y<=f||l&&(m<=b||x<=v))?M=!1:(e(B),(u+=D.x)<0&&(d=k,p-=u=-u),l&&(m+=(s.height-(g=u/l))/2));break;case T:D.y<=0&&(m<=b||l&&(p<=w||y<=f))?M=!1:(e(T),g-=D.y,m+=D.y,g<0&&(d=O,m-=g=-g),l&&(p+=(s.width-(u=g*l))/2));break;case k:D.x<=0&&(p<=w||l&&(m<=b||x<=v))?M=!1:(e(k),u-=D.x,p+=D.x,u<0&&(d=B,p-=u=-u),l&&(m+=(s.height-(g=u/l))/2));break;case O:0<=D.y&&(x<=v||l&&(p<=w||y<=f))?M=!1:(e(O),(g+=D.y)<0&&(d=T,m-=g=-g),l&&(p+=(s.width-(u=g*l))/2));break;case E:if(l){if(D.y<=0&&(m<=b||y<=f)){M=!1;break}e(T),g-=D.y,m+=D.y,u=g*l}else e(T),e(B),!(0<=D.x)||fMath.abs(o)&&(o=i)})}),o),t),M=!1;break;case I:D.x&&D.y?(i=Et(this.cropper),p=C.startX-i.left,m=C.startY-i.top,u=s.minWidth,g=s.minHeight,0 or element.");this.element=t,this.options=g({},mt,u(e)&&e),this.cropped=!1,this.disabled=!1,this.pointers={},this.ready=!1,this.reloading=!1,this.replaced=!1,this.sized=!1,this.sizing=!1,this.init()}var t,e,i;return t=n,i=[{key:"noConflict",value:function(){return window.Cropper=jt,n}},{key:"setDefaults",value:function(t){g(mt,u(t)&&t)}}],(e=[{key:"init",value:function(){var t,e=this.element,i=e.tagName.toLowerCase();if(!e[c]){if(e[c]=this,"img"===i){if(this.isImg=!0,t=e.getAttribute("src")||"",!(this.originalUrl=t))return;t=e.src}else"canvas"===i&&window.HTMLCanvasElement&&(t=e.toDataURL());this.load(t)}}},{key:"load",value:function(t){var e,i,a,n,o,h,r=this;t&&(this.url=t,this.imageData={},e=this.element,(i=this.options).rotatable||i.scalable||(i.checkOrientation=!1),i.checkOrientation&&window.ArrayBuffer?dt.test(t)?lt.test(t)?this.read((h=(h=t).replace(Yt,""),a=atob(h),h=new ArrayBuffer(a.length),z(n=new Uint8Array(h),function(t,e){n[e]=a.charCodeAt(e)}),h)):this.clone():(o=new XMLHttpRequest,h=this.clone.bind(this),this.reloading=!0,(this.xhr=o).onabort=h,o.onerror=h,o.ontimeout=h,o.onprogress=function(){o.getResponseHeader("content-type")!==st&&o.abort()},o.onload=function(){r.read(o.response)},o.onloadend=function(){r.reloading=!1,r.xhr=null},i.checkCrossOrigin&&Nt(t)&&e.crossOrigin&&(t=Lt(t)),o.open("GET",t,!0),o.responseType="arraybuffer",o.withCredentials="use-credentials"===e.crossOrigin,o.send()):this.clone())}},{key:"read",value:function(t){var e=this.options,i=this.imageData,a=Xt(t),n=0,o=1,h=1;1
',o=(n=n.querySelector(".".concat(c,"-container"))).querySelector(".".concat(c,"-canvas")),h=n.querySelector(".".concat(c,"-drag-box")),s=(r=n.querySelector(".".concat(c,"-crop-box"))).querySelector(".".concat(c,"-face")),this.container=a,this.cropper=n,this.canvas=o,this.dragBox=h,this.cropBox=r,this.viewBox=n.querySelector(".".concat(c,"-view-box")),this.face=s,o.appendChild(i),v(t,L),a.insertBefore(n,t.nextSibling),X(i,K),this.initPreview(),this.bind(),e.initialAspectRatio=Math.max(0,e.initialAspectRatio)||NaN,e.aspectRatio=Math.max(0,e.aspectRatio)||NaN,e.viewMode=Math.max(0,Math.min(3,Math.round(e.viewMode)))||0,v(r,L),e.guides||v(r.getElementsByClassName("".concat(c,"-dashed")),L),e.center||v(r.getElementsByClassName("".concat(c,"-center")),L),e.background&&v(n,"".concat(c,"-bg")),e.highlight||v(s,Z),e.cropBoxMovable&&(v(s,G),w(s,d,P)),e.cropBoxResizable||(v(r.getElementsByClassName("".concat(c,"-line")),L),v(r.getElementsByClassName("".concat(c,"-point")),L)),this.render(),this.ready=!0,this.setDragMode(e.dragMode),e.autoCrop&&this.crop(),this.setData(e.data),l(e.ready)&&b(t,"ready",e.ready,{once:!0}),y(t,"ready"))}},{key:"unbuild",value:function(){var t;this.ready&&(this.ready=!1,this.unbind(),this.resetPreview(),(t=this.cropper.parentNode)&&t.removeChild(this.cropper),X(this.element,L))}},{key:"uncreate",value:function(){this.ready?(this.unbuild(),this.ready=!1,this.cropped=!1):this.sizing?(this.sizingImage.onload=null,this.sizing=!1,this.sized=!1):this.reloading?(this.xhr.onabort=null,this.xhr.abort()):this.image&&this.stop()}}])&&A(t.prototype,e),i&&A(t,i),Object.defineProperty(t,"prototype",{writable:!1}),n}();return g(Pt.prototype,t,i,e,Rt,St,At),Pt}); \ No newline at end of file diff --git a/dash-fastapi-frontend/assets/js/echarts.min.js b/dash-fastapi-frontend/assets/js/echarts.min.js new file mode 100644 index 0000000000000000000000000000000000000000..9260d807497bd68977e0900b110c3f4732c4b7fe --- /dev/null +++ b/dash-fastapi-frontend/assets/js/echarts.min.js @@ -0,0 +1,45 @@ + +/* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).echarts={})}(this,(function(t){"use strict"; +/*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */var e=function(t,n){return e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])},e(t,n)};function n(t,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function i(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}var i=function(){this.firefox=!1,this.ie=!1,this.edge=!1,this.newEdge=!1,this.weChat=!1},r=new function(){this.browser=new i,this.node=!1,this.wxa=!1,this.worker=!1,this.svgSupported=!1,this.touchEventsSupported=!1,this.pointerEventsSupported=!1,this.domSupported=!1,this.transformSupported=!1,this.transform3dSupported=!1,this.hasGlobalWindow="undefined"!=typeof window};"object"==typeof wx&&"function"==typeof wx.getSystemInfoSync?(r.wxa=!0,r.touchEventsSupported=!0):"undefined"==typeof document&&"undefined"!=typeof self?r.worker=!0:"undefined"==typeof navigator?(r.node=!0,r.svgSupported=!0):function(t,e){var n=e.browser,i=t.match(/Firefox\/([\d.]+)/),r=t.match(/MSIE\s([\d.]+)/)||t.match(/Trident\/.+?rv:(([\d.]+))/),o=t.match(/Edge?\/([\d.]+)/),a=/micromessenger/i.test(t);i&&(n.firefox=!0,n.version=i[1]);r&&(n.ie=!0,n.version=r[1]);o&&(n.edge=!0,n.version=o[1],n.newEdge=+o[1].split(".")[0]>18);a&&(n.weChat=!0);e.svgSupported="undefined"!=typeof SVGRect,e.touchEventsSupported="ontouchstart"in window&&!n.ie&&!n.edge,e.pointerEventsSupported="onpointerdown"in window&&(n.edge||n.ie&&+n.version>=11),e.domSupported="undefined"!=typeof document;var s=document.documentElement.style;e.transform3dSupported=(n.ie&&"transition"in s||n.edge||"WebKitCSSMatrix"in window&&"m11"in new WebKitCSSMatrix||"MozPerspective"in s)&&!("OTransition"in s),e.transformSupported=e.transform3dSupported||n.ie&&+n.version>=9}(navigator.userAgent,r);var o="sans-serif",a="12px sans-serif";var s,l,u=function(t){var e={};if("undefined"==typeof JSON)return e;for(var n=0;n=0)o=r*t.length;else for(var c=0;c>1)%2;a.style.cssText=["position: absolute","visibility: hidden","padding: 0","margin: 0","border-width: 0","user-select: none","width:0","height:0",i[s]+":0",r[l]+":0",i[1-s]+":auto",r[1-l]+":auto",""].join("!important;"),t.appendChild(a),n.push(a)}return n}(e,a),l=function(t,e,n){for(var i=n?"invTrans":"trans",r=e[i],o=e.srcCoords,a=[],s=[],l=!0,u=0;u<4;u++){var h=t[u].getBoundingClientRect(),c=2*u,p=h.left,d=h.top;a.push(p,d),l=l&&o&&p===o[c]&&d===o[c+1],s.push(t[u].offsetLeft,t[u].offsetTop)}return l&&r?r:(e.srcCoords=a,e[i]=n?qt(s,a):qt(a,s))}(s,a,o);if(l)return l(t,n,i),!0}return!1}function Jt(t){return"CANVAS"===t.nodeName.toUpperCase()}var Qt=/([&<>"'])/g,te={"&":"&","<":"<",">":">",'"':""","'":"'"};function ee(t){return null==t?"":(t+"").replace(Qt,(function(t,e){return te[e]}))}var ne=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ie=[],re=r.browser.firefox&&+r.browser.version.split(".")[0]<39;function oe(t,e,n,i){return n=n||{},i?ae(t,e,n):re&&null!=e.layerX&&e.layerX!==e.offsetX?(n.zrX=e.layerX,n.zrY=e.layerY):null!=e.offsetX?(n.zrX=e.offsetX,n.zrY=e.offsetY):ae(t,e,n),n}function ae(t,e,n){if(r.domSupported&&t.getBoundingClientRect){var i=e.clientX,o=e.clientY;if(Jt(t)){var a=t.getBoundingClientRect();return n.zrX=i-a.left,void(n.zrY=o-a.top)}if($t(ie,t,i,o))return n.zrX=ie[0],void(n.zrY=ie[1])}n.zrX=n.zrY=0}function se(t){return t||window.event}function le(t,e,n){if(null!=(e=se(e)).zrX)return e;var i=e.type;if(i&&i.indexOf("touch")>=0){var r="touchend"!==i?e.targetTouches[0]:e.changedTouches[0];r&&oe(t,r,e,n)}else{oe(t,e,e,n);var o=function(t){var e=t.wheelDelta;if(e)return e;var n=t.deltaX,i=t.deltaY;if(null==n||null==i)return e;return 3*(0!==i?Math.abs(i):Math.abs(n))*(i>0?-1:i<0?1:n>0?-1:1)}(e);e.zrDelta=o?o/120:-(e.detail||0)/3}var a=e.button;return null==e.which&&void 0!==a&&ne.test(e.type)&&(e.which=1&a?1:2&a?3:4&a?2:0),e}function ue(t,e,n,i){t.addEventListener(e,n,i)}var he=function(t){t.preventDefault(),t.stopPropagation(),t.cancelBubble=!0};function ce(t){return 2===t.which||3===t.which}var pe=function(){function t(){this._track=[]}return t.prototype.recognize=function(t,e,n){return this._doTrack(t,e,n),this._recognize(t)},t.prototype.clear=function(){return this._track.length=0,this},t.prototype._doTrack=function(t,e,n){var i=t.touches;if(i){for(var r={points:[],touches:[],target:e,event:t},o=0,a=i.length;o1&&r&&r.length>1){var a=de(r)/de(o);!isFinite(a)&&(a=1),e.pinchScale=a;var s=[((i=r)[0][0]+i[1][0])/2,(i[0][1]+i[1][1])/2];return e.pinchX=s[0],e.pinchY=s[1],{type:"pinch",target:t[0].target,event:e}}}}};function ge(){return[1,0,0,1,0,0]}function ye(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t}function ve(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t}function me(t,e,n){var i=e[0]*n[0]+e[2]*n[1],r=e[1]*n[0]+e[3]*n[1],o=e[0]*n[2]+e[2]*n[3],a=e[1]*n[2]+e[3]*n[3],s=e[0]*n[4]+e[2]*n[5]+e[4],l=e[1]*n[4]+e[3]*n[5]+e[5];return t[0]=i,t[1]=r,t[2]=o,t[3]=a,t[4]=s,t[5]=l,t}function xe(t,e,n){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4]+n[0],t[5]=e[5]+n[1],t}function _e(t,e,n){var i=e[0],r=e[2],o=e[4],a=e[1],s=e[3],l=e[5],u=Math.sin(n),h=Math.cos(n);return t[0]=i*h+a*u,t[1]=-i*u+a*h,t[2]=r*h+s*u,t[3]=-r*u+h*s,t[4]=h*o+u*l,t[5]=h*l-u*o,t}function be(t,e,n){var i=n[0],r=n[1];return t[0]=e[0]*i,t[1]=e[1]*r,t[2]=e[2]*i,t[3]=e[3]*r,t[4]=e[4]*i,t[5]=e[5]*r,t}function we(t,e){var n=e[0],i=e[2],r=e[4],o=e[1],a=e[3],s=e[5],l=n*a-o*i;return l?(l=1/l,t[0]=a*l,t[1]=-o*l,t[2]=-i*l,t[3]=n*l,t[4]=(i*s-a*r)*l,t[5]=(o*r-n*s)*l,t):null}function Se(t){var e=[1,0,0,1,0,0];return ve(e,t),e}var Me=Object.freeze({__proto__:null,create:ge,identity:ye,copy:ve,mul:me,translate:xe,rotate:_e,scale:be,invert:we,clone:Se}),Ie=function(){function t(t,e){this.x=t||0,this.y=e||0}return t.prototype.copy=function(t){return this.x=t.x,this.y=t.y,this},t.prototype.clone=function(){return new t(this.x,this.y)},t.prototype.set=function(t,e){return this.x=t,this.y=e,this},t.prototype.equal=function(t){return t.x===this.x&&t.y===this.y},t.prototype.add=function(t){return this.x+=t.x,this.y+=t.y,this},t.prototype.scale=function(t){this.x*=t,this.y*=t},t.prototype.scaleAndAdd=function(t,e){this.x+=t.x*e,this.y+=t.y*e},t.prototype.sub=function(t){return this.x-=t.x,this.y-=t.y,this},t.prototype.dot=function(t){return this.x*t.x+this.y*t.y},t.prototype.len=function(){return Math.sqrt(this.x*this.x+this.y*this.y)},t.prototype.lenSquare=function(){return this.x*this.x+this.y*this.y},t.prototype.normalize=function(){var t=this.len();return this.x/=t,this.y/=t,this},t.prototype.distance=function(t){var e=this.x-t.x,n=this.y-t.y;return Math.sqrt(e*e+n*n)},t.prototype.distanceSquare=function(t){var e=this.x-t.x,n=this.y-t.y;return e*e+n*n},t.prototype.negate=function(){return this.x=-this.x,this.y=-this.y,this},t.prototype.transform=function(t){if(t){var e=this.x,n=this.y;return this.x=t[0]*e+t[2]*n+t[4],this.y=t[1]*e+t[3]*n+t[5],this}},t.prototype.toArray=function(t){return t[0]=this.x,t[1]=this.y,t},t.prototype.fromArray=function(t){this.x=t[0],this.y=t[1]},t.set=function(t,e,n){t.x=e,t.y=n},t.copy=function(t,e){t.x=e.x,t.y=e.y},t.len=function(t){return Math.sqrt(t.x*t.x+t.y*t.y)},t.lenSquare=function(t){return t.x*t.x+t.y*t.y},t.dot=function(t,e){return t.x*e.x+t.y*e.y},t.add=function(t,e,n){t.x=e.x+n.x,t.y=e.y+n.y},t.sub=function(t,e,n){t.x=e.x-n.x,t.y=e.y-n.y},t.scale=function(t,e,n){t.x=e.x*n,t.y=e.y*n},t.scaleAndAdd=function(t,e,n,i){t.x=e.x+n.x*i,t.y=e.y+n.y*i},t.lerp=function(t,e,n,i){var r=1-i;t.x=r*e.x+i*n.x,t.y=r*e.y+i*n.y},t}(),Te=Math.min,Ce=Math.max,De=new Ie,Ae=new Ie,ke=new Ie,Le=new Ie,Pe=new Ie,Oe=new Ie,Re=function(){function t(t,e,n,i){n<0&&(t+=n,n=-n),i<0&&(e+=i,i=-i),this.x=t,this.y=e,this.width=n,this.height=i}return t.prototype.union=function(t){var e=Te(t.x,this.x),n=Te(t.y,this.y);isFinite(this.x)&&isFinite(this.width)?this.width=Ce(t.x+t.width,this.x+this.width)-e:this.width=t.width,isFinite(this.y)&&isFinite(this.height)?this.height=Ce(t.y+t.height,this.y+this.height)-n:this.height=t.height,this.x=e,this.y=n},t.prototype.applyTransform=function(e){t.applyTransform(this,this,e)},t.prototype.calculateTransform=function(t){var e=this,n=t.width/e.width,i=t.height/e.height,r=[1,0,0,1,0,0];return xe(r,r,[-e.x,-e.y]),be(r,r,[n,i]),xe(r,r,[t.x,t.y]),r},t.prototype.intersect=function(e,n){if(!e)return!1;e instanceof t||(e=t.create(e));var i=this,r=i.x,o=i.x+i.width,a=i.y,s=i.y+i.height,l=e.x,u=e.x+e.width,h=e.y,c=e.y+e.height,p=!(of&&(f=x,gf&&(f=_,v=n.x&&t<=n.x+n.width&&e>=n.y&&e<=n.y+n.height},t.prototype.clone=function(){return new t(this.x,this.y,this.width,this.height)},t.prototype.copy=function(e){t.copy(this,e)},t.prototype.plain=function(){return{x:this.x,y:this.y,width:this.width,height:this.height}},t.prototype.isFinite=function(){return isFinite(this.x)&&isFinite(this.y)&&isFinite(this.width)&&isFinite(this.height)},t.prototype.isZero=function(){return 0===this.width||0===this.height},t.create=function(e){return new t(e.x,e.y,e.width,e.height)},t.copy=function(t,e){t.x=e.x,t.y=e.y,t.width=e.width,t.height=e.height},t.applyTransform=function(e,n,i){if(i){if(i[1]<1e-5&&i[1]>-1e-5&&i[2]<1e-5&&i[2]>-1e-5){var r=i[0],o=i[3],a=i[4],s=i[5];return e.x=n.x*r+a,e.y=n.y*o+s,e.width=n.width*r,e.height=n.height*o,e.width<0&&(e.x+=e.width,e.width=-e.width),void(e.height<0&&(e.y+=e.height,e.height=-e.height))}De.x=ke.x=n.x,De.y=Le.y=n.y,Ae.x=Le.x=n.x+n.width,Ae.y=ke.y=n.y+n.height,De.transform(i),Le.transform(i),Ae.transform(i),ke.transform(i),e.x=Te(De.x,Ae.x,ke.x,Le.x),e.y=Te(De.y,Ae.y,ke.y,Le.y);var l=Ce(De.x,Ae.x,ke.x,Le.x),u=Ce(De.y,Ae.y,ke.y,Le.y);e.width=l-e.x,e.height=u-e.y}else e!==n&&t.copy(e,n)},t}(),Ne="silent";function Ee(){he(this.event)}var ze=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.handler=null,e}return n(e,t),e.prototype.dispose=function(){},e.prototype.setCursor=function(){},e}(Xt),Ve=function(t,e){this.x=t,this.y=e},Be=["click","dblclick","mousewheel","mouseout","mouseup","mousedown","mousemove","contextmenu"],Fe=new Re(0,0,0,0),Ge=function(t){function e(e,n,i,r,o){var a=t.call(this)||this;return a._hovered=new Ve(0,0),a.storage=e,a.painter=n,a.painterRoot=r,a._pointerSize=o,i=i||new ze,a.proxy=null,a.setHandlerProxy(i),a._draggingMgr=new Ut(a),a}return n(e,t),e.prototype.setHandlerProxy=function(t){this.proxy&&this.proxy.dispose(),t&&(E(Be,(function(e){t.on&&t.on(e,this[e],this)}),this),t.handler=this),this.proxy=t},e.prototype.mousemove=function(t){var e=t.zrX,n=t.zrY,i=Ye(this,e,n),r=this._hovered,o=r.target;o&&!o.__zr&&(o=(r=this.findHover(r.x,r.y)).target);var a=this._hovered=i?new Ve(e,n):this.findHover(e,n),s=a.target,l=this.proxy;l.setCursor&&l.setCursor(s?s.cursor:"default"),o&&s!==o&&this.dispatchToElement(r,"mouseout",t),this.dispatchToElement(a,"mousemove",t),s&&s!==o&&this.dispatchToElement(a,"mouseover",t)},e.prototype.mouseout=function(t){var e=t.zrEventControl;"only_globalout"!==e&&this.dispatchToElement(this._hovered,"mouseout",t),"no_globalout"!==e&&this.trigger("globalout",{type:"globalout",event:t})},e.prototype.resize=function(){this._hovered=new Ve(0,0)},e.prototype.dispatch=function(t,e){var n=this[t];n&&n.call(this,e)},e.prototype.dispose=function(){this.proxy.dispose(),this.storage=null,this.proxy=null,this.painter=null},e.prototype.setCursorStyle=function(t){var e=this.proxy;e.setCursor&&e.setCursor(t)},e.prototype.dispatchToElement=function(t,e,n){var i=(t=t||{}).target;if(!i||!i.silent){for(var r="on"+e,o=function(t,e,n){return{type:t,event:n,target:e.target,topTarget:e.topTarget,cancelBubble:!1,offsetX:n.zrX,offsetY:n.zrY,gestureEvent:n.gestureEvent,pinchX:n.pinchX,pinchY:n.pinchY,pinchScale:n.pinchScale,wheelDelta:n.zrDelta,zrByTouch:n.zrByTouch,which:n.which,stop:Ee}}(e,t,n);i&&(i[r]&&(o.cancelBubble=!!i[r].call(i,o)),i.trigger(e,o),i=i.__hostTarget?i.__hostTarget:i.parent,!o.cancelBubble););o.cancelBubble||(this.trigger(e,o),this.painter&&this.painter.eachOtherLayer&&this.painter.eachOtherLayer((function(t){"function"==typeof t[r]&&t[r].call(t,o),t.trigger&&t.trigger(e,o)})))}},e.prototype.findHover=function(t,e,n){var i=this.storage.getDisplayList(),r=new Ve(t,e);if(He(i,r,t,e,n),this._pointerSize&&!r.target){for(var o=[],a=this._pointerSize,s=a/2,l=new Re(t-s,e-s,a,a),u=i.length-1;u>=0;u--){var h=i[u];h===n||h.ignore||h.ignoreCoarsePointer||h.parent&&h.parent.ignoreCoarsePointer||(Fe.copy(h.getBoundingRect()),h.transform&&Fe.applyTransform(h.transform),Fe.intersect(l)&&o.push(h))}if(o.length)for(var c=Math.PI/12,p=2*Math.PI,d=0;d=0;o--){var a=t[o],s=void 0;if(a!==r&&!a.ignore&&(s=We(a,n,i))&&(!e.topTarget&&(e.topTarget=a),s!==Ne)){e.target=a;break}}}function Ye(t,e,n){var i=t.painter;return e<0||e>i.getWidth()||n<0||n>i.getHeight()}E(["click","mousedown","mouseup","mousewheel","dblclick","contextmenu"],(function(t){Ge.prototype[t]=function(e){var n,i,r=e.zrX,o=e.zrY,a=Ye(this,r,o);if("mouseup"===t&&a||(i=(n=this.findHover(r,o)).target),"mousedown"===t)this._downEl=i,this._downPoint=[e.zrX,e.zrY],this._upEl=i;else if("mouseup"===t)this._upEl=i;else if("click"===t){if(this._downEl!==this._upEl||!this._downPoint||Et(this._downPoint,[e.zrX,e.zrY])>4)return;this._downPoint=null}this.dispatchToElement(n,t,e)}}));function Ue(t,e,n,i){var r=e+1;if(r===n)return 1;if(i(t[r++],t[e])<0){for(;r=0;)r++;return r-e}function Xe(t,e,n,i,r){for(i===e&&i++;i>>1])<0?l=o:s=o+1;var u=i-s;switch(u){case 3:t[s+3]=t[s+2];case 2:t[s+2]=t[s+1];case 1:t[s+1]=t[s];break;default:for(;u>0;)t[s+u]=t[s+u-1],u--}t[s]=a}}function Ze(t,e,n,i,r,o){var a=0,s=0,l=1;if(o(t,e[n+r])>0){for(s=i-r;l0;)a=l,(l=1+(l<<1))<=0&&(l=s);l>s&&(l=s),a+=r,l+=r}else{for(s=r+1;ls&&(l=s);var u=a;a=r-l,l=r-u}for(a++;a>>1);o(t,e[n+h])>0?a=h+1:l=h}return l}function je(t,e,n,i,r,o){var a=0,s=0,l=1;if(o(t,e[n+r])<0){for(s=r+1;ls&&(l=s);var u=a;a=r-l,l=r-u}else{for(s=i-r;l=0;)a=l,(l=1+(l<<1))<=0&&(l=s);l>s&&(l=s),a+=r,l+=r}for(a++;a>>1);o(t,e[n+h])<0?l=h:a=h+1}return l}function qe(t,e){var n,i,r=7,o=0;t.length;var a=[];function s(s){var l=n[s],u=i[s],h=n[s+1],c=i[s+1];i[s]=u+c,s===o-3&&(n[s+1]=n[s+2],i[s+1]=i[s+2]),o--;var p=je(t[h],t,l,u,0,e);l+=p,0!==(u-=p)&&0!==(c=Ze(t[l+u-1],t,h,c,c-1,e))&&(u<=c?function(n,i,o,s){var l=0;for(l=0;l=7||d>=7);if(f)break;g<0&&(g=0),g+=2}if((r=g)<1&&(r=1),1===i){for(l=0;l=0;l--)t[d+l]=t[p+l];return void(t[c]=a[h])}var f=r;for(;;){var g=0,y=0,v=!1;do{if(e(a[h],t[u])<0){if(t[c--]=t[u--],g++,y=0,0==--i){v=!0;break}}else if(t[c--]=a[h--],y++,g=0,1==--s){v=!0;break}}while((g|y)=0;l--)t[d+l]=t[p+l];if(0===i){v=!0;break}}if(t[c--]=a[h--],1==--s){v=!0;break}if(0!==(y=s-Ze(t[u],a,0,s,s-1,e))){for(s-=y,d=(c-=y)+1,p=(h-=y)+1,l=0;l=7||y>=7);if(v)break;f<0&&(f=0),f+=2}(r=f)<1&&(r=1);if(1===s){for(d=(c-=i)+1,p=(u-=i)+1,l=i-1;l>=0;l--)t[d+l]=t[p+l];t[c]=a[h]}else{if(0===s)throw new Error;for(p=c-(s-1),l=0;l1;){var t=o-2;if(t>=1&&i[t-1]<=i[t]+i[t+1]||t>=2&&i[t-2]<=i[t]+i[t-1])i[t-1]i[t+1])break;s(t)}},forceMergeRuns:function(){for(;o>1;){var t=o-2;t>0&&i[t-1]=32;)e|=1&t,t>>=1;return t+e}(r);do{if((o=Ue(t,n,i,e))s&&(l=s),Xe(t,n,n+l,n+o,e),o=l}a.pushRun(n,o),a.mergeRuns(),r-=o,n+=o}while(0!==r);a.forceMergeRuns()}}}var $e=!1;function Je(){$e||($e=!0,console.warn("z / z2 / zlevel of displayable is invalid, which may cause unexpected errors"))}function Qe(t,e){return t.zlevel===e.zlevel?t.z===e.z?t.z2-e.z2:t.z-e.z:t.zlevel-e.zlevel}var tn=function(){function t(){this._roots=[],this._displayList=[],this._displayListLen=0,this.displayableSortFunc=Qe}return t.prototype.traverse=function(t,e){for(var n=0;n0&&(u.__clipPaths=[]),isNaN(u.z)&&(Je(),u.z=0),isNaN(u.z2)&&(Je(),u.z2=0),isNaN(u.zlevel)&&(Je(),u.zlevel=0),this._displayList[this._displayListLen++]=u}var h=t.getDecalElement&&t.getDecalElement();h&&this._updateAndAddDisplayable(h,e,n);var c=t.getTextGuideLine();c&&this._updateAndAddDisplayable(c,e,n);var p=t.getTextContent();p&&this._updateAndAddDisplayable(p,e,n)}},t.prototype.addRoot=function(t){t.__zr&&t.__zr.storage===this||this._roots.push(t)},t.prototype.delRoot=function(t){if(t instanceof Array)for(var e=0,n=t.length;e=0&&this._roots.splice(i,1)}},t.prototype.delAllRoots=function(){this._roots=[],this._displayList=[],this._displayListLen=0},t.prototype.getRoots=function(){return this._roots},t.prototype.dispose=function(){this._displayList=null,this._roots=null},t}(),en=r.hasGlobalWindow&&(window.requestAnimationFrame&&window.requestAnimationFrame.bind(window)||window.msRequestAnimationFrame&&window.msRequestAnimationFrame.bind(window)||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame)||function(t){return setTimeout(t,16)},nn={linear:function(t){return t},quadraticIn:function(t){return t*t},quadraticOut:function(t){return t*(2-t)},quadraticInOut:function(t){return(t*=2)<1?.5*t*t:-.5*(--t*(t-2)-1)},cubicIn:function(t){return t*t*t},cubicOut:function(t){return--t*t*t+1},cubicInOut:function(t){return(t*=2)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},quarticIn:function(t){return t*t*t*t},quarticOut:function(t){return 1- --t*t*t*t},quarticInOut:function(t){return(t*=2)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},quinticIn:function(t){return t*t*t*t*t},quinticOut:function(t){return--t*t*t*t*t+1},quinticInOut:function(t){return(t*=2)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},sinusoidalIn:function(t){return 1-Math.cos(t*Math.PI/2)},sinusoidalOut:function(t){return Math.sin(t*Math.PI/2)},sinusoidalInOut:function(t){return.5*(1-Math.cos(Math.PI*t))},exponentialIn:function(t){return 0===t?0:Math.pow(1024,t-1)},exponentialOut:function(t){return 1===t?1:1-Math.pow(2,-10*t)},exponentialInOut:function(t){return 0===t?0:1===t?1:(t*=2)<1?.5*Math.pow(1024,t-1):.5*(2-Math.pow(2,-10*(t-1)))},circularIn:function(t){return 1-Math.sqrt(1-t*t)},circularOut:function(t){return Math.sqrt(1- --t*t)},circularInOut:function(t){return(t*=2)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},elasticIn:function(t){var e,n=.1;return 0===t?0:1===t?1:(!n||n<1?(n=1,e=.1):e=.4*Math.asin(1/n)/(2*Math.PI),-n*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/.4))},elasticOut:function(t){var e,n=.1;return 0===t?0:1===t?1:(!n||n<1?(n=1,e=.1):e=.4*Math.asin(1/n)/(2*Math.PI),n*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/.4)+1)},elasticInOut:function(t){var e,n=.1,i=.4;return 0===t?0:1===t?1:(!n||n<1?(n=1,e=.1):e=i*Math.asin(1/n)/(2*Math.PI),(t*=2)<1?n*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i)*-.5:n*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i)*.5+1)},backIn:function(t){var e=1.70158;return t*t*((e+1)*t-e)},backOut:function(t){var e=1.70158;return--t*t*((e+1)*t+e)+1},backInOut:function(t){var e=2.5949095;return(t*=2)<1?t*t*((e+1)*t-e)*.5:.5*((t-=2)*t*((e+1)*t+e)+2)},bounceIn:function(t){return 1-nn.bounceOut(1-t)},bounceOut:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},bounceInOut:function(t){return t<.5?.5*nn.bounceIn(2*t):.5*nn.bounceOut(2*t-1)+.5}},rn=Math.pow,on=Math.sqrt,an=1e-8,sn=1e-4,ln=on(3),un=1/3,hn=wt(),cn=wt(),pn=wt();function dn(t){return t>-1e-8&&tan||t<-1e-8}function gn(t,e,n,i,r){var o=1-r;return o*o*(o*t+3*r*e)+r*r*(r*i+3*o*n)}function yn(t,e,n,i,r){var o=1-r;return 3*(((e-t)*o+2*(n-e)*r)*o+(i-n)*r*r)}function vn(t,e,n,i,r,o){var a=i+3*(e-n)-t,s=3*(n-2*e+t),l=3*(e-t),u=t-r,h=s*s-3*a*l,c=s*l-9*a*u,p=l*l-3*s*u,d=0;if(dn(h)&&dn(c)){if(dn(s))o[0]=0;else(M=-l/s)>=0&&M<=1&&(o[d++]=M)}else{var f=c*c-4*h*p;if(dn(f)){var g=c/h,y=-g/2;(M=-s/a+g)>=0&&M<=1&&(o[d++]=M),y>=0&&y<=1&&(o[d++]=y)}else if(f>0){var v=on(f),m=h*s+1.5*a*(-c+v),x=h*s+1.5*a*(-c-v);(M=(-s-((m=m<0?-rn(-m,un):rn(m,un))+(x=x<0?-rn(-x,un):rn(x,un))))/(3*a))>=0&&M<=1&&(o[d++]=M)}else{var _=(2*h*s-3*a*c)/(2*on(h*h*h)),b=Math.acos(_)/3,w=on(h),S=Math.cos(b),M=(-s-2*w*S)/(3*a),I=(y=(-s+w*(S+ln*Math.sin(b)))/(3*a),(-s+w*(S-ln*Math.sin(b)))/(3*a));M>=0&&M<=1&&(o[d++]=M),y>=0&&y<=1&&(o[d++]=y),I>=0&&I<=1&&(o[d++]=I)}}return d}function mn(t,e,n,i,r){var o=6*n-12*e+6*t,a=9*e+3*i-3*t-9*n,s=3*e-3*t,l=0;if(dn(a)){if(fn(o))(h=-s/o)>=0&&h<=1&&(r[l++]=h)}else{var u=o*o-4*a*s;if(dn(u))r[0]=-o/(2*a);else if(u>0){var h,c=on(u),p=(-o-c)/(2*a);(h=(-o+c)/(2*a))>=0&&h<=1&&(r[l++]=h),p>=0&&p<=1&&(r[l++]=p)}}return l}function xn(t,e,n,i,r,o){var a=(e-t)*r+t,s=(n-e)*r+e,l=(i-n)*r+n,u=(s-a)*r+a,h=(l-s)*r+s,c=(h-u)*r+u;o[0]=t,o[1]=a,o[2]=u,o[3]=c,o[4]=c,o[5]=h,o[6]=l,o[7]=i}function _n(t,e,n,i,r,o,a,s,l,u,h){var c,p,d,f,g,y=.005,v=1/0;hn[0]=l,hn[1]=u;for(var m=0;m<1;m+=.05)cn[0]=gn(t,n,r,a,m),cn[1]=gn(e,i,o,s,m),(f=Vt(hn,cn))=0&&f=0&&y=1?1:vn(0,i,o,1,t,s)&&gn(0,r,a,1,s[0])}}}var kn=function(){function t(t){this._inited=!1,this._startTime=0,this._pausedTime=0,this._paused=!1,this._life=t.life||1e3,this._delay=t.delay||0,this.loop=t.loop||!1,this.onframe=t.onframe||xt,this.ondestroy=t.ondestroy||xt,this.onrestart=t.onrestart||xt,t.easing&&this.setEasing(t.easing)}return t.prototype.step=function(t,e){if(this._inited||(this._startTime=t+this._delay,this._inited=!0),!this._paused){var n=this._life,i=t-this._startTime-this._pausedTime,r=i/n;r<0&&(r=0),r=Math.min(r,1);var o=this.easingFunc,a=o?o(r):r;if(this.onframe(a),1===r){if(!this.loop)return!0;var s=i%n;this._startTime=t-s,this._pausedTime=0,this.onrestart()}return!1}this._pausedTime+=e},t.prototype.pause=function(){this._paused=!0},t.prototype.resume=function(){this._paused=!1},t.prototype.setEasing=function(t){this.easing=t,this.easingFunc=U(t)?t:nn[t]||An(t)},t}(),Ln=function(t){this.value=t},Pn=function(){function t(){this._len=0}return t.prototype.insert=function(t){var e=new Ln(t);return this.insertEntry(e),e},t.prototype.insertEntry=function(t){this.head?(this.tail.next=t,t.prev=this.tail,t.next=null,this.tail=t):this.head=this.tail=t,this._len++},t.prototype.remove=function(t){var e=t.prev,n=t.next;e?e.next=n:this.head=n,n?n.prev=e:this.tail=e,t.next=t.prev=null,this._len--},t.prototype.len=function(){return this._len},t.prototype.clear=function(){this.head=this.tail=null,this._len=0},t}(),On=function(){function t(t){this._list=new Pn,this._maxSize=10,this._map={},this._maxSize=t}return t.prototype.put=function(t,e){var n=this._list,i=this._map,r=null;if(null==i[t]){var o=n.len(),a=this._lastRemovedEntry;if(o>=this._maxSize&&o>0){var s=n.head;n.remove(s),delete i[s.key],r=s.value,this._lastRemovedEntry=s}a?a.value=e:a=new Ln(e),a.key=t,n.insertEntry(a),i[t]=a}return r},t.prototype.get=function(t){var e=this._map[t],n=this._list;if(null!=e)return e!==n.tail&&(n.remove(e),n.insertEntry(e)),e.value},t.prototype.clear=function(){this._list.clear(),this._map={}},t.prototype.len=function(){return this._list.len()},t}(),Rn={transparent:[0,0,0,0],aliceblue:[240,248,255,1],antiquewhite:[250,235,215,1],aqua:[0,255,255,1],aquamarine:[127,255,212,1],azure:[240,255,255,1],beige:[245,245,220,1],bisque:[255,228,196,1],black:[0,0,0,1],blanchedalmond:[255,235,205,1],blue:[0,0,255,1],blueviolet:[138,43,226,1],brown:[165,42,42,1],burlywood:[222,184,135,1],cadetblue:[95,158,160,1],chartreuse:[127,255,0,1],chocolate:[210,105,30,1],coral:[255,127,80,1],cornflowerblue:[100,149,237,1],cornsilk:[255,248,220,1],crimson:[220,20,60,1],cyan:[0,255,255,1],darkblue:[0,0,139,1],darkcyan:[0,139,139,1],darkgoldenrod:[184,134,11,1],darkgray:[169,169,169,1],darkgreen:[0,100,0,1],darkgrey:[169,169,169,1],darkkhaki:[189,183,107,1],darkmagenta:[139,0,139,1],darkolivegreen:[85,107,47,1],darkorange:[255,140,0,1],darkorchid:[153,50,204,1],darkred:[139,0,0,1],darksalmon:[233,150,122,1],darkseagreen:[143,188,143,1],darkslateblue:[72,61,139,1],darkslategray:[47,79,79,1],darkslategrey:[47,79,79,1],darkturquoise:[0,206,209,1],darkviolet:[148,0,211,1],deeppink:[255,20,147,1],deepskyblue:[0,191,255,1],dimgray:[105,105,105,1],dimgrey:[105,105,105,1],dodgerblue:[30,144,255,1],firebrick:[178,34,34,1],floralwhite:[255,250,240,1],forestgreen:[34,139,34,1],fuchsia:[255,0,255,1],gainsboro:[220,220,220,1],ghostwhite:[248,248,255,1],gold:[255,215,0,1],goldenrod:[218,165,32,1],gray:[128,128,128,1],green:[0,128,0,1],greenyellow:[173,255,47,1],grey:[128,128,128,1],honeydew:[240,255,240,1],hotpink:[255,105,180,1],indianred:[205,92,92,1],indigo:[75,0,130,1],ivory:[255,255,240,1],khaki:[240,230,140,1],lavender:[230,230,250,1],lavenderblush:[255,240,245,1],lawngreen:[124,252,0,1],lemonchiffon:[255,250,205,1],lightblue:[173,216,230,1],lightcoral:[240,128,128,1],lightcyan:[224,255,255,1],lightgoldenrodyellow:[250,250,210,1],lightgray:[211,211,211,1],lightgreen:[144,238,144,1],lightgrey:[211,211,211,1],lightpink:[255,182,193,1],lightsalmon:[255,160,122,1],lightseagreen:[32,178,170,1],lightskyblue:[135,206,250,1],lightslategray:[119,136,153,1],lightslategrey:[119,136,153,1],lightsteelblue:[176,196,222,1],lightyellow:[255,255,224,1],lime:[0,255,0,1],limegreen:[50,205,50,1],linen:[250,240,230,1],magenta:[255,0,255,1],maroon:[128,0,0,1],mediumaquamarine:[102,205,170,1],mediumblue:[0,0,205,1],mediumorchid:[186,85,211,1],mediumpurple:[147,112,219,1],mediumseagreen:[60,179,113,1],mediumslateblue:[123,104,238,1],mediumspringgreen:[0,250,154,1],mediumturquoise:[72,209,204,1],mediumvioletred:[199,21,133,1],midnightblue:[25,25,112,1],mintcream:[245,255,250,1],mistyrose:[255,228,225,1],moccasin:[255,228,181,1],navajowhite:[255,222,173,1],navy:[0,0,128,1],oldlace:[253,245,230,1],olive:[128,128,0,1],olivedrab:[107,142,35,1],orange:[255,165,0,1],orangered:[255,69,0,1],orchid:[218,112,214,1],palegoldenrod:[238,232,170,1],palegreen:[152,251,152,1],paleturquoise:[175,238,238,1],palevioletred:[219,112,147,1],papayawhip:[255,239,213,1],peachpuff:[255,218,185,1],peru:[205,133,63,1],pink:[255,192,203,1],plum:[221,160,221,1],powderblue:[176,224,230,1],purple:[128,0,128,1],red:[255,0,0,1],rosybrown:[188,143,143,1],royalblue:[65,105,225,1],saddlebrown:[139,69,19,1],salmon:[250,128,114,1],sandybrown:[244,164,96,1],seagreen:[46,139,87,1],seashell:[255,245,238,1],sienna:[160,82,45,1],silver:[192,192,192,1],skyblue:[135,206,235,1],slateblue:[106,90,205,1],slategray:[112,128,144,1],slategrey:[112,128,144,1],snow:[255,250,250,1],springgreen:[0,255,127,1],steelblue:[70,130,180,1],tan:[210,180,140,1],teal:[0,128,128,1],thistle:[216,191,216,1],tomato:[255,99,71,1],turquoise:[64,224,208,1],violet:[238,130,238,1],wheat:[245,222,179,1],white:[255,255,255,1],whitesmoke:[245,245,245,1],yellow:[255,255,0,1],yellowgreen:[154,205,50,1]};function Nn(t){return(t=Math.round(t))<0?0:t>255?255:t}function En(t){return t<0?0:t>1?1:t}function zn(t){var e=t;return e.length&&"%"===e.charAt(e.length-1)?Nn(parseFloat(e)/100*255):Nn(parseInt(e,10))}function Vn(t){var e=t;return e.length&&"%"===e.charAt(e.length-1)?En(parseFloat(e)/100):En(parseFloat(e))}function Bn(t,e,n){return n<0?n+=1:n>1&&(n-=1),6*n<1?t+(e-t)*n*6:2*n<1?e:3*n<2?t+(e-t)*(2/3-n)*6:t}function Fn(t,e,n){return t+(e-t)*n}function Gn(t,e,n,i,r){return t[0]=e,t[1]=n,t[2]=i,t[3]=r,t}function Wn(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t}var Hn=new On(20),Yn=null;function Un(t,e){Yn&&Wn(Yn,e),Yn=Hn.put(t,Yn||e.slice())}function Xn(t,e){if(t){e=e||[];var n=Hn.get(t);if(n)return Wn(e,n);var i=(t+="").replace(/ /g,"").toLowerCase();if(i in Rn)return Wn(e,Rn[i]),Un(t,e),e;var r,o=i.length;if("#"===i.charAt(0))return 4===o||5===o?(r=parseInt(i.slice(1,4),16))>=0&&r<=4095?(Gn(e,(3840&r)>>4|(3840&r)>>8,240&r|(240&r)>>4,15&r|(15&r)<<4,5===o?parseInt(i.slice(4),16)/15:1),Un(t,e),e):void Gn(e,0,0,0,1):7===o||9===o?(r=parseInt(i.slice(1,7),16))>=0&&r<=16777215?(Gn(e,(16711680&r)>>16,(65280&r)>>8,255&r,9===o?parseInt(i.slice(7),16)/255:1),Un(t,e),e):void Gn(e,0,0,0,1):void 0;var a=i.indexOf("("),s=i.indexOf(")");if(-1!==a&&s+1===o){var l=i.substr(0,a),u=i.substr(a+1,s-(a+1)).split(","),h=1;switch(l){case"rgba":if(4!==u.length)return 3===u.length?Gn(e,+u[0],+u[1],+u[2],1):Gn(e,0,0,0,1);h=Vn(u.pop());case"rgb":return u.length>=3?(Gn(e,zn(u[0]),zn(u[1]),zn(u[2]),3===u.length?h:Vn(u[3])),Un(t,e),e):void Gn(e,0,0,0,1);case"hsla":return 4!==u.length?void Gn(e,0,0,0,1):(u[3]=Vn(u[3]),Zn(u,e),Un(t,e),e);case"hsl":return 3!==u.length?void Gn(e,0,0,0,1):(Zn(u,e),Un(t,e),e);default:return}}Gn(e,0,0,0,1)}}function Zn(t,e){var n=(parseFloat(t[0])%360+360)%360/360,i=Vn(t[1]),r=Vn(t[2]),o=r<=.5?r*(i+1):r+i-r*i,a=2*r-o;return Gn(e=e||[],Nn(255*Bn(a,o,n+1/3)),Nn(255*Bn(a,o,n)),Nn(255*Bn(a,o,n-1/3)),1),4===t.length&&(e[3]=t[3]),e}function jn(t,e){var n=Xn(t);if(n){for(var i=0;i<3;i++)n[i]=e<0?n[i]*(1-e)|0:(255-n[i])*e+n[i]|0,n[i]>255?n[i]=255:n[i]<0&&(n[i]=0);return ei(n,4===n.length?"rgba":"rgb")}}function qn(t,e,n){if(e&&e.length&&t>=0&&t<=1){n=n||[];var i=t*(e.length-1),r=Math.floor(i),o=Math.ceil(i),a=e[r],s=e[o],l=i-r;return n[0]=Nn(Fn(a[0],s[0],l)),n[1]=Nn(Fn(a[1],s[1],l)),n[2]=Nn(Fn(a[2],s[2],l)),n[3]=En(Fn(a[3],s[3],l)),n}}var Kn=qn;function $n(t,e,n){if(e&&e.length&&t>=0&&t<=1){var i=t*(e.length-1),r=Math.floor(i),o=Math.ceil(i),a=Xn(e[r]),s=Xn(e[o]),l=i-r,u=ei([Nn(Fn(a[0],s[0],l)),Nn(Fn(a[1],s[1],l)),Nn(Fn(a[2],s[2],l)),En(Fn(a[3],s[3],l))],"rgba");return n?{color:u,leftIndex:r,rightIndex:o,value:i}:u}}var Jn=$n;function Qn(t,e,n,i){var r=Xn(t);if(t)return r=function(t){if(t){var e,n,i=t[0]/255,r=t[1]/255,o=t[2]/255,a=Math.min(i,r,o),s=Math.max(i,r,o),l=s-a,u=(s+a)/2;if(0===l)e=0,n=0;else{n=u<.5?l/(s+a):l/(2-s-a);var h=((s-i)/6+l/2)/l,c=((s-r)/6+l/2)/l,p=((s-o)/6+l/2)/l;i===s?e=p-c:r===s?e=1/3+h-p:o===s&&(e=2/3+c-h),e<0&&(e+=1),e>1&&(e-=1)}var d=[360*e,n,u];return null!=t[3]&&d.push(t[3]),d}}(r),null!=e&&(r[0]=function(t){return(t=Math.round(t))<0?0:t>360?360:t}(e)),null!=n&&(r[1]=Vn(n)),null!=i&&(r[2]=Vn(i)),ei(Zn(r),"rgba")}function ti(t,e){var n=Xn(t);if(n&&null!=e)return n[3]=En(e),ei(n,"rgba")}function ei(t,e){if(t&&t.length){var n=t[0]+","+t[1]+","+t[2];return"rgba"!==e&&"hsva"!==e&&"hsla"!==e||(n+=","+t[3]),e+"("+n+")"}}function ni(t,e){var n=Xn(t);return n?(.299*n[0]+.587*n[1]+.114*n[2])*n[3]/255+(1-n[3])*e:0}var ii=Object.freeze({__proto__:null,parse:Xn,lift:jn,toHex:function(t){var e=Xn(t);if(e)return((1<<24)+(e[0]<<16)+(e[1]<<8)+ +e[2]).toString(16).slice(1)},fastLerp:qn,fastMapToColor:Kn,lerp:$n,mapToColor:Jn,modifyHSL:Qn,modifyAlpha:ti,stringify:ei,lum:ni,random:function(){return ei([Math.round(255*Math.random()),Math.round(255*Math.random()),Math.round(255*Math.random())],"rgb")}}),ri=Math.round;function oi(t){var e;if(t&&"transparent"!==t){if("string"==typeof t&&t.indexOf("rgba")>-1){var n=Xn(t);n&&(t="rgb("+n[0]+","+n[1]+","+n[2]+")",e=n[3])}}else t="none";return{color:t,opacity:null==e?1:e}}var ai=1e-4;function si(t){return t-1e-4}function li(t){return ri(1e3*t)/1e3}function ui(t){return ri(1e4*t)/1e4}var hi={left:"start",right:"end",center:"middle",middle:"middle"};function ci(t){return t&&!!t.image}function pi(t){return"linear"===t.type}function di(t){return"radial"===t.type}function fi(t){return"url(#"+t+")"}function gi(t){var e=t.getGlobalScale(),n=Math.max(e[0],e[1]);return Math.max(Math.ceil(Math.log(n)/Math.log(10)),1)}function yi(t){var e=t.x||0,n=t.y||0,i=(t.rotation||0)*_t,r=rt(t.scaleX,1),o=rt(t.scaleY,1),a=t.skewX||0,s=t.skewY||0,l=[];return(e||n)&&l.push("translate("+e+"px,"+n+"px)"),i&&l.push("rotate("+i+")"),1===r&&1===o||l.push("scale("+r+","+o+")"),(a||s)&&l.push("skew("+ri(a*_t)+"deg, "+ri(s*_t)+"deg)"),l.join(" ")}var vi=r.hasGlobalWindow&&U(window.btoa)?function(t){return window.btoa(unescape(t))}:"undefined"!=typeof Buffer?function(t){return Buffer.from(t).toString("base64")}:function(t){return null},mi=Array.prototype.slice;function xi(t,e,n){return(e-t)*n+t}function _i(t,e,n,i){for(var r=e.length,o=0;oi?e:t,o=Math.min(n,i),a=r[o-1]||{color:[0,0,0,0],offset:0},s=o;sa)i.length=a;else for(var s=o;s=1},t.prototype.getAdditiveTrack=function(){return this._additiveTrack},t.prototype.addKeyframe=function(t,e,n){this._needsSort=!0;var i=this.keyframes,r=i.length,o=!1,a=6,s=e;if(N(e)){var l=function(t){return N(t&&t[0])?2:1}(e);a=l,(1===l&&!j(e[0])||2===l&&!j(e[0][0]))&&(o=!0)}else if(j(e)&&!nt(e))a=0;else if(X(e))if(isNaN(+e)){var u=Xn(e);u&&(s=u,a=3)}else a=0;else if(Q(e)){var h=A({},s);h.colorStops=z(e.colorStops,(function(t){return{offset:t.offset,color:Xn(t.color)}})),pi(e)?a=4:di(e)&&(a=5),s=h}0===r?this.valType=a:a===this.valType&&6!==a||(o=!0),this.discrete=this.discrete||o;var c={time:t,value:s,rawValue:e,percent:0};return n&&(c.easing=n,c.easingFunc=U(n)?n:nn[n]||An(n)),i.push(c),c},t.prototype.prepare=function(t,e){var n=this.keyframes;this._needsSort&&n.sort((function(t,e){return t.time-e.time}));for(var i=this.valType,r=n.length,o=n[r-1],a=this.discrete,s=Di(i),l=Ci(i),u=0;u=0&&!(l[n].percent<=e);n--);n=d(n,u-2)}else{for(n=p;ne);n++);n=d(n-1,u-2)}r=l[n+1],i=l[n]}if(i&&r){this._lastFr=n,this._lastFrP=e;var f=r.percent-i.percent,g=0===f?1:d((e-i.percent)/f,1);r.easingFunc&&(g=r.easingFunc(g));var y=o?this._additiveValue:c?Ai:t[h];if(!Di(s)&&!c||y||(y=this._additiveValue=[]),this.discrete)t[h]=g<1?i.rawValue:r.rawValue;else if(Di(s))1===s?_i(y,i[a],r[a],g):function(t,e,n,i){for(var r=e.length,o=r&&e[0].length,a=0;a0&&s.addKeyframe(0,Ii(l),i),this._trackKeys.push(a)}s.addKeyframe(t,Ii(e[a]),i)}return this._maxTime=Math.max(this._maxTime,t),this},t.prototype.pause=function(){this._clip.pause(),this._paused=!0},t.prototype.resume=function(){this._clip.resume(),this._paused=!1},t.prototype.isPaused=function(){return!!this._paused},t.prototype.duration=function(t){return this._maxTime=t,this._force=!0,this},t.prototype._doneCallback=function(){this._setTracksFinished(),this._clip=null;var t=this._doneCbs;if(t)for(var e=t.length,n=0;n0)){this._started=1;for(var e=this,n=[],i=this._maxTime||0,r=0;r1){var a=o.pop();r.addKeyframe(a.time,t[i]),r.prepare(this._maxTime,r.getAdditiveTrack())}}}},t}();function Pi(){return(new Date).getTime()}var Oi,Ri,Ni=function(t){function e(e){var n=t.call(this)||this;return n._running=!1,n._time=0,n._pausedTime=0,n._pauseStart=0,n._paused=!1,e=e||{},n.stage=e.stage||{},n}return n(e,t),e.prototype.addClip=function(t){t.animation&&this.removeClip(t),this._head?(this._tail.next=t,t.prev=this._tail,t.next=null,this._tail=t):this._head=this._tail=t,t.animation=this},e.prototype.addAnimator=function(t){t.animation=this;var e=t.getClip();e&&this.addClip(e)},e.prototype.removeClip=function(t){if(t.animation){var e=t.prev,n=t.next;e?e.next=n:this._head=n,n?n.prev=e:this._tail=e,t.next=t.prev=t.animation=null}},e.prototype.removeAnimator=function(t){var e=t.getClip();e&&this.removeClip(e),t.animation=null},e.prototype.update=function(t){for(var e=Pi()-this._pausedTime,n=e-this._time,i=this._head;i;){var r=i.next;i.step(e,n)?(i.ondestroy(),this.removeClip(i),i=r):i=r}this._time=e,t||(this.trigger("frame",n),this.stage.update&&this.stage.update())},e.prototype._startLoop=function(){var t=this;this._running=!0,en((function e(){t._running&&(en(e),!t._paused&&t.update())}))},e.prototype.start=function(){this._running||(this._time=Pi(),this._pausedTime=0,this._startLoop())},e.prototype.stop=function(){this._running=!1},e.prototype.pause=function(){this._paused||(this._pauseStart=Pi(),this._paused=!0)},e.prototype.resume=function(){this._paused&&(this._pausedTime+=Pi()-this._pauseStart,this._paused=!1)},e.prototype.clear=function(){for(var t=this._head;t;){var e=t.next;t.prev=t.next=t.animation=null,t=e}this._head=this._tail=null},e.prototype.isFinished=function(){return null==this._head},e.prototype.animate=function(t,e){e=e||{},this.start();var n=new Li(t,e.loop);return this.addAnimator(n),n},e}(Xt),Ei=r.domSupported,zi=(Ri={pointerdown:1,pointerup:1,pointermove:1,pointerout:1},{mouse:Oi=["click","dblclick","mousewheel","wheel","mouseout","mouseup","mousedown","mousemove","contextmenu"],touch:["touchstart","touchend","touchmove"],pointer:z(Oi,(function(t){var e=t.replace("mouse","pointer");return Ri.hasOwnProperty(e)?e:t}))}),Vi=["mousemove","mouseup"],Bi=["pointermove","pointerup"],Fi=!1;function Gi(t){var e=t.pointerType;return"pen"===e||"touch"===e}function Wi(t){t&&(t.zrByTouch=!0)}function Hi(t,e){for(var n=e,i=!1;n&&9!==n.nodeType&&!(i=n.domBelongToZr||n!==e&&n===t.painterRoot);)n=n.parentNode;return i}var Yi=function(t,e){this.stopPropagation=xt,this.stopImmediatePropagation=xt,this.preventDefault=xt,this.type=e.type,this.target=this.currentTarget=t.dom,this.pointerType=e.pointerType,this.clientX=e.clientX,this.clientY=e.clientY},Ui={mousedown:function(t){t=le(this.dom,t),this.__mayPointerCapture=[t.zrX,t.zrY],this.trigger("mousedown",t)},mousemove:function(t){t=le(this.dom,t);var e=this.__mayPointerCapture;!e||t.zrX===e[0]&&t.zrY===e[1]||this.__togglePointerCapture(!0),this.trigger("mousemove",t)},mouseup:function(t){t=le(this.dom,t),this.__togglePointerCapture(!1),this.trigger("mouseup",t)},mouseout:function(t){Hi(this,(t=le(this.dom,t)).toElement||t.relatedTarget)||(this.__pointerCapturing&&(t.zrEventControl="no_globalout"),this.trigger("mouseout",t))},wheel:function(t){Fi=!0,t=le(this.dom,t),this.trigger("mousewheel",t)},mousewheel:function(t){Fi||(t=le(this.dom,t),this.trigger("mousewheel",t))},touchstart:function(t){Wi(t=le(this.dom,t)),this.__lastTouchMoment=new Date,this.handler.processGesture(t,"start"),Ui.mousemove.call(this,t),Ui.mousedown.call(this,t)},touchmove:function(t){Wi(t=le(this.dom,t)),this.handler.processGesture(t,"change"),Ui.mousemove.call(this,t)},touchend:function(t){Wi(t=le(this.dom,t)),this.handler.processGesture(t,"end"),Ui.mouseup.call(this,t),+new Date-+this.__lastTouchMoment<300&&Ui.click.call(this,t)},pointerdown:function(t){Ui.mousedown.call(this,t)},pointermove:function(t){Gi(t)||Ui.mousemove.call(this,t)},pointerup:function(t){Ui.mouseup.call(this,t)},pointerout:function(t){Gi(t)||Ui.mouseout.call(this,t)}};E(["click","dblclick","contextmenu"],(function(t){Ui[t]=function(e){e=le(this.dom,e),this.trigger(t,e)}}));var Xi={pointermove:function(t){Gi(t)||Xi.mousemove.call(this,t)},pointerup:function(t){Xi.mouseup.call(this,t)},mousemove:function(t){this.trigger("mousemove",t)},mouseup:function(t){var e=this.__pointerCapturing;this.__togglePointerCapture(!1),this.trigger("mouseup",t),e&&(t.zrEventControl="only_globalout",this.trigger("mouseout",t))}};function Zi(t,e){var n=e.domHandlers;r.pointerEventsSupported?E(zi.pointer,(function(i){qi(e,i,(function(e){n[i].call(t,e)}))})):(r.touchEventsSupported&&E(zi.touch,(function(i){qi(e,i,(function(r){n[i].call(t,r),function(t){t.touching=!0,null!=t.touchTimer&&(clearTimeout(t.touchTimer),t.touchTimer=null),t.touchTimer=setTimeout((function(){t.touching=!1,t.touchTimer=null}),700)}(e)}))})),E(zi.mouse,(function(i){qi(e,i,(function(r){r=se(r),e.touching||n[i].call(t,r)}))})))}function ji(t,e){function n(n){qi(e,n,(function(i){i=se(i),Hi(t,i.target)||(i=function(t,e){return le(t.dom,new Yi(t,e),!0)}(t,i),e.domHandlers[n].call(t,i))}),{capture:!0})}r.pointerEventsSupported?E(Bi,n):r.touchEventsSupported||E(Vi,n)}function qi(t,e,n,i){t.mounted[e]=n,t.listenerOpts[e]=i,ue(t.domTarget,e,n,i)}function Ki(t){var e,n,i,r,o=t.mounted;for(var a in o)o.hasOwnProperty(a)&&(e=t.domTarget,n=a,i=o[a],r=t.listenerOpts[a],e.removeEventListener(n,i,r));t.mounted={}}var $i=function(t,e){this.mounted={},this.listenerOpts={},this.touching=!1,this.domTarget=t,this.domHandlers=e},Ji=function(t){function e(e,n){var i=t.call(this)||this;return i.__pointerCapturing=!1,i.dom=e,i.painterRoot=n,i._localHandlerScope=new $i(e,Ui),Ei&&(i._globalHandlerScope=new $i(document,Xi)),Zi(i,i._localHandlerScope),i}return n(e,t),e.prototype.dispose=function(){Ki(this._localHandlerScope),Ei&&Ki(this._globalHandlerScope)},e.prototype.setCursor=function(t){this.dom.style&&(this.dom.style.cursor=t||"default")},e.prototype.__togglePointerCapture=function(t){if(this.__mayPointerCapture=null,Ei&&+this.__pointerCapturing^+t){this.__pointerCapturing=t;var e=this._globalHandlerScope;t?ji(this,e):Ki(e)}},e}(Xt),Qi=1;r.hasGlobalWindow&&(Qi=Math.max(window.devicePixelRatio||window.screen&&window.screen.deviceXDPI/window.screen.logicalXDPI||1,1));var tr=Qi,er="#333",nr="#ccc",ir=ye,rr=5e-5;function or(t){return t>rr||t<-5e-5}var ar=[],sr=[],lr=[1,0,0,1,0,0],ur=Math.abs,hr=function(){function t(){}return t.prototype.getLocalTransform=function(e){return t.getLocalTransform(this,e)},t.prototype.setPosition=function(t){this.x=t[0],this.y=t[1]},t.prototype.setScale=function(t){this.scaleX=t[0],this.scaleY=t[1]},t.prototype.setSkew=function(t){this.skewX=t[0],this.skewY=t[1]},t.prototype.setOrigin=function(t){this.originX=t[0],this.originY=t[1]},t.prototype.needLocalTransform=function(){return or(this.rotation)||or(this.x)||or(this.y)||or(this.scaleX-1)||or(this.scaleY-1)||or(this.skewX)||or(this.skewY)},t.prototype.updateTransform=function(){var t=this.parent&&this.parent.transform,e=this.needLocalTransform(),n=this.transform;e||t?(n=n||[1,0,0,1,0,0],e?this.getLocalTransform(n):ir(n),t&&(e?me(n,t,n):ve(n,t)),this.transform=n,this._resolveGlobalScaleRatio(n)):n&&ir(n)},t.prototype._resolveGlobalScaleRatio=function(t){var e=this.globalScaleRatio;if(null!=e&&1!==e){this.getGlobalScale(ar);var n=ar[0]<0?-1:1,i=ar[1]<0?-1:1,r=((ar[0]-n)*e+n)/ar[0]||0,o=((ar[1]-i)*e+i)/ar[1]||0;t[0]*=r,t[1]*=r,t[2]*=o,t[3]*=o}this.invTransform=this.invTransform||[1,0,0,1,0,0],we(this.invTransform,t)},t.prototype.getComputedTransform=function(){for(var t=this,e=[];t;)e.push(t),t=t.parent;for(;t=e.pop();)t.updateTransform();return this.transform},t.prototype.setLocalTransform=function(t){if(t){var e=t[0]*t[0]+t[1]*t[1],n=t[2]*t[2]+t[3]*t[3],i=Math.atan2(t[1],t[0]),r=Math.PI/2+i-Math.atan2(t[3],t[2]);n=Math.sqrt(n)*Math.cos(r),e=Math.sqrt(e),this.skewX=r,this.skewY=0,this.rotation=-i,this.x=+t[4],this.y=+t[5],this.scaleX=e,this.scaleY=n,this.originX=0,this.originY=0}},t.prototype.decomposeTransform=function(){if(this.transform){var t=this.parent,e=this.transform;t&&t.transform&&(me(sr,t.invTransform,e),e=sr);var n=this.originX,i=this.originY;(n||i)&&(lr[4]=n,lr[5]=i,me(sr,e,lr),sr[4]-=n,sr[5]-=i,e=sr),this.setLocalTransform(e)}},t.prototype.getGlobalScale=function(t){var e=this.transform;return t=t||[],e?(t[0]=Math.sqrt(e[0]*e[0]+e[1]*e[1]),t[1]=Math.sqrt(e[2]*e[2]+e[3]*e[3]),e[0]<0&&(t[0]=-t[0]),e[3]<0&&(t[1]=-t[1]),t):(t[0]=1,t[1]=1,t)},t.prototype.transformCoordToLocal=function(t,e){var n=[t,e],i=this.invTransform;return i&&Ft(n,n,i),n},t.prototype.transformCoordToGlobal=function(t,e){var n=[t,e],i=this.transform;return i&&Ft(n,n,i),n},t.prototype.getLineScale=function(){var t=this.transform;return t&&ur(t[0]-1)>1e-10&&ur(t[3]-1)>1e-10?Math.sqrt(ur(t[0]*t[3]-t[2]*t[1])):1},t.prototype.copyTransform=function(t){pr(this,t)},t.getLocalTransform=function(t,e){e=e||[];var n=t.originX||0,i=t.originY||0,r=t.scaleX,o=t.scaleY,a=t.anchorX,s=t.anchorY,l=t.rotation||0,u=t.x,h=t.y,c=t.skewX?Math.tan(t.skewX):0,p=t.skewY?Math.tan(-t.skewY):0;if(n||i||a||s){var d=n+a,f=i+s;e[4]=-d*r-c*f*o,e[5]=-f*o-p*d*r}else e[4]=e[5]=0;return e[0]=r,e[3]=o,e[1]=p*r,e[2]=c*o,l&&_e(e,e,l),e[4]+=n+u,e[5]+=i+h,e},t.initDefaultProps=function(){var e=t.prototype;e.scaleX=e.scaleY=e.globalScaleRatio=1,e.x=e.y=e.originX=e.originY=e.skewX=e.skewY=e.rotation=e.anchorX=e.anchorY=0}(),t}(),cr=["x","y","originX","originY","anchorX","anchorY","rotation","scaleX","scaleY","skewX","skewY"];function pr(t,e){for(var n=0;n=0?parseFloat(t)/100*e:parseFloat(t):t}function br(t,e,n){var i=e.position||"inside",r=null!=e.distance?e.distance:5,o=n.height,a=n.width,s=o/2,l=n.x,u=n.y,h="left",c="top";if(i instanceof Array)l+=_r(i[0],n.width),u+=_r(i[1],n.height),h=null,c=null;else switch(i){case"left":l-=r,u+=s,h="right",c="middle";break;case"right":l+=r+a,u+=s,c="middle";break;case"top":l+=a/2,u-=r,h="center",c="bottom";break;case"bottom":l+=a/2,u+=o+r,h="center";break;case"inside":l+=a/2,u+=s,h="center",c="middle";break;case"insideLeft":l+=r,u+=s,c="middle";break;case"insideRight":l+=a-r,u+=s,h="right",c="middle";break;case"insideTop":l+=a/2,u+=r,h="center";break;case"insideBottom":l+=a/2,u+=o-r,h="center",c="bottom";break;case"insideTopLeft":l+=r,u+=r;break;case"insideTopRight":l+=a-r,u+=r,h="right";break;case"insideBottomLeft":l+=r,u+=o-r,c="bottom";break;case"insideBottomRight":l+=a-r,u+=o-r,h="right",c="bottom"}return(t=t||{}).x=l,t.y=u,t.align=h,t.verticalAlign=c,t}var wr="__zr_normal__",Sr=cr.concat(["ignore"]),Mr=V(cr,(function(t,e){return t[e]=!0,t}),{ignore:!1}),Ir={},Tr=new Re(0,0,0,0),Cr=function(){function t(t){this.id=M(),this.animators=[],this.currentStates=[],this.states={},this._init(t)}return t.prototype._init=function(t){this.attr(t)},t.prototype.drift=function(t,e,n){switch(this.draggable){case"horizontal":e=0;break;case"vertical":t=0}var i=this.transform;i||(i=this.transform=[1,0,0,1,0,0]),i[4]+=t,i[5]+=e,this.decomposeTransform(),this.markRedraw()},t.prototype.beforeUpdate=function(){},t.prototype.afterUpdate=function(){},t.prototype.update=function(){this.updateTransform(),this.__dirty&&this.updateInnerText()},t.prototype.updateInnerText=function(t){var e=this._textContent;if(e&&(!e.ignore||t)){this.textConfig||(this.textConfig={});var n=this.textConfig,i=n.local,r=e.innerTransformable,o=void 0,a=void 0,s=!1;r.parent=i?this:null;var l=!1;if(r.copyTransform(e),null!=n.position){var u=Tr;n.layoutRect?u.copy(n.layoutRect):u.copy(this.getBoundingRect()),i||u.applyTransform(this.transform),this.calculateTextPosition?this.calculateTextPosition(Ir,n,u):br(Ir,n,u),r.x=Ir.x,r.y=Ir.y,o=Ir.align,a=Ir.verticalAlign;var h=n.origin;if(h&&null!=n.rotation){var c=void 0,p=void 0;"center"===h?(c=.5*u.width,p=.5*u.height):(c=_r(h[0],u.width),p=_r(h[1],u.height)),l=!0,r.originX=-r.x+c+(i?0:u.x),r.originY=-r.y+p+(i?0:u.y)}}null!=n.rotation&&(r.rotation=n.rotation);var d=n.offset;d&&(r.x+=d[0],r.y+=d[1],l||(r.originX=-d[0],r.originY=-d[1]));var f=null==n.inside?"string"==typeof n.position&&n.position.indexOf("inside")>=0:n.inside,g=this._innerTextDefaultStyle||(this._innerTextDefaultStyle={}),y=void 0,v=void 0,m=void 0;f&&this.canBeInsideText()?(y=n.insideFill,v=n.insideStroke,null!=y&&"auto"!==y||(y=this.getInsideTextFill()),null!=v&&"auto"!==v||(v=this.getInsideTextStroke(y),m=!0)):(y=n.outsideFill,v=n.outsideStroke,null!=y&&"auto"!==y||(y=this.getOutsideFill()),null!=v&&"auto"!==v||(v=this.getOutsideStroke(y),m=!0)),(y=y||"#000")===g.fill&&v===g.stroke&&m===g.autoStroke&&o===g.align&&a===g.verticalAlign||(s=!0,g.fill=y,g.stroke=v,g.autoStroke=m,g.align=o,g.verticalAlign=a,e.setDefaultTextStyle(g)),e.__dirty|=1,s&&e.dirtyStyle(!0)}},t.prototype.canBeInsideText=function(){return!0},t.prototype.getInsideTextFill=function(){return"#fff"},t.prototype.getInsideTextStroke=function(t){return"#000"},t.prototype.getOutsideFill=function(){return this.__zr&&this.__zr.isDarkMode()?nr:er},t.prototype.getOutsideStroke=function(t){var e=this.__zr&&this.__zr.getBackgroundColor(),n="string"==typeof e&&Xn(e);n||(n=[255,255,255,1]);for(var i=n[3],r=this.__zr.isDarkMode(),o=0;o<3;o++)n[o]=n[o]*i+(r?0:255)*(1-i);return n[3]=1,ei(n,"rgba")},t.prototype.traverse=function(t,e){},t.prototype.attrKV=function(t,e){"textConfig"===t?this.setTextConfig(e):"textContent"===t?this.setTextContent(e):"clipPath"===t?this.setClipPath(e):"extra"===t?(this.extra=this.extra||{},A(this.extra,e)):this[t]=e},t.prototype.hide=function(){this.ignore=!0,this.markRedraw()},t.prototype.show=function(){this.ignore=!1,this.markRedraw()},t.prototype.attr=function(t,e){if("string"==typeof t)this.attrKV(t,e);else if(q(t))for(var n=G(t),i=0;i0},t.prototype.getState=function(t){return this.states[t]},t.prototype.ensureState=function(t){var e=this.states;return e[t]||(e[t]={}),e[t]},t.prototype.clearStates=function(t){this.useState(wr,!1,t)},t.prototype.useState=function(t,e,n,i){var r=t===wr;if(this.hasState()||!r){var o=this.currentStates,a=this.stateTransition;if(!(P(o,t)>=0)||!e&&1!==o.length){var s;if(this.stateProxy&&!r&&(s=this.stateProxy(t)),s||(s=this.states&&this.states[t]),s||r){r||this.saveCurrentToNormalState(s);var l=!!(s&&s.hoverLayer||i);l&&this._toggleHoverLayerFlag(!0),this._applyStateObj(t,s,this._normalState,e,!n&&!this.__inHover&&a&&a.duration>0,a);var u=this._textContent,h=this._textGuide;return u&&u.useState(t,e,n,l),h&&h.useState(t,e,n,l),r?(this.currentStates=[],this._normalState={}):e?this.currentStates.push(t):this.currentStates=[t],this._updateAnimationTargets(),this.markRedraw(),!l&&this.__inHover&&(this._toggleHoverLayerFlag(!1),this.__dirty&=-2),s}I("State "+t+" not exists.")}}},t.prototype.useStates=function(t,e,n){if(t.length){var i=[],r=this.currentStates,o=t.length,a=o===r.length;if(a)for(var s=0;s0,d);var f=this._textContent,g=this._textGuide;f&&f.useStates(t,e,c),g&&g.useStates(t,e,c),this._updateAnimationTargets(),this.currentStates=t.slice(),this.markRedraw(),!c&&this.__inHover&&(this._toggleHoverLayerFlag(!1),this.__dirty&=-2)}else this.clearStates()},t.prototype._updateAnimationTargets=function(){for(var t=0;t=0){var n=this.currentStates.slice();n.splice(e,1),this.useStates(n)}},t.prototype.replaceState=function(t,e,n){var i=this.currentStates.slice(),r=P(i,t),o=P(i,e)>=0;r>=0?o?i.splice(r,1):i[r]=e:n&&!o&&i.push(e),this.useStates(i)},t.prototype.toggleState=function(t,e){e?this.useState(t,!0):this.removeState(t)},t.prototype._mergeStates=function(t){for(var e,n={},i=0;i=0&&e.splice(n,1)})),this.animators.push(t),n&&n.animation.addAnimator(t),n&&n.wakeUp()},t.prototype.updateDuringAnimation=function(t){this.markRedraw()},t.prototype.stopAnimation=function(t,e){for(var n=this.animators,i=n.length,r=[],o=0;o0&&n.during&&o[0].during((function(t,e){n.during(e)}));for(var p=0;p0||r.force&&!a.length){var w,S=void 0,M=void 0,I=void 0;if(s){M={},p&&(S={});for(_=0;_=0&&(n.splice(i,0,t),this._doAdd(t))}return this},e.prototype.replace=function(t,e){var n=P(this._children,t);return n>=0&&this.replaceAt(e,n),this},e.prototype.replaceAt=function(t,e){var n=this._children,i=n[e];if(t&&t!==this&&t.parent!==this&&t!==i){n[e]=t,i.parent=null;var r=this.__zr;r&&i.removeSelfFromZr(r),this._doAdd(t)}return this},e.prototype._doAdd=function(t){t.parent&&t.parent.remove(t),t.parent=this;var e=this.__zr;e&&e!==t.__zr&&t.addSelfToZr(e),e&&e.refresh()},e.prototype.remove=function(t){var e=this.__zr,n=this._children,i=P(n,t);return i<0||(n.splice(i,1),t.parent=null,e&&t.removeSelfFromZr(e),e&&e.refresh()),this},e.prototype.removeAll=function(){for(var t=this._children,e=this.__zr,n=0;n0&&(this._stillFrameAccum++,this._stillFrameAccum>this._sleepAfterStill&&this.animation.stop())},t.prototype.setSleepAfterStill=function(t){this._sleepAfterStill=t},t.prototype.wakeUp=function(){this.animation.start(),this._stillFrameAccum=0},t.prototype.refreshHover=function(){this._needsRefreshHover=!0},t.prototype.refreshHoverImmediately=function(){this._needsRefreshHover=!1,this.painter.refreshHover&&"canvas"===this.painter.getType()&&this.painter.refreshHover()},t.prototype.resize=function(t){t=t||{},this.painter.resize(t.width,t.height),this.handler.resize()},t.prototype.clearAnimation=function(){this.animation.clear()},t.prototype.getWidth=function(){return this.painter.getWidth()},t.prototype.getHeight=function(){return this.painter.getHeight()},t.prototype.setCursorStyle=function(t){this.handler.setCursorStyle(t)},t.prototype.findHover=function(t,e){return this.handler.findHover(t,e)},t.prototype.on=function(t,e,n){return this.handler.on(t,e,n),this},t.prototype.off=function(t,e){this.handler.off(t,e)},t.prototype.trigger=function(t,e){this.handler.trigger(t,e)},t.prototype.clear=function(){for(var t=this.storage.getRoots(),e=0;e0){if(t<=r)return a;if(t>=o)return s}else{if(t>=r)return a;if(t<=o)return s}else{if(t===r)return a;if(t===o)return s}return(t-r)/l*u+a}function Gr(t,e){switch(t){case"center":case"middle":t="50%";break;case"left":case"top":t="0%";break;case"right":case"bottom":t="100%"}return X(t)?(n=t,n.replace(/^\s+|\s+$/g,"")).match(/%$/)?parseFloat(t)/100*e:parseFloat(t):null==t?NaN:+t;var n}function Wr(t,e,n){return null==e&&(e=10),e=Math.min(Math.max(0,e),20),t=(+t).toFixed(e),n?t:+t}function Hr(t){return t.sort((function(t,e){return t-e})),t}function Yr(t){if(t=+t,isNaN(t))return 0;if(t>1e-14)for(var e=1,n=0;n<15;n++,e*=10)if(Math.round(t*e)/e===t)return n;return Ur(t)}function Ur(t){var e=t.toString().toLowerCase(),n=e.indexOf("e"),i=n>0?+e.slice(n+1):0,r=n>0?n:e.length,o=e.indexOf("."),a=o<0?0:r-1-o;return Math.max(0,a-i)}function Xr(t,e){var n=Math.log,i=Math.LN10,r=Math.floor(n(t[1]-t[0])/i),o=Math.round(n(Math.abs(e[1]-e[0]))/i),a=Math.min(Math.max(-r+o,0),20);return isFinite(a)?a:20}function Zr(t,e){var n=V(t,(function(t,e){return t+(isNaN(e)?0:e)}),0);if(0===n)return[];for(var i=Math.pow(10,e),r=z(t,(function(t){return(isNaN(t)?0:t)/n*i*100})),o=100*i,a=z(r,(function(t){return Math.floor(t)})),s=V(a,(function(t,e){return t+e}),0),l=z(r,(function(t,e){return t-a[e]}));su&&(u=l[c],h=c);++a[h],l[h]=0,++s}return z(a,(function(t){return t/i}))}function jr(t,e){var n=Math.max(Yr(t),Yr(e)),i=t+e;return n>20?i:Wr(i,n)}var qr=9007199254740991;function Kr(t){var e=2*Math.PI;return(t%e+e)%e}function $r(t){return t>-1e-4&&t=10&&e++,e}function no(t,e){var n=eo(t),i=Math.pow(10,n),r=t/i;return t=(e?r<1.5?1:r<2.5?2:r<4?3:r<7?5:10:r<1?1:r<2?2:r<3?3:r<5?5:10)*i,n>=-20?+t.toFixed(n<0?-n:0):t}function io(t,e){var n=(t.length-1)*e+1,i=Math.floor(n),r=+t[i-1],o=n-i;return o?r+o*(t[i]-r):r}function ro(t){t.sort((function(t,e){return s(t,e,0)?-1:1}));for(var e=-1/0,n=1,i=0;i=0||r&&P(r,s)<0)){var l=n.getShallow(s,e);null!=l&&(o[t[a][0]]=l)}}return o}}var jo=Zo([["fill","color"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["opacity"],["shadowColor"]]),qo=function(){function t(){}return t.prototype.getAreaStyle=function(t,e){return jo(this,t,e)},t}(),Ko=new On(50);function $o(t){if("string"==typeof t){var e=Ko.get(t);return e&&e.image}return t}function Jo(t,e,n,i,r){if(t){if("string"==typeof t){if(e&&e.__zrImageSrc===t||!n)return e;var o=Ko.get(t),a={hostEl:n,cb:i,cbPayload:r};return o?!ta(e=o.image)&&o.pending.push(a):((e=h.loadImage(t,Qo,Qo)).__zrImageSrc=t,Ko.put(t,e.__cachedImgObj={image:e,pending:[a]})),e}return t}return e}function Qo(){var t=this.__cachedImgObj;this.onload=this.onerror=this.__cachedImgObj=null;for(var e=0;e=a;l++)s-=a;var u=fr(n,e);return u>s&&(n="",u=0),s=t-u,r.ellipsis=n,r.ellipsisWidth=u,r.contentWidth=s,r.containerWidth=t,r}function ra(t,e){var n=e.containerWidth,i=e.font,r=e.contentWidth;if(!n)return"";var o=fr(t,i);if(o<=n)return t;for(var a=0;;a++){if(o<=r||a>=e.maxIterations){t+=e.ellipsis;break}var s=0===a?oa(t,r,e.ascCharWidth,e.cnCharWidth):o>0?Math.floor(t.length*r/o):0;o=fr(t=t.substr(0,s),i)}return""===t&&(t=e.placeholder),t}function oa(t,e,n,i){for(var r=0,o=0,a=t.length;o0&&f+i.accumWidth>i.width&&(o=e.split("\n"),c=!0),i.accumWidth=f}else{var g=pa(e,h,i.width,i.breakAll,i.accumWidth);i.accumWidth=g.accumWidth+d,a=g.linesWidths,o=g.lines}}else o=e.split("\n");for(var y=0;y=33&&e<=383}(t)||!!ha[t]}function pa(t,e,n,i,r){for(var o=[],a=[],s="",l="",u=0,h=0,c=0;cn:r+h+d>n)?h?(s||l)&&(f?(s||(s=l,l="",h=u=0),o.push(s),a.push(h-u),l+=p,s="",h=u+=d):(l&&(s+=l,l="",u=0),o.push(s),a.push(h),s=p,h=d)):f?(o.push(l),a.push(u),l=p,u=d):(o.push(p),a.push(d)):(h+=d,f?(l+=p,u+=d):(l&&(s+=l,l="",u=0),s+=p))}else l&&(s+=l,h+=u),o.push(s),a.push(h),s="",l="",u=0,h=0}return o.length||s||(s=t,l="",u=0),l&&(s+=l),s&&(o.push(s),a.push(h)),1===o.length&&(h+=r),{accumWidth:h,lines:o,linesWidths:a}}var da="__zr_style_"+Math.round(10*Math.random()),fa={shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0,shadowColor:"#000",opacity:1,blend:"source-over"},ga={style:{shadowBlur:!0,shadowOffsetX:!0,shadowOffsetY:!0,shadowColor:!0,opacity:!0}};fa[da]=!0;var ya=["z","z2","invisible"],va=["invisible"],ma=function(t){function e(e){return t.call(this,e)||this}var i;return n(e,t),e.prototype._init=function(e){for(var n=G(e),i=0;i1e-4)return s[0]=t-n,s[1]=e-i,l[0]=t+n,void(l[1]=e+i);if(Ta[0]=Ma(r)*n+t,Ta[1]=Sa(r)*i+e,Ca[0]=Ma(o)*n+t,Ca[1]=Sa(o)*i+e,u(s,Ta,Ca),h(l,Ta,Ca),(r%=Ia)<0&&(r+=Ia),(o%=Ia)<0&&(o+=Ia),r>o&&!a?o+=Ia:rr&&(Da[0]=Ma(d)*n+t,Da[1]=Sa(d)*i+e,u(s,Da,s),h(l,Da,l))}var Ea={M:1,L:2,C:3,Q:4,A:5,Z:6,R:7},za=[],Va=[],Ba=[],Fa=[],Ga=[],Wa=[],Ha=Math.min,Ya=Math.max,Ua=Math.cos,Xa=Math.sin,Za=Math.abs,ja=Math.PI,qa=2*ja,Ka="undefined"!=typeof Float32Array,$a=[];function Ja(t){return Math.round(t/ja*1e8)/1e8%2*ja}function Qa(t,e){var n=Ja(t[0]);n<0&&(n+=qa);var i=n-t[0],r=t[1];r+=i,!e&&r-n>=qa?r=n+qa:e&&n-r>=qa?r=n-qa:!e&&n>r?r=n+(qa-Ja(n-r)):e&&n0&&(this._ux=Za(n/tr/t)||0,this._uy=Za(n/tr/e)||0)},t.prototype.setDPR=function(t){this.dpr=t},t.prototype.setContext=function(t){this._ctx=t},t.prototype.getContext=function(){return this._ctx},t.prototype.beginPath=function(){return this._ctx&&this._ctx.beginPath(),this.reset(),this},t.prototype.reset=function(){this._saveData&&(this._len=0),this._pathSegLen&&(this._pathSegLen=null,this._pathLen=0),this._version++},t.prototype.moveTo=function(t,e){return this._drawPendingPt(),this.addData(Ea.M,t,e),this._ctx&&this._ctx.moveTo(t,e),this._x0=t,this._y0=e,this._xi=t,this._yi=e,this},t.prototype.lineTo=function(t,e){var n=Za(t-this._xi),i=Za(e-this._yi),r=n>this._ux||i>this._uy;if(this.addData(Ea.L,t,e),this._ctx&&r&&this._ctx.lineTo(t,e),r)this._xi=t,this._yi=e,this._pendingPtDist=0;else{var o=n*n+i*i;o>this._pendingPtDist&&(this._pendingPtX=t,this._pendingPtY=e,this._pendingPtDist=o)}return this},t.prototype.bezierCurveTo=function(t,e,n,i,r,o){return this._drawPendingPt(),this.addData(Ea.C,t,e,n,i,r,o),this._ctx&&this._ctx.bezierCurveTo(t,e,n,i,r,o),this._xi=r,this._yi=o,this},t.prototype.quadraticCurveTo=function(t,e,n,i){return this._drawPendingPt(),this.addData(Ea.Q,t,e,n,i),this._ctx&&this._ctx.quadraticCurveTo(t,e,n,i),this._xi=n,this._yi=i,this},t.prototype.arc=function(t,e,n,i,r,o){this._drawPendingPt(),$a[0]=i,$a[1]=r,Qa($a,o),i=$a[0];var a=(r=$a[1])-i;return this.addData(Ea.A,t,e,n,n,i,a,0,o?0:1),this._ctx&&this._ctx.arc(t,e,n,i,r,o),this._xi=Ua(r)*n+t,this._yi=Xa(r)*n+e,this},t.prototype.arcTo=function(t,e,n,i,r){return this._drawPendingPt(),this._ctx&&this._ctx.arcTo(t,e,n,i,r),this},t.prototype.rect=function(t,e,n,i){return this._drawPendingPt(),this._ctx&&this._ctx.rect(t,e,n,i),this.addData(Ea.R,t,e,n,i),this},t.prototype.closePath=function(){this._drawPendingPt(),this.addData(Ea.Z);var t=this._ctx,e=this._x0,n=this._y0;return t&&t.closePath(),this._xi=e,this._yi=n,this},t.prototype.fill=function(t){t&&t.fill(),this.toStatic()},t.prototype.stroke=function(t){t&&t.stroke(),this.toStatic()},t.prototype.len=function(){return this._len},t.prototype.setData=function(t){var e=t.length;this.data&&this.data.length===e||!Ka||(this.data=new Float32Array(e));for(var n=0;nu.length&&(this._expandData(),u=this.data);for(var h=0;h0&&(this._ctx&&this._ctx.lineTo(this._pendingPtX,this._pendingPtY),this._pendingPtDist=0)},t.prototype._expandData=function(){if(!(this.data instanceof Array)){for(var t=[],e=0;e11&&(this.data=new Float32Array(t)))}},t.prototype.getBoundingRect=function(){Ba[0]=Ba[1]=Ga[0]=Ga[1]=Number.MAX_VALUE,Fa[0]=Fa[1]=Wa[0]=Wa[1]=-Number.MAX_VALUE;var t,e=this.data,n=0,i=0,r=0,o=0;for(t=0;tn||Za(y)>i||c===e-1)&&(f=Math.sqrt(A*A+y*y),r=g,o=x);break;case Ea.C:var v=t[c++],m=t[c++],x=(g=t[c++],t[c++]),_=t[c++],b=t[c++];f=bn(r,o,v,m,g,x,_,b,10),r=_,o=b;break;case Ea.Q:f=Cn(r,o,v=t[c++],m=t[c++],g=t[c++],x=t[c++],10),r=g,o=x;break;case Ea.A:var w=t[c++],S=t[c++],M=t[c++],I=t[c++],T=t[c++],C=t[c++],D=C+T;c+=1;t[c++];d&&(a=Ua(T)*M+w,s=Xa(T)*I+S),f=Ya(M,I)*Ha(qa,Math.abs(C)),r=Ua(D)*M+w,o=Xa(D)*I+S;break;case Ea.R:a=r=t[c++],s=o=t[c++],f=2*t[c++]+2*t[c++];break;case Ea.Z:var A=a-r;y=s-o;f=Math.sqrt(A*A+y*y),r=a,o=s}f>=0&&(l[h++]=f,u+=f)}return this._pathLen=u,u},t.prototype.rebuildPath=function(t,e){var n,i,r,o,a,s,l,u,h,c,p=this.data,d=this._ux,f=this._uy,g=this._len,y=e<1,v=0,m=0,x=0;if(!y||(this._pathSegLen||this._calculateLength(),l=this._pathSegLen,u=e*this._pathLen))t:for(var _=0;_0&&(t.lineTo(h,c),x=0),b){case Ea.M:n=r=p[_++],i=o=p[_++],t.moveTo(r,o);break;case Ea.L:a=p[_++],s=p[_++];var S=Za(a-r),M=Za(s-o);if(S>d||M>f){if(y){if(v+(j=l[m++])>u){var I=(u-v)/j;t.lineTo(r*(1-I)+a*I,o*(1-I)+s*I);break t}v+=j}t.lineTo(a,s),r=a,o=s,x=0}else{var T=S*S+M*M;T>x&&(h=a,c=s,x=T)}break;case Ea.C:var C=p[_++],D=p[_++],A=p[_++],k=p[_++],L=p[_++],P=p[_++];if(y){if(v+(j=l[m++])>u){xn(r,C,A,L,I=(u-v)/j,za),xn(o,D,k,P,I,Va),t.bezierCurveTo(za[1],Va[1],za[2],Va[2],za[3],Va[3]);break t}v+=j}t.bezierCurveTo(C,D,A,k,L,P),r=L,o=P;break;case Ea.Q:C=p[_++],D=p[_++],A=p[_++],k=p[_++];if(y){if(v+(j=l[m++])>u){In(r,C,A,I=(u-v)/j,za),In(o,D,k,I,Va),t.quadraticCurveTo(za[1],Va[1],za[2],Va[2]);break t}v+=j}t.quadraticCurveTo(C,D,A,k),r=A,o=k;break;case Ea.A:var O=p[_++],R=p[_++],N=p[_++],E=p[_++],z=p[_++],V=p[_++],B=p[_++],F=!p[_++],G=N>E?N:E,W=Za(N-E)>.001,H=z+V,Y=!1;if(y)v+(j=l[m++])>u&&(H=z+V*(u-v)/j,Y=!0),v+=j;if(W&&t.ellipse?t.ellipse(O,R,N,E,B,z,H,F):t.arc(O,R,G,z,H,F),Y)break t;w&&(n=Ua(z)*N+O,i=Xa(z)*E+R),r=Ua(H)*N+O,o=Xa(H)*E+R;break;case Ea.R:n=r=p[_],i=o=p[_+1],a=p[_++],s=p[_++];var U=p[_++],X=p[_++];if(y){if(v+(j=l[m++])>u){var Z=u-v;t.moveTo(a,s),t.lineTo(a+Ha(Z,U),s),(Z-=U)>0&&t.lineTo(a+U,s+Ha(Z,X)),(Z-=X)>0&&t.lineTo(a+Ya(U-Z,0),s+X),(Z-=U)>0&&t.lineTo(a,s+Ya(X-Z,0));break t}v+=j}t.rect(a,s,U,X);break;case Ea.Z:if(y){var j;if(v+(j=l[m++])>u){I=(u-v)/j;t.lineTo(r*(1-I)+n*I,o*(1-I)+i*I);break t}v+=j}t.closePath(),r=n,o=i}}},t.prototype.clone=function(){var e=new t,n=this.data;return e.data=n.slice?n.slice():Array.prototype.slice.call(n),e._len=this._len,e},t.CMD=Ea,t.initDefaultProps=function(){var e=t.prototype;e._saveData=!0,e._ux=0,e._uy=0,e._pendingPtDist=0,e._version=0}(),t}();function es(t,e,n,i,r,o,a){if(0===r)return!1;var s=r,l=0;if(a>e+s&&a>i+s||at+s&&o>n+s||oe+c&&h>i+c&&h>o+c&&h>s+c||ht+c&&u>n+c&&u>r+c&&u>a+c||ue+u&&l>i+u&&l>o+u||lt+u&&s>n+u&&s>r+u||sn||h+ur&&(r+=as);var p=Math.atan2(l,s);return p<0&&(p+=as),p>=i&&p<=r||p+as>=i&&p+as<=r}function ls(t,e,n,i,r,o){if(o>e&&o>i||or?s:0}var us=ts.CMD,hs=2*Math.PI;var cs=[-1,-1,-1],ps=[-1,-1];function ds(t,e,n,i,r,o,a,s,l,u){if(u>e&&u>i&&u>o&&u>s||u1&&(h=void 0,h=ps[0],ps[0]=ps[1],ps[1]=h),f=gn(e,i,o,s,ps[0]),d>1&&(g=gn(e,i,o,s,ps[1]))),2===d?ve&&s>i&&s>o||s=0&&h<=1&&(r[l++]=h);else{var u=a*a-4*o*s;if(dn(u))(h=-a/(2*o))>=0&&h<=1&&(r[l++]=h);else if(u>0){var h,c=on(u),p=(-a-c)/(2*o);(h=(-a+c)/(2*o))>=0&&h<=1&&(r[l++]=h),p>=0&&p<=1&&(r[l++]=p)}}return l}(e,i,o,s,cs);if(0===l)return 0;var u=Mn(e,i,o);if(u>=0&&u<=1){for(var h=0,c=wn(e,i,o,u),p=0;pn||s<-n)return 0;var l=Math.sqrt(n*n-s*s);cs[0]=-l,cs[1]=l;var u=Math.abs(i-r);if(u<1e-4)return 0;if(u>=hs-1e-4){i=0,r=hs;var h=o?1:-1;return a>=cs[0]+t&&a<=cs[1]+t?h:0}if(i>r){var c=i;i=r,r=c}i<0&&(i+=hs,r+=hs);for(var p=0,d=0;d<2;d++){var f=cs[d];if(f+t>a){var g=Math.atan2(s,f);h=o?1:-1;g<0&&(g=hs+g),(g>=i&&g<=r||g+hs>=i&&g+hs<=r)&&(g>Math.PI/2&&g<1.5*Math.PI&&(h=-h),p+=h)}}return p}function ys(t,e,n,i,r){for(var o,a,s,l,u=t.data,h=t.len(),c=0,p=0,d=0,f=0,g=0,y=0;y1&&(n||(c+=ls(p,d,f,g,i,r))),m&&(f=p=u[y],g=d=u[y+1]),v){case us.M:p=f=u[y++],d=g=u[y++];break;case us.L:if(n){if(es(p,d,u[y],u[y+1],e,i,r))return!0}else c+=ls(p,d,u[y],u[y+1],i,r)||0;p=u[y++],d=u[y++];break;case us.C:if(n){if(ns(p,d,u[y++],u[y++],u[y++],u[y++],u[y],u[y+1],e,i,r))return!0}else c+=ds(p,d,u[y++],u[y++],u[y++],u[y++],u[y],u[y+1],i,r)||0;p=u[y++],d=u[y++];break;case us.Q:if(n){if(is(p,d,u[y++],u[y++],u[y],u[y+1],e,i,r))return!0}else c+=fs(p,d,u[y++],u[y++],u[y],u[y+1],i,r)||0;p=u[y++],d=u[y++];break;case us.A:var x=u[y++],_=u[y++],b=u[y++],w=u[y++],S=u[y++],M=u[y++];y+=1;var I=!!(1-u[y++]);o=Math.cos(S)*b+x,a=Math.sin(S)*w+_,m?(f=o,g=a):c+=ls(p,d,o,a,i,r);var T=(i-x)*w/b+x;if(n){if(ss(x,_,w,S,S+M,I,e,T,r))return!0}else c+=gs(x,_,w,S,S+M,I,T,r);p=Math.cos(S+M)*b+x,d=Math.sin(S+M)*w+_;break;case us.R:if(f=p=u[y++],g=d=u[y++],o=f+u[y++],a=g+u[y++],n){if(es(f,g,o,g,e,i,r)||es(o,g,o,a,e,i,r)||es(o,a,f,a,e,i,r)||es(f,a,f,g,e,i,r))return!0}else c+=ls(o,g,o,a,i,r),c+=ls(f,a,f,g,i,r);break;case us.Z:if(n){if(es(p,d,f,g,e,i,r))return!0}else c+=ls(p,d,f,g,i,r);p=f,d=g}}return n||(s=d,l=g,Math.abs(s-l)<1e-4)||(c+=ls(p,d,f,g,i,r)||0),0!==c}var vs=k({fill:"#000",stroke:null,strokePercent:1,fillOpacity:1,strokeOpacity:1,lineDashOffset:0,lineWidth:1,lineCap:"butt",miterLimit:10,strokeNoScale:!1,strokeFirst:!1},fa),ms={style:k({fill:!0,stroke:!0,strokePercent:!0,fillOpacity:!0,strokeOpacity:!0,lineDashOffset:!0,lineWidth:!0,miterLimit:!0},ga.style)},xs=cr.concat(["invisible","culling","z","z2","zlevel","parent"]),_s=function(t){function e(e){return t.call(this,e)||this}var i;return n(e,t),e.prototype.update=function(){var n=this;t.prototype.update.call(this);var i=this.style;if(i.decal){var r=this._decalEl=this._decalEl||new e;r.buildPath===e.prototype.buildPath&&(r.buildPath=function(t){n.buildPath(t,n.shape)}),r.silent=!0;var o=r.style;for(var a in i)o[a]!==i[a]&&(o[a]=i[a]);o.fill=i.fill?i.decal:null,o.decal=null,o.shadowColor=null,i.strokeFirst&&(o.stroke=null);for(var s=0;s.5?er:e>.2?"#eee":nr}if(t)return nr}return er},e.prototype.getInsideTextStroke=function(t){var e=this.style.fill;if(X(e)){var n=this.__zr;if(!(!n||!n.isDarkMode())===ni(t,0)<.4)return e}},e.prototype.buildPath=function(t,e,n){},e.prototype.pathUpdated=function(){this.__dirty&=-5},e.prototype.getUpdatedPathProxy=function(t){return!this.path&&this.createPathProxy(),this.path.beginPath(),this.buildPath(this.path,this.shape,t),this.path},e.prototype.createPathProxy=function(){this.path=new ts(!1)},e.prototype.hasStroke=function(){var t=this.style,e=t.stroke;return!(null==e||"none"===e||!(t.lineWidth>0))},e.prototype.hasFill=function(){var t=this.style.fill;return null!=t&&"none"!==t},e.prototype.getBoundingRect=function(){var t=this._rect,e=this.style,n=!t;if(n){var i=!1;this.path||(i=!0,this.createPathProxy());var r=this.path;(i||4&this.__dirty)&&(r.beginPath(),this.buildPath(r,this.shape,!1),this.pathUpdated()),t=r.getBoundingRect()}if(this._rect=t,this.hasStroke()&&this.path&&this.path.len()>0){var o=this._rectStroke||(this._rectStroke=t.clone());if(this.__dirty||n){o.copy(t);var a=e.strokeNoScale?this.getLineScale():1,s=e.lineWidth;if(!this.hasFill()){var l=this.strokeContainThreshold;s=Math.max(s,null==l?4:l)}a>1e-10&&(o.width+=s/a,o.height+=s/a,o.x-=s/a/2,o.y-=s/a/2)}return o}return t},e.prototype.contain=function(t,e){var n=this.transformCoordToLocal(t,e),i=this.getBoundingRect(),r=this.style;if(t=n[0],e=n[1],i.contain(t,e)){var o=this.path;if(this.hasStroke()){var a=r.lineWidth,s=r.strokeNoScale?this.getLineScale():1;if(s>1e-10&&(this.hasFill()||(a=Math.max(a,this.strokeContainThreshold)),function(t,e,n,i){return ys(t,e,!0,n,i)}(o,a/s,t,e)))return!0}if(this.hasFill())return function(t,e,n){return ys(t,0,!1,e,n)}(o,t,e)}return!1},e.prototype.dirtyShape=function(){this.__dirty|=4,this._rect&&(this._rect=null),this._decalEl&&this._decalEl.dirtyShape(),this.markRedraw()},e.prototype.dirty=function(){this.dirtyStyle(),this.dirtyShape()},e.prototype.animateShape=function(t){return this.animate("shape",t)},e.prototype.updateDuringAnimation=function(t){"style"===t?this.dirtyStyle():"shape"===t?this.dirtyShape():this.markRedraw()},e.prototype.attrKV=function(e,n){"shape"===e?this.setShape(n):t.prototype.attrKV.call(this,e,n)},e.prototype.setShape=function(t,e){var n=this.shape;return n||(n=this.shape={}),"string"==typeof t?n[t]=e:A(n,t),this.dirtyShape(),this},e.prototype.shapeChanged=function(){return!!(4&this.__dirty)},e.prototype.createStyle=function(t){return yt(vs,t)},e.prototype._innerSaveToNormal=function(e){t.prototype._innerSaveToNormal.call(this,e);var n=this._normalState;e.shape&&!n.shape&&(n.shape=A({},this.shape))},e.prototype._applyStateObj=function(e,n,i,r,o,a){t.prototype._applyStateObj.call(this,e,n,i,r,o,a);var s,l=!(n&&r);if(n&&n.shape?o?r?s=n.shape:(s=A({},i.shape),A(s,n.shape)):(s=A({},r?this.shape:i.shape),A(s,n.shape)):l&&(s=i.shape),s)if(o){this.shape=A({},this.shape);for(var u={},h=G(s),c=0;c0},e.prototype.hasFill=function(){var t=this.style.fill;return null!=t&&"none"!==t},e.prototype.createStyle=function(t){return yt(bs,t)},e.prototype.setBoundingRect=function(t){this._rect=t},e.prototype.getBoundingRect=function(){var t=this.style;if(!this._rect){var e=t.text;null!=e?e+="":e="";var n=yr(e,t.font,t.textAlign,t.textBaseline);if(n.x+=t.x||0,n.y+=t.y||0,this.hasStroke()){var i=t.lineWidth;n.x-=i/2,n.y-=i/2,n.width+=i,n.height+=i}this._rect=n}return this._rect},e.initDefaultProps=void(e.prototype.dirtyRectTolerance=10),e}(ma);ws.prototype.type="tspan";var Ss=k({x:0,y:0},fa),Ms={style:k({x:!0,y:!0,width:!0,height:!0,sx:!0,sy:!0,sWidth:!0,sHeight:!0},ga.style)};var Is=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.createStyle=function(t){return yt(Ss,t)},e.prototype._getSize=function(t){var e=this.style,n=e[t];if(null!=n)return n;var i,r=(i=e.image)&&"string"!=typeof i&&i.width&&i.height?e.image:this.__image;if(!r)return 0;var o="width"===t?"height":"width",a=e[o];return null==a?r[t]:r[t]/r[o]*a},e.prototype.getWidth=function(){return this._getSize("width")},e.prototype.getHeight=function(){return this._getSize("height")},e.prototype.getAnimationStyleProps=function(){return Ms},e.prototype.getBoundingRect=function(){var t=this.style;return this._rect||(this._rect=new Re(t.x||0,t.y||0,this.getWidth(),this.getHeight())),this._rect},e}(ma);Is.prototype.type="image";var Ts=Math.round;function Cs(t,e,n){if(e){var i=e.x1,r=e.x2,o=e.y1,a=e.y2;t.x1=i,t.x2=r,t.y1=o,t.y2=a;var s=n&&n.lineWidth;return s?(Ts(2*i)===Ts(2*r)&&(t.x1=t.x2=As(i,s,!0)),Ts(2*o)===Ts(2*a)&&(t.y1=t.y2=As(o,s,!0)),t):t}}function Ds(t,e,n){if(e){var i=e.x,r=e.y,o=e.width,a=e.height;t.x=i,t.y=r,t.width=o,t.height=a;var s=n&&n.lineWidth;return s?(t.x=As(i,s,!0),t.y=As(r,s,!0),t.width=Math.max(As(i+o,s,!1)-t.x,0===o?0:1),t.height=Math.max(As(r+a,s,!1)-t.y,0===a?0:1),t):t}}function As(t,e,n){if(!e)return t;var i=Ts(2*t);return(i+Ts(e))%2==0?i/2:(i+(n?1:-1))/2}var ks=function(){this.x=0,this.y=0,this.width=0,this.height=0},Ls={},Ps=function(t){function e(e){return t.call(this,e)||this}return n(e,t),e.prototype.getDefaultShape=function(){return new ks},e.prototype.buildPath=function(t,e){var n,i,r,o;if(this.subPixelOptimize){var a=Ds(Ls,e,this.style);n=a.x,i=a.y,r=a.width,o=a.height,a.r=e.r,e=a}else n=e.x,i=e.y,r=e.width,o=e.height;e.r?function(t,e){var n,i,r,o,a,s=e.x,l=e.y,u=e.width,h=e.height,c=e.r;u<0&&(s+=u,u=-u),h<0&&(l+=h,h=-h),"number"==typeof c?n=i=r=o=c:c instanceof Array?1===c.length?n=i=r=o=c[0]:2===c.length?(n=r=c[0],i=o=c[1]):3===c.length?(n=c[0],i=o=c[1],r=c[2]):(n=c[0],i=c[1],r=c[2],o=c[3]):n=i=r=o=0,n+i>u&&(n*=u/(a=n+i),i*=u/a),r+o>u&&(r*=u/(a=r+o),o*=u/a),i+r>h&&(i*=h/(a=i+r),r*=h/a),n+o>h&&(n*=h/(a=n+o),o*=h/a),t.moveTo(s+n,l),t.lineTo(s+u-i,l),0!==i&&t.arc(s+u-i,l+i,i,-Math.PI/2,0),t.lineTo(s+u,l+h-r),0!==r&&t.arc(s+u-r,l+h-r,r,0,Math.PI/2),t.lineTo(s+o,l+h),0!==o&&t.arc(s+o,l+h-o,o,Math.PI/2,Math.PI),t.lineTo(s,l+n),0!==n&&t.arc(s+n,l+n,n,Math.PI,1.5*Math.PI)}(t,e):t.rect(n,i,r,o)},e.prototype.isZeroArea=function(){return!this.shape.width||!this.shape.height},e}(_s);Ps.prototype.type="rect";var Os={fill:"#000"},Rs={style:k({fill:!0,stroke:!0,fillOpacity:!0,strokeOpacity:!0,lineWidth:!0,fontSize:!0,lineHeight:!0,width:!0,height:!0,textShadowColor:!0,textShadowBlur:!0,textShadowOffsetX:!0,textShadowOffsetY:!0,backgroundColor:!0,padding:!0,borderColor:!0,borderWidth:!0,borderRadius:!0},ga.style)},Ns=function(t){function e(e){var n=t.call(this)||this;return n.type="text",n._children=[],n._defaultStyle=Os,n.attr(e),n}return n(e,t),e.prototype.childrenRef=function(){return this._children},e.prototype.update=function(){t.prototype.update.call(this),this.styleChanged()&&this._updateSubTexts();for(var e=0;ed&&h){var f=Math.floor(d/l);n=n.slice(0,f)}if(t&&a&&null!=c)for(var g=ia(c,o,e.ellipsis,{minChar:e.truncateMinChar,placeholder:e.placeholder}),y=0;y0,T=null!=t.width&&("truncate"===t.overflow||"break"===t.overflow||"breakAll"===t.overflow),C=i.calculatedLineHeight,D=0;Dl&&ua(n,t.substring(l,u),e,s),ua(n,i[2],e,s,i[1]),l=ea.lastIndex}lo){b>0?(m.tokens=m.tokens.slice(0,b),y(m,_,x),n.lines=n.lines.slice(0,v+1)):n.lines=n.lines.slice(0,v);break t}var C=w.width,D=null==C||"auto"===C;if("string"==typeof C&&"%"===C.charAt(C.length-1))P.percentWidth=C,h.push(P),P.contentWidth=fr(P.text,I);else{if(D){var A=w.backgroundColor,k=A&&A.image;k&&ta(k=$o(k))&&(P.width=Math.max(P.width,k.width*T/k.height))}var L=f&&null!=r?r-_:null;null!=L&&L=0&&"right"===(C=x[T]).align;)this._placeToken(C,t,b,f,I,"right",y),w-=C.width,I-=C.width,T--;for(M+=(n-(M-d)-(g-I)-w)/2;S<=T;)C=x[S],this._placeToken(C,t,b,f,M+C.width/2,"center",y),M+=C.width,S++;f+=b}},e.prototype._placeToken=function(t,e,n,i,r,o,s){var l=e.rich[t.styleName]||{};l.text=t.text;var u=t.verticalAlign,h=i+n/2;"top"===u?h=i+t.height/2:"bottom"===u&&(h=i+n-t.height/2),!t.isLineHolder&&Zs(l)&&this._renderBackground(l,e,"right"===o?r-t.width:"center"===o?r-t.width/2:r,h-t.height/2,t.width,t.height);var c=!!l.backgroundColor,p=t.textPadding;p&&(r=Us(r,o,p),h-=t.height/2-p[0]-t.innerHeight/2);var d=this._getOrCreateChild(ws),f=d.createStyle();d.useStyle(f);var g=this._defaultStyle,y=!1,v=0,m=Ys("fill"in l?l.fill:"fill"in e?e.fill:(y=!0,g.fill)),x=Hs("stroke"in l?l.stroke:"stroke"in e?e.stroke:c||s||g.autoStroke&&!y?null:(v=2,g.stroke)),_=l.textShadowBlur>0||e.textShadowBlur>0;f.text=t.text,f.x=r,f.y=h,_&&(f.shadowBlur=l.textShadowBlur||e.textShadowBlur||0,f.shadowColor=l.textShadowColor||e.textShadowColor||"transparent",f.shadowOffsetX=l.textShadowOffsetX||e.textShadowOffsetX||0,f.shadowOffsetY=l.textShadowOffsetY||e.textShadowOffsetY||0),f.textAlign=o,f.textBaseline="middle",f.font=t.font||a,f.opacity=ot(l.opacity,e.opacity,1),Fs(f,l),x&&(f.lineWidth=ot(l.lineWidth,e.lineWidth,v),f.lineDash=rt(l.lineDash,e.lineDash),f.lineDashOffset=e.lineDashOffset||0,f.stroke=x),m&&(f.fill=m);var b=t.contentWidth,w=t.contentHeight;d.setBoundingRect(new Re(vr(f.x,b,f.textAlign),mr(f.y,w,f.textBaseline),b,w))},e.prototype._renderBackground=function(t,e,n,i,r,o){var a,s,l,u=t.backgroundColor,h=t.borderWidth,c=t.borderColor,p=u&&u.image,d=u&&!p,f=t.borderRadius,g=this;if(d||t.lineHeight||h&&c){(a=this._getOrCreateChild(Ps)).useStyle(a.createStyle()),a.style.fill=null;var y=a.shape;y.x=n,y.y=i,y.width=r,y.height=o,y.r=f,a.dirtyShape()}if(d)(l=a.style).fill=u||null,l.fillOpacity=rt(t.fillOpacity,1);else if(p){(s=this._getOrCreateChild(Is)).onload=function(){g.dirtyStyle()};var v=s.style;v.image=u.image,v.x=n,v.y=i,v.width=r,v.height=o}h&&c&&((l=a.style).lineWidth=h,l.stroke=c,l.strokeOpacity=rt(t.strokeOpacity,1),l.lineDash=t.borderDash,l.lineDashOffset=t.borderDashOffset||0,a.strokeContainThreshold=0,a.hasFill()&&a.hasStroke()&&(l.strokeFirst=!0,l.lineWidth*=2));var m=(a||s).style;m.shadowBlur=t.shadowBlur||0,m.shadowColor=t.shadowColor||"transparent",m.shadowOffsetX=t.shadowOffsetX||0,m.shadowOffsetY=t.shadowOffsetY||0,m.opacity=ot(t.opacity,e.opacity,1)},e.makeFont=function(t){var e="";return Gs(t)&&(e=[t.fontStyle,t.fontWeight,Bs(t.fontSize),t.fontFamily||"sans-serif"].join(" ")),e&&ut(e)||t.textFont||t.font},e}(ma),Es={left:!0,right:1,center:1},zs={top:1,bottom:1,middle:1},Vs=["fontStyle","fontWeight","fontSize","fontFamily"];function Bs(t){return"string"!=typeof t||-1===t.indexOf("px")&&-1===t.indexOf("rem")&&-1===t.indexOf("em")?isNaN(+t)?"12px":t+"px":t}function Fs(t,e){for(var n=0;n=0,o=!1;if(t instanceof _s){var a=Js(t),s=r&&a.selectFill||a.normalFill,l=r&&a.selectStroke||a.normalStroke;if(ll(s)||ll(l)){var u=(i=i||{}).style||{};"inherit"===u.fill?(o=!0,i=A({},i),(u=A({},u)).fill=s):!ll(u.fill)&&ll(s)?(o=!0,i=A({},i),(u=A({},u)).fill=hl(s)):!ll(u.stroke)&&ll(l)&&(o||(i=A({},i),u=A({},u)),u.stroke=hl(l)),i.style=u}}if(i&&null==i.z2){o||(i=A({},i));var h=t.z2EmphasisLift;i.z2=t.z2+(null!=h?h:nl)}return i}(this,0,e,n);if("blur"===t)return function(t,e,n){var i=P(t.currentStates,e)>=0,r=t.style.opacity,o=i?null:function(t,e,n,i){for(var r=t.style,o={},a=0;a0){var o={dataIndex:r,seriesIndex:t.seriesIndex};null!=i&&(o.dataType=i),e.push(o)}}))})),e}function Vl(t,e,n){Yl(t,!0),xl(t,wl),Fl(t,e,n)}function Bl(t,e,n,i){i?function(t){Yl(t,!1)}(t):Vl(t,e,n)}function Fl(t,e,n){var i=js(t);null!=e?(i.focus=e,i.blurScope=n):i.focus&&(i.focus=null)}var Gl=["emphasis","blur","select"],Wl={itemStyle:"getItemStyle",lineStyle:"getLineStyle",areaStyle:"getAreaStyle"};function Hl(t,e,n,i){n=n||"itemStyle";for(var r=0;r1&&(a*=Ql(f),s*=Ql(f));var g=(r===o?-1:1)*Ql((a*a*(s*s)-a*a*(d*d)-s*s*(p*p))/(a*a*(d*d)+s*s*(p*p)))||0,y=g*a*d/s,v=g*-s*p/a,m=(t+n)/2+eu(c)*y-tu(c)*v,x=(e+i)/2+tu(c)*y+eu(c)*v,_=ou([1,0],[(p-y)/a,(d-v)/s]),b=[(p-y)/a,(d-v)/s],w=[(-1*p-y)/a,(-1*d-v)/s],S=ou(b,w);if(ru(b,w)<=-1&&(S=nu),ru(b,w)>=1&&(S=0),S<0){var M=Math.round(S/nu*1e6)/1e6;S=2*nu+M%2*nu}h.addData(u,m,x,a,s,_,S,c,o)}var su=/([mlvhzcqtsa])([^mlvhzcqtsa]*)/gi,lu=/-?([0-9]*\.)?[0-9]+([eE]-?[0-9]+)?/g;var uu=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.applyTransform=function(t){},e}(_s);function hu(t){return null!=t.setData}function cu(t,e){var n=function(t){var e=new ts;if(!t)return e;var n,i=0,r=0,o=i,a=r,s=ts.CMD,l=t.match(su);if(!l)return e;for(var u=0;uk*k+L*L&&(M=T,I=C),{cx:M,cy:I,x0:-h,y0:-c,x1:M*(r/b-1),y1:I*(r/b-1)}}function ku(t,e){var n,i=Tu(e.r,0),r=Tu(e.r0||0,0),o=i>0;if(o||r>0){if(o||(i=r,r=0),r>i){var a=i;i=r,r=a}var s=e.startAngle,l=e.endAngle;if(!isNaN(s)&&!isNaN(l)){var u=e.cx,h=e.cy,c=!!e.clockwise,p=Mu(l-s),d=p>xu&&p%xu;if(d>Du&&(p=d),i>Du)if(p>xu-Du)t.moveTo(u+i*bu(s),h+i*_u(s)),t.arc(u,h,i,s,l,!c),r>Du&&(t.moveTo(u+r*bu(l),h+r*_u(l)),t.arc(u,h,r,l,s,c));else{var f=void 0,g=void 0,y=void 0,v=void 0,m=void 0,x=void 0,_=void 0,b=void 0,w=void 0,S=void 0,M=void 0,I=void 0,T=void 0,C=void 0,D=void 0,A=void 0,k=i*bu(s),L=i*_u(s),P=r*bu(l),O=r*_u(l),R=p>Du;if(R){var N=e.cornerRadius;N&&(n=function(t){var e;if(Y(t)){var n=t.length;if(!n)return t;e=1===n?[t[0],t[0],0,0]:2===n?[t[0],t[0],t[1],t[1]]:3===n?t.concat(t[2]):t}else e=[t,t,t,t];return e}(N),f=n[0],g=n[1],y=n[2],v=n[3]);var E=Mu(i-r)/2;if(m=Cu(E,y),x=Cu(E,v),_=Cu(E,f),b=Cu(E,g),M=w=Tu(m,x),I=S=Tu(_,b),(w>Du||S>Du)&&(T=i*bu(l),C=i*_u(l),D=r*bu(s),A=r*_u(s),pDu){var U=Cu(y,M),X=Cu(v,M),Z=Au(D,A,k,L,i,U,c),j=Au(T,C,P,O,i,X,c);t.moveTo(u+Z.cx+Z.x0,h+Z.cy+Z.y0),M0&&t.arc(u+Z.cx,h+Z.cy,U,Su(Z.y0,Z.x0),Su(Z.y1,Z.x1),!c),t.arc(u,h,i,Su(Z.cy+Z.y1,Z.cx+Z.x1),Su(j.cy+j.y1,j.cx+j.x1),!c),X>0&&t.arc(u+j.cx,h+j.cy,X,Su(j.y1,j.x1),Su(j.y0,j.x0),!c))}else t.moveTo(u+k,h+L),t.arc(u,h,i,s,l,!c);else t.moveTo(u+k,h+L);if(r>Du&&R)if(I>Du){U=Cu(f,I),Z=Au(P,O,T,C,r,-(X=Cu(g,I)),c),j=Au(k,L,D,A,r,-U,c);t.lineTo(u+Z.cx+Z.x0,h+Z.cy+Z.y0),I0&&t.arc(u+Z.cx,h+Z.cy,X,Su(Z.y0,Z.x0),Su(Z.y1,Z.x1),!c),t.arc(u,h,r,Su(Z.cy+Z.y1,Z.cx+Z.x1),Su(j.cy+j.y1,j.cx+j.x1),c),U>0&&t.arc(u+j.cx,h+j.cy,U,Su(j.y1,j.x1),Su(j.y0,j.x0),!c))}else t.lineTo(u+P,h+O),t.arc(u,h,r,l,s,c);else t.lineTo(u+P,h+O)}else t.moveTo(u,h);t.closePath()}}}var Lu=function(){this.cx=0,this.cy=0,this.r0=0,this.r=0,this.startAngle=0,this.endAngle=2*Math.PI,this.clockwise=!0,this.cornerRadius=0},Pu=function(t){function e(e){return t.call(this,e)||this}return n(e,t),e.prototype.getDefaultShape=function(){return new Lu},e.prototype.buildPath=function(t,e){ku(t,e)},e.prototype.isZeroArea=function(){return this.shape.startAngle===this.shape.endAngle||this.shape.r===this.shape.r0},e}(_s);Pu.prototype.type="sector";var Ou=function(){this.cx=0,this.cy=0,this.r=0,this.r0=0},Ru=function(t){function e(e){return t.call(this,e)||this}return n(e,t),e.prototype.getDefaultShape=function(){return new Ou},e.prototype.buildPath=function(t,e){var n=e.cx,i=e.cy,r=2*Math.PI;t.moveTo(n+e.r,i),t.arc(n,i,e.r,0,r,!1),t.moveTo(n+e.r0,i),t.arc(n,i,e.r0,0,r,!0)},e}(_s);function Nu(t,e,n){var i=e.smooth,r=e.points;if(r&&r.length>=2){if(i){var o=function(t,e,n,i){var r,o,a,s,l=[],u=[],h=[],c=[];if(i){a=[1/0,1/0],s=[-1/0,-1/0];for(var p=0,d=t.length;pth[1]){if(a=!1,r)return a;var u=Math.abs(th[0]-Qu[1]),h=Math.abs(Qu[0]-th[1]);Math.min(u,h)>i.len()&&(u0){var c={duration:h.duration,delay:h.delay||0,easing:h.easing,done:o,force:!!o||!!a,setToFinal:!u,scope:t,during:a};l?e.animateFrom(n,c):e.animateTo(n,c)}else e.stopAnimation(),!l&&e.attr(n),a&&a(1),o&&o()}function uh(t,e,n,i,r,o){lh("update",t,e,n,i,r,o)}function hh(t,e,n,i,r,o){lh("enter",t,e,n,i,r,o)}function ch(t){if(!t.__zr)return!0;for(var e=0;eMath.abs(o[1])?o[0]>0?"right":"left":o[1]>0?"bottom":"top"}function Rh(t){return!t.isGroup}function Nh(t,e,n){if(t&&e){var i,r=(i={},t.traverse((function(t){Rh(t)&&t.anid&&(i[t.anid]=t)})),i);e.traverse((function(t){if(Rh(t)&&t.anid){var e=r[t.anid];if(e){var i=o(t);t.attr(o(e)),uh(t,i,n,js(t).dataIndex)}}}))}function o(t){var e={x:t.x,y:t.y,rotation:t.rotation};return function(t){return null!=t.shape}(t)&&(e.shape=A({},t.shape)),e}}function Eh(t,e){return z(t,(function(t){var n=t[0];n=yh(n,e.x),n=vh(n,e.x+e.width);var i=t[1];return i=yh(i,e.y),[n,i=vh(i,e.y+e.height)]}))}function zh(t,e){var n=yh(t.x,e.x),i=vh(t.x+t.width,e.x+e.width),r=yh(t.y,e.y),o=vh(t.y+t.height,e.y+e.height);if(i>=n&&o>=r)return{x:n,y:r,width:i-n,height:o-r}}function Vh(t,e,n){var i=A({rectHover:!0},e),r=i.style={strokeNoScale:!0};if(n=n||{x:-1,y:-1,width:2,height:2},t)return 0===t.indexOf("image://")?(r.image=t.slice(8),k(r,n),new Is(i)):Mh(t.replace("path://",""),i,n,"center")}function Bh(t,e,n,i,r){for(var o=0,a=r[r.length-1];o=-1e-6)return!1;var f=t-r,g=e-o,y=Gh(f,g,u,h)/d;if(y<0||y>1)return!1;var v=Gh(f,g,c,p)/d;return!(v<0||v>1)}function Gh(t,e,n,i){return t*i-n*e}function Wh(t){var e=t.itemTooltipOption,n=t.componentModel,i=t.itemName,r=X(e)?{formatter:e}:e,o=n.mainType,a=n.componentIndex,s={componentType:o,name:i,$vars:["name"]};s[o+"Index"]=a;var l=t.formatterParamsExtra;l&&E(G(l),(function(t){mt(s,t)||(s[t]=l[t],s.$vars.push(t))}));var u=js(t.el);u.componentMainType=o,u.componentIndex=a,u.tooltipConfig={name:i,option:k({content:i,formatterParams:s},r)}}function Hh(t,e){var n;t.isGroup&&(n=e(t)),n||t.traverse(e)}function Yh(t,e){if(t)if(Y(t))for(var n=0;n-1?Sc:Ic;function Ac(t,e){t=t.toUpperCase(),Cc[t]=new xc(e),Tc[t]=e}function kc(t){return Cc[t]}Ac(Mc,{time:{month:["January","February","March","April","May","June","July","August","September","October","November","December"],monthAbbr:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayOfWeek:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayOfWeekAbbr:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]},legend:{selector:{all:"All",inverse:"Inv"}},toolbox:{brush:{title:{rect:"Box Select",polygon:"Lasso Select",lineX:"Horizontally Select",lineY:"Vertically Select",keep:"Keep Selections",clear:"Clear Selections"}},dataView:{title:"Data View",lang:["Data View","Close","Refresh"]},dataZoom:{title:{zoom:"Zoom",back:"Zoom Reset"}},magicType:{title:{line:"Switch to Line Chart",bar:"Switch to Bar Chart",stack:"Stack",tiled:"Tile"}},restore:{title:"Restore"},saveAsImage:{title:"Save as Image",lang:["Right Click to Save Image"]}},series:{typeNames:{pie:"Pie chart",bar:"Bar chart",line:"Line chart",scatter:"Scatter plot",effectScatter:"Ripple scatter plot",radar:"Radar chart",tree:"Tree",treemap:"Treemap",boxplot:"Boxplot",candlestick:"Candlestick",k:"K line chart",heatmap:"Heat map",map:"Map",parallel:"Parallel coordinate map",lines:"Line graph",graph:"Relationship graph",sankey:"Sankey diagram",funnel:"Funnel chart",gauge:"Gauge",pictorialBar:"Pictorial bar",themeRiver:"Theme River Map",sunburst:"Sunburst"}},aria:{general:{withTitle:'This is a chart about "{title}"',withoutTitle:"This is a chart"},series:{single:{prefix:"",withName:" with type {seriesType} named {seriesName}.",withoutName:" with type {seriesType}."},multiple:{prefix:". It consists of {seriesCount} series count.",withName:" The {seriesId} series is a {seriesType} representing {seriesName}.",withoutName:" The {seriesId} series is a {seriesType}.",separator:{middle:"",end:""}}},data:{allData:"The data is as follows: ",partialData:"The first {displayCnt} items are: ",withName:"the data for {name} is {value}",withoutName:"{value}",separator:{middle:", ",end:". "}}}}),Ac(Sc,{time:{month:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthAbbr:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],dayOfWeek:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],dayOfWeekAbbr:["日","一","二","三","四","五","六"]},legend:{selector:{all:"全选",inverse:"反选"}},toolbox:{brush:{title:{rect:"矩形选择",polygon:"圈选",lineX:"横向选择",lineY:"纵向选择",keep:"保持选择",clear:"清除选择"}},dataView:{title:"数据视图",lang:["数据视图","关闭","刷新"]},dataZoom:{title:{zoom:"区域缩放",back:"区域缩放还原"}},magicType:{title:{line:"切换为折线图",bar:"切换为柱状图",stack:"切换为堆叠",tiled:"切换为平铺"}},restore:{title:"还原"},saveAsImage:{title:"保存为图片",lang:["右键另存为图片"]}},series:{typeNames:{pie:"饼图",bar:"柱状图",line:"折线图",scatter:"散点图",effectScatter:"涟漪散点图",radar:"雷达图",tree:"树图",treemap:"矩形树图",boxplot:"箱型图",candlestick:"K线图",k:"K线图",heatmap:"热力图",map:"地图",parallel:"平行坐标图",lines:"线图",graph:"关系图",sankey:"桑基图",funnel:"漏斗图",gauge:"仪表盘图",pictorialBar:"象形柱图",themeRiver:"主题河流图",sunburst:"旭日图"}},aria:{general:{withTitle:"这是一个关于“{title}”的图表。",withoutTitle:"这是一个图表,"},series:{single:{prefix:"",withName:"图表类型是{seriesType},表示{seriesName}。",withoutName:"图表类型是{seriesType}。"},multiple:{prefix:"它由{seriesCount}个图表系列组成。",withName:"第{seriesId}个系列是一个表示{seriesName}的{seriesType},",withoutName:"第{seriesId}个系列是一个{seriesType},",separator:{middle:";",end:"。"}}},data:{allData:"其数据是——",partialData:"其中,前{displayCnt}项是——",withName:"{name}的数据是{value}",withoutName:"{value}",separator:{middle:",",end:""}}}});var Lc=1e3,Pc=6e4,Oc=36e5,Rc=864e5,Nc=31536e6,Ec={year:"{yyyy}",month:"{MMM}",day:"{d}",hour:"{HH}:{mm}",minute:"{HH}:{mm}",second:"{HH}:{mm}:{ss}",millisecond:"{HH}:{mm}:{ss} {SSS}",none:"{yyyy}-{MM}-{dd} {HH}:{mm}:{ss} {SSS}"},zc="{yyyy}-{MM}-{dd}",Vc={year:"{yyyy}",month:"{yyyy}-{MM}",day:zc,hour:"{yyyy}-{MM}-{dd} "+Ec.hour,minute:"{yyyy}-{MM}-{dd} "+Ec.minute,second:"{yyyy}-{MM}-{dd} "+Ec.second,millisecond:Ec.none},Bc=["year","month","day","hour","minute","second","millisecond"],Fc=["year","half-year","quarter","month","week","half-week","day","half-day","quarter-day","hour","minute","second","millisecond"];function Gc(t,e){return"0000".substr(0,e-(t+="").length)+t}function Wc(t){switch(t){case"half-year":case"quarter":return"month";case"week":case"half-week":return"day";case"half-day":case"quarter-day":return"hour";default:return t}}function Hc(t){return t===Wc(t)}function Yc(t,e,n,i){var r=Qr(t),o=r[Zc(n)](),a=r[jc(n)]()+1,s=Math.floor((a-1)/3)+1,l=r[qc(n)](),u=r["get"+(n?"UTC":"")+"Day"](),h=r[Kc(n)](),c=(h-1)%12+1,p=r[$c(n)](),d=r[Jc(n)](),f=r[Qc(n)](),g=(i instanceof xc?i:kc(i||Dc)||Cc.EN).getModel("time"),y=g.get("month"),v=g.get("monthAbbr"),m=g.get("dayOfWeek"),x=g.get("dayOfWeekAbbr");return(e||"").replace(/{yyyy}/g,o+"").replace(/{yy}/g,o%100+"").replace(/{Q}/g,s+"").replace(/{MMMM}/g,y[a-1]).replace(/{MMM}/g,v[a-1]).replace(/{MM}/g,Gc(a,2)).replace(/{M}/g,a+"").replace(/{dd}/g,Gc(l,2)).replace(/{d}/g,l+"").replace(/{eeee}/g,m[u]).replace(/{ee}/g,x[u]).replace(/{e}/g,u+"").replace(/{HH}/g,Gc(h,2)).replace(/{H}/g,h+"").replace(/{hh}/g,Gc(c+"",2)).replace(/{h}/g,c+"").replace(/{mm}/g,Gc(p,2)).replace(/{m}/g,p+"").replace(/{ss}/g,Gc(d,2)).replace(/{s}/g,d+"").replace(/{SSS}/g,Gc(f,3)).replace(/{S}/g,f+"")}function Uc(t,e){var n=Qr(t),i=n[jc(e)]()+1,r=n[qc(e)](),o=n[Kc(e)](),a=n[$c(e)](),s=n[Jc(e)](),l=0===n[Qc(e)](),u=l&&0===s,h=u&&0===a,c=h&&0===o,p=c&&1===r;return p&&1===i?"year":p?"month":c?"day":h?"hour":u?"minute":l?"second":"millisecond"}function Xc(t,e,n){var i=j(t)?Qr(t):t;switch(e=e||Uc(t,n)){case"year":return i[Zc(n)]();case"half-year":return i[jc(n)]()>=6?1:0;case"quarter":return Math.floor((i[jc(n)]()+1)/4);case"month":return i[jc(n)]();case"day":return i[qc(n)]();case"half-day":return i[Kc(n)]()/24;case"hour":return i[Kc(n)]();case"minute":return i[$c(n)]();case"second":return i[Jc(n)]();case"millisecond":return i[Qc(n)]()}}function Zc(t){return t?"getUTCFullYear":"getFullYear"}function jc(t){return t?"getUTCMonth":"getMonth"}function qc(t){return t?"getUTCDate":"getDate"}function Kc(t){return t?"getUTCHours":"getHours"}function $c(t){return t?"getUTCMinutes":"getMinutes"}function Jc(t){return t?"getUTCSeconds":"getSeconds"}function Qc(t){return t?"getUTCMilliseconds":"getMilliseconds"}function tp(t){return t?"setUTCFullYear":"setFullYear"}function ep(t){return t?"setUTCMonth":"setMonth"}function np(t){return t?"setUTCDate":"setDate"}function ip(t){return t?"setUTCHours":"setHours"}function rp(t){return t?"setUTCMinutes":"setMinutes"}function op(t){return t?"setUTCSeconds":"setSeconds"}function ap(t){return t?"setUTCMilliseconds":"setMilliseconds"}function sp(t){if(!ao(t))return X(t)?t:"-";var e=(t+"").split(".");return e[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g,"$1,")+(e.length>1?"."+e[1]:"")}function lp(t,e){return t=(t||"").toLowerCase().replace(/-(.)/g,(function(t,e){return e.toUpperCase()})),e&&t&&(t=t.charAt(0).toUpperCase()+t.slice(1)),t}var up=st;function hp(t,e,n){function i(t){return t&&ut(t)?t:"-"}function r(t){return!(null==t||isNaN(t)||!isFinite(t))}var o="time"===e,a=t instanceof Date;if(o||a){var s=o?Qr(t):t;if(!isNaN(+s))return Yc(s,"{yyyy}-{MM}-{dd} {HH}:{mm}:{ss}",n);if(a)return"-"}if("ordinal"===e)return Z(t)?i(t):j(t)&&r(t)?t+"":"-";var l=oo(t);return r(l)?sp(l):Z(t)?i(t):"boolean"==typeof t?t+"":"-"}var cp=["a","b","c","d","e","f","g"],pp=function(t,e){return"{"+t+(null==e?"":e)+"}"};function dp(t,e,n){Y(e)||(e=[e]);var i=e.length;if(!i)return"";for(var r=e[0].$vars||[],o=0;o':'':{renderMode:o,content:"{"+(n.markerId||"markerX")+"|} ",style:"subItem"===r?{width:4,height:4,borderRadius:2,backgroundColor:i}:{width:10,height:10,borderRadius:5,backgroundColor:i}}:""}function gp(t,e){return e=e||"transparent",X(t)?t:q(t)&&t.colorStops&&(t.colorStops[0]||{}).color||e}function yp(t,e){if("_blank"===e||"blank"===e){var n=window.open();n.opener=null,n.location.href=t}else window.open(t,e)}var vp=E,mp=["left","right","top","bottom","width","height"],xp=[["width","left","right"],["height","top","bottom"]];function _p(t,e,n,i,r){var o=0,a=0;null==i&&(i=1/0),null==r&&(r=1/0);var s=0;e.eachChild((function(l,u){var h,c,p=l.getBoundingRect(),d=e.childAt(u+1),f=d&&d.getBoundingRect();if("horizontal"===t){var g=p.width+(f?-f.x+p.x:0);(h=o+g)>i||l.newline?(o=0,h=g,a+=s+n,s=p.height):s=Math.max(s,p.height)}else{var y=p.height+(f?-f.y+p.y:0);(c=a+y)>r||l.newline?(o+=s+n,a=0,c=y,s=p.width):s=Math.max(s,p.width)}l.newline||(l.x=o,l.y=a,l.markRedraw(),"horizontal"===t?o=h+n:a=c+n)}))}var bp=_p;H(_p,"vertical"),H(_p,"horizontal");function wp(t,e,n){n=up(n||0);var i=e.width,r=e.height,o=Gr(t.left,i),a=Gr(t.top,r),s=Gr(t.right,i),l=Gr(t.bottom,r),u=Gr(t.width,i),h=Gr(t.height,r),c=n[2]+n[0],p=n[1]+n[3],d=t.aspect;switch(isNaN(u)&&(u=i-s-p-o),isNaN(h)&&(h=r-l-c-a),null!=d&&(isNaN(u)&&isNaN(h)&&(d>i/r?u=.8*i:h=.8*r),isNaN(u)&&(u=d*h),isNaN(h)&&(h=u/d)),isNaN(o)&&(o=i-s-u-p),isNaN(a)&&(a=r-l-h-c),t.left||t.right){case"center":o=i/2-u/2-n[3];break;case"right":o=i-u-p}switch(t.top||t.bottom){case"middle":case"center":a=r/2-h/2-n[0];break;case"bottom":a=r-h-c}o=o||0,a=a||0,isNaN(u)&&(u=i-p-o-(s||0)),isNaN(h)&&(h=r-c-a-(l||0));var f=new Re(o+n[3],a+n[0],u,h);return f.margin=n,f}function Sp(t,e,n,i,r,o){var a,s=!r||!r.hv||r.hv[0],l=!r||!r.hv||r.hv[1],u=r&&r.boundingMode||"all";if((o=o||t).x=t.x,o.y=t.y,!s&&!l)return!1;if("raw"===u)a="group"===t.type?new Re(0,0,+e.width||0,+e.height||0):t.getBoundingRect();else if(a=t.getBoundingRect(),t.needLocalTransform()){var h=t.getLocalTransform();(a=a.clone()).applyTransform(h)}var c=wp(k({width:a.width,height:a.height},e),n,i),p=s?c.x-a.x:0,d=l?c.y-a.y:0;return"raw"===u?(o.x=p,o.y=d):(o.x+=p,o.y+=d),o===t&&t.markRedraw(),!0}function Mp(t){var e=t.layoutMode||t.constructor.layoutMode;return q(e)?e:e?{type:e}:null}function Ip(t,e,n){var i=n&&n.ignoreSize;!Y(i)&&(i=[i,i]);var r=a(xp[0],0),o=a(xp[1],1);function a(n,r){var o={},a=0,u={},h=0;if(vp(n,(function(e){u[e]=t[e]})),vp(n,(function(t){s(e,t)&&(o[t]=u[t]=e[t]),l(o,t)&&a++,l(u,t)&&h++})),i[r])return l(e,n[1])?u[n[2]]=null:l(e,n[2])&&(u[n[1]]=null),u;if(2!==h&&a){if(a>=2)return o;for(var c=0;c=0;a--)o=C(o,n[a],!0);e.defaultOption=o}return e.defaultOption},e.prototype.getReferringComponents=function(t,e){var n=t+"Index",i=t+"Id";return Ro(this.ecModel,t,{index:this.get(n,!0),id:this.get(i,!0)},e)},e.prototype.getBoxLayoutParams=function(){var t=this;return{left:t.get("left"),top:t.get("top"),right:t.get("right"),bottom:t.get("bottom"),width:t.get("width"),height:t.get("height")}},e.prototype.getZLevelKey=function(){return""},e.prototype.setZLevel=function(t){this.option.zlevel=t},e.protoInitialize=function(){var t=e.prototype;t.type="component",t.id="",t.name="",t.mainType="",t.subType="",t.componentIndex=0}(),e}(xc);Wo(Ap,xc),Xo(Ap),function(t){var e={};t.registerSubTypeDefaulter=function(t,n){var i=Fo(t);e[i.main]=n},t.determineSubType=function(n,i){var r=i.type;if(!r){var o=Fo(n).main;t.hasSubTypes(n)&&e[o]&&(r=e[o](i))}return r}}(Ap),function(t,e){function n(t,e){return t[e]||(t[e]={predecessor:[],successor:[]}),t[e]}t.topologicalTravel=function(t,i,r,o){if(t.length){var a=function(t){var i={},r=[];return E(t,(function(o){var a=n(i,o),s=function(t,e){var n=[];return E(t,(function(t){P(e,t)>=0&&n.push(t)})),n}(a.originalDeps=e(o),t);a.entryCount=s.length,0===a.entryCount&&r.push(o),E(s,(function(t){P(a.predecessor,t)<0&&a.predecessor.push(t);var e=n(i,t);P(e.successor,t)<0&&e.successor.push(o)}))})),{graph:i,noEntryList:r}}(i),s=a.graph,l=a.noEntryList,u={};for(E(t,(function(t){u[t]=!0}));l.length;){var h=l.pop(),c=s[h],p=!!u[h];p&&(r.call(o,h,c.originalDeps.slice()),delete u[h]),E(c.successor,p?f:d)}E(u,(function(){var t="";throw new Error(t)}))}function d(t){s[t].entryCount--,0===s[t].entryCount&&l.push(t)}function f(t){u[t]=!0,d(t)}}}(Ap,(function(t){var e=[];E(Ap.getClassesByMainType(t),(function(t){e=e.concat(t.dependencies||t.prototype.dependencies||[])})),e=z(e,(function(t){return Fo(t).main})),"dataset"!==t&&P(e,"dataset")<=0&&e.unshift("dataset");return e}));var kp="";"undefined"!=typeof navigator&&(kp=navigator.platform||"");var Lp="rgba(0, 0, 0, 0.2)",Pp={darkMode:"auto",colorBy:"series",color:["#5470c6","#91cc75","#fac858","#ee6666","#73c0de","#3ba272","#fc8452","#9a60b4","#ea7ccc"],gradientColor:["#f6efa6","#d88273","#bf444c"],aria:{decal:{decals:[{color:Lp,dashArrayX:[1,0],dashArrayY:[2,5],symbolSize:1,rotation:Math.PI/6},{color:Lp,symbol:"circle",dashArrayX:[[8,8],[0,8,8,0]],dashArrayY:[6,0],symbolSize:.8},{color:Lp,dashArrayX:[1,0],dashArrayY:[4,3],rotation:-Math.PI/4},{color:Lp,dashArrayX:[[6,6],[0,6,6,0]],dashArrayY:[6,0]},{color:Lp,dashArrayX:[[1,0],[1,6]],dashArrayY:[1,0,6,0],rotation:Math.PI/4},{color:Lp,symbol:"triangle",dashArrayX:[[9,9],[0,9,9,0]],dashArrayY:[7,2],symbolSize:.75}]}},textStyle:{fontFamily:kp.match(/^Win/)?"Microsoft YaHei":"sans-serif",fontSize:12,fontStyle:"normal",fontWeight:"normal"},blendMode:null,stateAnimation:{duration:300,easing:"cubicOut"},animation:"auto",animationDuration:1e3,animationDurationUpdate:500,animationEasing:"cubicInOut",animationEasingUpdate:"cubicInOut",animationThreshold:2e3,progressiveThreshold:3e3,progressive:400,hoverLayerThreshold:3e3,useUTC:!1},Op=ft(["tooltip","label","itemName","itemId","itemGroupId","seriesName"]),Rp="original",Np="arrayRows",Ep="objectRows",zp="keyedColumns",Vp="typedArray",Bp="unknown",Fp="column",Gp="row",Wp=1,Hp=2,Yp=3,Up=Do();function Xp(t,e,n){var i={},r=jp(e);if(!r||!t)return i;var o,a,s=[],l=[],u=e.ecModel,h=Up(u).datasetMap,c=r.uid+"_"+n.seriesLayoutBy;E(t=t.slice(),(function(e,n){var r=q(e)?e:t[n]={name:e};"ordinal"===r.type&&null==o&&(o=n,a=f(r)),i[r.name]=[]}));var p=h.get(c)||h.set(c,{categoryWayDim:a,valueWayDim:0});function d(t,e,n){for(var i=0;ie)return t[i];return t[n-1]}(i,a):n;if((h=h||n)&&h.length){var c=h[l];return r&&(u[r]=c),s.paletteIdx=(l+1)%h.length,c}}var ad=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.init=function(t,e,n,i,r,o){i=i||{},this.option=null,this._theme=new xc(i),this._locale=new xc(r),this._optionManager=o},e.prototype.setOption=function(t,e,n){var i=ud(e);this._optionManager.setOption(t,n,i),this._resetOption(null,i)},e.prototype.resetOption=function(t,e){return this._resetOption(t,ud(e))},e.prototype._resetOption=function(t,e){var n=!1,i=this._optionManager;if(!t||"recreate"===t){var r=i.mountOption("recreate"===t);0,this.option&&"recreate"!==t?(this.restoreData(),this._mergeOption(r,e)):td(this,r),n=!0}if("timeline"!==t&&"media"!==t||this.restoreData(),!t||"recreate"===t||"timeline"===t){var o=i.getTimelineOption(this);o&&(n=!0,this._mergeOption(o,e))}if(!t||"recreate"===t||"media"===t){var a=i.getMediaOption(this);a.length&&E(a,(function(t){n=!0,this._mergeOption(t,e)}),this)}return n},e.prototype.mergeOption=function(t){this._mergeOption(t,null)},e.prototype._mergeOption=function(t,e){var n=this.option,i=this._componentsMap,r=this._componentsCount,o=[],a=ft(),s=e&&e.replaceMergeMainTypeMap;Up(this).datasetMap=ft(),E(t,(function(t,e){null!=t&&(Ap.hasClass(e)?e&&(o.push(e),a.set(e,!0)):n[e]=null==n[e]?T(t):C(n[e],t,!0))})),s&&s.each((function(t,e){Ap.hasClass(e)&&!a.get(e)&&(o.push(e),a.set(e,!0))})),Ap.topologicalTravel(o,Ap.getAllClassMainTypes(),(function(e){var o=function(t,e,n){var i=$p.get(e);if(!i)return n;var r=i(t);return r?n.concat(r):n}(this,e,yo(t[e])),a=i.get(e),l=a?s&&s.get(e)?"replaceMerge":"normalMerge":"replaceAll",u=bo(a,o,l);(function(t,e,n){E(t,(function(t){var i=t.newOption;q(i)&&(t.keyInfo.mainType=e,t.keyInfo.subType=function(t,e,n,i){return e.type?e.type:n?n.subType:i.determineSubType(t,e)}(e,i,t.existing,n))}))})(u,e,Ap),n[e]=null,i.set(e,null),r.set(e,0);var h,c=[],p=[],d=0;E(u,(function(t,n){var i=t.existing,r=t.newOption;if(r){var o="series"===e,a=Ap.getClass(e,t.keyInfo.subType,!o);if(!a)return;if("tooltip"===e){if(h)return void 0;h=!0}if(i&&i.constructor===a)i.name=t.keyInfo.name,i.mergeOption(r,this),i.optionUpdated(r,!1);else{var s=A({componentIndex:n},t.keyInfo);A(i=new a(r,this,this,s),s),t.brandNew&&(i.__requireNewView=!0),i.init(r,this,this),i.optionUpdated(null,!0)}}else i&&(i.mergeOption({},this),i.optionUpdated({},!1));i?(c.push(i.option),p.push(i),d++):(c.push(void 0),p.push(void 0))}),this),n[e]=c,i.set(e,p),r.set(e,d),"series"===e&&Jp(this)}),this),this._seriesIndices||Jp(this)},e.prototype.getOption=function(){var t=T(this.option);return E(t,(function(e,n){if(Ap.hasClass(n)){for(var i=yo(e),r=i.length,o=!1,a=r-1;a>=0;a--)i[a]&&!To(i[a])?o=!0:(i[a]=null,!o&&r--);i.length=r,t[n]=i}})),delete t["\0_ec_inner"],t},e.prototype.getTheme=function(){return this._theme},e.prototype.getLocaleModel=function(){return this._locale},e.prototype.setUpdatePayload=function(t){this._payload=t},e.prototype.getUpdatePayload=function(){return this._payload},e.prototype.getComponent=function(t,e){var n=this._componentsMap.get(t);if(n){var i=n[e||0];if(i)return i;if(null==e)for(var r=0;r=e:"max"===n?t<=e:t===e})(i[a],t,o)||(r=!1)}})),r}var vd=E,md=q,xd=["areaStyle","lineStyle","nodeStyle","linkStyle","chordStyle","label","labelLine"];function _d(t){var e=t&&t.itemStyle;if(e)for(var n=0,i=xd.length;n=0;g--){var y=t[g];if(s||(p=y.data.rawIndexOf(y.stackedByDimension,c)),p>=0){var v=y.data.getByRawIndex(y.stackResultDimension,p);if("all"===l||"positive"===l&&v>0||"negative"===l&&v<0||"samesign"===l&&d>=0&&v>0||"samesign"===l&&d<=0&&v<0){d=jr(d,v),f=v;break}}}return i[0]=d,i[1]=f,i}))}))}var Vd,Bd,Fd,Gd,Wd,Hd=function(t){this.data=t.data||(t.sourceFormat===zp?{}:[]),this.sourceFormat=t.sourceFormat||Bp,this.seriesLayoutBy=t.seriesLayoutBy||Fp,this.startIndex=t.startIndex||0,this.dimensionsDetectedCount=t.dimensionsDetectedCount,this.metaRawOption=t.metaRawOption;var e=this.dimensionsDefine=t.dimensionsDefine;if(e)for(var n=0;nu&&(u=d)}s[0]=l,s[1]=u}},i=function(){return this._data?this._data.length/this._dimSize:0};function r(t){for(var e=0;e=0&&(s=o.interpolatedValue[l])}return null!=s?s+"":""})):void 0},t.prototype.getRawValue=function(t,e){return uf(this.getData(e),t)},t.prototype.formatTooltip=function(t,e,n){},t}();function pf(t){var e,n;return q(t)?t.type&&(n=t):e=t,{text:e,frag:n}}function df(t){return new ff(t)}var ff=function(){function t(t){t=t||{},this._reset=t.reset,this._plan=t.plan,this._count=t.count,this._onDirty=t.onDirty,this._dirty=!0}return t.prototype.perform=function(t){var e,n=this._upstream,i=t&&t.skip;if(this._dirty&&n){var r=this.context;r.data=r.outputData=n.context.outputData}this.__pipeline&&(this.__pipeline.currentTask=this),this._plan&&!i&&(e=this._plan(this.context));var o,a=h(this._modBy),s=this._modDataCount||0,l=h(t&&t.modBy),u=t&&t.modDataCount||0;function h(t){return!(t>=1)&&(t=1),t}a===l&&s===u||(e="reset"),(this._dirty||"reset"===e)&&(this._dirty=!1,o=this._doReset(i)),this._modBy=l,this._modDataCount=u;var c=t&&t.step;if(this._dueEnd=n?n._outputDueEnd:this._count?this._count(this.context):1/0,this._progress){var p=this._dueIndex,d=Math.min(null!=c?this._dueIndex+c:1/0,this._dueEnd);if(!i&&(o||p1&&i>0?s:a}};return o;function a(){return e=t?null:oe},gte:function(t,e){return t>=e}},_f=function(){function t(t,e){if(!j(e)){var n="";0,co(n)}this._opFn=xf[t],this._rvalFloat=oo(e)}return t.prototype.evaluate=function(t){return j(t)?this._opFn(t,this._rvalFloat):this._opFn(oo(t),this._rvalFloat)},t}(),bf=function(){function t(t,e){var n="desc"===t;this._resultLT=n?1:-1,null==e&&(e=n?"min":"max"),this._incomparable="min"===e?-1/0:1/0}return t.prototype.evaluate=function(t,e){var n=j(t)?t:oo(t),i=j(e)?e:oo(e),r=isNaN(n),o=isNaN(i);if(r&&(n=this._incomparable),o&&(i=this._incomparable),r&&o){var a=X(t),s=X(e);a&&(n=s?t:0),s&&(i=a?e:0)}return ni?-this._resultLT:0},t}(),wf=function(){function t(t,e){this._rval=e,this._isEQ=t,this._rvalTypeof=typeof e,this._rvalFloat=oo(e)}return t.prototype.evaluate=function(t){var e=t===this._rval;if(!e){var n=typeof t;n===this._rvalTypeof||"number"!==n&&"number"!==this._rvalTypeof||(e=oo(t)===this._rvalFloat)}return this._isEQ?e:!e},t}();function Sf(t,e){return"eq"===t||"ne"===t?new wf("eq"===t,e):mt(xf,t)?new _f(t,e):null}var Mf=function(){function t(){}return t.prototype.getRawData=function(){throw new Error("not supported")},t.prototype.getRawDataItem=function(t){throw new Error("not supported")},t.prototype.cloneRawData=function(){},t.prototype.getDimensionInfo=function(t){},t.prototype.cloneAllDimensionInfo=function(){},t.prototype.count=function(){},t.prototype.retrieveValue=function(t,e){},t.prototype.retrieveValueFromItem=function(t,e){},t.prototype.convertValue=function(t,e){return yf(t,e)},t}();function If(t){var e=t.sourceFormat;if(!Lf(e)){var n="";0,co(n)}return t.data}function Tf(t){var e=t.sourceFormat,n=t.data;if(!Lf(e)){var i="";0,co(i)}if(e===Np){for(var r=[],o=0,a=n.length;o65535?Rf:Nf}function Ff(t,e,n,i,r){var o=Vf[n||"float"];if(r){var a=t[e],s=a&&a.length;if(s!==i){for(var l=new o(i),u=0;ug[1]&&(g[1]=f)}return this._rawCount=this._count=s,{start:a,end:s}},t.prototype._initDataFromProvider=function(t,e,n){for(var i=this._provider,r=this._chunks,o=this._dimensions,a=o.length,s=this._rawExtent,l=z(o,(function(t){return t.property})),u=0;uy[1]&&(y[1]=g)}}!i.persistent&&i.clean&&i.clean(),this._rawCount=this._count=e,this._extent=[]},t.prototype.count=function(){return this._count},t.prototype.get=function(t,e){if(!(e>=0&&e=0&&e=this._rawCount||t<0)return-1;if(!this._indices)return t;var e=this._indices,n=e[t];if(null!=n&&nt))return o;r=o-1}}return-1},t.prototype.indicesOfNearest=function(t,e,n){var i=this._chunks[t],r=[];if(!i)return r;null==n&&(n=1/0);for(var o=1/0,a=-1,s=0,l=0,u=this.count();l=0&&a<0)&&(o=c,a=h,s=0),h===a&&(r[s++]=l))}return r.length=s,r},t.prototype.getIndices=function(){var t,e=this._indices;if(e){var n=e.constructor,i=this._count;if(n===Array){t=new n(i);for(var r=0;r=u&&x<=h||isNaN(x))&&(a[s++]=d),d++}p=!0}else if(2===r){f=c[i[0]];var y=c[i[1]],v=t[i[1]][0],m=t[i[1]][1];for(g=0;g=u&&x<=h||isNaN(x))&&(_>=v&&_<=m||isNaN(_))&&(a[s++]=d),d++}p=!0}}if(!p)if(1===r)for(g=0;g=u&&x<=h||isNaN(x))&&(a[s++]=b)}else for(g=0;gt[M][1])&&(w=!1)}w&&(a[s++]=e.getRawIndex(g))}return sy[1]&&(y[1]=g)}}}},t.prototype.lttbDownSample=function(t,e){var n,i,r,o=this.clone([t],!0),a=o._chunks[t],s=this.count(),l=0,u=Math.floor(1/e),h=this.getRawIndex(0),c=new(Bf(this._rawCount))(Math.min(2*(Math.ceil(s/u)+2),s));c[l++]=h;for(var p=1;pn&&(n=i,r=I)}M>0&&M<_-x&&(c[l++]=Math.min(S,r),r=Math.max(S,r)),c[l++]=r,h=r}return c[l++]=this.getRawIndex(s-1),o._count=l,o._indices=c,o.getRawIndex=this._getRawIdx,o},t.prototype.downSample=function(t,e,n,i){for(var r=this.clone([t],!0),o=r._chunks,a=[],s=Math.floor(1/e),l=o[t],u=this.count(),h=r._rawExtent[t]=[1/0,-1/0],c=new(Bf(this._rawCount))(Math.ceil(u/s)),p=0,d=0;du-d&&(s=u-d,a.length=s);for(var f=0;fh[1]&&(h[1]=y),c[p++]=v}return r._count=p,r._indices=c,r._updateGetRawIdx(),r},t.prototype.each=function(t,e){if(this._count)for(var n=t.length,i=this._chunks,r=0,o=this.count();ra&&(a=l)}return i=[o,a],this._extent[t]=i,i},t.prototype.getRawDataItem=function(t){var e=this.getRawIndex(t);if(this._provider.persistent)return this._provider.getItem(e);for(var n=[],i=this._chunks,r=0;r=0?this._indices[t]:-1},t.prototype._updateGetRawIdx=function(){this.getRawIndex=this._indices?this._getRawIdx:this._getRawIdxIdentity},t.internalField=function(){function t(t,e,n,i){return yf(t[i],this._dimensions[i])}Pf={arrayRows:t,objectRows:function(t,e,n,i){return yf(t[e],this._dimensions[i])},keyedColumns:t,original:function(t,e,n,i){var r=t&&(null==t.value?t:t.value);return yf(r instanceof Array?r[i]:r,this._dimensions[i])},typedArray:function(t,e,n,i){return t[i]}}}(),t}(),Wf=function(){function t(t){this._sourceList=[],this._storeList=[],this._upstreamSignList=[],this._versionSignBase=0,this._dirty=!0,this._sourceHost=t}return t.prototype.dirty=function(){this._setLocalSource([],[]),this._storeList=[],this._dirty=!0},t.prototype._setLocalSource=function(t,e){this._sourceList=t,this._upstreamSignList=e,this._versionSignBase++,this._versionSignBase>9e10&&(this._versionSignBase=0)},t.prototype._getVersionSign=function(){return this._sourceHost.uid+"_"+this._versionSignBase},t.prototype.prepareSource=function(){this._isDirty()&&(this._createSource(),this._dirty=!1)},t.prototype._createSource=function(){this._setLocalSource([],[]);var t,e,n=this._sourceHost,i=this._getUpstreamSourceManagers(),r=!!i.length;if(Yf(n)){var o=n,a=void 0,s=void 0,l=void 0;if(r){var u=i[0];u.prepareSource(),a=(l=u.getSource()).data,s=l.sourceFormat,e=[u._getVersionSign()]}else s=$(a=o.get("data",!0))?Vp:Rp,e=[];var h=this._getSourceMetaRawOption()||{},c=l&&l.metaRawOption||{},p=rt(h.seriesLayoutBy,c.seriesLayoutBy)||null,d=rt(h.sourceHeader,c.sourceHeader),f=rt(h.dimensions,c.dimensions);t=p!==c.seriesLayoutBy||!!d!=!!c.sourceHeader||f?[Ud(a,{seriesLayoutBy:p,sourceHeader:d,dimensions:f},s)]:[]}else{var g=n;if(r){var y=this._applyTransform(i);t=y.sourceList,e=y.upstreamSignList}else{t=[Ud(g.get("source",!0),this._getSourceMetaRawOption(),null)],e=[]}}this._setLocalSource(t,e)},t.prototype._applyTransform=function(t){var e,n=this._sourceHost,i=n.get("transform",!0),r=n.get("fromTransformResult",!0);if(null!=r){var o="";1!==t.length&&Uf(o)}var a,s=[],l=[];return E(t,(function(t){t.prepareSource();var e=t.getSource(r||0),n="";null==r||e||Uf(n),s.push(e),l.push(t._getVersionSign())})),i?e=function(t,e,n){var i=yo(t),r=i.length,o="";r||co(o);for(var a=0,s=r;a1||n>0&&!t.noHeader;return E(t.blocks,(function(t){var n=Jf(t);n>=e&&(e=n+ +(i&&(!n||Kf(t)&&!t.noHeader)))})),e}return 0}function Qf(t,e,n,i){var r,o=e.noHeader,a=(r=Jf(e),{html:Zf[r],richText:jf[r]}),s=[],l=e.blocks||[];lt(!l||Y(l)),l=l||[];var u=t.orderMode;if(e.sortBlocks&&u){l=l.slice();var h={valueAsc:"asc",valueDesc:"desc"};if(mt(h,u)){var c=new bf(h[u],null);l.sort((function(t,e){return c.evaluate(t.sortParam,e.sortParam)}))}else"seriesDesc"===u&&l.reverse()}E(l,(function(n,r){var o=e.valueFormatter,l=$f(n)(o?A(A({},t),{valueFormatter:o}):t,n,r>0?a.html:0,i);null!=l&&s.push(l)}));var p="richText"===t.renderMode?s.join(a.richText):ng(s.join(""),o?n:a.html);if(o)return p;var d=hp(e.header,"ordinal",t.useUTC),f=Xf(i,t.renderMode).nameStyle;return"richText"===t.renderMode?ig(t,d,f)+a.richText+p:ng('
'+ee(d)+"
"+p,n)}function tg(t,e,n,i){var r=t.renderMode,o=e.noName,a=e.noValue,s=!e.markerType,l=e.name,u=t.useUTC,h=e.valueFormatter||t.valueFormatter||function(t){return z(t=Y(t)?t:[t],(function(t,e){return hp(t,Y(d)?d[e]:d,u)}))};if(!o||!a){var c=s?"":t.markupStyleCreator.makeTooltipMarker(e.markerType,e.markerColor||"#333",r),p=o?"":hp(l,"ordinal",u),d=e.valueType,f=a?[]:h(e.value),g=!s||!o,y=!s&&o,v=Xf(i,r),m=v.nameStyle,x=v.valueStyle;return"richText"===r?(s?"":c)+(o?"":ig(t,p,m))+(a?"":function(t,e,n,i,r){var o=[r],a=i?10:20;return n&&o.push({padding:[0,0,0,a],align:"right"}),t.markupStyleCreator.wrapRichTextStyle(Y(e)?e.join(" "):e,o)}(t,f,g,y,x)):ng((s?"":c)+(o?"":function(t,e,n){return''+ee(t)+""}(p,!s,m))+(a?"":function(t,e,n,i){var r=n?"10px":"20px",o=e?"float:right;margin-left:"+r:"";return t=Y(t)?t:[t],''+z(t,(function(t){return ee(t)})).join("  ")+""}(f,g,y,x)),n)}}function eg(t,e,n,i,r,o){if(t)return $f(t)({useUTC:r,renderMode:n,orderMode:i,markupStyleCreator:e,valueFormatter:t.valueFormatter},t,0,o)}function ng(t,e){return'
'+t+'
'}function ig(t,e,n){return t.markupStyleCreator.wrapRichTextStyle(e,n)}function rg(t,e){return gp(t.getData().getItemVisual(e,"style")[t.visualDrawType])}function og(t,e){var n=t.get("padding");return null!=n?n:"richText"===e?[8,10]:10}var ag=function(){function t(){this.richTextStyles={},this._nextStyleNameId=so()}return t.prototype._generateStyleName=function(){return"__EC_aUTo_"+this._nextStyleNameId++},t.prototype.makeTooltipMarker=function(t,e,n){var i="richText"===n?this._generateStyleName():null,r=fp({color:e,type:t,renderMode:n,markerId:i});return X(r)?r:(this.richTextStyles[i]=r.style,r.content)},t.prototype.wrapRichTextStyle=function(t,e){var n={};Y(e)?E(e,(function(t){return A(n,t)})):A(n,e);var i=this._generateStyleName();return this.richTextStyles[i]=n,"{"+i+"|"+t+"}"},t}();function sg(t){var e,n,i,r,o=t.series,a=t.dataIndex,s=t.multipleSeries,l=o.getData(),u=l.mapDimensionsAll("defaultedTooltip"),h=u.length,c=o.getRawValue(a),p=Y(c),d=rg(o,a);if(h>1||p&&!h){var f=function(t,e,n,i,r){var o=e.getData(),a=V(t,(function(t,e,n){var i=o.getDimensionInfo(n);return t||i&&!1!==i.tooltip&&null!=i.displayName}),!1),s=[],l=[],u=[];function h(t,e){var n=o.getDimensionInfo(e);n&&!1!==n.otherDims.tooltip&&(a?u.push(qf("nameValue",{markerType:"subItem",markerColor:r,name:n.displayName,value:t,valueType:n.type})):(s.push(t),l.push(n.type)))}return i.length?E(i,(function(t){h(uf(o,n,t),t)})):E(t,h),{inlineValues:s,inlineValueTypes:l,blocks:u}}(c,o,a,u,d);e=f.inlineValues,n=f.inlineValueTypes,i=f.blocks,r=f.inlineValues[0]}else if(h){var g=l.getDimensionInfo(u[0]);r=e=uf(l,a,u[0]),n=g.type}else r=e=p?c[0]:c;var y=Io(o),v=y&&o.name||"",m=l.getName(a),x=s?v:m;return qf("section",{header:v,noHeader:s||!y,sortParam:r,blocks:[qf("nameValue",{markerType:"item",markerColor:d,name:x,noName:!ut(x),value:e,valueType:n})].concat(i||[])})}var lg=Do();function ug(t,e){return t.getName(e)||t.getId(e)}var hg=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e._selectedDataIndicesMap={},e}return n(e,t),e.prototype.init=function(t,e,n){this.seriesIndex=this.componentIndex,this.dataTask=df({count:pg,reset:dg}),this.dataTask.context={model:this},this.mergeDefaultAndTheme(t,n),(lg(this).sourceManager=new Wf(this)).prepareSource();var i=this.getInitialData(t,n);gg(i,this),this.dataTask.context.data=i,lg(this).dataBeforeProcessed=i,cg(this),this._initSelectedMapFromData(i)},e.prototype.mergeDefaultAndTheme=function(t,e){var n=Mp(this),i=n?Tp(t):{},r=this.subType;Ap.hasClass(r)&&(r+="Series"),C(t,e.getTheme().get(this.subType)),C(t,this.getDefaultOption()),vo(t,"label",["show"]),this.fillDataTextStyle(t.data),n&&Ip(t,i,n)},e.prototype.mergeOption=function(t,e){t=C(this.option,t,!0),this.fillDataTextStyle(t.data);var n=Mp(this);n&&Ip(this.option,t,n);var i=lg(this).sourceManager;i.dirty(),i.prepareSource();var r=this.getInitialData(t,e);gg(r,this),this.dataTask.dirty(),this.dataTask.context.data=r,lg(this).dataBeforeProcessed=r,cg(this),this._initSelectedMapFromData(r)},e.prototype.fillDataTextStyle=function(t){if(t&&!$(t))for(var e=["show"],n=0;nthis.getShallow("animationThreshold")&&(e=!1),!!e},e.prototype.restoreData=function(){this.dataTask.dirty()},e.prototype.getColorFromPalette=function(t,e,n){var i=this.ecModel,r=id.prototype.getColorFromPalette.call(this,t,e,n);return r||(r=i.getColorFromPalette(t,e,n)),r},e.prototype.coordDimToDataDim=function(t){return this.getRawData().mapDimensionsAll(t)},e.prototype.getProgressive=function(){return this.get("progressive")},e.prototype.getProgressiveThreshold=function(){return this.get("progressiveThreshold")},e.prototype.select=function(t,e){this._innerSelect(this.getData(e),t)},e.prototype.unselect=function(t,e){var n=this.option.selectedMap;if(n){var i=this.option.selectedMode,r=this.getData(e);if("series"===i||"all"===n)return this.option.selectedMap={},void(this._selectedDataIndicesMap={});for(var o=0;o=0&&n.push(r)}return n},e.prototype.isSelected=function(t,e){var n=this.option.selectedMap;if(!n)return!1;var i=this.getData(e);return("all"===n||n[ug(i,t)])&&!i.getItemModel(t).get(["select","disabled"])},e.prototype.isUniversalTransitionEnabled=function(){if(this.__universalTransitionEnabled)return!0;var t=this.option.universalTransition;return!!t&&(!0===t||t&&t.enabled)},e.prototype._innerSelect=function(t,e){var n,i,r=this.option,o=r.selectedMode,a=e.length;if(o&&a)if("series"===o)r.selectedMap="all";else if("multiple"===o){q(r.selectedMap)||(r.selectedMap={});for(var s=r.selectedMap,l=0;l0&&this._innerSelect(t,e)}},e.registerClass=function(t){return Ap.registerClass(t)},e.protoInitialize=function(){var t=e.prototype;t.type="series.__base__",t.seriesIndex=0,t.ignoreStyleOnData=!1,t.hasSymbolVisual=!1,t.defaultSymbol="circle",t.visualStyleAccessPath="itemStyle",t.visualDrawType="fill"}(),e}(Ap);function cg(t){var e=t.name;Io(t)||(t.name=function(t){var e=t.getRawData(),n=e.mapDimensionsAll("seriesName"),i=[];return E(n,(function(t){var n=e.getDimensionInfo(t);n.displayName&&i.push(n.displayName)})),i.join(" ")}(t)||e)}function pg(t){return t.model.getRawData().count()}function dg(t){var e=t.model;return e.setData(e.getRawData().cloneShallow()),fg}function fg(t,e){e.outputData&&t.end>e.outputData.count()&&e.model.getRawData().cloneShallow(e.outputData)}function gg(t,e){E(gt(t.CHANGABLE_METHODS,t.DOWNSAMPLE_METHODS),(function(n){t.wrapMethod(n,H(yg,e))}))}function yg(t,e){var n=vg(t);return n&&n.setOutputEnd((e||this).count()),e}function vg(t){var e=(t.ecModel||{}).scheduler,n=e&&e.getPipeline(t.uid);if(n){var i=n.currentTask;if(i){var r=i.agentStubMap;r&&(i=r.get(t.uid))}return i}}R(hg,cf),R(hg,id),Wo(hg,Ap);var mg=function(){function t(){this.group=new Pr,this.uid=bc("viewComponent")}return t.prototype.init=function(t,e){},t.prototype.render=function(t,e,n,i){},t.prototype.dispose=function(t,e){},t.prototype.updateView=function(t,e,n,i){},t.prototype.updateLayout=function(t,e,n,i){},t.prototype.updateVisual=function(t,e,n,i){},t.prototype.toggleBlurSeries=function(t,e,n){},t.prototype.eachRendered=function(t){var e=this.group;e&&e.traverse(t)},t}();function xg(){var t=Do();return function(e){var n=t(e),i=e.pipelineContext,r=!!n.large,o=!!n.progressiveRender,a=n.large=!(!i||!i.large),s=n.progressiveRender=!(!i||!i.progressiveRender);return!(r===a&&o===s)&&"reset"}}Go(mg),Xo(mg);var _g=Do(),bg=xg(),wg=function(){function t(){this.group=new Pr,this.uid=bc("viewChart"),this.renderTask=df({plan:Ig,reset:Tg}),this.renderTask.context={view:this}}return t.prototype.init=function(t,e){},t.prototype.render=function(t,e,n,i){0},t.prototype.highlight=function(t,e,n,i){var r=t.getData(i&&i.dataType);r&&Mg(r,i,"emphasis")},t.prototype.downplay=function(t,e,n,i){var r=t.getData(i&&i.dataType);r&&Mg(r,i,"normal")},t.prototype.remove=function(t,e){this.group.removeAll()},t.prototype.dispose=function(t,e){},t.prototype.updateView=function(t,e,n,i){this.render(t,e,n,i)},t.prototype.updateLayout=function(t,e,n,i){this.render(t,e,n,i)},t.prototype.updateVisual=function(t,e,n,i){this.render(t,e,n,i)},t.prototype.eachRendered=function(t){Yh(this.group,t)},t.markUpdateMethod=function(t,e){_g(t).updateMethod=e},t.protoInitialize=void(t.prototype.type="chart"),t}();function Sg(t,e,n){t&&Ul(t)&&("emphasis"===e?Il:Tl)(t,n)}function Mg(t,e,n){var i=Co(t,e),r=e&&null!=e.highlightKey?function(t){var e=$s[t];return null==e&&Ks<=32&&(e=$s[t]=Ks++),e}(e.highlightKey):null;null!=i?E(yo(i),(function(e){Sg(t.getItemGraphicEl(e),n,r)})):t.eachItemGraphicEl((function(t){Sg(t,n,r)}))}function Ig(t){return bg(t.model)}function Tg(t){var e=t.model,n=t.ecModel,i=t.api,r=t.payload,o=e.pipelineContext.progressiveRender,a=t.view,s=r&&_g(r).updateMethod,l=o?"incrementalPrepareRender":s&&a[s]?s:"render";return"render"!==l&&a[l](e,n,i,r),Cg[l]}Go(wg),Xo(wg);var Cg={incrementalPrepareRender:{progress:function(t,e){e.view.incrementalRender(t,e.model,e.ecModel,e.api,e.payload)}},render:{forceFirstProgress:!0,progress:function(t,e){e.view.render(e.model,e.ecModel,e.api,e.payload)}}},Dg="\0__throttleOriginMethod",Ag="\0__throttleRate",kg="\0__throttleType";function Lg(t,e,n){var i,r,o,a,s,l=0,u=0,h=null;function c(){u=(new Date).getTime(),h=null,t.apply(o,a||[])}e=e||0;var p=function(){for(var t=[],p=0;p=0?c():h=setTimeout(c,-r),l=i};return p.clear=function(){h&&(clearTimeout(h),h=null)},p.debounceNextCall=function(t){s=t},p}function Pg(t,e,n,i){var r=t[e];if(r){var o=r[Dg]||r,a=r[kg];if(r[Ag]!==n||a!==i){if(null==n||!i)return t[e]=o;(r=t[e]=Lg(o,n,"debounce"===i))[Dg]=o,r[kg]=i,r[Ag]=n}return r}}function Og(t,e){var n=t[e];n&&n[Dg]&&(n.clear&&n.clear(),t[e]=n[Dg])}var Rg=Do(),Ng={itemStyle:Zo(yc,!0),lineStyle:Zo(dc,!0)},Eg={lineStyle:"stroke",itemStyle:"fill"};function zg(t,e){var n=t.visualStyleMapper||Ng[e];return n||(console.warn("Unkown style type '"+e+"'."),Ng.itemStyle)}function Vg(t,e){var n=t.visualDrawType||Eg[e];return n||(console.warn("Unkown style type '"+e+"'."),"fill")}var Bg={createOnAllSeries:!0,performRawSeries:!0,reset:function(t,e){var n=t.getData(),i=t.visualStyleAccessPath||"itemStyle",r=t.getModel(i),o=zg(t,i)(r),a=r.getShallow("decal");a&&(n.setVisual("decal",a),a.dirty=!0);var s=Vg(t,i),l=o[s],u=U(l)?l:null,h="auto"===o.fill||"auto"===o.stroke;if(!o[s]||u||h){var c=t.getColorFromPalette(t.name,null,e.getSeriesCount());o[s]||(o[s]=c,n.setVisual("colorFromPalette",!0)),o.fill="auto"===o.fill||U(o.fill)?c:o.fill,o.stroke="auto"===o.stroke||U(o.stroke)?c:o.stroke}if(n.setVisual("style",o),n.setVisual("drawType",s),!e.isSeriesFiltered(t)&&u)return n.setVisual("colorFromPalette",!1),{dataEach:function(e,n){var i=t.getDataParams(n),r=A({},o);r[s]=u(i),e.setItemVisual(n,"style",r)}}}},Fg=new xc,Gg={createOnAllSeries:!0,performRawSeries:!0,reset:function(t,e){if(!t.ignoreStyleOnData&&!e.isSeriesFiltered(t)){var n=t.getData(),i=t.visualStyleAccessPath||"itemStyle",r=zg(t,i),o=n.getVisual("drawType");return{dataEach:n.hasItemOption?function(t,e){var n=t.getRawDataItem(e);if(n&&n[i]){Fg.option=n[i];var a=r(Fg);A(t.ensureUniqueItemVisual(e,"style"),a),Fg.option.decal&&(t.setItemVisual(e,"decal",Fg.option.decal),Fg.option.decal.dirty=!0),o in a&&t.setItemVisual(e,"colorFromPalette",!1)}}:null}}}},Wg={performRawSeries:!0,overallReset:function(t){var e=ft();t.eachSeries((function(t){var n=t.getColorBy();if(!t.isColorBySeries()){var i=t.type+"-"+n,r=e.get(i);r||(r={},e.set(i,r)),Rg(t).scope=r}})),t.eachSeries((function(e){if(!e.isColorBySeries()&&!t.isSeriesFiltered(e)){var n=e.getRawData(),i={},r=e.getData(),o=Rg(e).scope,a=e.visualStyleAccessPath||"itemStyle",s=Vg(e,a);r.each((function(t){var e=r.getRawIndex(t);i[e]=t})),n.each((function(t){var a=i[t];if(r.getItemVisual(a,"colorFromPalette")){var l=r.ensureUniqueItemVisual(a,"style"),u=n.getName(t)||t+"",h=n.count();l[s]=e.getColorFromPalette(u,o,h)}}))}}))}},Hg=Math.PI;var Yg=function(){function t(t,e,n,i){this._stageTaskMap=ft(),this.ecInstance=t,this.api=e,n=this._dataProcessorHandlers=n.slice(),i=this._visualHandlers=i.slice(),this._allHandlers=n.concat(i)}return t.prototype.restoreData=function(t,e){t.restoreData(e),this._stageTaskMap.each((function(t){var e=t.overallTask;e&&e.dirty()}))},t.prototype.getPerformArgs=function(t,e){if(t.__pipeline){var n=this._pipelineMap.get(t.__pipeline.id),i=n.context,r=!e&&n.progressiveEnabled&&(!i||i.progressiveRender)&&t.__idxInPipeline>n.blockIndex?n.step:null,o=i&&i.modDataCount;return{step:r,modBy:null!=o?Math.ceil(o/r):null,modDataCount:o}}},t.prototype.getPipeline=function(t){return this._pipelineMap.get(t)},t.prototype.updateStreamModes=function(t,e){var n=this._pipelineMap.get(t.uid),i=t.getData().count(),r=n.progressiveEnabled&&e.incrementalPrepareRender&&i>=n.threshold,o=t.get("large")&&i>=t.get("largeThreshold"),a="mod"===t.get("progressiveChunkMode")?i:null;t.pipelineContext=n.context={progressiveRender:r,modDataCount:a,large:o}},t.prototype.restorePipelines=function(t){var e=this,n=e._pipelineMap=ft();t.eachSeries((function(t){var i=t.getProgressive(),r=t.uid;n.set(r,{id:r,head:null,tail:null,threshold:t.getProgressiveThreshold(),progressiveEnabled:i&&!(t.preventIncremental&&t.preventIncremental()),blockIndex:-1,step:Math.round(i||700),count:0}),e._pipe(t,t.dataTask)}))},t.prototype.prepareStageTasks=function(){var t=this._stageTaskMap,e=this.api.getModel(),n=this.api;E(this._allHandlers,(function(i){var r=t.get(i.uid)||t.set(i.uid,{}),o="";lt(!(i.reset&&i.overallReset),o),i.reset&&this._createSeriesStageTask(i,r,e,n),i.overallReset&&this._createOverallStageTask(i,r,e,n)}),this)},t.prototype.prepareView=function(t,e,n,i){var r=t.renderTask,o=r.context;o.model=e,o.ecModel=n,o.api=i,r.__block=!t.incrementalPrepareRender,this._pipe(e,r)},t.prototype.performDataProcessorTasks=function(t,e){this._performStageTasks(this._dataProcessorHandlers,t,e,{block:!0})},t.prototype.performVisualTasks=function(t,e,n){this._performStageTasks(this._visualHandlers,t,e,n)},t.prototype._performStageTasks=function(t,e,n,i){i=i||{};var r=!1,o=this;function a(t,e){return t.setDirty&&(!t.dirtyMap||t.dirtyMap.get(e.__pipeline.id))}E(t,(function(t,s){if(!i.visualType||i.visualType===t.visualType){var l=o._stageTaskMap.get(t.uid),u=l.seriesTaskMap,h=l.overallTask;if(h){var c,p=h.agentStubMap;p.each((function(t){a(i,t)&&(t.dirty(),c=!0)})),c&&h.dirty(),o.updatePayload(h,n);var d=o.getPerformArgs(h,i.block);p.each((function(t){t.perform(d)})),h.perform(d)&&(r=!0)}else u&&u.each((function(s,l){a(i,s)&&s.dirty();var u=o.getPerformArgs(s,i.block);u.skip=!t.performRawSeries&&e.isSeriesFiltered(s.context.model),o.updatePayload(s,n),s.perform(u)&&(r=!0)}))}})),this.unfinished=r||this.unfinished},t.prototype.performSeriesTasks=function(t){var e;t.eachSeries((function(t){e=t.dataTask.perform()||e})),this.unfinished=e||this.unfinished},t.prototype.plan=function(){this._pipelineMap.each((function(t){var e=t.tail;do{if(e.__block){t.blockIndex=e.__idxInPipeline;break}e=e.getUpstream()}while(e)}))},t.prototype.updatePayload=function(t,e){"remain"!==e&&(t.context.payload=e)},t.prototype._createSeriesStageTask=function(t,e,n,i){var r=this,o=e.seriesTaskMap,a=e.seriesTaskMap=ft(),s=t.seriesType,l=t.getTargetSeries;function u(e){var s=e.uid,l=a.set(s,o&&o.get(s)||df({plan:qg,reset:Kg,count:Qg}));l.context={model:e,ecModel:n,api:i,useClearVisual:t.isVisual&&!t.isLayout,plan:t.plan,reset:t.reset,scheduler:r},r._pipe(e,l)}t.createOnAllSeries?n.eachRawSeries(u):s?n.eachRawSeriesByType(s,u):l&&l(n,i).each(u)},t.prototype._createOverallStageTask=function(t,e,n,i){var r=this,o=e.overallTask=e.overallTask||df({reset:Ug});o.context={ecModel:n,api:i,overallReset:t.overallReset,scheduler:r};var a=o.agentStubMap,s=o.agentStubMap=ft(),l=t.seriesType,u=t.getTargetSeries,h=!0,c=!1,p="";function d(t){var e=t.uid,n=s.set(e,a&&a.get(e)||(c=!0,df({reset:Xg,onDirty:jg})));n.context={model:t,overallProgress:h},n.agent=o,n.__block=h,r._pipe(t,n)}lt(!t.createOnAllSeries,p),l?n.eachRawSeriesByType(l,d):u?u(n,i).each(d):(h=!1,E(n.getSeries(),d)),c&&o.dirty()},t.prototype._pipe=function(t,e){var n=t.uid,i=this._pipelineMap.get(n);!i.head&&(i.head=e),i.tail&&i.tail.pipe(e),i.tail=e,e.__idxInPipeline=i.count++,e.__pipeline=i},t.wrapStageHandler=function(t,e){return U(t)&&(t={overallReset:t,seriesType:ty(t)}),t.uid=bc("stageHandler"),e&&(t.visualType=e),t},t}();function Ug(t){t.overallReset(t.ecModel,t.api,t.payload)}function Xg(t){return t.overallProgress&&Zg}function Zg(){this.agent.dirty(),this.getDownstream().dirty()}function jg(){this.agent&&this.agent.dirty()}function qg(t){return t.plan?t.plan(t.model,t.ecModel,t.api,t.payload):null}function Kg(t){t.useClearVisual&&t.data.clearAllVisual();var e=t.resetDefines=yo(t.reset(t.model,t.ecModel,t.api,t.payload));return e.length>1?z(e,(function(t,e){return Jg(e)})):$g}var $g=Jg(0);function Jg(t){return function(e,n){var i=n.data,r=n.resetDefines[t];if(r&&r.dataEach)for(var o=e.start;o0&&h===r.length-u.length){var c=r.slice(0,h);"data"!==c&&(e.mainType=c,e[u.toLowerCase()]=t,s=!0)}}a.hasOwnProperty(r)&&(n[r]=t,s=!0),s||(i[r]=t)}))}return{cptQuery:e,dataQuery:n,otherQuery:i}},t.prototype.filter=function(t,e){var n=this.eventInfo;if(!n)return!0;var i=n.targetEl,r=n.packedEvent,o=n.model,a=n.view;if(!o||!a)return!0;var s=e.cptQuery,l=e.dataQuery;return u(s,o,"mainType")&&u(s,o,"subType")&&u(s,o,"index","componentIndex")&&u(s,o,"name")&&u(s,o,"id")&&u(l,r,"name")&&u(l,r,"dataIndex")&&u(l,r,"dataType")&&(!a.filterForExposedEvent||a.filterForExposedEvent(t,e.otherQuery,i,r));function u(t,e,n,i){return null==t[n]||e[i||n]===t[n]}},t.prototype.afterTrigger=function(){this.eventInfo=null},t}(),dy=["symbol","symbolSize","symbolRotate","symbolOffset"],fy=dy.concat(["symbolKeepAspect"]),gy={createOnAllSeries:!0,performRawSeries:!0,reset:function(t,e){var n=t.getData();if(t.legendIcon&&n.setVisual("legendIcon",t.legendIcon),t.hasSymbolVisual){for(var i={},r={},o=!1,a=0;a=0&&zy(l)?l:.5,t.createRadialGradient(a,s,0,a,s,l)}(t,e,n):function(t,e,n){var i=null==e.x?0:e.x,r=null==e.x2?1:e.x2,o=null==e.y?0:e.y,a=null==e.y2?0:e.y2;return e.global||(i=i*n.width+n.x,r=r*n.width+n.x,o=o*n.height+n.y,a=a*n.height+n.y),i=zy(i)?i:0,r=zy(r)?r:1,o=zy(o)?o:0,a=zy(a)?a:0,t.createLinearGradient(i,o,r,a)}(t,e,n),r=e.colorStops,o=0;o0&&(e=i.lineDash,n=i.lineWidth,e&&"solid"!==e&&n>0?"dashed"===e?[4*n,2*n]:"dotted"===e?[n]:j(e)?[e]:Y(e)?e:null:null),o=i.lineDashOffset;if(r){var a=i.strokeNoScale&&t.getLineScale?t.getLineScale():1;a&&1!==a&&(r=z(r,(function(t){return t/a})),o/=a)}return[r,o]}var Wy=new ts(!0);function Hy(t){var e=t.stroke;return!(null==e||"none"===e||!(t.lineWidth>0))}function Yy(t){return"string"==typeof t&&"none"!==t}function Uy(t){var e=t.fill;return null!=e&&"none"!==e}function Xy(t,e){if(null!=e.fillOpacity&&1!==e.fillOpacity){var n=t.globalAlpha;t.globalAlpha=e.fillOpacity*e.opacity,t.fill(),t.globalAlpha=n}else t.fill()}function Zy(t,e){if(null!=e.strokeOpacity&&1!==e.strokeOpacity){var n=t.globalAlpha;t.globalAlpha=e.strokeOpacity*e.opacity,t.stroke(),t.globalAlpha=n}else t.stroke()}function jy(t,e,n){var i=Jo(e.image,e.__image,n);if(ta(i)){var r=t.createPattern(i,e.repeat||"repeat");if("function"==typeof DOMMatrix&&r&&r.setTransform){var o=new DOMMatrix;o.translateSelf(e.x||0,e.y||0),o.rotateSelf(0,0,(e.rotation||0)*_t),o.scaleSelf(e.scaleX||1,e.scaleY||1),r.setTransform(o)}return r}}var qy=["shadowBlur","shadowOffsetX","shadowOffsetY"],Ky=[["lineCap","butt"],["lineJoin","miter"],["miterLimit",10]];function $y(t,e,n,i,r){var o=!1;if(!i&&e===(n=n||{}))return!1;if(i||e.opacity!==n.opacity){tv(t,r),o=!0;var a=Math.max(Math.min(e.opacity,1),0);t.globalAlpha=isNaN(a)?fa.opacity:a}(i||e.blend!==n.blend)&&(o||(tv(t,r),o=!0),t.globalCompositeOperation=e.blend||fa.blend);for(var s=0;s0&&t.unfinished);t.unfinished||this._zr.flush()}}},e.prototype.getDom=function(){return this._dom},e.prototype.getId=function(){return this.id},e.prototype.getZr=function(){return this._zr},e.prototype.isSSR=function(){return this._ssr},e.prototype.setOption=function(t,e,n){if(!this.__flagInMainProcess)if(this._disposed)Xv(this.id);else{var i,r,o;if(q(e)&&(n=e.lazyUpdate,i=e.silent,r=e.replaceMerge,o=e.transition,e=e.notMerge),this.__flagInMainProcess=!0,!this._model||e){var a=new gd(this._api),s=this._theme,l=this._model=new ad;l.scheduler=this._scheduler,l.ssr=this._ssr,l.init(null,null,null,s,this._locale,a)}this._model.setOption(t,{replaceMerge:r},Kv);var u={seriesTransition:o,optionChanged:!0};if(n)this.__pendingUpdate={silent:i,updateParams:u},this.__flagInMainProcess=!1,this.getZr().wakeUp();else{try{Sv(this),Tv.update.call(this,null,u)}catch(t){throw this.__pendingUpdate=null,this.__flagInMainProcess=!1,t}this._ssr||this._zr.flush(),this.__pendingUpdate=null,this.__flagInMainProcess=!1,kv.call(this,i),Lv.call(this,i)}}},e.prototype.setTheme=function(){ho()},e.prototype.getModel=function(){return this._model},e.prototype.getOption=function(){return this._model&&this._model.getOption()},e.prototype.getWidth=function(){return this._zr.getWidth()},e.prototype.getHeight=function(){return this._zr.getHeight()},e.prototype.getDevicePixelRatio=function(){return this._zr.painter.dpr||fv&&window.devicePixelRatio||1},e.prototype.getRenderedCanvas=function(t){return this.renderToCanvas(t)},e.prototype.renderToCanvas=function(t){t=t||{};var e=this._zr.painter;return e.getRenderedCanvas({backgroundColor:t.backgroundColor||this._model.get("backgroundColor"),pixelRatio:t.pixelRatio||this.getDevicePixelRatio()})},e.prototype.renderToSVGString=function(t){t=t||{};var e=this._zr.painter;return e.renderToString({useViewBox:t.useViewBox})},e.prototype.getSvgDataURL=function(){if(r.svgSupported){var t=this._zr;return E(t.storage.getDisplayList(),(function(t){t.stopAnimation(null,!0)})),t.painter.toDataURL()}},e.prototype.getDataURL=function(t){if(!this._disposed){var e=(t=t||{}).excludeComponents,n=this._model,i=[],r=this;E(e,(function(t){n.eachComponent({mainType:t},(function(t){var e=r._componentsMap[t.__viewId];e.group.ignore||(i.push(e),e.group.ignore=!0)}))}));var o="svg"===this._zr.painter.getType()?this.getSvgDataURL():this.renderToCanvas(t).toDataURL("image/"+(t&&t.type||"png"));return E(i,(function(t){t.group.ignore=!1})),o}Xv(this.id)},e.prototype.getConnectedDataURL=function(t){if(!this._disposed){var e="svg"===t.type,n=this.group,i=Math.min,r=Math.max,o=1/0;if(em[n]){var a=o,s=o,l=-1/0,u=-1/0,c=[],p=t&&t.pixelRatio||this.getDevicePixelRatio();E(tm,(function(o,h){if(o.group===n){var p=e?o.getZr().painter.getSvgDom().innerHTML:o.renderToCanvas(T(t)),d=o.getDom().getBoundingClientRect();a=i(d.left,a),s=i(d.top,s),l=r(d.right,l),u=r(d.bottom,u),c.push({dom:p,left:d.left,top:d.top})}}));var d=(l*=p)-(a*=p),f=(u*=p)-(s*=p),g=h.createCanvas(),y=Er(g,{renderer:e?"svg":"canvas"});if(y.resize({width:d,height:f}),e){var v="";return E(c,(function(t){var e=t.left-a,n=t.top-s;v+=''+t.dom+""})),y.painter.getSvgRoot().innerHTML=v,t.connectedBackgroundColor&&y.painter.setBackgroundColor(t.connectedBackgroundColor),y.refreshImmediately(),y.painter.toDataURL()}return t.connectedBackgroundColor&&y.add(new Ps({shape:{x:0,y:0,width:d,height:f},style:{fill:t.connectedBackgroundColor}})),E(c,(function(t){var e=new Is({style:{x:t.left*p-a,y:t.top*p-s,image:t.dom}});y.add(e)})),y.refreshImmediately(),g.toDataURL("image/"+(t&&t.type||"png"))}return this.getDataURL(t)}Xv(this.id)},e.prototype.convertToPixel=function(t,e){return Cv(this,"convertToPixel",t,e)},e.prototype.convertFromPixel=function(t,e){return Cv(this,"convertFromPixel",t,e)},e.prototype.containPixel=function(t,e){var n;if(!this._disposed)return E(ko(this._model,t),(function(t,i){i.indexOf("Models")>=0&&E(t,(function(t){var r=t.coordinateSystem;if(r&&r.containPoint)n=n||!!r.containPoint(e);else if("seriesModels"===i){var o=this._chartsMap[t.__viewId];o&&o.containPoint&&(n=n||o.containPoint(e,t))}else 0}),this)}),this),!!n;Xv(this.id)},e.prototype.getVisual=function(t,e){var n=ko(this._model,t,{defaultMainType:"series"}),i=n.seriesModel;var r=i.getData(),o=n.hasOwnProperty("dataIndexInside")?n.dataIndexInside:n.hasOwnProperty("dataIndex")?r.indexOfRawIndex(n.dataIndex):null;return null!=o?vy(r,o,e):my(r,e)},e.prototype.getViewOfComponentModel=function(t){return this._componentsMap[t.__viewId]},e.prototype.getViewOfSeriesModel=function(t){return this._chartsMap[t.__viewId]},e.prototype._initEvents=function(){var t,e,n,i=this;E(Uv,(function(t){var e=function(e){var n,r=i.getModel(),o=e.target,a="globalout"===t;if(a?n={}:o&&wy(o,(function(t){var e=js(t);if(e&&null!=e.dataIndex){var i=e.dataModel||r.getSeriesByIndex(e.seriesIndex);return n=i&&i.getDataParams(e.dataIndex,e.dataType)||{},!0}if(e.eventData)return n=A({},e.eventData),!0}),!0),n){var s=n.componentType,l=n.componentIndex;"markLine"!==s&&"markPoint"!==s&&"markArea"!==s||(s="series",l=n.seriesIndex);var u=s&&null!=l&&r.getComponent(s,l),h=u&&i["series"===u.mainType?"_chartsMap":"_componentsMap"][u.__viewId];0,n.event=e,n.type=t,i._$eventProcessor.eventInfo={targetEl:o,packedEvent:n,model:u,view:h},i.trigger(t,n)}};e.zrEventfulCallAtLast=!0,i._zr.on(t,e,i)})),E(jv,(function(t,e){i._messageCenter.on(e,(function(t){this.trigger(e,t)}),i)})),E(["selectchanged"],(function(t){i._messageCenter.on(t,(function(e){this.trigger(t,e)}),i)})),t=this._messageCenter,e=this,n=this._api,t.on("selectchanged",(function(t){var i=n.getModel();t.isFromClick?(by("map","selectchanged",e,i,t),by("pie","selectchanged",e,i,t)):"select"===t.fromAction?(by("map","selected",e,i,t),by("pie","selected",e,i,t)):"unselect"===t.fromAction&&(by("map","unselected",e,i,t),by("pie","unselected",e,i,t))}))},e.prototype.isDisposed=function(){return this._disposed},e.prototype.clear=function(){this._disposed?Xv(this.id):this.setOption({series:[]},!0)},e.prototype.dispose=function(){if(this._disposed)Xv(this.id);else{this._disposed=!0,this.getDom()&&No(this.getDom(),rm,"");var t=this,e=t._api,n=t._model;E(t._componentsViews,(function(t){t.dispose(n,e)})),E(t._chartsViews,(function(t){t.dispose(n,e)})),t._zr.dispose(),t._dom=t._model=t._chartsMap=t._componentsMap=t._chartsViews=t._componentsViews=t._scheduler=t._api=t._zr=t._throttledZrFlush=t._theme=t._coordSysMgr=t._messageCenter=null,delete tm[t.id]}},e.prototype.resize=function(t){if(!this.__flagInMainProcess)if(this._disposed)Xv(this.id);else{this._zr.resize(t);var e=this._model;if(this._loadingFX&&this._loadingFX.resize(),e){var n=e.resetOption("media"),i=t&&t.silent;this.__pendingUpdate&&(null==i&&(i=this.__pendingUpdate.silent),n=!0,this.__pendingUpdate=null),this.__flagInMainProcess=!0;try{n&&Sv(this),Tv.update.call(this,{type:"resize",animation:A({duration:0},t&&t.animation)})}catch(t){throw this.__flagInMainProcess=!1,t}this.__flagInMainProcess=!1,kv.call(this,i),Lv.call(this,i)}}},e.prototype.showLoading=function(t,e){if(this._disposed)Xv(this.id);else if(q(t)&&(e=t,t=""),t=t||"default",this.hideLoading(),Qv[t]){var n=Qv[t](this._api,e),i=this._zr;this._loadingFX=n,i.add(n)}},e.prototype.hideLoading=function(){this._disposed?Xv(this.id):(this._loadingFX&&this._zr.remove(this._loadingFX),this._loadingFX=null)},e.prototype.makeActionFromEvent=function(t){var e=A({},t);return e.type=jv[t.type],e},e.prototype.dispatchAction=function(t,e){if(this._disposed)Xv(this.id);else if(q(e)||(e={silent:!!e}),Zv[t.type]&&this._model)if(this.__flagInMainProcess)this._pendingActions.push(t);else{var n=e.silent;Av.call(this,t,n);var i=e.flush;i?this._zr.flush():!1!==i&&r.browser.weChat&&this._throttledZrFlush(),kv.call(this,n),Lv.call(this,n)}},e.prototype.updateLabelLayout=function(){cv.trigger("series:layoutlabels",this._model,this._api,{updatedSeries:[]})},e.prototype.appendData=function(t){if(this._disposed)Xv(this.id);else{var e=t.seriesIndex,n=this.getModel().getSeriesByIndex(e);0,n.appendData(t),this._scheduler.unfinished=!0,this.getZr().wakeUp()}},e.internalField=function(){function t(t){t.clearColorPalette(),t.eachSeries((function(t){t.clearColorPalette()}))}function e(t){for(var e=[],n=t.currentStates,i=0;i0?{duration:o,delay:i.get("delay"),easing:i.get("easing")}:null;n.eachRendered((function(t){if(t.states&&t.states.emphasis){if(ch(t))return;if(t instanceof _s&&function(t){var e=Js(t);e.normalFill=t.style.fill,e.normalStroke=t.style.stroke;var n=t.states.select||{};e.selectFill=n.style&&n.style.fill||null,e.selectStroke=n.style&&n.style.stroke||null}(t),t.__dirty){var n=t.prevStates;n&&t.useStates(n)}if(r){t.stateTransition=a;var i=t.getTextContent(),o=t.getTextGuideLine();i&&(i.stateTransition=a),o&&(o.stateTransition=a)}t.__dirty&&e(t)}}))}Sv=function(t){var e=t._scheduler;e.restorePipelines(t._model),e.prepareStageTasks(),Mv(t,!0),Mv(t,!1),e.plan()},Mv=function(t,e){for(var n=t._model,i=t._scheduler,r=e?t._componentsViews:t._chartsViews,o=e?t._componentsMap:t._chartsMap,a=t._zr,s=t._api,l=0;le.get("hoverLayerThreshold")&&!r.node&&!r.worker&&e.eachSeries((function(e){if(!e.preventUsingHoverLayer){var n=t._chartsMap[e.__viewId];n.__alive&&n.eachRendered((function(t){t.states.emphasis&&(t.states.emphasis.hoverLayer=!0)}))}}))}(t,e),cv.trigger("series:afterupdate",e,n,l)},Bv=function(t){t.__needsUpdateStatus=!0,t.getZr().wakeUp()},Fv=function(t){t.__needsUpdateStatus&&(t.getZr().storage.traverse((function(t){ch(t)||e(t)})),t.__needsUpdateStatus=!1)},zv=function(t){return new(function(e){function i(){return null!==e&&e.apply(this,arguments)||this}return n(i,e),i.prototype.getCoordinateSystems=function(){return t._coordSysMgr.getCoordinateSystems()},i.prototype.getComponentByElement=function(e){for(;e;){var n=e.__ecComponentInfo;if(null!=n)return t._model.getComponent(n.mainType,n.index);e=e.parent}},i.prototype.enterEmphasis=function(e,n){Il(e,n),Bv(t)},i.prototype.leaveEmphasis=function(e,n){Tl(e,n),Bv(t)},i.prototype.enterBlur=function(e){Cl(e),Bv(t)},i.prototype.leaveBlur=function(e){Dl(e),Bv(t)},i.prototype.enterSelect=function(e){Al(e),Bv(t)},i.prototype.leaveSelect=function(e){kl(e),Bv(t)},i.prototype.getModel=function(){return t.getModel()},i.prototype.getViewOfComponentModel=function(e){return t.getViewOfComponentModel(e)},i.prototype.getViewOfSeriesModel=function(e){return t.getViewOfSeriesModel(e)},i}(cd))(t)},Vv=function(t){function e(t,e){for(var n=0;n=0)){mm.push(n);var o=Yg.wrapStageHandler(n,r);o.__prio=e,o.__raw=n,t.push(o)}}function _m(t,e){Qv[t]=e}function bm(t,e,n){var i=dv("registerMap");i&&i(t,e,n)}var wm=function(t){var e=(t=T(t)).type,n="";e||co(n);var i=e.split(":");2!==i.length&&co(n);var r=!1;"echarts"===i[0]&&(e=i[1],r=!0),t.__isBuiltIn=r,Af.set(e,t)};vm(gv,Bg),vm(yv,Gg),vm(yv,Wg),vm(gv,gy),vm(yv,yy),vm(7e3,(function(t,e){t.eachRawSeries((function(n){if(!t.isSeriesFiltered(n)){var i=n.getData();i.hasItemVisual()&&i.each((function(t){var n=i.getItemVisual(t,"decal");n&&(i.ensureUniqueItemVisual(t,"style").decal=sv(n,e))}));var r=i.getVisual("decal");if(r)i.getVisual("style").decal=sv(r,e)}}))})),um(Ed),hm(900,(function(t){var e=ft();t.eachSeries((function(t){var n=t.get("stack");if(n){var i=e.get(n)||e.set(n,[]),r=t.getData(),o={stackResultDimension:r.getCalculationInfo("stackResultDimension"),stackedOverDimension:r.getCalculationInfo("stackedOverDimension"),stackedDimension:r.getCalculationInfo("stackedDimension"),stackedByDimension:r.getCalculationInfo("stackedByDimension"),isStackedByIndex:r.getCalculationInfo("isStackedByIndex"),data:r,seriesModel:t};if(!o.stackedDimension||!o.isStackedByIndex&&!o.stackedByDimension)return;i.length&&r.setCalculationInfo("stackedOnSeries",i[i.length-1].seriesModel),i.push(o)}})),e.each(zd)})),_m("default",(function(t,e){k(e=e||{},{text:"loading",textColor:"#000",fontSize:12,fontWeight:"normal",fontStyle:"normal",fontFamily:"sans-serif",maskColor:"rgba(255, 255, 255, 0.8)",showSpinner:!0,color:"#5470c6",spinnerRadius:10,lineWidth:5,zlevel:0});var n=new Pr,i=new Ps({style:{fill:e.maskColor},zlevel:e.zlevel,z:1e4});n.add(i);var r,o=new Ns({style:{text:e.text,fill:e.textColor,fontSize:e.fontSize,fontWeight:e.fontWeight,fontStyle:e.fontStyle,fontFamily:e.fontFamily},zlevel:e.zlevel,z:10001}),a=new Ps({style:{fill:"none"},textContent:o,textConfig:{position:"right",distance:10},zlevel:e.zlevel,z:10001});return n.add(a),e.showSpinner&&((r=new ju({shape:{startAngle:-Hg/2,endAngle:-Hg/2+.1,r:e.spinnerRadius},style:{stroke:e.color,lineCap:"round",lineWidth:e.lineWidth},zlevel:e.zlevel,z:10001})).animateShape(!0).when(1e3,{endAngle:3*Hg/2}).start("circularInOut"),r.animateShape(!0).when(1e3,{startAngle:3*Hg/2}).delay(300).start("circularInOut"),n.add(r)),n.resize=function(){var n=o.getBoundingRect().width,s=e.showSpinner?e.spinnerRadius:0,l=(t.getWidth()-2*s-(e.showSpinner&&n?10:0)-n)/2-(e.showSpinner&&n?0:5+n/2)+(e.showSpinner?0:n/2)+(n?0:s),u=t.getHeight()/2;e.showSpinner&&r.setShape({cx:l,cy:u}),a.setShape({x:l-s,y:u-s,width:2*s,height:2*s}),i.setShape({x:0,y:0,width:t.getWidth(),height:t.getHeight()})},n.resize(),n})),fm({type:il,event:il,update:il},xt),fm({type:rl,event:rl,update:rl},xt),fm({type:ol,event:ol,update:ol},xt),fm({type:al,event:al,update:al},xt),fm({type:sl,event:sl,update:sl},xt),lm("light",ay),lm("dark",cy);var Sm=[],Mm={registerPreprocessor:um,registerProcessor:hm,registerPostInit:cm,registerPostUpdate:pm,registerUpdateLifecycle:dm,registerAction:fm,registerCoordinateSystem:gm,registerLayout:ym,registerVisual:vm,registerTransform:wm,registerLoading:_m,registerMap:bm,registerImpl:function(t,e){pv[t]=e},PRIORITY:vv,ComponentModel:Ap,ComponentView:mg,SeriesModel:hg,ChartView:wg,registerComponentModel:function(t){Ap.registerClass(t)},registerComponentView:function(t){mg.registerClass(t)},registerSeriesModel:function(t){hg.registerClass(t)},registerChartView:function(t){wg.registerClass(t)},registerSubTypeDefaulter:function(t,e){Ap.registerSubTypeDefaulter(t,e)},registerPainter:function(t,e){zr(t,e)}};function Im(t){Y(t)?E(t,(function(t){Im(t)})):P(Sm,t)>=0||(Sm.push(t),U(t)&&(t={install:t}),t.install(Mm))}function Tm(t){return null==t?0:t.length||1}function Cm(t){return t}var Dm=function(){function t(t,e,n,i,r,o){this._old=t,this._new=e,this._oldKeyGetter=n||Cm,this._newKeyGetter=i||Cm,this.context=r,this._diffModeMultiple="multiple"===o}return t.prototype.add=function(t){return this._add=t,this},t.prototype.update=function(t){return this._update=t,this},t.prototype.updateManyToOne=function(t){return this._updateManyToOne=t,this},t.prototype.updateOneToMany=function(t){return this._updateOneToMany=t,this},t.prototype.updateManyToMany=function(t){return this._updateManyToMany=t,this},t.prototype.remove=function(t){return this._remove=t,this},t.prototype.execute=function(){this[this._diffModeMultiple?"_executeMultiple":"_executeOneToOne"]()},t.prototype._executeOneToOne=function(){var t=this._old,e=this._new,n={},i=new Array(t.length),r=new Array(e.length);this._initIndexMap(t,null,i,"_oldKeyGetter"),this._initIndexMap(e,n,r,"_newKeyGetter");for(var o=0;o1){var u=s.shift();1===s.length&&(n[a]=s[0]),this._update&&this._update(u,o)}else 1===l?(n[a]=null,this._update&&this._update(s,o)):this._remove&&this._remove(o)}this._performRestAdd(r,n)},t.prototype._executeMultiple=function(){var t=this._old,e=this._new,n={},i={},r=[],o=[];this._initIndexMap(t,n,r,"_oldKeyGetter"),this._initIndexMap(e,i,o,"_newKeyGetter");for(var a=0;a1&&1===c)this._updateManyToOne&&this._updateManyToOne(u,l),i[s]=null;else if(1===h&&c>1)this._updateOneToMany&&this._updateOneToMany(u,l),i[s]=null;else if(1===h&&1===c)this._update&&this._update(u,l),i[s]=null;else if(h>1&&c>1)this._updateManyToMany&&this._updateManyToMany(u,l),i[s]=null;else if(h>1)for(var p=0;p1)for(var a=0;a30}var Fm,Gm,Wm,Hm,Ym,Um,Xm,Zm=q,jm=z,qm="undefined"==typeof Int32Array?Array:Int32Array,Km=["hasItemOption","_nameList","_idList","_invertedIndicesMap","_dimSummary","userOutput","_rawData","_dimValueGetter","_nameDimIdx","_idDimIdx","_nameRepeatCount"],$m=["_approximateExtent"],Jm=function(){function t(t,e){var n;this.type="list",this._dimOmitted=!1,this._nameList=[],this._idList=[],this._visual={},this._layout={},this._itemVisuals=[],this._itemLayouts=[],this._graphicEls=[],this._approximateExtent={},this._calculationInfo={},this.hasItemOption=!1,this.TRANSFERABLE_METHODS=["cloneShallow","downSample","lttbDownSample","map"],this.CHANGABLE_METHODS=["filterSelf","selectRange"],this.DOWNSAMPLE_METHODS=["downSample","lttbDownSample"];var i=!1;Em(t)?(n=t.dimensions,this._dimOmitted=t.isDimensionOmitted(),this._schema=t):(i=!0,n=t),n=n||["x","y"];for(var r={},o=[],a={},s=!1,l={},u=0;u=e)){var n=this._store.getProvider();this._updateOrdinalMeta();var i=this._nameList,r=this._idList;if(n.getSource().sourceFormat===Rp&&!n.pure)for(var o=[],a=t;a0},t.prototype.ensureUniqueItemVisual=function(t,e){var n=this._itemVisuals,i=n[t];i||(i=n[t]={});var r=i[e];return null==r&&(Y(r=this.getVisual(e))?r=r.slice():Zm(r)&&(r=A({},r)),i[e]=r),r},t.prototype.setItemVisual=function(t,e,n){var i=this._itemVisuals[t]||{};this._itemVisuals[t]=i,Zm(e)?A(i,e):i[e]=n},t.prototype.clearAllVisual=function(){this._visual={},this._itemVisuals=[]},t.prototype.setLayout=function(t,e){Zm(t)?A(this._layout,t):this._layout[t]=e},t.prototype.getLayout=function(t){return this._layout[t]},t.prototype.getItemLayout=function(t){return this._itemLayouts[t]},t.prototype.setItemLayout=function(t,e,n){this._itemLayouts[t]=n?A(this._itemLayouts[t]||{},e):e},t.prototype.clearItemLayouts=function(){this._itemLayouts.length=0},t.prototype.setItemGraphicEl=function(t,e){var n=this.hostModel&&this.hostModel.seriesIndex;qs(n,this.dataType,t,e),this._graphicEls[t]=e},t.prototype.getItemGraphicEl=function(t){return this._graphicEls[t]},t.prototype.eachItemGraphicEl=function(t,e){E(this._graphicEls,(function(n,i){n&&t&&t.call(e,n,i)}))},t.prototype.cloneShallow=function(e){return e||(e=new t(this._schema?this._schema:jm(this.dimensions,this._getDimInfo,this),this.hostModel)),Ym(e,this),e._store=this._store,e},t.prototype.wrapMethod=function(t,e){var n=this[t];U(n)&&(this.__wrappedMethods=this.__wrappedMethods||[],this.__wrappedMethods.push(t),this[t]=function(){var t=n.apply(this,arguments);return e.apply(this,[t].concat(at(arguments)))})},t.internalField=(Fm=function(t){var e=t._invertedIndicesMap;E(e,(function(n,i){var r=t._dimInfos[i],o=r.ordinalMeta,a=t._store;if(o){n=e[i]=new qm(o.categories.length);for(var s=0;s1&&(s+="__ec__"+u),i[e]=s}})),t}();function Qm(t,e){Yd(t)||(t=Xd(t));var n=(e=e||{}).coordDimensions||[],i=e.dimensionsDefine||t.dimensionsDefine||[],r=ft(),o=[],a=function(t,e,n,i){var r=Math.max(t.dimensionsDetectedCount||1,e.length,n.length,i||0);return E(e,(function(t){var e;q(t)&&(e=t.dimsDef)&&(r=Math.max(r,e.length))})),r}(t,n,i,e.dimensionsCount),s=e.canOmitUnusedDimensions&&Bm(a),l=i===t.dimensionsDefine,u=l?Vm(t):zm(i),h=e.encodeDefine;!h&&e.encodeDefaulter&&(h=e.encodeDefaulter(t,a));for(var c=ft(h),p=new Ef(a),d=0;d0&&(i.name=r+(o-1)),o++,e.set(r,o)}}(o),new Nm({source:t,dimensions:o,fullDimensionCount:a,dimensionOmitted:s})}function tx(t,e,n){var i=e.data;if(n||i.hasOwnProperty(t)){for(var r=0;i.hasOwnProperty(t+r);)r++;t+=r}return e.set(t,!0),t}var ex=function(t){this.coordSysDims=[],this.axisMap=ft(),this.categoryAxisMap=ft(),this.coordSysName=t};var nx={cartesian2d:function(t,e,n,i){var r=t.getReferringComponents("xAxis",Po).models[0],o=t.getReferringComponents("yAxis",Po).models[0];e.coordSysDims=["x","y"],n.set("x",r),n.set("y",o),ix(r)&&(i.set("x",r),e.firstCategoryDimIndex=0),ix(o)&&(i.set("y",o),null==e.firstCategoryDimIndex&&(e.firstCategoryDimIndex=1))},singleAxis:function(t,e,n,i){var r=t.getReferringComponents("singleAxis",Po).models[0];e.coordSysDims=["single"],n.set("single",r),ix(r)&&(i.set("single",r),e.firstCategoryDimIndex=0)},polar:function(t,e,n,i){var r=t.getReferringComponents("polar",Po).models[0],o=r.findAxisModel("radiusAxis"),a=r.findAxisModel("angleAxis");e.coordSysDims=["radius","angle"],n.set("radius",o),n.set("angle",a),ix(o)&&(i.set("radius",o),e.firstCategoryDimIndex=0),ix(a)&&(i.set("angle",a),null==e.firstCategoryDimIndex&&(e.firstCategoryDimIndex=1))},geo:function(t,e,n,i){e.coordSysDims=["lng","lat"]},parallel:function(t,e,n,i){var r=t.ecModel,o=r.getComponent("parallel",t.get("parallelIndex")),a=e.coordSysDims=o.dimensions.slice();E(o.parallelAxisIndex,(function(t,o){var s=r.getComponent("parallelAxis",t),l=a[o];n.set(l,s),ix(s)&&(i.set(l,s),null==e.firstCategoryDimIndex&&(e.firstCategoryDimIndex=o))}))}};function ix(t){return"category"===t.get("type")}function rx(t,e,n){var i,r,o,a=(n=n||{}).byIndex,s=n.stackedCoordDimension;!function(t){return!Em(t.schema)}(e)?(r=e.schema,i=r.dimensions,o=e.store):i=e;var l,u,h,c,p=!(!t||!t.get("stack"));if(E(i,(function(t,e){X(t)&&(i[e]=t={name:t}),p&&!t.isExtraCoord&&(a||l||!t.ordinalMeta||(l=t),u||"ordinal"===t.type||"time"===t.type||s&&s!==t.coordDim||(u=t))})),!u||a||l||(a=!0),u){h="__\0ecstackresult_"+t.id,c="__\0ecstackedover_"+t.id,l&&(l.createInvertedIndices=!0);var d=u.coordDim,f=u.type,g=0;E(i,(function(t){t.coordDim===d&&g++}));var y={name:h,coordDim:d,coordDimIndex:g,type:f,isExtraCoord:!0,isCalculationCoord:!0,storeDimIndex:i.length},v={name:c,coordDim:c,coordDimIndex:g+1,type:f,isExtraCoord:!0,isCalculationCoord:!0,storeDimIndex:i.length+1};r?(o&&(y.storeDimIndex=o.ensureCalculationDimension(c,f),v.storeDimIndex=o.ensureCalculationDimension(h,f)),r.appendCalculationDimension(y),r.appendCalculationDimension(v)):(i.push(y),i.push(v))}return{stackedDimension:u&&u.name,stackedByDimension:l&&l.name,isStackedByIndex:a,stackedOverDimension:c,stackResultDimension:h}}function ox(t,e){return!!e&&e===t.getCalculationInfo("stackedDimension")}function ax(t,e){return ox(t,e)?t.getCalculationInfo("stackResultDimension"):e}function sx(t,e,n){n=n||{};var i,r=e.getSourceManager(),o=!1;t?(o=!0,i=Xd(t)):o=(i=r.getSource()).sourceFormat===Rp;var a=function(t){var e=t.get("coordinateSystem"),n=new ex(e),i=nx[e];if(i)return i(t,n,n.axisMap,n.categoryAxisMap),n}(e),s=function(t,e){var n,i=t.get("coordinateSystem"),r=dd.get(i);return e&&e.coordSysDims&&(n=z(e.coordSysDims,(function(t){var n={name:t},i=e.axisMap.get(t);if(i){var r=i.get("type");n.type=Lm(r)}return n}))),n||(n=r&&(r.getDimensionsInfo?r.getDimensionsInfo():r.dimensions.slice())||["x","y"]),n}(e,a),l=n.useEncodeDefaulter,u=U(l)?l:l?H(Xp,s,e):null,h=Qm(i,{coordDimensions:s,generateCoord:n.generateCoord,encodeDefine:e.getEncode(),encodeDefaulter:u,canOmitUnusedDimensions:!o}),c=function(t,e,n){var i,r;return n&&E(t,(function(t,o){var a=t.coordDim,s=n.categoryAxisMap.get(a);s&&(null==i&&(i=o),t.ordinalMeta=s.getOrdinalMeta(),e&&(t.createInvertedIndices=!0)),null!=t.otherDims.itemName&&(r=!0)})),r||null==i||(t[i].otherDims.itemName=0),i}(h.dimensions,n.createInvertedIndices,a),p=o?null:r.getSharedDataStore(h),d=rx(e,{schema:h,store:p}),f=new Jm(h,e);f.setCalculationInfo(d);var g=null!=c&&function(t){if(t.sourceFormat===Rp){var e=function(t){var e=0;for(;ee[1]&&(e[1]=t[1])},t.prototype.unionExtentFromData=function(t,e){this.unionExtent(t.getApproximateExtent(e))},t.prototype.getExtent=function(){return this._extent.slice()},t.prototype.setExtent=function(t,e){var n=this._extent;isNaN(t)||(n[0]=t),isNaN(e)||(n[1]=e)},t.prototype.isInExtentRange=function(t){return this._extent[0]<=t&&this._extent[1]>=t},t.prototype.isBlank=function(){return this._isBlank},t.prototype.setBlank=function(t){this._isBlank=t},t}();Xo(lx);var ux=0,hx=function(){function t(t){this.categories=t.categories||[],this._needCollect=t.needCollect,this._deduplication=t.deduplication,this.uid=++ux}return t.createByAxisModel=function(e){var n=e.option,i=n.data,r=i&&z(i,cx);return new t({categories:r,needCollect:!r,deduplication:!1!==n.dedplication})},t.prototype.getOrdinal=function(t){return this._getOrCreateMap().get(t)},t.prototype.parseAndCollect=function(t){var e,n=this._needCollect;if(!X(t)&&!n)return t;if(n&&!this._deduplication)return e=this.categories.length,this.categories[e]=t,e;var i=this._getOrCreateMap();return null==(e=i.get(t))&&(n?(e=this.categories.length,this.categories[e]=t,i.set(t,e)):e=NaN),e},t.prototype._getOrCreateMap=function(){return this._map||(this._map=ft(this.categories))},t}();function cx(t){return q(t)&&null!=t.value?t.value:t+""}function px(t){return"interval"===t.type||"log"===t.type}function dx(t,e,n,i){var r={},o=t[1]-t[0],a=r.interval=no(o/e,!0);null!=n&&ai&&(a=r.interval=i);var s=r.intervalPrecision=gx(a);return function(t,e){!isFinite(t[0])&&(t[0]=e[0]),!isFinite(t[1])&&(t[1]=e[1]),yx(t,0,e),yx(t,1,e),t[0]>t[1]&&(t[0]=t[1])}(r.niceTickExtent=[Wr(Math.ceil(t[0]/a)*a,s),Wr(Math.floor(t[1]/a)*a,s)],t),r}function fx(t){var e=Math.pow(10,eo(t)),n=t/e;return n?2===n?n=3:3===n?n=5:n*=2:n=1,Wr(n*e)}function gx(t){return Yr(t)+2}function yx(t,e,n){t[e]=Math.max(Math.min(t[e],n[1]),n[0])}function vx(t,e){return t>=e[0]&&t<=e[1]}function mx(t,e){return e[1]===e[0]?.5:(t-e[0])/(e[1]-e[0])}function xx(t,e){return t*(e[1]-e[0])+e[0]}var _x=function(t){function e(e){var n=t.call(this,e)||this;n.type="ordinal";var i=n.getSetting("ordinalMeta");return i||(i=new hx({})),Y(i)&&(i=new hx({categories:z(i,(function(t){return q(t)?t.value:t}))})),n._ordinalMeta=i,n._extent=n.getSetting("extent")||[0,i.categories.length-1],n}return n(e,t),e.prototype.parse=function(t){return null==t?NaN:X(t)?this._ordinalMeta.getOrdinal(t):Math.round(t)},e.prototype.contain=function(t){return vx(t=this.parse(t),this._extent)&&null!=this._ordinalMeta.categories[t]},e.prototype.normalize=function(t){return mx(t=this._getTickNumber(this.parse(t)),this._extent)},e.prototype.scale=function(t){return t=Math.round(xx(t,this._extent)),this.getRawOrdinalNumber(t)},e.prototype.getTicks=function(){for(var t=[],e=this._extent,n=e[0];n<=e[1];)t.push({value:n}),n++;return t},e.prototype.getMinorTicks=function(t){},e.prototype.setSortInfo=function(t){if(null!=t){for(var e=t.ordinalNumbers,n=this._ordinalNumbersByTick=[],i=this._ticksByOrdinalNumber=[],r=0,o=this._ordinalMeta.categories.length,a=Math.min(o,e.length);r=0&&t=0&&t=t},e.prototype.getOrdinalMeta=function(){return this._ordinalMeta},e.prototype.calcNiceTicks=function(){},e.prototype.calcNiceExtent=function(){},e.type="ordinal",e}(lx);lx.registerClass(_x);var bx=Wr,Sx=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.type="interval",e._interval=0,e._intervalPrecision=2,e}return n(e,t),e.prototype.parse=function(t){return t},e.prototype.contain=function(t){return vx(t,this._extent)},e.prototype.normalize=function(t){return mx(t,this._extent)},e.prototype.scale=function(t){return xx(t,this._extent)},e.prototype.setExtent=function(t,e){var n=this._extent;isNaN(t)||(n[0]=parseFloat(t)),isNaN(e)||(n[1]=parseFloat(e))},e.prototype.unionExtent=function(t){var e=this._extent;t[0]e[1]&&(e[1]=t[1]),this.setExtent(e[0],e[1])},e.prototype.getInterval=function(){return this._interval},e.prototype.setInterval=function(t){this._interval=t,this._niceExtent=this._extent.slice(),this._intervalPrecision=gx(t)},e.prototype.getTicks=function(t){var e=this._interval,n=this._extent,i=this._niceExtent,r=this._intervalPrecision,o=[];if(!e)return o;n[0]1e4)return[];var s=o.length?o[o.length-1].value:i[1];return n[1]>s&&(t?o.push({value:bx(s+e,r)}):o.push({value:n[1]})),o},e.prototype.getMinorTicks=function(t){for(var e=this.getTicks(!0),n=[],i=this.getExtent(),r=1;ri[0]&&h0&&(o=null===o?s:Math.min(o,s))}n[i]=o}}return n}(t),n=[];return E(t,(function(t){var i,r=t.coordinateSystem.getBaseAxis(),o=r.getExtent();if("category"===r.type)i=r.getBandWidth();else if("value"===r.type||"time"===r.type){var a=r.dim+"_"+r.index,s=e[a],l=Math.abs(o[1]-o[0]),u=r.scale.getExtent(),h=Math.abs(u[1]-u[0]);i=s?l/h*s:l}else{var c=t.getData();i=Math.abs(o[1]-o[0])/c.count()}var p=Gr(t.get("barWidth"),i),d=Gr(t.get("barMaxWidth"),i),f=Gr(t.get("barMinWidth")||(Ex(t)?.5:1),i),g=t.get("barGap"),y=t.get("barCategoryGap");n.push({bandWidth:i,barWidth:p,barMaxWidth:d,barMinWidth:f,barGap:g,barCategoryGap:y,axisKey:Ax(r),stackId:Dx(t)})})),Px(n)}function Px(t){var e={};E(t,(function(t,n){var i=t.axisKey,r=t.bandWidth,o=e[i]||{bandWidth:r,remainedWidth:r,autoWidthCount:0,categoryGap:null,gap:"20%",stacks:{}},a=o.stacks;e[i]=o;var s=t.stackId;a[s]||o.autoWidthCount++,a[s]=a[s]||{width:0,maxWidth:0};var l=t.barWidth;l&&!a[s].width&&(a[s].width=l,l=Math.min(o.remainedWidth,l),o.remainedWidth-=l);var u=t.barMaxWidth;u&&(a[s].maxWidth=u);var h=t.barMinWidth;h&&(a[s].minWidth=h);var c=t.barGap;null!=c&&(o.gap=c);var p=t.barCategoryGap;null!=p&&(o.categoryGap=p)}));var n={};return E(e,(function(t,e){n[e]={};var i=t.stacks,r=t.bandWidth,o=t.categoryGap;if(null==o){var a=G(i).length;o=Math.max(35-4*a,15)+"%"}var s=Gr(o,r),l=Gr(t.gap,1),u=t.remainedWidth,h=t.autoWidthCount,c=(u-s)/(h+(h-1)*l);c=Math.max(c,0),E(i,(function(t){var e=t.maxWidth,n=t.minWidth;if(t.width){i=t.width;e&&(i=Math.min(i,e)),n&&(i=Math.max(i,n)),t.width=i,u-=i+l*i,h--}else{var i=c;e&&ei&&(i=n),i!==c&&(t.width=i,u-=i+l*i,h--)}})),c=(u-s)/(h+(h-1)*l),c=Math.max(c,0);var p,d=0;E(i,(function(t,e){t.width||(t.width=c),p=t,d+=t.width*(1+l)})),p&&(d-=p.width*l);var f=-d/2;E(i,(function(t,i){n[e][i]=n[e][i]||{bandWidth:r,offset:f,width:t.width},f+=t.width*(1+l)}))})),n}function Ox(t,e){var n=kx(t,e),i=Lx(n);E(n,(function(t){var e=t.getData(),n=t.coordinateSystem.getBaseAxis(),r=Dx(t),o=i[Ax(n)][r],a=o.offset,s=o.width;e.setLayout({bandWidth:o.bandWidth,offset:a,size:s})}))}function Rx(t){return{seriesType:t,plan:xg(),reset:function(t){if(Nx(t)){var e=t.getData(),n=t.coordinateSystem,i=n.getBaseAxis(),r=n.getOtherAxis(i),o=e.getDimensionIndex(e.mapDimension(r.dim)),a=e.getDimensionIndex(e.mapDimension(i.dim)),s=t.get("showBackground",!0),l=e.mapDimension(r.dim),u=e.getCalculationInfo("stackResultDimension"),h=ox(e,l)&&!!e.getCalculationInfo("stackedOnSeries"),c=r.isHorizontal(),p=function(t,e){return e.toGlobalCoord(e.dataToCoord("log"===e.type?1:0))}(0,r),d=Ex(t),f=t.get("barMinHeight")||0,g=u&&e.getDimensionIndex(u),y=e.getLayout("size"),v=e.getLayout("offset");return{progress:function(t,e){for(var i,r=t.count,l=d&&Tx(3*r),u=d&&s&&Tx(3*r),m=d&&Tx(r),x=n.master.getRect(),_=c?x.width:x.height,b=e.getStore(),w=0;null!=(i=t.next());){var S=b.get(h?g:o,i),M=b.get(a,i),I=p,T=void 0;h&&(T=+S-b.get(o,i));var C=void 0,D=void 0,A=void 0,k=void 0;if(c){var L=n.dataToPoint([S,M]);if(h)I=n.dataToPoint([T,M])[0];C=I,D=L[1]+v,A=L[0]-I,k=y,Math.abs(A)0)for(var s=0;s=0;--s)if(l[u]){o=l[u];break}o=o||a.none}if(Y(o)){var h=null==t.level?0:t.level>=0?t.level:o.length+t.level;o=o[h=Math.min(h,o.length-1)]}}return Yc(new Date(t.value),o,r,i)}(t,e,n,this.getSetting("locale"),i)},e.prototype.getTicks=function(){var t=this._interval,e=this._extent,n=[];if(!t)return n;n.push({value:e[0],level:0});var i=this.getSetting("useUTC"),r=function(t,e,n,i){var r=1e4,o=Fc,a=0;function s(t,e,n,r,o,a,s){for(var l=new Date(e),u=e,h=l[r]();u1&&0===u&&o.unshift({value:o[0].value-p})}}for(u=0;u=i[0]&&v<=i[1]&&c++)}var m=(i[1]-i[0])/e;if(c>1.5*m&&p>m/1.5)break;if(u.push(g),c>m||t===o[d])break}h=[]}}0;var x=B(z(u,(function(t){return B(t,(function(t){return t.value>=i[0]&&t.value<=i[1]&&!t.notAdd}))})),(function(t){return t.length>0})),_=[],b=x.length-1;for(d=0;dn&&(this._approxInterval=n);var o=Vx.length,a=Math.min(function(t,e,n,i){for(;n>>1;t[r][1]16?16:t>7.5?7:t>3.5?4:t>1.5?2:1}function Fx(t){return(t/=2592e6)>6?6:t>3?3:t>2?2:1}function Gx(t){return(t/=Oc)>12?12:t>6?6:t>3.5?4:t>2?2:1}function Wx(t,e){return(t/=e?Pc:Lc)>30?30:t>20?20:t>15?15:t>10?10:t>5?5:t>2?2:1}function Hx(t){return no(t,!0)}function Yx(t,e,n){var i=new Date(t);switch(Wc(e)){case"year":case"month":i[ep(n)](0);case"day":i[np(n)](1);case"hour":i[ip(n)](0);case"minute":i[rp(n)](0);case"second":i[op(n)](0),i[ap(n)](0)}return i.getTime()}lx.registerClass(zx);var Ux=lx.prototype,Xx=Sx.prototype,Zx=Wr,jx=Math.floor,qx=Math.ceil,Kx=Math.pow,$x=Math.log,Jx=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.type="log",e.base=10,e._originalScale=new Sx,e._interval=0,e}return n(e,t),e.prototype.getTicks=function(t){var e=this._originalScale,n=this._extent,i=e.getExtent();return z(Xx.getTicks.call(this,t),(function(t){var e=t.value,r=Wr(Kx(this.base,e));return r=e===n[0]&&this._fixMin?t_(r,i[0]):r,{value:r=e===n[1]&&this._fixMax?t_(r,i[1]):r}}),this)},e.prototype.setExtent=function(t,e){var n=$x(this.base);t=$x(Math.max(0,t))/n,e=$x(Math.max(0,e))/n,Xx.setExtent.call(this,t,e)},e.prototype.getExtent=function(){var t=this.base,e=Ux.getExtent.call(this);e[0]=Kx(t,e[0]),e[1]=Kx(t,e[1]);var n=this._originalScale.getExtent();return this._fixMin&&(e[0]=t_(e[0],n[0])),this._fixMax&&(e[1]=t_(e[1],n[1])),e},e.prototype.unionExtent=function(t){this._originalScale.unionExtent(t);var e=this.base;t[0]=$x(t[0])/$x(e),t[1]=$x(t[1])/$x(e),Ux.unionExtent.call(this,t)},e.prototype.unionExtentFromData=function(t,e){this.unionExtent(t.getApproximateExtent(e))},e.prototype.calcNiceTicks=function(t){t=t||10;var e=this._extent,n=e[1]-e[0];if(!(n===1/0||n<=0)){var i=to(n);for(t/n*i<=.5&&(i*=10);!isNaN(i)&&Math.abs(i)<1&&Math.abs(i)>0;)i*=10;var r=[Wr(qx(e[0]/i)*i),Wr(jx(e[1]/i)*i)];this._interval=i,this._niceExtent=r}},e.prototype.calcNiceExtent=function(t){Xx.calcNiceExtent.call(this,t),this._fixMin=t.fixMin,this._fixMax=t.fixMax},e.prototype.parse=function(t){return t},e.prototype.contain=function(t){return vx(t=$x(t)/$x(this.base),this._extent)},e.prototype.normalize=function(t){return mx(t=$x(t)/$x(this.base),this._extent)},e.prototype.scale=function(t){return t=xx(t,this._extent),Kx(this.base,t)},e.type="log",e}(lx),Qx=Jx.prototype;function t_(t,e){return Zx(t,Yr(e))}Qx.getMinorTicks=Xx.getMinorTicks,Qx.getLabel=Xx.getLabel,lx.registerClass(Jx);var e_=function(){function t(t,e,n){this._prepareParams(t,e,n)}return t.prototype._prepareParams=function(t,e,n){n[1]0&&s>0&&!l&&(a=0),a<0&&s<0&&!u&&(s=0));var c=this._determinedMin,p=this._determinedMax;return null!=c&&(a=c,l=!0),null!=p&&(s=p,u=!0),{min:a,max:s,minFixed:l,maxFixed:u,isBlank:h}},t.prototype.modifyDataMinMax=function(t,e){this[i_[t]]=e},t.prototype.setDeterminedMinMax=function(t,e){var n=n_[t];this[n]=e},t.prototype.freeze=function(){this.frozen=!0},t}(),n_={min:"_determinedMin",max:"_determinedMax"},i_={min:"_dataMin",max:"_dataMax"};function r_(t,e,n){var i=t.rawExtentInfo;return i||(i=new e_(t,e,n),t.rawExtentInfo=i,i)}function o_(t,e){return null==e?null:nt(e)?NaN:t.parse(e)}function a_(t,e){var n=t.type,i=r_(t,e,t.getExtent()).calculate();t.setBlank(i.isBlank);var r=i.min,o=i.max,a=e.ecModel;if(a&&"time"===n){var s=kx("bar",a),l=!1;if(E(s,(function(t){l=l||t.getBaseAxis()===e.axis})),l){var u=Lx(s),h=function(t,e,n,i){var r=n.axis.getExtent(),o=r[1]-r[0],a=function(t,e,n){if(t&&e){var i=t[Ax(e)];return null!=i&&null!=n?i[Dx(n)]:i}}(i,n.axis);if(void 0===a)return{min:t,max:e};var s=1/0;E(a,(function(t){s=Math.min(t.offset,s)}));var l=-1/0;E(a,(function(t){l=Math.max(t.offset+t.width,l)})),s=Math.abs(s),l=Math.abs(l);var u=s+l,h=e-t,c=h/(1-(s+l)/o)-h;return{min:t-=c*(s/u),max:e+=c*(l/u)}}(r,o,e,u);r=h.min,o=h.max}}return{extent:[r,o],fixMin:i.minFixed,fixMax:i.maxFixed}}function s_(t,e){var n=e,i=a_(t,n),r=i.extent,o=n.get("splitNumber");t instanceof Jx&&(t.base=n.get("logBase"));var a=t.type,s=n.get("interval"),l="interval"===a||"time"===a;t.setExtent(r[0],r[1]),t.calcNiceExtent({splitNumber:o,fixMin:i.fixMin,fixMax:i.fixMax,minInterval:l?n.get("minInterval"):null,maxInterval:l?n.get("maxInterval"):null}),null!=s&&t.setInterval&&t.setInterval(s)}function l_(t,e){if(e=e||t.get("type"))switch(e){case"category":return new _x({ordinalMeta:t.getOrdinalMeta?t.getOrdinalMeta():t.getCategories(),extent:[1/0,-1/0]});case"time":return new zx({locale:t.ecModel.getLocaleModel(),useUTC:t.ecModel.get("useUTC")});default:return new(lx.getClass(e)||Sx)}}function u_(t){var e,n,i=t.getLabelModel().get("formatter"),r="category"===t.type?t.scale.getExtent()[0]:null;return"time"===t.scale.type?(n=i,function(e,i){return t.scale.getFormattedLabel(e,i,n)}):X(i)?function(e){return function(n){var i=t.scale.getLabel(n);return e.replace("{value}",null!=i?i:"")}}(i):U(i)?(e=i,function(n,i){return null!=r&&(i=n.value-r),e(h_(t,n),i,null!=n.level?{level:n.level}:null)}):function(e){return t.scale.getLabel(e)}}function h_(t,e){return"category"===t.type?t.scale.getLabel(e):e.value}function c_(t,e){var n=e*Math.PI/180,i=t.width,r=t.height,o=i*Math.abs(Math.cos(n))+Math.abs(r*Math.sin(n)),a=i*Math.abs(Math.sin(n))+Math.abs(r*Math.cos(n));return new Re(t.x,t.y,o,a)}function p_(t){var e=t.get("interval");return null==e?"auto":e}function d_(t){return"category"===t.type&&0===p_(t.getLabelModel())}function f_(t,e){var n={};return E(t.mapDimensionsAll(e),(function(e){n[ax(t,e)]=!0})),G(n)}var g_=function(){function t(){}return t.prototype.getNeedCrossZero=function(){return!this.option.scale},t.prototype.getCoordSysModel=function(){},t}();var y_={isDimensionStacked:ox,enableDataStack:rx,getStackedDimension:ax};var v_=Object.freeze({__proto__:null,createList:function(t){return sx(null,t)},getLayoutRect:wp,dataStack:y_,createScale:function(t,e){var n=e;e instanceof xc||(n=new xc(e));var i=l_(n);return i.setExtent(t[0],t[1]),s_(i,n),i},mixinAxisModelCommonMethods:function(t){R(t,g_)},getECData:js,createTextStyle:function(t,e){return $h(t,null,null,"normal"!==(e=e||{}).state)},createDimensions:function(t,e){return Qm(t,e).dimensions},createSymbol:Ry,enableHoverEmphasis:Vl});function m_(t,e){return Math.abs(t-e)<1e-8}function x_(t,e,n){var i=0,r=t[0];if(!r)return!1;for(var o=1;on&&(t=r,n=a)}if(t)return function(t){for(var e=0,n=0,i=0,r=t.length,o=t[r-1][0],a=t[r-1][1],s=0;s>1^-(1&s),l=l>>1^-(1&l),r=s+=r,o=l+=o,i.push([s/n,l/n])}return i}function k_(t,e){return z(B((t=function(t){if(!t.UTF8Encoding)return t;var e=t,n=e.UTF8Scale;return null==n&&(n=1024),E(e.features,(function(t){var e=t.geometry,i=e.encodeOffsets,r=e.coordinates;if(i)switch(e.type){case"LineString":e.coordinates=A_(r,i,n);break;case"Polygon":case"MultiLineString":D_(r,i,n);break;case"MultiPolygon":E(r,(function(t,e){return D_(t,i[e],n)}))}})),e.UTF8Encoding=!1,e}(t)).features,(function(t){return t.geometry&&t.properties&&t.geometry.coordinates.length>0})),(function(t){var n=t.properties,i=t.geometry,r=[];switch(i.type){case"Polygon":var o=i.coordinates;r.push(new M_(o[0],o.slice(1)));break;case"MultiPolygon":E(i.coordinates,(function(t){t[0]&&r.push(new M_(t[0],t.slice(1)))}));break;case"LineString":r.push(new I_([i.coordinates]));break;case"MultiLineString":r.push(new I_(i.coordinates))}var a=new T_(n[e||"name"],r,n.cp);return a.properties=n,a}))}var L_=Object.freeze({__proto__:null,linearMap:Fr,round:Wr,asc:Hr,getPrecision:Yr,getPrecisionSafe:Ur,getPixelPrecision:Xr,getPercentWithPrecision:function(t,e,n){return t[e]&&Zr(t,n)[e]||0},MAX_SAFE_INTEGER:qr,remRadian:Kr,isRadianAroundZero:$r,parseDate:Qr,quantity:to,quantityExponent:eo,nice:no,quantile:io,reformIntervals:ro,isNumeric:ao,numericToNumber:oo}),P_=Object.freeze({__proto__:null,parse:Qr,format:Yc}),O_=Object.freeze({__proto__:null,extendShape:xh,extendPath:bh,makePath:Mh,makeImage:Ih,mergePath:Ch,resizePath:Dh,createIcon:Vh,updateProps:uh,initProps:hh,getTransform:Lh,clipPointsByRect:Eh,clipRectByRect:zh,registerShape:wh,getShapeClass:Sh,Group:Pr,Image:Is,Text:Ns,Circle:gu,Ellipse:vu,Sector:Pu,Ring:Ru,Polygon:zu,Polyline:Bu,Rect:Ps,Line:Wu,BezierCurve:Xu,Arc:ju,IncrementalDisplayable:oh,CompoundPath:qu,LinearGradient:$u,RadialGradient:Ju,BoundingRect:Re}),R_=Object.freeze({__proto__:null,addCommas:sp,toCamelCase:lp,normalizeCssArray:up,encodeHTML:ee,formatTpl:dp,getTooltipMarker:fp,formatTime:function(t,e,n){"week"!==t&&"month"!==t&&"quarter"!==t&&"half-year"!==t&&"year"!==t||(t="MM-dd\nyyyy");var i=Qr(e),r=n?"getUTC":"get",o=i[r+"FullYear"](),a=i[r+"Month"]()+1,s=i[r+"Date"](),l=i[r+"Hours"](),u=i[r+"Minutes"](),h=i[r+"Seconds"](),c=i[r+"Milliseconds"]();return t=t.replace("MM",Gc(a,2)).replace("M",a).replace("yyyy",o).replace("yy",Gc(o%100+"",2)).replace("dd",Gc(s,2)).replace("d",s).replace("hh",Gc(l,2)).replace("h",l).replace("mm",Gc(u,2)).replace("m",u).replace("ss",Gc(h,2)).replace("s",h).replace("SSS",Gc(c,3))},capitalFirst:function(t){return t?t.charAt(0).toUpperCase()+t.substr(1):t},truncateText:na,getTextRect:function(t,e,n,i,r,o,a,s){return new Ns({style:{text:t,font:e,align:n,verticalAlign:i,padding:r,rich:o,overflow:a?"truncate":null,lineHeight:s}}).getBoundingRect()}}),N_=Object.freeze({__proto__:null,map:z,each:E,indexOf:P,inherits:O,reduce:V,filter:B,bind:W,curry:H,isArray:Y,isString:X,isObject:q,isFunction:U,extend:A,defaults:k,clone:T,merge:C}),E_=Do();function z_(t){return"category"===t.type?function(t){var e=t.getLabelModel(),n=B_(t,e);return!e.get("show")||t.scale.isBlank()?{labels:[],labelCategoryInterval:n.labelCategoryInterval}:n}(t):function(t){var e=t.scale.getTicks(),n=u_(t);return{labels:z(e,(function(e,i){return{level:e.level,formattedLabel:n(e,i),rawLabel:t.scale.getLabel(e),tickValue:e.value}}))}}(t)}function V_(t,e){return"category"===t.type?function(t,e){var n,i,r=F_(t,"ticks"),o=p_(e),a=G_(r,o);if(a)return a;e.get("show")&&!t.scale.isBlank()||(n=[]);if(U(o))n=Y_(t,o,!0);else if("auto"===o){var s=B_(t,t.getLabelModel());i=s.labelCategoryInterval,n=z(s.labels,(function(t){return t.tickValue}))}else n=H_(t,i=o,!0);return W_(r,o,{ticks:n,tickCategoryInterval:i})}(t,e):{ticks:z(t.scale.getTicks(),(function(t){return t.value}))}}function B_(t,e){var n,i,r=F_(t,"labels"),o=p_(e),a=G_(r,o);return a||(U(o)?n=Y_(t,o):(i="auto"===o?function(t){var e=E_(t).autoInterval;return null!=e?e:E_(t).autoInterval=t.calculateCategoryInterval()}(t):o,n=H_(t,i)),W_(r,o,{labels:n,labelCategoryInterval:i}))}function F_(t,e){return E_(t)[e]||(E_(t)[e]=[])}function G_(t,e){for(var n=0;n1&&h/l>2&&(u=Math.round(Math.ceil(u/l)*l));var c=d_(t),p=a.get("showMinLabel")||c,d=a.get("showMaxLabel")||c;p&&u!==o[0]&&g(o[0]);for(var f=u;f<=o[1];f+=l)g(f);function g(t){var e={value:t};s.push(n?t:{formattedLabel:i(e),rawLabel:r.getLabel(e),tickValue:t})}return d&&f-l!==o[1]&&g(o[1]),s}function Y_(t,e,n){var i=t.scale,r=u_(t),o=[];return E(i.getTicks(),(function(t){var a=i.getLabel(t),s=t.value;e(t.value,a)&&o.push(n?s:{formattedLabel:r(t),rawLabel:a,tickValue:s})})),o}var U_=[0,1],X_=function(){function t(t,e,n){this.onBand=!1,this.inverse=!1,this.dim=t,this.scale=e,this._extent=n||[0,0]}return t.prototype.contain=function(t){var e=this._extent,n=Math.min(e[0],e[1]),i=Math.max(e[0],e[1]);return t>=n&&t<=i},t.prototype.containData=function(t){return this.scale.contain(t)},t.prototype.getExtent=function(){return this._extent.slice()},t.prototype.getPixelPrecision=function(t){return Xr(t||this.scale.getExtent(),this._extent)},t.prototype.setExtent=function(t,e){var n=this._extent;n[0]=t,n[1]=e},t.prototype.dataToCoord=function(t,e){var n=this._extent,i=this.scale;return t=i.normalize(t),this.onBand&&"ordinal"===i.type&&Z_(n=n.slice(),i.count()),Fr(t,U_,n,e)},t.prototype.coordToData=function(t,e){var n=this._extent,i=this.scale;this.onBand&&"ordinal"===i.type&&Z_(n=n.slice(),i.count());var r=Fr(t,n,U_,e);return this.scale.scale(r)},t.prototype.pointToData=function(t,e){},t.prototype.getTicksCoords=function(t){var e=(t=t||{}).tickModel||this.getTickModel(),n=z(V_(this,e).ticks,(function(t){return{coord:this.dataToCoord("ordinal"===this.scale.type?this.scale.getRawOrdinalNumber(t):t),tickValue:t}}),this);return function(t,e,n,i){var r=e.length;if(!t.onBand||n||!r)return;var o,a,s=t.getExtent();if(1===r)e[0].coord=s[0],o=e[1]={coord:s[0]};else{var l=e[r-1].tickValue-e[0].tickValue,u=(e[r-1].coord-e[0].coord)/l;E(e,(function(t){t.coord-=u/2})),a=1+t.scale.getExtent()[1]-e[r-1].tickValue,o={coord:e[r-1].coord+u*a},e.push(o)}var h=s[0]>s[1];c(e[0].coord,s[0])&&(i?e[0].coord=s[0]:e.shift());i&&c(s[0],e[0].coord)&&e.unshift({coord:s[0]});c(s[1],o.coord)&&(i?o.coord=s[1]:e.pop());i&&c(o.coord,s[1])&&e.push({coord:s[1]});function c(t,e){return t=Wr(t),e=Wr(e),h?t>e:t0&&t<100||(t=5),z(this.scale.getMinorTicks(t),(function(t){return z(t,(function(t){return{coord:this.dataToCoord(t),tickValue:t}}),this)}),this)},t.prototype.getViewLabels=function(){return z_(this).labels},t.prototype.getLabelModel=function(){return this.model.getModel("axisLabel")},t.prototype.getTickModel=function(){return this.model.getModel("axisTick")},t.prototype.getBandWidth=function(){var t=this._extent,e=this.scale.getExtent(),n=e[1]-e[0]+(this.onBand?1:0);0===n&&(n=1);var i=Math.abs(t[1]-t[0]);return Math.abs(i)/n},t.prototype.calculateCategoryInterval=function(){return function(t){var e=function(t){var e=t.getLabelModel();return{axisRotate:t.getRotate?t.getRotate():t.isHorizontal&&!t.isHorizontal()?90:0,labelRotate:e.get("rotate")||0,font:e.getFont()}}(t),n=u_(t),i=(e.axisRotate-e.labelRotate)/180*Math.PI,r=t.scale,o=r.getExtent(),a=r.count();if(o[1]-o[0]<1)return 0;var s=1;a>40&&(s=Math.max(1,Math.floor(a/40)));for(var l=o[0],u=t.dataToCoord(l+1)-t.dataToCoord(l),h=Math.abs(u*Math.cos(i)),c=Math.abs(u*Math.sin(i)),p=0,d=0;l<=o[1];l+=s){var f,g,y=yr(n({value:l}),e.font,"center","top");f=1.3*y.width,g=1.3*y.height,p=Math.max(p,f,7),d=Math.max(d,g,7)}var v=p/h,m=d/c;isNaN(v)&&(v=1/0),isNaN(m)&&(m=1/0);var x=Math.max(0,Math.floor(Math.min(v,m))),_=E_(t.model),b=t.getExtent(),w=_.lastAutoInterval,S=_.lastTickCount;return null!=w&&null!=S&&Math.abs(w-x)<=1&&Math.abs(S-a)<=1&&w>x&&_.axisExtent0===b[0]&&_.axisExtent1===b[1]?x=w:(_.lastTickCount=a,_.lastAutoInterval=x,_.axisExtent0=b[0],_.axisExtent1=b[1]),x}(this)},t}();function Z_(t,e){var n=(t[1]-t[0])/e/2;t[0]+=n,t[1]-=n}var j_=2*Math.PI,q_=ts.CMD,K_=["top","right","bottom","left"];function $_(t,e,n,i,r){var o=n.width,a=n.height;switch(t){case"top":i.set(n.x+o/2,n.y-e),r.set(0,-1);break;case"bottom":i.set(n.x+o/2,n.y+a+e),r.set(0,1);break;case"left":i.set(n.x-e,n.y+a/2),r.set(-1,0);break;case"right":i.set(n.x+o+e,n.y+a/2),r.set(1,0)}}function J_(t,e,n,i,r,o,a,s,l){a-=t,s-=e;var u=Math.sqrt(a*a+s*s),h=(a/=u)*n+t,c=(s/=u)*n+e;if(Math.abs(i-r)%j_<1e-4)return l[0]=h,l[1]=c,u-n;if(o){var p=i;i=os(r),r=os(p)}else i=os(i),r=os(r);i>r&&(r+=j_);var d=Math.atan2(s,a);if(d<0&&(d+=j_),d>=i&&d<=r||d+j_>=i&&d+j_<=r)return l[0]=h,l[1]=c,u-n;var f=n*Math.cos(i)+t,g=n*Math.sin(i)+e,y=n*Math.cos(r)+t,v=n*Math.sin(r)+e,m=(f-a)*(f-a)+(g-s)*(g-s),x=(y-a)*(y-a)+(v-s)*(v-s);return m0){e=e/180*Math.PI,rb.fromArray(t[0]),ob.fromArray(t[1]),ab.fromArray(t[2]),Ie.sub(sb,rb,ob),Ie.sub(lb,ab,ob);var n=sb.len(),i=lb.len();if(!(n<.001||i<.001)){sb.scale(1/n),lb.scale(1/i);var r=sb.dot(lb);if(Math.cos(e)1&&Ie.copy(cb,ab),cb.toArray(t[1])}}}}function db(t,e,n){if(n<=180&&n>0){n=n/180*Math.PI,rb.fromArray(t[0]),ob.fromArray(t[1]),ab.fromArray(t[2]),Ie.sub(sb,ob,rb),Ie.sub(lb,ab,ob);var i=sb.len(),r=lb.len();if(!(i<.001||r<.001))if(sb.scale(1/i),lb.scale(1/r),sb.dot(e)=a)Ie.copy(cb,ab);else{cb.scaleAndAdd(lb,o/Math.tan(Math.PI/2-s));var l=ab.x!==ob.x?(cb.x-ob.x)/(ab.x-ob.x):(cb.y-ob.y)/(ab.y-ob.y);if(isNaN(l))return;l<0?Ie.copy(cb,ob):l>1&&Ie.copy(cb,ab)}cb.toArray(t[1])}}}function fb(t,e,n,i){var r="normal"===n,o=r?t:t.ensureState(n);o.ignore=e;var a=i.get("smooth");a&&!0===a&&(a=.3),o.shape=o.shape||{},a>0&&(o.shape.smooth=a);var s=i.getModel("lineStyle").getLineStyle();r?t.useStyle(s):o.style=s}function gb(t,e){var n=e.smooth,i=e.points;if(i)if(t.moveTo(i[0][0],i[0][1]),n>0&&i.length>=3){var r=Et(i[0],i[1]),o=Et(i[1],i[2]);if(!r||!o)return t.lineTo(i[1][0],i[1][1]),void t.lineTo(i[2][0],i[2][1]);var a=Math.min(r,o)*n,s=Bt([],i[1],i[0],a/r),l=Bt([],i[1],i[2],a/o),u=Bt([],s,l,.5);t.bezierCurveTo(s[0],s[1],s[0],s[1],u[0],u[1]),t.bezierCurveTo(l[0],l[1],l[0],l[1],i[2][0],i[2][1])}else for(var h=1;h0&&o&&_(-h/a,0,a);var f,g,y=t[0],v=t[a-1];return m(),f<0&&b(-f,.8),g<0&&b(g,.8),m(),x(f,g,1),x(g,f,-1),m(),f<0&&w(-f),g<0&&w(g),u}function m(){f=y.rect[e]-i,g=r-v.rect[e]-v.rect[n]}function x(t,e,n){if(t<0){var i=Math.min(e,-t);if(i>0){_(i*n,0,a);var r=i+t;r<0&&b(-r*n,1)}else b(-t*n,1)}}function _(n,i,r){0!==n&&(u=!0);for(var o=i;o0)for(l=0;l0;l--){_(-(o[l-1]*c),l,a)}}}function w(t){var e=t<0?-1:1;t=Math.abs(t);for(var n=Math.ceil(t/(a-1)),i=0;i0?_(n,0,i+1):_(-n,a-i-1,a),(t-=n)<=0)return}}function _b(t,e,n,i){return xb(t,"y","height",e,n,i)}function bb(t){var e=[];t.sort((function(t,e){return e.priority-t.priority}));var n=new Re(0,0,0,0);function i(t){if(!t.ignore){var e=t.ensureState("emphasis");null==e.ignore&&(e.ignore=!1)}t.ignore=!0}for(var r=0;r=0&&n.attr(d.oldLayoutSelect),P(u,"emphasis")>=0&&n.attr(d.oldLayoutEmphasis)),uh(n,s,e,a)}else if(n.attr(s),!rc(n).valueAnimation){var h=rt(n.style.opacity,1);n.style.opacity=0,hh(n,{style:{opacity:h}},e,a)}if(d.oldLayout=s,n.states.select){var c=d.oldLayoutSelect={};Db(c,s,Ab),Db(c,n.states.select,Ab)}if(n.states.emphasis){var p=d.oldLayoutEmphasis={};Db(p,s,Ab),Db(p,n.states.emphasis,Ab)}ac(n,a,l,e,e)}if(i&&!i.ignore&&!i.invisible){r=(d=Cb(i)).oldLayout;var d,f={points:i.shape.points};r?(i.attr({shape:r}),uh(i,{shape:f},e)):(i.setShape(f),i.style.strokePercent=0,hh(i,{style:{strokePercent:1}},e)),d.oldLayout=f}},t}(),Lb=Do();var Pb=Math.sin,Ob=Math.cos,Rb=Math.PI,Nb=2*Math.PI,Eb=180/Rb,zb=function(){function t(){}return t.prototype.reset=function(t){this._start=!0,this._d=[],this._str="",this._p=Math.pow(10,t||4)},t.prototype.moveTo=function(t,e){this._add("M",t,e)},t.prototype.lineTo=function(t,e){this._add("L",t,e)},t.prototype.bezierCurveTo=function(t,e,n,i,r,o){this._add("C",t,e,n,i,r,o)},t.prototype.quadraticCurveTo=function(t,e,n,i){this._add("Q",t,e,n,i)},t.prototype.arc=function(t,e,n,i,r,o){this.ellipse(t,e,n,n,0,i,r,o)},t.prototype.ellipse=function(t,e,n,i,r,o,a,s){var l=a-o,u=!s,h=Math.abs(l),c=si(h-Nb)||(u?l>=Nb:-l>=Nb),p=l>0?l%Nb:l%Nb+Nb,d=!1;d=!!c||!si(h)&&p>=Rb==!!u;var f=t+n*Ob(o),g=e+i*Pb(o);this._start&&this._add("M",f,g);var y=Math.round(r*Eb);if(c){var v=1/this._p,m=(u?1:-1)*(Nb-v);this._add("A",n,i,y,1,+u,t+n*Ob(o+m),e+i*Pb(o+m)),v>.01&&this._add("A",n,i,y,0,+u,f,g)}else{var x=t+n*Ob(a),_=e+i*Pb(a);this._add("A",n,i,y,+d,+u,x,_)}},t.prototype.rect=function(t,e,n,i){this._add("M",t,e),this._add("l",n,0),this._add("l",0,i),this._add("l",-n,0),this._add("Z")},t.prototype.closePath=function(){this._d.length>0&&this._add("Z")},t.prototype._add=function(t,e,n,i,r,o,a,s,l){for(var u=[],h=this._p,c=1;c"}(r,e.attrs)+ee(e.text)+(i?""+n+z(i,(function(e){return t(e)})).join(n)+n:"")+("")}(t)}function jb(t){return{zrId:t,shadowCache:{},patternCache:{},gradientCache:{},clipPathCache:{},defs:{},cssNodes:{},cssAnims:{},cssClassIdx:0,cssAnimIdx:0,shadowIdx:0,gradientIdx:0,patternIdx:0,clipPathIdx:0}}function qb(t,e,n,i){return Xb("svg","root",{width:t,height:e,xmlns:Hb,"xmlns:xlink":Yb,version:"1.1",baseProfile:"full",viewBox:!!i&&"0 0 "+t+" "+e},n)}var Kb={cubicIn:"0.32,0,0.67,0",cubicOut:"0.33,1,0.68,1",cubicInOut:"0.65,0,0.35,1",quadraticIn:"0.11,0,0.5,0",quadraticOut:"0.5,1,0.89,1",quadraticInOut:"0.45,0,0.55,1",quarticIn:"0.5,0,0.75,0",quarticOut:"0.25,1,0.5,1",quarticInOut:"0.76,0,0.24,1",quinticIn:"0.64,0,0.78,0",quinticOut:"0.22,1,0.36,1",quinticInOut:"0.83,0,0.17,1",sinusoidalIn:"0.12,0,0.39,0",sinusoidalOut:"0.61,1,0.88,1",sinusoidalInOut:"0.37,0,0.63,1",exponentialIn:"0.7,0,0.84,0",exponentialOut:"0.16,1,0.3,1",exponentialInOut:"0.87,0,0.13,1",circularIn:"0.55,0,1,0.45",circularOut:"0,0.55,0.45,1",circularInOut:"0.85,0,0.15,1"},$b="transform-origin";function Jb(t,e,n){var i=A({},t.shape);A(i,e),t.buildPath(n,i);var r=new zb;return r.reset(gi(t)),n.rebuildPath(r,1),r.generateStr(),r.getStr()}function Qb(t,e){var n=e.originX,i=e.originY;(n||i)&&(t[$b]=n+"px "+i+"px")}var tw={fill:"fill",opacity:"opacity",lineWidth:"stroke-width",lineDashOffset:"stroke-dashoffset"};function ew(t,e){var n=e.zrId+"-ani-"+e.cssAnimIdx++;return e.cssAnims[n]=t,n}function nw(t){return X(t)?Kb[t]?"cubic-bezier("+Kb[t]+")":An(t)?t:"":""}function iw(t,e,n,i){var r=t.animators,o=r.length,a=[];if(t instanceof qu){var s=function(t,e,n){var i,r,o=t.shape.paths,a={};if(E(o,(function(t){var e=jb(n.zrId);e.animation=!0,iw(t,{},e,!0);var o=e.cssAnims,s=e.cssNodes,l=G(o),u=l.length;if(u){var h=o[r=l[u-1]];for(var c in h){var p=h[c];a[c]=a[c]||{d:""},a[c].d+=p.d||""}for(var d in s){var f=s[d].animation;f.indexOf(r)>=0&&(i=f)}}})),i){e.d=!1;var s=ew(a,n);return i.replace(r,s)}}(t,e,n);if(s)a.push(s);else if(!o)return}else if(!o)return;for(var l={},u=0;u0})).length)return ew(h,n)+" "+r[0]+" both"}for(var y in l){(s=g(l[y]))&&a.push(s)}if(a.length){var v=n.zrId+"-cls-"+n.cssClassIdx++;n.cssNodes["."+v]={animation:a.join(",")},e.class=v}}var rw=Math.round;function ow(t){return t&&X(t.src)}function aw(t){return t&&U(t.toDataURL)}function sw(t,e,n,i){Wb((function(r,o){var a="fill"===r||"stroke"===r;a&&function(t){return t&&("linear"===t.type||"radial"===t.type)}(o)?function(t,e,n,i){var r,o=t[n],a={gradientUnits:o.global?"userSpaceOnUse":"objectBoundingBox"};if(pi(o))r="linearGradient",a.x1=o.x,a.y1=o.y,a.x2=o.x2,a.y2=o.y2;else{if(!di(o))return void 0;r="radialGradient",a.cx=rt(o.x,.5),a.cy=rt(o.y,.5),a.r=rt(o.r,.5)}for(var s=o.colorStops,l=[],u=0,h=s.length;ul?Lw(t,null==n[c+1]?null:n[c+1].elm,n,s,c):Pw(t,e,a,l))}(n,i,r):Cw(r)?(Cw(t.text)&&Mw(n,""),Lw(n,null,r,0,r.length-1)):Cw(i)?Pw(n,i,0,i.length-1):Cw(t.text)&&Mw(n,""):t.text!==e.text&&(Cw(i)&&Pw(n,i,0,i.length-1),Mw(n,e.text)))}var Nw=0,Ew=function(){function t(t,e,n){if(this.type="svg",this.refreshHover=zw("refreshHover"),this.configLayer=zw("configLayer"),this.storage=e,this._opts=n=A({},n),this.root=t,this._id="zr"+Nw++,this._oldVNode=qb(n.width,n.height),t&&!n.ssr){var i=this._viewport=document.createElement("div");i.style.cssText="position:relative;overflow:hidden";var r=this._svgDom=this._oldVNode.elm=Ub("svg");Ow(null,this._oldVNode),i.appendChild(r),t.appendChild(i)}this.resize(n.width,n.height)}return t.prototype.getType=function(){return this.type},t.prototype.getViewportRoot=function(){return this._viewport},t.prototype.getViewportRootOffset=function(){var t=this.getViewportRoot();if(t)return{offsetLeft:t.offsetLeft||0,offsetTop:t.offsetTop||0}},t.prototype.getSvgDom=function(){return this._svgDom},t.prototype.refresh=function(){if(this.root){var t=this.renderToVNode({willUpdate:!0});t.attrs.style="position:absolute;left:0;top:0;user-select:none",function(t,e){if(Aw(t,e))Rw(t,e);else{var n=t.elm,i=ww(n);kw(e),null!==i&&(xw(i,e.elm,Sw(n)),Pw(i,[t],0,0))}}(this._oldVNode,t),this._oldVNode=t}},t.prototype.renderOneToVNode=function(t){return yw(t,jb(this._id))},t.prototype.renderToVNode=function(t){t=t||{};var e=this.storage.getDisplayList(!0),n=this._backgroundColor,i=this._width,r=this._height,o=jb(this._id);o.animation=t.animation,o.willUpdate=t.willUpdate,o.compress=t.compress;var a=[];if(n&&"none"!==n){var s=oi(n),l=s.color,u=s.opacity;this._bgVNode=Xb("rect","bg",{width:i,height:r,x:"0",y:"0",id:"0",fill:l,"fill-opacity":u}),a.push(this._bgVNode)}else this._bgVNode=null;var h=t.compress?null:this._mainVNode=Xb("g","main",{},[]);this._paintList(e,o,h?h.children:a),h&&a.push(h);var c=z(G(o.defs),(function(t){return o.defs[t]}));if(c.length&&a.push(Xb("defs","defs",{},c)),t.animation){var p=function(t,e,n){var i=(n=n||{}).newline?"\n":"",r=" {"+i,o=i+"}",a=z(G(t),(function(e){return e+r+z(G(t[e]),(function(n){return n+":"+t[e][n]+";"})).join(i)+o})).join(i),s=z(G(e),(function(t){return"@keyframes "+t+r+z(G(e[t]),(function(n){return n+r+z(G(e[t][n]),(function(i){var r=e[t][n][i];return"d"===i&&(r='path("'+r+'")'),i+":"+r+";"})).join(i)+o})).join(i)+o})).join(i);return a||s?[""].join(i):""}(o.cssNodes,o.cssAnims,{newline:!0});if(p){var d=Xb("style","stl",{},[],p);a.push(d)}}return qb(i,r,a,t.useViewBox)},t.prototype.renderToString=function(t){return t=t||{},Zb(this.renderToVNode({animation:rt(t.cssAnimation,!0),willUpdate:!1,compress:!0,useViewBox:rt(t.useViewBox,!0)}),{newline:!0})},t.prototype.setBackgroundColor=function(t){this._backgroundColor=t;var e=this._bgVNode;if(e&&e.elm){var n=oi(t),i=n.color,r=n.opacity;e.elm.setAttribute("fill",i),r<1&&e.elm.setAttribute("fill-opacity",r)}},t.prototype.getSvgRoot=function(){return this._mainVNode&&this._mainVNode.elm},t.prototype._paintList=function(t,e,n){for(var i,r,o=t.length,a=[],s=0,l=0,u=0;u=0&&(!c||!r||c[f]!==r[f]);f--);for(var g=d-1;g>f;g--)i=a[--s-1];for(var y=f+1;y=a)}}for(var h=this.__startIndex;h15)break}n.prevElClipPaths&&u.restore()};if(p)if(0===p.length)s=l.__endIndex;else for(var _=d.dpr,b=0;b0&&t>i[0]){for(s=0;st);s++);a=n[i[s]]}if(i.splice(s+1,0,t),n[t]=e,!e.virtual)if(a){var l=a.dom;l.nextSibling?o.insertBefore(e.dom,l.nextSibling):o.appendChild(e.dom)}else o.firstChild?o.insertBefore(e.dom,o.firstChild):o.appendChild(e.dom);e.__painter=this}},t.prototype.eachLayer=function(t,e){for(var n=this._zlevelList,i=0;i0?Ww:0),this._needsManuallyCompositing),u.__builtin__||I("ZLevel "+l+" has been used by unkown layer "+u.id),u!==o&&(u.__used=!0,u.__startIndex!==r&&(u.__dirty=!0),u.__startIndex=r,u.incremental?u.__drawIndex=-1:u.__drawIndex=r,e(r),o=u),1&s.__dirty&&!s.__inHover&&(u.__dirty=!0,u.incremental&&u.__drawIndex<0&&(u.__drawIndex=r))}e(r),this.eachBuiltinLayer((function(t,e){!t.__used&&t.getElementCount()>0&&(t.__dirty=!0,t.__startIndex=t.__endIndex=t.__drawIndex=0),t.__dirty&&t.__drawIndex<0&&(t.__drawIndex=t.__startIndex)}))},t.prototype.clear=function(){return this.eachBuiltinLayer(this._clearLayer),this},t.prototype._clearLayer=function(t){t.clear()},t.prototype.setBackgroundColor=function(t){this._backgroundColor=t,E(this._layers,(function(t){t.setUnpainted()}))},t.prototype.configLayer=function(t,e){if(e){var n=this._layerConfig;n[t]?C(n[t],e,!0):n[t]=e;for(var i=0;i-1&&(s.style.stroke=s.style.fill,s.style.fill="#fff",s.style.lineWidth=2),e},e.type="series.line",e.dependencies=["grid","polar"],e.defaultOption={z:3,coordinateSystem:"cartesian2d",legendHoverLink:!0,clip:!0,label:{position:"top"},endLabel:{show:!1,valueAnimation:!0,distance:8},lineStyle:{width:2,type:"solid"},emphasis:{scale:!0},step:!1,smooth:!1,smoothMonotone:null,symbol:"emptyCircle",symbolSize:4,symbolRotate:null,showSymbol:!0,showAllSymbol:"auto",connectNulls:!1,sampling:"none",animationEasing:"linear",progressive:0,hoverLayerThreshold:1/0,universalTransition:{divideShape:"clone"},triggerLineEvent:!1},e}(hg);function Uw(t,e){var n=t.mapDimensionsAll("defaultedLabel"),i=n.length;if(1===i){var r=uf(t,e,n[0]);return null!=r?r+"":null}if(i){for(var o=[],a=0;a=0&&i.push(e[o])}return i.join(" ")}var Zw=function(t){function e(e,n,i,r){var o=t.call(this)||this;return o.updateData(e,n,i,r),o}return n(e,t),e.prototype._createSymbol=function(t,e,n,i,r){this.removeAll();var o=Ry(t,-1,-1,2,2,null,r);o.attr({z2:100,culling:!0,scaleX:i[0]/2,scaleY:i[1]/2}),o.drift=jw,this._symbolType=t,this.add(o)},e.prototype.stopSymbolAnimation=function(t){this.childAt(0).stopAnimation(null,t)},e.prototype.getSymbolType=function(){return this._symbolType},e.prototype.getSymbolPath=function(){return this.childAt(0)},e.prototype.highlight=function(){Il(this.childAt(0))},e.prototype.downplay=function(){Tl(this.childAt(0))},e.prototype.setZ=function(t,e){var n=this.childAt(0);n.zlevel=t,n.z=e},e.prototype.setDraggable=function(t,e){var n=this.childAt(0);n.draggable=t,n.cursor=!e&&t?"move":n.cursor},e.prototype.updateData=function(t,n,i,r){this.silent=!1;var o=t.getItemVisual(n,"symbol")||"circle",a=t.hostModel,s=e.getSymbolSize(t,n),l=o!==this._symbolType,u=r&&r.disableAnimation;if(l){var h=t.getItemVisual(n,"symbolKeepAspect");this._createSymbol(o,t,n,s,h)}else{(p=this.childAt(0)).silent=!1;var c={scaleX:s[0]/2,scaleY:s[1]/2};u?p.attr(c):uh(p,c,a,n),gh(p)}if(this._updateCommon(t,n,s,i,r),l){var p=this.childAt(0);if(!u){c={scaleX:this._sizeX,scaleY:this._sizeY,style:{opacity:p.style.opacity}};p.scaleX=p.scaleY=0,p.style.opacity=0,hh(p,c,a,n)}}u&&this.childAt(0).stopAnimation("leave")},e.prototype._updateCommon=function(t,e,n,i,r){var o,a,s,l,u,h,c,p,d,f=this.childAt(0),g=t.hostModel;if(i&&(o=i.emphasisItemStyle,a=i.blurItemStyle,s=i.selectItemStyle,l=i.focus,u=i.blurScope,c=i.labelStatesModels,p=i.hoverScale,d=i.cursorStyle,h=i.emphasisDisabled),!i||t.hasItemOption){var y=i&&i.itemModel?i.itemModel:t.getItemModel(e),v=y.getModel("emphasis");o=v.getModel("itemStyle").getItemStyle(),s=y.getModel(["select","itemStyle"]).getItemStyle(),a=y.getModel(["blur","itemStyle"]).getItemStyle(),l=v.get("focus"),u=v.get("blurScope"),h=v.get("disabled"),c=Kh(y),p=v.getShallow("scale"),d=y.getShallow("cursor")}var m=t.getItemVisual(e,"symbolRotate");f.attr("rotation",(m||0)*Math.PI/180||0);var x=Ey(t.getItemVisual(e,"symbolOffset"),n);x&&(f.x=x[0],f.y=x[1]),d&&f.attr("cursor",d);var _=t.getItemVisual(e,"style"),b=_.fill;if(f instanceof Is){var w=f.style;f.useStyle(A({image:w.image,x:w.x,y:w.y,width:w.width,height:w.height},_))}else f.__isEmptyBrush?f.useStyle(A({},_)):f.useStyle(_),f.style.decal=null,f.setColor(b,r&&r.symbolInnerColor),f.style.strokeNoScale=!0;var S=t.getItemVisual(e,"liftZ"),M=this._z2;null!=S?null==M&&(this._z2=f.z2,f.z2+=S):null!=M&&(f.z2=M,this._z2=null);var I=r&&r.useNameLabel;qh(f,c,{labelFetcher:g,labelDataIndex:e,defaultText:function(e){return I?t.getName(e):Uw(t,e)},inheritColor:b,defaultOpacity:_.opacity}),this._sizeX=n[0]/2,this._sizeY=n[1]/2;var T=f.ensureState("emphasis");T.style=o,f.ensureState("select").style=s,f.ensureState("blur").style=a;var C=null==p||!0===p?Math.max(1.1,3/this._sizeY):isFinite(p)&&p>0?+p:1;T.scaleX=this._sizeX*C,T.scaleY=this._sizeY*C,this.setSymbolScale(1),Bl(this,l,u,h)},e.prototype.setSymbolScale=function(t){this.scaleX=this.scaleY=t},e.prototype.fadeOut=function(t,e,n){var i=this.childAt(0),r=js(this).dataIndex,o=n&&n.animation;if(this.silent=i.silent=!0,n&&n.fadeLabel){var a=i.getTextContent();a&&ph(a,{style:{opacity:0}},e,{dataIndex:r,removeOpt:o,cb:function(){i.removeTextContent()}})}else i.removeTextContent();ph(i,{style:{opacity:0},scaleX:0,scaleY:0},e,{dataIndex:r,cb:t,removeOpt:o})},e.getSymbolSize=function(t,e){return Ny(t.getItemVisual(e,"symbolSize"))},e}(Pr);function jw(t,e){this.parent.drift(t,e)}function qw(t,e,n,i){return e&&!isNaN(e[0])&&!isNaN(e[1])&&!(i.isIgnore&&i.isIgnore(n))&&!(i.clipShape&&!i.clipShape.contain(e[0],e[1]))&&"none"!==t.getItemVisual(n,"symbol")}function Kw(t){return null==t||q(t)||(t={isIgnore:t}),t||{}}function $w(t){var e=t.hostModel,n=e.getModel("emphasis");return{emphasisItemStyle:n.getModel("itemStyle").getItemStyle(),blurItemStyle:e.getModel(["blur","itemStyle"]).getItemStyle(),selectItemStyle:e.getModel(["select","itemStyle"]).getItemStyle(),focus:n.get("focus"),blurScope:n.get("blurScope"),emphasisDisabled:n.get("disabled"),hoverScale:n.get("scale"),labelStatesModels:Kh(e),cursorStyle:e.get("cursor")}}var Jw=function(){function t(t){this.group=new Pr,this._SymbolCtor=t||Zw}return t.prototype.updateData=function(t,e){this._progressiveEls=null,e=Kw(e);var n=this.group,i=t.hostModel,r=this._data,o=this._SymbolCtor,a=e.disableAnimation,s=$w(t),l={disableAnimation:a},u=e.getSymbolPoint||function(e){return t.getItemLayout(e)};r||n.removeAll(),t.diff(r).add((function(i){var r=u(i);if(qw(t,r,i,e)){var a=new o(t,i,s,l);a.setPosition(r),t.setItemGraphicEl(i,a),n.add(a)}})).update((function(h,c){var p=r.getItemGraphicEl(c),d=u(h);if(qw(t,d,h,e)){var f=t.getItemVisual(h,"symbol")||"circle",g=p&&p.getSymbolType&&p.getSymbolType();if(!p||g&&g!==f)n.remove(p),(p=new o(t,h,s,l)).setPosition(d);else{p.updateData(t,h,s,l);var y={x:d[0],y:d[1]};a?p.attr(y):uh(p,y,i)}n.add(p),t.setItemGraphicEl(h,p)}else n.remove(p)})).remove((function(t){var e=r.getItemGraphicEl(t);e&&e.fadeOut((function(){n.remove(e)}),i)})).execute(),this._getSymbolPoint=u,this._data=t},t.prototype.updateLayout=function(){var t=this,e=this._data;e&&e.eachItemGraphicEl((function(e,n){var i=t._getSymbolPoint(n);e.setPosition(i),e.markRedraw()}))},t.prototype.incrementalPrepareUpdate=function(t){this._seriesScope=$w(t),this._data=null,this.group.removeAll()},t.prototype.incrementalUpdate=function(t,e,n){function i(t){t.isGroup||(t.incremental=!0,t.ensureState("emphasis").hoverLayer=!0)}this._progressiveEls=[],n=Kw(n);for(var r=t.start;r0?n=i[0]:i[1]<0&&(n=i[1]);return n}(r,n),a=i.dim,s=r.dim,l=e.mapDimension(s),u=e.mapDimension(a),h="x"===s||"radius"===s?1:0,c=z(t.dimensions,(function(t){return e.mapDimension(t)})),p=!1,d=e.getCalculationInfo("stackResultDimension");return ox(e,c[0])&&(p=!0,c[0]=d),ox(e,c[1])&&(p=!0,c[1]=d),{dataDimsForPoint:c,valueStart:o,valueAxisDim:s,baseAxisDim:a,stacked:!!p,valueDim:l,baseDim:u,baseDataOffset:h,stackedOverDimension:e.getCalculationInfo("stackedOverDimension")}}function tS(t,e,n,i){var r=NaN;t.stacked&&(r=n.get(n.getCalculationInfo("stackedOverDimension"),i)),isNaN(r)&&(r=t.valueStart);var o=t.baseDataOffset,a=[];return a[o]=n.get(t.baseDim,i),a[1-o]=r,e.dataToPoint(a)}var eS=Math.min,nS=Math.max;function iS(t,e){return isNaN(t)||isNaN(e)}function rS(t,e,n,i,r,o,a,s,l){for(var u,h,c,p,d,f,g=n,y=0;y=r||g<0)break;if(iS(v,m)){if(l){g+=o;continue}break}if(g===n)t[o>0?"moveTo":"lineTo"](v,m),c=v,p=m;else{var x=v-u,_=m-h;if(x*x+_*_<.5){g+=o;continue}if(a>0){for(var b=g+o,w=e[2*b],S=e[2*b+1];w===v&&S===m&&y=i||iS(w,S))d=v,f=m;else{T=w-u,C=S-h;var k=v-u,L=w-v,P=m-h,O=S-m,R=void 0,N=void 0;if("x"===s){var E=T>0?1:-1;d=v-E*(R=Math.abs(k))*a,f=m,D=v+E*(N=Math.abs(L))*a,A=m}else if("y"===s){var z=C>0?1:-1;d=v,f=m-z*(R=Math.abs(P))*a,D=v,A=m+z*(N=Math.abs(O))*a}else R=Math.sqrt(k*k+P*P),d=v-T*a*(1-(I=(N=Math.sqrt(L*L+O*O))/(N+R))),f=m-C*a*(1-I),A=m+C*a*I,D=eS(D=v+T*a*I,nS(w,v)),A=eS(A,nS(S,m)),D=nS(D,eS(w,v)),f=m-(C=(A=nS(A,eS(S,m)))-m)*R/N,d=eS(d=v-(T=D-v)*R/N,nS(u,v)),f=eS(f,nS(h,m)),D=v+(T=v-(d=nS(d,eS(u,v))))*N/R,A=m+(C=m-(f=nS(f,eS(h,m))))*N/R}t.bezierCurveTo(c,p,d,f,v,m),c=D,p=A}else t.lineTo(v,m)}u=v,h=m,g+=o}return y}var oS=function(){this.smooth=0,this.smoothConstraint=!0},aS=function(t){function e(e){var n=t.call(this,e)||this;return n.type="ec-polyline",n}return n(e,t),e.prototype.getDefaultStyle=function(){return{stroke:"#000",fill:null}},e.prototype.getDefaultShape=function(){return new oS},e.prototype.buildPath=function(t,e){var n=e.points,i=0,r=n.length/2;if(e.connectNulls){for(;r>0&&iS(n[2*r-2],n[2*r-1]);r--);for(;i=0){var y=a?(h-i)*g+i:(u-n)*g+n;return a?[t,y]:[y,t]}n=u,i=h;break;case o.C:u=r[l++],h=r[l++],c=r[l++],p=r[l++],d=r[l++],f=r[l++];var v=a?vn(n,u,c,d,t,s):vn(i,h,p,f,t,s);if(v>0)for(var m=0;m=0){y=a?gn(i,h,p,f,x):gn(n,u,c,d,x);return a?[t,y]:[y,t]}}n=d,i=f}}},e}(_s),sS=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e}(oS),lS=function(t){function e(e){var n=t.call(this,e)||this;return n.type="ec-polygon",n}return n(e,t),e.prototype.getDefaultShape=function(){return new sS},e.prototype.buildPath=function(t,e){var n=e.points,i=e.stackedOnPoints,r=0,o=n.length/2,a=e.smoothMonotone;if(e.connectNulls){for(;o>0&&iS(n[2*o-2],n[2*o-1]);o--);for(;r=0;a--){var s=t.getDimensionInfo(i[a].dimension);if("x"===(r=s&&s.coordDim)||"y"===r){o=i[a];break}}if(o){var l=e.getAxis(r),u=z(o.stops,(function(t){return{coord:l.toGlobalCoord(l.dataToCoord(t.value)),color:t.color}})),h=u.length,c=o.outerColors.slice();h&&u[0].coord>u[h-1].coord&&(u.reverse(),c.reverse());var p=function(t,e){var n,i,r=[],o=t.length;function a(t,e,n){var i=t.coord;return{coord:n,color:$n((n-i)/(e.coord-i),[t.color,e.color])}}for(var s=0;se){i?r.push(a(i,l,e)):n&&r.push(a(n,l,0),a(n,l,e));break}n&&(r.push(a(n,l,0)),n=null),r.push(l),i=l}}return r}(u,"x"===r?n.getWidth():n.getHeight()),d=p.length;if(!d&&h)return u[0].coord<0?c[1]?c[1]:u[h-1].color:c[0]?c[0]:u[0].color;var f=p[0].coord-10,g=p[d-1].coord+10,y=g-f;if(y<.001)return"transparent";E(p,(function(t){t.offset=(t.coord-f)/y})),p.push({offset:d?p[d-1].offset:.5,color:c[1]||"transparent"}),p.unshift({offset:d?p[0].offset:.5,color:c[0]||"transparent"});var v=new $u(0,0,0,0,p,!0);return v[r]=f,v[r+"2"]=g,v}}}function xS(t,e,n){var i=t.get("showAllSymbol"),r="auto"===i;if(!i||r){var o=n.getAxesByScale("ordinal")[0];if(o&&(!r||!function(t,e){var n=t.getExtent(),i=Math.abs(n[1]-n[0])/t.scale.count();isNaN(i)&&(i=0);for(var r=e.count(),o=Math.max(1,Math.round(r/5)),a=0;ai)return!1;return!0}(o,e))){var a=e.mapDimension(o.dim),s={};return E(o.getViewLabels(),(function(t){var e=o.scale.getRawOrdinalNumber(t.tickValue);s[e]=1})),function(t){return!s.hasOwnProperty(e.get(a,t))}}}}function _S(t,e){return[t[2*e],t[2*e+1]]}function bS(t){if(t.get(["endLabel","show"]))return!0;for(var e=0;e0&&"bolder"===t.get(["emphasis","lineStyle","width"]))&&(d.getState("emphasis").style.lineWidth=+d.style.lineWidth+1);js(d).seriesIndex=t.seriesIndex,Bl(d,L,P,O);var R=yS(t.get("smooth")),N=t.get("smoothMonotone");if(d.setShape({smooth:R,smoothMonotone:N,connectNulls:w}),f){var E=a.getCalculationInfo("stackedOnSeries"),z=0;f.useStyle(k(l.getAreaStyle(),{fill:C,opacity:.7,lineJoin:"bevel",decal:a.getVisual("style").decal})),E&&(z=yS(E.get("smooth"))),f.setShape({smooth:R,stackedOnSmooth:z,smoothMonotone:N,connectNulls:w}),Hl(f,t,"areaStyle"),js(f).seriesIndex=t.seriesIndex,Bl(f,L,P,O)}var V=function(t){i._changePolyState(t)};a.eachItemGraphicEl((function(t){t&&(t.onHoverStateChange=V)})),this._polyline.onHoverStateChange=V,this._data=a,this._coordSys=r,this._stackedOnPoints=_,this._points=u,this._step=T,this._valueOrigin=m,t.get("triggerLineEvent")&&(this.packEventData(t,d),f&&this.packEventData(t,f))},e.prototype.packEventData=function(t,e){js(e).eventData={componentType:"series",componentSubType:"line",componentIndex:t.componentIndex,seriesIndex:t.seriesIndex,seriesName:t.name,seriesType:"line"}},e.prototype.highlight=function(t,e,n,i){var r=t.getData(),o=Co(r,i);if(this._changePolyState("emphasis"),!(o instanceof Array)&&null!=o&&o>=0){var a=r.getLayout("points"),s=r.getItemGraphicEl(o);if(!s){var l=a[2*o],u=a[2*o+1];if(isNaN(l)||isNaN(u))return;if(this._clipShapeForSymbol&&!this._clipShapeForSymbol.contain(l,u))return;var h=t.get("zlevel")||0,c=t.get("z")||0;(s=new Zw(r,o)).x=l,s.y=u,s.setZ(h,c);var p=s.getSymbolPath().getTextContent();p&&(p.zlevel=h,p.z=c,p.z2=this._polyline.z2+1),s.__temp=!0,r.setItemGraphicEl(o,s),s.stopSymbolAnimation(!0),this.group.add(s)}s.highlight()}else wg.prototype.highlight.call(this,t,e,n,i)},e.prototype.downplay=function(t,e,n,i){var r=t.getData(),o=Co(r,i);if(this._changePolyState("normal"),null!=o&&o>=0){var a=r.getItemGraphicEl(o);a&&(a.__temp?(r.setItemGraphicEl(o,null),this.group.remove(a)):a.downplay())}else wg.prototype.downplay.call(this,t,e,n,i)},e.prototype._changePolyState=function(t){var e=this._polygon;_l(this._polyline,t),e&&_l(e,t)},e.prototype._newPolyline=function(t){var e=this._polyline;return e&&this._lineGroup.remove(e),e=new aS({shape:{points:t},segmentIgnoreThreshold:2,z2:10}),this._lineGroup.add(e),this._polyline=e,e},e.prototype._newPolygon=function(t,e){var n=this._polygon;return n&&this._lineGroup.remove(n),n=new lS({shape:{points:t,stackedOnPoints:e},segmentIgnoreThreshold:2}),this._lineGroup.add(n),this._polygon=n,n},e.prototype._initSymbolLabelAnimation=function(t,e,n){var i,r,o=e.getBaseAxis(),a=o.inverse;"cartesian2d"===e.type?(i=o.isHorizontal(),r=!1):"polar"===e.type&&(i="angle"===o.dim,r=!0);var s=t.hostModel,l=s.get("animationDuration");U(l)&&(l=l(null));var u=s.get("animationDelay")||0,h=U(u)?u(null):u;t.eachItemGraphicEl((function(t,o){var s=t;if(s){var c=[t.x,t.y],p=void 0,d=void 0,f=void 0;if(n)if(r){var g=n,y=e.pointToCoord(c);i?(p=g.startAngle,d=g.endAngle,f=-y[1]/180*Math.PI):(p=g.r0,d=g.r,f=y[0])}else{var v=n;i?(p=v.x,d=v.x+v.width,f=t.x):(p=v.y+v.height,d=v.y,f=t.y)}var m=d===p?0:(f-p)/(d-p);a&&(m=1-m);var x=U(u)?u(o):l*m+h,_=s.getSymbolPath(),b=_.getTextContent();s.attr({scaleX:0,scaleY:0}),s.animateTo({scaleX:1,scaleY:1},{duration:200,setToFinal:!0,delay:x}),b&&b.animateFrom({style:{opacity:0}},{duration:300,delay:x}),_.disableLabelAnimation=!0}}))},e.prototype._initOrUpdateEndLabel=function(t,e,n){var i=t.getModel("endLabel");if(bS(t)){var r=t.getData(),o=this._polyline,a=r.getLayout("points");if(!a)return o.removeTextContent(),void(this._endLabel=null);var s=this._endLabel;s||((s=this._endLabel=new Ns({z2:200})).ignoreClip=!0,o.setTextContent(this._endLabel),o.disableLabelAnimation=!0);var l=function(t){for(var e,n,i=t.length/2;i>0&&(e=t[2*i-2],n=t[2*i-1],isNaN(e)||isNaN(n));i--);return i-1}(a);l>=0&&(qh(o,Kh(t,"endLabel"),{inheritColor:n,labelFetcher:t,labelDataIndex:l,defaultText:function(t,e,n){return null!=n?Xw(r,n):Uw(r,t)},enableTextSetter:!0},function(t,e){var n=e.getBaseAxis(),i=n.isHorizontal(),r=n.inverse,o=i?r?"right":"left":"center",a=i?"middle":r?"top":"bottom";return{normal:{align:t.get("align")||o,verticalAlign:t.get("verticalAlign")||a}}}(i,e)),o.textConfig.position=null)}else this._endLabel&&(this._polyline.removeTextContent(),this._endLabel=null)},e.prototype._endLabelOnDuring=function(t,e,n,i,r,o,a){var s=this._endLabel,l=this._polyline;if(s){t<1&&null==i.originalX&&(i.originalX=s.x,i.originalY=s.y);var u=n.getLayout("points"),h=n.hostModel,c=h.get("connectNulls"),p=o.get("precision"),d=o.get("distance")||0,f=a.getBaseAxis(),g=f.isHorizontal(),y=f.inverse,v=e.shape,m=y?g?v.x:v.y+v.height:g?v.x+v.width:v.y,x=(g?d:0)*(y?-1:1),_=(g?0:-d)*(y?-1:1),b=g?"x":"y",w=function(t,e,n){for(var i,r,o=t.length/2,a="x"===n?0:1,s=0,l=-1,u=0;u=e||i>=e&&r<=e){l=u;break}s=u,i=r}else i=r;return{range:[s,l],t:(e-i)/(r-i)}}(u,m,b),S=w.range,M=S[1]-S[0],I=void 0;if(M>=1){if(M>1&&!c){var T=_S(u,S[0]);s.attr({x:T[0]+x,y:T[1]+_}),r&&(I=h.getRawValue(S[0]))}else{(T=l.getPointOn(m,b))&&s.attr({x:T[0]+x,y:T[1]+_});var C=h.getRawValue(S[0]),D=h.getRawValue(S[1]);r&&(I=zo(n,p,C,D,w.t))}i.lastFrameIndex=S[0]}else{var A=1===t||i.lastFrameIndex>0?S[0]:0;T=_S(u,A);r&&(I=h.getRawValue(A)),s.attr({x:T[0]+x,y:T[1]+_})}r&&rc(s).setLabelText(I)}},e.prototype._doUpdateAnimation=function(t,e,n,i,r,o,a){var s=this._polyline,l=this._polygon,u=t.hostModel,h=function(t,e,n,i,r,o,a,s){for(var l=function(t,e){var n=[];return e.diff(t).add((function(t){n.push({cmd:"+",idx:t})})).update((function(t,e){n.push({cmd:"=",idx:e,idx1:t})})).remove((function(t){n.push({cmd:"-",idx:t})})).execute(),n}(t,e),u=[],h=[],c=[],p=[],d=[],f=[],g=[],y=Qw(r,e,a),v=t.getLayout("points")||[],m=e.getLayout("points")||[],x=0;x3e3||l&&gS(p,f)>3e3)return s.stopAnimation(),s.setShape({points:d}),void(l&&(l.stopAnimation(),l.setShape({points:d,stackedOnPoints:f})));s.shape.__points=h.current,s.shape.points=c;var g={shape:{points:d}};h.current!==c&&(g.shape.__points=h.next),s.stopAnimation(),uh(s,g,u),l&&(l.setShape({points:c,stackedOnPoints:p}),l.stopAnimation(),uh(l,{shape:{stackedOnPoints:f}},u),s.shape.points!==l.shape.points&&(l.shape.points=s.shape.points));for(var y=[],v=h.status,m=0;me&&(e=t[n]);return isFinite(e)?e:NaN},min:function(t){for(var e=1/0,n=0;n10&&"cartesian2d"===o.type&&r){var s=o.getBaseAxis(),l=o.getOtherAxis(s),u=s.getExtent(),h=n.getDevicePixelRatio(),c=Math.abs(u[1]-u[0])*(h||1),p=Math.round(a/c);if(isFinite(p)&&p>1){"lttb"===r&&t.setData(i.lttbDownSample(i.mapDimension(l.dim),1/p));var d=void 0;X(r)?d=IS[r]:U(r)&&(d=r),d&&t.setData(i.downSample(i.mapDimension(l.dim),1/p,d,TS))}}}}}var DS=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.getInitialData=function(t,e){return sx(null,this,{useEncodeDefaulter:!0})},e.prototype.getMarkerPosition=function(t){var e=this.coordinateSystem;if(e&&e.clampData){var n=e.dataToPoint(e.clampData(t)),i=this.getData(),r=i.getLayout("offset"),o=i.getLayout("size");return n[e.getBaseAxis().isHorizontal()?0:1]+=r+o/2,n}return[NaN,NaN]},e.type="series.__base_bar__",e.defaultOption={z:2,coordinateSystem:"cartesian2d",legendHoverLink:!0,barMinHeight:0,barMinAngle:0,large:!1,largeThreshold:400,progressive:3e3,progressiveChunkMode:"mod"},e}(hg);hg.registerClass(DS);var AS=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.getInitialData=function(){return sx(null,this,{useEncodeDefaulter:!0,createInvertedIndices:!!this.get("realtimeSort",!0)||null})},e.prototype.getProgressive=function(){return!!this.get("large")&&this.get("progressive")},e.prototype.getProgressiveThreshold=function(){var t=this.get("progressiveThreshold"),e=this.get("largeThreshold");return e>t&&(t=e),t},e.prototype.brushSelector=function(t,e,n){return n.rect(e.getItemLayout(t))},e.type="series.bar",e.dependencies=["grid","polar"],e.defaultOption=wc(DS.defaultOption,{clip:!0,roundCap:!1,showBackground:!1,backgroundStyle:{color:"rgba(180, 180, 180, 0.2)",borderColor:null,borderWidth:0,borderType:"solid",borderRadius:0,shadowBlur:0,shadowColor:null,shadowOffsetX:0,shadowOffsetY:0,opacity:1},select:{itemStyle:{borderColor:"#212121"}},realtimeSort:!1}),e}(DS),kS=function(){this.cx=0,this.cy=0,this.r0=0,this.r=0,this.startAngle=0,this.endAngle=2*Math.PI,this.clockwise=!0},LS=function(t){function e(e){var n=t.call(this,e)||this;return n.type="sausage",n}return n(e,t),e.prototype.getDefaultShape=function(){return new kS},e.prototype.buildPath=function(t,e){var n=e.cx,i=e.cy,r=Math.max(e.r0||0,0),o=Math.max(e.r,0),a=.5*(o-r),s=r+a,l=e.startAngle,u=e.endAngle,h=e.clockwise,c=2*Math.PI,p=h?u-lo)return!0;o=u}return!1},e.prototype._isOrderDifferentInView=function(t,e){for(var n=e.scale,i=n.getExtent(),r=Math.max(0,i[0]),o=Math.min(i[1],n.getOrdinalMeta().categories.length-1);r<=o;++r)if(t.ordinalNumbers[r]!==n.getRawOrdinalNumber(r))return!0},e.prototype._updateSortWithinSameData=function(t,e,n,i){if(this._isOrderChangedWithinSameData(t,e,n)){var r=this._dataSort(t,n,e);this._isOrderDifferentInView(r,n)&&(this._removeOnRenderedListener(i),i.dispatchAction({type:"changeAxisOrder",componentType:n.dim+"Axis",axisId:n.index,sortInfo:r}))}},e.prototype._dispatchInitSort=function(t,e,n){var i=e.baseAxis,r=this._dataSort(t,i,(function(n){return t.get(t.mapDimension(e.otherAxis.dim),n)}));n.dispatchAction({type:"changeAxisOrder",componentType:i.dim+"Axis",isInitSort:!0,axisId:i.index,sortInfo:r})},e.prototype.remove=function(t,e){this._clear(this._model),this._removeOnRenderedListener(e)},e.prototype.dispose=function(t,e){this._removeOnRenderedListener(e)},e.prototype._removeOnRenderedListener=function(t){this._onRendered&&(t.getZr().off("rendered",this._onRendered),this._onRendered=null)},e.prototype._clear=function(t){var e=this.group,n=this._data;t&&t.isAnimationEnabled()&&n&&!this._isLargeDraw?(this._removeBackground(),this._backgroundEls=[],n.eachItemGraphicEl((function(e){fh(e,t,js(e).dataIndex)}))):e.removeAll(),this._data=null,this._isFirstFrame=!0},e.prototype._removeBackground=function(){this.group.remove(this._backgroundGroup),this._backgroundGroup=null},e.type="bar",e}(wg),zS={cartesian2d:function(t,e){var n=e.width<0?-1:1,i=e.height<0?-1:1;n<0&&(e.x+=e.width,e.width=-e.width),i<0&&(e.y+=e.height,e.height=-e.height);var r=t.x+t.width,o=t.y+t.height,a=RS(e.x,t.x),s=NS(e.x+e.width,r),l=RS(e.y,t.y),u=NS(e.y+e.height,o),h=sr?s:a,e.y=c&&l>o?u:l,e.width=h?0:s-a,e.height=c?0:u-l,n<0&&(e.x+=e.width,e.width=-e.width),i<0&&(e.y+=e.height,e.height=-e.height),h||c},polar:function(t,e){var n=e.r0<=e.r?1:-1;if(n<0){var i=e.r;e.r=e.r0,e.r0=i}var r=NS(e.r,t.r),o=RS(e.r0,t.r0);e.r=r,e.r0=o;var a=r-o<0;if(n<0){i=e.r;e.r=e.r0,e.r0=i}return a}},VS={cartesian2d:function(t,e,n,i,r,o,a,s,l){var u=new Ps({shape:A({},i),z2:1});(u.__dataIndex=n,u.name="item",o)&&(u.shape[r?"height":"width"]=0);return u},polar:function(t,e,n,i,r,o,a,s,l){var u=!r&&l?LS:Pu,h=new u({shape:i,z2:1});h.name="item";var c,p,d=US(r);if(h.calculateTextPosition=(c=d,p=({isRoundCap:u===LS}||{}).isRoundCap,function(t,e,n){var i=e.position;if(!i||i instanceof Array)return br(t,e,n);var r=c(i),o=null!=e.distance?e.distance:5,a=this.shape,s=a.cx,l=a.cy,u=a.r,h=a.r0,d=(u+h)/2,f=a.startAngle,g=a.endAngle,y=(f+g)/2,v=p?Math.abs(u-h)/2:0,m=Math.cos,x=Math.sin,_=s+u*m(f),b=l+u*x(f),w="left",S="top";switch(r){case"startArc":_=s+(h-o)*m(y),b=l+(h-o)*x(y),w="center",S="top";break;case"insideStartArc":_=s+(h+o)*m(y),b=l+(h+o)*x(y),w="center",S="bottom";break;case"startAngle":_=s+d*m(f)+PS(f,o+v,!1),b=l+d*x(f)+OS(f,o+v,!1),w="right",S="middle";break;case"insideStartAngle":_=s+d*m(f)+PS(f,-o+v,!1),b=l+d*x(f)+OS(f,-o+v,!1),w="left",S="middle";break;case"middle":_=s+d*m(y),b=l+d*x(y),w="center",S="middle";break;case"endArc":_=s+(u+o)*m(y),b=l+(u+o)*x(y),w="center",S="bottom";break;case"insideEndArc":_=s+(u-o)*m(y),b=l+(u-o)*x(y),w="center",S="top";break;case"endAngle":_=s+d*m(g)+PS(g,o+v,!0),b=l+d*x(g)+OS(g,o+v,!0),w="left",S="middle";break;case"insideEndAngle":_=s+d*m(g)+PS(g,-o+v,!0),b=l+d*x(g)+OS(g,-o+v,!0),w="right",S="middle";break;default:return br(t,e,n)}return(t=t||{}).x=_,t.y=b,t.align=w,t.verticalAlign=S,t}),o){var f=r?"r":"endAngle",g={};h.shape[f]=r?0:i.startAngle,g[f]=i[f],(s?uh:hh)(h,{shape:g},o)}return h}};function BS(t,e,n,i,r,o,a,s){var l,u;o?(u={x:i.x,width:i.width},l={y:i.y,height:i.height}):(u={y:i.y,height:i.height},l={x:i.x,width:i.width}),s||(a?uh:hh)(n,{shape:l},e,r,null),(a?uh:hh)(n,{shape:u},e?t.baseAxis.model:null,r)}function FS(t,e){for(var n=0;n0?1:-1,a=i.height>0?1:-1;return{x:i.x+o*r/2,y:i.y+a*r/2,width:i.width-o*r,height:i.height-a*r}},polar:function(t,e,n){var i=t.getItemLayout(e);return{cx:i.cx,cy:i.cy,r0:i.r0,r:i.r,startAngle:i.startAngle,endAngle:i.endAngle,clockwise:i.clockwise}}};function US(t){return function(t){var e=t?"Arc":"Angle";return function(t){switch(t){case"start":case"insideStart":case"end":case"insideEnd":return t+e;default:return t}}}(t)}function XS(t,e,n,i,r,o,a,s){var l=e.getItemVisual(n,"style");s||t.setShape("r",i.get(["itemStyle","borderRadius"])||0),t.useStyle(l);var u=i.getShallow("cursor");u&&t.attr("cursor",u);var h=s?a?r.r>=r.r0?"endArc":"startArc":r.endAngle>=r.startAngle?"endAngle":"startAngle":a?r.height>=0?"bottom":"top":r.width>=0?"right":"left",c=Kh(i);qh(t,c,{labelFetcher:o,labelDataIndex:n,defaultText:Uw(o.getData(),n),inheritColor:l.fill,defaultOpacity:l.opacity,defaultOutsidePosition:h});var p=t.getTextContent();if(s&&p){var d=i.get(["label","position"]);t.textConfig.inside="middle"===d||null,function(t,e,n,i){if(j(i))t.setTextConfig({rotation:i});else if(Y(e))t.setTextConfig({rotation:0});else{var r,o=t.shape,a=o.clockwise?o.startAngle:o.endAngle,s=o.clockwise?o.endAngle:o.startAngle,l=(a+s)/2,u=n(e);switch(u){case"startArc":case"insideStartArc":case"middle":case"insideEndArc":case"endArc":r=l;break;case"startAngle":case"insideStartAngle":r=a;break;case"endAngle":case"insideEndAngle":r=s;break;default:return void t.setTextConfig({rotation:0})}var h=1.5*Math.PI-r;"middle"===u&&h>Math.PI/2&&h<1.5*Math.PI&&(h-=Math.PI),t.setTextConfig({rotation:h})}}(t,"outside"===d?h:d,US(a),i.get(["label","rotate"]))}oc(p,c,o.getRawValue(n),(function(t){return Xw(e,t)}));var f=i.getModel(["emphasis"]);Bl(t,f.get("focus"),f.get("blurScope"),f.get("disabled")),Hl(t,i),function(t){return null!=t.startAngle&&null!=t.endAngle&&t.startAngle===t.endAngle}(r)&&(t.style.fill="none",t.style.stroke="none",E(t.states,(function(t){t.style&&(t.style.fill=t.style.stroke="none")})))}var ZS=function(){},jS=function(t){function e(e){var n=t.call(this,e)||this;return n.type="largeBar",n}return n(e,t),e.prototype.getDefaultShape=function(){return new ZS},e.prototype.buildPath=function(t,e){for(var n=e.points,i=this.baseDimIdx,r=1-this.baseDimIdx,o=[],a=[],s=this.barWidth,l=0;l=s[0]&&e<=s[0]+l[0]&&n>=s[1]&&n<=s[1]+l[1])return a[h]}return-1}(this,t.offsetX,t.offsetY);js(this).dataIndex=e>=0?e:null}),30,!1);function $S(t,e,n){if(pS(n,"cartesian2d")){var i=e,r=n.getArea();return{x:t?i.x:r.x,y:t?r.y:i.y,width:t?i.width:r.width,height:t?r.height:i.height}}var o=e;return{cx:(r=n.getArea()).cx,cy:r.cy,r0:t?r.r0:o.r0,r:t?r.r:o.r,startAngle:t?o.startAngle:0,endAngle:t?o.endAngle:2*Math.PI}}var JS=2*Math.PI,QS=Math.PI/180;function tM(t,e){return wp(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()})}function eM(t,e){var n=tM(t,e),i=t.get("center"),r=t.get("radius");Y(r)||(r=[0,r]),Y(i)||(i=[i,i]);var o,a,s=Gr(n.width,e.getWidth()),l=Gr(n.height,e.getHeight()),u=Math.min(s,l),h=Gr(r[0],u/2),c=Gr(r[1],u/2),p=t.coordinateSystem;if(p){var d=p.dataToPoint(i);o=d[0]||0,a=d[1]||0}else o=Gr(i[0],s)+n.x,a=Gr(i[1],l)+n.y;return{cx:o,cy:a,r0:h,r:c}}function nM(t,e,n){e.eachSeriesByType(t,(function(t){var e=t.getData(),i=e.mapDimension("value"),r=tM(t,n),o=eM(t,n),a=o.cx,s=o.cy,l=o.r,u=o.r0,h=-t.get("startAngle")*QS,c=t.get("minAngle")*QS,p=0;e.each(i,(function(t){!isNaN(t)&&p++}));var d=e.getSum(i),f=Math.PI/(d||p)*2,g=t.get("clockwise"),y=t.get("roseType"),v=t.get("stillShowZeroSum"),m=e.getDataExtent(i);m[0]=0;var x=JS,_=0,b=h,w=g?1:-1;if(e.setLayout({viewRect:r,r:l}),e.each(i,(function(t,n){var i;if(isNaN(t))e.setItemLayout(n,{angle:NaN,startAngle:NaN,endAngle:NaN,clockwise:g,cx:a,cy:s,r0:u,r:y?NaN:l});else{(i="area"!==y?0===d&&v?f:t*f:JS/p)n?a:o,h=Math.abs(l.label.y-n);if(h>=u.maxY){var c=l.label.x-e-l.len2*r,p=i+l.len,f=Math.abs(c)t.unconstrainedWidth?null:d:null;i.setStyle("width",f)}var g=i.getBoundingRect();o.width=g.width;var y=(i.style.margin||0)+2.1;o.height=g.height+y,o.y-=(o.height-c)/2}}}function sM(t){return"center"===t.position}function lM(t){var e,n,i=t.getData(),r=[],o=!1,a=(t.get("minShowLabelAngle")||0)*rM,s=i.getLayout("viewRect"),l=i.getLayout("r"),u=s.width,h=s.x,c=s.y,p=s.height;function d(t){t.ignore=!0}i.each((function(t){var s=i.getItemGraphicEl(t),c=s.shape,p=s.getTextContent(),f=s.getTextGuideLine(),g=i.getItemModel(t),y=g.getModel("label"),v=y.get("position")||g.get(["emphasis","label","position"]),m=y.get("distanceToLabelLine"),x=y.get("alignTo"),_=Gr(y.get("edgeDistance"),u),b=y.get("bleedMargin"),w=g.getModel("labelLine"),S=w.get("length");S=Gr(S,u);var M=w.get("length2");if(M=Gr(M,u),Math.abs(c.endAngle-c.startAngle)0?"right":"left":k>0?"left":"right"}var B=Math.PI,F=0,G=y.get("rotate");if(j(G))F=G*(B/180);else if("center"===v)F=0;else if("radial"===G||!0===G){F=k<0?-A+B:-A}else if("tangential"===G&&"outside"!==v&&"outer"!==v){var W=Math.atan2(k,L);W<0&&(W=2*B+W),L>0&&(W=B+W),F=W-B}if(o=!!F,p.x=I,p.y=T,p.rotation=F,p.setStyle({verticalAlign:"middle"}),P){p.setStyle({align:D});var H=p.states.select;H&&(H.x+=p.x,H.y+=p.y)}else{var Y=p.getBoundingRect().clone();Y.applyTransform(p.getComputedTransform());var U=(p.style.margin||0)+2.1;Y.y-=U/2,Y.height+=U,r.push({label:p,labelLine:f,position:v,len:S,len2:M,minTurnAngle:w.get("minTurnAngle"),maxSurfaceAngle:w.get("maxSurfaceAngle"),surfaceNormal:new Ie(k,L),linePoints:C,textAlign:D,labelDistance:m,labelAlignTo:x,edgeDistance:_,bleedMargin:b,rect:Y,unconstrainedWidth:Y.width,labelStyleWidth:p.style.width})}s.setTextConfig({inside:P})}})),!o&&t.get("avoidLabelOverlap")&&function(t,e,n,i,r,o,a,s){for(var l=[],u=[],h=Number.MAX_VALUE,c=-Number.MAX_VALUE,p=0;p0){for(var l=o.getItemLayout(0),u=1;isNaN(l&&l.startAngle)&&u=n.r0}},e.type="pie",e}(wg);function pM(t,e,n){e=Y(e)&&{coordDimensions:e}||A({encodeDefine:t.getEncode()},e);var i=t.getSource(),r=Qm(i,e).dimensions,o=new Jm(r,t);return o.initData(i,n),o}var dM=function(){function t(t,e){this._getDataWithEncodedVisual=t,this._getRawData=e}return t.prototype.getAllNames=function(){var t=this._getRawData();return t.mapArray(t.getName)},t.prototype.containName=function(t){return this._getRawData().indexOfName(t)>=0},t.prototype.indexOfName=function(t){return this._getDataWithEncodedVisual().indexOfName(t)},t.prototype.getItemVisual=function(t,e){return this._getDataWithEncodedVisual().getItemVisual(t,e)},t}(),fM=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.init=function(e){t.prototype.init.apply(this,arguments),this.legendVisualProvider=new dM(W(this.getData,this),W(this.getRawData,this)),this._defaultLabelLine(e)},e.prototype.mergeOption=function(){t.prototype.mergeOption.apply(this,arguments)},e.prototype.getInitialData=function(){var t=pM(this,{coordDimensions:["value"],encodeDefaulter:H(Zp,this)}),e=[];return t.each(t.mapDimension("value"),(function(t){e.push(t)})),this.seats=Zr(e,t.hostModel.get("percentPrecision")),t},e.prototype.getDataParams=function(e){var n=t.prototype.getDataParams.call(this,e);return n.percent=this.seats[e],n.$vars.push("percent"),n},e.prototype._defaultLabelLine=function(t){vo(t,"labelLine",["show"]);var e=t.labelLine,n=t.emphasis.labelLine;e.show=e.show&&t.label.show,n.show=n.show&&t.emphasis.label.show},e.type="series.pie",e.defaultOption={z:2,legendHoverLink:!0,colorBy:"data",center:["50%","50%"],radius:[0,"75%"],clockwise:!0,startAngle:90,minAngle:0,minShowLabelAngle:0,selectedOffset:10,percentPrecision:2,stillShowZeroSum:!0,left:0,top:0,right:0,bottom:0,width:null,height:null,label:{rotate:0,show:!0,overflow:"truncate",position:"outer",alignTo:"none",edgeDistance:"25%",bleedMargin:10,distanceToLabelLine:5},labelLine:{show:!0,length:15,length2:15,smooth:!1,minTurnAngle:90,maxSurfaceAngle:90,lineStyle:{width:1,type:"solid"}},itemStyle:{borderWidth:1,borderJoin:"round"},showEmptyCircle:!0,emptyCircleStyle:{color:"lightgray",opacity:1},labelLayout:{hideOverlap:!0},emphasis:{scale:!0,scaleSize:5},avoidLabelOverlap:!0,animationType:"expansion",animationDuration:1e3,animationTypeUpdate:"transition",animationEasingUpdate:"cubicInOut",animationDurationUpdate:500,animationEasing:"cubicInOut"},e}(hg);var gM=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.hasSymbolVisual=!0,n}return n(e,t),e.prototype.getInitialData=function(t,e){return sx(null,this,{useEncodeDefaulter:!0})},e.prototype.getProgressive=function(){var t=this.option.progressive;return null==t?this.option.large?5e3:this.get("progressive"):t},e.prototype.getProgressiveThreshold=function(){var t=this.option.progressiveThreshold;return null==t?this.option.large?1e4:this.get("progressiveThreshold"):t},e.prototype.brushSelector=function(t,e,n){return n.point(e.getItemLayout(t))},e.prototype.getZLevelKey=function(){return this.getData().count()>this.getProgressiveThreshold()?this.id:""},e.type="series.scatter",e.dependencies=["grid","polar","geo","singleAxis","calendar"],e.defaultOption={coordinateSystem:"cartesian2d",z:2,legendHoverLink:!0,symbolSize:10,large:!1,largeThreshold:2e3,itemStyle:{opacity:.8},emphasis:{scale:!0},clip:!0,select:{itemStyle:{borderColor:"#212121"}},universalTransition:{divideShape:"clone"}},e}(hg),yM=function(){},vM=function(t){function e(e){var n=t.call(this,e)||this;return n._off=0,n.hoverDataIdx=-1,n}return n(e,t),e.prototype.getDefaultShape=function(){return new yM},e.prototype.reset=function(){this.notClear=!1,this._off=0},e.prototype.buildPath=function(t,e){var n,i=e.points,r=e.size,o=this.symbolProxy,a=o.shape,s=t.getContext?t.getContext():t,l=s&&r[0]<4,u=this.softClipShape;if(l)this._ctx=s;else{for(this._ctx=null,n=this._off;n=0;s--){var l=2*s,u=i[l]-o/2,h=i[l+1]-a/2;if(t>=u&&e>=h&&t<=u+o&&e<=h+a)return s}return-1},e.prototype.contain=function(t,e){var n=this.transformCoordToLocal(t,e),i=this.getBoundingRect();return t=n[0],e=n[1],i.contain(t,e)?(this.hoverDataIdx=this.findDataIndex(t,e))>=0:(this.hoverDataIdx=-1,!1)},e.prototype.getBoundingRect=function(){var t=this._rect;if(!t){for(var e=this.shape,n=e.points,i=e.size,r=i[0],o=i[1],a=1/0,s=1/0,l=-1/0,u=-1/0,h=0;h=0&&(l.dataIndex=n+(t.startIndex||0))}))},t.prototype.remove=function(){this._clear()},t.prototype._clear=function(){this._newAdded=[],this.group.removeAll()},t}(),xM=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){var i=t.getData();this._updateSymbolDraw(i,t).updateData(i,{clipShape:this._getClipShape(t)}),this._finished=!0},e.prototype.incrementalPrepareRender=function(t,e,n){var i=t.getData();this._updateSymbolDraw(i,t).incrementalPrepareUpdate(i),this._finished=!1},e.prototype.incrementalRender=function(t,e,n){this._symbolDraw.incrementalUpdate(t,e.getData(),{clipShape:this._getClipShape(e)}),this._finished=t.end===e.getData().count()},e.prototype.updateTransform=function(t,e,n){var i=t.getData();if(this.group.dirty(),!this._finished||i.count()>1e4)return{update:!0};var r=MS("").reset(t,e,n);r.progress&&r.progress({start:0,end:i.count(),count:i.count()},i),this._symbolDraw.updateLayout(i)},e.prototype.eachRendered=function(t){this._symbolDraw&&this._symbolDraw.eachRendered(t)},e.prototype._getClipShape=function(t){var e=t.coordinateSystem,n=e&&e.getArea&&e.getArea();return t.get("clip",!0)?n:null},e.prototype._updateSymbolDraw=function(t,e){var n=this._symbolDraw,i=e.pipelineContext.large;return n&&i===this._isLargeDraw||(n&&n.remove(),n=this._symbolDraw=i?new mM:new Jw,this._isLargeDraw=i,this.group.removeAll()),this.group.add(n.group),n},e.prototype.remove=function(t,e){this._symbolDraw&&this._symbolDraw.remove(!0),this._symbolDraw=null},e.prototype.dispose=function(){},e.type="scatter",e}(wg),_M=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.type="grid",e.dependencies=["xAxis","yAxis"],e.layoutMode="box",e.defaultOption={show:!1,z:0,left:"10%",top:60,right:"10%",bottom:70,containLabel:!1,backgroundColor:"rgba(0,0,0,0)",borderWidth:1,borderColor:"#ccc"},e}(Ap),bM=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.getCoordSysModel=function(){return this.getReferringComponents("grid",Po).models[0]},e.type="cartesian2dAxis",e}(Ap);R(bM,g_);var wM={show:!0,z:0,inverse:!1,name:"",nameLocation:"end",nameRotate:null,nameTruncate:{maxWidth:null,ellipsis:"...",placeholder:"."},nameTextStyle:{},nameGap:15,silent:!1,triggerEvent:!1,tooltip:{show:!1},axisPointer:{},axisLine:{show:!0,onZero:!0,onZeroAxisIndex:null,lineStyle:{color:"#6E7079",width:1,type:"solid"},symbol:["none","none"],symbolSize:[10,15]},axisTick:{show:!0,inside:!1,length:5,lineStyle:{width:1}},axisLabel:{show:!0,inside:!1,rotate:0,showMinLabel:null,showMaxLabel:null,margin:8,fontSize:12},splitLine:{show:!0,lineStyle:{color:["#E0E6F1"],width:1,type:"solid"}},splitArea:{show:!1,areaStyle:{color:["rgba(250,250,250,0.2)","rgba(210,219,238,0.2)"]}}},SM=C({boundaryGap:!0,deduplication:null,splitLine:{show:!1},axisTick:{alignWithLabel:!1,interval:"auto"},axisLabel:{interval:"auto"}},wM),MM=C({boundaryGap:[0,0],axisLine:{show:"auto"},axisTick:{show:"auto"},splitNumber:5,minorTick:{show:!1,splitNumber:5,length:3,lineStyle:{}},minorSplitLine:{show:!1,lineStyle:{color:"#F4F7FD",width:1}}},wM),IM={category:SM,value:MM,time:C({splitNumber:6,axisLabel:{showMinLabel:!1,showMaxLabel:!1,rich:{primary:{fontWeight:"bold"}}},splitLine:{show:!1}},MM),log:k({logBase:10},MM)},TM={value:1,category:1,time:1,log:1};function CM(t,e,i,r){E(TM,(function(o,a){var s=C(C({},IM[a],!0),r,!0),l=function(t){function i(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e+"Axis."+a,n}return n(i,t),i.prototype.mergeDefaultAndTheme=function(t,e){var n=Mp(this),i=n?Tp(t):{};C(t,e.getTheme().get(a+"Axis")),C(t,this.getDefaultOption()),t.type=DM(t),n&&Ip(t,i,n)},i.prototype.optionUpdated=function(){"category"===this.option.type&&(this.__ordinalMeta=hx.createByAxisModel(this))},i.prototype.getCategories=function(t){var e=this.option;if("category"===e.type)return t?e.data:this.__ordinalMeta.categories},i.prototype.getOrdinalMeta=function(){return this.__ordinalMeta},i.type=e+"Axis."+a,i.defaultOption=s,i}(i);t.registerComponentModel(l)})),t.registerSubTypeDefaulter(e+"Axis",DM)}function DM(t){return t.type||(t.data?"category":"value")}var AM=function(){function t(t){this.type="cartesian",this._dimList=[],this._axes={},this.name=t||""}return t.prototype.getAxis=function(t){return this._axes[t]},t.prototype.getAxes=function(){return z(this._dimList,(function(t){return this._axes[t]}),this)},t.prototype.getAxesByScale=function(t){return t=t.toLowerCase(),B(this.getAxes(),(function(e){return e.scale.type===t}))},t.prototype.addAxis=function(t){var e=t.dim;this._axes[e]=t,this._dimList.push(e)},t}(),kM=["x","y"];function LM(t){return"interval"===t.type||"time"===t.type}var PM=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.type="cartesian2d",e.dimensions=kM,e}return n(e,t),e.prototype.calcAffineTransform=function(){this._transform=this._invTransform=null;var t=this.getAxis("x").scale,e=this.getAxis("y").scale;if(LM(t)&&LM(e)){var n=t.getExtent(),i=e.getExtent(),r=this.dataToPoint([n[0],i[0]]),o=this.dataToPoint([n[1],i[1]]),a=n[1]-n[0],s=i[1]-i[0];if(a&&s){var l=(o[0]-r[0])/a,u=(o[1]-r[1])/s,h=r[0]-n[0]*l,c=r[1]-i[0]*u,p=this._transform=[l,0,0,u,h,c];this._invTransform=we([],p)}}},e.prototype.getBaseAxis=function(){return this.getAxesByScale("ordinal")[0]||this.getAxesByScale("time")[0]||this.getAxis("x")},e.prototype.containPoint=function(t){var e=this.getAxis("x"),n=this.getAxis("y");return e.contain(e.toLocalCoord(t[0]))&&n.contain(n.toLocalCoord(t[1]))},e.prototype.containData=function(t){return this.getAxis("x").containData(t[0])&&this.getAxis("y").containData(t[1])},e.prototype.containZone=function(t,e){var n=this.dataToPoint(t),i=this.dataToPoint(e),r=this.getArea(),o=new Re(n[0],n[1],i[0]-n[0],i[1]-n[1]);return r.intersect(o)},e.prototype.dataToPoint=function(t,e,n){n=n||[];var i=t[0],r=t[1];if(this._transform&&null!=i&&isFinite(i)&&null!=r&&isFinite(r))return Ft(n,t,this._transform);var o=this.getAxis("x"),a=this.getAxis("y");return n[0]=o.toGlobalCoord(o.dataToCoord(i,e)),n[1]=a.toGlobalCoord(a.dataToCoord(r,e)),n},e.prototype.clampData=function(t,e){var n=this.getAxis("x").scale,i=this.getAxis("y").scale,r=n.getExtent(),o=i.getExtent(),a=n.parse(t[0]),s=i.parse(t[1]);return(e=e||[])[0]=Math.min(Math.max(Math.min(r[0],r[1]),a),Math.max(r[0],r[1])),e[1]=Math.min(Math.max(Math.min(o[0],o[1]),s),Math.max(o[0],o[1])),e},e.prototype.pointToData=function(t,e){var n=[];if(this._invTransform)return Ft(n,t,this._invTransform);var i=this.getAxis("x"),r=this.getAxis("y");return n[0]=i.coordToData(i.toLocalCoord(t[0]),e),n[1]=r.coordToData(r.toLocalCoord(t[1]),e),n},e.prototype.getOtherAxis=function(t){return this.getAxis("x"===t.dim?"y":"x")},e.prototype.getArea=function(){var t=this.getAxis("x").getGlobalExtent(),e=this.getAxis("y").getGlobalExtent(),n=Math.min(t[0],t[1]),i=Math.min(e[0],e[1]),r=Math.max(t[0],t[1])-n,o=Math.max(e[0],e[1])-i;return new Re(n,i,r,o)},e}(AM),OM=function(t){function e(e,n,i,r,o){var a=t.call(this,e,n,i)||this;return a.index=0,a.type=r||"value",a.position=o||"bottom",a}return n(e,t),e.prototype.isHorizontal=function(){var t=this.position;return"top"===t||"bottom"===t},e.prototype.getGlobalExtent=function(t){var e=this.getExtent();return e[0]=this.toGlobalCoord(e[0]),e[1]=this.toGlobalCoord(e[1]),t&&e[0]>e[1]&&e.reverse(),e},e.prototype.pointToData=function(t,e){return this.coordToData(this.toLocalCoord(t["x"===this.dim?0:1]),e)},e.prototype.setCategorySortInfo=function(t){if("category"!==this.type)return!1;this.model.option.categorySortInfo=t,this.scale.setSortInfo(t)},e}(X_);function RM(t,e,n){n=n||{};var i=t.coordinateSystem,r=e.axis,o={},a=r.getAxesOnZeroOf()[0],s=r.position,l=a?"onZero":s,u=r.dim,h=i.getRect(),c=[h.x,h.x+h.width,h.y,h.y+h.height],p={left:0,right:1,top:0,bottom:1,onZero:2},d=e.get("offset")||0,f="x"===u?[c[2]-d,c[3]+d]:[c[0]-d,c[1]+d];if(a){var g=a.toGlobalCoord(a.dataToCoord(0));f[p.onZero]=Math.max(Math.min(g,f[1]),f[0])}o.position=["y"===u?f[p[l]]:c[0],"x"===u?f[p[l]]:c[3]],o.rotation=Math.PI/2*("x"===u?0:1);o.labelDirection=o.tickDirection=o.nameDirection={top:-1,bottom:1,left:-1,right:1}[s],o.labelOffset=a?f[p[s]]-f[p.onZero]:0,e.get(["axisTick","inside"])&&(o.tickDirection=-o.tickDirection),it(n.labelInside,e.get(["axisLabel","inside"]))&&(o.labelDirection=-o.labelDirection);var y=e.get(["axisLabel","rotate"]);return o.labelRotate="top"===l?-y:y,o.z2=1,o}function NM(t){return"cartesian2d"===t.get("coordinateSystem")}function EM(t){var e={xAxisModel:null,yAxisModel:null};return E(e,(function(n,i){var r=i.replace(/Model$/,""),o=t.getReferringComponents(r,Po).models[0];e[i]=o})),e}var zM=Math.log;function VM(t,e,n){var i=Sx.prototype,r=i.getTicks.call(n),o=i.getTicks.call(n,!0),a=r.length-1,s=i.getInterval.call(n),l=a_(t,e),u=l.extent,h=l.fixMin,c=l.fixMax;if("log"===t.type){var p=zM(t.base);u=[zM(u[0])/p,zM(u[1])/p]}t.setExtent(u[0],u[1]),t.calcNiceExtent({splitNumber:a,fixMin:h,fixMax:c});var d=i.getExtent.call(t);h&&(u[0]=d[0]),c&&(u[1]=d[1]);var f=i.getInterval.call(t),g=u[0],y=u[1];if(h&&c)f=(y-g)/a;else if(h)for(y=u[0]+f*a;yu[0]&&isFinite(g)&&isFinite(u[0]);)f=fx(f),g=u[1]-f*a;else{t.getTicks().length-1>a&&(f=fx(f));var v=f*a;(g=Wr((y=Math.ceil(u[1]/f)*f)-v))<0&&u[0]>=0?(g=0,y=Wr(v)):y>0&&u[1]<=0&&(y=0,g=-Wr(v))}var m=(r[0].value-o[0].value)/s,x=(r[a].value-o[a].value)/s;i.setExtent.call(t,g+f*m,y+f*x),i.setInterval.call(t,f),(m||x)&&i.setNiceExtent.call(t,g+f,y-f)}var BM=function(){function t(t,e,n){this.type="grid",this._coordsMap={},this._coordsList=[],this._axesMap={},this._axesList=[],this.axisPointerEnabled=!0,this.dimensions=kM,this._initCartesian(t,e,n),this.model=t}return t.prototype.getRect=function(){return this._rect},t.prototype.update=function(t,e){var n=this._axesMap;function i(t){var e,n=G(t),i=n.length;if(i){for(var r=[],o=i-1;o>=0;o--){var a=t[+n[o]],s=a.model,l=a.scale;px(l)&&s.get("alignTicks")&&null==s.get("interval")?r.push(a):(s_(l,s),px(l)&&(e=a))}r.length&&(e||s_((e=r.pop()).scale,e.model),E(r,(function(t){VM(t.scale,t.model,e.scale)})))}}this._updateScale(t,this.model),i(n.x),i(n.y);var r={};E(n.x,(function(t){GM(n,"y",t,r)})),E(n.y,(function(t){GM(n,"x",t,r)})),this.resize(this.model,e)},t.prototype.resize=function(t,e,n){var i=t.getBoxLayoutParams(),r=!n&&t.get("containLabel"),o=wp(i,{width:e.getWidth(),height:e.getHeight()});this._rect=o;var a=this._axesList;function s(){E(a,(function(t){var e=t.isHorizontal(),n=e?[0,o.width]:[0,o.height],i=t.inverse?1:0;t.setExtent(n[i],n[1-i]),function(t,e){var n=t.getExtent(),i=n[0]+n[1];t.toGlobalCoord="x"===t.dim?function(t){return t+e}:function(t){return i-t+e},t.toLocalCoord="x"===t.dim?function(t){return t-e}:function(t){return i-t+e}}(t,e?o.x:o.y)}))}s(),r&&(E(a,(function(t){if(!t.model.get(["axisLabel","inside"])){var e=function(t){var e=t.model,n=t.scale;if(e.get(["axisLabel","show"])&&!n.isBlank()){var i,r,o=n.getExtent();r=n instanceof _x?n.count():(i=n.getTicks()).length;var a,s=t.getLabelModel(),l=u_(t),u=1;r>40&&(u=Math.ceil(r/40));for(var h=0;h0&&i>0||n<0&&i<0)}(t)}var HM=Math.PI,YM=function(){function t(t,e){this.group=new Pr,this.opt=e,this.axisModel=t,k(e,{labelOffset:0,nameDirection:1,tickDirection:1,labelDirection:1,silent:!0,handleAutoShown:function(){return!0}});var n=new Pr({x:e.position[0],y:e.position[1],rotation:e.rotation});n.updateTransform(),this._transformGroup=n}return t.prototype.hasBuilder=function(t){return!!UM[t]},t.prototype.add=function(t){UM[t](this.opt,this.axisModel,this.group,this._transformGroup)},t.prototype.getGroup=function(){return this.group},t.innerTextLayout=function(t,e,n){var i,r,o=Kr(e-t);return $r(o)?(r=n>0?"top":"bottom",i="center"):$r(o-HM)?(r=n>0?"bottom":"top",i="center"):(r="middle",i=o>0&&o0?"right":"left":n>0?"left":"right"),{rotation:o,textAlign:i,textVerticalAlign:r}},t.makeAxisEventDataBase=function(t){var e={componentType:t.mainType,componentIndex:t.componentIndex};return e[t.mainType+"Index"]=t.componentIndex,e},t.isLabelSilent=function(t){var e=t.get("tooltip");return t.get("silent")||!(t.get("triggerEvent")||e&&e.show)},t}(),UM={axisLine:function(t,e,n,i){var r=e.get(["axisLine","show"]);if("auto"===r&&t.handleAutoShown&&(r=t.handleAutoShown("axisLine")),r){var o=e.axis.getExtent(),a=i.transform,s=[o[0],0],l=[o[1],0],u=s[0]>l[0];a&&(Ft(s,s,a),Ft(l,l,a));var h=A({lineCap:"round"},e.getModel(["axisLine","lineStyle"]).getLineStyle()),c=new Wu({shape:{x1:s[0],y1:s[1],x2:l[0],y2:l[1]},style:h,strokeContainThreshold:t.strokeContainThreshold||5,silent:!0,z2:1});Ah(c.shape,c.style.lineWidth),c.anid="line",n.add(c);var p=e.get(["axisLine","symbol"]);if(null!=p){var d=e.get(["axisLine","symbolSize"]);X(p)&&(p=[p,p]),(X(d)||j(d))&&(d=[d,d]);var f=Ey(e.get(["axisLine","symbolOffset"])||0,d),g=d[0],y=d[1];E([{rotate:t.rotation+Math.PI/2,offset:f[0],r:0},{rotate:t.rotation-Math.PI/2,offset:f[1],r:Math.sqrt((s[0]-l[0])*(s[0]-l[0])+(s[1]-l[1])*(s[1]-l[1]))}],(function(e,i){if("none"!==p[i]&&null!=p[i]){var r=Ry(p[i],-g/2,-y/2,g,y,h.stroke,!0),o=e.r+e.offset,a=u?l:s;r.attr({rotation:e.rotate,x:a[0]+o*Math.cos(t.rotation),y:a[1]-o*Math.sin(t.rotation),silent:!0,z2:11}),n.add(r)}}))}}},axisTickLabel:function(t,e,n,i){var r=function(t,e,n,i){var r=n.axis,o=n.getModel("axisTick"),a=o.get("show");"auto"===a&&i.handleAutoShown&&(a=i.handleAutoShown("axisTick"));if(!a||r.scale.isBlank())return;for(var s=o.getModel("lineStyle"),l=i.tickDirection*o.get("length"),u=qM(r.getTicksCoords(),e.transform,l,k(s.getLineStyle(),{stroke:n.get(["axisLine","lineStyle","color"])}),"ticks"),h=0;hc[1]?-1:1,d=["start"===s?c[0]-p*h:"end"===s?c[1]+p*h:(c[0]+c[1])/2,jM(s)?t.labelOffset+l*h:0],f=e.get("nameRotate");null!=f&&(f=f*HM/180),jM(s)?o=YM.innerTextLayout(t.rotation,null!=f?f:t.rotation,l):(o=function(t,e,n,i){var r,o,a=Kr(n-t),s=i[0]>i[1],l="start"===e&&!s||"start"!==e&&s;$r(a-HM/2)?(o=l?"bottom":"top",r="center"):$r(a-1.5*HM)?(o=l?"top":"bottom",r="center"):(o="middle",r=a<1.5*HM&&a>HM/2?l?"left":"right":l?"right":"left");return{rotation:a,textAlign:r,textVerticalAlign:o}}(t.rotation,s,f||0,c),null!=(a=t.axisNameAvailableWidth)&&(a=Math.abs(a/Math.sin(o.rotation)),!isFinite(a)&&(a=null)));var g=u.getFont(),y=e.get("nameTruncate",!0)||{},v=y.ellipsis,m=it(t.nameTruncateMaxWidth,y.maxWidth,a),x=new Ns({x:d[0],y:d[1],rotation:o.rotation,silent:YM.isLabelSilent(e),style:$h(u,{text:r,font:g,overflow:"truncate",width:m,ellipsis:v,fill:u.getTextColor()||e.get(["axisLine","lineStyle","color"]),align:u.get("align")||o.textAlign,verticalAlign:u.get("verticalAlign")||o.textVerticalAlign}),z2:1});if(Wh({el:x,componentModel:e,itemName:r}),x.__fullText=r,x.anid="name",e.get("triggerEvent")){var _=YM.makeAxisEventDataBase(e);_.targetType="axisName",_.name=r,js(x).eventData=_}i.add(x),x.updateTransform(),n.add(x),x.decomposeTransform()}}};function XM(t){t&&(t.ignore=!0)}function ZM(t,e){var n=t&&t.getBoundingRect().clone(),i=e&&e.getBoundingRect().clone();if(n&&i){var r=ye([]);return _e(r,r,-t.rotation),n.applyTransform(me([],r,t.getLocalTransform())),i.applyTransform(me([],r,e.getLocalTransform())),n.intersect(i)}}function jM(t){return"middle"===t||"center"===t}function qM(t,e,n,i,r){for(var o=[],a=[],s=[],l=0;l=0||t===e}function JM(t){var e=QM(t);if(e){var n=e.axisPointerModel,i=e.axis.scale,r=n.option,o=n.get("status"),a=n.get("value");null!=a&&(a=i.parse(a));var s=tI(n);null==o&&(r.status=s?"show":"hide");var l=i.getExtent().slice();l[0]>l[1]&&l.reverse(),(null==a||a>l[1])&&(a=l[1]),a0&&!c.min?c.min=0:null!=c.min&&c.min<0&&!c.max&&(c.max=0);var p=a;null!=c.color&&(p=k({color:c.color},a));var d=C(T(c),{boundaryGap:t,splitNumber:e,scale:n,axisLine:i,axisTick:r,axisLabel:o,name:c.text,showName:s,nameLocation:"end",nameGap:u,nameTextStyle:p,triggerEvent:h},!1);if(X(l)){var f=d.name;d.name=l.replace("{value}",null!=f?f:"")}else U(l)&&(d.name=l(d.name,d));var g=new xc(d,null,this.ecModel);return R(g,g_.prototype),g.mainType="radar",g.componentIndex=this.componentIndex,g}),this);this._indicatorModels=c},e.prototype.getIndicatorModels=function(){return this._indicatorModels},e.type="radar",e.defaultOption={z:0,center:["50%","50%"],radius:"75%",startAngle:90,axisName:{show:!0},boundaryGap:[0,0],splitNumber:5,axisNameGap:15,scale:!1,shape:"polygon",axisLine:C({lineStyle:{color:"#bbb"}},wI.axisLine),axisLabel:SI(wI.axisLabel,!1),axisTick:SI(wI.axisTick,!1),splitLine:SI(wI.splitLine,!0),splitArea:SI(wI.splitArea,!0),indicator:[]},e}(Ap),II=["axisLine","axisTickLabel","axisName"],TI=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){this.group.removeAll(),this._buildAxes(t),this._buildSplitLineAndArea(t)},e.prototype._buildAxes=function(t){var e=t.coordinateSystem;E(z(e.getIndicatorAxes(),(function(t){var n=t.model.get("showName")?t.name:"";return new YM(t.model,{axisName:n,position:[e.cx,e.cy],rotation:t.angle,labelDirection:-1,tickDirection:-1,nameDirection:1})})),(function(t){E(II,t.add,t),this.group.add(t.getGroup())}),this)},e.prototype._buildSplitLineAndArea=function(t){var e=t.coordinateSystem,n=e.getIndicatorAxes();if(n.length){var i=t.get("shape"),r=t.getModel("splitLine"),o=t.getModel("splitArea"),a=r.getModel("lineStyle"),s=o.getModel("areaStyle"),l=r.get("show"),u=o.get("show"),h=a.get("color"),c=s.get("color"),p=Y(h)?h:[h],d=Y(c)?c:[c],f=[],g=[];if("circle"===i)for(var y=n[0].getTicksCoords(),v=e.cx,m=e.cy,x=0;x3?1.4:r>1?1.2:1.1;RI(this,"zoom","zoomOnMouseWheel",t,{scale:i>0?s:1/s,originX:o,originY:a,isAvailableBehavior:null})}if(n){var l=Math.abs(i);RI(this,"scrollMove","moveOnMouseWheel",t,{scrollDelta:(i>0?1:-1)*(l>3?.4:l>1?.15:.05),originX:o,originY:a,isAvailableBehavior:null})}}},e.prototype._pinchHandler=function(t){LI(this._zr,"globalPan")||RI(this,"zoom",null,t,{scale:t.pinchScale>1?1.1:1/1.1,originX:t.pinchX,originY:t.pinchY,isAvailableBehavior:null})},e}(Xt);function RI(t,e,n,i,r){t.pointerChecker&&t.pointerChecker(i,r.originX,r.originY)&&(he(i.event),NI(t,e,n,i,r))}function NI(t,e,n,i,r){r.isAvailableBehavior=W(EI,null,n,i),t.trigger(e,r)}function EI(t,e,n){var i=n[t];return!t||i&&(!X(i)||e.event[i+"Key"])}function zI(t,e,n){var i=t.target;i.x+=e,i.y+=n,i.dirty()}function VI(t,e,n,i){var r=t.target,o=t.zoomLimit,a=t.zoom=t.zoom||1;if(a*=e,o){var s=o.min||0,l=o.max||1/0;a=Math.max(Math.min(l,a),s)}var u=a/t.zoom;t.zoom=a,r.x-=(n-r.x)*(u-1),r.y-=(i-r.y)*(u-1),r.scaleX*=u,r.scaleY*=u,r.dirty()}var BI,FI={axisPointer:1,tooltip:1,brush:1};function GI(t,e,n){var i=e.getComponentByElement(t.topTarget),r=i&&i.coordinateSystem;return i&&i!==n&&!FI.hasOwnProperty(i.mainType)&&r&&r.model!==n}function WI(t){X(t)&&(t=(new DOMParser).parseFromString(t,"text/xml"));var e=t;for(9===e.nodeType&&(e=e.firstChild);"svg"!==e.nodeName.toLowerCase()||1!==e.nodeType;)e=e.nextSibling;return e}var HI={fill:"fill",stroke:"stroke","stroke-width":"lineWidth",opacity:"opacity","fill-opacity":"fillOpacity","stroke-opacity":"strokeOpacity","stroke-dasharray":"lineDash","stroke-dashoffset":"lineDashOffset","stroke-linecap":"lineCap","stroke-linejoin":"lineJoin","stroke-miterlimit":"miterLimit","font-family":"fontFamily","font-size":"fontSize","font-style":"fontStyle","font-weight":"fontWeight","text-anchor":"textAlign",visibility:"visibility",display:"display"},YI=G(HI),UI={"alignment-baseline":"textBaseline","stop-color":"stopColor"},XI=G(UI),ZI=function(){function t(){this._defs={},this._root=null}return t.prototype.parse=function(t,e){e=e||{};var n=WI(t);this._defsUsePending=[];var i=new Pr;this._root=i;var r=[],o=n.getAttribute("viewBox")||"",a=parseFloat(n.getAttribute("width")||e.width),s=parseFloat(n.getAttribute("height")||e.height);isNaN(a)&&(a=null),isNaN(s)&&(s=null),QI(n,i,null,!0,!1);for(var l,u,h=n.firstChild;h;)this._parseNode(h,i,r,null,!1,!1),h=h.nextSibling;if(function(t,e){for(var n=0;n=4&&(l={x:parseFloat(c[0]||0),y:parseFloat(c[1]||0),width:parseFloat(c[2]),height:parseFloat(c[3])})}if(l&&null!=a&&null!=s&&(u=lT(l,{x:0,y:0,width:a,height:s}),!e.ignoreViewBox)){var p=i;(i=new Pr).add(p),p.scaleX=p.scaleY=u.scale,p.x=u.x,p.y=u.y}return e.ignoreRootClip||null==a||null==s||i.setClipPath(new Ps({shape:{x:0,y:0,width:a,height:s}})),{root:i,width:a,height:s,viewBoxRect:l,viewBoxTransform:u,named:r}},t.prototype._parseNode=function(t,e,n,i,r,o){var a,s=t.nodeName.toLowerCase(),l=i;if("defs"===s&&(r=!0),"text"===s&&(o=!0),"defs"===s||"switch"===s)a=e;else{if(!r){var u=BI[s];if(u&&mt(BI,s)){a=u.call(this,t,e);var h=t.getAttribute("name");if(h){var c={name:h,namedFrom:null,svgNodeTagLower:s,el:a};n.push(c),"g"===s&&(l=c)}else i&&n.push({name:i.name,namedFrom:i,svgNodeTagLower:s,el:a});e.add(a)}}var p=jI[s];if(p&&mt(jI,s)){var d=p.call(this,t),f=t.getAttribute("id");f&&(this._defs[f]=d)}}if(a&&a.isGroup)for(var g=t.firstChild;g;)1===g.nodeType?this._parseNode(g,a,n,l,r,o):3===g.nodeType&&o&&this._parseText(g,a),g=g.nextSibling},t.prototype._parseText=function(t,e){var n=new ws({style:{text:t.textContent},silent:!0,x:this._textX||0,y:this._textY||0});$I(e,n),QI(t,n,this._defsUsePending,!1,!1),function(t,e){var n=e.__selfStyle;if(n){var i=n.textBaseline,r=i;i&&"auto"!==i?"baseline"===i?r="alphabetic":"before-edge"===i||"text-before-edge"===i?r="top":"after-edge"===i||"text-after-edge"===i?r="bottom":"central"!==i&&"mathematical"!==i||(r="middle"):r="alphabetic",t.style.textBaseline=r}var o=e.__inheritedStyle;if(o){var a=o.textAlign,s=a;a&&("middle"===a&&(s="center"),t.style.textAlign=s)}}(n,e);var i=n.style,r=i.fontSize;r&&r<9&&(i.fontSize=9,n.scaleX*=r/9,n.scaleY*=r/9);var o=(i.fontSize||i.fontFamily)&&[i.fontStyle,i.fontWeight,(i.fontSize||12)+"px",i.fontFamily||"sans-serif"].join(" ");i.font=o;var a=n.getBoundingRect();return this._textX+=a.width,e.add(n),n},t.internalField=void(BI={g:function(t,e){var n=new Pr;return $I(e,n),QI(t,n,this._defsUsePending,!1,!1),n},rect:function(t,e){var n=new Ps;return $I(e,n),QI(t,n,this._defsUsePending,!1,!1),n.setShape({x:parseFloat(t.getAttribute("x")||"0"),y:parseFloat(t.getAttribute("y")||"0"),width:parseFloat(t.getAttribute("width")||"0"),height:parseFloat(t.getAttribute("height")||"0")}),n.silent=!0,n},circle:function(t,e){var n=new gu;return $I(e,n),QI(t,n,this._defsUsePending,!1,!1),n.setShape({cx:parseFloat(t.getAttribute("cx")||"0"),cy:parseFloat(t.getAttribute("cy")||"0"),r:parseFloat(t.getAttribute("r")||"0")}),n.silent=!0,n},line:function(t,e){var n=new Wu;return $I(e,n),QI(t,n,this._defsUsePending,!1,!1),n.setShape({x1:parseFloat(t.getAttribute("x1")||"0"),y1:parseFloat(t.getAttribute("y1")||"0"),x2:parseFloat(t.getAttribute("x2")||"0"),y2:parseFloat(t.getAttribute("y2")||"0")}),n.silent=!0,n},ellipse:function(t,e){var n=new vu;return $I(e,n),QI(t,n,this._defsUsePending,!1,!1),n.setShape({cx:parseFloat(t.getAttribute("cx")||"0"),cy:parseFloat(t.getAttribute("cy")||"0"),rx:parseFloat(t.getAttribute("rx")||"0"),ry:parseFloat(t.getAttribute("ry")||"0")}),n.silent=!0,n},polygon:function(t,e){var n,i=t.getAttribute("points");i&&(n=JI(i));var r=new zu({shape:{points:n||[]},silent:!0});return $I(e,r),QI(t,r,this._defsUsePending,!1,!1),r},polyline:function(t,e){var n,i=t.getAttribute("points");i&&(n=JI(i));var r=new Bu({shape:{points:n||[]},silent:!0});return $I(e,r),QI(t,r,this._defsUsePending,!1,!1),r},image:function(t,e){var n=new Is;return $I(e,n),QI(t,n,this._defsUsePending,!1,!1),n.setStyle({image:t.getAttribute("xlink:href")||t.getAttribute("href"),x:+t.getAttribute("x"),y:+t.getAttribute("y"),width:+t.getAttribute("width"),height:+t.getAttribute("height")}),n.silent=!0,n},text:function(t,e){var n=t.getAttribute("x")||"0",i=t.getAttribute("y")||"0",r=t.getAttribute("dx")||"0",o=t.getAttribute("dy")||"0";this._textX=parseFloat(n)+parseFloat(r),this._textY=parseFloat(i)+parseFloat(o);var a=new Pr;return $I(e,a),QI(t,a,this._defsUsePending,!1,!0),a},tspan:function(t,e){var n=t.getAttribute("x"),i=t.getAttribute("y");null!=n&&(this._textX=parseFloat(n)),null!=i&&(this._textY=parseFloat(i));var r=t.getAttribute("dx")||"0",o=t.getAttribute("dy")||"0",a=new Pr;return $I(e,a),QI(t,a,this._defsUsePending,!1,!0),this._textX+=parseFloat(r),this._textY+=parseFloat(o),a},path:function(t,e){var n=pu(t.getAttribute("d")||"");return $I(e,n),QI(t,n,this._defsUsePending,!1,!1),n.silent=!0,n}}),t}(),jI={lineargradient:function(t){var e=parseInt(t.getAttribute("x1")||"0",10),n=parseInt(t.getAttribute("y1")||"0",10),i=parseInt(t.getAttribute("x2")||"10",10),r=parseInt(t.getAttribute("y2")||"0",10),o=new $u(e,n,i,r);return qI(t,o),KI(t,o),o},radialgradient:function(t){var e=parseInt(t.getAttribute("cx")||"0",10),n=parseInt(t.getAttribute("cy")||"0",10),i=parseInt(t.getAttribute("r")||"0",10),r=new Ju(e,n,i);return qI(t,r),KI(t,r),r}};function qI(t,e){"userSpaceOnUse"===t.getAttribute("gradientUnits")&&(e.global=!0)}function KI(t,e){for(var n=t.firstChild;n;){if(1===n.nodeType&&"stop"===n.nodeName.toLocaleLowerCase()){var i=n.getAttribute("offset"),r=void 0;r=i&&i.indexOf("%")>0?parseInt(i,10)/100:i?parseFloat(i):0;var o={};sT(n,o,o);var a=o.stopColor||n.getAttribute("stop-color")||"#000000";e.colorStops.push({offset:r,color:a})}n=n.nextSibling}}function $I(t,e){t&&t.__inheritedStyle&&(e.__inheritedStyle||(e.__inheritedStyle={}),k(e.__inheritedStyle,t.__inheritedStyle))}function JI(t){for(var e=iT(t),n=[],i=0;i0;o-=2){var a=i[o],s=i[o-1],l=iT(a);switch(r=r||[1,0,0,1,0,0],s){case"translate":xe(r,r,[parseFloat(l[0]),parseFloat(l[1]||"0")]);break;case"scale":be(r,r,[parseFloat(l[0]),parseFloat(l[1]||l[0])]);break;case"rotate":_e(r,r,-parseFloat(l[0])*oT);break;case"skewX":me(r,[1,0,Math.tan(parseFloat(l[0])*oT),1,0,0],r);break;case"skewY":me(r,[1,Math.tan(parseFloat(l[0])*oT),0,1,0,0],r);break;case"matrix":r[0]=parseFloat(l[0]),r[1]=parseFloat(l[1]),r[2]=parseFloat(l[2]),r[3]=parseFloat(l[3]),r[4]=parseFloat(l[4]),r[5]=parseFloat(l[5])}}e.setLocalTransform(r)}}(t,e),sT(t,a,s),i||function(t,e,n){for(var i=0;i0,f={api:n,geo:s,mapOrGeoModel:t,data:a,isVisualEncodedByVisualMap:d,isGeo:o,transformInfoRaw:c};"geoJSON"===s.resourceType?this._buildGeoJSON(f):"geoSVG"===s.resourceType&&this._buildSVG(f),this._updateController(t,e,n),this._updateMapSelectHandler(t,l,n,i)},t.prototype._buildGeoJSON=function(t){var e=this._regionsGroupByName=ft(),n=ft(),i=this._regionsGroup,r=t.transformInfoRaw,o=t.mapOrGeoModel,a=t.data,s=t.geo.projection,l=s&&s.stream;function u(t,e){return e&&(t=e(t)),t&&[t[0]*r.scaleX+r.x,t[1]*r.scaleY+r.y]}function h(t){for(var e=[],n=!l&&s&&s.project,i=0;i=0)&&(p=r);var d=a?{normal:{align:"center",verticalAlign:"middle"}}:null;qh(e,Kh(i),{labelFetcher:p,labelDataIndex:c,defaultText:n},d);var f=e.getTextContent();if(f&&(AT(f).ignore=f.ignore,e.textConfig&&a)){var g=e.getBoundingRect().clone();e.textConfig.layoutRect=g,e.textConfig.position=[(a[0]-g.x)/g.width*100+"%",(a[1]-g.y)/g.height*100+"%"]}e.disableLabelAnimation=!0}else e.removeTextContent(),e.removeTextConfig(),e.disableLabelAnimation=null}function NT(t,e,n,i,r,o){t.data?t.data.setItemGraphicEl(o,e):js(e).eventData={componentType:"geo",componentIndex:r.componentIndex,geoIndex:r.componentIndex,name:n,region:i&&i.option||{}}}function ET(t,e,n,i,r){t.data||Wh({el:e,componentModel:r,itemName:n,itemTooltipOption:i.get("tooltip")})}function zT(t,e,n,i,r){e.highDownSilentOnTouch=!!r.get("selectedMode");var o=i.getModel("emphasis"),a=o.get("focus");return Bl(e,a,o.get("blurScope"),o.get("disabled")),t.isGeo&&function(t,e,n){var i=js(t);i.componentMainType=e.mainType,i.componentIndex=e.componentIndex,i.componentHighDownName=n}(e,r,n),a}function VT(t,e,n){var i,r=[];function o(){i=[]}function a(){i.length&&(r.push(i),i=[])}var s=e({polygonStart:o,polygonEnd:a,lineStart:o,lineEnd:a,point:function(t,e){isFinite(t)&&isFinite(e)&&i.push([t,e])},sphere:function(){}});return!n&&s.polygonStart(),E(t,(function(t){s.lineStart();for(var e=0;e-1&&(n.style.stroke=n.style.fill,n.style.fill="#fff",n.style.lineWidth=2),n},e.type="series.map",e.dependencies=["geo"],e.layoutMode="box",e.defaultOption={z:2,coordinateSystem:"geo",map:"",left:"center",top:"center",aspectScale:null,showLegendSymbol:!0,boundingCoords:null,center:null,zoom:1,scaleLimit:null,selectedMode:!0,label:{show:!1,color:"#000"},itemStyle:{borderWidth:.5,borderColor:"#444",areaColor:"#eee"},emphasis:{label:{show:!0,color:"rgb(100,0,0)"},itemStyle:{areaColor:"rgba(255,215,0,0.8)"}},select:{label:{show:!0,color:"rgb(100,0,0)"},itemStyle:{color:"rgba(255,215,0,0.8)"}},nameProperty:"name"},e}(hg);function GT(t){var e={};t.eachSeriesByType("map",(function(t){var n=t.getHostGeoModel(),i=n?"o"+n.id:"i"+t.getMapType();(e[i]=e[i]||[]).push(t)})),E(e,(function(t,e){for(var n,i,r,o=(n=z(t,(function(t){return t.getData()})),i=t[0].get("mapValueCalculation"),r={},E(n,(function(t){t.each(t.mapDimension("value"),(function(e,n){var i="ec-"+t.getName(n);r[i]=r[i]||[],isNaN(e)||r[i].push(e)}))})),n[0].map(n[0].mapDimension("value"),(function(t,e){for(var o="ec-"+n[0].getName(e),a=0,s=1/0,l=-1/0,u=r[o].length,h=0;h1?(d.width=p,d.height=p/x):(d.height=p,d.width=p*x),d.y=c[1]-d.height/2,d.x=c[0]-d.width/2;else{var b=t.getBoxLayoutParams();b.aspect=x,d=wp(b,{width:v,height:m})}this.setViewRect(d.x,d.y,d.width,d.height),this.setCenter(t.get("center"),e),this.setZoom(t.get("zoom"))}R(jT,YT);var $T=function(){function t(){this.dimensions=ZT}return t.prototype.create=function(t,e){var n=[];function i(t){return{nameProperty:t.get("nameProperty"),aspectScale:t.get("aspectScale"),projection:t.get("projection")}}t.eachComponent("geo",(function(t,r){var o=t.get("map"),a=new jT(o+r,o,A({nameMap:t.get("nameMap")},i(t)));a.zoomLimit=t.get("scaleLimit"),n.push(a),t.coordinateSystem=a,a.model=t,a.resize=KT,a.resize(t,e)})),t.eachSeries((function(t){if("geo"===t.get("coordinateSystem")){var e=t.get("geoIndex")||0;t.coordinateSystem=n[e]}}));var r={};return t.eachSeriesByType("map",(function(t){if(!t.getHostGeoModel()){var e=t.getMapType();r[e]=r[e]||[],r[e].push(t)}})),E(r,(function(t,r){var o=z(t,(function(t){return t.get("nameMap")})),a=new jT(r,r,A({nameMap:D(o)},i(t[0])));a.zoomLimit=it.apply(null,z(t,(function(t){return t.get("scaleLimit")}))),n.push(a),a.resize=KT,a.resize(t[0],e),E(t,(function(t){t.coordinateSystem=a,function(t,e){E(e.get("geoCoord"),(function(e,n){t.addGeoCoord(n,e)}))}(a,t)}))})),n},t.prototype.getFilledRegions=function(t,e,n,i){for(var r=(t||[]).slice(),o=ft(),a=0;a=0;){var o=e[n];o.hierNode.prelim+=i,o.hierNode.modifier+=i,r+=o.hierNode.change,i+=o.hierNode.shift+r}}(t);var o=(n[0].hierNode.prelim+n[n.length-1].hierNode.prelim)/2;r?(t.hierNode.prelim=r.hierNode.prelim+e(t,r),t.hierNode.modifier=t.hierNode.prelim-o):t.hierNode.prelim=o}else r&&(t.hierNode.prelim=r.hierNode.prelim+e(t,r));t.parentNode.hierNode.defaultAncestor=function(t,e,n,i){if(e){for(var r=t,o=t,a=o.parentNode.children[0],s=e,l=r.hierNode.modifier,u=o.hierNode.modifier,h=a.hierNode.modifier,c=s.hierNode.modifier;s=uC(s),o=hC(o),s&&o;){r=uC(r),a=hC(a),r.hierNode.ancestor=t;var p=s.hierNode.prelim+c-o.hierNode.prelim-u+i(s,o);p>0&&(pC(cC(s,t,n),t,p),u+=p,l+=p),c+=s.hierNode.modifier,u+=o.hierNode.modifier,l+=r.hierNode.modifier,h+=a.hierNode.modifier}s&&!uC(r)&&(r.hierNode.thread=s,r.hierNode.modifier+=c-l),o&&!hC(a)&&(a.hierNode.thread=o,a.hierNode.modifier+=u-h,n=t)}return n}(t,r,t.parentNode.hierNode.defaultAncestor||i[0],e)}function aC(t){var e=t.hierNode.prelim+t.parentNode.hierNode.modifier;t.setLayout({x:e},!0),t.hierNode.modifier+=t.parentNode.hierNode.modifier}function sC(t){return arguments.length?t:dC}function lC(t,e){return t-=Math.PI/2,{x:e*Math.cos(t),y:e*Math.sin(t)}}function uC(t){var e=t.children;return e.length&&t.isExpand?e[e.length-1]:t.hierNode.thread}function hC(t){var e=t.children;return e.length&&t.isExpand?e[0]:t.hierNode.thread}function cC(t,e,n){return t.hierNode.ancestor.parentNode===e.parentNode?t.hierNode.ancestor:n}function pC(t,e,n){var i=n/(e.hierNode.i-t.hierNode.i);e.hierNode.change-=i,e.hierNode.shift+=n,e.hierNode.modifier+=n,e.hierNode.prelim+=n,t.hierNode.change+=i}function dC(t,e){return t.parentNode===e.parentNode?1:2}var fC=function(){this.parentPoint=[],this.childPoints=[]},gC=function(t){function e(e){return t.call(this,e)||this}return n(e,t),e.prototype.getDefaultStyle=function(){return{stroke:"#000",fill:null}},e.prototype.getDefaultShape=function(){return new fC},e.prototype.buildPath=function(t,e){var n=e.childPoints,i=n.length,r=e.parentPoint,o=n[0],a=n[i-1];if(1===i)return t.moveTo(r[0],r[1]),void t.lineTo(o[0],o[1]);var s=e.orient,l="TB"===s||"BT"===s?0:1,u=1-l,h=Gr(e.forkPosition,1),c=[];c[l]=r[l],c[u]=r[u]+(a[u]-r[u])*h,t.moveTo(r[0],r[1]),t.lineTo(c[0],c[1]),t.moveTo(o[0],o[1]),c[l]=o[l],t.lineTo(c[0],c[1]),c[l]=a[l],t.lineTo(c[0],c[1]),t.lineTo(a[0],a[1]);for(var p=1;pm.x)||(_-=Math.PI);var S=b?"left":"right",M=s.getModel("label"),I=M.get("rotate"),T=I*(Math.PI/180),C=y.getTextContent();C&&(y.setTextConfig({position:M.get("position")||S,rotation:null==I?-_:T,origin:"center"}),C.setStyle("verticalAlign","middle"))}var D=s.get(["emphasis","focus"]),A="relative"===D?gt(a.getAncestorsIndices(),a.getDescendantIndices()):"ancestor"===D?a.getAncestorsIndices():"descendant"===D?a.getDescendantIndices():null;A&&(js(n).focus=A),function(t,e,n,i,r,o,a,s){var l=e.getModel(),u=t.get("edgeShape"),h=t.get("layout"),c=t.getOrient(),p=t.get(["lineStyle","curveness"]),d=t.get("edgeForkPosition"),f=l.getModel("lineStyle").getLineStyle(),g=i.__edge;if("curve"===u)e.parentNode&&e.parentNode!==n&&(g||(g=i.__edge=new Xu({shape:wC(h,c,p,r,r)})),uh(g,{shape:wC(h,c,p,o,a)},t));else if("polyline"===u)if("orthogonal"===h){if(e!==n&&e.children&&0!==e.children.length&&!0===e.isExpand){for(var y=e.children,v=[],m=0;me&&(e=i.height)}this.height=e+1},t.prototype.getNodeById=function(t){if(this.getId()===t)return this;for(var e=0,n=this.children,i=n.length;e=0&&this.hostTree.data.setItemLayout(this.dataIndex,t,e)},t.prototype.getLayout=function(){return this.hostTree.data.getItemLayout(this.dataIndex)},t.prototype.getModel=function(t){if(!(this.dataIndex<0))return this.hostTree.data.getItemModel(this.dataIndex).getModel(t)},t.prototype.getLevelModel=function(){return(this.hostTree.levelModels||[])[this.depth]},t.prototype.setVisual=function(t,e){this.dataIndex>=0&&this.hostTree.data.setItemVisual(this.dataIndex,t,e)},t.prototype.getVisual=function(t){return this.hostTree.data.getItemVisual(this.dataIndex,t)},t.prototype.getRawIndex=function(){return this.hostTree.data.getRawIndex(this.dataIndex)},t.prototype.getId=function(){return this.hostTree.data.getId(this.dataIndex)},t.prototype.getChildIndex=function(){if(this.parentNode){for(var t=this.parentNode.children,e=0;e=0){var i=n.getData().tree.root,r=t.targetNode;if(X(r)&&(r=i.getNodeById(r)),r&&i.contains(r))return{node:r};var o=t.targetNodeId;if(null!=o&&(r=i.getNodeById(o)))return{node:r}}}function NC(t){for(var e=[];t;)(t=t.parentNode)&&e.push(t);return e.reverse()}function EC(t,e){return P(NC(t),e)>=0}function zC(t,e){for(var n=[];t;){var i=t.dataIndex;n.push({name:t.name,dataIndex:i,value:e.getRawValue(i)}),t=t.parentNode}return n.reverse(),n}var VC=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.hasSymbolVisual=!0,e.ignoreStyleOnData=!0,e}return n(e,t),e.prototype.getInitialData=function(t){var e={name:t.name,children:t.data},n=t.leaves||{},i=new xc(n,this,this.ecModel),r=OC.createTree(e,this,(function(t){t.wrapMethod("getItemModel",(function(t,e){var n=r.getNodeByDataIndex(e);return n&&n.children.length&&n.isExpand||(t.parentModel=i),t}))}));var o=0;r.eachNode("preorder",(function(t){t.depth>o&&(o=t.depth)}));var a=t.expandAndCollapse&&t.initialTreeDepth>=0?t.initialTreeDepth:o;return r.root.eachNode("preorder",(function(t){var e=t.hostTree.data.getRawDataItem(t.dataIndex);t.isExpand=e&&null!=e.collapsed?!e.collapsed:t.depth<=a})),r.data},e.prototype.getOrient=function(){var t=this.get("orient");return"horizontal"===t?t="LR":"vertical"===t&&(t="TB"),t},e.prototype.setZoom=function(t){this.option.zoom=t},e.prototype.setCenter=function(t){this.option.center=t},e.prototype.formatTooltip=function(t,e,n){for(var i=this.getData().tree,r=i.root.children[0],o=i.getNodeByDataIndex(t),a=o.getValue(),s=o.name;o&&o!==r;)s=o.parentNode.name+"."+s,o=o.parentNode;return qf("nameValue",{name:s,value:a,noValue:isNaN(a)||null==a})},e.prototype.getDataParams=function(e){var n=t.prototype.getDataParams.apply(this,arguments),i=this.getData().tree.getNodeByDataIndex(e);return n.treeAncestors=zC(i,this),n.collapsed=!i.isExpand,n},e.type="series.tree",e.layoutMode="box",e.defaultOption={z:2,coordinateSystem:"view",left:"12%",top:"12%",right:"12%",bottom:"12%",layout:"orthogonal",edgeShape:"curve",edgeForkPosition:"50%",roam:!1,nodeScaleRatio:.4,center:null,zoom:1,orient:"LR",symbol:"emptyCircle",symbolSize:7,expandAndCollapse:!0,initialTreeDepth:2,lineStyle:{color:"#ccc",width:1.5,curveness:.5},itemStyle:{color:"lightsteelblue",borderWidth:1.5},label:{show:!0},animationEasing:"linear",animationDuration:700,animationDurationUpdate:500},e}(hg);function BC(t,e){for(var n,i=[t];n=i.pop();)if(e(n),n.isExpand){var r=n.children;if(r.length)for(var o=r.length-1;o>=0;o--)i.push(r[o])}}function FC(t,e){t.eachSeriesByType("tree",(function(t){!function(t,e){var n=function(t,e){return wp(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()})}(t,e);t.layoutInfo=n;var i=t.get("layout"),r=0,o=0,a=null;"radial"===i?(r=2*Math.PI,o=Math.min(n.height,n.width)/2,a=sC((function(t,e){return(t.parentNode===e.parentNode?1:2)/t.depth}))):(r=n.width,o=n.height,a=sC());var s=t.getData().tree.root,l=s.children[0];if(l){!function(t){var e=t;e.hierNode={defaultAncestor:null,ancestor:e,prelim:0,modifier:0,change:0,shift:0,i:0,thread:null};for(var n,i,r=[e];n=r.pop();)if(i=n.children,n.isExpand&&i.length)for(var o=i.length-1;o>=0;o--){var a=i[o];a.hierNode={defaultAncestor:null,ancestor:a,prelim:0,modifier:0,change:0,shift:0,i:o,thread:null},r.push(a)}}(s),function(t,e,n){for(var i,r=[t],o=[];i=r.pop();)if(o.push(i),i.isExpand){var a=i.children;if(a.length)for(var s=0;sh.getLayout().x&&(h=t),t.depth>c.depth&&(c=t)}));var p=u===h?1:a(u,h)/2,d=p-u.getLayout().x,f=0,g=0,y=0,v=0;if("radial"===i)f=r/(h.getLayout().x+p+d),g=o/(c.depth-1||1),BC(l,(function(t){y=(t.getLayout().x+d)*f,v=(t.depth-1)*g;var e=lC(y,v);t.setLayout({x:e.x,y:e.y,rawX:y,rawY:v},!0)}));else{var m=t.getOrient();"RL"===m||"LR"===m?(g=o/(h.getLayout().x+p+d),f=r/(c.depth-1||1),BC(l,(function(t){v=(t.getLayout().x+d)*g,y="LR"===m?(t.depth-1)*f:r-(t.depth-1)*f,t.setLayout({x:y,y:v},!0)}))):"TB"!==m&&"BT"!==m||(f=r/(h.getLayout().x+p+d),g=o/(c.depth-1||1),BC(l,(function(t){y=(t.getLayout().x+d)*f,v="TB"===m?(t.depth-1)*g:o-(t.depth-1)*g,t.setLayout({x:y,y:v},!0)})))}}}(t,e)}))}function GC(t){t.eachSeriesByType("tree",(function(t){var e=t.getData();e.tree.eachNode((function(t){var n=t.getModel().getModel("itemStyle").getItemStyle();A(e.ensureUniqueItemVisual(t.dataIndex,"style"),n)}))}))}var WC=["treemapZoomToNode","treemapRender","treemapMove"];function HC(t){var e=t.getData().tree,n={};e.eachNode((function(e){for(var i=e;i&&i.depth>1;)i=i.parentNode;var r=rd(t.ecModel,i.name||i.dataIndex+"",n);e.setVisual("decal",r)}))}var YC=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.preventUsingHoverLayer=!0,n}return n(e,t),e.prototype.getInitialData=function(t,e){var n={name:t.name,children:t.data};UC(n);var i=t.levels||[],r=this.designatedVisualItemStyle={},o=new xc({itemStyle:r},this,e);i=t.levels=function(t,e){var n,i,r=yo(e.get("color")),o=yo(e.get(["aria","decal","decals"]));if(!r)return;E(t=t||[],(function(t){var e=new xc(t),r=e.get("color"),o=e.get("decal");(e.get(["itemStyle","color"])||r&&"none"!==r)&&(n=!0),(e.get(["itemStyle","decal"])||o&&"none"!==o)&&(i=!0)}));var a=t[0]||(t[0]={});n||(a.color=r.slice());!i&&o&&(a.decal=o.slice());return t}(i,e);var a=z(i||[],(function(t){return new xc(t,o,e)}),this),s=OC.createTree(n,this,(function(t){t.wrapMethod("getItemModel",(function(t,e){var n=s.getNodeByDataIndex(e),i=n?a[n.depth]:null;return t.parentModel=i||o,t}))}));return s.data},e.prototype.optionUpdated=function(){this.resetViewRoot()},e.prototype.formatTooltip=function(t,e,n){var i=this.getData(),r=this.getRawValue(t);return qf("nameValue",{name:i.getName(t),value:r})},e.prototype.getDataParams=function(e){var n=t.prototype.getDataParams.apply(this,arguments),i=this.getData().tree.getNodeByDataIndex(e);return n.treeAncestors=zC(i,this),n.treePathInfo=n.treeAncestors,n},e.prototype.setLayoutInfo=function(t){this.layoutInfo=this.layoutInfo||{},A(this.layoutInfo,t)},e.prototype.mapIdToIndex=function(t){var e=this._idIndexMap;e||(e=this._idIndexMap=ft(),this._idIndexMapCount=0);var n=e.get(t);return null==n&&e.set(t,n=this._idIndexMapCount++),n},e.prototype.getViewRoot=function(){return this._viewRoot},e.prototype.resetViewRoot=function(t){t?this._viewRoot=t:t=this._viewRoot;var e=this.getRawData().tree.root;t&&(t===e||e.contains(t))||(this._viewRoot=e)},e.prototype.enableAriaDecal=function(){HC(this)},e.type="series.treemap",e.layoutMode="box",e.defaultOption={progressive:0,left:"center",top:"middle",width:"80%",height:"80%",sort:!0,clipWindow:"origin",squareRatio:.5*(1+Math.sqrt(5)),leafDepth:null,drillDownIcon:"▶",zoomToNodeRatio:.1024,roam:!0,nodeClick:"zoomToNode",animation:!0,animationDurationUpdate:900,animationEasing:"quinticInOut",breadcrumb:{show:!0,height:22,left:"center",top:"bottom",emptyItemWidth:25,itemStyle:{color:"rgba(0,0,0,0.7)",textStyle:{color:"#fff"}},emphasis:{itemStyle:{color:"rgba(0,0,0,0.9)"}}},label:{show:!0,distance:0,padding:5,position:"inside",color:"#fff",overflow:"truncate"},upperLabel:{show:!1,position:[0,"50%"],height:20,overflow:"truncate",verticalAlign:"middle"},itemStyle:{color:null,colorAlpha:null,colorSaturation:null,borderWidth:0,gapWidth:0,borderColor:"#fff",borderColorSaturation:null},emphasis:{upperLabel:{show:!0,position:[0,"50%"],overflow:"truncate",verticalAlign:"middle"}},visualDimension:0,visualMin:null,visualMax:null,color:[],colorAlpha:null,colorSaturation:null,colorMappingBy:"index",visibleMin:10,childrenVisibleMin:null,levels:[]},e}(hg);function UC(t){var e=0;E(t.children,(function(t){UC(t);var n=t.value;Y(n)&&(n=n[0]),e+=n}));var n=t.value;Y(n)&&(n=n[0]),(null==n||isNaN(n))&&(n=e),n<0&&(n=0),Y(t.value)?t.value[0]=n:t.value=n}var XC=function(){function t(t){this.group=new Pr,t.add(this.group)}return t.prototype.render=function(t,e,n,i){var r=t.getModel("breadcrumb"),o=this.group;if(o.removeAll(),r.get("show")&&n){var a=r.getModel("itemStyle"),s=r.getModel("emphasis"),l=a.getModel("textStyle"),u=s.getModel(["itemStyle","textStyle"]),h={pos:{left:r.get("left"),right:r.get("right"),top:r.get("top"),bottom:r.get("bottom")},box:{width:e.getWidth(),height:e.getHeight()},emptyItemWidth:r.get("emptyItemWidth"),totalWidth:0,renderList:[]};this._prepare(n,h,l),this._renderContent(t,h,a,s,l,u,i),Sp(o,h.pos,h.box)}},t.prototype._prepare=function(t,e,n){for(var i=t;i;i=i.parentNode){var r=Mo(i.getModel().get("name"),""),o=n.getTextRect(r),a=Math.max(o.width+16,e.emptyItemWidth);e.totalWidth+=a+8,e.renderList.push({node:i,text:r,width:a})}},t.prototype._renderContent=function(t,e,n,i,r,o,a){for(var s,l,u,h,c,p,d,f,g,y=0,v=e.emptyItemWidth,m=t.get(["breadcrumb","height"]),x=(s=e.pos,l=e.box,h=l.width,c=l.height,p=Gr(s.left,h),d=Gr(s.top,c),f=Gr(s.right,h),g=Gr(s.bottom,c),(isNaN(p)||isNaN(parseFloat(s.left)))&&(p=0),(isNaN(f)||isNaN(parseFloat(s.right)))&&(f=h),(isNaN(d)||isNaN(parseFloat(s.top)))&&(d=0),(isNaN(g)||isNaN(parseFloat(s.bottom)))&&(g=c),u=up(u||0),{width:Math.max(f-p-u[1]-u[3],0),height:Math.max(g-d-u[0]-u[2],0)}),_=e.totalWidth,b=e.renderList,w=i.getModel("itemStyle").getItemStyle(),S=b.length-1;S>=0;S--){var M=b[S],I=M.node,T=M.width,C=M.text;_>x.width&&(_-=T-v,T=v,C=null);var D=new zu({shape:{points:ZC(y,0,T,m,S===b.length-1,0===S)},style:k(n.getItemStyle(),{lineJoin:"bevel"}),textContent:new Ns({style:$h(r,{text:C})}),textConfig:{position:"inside"},z2:1e5,onclick:H(a,I)});D.disableLabelAnimation=!0,D.getTextContent().ensureState("emphasis").style=$h(o,{text:C}),D.ensureState("emphasis").style=w,Bl(D,i.get("focus"),i.get("blurScope"),i.get("disabled")),this.group.add(D),jC(D,t,I),y+=T+8}},t.prototype.remove=function(){this.group.removeAll()},t}();function ZC(t,e,n,i,r,o){var a=[[r?t:t-5,e],[t+n,e],[t+n,e+i],[r?t:t-5,e+i]];return!o&&a.splice(2,0,[t+n+5,e+i/2]),!r&&a.push([t,e+i/2]),a}function jC(t,e,n){js(t).eventData={componentType:"series",componentSubType:"treemap",componentIndex:e.componentIndex,seriesIndex:e.seriesIndex,seriesName:e.name,seriesType:"treemap",selfType:"breadcrumb",nodeData:{dataIndex:n&&n.dataIndex,name:n&&n.name},treePathInfo:n&&zC(n,e)}}var qC=function(){function t(){this._storage=[],this._elExistsMap={}}return t.prototype.add=function(t,e,n,i,r){return!this._elExistsMap[t.id]&&(this._elExistsMap[t.id]=!0,this._storage.push({el:t,target:e,duration:n,delay:i,easing:r}),!0)},t.prototype.finished=function(t){return this._finishedCallback=t,this},t.prototype.start=function(){for(var t=this,e=this._storage.length,n=function(){--e<=0&&(t._storage.length=0,t._elExistsMap={},t._finishedCallback&&t._finishedCallback())},i=0,r=this._storage.length;i3||Math.abs(t.dy)>3)){var e=this.seriesModel.getData().tree.root;if(!e)return;var n=e.getLayout();if(!n)return;this.api.dispatchAction({type:"treemapMove",from:this.uid,seriesId:this.seriesModel.id,rootRect:{x:n.x+t.dx,y:n.y+t.dy,width:n.width,height:n.height}})}},e.prototype._onZoom=function(t){var e=t.originX,n=t.originY;if("animating"!==this._state){var i=this.seriesModel.getData().tree.root;if(!i)return;var r=i.getLayout();if(!r)return;var o=new Re(r.x,r.y,r.width,r.height),a=this.seriesModel.layoutInfo,s=[1,0,0,1,0,0];xe(s,s,[-(e-=a.x),-(n-=a.y)]),be(s,s,[t.scale,t.scale]),xe(s,s,[e,n]),o.applyTransform(s),this.api.dispatchAction({type:"treemapRender",from:this.uid,seriesId:this.seriesModel.id,rootRect:{x:o.x,y:o.y,width:o.width,height:o.height}})}},e.prototype._initEvents=function(t){var e=this;t.on("click",(function(t){if("ready"===e._state){var n=e.seriesModel.get("nodeClick",!0);if(n){var i=e.findTarget(t.offsetX,t.offsetY);if(i){var r=i.node;if(r.getLayout().isLeafRoot)e._rootToNode(i);else if("zoomToNode"===n)e._zoomToNode(i);else if("link"===n){var o=r.hostTree.data.getItemModel(r.dataIndex),a=o.get("link",!0),s=o.get("target",!0)||"blank";a&&yp(a,s)}}}}}),this)},e.prototype._renderBreadcrumb=function(t,e,n){var i=this;n||(n=null!=t.get("leafDepth",!0)?{node:t.getViewRoot()}:this.findTarget(e.getWidth()/2,e.getHeight()/2))||(n={node:t.getData().tree.root}),(this._breadcrumb||(this._breadcrumb=new XC(this.group))).render(t,e,n.node,(function(e){"animating"!==i._state&&(EC(t.getViewRoot(),e)?i._rootToNode({node:e}):i._zoomToNode({node:e}))}))},e.prototype.remove=function(){this._clearController(),this._containerGroup&&this._containerGroup.removeAll(),this._storage={nodeGroup:[],background:[],content:[]},this._state="ready",this._breadcrumb&&this._breadcrumb.remove()},e.prototype.dispose=function(){this._clearController()},e.prototype._zoomToNode=function(t){this.api.dispatchAction({type:"treemapZoomToNode",from:this.uid,seriesId:this.seriesModel.id,targetNode:t.node})},e.prototype._rootToNode=function(t){this.api.dispatchAction({type:"treemapRootToNode",from:this.uid,seriesId:this.seriesModel.id,targetNode:t.node})},e.prototype.findTarget=function(t,e){var n;return this.seriesModel.getViewRoot().eachNode({attr:"viewChildren",order:"preorder"},(function(i){var r=this._storage.background[i.getRawIndex()];if(r){var o=r.transformCoordToLocal(t,e),a=r.shape;if(!(a.x<=o[0]&&o[0]<=a.x+a.width&&a.y<=o[1]&&o[1]<=a.y+a.height))return!1;n={node:i,offsetX:o[0],offsetY:o[1]}}}),this),n},e.type="treemap",e}(wg);var rD=E,oD=q,aD=-1,sD=function(){function t(e){var n=e.mappingMethod,i=e.type,r=this.option=T(e);this.type=i,this.mappingMethod=n,this._normalizeData=vD[n];var o=t.visualHandlers[i];this.applyVisual=o.applyVisual,this.getColorMapper=o.getColorMapper,this._normalizedToVisual=o._normalizedToVisual[n],"piecewise"===n?(lD(r),function(t){var e=t.pieceList;t.hasSpecialVisual=!1,E(e,(function(e,n){e.originIndex=n,null!=e.visual&&(t.hasSpecialVisual=!0)}))}(r)):"category"===n?r.categories?function(t){var e=t.categories,n=t.categoryMap={},i=t.visual;if(rD(e,(function(t,e){n[t]=e})),!Y(i)){var r=[];q(i)?rD(i,(function(t,e){var i=n[e];r[null!=i?i:aD]=t})):r[-1]=i,i=yD(t,r)}for(var o=e.length-1;o>=0;o--)null==i[o]&&(delete n[e[o]],e.pop())}(r):lD(r,!0):(lt("linear"!==n||r.dataExtent),lD(r))}return t.prototype.mapValueToVisual=function(t){var e=this._normalizeData(t);return this._normalizedToVisual(e,t)},t.prototype.getNormalizer=function(){return W(this._normalizeData,this)},t.listVisualTypes=function(){return G(t.visualHandlers)},t.isValidType=function(e){return t.visualHandlers.hasOwnProperty(e)},t.eachVisual=function(t,e,n){q(t)?E(t,e,n):e.call(n,t)},t.mapVisual=function(e,n,i){var r,o=Y(e)?[]:q(e)?{}:(r=!0,null);return t.eachVisual(e,(function(t,e){var a=n.call(i,t,e);r?o=a:o[e]=a})),o},t.retrieveVisuals=function(e){var n,i={};return e&&rD(t.visualHandlers,(function(t,r){e.hasOwnProperty(r)&&(i[r]=e[r],n=!0)})),n?i:null},t.prepareVisualTypes=function(t){if(Y(t))t=t.slice();else{if(!oD(t))return[];var e=[];rD(t,(function(t,n){e.push(n)})),t=e}return t.sort((function(t,e){return"color"===e&&"color"!==t&&0===t.indexOf("color")?1:-1})),t},t.dependsOn=function(t,e){return"color"===e?!(!t||0!==t.indexOf(e)):t===e},t.findPieceIndex=function(t,e,n){for(var i,r=1/0,o=0,a=e.length;ou[1]&&(u[1]=l);var h=e.get("colorMappingBy"),c={type:a.name,dataExtent:u,visual:a.range};"color"!==c.type||"index"!==h&&"id"!==h?c.mappingMethod="linear":(c.mappingMethod="category",c.loop=!0);var p=new sD(c);return xD(p).drColorMappingBy=h,p}(0,r,o,0,u,d);E(d,(function(t,e){if(t.depth>=n.length||t===n[t.depth]){var o=function(t,e,n,i,r,o){var a=A({},e);if(r){var s=r.type,l="color"===s&&xD(r).drColorMappingBy,u="index"===l?i:"id"===l?o.mapIdToIndex(n.getId()):n.getValue(t.get("visualDimension"));a[s]=r.mapValueToVisual(u)}return a}(r,u,t,e,f,i);bD(t,o,n,i)}}))}else s=wD(u),h.fill=s}}function wD(t){var e=SD(t,"color");if(e){var n=SD(t,"colorAlpha"),i=SD(t,"colorSaturation");return i&&(e=Qn(e,null,null,i)),n&&(e=ti(e,n)),e}}function SD(t,e){var n=t[e];if(null!=n&&"none"!==n)return n}function MD(t,e){var n=t.get(e);return Y(n)&&n.length?{name:e,range:n}:null}var ID=Math.max,TD=Math.min,CD=it,DD=E,AD=["itemStyle","borderWidth"],kD=["itemStyle","gapWidth"],LD=["upperLabel","show"],PD=["upperLabel","height"],OD={seriesType:"treemap",reset:function(t,e,n,i){var r=n.getWidth(),o=n.getHeight(),a=t.option,s=wp(t.getBoxLayoutParams(),{width:n.getWidth(),height:n.getHeight()}),l=a.size||[],u=Gr(CD(s.width,l[0]),r),h=Gr(CD(s.height,l[1]),o),c=i&&i.type,p=RC(i,["treemapZoomToNode","treemapRootToNode"],t),d="treemapRender"===c||"treemapMove"===c?i.rootRect:null,f=t.getViewRoot(),g=NC(f);if("treemapMove"!==c){var y="treemapZoomToNode"===c?function(t,e,n,i,r){var o,a=(e||{}).node,s=[i,r];if(!a||a===n)return s;var l=i*r,u=l*t.option.zoomToNodeRatio;for(;o=a.parentNode;){for(var h=0,c=o.children,p=0,d=c.length;pqr&&(u=qr),a=o}ua[1]&&(a[1]=e)}))):a=[NaN,NaN];return{sum:i,dataExtent:a}}(e,a,s);if(0===u.sum)return t.viewChildren=[];if(u.sum=function(t,e,n,i,r){if(!i)return n;for(var o=t.get("visibleMin"),a=r.length,s=a,l=a-1;l>=0;l--){var u=r["asc"===i?a-l-1:l].getValue();u/n*ei&&(i=a));var l=t.area*t.area,u=e*e*n;return l?ID(u*i/l,l/(u*r)):1/0}function ED(t,e,n,i,r){var o=e===n.width?0:1,a=1-o,s=["x","y"],l=["width","height"],u=n[s[o]],h=e?t.area/e:0;(r||h>n[l[a]])&&(h=n[l[a]]);for(var c=0,p=t.length;ci&&(i=e);var o=i%2?i+2:i+3;r=[];for(var a=0;a0&&(m[0]=-m[0],m[1]=-m[1]);var _=v[0]<0?-1:1;if("start"!==i.__position&&"end"!==i.__position){var b=-Math.atan2(v[1],v[0]);u[0].8?"left":h[0]<-.8?"right":"center",p=h[1]>.8?"top":h[1]<-.8?"bottom":"middle";break;case"start":i.x=-h[0]*f+l[0],i.y=-h[1]*g+l[1],c=h[0]>.8?"right":h[0]<-.8?"left":"center",p=h[1]>.8?"bottom":h[1]<-.8?"top":"middle";break;case"insideStartTop":case"insideStart":case"insideStartBottom":i.x=f*_+l[0],i.y=l[1]+w,c=v[0]<0?"right":"left",i.originX=-f*_,i.originY=-w;break;case"insideMiddleTop":case"insideMiddle":case"insideMiddleBottom":case"middle":i.x=x[0],i.y=x[1]+w,c="center",i.originY=-w;break;case"insideEndTop":case"insideEnd":case"insideEndBottom":i.x=-f*_+u[0],i.y=u[1]+w,c=v[0]>=0?"right":"left",i.originX=f*_,i.originY=-w}i.scaleX=i.scaleY=r,i.setStyle({verticalAlign:i.__verticalAlign||p,align:i.__align||c})}}}function S(t,e){var n=t.__specifiedRotation;if(null==n){var i=a.tangentAt(e);t.attr("rotation",(1===e?-1:1)*Math.PI/2-Math.atan2(i[1],i[0]))}else t.attr("rotation",n)}},e}(Pr),_A=function(){function t(t){this.group=new Pr,this._LineCtor=t||xA}return t.prototype.updateData=function(t){var e=this;this._progressiveEls=null;var n=this,i=n.group,r=n._lineData;n._lineData=t,r||i.removeAll();var o=bA(t);t.diff(r).add((function(n){e._doAdd(t,n,o)})).update((function(n,i){e._doUpdate(r,t,i,n,o)})).remove((function(t){i.remove(r.getItemGraphicEl(t))})).execute()},t.prototype.updateLayout=function(){var t=this._lineData;t&&t.eachItemGraphicEl((function(e,n){e.updateLayout(t,n)}),this)},t.prototype.incrementalPrepareUpdate=function(t){this._seriesScope=bA(t),this._lineData=null,this.group.removeAll()},t.prototype.incrementalUpdate=function(t,e){function n(t){t.isGroup||function(t){return t.animators&&t.animators.length>0}(t)||(t.incremental=!0,t.ensureState("emphasis").hoverLayer=!0)}this._progressiveEls=[];for(var i=t.start;i=0?i+=u:i-=u:f>=0?i-=u:i+=u}return i}function LA(t,e){var n=[],i=In,r=[[],[],[]],o=[[],[]],a=[];e/=2,t.eachEdge((function(t,s){var l=t.getLayout(),u=t.getVisual("fromSymbol"),h=t.getVisual("toSymbol");l.__original||(l.__original=[Mt(l[0]),Mt(l[1])],l[2]&&l.__original.push(Mt(l[2])));var c=l.__original;if(null!=l[2]){if(St(r[0],c[0]),St(r[1],c[2]),St(r[2],c[1]),u&&"none"!==u){var p=tA(t.node1),d=kA(r,c[0],p*e);i(r[0][0],r[1][0],r[2][0],d,n),r[0][0]=n[3],r[1][0]=n[4],i(r[0][1],r[1][1],r[2][1],d,n),r[0][1]=n[3],r[1][1]=n[4]}if(h&&"none"!==h){p=tA(t.node2),d=kA(r,c[1],p*e);i(r[0][0],r[1][0],r[2][0],d,n),r[1][0]=n[1],r[2][0]=n[2],i(r[0][1],r[1][1],r[2][1],d,n),r[1][1]=n[1],r[2][1]=n[2]}St(l[0],r[0]),St(l[1],r[2]),St(l[2],r[1])}else{if(St(o[0],c[0]),St(o[1],c[1]),Dt(a,o[1],o[0]),Rt(a,a),u&&"none"!==u){p=tA(t.node1);Ct(o[0],o[0],a,p*e)}if(h&&"none"!==h){p=tA(t.node2);Ct(o[1],o[1],a,-p*e)}St(l[0],o[0]),St(l[1],o[1])}}))}function PA(t){return"view"===t.type}var OA=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.init=function(t,e){var n=new Jw,i=new _A,r=this.group;this._controller=new OI(e.getZr()),this._controllerHost={target:r},r.add(n.group),r.add(i.group),this._symbolDraw=n,this._lineDraw=i,this._firstRender=!0},e.prototype.render=function(t,e,n){var i=this,r=t.coordinateSystem;this._model=t;var o=this._symbolDraw,a=this._lineDraw,s=this.group;if(PA(r)){var l={x:r.x,y:r.y,scaleX:r.scaleX,scaleY:r.scaleY};this._firstRender?s.attr(l):uh(s,l,t)}LA(t.getGraph(),QD(t));var u=t.getData();o.updateData(u);var h=t.getEdgeData();a.updateData(h),this._updateNodeAndLinkScale(),this._updateController(t,e,n),clearTimeout(this._layoutTimeout);var c=t.forceLayout,p=t.get(["force","layoutAnimation"]);c&&this._startForceLayoutIteration(c,p);var d=t.get("layout");u.graph.eachNode((function(e){var n=e.dataIndex,r=e.getGraphicEl(),o=e.getModel();if(r){r.off("drag").off("dragend");var a=o.get("draggable");a&&r.on("drag",(function(o){switch(d){case"force":c.warmUp(),!i._layouting&&i._startForceLayoutIteration(c,p),c.setFixed(n),u.setItemLayout(n,[r.x,r.y]);break;case"circular":u.setItemLayout(n,[r.x,r.y]),e.setLayout({fixed:!0},!0),iA(t,"symbolSize",e,[o.offsetX,o.offsetY]),i.updateLayout(t);break;default:u.setItemLayout(n,[r.x,r.y]),$D(t.getGraph(),t),i.updateLayout(t)}})).on("dragend",(function(){c&&c.setUnfixed(n)})),r.setDraggable(a&&!!c,!!o.get("cursor")),"adjacency"===o.get(["emphasis","focus"])&&(js(r).focus=e.getAdjacentDataIndices())}})),u.graph.eachEdge((function(t){var e=t.getGraphicEl(),n=t.getModel().get(["emphasis","focus"]);e&&"adjacency"===n&&(js(e).focus={edge:[t.dataIndex],node:[t.node1.dataIndex,t.node2.dataIndex]})}));var f="circular"===t.get("layout")&&t.get(["circular","rotateLabel"]),g=u.getLayout("cx"),y=u.getLayout("cy");u.graph.eachNode((function(t){oA(t,f,g,y)})),this._firstRender=!1},e.prototype.dispose=function(){this._controller&&this._controller.dispose(),this._controllerHost=null},e.prototype._startForceLayoutIteration=function(t,e){var n=this;!function i(){t.step((function(t){n.updateLayout(n._model),(n._layouting=!t)&&(e?n._layoutTimeout=setTimeout(i,16):i())}))}()},e.prototype._updateController=function(t,e,n){var i=this,r=this._controller,o=this._controllerHost,a=this.group;r.setPointerChecker((function(e,i,r){var o=a.getBoundingRect();return o.applyTransform(a.transform),o.contain(i,r)&&!GI(e,n,t)})),PA(t.coordinateSystem)?(r.enable(t.get("roam")),o.zoomLimit=t.get("scaleLimit"),o.zoom=t.coordinateSystem.getZoom(),r.off("pan").off("zoom").on("pan",(function(e){zI(o,e.dx,e.dy),n.dispatchAction({seriesId:t.id,type:"graphRoam",dx:e.dx,dy:e.dy})})).on("zoom",(function(e){VI(o,e.scale,e.originX,e.originY),n.dispatchAction({seriesId:t.id,type:"graphRoam",zoom:e.scale,originX:e.originX,originY:e.originY}),i._updateNodeAndLinkScale(),LA(t.getGraph(),QD(t)),i._lineDraw.updateLayout(),n.updateLabelLayout()}))):r.disable()},e.prototype._updateNodeAndLinkScale=function(){var t=this._model,e=t.getData(),n=QD(t);e.eachItemGraphicEl((function(t,e){t&&t.setSymbolScale(n)}))},e.prototype.updateLayout=function(t){LA(t.getGraph(),QD(t)),this._symbolDraw.updateLayout(),this._lineDraw.updateLayout()},e.prototype.remove=function(t,e){this._symbolDraw&&this._symbolDraw.remove(),this._lineDraw&&this._lineDraw.remove()},e.type="graph",e}(wg);function RA(t){return"_EC_"+t}var NA=function(){function t(t){this.type="graph",this.nodes=[],this.edges=[],this._nodesMap={},this._edgesMap={},this._directed=t||!1}return t.prototype.isDirected=function(){return this._directed},t.prototype.addNode=function(t,e){t=null==t?""+e:""+t;var n=this._nodesMap;if(!n[RA(t)]){var i=new EA(t,e);return i.hostGraph=this,this.nodes.push(i),n[RA(t)]=i,i}},t.prototype.getNodeByIndex=function(t){var e=this.data.getRawIndex(t);return this.nodes[e]},t.prototype.getNodeById=function(t){return this._nodesMap[RA(t)]},t.prototype.addEdge=function(t,e,n){var i=this._nodesMap,r=this._edgesMap;if(j(t)&&(t=this.nodes[t]),j(e)&&(e=this.nodes[e]),t instanceof EA||(t=i[RA(t)]),e instanceof EA||(e=i[RA(e)]),t&&e){var o=t.id+"-"+e.id,a=new zA(t,e,n);return a.hostGraph=this,this._directed&&(t.outEdges.push(a),e.inEdges.push(a)),t.edges.push(a),t!==e&&e.edges.push(a),this.edges.push(a),r[o]=a,a}},t.prototype.getEdgeByIndex=function(t){var e=this.edgeData.getRawIndex(t);return this.edges[e]},t.prototype.getEdge=function(t,e){t instanceof EA&&(t=t.id),e instanceof EA&&(e=e.id);var n=this._edgesMap;return this._directed?n[t+"-"+e]:n[t+"-"+e]||n[e+"-"+t]},t.prototype.eachNode=function(t,e){for(var n=this.nodes,i=n.length,r=0;r=0&&t.call(e,n[r],r)},t.prototype.eachEdge=function(t,e){for(var n=this.edges,i=n.length,r=0;r=0&&n[r].node1.dataIndex>=0&&n[r].node2.dataIndex>=0&&t.call(e,n[r],r)},t.prototype.breadthFirstTraverse=function(t,e,n,i){if(e instanceof EA||(e=this._nodesMap[RA(e)]),e){for(var r="out"===n?"outEdges":"in"===n?"inEdges":"edges",o=0;o=0&&n.node2.dataIndex>=0}));for(r=0,o=i.length;r=0&&this[t][e].setItemVisual(this.dataIndex,n,i)},getVisual:function(n){return this[t][e].getItemVisual(this.dataIndex,n)},setLayout:function(n,i){this.dataIndex>=0&&this[t][e].setItemLayout(this.dataIndex,n,i)},getLayout:function(){return this[t][e].getItemLayout(this.dataIndex)},getGraphicEl:function(){return this[t][e].getItemGraphicEl(this.dataIndex)},getRawIndex:function(){return this[t][e].getRawIndex(this.dataIndex)}}}function BA(t,e,n,i,r){for(var o=new NA(i),a=0;a "+p)),u++)}var d,f=n.get("coordinateSystem");if("cartesian2d"===f||"polar"===f)d=sx(t,n);else{var g=dd.get(f),y=g&&g.dimensions||[];P(y,"value")<0&&y.concat(["value"]);var v=Qm(t,{coordDimensions:y,encodeDefine:n.getEncode()}).dimensions;(d=new Jm(v,n)).initData(t)}var m=new Jm(["value"],n);return m.initData(l,s),r&&r(d,m),MC({mainData:d,struct:o,structAttr:"graph",datas:{node:d,edge:m},datasAttr:{node:"data",edge:"edgeData"}}),o.update(),o}R(EA,VA("hostGraph","data")),R(zA,VA("hostGraph","edgeData"));var FA=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.hasSymbolVisual=!0,n}return n(e,t),e.prototype.init=function(e){t.prototype.init.apply(this,arguments);var n=this;function i(){return n._categoriesData}this.legendVisualProvider=new dM(i,i),this.fillDataTextStyle(e.edges||e.links),this._updateCategoriesData()},e.prototype.mergeOption=function(e){t.prototype.mergeOption.apply(this,arguments),this.fillDataTextStyle(e.edges||e.links),this._updateCategoriesData()},e.prototype.mergeDefaultAndTheme=function(e){t.prototype.mergeDefaultAndTheme.apply(this,arguments),vo(e,"edgeLabel",["show"])},e.prototype.getInitialData=function(t,e){var n,i=t.edges||t.links||[],r=t.data||t.nodes||[],o=this;if(r&&i){YD(n=this)&&(n.__curvenessList=[],n.__edgeMap={},UD(n));var a=BA(r,i,this,!0,(function(t,e){t.wrapMethod("getItemModel",(function(t){var e=o._categoriesModels[t.getShallow("category")];return e&&(e.parentModel=t.parentModel,t.parentModel=e),t}));var n=xc.prototype.getModel;function i(t,e){var i=n.call(this,t,e);return i.resolveParentPath=r,i}function r(t){if(t&&("label"===t[0]||"label"===t[1])){var e=t.slice();return"label"===t[0]?e[0]="edgeLabel":"label"===t[1]&&(e[1]="edgeLabel"),e}return t}e.wrapMethod("getItemModel",(function(t){return t.resolveParentPath=r,t.getModel=i,t}))}));return E(a.edges,(function(t){!function(t,e,n,i){if(YD(n)){var r=XD(t,e,n),o=n.__edgeMap,a=o[ZD(r)];o[r]&&!a?o[r].isForward=!0:a&&o[r]&&(a.isForward=!0,o[r].isForward=!1),o[r]=o[r]||[],o[r].push(i)}}(t.node1,t.node2,this,t.dataIndex)}),this),a.data}},e.prototype.getGraph=function(){return this.getData().graph},e.prototype.getEdgeData=function(){return this.getGraph().edgeData},e.prototype.getCategoriesData=function(){return this._categoriesData},e.prototype.formatTooltip=function(t,e,n){if("edge"===n){var i=this.getData(),r=this.getDataParams(t,n),o=i.graph.getEdgeByIndex(t),a=i.getName(o.node1.dataIndex),s=i.getName(o.node2.dataIndex),l=[];return null!=a&&l.push(a),null!=s&&l.push(s),qf("nameValue",{name:l.join(" > "),value:r.value,noValue:null==r.value})}return sg({series:this,dataIndex:t,multipleSeries:e})},e.prototype._updateCategoriesData=function(){var t=z(this.option.categories||[],(function(t){return null!=t.value?t:A({value:0},t)})),e=new Jm(["value"],this);e.initData(t),this._categoriesData=e,this._categoriesModels=e.mapArray((function(t){return e.getItemModel(t)}))},e.prototype.setZoom=function(t){this.option.zoom=t},e.prototype.setCenter=function(t){this.option.center=t},e.prototype.isAnimationEnabled=function(){return t.prototype.isAnimationEnabled.call(this)&&!("force"===this.get("layout")&&this.get(["force","layoutAnimation"]))},e.type="series.graph",e.dependencies=["grid","polar","geo","singleAxis","calendar"],e.defaultOption={z:2,coordinateSystem:"view",legendHoverLink:!0,layout:null,circular:{rotateLabel:!1},force:{initLayout:null,repulsion:[0,50],gravity:.1,friction:.6,edgeLength:30,layoutAnimation:!0},left:"center",top:"center",symbol:"circle",symbolSize:10,edgeSymbol:["none","none"],edgeSymbolSize:10,edgeLabel:{position:"middle",distance:5},draggable:!1,roam:!1,center:null,zoom:1,nodeScaleRatio:.6,label:{show:!1,formatter:"{b}"},itemStyle:{},lineStyle:{color:"#aaa",width:1,opacity:.5},emphasis:{scale:!0,label:{show:!0}},select:{itemStyle:{borderColor:"#212121"}}},e}(hg),GA={type:"graphRoam",event:"graphRoam",update:"none"};var WA=function(){this.angle=0,this.width=10,this.r=10,this.x=0,this.y=0},HA=function(t){function e(e){var n=t.call(this,e)||this;return n.type="pointer",n}return n(e,t),e.prototype.getDefaultShape=function(){return new WA},e.prototype.buildPath=function(t,e){var n=Math.cos,i=Math.sin,r=e.r,o=e.width,a=e.angle,s=e.x-n(a)*o*(o>=r/3?1:2),l=e.y-i(a)*o*(o>=r/3?1:2);a=e.angle-Math.PI/2,t.moveTo(s,l),t.lineTo(e.x+n(a)*o,e.y+i(a)*o),t.lineTo(e.x+n(e.angle)*r,e.y+i(e.angle)*r),t.lineTo(e.x-n(a)*o,e.y-i(a)*o),t.lineTo(s,l)},e}(_s);function YA(t,e){var n=null==t?"":t+"";return e&&(X(e)?n=e.replace("{value}",n):U(e)&&(n=e(t))),n}var UA=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){this.group.removeAll();var i=t.get(["axisLine","lineStyle","color"]),r=function(t,e){var n=t.get("center"),i=e.getWidth(),r=e.getHeight(),o=Math.min(i,r);return{cx:Gr(n[0],e.getWidth()),cy:Gr(n[1],e.getHeight()),r:Gr(t.get("radius"),o/2)}}(t,n);this._renderMain(t,e,n,i,r),this._data=t.getData()},e.prototype.dispose=function(){},e.prototype._renderMain=function(t,e,n,i,r){var o=this.group,a=t.get("clockwise"),s=-t.get("startAngle")/180*Math.PI,l=-t.get("endAngle")/180*Math.PI,u=t.getModel("axisLine"),h=u.get("roundCap")?LS:Pu,c=u.get("show"),p=u.getModel("lineStyle"),d=p.get("width"),f=[s,l];Qa(f,!a);for(var g=(l=f[1])-(s=f[0]),y=s,v=0;c&&v=t&&(0===e?0:i[e-1][0])Math.PI/2&&(V+=Math.PI):"tangential"===z?V=-M-Math.PI/2:j(z)&&(V=z*Math.PI/180),0===V?c.add(new Ns({style:$h(x,{text:O,x:N,y:E,verticalAlign:h<-.8?"top":h>.8?"bottom":"middle",align:u<-.4?"left":u>.4?"right":"center"},{inheritColor:R}),silent:!0})):c.add(new Ns({style:$h(x,{text:O,x:N,y:E,verticalAlign:"middle",align:"center"},{inheritColor:R}),silent:!0,originX:N,originY:E,rotation:V}))}if(m.get("show")&&k!==_){P=(P=m.get("distance"))?P+l:l;for(var B=0;B<=b;B++){u=Math.cos(M),h=Math.sin(M);var F=new Wu({shape:{x1:u*(f-P)+p,y1:h*(f-P)+d,x2:u*(f-S-P)+p,y2:h*(f-S-P)+d},silent:!0,style:D});"auto"===D.stroke&&F.setStyle({stroke:i((k+B/b)/_)}),c.add(F),M+=T}M-=T}else M+=I}},e.prototype._renderPointer=function(t,e,n,i,r,o,a,s,l){var u=this.group,h=this._data,c=this._progressEls,p=[],d=t.get(["pointer","show"]),f=t.getModel("progress"),g=f.get("show"),y=t.getData(),v=y.mapDimension("value"),m=+t.get("min"),x=+t.get("max"),_=[m,x],b=[o,a];function w(e,n){var i,o=y.getItemModel(e).getModel("pointer"),a=Gr(o.get("width"),r.r),s=Gr(o.get("length"),r.r),l=t.get(["pointer","icon"]),u=o.get("offsetCenter"),h=Gr(u[0],r.r),c=Gr(u[1],r.r),p=o.get("keepAspect");return(i=l?Ry(l,h-a/2,c-s,a,s,null,p):new HA({shape:{angle:-Math.PI/2,width:a,r:s,x:h,y:c}})).rotation=-(n+Math.PI/2),i.x=r.cx,i.y=r.cy,i}function S(t,e){var n=f.get("roundCap")?LS:Pu,i=f.get("overlap"),a=i?f.get("width"):l/y.count(),u=i?r.r-a:r.r-(t+1)*a,h=i?r.r:r.r-t*a,c=new n({shape:{startAngle:o,endAngle:e,cx:r.cx,cy:r.cy,clockwise:s,r0:u,r:h}});return i&&(c.z2=x-y.get(v,t)%x),c}(g||d)&&(y.diff(h).add((function(e){var n=y.get(v,e);if(d){var i=w(e,o);hh(i,{rotation:-((isNaN(+n)?b[0]:Fr(n,_,b,!0))+Math.PI/2)},t),u.add(i),y.setItemGraphicEl(e,i)}if(g){var r=S(e,o),a=f.get("clip");hh(r,{shape:{endAngle:Fr(n,_,b,a)}},t),u.add(r),qs(t.seriesIndex,y.dataType,e,r),p[e]=r}})).update((function(e,n){var i=y.get(v,e);if(d){var r=h.getItemGraphicEl(n),a=r?r.rotation:o,s=w(e,a);s.rotation=a,uh(s,{rotation:-((isNaN(+i)?b[0]:Fr(i,_,b,!0))+Math.PI/2)},t),u.add(s),y.setItemGraphicEl(e,s)}if(g){var l=c[n],m=S(e,l?l.shape.endAngle:o),x=f.get("clip");uh(m,{shape:{endAngle:Fr(i,_,b,x)}},t),u.add(m),qs(t.seriesIndex,y.dataType,e,m),p[e]=m}})).execute(),y.each((function(t){var e=y.getItemModel(t),n=e.getModel("emphasis"),r=n.get("focus"),o=n.get("blurScope"),a=n.get("disabled");if(d){var s=y.getItemGraphicEl(t),l=y.getItemVisual(t,"style"),u=l.fill;if(s instanceof Is){var h=s.style;s.useStyle(A({image:h.image,x:h.x,y:h.y,width:h.width,height:h.height},l))}else s.useStyle(l),"pointer"!==s.type&&s.setColor(u);s.setStyle(e.getModel(["pointer","itemStyle"]).getItemStyle()),"auto"===s.style.fill&&s.setStyle("fill",i(Fr(y.get(v,t),_,[0,1],!0))),s.z2EmphasisLift=0,Hl(s,e),Bl(s,r,o,a)}if(g){var c=p[t];c.useStyle(y.getItemVisual(t,"style")),c.setStyle(e.getModel(["progress","itemStyle"]).getItemStyle()),c.z2EmphasisLift=0,Hl(c,e),Bl(c,r,o,a)}})),this._progressEls=p)},e.prototype._renderAnchor=function(t,e){var n=t.getModel("anchor");if(n.get("show")){var i=n.get("size"),r=n.get("icon"),o=n.get("offsetCenter"),a=n.get("keepAspect"),s=Ry(r,e.cx-i/2+Gr(o[0],e.r),e.cy-i/2+Gr(o[1],e.r),i,i,null,a);s.z2=n.get("showAbove")?1:0,s.setStyle(n.getModel("itemStyle").getItemStyle()),this.group.add(s)}},e.prototype._renderTitleAndDetail=function(t,e,n,i,r){var o=this,a=t.getData(),s=a.mapDimension("value"),l=+t.get("min"),u=+t.get("max"),h=new Pr,c=[],p=[],d=t.isAnimationEnabled(),f=t.get(["pointer","showAbove"]);a.diff(this._data).add((function(t){c[t]=new Ns({silent:!0}),p[t]=new Ns({silent:!0})})).update((function(t,e){c[t]=o._titleEls[e],p[t]=o._detailEls[e]})).execute(),a.each((function(e){var n=a.getItemModel(e),o=a.get(s,e),g=new Pr,y=i(Fr(o,[l,u],[0,1],!0)),v=n.getModel("title");if(v.get("show")){var m=v.get("offsetCenter"),x=r.cx+Gr(m[0],r.r),_=r.cy+Gr(m[1],r.r);(D=c[e]).attr({z2:f?0:2,style:$h(v,{x:x,y:_,text:a.getName(e),align:"center",verticalAlign:"middle"},{inheritColor:y})}),g.add(D)}var b=n.getModel("detail");if(b.get("show")){var w=b.get("offsetCenter"),S=r.cx+Gr(w[0],r.r),M=r.cy+Gr(w[1],r.r),I=Gr(b.get("width"),r.r),T=Gr(b.get("height"),r.r),C=t.get(["progress","show"])?a.getItemVisual(e,"style").fill:y,D=p[e],A=b.get("formatter");D.attr({z2:f?0:2,style:$h(b,{x:S,y:M,text:YA(o,A),width:isNaN(I)?null:I,height:isNaN(T)?null:T,align:"center",verticalAlign:"middle"},{inheritColor:C})}),oc(D,{normal:b},o,(function(t){return YA(t,A)})),d&&ac(D,e,a,t,{getFormattedLabel:function(t,e,n,i,r,a){return YA(a?a.interpolatedValue:o,A)}}),g.add(D)}h.add(g)})),this.group.add(h),this._titleEls=c,this._detailEls=p},e.type="gauge",e}(wg),XA=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.visualStyleAccessPath="itemStyle",n}return n(e,t),e.prototype.getInitialData=function(t,e){return pM(this,["value"])},e.type="series.gauge",e.defaultOption={z:2,colorBy:"data",center:["50%","50%"],legendHoverLink:!0,radius:"75%",startAngle:225,endAngle:-45,clockwise:!0,min:0,max:100,splitNumber:10,axisLine:{show:!0,roundCap:!1,lineStyle:{color:[[1,"#E6EBF8"]],width:10}},progress:{show:!1,overlap:!0,width:10,roundCap:!1,clip:!0},splitLine:{show:!0,length:10,distance:10,lineStyle:{color:"#63677A",width:3,type:"solid"}},axisTick:{show:!0,splitNumber:5,length:6,distance:10,lineStyle:{color:"#63677A",width:1,type:"solid"}},axisLabel:{show:!0,distance:15,color:"#464646",fontSize:12,rotate:0},pointer:{icon:null,offsetCenter:[0,0],show:!0,showAbove:!0,length:"60%",width:6,keepAspect:!1},anchor:{show:!1,showAbove:!1,size:6,icon:"circle",offsetCenter:[0,0],keepAspect:!1,itemStyle:{color:"#fff",borderWidth:0,borderColor:"#5470c6"}},title:{show:!0,offsetCenter:[0,"20%"],color:"#464646",fontSize:16,valueAnimation:!1},detail:{show:!0,backgroundColor:"rgba(0,0,0,0)",borderWidth:0,borderColor:"#ccc",width:100,height:null,padding:[5,10],offsetCenter:[0,"40%"],color:"#464646",fontSize:30,fontWeight:"bold",lineHeight:30,valueAnimation:!1}},e}(hg);var ZA=["itemStyle","opacity"],jA=function(t){function e(e,n){var i=t.call(this)||this,r=i,o=new Bu,a=new Ns;return r.setTextContent(a),i.setTextGuideLine(o),i.updateData(e,n,!0),i}return n(e,t),e.prototype.updateData=function(t,e,n){var i=this,r=t.hostModel,o=t.getItemModel(e),a=t.getItemLayout(e),s=o.getModel("emphasis"),l=o.get(ZA);l=null==l?1:l,n||gh(i),i.useStyle(t.getItemVisual(e,"style")),i.style.lineJoin="round",n?(i.setShape({points:a.points}),i.style.opacity=0,hh(i,{style:{opacity:l}},r,e)):uh(i,{style:{opacity:l},shape:{points:a.points}},r,e),Hl(i,o),this._updateLabel(t,e),Bl(this,s.get("focus"),s.get("blurScope"),s.get("disabled"))},e.prototype._updateLabel=function(t,e){var n=this,i=this.getTextGuideLine(),r=n.getTextContent(),o=t.hostModel,a=t.getItemModel(e),s=t.getItemLayout(e).label,l=t.getItemVisual(e,"style"),u=l.fill;qh(r,Kh(a),{labelFetcher:t.hostModel,labelDataIndex:e,defaultOpacity:l.opacity,defaultText:t.getName(e)},{normal:{align:s.textAlign,verticalAlign:s.verticalAlign}}),n.setTextConfig({local:!0,inside:!!s.inside,insideStroke:u,outsideFill:u});var h=s.linePoints;i.setShape({points:h}),n.textGuideLineConfig={anchor:h?new Ie(h[0][0],h[0][1]):null},uh(r,{style:{x:s.x,y:s.y}},o,e),r.attr({rotation:s.rotation,originX:s.x,originY:s.y,z2:10}),yb(n,vb(a),{stroke:u})},e}(zu),qA=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.ignoreLabelLineUpdate=!0,n}return n(e,t),e.prototype.render=function(t,e,n){var i=t.getData(),r=this._data,o=this.group;i.diff(r).add((function(t){var e=new jA(i,t);i.setItemGraphicEl(t,e),o.add(e)})).update((function(t,e){var n=r.getItemGraphicEl(e);n.updateData(i,t),o.add(n),i.setItemGraphicEl(t,n)})).remove((function(e){fh(r.getItemGraphicEl(e),t,e)})).execute(),this._data=i},e.prototype.remove=function(){this.group.removeAll(),this._data=null},e.prototype.dispose=function(){},e.type="funnel",e}(wg),KA=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.init=function(e){t.prototype.init.apply(this,arguments),this.legendVisualProvider=new dM(W(this.getData,this),W(this.getRawData,this)),this._defaultLabelLine(e)},e.prototype.getInitialData=function(t,e){return pM(this,{coordDimensions:["value"],encodeDefaulter:H(Zp,this)})},e.prototype._defaultLabelLine=function(t){vo(t,"labelLine",["show"]);var e=t.labelLine,n=t.emphasis.labelLine;e.show=e.show&&t.label.show,n.show=n.show&&t.emphasis.label.show},e.prototype.getDataParams=function(e){var n=this.getData(),i=t.prototype.getDataParams.call(this,e),r=n.mapDimension("value"),o=n.getSum(r);return i.percent=o?+(n.get(r,e)/o*100).toFixed(2):0,i.$vars.push("percent"),i},e.type="series.funnel",e.defaultOption={z:2,legendHoverLink:!0,colorBy:"data",left:80,top:60,right:80,bottom:60,minSize:"0%",maxSize:"100%",sort:"descending",orient:"vertical",gap:0,funnelAlign:"center",label:{show:!0,position:"outer"},labelLine:{show:!0,length:20,lineStyle:{width:1}},itemStyle:{borderColor:"#fff",borderWidth:1},emphasis:{label:{show:!0}},select:{itemStyle:{borderColor:"#212121"}}},e}(hg);function $A(t,e){t.eachSeriesByType("funnel",(function(t){var n=t.getData(),i=n.mapDimension("value"),r=t.get("sort"),o=function(t,e){return wp(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()})}(t,e),a=t.get("orient"),s=o.width,l=o.height,u=function(t,e){for(var n=t.mapDimension("value"),i=t.mapArray(n,(function(t){return t})),r=[],o="ascending"===e,a=0,s=t.count();a5)return;var i=this._model.coordinateSystem.getSlidedAxisExpandWindow([t.offsetX,t.offsetY]);"none"!==i.behavior&&this._dispatchExpand({axisExpandWindow:i.axisExpandWindow})}this._mouseDownPoint=null},mousemove:function(t){if(!this._mouseDownPoint&&hk(this,"mousemove")){var e=this._model,n=e.coordinateSystem.getSlidedAxisExpandWindow([t.offsetX,t.offsetY]),i=n.behavior;"jump"===i&&this._throttledDispatchExpand.debounceNextCall(e.get("axisExpandDebounce")),this._throttledDispatchExpand("none"===i?null:{axisExpandWindow:n.axisExpandWindow,animation:"jump"===i?null:{duration:0}})}}};function hk(t,e){var n=t._model;return n.get("axisExpandable")&&n.get("axisExpandTriggerOn")===e}var ck=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.init=function(){t.prototype.init.apply(this,arguments),this.mergeOption({})},e.prototype.mergeOption=function(t){var e=this.option;t&&C(e,t,!0),this._initDimensions()},e.prototype.contains=function(t,e){var n=t.get("parallelIndex");return null!=n&&e.getComponent("parallel",n)===this},e.prototype.setAxisExpand=function(t){E(["axisExpandable","axisExpandCenter","axisExpandCount","axisExpandWidth","axisExpandWindow"],(function(e){t.hasOwnProperty(e)&&(this.option[e]=t[e])}),this)},e.prototype._initDimensions=function(){var t=this.dimensions=[],e=this.parallelAxisIndex=[];E(B(this.ecModel.queryComponents({mainType:"parallelAxis"}),(function(t){return(t.get("parallelIndex")||0)===this.componentIndex}),this),(function(n){t.push("dim"+n.get("dim")),e.push(n.componentIndex)}))},e.type="parallel",e.dependencies=["parallelAxis"],e.layoutMode="box",e.defaultOption={z:0,left:80,top:60,right:80,bottom:60,layout:"horizontal",axisExpandable:!1,axisExpandCenter:null,axisExpandCount:0,axisExpandWidth:50,axisExpandRate:17,axisExpandDebounce:50,axisExpandSlideTriggerArea:[-.15,.05,.4],axisExpandTriggerOn:"click",parallelAxisDefault:null},e}(Ap),pk=function(t){function e(e,n,i,r,o){var a=t.call(this,e,n,i)||this;return a.type=r||"value",a.axisIndex=o,a}return n(e,t),e.prototype.isHorizontal=function(){return"horizontal"!==this.coordinateSystem.getModel().get("layout")},e}(X_);function dk(t,e,n,i,r,o){t=t||0;var a=n[1]-n[0];if(null!=r&&(r=gk(r,[0,a])),null!=o&&(o=Math.max(o,null!=r?r:0)),"all"===i){var s=Math.abs(e[1]-e[0]);s=gk(s,[0,a]),r=o=gk(s,[r,o]),i=0}e[0]=gk(e[0],n),e[1]=gk(e[1],n);var l=fk(e,i);e[i]+=t;var u,h=r||0,c=n.slice();return l.sign<0?c[0]+=h:c[1]-=h,e[i]=gk(e[i],c),u=fk(e,i),null!=r&&(u.sign!==l.sign||u.spano&&(e[1-i]=e[i]+u.sign*o),e}function fk(t,e){var n=t[e]-t[1-e];return{span:Math.abs(n),sign:n>0?-1:n<0?1:e?-1:1}}function gk(t,e){return Math.min(null!=e[1]?e[1]:1/0,Math.max(null!=e[0]?e[0]:-1/0,t))}var yk=E,vk=Math.min,mk=Math.max,xk=Math.floor,_k=Math.ceil,bk=Wr,wk=Math.PI,Sk=function(){function t(t,e,n){this.type="parallel",this._axesMap=ft(),this._axesLayout={},this.dimensions=t.dimensions,this._model=t,this._init(t,e,n)}return t.prototype._init=function(t,e,n){var i=t.dimensions,r=t.parallelAxisIndex;yk(i,(function(t,n){var i=r[n],o=e.getComponent("parallelAxis",i),a=this._axesMap.set(t,new pk(t,l_(o),[0,0],o.get("type"),i)),s="category"===a.type;a.onBand=s&&o.get("boundaryGap"),a.inverse=o.get("inverse"),o.axis=a,a.model=o,a.coordinateSystem=o.coordinateSystem=this}),this)},t.prototype.update=function(t,e){this._updateAxesFromSeries(this._model,t)},t.prototype.containPoint=function(t){var e=this._makeLayoutInfo(),n=e.axisBase,i=e.layoutBase,r=e.pixelDimIndex,o=t[1-r],a=t[r];return o>=n&&o<=n+e.axisLength&&a>=i&&a<=i+e.layoutLength},t.prototype.getModel=function(){return this._model},t.prototype._updateAxesFromSeries=function(t,e){e.eachSeries((function(n){if(t.contains(n,e)){var i=n.getData();yk(this.dimensions,(function(t){var e=this._axesMap.get(t);e.scale.unionExtentFromData(i,i.mapDimension(t)),s_(e.scale,e.model)}),this)}}),this)},t.prototype.resize=function(t,e){this._rect=wp(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()}),this._layoutAxes()},t.prototype.getRect=function(){return this._rect},t.prototype._makeLayoutInfo=function(){var t,e=this._model,n=this._rect,i=["x","y"],r=["width","height"],o=e.get("layout"),a="horizontal"===o?0:1,s=n[r[a]],l=[0,s],u=this.dimensions.length,h=Mk(e.get("axisExpandWidth"),l),c=Mk(e.get("axisExpandCount")||0,[0,u]),p=e.get("axisExpandable")&&u>3&&u>c&&c>1&&h>0&&s>0,d=e.get("axisExpandWindow");d?(t=Mk(d[1]-d[0],l),d[1]=d[0]+t):(t=Mk(h*(c-1),l),(d=[h*(e.get("axisExpandCenter")||xk(u/2))-t/2])[1]=d[0]+t);var f=(s-t)/(u-c);f<3&&(f=0);var g=[xk(bk(d[0]/h,1))+1,_k(bk(d[1]/h,1))-1],y=f/h*d[0];return{layout:o,pixelDimIndex:a,layoutBase:n[i[a]],layoutLength:s,axisBase:n[i[1-a]],axisLength:n[r[1-a]],axisExpandable:p,axisExpandWidth:h,axisCollapseWidth:f,axisExpandWindow:d,axisCount:u,winInnerIndices:g,axisExpandWindow0Pos:y}},t.prototype._layoutAxes=function(){var t=this._rect,e=this._axesMap,n=this.dimensions,i=this._makeLayoutInfo(),r=i.layout;e.each((function(t){var e=[0,i.axisLength],n=t.inverse?1:0;t.setExtent(e[n],e[1-n])})),yk(n,(function(e,n){var o=(i.axisExpandable?Tk:Ik)(n,i),a={horizontal:{x:o.position,y:i.axisLength},vertical:{x:0,y:o.position}},s={horizontal:wk/2,vertical:0},l=[a[r].x+t.x,a[r].y+t.y],u=s[r],h=[1,0,0,1,0,0];_e(h,h,u),xe(h,h,l),this._axesLayout[e]={position:l,rotation:u,transform:h,axisNameAvailableWidth:o.axisNameAvailableWidth,axisLabelShow:o.axisLabelShow,nameTruncateMaxWidth:o.nameTruncateMaxWidth,tickDirection:1,labelDirection:1}}),this)},t.prototype.getAxis=function(t){return this._axesMap.get(t)},t.prototype.dataToPoint=function(t,e){return this.axisCoordToPoint(this._axesMap.get(e).dataToCoord(t),e)},t.prototype.eachActiveState=function(t,e,n,i){null==n&&(n=0),null==i&&(i=t.count());var r=this._axesMap,o=this.dimensions,a=[],s=[];E(o,(function(e){a.push(t.mapDimension(e)),s.push(r.get(e).model)}));for(var l=this.hasAxisBrushed(),u=n;ur*(1-h[0])?(l="jump",a=s-r*(1-h[2])):(a=s-r*h[1])>=0&&(a=s-r*(1-h[1]))<=0&&(a=0),(a*=e.axisExpandWidth/u)?dk(a,i,o,"all"):l="none";else{var p=i[1]-i[0];(i=[mk(0,o[1]*s/p-p/2)])[1]=vk(o[1],i[0]+p),i[0]=i[1]-p}return{axisExpandWindow:i,behavior:l}},t}();function Mk(t,e){return vk(mk(t,e[0]),e[1])}function Ik(t,e){var n=e.layoutLength/(e.axisCount-1);return{position:n*t,axisNameAvailableWidth:n,axisLabelShow:!0}}function Tk(t,e){var n,i,r=e.layoutLength,o=e.axisExpandWidth,a=e.axisCount,s=e.axisCollapseWidth,l=e.winInnerIndices,u=s,h=!1;return t=0;n--)Hr(e[n])},e.prototype.getActiveState=function(t){var e=this.activeIntervals;if(!e.length)return"normal";if(null==t||isNaN(+t))return"inactive";if(1===e.length){var n=e[0];if(n[0]<=t&&t<=n[1])return"active"}else for(var i=0,r=e.length;i6}(t)||o){if(a&&!o){"single"===s.brushMode&&Zk(t);var l=T(s);l.brushType=hL(l.brushType,a),l.panelId=a===Ak?null:a.panelId,o=t._creatingCover=Bk(t,l),t._covers.push(o)}if(o){var u=dL[hL(t._brushType,a)];o.__brushOption.range=u.getCreatingRange(aL(t,o,t._track)),i&&(Fk(t,o),u.updateCommon(t,o)),Gk(t,o),r={isEnd:i}}}else i&&"single"===s.brushMode&&s.removeOnClick&&Uk(t,e,n)&&Zk(t)&&(r={isEnd:i,removeOnClick:!0});return r}function hL(t,e){return"auto"===t?e.defaultBrushType:t}var cL={mousedown:function(t){if(this._dragging)pL(this,t);else if(!t.target||!t.target.draggable){sL(t);var e=this.group.transformCoordToLocal(t.offsetX,t.offsetY);this._creatingCover=null,(this._creatingPanel=Uk(this,t,e))&&(this._dragging=!0,this._track=[e.slice()])}},mousemove:function(t){var e=t.offsetX,n=t.offsetY,i=this.group.transformCoordToLocal(e,n);if(function(t,e,n){if(t._brushType&&!function(t,e,n){var i=t._zr;return e<0||e>i.getWidth()||n<0||n>i.getHeight()}(t,e.offsetX,e.offsetY)){var i=t._zr,r=t._covers,o=Uk(t,e,n);if(!t._dragging)for(var a=0;a=0&&(o[r[a].depth]=new xc(r[a],this,e));if(i&&n){var s=BA(i,n,this,!0,(function(t,e){t.wrapMethod("getItemModel",(function(t,e){var n=t.parentModel,i=n.getData().getItemLayout(e);if(i){var r=i.depth,o=n.levelModels[r];o&&(t.parentModel=o)}return t})),e.wrapMethod("getItemModel",(function(t,e){var n=t.parentModel,i=n.getGraph().getEdgeByIndex(e).node1.getLayout();if(i){var r=i.depth,o=n.levelModels[r];o&&(t.parentModel=o)}return t}))}));return s.data}},e.prototype.setNodePosition=function(t,e){var n=(this.option.data||this.option.nodes)[t];n.localX=e[0],n.localY=e[1]},e.prototype.getGraph=function(){return this.getData().graph},e.prototype.getEdgeData=function(){return this.getGraph().edgeData},e.prototype.formatTooltip=function(t,e,n){function i(t){return isNaN(t)||null==t}if("edge"===n){var r=this.getDataParams(t,n),o=r.data,a=r.value;return qf("nameValue",{name:o.source+" -- "+o.target,value:a,noValue:i(a)})}var s=this.getGraph().getNodeByIndex(t).getLayout().value,l=this.getDataParams(t,n).data.name;return qf("nameValue",{name:null!=l?l+"":null,value:s,noValue:i(s)})},e.prototype.optionUpdated=function(){},e.prototype.getDataParams=function(e,n){var i=t.prototype.getDataParams.call(this,e,n);if(null==i.value&&"node"===n){var r=this.getGraph().getNodeByIndex(e).getLayout().value;i.value=r}return i},e.type="series.sankey",e.defaultOption={z:2,coordinateSystem:"view",left:"5%",top:"5%",right:"20%",bottom:"5%",orient:"horizontal",nodeWidth:20,nodeGap:8,draggable:!0,layoutIterations:32,label:{show:!0,position:"right",fontSize:12},levels:[],nodeAlign:"justify",lineStyle:{color:"#314656",opacity:.2,curveness:.5},emphasis:{label:{show:!0},lineStyle:{opacity:.5}},select:{itemStyle:{borderColor:"#212121"}},animationEasing:"linear",animationDuration:1e3},e}(hg);function DL(t,e){t.eachSeriesByType("sankey",(function(t){var n=t.get("nodeWidth"),i=t.get("nodeGap"),r=function(t,e){return wp(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()})}(t,e);t.layoutInfo=r;var o=r.width,a=r.height,s=t.getGraph(),l=s.nodes,u=s.edges;!function(t){E(t,(function(t){var e=VL(t.outEdges,zL),n=VL(t.inEdges,zL),i=t.getValue()||0,r=Math.max(e,n,i);t.setLayout({value:r},!0)}))}(l),function(t,e,n,i,r,o,a,s,l){(function(t,e,n,i,r,o,a){for(var s=[],l=[],u=[],h=[],c=0,p=0;p=0;v&&y.depth>d&&(d=y.depth),g.setLayout({depth:v?y.depth:c},!0),"vertical"===o?g.setLayout({dy:n},!0):g.setLayout({dx:n},!0);for(var m=0;mc-1?d:c-1;a&&"left"!==a&&function(t,e,n,i){if("right"===e){for(var r=[],o=t,a=0;o.length;){for(var s=0;s0;o--)LL(s,l*=.99,a),kL(s,r,n,i,a),BL(s,l,a),kL(s,r,n,i,a)}(t,e,o,r,i,a,s),function(t,e){var n="vertical"===e?"x":"y";E(t,(function(t){t.outEdges.sort((function(t,e){return t.node2.getLayout()[n]-e.node2.getLayout()[n]})),t.inEdges.sort((function(t,e){return t.node1.getLayout()[n]-e.node1.getLayout()[n]}))})),E(t,(function(t){var e=0,n=0;E(t.outEdges,(function(t){t.setLayout({sy:e},!0),e+=t.getLayout().dy})),E(t.inEdges,(function(t){t.setLayout({ty:n},!0),n+=t.getLayout().dy}))}))}(t,s)}(l,u,n,i,o,a,0!==B(l,(function(t){return 0===t.getLayout().value})).length?0:t.get("layoutIterations"),t.get("orient"),t.get("nodeAlign"))}))}function AL(t){var e=t.hostGraph.data.getRawDataItem(t.dataIndex);return null!=e.depth&&e.depth>=0}function kL(t,e,n,i,r){var o="vertical"===r?"x":"y";E(t,(function(t){var a,s,l;t.sort((function(t,e){return t.getLayout()[o]-e.getLayout()[o]}));for(var u=0,h=t.length,c="vertical"===r?"dx":"dy",p=0;p0&&(a=s.getLayout()[o]+l,"vertical"===r?s.setLayout({x:a},!0):s.setLayout({y:a},!0)),u=s.getLayout()[o]+s.getLayout()[c]+e;if((l=u-e-("vertical"===r?i:n))>0){a=s.getLayout()[o]-l,"vertical"===r?s.setLayout({x:a},!0):s.setLayout({y:a},!0),u=a;for(p=h-2;p>=0;--p)(l=(s=t[p]).getLayout()[o]+s.getLayout()[c]+e-u)>0&&(a=s.getLayout()[o]-l,"vertical"===r?s.setLayout({x:a},!0):s.setLayout({y:a},!0)),u=s.getLayout()[o]}}))}function LL(t,e,n){E(t.slice().reverse(),(function(t){E(t,(function(t){if(t.outEdges.length){var i=VL(t.outEdges,PL,n)/VL(t.outEdges,zL);if(isNaN(i)){var r=t.outEdges.length;i=r?VL(t.outEdges,OL,n)/r:0}if("vertical"===n){var o=t.getLayout().x+(i-EL(t,n))*e;t.setLayout({x:o},!0)}else{var a=t.getLayout().y+(i-EL(t,n))*e;t.setLayout({y:a},!0)}}}))}))}function PL(t,e){return EL(t.node2,e)*t.getValue()}function OL(t,e){return EL(t.node2,e)}function RL(t,e){return EL(t.node1,e)*t.getValue()}function NL(t,e){return EL(t.node1,e)}function EL(t,e){return"vertical"===e?t.getLayout().x+t.getLayout().dx/2:t.getLayout().y+t.getLayout().dy/2}function zL(t){return t.getValue()}function VL(t,e,n){for(var i=0,r=t.length,o=-1;++oi&&(i=e)})),E(e,(function(e){var r=new sD({type:"color",mappingMethod:"linear",dataExtent:[n,i],visual:t.get("color")}).mapValueToVisual(e.getLayout().value),o=e.getModel().get(["itemStyle","color"]);null!=o?(e.setVisual("color",o),e.setVisual("style",{fill:o})):(e.setVisual("color",r),e.setVisual("style",{fill:r}))}))}}))}var GL=function(){function t(){}return t.prototype.getInitialData=function(t,e){var n,i,r=e.getComponent("xAxis",this.get("xAxisIndex")),o=e.getComponent("yAxis",this.get("yAxisIndex")),a=r.get("type"),s=o.get("type");"category"===a?(t.layout="horizontal",n=r.getOrdinalMeta(),i=!0):"category"===s?(t.layout="vertical",n=o.getOrdinalMeta(),i=!0):t.layout=t.layout||"horizontal";var l=["x","y"],u="horizontal"===t.layout?0:1,h=this._baseAxisDim=l[u],c=l[1-u],p=[r,o],d=p[u].get("type"),f=p[1-u].get("type"),g=t.data;if(g&&i){var y=[];E(g,(function(t,e){var n;Y(t)?(n=t.slice(),t.unshift(e)):Y(t.value)?((n=A({},t)).value=n.value.slice(),t.value.unshift(e)):n=t,y.push(n)})),t.data=y}var v=this.defaultValueDimensions,m=[{name:h,type:Lm(d),ordinalMeta:n,otherDims:{tooltip:!1,itemName:0},dimsDef:["base"]},{name:c,type:Lm(f),dimsDef:v.slice()}];return pM(this,{coordDimensions:m,dimensionsCount:v.length+1,encodeDefaulter:H(Xp,m,this)})},t.prototype.getBaseAxis=function(){var t=this._baseAxisDim;return this.ecModel.getComponent(t+"Axis",this.get(t+"AxisIndex")).axis},t}(),WL=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.defaultValueDimensions=[{name:"min",defaultTooltip:!0},{name:"Q1",defaultTooltip:!0},{name:"median",defaultTooltip:!0},{name:"Q3",defaultTooltip:!0},{name:"max",defaultTooltip:!0}],n.visualDrawType="stroke",n}return n(e,t),e.type="series.boxplot",e.dependencies=["xAxis","yAxis","grid"],e.defaultOption={z:2,coordinateSystem:"cartesian2d",legendHoverLink:!0,layout:null,boxWidth:[7,50],itemStyle:{color:"#fff",borderWidth:1},emphasis:{scale:!0,itemStyle:{borderWidth:2,shadowBlur:5,shadowOffsetX:1,shadowOffsetY:1,shadowColor:"rgba(0,0,0,0.2)"}},animationDuration:800},e}(hg);R(WL,GL,!0);var HL=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){var i=t.getData(),r=this.group,o=this._data;this._data||r.removeAll();var a="horizontal"===t.get("layout")?1:0;i.diff(o).add((function(t){if(i.hasValue(t)){var e=XL(i.getItemLayout(t),i,t,a,!0);i.setItemGraphicEl(t,e),r.add(e)}})).update((function(t,e){var n=o.getItemGraphicEl(e);if(i.hasValue(t)){var s=i.getItemLayout(t);n?(gh(n),ZL(s,n,i,t)):n=XL(s,i,t,a),r.add(n),i.setItemGraphicEl(t,n)}else r.remove(n)})).remove((function(t){var e=o.getItemGraphicEl(t);e&&r.remove(e)})).execute(),this._data=i},e.prototype.remove=function(t){var e=this.group,n=this._data;this._data=null,n&&n.eachItemGraphicEl((function(t){t&&e.remove(t)}))},e.type="boxplot",e}(wg),YL=function(){},UL=function(t){function e(e){var n=t.call(this,e)||this;return n.type="boxplotBoxPath",n}return n(e,t),e.prototype.getDefaultShape=function(){return new YL},e.prototype.buildPath=function(t,e){var n=e.points,i=0;for(t.moveTo(n[i][0],n[i][1]),i++;i<4;i++)t.lineTo(n[i][0],n[i][1]);for(t.closePath();ig){var _=[v,x];i.push(_)}}}return{boxData:n,outliers:i}}(e.getRawData(),t.config);return[{dimensions:["ItemName","Low","Q1","Q2","Q3","High"],data:i.boxData},{data:i.outliers}]}};var QL=["color","borderColor"],tP=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){this.group.removeClipPath(),this._progressiveEls=null,this._updateDrawMode(t),this._isLargeDraw?this._renderLarge(t):this._renderNormal(t)},e.prototype.incrementalPrepareRender=function(t,e,n){this._clear(),this._updateDrawMode(t)},e.prototype.incrementalRender=function(t,e,n,i){this._progressiveEls=[],this._isLargeDraw?this._incrementalRenderLarge(t,e):this._incrementalRenderNormal(t,e)},e.prototype.eachRendered=function(t){Yh(this._progressiveEls||this.group,t)},e.prototype._updateDrawMode=function(t){var e=t.pipelineContext.large;null!=this._isLargeDraw&&e===this._isLargeDraw||(this._isLargeDraw=e,this._clear())},e.prototype._renderNormal=function(t){var e=t.getData(),n=this._data,i=this.group,r=e.getLayout("isSimpleBox"),o=t.get("clip",!0),a=t.coordinateSystem,s=a.getArea&&a.getArea();this._data||i.removeAll(),e.diff(n).add((function(n){if(e.hasValue(n)){var a=e.getItemLayout(n);if(o&&rP(s,a))return;var l=iP(a,n,!0);hh(l,{shape:{points:a.ends}},t,n),oP(l,e,n,r),i.add(l),e.setItemGraphicEl(n,l)}})).update((function(a,l){var u=n.getItemGraphicEl(l);if(e.hasValue(a)){var h=e.getItemLayout(a);o&&rP(s,h)?i.remove(u):(u?(uh(u,{shape:{points:h.ends}},t,a),gh(u)):u=iP(h),oP(u,e,a,r),i.add(u),e.setItemGraphicEl(a,u))}else i.remove(u)})).remove((function(t){var e=n.getItemGraphicEl(t);e&&i.remove(e)})).execute(),this._data=e},e.prototype._renderLarge=function(t){this._clear(),uP(t,this.group);var e=t.get("clip",!0)?cS(t.coordinateSystem,!1,t):null;e?this.group.setClipPath(e):this.group.removeClipPath()},e.prototype._incrementalRenderNormal=function(t,e){for(var n,i=e.getData(),r=i.getLayout("isSimpleBox");null!=(n=t.next());){var o=iP(i.getItemLayout(n));oP(o,i,n,r),o.incremental=!0,this.group.add(o),this._progressiveEls.push(o)}},e.prototype._incrementalRenderLarge=function(t,e){uP(e,this.group,this._progressiveEls,!0)},e.prototype.remove=function(t){this._clear()},e.prototype._clear=function(){this.group.removeAll(),this._data=null},e.type="candlestick",e}(wg),eP=function(){},nP=function(t){function e(e){var n=t.call(this,e)||this;return n.type="normalCandlestickBox",n}return n(e,t),e.prototype.getDefaultShape=function(){return new eP},e.prototype.buildPath=function(t,e){var n=e.points;this.__simpleBox?(t.moveTo(n[4][0],n[4][1]),t.lineTo(n[6][0],n[6][1])):(t.moveTo(n[0][0],n[0][1]),t.lineTo(n[1][0],n[1][1]),t.lineTo(n[2][0],n[2][1]),t.lineTo(n[3][0],n[3][1]),t.closePath(),t.moveTo(n[4][0],n[4][1]),t.lineTo(n[5][0],n[5][1]),t.moveTo(n[6][0],n[6][1]),t.lineTo(n[7][0],n[7][1]))},e}(_s);function iP(t,e,n){var i=t.ends;return new nP({shape:{points:n?aP(i,t):i},z2:100})}function rP(t,e){for(var n=!0,i=0;i0?"borderColor":"borderColor0"])||n.get(["itemStyle",t>0?"color":"color0"]),o=n.getModel("itemStyle").getItemStyle(QL);e.useStyle(o),e.style.fill=null,e.style.stroke=r}var cP=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.defaultValueDimensions=[{name:"open",defaultTooltip:!0},{name:"close",defaultTooltip:!0},{name:"lowest",defaultTooltip:!0},{name:"highest",defaultTooltip:!0}],n}return n(e,t),e.prototype.getShadowDim=function(){return"open"},e.prototype.brushSelector=function(t,e,n){var i=e.getItemLayout(t);return i&&n.rect(i.brushRect)},e.type="series.candlestick",e.dependencies=["xAxis","yAxis","grid"],e.defaultOption={z:2,coordinateSystem:"cartesian2d",legendHoverLink:!0,layout:null,clip:!0,itemStyle:{color:"#eb5454",color0:"#47b262",borderColor:"#eb5454",borderColor0:"#47b262",borderWidth:1},emphasis:{scale:!0,itemStyle:{borderWidth:2}},barMaxWidth:null,barMinWidth:null,barWidth:null,large:!0,largeThreshold:600,progressive:3e3,progressiveThreshold:1e4,progressiveChunkMode:"mod",animationEasing:"linear",animationDuration:300},e}(hg);function pP(t){t&&Y(t.series)&&E(t.series,(function(t){q(t)&&"k"===t.type&&(t.type="candlestick")}))}R(cP,GL,!0);var dP=["itemStyle","borderColor"],fP=["itemStyle","borderColor0"],gP=["itemStyle","color"],yP=["itemStyle","color0"],vP={seriesType:"candlestick",plan:xg(),performRawSeries:!0,reset:function(t,e){function n(t,e){return e.get(t>0?gP:yP)}function i(t,e){return e.get(t>0?dP:fP)}if(!e.isSeriesFiltered(t))return!t.pipelineContext.large&&{progress:function(t,e){for(var r;null!=(r=t.next());){var o=e.getItemModel(r),a=e.getItemLayout(r).sign,s=o.getItemStyle();s.fill=n(a,o),s.stroke=i(a,o)||s.fill,A(e.ensureUniqueItemVisual(r,"style"),s)}}}}},mP={seriesType:"candlestick",plan:xg(),reset:function(t){var e=t.coordinateSystem,n=t.getData(),i=function(t,e){var n,i=t.getBaseAxis(),r="category"===i.type?i.getBandWidth():(n=i.getExtent(),Math.abs(n[1]-n[0])/e.count()),o=Gr(rt(t.get("barMaxWidth"),r),r),a=Gr(rt(t.get("barMinWidth"),1),r),s=t.get("barWidth");return null!=s?Gr(s,r):Math.max(Math.min(r/2,o),a)}(t,n),r=["x","y"],o=n.getDimensionIndex(n.mapDimension(r[0])),a=z(n.mapDimensionsAll(r[1]),n.getDimensionIndex,n),s=a[0],l=a[1],u=a[2],h=a[3];if(n.setLayout({candleWidth:i,isSimpleBox:i<=1.3}),!(o<0||a.length<4))return{progress:t.pipelineContext.large?function(t,n){var i,r,a=Tx(4*t.count),c=0,p=[],d=[],f=n.getStore();for(;null!=(r=t.next());){var g=f.get(o,r),y=f.get(s,r),v=f.get(l,r),m=f.get(u,r),x=f.get(h,r);isNaN(g)||isNaN(m)||isNaN(x)?(a[c++]=NaN,c+=3):(a[c++]=xP(f,r,y,v,l),p[0]=g,p[1]=m,i=e.dataToPoint(p,null,d),a[c++]=i?i[0]:NaN,a[c++]=i?i[1]:NaN,p[1]=x,i=e.dataToPoint(p,null,d),a[c++]=i?i[1]:NaN)}n.setLayout("largePoints",a)}:function(t,n){var r,a=n.getStore();for(;null!=(r=t.next());){var c=a.get(o,r),p=a.get(s,r),d=a.get(l,r),f=a.get(u,r),g=a.get(h,r),y=Math.min(p,d),v=Math.max(p,d),m=S(y,c),x=S(v,c),_=S(f,c),b=S(g,c),w=[];M(w,x,0),M(w,m,1),w.push(T(b),T(x),T(_),T(m)),n.setItemLayout(r,{sign:xP(a,r,p,d,l),initBaseline:p>d?x[1]:m[1],ends:w,brushRect:I(f,g,c)})}function S(t,n){var i=[];return i[0]=n,i[1]=t,isNaN(n)||isNaN(t)?[NaN,NaN]:e.dataToPoint(i)}function M(t,e,n){var r=e.slice(),o=e.slice();r[0]=kh(r[0]+i/2,1,!1),o[0]=kh(o[0]-i/2,1,!0),n?t.push(r,o):t.push(o,r)}function I(t,e,n){var r=S(t,n),o=S(e,n);return r[0]-=i/2,o[0]-=i/2,{x:r[0],y:r[1],width:i,height:o[1]-r[1]}}function T(t){return t[0]=kh(t[0],1),t}}}}};function xP(t,e,n,i,r){return n>i?-1:n0?t.get(r,e-1)<=i?1:-1:1}function _P(t,e){var n=e.rippleEffectColor||e.color;t.eachChild((function(t){t.attr({z:e.z,zlevel:e.zlevel,style:{stroke:"stroke"===e.brushType?n:null,fill:"fill"===e.brushType?n:null}})}))}var bP=function(t){function e(e,n){var i=t.call(this)||this,r=new Zw(e,n),o=new Pr;return i.add(r),i.add(o),i.updateData(e,n),i}return n(e,t),e.prototype.stopEffectAnimation=function(){this.childAt(1).removeAll()},e.prototype.startEffectAnimation=function(t){for(var e=t.symbolType,n=t.color,i=t.rippleNumber,r=this.childAt(1),o=0;o0&&(o=this._getLineLength(i)/l*1e3),o!==this._period||a!==this._loop||s!==this._roundTrip){i.stopAnimation();var h=void 0;h=U(u)?u(n):u,i.__t>0&&(h=-o*i.__t),this._animateSymbol(i,o,h,a,s)}this._period=o,this._loop=a,this._roundTrip=s}},e.prototype._animateSymbol=function(t,e,n,i,r){if(e>0){t.__t=0;var o=this,a=t.animate("",i).when(r?2*e:e,{__t:r?2:1}).delay(n).during((function(){o._updateSymbolPosition(t)}));i||a.done((function(){o.remove(t)})),a.start()}},e.prototype._getLineLength=function(t){return Et(t.__p1,t.__cp1)+Et(t.__cp1,t.__p2)},e.prototype._updateAnimationPoints=function(t,e){t.__p1=e[0],t.__p2=e[1],t.__cp1=e[2]||[(e[0][0]+e[1][0])/2,(e[0][1]+e[1][1])/2]},e.prototype.updateData=function(t,e,n){this.childAt(0).updateData(t,e,n),this._updateEffectSymbol(t,e)},e.prototype._updateSymbolPosition=function(t){var e=t.__p1,n=t.__p2,i=t.__cp1,r=t.__t<1?t.__t:2-t.__t,o=[t.x,t.y],a=o.slice(),s=wn,l=Sn;o[0]=s(e[0],i[0],n[0],r),o[1]=s(e[1],i[1],n[1],r);var u=t.__t<1?l(e[0],i[0],n[0],r):l(n[0],i[0],e[0],1-r),h=t.__t<1?l(e[1],i[1],n[1],r):l(n[1],i[1],e[1],1-r);t.rotation=-Math.atan2(h,u)-Math.PI/2,"line"!==this._symbolType&&"rect"!==this._symbolType&&"roundRect"!==this._symbolType||(void 0!==t.__lastT&&t.__lastT=0&&!(i[o]<=e);o--);o=Math.min(o,r-2)}else{for(o=a;oe);o++);o=Math.min(o-1,r-2)}var s=(e-i[o])/(i[o+1]-i[o]),l=n[o],u=n[o+1];t.x=l[0]*(1-s)+s*u[0],t.y=l[1]*(1-s)+s*u[1];var h=t.__t<1?u[0]-l[0]:l[0]-u[0],c=t.__t<1?u[1]-l[1]:l[1]-u[1];t.rotation=-Math.atan2(c,h)-Math.PI/2,this._lastFrame=o,this._lastFramePercent=e,t.ignore=!1}},e}(MP),CP=function(){this.polyline=!1,this.curveness=0,this.segs=[]},DP=function(t){function e(e){var n=t.call(this,e)||this;return n._off=0,n.hoverDataIdx=-1,n}return n(e,t),e.prototype.reset=function(){this.notClear=!1,this._off=0},e.prototype.getDefaultStyle=function(){return{stroke:"#000",fill:null}},e.prototype.getDefaultShape=function(){return new CP},e.prototype.buildPath=function(t,e){var n,i=e.segs,r=e.curveness;if(e.polyline)for(n=this._off;n0){t.moveTo(i[n++],i[n++]);for(var a=1;a0){var c=(s+u)/2-(l-h)*r,p=(l+h)/2-(u-s)*r;t.quadraticCurveTo(c,p,u,h)}else t.lineTo(u,h)}this.incremental&&(this._off=n,this.notClear=!0)},e.prototype.findDataIndex=function(t,e){var n=this.shape,i=n.segs,r=n.curveness,o=this.style.lineWidth;if(n.polyline)for(var a=0,s=0;s0)for(var u=i[s++],h=i[s++],c=1;c0){if(is(u,h,(u+p)/2-(h-d)*r,(h+d)/2-(p-u)*r,p,d,o,t,e))return a}else if(es(u,h,p,d,o,t,e))return a;a++}return-1},e.prototype.contain=function(t,e){var n=this.transformCoordToLocal(t,e),i=this.getBoundingRect();return t=n[0],e=n[1],i.contain(t,e)?(this.hoverDataIdx=this.findDataIndex(t,e))>=0:(this.hoverDataIdx=-1,!1)},e.prototype.getBoundingRect=function(){var t=this._rect;if(!t){for(var e=this.shape.segs,n=1/0,i=1/0,r=-1/0,o=-1/0,a=0;a0&&(o.dataIndex=n+t.__startIndex)}))},t.prototype._clear=function(){this._newAdded=[],this.group.removeAll()},t}(),kP={seriesType:"lines",plan:xg(),reset:function(t){var e=t.coordinateSystem;if(e){var n=t.get("polyline"),i=t.pipelineContext.large;return{progress:function(r,o){var a=[];if(i){var s=void 0,l=r.end-r.start;if(n){for(var u=0,h=r.start;h0&&(l||s.configLayer(o,{motionBlur:!0,lastFrameAlpha:Math.max(Math.min(a/10+.9,1),0)})),r.updateData(i);var u=t.get("clip",!0)&&cS(t.coordinateSystem,!1,t);u?this.group.setClipPath(u):this.group.removeClipPath(),this._lastZlevel=o,this._finished=!0},e.prototype.incrementalPrepareRender=function(t,e,n){var i=t.getData();this._updateLineDraw(i,t).incrementalPrepareUpdate(i),this._clearLayer(n),this._finished=!1},e.prototype.incrementalRender=function(t,e,n){this._lineDraw.incrementalUpdate(t,e.getData()),this._finished=t.end===e.getData().count()},e.prototype.eachRendered=function(t){this._lineDraw&&this._lineDraw.eachRendered(t)},e.prototype.updateTransform=function(t,e,n){var i=t.getData(),r=t.pipelineContext;if(!this._finished||r.large||r.progressiveRender)return{update:!0};var o=kP.reset(t,e,n);o.progress&&o.progress({start:0,end:i.count(),count:i.count()},i),this._lineDraw.updateLayout(),this._clearLayer(n)},e.prototype._updateLineDraw=function(t,e){var n=this._lineDraw,i=this._showEffect(e),r=!!e.get("polyline"),o=e.pipelineContext.large;return n&&i===this._hasEffet&&r===this._isPolyline&&o===this._isLargeDraw||(n&&n.remove(),n=this._lineDraw=o?new AP:new _A(r?i?TP:IP:i?MP:xA),this._hasEffet=i,this._isPolyline=r,this._isLargeDraw=o),this.group.add(n.group),n},e.prototype._showEffect=function(t){return!!t.get(["effect","show"])},e.prototype._clearLayer=function(t){var e=t.getZr();"svg"===e.painter.getType()||null==this._lastZlevel||e.painter.getLayer(this._lastZlevel).clear(!0)},e.prototype.remove=function(t,e){this._lineDraw&&this._lineDraw.remove(),this._lineDraw=null,this._clearLayer(e)},e.prototype.dispose=function(t,e){this.remove(t,e)},e.type="lines",e}(wg),PP="undefined"==typeof Uint32Array?Array:Uint32Array,OP="undefined"==typeof Float64Array?Array:Float64Array;function RP(t){var e=t.data;e&&e[0]&&e[0][0]&&e[0][0].coord&&(t.data=z(e,(function(t){var e={coords:[t[0].coord,t[1].coord]};return t[0].name&&(e.fromName=t[0].name),t[1].name&&(e.toName=t[1].name),D([e,t[0],t[1]])})))}var NP=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.visualStyleAccessPath="lineStyle",n.visualDrawType="stroke",n}return n(e,t),e.prototype.init=function(e){e.data=e.data||[],RP(e);var n=this._processFlatCoordsArray(e.data);this._flatCoords=n.flatCoords,this._flatCoordsOffset=n.flatCoordsOffset,n.flatCoords&&(e.data=new Float32Array(n.count)),t.prototype.init.apply(this,arguments)},e.prototype.mergeOption=function(e){if(RP(e),e.data){var n=this._processFlatCoordsArray(e.data);this._flatCoords=n.flatCoords,this._flatCoordsOffset=n.flatCoordsOffset,n.flatCoords&&(e.data=new Float32Array(n.count))}t.prototype.mergeOption.apply(this,arguments)},e.prototype.appendData=function(t){var e=this._processFlatCoordsArray(t.data);e.flatCoords&&(this._flatCoords?(this._flatCoords=gt(this._flatCoords,e.flatCoords),this._flatCoordsOffset=gt(this._flatCoordsOffset,e.flatCoordsOffset)):(this._flatCoords=e.flatCoords,this._flatCoordsOffset=e.flatCoordsOffset),t.data=new Float32Array(e.count)),this.getRawData().appendData(t.data)},e.prototype._getCoordsFromItemModel=function(t){var e=this.getData().getItemModel(t),n=e.option instanceof Array?e.option:e.getShallow("coords");return n},e.prototype.getLineCoordsCount=function(t){return this._flatCoordsOffset?this._flatCoordsOffset[2*t+1]:this._getCoordsFromItemModel(t).length},e.prototype.getLineCoords=function(t,e){if(this._flatCoordsOffset){for(var n=this._flatCoordsOffset[2*t],i=this._flatCoordsOffset[2*t+1],r=0;r ")})},e.prototype.preventIncremental=function(){return!!this.get(["effect","show"])},e.prototype.getProgressive=function(){var t=this.option.progressive;return null==t?this.option.large?1e4:this.get("progressive"):t},e.prototype.getProgressiveThreshold=function(){var t=this.option.progressiveThreshold;return null==t?this.option.large?2e4:this.get("progressiveThreshold"):t},e.prototype.getZLevelKey=function(){var t=this.getModel("effect"),e=t.get("trailLength");return this.getData().count()>this.getProgressiveThreshold()?this.id:t.get("show")&&e>0?e+"":""},e.type="series.lines",e.dependencies=["grid","polar","geo","calendar"],e.defaultOption={coordinateSystem:"geo",z:2,legendHoverLink:!0,xAxisIndex:0,yAxisIndex:0,symbol:["none","none"],symbolSize:[10,10],geoIndex:0,effect:{show:!1,period:4,constantSpeed:0,symbol:"circle",symbolSize:3,loop:!0,trailLength:.2},large:!1,largeThreshold:2e3,polyline:!1,clip:!0,label:{show:!1,position:"end"},lineStyle:{opacity:.5}},e}(hg);function EP(t){return t instanceof Array||(t=[t,t]),t}var zP={seriesType:"lines",reset:function(t){var e=EP(t.get("symbol")),n=EP(t.get("symbolSize")),i=t.getData();return i.setVisual("fromSymbol",e&&e[0]),i.setVisual("toSymbol",e&&e[1]),i.setVisual("fromSymbolSize",n&&n[0]),i.setVisual("toSymbolSize",n&&n[1]),{dataEach:i.hasItemOption?function(t,e){var n=t.getItemModel(e),i=EP(n.getShallow("symbol",!0)),r=EP(n.getShallow("symbolSize",!0));i[0]&&t.setItemVisual(e,"fromSymbol",i[0]),i[1]&&t.setItemVisual(e,"toSymbol",i[1]),r[0]&&t.setItemVisual(e,"fromSymbolSize",r[0]),r[1]&&t.setItemVisual(e,"toSymbolSize",r[1])}:null}}};var VP=function(){function t(){this.blurSize=30,this.pointSize=20,this.maxOpacity=1,this.minOpacity=0,this._gradientPixels={inRange:null,outOfRange:null};var t=h.createCanvas();this.canvas=t}return t.prototype.update=function(t,e,n,i,r,o){var a=this._getBrush(),s=this._getGradient(r,"inRange"),l=this._getGradient(r,"outOfRange"),u=this.pointSize+this.blurSize,h=this.canvas,c=h.getContext("2d"),p=t.length;h.width=e,h.height=n;for(var d=0;d0){var I=o(v)?s:l;v>0&&(v=v*S+w),x[_++]=I[M],x[_++]=I[M+1],x[_++]=I[M+2],x[_++]=I[M+3]*v*256}else _+=4}return c.putImageData(m,0,0),h},t.prototype._getBrush=function(){var t=this._brushCanvas||(this._brushCanvas=h.createCanvas()),e=this.pointSize+this.blurSize,n=2*e;t.width=n,t.height=n;var i=t.getContext("2d");return i.clearRect(0,0,n,n),i.shadowOffsetX=n,i.shadowBlur=this.blurSize,i.shadowColor="#000",i.beginPath(),i.arc(-e,e,this.pointSize,0,2*Math.PI,!0),i.closePath(),i.fill(),t},t.prototype._getGradient=function(t,e){for(var n=this._gradientPixels,i=n[e]||(n[e]=new Uint8ClampedArray(1024)),r=[0,0,0,0],o=0,a=0;a<256;a++)t[e](a/255,!0,r),i[o++]=r[0],i[o++]=r[1],i[o++]=r[2],i[o++]=r[3];return i},t}();function BP(t){var e=t.dimensions;return"lng"===e[0]&&"lat"===e[1]}var FP=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){var i;e.eachComponent("visualMap",(function(e){e.eachTargetSeries((function(n){n===t&&(i=e)}))})),this._progressiveEls=null,this.group.removeAll();var r=t.coordinateSystem;"cartesian2d"===r.type||"calendar"===r.type?this._renderOnCartesianAndCalendar(t,n,0,t.getData().count()):BP(r)&&this._renderOnGeo(r,t,i,n)},e.prototype.incrementalPrepareRender=function(t,e,n){this.group.removeAll()},e.prototype.incrementalRender=function(t,e,n,i){var r=e.coordinateSystem;r&&(BP(r)?this.render(e,n,i):(this._progressiveEls=[],this._renderOnCartesianAndCalendar(e,i,t.start,t.end,!0)))},e.prototype.eachRendered=function(t){Yh(this._progressiveEls||this.group,t)},e.prototype._renderOnCartesianAndCalendar=function(t,e,n,i,r){var o,a,s,l,u=t.coordinateSystem,h=pS(u,"cartesian2d");if(h){var c=u.getAxis("x"),p=u.getAxis("y");0,o=c.getBandWidth()+.5,a=p.getBandWidth()+.5,s=c.scale.getExtent(),l=p.scale.getExtent()}for(var d=this.group,f=t.getData(),g=t.getModel(["emphasis","itemStyle"]).getItemStyle(),y=t.getModel(["blur","itemStyle"]).getItemStyle(),v=t.getModel(["select","itemStyle"]).getItemStyle(),m=t.get(["itemStyle","borderRadius"]),x=Kh(t),_=t.getModel("emphasis"),b=_.get("focus"),w=_.get("blurScope"),S=_.get("disabled"),M=h?[f.mapDimension("x"),f.mapDimension("y"),f.mapDimension("value")]:[f.mapDimension("time"),f.mapDimension("value")],I=n;Is[1]||Al[1])continue;var k=u.dataToPoint([D,A]);T=new Ps({shape:{x:k[0]-o/2,y:k[1]-a/2,width:o,height:a},style:C})}else{if(isNaN(f.get(M[1],I)))continue;T=new Ps({z2:1,shape:u.dataToRect([f.get(M[0],I)]).contentShape,style:C})}if(f.hasItemOption){var L=f.getItemModel(I),P=L.getModel("emphasis");g=P.getModel("itemStyle").getItemStyle(),y=L.getModel(["blur","itemStyle"]).getItemStyle(),v=L.getModel(["select","itemStyle"]).getItemStyle(),m=L.get(["itemStyle","borderRadius"]),b=P.get("focus"),w=P.get("blurScope"),S=P.get("disabled"),x=Kh(L)}T.shape.r=m;var O=t.getRawValue(I),R="-";O&&null!=O[2]&&(R=O[2]+""),qh(T,x,{labelFetcher:t,labelDataIndex:I,defaultOpacity:C.opacity,defaultText:R}),T.ensureState("emphasis").style=g,T.ensureState("blur").style=y,T.ensureState("select").style=v,Bl(T,b,w,S),T.incremental=r,r&&(T.states.emphasis.hoverLayer=!0),d.add(T),f.setItemGraphicEl(I,T),this._progressiveEls&&this._progressiveEls.push(T)}},e.prototype._renderOnGeo=function(t,e,n,i){var r=n.targetVisuals.inRange,o=n.targetVisuals.outOfRange,a=e.getData(),s=this._hmLayer||this._hmLayer||new VP;s.blurSize=e.get("blurSize"),s.pointSize=e.get("pointSize"),s.minOpacity=e.get("minOpacity"),s.maxOpacity=e.get("maxOpacity");var l=t.getViewRect().clone(),u=t.getRoamTransform();l.applyTransform(u);var h=Math.max(l.x,0),c=Math.max(l.y,0),p=Math.min(l.width+l.x,i.getWidth()),d=Math.min(l.height+l.y,i.getHeight()),f=p-h,g=d-c,y=[a.mapDimension("lng"),a.mapDimension("lat"),a.mapDimension("value")],v=a.mapArray(y,(function(e,n,i){var r=t.dataToPoint([e,n]);return r[0]-=h,r[1]-=c,r.push(i),r})),m=n.getExtent(),x="visualMap.continuous"===n.type?function(t,e){var n=t[1]-t[0];return e=[(e[0]-t[0])/n,(e[1]-t[0])/n],function(t){return t>=e[0]&&t<=e[1]}}(m,n.option.range):function(t,e,n){var i=t[1]-t[0],r=(e=z(e,(function(e){return{interval:[(e.interval[0]-t[0])/i,(e.interval[1]-t[0])/i]}}))).length,o=0;return function(t){var i;for(i=o;i=0;i--){var a;if((a=e[i].interval)[0]<=t&&t<=a[1]){o=i;break}}return i>=0&&i0?1:-1}(n,o,r,i,c),function(t,e,n,i,r,o,a,s,l,u){var h,c=l.valueDim,p=l.categoryDim,d=Math.abs(n[p.wh]),f=t.getItemVisual(e,"symbolSize");h=Y(f)?f.slice():null==f?["100%","100%"]:[f,f];h[p.index]=Gr(h[p.index],d),h[c.index]=Gr(h[c.index],i?d:Math.abs(o)),u.symbolSize=h,(u.symbolScale=[h[0]/s,h[1]/s])[c.index]*=(l.isHorizontal?-1:1)*a}(t,e,r,o,0,c.boundingLength,c.pxSign,u,i,c),function(t,e,n,i,r){var o=t.get(WP)||0;o&&(YP.attr({scaleX:e[0],scaleY:e[1],rotation:n}),YP.updateTransform(),o/=YP.getLineScale(),o*=e[i.valueDim.index]);r.valueLineWidth=o||0}(n,c.symbolScale,l,i,c);var p=c.symbolSize,d=Ey(n.get("symbolOffset"),p);return function(t,e,n,i,r,o,a,s,l,u,h,c){var p=h.categoryDim,d=h.valueDim,f=c.pxSign,g=Math.max(e[d.index]+s,0),y=g;if(i){var v=Math.abs(l),m=it(t.get("symbolMargin"),"15%")+"",x=!1;m.lastIndexOf("!")===m.length-1&&(x=!0,m=m.slice(0,m.length-1));var _=Gr(m,e[d.index]),b=Math.max(g+2*_,0),w=x?0:2*_,S=ao(i),M=S?i:lO((v+w)/b);b=g+2*(_=(v-M*g)/2/(x?M:Math.max(M-1,1))),w=x?0:2*_,S||"fixed"===i||(M=u?lO((Math.abs(u)+w)/b):0),y=M*b-w,c.repeatTimes=M,c.symbolMargin=_}var I=f*(y/2),T=c.pathPosition=[];T[p.index]=n[p.wh]/2,T[d.index]="start"===a?I:"end"===a?l-I:l/2,o&&(T[0]+=o[0],T[1]+=o[1]);var C=c.bundlePosition=[];C[p.index]=n[p.xy],C[d.index]=n[d.xy];var D=c.barRectShape=A({},n);D[d.wh]=f*Math.max(Math.abs(n[d.wh]),Math.abs(T[d.index]+I)),D[p.wh]=n[p.wh];var k=c.clipShape={};k[p.xy]=-n[p.xy],k[p.wh]=h.ecSize[p.wh],k[d.xy]=0,k[d.wh]=n[d.wh]}(n,p,r,o,0,d,s,c.valueLineWidth,c.boundingLength,c.repeatCutLength,i,c),c}function ZP(t,e){return t.toGlobalCoord(t.dataToCoord(t.scale.parse(e)))}function jP(t){var e=t.symbolPatternSize,n=Ry(t.symbolType,-e/2,-e/2,e,e);return n.attr({culling:!0}),"image"!==n.type&&n.setStyle({strokeNoScale:!0}),n}function qP(t,e,n,i){var r=t.__pictorialBundle,o=n.symbolSize,a=n.valueLineWidth,s=n.pathPosition,l=e.valueDim,u=n.repeatTimes||0,h=0,c=o[e.valueDim.index]+a+2*n.symbolMargin;for(oO(t,(function(t){t.__pictorialAnimationIndex=h,t.__pictorialRepeatTimes=u,h0:i<0)&&(r=u-1-t),e[l.index]=c*(r-u/2+.5)+s[l.index],{x:e[0],y:e[1],scaleX:n.symbolScale[0],scaleY:n.symbolScale[1],rotation:n.rotation}}}function KP(t,e,n,i){var r=t.__pictorialBundle,o=t.__pictorialMainPath;o?aO(o,null,{x:n.pathPosition[0],y:n.pathPosition[1],scaleX:n.symbolScale[0],scaleY:n.symbolScale[1],rotation:n.rotation},n,i):(o=t.__pictorialMainPath=jP(n),r.add(o),aO(o,{x:n.pathPosition[0],y:n.pathPosition[1],scaleX:0,scaleY:0,rotation:n.rotation},{scaleX:n.symbolScale[0],scaleY:n.symbolScale[1]},n,i))}function $P(t,e,n){var i=A({},e.barRectShape),r=t.__pictorialBarRect;r?aO(r,null,{shape:i},e,n):((r=t.__pictorialBarRect=new Ps({z2:2,shape:i,silent:!0,style:{stroke:"transparent",fill:"transparent",lineWidth:0}})).disableMorphing=!0,t.add(r))}function JP(t,e,n,i){if(n.symbolClip){var r=t.__pictorialClipPath,o=A({},n.clipShape),a=e.valueDim,s=n.animationModel,l=n.dataIndex;if(r)uh(r,{shape:o},s,l);else{o[a.wh]=0,r=new Ps({shape:o}),t.__pictorialBundle.setClipPath(r),t.__pictorialClipPath=r;var u={};u[a.wh]=n.clipShape[a.wh],Uh[i?"updateProps":"initProps"](r,{shape:u},s,l)}}}function QP(t,e){var n=t.getItemModel(e);return n.getAnimationDelayParams=tO,n.isAnimationEnabled=eO,n}function tO(t){return{index:t.__pictorialAnimationIndex,count:t.__pictorialRepeatTimes}}function eO(){return this.parentModel.isAnimationEnabled()&&!!this.getShallow("animation")}function nO(t,e,n,i){var r=new Pr,o=new Pr;return r.add(o),r.__pictorialBundle=o,o.x=n.bundlePosition[0],o.y=n.bundlePosition[1],n.symbolRepeat?qP(r,e,n):KP(r,0,n),$P(r,n,i),JP(r,e,n,i),r.__pictorialShapeStr=rO(t,n),r.__pictorialSymbolMeta=n,r}function iO(t,e,n,i){var r=i.__pictorialBarRect;r&&r.removeTextContent();var o=[];oO(i,(function(t){o.push(t)})),i.__pictorialMainPath&&o.push(i.__pictorialMainPath),i.__pictorialClipPath&&(n=null),E(o,(function(t){ph(t,{scaleX:0,scaleY:0},n,e,(function(){i.parent&&i.parent.remove(i)}))})),t.setItemGraphicEl(e,null)}function rO(t,e){return[t.getItemVisual(e.dataIndex,"symbol")||"none",!!e.symbolRepeat,!!e.symbolClip].join(":")}function oO(t,e,n){E(t.__pictorialBundle.children(),(function(i){i!==t.__pictorialBarRect&&e.call(n,i)}))}function aO(t,e,n,i,r,o){e&&t.attr(e),i.symbolClip&&!r?n&&t.attr(n):n&&Uh[r?"updateProps":"initProps"](t,n,i.animationModel,i.dataIndex,o)}function sO(t,e,n){var i=n.dataIndex,r=n.itemModel,o=r.getModel("emphasis"),a=o.getModel("itemStyle").getItemStyle(),s=r.getModel(["blur","itemStyle"]).getItemStyle(),l=r.getModel(["select","itemStyle"]).getItemStyle(),u=r.getShallow("cursor"),h=o.get("focus"),c=o.get("blurScope"),p=o.get("scale");oO(t,(function(t){if(t instanceof Is){var e=t.style;t.useStyle(A({image:e.image,x:e.x,y:e.y,width:e.width,height:e.height},n.style))}else t.useStyle(n.style);var i=t.ensureState("emphasis");i.style=a,p&&(i.scaleX=1.1*t.scaleX,i.scaleY=1.1*t.scaleY),t.ensureState("blur").style=s,t.ensureState("select").style=l,u&&(t.cursor=u),t.z2=n.z2}));var d=e.valueDim.posDesc[+(n.boundingLength>0)];qh(t.__pictorialBarRect,Kh(r),{labelFetcher:e.seriesModel,labelDataIndex:i,defaultText:Uw(e.seriesModel.getData(),i),inheritColor:n.style.fill,defaultOpacity:n.style.opacity,defaultOutsidePosition:d}),Bl(t,h,c,o.get("disabled"))}function lO(t){var e=Math.round(t);return Math.abs(t-e)<1e-4?e:Math.ceil(t)}var uO=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.hasSymbolVisual=!0,n.defaultSymbol="roundRect",n}return n(e,t),e.prototype.getInitialData=function(e){return e.stack=null,t.prototype.getInitialData.apply(this,arguments)},e.type="series.pictorialBar",e.dependencies=["grid"],e.defaultOption=wc(DS.defaultOption,{symbol:"circle",symbolSize:null,symbolRotate:null,symbolPosition:null,symbolOffset:null,symbolMargin:null,symbolRepeat:!1,symbolRepeatDirection:"end",symbolClip:!1,symbolBoundingData:null,symbolPatternSize:400,barGap:"-100%",progressive:0,emphasis:{scale:!1},select:{itemStyle:{borderColor:"#212121"}}}),e}(DS);var hO=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n._layers=[],n}return n(e,t),e.prototype.render=function(t,e,n){var i=t.getData(),r=this,o=this.group,a=t.getLayerSeries(),s=i.getLayout("layoutInfo"),l=s.rect,u=s.boundaryGap;function h(t){return t.name}o.x=0,o.y=l.y+u[0];var c=new Dm(this._layersSeries||[],a,h,h),p=[];function d(e,n,s){var l=r._layers;if("remove"!==e){for(var u,h,c=[],d=[],f=a[n].indices,g=0;go&&(o=s),i.push(s)}for(var u=0;uo&&(o=c)}return{y0:r,max:o}}(l),h=u.y0,c=n/u.max,p=o.length,d=o[0].indices.length,f=0;fMath.PI/2?"right":"left"):S&&"center"!==S?"left"===S?(m=r.r0+w,a>Math.PI/2&&(S="right")):"right"===S&&(m=r.r-w,a>Math.PI/2&&(S="left")):(m=o===2*Math.PI&&0===r.r0?0:(r.r+r.r0)/2,S="center"),g.style.align=S,g.style.verticalAlign=f(p,"verticalAlign")||"middle",g.x=m*s+r.cx,g.y=m*l+r.cy;var M=f(p,"rotate"),I=0;"radial"===M?(I=-a)<-Math.PI/2&&(I+=Math.PI):"tangential"===M?(I=Math.PI/2-a)>Math.PI/2?I-=Math.PI:I<-Math.PI/2&&(I+=Math.PI):j(M)&&(I=M*Math.PI/180),g.rotation=I})),h.dirtyStyle()},e}(Pu),gO="sunburstRootToNode",yO="sunburstHighlight";var vO=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n,i){var r=this;this.seriesModel=t,this.api=n,this.ecModel=e;var o=t.getData(),a=o.tree.root,s=t.getViewRoot(),l=this.group,u=t.get("renderLabelForZeroData"),h=[];s.eachNode((function(t){h.push(t)}));var c=this._oldChildren||[];!function(i,r){if(0===i.length&&0===r.length)return;function s(t){return t.getId()}function h(s,h){!function(i,r){u||!i||i.getValue()||(i=null);if(i!==a&&r!==a)if(r&&r.piece)i?(r.piece.updateData(!1,i,t,e,n),o.setItemGraphicEl(i.dataIndex,r.piece)):function(t){if(!t)return;t.piece&&(l.remove(t.piece),t.piece=null)}(r);else if(i){var s=new fO(i,t,e,n);l.add(s),o.setItemGraphicEl(i.dataIndex,s)}}(null==s?null:i[s],null==h?null:r[h])}new Dm(r,i,s,s).add(h).update(h).remove(H(h,null)).execute()}(h,c),function(i,o){o.depth>0?(r.virtualPiece?r.virtualPiece.updateData(!1,i,t,e,n):(r.virtualPiece=new fO(i,t,e,n),l.add(r.virtualPiece)),o.piece.off("click"),r.virtualPiece.on("click",(function(t){r._rootToNode(o.parentNode)}))):r.virtualPiece&&(l.remove(r.virtualPiece),r.virtualPiece=null)}(a,s),this._initEvents(),this._oldChildren=h},e.prototype._initEvents=function(){var t=this;this.group.off("click"),this.group.on("click",(function(e){var n=!1;t.seriesModel.getViewRoot().eachNode((function(i){if(!n&&i.piece&&i.piece===e.target){var r=i.getModel().get("nodeClick");if("rootToNode"===r)t._rootToNode(i);else if("link"===r){var o=i.getModel(),a=o.get("link");if(a)yp(a,o.get("target",!0)||"_blank")}n=!0}}))}))},e.prototype._rootToNode=function(t){t!==this.seriesModel.getViewRoot()&&this.api.dispatchAction({type:gO,from:this.uid,seriesId:this.seriesModel.id,targetNode:t})},e.prototype.containPoint=function(t,e){var n=e.getData().getItemLayout(0);if(n){var i=t[0]-n.cx,r=t[1]-n.cy,o=Math.sqrt(i*i+r*r);return o<=n.r&&o>=n.r0}},e.type="sunburst",e}(wg),mO=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.ignoreStyleOnData=!0,n}return n(e,t),e.prototype.getInitialData=function(t,e){var n={name:t.name,children:t.data};xO(n);var i=this._levelModels=z(t.levels||[],(function(t){return new xc(t,this,e)}),this),r=OC.createTree(n,this,(function(t){t.wrapMethod("getItemModel",(function(t,e){var n=r.getNodeByDataIndex(e),o=i[n.depth];return o&&(t.parentModel=o),t}))}));return r.data},e.prototype.optionUpdated=function(){this.resetViewRoot()},e.prototype.getDataParams=function(e){var n=t.prototype.getDataParams.apply(this,arguments),i=this.getData().tree.getNodeByDataIndex(e);return n.treePathInfo=zC(i,this),n},e.prototype.getLevelModel=function(t){return this._levelModels&&this._levelModels[t.depth]},e.prototype.getViewRoot=function(){return this._viewRoot},e.prototype.resetViewRoot=function(t){t?this._viewRoot=t:t=this._viewRoot;var e=this.getRawData().tree.root;t&&(t===e||e.contains(t))||(this._viewRoot=e)},e.prototype.enableAriaDecal=function(){HC(this)},e.type="series.sunburst",e.defaultOption={z:2,center:["50%","50%"],radius:[0,"75%"],clockwise:!0,startAngle:90,minAngle:0,stillShowZeroSum:!0,nodeClick:"rootToNode",renderLabelForZeroData:!1,label:{rotate:"radial",show:!0,opacity:1,align:"center",position:"inside",distance:5,silent:!0},itemStyle:{borderWidth:1,borderColor:"white",borderType:"solid",shadowBlur:0,shadowColor:"rgba(0, 0, 0, 0.2)",shadowOffsetX:0,shadowOffsetY:0,opacity:1},emphasis:{focus:"descendant"},blur:{itemStyle:{opacity:.2},label:{opacity:.1}},animationType:"expansion",animationDuration:1e3,animationDurationUpdate:500,data:[],sort:"desc"},e}(hg);function xO(t){var e=0;E(t.children,(function(t){xO(t);var n=t.value;Y(n)&&(n=n[0]),e+=n}));var n=t.value;Y(n)&&(n=n[0]),(null==n||isNaN(n))&&(n=e),n<0&&(n=0),Y(t.value)?t.value[0]=n:t.value=n}var _O=Math.PI/180;function bO(t,e,n){e.eachSeriesByType(t,(function(t){var e=t.get("center"),i=t.get("radius");Y(i)||(i=[0,i]),Y(e)||(e=[e,e]);var r=n.getWidth(),o=n.getHeight(),a=Math.min(r,o),s=Gr(e[0],r),l=Gr(e[1],o),u=Gr(i[0],a/2),h=Gr(i[1],a/2),c=-t.get("startAngle")*_O,p=t.get("minAngle")*_O,d=t.getData().tree.root,f=t.getViewRoot(),g=f.depth,y=t.get("sort");null!=y&&wO(f,y);var v=0;E(f.children,(function(t){!isNaN(t.getValue())&&v++}));var m=f.getValue(),x=Math.PI/(m||v)*2,_=f.depth>0,b=f.height-(_?-1:1),w=(h-u)/(b||1),S=t.get("clockwise"),M=t.get("stillShowZeroSum"),I=S?1:-1,T=function(e,n){if(e){var i=n;if(e!==d){var r=e.getValue(),o=0===m&&M?x:r*x;o1;)r=r.parentNode;var o=n.getColorFromPalette(r.name||r.dataIndex+"",e);return t.depth>1&&X(o)&&(o=jn(o,(t.depth-1)/(i-1)*.5)),o}(r,t,i.root.height)),A(n.ensureUniqueItemVisual(r.dataIndex,"style"),o)}))}))}var MO={color:"fill",borderColor:"stroke"},IO={symbol:1,symbolSize:1,symbolKeepAspect:1,legendIcon:1,visualMeta:1,liftZ:1,decal:1},TO=Do(),CO=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.optionUpdated=function(){this.currentZLevel=this.get("zlevel",!0),this.currentZ=this.get("z",!0)},e.prototype.getInitialData=function(t,e){return sx(null,this)},e.prototype.getDataParams=function(e,n,i){var r=t.prototype.getDataParams.call(this,e,n);return i&&(r.info=TO(i).info),r},e.type="series.custom",e.dependencies=["grid","polar","geo","singleAxis","calendar"],e.defaultOption={coordinateSystem:"cartesian2d",z:2,legendHoverLink:!0,clip:!1},e}(hg);function DO(t,e){return e=e||[0,0],z(["x","y"],(function(n,i){var r=this.getAxis(n),o=e[i],a=t[i]/2;return"category"===r.type?r.getBandWidth():Math.abs(r.dataToCoord(o-a)-r.dataToCoord(o+a))}),this)}function AO(t,e){return e=e||[0,0],z([0,1],(function(n){var i=e[n],r=t[n]/2,o=[],a=[];return o[n]=i-r,a[n]=i+r,o[1-n]=a[1-n]=e[1-n],Math.abs(this.dataToPoint(o)[n]-this.dataToPoint(a)[n])}),this)}function kO(t,e){var n=this.getAxis(),i=e instanceof Array?e[0]:e,r=(t instanceof Array?t[0]:t)/2;return"category"===n.type?n.getBandWidth():Math.abs(n.dataToCoord(i-r)-n.dataToCoord(i+r))}function LO(t,e){return e=e||[0,0],z(["Radius","Angle"],(function(n,i){var r=this["get"+n+"Axis"](),o=e[i],a=t[i]/2,s="category"===r.type?r.getBandWidth():Math.abs(r.dataToCoord(o-a)-r.dataToCoord(o+a));return"Angle"===n&&(s=s*Math.PI/180),s}),this)}function PO(t,e,n,i){return t&&(t.legacy||!1!==t.legacy&&!n&&!i&&"tspan"!==e&&("text"===e||mt(t,"text")))}function OO(t,e,n){var i,r,o,a=t;if("text"===e)o=a;else{o={},mt(a,"text")&&(o.text=a.text),mt(a,"rich")&&(o.rich=a.rich),mt(a,"textFill")&&(o.fill=a.textFill),mt(a,"textStroke")&&(o.stroke=a.textStroke),mt(a,"fontFamily")&&(o.fontFamily=a.fontFamily),mt(a,"fontSize")&&(o.fontSize=a.fontSize),mt(a,"fontStyle")&&(o.fontStyle=a.fontStyle),mt(a,"fontWeight")&&(o.fontWeight=a.fontWeight),r={type:"text",style:o,silent:!0},i={};var s=mt(a,"textPosition");n?i.position=s?a.textPosition:"inside":s&&(i.position=a.textPosition),mt(a,"textPosition")&&(i.position=a.textPosition),mt(a,"textOffset")&&(i.offset=a.textOffset),mt(a,"textRotation")&&(i.rotation=a.textRotation),mt(a,"textDistance")&&(i.distance=a.textDistance)}return RO(o,t),E(o.rich,(function(t){RO(t,t)})),{textConfig:i,textContent:r}}function RO(t,e){e&&(e.font=e.textFont||e.font,mt(e,"textStrokeWidth")&&(t.lineWidth=e.textStrokeWidth),mt(e,"textAlign")&&(t.align=e.textAlign),mt(e,"textVerticalAlign")&&(t.verticalAlign=e.textVerticalAlign),mt(e,"textLineHeight")&&(t.lineHeight=e.textLineHeight),mt(e,"textWidth")&&(t.width=e.textWidth),mt(e,"textHeight")&&(t.height=e.textHeight),mt(e,"textBackgroundColor")&&(t.backgroundColor=e.textBackgroundColor),mt(e,"textPadding")&&(t.padding=e.textPadding),mt(e,"textBorderColor")&&(t.borderColor=e.textBorderColor),mt(e,"textBorderWidth")&&(t.borderWidth=e.textBorderWidth),mt(e,"textBorderRadius")&&(t.borderRadius=e.textBorderRadius),mt(e,"textBoxShadowColor")&&(t.shadowColor=e.textBoxShadowColor),mt(e,"textBoxShadowBlur")&&(t.shadowBlur=e.textBoxShadowBlur),mt(e,"textBoxShadowOffsetX")&&(t.shadowOffsetX=e.textBoxShadowOffsetX),mt(e,"textBoxShadowOffsetY")&&(t.shadowOffsetY=e.textBoxShadowOffsetY))}function NO(t,e,n){var i=t;i.textPosition=i.textPosition||n.position||"inside",null!=n.offset&&(i.textOffset=n.offset),null!=n.rotation&&(i.textRotation=n.rotation),null!=n.distance&&(i.textDistance=n.distance);var r=i.textPosition.indexOf("inside")>=0,o=t.fill||"#000";EO(i,e);var a=null==i.textFill;return r?a&&(i.textFill=n.insideFill||"#fff",!i.textStroke&&n.insideStroke&&(i.textStroke=n.insideStroke),!i.textStroke&&(i.textStroke=o),null==i.textStrokeWidth&&(i.textStrokeWidth=2)):(a&&(i.textFill=t.fill||n.outsideFill||"#000"),!i.textStroke&&n.outsideStroke&&(i.textStroke=n.outsideStroke)),i.text=e.text,i.rich=e.rich,E(e.rich,(function(t){EO(t,t)})),i}function EO(t,e){e&&(mt(e,"fill")&&(t.textFill=e.fill),mt(e,"stroke")&&(t.textStroke=e.fill),mt(e,"lineWidth")&&(t.textStrokeWidth=e.lineWidth),mt(e,"font")&&(t.font=e.font),mt(e,"fontStyle")&&(t.fontStyle=e.fontStyle),mt(e,"fontWeight")&&(t.fontWeight=e.fontWeight),mt(e,"fontSize")&&(t.fontSize=e.fontSize),mt(e,"fontFamily")&&(t.fontFamily=e.fontFamily),mt(e,"align")&&(t.textAlign=e.align),mt(e,"verticalAlign")&&(t.textVerticalAlign=e.verticalAlign),mt(e,"lineHeight")&&(t.textLineHeight=e.lineHeight),mt(e,"width")&&(t.textWidth=e.width),mt(e,"height")&&(t.textHeight=e.height),mt(e,"backgroundColor")&&(t.textBackgroundColor=e.backgroundColor),mt(e,"padding")&&(t.textPadding=e.padding),mt(e,"borderColor")&&(t.textBorderColor=e.borderColor),mt(e,"borderWidth")&&(t.textBorderWidth=e.borderWidth),mt(e,"borderRadius")&&(t.textBorderRadius=e.borderRadius),mt(e,"shadowColor")&&(t.textBoxShadowColor=e.shadowColor),mt(e,"shadowBlur")&&(t.textBoxShadowBlur=e.shadowBlur),mt(e,"shadowOffsetX")&&(t.textBoxShadowOffsetX=e.shadowOffsetX),mt(e,"shadowOffsetY")&&(t.textBoxShadowOffsetY=e.shadowOffsetY),mt(e,"textShadowColor")&&(t.textShadowColor=e.textShadowColor),mt(e,"textShadowBlur")&&(t.textShadowBlur=e.textShadowBlur),mt(e,"textShadowOffsetX")&&(t.textShadowOffsetX=e.textShadowOffsetX),mt(e,"textShadowOffsetY")&&(t.textShadowOffsetY=e.textShadowOffsetY))}var zO={position:["x","y"],scale:["scaleX","scaleY"],origin:["originX","originY"]},VO=G(zO),BO=(V(cr,(function(t,e){return t[e]=1,t}),{}),cr.join(", "),["","style","shape","extra"]),FO=Do();function GO(t,e,n,i,r){var o=t+"Animation",a=sh(t,i,r)||{},s=FO(e).userDuring;return a.duration>0&&(a.during=s?W(jO,{el:e,userDuring:s}):null,a.setToFinal=!0,a.scope=t),A(a,n[o]),a}function WO(t,e,n,i){var r=(i=i||{}).dataIndex,o=i.isInit,a=i.clearStyle,s=n.isAnimationEnabled(),l=FO(t),u=e.style;l.userDuring=e.during;var h={},c={};if(function(t,e,n){for(var i=0;i=0)){var c=t.getAnimationStyleProps(),p=c?c.style:null;if(p){!r&&(r=i.style={});var d=G(n);for(u=0;u0&&t.animateFrom(p,d)}else!function(t,e,n,i,r){if(r){var o=GO("update",t,e,i,n);o.duration>0&&t.animateFrom(r,o)}}(t,e,r||0,n,h);HO(t,e),u?t.dirty():t.markRedraw()}function HO(t,e){for(var n=FO(t).leaveToProps,i=0;i=0){!o&&(o=i[t]={});var p=G(a);for(h=0;hi[1]&&i.reverse(),{coordSys:{type:"polar",cx:t.cx,cy:t.cy,r:i[1],r0:i[0]},api:{coord:function(i){var r=e.dataToRadius(i[0]),o=n.dataToAngle(i[1]),a=t.coordToPoint([r,o]);return a.push(r,o*Math.PI/180),a},size:W(LO,t)}}},calendar:function(t){var e=t.getRect(),n=t.getRangeInfo();return{coordSys:{type:"calendar",x:e.x,y:e.y,width:e.width,height:e.height,cellWidth:t.getCellWidth(),cellHeight:t.getCellHeight(),rangeInfo:{start:n.start,end:n.end,weeks:n.weeks,dayCount:n.allDay}},api:{coord:function(e,n){return t.dataToPoint(e,n)}}}}};function pR(t){return t instanceof _s}function dR(t){return t instanceof ma}var fR=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n,i){this._progressiveEls=null;var r=this._data,o=t.getData(),a=this.group,s=xR(t,o,e,n);r||a.removeAll(),o.diff(r).add((function(e){bR(n,null,e,s(e,i),t,a,o)})).remove((function(e){var n=r.getItemGraphicEl(e);n&&YO(n,TO(n).option,t)})).update((function(e,l){var u=r.getItemGraphicEl(l);bR(n,u,e,s(e,i),t,a,o)})).execute();var l=t.get("clip",!0)?cS(t.coordinateSystem,!1,t):null;l?a.setClipPath(l):a.removeClipPath(),this._data=o},e.prototype.incrementalPrepareRender=function(t,e,n){this.group.removeAll(),this._data=null},e.prototype.incrementalRender=function(t,e,n,i,r){var o=e.getData(),a=xR(e,o,n,i),s=this._progressiveEls=[];function l(t){t.isGroup||(t.incremental=!0,t.ensureState("emphasis").hoverLayer=!0)}for(var u=t.start;u=0?e.getStore().get(r,n):void 0}var o=e.get(i.name,n),a=i&&i.ordinalMeta;return a?a.categories[o]:o},styleEmphasis:function(n,i){0;null==i&&(i=s);var r=m(i,nR).getItemStyle(),o=x(i,nR),a=$h(o,null,null,!0,!0);a.text=o.getShallow("show")?ot(t.getFormattedLabel(i,nR),t.getFormattedLabel(i,iR),Uw(e,i)):null;var l=Jh(o,null,!0);return b(n,r),r=NO(r,a,l),n&&_(r,n),r.legacy=!0,r},visual:function(t,n){if(null==n&&(n=s),mt(MO,t)){var i=e.getItemVisual(n,"style");return i?i[MO[t]]:null}if(mt(IO,t))return e.getItemVisual(n,t)},barLayout:function(t){if("cartesian2d"===o.type){return function(t){var e=[],n=t.axis,i="axis0";if("category"===n.type){for(var r=n.getBandWidth(),o=0;o=c;f--){var g=e.childAt(f);CR(e,g,r)}}(t,c,n,i,r),a>=0?o.replaceAt(c,a):o.add(c),c}function SR(t,e,n){var i,r=TO(t),o=e.type,a=e.shape,s=e.style;return n.isUniversalTransitionEnabled()||null!=o&&o!==r.customGraphicType||"path"===o&&((i=a)&&(mt(i,"pathData")||mt(i,"d")))&&LR(a)!==r.customPathData||"image"===o&&mt(s,"image")&&s.image!==r.customImagePath}function MR(t,e,n){var i=e?IR(t,e):t,r=e?TR(t,i,nR):t.style,o=t.type,a=i?i.textConfig:null,s=t.textContent,l=s?e?IR(s,e):s:null;if(r&&(n.isLegacy||PO(r,o,!!a,!!l))){n.isLegacy=!0;var u=OO(r,o,!e);!a&&u.textConfig&&(a=u.textConfig),!l&&u.textContent&&(l=u.textContent)}if(!e&&l){var h=l;!h.type&&(h.type="text")}var c=e?n[e]:n.normal;c.cfg=a,c.conOpt=l}function IR(t,e){return e?t?t[e]:null:t}function TR(t,e,n){var i=e&&e.style;return null==i&&n===nR&&t&&(i=t.styleEmphasis),i}function CR(t,e,n){e&&YO(e,TO(t).option,n)}function DR(t,e){var n=t&&t.name;return null!=n?n:"e\0\0"+e}function AR(t,e){var n=this.context,i=null!=t?n.newChildren[t]:null,r=null!=e?n.oldChildren[e]:null;wR(n.api,r,n.dataIndex,i,n.seriesModel,n.group)}function kR(t){var e=this.context,n=e.oldChildren[t];n&&YO(n,TO(n).option,e.seriesModel)}function LR(t){return t&&(t.pathData||t.d)}var PR=Do(),OR=T,RR=W,NR=function(){function t(){this._dragging=!1,this.animationThreshold=15}return t.prototype.render=function(t,e,n,i){var r=e.get("value"),o=e.get("status");if(this._axisModel=t,this._axisPointerModel=e,this._api=n,i||this._lastValue!==r||this._lastStatus!==o){this._lastValue=r,this._lastStatus=o;var a=this._group,s=this._handle;if(!o||"hide"===o)return a&&a.hide(),void(s&&s.hide());a&&a.show(),s&&s.show();var l={};this.makeElOption(l,r,t,e,n);var u=l.graphicKey;u!==this._lastGraphicKey&&this.clear(n),this._lastGraphicKey=u;var h=this._moveAnimation=this.determineAnimation(t,e);if(a){var c=H(ER,e,h);this.updatePointerEl(a,l,c),this.updateLabelEl(a,l,c,e)}else a=this._group=new Pr,this.createPointerEl(a,l,t,e),this.createLabelEl(a,l,t,e),n.getZr().add(a);FR(a,e,!0),this._renderHandle(r)}},t.prototype.remove=function(t){this.clear(t)},t.prototype.dispose=function(t){this.clear(t)},t.prototype.determineAnimation=function(t,e){var n=e.get("animation"),i=t.axis,r="category"===i.type,o=e.get("snap");if(!o&&!r)return!1;if("auto"===n||null==n){var a=this.animationThreshold;if(r&&i.getBandWidth()>a)return!0;if(o){var s=QM(t).seriesDataCount,l=i.getExtent();return Math.abs(l[0]-l[1])/s>a}return!1}return!0===n},t.prototype.makeElOption=function(t,e,n,i,r){},t.prototype.createPointerEl=function(t,e,n,i){var r=e.pointer;if(r){var o=PR(t).pointerEl=new Uh[r.type](OR(e.pointer));t.add(o)}},t.prototype.createLabelEl=function(t,e,n,i){if(e.label){var r=PR(t).labelEl=new Ns(OR(e.label));t.add(r),VR(r,i)}},t.prototype.updatePointerEl=function(t,e,n){var i=PR(t).pointerEl;i&&e.pointer&&(i.setStyle(e.pointer.style),n(i,{shape:e.pointer.shape}))},t.prototype.updateLabelEl=function(t,e,n,i){var r=PR(t).labelEl;r&&(r.setStyle(e.label.style),n(r,{x:e.label.x,y:e.label.y}),VR(r,i))},t.prototype._renderHandle=function(t){if(!this._dragging&&this.updateHandleTransform){var e,n=this._axisPointerModel,i=this._api.getZr(),r=this._handle,o=n.getModel("handle"),a=n.get("status");if(!o.get("show")||!a||"hide"===a)return r&&i.remove(r),void(this._handle=null);this._handle||(e=!0,r=this._handle=Vh(o.get("icon"),{cursor:"move",draggable:!0,onmousemove:function(t){he(t.event)},onmousedown:RR(this._onHandleDragMove,this,0,0),drift:RR(this._onHandleDragMove,this),ondragend:RR(this._onHandleDragEnd,this)}),i.add(r)),FR(r,n,!1),r.setStyle(o.getItemStyle(null,["color","borderColor","borderWidth","opacity","shadowColor","shadowBlur","shadowOffsetX","shadowOffsetY"]));var s=o.get("size");Y(s)||(s=[s,s]),r.scaleX=s[0]/2,r.scaleY=s[1]/2,Pg(this,"_doDispatchAxisPointer",o.get("throttle")||0,"fixRate"),this._moveHandleToValue(t,e)}},t.prototype._moveHandleToValue=function(t,e){ER(this._axisPointerModel,!e&&this._moveAnimation,this._handle,BR(this.getHandleTransform(t,this._axisModel,this._axisPointerModel)))},t.prototype._onHandleDragMove=function(t,e){var n=this._handle;if(n){this._dragging=!0;var i=this.updateHandleTransform(BR(n),[t,e],this._axisModel,this._axisPointerModel);this._payloadInfo=i,n.stopAnimation(),n.attr(BR(i)),PR(n).lastProp=null,this._doDispatchAxisPointer()}},t.prototype._doDispatchAxisPointer=function(){if(this._handle){var t=this._payloadInfo,e=this._axisModel;this._api.dispatchAction({type:"updateAxisPointer",x:t.cursorPoint[0],y:t.cursorPoint[1],tooltipOption:t.tooltipOption,axesInfo:[{axisDim:e.axis.dim,axisIndex:e.componentIndex}]})}},t.prototype._onHandleDragEnd=function(){if(this._dragging=!1,this._handle){var t=this._axisPointerModel.get("value");this._moveHandleToValue(t),this._api.dispatchAction({type:"hideTip"})}},t.prototype.clear=function(t){this._lastValue=null,this._lastStatus=null;var e=t.getZr(),n=this._group,i=this._handle;e&&n&&(this._lastGraphicKey=null,n&&e.remove(n),i&&e.remove(i),this._group=null,this._handle=null,this._payloadInfo=null),Og(this,"_doDispatchAxisPointer")},t.prototype.doClear=function(){},t.prototype.buildLabel=function(t,e,n){return{x:t[n=n||0],y:t[1-n],width:e[n],height:e[1-n]}},t}();function ER(t,e,n,i){zR(PR(n).lastProp,i)||(PR(n).lastProp=i,e?uh(n,i,t):(n.stopAnimation(),n.attr(i)))}function zR(t,e){if(q(t)&&q(e)){var n=!0;return E(e,(function(e,i){n=n&&zR(t[i],e)})),!!n}return t===e}function VR(t,e){t[e.get(["label","show"])?"show":"hide"]()}function BR(t){return{x:t.x||0,y:t.y||0,rotation:t.rotation||0}}function FR(t,e,n){var i=e.get("z"),r=e.get("zlevel");t&&t.traverse((function(t){"group"!==t.type&&(null!=i&&(t.z=i),null!=r&&(t.zlevel=r),t.silent=n)}))}function GR(t){var e,n=t.get("type"),i=t.getModel(n+"Style");return"line"===n?(e=i.getLineStyle()).fill=null:"shadow"===n&&((e=i.getAreaStyle()).stroke=null),e}function WR(t,e,n,i,r){var o=HR(n.get("value"),e.axis,e.ecModel,n.get("seriesDataIndices"),{precision:n.get(["label","precision"]),formatter:n.get(["label","formatter"])}),a=n.getModel("label"),s=up(a.get("padding")||0),l=a.getFont(),u=yr(o,l),h=r.position,c=u.width+s[1]+s[3],p=u.height+s[0]+s[2],d=r.align;"right"===d&&(h[0]-=c),"center"===d&&(h[0]-=c/2);var f=r.verticalAlign;"bottom"===f&&(h[1]-=p),"middle"===f&&(h[1]-=p/2),function(t,e,n,i){var r=i.getWidth(),o=i.getHeight();t[0]=Math.min(t[0]+e,r)-e,t[1]=Math.min(t[1]+n,o)-n,t[0]=Math.max(t[0],0),t[1]=Math.max(t[1],0)}(h,c,p,i);var g=a.get("backgroundColor");g&&"auto"!==g||(g=e.get(["axisLine","lineStyle","color"])),t.label={x:h[0],y:h[1],style:$h(a,{text:o,font:l,fill:a.getTextColor(),padding:s,backgroundColor:g}),z2:10}}function HR(t,e,n,i,r){t=e.scale.parse(t);var o=e.scale.getLabel({value:t},{precision:r.precision}),a=r.formatter;if(a){var s={value:h_(e,{value:t}),axisDimension:e.dim,axisIndex:e.index,seriesData:[]};E(i,(function(t){var e=n.getSeriesByIndex(t.seriesIndex),i=t.dataIndexInside,r=e&&e.getDataParams(i);r&&s.seriesData.push(r)})),X(a)?o=a.replace("{value}",o):U(a)&&(o=a(s))}return o}function YR(t,e,n){var i=[1,0,0,1,0,0];return _e(i,i,n.rotation),xe(i,i,n.position),Ph([t.dataToCoord(e),(n.labelOffset||0)+(n.labelDirection||1)*(n.labelMargin||0)],i)}function UR(t,e,n,i,r,o){var a=YM.innerTextLayout(n.rotation,0,n.labelDirection);n.labelMargin=r.get(["label","margin"]),WR(e,i,r,o,{position:YR(i.axis,t,n),align:a.textAlign,verticalAlign:a.textVerticalAlign})}function XR(t,e,n){return{x1:t[n=n||0],y1:t[1-n],x2:e[n],y2:e[1-n]}}function ZR(t,e,n){return{x:t[n=n||0],y:t[1-n],width:e[n],height:e[1-n]}}function jR(t,e,n,i,r,o){return{cx:t,cy:e,r0:n,r:i,startAngle:r,endAngle:o,clockwise:!0}}var qR=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.makeElOption=function(t,e,n,i,r){var o=n.axis,a=o.grid,s=i.get("type"),l=KR(a,o).getOtherAxis(o).getGlobalExtent(),u=o.toGlobalCoord(o.dataToCoord(e,!0));if(s&&"none"!==s){var h=GR(i),c=$R[s](o,u,l);c.style=h,t.graphicKey=c.type,t.pointer=c}UR(e,t,RM(a.model,n),n,i,r)},e.prototype.getHandleTransform=function(t,e,n){var i=RM(e.axis.grid.model,e,{labelInside:!1});i.labelMargin=n.get(["handle","margin"]);var r=YR(e.axis,t,i);return{x:r[0],y:r[1],rotation:i.rotation+(i.labelDirection<0?Math.PI:0)}},e.prototype.updateHandleTransform=function(t,e,n,i){var r=n.axis,o=r.grid,a=r.getGlobalExtent(!0),s=KR(o,r).getOtherAxis(r).getGlobalExtent(),l="x"===r.dim?0:1,u=[t.x,t.y];u[l]+=e[l],u[l]=Math.min(a[1],u[l]),u[l]=Math.max(a[0],u[l]);var h=(s[1]+s[0])/2,c=[h,h];c[l]=u[l];return{x:u[0],y:u[1],rotation:t.rotation,cursorPoint:c,tooltipOption:[{verticalAlign:"middle"},{align:"center"}][l]}},e}(NR);function KR(t,e){var n={};return n[e.dim+"AxisIndex"]=e.index,t.getCartesian(n)}var $R={line:function(t,e,n){return{type:"Line",subPixelOptimize:!0,shape:XR([e,n[0]],[e,n[1]],JR(t))}},shadow:function(t,e,n){var i=Math.max(1,t.getBandWidth()),r=n[1]-n[0];return{type:"Rect",shape:ZR([e-i/2,n[0]],[i,r],JR(t))}}};function JR(t){return"x"===t.dim?0:1}var QR=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="axisPointer",e.defaultOption={show:"auto",z:50,type:"line",snap:!1,triggerTooltip:!0,value:null,status:null,link:[],animation:null,animationDurationUpdate:200,lineStyle:{color:"#B9BEC9",width:1,type:"dashed"},shadowStyle:{color:"rgba(210,219,238,0.2)"},label:{show:!0,formatter:null,precision:"auto",margin:3,color:"#fff",padding:[5,7,5,7],backgroundColor:"auto",borderColor:null,borderWidth:0,borderRadius:3},handle:{show:!1,icon:"M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4h1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7v-1.2h6.6z M13.3,22H6.7v-1.2h6.6z M13.3,19.6H6.7v-1.2h6.6z",size:45,margin:50,color:"#333",shadowBlur:3,shadowColor:"#aaa",shadowOffsetX:0,shadowOffsetY:2,throttle:40}},e}(Ap),tN=Do(),eN=E;function nN(t,e,n){if(!r.node){var i=e.getZr();tN(i).records||(tN(i).records={}),function(t,e){if(tN(t).initialized)return;function n(n,i){t.on(n,(function(n){var r=function(t){var e={showTip:[],hideTip:[]},n=function(i){var r=e[i.type];r?r.push(i):(i.dispatchAction=n,t.dispatchAction(i))};return{dispatchAction:n,pendings:e}}(e);eN(tN(t).records,(function(t){t&&i(t,n,r.dispatchAction)})),function(t,e){var n,i=t.showTip.length,r=t.hideTip.length;i?n=t.showTip[i-1]:r&&(n=t.hideTip[r-1]);n&&(n.dispatchAction=null,e.dispatchAction(n))}(r.pendings,e)}))}tN(t).initialized=!0,n("click",H(rN,"click")),n("mousemove",H(rN,"mousemove")),n("globalout",iN)}(i,e),(tN(i).records[t]||(tN(i).records[t]={})).handler=n}}function iN(t,e,n){t.handler("leave",null,n)}function rN(t,e,n,i){e.handler(t,n,i)}function oN(t,e){if(!r.node){var n=e.getZr();(tN(n).records||{})[t]&&(tN(n).records[t]=null)}}var aN=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){var i=e.getComponent("tooltip"),r=t.get("triggerOn")||i&&i.get("triggerOn")||"mousemove|click";nN("axisPointer",n,(function(t,e,n){"none"!==r&&("leave"===t||r.indexOf(t)>=0)&&n({type:"updateAxisPointer",currTrigger:t,x:e&&e.offsetX,y:e&&e.offsetY})}))},e.prototype.remove=function(t,e){oN("axisPointer",e)},e.prototype.dispose=function(t,e){oN("axisPointer",e)},e.type="axisPointer",e}(mg);function sN(t,e){var n,i=[],r=t.seriesIndex;if(null==r||!(n=e.getSeriesByIndex(r)))return{point:[]};var o=n.getData(),a=Co(o,t);if(null==a||a<0||Y(a))return{point:[]};var s=o.getItemGraphicEl(a),l=n.coordinateSystem;if(n.getTooltipPosition)i=n.getTooltipPosition(a)||[];else if(l&&l.dataToPoint)if(t.isStacked){var u=l.getBaseAxis(),h=l.getOtherAxis(u).dim,c=u.dim,p="x"===h||"radius"===h?1:0,d=o.mapDimension(c),f=[];f[p]=o.get(d,a),f[1-p]=o.get(o.getCalculationInfo("stackResultDimension"),a),i=l.dataToPoint(f)||[]}else i=l.dataToPoint(o.getValues(z(l.dimensions,(function(t){return o.mapDimension(t)})),a))||[];else if(s){var g=s.getBoundingRect().clone();g.applyTransform(s.transform),i=[g.x+g.width/2,g.y+g.height/2]}return{point:i,el:s}}var lN=Do();function uN(t,e,n){var i=t.currTrigger,r=[t.x,t.y],o=t,a=t.dispatchAction||W(n.dispatchAction,n),s=e.getComponent("axisPointer").coordSysAxesInfo;if(s){fN(r)&&(r=sN({seriesIndex:o.seriesIndex,dataIndex:o.dataIndex},e).point);var l=fN(r),u=o.axesInfo,h=s.axesInfo,c="leave"===i||fN(r),p={},d={},f={list:[],map:{}},g={showPointer:H(cN,d),showTooltip:H(pN,f)};E(s.coordSysMap,(function(t,e){var n=l||t.containPoint(r);E(s.coordSysAxesInfo[e],(function(t,e){var i=t.axis,o=function(t,e){for(var n=0;n<(t||[]).length;n++){var i=t[n];if(e.axis.dim===i.axisDim&&e.axis.model.componentIndex===i.axisIndex)return i}}(u,t);if(!c&&n&&(!u||o)){var a=o&&o.value;null!=a||l||(a=i.pointToData(r)),null!=a&&hN(t,a,g,!1,p)}}))}));var y={};return E(h,(function(t,e){var n=t.linkGroup;n&&!d[e]&&E(n.axesInfo,(function(e,i){var r=d[i];if(e!==t&&r){var o=r.value;n.mapper&&(o=t.axis.scale.parse(n.mapper(o,dN(e),dN(t)))),y[t.key]=o}}))})),E(y,(function(t,e){hN(h[e],t,g,!0,p)})),function(t,e,n){var i=n.axesInfo=[];E(e,(function(e,n){var r=e.axisPointerModel.option,o=t[n];o?(!e.useHandle&&(r.status="show"),r.value=o.value,r.seriesDataIndices=(o.payloadBatch||[]).slice()):!e.useHandle&&(r.status="hide"),"show"===r.status&&i.push({axisDim:e.axis.dim,axisIndex:e.axis.model.componentIndex,value:r.value})}))}(d,h,p),function(t,e,n,i){if(fN(e)||!t.list.length)return void i({type:"hideTip"});var r=((t.list[0].dataByAxis[0]||{}).seriesDataIndices||[])[0]||{};i({type:"showTip",escapeConnect:!0,x:e[0],y:e[1],tooltipOption:n.tooltipOption,position:n.position,dataIndexInside:r.dataIndexInside,dataIndex:r.dataIndex,seriesIndex:r.seriesIndex,dataByCoordSys:t.list})}(f,r,t,a),function(t,e,n){var i=n.getZr(),r="axisPointerLastHighlights",o=lN(i)[r]||{},a=lN(i)[r]={};E(t,(function(t,e){var n=t.axisPointerModel.option;"show"===n.status&&E(n.seriesDataIndices,(function(t){var e=t.seriesIndex+" | "+t.dataIndex;a[e]=t}))}));var s=[],l=[];E(o,(function(t,e){!a[e]&&l.push(t)})),E(a,(function(t,e){!o[e]&&s.push(t)})),l.length&&n.dispatchAction({type:"downplay",escapeConnect:!0,notBlur:!0,batch:l}),s.length&&n.dispatchAction({type:"highlight",escapeConnect:!0,notBlur:!0,batch:s})}(h,0,n),p}}function hN(t,e,n,i,r){var o=t.axis;if(!o.scale.isBlank()&&o.containData(e))if(t.involveSeries){var a=function(t,e){var n=e.axis,i=n.dim,r=t,o=[],a=Number.MAX_VALUE,s=-1;return E(e.seriesModels,(function(e,l){var u,h,c=e.getData().mapDimensionsAll(i);if(e.getAxisTooltipData){var p=e.getAxisTooltipData(c,t,n);h=p.dataIndices,u=p.nestestValue}else{if(!(h=e.getData().indicesOfNearest(c[0],t,"category"===n.type?.5:null)).length)return;u=e.getData().get(c[0],h[0])}if(null!=u&&isFinite(u)){var d=t-u,f=Math.abs(d);f<=a&&((f=0&&s<0)&&(a=f,s=d,r=u,o.length=0),E(h,(function(t){o.push({seriesIndex:e.seriesIndex,dataIndexInside:t,dataIndex:e.getData().getRawIndex(t)})})))}})),{payloadBatch:o,snapToValue:r}}(e,t),s=a.payloadBatch,l=a.snapToValue;s[0]&&null==r.seriesIndex&&A(r,s[0]),!i&&t.snap&&o.containData(l)&&null!=l&&(e=l),n.showPointer(t,e,s),n.showTooltip(t,a,l)}else n.showPointer(t,e)}function cN(t,e,n,i){t[e.key]={value:n,payloadBatch:i}}function pN(t,e,n,i){var r=n.payloadBatch,o=e.axis,a=o.model,s=e.axisPointerModel;if(e.triggerTooltip&&r.length){var l=e.coordSys.model,u=eI(l),h=t.map[u];h||(h=t.map[u]={coordSysId:l.id,coordSysIndex:l.componentIndex,coordSysType:l.type,coordSysMainType:l.mainType,dataByAxis:[]},t.list.push(h)),h.dataByAxis.push({axisDim:o.dim,axisIndex:a.componentIndex,axisType:a.type,axisId:a.id,value:i,valueLabelOpt:{precision:s.get(["label","precision"]),formatter:s.get(["label","formatter"])},seriesDataIndices:r.slice()})}}function dN(t){var e=t.axis.model,n={},i=n.axisDim=t.axis.dim;return n.axisIndex=n[i+"AxisIndex"]=e.componentIndex,n.axisName=n[i+"AxisName"]=e.name,n.axisId=n[i+"AxisId"]=e.id,n}function fN(t){return!t||null==t[0]||isNaN(t[0])||null==t[1]||isNaN(t[1])}function gN(t){iI.registerAxisPointerClass("CartesianAxisPointer",qR),t.registerComponentModel(QR),t.registerComponentView(aN),t.registerPreprocessor((function(t){if(t){(!t.axisPointer||0===t.axisPointer.length)&&(t.axisPointer={});var e=t.axisPointer.link;e&&!Y(e)&&(t.axisPointer.link=[e])}})),t.registerProcessor(t.PRIORITY.PROCESSOR.STATISTIC,(function(t,e){t.getComponent("axisPointer").coordSysAxesInfo=KM(t,e)})),t.registerAction({type:"updateAxisPointer",event:"updateAxisPointer",update:":updateAxisPointer"},uN)}var yN=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.makeElOption=function(t,e,n,i,r){var o=n.axis;"angle"===o.dim&&(this.animationThreshold=Math.PI/18);var a=o.polar,s=a.getOtherAxis(o).getExtent(),l=o.dataToCoord(e),u=i.get("type");if(u&&"none"!==u){var h=GR(i),c=vN[u](o,a,l,s);c.style=h,t.graphicKey=c.type,t.pointer=c}var p=function(t,e,n,i,r){var o=e.axis,a=o.dataToCoord(t),s=i.getAngleAxis().getExtent()[0];s=s/180*Math.PI;var l,u,h,c=i.getRadiusAxis().getExtent();if("radius"===o.dim){var p=[1,0,0,1,0,0];_e(p,p,s),xe(p,p,[i.cx,i.cy]),l=Ph([a,-r],p);var d=e.getModel("axisLabel").get("rotate")||0,f=YM.innerTextLayout(s,d*Math.PI/180,-1);u=f.textAlign,h=f.textVerticalAlign}else{var g=c[1];l=i.coordToPoint([g+r,a]);var y=i.cx,v=i.cy;u=Math.abs(l[0]-y)/g<.3?"center":l[0]>y?"left":"right",h=Math.abs(l[1]-v)/g<.3?"middle":l[1]>v?"top":"bottom"}return{position:l,align:u,verticalAlign:h}}(e,n,0,a,i.get(["label","margin"]));WR(t,n,i,r,p)},e}(NR);var vN={line:function(t,e,n,i){return"angle"===t.dim?{type:"Line",shape:XR(e.coordToPoint([i[0],n]),e.coordToPoint([i[1],n]))}:{type:"Circle",shape:{cx:e.cx,cy:e.cy,r:n}}},shadow:function(t,e,n,i){var r=Math.max(1,t.getBandWidth()),o=Math.PI/180;return"angle"===t.dim?{type:"Sector",shape:jR(e.cx,e.cy,i[0],i[1],(-n-r/2)*o,(r/2-n)*o)}:{type:"Sector",shape:jR(e.cx,e.cy,n-r/2,n+r/2,0,2*Math.PI)}}},mN=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.findAxisModel=function(t){var e;return this.ecModel.eachComponent(t,(function(t){t.getCoordSysModel()===this&&(e=t)}),this),e},e.type="polar",e.dependencies=["radiusAxis","angleAxis"],e.defaultOption={z:0,center:["50%","50%"],radius:"80%"},e}(Ap),xN=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.getCoordSysModel=function(){return this.getReferringComponents("polar",Po).models[0]},e.type="polarAxis",e}(Ap);R(xN,g_);var _N=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="angleAxis",e}(xN),bN=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="radiusAxis",e}(xN),wN=function(t){function e(e,n){return t.call(this,"radius",e,n)||this}return n(e,t),e.prototype.pointToData=function(t,e){return this.polar.pointToData(t,e)["radius"===this.dim?0:1]},e}(X_);wN.prototype.dataToRadius=X_.prototype.dataToCoord,wN.prototype.radiusToData=X_.prototype.coordToData;var SN=Do(),MN=function(t){function e(e,n){return t.call(this,"angle",e,n||[0,360])||this}return n(e,t),e.prototype.pointToData=function(t,e){return this.polar.pointToData(t,e)["radius"===this.dim?0:1]},e.prototype.calculateCategoryInterval=function(){var t=this,e=t.getLabelModel(),n=t.scale,i=n.getExtent(),r=n.count();if(i[1]-i[0]<1)return 0;var o=i[0],a=t.dataToCoord(o+1)-t.dataToCoord(o),s=Math.abs(a),l=yr(null==o?"":o+"",e.getFont(),"center","top"),u=Math.max(l.height,7)/s;isNaN(u)&&(u=1/0);var h=Math.max(0,Math.floor(u)),c=SN(t.model),p=c.lastAutoInterval,d=c.lastTickCount;return null!=p&&null!=d&&Math.abs(p-h)<=1&&Math.abs(d-r)<=1&&p>h?h=p:(c.lastTickCount=r,c.lastAutoInterval=h),h},e}(X_);MN.prototype.dataToAngle=X_.prototype.dataToCoord,MN.prototype.angleToData=X_.prototype.coordToData;var IN=["radius","angle"],TN=function(){function t(t){this.dimensions=IN,this.type="polar",this.cx=0,this.cy=0,this._radiusAxis=new wN,this._angleAxis=new MN,this.axisPointerEnabled=!0,this.name=t||"",this._radiusAxis.polar=this._angleAxis.polar=this}return t.prototype.containPoint=function(t){var e=this.pointToCoord(t);return this._radiusAxis.contain(e[0])&&this._angleAxis.contain(e[1])},t.prototype.containData=function(t){return this._radiusAxis.containData(t[0])&&this._angleAxis.containData(t[1])},t.prototype.getAxis=function(t){return this["_"+t+"Axis"]},t.prototype.getAxes=function(){return[this._radiusAxis,this._angleAxis]},t.prototype.getAxesByScale=function(t){var e=[],n=this._angleAxis,i=this._radiusAxis;return n.scale.type===t&&e.push(n),i.scale.type===t&&e.push(i),e},t.prototype.getAngleAxis=function(){return this._angleAxis},t.prototype.getRadiusAxis=function(){return this._radiusAxis},t.prototype.getOtherAxis=function(t){var e=this._angleAxis;return t===e?this._radiusAxis:e},t.prototype.getBaseAxis=function(){return this.getAxesByScale("ordinal")[0]||this.getAxesByScale("time")[0]||this.getAngleAxis()},t.prototype.getTooltipAxes=function(t){var e=null!=t&&"auto"!==t?this.getAxis(t):this.getBaseAxis();return{baseAxes:[e],otherAxes:[this.getOtherAxis(e)]}},t.prototype.dataToPoint=function(t,e){return this.coordToPoint([this._radiusAxis.dataToRadius(t[0],e),this._angleAxis.dataToAngle(t[1],e)])},t.prototype.pointToData=function(t,e){var n=this.pointToCoord(t);return[this._radiusAxis.radiusToData(n[0],e),this._angleAxis.angleToData(n[1],e)]},t.prototype.pointToCoord=function(t){var e=t[0]-this.cx,n=t[1]-this.cy,i=this.getAngleAxis(),r=i.getExtent(),o=Math.min(r[0],r[1]),a=Math.max(r[0],r[1]);i.inverse?o=a-360:a=o+360;var s=Math.sqrt(e*e+n*n);e/=s,n/=s;for(var l=Math.atan2(-n,e)/Math.PI*180,u=la;)l+=360*u;return[s,l]},t.prototype.coordToPoint=function(t){var e=t[0],n=t[1]/180*Math.PI;return[Math.cos(n)*e+this.cx,-Math.sin(n)*e+this.cy]},t.prototype.getArea=function(){var t=this.getAngleAxis(),e=this.getRadiusAxis().getExtent().slice();e[0]>e[1]&&e.reverse();var n=t.getExtent(),i=Math.PI/180;return{cx:this.cx,cy:this.cy,r0:e[0],r:e[1],startAngle:-n[0]*i,endAngle:-n[1]*i,clockwise:t.inverse,contain:function(t,e){var n=t-this.cx,i=e-this.cy,r=n*n+i*i-1e-4,o=this.r,a=this.r0;return r<=o*o&&r>=a*a}}},t.prototype.convertToPixel=function(t,e,n){return CN(e)===this?this.dataToPoint(n):null},t.prototype.convertFromPixel=function(t,e,n){return CN(e)===this?this.pointToData(n):null},t}();function CN(t){var e=t.seriesModel,n=t.polarModel;return n&&n.coordinateSystem||e&&e.coordinateSystem}function DN(t,e){var n=this,i=n.getAngleAxis(),r=n.getRadiusAxis();if(i.scale.setExtent(1/0,-1/0),r.scale.setExtent(1/0,-1/0),t.eachSeries((function(t){if(t.coordinateSystem===n){var e=t.getData();E(f_(e,"radius"),(function(t){r.scale.unionExtentFromData(e,t)})),E(f_(e,"angle"),(function(t){i.scale.unionExtentFromData(e,t)}))}})),s_(i.scale,i.model),s_(r.scale,r.model),"category"===i.type&&!i.onBand){var o=i.getExtent(),a=360/i.scale.count();i.inverse?o[1]+=a:o[1]-=a,i.setExtent(o[0],o[1])}}function AN(t,e){if(t.type=e.get("type"),t.scale=l_(e),t.onBand=e.get("boundaryGap")&&"category"===t.type,t.inverse=e.get("inverse"),function(t){return"angleAxis"===t.mainType}(e)){t.inverse=t.inverse!==e.get("clockwise");var n=e.get("startAngle");t.setExtent(n,n+(t.inverse?-360:360))}e.axis=t,t.model=e}var kN={dimensions:IN,create:function(t,e){var n=[];return t.eachComponent("polar",(function(t,i){var r=new TN(i+"");r.update=DN;var o=r.getRadiusAxis(),a=r.getAngleAxis(),s=t.findAxisModel("radiusAxis"),l=t.findAxisModel("angleAxis");AN(o,s),AN(a,l),function(t,e,n){var i=e.get("center"),r=n.getWidth(),o=n.getHeight();t.cx=Gr(i[0],r),t.cy=Gr(i[1],o);var a=t.getRadiusAxis(),s=Math.min(r,o)/2,l=e.get("radius");null==l?l=[0,"100%"]:Y(l)||(l=[0,l]);var u=[Gr(l[0],s),Gr(l[1],s)];a.inverse?a.setExtent(u[1],u[0]):a.setExtent(u[0],u[1])}(r,t,e),n.push(r),t.coordinateSystem=r,r.model=t})),t.eachSeries((function(t){if("polar"===t.get("coordinateSystem")){var e=t.getReferringComponents("polar",Po).models[0];0,t.coordinateSystem=e.coordinateSystem}})),n}},LN=["axisLine","axisLabel","axisTick","minorTick","splitLine","minorSplitLine","splitArea"];function PN(t,e,n){e[1]>e[0]&&(e=e.slice().reverse());var i=t.coordToPoint([e[0],n]),r=t.coordToPoint([e[1],n]);return{x1:i[0],y1:i[1],x2:r[0],y2:r[1]}}function ON(t){return t.getRadiusAxis().inverse?0:1}function RN(t){var e=t[0],n=t[t.length-1];e&&n&&Math.abs(Math.abs(e.coord-n.coord)-360)<1e-4&&t.pop()}var NN=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.axisPointerClass="PolarAxisPointer",n}return n(e,t),e.prototype.render=function(t,e){if(this.group.removeAll(),t.get("show")){var n=t.axis,i=n.polar,r=i.getRadiusAxis().getExtent(),o=n.getTicksCoords(),a=n.getMinorTicksCoords(),s=z(n.getViewLabels(),(function(t){t=T(t);var e=n.scale,i="ordinal"===e.type?e.getRawOrdinalNumber(t.tickValue):t.tickValue;return t.coord=n.dataToCoord(i),t}));RN(s),RN(o),E(LN,(function(e){!t.get([e,"show"])||n.scale.isBlank()&&"axisLine"!==e||EN[e](this.group,t,i,o,a,r,s)}),this)}},e.type="angleAxis",e}(iI),EN={axisLine:function(t,e,n,i,r,o){var a,s=e.getModel(["axisLine","lineStyle"]),l=ON(n),u=l?0:1;(a=0===o[u]?new gu({shape:{cx:n.cx,cy:n.cy,r:o[l]},style:s.getLineStyle(),z2:1,silent:!0}):new Ru({shape:{cx:n.cx,cy:n.cy,r:o[l],r0:o[u]},style:s.getLineStyle(),z2:1,silent:!0})).style.fill=null,t.add(a)},axisTick:function(t,e,n,i,r,o){var a=e.getModel("axisTick"),s=(a.get("inside")?-1:1)*a.get("length"),l=o[ON(n)],u=z(i,(function(t){return new Wu({shape:PN(n,[l,l+s],t.coord)})}));t.add(Ch(u,{style:k(a.getModel("lineStyle").getLineStyle(),{stroke:e.get(["axisLine","lineStyle","color"])})}))},minorTick:function(t,e,n,i,r,o){if(r.length){for(var a=e.getModel("axisTick"),s=e.getModel("minorTick"),l=(a.get("inside")?-1:1)*s.get("length"),u=o[ON(n)],h=[],c=0;cf?"left":"right",v=Math.abs(d[1]-g)/p<.3?"middle":d[1]>g?"top":"bottom";if(s&&s[c]){var m=s[c];q(m)&&m.textStyle&&(a=new xc(m.textStyle,l,l.ecModel))}var x=new Ns({silent:YM.isLabelSilent(e),style:$h(a,{x:d[0],y:d[1],fill:a.getTextColor()||e.get(["axisLine","lineStyle","color"]),text:i.formattedLabel,align:y,verticalAlign:v})});if(t.add(x),h){var _=YM.makeAxisEventDataBase(e);_.targetType="axisLabel",_.value=i.rawLabel,js(x).eventData=_}}),this)},splitLine:function(t,e,n,i,r,o){var a=e.getModel("splitLine").getModel("lineStyle"),s=a.get("color"),l=0;s=s instanceof Array?s:[s];for(var u=[],h=0;h=0?"p":"n",T=_;m&&(i[s][M]||(i[s][M]={p:_,n:_}),T=i[s][M][I]);var C=void 0,D=void 0,A=void 0,k=void 0;if("radius"===c.dim){var L=c.dataToCoord(S)-_,P=o.dataToCoord(M);Math.abs(L)=k})}}}))}var YN={startAngle:90,clockwise:!0,splitNumber:12,axisLabel:{rotate:0}},UN={splitNumber:5},XN=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="polar",e}(mg);function ZN(t,e){e=e||{};var n=t.coordinateSystem,i=t.axis,r={},o=i.position,a=i.orient,s=n.getRect(),l=[s.x,s.x+s.width,s.y,s.y+s.height],u={horizontal:{top:l[2],bottom:l[3]},vertical:{left:l[0],right:l[1]}};r.position=["vertical"===a?u.vertical[o]:l[0],"horizontal"===a?u.horizontal[o]:l[3]];r.rotation=Math.PI/2*{horizontal:0,vertical:1}[a];r.labelDirection=r.tickDirection=r.nameDirection={top:-1,bottom:1,right:1,left:-1}[o],t.get(["axisTick","inside"])&&(r.tickDirection=-r.tickDirection),it(e.labelInside,t.get(["axisLabel","inside"]))&&(r.labelDirection=-r.labelDirection);var h=e.rotate;return null==h&&(h=t.get(["axisLabel","rotate"])),r.labelRotation="top"===o?-h:h,r.z2=1,r}var jN=["axisLine","axisTickLabel","axisName"],qN=["splitArea","splitLine"],KN=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.axisPointerClass="SingleAxisPointer",n}return n(e,t),e.prototype.render=function(e,n,i,r){var o=this.group;o.removeAll();var a=this._axisGroup;this._axisGroup=new Pr;var s=ZN(e),l=new YM(e,s);E(jN,l.add,l),o.add(this._axisGroup),o.add(l.getGroup()),E(qN,(function(t){e.get([t,"show"])&&$N[t](this,this.group,this._axisGroup,e)}),this),Nh(a,this._axisGroup,e),t.prototype.render.call(this,e,n,i,r)},e.prototype.remove=function(){aI(this)},e.type="singleAxis",e}(iI),$N={splitLine:function(t,e,n,i){var r=i.axis;if(!r.scale.isBlank()){var o=i.getModel("splitLine"),a=o.getModel("lineStyle"),s=a.get("color");s=s instanceof Array?s:[s];for(var l=a.get("width"),u=i.coordinateSystem.getRect(),h=r.isHorizontal(),c=[],p=0,d=r.getTicksCoords({tickModel:o}),f=[],g=[],y=0;y=e.y&&t[1]<=e.y+e.height:n.contain(n.toLocalCoord(t[1]))&&t[0]>=e.y&&t[0]<=e.y+e.height},t.prototype.pointToData=function(t){var e=this.getAxis();return[e.coordToData(e.toLocalCoord(t["horizontal"===e.orient?0:1]))]},t.prototype.dataToPoint=function(t){var e=this.getAxis(),n=this.getRect(),i=[],r="horizontal"===e.orient?0:1;return t instanceof Array&&(t=t[0]),i[r]=e.toGlobalCoord(e.dataToCoord(+t)),i[1-r]=0===r?n.y+n.height/2:n.x+n.width/2,i},t.prototype.convertToPixel=function(t,e,n){return nE(e)===this?this.dataToPoint(n):null},t.prototype.convertFromPixel=function(t,e,n){return nE(e)===this?this.pointToData(n):null},t}();function nE(t){var e=t.seriesModel,n=t.singleAxisModel;return n&&n.coordinateSystem||e&&e.coordinateSystem}var iE={create:function(t,e){var n=[];return t.eachComponent("singleAxis",(function(i,r){var o=new eE(i,t,e);o.name="single_"+r,o.resize(i,e),i.coordinateSystem=o,n.push(o)})),t.eachSeries((function(t){if("singleAxis"===t.get("coordinateSystem")){var e=t.getReferringComponents("singleAxis",Po).models[0];t.coordinateSystem=e&&e.coordinateSystem}})),n},dimensions:tE},rE=["x","y"],oE=["width","height"],aE=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.makeElOption=function(t,e,n,i,r){var o=n.axis,a=o.coordinateSystem,s=uE(a,1-lE(o)),l=a.dataToPoint(e)[0],u=i.get("type");if(u&&"none"!==u){var h=GR(i),c=sE[u](o,l,s);c.style=h,t.graphicKey=c.type,t.pointer=c}UR(e,t,ZN(n),n,i,r)},e.prototype.getHandleTransform=function(t,e,n){var i=ZN(e,{labelInside:!1});i.labelMargin=n.get(["handle","margin"]);var r=YR(e.axis,t,i);return{x:r[0],y:r[1],rotation:i.rotation+(i.labelDirection<0?Math.PI:0)}},e.prototype.updateHandleTransform=function(t,e,n,i){var r=n.axis,o=r.coordinateSystem,a=lE(r),s=uE(o,a),l=[t.x,t.y];l[a]+=e[a],l[a]=Math.min(s[1],l[a]),l[a]=Math.max(s[0],l[a]);var u=uE(o,1-a),h=(u[1]+u[0])/2,c=[h,h];return c[a]=l[a],{x:l[0],y:l[1],rotation:t.rotation,cursorPoint:c,tooltipOption:{verticalAlign:"middle"}}},e}(NR),sE={line:function(t,e,n){return{type:"Line",subPixelOptimize:!0,shape:XR([e,n[0]],[e,n[1]],lE(t))}},shadow:function(t,e,n){var i=t.getBandWidth(),r=n[1]-n[0];return{type:"Rect",shape:ZR([e-i/2,n[0]],[i,r],lE(t))}}};function lE(t){return t.isHorizontal()?0:1}function uE(t,e){var n=t.getRect();return[n[rE[e]],n[rE[e]]+n[oE[e]]]}var hE=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="single",e}(mg);var cE=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.init=function(e,n,i){var r=Tp(e);t.prototype.init.apply(this,arguments),pE(e,r)},e.prototype.mergeOption=function(e){t.prototype.mergeOption.apply(this,arguments),pE(this.option,e)},e.prototype.getCellSize=function(){return this.option.cellSize},e.type="calendar",e.defaultOption={z:2,left:80,top:60,cellSize:20,orient:"horizontal",splitLine:{show:!0,lineStyle:{color:"#000",width:1,type:"solid"}},itemStyle:{color:"#fff",borderWidth:1,borderColor:"#ccc"},dayLabel:{show:!0,firstDay:0,position:"start",margin:"50%",color:"#000"},monthLabel:{show:!0,position:"start",margin:5,align:"center",formatter:null,color:"#000"},yearLabel:{show:!0,position:null,margin:30,formatter:null,color:"#ccc",fontFamily:"sans-serif",fontWeight:"bolder",fontSize:20}},e}(Ap);function pE(t,e){var n,i=t.cellSize;1===(n=Y(i)?i:t.cellSize=[i,i]).length&&(n[1]=n[0]);var r=z([0,1],(function(t){return function(t,e){return null!=t[xp[e][0]]||null!=t[xp[e][1]]&&null!=t[xp[e][2]]}(e,t)&&(n[t]="auto"),null!=n[t]&&"auto"!==n[t]}));Ip(t,e,{type:"box",ignoreSize:r})}var dE=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){var i=this.group;i.removeAll();var r=t.coordinateSystem,o=r.getRangeInfo(),a=r.getOrient(),s=e.getLocaleModel();this._renderDayRect(t,o,i),this._renderLines(t,o,a,i),this._renderYearText(t,o,a,i),this._renderMonthText(t,s,a,i),this._renderWeekText(t,s,o,a,i)},e.prototype._renderDayRect=function(t,e,n){for(var i=t.coordinateSystem,r=t.getModel("itemStyle").getItemStyle(),o=i.getCellWidth(),a=i.getCellHeight(),s=e.start.time;s<=e.end.time;s=i.getNextNDay(s,1).time){var l=i.dataToRect([s],!1).tl,u=new Ps({shape:{x:l[0],y:l[1],width:o,height:a},cursor:"default",style:r});n.add(u)}},e.prototype._renderLines=function(t,e,n,i){var r=this,o=t.coordinateSystem,a=t.getModel(["splitLine","lineStyle"]).getLineStyle(),s=t.get(["splitLine","show"]),l=a.lineWidth;this._tlpoints=[],this._blpoints=[],this._firstDayOfMonth=[],this._firstDayPoints=[];for(var u=e.start,h=0;u.time<=e.end.time;h++){p(u.formatedDate),0===h&&(u=o.getDateInfo(e.start.y+"-"+e.start.m));var c=u.date;c.setMonth(c.getMonth()+1),u=o.getDateInfo(c)}function p(e){r._firstDayOfMonth.push(o.getDateInfo(e)),r._firstDayPoints.push(o.dataToRect([e],!1).tl);var l=r._getLinePointsOfOneWeek(t,e,n);r._tlpoints.push(l[0]),r._blpoints.push(l[l.length-1]),s&&r._drawSplitline(l,a,i)}p(o.getNextNDay(e.end.time,1).formatedDate),s&&this._drawSplitline(r._getEdgesPoints(r._tlpoints,l,n),a,i),s&&this._drawSplitline(r._getEdgesPoints(r._blpoints,l,n),a,i)},e.prototype._getEdgesPoints=function(t,e,n){var i=[t[0].slice(),t[t.length-1].slice()],r="horizontal"===n?0:1;return i[0][r]=i[0][r]-e/2,i[1][r]=i[1][r]+e/2,i},e.prototype._drawSplitline=function(t,e,n){var i=new Bu({z2:20,shape:{points:t},style:e});n.add(i)},e.prototype._getLinePointsOfOneWeek=function(t,e,n){for(var i=t.coordinateSystem,r=i.getDateInfo(e),o=[],a=0;a<7;a++){var s=i.getNextNDay(r.time,a),l=i.dataToRect([s.time],!1);o[2*s.day]=l.tl,o[2*s.day+1]=l["horizontal"===n?"bl":"tr"]}return o},e.prototype._formatterLabel=function(t,e){return X(t)&&t?(n=t,E(e,(function(t,e){n=n.replace("{"+e+"}",i?ee(t):t)})),n):U(t)?t(e):e.nameMap;var n,i},e.prototype._yearTextPositionControl=function(t,e,n,i,r){var o=e[0],a=e[1],s=["center","bottom"];"bottom"===i?(a+=r,s=["center","top"]):"left"===i?o-=r:"right"===i?(o+=r,s=["center","top"]):a-=r;var l=0;return"left"!==i&&"right"!==i||(l=Math.PI/2),{rotation:l,x:o,y:a,style:{align:s[0],verticalAlign:s[1]}}},e.prototype._renderYearText=function(t,e,n,i){var r=t.getModel("yearLabel");if(r.get("show")){var o=r.get("margin"),a=r.get("position");a||(a="horizontal"!==n?"top":"left");var s=[this._tlpoints[this._tlpoints.length-1],this._blpoints[0]],l=(s[0][0]+s[1][0])/2,u=(s[0][1]+s[1][1])/2,h="horizontal"===n?0:1,c={top:[l,s[h][1]],bottom:[l,s[1-h][1]],left:[s[1-h][0],u],right:[s[h][0],u]},p=e.start.y;+e.end.y>+e.start.y&&(p=p+"-"+e.end.y);var d=r.get("formatter"),f={start:e.start.y,end:e.end.y,nameMap:p},g=this._formatterLabel(d,f),y=new Ns({z2:30,style:$h(r,{text:g})});y.attr(this._yearTextPositionControl(y,c[a],n,a,o)),i.add(y)}},e.prototype._monthTextPositionControl=function(t,e,n,i,r){var o="left",a="top",s=t[0],l=t[1];return"horizontal"===n?(l+=r,e&&(o="center"),"start"===i&&(a="bottom")):(s+=r,e&&(a="middle"),"start"===i&&(o="right")),{x:s,y:l,align:o,verticalAlign:a}},e.prototype._renderMonthText=function(t,e,n,i){var r=t.getModel("monthLabel");if(r.get("show")){var o=r.get("nameMap"),a=r.get("margin"),s=r.get("position"),l=r.get("align"),u=[this._tlpoints,this._blpoints];o&&!X(o)||(o&&(e=kc(o)||e),o=e.get(["time","monthAbbr"])||[]);var h="start"===s?0:1,c="horizontal"===n?0:1;a="start"===s?-a:a;for(var p="center"===l,d=0;d=i.start.time&&n.timea.end.time&&t.reverse(),t},t.prototype._getRangeInfo=function(t){var e,n=[this.getDateInfo(t[0]),this.getDateInfo(t[1])];n[0].time>n[1].time&&(e=!0,n.reverse());var i=Math.floor(n[1].time/fE)-Math.floor(n[0].time/fE)+1,r=new Date(n[0].time),o=r.getDate(),a=n[1].date.getDate();r.setDate(o+i-1);var s=r.getDate();if(s!==a)for(var l=r.getTime()-n[1].time>0?1:-1;(s=r.getDate())!==a&&(r.getTime()-n[1].time)*l>0;)i-=l,r.setDate(s-l);var u=Math.floor((i+n[0].day+6)/7),h=e?1-u:u-1;return e&&n.reverse(),{range:[n[0].formatedDate,n[1].formatedDate],start:n[0],end:n[1],allDay:i,weeks:u,nthWeek:h,fweek:n[0].day,lweek:n[1].day}},t.prototype._getDateByWeeksAndDay=function(t,e,n){var i=this._getRangeInfo(n);if(t>i.weeks||0===t&&ei.lweek)return null;var r=7*(t-1)-i.fweek+e,o=new Date(i.start.time);return o.setDate(+i.start.d+r),this.getDateInfo(o)},t.create=function(e,n){var i=[];return e.eachComponent("calendar",(function(r){var o=new t(r,e,n);i.push(o),r.coordinateSystem=o})),e.eachSeries((function(t){"calendar"===t.get("coordinateSystem")&&(t.coordinateSystem=i[t.get("calendarIndex")||0])})),i},t.dimensions=["time","value"],t}();function yE(t){var e=t.calendarModel,n=t.seriesModel;return e?e.coordinateSystem:n?n.coordinateSystem:null}function vE(t,e){var n;return E(e,(function(e){null!=t[e]&&"auto"!==t[e]&&(n=!0)})),n}var mE=["transition","enterFrom","leaveTo"],xE=mE.concat(["enterAnimation","updateAnimation","leaveAnimation"]);function _E(t,e,n){if(n&&(!t[n]&&e[n]&&(t[n]={}),t=t[n],e=e[n]),t&&e)for(var i=n?mE:xE,r=0;r=0;l--){var p,d,f;if(f=null!=(d=Mo((p=n[l]).id,null))?r.get(d):null){var g=f.parent,y=(c=SE(g),{}),v=Sp(f,p,g===i?{width:o,height:a}:{width:c.width,height:c.height},null,{hv:p.hv,boundingMode:p.bounding},y);if(!SE(f).isNew&&v){for(var m=p.transition,x={},_=0;_=0)?x[b]=w:f[b]=w}uh(f,x,t,0)}else f.attr(y)}}},e.prototype._clear=function(){var t=this,e=this._elMap;e.each((function(n){CE(n,SE(n).option,e,t._lastGraphicModel)})),this._elMap=ft()},e.prototype.dispose=function(){this._clear()},e.type="graphic",e}(mg);function IE(t){var e=mt(wE,t)?wE[t]:Sh(t);var n=new e({});return SE(n).type=t,n}function TE(t,e,n,i){var r=IE(n);return e.add(r),i.set(t,r),SE(r).id=t,SE(r).isNew=!0,r}function CE(t,e,n,i){t&&t.parent&&("group"===t.type&&t.traverse((function(t){CE(t,e,n,i)})),YO(t,e,i),n.removeKey(SE(t).id))}function DE(t,e,n,i){t.isGroup||E([["cursor",ma.prototype.cursor],["zlevel",i||0],["z",n||0],["z2",0]],(function(n){var i=n[0];mt(e,i)?t[i]=rt(e[i],n[1]):null==t[i]&&(t[i]=n[1])})),E(G(e),(function(n){if(0===n.indexOf("on")){var i=e[n];t[n]=U(i)?i:null}})),mt(e,"draggable")&&(t.draggable=e.draggable),null!=e.name&&(t.name=e.name),null!=e.id&&(t.id=e.id)}var AE=["x","y","radius","angle","single"],kE=["cartesian2d","polar","singleAxis"];function LE(t){return t+"Axis"}function PE(t,e){var n,i=ft(),r=[],o=ft();t.eachComponent({mainType:"dataZoom",query:e},(function(t){o.get(t.uid)||s(t)}));do{n=!1,t.eachComponent("dataZoom",a)}while(n);function a(t){!o.get(t.uid)&&function(t){var e=!1;return t.eachTargetAxis((function(t,n){var r=i.get(t);r&&r[n]&&(e=!0)})),e}(t)&&(s(t),n=!0)}function s(t){o.set(t.uid,!0),r.push(t),t.eachTargetAxis((function(t,e){(i.get(t)||i.set(t,[]))[e]=!0}))}return r}function OE(t){var e=t.ecModel,n={infoList:[],infoMap:ft()};return t.eachTargetAxis((function(t,i){var r=e.getComponent(LE(t),i);if(r){var o=r.getCoordSysModel();if(o){var a=o.uid,s=n.infoMap.get(a);s||(s={model:o,axisModels:[]},n.infoList.push(s),n.infoMap.set(a,s)),s.axisModels.push(r)}}})),n}var RE=function(){function t(){this.indexList=[],this.indexMap=[]}return t.prototype.add=function(t){this.indexMap[t]||(this.indexList.push(t),this.indexMap[t]=!0)},t}(),NE=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n._autoThrottle=!0,n._noTarget=!0,n._rangePropMode=["percent","percent"],n}return n(e,t),e.prototype.init=function(t,e,n){var i=EE(t);this.settledOption=i,this.mergeDefaultAndTheme(t,n),this._doInit(i)},e.prototype.mergeOption=function(t){var e=EE(t);C(this.option,t,!0),C(this.settledOption,e,!0),this._doInit(e)},e.prototype._doInit=function(t){var e=this.option;this._setDefaultThrottle(t),this._updateRangeUse(t);var n=this.settledOption;E([["start","startValue"],["end","endValue"]],(function(t,i){"value"===this._rangePropMode[i]&&(e[t[0]]=n[t[0]]=null)}),this),this._resetTarget()},e.prototype._resetTarget=function(){var t=this.get("orient",!0),e=this._targetAxisInfoMap=ft();this._fillSpecifiedTargetAxis(e)?this._orient=t||this._makeAutoOrientByTargetAxis():(this._orient=t||"horizontal",this._fillAutoTargetAxisByOrient(e,this._orient)),this._noTarget=!0,e.each((function(t){t.indexList.length&&(this._noTarget=!1)}),this)},e.prototype._fillSpecifiedTargetAxis=function(t){var e=!1;return E(AE,(function(n){var i=this.getReferringComponents(LE(n),Oo);if(i.specified){e=!0;var r=new RE;E(i.models,(function(t){r.add(t.componentIndex)})),t.set(n,r)}}),this),e},e.prototype._fillAutoTargetAxisByOrient=function(t,e){var n=this.ecModel,i=!0;if(i){var r="vertical"===e?"y":"x";o(n.findComponents({mainType:r+"Axis"}),r)}i&&o(n.findComponents({mainType:"singleAxis",filter:function(t){return t.get("orient",!0)===e}}),"single");function o(e,n){var r=e[0];if(r){var o=new RE;if(o.add(r.componentIndex),t.set(n,o),i=!1,"x"===n||"y"===n){var a=r.getReferringComponents("grid",Po).models[0];a&&E(e,(function(t){r.componentIndex!==t.componentIndex&&a===t.getReferringComponents("grid",Po).models[0]&&o.add(t.componentIndex)}))}}}i&&E(AE,(function(e){if(i){var r=n.findComponents({mainType:LE(e),filter:function(t){return"category"===t.get("type",!0)}});if(r[0]){var o=new RE;o.add(r[0].componentIndex),t.set(e,o),i=!1}}}),this)},e.prototype._makeAutoOrientByTargetAxis=function(){var t;return this.eachTargetAxis((function(e){!t&&(t=e)}),this),"y"===t?"vertical":"horizontal"},e.prototype._setDefaultThrottle=function(t){if(t.hasOwnProperty("throttle")&&(this._autoThrottle=!1),this._autoThrottle){var e=this.ecModel.option;this.option.throttle=e.animation&&e.animationDurationUpdate>0?100:20}},e.prototype._updateRangeUse=function(t){var e=this._rangePropMode,n=this.get("rangeMode");E([["start","startValue"],["end","endValue"]],(function(i,r){var o=null!=t[i[0]],a=null!=t[i[1]];o&&!a?e[r]="percent":!o&&a?e[r]="value":n?e[r]=n[r]:o&&(e[r]="percent")}))},e.prototype.noTarget=function(){return this._noTarget},e.prototype.getFirstTargetAxisModel=function(){var t;return this.eachTargetAxis((function(e,n){null==t&&(t=this.ecModel.getComponent(LE(e),n))}),this),t},e.prototype.eachTargetAxis=function(t,e){this._targetAxisInfoMap.each((function(n,i){E(n.indexList,(function(n){t.call(e,i,n)}))}))},e.prototype.getAxisProxy=function(t,e){var n=this.getAxisModel(t,e);if(n)return n.__dzAxisProxy},e.prototype.getAxisModel=function(t,e){var n=this._targetAxisInfoMap.get(t);if(n&&n.indexMap[e])return this.ecModel.getComponent(LE(t),e)},e.prototype.setRawRange=function(t){var e=this.option,n=this.settledOption;E([["start","startValue"],["end","endValue"]],(function(i){null==t[i[0]]&&null==t[i[1]]||(e[i[0]]=n[i[0]]=t[i[0]],e[i[1]]=n[i[1]]=t[i[1]])}),this),this._updateRangeUse(t)},e.prototype.setCalculatedRange=function(t){var e=this.option;E(["start","startValue","end","endValue"],(function(n){e[n]=t[n]}))},e.prototype.getPercentRange=function(){var t=this.findRepresentativeAxisProxy();if(t)return t.getDataPercentWindow()},e.prototype.getValueRange=function(t,e){if(null!=t||null!=e)return this.getAxisProxy(t,e).getDataValueWindow();var n=this.findRepresentativeAxisProxy();return n?n.getDataValueWindow():void 0},e.prototype.findRepresentativeAxisProxy=function(t){if(t)return t.__dzAxisProxy;for(var e,n=this._targetAxisInfoMap.keys(),i=0;i=0}(e)){var n=LE(this._dimName),i=e.getReferringComponents(n,Po).models[0];i&&this._axisIndex===i.componentIndex&&t.push(e)}}),this),t},t.prototype.getAxisModel=function(){return this.ecModel.getComponent(this._dimName+"Axis",this._axisIndex)},t.prototype.getMinMaxSpan=function(){return T(this._minMaxSpan)},t.prototype.calculateDataWindow=function(t){var e,n=this._dataExtent,i=this.getAxisModel().axis.scale,r=this._dataZoomModel.getRangePropMode(),o=[0,100],a=[],s=[];FE(["start","end"],(function(l,u){var h=t[l],c=t[l+"Value"];"percent"===r[u]?(null==h&&(h=o[u]),c=i.parse(Fr(h,o,n))):(e=!0,h=Fr(c=null==c?n[u]:i.parse(c),n,o)),s[u]=c,a[u]=h})),GE(s),GE(a);var l=this._minMaxSpan;function u(t,e,n,r,o){var a=o?"Span":"ValueSpan";dk(0,t,n,"all",l["min"+a],l["max"+a]);for(var s=0;s<2;s++)e[s]=Fr(t[s],n,r,!0),o&&(e[s]=i.parse(e[s]))}return e?u(s,a,n,o,!1):u(a,s,o,n,!0),{valueWindow:s,percentWindow:a}},t.prototype.reset=function(t){if(t===this._dataZoomModel){var e=this.getTargetSeriesModels();this._dataExtent=function(t,e,n){var i=[1/0,-1/0];FE(n,(function(t){!function(t,e,n){e&&E(f_(e,n),(function(n){var i=e.getApproximateExtent(n);i[0]t[1]&&(t[1]=i[1])}))}(i,t.getData(),e)}));var r=t.getAxisModel(),o=r_(r.axis.scale,r,i).calculate();return[o.min,o.max]}(this,this._dimName,e),this._updateMinMaxSpan();var n=this.calculateDataWindow(t.settledOption);this._valueWindow=n.valueWindow,this._percentWindow=n.percentWindow,this._setAxisModel()}},t.prototype.filterData=function(t,e){if(t===this._dataZoomModel){var n=this._dimName,i=this.getTargetSeriesModels(),r=t.get("filterMode"),o=this._valueWindow;"none"!==r&&FE(i,(function(t){var e=t.getData(),i=e.mapDimensionsAll(n);if(i.length){if("weakFilter"===r){var a=e.getStore(),s=z(i,(function(t){return e.getDimensionIndex(t)}),e);e.filterSelf((function(t){for(var e,n,r,l=0;lo[1];if(h&&!c&&!p)return!0;h&&(r=!0),c&&(e=!0),p&&(n=!0)}return r&&e&&n}))}else FE(i,(function(n){if("empty"===r)t.setData(e=e.map(n,(function(t){return function(t){return t>=o[0]&&t<=o[1]}(t)?t:NaN})));else{var i={};i[n]=o,e.selectRange(i)}}));FE(i,(function(t){e.setApproximateExtent(o,t)}))}}))}},t.prototype._updateMinMaxSpan=function(){var t=this._minMaxSpan={},e=this._dataZoomModel,n=this._dataExtent;FE(["min","max"],(function(i){var r=e.get(i+"Span"),o=e.get(i+"ValueSpan");null!=o&&(o=this.getAxisModel().axis.scale.parse(o)),null!=o?r=Fr(n[0]+o,n,[0,100],!0):null!=r&&(o=Fr(r,[0,100],n,!0)-n[0]),t[i+"Span"]=r,t[i+"ValueSpan"]=o}),this)},t.prototype._setAxisModel=function(){var t=this.getAxisModel(),e=this._percentWindow,n=this._valueWindow;if(e){var i=Xr(n,[0,500]);i=Math.min(i,20);var r=t.axis.scale.rawExtentInfo;0!==e[0]&&r.setDeterminedMinMax("min",+n[0].toFixed(i)),100!==e[1]&&r.setDeterminedMinMax("max",+n[1].toFixed(i)),r.freeze()}},t}();var HE={getTargetSeries:function(t){function e(e){t.eachComponent("dataZoom",(function(n){n.eachTargetAxis((function(i,r){var o=t.getComponent(LE(i),r);e(i,r,o,n)}))}))}e((function(t,e,n,i){n.__dzAxisProxy=null}));var n=[];e((function(e,i,r,o){r.__dzAxisProxy||(r.__dzAxisProxy=new WE(e,i,o,t),n.push(r.__dzAxisProxy))}));var i=ft();return E(n,(function(t){E(t.getTargetSeriesModels(),(function(t){i.set(t.uid,t)}))})),i},overallReset:function(t,e){t.eachComponent("dataZoom",(function(t){t.eachTargetAxis((function(e,n){t.getAxisProxy(e,n).reset(t)})),t.eachTargetAxis((function(n,i){t.getAxisProxy(n,i).filterData(t,e)}))})),t.eachComponent("dataZoom",(function(t){var e=t.findRepresentativeAxisProxy();if(e){var n=e.getDataPercentWindow(),i=e.getDataValueWindow();t.setCalculatedRange({start:n[0],end:n[1],startValue:i[0],endValue:i[1]})}}))}};var YE=!1;function UE(t){YE||(YE=!0,t.registerProcessor(t.PRIORITY.PROCESSOR.FILTER,HE),function(t){t.registerAction("dataZoom",(function(t,e){E(PE(e,t),(function(e){e.setRawRange({start:t.start,end:t.end,startValue:t.startValue,endValue:t.endValue})}))}))}(t),t.registerSubTypeDefaulter("dataZoom",(function(){return"slider"})))}function XE(t){t.registerComponentModel(zE),t.registerComponentView(BE),UE(t)}var ZE=function(){},jE={};function qE(t,e){jE[t]=e}function KE(t){return jE[t]}var $E=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.optionUpdated=function(){t.prototype.optionUpdated.apply(this,arguments);var e=this.ecModel;E(this.option.feature,(function(t,n){var i=KE(n);i&&(i.getDefaultOption&&(i.defaultOption=i.getDefaultOption(e)),C(t,i.defaultOption))}))},e.type="toolbox",e.layoutMode={type:"box",ignoreSize:!0},e.defaultOption={show:!0,z:6,orient:"horizontal",left:"right",top:"top",backgroundColor:"transparent",borderColor:"#ccc",borderRadius:0,borderWidth:0,padding:5,itemSize:15,itemGap:8,showTitle:!0,iconStyle:{borderColor:"#666",color:"none"},emphasis:{iconStyle:{borderColor:"#3E98C5"}},tooltip:{show:!1,position:"bottom"}},e}(Ap);function JE(t,e){var n=up(e.get("padding")),i=e.getItemStyle(["color","opacity"]);return i.fill=e.get("backgroundColor"),t=new Ps({shape:{x:t.x-n[3],y:t.y-n[0],width:t.width+n[1]+n[3],height:t.height+n[0]+n[2],r:e.get("borderRadius")},style:i,silent:!0,z2:-1})}var QE=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.render=function(t,e,n,i){var r=this.group;if(r.removeAll(),t.get("show")){var o=+t.get("itemSize"),a="vertical"===t.get("orient"),s=t.get("feature")||{},l=this._features||(this._features={}),u=[];E(s,(function(t,e){u.push(e)})),new Dm(this._featureNames||[],u).add(h).update(h).remove(H(h,null)).execute(),this._featureNames=u,function(t,e,n){var i=e.getBoxLayoutParams(),r=e.get("padding"),o={width:n.getWidth(),height:n.getHeight()},a=wp(i,o,r);bp(e.get("orient"),t,e.get("itemGap"),a.width,a.height),Sp(t,i,o,r)}(r,t,n),r.add(JE(r.getBoundingRect(),t)),a||r.eachChild((function(t){var e=t.__title,i=t.ensureState("emphasis"),a=i.textConfig||(i.textConfig={}),s=t.getTextContent(),l=s&&s.ensureState("emphasis");if(l&&!U(l)&&e){var u=l.style||(l.style={}),h=yr(e,Ns.makeFont(u)),c=t.x+r.x,p=!1;t.y+r.y+o+h.height>n.getHeight()&&(a.position="top",p=!0);var d=p?-5-h.height:o+10;c+h.width/2>n.getWidth()?(a.position=["100%",d],u.align="right"):c-h.width/2<0&&(a.position=[0,d],u.align="left")}}))}function h(h,c){var p,d=u[h],f=u[c],g=s[d],y=new xc(g,t,t.ecModel);if(i&&null!=i.newTitle&&i.featureName===d&&(g.title=i.newTitle),d&&!f){if(function(t){return 0===t.indexOf("my")}(d))p={onclick:y.option.onclick,featureName:d};else{var v=KE(d);if(!v)return;p=new v}l[d]=p}else if(!(p=l[f]))return;p.uid=bc("toolbox-feature"),p.model=y,p.ecModel=e,p.api=n;var m=p instanceof ZE;d||!f?!y.get("show")||m&&p.unusable?m&&p.remove&&p.remove(e,n):(!function(i,s,l){var u,h,c=i.getModel("iconStyle"),p=i.getModel(["emphasis","iconStyle"]),d=s instanceof ZE&&s.getIcons?s.getIcons():i.get("icon"),f=i.get("title")||{};X(d)?(u={})[l]=d:u=d;X(f)?(h={})[l]=f:h=f;var g=i.iconPaths={};E(u,(function(l,u){var d=Vh(l,{},{x:-o/2,y:-o/2,width:o,height:o});d.setStyle(c.getItemStyle()),d.ensureState("emphasis").style=p.getItemStyle();var f=new Ns({style:{text:h[u],align:p.get("textAlign"),borderRadius:p.get("textBorderRadius"),padding:p.get("textPadding"),fill:null},ignore:!0});d.setTextContent(f),Wh({el:d,componentModel:t,itemName:u,formatterParamsExtra:{title:h[u]}}),d.__title=h[u],d.on("mouseover",(function(){var e=p.getItemStyle(),i=a?null==t.get("right")&&"right"!==t.get("left")?"right":"left":null==t.get("bottom")&&"bottom"!==t.get("top")?"bottom":"top";f.setStyle({fill:p.get("textFill")||e.fill||e.stroke||"#000",backgroundColor:p.get("textBackgroundColor")}),d.setTextConfig({position:p.get("textPosition")||i}),f.ignore=!t.get("showTitle"),n.enterEmphasis(this)})).on("mouseout",(function(){"emphasis"!==i.get(["iconStatus",u])&&n.leaveEmphasis(this),f.hide()})),("emphasis"===i.get(["iconStatus",u])?Il:Tl)(d),r.add(d),d.on("click",W(s.onclick,s,e,n,u)),g[u]=d}))}(y,p,d),y.setIconStatus=function(t,e){var n=this.option,i=this.iconPaths;n.iconStatus=n.iconStatus||{},n.iconStatus[t]=e,i[t]&&("emphasis"===e?Il:Tl)(i[t])},p instanceof ZE&&p.render&&p.render(y,e,n,i)):m&&p.dispose&&p.dispose(e,n)}},e.prototype.updateView=function(t,e,n,i){E(this._features,(function(t){t instanceof ZE&&t.updateView&&t.updateView(t.model,e,n,i)}))},e.prototype.remove=function(t,e){E(this._features,(function(n){n instanceof ZE&&n.remove&&n.remove(t,e)})),this.group.removeAll()},e.prototype.dispose=function(t,e){E(this._features,(function(n){n instanceof ZE&&n.dispose&&n.dispose(t,e)}))},e.type="toolbox",e}(mg);var tz=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.onclick=function(t,e){var n=this.model,i=n.get("name")||t.get("title.0.text")||"echarts",o="svg"===e.getZr().painter.getType(),a=o?"svg":n.get("type",!0)||"png",s=e.getConnectedDataURL({type:a,backgroundColor:n.get("backgroundColor",!0)||t.get("backgroundColor")||"#fff",connectedBackgroundColor:n.get("connectedBackgroundColor"),excludeComponents:n.get("excludeComponents"),pixelRatio:n.get("pixelRatio")}),l=r.browser;if(U(MouseEvent)&&(l.newEdge||!l.ie&&!l.edge)){var u=document.createElement("a");u.download=i+"."+a,u.target="_blank",u.href=s;var h=new MouseEvent("click",{view:document.defaultView,bubbles:!0,cancelable:!1});u.dispatchEvent(h)}else if(window.navigator.msSaveOrOpenBlob||o){var c=s.split(","),p=c[0].indexOf("base64")>-1,d=o?decodeURIComponent(c[1]):c[1];p&&(d=window.atob(d));var f=i+"."+a;if(window.navigator.msSaveOrOpenBlob){for(var g=d.length,y=new Uint8Array(g);g--;)y[g]=d.charCodeAt(g);var v=new Blob([y]);window.navigator.msSaveOrOpenBlob(v,f)}else{var m=document.createElement("iframe");document.body.appendChild(m);var x=m.contentWindow,_=x.document;_.open("image/svg+xml","replace"),_.write(d),_.close(),x.focus(),_.execCommand("SaveAs",!0,f),document.body.removeChild(m)}}else{var b=n.get("lang"),w='',S=window.open();S.document.write(w),S.document.title=i}},e.getDefaultOption=function(t){return{show:!0,icon:"M4.7,22.9L29.3,45.5L54.7,23.4M4.6,43.6L4.6,58L53.8,58L53.8,43.6M29.2,45.1L29.2,0",title:t.getLocaleModel().get(["toolbox","saveAsImage","title"]),type:"png",connectedBackgroundColor:"#fff",name:"",excludeComponents:["toolbox"],lang:t.getLocaleModel().get(["toolbox","saveAsImage","lang"])}},e}(ZE),ez="__ec_magicType_stack__",nz=[["line","bar"],["stack"]],iz=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.getIcons=function(){var t=this.model,e=t.get("icon"),n={};return E(t.get("type"),(function(t){e[t]&&(n[t]=e[t])})),n},e.getDefaultOption=function(t){return{show:!0,type:[],icon:{line:"M4.1,28.9h7.1l9.3-22l7.4,38l9.7-19.7l3,12.8h14.9M4.1,58h51.4",bar:"M6.7,22.9h10V48h-10V22.9zM24.9,13h10v35h-10V13zM43.2,2h10v46h-10V2zM3.1,58h53.7",stack:"M8.2,38.4l-8.4,4.1l30.6,15.3L60,42.5l-8.1-4.1l-21.5,11L8.2,38.4z M51.9,30l-8.1,4.2l-13.4,6.9l-13.9-6.9L8.2,30l-8.4,4.2l8.4,4.2l22.2,11l21.5-11l8.1-4.2L51.9,30z M51.9,21.7l-8.1,4.2L35.7,30l-5.3,2.8L24.9,30l-8.4-4.1l-8.3-4.2l-8.4,4.2L8.2,30l8.3,4.2l13.9,6.9l13.4-6.9l8.1-4.2l8.1-4.1L51.9,21.7zM30.4,2.2L-0.2,17.5l8.4,4.1l8.3,4.2l8.4,4.2l5.5,2.7l5.3-2.7l8.1-4.2l8.1-4.2l8.1-4.1L30.4,2.2z"},title:t.getLocaleModel().get(["toolbox","magicType","title"]),option:{},seriesIndex:{}}},e.prototype.onclick=function(t,e,n){var i=this.model,r=i.get(["seriesIndex",n]);if(rz[n]){var o,a={series:[]};E(nz,(function(t){P(t,n)>=0&&E(t,(function(t){i.setIconStatus(t,"normal")}))})),i.setIconStatus(n,"emphasis"),t.eachComponent({mainType:"series",query:null==r?null:{seriesIndex:r}},(function(t){var e=t.subType,r=t.id,o=rz[n](e,r,t,i);o&&(k(o,t.option),a.series.push(o));var s=t.coordinateSystem;if(s&&"cartesian2d"===s.type&&("line"===n||"bar"===n)){var l=s.getAxesByScale("ordinal")[0];if(l){var u=l.dim+"Axis",h=t.getReferringComponents(u,Po).models[0].componentIndex;a[u]=a[u]||[];for(var c=0;c<=h;c++)a[u][h]=a[u][h]||{};a[u][h].boundaryGap="bar"===n}}}));var s=n;"stack"===n&&(o=C({stack:i.option.title.tiled,tiled:i.option.title.stack},i.option.title),"emphasis"!==i.get(["iconStatus",n])&&(s="tiled")),e.dispatchAction({type:"changeMagicType",currentType:s,newOption:a,newTitle:o,featureName:"magicType"})}},e}(ZE),rz={line:function(t,e,n,i){if("bar"===t)return C({id:e,type:"line",data:n.get("data"),stack:n.get("stack"),markPoint:n.get("markPoint"),markLine:n.get("markLine")},i.get(["option","line"])||{},!0)},bar:function(t,e,n,i){if("line"===t)return C({id:e,type:"bar",data:n.get("data"),stack:n.get("stack"),markPoint:n.get("markPoint"),markLine:n.get("markLine")},i.get(["option","bar"])||{},!0)},stack:function(t,e,n,i){var r=n.get("stack")===ez;if("line"===t||"bar"===t)return i.setIconStatus("stack",r?"normal":"emphasis"),C({id:e,stack:r?"":ez},i.get(["option","stack"])||{},!0)}};fm({type:"changeMagicType",event:"magicTypeChanged",update:"prepareAndUpdate"},(function(t,e){e.mergeOption(t.newOption)}));var oz=new Array(60).join("-"),az="\t";function sz(t){return t.replace(/^\s\s*/,"").replace(/\s\s*$/,"")}var lz=new RegExp("[\t]+","g");function uz(t,e){var n=t.split(new RegExp("\n*"+oz+"\n*","g")),i={series:[]};return E(n,(function(t,n){if(function(t){if(t.slice(0,t.indexOf("\n")).indexOf(az)>=0)return!0}(t)){var r=function(t){for(var e=t.split(/\n+/g),n=[],i=z(sz(e.shift()).split(lz),(function(t){return{name:t,data:[]}})),r=0;r=0)&&t(r,i._targetInfoList)}))}return t.prototype.setOutputRanges=function(t,e){return this.matchOutputRanges(t,e,(function(t,e,n){if((t.coordRanges||(t.coordRanges=[])).push(e),!t.coordRange){t.coordRange=e;var i=Sz[t.brushType](0,n,e);t.__rangeOffset={offset:Iz[t.brushType](i.values,t.range,[1,1]),xyMinMax:i.xyMinMax}}})),t},t.prototype.matchOutputRanges=function(t,e,n){E(t,(function(t){var i=this.findTargetInfo(t,e);i&&!0!==i&&E(i.coordSyses,(function(i){var r=Sz[t.brushType](1,i,t.range,!0);n(t,r.values,i,e)}))}),this)},t.prototype.setInputRanges=function(t,e){E(t,(function(t){var n,i,r,o,a,s=this.findTargetInfo(t,e);if(t.range=t.range||[],s&&!0!==s){t.panelId=s.panelId;var l=Sz[t.brushType](0,s.coordSys,t.coordRange),u=t.__rangeOffset;t.range=u?Iz[t.brushType](l.values,u.offset,(n=l.xyMinMax,i=u.xyMinMax,r=Cz(n),o=Cz(i),a=[r[0]/o[0],r[1]/o[1]],isNaN(a[0])&&(a[0]=1),isNaN(a[1])&&(a[1]=1),a)):l.values}}),this)},t.prototype.makePanelOpts=function(t,e){return z(this._targetInfoList,(function(n){var i=n.getPanelRect();return{panelId:n.panelId,defaultBrushType:e?e(n):null,clipPath:gL(i),isTargetByCursor:vL(i,t,n.coordSysModel),getLinearBrushOtherExtent:yL(i)}}))},t.prototype.controlSeries=function(t,e,n){var i=this.findTargetInfo(t,n);return!0===i||i&&P(i.coordSyses,e.coordinateSystem)>=0},t.prototype.findTargetInfo=function(t,e){for(var n=this._targetInfoList,i=xz(e,t),r=0;rt[1]&&t.reverse(),t}function xz(t,e){return ko(t,e,{includeMainTypes:yz})}var _z={grid:function(t,e){var n=t.xAxisModels,i=t.yAxisModels,r=t.gridModels,o=ft(),a={},s={};(n||i||r)&&(E(n,(function(t){var e=t.axis.grid.model;o.set(e.id,e),a[e.id]=!0})),E(i,(function(t){var e=t.axis.grid.model;o.set(e.id,e),s[e.id]=!0})),E(r,(function(t){o.set(t.id,t),a[t.id]=!0,s[t.id]=!0})),o.each((function(t){var r=t.coordinateSystem,o=[];E(r.getCartesians(),(function(t,e){(P(n,t.getAxis("x").model)>=0||P(i,t.getAxis("y").model)>=0)&&o.push(t)})),e.push({panelId:"grid--"+t.id,gridModel:t,coordSysModel:t,coordSys:o[0],coordSyses:o,getPanelRect:wz.grid,xAxisDeclared:a[t.id],yAxisDeclared:s[t.id]})})))},geo:function(t,e){E(t.geoModels,(function(t){var n=t.coordinateSystem;e.push({panelId:"geo--"+t.id,geoModel:t,coordSysModel:t,coordSys:n,coordSyses:[n],getPanelRect:wz.geo})}))}},bz=[function(t,e){var n=t.xAxisModel,i=t.yAxisModel,r=t.gridModel;return!r&&n&&(r=n.axis.grid.model),!r&&i&&(r=i.axis.grid.model),r&&r===e.gridModel},function(t,e){var n=t.geoModel;return n&&n===e.geoModel}],wz={grid:function(){return this.coordSys.master.getRect().clone()},geo:function(){var t=this.coordSys,e=t.getBoundingRect().clone();return e.applyTransform(Lh(t)),e}},Sz={lineX:H(Mz,0),lineY:H(Mz,1),rect:function(t,e,n,i){var r=t?e.pointToData([n[0][0],n[1][0]],i):e.dataToPoint([n[0][0],n[1][0]],i),o=t?e.pointToData([n[0][1],n[1][1]],i):e.dataToPoint([n[0][1],n[1][1]],i),a=[mz([r[0],o[0]]),mz([r[1],o[1]])];return{values:a,xyMinMax:a}},polygon:function(t,e,n,i){var r=[[1/0,-1/0],[1/0,-1/0]];return{values:z(n,(function(n){var o=t?e.pointToData(n,i):e.dataToPoint(n,i);return r[0][0]=Math.min(r[0][0],o[0]),r[1][0]=Math.min(r[1][0],o[1]),r[0][1]=Math.max(r[0][1],o[0]),r[1][1]=Math.max(r[1][1],o[1]),o})),xyMinMax:r}}};function Mz(t,e,n,i){var r=n.getAxis(["x","y"][t]),o=mz(z([0,1],(function(t){return e?r.coordToData(r.toLocalCoord(i[t]),!0):r.toGlobalCoord(r.dataToCoord(i[t]))}))),a=[];return a[t]=o,a[1-t]=[NaN,NaN],{values:o,xyMinMax:a}}var Iz={lineX:H(Tz,0),lineY:H(Tz,1),rect:function(t,e,n){return[[t[0][0]-n[0]*e[0][0],t[0][1]-n[0]*e[0][1]],[t[1][0]-n[1]*e[1][0],t[1][1]-n[1]*e[1][1]]]},polygon:function(t,e,n){return z(t,(function(t,i){return[t[0]-n[0]*e[i][0],t[1]-n[1]*e[i][1]]}))}};function Tz(t,e,n,i){return[e[0]-i[t]*n[0],e[1]-i[t]*n[1]]}function Cz(t){return t?[t[0][1]-t[0][0],t[1][1]-t[1][0]]:[NaN,NaN]}var Dz,Az,kz=E,Lz=go+"toolbox-dataZoom_",Pz=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.render=function(t,e,n,i){this._brushController||(this._brushController=new Vk(n.getZr()),this._brushController.on("brush",W(this._onBrush,this)).mount()),function(t,e,n,i,r){var o=n._isZoomActive;i&&"takeGlobalCursor"===i.type&&(o="dataZoomSelect"===i.key&&i.dataZoomSelectActive);n._isZoomActive=o,t.setIconStatus("zoom",o?"emphasis":"normal");var a=new vz(Rz(t),e,{include:["grid"]}).makePanelOpts(r,(function(t){return t.xAxisDeclared&&!t.yAxisDeclared?"lineX":!t.xAxisDeclared&&t.yAxisDeclared?"lineY":"rect"}));n._brushController.setPanels(a).enableBrush(!(!o||!a.length)&&{brushType:"auto",brushStyle:t.getModel("brushStyle").getItemStyle()})}(t,e,this,i,n),function(t,e){t.setIconStatus("back",function(t){return fz(t).length}(e)>1?"emphasis":"normal")}(t,e)},e.prototype.onclick=function(t,e,n){Oz[n].call(this)},e.prototype.remove=function(t,e){this._brushController&&this._brushController.unmount()},e.prototype.dispose=function(t,e){this._brushController&&this._brushController.dispose()},e.prototype._onBrush=function(t){var e=t.areas;if(t.isEnd&&e.length){var n={},i=this.ecModel;this._brushController.updateCovers([]),new vz(Rz(this.model),i,{include:["grid"]}).matchOutputRanges(e,i,(function(t,e,n){if("cartesian2d"===n.type){var i=t.brushType;"rect"===i?(r("x",n,e[0]),r("y",n,e[1])):r({lineX:"x",lineY:"y"}[i],n,e)}})),function(t,e){var n=fz(t);pz(e,(function(e,i){for(var r=n.length-1;r>=0&&!n[r][i];r--);if(r<0){var o=t.queryComponents({mainType:"dataZoom",subType:"select",id:i})[0];if(o){var a=o.getPercentRange();n[0][i]={dataZoomId:i,start:a[0],end:a[1]}}}})),n.push(e)}(i,n),this._dispatchZoomAction(n)}function r(t,e,r){var o=e.getAxis(t),a=o.model,s=function(t,e,n){var i;return n.eachComponent({mainType:"dataZoom",subType:"select"},(function(n){n.getAxisModel(t,e.componentIndex)&&(i=n)})),i}(t,a,i),l=s.findRepresentativeAxisProxy(a).getMinMaxSpan();null==l.minValueSpan&&null==l.maxValueSpan||(r=dk(0,r.slice(),o.scale.getExtent(),0,l.minValueSpan,l.maxValueSpan)),s&&(n[s.id]={dataZoomId:s.id,startValue:r[0],endValue:r[1]})}},e.prototype._dispatchZoomAction=function(t){var e=[];kz(t,(function(t,n){e.push(T(t))})),e.length&&this.api.dispatchAction({type:"dataZoom",from:this.uid,batch:e})},e.getDefaultOption=function(t){return{show:!0,filterMode:"filter",icon:{zoom:"M0,13.5h26.9 M13.5,26.9V0 M32.1,13.5H58V58H13.5 V32.1",back:"M22,1.4L9.9,13.5l12.3,12.3 M10.3,13.5H54.9v44.6 H10.3v-26"},title:t.getLocaleModel().get(["toolbox","dataZoom","title"]),brushStyle:{borderWidth:0,color:"rgba(210,219,238,0.2)"}}},e}(ZE),Oz={zoom:function(){var t=!this._isZoomActive;this.api.dispatchAction({type:"takeGlobalCursor",key:"dataZoomSelect",dataZoomSelectActive:t})},back:function(){this._dispatchZoomAction(function(t){var e=fz(t),n=e[e.length-1];e.length>1&&e.pop();var i={};return pz(n,(function(t,n){for(var r=e.length-1;r>=0;r--)if(t=e[r][n]){i[n]=t;break}})),i}(this.ecModel))}};function Rz(t){var e={xAxisIndex:t.get("xAxisIndex",!0),yAxisIndex:t.get("yAxisIndex",!0),xAxisId:t.get("xAxisId",!0),yAxisId:t.get("yAxisId",!0)};return null==e.xAxisIndex&&null==e.xAxisId&&(e.xAxisIndex="all"),null==e.yAxisIndex&&null==e.yAxisId&&(e.yAxisIndex="all"),e}Dz="dataZoom",Az=function(t){var e=t.getComponent("toolbox",0),n=["feature","dataZoom"];if(e&&null!=e.get(n)){var i=e.getModel(n),r=[],o=ko(t,Rz(i));return kz(o.xAxisModels,(function(t){return a(t,"xAxis","xAxisIndex")})),kz(o.yAxisModels,(function(t){return a(t,"yAxis","yAxisIndex")})),r}function a(t,e,n){var o=t.componentIndex,a={type:"select",$fromToolbox:!0,filterMode:i.get("filterMode",!0)||"filter",id:Lz+e+o};a[n]=o,r.push(a)}},lt(null==$p.get(Dz)&&Az),$p.set(Dz,Az);var Nz=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="tooltip",e.dependencies=["axisPointer"],e.defaultOption={z:60,show:!0,showContent:!0,trigger:"item",triggerOn:"mousemove|click",alwaysShowContent:!1,displayMode:"single",renderMode:"auto",confine:null,showDelay:0,hideDelay:100,transitionDuration:.4,enterable:!1,backgroundColor:"#fff",shadowBlur:10,shadowColor:"rgba(0, 0, 0, .2)",shadowOffsetX:1,shadowOffsetY:2,borderRadius:4,borderWidth:1,padding:null,extraCssText:"",axisPointer:{type:"line",axis:"auto",animation:"auto",animationDurationUpdate:200,animationEasingUpdate:"exponentialOut",crossStyle:{color:"#999",width:1,type:"dashed",textStyle:{}}},textStyle:{color:"#666",fontSize:14}},e}(Ap);function Ez(t){var e=t.get("confine");return null!=e?!!e:"richText"===t.get("renderMode")}function zz(t){if(r.domSupported)for(var e=document.documentElement.style,n=0,i=t.length;n-1?(u+="top:50%",h+="translateY(-50%) rotate("+(a="left"===s?-225:-45)+"deg)"):(u+="left:50%",h+="translateX(-50%) rotate("+(a="top"===s?225:45)+"deg)");var c=a*Math.PI/180,p=l+r,d=p*Math.abs(Math.cos(c))+p*Math.abs(Math.sin(c)),f=e+" solid "+r+"px;";return'
'}(n,i,r)),X(t))o.innerHTML=t+a;else if(t){o.innerHTML="",Y(t)||(t=[t]);for(var s=0;s=0?this._tryShow(n,i):"leave"===e&&this._hide(i))}),this))},e.prototype._keepShow=function(){var t=this._tooltipModel,e=this._ecModel,n=this._api,i=t.get("triggerOn");if(null!=this._lastX&&null!=this._lastY&&"none"!==i&&"click"!==i){var r=this;clearTimeout(this._refreshUpdateTimeout),this._refreshUpdateTimeout=setTimeout((function(){!n.isDisposed()&&r.manuallyShowTip(t,e,n,{x:r._lastX,y:r._lastY,dataByCoordSys:r._lastDataByCoordSys})}))}},e.prototype.manuallyShowTip=function(t,e,n,i){if(i.from!==this.uid&&!r.node&&n.getDom()){var o=tV(i,n);this._ticket="";var a=i.dataByCoordSys,s=function(t,e,n){var i=Lo(t).queryOptionMap,r=i.keys()[0];if(!r||"series"===r)return;var o,a=Ro(e,r,i.get(r),{useDefault:!1,enableAll:!1,enableNone:!1}).models[0];if(!a)return;if(n.getViewOfComponentModel(a).group.traverse((function(e){var n=js(e).tooltipConfig;if(n&&n.name===t.name)return o=e,!0})),o)return{componentMainType:r,componentIndex:a.componentIndex,el:o}}(i,e,n);if(s){var l=s.el.getBoundingRect().clone();l.applyTransform(s.el.transform),this._tryShow({offsetX:l.x+l.width/2,offsetY:l.y+l.height/2,target:s.el,position:i.position,positionDefault:"bottom"},o)}else if(i.tooltip&&null!=i.x&&null!=i.y){var u=$z;u.x=i.x,u.y=i.y,u.update(),js(u).tooltipConfig={name:null,option:i.tooltip},this._tryShow({offsetX:i.x,offsetY:i.y,target:u},o)}else if(a)this._tryShow({offsetX:i.x,offsetY:i.y,position:i.position,dataByCoordSys:a,tooltipOption:i.tooltipOption},o);else if(null!=i.seriesIndex){if(this._manuallyAxisShowTip(t,e,n,i))return;var h=sN(i,e),c=h.point[0],p=h.point[1];null!=c&&null!=p&&this._tryShow({offsetX:c,offsetY:p,target:h.el,position:i.position,positionDefault:"bottom"},o)}else null!=i.x&&null!=i.y&&(n.dispatchAction({type:"updateAxisPointer",x:i.x,y:i.y}),this._tryShow({offsetX:i.x,offsetY:i.y,position:i.position,target:n.getZr().findHover(i.x,i.y).target},o))}},e.prototype.manuallyHideTip=function(t,e,n,i){var r=this._tooltipContent;!this._alwaysShowContent&&this._tooltipModel&&r.hideLater(this._tooltipModel.get("hideDelay")),this._lastX=this._lastY=this._lastDataByCoordSys=null,i.from!==this.uid&&this._hide(tV(i,n))},e.prototype._manuallyAxisShowTip=function(t,e,n,i){var r=i.seriesIndex,o=i.dataIndex,a=e.getComponent("axisPointer").coordSysAxesInfo;if(null!=r&&null!=o&&null!=a){var s=e.getSeriesByIndex(r);if(s)if("axis"===Qz([s.getData().getItemModel(o),s,(s.coordinateSystem||{}).model],this._tooltipModel).get("trigger"))return n.dispatchAction({type:"updateAxisPointer",seriesIndex:r,dataIndex:o,position:i.position}),!0}},e.prototype._tryShow=function(t,e){var n=t.target;if(this._tooltipModel){this._lastX=t.offsetX,this._lastY=t.offsetY;var i=t.dataByCoordSys;if(i&&i.length)this._showAxisTooltip(i,t);else if(n){var r,o;this._lastDataByCoordSys=null,wy(n,(function(t){return null!=js(t).dataIndex?(r=t,!0):null!=js(t).tooltipConfig?(o=t,!0):void 0}),!0),r?this._showSeriesItemTooltip(t,r,e):o?this._showComponentItemTooltip(t,o,e):this._hide(e)}else this._lastDataByCoordSys=null,this._hide(e)}},e.prototype._showOrMove=function(t,e){var n=t.get("showDelay");e=W(e,this),clearTimeout(this._showTimout),n>0?this._showTimout=setTimeout(e,n):e()},e.prototype._showAxisTooltip=function(t,e){var n=this._ecModel,i=this._tooltipModel,r=[e.offsetX,e.offsetY],o=Qz([e.tooltipOption],i),a=this._renderMode,s=[],l=qf("section",{blocks:[],noHeader:!0}),u=[],h=new ag;E(t,(function(t){E(t.dataByAxis,(function(t){var e=n.getComponent(t.axisDim+"Axis",t.axisIndex),r=t.value;if(e&&null!=r){var o=HR(r,e.axis,n,t.seriesDataIndices,t.valueLabelOpt),c=qf("section",{header:o,noHeader:!ut(o),sortBlocks:!0,blocks:[]});l.blocks.push(c),E(t.seriesDataIndices,(function(l){var p=n.getSeriesByIndex(l.seriesIndex),d=l.dataIndexInside,f=p.getDataParams(d);if(!(f.dataIndex<0)){f.axisDim=t.axisDim,f.axisIndex=t.axisIndex,f.axisType=t.axisType,f.axisId=t.axisId,f.axisValue=h_(e.axis,{value:r}),f.axisValueLabel=o,f.marker=h.makeTooltipMarker("item",gp(f.color),a);var g=pf(p.formatTooltip(d,!0,null)),y=g.frag;if(y){var v=Qz([p],i).get("valueFormatter");c.blocks.push(v?A({valueFormatter:v},y):y)}g.text&&u.push(g.text),s.push(f)}}))}}))})),l.blocks.reverse(),u.reverse();var c=e.position,p=o.get("order"),d=eg(l,h,a,p,n.get("useUTC"),o.get("textStyle"));d&&u.unshift(d);var f="richText"===a?"\n\n":"
",g=u.join(f);this._showOrMove(o,(function(){this._updateContentNotChangedOnAxis(t,s)?this._updatePosition(o,c,r[0],r[1],this._tooltipContent,s):this._showTooltipContent(o,g,s,Math.random()+"",r[0],r[1],c,null,h)}))},e.prototype._showSeriesItemTooltip=function(t,e,n){var i=this._ecModel,r=js(e),o=r.seriesIndex,a=i.getSeriesByIndex(o),s=r.dataModel||a,l=r.dataIndex,u=r.dataType,h=s.getData(u),c=this._renderMode,p=t.positionDefault,d=Qz([h.getItemModel(l),s,a&&(a.coordinateSystem||{}).model],this._tooltipModel,p?{position:p}:null),f=d.get("trigger");if(null==f||"item"===f){var g=s.getDataParams(l,u),y=new ag;g.marker=y.makeTooltipMarker("item",gp(g.color),c);var v=pf(s.formatTooltip(l,!1,u)),m=d.get("order"),x=d.get("valueFormatter"),_=v.frag,b=_?eg(x?A({valueFormatter:x},_):_,y,c,m,i.get("useUTC"),d.get("textStyle")):v.text,w="item_"+s.name+"_"+l;this._showOrMove(d,(function(){this._showTooltipContent(d,b,g,w,t.offsetX,t.offsetY,t.position,t.target,y)})),n({type:"showTip",dataIndexInside:l,dataIndex:h.getRawIndex(l),seriesIndex:o,from:this.uid})}},e.prototype._showComponentItemTooltip=function(t,e,n){var i=js(e),r=i.tooltipConfig.option||{};if(X(r)){r={content:r,formatter:r}}var o=[r],a=this._ecModel.getComponent(i.componentMainType,i.componentIndex);a&&o.push(a),o.push({formatter:r.content});var s=t.positionDefault,l=Qz(o,this._tooltipModel,s?{position:s}:null),u=l.get("content"),h=Math.random()+"",c=new ag;this._showOrMove(l,(function(){var n=T(l.get("formatterParams")||{});this._showTooltipContent(l,u,n,h,t.offsetX,t.offsetY,t.position,e,c)})),n({type:"showTip",from:this.uid})},e.prototype._showTooltipContent=function(t,e,n,i,r,o,a,s,l){if(this._ticket="",t.get("showContent")&&t.get("show")){var u=this._tooltipContent;u.setEnterable(t.get("enterable"));var h=t.get("formatter");a=a||t.get("position");var c=e,p=this._getNearestPoint([r,o],n,t.get("trigger"),t.get("borderColor")).color;if(h)if(X(h)){var d=t.ecModel.get("useUTC"),f=Y(n)?n[0]:n;c=h,f&&f.axisType&&f.axisType.indexOf("time")>=0&&(c=Yc(f.axisValue,c,d)),c=dp(c,n,!0)}else if(U(h)){var g=W((function(e,i){e===this._ticket&&(u.setContent(i,l,t,p,a),this._updatePosition(t,a,r,o,u,n,s))}),this);this._ticket=i,c=h(n,i,g)}else c=h;u.setContent(c,l,t,p,a),u.show(t,p),this._updatePosition(t,a,r,o,u,n,s)}},e.prototype._getNearestPoint=function(t,e,n,i){return"axis"===n||Y(e)?{color:i||("html"===this._renderMode?"#fff":"none")}:Y(e)?void 0:{color:i||e.color||e.borderColor}},e.prototype._updatePosition=function(t,e,n,i,r,o,a){var s=this._api.getWidth(),l=this._api.getHeight();e=e||t.get("position");var u=r.getSize(),h=t.get("align"),c=t.get("verticalAlign"),p=a&&a.getBoundingRect().clone();if(a&&p.applyTransform(a.transform),U(e)&&(e=e([n,i],o,r.el,p,{viewSize:[s,l],contentSize:u.slice()})),Y(e))n=Gr(e[0],s),i=Gr(e[1],l);else if(q(e)){var d=e;d.width=u[0],d.height=u[1];var f=wp(d,{width:s,height:l});n=f.x,i=f.y,h=null,c=null}else if(X(e)&&a){var g=function(t,e,n,i){var r=n[0],o=n[1],a=Math.ceil(Math.SQRT2*i)+8,s=0,l=0,u=e.width,h=e.height;switch(t){case"inside":s=e.x+u/2-r/2,l=e.y+h/2-o/2;break;case"top":s=e.x+u/2-r/2,l=e.y-o-a;break;case"bottom":s=e.x+u/2-r/2,l=e.y+h+a;break;case"left":s=e.x-r-a,l=e.y+h/2-o/2;break;case"right":s=e.x+u+a,l=e.y+h/2-o/2}return[s,l]}(e,p,u,t.get("borderWidth"));n=g[0],i=g[1]}else{g=function(t,e,n,i,r,o,a){var s=n.getSize(),l=s[0],u=s[1];null!=o&&(t+l+o+2>i?t-=l+o:t+=o);null!=a&&(e+u+a>r?e-=u+a:e+=a);return[t,e]}(n,i,r,s,l,h?null:20,c?null:20);n=g[0],i=g[1]}if(h&&(n-=eV(h)?u[0]/2:"right"===h?u[0]:0),c&&(i-=eV(c)?u[1]/2:"bottom"===c?u[1]:0),Ez(t)){g=function(t,e,n,i,r){var o=n.getSize(),a=o[0],s=o[1];return t=Math.min(t+a,i)-a,e=Math.min(e+s,r)-s,t=Math.max(t,0),e=Math.max(e,0),[t,e]}(n,i,r,s,l);n=g[0],i=g[1]}r.moveTo(n,i)},e.prototype._updateContentNotChangedOnAxis=function(t,e){var n=this._lastDataByCoordSys,i=this._cbParamsList,r=!!n&&n.length===t.length;return r&&E(n,(function(n,o){var a=n.dataByAxis||[],s=(t[o]||{}).dataByAxis||[];(r=r&&a.length===s.length)&&E(a,(function(t,n){var o=s[n]||{},a=t.seriesDataIndices||[],l=o.seriesDataIndices||[];(r=r&&t.value===o.value&&t.axisType===o.axisType&&t.axisId===o.axisId&&a.length===l.length)&&E(a,(function(t,e){var n=l[e];r=r&&t.seriesIndex===n.seriesIndex&&t.dataIndex===n.dataIndex})),i&&E(t.seriesDataIndices,(function(t){var n=t.seriesIndex,o=e[n],a=i[n];o&&a&&a.data!==o.data&&(r=!1)}))}))})),this._lastDataByCoordSys=t,this._cbParamsList=e,!!r},e.prototype._hide=function(t){this._lastDataByCoordSys=null,t({type:"hideTip",from:this.uid})},e.prototype.dispose=function(t,e){!r.node&&e.getDom()&&(Og(this,"_updatePosition"),this._tooltipContent.dispose(),oN("itemTooltip",e))},e.type="tooltip",e}(mg);function Qz(t,e,n){var i,r=e.ecModel;n?(i=new xc(n,r,r),i=new xc(e.option,i,r)):i=e;for(var o=t.length-1;o>=0;o--){var a=t[o];a&&(a instanceof xc&&(a=a.get("tooltip",!0)),X(a)&&(a={formatter:a}),a&&(i=new xc(a,i,r)))}return i}function tV(t,e){return t.dispatchAction||W(e.dispatchAction,e)}function eV(t){return"center"===t||"middle"===t}var nV=["rect","polygon","keep","clear"];function iV(t,e){var n=yo(t?t.brush:[]);if(n.length){var i=[];E(n,(function(t){var e=t.hasOwnProperty("toolbox")?t.toolbox:[];e instanceof Array&&(i=i.concat(e))}));var r=t&&t.toolbox;Y(r)&&(r=r[0]),r||(r={feature:{}},t.toolbox=[r]);var o=r.feature||(r.feature={}),a=o.brush||(o.brush={}),s=a.type||(a.type=[]);s.push.apply(s,i),function(t){var e={};E(t,(function(t){e[t]=1})),t.length=0,E(e,(function(e,n){t.push(n)}))}(s),e&&!s.length&&s.push.apply(s,nV)}}var rV=E;function oV(t){if(t)for(var e in t)if(t.hasOwnProperty(e))return!0}function aV(t,e,n){var i={};return rV(e,(function(e){var r,o=i[e]=((r=function(){}).prototype.__hidden=r.prototype,new r);rV(t[e],(function(t,i){if(sD.isValidType(i)){var r={type:i,visual:t};n&&n(r,e),o[i]=new sD(r),"opacity"===i&&((r=T(r)).type="colorAlpha",o.__hidden.__alphaForOpacity=new sD(r))}}))})),i}function sV(t,e,n){var i;E(n,(function(t){e.hasOwnProperty(t)&&oV(e[t])&&(i=!0)})),i&&E(n,(function(n){e.hasOwnProperty(n)&&oV(e[n])?t[n]=T(e[n]):delete t[n]}))}var lV={lineX:uV(0),lineY:uV(1),rect:{point:function(t,e,n){return t&&n.boundingRect.contain(t[0],t[1])},rect:function(t,e,n){return t&&n.boundingRect.intersect(t)}},polygon:{point:function(t,e,n){return t&&n.boundingRect.contain(t[0],t[1])&&x_(n.range,t[0],t[1])},rect:function(t,e,n){var i=n.range;if(!t||i.length<=1)return!1;var r=t.x,o=t.y,a=t.width,s=t.height,l=i[0];return!!(x_(i,r,o)||x_(i,r+a,o)||x_(i,r,o+s)||x_(i,r+a,o+s)||Re.create(t).contain(l[0],l[1])||Bh(r,o,r+a,o,i)||Bh(r,o,r,o+s,i)||Bh(r+a,o,r+a,o+s,i)||Bh(r,o+s,r+a,o+s,i))||void 0}}};function uV(t){var e=["x","y"],n=["width","height"];return{point:function(e,n,i){if(e){var r=i.range;return hV(e[t],r)}},rect:function(i,r,o){if(i){var a=o.range,s=[i[e[t]],i[e[t]]+i[n[t]]];return s[1]e[0][1]&&(e[0][1]=o[0]),o[1]e[1][1]&&(e[1][1]=o[1])}return e&&xV(e)}};function xV(t){return new Re(t[0][0],t[1][0],t[0][1]-t[0][0],t[1][1]-t[1][0])}var _V=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.init=function(t,e){this.ecModel=t,this.api=e,this.model,(this._brushController=new Vk(e.getZr())).on("brush",W(this._onBrush,this)).mount()},e.prototype.render=function(t,e,n,i){this.model=t,this._updateController(t,e,n,i)},e.prototype.updateTransform=function(t,e,n,i){fV(e),this._updateController(t,e,n,i)},e.prototype.updateVisual=function(t,e,n,i){this.updateTransform(t,e,n,i)},e.prototype.updateView=function(t,e,n,i){this._updateController(t,e,n,i)},e.prototype._updateController=function(t,e,n,i){(!i||i.$from!==t.id)&&this._brushController.setPanels(t.brushTargetManager.makePanelOpts(n)).enableBrush(t.brushOption).updateCovers(t.areas.slice())},e.prototype.dispose=function(){this._brushController.dispose()},e.prototype._onBrush=function(t){var e=this.model.id,n=this.model.brushTargetManager.setOutputRanges(t.areas,this.ecModel);(!t.isEnd||t.removeOnClick)&&this.api.dispatchAction({type:"brush",brushId:e,areas:T(n),$from:e}),t.isEnd&&this.api.dispatchAction({type:"brushEnd",brushId:e,areas:T(n),$from:e})},e.type="brush",e}(mg),bV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.areas=[],n.brushOption={},n}return n(e,t),e.prototype.optionUpdated=function(t,e){var n=this.option;!e&&sV(n,t,["inBrush","outOfBrush"]);var i=n.inBrush=n.inBrush||{};n.outOfBrush=n.outOfBrush||{color:"#ddd"},i.hasOwnProperty("liftZ")||(i.liftZ=5)},e.prototype.setAreas=function(t){t&&(this.areas=z(t,(function(t){return wV(this.option,t)}),this))},e.prototype.setBrushOption=function(t){this.brushOption=wV(this.option,t),this.brushType=this.brushOption.brushType},e.type="brush",e.dependencies=["geo","grid","xAxis","yAxis","parallel","series"],e.defaultOption={seriesIndex:"all",brushType:"rect",brushMode:"single",transformable:!0,brushStyle:{borderWidth:1,color:"rgba(210,219,238,0.3)",borderColor:"#D2DBEE"},throttleType:"fixRate",throttleDelay:0,removeOnClick:!0,z:1e4},e}(Ap);function wV(t,e){return C({brushType:t.brushType,brushMode:t.brushMode,transformable:t.transformable,brushStyle:new xc(t.brushStyle).getItemStyle(),removeOnClick:t.removeOnClick,z:t.z},e,!0)}var SV=["rect","polygon","lineX","lineY","keep","clear"],MV=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.render=function(t,e,n){var i,r,o;e.eachComponent({mainType:"brush"},(function(t){i=t.brushType,r=t.brushOption.brushMode||"single",o=o||!!t.areas.length})),this._brushType=i,this._brushMode=r,E(t.get("type",!0),(function(e){t.setIconStatus(e,("keep"===e?"multiple"===r:"clear"===e?o:e===i)?"emphasis":"normal")}))},e.prototype.updateView=function(t,e,n){this.render(t,e,n)},e.prototype.getIcons=function(){var t=this.model,e=t.get("icon",!0),n={};return E(t.get("type",!0),(function(t){e[t]&&(n[t]=e[t])})),n},e.prototype.onclick=function(t,e,n){var i=this._brushType,r=this._brushMode;"clear"===n?(e.dispatchAction({type:"axisAreaSelect",intervals:[]}),e.dispatchAction({type:"brush",command:"clear",areas:[]})):e.dispatchAction({type:"takeGlobalCursor",key:"brush",brushOption:{brushType:"keep"===n?i:i!==n&&n,brushMode:"keep"===n?"multiple"===r?"single":"multiple":r}})},e.getDefaultOption=function(t){return{show:!0,type:SV.slice(),icon:{rect:"M7.3,34.7 M0.4,10V-0.2h9.8 M89.6,10V-0.2h-9.8 M0.4,60v10.2h9.8 M89.6,60v10.2h-9.8 M12.3,22.4V10.5h13.1 M33.6,10.5h7.8 M49.1,10.5h7.8 M77.5,22.4V10.5h-13 M12.3,31.1v8.2 M77.7,31.1v8.2 M12.3,47.6v11.9h13.1 M33.6,59.5h7.6 M49.1,59.5 h7.7 M77.5,47.6v11.9h-13",polygon:"M55.2,34.9c1.7,0,3.1,1.4,3.1,3.1s-1.4,3.1-3.1,3.1 s-3.1-1.4-3.1-3.1S53.5,34.9,55.2,34.9z M50.4,51c1.7,0,3.1,1.4,3.1,3.1c0,1.7-1.4,3.1-3.1,3.1c-1.7,0-3.1-1.4-3.1-3.1 C47.3,52.4,48.7,51,50.4,51z M55.6,37.1l1.5-7.8 M60.1,13.5l1.6-8.7l-7.8,4 M59,19l-1,5.3 M24,16.1l6.4,4.9l6.4-3.3 M48.5,11.6 l-5.9,3.1 M19.1,12.8L9.7,5.1l1.1,7.7 M13.4,29.8l1,7.3l6.6,1.6 M11.6,18.4l1,6.1 M32.8,41.9 M26.6,40.4 M27.3,40.2l6.1,1.6 M49.9,52.1l-5.6-7.6l-4.9-1.2",lineX:"M15.2,30 M19.7,15.6V1.9H29 M34.8,1.9H40.4 M55.3,15.6V1.9H45.9 M19.7,44.4V58.1H29 M34.8,58.1H40.4 M55.3,44.4 V58.1H45.9 M12.5,20.3l-9.4,9.6l9.6,9.8 M3.1,29.9h16.5 M62.5,20.3l9.4,9.6L62.3,39.7 M71.9,29.9H55.4",lineY:"M38.8,7.7 M52.7,12h13.2v9 M65.9,26.6V32 M52.7,46.3h13.2v-9 M24.9,12H11.8v9 M11.8,26.6V32 M24.9,46.3H11.8v-9 M48.2,5.1l-9.3-9l-9.4,9.2 M38.9-3.9V12 M48.2,53.3l-9.3,9l-9.4-9.2 M38.9,62.3V46.4",keep:"M4,10.5V1h10.3 M20.7,1h6.1 M33,1h6.1 M55.4,10.5V1H45.2 M4,17.3v6.6 M55.6,17.3v6.6 M4,30.5V40h10.3 M20.7,40 h6.1 M33,40h6.1 M55.4,30.5V40H45.2 M21,18.9h62.9v48.6H21V18.9z",clear:"M22,14.7l30.9,31 M52.9,14.7L22,45.7 M4.7,16.8V4.2h13.1 M26,4.2h7.8 M41.6,4.2h7.8 M70.3,16.8V4.2H57.2 M4.7,25.9v8.6 M70.3,25.9v8.6 M4.7,43.2v12.6h13.1 M26,55.8h7.8 M41.6,55.8h7.8 M70.3,43.2v12.6H57.2"},title:t.getLocaleModel().get(["toolbox","brush","title"])}},e}(ZE);var IV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.layoutMode={type:"box",ignoreSize:!0},n}return n(e,t),e.type="title",e.defaultOption={z:6,show:!0,text:"",target:"blank",subtext:"",subtarget:"blank",left:0,top:0,backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderWidth:0,padding:5,itemGap:10,textStyle:{fontSize:18,fontWeight:"bold",color:"#464646"},subtextStyle:{fontSize:12,color:"#6E7079"}},e}(Ap),TV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){if(this.group.removeAll(),t.get("show")){var i=this.group,r=t.getModel("textStyle"),o=t.getModel("subtextStyle"),a=t.get("textAlign"),s=rt(t.get("textBaseline"),t.get("textVerticalAlign")),l=new Ns({style:$h(r,{text:t.get("text"),fill:r.getTextColor()},{disableBox:!0}),z2:10}),u=l.getBoundingRect(),h=t.get("subtext"),c=new Ns({style:$h(o,{text:h,fill:o.getTextColor(),y:u.height+t.get("itemGap"),verticalAlign:"top"},{disableBox:!0}),z2:10}),p=t.get("link"),d=t.get("sublink"),f=t.get("triggerEvent",!0);l.silent=!p&&!f,c.silent=!d&&!f,p&&l.on("click",(function(){yp(p,"_"+t.get("target"))})),d&&c.on("click",(function(){yp(d,"_"+t.get("subtarget"))})),js(l).eventData=js(c).eventData=f?{componentType:"title",componentIndex:t.componentIndex}:null,i.add(l),h&&i.add(c);var g=i.getBoundingRect(),y=t.getBoxLayoutParams();y.width=g.width,y.height=g.height;var v=wp(y,{width:n.getWidth(),height:n.getHeight()},t.get("padding"));a||("middle"===(a=t.get("left")||t.get("right"))&&(a="center"),"right"===a?v.x+=v.width:"center"===a&&(v.x+=v.width/2)),s||("center"===(s=t.get("top")||t.get("bottom"))&&(s="middle"),"bottom"===s?v.y+=v.height:"middle"===s&&(v.y+=v.height/2),s=s||"top"),i.x=v.x,i.y=v.y,i.markRedraw();var m={align:a,verticalAlign:s};l.setStyle(m),c.setStyle(m),g=i.getBoundingRect();var x=v.margin,_=t.getItemStyle(["color","opacity"]);_.fill=t.get("backgroundColor");var b=new Ps({shape:{x:g.x-x[3],y:g.y-x[0],width:g.width+x[1]+x[3],height:g.height+x[0]+x[2],r:t.get("borderRadius")},style:_,subPixelOptimize:!0,silent:!0});i.add(b)}},e.type="title",e}(mg);var CV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.layoutMode="box",n}return n(e,t),e.prototype.init=function(t,e,n){this.mergeDefaultAndTheme(t,n),this._initData()},e.prototype.mergeOption=function(e){t.prototype.mergeOption.apply(this,arguments),this._initData()},e.prototype.setCurrentIndex=function(t){null==t&&(t=this.option.currentIndex);var e=this._data.count();this.option.loop?t=(t%e+e)%e:(t>=e&&(t=e-1),t<0&&(t=0)),this.option.currentIndex=t},e.prototype.getCurrentIndex=function(){return this.option.currentIndex},e.prototype.isIndexMax=function(){return this.getCurrentIndex()>=this._data.count()-1},e.prototype.setPlayState=function(t){this.option.autoPlay=!!t},e.prototype.getPlayState=function(){return!!this.option.autoPlay},e.prototype._initData=function(){var t,e=this.option,n=e.data||[],i=e.axisType,r=this._names=[];"category"===i?(t=[],E(n,(function(e,n){var i,o=Mo(xo(e),"");q(e)?(i=T(e)).value=n:i=n,t.push(i),r.push(o)}))):t=n;var o={category:"ordinal",time:"time",value:"number"}[i]||"number";(this._data=new Jm([{name:"value",type:o}],this)).initData(t,r)},e.prototype.getData=function(){return this._data},e.prototype.getCategories=function(){if("category"===this.get("axisType"))return this._names.slice()},e.type="timeline",e.defaultOption={z:4,show:!0,axisType:"time",realtime:!0,left:"20%",top:null,right:"20%",bottom:0,width:null,height:40,padding:5,controlPosition:"left",autoPlay:!1,rewind:!1,loop:!0,playInterval:2e3,currentIndex:0,itemStyle:{},label:{color:"#000"},data:[]},e}(Ap),DV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="timeline.slider",e.defaultOption=wc(CV.defaultOption,{backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderWidth:0,orient:"horizontal",inverse:!1,tooltip:{trigger:"item"},symbol:"circle",symbolSize:12,lineStyle:{show:!0,width:2,color:"#DAE1F5"},label:{position:"auto",show:!0,interval:"auto",rotate:0,color:"#A4B1D7"},itemStyle:{color:"#A4B1D7",borderWidth:1},checkpointStyle:{symbol:"circle",symbolSize:15,color:"#316bf3",borderColor:"#fff",borderWidth:2,shadowBlur:2,shadowOffsetX:1,shadowOffsetY:1,shadowColor:"rgba(0, 0, 0, 0.3)",animation:!0,animationDuration:300,animationEasing:"quinticInOut"},controlStyle:{show:!0,showPlayBtn:!0,showPrevBtn:!0,showNextBtn:!0,itemSize:24,itemGap:12,position:"left",playIcon:"path://M31.6,53C17.5,53,6,41.5,6,27.4S17.5,1.8,31.6,1.8C45.7,1.8,57.2,13.3,57.2,27.4S45.7,53,31.6,53z M31.6,3.3 C18.4,3.3,7.5,14.1,7.5,27.4c0,13.3,10.8,24.1,24.1,24.1C44.9,51.5,55.7,40.7,55.7,27.4C55.7,14.1,44.9,3.3,31.6,3.3z M24.9,21.3 c0-2.2,1.6-3.1,3.5-2l10.5,6.1c1.899,1.1,1.899,2.9,0,4l-10.5,6.1c-1.9,1.1-3.5,0.2-3.5-2V21.3z",stopIcon:"path://M30.9,53.2C16.8,53.2,5.3,41.7,5.3,27.6S16.8,2,30.9,2C45,2,56.4,13.5,56.4,27.6S45,53.2,30.9,53.2z M30.9,3.5C17.6,3.5,6.8,14.4,6.8,27.6c0,13.3,10.8,24.1,24.101,24.1C44.2,51.7,55,40.9,55,27.6C54.9,14.4,44.1,3.5,30.9,3.5z M36.9,35.8c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H36c0.5,0,0.9,0.4,0.9,1V35.8z M27.8,35.8 c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H27c0.5,0,0.9,0.4,0.9,1L27.8,35.8L27.8,35.8z",nextIcon:"M2,18.5A1.52,1.52,0,0,1,.92,18a1.49,1.49,0,0,1,0-2.12L7.81,9.36,1,3.11A1.5,1.5,0,1,1,3,.89l8,7.34a1.48,1.48,0,0,1,.49,1.09,1.51,1.51,0,0,1-.46,1.1L3,18.08A1.5,1.5,0,0,1,2,18.5Z",prevIcon:"M10,.5A1.52,1.52,0,0,1,11.08,1a1.49,1.49,0,0,1,0,2.12L4.19,9.64,11,15.89a1.5,1.5,0,1,1-2,2.22L1,10.77A1.48,1.48,0,0,1,.5,9.68,1.51,1.51,0,0,1,1,8.58L9,.92A1.5,1.5,0,0,1,10,.5Z",prevBtnSize:18,nextBtnSize:18,color:"#A4B1D7",borderColor:"#A4B1D7",borderWidth:1},emphasis:{label:{show:!0,color:"#6f778d"},itemStyle:{color:"#316BF3"},controlStyle:{color:"#316BF3",borderColor:"#316BF3",borderWidth:2}},progress:{lineStyle:{color:"#316BF3"},itemStyle:{color:"#316BF3"},label:{color:"#6f778d"}},data:[]}),e}(CV);R(DV,cf.prototype);var AV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="timeline",e}(mg),kV=function(t){function e(e,n,i,r){var o=t.call(this,e,n,i)||this;return o.type=r||"value",o}return n(e,t),e.prototype.getLabelModel=function(){return this.model.getModel("label")},e.prototype.isHorizontal=function(){return"horizontal"===this.model.get("orient")},e}(X_),LV=Math.PI,PV=Do(),OV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.init=function(t,e){this.api=e},e.prototype.render=function(t,e,n){if(this.model=t,this.api=n,this.ecModel=e,this.group.removeAll(),t.get("show",!0)){var i=this._layout(t,n),r=this._createGroup("_mainGroup"),o=this._createGroup("_labelGroup"),a=this._axis=this._createAxis(i,t);t.formatTooltip=function(t){return qf("nameValue",{noName:!0,value:a.scale.getLabel({value:t})})},E(["AxisLine","AxisTick","Control","CurrentPointer"],(function(e){this["_render"+e](i,r,a,t)}),this),this._renderAxisLabel(i,o,a,t),this._position(i,t)}this._doPlayStop(),this._updateTicksStatus()},e.prototype.remove=function(){this._clearTimer(),this.group.removeAll()},e.prototype.dispose=function(){this._clearTimer()},e.prototype._layout=function(t,e){var n,i,r,o,a=t.get(["label","position"]),s=t.get("orient"),l=function(t,e){return wp(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()},t.get("padding"))}(t,e),u={horizontal:"center",vertical:(n=null==a||"auto"===a?"horizontal"===s?l.y+l.height/2=0||"+"===n?"left":"right"},h={horizontal:n>=0||"+"===n?"top":"bottom",vertical:"middle"},c={horizontal:0,vertical:LV/2},p="vertical"===s?l.height:l.width,d=t.getModel("controlStyle"),f=d.get("show",!0),g=f?d.get("itemSize"):0,y=f?d.get("itemGap"):0,v=g+y,m=t.get(["label","rotate"])||0;m=m*LV/180;var x=d.get("position",!0),_=f&&d.get("showPlayBtn",!0),b=f&&d.get("showPrevBtn",!0),w=f&&d.get("showNextBtn",!0),S=0,M=p;"left"===x||"bottom"===x?(_&&(i=[0,0],S+=v),b&&(r=[S,0],S+=v),w&&(o=[M-g,0],M-=v)):(_&&(i=[M-g,0],M-=v),b&&(r=[0,0],S+=v),w&&(o=[M-g,0],M-=v));var I=[S,M];return t.get("inverse")&&I.reverse(),{viewRect:l,mainLength:p,orient:s,rotation:c[s],labelRotation:m,labelPosOpt:n,labelAlign:t.get(["label","align"])||u[s],labelBaseline:t.get(["label","verticalAlign"])||t.get(["label","baseline"])||h[s],playPosition:i,prevBtnPosition:r,nextBtnPosition:o,axisExtent:I,controlSize:g,controlGap:y}},e.prototype._position=function(t,e){var n=this._mainGroup,i=this._labelGroup,r=t.viewRect;if("vertical"===t.orient){var o=[1,0,0,1,0,0],a=r.x,s=r.y+r.height;xe(o,o,[-a,-s]),_e(o,o,-LV/2),xe(o,o,[a,s]),(r=r.clone()).applyTransform(o)}var l=y(r),u=y(n.getBoundingRect()),h=y(i.getBoundingRect()),c=[n.x,n.y],p=[i.x,i.y];p[0]=c[0]=l[0][0];var d,f=t.labelPosOpt;null==f||X(f)?(v(c,u,l,1,d="+"===f?0:1),v(p,h,l,1,1-d)):(v(c,u,l,1,d=f>=0?0:1),p[1]=c[1]+f);function g(t){t.originX=l[0][0]-t.x,t.originY=l[1][0]-t.y}function y(t){return[[t.x,t.x+t.width],[t.y,t.y+t.height]]}function v(t,e,n,i,r){t[i]+=n[i][r]-e[i][r]}n.setPosition(c),i.setPosition(p),n.rotation=i.rotation=t.rotation,g(n),g(i)},e.prototype._createAxis=function(t,e){var n=e.getData(),i=e.get("axisType"),r=function(t,e){if(e=e||t.get("type"))switch(e){case"category":return new _x({ordinalMeta:t.getCategories(),extent:[1/0,-1/0]});case"time":return new zx({locale:t.ecModel.getLocaleModel(),useUTC:t.ecModel.get("useUTC")});default:return new Sx}}(e,i);r.getTicks=function(){return n.mapArray(["value"],(function(t){return{value:t}}))};var o=n.getDataExtent("value");r.setExtent(o[0],o[1]),r.calcNiceTicks();var a=new kV("value",r,t.axisExtent,i);return a.model=e,a},e.prototype._createGroup=function(t){var e=this[t]=new Pr;return this.group.add(e),e},e.prototype._renderAxisLine=function(t,e,n,i){var r=n.getExtent();if(i.get(["lineStyle","show"])){var o=new Wu({shape:{x1:r[0],y1:0,x2:r[1],y2:0},style:A({lineCap:"round"},i.getModel("lineStyle").getLineStyle()),silent:!0,z2:1});e.add(o);var a=this._progressLine=new Wu({shape:{x1:r[0],x2:this._currentPointer?this._currentPointer.x:r[0],y1:0,y2:0},style:k({lineCap:"round",lineWidth:o.style.lineWidth},i.getModel(["progress","lineStyle"]).getLineStyle()),silent:!0,z2:1});e.add(a)}},e.prototype._renderAxisTick=function(t,e,n,i){var r=this,o=i.getData(),a=n.scale.getTicks();this._tickSymbols=[],E(a,(function(t){var a=n.dataToCoord(t.value),s=o.getItemModel(t.value),l=s.getModel("itemStyle"),u=s.getModel(["emphasis","itemStyle"]),h=s.getModel(["progress","itemStyle"]),c={x:a,y:0,onclick:W(r._changeTimeline,r,t.value)},p=RV(s,l,e,c);p.ensureState("emphasis").style=u.getItemStyle(),p.ensureState("progress").style=h.getItemStyle(),Vl(p);var d=js(p);s.get("tooltip")?(d.dataIndex=t.value,d.dataModel=i):d.dataIndex=d.dataModel=null,r._tickSymbols.push(p)}))},e.prototype._renderAxisLabel=function(t,e,n,i){var r=this;if(n.getLabelModel().get("show")){var o=i.getData(),a=n.getViewLabels();this._tickLabels=[],E(a,(function(i){var a=i.tickValue,s=o.getItemModel(a),l=s.getModel("label"),u=s.getModel(["emphasis","label"]),h=s.getModel(["progress","label"]),c=n.dataToCoord(i.tickValue),p=new Ns({x:c,y:0,rotation:t.labelRotation-t.rotation,onclick:W(r._changeTimeline,r,a),silent:!1,style:$h(l,{text:i.formattedLabel,align:t.labelAlign,verticalAlign:t.labelBaseline})});p.ensureState("emphasis").style=$h(u),p.ensureState("progress").style=$h(h),e.add(p),Vl(p),PV(p).dataIndex=a,r._tickLabels.push(p)}))}},e.prototype._renderControl=function(t,e,n,i){var r=t.controlSize,o=t.rotation,a=i.getModel("controlStyle").getItemStyle(),s=i.getModel(["emphasis","controlStyle"]).getItemStyle(),l=i.getPlayState(),u=i.get("inverse",!0);function h(t,n,l,u){if(t){var h=_r(rt(i.get(["controlStyle",n+"BtnSize"]),r),r),c=function(t,e,n,i){var r=i.style,o=Vh(t.get(["controlStyle",e]),i||{},new Re(n[0],n[1],n[2],n[3]));r&&o.setStyle(r);return o}(i,n+"Icon",[0,-h/2,h,h],{x:t[0],y:t[1],originX:r/2,originY:0,rotation:u?-o:0,rectHover:!0,style:a,onclick:l});c.ensureState("emphasis").style=s,e.add(c),Vl(c)}}h(t.nextBtnPosition,"next",W(this._changeTimeline,this,u?"-":"+")),h(t.prevBtnPosition,"prev",W(this._changeTimeline,this,u?"+":"-")),h(t.playPosition,l?"stop":"play",W(this._handlePlayClick,this,!l),!0)},e.prototype._renderCurrentPointer=function(t,e,n,i){var r=i.getData(),o=i.getCurrentIndex(),a=r.getItemModel(o).getModel("checkpointStyle"),s=this,l={onCreate:function(t){t.draggable=!0,t.drift=W(s._handlePointerDrag,s),t.ondragend=W(s._handlePointerDragend,s),NV(t,s._progressLine,o,n,i,!0)},onUpdate:function(t){NV(t,s._progressLine,o,n,i)}};this._currentPointer=RV(a,a,this._mainGroup,{},this._currentPointer,l)},e.prototype._handlePlayClick=function(t){this._clearTimer(),this.api.dispatchAction({type:"timelinePlayChange",playState:t,from:this.uid})},e.prototype._handlePointerDrag=function(t,e,n){this._clearTimer(),this._pointerChangeTimeline([n.offsetX,n.offsetY])},e.prototype._handlePointerDragend=function(t){this._pointerChangeTimeline([t.offsetX,t.offsetY],!0)},e.prototype._pointerChangeTimeline=function(t,e){var n=this._toAxisCoord(t)[0],i=Hr(this._axis.getExtent().slice());n>i[1]&&(n=i[1]),n=0&&(a[o]=+a[o].toFixed(c)),[a,h]}var XV={min:H(UV,"min"),max:H(UV,"max"),average:H(UV,"average"),median:H(UV,"median")};function ZV(t,e){var n=t.getData(),i=t.coordinateSystem;if(e&&!function(t){return!isNaN(parseFloat(t.x))&&!isNaN(parseFloat(t.y))}(e)&&!Y(e.coord)&&i){var r=i.dimensions,o=jV(e,n,i,t);if((e=T(e)).type&&XV[e.type]&&o.baseAxis&&o.valueAxis){var a=P(r,o.baseAxis.dim),s=P(r,o.valueAxis.dim),l=XV[e.type](n,o.baseDataDim,o.valueDataDim,a,s);e.coord=l[0],e.value=l[1]}else{for(var u=[null!=e.xAxis?e.xAxis:e.radiusAxis,null!=e.yAxis?e.yAxis:e.angleAxis],h=0;h<2;h++)XV[u[h]]&&(u[h]=$V(n,n.mapDimension(r[h]),u[h]));e.coord=u}}return e}function jV(t,e,n,i){var r={};return null!=t.valueIndex||null!=t.valueDim?(r.valueDataDim=null!=t.valueIndex?e.getDimension(t.valueIndex):t.valueDim,r.valueAxis=n.getAxis(function(t,e){var n=t.getData().getDimensionInfo(e);return n&&n.coordDim}(i,r.valueDataDim)),r.baseAxis=n.getOtherAxis(r.valueAxis),r.baseDataDim=e.mapDimension(r.baseAxis.dim)):(r.baseAxis=i.getBaseAxis(),r.valueAxis=n.getOtherAxis(r.baseAxis),r.baseDataDim=e.mapDimension(r.baseAxis.dim),r.valueDataDim=e.mapDimension(r.valueAxis.dim)),r}function qV(t,e){return!(t&&t.containData&&e.coord&&!YV(e))||t.containData(e.coord)}function KV(t,e){return t?function(t,n,i,r){return yf(r<2?t.coord&&t.coord[r]:t.value,e[r])}:function(t,n,i,r){return yf(t.value,e[r])}}function $V(t,e,n){if("average"===n){var i=0,r=0;return t.each(e,(function(t,e){isNaN(t)||(i+=t,r++)})),i/r}return"median"===n?t.getMedian(e):t.getDataExtent(e)["max"===n?1:0]}var JV=Do(),QV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.init=function(){this.markerGroupMap=ft()},e.prototype.render=function(t,e,n){var i=this,r=this.markerGroupMap;r.each((function(t){JV(t).keep=!1})),e.eachSeries((function(t){var r=WV.getMarkerModelFromSeries(t,i.type);r&&i.renderSeries(t,r,e,n)})),r.each((function(t){!JV(t).keep&&i.group.remove(t.group)}))},e.prototype.markKeep=function(t){JV(t).keep=!0},e.prototype.toggleBlurSeries=function(t,e){var n=this;E(t,(function(t){var i=WV.getMarkerModelFromSeries(t,n.type);i&&i.getData().eachItemGraphicEl((function(t){t&&(e?Cl(t):Dl(t))}))}))},e.type="marker",e}(mg);function tB(t,e,n){var i=e.coordinateSystem;t.each((function(r){var o,a=t.getItemModel(r),s=Gr(a.get("x"),n.getWidth()),l=Gr(a.get("y"),n.getHeight());if(isNaN(s)||isNaN(l)){if(e.getMarkerPosition)o=e.getMarkerPosition(t.getValues(t.dimensions,r));else if(i){var u=t.get(i.dimensions[0],r),h=t.get(i.dimensions[1],r);o=i.dataToPoint([u,h])}}else o=[s,l];isNaN(s)||(o[0]=s),isNaN(l)||(o[1]=l),t.setItemLayout(r,o)}))}var eB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.updateTransform=function(t,e,n){e.eachSeries((function(t){var e=WV.getMarkerModelFromSeries(t,"markPoint");e&&(tB(e.getData(),t,n),this.markerGroupMap.get(t.id).updateLayout())}),this)},e.prototype.renderSeries=function(t,e,n,i){var r=t.coordinateSystem,o=t.id,a=t.getData(),s=this.markerGroupMap,l=s.get(o)||s.set(o,new Jw),u=function(t,e,n){var i;i=t?z(t&&t.dimensions,(function(t){return A(A({},e.getData().getDimensionInfo(e.getData().mapDimension(t))||{}),{name:t,ordinalMeta:null})})):[{name:"value",type:"float"}];var r=new Jm(i,n),o=z(n.get("data"),H(ZV,e));t&&(o=B(o,H(qV,t)));var a=KV(!!t,i);return r.initData(o,null,a),r}(r,t,e);e.setData(u),tB(e.getData(),t,i),u.each((function(t){var n=u.getItemModel(t),i=n.getShallow("symbol"),r=n.getShallow("symbolSize"),o=n.getShallow("symbolRotate"),s=n.getShallow("symbolOffset"),l=n.getShallow("symbolKeepAspect");if(U(i)||U(r)||U(o)||U(s)){var h=e.getRawValue(t),c=e.getDataParams(t);U(i)&&(i=i(h,c)),U(r)&&(r=r(h,c)),U(o)&&(o=o(h,c)),U(s)&&(s=s(h,c))}var p=n.getModel("itemStyle").getItemStyle(),d=my(a,"color");p.fill||(p.fill=d),u.setItemVisual(t,{symbol:i,symbolSize:r,symbolRotate:o,symbolOffset:s,symbolKeepAspect:l,style:p})})),l.updateData(u),this.group.add(l.group),u.eachItemGraphicEl((function(t){t.traverse((function(t){js(t).dataModel=e}))})),this.markKeep(l),l.group.silent=e.get("silent")||t.get("silent")},e.type="markPoint",e}(QV);var nB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.createMarkerModelFromSeries=function(t,n,i){return new e(t,n,i)},e.type="markLine",e.defaultOption={z:5,symbol:["circle","arrow"],symbolSize:[8,16],symbolOffset:0,precision:2,tooltip:{trigger:"item"},label:{show:!0,position:"end",distance:5},lineStyle:{type:"dashed"},emphasis:{label:{show:!0},lineStyle:{width:3}},animationEasing:"linear"},e}(WV),iB=Do(),rB=function(t,e,n,i){var r,o=t.getData();if(Y(i))r=i;else{var a=i.type;if("min"===a||"max"===a||"average"===a||"median"===a||null!=i.xAxis||null!=i.yAxis){var s=void 0,l=void 0;if(null!=i.yAxis||null!=i.xAxis)s=e.getAxis(null!=i.yAxis?"y":"x"),l=it(i.yAxis,i.xAxis);else{var u=jV(i,o,e,t);s=u.valueAxis,l=$V(o,ax(o,u.valueDataDim),a)}var h="x"===s.dim?0:1,c=1-h,p=T(i),d={coord:[]};p.type=null,p.coord=[],p.coord[c]=-1/0,d.coord[c]=1/0;var f=n.get("precision");f>=0&&j(l)&&(l=+l.toFixed(Math.min(f,20))),p.coord[h]=d.coord[h]=l,r=[p,d,{type:a,valueIndex:i.valueIndex,value:l}]}else r=[]}var g=[ZV(t,r[0]),ZV(t,r[1]),A({},r[2])];return g[2].type=g[2].type||null,C(g[2],g[0]),C(g[2],g[1]),g};function oB(t){return!isNaN(t)&&!isFinite(t)}function aB(t,e,n,i){var r=1-t,o=i.dimensions[t];return oB(e[r])&&oB(n[r])&&e[t]===n[t]&&i.getAxis(o).containData(e[t])}function sB(t,e){if("cartesian2d"===t.type){var n=e[0].coord,i=e[1].coord;if(n&&i&&(aB(1,n,i,t)||aB(0,n,i,t)))return!0}return qV(t,e[0])&&qV(t,e[1])}function lB(t,e,n,i,r){var o,a=i.coordinateSystem,s=t.getItemModel(e),l=Gr(s.get("x"),r.getWidth()),u=Gr(s.get("y"),r.getHeight());if(isNaN(l)||isNaN(u)){if(i.getMarkerPosition)o=i.getMarkerPosition(t.getValues(t.dimensions,e));else{var h=a.dimensions,c=t.get(h[0],e),p=t.get(h[1],e);o=a.dataToPoint([c,p])}if(pS(a,"cartesian2d")){var d=a.getAxis("x"),f=a.getAxis("y");h=a.dimensions;oB(t.get(h[0],e))?o[0]=d.toGlobalCoord(d.getExtent()[n?0:1]):oB(t.get(h[1],e))&&(o[1]=f.toGlobalCoord(f.getExtent()[n?0:1]))}isNaN(l)||(o[0]=l),isNaN(u)||(o[1]=u)}else o=[l,u];t.setItemLayout(e,o)}var uB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.updateTransform=function(t,e,n){e.eachSeries((function(t){var e=WV.getMarkerModelFromSeries(t,"markLine");if(e){var i=e.getData(),r=iB(e).from,o=iB(e).to;r.each((function(e){lB(r,e,!0,t,n),lB(o,e,!1,t,n)})),i.each((function(t){i.setItemLayout(t,[r.getItemLayout(t),o.getItemLayout(t)])})),this.markerGroupMap.get(t.id).updateLayout()}}),this)},e.prototype.renderSeries=function(t,e,n,i){var r=t.coordinateSystem,o=t.id,a=t.getData(),s=this.markerGroupMap,l=s.get(o)||s.set(o,new _A);this.group.add(l.group);var u=function(t,e,n){var i;i=t?z(t&&t.dimensions,(function(t){return A(A({},e.getData().getDimensionInfo(e.getData().mapDimension(t))||{}),{name:t,ordinalMeta:null})})):[{name:"value",type:"float"}];var r=new Jm(i,n),o=new Jm(i,n),a=new Jm([],n),s=z(n.get("data"),H(rB,e,t,n));t&&(s=B(s,H(sB,t)));var l=KV(!!t,i);return r.initData(z(s,(function(t){return t[0]})),null,l),o.initData(z(s,(function(t){return t[1]})),null,l),a.initData(z(s,(function(t){return t[2]}))),a.hasItemOption=!0,{from:r,to:o,line:a}}(r,t,e),h=u.from,c=u.to,p=u.line;iB(e).from=h,iB(e).to=c,e.setData(p);var d=e.get("symbol"),f=e.get("symbolSize"),g=e.get("symbolRotate"),y=e.get("symbolOffset");function v(e,n,r){var o=e.getItemModel(n);lB(e,n,r,t,i);var s=o.getModel("itemStyle").getItemStyle();null==s.fill&&(s.fill=my(a,"color")),e.setItemVisual(n,{symbolKeepAspect:o.get("symbolKeepAspect"),symbolOffset:rt(o.get("symbolOffset",!0),y[r?0:1]),symbolRotate:rt(o.get("symbolRotate",!0),g[r?0:1]),symbolSize:rt(o.get("symbolSize"),f[r?0:1]),symbol:rt(o.get("symbol",!0),d[r?0:1]),style:s})}Y(d)||(d=[d,d]),Y(f)||(f=[f,f]),Y(g)||(g=[g,g]),Y(y)||(y=[y,y]),u.from.each((function(t){v(h,t,!0),v(c,t,!1)})),p.each((function(t){var e=p.getItemModel(t).getModel("lineStyle").getLineStyle();p.setItemLayout(t,[h.getItemLayout(t),c.getItemLayout(t)]),null==e.stroke&&(e.stroke=h.getItemVisual(t,"style").fill),p.setItemVisual(t,{fromSymbolKeepAspect:h.getItemVisual(t,"symbolKeepAspect"),fromSymbolOffset:h.getItemVisual(t,"symbolOffset"),fromSymbolRotate:h.getItemVisual(t,"symbolRotate"),fromSymbolSize:h.getItemVisual(t,"symbolSize"),fromSymbol:h.getItemVisual(t,"symbol"),toSymbolKeepAspect:c.getItemVisual(t,"symbolKeepAspect"),toSymbolOffset:c.getItemVisual(t,"symbolOffset"),toSymbolRotate:c.getItemVisual(t,"symbolRotate"),toSymbolSize:c.getItemVisual(t,"symbolSize"),toSymbol:c.getItemVisual(t,"symbol"),style:e})})),l.updateData(p),u.line.eachItemGraphicEl((function(t){js(t).dataModel=e,t.traverse((function(t){js(t).dataModel=e}))})),this.markKeep(l),l.group.silent=e.get("silent")||t.get("silent")},e.type="markLine",e}(QV);var hB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.createMarkerModelFromSeries=function(t,n,i){return new e(t,n,i)},e.type="markArea",e.defaultOption={z:1,tooltip:{trigger:"item"},animation:!1,label:{show:!0,position:"top"},itemStyle:{borderWidth:0},emphasis:{label:{show:!0,position:"top"}}},e}(WV),cB=Do(),pB=function(t,e,n,i){var r=ZV(t,i[0]),o=ZV(t,i[1]),a=r.coord,s=o.coord;a[0]=it(a[0],-1/0),a[1]=it(a[1],-1/0),s[0]=it(s[0],1/0),s[1]=it(s[1],1/0);var l=D([{},r,o]);return l.coord=[r.coord,o.coord],l.x0=r.x,l.y0=r.y,l.x1=o.x,l.y1=o.y,l};function dB(t){return!isNaN(t)&&!isFinite(t)}function fB(t,e,n,i){var r=1-t;return dB(e[r])&&dB(n[r])}function gB(t,e){var n=e.coord[0],i=e.coord[1],r={coord:n,x:e.x0,y:e.y0},o={coord:i,x:e.x1,y:e.y1};return pS(t,"cartesian2d")?!(!n||!i||!fB(1,n,i)&&!fB(0,n,i))||function(t,e,n){return!(t&&t.containZone&&e.coord&&n.coord&&!YV(e)&&!YV(n))||t.containZone(e.coord,n.coord)}(t,r,o):qV(t,r)||qV(t,o)}function yB(t,e,n,i,r){var o,a=i.coordinateSystem,s=t.getItemModel(e),l=Gr(s.get(n[0]),r.getWidth()),u=Gr(s.get(n[1]),r.getHeight());if(isNaN(l)||isNaN(u)){if(i.getMarkerPosition)o=i.getMarkerPosition(t.getValues(n,e));else{var h=[d=t.get(n[0],e),f=t.get(n[1],e)];a.clampData&&a.clampData(h,h),o=a.dataToPoint(h,!0)}if(pS(a,"cartesian2d")){var c=a.getAxis("x"),p=a.getAxis("y"),d=t.get(n[0],e),f=t.get(n[1],e);dB(d)?o[0]=c.toGlobalCoord(c.getExtent()["x0"===n[0]?0:1]):dB(f)&&(o[1]=p.toGlobalCoord(p.getExtent()["y0"===n[1]?0:1]))}isNaN(l)||(o[0]=l),isNaN(u)||(o[1]=u)}else o=[l,u];return o}var vB=[["x0","y0"],["x1","y0"],["x1","y1"],["x0","y1"]],mB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.updateTransform=function(t,e,n){e.eachSeries((function(t){var e=WV.getMarkerModelFromSeries(t,"markArea");if(e){var i=e.getData();i.each((function(e){var r=z(vB,(function(r){return yB(i,e,r,t,n)}));i.setItemLayout(e,r),i.getItemGraphicEl(e).setShape("points",r)}))}}),this)},e.prototype.renderSeries=function(t,e,n,i){var r=t.coordinateSystem,o=t.id,a=t.getData(),s=this.markerGroupMap,l=s.get(o)||s.set(o,{group:new Pr});this.group.add(l.group),this.markKeep(l);var u=function(t,e,n){var i,r,o=["x0","y0","x1","y1"];if(t){var a=z(t&&t.dimensions,(function(t){var n=e.getData();return A(A({},n.getDimensionInfo(n.mapDimension(t))||{}),{name:t,ordinalMeta:null})}));r=z(o,(function(t,e){return{name:t,type:a[e%2].type}})),i=new Jm(r,n)}else i=new Jm(r=[{name:"value",type:"float"}],n);var s=z(n.get("data"),H(pB,e,t,n));t&&(s=B(s,H(gB,t)));var l=t?function(t,e,n,i){return yf(t.coord[Math.floor(i/2)][i%2],r[i])}:function(t,e,n,i){return yf(t.value,r[i])};return i.initData(s,null,l),i.hasItemOption=!0,i}(r,t,e);e.setData(u),u.each((function(e){var n=z(vB,(function(n){return yB(u,e,n,t,i)})),o=r.getAxis("x").scale,s=r.getAxis("y").scale,l=o.getExtent(),h=s.getExtent(),c=[o.parse(u.get("x0",e)),o.parse(u.get("x1",e))],p=[s.parse(u.get("y0",e)),s.parse(u.get("y1",e))];Hr(c),Hr(p);var d=!!(l[0]>c[1]||l[1]p[1]||h[1]=0},e.prototype.getOrient=function(){return"vertical"===this.get("orient")?{index:1,name:"vertical"}:{index:0,name:"horizontal"}},e.type="legend.plain",e.dependencies=["series"],e.defaultOption={z:4,show:!0,orient:"horizontal",left:"center",top:0,align:"auto",backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderRadius:0,borderWidth:0,padding:5,itemGap:10,itemWidth:25,itemHeight:14,symbolRotate:"inherit",symbolKeepAspect:!0,inactiveColor:"#ccc",inactiveBorderColor:"#ccc",inactiveBorderWidth:"auto",itemStyle:{color:"inherit",opacity:"inherit",borderColor:"inherit",borderWidth:"auto",borderCap:"inherit",borderJoin:"inherit",borderDashOffset:"inherit",borderMiterLimit:"inherit"},lineStyle:{width:"auto",color:"inherit",inactiveColor:"#ccc",inactiveWidth:2,opacity:"inherit",type:"inherit",cap:"inherit",join:"inherit",dashOffset:"inherit",miterLimit:"inherit"},textStyle:{color:"#333"},selectedMode:!0,selector:!1,selectorLabel:{show:!0,borderRadius:10,padding:[3,5,3,5],fontSize:12,fontFamily:"sans-serif",color:"#666",borderWidth:1,borderColor:"#666"},emphasis:{selectorLabel:{show:!0,color:"#eee",backgroundColor:"#666"}},selectorPosition:"auto",selectorItemGap:7,selectorButtonGap:10,tooltip:{show:!1}},e}(Ap),_B=H,bB=E,wB=Pr,SB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.newlineDisabled=!1,n}return n(e,t),e.prototype.init=function(){this.group.add(this._contentGroup=new wB),this.group.add(this._selectorGroup=new wB),this._isFirstRender=!0},e.prototype.getContentGroup=function(){return this._contentGroup},e.prototype.getSelectorGroup=function(){return this._selectorGroup},e.prototype.render=function(t,e,n){var i=this._isFirstRender;if(this._isFirstRender=!1,this.resetInner(),t.get("show",!0)){var r=t.get("align"),o=t.get("orient");r&&"auto"!==r||(r="right"===t.get("left")&&"vertical"===o?"right":"left");var a=t.get("selector",!0),s=t.get("selectorPosition",!0);!a||s&&"auto"!==s||(s="horizontal"===o?"end":"start"),this.renderInner(r,t,e,n,a,o,s);var l=t.getBoxLayoutParams(),u={width:n.getWidth(),height:n.getHeight()},h=t.get("padding"),c=wp(l,u,h),p=this.layoutInner(t,r,c,i,a,s),d=wp(k({width:p.width,height:p.height},l),u,h);this.group.x=d.x-p.x,this.group.y=d.y-p.y,this.group.markRedraw(),this.group.add(this._backgroundEl=JE(p,t))}},e.prototype.resetInner=function(){this.getContentGroup().removeAll(),this._backgroundEl&&this.group.remove(this._backgroundEl),this.getSelectorGroup().removeAll()},e.prototype.renderInner=function(t,e,n,i,r,o,a){var s=this.getContentGroup(),l=ft(),u=e.get("selectedMode"),h=[];n.eachRawSeries((function(t){!t.get("legendHoverLink")&&h.push(t.id)})),bB(e.getData(),(function(r,o){var a=r.get("name");if(!this.newlineDisabled&&(""===a||"\n"===a)){var c=new wB;return c.newline=!0,void s.add(c)}var p=n.getSeriesByName(a)[0];if(!l.get(a)){if(p){var d=p.getData(),f=d.getVisual("legendLineStyle")||{},g=d.getVisual("legendIcon"),y=d.getVisual("style");this._createItem(p,a,o,r,e,t,f,y,g,u,i).on("click",_B(MB,a,null,i,h)).on("mouseover",_B(TB,p.name,null,i,h)).on("mouseout",_B(CB,p.name,null,i,h)),l.set(a,!0)}else n.eachRawSeries((function(n){if(!l.get(a)&&n.legendVisualProvider){var s=n.legendVisualProvider;if(!s.containName(a))return;var c=s.indexOfName(a),p=s.getItemVisual(c,"style"),d=s.getItemVisual(c,"legendIcon"),f=Xn(p.fill);f&&0===f[3]&&(f[3]=.2,p=A(A({},p),{fill:ei(f,"rgba")})),this._createItem(n,a,o,r,e,t,{},p,d,u,i).on("click",_B(MB,null,a,i,h)).on("mouseover",_B(TB,null,a,i,h)).on("mouseout",_B(CB,null,a,i,h)),l.set(a,!0)}}),this);0}}),this),r&&this._createSelector(r,e,i,o,a)},e.prototype._createSelector=function(t,e,n,i,r){var o=this.getSelectorGroup();bB(t,(function(t){var i=t.type,r=new Ns({style:{x:0,y:0,align:"center",verticalAlign:"middle"},onclick:function(){n.dispatchAction({type:"all"===i?"legendAllSelect":"legendInverseSelect"})}});o.add(r),qh(r,{normal:e.getModel("selectorLabel"),emphasis:e.getModel(["emphasis","selectorLabel"])},{defaultText:t.title}),Vl(r)}))},e.prototype._createItem=function(t,e,n,i,r,o,a,s,l,u,h){var c=t.visualDrawType,p=r.get("itemWidth"),d=r.get("itemHeight"),f=r.isSelected(e),g=i.get("symbolRotate"),y=i.get("symbolKeepAspect"),v=i.get("icon"),m=function(t,e,n,i,r,o,a){function s(t,e){"auto"===t.lineWidth&&(t.lineWidth=e.lineWidth>0?2:0),bB(t,(function(n,i){"inherit"===t[i]&&(t[i]=e[i])}))}var l=e.getModel("itemStyle"),u=l.getItemStyle(),h=0===t.lastIndexOf("empty",0)?"fill":"stroke",c=l.getShallow("decal");u.decal=c&&"inherit"!==c?sv(c,a):i.decal,"inherit"===u.fill&&(u.fill=i[r]);"inherit"===u.stroke&&(u.stroke=i[h]);"inherit"===u.opacity&&(u.opacity=("fill"===r?i:n).opacity);s(u,i);var p=e.getModel("lineStyle"),d=p.getLineStyle();if(s(d,n),"auto"===u.fill&&(u.fill=i.fill),"auto"===u.stroke&&(u.stroke=i.fill),"auto"===d.stroke&&(d.stroke=i.fill),!o){var f=e.get("inactiveBorderWidth"),g=u[h];u.lineWidth="auto"===f?i.lineWidth>0&&g?2:0:u.lineWidth,u.fill=e.get("inactiveColor"),u.stroke=e.get("inactiveBorderColor"),d.stroke=p.get("inactiveColor"),d.lineWidth=p.get("inactiveWidth")}return{itemStyle:u,lineStyle:d}}(l=v||l||"roundRect",i,a,s,c,f,h),x=new wB,_=i.getModel("textStyle");if(!U(t.getLegendIcon)||v&&"inherit"!==v){var b="inherit"===v&&t.getData().getVisual("symbol")?"inherit"===g?t.getData().getVisual("symbolRotate"):g:0;x.add(function(t){var e=t.icon||"roundRect",n=Ry(e,0,0,t.itemWidth,t.itemHeight,t.itemStyle.fill,t.symbolKeepAspect);n.setStyle(t.itemStyle),n.rotation=(t.iconRotate||0)*Math.PI/180,n.setOrigin([t.itemWidth/2,t.itemHeight/2]),e.indexOf("empty")>-1&&(n.style.stroke=n.style.fill,n.style.fill="#fff",n.style.lineWidth=2);return n}({itemWidth:p,itemHeight:d,icon:l,iconRotate:b,itemStyle:m.itemStyle,lineStyle:m.lineStyle,symbolKeepAspect:y}))}else x.add(t.getLegendIcon({itemWidth:p,itemHeight:d,icon:l,iconRotate:g,itemStyle:m.itemStyle,lineStyle:m.lineStyle,symbolKeepAspect:y}));var w="left"===o?p+5:-5,S=o,M=r.get("formatter"),I=e;X(M)&&M?I=M.replace("{name}",null!=e?e:""):U(M)&&(I=M(e));var T=i.get("inactiveColor");x.add(new Ns({style:$h(_,{text:I,x:w,y:d/2,fill:f?_.getTextColor():T,align:S,verticalAlign:"middle"})}));var C=new Ps({shape:x.getBoundingRect(),invisible:!0}),D=i.getModel("tooltip");return D.get("show")&&Wh({el:C,componentModel:r,itemName:e,itemTooltipOption:D.option}),x.add(C),x.eachChild((function(t){t.silent=!0})),C.silent=!u,this.getContentGroup().add(x),Vl(x),x.__legendDataIndex=n,x},e.prototype.layoutInner=function(t,e,n,i,r,o){var a=this.getContentGroup(),s=this.getSelectorGroup();bp(t.get("orient"),a,t.get("itemGap"),n.width,n.height);var l=a.getBoundingRect(),u=[-l.x,-l.y];if(s.markRedraw(),a.markRedraw(),r){bp("horizontal",s,t.get("selectorItemGap",!0));var h=s.getBoundingRect(),c=[-h.x,-h.y],p=t.get("selectorButtonGap",!0),d=t.getOrient().index,f=0===d?"width":"height",g=0===d?"height":"width",y=0===d?"y":"x";"end"===o?c[d]+=l[f]+p:u[d]+=h[f]+p,c[1-d]+=l[g]/2-h[g]/2,s.x=c[0],s.y=c[1],a.x=u[0],a.y=u[1];var v={x:0,y:0};return v[f]=l[f]+p+h[f],v[g]=Math.max(l[g],h[g]),v[y]=Math.min(0,h[y]+c[1-d]),v}return a.x=u[0],a.y=u[1],this.group.getBoundingRect()},e.prototype.remove=function(){this.getContentGroup().removeAll(),this._isFirstRender=!0},e.type="legend.plain",e}(mg);function MB(t,e,n,i){CB(t,e,n,i),n.dispatchAction({type:"legendToggleSelect",name:null!=t?t:e}),TB(t,e,n,i)}function IB(t){for(var e,n=t.getZr().storage.getDisplayList(),i=0,r=n.length;in[r],f=[-c.x,-c.y];e||(f[i]=l[s]);var g=[0,0],y=[-p.x,-p.y],v=rt(t.get("pageButtonGap",!0),t.get("itemGap",!0));d&&("end"===t.get("pageButtonPosition",!0)?y[i]+=n[r]-p[r]:g[i]+=p[r]+v);y[1-i]+=c[o]/2-p[o]/2,l.setPosition(f),u.setPosition(g),h.setPosition(y);var m={x:0,y:0};if(m[r]=d?n[r]:c[r],m[o]=Math.max(c[o],p[o]),m[a]=Math.min(0,p[a]+y[1-i]),u.__rectSize=n[r],d){var x={x:0,y:0};x[r]=Math.max(n[r]-p[r]-v,0),x[o]=m[o],u.setClipPath(new Ps({shape:x})),u.__rectSize=x[r]}else h.eachChild((function(t){t.attr({invisible:!0,silent:!0})}));var _=this._getPageInfo(t);return null!=_.pageIndex&&uh(l,{x:_.contentPosition[0],y:_.contentPosition[1]},d?t:null),this._updatePageInfoView(t,_),m},e.prototype._pageGo=function(t,e,n){var i=this._getPageInfo(e)[t];null!=i&&n.dispatchAction({type:"legendScroll",scrollDataIndex:i,legendId:e.id})},e.prototype._updatePageInfoView=function(t,e){var n=this._controllerGroup;E(["pagePrev","pageNext"],(function(i){var r=null!=e[i+"DataIndex"],o=n.childOfName(i);o&&(o.setStyle("fill",r?t.get("pageIconColor",!0):t.get("pageIconInactiveColor",!0)),o.cursor=r?"pointer":"default")}));var i=n.childOfName("pageText"),r=t.get("pageFormatter"),o=e.pageIndex,a=null!=o?o+1:0,s=e.pageCount;i&&r&&i.setStyle("text",X(r)?r.replace("{current}",null==a?"":a+"").replace("{total}",null==s?"":s+""):r({current:a,total:s}))},e.prototype._getPageInfo=function(t){var e=t.get("scrollDataIndex",!0),n=this.getContentGroup(),i=this._containerGroup.__rectSize,r=t.getOrient().index,o=RB[r],a=NB[r],s=this._findTargetItemIndex(e),l=n.children(),u=l[s],h=l.length,c=h?1:0,p={contentPosition:[n.x,n.y],pageCount:c,pageIndex:c-1,pagePrevDataIndex:null,pageNextDataIndex:null};if(!u)return p;var d=m(u);p.contentPosition[r]=-d.s;for(var f=s+1,g=d,y=d,v=null;f<=h;++f)(!(v=m(l[f]))&&y.e>g.s+i||v&&!x(v,g.s))&&(g=y.i>g.i?y:v)&&(null==p.pageNextDataIndex&&(p.pageNextDataIndex=g.i),++p.pageCount),y=v;for(f=s-1,g=d,y=d,v=null;f>=-1;--f)(v=m(l[f]))&&x(y,v.s)||!(g.i=e&&t.s<=e+i}},e.prototype._findTargetItemIndex=function(t){return this._showController?(this.getContentGroup().eachChild((function(i,r){var o=i.__legendDataIndex;null==n&&null!=o&&(n=r),o===t&&(e=r)})),null!=e?e:n):0;var e,n},e.type="legend.scroll",e}(SB);function zB(t){Im(kB),t.registerComponentModel(LB),t.registerComponentView(EB),function(t){t.registerAction("legendScroll","legendscroll",(function(t,e){var n=t.scrollDataIndex;null!=n&&e.eachComponent({mainType:"legend",subType:"scroll",query:t},(function(t){t.setScrollDataIndex(n)}))}))}(t)}var VB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="dataZoom.inside",e.defaultOption=wc(NE.defaultOption,{disabled:!1,zoomLock:!1,zoomOnMouseWheel:!0,moveOnMouseMove:!0,moveOnMouseWheel:!1,preventDefaultMouseMove:!0}),e}(NE),BB=Do();function FB(t,e,n){BB(t).coordSysRecordMap.each((function(t){var i=t.dataZoomInfoMap.get(e.uid);i&&(i.getRange=n)}))}function GB(t,e){if(e){t.removeKey(e.model.uid);var n=e.controller;n&&n.dispose()}}function WB(t,e){t.isDisposed()||t.dispatchAction({type:"dataZoom",animation:{easing:"cubicOut",duration:100},batch:e})}function HB(t,e,n,i){return t.coordinateSystem.containPoint([n,i])}function YB(t){t.registerProcessor(t.PRIORITY.PROCESSOR.FILTER,(function(t,e){var n=BB(e),i=n.coordSysRecordMap||(n.coordSysRecordMap=ft());i.each((function(t){t.dataZoomInfoMap=null})),t.eachComponent({mainType:"dataZoom",subType:"inside"},(function(t){E(OE(t).infoList,(function(n){var r=n.model.uid,o=i.get(r)||i.set(r,function(t,e){var n={model:e,containsPoint:H(HB,e),dispatchAction:H(WB,t),dataZoomInfoMap:null,controller:null},i=n.controller=new OI(t.getZr());return E(["pan","zoom","scrollMove"],(function(t){i.on(t,(function(e){var i=[];n.dataZoomInfoMap.each((function(r){if(e.isAvailableBehavior(r.model.option)){var o=(r.getRange||{})[t],a=o&&o(r.dzReferCoordSysInfo,n.model.mainType,n.controller,e);!r.model.get("disabled",!0)&&a&&i.push({dataZoomId:r.model.id,start:a[0],end:a[1]})}})),i.length&&n.dispatchAction(i)}))})),n}(e,n.model));(o.dataZoomInfoMap||(o.dataZoomInfoMap=ft())).set(t.uid,{dzReferCoordSysInfo:n,model:t,getRange:null})}))})),i.each((function(t){var e,n=t.controller,r=t.dataZoomInfoMap;if(r){var o=r.keys()[0];null!=o&&(e=r.get(o))}if(e){var a=function(t){var e,n="type_",i={type_true:2,type_move:1,type_false:0,type_undefined:-1},r=!0;return t.each((function(t){var o=t.model,a=!o.get("disabled",!0)&&(!o.get("zoomLock",!0)||"move");i[n+a]>i[n+e]&&(e=a),r=r&&o.get("preventDefaultMouseMove",!0)})),{controlType:e,opt:{zoomOnMouseWheel:!0,moveOnMouseMove:!0,moveOnMouseWheel:!0,preventDefaultMouseMove:!!r}}}(r);n.enable(a.controlType,a.opt),n.setPointerChecker(t.containsPoint),Pg(t,"dispatchAction",e.model.get("throttle",!0),"fixRate")}else GB(i,t)}))}))}var UB=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.type="dataZoom.inside",e}return n(e,t),e.prototype.render=function(e,n,i){t.prototype.render.apply(this,arguments),e.noTarget()?this._clear():(this.range=e.getPercentRange(),FB(i,e,{pan:W(XB.pan,this),zoom:W(XB.zoom,this),scrollMove:W(XB.scrollMove,this)}))},e.prototype.dispose=function(){this._clear(),t.prototype.dispose.apply(this,arguments)},e.prototype._clear=function(){!function(t,e){for(var n=BB(t).coordSysRecordMap,i=n.keys(),r=0;r0?s.pixelStart+s.pixelLength-s.pixel:s.pixel-s.pixelStart)/s.pixelLength*(o[1]-o[0])+o[0],u=Math.max(1/i.scale,0);o[0]=(o[0]-l)*u+l,o[1]=(o[1]-l)*u+l;var h=this.dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan();return dk(0,o,[0,100],0,h.minSpan,h.maxSpan),this.range=o,r[0]!==o[0]||r[1]!==o[1]?o:void 0}},pan:ZB((function(t,e,n,i,r,o){var a=jB[i]([o.oldX,o.oldY],[o.newX,o.newY],e,r,n);return a.signal*(t[1]-t[0])*a.pixel/a.pixelLength})),scrollMove:ZB((function(t,e,n,i,r,o){return jB[i]([0,0],[o.scrollDelta,o.scrollDelta],e,r,n).signal*(t[1]-t[0])*o.scrollDelta}))};function ZB(t){return function(e,n,i,r){var o=this.range,a=o.slice(),s=e.axisModels[0];if(s)return dk(t(a,s,e,n,i,r),a,[0,100],"all"),this.range=a,o[0]!==a[0]||o[1]!==a[1]?a:void 0}}var jB={grid:function(t,e,n,i,r){var o=n.axis,a={},s=r.model.coordinateSystem.getRect();return t=t||[0,0],"x"===o.dim?(a.pixel=e[0]-t[0],a.pixelLength=s.width,a.pixelStart=s.x,a.signal=o.inverse?1:-1):(a.pixel=e[1]-t[1],a.pixelLength=s.height,a.pixelStart=s.y,a.signal=o.inverse?-1:1),a},polar:function(t,e,n,i,r){var o=n.axis,a={},s=r.model.coordinateSystem,l=s.getRadiusAxis().getExtent(),u=s.getAngleAxis().getExtent();return t=t?s.pointToCoord(t):[0,0],e=s.pointToCoord(e),"radiusAxis"===n.mainType?(a.pixel=e[0]-t[0],a.pixelLength=l[1]-l[0],a.pixelStart=l[0],a.signal=o.inverse?1:-1):(a.pixel=e[1]-t[1],a.pixelLength=u[1]-u[0],a.pixelStart=u[0],a.signal=o.inverse?-1:1),a},singleAxis:function(t,e,n,i,r){var o=n.axis,a=r.model.coordinateSystem.getRect(),s={};return t=t||[0,0],"horizontal"===o.orient?(s.pixel=e[0]-t[0],s.pixelLength=a.width,s.pixelStart=a.x,s.signal=o.inverse?1:-1):(s.pixel=e[1]-t[1],s.pixelLength=a.height,s.pixelStart=a.y,s.signal=o.inverse?-1:1),s}};function qB(t){UE(t),t.registerComponentModel(VB),t.registerComponentView(UB),YB(t)}var KB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="dataZoom.slider",e.layoutMode="box",e.defaultOption=wc(NE.defaultOption,{show:!0,right:"ph",top:"ph",width:"ph",height:"ph",left:null,bottom:null,borderColor:"#d2dbee",borderRadius:3,backgroundColor:"rgba(47,69,84,0)",dataBackground:{lineStyle:{color:"#d2dbee",width:.5},areaStyle:{color:"#d2dbee",opacity:.2}},selectedDataBackground:{lineStyle:{color:"#8fb0f7",width:.5},areaStyle:{color:"#8fb0f7",opacity:.2}},fillerColor:"rgba(135,175,274,0.2)",handleIcon:"path://M-9.35,34.56V42m0-40V9.5m-2,0h4a2,2,0,0,1,2,2v21a2,2,0,0,1-2,2h-4a2,2,0,0,1-2-2v-21A2,2,0,0,1-11.35,9.5Z",handleSize:"100%",handleStyle:{color:"#fff",borderColor:"#ACB8D1"},moveHandleSize:7,moveHandleIcon:"path://M-320.9-50L-320.9-50c18.1,0,27.1,9,27.1,27.1V85.7c0,18.1-9,27.1-27.1,27.1l0,0c-18.1,0-27.1-9-27.1-27.1V-22.9C-348-41-339-50-320.9-50z M-212.3-50L-212.3-50c18.1,0,27.1,9,27.1,27.1V85.7c0,18.1-9,27.1-27.1,27.1l0,0c-18.1,0-27.1-9-27.1-27.1V-22.9C-239.4-41-230.4-50-212.3-50z M-103.7-50L-103.7-50c18.1,0,27.1,9,27.1,27.1V85.7c0,18.1-9,27.1-27.1,27.1l0,0c-18.1,0-27.1-9-27.1-27.1V-22.9C-130.9-41-121.8-50-103.7-50z",moveHandleStyle:{color:"#D2DBEE",opacity:.7},showDetail:!0,showDataShadow:"auto",realtime:!0,zoomLock:!1,textStyle:{color:"#6E7079"},brushSelect:!0,brushStyle:{color:"rgba(135,175,274,0.15)"},emphasis:{handleStyle:{borderColor:"#8FB0F7"},moveHandleStyle:{color:"#8FB0F7"}}}),e}(NE),$B=Ps,JB="horizontal",QB="vertical",tF=["line","bar","candlestick","scatter"],eF={easing:"cubicOut",duration:100,delay:0},nF=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n._displayables={},n}return n(e,t),e.prototype.init=function(t,e){this.api=e,this._onBrush=W(this._onBrush,this),this._onBrushEnd=W(this._onBrushEnd,this)},e.prototype.render=function(e,n,i,r){if(t.prototype.render.apply(this,arguments),Pg(this,"_dispatchZoomAction",e.get("throttle"),"fixRate"),this._orient=e.getOrient(),!1!==e.get("show")){if(e.noTarget())return this._clear(),void this.group.removeAll();r&&"dataZoom"===r.type&&r.from===this.uid||this._buildView(),this._updateView()}else this.group.removeAll()},e.prototype.dispose=function(){this._clear(),t.prototype.dispose.apply(this,arguments)},e.prototype._clear=function(){Og(this,"_dispatchZoomAction");var t=this.api.getZr();t.off("mousemove",this._onBrush),t.off("mouseup",this._onBrushEnd)},e.prototype._buildView=function(){var t=this.group;t.removeAll(),this._brushing=!1,this._displayables.brushRect=null,this._resetLocation(),this._resetInterval();var e=this._displayables.sliderGroup=new Pr;this._renderBackground(),this._renderHandle(),this._renderDataShadow(),t.add(e),this._positionGroup()},e.prototype._resetLocation=function(){var t=this.dataZoomModel,e=this.api,n=t.get("brushSelect")?7:0,i=this._findCoordRect(),r={width:e.getWidth(),height:e.getHeight()},o=this._orient===JB?{right:r.width-i.x-i.width,top:r.height-30-7-n,width:i.width,height:30}:{right:7,top:i.y,width:30,height:i.height},a=Tp(t.option);E(["right","top","width","height"],(function(t){"ph"===a[t]&&(a[t]=o[t])}));var s=wp(a,r);this._location={x:s.x,y:s.y},this._size=[s.width,s.height],this._orient===QB&&this._size.reverse()},e.prototype._positionGroup=function(){var t=this.group,e=this._location,n=this._orient,i=this.dataZoomModel.getFirstTargetAxisModel(),r=i&&i.get("inverse"),o=this._displayables.sliderGroup,a=(this._dataShadowInfo||{}).otherAxisInverse;o.attr(n!==JB||r?n===JB&&r?{scaleY:a?1:-1,scaleX:-1}:n!==QB||r?{scaleY:a?-1:1,scaleX:-1,rotation:Math.PI/2}:{scaleY:a?-1:1,scaleX:1,rotation:Math.PI/2}:{scaleY:a?1:-1,scaleX:1});var s=t.getBoundingRect([o]);t.x=e.x-s.x,t.y=e.y-s.y,t.markRedraw()},e.prototype._getViewExtent=function(){return[0,this._size[0]]},e.prototype._renderBackground=function(){var t=this.dataZoomModel,e=this._size,n=this._displayables.sliderGroup,i=t.get("brushSelect");n.add(new $B({silent:!0,shape:{x:0,y:0,width:e[0],height:e[1]},style:{fill:t.get("backgroundColor")},z2:-40}));var r=new $B({shape:{x:0,y:0,width:e[0],height:e[1]},style:{fill:"transparent"},z2:0,onclick:W(this._onClickPanel,this)}),o=this.api.getZr();i?(r.on("mousedown",this._onBrushStart,this),r.cursor="crosshair",o.on("mousemove",this._onBrush),o.on("mouseup",this._onBrushEnd)):(o.off("mousemove",this._onBrush),o.off("mouseup",this._onBrushEnd)),n.add(r)},e.prototype._renderDataShadow=function(){var t=this._dataShadowInfo=this._prepareDataShadowInfo();if(this._displayables.dataShadowSegs=[],t){var e=this._size,n=this._shadowSize||[],i=t.series,r=i.getRawData(),o=i.getShadowDim&&i.getShadowDim(),a=o&&r.getDimensionInfo(o)?i.getShadowDim():t.otherDim;if(null!=a){var s=this._shadowPolygonPts,l=this._shadowPolylinePts;if(r!==this._shadowData||a!==this._shadowDim||e[0]!==n[0]||e[1]!==n[1]){var u=r.getDataExtent(a),h=.3*(u[1]-u[0]);u=[u[0]-h,u[1]+h];var c,p=[0,e[1]],d=[0,e[0]],f=[[e[0],0],[0,0]],g=[],y=d[1]/(r.count()-1),v=0,m=Math.round(r.count()/e[0]);r.each([a],(function(t,e){if(m>0&&e%m)v+=y;else{var n=null==t||isNaN(t)||""===t,i=n?0:Fr(t,u,p,!0);n&&!c&&e?(f.push([f[f.length-1][0],0]),g.push([g[g.length-1][0],0])):!n&&c&&(f.push([v,0]),g.push([v,0])),f.push([v,i]),g.push([v,i]),v+=y,c=n}})),s=this._shadowPolygonPts=f,l=this._shadowPolylinePts=g}this._shadowData=r,this._shadowDim=a,this._shadowSize=[e[0],e[1]];for(var x=this.dataZoomModel,_=0;_<3;_++){var b=w(1===_);this._displayables.sliderGroup.add(b),this._displayables.dataShadowSegs.push(b)}}}function w(t){var e=x.getModel(t?"selectedDataBackground":"dataBackground"),n=new Pr,i=new zu({shape:{points:s},segmentIgnoreThreshold:1,style:e.getModel("areaStyle").getAreaStyle(),silent:!0,z2:-20}),r=new Bu({shape:{points:l},segmentIgnoreThreshold:1,style:e.getModel("lineStyle").getLineStyle(),silent:!0,z2:-19});return n.add(i),n.add(r),n}},e.prototype._prepareDataShadowInfo=function(){var t=this.dataZoomModel,e=t.get("showDataShadow");if(!1!==e){var n,i=this.ecModel;return t.eachTargetAxis((function(r,o){E(t.getAxisProxy(r,o).getTargetSeriesModels(),(function(t){if(!(n||!0!==e&&P(tF,t.get("type"))<0)){var a,s=i.getComponent(LE(r),o).axis,l={x:"y",y:"x",radius:"angle",angle:"radius"}[r],u=t.coordinateSystem;null!=l&&u.getOtherAxis&&(a=u.getOtherAxis(s).inverse),l=t.getData().mapDimension(l),n={thisAxis:s,series:t,thisDim:r,otherDim:l,otherAxisInverse:a}}}),this)}),this),n}},e.prototype._renderHandle=function(){var t=this.group,e=this._displayables,n=e.handles=[null,null],i=e.handleLabels=[null,null],r=this._displayables.sliderGroup,o=this._size,a=this.dataZoomModel,s=this.api,l=a.get("borderRadius")||0,u=a.get("brushSelect"),h=e.filler=new $B({silent:u,style:{fill:a.get("fillerColor")},textConfig:{position:"inside"}});r.add(h),r.add(new $B({silent:!0,subPixelOptimize:!0,shape:{x:0,y:0,width:o[0],height:o[1],r:l},style:{stroke:a.get("dataBackgroundColor")||a.get("borderColor"),lineWidth:1,fill:"rgba(0,0,0,0)"}})),E([0,1],(function(e){var o=a.get("handleIcon");!Ly[o]&&o.indexOf("path://")<0&&o.indexOf("image://")<0&&(o="path://"+o);var s=Ry(o,-1,0,2,2,null,!0);s.attr({cursor:iF(this._orient),draggable:!0,drift:W(this._onDragMove,this,e),ondragend:W(this._onDragEnd,this),onmouseover:W(this._showDataInfo,this,!0),onmouseout:W(this._showDataInfo,this,!1),z2:5});var l=s.getBoundingRect(),u=a.get("handleSize");this._handleHeight=Gr(u,this._size[1]),this._handleWidth=l.width/l.height*this._handleHeight,s.setStyle(a.getModel("handleStyle").getItemStyle()),s.style.strokeNoScale=!0,s.rectHover=!0,s.ensureState("emphasis").style=a.getModel(["emphasis","handleStyle"]).getItemStyle(),Vl(s);var h=a.get("handleColor");null!=h&&(s.style.fill=h),r.add(n[e]=s);var c=a.getModel("textStyle");t.add(i[e]=new Ns({silent:!0,invisible:!0,style:$h(c,{x:0,y:0,text:"",verticalAlign:"middle",align:"center",fill:c.getTextColor(),font:c.getFont()}),z2:10}))}),this);var c=h;if(u){var p=Gr(a.get("moveHandleSize"),o[1]),d=e.moveHandle=new Ps({style:a.getModel("moveHandleStyle").getItemStyle(),silent:!0,shape:{r:[0,0,2,2],y:o[1]-.5,height:p}}),f=.8*p,g=e.moveHandleIcon=Ry(a.get("moveHandleIcon"),-f/2,-f/2,f,f,"#fff",!0);g.silent=!0,g.y=o[1]+p/2-.5,d.ensureState("emphasis").style=a.getModel(["emphasis","moveHandleStyle"]).getItemStyle();var y=Math.min(o[1]/2,Math.max(p,10));(c=e.moveZone=new Ps({invisible:!0,shape:{y:o[1]-y,height:p+y}})).on("mouseover",(function(){s.enterEmphasis(d)})).on("mouseout",(function(){s.leaveEmphasis(d)})),r.add(d),r.add(g),r.add(c)}c.attr({draggable:!0,cursor:iF(this._orient),drift:W(this._onDragMove,this,"all"),ondragstart:W(this._showDataInfo,this,!0),ondragend:W(this._onDragEnd,this),onmouseover:W(this._showDataInfo,this,!0),onmouseout:W(this._showDataInfo,this,!1)})},e.prototype._resetInterval=function(){var t=this._range=this.dataZoomModel.getPercentRange(),e=this._getViewExtent();this._handleEnds=[Fr(t[0],[0,100],e,!0),Fr(t[1],[0,100],e,!0)]},e.prototype._updateInterval=function(t,e){var n=this.dataZoomModel,i=this._handleEnds,r=this._getViewExtent(),o=n.findRepresentativeAxisProxy().getMinMaxSpan(),a=[0,100];dk(e,i,r,n.get("zoomLock")?"all":t,null!=o.minSpan?Fr(o.minSpan,a,r,!0):null,null!=o.maxSpan?Fr(o.maxSpan,a,r,!0):null);var s=this._range,l=this._range=Hr([Fr(i[0],r,a,!0),Fr(i[1],r,a,!0)]);return!s||s[0]!==l[0]||s[1]!==l[1]},e.prototype._updateView=function(t){var e=this._displayables,n=this._handleEnds,i=Hr(n.slice()),r=this._size;E([0,1],(function(t){var i=e.handles[t],o=this._handleHeight;i.attr({scaleX:o/2,scaleY:o/2,x:n[t]+(t?-1:1),y:r[1]/2-o/2})}),this),e.filler.setShape({x:i[0],y:0,width:i[1]-i[0],height:r[1]});var o={x:i[0],width:i[1]-i[0]};e.moveHandle&&(e.moveHandle.setShape(o),e.moveZone.setShape(o),e.moveZone.getBoundingRect(),e.moveHandleIcon&&e.moveHandleIcon.attr("x",o.x+o.width/2));for(var a=e.dataShadowSegs,s=[0,i[0],i[1],r[0]],l=0;le[0]||n[1]<0||n[1]>e[1])){var i=this._handleEnds,r=(i[0]+i[1])/2,o=this._updateInterval("all",n[0]-r);this._updateView(),o&&this._dispatchZoomAction(!1)}},e.prototype._onBrushStart=function(t){var e=t.offsetX,n=t.offsetY;this._brushStart=new Ie(e,n),this._brushing=!0,this._brushStartTime=+new Date},e.prototype._onBrushEnd=function(t){if(this._brushing){var e=this._displayables.brushRect;if(this._brushing=!1,e){e.attr("ignore",!0);var n=e.shape;if(!(+new Date-this._brushStartTime<200&&Math.abs(n.width)<5)){var i=this._getViewExtent(),r=[0,100];this._range=Hr([Fr(n.x,i,r,!0),Fr(n.x+n.width,i,r,!0)]),this._handleEnds=[n.x,n.x+n.width],this._updateView(),this._dispatchZoomAction(!1)}}}},e.prototype._onBrush=function(t){this._brushing&&(he(t.event),this._updateBrushRect(t.offsetX,t.offsetY))},e.prototype._updateBrushRect=function(t,e){var n=this._displayables,i=this.dataZoomModel,r=n.brushRect;r||(r=n.brushRect=new $B({silent:!0,style:i.getModel("brushStyle").getItemStyle()}),n.sliderGroup.add(r)),r.attr("ignore",!1);var o=this._brushStart,a=this._displayables.sliderGroup,s=a.transformCoordToLocal(t,e),l=a.transformCoordToLocal(o.x,o.y),u=this._size;s[0]=Math.max(Math.min(u[0],s[0]),0),r.setShape({x:l[0],y:0,width:s[0]-l[0],height:u[1]})},e.prototype._dispatchZoomAction=function(t){var e=this._range;this.api.dispatchAction({type:"dataZoom",from:this.uid,dataZoomId:this.dataZoomModel.id,animation:t?eF:null,start:e[0],end:e[1]})},e.prototype._findCoordRect=function(){var t,e=OE(this.dataZoomModel).infoList;if(!t&&e.length){var n=e[0].model.coordinateSystem;t=n.getRect&&n.getRect()}if(!t){var i=this.api.getWidth(),r=this.api.getHeight();t={x:.2*i,y:.2*r,width:.6*i,height:.6*r}}return t},e.type="dataZoom.slider",e}(VE);function iF(t){return"vertical"===t?"ns-resize":"ew-resize"}function rF(t){t.registerComponentModel(KB),t.registerComponentView(nF),UE(t)}var oF=function(t,e,n){var i=T((aF[t]||{})[e]);return n&&Y(i)?i[i.length-1]:i},aF={color:{active:["#006edd","#e0ffff"],inactive:["rgba(0,0,0,0)"]},colorHue:{active:[0,360],inactive:[0,0]},colorSaturation:{active:[.3,1],inactive:[0,0]},colorLightness:{active:[.9,.5],inactive:[0,0]},colorAlpha:{active:[.3,1],inactive:[0,0]},opacity:{active:[.3,1],inactive:[0,0]},symbol:{active:["circle","roundRect","diamond"],inactive:["none"]},symbolSize:{active:[10,50],inactive:[0,0]}},sF=sD.mapVisual,lF=sD.eachVisual,uF=Y,hF=E,cF=Hr,pF=Fr,dF=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.stateList=["inRange","outOfRange"],n.replacableOptionKeys=["inRange","outOfRange","target","controller","color"],n.layoutMode={type:"box",ignoreSize:!0},n.dataBound=[-1/0,1/0],n.targetVisuals={},n.controllerVisuals={},n}return n(e,t),e.prototype.init=function(t,e,n){this.mergeDefaultAndTheme(t,n)},e.prototype.optionUpdated=function(t,e){var n=this.option;!e&&sV(n,t,this.replacableOptionKeys),this.textStyleModel=this.getModel("textStyle"),this.resetItemSize(),this.completeVisualOption()},e.prototype.resetVisual=function(t){var e=this.stateList;t=W(t,this),this.controllerVisuals=aV(this.option.controller,e,t),this.targetVisuals=aV(this.option.target,e,t)},e.prototype.getItemSymbol=function(){return null},e.prototype.getTargetSeriesIndices=function(){var t=this.option.seriesIndex,e=[];return null==t||"all"===t?this.ecModel.eachSeries((function(t,n){e.push(n)})):e=yo(t),e},e.prototype.eachTargetSeries=function(t,e){E(this.getTargetSeriesIndices(),(function(n){var i=this.ecModel.getSeriesByIndex(n);i&&t.call(e,i)}),this)},e.prototype.isTargetSeries=function(t){var e=!1;return this.eachTargetSeries((function(n){n===t&&(e=!0)})),e},e.prototype.formatValueText=function(t,e,n){var i,r=this.option,o=r.precision,a=this.dataBound,s=r.formatter;n=n||["<",">"],Y(t)&&(t=t.slice(),i=!0);var l=e?t:i?[u(t[0]),u(t[1])]:u(t);return X(s)?s.replace("{value}",i?l[0]:l).replace("{value2}",i?l[1]:l):U(s)?i?s(t[0],t[1]):s(t):i?t[0]===a[0]?n[0]+" "+l[1]:t[1]===a[1]?n[1]+" "+l[0]:l[0]+" - "+l[1]:l;function u(t){return t===a[0]?"min":t===a[1]?"max":(+t).toFixed(Math.min(o,20))}},e.prototype.resetExtent=function(){var t=this.option,e=cF([t.min,t.max]);this._dataExtent=e},e.prototype.getDataDimensionIndex=function(t){var e=this.option.dimension;if(null!=e)return t.getDimensionIndex(e);for(var n=t.dimensions,i=n.length-1;i>=0;i--){var r=n[i],o=t.getDimensionInfo(r);if(!o.isCalculationCoord)return o.storeDimIndex}},e.prototype.getExtent=function(){return this._dataExtent.slice()},e.prototype.completeVisualOption=function(){var t=this.ecModel,e=this.option,n={inRange:e.inRange,outOfRange:e.outOfRange},i=e.target||(e.target={}),r=e.controller||(e.controller={});C(i,n),C(r,n);var o=this.isCategory();function a(n){uF(e.color)&&!n.inRange&&(n.inRange={color:e.color.slice().reverse()}),n.inRange=n.inRange||{color:t.get("gradientColor")}}a.call(this,i),a.call(this,r),function(t,e,n){var i=t[e],r=t[n];i&&!r&&(r=t[n]={},hF(i,(function(t,e){if(sD.isValidType(e)){var n=oF(e,"inactive",o);null!=n&&(r[e]=n,"color"!==e||r.hasOwnProperty("opacity")||r.hasOwnProperty("colorAlpha")||(r.opacity=[0,0]))}})))}.call(this,i,"inRange","outOfRange"),function(t){var e=(t.inRange||{}).symbol||(t.outOfRange||{}).symbol,n=(t.inRange||{}).symbolSize||(t.outOfRange||{}).symbolSize,i=this.get("inactiveColor"),r=this.getItemSymbol()||"roundRect";hF(this.stateList,(function(a){var s=this.itemSize,l=t[a];l||(l=t[a]={color:o?i:[i]}),null==l.symbol&&(l.symbol=e&&T(e)||(o?r:[r])),null==l.symbolSize&&(l.symbolSize=n&&T(n)||(o?s[0]:[s[0],s[0]])),l.symbol=sF(l.symbol,(function(t){return"none"===t?r:t}));var u=l.symbolSize;if(null!=u){var h=-1/0;lF(u,(function(t){t>h&&(h=t)})),l.symbolSize=sF(u,(function(t){return pF(t,[0,h],[0,s[0]],!0)}))}}),this)}.call(this,r)},e.prototype.resetItemSize=function(){this.itemSize=[parseFloat(this.get("itemWidth")),parseFloat(this.get("itemHeight"))]},e.prototype.isCategory=function(){return!!this.option.categories},e.prototype.setSelected=function(t){},e.prototype.getSelected=function(){return null},e.prototype.getValueState=function(t){return null},e.prototype.getVisualMeta=function(t){return null},e.type="visualMap",e.dependencies=["series"],e.defaultOption={show:!0,z:4,seriesIndex:"all",min:0,max:200,left:0,right:null,top:null,bottom:0,itemWidth:null,itemHeight:null,inverse:!1,orient:"vertical",backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",contentColor:"#5793f3",inactiveColor:"#aaa",borderWidth:0,padding:5,textGap:10,precision:0,textStyle:{color:"#333"}},e}(Ap),fF=[20,140],gF=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.optionUpdated=function(e,n){t.prototype.optionUpdated.apply(this,arguments),this.resetExtent(),this.resetVisual((function(t){t.mappingMethod="linear",t.dataExtent=this.getExtent()})),this._resetRange()},e.prototype.resetItemSize=function(){t.prototype.resetItemSize.apply(this,arguments);var e=this.itemSize;(null==e[0]||isNaN(e[0]))&&(e[0]=fF[0]),(null==e[1]||isNaN(e[1]))&&(e[1]=fF[1])},e.prototype._resetRange=function(){var t=this.getExtent(),e=this.option.range;!e||e.auto?(t.auto=1,this.option.range=t):Y(e)&&(e[0]>e[1]&&e.reverse(),e[0]=Math.max(e[0],t[0]),e[1]=Math.min(e[1],t[1]))},e.prototype.completeVisualOption=function(){t.prototype.completeVisualOption.apply(this,arguments),E(this.stateList,(function(t){var e=this.option.controller[t].symbolSize;e&&e[0]!==e[1]&&(e[0]=e[1]/3)}),this)},e.prototype.setSelected=function(t){this.option.range=t.slice(),this._resetRange()},e.prototype.getSelected=function(){var t=this.getExtent(),e=Hr((this.get("range")||[]).slice());return e[0]>t[1]&&(e[0]=t[1]),e[1]>t[1]&&(e[1]=t[1]),e[0]=n[1]||t<=e[1])?"inRange":"outOfRange"},e.prototype.findTargetDataIndices=function(t){var e=[];return this.eachTargetSeries((function(n){var i=[],r=n.getData();r.each(this.getDataDimensionIndex(r),(function(e,n){t[0]<=e&&e<=t[1]&&i.push(n)}),this),e.push({seriesId:n.id,dataIndex:i})}),this),e},e.prototype.getVisualMeta=function(t){var e=yF(this,"outOfRange",this.getExtent()),n=yF(this,"inRange",this.option.range.slice()),i=[];function r(e,n){i.push({value:e,color:t(e,n)})}for(var o=0,a=0,s=n.length,l=e.length;at[1])break;n.push({color:this.getControllerVisual(o,"color",e),offset:r/100})}return n.push({color:this.getControllerVisual(t[1],"color",e),offset:1}),n},e.prototype._createBarPoints=function(t,e){var n=this.visualMapModel.itemSize;return[[n[0]-e[0],t[0]],[n[0],t[0]],[n[0],t[1]],[n[0]-e[1],t[1]]]},e.prototype._createBarGroup=function(t){var e=this._orient,n=this.visualMapModel.get("inverse");return new Pr("horizontal"!==e||n?"horizontal"===e&&n?{scaleX:"bottom"===t?-1:1,rotation:-Math.PI/2}:"vertical"!==e||n?{scaleX:"left"===t?1:-1}:{scaleX:"left"===t?1:-1,scaleY:-1}:{scaleX:"bottom"===t?1:-1,rotation:Math.PI/2})},e.prototype._updateHandle=function(t,e){if(this._useHandle){var n=this._shapes,i=this.visualMapModel,r=n.handleThumbs,o=n.handleLabels,a=i.itemSize,s=i.getExtent();wF([0,1],(function(l){var u=r[l];u.setStyle("fill",e.handlesColor[l]),u.y=t[l];var h=bF(t[l],[0,a[1]],s,!0),c=this.getControllerVisual(h,"symbolSize");u.scaleX=u.scaleY=c/a[0],u.x=a[0]-c/2;var p=Ph(n.handleLabelPoints[l],Lh(u,this.group));o[l].setStyle({x:p[0],y:p[1],text:i.formatValueText(this._dataInterval[l]),verticalAlign:"middle",align:"vertical"===this._orient?this._applyTransform("left",n.mainGroup):"center"})}),this)}},e.prototype._showIndicator=function(t,e,n,i){var r=this.visualMapModel,o=r.getExtent(),a=r.itemSize,s=[0,a[1]],l=this._shapes,u=l.indicator;if(u){u.attr("invisible",!1);var h=this.getControllerVisual(t,"color",{convertOpacityToAlpha:!0}),c=this.getControllerVisual(t,"symbolSize"),p=bF(t,o,s,!0),d=a[0]-c/2,f={x:u.x,y:u.y};u.y=p,u.x=d;var g=Ph(l.indicatorLabelPoint,Lh(u,this.group)),y=l.indicatorLabel;y.attr("invisible",!1);var v=this._applyTransform("left",l.mainGroup),m="horizontal"===this._orient;y.setStyle({text:(n||"")+r.formatValueText(e),verticalAlign:m?v:"middle",align:m?"center":v});var x={x:d,y:p,style:{fill:h}},_={style:{x:g[0],y:g[1]}};if(r.ecModel.isAnimationEnabled()&&!this._firstShowIndicator){var b={duration:100,easing:"cubicInOut",additive:!0};u.x=f.x,u.y=f.y,u.animateTo(x,b),y.animateTo(_,b)}else u.attr(x),y.attr(_);this._firstShowIndicator=!1;var w=this._shapes.handleLabels;if(w)for(var S=0;Sr[1]&&(u[1]=1/0),e&&(u[0]===-1/0?this._showIndicator(l,u[1],"< ",a):u[1]===1/0?this._showIndicator(l,u[0],"> ",a):this._showIndicator(l,l,"≈ ",a));var h=this._hoverLinkDataIndices,c=[];(e||CF(n))&&(c=this._hoverLinkDataIndices=n.findTargetDataIndices(u));var p=function(t,e){var n={},i={};return r(t||[],n),r(e||[],i,n),[o(n),o(i)];function r(t,e,n){for(var i=0,r=t.length;i=0&&(r.dimension=o,i.push(r))}})),t.getData().setVisual("visualMeta",i)}}];function PF(t,e,n,i){for(var r=e.targetVisuals[i],o=sD.prepareVisualTypes(r),a={color:my(t.getData(),"color")},s=0,l=o.length;s0:t.splitNumber>0)&&!t.calculable?"piecewise":"continuous"})),t.registerAction(AF,kF),E(LF,(function(e){t.registerVisual(t.PRIORITY.VISUAL.COMPONENT,e)})),t.registerPreprocessor(RF))}function VF(t){t.registerComponentModel(gF),t.registerComponentView(IF),zF(t)}var BF=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n._pieceList=[],n}return n(e,t),e.prototype.optionUpdated=function(e,n){t.prototype.optionUpdated.apply(this,arguments),this.resetExtent();var i=this._mode=this._determineMode();this._pieceList=[],FF[this._mode].call(this,this._pieceList),this._resetSelected(e,n);var r=this.option.categories;this.resetVisual((function(t,e){"categories"===i?(t.mappingMethod="category",t.categories=T(r)):(t.dataExtent=this.getExtent(),t.mappingMethod="piecewise",t.pieceList=z(this._pieceList,(function(t){return t=T(t),"inRange"!==e&&(t.visual=null),t})))}))},e.prototype.completeVisualOption=function(){var e=this.option,n={},i=sD.listVisualTypes(),r=this.isCategory();function o(t,e,n){return t&&t[e]&&t[e].hasOwnProperty(n)}E(e.pieces,(function(t){E(i,(function(e){t.hasOwnProperty(e)&&(n[e]=1)}))})),E(n,(function(t,n){var i=!1;E(this.stateList,(function(t){i=i||o(e,t,n)||o(e.target,t,n)}),this),!i&&E(this.stateList,(function(t){(e[t]||(e[t]={}))[n]=oF(n,"inRange"===t?"active":"inactive",r)}))}),this),t.prototype.completeVisualOption.apply(this,arguments)},e.prototype._resetSelected=function(t,e){var n=this.option,i=this._pieceList,r=(e?n:t).selected||{};if(n.selected=r,E(i,(function(t,e){var n=this.getSelectedMapKey(t);r.hasOwnProperty(n)||(r[n]=!0)}),this),"single"===n.selectedMode){var o=!1;E(i,(function(t,e){var n=this.getSelectedMapKey(t);r[n]&&(o?r[n]=!1:o=!0)}),this)}},e.prototype.getItemSymbol=function(){return this.get("itemSymbol")},e.prototype.getSelectedMapKey=function(t){return"categories"===this._mode?t.value+"":t.index+""},e.prototype.getPieceList=function(){return this._pieceList},e.prototype._determineMode=function(){var t=this.option;return t.pieces&&t.pieces.length>0?"pieces":this.option.categories?"categories":"splitNumber"},e.prototype.setSelected=function(t){this.option.selected=T(t)},e.prototype.getValueState=function(t){var e=sD.findPieceIndex(t,this._pieceList);return null!=e&&this.option.selected[this.getSelectedMapKey(this._pieceList[e])]?"inRange":"outOfRange"},e.prototype.findTargetDataIndices=function(t){var e=[],n=this._pieceList;return this.eachTargetSeries((function(i){var r=[],o=i.getData();o.each(this.getDataDimensionIndex(o),(function(e,i){sD.findPieceIndex(e,n)===t&&r.push(i)}),this),e.push({seriesId:i.id,dataIndex:r})}),this),e},e.prototype.getRepresentValue=function(t){var e;if(this.isCategory())e=t.value;else if(null!=t.value)e=t.value;else{var n=t.interval||[];e=n[0]===-1/0&&n[1]===1/0?0:(n[0]+n[1])/2}return e},e.prototype.getVisualMeta=function(t){if(!this.isCategory()){var e=[],n=["",""],i=this,r=this._pieceList.slice();if(r.length){var o=r[0].interval[0];o!==-1/0&&r.unshift({interval:[-1/0,o]}),(o=r[r.length-1].interval[1])!==1/0&&r.push({interval:[o,1/0]})}else r.push({interval:[-1/0,1/0]});var a=-1/0;return E(r,(function(t){var e=t.interval;e&&(e[0]>a&&s([a,e[0]],"outOfRange"),s(e.slice()),a=e[1])}),this),{stops:e,outerColors:n}}function s(r,o){var a=i.getRepresentValue({interval:r});o||(o=i.getValueState(a));var s=t(a,o);r[0]===-1/0?n[0]=s:r[1]===1/0?n[1]=s:e.push({value:r[0],color:s},{value:r[1],color:s})}},e.type="visualMap.piecewise",e.defaultOption=wc(dF.defaultOption,{selected:null,minOpen:!1,maxOpen:!1,align:"auto",itemWidth:20,itemHeight:14,itemSymbol:"roundRect",pieces:null,categories:null,splitNumber:5,selectedMode:"multiple",itemGap:10,hoverLink:!0}),e}(dF),FF={splitNumber:function(t){var e=this.option,n=Math.min(e.precision,20),i=this.getExtent(),r=e.splitNumber;r=Math.max(parseInt(r,10),1),e.splitNumber=r;for(var o=(i[1]-i[0])/r;+o.toFixed(n)!==o&&n<5;)n++;e.precision=n,o=+o.toFixed(n),e.minOpen&&t.push({interval:[-1/0,i[0]],close:[0,0]});for(var a=0,s=i[0];a","≥"][e[0]]];t.text=t.text||this.formatValueText(null!=t.value?t.value:t.interval,!1,n)}),this)}};function GF(t,e){var n=t.inverse;("vertical"===t.orient?!n:n)&&e.reverse()}var WF=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.doRender=function(){var t=this.group;t.removeAll();var e=this.visualMapModel,n=e.get("textGap"),i=e.textStyleModel,r=i.getFont(),o=i.getTextColor(),a=this._getItemAlign(),s=e.itemSize,l=this._getViewData(),u=l.endsText,h=it(e.get("showLabel",!0),!u);u&&this._renderEndsText(t,u[0],s,h,a),E(l.viewPieceList,(function(i){var l=i.piece,u=new Pr;u.onclick=W(this._onItemClick,this,l),this._enableHoverLink(u,i.indexInModelPieceList);var c=e.getRepresentValue(l);if(this._createItemSymbol(u,c,[0,0,s[0],s[1]]),h){var p=this.visualMapModel.getValueState(c);u.add(new Ns({style:{x:"right"===a?-n:s[0]+n,y:s[1]/2,text:l.text,verticalAlign:"middle",align:a,font:r,fill:o,opacity:"outOfRange"===p?.5:1}}))}t.add(u)}),this),u&&this._renderEndsText(t,u[1],s,h,a),bp(e.get("orient"),t,e.get("itemGap")),this.renderBackground(t),this.positionGroup(t)},e.prototype._enableHoverLink=function(t,e){var n=this;t.on("mouseover",(function(){return i("highlight")})).on("mouseout",(function(){return i("downplay")}));var i=function(t){var i=n.visualMapModel;i.option.hoverLink&&n.api.dispatchAction({type:t,batch:_F(i.findTargetDataIndices(e),i)})}},e.prototype._getItemAlign=function(){var t=this.visualMapModel,e=t.option;if("vertical"===e.orient)return xF(t,this.api,t.itemSize);var n=e.align;return n&&"auto"!==n||(n="left"),n},e.prototype._renderEndsText=function(t,e,n,i,r){if(e){var o=new Pr,a=this.visualMapModel.textStyleModel;o.add(new Ns({style:$h(a,{x:i?"right"===r?n[0]:0:n[0]/2,y:n[1]/2,verticalAlign:"middle",align:i?r:"center",text:e})})),t.add(o)}},e.prototype._getViewData=function(){var t=this.visualMapModel,e=z(t.getPieceList(),(function(t,e){return{piece:t,indexInModelPieceList:e}})),n=t.get("text"),i=t.get("orient"),r=t.get("inverse");return("horizontal"===i?r:!r)?e.reverse():n&&(n=n.slice().reverse()),{viewPieceList:e,endsText:n}},e.prototype._createItemSymbol=function(t,e,n){t.add(Ry(this.getControllerVisual(e,"symbol"),n[0],n[1],n[2],n[3],this.getControllerVisual(e,"color")))},e.prototype._onItemClick=function(t){var e=this.visualMapModel,n=e.option,i=n.selectedMode;if(i){var r=T(n.selected),o=e.getSelectedMapKey(t);"single"===i||!0===i?(r[o]=!0,E(r,(function(t,e){r[e]=e===o}))):r[o]=!r[o],this.api.dispatchAction({type:"selectDataRange",from:this.uid,visualMapId:this.visualMapModel.id,selected:r})}},e.type="visualMap.piecewise",e}(vF);function HF(t){t.registerComponentModel(BF),t.registerComponentView(WF),zF(t)}var YF={label:{enabled:!0},decal:{show:!1}},UF=Do(),XF={};function ZF(t,e){var n=t.getModel("aria");if(n.get("enabled")){var i=T(YF);C(i.label,t.getLocaleModel().get("aria"),!1),C(n.option,i,!1),function(){if(n.getModel("decal").get("show")){var e=ft();t.eachSeries((function(t){if(!t.isColorBySeries()){var n=e.get(t.type);n||(n={},e.set(t.type,n)),UF(t).scope=n}})),t.eachRawSeries((function(e){if(!t.isSeriesFiltered(e))if(U(e.enableAriaDecal))e.enableAriaDecal();else{var n=e.getData();if(e.isColorBySeries()){var i=rd(e.ecModel,e.name,XF,t.getSeriesCount()),r=n.getVisual("decal");n.setVisual("decal",u(r,i))}else{var o=e.getRawData(),a={},s=UF(e).scope;n.each((function(t){var e=n.getRawIndex(t);a[e]=t}));var l=o.count();o.each((function(t){var i=a[t],r=o.getName(t)||t+"",h=rd(e.ecModel,r,s,l),c=n.getItemVisual(i,"decal");n.setItemVisual(i,"decal",u(c,h))}))}}function u(t,e){var n=t?A(A({},e),t):e;return n.dirty=!0,n}}))}}(),function(){var i=t.getLocaleModel().get("aria"),o=n.getModel("label");if(o.option=k(o.option,i),!o.get("enabled"))return;var a=e.getZr().dom;if(o.get("description"))return void a.setAttribute("aria-label",o.get("description"));var s,l=t.getSeriesCount(),u=o.get(["data","maxCount"])||10,h=o.get(["series","maxCount"])||10,c=Math.min(l,h);if(l<1)return;var p=function(){var e=t.get("title");e&&e.length&&(e=e[0]);return e&&e.text}();if(p){var d=o.get(["general","withTitle"]);s=r(d,{title:p})}else s=o.get(["general","withoutTitle"]);var f=[],g=l>1?o.get(["series","multiple","prefix"]):o.get(["series","single","prefix"]);s+=r(g,{seriesCount:l}),t.eachSeries((function(e,n){if(n1?o.get(["series","multiple",a]):o.get(["series","single",a]),{seriesId:e.seriesIndex,seriesName:e.get("name"),seriesType:(x=e.subType,t.getLocaleModel().get(["series","typeNames"])[x]||"自定义图")});var s=e.getData();if(s.count()>u)i+=r(o.get(["data","partialData"]),{displayCnt:u});else i+=o.get(["data","allData"]);for(var h=o.get(["data","separator","middle"]),p=o.get(["data","separator","end"]),d=[],g=0;g":"gt",">=":"gte","=":"eq","!=":"ne","<>":"ne"},KF=function(){function t(t){if(null==(this._condVal=X(t)?new RegExp(t):et(t)?t:null)){var e="";0,co(e)}}return t.prototype.evaluate=function(t){var e=typeof t;return X(e)?this._condVal.test(t):!!j(e)&&this._condVal.test(t+"")},t}(),$F=function(){function t(){}return t.prototype.evaluate=function(){return this.value},t}(),JF=function(){function t(){}return t.prototype.evaluate=function(){for(var t=this.children,e=0;e2&&l.push(e),e=[t,n]}function f(t,n,i,r){cG(t,i)&&cG(n,r)||e.push(t,n,i,r,i,r)}function g(t,n,i,r,o,a){var s=Math.abs(n-t),l=4*Math.tan(s/4)/3,u=nM:C2&&l.push(e),l}function dG(t,e,n,i,r,o,a,s,l,u){if(cG(t,n)&&cG(e,i)&&cG(r,a)&&cG(o,s))l.push(a,s);else{var h=2/u,c=h*h,p=a-t,d=s-e,f=Math.sqrt(p*p+d*d);p/=f,d/=f;var g=n-t,y=i-e,v=r-a,m=o-s,x=g*g+y*y,_=v*v+m*m;if(x=0&&_-w*w=0)l.push(a,s);else{var S=[],M=[];xn(t,n,r,a,.5,S),xn(e,i,o,s,.5,M),dG(S[0],M[0],S[1],M[1],S[2],M[2],S[3],M[3],l,u),dG(S[4],M[4],S[5],M[5],S[6],M[6],S[7],M[7],l,u)}}}}function fG(t,e,n){var i=t[e],r=t[1-e],o=Math.abs(i/r),a=Math.ceil(Math.sqrt(o*n)),s=Math.floor(n/a);0===s&&(s=1,a=n);for(var l=[],u=0;u0)for(u=0;uMath.abs(u),c=fG([l,u],h?0:1,e),p=(h?s:u)/c.length,d=0;d1?null:new Ie(d*l+t,d*u+e)}function mG(t,e,n){var i=new Ie;Ie.sub(i,n,e),i.normalize();var r=new Ie;return Ie.sub(r,t,e),r.dot(i)}function xG(t,e){var n=t[t.length-1];n&&n[0]===e[0]&&n[1]===e[1]||t.push(e)}function _G(t){var e=t.points,n=[],i=[];Aa(e,n,i);var r=new Re(n[0],n[1],i[0]-n[0],i[1]-n[1]),o=r.width,a=r.height,s=r.x,l=r.y,u=new Ie,h=new Ie;return o>a?(u.x=h.x=s+o/2,u.y=l,h.y=l+a):(u.y=h.y=l+a/2,u.x=s,h.x=s+o),function(t,e,n){for(var i=t.length,r=[],o=0;or,a=fG([i,r],o?0:1,e),s=o?"width":"height",l=o?"height":"width",u=o?"x":"y",h=o?"y":"x",c=t[s]/a.length,p=0;p0)for(var b=i/n,w=-i/2;w<=i/2;w+=b){var S=Math.sin(w),M=Math.cos(w),I=0;for(x=0;x0;l/=2){var u=0,h=0;(t&l)>0&&(u=1),(e&l)>0&&(h=1),s+=l*l*(3*u^h),0===h&&(1===u&&(t=l-1-t,e=l-1-e),a=t,t=e,e=a)}return s}function zG(t){var e=1/0,n=1/0,i=-1/0,r=-1/0,o=z(t,(function(t){var o=t.getBoundingRect(),a=t.getComputedTransform(),s=o.x+o.width/2+(a?a[4]:0),l=o.y+o.height/2+(a?a[5]:0);return e=Math.min(s,e),n=Math.min(l,n),i=Math.max(s,i),r=Math.max(l,r),[s,l]}));return z(o,(function(o,a){return{cp:o,z:EG(o[0],o[1],e,n,i,r),path:t[a]}})).sort((function(t,e){return t.z-e.z})).map((function(t){return t.path}))}function VG(t){return SG(t.path,t.count)}function BG(t){return Y(t[0])}function FG(t,e){for(var n=[],i=t.length,r=0;r=0;r--)if(!n[r].many.length){var l=n[s].many;if(l.length<=1){if(!s)return n;s=0}o=l.length;var u=Math.ceil(o/2);n[r].many=l.slice(u,o),n[s].many=l.slice(0,u),s++}return n}var GG={clone:function(t){for(var e=[],n=1-Math.pow(1-t.path.style.opacity,1/t.count),i=0;i0){var s,l,u=i.getModel("universalTransition").get("delay"),h=Object.assign({setToFinal:!0},a);BG(t)&&(s=t,l=e),BG(e)&&(s=e,l=t);for(var c=s?s===t:t.length>e.length,p=s?FG(l,s):FG(c?e:t,[c?t:e]),d=0,f=0;f1e4))for(var i=n.getIndices(),r=function(t){for(var e=t.dimensions,n=0;n0&&i.group.traverse((function(t){t instanceof _s&&!t.animators.length&&t.animateFrom({style:{opacity:0}},r)}))}))}function $G(t){var e=t.getModel("universalTransition").get("seriesKey");return e||t.id}function JG(t){return Y(t)?t.sort().join(","):t}function QG(t){if(t.hostModel)return t.hostModel.getModel("universalTransition").get("divideShape")}function tW(t,e){for(var n=0;n=0&&r.push({data:e.oldData[n],divide:QG(e.oldData[n]),dim:t.dimension})})),E(yo(t.to),(function(t){var e=tW(n.updatedSeries,t);if(e>=0){var i=n.updatedSeries[e].getData();o.push({data:i,divide:QG(i),dim:t.dimension})}})),r.length>0&&o.length>0&&KG(r,o,i)}(t,i,n,e)}));else{var o=function(t,e){var n=ft(),i=ft(),r=ft();return E(t.oldSeries,(function(e,n){var o=t.oldData[n],a=$G(e),s=JG(a);i.set(s,o),Y(a)&&E(a,(function(t){r.set(t,{data:o,key:s})}))})),E(e.updatedSeries,(function(t){if(t.isUniversalTransitionEnabled()&&t.isAnimationEnabled()){var e=t.getData(),o=$G(t),a=JG(o),s=i.get(a);if(s)n.set(a,{oldSeries:[{divide:QG(s),data:s}],newSeries:[{divide:QG(e),data:e}]});else if(Y(o)){var l=[];E(o,(function(t){var e=i.get(t);e&&l.push({divide:QG(e),data:e})})),l.length&&n.set(a,{oldSeries:l,newSeries:[{data:e,divide:QG(e)}]})}else{var u=r.get(o);if(u){var h=n.get(u.key);h||(h={oldSeries:[{data:u.data,divide:QG(u.data)}],newSeries:[]},n.set(u.key,h)),h.newSeries.push({data:e,divide:QG(e)})}}}})),n}(i,n);E(o.keys(),(function(t){var n=o.get(t);KG(n.oldSeries,n.newSeries,e)}))}E(n.updatedSeries,(function(t){t.__universalTransitionEnabled&&(t.__universalTransitionEnabled=!1)}))}for(var a=t.getSeries(),s=i.oldSeries=[],l=i.oldData=[],u=0;ucode{background-color:var(--w-e-textarea-slight-bg-color);border:1px solid var(--w-e-textarea-slight-border-color);border-radius:4px 4px;display:block;font-size:14px;padding:10px;text-indent:0}.w-e-text-container [data-slate-editor] .w-e-image-container{display:inline-block;margin:0 3px}.w-e-text-container [data-slate-editor] .w-e-image-container:hover{box-shadow:0 0 0 2px var(--w-e-textarea-selected-border-color)}.w-e-text-container [data-slate-editor] .w-e-selected-image-container{overflow:hidden;position:relative}.w-e-text-container [data-slate-editor] .w-e-selected-image-container .w-e-image-dragger{background-color:var(--w-e-textarea-handler-bg-color);height:7px;position:absolute;width:7px}.w-e-text-container [data-slate-editor] .w-e-selected-image-container .left-top{cursor:nwse-resize;left:0;top:0}.w-e-text-container [data-slate-editor] .w-e-selected-image-container .right-top{cursor:nesw-resize;right:0;top:0}.w-e-text-container [data-slate-editor] .w-e-selected-image-container .left-bottom{bottom:0;cursor:nesw-resize;left:0}.w-e-text-container [data-slate-editor] .w-e-selected-image-container .right-bottom{bottom:0;cursor:nwse-resize;right:0}.w-e-text-container [data-slate-editor] .w-e-selected-image-container:hover{box-shadow:none}.w-e-text-container [contenteditable=false] .w-e-image-container:hover{box-shadow:none} + +.w-e-text-container [data-slate-editor] .table-container{border:1px dashed var(--w-e-textarea-border-color);border-radius:5px;margin-top:10px;overflow-x:auto;padding:10px;width:100%}.w-e-text-container [data-slate-editor] table{border-collapse:collapse}.w-e-text-container [data-slate-editor] table td,.w-e-text-container [data-slate-editor] table th{border:1px solid var(--w-e-textarea-border-color);line-height:1.5;min-width:30px;padding:3px 5px;text-align:left}.w-e-text-container [data-slate-editor] table th{background-color:var(--w-e-textarea-slight-bg-color);font-weight:700;text-align:center}.w-e-panel-content-table{background-color:var(--w-e-toolbar-bg-color)}.w-e-panel-content-table table{border-collapse:collapse}.w-e-panel-content-table td{border:1px solid var(--w-e-toolbar-border-color);cursor:pointer;height:15px;padding:3px 5px;width:20px}.w-e-panel-content-table td.active{background-color:var(--w-e-toolbar-active-bg-color)} +.w-e-textarea-video-container{background-image:linear-gradient(45deg,#eee 25%,transparent 0,transparent 75%,#eee 0,#eee),linear-gradient(45deg,#eee 25%,#fff 0,#fff 75%,#eee 0,#eee);background-position:0 0,10px 10px;background-size:20px 20px;border:1px dashed var(--w-e-textarea-border-color);border-radius:5px;margin:10px auto 0;padding:10px 0;text-align:center} + +.w-e-text-container [data-slate-editor] pre>code{word-wrap:normal;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;-webkit-hyphens:none;hyphens:none;line-height:1.5;margin:.5em 0;overflow:auto;padding:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;text-align:left;text-shadow:0 1px #fff;white-space:pre;word-break:normal;word-spacing:normal}.w-e-text-container [data-slate-editor] pre>code .token.cdata,.w-e-text-container [data-slate-editor] pre>code .token.comment,.w-e-text-container [data-slate-editor] pre>code .token.doctype,.w-e-text-container [data-slate-editor] pre>code .token.prolog{color:#708090}.w-e-text-container [data-slate-editor] pre>code .token.punctuation{color:#999}.w-e-text-container [data-slate-editor] pre>code .token.namespace{opacity:.7}.w-e-text-container [data-slate-editor] pre>code .token.boolean,.w-e-text-container [data-slate-editor] pre>code .token.constant,.w-e-text-container [data-slate-editor] pre>code .token.deleted,.w-e-text-container [data-slate-editor] pre>code .token.number,.w-e-text-container [data-slate-editor] pre>code .token.property,.w-e-text-container [data-slate-editor] pre>code .token.symbol,.w-e-text-container [data-slate-editor] pre>code .token.tag{color:#905}.w-e-text-container [data-slate-editor] pre>code .token.attr-name,.w-e-text-container [data-slate-editor] pre>code .token.builtin,.w-e-text-container [data-slate-editor] pre>code .token.char,.w-e-text-container [data-slate-editor] pre>code .token.inserted,.w-e-text-container [data-slate-editor] pre>code .token.selector,.w-e-text-container [data-slate-editor] pre>code .token.string{color:#690}.w-e-text-container [data-slate-editor] pre>code .language-css .token.string,.w-e-text-container [data-slate-editor] pre>code .style .token.string,.w-e-text-container [data-slate-editor] pre>code .token.entity,.w-e-text-container [data-slate-editor] pre>code .token.operator,.w-e-text-container [data-slate-editor] pre>code .token.url{color:#9a6e3a}.w-e-text-container [data-slate-editor] pre>code .token.atrule,.w-e-text-container [data-slate-editor] pre>code .token.attr-value,.w-e-text-container [data-slate-editor] pre>code .token.keyword{color:#07a}.w-e-text-container [data-slate-editor] pre>code .token.class-name,.w-e-text-container [data-slate-editor] pre>code .token.function{color:#dd4a68}.w-e-text-container [data-slate-editor] pre>code .token.important,.w-e-text-container [data-slate-editor] pre>code .token.regex,.w-e-text-container [data-slate-editor] pre>code .token.variable{color:#e90}.w-e-text-container [data-slate-editor] pre>code .token.bold,.w-e-text-container [data-slate-editor] pre>code .token.important{font-weight:700}.w-e-text-container [data-slate-editor] pre>code .token.italic{font-style:italic}.w-e-text-container [data-slate-editor] pre>code .token.entity{cursor:help} \ No newline at end of file diff --git a/dash-fastapi-frontend/assets/wangeditor/index.js b/dash-fastapi-frontend/assets/wangeditor/index.js new file mode 100644 index 0000000000000000000000000000000000000000..a2233e40ddef7a2c11feef29687b3c9566a23125 --- /dev/null +++ b/dash-fastapi-frontend/assets/wangeditor/index.js @@ -0,0 +1,24129 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.wangEditor = {})); +})(this, (function (exports) { 'use strict'; + + /** + * @description browser polyfill + * @author wangfupeng + */ + var _a; + // @ts-nocheck + // 必须是浏览器环境 + if (typeof global === 'undefined') { + // 检查 IE 浏览器 + if ('ActiveXObject' in window) { + var info = '抱歉,wangEditor V5+ 版本开始,不在支持 IE 浏览器'; + info += '\n Sorry, wangEditor V5+ versions do not support IE browser.'; + console.error(info); + } + globalThisPolyfill(); + AggregateErrorPolyfill(); + } + else if (global && ((_a = global.navigator) === null || _a === void 0 ? void 0 : _a.userAgent.match('QQBrowser'))) { + // 兼容 QQ 浏览器 AggregateError 报错 + globalThisPolyfill(); + AggregateErrorPolyfill(); + } + function globalThisPolyfill() { + // 部分浏览器不支持 globalThis + if (typeof globalThis === 'undefined') { + // @ts-ignore + window.globalThis = window; + } + } + function AggregateErrorPolyfill() { + if (typeof AggregateError === 'undefined') { + window.AggregateError = function (errors, msg) { + var err = new Error(msg); + err.errors = errors; + return err; + }; + } + } + + /** + * @description node polyfill + * @author wangfupeng + */ + // @ts-nocheck + // 必须是 node 环境 + if (typeof global === 'object') { + // 用于 nodejs ,避免报错 + var globalProperty = Object.getOwnPropertyDescriptor(global, 'window'); + // global.window 为空则直接写入 + // 部分框架下已经定义了global.window且是不可写属性 + if (!global.window || globalProperty.set) { + global.window = global; + global.requestAnimationFrame = function () { }; + global.navigator = { + userAgent: '', + }; + global.location = { + hostname: '0.0.0.0', + port: 0, + protocol: 'http:', + }; + global.btoa = function () { }; + global.crypto = { + getRandomValues: function (buffer) { + return nodeCrypto.randomFillSync(buffer); + }, + }; + } + if (global.document != null) { + // SSR 环境下可能会报错 (issue 4409) + if (global.document.getElementsByTagName == null) { + global.document.getElementsByTagName = function () { return []; }; + } + } + } + + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createCommonjsModule$1(fn) { + var module = { exports: {} }; + return fn(module, module.exports), module.exports; + } + + /*! + * is-plain-object + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ + + function isObject$4(o) { + return Object.prototype.toString.call(o) === '[object Object]'; + } + + function isPlainObject$2(o) { + var ctor,prot; + + if (isObject$4(o) === false) return false; + + // If has modified constructor + ctor = o.constructor; + if (ctor === undefined) return true; + + // If has modified prototype + prot = ctor.prototype; + if (isObject$4(prot) === false) return false; + + // If constructor does not have an Object-specific method + if (prot.hasOwnProperty('isPrototypeOf') === false) { + return false; + } + + // Most likely a plain Object + return true; + } + + var isPlainObject_2 = isPlainObject$2; + + var isPlainObject_1 = /*#__PURE__*/Object.defineProperty({ + isPlainObject: isPlainObject_2 + }, '__esModule', {value: true}); + + var _ref; + + // Should be no imports here! + // Some things that should be evaluated before all else... + // We only want to know if non-polyfilled symbols are available + var hasSymbol = typeof Symbol !== "undefined" && typeof + /*#__PURE__*/ + Symbol("x") === "symbol"; + var hasMap = typeof Map !== "undefined"; + var hasSet = typeof Set !== "undefined"; + var hasProxies = typeof Proxy !== "undefined" && typeof Proxy.revocable !== "undefined" && typeof Reflect !== "undefined"; + /** + * The sentinel value returned by producers to replace the draft with undefined. + */ + + var NOTHING = hasSymbol ? + /*#__PURE__*/ + Symbol.for("immer-nothing") : (_ref = {}, _ref["immer-nothing"] = true, _ref); + /** + * To let Immer treat your class instances as plain immutable objects + * (albeit with a custom prototype), you must define either an instance property + * or a static property on each of your custom classes. + * + * Otherwise, your class instance will never be drafted, which means it won't be + * safe to mutate in a produce callback. + */ + + var DRAFTABLE = hasSymbol ? + /*#__PURE__*/ + Symbol.for("immer-draftable") : "__$immer_draftable"; + var DRAFT_STATE = hasSymbol ? + /*#__PURE__*/ + Symbol.for("immer-state") : "__$immer_state"; // Even a polyfilled Symbol might provide Symbol.iterator + + var iteratorSymbol$1 = typeof Symbol != "undefined" && Symbol.iterator || "@@iterator"; + + var errors = { + 0: "Illegal state", + 1: "Immer drafts cannot have computed properties", + 2: "This object has been frozen and should not be mutated", + 3: function _(data) { + return "Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? " + data; + }, + 4: "An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.", + 5: "Immer forbids circular references", + 6: "The first or second argument to `produce` must be a function", + 7: "The third argument to `produce` must be a function or undefined", + 8: "First argument to `createDraft` must be a plain object, an array, or an immerable object", + 9: "First argument to `finishDraft` must be a draft returned by `createDraft`", + 10: "The given draft is already finalized", + 11: "Object.defineProperty() cannot be used on an Immer draft", + 12: "Object.setPrototypeOf() cannot be used on an Immer draft", + 13: "Immer only supports deleting array indices", + 14: "Immer only supports setting array indices and the 'length' property", + 15: function _(path) { + return "Cannot apply patch, path doesn't resolve: " + path; + }, + 16: 'Sets cannot have "replace" patches.', + 17: function _(op) { + return "Unsupported patch operation: " + op; + }, + 18: function _(plugin) { + return "The plugin for '" + plugin + "' has not been loaded into Immer. To enable the plugin, import and call `enable" + plugin + "()` when initializing your application."; + }, + 20: "Cannot use proxies if Proxy, Proxy.revocable or Reflect are not available", + 21: function _(thing) { + return "produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '" + thing + "'"; + }, + 22: function _(thing) { + return "'current' expects a draft, got: " + thing; + }, + 23: function _(thing) { + return "'original' expects a draft, got: " + thing; + }, + 24: "Patching reserved attributes like __proto__, prototype and constructor is not allowed" + }; + function die(error) { + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + { + var e = errors[error]; + var msg = !e ? "unknown error nr: " + error : typeof e === "function" ? e.apply(null, args) : e; + throw new Error("[Immer] " + msg); + } + } + + /** Returns true if the given value is an Immer draft */ + + + + function isDraft(value) { + return !!value && !!value[DRAFT_STATE]; + } + /** Returns true if the given value can be drafted by Immer */ + + + + function isDraftable(value) { + if (!value) return false; + return isPlainObject$1(value) || Array.isArray(value) || !!value[DRAFTABLE] || !!value.constructor[DRAFTABLE] || isMap(value) || isSet(value); + } + var objectCtorString = + /*#__PURE__*/ + Object.prototype.constructor.toString(); + + + function isPlainObject$1(value) { + if (!value || typeof value !== "object") return false; + var proto = Object.getPrototypeOf(value); + + if (proto === null) { + return true; + } + + var Ctor = Object.hasOwnProperty.call(proto, "constructor") && proto.constructor; + if (Ctor === Object) return true; + return typeof Ctor == "function" && Function.toString.call(Ctor) === objectCtorString; + } + function original(value) { + if (!isDraft(value)) die(23, value); + return value[DRAFT_STATE].base_; + } + + + var ownKeys$a = typeof Reflect !== "undefined" && Reflect.ownKeys ? Reflect.ownKeys : typeof Object.getOwnPropertySymbols !== "undefined" ? function (obj) { + return Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(obj)); + } : + /* istanbul ignore next */ + Object.getOwnPropertyNames; + var getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors || function getOwnPropertyDescriptors(target) { + // Polyfill needed for Hermes and IE, see https://github.com/facebook/hermes/issues/274 + var res = {}; + ownKeys$a(target).forEach(function (key) { + res[key] = Object.getOwnPropertyDescriptor(target, key); + }); + return res; + }; + function each$1(obj, iter, enumerableOnly) { + if (enumerableOnly === void 0) { + enumerableOnly = false; + } + + if (getArchtype(obj) === 0 + /* Object */ + ) { + (enumerableOnly ? Object.keys : ownKeys$a)(obj).forEach(function (key) { + if (!enumerableOnly || typeof key !== "symbol") iter(key, obj[key], obj); + }); + } else { + obj.forEach(function (entry, index) { + return iter(index, entry, obj); + }); + } + } + + + function getArchtype(thing) { + /* istanbul ignore next */ + var state = thing[DRAFT_STATE]; + return state ? state.type_ > 3 ? state.type_ - 4 // cause Object and Array map back from 4 and 5 + : state.type_ // others are the same + : Array.isArray(thing) ? 1 + /* Array */ + : isMap(thing) ? 2 + /* Map */ + : isSet(thing) ? 3 + /* Set */ + : 0 + /* Object */ + ; + } + + + function has(thing, prop) { + return getArchtype(thing) === 2 + /* Map */ + ? thing.has(prop) : Object.prototype.hasOwnProperty.call(thing, prop); + } + + + function get(thing, prop) { + // @ts-ignore + return getArchtype(thing) === 2 + /* Map */ + ? thing.get(prop) : thing[prop]; + } + + + function set(thing, propOrOldValue, value) { + var t = getArchtype(thing); + if (t === 2 + /* Map */ + ) thing.set(propOrOldValue, value);else if (t === 3 + /* Set */ + ) { + thing.delete(propOrOldValue); + thing.add(value); + } else thing[propOrOldValue] = value; + } + + + function is$1(x, y) { + // From: https://github.com/facebook/fbjs/blob/c69904a511b900266935168223063dd8772dfc40/packages/fbjs/src/core/shallowEqual.js + if (x === y) { + return x !== 0 || 1 / x === 1 / y; + } else { + return x !== x && y !== y; + } + } + + + function isMap(target) { + return hasMap && target instanceof Map; + } + + + function isSet(target) { + return hasSet && target instanceof Set; + } + + + function latest(state) { + return state.copy_ || state.base_; + } + + + function shallowCopy(base) { + if (Array.isArray(base)) return Array.prototype.slice.call(base); + var descriptors = getOwnPropertyDescriptors(base); + delete descriptors[DRAFT_STATE]; + var keys = ownKeys$a(descriptors); + + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var desc = descriptors[key]; + + if (desc.writable === false) { + desc.writable = true; + desc.configurable = true; + } // like object.assign, we will read any _own_, get/set accessors. This helps in dealing + // with libraries that trap values, like mobx or vue + // unlike object.assign, non-enumerables will be copied as well + + + if (desc.get || desc.set) descriptors[key] = { + configurable: true, + writable: true, + enumerable: desc.enumerable, + value: base[key] + }; + } + + return Object.create(Object.getPrototypeOf(base), descriptors); + } + function freeze(obj, deep) { + if (deep === void 0) { + deep = false; + } + + if (isFrozen(obj) || isDraft(obj) || !isDraftable(obj)) return obj; + + if (getArchtype(obj) > 1 + /* Map or Set */ + ) { + obj.set = obj.add = obj.clear = obj.delete = dontMutateFrozenCollections; + } + + Object.freeze(obj); + if (deep) each$1(obj, function (key, value) { + return freeze(value, true); + }, true); + return obj; + } + + function dontMutateFrozenCollections() { + die(2); + } + + function isFrozen(obj) { + if (obj == null || typeof obj !== "object") return true; // See #600, IE dies on non-objects in Object.isFrozen + + return Object.isFrozen(obj); + } + + /** Plugin utilities */ + + var plugins = {}; + function getPlugin(pluginKey) { + var plugin = plugins[pluginKey]; + + if (!plugin) { + die(18, pluginKey); + } // @ts-ignore + + + return plugin; + } + function loadPlugin(pluginKey, implementation) { + if (!plugins[pluginKey]) plugins[pluginKey] = implementation; + } + + var currentScope; + function getCurrentScope() { + if ( !currentScope) die(0); + return currentScope; + } + + function createScope(parent_, immer_) { + return { + drafts_: [], + parent_: parent_, + immer_: immer_, + // Whenever the modified draft contains a draft from another scope, we + // need to prevent auto-freezing so the unowned draft can be finalized. + canAutoFreeze_: true, + unfinalizedDrafts_: 0 + }; + } + + function usePatchesInScope(scope, patchListener) { + if (patchListener) { + getPlugin("Patches"); // assert we have the plugin + + scope.patches_ = []; + scope.inversePatches_ = []; + scope.patchListener_ = patchListener; + } + } + function revokeScope(scope) { + leaveScope(scope); + scope.drafts_.forEach(revokeDraft); // @ts-ignore + + scope.drafts_ = null; + } + function leaveScope(scope) { + if (scope === currentScope) { + currentScope = scope.parent_; + } + } + function enterScope(immer) { + return currentScope = createScope(currentScope, immer); + } + + function revokeDraft(draft) { + var state = draft[DRAFT_STATE]; + if (state.type_ === 0 + /* ProxyObject */ + || state.type_ === 1 + /* ProxyArray */ + ) state.revoke_();else state.revoked_ = true; + } + + function processResult(result, scope) { + scope.unfinalizedDrafts_ = scope.drafts_.length; + var baseDraft = scope.drafts_[0]; + var isReplaced = result !== undefined && result !== baseDraft; + if (!scope.immer_.useProxies_) getPlugin("ES5").willFinalizeES5_(scope, result, isReplaced); + + if (isReplaced) { + if (baseDraft[DRAFT_STATE].modified_) { + revokeScope(scope); + die(4); + } + + if (isDraftable(result)) { + // Finalize the result in case it contains (or is) a subset of the draft. + result = finalize(scope, result); + if (!scope.parent_) maybeFreeze(scope, result); + } + + if (scope.patches_) { + getPlugin("Patches").generateReplacementPatches_(baseDraft[DRAFT_STATE], result, scope.patches_, scope.inversePatches_); + } + } else { + // Finalize the base draft. + result = finalize(scope, baseDraft, []); + } + + revokeScope(scope); + + if (scope.patches_) { + scope.patchListener_(scope.patches_, scope.inversePatches_); + } + + return result !== NOTHING ? result : undefined; + } + + function finalize(rootScope, value, path) { + // Don't recurse in tho recursive data structures + if (isFrozen(value)) return value; + var state = value[DRAFT_STATE]; // A plain object, might need freezing, might contain drafts + + if (!state) { + each$1(value, function (key, childValue) { + return finalizeProperty(rootScope, state, value, key, childValue, path); + }, true // See #590, don't recurse into non-enumerable of non drafted objects + ); + return value; + } // Never finalize drafts owned by another scope. + + + if (state.scope_ !== rootScope) return value; // Unmodified draft, return the (frozen) original + + if (!state.modified_) { + maybeFreeze(rootScope, state.base_, true); + return state.base_; + } // Not finalized yet, let's do that now + + + if (!state.finalized_) { + state.finalized_ = true; + state.scope_.unfinalizedDrafts_--; + var result = // For ES5, create a good copy from the draft first, with added keys and without deleted keys. + state.type_ === 4 + /* ES5Object */ + || state.type_ === 5 + /* ES5Array */ + ? state.copy_ = shallowCopy(state.draft_) : state.copy_; // Finalize all children of the copy + // For sets we clone before iterating, otherwise we can get in endless loop due to modifying during iteration, see #628 + // Although the original test case doesn't seem valid anyway, so if this in the way we can turn the next line + // back to each(result, ....) + + each$1(state.type_ === 3 + /* Set */ + ? new Set(result) : result, function (key, childValue) { + return finalizeProperty(rootScope, state, result, key, childValue, path); + }); // everything inside is frozen, we can freeze here + + maybeFreeze(rootScope, result, false); // first time finalizing, let's create those patches + + if (path && rootScope.patches_) { + getPlugin("Patches").generatePatches_(state, path, rootScope.patches_, rootScope.inversePatches_); + } + } + + return state.copy_; + } + + function finalizeProperty(rootScope, parentState, targetObject, prop, childValue, rootPath) { + if ( childValue === targetObject) die(5); + + if (isDraft(childValue)) { + var path = rootPath && parentState && parentState.type_ !== 3 + /* Set */ + && // Set objects are atomic since they have no keys. + !has(parentState.assigned_, prop) // Skip deep patches for assigned keys. + ? rootPath.concat(prop) : undefined; // Drafts owned by `scope` are finalized here. + + var res = finalize(rootScope, childValue, path); + set(targetObject, prop, res); // Drafts from another scope must prevented to be frozen + // if we got a draft back from finalize, we're in a nested produce and shouldn't freeze + + if (isDraft(res)) { + rootScope.canAutoFreeze_ = false; + } else return; + } // Search new objects for unfinalized drafts. Frozen objects should never contain drafts. + + + if (isDraftable(childValue) && !isFrozen(childValue)) { + if (!rootScope.immer_.autoFreeze_ && rootScope.unfinalizedDrafts_ < 1) { + // optimization: if an object is not a draft, and we don't have to + // deepfreeze everything, and we are sure that no drafts are left in the remaining object + // cause we saw and finalized all drafts already; we can stop visiting the rest of the tree. + // This benefits especially adding large data tree's without further processing. + // See add-data.js perf test + return; + } + + finalize(rootScope, childValue); // immer deep freezes plain objects, so if there is no parent state, we freeze as well + + if (!parentState || !parentState.scope_.parent_) maybeFreeze(rootScope, childValue); + } + } + + function maybeFreeze(scope, value, deep) { + if (deep === void 0) { + deep = false; + } + + if (scope.immer_.autoFreeze_ && scope.canAutoFreeze_) { + freeze(value, deep); + } + } + + /** + * Returns a new draft of the `base` object. + * + * The second argument is the parent draft-state (used internally). + */ + + function createProxyProxy(base, parent) { + var isArray = Array.isArray(base); + var state = { + type_: isArray ? 1 + /* ProxyArray */ + : 0 + /* ProxyObject */ + , + // Track which produce call this is associated with. + scope_: parent ? parent.scope_ : getCurrentScope(), + // True for both shallow and deep changes. + modified_: false, + // Used during finalization. + finalized_: false, + // Track which properties have been assigned (true) or deleted (false). + assigned_: {}, + // The parent draft state. + parent_: parent, + // The base state. + base_: base, + // The base proxy. + draft_: null, + // The base copy with any updated values. + copy_: null, + // Called by the `produce` function. + revoke_: null, + isManual_: false + }; // the traps must target something, a bit like the 'real' base. + // but also, we need to be able to determine from the target what the relevant state is + // (to avoid creating traps per instance to capture the state in closure, + // and to avoid creating weird hidden properties as well) + // So the trick is to use 'state' as the actual 'target'! (and make sure we intercept everything) + // Note that in the case of an array, we put the state in an array to have better Reflect defaults ootb + + var target = state; + var traps = objectTraps; + + if (isArray) { + target = [state]; + traps = arrayTraps; + } + + var _Proxy$revocable = Proxy.revocable(target, traps), + revoke = _Proxy$revocable.revoke, + proxy = _Proxy$revocable.proxy; + + state.draft_ = proxy; + state.revoke_ = revoke; + return proxy; + } + /** + * Object drafts + */ + + var objectTraps = { + get: function get(state, prop) { + if (prop === DRAFT_STATE) return state; + var source = latest(state); + + if (!has(source, prop)) { + // non-existing or non-own property... + return readPropFromProto(state, source, prop); + } + + var value = source[prop]; + + if (state.finalized_ || !isDraftable(value)) { + return value; + } // Check for existing draft in modified state. + // Assigned values are never drafted. This catches any drafts we created, too. + + + if (value === peek(state.base_, prop)) { + prepareCopy(state); + return state.copy_[prop] = createProxy(state.scope_.immer_, value, state); + } + + return value; + }, + has: function has(state, prop) { + return prop in latest(state); + }, + ownKeys: function ownKeys(state) { + return Reflect.ownKeys(latest(state)); + }, + set: function set(state, prop + /* strictly not, but helps TS */ + , value) { + var desc = getDescriptorFromProto(latest(state), prop); + + if (desc === null || desc === void 0 ? void 0 : desc.set) { + // special case: if this write is captured by a setter, we have + // to trigger it with the correct context + desc.set.call(state.draft_, value); + return true; + } + + if (!state.modified_) { + // the last check is because we need to be able to distinguish setting a non-existing to undefined (which is a change) + // from setting an existing property with value undefined to undefined (which is not a change) + var current = peek(latest(state), prop); // special case, if we assigning the original value to a draft, we can ignore the assignment + + var currentState = current === null || current === void 0 ? void 0 : current[DRAFT_STATE]; + + if (currentState && currentState.base_ === value) { + state.copy_[prop] = value; + state.assigned_[prop] = false; + return true; + } + + if (is$1(value, current) && (value !== undefined || has(state.base_, prop))) return true; + prepareCopy(state); + markChanged(state); + } + + if (state.copy_[prop] === value && // special case: NaN + typeof value !== "number" && ( // special case: handle new props with value 'undefined' + value !== undefined || prop in state.copy_)) return true; // @ts-ignore + + state.copy_[prop] = value; + state.assigned_[prop] = true; + return true; + }, + deleteProperty: function deleteProperty(state, prop) { + // The `undefined` check is a fast path for pre-existing keys. + if (peek(state.base_, prop) !== undefined || prop in state.base_) { + state.assigned_[prop] = false; + prepareCopy(state); + markChanged(state); + } else { + // if an originally not assigned property was deleted + delete state.assigned_[prop]; + } // @ts-ignore + + + if (state.copy_) delete state.copy_[prop]; + return true; + }, + // Note: We never coerce `desc.value` into an Immer draft, because we can't make + // the same guarantee in ES5 mode. + getOwnPropertyDescriptor: function getOwnPropertyDescriptor(state, prop) { + var owner = latest(state); + var desc = Reflect.getOwnPropertyDescriptor(owner, prop); + if (!desc) return desc; + return { + writable: true, + configurable: state.type_ !== 1 + /* ProxyArray */ + || prop !== "length", + enumerable: desc.enumerable, + value: owner[prop] + }; + }, + defineProperty: function defineProperty() { + die(11); + }, + getPrototypeOf: function getPrototypeOf(state) { + return Object.getPrototypeOf(state.base_); + }, + setPrototypeOf: function setPrototypeOf() { + die(12); + } + }; + /** + * Array drafts + */ + + var arrayTraps = {}; + each$1(objectTraps, function (key, fn) { + // @ts-ignore + arrayTraps[key] = function () { + arguments[0] = arguments[0][0]; + return fn.apply(this, arguments); + }; + }); + + arrayTraps.deleteProperty = function (state, prop) { + if ( isNaN(parseInt(prop))) die(13); + return objectTraps.deleteProperty.call(this, state[0], prop); + }; + + arrayTraps.set = function (state, prop, value) { + if ( prop !== "length" && isNaN(parseInt(prop))) die(14); + return objectTraps.set.call(this, state[0], prop, value, state[0]); + }; // Access a property without creating an Immer draft. + + + function peek(draft, prop) { + var state = draft[DRAFT_STATE]; + var source = state ? latest(state) : draft; + return source[prop]; + } + + function readPropFromProto(state, source, prop) { + var _desc$get; + + var desc = getDescriptorFromProto(source, prop); + return desc ? "value" in desc ? desc.value : // This is a very special case, if the prop is a getter defined by the + // prototype, we should invoke it with the draft as context! + (_desc$get = desc.get) === null || _desc$get === void 0 ? void 0 : _desc$get.call(state.draft_) : undefined; + } + + function getDescriptorFromProto(source, prop) { + // 'in' checks proto! + if (!(prop in source)) return undefined; + var proto = Object.getPrototypeOf(source); + + while (proto) { + var desc = Object.getOwnPropertyDescriptor(proto, prop); + if (desc) return desc; + proto = Object.getPrototypeOf(proto); + } + + return undefined; + } + + function markChanged(state) { + if (!state.modified_) { + state.modified_ = true; + + if (state.parent_) { + markChanged(state.parent_); + } + } + } + function prepareCopy(state) { + if (!state.copy_) { + state.copy_ = shallowCopy(state.base_); + } + } + + var Immer = + /*#__PURE__*/ + function () { + function Immer(config) { + var _this = this; + + this.useProxies_ = hasProxies; + this.autoFreeze_ = true; + /** + * The `produce` function takes a value and a "recipe function" (whose + * return value often depends on the base state). The recipe function is + * free to mutate its first argument however it wants. All mutations are + * only ever applied to a __copy__ of the base state. + * + * Pass only a function to create a "curried producer" which relieves you + * from passing the recipe function every time. + * + * Only plain objects and arrays are made mutable. All other objects are + * considered uncopyable. + * + * Note: This function is __bound__ to its `Immer` instance. + * + * @param {any} base - the initial state + * @param {Function} producer - function that receives a proxy of the base state as first argument and which can be freely modified + * @param {Function} patchListener - optional function that will be called with all the patches produced here + * @returns {any} a new state, or the initial state if nothing was modified + */ + + this.produce = function (base, recipe, patchListener) { + // curried invocation + if (typeof base === "function" && typeof recipe !== "function") { + var defaultBase = recipe; + recipe = base; + var self = _this; + return function curriedProduce(base) { + var _this2 = this; + + if (base === void 0) { + base = defaultBase; + } + + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + return self.produce(base, function (draft) { + var _recipe; + + return (_recipe = recipe).call.apply(_recipe, [_this2, draft].concat(args)); + }); // prettier-ignore + }; + } + + if (typeof recipe !== "function") die(6); + if (patchListener !== undefined && typeof patchListener !== "function") die(7); + var result; // Only plain objects, arrays, and "immerable classes" are drafted. + + if (isDraftable(base)) { + var scope = enterScope(_this); + var proxy = createProxy(_this, base, undefined); + var hasError = true; + + try { + result = recipe(proxy); + hasError = false; + } finally { + // finally instead of catch + rethrow better preserves original stack + if (hasError) revokeScope(scope);else leaveScope(scope); + } + + if (typeof Promise !== "undefined" && result instanceof Promise) { + return result.then(function (result) { + usePatchesInScope(scope, patchListener); + return processResult(result, scope); + }, function (error) { + revokeScope(scope); + throw error; + }); + } + + usePatchesInScope(scope, patchListener); + return processResult(result, scope); + } else if (!base || typeof base !== "object") { + result = recipe(base); + if (result === NOTHING) return undefined; + if (result === undefined) result = base; + if (_this.autoFreeze_) freeze(result, true); + return result; + } else die(21, base); + }; + + this.produceWithPatches = function (arg1, arg2, arg3) { + if (typeof arg1 === "function") { + return function (state) { + for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + args[_key2 - 1] = arguments[_key2]; + } + + return _this.produceWithPatches(state, function (draft) { + return arg1.apply(void 0, [draft].concat(args)); + }); + }; + } + + var patches, inversePatches; + + var nextState = _this.produce(arg1, arg2, function (p, ip) { + patches = p; + inversePatches = ip; + }); + + return [nextState, patches, inversePatches]; + }; + + if (typeof (config === null || config === void 0 ? void 0 : config.useProxies) === "boolean") this.setUseProxies(config.useProxies); + if (typeof (config === null || config === void 0 ? void 0 : config.autoFreeze) === "boolean") this.setAutoFreeze(config.autoFreeze); + } + + var _proto = Immer.prototype; + + _proto.createDraft = function createDraft(base) { + if (!isDraftable(base)) die(8); + if (isDraft(base)) base = current(base); + var scope = enterScope(this); + var proxy = createProxy(this, base, undefined); + proxy[DRAFT_STATE].isManual_ = true; + leaveScope(scope); + return proxy; + }; + + _proto.finishDraft = function finishDraft(draft, patchListener) { + var state = draft && draft[DRAFT_STATE]; + + { + if (!state || !state.isManual_) die(9); + if (state.finalized_) die(10); + } + + var scope = state.scope_; + usePatchesInScope(scope, patchListener); + return processResult(undefined, scope); + } + /** + * Pass true to automatically freeze all copies created by Immer. + * + * By default, auto-freezing is enabled. + */ + ; + + _proto.setAutoFreeze = function setAutoFreeze(value) { + this.autoFreeze_ = value; + } + /** + * Pass true to use the ES2015 `Proxy` class when creating drafts, which is + * always faster than using ES5 proxies. + * + * By default, feature detection is used, so calling this is rarely necessary. + */ + ; + + _proto.setUseProxies = function setUseProxies(value) { + if (value && !hasProxies) { + die(20); + } + + this.useProxies_ = value; + }; + + _proto.applyPatches = function applyPatches(base, patches) { + // If a patch replaces the entire state, take that replacement as base + // before applying patches + var i; + + for (i = patches.length - 1; i >= 0; i--) { + var patch = patches[i]; + + if (patch.path.length === 0 && patch.op === "replace") { + base = patch.value; + break; + } + } // If there was a patch that replaced the entire state, start from the + // patch after that. + + + if (i > -1) { + patches = patches.slice(i + 1); + } + + var applyPatchesImpl = getPlugin("Patches").applyPatches_; + + if (isDraft(base)) { + // N.B: never hits if some patch a replacement, patches are never drafts + return applyPatchesImpl(base, patches); + } // Otherwise, produce a copy of the base state. + + + return this.produce(base, function (draft) { + return applyPatchesImpl(draft, patches); + }); + }; + + return Immer; + }(); + function createProxy(immer, value, parent) { + // precondition: createProxy should be guarded by isDraftable, so we know we can safely draft + var draft = isMap(value) ? getPlugin("MapSet").proxyMap_(value, parent) : isSet(value) ? getPlugin("MapSet").proxySet_(value, parent) : immer.useProxies_ ? createProxyProxy(value, parent) : getPlugin("ES5").createES5Proxy_(value, parent); + var scope = parent ? parent.scope_ : getCurrentScope(); + scope.drafts_.push(draft); + return draft; + } + + function current(value) { + if (!isDraft(value)) die(22, value); + return currentImpl(value); + } + + function currentImpl(value) { + if (!isDraftable(value)) return value; + var state = value[DRAFT_STATE]; + var copy; + var archType = getArchtype(value); + + if (state) { + if (!state.modified_ && (state.type_ < 4 || !getPlugin("ES5").hasChanges_(state))) return state.base_; // Optimization: avoid generating new drafts during copying + + state.finalized_ = true; + copy = copyHelper(value, archType); + state.finalized_ = false; + } else { + copy = copyHelper(value, archType); + } + + each$1(copy, function (key, childValue) { + if (state && get(state.base_, key) === childValue) return; // no need to copy or search in something that didn't change + + set(copy, key, currentImpl(childValue)); + }); // In the future, we might consider freezing here, based on the current settings + + return archType === 3 + /* Set */ + ? new Set(copy) : copy; + } + + function copyHelper(value, archType) { + // creates a shallow copy, even if it is a map or set + switch (archType) { + case 2 + /* Map */ + : + return new Map(value); + + case 3 + /* Set */ + : + // Set will be cloned as array temporarily, so that we can replace individual items + return Array.from(value); + } + + return shallowCopy(value); + } + + function enableES5() { + function willFinalizeES5_(scope, result, isReplaced) { + if (!isReplaced) { + if (scope.patches_) { + markChangesRecursively(scope.drafts_[0]); + } // This is faster when we don't care about which attributes changed. + + + markChangesSweep(scope.drafts_); + } // When a child draft is returned, look for changes. + else if (isDraft(result) && result[DRAFT_STATE].scope_ === scope) { + markChangesSweep(scope.drafts_); + } + } + + function createES5Draft(isArray, base) { + if (isArray) { + var draft = new Array(base.length); + + for (var i = 0; i < base.length; i++) { + Object.defineProperty(draft, "" + i, proxyProperty(i, true)); + } + + return draft; + } else { + var _descriptors = getOwnPropertyDescriptors(base); + + delete _descriptors[DRAFT_STATE]; + var keys = ownKeys$a(_descriptors); + + for (var _i = 0; _i < keys.length; _i++) { + var key = keys[_i]; + _descriptors[key] = proxyProperty(key, isArray || !!_descriptors[key].enumerable); + } + + return Object.create(Object.getPrototypeOf(base), _descriptors); + } + } + + function createES5Proxy_(base, parent) { + var isArray = Array.isArray(base); + var draft = createES5Draft(isArray, base); + var state = { + type_: isArray ? 5 + /* ES5Array */ + : 4 + /* ES5Object */ + , + scope_: parent ? parent.scope_ : getCurrentScope(), + modified_: false, + finalized_: false, + assigned_: {}, + parent_: parent, + // base is the object we are drafting + base_: base, + // draft is the draft object itself, that traps all reads and reads from either the base (if unmodified) or copy (if modified) + draft_: draft, + copy_: null, + revoked_: false, + isManual_: false + }; + Object.defineProperty(draft, DRAFT_STATE, { + value: state, + // enumerable: false <- the default + writable: true + }); + return draft; + } // property descriptors are recycled to make sure we don't create a get and set closure per property, + // but share them all instead + + + var descriptors = {}; + + function proxyProperty(prop, enumerable) { + var desc = descriptors[prop]; + + if (desc) { + desc.enumerable = enumerable; + } else { + descriptors[prop] = desc = { + configurable: true, + enumerable: enumerable, + get: function get() { + var state = this[DRAFT_STATE]; + assertUnrevoked(state); // @ts-ignore + + return objectTraps.get(state, prop); + }, + set: function set(value) { + var state = this[DRAFT_STATE]; + assertUnrevoked(state); // @ts-ignore + + objectTraps.set(state, prop, value); + } + }; + } + + return desc; + } // This looks expensive, but only proxies are visited, and only objects without known changes are scanned. + + + function markChangesSweep(drafts) { + // The natural order of drafts in the `scope` array is based on when they + // were accessed. By processing drafts in reverse natural order, we have a + // better chance of processing leaf nodes first. When a leaf node is known to + // have changed, we can avoid any traversal of its ancestor nodes. + for (var i = drafts.length - 1; i >= 0; i--) { + var state = drafts[i][DRAFT_STATE]; + + if (!state.modified_) { + switch (state.type_) { + case 5 + /* ES5Array */ + : + if (hasArrayChanges(state)) markChanged(state); + break; + + case 4 + /* ES5Object */ + : + if (hasObjectChanges(state)) markChanged(state); + break; + } + } + } + } + + function markChangesRecursively(object) { + if (!object || typeof object !== "object") return; + var state = object[DRAFT_STATE]; + if (!state) return; + var base_ = state.base_, + draft_ = state.draft_, + assigned_ = state.assigned_, + type_ = state.type_; + + if (type_ === 4 + /* ES5Object */ + ) { + // Look for added keys. + // probably there is a faster way to detect changes, as sweep + recurse seems to do some + // unnecessary work. + // also: probably we can store the information we detect here, to speed up tree finalization! + each$1(draft_, function (key) { + if (key === DRAFT_STATE) return; // The `undefined` check is a fast path for pre-existing keys. + + if (base_[key] === undefined && !has(base_, key)) { + assigned_[key] = true; + markChanged(state); + } else if (!assigned_[key]) { + // Only untouched properties trigger recursion. + markChangesRecursively(draft_[key]); + } + }); // Look for removed keys. + + each$1(base_, function (key) { + // The `undefined` check is a fast path for pre-existing keys. + if (draft_[key] === undefined && !has(draft_, key)) { + assigned_[key] = false; + markChanged(state); + } + }); + } else if (type_ === 5 + /* ES5Array */ + ) { + if (hasArrayChanges(state)) { + markChanged(state); + assigned_.length = true; + } + + if (draft_.length < base_.length) { + for (var i = draft_.length; i < base_.length; i++) { + assigned_[i] = false; + } + } else { + for (var _i2 = base_.length; _i2 < draft_.length; _i2++) { + assigned_[_i2] = true; + } + } // Minimum count is enough, the other parts has been processed. + + + var min = Math.min(draft_.length, base_.length); + + for (var _i3 = 0; _i3 < min; _i3++) { + // Only untouched indices trigger recursion. + if (assigned_[_i3] === undefined) markChangesRecursively(draft_[_i3]); + } + } + } + + function hasObjectChanges(state) { + var base_ = state.base_, + draft_ = state.draft_; // Search for added keys and changed keys. Start at the back, because + // non-numeric keys are ordered by time of definition on the object. + + var keys = ownKeys$a(draft_); + + for (var i = keys.length - 1; i >= 0; i--) { + var key = keys[i]; + if (key === DRAFT_STATE) continue; + var baseValue = base_[key]; // The `undefined` check is a fast path for pre-existing keys. + + if (baseValue === undefined && !has(base_, key)) { + return true; + } // Once a base key is deleted, future changes go undetected, because its + // descriptor is erased. This branch detects any missed changes. + else { + var value = draft_[key]; + + var _state = value && value[DRAFT_STATE]; + + if (_state ? _state.base_ !== baseValue : !is$1(value, baseValue)) { + return true; + } + } + } // At this point, no keys were added or changed. + // Compare key count to determine if keys were deleted. + + + var baseIsDraft = !!base_[DRAFT_STATE]; + return keys.length !== ownKeys$a(base_).length + (baseIsDraft ? 0 : 1); // + 1 to correct for DRAFT_STATE + } + + function hasArrayChanges(state) { + var draft_ = state.draft_; + if (draft_.length !== state.base_.length) return true; // See #116 + // If we first shorten the length, our array interceptors will be removed. + // If after that new items are added, result in the same original length, + // those last items will have no intercepting property. + // So if there is no own descriptor on the last position, we know that items were removed and added + // N.B.: splice, unshift, etc only shift values around, but not prop descriptors, so we only have to check + // the last one + + var descriptor = Object.getOwnPropertyDescriptor(draft_, draft_.length - 1); // descriptor can be null, but only for newly created sparse arrays, eg. new Array(10) + + if (descriptor && !descriptor.get) return true; // For all other cases, we don't have to compare, as they would have been picked up by the index setters + + return false; + } + + function hasChanges_(state) { + return state.type_ === 4 + /* ES5Object */ + ? hasObjectChanges(state) : hasArrayChanges(state); + } + + function assertUnrevoked(state + /*ES5State | MapState | SetState*/ + ) { + if (state.revoked_) die(3, JSON.stringify(latest(state))); + } + + loadPlugin("ES5", { + createES5Proxy_: createES5Proxy_, + willFinalizeES5_: willFinalizeES5_, + hasChanges_: hasChanges_ + }); + } + + function enablePatches() { + var REPLACE = "replace"; + var ADD = "add"; + var REMOVE = "remove"; + + function generatePatches_(state, basePath, patches, inversePatches) { + switch (state.type_) { + case 0 + /* ProxyObject */ + : + case 4 + /* ES5Object */ + : + case 2 + /* Map */ + : + return generatePatchesFromAssigned(state, basePath, patches, inversePatches); + + case 5 + /* ES5Array */ + : + case 1 + /* ProxyArray */ + : + return generateArrayPatches(state, basePath, patches, inversePatches); + + case 3 + /* Set */ + : + return generateSetPatches(state, basePath, patches, inversePatches); + } + } + + function generateArrayPatches(state, basePath, patches, inversePatches) { + var base_ = state.base_, + assigned_ = state.assigned_; + var copy_ = state.copy_; // Reduce complexity by ensuring `base` is never longer. + + if (copy_.length < base_.length) { + var _ref = [copy_, base_]; + base_ = _ref[0]; + copy_ = _ref[1]; + var _ref2 = [inversePatches, patches]; + patches = _ref2[0]; + inversePatches = _ref2[1]; + } // Process replaced indices. + + + for (var i = 0; i < base_.length; i++) { + if (assigned_[i] && copy_[i] !== base_[i]) { + var path = basePath.concat([i]); + patches.push({ + op: REPLACE, + path: path, + // Need to maybe clone it, as it can in fact be the original value + // due to the base/copy inversion at the start of this function + value: clonePatchValueIfNeeded(copy_[i]) + }); + inversePatches.push({ + op: REPLACE, + path: path, + value: clonePatchValueIfNeeded(base_[i]) + }); + } + } // Process added indices. + + + for (var _i = base_.length; _i < copy_.length; _i++) { + var _path = basePath.concat([_i]); + + patches.push({ + op: ADD, + path: _path, + // Need to maybe clone it, as it can in fact be the original value + // due to the base/copy inversion at the start of this function + value: clonePatchValueIfNeeded(copy_[_i]) + }); + } + + if (base_.length < copy_.length) { + inversePatches.push({ + op: REPLACE, + path: basePath.concat(["length"]), + value: base_.length + }); + } + } // This is used for both Map objects and normal objects. + + + function generatePatchesFromAssigned(state, basePath, patches, inversePatches) { + var base_ = state.base_, + copy_ = state.copy_; + each$1(state.assigned_, function (key, assignedValue) { + var origValue = get(base_, key); + var value = get(copy_, key); + var op = !assignedValue ? REMOVE : has(base_, key) ? REPLACE : ADD; + if (origValue === value && op === REPLACE) return; + var path = basePath.concat(key); + patches.push(op === REMOVE ? { + op: op, + path: path + } : { + op: op, + path: path, + value: value + }); + inversePatches.push(op === ADD ? { + op: REMOVE, + path: path + } : op === REMOVE ? { + op: ADD, + path: path, + value: clonePatchValueIfNeeded(origValue) + } : { + op: REPLACE, + path: path, + value: clonePatchValueIfNeeded(origValue) + }); + }); + } + + function generateSetPatches(state, basePath, patches, inversePatches) { + var base_ = state.base_, + copy_ = state.copy_; + var i = 0; + base_.forEach(function (value) { + if (!copy_.has(value)) { + var path = basePath.concat([i]); + patches.push({ + op: REMOVE, + path: path, + value: value + }); + inversePatches.unshift({ + op: ADD, + path: path, + value: value + }); + } + + i++; + }); + i = 0; + copy_.forEach(function (value) { + if (!base_.has(value)) { + var path = basePath.concat([i]); + patches.push({ + op: ADD, + path: path, + value: value + }); + inversePatches.unshift({ + op: REMOVE, + path: path, + value: value + }); + } + + i++; + }); + } + + function generateReplacementPatches_(rootState, replacement, patches, inversePatches) { + patches.push({ + op: REPLACE, + path: [], + value: replacement === NOTHING ? undefined : replacement + }); + inversePatches.push({ + op: REPLACE, + path: [], + value: rootState.base_ + }); + } + + function applyPatches_(draft, patches) { + patches.forEach(function (patch) { + var path = patch.path, + op = patch.op; + var base = draft; + + for (var i = 0; i < path.length - 1; i++) { + var parentType = getArchtype(base); + var p = "" + path[i]; // See #738, avoid prototype pollution + + if ((parentType === 0 + /* Object */ + || parentType === 1 + /* Array */ + ) && (p === "__proto__" || p === "constructor")) die(24); + if (typeof base === "function" && p === "prototype") die(24); + base = get(base, p); + if (typeof base !== "object") die(15, path.join("/")); + } + + var type = getArchtype(base); + var value = deepClonePatchValue(patch.value); // used to clone patch to ensure original patch is not modified, see #411 + + var key = path[path.length - 1]; + + switch (op) { + case REPLACE: + switch (type) { + case 2 + /* Map */ + : + return base.set(key, value); + + /* istanbul ignore next */ + + case 3 + /* Set */ + : + die(16); + + default: + // if value is an object, then it's assigned by reference + // in the following add or remove ops, the value field inside the patch will also be modifyed + // so we use value from the cloned patch + // @ts-ignore + return base[key] = value; + } + + case ADD: + switch (type) { + case 1 + /* Array */ + : + return key === "-" ? base.push(value) : base.splice(key, 0, value); + + case 2 + /* Map */ + : + return base.set(key, value); + + case 3 + /* Set */ + : + return base.add(value); + + default: + return base[key] = value; + } + + case REMOVE: + switch (type) { + case 1 + /* Array */ + : + return base.splice(key, 1); + + case 2 + /* Map */ + : + return base.delete(key); + + case 3 + /* Set */ + : + return base.delete(patch.value); + + default: + return delete base[key]; + } + + default: + die(17, op); + } + }); + return draft; + } + + function deepClonePatchValue(obj) { + if (!isDraftable(obj)) return obj; + if (Array.isArray(obj)) return obj.map(deepClonePatchValue); + if (isMap(obj)) return new Map(Array.from(obj.entries()).map(function (_ref3) { + var k = _ref3[0], + v = _ref3[1]; + return [k, deepClonePatchValue(v)]; + })); + if (isSet(obj)) return new Set(Array.from(obj).map(deepClonePatchValue)); + var cloned = Object.create(Object.getPrototypeOf(obj)); + + for (var key in obj) { + cloned[key] = deepClonePatchValue(obj[key]); + } + + if (has(obj, DRAFTABLE)) cloned[DRAFTABLE] = obj[DRAFTABLE]; + return cloned; + } + + function clonePatchValueIfNeeded(obj) { + if (isDraft(obj)) { + return deepClonePatchValue(obj); + } else return obj; + } + + loadPlugin("Patches", { + applyPatches_: applyPatches_, + generatePatches_: generatePatches_, + generateReplacementPatches_: generateReplacementPatches_ + }); + } + + // types only! + function enableMapSet() { + /* istanbul ignore next */ + var _extendStatics = function extendStatics(d, b) { + _extendStatics = Object.setPrototypeOf || { + __proto__: [] + } instanceof Array && function (d, b) { + d.__proto__ = b; + } || function (d, b) { + for (var p in b) { + if (b.hasOwnProperty(p)) d[p] = b[p]; + } + }; + + return _extendStatics(d, b); + }; // Ugly hack to resolve #502 and inherit built in Map / Set + + + function __extends(d, b) { + _extendStatics(d, b); + + function __() { + this.constructor = d; + } + + d.prototype = ( // @ts-ignore + __.prototype = b.prototype, new __()); + } + + var DraftMap = function (_super) { + __extends(DraftMap, _super); // Create class manually, cause #502 + + + function DraftMap(target, parent) { + this[DRAFT_STATE] = { + type_: 2 + /* Map */ + , + parent_: parent, + scope_: parent ? parent.scope_ : getCurrentScope(), + modified_: false, + finalized_: false, + copy_: undefined, + assigned_: undefined, + base_: target, + draft_: this, + isManual_: false, + revoked_: false + }; + return this; + } + + var p = DraftMap.prototype; + Object.defineProperty(p, "size", { + get: function get() { + return latest(this[DRAFT_STATE]).size; + } // enumerable: false, + // configurable: true + + }); + + p.has = function (key) { + return latest(this[DRAFT_STATE]).has(key); + }; + + p.set = function (key, value) { + var state = this[DRAFT_STATE]; + assertUnrevoked(state); + + if (!latest(state).has(key) || latest(state).get(key) !== value) { + prepareMapCopy(state); + markChanged(state); + state.assigned_.set(key, true); + state.copy_.set(key, value); + state.assigned_.set(key, true); + } + + return this; + }; + + p.delete = function (key) { + if (!this.has(key)) { + return false; + } + + var state = this[DRAFT_STATE]; + assertUnrevoked(state); + prepareMapCopy(state); + markChanged(state); + state.assigned_.set(key, false); + state.copy_.delete(key); + return true; + }; + + p.clear = function () { + var state = this[DRAFT_STATE]; + assertUnrevoked(state); + + if (latest(state).size) { + prepareMapCopy(state); + markChanged(state); + state.assigned_ = new Map(); + each$1(state.base_, function (key) { + state.assigned_.set(key, false); + }); + state.copy_.clear(); + } + }; + + p.forEach = function (cb, thisArg) { + var _this = this; + + var state = this[DRAFT_STATE]; + latest(state).forEach(function (_value, key, _map) { + cb.call(thisArg, _this.get(key), key, _this); + }); + }; + + p.get = function (key) { + var state = this[DRAFT_STATE]; + assertUnrevoked(state); + var value = latest(state).get(key); + + if (state.finalized_ || !isDraftable(value)) { + return value; + } + + if (value !== state.base_.get(key)) { + return value; // either already drafted or reassigned + } // despite what it looks, this creates a draft only once, see above condition + + + var draft = createProxy(state.scope_.immer_, value, state); + prepareMapCopy(state); + state.copy_.set(key, draft); + return draft; + }; + + p.keys = function () { + return latest(this[DRAFT_STATE]).keys(); + }; + + p.values = function () { + var _this2 = this, + _ref; + + var iterator = this.keys(); + return _ref = {}, _ref[iteratorSymbol$1] = function () { + return _this2.values(); + }, _ref.next = function next() { + var r = iterator.next(); + /* istanbul ignore next */ + + if (r.done) return r; + + var value = _this2.get(r.value); + + return { + done: false, + value: value + }; + }, _ref; + }; + + p.entries = function () { + var _this3 = this, + _ref2; + + var iterator = this.keys(); + return _ref2 = {}, _ref2[iteratorSymbol$1] = function () { + return _this3.entries(); + }, _ref2.next = function next() { + var r = iterator.next(); + /* istanbul ignore next */ + + if (r.done) return r; + + var value = _this3.get(r.value); + + return { + done: false, + value: [r.value, value] + }; + }, _ref2; + }; + + p[iteratorSymbol$1] = function () { + return this.entries(); + }; + + return DraftMap; + }(Map); + + function proxyMap_(target, parent) { + // @ts-ignore + return new DraftMap(target, parent); + } + + function prepareMapCopy(state) { + if (!state.copy_) { + state.assigned_ = new Map(); + state.copy_ = new Map(state.base_); + } + } + + var DraftSet = function (_super) { + __extends(DraftSet, _super); // Create class manually, cause #502 + + + function DraftSet(target, parent) { + this[DRAFT_STATE] = { + type_: 3 + /* Set */ + , + parent_: parent, + scope_: parent ? parent.scope_ : getCurrentScope(), + modified_: false, + finalized_: false, + copy_: undefined, + base_: target, + draft_: this, + drafts_: new Map(), + revoked_: false, + isManual_: false + }; + return this; + } + + var p = DraftSet.prototype; + Object.defineProperty(p, "size", { + get: function get() { + return latest(this[DRAFT_STATE]).size; + } // enumerable: true, + + }); + + p.has = function (value) { + var state = this[DRAFT_STATE]; + assertUnrevoked(state); // bit of trickery here, to be able to recognize both the value, and the draft of its value + + if (!state.copy_) { + return state.base_.has(value); + } + + if (state.copy_.has(value)) return true; + if (state.drafts_.has(value) && state.copy_.has(state.drafts_.get(value))) return true; + return false; + }; + + p.add = function (value) { + var state = this[DRAFT_STATE]; + assertUnrevoked(state); + + if (!this.has(value)) { + prepareSetCopy(state); + markChanged(state); + state.copy_.add(value); + } + + return this; + }; + + p.delete = function (value) { + if (!this.has(value)) { + return false; + } + + var state = this[DRAFT_STATE]; + assertUnrevoked(state); + prepareSetCopy(state); + markChanged(state); + return state.copy_.delete(value) || (state.drafts_.has(value) ? state.copy_.delete(state.drafts_.get(value)) : + /* istanbul ignore next */ + false); + }; + + p.clear = function () { + var state = this[DRAFT_STATE]; + assertUnrevoked(state); + + if (latest(state).size) { + prepareSetCopy(state); + markChanged(state); + state.copy_.clear(); + } + }; + + p.values = function () { + var state = this[DRAFT_STATE]; + assertUnrevoked(state); + prepareSetCopy(state); + return state.copy_.values(); + }; + + p.entries = function entries() { + var state = this[DRAFT_STATE]; + assertUnrevoked(state); + prepareSetCopy(state); + return state.copy_.entries(); + }; + + p.keys = function () { + return this.values(); + }; + + p[iteratorSymbol$1] = function () { + return this.values(); + }; + + p.forEach = function forEach(cb, thisArg) { + var iterator = this.values(); + var result = iterator.next(); + + while (!result.done) { + cb.call(thisArg, result.value, result.value, this); + result = iterator.next(); + } + }; + + return DraftSet; + }(Set); + + function proxySet_(target, parent) { + // @ts-ignore + return new DraftSet(target, parent); + } + + function prepareSetCopy(state) { + if (!state.copy_) { + // create drafts for all entries to preserve insertion order + state.copy_ = new Set(); + state.base_.forEach(function (value) { + if (isDraftable(value)) { + var draft = createProxy(state.scope_.immer_, value, state); + state.drafts_.set(value, draft); + state.copy_.add(draft); + } else { + state.copy_.add(value); + } + }); + } + } + + function assertUnrevoked(state + /*ES5State | MapState | SetState*/ + ) { + if (state.revoked_) die(3, JSON.stringify(latest(state))); + } + + loadPlugin("MapSet", { + proxyMap_: proxyMap_, + proxySet_: proxySet_ + }); + } + + function enableAllPlugins() { + enableES5(); + enableMapSet(); + enablePatches(); + } + + var immer$1 = + /*#__PURE__*/ + new Immer(); + /** + * The `produce` function takes a value and a "recipe function" (whose + * return value often depends on the base state). The recipe function is + * free to mutate its first argument however it wants. All mutations are + * only ever applied to a __copy__ of the base state. + * + * Pass only a function to create a "curried producer" which relieves you + * from passing the recipe function every time. + * + * Only plain objects and arrays are made mutable. All other objects are + * considered uncopyable. + * + * Note: This function is __bound__ to its `Immer` instance. + * + * @param {any} base - the initial state + * @param {Function} producer - function that receives a proxy of the base state as first argument and which can be freely modified + * @param {Function} patchListener - optional function that will be called with all the patches produced here + * @returns {any} a new state, or the initial state if nothing was modified + */ + + var produce = immer$1.produce; + /** + * Like `produce`, but `produceWithPatches` always returns a tuple + * [nextState, patches, inversePatches] (instead of just the next state) + */ + + var produceWithPatches = + /*#__PURE__*/ + immer$1.produceWithPatches.bind(immer$1); + /** + * Pass true to automatically freeze all copies created by Immer. + * + * Always freeze by default, even in production mode + */ + + var setAutoFreeze = + /*#__PURE__*/ + immer$1.setAutoFreeze.bind(immer$1); + /** + * Pass true to use the ES2015 `Proxy` class when creating drafts, which is + * always faster than using ES5 proxies. + * + * By default, feature detection is used, so calling this is rarely necessary. + */ + + var setUseProxies = + /*#__PURE__*/ + immer$1.setUseProxies.bind(immer$1); + /** + * Apply an array of Immer patches to the first argument. + * + * This function is a producer, which means copy-on-write is in effect. + */ + + var applyPatches = + /*#__PURE__*/ + immer$1.applyPatches.bind(immer$1); + /** + * Create an Immer draft from the given base state, which may be a draft itself. + * The draft can be modified until you finalize it with the `finishDraft` function. + */ + + var createDraft = + /*#__PURE__*/ + immer$1.createDraft.bind(immer$1); + /** + * Finalize an Immer draft from a `createDraft` call, returning the base state + * (if no changes were made) or a modified copy. The draft must *not* be + * mutated afterwards. + * + * Pass a function as the 2nd argument to generate Immer patches based on the + * changes that were made. + */ + + var finishDraft = + /*#__PURE__*/ + immer$1.finishDraft.bind(immer$1); + /** + * This function is actually a no-op, but can be used to cast an immutable type + * to an draft type and make TypeScript happy + * + * @param value + */ + + function castDraft(value) { + return value; + } + /** + * This function is actually a no-op, but can be used to cast a mutable type + * to an immutable type and make TypeScript happy + * @param value + */ + + function castImmutable(value) { + return value; + } + + var Immer_1 = Immer; + var applyPatches_1 = applyPatches; + var castDraft_1 = castDraft; + var castImmutable_1 = castImmutable; + var createDraft_1 = createDraft; + var current_1 = current; + var _default$2 = produce; + var enableAllPlugins_1 = enableAllPlugins; + var enableES5_1 = enableES5; + var enableMapSet_1 = enableMapSet; + var enablePatches_1 = enablePatches; + var finishDraft_1 = finishDraft; + var freeze_1 = freeze; + var immerable = DRAFTABLE; + var isDraft_1 = isDraft; + var isDraftable_1 = isDraftable; + var nothing = NOTHING; + var original_1 = original; + var produce_1 = produce; + var produceWithPatches_1 = produceWithPatches; + var setAutoFreeze_1 = setAutoFreeze; + var setUseProxies_1 = setUseProxies; + + + var immer_cjs_development = /*#__PURE__*/Object.defineProperty({ + Immer: Immer_1, + applyPatches: applyPatches_1, + castDraft: castDraft_1, + castImmutable: castImmutable_1, + createDraft: createDraft_1, + current: current_1, + default: _default$2, + enableAllPlugins: enableAllPlugins_1, + enableES5: enableES5_1, + enableMapSet: enableMapSet_1, + enablePatches: enablePatches_1, + finishDraft: finishDraft_1, + freeze: freeze_1, + immerable: immerable, + isDraft: isDraft_1, + isDraftable: isDraftable_1, + nothing: nothing, + original: original_1, + produce: produce_1, + produceWithPatches: produceWithPatches_1, + setAutoFreeze: setAutoFreeze_1, + setUseProxies: setUseProxies_1 + }, '__esModule', {value: true}); + + var require$$1$1 = immer_cjs_development; + + var dist$8 = createCommonjsModule$1(function (module) { + + { + module.exports = require$$1$1; + } + }); + + var isPlainObject = isPlainObject_1; + + var immer = dist$8; + + function unwrapExports (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; + } + + var arrayLikeToArray = createCommonjsModule(function (module) { + function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) len = arr.length; + + for (var i = 0, arr2 = new Array(len); i < len; i++) { + arr2[i] = arr[i]; + } + + return arr2; + } + + module.exports = _arrayLikeToArray; + module.exports["default"] = module.exports, module.exports.__esModule = true; + }); + + unwrapExports(arrayLikeToArray); + + var arrayWithoutHoles = createCommonjsModule(function (module) { + function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) return arrayLikeToArray(arr); + } + + module.exports = _arrayWithoutHoles; + module.exports["default"] = module.exports, module.exports.__esModule = true; + }); + + unwrapExports(arrayWithoutHoles); + + var iterableToArray = createCommonjsModule(function (module) { + function _iterableToArray(iter) { + if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); + } + + module.exports = _iterableToArray; + module.exports["default"] = module.exports, module.exports.__esModule = true; + }); + + unwrapExports(iterableToArray); + + var unsupportedIterableToArray = createCommonjsModule(function (module) { + function _unsupportedIterableToArray(o, minLen) { + if (!o) return; + if (typeof o === "string") return arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen); + } + + module.exports = _unsupportedIterableToArray; + module.exports["default"] = module.exports, module.exports.__esModule = true; + }); + + unwrapExports(unsupportedIterableToArray); + + var nonIterableSpread = createCommonjsModule(function (module) { + function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + + module.exports = _nonIterableSpread; + module.exports["default"] = module.exports, module.exports.__esModule = true; + }); + + unwrapExports(nonIterableSpread); + + var toConsumableArray = createCommonjsModule(function (module) { + function _toConsumableArray(arr) { + return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread(); + } + + module.exports = _toConsumableArray; + module.exports["default"] = module.exports, module.exports.__esModule = true; + }); + + var _toConsumableArray = unwrapExports(toConsumableArray); + + var arrayWithHoles = createCommonjsModule(function (module) { + function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; + } + + module.exports = _arrayWithHoles; + module.exports["default"] = module.exports, module.exports.__esModule = true; + }); + + unwrapExports(arrayWithHoles); + + var iterableToArrayLimit = createCommonjsModule(function (module) { + function _iterableToArrayLimit(arr, i) { + var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; + + if (_i == null) return; + var _arr = []; + var _n = true; + var _d = false; + + var _s, _e; + + try { + for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"] != null) _i["return"](); + } finally { + if (_d) throw _e; + } + } + + return _arr; + } + + module.exports = _iterableToArrayLimit; + module.exports["default"] = module.exports, module.exports.__esModule = true; + }); + + unwrapExports(iterableToArrayLimit); + + var nonIterableRest = createCommonjsModule(function (module) { + function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + + module.exports = _nonIterableRest; + module.exports["default"] = module.exports, module.exports.__esModule = true; + }); + + unwrapExports(nonIterableRest); + + var slicedToArray = createCommonjsModule(function (module) { + function _slicedToArray(arr, i) { + return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest(); + } + + module.exports = _slicedToArray; + module.exports["default"] = module.exports, module.exports.__esModule = true; + }); + + var _slicedToArray = unwrapExports(slicedToArray); + + var defineProperty = createCommonjsModule(function (module) { + function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; + } + + module.exports = _defineProperty; + module.exports["default"] = module.exports, module.exports.__esModule = true; + }); + + var _defineProperty = unwrapExports(defineProperty); + + var DIRTY_PATHS = new WeakMap(); + var FLUSHING = new WeakMap(); + var NORMALIZING = new WeakMap(); + var PATH_REFS = new WeakMap(); + var POINT_REFS = new WeakMap(); + var RANGE_REFS = new WeakMap(); + + function ownKeys$9(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } + + function _objectSpread$9(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$9(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$9(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + + function _createForOfIteratorHelper$7(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$7(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } + + function _unsupportedIterableToArray$7(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$7(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$7(o, minLen); } + + function _arrayLikeToArray$7(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + /** + * Create a new Slate `Editor` object. + */ + + var createEditor$1 = function createEditor() { + var editor = { + children: [], + operations: [], + selection: null, + marks: null, + isInline: function isInline() { + return false; + }, + isVoid: function isVoid() { + return false; + }, + onChange: function onChange() {}, + apply: function apply(op) { + var _iterator = _createForOfIteratorHelper$7(Editor.pathRefs(editor)), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var ref = _step.value; + PathRef.transform(ref, op); + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + + var _iterator2 = _createForOfIteratorHelper$7(Editor.pointRefs(editor)), + _step2; + + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var _ref = _step2.value; + PointRef.transform(_ref, op); + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + + var _iterator3 = _createForOfIteratorHelper$7(Editor.rangeRefs(editor)), + _step3; + + try { + for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { + var _ref2 = _step3.value; + RangeRef.transform(_ref2, op); + } + } catch (err) { + _iterator3.e(err); + } finally { + _iterator3.f(); + } + + var set = new Set(); + var dirtyPaths = []; + + var add = function add(path) { + if (path) { + var key = path.join(','); + + if (!set.has(key)) { + set.add(key); + dirtyPaths.push(path); + } + } + }; + + var oldDirtyPaths = DIRTY_PATHS.get(editor) || []; + var newDirtyPaths = getDirtyPaths(op); + + var _iterator4 = _createForOfIteratorHelper$7(oldDirtyPaths), + _step4; + + try { + for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) { + var path = _step4.value; + var newPath = Path.transform(path, op); + add(newPath); + } + } catch (err) { + _iterator4.e(err); + } finally { + _iterator4.f(); + } + + var _iterator5 = _createForOfIteratorHelper$7(newDirtyPaths), + _step5; + + try { + for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) { + var _path = _step5.value; + add(_path); + } + } catch (err) { + _iterator5.e(err); + } finally { + _iterator5.f(); + } + + DIRTY_PATHS.set(editor, dirtyPaths); + Transforms.transform(editor, op); + editor.operations.push(op); + Editor.normalize(editor); // Clear any formats applied to the cursor if the selection changes. + + if (op.type === 'set_selection') { + editor.marks = null; + } + + if (!FLUSHING.get(editor)) { + FLUSHING.set(editor, true); + Promise.resolve().then(function () { + FLUSHING.set(editor, false); + editor.onChange(); + editor.operations = []; + }); + } + }, + addMark: function addMark(key, value) { + var selection = editor.selection; + + if (selection) { + if (Range.isExpanded(selection)) { + Transforms.setNodes(editor, _defineProperty({}, key, value), { + match: Text.isText, + split: true + }); + } else { + var marks = _objectSpread$9(_objectSpread$9({}, Editor.marks(editor) || {}), {}, _defineProperty({}, key, value)); + + editor.marks = marks; + + if (!FLUSHING.get(editor)) { + editor.onChange(); + } + } + } + }, + deleteBackward: function deleteBackward(unit) { + var selection = editor.selection; + + if (selection && Range.isCollapsed(selection)) { + Transforms["delete"](editor, { + unit: unit, + reverse: true + }); + } + }, + deleteForward: function deleteForward(unit) { + var selection = editor.selection; + + if (selection && Range.isCollapsed(selection)) { + Transforms["delete"](editor, { + unit: unit + }); + } + }, + deleteFragment: function deleteFragment(direction) { + var selection = editor.selection; + + if (selection && Range.isExpanded(selection)) { + Transforms["delete"](editor, { + reverse: direction === 'backward' + }); + } + }, + getFragment: function getFragment() { + var selection = editor.selection; + + if (selection) { + return Node$1.fragment(editor, selection); + } + + return []; + }, + insertBreak: function insertBreak() { + Transforms.splitNodes(editor, { + always: true + }); + }, + insertFragment: function insertFragment(fragment) { + Transforms.insertFragment(editor, fragment); + }, + insertNode: function insertNode(node) { + Transforms.insertNodes(editor, node); + }, + insertText: function insertText(text) { + var selection = editor.selection, + marks = editor.marks; + + if (selection) { + if (marks) { + var node = _objectSpread$9({ + text: text + }, marks); + + Transforms.insertNodes(editor, node); + } else { + Transforms.insertText(editor, text); + } + + editor.marks = null; + } + }, + normalizeNode: function normalizeNode(entry) { + var _entry = _slicedToArray(entry, 2), + node = _entry[0], + path = _entry[1]; // There are no core normalizations for text nodes. + + + if (Text.isText(node)) { + return; + } // Ensure that block and inline nodes have at least one text child. + + + if (Element$1.isElement(node) && node.children.length === 0) { + var child = { + text: '' + }; + Transforms.insertNodes(editor, child, { + at: path.concat(0), + voids: true + }); + return; + } // Determine whether the node should have block or inline children. + + + var shouldHaveInlines = Editor.isEditor(node) ? false : Element$1.isElement(node) && (editor.isInline(node) || node.children.length === 0 || Text.isText(node.children[0]) || editor.isInline(node.children[0])); // Since we'll be applying operations while iterating, keep track of an + // index that accounts for any added/removed nodes. + + var n = 0; + + for (var i = 0; i < node.children.length; i++, n++) { + var currentNode = Node$1.get(editor, path); + if (Text.isText(currentNode)) continue; + var _child = node.children[i]; + var prev = currentNode.children[n - 1]; + var isLast = i === node.children.length - 1; + var isInlineOrText = Text.isText(_child) || Element$1.isElement(_child) && editor.isInline(_child); // Only allow block nodes in the top-level children and parent blocks + // that only contain block nodes. Similarly, only allow inline nodes in + // other inline nodes, or parent blocks that only contain inlines and + // text. + + if (isInlineOrText !== shouldHaveInlines) { + Transforms.removeNodes(editor, { + at: path.concat(n), + voids: true + }); + n--; + } else if (Element$1.isElement(_child)) { + // Ensure that inline nodes are surrounded by text nodes. + if (editor.isInline(_child)) { + if (prev == null || !Text.isText(prev)) { + var newChild = { + text: '' + }; + Transforms.insertNodes(editor, newChild, { + at: path.concat(n), + voids: true + }); + n++; + } else if (isLast) { + var _newChild = { + text: '' + }; + Transforms.insertNodes(editor, _newChild, { + at: path.concat(n + 1), + voids: true + }); + n++; + } + } + } else { + // Merge adjacent text nodes that are empty or match. + if (prev != null && Text.isText(prev)) { + if (Text.equals(_child, prev, { + loose: true + })) { + Transforms.mergeNodes(editor, { + at: path.concat(n), + voids: true + }); + n--; + } else if (prev.text === '') { + Transforms.removeNodes(editor, { + at: path.concat(n - 1), + voids: true + }); + n--; + } else if (_child.text === '') { + Transforms.removeNodes(editor, { + at: path.concat(n), + voids: true + }); + n--; + } + } + } + } + }, + removeMark: function removeMark(key) { + var selection = editor.selection; + + if (selection) { + if (Range.isExpanded(selection)) { + Transforms.unsetNodes(editor, key, { + match: Text.isText, + split: true + }); + } else { + var marks = _objectSpread$9({}, Editor.marks(editor) || {}); + + delete marks[key]; + editor.marks = marks; + + if (!FLUSHING.get(editor)) { + editor.onChange(); + } + } + } + } + }; + return editor; + }; + /** + * Get the "dirty" paths generated from an operation. + */ + + var getDirtyPaths = function getDirtyPaths(op) { + switch (op.type) { + case 'insert_text': + case 'remove_text': + case 'set_node': + { + var path = op.path; + return Path.levels(path); + } + + case 'insert_node': + { + var node = op.node, + _path2 = op.path; + var levels = Path.levels(_path2); + var descendants = Text.isText(node) ? [] : Array.from(Node$1.nodes(node), function (_ref3) { + var _ref4 = _slicedToArray(_ref3, 2), + p = _ref4[1]; + + return _path2.concat(p); + }); + return [].concat(_toConsumableArray(levels), _toConsumableArray(descendants)); + } + + case 'merge_node': + { + var _path3 = op.path; + var ancestors = Path.ancestors(_path3); + var previousPath = Path.previous(_path3); + return [].concat(_toConsumableArray(ancestors), [previousPath]); + } + + case 'move_node': + { + var _path4 = op.path, + newPath = op.newPath; + + if (Path.equals(_path4, newPath)) { + return []; + } + + var oldAncestors = []; + var newAncestors = []; + + var _iterator6 = _createForOfIteratorHelper$7(Path.ancestors(_path4)), + _step6; + + try { + for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) { + var ancestor = _step6.value; + var p = Path.transform(ancestor, op); + oldAncestors.push(p); + } + } catch (err) { + _iterator6.e(err); + } finally { + _iterator6.f(); + } + + var _iterator7 = _createForOfIteratorHelper$7(Path.ancestors(newPath)), + _step7; + + try { + for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) { + var _ancestor = _step7.value; + + var _p = Path.transform(_ancestor, op); + + newAncestors.push(_p); + } + } catch (err) { + _iterator7.e(err); + } finally { + _iterator7.f(); + } + + var newParent = newAncestors[newAncestors.length - 1]; + var newIndex = newPath[newPath.length - 1]; + var resultPath = newParent.concat(newIndex); + return [].concat(oldAncestors, newAncestors, [resultPath]); + } + + case 'remove_node': + { + var _path5 = op.path; + + var _ancestors = Path.ancestors(_path5); + + return _toConsumableArray(_ancestors); + } + + case 'split_node': + { + var _path6 = op.path; + + var _levels = Path.levels(_path6); + + var nextPath = Path.next(_path6); + return [].concat(_toConsumableArray(_levels), [nextPath]); + } + + default: + { + return []; + } + } + }; + + var objectWithoutPropertiesLoose = createCommonjsModule(function (module) { + function _objectWithoutPropertiesLoose(source, excluded) { + if (source == null) return {}; + var target = {}; + var sourceKeys = Object.keys(source); + var key, i; + + for (i = 0; i < sourceKeys.length; i++) { + key = sourceKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + target[key] = source[key]; + } + + return target; + } + + module.exports = _objectWithoutPropertiesLoose; + module.exports["default"] = module.exports, module.exports.__esModule = true; + }); + + unwrapExports(objectWithoutPropertiesLoose); + + var objectWithoutProperties = createCommonjsModule(function (module) { + function _objectWithoutProperties(source, excluded) { + if (source == null) return {}; + var target = objectWithoutPropertiesLoose(source, excluded); + var key, i; + + if (Object.getOwnPropertySymbols) { + var sourceSymbolKeys = Object.getOwnPropertySymbols(source); + + for (i = 0; i < sourceSymbolKeys.length; i++) { + key = sourceSymbolKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; + target[key] = source[key]; + } + } + + return target; + } + + module.exports = _objectWithoutProperties; + module.exports["default"] = module.exports, module.exports.__esModule = true; + }); + + var _objectWithoutProperties = unwrapExports(objectWithoutProperties); + + function _createForOfIteratorHelper$6(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$6(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } + + function _unsupportedIterableToArray$6(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$6(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$6(o, minLen); } + + function _arrayLikeToArray$6(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + + // Character (grapheme cluster) boundaries are determined according to + // the default grapheme cluster boundary specification, extended grapheme clusters variant[1]. + // + // References: + // + // [1] https://www.unicode.org/reports/tr29/#Default_Grapheme_Cluster_Table + // [2] https://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakProperty.txt + // [3] https://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakTest.html + // [4] https://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakTest.txt + + /** + * Get the distance to the end of the first character in a string of text. + */ + var getCharacterDistance = function getCharacterDistance(str) { + var isRTL = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + var isLTR = !isRTL; + var codepoints = isRTL ? codepointsIteratorRTL(str) : str; + var left = CodepointType.None; + var right = CodepointType.None; + var distance = 0; // Evaluation of these conditions are deferred. + + var gb11 = null; // Is GB11 applicable? + + var gb12Or13 = null; // Is GB12 or GB13 applicable? + + var _iterator = _createForOfIteratorHelper$6(codepoints), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var _char = _step.value; + + var code = _char.codePointAt(0); + + if (!code) break; + var type = getCodepointType(_char, code); + + var _ref = isLTR ? [right, type] : [type, left]; + + var _ref2 = _slicedToArray(_ref, 2); + + left = _ref2[0]; + right = _ref2[1]; + + if (intersects(left, CodepointType.ZWJ) && intersects(right, CodepointType.ExtPict)) { + if (isLTR) { + gb11 = endsWithEmojiZWJ(str.substring(0, distance)); + } else { + gb11 = endsWithEmojiZWJ(str.substring(0, str.length - distance)); + } + + if (!gb11) break; + } + + if (intersects(left, CodepointType.RI) && intersects(right, CodepointType.RI)) { + if (gb12Or13 !== null) { + gb12Or13 = !gb12Or13; + } else { + if (isLTR) { + gb12Or13 = true; + } else { + gb12Or13 = endsWithOddNumberOfRIs(str.substring(0, str.length - distance)); + } + } + + if (!gb12Or13) break; + } + + if (left !== CodepointType.None && right !== CodepointType.None && isBoundaryPair(left, right)) { + break; + } + + distance += _char.length; + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + + return distance || 1; + }; + var SPACE = /\s/; + var PUNCTUATION = /[\u0021-\u0023\u0025-\u002A\u002C-\u002F\u003A\u003B\u003F\u0040\u005B-\u005D\u005F\u007B\u007D\u00A1\u00A7\u00AB\u00B6\u00B7\u00BB\u00BF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u0AF0\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E3B\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/; + var CHAMELEON = /['\u2018\u2019]/; + /** + * Get the distance to the end of the first word in a string of text. + */ + + var getWordDistance = function getWordDistance(text) { + var isRTL = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + var dist = 0; + var started = false; + + while (text.length > 0) { + var charDist = getCharacterDistance(text, isRTL); + + var _splitByCharacterDist = splitByCharacterDistance(text, charDist, isRTL), + _splitByCharacterDist2 = _slicedToArray(_splitByCharacterDist, 2), + _char2 = _splitByCharacterDist2[0], + remaining = _splitByCharacterDist2[1]; + + if (isWordCharacter(_char2, remaining, isRTL)) { + started = true; + dist += charDist; + } else if (!started) { + dist += charDist; + } else { + break; + } + + text = remaining; + } + + return dist; + }; + /** + * Split a string in two parts at a given distance starting from the end when + * `isRTL` is set to `true`. + */ + + var splitByCharacterDistance = function splitByCharacterDistance(str, dist, isRTL) { + if (isRTL) { + var at = str.length - dist; + return [str.slice(at, str.length), str.slice(0, at)]; + } + + return [str.slice(0, dist), str.slice(dist)]; + }; + /** + * Check if a character is a word character. The `remaining` argument is used + * because sometimes you must read subsequent characters to truly determine it. + */ + + var isWordCharacter = function isWordCharacter(_char3, remaining) { + var isRTL = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + if (SPACE.test(_char3)) { + return false; + } // Chameleons count as word characters as long as they're in a word, so + // recurse to see if the next one is a word character or not. + + + if (CHAMELEON.test(_char3)) { + var charDist = getCharacterDistance(remaining, isRTL); + + var _splitByCharacterDist3 = splitByCharacterDistance(remaining, charDist, isRTL), + _splitByCharacterDist4 = _slicedToArray(_splitByCharacterDist3, 2), + nextChar = _splitByCharacterDist4[0], + nextRemaining = _splitByCharacterDist4[1]; + + if (isWordCharacter(nextChar, nextRemaining, isRTL)) { + return true; + } + } + + if (PUNCTUATION.test(_char3)) { + return false; + } + + return true; + }; + /** + * Iterate on codepoints from right to left. + */ + + + var codepointsIteratorRTL = function* codepointsIteratorRTL(str) { + var end = str.length - 1; + + for (var i = 0; i < str.length; i++) { + var char1 = str.charAt(end - i); + + if (isLowSurrogate(char1.charCodeAt(0))) { + var char2 = str.charAt(end - i - 1); + + if (isHighSurrogate(char2.charCodeAt(0))) { + yield char2 + char1; + i++; + continue; + } + } + + yield char1; + } + }; + /** + * Is `charCode` a high surrogate. + * + * https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Surrogates + */ + + var isHighSurrogate = function isHighSurrogate(charCode) { + return charCode >= 0xd800 && charCode <= 0xdbff; + }; + /** + * Is `charCode` a low surrogate. + * + * https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Surrogates + */ + + + var isLowSurrogate = function isLowSurrogate(charCode) { + return charCode >= 0xdc00 && charCode <= 0xdfff; + }; + + var CodepointType; + + (function (CodepointType) { + CodepointType[CodepointType["None"] = 0] = "None"; + CodepointType[CodepointType["Extend"] = 1] = "Extend"; + CodepointType[CodepointType["ZWJ"] = 2] = "ZWJ"; + CodepointType[CodepointType["RI"] = 4] = "RI"; + CodepointType[CodepointType["Prepend"] = 8] = "Prepend"; + CodepointType[CodepointType["SpacingMark"] = 16] = "SpacingMark"; + CodepointType[CodepointType["L"] = 32] = "L"; + CodepointType[CodepointType["V"] = 64] = "V"; + CodepointType[CodepointType["T"] = 128] = "T"; + CodepointType[CodepointType["LV"] = 256] = "LV"; + CodepointType[CodepointType["LVT"] = 512] = "LVT"; + CodepointType[CodepointType["ExtPict"] = 1024] = "ExtPict"; + CodepointType[CodepointType["Any"] = 2048] = "Any"; + })(CodepointType || (CodepointType = {})); + + var reExtend = /^(?:[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D3-\u08E1\u08E3-\u0902\u093A\u093C\u0941-\u0948\u094D\u0951-\u0957\u0962\u0963\u0981\u09BC\u09BE\u09C1-\u09C4\u09CD\u09D7\u09E2\u09E3\u09FE\u0A01\u0A02\u0A3C\u0A41\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81\u0A82\u0ABC\u0AC1-\u0AC5\u0AC7\u0AC8\u0ACD\u0AE2\u0AE3\u0AFA-\u0AFF\u0B01\u0B3C\u0B3E\u0B3F\u0B41-\u0B44\u0B4D\u0B55-\u0B57\u0B62\u0B63\u0B82\u0BBE\u0BC0\u0BCD\u0BD7\u0C00\u0C04\u0C3E-\u0C40\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81\u0CBC\u0CBF\u0CC2\u0CC6\u0CCC\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D00\u0D01\u0D3B\u0D3C\u0D3E\u0D41-\u0D44\u0D4D\u0D57\u0D62\u0D63\u0D81\u0DCA\u0DCF\u0DD2-\u0DD4\u0DD6\u0DDF\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F71-\u0F7E\u0F80-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102D-\u1030\u1032-\u1037\u1039\u103A\u103D\u103E\u1058\u1059\u105E-\u1060\u1071-\u1074\u1082\u1085\u1086\u108D\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4\u17B5\u17B7-\u17BD\u17C6\u17C9-\u17D3\u17DD\u180B-\u180D\u1885\u1886\u18A9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193B\u1A17\u1A18\u1A1B\u1A56\u1A58-\u1A5E\u1A60\u1A62\u1A65-\u1A6C\u1A73-\u1A7C\u1A7F\u1AB0-\u1AC0\u1B00-\u1B03\u1B34-\u1B3A\u1B3C\u1B42\u1B6B-\u1B73\u1B80\u1B81\u1BA2-\u1BA5\u1BA8\u1BA9\u1BAB-\u1BAD\u1BE6\u1BE8\u1BE9\u1BED\u1BEF-\u1BF1\u1C2C-\u1C33\u1C36\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE0\u1CE2-\u1CE8\u1CED\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF9\u1DFB-\u1DFF\u200C\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA825\uA826\uA82C\uA8C4\uA8C5\uA8E0-\uA8F1\uA8FF\uA926-\uA92D\uA947-\uA951\uA980-\uA982\uA9B3\uA9B6-\uA9B9\uA9BC\uA9BD\uA9E5\uAA29-\uAA2E\uAA31\uAA32\uAA35\uAA36\uAA43\uAA4C\uAA7C\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEC\uAAED\uAAF6\uABE5\uABE8\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F\uFF9E\uFF9F]|\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD803[\uDD24-\uDD27\uDEAB\uDEAC\uDF46-\uDF50]|\uD804[\uDC01\uDC38-\uDC46\uDC7F-\uDC81\uDCB3-\uDCB6\uDCB9\uDCBA\uDD00-\uDD02\uDD27-\uDD2B\uDD2D-\uDD34\uDD73\uDD80\uDD81\uDDB6-\uDDBE\uDDC9-\uDDCC\uDDCF\uDE2F-\uDE31\uDE34\uDE36\uDE37\uDE3E\uDEDF\uDEE3-\uDEEA\uDF00\uDF01\uDF3B\uDF3C\uDF3E\uDF40\uDF57\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC38-\uDC3F\uDC42-\uDC44\uDC46\uDC5E\uDCB0\uDCB3-\uDCB8\uDCBA\uDCBD\uDCBF\uDCC0\uDCC2\uDCC3\uDDAF\uDDB2-\uDDB5\uDDBC\uDDBD\uDDBF\uDDC0\uDDDC\uDDDD\uDE33-\uDE3A\uDE3D\uDE3F\uDE40\uDEAB\uDEAD\uDEB0-\uDEB5\uDEB7\uDF1D-\uDF1F\uDF22-\uDF25\uDF27-\uDF2B]|\uD806[\uDC2F-\uDC37\uDC39\uDC3A\uDD30\uDD3B\uDD3C\uDD3E\uDD43\uDDD4-\uDDD7\uDDDA\uDDDB\uDDE0\uDE01-\uDE0A\uDE33-\uDE38\uDE3B-\uDE3E\uDE47\uDE51-\uDE56\uDE59-\uDE5B\uDE8A-\uDE96\uDE98\uDE99]|\uD807[\uDC30-\uDC36\uDC38-\uDC3D\uDC3F\uDC92-\uDCA7\uDCAA-\uDCB0\uDCB2\uDCB3\uDCB5\uDCB6\uDD31-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD45\uDD47\uDD90\uDD91\uDD95\uDD97\uDEF3\uDEF4]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF4F\uDF8F-\uDF92\uDFE4]|\uD82F[\uDC9D\uDC9E]|\uD834[\uDD65\uDD67-\uDD69\uDD6E-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A\uDD30-\uDD36\uDEEC-\uDEEF]|\uD83A[\uDCD0-\uDCD6\uDD44-\uDD4A]|\uD83C[\uDFFB-\uDFFF]|\uDB40[\uDC20-\uDC7F\uDD00-\uDDEF])$/; + var rePrepend = /^(?:[\u0600-\u0605\u06DD\u070F\u0890\u0891\u08E2\u0D4E]|\uD804[\uDCBD\uDCCD\uDDC2\uDDC3]|\uD806[\uDD3F\uDD41\uDE3A\uDE84-\uDE89]|\uD807\uDD46)$/; + var reSpacingMark = /^(?:[\u0903\u093B\u093E-\u0940\u0949-\u094C\u094E\u094F\u0982\u0983\u09BF\u09C0\u09C7\u09C8\u09CB\u09CC\u0A03\u0A3E-\u0A40\u0A83\u0ABE-\u0AC0\u0AC9\u0ACB\u0ACC\u0B02\u0B03\u0B40\u0B47\u0B48\u0B4B\u0B4C\u0BBF\u0BC1\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCC\u0C01-\u0C03\u0C41-\u0C44\u0C82\u0C83\u0CBE\u0CC0\u0CC1\u0CC3\u0CC4\u0CC7\u0CC8\u0CCA\u0CCB\u0D02\u0D03\u0D3F\u0D40\u0D46-\u0D48\u0D4A-\u0D4C\u0D82\u0D83\u0DD0\u0DD1\u0DD8-\u0DDE\u0DF2\u0DF3\u0E33\u0EB3\u0F3E\u0F3F\u0F7F\u1031\u103B\u103C\u1056\u1057\u1084\u1715\u1734\u17B6\u17BE-\u17C5\u17C7\u17C8\u1923-\u1926\u1929-\u192B\u1930\u1931\u1933-\u1938\u1A19\u1A1A\u1A55\u1A57\u1A6D-\u1A72\u1B04\u1B3B\u1B3D-\u1B41\u1B43\u1B44\u1B82\u1BA1\u1BA6\u1BA7\u1BAA\u1BE7\u1BEA-\u1BEC\u1BEE\u1BF2\u1BF3\u1C24-\u1C2B\u1C34\u1C35\u1CE1\u1CF7\uA823\uA824\uA827\uA880\uA881\uA8B4-\uA8C3\uA952\uA953\uA983\uA9B4\uA9B5\uA9BA\uA9BB\uA9BE-\uA9C0\uAA2F\uAA30\uAA33\uAA34\uAA4D\uAAEB\uAAEE\uAAEF\uAAF5\uABE3\uABE4\uABE6\uABE7\uABE9\uABEA\uABEC]|\uD804[\uDC00\uDC02\uDC82\uDCB0-\uDCB2\uDCB7\uDCB8\uDD2C\uDD45\uDD46\uDD82\uDDB3-\uDDB5\uDDBF\uDDC0\uDDCE\uDE2C-\uDE2E\uDE32\uDE33\uDE35\uDEE0-\uDEE2\uDF02\uDF03\uDF3F\uDF41-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF62\uDF63]|\uD805[\uDC35-\uDC37\uDC40\uDC41\uDC45\uDCB1\uDCB2\uDCB9\uDCBB\uDCBC\uDCBE\uDCC1\uDDB0\uDDB1\uDDB8-\uDDBB\uDDBE\uDE30-\uDE32\uDE3B\uDE3C\uDE3E\uDEAC\uDEAE\uDEAF\uDEB6\uDF26]|\uD806[\uDC2C-\uDC2E\uDC38\uDD31-\uDD35\uDD37\uDD38\uDD3D\uDD40\uDD42\uDDD1-\uDDD3\uDDDC-\uDDDF\uDDE4\uDE39\uDE57\uDE58\uDE97]|\uD807[\uDC2F\uDC3E\uDCA9\uDCB1\uDCB4\uDD8A-\uDD8E\uDD93\uDD94\uDD96\uDEF5\uDEF6]|\uD81B[\uDF51-\uDF87\uDFF0\uDFF1]|\uD834[\uDD66\uDD6D])$/; + var reL = /^[\u1100-\u115F\uA960-\uA97C]$/; + var reV = /^[\u1160-\u11A7\uD7B0-\uD7C6]$/; + var reT = /^[\u11A8-\u11FF\uD7CB-\uD7FB]$/; + var reLV = /^[\uAC00\uAC1C\uAC38\uAC54\uAC70\uAC8C\uACA8\uACC4\uACE0\uACFC\uAD18\uAD34\uAD50\uAD6C\uAD88\uADA4\uADC0\uADDC\uADF8\uAE14\uAE30\uAE4C\uAE68\uAE84\uAEA0\uAEBC\uAED8\uAEF4\uAF10\uAF2C\uAF48\uAF64\uAF80\uAF9C\uAFB8\uAFD4\uAFF0\uB00C\uB028\uB044\uB060\uB07C\uB098\uB0B4\uB0D0\uB0EC\uB108\uB124\uB140\uB15C\uB178\uB194\uB1B0\uB1CC\uB1E8\uB204\uB220\uB23C\uB258\uB274\uB290\uB2AC\uB2C8\uB2E4\uB300\uB31C\uB338\uB354\uB370\uB38C\uB3A8\uB3C4\uB3E0\uB3FC\uB418\uB434\uB450\uB46C\uB488\uB4A4\uB4C0\uB4DC\uB4F8\uB514\uB530\uB54C\uB568\uB584\uB5A0\uB5BC\uB5D8\uB5F4\uB610\uB62C\uB648\uB664\uB680\uB69C\uB6B8\uB6D4\uB6F0\uB70C\uB728\uB744\uB760\uB77C\uB798\uB7B4\uB7D0\uB7EC\uB808\uB824\uB840\uB85C\uB878\uB894\uB8B0\uB8CC\uB8E8\uB904\uB920\uB93C\uB958\uB974\uB990\uB9AC\uB9C8\uB9E4\uBA00\uBA1C\uBA38\uBA54\uBA70\uBA8C\uBAA8\uBAC4\uBAE0\uBAFC\uBB18\uBB34\uBB50\uBB6C\uBB88\uBBA4\uBBC0\uBBDC\uBBF8\uBC14\uBC30\uBC4C\uBC68\uBC84\uBCA0\uBCBC\uBCD8\uBCF4\uBD10\uBD2C\uBD48\uBD64\uBD80\uBD9C\uBDB8\uBDD4\uBDF0\uBE0C\uBE28\uBE44\uBE60\uBE7C\uBE98\uBEB4\uBED0\uBEEC\uBF08\uBF24\uBF40\uBF5C\uBF78\uBF94\uBFB0\uBFCC\uBFE8\uC004\uC020\uC03C\uC058\uC074\uC090\uC0AC\uC0C8\uC0E4\uC100\uC11C\uC138\uC154\uC170\uC18C\uC1A8\uC1C4\uC1E0\uC1FC\uC218\uC234\uC250\uC26C\uC288\uC2A4\uC2C0\uC2DC\uC2F8\uC314\uC330\uC34C\uC368\uC384\uC3A0\uC3BC\uC3D8\uC3F4\uC410\uC42C\uC448\uC464\uC480\uC49C\uC4B8\uC4D4\uC4F0\uC50C\uC528\uC544\uC560\uC57C\uC598\uC5B4\uC5D0\uC5EC\uC608\uC624\uC640\uC65C\uC678\uC694\uC6B0\uC6CC\uC6E8\uC704\uC720\uC73C\uC758\uC774\uC790\uC7AC\uC7C8\uC7E4\uC800\uC81C\uC838\uC854\uC870\uC88C\uC8A8\uC8C4\uC8E0\uC8FC\uC918\uC934\uC950\uC96C\uC988\uC9A4\uC9C0\uC9DC\uC9F8\uCA14\uCA30\uCA4C\uCA68\uCA84\uCAA0\uCABC\uCAD8\uCAF4\uCB10\uCB2C\uCB48\uCB64\uCB80\uCB9C\uCBB8\uCBD4\uCBF0\uCC0C\uCC28\uCC44\uCC60\uCC7C\uCC98\uCCB4\uCCD0\uCCEC\uCD08\uCD24\uCD40\uCD5C\uCD78\uCD94\uCDB0\uCDCC\uCDE8\uCE04\uCE20\uCE3C\uCE58\uCE74\uCE90\uCEAC\uCEC8\uCEE4\uCF00\uCF1C\uCF38\uCF54\uCF70\uCF8C\uCFA8\uCFC4\uCFE0\uCFFC\uD018\uD034\uD050\uD06C\uD088\uD0A4\uD0C0\uD0DC\uD0F8\uD114\uD130\uD14C\uD168\uD184\uD1A0\uD1BC\uD1D8\uD1F4\uD210\uD22C\uD248\uD264\uD280\uD29C\uD2B8\uD2D4\uD2F0\uD30C\uD328\uD344\uD360\uD37C\uD398\uD3B4\uD3D0\uD3EC\uD408\uD424\uD440\uD45C\uD478\uD494\uD4B0\uD4CC\uD4E8\uD504\uD520\uD53C\uD558\uD574\uD590\uD5AC\uD5C8\uD5E4\uD600\uD61C\uD638\uD654\uD670\uD68C\uD6A8\uD6C4\uD6E0\uD6FC\uD718\uD734\uD750\uD76C\uD788]$/; + var reLVT = /^[\uAC01-\uAC1B\uAC1D-\uAC37\uAC39-\uAC53\uAC55-\uAC6F\uAC71-\uAC8B\uAC8D-\uACA7\uACA9-\uACC3\uACC5-\uACDF\uACE1-\uACFB\uACFD-\uAD17\uAD19-\uAD33\uAD35-\uAD4F\uAD51-\uAD6B\uAD6D-\uAD87\uAD89-\uADA3\uADA5-\uADBF\uADC1-\uADDB\uADDD-\uADF7\uADF9-\uAE13\uAE15-\uAE2F\uAE31-\uAE4B\uAE4D-\uAE67\uAE69-\uAE83\uAE85-\uAE9F\uAEA1-\uAEBB\uAEBD-\uAED7\uAED9-\uAEF3\uAEF5-\uAF0F\uAF11-\uAF2B\uAF2D-\uAF47\uAF49-\uAF63\uAF65-\uAF7F\uAF81-\uAF9B\uAF9D-\uAFB7\uAFB9-\uAFD3\uAFD5-\uAFEF\uAFF1-\uB00B\uB00D-\uB027\uB029-\uB043\uB045-\uB05F\uB061-\uB07B\uB07D-\uB097\uB099-\uB0B3\uB0B5-\uB0CF\uB0D1-\uB0EB\uB0ED-\uB107\uB109-\uB123\uB125-\uB13F\uB141-\uB15B\uB15D-\uB177\uB179-\uB193\uB195-\uB1AF\uB1B1-\uB1CB\uB1CD-\uB1E7\uB1E9-\uB203\uB205-\uB21F\uB221-\uB23B\uB23D-\uB257\uB259-\uB273\uB275-\uB28F\uB291-\uB2AB\uB2AD-\uB2C7\uB2C9-\uB2E3\uB2E5-\uB2FF\uB301-\uB31B\uB31D-\uB337\uB339-\uB353\uB355-\uB36F\uB371-\uB38B\uB38D-\uB3A7\uB3A9-\uB3C3\uB3C5-\uB3DF\uB3E1-\uB3FB\uB3FD-\uB417\uB419-\uB433\uB435-\uB44F\uB451-\uB46B\uB46D-\uB487\uB489-\uB4A3\uB4A5-\uB4BF\uB4C1-\uB4DB\uB4DD-\uB4F7\uB4F9-\uB513\uB515-\uB52F\uB531-\uB54B\uB54D-\uB567\uB569-\uB583\uB585-\uB59F\uB5A1-\uB5BB\uB5BD-\uB5D7\uB5D9-\uB5F3\uB5F5-\uB60F\uB611-\uB62B\uB62D-\uB647\uB649-\uB663\uB665-\uB67F\uB681-\uB69B\uB69D-\uB6B7\uB6B9-\uB6D3\uB6D5-\uB6EF\uB6F1-\uB70B\uB70D-\uB727\uB729-\uB743\uB745-\uB75F\uB761-\uB77B\uB77D-\uB797\uB799-\uB7B3\uB7B5-\uB7CF\uB7D1-\uB7EB\uB7ED-\uB807\uB809-\uB823\uB825-\uB83F\uB841-\uB85B\uB85D-\uB877\uB879-\uB893\uB895-\uB8AF\uB8B1-\uB8CB\uB8CD-\uB8E7\uB8E9-\uB903\uB905-\uB91F\uB921-\uB93B\uB93D-\uB957\uB959-\uB973\uB975-\uB98F\uB991-\uB9AB\uB9AD-\uB9C7\uB9C9-\uB9E3\uB9E5-\uB9FF\uBA01-\uBA1B\uBA1D-\uBA37\uBA39-\uBA53\uBA55-\uBA6F\uBA71-\uBA8B\uBA8D-\uBAA7\uBAA9-\uBAC3\uBAC5-\uBADF\uBAE1-\uBAFB\uBAFD-\uBB17\uBB19-\uBB33\uBB35-\uBB4F\uBB51-\uBB6B\uBB6D-\uBB87\uBB89-\uBBA3\uBBA5-\uBBBF\uBBC1-\uBBDB\uBBDD-\uBBF7\uBBF9-\uBC13\uBC15-\uBC2F\uBC31-\uBC4B\uBC4D-\uBC67\uBC69-\uBC83\uBC85-\uBC9F\uBCA1-\uBCBB\uBCBD-\uBCD7\uBCD9-\uBCF3\uBCF5-\uBD0F\uBD11-\uBD2B\uBD2D-\uBD47\uBD49-\uBD63\uBD65-\uBD7F\uBD81-\uBD9B\uBD9D-\uBDB7\uBDB9-\uBDD3\uBDD5-\uBDEF\uBDF1-\uBE0B\uBE0D-\uBE27\uBE29-\uBE43\uBE45-\uBE5F\uBE61-\uBE7B\uBE7D-\uBE97\uBE99-\uBEB3\uBEB5-\uBECF\uBED1-\uBEEB\uBEED-\uBF07\uBF09-\uBF23\uBF25-\uBF3F\uBF41-\uBF5B\uBF5D-\uBF77\uBF79-\uBF93\uBF95-\uBFAF\uBFB1-\uBFCB\uBFCD-\uBFE7\uBFE9-\uC003\uC005-\uC01F\uC021-\uC03B\uC03D-\uC057\uC059-\uC073\uC075-\uC08F\uC091-\uC0AB\uC0AD-\uC0C7\uC0C9-\uC0E3\uC0E5-\uC0FF\uC101-\uC11B\uC11D-\uC137\uC139-\uC153\uC155-\uC16F\uC171-\uC18B\uC18D-\uC1A7\uC1A9-\uC1C3\uC1C5-\uC1DF\uC1E1-\uC1FB\uC1FD-\uC217\uC219-\uC233\uC235-\uC24F\uC251-\uC26B\uC26D-\uC287\uC289-\uC2A3\uC2A5-\uC2BF\uC2C1-\uC2DB\uC2DD-\uC2F7\uC2F9-\uC313\uC315-\uC32F\uC331-\uC34B\uC34D-\uC367\uC369-\uC383\uC385-\uC39F\uC3A1-\uC3BB\uC3BD-\uC3D7\uC3D9-\uC3F3\uC3F5-\uC40F\uC411-\uC42B\uC42D-\uC447\uC449-\uC463\uC465-\uC47F\uC481-\uC49B\uC49D-\uC4B7\uC4B9-\uC4D3\uC4D5-\uC4EF\uC4F1-\uC50B\uC50D-\uC527\uC529-\uC543\uC545-\uC55F\uC561-\uC57B\uC57D-\uC597\uC599-\uC5B3\uC5B5-\uC5CF\uC5D1-\uC5EB\uC5ED-\uC607\uC609-\uC623\uC625-\uC63F\uC641-\uC65B\uC65D-\uC677\uC679-\uC693\uC695-\uC6AF\uC6B1-\uC6CB\uC6CD-\uC6E7\uC6E9-\uC703\uC705-\uC71F\uC721-\uC73B\uC73D-\uC757\uC759-\uC773\uC775-\uC78F\uC791-\uC7AB\uC7AD-\uC7C7\uC7C9-\uC7E3\uC7E5-\uC7FF\uC801-\uC81B\uC81D-\uC837\uC839-\uC853\uC855-\uC86F\uC871-\uC88B\uC88D-\uC8A7\uC8A9-\uC8C3\uC8C5-\uC8DF\uC8E1-\uC8FB\uC8FD-\uC917\uC919-\uC933\uC935-\uC94F\uC951-\uC96B\uC96D-\uC987\uC989-\uC9A3\uC9A5-\uC9BF\uC9C1-\uC9DB\uC9DD-\uC9F7\uC9F9-\uCA13\uCA15-\uCA2F\uCA31-\uCA4B\uCA4D-\uCA67\uCA69-\uCA83\uCA85-\uCA9F\uCAA1-\uCABB\uCABD-\uCAD7\uCAD9-\uCAF3\uCAF5-\uCB0F\uCB11-\uCB2B\uCB2D-\uCB47\uCB49-\uCB63\uCB65-\uCB7F\uCB81-\uCB9B\uCB9D-\uCBB7\uCBB9-\uCBD3\uCBD5-\uCBEF\uCBF1-\uCC0B\uCC0D-\uCC27\uCC29-\uCC43\uCC45-\uCC5F\uCC61-\uCC7B\uCC7D-\uCC97\uCC99-\uCCB3\uCCB5-\uCCCF\uCCD1-\uCCEB\uCCED-\uCD07\uCD09-\uCD23\uCD25-\uCD3F\uCD41-\uCD5B\uCD5D-\uCD77\uCD79-\uCD93\uCD95-\uCDAF\uCDB1-\uCDCB\uCDCD-\uCDE7\uCDE9-\uCE03\uCE05-\uCE1F\uCE21-\uCE3B\uCE3D-\uCE57\uCE59-\uCE73\uCE75-\uCE8F\uCE91-\uCEAB\uCEAD-\uCEC7\uCEC9-\uCEE3\uCEE5-\uCEFF\uCF01-\uCF1B\uCF1D-\uCF37\uCF39-\uCF53\uCF55-\uCF6F\uCF71-\uCF8B\uCF8D-\uCFA7\uCFA9-\uCFC3\uCFC5-\uCFDF\uCFE1-\uCFFB\uCFFD-\uD017\uD019-\uD033\uD035-\uD04F\uD051-\uD06B\uD06D-\uD087\uD089-\uD0A3\uD0A5-\uD0BF\uD0C1-\uD0DB\uD0DD-\uD0F7\uD0F9-\uD113\uD115-\uD12F\uD131-\uD14B\uD14D-\uD167\uD169-\uD183\uD185-\uD19F\uD1A1-\uD1BB\uD1BD-\uD1D7\uD1D9-\uD1F3\uD1F5-\uD20F\uD211-\uD22B\uD22D-\uD247\uD249-\uD263\uD265-\uD27F\uD281-\uD29B\uD29D-\uD2B7\uD2B9-\uD2D3\uD2D5-\uD2EF\uD2F1-\uD30B\uD30D-\uD327\uD329-\uD343\uD345-\uD35F\uD361-\uD37B\uD37D-\uD397\uD399-\uD3B3\uD3B5-\uD3CF\uD3D1-\uD3EB\uD3ED-\uD407\uD409-\uD423\uD425-\uD43F\uD441-\uD45B\uD45D-\uD477\uD479-\uD493\uD495-\uD4AF\uD4B1-\uD4CB\uD4CD-\uD4E7\uD4E9-\uD503\uD505-\uD51F\uD521-\uD53B\uD53D-\uD557\uD559-\uD573\uD575-\uD58F\uD591-\uD5AB\uD5AD-\uD5C7\uD5C9-\uD5E3\uD5E5-\uD5FF\uD601-\uD61B\uD61D-\uD637\uD639-\uD653\uD655-\uD66F\uD671-\uD68B\uD68D-\uD6A7\uD6A9-\uD6C3\uD6C5-\uD6DF\uD6E1-\uD6FB\uD6FD-\uD717\uD719-\uD733\uD735-\uD74F\uD751-\uD76B\uD76D-\uD787\uD789-\uD7A3]$/; + var reExtPict = /^(?:[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u2388\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2605\u2607-\u2612\u2614-\u2685\u2690-\u2705\u2708-\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763-\u2767\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC00-\uDCFF\uDD0D-\uDD0F\uDD2F\uDD6C-\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDAD-\uDDE5\uDE01-\uDE0F\uDE1A\uDE2F\uDE32-\uDE3A\uDE3C-\uDE3F\uDE49-\uDFFA]|\uD83D[\uDC00-\uDD3D\uDD46-\uDE4F\uDE80-\uDEFF\uDF74-\uDF7F\uDFD5-\uDFFF]|\uD83E[\uDC0C-\uDC0F\uDC48-\uDC4F\uDC5A-\uDC5F\uDC88-\uDC8F\uDCAE-\uDCFF\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDEFF]|\uD83F[\uDC00-\uDFFD])$/; + + var getCodepointType = function getCodepointType(_char4, code) { + var type = CodepointType.Any; + + if (_char4.search(reExtend) !== -1) { + type |= CodepointType.Extend; + } + + if (code === 0x200d) { + type |= CodepointType.ZWJ; + } + + if (code >= 0x1f1e6 && code <= 0x1f1ff) { + type |= CodepointType.RI; + } + + if (_char4.search(rePrepend) !== -1) { + type |= CodepointType.Prepend; + } + + if (_char4.search(reSpacingMark) !== -1) { + type |= CodepointType.SpacingMark; + } + + if (_char4.search(reL) !== -1) { + type |= CodepointType.L; + } + + if (_char4.search(reV) !== -1) { + type |= CodepointType.V; + } + + if (_char4.search(reT) !== -1) { + type |= CodepointType.T; + } + + if (_char4.search(reLV) !== -1) { + type |= CodepointType.LV; + } + + if (_char4.search(reLVT) !== -1) { + type |= CodepointType.LVT; + } + + if (_char4.search(reExtPict) !== -1) { + type |= CodepointType.ExtPict; + } + + return type; + }; + + function intersects(x, y) { + return (x & y) !== 0; + } + + var NonBoundaryPairs = [// GB6 + [CodepointType.L, CodepointType.L | CodepointType.V | CodepointType.LV | CodepointType.LVT], // GB7 + [CodepointType.LV | CodepointType.V, CodepointType.V | CodepointType.T], // GB8 + [CodepointType.LVT | CodepointType.T, CodepointType.T], // GB9 + [CodepointType.Any, CodepointType.Extend | CodepointType.ZWJ], // GB9a + [CodepointType.Any, CodepointType.SpacingMark], // GB9b + [CodepointType.Prepend, CodepointType.Any], // GB11 + [CodepointType.ZWJ, CodepointType.ExtPict], // GB12 and GB13 + [CodepointType.RI, CodepointType.RI]]; + + function isBoundaryPair(left, right) { + return NonBoundaryPairs.findIndex(function (r) { + return intersects(left, r[0]) && intersects(right, r[1]); + }) === -1; + } + + var endingEmojiZWJ = /(?:[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u2388\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2605\u2607-\u2612\u2614-\u2685\u2690-\u2705\u2708-\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763-\u2767\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC00-\uDCFF\uDD0D-\uDD0F\uDD2F\uDD6C-\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDAD-\uDDE5\uDE01-\uDE0F\uDE1A\uDE2F\uDE32-\uDE3A\uDE3C-\uDE3F\uDE49-\uDFFA]|\uD83D[\uDC00-\uDD3D\uDD46-\uDE4F\uDE80-\uDEFF\uDF74-\uDF7F\uDFD5-\uDFFF]|\uD83E[\uDC0C-\uDC0F\uDC48-\uDC4F\uDC5A-\uDC5F\uDC88-\uDC8F\uDCAE-\uDCFF\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDEFF]|\uD83F[\uDC00-\uDFFD])(?:[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D3-\u08E1\u08E3-\u0902\u093A\u093C\u0941-\u0948\u094D\u0951-\u0957\u0962\u0963\u0981\u09BC\u09BE\u09C1-\u09C4\u09CD\u09D7\u09E2\u09E3\u09FE\u0A01\u0A02\u0A3C\u0A41\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81\u0A82\u0ABC\u0AC1-\u0AC5\u0AC7\u0AC8\u0ACD\u0AE2\u0AE3\u0AFA-\u0AFF\u0B01\u0B3C\u0B3E\u0B3F\u0B41-\u0B44\u0B4D\u0B55-\u0B57\u0B62\u0B63\u0B82\u0BBE\u0BC0\u0BCD\u0BD7\u0C00\u0C04\u0C3E-\u0C40\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81\u0CBC\u0CBF\u0CC2\u0CC6\u0CCC\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D00\u0D01\u0D3B\u0D3C\u0D3E\u0D41-\u0D44\u0D4D\u0D57\u0D62\u0D63\u0D81\u0DCA\u0DCF\u0DD2-\u0DD4\u0DD6\u0DDF\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F71-\u0F7E\u0F80-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102D-\u1030\u1032-\u1037\u1039\u103A\u103D\u103E\u1058\u1059\u105E-\u1060\u1071-\u1074\u1082\u1085\u1086\u108D\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4\u17B5\u17B7-\u17BD\u17C6\u17C9-\u17D3\u17DD\u180B-\u180D\u1885\u1886\u18A9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193B\u1A17\u1A18\u1A1B\u1A56\u1A58-\u1A5E\u1A60\u1A62\u1A65-\u1A6C\u1A73-\u1A7C\u1A7F\u1AB0-\u1AC0\u1B00-\u1B03\u1B34-\u1B3A\u1B3C\u1B42\u1B6B-\u1B73\u1B80\u1B81\u1BA2-\u1BA5\u1BA8\u1BA9\u1BAB-\u1BAD\u1BE6\u1BE8\u1BE9\u1BED\u1BEF-\u1BF1\u1C2C-\u1C33\u1C36\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE0\u1CE2-\u1CE8\u1CED\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF9\u1DFB-\u1DFF\u200C\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA825\uA826\uA82C\uA8C4\uA8C5\uA8E0-\uA8F1\uA8FF\uA926-\uA92D\uA947-\uA951\uA980-\uA982\uA9B3\uA9B6-\uA9B9\uA9BC\uA9BD\uA9E5\uAA29-\uAA2E\uAA31\uAA32\uAA35\uAA36\uAA43\uAA4C\uAA7C\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEC\uAAED\uAAF6\uABE5\uABE8\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F\uFF9E\uFF9F]|\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD803[\uDD24-\uDD27\uDEAB\uDEAC\uDF46-\uDF50]|\uD804[\uDC01\uDC38-\uDC46\uDC7F-\uDC81\uDCB3-\uDCB6\uDCB9\uDCBA\uDD00-\uDD02\uDD27-\uDD2B\uDD2D-\uDD34\uDD73\uDD80\uDD81\uDDB6-\uDDBE\uDDC9-\uDDCC\uDDCF\uDE2F-\uDE31\uDE34\uDE36\uDE37\uDE3E\uDEDF\uDEE3-\uDEEA\uDF00\uDF01\uDF3B\uDF3C\uDF3E\uDF40\uDF57\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC38-\uDC3F\uDC42-\uDC44\uDC46\uDC5E\uDCB0\uDCB3-\uDCB8\uDCBA\uDCBD\uDCBF\uDCC0\uDCC2\uDCC3\uDDAF\uDDB2-\uDDB5\uDDBC\uDDBD\uDDBF\uDDC0\uDDDC\uDDDD\uDE33-\uDE3A\uDE3D\uDE3F\uDE40\uDEAB\uDEAD\uDEB0-\uDEB5\uDEB7\uDF1D-\uDF1F\uDF22-\uDF25\uDF27-\uDF2B]|\uD806[\uDC2F-\uDC37\uDC39\uDC3A\uDD30\uDD3B\uDD3C\uDD3E\uDD43\uDDD4-\uDDD7\uDDDA\uDDDB\uDDE0\uDE01-\uDE0A\uDE33-\uDE38\uDE3B-\uDE3E\uDE47\uDE51-\uDE56\uDE59-\uDE5B\uDE8A-\uDE96\uDE98\uDE99]|\uD807[\uDC30-\uDC36\uDC38-\uDC3D\uDC3F\uDC92-\uDCA7\uDCAA-\uDCB0\uDCB2\uDCB3\uDCB5\uDCB6\uDD31-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD45\uDD47\uDD90\uDD91\uDD95\uDD97\uDEF3\uDEF4]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF4F\uDF8F-\uDF92\uDFE4]|\uD82F[\uDC9D\uDC9E]|\uD834[\uDD65\uDD67-\uDD69\uDD6E-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A\uDD30-\uDD36\uDEEC-\uDEEF]|\uD83A[\uDCD0-\uDCD6\uDD44-\uDD4A]|\uD83C[\uDFFB-\uDFFF]|\uDB40[\uDC20-\uDC7F\uDD00-\uDDEF])*\u200D$/; + + var endsWithEmojiZWJ = function endsWithEmojiZWJ(str) { + return str.search(endingEmojiZWJ) !== -1; + }; + + var endingRIs = /(?:\uD83C[\uDDE6-\uDDFF])+$/g; + + var endsWithOddNumberOfRIs = function endsWithOddNumberOfRIs(str) { + var match = str.match(endingRIs); + + if (match === null) { + return false; + } else { + // A RI is represented by a surrogate pair. + var numRIs = match[0].length / 2; + return numRIs % 2 === 1; + } + }; + + /** + * Shared the function with isElementType utility + */ + + var isElement = function isElement(value) { + return isPlainObject.isPlainObject(value) && Node$1.isNodeList(value.children) && !Editor.isEditor(value); + }; + + var Element$1 = { + /** + * Check if a value implements the 'Ancestor' interface. + */ + isAncestor: function isAncestor(value) { + return isPlainObject.isPlainObject(value) && Node$1.isNodeList(value.children); + }, + + /** + * Check if a value implements the `Element` interface. + */ + isElement: isElement, + + /** + * Check if a value is an array of `Element` objects. + */ + isElementList: function isElementList(value) { + return Array.isArray(value) && value.every(function (val) { + return Element$1.isElement(val); + }); + }, + + /** + * Check if a set of props is a partial of Element. + */ + isElementProps: function isElementProps(props) { + return props.children !== undefined; + }, + + /** + * Check if a value implements the `Element` interface and has elementKey with selected value. + * Default it check to `type` key value + */ + isElementType: function isElementType(value, elementVal) { + var elementKey = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'type'; + return isElement(value) && value[elementKey] === elementVal; + }, + + /** + * Check if an element matches set of properties. + * + * Note: this checks custom properties, and it does not ensure that any + * children are equivalent. + */ + matches: function matches(element, props) { + for (var key in props) { + if (key === 'children') { + continue; + } + + if (element[key] !== props[key]) { + return false; + } + } + + return true; + } + }; + + var _excluded$4 = ["text"], + _excluded2$3 = ["text"]; + + function ownKeys$8(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } + + function _objectSpread$8(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$8(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$8(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + + function _createForOfIteratorHelper$5(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$5(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } + + function _unsupportedIterableToArray$5(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$5(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$5(o, minLen); } + + function _arrayLikeToArray$5(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + var IS_EDITOR_CACHE = new WeakMap(); + var Editor = { + /** + * Get the ancestor above a location in the document. + */ + above: function above(editor) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _options$voids = options.voids, + voids = _options$voids === void 0 ? false : _options$voids, + _options$mode = options.mode, + mode = _options$mode === void 0 ? 'lowest' : _options$mode, + _options$at = options.at, + at = _options$at === void 0 ? editor.selection : _options$at, + match = options.match; + + if (!at) { + return; + } + + var path = Editor.path(editor, at); + var reverse = mode === 'lowest'; + + var _iterator = _createForOfIteratorHelper$5(Editor.levels(editor, { + at: path, + voids: voids, + match: match, + reverse: reverse + })), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var _step$value = _slicedToArray(_step.value, 2), + n = _step$value[0], + p = _step$value[1]; + + if (!Text.isText(n) && !Path.equals(path, p)) { + return [n, p]; + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + }, + + /** + * Add a custom property to the leaf text nodes in the current selection. + * + * If the selection is currently collapsed, the marks will be added to the + * `editor.marks` property instead, and applied when text is inserted next. + */ + addMark: function addMark(editor, key, value) { + editor.addMark(key, value); + }, + + /** + * Get the point after a location. + */ + after: function after(editor, at) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var anchor = Editor.point(editor, at, { + edge: 'end' + }); + var focus = Editor.end(editor, []); + var range = { + anchor: anchor, + focus: focus + }; + var _options$distance = options.distance, + distance = _options$distance === void 0 ? 1 : _options$distance; + var d = 0; + var target; + + var _iterator2 = _createForOfIteratorHelper$5(Editor.positions(editor, _objectSpread$8(_objectSpread$8({}, options), {}, { + at: range + }))), + _step2; + + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var p = _step2.value; + + if (d > distance) { + break; + } + + if (d !== 0) { + target = p; + } + + d++; + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + + return target; + }, + + /** + * Get the point before a location. + */ + before: function before(editor, at) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var anchor = Editor.start(editor, []); + var focus = Editor.point(editor, at, { + edge: 'start' + }); + var range = { + anchor: anchor, + focus: focus + }; + var _options$distance2 = options.distance, + distance = _options$distance2 === void 0 ? 1 : _options$distance2; + var d = 0; + var target; + + var _iterator3 = _createForOfIteratorHelper$5(Editor.positions(editor, _objectSpread$8(_objectSpread$8({}, options), {}, { + at: range, + reverse: true + }))), + _step3; + + try { + for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { + var p = _step3.value; + + if (d > distance) { + break; + } + + if (d !== 0) { + target = p; + } + + d++; + } + } catch (err) { + _iterator3.e(err); + } finally { + _iterator3.f(); + } + + return target; + }, + + /** + * Delete content in the editor backward from the current selection. + */ + deleteBackward: function deleteBackward(editor) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _options$unit = options.unit, + unit = _options$unit === void 0 ? 'character' : _options$unit; + editor.deleteBackward(unit); + }, + + /** + * Delete content in the editor forward from the current selection. + */ + deleteForward: function deleteForward(editor) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _options$unit2 = options.unit, + unit = _options$unit2 === void 0 ? 'character' : _options$unit2; + editor.deleteForward(unit); + }, + + /** + * Delete the content in the current selection. + */ + deleteFragment: function deleteFragment(editor) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _options$direction = options.direction, + direction = _options$direction === void 0 ? 'forward' : _options$direction; + editor.deleteFragment(direction); + }, + + /** + * Get the start and end points of a location. + */ + edges: function edges(editor, at) { + return [Editor.start(editor, at), Editor.end(editor, at)]; + }, + + /** + * Get the end point of a location. + */ + end: function end(editor, at) { + return Editor.point(editor, at, { + edge: 'end' + }); + }, + + /** + * Get the first node at a location. + */ + first: function first(editor, at) { + var path = Editor.path(editor, at, { + edge: 'start' + }); + return Editor.node(editor, path); + }, + + /** + * Get the fragment at a location. + */ + fragment: function fragment(editor, at) { + var range = Editor.range(editor, at); + var fragment = Node$1.fragment(editor, range); + return fragment; + }, + + /** + * Check if a node has block children. + */ + hasBlocks: function hasBlocks(editor, element) { + return element.children.some(function (n) { + return Editor.isBlock(editor, n); + }); + }, + + /** + * Check if a node has inline and text children. + */ + hasInlines: function hasInlines(editor, element) { + return element.children.some(function (n) { + return Text.isText(n) || Editor.isInline(editor, n); + }); + }, + + /** + * Check if a node has text children. + */ + hasTexts: function hasTexts(editor, element) { + return element.children.every(function (n) { + return Text.isText(n); + }); + }, + + /** + * Insert a block break at the current selection. + * + * If the selection is currently expanded, it will be deleted first. + */ + insertBreak: function insertBreak(editor) { + editor.insertBreak(); + }, + + /** + * Insert a fragment at the current selection. + * + * If the selection is currently expanded, it will be deleted first. + */ + insertFragment: function insertFragment(editor, fragment) { + editor.insertFragment(fragment); + }, + + /** + * Insert a node at the current selection. + * + * If the selection is currently expanded, it will be deleted first. + */ + insertNode: function insertNode(editor, node) { + editor.insertNode(node); + }, + + /** + * Insert text at the current selection. + * + * If the selection is currently expanded, it will be deleted first. + */ + insertText: function insertText(editor, text) { + editor.insertText(text); + }, + + /** + * Check if a value is a block `Element` object. + */ + isBlock: function isBlock(editor, value) { + return Element$1.isElement(value) && !editor.isInline(value); + }, + + /** + * Check if a value is an `Editor` object. + */ + isEditor: function isEditor(value) { + if (!isPlainObject.isPlainObject(value)) return false; + var cachedIsEditor = IS_EDITOR_CACHE.get(value); + + if (cachedIsEditor !== undefined) { + return cachedIsEditor; + } + + var isEditor = typeof value.addMark === 'function' && typeof value.apply === 'function' && typeof value.deleteBackward === 'function' && typeof value.deleteForward === 'function' && typeof value.deleteFragment === 'function' && typeof value.insertBreak === 'function' && typeof value.insertFragment === 'function' && typeof value.insertNode === 'function' && typeof value.insertText === 'function' && typeof value.isInline === 'function' && typeof value.isVoid === 'function' && typeof value.normalizeNode === 'function' && typeof value.onChange === 'function' && typeof value.removeMark === 'function' && (value.marks === null || isPlainObject.isPlainObject(value.marks)) && (value.selection === null || Range.isRange(value.selection)) && Node$1.isNodeList(value.children) && Operation.isOperationList(value.operations); + IS_EDITOR_CACHE.set(value, isEditor); + return isEditor; + }, + + /** + * Check if a point is the end point of a location. + */ + isEnd: function isEnd(editor, point, at) { + var end = Editor.end(editor, at); + return Point.equals(point, end); + }, + + /** + * Check if a point is an edge of a location. + */ + isEdge: function isEdge(editor, point, at) { + return Editor.isStart(editor, point, at) || Editor.isEnd(editor, point, at); + }, + + /** + * Check if an element is empty, accounting for void nodes. + */ + isEmpty: function isEmpty(editor, element) { + var children = element.children; + + var _children = _slicedToArray(children, 1), + first = _children[0]; + + return children.length === 0 || children.length === 1 && Text.isText(first) && first.text === '' && !editor.isVoid(element); + }, + + /** + * Check if a value is an inline `Element` object. + */ + isInline: function isInline(editor, value) { + return Element$1.isElement(value) && editor.isInline(value); + }, + + /** + * Check if the editor is currently normalizing after each operation. + */ + isNormalizing: function isNormalizing(editor) { + var isNormalizing = NORMALIZING.get(editor); + return isNormalizing === undefined ? true : isNormalizing; + }, + + /** + * Check if a point is the start point of a location. + */ + isStart: function isStart(editor, point, at) { + // PERF: If the offset isn't `0` we know it's not the start. + if (point.offset !== 0) { + return false; + } + + var start = Editor.start(editor, at); + return Point.equals(point, start); + }, + + /** + * Check if a value is a void `Element` object. + */ + isVoid: function isVoid(editor, value) { + return Element$1.isElement(value) && editor.isVoid(value); + }, + + /** + * Get the last node at a location. + */ + last: function last(editor, at) { + var path = Editor.path(editor, at, { + edge: 'end' + }); + return Editor.node(editor, path); + }, + + /** + * Get the leaf text node at a location. + */ + leaf: function leaf(editor, at) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var path = Editor.path(editor, at, options); + var node = Node$1.leaf(editor, path); + return [node, path]; + }, + + /** + * Iterate through all of the levels at a location. + */ + levels: function* levels(editor) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _options$at2 = options.at, + at = _options$at2 === void 0 ? editor.selection : _options$at2, + _options$reverse = options.reverse, + reverse = _options$reverse === void 0 ? false : _options$reverse, + _options$voids2 = options.voids, + voids = _options$voids2 === void 0 ? false : _options$voids2; + var match = options.match; + + if (match == null) { + match = function match() { + return true; + }; + } + + if (!at) { + return; + } + + var levels = []; + var path = Editor.path(editor, at); + + var _iterator4 = _createForOfIteratorHelper$5(Node$1.levels(editor, path)), + _step4; + + try { + for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) { + var _step4$value = _slicedToArray(_step4.value, 2), + n = _step4$value[0], + p = _step4$value[1]; + + if (!match(n, p)) { + continue; + } + + levels.push([n, p]); + + if (!voids && Editor.isVoid(editor, n)) { + break; + } + } + } catch (err) { + _iterator4.e(err); + } finally { + _iterator4.f(); + } + + if (reverse) { + levels.reverse(); + } + + yield* levels; + }, + + /** + * Get the marks that would be added to text at the current selection. + */ + marks: function marks(editor) { + var marks = editor.marks, + selection = editor.selection; + + if (!selection) { + return null; + } + + if (marks) { + return marks; + } + + if (Range.isExpanded(selection)) { + var _Editor$nodes = Editor.nodes(editor, { + match: Text.isText + }), + _Editor$nodes2 = _slicedToArray(_Editor$nodes, 1), + match = _Editor$nodes2[0]; + + if (match) { + var _match = _slicedToArray(match, 1), + _node = _match[0]; + + _node.text; + var _rest = _objectWithoutProperties(_node, _excluded$4); + + return _rest; + } else { + return {}; + } + } + + var anchor = selection.anchor; + var path = anchor.path; + + var _Editor$leaf = Editor.leaf(editor, path), + _Editor$leaf2 = _slicedToArray(_Editor$leaf, 1), + node = _Editor$leaf2[0]; + + if (anchor.offset === 0) { + var prev = Editor.previous(editor, { + at: path, + match: Text.isText + }); + var block = Editor.above(editor, { + match: function match(n) { + return Editor.isBlock(editor, n); + } + }); + + if (prev && block) { + var _prev = _slicedToArray(prev, 2), + prevNode = _prev[0], + prevPath = _prev[1]; + + var _block = _slicedToArray(block, 2), + blockPath = _block[1]; + + if (Path.isAncestor(blockPath, prevPath)) { + node = prevNode; + } + } + } + + var _node2 = node; + _node2.text; + var rest = _objectWithoutProperties(_node2, _excluded2$3); + + return rest; + }, + + /** + * Get the matching node in the branch of the document after a location. + */ + next: function next(editor) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _options$mode2 = options.mode, + mode = _options$mode2 === void 0 ? 'lowest' : _options$mode2, + _options$voids3 = options.voids, + voids = _options$voids3 === void 0 ? false : _options$voids3; + var match = options.match, + _options$at3 = options.at, + at = _options$at3 === void 0 ? editor.selection : _options$at3; + + if (!at) { + return; + } + + var pointAfterLocation = Editor.after(editor, at, { + voids: voids + }); + if (!pointAfterLocation) return; + + var _Editor$last = Editor.last(editor, []), + _Editor$last2 = _slicedToArray(_Editor$last, 2), + to = _Editor$last2[1]; + + var span = [pointAfterLocation.path, to]; + + if (Path.isPath(at) && at.length === 0) { + throw new Error("Cannot get the next node from the root node!"); + } + + if (match == null) { + if (Path.isPath(at)) { + var _Editor$parent = Editor.parent(editor, at), + _Editor$parent2 = _slicedToArray(_Editor$parent, 1), + parent = _Editor$parent2[0]; + + match = function match(n) { + return parent.children.includes(n); + }; + } else { + match = function match() { + return true; + }; + } + } + + var _Editor$nodes3 = Editor.nodes(editor, { + at: span, + match: match, + mode: mode, + voids: voids + }), + _Editor$nodes4 = _slicedToArray(_Editor$nodes3, 1), + next = _Editor$nodes4[0]; + + return next; + }, + + /** + * Get the node at a location. + */ + node: function node(editor, at) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var path = Editor.path(editor, at, options); + var node = Node$1.get(editor, path); + return [node, path]; + }, + + /** + * Iterate through all of the nodes in the Editor. + */ + nodes: function* nodes(editor) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _options$at4 = options.at, + at = _options$at4 === void 0 ? editor.selection : _options$at4, + _options$mode3 = options.mode, + mode = _options$mode3 === void 0 ? 'all' : _options$mode3, + _options$universal = options.universal, + universal = _options$universal === void 0 ? false : _options$universal, + _options$reverse2 = options.reverse, + reverse = _options$reverse2 === void 0 ? false : _options$reverse2, + _options$voids4 = options.voids, + voids = _options$voids4 === void 0 ? false : _options$voids4; + var match = options.match; + + if (!match) { + match = function match() { + return true; + }; + } + + if (!at) { + return; + } + + var from; + var to; + + if (Span.isSpan(at)) { + from = at[0]; + to = at[1]; + } else { + var first = Editor.path(editor, at, { + edge: 'start' + }); + var last = Editor.path(editor, at, { + edge: 'end' + }); + from = reverse ? last : first; + to = reverse ? first : last; + } + + var nodeEntries = Node$1.nodes(editor, { + reverse: reverse, + from: from, + to: to, + pass: function pass(_ref) { + var _ref2 = _slicedToArray(_ref, 1), + n = _ref2[0]; + + return voids ? false : Editor.isVoid(editor, n); + } + }); + var matches = []; + var hit; + + var _iterator5 = _createForOfIteratorHelper$5(nodeEntries), + _step5; + + try { + for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) { + var _step5$value = _slicedToArray(_step5.value, 2), + node = _step5$value[0], + path = _step5$value[1]; + + var isLower = hit && Path.compare(path, hit[1]) === 0; // In highest mode any node lower than the last hit is not a match. + + if (mode === 'highest' && isLower) { + continue; + } + + if (!match(node, path)) { + // If we've arrived at a leaf text node that is not lower than the last + // hit, then we've found a branch that doesn't include a match, which + // means the match is not universal. + if (universal && !isLower && Text.isText(node)) { + return; + } else { + continue; + } + } // If there's a match and it's lower than the last, update the hit. + + + if (mode === 'lowest' && isLower) { + hit = [node, path]; + continue; + } // In lowest mode we emit the last hit, once it's guaranteed lowest. + + + var emit = mode === 'lowest' ? hit : [node, path]; + + if (emit) { + if (universal) { + matches.push(emit); + } else { + yield emit; + } + } + + hit = [node, path]; + } // Since lowest is always emitting one behind, catch up at the end. + + } catch (err) { + _iterator5.e(err); + } finally { + _iterator5.f(); + } + + if (mode === 'lowest' && hit) { + if (universal) { + matches.push(hit); + } else { + yield hit; + } + } // Universal defers to ensure that the match occurs in every branch, so we + // yield all of the matches after iterating. + + + if (universal) { + yield* matches; + } + }, + + /** + * Normalize any dirty objects in the editor. + */ + normalize: function normalize(editor) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _options$force = options.force, + force = _options$force === void 0 ? false : _options$force; + + var getDirtyPaths = function getDirtyPaths(editor) { + return DIRTY_PATHS.get(editor) || []; + }; + + if (!Editor.isNormalizing(editor)) { + return; + } + + if (force) { + var allPaths = Array.from(Node$1.nodes(editor), function (_ref3) { + var _ref4 = _slicedToArray(_ref3, 2), + p = _ref4[1]; + + return p; + }); + DIRTY_PATHS.set(editor, allPaths); + } + + if (getDirtyPaths(editor).length === 0) { + return; + } + + Editor.withoutNormalizing(editor, function () { + /* + Fix dirty elements with no children. + editor.normalizeNode() does fix this, but some normalization fixes also require it to work. + Running an initial pass avoids the catch-22 race condition. + */ + var _iterator6 = _createForOfIteratorHelper$5(getDirtyPaths(editor)), + _step6; + + try { + for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) { + var _dirtyPath = _step6.value; + + if (Node$1.has(editor, _dirtyPath)) { + var _entry = Editor.node(editor, _dirtyPath); + + var _entry2 = _slicedToArray(_entry, 2), + node = _entry2[0], + _ = _entry2[1]; + /* + The default normalizer inserts an empty text node in this scenario, but it can be customised. + So there is some risk here. + As long as the normalizer only inserts child nodes for this case it is safe to do in any order; + by definition adding children to an empty node can't cause other paths to change. + */ + + + if (Element$1.isElement(node) && node.children.length === 0) { + editor.normalizeNode(_entry); + } + } + } + } catch (err) { + _iterator6.e(err); + } finally { + _iterator6.f(); + } + + var max = getDirtyPaths(editor).length * 42; // HACK: better way? + + var m = 0; + + while (getDirtyPaths(editor).length !== 0) { + if (m > max) { + throw new Error("\n Could not completely normalize the editor after ".concat(max, " iterations! This is usually due to incorrect normalization logic that leaves a node in an invalid state.\n ")); + } + + var dirtyPath = getDirtyPaths(editor).pop(); // If the node doesn't exist in the tree, it does not need to be normalized. + + if (Node$1.has(editor, dirtyPath)) { + var entry = Editor.node(editor, dirtyPath); + editor.normalizeNode(entry); + } + + m++; + } + }); + }, + + /** + * Get the parent node of a location. + */ + parent: function parent(editor, at) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var path = Editor.path(editor, at, options); + var parentPath = Path.parent(path); + var entry = Editor.node(editor, parentPath); + return entry; + }, + + /** + * Get the path of a location. + */ + path: function path(editor, at) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var depth = options.depth, + edge = options.edge; + + if (Path.isPath(at)) { + if (edge === 'start') { + var _Node$first = Node$1.first(editor, at), + _Node$first2 = _slicedToArray(_Node$first, 2), + firstPath = _Node$first2[1]; + + at = firstPath; + } else if (edge === 'end') { + var _Node$last = Node$1.last(editor, at), + _Node$last2 = _slicedToArray(_Node$last, 2), + lastPath = _Node$last2[1]; + + at = lastPath; + } + } + + if (Range.isRange(at)) { + if (edge === 'start') { + at = Range.start(at); + } else if (edge === 'end') { + at = Range.end(at); + } else { + at = Path.common(at.anchor.path, at.focus.path); + } + } + + if (Point.isPoint(at)) { + at = at.path; + } + + if (depth != null) { + at = at.slice(0, depth); + } + + return at; + }, + hasPath: function hasPath(editor, path) { + return Node$1.has(editor, path); + }, + + /** + * Create a mutable ref for a `Path` object, which will stay in sync as new + * operations are applied to the editor. + */ + pathRef: function pathRef(editor, path) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var _options$affinity = options.affinity, + affinity = _options$affinity === void 0 ? 'forward' : _options$affinity; + var ref = { + current: path, + affinity: affinity, + unref: function unref() { + var current = ref.current; + var pathRefs = Editor.pathRefs(editor); + pathRefs["delete"](ref); + ref.current = null; + return current; + } + }; + var refs = Editor.pathRefs(editor); + refs.add(ref); + return ref; + }, + + /** + * Get the set of currently tracked path refs of the editor. + */ + pathRefs: function pathRefs(editor) { + var refs = PATH_REFS.get(editor); + + if (!refs) { + refs = new Set(); + PATH_REFS.set(editor, refs); + } + + return refs; + }, + + /** + * Get the start or end point of a location. + */ + point: function point(editor, at) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var _options$edge = options.edge, + edge = _options$edge === void 0 ? 'start' : _options$edge; + + if (Path.isPath(at)) { + var path; + + if (edge === 'end') { + var _Node$last3 = Node$1.last(editor, at), + _Node$last4 = _slicedToArray(_Node$last3, 2), + lastPath = _Node$last4[1]; + + path = lastPath; + } else { + var _Node$first3 = Node$1.first(editor, at), + _Node$first4 = _slicedToArray(_Node$first3, 2), + firstPath = _Node$first4[1]; + + path = firstPath; + } + + var node = Node$1.get(editor, path); + + if (!Text.isText(node)) { + throw new Error("Cannot get the ".concat(edge, " point in the node at path [").concat(at, "] because it has no ").concat(edge, " text node.")); + } + + return { + path: path, + offset: edge === 'end' ? node.text.length : 0 + }; + } + + if (Range.isRange(at)) { + var _Range$edges = Range.edges(at), + _Range$edges2 = _slicedToArray(_Range$edges, 2), + start = _Range$edges2[0], + end = _Range$edges2[1]; + + return edge === 'start' ? start : end; + } + + return at; + }, + + /** + * Create a mutable ref for a `Point` object, which will stay in sync as new + * operations are applied to the editor. + */ + pointRef: function pointRef(editor, point) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var _options$affinity2 = options.affinity, + affinity = _options$affinity2 === void 0 ? 'forward' : _options$affinity2; + var ref = { + current: point, + affinity: affinity, + unref: function unref() { + var current = ref.current; + var pointRefs = Editor.pointRefs(editor); + pointRefs["delete"](ref); + ref.current = null; + return current; + } + }; + var refs = Editor.pointRefs(editor); + refs.add(ref); + return ref; + }, + + /** + * Get the set of currently tracked point refs of the editor. + */ + pointRefs: function pointRefs(editor) { + var refs = POINT_REFS.get(editor); + + if (!refs) { + refs = new Set(); + POINT_REFS.set(editor, refs); + } + + return refs; + }, + + /** + * Return all the positions in `at` range where a `Point` can be placed. + * + * By default, moves forward by individual offsets at a time, but + * the `unit` option can be used to to move by character, word, line, or block. + * + * The `reverse` option can be used to change iteration direction. + * + * Note: By default void nodes are treated as a single point and iteration + * will not happen inside their content unless you pass in true for the + * `voids` option, then iteration will occur. + */ + positions: function* positions(editor) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _options$at5 = options.at, + at = _options$at5 === void 0 ? editor.selection : _options$at5, + _options$unit3 = options.unit, + unit = _options$unit3 === void 0 ? 'offset' : _options$unit3, + _options$reverse3 = options.reverse, + reverse = _options$reverse3 === void 0 ? false : _options$reverse3, + _options$voids5 = options.voids, + voids = _options$voids5 === void 0 ? false : _options$voids5; + + if (!at) { + return; + } + /** + * Algorithm notes: + * + * Each step `distance` is dynamic depending on the underlying text + * and the `unit` specified. Each step, e.g., a line or word, may + * span multiple text nodes, so we iterate through the text both on + * two levels in step-sync: + * + * `leafText` stores the text on a text leaf level, and is advanced + * through using the counters `leafTextOffset` and `leafTextRemaining`. + * + * `blockText` stores the text on a block level, and is shortened + * by `distance` every time it is advanced. + * + * We only maintain a window of one blockText and one leafText because + * a block node always appears before all of its leaf nodes. + */ + + + var range = Editor.range(editor, at); + + var _Range$edges3 = Range.edges(range), + _Range$edges4 = _slicedToArray(_Range$edges3, 2), + start = _Range$edges4[0], + end = _Range$edges4[1]; + + var first = reverse ? end : start; + var isNewBlock = false; + var blockText = ''; + var distance = 0; // Distance for leafText to catch up to blockText. + + var leafTextRemaining = 0; + var leafTextOffset = 0; // Iterate through all nodes in range, grabbing entire textual content + // of block nodes in blockText, and text nodes in leafText. + // Exploits the fact that nodes are sequenced in such a way that we first + // encounter the block node, then all of its text nodes, so when iterating + // through the blockText and leafText we just need to remember a window of + // one block node and leaf node, respectively. + + var _iterator7 = _createForOfIteratorHelper$5(Editor.nodes(editor, { + at: at, + reverse: reverse, + voids: voids + })), + _step7; + + try { + for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) { + var _step7$value = _slicedToArray(_step7.value, 2), + node = _step7$value[0], + path = _step7$value[1]; + + /* + * ELEMENT NODE - Yield position(s) for voids, collect blockText for blocks + */ + if (Element$1.isElement(node)) { + // Void nodes are a special case, so by default we will always + // yield their first point. If the `voids` option is set to true, + // then we will iterate over their content. + if (!voids && editor.isVoid(node)) { + yield Editor.start(editor, path); + continue; + } // Inline element nodes are ignored as they don't themselves + // contribute to `blockText` or `leafText` - their parent and + // children do. + + + if (editor.isInline(node)) continue; // Block element node - set `blockText` to its text content. + + if (Editor.hasInlines(editor, node)) { + // We always exhaust block nodes before encountering a new one: + // console.assert(blockText === '', + // `blockText='${blockText}' - `+ + // `not exhausted before new block node`, path) + // Ensure range considered is capped to `range`, in the + // start/end edge cases where block extends beyond range. + // Equivalent to this, but presumably more performant: + // blockRange = Editor.range(editor, ...Editor.edges(editor, path)) + // blockRange = Range.intersection(range, blockRange) // intersect + // blockText = Editor.string(editor, blockRange, { voids }) + var e = Path.isAncestor(path, end.path) ? end : Editor.end(editor, path); + var s = Path.isAncestor(path, start.path) ? start : Editor.start(editor, path); + blockText = Editor.string(editor, { + anchor: s, + focus: e + }, { + voids: voids + }); + isNewBlock = true; + } + } + /* + * TEXT LEAF NODE - Iterate through text content, yielding + * positions every `distance` offset according to `unit`. + */ + + + if (Text.isText(node)) { + var isFirst = Path.equals(path, first.path); // Proof that we always exhaust text nodes before encountering a new one: + // console.assert(leafTextRemaining <= 0, + // `leafTextRemaining=${leafTextRemaining} - `+ + // `not exhausted before new leaf text node`, path) + // Reset `leafText` counters for new text node. + + if (isFirst) { + leafTextRemaining = reverse ? first.offset : node.text.length - first.offset; + leafTextOffset = first.offset; // Works for reverse too. + } else { + leafTextRemaining = node.text.length; + leafTextOffset = reverse ? leafTextRemaining : 0; + } // Yield position at the start of node (potentially). + + + if (isFirst || isNewBlock || unit === 'offset') { + yield { + path: path, + offset: leafTextOffset + }; + isNewBlock = false; + } // Yield positions every (dynamically calculated) `distance` offset. + + + while (true) { + // If `leafText` has caught up with `blockText` (distance=0), + // and if blockText is exhausted, break to get another block node, + // otherwise advance blockText forward by the new `distance`. + if (distance === 0) { + if (blockText === '') break; + distance = calcDistance(blockText, unit, reverse); // Split the string at the previously found distance and use the + // remaining string for the next iteration. + + blockText = splitByCharacterDistance(blockText, distance, reverse)[1]; + } // Advance `leafText` by the current `distance`. + + + leafTextOffset = reverse ? leafTextOffset - distance : leafTextOffset + distance; + leafTextRemaining = leafTextRemaining - distance; // If `leafText` is exhausted, break to get a new leaf node + // and set distance to the overflow amount, so we'll (maybe) + // catch up to blockText in the next leaf text node. + + if (leafTextRemaining < 0) { + distance = -leafTextRemaining; + break; + } // Successfully walked `distance` offsets through `leafText` + // to catch up with `blockText`, so we can reset `distance` + // and yield this position in this node. + + + distance = 0; + yield { + path: path, + offset: leafTextOffset + }; + } + } + } // Proof that upon completion, we've exahusted both leaf and block text: + // console.assert(leafTextRemaining <= 0, "leafText wasn't exhausted") + // console.assert(blockText === '', "blockText wasn't exhausted") + // Helper: + // Return the distance in offsets for a step of size `unit` on given string. + + } catch (err) { + _iterator7.e(err); + } finally { + _iterator7.f(); + } + + function calcDistance(text, unit, reverse) { + if (unit === 'character') { + return getCharacterDistance(text, reverse); + } else if (unit === 'word') { + return getWordDistance(text, reverse); + } else if (unit === 'line' || unit === 'block') { + return text.length; + } + + return 1; + } + }, + + /** + * Get the matching node in the branch of the document before a location. + */ + previous: function previous(editor) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _options$mode4 = options.mode, + mode = _options$mode4 === void 0 ? 'lowest' : _options$mode4, + _options$voids6 = options.voids, + voids = _options$voids6 === void 0 ? false : _options$voids6; + var match = options.match, + _options$at6 = options.at, + at = _options$at6 === void 0 ? editor.selection : _options$at6; + + if (!at) { + return; + } + + var pointBeforeLocation = Editor.before(editor, at, { + voids: voids + }); + + if (!pointBeforeLocation) { + return; + } + + var _Editor$first = Editor.first(editor, []), + _Editor$first2 = _slicedToArray(_Editor$first, 2), + to = _Editor$first2[1]; // The search location is from the start of the document to the path of + // the point before the location passed in + + + var span = [pointBeforeLocation.path, to]; + + if (Path.isPath(at) && at.length === 0) { + throw new Error("Cannot get the previous node from the root node!"); + } + + if (match == null) { + if (Path.isPath(at)) { + var _Editor$parent3 = Editor.parent(editor, at), + _Editor$parent4 = _slicedToArray(_Editor$parent3, 1), + parent = _Editor$parent4[0]; + + match = function match(n) { + return parent.children.includes(n); + }; + } else { + match = function match() { + return true; + }; + } + } + + var _Editor$nodes5 = Editor.nodes(editor, { + reverse: true, + at: span, + match: match, + mode: mode, + voids: voids + }), + _Editor$nodes6 = _slicedToArray(_Editor$nodes5, 1), + previous = _Editor$nodes6[0]; + + return previous; + }, + + /** + * Get a range of a location. + */ + range: function range(editor, at, to) { + if (Range.isRange(at) && !to) { + return at; + } + + var start = Editor.start(editor, at); + var end = Editor.end(editor, to || at); + return { + anchor: start, + focus: end + }; + }, + + /** + * Create a mutable ref for a `Range` object, which will stay in sync as new + * operations are applied to the editor. + */ + rangeRef: function rangeRef(editor, range) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var _options$affinity3 = options.affinity, + affinity = _options$affinity3 === void 0 ? 'forward' : _options$affinity3; + var ref = { + current: range, + affinity: affinity, + unref: function unref() { + var current = ref.current; + var rangeRefs = Editor.rangeRefs(editor); + rangeRefs["delete"](ref); + ref.current = null; + return current; + } + }; + var refs = Editor.rangeRefs(editor); + refs.add(ref); + return ref; + }, + + /** + * Get the set of currently tracked range refs of the editor. + */ + rangeRefs: function rangeRefs(editor) { + var refs = RANGE_REFS.get(editor); + + if (!refs) { + refs = new Set(); + RANGE_REFS.set(editor, refs); + } + + return refs; + }, + + /** + * Remove a custom property from all of the leaf text nodes in the current + * selection. + * + * If the selection is currently collapsed, the removal will be stored on + * `editor.marks` and applied to the text inserted next. + */ + removeMark: function removeMark(editor, key) { + editor.removeMark(key); + }, + + /** + * Manually set if the editor should currently be normalizing. + * + * Note: Using this incorrectly can leave the editor in an invalid state. + * + */ + setNormalizing: function setNormalizing(editor, isNormalizing) { + NORMALIZING.set(editor, isNormalizing); + }, + + /** + * Get the start point of a location. + */ + start: function start(editor, at) { + return Editor.point(editor, at, { + edge: 'start' + }); + }, + + /** + * Get the text string content of a location. + * + * Note: by default the text of void nodes is considered to be an empty + * string, regardless of content, unless you pass in true for the voids option + */ + string: function string(editor, at) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var _options$voids7 = options.voids, + voids = _options$voids7 === void 0 ? false : _options$voids7; + var range = Editor.range(editor, at); + + var _Range$edges5 = Range.edges(range), + _Range$edges6 = _slicedToArray(_Range$edges5, 2), + start = _Range$edges6[0], + end = _Range$edges6[1]; + + var text = ''; + + var _iterator8 = _createForOfIteratorHelper$5(Editor.nodes(editor, { + at: range, + match: Text.isText, + voids: voids + })), + _step8; + + try { + for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) { + var _step8$value = _slicedToArray(_step8.value, 2), + node = _step8$value[0], + path = _step8$value[1]; + + var t = node.text; + + if (Path.equals(path, end.path)) { + t = t.slice(0, end.offset); + } + + if (Path.equals(path, start.path)) { + t = t.slice(start.offset); + } + + text += t; + } + } catch (err) { + _iterator8.e(err); + } finally { + _iterator8.f(); + } + + return text; + }, + + /** + * Convert a range into a non-hanging one. + */ + unhangRange: function unhangRange(editor, range) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var _options$voids8 = options.voids, + voids = _options$voids8 === void 0 ? false : _options$voids8; + + var _Range$edges7 = Range.edges(range), + _Range$edges8 = _slicedToArray(_Range$edges7, 2), + start = _Range$edges8[0], + end = _Range$edges8[1]; // PERF: exit early if we can guarantee that the range isn't hanging. + + + if (start.offset !== 0 || end.offset !== 0 || Range.isCollapsed(range)) { + return range; + } + + var endBlock = Editor.above(editor, { + at: end, + match: function match(n) { + return Editor.isBlock(editor, n); + } + }); + var blockPath = endBlock ? endBlock[1] : []; + var first = Editor.start(editor, []); + var before = { + anchor: first, + focus: end + }; + var skip = true; + + var _iterator9 = _createForOfIteratorHelper$5(Editor.nodes(editor, { + at: before, + match: Text.isText, + reverse: true, + voids: voids + })), + _step9; + + try { + for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) { + var _step9$value = _slicedToArray(_step9.value, 2), + node = _step9$value[0], + path = _step9$value[1]; + + if (skip) { + skip = false; + continue; + } + + if (node.text !== '' || Path.isBefore(path, blockPath)) { + end = { + path: path, + offset: node.text.length + }; + break; + } + } + } catch (err) { + _iterator9.e(err); + } finally { + _iterator9.f(); + } + + return { + anchor: start, + focus: end + }; + }, + + /** + * Match a void node in the current branch of the editor. + */ + "void": function _void(editor) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + return Editor.above(editor, _objectSpread$8(_objectSpread$8({}, options), {}, { + match: function match(n) { + return Editor.isVoid(editor, n); + } + })); + }, + + /** + * Call a function, deferring normalization until after it completes. + */ + withoutNormalizing: function withoutNormalizing(editor, fn) { + var value = Editor.isNormalizing(editor); + Editor.setNormalizing(editor, false); + + try { + fn(); + } finally { + Editor.setNormalizing(editor, value); + } + + Editor.normalize(editor); + } + }; + + var Location = { + /** + * Check if a value implements the `Location` interface. + */ + isLocation: function isLocation(value) { + return Path.isPath(value) || Point.isPoint(value) || Range.isRange(value); + } + }; + var Span = { + /** + * Check if a value implements the `Span` interface. + */ + isSpan: function isSpan(value) { + return Array.isArray(value) && value.length === 2 && value.every(Path.isPath); + } + }; + + var _excluded$3 = ["children"], + _excluded2$2 = ["text"]; + + function _createForOfIteratorHelper$4(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$4(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } + + function _unsupportedIterableToArray$4(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$4(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$4(o, minLen); } + + function _arrayLikeToArray$4(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + var IS_NODE_LIST_CACHE = new WeakMap(); + var Node$1 = { + /** + * Get the node at a specific path, asserting that it's an ancestor node. + */ + ancestor: function ancestor(root, path) { + var node = Node$1.get(root, path); + + if (Text.isText(node)) { + throw new Error("Cannot get the ancestor node at path [".concat(path, "] because it refers to a text node instead: ").concat(node)); + } + + return node; + }, + + /** + * Return a generator of all the ancestor nodes above a specific path. + * + * By default the order is bottom-up, from lowest to highest ancestor in + * the tree, but you can pass the `reverse: true` option to go top-down. + */ + ancestors: function* ancestors(root, path) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + + var _iterator = _createForOfIteratorHelper$4(Path.ancestors(path, options)), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var p = _step.value; + var n = Node$1.ancestor(root, p); + var entry = [n, p]; + yield entry; + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + }, + + /** + * Get the child of a node at a specific index. + */ + child: function child(root, index) { + if (Text.isText(root)) { + throw new Error("Cannot get the child of a text node: ".concat(JSON.stringify(root))); + } + + var c = root.children[index]; + + if (c == null) { + throw new Error("Cannot get child at index `".concat(index, "` in node: ").concat(JSON.stringify(root))); + } + + return c; + }, + + /** + * Iterate over the children of a node at a specific path. + */ + children: function* children(root, path) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var _options$reverse = options.reverse, + reverse = _options$reverse === void 0 ? false : _options$reverse; + var ancestor = Node$1.ancestor(root, path); + var children = ancestor.children; + var index = reverse ? children.length - 1 : 0; + + while (reverse ? index >= 0 : index < children.length) { + var child = Node$1.child(ancestor, index); + var childPath = path.concat(index); + yield [child, childPath]; + index = reverse ? index - 1 : index + 1; + } + }, + + /** + * Get an entry for the common ancesetor node of two paths. + */ + common: function common(root, path, another) { + var p = Path.common(path, another); + var n = Node$1.get(root, p); + return [n, p]; + }, + + /** + * Get the node at a specific path, asserting that it's a descendant node. + */ + descendant: function descendant(root, path) { + var node = Node$1.get(root, path); + + if (Editor.isEditor(node)) { + throw new Error("Cannot get the descendant node at path [".concat(path, "] because it refers to the root editor node instead: ").concat(node)); + } + + return node; + }, + + /** + * Return a generator of all the descendant node entries inside a root node. + */ + descendants: function* descendants(root) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var _iterator2 = _createForOfIteratorHelper$4(Node$1.nodes(root, options)), + _step2; + + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var _step2$value = _slicedToArray(_step2.value, 2), + node = _step2$value[0], + path = _step2$value[1]; + + if (path.length !== 0) { + // NOTE: we have to coerce here because checking the path's length does + // guarantee that `node` is not a `Editor`, but TypeScript doesn't know. + yield [node, path]; + } + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + }, + + /** + * Return a generator of all the element nodes inside a root node. Each iteration + * will return an `ElementEntry` tuple consisting of `[Element, Path]`. If the + * root node is an element it will be included in the iteration as well. + */ + elements: function* elements(root) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var _iterator3 = _createForOfIteratorHelper$4(Node$1.nodes(root, options)), + _step3; + + try { + for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { + var _step3$value = _slicedToArray(_step3.value, 2), + node = _step3$value[0], + path = _step3$value[1]; + + if (Element$1.isElement(node)) { + yield [node, path]; + } + } + } catch (err) { + _iterator3.e(err); + } finally { + _iterator3.f(); + } + }, + + /** + * Extract props from a Node. + */ + extractProps: function extractProps(node) { + if (Element$1.isAncestor(node)) { + node.children; + var properties = _objectWithoutProperties(node, _excluded$3); + + return properties; + } else { + node.text; + var _properties = _objectWithoutProperties(node, _excluded2$2); + + return _properties; + } + }, + + /** + * Get the first node entry in a root node from a path. + */ + first: function first(root, path) { + var p = path.slice(); + var n = Node$1.get(root, p); + + while (n) { + if (Text.isText(n) || n.children.length === 0) { + break; + } else { + n = n.children[0]; + p.push(0); + } + } + + return [n, p]; + }, + + /** + * Get the sliced fragment represented by a range inside a root node. + */ + fragment: function fragment(root, range) { + if (Text.isText(root)) { + throw new Error("Cannot get a fragment starting from a root text node: ".concat(JSON.stringify(root))); + } + + var newRoot = immer.produce({ + children: root.children + }, function (r) { + var _Range$edges = Range.edges(range), + _Range$edges2 = _slicedToArray(_Range$edges, 2), + start = _Range$edges2[0], + end = _Range$edges2[1]; + + var nodeEntries = Node$1.nodes(r, { + reverse: true, + pass: function pass(_ref) { + var _ref2 = _slicedToArray(_ref, 2), + path = _ref2[1]; + + return !Range.includes(range, path); + } + }); + + var _iterator4 = _createForOfIteratorHelper$4(nodeEntries), + _step4; + + try { + for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) { + var _step4$value = _slicedToArray(_step4.value, 2), + path = _step4$value[1]; + + if (!Range.includes(range, path)) { + var parent = Node$1.parent(r, path); + var index = path[path.length - 1]; + parent.children.splice(index, 1); + } + + if (Path.equals(path, end.path)) { + var leaf = Node$1.leaf(r, path); + leaf.text = leaf.text.slice(0, end.offset); + } + + if (Path.equals(path, start.path)) { + var _leaf = Node$1.leaf(r, path); + + _leaf.text = _leaf.text.slice(start.offset); + } + } + } catch (err) { + _iterator4.e(err); + } finally { + _iterator4.f(); + } + + if (Editor.isEditor(r)) { + r.selection = null; + } + }); + return newRoot.children; + }, + + /** + * Get the descendant node referred to by a specific path. If the path is an + * empty array, it refers to the root node itself. + */ + get: function get(root, path) { + var node = root; + + for (var i = 0; i < path.length; i++) { + var p = path[i]; + + if (Text.isText(node) || !node.children[p]) { + throw new Error("Cannot find a descendant at path [".concat(path, "] in node: ").concat(JSON.stringify(root))); + } + + node = node.children[p]; + } + + return node; + }, + + /** + * Check if a descendant node exists at a specific path. + */ + has: function has(root, path) { + var node = root; + + for (var i = 0; i < path.length; i++) { + var p = path[i]; + + if (Text.isText(node) || !node.children[p]) { + return false; + } + + node = node.children[p]; + } + + return true; + }, + + /** + * Check if a value implements the `Node` interface. + */ + isNode: function isNode(value) { + return Text.isText(value) || Element$1.isElement(value) || Editor.isEditor(value); + }, + + /** + * Check if a value is a list of `Node` objects. + */ + isNodeList: function isNodeList(value) { + if (!Array.isArray(value)) { + return false; + } + + var cachedResult = IS_NODE_LIST_CACHE.get(value); + + if (cachedResult !== undefined) { + return cachedResult; + } + + var isNodeList = value.every(function (val) { + return Node$1.isNode(val); + }); + IS_NODE_LIST_CACHE.set(value, isNodeList); + return isNodeList; + }, + + /** + * Get the last node entry in a root node from a path. + */ + last: function last(root, path) { + var p = path.slice(); + var n = Node$1.get(root, p); + + while (n) { + if (Text.isText(n) || n.children.length === 0) { + break; + } else { + var i = n.children.length - 1; + n = n.children[i]; + p.push(i); + } + } + + return [n, p]; + }, + + /** + * Get the node at a specific path, ensuring it's a leaf text node. + */ + leaf: function leaf(root, path) { + var node = Node$1.get(root, path); + + if (!Text.isText(node)) { + throw new Error("Cannot get the leaf node at path [".concat(path, "] because it refers to a non-leaf node: ").concat(node)); + } + + return node; + }, + + /** + * Return a generator of the in a branch of the tree, from a specific path. + * + * By default the order is top-down, from lowest to highest node in the tree, + * but you can pass the `reverse: true` option to go bottom-up. + */ + levels: function* levels(root, path) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + + var _iterator5 = _createForOfIteratorHelper$4(Path.levels(path, options)), + _step5; + + try { + for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) { + var p = _step5.value; + var n = Node$1.get(root, p); + yield [n, p]; + } + } catch (err) { + _iterator5.e(err); + } finally { + _iterator5.f(); + } + }, + + /** + * Check if a node matches a set of props. + */ + matches: function matches(node, props) { + return Element$1.isElement(node) && Element$1.isElementProps(props) && Element$1.matches(node, props) || Text.isText(node) && Text.isTextProps(props) && Text.matches(node, props); + }, + + /** + * Return a generator of all the node entries of a root node. Each entry is + * returned as a `[Node, Path]` tuple, with the path referring to the node's + * position inside the root node. + */ + nodes: function* nodes(root) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var pass = options.pass, + _options$reverse2 = options.reverse, + reverse = _options$reverse2 === void 0 ? false : _options$reverse2; + var _options$from = options.from, + from = _options$from === void 0 ? [] : _options$from, + to = options.to; + var visited = new Set(); + var p = []; + var n = root; + + while (true) { + if (to && (reverse ? Path.isBefore(p, to) : Path.isAfter(p, to))) { + break; + } + + if (!visited.has(n)) { + yield [n, p]; + } // If we're allowed to go downward and we haven't descended yet, do. + + + if (!visited.has(n) && !Text.isText(n) && n.children.length !== 0 && (pass == null || pass([n, p]) === false)) { + visited.add(n); + var nextIndex = reverse ? n.children.length - 1 : 0; + + if (Path.isAncestor(p, from)) { + nextIndex = from[p.length]; + } + + p = p.concat(nextIndex); + n = Node$1.get(root, p); + continue; + } // If we're at the root and we can't go down, we're done. + + + if (p.length === 0) { + break; + } // If we're going forward... + + + if (!reverse) { + var newPath = Path.next(p); + + if (Node$1.has(root, newPath)) { + p = newPath; + n = Node$1.get(root, p); + continue; + } + } // If we're going backward... + + + if (reverse && p[p.length - 1] !== 0) { + var _newPath = Path.previous(p); + + p = _newPath; + n = Node$1.get(root, p); + continue; + } // Otherwise we're going upward... + + + p = Path.parent(p); + n = Node$1.get(root, p); + visited.add(n); + } + }, + + /** + * Get the parent of a node at a specific path. + */ + parent: function parent(root, path) { + var parentPath = Path.parent(path); + var p = Node$1.get(root, parentPath); + + if (Text.isText(p)) { + throw new Error("Cannot get the parent of path [".concat(path, "] because it does not exist in the root.")); + } + + return p; + }, + + /** + * Get the concatenated text string of a node's content. + * + * Note that this will not include spaces or line breaks between block nodes. + * It is not a user-facing string, but a string for performing offset-related + * computations for a node. + */ + string: function string(node) { + if (Text.isText(node)) { + return node.text; + } else { + return node.children.map(Node$1.string).join(''); + } + }, + + /** + * Return a generator of all leaf text nodes in a root node. + */ + texts: function* texts(root) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var _iterator6 = _createForOfIteratorHelper$4(Node$1.nodes(root, options)), + _step6; + + try { + for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) { + var _step6$value = _slicedToArray(_step6.value, 2), + node = _step6$value[0], + path = _step6$value[1]; + + if (Text.isText(node)) { + yield [node, path]; + } + } + } catch (err) { + _iterator6.e(err); + } finally { + _iterator6.f(); + } + } + }; + + function ownKeys$7(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } + + function _objectSpread$7(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$7(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$7(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + var Operation = { + /** + * Check of a value is a `NodeOperation` object. + */ + isNodeOperation: function isNodeOperation(value) { + return Operation.isOperation(value) && value.type.endsWith('_node'); + }, + + /** + * Check of a value is an `Operation` object. + */ + isOperation: function isOperation(value) { + if (!isPlainObject.isPlainObject(value)) { + return false; + } + + switch (value.type) { + case 'insert_node': + return Path.isPath(value.path) && Node$1.isNode(value.node); + + case 'insert_text': + return typeof value.offset === 'number' && typeof value.text === 'string' && Path.isPath(value.path); + + case 'merge_node': + return typeof value.position === 'number' && Path.isPath(value.path) && isPlainObject.isPlainObject(value.properties); + + case 'move_node': + return Path.isPath(value.path) && Path.isPath(value.newPath); + + case 'remove_node': + return Path.isPath(value.path) && Node$1.isNode(value.node); + + case 'remove_text': + return typeof value.offset === 'number' && typeof value.text === 'string' && Path.isPath(value.path); + + case 'set_node': + return Path.isPath(value.path) && isPlainObject.isPlainObject(value.properties) && isPlainObject.isPlainObject(value.newProperties); + + case 'set_selection': + return value.properties === null && Range.isRange(value.newProperties) || value.newProperties === null && Range.isRange(value.properties) || isPlainObject.isPlainObject(value.properties) && isPlainObject.isPlainObject(value.newProperties); + + case 'split_node': + return Path.isPath(value.path) && typeof value.position === 'number' && isPlainObject.isPlainObject(value.properties); + + default: + return false; + } + }, + + /** + * Check if a value is a list of `Operation` objects. + */ + isOperationList: function isOperationList(value) { + return Array.isArray(value) && value.every(function (val) { + return Operation.isOperation(val); + }); + }, + + /** + * Check of a value is a `SelectionOperation` object. + */ + isSelectionOperation: function isSelectionOperation(value) { + return Operation.isOperation(value) && value.type.endsWith('_selection'); + }, + + /** + * Check of a value is a `TextOperation` object. + */ + isTextOperation: function isTextOperation(value) { + return Operation.isOperation(value) && value.type.endsWith('_text'); + }, + + /** + * Invert an operation, returning a new operation that will exactly undo the + * original when applied. + */ + inverse: function inverse(op) { + switch (op.type) { + case 'insert_node': + { + return _objectSpread$7(_objectSpread$7({}, op), {}, { + type: 'remove_node' + }); + } + + case 'insert_text': + { + return _objectSpread$7(_objectSpread$7({}, op), {}, { + type: 'remove_text' + }); + } + + case 'merge_node': + { + return _objectSpread$7(_objectSpread$7({}, op), {}, { + type: 'split_node', + path: Path.previous(op.path) + }); + } + + case 'move_node': + { + var newPath = op.newPath, + path = op.path; // PERF: in this case the move operation is a no-op anyways. + + if (Path.equals(newPath, path)) { + return op; + } // If the move happens completely within a single parent the path and + // newPath are stable with respect to each other. + + + if (Path.isSibling(path, newPath)) { + return _objectSpread$7(_objectSpread$7({}, op), {}, { + path: newPath, + newPath: path + }); + } // If the move does not happen within a single parent it is possible + // for the move to impact the true path to the location where the node + // was removed from and where it was inserted. We have to adjust for this + // and find the original path. We can accomplish this (only in non-sibling) + // moves by looking at the impact of the move operation on the node + // after the original move path. + + + var inversePath = Path.transform(path, op); + var inverseNewPath = Path.transform(Path.next(path), op); + return _objectSpread$7(_objectSpread$7({}, op), {}, { + path: inversePath, + newPath: inverseNewPath + }); + } + + case 'remove_node': + { + return _objectSpread$7(_objectSpread$7({}, op), {}, { + type: 'insert_node' + }); + } + + case 'remove_text': + { + return _objectSpread$7(_objectSpread$7({}, op), {}, { + type: 'insert_text' + }); + } + + case 'set_node': + { + var properties = op.properties, + newProperties = op.newProperties; + return _objectSpread$7(_objectSpread$7({}, op), {}, { + properties: newProperties, + newProperties: properties + }); + } + + case 'set_selection': + { + var _properties = op.properties, + _newProperties = op.newProperties; + + if (_properties == null) { + return _objectSpread$7(_objectSpread$7({}, op), {}, { + properties: _newProperties, + newProperties: null + }); + } else if (_newProperties == null) { + return _objectSpread$7(_objectSpread$7({}, op), {}, { + properties: null, + newProperties: _properties + }); + } else { + return _objectSpread$7(_objectSpread$7({}, op), {}, { + properties: _newProperties, + newProperties: _properties + }); + } + } + + case 'split_node': + { + return _objectSpread$7(_objectSpread$7({}, op), {}, { + type: 'merge_node', + path: Path.next(op.path) + }); + } + } + } + }; + + var Path = { + /** + * Get a list of ancestor paths for a given path. + * + * The paths are sorted from deepest to shallowest ancestor. However, if the + * `reverse: true` option is passed, they are reversed. + */ + ancestors: function ancestors(path) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _options$reverse = options.reverse, + reverse = _options$reverse === void 0 ? false : _options$reverse; + var paths = Path.levels(path, options); + + if (reverse) { + paths = paths.slice(1); + } else { + paths = paths.slice(0, -1); + } + + return paths; + }, + + /** + * Get the common ancestor path of two paths. + */ + common: function common(path, another) { + var common = []; + + for (var i = 0; i < path.length && i < another.length; i++) { + var av = path[i]; + var bv = another[i]; + + if (av !== bv) { + break; + } + + common.push(av); + } + + return common; + }, + + /** + * Compare a path to another, returning an integer indicating whether the path + * was before, at, or after the other. + * + * Note: Two paths of unequal length can still receive a `0` result if one is + * directly above or below the other. If you want exact matching, use + * [[Path.equals]] instead. + */ + compare: function compare(path, another) { + var min = Math.min(path.length, another.length); + + for (var i = 0; i < min; i++) { + if (path[i] < another[i]) return -1; + if (path[i] > another[i]) return 1; + } + + return 0; + }, + + /** + * Check if a path ends after one of the indexes in another. + */ + endsAfter: function endsAfter(path, another) { + var i = path.length - 1; + var as = path.slice(0, i); + var bs = another.slice(0, i); + var av = path[i]; + var bv = another[i]; + return Path.equals(as, bs) && av > bv; + }, + + /** + * Check if a path ends at one of the indexes in another. + */ + endsAt: function endsAt(path, another) { + var i = path.length; + var as = path.slice(0, i); + var bs = another.slice(0, i); + return Path.equals(as, bs); + }, + + /** + * Check if a path ends before one of the indexes in another. + */ + endsBefore: function endsBefore(path, another) { + var i = path.length - 1; + var as = path.slice(0, i); + var bs = another.slice(0, i); + var av = path[i]; + var bv = another[i]; + return Path.equals(as, bs) && av < bv; + }, + + /** + * Check if a path is exactly equal to another. + */ + equals: function equals(path, another) { + return path.length === another.length && path.every(function (n, i) { + return n === another[i]; + }); + }, + + /** + * Check if the path of previous sibling node exists + */ + hasPrevious: function hasPrevious(path) { + return path[path.length - 1] > 0; + }, + + /** + * Check if a path is after another. + */ + isAfter: function isAfter(path, another) { + return Path.compare(path, another) === 1; + }, + + /** + * Check if a path is an ancestor of another. + */ + isAncestor: function isAncestor(path, another) { + return path.length < another.length && Path.compare(path, another) === 0; + }, + + /** + * Check if a path is before another. + */ + isBefore: function isBefore(path, another) { + return Path.compare(path, another) === -1; + }, + + /** + * Check if a path is a child of another. + */ + isChild: function isChild(path, another) { + return path.length === another.length + 1 && Path.compare(path, another) === 0; + }, + + /** + * Check if a path is equal to or an ancestor of another. + */ + isCommon: function isCommon(path, another) { + return path.length <= another.length && Path.compare(path, another) === 0; + }, + + /** + * Check if a path is a descendant of another. + */ + isDescendant: function isDescendant(path, another) { + return path.length > another.length && Path.compare(path, another) === 0; + }, + + /** + * Check if a path is the parent of another. + */ + isParent: function isParent(path, another) { + return path.length + 1 === another.length && Path.compare(path, another) === 0; + }, + + /** + * Check is a value implements the `Path` interface. + */ + isPath: function isPath(value) { + return Array.isArray(value) && (value.length === 0 || typeof value[0] === 'number'); + }, + + /** + * Check if a path is a sibling of another. + */ + isSibling: function isSibling(path, another) { + if (path.length !== another.length) { + return false; + } + + var as = path.slice(0, -1); + var bs = another.slice(0, -1); + var al = path[path.length - 1]; + var bl = another[another.length - 1]; + return al !== bl && Path.equals(as, bs); + }, + + /** + * Get a list of paths at every level down to a path. Note: this is the same + * as `Path.ancestors`, but including the path itself. + * + * The paths are sorted from shallowest to deepest. However, if the `reverse: + * true` option is passed, they are reversed. + */ + levels: function levels(path) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _options$reverse2 = options.reverse, + reverse = _options$reverse2 === void 0 ? false : _options$reverse2; + var list = []; + + for (var i = 0; i <= path.length; i++) { + list.push(path.slice(0, i)); + } + + if (reverse) { + list.reverse(); + } + + return list; + }, + + /** + * Given a path, get the path to the next sibling node. + */ + next: function next(path) { + if (path.length === 0) { + throw new Error("Cannot get the next path of a root path [".concat(path, "], because it has no next index.")); + } + + var last = path[path.length - 1]; + return path.slice(0, -1).concat(last + 1); + }, + + /** + * Given a path, return a new path referring to the parent node above it. + */ + parent: function parent(path) { + if (path.length === 0) { + throw new Error("Cannot get the parent path of the root path [".concat(path, "].")); + } + + return path.slice(0, -1); + }, + + /** + * Given a path, get the path to the previous sibling node. + */ + previous: function previous(path) { + if (path.length === 0) { + throw new Error("Cannot get the previous path of a root path [".concat(path, "], because it has no previous index.")); + } + + var last = path[path.length - 1]; + + if (last <= 0) { + throw new Error("Cannot get the previous path of a first child path [".concat(path, "] because it would result in a negative index.")); + } + + return path.slice(0, -1).concat(last - 1); + }, + + /** + * Get a path relative to an ancestor. + */ + relative: function relative(path, ancestor) { + if (!Path.isAncestor(ancestor, path) && !Path.equals(path, ancestor)) { + throw new Error("Cannot get the relative path of [".concat(path, "] inside ancestor [").concat(ancestor, "], because it is not above or equal to the path.")); + } + + return path.slice(ancestor.length); + }, + + /** + * Transform a path by an operation. + */ + transform: function transform(path, operation) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + return immer.produce(path, function (p) { + var _options$affinity = options.affinity, + affinity = _options$affinity === void 0 ? 'forward' : _options$affinity; // PERF: Exit early if the operation is guaranteed not to have an effect. + + if (!path || (path === null || path === void 0 ? void 0 : path.length) === 0) { + return; + } + + if (p === null) { + return null; + } + + switch (operation.type) { + case 'insert_node': + { + var op = operation.path; + + if (Path.equals(op, p) || Path.endsBefore(op, p) || Path.isAncestor(op, p)) { + p[op.length - 1] += 1; + } + + break; + } + + case 'remove_node': + { + var _op = operation.path; + + if (Path.equals(_op, p) || Path.isAncestor(_op, p)) { + return null; + } else if (Path.endsBefore(_op, p)) { + p[_op.length - 1] -= 1; + } + + break; + } + + case 'merge_node': + { + var _op2 = operation.path, + position = operation.position; + + if (Path.equals(_op2, p) || Path.endsBefore(_op2, p)) { + p[_op2.length - 1] -= 1; + } else if (Path.isAncestor(_op2, p)) { + p[_op2.length - 1] -= 1; + p[_op2.length] += position; + } + + break; + } + + case 'split_node': + { + var _op3 = operation.path, + _position = operation.position; + + if (Path.equals(_op3, p)) { + if (affinity === 'forward') { + p[p.length - 1] += 1; + } else if (affinity === 'backward') ; else { + return null; + } + } else if (Path.endsBefore(_op3, p)) { + p[_op3.length - 1] += 1; + } else if (Path.isAncestor(_op3, p) && path[_op3.length] >= _position) { + p[_op3.length - 1] += 1; + p[_op3.length] -= _position; + } + + break; + } + + case 'move_node': + { + var _op4 = operation.path, + onp = operation.newPath; // If the old and new path are the same, it's a no-op. + + if (Path.equals(_op4, onp)) { + return; + } + + if (Path.isAncestor(_op4, p) || Path.equals(_op4, p)) { + var copy = onp.slice(); + + if (Path.endsBefore(_op4, onp) && _op4.length < onp.length) { + copy[_op4.length - 1] -= 1; + } + + return copy.concat(p.slice(_op4.length)); + } else if (Path.isSibling(_op4, onp) && (Path.isAncestor(onp, p) || Path.equals(onp, p))) { + if (Path.endsBefore(_op4, p)) { + p[_op4.length - 1] -= 1; + } else { + p[_op4.length - 1] += 1; + } + } else if (Path.endsBefore(onp, p) || Path.equals(onp, p) || Path.isAncestor(onp, p)) { + if (Path.endsBefore(_op4, p)) { + p[_op4.length - 1] -= 1; + } + + p[onp.length - 1] += 1; + } else if (Path.endsBefore(_op4, p)) { + if (Path.equals(onp, p)) { + p[onp.length - 1] += 1; + } + + p[_op4.length - 1] -= 1; + } + + break; + } + } + }); + } + }; + + var PathRef = { + /** + * Transform the path ref's current value by an operation. + */ + transform: function transform(ref, op) { + var current = ref.current, + affinity = ref.affinity; + + if (current == null) { + return; + } + + var path = Path.transform(current, op, { + affinity: affinity + }); + ref.current = path; + + if (path == null) { + ref.unref(); + } + } + }; + + function ownKeys$6(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } + + function _objectSpread$6(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$6(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$6(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + var Point = { + /** + * Compare a point to another, returning an integer indicating whether the + * point was before, at, or after the other. + */ + compare: function compare(point, another) { + var result = Path.compare(point.path, another.path); + + if (result === 0) { + if (point.offset < another.offset) return -1; + if (point.offset > another.offset) return 1; + return 0; + } + + return result; + }, + + /** + * Check if a point is after another. + */ + isAfter: function isAfter(point, another) { + return Point.compare(point, another) === 1; + }, + + /** + * Check if a point is before another. + */ + isBefore: function isBefore(point, another) { + return Point.compare(point, another) === -1; + }, + + /** + * Check if a point is exactly equal to another. + */ + equals: function equals(point, another) { + // PERF: ensure the offsets are equal first since they are cheaper to check. + return point.offset === another.offset && Path.equals(point.path, another.path); + }, + + /** + * Check if a value implements the `Point` interface. + */ + isPoint: function isPoint(value) { + return isPlainObject.isPlainObject(value) && typeof value.offset === 'number' && Path.isPath(value.path); + }, + + /** + * Transform a point by an operation. + */ + transform: function transform(point, op) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + return immer.produce(point, function (p) { + if (p === null) { + return null; + } + + var _options$affinity = options.affinity, + affinity = _options$affinity === void 0 ? 'forward' : _options$affinity; + var path = p.path, + offset = p.offset; + + switch (op.type) { + case 'insert_node': + case 'move_node': + { + p.path = Path.transform(path, op, options); + break; + } + + case 'insert_text': + { + if (Path.equals(op.path, path) && op.offset <= offset) { + p.offset += op.text.length; + } + + break; + } + + case 'merge_node': + { + if (Path.equals(op.path, path)) { + p.offset += op.position; + } + + p.path = Path.transform(path, op, options); + break; + } + + case 'remove_text': + { + if (Path.equals(op.path, path) && op.offset <= offset) { + p.offset -= Math.min(offset - op.offset, op.text.length); + } + + break; + } + + case 'remove_node': + { + if (Path.equals(op.path, path) || Path.isAncestor(op.path, path)) { + return null; + } + + p.path = Path.transform(path, op, options); + break; + } + + case 'split_node': + { + if (Path.equals(op.path, path)) { + if (op.position === offset && affinity == null) { + return null; + } else if (op.position < offset || op.position === offset && affinity === 'forward') { + p.offset -= op.position; + p.path = Path.transform(path, op, _objectSpread$6(_objectSpread$6({}, options), {}, { + affinity: 'forward' + })); + } + } else { + p.path = Path.transform(path, op, options); + } + + break; + } + } + }); + } + }; + + var PointRef = { + /** + * Transform the point ref's current value by an operation. + */ + transform: function transform(ref, op) { + var current = ref.current, + affinity = ref.affinity; + + if (current == null) { + return; + } + + var point = Point.transform(current, op, { + affinity: affinity + }); + ref.current = point; + + if (point == null) { + ref.unref(); + } + } + }; + + var _excluded$2 = ["anchor", "focus"]; + + function ownKeys$5(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } + + function _objectSpread$5(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$5(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$5(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + var Range = { + /** + * Get the start and end points of a range, in the order in which they appear + * in the document. + */ + edges: function edges(range) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _options$reverse = options.reverse, + reverse = _options$reverse === void 0 ? false : _options$reverse; + var anchor = range.anchor, + focus = range.focus; + return Range.isBackward(range) === reverse ? [anchor, focus] : [focus, anchor]; + }, + + /** + * Get the end point of a range. + */ + end: function end(range) { + var _Range$edges = Range.edges(range), + _Range$edges2 = _slicedToArray(_Range$edges, 2), + end = _Range$edges2[1]; + + return end; + }, + + /** + * Check if a range is exactly equal to another. + */ + equals: function equals(range, another) { + return Point.equals(range.anchor, another.anchor) && Point.equals(range.focus, another.focus); + }, + + /** + * Check if a range includes a path, a point or part of another range. + */ + includes: function includes(range, target) { + if (Range.isRange(target)) { + if (Range.includes(range, target.anchor) || Range.includes(range, target.focus)) { + return true; + } + + var _Range$edges3 = Range.edges(range), + _Range$edges4 = _slicedToArray(_Range$edges3, 2), + rs = _Range$edges4[0], + re = _Range$edges4[1]; + + var _Range$edges5 = Range.edges(target), + _Range$edges6 = _slicedToArray(_Range$edges5, 2), + ts = _Range$edges6[0], + te = _Range$edges6[1]; + + return Point.isBefore(rs, ts) && Point.isAfter(re, te); + } + + var _Range$edges7 = Range.edges(range), + _Range$edges8 = _slicedToArray(_Range$edges7, 2), + start = _Range$edges8[0], + end = _Range$edges8[1]; + + var isAfterStart = false; + var isBeforeEnd = false; + + if (Point.isPoint(target)) { + isAfterStart = Point.compare(target, start) >= 0; + isBeforeEnd = Point.compare(target, end) <= 0; + } else { + isAfterStart = Path.compare(target, start.path) >= 0; + isBeforeEnd = Path.compare(target, end.path) <= 0; + } + + return isAfterStart && isBeforeEnd; + }, + + /** + * Get the intersection of a range with another. + */ + intersection: function intersection(range, another) { + range.anchor; + range.focus; + var rest = _objectWithoutProperties(range, _excluded$2); + + var _Range$edges9 = Range.edges(range), + _Range$edges10 = _slicedToArray(_Range$edges9, 2), + s1 = _Range$edges10[0], + e1 = _Range$edges10[1]; + + var _Range$edges11 = Range.edges(another), + _Range$edges12 = _slicedToArray(_Range$edges11, 2), + s2 = _Range$edges12[0], + e2 = _Range$edges12[1]; + + var start = Point.isBefore(s1, s2) ? s2 : s1; + var end = Point.isBefore(e1, e2) ? e1 : e2; + + if (Point.isBefore(end, start)) { + return null; + } else { + return _objectSpread$5({ + anchor: start, + focus: end + }, rest); + } + }, + + /** + * Check if a range is backward, meaning that its anchor point appears in the + * document _after_ its focus point. + */ + isBackward: function isBackward(range) { + var anchor = range.anchor, + focus = range.focus; + return Point.isAfter(anchor, focus); + }, + + /** + * Check if a range is collapsed, meaning that both its anchor and focus + * points refer to the exact same position in the document. + */ + isCollapsed: function isCollapsed(range) { + var anchor = range.anchor, + focus = range.focus; + return Point.equals(anchor, focus); + }, + + /** + * Check if a range is expanded. + * + * This is the opposite of [[Range.isCollapsed]] and is provided for legibility. + */ + isExpanded: function isExpanded(range) { + return !Range.isCollapsed(range); + }, + + /** + * Check if a range is forward. + * + * This is the opposite of [[Range.isBackward]] and is provided for legibility. + */ + isForward: function isForward(range) { + return !Range.isBackward(range); + }, + + /** + * Check if a value implements the [[Range]] interface. + */ + isRange: function isRange(value) { + return isPlainObject.isPlainObject(value) && Point.isPoint(value.anchor) && Point.isPoint(value.focus); + }, + + /** + * Iterate through all of the point entries in a range. + */ + points: function* points(range) { + yield [range.anchor, 'anchor']; + yield [range.focus, 'focus']; + }, + + /** + * Get the start point of a range. + */ + start: function start(range) { + var _Range$edges13 = Range.edges(range), + _Range$edges14 = _slicedToArray(_Range$edges13, 1), + start = _Range$edges14[0]; + + return start; + }, + + /** + * Transform a range by an operation. + */ + transform: function transform(range, op) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + return immer.produce(range, function (r) { + if (r === null) { + return null; + } + + var _options$affinity = options.affinity, + affinity = _options$affinity === void 0 ? 'inward' : _options$affinity; + var affinityAnchor; + var affinityFocus; + + if (affinity === 'inward') { + // If the range is collapsed, make sure to use the same affinity to + // avoid the two points passing each other and expanding in the opposite + // direction + var isCollapsed = Range.isCollapsed(r); + + if (Range.isForward(r)) { + affinityAnchor = 'forward'; + affinityFocus = isCollapsed ? affinityAnchor : 'backward'; + } else { + affinityAnchor = 'backward'; + affinityFocus = isCollapsed ? affinityAnchor : 'forward'; + } + } else if (affinity === 'outward') { + if (Range.isForward(r)) { + affinityAnchor = 'backward'; + affinityFocus = 'forward'; + } else { + affinityAnchor = 'forward'; + affinityFocus = 'backward'; + } + } else { + affinityAnchor = affinity; + affinityFocus = affinity; + } + + var anchor = Point.transform(r.anchor, op, { + affinity: affinityAnchor + }); + var focus = Point.transform(r.focus, op, { + affinity: affinityFocus + }); + + if (!anchor || !focus) { + return null; + } + + r.anchor = anchor; + r.focus = focus; + }); + } + }; + + var RangeRef = { + /** + * Transform the range ref's current value by an operation. + */ + transform: function transform(ref, op) { + var current = ref.current, + affinity = ref.affinity; + + if (current == null) { + return; + } + + var path = Range.transform(current, op, { + affinity: affinity + }); + ref.current = path; + + if (path == null) { + ref.unref(); + } + } + }; + + /* + Custom deep equal comparison for Slate nodes. + + We don't need general purpose deep equality; + Slate only supports plain values, Arrays, and nested objects. + Complex values nested inside Arrays are not supported. + + Slate objects are designed to be serialised, so + missing keys are deliberately normalised to undefined. + */ + + var isDeepEqual = function isDeepEqual(node, another) { + for (var key in node) { + var a = node[key]; + var b = another[key]; + + if (isPlainObject.isPlainObject(a) && isPlainObject.isPlainObject(b)) { + if (!isDeepEqual(a, b)) return false; + } else if (Array.isArray(a) && Array.isArray(b)) { + if (a.length !== b.length) return false; + + for (var i = 0; i < a.length; i++) { + if (a[i] !== b[i]) return false; + } + } else if (a !== b) { + return false; + } + } + /* + Deep object equality is only necessary in one direction; in the reverse direction + we are only looking for keys that are missing. + As above, undefined keys are normalised to missing. + */ + + + for (var _key in another) { + if (node[_key] === undefined && another[_key] !== undefined) { + return false; + } + } + + return true; + }; + + var _excluded$1 = ["text"], + _excluded2$1 = ["anchor", "focus"]; + + function _createForOfIteratorHelper$3(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$3(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } + + function _unsupportedIterableToArray$3(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$3(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$3(o, minLen); } + + function _arrayLikeToArray$3(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + + function ownKeys$4(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } + + function _objectSpread$4(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$4(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$4(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + var Text = { + /** + * Check if two text nodes are equal. + * + * When loose is set, the text is not compared. This is + * used to check whether sibling text nodes can be merged. + */ + equals: function equals(text, another) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var _options$loose = options.loose, + loose = _options$loose === void 0 ? false : _options$loose; + + function omitText(obj) { + obj.text; + var rest = _objectWithoutProperties(obj, _excluded$1); + + return rest; + } + + return isDeepEqual(loose ? omitText(text) : text, loose ? omitText(another) : another); + }, + + /** + * Check if a value implements the `Text` interface. + */ + isText: function isText(value) { + return isPlainObject.isPlainObject(value) && typeof value.text === 'string'; + }, + + /** + * Check if a value is a list of `Text` objects. + */ + isTextList: function isTextList(value) { + return Array.isArray(value) && value.every(function (val) { + return Text.isText(val); + }); + }, + + /** + * Check if some props are a partial of Text. + */ + isTextProps: function isTextProps(props) { + return props.text !== undefined; + }, + + /** + * Check if an text matches set of properties. + * + * Note: this is for matching custom properties, and it does not ensure that + * the `text` property are two nodes equal. + */ + matches: function matches(text, props) { + for (var key in props) { + if (key === 'text') { + continue; + } + + if (!text.hasOwnProperty(key) || text[key] !== props[key]) { + return false; + } + } + + return true; + }, + + /** + * Get the leaves for a text node given decorations. + */ + decorations: function decorations(node, _decorations) { + var leaves = [_objectSpread$4({}, node)]; + + var _iterator = _createForOfIteratorHelper$3(_decorations), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var dec = _step.value; + + var anchor = dec.anchor, + focus = dec.focus, + rest = _objectWithoutProperties(dec, _excluded2$1); + + var _Range$edges = Range.edges(dec), + _Range$edges2 = _slicedToArray(_Range$edges, 2), + start = _Range$edges2[0], + end = _Range$edges2[1]; + + var next = []; + var o = 0; + + var _iterator2 = _createForOfIteratorHelper$3(leaves), + _step2; + + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var leaf = _step2.value; + var length = leaf.text.length; + var offset = o; + o += length; // If the range encompases the entire leaf, add the range. + + if (start.offset <= offset && end.offset >= o) { + Object.assign(leaf, rest); + next.push(leaf); + continue; + } // If the range expanded and match the leaf, or starts after, or ends before it, continue. + + + if (start.offset !== end.offset && (start.offset === o || end.offset === offset) || start.offset > o || end.offset < offset || end.offset === offset && offset !== 0) { + next.push(leaf); + continue; + } // Otherwise we need to split the leaf, at the start, end, or both, + // and add the range to the middle intersecting section. Do the end + // split first since we don't need to update the offset that way. + + + var middle = leaf; + var before = void 0; + var after = void 0; + + if (end.offset < o) { + var off = end.offset - offset; + after = _objectSpread$4(_objectSpread$4({}, middle), {}, { + text: middle.text.slice(off) + }); + middle = _objectSpread$4(_objectSpread$4({}, middle), {}, { + text: middle.text.slice(0, off) + }); + } + + if (start.offset > offset) { + var _off = start.offset - offset; + + before = _objectSpread$4(_objectSpread$4({}, middle), {}, { + text: middle.text.slice(0, _off) + }); + middle = _objectSpread$4(_objectSpread$4({}, middle), {}, { + text: middle.text.slice(_off) + }); + } + + Object.assign(middle, rest); + + if (before) { + next.push(before); + } + + next.push(middle); + + if (after) { + next.push(after); + } + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + + leaves = next; + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + + return leaves; + } + }; + + function ownKeys$3(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } + + function _objectSpread$3(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$3(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$3(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + + function _createForOfIteratorHelper$2(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$2(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } + + function _unsupportedIterableToArray$2(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$2(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$2(o, minLen); } + + function _arrayLikeToArray$2(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + + var applyToDraft = function applyToDraft(editor, selection, op) { + switch (op.type) { + case 'insert_node': + { + var path = op.path, + node = op.node; + var parent = Node$1.parent(editor, path); + var index = path[path.length - 1]; + + if (index > parent.children.length) { + throw new Error("Cannot apply an \"insert_node\" operation at path [".concat(path, "] because the destination is past the end of the node.")); + } + + parent.children.splice(index, 0, node); + + if (selection) { + var _iterator = _createForOfIteratorHelper$2(Range.points(selection)), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var _step$value = _slicedToArray(_step.value, 2), + point = _step$value[0], + key = _step$value[1]; + + selection[key] = Point.transform(point, op); + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + } + + break; + } + + case 'insert_text': + { + var _path = op.path, + offset = op.offset, + text = op.text; + if (text.length === 0) break; + + var _node = Node$1.leaf(editor, _path); + + var before = _node.text.slice(0, offset); + + var after = _node.text.slice(offset); + + _node.text = before + text + after; + + if (selection) { + var _iterator2 = _createForOfIteratorHelper$2(Range.points(selection)), + _step2; + + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var _step2$value = _slicedToArray(_step2.value, 2), + _point = _step2$value[0], + _key = _step2$value[1]; + + selection[_key] = Point.transform(_point, op); + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + } + + break; + } + + case 'merge_node': + { + var _path2 = op.path; + + var _node2 = Node$1.get(editor, _path2); + + var prevPath = Path.previous(_path2); + var prev = Node$1.get(editor, prevPath); + + var _parent = Node$1.parent(editor, _path2); + + var _index = _path2[_path2.length - 1]; + + if (Text.isText(_node2) && Text.isText(prev)) { + prev.text += _node2.text; + } else if (!Text.isText(_node2) && !Text.isText(prev)) { + var _prev$children; + + (_prev$children = prev.children).push.apply(_prev$children, _toConsumableArray(_node2.children)); + } else { + throw new Error("Cannot apply a \"merge_node\" operation at path [".concat(_path2, "] to nodes of different interfaces: ").concat(_node2, " ").concat(prev)); + } + + _parent.children.splice(_index, 1); + + if (selection) { + var _iterator3 = _createForOfIteratorHelper$2(Range.points(selection)), + _step3; + + try { + for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { + var _step3$value = _slicedToArray(_step3.value, 2), + _point2 = _step3$value[0], + _key2 = _step3$value[1]; + + selection[_key2] = Point.transform(_point2, op); + } + } catch (err) { + _iterator3.e(err); + } finally { + _iterator3.f(); + } + } + + break; + } + + case 'move_node': + { + var _path3 = op.path, + newPath = op.newPath; + + if (Path.isAncestor(_path3, newPath)) { + throw new Error("Cannot move a path [".concat(_path3, "] to new path [").concat(newPath, "] because the destination is inside itself.")); + } + + var _node3 = Node$1.get(editor, _path3); + + var _parent2 = Node$1.parent(editor, _path3); + + var _index2 = _path3[_path3.length - 1]; // This is tricky, but since the `path` and `newPath` both refer to + // the same snapshot in time, there's a mismatch. After either + // removing the original position, the second step's path can be out + // of date. So instead of using the `op.newPath` directly, we + // transform `op.path` to ascertain what the `newPath` would be after + // the operation was applied. + + _parent2.children.splice(_index2, 1); + + var truePath = Path.transform(_path3, op); + var newParent = Node$1.get(editor, Path.parent(truePath)); + var newIndex = truePath[truePath.length - 1]; + newParent.children.splice(newIndex, 0, _node3); + + if (selection) { + var _iterator4 = _createForOfIteratorHelper$2(Range.points(selection)), + _step4; + + try { + for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) { + var _step4$value = _slicedToArray(_step4.value, 2), + _point3 = _step4$value[0], + _key3 = _step4$value[1]; + + selection[_key3] = Point.transform(_point3, op); + } + } catch (err) { + _iterator4.e(err); + } finally { + _iterator4.f(); + } + } + + break; + } + + case 'remove_node': + { + var _path4 = op.path; + var _index3 = _path4[_path4.length - 1]; + + var _parent3 = Node$1.parent(editor, _path4); + + _parent3.children.splice(_index3, 1); // Transform all of the points in the value, but if the point was in the + // node that was removed we need to update the range or remove it. + + + if (selection) { + var _iterator5 = _createForOfIteratorHelper$2(Range.points(selection)), + _step5; + + try { + for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) { + var _step5$value = _slicedToArray(_step5.value, 2), + _point4 = _step5$value[0], + _key4 = _step5$value[1]; + + var result = Point.transform(_point4, op); + + if (selection != null && result != null) { + selection[_key4] = result; + } else { + var _prev = void 0; + + var next = void 0; + + var _iterator6 = _createForOfIteratorHelper$2(Node$1.texts(editor)), + _step6; + + try { + for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) { + var _step6$value = _slicedToArray(_step6.value, 2), + n = _step6$value[0], + p = _step6$value[1]; + + if (Path.compare(p, _path4) === -1) { + _prev = [n, p]; + } else { + next = [n, p]; + break; + } + } + } catch (err) { + _iterator6.e(err); + } finally { + _iterator6.f(); + } + + var preferNext = false; + + if (_prev && next) { + if (Path.equals(next[1], _path4)) { + preferNext = !Path.hasPrevious(next[1]); + } else { + preferNext = Path.common(_prev[1], _path4).length < Path.common(next[1], _path4).length; + } + } + + if (_prev && !preferNext) { + _point4.path = _prev[1]; + _point4.offset = _prev[0].text.length; + } else if (next) { + _point4.path = next[1]; + _point4.offset = 0; + } else { + selection = null; + } + } + } + } catch (err) { + _iterator5.e(err); + } finally { + _iterator5.f(); + } + } + + break; + } + + case 'remove_text': + { + var _path5 = op.path, + _offset = op.offset, + _text = op.text; + if (_text.length === 0) break; + + var _node4 = Node$1.leaf(editor, _path5); + + var _before = _node4.text.slice(0, _offset); + + var _after = _node4.text.slice(_offset + _text.length); + + _node4.text = _before + _after; + + if (selection) { + var _iterator7 = _createForOfIteratorHelper$2(Range.points(selection)), + _step7; + + try { + for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) { + var _step7$value = _slicedToArray(_step7.value, 2), + _point5 = _step7$value[0], + _key5 = _step7$value[1]; + + selection[_key5] = Point.transform(_point5, op); + } + } catch (err) { + _iterator7.e(err); + } finally { + _iterator7.f(); + } + } + + break; + } + + case 'set_node': + { + var _path6 = op.path, + properties = op.properties, + newProperties = op.newProperties; + + if (_path6.length === 0) { + throw new Error("Cannot set properties on the root node!"); + } + + var _node5 = Node$1.get(editor, _path6); + + for (var _key6 in newProperties) { + if (_key6 === 'children' || _key6 === 'text') { + throw new Error("Cannot set the \"".concat(_key6, "\" property of nodes!")); + } + + var value = newProperties[_key6]; + + if (value == null) { + delete _node5[_key6]; + } else { + _node5[_key6] = value; + } + } // properties that were previously defined, but are now missing, must be deleted + + + for (var _key7 in properties) { + if (!newProperties.hasOwnProperty(_key7)) { + delete _node5[_key7]; + } + } + + break; + } + + case 'set_selection': + { + var _newProperties = op.newProperties; + + if (_newProperties == null) { + selection = _newProperties; + } else { + if (selection == null) { + if (!Range.isRange(_newProperties)) { + throw new Error("Cannot apply an incomplete \"set_selection\" operation properties ".concat(JSON.stringify(_newProperties), " when there is no current selection.")); + } + + selection = _objectSpread$3({}, _newProperties); + } + + for (var _key8 in _newProperties) { + var _value = _newProperties[_key8]; + + if (_value == null) { + if (_key8 === 'anchor' || _key8 === 'focus') { + throw new Error("Cannot remove the \"".concat(_key8, "\" selection property")); + } + + delete selection[_key8]; + } else { + selection[_key8] = _value; + } + } + } + + break; + } + + case 'split_node': + { + var _path7 = op.path, + position = op.position, + _properties = op.properties; + + if (_path7.length === 0) { + throw new Error("Cannot apply a \"split_node\" operation at path [".concat(_path7, "] because the root node cannot be split.")); + } + + var _node6 = Node$1.get(editor, _path7); + + var _parent4 = Node$1.parent(editor, _path7); + + var _index4 = _path7[_path7.length - 1]; + var newNode; + + if (Text.isText(_node6)) { + var _before2 = _node6.text.slice(0, position); + + var _after2 = _node6.text.slice(position); + + _node6.text = _before2; + newNode = _objectSpread$3(_objectSpread$3({}, _properties), {}, { + text: _after2 + }); + } else { + var _before3 = _node6.children.slice(0, position); + + var _after3 = _node6.children.slice(position); + + _node6.children = _before3; + newNode = _objectSpread$3(_objectSpread$3({}, _properties), {}, { + children: _after3 + }); + } + + _parent4.children.splice(_index4 + 1, 0, newNode); + + if (selection) { + var _iterator8 = _createForOfIteratorHelper$2(Range.points(selection)), + _step8; + + try { + for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) { + var _step8$value = _slicedToArray(_step8.value, 2), + _point6 = _step8$value[0], + _key9 = _step8$value[1]; + + selection[_key9] = Point.transform(_point6, op); + } + } catch (err) { + _iterator8.e(err); + } finally { + _iterator8.f(); + } + } + + break; + } + } + + return selection; + }; + + var GeneralTransforms = { + /** + * Transform the editor by an operation. + */ + transform: function transform(editor, op) { + editor.children = immer.createDraft(editor.children); + var selection = editor.selection && immer.createDraft(editor.selection); + + try { + selection = applyToDraft(editor, selection, op); + } finally { + editor.children = immer.finishDraft(editor.children); + + if (selection) { + editor.selection = immer.isDraft(selection) ? immer.finishDraft(selection) : selection; + } else { + editor.selection = null; + } + } + } + }; + + var _excluded = ["text"], + _excluded2 = ["children"]; + + function ownKeys$2(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } + + function _objectSpread$2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$2(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$2(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + + function _createForOfIteratorHelper$1(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$1(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } + + function _unsupportedIterableToArray$1(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$1(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$1(o, minLen); } + + function _arrayLikeToArray$1(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + var NodeTransforms = { + /** + * Insert nodes at a specific location in the Editor. + */ + insertNodes: function insertNodes(editor, nodes) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + Editor.withoutNormalizing(editor, function () { + var _options$hanging = options.hanging, + hanging = _options$hanging === void 0 ? false : _options$hanging, + _options$voids = options.voids, + voids = _options$voids === void 0 ? false : _options$voids, + _options$mode = options.mode, + mode = _options$mode === void 0 ? 'lowest' : _options$mode; + var at = options.at, + match = options.match, + select = options.select; + + if (Node$1.isNode(nodes)) { + nodes = [nodes]; + } + + if (nodes.length === 0) { + return; + } + + var _nodes = nodes, + _nodes2 = _slicedToArray(_nodes, 1), + node = _nodes2[0]; // By default, use the selection as the target location. But if there is + // no selection, insert at the end of the document since that is such a + // common use case when inserting from a non-selected state. + + + if (!at) { + if (editor.selection) { + at = editor.selection; + } else if (editor.children.length > 0) { + at = Editor.end(editor, []); + } else { + at = [0]; + } + + select = true; + } + + if (select == null) { + select = false; + } + + if (Range.isRange(at)) { + if (!hanging) { + at = Editor.unhangRange(editor, at); + } + + if (Range.isCollapsed(at)) { + at = at.anchor; + } else { + var _Range$edges = Range.edges(at), + _Range$edges2 = _slicedToArray(_Range$edges, 2), + end = _Range$edges2[1]; + + var pointRef = Editor.pointRef(editor, end); + Transforms["delete"](editor, { + at: at + }); + at = pointRef.unref(); + } + } + + if (Point.isPoint(at)) { + if (match == null) { + if (Text.isText(node)) { + match = function match(n) { + return Text.isText(n); + }; + } else if (editor.isInline(node)) { + match = function match(n) { + return Text.isText(n) || Editor.isInline(editor, n); + }; + } else { + match = function match(n) { + return Editor.isBlock(editor, n); + }; + } + } + + var _Editor$nodes = Editor.nodes(editor, { + at: at.path, + match: match, + mode: mode, + voids: voids + }), + _Editor$nodes2 = _slicedToArray(_Editor$nodes, 1), + entry = _Editor$nodes2[0]; + + if (entry) { + var _entry = _slicedToArray(entry, 2), + _matchPath = _entry[1]; + + var pathRef = Editor.pathRef(editor, _matchPath); + var isAtEnd = Editor.isEnd(editor, at, _matchPath); + Transforms.splitNodes(editor, { + at: at, + match: match, + mode: mode, + voids: voids + }); + var path = pathRef.unref(); + at = isAtEnd ? Path.next(path) : path; + } else { + return; + } + } + + var parentPath = Path.parent(at); + var index = at[at.length - 1]; + + if (!voids && Editor["void"](editor, { + at: parentPath + })) { + return; + } + + var _iterator = _createForOfIteratorHelper$1(nodes), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var _node = _step.value; + + var _path = parentPath.concat(index); + + index++; + editor.apply({ + type: 'insert_node', + path: _path, + node: _node + }); + at = Path.next(at); + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + + at = Path.previous(at); + + if (select) { + var point = Editor.end(editor, at); + + if (point) { + Transforms.select(editor, point); + } + } + }); + }, + + /** + * Lift nodes at a specific location upwards in the document tree, splitting + * their parent in two if necessary. + */ + liftNodes: function liftNodes(editor) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + Editor.withoutNormalizing(editor, function () { + var _options$at = options.at, + at = _options$at === void 0 ? editor.selection : _options$at, + _options$mode2 = options.mode, + mode = _options$mode2 === void 0 ? 'lowest' : _options$mode2, + _options$voids2 = options.voids, + voids = _options$voids2 === void 0 ? false : _options$voids2; + var match = options.match; + + if (match == null) { + match = Path.isPath(at) ? matchPath(editor, at) : function (n) { + return Editor.isBlock(editor, n); + }; + } + + if (!at) { + return; + } + + var matches = Editor.nodes(editor, { + at: at, + match: match, + mode: mode, + voids: voids + }); + var pathRefs = Array.from(matches, function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + p = _ref2[1]; + + return Editor.pathRef(editor, p); + }); + + for (var _i = 0, _pathRefs = pathRefs; _i < _pathRefs.length; _i++) { + var pathRef = _pathRefs[_i]; + var path = pathRef.unref(); + + if (path.length < 2) { + throw new Error("Cannot lift node at a path [".concat(path, "] because it has a depth of less than `2`.")); + } + + var parentNodeEntry = Editor.node(editor, Path.parent(path)); + + var _parentNodeEntry = _slicedToArray(parentNodeEntry, 2), + parent = _parentNodeEntry[0], + parentPath = _parentNodeEntry[1]; + + var index = path[path.length - 1]; + var length = parent.children.length; + + if (length === 1) { + var toPath = Path.next(parentPath); + Transforms.moveNodes(editor, { + at: path, + to: toPath, + voids: voids + }); + Transforms.removeNodes(editor, { + at: parentPath, + voids: voids + }); + } else if (index === 0) { + Transforms.moveNodes(editor, { + at: path, + to: parentPath, + voids: voids + }); + } else if (index === length - 1) { + var _toPath = Path.next(parentPath); + + Transforms.moveNodes(editor, { + at: path, + to: _toPath, + voids: voids + }); + } else { + var splitPath = Path.next(path); + + var _toPath2 = Path.next(parentPath); + + Transforms.splitNodes(editor, { + at: splitPath, + voids: voids + }); + Transforms.moveNodes(editor, { + at: path, + to: _toPath2, + voids: voids + }); + } + } + }); + }, + + /** + * Merge a node at a location with the previous node of the same depth, + * removing any empty containing nodes after the merge if necessary. + */ + mergeNodes: function mergeNodes(editor) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + Editor.withoutNormalizing(editor, function () { + var match = options.match, + _options$at2 = options.at, + at = _options$at2 === void 0 ? editor.selection : _options$at2; + var _options$hanging2 = options.hanging, + hanging = _options$hanging2 === void 0 ? false : _options$hanging2, + _options$voids3 = options.voids, + voids = _options$voids3 === void 0 ? false : _options$voids3, + _options$mode3 = options.mode, + mode = _options$mode3 === void 0 ? 'lowest' : _options$mode3; + + if (!at) { + return; + } + + if (match == null) { + if (Path.isPath(at)) { + var _Editor$parent = Editor.parent(editor, at), + _Editor$parent2 = _slicedToArray(_Editor$parent, 1), + parent = _Editor$parent2[0]; + + match = function match(n) { + return parent.children.includes(n); + }; + } else { + match = function match(n) { + return Editor.isBlock(editor, n); + }; + } + } + + if (!hanging && Range.isRange(at)) { + at = Editor.unhangRange(editor, at); + } + + if (Range.isRange(at)) { + if (Range.isCollapsed(at)) { + at = at.anchor; + } else { + var _Range$edges3 = Range.edges(at), + _Range$edges4 = _slicedToArray(_Range$edges3, 2), + end = _Range$edges4[1]; + + var pointRef = Editor.pointRef(editor, end); + Transforms["delete"](editor, { + at: at + }); + at = pointRef.unref(); + + if (options.at == null) { + Transforms.select(editor, at); + } + } + } + + var _Editor$nodes3 = Editor.nodes(editor, { + at: at, + match: match, + voids: voids, + mode: mode + }), + _Editor$nodes4 = _slicedToArray(_Editor$nodes3, 1), + current = _Editor$nodes4[0]; + + var prev = Editor.previous(editor, { + at: at, + match: match, + voids: voids, + mode: mode + }); + + if (!current || !prev) { + return; + } + + var _current = _slicedToArray(current, 2), + node = _current[0], + path = _current[1]; + + var _prev = _slicedToArray(prev, 2), + prevNode = _prev[0], + prevPath = _prev[1]; + + if (path.length === 0 || prevPath.length === 0) { + return; + } + + var newPath = Path.next(prevPath); + var commonPath = Path.common(path, prevPath); + var isPreviousSibling = Path.isSibling(path, prevPath); + var levels = Array.from(Editor.levels(editor, { + at: path + }), function (_ref3) { + var _ref4 = _slicedToArray(_ref3, 1), + n = _ref4[0]; + + return n; + }).slice(commonPath.length).slice(0, -1); // Determine if the merge will leave an ancestor of the path empty as a + // result, in which case we'll want to remove it after merging. + + var emptyAncestor = Editor.above(editor, { + at: path, + mode: 'highest', + match: function match(n) { + return levels.includes(n) && hasSingleChildNest(editor, n); + } + }); + var emptyRef = emptyAncestor && Editor.pathRef(editor, emptyAncestor[1]); + var properties; + var position; // Ensure that the nodes are equivalent, and figure out what the position + // and extra properties of the merge will be. + + if (Text.isText(node) && Text.isText(prevNode)) { + node.text; + var rest = _objectWithoutProperties(node, _excluded); + + position = prevNode.text.length; + properties = rest; + } else if (Element$1.isElement(node) && Element$1.isElement(prevNode)) { + node.children; + var _rest = _objectWithoutProperties(node, _excluded2); + + position = prevNode.children.length; + properties = _rest; + } else { + throw new Error("Cannot merge the node at path [".concat(path, "] with the previous sibling because it is not the same kind: ").concat(JSON.stringify(node), " ").concat(JSON.stringify(prevNode))); + } // If the node isn't already the next sibling of the previous node, move + // it so that it is before merging. + + + if (!isPreviousSibling) { + Transforms.moveNodes(editor, { + at: path, + to: newPath, + voids: voids + }); + } // If there was going to be an empty ancestor of the node that was merged, + // we remove it from the tree. + + + if (emptyRef) { + Transforms.removeNodes(editor, { + at: emptyRef.current, + voids: voids + }); + } // If the target node that we're merging with is empty, remove it instead + // of merging the two. This is a common rich text editor behavior to + // prevent losing formatting when deleting entire nodes when you have a + // hanging selection. + // if prevNode is first child in parent,don't remove it. + + + if (Element$1.isElement(prevNode) && Editor.isEmpty(editor, prevNode) || Text.isText(prevNode) && prevNode.text === '' && prevPath[prevPath.length - 1] !== 0) { + Transforms.removeNodes(editor, { + at: prevPath, + voids: voids + }); + } else { + editor.apply({ + type: 'merge_node', + path: newPath, + position: position, + properties: properties + }); + } + + if (emptyRef) { + emptyRef.unref(); + } + }); + }, + + /** + * Move the nodes at a location to a new location. + */ + moveNodes: function moveNodes(editor, options) { + Editor.withoutNormalizing(editor, function () { + var to = options.to, + _options$at3 = options.at, + at = _options$at3 === void 0 ? editor.selection : _options$at3, + _options$mode4 = options.mode, + mode = _options$mode4 === void 0 ? 'lowest' : _options$mode4, + _options$voids4 = options.voids, + voids = _options$voids4 === void 0 ? false : _options$voids4; + var match = options.match; + + if (!at) { + return; + } + + if (match == null) { + match = Path.isPath(at) ? matchPath(editor, at) : function (n) { + return Editor.isBlock(editor, n); + }; + } + + var toRef = Editor.pathRef(editor, to); + var targets = Editor.nodes(editor, { + at: at, + match: match, + mode: mode, + voids: voids + }); + var pathRefs = Array.from(targets, function (_ref5) { + var _ref6 = _slicedToArray(_ref5, 2), + p = _ref6[1]; + + return Editor.pathRef(editor, p); + }); + + for (var _i2 = 0, _pathRefs2 = pathRefs; _i2 < _pathRefs2.length; _i2++) { + var pathRef = _pathRefs2[_i2]; + var path = pathRef.unref(); + var newPath = toRef.current; + + if (path.length !== 0) { + editor.apply({ + type: 'move_node', + path: path, + newPath: newPath + }); + } + + if (toRef.current && Path.isSibling(newPath, path) && Path.isAfter(newPath, path)) { + // When performing a sibling move to a later index, the path at the destination is shifted + // to before the insertion point instead of after. To ensure our group of nodes are inserted + // in the correct order we increment toRef to account for that + toRef.current = Path.next(toRef.current); + } + } + + toRef.unref(); + }); + }, + + /** + * Remove the nodes at a specific location in the document. + */ + removeNodes: function removeNodes(editor) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + Editor.withoutNormalizing(editor, function () { + var _options$hanging3 = options.hanging, + hanging = _options$hanging3 === void 0 ? false : _options$hanging3, + _options$voids5 = options.voids, + voids = _options$voids5 === void 0 ? false : _options$voids5, + _options$mode5 = options.mode, + mode = _options$mode5 === void 0 ? 'lowest' : _options$mode5; + var _options$at4 = options.at, + at = _options$at4 === void 0 ? editor.selection : _options$at4, + match = options.match; + + if (!at) { + return; + } + + if (match == null) { + match = Path.isPath(at) ? matchPath(editor, at) : function (n) { + return Editor.isBlock(editor, n); + }; + } + + if (!hanging && Range.isRange(at)) { + at = Editor.unhangRange(editor, at); + } + + var depths = Editor.nodes(editor, { + at: at, + match: match, + mode: mode, + voids: voids + }); + var pathRefs = Array.from(depths, function (_ref7) { + var _ref8 = _slicedToArray(_ref7, 2), + p = _ref8[1]; + + return Editor.pathRef(editor, p); + }); + + for (var _i3 = 0, _pathRefs3 = pathRefs; _i3 < _pathRefs3.length; _i3++) { + var pathRef = _pathRefs3[_i3]; + var path = pathRef.unref(); + + if (path) { + var _Editor$node = Editor.node(editor, path), + _Editor$node2 = _slicedToArray(_Editor$node, 1), + node = _Editor$node2[0]; + + editor.apply({ + type: 'remove_node', + path: path, + node: node + }); + } + } + }); + }, + + /** + * Set new properties on the nodes at a location. + */ + setNodes: function setNodes(editor, props) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + Editor.withoutNormalizing(editor, function () { + var match = options.match, + _options$at5 = options.at, + at = _options$at5 === void 0 ? editor.selection : _options$at5; + var _options$hanging4 = options.hanging, + hanging = _options$hanging4 === void 0 ? false : _options$hanging4, + _options$mode6 = options.mode, + mode = _options$mode6 === void 0 ? 'lowest' : _options$mode6, + _options$split = options.split, + split = _options$split === void 0 ? false : _options$split, + _options$voids6 = options.voids, + voids = _options$voids6 === void 0 ? false : _options$voids6; + + if (!at) { + return; + } + + if (match == null) { + match = Path.isPath(at) ? matchPath(editor, at) : function (n) { + return Editor.isBlock(editor, n); + }; + } + + if (!hanging && Range.isRange(at)) { + at = Editor.unhangRange(editor, at); + } + + if (split && Range.isRange(at)) { + if (Range.isCollapsed(at) && Editor.leaf(editor, at.anchor)[0].text.length > 0) { + // If the range is collapsed in a non-empty node and 'split' is true, there's nothing to + // set that won't get normalized away + return; + } + + var rangeRef = Editor.rangeRef(editor, at, { + affinity: 'inward' + }); + + var _Range$edges5 = Range.edges(at), + _Range$edges6 = _slicedToArray(_Range$edges5, 2), + start = _Range$edges6[0], + end = _Range$edges6[1]; + + var splitMode = mode === 'lowest' ? 'lowest' : 'highest'; + var endAtEndOfNode = Editor.isEnd(editor, end, end.path); + Transforms.splitNodes(editor, { + at: end, + match: match, + mode: splitMode, + voids: voids, + always: !endAtEndOfNode + }); + var startAtStartOfNode = Editor.isStart(editor, start, start.path); + Transforms.splitNodes(editor, { + at: start, + match: match, + mode: splitMode, + voids: voids, + always: !startAtStartOfNode + }); + at = rangeRef.unref(); + + if (options.at == null) { + Transforms.select(editor, at); + } + } + + var _iterator2 = _createForOfIteratorHelper$1(Editor.nodes(editor, { + at: at, + match: match, + mode: mode, + voids: voids + })), + _step2; + + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var _step2$value = _slicedToArray(_step2.value, 2), + node = _step2$value[0], + path = _step2$value[1]; + + var properties = {}; + var newProperties = {}; // You can't set properties on the editor node. + + if (path.length === 0) { + continue; + } + + var hasChanges = false; + + for (var k in props) { + if (k === 'children' || k === 'text') { + continue; + } + + if (props[k] !== node[k]) { + hasChanges = true; // Omit new properties from the old properties list + + if (node.hasOwnProperty(k)) properties[k] = node[k]; // Omit properties that have been removed from the new properties list + + if (props[k] != null) newProperties[k] = props[k]; + } + } + + if (hasChanges) { + editor.apply({ + type: 'set_node', + path: path, + properties: properties, + newProperties: newProperties + }); + } + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + }); + }, + + /** + * Split the nodes at a specific location. + */ + splitNodes: function splitNodes(editor) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + Editor.withoutNormalizing(editor, function () { + var _options$mode7 = options.mode, + mode = _options$mode7 === void 0 ? 'lowest' : _options$mode7, + _options$voids7 = options.voids, + voids = _options$voids7 === void 0 ? false : _options$voids7; + var match = options.match, + _options$at6 = options.at, + at = _options$at6 === void 0 ? editor.selection : _options$at6, + _options$height = options.height, + height = _options$height === void 0 ? 0 : _options$height, + _options$always = options.always, + always = _options$always === void 0 ? false : _options$always; + + if (match == null) { + match = function match(n) { + return Editor.isBlock(editor, n); + }; + } + + if (Range.isRange(at)) { + at = deleteRange(editor, at); + } // If the target is a path, the default height-skipping and position + // counters need to account for us potentially splitting at a non-leaf. + + + if (Path.isPath(at)) { + var path = at; + var point = Editor.point(editor, path); + + var _Editor$parent3 = Editor.parent(editor, path), + _Editor$parent4 = _slicedToArray(_Editor$parent3, 1), + parent = _Editor$parent4[0]; + + match = function match(n) { + return n === parent; + }; + + height = point.path.length - path.length + 1; + at = point; + always = true; + } + + if (!at) { + return; + } + + var beforeRef = Editor.pointRef(editor, at, { + affinity: 'backward' + }); + + var _Editor$nodes5 = Editor.nodes(editor, { + at: at, + match: match, + mode: mode, + voids: voids + }), + _Editor$nodes6 = _slicedToArray(_Editor$nodes5, 1), + highest = _Editor$nodes6[0]; + + if (!highest) { + return; + } + + var voidMatch = Editor["void"](editor, { + at: at, + mode: 'highest' + }); + var nudge = 0; + + if (!voids && voidMatch) { + var _voidMatch = _slicedToArray(voidMatch, 2), + voidNode = _voidMatch[0], + voidPath = _voidMatch[1]; + + if (Element$1.isElement(voidNode) && editor.isInline(voidNode)) { + var after = Editor.after(editor, voidPath); + + if (!after) { + var text = { + text: '' + }; + var afterPath = Path.next(voidPath); + Transforms.insertNodes(editor, text, { + at: afterPath, + voids: voids + }); + after = Editor.point(editor, afterPath); + } + + at = after; + always = true; + } + + var siblingHeight = at.path.length - voidPath.length; + height = siblingHeight + 1; + always = true; + } + + var afterRef = Editor.pointRef(editor, at); + var depth = at.path.length - height; + + var _highest = _slicedToArray(highest, 2), + highestPath = _highest[1]; + + var lowestPath = at.path.slice(0, depth); + var position = height === 0 ? at.offset : at.path[depth] + nudge; + + var _iterator3 = _createForOfIteratorHelper$1(Editor.levels(editor, { + at: lowestPath, + reverse: true, + voids: voids + })), + _step3; + + try { + for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { + var _step3$value = _slicedToArray(_step3.value, 2), + node = _step3$value[0], + _path2 = _step3$value[1]; + + var split = false; + + if (_path2.length < highestPath.length || _path2.length === 0 || !voids && Editor.isVoid(editor, node)) { + break; + } + + var _point2 = beforeRef.current; + var isEnd = Editor.isEnd(editor, _point2, _path2); + + if (always || !beforeRef || !Editor.isEdge(editor, _point2, _path2)) { + split = true; + var properties = Node$1.extractProps(node); + editor.apply({ + type: 'split_node', + path: _path2, + position: position, + properties: properties + }); + } + + position = _path2[_path2.length - 1] + (split || isEnd ? 1 : 0); + } + } catch (err) { + _iterator3.e(err); + } finally { + _iterator3.f(); + } + + if (options.at == null) { + var _point = afterRef.current || Editor.end(editor, []); + + Transforms.select(editor, _point); + } + + beforeRef.unref(); + afterRef.unref(); + }); + }, + + /** + * Unset properties on the nodes at a location. + */ + unsetNodes: function unsetNodes(editor, props) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + + if (!Array.isArray(props)) { + props = [props]; + } + + var obj = {}; + + var _iterator4 = _createForOfIteratorHelper$1(props), + _step4; + + try { + for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) { + var key = _step4.value; + obj[key] = null; + } + } catch (err) { + _iterator4.e(err); + } finally { + _iterator4.f(); + } + + Transforms.setNodes(editor, obj, options); + }, + + /** + * Unwrap the nodes at a location from a parent node, splitting the parent if + * necessary to ensure that only the content in the range is unwrapped. + */ + unwrapNodes: function unwrapNodes(editor) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + Editor.withoutNormalizing(editor, function () { + var _options$mode8 = options.mode, + mode = _options$mode8 === void 0 ? 'lowest' : _options$mode8, + _options$split2 = options.split, + split = _options$split2 === void 0 ? false : _options$split2, + _options$voids8 = options.voids, + voids = _options$voids8 === void 0 ? false : _options$voids8; + var _options$at7 = options.at, + at = _options$at7 === void 0 ? editor.selection : _options$at7, + match = options.match; + + if (!at) { + return; + } + + if (match == null) { + match = Path.isPath(at) ? matchPath(editor, at) : function (n) { + return Editor.isBlock(editor, n); + }; + } + + if (Path.isPath(at)) { + at = Editor.range(editor, at); + } + + var rangeRef = Range.isRange(at) ? Editor.rangeRef(editor, at) : null; + var matches = Editor.nodes(editor, { + at: at, + match: match, + mode: mode, + voids: voids + }); + var pathRefs = Array.from(matches, function (_ref9) { + var _ref10 = _slicedToArray(_ref9, 2), + p = _ref10[1]; + + return Editor.pathRef(editor, p); + } // unwrapNode will call liftNode which does not support splitting the node when nested. + // If we do not reverse the order and call it from top to the bottom, it will remove all blocks + // that wrap target node. So we reverse the order. + ).reverse(); + + var _iterator5 = _createForOfIteratorHelper$1(pathRefs), + _step5; + + try { + var _loop = function _loop() { + var pathRef = _step5.value; + var path = pathRef.unref(); + + var _Editor$node3 = Editor.node(editor, path), + _Editor$node4 = _slicedToArray(_Editor$node3, 1), + node = _Editor$node4[0]; + + var range = Editor.range(editor, path); + + if (split && rangeRef) { + range = Range.intersection(rangeRef.current, range); + } + + Transforms.liftNodes(editor, { + at: range, + match: function match(n) { + return Element$1.isAncestor(node) && node.children.includes(n); + }, + voids: voids + }); + }; + + for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) { + _loop(); + } + } catch (err) { + _iterator5.e(err); + } finally { + _iterator5.f(); + } + + if (rangeRef) { + rangeRef.unref(); + } + }); + }, + + /** + * Wrap the nodes at a location in a new container node, splitting the edges + * of the range first to ensure that only the content in the range is wrapped. + */ + wrapNodes: function wrapNodes(editor, element) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + Editor.withoutNormalizing(editor, function () { + var _options$mode9 = options.mode, + mode = _options$mode9 === void 0 ? 'lowest' : _options$mode9, + _options$split3 = options.split, + split = _options$split3 === void 0 ? false : _options$split3, + _options$voids9 = options.voids, + voids = _options$voids9 === void 0 ? false : _options$voids9; + var match = options.match, + _options$at8 = options.at, + at = _options$at8 === void 0 ? editor.selection : _options$at8; + + if (!at) { + return; + } + + if (match == null) { + if (Path.isPath(at)) { + match = matchPath(editor, at); + } else if (editor.isInline(element)) { + match = function match(n) { + return Editor.isInline(editor, n) || Text.isText(n); + }; + } else { + match = function match(n) { + return Editor.isBlock(editor, n); + }; + } + } + + if (split && Range.isRange(at)) { + var _Range$edges7 = Range.edges(at), + _Range$edges8 = _slicedToArray(_Range$edges7, 2), + start = _Range$edges8[0], + end = _Range$edges8[1]; + + var rangeRef = Editor.rangeRef(editor, at, { + affinity: 'inward' + }); + Transforms.splitNodes(editor, { + at: end, + match: match, + voids: voids + }); + Transforms.splitNodes(editor, { + at: start, + match: match, + voids: voids + }); + at = rangeRef.unref(); + + if (options.at == null) { + Transforms.select(editor, at); + } + } + + var roots = Array.from(Editor.nodes(editor, { + at: at, + match: editor.isInline(element) ? function (n) { + return Editor.isBlock(editor, n); + } : function (n) { + return Editor.isEditor(n); + }, + mode: 'lowest', + voids: voids + })); + + for (var _i4 = 0, _roots = roots; _i4 < _roots.length; _i4++) { + var _roots$_i = _slicedToArray(_roots[_i4], 2), + rootPath = _roots$_i[1]; + + var a = Range.isRange(at) ? Range.intersection(at, Editor.range(editor, rootPath)) : at; + + if (!a) { + continue; + } + + var matches = Array.from(Editor.nodes(editor, { + at: a, + match: match, + mode: mode, + voids: voids + })); + + if (matches.length > 0) { + var _ret = function () { + var _matches = _slicedToArray(matches, 1), + first = _matches[0]; + + var last = matches[matches.length - 1]; + + var _first = _slicedToArray(first, 2), + firstPath = _first[1]; + + var _last = _slicedToArray(last, 2), + lastPath = _last[1]; + + if (firstPath.length === 0 && lastPath.length === 0) { + // if there's no matching parent - usually means the node is an editor - don't do anything + return "continue"; + } + + var commonPath = Path.equals(firstPath, lastPath) ? Path.parent(firstPath) : Path.common(firstPath, lastPath); + var range = Editor.range(editor, firstPath, lastPath); + var commonNodeEntry = Editor.node(editor, commonPath); + + var _commonNodeEntry = _slicedToArray(commonNodeEntry, 1), + commonNode = _commonNodeEntry[0]; + + var depth = commonPath.length + 1; + var wrapperPath = Path.next(lastPath.slice(0, depth)); + + var wrapper = _objectSpread$2(_objectSpread$2({}, element), {}, { + children: [] + }); + + Transforms.insertNodes(editor, wrapper, { + at: wrapperPath, + voids: voids + }); + Transforms.moveNodes(editor, { + at: range, + match: function match(n) { + return Element$1.isAncestor(commonNode) && commonNode.children.includes(n); + }, + to: wrapperPath.concat(0), + voids: voids + }); + }(); + + if (_ret === "continue") continue; + } + } + }); + } + }; + + var hasSingleChildNest = function hasSingleChildNest(editor, node) { + if (Element$1.isElement(node)) { + var element = node; + + if (Editor.isVoid(editor, node)) { + return true; + } else if (element.children.length === 1) { + return hasSingleChildNest(editor, element.children[0]); + } else { + return false; + } + } else if (Editor.isEditor(node)) { + return false; + } else { + return true; + } + }; + /** + * Convert a range into a point by deleting it's content. + */ + + + var deleteRange = function deleteRange(editor, range) { + if (Range.isCollapsed(range)) { + return range.anchor; + } else { + var _Range$edges9 = Range.edges(range), + _Range$edges10 = _slicedToArray(_Range$edges9, 2), + end = _Range$edges10[1]; + + var pointRef = Editor.pointRef(editor, end); + Transforms["delete"](editor, { + at: range + }); + return pointRef.unref(); + } + }; + + var matchPath = function matchPath(editor, path) { + var _Editor$node5 = Editor.node(editor, path), + _Editor$node6 = _slicedToArray(_Editor$node5, 1), + node = _Editor$node6[0]; + + return function (n) { + return n === node; + }; + }; + + function ownKeys$1(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } + + function _objectSpread$1(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$1(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$1(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + var SelectionTransforms = { + /** + * Collapse the selection. + */ + collapse: function collapse(editor) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var _options$edge = options.edge, + edge = _options$edge === void 0 ? 'anchor' : _options$edge; + var selection = editor.selection; + + if (!selection) { + return; + } else if (edge === 'anchor') { + Transforms.select(editor, selection.anchor); + } else if (edge === 'focus') { + Transforms.select(editor, selection.focus); + } else if (edge === 'start') { + var _Range$edges = Range.edges(selection), + _Range$edges2 = _slicedToArray(_Range$edges, 1), + start = _Range$edges2[0]; + + Transforms.select(editor, start); + } else if (edge === 'end') { + var _Range$edges3 = Range.edges(selection), + _Range$edges4 = _slicedToArray(_Range$edges3, 2), + end = _Range$edges4[1]; + + Transforms.select(editor, end); + } + }, + + /** + * Unset the selection. + */ + deselect: function deselect(editor) { + var selection = editor.selection; + + if (selection) { + editor.apply({ + type: 'set_selection', + properties: selection, + newProperties: null + }); + } + }, + + /** + * Move the selection's point forward or backward. + */ + move: function move(editor) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var selection = editor.selection; + var _options$distance = options.distance, + distance = _options$distance === void 0 ? 1 : _options$distance, + _options$unit = options.unit, + unit = _options$unit === void 0 ? 'character' : _options$unit, + _options$reverse = options.reverse, + reverse = _options$reverse === void 0 ? false : _options$reverse; + var _options$edge2 = options.edge, + edge = _options$edge2 === void 0 ? null : _options$edge2; + + if (!selection) { + return; + } + + if (edge === 'start') { + edge = Range.isBackward(selection) ? 'focus' : 'anchor'; + } + + if (edge === 'end') { + edge = Range.isBackward(selection) ? 'anchor' : 'focus'; + } + + var anchor = selection.anchor, + focus = selection.focus; + var opts = { + distance: distance, + unit: unit + }; + var props = {}; + + if (edge == null || edge === 'anchor') { + var point = reverse ? Editor.before(editor, anchor, opts) : Editor.after(editor, anchor, opts); + + if (point) { + props.anchor = point; + } + } + + if (edge == null || edge === 'focus') { + var _point = reverse ? Editor.before(editor, focus, opts) : Editor.after(editor, focus, opts); + + if (_point) { + props.focus = _point; + } + } + + Transforms.setSelection(editor, props); + }, + + /** + * Set the selection to a new value. + */ + select: function select(editor, target) { + var selection = editor.selection; + target = Editor.range(editor, target); + + if (selection) { + Transforms.setSelection(editor, target); + return; + } + + if (!Range.isRange(target)) { + throw new Error("When setting the selection and the current selection is `null` you must provide at least an `anchor` and `focus`, but you passed: ".concat(JSON.stringify(target))); + } + + editor.apply({ + type: 'set_selection', + properties: selection, + newProperties: target + }); + }, + + /** + * Set new properties on one of the selection's points. + */ + setPoint: function setPoint(editor, props) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var selection = editor.selection; + var _options$edge3 = options.edge, + edge = _options$edge3 === void 0 ? 'both' : _options$edge3; + + if (!selection) { + return; + } + + if (edge === 'start') { + edge = Range.isBackward(selection) ? 'focus' : 'anchor'; + } + + if (edge === 'end') { + edge = Range.isBackward(selection) ? 'anchor' : 'focus'; + } + + var anchor = selection.anchor, + focus = selection.focus; + var point = edge === 'anchor' ? anchor : focus; + Transforms.setSelection(editor, _defineProperty({}, edge === 'anchor' ? 'anchor' : 'focus', _objectSpread$1(_objectSpread$1({}, point), props))); + }, + + /** + * Set new properties on the selection. + */ + setSelection: function setSelection(editor, props) { + var selection = editor.selection; + var oldProps = {}; + var newProps = {}; + + if (!selection) { + return; + } + + for (var k in props) { + if (k === 'anchor' && props.anchor != null && !Point.equals(props.anchor, selection.anchor) || k === 'focus' && props.focus != null && !Point.equals(props.focus, selection.focus) || k !== 'anchor' && k !== 'focus' && props[k] !== selection[k]) { + oldProps[k] = selection[k]; + newProps[k] = props[k]; + } + } + + if (Object.keys(oldProps).length > 0) { + editor.apply({ + type: 'set_selection', + properties: oldProps, + newProperties: newProps + }); + } + } + }; + + function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } + + function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } + + function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + var TextTransforms = { + /** + * Delete content in the editor. + */ + "delete": function _delete(editor) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + Editor.withoutNormalizing(editor, function () { + var _options$reverse = options.reverse, + reverse = _options$reverse === void 0 ? false : _options$reverse, + _options$unit = options.unit, + unit = _options$unit === void 0 ? 'character' : _options$unit, + _options$distance = options.distance, + distance = _options$distance === void 0 ? 1 : _options$distance, + _options$voids = options.voids, + voids = _options$voids === void 0 ? false : _options$voids; + var _options$at = options.at, + at = _options$at === void 0 ? editor.selection : _options$at, + _options$hanging = options.hanging, + hanging = _options$hanging === void 0 ? false : _options$hanging; + + if (!at) { + return; + } + + if (Range.isRange(at) && Range.isCollapsed(at)) { + at = at.anchor; + } + + if (Point.isPoint(at)) { + var furthestVoid = Editor["void"](editor, { + at: at, + mode: 'highest' + }); + + if (!voids && furthestVoid) { + var _furthestVoid = _slicedToArray(furthestVoid, 2), + voidPath = _furthestVoid[1]; + + at = voidPath; + } else { + var opts = { + unit: unit, + distance: distance + }; + var target = reverse ? Editor.before(editor, at, opts) || Editor.start(editor, []) : Editor.after(editor, at, opts) || Editor.end(editor, []); + at = { + anchor: at, + focus: target + }; + hanging = true; + } + } + + if (Path.isPath(at)) { + Transforms.removeNodes(editor, { + at: at, + voids: voids + }); + return; + } + + if (Range.isCollapsed(at)) { + return; + } + + if (!hanging) { + var _Range$edges = Range.edges(at), + _Range$edges2 = _slicedToArray(_Range$edges, 2), + _end = _Range$edges2[1]; + + var endOfDoc = Editor.end(editor, []); + + if (!Point.equals(_end, endOfDoc)) { + at = Editor.unhangRange(editor, at, { + voids: voids + }); + } + } + + var _Range$edges3 = Range.edges(at), + _Range$edges4 = _slicedToArray(_Range$edges3, 2), + start = _Range$edges4[0], + end = _Range$edges4[1]; + + var startBlock = Editor.above(editor, { + match: function match(n) { + return Editor.isBlock(editor, n); + }, + at: start, + voids: voids + }); + var endBlock = Editor.above(editor, { + match: function match(n) { + return Editor.isBlock(editor, n); + }, + at: end, + voids: voids + }); + var isAcrossBlocks = startBlock && endBlock && !Path.equals(startBlock[1], endBlock[1]); + var isSingleText = Path.equals(start.path, end.path); + var startVoid = voids ? null : Editor["void"](editor, { + at: start, + mode: 'highest' + }); + var endVoid = voids ? null : Editor["void"](editor, { + at: end, + mode: 'highest' + }); // If the start or end points are inside an inline void, nudge them out. + + if (startVoid) { + var before = Editor.before(editor, start); + + if (before && startBlock && Path.isAncestor(startBlock[1], before.path)) { + start = before; + } + } + + if (endVoid) { + var after = Editor.after(editor, end); + + if (after && endBlock && Path.isAncestor(endBlock[1], after.path)) { + end = after; + } + } // Get the highest nodes that are completely inside the range, as well as + // the start and end nodes. + + + var matches = []; + var lastPath; + + var _iterator = _createForOfIteratorHelper(Editor.nodes(editor, { + at: at, + voids: voids + })), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var entry = _step.value; + + var _entry = _slicedToArray(entry, 2), + _node2 = _entry[0], + _path3 = _entry[1]; + + if (lastPath && Path.compare(_path3, lastPath) === 0) { + continue; + } + + if (!voids && Editor.isVoid(editor, _node2) || !Path.isCommon(_path3, start.path) && !Path.isCommon(_path3, end.path)) { + matches.push(entry); + lastPath = _path3; + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + + var pathRefs = Array.from(matches, function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + p = _ref2[1]; + + return Editor.pathRef(editor, p); + }); + var startRef = Editor.pointRef(editor, start); + var endRef = Editor.pointRef(editor, end); + + if (!isSingleText && !startVoid) { + var _point = startRef.current; + + var _Editor$leaf = Editor.leaf(editor, _point), + _Editor$leaf2 = _slicedToArray(_Editor$leaf, 1), + node = _Editor$leaf2[0]; + + var path = _point.path; + var _start = start, + offset = _start.offset; + var text = node.text.slice(offset); + if (text.length > 0) editor.apply({ + type: 'remove_text', + path: path, + offset: offset, + text: text + }); + } + + for (var _i = 0, _pathRefs = pathRefs; _i < _pathRefs.length; _i++) { + var pathRef = _pathRefs[_i]; + + var _path = pathRef.unref(); + + Transforms.removeNodes(editor, { + at: _path, + voids: voids + }); + } + + if (!endVoid) { + var _point2 = endRef.current; + + var _Editor$leaf3 = Editor.leaf(editor, _point2), + _Editor$leaf4 = _slicedToArray(_Editor$leaf3, 1), + _node = _Editor$leaf4[0]; + + var _path2 = _point2.path; + + var _offset = isSingleText ? start.offset : 0; + + var _text = _node.text.slice(_offset, end.offset); + + if (_text.length > 0) editor.apply({ + type: 'remove_text', + path: _path2, + offset: _offset, + text: _text + }); + } + + if (!isSingleText && isAcrossBlocks && endRef.current && startRef.current) { + Transforms.mergeNodes(editor, { + at: endRef.current, + hanging: true, + voids: voids + }); + } + + var point = reverse ? startRef.unref() || endRef.unref() : endRef.unref() || startRef.unref(); + + if (options.at == null && point) { + Transforms.select(editor, point); + } + }); + }, + + /** + * Insert a fragment at a specific location in the editor. + */ + insertFragment: function insertFragment(editor, fragment) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + Editor.withoutNormalizing(editor, function () { + var _options$hanging2 = options.hanging, + hanging = _options$hanging2 === void 0 ? false : _options$hanging2, + _options$voids2 = options.voids, + voids = _options$voids2 === void 0 ? false : _options$voids2; + var _options$at2 = options.at, + at = _options$at2 === void 0 ? editor.selection : _options$at2; + + if (!fragment.length) { + return; + } + + if (!at) { + return; + } else if (Range.isRange(at)) { + if (!hanging) { + at = Editor.unhangRange(editor, at); + } + + if (Range.isCollapsed(at)) { + at = at.anchor; + } else { + var _Range$edges5 = Range.edges(at), + _Range$edges6 = _slicedToArray(_Range$edges5, 2), + end = _Range$edges6[1]; + + if (!voids && Editor["void"](editor, { + at: end + })) { + return; + } + + var pointRef = Editor.pointRef(editor, end); + Transforms["delete"](editor, { + at: at + }); + at = pointRef.unref(); + } + } else if (Path.isPath(at)) { + at = Editor.start(editor, at); + } + + if (!voids && Editor["void"](editor, { + at: at + })) { + return; + } // If the insert point is at the edge of an inline node, move it outside + // instead since it will need to be split otherwise. + + + var inlineElementMatch = Editor.above(editor, { + at: at, + match: function match(n) { + return Editor.isInline(editor, n); + }, + mode: 'highest', + voids: voids + }); + + if (inlineElementMatch) { + var _inlineElementMatch = _slicedToArray(inlineElementMatch, 2), + _inlinePath = _inlineElementMatch[1]; + + if (Editor.isEnd(editor, at, _inlinePath)) { + var after = Editor.after(editor, _inlinePath); + at = after; + } else if (Editor.isStart(editor, at, _inlinePath)) { + var before = Editor.before(editor, _inlinePath); + at = before; + } + } + + var blockMatch = Editor.above(editor, { + match: function match(n) { + return Editor.isBlock(editor, n); + }, + at: at, + voids: voids + }); + + var _blockMatch = _slicedToArray(blockMatch, 2), + blockPath = _blockMatch[1]; + + var isBlockStart = Editor.isStart(editor, at, blockPath); + var isBlockEnd = Editor.isEnd(editor, at, blockPath); + var isBlockEmpty = isBlockStart && isBlockEnd; + var mergeStart = !isBlockStart || isBlockStart && isBlockEnd; + var mergeEnd = !isBlockEnd; + + var _Node$first = Node$1.first({ + children: fragment + }, []), + _Node$first2 = _slicedToArray(_Node$first, 2), + firstPath = _Node$first2[1]; + + var _Node$last = Node$1.last({ + children: fragment + }, []), + _Node$last2 = _slicedToArray(_Node$last, 2), + lastPath = _Node$last2[1]; + + var matches = []; + + var matcher = function matcher(_ref3) { + var _ref4 = _slicedToArray(_ref3, 2), + n = _ref4[0], + p = _ref4[1]; + + var isRoot = p.length === 0; + + if (isRoot) { + return false; + } + + if (isBlockEmpty) { + return true; + } + + if (mergeStart && Path.isAncestor(p, firstPath) && Element$1.isElement(n) && !editor.isVoid(n) && !editor.isInline(n)) { + return false; + } + + if (mergeEnd && Path.isAncestor(p, lastPath) && Element$1.isElement(n) && !editor.isVoid(n) && !editor.isInline(n)) { + return false; + } + + return true; + }; + + var _iterator2 = _createForOfIteratorHelper(Node$1.nodes({ + children: fragment + }, { + pass: matcher + })), + _step2; + + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var entry = _step2.value; + + if (matcher(entry)) { + matches.push(entry); + } + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + + var starts = []; + var middles = []; + var ends = []; + var starting = true; + var hasBlocks = false; + + for (var _i2 = 0, _matches = matches; _i2 < _matches.length; _i2++) { + var _matches$_i = _slicedToArray(_matches[_i2], 1), + node = _matches$_i[0]; + + if (Element$1.isElement(node) && !editor.isInline(node)) { + starting = false; + hasBlocks = true; + middles.push(node); + } else if (starting) { + starts.push(node); + } else { + ends.push(node); + } + } + + var _Editor$nodes = Editor.nodes(editor, { + at: at, + match: function match(n) { + return Text.isText(n) || Editor.isInline(editor, n); + }, + mode: 'highest', + voids: voids + }), + _Editor$nodes2 = _slicedToArray(_Editor$nodes, 1), + inlineMatch = _Editor$nodes2[0]; + + var _inlineMatch = _slicedToArray(inlineMatch, 2), + inlinePath = _inlineMatch[1]; + + var isInlineStart = Editor.isStart(editor, at, inlinePath); + var isInlineEnd = Editor.isEnd(editor, at, inlinePath); + var middleRef = Editor.pathRef(editor, isBlockEnd ? Path.next(blockPath) : blockPath); + var endRef = Editor.pathRef(editor, isInlineEnd ? Path.next(inlinePath) : inlinePath); + var blockPathRef = Editor.pathRef(editor, blockPath); + Transforms.splitNodes(editor, { + at: at, + match: function match(n) { + return hasBlocks ? Editor.isBlock(editor, n) : Text.isText(n) || Editor.isInline(editor, n); + }, + mode: hasBlocks ? 'lowest' : 'highest', + voids: voids + }); + var startRef = Editor.pathRef(editor, !isInlineStart || isInlineStart && isInlineEnd ? Path.next(inlinePath) : inlinePath); + Transforms.insertNodes(editor, starts, { + at: startRef.current, + match: function match(n) { + return Text.isText(n) || Editor.isInline(editor, n); + }, + mode: 'highest', + voids: voids + }); + + if (isBlockEmpty && middles.length) { + Transforms["delete"](editor, { + at: blockPathRef.unref(), + voids: voids + }); + } + + Transforms.insertNodes(editor, middles, { + at: middleRef.current, + match: function match(n) { + return Editor.isBlock(editor, n); + }, + mode: 'lowest', + voids: voids + }); + Transforms.insertNodes(editor, ends, { + at: endRef.current, + match: function match(n) { + return Text.isText(n) || Editor.isInline(editor, n); + }, + mode: 'highest', + voids: voids + }); + + if (!options.at) { + var path; + + if (ends.length > 0) { + path = Path.previous(endRef.current); + } else if (middles.length > 0) { + path = Path.previous(middleRef.current); + } else { + path = Path.previous(startRef.current); + } + + var _end2 = Editor.end(editor, path); + + Transforms.select(editor, _end2); + } + + startRef.unref(); + middleRef.unref(); + endRef.unref(); + }); + }, + + /** + * Insert a string of text in the Editor. + */ + insertText: function insertText(editor, text) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + Editor.withoutNormalizing(editor, function () { + var _options$voids3 = options.voids, + voids = _options$voids3 === void 0 ? false : _options$voids3; + var _options$at3 = options.at, + at = _options$at3 === void 0 ? editor.selection : _options$at3; + + if (!at) { + return; + } + + if (Path.isPath(at)) { + at = Editor.range(editor, at); + } + + if (Range.isRange(at)) { + if (Range.isCollapsed(at)) { + at = at.anchor; + } else { + var end = Range.end(at); + + if (!voids && Editor["void"](editor, { + at: end + })) { + return; + } + + var pointRef = Editor.pointRef(editor, end); + Transforms["delete"](editor, { + at: at, + voids: voids + }); + at = pointRef.unref(); + Transforms.setSelection(editor, { + anchor: at, + focus: at + }); + } + } + + if (!voids && Editor["void"](editor, { + at: at + })) { + return; + } + + var _at = at, + path = _at.path, + offset = _at.offset; + if (text.length > 0) editor.apply({ + type: 'insert_text', + path: path, + offset: offset, + text: text + }); + }); + } + }; + + function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } + + function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + var Transforms = _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, GeneralTransforms), NodeTransforms), SelectionTransforms), TextTransforms); + + var Editor_1 = Editor; + var Element_1 = Element$1; + var Location_1 = Location; + var Node_1 = Node$1; + var Operation_1 = Operation; + var Path_1 = Path; + var PathRef_1 = PathRef; + var Point_1 = Point; + var PointRef_1 = PointRef; + var Range_1 = Range; + var RangeRef_1 = RangeRef; + var Span_1 = Span; + var Text_1 = Text; + var Transforms_1 = Transforms; + var createEditor_1 = createEditor$1; + + + var dist$7 = /*#__PURE__*/Object.defineProperty({ + Editor: Editor_1, + Element: Element_1, + Location: Location_1, + Node: Node_1, + Operation: Operation_1, + Path: Path_1, + PathRef: PathRef_1, + Point: Point_1, + PointRef: PointRef_1, + Range: Range_1, + RangeRef: RangeRef_1, + Span: Span_1, + Text: Text_1, + Transforms: Transforms_1, + createEditor: createEditor_1 + }, '__esModule', {value: true}); + + /** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER$1 = 9007199254740991; + + /** `Object#toString` result references. */ + var argsTag$1 = '[object Arguments]', + funcTag$1 = '[object Function]', + genTag$1 = '[object GeneratorFunction]', + mapTag = '[object Map]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + setTag = '[object Set]', + stringTag = '[object String]', + weakMapTag = '[object WeakMap]'; + + var dataViewTag = '[object DataView]'; + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + + /** Used to detect host constructors (Safari). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to detect unsigned integer values. */ + var reIsUint$1 = /^(?:0|[1-9]\d*)$/; + + /** Used to compose unicode character classes. */ + var rsAstralRange$1 = '\\ud800-\\udfff', + rsComboMarksRange$1 = '\\u0300-\\u036f\\ufe20-\\ufe23', + rsComboSymbolsRange$1 = '\\u20d0-\\u20f0', + rsVarRange$1 = '\\ufe0e\\ufe0f'; + + /** Used to compose unicode capture groups. */ + var rsAstral$1 = '[' + rsAstralRange$1 + ']', + rsCombo$1 = '[' + rsComboMarksRange$1 + rsComboSymbolsRange$1 + ']', + rsFitz$1 = '\\ud83c[\\udffb-\\udfff]', + rsModifier$1 = '(?:' + rsCombo$1 + '|' + rsFitz$1 + ')', + rsNonAstral$1 = '[^' + rsAstralRange$1 + ']', + rsRegional$1 = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair$1 = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsZWJ$1 = '\\u200d'; + + /** Used to compose unicode regexes. */ + var reOptMod$1 = rsModifier$1 + '?', + rsOptVar$1 = '[' + rsVarRange$1 + ']?', + rsOptJoin$1 = '(?:' + rsZWJ$1 + '(?:' + [rsNonAstral$1, rsRegional$1, rsSurrPair$1].join('|') + ')' + rsOptVar$1 + reOptMod$1 + ')*', + rsSeq$1 = rsOptVar$1 + reOptMod$1 + rsOptJoin$1, + rsSymbol$1 = '(?:' + [rsNonAstral$1 + rsCombo$1 + '?', rsCombo$1, rsRegional$1, rsSurrPair$1, rsAstral$1].join('|') + ')'; + + /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ + var reUnicode$1 = RegExp(rsFitz$1 + '(?=' + rsFitz$1 + ')|' + rsSymbol$1 + rsSeq$1, 'g'); + + /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ + var reHasUnicode$1 = RegExp('[' + rsZWJ$1 + rsAstralRange$1 + rsComboMarksRange$1 + rsComboSymbolsRange$1 + rsVarRange$1 + ']'); + + /** Detect free variable `global` from Node.js. */ + var freeGlobal$3 = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; + + /** Detect free variable `self`. */ + var freeSelf$3 = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root$3 = freeGlobal$3 || freeSelf$3 || Function('return this')(); + + /** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array ? array.length : 0, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + + /** + * Converts an ASCII `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function asciiToArray$1(string) { + return string.split(''); + } + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes$1(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ + function baseValues(object, props) { + return arrayMap(props, function(key) { + return object[key]; + }); + } + + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function getValue(object, key) { + return object == null ? undefined : object[key]; + } + + /** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ + function hasUnicode$1(string) { + return reHasUnicode$1.test(string); + } + + /** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ + function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; + } + + /** + * Converts `iterator` to an array. + * + * @private + * @param {Object} iterator The iterator to convert. + * @returns {Array} Returns the converted array. + */ + function iteratorToArray(iterator) { + var data, + result = []; + + while (!(data = iterator.next()).done) { + result.push(data.value); + } + return result; + } + + /** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ + function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; + } + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg$1(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + /** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ + function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; + } + + /** + * Converts `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function stringToArray$1(string) { + return hasUnicode$1(string) + ? unicodeToArray$1(string) + : asciiToArray$1(string); + } + + /** + * Converts a Unicode `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function unicodeToArray$1(string) { + return string.match(reUnicode$1) || []; + } + + /** Used for built-in method references. */ + var funcProto = Function.prototype, + objectProto$4 = Object.prototype; + + /** Used to detect overreaching core-js shims. */ + var coreJsData = root$3['__core-js_shared__']; + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty$2 = objectProto$4.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString$4 = objectProto$4.toString; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty$2).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Built-in value references. */ + var Symbol$2 = root$3.Symbol, + iteratorSymbol = Symbol$2 ? Symbol$2.iterator : undefined, + propertyIsEnumerable$1 = objectProto$4.propertyIsEnumerable; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeKeys$1 = overArg$1(Object.keys, Object); + + /* Built-in method references that are verified to be native. */ + var DataView = getNative(root$3, 'DataView'), + Map$1 = getNative(root$3, 'Map'), + Promise$1 = getNative(root$3, 'Promise'), + Set$1 = getNative(root$3, 'Set'), + WeakMap$1 = getNative(root$3, 'WeakMap'); + + /** Used to detect maps, sets, and weakmaps. */ + var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map$1), + promiseCtorString = toSource(Promise$1), + setCtorString = toSource(Set$1), + weakMapCtorString = toSource(WeakMap$1); + + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ + function arrayLikeKeys$1(value, inherited) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + // Safari 9 makes `arguments.length` enumerable in strict mode. + var result = (isArray$1(value) || isArguments$1(value)) + ? baseTimes$1(value.length, String) + : []; + + var length = result.length, + skipIndexes = !!length; + + for (var key in value) { + if ((inherited || hasOwnProperty$2.call(value, key)) && + !(skipIndexes && (key == 'length' || isIndex$1(key, length)))) { + result.push(key); + } + } + return result; + } + + /** + * The base implementation of `getTag`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + return objectToString$4.call(value); + } + + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative(value) { + if (!isObject$3(value) || isMasked(value)) { + return false; + } + var pattern = (isFunction$1(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); + } + + /** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys$1(object) { + if (!isPrototype$1(object)) { + return nativeKeys$1(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty$2.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; + } + + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + var getTag = baseGetTag; + + // Fallback for data views, maps, sets, and weak maps in IE 11, + // for data views in Edge < 14, and promises in Node.js. + if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map$1 && getTag(new Map$1) != mapTag) || + (Promise$1 && getTag(Promise$1.resolve()) != promiseTag) || + (Set$1 && getTag(new Set$1) != setTag) || + (WeakMap$1 && getTag(new WeakMap$1) != weakMapTag)) { + getTag = function(value) { + var result = objectToString$4.call(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : undefined; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag; + case mapCtorString: return mapTag; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex$1(value, length) { + length = length == null ? MAX_SAFE_INTEGER$1 : length; + return !!length && + (typeof value == 'number' || reIsUint$1.test(value)) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype$1(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$4; + + return value === proto; + } + + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to process. + * @returns {string} Returns the source code. + */ + function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; + } + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments$1(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject$1(value) && hasOwnProperty$2.call(value, 'callee') && + (!propertyIsEnumerable$1.call(value, 'callee') || objectToString$4.call(value) == argsTag$1); + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray$1 = Array.isArray; + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike$1(value) { + return value != null && isLength$1(value.length) && !isFunction$1(value); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject$1(value) { + return isObjectLike$4(value) && isArrayLike$1(value); + } + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction$1(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject$3(value) ? objectToString$4.call(value) : ''; + return tag == funcTag$1 || tag == genTag$1; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength$1(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$1; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject$3(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike$4(value) { + return !!value && typeof value == 'object'; + } + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || + (!isArray$1(value) && isObjectLike$4(value) && objectToString$4.call(value) == stringTag); + } + + /** + * Converts `value` to an array. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. + * @example + * + * _.toArray({ 'a': 1, 'b': 2 }); + * // => [1, 2] + * + * _.toArray('abc'); + * // => ['a', 'b', 'c'] + * + * _.toArray(1); + * // => [] + * + * _.toArray(null); + * // => [] + */ + function toArray(value) { + if (!value) { + return []; + } + if (isArrayLike$1(value)) { + return isString(value) ? stringToArray$1(value) : copyArray(value); + } + if (iteratorSymbol && value[iteratorSymbol]) { + return iteratorToArray(value[iteratorSymbol]()); + } + var tag = getTag(value), + func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values); + + return func(value); + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys$1(object) { + return isArrayLike$1(object) ? arrayLikeKeys$1(object) : baseKeys$1(object); + } + + /** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ + function values(object) { + return object ? baseValues(object, keys$1(object)) : []; + } + + var lodash_toarray = toArray; + + /** + * SSR Window 3.0.0 + * Better handling for window object in SSR environment + * https://github.com/nolimits4web/ssr-window + * + * Copyright 2020, Vladimir Kharlampidi + * + * Licensed under MIT + * + * Released on: November 9, 2020 + */ + + var ssrWindow_umd = createCommonjsModule$1(function (module, exports) { + (function (global, factory) { + factory(exports) ; + }(commonjsGlobal, (function (exports) { + /* eslint-disable no-param-reassign */ + function isObject(obj) { + return (obj !== null && + typeof obj === 'object' && + 'constructor' in obj && + obj.constructor === Object); + } + function extend(target, src) { + if (target === void 0) { target = {}; } + if (src === void 0) { src = {}; } + Object.keys(src).forEach(function (key) { + if (typeof target[key] === 'undefined') + target[key] = src[key]; + else if (isObject(src[key]) && + isObject(target[key]) && + Object.keys(src[key]).length > 0) { + extend(target[key], src[key]); + } + }); + } + + var ssrDocument = { + body: {}, + addEventListener: function () { }, + removeEventListener: function () { }, + activeElement: { + blur: function () { }, + nodeName: '', + }, + querySelector: function () { + return null; + }, + querySelectorAll: function () { + return []; + }, + getElementById: function () { + return null; + }, + createEvent: function () { + return { + initEvent: function () { }, + }; + }, + createElement: function () { + return { + children: [], + childNodes: [], + style: {}, + setAttribute: function () { }, + getElementsByTagName: function () { + return []; + }, + }; + }, + createElementNS: function () { + return {}; + }, + importNode: function () { + return null; + }, + location: { + hash: '', + host: '', + hostname: '', + href: '', + origin: '', + pathname: '', + protocol: '', + search: '', + }, + }; + function getDocument() { + var doc = typeof document !== 'undefined' ? document : {}; + extend(doc, ssrDocument); + return doc; + } + + var ssrWindow = { + document: ssrDocument, + navigator: { + userAgent: '', + }, + location: { + hash: '', + host: '', + hostname: '', + href: '', + origin: '', + pathname: '', + protocol: '', + search: '', + }, + history: { + replaceState: function () { }, + pushState: function () { }, + go: function () { }, + back: function () { }, + }, + CustomEvent: function CustomEvent() { + return this; + }, + addEventListener: function () { }, + removeEventListener: function () { }, + getComputedStyle: function () { + return { + getPropertyValue: function () { + return ''; + }, + }; + }, + Image: function () { }, + Date: function () { }, + screen: {}, + setTimeout: function () { }, + clearTimeout: function () { }, + matchMedia: function () { + return {}; + }, + requestAnimationFrame: function (callback) { + if (typeof setTimeout === 'undefined') { + callback(); + return null; + } + return setTimeout(callback, 0); + }, + cancelAnimationFrame: function (id) { + if (typeof setTimeout === 'undefined') { + return; + } + clearTimeout(id); + }, + }; + function getWindow() { + var win = typeof window !== 'undefined' ? window : {}; + extend(win, ssrWindow); + return win; + } + + exports.extend = extend; + exports.getDocument = getDocument; + exports.getWindow = getWindow; + exports.ssrDocument = ssrDocument; + exports.ssrWindow = ssrWindow; + + Object.defineProperty(exports, '__esModule', { value: true }); + + }))); + + }); + + /** + * Dom7 3.0.0 + * Minimalistic JavaScript library for DOM manipulation, with a jQuery-compatible API + * https://framework7.io/docs/dom7.html + * + * Copyright 2020, Vladimir Kharlampidi + * + * Licensed under MIT + * + * Released on: November 9, 2020 + */ + + + + + + function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; + } + + function _getPrototypeOf(o) { + _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { + return o.__proto__ || Object.getPrototypeOf(o); + }; + return _getPrototypeOf(o); + } + + function _setPrototypeOf(o, p) { + _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; + + return _setPrototypeOf(o, p); + } + + function _isNativeReflectConstruct() { + if (typeof Reflect === "undefined" || !Reflect.construct) return false; + if (Reflect.construct.sham) return false; + if (typeof Proxy === "function") return true; + + try { + Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); + return true; + } catch (e) { + return false; + } + } + + function _construct(Parent, args, Class) { + if (_isNativeReflectConstruct()) { + _construct = Reflect.construct; + } else { + _construct = function _construct(Parent, args, Class) { + var a = [null]; + a.push.apply(a, args); + var Constructor = Function.bind.apply(Parent, a); + var instance = new Constructor(); + if (Class) _setPrototypeOf(instance, Class.prototype); + return instance; + }; + } + + return _construct.apply(null, arguments); + } + + function _isNativeFunction(fn) { + return Function.toString.call(fn).indexOf("[native code]") !== -1; + } + + function _wrapNativeSuper(Class) { + var _cache = typeof Map === "function" ? new Map() : undefined; + + _wrapNativeSuper = function _wrapNativeSuper(Class) { + if (Class === null || !_isNativeFunction(Class)) return Class; + + if (typeof Class !== "function") { + throw new TypeError("Super expression must either be null or a function"); + } + + if (typeof _cache !== "undefined") { + if (_cache.has(Class)) return _cache.get(Class); + + _cache.set(Class, Wrapper); + } + + function Wrapper() { + return _construct(Class, arguments, _getPrototypeOf(this).constructor); + } + + Wrapper.prototype = Object.create(Class.prototype, { + constructor: { + value: Wrapper, + enumerable: false, + writable: true, + configurable: true + } + }); + return _setPrototypeOf(Wrapper, Class); + }; + + return _wrapNativeSuper(Class); + } + + function _assertThisInitialized(self) { + if (self === void 0) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + + return self; + } + + /* eslint-disable no-proto */ + function makeReactive(obj) { + var proto = obj.__proto__; + Object.defineProperty(obj, '__proto__', { + get: function get() { + return proto; + }, + set: function set(value) { + proto.__proto__ = value; + } + }); + } + + var Dom7 = /*#__PURE__*/function (_Array) { + _inheritsLoose(Dom7, _Array); + + function Dom7(items) { + var _this; + + _this = _Array.call.apply(_Array, [this].concat(items)) || this; + makeReactive(_assertThisInitialized(_this)); + return _this; + } + + return Dom7; + }( /*#__PURE__*/_wrapNativeSuper(Array)); + + function arrayFlat(arr) { + if (arr === void 0) { + arr = []; + } + + var res = []; + arr.forEach(function (el) { + if (Array.isArray(el)) { + res.push.apply(res, arrayFlat(el)); + } else { + res.push(el); + } + }); + return res; + } + function arrayFilter(arr, callback) { + return Array.prototype.filter.call(arr, callback); + } + function arrayUnique(arr) { + var uniqueArray = []; + + for (var i = 0; i < arr.length; i += 1) { + if (uniqueArray.indexOf(arr[i]) === -1) uniqueArray.push(arr[i]); + } + + return uniqueArray; + } + function toCamelCase(string) { + return string.toLowerCase().replace(/-(.)/g, function (match, group) { + return group.toUpperCase(); + }); + } + + function qsa(selector, context) { + if (typeof selector !== 'string') { + return [selector]; + } + + var a = []; + var res = context.querySelectorAll(selector); + + for (var i = 0; i < res.length; i += 1) { + a.push(res[i]); + } + + return a; + } + + function $(selector, context) { + var window = ssrWindow_umd.getWindow(); + var document = ssrWindow_umd.getDocument(); + var arr = []; + + if (!context && selector instanceof Dom7) { + return selector; + } + + if (!selector) { + return new Dom7(arr); + } + + if (typeof selector === 'string') { + var html = selector.trim(); + + if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) { + var toCreate = 'div'; + if (html.indexOf(' 0; + }).length > 0; + } + + function attr(attrs, value) { + if (arguments.length === 1 && typeof attrs === 'string') { + // Get attr + if (this[0]) return this[0].getAttribute(attrs); + return undefined; + } // Set attrs + + + for (var i = 0; i < this.length; i += 1) { + if (arguments.length === 2) { + // String + this[i].setAttribute(attrs, value); + } else { + // Object + for (var attrName in attrs) { + this[i][attrName] = attrs[attrName]; + this[i].setAttribute(attrName, attrs[attrName]); + } + } + } + + return this; + } + + function removeAttr(attr) { + for (var i = 0; i < this.length; i += 1) { + this[i].removeAttribute(attr); + } + + return this; + } + + function prop(props, value) { + if (arguments.length === 1 && typeof props === 'string') { + // Get prop + if (this[0]) return this[0][props]; + } else { + // Set props + for (var i = 0; i < this.length; i += 1) { + if (arguments.length === 2) { + // String + this[i][props] = value; + } else { + // Object + for (var propName in props) { + this[i][propName] = props[propName]; + } + } + } + + return this; + } + + return this; + } + + function data(key, value) { + var el; + + if (typeof value === 'undefined') { + el = this[0]; + if (!el) return undefined; // Get value + + if (el.dom7ElementDataStorage && key in el.dom7ElementDataStorage) { + return el.dom7ElementDataStorage[key]; + } + + var dataKey = el.getAttribute("data-" + key); + + if (dataKey) { + return dataKey; + } + + return undefined; + } // Set value + + + for (var i = 0; i < this.length; i += 1) { + el = this[i]; + if (!el.dom7ElementDataStorage) el.dom7ElementDataStorage = {}; + el.dom7ElementDataStorage[key] = value; + } + + return this; + } + + function removeData(key) { + for (var i = 0; i < this.length; i += 1) { + var el = this[i]; + + if (el.dom7ElementDataStorage && el.dom7ElementDataStorage[key]) { + el.dom7ElementDataStorage[key] = null; + delete el.dom7ElementDataStorage[key]; + } + } + } + + function dataset() { + var el = this[0]; + if (!el) return undefined; + var dataset = {}; // eslint-disable-line + + if (el.dataset) { + for (var dataKey in el.dataset) { + dataset[dataKey] = el.dataset[dataKey]; + } + } else { + for (var i = 0; i < el.attributes.length; i += 1) { + var _attr = el.attributes[i]; + + if (_attr.name.indexOf('data-') >= 0) { + dataset[toCamelCase(_attr.name.split('data-')[1])] = _attr.value; + } + } + } + + for (var key in dataset) { + if (dataset[key] === 'false') dataset[key] = false;else if (dataset[key] === 'true') dataset[key] = true;else if (parseFloat(dataset[key]) === dataset[key] * 1) dataset[key] *= 1; + } + + return dataset; + } + + function val(value) { + if (typeof value === 'undefined') { + // get value + var el = this[0]; + if (!el) return undefined; + + if (el.multiple && el.nodeName.toLowerCase() === 'select') { + var values = []; + + for (var i = 0; i < el.selectedOptions.length; i += 1) { + values.push(el.selectedOptions[i].value); + } + + return values; + } + + return el.value; + } // set value + + + for (var _i = 0; _i < this.length; _i += 1) { + var _el = this[_i]; + + if (Array.isArray(value) && _el.multiple && _el.nodeName.toLowerCase() === 'select') { + for (var j = 0; j < _el.options.length; j += 1) { + _el.options[j].selected = value.indexOf(_el.options[j].value) >= 0; + } + } else { + _el.value = value; + } + } + + return this; + } + + function value(value) { + return this.val(value); + } + + function transform(transform) { + for (var i = 0; i < this.length; i += 1) { + this[i].style.transform = transform; + } + + return this; + } + + function transition(duration) { + for (var i = 0; i < this.length; i += 1) { + this[i].style.transitionDuration = typeof duration !== 'string' ? duration + "ms" : duration; + } + + return this; + } + + function on() { + for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) { + args[_key5] = arguments[_key5]; + } + + var eventType = args[0], + targetSelector = args[1], + listener = args[2], + capture = args[3]; + + if (typeof args[1] === 'function') { + eventType = args[0]; + listener = args[1]; + capture = args[2]; + targetSelector = undefined; + } + + if (!capture) capture = false; + + function handleLiveEvent(e) { + var target = e.target; + if (!target) return; + var eventData = e.target.dom7EventData || []; + + if (eventData.indexOf(e) < 0) { + eventData.unshift(e); + } + + if ($(target).is(targetSelector)) listener.apply(target, eventData);else { + var _parents = $(target).parents(); // eslint-disable-line + + + for (var k = 0; k < _parents.length; k += 1) { + if ($(_parents[k]).is(targetSelector)) listener.apply(_parents[k], eventData); + } + } + } + + function handleEvent(e) { + var eventData = e && e.target ? e.target.dom7EventData || [] : []; + + if (eventData.indexOf(e) < 0) { + eventData.unshift(e); + } + + listener.apply(this, eventData); + } + + var events = eventType.split(' '); + var j; + + for (var i = 0; i < this.length; i += 1) { + var el = this[i]; + + if (!targetSelector) { + for (j = 0; j < events.length; j += 1) { + var event = events[j]; + if (!el.dom7Listeners) el.dom7Listeners = {}; + if (!el.dom7Listeners[event]) el.dom7Listeners[event] = []; + el.dom7Listeners[event].push({ + listener: listener, + proxyListener: handleEvent + }); + el.addEventListener(event, handleEvent, capture); + } + } else { + // Live events + for (j = 0; j < events.length; j += 1) { + var _event = events[j]; + if (!el.dom7LiveListeners) el.dom7LiveListeners = {}; + if (!el.dom7LiveListeners[_event]) el.dom7LiveListeners[_event] = []; + + el.dom7LiveListeners[_event].push({ + listener: listener, + proxyListener: handleLiveEvent + }); + + el.addEventListener(_event, handleLiveEvent, capture); + } + } + } + + return this; + } + + function off() { + for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) { + args[_key6] = arguments[_key6]; + } + + var eventType = args[0], + targetSelector = args[1], + listener = args[2], + capture = args[3]; + + if (typeof args[1] === 'function') { + eventType = args[0]; + listener = args[1]; + capture = args[2]; + targetSelector = undefined; + } + + if (!capture) capture = false; + var events = eventType.split(' '); + + for (var i = 0; i < events.length; i += 1) { + var event = events[i]; + + for (var j = 0; j < this.length; j += 1) { + var el = this[j]; + var handlers = void 0; + + if (!targetSelector && el.dom7Listeners) { + handlers = el.dom7Listeners[event]; + } else if (targetSelector && el.dom7LiveListeners) { + handlers = el.dom7LiveListeners[event]; + } + + if (handlers && handlers.length) { + for (var k = handlers.length - 1; k >= 0; k -= 1) { + var handler = handlers[k]; + + if (listener && handler.listener === listener) { + el.removeEventListener(event, handler.proxyListener, capture); + handlers.splice(k, 1); + } else if (listener && handler.listener && handler.listener.dom7proxy && handler.listener.dom7proxy === listener) { + el.removeEventListener(event, handler.proxyListener, capture); + handlers.splice(k, 1); + } else if (!listener) { + el.removeEventListener(event, handler.proxyListener, capture); + handlers.splice(k, 1); + } + } + } + } + } + + return this; + } + + function once() { + var dom = this; + + for (var _len7 = arguments.length, args = new Array(_len7), _key7 = 0; _key7 < _len7; _key7++) { + args[_key7] = arguments[_key7]; + } + + var eventName = args[0], + targetSelector = args[1], + listener = args[2], + capture = args[3]; + + if (typeof args[1] === 'function') { + eventName = args[0]; + listener = args[1]; + capture = args[2]; + targetSelector = undefined; + } + + function onceHandler() { + for (var _len8 = arguments.length, eventArgs = new Array(_len8), _key8 = 0; _key8 < _len8; _key8++) { + eventArgs[_key8] = arguments[_key8]; + } + + listener.apply(this, eventArgs); + dom.off(eventName, targetSelector, onceHandler, capture); + + if (onceHandler.dom7proxy) { + delete onceHandler.dom7proxy; + } + } + + onceHandler.dom7proxy = listener; + return dom.on(eventName, targetSelector, onceHandler, capture); + } + + function trigger() { + var window = ssrWindow_umd.getWindow(); + + for (var _len9 = arguments.length, args = new Array(_len9), _key9 = 0; _key9 < _len9; _key9++) { + args[_key9] = arguments[_key9]; + } + + var events = args[0].split(' '); + var eventData = args[1]; + + for (var i = 0; i < events.length; i += 1) { + var event = events[i]; + + for (var j = 0; j < this.length; j += 1) { + var el = this[j]; + + if (window.CustomEvent) { + var evt = new window.CustomEvent(event, { + detail: eventData, + bubbles: true, + cancelable: true + }); + el.dom7EventData = args.filter(function (data, dataIndex) { + return dataIndex > 0; + }); + el.dispatchEvent(evt); + el.dom7EventData = []; + delete el.dom7EventData; + } + } + } + + return this; + } + + function transitionEnd(callback) { + var dom = this; + + function fireCallBack(e) { + if (e.target !== this) return; + callback.call(this, e); + dom.off('transitionend', fireCallBack); + } + + if (callback) { + dom.on('transitionend', fireCallBack); + } + + return this; + } + + function animationEnd(callback) { + var dom = this; + + function fireCallBack(e) { + if (e.target !== this) return; + callback.call(this, e); + dom.off('animationend', fireCallBack); + } + + if (callback) { + dom.on('animationend', fireCallBack); + } + + return this; + } + + function width() { + var window = ssrWindow_umd.getWindow(); + + if (this[0] === window) { + return window.innerWidth; + } + + if (this.length > 0) { + return parseFloat(this.css('width')); + } + + return null; + } + + function outerWidth(includeMargins) { + if (this.length > 0) { + if (includeMargins) { + var _styles = this.styles(); + + return this[0].offsetWidth + parseFloat(_styles.getPropertyValue('margin-right')) + parseFloat(_styles.getPropertyValue('margin-left')); + } + + return this[0].offsetWidth; + } + + return null; + } + + function height() { + var window = ssrWindow_umd.getWindow(); + + if (this[0] === window) { + return window.innerHeight; + } + + if (this.length > 0) { + return parseFloat(this.css('height')); + } + + return null; + } + + function outerHeight(includeMargins) { + if (this.length > 0) { + if (includeMargins) { + var _styles2 = this.styles(); + + return this[0].offsetHeight + parseFloat(_styles2.getPropertyValue('margin-top')) + parseFloat(_styles2.getPropertyValue('margin-bottom')); + } + + return this[0].offsetHeight; + } + + return null; + } + + function offset() { + if (this.length > 0) { + var window = ssrWindow_umd.getWindow(); + var document = ssrWindow_umd.getDocument(); + var el = this[0]; + var box = el.getBoundingClientRect(); + var body = document.body; + var clientTop = el.clientTop || body.clientTop || 0; + var clientLeft = el.clientLeft || body.clientLeft || 0; + var scrollTop = el === window ? window.scrollY : el.scrollTop; + var scrollLeft = el === window ? window.scrollX : el.scrollLeft; + return { + top: box.top + scrollTop - clientTop, + left: box.left + scrollLeft - clientLeft + }; + } + + return null; + } + + function hide() { + for (var i = 0; i < this.length; i += 1) { + this[i].style.display = 'none'; + } + + return this; + } + + function show() { + var window = ssrWindow_umd.getWindow(); + + for (var i = 0; i < this.length; i += 1) { + var el = this[i]; + + if (el.style.display === 'none') { + el.style.display = ''; + } + + if (window.getComputedStyle(el, null).getPropertyValue('display') === 'none') { + // Still not visible + el.style.display = 'block'; + } + } + + return this; + } + + function styles() { + var window = ssrWindow_umd.getWindow(); + if (this[0]) return window.getComputedStyle(this[0], null); + return {}; + } + + function css(props, value) { + var window = ssrWindow_umd.getWindow(); + var i; + + if (arguments.length === 1) { + if (typeof props === 'string') { + // .css('width') + if (this[0]) return window.getComputedStyle(this[0], null).getPropertyValue(props); + } else { + // .css({ width: '100px' }) + for (i = 0; i < this.length; i += 1) { + for (var _prop in props) { + this[i].style[_prop] = props[_prop]; + } + } + + return this; + } + } + + if (arguments.length === 2 && typeof props === 'string') { + // .css('width', '100px') + for (i = 0; i < this.length; i += 1) { + this[i].style[props] = value; + } + + return this; + } + + return this; + } + + function each(callback) { + if (!callback) return this; + this.forEach(function (el, index) { + callback.apply(el, [el, index]); + }); + return this; + } + + function filter(callback) { + var result = arrayFilter(this, callback); + return $(result); + } + + function html(html) { + if (typeof html === 'undefined') { + return this[0] ? this[0].innerHTML : null; + } + + for (var i = 0; i < this.length; i += 1) { + this[i].innerHTML = html; + } + + return this; + } + + function text(text) { + if (typeof text === 'undefined') { + return this[0] ? this[0].textContent.trim() : null; + } + + for (var i = 0; i < this.length; i += 1) { + this[i].textContent = text; + } + + return this; + } + + function is(selector) { + var window = ssrWindow_umd.getWindow(); + var document = ssrWindow_umd.getDocument(); + var el = this[0]; + var compareWith; + var i; + if (!el || typeof selector === 'undefined') return false; + + if (typeof selector === 'string') { + if (el.matches) return el.matches(selector); + if (el.webkitMatchesSelector) return el.webkitMatchesSelector(selector); + if (el.msMatchesSelector) return el.msMatchesSelector(selector); + compareWith = $(selector); + + for (i = 0; i < compareWith.length; i += 1) { + if (compareWith[i] === el) return true; + } + + return false; + } + + if (selector === document) { + return el === document; + } + + if (selector === window) { + return el === window; + } + + if (selector.nodeType || selector instanceof Dom7) { + compareWith = selector.nodeType ? [selector] : selector; + + for (i = 0; i < compareWith.length; i += 1) { + if (compareWith[i] === el) return true; + } + + return false; + } + + return false; + } + + function index$1() { + var child = this[0]; + var i; + + if (child) { + i = 0; // eslint-disable-next-line + + while ((child = child.previousSibling) !== null) { + if (child.nodeType === 1) i += 1; + } + + return i; + } + + return undefined; + } + + function eq(index) { + if (typeof index === 'undefined') return this; + var length = this.length; + + if (index > length - 1) { + return $([]); + } + + if (index < 0) { + var returnIndex = length + index; + if (returnIndex < 0) return $([]); + return $([this[returnIndex]]); + } + + return $([this[index]]); + } + + function append() { + var newChild; + var document = ssrWindow_umd.getDocument(); + + for (var k = 0; k < arguments.length; k += 1) { + newChild = k < 0 || arguments.length <= k ? undefined : arguments[k]; + + for (var i = 0; i < this.length; i += 1) { + if (typeof newChild === 'string') { + var tempDiv = document.createElement('div'); + tempDiv.innerHTML = newChild; + + while (tempDiv.firstChild) { + this[i].appendChild(tempDiv.firstChild); + } + } else if (newChild instanceof Dom7) { + for (var j = 0; j < newChild.length; j += 1) { + this[i].appendChild(newChild[j]); + } + } else { + this[i].appendChild(newChild); + } + } + } + + return this; + } + + function appendTo(parent) { + $(parent).append(this); + return this; + } + + function prepend(newChild) { + var document = ssrWindow_umd.getDocument(); + var i; + var j; + + for (i = 0; i < this.length; i += 1) { + if (typeof newChild === 'string') { + var tempDiv = document.createElement('div'); + tempDiv.innerHTML = newChild; + + for (j = tempDiv.childNodes.length - 1; j >= 0; j -= 1) { + this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]); + } + } else if (newChild instanceof Dom7) { + for (j = 0; j < newChild.length; j += 1) { + this[i].insertBefore(newChild[j], this[i].childNodes[0]); + } + } else { + this[i].insertBefore(newChild, this[i].childNodes[0]); + } + } + + return this; + } + + function prependTo(parent) { + $(parent).prepend(this); + return this; + } + + function insertBefore(selector) { + var before = $(selector); + + for (var i = 0; i < this.length; i += 1) { + if (before.length === 1) { + before[0].parentNode.insertBefore(this[i], before[0]); + } else if (before.length > 1) { + for (var j = 0; j < before.length; j += 1) { + before[j].parentNode.insertBefore(this[i].cloneNode(true), before[j]); + } + } + } + } + + function insertAfter(selector) { + var after = $(selector); + + for (var i = 0; i < this.length; i += 1) { + if (after.length === 1) { + after[0].parentNode.insertBefore(this[i], after[0].nextSibling); + } else if (after.length > 1) { + for (var j = 0; j < after.length; j += 1) { + after[j].parentNode.insertBefore(this[i].cloneNode(true), after[j].nextSibling); + } + } + } + } + + function next(selector) { + if (this.length > 0) { + if (selector) { + if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) { + return $([this[0].nextElementSibling]); + } + + return $([]); + } + + if (this[0].nextElementSibling) return $([this[0].nextElementSibling]); + return $([]); + } + + return $([]); + } + + function nextAll(selector) { + var nextEls = []; + var el = this[0]; + if (!el) return $([]); + + while (el.nextElementSibling) { + var _next = el.nextElementSibling; // eslint-disable-line + + if (selector) { + if ($(_next).is(selector)) nextEls.push(_next); + } else nextEls.push(_next); + + el = _next; + } + + return $(nextEls); + } + + function prev(selector) { + if (this.length > 0) { + var el = this[0]; + + if (selector) { + if (el.previousElementSibling && $(el.previousElementSibling).is(selector)) { + return $([el.previousElementSibling]); + } + + return $([]); + } + + if (el.previousElementSibling) return $([el.previousElementSibling]); + return $([]); + } + + return $([]); + } + + function prevAll(selector) { + var prevEls = []; + var el = this[0]; + if (!el) return $([]); + + while (el.previousElementSibling) { + var _prev = el.previousElementSibling; // eslint-disable-line + + if (selector) { + if ($(_prev).is(selector)) prevEls.push(_prev); + } else prevEls.push(_prev); + + el = _prev; + } + + return $(prevEls); + } + + function siblings(selector) { + return this.nextAll(selector).add(this.prevAll(selector)); + } + + function parent(selector) { + var parents = []; // eslint-disable-line + + for (var i = 0; i < this.length; i += 1) { + if (this[i].parentNode !== null) { + if (selector) { + if ($(this[i].parentNode).is(selector)) parents.push(this[i].parentNode); + } else { + parents.push(this[i].parentNode); + } + } + } + + return $(parents); + } + + function parents(selector) { + var parents = []; // eslint-disable-line + + for (var i = 0; i < this.length; i += 1) { + var _parent = this[i].parentNode; // eslint-disable-line + + while (_parent) { + if (selector) { + if ($(_parent).is(selector)) parents.push(_parent); + } else { + parents.push(_parent); + } + + _parent = _parent.parentNode; + } + } + + return $(parents); + } + + function closest(selector) { + var closest = this; // eslint-disable-line + + if (typeof selector === 'undefined') { + return $([]); + } + + if (!closest.is(selector)) { + closest = closest.parents(selector).eq(0); + } + + return closest; + } + + function find(selector) { + var foundElements = []; + + for (var i = 0; i < this.length; i += 1) { + var found = this[i].querySelectorAll(selector); + + for (var j = 0; j < found.length; j += 1) { + foundElements.push(found[j]); + } + } + + return $(foundElements); + } + + function children(selector) { + var children = []; // eslint-disable-line + + for (var i = 0; i < this.length; i += 1) { + var childNodes = this[i].children; + + for (var j = 0; j < childNodes.length; j += 1) { + if (!selector || $(childNodes[j]).is(selector)) { + children.push(childNodes[j]); + } + } + } + + return $(children); + } + + function remove() { + for (var i = 0; i < this.length; i += 1) { + if (this[i].parentNode) this[i].parentNode.removeChild(this[i]); + } + + return this; + } + + function detach() { + return this.remove(); + } + + function add() { + var dom = this; + var i; + var j; + + for (var _len10 = arguments.length, els = new Array(_len10), _key10 = 0; _key10 < _len10; _key10++) { + els[_key10] = arguments[_key10]; + } + + for (i = 0; i < els.length; i += 1) { + var toAdd = $(els[i]); + + for (j = 0; j < toAdd.length; j += 1) { + dom.push(toAdd[j]); + } + } + + return dom; + } + + function empty() { + for (var i = 0; i < this.length; i += 1) { + var el = this[i]; + + if (el.nodeType === 1) { + for (var j = 0; j < el.childNodes.length; j += 1) { + if (el.childNodes[j].parentNode) { + el.childNodes[j].parentNode.removeChild(el.childNodes[j]); + } + } + + el.textContent = ''; + } + } + + return this; + } + + function scrollTo() { + var window = ssrWindow_umd.getWindow(); + + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + var left = args[0], + top = args[1], + duration = args[2], + easing = args[3], + callback = args[4]; + + if (args.length === 4 && typeof easing === 'function') { + callback = easing; + left = args[0]; + top = args[1]; + duration = args[2]; + callback = args[3]; + easing = args[4]; + } + + if (typeof easing === 'undefined') easing = 'swing'; + return this.each(function animate() { + var el = this; + var currentTop; + var currentLeft; + var maxTop; + var maxLeft; + var newTop; + var newLeft; + var scrollTop; // eslint-disable-line + + var scrollLeft; // eslint-disable-line + + var animateTop = top > 0 || top === 0; + var animateLeft = left > 0 || left === 0; + + if (typeof easing === 'undefined') { + easing = 'swing'; + } + + if (animateTop) { + currentTop = el.scrollTop; + + if (!duration) { + el.scrollTop = top; + } + } + + if (animateLeft) { + currentLeft = el.scrollLeft; + + if (!duration) { + el.scrollLeft = left; + } + } + + if (!duration) return; + + if (animateTop) { + maxTop = el.scrollHeight - el.offsetHeight; + newTop = Math.max(Math.min(top, maxTop), 0); + } + + if (animateLeft) { + maxLeft = el.scrollWidth - el.offsetWidth; + newLeft = Math.max(Math.min(left, maxLeft), 0); + } + + var startTime = null; + if (animateTop && newTop === currentTop) animateTop = false; + if (animateLeft && newLeft === currentLeft) animateLeft = false; + + function render(time) { + if (time === void 0) { + time = new Date().getTime(); + } + + if (startTime === null) { + startTime = time; + } + + var progress = Math.max(Math.min((time - startTime) / duration, 1), 0); + var easeProgress = easing === 'linear' ? progress : 0.5 - Math.cos(progress * Math.PI) / 2; + var done; + if (animateTop) scrollTop = currentTop + easeProgress * (newTop - currentTop); + if (animateLeft) scrollLeft = currentLeft + easeProgress * (newLeft - currentLeft); + + if (animateTop && newTop > currentTop && scrollTop >= newTop) { + el.scrollTop = newTop; + done = true; + } + + if (animateTop && newTop < currentTop && scrollTop <= newTop) { + el.scrollTop = newTop; + done = true; + } + + if (animateLeft && newLeft > currentLeft && scrollLeft >= newLeft) { + el.scrollLeft = newLeft; + done = true; + } + + if (animateLeft && newLeft < currentLeft && scrollLeft <= newLeft) { + el.scrollLeft = newLeft; + done = true; + } + + if (done) { + if (callback) callback(); + return; + } + + if (animateTop) el.scrollTop = scrollTop; + if (animateLeft) el.scrollLeft = scrollLeft; + window.requestAnimationFrame(render); + } + + window.requestAnimationFrame(render); + }); + } // scrollTop(top, duration, easing, callback) { + + + function scrollTop() { + for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + + var top = args[0], + duration = args[1], + easing = args[2], + callback = args[3]; + + if (args.length === 3 && typeof easing === 'function') { + top = args[0]; + duration = args[1]; + callback = args[2]; + easing = args[3]; + } + + var dom = this; + + if (typeof top === 'undefined') { + if (dom.length > 0) return dom[0].scrollTop; + return null; + } + + return dom.scrollTo(undefined, top, duration, easing, callback); + } + + function scrollLeft() { + for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + args[_key3] = arguments[_key3]; + } + + var left = args[0], + duration = args[1], + easing = args[2], + callback = args[3]; + + if (args.length === 3 && typeof easing === 'function') { + left = args[0]; + duration = args[1]; + callback = args[2]; + easing = args[3]; + } + + var dom = this; + + if (typeof left === 'undefined') { + if (dom.length > 0) return dom[0].scrollLeft; + return null; + } + + return dom.scrollTo(left, undefined, duration, easing, callback); + } + + function animate(initialProps, initialParams) { + var window = ssrWindow_umd.getWindow(); + var els = this; + var a = { + props: Object.assign({}, initialProps), + params: Object.assign({ + duration: 300, + easing: 'swing' // or 'linear' + + /* Callbacks + begin(elements) + complete(elements) + progress(elements, complete, remaining, start, tweenValue) + */ + + }, initialParams), + elements: els, + animating: false, + que: [], + easingProgress: function easingProgress(easing, progress) { + if (easing === 'swing') { + return 0.5 - Math.cos(progress * Math.PI) / 2; + } + + if (typeof easing === 'function') { + return easing(progress); + } + + return progress; + }, + stop: function stop() { + if (a.frameId) { + window.cancelAnimationFrame(a.frameId); + } + + a.animating = false; + a.elements.each(function (el) { + var element = el; + delete element.dom7AnimateInstance; + }); + a.que = []; + }, + done: function done(complete) { + a.animating = false; + a.elements.each(function (el) { + var element = el; + delete element.dom7AnimateInstance; + }); + if (complete) complete(els); + + if (a.que.length > 0) { + var que = a.que.shift(); + a.animate(que[0], que[1]); + } + }, + animate: function animate(props, params) { + if (a.animating) { + a.que.push([props, params]); + return a; + } + + var elements = []; // Define & Cache Initials & Units + + a.elements.each(function (el, index) { + var initialFullValue; + var initialValue; + var unit; + var finalValue; + var finalFullValue; + if (!el.dom7AnimateInstance) a.elements[index].dom7AnimateInstance = a; + elements[index] = { + container: el + }; + Object.keys(props).forEach(function (prop) { + initialFullValue = window.getComputedStyle(el, null).getPropertyValue(prop).replace(',', '.'); + initialValue = parseFloat(initialFullValue); + unit = initialFullValue.replace(initialValue, ''); + finalValue = parseFloat(props[prop]); + finalFullValue = props[prop] + unit; + elements[index][prop] = { + initialFullValue: initialFullValue, + initialValue: initialValue, + unit: unit, + finalValue: finalValue, + finalFullValue: finalFullValue, + currentValue: initialValue + }; + }); + }); + var startTime = null; + var time; + var elementsDone = 0; + var propsDone = 0; + var done; + var began = false; + a.animating = true; + + function render() { + time = new Date().getTime(); + var progress; + var easeProgress; // let el; + + if (!began) { + began = true; + if (params.begin) params.begin(els); + } + + if (startTime === null) { + startTime = time; + } + + if (params.progress) { + // eslint-disable-next-line + params.progress(els, Math.max(Math.min((time - startTime) / params.duration, 1), 0), startTime + params.duration - time < 0 ? 0 : startTime + params.duration - time, startTime); + } + + elements.forEach(function (element) { + var el = element; + if (done || el.done) return; + Object.keys(props).forEach(function (prop) { + if (done || el.done) return; + progress = Math.max(Math.min((time - startTime) / params.duration, 1), 0); + easeProgress = a.easingProgress(params.easing, progress); + var _el$prop = el[prop], + initialValue = _el$prop.initialValue, + finalValue = _el$prop.finalValue, + unit = _el$prop.unit; + el[prop].currentValue = initialValue + easeProgress * (finalValue - initialValue); + var currentValue = el[prop].currentValue; + + if (finalValue > initialValue && currentValue >= finalValue || finalValue < initialValue && currentValue <= finalValue) { + el.container.style[prop] = finalValue + unit; + propsDone += 1; + + if (propsDone === Object.keys(props).length) { + el.done = true; + elementsDone += 1; + } + + if (elementsDone === elements.length) { + done = true; + } + } + + if (done) { + a.done(params.complete); + return; + } + + el.container.style[prop] = currentValue + unit; + }); + }); + if (done) return; // Then call + + a.frameId = window.requestAnimationFrame(render); + } + + a.frameId = window.requestAnimationFrame(render); + return a; + } + }; + + if (a.elements.length === 0) { + return els; + } + + var animateInstance; + + for (var i = 0; i < a.elements.length; i += 1) { + if (a.elements[i].dom7AnimateInstance) { + animateInstance = a.elements[i].dom7AnimateInstance; + } else a.elements[i].dom7AnimateInstance = a; + } + + if (!animateInstance) { + animateInstance = a; + } + + if (initialProps === 'stop') { + animateInstance.stop(); + } else { + animateInstance.animate(a.props, a.params); + } + + return els; + } + + function stop() { + var els = this; + + for (var i = 0; i < els.length; i += 1) { + if (els[i].dom7AnimateInstance) { + els[i].dom7AnimateInstance.stop(); + } + } + } + + var noTrigger = 'resize scroll'.split(' '); + + function shortcut(name) { + function eventHandler() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + if (typeof args[0] === 'undefined') { + for (var i = 0; i < this.length; i += 1) { + if (noTrigger.indexOf(name) < 0) { + if (name in this[i]) this[i][name]();else { + $(this[i]).trigger(name); + } + } + } + + return this; + } + + return this.on.apply(this, [name].concat(args)); + } + + return eventHandler; + } + + var click = shortcut('click'); + var blur = shortcut('blur'); + var focus = shortcut('focus'); + var focusin = shortcut('focusin'); + var focusout = shortcut('focusout'); + var keyup = shortcut('keyup'); + var keydown = shortcut('keydown'); + var keypress = shortcut('keypress'); + var submit = shortcut('submit'); + var change = shortcut('change'); + var mousedown = shortcut('mousedown'); + var mousemove = shortcut('mousemove'); + var mouseup = shortcut('mouseup'); + var mouseenter = shortcut('mouseenter'); + var mouseleave = shortcut('mouseleave'); + var mouseout = shortcut('mouseout'); + var mouseover = shortcut('mouseover'); + var touchstart = shortcut('touchstart'); + var touchend = shortcut('touchend'); + var touchmove = shortcut('touchmove'); + var resize = shortcut('resize'); + var scroll = shortcut('scroll'); + + var $_1 = $; + var add_1 = add; + var addClass_1 = addClass; + var animate_1 = animate; + var animationEnd_1 = animationEnd; + var append_1 = append; + var appendTo_1 = appendTo; + var attr_1 = attr; + var blur_1 = blur; + var change_1 = change; + var children_1 = children; + var click_1 = click; + var closest_1 = closest; + var css_1 = css; + var data_1 = data; + var dataset_1 = dataset; + var _default$1 = $; + var detach_1 = detach; + var each_1 = each; + var empty_1 = empty; + var eq_1 = eq; + var filter_1 = filter; + var find_1 = find; + var focus_1 = focus; + var focusin_1 = focusin; + var focusout_1 = focusout; + var hasClass_1 = hasClass; + var height_1 = height; + var hide_1 = hide; + var html_1 = html; + var index_1 = index$1; + var insertAfter_1 = insertAfter; + var insertBefore_1 = insertBefore; + var is_1 = is; + var keydown_1 = keydown; + var keypress_1 = keypress; + var keyup_1 = keyup; + var mousedown_1 = mousedown; + var mouseenter_1 = mouseenter; + var mouseleave_1 = mouseleave; + var mousemove_1 = mousemove; + var mouseout_1 = mouseout; + var mouseover_1 = mouseover; + var mouseup_1 = mouseup; + var next_1 = next; + var nextAll_1 = nextAll; + var off_1 = off; + var offset_1 = offset; + var on_1 = on; + var once_1 = once; + var outerHeight_1 = outerHeight; + var outerWidth_1 = outerWidth; + var parent_1 = parent; + var parents_1 = parents; + var prepend_1 = prepend; + var prependTo_1 = prependTo; + var prev_1 = prev; + var prevAll_1 = prevAll; + var prop_1 = prop; + var remove_1 = remove; + var removeAttr_1 = removeAttr; + var removeClass_1 = removeClass; + var removeData_1 = removeData; + var resize_1 = resize; + var scroll_1 = scroll; + var scrollLeft_1 = scrollLeft; + var scrollTo_1 = scrollTo; + var scrollTop_1 = scrollTop; + var show_1 = show; + var siblings_1 = siblings; + var stop_1 = stop; + var styles_1 = styles; + var submit_1 = submit; + var text_1 = text; + var toggleClass_1 = toggleClass; + var touchend_1 = touchend; + var touchmove_1 = touchmove; + var touchstart_1 = touchstart; + var transform_1 = transform; + var transition_1 = transition; + var transitionEnd_1 = transitionEnd; + var trigger_1 = trigger; + var val_1 = val; + var value_1 = value; + var width_1 = width; + + var dom7_cjs = /*#__PURE__*/Object.defineProperty({ + $: $_1, + add: add_1, + addClass: addClass_1, + animate: animate_1, + animationEnd: animationEnd_1, + append: append_1, + appendTo: appendTo_1, + attr: attr_1, + blur: blur_1, + change: change_1, + children: children_1, + click: click_1, + closest: closest_1, + css: css_1, + data: data_1, + dataset: dataset_1, + default: _default$1, + detach: detach_1, + each: each_1, + empty: empty_1, + eq: eq_1, + filter: filter_1, + find: find_1, + focus: focus_1, + focusin: focusin_1, + focusout: focusout_1, + hasClass: hasClass_1, + height: height_1, + hide: hide_1, + html: html_1, + index: index_1, + insertAfter: insertAfter_1, + insertBefore: insertBefore_1, + is: is_1, + keydown: keydown_1, + keypress: keypress_1, + keyup: keyup_1, + mousedown: mousedown_1, + mouseenter: mouseenter_1, + mouseleave: mouseleave_1, + mousemove: mousemove_1, + mouseout: mouseout_1, + mouseover: mouseover_1, + mouseup: mouseup_1, + next: next_1, + nextAll: nextAll_1, + off: off_1, + offset: offset_1, + on: on_1, + once: once_1, + outerHeight: outerHeight_1, + outerWidth: outerWidth_1, + parent: parent_1, + parents: parents_1, + prepend: prepend_1, + prependTo: prependTo_1, + prev: prev_1, + prevAll: prevAll_1, + prop: prop_1, + remove: remove_1, + removeAttr: removeAttr_1, + removeClass: removeClass_1, + removeData: removeData_1, + resize: resize_1, + scroll: scroll_1, + scrollLeft: scrollLeft_1, + scrollTo: scrollTo_1, + scrollTop: scrollTop_1, + show: show_1, + siblings: siblings_1, + stop: stop_1, + styles: styles_1, + submit: submit_1, + text: text_1, + toggleClass: toggleClass_1, + touchend: touchend_1, + touchmove: touchmove_1, + touchstart: touchstart_1, + transform: transform_1, + transition: transition_1, + transitionEnd: transitionEnd_1, + trigger: trigger_1, + val: val_1, + value: value_1, + width: width_1 + }, '__esModule', {value: true}); + + /** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER = 9007199254740991; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]'; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array ? array.length : 0; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + /** Used for built-in method references. */ + var objectProto$3 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$1 = objectProto$3.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString$3 = objectProto$3.toString; + + /** Built-in value references. */ + var propertyIsEnumerable = objectProto$3.propertyIsEnumerable; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeKeys = overArg(Object.keys, Object); + + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ + function arrayLikeKeys(value, inherited) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + // Safari 9 makes `arguments.length` enumerable in strict mode. + var result = (isArray(value) || isArguments(value)) + ? baseTimes(value.length, String) + : []; + + var length = result.length, + skipIndexes = !!length; + + for (var key in value) { + if ((inherited || hasOwnProperty$1.call(value, key)) && + !(skipIndexes && (key == 'length' || isIndex(key, length)))) { + result.push(key); + } + } + return result; + } + + /** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ + var baseEach = createBaseEach(baseForOwn); + + /** + * The base implementation of `baseForOwn` which iterates over `object` + * properties returned by `keysFunc` and invokes `iteratee` for each property. + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseFor = createBaseFor(); + + /** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwn(object, iteratee) { + return object && baseFor(object, iteratee, keys); + } + + /** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty$1.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; + } + + /** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!isArrayLike(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; + } + + /** + * Creates a base function for methods like `_.forIn` and `_.forOwn`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; + + while (length--) { + var key = props[fromRight ? length : ++index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$3; + + return value === proto; + } + + /** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _([1, 2]).forEach(function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ + function forEach(collection, iteratee) { + var func = isArray(collection) ? arrayEach : baseEach; + return func(collection, typeof iteratee == 'function' ? iteratee : identity); + } + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty$1.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString$3.call(value) == argsTag); + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike$3(value) && isArrayLike(value); + } + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject$2(value) ? objectToString$3.call(value) : ''; + return tag == funcTag || tag == genTag; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject$2(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike$3(value) { + return !!value && typeof value == 'object'; + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + + /** + * This method returns the first argument it receives. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'a': 1 }; + * + * console.log(_.identity(object) === object); + * // => true + */ + function identity(value) { + return value; + } + + var lodash_foreach = forEach; + + let urlAlphabet$1 = + 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'; + var urlAlphabet_1 = { urlAlphabet: urlAlphabet$1 }; + + let { urlAlphabet } = urlAlphabet_1; + { + if ( + typeof navigator !== 'undefined' && + navigator.product === 'ReactNative' && + typeof crypto === 'undefined' + ) { + throw new Error( + 'React Native does not have a built-in secure random generator. ' + + 'If you don’t need unpredictable IDs use `nanoid/non-secure`. ' + + 'For secure IDs, import `react-native-get-random-values` ' + + 'before Nano ID.' + ) + } + if (typeof msCrypto !== 'undefined' && typeof crypto === 'undefined') { + throw new Error( + 'Import file with `if (!window.crypto) window.crypto = window.msCrypto`' + + ' before importing Nano ID to fix IE 11 support' + ) + } + if (typeof crypto === 'undefined') { + throw new Error( + 'Your browser does not have secure random generator. ' + + 'If you don’t need unpredictable IDs, you can use nanoid/non-secure.' + ) + } + } + let random = bytes => crypto.getRandomValues(new Uint8Array(bytes)); + let customRandom = (alphabet, size, getRandom) => { + let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1; + let step = -~((1.6 * mask * size) / alphabet.length); + return () => { + let id = ''; + while (true) { + let bytes = getRandom(step); + let j = step; + while (j--) { + id += alphabet[bytes[j] & mask] || ''; + if (id.length === size) return id + } + } + } + }; + let customAlphabet = (alphabet, size) => customRandom(alphabet, size, random); + let nanoid$2 = (size = 21) => { + let id = ''; + let bytes = crypto.getRandomValues(new Uint8Array(size)); + while (size--) { + let byte = bytes[size] & 63; + if (byte < 36) { + id += byte.toString(36); + } else if (byte < 62) { + id += (byte - 26).toString(36).toUpperCase(); + } else if (byte < 63) { + id += '_'; + } else { + id += '-'; + } + } + return id + }; + var index_browser = { nanoid: nanoid$2, customAlphabet, customRandom, urlAlphabet, random }; + + /** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + + /** Used as the `TypeError` message for "Functions" methods. */ + var FUNC_ERROR_TEXT$1 = 'Expected a function'; + + /** Used as references for various `Number` constants. */ + var NAN$1 = 0 / 0; + + /** `Object#toString` result references. */ + var symbolTag$2 = '[object Symbol]'; + + /** Used to match leading and trailing whitespace. */ + var reTrim$1 = /^\s+|\s+$/g; + + /** Used to detect bad signed hexadecimal string values. */ + var reIsBadHex$1 = /^[-+]0x[0-9a-f]+$/i; + + /** Used to detect binary string values. */ + var reIsBinary$1 = /^0b[01]+$/i; + + /** Used to detect octal string values. */ + var reIsOctal$1 = /^0o[0-7]+$/i; + + /** Built-in method references without a dependency on `root`. */ + var freeParseInt$1 = parseInt; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal$2 = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; + + /** Detect free variable `self`. */ + var freeSelf$2 = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root$2 = freeGlobal$2 || freeSelf$2 || Function('return this')(); + + /** Used for built-in method references. */ + var objectProto$2 = Object.prototype; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString$2 = objectProto$2.toString; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeMax$1 = Math.max, + nativeMin$1 = Math.min; + + /** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ + var now$1 = function() { + return root$2.Date.now(); + }; + + /** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed `func` invocations and a `flush` method to immediately invoke them. + * Provide `options` to indicate whether `func` should be invoked on the + * leading and/or trailing edge of the `wait` timeout. The `func` is invoked + * with the last arguments provided to the debounced function. Subsequent + * calls to the debounced function return the result of the last `func` + * invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the debounced function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=false] + * Specify invoking on the leading edge of the timeout. + * @param {number} [options.maxWait] + * The maximum time `func` is allowed to be delayed before it's invoked. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // Avoid costly calculations while the window size is in flux. + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // Invoke `sendMail` when clicked, debouncing subsequent calls. + * jQuery(element).on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. + * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); + * var source = new EventSource('/stream'); + * jQuery(source).on('message', debounced); + * + * // Cancel the trailing debounced invocation. + * jQuery(window).on('popstate', debounced.cancel); + */ + function debounce$2(func, wait, options) { + var lastArgs, + lastThis, + maxWait, + result, + timerId, + lastCallTime, + lastInvokeTime = 0, + leading = false, + maxing = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT$1); + } + wait = toNumber$1(wait) || 0; + if (isObject$1(options)) { + leading = !!options.leading; + maxing = 'maxWait' in options; + maxWait = maxing ? nativeMax$1(toNumber$1(options.maxWait) || 0, wait) : maxWait; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function invokeFunc(time) { + var args = lastArgs, + thisArg = lastThis; + + lastArgs = lastThis = undefined; + lastInvokeTime = time; + result = func.apply(thisArg, args); + return result; + } + + function leadingEdge(time) { + // Reset any `maxWait` timer. + lastInvokeTime = time; + // Start the timer for the trailing edge. + timerId = setTimeout(timerExpired, wait); + // Invoke the leading edge. + return leading ? invokeFunc(time) : result; + } + + function remainingWait(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime, + result = wait - timeSinceLastCall; + + return maxing ? nativeMin$1(result, maxWait - timeSinceLastInvoke) : result; + } + + function shouldInvoke(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime; + + // Either this is the first call, activity has stopped and we're at the + // trailing edge, the system time has gone backwards and we're treating + // it as the trailing edge, or we've hit the `maxWait` limit. + return (lastCallTime === undefined || (timeSinceLastCall >= wait) || + (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); + } + + function timerExpired() { + var time = now$1(); + if (shouldInvoke(time)) { + return trailingEdge(time); + } + // Restart the timer. + timerId = setTimeout(timerExpired, remainingWait(time)); + } + + function trailingEdge(time) { + timerId = undefined; + + // Only invoke if we have `lastArgs` which means `func` has been + // debounced at least once. + if (trailing && lastArgs) { + return invokeFunc(time); + } + lastArgs = lastThis = undefined; + return result; + } + + function cancel() { + if (timerId !== undefined) { + clearTimeout(timerId); + } + lastInvokeTime = 0; + lastArgs = lastCallTime = lastThis = timerId = undefined; + } + + function flush() { + return timerId === undefined ? result : trailingEdge(now$1()); + } + + function debounced() { + var time = now$1(), + isInvoking = shouldInvoke(time); + + lastArgs = arguments; + lastThis = this; + lastCallTime = time; + + if (isInvoking) { + if (timerId === undefined) { + return leadingEdge(lastCallTime); + } + if (maxing) { + // Handle invocations in a tight loop. + timerId = setTimeout(timerExpired, wait); + return invokeFunc(lastCallTime); + } + } + if (timerId === undefined) { + timerId = setTimeout(timerExpired, wait); + } + return result; + } + debounced.cancel = cancel; + debounced.flush = flush; + return debounced; + } + + /** + * Creates a throttled function that only invokes `func` at most once per + * every `wait` milliseconds. The throttled function comes with a `cancel` + * method to cancel delayed `func` invocations and a `flush` method to + * immediately invoke them. Provide `options` to indicate whether `func` + * should be invoked on the leading and/or trailing edge of the `wait` + * timeout. The `func` is invoked with the last arguments provided to the + * throttled function. Subsequent calls to the throttled function return the + * result of the last `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the throttled function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.throttle` and `_.debounce`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to throttle. + * @param {number} [wait=0] The number of milliseconds to throttle invocations to. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=true] + * Specify invoking on the leading edge of the timeout. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // Avoid excessively updating the position while scrolling. + * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); + * + * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. + * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); + * jQuery(element).on('click', throttled); + * + * // Cancel the trailing throttled invocation. + * jQuery(window).on('popstate', throttled.cancel); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT$1); + } + if (isObject$1(options)) { + leading = 'leading' in options ? !!options.leading : leading; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + return debounce$2(func, wait, { + 'leading': leading, + 'maxWait': wait, + 'trailing': trailing + }); + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject$1(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike$2(value) { + return !!value && typeof value == 'object'; + } + + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol$2(value) { + return typeof value == 'symbol' || + (isObjectLike$2(value) && objectToString$2.call(value) == symbolTag$2); + } + + /** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ + function toNumber$1(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol$2(value)) { + return NAN$1; + } + if (isObject$1(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = isObject$1(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = value.replace(reTrim$1, ''); + var isBinary = reIsBinary$1.test(value); + return (isBinary || reIsOctal$1.test(value)) + ? freeParseInt$1(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex$1.test(value) ? NAN$1 : +value); + } + + var lodash_throttle = throttle; + + var snabbdom_cjs = createCommonjsModule$1(function (module, exports) { + + Object.defineProperty(exports, '__esModule', { value: true }); + + function createElement(tagName, options) { + return document.createElement(tagName, options); + } + function createElementNS(namespaceURI, qualifiedName, options) { + return document.createElementNS(namespaceURI, qualifiedName, options); + } + function createTextNode(text) { + return document.createTextNode(text); + } + function createComment(text) { + return document.createComment(text); + } + function insertBefore(parentNode, newNode, referenceNode) { + parentNode.insertBefore(newNode, referenceNode); + } + function removeChild(node, child) { + node.removeChild(child); + } + function appendChild(node, child) { + node.appendChild(child); + } + function parentNode(node) { + return node.parentNode; + } + function nextSibling(node) { + return node.nextSibling; + } + function tagName(elm) { + return elm.tagName; + } + function setTextContent(node, text) { + node.textContent = text; + } + function getTextContent(node) { + return node.textContent; + } + function isElement(node) { + return node.nodeType === 1; + } + function isText(node) { + return node.nodeType === 3; + } + function isComment(node) { + return node.nodeType === 8; + } + const htmlDomApi = { + createElement, + createElementNS, + createTextNode, + createComment, + insertBefore, + removeChild, + appendChild, + parentNode, + nextSibling, + tagName, + setTextContent, + getTextContent, + isElement, + isText, + isComment, + }; + + function vnode(sel, data, children, text, elm) { + const key = data === undefined ? undefined : data.key; + return { sel, data, children, text, elm, key }; + } + + const array = Array.isArray; + function primitive(s) { + return typeof s === "string" || + typeof s === "number" || + s instanceof String || + s instanceof Number; + } + + function isUndef(s) { + return s === undefined; + } + function isDef(s) { + return s !== undefined; + } + const emptyNode = vnode("", {}, [], undefined, undefined); + function sameVnode(vnode1, vnode2) { + var _a, _b; + const isSameKey = vnode1.key === vnode2.key; + const isSameIs = ((_a = vnode1.data) === null || _a === void 0 ? void 0 : _a.is) === ((_b = vnode2.data) === null || _b === void 0 ? void 0 : _b.is); + const isSameSel = vnode1.sel === vnode2.sel; + return isSameSel && isSameKey && isSameIs; + } + function isVnode(vnode) { + return vnode.sel !== undefined; + } + function createKeyToOldIdx(children, beginIdx, endIdx) { + var _a; + const map = {}; + for (let i = beginIdx; i <= endIdx; ++i) { + const key = (_a = children[i]) === null || _a === void 0 ? void 0 : _a.key; + if (key !== undefined) { + map[key] = i; + } + } + return map; + } + const hooks = [ + "create", + "update", + "remove", + "destroy", + "pre", + "post", + ]; + function init$1(modules, domApi) { + const cbs = { + create: [], + update: [], + remove: [], + destroy: [], + pre: [], + post: [], + }; + const api = domApi !== undefined ? domApi : htmlDomApi; + for (const hook of hooks) { + for (const module of modules) { + const currentHook = module[hook]; + if (currentHook !== undefined) { + cbs[hook].push(currentHook); + } + } + } + function emptyNodeAt(elm) { + const id = elm.id ? "#" + elm.id : ""; + // elm.className doesn't return a string when elm is an SVG element inside a shadowRoot. + // https://stackoverflow.com/questions/29454340/detecting-classname-of-svganimatedstring + const classes = elm.getAttribute("class"); + const c = classes ? "." + classes.split(" ").join(".") : ""; + return vnode(api.tagName(elm).toLowerCase() + id + c, {}, [], undefined, elm); + } + function createRmCb(childElm, listeners) { + return function rmCb() { + if (--listeners === 0) { + const parent = api.parentNode(childElm); + api.removeChild(parent, childElm); + } + }; + } + function createElm(vnode, insertedVnodeQueue) { + var _a, _b; + let i; + let data = vnode.data; + if (data !== undefined) { + const init = (_a = data.hook) === null || _a === void 0 ? void 0 : _a.init; + if (isDef(init)) { + init(vnode); + data = vnode.data; + } + } + const children = vnode.children; + const sel = vnode.sel; + if (sel === "!") { + if (isUndef(vnode.text)) { + vnode.text = ""; + } + vnode.elm = api.createComment(vnode.text); + } + else if (sel !== undefined) { + // Parse selector + const hashIdx = sel.indexOf("#"); + const dotIdx = sel.indexOf(".", hashIdx); + const hash = hashIdx > 0 ? hashIdx : sel.length; + const dot = dotIdx > 0 ? dotIdx : sel.length; + const tag = hashIdx !== -1 || dotIdx !== -1 + ? sel.slice(0, Math.min(hash, dot)) + : sel; + const elm = (vnode.elm = + isDef(data) && isDef((i = data.ns)) + ? api.createElementNS(i, tag, data) + : api.createElement(tag, data)); + if (hash < dot) + elm.setAttribute("id", sel.slice(hash + 1, dot)); + if (dotIdx > 0) + elm.setAttribute("class", sel.slice(dot + 1).replace(/\./g, " ")); + for (i = 0; i < cbs.create.length; ++i) + cbs.create[i](emptyNode, vnode); + if (array(children)) { + for (i = 0; i < children.length; ++i) { + const ch = children[i]; + if (ch != null) { + api.appendChild(elm, createElm(ch, insertedVnodeQueue)); + } + } + } + else if (primitive(vnode.text)) { + api.appendChild(elm, api.createTextNode(vnode.text)); + } + const hook = vnode.data.hook; + if (isDef(hook)) { + (_b = hook.create) === null || _b === void 0 ? void 0 : _b.call(hook, emptyNode, vnode); + if (hook.insert) { + insertedVnodeQueue.push(vnode); + } + } + } + else { + vnode.elm = api.createTextNode(vnode.text); + } + return vnode.elm; + } + function addVnodes(parentElm, before, vnodes, startIdx, endIdx, insertedVnodeQueue) { + for (; startIdx <= endIdx; ++startIdx) { + const ch = vnodes[startIdx]; + if (ch != null) { + api.insertBefore(parentElm, createElm(ch, insertedVnodeQueue), before); + } + } + } + function invokeDestroyHook(vnode) { + var _a, _b; + const data = vnode.data; + if (data !== undefined) { + (_b = (_a = data === null || data === void 0 ? void 0 : data.hook) === null || _a === void 0 ? void 0 : _a.destroy) === null || _b === void 0 ? void 0 : _b.call(_a, vnode); + for (let i = 0; i < cbs.destroy.length; ++i) + cbs.destroy[i](vnode); + if (vnode.children !== undefined) { + for (let j = 0; j < vnode.children.length; ++j) { + const child = vnode.children[j]; + if (child != null && typeof child !== "string") { + invokeDestroyHook(child); + } + } + } + } + } + function removeVnodes(parentElm, vnodes, startIdx, endIdx) { + var _a, _b; + for (; startIdx <= endIdx; ++startIdx) { + let listeners; + let rm; + const ch = vnodes[startIdx]; + if (ch != null) { + if (isDef(ch.sel)) { + invokeDestroyHook(ch); + listeners = cbs.remove.length + 1; + rm = createRmCb(ch.elm, listeners); + for (let i = 0; i < cbs.remove.length; ++i) + cbs.remove[i](ch, rm); + const removeHook = (_b = (_a = ch === null || ch === void 0 ? void 0 : ch.data) === null || _a === void 0 ? void 0 : _a.hook) === null || _b === void 0 ? void 0 : _b.remove; + if (isDef(removeHook)) { + removeHook(ch, rm); + } + else { + rm(); + } + } + else { + // Text node + api.removeChild(parentElm, ch.elm); + } + } + } + } + function updateChildren(parentElm, oldCh, newCh, insertedVnodeQueue) { + let oldStartIdx = 0; + let newStartIdx = 0; + let oldEndIdx = oldCh.length - 1; + let oldStartVnode = oldCh[0]; + let oldEndVnode = oldCh[oldEndIdx]; + let newEndIdx = newCh.length - 1; + let newStartVnode = newCh[0]; + let newEndVnode = newCh[newEndIdx]; + let oldKeyToIdx; + let idxInOld; + let elmToMove; + let before; + while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) { + if (oldStartVnode == null) { + oldStartVnode = oldCh[++oldStartIdx]; // Vnode might have been moved left + } + else if (oldEndVnode == null) { + oldEndVnode = oldCh[--oldEndIdx]; + } + else if (newStartVnode == null) { + newStartVnode = newCh[++newStartIdx]; + } + else if (newEndVnode == null) { + newEndVnode = newCh[--newEndIdx]; + } + else if (sameVnode(oldStartVnode, newStartVnode)) { + patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue); + oldStartVnode = oldCh[++oldStartIdx]; + newStartVnode = newCh[++newStartIdx]; + } + else if (sameVnode(oldEndVnode, newEndVnode)) { + patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue); + oldEndVnode = oldCh[--oldEndIdx]; + newEndVnode = newCh[--newEndIdx]; + } + else if (sameVnode(oldStartVnode, newEndVnode)) { + // Vnode moved right + patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue); + api.insertBefore(parentElm, oldStartVnode.elm, api.nextSibling(oldEndVnode.elm)); + oldStartVnode = oldCh[++oldStartIdx]; + newEndVnode = newCh[--newEndIdx]; + } + else if (sameVnode(oldEndVnode, newStartVnode)) { + // Vnode moved left + patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue); + api.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm); + oldEndVnode = oldCh[--oldEndIdx]; + newStartVnode = newCh[++newStartIdx]; + } + else { + if (oldKeyToIdx === undefined) { + oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx); + } + idxInOld = oldKeyToIdx[newStartVnode.key]; + if (isUndef(idxInOld)) { + // New element + api.insertBefore(parentElm, createElm(newStartVnode, insertedVnodeQueue), oldStartVnode.elm); + } + else { + elmToMove = oldCh[idxInOld]; + if (elmToMove.sel !== newStartVnode.sel) { + api.insertBefore(parentElm, createElm(newStartVnode, insertedVnodeQueue), oldStartVnode.elm); + } + else { + patchVnode(elmToMove, newStartVnode, insertedVnodeQueue); + oldCh[idxInOld] = undefined; + api.insertBefore(parentElm, elmToMove.elm, oldStartVnode.elm); + } + } + newStartVnode = newCh[++newStartIdx]; + } + } + if (oldStartIdx <= oldEndIdx || newStartIdx <= newEndIdx) { + if (oldStartIdx > oldEndIdx) { + before = newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].elm; + addVnodes(parentElm, before, newCh, newStartIdx, newEndIdx, insertedVnodeQueue); + } + else { + removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx); + } + } + } + function patchVnode(oldVnode, vnode, insertedVnodeQueue) { + var _a, _b, _c, _d, _e; + const hook = (_a = vnode.data) === null || _a === void 0 ? void 0 : _a.hook; + (_b = hook === null || hook === void 0 ? void 0 : hook.prepatch) === null || _b === void 0 ? void 0 : _b.call(hook, oldVnode, vnode); + const elm = (vnode.elm = oldVnode.elm); + const oldCh = oldVnode.children; + const ch = vnode.children; + if (oldVnode === vnode) + return; + if (vnode.data !== undefined) { + for (let i = 0; i < cbs.update.length; ++i) + cbs.update[i](oldVnode, vnode); + (_d = (_c = vnode.data.hook) === null || _c === void 0 ? void 0 : _c.update) === null || _d === void 0 ? void 0 : _d.call(_c, oldVnode, vnode); + } + if (isUndef(vnode.text)) { + if (isDef(oldCh) && isDef(ch)) { + if (oldCh !== ch) + updateChildren(elm, oldCh, ch, insertedVnodeQueue); + } + else if (isDef(ch)) { + if (isDef(oldVnode.text)) + api.setTextContent(elm, ""); + addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue); + } + else if (isDef(oldCh)) { + removeVnodes(elm, oldCh, 0, oldCh.length - 1); + } + else if (isDef(oldVnode.text)) { + api.setTextContent(elm, ""); + } + } + else if (oldVnode.text !== vnode.text) { + if (isDef(oldCh)) { + removeVnodes(elm, oldCh, 0, oldCh.length - 1); + } + api.setTextContent(elm, vnode.text); + } + (_e = hook === null || hook === void 0 ? void 0 : hook.postpatch) === null || _e === void 0 ? void 0 : _e.call(hook, oldVnode, vnode); + } + return function patch(oldVnode, vnode) { + let i, elm, parent; + const insertedVnodeQueue = []; + for (i = 0; i < cbs.pre.length; ++i) + cbs.pre[i](); + if (!isVnode(oldVnode)) { + oldVnode = emptyNodeAt(oldVnode); + } + if (sameVnode(oldVnode, vnode)) { + patchVnode(oldVnode, vnode, insertedVnodeQueue); + } + else { + elm = oldVnode.elm; + parent = api.parentNode(elm); + createElm(vnode, insertedVnodeQueue); + if (parent !== null) { + api.insertBefore(parent, vnode.elm, api.nextSibling(elm)); + removeVnodes(parent, [oldVnode], 0, 0); + } + } + for (i = 0; i < insertedVnodeQueue.length; ++i) { + insertedVnodeQueue[i].data.hook.insert(insertedVnodeQueue[i]); + } + for (i = 0; i < cbs.post.length; ++i) + cbs.post[i](); + return vnode; + }; + } + + function addNS(data, children, sel) { + data.ns = "http://www.w3.org/2000/svg"; + if (sel !== "foreignObject" && children !== undefined) { + for (let i = 0; i < children.length; ++i) { + const childData = children[i].data; + if (childData !== undefined) { + addNS(childData, children[i].children, children[i].sel); + } + } + } + } + function h(sel, b, c) { + let data = {}; + let children; + let text; + let i; + if (c !== undefined) { + if (b !== null) { + data = b; + } + if (array(c)) { + children = c; + } + else if (primitive(c)) { + text = c.toString(); + } + else if (c && c.sel) { + children = [c]; + } + } + else if (b !== undefined && b !== null) { + if (array(b)) { + children = b; + } + else if (primitive(b)) { + text = b.toString(); + } + else if (b && b.sel) { + children = [b]; + } + else { + data = b; + } + } + if (children !== undefined) { + for (i = 0; i < children.length; ++i) { + if (primitive(children[i])) + children[i] = vnode(undefined, undefined, undefined, children[i], undefined); + } + } + if (sel[0] === "s" && + sel[1] === "v" && + sel[2] === "g" && + (sel.length === 3 || sel[3] === "." || sel[3] === "#")) { + addNS(data, children, sel); + } + return vnode(sel, data, children, text, undefined); + } + + function copyToThunk(vnode, thunk) { + vnode.data.fn = thunk.data.fn; + vnode.data.args = thunk.data.args; + thunk.data = vnode.data; + thunk.children = vnode.children; + thunk.text = vnode.text; + thunk.elm = vnode.elm; + } + function init(thunk) { + const cur = thunk.data; + const vnode = cur.fn(...cur.args); + copyToThunk(vnode, thunk); + } + function prepatch(oldVnode, thunk) { + let i; + const old = oldVnode.data; + const cur = thunk.data; + const oldArgs = old.args; + const args = cur.args; + if (old.fn !== cur.fn || oldArgs.length !== args.length) { + copyToThunk(cur.fn(...args), thunk); + return; + } + for (i = 0; i < args.length; ++i) { + if (oldArgs[i] !== args[i]) { + copyToThunk(cur.fn(...args), thunk); + return; + } + } + copyToThunk(oldVnode, thunk); + } + const thunk = function thunk(sel, key, fn, args) { + if (args === undefined) { + args = fn; + fn = key; + key = undefined; + } + return h(sel, { + key: key, + hook: { init, prepatch }, + fn: fn, + args: args, + }); + }; + + function pre(vnode, newVnode) { + const attachData = vnode.data.attachData; + // Copy created placeholder and real element from old vnode + newVnode.data.attachData.placeholder = attachData.placeholder; + newVnode.data.attachData.real = attachData.real; + // Mount real element in vnode so the patch process operates on it + vnode.elm = vnode.data.attachData.real; + } + function post(_, vnode) { + // Mount dummy placeholder in vnode so potential reorders use it + vnode.elm = vnode.data.attachData.placeholder; + } + function destroy(vnode) { + // Remove placeholder + if (vnode.elm !== undefined) { + vnode.elm.parentNode.removeChild(vnode.elm); + } + // Remove real element from where it was inserted + vnode.elm = vnode.data.attachData.real; + } + function create(_, vnode) { + const real = vnode.elm; + const attachData = vnode.data.attachData; + const placeholder = document.createElement("span"); + // Replace actual element with dummy placeholder + // Snabbdom will then insert placeholder instead + vnode.elm = placeholder; + attachData.target.appendChild(real); + attachData.real = real; + attachData.placeholder = placeholder; + } + function attachTo(target, vnode) { + if (vnode.data === undefined) + vnode.data = {}; + if (vnode.data.hook === undefined) + vnode.data.hook = {}; + const data = vnode.data; + const hook = vnode.data.hook; + data.attachData = { target: target, placeholder: undefined, real: undefined }; + hook.create = create; + hook.prepatch = pre; + hook.postpatch = post; + hook.destroy = destroy; + return vnode; + } + + function toVNode(node, domApi) { + const api = domApi !== undefined ? domApi : htmlDomApi; + let text; + if (api.isElement(node)) { + const id = node.id ? "#" + node.id : ""; + const cn = node.getAttribute("class"); + const c = cn ? "." + cn.split(" ").join(".") : ""; + const sel = api.tagName(node).toLowerCase() + id + c; + const attrs = {}; + const children = []; + let name; + let i, n; + const elmAttrs = node.attributes; + const elmChildren = node.childNodes; + for (i = 0, n = elmAttrs.length; i < n; i++) { + name = elmAttrs[i].nodeName; + if (name !== "id" && name !== "class") { + attrs[name] = elmAttrs[i].nodeValue; + } + } + for (i = 0, n = elmChildren.length; i < n; i++) { + children.push(toVNode(elmChildren[i], domApi)); + } + return vnode(sel, { attrs }, children, undefined, node); + } + else if (api.isText(node)) { + text = api.getTextContent(node); + return vnode(undefined, undefined, undefined, text, node); + } + else if (api.isComment(node)) { + text = api.getTextContent(node); + return vnode("!", {}, [], text, node); + } + else { + return vnode("", {}, [], undefined, node); + } + } + + const xlinkNS = "http://www.w3.org/1999/xlink"; + const xmlNS = "http://www.w3.org/XML/1998/namespace"; + const colonChar = 58; + const xChar = 120; + function updateAttrs(oldVnode, vnode) { + let key; + const elm = vnode.elm; + let oldAttrs = oldVnode.data.attrs; + let attrs = vnode.data.attrs; + if (!oldAttrs && !attrs) + return; + if (oldAttrs === attrs) + return; + oldAttrs = oldAttrs || {}; + attrs = attrs || {}; + // update modified attributes, add new attributes + for (key in attrs) { + const cur = attrs[key]; + const old = oldAttrs[key]; + if (old !== cur) { + if (cur === true) { + elm.setAttribute(key, ""); + } + else if (cur === false) { + elm.removeAttribute(key); + } + else { + if (key.charCodeAt(0) !== xChar) { + elm.setAttribute(key, cur); + } + else if (key.charCodeAt(3) === colonChar) { + // Assume xml namespace + elm.setAttributeNS(xmlNS, key, cur); + } + else if (key.charCodeAt(5) === colonChar) { + // Assume xlink namespace + elm.setAttributeNS(xlinkNS, key, cur); + } + else { + elm.setAttribute(key, cur); + } + } + } + } + // remove removed attributes + // use `in` operator since the previous `for` iteration uses it (.i.e. add even attributes with undefined value) + // the other option is to remove all attributes with value == undefined + for (key in oldAttrs) { + if (!(key in attrs)) { + elm.removeAttribute(key); + } + } + } + const attributesModule = { + create: updateAttrs, + update: updateAttrs, + }; + + function updateClass(oldVnode, vnode) { + let cur; + let name; + const elm = vnode.elm; + let oldClass = oldVnode.data.class; + let klass = vnode.data.class; + if (!oldClass && !klass) + return; + if (oldClass === klass) + return; + oldClass = oldClass || {}; + klass = klass || {}; + for (name in oldClass) { + if (oldClass[name] && !Object.prototype.hasOwnProperty.call(klass, name)) { + // was `true` and now not provided + elm.classList.remove(name); + } + } + for (name in klass) { + cur = klass[name]; + if (cur !== oldClass[name]) { + elm.classList[cur ? "add" : "remove"](name); + } + } + } + const classModule = { create: updateClass, update: updateClass }; + + const CAPS_REGEX = /[A-Z]/g; + function updateDataset(oldVnode, vnode) { + const elm = vnode.elm; + let oldDataset = oldVnode.data.dataset; + let dataset = vnode.data.dataset; + let key; + if (!oldDataset && !dataset) + return; + if (oldDataset === dataset) + return; + oldDataset = oldDataset || {}; + dataset = dataset || {}; + const d = elm.dataset; + for (key in oldDataset) { + if (!dataset[key]) { + if (d) { + if (key in d) { + delete d[key]; + } + } + else { + elm.removeAttribute("data-" + key.replace(CAPS_REGEX, "-$&").toLowerCase()); + } + } + } + for (key in dataset) { + if (oldDataset[key] !== dataset[key]) { + if (d) { + d[key] = dataset[key]; + } + else { + elm.setAttribute("data-" + key.replace(CAPS_REGEX, "-$&").toLowerCase(), dataset[key]); + } + } + } + } + const datasetModule = { + create: updateDataset, + update: updateDataset, + }; + + function invokeHandler(handler, vnode, event) { + if (typeof handler === "function") { + // call function handler + handler.call(vnode, event, vnode); + } + else if (typeof handler === "object") { + // call multiple handlers + for (let i = 0; i < handler.length; i++) { + invokeHandler(handler[i], vnode, event); + } + } + } + function handleEvent(event, vnode) { + const name = event.type; + const on = vnode.data.on; + // call event handler(s) if exists + if (on && on[name]) { + invokeHandler(on[name], vnode, event); + } + } + function createListener() { + return function handler(event) { + handleEvent(event, handler.vnode); + }; + } + function updateEventListeners(oldVnode, vnode) { + const oldOn = oldVnode.data.on; + const oldListener = oldVnode.listener; + const oldElm = oldVnode.elm; + const on = vnode && vnode.data.on; + const elm = (vnode && vnode.elm); + let name; + // optimization for reused immutable handlers + if (oldOn === on) { + return; + } + // remove existing listeners which no longer used + if (oldOn && oldListener) { + // if element changed or deleted we remove all existing listeners unconditionally + if (!on) { + for (name in oldOn) { + // remove listener if element was changed or existing listeners removed + oldElm.removeEventListener(name, oldListener, false); + } + } + else { + for (name in oldOn) { + // remove listener if existing listener removed + if (!on[name]) { + oldElm.removeEventListener(name, oldListener, false); + } + } + } + } + // add new listeners which has not already attached + if (on) { + // reuse existing listener or create new + const listener = (vnode.listener = + oldVnode.listener || createListener()); + // update vnode for listener + listener.vnode = vnode; + // if element changed or added we add all needed listeners unconditionally + if (!oldOn) { + for (name in on) { + // add listener if element was changed or new listeners added + elm.addEventListener(name, listener, false); + } + } + else { + for (name in on) { + // add listener if new listener added + if (!oldOn[name]) { + elm.addEventListener(name, listener, false); + } + } + } + } + } + const eventListenersModule = { + create: updateEventListeners, + update: updateEventListeners, + destroy: updateEventListeners, + }; + + function updateProps(oldVnode, vnode) { + let key; + let cur; + let old; + const elm = vnode.elm; + let oldProps = oldVnode.data.props; + let props = vnode.data.props; + if (!oldProps && !props) + return; + if (oldProps === props) + return; + oldProps = oldProps || {}; + props = props || {}; + for (key in props) { + cur = props[key]; + old = oldProps[key]; + if (old !== cur && (key !== "value" || elm[key] !== cur)) { + elm[key] = cur; + } + } + } + const propsModule = { create: updateProps, update: updateProps }; + + // Bindig `requestAnimationFrame` like this fixes a bug in IE/Edge. See #360 and #409. + const raf = (typeof window !== "undefined" && + window.requestAnimationFrame.bind(window)) || + setTimeout; + const nextFrame = function (fn) { + raf(function () { + raf(fn); + }); + }; + let reflowForced = false; + function setNextFrame(obj, prop, val) { + nextFrame(function () { + obj[prop] = val; + }); + } + function updateStyle(oldVnode, vnode) { + let cur; + let name; + const elm = vnode.elm; + let oldStyle = oldVnode.data.style; + let style = vnode.data.style; + if (!oldStyle && !style) + return; + if (oldStyle === style) + return; + oldStyle = oldStyle || {}; + style = style || {}; + const oldHasDel = "delayed" in oldStyle; + for (name in oldStyle) { + if (!style[name]) { + if (name[0] === "-" && name[1] === "-") { + elm.style.removeProperty(name); + } + else { + elm.style[name] = ""; + } + } + } + for (name in style) { + cur = style[name]; + if (name === "delayed" && style.delayed) { + for (const name2 in style.delayed) { + cur = style.delayed[name2]; + if (!oldHasDel || cur !== oldStyle.delayed[name2]) { + setNextFrame(elm.style, name2, cur); + } + } + } + else if (name !== "remove" && cur !== oldStyle[name]) { + if (name[0] === "-" && name[1] === "-") { + elm.style.setProperty(name, cur); + } + else { + elm.style[name] = cur; + } + } + } + } + function applyDestroyStyle(vnode) { + let style; + let name; + const elm = vnode.elm; + const s = vnode.data.style; + if (!s || !(style = s.destroy)) + return; + for (name in style) { + elm.style[name] = style[name]; + } + } + function applyRemoveStyle(vnode, rm) { + const s = vnode.data.style; + if (!s || !s.remove) { + rm(); + return; + } + if (!reflowForced) { + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + vnode.elm.offsetLeft; + reflowForced = true; + } + let name; + const elm = vnode.elm; + let i = 0; + const style = s.remove; + let amount = 0; + const applied = []; + for (name in style) { + applied.push(name); + elm.style[name] = style[name]; + } + const compStyle = getComputedStyle(elm); + const props = compStyle["transition-property"].split(", "); + for (; i < props.length; ++i) { + if (applied.indexOf(props[i]) !== -1) + amount++; + } + elm.addEventListener("transitionend", function (ev) { + if (ev.target === elm) + --amount; + if (amount === 0) + rm(); + }); + } + function forceReflow() { + reflowForced = false; + } + const styleModule = { + pre: forceReflow, + create: updateStyle, + update: updateStyle, + destroy: applyDestroyStyle, + remove: applyRemoveStyle, + }; + + /* eslint-disable @typescript-eslint/no-namespace, import/export */ + function flattenAndFilter(children, flattened) { + for (const child of children) { + // filter out falsey children, except 0 since zero can be a valid value e.g inside a chart + if (child !== undefined && + child !== null && + child !== false && + child !== "") { + if (Array.isArray(child)) { + flattenAndFilter(child, flattened); + } + else if (typeof child === "string" || + typeof child === "number" || + typeof child === "boolean") { + flattened.push(vnode(undefined, undefined, undefined, String(child), undefined)); + } + else { + flattened.push(child); + } + } + } + return flattened; + } + /** + * jsx/tsx compatible factory function + * see: https://www.typescriptlang.org/docs/handbook/jsx.html#factory-functions + */ + function jsx(tag, data, ...children) { + const flatChildren = flattenAndFilter(children, []); + if (typeof tag === "function") { + // tag is a function component + return tag(data, flatChildren); + } + else { + if (flatChildren.length === 1 && + !flatChildren[0].sel && + flatChildren[0].text) { + // only child is a simple text node, pass as text for a simpler vtree + return h(tag, data, flatChildren[0].text); + } + else { + return h(tag, data, flatChildren); + } + } + } + (function (jsx) { + })(jsx || (jsx = {})); + + exports.array = array; + exports.attachTo = attachTo; + exports.attributesModule = attributesModule; + exports.classModule = classModule; + exports.datasetModule = datasetModule; + exports.eventListenersModule = eventListenersModule; + exports.h = h; + exports.htmlDomApi = htmlDomApi; + exports.init = init$1; + exports.jsx = jsx; + exports.primitive = primitive; + exports.propsModule = propsModule; + exports.styleModule = styleModule; + exports.thunk = thunk; + exports.toVNode = toVNode; + exports.vnode = vnode; + }); + + /** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0; + + /** `Object#toString` result references. */ + var symbolTag$1 = '[object Symbol]'; + + /** Used to match words composed of alphanumeric characters. */ + var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g; + + /** Used to match Latin Unicode letters (excluding mathematical operators). */ + var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g; + + /** Used to compose unicode character classes. */ + var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23', + rsComboSymbolsRange = '\\u20d0-\\u20f0', + rsDingbatRange = '\\u2700-\\u27bf', + rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff', + rsMathOpRange = '\\xac\\xb1\\xd7\\xf7', + rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf', + rsPunctuationRange = '\\u2000-\\u206f', + rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000', + rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde', + rsVarRange = '\\ufe0e\\ufe0f', + rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange; + + /** Used to compose unicode capture groups. */ + var rsApos = "['\u2019]", + rsAstral = '[' + rsAstralRange + ']', + rsBreak = '[' + rsBreakRange + ']', + rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']', + rsDigits = '\\d+', + rsDingbat = '[' + rsDingbatRange + ']', + rsLower = '[' + rsLowerRange + ']', + rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + rsUpper = '[' + rsUpperRange + ']', + rsZWJ = '\\u200d'; + + /** Used to compose unicode regexes. */ + var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')', + rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')', + rsOptLowerContr = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?', + rsOptUpperContr = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?', + reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange + ']?', + rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + + /** Used to match apostrophes. */ + var reApos = RegExp(rsApos, 'g'); + + /** + * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and + * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). + */ + var reComboMark = RegExp(rsCombo, 'g'); + + /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ + var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + + /** Used to match complex or compound words. */ + var reUnicodeWord = RegExp([ + rsUpper + '?' + rsLower + '+' + rsOptLowerContr + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')', + rsUpperMisc + '+' + rsOptUpperContr + '(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')', + rsUpper + '?' + rsLowerMisc + '+' + rsOptLowerContr, + rsUpper + '+' + rsOptUpperContr, + rsDigits, + rsEmoji + ].join('|'), 'g'); + + /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ + var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']'); + + /** Used to detect strings that need a more robust regexp to match words. */ + var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/; + + /** Used to map Latin Unicode letters to basic Latin letters. */ + var deburredLetters = { + // Latin-1 Supplement block. + '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', + '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', + '\xc7': 'C', '\xe7': 'c', + '\xd0': 'D', '\xf0': 'd', + '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', + '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', + '\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', + '\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', + '\xd1': 'N', '\xf1': 'n', + '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', + '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', + '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', + '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', + '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', + '\xc6': 'Ae', '\xe6': 'ae', + '\xde': 'Th', '\xfe': 'th', + '\xdf': 'ss', + // Latin Extended-A block. + '\u0100': 'A', '\u0102': 'A', '\u0104': 'A', + '\u0101': 'a', '\u0103': 'a', '\u0105': 'a', + '\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C', + '\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c', + '\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd', + '\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E', + '\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e', + '\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G', + '\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g', + '\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h', + '\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I', + '\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i', + '\u0134': 'J', '\u0135': 'j', + '\u0136': 'K', '\u0137': 'k', '\u0138': 'k', + '\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L', + '\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l', + '\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N', + '\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n', + '\u014c': 'O', '\u014e': 'O', '\u0150': 'O', + '\u014d': 'o', '\u014f': 'o', '\u0151': 'o', + '\u0154': 'R', '\u0156': 'R', '\u0158': 'R', + '\u0155': 'r', '\u0157': 'r', '\u0159': 'r', + '\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S', + '\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's', + '\u0162': 'T', '\u0164': 'T', '\u0166': 'T', + '\u0163': 't', '\u0165': 't', '\u0167': 't', + '\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U', + '\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u', + '\u0174': 'W', '\u0175': 'w', + '\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y', + '\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z', + '\u017a': 'z', '\u017c': 'z', '\u017e': 'z', + '\u0132': 'IJ', '\u0133': 'ij', + '\u0152': 'Oe', '\u0153': 'oe', + '\u0149': "'n", '\u017f': 'ss' + }; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal$1 = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; + + /** Detect free variable `self`. */ + var freeSelf$1 = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root$1 = freeGlobal$1 || freeSelf$1 || Function('return this')(); + + /** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array ? array.length : 0; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * Converts an ASCII `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function asciiToArray(string) { + return string.split(''); + } + + /** + * Splits an ASCII `string` into an array of its words. + * + * @private + * @param {string} The string to inspect. + * @returns {Array} Returns the words of `string`. + */ + function asciiWords(string) { + return string.match(reAsciiWord) || []; + } + + /** + * The base implementation of `_.propertyOf` without support for deep paths. + * + * @private + * @param {Object} object The object to query. + * @returns {Function} Returns the new accessor function. + */ + function basePropertyOf(object) { + return function(key) { + return object == null ? undefined : object[key]; + }; + } + + /** + * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A + * letters to basic Latin letters. + * + * @private + * @param {string} letter The matched letter to deburr. + * @returns {string} Returns the deburred letter. + */ + var deburrLetter = basePropertyOf(deburredLetters); + + /** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ + function hasUnicode(string) { + return reHasUnicode.test(string); + } + + /** + * Checks if `string` contains a word composed of Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a word is found, else `false`. + */ + function hasUnicodeWord(string) { + return reHasUnicodeWord.test(string); + } + + /** + * Converts `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function stringToArray(string) { + return hasUnicode(string) + ? unicodeToArray(string) + : asciiToArray(string); + } + + /** + * Converts a Unicode `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function unicodeToArray(string) { + return string.match(reUnicode) || []; + } + + /** + * Splits a Unicode `string` into an array of its words. + * + * @private + * @param {string} The string to inspect. + * @returns {Array} Returns the words of `string`. + */ + function unicodeWords(string) { + return string.match(reUnicodeWord) || []; + } + + /** Used for built-in method references. */ + var objectProto$1 = Object.prototype; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString$1 = objectProto$1.toString; + + /** Built-in value references. */ + var Symbol$1 = root$1.Symbol; + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol$1 ? Symbol$1.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = end > length ? length : end; + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } + + /** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ + function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (isSymbol$1(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + } + + /** + * Casts `array` to a slice if it's needed. + * + * @private + * @param {Array} array The array to inspect. + * @param {number} start The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the cast slice. + */ + function castSlice(array, start, end) { + var length = array.length; + end = end === undefined ? length : end; + return (!start && end >= length) ? array : baseSlice(array, start, end); + } + + /** + * Creates a function like `_.lowerFirst`. + * + * @private + * @param {string} methodName The name of the `String` case method to use. + * @returns {Function} Returns the new case function. + */ + function createCaseFirst(methodName) { + return function(string) { + string = toString(string); + + var strSymbols = hasUnicode(string) + ? stringToArray(string) + : undefined; + + var chr = strSymbols + ? strSymbols[0] + : string.charAt(0); + + var trailing = strSymbols + ? castSlice(strSymbols, 1).join('') + : string.slice(1); + + return chr[methodName]() + trailing; + }; + } + + /** + * Creates a function like `_.camelCase`. + * + * @private + * @param {Function} callback The function to combine each word. + * @returns {Function} Returns the new compounder function. + */ + function createCompounder(callback) { + return function(string) { + return arrayReduce(words(deburr(string).replace(reApos, '')), callback, ''); + }; + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike$1(value) { + return !!value && typeof value == 'object'; + } + + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol$1(value) { + return typeof value == 'symbol' || + (isObjectLike$1(value) && objectToString$1.call(value) == symbolTag$1); + } + + /** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {string} Returns the string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ + function toString(value) { + return value == null ? '' : baseToString(value); + } + + /** + * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the camel cased string. + * @example + * + * _.camelCase('Foo Bar'); + * // => 'fooBar' + * + * _.camelCase('--foo-bar--'); + * // => 'fooBar' + * + * _.camelCase('__FOO_BAR__'); + * // => 'fooBar' + */ + var camelCase = createCompounder(function(result, word, index) { + word = word.toLowerCase(); + return result + (index ? capitalize(word) : word); + }); + + /** + * Converts the first character of `string` to upper case and the remaining + * to lower case. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to capitalize. + * @returns {string} Returns the capitalized string. + * @example + * + * _.capitalize('FRED'); + * // => 'Fred' + */ + function capitalize(string) { + return upperFirst(toString(string).toLowerCase()); + } + + /** + * Deburrs `string` by converting + * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A) + * letters to basic Latin letters and removing + * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the deburred string. + * @example + * + * _.deburr('déjà vu'); + * // => 'deja vu' + */ + function deburr(string) { + string = toString(string); + return string && string.replace(reLatin, deburrLetter).replace(reComboMark, ''); + } + + /** + * Converts the first character of `string` to upper case. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.upperFirst('fred'); + * // => 'Fred' + * + * _.upperFirst('FRED'); + * // => 'FRED' + */ + var upperFirst = createCaseFirst('toUpperCase'); + + /** + * Splits `string` into an array of its words. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to inspect. + * @param {RegExp|string} [pattern] The pattern to match words. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {Array} Returns the words of `string`. + * @example + * + * _.words('fred, barney, & pebbles'); + * // => ['fred', 'barney', 'pebbles'] + * + * _.words('fred, barney, & pebbles', /[^, ]+/g); + * // => ['fred', 'barney', '&', 'pebbles'] + */ + function words(string, pattern, guard) { + string = toString(string); + pattern = guard ? undefined : pattern; + + if (pattern === undefined) { + return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string); + } + return string.match(pattern) || []; + } + + var lodash_camelcase = camelCase; + + /** + * Constants. + */ + + var IS_MAC = typeof window != 'undefined' && /Mac|iPod|iPhone|iPad/.test(window.navigator.platform); + + var MODIFIERS = { + alt: 'altKey', + control: 'ctrlKey', + meta: 'metaKey', + shift: 'shiftKey' + }; + + var ALIASES = { + add: '+', + break: 'pause', + cmd: 'meta', + command: 'meta', + ctl: 'control', + ctrl: 'control', + del: 'delete', + down: 'arrowdown', + esc: 'escape', + ins: 'insert', + left: 'arrowleft', + mod: IS_MAC ? 'meta' : 'control', + opt: 'alt', + option: 'alt', + return: 'enter', + right: 'arrowright', + space: ' ', + spacebar: ' ', + up: 'arrowup', + win: 'meta', + windows: 'meta' + }; + + var CODES = { + backspace: 8, + tab: 9, + enter: 13, + shift: 16, + control: 17, + alt: 18, + pause: 19, + capslock: 20, + escape: 27, + ' ': 32, + pageup: 33, + pagedown: 34, + end: 35, + home: 36, + arrowleft: 37, + arrowup: 38, + arrowright: 39, + arrowdown: 40, + insert: 45, + delete: 46, + meta: 91, + numlock: 144, + scrolllock: 145, + ';': 186, + '=': 187, + ',': 188, + '-': 189, + '.': 190, + '/': 191, + '`': 192, + '[': 219, + '\\': 220, + ']': 221, + '\'': 222 + }; + + for (var f = 1; f < 20; f++) { + CODES['f' + f] = 111 + f; + } + + /** + * Is hotkey? + */ + + function isHotkey(hotkey, options, event) { + if (options && !('byKey' in options)) { + event = options; + options = null; + } + + if (!Array.isArray(hotkey)) { + hotkey = [hotkey]; + } + + var array = hotkey.map(function (string) { + return parseHotkey(string, options); + }); + var check = function check(e) { + return array.some(function (object) { + return compareHotkey(object, e); + }); + }; + var ret = event == null ? check : check(event); + return ret; + } + + function isCodeHotkey(hotkey, event) { + return isHotkey(hotkey, event); + } + + function isKeyHotkey(hotkey, event) { + return isHotkey(hotkey, { byKey: true }, event); + } + + /** + * Parse. + */ + + function parseHotkey(hotkey, options) { + var byKey = options && options.byKey; + var ret = {}; + + // Special case to handle the `+` key since we use it as a separator. + hotkey = hotkey.replace('++', '+add'); + var values = hotkey.split('+'); + var length = values.length; + + // Ensure that all the modifiers are set to false unless the hotkey has them. + + for (var k in MODIFIERS) { + ret[MODIFIERS[k]] = false; + } + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = values[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var value = _step.value; + + var optional = value.endsWith('?') && value.length > 1; + + if (optional) { + value = value.slice(0, -1); + } + + var name = toKeyName(value); + var modifier = MODIFIERS[name]; + + if (value.length > 1 && !modifier && !ALIASES[value] && !CODES[name]) { + throw new TypeError('Unknown modifier: "' + value + '"'); + } + + if (length === 1 || !modifier) { + if (byKey) { + ret.key = name; + } else { + ret.which = toKeyCode(value); + } + } + + if (modifier) { + ret[modifier] = optional ? null : true; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return ret; + } + + /** + * Compare. + */ + + function compareHotkey(object, event) { + for (var key in object) { + var expected = object[key]; + var actual = void 0; + + if (expected == null) { + continue; + } + + if (key === 'key' && event.key != null) { + actual = event.key.toLowerCase(); + } else if (key === 'which') { + actual = expected === 91 && event.which === 93 ? 91 : event.which; + } else { + actual = event[key]; + } + + if (actual == null && expected === false) { + continue; + } + + if (actual !== expected) { + return false; + } + } + + return true; + } + + /** + * Utils. + */ + + function toKeyCode(name) { + name = toKeyName(name); + var code = CODES[name] || name.toUpperCase().charCodeAt(0); + return code; + } + + function toKeyName(name) { + name = name.toLowerCase(); + name = ALIASES[name] || name; + return name; + } + + /** + * Export. + */ + + var _default = isHotkey; + var isHotkey_1 = isHotkey; + var isCodeHotkey_1 = isCodeHotkey; + var isKeyHotkey_1 = isKeyHotkey; + var parseHotkey_1 = parseHotkey; + var compareHotkey_1 = compareHotkey; + var toKeyCode_1 = toKeyCode; + var toKeyName_1 = toKeyName; + + var lib$4 = /*#__PURE__*/Object.defineProperty({ + default: _default, + isHotkey: isHotkey_1, + isCodeHotkey: isCodeHotkey_1, + isKeyHotkey: isKeyHotkey_1, + parseHotkey: parseHotkey_1, + compareHotkey: compareHotkey_1, + toKeyCode: toKeyCode_1, + toKeyName: toKeyName_1 + }, '__esModule', {value: true}); + + /** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + + /** Used as the `TypeError` message for "Functions" methods. */ + var FUNC_ERROR_TEXT = 'Expected a function'; + + /** Used as references for various `Number` constants. */ + var NAN = 0 / 0; + + /** `Object#toString` result references. */ + var symbolTag = '[object Symbol]'; + + /** Used to match leading and trailing whitespace. */ + var reTrim = /^\s+|\s+$/g; + + /** Used to detect bad signed hexadecimal string values. */ + var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + + /** Used to detect binary string values. */ + var reIsBinary = /^0b[01]+$/i; + + /** Used to detect octal string values. */ + var reIsOctal = /^0o[0-7]+$/i; + + /** Built-in method references without a dependency on `root`. */ + var freeParseInt = parseInt; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); + + /** Used for built-in method references. */ + var objectProto = Object.prototype; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString = objectProto.toString; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeMax = Math.max, + nativeMin = Math.min; + + /** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ + var now = function() { + return root.Date.now(); + }; + + /** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed `func` invocations and a `flush` method to immediately invoke them. + * Provide `options` to indicate whether `func` should be invoked on the + * leading and/or trailing edge of the `wait` timeout. The `func` is invoked + * with the last arguments provided to the debounced function. Subsequent + * calls to the debounced function return the result of the last `func` + * invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the debounced function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=false] + * Specify invoking on the leading edge of the timeout. + * @param {number} [options.maxWait] + * The maximum time `func` is allowed to be delayed before it's invoked. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // Avoid costly calculations while the window size is in flux. + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // Invoke `sendMail` when clicked, debouncing subsequent calls. + * jQuery(element).on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. + * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); + * var source = new EventSource('/stream'); + * jQuery(source).on('message', debounced); + * + * // Cancel the trailing debounced invocation. + * jQuery(window).on('popstate', debounced.cancel); + */ + function debounce$1(func, wait, options) { + var lastArgs, + lastThis, + maxWait, + result, + timerId, + lastCallTime, + lastInvokeTime = 0, + leading = false, + maxing = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = toNumber(wait) || 0; + if (isObject(options)) { + leading = !!options.leading; + maxing = 'maxWait' in options; + maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function invokeFunc(time) { + var args = lastArgs, + thisArg = lastThis; + + lastArgs = lastThis = undefined; + lastInvokeTime = time; + result = func.apply(thisArg, args); + return result; + } + + function leadingEdge(time) { + // Reset any `maxWait` timer. + lastInvokeTime = time; + // Start the timer for the trailing edge. + timerId = setTimeout(timerExpired, wait); + // Invoke the leading edge. + return leading ? invokeFunc(time) : result; + } + + function remainingWait(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime, + result = wait - timeSinceLastCall; + + return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result; + } + + function shouldInvoke(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime; + + // Either this is the first call, activity has stopped and we're at the + // trailing edge, the system time has gone backwards and we're treating + // it as the trailing edge, or we've hit the `maxWait` limit. + return (lastCallTime === undefined || (timeSinceLastCall >= wait) || + (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); + } + + function timerExpired() { + var time = now(); + if (shouldInvoke(time)) { + return trailingEdge(time); + } + // Restart the timer. + timerId = setTimeout(timerExpired, remainingWait(time)); + } + + function trailingEdge(time) { + timerId = undefined; + + // Only invoke if we have `lastArgs` which means `func` has been + // debounced at least once. + if (trailing && lastArgs) { + return invokeFunc(time); + } + lastArgs = lastThis = undefined; + return result; + } + + function cancel() { + if (timerId !== undefined) { + clearTimeout(timerId); + } + lastInvokeTime = 0; + lastArgs = lastCallTime = lastThis = timerId = undefined; + } + + function flush() { + return timerId === undefined ? result : trailingEdge(now()); + } + + function debounced() { + var time = now(), + isInvoking = shouldInvoke(time); + + lastArgs = arguments; + lastThis = this; + lastCallTime = time; + + if (isInvoking) { + if (timerId === undefined) { + return leadingEdge(lastCallTime); + } + if (maxing) { + // Handle invocations in a tight loop. + timerId = setTimeout(timerExpired, wait); + return invokeFunc(lastCallTime); + } + } + if (timerId === undefined) { + timerId = setTimeout(timerExpired, wait); + } + return result; + } + debounced.cancel = cancel; + debounced.flush = flush; + return debounced; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && objectToString.call(value) == symbolTag); + } + + /** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ + function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol(value)) { + return NAN; + } + if (isObject(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = isObject(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ''); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); + } + + var lodash_debounce = debounce$1; + + /** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + + var lodash_clonedeep = createCommonjsModule$1(function (module, exports) { + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER = 9007199254740991; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; + + /** Used to detect host constructors (Safari). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = + cloneableTags[boolTag] = cloneableTags[dateTag] = + cloneableTags[float32Tag] = cloneableTags[float64Tag] = + cloneableTags[int8Tag] = cloneableTags[int16Tag] = + cloneableTags[int32Tag] = cloneableTags[mapTag] = + cloneableTags[numberTag] = cloneableTags[objectTag] = + cloneableTags[regexpTag] = cloneableTags[setTag] = + cloneableTags[stringTag] = cloneableTags[symbolTag] = + cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = + cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[weakMapTag] = false; + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); + + /** Detect free variable `exports`. */ + var freeExports = exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; + + /** + * Adds the key-value `pair` to `map`. + * + * @private + * @param {Object} map The map to modify. + * @param {Array} pair The key-value pair to add. + * @returns {Object} Returns `map`. + */ + function addMapEntry(map, pair) { + // Don't return `map.set` because it's not chainable in IE 11. + map.set(pair[0], pair[1]); + return map; + } + + /** + * Adds `value` to `set`. + * + * @private + * @param {Object} set The set to modify. + * @param {*} value The value to add. + * @returns {Object} Returns `set`. + */ + function addSetEntry(set, value) { + // Don't return `set.add` because it's not chainable in IE 11. + set.add(value); + return set; + } + + /** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array ? array.length : 0; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + /** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array ? array.length : 0; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function getValue(object, key) { + return object == null ? undefined : object[key]; + } + + /** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ + function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; + } + + /** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ + function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; + } + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + /** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ + function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; + } + + /** Used for built-in method references. */ + var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto = Object.prototype; + + /** Used to detect overreaching core-js shims. */ + var coreJsData = root['__core-js_shared__']; + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString = objectProto.toString; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Built-in value references. */ + var Buffer = moduleExports ? root.Buffer : undefined, + Symbol = root.Symbol, + Uint8Array = root.Uint8Array, + getPrototype = overArg(Object.getPrototypeOf, Object), + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + splice = arrayProto.splice; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeGetSymbols = Object.getOwnPropertySymbols, + nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, + nativeKeys = overArg(Object.keys, Object); + + /* Built-in method references that are verified to be native. */ + var DataView = getNative(root, 'DataView'), + Map = getNative(root, 'Map'), + Promise = getNative(root, 'Promise'), + Set = getNative(root, 'Set'), + WeakMap = getNative(root, 'WeakMap'), + nativeCreate = getNative(Object, 'create'); + + /** Used to detect maps, sets, and weakmaps. */ + var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + + /** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Hash(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ + function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + } + + /** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(key) { + return this.has(key) && delete this.__data__[key]; + } + + /** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; + } + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas(key) { + var data = this.__data__; + return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); + } + + /** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ + function hashSet(key, value) { + var data = this.__data__; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; + } + + // Add methods to `Hash`. + Hash.prototype.clear = hashClear; + Hash.prototype['delete'] = hashDelete; + Hash.prototype.get = hashGet; + Hash.prototype.has = hashHas; + Hash.prototype.set = hashSet; + + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function ListCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ + function listCacheClear() { + this.__data__ = []; + } + + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + return true; + } + + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; + } + + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; + } + + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ + function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; + } + + // Add methods to `ListCache`. + ListCache.prototype.clear = listCacheClear; + ListCache.prototype['delete'] = listCacheDelete; + ListCache.prototype.get = listCacheGet; + ListCache.prototype.has = listCacheHas; + ListCache.prototype.set = listCacheSet; + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function MapCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapCacheClear() { + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; + } + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapCacheDelete(key) { + return getMapData(this, key)['delete'](key); + } + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapCacheGet(key) { + return getMapData(this, key).get(key); + } + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapCacheHas(key) { + return getMapData(this, key).has(key); + } + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ + function mapCacheSet(key, value) { + getMapData(this, key).set(key, value); + return this; + } + + // Add methods to `MapCache`. + MapCache.prototype.clear = mapCacheClear; + MapCache.prototype['delete'] = mapCacheDelete; + MapCache.prototype.get = mapCacheGet; + MapCache.prototype.has = mapCacheHas; + MapCache.prototype.set = mapCacheSet; + + /** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Stack(entries) { + this.__data__ = new ListCache(entries); + } + + /** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ + function stackClear() { + this.__data__ = new ListCache; + } + + /** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function stackDelete(key) { + return this.__data__['delete'](key); + } + + /** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function stackGet(key) { + return this.__data__.get(key); + } + + /** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function stackHas(key) { + return this.__data__.has(key); + } + + /** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ + function stackSet(key, value) { + var cache = this.__data__; + if (cache instanceof ListCache) { + var pairs = cache.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + return this; + } + cache = this.__data__ = new MapCache(pairs); + } + cache.set(key, value); + return this; + } + + // Add methods to `Stack`. + Stack.prototype.clear = stackClear; + Stack.prototype['delete'] = stackDelete; + Stack.prototype.get = stackGet; + Stack.prototype.has = stackHas; + Stack.prototype.set = stackSet; + + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ + function arrayLikeKeys(value, inherited) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + // Safari 9 makes `arguments.length` enumerable in strict mode. + var result = (isArray(value) || isArguments(value)) + ? baseTimes(value.length, String) + : []; + + var length = result.length, + skipIndexes = !!length; + + for (var key in value) { + if ((inherited || hasOwnProperty.call(value, key)) && + !(skipIndexes && (key == 'length' || isIndex(key, length)))) { + result.push(key); + } + } + return result; + } + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } + } + + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; + } + + /** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); + } + + /** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {boolean} [isFull] Specify a clone including symbols. + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, isFull, customizer, key, object, stack) { + var result; + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + if (isHostObject(value)) { + return object ? value : {}; + } + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + return copySymbols(value, baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, baseClone, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (!isArr) { + var props = isFull ? getAllKeys(value) : keys(value); + } + arrayEach(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack)); + }); + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; + } + + /** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ + function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); + } + + /** + * The base implementation of `getTag`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + return objectToString.call(value); + } + + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); + } + + /** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; + } + + /** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var result = new buffer.constructor(buffer.length); + buffer.copy(result); + return result; + } + + /** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; + } + + /** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ + function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); + } + + /** + * Creates a clone of `map`. + * + * @private + * @param {Object} map The map to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned map. + */ + function cloneMap(map, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map); + return arrayReduce(array, addMapEntry, new map.constructor); + } + + /** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ + function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; + } + + /** + * Creates a clone of `set`. + * + * @private + * @param {Object} set The set to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned set. + */ + function cloneSet(set, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set); + return arrayReduce(array, addSetEntry, new set.constructor); + } + + /** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ + function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; + } + + /** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ + function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); + } + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObject(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; + + assignValue(object, key, newValue === undefined ? source[key] : newValue); + } + return object; + } + + /** + * Copies own symbol properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); + } + + /** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); + } + + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; + } + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; + } + + /** + * Creates an array of the own enumerable symbol properties of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray; + + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + var getTag = baseGetTag; + + // Fallback for data views, maps, sets, and weak maps in IE 11, + // for data views in Edge < 14, and promises in Node.js. + if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map && getTag(new Map) != mapTag) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = objectToString.call(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : undefined; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag; + case mapCtorString: return mapTag; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; + } + + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray(array) { + var length = array.length, + result = array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; + } + + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, cloneFunc, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); + + case mapTag: + return cloneMap(object, isDeep, cloneFunc); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return cloneSet(object, isDeep, cloneFunc); + + case symbolTag: + return cloneSymbol(object); + } + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); + } + + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; + } + + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to process. + * @returns {string} Returns the source code. + */ + function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; + } + + /** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ + function cloneDeep(value) { + return baseClone(value, true, true); + } + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = nativeIsBuffer || stubFalse; + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + + /** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ + function stubArray() { + return []; + } + + /** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ + function stubFalse() { + return false; + } + + module.exports = cloneDeep; + }); + + var hasProperty = function has(object, key) { + return Object.prototype.hasOwnProperty.call(object, key); + }; + + var _apply; + + function _classPrivateFieldLooseBase$8(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; } + + var id$8 = 0; + + function _classPrivateFieldLooseKey$8(name) { return "__private_" + id$8++ + "_" + name; } + + + + function insertReplacement(source, rx, replacement) { + const newParts = []; + source.forEach(chunk => { + // When the source contains multiple placeholders for interpolation, + // we should ignore chunks that are not strings, because those + // can be JSX objects and will be otherwise incorrectly turned into strings. + // Without this condition we’d get this: [object Object] hello [object Object] my