commit 0bb2eb4c3647f18ada49fc94286459f409a79a04 Author: admin <605696661@qq.com> Date: Thu Jul 9 16:31:30 2026 +0800 更新 diff --git a/admin.php b/admin.php new file mode 100644 index 0000000..d63b483 --- /dev/null +++ b/admin.php @@ -0,0 +1,619 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +// 数据库读取现有配置,页面打开自动回填 +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$conn = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($conn, "utf8mb4"); +$res = mysqli_query($conn, "SELECT k,v FROM sys_config"); +$config = []; +while ($row = mysqli_fetch_assoc($res)) { + $config[$row['k']] = $row['v']; +} +mysqli_close($conn); + +// 赋值表单默认值 +$pageTitle = $config['page_title'] ?? "告警监控系统"; +$themeColor = $config['theme_color'] ?? "#409eff"; +$pageSize = $config['page_size'] ?? "20"; +$footerText = $config['footer_text'] ?? ""; +$sidebarLinks = $config['sidebar_links'] ?? ""; +?> + + + + + +系统后台管理 - Advantest 运维告警平台 + + + + + +
+ + + + +
+ +
+
+
+
Advantest
+
系统后台管理面板
+
+
+
+ + + + +
+
+ +
+
系统全局配置管理
+ + +
+
修改登录密码
+
界面外观配置
+
侧边栏外链管理
+
+ + +
+

账户密码修改(BCrypt哈希加密,与登录算法统一)

+
+ + +
+
输入你现在登录的密码用于身份校验
+
+ + +
+
+ + +
+
+ +
+
+
+
+ + +
+

监控大屏界面外观全局配置

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
保存后刷新告警监控大屏dashboard.php即可生效,前端标题、分页、底部文案同步更新
+
+
+
+ + + + + + +
+
+
+ + + + diff --git a/admin.php.1 b/admin.php.1 new file mode 100644 index 0000000..53640f8 --- /dev/null +++ b/admin.php.1 @@ -0,0 +1,203 @@ + + + + + +系统后台管理 Admin + + + +
+

系统后台管理面板

+
+
修改登录密码
+
界面外观配置
+
侧边栏外链管理
+
+ + +
+

账户密码修改(采用bcrypt哈希加密,和历史密码算法统一)

+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+
+ + +
+

大屏界面外观参数配置

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+
+ + + + +
+ 👉 进入开发者调试面板(所有接口可视化调用) +

+ 返回监控告警大屏 +
+
+ + + + diff --git a/admin.php.2 b/admin.php.2 new file mode 100644 index 0000000..fdf49f6 --- /dev/null +++ b/admin.php.2 @@ -0,0 +1,605 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +// 刷新登录计时 +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +// 预加载现有配置,页面打开自动回填表单 +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$conn = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($conn, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} +mysqli_close($conn); + +// 读取已有配置默认值 +$pageTitle = $sysConfig['page_title'] ?? "告警监控系统"; +$themeColor = $sysConfig['theme_color'] ?? "#409eff"; +$pageSize = $sysConfig['page_size'] ?? "20"; +$footerText = $sysConfig['footer_text'] ?? ""; +$sidebarLinks = $sysConfig['sidebar_links'] ?? ""; +?> + + + + + +系统后台管理 - Advantest 爱德万测试运维告警平台 + + + + + +
+ + + + +
+ +
+
+
+
Advantest
+
系统后台管理面板
+
+
+
+ + + + +
+
+ +
+
系统全局配置管理
+ + +
+
修改登录密码
+
界面外观配置
+
侧边栏外链管理
+
+ + +
+

账户密码修改(BCrypt哈希加密,与登录算法统一)

+
+ + +
+
输入你现在登录的密码用于身份校验
+
+ + +
+
+ + +
+
+ +
+
+
+
+ + +
+

监控大屏界面外观全局配置

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
保存后刷新告警监控大屏dashboard.php即可生效
+
+
+
+ + + + + + +
+
+
+ + + + diff --git a/admin.php.3 b/admin.php.3 new file mode 100644 index 0000000..5e18065 --- /dev/null +++ b/admin.php.3 @@ -0,0 +1,625 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +// 刷新登录计时 +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +// 数据库连接读取全局配置,页面打开自动回填 +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$conn = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($conn, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($conn, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} +mysqli_close($conn); + +// 读取配置默认值 +$pageTitle = $sysConfig['page_title'] ?? "告警监控系统"; +$themeColor = $sysConfig['theme_color'] ?? "#409eff"; +$pageSize = $sysConfig['page_size'] ?? "20"; +$footerText = $sysConfig['footer_text'] ?? ""; +$sidebarLinks = $sysConfig['sidebar_links'] ?? ""; +?> + + + + + +系统后台管理 - Advantest 爱德万测试运维告警平台 + + + + + +
+ + + + +
+ +
+
+
+
Advantest
+
系统后台管理面板
+
+
+
+ + + + +
+
+ +
+
系统全局配置管理
+ + +
+
修改登录密码
+
界面外观配置
+
侧边栏外链管理
+
+ + +
+

账户密码修改(BCrypt哈希加密,与登录算法统一)

+
+ + +
+
输入你现在登录的密码用于身份校验
+
+ + +
+
+ + +
+
+ +
+
+
+
+ + +
+

监控大屏界面外观全局配置

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
保存后刷新告警监控大屏dashboard.php即可生效
+
+
+
+ + + + + + +
+
+
+ + + + diff --git a/alert_index.php b/alert_index.php new file mode 100644 index 0000000..cf212fe --- /dev/null +++ b/alert_index.php @@ -0,0 +1,375 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$userName = $_SESSION['user_name'] ?? ''; +$today = date("Y-m-d"); +// Grafana固定看板地址 +$grafanaBase = "http://10.150.117.190:3000/d/linux-server-alert-fix-startsat/linux-fu-wu-qi-gao-jing-zhong-xin?orgId=1&refresh=10s"; +?> + + + + + +告警时序监控面板 + + + + + + +
+
+ + + +
+ + +
+
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + + +
+
+
+ +
+ + +
+
+
+
+ + + + 当前:去重汇总模式 + + +
+
+ + + + + +
+
+ + + + + +
数据加载中...
+
+ +
+
快捷键:Enter快速查询 | ESC关闭弹窗 | Ctrl+F全局搜索
+
+ + + diff --git a/alert_index1.php b/alert_index1.php new file mode 100644 index 0000000..c0772b0 --- /dev/null +++ b/alert_index1.php @@ -0,0 +1,340 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$userName = $_SESSION['user_name'] ?? ''; +$today = date("Y-m-d"); +$grafanaUrl = "http://10.150.117.190:3000"; +?> + + + + + +告警时序监控面板 + + + + + + +
+
+ + +
+ + +
+
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + + +
+
+
+ +
+ + +
+
+
+
+ + + + 当前:去重汇总模式 + + +
+
+ + + + + +
+
+ + + + + +
数据加载中...
+
+ +
+
快捷键:Enter快速查询 | ESC关闭弹窗 | Ctrl+F全局搜索
+
+ + + diff --git a/alert_list.php b/alert_list.php new file mode 100644 index 0000000..94f2785 --- /dev/null +++ b/alert_list.php @@ -0,0 +1,369 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$userName = $_SESSION['user_name'] ?? ''; +$today = date("Y-m-d"); +$grafanaBase = "http://10.150.117.190:3000/d/linux-server-alert-fix-startsat/linux-fu-wu-qi-gao-jing-zhong-xin?orgId=1&refresh=10s"; +?> + + + + + +告警时序监控面板 + + + + + + +
+
+ + +
+ +
+
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + + +
+
+
+ +
+ + +
+
+
+
+ + + + 当前:去重汇总模式 + + +
+
+ + + +
+
+ + + + + +
数据加载中...
+
+ +
+
快捷键:Enter快速查询 | ESC关闭弹窗 | Ctrl+F全局搜索
+
+ + + diff --git a/alert_list.php.1 b/alert_list.php.1 new file mode 100644 index 0000000..6455dd7 --- /dev/null +++ b/alert_list.php.1 @@ -0,0 +1,650 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username'] ?? ""); +$userRole = $_SESSION['role'] ?? "user"; + +// 固定配置 +$grafanaUrl = "http://10.150.117.190:3000"; +$currentLang = "zh"; + +$langMap = [ + 'zh' => [ + 'page_title' => '告警时序监控面板', + 'global_search' => '全局检索(告警/实例/级别)', + 'filter_instance' => '实例IP模糊匹配', + 'start_date' => '起始日期', + 'end_date' => '结束日期', + 'severity_title' => '告警级别', + 'status_title' => '告警状态', + 'btn_query' => '查询', + 'btn_reset' => '重置筛选', + 'btn_detail_mode' => '切换详细模式', + 'tip_distinct' => '当前:去重汇总模式', + 'tip_raw' => '当前:逐条时序模式', + 'stat_total' => '总告警种类', + 'stat_firing' => '触发中', + 'stat_resolved' => '已恢复', + 'stat_critical' => '严重告警', + 'hour_chart_title' => '24小时告警触发趋势', + 'pie_title' => '告警级别分布占比', + 'col_state' => '状态', + 'col_alert' => '告警名称', + 'col_instance' => '实例地址', + 'col_severity' => '级别', + 'col_count' => '当日触发次数', + 'col_time' => '最新触发时间', + 'btn_copy_name' => '复制告警名', + 'btn_copy_link' => '复制筛选链接', + 'btn_export' => '导出CSV报表', + 'btn_refresh_auto' => '60秒自动刷新', + 'modal_title' => '告警完整详情', + 'modal_grafana' => '跳转Grafana大盘', + 'modal_labels' => '全量标签信息', + 'empty_tip' => '暂无匹配告警数据,请调整筛选条件', + 'storm_tip' => '风暴告警', + 'shortcut_tip' => 'Enter快速查询 | ESC关闭弹窗 | Ctrl+F全局搜索' + ] +]; +$t = $langMap[$currentLang]; +$today = date("Y-m-d"); +?> + + + + + +<?php echo $t['page_title']; ?> + + + + + + +
+
+ 返回监控大盘 + +
+ + +
+
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + + +
+
+
+ +
+ + +
+
+
+
+ + + + + + + +
+
+ + + + + +
+
+ + + + + +
Loading...
+
+ +
+
+
+ + + + + + + diff --git a/alert_list.php.bak b/alert_list.php.bak new file mode 100644 index 0000000..dddf1bd --- /dev/null +++ b/alert_list.php.bak @@ -0,0 +1,374 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) $sysConfig[$row['k']] = $row['v']; +mysqli_close($connConfig); +$currentLang = $sysConfig['lang'] ?? "zh"; + +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_title_list' => '告警分页列表', + 'filter_date' => '日期筛选', + 'filter_alert_name' => '告警名称', + 'filter_severity' => '告警级别', + 'filter_status' => '告警状态', + 'btn_search' => '查询', + 'btn_reset' => '重置', + 'page_total' => '共', + 'page_record' => '条记录', + 'page_size' => '每页', + 'page_prev' => '上一页', + 'page_next' => '下一页', + 'page_first' => '首页', + 'page_last' => '末页', + 'empty_no_data' => '暂无告警时序数据', + 'server_fail' => 'Prometheus 接口请求失败', + 'tag' => '状态', + 'alert_name' => '告警指标', + 'instance_addr' => '实例', + 'severity' => '级别', + 'occur_time_group' => '最新触发时间', + 'occur_time_detail' => '触发时间', + 'firing' => '触发', + 'resolved' => '恢复', + 'critical' => '严重', + 'warning' => '警告', + 'info' => '信息', + 'btn_detail' => '详细模式', + 'tip_distinct' => '当前:合并去重(汇总次数)', + 'tip_all' => '当前:详细时序(逐条展示触发时间)', + 'col_count' => '总触发次数' + ], + 'en' => [ + 'html_lang' => 'en', + 'page_title_list' => 'Alert Pagination List', + 'filter_date' => 'Date', + 'filter_alert_name' => 'Metric', + 'filter_severity' => 'Severity', + 'filter_status' => 'Status', + 'btn_search' => 'Search', + 'btn_reset' => 'Reset', + 'page_total' => 'Total ', + 'page_record' => ' records', + 'page_size' => 'Per page', + 'page_prev' => 'Prev', + 'page_next' => 'Next', + 'page_first' => 'First', + 'page_last' => 'Last', + 'empty_no_data' => 'No alert time series data', + 'server_fail' => 'Prometheus API request failed', + 'tag' => 'Status', + 'alert_name' => 'Metric', + 'instance_addr' => 'Instance', + 'severity' => 'Severity', + 'occur_time_group' => 'Last Trigger Time', + 'occur_time_detail' => 'Trigger Time', + 'firing' => 'Firing', + 'resolved' => 'Resolved', + 'critical' => 'Critical', + 'warning' => 'Warning', + 'info' => 'Info', + 'btn_detail' => 'Detail Mode', + 'tip_distinct' => 'Mode: Deduplicated (Total Count)', + 'tip_all' => 'Mode: Raw Time Series (Each Trigger)', + 'col_count' => 'Total Triggers' + ] +]; +$t = $langMap[$currentLang]; +?> + + + + + +<?php echo $t['page_title_list']; ?> + + + + + +
+ 返回监控大屏 +
+ () + 退出登录 +
+
+
+
+
+
+ + +
+
+
+ + + + + + +
+
+ + + + + + + + + +
+
+
Loading...
+
+
+ +
+ + + + diff --git a/alert_subscribe.php b/alert_subscribe.php new file mode 100644 index 0000000..e96e825 --- /dev/null +++ b/alert_subscribe.php @@ -0,0 +1,132 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$userName = $_SESSION['user_name'] ?? ''; +?> + + + + + +告警订阅管理 + + + + + +
+
+ 返回告警监控面板 + +
+
+

告警推送订阅配置

+
+ + +
+
+ + +
可选:critical / warning / info
+
+
+ + +
填写实例片段,为空订阅所有实例告警
+
+
+ + +
只推送包含该名称的告警,为空订阅全部告警
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
说明:配置保存后,符合筛选条件的新增告警将通过配置渠道推送;关闭全局开关则暂停所有推送。
+
+
+ + + diff --git a/api/__pycache__/docker.cpython-36.pyc b/api/__pycache__/docker.cpython-36.pyc new file mode 100644 index 0000000..03f306a Binary files /dev/null and b/api/__pycache__/docker.cpython-36.pyc differ diff --git a/api/api_alert_list.php b/api/api_alert_list.php new file mode 100644 index 0000000..026dcca --- /dev/null +++ b/api/api_alert_list.php @@ -0,0 +1,198 @@ +0)); + exit; +} +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + echo json_encode(array('code'=>401,'msg'=>'登录失效','list'=>array(),'total'=>0,'stat'=>array())); + exit; +} +$_SESSION['login_time'] = time(); + +$promHost = "10.150.117.190"; +$promPort = "9090"; +$promApi = "http://".$promHost.":".$promPort."/api/v1"; + +// 修复低版本PHP不支持 ?? 运算符,改用三元判断 +$page = isset($_REQUEST['page']) ? (int)$_REQUEST['page'] : 1; +$pageSize = isset($_REQUEST['page_size']) ? (int)$_REQUEST['page_size'] : 20; +$startDate = isset($_REQUEST['start_date']) ? $_REQUEST['start_date'] : ""; +$endDate = isset($_REQUEST['end_date']) ? $_REQUEST['end_date'] : ""; +$filterMetric = isset($_REQUEST['metric']) ? trim($_REQUEST['metric']) : ""; +$filterInstance = isset($_REQUEST['instance']) ? trim($_REQUEST['instance']) : ""; +$filterGlobal = isset($_REQUEST['global']) ? trim($_REQUEST['global']) : ""; +$distinct = isset($_REQUEST['distinct']) ? (int)$_REQUEST['distinct'] : 1; +$filterSeverity = isset($_REQUEST['severity']) ? $_REQUEST['severity'] : array(); +$filterStatus = isset($_REQUEST['status']) ? $_REQUEST['status'] : array(); +$isExport = (isset($_REQUEST['export']) && $_REQUEST['export'] == 1) ? 1 : 0; + +$startTs = 0; +$endTs = 0; +if (!empty($startDate) && !empty($endDate)) { + $startTs = strtotime($startDate); + $endTs = strtotime($endDate . " 23:59:59"); +} else { + $today = date("Y-m-d"); + $startTs = strtotime($today); + $endTs = strtotime($today . " 23:59:59"); +} + +$promQL = 'sort_desc(ALERTS)'; +$params = array('query' => $promQL); +$params['start'] = $startTs; +$params['end'] = $endTs; +$params['step'] = 60; +$queryUrl = $promApi . "/query_range"; +$url = $queryUrl . "?" . http_build_query($params); + +$ch = curl_init($url); +curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); +curl_setopt($ch, CURLOPT_TIMEOUT, 10); +$resp = curl_exec($ch); +$err = curl_error($ch); +$code = curl_getinfo($ch, CURLINFO_HTTP_CODE); +curl_close($ch); + +if (!empty($err) || empty($resp)) { + echo json_encode(array( + 'code' => 500, + 'msg' => 'Prometheus连接失败:' . $err, + 'list' => array(), + 'total' => 0, + 'stat' => array() + )); + exit; +} +$promData = json_decode($resp, true); +if (!isset($promData['status']) || $promData['status'] !== 'success') { + echo json_encode(array( + 'code' => 500, + 'msg' => 'Prometheus查询异常:'.$resp, + 'list' => array(), + 'total' => 0, + 'stat' => array() + )); + exit; +} + +$rawAll = array(); +$hourCount = array(); +for ($h = 0; $h < 24; $h++){ + $hourCount[$h] = 0; +} +if (!empty($promData['data']['result'])) { + foreach ($promData['data']['result'] as $item) { + $metric = $item['metric']; + $state = isset($metric['alertstate']) ? $metric['alertstate'] : ""; + $sev = isset($metric['severity']) ? $metric['severity'] : "info"; + $alertName = isset($metric['alertname']) ? $metric['alertname'] : ""; + $inst = isset($metric['instance']) ? $metric['instance'] : ""; + $values = isset($item['values']) ? $item['values'] : array(); + foreach ($values as $v) { + $ts = (int)$v[0]; + $dt = date("Y-m-d H:i:s", $ts); + $hour = date("G", $ts); + $hourCount[$hour]++; + $rawAll[] = array( + 'state' => $state, + 'severity' => $sev, + 'metric' => $alertName, + 'instance' => $inst, + 'time' => $dt, + 'timestamp' => $ts, + 'labels' => $metric + ); + } + } +} + +$filterFunc = function ($row) use ($filterMetric, $filterInstance, $filterGlobal, $filterSeverity, $filterStatus) { + if (!empty($filterGlobal)) { + $g = strtolower($filterGlobal); + $match = (stripos(strtolower($row['metric']), $g) !== false) + || (stripos(strtolower($row['instance']), $g) !== false) + || (stripos(strtolower($row['severity']), $g) !== false); + if (!$match) return false; + } + if (!empty($filterMetric) && stripos($row['metric'], $filterMetric) === false) return false; + if (!empty($filterInstance) && stripos($row['instance'], $filterInstance) === false) return false; + if (!empty($filterSeverity) && !in_array($row['severity'], $filterSeverity)) return false; + if (!empty($filterStatus) && !in_array($row['state'], $filterStatus)) return false; + return true; +}; +$rawAll = array_filter($rawAll, $filterFunc); +usort($rawAll, function($a, $b){ + return $b['timestamp'] - $a['timestamp']; +}); + +$listRaw = array(); +$stat = array( + 'total_all' => count($rawAll), + 'total_firing' => 0, + 'total_resolved' => 0, + 'total_critical' => 0, + 'unique_count' => 0, + 'hour_data' => $hourCount +); +if ($distinct !== 1) { + $listRaw = $rawAll; + foreach ($rawAll as $r) { + if ($r['state'] == 'firing') $stat['total_firing']++; + else $stat['total_resolved']++; + if ($r['severity'] == 'critical') $stat['total_critical']++; + } +} else { + $group = array(); + foreach ($rawAll as $row) { + $key = md5($row['metric'] . "|" . $row['instance'] . "|" . $row['severity'] . "|" . $row['state']); + if (!isset($group[$key])) { + $group[$key] = array( + 'state' => $row['state'], + 'severity' => $row['severity'], + 'metric' => $row['metric'], + 'instance' => $row['instance'], + 'time' => $row['time'], + 'timestamp' => $row['timestamp'], + 'total_count' => 1, + 'labels' => $row['labels'] + ); + } else { + $group[$key]['total_count']++; + if ($row['timestamp'] > $group[$key]['timestamp']) { + $group[$key]['time'] = $row['time']; + $group[$key]['timestamp'] = $row['timestamp']; + } + } + } + $listRaw = array_values($group); + $stat['unique_count'] = count($listRaw); + foreach ($listRaw as $r) { + if ($r['state'] == 'firing') $stat['total_firing']++; + else $stat['total_resolved']++; + if ($r['severity'] == 'critical') $stat['total_critical']++; + } +} + +$total = count($listRaw); +if ($isExport) { + $pageData = $listRaw; +} else { + $offset = ($page - 1) * $pageSize; + $pageData = array_slice($listRaw, $offset, $pageSize); +} + +echo json_encode(array( + 'code' => 0, + 'msg' => 'ok', + 'total' => $total, + 'stat' => $stat, + 'list' => $pageData +), JSON_UNESCAPED_UNICODE); +exit; +?> diff --git a/api/api_alert_list.php.bak b/api/api_alert_list.php.bak new file mode 100644 index 0000000..4f8cfa7 --- /dev/null +++ b/api/api_alert_list.php.bak @@ -0,0 +1,143 @@ +0])); + +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + exit(json_encode(['code'=>401,'msg'=>'登录失效','list'=>[],'total'=>0])); +} +$_SESSION['login_time'] = time(); + +$promHost = "10.150.117.190"; +$promPort = "9090"; +$promApi = "http://{$promHost}:{$promPort}/api/v1"; + +$page = (int)($_REQUEST['page'] ?? 1); +$pageSize = (int)($_REQUEST['page_size'] ?? 20); +$filterDate = $_REQUEST['date'] ?? ""; +$filterMetric = trim($_REQUEST['metric'] ?? ""); +$filterSeverity = $_REQUEST['severity'] ?? ""; +$filterStatus = $_REQUEST['status'] ?? ""; +$distinct = (int)($_REQUEST['distinct'] ?? 1); + +$promQL = 'sort_desc(ALERTS)'; +$params = ['query' => $promQL]; +if (!empty($filterDate)) { + $end = strtotime($filterDate . " 23:59:59"); + $start = $end - 86400; + $params['start'] = $start; + $params['end'] = $end; + $params['step'] = 60; + $queryUrl = $promApi . "/query_range"; +} else { + $queryUrl = $promApi . "/query"; +} + +$url = $queryUrl . "?" . http_build_query($params); +$ch = curl_init($url); +curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); +curl_setopt($ch, CURLOPT_TIMEOUT, 10); +$resp = curl_exec($ch); +$err = curl_error($ch); +curl_close($ch); + +if (!empty($err) || empty($resp)) { + exit(json_encode([ + 'code' => 500, + 'msg' => 'Prometheus连接失败:'.$err, + 'list' => [], + 'total' => 0 + ])); +} +$promData = json_decode($resp, true); +if ($promData['status'] !== 'success') { + exit(json_encode([ + 'code' => 500, + 'msg' => 'Prometheus查询异常', + 'list' => [], + 'total' => 0 + ])); +} + +$rawAll = []; +if (!empty($promData['data']['result'])) { + foreach ($promData['data']['result'] as $item) { + $metric = $item['metric']; + $state = $metric['alertstate'] ?? ""; + $sev = $metric['severity'] ?? "info"; + $alertName = $metric['alertname'] ?? ""; + $inst = $metric['instance'] ?? ""; + $values = $item['values'] ?? []; + foreach ($values as $v) { + $ts = (int)$v[0]; + $dt = date("Y-m-d H:i:s", $ts); + $rawAll[] = [ + 'state' => $state, + 'severity' => $sev, + 'metric' => $alertName, + 'instance' => $inst, + 'time' => $dt, + 'timestamp' => $ts + ]; + } + } +} + +// ==========修复过滤逻辑========== +if (!empty($filterMetric)) { + $rawAll = array_filter($rawAll, function($r) use ($filterMetric){ + return stripos($r['metric'], $filterMetric) !== false; + }); +} +if (!empty($filterSeverity)) { + $rawAll = array_filter($rawAll, fn($r) => $r['severity'] === $filterSeverity); +} +if (!empty($filterStatus)) { + $rawAll = array_filter($rawAll, fn($r) => $r['state'] === $filterStatus); +} + +usort($rawAll, fn($a,$b) => $b['timestamp'] - $a['timestamp']); + +if ($distinct !== 1) { + $list = $rawAll; +} else { + $group = []; + foreach ($rawAll as $row) { + $key = md5($row['metric'] . "|" . $row['instance'] . "|" . $row['severity'] . "|" . $row['state']); + if (!isset($group[$key])) { + $group[$key] = [ + 'state' => $row['state'], + 'severity' => $row['severity'], + 'metric' => $row['metric'], + 'instance' => $row['instance'], + 'time' => $row['time'], + 'timestamp' => $row['timestamp'], + 'total_count' => 1 + ]; + } else { + $group[$key]['total_count']++; + if ($row['timestamp'] > $group[$key]['timestamp']) { + $group[$key]['time'] = $row['time']; + $group[$key]['timestamp'] = $row['timestamp']; + } + } + } + $list = array_values($group); +} + +$total = count($list); +$offset = ($page - 1) * $pageSize; +$pageData = array_slice($list, $offset, $pageSize); + +echo json_encode([ + 'code' => 0, + 'msg' => 'ok', + 'total' => $total, + 'list' => $pageData +], JSON_UNESCAPED_UNICODE); +exit; +?> diff --git a/api/config_save.php b/api/config_save.php new file mode 100644 index 0000000..3f10c4b --- /dev/null +++ b/api/config_save.php @@ -0,0 +1,40 @@ + $expire)) { + echo json_encode(["code"=>401,"msg"=>"未登录"]); + exit; +} +header("Content-Type:application/json;charset=utf-8"); +$configFile = "./system_config.json"; +if(!file_exists($configFile)){ + echo json_encode(["code"=>500,"msg"=>"配置文件缺失"]); + exit; +} +$config = json_decode(file_get_contents($configFile),true); +$act = $_POST['act'] ?? ''; + +if($act == "save_style"){ + $config['theme_color'] = $_POST['theme_color']; + $config['card_bg'] = $_POST['card_bg']; + $config['body_bg'] = $_POST['body_bg']; + $config['font_family'] = $_POST['font_family']; + file_put_contents($configFile,json_encode($config,JSON_UNESCAPED_UNICODE)); + echo json_encode(["code"=>0,"msg"=>"样式保存成功,刷新页面生效"]); + exit; +} + +if($act == "save_sidebar_link"){ + $list = json_decode($_POST['link_list'],true); + $config['sidebar_links'] = $list; + file_put_contents($configFile,json_encode($config,JSON_UNESCAPED_UNICODE)); + echo json_encode(["code"=>0,"msg"=>"侧边栏链接更新成功"]); + exit; +} + +if($act == "get_config"){ + echo json_encode(["code"=>0,"data"=>$config]); + exit; +} +echo json_encode(["code"=>400,"msg"=>"非法操作"]); +?> diff --git a/api/debug.php b/api/debug.php new file mode 100644 index 0000000..ba1952f --- /dev/null +++ b/api/debug.php @@ -0,0 +1,3 @@ +200,"msg"=>"PHP正常,mysqli已加载"]); diff --git a/api/dev_panel.php b/api/dev_panel.php new file mode 100644 index 0000000..4537a96 --- /dev/null +++ b/api/dev_panel.php @@ -0,0 +1,205 @@ + + + + + +开发者模式 - 接口可视化调试面板 + + + +
+

开发者调试面板 | 全部告警接口可视化调用

+ ← 返回系统后台管理页 + + +
+

1. 临时隐藏单实例告警 clear_single_instance

+
+ + + + + +
+
仅插入恢复日志,下次故障自动重新展示;冒号自动编码无需手动处理
+
+ + +
+

2. 永久屏蔽单实例 offline_single_instance

+
+ + + + + +
+
修改monitor_rule状态0,不恢复永远不告警
+
+ + +
+

3. 恢复单实例 restore_single_instance

+
+ + + + + +
+
+ + +
+

4. 整条规则全部下线 clear_offline_rule

+
+ + + +
+
+ + +
+

5. 恢复整条规则 restore_rule

+
+ + + +
+
+ + +
+

6. 删除单实例所有告警日志 delete_single_instance_log

+
+ + + + + +
+
+ + +
+

7. 手动同步Prometheus告警(清除脏恢复记录)

+
+ +
+
自动删除故障中残留的手动恢复记录,修复前端不显示告警bug
+
+ + +
+

8. 数据查询接口(查看面板原始数据)

+
+ + + + +
+
+ + +
+

9. 导出今日告警CSV报表

+
+ +
+
+ + +
+

接口返回结果(JSON)

+
等待操作...
+
+
+ + + + diff --git a/api/dev_panel.php.2 b/api/dev_panel.php.2 new file mode 100644 index 0000000..5483cf1 --- /dev/null +++ b/api/dev_panel.php.2 @@ -0,0 +1,411 @@ + $expire)) { + session_destroy(); + header("Location: ../login.php"); + exit; +} +// 刷新登录时间 +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; +?> + + + + + +开发者调试面板 - Advantest 运维告警监控平台 + + + + + + +
+
+
+
开发者调试面板
+
全部告警接口可视化调用 · 后端API调试工具
+
+
+
+ + + + +
+
+ +
+ +
+

1. 临时隐藏单实例告警 clear_single_instance

+
+ + + + + +
+
仅插入恢复日志,下次故障自动重新展示;instance冒号无需手动编码,JS自动处理
+
+ + +
+

2. 永久屏蔽单实例 offline_single_instance

+
+ + + + + +
+
修改monitor_rule状态0,不执行恢复接口则永久不展示该实例告警
+
+ + +
+

3. 恢复单实例 restore_single_instance

+
+ + + + + +
+
解除单实例永久屏蔽状态,新故障会正常展示
+
+ + +
+

4. 整条规则全部下线 clear_offline_rule

+
+ + + +
+
+ + +
+

5. 恢复整条规则 restore_rule

+
+ + + +
+
+ + +
+

6. 删除单实例所有告警日志 delete_single_instance_log

+
+ + + + + +
+
+ + +
+

7. 手动同步Prometheus告警(清除脏恢复记录)

+
+ +
+
自动删除故障中残留的手动恢复记录,修复前端“故障存在但页面不显示”bug
+
+ + +
+

8. 数据查询接口(获取面板原始数据)

+
+ + + + +
+
+ + +
+

9. 导出告警CSV报表(支持历史日期)

+
+ + + +
+
不选择日期默认导出今日告警;选择历史日期可下载过往报表
+
+ + +
+

接口返回结果(JSON)

+
等待执行接口操作...
+
+
+ + + + diff --git a/api/df.php b/api/df.php new file mode 100644 index 0000000..e763e41 --- /dev/null +++ b/api/df.php @@ -0,0 +1,60 @@ + $expire)) { + session_destroy(); + header("Content-Type:application/json;charset=utf-8"); + echo json_encode(["code"=>401,"msg"=>"未登录,请前往登录页面"],JSON_UNESCAPED_UNICODE); + exit; +} +header("Content-Type:application/json; charset=utf-8"); + +$promAddr = "http://10.150.117.190:9090"; +$gbUnit = 1073741824; +$promQuery = urlencode('node_directory_size_bytes'); +$apiUrl = "{$promAddr}/api/v1/query?query={$promQuery}"; + +// 改用curl,不依赖allow_url_fopen +$ch = curl_init($apiUrl); +curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); +curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); +curl_setopt($ch, CURLOPT_TIMEOUT, 10); +$resp = curl_exec($ch); +$curlErr = curl_error($ch); +curl_close($ch); + +if(!$resp || !empty($curlErr)){ + echo json_encode(["code"=>500,"msg"=>"无法连接Prometheus:".$curlErr],JSON_UNESCAPED_UNICODE); + exit; +} +$raw = json_decode($resp, true); + +$allData = []; +if ($raw['status'] === 'success' && !empty($raw['data']['result'])) { + foreach ($raw['data']['result'] as $item) { + $dir = $item['metric']['directory']; + $instanceIp = $item['metric']['instance']; + $instanceIp = explode(':', $instanceIp)[0]; + $userName = basename($dir); + $byteNum = floatval($item['value'][1]); + $gbNum = round($byteNum / $gbUnit, 2); + + $allData[] = [ + "instance_ip" => $instanceIp, + "username" => $userName, + "directory" => $dir, + "size_gb" => $gbNum + ]; + } + usort($allData, function ($a, $b) { + return $b['size_gb'] <=> $a['size_gb']; + }); +} + +echo json_encode([ + "code" => 0, + "msg" => "查询成功", + "list" => $allData +], JSON_UNESCAPED_UNICODE); +exit; +?> diff --git a/api/df.php.bak b/api/df.php.bak new file mode 100644 index 0000000..325662c --- /dev/null +++ b/api/df.php.bak @@ -0,0 +1,51 @@ + $expire)) { + session_destroy(); + header("Content-Type:application/json;charset=utf-8"); + echo json_encode(["code"=>401,"msg"=>"未登录,请前往登录页面"],JSON_UNESCAPED_UNICODE); + exit; +} +header("Content-Type:application/json; charset=utf-8"); + +$promAddr = "http://10.150.117.190:9090"; +$gbUnit = 1073741824; +$promQuery = urlencode('node_directory_size_bytes'); +$apiUrl = "{$promAddr}/api/v1/query?query={$promQuery}"; +$resp = @file_get_contents($apiUrl); +if(!$resp){ + echo json_encode(["code"=>500,"msg"=>"无法连接Prometheus"],JSON_UNESCAPED_UNICODE); + exit; +} +$raw = json_decode($resp, true); + +$allData = []; +if ($raw['status'] === 'success' && !empty($raw['data']['result'])) { + foreach ($raw['data']['result'] as $item) { + $dir = $item['metric']['directory']; + $instanceIp = $item['metric']['instance']; + $instanceIp = explode(':', $instanceIp)[0]; + $userName = basename($dir); + $byteNum = floatval($item['value'][1]); + $gbNum = round($byteNum / $gbUnit, 2); + + $allData[] = [ + "instance_ip" => $instanceIp, + "username" => $userName, + "directory" => $dir, + "size_gb" => $gbNum + ]; + } + usort($allData, function ($a, $b) { + return $b['size_gb'] <=> $a['size_gb']; + }); +} + +echo json_encode([ + "code" => 0, + "msg" => "查询成功", + "list" => $allData +], JSON_UNESCAPED_UNICODE); +exit; +?> diff --git a/api/docker.php b/api/docker.php new file mode 100644 index 0000000..607471d --- /dev/null +++ b/api/docker.php @@ -0,0 +1,165 @@ + session_id(), + "session_data" => $_SESSION +]; + +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + session_destroy(); + echo json_encode([ + "code"=>401, + "msg"=>"未登录", + "debug"=>$debug + ],JSON_UNESCAPED_UNICODE); + exit; +} + +$user = $_SESSION['user_id']; +$role = $_SESSION['role']; +$ts = time(); +$rawSignStr = $user . "|" . $role . "|" . $ts; +$sign = hash_hmac("sha256", $rawSignStr, $SECRET_RAW); +$clientIp = $_SERVER['REMOTE_ADDR']; + +$act = $_POST['act'] ?? $_GET['act'] ?? 'list'; +$cid = $_POST['container_id'] ?? $_GET['container_id'] ?? ''; +$imageId = $_POST['image_id'] ?? $_GET['image_id'] ?? ''; +$lines = $_POST['lines'] ?? $_GET['lines'] ?? 200; +$postRaw = file_get_contents("php://input"); +$apiBase = "http://10.150.117.190:8090"; + +$authHeaders = [ + "X-User: {$user}", + "X-Role: {$role}", + "X-Time: {$ts}", + "X-Sign: {$sign}", + "X-Client-Ip: {$clientIp}", + "Content-Type: application/json; charset=utf-8" +]; +$headerStr = implode("\r\n", $authHeaders); + +$getMap = [ + 'list' => '/list', + 'image_list' => '/image_list', + 'restart' => '/restart/%s', + 'stop' => '/stop/%s', + 'rm' => '/rm/%s', + 'remove_image' => '/remove_image/%s', + 'logs' => '/logs/%s/%d', + 'network' => '/network/%s', + 'stats' => '/stats/%s', + 'detail' => '/detail/%s' +]; + +$postMap = [ + 'exec' => '/exec/%s', + 'create' => '/create', + 'bind_repo' => '/bind_repo', +]; + +if (isset($getMap[$act])) { + $path = $getMap[$act]; + $url = ''; + switch ($act) { + case 'restart': + case 'stop': + case 'rm': + case 'network': + case 'stats': + case 'detail': + if (empty($cid)) { + echo json_encode(["code"=>400,"msg"=>"缺少容器ID","debug"=>$debug],JSON_UNESCAPED_UNICODE); + exit; + } + $url = $apiBase . sprintf($path, urlencode($cid)); + break; + case 'remove_image': + if (empty($imageId)) { + echo json_encode(["code"=>400,"msg"=>"缺少镜像ID","debug"=>$debug],JSON_UNESCAPED_UNICODE); + exit; + } + $url = $apiBase . sprintf($path, urlencode($imageId)); + break; + case 'logs': + if (empty($cid)) { + echo json_encode(["code"=>400,"msg"=>"缺少容器ID","debug"=>$debug],JSON_UNESCAPED_UNICODE); + exit; + } + $url = $apiBase . sprintf($path, urlencode($cid), (int)$lines); + break; + default: + $url = $apiBase . $path; + break; + } + $ctx = stream_context_create([ + 'http' => [ + 'method' => 'GET', + 'header' => $headerStr, + 'timeout' => 30 + ] + ]); + $resp = @file_get_contents($url, false, $ctx); + if ($resp === false) { + echo json_encode([ + "code" => 503, + "msg" => "后端Docker接口连接失败,请检查服务是否启动", + "debug" => $debug + ], JSON_UNESCAPED_UNICODE); + exit; + } + echo $resp; + exit; +} + +if (isset($postMap[$act])) { + $path = $postMap[$act]; + $url = ''; + if ($act === 'exec') { + if (empty($cid)) { + echo json_encode(["code"=>400,"msg"=>"缺少容器ID","debug"=>$debug],JSON_UNESCAPED_UNICODE); + exit; + } + $url = $apiBase . sprintf($path, urlencode($cid)); + } else { + $url = $apiBase . $path; + } + $ctx = stream_context_create([ + 'http' => [ + 'method' => 'POST', + 'header' => $headerStr, + 'content' => $postRaw, + 'timeout' => 30 + ] + ]); + $resp = @file_get_contents($url, false, $ctx); + if ($resp === false) { + echo json_encode([ + "code" => 503, + "msg" => "后端Docker接口连接失败,请检查服务是否启动", + "debug" => $debug + ], JSON_UNESCAPED_UNICODE); + exit; + } + echo $resp; + exit; +} + +echo json_encode([ + "code"=>400, + "msg"=>"无效操作act参数", + "debug"=>$debug +],JSON_UNESCAPED_UNICODE); +exit; diff --git a/api/docker_api.py b/api/docker_api.py new file mode 100644 index 0000000..c925759 --- /dev/null +++ b/api/docker_api.py @@ -0,0 +1,752 @@ +import json +import shlex +import time +import hashlib +import hmac +import docker +from flask import Flask, jsonify, request +from flask_socketio import SocketIO + +# 全局签名密钥,前后端统一,生产环境使用环境变量注入 +SIGN_SECRET = b"DockerAdminPlatform2026SecretKey123456789" +# 签名有效期 300秒(5分钟) +SIGN_EXPIRE = 300 + +# 兼容新旧docker-py客户端 +try: + cli = docker.DockerClient(base_url='unix:///var/run/docker.sock') + api_cli = docker.APIClient(base_url='unix:///var/run/docker.sock') +except AttributeError: + cli = docker.Client(base_url='unix:///var/run/docker.sock') + api_cli = docker.APIClient(base_url='unix:///var/run/docker.sock') + +app = Flask(__name__) +app.config['SECRET_KEY'] = 'docker-terminal-secret-2026' + +# WebSocket心跳保活,防止Nginx/反向代理断连 +socketio = SocketIO( + app, + cors_allowed_origins="*", + async_mode="threading", + ping_timeout=60, + ping_interval=25 +) + +# 全局会话存储 +session_exec_map = {} # sid => TTY终端流信息 +log_task_map = {} # sid => {"cid": "", "running": True} +ws_user_map = {} # 新增:sid 映射 WebSocket鉴权用户信息 +registry_config = { + "repo_name": "", + "repo_addr": "", + "repo_user": "", + "repo_pwd": "" +} +# 多系统shell兼容列表(Ubuntu/Alpine/标准Linux) +SHELL_CANDIDATES = [ + "/bin/bash", + "/usr/bin/bash", + "/bin/sh", + "/bin/ash" +] + +# ===================== 工具函数1:docker socket兼容recv ===================== +def docker_recv(sock, size=1024): + try: + return sock.recv(size) + except Exception: + try: + return sock._sock.recv(size) + except Exception: + return b"" + +# ===================== 工具函数2:操作审计日志(终端输入脱敏,不存明文密码) ===================== +def write_audit_log(user, role, action, target_name, target_id, result, client_ip): + """企业审计记录,可对接数据库docker_audit_log表""" + # 终端输入仅标记事件,不记录明文命令,规避密码泄露风险 + if action == "terminal_input": + result = "command_entered" + log_item = { + "timestamp": time.strftime("%Y-%m-%d %H:%M:%S"), + "user": user, + "role": role, + "action": action, + "container_name": target_name, + "container_id": target_id, + "result": result, + "client_ip": client_ip + } + # 生产环境替换为mysql insert语句 + print(json.dumps(log_item, ensure_ascii=False)) + +# ===================== 工具函数3:HTTP Header HMAC签名鉴权(原有,HTTP接口专用) ===================== +def verify_auth_sign(): + """ + 校验前端PHP生成的HMAC签名,防止伪造X-Role:admin + 请求Header要求: + X-User: 用户名 + X-Role: admin/user/guest + X-Time: 当前时间戳(秒) + X-Sign: hmac-sha256签名 + 返回 (user, role, client_ip, True/False) + """ + user = request.headers.get("X-User", "anonymous") + role = request.headers.get("X-Role", "guest") + ts_str = request.headers.get("X-Time", "0") + sign = request.headers.get("X-Sign", "") + client_ip = request.headers.get("X-Client-Ip", request.remote_addr) + try: + ts = int(ts_str) + except ValueError: + return user, role, client_ip, False + # 校验签名有效期 + now = int(time.time()) + if abs(now - ts) > SIGN_EXPIRE: + return user, role, client_ip, False + # 校验HMAC签名 + raw_data = f"{user}|{role}|{ts}".encode("utf-8") + calc_sign = hmac.new(SIGN_SECRET, raw_data, hashlib.sha256).hexdigest() + if calc_sign != sign: + return user, role, client_ip, False + return user, role, client_ip, True + +# ===================== 新增工具函数4:WebSocket连接专用鉴权函数 ===================== +def verify_socket_auth(auth): + user = auth.get("user", "") + role = auth.get("role", "") + ts_str = auth.get("ts", "0") + sign = auth.get("sign", "") + try: + ts = int(ts_str) + except: + return user, role, "", False + if abs(int(time.time()) - ts) > SIGN_EXPIRE: + return user, role, "", False + raw_data = f"{user}|{role}|{ts}".encode("utf-8") + calc_sign = hmac.new( + SIGN_SECRET, + raw_data, + hashlib.sha256 + ).hexdigest() + if calc_sign != sign: + return user, role, "", False + return user, role, "", True + +# ===================== 工具函数5:环境变量脱敏,屏蔽密码/密钥 ===================== +def safe_env_filter(env_list): + safe_env = [] + sensitive_keywords = ["PASS", "PASSWORD", "TOKEN", "SECRET", "KEY", "CREDENTIAL"] + for item in env_list: + equal_pos = item.find("=") + if equal_pos == -1: + safe_env.append(item) + continue + key = item[:equal_pos] + val = item[equal_pos+1:] + if any(word in key.upper() for word in sensitive_keywords): + safe_env.append(f"{key}=******") + else: + safe_env.append(item) + return safe_env + +# ===================== 全部HTTP业务接口 ===================== +# 1. 容器列表(端口预拼接字符串,前端直接渲染,无需formatPorts) +@app.route("/list") +def api_list(): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "list_container", "", "", "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + arr = [] + for c in cli.containers.list(all=True): + img_name = c.image.tags[0] if c.image.tags else "" + port_str_arr = [] + ports_raw = c.ports + for c_port, host_list in ports_raw.items(): + if not host_list: + continue + for host_item in host_list: + host_port = host_item.get("HostPort", "") + port_str_arr.append(f"{host_port}:{c_port.split('/')[0]}") + port_display = ",".join(port_str_arr) if port_str_arr else "-" + arr.append({ + "id": c.short_id, + "full_id": c.id, + "name": c.name, + "image": img_name, + "status": c.status, + "ports": port_display + }) + write_audit_log(user, role, "list_container", "", "", "success", ip) + return jsonify({"code":0,"msg":"success","list":arr}) + +# 2. 镜像列表 +@app.route("/image_list") +def api_image_list(): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "list_image", "", "", "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + arr = [] + for img in cli.images.list(): + if not img.tags: + continue + full_tag = img.tags[0] + repo, tag = full_tag.split(":", 1) + size_mb = round(img.attrs["Size"] / 1024 / 1024, 1) + arr.append({ + "repo": repo, + "tag": tag, + "id": img.short_id, + "full_id": img.id, + "size": f"{size_mb}MB", + "created": img.attrs["Created"] + }) + write_audit_log(user, role, "list_image", "", "", "success", ip) + return jsonify({"code":0,"msg":"success","list":arr}) + +# 3. 删除镜像 +@app.route("/remove_image/") +def api_remove_image(image_id): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "remove_image", "", image_id, "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + if role != "admin": + write_audit_log(user, role, "remove_image", "", image_id, "denied", ip) + return jsonify({"code":403,"msg":"权限不足,仅管理员可删除镜像"}) + try: + img = cli.images.get(image_id) + cli.images.remove(image_id, force=True) + write_audit_log(user, role, "remove_image", img.tags[0] if img.tags else "", image_id, "success", ip) + return jsonify({"code":0,"msg":"镜像已强制删除"}) + except Exception as e: + write_audit_log(user, role, "remove_image", "", image_id, f"fail:{str(e)}", ip) + return jsonify({"code":500,"msg":str(e)}) + +# 4. 重启容器 +@app.route("/restart/") +def api_restart(cid): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "restart", "", cid, "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + if role != "admin": + write_audit_log(user, role, "restart", "", cid, "denied", ip) + return jsonify({"code":403,"msg":"权限不足,仅管理员可操作容器"}) + try: + container = cli.containers.get(cid) + container.restart() + write_audit_log(user, role, "restart", container.name, cid, "success", ip) + return jsonify({"code":0,"msg":"容器已重启"}) + except Exception as e: + write_audit_log(user, role, "restart", "", cid, f"fail:{str(e)}", ip) + return jsonify({"code":500,"msg":str(e)}) + +# 5. 停止容器 +@app.route("/stop/") +def api_stop(cid): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "stop", "", cid, "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + if role != "admin": + write_audit_log(user, role, "stop", "", cid, "denied", ip) + return jsonify({"code":403,"msg":"权限不足,仅管理员可操作容器"}) + try: + container = cli.containers.get(cid) + container.stop() + write_audit_log(user, role, "stop", container.name, cid, "success", ip) + return jsonify({"code":0,"msg":"容器已停止"}) + except Exception as e: + write_audit_log(user, role, "stop", "", cid, f"fail:{str(e)}", ip) + return jsonify({"code":500,"msg":str(e)}) + +# 6. 删除容器 +@app.route("/rm/") +def api_rm(cid): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "rm", "", cid, "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + if role != "admin": + write_audit_log(user, role, "rm", "", cid, "denied", ip) + return jsonify({"code":403,"msg":"权限不足,仅管理员可删除容器"}) + try: + container = cli.containers.get(cid) + container.remove(force=True) + write_audit_log(user, role, "rm", container.name, cid, "success", ip) + return jsonify({"code":0,"msg":"容器已强制删除"}) + except Exception as e: + write_audit_log(user, role, "rm", "", cid, f"fail:{str(e)}", ip) + return jsonify({"code":500,"msg":str(e)}) + +# 7. 一次性拉取日志(兼容旧页面单次查看) +@app.route("/logs//") +def api_logs(cid, tail_lines): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "read_log", "", cid, "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + try: + container = cli.containers.get(cid) + log_bytes = container.logs(tail=tail_lines) + log_str = log_bytes.decode("utf-8", errors="replace") + write_audit_log(user, role, "read_log", container.name, cid, "success", ip) + return jsonify({"code":0,"msg":"success","data":log_str}) + except Exception as e: + write_audit_log(user, role, "read_log", "", cid, f"fail:{str(e)}", ip) + return jsonify({"code":500,"msg":str(e),"data":""}) + +# 8. 容器网络详情 +@app.route("/network/") +def api_network(cid): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "read_network", "", cid, "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + try: + container = cli.containers.get(cid) + info = container.attrs["NetworkSettings"]["Networks"] + write_audit_log(user, role, "read_network", container.name, cid, "success", ip) + return jsonify({"code":0,"msg":"success","data":json.dumps(info,indent=2)}) + except Exception as e: + write_audit_log(user, role, "read_network", "", cid, f"fail:{str(e)}", ip) + return jsonify({"code":500,"msg":str(e),"data":""}) + +# 9. 短连接单次执行命令(旧弹窗兼容,非实时终端) +@app.route("/exec/", methods=["POST"]) +def api_exec(cid): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "single_exec", "", cid, "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + if role != "admin": + write_audit_log(user, role, "single_exec", "", cid, "denied", ip) + return jsonify({"code":403,"msg":"权限不足,仅管理员可执行命令"}) + try: + data = request.get_json() + cmd = data.get("cmd", "") + if not cmd: + return jsonify({"code":400,"msg":"命令不能为空","data":""}) + cmd_list = shlex.split(cmd) + container = cli.containers.get(cid) + exec_obj = container.exec_run(cmd_list, stdout=True, stderr=True) + output = exec_obj.output.decode("utf-8", errors="replace") + write_audit_log(user, role, "single_exec", container.name, cid, "command_executed", ip) + return jsonify({"code":0,"msg":"success","data":output}) + except Exception as e: + write_audit_log(user, role, "single_exec", "", cid, f"fail:{str(e)}", ip) + return jsonify({"code":500,"msg":str(e),"data":""}) + +# 10. 创建容器(端口标准格式 + 前端可配置CPU/内存) +@app.route("/create", methods=["POST"]) +def api_create(): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "create_container", "", "", "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + if role != "admin": + write_audit_log(user, role, "create_container", "", "", "denied", ip) + return jsonify({"code":403,"msg":"权限不足,仅管理员可创建容器"}) + try: + data = request.get_json() + name = data.get("name", "") + image = data.get("image") + cmd = data.get("cmd") + ports_input = data.get("ports", {}) + # 修复:docker标准端口字典格式 {内部端口:宿主机端口} + port_bind = {} + for inner_port, host_port in ports_input.items(): + port_bind[f"{inner_port}/tcp"] = int(host_port) + # 前端可配置资源限制,默认1核512M + cpu_core = int(data.get("cpu", 1)) + memory_limit = data.get("memory", "512m") + nano_cpus = cpu_core * 1000000000 + container = cli.containers.run( + image=image, + name=name if name else None, + command=cmd if cmd else None, + ports=port_bind, + detach=True, + restart_policy={"Name": "always"}, + mem_limit=memory_limit, + nano_cpus=nano_cpus + ) + write_audit_log(user, role, "create_container", container.name, container.id, "success", ip) + return jsonify({"code":0,"msg":f"容器创建成功,ID:{container.short_id}"}) + except Exception as e: + write_audit_log(user, role, "create_container", "", "", f"fail:{str(e)}", ip) + return jsonify({"code":500,"msg":str(e)}) + +# 11. 登录私有镜像仓库 +@app.route("/bind_repo", methods=["POST"]) +def api_bind_repo(): + global registry_config + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "repo_login", "", "", "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + if role != "admin": + write_audit_log(user, role, "repo_login", "", "", "denied", ip) + return jsonify({"code":403,"msg":"权限不足,仅管理员可登录镜像仓库"}) + try: + data = request.get_json() + repo_name = data.get("repo_name","") + repo_addr = data.get("repo_addr") + repo_user = data.get("repo_user","") + repo_pwd = data.get("repo_pwd","") + api_cli.login(username=repo_user, password=repo_pwd, registry=repo_addr) + registry_config["repo_name"] = repo_name + registry_config["repo_addr"] = repo_addr + registry_config["repo_user"] = repo_user + registry_config["repo_pwd"] = repo_pwd + write_audit_log(user, role, "repo_login", repo_addr, "", "success", ip) + return jsonify({"code":0,"msg":"镜像仓库登录绑定成功"}) + except Exception as e: + write_audit_log(user, role, "repo_login", repo_addr, "", f"fail:{str(e)}", ip) + return jsonify({"code":500,"msg":str(e)}) + +# 修复:stats接口online_cpus兜底兼容,无KeyError +@app.route("/stats/") +def api_stats(cid): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "read_stats", "", cid, "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + try: + container = cli.containers.get(cid) + raw = container.stats(stream=False) + # CPU兼容兜底,不存在online_cpus自动计算 + cpu_stats = raw["cpu_stats"] + online_cpus = cpu_stats.get("online_cpus", len(cpu_stats["cpu_usage"].get("percpu_usage", [])) or 1) + cpu_delta = cpu_stats["cpu_usage"]["total_usage"] - raw["precpu_stats"]["cpu_usage"]["total_usage"] + system_delta = cpu_stats["system_cpu_usage"] - raw["precpu_stats"]["system_cpu_usage"] + cpu_percent = 0.0 + if system_delta > 0 and cpu_delta > 0: + cpu_percent = round((cpu_delta / system_delta) * online_cpus * 100, 1) + # 内存计算 + mem_usage = raw["memory_stats"]["usage"] / 1024 / 1024 + mem_limit = raw["memory_stats"]["limit"] / 1024 / 1024 + mem_percent = round((mem_usage / mem_limit) * 100, 1) if mem_limit > 0 else 0 + # 网络流量 + net_rx = 0 + net_tx = 0 + for net in raw["networks"].values(): + net_rx += net["rx_bytes"] / 1024 / 1024 + net_tx += net["tx_bytes"] / 1024 / 1024 + res = { + "cpu": cpu_percent, + "mem_mb": round(mem_usage, 1), + "mem_limit_mb": round(mem_limit, 1), + "mem_percent": mem_percent, + "net_rx_mb": round(net_rx, 1), + "net_tx_mb": round(net_tx, 1) + } + write_audit_log(user, role, "read_stats", container.name, cid, "success", ip) + return jsonify({"code":0,"msg":"success","data":res}) + except Exception as e: + write_audit_log(user, role, "read_stats", "", cid, f"fail:{str(e)}", ip) + return jsonify({"code":500,"msg":str(e),"data":{}}) + +# 修复:detail接口ENV脱敏,多网卡IP兼容 +@app.route("/detail/") +def api_detail(cid): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "read_detail", "", cid, "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + try: + container = cli.containers.get(cid) + attrs = container.attrs + nets = attrs["NetworkSettings"]["Networks"] + ip_map = {} + for net_name, net_info in nets.items(): + ip_map[net_name] = net_info.get("IPAddress", "") + # 敏感环境变量脱敏 + raw_env = attrs["Config"].get("Env", []) + safe_env = safe_env_filter(raw_env) + res = { + "network_ips": ip_map, + "mounts": attrs["Mounts"], + "env": safe_env, + "created": attrs["Created"], + "entrypoint": attrs["Config"]["Entrypoint"], + "cmd": attrs["Config"]["Cmd"], + "restart_policy": attrs["HostConfig"]["RestartPolicy"] + } + write_audit_log(user, role, "read_detail", container.name, cid, "success", ip) + return jsonify({"code":0,"msg":"success","data":res}) + except Exception as e: + write_audit_log(user, role, "read_detail", "", cid, f"fail:{str(e)}", ip) + return jsonify({"code":500,"msg":str(e),"data":{}}) + +# 根路由 +@app.route("/") +def index(): + return jsonify({"code":400,"msg":"无效操作","list":[],"data":""}) + +# ===================== WebSocket 连接鉴权事件(新增) ===================== +@socketio.on("connect") +def handle_connect(auth): + user, role, _, auth_ok = verify_socket_auth(auth) + if not auth_ok: + return False + ws_user_map[request.sid] = { + "user": user, + "role": role + } + print("WS Connected:", user, role) + +# ===================== WebSocket 交互式TTY实时终端 ===================== +def stream_terminal_output(sid, sock): + """后台异步读取docker终端输出,兼容两种socket接收方式""" + try: + while True: + chunk = docker_recv(sock, 1024) + if not chunk: + break + text = chunk.decode("utf-8", errors="replace") + socketio.emit("terminal_output", {"data": text}, room=sid) + except Exception: + pass + # 流结束自动清理会话 + if sid in session_exec_map: + try: + session_exec_map[sid]["socket"].close() + except Exception: + pass + del session_exec_map[sid] + +@socketio.on("terminal_start") +def handle_terminal_start(json_data): + sid = request.sid + # 新增调试输出 + socketio.emit( + "terminal_output", + { + "data":"[DEBUG] terminal_start reached\r\n" + }, + room=sid + ) + # 替换原verify_auth_sign(),从ws_user_map读取身份 + info = ws_user_map.get(request.sid) + if not info: + socketio.emit( + "terminal_output", + {"data":"身份认证失效\n"}, + room=request.sid + ) + return + user = info["user"] + role = info["role"] + client_ip = request.remote_addr + + # 权限拦截:非管理员禁止打开交互式终端 + if role != "admin": + socketio.emit("terminal_output", {"data": "Permission denied: 仅管理员可访问交互式终端\n"}, room=sid) + write_audit_log(user, role, "terminal_start", "", json_data.get("cid"), "denied", client_ip) + return + + cid = json_data.get("cid") + if not cid: + socketio.emit("terminal_output", {"data": "错误:容器ID不能为空\n"}, room=sid) + write_audit_log(user, role, "terminal_start", "", "", "empty_cid", client_ip) + return + + # 自动探测容器可用shell,兼容全版本docker-py(exec_create返回dict取Id) + target_shell = None + for shell in SHELL_CANDIDATES: + try: + ret = api_cli.exec_create( + container=cid, + cmd=[shell, "-c", "echo ok"] + ) + test_exec_id = ret["Id"] + test_stream = api_cli.exec_start(test_exec_id) + test_stream.read() + target_shell = shell + break + except Exception: + continue + if not target_shell: + socketio.emit("terminal_output", {"data": "错误:容器内无可用shell(bash/sh/ash)\n"}, room=sid) + write_audit_log(user, role, "terminal_start", "", cid, "no_shell", client_ip) + return + + try: + # 创建交互式TTY会话,统一提取Id兼容所有SDK版本 + exec_ret = api_cli.exec_create( + container=cid, + cmd=target_shell, + stdin=True, + stdout=True, + stderr=True, + tty=True + ) + exec_id = exec_ret["Id"] + sock = api_cli.exec_start(exec_id=exec_id, tty=True, socket=True, detach=False) + session_exec_map[sid] = { + "cid": cid, + "exec_id": exec_id, + "socket": sock + } + socketio.start_background_task(stream_terminal_output, sid, sock) + container_name = cli.containers.get(cid).name + write_audit_log(user, role, "terminal_start", container_name, cid, "success", client_ip) + except Exception as e: + socketio.emit("terminal_output", {"data": f"启动终端失败:{str(e)}\n"}, room=sid) + write_audit_log(user, role, "terminal_start", "", cid, f"fail:{str(e)}", client_ip) + +@socketio.on("terminal_input") +def handle_terminal_input(json_data): + """前端输入字符写入容器标准输入,审计脱敏不记录明文""" + sid = request.sid + # 替换原verify_auth_sign() + info = ws_user_map.get(request.sid) + if not info: + return + user = info["user"] + role = info["role"] + client_ip = request.remote_addr + + if sid not in session_exec_map: + socketio.emit("terminal_output", {"data": "终端会话已断开,请重新打开\n"}, room=sid) + return + input_text = json_data.get("data", "") + sock = session_exec_map[sid]["socket"] + sock.send(input_text.encode("utf-8")) + cid = session_exec_map[sid]["cid"] + # 审计仅标记事件,不再记录明文命令,规避密码泄露 + write_audit_log(user, role, "terminal_input", "", cid, "command_entered", client_ip) + +@socketio.on("terminal_resize") +def handle_terminal_resize(json_data): + """前端xterm窗口大小自适应""" + sid = request.sid + if sid not in session_exec_map: + return + exec_id = session_exec_map[sid]["exec_id"] + height = int(json_data.get("height", 24)) + width = int(json_data.get("width", 80)) + try: + api_cli.exec_resize(exec_id=exec_id, height=height, width=width) + except Exception: + pass + +# 新增主动关闭终端事件(解决切换容器残留TTY) +@socketio.on("terminal_close") +def handle_terminal_close(): + sid = request.sid + info = ws_user_map.get(request.sid) + if not info: + return + user = info["user"] + role = info["role"] + client_ip = request.remote_addr + + if sid in session_exec_map: + cid = session_exec_map[sid]["cid"] + try: + session_exec_map[sid]["socket"].close() + except Exception: + pass + del session_exec_map[sid] + write_audit_log(user, role, "terminal_close", "", cid, "manual_close", client_ip) + +@socketio.on("disconnect") +def handle_disconnect(): + """前端断开连接,释放docker socket、清理会话,防止句柄泄漏""" + sid = request.sid + # 清理ws_user_map会话 + if sid in ws_user_map: + del ws_user_map[sid] + info = ws_user_map.get(sid) + if not info: + user = "" + role = "" + client_ip = request.remote_addr + else: + user = info["user"] + role = info["role"] + client_ip = request.remote_addr + + # 清理TTY终端 + if sid in session_exec_map: + cid = session_exec_map[sid]["cid"] + try: + session_exec_map[sid]["socket"].close() + except Exception: + pass + del session_exec_map[sid] + write_audit_log(user, role, "terminal_close", "", cid, "disconnect", client_ip) + # 清理实时日志标记,终止日志循环 + if sid in log_task_map: + del log_task_map[sid] + +# ===================== WebSocket 实时流式日志 docker logs -f(生成器主动释放) ===================== +def stream_follow_log(sid, cid): + generator = None + try: + container = cli.containers.get(cid) + generator = container.logs(stream=True, follow=True) + log_task_map[sid] = {"cid": cid, "running": True} + for line in generator: + task_info = log_task_map.get(sid, {}) + if not task_info.get("running"): + break + txt = line.decode("utf-8", errors="replace") + socketio.emit("log_output", {"data": txt}, room=sid) + except Exception: + pass + finally: + # 主动关闭日志生成器,释放docker daemon长连接 + if generator is not None: + generator.close() + if sid in log_task_map: + del log_task_map[sid] + +@socketio.on("log_start") +def handle_log_start(json_data): + sid = request.sid + # 替换verify_auth_sign,读取ws_user_map + info = ws_user_map.get(request.sid) + if not info: + socketio.emit("log_output", {"data": "身份校验失败"}, room=sid) + write_audit_log("", "", "log_start", "", "", "auth_failed", request.remote_addr) + return + user = info["user"] + role = info["role"] + client_ip = request.remote_addr + + cid = json_data.get("cid") + if not cid: + socketio.emit("log_output", {"data": "容器ID不能为空"}, room=sid) + write_audit_log(user, role, "log_start", "", "", "empty_cid", client_ip) + return + if role != "admin": + socketio.emit("log_output", {"data": "权限不足,仅管理员可查看实时日志"}, room=sid) + write_audit_log(user, role, "log_start", "", cid, "denied", client_ip) + return + socketio.start_background_task(stream_follow_log, sid, cid) + container_name = cli.containers.get(cid).name + write_audit_log(user, role, "log_start", container_name, cid, "success", client_ip) + +@socketio.on("log_stop") +def handle_log_stop(): + sid = request.sid + info = ws_user_map.get(request.sid) + if not info: + return + user = info["user"] + role = info["role"] + client_ip = request.remote_addr + + if sid in log_task_map: + log_task_map[sid]["running"] = False + cid = log_task_map[sid]["cid"] + write_audit_log(user, role, "log_stop", "", cid, "manual_close", client_ip) + +# 启动入口(eventlet异步,必须socketio.run) +if __name__ == "__main__": + socketio.run(app, host="0.0.0.0", port=8090, debug=False, allow_unsafe_werkzeug=True) diff --git a/api/docker_api.py.bak b/api/docker_api.py.bak new file mode 100644 index 0000000..b607643 --- /dev/null +++ b/api/docker_api.py.bak @@ -0,0 +1,100 @@ +import json +import docker +from flask import Flask, jsonify + +# 兼容新旧版本 +try: + cli = docker.DockerClient(base_url='unix:///var/run/docker.sock') +except AttributeError: + cli = docker.Client(base_url='unix:///var/run/docker.sock') + +app = Flask(__name__) + +# 容器列表 +@app.route("/list") +def api_list(): + arr = [] + for c in cli.containers.list(all=True): + img_name = c.image.tags[0] if c.image.tags else "" + arr.append({ + "id": c.short_id, + "full_id": c.id, + "name": c.name, + "image": img_name, + "status": c.status, + "ports": str(c.ports) + }) + return jsonify({"code":0,"msg":"success","list":arr}) + +# 镜像列表 +@app.route("/image_list") +def api_image_list(): + arr = [] + for img in cli.images.list(): + if not img.tags: + continue + full_tag = img.tags[0] + repo, tag = full_tag.split(":", 1) + size_mb = round(img.attrs["Size"] / 1024 / 1024, 1) + arr.append({ + "repo": repo, + "tag": tag, + "id": img.short_id, + "full_id": img.id, + "size": f"{size_mb}MB", + "created": img.attrs["Created"] + }) + return jsonify({"code":0,"msg":"success","list":arr}) + +# 重启容器 +@app.route("/restart/") +def api_restart(cid): + try: + cli.containers.get(cid).restart() + return jsonify({"code":0,"msg":"容器已重启"}) + except Exception as e: + return jsonify({"code":500,"msg":str(e)}) + +# 停止容器 +@app.route("/stop/") +def api_stop(cid): + try: + cli.containers.get(cid).stop() + return jsonify({"code":0,"msg":"容器已停止"}) + except Exception as e: + return jsonify({"code":500,"msg":str(e)}) + +# 删除容器 +@app.route("/rm/") +def api_rm(cid): + try: + cli.containers.get(cid).remove(force=True) + return jsonify({"code":0,"msg":"容器已强制删除"}) + except Exception as e: + return jsonify({"code":500,"msg":str(e)}) + +# 容器日志 +@app.route("/logs//") +def api_logs(cid, tail_lines): + try: + log_bytes = cli.containers.get(cid).logs(tail=tail_lines) + log_str = log_bytes.decode("utf-8", errors="ignore") + return jsonify({"code":0,"msg":"success","data":log_str}) + except Exception as e: + return jsonify({"code":500,"msg":str(e),"data":""}) + +# 网络信息 +@app.route("/network/") +def api_network(cid): + try: + info = cli.containers.get(cid).attrs["NetworkSettings"]["Networks"] + return jsonify({"code":0,"msg":"success","data":info}) + except Exception as e: + return jsonify({"code":500,"msg":str(e),"data":""}) + +@app.route("/") +def index(): + return jsonify({"code":400,"msg":"无效操作","list":[],"data":""}) + +if __name__ == "__main__": + app.run(host="0.0.0.0", port=8090, debug=False) diff --git a/api/docker_api.py1 b/api/docker_api.py1 new file mode 100644 index 0000000..b514e30 --- /dev/null +++ b/api/docker_api.py1 @@ -0,0 +1,669 @@ +# 【强制置顶】eventlet猴子补丁,必须放在所有导入最前面 +import json +import shlex +import time +import hashlib +import hmac +import docker +from flask import Flask, jsonify, request +from flask_socketio import SocketIO + +# 全局签名密钥,前后端统一,生产环境使用环境变量注入 +SIGN_SECRET = b"DockerAdminPlatform2026SecretKey123456789" +# 签名有效期 300秒(5分钟) +SIGN_EXPIRE = 300 + +# 兼容新旧docker-py客户端 +try: + cli = docker.DockerClient(base_url='unix:///var/run/docker.sock') + api_cli = docker.APIClient(base_url='unix:///var/run/docker.sock') +except AttributeError: + cli = docker.Client(base_url='unix:///var/run/docker.sock') + api_cli = docker.APIClient(base_url='unix:///var/run/docker.sock') + +app = Flask(__name__) +app.config['SECRET_KEY'] = 'docker-terminal-secret-2026' + +# WebSocket心跳保活,防止Nginx/反向代理断连 +socketio = SocketIO( + app, + cors_allowed_origins="*", + async_mode="threading", + ping_timeout=60, + ping_interval=25 +) + +# 全局会话存储 +session_exec_map = {} # sid => TTY终端流信息 +log_task_map = {} # sid => {"cid": "", "running": True} +registry_config = { + "repo_name": "", + "repo_addr": "", + "repo_user": "", + "repo_pwd": "" +} +# 多系统shell兼容列表(Ubuntu/Alpine/标准Linux) +SHELL_CANDIDATES = [ + "/bin/bash", + "/usr/bin/bash", + "/bin/sh", + "/bin/ash" +] + +# ===================== 工具函数1:docker socket兼容recv ===================== +def docker_recv(sock, size=1024): + try: + return sock.recv(size) + except Exception: + try: + return sock._sock.recv(size) + except Exception: + return b"" + +# ===================== 工具函数2:操作审计日志(终端输入脱敏,不存明文密码) ===================== +def write_audit_log(user, role, action, target_name, target_id, result, client_ip): + """企业审计记录,可对接数据库docker_audit_log表""" + # 终端输入仅标记事件,不记录明文命令,规避密码泄露风险 + if action == "terminal_input": + result = "command_entered" + log_item = { + "timestamp": time.strftime("%Y-%m-%d %H:%M:%S"), + "user": user, + "role": role, + "action": action, + "container_name": target_name, + "container_id": target_id, + "result": result, + "client_ip": client_ip + } + # 生产环境替换为mysql insert语句 + print(json.dumps(log_item, ensure_ascii=False)) + +# ===================== 工具函数3:HMAC签名鉴权,防Header伪造 ===================== +def verify_auth_sign(): + """ + 校验前端PHP生成的HMAC签名,防止伪造X-Role:admin + 请求Header要求: + X-User: 用户名 + X-Role: admin/user/guest + X-Time: 当前时间戳(秒) + X-Sign: hmac-sha256签名 + 返回 (user, role, client_ip, True/False) + """ + user = request.headers.get("X-User", "anonymous") + role = request.headers.get("X-Role", "guest") + ts_str = request.headers.get("X-Time", "0") + sign = request.headers.get("X-Sign", "") + client_ip = request.headers.get("X-Client-Ip", request.remote_addr) + try: + ts = int(ts_str) + except ValueError: + return user, role, client_ip, False + # 校验签名有效期 + now = int(time.time()) + if abs(now - ts) > SIGN_EXPIRE: + return user, role, client_ip, False + # 校验HMAC签名 + raw_data = f"{user}|{role}|{ts}".encode("utf-8") + calc_sign = hmac.new(SIGN_SECRET, raw_data, hashlib.sha256).hexdigest() + if calc_sign != sign: + return user, role, client_ip, False + return user, role, client_ip, True + +# ===================== 工具函数4:环境变量脱敏,屏蔽密码/密钥 ===================== +def safe_env_filter(env_list): + safe_env = [] + sensitive_keywords = ["PASS", "PASSWORD", "TOKEN", "SECRET", "KEY", "CREDENTIAL"] + for item in env_list: + equal_pos = item.find("=") + if equal_pos == -1: + safe_env.append(item) + continue + key = item[:equal_pos] + val = item[equal_pos+1:] + if any(word in key.upper() for word in sensitive_keywords): + safe_env.append(f"{key}=******") + else: + safe_env.append(item) + return safe_env + +# ===================== 全部HTTP业务接口 ===================== +# 1. 容器列表(端口预拼接字符串,前端直接渲染,无需formatPorts) +@app.route("/list") +def api_list(): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "list_container", "", "", "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + arr = [] + for c in cli.containers.list(all=True): + img_name = c.image.tags[0] if c.image.tags else "" + port_str_arr = [] + ports_raw = c.ports + for c_port, host_list in ports_raw.items(): + if not host_list: + continue + for host_item in host_list: + host_port = host_item.get("HostPort", "") + port_str_arr.append(f"{host_port}:{c_port.split('/')[0]}") + port_display = ",".join(port_str_arr) if port_str_arr else "-" + arr.append({ + "id": c.short_id, + "full_id": c.id, + "name": c.name, + "image": img_name, + "status": c.status, + "ports": port_display + }) + write_audit_log(user, role, "list_container", "", "", "success", ip) + return jsonify({"code":0,"msg":"success","list":arr}) + +# 2. 镜像列表 +@app.route("/image_list") +def api_image_list(): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "list_image", "", "", "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + arr = [] + for img in cli.images.list(): + if not img.tags: + continue + full_tag = img.tags[0] + repo, tag = full_tag.split(":", 1) + size_mb = round(img.attrs["Size"] / 1024 / 1024, 1) + arr.append({ + "repo": repo, + "tag": tag, + "id": img.short_id, + "full_id": img.id, + "size": f"{size_mb}MB", + "created": img.attrs["Created"] + }) + write_audit_log(user, role, "list_image", "", "", "success", ip) + return jsonify({"code":0,"msg":"success","list":arr}) + +# 3. 删除镜像 +@app.route("/remove_image/") +def api_remove_image(image_id): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "remove_image", "", image_id, "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + if role != "admin": + write_audit_log(user, role, "remove_image", "", image_id, "denied", ip) + return jsonify({"code":403,"msg":"权限不足,仅管理员可删除镜像"}) + try: + img = cli.images.get(image_id) + cli.images.remove(image_id, force=True) + write_audit_log(user, role, "remove_image", img.tags[0] if img.tags else "", image_id, "success", ip) + return jsonify({"code":0,"msg":"镜像已强制删除"}) + except Exception as e: + write_audit_log(user, role, "remove_image", "", image_id, f"fail:{str(e)}", ip) + return jsonify({"code":500,"msg":str(e)}) + +# 4. 重启容器 +@app.route("/restart/") +def api_restart(cid): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "restart", "", cid, "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + if role != "admin": + write_audit_log(user, role, "restart", "", cid, "denied", ip) + return jsonify({"code":403,"msg":"权限不足,仅管理员可操作容器"}) + try: + container = cli.containers.get(cid) + container.restart() + write_audit_log(user, role, "restart", container.name, cid, "success", ip) + return jsonify({"code":0,"msg":"容器已重启"}) + except Exception as e: + write_audit_log(user, role, "restart", "", cid, f"fail:{str(e)}", ip) + return jsonify({"code":500,"msg":str(e)}) + +# 5. 停止容器 +@app.route("/stop/") +def api_stop(cid): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "stop", "", cid, "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + if role != "admin": + write_audit_log(user, role, "stop", "", cid, "denied", ip) + return jsonify({"code":403,"msg":"权限不足,仅管理员可操作容器"}) + try: + container = cli.containers.get(cid) + container.stop() + write_audit_log(user, role, "stop", container.name, cid, "success", ip) + return jsonify({"code":0,"msg":"容器已停止"}) + except Exception as e: + write_audit_log(user, role, "stop", "", cid, f"fail:{str(e)}", ip) + return jsonify({"code":500,"msg":str(e)}) + +# 6. 删除容器 +@app.route("/rm/") +def api_rm(cid): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "rm", "", cid, "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + if role != "admin": + write_audit_log(user, role, "rm", "", cid, "denied", ip) + return jsonify({"code":403,"msg":"权限不足,仅管理员可删除容器"}) + try: + container = cli.containers.get(cid) + container.remove(force=True) + write_audit_log(user, role, "rm", container.name, cid, "success", ip) + return jsonify({"code":0,"msg":"容器已强制删除"}) + except Exception as e: + write_audit_log(user, role, "rm", "", cid, f"fail:{str(e)}", ip) + return jsonify({"code":500,"msg":str(e)}) + +# 7. 一次性拉取日志(兼容旧页面单次查看) +@app.route("/logs//") +def api_logs(cid, tail_lines): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "read_log", "", cid, "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + try: + container = cli.containers.get(cid) + log_bytes = container.logs(tail=tail_lines) + log_str = log_bytes.decode("utf-8", errors="replace") + write_audit_log(user, role, "read_log", container.name, cid, "success", ip) + return jsonify({"code":0,"msg":"success","data":log_str}) + except Exception as e: + write_audit_log(user, role, "read_log", "", cid, f"fail:{str(e)}", ip) + return jsonify({"code":500,"msg":str(e),"data":""}) + +# 8. 容器网络详情 +@app.route("/network/") +def api_network(cid): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "read_network", "", cid, "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + try: + container = cli.containers.get(cid) + info = container.attrs["NetworkSettings"]["Networks"] + write_audit_log(user, role, "read_network", container.name, cid, "success", ip) + return jsonify({"code":0,"msg":"success","data":json.dumps(info,indent=2)}) + except Exception as e: + write_audit_log(user, role, "read_network", "", cid, f"fail:{str(e)}", ip) + return jsonify({"code":500,"msg":str(e),"data":""}) + +# 9. 短连接单次执行命令(旧弹窗兼容,非实时终端) +@app.route("/exec/", methods=["POST"]) +def api_exec(cid): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "single_exec", "", cid, "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + if role != "admin": + write_audit_log(user, role, "single_exec", "", cid, "denied", ip) + return jsonify({"code":403,"msg":"权限不足,仅管理员可执行命令"}) + try: + data = request.get_json() + cmd = data.get("cmd", "") + if not cmd: + return jsonify({"code":400,"msg":"命令不能为空","data":""}) + cmd_list = shlex.split(cmd) + container = cli.containers.get(cid) + exec_obj = container.exec_run(cmd_list, stdout=True, stderr=True) + output = exec_obj.output.decode("utf-8", errors="replace") + write_audit_log(user, role, "single_exec", container.name, cid, "command_executed", ip) + return jsonify({"code":0,"msg":"success","data":output}) + except Exception as e: + write_audit_log(user, role, "single_exec", "", cid, f"fail:{str(e)}", ip) + return jsonify({"code":500,"msg":str(e),"data":""}) + +# 10. 创建容器(端口标准格式 + 前端可配置CPU/内存) +@app.route("/create", methods=["POST"]) +def api_create(): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "create_container", "", "", "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + if role != "admin": + write_audit_log(user, role, "create_container", "", "", "denied", ip) + return jsonify({"code":403,"msg":"权限不足,仅管理员可创建容器"}) + try: + data = request.get_json() + name = data.get("name", "") + image = data.get("image") + cmd = data.get("cmd") + ports_input = data.get("ports", {}) + # 修复:docker标准端口字典格式 {内部端口:宿主机端口} + port_bind = {} + for inner_port, host_port in ports_input.items(): + port_bind[f"{inner_port}/tcp"] = int(host_port) + # 前端可配置资源限制,默认1核512M + cpu_core = int(data.get("cpu", 1)) + memory_limit = data.get("memory", "512m") + nano_cpus = cpu_core * 1000000000 + container = cli.containers.run( + image=image, + name=name if name else None, + command=cmd if cmd else None, + ports=port_bind, + detach=True, + restart_policy={"Name": "always"}, + mem_limit=memory_limit, + nano_cpus=nano_cpus + ) + write_audit_log(user, role, "create_container", container.name, container.id, "success", ip) + return jsonify({"code":0,"msg":f"容器创建成功,ID:{container.short_id}"}) + except Exception as e: + write_audit_log(user, role, "create_container", "", "", f"fail:{str(e)}", ip) + return jsonify({"code":500,"msg":str(e)}) + +# 11. 登录私有镜像仓库 +@app.route("/bind_repo", methods=["POST"]) +def api_bind_repo(): + global registry_config + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "repo_login", "", "", "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + if role != "admin": + write_audit_log(user, role, "repo_login", "", "", "denied", ip) + return jsonify({"code":403,"msg":"权限不足,仅管理员可登录镜像仓库"}) + try: + data = request.get_json() + repo_name = data.get("repo_name","") + repo_addr = data.get("repo_addr") + repo_user = data.get("repo_user","") + repo_pwd = data.get("repo_pwd","") + api_cli.login(username=repo_user, password=repo_pwd, registry=repo_addr) + registry_config["repo_name"] = repo_name + registry_config["repo_addr"] = repo_addr + registry_config["repo_user"] = repo_user + registry_config["repo_pwd"] = repo_pwd + write_audit_log(user, role, "repo_login", repo_addr, "", "success", ip) + return jsonify({"code":0,"msg":"镜像仓库登录绑定成功"}) + except Exception as e: + write_audit_log(user, role, "repo_login", repo_addr, "", f"fail:{str(e)}", ip) + return jsonify({"code":500,"msg":str(e)}) + +# 修复:stats接口online_cpus兜底兼容,无KeyError +@app.route("/stats/") +def api_stats(cid): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "read_stats", "", cid, "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + try: + container = cli.containers.get(cid) + raw = container.stats(stream=False) + # CPU兼容兜底,不存在online_cpus自动计算 + cpu_stats = raw["cpu_stats"] + online_cpus = cpu_stats.get("online_cpus", len(cpu_stats["cpu_usage"].get("percpu_usage", [])) or 1) + cpu_delta = cpu_stats["cpu_usage"]["total_usage"] - raw["precpu_stats"]["cpu_usage"]["total_usage"] + system_delta = cpu_stats["system_cpu_usage"] - raw["precpu_stats"]["system_cpu_usage"] + cpu_percent = 0.0 + if system_delta > 0 and cpu_delta > 0: + cpu_percent = round((cpu_delta / system_delta) * online_cpus * 100, 1) + # 内存计算 + mem_usage = raw["memory_stats"]["usage"] / 1024 / 1024 + mem_limit = raw["memory_stats"]["limit"] / 1024 / 1024 + mem_percent = round((mem_usage / mem_limit) * 100, 1) if mem_limit > 0 else 0 + # 网络流量 + net_rx = 0 + net_tx = 0 + for net in raw["networks"].values(): + net_rx += net["rx_bytes"] / 1024 / 1024 + net_tx += net["tx_bytes"] / 1024 / 1024 + res = { + "cpu": cpu_percent, + "mem_mb": round(mem_usage, 1), + "mem_limit_mb": round(mem_limit, 1), + "mem_percent": mem_percent, + "net_rx_mb": round(net_rx, 1), + "net_tx_mb": round(net_tx, 1) + } + write_audit_log(user, role, "read_stats", container.name, cid, "success", ip) + return jsonify({"code":0,"msg":"success","data":res}) + except Exception as e: + write_audit_log(user, role, "read_stats", "", cid, f"fail:{str(e)}", ip) + return jsonify({"code":500,"msg":str(e),"data":{}}) + +# 修复:detail接口ENV脱敏,多网卡IP兼容 +@app.route("/detail/") +def api_detail(cid): + user, role, ip, auth_ok = verify_auth_sign() + if not auth_ok: + write_audit_log(user, role, "read_detail", "", cid, "auth_failed", ip) + return jsonify({"code":403,"msg":"身份校验失败,非法访问"}) + try: + container = cli.containers.get(cid) + attrs = container.attrs + nets = attrs["NetworkSettings"]["Networks"] + ip_map = {} + for net_name, net_info in nets.items(): + ip_map[net_name] = net_info.get("IPAddress", "") + # 敏感环境变量脱敏 + raw_env = attrs["Config"].get("Env", []) + safe_env = safe_env_filter(raw_env) + res = { + "network_ips": ip_map, + "mounts": attrs["Mounts"], + "env": safe_env, + "created": attrs["Created"], + "entrypoint": attrs["Config"]["Entrypoint"], + "cmd": attrs["Config"]["Cmd"], + "restart_policy": attrs["HostConfig"]["RestartPolicy"] + } + write_audit_log(user, role, "read_detail", container.name, cid, "success", ip) + return jsonify({"code":0,"msg":"success","data":res}) + except Exception as e: + write_audit_log(user, role, "read_detail", "", cid, f"fail:{str(e)}", ip) + return jsonify({"code":500,"msg":str(e),"data":{}}) + +# 根路由 +@app.route("/") +def index(): + return jsonify({"code":400,"msg":"无效操作","list":[],"data":""}) + +# ===================== WebSocket 交互式TTY实时终端 ===================== +def stream_terminal_output(sid, sock): + """后台异步读取docker终端输出,兼容两种socket接收方式""" + try: + while True: + chunk = docker_recv(sock, 1024) + if not chunk: + break + text = chunk.decode("utf-8", errors="replace") + socketio.emit("terminal_output", {"data": text}, room=sid) + except Exception: + pass + # 流结束自动清理会话 + if sid in session_exec_map: + try: + session_exec_map[sid]["socket"].close() + except Exception: + pass + del session_exec_map[sid] + +@socketio.on("terminal_start") +def handle_terminal_start(json_data): + sid = request.sid + user, role, client_ip, auth_ok = verify_auth_sign() + if not auth_ok: + socketio.emit("terminal_output", {"data": "Permission denied: 身份校验失败\n"}, room=sid) + write_audit_log(user, role, "terminal_start", "", json_data.get("cid"), "auth_failed", client_ip) + return + # 权限拦截:非管理员禁止打开交互式终端 + if role != "admin": + socketio.emit("terminal_output", {"data": "Permission denied: 仅管理员可访问交互式终端\n"}, room=sid) + write_audit_log(user, role, "terminal_start", "", json_data.get("cid"), "denied", client_ip) + return + + cid = json_data.get("cid") + if not cid: + socketio.emit("terminal_output", {"data": "错误:容器ID不能为空\n"}, room=sid) + write_audit_log(user, role, "terminal_start", "", "", "empty_cid", client_ip) + return + + # 自动探测容器可用shell,兼容全版本docker-py(exec_create返回dict取Id) + target_shell = None + for shell in SHELL_CANDIDATES: + try: + ret = api_cli.exec_create( + container=cid, + cmd=[shell, "-c", "echo ok"] + ) + test_exec_id = ret["Id"] + test_stream = api_cli.exec_start(test_exec_id) + test_stream.read() + target_shell = shell + break + except Exception: + continue + if not target_shell: + socketio.emit("terminal_output", {"data": "错误:容器内无可用shell(bash/sh/ash)\n"}, room=sid) + write_audit_log(user, role, "terminal_start", "", cid, "no_shell", client_ip) + return + + try: + # 创建交互式TTY会话,统一提取Id兼容所有SDK版本 + exec_ret = api_cli.exec_create( + container=cid, + cmd=target_shell, + stdin=True, + stdout=True, + stderr=True, + tty=True + ) + exec_id = exec_ret["Id"] + sock = api_cli.exec_start(exec_id=exec_id, tty=True, socket=True, detach=False) + session_exec_map[sid] = { + "cid": cid, + "exec_id": exec_id, + "socket": sock + } + socketio.start_background_task(stream_terminal_output, sid, sock) + container_name = cli.containers.get(cid).name + write_audit_log(user, role, "terminal_start", container_name, cid, "success", client_ip) + except Exception as e: + socketio.emit("terminal_output", {"data": f"启动终端失败:{str(e)}\n"}, room=sid) + write_audit_log(user, role, "terminal_start", "", cid, f"fail:{str(e)}", client_ip) + +@socketio.on("terminal_input") +def handle_terminal_input(json_data): + """前端输入字符写入容器标准输入,审计脱敏不记录明文""" + sid = request.sid + user, role, client_ip, auth_ok = verify_auth_sign() + if not auth_ok: + socketio.emit("terminal_output", {"data": "身份校验失败\n"}, room=sid) + return + if sid not in session_exec_map: + socketio.emit("terminal_output", {"data": "终端会话已断开,请重新打开\n"}, room=sid) + return + input_text = json_data.get("data", "") + sock = session_exec_map[sid]["socket"] + sock.send(input_text.encode("utf-8")) + cid = session_exec_map[sid]["cid"] + # 审计仅标记事件,不再记录明文命令,规避密码泄露 + write_audit_log(user, role, "terminal_input", "", cid, "command_entered", client_ip) + +@socketio.on("terminal_resize") +def handle_terminal_resize(json_data): + """前端xterm窗口大小自适应""" + sid = request.sid + if sid not in session_exec_map: + return + exec_id = session_exec_map[sid]["exec_id"] + height = int(json_data.get("height", 24)) + width = int(json_data.get("width", 80)) + try: + api_cli.exec_resize(exec_id=exec_id, height=height, width=width) + except Exception: + pass + +# 新增主动关闭终端事件(解决切换容器残留TTY) +@socketio.on("terminal_close") +def handle_terminal_close(): + sid = request.sid + user, role, client_ip, auth_ok = verify_auth_sign() + if sid in session_exec_map: + cid = session_exec_map[sid]["cid"] + try: + session_exec_map[sid]["socket"].close() + except Exception: + pass + del session_exec_map[sid] + write_audit_log(user, role, "terminal_close", "", cid, "manual_close", client_ip) + +@socketio.on("disconnect") +def handle_disconnect(): + """前端断开连接,释放docker socket、清理会话,防止句柄泄漏""" + sid = request.sid + user, role, client_ip, auth_ok = verify_auth_sign() + # 清理TTY终端 + if sid in session_exec_map: + cid = session_exec_map[sid]["cid"] + try: + session_exec_map[sid]["socket"].close() + except Exception: + pass + del session_exec_map[sid] + write_audit_log(user, role, "terminal_close", "", cid, "disconnect", client_ip) + # 清理实时日志标记,终止日志循环 + if sid in log_task_map: + del log_task_map[sid] + +# ===================== WebSocket 实时流式日志 docker logs -f(生成器主动释放) ===================== +def stream_follow_log(sid, cid): + generator = None + try: + container = cli.containers.get(cid) + generator = container.logs(stream=True, follow=True) + log_task_map[sid] = {"cid": cid, "running": True} + for line in generator: + task_info = log_task_map.get(sid, {}) + if not task_info.get("running"): + break + txt = line.decode("utf-8", errors="replace") + socketio.emit("log_output", {"data": txt}, room=sid) + except Exception: + pass + finally: + # 主动关闭日志生成器,释放docker daemon长连接 + if generator is not None: + generator.close() + if sid in log_task_map: + del log_task_map[sid] + +@socketio.on("log_start") +def handle_log_start(json_data): + sid = request.sid + user, role, client_ip, auth_ok = verify_auth_sign() + if not auth_ok: + socketio.emit("log_output", {"data": "身份校验失败"}, room=sid) + write_audit_log(user, role, "log_start", "", "", "auth_failed", client_ip) + return + cid = json_data.get("cid") + if not cid: + socketio.emit("log_output", {"data": "容器ID不能为空"}, room=sid) + write_audit_log(user, role, "log_start", "", "", "empty_cid", client_ip) + return + if role != "admin": + socketio.emit("log_output", {"data": "权限不足,仅管理员可查看实时日志"}, room=sid) + write_audit_log(user, role, "log_start", "", cid, "denied", client_ip) + return + socketio.start_background_task(stream_follow_log, sid, cid) + container_name = cli.containers.get(cid).name + write_audit_log(user, role, "log_start", container_name, cid, "success", client_ip) + +@socketio.on("log_stop") +def handle_log_stop(): + sid = request.sid + user, role, client_ip, auth_ok = verify_auth_sign() + if sid in log_task_map: + log_task_map[sid]["running"] = False + cid = log_task_map[sid]["cid"] + write_audit_log(user, role, "log_stop", "", cid, "manual_close", client_ip) + +# 启动入口(eventlet异步,必须socketio.run) +if __name__ == "__main__": + socketio.run(app, host="0.0.0.0", port=8090, debug=False, allow_unsafe_werkzeug=True) diff --git a/api/docker_api.sh b/api/docker_api.sh new file mode 100644 index 0000000..f6b244a --- /dev/null +++ b/api/docker_api.sh @@ -0,0 +1,9 @@ +#!/bin/bash +while true; do +nc -l 127.0.0.1 9999 <401,"msg"=>"未登录,请前往登录页面"], JSON_UNESCAPED_UNICODE); + exit; +} + +// 统一数据库配置 +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPass = "hp93000"; +$dbName = "alert_mail_stat"; + +// 统一数据库连接函数 +function getDbConn() { + global $dbHost, $dbUser, $dbPass, $dbName; + $conn = mysqli_connect($dbHost, $dbUser, $dbPass, $dbName); + mysqli_set_charset($conn, "utf8mb4"); + return $conn; +} + +// CSV导出接口(支持指定历史日期下载,不输出JSON头) +if ($act === "export_csv") { + date_default_timezone_set('Asia/Shanghai'); + $conn = getDbConn(); + mysqli_query($conn, "SET time_zone = '+08:00'"); + if (!$conn) { + header("Content-Type:text/html;charset=utf-8"); + echo "数据库连接失败:" . mysqli_connect_error(); + exit; + } + + $singleDate = $_GET['date'] ?? ''; + $startDate = $_GET['start'] ?? ''; + $endDate = $_GET['end'] ?? ''; + $where = ""; + $fileName = ""; + + if (!empty($startDate) && !empty($endDate)) { + if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $startDate) || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $endDate)) { + header("Content-Type:application/json;charset=utf-8"); + echo json_encode(["code"=>400,"msg"=>"日期格式错误"], JSON_UNESCAPED_UNICODE); + exit; + } + if ($startDate > $endDate) { + header("Content-Type:application/json;charset=utf-8"); + echo json_encode(["code"=>400,"msg"=>"开始日期不能大于结束日期"], JSON_UNESCAPED_UNICODE); + exit; + } + $where = "receive_time >= '$startDate 00:00:00' AND receive_time <= '$endDate 23:59:59'"; + $fileName = "告警报表_{$startDate}_至_{$endDate}.csv"; + } elseif (!empty($singleDate)) { + if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $singleDate)) { + header("Content-Type:application/json;charset=utf-8"); + echo json_encode(["code"=>400,"msg"=>"日期格式错误"], JSON_UNESCAPED_UNICODE); + exit; + } + $where = "DATE(receive_time) = '$singleDate'"; + $fileName = "告警报表_{$singleDate}.csv"; + } else { + $today = date("Y-m-d"); + $where = "DATE(receive_time) = '$today'"; + $fileName = "告警报表_今日_{$today}.csv"; + } + + // 调试:打印where条件,访问接口先看这个 + // echo "WHERE条件:".$where;exit; + + $sql = "SELECT alert_type,alert_name,instance,severity,starts_at,receive_time + FROM alert_log WHERE {$where} ORDER BY receive_time DESC"; + $res = mysqli_query($conn, $sql); + + ob_clean(); + header("Content-Type: text/csv; charset=utf-8"); + header("Content-Disposition: attachment; filename={$fileName}"); + echo "\xEF\xBB\xBF"; + $header = ["告警状态", "告警名称", "实例", "级别", "故障开始时间", "接收时间"]; + echo implode(",", $header) . "\r\n"; + + while ($row = mysqli_fetch_assoc($res)) { + $status = $row['alert_type'] == 1 ? "触发" : "恢复"; + $line = [ + $status, + $row['alert_name'], + $row['instance'], + $row['severity'], + $row['starts_at'], + $row['receive_time'] + ]; + foreach ($line as &$v) { + $v = '"' . str_replace('"', '""', $v) . '"'; + } + echo implode(",", $line) . "\r\n"; + } + mysqli_close($conn); + exit; +} +// 所有JSON接口统一返回头 +header("Content-Type:application/json;charset=utf-8"); +$conn = getDbConn(); +if (!$conn) { + echo json_encode(["code" => 500, "msg" => "数据库连接失败:" . mysqli_connect_error()], JSON_UNESCAPED_UNICODE); + exit; +} +$today = date("Y-m-d"); + +// 调试代码:打印GET入参,测试完成后删除此段 +// $getAct = $_GET['act'] ?? ''; +//echo json_encode([ +// "debug_act" => $getAct, +// "debug_rule" => $_GET['rule_name'] ?? '', +// "debug_instance" => $_GET['instance'] ?? '' +//], JSON_UNESCAPED_UNICODE); +//exit; + +// 接口1:下线整条监控规则(该规则下所有实例一并清理) +if($act === "clear_offline_rule"){ + $rule = $_GET['rule_name'] ?? ''; + if(empty($rule)){ + echo json_encode(["code"=>400,"msg"=>"缺少rule_name参数"],JSON_UNESCAPED_UNICODE); + exit; + } + $ruleEsc = mysqli_real_escape_string($conn, $rule); + // 标记该规则下全部实例为下线 + $updateSql = "UPDATE monitor_rule SET status=0, update_at=NOW() WHERE rule_name='$ruleEsc'"; + mysqli_query($conn, $updateSql); + // 批量插入恢复记录,消除页面残留告警 + $insertSql = " + INSERT INTO alert_log (alert_type,alert_name,instance,severity,starts_at,receive_time) + SELECT DISTINCT 2,alert_name,instance,severity,NOW(),NOW() + FROM alert_log + WHERE alert_name='$ruleEsc' + AND (alert_name,instance) NOT IN ( + SELECT alert_name,instance FROM alert_log WHERE alert_type=2 + ) + "; + mysqli_query($conn, $insertSql); + echo json_encode(["code"=>0,"msg"=>"整条规则下线完成,所有实例告警已清除"],JSON_UNESCAPED_UNICODE); + exit; +} + +// 接口2:单独下线单台实例(仅隐藏指定机器,同规则其他主机不受影响) +if($act === "clear_single_instance"){ + $rule = $_GET['rule_name'] ?? ''; + $inst = $_GET['instance'] ?? ''; + if(empty($rule) || empty($inst)){ + echo json_encode(["code"=>400,"msg"=>"缺少rule_name或instance参数"],JSON_UNESCAPED_UNICODE); + exit; + } + $ruleEsc = mysqli_real_escape_string($conn, $rule); + $instEsc = mysqli_real_escape_string($conn, $inst); + + // 第一步:删除当前实例旧的恢复记录,避免重复拦截 + $delSql = "DELETE FROM alert_log WHERE alert_type=2 AND alert_name='$ruleEsc' AND instance='$instEsc'"; + mysqli_query($conn, $delSql); + + // 第二步:插入最新恢复记录,移除NOT IN限制,强制生成 + $insertSql = " + INSERT INTO alert_log (alert_type,alert_name,instance,severity,starts_at,receive_time) + SELECT DISTINCT 2,alert_name,instance,severity,NOW(),NOW() + FROM alert_log + WHERE alert_name='$ruleEsc' AND instance='$instEsc' + "; + mysqli_query($conn, $insertSql); + $affected = mysqli_affected_rows($conn); + + echo json_encode([ + "code"=>0, + "msg"=>"单实例告警清理完成", + "insert_rows" => $affected + ],JSON_UNESCAPED_UNICODE); + exit; +} + +// 接口3:恢复整条已下线规则(status改为1,重新展示所有实例告警) +if($act === "restore_rule"){ + $rule = $_GET['rule_name'] ?? ''; + if(empty($rule)){ + echo json_encode(["code"=>400,"msg"=>"缺少rule_name参数"],JSON_UNESCAPED_UNICODE); + exit; + } + $ruleEsc = mysqli_real_escape_string($conn, $rule); + $updateSql = "UPDATE monitor_rule SET status=1, update_at=NOW() WHERE rule_name='$ruleEsc'"; + mysqli_query($conn, $updateSql); + echo json_encode(["code"=>0,"msg"=>"监控规则已恢复,新故障会正常展示"],JSON_UNESCAPED_UNICODE); + exit; +} + +// 接口4:恢复单台实例(仅把指定rule+instance置为启用) +if($act === "restore_single_instance"){ + $rule = $_GET['rule_name'] ?? ''; + $inst = $_GET['instance'] ?? ''; + if(empty($rule) || empty($inst)){ + echo json_encode(["code"=>400,"msg"=>"缺少rule_name或instance参数"],JSON_UNESCAPED_UNICODE); + exit; + } + $ruleEsc = mysqli_real_escape_string($conn, $rule); + $instEsc = mysqli_real_escape_string($conn, $inst); + $updateSql = "UPDATE monitor_rule SET status=1, update_at=NOW() WHERE rule_name='$ruleEsc' AND instance='$instEsc'"; + mysqli_query($conn, $updateSql); + echo json_encode(["code"=>0,"msg"=>"单实例已恢复"],JSON_UNESCAPED_UNICODE); + exit; +} + +// 接口5:删除单实例全部告警日志 +if($act === "delete_single_instance_log"){ + $rule = $_GET['rule_name'] ?? ''; + $inst = $_GET['instance'] ?? ''; + if(empty($rule) || empty($inst)){ + echo json_encode(["code"=>400,"msg"=>"缺少rule_name或instance参数"],JSON_UNESCAPED_UNICODE); + exit; + } + $ruleEsc = mysqli_real_escape_string($conn, $rule); + $instEsc = mysqli_real_escape_string($conn, $inst); + $delSql = "DELETE FROM alert_log WHERE alert_name='$ruleEsc' AND instance='$instEsc'"; + mysqli_query($conn, $delSql); + $aff = mysqli_affected_rows($conn); + echo json_encode(["code"=>0,"msg"=>"单实例告警日志已删除","affected_rows"=>$aff],JSON_UNESCAPED_UNICODE); + exit; +} + +// 接口:永久屏蔽单台实例(monitor_rule 该条实例status=0,不手动恢复永远不告警) +if($act === "offline_single_instance"){ + $rule = $_GET['rule_name'] ?? ''; + $inst = $_GET['instance'] ?? ''; + if(empty($rule) || empty($inst)){ + echo json_encode(["code"=>400,"msg"=>"缺少rule_name或instance参数"],JSON_UNESCAPED_UNICODE); + exit; + } + $ruleEsc = mysqli_real_escape_string($conn, $rule); + $instEsc = mysqli_real_escape_string($conn, $inst); + + // 把这条【规则+实例】状态改为0,永久屏蔽 + $updateSql = "UPDATE monitor_rule SET status=0, update_at=NOW() WHERE rule_name='$ruleEsc' AND instance='$instEsc'"; + mysqli_query($conn, $updateSql); + $aff = mysqli_affected_rows($conn); + + // 同步生成恢复日志,界面立刻消失旧告警 + $delOld = "DELETE FROM alert_log WHERE alert_type=2 AND alert_name='$ruleEsc' AND instance='$instEsc'"; + mysqli_query($conn, $delOld); + $insertSql = " + INSERT INTO alert_log (alert_type,alert_name,instance,severity,starts_at,receive_time) + SELECT DISTINCT 2,alert_name,instance,severity,NOW(),NOW() + FROM alert_log + WHERE alert_name='$ruleEsc' AND instance='$instEsc' + "; + mysqli_query($conn, $insertSql); + + echo json_encode([ + "code"=>0, + "msg"=>"单实例已永久屏蔽,需调用restore_single_instance恢复", + "update_rows"=>$aff + ],JSON_UNESCAPED_UNICODE); + exit; +} + +// 新增:同步Prometheus实时告警,自动清理残留恢复记录 +if($act === "sync_prom_alerts"){ + $promUrl = "http://10.150.117.190:9090/api/v1/alerts"; + $resp = @file_get_contents($promUrl); + if($resp === false){ + echo json_encode(["code"=>500,"msg"=>"无法连接Prometheus接口"],JSON_UNESCAPED_UNICODE); + exit; + } + $promData = json_decode($resp,true); + if(!isset($promData['data']['alerts'])){ + echo json_encode(["code"=>500,"msg"=>"Prometheus返回数据异常"],JSON_UNESCAPED_UNICODE); + exit; + } + + $firingMap = []; + foreach($promData['data']['alerts'] as $item){ + $an = $item['labels']['alertname']; + $ins = $item['labels']['instance']; + $key = "$an||$ins"; + $firingMap[$key] = 1; + } + + $res = mysqli_query($conn,"SELECT alert_name,instance FROM alert_log WHERE alert_type=2"); + $delCnt = 0; + while($row = mysqli_fetch_assoc($res)){ + $k = $row['alert_name']."||".$row['instance']; + if(isset($firingMap[$k])){ + $n = mysqli_real_escape_string($conn,$row['alert_name']); + $i = mysqli_real_escape_string($conn,$row['instance']); + mysqli_query($conn,"DELETE FROM alert_log WHERE alert_type=2 AND alert_name='$n' AND instance='$i'"); + $delCnt++; + } + } + echo json_encode(["code"=>0,"msg"=>"同步完成","delete_clear_log"=>$delCnt],JSON_UNESCAPED_UNICODE); + exit; +} + +// ============后台管理专用接口 start============ +// 修改密码 BCrypt哈希加密,匹配历史密码算法 +if($act === "change_pwd"){ + $uid = $_SESSION['user_id']; + $oldPwdRaw = $_GET['old_pwd'] ?? ''; + $newPwdRaw = $_GET['new_pwd'] ?? ''; + if(empty($oldPwdRaw) || empty($newPwdRaw)){ + echo json_encode(["code"=>400,"msg"=>"密码不能为空"],JSON_UNESCAPED_UNICODE); + exit; + } + // 查询原密码哈希 + $userSql = "SELECT password FROM admin_user WHERE user_id='$uid' LIMIT 1"; + $userRes = mysqli_query($conn,$userSql); + $userRow = mysqli_fetch_assoc($userRes); + if(!$userRow){ + echo json_encode(["code"=>401,"msg"=>"账户不存在"],JSON_UNESCAPED_UNICODE); + exit; + } + $oldHash = $userRow['password']; + // 校验旧密码(和原有登录逻辑一致) + if(!password_verify($oldPwdRaw, $oldHash)){ + echo json_encode(["code"=>400,"msg"=>"原密码输入错误"],JSON_UNESCAPED_UNICODE); + exit; + } + // 生成新bcrypt哈希 + $newHash = password_hash($newPwdRaw, PASSWORD_DEFAULT); + $updateSql = "UPDATE admin_user SET password='$newHash', update_at=NOW() WHERE user_id='$uid'"; + mysqli_query($conn,$updateSql); + echo json_encode(["code"=>0,"msg"=>"密码修改成功"],JSON_UNESCAPED_UNICODE); + exit; +} + +// 保存界面外观配置 +if($act === "save_theme"){ + // 兼容POST/GET + $title = mysqli_real_escape_string($conn,$_POST['title'] ?? $_GET['title'] ?? ''); + $color = mysqli_real_escape_string($conn,$_POST['color'] ?? $_GET['color'] ?? ''); + $pagesize = mysqli_real_escape_string($conn,$_POST['pagesize'] ?? $_GET['pagesize'] ?? '20'); + $footer = mysqli_real_escape_string($conn,$_POST['footer'] ?? $_GET['footer'] ?? ''); + $lang = mysqli_real_escape_string($conn,$_POST['lang'] ?? $_GET['lang'] ?? 'zh'); + + $sql = "REPLACE INTO sys_config (k,v) VALUES + ('page_title','$title'), + ('theme_color','$color'), + ('page_size','$pagesize'), + ('footer_text','$footer'), + ('lang','$lang')"; + mysqli_query($conn,$sql); + echo json_encode(["code"=>0,"msg"=>"外观配置已保存"],JSON_UNESCAPED_UNICODE); + exit; +} +// 保存侧边栏外链 +if($act === "save_sidebar_link"){ + $linkText = mysqli_real_escape_string($conn,$_GET['link_text'] ?? ''); + $sql = "REPLACE INTO sys_config (k,v) VALUES ('sidebar_links','$linkText')"; + mysqli_query($conn,$sql); + echo json_encode(["code"=>0,"msg"=>"侧边外链保存成功"],JSON_UNESCAPED_UNICODE); + exit; +} + +// 单独切换语言接口 +if ($_POST['act'] === 'save_lang') { + $lang = mysqli_real_escape_string($conn, $_POST['lang']); + $sql = "REPLACE INTO sys_config(k, v) VALUES ('lang', '$lang')"; + mysqli_query($conn, $sql); + echo json_encode(["code" => 0]); + exit; +} +// ============后台管理专用接口 end============ +// 1. 今日统计卡片 +if ($act === "day_total") { + $sql = "SELECT + SUM(IF(alert_type=1,1,0)) as fire_count, + SUM(IF(alert_type=2,1,0)) as resolve_count, + COUNT(DISTINCT instance) as instance_num + FROM alert_log WHERE DATE(receive_time) = '$today'"; + $data = mysqli_fetch_assoc(mysqli_query($conn, $sql)); + echo json_encode($data, JSON_UNESCAPED_UNICODE); + exit; +} + +// 2. 今日告警TOP10图表 +if ($act === "top_alert") { + $sql = "SELECT alert_name,COUNT(*) cnt FROM alert_log WHERE DATE(receive_time)='$today' GROUP BY alert_name ORDER BY cnt DESC LIMIT 10"; + $list = []; + $q = mysqli_query($conn, $sql); + while ($r = mysqli_fetch_assoc($q)) $list[] = $r; + echo json_encode($list, JSON_UNESCAPED_UNICODE); + exit; +} + +// 3. 今日全量告警明细表格 +if ($act === "log_list") { + $sql = "SELECT alert_type,alert_name,instance,severity,starts_at,ends_at,receive_time + FROM alert_log WHERE DATE(receive_time)='$today' ORDER BY receive_time DESC"; + $list = []; + $q = mysqli_query($conn, $sql); + while ($r = mysqli_fetch_assoc($q)) $list[] = $r; + echo json_encode($list, JSON_UNESCAPED_UNICODE); + exit; +} + +// 4. 全局跨天未恢复告警(过滤整条下线规则,单实例仅靠恢复日志隐藏) +if ($act === "active_firing") { + $maxSql = "SELECT alert_name,instance,MAX(receive_time) max_rt FROM alert_log GROUP BY alert_name,instance"; + $maxRes = mysqli_query($conn, $maxSql); + $activeList = []; + while ($maxRow = mysqli_fetch_assoc($maxRes)) { + $an = $conn->real_escape_string($maxRow['alert_name']); + $ins = $conn->real_escape_string($maxRow['instance']); + $mrt = $conn->real_escape_string($maxRow['max_rt']); + + // 判断该规则是否整条下线,下线直接跳过 + $ruleCheck = mysqli_query($conn, "SELECT status FROM monitor_rule WHERE rule_name='$an' LIMIT 1"); + $ruleStatus = 1; + if($ruleCheck && $ruleRow = mysqli_fetch_assoc($ruleCheck)){ + $ruleStatus = intval($ruleRow['status']); + } + if($ruleStatus === 0){ + continue; + } + + $rowSql = "SELECT alert_name,instance,severity,starts_at,receive_time,alert_type + FROM alert_log + WHERE alert_name='$an' AND instance='$ins' AND receive_time='$mrt'"; + $rowRes = mysqli_query($conn, $rowSql); + $data = mysqli_fetch_assoc($rowRes); + if ($data && (int)$data['alert_type'] === 1) { + $activeList[] = $data; + } + } + echo json_encode($activeList, JSON_UNESCAPED_UNICODE); + exit; +} + +// 非法请求兜底 +echo json_encode(["code" => 400, "msg" => "无效请求参数act"], JSON_UNESCAPED_UNICODE); +mysqli_close($conn); +?> diff --git a/api/index.php0.09版本 b/api/index.php0.09版本 new file mode 100644 index 0000000..27b6d22 --- /dev/null +++ b/api/index.php0.09版本 @@ -0,0 +1,45 @@ + diff --git a/api/index.php0.1版本 b/api/index.php0.1版本 new file mode 100644 index 0000000..6ceac65 --- /dev/null +++ b/api/index.php0.1版本 @@ -0,0 +1,49 @@ +500,"msg"=>"数据库连接失败:".mysqli_connect_error()]); + exit; +} +mysqli_set_charset($conn,"utf8mb4"); +$act = $_GET['act'] ?? ''; +$today = date("Y-m-d"); + +// 当日总统计 +if($act == "day_total"){ + $sql = "SELECT + SUM(IF(alert_type=1,1,0)) as fire_count, + SUM(IF(alert_type=2,1,0)) as resolve_count, + COUNT(DISTINCT instance) as instance_num + FROM alert_log WHERE DATE(receive_time) = '$today'"; + $res = mysqli_fetch_assoc(mysqli_query($conn,$sql)); + echo json_encode($res,JSON_UNESCAPED_UNICODE); +} + +// 告警TOP10 +if($act == "top_alert"){ + $sql = "SELECT alert_name,COUNT(*) cnt FROM alert_log WHERE DATE(receive_time)='$today' GROUP BY alert_name ORDER BY cnt DESC LIMIT 10"; + $data = []; + $q = mysqli_query($conn,$sql); + while($r = mysqli_fetch_assoc($q)) $data[] = $r; + echo json_encode($data,JSON_UNESCAPED_UNICODE); +} + +// 明细列表 +if($act == "log_list"){ + $sql = "SELECT alert_type,alert_name,instance,severity,starts_at,ends_at,receive_time + FROM alert_log WHERE DATE(receive_time)='$today' ORDER BY receive_time DESC"; + $data = []; + $q = mysqli_query($conn,$sql); + while($r = mysqli_fetch_assoc($q)) $data[] = $r; + echo json_encode($data,JSON_UNESCAPED_UNICODE); +} + +mysqli_close($conn); +?> diff --git a/api/index.php0.2版本 b/api/index.php0.2版本 new file mode 100644 index 0000000..6ceac65 --- /dev/null +++ b/api/index.php0.2版本 @@ -0,0 +1,49 @@ +500,"msg"=>"数据库连接失败:".mysqli_connect_error()]); + exit; +} +mysqli_set_charset($conn,"utf8mb4"); +$act = $_GET['act'] ?? ''; +$today = date("Y-m-d"); + +// 当日总统计 +if($act == "day_total"){ + $sql = "SELECT + SUM(IF(alert_type=1,1,0)) as fire_count, + SUM(IF(alert_type=2,1,0)) as resolve_count, + COUNT(DISTINCT instance) as instance_num + FROM alert_log WHERE DATE(receive_time) = '$today'"; + $res = mysqli_fetch_assoc(mysqli_query($conn,$sql)); + echo json_encode($res,JSON_UNESCAPED_UNICODE); +} + +// 告警TOP10 +if($act == "top_alert"){ + $sql = "SELECT alert_name,COUNT(*) cnt FROM alert_log WHERE DATE(receive_time)='$today' GROUP BY alert_name ORDER BY cnt DESC LIMIT 10"; + $data = []; + $q = mysqli_query($conn,$sql); + while($r = mysqli_fetch_assoc($q)) $data[] = $r; + echo json_encode($data,JSON_UNESCAPED_UNICODE); +} + +// 明细列表 +if($act == "log_list"){ + $sql = "SELECT alert_type,alert_name,instance,severity,starts_at,ends_at,receive_time + FROM alert_log WHERE DATE(receive_time)='$today' ORDER BY receive_time DESC"; + $data = []; + $q = mysqli_query($conn,$sql); + while($r = mysqli_fetch_assoc($q)) $data[] = $r; + echo json_encode($data,JSON_UNESCAPED_UNICODE); +} + +mysqli_close($conn); +?> diff --git a/api/index.php0.3版本 b/api/index.php0.3版本 new file mode 100644 index 0000000..a1141f0 --- /dev/null +++ b/api/index.php0.3版本 @@ -0,0 +1,106 @@ +500,"msg"=>"数据库连接失败:".mysqli_connect_error()]); + exit; +} +mysqli_set_charset($conn,"utf8mb4"); +$today = date("Y-m-d"); + +// 当日总统计 +if($act == "day_total"){ + $sql = "SELECT + SUM(IF(alert_type=1,1,0)) as fire_count, + SUM(IF(alert_type=2,1,0)) as resolve_count, + COUNT(DISTINCT instance) as instance_num + FROM alert_log WHERE DATE(receive_time) = '$today'"; + $res = mysqli_fetch_assoc(mysqli_query($conn,$sql)); + echo json_encode($res,JSON_UNESCAPED_UNICODE); + mysqli_close($conn); + exit; +} + +// 告警TOP10 +if($act == "top_alert"){ + $sql = "SELECT alert_name,COUNT(*) cnt FROM alert_log WHERE DATE(receive_time)='$today' GROUP BY alert_name ORDER BY cnt DESC LIMIT 10"; + $data = []; + $q = mysqli_query($conn,$sql); + while($r = mysqli_fetch_assoc($q)) $data[] = $r; + echo json_encode($data,JSON_UNESCAPED_UNICODE); + mysqli_close($conn); + exit; +} + +// 明细列表 +if($act == "log_list"){ + $sql = "SELECT alert_type,alert_name,instance,severity,starts_at,ends_at,receive_time + FROM alert_log WHERE DATE(receive_time)='$today' ORDER BY receive_time DESC"; + $data = []; + $q = mysqli_query($conn,$sql); + while($r = mysqli_fetch_assoc($q)) $data[] = $r; + echo json_encode($data,JSON_UNESCAPED_UNICODE); + mysqli_close($conn); + exit; +} + +// 无效参数兜底 +echo json_encode(["code"=>400,"msg"=>"无效请求参数act"],JSON_UNESCAPED_UNICODE); +mysqli_close($conn); +?> diff --git a/api/index.php0.4版本 b/api/index.php0.4版本 new file mode 100644 index 0000000..de768b0 --- /dev/null +++ b/api/index.php0.4版本 @@ -0,0 +1,140 @@ + 500, "msg" => "数据库连接失败:" . mysqli_connect_error()], JSON_UNESCAPED_UNICODE); + exit; +} +$today = date("Y-m-d"); + +// 1. 今日统计卡片 +if ($act === "day_total") { + $sql = "SELECT + SUM(IF(alert_type=1,1,0)) as fire_count, + SUM(IF(alert_type=2,1,0)) as resolve_count, + COUNT(DISTINCT instance) as instance_num + FROM alert_log WHERE DATE(receive_time) = '$today'"; + $data = mysqli_fetch_assoc(mysqli_query($conn, $sql)); + echo json_encode($data, JSON_UNESCAPED_UNICODE); + mysqli_close($conn); + exit; +} + +// 2. 今日告警TOP10图表 +if ($act === "top_alert") { + $sql = "SELECT alert_name,COUNT(*) cnt FROM alert_log WHERE DATE(receive_time)='$today' GROUP BY alert_name ORDER BY cnt DESC LIMIT 10"; + $list = []; + $q = mysqli_query($conn, $sql); + while ($r = mysqli_fetch_assoc($q)) $list[] = $r; + echo json_encode($list, JSON_UNESCAPED_UNICODE); + mysqli_close($conn); + exit; +} + +// 3. 今日全量告警明细表格 +if ($act === "log_list") { + $sql = "SELECT alert_type,alert_name,instance,severity,starts_at,ends_at,receive_time + FROM alert_log WHERE DATE(receive_time)='$today' ORDER BY receive_time DESC"; + $list = []; + $q = mysqli_query($conn, $sql); + while ($r = mysqli_fetch_assoc($q)) $list[] = $r; + echo json_encode($list, JSON_UNESCAPED_UNICODE); + mysqli_close($conn); + exit; +} + +// 4. 全局跨天未恢复告警(解决6.30残留故障不显示) +if ($act === "active_firing") { + // 查询全部触发告警 + $fireSql = "SELECT DISTINCT alert_name,instance,severity,starts_at,receive_time FROM alert_log WHERE alert_type=1"; + $fireRes = mysqli_query($conn, $fireSql); + $fireMap = []; + while ($row = mysqli_fetch_assoc($fireRes)) { + $key = $row['alert_name'] . "|" . $row['instance']; + $fireMap[$key] = $row; + } + if (empty($fireMap)) { + echo json_encode([], JSON_UNESCAPED_UNICODE); + mysqli_close($conn); + exit; + } + // 查询全部恢复告警唯一标识 + $resolveSql = "SELECT DISTINCT CONCAT(alert_name,'|',instance) as k FROM alert_log WHERE alert_type=2"; + $resolveRes = mysqli_query($conn, $resolveSql); + $resolveKeys = []; + while ($r = mysqli_fetch_assoc($resolveRes)) { + $resolveKeys[] = $r['k']; + } + // 过滤:存在触发、无对应恢复 = 当前活跃故障 + $activeList = []; + foreach ($fireMap as $key => $row) { + if (!in_array($key, $resolveKeys)) { + $row['alert_type'] = 1; + $activeList[] = $row; + } + } + echo json_encode($activeList, JSON_UNESCAPED_UNICODE); + mysqli_close($conn); + exit; +} + +// 非法请求兜底 +echo json_encode(["code" => 400, "msg" => "无效请求参数act"], JSON_UNESCAPED_UNICODE); +mysqli_close($conn); +?> diff --git a/api/index.php0.5版本 b/api/index.php0.5版本 new file mode 100644 index 0000000..f5e7443 --- /dev/null +++ b/api/index.php0.5版本 @@ -0,0 +1,139 @@ +401,"msg"=>"未登录,请前往登录页面"]); + exit; +} +// 统一数据库配置 +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPass = "hp93000"; +$dbName = "alert_mail_stat"; + +// 统一数据库连接函数 +function getDbConn() { + global $dbHost, $dbUser, $dbPass, $dbName; + $conn = mysqli_connect($dbHost, $dbUser, $dbPass, $dbName); + mysqli_set_charset($conn, "utf8mb4"); + return $conn; +} + +$act = $_GET['act'] ?? ''; + +// CSV导出接口(独立流式下载,不输出JSON头) +if ($act === "export_csv") { + $conn = getDbConn(); + if (!$conn) { + header("Content-Type:text/html;charset=utf-8"); + echo "数据库连接失败:" . mysqli_connect_error(); + exit; + } + $today = date("Y-m-d"); + $sql = "SELECT alert_type,alert_name,instance,severity,starts_at,receive_time + FROM alert_log WHERE DATE(receive_time) = '$today' ORDER BY receive_time DESC"; + $res = mysqli_query($conn, $sql); + + ob_clean(); + header("Content-Type: text/csv; charset=utf-8"); + header("Content-Disposition: attachment; filename=告警报表_" . $today . ".csv"); + echo "\xEF\xBB\xBF"; + $header = ["告警状态", "告警名称", "实例", "级别", "故障开始时间", "接收时间"]; + echo implode(",", $header) . "\r\n"; + + while ($row = mysqli_fetch_assoc($res)) { + $status = $row['alert_type'] == 1 ? "触发" : "恢复"; + $line = [ + $status, + $row['alert_name'], + $row['instance'], + $row['severity'], + $row['starts_at'], + $row['receive_time'] + ]; + foreach ($line as &$v) { + $v = '"' . str_replace('"', '""', $v) . '"'; + } + echo implode(",", $line) . "\r\n"; + } + mysqli_close($conn); + exit; +} + +// 所有JSON接口统一返回头 +header("Content-Type:application/json;charset=utf-8"); +$conn = getDbConn(); +if (!$conn) { + echo json_encode(["code" => 500, "msg" => "数据库连接失败:" . mysqli_connect_error()], JSON_UNESCAPED_UNICODE); + exit; +} +$today = date("Y-m-d"); + +// 1. 今日统计卡片 +if ($act === "day_total") { + $sql = "SELECT + SUM(IF(alert_type=1,1,0)) as fire_count, + SUM(IF(alert_type=2,1,0)) as resolve_count, + COUNT(DISTINCT instance) as instance_num + FROM alert_log WHERE DATE(receive_time) = '$today'"; + $data = mysqli_fetch_assoc(mysqli_query($conn, $sql)); + echo json_encode($data, JSON_UNESCAPED_UNICODE); + mysqli_close($conn); + exit; +} + +// 2. 今日告警TOP10图表 +if ($act === "top_alert") { + $sql = "SELECT alert_name,COUNT(*) cnt FROM alert_log WHERE DATE(receive_time)='$today' GROUP BY alert_name ORDER BY cnt DESC LIMIT 10"; + $list = []; + $q = mysqli_query($conn, $sql); + while ($r = mysqli_fetch_assoc($q)) $list[] = $r; + echo json_encode($list, JSON_UNESCAPED_UNICODE); + mysqli_close($conn); + exit; +} + +// 3. 今日全量告警明细表格 +if ($act === "log_list") { + $sql = "SELECT alert_type,alert_name,instance,severity,starts_at,ends_at,receive_time + FROM alert_log WHERE DATE(receive_time)='$today' ORDER BY receive_time DESC"; + $list = []; + $q = mysqli_query($conn, $sql); + while ($r = mysqli_fetch_assoc($q)) $list[] = $r; + echo json_encode($list, JSON_UNESCAPED_UNICODE); + mysqli_close($conn); + exit; +} + +// 4. 全局跨天未恢复告警【修复版:只看每条告警最新状态,兼容低版本MariaDB】 +if ($act === "active_firing") { + // 第一步:分组获取每个告警+实例的最新入库时间 + $maxSql = "SELECT alert_name,instance,MAX(receive_time) max_rt FROM alert_log GROUP BY alert_name,instance"; + $maxRes = mysqli_query($conn, $maxSql); + $activeList = []; + while ($maxRow = mysqli_fetch_assoc($maxRes)) { + // 转义防止SQL注入 + $an = $conn->real_escape_string($maxRow['alert_name']); + $ins = $conn->real_escape_string($maxRow['instance']); + $mrt = $conn->real_escape_string($maxRow['max_rt']); + // 根据告警名、实例、最新时间取出最后一条记录 + $rowSql = "SELECT alert_name,instance,severity,starts_at,receive_time,alert_type + FROM alert_log + WHERE alert_name='$an' AND instance='$ins' AND receive_time='$mrt'"; + $rowRes = mysqli_query($conn, $rowSql); + $data = mysqli_fetch_assoc($rowRes); + // 仅最后一条状态为触发,才判定为当前活跃未恢复告警 + if ($data && (int)$data['alert_type'] === 1) { + $activeList[] = $data; + } + } + echo json_encode($activeList, JSON_UNESCAPED_UNICODE); + mysqli_close($conn); + exit; +} + +// 非法请求兜底 +echo json_encode(["code" => 400, "msg" => "无效请求参数act"], JSON_UNESCAPED_UNICODE); +mysqli_close($conn); +?> diff --git a/api/index.php0.6版本 b/api/index.php0.6版本 new file mode 100644 index 0000000..895ad1e --- /dev/null +++ b/api/index.php0.6版本 @@ -0,0 +1,330 @@ +401,"msg"=>"未登录,请前往登录页面"], JSON_UNESCAPED_UNICODE); + exit; +} + +// 统一数据库配置 +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPass = "hp93000"; +$dbName = "alert_mail_stat"; + +// 统一数据库连接函数 +function getDbConn() { + global $dbHost, $dbUser, $dbPass, $dbName; + $conn = mysqli_connect($dbHost, $dbUser, $dbPass, $dbName); + mysqli_set_charset($conn, "utf8mb4"); + return $conn; +} + +// CSV导出接口(独立流式下载,不输出JSON头) +if ($act === "export_csv") { + $conn = getDbConn(); + if (!$conn) { + header("Content-Type:text/html;charset=utf-8"); + echo "数据库连接失败:" . mysqli_connect_error(); + exit; + } + $today = date("Y-m-d"); + $sql = "SELECT alert_type,alert_name,instance,severity,starts_at,receive_time + FROM alert_log WHERE DATE(receive_time) = '$today' ORDER BY receive_time DESC"; + $res = mysqli_query($conn, $sql); + + ob_clean(); + header("Content-Type: text/csv; charset=utf-8"); + header("Content-Disposition: attachment; filename=告警报表_" . $today . ".csv"); + echo "\xEF\xBB\xBF"; + $header = ["告警状态", "告警名称", "实例", "级别", "故障开始时间", "接收时间"]; + echo implode(",", $header) . "\r\n"; + + while ($row = mysqli_fetch_assoc($res)) { + $status = $row['alert_type'] == 1 ? "触发" : "恢复"; + $line = [ + $status, + $row['alert_name'], + $row['instance'], + $row['severity'], + $row['starts_at'], + $row['receive_time'] + ]; + foreach ($line as &$v) { + $v = '"' . str_replace('"', '""', $v) . '"'; + } + echo implode(",", $line) . "\r\n"; + } + mysqli_close($conn); + exit; +} + +// 所有JSON接口统一返回头 +header("Content-Type:application/json;charset=utf-8"); +$conn = getDbConn(); +if (!$conn) { + echo json_encode(["code" => 500, "msg" => "数据库连接失败:" . mysqli_connect_error()], JSON_UNESCAPED_UNICODE); + exit; +} +$today = date("Y-m-d"); + +// 调试代码:打印GET入参,测试完成后删除此段 +// $getAct = $_GET['act'] ?? ''; +//echo json_encode([ +// "debug_act" => $getAct, +// "debug_rule" => $_GET['rule_name'] ?? '', +// "debug_instance" => $_GET['instance'] ?? '' +//], JSON_UNESCAPED_UNICODE); +//exit; + +// 接口1:下线整条监控规则(该规则下所有实例一并清理) +if($act === "clear_offline_rule"){ + $rule = $_GET['rule_name'] ?? ''; + if(empty($rule)){ + echo json_encode(["code"=>400,"msg"=>"缺少rule_name参数"],JSON_UNESCAPED_UNICODE); + exit; + } + $ruleEsc = mysqli_real_escape_string($conn, $rule); + // 标记该规则下全部实例为下线 + $updateSql = "UPDATE monitor_rule SET status=0, update_at=NOW() WHERE rule_name='$ruleEsc'"; + mysqli_query($conn, $updateSql); + // 批量插入恢复记录,消除页面残留告警 + $insertSql = " + INSERT INTO alert_log (alert_type,alert_name,instance,severity,starts_at,receive_time) + SELECT DISTINCT 2,alert_name,instance,severity,NOW(),NOW() + FROM alert_log + WHERE alert_name='$ruleEsc' + AND (alert_name,instance) NOT IN ( + SELECT alert_name,instance FROM alert_log WHERE alert_type=2 + ) + "; + mysqli_query($conn, $insertSql); + echo json_encode(["code"=>0,"msg"=>"整条规则下线完成,所有实例告警已清除"],JSON_UNESCAPED_UNICODE); + exit; +} + +// 接口2:单独下线单台实例(仅隐藏指定机器,同规则其他主机不受影响) +if($act === "clear_single_instance"){ + $rule = $_GET['rule_name'] ?? ''; + $inst = $_GET['instance'] ?? ''; + if(empty($rule) || empty($inst)){ + echo json_encode(["code"=>400,"msg"=>"缺少rule_name或instance参数"],JSON_UNESCAPED_UNICODE); + exit; + } + $ruleEsc = mysqli_real_escape_string($conn, $rule); + $instEsc = mysqli_real_escape_string($conn, $inst); + + // 第一步:删除当前实例旧的恢复记录,避免重复拦截 + $delSql = "DELETE FROM alert_log WHERE alert_type=2 AND alert_name='$ruleEsc' AND instance='$instEsc'"; + mysqli_query($conn, $delSql); + + // 第二步:插入最新恢复记录,移除NOT IN限制,强制生成 + $insertSql = " + INSERT INTO alert_log (alert_type,alert_name,instance,severity,starts_at,receive_time) + SELECT DISTINCT 2,alert_name,instance,severity,NOW(),NOW() + FROM alert_log + WHERE alert_name='$ruleEsc' AND instance='$instEsc' + "; + mysqli_query($conn, $insertSql); + $affected = mysqli_affected_rows($conn); + + echo json_encode([ + "code"=>0, + "msg"=>"单实例告警清理完成", + "insert_rows" => $affected + ],JSON_UNESCAPED_UNICODE); + exit; +} + +// 接口3:恢复整条已下线规则(status改为1,重新展示所有实例告警) +if($act === "restore_rule"){ + $rule = $_GET['rule_name'] ?? ''; + if(empty($rule)){ + echo json_encode(["code"=>400,"msg"=>"缺少rule_name参数"],JSON_UNESCAPED_UNICODE); + exit; + } + $ruleEsc = mysqli_real_escape_string($conn, $rule); + $updateSql = "UPDATE monitor_rule SET status=1, update_at=NOW() WHERE rule_name='$ruleEsc'"; + mysqli_query($conn, $updateSql); + echo json_encode(["code"=>0,"msg"=>"监控规则已恢复,新故障会正常展示"],JSON_UNESCAPED_UNICODE); + exit; +} + +// 接口4:恢复单台实例(仅把指定rule+instance置为启用) +if($act === "restore_single_instance"){ + $rule = $_GET['rule_name'] ?? ''; + $inst = $_GET['instance'] ?? ''; + if(empty($rule) || empty($inst)){ + echo json_encode(["code"=>400,"msg"=>"缺少rule_name或instance参数"],JSON_UNESCAPED_UNICODE); + exit; + } + $ruleEsc = mysqli_real_escape_string($conn, $rule); + $instEsc = mysqli_real_escape_string($conn, $inst); + $updateSql = "UPDATE monitor_rule SET status=1, update_at=NOW() WHERE rule_name='$ruleEsc' AND instance='$instEsc'"; + mysqli_query($conn, $updateSql); + echo json_encode(["code"=>0,"msg"=>"单实例已恢复"],JSON_UNESCAPED_UNICODE); + exit; +} + +// 接口5:删除单实例全部告警日志 +if($act === "delete_single_instance_log"){ + $rule = $_GET['rule_name'] ?? ''; + $inst = $_GET['instance'] ?? ''; + if(empty($rule) || empty($inst)){ + echo json_encode(["code"=>400,"msg"=>"缺少rule_name或instance参数"],JSON_UNESCAPED_UNICODE); + exit; + } + $ruleEsc = mysqli_real_escape_string($conn, $rule); + $instEsc = mysqli_real_escape_string($conn, $inst); + $delSql = "DELETE FROM alert_log WHERE alert_name='$ruleEsc' AND instance='$instEsc'"; + mysqli_query($conn, $delSql); + $aff = mysqli_affected_rows($conn); + echo json_encode(["code"=>0,"msg"=>"单实例告警日志已删除","affected_rows"=>$aff],JSON_UNESCAPED_UNICODE); + exit; +} + +// 接口:永久屏蔽单台实例(monitor_rule 该条实例status=0,不手动恢复永远不告警) +if($act === "offline_single_instance"){ + $rule = $_GET['rule_name'] ?? ''; + $inst = $_GET['instance'] ?? ''; + if(empty($rule) || empty($inst)){ + echo json_encode(["code"=>400,"msg"=>"缺少rule_name或instance参数"],JSON_UNESCAPED_UNICODE); + exit; + } + $ruleEsc = mysqli_real_escape_string($conn, $rule); + $instEsc = mysqli_real_escape_string($conn, $inst); + + // 把这条【规则+实例】状态改为0,永久屏蔽 + $updateSql = "UPDATE monitor_rule SET status=0, update_at=NOW() WHERE rule_name='$ruleEsc' AND instance='$instEsc'"; + mysqli_query($conn, $updateSql); + $aff = mysqli_affected_rows($conn); + + // 同步生成恢复日志,界面立刻消失旧告警 + $delOld = "DELETE FROM alert_log WHERE alert_type=2 AND alert_name='$ruleEsc' AND instance='$instEsc'"; + mysqli_query($conn, $delOld); + $insertSql = " + INSERT INTO alert_log (alert_type,alert_name,instance,severity,starts_at,receive_time) + SELECT DISTINCT 2,alert_name,instance,severity,NOW(),NOW() + FROM alert_log + WHERE alert_name='$ruleEsc' AND instance='$instEsc' + "; + mysqli_query($conn, $insertSql); + + echo json_encode([ + "code"=>0, + "msg"=>"单实例已永久屏蔽,需调用restore_single_instance恢复", + "update_rows"=>$aff + ],JSON_UNESCAPED_UNICODE); + exit; +} + +// 新增:同步Prometheus实时告警,自动清理残留恢复记录 +if($act === "sync_prom_alerts"){ + $promUrl = "http://10.150.117.190:9090/api/v1/alerts"; + $resp = @file_get_contents($promUrl); + if($resp === false){ + echo json_encode(["code"=>500,"msg"=>"无法连接Prometheus接口"],JSON_UNESCAPED_UNICODE); + exit; + } + $promData = json_decode($resp,true); + if(!isset($promData['data']['alerts'])){ + echo json_encode(["code"=>500,"msg"=>"Prometheus返回数据异常"],JSON_UNESCAPED_UNICODE); + exit; + } + + $firingMap = []; + foreach($promData['data']['alerts'] as $item){ + $an = $item['labels']['alertname']; + $ins = $item['labels']['instance']; + $key = "$an||$ins"; + $firingMap[$key] = 1; + } + + $res = mysqli_query($conn,"SELECT alert_name,instance FROM alert_log WHERE alert_type=2"); + $delCnt = 0; + while($row = mysqli_fetch_assoc($res)){ + $k = $row['alert_name']."||".$row['instance']; + if(isset($firingMap[$k])){ + $n = mysqli_real_escape_string($conn,$row['alert_name']); + $i = mysqli_real_escape_string($conn,$row['instance']); + mysqli_query($conn,"DELETE FROM alert_log WHERE alert_type=2 AND alert_name='$n' AND instance='$i'"); + $delCnt++; + } + } + echo json_encode(["code"=>0,"msg"=>"同步完成","delete_clear_log"=>$delCnt],JSON_UNESCAPED_UNICODE); + exit; +} + +// 1. 今日统计卡片 +if ($act === "day_total") { + $sql = "SELECT + SUM(IF(alert_type=1,1,0)) as fire_count, + SUM(IF(alert_type=2,1,0)) as resolve_count, + COUNT(DISTINCT instance) as instance_num + FROM alert_log WHERE DATE(receive_time) = '$today'"; + $data = mysqli_fetch_assoc(mysqli_query($conn, $sql)); + echo json_encode($data, JSON_UNESCAPED_UNICODE); + exit; +} + +// 2. 今日告警TOP10图表 +if ($act === "top_alert") { + $sql = "SELECT alert_name,COUNT(*) cnt FROM alert_log WHERE DATE(receive_time)='$today' GROUP BY alert_name ORDER BY cnt DESC LIMIT 10"; + $list = []; + $q = mysqli_query($conn, $sql); + while ($r = mysqli_fetch_assoc($q)) $list[] = $r; + echo json_encode($list, JSON_UNESCAPED_UNICODE); + exit; +} + +// 3. 今日全量告警明细表格 +if ($act === "log_list") { + $sql = "SELECT alert_type,alert_name,instance,severity,starts_at,ends_at,receive_time + FROM alert_log WHERE DATE(receive_time)='$today' ORDER BY receive_time DESC"; + $list = []; + $q = mysqli_query($conn, $sql); + while ($r = mysqli_fetch_assoc($q)) $list[] = $r; + echo json_encode($list, JSON_UNESCAPED_UNICODE); + exit; +} + +// 4. 全局跨天未恢复告警(过滤整条下线规则,单实例仅靠恢复日志隐藏) +if ($act === "active_firing") { + $maxSql = "SELECT alert_name,instance,MAX(receive_time) max_rt FROM alert_log GROUP BY alert_name,instance"; + $maxRes = mysqli_query($conn, $maxSql); + $activeList = []; + while ($maxRow = mysqli_fetch_assoc($maxRes)) { + $an = $conn->real_escape_string($maxRow['alert_name']); + $ins = $conn->real_escape_string($maxRow['instance']); + $mrt = $conn->real_escape_string($maxRow['max_rt']); + + // 判断该规则是否整条下线,下线直接跳过 + $ruleCheck = mysqli_query($conn, "SELECT status FROM monitor_rule WHERE rule_name='$an' LIMIT 1"); + $ruleStatus = 1; + if($ruleCheck && $ruleRow = mysqli_fetch_assoc($ruleCheck)){ + $ruleStatus = intval($ruleRow['status']); + } + if($ruleStatus === 0){ + continue; + } + + $rowSql = "SELECT alert_name,instance,severity,starts_at,receive_time,alert_type + FROM alert_log + WHERE alert_name='$an' AND instance='$ins' AND receive_time='$mrt'"; + $rowRes = mysqli_query($conn, $rowSql); + $data = mysqli_fetch_assoc($rowRes); + if ($data && (int)$data['alert_type'] === 1) { + $activeList[] = $data; + } + } + echo json_encode($activeList, JSON_UNESCAPED_UNICODE); + exit; +} + +// 非法请求兜底 +echo json_encode(["code" => 400, "msg" => "无效请求参数act"], JSON_UNESCAPED_UNICODE); +mysqli_close($conn); +?> diff --git a/api/index.php最早版 b/api/index.php最早版 new file mode 100644 index 0000000..1d6ecb3 --- /dev/null +++ b/api/index.php最早版 @@ -0,0 +1,46 @@ + diff --git a/api/login.php b/api/login.php new file mode 100644 index 0000000..ba53471 --- /dev/null +++ b/api/login.php @@ -0,0 +1,12 @@ +200,"token"=>"alert_".md5(time().uniqid())]); +}else{ + echo json_encode(["code"=>400,"msg"=>"密码错误"]); +} diff --git a/api/oldapi.php b/api/oldapi.php new file mode 100644 index 0000000..9191938 --- /dev/null +++ b/api/oldapi.php @@ -0,0 +1,126 @@ + 500, "msg" => "数据库连接失败:" . mysqli_connect_error()], JSON_UNESCAPED_UNICODE); + exit; +} +$today = date("Y-m-d"); + +// 1.今日统计卡片 +if ($act === "day_total") { + $sql = "SELECT + SUM(IF(alert_type=1,1,0)) as fire_count, + SUM(IF(alert_type=2,1,0)) as resolve_count, + COUNT(DISTINCT instance) as instance_num + FROM alert_log WHERE DATE(receive_time) = '$today'"; + $data = mysqli_fetch_assoc(mysqli_query($conn, $sql)); + echo json_encode($data, JSON_UNESCAPED_UNICODE); + mysqli_close($conn); + exit; +} + +// 2.今日告警TOP10图表 +if ($act === "top_alert") { + $sql = "SELECT alert_name,COUNT(*) cnt FROM alert_log WHERE DATE(receive_time)='$today' GROUP BY alert_name ORDER BY cnt DESC LIMIT 10"; + $list = []; + $q = mysqli_query($conn, $sql); + while ($r = mysqli_fetch_assoc($q)) $list[] = $r; + echo json_encode($list, JSON_UNESCAPED_UNICODE); + mysqli_close($conn); + exit; +} + +// 3.今日全量告警明细 +if ($act === "log_list") { + $sql = "SELECT alert_type,alert_name,instance,severity,starts_at,ends_at,receive_time + FROM alert_log WHERE DATE(receive_time)='$today' ORDER BY receive_time DESC"; + $list = []; + $q = mysqli_query($conn, $sql); + while ($r = mysqli_fetch_assoc($q)) $list[] = $r; + echo json_encode($list, JSON_UNESCAPED_UNICODE); + mysqli_close($conn); + exit; +} + +// 4.全局跨天未恢复告警(修复版,取每组最新一条判断状态) +if ($act === "active_firing") { + $maxSql = "SELECT alert_name,instance,MAX(receive_time) max_rt FROM alert_log GROUP BY alert_name,instance"; + $maxRes = mysqli_query($conn, $maxSql); + $activeList = []; + while ($row = mysqli_fetch_assoc($maxRes)) { + $an = mysqli_real_escape_string($conn, $row['alert_name']); + $ins = mysqli_real_escape_string($conn, $row['instance']); + $rt = mysqli_real_escape_string($conn, $row['max_rt']); + $sql = "SELECT alert_name,instance,severity,starts_at,receive_time,alert_type + FROM alert_log WHERE alert_name='$an' AND instance='$ins' AND receive_time='$rt' LIMIT 1"; + $one = mysqli_fetch_assoc(mysqli_query($conn, $sql)); + if ($one && (int)$one['alert_type'] === 1) { + $activeList[] = $one; + } + } + echo json_encode($activeList, JSON_UNESCAPED_UNICODE); + mysqli_close($conn); + exit; +} + +// 非法act +echo json_encode(["code" => 400, "msg" => "无效请求参数act"], JSON_UNESCAPED_UNICODE); +mysqli_close($conn); +?> diff --git a/api/panel.php b/api/panel.php new file mode 100644 index 0000000..1ba07ee --- /dev/null +++ b/api/panel.php @@ -0,0 +1,440 @@ + $expire)) { + session_destroy(); + header("Location: ../login.php"); + exit; +} +// 刷新登录时间 +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; +?> + + + + + +开发者调试面板 - Advantest 运维告警监控平台 + + + + + + +
+
+
+
开发者调试面板
+
全部告警接口可视化调用 · 后端API调试工具
+
+
+
+ + + + +
+
+ +
+ +
+

1. 临时隐藏单实例告警 clear_single_instance

+
+ + + + + +
+
仅插入恢复日志,下次故障自动重新展示;instance冒号无需手动编码,JS自动处理
+
+ + +
+

2. 永久屏蔽单实例 offline_single_instance

+
+ + + + + +
+
修改monitor_rule状态0,不执行恢复接口则永久不展示该实例告警
+
+ + +
+

3. 恢复单实例 restore_single_instance

+
+ + + + + +
+
解除单实例永久屏蔽状态,新故障会正常展示
+
+ + +
+

4. 整条规则全部下线 clear_offline_rule

+
+ + + +
+
+ + +
+

5. 恢复整条规则 restore_rule

+
+ + + +
+
+ + +
+

6. 删除单实例所有告警日志 delete_single_instance_log

+
+ + + + + +
+
+ + +
+

7. 手动同步Prometheus告警(清除脏恢复记录)

+
+ +
+
自动删除故障中残留的手动恢复记录,修复前端“故障存在但页面不显示”bug
+
+ + +
+

8. 数据查询接口(获取面板原始数据)

+
+ + + + +
+
+ + +
+

9. 导出告警CSV报表

+ + +
+ + + +
+
不选择日期默认导出今日告警;选择历史日期下载单日报表
+ + +
+ + + + + +
+
填写开始、结束日期,导出该时间段全部告警数据
+
+ + +
+

接口返回结果(JSON)

+
等待执行接口操作...
+
+
+ + + + diff --git a/api/panel.php.2 b/api/panel.php.2 new file mode 100644 index 0000000..5483cf1 --- /dev/null +++ b/api/panel.php.2 @@ -0,0 +1,411 @@ + $expire)) { + session_destroy(); + header("Location: ../login.php"); + exit; +} +// 刷新登录时间 +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; +?> + + + + + +开发者调试面板 - Advantest 运维告警监控平台 + + + + + + +
+
+
+
开发者调试面板
+
全部告警接口可视化调用 · 后端API调试工具
+
+
+
+ + + + +
+
+ +
+ +
+

1. 临时隐藏单实例告警 clear_single_instance

+
+ + + + + +
+
仅插入恢复日志,下次故障自动重新展示;instance冒号无需手动编码,JS自动处理
+
+ + +
+

2. 永久屏蔽单实例 offline_single_instance

+
+ + + + + +
+
修改monitor_rule状态0,不执行恢复接口则永久不展示该实例告警
+
+ + +
+

3. 恢复单实例 restore_single_instance

+
+ + + + + +
+
解除单实例永久屏蔽状态,新故障会正常展示
+
+ + +
+

4. 整条规则全部下线 clear_offline_rule

+
+ + + +
+
+ + +
+

5. 恢复整条规则 restore_rule

+
+ + + +
+
+ + +
+

6. 删除单实例所有告警日志 delete_single_instance_log

+
+ + + + + +
+
+ + +
+

7. 手动同步Prometheus告警(清除脏恢复记录)

+
+ +
+
自动删除故障中残留的手动恢复记录,修复前端“故障存在但页面不显示”bug
+
+ + +
+

8. 数据查询接口(获取面板原始数据)

+
+ + + + +
+
+ + +
+

9. 导出告警CSV报表(支持历史日期)

+
+ + + +
+
不选择日期默认导出今日告警;选择历史日期可下载过往报表
+
+ + +
+

接口返回结果(JSON)

+
等待执行接口操作...
+
+
+ + + + diff --git a/api/subscribe_api.php b/api/subscribe_api.php new file mode 100644 index 0000000..400d569 --- /dev/null +++ b/api/subscribe_api.php @@ -0,0 +1,89 @@ + 0, 'msg' => 'ok'])); +} + +// 数据库配置 +$dbHost = '127.0.0.1'; +$dbUser = 'root'; +$dbPwd = 'hp93000'; +$dbName = 'monitor'; + +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + echo json_encode(['code' => 401, 'msg' => '登录失效,请重新登录']); + exit; +} +$uid = $_SESSION['user_id']; + +$conn = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +if (!$conn) { + echo json_encode(['code' => 500, 'msg' => '数据库连接失败:' . mysqli_connect_error()]); + exit; +} +mysqli_set_charset($conn, 'utf8mb4'); + +$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : ''; + +// 获取当前用户订阅配置 +if ($action === 'get_subscribe') { + $sql = "SELECT * FROM alert_subscribe WHERE uid = ? LIMIT 1"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 's', $uid); + mysqli_stmt_execute($stmt); + $res = mysqli_stmt_get_result($stmt); + $data = mysqli_fetch_assoc($res); + if (empty($data)) { + $data = [ + 'severity' => '', + 'instance' => '', + 'alertname' => '', + 'dingtalk_webhook' => '', + 'wecom_webhook' => '', + 'mail_receiver' => '', + 'enable' => 0 + ]; + } + echo json_encode(['code' => 0, 'msg' => 'ok', 'data' => $data], JSON_UNESCAPED_UNICODE); + exit; +} + +// 保存/更新订阅配置 +if ($action === 'save_subscribe') { + $post = json_decode(file_get_contents('php://input'), true); + $severity = $post['severity'] ?? ''; + $instance = $post['instance'] ?? ''; + $alertname = $post['alertname'] ?? ''; + $dingtalk = $post['dingtalk_webhook'] ?? ''; + $wecom = $post['wecom_webhook'] ?? ''; + $mail = $post['mail_receiver'] ?? ''; + $enable = intval($post['enable'] ?? 0); + + $check = mysqli_query($conn, "SELECT id FROM alert_subscribe WHERE uid = '$uid' LIMIT 1"); + if (mysqli_num_rows($check) > 0) { + $sql = "UPDATE alert_subscribe SET severity=?,instance=?,alertname=?,dingtalk_webhook=?,wecom_webhook=?,mail_receiver=?,enable=? WHERE uid=?"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'ssssssis', $severity, $instance, $alertname, $dingtalk, $wecom, $mail, $enable, $uid); + } else { + $sql = "INSERT INTO alert_subscribe(uid,severity,instance,alertname,dingtalk_webhook,wecom_webhook,mail_receiver,enable) VALUES (?,?,?,?,?,?,?,?)"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'ssssssss', $uid, $severity, $instance, $alertname, $dingtalk, $wecom, $mail, $enable); + } + $ok = mysqli_stmt_execute($stmt); + if ($ok) { + echo json_encode(['code' => 0, 'msg' => '订阅配置保存成功'], JSON_UNESCAPED_UNICODE); + } else { + echo json_encode(['code' => 500, 'msg' => '保存失败:' . mysqli_error($conn)], JSON_UNESCAPED_UNICODE); + } + exit; +} + +echo json_encode(['code' => 400, 'msg' => '无效操作']); +mysqli_close($conn); +exit; +?> diff --git a/api/subscribe_api.php.bak b/api/subscribe_api.php.bak new file mode 100644 index 0000000..57da751 --- /dev/null +++ b/api/subscribe_api.php.bak @@ -0,0 +1,130 @@ + 0, 'msg' => 'ok'])); +} + +// 数据库配置 +$dbHost = '10.150.117.190'; +$dbUser = 'root'; +$dbPwd = 'hp93000'; +$dbName = 'monitor'; + +// 登录会话校验(和你原有登录体系一致) +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + echo json_encode(['code' => 401, 'msg' => '登录失效,请重新登录']); + exit; +} +$uid = $_SESSION['user_id']; + +// 连接数据库 +$conn = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +if (!$conn) { + echo json_encode(['code' => 500, 'msg' => '数据库连接失败:' . mysqli_connect_error()]); + exit; +} +mysqli_set_charset($conn, 'utf8mb4'); + +$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : ''; + +// 1、获取当前用户订阅配置 +if ($action === 'get_subscribe') { + $sql = "SELECT * FROM alert_subscribe WHERE uid = ? LIMIT 1"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 's', $uid); + mysqli_stmt_execute($stmt); + $res = mysqli_stmt_get_result($stmt); + $data = mysqli_fetch_assoc($res); + if (empty($data)) { + $data = [ + 'severity' => '', + 'instance' => '', + 'alertname' => '', + 'dingtalk_webhook' => '', + 'wecom_webhook' => '', + 'mail_receiver' => '', + 'enable' => 0 + ]; + } + echo json_encode(['code' => 0, 'msg' => 'ok', 'data' => $data], JSON_UNESCAPED_UNICODE); + exit; +} + +// 2、保存/更新订阅配置 +if ($action === 'save_subscribe') { + $post = json_decode(file_get_contents('php://input'), true); + $severity = $post['severity'] ?? ''; + $instance = $post['instance'] ?? ''; + $alertname = $post['alertname'] ?? ''; + $dingtalk = $post['dingtalk_webhook'] ?? ''; + $wecom = $post['wecom_webhook'] ?? ''; + $mail = $post['mail_receiver'] ?? ''; + $enable = intval($post['enable'] ?? 0); + + // 判断是否已有记录 + $check = mysqli_query($conn, "SELECT id FROM alert_subscribe WHERE uid = '$uid' LIMIT 1"); + if (mysqli_num_rows($check) > 0) { + $sql = "UPDATE alert_subscribe SET severity=?,instance=?,alertname=?,dingtalk_webhook=?,wecom_webhook=?,mail_receiver=?,enable=? WHERE uid=?"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'ssssssis', $severity, $instance, $alertname, $dingtalk, $wecom, $mail, $enable, $uid); + } else { + $sql = "INSERT INTO alert_subscribe(uid,severity,instance,alertname,dingtalk_webhook,wecom_webhook,mail_receiver,enable) VALUES (?,?,?,?,?,?,?,?)"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'ssssssss', $uid, $severity, $instance, $alertname, $dingtalk, $wecom, $mail, $enable); + } + $ok = mysqli_stmt_execute($stmt); + if ($ok) { + echo json_encode(['code' => 0, 'msg' => '订阅配置保存成功'], JSON_UNESCAPED_UNICODE); + } else { + echo json_encode(['code' => 500, 'msg' => '保存失败:' . mysqli_error($conn)], JSON_UNESCAPED_UNICODE); + } + exit; +} + +// 3、分页查询推送日志 +if ($action === 'list_push_log') { + $page = isset($_REQUEST['page']) ? intval($_REQUEST['page']) : 1; + $pageSize = isset($_REQUEST['page_size']) ? intval($_REQUEST['page_size']) : 10; + $offset = ($page - 1) * $pageSize; + + // 总条数 + $cntSql = "SELECT COUNT(*) as total FROM alert_push_log WHERE uid = ?"; + $stmtCnt = mysqli_prepare($conn, $cntSql); + mysqli_stmt_bind_param($stmtCnt, 's', $uid); + mysqli_stmt_execute($stmtCnt); + $cntRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtCnt)); + $total = $cntRow['total']; + + // 分页数据 + $sql = "SELECT * FROM alert_push_log WHERE uid = ? ORDER BY push_time DESC LIMIT ?,?"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'sii', $uid, $offset, $pageSize); + mysqli_stmt_execute($stmt); + $res = mysqli_stmt_get_result($stmt); + $list = []; + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + echo json_encode([ + 'code' => 0, + 'msg' => 'ok', + 'data' => [ + 'list' => $list, + 'page' => $page, + 'page_size' => $pageSize, + 'total' => $total, + 'pages' => ceil($total / $pageSize) + ] + ], JSON_UNESCAPED_UNICODE); + exit; +} + +// 无匹配操作 +echo json_encode(['code' => 400, 'msg' => '无效操作']); +mysqli_close($conn); +exit; diff --git a/api/system_config.json b/api/system_config.json new file mode 100644 index 0000000..60e4f30 --- /dev/null +++ b/api/system_config.json @@ -0,0 +1,14 @@ +{ + "theme_color": "#152c5b", + "card_bg": "#ffffff", + "body_bg": "#f9fafc", + "font_family": "Inter,PingFang SC,Microsoft YaHei", + "sidebar_links": [ + { + "icon": "fa-github", + "title": "运维监控中心", + "url": "http://10.150.117.190:3000/d/linux-server-alert-fix-startsat/linux-fu-wu-qi-gao-jing-zhong-xin?orgId=1&refresh=10s", + "target": "_blank" + } + ] +} diff --git a/api/user_info.json b/api/user_info.json new file mode 100644 index 0000000..88b53e2 --- /dev/null +++ b/api/user_info.json @@ -0,0 +1,6 @@ +{ + "user_id": "admin001", + "username": "admin", + "role": "admin", + "password": "e10adc3949ba59abbe56e057f20f883e" +} diff --git a/api/user_pass.php b/api/user_pass.php new file mode 100644 index 0000000..3e16731 --- /dev/null +++ b/api/user_pass.php @@ -0,0 +1,35 @@ + $expire)) { + echo json_encode(["code"=>401,"msg"=>"未登录"]); + exit; +} +header("Content-Type:application/json;charset=utf-8"); +$userFile = "./user_info.json"; +if(!file_exists($userFile)){ + echo json_encode(["code"=>500,"msg"=>"账号配置文件缺失"]); + exit; +} +$userData = json_decode(file_get_contents($userFile),true); +$act = $_POST['act'] ?? ''; + +if($act == "change_pwd"){ + $old = $_POST['old_pwd']; + $new = $_POST['new_pwd']; + $confirm = $_POST['confirm_pwd']; + if($userData['password'] != md5($old)){ + echo json_encode(["code"=>400,"msg"=>"原密码错误"]); + exit; + } + if($new != $confirm){ + echo json_encode(["code"=>400,"msg"=>"两次新密码不一致"]); + exit; + } + $userData['password'] = md5($new); + file_put_contents($userFile,json_encode($userData,JSON_UNESCAPED_UNICODE)); + echo json_encode(["code"=>0,"msg"=>"密码修改成功,请重新登录"]); + exit; +} +echo json_encode(["code"=>400,"msg"=>"非法操作"]); +?> diff --git a/api/webhook.php b/api/webhook.php new file mode 100644 index 0000000..75454a3 --- /dev/null +++ b/api/webhook.php @@ -0,0 +1,64 @@ + 500, + "msg" => "数据库连接失败:" . mysqli_connect_error() + ], JSON_UNESCAPED_UNICODE); + exit; +} +mysqli_set_charset($conn,"utf8mb4"); + +$rawBody = file_get_contents('php://input'); +$alertData = json_decode($rawBody, true); + +if (!is_array($alertData) || empty($alertData['alerts'])) { + echo json_encode([ + "code" => 400, + "msg" => "未获取到有效告警数据" + ], JSON_UNESCAPED_UNICODE); + mysqli_close($conn); + exit; +} + +$insertCount = 0; +foreach ($alertData['alerts'] as $alert) { + $alertName = mysqli_real_escape_string($conn, $alert['labels']['alertname'] ?? "未知告警"); + $instance = mysqli_real_escape_string($conn, $alert['labels']['instance'] ?? ""); + $severity = mysqli_real_escape_string($conn, $alert['labels']['severity'] ?? "warning"); + $status = $alert['status'] ?? "firing"; + $startsAt = mysqli_real_escape_string($conn, $alert['startsAt'] ?? date("Y-m-d H:i:s")); + $endsAt = isset($alert['endsAt']) ? "'" . mysqli_real_escape_string($conn, $alert['endsAt']) . "'" : "NULL"; + $fingerprint= mysqli_real_escape_string($conn, $alert['fingerprint'] ?? md5($alertName.$instance.$startsAt)); + $content = mysqli_real_escape_string($conn, json_encode($alert, JSON_UNESCAPED_UNICODE)); + $alertType = $status === "resolved" ? 2 : 1; + + $checkSql = "SELECT id FROM alert_log WHERE mail_uid = '$fingerprint'"; + $checkRes = mysqli_query($conn, $checkSql); + if (mysqli_num_rows($checkRes) > 0) continue; + + $insertSql = "INSERT INTO alert_log + (mail_uid, alert_type, alert_name, instance, severity, starts_at, ends_at, content, receive_time) + VALUES ('$fingerprint', $alertType, '$alertName', '$instance', '$severity', '$startsAt', $endsAt, '$content', NOW())"; + + if (mysqli_query($conn, $insertSql)) $insertCount++; +} + +echo json_encode([ + "code" => 200, + "msg" => "告警处理完成", + "insert_num" => $insertCount +], JSON_UNESCAPED_UNICODE); + +mysqli_close($conn); +?> diff --git a/api/work_order_api.php b/api/work_order_api.php new file mode 100644 index 0000000..f71add0 --- /dev/null +++ b/api/work_order_api.php @@ -0,0 +1,528 @@ + 0, 'msg' => 'ok']); + exit; +} +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time']) > $expire) { + echo json_encode(['code' => 401, 'msg' => '登录失效']); + exit; +} +$loginUid = $_SESSION['user_id']; + +// 工单业务库 monitor +$dbWorkHost = '10.150.117.190'; +$dbWorkUser = 'root'; +$dbWorkPwd = 'hp93000'; +$dbWorkName = 'monitor'; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + echo json_encode(['code' => 500, 'msg' => '工单数据库连接失败:' . mysqli_connect_error()]); + exit; +} +mysqli_set_charset($connWork, 'utf8mb4'); + +// 配置库 alert_mail_stat(告警、通知配置统一此处) +$dbConfHost = "10.150.117.190"; +$dbConfUser = "root"; +$dbConfPwd = "hp93000"; +$dbConfName = "alert_mail_stat"; +$connConf = mysqli_connect($dbConfHost, $dbConfUser, $dbConfPwd, $dbConfName); +if(!$connConf){ + echo json_encode(['code' => 500, 'msg' => '配置库连接失败']); + exit; +} +mysqli_set_charset($connConf, "utf8mb4"); + +// 获取当前用户角色权限 +$isAdmin = 0; +$permList = ""; +$roleId = 0; +$roleSql = "SELECT r.is_admin, r.perm_list, u.role_id FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRes = mysqli_stmt_get_result($stmtRole); +$roleRow = $roleRes ? mysqli_fetch_assoc($roleRes) : []; +if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; + $roleId = intval($roleRow['role_id'] ?? 0); +} + +// 读取当前角色页面权限列表(用于分发工单权限判断) +$allowPages = []; +if ($roleId > 0) { + $permSql = "SELECT page_key FROM sys_role_permission WHERE role_id = ?"; + $stmtPerm = mysqli_prepare($connWork, $permSql); + mysqli_stmt_bind_param($stmtPerm, 'i', $roleId); + mysqli_stmt_execute($stmtPerm); + $pRes = mysqli_stmt_get_result($stmtPerm); + while ($p = mysqli_fetch_assoc($pRes)) { + $allowPages[] = $p['page_key']; + } +} + +$action = $_REQUEST['action'] ?? ''; +$post = json_decode(file_get_contents("php://input"), true) ?: []; + +// ===================== 工单列表查询 ===================== +if ($action === "get_list") { + $page = intval($_GET['page'] ?? 1); + $size = intval($_GET['size'] ?? 20); + $offset = ($page - 1) * $size; + $status = trim($_GET['status'] ?? ''); + $keyword = trim($_GET['keyword'] ?? ''); + + $where = []; + $param = []; + $paramType = ''; + + // 全部用户查看全部工单,不再按uid过滤 + $whereSql = "1=1"; + + if ($status !== '') { + $where[] = "status = ?"; + $param[] = $status; + $paramType .= 'i'; + } + if ($keyword !== '') { + $where[] = "(title LIKE ? OR content LIKE ?)"; + $param[] = "%$keyword%"; + $param[] = "%$keyword%"; + $paramType .= 'ss'; + } + + if (!empty($where)) { + $whereSql = "WHERE " . implode(" AND ", $where); + } + + // 分页列表,LEFT JOIN 认领人姓名 + $listSql = "SELECT wo.*, uu.real_name claim_name +FROM work_order wo +LEFT JOIN sys_user uu ON wo.claim_uid = uu.uid +$whereSql ORDER BY create_time DESC LIMIT ?,?"; + $param[] = $offset; + $param[] = $size; + $paramType .= 'ii'; + + $stmtList = mysqli_prepare($connWork, $listSql); + mysqli_stmt_bind_param($stmtList, $paramType, ...$param); + mysqli_stmt_execute($stmtList); + $res = mysqli_stmt_get_result($stmtList); + $list = []; + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + + // 总数统计 + $countSql = "SELECT COUNT(id) total FROM work_order $whereSql"; + $stmtCount = mysqli_prepare($connWork, $countSql); + array_pop($param); + array_pop($param); + $paramTypeCount = rtrim($paramType, 'ii'); + if ($paramTypeCount) { + mysqli_stmt_bind_param($stmtCount, $paramTypeCount, ...$param); + } + mysqli_stmt_execute($stmtCount); + $countRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtCount)); + $total = intval($countRow['total']); + + echo json_encode([ + 'code' => 0, + 'list' => $list, + 'total' => $total, + 'page' => $page, + 'size' => $size + ], JSON_UNESCAPED_UNICODE); + exit; +} + +// ===================== 根据告警ID查询关联工单 ===================== +if ($action === "get_workorder_by_alertid") { + $alertId = trim($_GET['alert_id'] ?? ''); + if (empty($alertId)) { + echo json_encode(['code' => 400, 'msg' => '缺少告警ID参数']); + exit; + } + $alertEsc = mysqli_real_escape_string($connWork, $alertId); + $sql = "SELECT id,title,status,assign_uid,create_time FROM work_order WHERE relate_alert_id = ? ORDER BY create_time DESC"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 's', $alertEsc); + mysqli_stmt_execute($stmt); + $res = mysqli_stmt_get_result($stmt); + $list = []; + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + echo json_encode(['code' => 0, 'list' => $list]); + exit; +} + +// ===================== 自动同步告警状态,批量更新工单为已完成 ===================== +if ($action === "auto_sync_workorder_status") { + $resolveSql = "SELECT DISTINCT CONCAT(alert_name,'_',instance) as alert_id FROM alert_log WHERE alert_type=2"; + $resolveRes = mysqli_query($connConf, $resolveSql); + $resolveAlertIds = []; + while ($row = mysqli_fetch_assoc($resolveRes)) { + $resolveAlertIds[] = $row['alert_id']; + } + if (empty($resolveAlertIds)) { + echo json_encode(['code' => 0, 'msg' => '暂无已恢复告警,无需更新工单', 'update_count' => 0]); + exit; + } + + $inStr = implode("','", array_map(function($v) use ($connWork) { + return mysqli_real_escape_string($connWork, $v); + }, $resolveAlertIds)); + $updateSql = "UPDATE work_order SET status=3,update_time=NOW() WHERE relate_alert_id IN ('$inStr') AND status IN (1,2)"; + mysqli_query($connWork, $updateSql); + $updateCnt = mysqli_affected_rows($connWork); + + echo json_encode([ + 'code' => 0, + 'msg' => '工单状态自动同步完成,已恢复告警绑定工单全部置为已完成', + 'update_count' => $updateCnt + ], JSON_UNESCAPED_UNICODE); + exit; +} + +// 1、获取实时活跃告警(alert_mail_stat.alert_firing 数据源) +if ($action === "get_firing_alert") { + $alertSql = "SELECT alert_id,alert_name,instance FROM alert_firing WHERE status='firing' ORDER BY receive_time DESC LIMIT 100"; + $res = mysqli_query($connConf, $alertSql); + $list = []; + if($res instanceof mysqli_result){ + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + } + echo json_encode(['code' => 0, 'list' => $list]); + exit; +} + +// 2、新建工单 +if ($action === "create") { + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $relateAlertId = trim($post['relate_alert_id'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + $status = 1; + + if (!$title || !$content) { + echo json_encode(['code' => 400, 'msg' => '标题和内容不能为空']); + exit; + } + + if (!empty($relateAlertId)) { + $alertEsc = mysqli_real_escape_string($connConf, $relateAlertId); + $checkResolveSql = "SELECT 1 FROM alert_log WHERE CONCAT(alert_name,'_',instance) = ? AND alert_type=2 LIMIT 1"; + $stmtCheck = mysqli_prepare($connConf, $checkResolveSql); + mysqli_stmt_bind_param($stmtCheck, 's', $alertEsc); + mysqli_stmt_execute($stmtCheck); + $checkRes = mysqli_stmt_get_result($stmtCheck); + if (mysqli_num_rows($checkRes) > 0) { + $status = 3; + } + } + + // 新建工单默认无认领人 claim_uid='' + $sql = "INSERT INTO work_order(title,content,create_uid,assign_uid,relate_alert_id,notify_user,notify_channel,status,is_read,claim_uid,create_time,update_time) VALUES (?,?,?,?,?,?,?,?,?, '',NOW(),NOW())"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ssssssss', $title, $content, $loginUid, $assign, $relateAlertId, $notifyUser, $notifyChannel, $status); + $ok = mysqli_stmt_execute($stmt); + if (!$ok) { + echo json_encode(['code' => 500, 'msg' => '创建失败:' . mysqli_error($connWork)]); + exit; + } + $orderId = mysqli_insert_id($connWork); + sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单提交成功,通知已下发', 'init_status' => $status]); + exit; +} + +// ========== 新增:工单认领接口 claim_work ========== +if ($action === "claim_work") { + $id = intval($post['id'] ?? 0); + $uid = trim($post['uid'] ?? ''); + if ($id <= 0 || empty($uid)) { + echo json_encode(["code" => 400, "msg" => "参数错误"]); + exit; + } + // 校验工单未被认领 + $chkSql = "SELECT id FROM work_order WHERE id=? AND (claim_uid IS NULL OR claim_uid = '')"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'i', $id); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if(mysqli_num_rows($chkRes) === 0){ + echo json_encode(["code" => 400, "msg" => "该工单已被他人认领,无法重复认领"]); + exit; + } + $updateSql = "UPDATE work_order SET claim_uid=?, claim_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $updateSql); + mysqli_stmt_bind_param($stmt, 'si', $uid, $id); + $ok = mysqli_stmt_execute($stmt); + if($ok){ + echo json_encode(["code" => 0, "msg" => "工单认领成功,现在你可以编辑处理"]); + }else{ + echo json_encode(["code" => 500, "msg" => "认领失败:".mysqli_error($connWork)]); + } + exit; +} + +// 3、编辑工单(权限:管理员 或 当前用户是认领人) +if ($action === "edit") { + $id = intval($post['id'] ?? 0); + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $relateAlertId = trim($post['relate_alert_id'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + if ($id <= 0 || empty($title) || empty($content)) { + echo json_encode(['code' => 400, 'msg' => '参数不能为空']); + exit; + } + // 权限重写 + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND claim_uid=?"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'is', $id, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '仅工单认领人可编辑']); + exit; + } + } + $sql = "UPDATE work_order SET title=?,content=?,assign_uid=?,relate_alert_id=?,notify_user=?,notify_channel=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ssssssi', $title, $content, $assign, $relateAlertId, $notifyUser, $notifyChannel, $id); + mysqli_stmt_execute($stmt); + sendWorkOrderNotify($connConf, $connWork, $id, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单保存成功,通知已更新下发']); + exit; +} + +// 4、修改工单状态(权限:管理员 或 当前用户是认领人) +if ($action === "update_status") { + $id = intval($post['id'] ?? 0); + $status = intval($post['status'] ?? 1); + if ($id <= 0) { + echo json_encode(['code' => 400, 'msg' => '工单ID错误']); + exit; + } + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND claim_uid=?"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'is', $id, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '仅工单认领人可修改状态']); + exit; + } + } + $sql = "UPDATE work_order SET status=?,is_read=1,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ii', $status, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '状态更新成功']); + exit; +} + +// 5、管理员/拥有system_manage权限角色 分发工单 +if ($action === "assign") { + if ($isAdmin !== 1 && !in_array("system_manage", $allowPages)) { + echo json_encode(['code' => 403, 'msg' => '无工单分发权限,请联系管理员']); + exit; + } + $id = intval($post['id'] ?? 0); + $assignUid = trim($post['assign_uid'] ?? ''); + $sql = "UPDATE work_order SET assign_uid=?,is_read=0,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'si', $assignUid, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单分发成功']); + exit; +} + +// 一键标记当前用户全部待处理工单为已读 +if ($action === 'mark_all_read') { + $uid = $post['uid'] ?? ''; + $sql = "UPDATE work_order SET is_read=1 WHERE assign_uid=? AND status=1"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, "s", $uid); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '已全部标记为已读']); + exit; +} + +// 语言切换 +if ($action === 'save_lang') { + $lang = $post['lang'] ?? 'zh'; + $sql = "UPDATE sys_config SET v=? WHERE k='lang'"; + $stmt = mysqli_prepare($connConf, $sql); + mysqli_stmt_bind_param($stmt, "s", $lang); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '成功']); + exit; +} + +// 同步Prometheus实时告警,自动清理恢复告警 +if ($action === "sync_prom_alerts") { + $promUrl = "http://10.150.117.190:9090/api/v1/alerts"; + $resp = @file_get_contents($promUrl); + if($resp === false){ + echo json_encode(["code"=>500,"msg"=>"无法连接Prometheus接口"],JSON_UNESCAPED_UNICODE); + exit; + } + $promData = json_decode($resp,true); + if(!isset($promData['data']['alerts'])){ + echo json_encode(["code"=>500,"msg"=>"Prometheus返回数据异常"],JSON_UNESCAPED_UNICODE); + exit; + } + + mysqli_query($connConf,"UPDATE alert_firing SET status='resolved'"); + + $alerts = $promData['data']['alerts'] ?? []; + foreach($alerts as $item){ + $alertName = $item['labels']['alertname'] ?? "unknown"; + $instance = $item['labels']['instance'] ?? "unknown"; + $alertId = $alertName."_".$instance; + $sql = "INSERT INTO alert_firing(alert_id,alert_name,instance,status,receive_time) VALUES (?,?,?,'firing',NOW()) ON DUPLICATE KEY UPDATE status='firing',receive_time=NOW()"; + $stmt = mysqli_prepare($connConf,$sql); + mysqli_stmt_bind_param($stmt,"sss",$alertId,$alertName,$instance); + mysqli_stmt_execute($stmt); + } + $syncNum = count($alerts); + + $syncWorkUrl = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'] . "?action=auto_sync_workorder_status"; + @file_get_contents($syncWorkUrl); + + echo json_encode([ + "code"=>0, + "msg"=>"Prometheus告警同步完成,已自动同步工单状态", + "active_alert_total"=>$syncNum + ],JSON_UNESCAPED_UNICODE); + exit; +} + +// 定时同步:告警恢复自动完工单 +if($action === "sync_alert_auto_close"){ + $alertApi = "./index.php?act=active_firing"; + $raw = @file_get_contents($alertApi); + $activeList = json_decode($raw, true) ?: []; + $activeKeys = []; + foreach($activeList as $item){ + $activeKeys[] = $item['alert_name'] . "_" . $item['instance']; + } + $sql = "SELECT id, relate_alert_id FROM work_order WHERE status IN(1,2) AND relate_alert_id <> ''"; + $res = mysqli_query($connWork, $sql); + while($row = mysqli_fetch_assoc($res)){ + if(!in_array($row['relate_alert_id'], $activeKeys)){ + $updateSql = "UPDATE work_order SET status=3, update_time=NOW() WHERE id = ".(int)$row['id']; + mysqli_query($connWork, $updateSql); + } + } + echo json_encode(['code'=>0, 'msg'=>'同步完成']); + exit; +} + +// ==================== 全局通知统一函数 ==================== +function sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUserStr, $channelStr) +{ + if (empty($notifyUserStr) || empty($channelStr)) return; + $userArr = explode(",", $notifyUserStr); + $channelArr = explode(",", $channelStr); + + $cfgRes = mysqli_query($connConf, "SELECT * FROM sys_smtp_config WHERE id=1"); + $notifyCfg = $cfgRes ? mysqli_fetch_assoc($cfgRes) : []; + if(empty($notifyCfg)) return; + + $orderRes = mysqli_query($connWork, "SELECT * FROM work_order WHERE id=$orderId"); + $order = $orderRes ? mysqli_fetch_assoc($orderRes) : []; + $title = $order['title']; + $content = $order['content']; + $relateId = $order['relate_alert_id'] ?: "无"; + + $msgText = "【运维工单通知】\n工单ID:$orderId\n关联告警:$relateId\n标题:$title\n详情:$content"; + + foreach ($channelArr as $ch) { + $ch = trim($ch); + switch ($ch) { + case "mail": + sendMailNotify($notifyCfg, $connWork, $userArr, $title, $content, $relateId, $orderId); + break; + case "dingtalk": + sendDingNotify($notifyCfg, $msgText); + break; + case "wecom": + sendWecomNotify($notifyCfg, $msgText); + break; + } + } +} + +// 邮件发送 +function sendMailNotify($smtp, $connWork, $uidList, $title, $content, $relateId, $orderId) +{ + if (empty($smtp['smtp_host']) || empty($smtp['smtp_account'])) return; + $emailList = []; + foreach ($uidList as $uid) { + $uid = trim($uid); + if (empty($uid)) continue; + $res = mysqli_query($connWork, "SELECT email FROM sys_user WHERE uid='$uid'"); + $u = mysqli_fetch_assoc($res); + if (!empty($u['email'])) $emailList[] = $u['email']; + } + if (empty($emailList)) return; + $to = implode(",", array_unique($emailList)); + $subject = "【工单通知】#$orderId $title"; + $body = "

工单 #$orderId

+

关联告警ID:$relateId

+

标题:$title

+
$content
"; +} + +// 钉钉机器人推送 +function sendDingNotify($cfg, $text) +{ + $webhook = $cfg['ding_webhook'] ?? ''; + $secret = $cfg['ding_secret'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 企业微信机器人推送 +function sendWecomNotify($cfg, $text) +{ + $webhook = $cfg['wecom_webhook'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 无匹配动作 +echo json_encode(['code' => 400, 'msg' => '无效请求动作']); +mysqli_close($connWork); +mysqli_close($connConf); +exit; +?> diff --git a/api/work_order_api.php.1 b/api/work_order_api.php.1 new file mode 100644 index 0000000..62697b4 --- /dev/null +++ b/api/work_order_api.php.1 @@ -0,0 +1,117 @@ + 0, 'msg' => 'ok']); + exit; +} +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + echo json_encode(['code' => 401, 'msg' => '登录失效']); + exit; +} +$loginUid = $_SESSION['user_id']; + +// 数据库本地连接,避免远程拦截 +$dbHost = '10.150.117.190'; +$dbUser = 'root'; +$dbPwd = 'hp93000'; +$dbName = 'monitor'; +$dbPort = 3306; +$conn = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName, $dbPort); +if (!$conn) { + echo json_encode([ + 'code' => 500, + 'msg' => '数据库连接失败:' . mysqli_connect_error() + ]); + exit; +} +mysqli_set_charset($conn, 'utf8mb4'); + +// 获取当前用户是否管理员 +$isAdmin = 0; +$roleSql = "SELECT r.is_admin FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($conn, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtRole)); +if ($roleRow) $isAdmin = intval($roleRow['is_admin']); + +$action = $_REQUEST['action'] ?? ''; +$post = json_decode(file_get_contents("php://input"), true) ?: []; + +// 1、新建工单(修复第50行引用报错) +if ($action === "create") { + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $status = 1; // 单独定义变量,不能直接写1传入bind_param + if (!$title || !$content) { + echo json_encode(['code' => 400, 'msg' => '标题和内容不能为空']); + exit; + } + $sql = "INSERT INTO work_order(title,content,create_uid,assign_uid,status,create_time,update_time) VALUES (?,?,?,?,?,NOW(),NOW())"; + $stmt = mysqli_prepare($conn, $sql); + // 全部使用变量传参,禁止直接写数字/字符串 + mysqli_stmt_bind_param($stmt, 'ssssi', $title, $content, $loginUid, $assign, $status); + $ok = mysqli_stmt_execute($stmt); + if ($ok) { + echo json_encode(['code' => 0, 'msg' => '工单提交成功']); + } else { + echo json_encode(['code' => 500, 'msg' => '提交失败:' . mysqli_error($conn)]); + } + exit; +} + +// 2、修改工单状态 +if ($action === "update_status") { + $id = intval($post['id'] ?? 0); + $status = intval($post['status'] ?? 1); + if ($id <= 0) { + echo json_encode(['code' => 400, 'msg' => '工单ID错误']); + exit; + } + // 普通用户权限校验 + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($conn, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限操作该工单']); + exit; + } + } + $sql = "UPDATE work_order SET status=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'ii', $status, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '状态更新成功']); + exit; +} + +// 3、管理员分发工单 +if ($action === "assign_order") { + if ($isAdmin !== 1) { + echo json_encode(['code' => 403, 'msg' => '仅管理员可分发工单']); + exit; + } + $id = intval($post['id'] ?? 0); + $assignUid = trim($post['assign_uid'] ?? ''); + $sql = "UPDATE work_order SET assign_uid=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'si', $assignUid, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单分发成功']); + exit; +} + +// 无效操作 +echo json_encode(['code' => 400, 'msg' => '无效操作']); +mysqli_close($conn); +exit; +?> diff --git a/api/work_order_api.php.2.0 b/api/work_order_api.php.2.0 new file mode 100644 index 0000000..c80f790 --- /dev/null +++ b/api/work_order_api.php.2.0 @@ -0,0 +1,144 @@ + 0, 'msg' => 'ok']); + exit; +} +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + echo json_encode(['code' => 401, 'msg' => '登录失效']); + exit; +} +$loginUid = $_SESSION['user_id']; + +// 数据库本地连接 +$dbHost = '10.150.117.190'; +$dbUser = 'root'; +$dbPwd = 'hp93000'; +$dbName = 'monitor'; +$dbPort = 3306; +$conn = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName, $dbPort); +if (!$conn) { + echo json_encode([ + 'code' => 500, + 'msg' => '数据库连接失败:' . mysqli_connect_error() + ]); + exit; +} +mysqli_set_charset($conn, 'utf8mb4'); + +// 获取当前用户是否管理员 +$isAdmin = 0; +$roleSql = "SELECT r.is_admin FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($conn, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtRole)); +if ($roleRow) $isAdmin = intval($roleRow['is_admin']); + +$action = $_REQUEST['action'] ?? ''; +$post = json_decode(file_get_contents("php://input"), true) ?: []; + +// 1、新建工单 +if ($action === "create") { + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $status = 1; + if (!$title || !$content) { + echo json_encode(['code' => 400, 'msg' => '标题和内容不能为空']); + exit; + } + $sql = "INSERT INTO work_order(title,content,create_uid,assign_uid,status,create_time,update_time) VALUES (?,?,?,?,?,NOW(),NOW())"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'ssssi', $title, $content, $loginUid, $assign, $status); + $ok = mysqli_stmt_execute($stmt); + if ($ok) { + echo json_encode(['code' => 0, 'msg' => '工单提交成功']); + } else { + echo json_encode(['code' => 500, 'msg' => '提交失败:' . mysqli_error($conn)]); + } + exit; +} + +// 2、编辑工单(新增,支持修改标题、内容备注、分配人) +if ($action === "edit") { + $id = intval($post['id'] ?? 0); + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + if ($id <= 0 || empty($title) || empty($content)) { + echo json_encode(['code' => 400, 'msg' => '参数不能为空']); + exit; + } + // 权限校验 + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($conn, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限编辑该工单']); + exit; + } + } + $sql = "UPDATE work_order SET title=?,content=?,assign_uid=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'sssi', $title, $content, $assign, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单修改备注保存成功']); + exit; +} + +// 3、修改工单状态 +if ($action === "update_status") { + $id = intval($post['id'] ?? 0); + $status = intval($post['status'] ?? 1); + if ($id <= 0) { + echo json_encode(['code' => 400, 'msg' => '工单ID错误']); + exit; + } + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($conn, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限操作该工单']); + exit; + } + } + $sql = "UPDATE work_order SET status=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'ii', $status, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '状态更新成功']); + exit; +} + +// 4、管理员分发工单 +if ($action === "assign_order") { + if ($isAdmin !== 1) { + echo json_encode(['code' => 403, 'msg' => '仅管理员可分发工单']); + exit; + } + $id = intval($post['id'] ?? 0); + $assignUid = trim($post['assign_uid'] ?? ''); + $sql = "UPDATE work_order SET assign_uid=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'si', $assignUid, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单分发成功']); + exit; +} + +echo json_encode(['code' => 400, 'msg' => '无效操作']); +mysqli_close($conn); +exit; +?> diff --git a/api/work_order_api.php.3.0 b/api/work_order_api.php.3.0 new file mode 100644 index 0000000..9230ec7 --- /dev/null +++ b/api/work_order_api.php.3.0 @@ -0,0 +1,146 @@ + 0, 'msg' => 'ok']); + exit; +} +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + echo json_encode(['code' => 401, 'msg' => '登录失效']); + exit; +} +$loginUid = $_SESSION['user_id']; + +// 工单数据库本地连接 +$dbHost = '10.150.117.190'; +$dbUser = 'root'; +$dbPwd = 'hp93000'; +$dbName = 'monitor'; +$dbPort = 3306; +$conn = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName, $dbPort); +if (!$conn) { + echo json_encode([ + 'code' => 500, + 'msg' => '数据库连接失败:' . mysqli_connect_error() + ]); + exit; +} +mysqli_set_charset($conn, 'utf8mb4'); + +// 判断管理员 +$isAdmin = 0; +$roleSql = "SELECT r.is_admin FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($conn, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtRole)); +if ($roleRow) $isAdmin = intval($roleRow['is_admin']); + +$action = $_REQUEST['action'] ?? ''; +$post = json_decode(file_get_contents("php://input"), true) ?: []; + +// 1、新建工单(新增relate_alert_id字段) +if ($action === "create") { + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $relateAlertId = trim($post['relate_alert_id'] ?? ''); + $status = 1; + if (!$title || !$content) { + echo json_encode(['code' => 400, 'msg' => '标题和内容不能为空']); + exit; + } + $sql = "INSERT INTO work_order(title,content,create_uid,assign_uid,relate_alert_id,status,create_time,update_time) VALUES (?,?,?,?,?,?,NOW(),NOW())"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'sssssi', $title, $content, $loginUid, $assign, $relateAlertId, $status); + $ok = mysqli_stmt_execute($stmt); + if ($ok) { + echo json_encode(['code' => 0, 'msg' => '工单提交成功']); + } else { + echo json_encode(['code' => 500, 'msg' => '提交失败:' . mysqli_error($conn)]); + } + exit; +} + +// 2、编辑工单(不修改关联告警ID) +if ($action === "edit") { + $id = intval($post['id'] ?? 0); + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + if ($id <= 0 || empty($title) || empty($content)) { + echo json_encode(['code' => 400, 'msg' => '参数不能为空']); + exit; + } + // 权限校验 + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($conn, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限编辑该工单']); + exit; + } + } + $sql = "UPDATE work_order SET title=?,content=?,assign_uid=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'sssi', $title, $content, $assign, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单修改备注保存成功']); + exit; +} + +// 3、修改工单状态 +if ($action === "update_status") { + $id = intval($post['id'] ?? 0); + $status = intval($post['status'] ?? 1); + if ($id <= 0) { + echo json_encode(['code' => 400, 'msg' => '工单ID错误']); + exit; + } + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($conn, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限操作该工单']); + exit; + } + } + $sql = "UPDATE work_order SET status=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'ii', $status, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '状态更新成功']); + exit; +} + +// 4、管理员分发工单 +if ($action === "assign_order") { + if ($isAdmin !== 1) { + echo json_encode(['code' => 403, 'msg' => '仅管理员可分发工单']); + exit; + } + $id = intval($post['id'] ?? 0); + $assignUid = trim($post['assign_uid'] ?? ''); + $sql = "UPDATE work_order SET assign_uid=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'si', $assignUid, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单分发成功']); + exit; +} + +// 无匹配操作 +echo json_encode(['code' => 400, 'msg' => '无效请求动作']); +mysqli_close($conn); +exit; +?> diff --git a/api/work_order_api.php.4.0 b/api/work_order_api.php.4.0 new file mode 100644 index 0000000..cc5d80f --- /dev/null +++ b/api/work_order_api.php.4.0 @@ -0,0 +1,247 @@ + 0, 'msg' => 'ok']); + exit; +} +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + echo json_encode(['code' => 401, 'msg' => '登录失效']); + exit; +} +$loginUid = $_SESSION['user_id']; + +// 工单业务库 monitor +$dbWorkHost = 'localhost'; +$dbWorkUser = 'root'; +$dbWorkPwd = 'hp93000'; +$dbWorkName = 'monitor'; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + echo json_encode(['code' => 500, 'msg' => '工单数据库连接失败:' . mysqli_connect_error()]); + exit; +} +mysqli_set_charset($connWork, 'utf8mb4'); + +// 配置库 alert_mail_stat +$dbConfHost = "10.150.117.190"; +$dbConfUser = "root"; +$dbConfPwd = "hp93000"; +$dbConfName = "alert_mail_stat"; +$connConf = mysqli_connect($dbConfHost, $dbConfUser, $dbConfPwd, $dbConfName); +mysqli_set_charset($connConf, "utf8mb4"); + +// 获取当前用户角色权限 +$isAdmin = 0; +$permList = ""; +$roleSql = "SELECT r.is_admin, r.perm_list FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtRole)); +if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; +} + +$action = $_REQUEST['action'] ?? ''; +$post = json_decode(file_get_contents("php://input"), true) ?: []; + +// 1、获取当前活跃告警(解决前端下拉空白) +if ($action === "get_firing_alert") { + $alertSql = "SELECT alert_id,alert_name,instance FROM alert_firing ORDER BY receive_time DESC LIMIT 100"; + $res = mysqli_query($connConf, $alertSql); + $list = []; + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + echo json_encode(['code' => 0, 'list' => $list]); + exit; +} + +// 2、新建工单(新增通知用户、通知渠道、关联告警) +if ($action === "create") { + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $relateAlertId = trim($post['relate_alert_id'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + $status = 1; + if (!$title || !$content) { + echo json_encode(['code' => 400, 'msg' => '标题和内容不能为空']); + exit; + } + $sql = "INSERT INTO work_order(title,content,create_uid,assign_uid,relate_alert_id,notify_user,notify_channel,status,create_time,update_time) VALUES (?,?,?,?,?,?,?,?,NOW(),NOW())"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'sssssssi', $title, $content, $loginUid, $assign, $relateAlertId, $notifyUser, $notifyChannel, $status); + $ok = mysqli_stmt_execute($stmt); + if (!$ok) { + echo json_encode(['code' => 500, 'msg' => '创建失败:' . mysqli_error($connWork)]); + exit; + } + $orderId = mysqli_insert_id($connWork); + // 发送通知 + sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单提交成功,通知已下发']); + exit; +} + +// 3、编辑工单(更新通知、不修改关联告警) +if ($action === "edit") { + $id = intval($post['id'] ?? 0); + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + if ($id <= 0 || empty($title) || empty($content)) { + echo json_encode(['code' => 400, 'msg' => '参数不能为空']); + exit; + } + // 权限校验 + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限编辑该工单']); + exit; + } + } + $sql = "UPDATE work_order SET title=?,content=?,assign_uid=?,notify_user=?,notify_channel=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'sssssi', $title, $content, $assign, $notifyUser, $notifyChannel, $id); + mysqli_stmt_execute($stmt); + sendWorkOrderNotify($connConf, $connWork, $id, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单保存成功,通知已更新下发']); + exit; +} + +// 4、修改工单状态 +if ($action === "update_status") { + $id = intval($post['id'] ?? 0); + $status = intval($post['status'] ?? 1); + if ($id <= 0) { + echo json_encode(['code' => 400, 'msg' => '工单ID错误']); + exit; + } + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限操作该工单']); + exit; + } + } + $sql = "UPDATE work_order SET status=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ii', $status, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '状态更新成功']); + exit; +} + +// 5、管理员分发工单 +if ($action === "assign_order") { + if ($isAdmin !== 1) { + echo json_encode(['code' => 403, 'msg' => '仅管理员可分发工单']); + exit; + } + $id = intval($post['id'] ?? 0); + $assignUid = trim($post['assign_uid'] ?? ''); + $sql = "UPDATE work_order SET assign_uid=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'si', $assignUid, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单分发成功']); + exit; +} + +// 通知发送统一函数 +function sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUserStr, $channelStr) +{ + if (empty($notifyUserStr) || empty($channelStr)) return; + $userArr = explode(",", $notifyUserStr); + $channelArr = explode(",", $channelStr); + + // 获取SMTP配置 + $smtpRow = mysqli_fetch_assoc(mysqli_query($connConf, "SELECT * FROM sys_smtp_config WHERE id=1")); + $smtpConfig = $smtpRow ?? []; + + // 获取工单详情 + $orderRow = mysqli_fetch_assoc(mysqli_query($connWork, "SELECT * FROM work_order WHERE id=$orderId")); + $title = $orderRow['title']; + $content = $orderRow['content']; + + // 遍历渠道发送 + foreach ($channelArr as $ch) { + switch ($ch) { + case "mail": + sendMailNotify($smtpConfig, $userArr, $title, $content); + break; + case "dingtalk": + // 此处填入钉钉机器人发送逻辑,按需补充 + break; + case "wecom": + // 此处填入企业微信机器人发送逻辑,按需补充 + break; + } + } +} + +// 邮件发送函数 +function sendMailNotify($smtp, $uidList, $title, $content) +{ + if (empty($smtp['smtp_host']) || empty($smtp['smtp_user']) || empty($smtp['smtp_pass'])) return; + // 查询用户邮箱 + $emailList = []; + foreach ($uidList as $uid) { + $uid = trim($uid); + if (empty($uid)) continue; + $res = mysqli_query($GLOBALS['connWork'], "SELECT email FROM sys_user WHERE uid='$uid'"); + $u = mysqli_fetch_assoc($res); + if (!empty($u['email'])) $emailList[] = $u['email']; + } + if (empty($emailList)) return; + $to = implode(",", $emailList); + $subject = "【工单通知】" . $title; + $body = "

工单内容

".$content."
"; + // PHPMailer 发送逻辑,环境需安装phpmailer + /* + require_once 'PHPMailer.php'; + require_once 'SMTP.php'; + $mail = new PHPMailer\PHPMailer\PHPMailer(true); + try { + $mail->isSMTP(); + $mail->Host = $smtp['smtp_host']; + $mail->SMTPAuth = true; + $mail->Username = $smtp['smtp_user']; + $mail->Password = $smtp['smtp_pass']; + $mail->SMTPSecure = $smtp['smtp_ssl'] ? PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_SMTPS : ''; + $mail->Port = $smtp['smtp_port']; + $mail->setFrom($smtp['send_from'], $smtp['send_from']); + $mail->addAddress($to); + $mail->isHTML(true); + $mail->Subject = $subject; + $mail->Body = $body; + $mail->send(); + } catch (Exception $e) {} + */ +} + +// 无匹配动作 +echo json_encode(['code' => 400, 'msg' => '无效请求动作']); +mysqli_close($connWork); +mysqli_close($connConf); +exit; +?> diff --git a/api/work_order_api.php.5.0 b/api/work_order_api.php.5.0 new file mode 100644 index 0000000..c1f6af8 --- /dev/null +++ b/api/work_order_api.php.5.0 @@ -0,0 +1,267 @@ + 0, 'msg' => 'ok']); + exit; +} +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + echo json_encode(['code' => 401, 'msg' => '登录失效']); + exit; +} +$loginUid = $_SESSION['user_id']; + +// 工单业务库 monitor +$dbWorkHost = '10.150.117.190'; +$dbWorkUser = 'root'; +$dbWorkPwd = 'hp93000'; +$dbWorkName = 'monitor'; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + echo json_encode(['code' => 500, 'msg' => '工单数据库连接失败:' . mysqli_connect_error()]); + exit; +} +mysqli_set_charset($connWork, 'utf8mb4'); + +// 配置库 alert_mail_stat(告警、通知配置统一此处) +$dbConfHost = "10.150.117.190"; +$dbConfUser = "root"; +$dbConfPwd = "hp93000"; +$dbConfName = "alert_mail_stat"; +$connConf = mysqli_connect($dbConfHost, $dbConfUser, $dbConfPwd, $dbConfName); +if(!$connConf){ + echo json_encode(['code' => 500, 'msg' => '配置库连接失败']); + exit; +} +mysqli_set_charset($connConf, "utf8mb4"); + +// 获取当前用户角色权限 +$isAdmin = 0; +$permList = ""; +$roleSql = "SELECT r.is_admin, r.perm_list FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRes = mysqli_stmt_get_result($stmtRole); +$roleRow = $roleRes ? mysqli_fetch_assoc($roleRes) : []; +if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; +} + +$action = $_REQUEST['action'] ?? ''; +$post = json_decode(file_get_contents("php://input"), true) ?: []; + +// 1、获取实时活跃告警(alert_mail_stat.alert_firing 数据源) +if ($action === "get_firing_alert") { + $alertSql = "SELECT alert_id,alert_name,instance FROM alert_firing WHERE status='firing' ORDER BY receive_time DESC LIMIT 100"; + $res = mysqli_query($connConf, $alertSql); + $list = []; + if($res instanceof mysqli_result){ + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + } + echo json_encode(['code' => 0, 'list' => $list]); + exit; +} + +// 2、新建工单(关联告警、多渠道通知) +if ($action === "create") { + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $relateAlertId = trim($post['relate_alert_id'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + $status = 1; + if (!$title || !$content) { + echo json_encode(['code' => 400, 'msg' => '标题和内容不能为空']); + exit; + } + $sql = "INSERT INTO work_order(title,content,create_uid,assign_uid,relate_alert_id,notify_user,notify_channel,status,create_time,update_time) VALUES (?,?,?,?,?,?,?,?,NOW(),NOW())"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'sssssssi', $title, $content, $loginUid, $assign, $relateAlertId, $notifyUser, $notifyChannel, $status); + $ok = mysqli_stmt_execute($stmt); + if (!$ok) { + echo json_encode(['code' => 500, 'msg' => '创建失败:' . mysqli_error($connWork)]); + exit; + } + $orderId = mysqli_insert_id($connWork); + sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单提交成功,通知已下发']); + exit; +} + +// 3、编辑工单 +if ($action === "edit") { + $id = intval($post['id'] ?? 0); + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + if ($id <= 0 || empty($title) || empty($content)) { + echo json_encode(['code' => 400, 'msg' => '参数不能为空']); + exit; + } + // 非管理员权限校验 + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限编辑该工单']); + exit; + } + } + $sql = "UPDATE work_order SET title=?,content=?,assign_uid=?,notify_user=?,notify_channel=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'sssssi', $title, $content, $assign, $notifyUser, $notifyChannel, $id); + mysqli_stmt_execute($stmt); + sendWorkOrderNotify($connConf, $connWork, $id, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单保存成功,通知已更新下发']); + exit; +} + +// 4、修改工单状态 +if ($action === "update_status") { + $id = intval($post['id'] ?? 0); + $status = intval($post['status'] ?? 1); + if ($id <= 0) { + echo json_encode(['code' => 400, 'msg' => '工单ID错误']); + exit; + } + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限操作该工单']); + exit; + } + } + $sql = "UPDATE work_order SET status=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ii', $status, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '状态更新成功']); + exit; +} + +// 5、管理员分发工单(前端统一action=assign,废弃assign_order) +if ($action === "assign") { + if ($isAdmin !== 1) { + echo json_encode(['code' => 403, 'msg' => '仅管理员可分发工单']); + exit; + } + $id = intval($post['id'] ?? 0); + $assignUid = trim($post['assign_uid'] ?? ''); + $sql = "UPDATE work_order SET assign_uid=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'si', $assignUid, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单分发成功']); + exit; +} + +// ==================== 全局通知统一函数 ==================== +function sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUserStr, $channelStr) +{ + if (empty($notifyUserStr) || empty($channelStr)) return; + $userArr = explode(",", $notifyUserStr); + $channelArr = explode(",", $channelStr); + + // 读取完整通知配置(邮箱+钉钉+企微) + $cfgRes = mysqli_query($connConf, "SELECT * FROM sys_smtp_config WHERE id=1"); + $notifyCfg = $cfgRes ? mysqli_fetch_assoc($cfgRes) : []; + if(empty($notifyCfg)) return; + + // 获取工单完整信息 + $orderRes = mysqli_query($connWork, "SELECT * FROM work_order WHERE id=$orderId"); + $order = $orderRes ? mysqli_fetch_assoc($orderRes) : []; + $title = $order['title']; + $content = $order['content']; + $relateId = $order['relate_alert_id'] ?: "无"; + + $msgText = "【运维工单通知】\n工单ID:$orderId\n关联告警:$relateId\n标题:$title\n详情:$content"; + + foreach ($channelArr as $ch) { + $ch = trim($ch); + switch ($ch) { + case "mail": + sendMailNotify($notifyCfg, $userArr, $title, $content, $relateId, $orderId); + break; + case "dingtalk": + sendDingNotify($notifyCfg, $msgText); + break; + case "wecom": + sendWecomNotify($notifyCfg, $msgText); + break; + } + } +} + +// 邮件发送 +function sendMailNotify($smtp, $uidList, $title, $content, $relateId, $orderId) +{ + if (empty($smtp['smtp_host']) || empty($smtp['smtp_account'])) return; + $emailList = []; + foreach ($uidList as $uid) { + $uid = trim($uid); + if (empty($uid)) continue; + $res = mysqli_query($GLOBALS['connWork'], "SELECT email FROM sys_user WHERE uid='$uid'"); + $u = mysqli_fetch_assoc($res); + if (!empty($u['email'])) $emailList[] = $u['email']; + } + if (empty($emailList)) return; + $to = implode(",", array_unique($emailList)); + $subject = "【工单通知】#$orderId $title"; + $body = "

工单 #$orderId

+

关联告警ID:$relateId

+

标题:$title

+
$content
"; + // 此处接入PHPMailer发送逻辑 +} + +// 钉钉机器人推送 +function sendDingNotify($cfg, $text) +{ + $webhook = $cfg['ding_webhook'] ?? ''; + $secret = $cfg['ding_secret'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 企业微信机器人推送 +function sendWecomNotify($cfg, $text) +{ + $webhook = $cfg['wecom_webhook'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 无匹配动作 +echo json_encode(['code' => 400, 'msg' => '无效请求动作']); +mysqli_close($connWork); +mysqli_close($connConf); +exit; +?> diff --git a/api/work_order_api.php.6.0 b/api/work_order_api.php.6.0 new file mode 100644 index 0000000..7502531 --- /dev/null +++ b/api/work_order_api.php.6.0 @@ -0,0 +1,378 @@ + 0, 'msg' => 'ok']); + exit; +} +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + echo json_encode(['code' => 401, 'msg' => '登录失效']); + exit; +} +$loginUid = $_SESSION['user_id']; + +// 工单业务库 monitor +$dbWorkHost = '10.150.117.190'; +$dbWorkUser = 'root'; +$dbWorkPwd = 'hp93000'; +$dbWorkName = 'monitor'; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + echo json_encode(['code' => 500, 'msg' => '工单数据库连接失败:' . mysqli_connect_error()]); + exit; +} +mysqli_set_charset($connWork, 'utf8mb4'); + +// 配置库 alert_mail_stat(告警、通知配置统一此处) +$dbConfHost = "10.150.117.190"; +$dbConfUser = "root"; +$dbConfPwd = "hp93000"; +$dbConfName = "alert_mail_stat"; +$connConf = mysqli_connect($dbConfHost, $dbConfUser, $dbConfPwd, $dbConfName); +if(!$connConf){ + echo json_encode(['code' => 500, 'msg' => '配置库连接失败']); + exit; +} +mysqli_set_charset($connConf, "utf8mb4"); + +// 获取当前用户角色权限 +$isAdmin = 0; +$permList = ""; +$roleSql = "SELECT r.is_admin, r.perm_list FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRes = mysqli_stmt_get_result($stmtRole); +$roleRow = $roleRes ? mysqli_fetch_assoc($roleRes) : []; +if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; +} + +$action = $_REQUEST['action'] ?? ''; +$post = json_decode(file_get_contents("php://input"), true) ?: []; + +// ===================== 新增1:根据告警ID查询关联工单 ===================== +if ($action === "get_workorder_by_alertid") { + $alertId = trim($_GET['alert_id'] ?? ''); + if (empty($alertId)) { + echo json_encode(['code' => 400, 'msg' => '缺少告警ID参数']); + exit; + } + $alertEsc = mysqli_real_escape_string($connWork, $alertId); + $sql = "SELECT id,title,status,assign_uid,create_time FROM work_order WHERE relate_alert_id = ? ORDER BY create_time DESC"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 's', $alertEsc); + mysqli_stmt_execute($stmt); + $res = mysqli_stmt_get_result($stmt); + $list = []; + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + echo json_encode(['code' => 0, 'list' => $list]); + exit; +} + +// ===================== 新增2:自动同步告警状态,批量更新工单为已完成 ===================== +if ($action === "auto_sync_workorder_status") { + // 1. 查询所有已恢复的告警(alert_type=2),去重获取告警ID + $resolveSql = "SELECT DISTINCT CONCAT(alert_name,'_',instance) as alert_id FROM alert_log WHERE alert_type=2"; + $resolveRes = mysqli_query($connConf, $resolveSql); + $resolveAlertIds = []; + while ($row = mysqli_fetch_assoc($resolveRes)) { + $resolveAlertIds[] = $row['alert_id']; + } + if (empty($resolveAlertIds)) { + echo json_encode(['code' => 0, 'msg' => '暂无已恢复告警,无需更新工单', 'update_count' => 0]); + exit; + } + + // 2. 拼接IN条件,查询未完成、关联该告警的工单 + $inStr = implode("','", array_map(function($v) use ($connWork) { + return mysqli_real_escape_string($connWork, $v); + }, $resolveAlertIds)); + // status=1待处理 / status=2处理中,统一改为3已完成 + $updateSql = "UPDATE work_order SET status=3,update_time=NOW() WHERE relate_alert_id IN ('$inStr') AND status IN (1,2)"; + mysqli_query($connWork, $updateSql); + $updateCnt = mysqli_affected_rows($connWork); + + echo json_encode([ + 'code' => 0, + 'msg' => '工单状态自动同步完成,已恢复告警绑定工单全部置为已完成', + 'update_count' => $updateCnt + ], JSON_UNESCAPED_UNICODE); + exit; +} + +// 1、获取实时活跃告警(alert_mail_stat.alert_firing 数据源) +if ($action === "get_firing_alert") { + $alertSql = "SELECT alert_id,alert_name,instance FROM alert_firing WHERE status='firing' ORDER BY receive_time DESC LIMIT 100"; + $res = mysqli_query($connConf, $alertSql); + $list = []; + if($res instanceof mysqli_result){ + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + } + echo json_encode(['code' => 0, 'list' => $list]); + exit; +} + +// 2、新建工单(关联告警、多渠道通知 + 自动判断告警是否已恢复) +if ($action === "create") { + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $relateAlertId = trim($post['relate_alert_id'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + // 默认待处理1;若关联告警已恢复,直接置完成3 + $status = 1; + + if (!$title || !$content) { + echo json_encode(['code' => 400, 'msg' => '标题和内容不能为空']); + exit; + } + + // 关联了告警,判断该告警是否存在恢复记录 + if (!empty($relateAlertId)) { + $alertEsc = mysqli_real_escape_string($connConf, $relateAlertId); + $checkResolveSql = "SELECT 1 FROM alert_log WHERE CONCAT(alert_name,'_',instance) = ? AND alert_type=2 LIMIT 1"; + $stmtCheck = mysqli_prepare($connConf, $checkResolveSql); + mysqli_stmt_bind_param($stmtCheck, 's', $alertEsc); + mysqli_stmt_execute($stmtCheck); + $checkRes = mysqli_stmt_get_result($stmtCheck); + if (mysqli_num_rows($checkRes) > 0) { + $status = 3; + } + } + + $sql = "INSERT INTO work_order(title,content,create_uid,assign_uid,relate_alert_id,notify_user,notify_channel,status,create_time,update_time) VALUES (?,?,?,?,?,?,?,?,NOW(),NOW())"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'sssssssi', $title, $content, $loginUid, $assign, $relateAlertId, $notifyUser, $notifyChannel, $status); + $ok = mysqli_stmt_execute($stmt); + if (!$ok) { + echo json_encode(['code' => 500, 'msg' => '创建失败:' . mysqli_error($connWork)]); + exit; + } + $orderId = mysqli_insert_id($connWork); + sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单提交成功,通知已下发', 'init_status' => $status]); + exit; +} + +// 3、编辑工单 +if ($action === "edit") { + $id = intval($post['id'] ?? 0); + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + if ($id <= 0 || empty($title) || empty($content)) { + echo json_encode(['code' => 400, 'msg' => '参数不能为空']); + exit; + } + // 非管理员权限校验 + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限编辑该工单']); + exit; + } + } + $sql = "UPDATE work_order SET title=?,content=?,assign_uid=?,notify_user=?,notify_channel=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'sssssi', $title, $content, $assign, $notifyUser, $notifyChannel, $id); + mysqli_stmt_execute($stmt); + sendWorkOrderNotify($connConf, $connWork, $id, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单保存成功,通知已更新下发']); + exit; +} + +// 4、修改工单状态 +if ($action === "update_status") { + $id = intval($post['id'] ?? 0); + $status = intval($post['status'] ?? 1); + if ($id <= 0) { + echo json_encode(['code' => 400, 'msg' => '工单ID错误']); + exit; + } + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限操作该工单']); + exit; + } + } + $sql = "UPDATE work_order SET status=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ii', $status, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '状态更新成功']); + exit; +} + +// 5、管理员分发工单(前端统一action=assign,废弃assign_order) +if ($action === "assign") { + if ($isAdmin !== 1) { + echo json_encode(['code' => 403, 'msg' => '仅管理员可分发工单']); + exit; + } + $id = intval($post['id'] ?? 0); + $assignUid = trim($post['assign_uid'] ?? ''); + $sql = "UPDATE work_order SET assign_uid=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'si', $assignUid, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单分发成功']); + exit; +} + +// 新增:同步Prometheus实时告警,自动清理恢复告警(完全独立,无需index.php) +if ($action === "sync_prom_alerts") { + header("Content-Type: application/json;charset=utf-8"); + $promUrl = "http://10.150.117.190:9090/api/v1/alerts"; + $resp = @file_get_contents($promUrl); + if($resp === false){ + echo json_encode(["code"=>500,"msg"=>"无法连接Prometheus接口"],JSON_UNESCAPED_UNICODE); + exit; + } + $promData = json_decode($resp,true); + if(!isset($promData['data']['alerts'])){ + echo json_encode(["code"=>500,"msg"=>"Prometheus返回数据异常"],JSON_UNESCAPED_UNICODE); + exit; + } + + // 1. 先将表内所有告警标记为已恢复 + mysqli_query($connConf,"UPDATE alert_firing SET status='resolved'"); + + // 2. 遍历当前Prometheus活跃告警,写入/更新 + $alerts = $promData['data']['alerts'] ?? []; + foreach($alerts as $item){ + $alertName = $item['labels']['alertname'] ?? "unknown"; + $instance = $item['labels']['instance'] ?? "unknown"; + $alertId = $alertName."_".$instance; + $sql = "INSERT INTO alert_firing(alert_id,alert_name,instance,status,receive_time) VALUES (?,?,?,'firing',NOW()) ON DUPLICATE KEY UPDATE status='firing',receive_time=NOW()"; + $stmt = mysqli_prepare($connConf,$sql); + mysqli_stmt_bind_param($stmt,"sss",$alertId,$alertName,$instance); + mysqli_stmt_execute($stmt); + } + $syncNum = count($alerts); + + // 同步完成后自动执行工单状态更新,无需额外调用 + $syncWorkUrl = apiOrder . "?action=auto_sync_workorder_status"; + @file_get_contents($syncWorkUrl); + + echo json_encode([ + "code"=>0, + "msg"=>"Prometheus告警同步完成,已自动同步工单状态", + "active_alert_total"=>$syncNum + ],JSON_UNESCAPED_UNICODE); + exit; +} + +// ==================== 全局通知统一函数 ==================== +function sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUserStr, $channelStr) +{ + if (empty($notifyUserStr) || empty($channelStr)) return; + $userArr = explode(",", $notifyUserStr); + $channelArr = explode(",", $channelStr); + + // 读取完整通知配置(邮箱+钉钉+企微) + $cfgRes = mysqli_query($connConf, "SELECT * FROM sys_smtp_config WHERE id=1"); + $notifyCfg = $cfgRes ? mysqli_fetch_assoc($cfgRes) : []; + if(empty($notifyCfg)) return; + + // 获取工单完整信息 + $orderRes = mysqli_query($connWork, "SELECT * FROM work_order WHERE id=$orderId"); + $order = $orderRes ? mysqli_fetch_assoc($orderRes) : []; + $title = $order['title']; + $content = $order['content']; + $relateId = $order['relate_alert_id'] ?: "无"; + + $msgText = "【运维工单通知】\n工单ID:$orderId\n关联告警:$relateId\n标题:$title\n详情:$content"; + + foreach ($channelArr as $ch) { + $ch = trim($ch); + switch ($ch) { + case "mail": + sendMailNotify($notifyCfg, $userArr, $title, $content, $relateId, $orderId); + break; + case "dingtalk": + sendDingNotify($notifyCfg, $msgText); + break; + case "wecom": + sendWecomNotify($notifyCfg, $msgText); + break; + } + } +} + +// 邮件发送 +function sendMailNotify($smtp, $uidList, $title, $content, $relateId, $orderId) +{ + if (empty($smtp['smtp_host']) || empty($smtp['smtp_account'])) return; + $emailList = []; + foreach ($uidList as $uid) { + $uid = trim($uid); + if (empty($uid)) continue; + $res = mysqli_query($GLOBALS['connWork'], "SELECT email FROM sys_user WHERE uid='$uid'"); + $u = mysqli_fetch_assoc($res); + if (!empty($u['email'])) $emailList[] = $u['email']; + } + if (empty($emailList)) return; + $to = implode(",", array_unique($emailList)); + $subject = "【工单通知】#$orderId $title"; + $body = "

工单 #$orderId

+

关联告警ID:$relateId

+

标题:$title

+
$content
"; + // 此处接入PHPMailer发送逻辑 +} + +// 钉钉机器人推送 +function sendDingNotify($cfg, $text) +{ + $webhook = $cfg['ding_webhook'] ?? ''; + $secret = $cfg['ding_secret'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 企业微信机器人推送 +function sendWecomNotify($cfg, $text) +{ + $webhook = $cfg['wecom_webhook'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 无匹配动作 +echo json_encode(['code' => 400, 'msg' => '无效请求动作']); +mysqli_close($connWork); +mysqli_close($connConf); +exit; +?> diff --git a/api/work_order_api.php.7.0 b/api/work_order_api.php.7.0 new file mode 100644 index 0000000..6a210d6 --- /dev/null +++ b/api/work_order_api.php.7.0 @@ -0,0 +1,407 @@ + 0, 'msg' => 'ok']); + exit; +} +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + echo json_encode(['code' => 401, 'msg' => '登录失效']); + exit; +} +$loginUid = $_SESSION['user_id']; + +// 工单业务库 monitor +$dbWorkHost = '10.150.117.190'; +$dbWorkUser = 'root'; +$dbWorkPwd = 'hp93000'; +$dbWorkName = 'monitor'; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + echo json_encode(['code' => 500, 'msg' => '工单数据库连接失败:' . mysqli_connect_error()]); + exit; +} +mysqli_set_charset($connWork, 'utf8mb4'); + +// 配置库 alert_mail_stat(告警、通知配置统一此处) +$dbConfHost = "10.150.117.190"; +$dbConfUser = "root"; +$dbConfPwd = "hp93000"; +$dbConfName = "alert_mail_stat"; +$connConf = mysqli_connect($dbConfHost, $dbConfUser, $dbConfPwd, $dbConfName); +if(!$connConf){ + echo json_encode(['code' => 500, 'msg' => '配置库连接失败']); + exit; +} +mysqli_set_charset($connConf, "utf8mb4"); + +// 获取当前用户角色权限 +$isAdmin = 0; +$permList = ""; +$roleSql = "SELECT r.is_admin, r.perm_list FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRes = mysqli_stmt_get_result($stmtRole); +$roleRow = $roleRes ? mysqli_fetch_assoc($roleRes) : []; +if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; +} + +$action = $_REQUEST['action'] ?? ''; +$post = json_decode(file_get_contents("php://input"), true) ?: []; + +// ===================== 新增1:根据告警ID查询关联工单 ===================== +if ($action === "get_workorder_by_alertid") { + $alertId = trim($_GET['alert_id'] ?? ''); + if (empty($alertId)) { + echo json_encode(['code' => 400, 'msg' => '缺少告警ID参数']); + exit; + } + $alertEsc = mysqli_real_escape_string($connWork, $alertId); + $sql = "SELECT id,title,status,assign_uid,create_time FROM work_order WHERE relate_alert_id = ? ORDER BY create_time DESC"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 's', $alertEsc); + mysqli_stmt_execute($stmt); + $res = mysqli_stmt_get_result($stmt); + $list = []; + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + echo json_encode(['code' => 0, 'list' => $list]); + exit; +} + +// ===================== 新增2:自动同步告警状态,批量更新工单为已完成 ===================== +if ($action === "auto_sync_workorder_status") { + // 1. 查询所有已恢复的告警(alert_type=2),去重获取告警ID + $resolveSql = "SELECT DISTINCT CONCAT(alert_name,'_',instance) as alert_id FROM alert_log WHERE alert_type=2"; + $resolveRes = mysqli_query($connConf, $resolveSql); + $resolveAlertIds = []; + while ($row = mysqli_fetch_assoc($resolveRes)) { + $resolveAlertIds[] = $row['alert_id']; + } + if (empty($resolveAlertIds)) { + echo json_encode(['code' => 0, 'msg' => '暂无已恢复告警,无需更新工单', 'update_count' => 0]); + exit; + } + + // 2. 拼接IN条件,查询未完成、关联该告警的工单 + $inStr = implode("','", array_map(function($v) use ($connWork) { + return mysqli_real_escape_string($connWork, $v); + }, $resolveAlertIds)); + // status=1待处理 / status=2处理中,统一改为3已完成 + $updateSql = "UPDATE work_order SET status=3,update_time=NOW() WHERE relate_alert_id IN ('$inStr') AND status IN (1,2)"; + mysqli_query($connWork, $updateSql); + $updateCnt = mysqli_affected_rows($connWork); + + echo json_encode([ + 'code' => 0, + 'msg' => '工单状态自动同步完成,已恢复告警绑定工单全部置为已完成', + 'update_count' => $updateCnt + ], JSON_UNESCAPED_UNICODE); + exit; +} + +// 1、获取实时活跃告警(alert_mail_stat.alert_firing 数据源) +if ($action === "get_firing_alert") { + $alertSql = "SELECT alert_id,alert_name,instance FROM alert_firing WHERE status='firing' ORDER BY receive_time DESC LIMIT 100"; + $res = mysqli_query($connConf, $alertSql); + $list = []; + if($res instanceof mysqli_result){ + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + } + echo json_encode(['code' => 0, 'list' => $list]); + exit; +} + +// 2、新建工单(关联告警、多渠道通知 + 自动判断告警是否已恢复) +if ($action === "create") { + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $relateAlertId = trim($post['relate_alert_id'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + // 默认待处理1;若关联告警已恢复,直接置完成3 + $status = 1; + + if (!$title || !$content) { + echo json_encode(['code' => 400, 'msg' => '标题和内容不能为空']); + exit; + } + + // 关联了告警,判断该告警是否存在恢复记录 + if (!empty($relateAlertId)) { + $alertEsc = mysqli_real_escape_string($connConf, $relateAlertId); + $checkResolveSql = "SELECT 1 FROM alert_log WHERE CONCAT(alert_name,'_',instance) = ? AND alert_type=2 LIMIT 1"; + $stmtCheck = mysqli_prepare($connConf, $checkResolveSql); + mysqli_stmt_bind_param($stmtCheck, 's', $alertEsc); + mysqli_stmt_execute($stmtCheck); + $checkRes = mysqli_stmt_get_result($stmtCheck); + if (mysqli_num_rows($checkRes) > 0) { + $status = 3; + } + } + + $sql = "INSERT INTO work_order(title,content,create_uid,assign_uid,relate_alert_id,notify_user,notify_channel,status,create_time,update_time) VALUES (?,?,?,?,?,?,?,?,NOW(),NOW())"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'sssssssi', $title, $content, $loginUid, $assign, $relateAlertId, $notifyUser, $notifyChannel, $status); + $ok = mysqli_stmt_execute($stmt); + if (!$ok) { + echo json_encode(['code' => 500, 'msg' => '创建失败:' . mysqli_error($connWork)]); + exit; + } + $orderId = mysqli_insert_id($connWork); + sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单提交成功,通知已下发', 'init_status' => $status]); + exit; +} + +// 3、编辑工单 +if ($action === "edit") { + $id = intval($post['id'] ?? 0); + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + if ($id <= 0 || empty($title) || empty($content)) { + echo json_encode(['code' => 400, 'msg' => '参数不能为空']); + exit; + } + // 非管理员权限校验 + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限编辑该工单']); + exit; + } + } + $sql = "UPDATE work_order SET title=?,content=?,assign_uid=?,notify_user=?,notify_channel=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'sssssi', $title, $content, $assign, $notifyUser, $notifyChannel, $id); + mysqli_stmt_execute($stmt); + sendWorkOrderNotify($connConf, $connWork, $id, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单保存成功,通知已更新下发']); + exit; +} + +// 4、修改工单状态 +if ($action === "update_status") { + $id = intval($post['id'] ?? 0); + $status = intval($post['status'] ?? 1); + if ($id <= 0) { + echo json_encode(['code' => 400, 'msg' => '工单ID错误']); + exit; + } + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限操作该工单']); + exit; + } + } + $sql = "UPDATE work_order SET status=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ii', $status, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '状态更新成功']); + exit; +} + +// 5、管理员分发工单(前端统一action=assign,废弃assign_order) +if ($action === "assign") { + if ($isAdmin !== 1) { + echo json_encode(['code' => 403, 'msg' => '仅管理员可分发工单']); + exit; + } + $id = intval($post['id'] ?? 0); + $assignUid = trim($post['assign_uid'] ?? ''); + $sql = "UPDATE work_order SET assign_uid=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'si', $assignUid, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单分发成功']); + exit; +} + +// 新增:同步Prometheus实时告警,自动清理恢复告警(完全独立,无需index.php) +if ($action === "sync_prom_alerts") { + header("Content-Type: application/json;charset=utf-8"); + $promUrl = "http://10.150.117.190:9090/api/v1/alerts"; + $resp = @file_get_contents($promUrl); + if($resp === false){ + echo json_encode(["code"=>500,"msg"=>"无法连接Prometheus接口"],JSON_UNESCAPED_UNICODE); + exit; + } + $promData = json_decode($resp,true); + if(!isset($promData['data']['alerts'])){ + echo json_encode(["code"=>500,"msg"=>"Prometheus返回数据异常"],JSON_UNESCAPED_UNICODE); + exit; + } + + // 1. 先将表内所有告警标记为已恢复 + mysqli_query($connConf,"UPDATE alert_firing SET status='resolved'"); + + // 2. 遍历当前Prometheus活跃告警,写入/更新 + $alerts = $promData['data']['alerts'] ?? []; + foreach($alerts as $item){ + $alertName = $item['labels']['alertname'] ?? "unknown"; + $instance = $item['labels']['instance'] ?? "unknown"; + $alertId = $alertName."_".$instance; + $sql = "INSERT INTO alert_firing(alert_id,alert_name,instance,status,receive_time) VALUES (?,?,?,'firing',NOW()) ON DUPLICATE KEY UPDATE status='firing',receive_time=NOW()"; + $stmt = mysqli_prepare($connConf,$sql); + mysqli_stmt_bind_param($stmt,"sss",$alertId,$alertName,$instance); + mysqli_stmt_execute($stmt); + } + $syncNum = count($alerts); + + // 同步完成后自动执行工单状态更新,无需额外调用 + $syncWorkUrl = apiOrder . "?action=auto_sync_workorder_status"; + @file_get_contents($syncWorkUrl); + + echo json_encode([ + "code"=>0, + "msg"=>"Prometheus告警同步完成,已自动同步工单状态", + "active_alert_total"=>$syncNum + ],JSON_UNESCAPED_UNICODE); + exit; +} + +// 定时同步:告警恢复自动完工单 +if($_POST['action'] === "sync_alert_auto_close"){ + // 1、拉取仪表盘实时未恢复告警 + $alertApi = "./index.php?act=active_firing"; + $raw = file_get_contents($alertApi); + $activeList = json_decode($raw, true) ?: []; + $activeKeys = []; + foreach($activeList as $item){ + $activeKeys[] = $item['alert_name'] . "|" . $item['instance']; + } + // 2、查询所有未完成、绑定告警的工单 + $sql = "SELECT id, relate_alert_id FROM work_order WHERE status IN(1,2) AND relate_alert_id <> ''"; + $res = mysqli_query($conn, $sql); + while($row = mysqli_fetch_assoc($res)){ + // 工单关联告警不在当前活跃列表=已恢复,自动设为完成 + if(!in_array($row['relate_alert_id'], $activeKeys)){ + $updateSql = "UPDATE work_order SET status=3, update_time=NOW() WHERE id = ".(int)$row['id']; + mysqli_query($conn, $updateSql); + } + } + echo json_encode(['code'=>0, 'msg'=>'同步完成']); + exit; +} + +// 读取通知配置 +$notifyRow = mysqli_fetch_assoc(mysqli_query($conn, "SELECT * FROM sys_workorder_notify LIMIT 1")); +if(!$notifyRow || $notifyRow['notify_open'] != 1) return; +// 组装钉钉、企业微信请求,curl发送webhook + +// ==================== 全局通知统一函数 ==================== +function sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUserStr, $channelStr) +{ + if (empty($notifyUserStr) || empty($channelStr)) return; + $userArr = explode(",", $notifyUserStr); + $channelArr = explode(",", $channelStr); + + // 读取完整通知配置(邮箱+钉钉+企微) + $cfgRes = mysqli_query($connConf, "SELECT * FROM sys_smtp_config WHERE id=1"); + $notifyCfg = $cfgRes ? mysqli_fetch_assoc($cfgRes) : []; + if(empty($notifyCfg)) return; + + // 获取工单完整信息 + $orderRes = mysqli_query($connWork, "SELECT * FROM work_order WHERE id=$orderId"); + $order = $orderRes ? mysqli_fetch_assoc($orderRes) : []; + $title = $order['title']; + $content = $order['content']; + $relateId = $order['relate_alert_id'] ?: "无"; + + $msgText = "【运维工单通知】\n工单ID:$orderId\n关联告警:$relateId\n标题:$title\n详情:$content"; + + foreach ($channelArr as $ch) { + $ch = trim($ch); + switch ($ch) { + case "mail": + sendMailNotify($notifyCfg, $userArr, $title, $content, $relateId, $orderId); + break; + case "dingtalk": + sendDingNotify($notifyCfg, $msgText); + break; + case "wecom": + sendWecomNotify($notifyCfg, $msgText); + break; + } + } +} + +// 邮件发送 +function sendMailNotify($smtp, $uidList, $title, $content, $relateId, $orderId) +{ + if (empty($smtp['smtp_host']) || empty($smtp['smtp_account'])) return; + $emailList = []; + foreach ($uidList as $uid) { + $uid = trim($uid); + if (empty($uid)) continue; + $res = mysqli_query($GLOBALS['connWork'], "SELECT email FROM sys_user WHERE uid='$uid'"); + $u = mysqli_fetch_assoc($res); + if (!empty($u['email'])) $emailList[] = $u['email']; + } + if (empty($emailList)) return; + $to = implode(",", array_unique($emailList)); + $subject = "【工单通知】#$orderId $title"; + $body = "

工单 #$orderId

+

关联告警ID:$relateId

+

标题:$title

+
$content
"; + // 此处接入PHPMailer发送逻辑 +} + +// 钉钉机器人推送 +function sendDingNotify($cfg, $text) +{ + $webhook = $cfg['ding_webhook'] ?? ''; + $secret = $cfg['ding_secret'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 企业微信机器人推送 +function sendWecomNotify($cfg, $text) +{ + $webhook = $cfg['wecom_webhook'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 无匹配动作 +echo json_encode(['code' => 400, 'msg' => '无效请求动作']); +mysqli_close($connWork); +mysqli_close($connConf); +exit; +?> diff --git a/api/work_order_api.php.8.0 b/api/work_order_api.php.8.0 new file mode 100644 index 0000000..63e3a97 --- /dev/null +++ b/api/work_order_api.php.8.0 @@ -0,0 +1,427 @@ + 0, 'msg' => 'ok']); + exit; +} +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + echo json_encode(['code' => 401, 'msg' => '登录失效']); + exit; +} +$loginUid = $_SESSION['user_id']; + +// 工单业务库 monitor +$dbWorkHost = '10.150.117.190'; +$dbWorkUser = 'root'; +$dbWorkPwd = 'hp93000'; +$dbWorkName = 'monitor'; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + echo json_encode(['code' => 500, 'msg' => '工单数据库连接失败:' . mysqli_connect_error()]); + exit; +} +mysqli_set_charset($connWork, 'utf8mb4'); + +// 配置库 alert_mail_stat(告警、通知配置统一此处) +$dbConfHost = "10.150.117.190"; +$dbConfUser = "root"; +$dbConfPwd = "hp93000"; +$dbConfName = "alert_mail_stat"; +$connConf = mysqli_connect($dbConfHost, $dbConfUser, $dbConfPwd, $dbConfName); +if(!$connConf){ + echo json_encode(['code' => 500, 'msg' => '配置库连接失败']); + exit; +} +mysqli_set_charset($connConf, "utf8mb4"); + +// 获取当前用户角色权限 +$isAdmin = 0; +$permList = ""; +$roleSql = "SELECT r.is_admin, r.perm_list FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRes = mysqli_stmt_get_result($stmtRole); +$roleRow = $roleRes ? mysqli_fetch_assoc($roleRes) : []; +if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; +} + +$action = $_REQUEST['action'] ?? ''; +$post = json_decode(file_get_contents("php://input"), true) ?: []; + +// ===================== 新增1:根据告警ID查询关联工单 ===================== +if ($action === "get_workorder_by_alertid") { + $alertId = trim($_GET['alert_id'] ?? ''); + if (empty($alertId)) { + echo json_encode(['code' => 400, 'msg' => '缺少告警ID参数']); + exit; + } + $alertEsc = mysqli_real_escape_string($connWork, $alertId); + $sql = "SELECT id,title,status,assign_uid,create_time FROM work_order WHERE relate_alert_id = ? ORDER BY create_time DESC"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 's', $alertEsc); + mysqli_stmt_execute($stmt); + $res = mysqli_stmt_get_result($stmt); + $list = []; + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + echo json_encode(['code' => 0, 'list' => $list]); + exit; +} + +// ===================== 新增2:自动同步告警状态,批量更新工单为已完成 ===================== +if ($action === "auto_sync_workorder_status") { + // 1. 查询所有已恢复的告警(alert_type=2),去重获取告警ID + $resolveSql = "SELECT DISTINCT CONCAT(alert_name,'_',instance) as alert_id FROM alert_log WHERE alert_type=2"; + $resolveRes = mysqli_query($connConf, $resolveSql); + $resolveAlertIds = []; + while ($row = mysqli_fetch_assoc($resolveRes)) { + $resolveAlertIds[] = $row['alert_id']; + } + if (empty($resolveAlertIds)) { + echo json_encode(['code' => 0, 'msg' => '暂无已恢复告警,无需更新工单', 'update_count' => 0]); + exit; + } + + // 2. 拼接IN条件,查询未完成、关联该告警的工单 + $inStr = implode("','", array_map(function($v) use ($connWork) { + return mysqli_real_escape_string($connWork, $v); + }, $resolveAlertIds)); + // status=1待处理 / status=2处理中,统一改为3已完成 + $updateSql = "UPDATE work_order SET status=3,update_time=NOW() WHERE relate_alert_id IN ('$inStr') AND status IN (1,2)"; + mysqli_query($connWork, $updateSql); + $updateCnt = mysqli_affected_rows($connWork); + + echo json_encode([ + 'code' => 0, + 'msg' => '工单状态自动同步完成,已恢复告警绑定工单全部置为已完成', + 'update_count' => $updateCnt + ], JSON_UNESCAPED_UNICODE); + exit; +} + +// 1、获取实时活跃告警(alert_mail_stat.alert_firing 数据源) +if ($action === "get_firing_alert") { + $alertSql = "SELECT alert_id,alert_name,instance FROM alert_firing WHERE status='firing' ORDER BY receive_time DESC LIMIT 100"; + $res = mysqli_query($connConf, $alertSql); + $list = []; + if($res instanceof mysqli_result){ + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + } + echo json_encode(['code' => 0, 'list' => $list]); + exit; +} + +// 2、新建工单(关联告警、多渠道通知 + 自动判断告警是否已恢复) +if ($action === "create") { + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $relateAlertId = trim($post['relate_alert_id'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + // 默认待处理1;若关联告警已恢复,直接置完成3 + $status = 1; + + if (!$title || !$content) { + echo json_encode(['code' => 400, 'msg' => '标题和内容不能为空']); + exit; + } + + // 关联了告警,判断该告警是否存在恢复记录 + if (!empty($relateAlertId)) { + $alertEsc = mysqli_real_escape_string($connConf, $relateAlertId); + $checkResolveSql = "SELECT 1 FROM alert_log WHERE CONCAT(alert_name,'_',instance) = ? AND alert_type=2 LIMIT 1"; + $stmtCheck = mysqli_prepare($connConf, $checkResolveSql); + mysqli_stmt_bind_param($stmtCheck, 's', $alertEsc); + mysqli_stmt_execute($stmtCheck); + $checkRes = mysqli_stmt_get_result($stmtCheck); + if (mysqli_num_rows($checkRes) > 0) { + $status = 3; + } + } + + // 新增工单默认未读 is_read=0 + $sql = "INSERT INTO work_order(title,content,create_uid,assign_uid,relate_alert_id,notify_user,notify_channel,status,is_read,create_time,update_time) VALUES (?,?,?,?,?,?,?,?,0,NOW(),NOW())"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ssssssss', $title, $content, $loginUid, $assign, $relateAlertId, $notifyUser, $notifyChannel, $status); + $ok = mysqli_stmt_execute($stmt); + if (!$ok) { + echo json_encode(['code' => 500, 'msg' => '创建失败:' . mysqli_error($connWork)]); + exit; + } + $orderId = mysqli_insert_id($connWork); + sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单提交成功,通知已下发', 'init_status' => $status]); + exit; +} + +// 3、编辑工单 +if ($action === "edit") { + $id = intval($post['id'] ?? 0); + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $relateAlertId = trim($post['relate_alert_id'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + if ($id <= 0 || empty($title) || empty($content)) { + echo json_encode(['code' => 400, 'msg' => '参数不能为空']); + exit; + } + // 非管理员权限校验 + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限编辑该工单']); + exit; + } + } + $sql = "UPDATE work_order SET title=?,content=?,assign_uid=?,relate_alert_id=?,notify_user=?,notify_channel=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ssssssi', $title, $content, $assign, $relateAlertId, $notifyUser, $notifyChannel, $id); + mysqli_stmt_execute($stmt); + sendWorkOrderNotify($connConf, $connWork, $id, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单保存成功,通知已更新下发']); + exit; +} + +// 4、修改工单状态 +if ($action === "update_status") { + $id = intval($post['id'] ?? 0); + $status = intval($post['status'] ?? 1); + if ($id <= 0) { + echo json_encode(['code' => 400, 'msg' => '工单ID错误']); + exit; + } + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限操作该工单']); + exit; + } + } + // 修改状态自动标记已读 + $sql = "UPDATE work_order SET status=?,is_read=1,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ii', $status, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '状态更新成功']); + exit; +} + +// 5、管理员分发工单(前端统一action=assign,废弃assign_order) +if ($action === "assign") { + if ($isAdmin !== 1) { + echo json_encode(['code' => 403, 'msg' => '仅管理员可分发工单']); + exit; + } + $id = intval($post['id'] ?? 0); + $assignUid = trim($post['assign_uid'] ?? ''); + // 修复BUG:仅按工单唯一ID更新,不再使用标题模糊匹配,选中哪一行只修改该行工单 + $sql = "UPDATE work_order SET assign_uid=?,is_read=0,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'si', $assignUid, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单分发成功']); + exit; +} + +// 一键标记当前用户全部待处理工单为已读 +if ($action === 'mark_all_read') { + $uid = $post['uid'] ?? ''; + $sql = "UPDATE work_order SET is_read=1 WHERE assign_uid=? AND status=1"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, "s", $uid); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '已全部标记为已读']); + exit; +} + +// 语言切换 +if ($action === 'save_lang') { + $lang = $post['lang'] ?? 'zh'; + $sql = "UPDATE sys_config SET v=? WHERE k='lang'"; + $stmt = mysqli_prepare($connConf, $sql); + mysqli_stmt_bind_param($stmt, "s", $lang); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '成功']); + exit; +} + +// 新增:同步Prometheus实时告警,自动清理恢复告警(完全独立,无需index.php) +if ($action === "sync_prom_alerts") { + $promUrl = "http://10.150.117.190:9090/api/v1/alerts"; + $resp = @file_get_contents($promUrl); + if($resp === false){ + echo json_encode(["code"=>500,"msg"=>"无法连接Prometheus接口"],JSON_UNESCAPED_UNICODE); + exit; + } + $promData = json_decode($resp,true); + if(!isset($promData['data']['alerts'])){ + echo json_encode(["code"=>500,"msg"=>"Prometheus返回数据异常"],JSON_UNESCAPED_UNICODE); + exit; + } + + // 1. 先将表内所有告警标记为已恢复 + mysqli_query($connConf,"UPDATE alert_firing SET status='resolved'"); + + // 2. 遍历当前Prometheus活跃告警,写入/更新 + $alerts = $promData['data']['alerts'] ?? []; + foreach($alerts as $item){ + $alertName = $item['labels']['alertname'] ?? "unknown"; + $instance = $item['labels']['instance'] ?? "unknown"; + $alertId = $alertName."_".$instance; + $sql = "INSERT INTO alert_firing(alert_id,alert_name,instance,status,receive_time) VALUES (?,?,?,'firing',NOW()) ON DUPLICATE KEY UPDATE status='firing',receive_time=NOW()"; + $stmt = mysqli_prepare($connConf,$sql); + mysqli_stmt_bind_param($stmt,"sss",$alertId,$alertName,$instance); + mysqli_stmt_execute($stmt); + } + $syncNum = count($alerts); + + // 同步完成后自动执行工单状态更新 + $syncWorkUrl = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'] . "?action=auto_sync_workorder_status"; + @file_get_contents($syncWorkUrl); + + echo json_encode([ + "code"=>0, + "msg"=>"Prometheus告警同步完成,已自动同步工单状态", + "active_alert_total"=>$syncNum + ],JSON_UNESCAPED_UNICODE); + exit; +} + +// 定时同步:告警恢复自动完工单 +if($action === "sync_alert_auto_close"){ + // 1、拉取仪表盘实时未恢复告警 + $alertApi = "./index.php?act=active_firing"; + $raw = @file_get_contents($alertApi); + $activeList = json_decode($raw, true) ?: []; + $activeKeys = []; + foreach($activeList as $item){ + $activeKeys[] = $item['alert_name'] . "|" . $item['instance']; + } + // 2、查询所有未完成、绑定告警的工单 + $sql = "SELECT id, relate_alert_id FROM work_order WHERE status IN(1,2) AND relate_alert_id <> ''"; + $res = mysqli_query($connWork, $sql); + while($row = mysqli_fetch_assoc($res)){ + // 工单关联告警不在当前活跃列表=已恢复,自动设为完成 + if(!in_array($row['relate_alert_id'], $activeKeys)){ + $updateSql = "UPDATE work_order SET status=3, update_time=NOW() WHERE id = ".(int)$row['id']; + mysqli_query($connWork, $updateSql); + } + } + echo json_encode(['code'=>0, 'msg'=>'同步完成']); + exit; +} + +// ==================== 全局通知统一函数 ==================== +function sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUserStr, $channelStr) +{ + if (empty($notifyUserStr) || empty($channelStr)) return; + $userArr = explode(",", $notifyUserStr); + $channelArr = explode(",", $channelStr); + + // 读取完整通知配置(邮箱+钉钉+企微) + $cfgRes = mysqli_query($connConf, "SELECT * FROM sys_smtp_config WHERE id=1"); + $notifyCfg = $cfgRes ? mysqli_fetch_assoc($cfgRes) : []; + if(empty($notifyCfg)) return; + + // 获取工单完整信息 + $orderRes = mysqli_query($connWork, "SELECT * FROM work_order WHERE id=$orderId"); + $order = $orderRes ? mysqli_fetch_assoc($orderRes) : []; + $title = $order['title']; + $content = $order['content']; + $relateId = $order['relate_alert_id'] ?: "无"; + + $msgText = "【运维工单通知】\n工单ID:$orderId\n关联告警:$relateId\n标题:$title\n详情:$content"; + + foreach ($channelArr as $ch) { + $ch = trim($ch); + switch ($ch) { + case "mail": + sendMailNotify($notifyCfg, $connWork, $userArr, $title, $content, $relateId, $orderId); + break; + case "dingtalk": + sendDingNotify($notifyCfg, $msgText); + break; + case "wecom": + sendWecomNotify($notifyCfg, $msgText); + break; + } + } +} + +// 邮件发送 +function sendMailNotify($smtp, $connWork, $uidList, $title, $content, $relateId, $orderId) +{ + if (empty($smtp['smtp_host']) || empty($smtp['smtp_account'])) return; + $emailList = []; + foreach ($uidList as $uid) { + $uid = trim($uid); + if (empty($uid)) continue; + $res = mysqli_query($connWork, "SELECT email FROM sys_user WHERE uid='$uid'"); + $u = mysqli_fetch_assoc($res); + if (!empty($u['email'])) $emailList[] = $u['email']; + } + if (empty($emailList)) return; + $to = implode(",", array_unique($emailList)); + $subject = "【工单通知】#$orderId $title"; + $body = "

工单 #$orderId

+

关联告警ID:$relateId

+

标题:$title

+
$content
"; + // 此处接入PHPMailer发送逻辑 +} + +// 钉钉机器人推送 +function sendDingNotify($cfg, $text) +{ + $webhook = $cfg['ding_webhook'] ?? ''; + $secret = $cfg['ding_secret'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 企业微信机器人推送 +function sendWecomNotify($cfg, $text) +{ + $webhook = $cfg['wecom_webhook'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 无匹配动作 +echo json_encode(['code' => 400, 'msg' => '无效请求动作']); +mysqli_close($connWork); +mysqli_close($connConf); +exit; +?> diff --git a/api/work_order_api.php.9.0 b/api/work_order_api.php.9.0 new file mode 100644 index 0000000..e2dfc88 --- /dev/null +++ b/api/work_order_api.php.9.0 @@ -0,0 +1,515 @@ + 0, 'msg' => 'ok']); + exit; +} +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time']) > $expire) { + echo json_encode(['code' => 401, 'msg' => '登录失效']); + exit; +} +$loginUid = $_SESSION['user_id']; + +// 工单业务库 monitor +$dbWorkHost = '10.150.117.190'; +$dbWorkUser = 'root'; +$dbWorkPwd = 'hp93000'; +$dbWorkName = 'monitor'; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + echo json_encode(['code' => 500, 'msg' => '工单数据库连接失败:' . mysqli_connect_error()]); + exit; +} +mysqli_set_charset($connWork, 'utf8mb4'); + +// 配置库 alert_mail_stat(告警、通知配置统一此处) +$dbConfHost = "10.150.117.190"; +$dbConfUser = "root"; +$dbConfPwd = "hp93000"; +$dbConfName = "alert_mail_stat"; +$connConf = mysqli_connect($dbConfHost, $dbConfUser, $dbConfPwd, $dbConfName); +if(!$connConf){ + echo json_encode(['code' => 500, 'msg' => '配置库连接失败']); + exit; +} +mysqli_set_charset($connConf, "utf8mb4"); + +// 获取当前用户角色权限 +$isAdmin = 0; +$permList = ""; +$roleId = 0; +$roleSql = "SELECT r.is_admin, r.perm_list, u.role_id FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRes = mysqli_stmt_get_result($stmtRole); +$roleRow = $roleRes ? mysqli_fetch_assoc($roleRes) : []; +if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; + $roleId = intval($roleRow['role_id'] ?? 0); +} + +// 读取当前角色页面权限列表(用于分发工单权限判断) +$allowPages = []; +if ($roleId > 0) { + $permSql = "SELECT page_key FROM sys_role_permission WHERE role_id = ?"; + $stmtPerm = mysqli_prepare($connWork, $permSql); + mysqli_stmt_bind_param($stmtPerm, 'i', $roleId); + mysqli_stmt_execute($stmtPerm); + $pRes = mysqli_stmt_get_result($stmtPerm); + while ($p = mysqli_fetch_assoc($pRes)) { + $allowPages[] = $p['page_key']; + } +} + +$action = $_REQUEST['action'] ?? ''; +$post = json_decode(file_get_contents("php://input"), true) ?: []; + +// ===================== 工单列表查询(新增,解决数据可见权限隔离) ===================== +if ($action === "get_list") { + $page = intval($_GET['page'] ?? 1); + $size = intval($_GET['size'] ?? 20); + $offset = ($page - 1) * $size; + $status = trim($_GET['status'] ?? ''); + $keyword = trim($_GET['keyword'] ?? ''); + + $where = []; + $param = []; + $paramType = ''; + + // 普通用户:仅能查看自己创建 或 分配给自己的工单;管理员无限制查看全部 + if ($isAdmin !== 1) { + $where[] = "(create_uid = ? OR assign_uid = ?)"; + $param[] = $loginUid; + $param[] = $loginUid; + $paramType .= 'ss'; + } + + if ($status !== '') { + $where[] = "status = ?"; + $param[] = $status; + $paramType .= 'i'; + } + if ($keyword !== '') { + $where[] = "(title LIKE ? OR content LIKE ?)"; + $param[] = "%$keyword%"; + $param[] = "%$keyword%"; + $paramType .= 'ss'; + } + + $whereSql = $where ? "WHERE " . implode(" AND ", $where) : ""; + + // 分页列表 + $listSql = "SELECT * FROM work_order $whereSql ORDER BY create_time DESC LIMIT ?,?"; + $param[] = $offset; + $param[] = $size; + $paramType .= 'ii'; + + $stmtList = mysqli_prepare($connWork, $listSql); + mysqli_stmt_bind_param($stmtList, $paramType, ...$param); + mysqli_stmt_execute($stmtList); + $res = mysqli_stmt_get_result($stmtList); + $list = []; + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + + // 总数统计 + $countSql = "SELECT COUNT(id) total FROM work_order $whereSql"; + $stmtCount = mysqli_prepare($connWork, $countSql); + array_pop($param); + array_pop($param); + $paramTypeCount = rtrim($paramType, 'ii'); + if ($paramTypeCount) { + mysqli_stmt_bind_param($stmtCount, $paramTypeCount, ...$param); + } + mysqli_stmt_execute($stmtCount); + $countRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtCount)); + $total = intval($countRow['total']); + + echo json_encode([ + 'code' => 0, + 'list' => $list, + 'total' => $total, + 'page' => $page, + 'size' => $size + ], JSON_UNESCAPED_UNICODE); + exit; +} + +// ===================== 根据告警ID查询关联工单 ===================== +if ($action === "get_workorder_by_alertid") { + $alertId = trim($_GET['alert_id'] ?? ''); + if (empty($alertId)) { + echo json_encode(['code' => 400, 'msg' => '缺少告警ID参数']); + exit; + } + $alertEsc = mysqli_real_escape_string($connWork, $alertId); + $sql = "SELECT id,title,status,assign_uid,create_time FROM work_order WHERE relate_alert_id = ? ORDER BY create_time DESC"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 's', $alertEsc); + mysqli_stmt_execute($stmt); + $res = mysqli_stmt_get_result($stmt); + $list = []; + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + echo json_encode(['code' => 0, 'list' => $list]); + exit; +} + +// ===================== 自动同步告警状态,批量更新工单为已完成 ===================== +if ($action === "auto_sync_workorder_status") { + // 1. 查询所有已恢复的告警(alert_type=2),去重获取告警ID + $resolveSql = "SELECT DISTINCT CONCAT(alert_name,'_',instance) as alert_id FROM alert_log WHERE alert_type=2"; + $resolveRes = mysqli_query($connConf, $resolveSql); + $resolveAlertIds = []; + while ($row = mysqli_fetch_assoc($resolveRes)) { + $resolveAlertIds[] = $row['alert_id']; + } + if (empty($resolveAlertIds)) { + echo json_encode(['code' => 0, 'msg' => '暂无已恢复告警,无需更新工单', 'update_count' => 0]); + exit; + } + + // 2. 拼接IN条件,查询未完成、关联该告警的工单 + $inStr = implode("','", array_map(function($v) use ($connWork) { + return mysqli_real_escape_string($connWork, $v); + }, $resolveAlertIds)); + // status=1待处理 / status=2处理中,统一改为3已完成 + $updateSql = "UPDATE work_order SET status=3,update_time=NOW() WHERE relate_alert_id IN ('$inStr') AND status IN (1,2)"; + mysqli_query($connWork, $updateSql); + $updateCnt = mysqli_affected_rows($connWork); + + echo json_encode([ + 'code' => 0, + 'msg' => '工单状态自动同步完成,已恢复告警绑定工单全部置为已完成', + 'update_count' => $updateCnt + ], JSON_UNESCAPED_UNICODE); + exit; +} + +// 1、获取实时活跃告警(alert_mail_stat.alert_firing 数据源) +if ($action === "get_firing_alert") { + $alertSql = "SELECT alert_id,alert_name,instance FROM alert_firing WHERE status='firing' ORDER BY receive_time DESC LIMIT 100"; + $res = mysqli_query($connConf, $alertSql); + $list = []; + if($res instanceof mysqli_result){ + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + } + echo json_encode(['code' => 0, 'list' => $list]); + exit; +} + +// 2、新建工单(关联告警、多渠道通知 + 自动判断告警是否已恢复) +if ($action === "create") { + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $relateAlertId = trim($post['relate_alert_id'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + // 默认待处理1;若关联告警已恢复,直接置完成3 + $status = 1; + + if (!$title || !$content) { + echo json_encode(['code' => 400, 'msg' => '标题和内容不能为空']); + exit; + } + + // 关联了告警,判断该告警是否存在恢复记录 + if (!empty($relateAlertId)) { + $alertEsc = mysqli_real_escape_string($connConf, $relateAlertId); + $checkResolveSql = "SELECT 1 FROM alert_log WHERE CONCAT(alert_name,'_',instance) = ? AND alert_type=2 LIMIT 1"; + $stmtCheck = mysqli_prepare($connConf, $checkResolveSql); + mysqli_stmt_bind_param($stmtCheck, 's', $alertEsc); + mysqli_stmt_execute($stmtCheck); + $checkRes = mysqli_stmt_get_result($stmtCheck); + if (mysqli_num_rows($checkRes) > 0) { + $status = 3; + } + } + + // 新增工单默认未读 is_read=0 + $sql = "INSERT INTO work_order(title,content,create_uid,assign_uid,relate_alert_id,notify_user,notify_channel,status,is_read,create_time,update_time) VALUES (?,?,?,?,?,?,?,?,0,NOW(),NOW())"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ssssssss', $title, $content, $loginUid, $assign, $relateAlertId, $notifyUser, $notifyChannel, $status); + $ok = mysqli_stmt_execute($stmt); + if (!$ok) { + echo json_encode(['code' => 500, 'msg' => '创建失败:' . mysqli_error($connWork)]); + exit; + } + $orderId = mysqli_insert_id($connWork); + sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单提交成功,通知已下发', 'init_status' => $status]); + exit; +} + +// 3、编辑工单 +if ($action === "edit") { + $id = intval($post['id'] ?? 0); + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $relateAlertId = trim($post['relate_alert_id'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + if ($id <= 0 || empty($title) || empty($content)) { + echo json_encode(['code' => 400, 'msg' => '参数不能为空']); + exit; + } + // 非管理员权限校验 + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限编辑该工单']); + exit; + } + } + $sql = "UPDATE work_order SET title=?,content=?,assign_uid=?,relate_alert_id=?,notify_user=?,notify_channel=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ssssssi', $title, $content, $assign, $relateAlertId, $notifyUser, $notifyChannel, $id); + mysqli_stmt_execute($stmt); + sendWorkOrderNotify($connConf, $connWork, $id, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单保存成功,通知已更新下发']); + exit; +} + +// 4、修改工单状态 +if ($action === "update_status") { + $id = intval($post['id'] ?? 0); + $status = intval($post['status'] ?? 1); + if ($id <= 0) { + echo json_encode(['code' => 400, 'msg' => '工单ID错误']); + exit; + } + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限操作该工单']); + exit; + } + } + // 修改状态自动标记已读 + $sql = "UPDATE work_order SET status=?,is_read=1,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ii', $status, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '状态更新成功']); + exit; +} + +// 5、管理员/拥有system_manage权限角色 分发工单 +if ($action === "assign") { + // 修复:超级管理员 或 拥有system_manage页面权限均可分发工单 + if ($isAdmin !== 1 && !in_array("system_manage", $allowPages)) { + echo json_encode(['code' => 403, 'msg' => '无工单分发权限,请联系管理员']); + exit; + } + $id = intval($post['id'] ?? 0); + $assignUid = trim($post['assign_uid'] ?? ''); + // 修复BUG:仅按工单唯一ID更新,不再使用标题模糊匹配,选中哪一行只修改该行工单 + $sql = "UPDATE work_order SET assign_uid=?,is_read=0,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'si', $assignUid, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单分发成功']); + exit; +} + +// 一键标记当前用户全部待处理工单为已读 +if ($action === 'mark_all_read') { + $uid = $post['uid'] ?? ''; + $sql = "UPDATE work_order SET is_read=1 WHERE assign_uid=? AND status=1"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, "s", $uid); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '已全部标记为已读']); + exit; +} + +// 语言切换 +if ($action === 'save_lang') { + $lang = $post['lang'] ?? 'zh'; + $sql = "UPDATE sys_config SET v=? WHERE k='lang'"; + $stmt = mysqli_prepare($connConf, $sql); + mysqli_stmt_bind_param($stmt, "s", $lang); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '成功']); + exit; +} + +// 同步Prometheus实时告警,自动清理恢复告警 +if ($action === "sync_prom_alerts") { + $promUrl = "http://10.150.117.190:9090/api/v1/alerts"; + $resp = @file_get_contents($promUrl); + if($resp === false){ + echo json_encode(["code"=>500,"msg"=>"无法连接Prometheus接口"],JSON_UNESCAPED_UNICODE); + exit; + } + $promData = json_decode($resp,true); + if(!isset($promData['data']['alerts'])){ + echo json_encode(["code"=>500,"msg"=>"Prometheus返回数据异常"],JSON_UNESCAPED_UNICODE); + exit; + } + + // 1. 先将表内所有告警标记为已恢复 + mysqli_query($connConf,"UPDATE alert_firing SET status='resolved'"); + + // 2. 遍历当前Prometheus活跃告警,写入/更新 + $alerts = $promData['data']['alerts'] ?? []; + foreach($alerts as $item){ + $alertName = $item['labels']['alertname'] ?? "unknown"; + $instance = $item['labels']['instance'] ?? "unknown"; + $alertId = $alertName."_".$instance; + $sql = "INSERT INTO alert_firing(alert_id,alert_name,instance,status,receive_time) VALUES (?,?,?,'firing',NOW()) ON DUPLICATE KEY UPDATE status='firing',receive_time=NOW()"; + $stmt = mysqli_prepare($connConf,$sql); + mysqli_stmt_bind_param($stmt,"sss",$alertId,$alertName,$instance); + mysqli_stmt_execute($stmt); + } + $syncNum = count($alerts); + + // 同步完成后自动执行工单状态更新 + $syncWorkUrl = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'] . "?action=auto_sync_workorder_status"; + @file_get_contents($syncWorkUrl); + + echo json_encode([ + "code"=>0, + "msg"=>"Prometheus告警同步完成,已自动同步工单状态", + "active_alert_total"=>$syncNum + ],JSON_UNESCAPED_UNICODE); + exit; +} + +// 定时同步:告警恢复自动完工单 +if($action === "sync_alert_auto_close"){ + // 1、拉取仪表盘实时未恢复告警 + $alertApi = "./index.php?act=active_firing"; + $raw = @file_get_contents($alertApi); + $activeList = json_decode($raw, true) ?: []; + $activeKeys = []; + foreach($activeList as $item){ + $activeKeys[] = $item['alert_name'] . "|" . $item['instance']; + } + // 2、查询所有未完成、绑定告警的工单 + $sql = "SELECT id, relate_alert_id FROM work_order WHERE status IN(1,2) AND relate_alert_id <> ''"; + $res = mysqli_query($connWork, $sql); + while($row = mysqli_fetch_assoc($res)){ + // 工单关联告警不在当前活跃列表=已恢复,自动设为完成 + if(!in_array($row['relate_alert_id'], $activeKeys)){ + $updateSql = "UPDATE work_order SET status=3, update_time=NOW() WHERE id = ".(int)$row['id']; + mysqli_query($connWork, $updateSql); + } + } + echo json_encode(['code'=>0, 'msg'=>'同步完成']); + exit; +} + +// ==================== 全局通知统一函数 ==================== +function sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUserStr, $channelStr) +{ + if (empty($notifyUserStr) || empty($channelStr)) return; + $userArr = explode(",", $notifyUserStr); + $channelArr = explode(",", $channelStr); + + // 读取完整通知配置(邮箱+钉钉+企微) + $cfgRes = mysqli_query($connConf, "SELECT * FROM sys_smtp_config WHERE id=1"); + $notifyCfg = $cfgRes ? mysqli_fetch_assoc($cfgRes) : []; + if(empty($notifyCfg)) return; + + // 获取工单完整信息 + $orderRes = mysqli_query($connWork, "SELECT * FROM work_order WHERE id=$orderId"); + $order = $orderRes ? mysqli_fetch_assoc($orderRes) : []; + $title = $order['title']; + $content = $order['content']; + $relateId = $order['relate_alert_id'] ?: "无"; + + $msgText = "【运维工单通知】\n工单ID:$orderId\n关联告警:$relateId\n标题:$title\n详情:$content"; + + foreach ($channelArr as $ch) { + $ch = trim($ch); + switch ($ch) { + case "mail": + sendMailNotify($notifyCfg, $connWork, $userArr, $title, $content, $relateId, $orderId); + break; + case "dingtalk": + sendDingNotify($notifyCfg, $msgText); + break; + case "wecom": + sendWecomNotify($notifyCfg, $msgText); + break; + } + } +} + +// 邮件发送 +function sendMailNotify($smtp, $connWork, $uidList, $title, $content, $relateId, $orderId) +{ + if (empty($smtp['smtp_host']) || empty($smtp['smtp_account'])) return; + $emailList = []; + foreach ($uidList as $uid) { + $uid = trim($uid); + if (empty($uid)) continue; + $res = mysqli_query($connWork, "SELECT email FROM sys_user WHERE uid='$uid'"); + $u = mysqli_fetch_assoc($res); + if (!empty($u['email'])) $emailList[] = $u['email']; + } + if (empty($emailList)) return; + $to = implode(",", array_unique($emailList)); + $subject = "【工单通知】#$orderId $title"; + $body = "

工单 #$orderId

+

关联告警ID:$relateId

+

标题:$title

+
$content
"; + // 此处接入PHPMailer发送逻辑 +} + +// 钉钉机器人推送 +function sendDingNotify($cfg, $text) +{ + $webhook = $cfg['ding_webhook'] ?? ''; + $secret = $cfg['ding_secret'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 企业微信机器人推送 +function sendWecomNotify($cfg, $text) +{ + $webhook = $cfg['wecom_webhook'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 无匹配动作 +echo json_encode(['code' => 400, 'msg' => '无效请求动作']); +mysqli_close($connWork); +mysqli_close($connConf); +exit; +?> diff --git a/api/work_order_api.php.bak b/api/work_order_api.php.bak new file mode 100644 index 0000000..ce696eb --- /dev/null +++ b/api/work_order_api.php.bak @@ -0,0 +1,104 @@ + 0])); +} +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + echo json_encode(['code' => 401, 'msg' => '登录失效']); + exit; +} +$loginUid = $_SESSION['user_id']; + +// 数据库配置,优先本地localhost +$dbHost = '10.150.117.190'; +$dbUser = 'root'; +$dbPwd = 'hp93000'; +$dbName = 'monitor'; +$dbPort = 3306; + +// 关键:连接后立刻判断是否失败 +$conn = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName, $dbPort); +if (!$conn) { + echo json_encode([ + 'code' => 500, + 'msg' => '数据库连接失败:' . mysqli_connect_error() . ' 错误码:' . mysqli_connect_errno() + ]); + exit; +} +// 只有连接成功才执行字符集 +mysqli_set_charset($conn, 'utf8mb4'); + +// 下面原有业务代码不变 ... +// 获取角色 +$isAdmin = 0; +$r = mysqli_query($conn,"SELECT r.is_admin FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid='$loginUid'"); +if($rr = mysqli_fetch_assoc($r)) $isAdmin = intval($rr['is_admin']); +$action = $_REQUEST['action'] ?? ''; +$post = json_decode(file_get_contents("php://input"),true) ?: []; + +// 1、新建工单 +if($action === "create"){ + $title = $post['title'] ?? ''; + $content = $post['content'] ?? ''; + $assign = $post['assign_uid'] ?? ''; + if(!$title || !$content){ + echo json_encode(['code'=>400,'msg'=>'标题和内容不能为空']); + exit; + } + $sql = "INSERT INTO work_order(title,content,create_uid,assign_uid,status,create_time,update_time) VALUES (?,?,?,?,?,NOW(),NOW())"; + $stmt = mysqli_prepare($conn,$sql); + mysqli_stmt_bind_param($stmt,'ssssi',$title,$content,$loginUid,$assign,1); + $ok = mysqli_stmt_execute($stmt); + if($ok) echo json_encode(['code'=>0,'msg'=>'工单提交成功']); + else echo json_encode(['code'=>500,'msg'=>'提交失败:'.mysqli_error($conn)]); + exit; +} + +// 2、修改工单状态 +if($action === "update_status"){ + $id = intval($post['id'] ?? 0); + $status = intval($post['status'] ?? 1); + if($id <=0){ + echo json_encode(['code'=>400,'msg'=>'工单ID错误']); + exit; + } + // 权限校验:普通用户只能改自己创建/分配给自己的工单 + if($isAdmin !== 1){ + $chk = mysqli_query($conn,"SELECT id FROM work_order WHERE id=$id AND (create_uid='$loginUid' OR assign_uid='$loginUid')"); + if(mysqli_num_rows($chk) === 0){ + echo json_encode(['code'=>403,'msg'=>'无权限操作该工单']); + exit; + } + } + $sql = "UPDATE work_order SET status=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($conn,$sql); + mysqli_stmt_bind_param($stmt,'ii',$status,$id); + mysqli_stmt_execute($stmt); + echo json_encode(['code'=>0,'msg'=>'状态更新成功']); + exit; +} + +// 3、管理员分发工单 +if($action === "assign_order"){ + if($isAdmin !== 1){ + echo json_encode(['code'=>403,'msg'=>'仅管理员可分发工单']); + exit; + } + $id = intval($post['id'] ?? 0); + $assignUid = $post['assign_uid'] ?? ''; + $sql = "UPDATE work_order SET assign_uid=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($conn,$sql); + mysqli_stmt_bind_param($stmt,'si',$assignUid,$id); + mysqli_stmt_execute($stmt); + echo json_encode(['code'=>0,'msg'=>'工单分发成功']); + exit; +} + +echo json_encode(['code'=>400,'msg'=>'无效操作']); +mysqli_close($conn); +exit; +?> diff --git a/auth.php b/auth.php new file mode 100644 index 0000000..126661c --- /dev/null +++ b/auth.php @@ -0,0 +1,163 @@ + $expireTime) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); + +// 登录用户基础信息 +$loginUserId = $_SESSION['user_id']; +$userName = htmlspecialchars($_SESSION['username'] ?? ''); +$isAdmin = intval($_SESSION['is_admin'] ?? 0); +$userRoleId = intval($_SESSION['role_id'] ?? 0); + +// ====================== 双库固定连接 ====================== +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPass = "hp93000"; + +// 业务库 alert_mail_stat(工单、SMTP、大盘) +$dbAlertName = "alert_mail_stat"; +$connAlert = mysqli_connect($dbHost, $dbUser, $dbPass, $dbAlertName); +if (!$connAlert) { + die("业务库alert_mail_stat连接失败:" . mysqli_connect_error()); +} +mysqli_set_charset($connAlert, "utf8mb4"); + +// 权限库 monitor(用户、角色、权限、消息) +$dbMonitorName = "monitor"; +$connMonitor = mysqli_connect($dbHost, $dbUser, $dbPass, $dbMonitorName); +if (!$connMonitor) { + die("权限库monitor连接失败:" . mysqli_connect_error()); +} +mysqli_set_charset($connMonitor, "utf8mb4"); +// ======================================================================== + +// ========== 新增:读取角色真实名称 ========== +$roleRealName = "未知角色"; +if ($userRoleId > 0) { + $getRoleSql = "SELECT role_name FROM sys_role WHERE id = $userRoleId"; + $roleResult = mysqli_query($connMonitor, $getRoleSql); + if ($roleResult && $roleRow = mysqli_fetch_assoc($roleResult)) { + $roleRealName = $roleRow['role_name']; + } +} +// 超级管理员强制覆盖文字 +if ($isAdmin === 1) { + $roleRealName = "超级管理员"; +} +// =========================================== + +// 1. 登录时一次性加载当前角色全部权限,存入全局变量(侧边栏共用) +$allowPages = []; +if ($userRoleId > 0) { + $permSql = "SELECT page_key FROM sys_role_permission WHERE role_id = $userRoleId"; + $permRes = mysqli_query($connMonitor, $permSql); + if ($permRes) { + while ($row = mysqli_fetch_assoc($permRes)) { + $allowPages[] = $row['page_key']; + } + } +} + +// 2. 获取当前访问页面文件名(去掉.php后缀) +$currentPage = basename($_SERVER['SCRIPT_NAME'], '.php'); + +// 3. 非管理员自动拦截无权限页面(全局统一校验,无需每个页面重复写) +if ($isAdmin !== 1 && !in_array($currentPage, $allowPages)) { + echo ""; + exit; +} + +// 读取右上角未读消息数量 +$unreadMsgCount = 0; +$msgSql = "SELECT COUNT(id) cnt FROM sys_user_msg WHERE user_id = $loginUserId AND is_read = 0"; +$msgRes = mysqli_query($connMonitor, $msgSql); +if ($msgRes) { + $msgRow = mysqli_fetch_assoc($msgRes); + $unreadMsgCount = intval($msgRow['cnt']); +} + +// 读取系统基础配置 +$sysConfig = []; +$configSql = "SELECT k, v FROM sys_config"; +$configRes = mysqli_query($connAlert, $configSql); +if ($configRes) { + while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; + } +} +$currentLang = $sysConfig['lang'] ?? "zh"; +$sidebarRawLinks = $sysConfig['quick_link'] ?? ""; + +// 多语言字典 +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_title' => '运维监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警总览', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'notify_config' => '消息通知配置', + 'role_manage' => '角色管理', + 'user_manage' => '用户管理', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh' => '刷新页面', + 'logout' => '退出登录', + 'unread_msg' => '未读消息' + ], + 'en' => [ + 'html_lang' => 'en', + 'page_title' => "Monitor Platform", + 'monitor_panel' => "Monitor Panel", + 'alert_overview' => "Alert Dashboard", + 'quick_link' => "Quick Link", + 'system_manage' => "System Manage", + 'notify_config' => "Notify Config", + 'role_manage' => "Role Manage", + 'user_manage' => "User Manage", + 'current_user' => "User: ", + 'sys_time' => "Time: ", + 'refresh' => "Refresh", + 'logout' => "Logout", + 'unread_msg' => "Unread Msg" + ] +]; +$t = $langMap[$currentLang]; + +// 解析侧边栏外链 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line); + if (count($item) === 2) { + $sidebarLinkList[] = [ + 'name' => trim($item[0]), + 'url' => trim($item[1]) + ]; + } + } +} + +// 【已删除冲突无用函数 hasPagePerm】 +?> diff --git a/dashbaord.en-zh.php b/dashbaord.en-zh.php new file mode 100644 index 0000000..82f6e8c --- /dev/null +++ b/dashbaord.en-zh.php @@ -0,0 +1,1094 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +// 刷新登录计时 +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +// 读取全局系统配置(admin后台保存后同步生效) +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} +mysqli_close($connConfig); + +// 赋值全局配置 +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$themeColor = htmlspecialchars($sysConfig['theme_color'] ?? "#409eff"); +$pageSize = $sysConfig['page_size'] ?? "20"; +$footerText = htmlspecialchars($sysConfig['footer_text'] ?? ""); +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +// 读取语言配置 zh=中文 en=英文 +$currentLang = $sysConfig['lang'] ?? "zh"; + +// 全局多语言词典 +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警监控总览', + 'disk_capacity' => '服务器磁盘容量', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '后台配置管理', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新全部数据', + 'export_csv' => '导出告警CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'today_fire' => '今日触发告警', + 'unresolved_now' => '当前未恢复告警', + 'resolved_today' => '今日恢复告警', + 'instance_total' => '故障实例总数', + 'recovery_rate' => '告警恢复率', + 'today_fire_sub' => 'Total Firing Today', + 'unresolved_sub' => 'Unresolved Now', + 'resolved_sub' => 'Resolved Today', + 'instance_sub' => 'Affected Host Instance', + 'rate_sub' => 'Daily Recovery Rate', + 'top10_alert' => '今日告警频次 TOP 10', + 'active_alert' => '当前未恢复活跃告警', + 'alert_count' => '条未恢复故障', + 'all_alert_log' => '今日全量告警明细列表', + 'total_alert' => '条告警记录', + 'tag' => '告警状态', + 'alert_name' => '告警名称', + 'instance_addr' => '实例地址', + 'severity' => '告警级别', + 'occur_time' => '故障发生时间', + 'empty_normal' => '当前无未恢复告警,系统运行正常', + 'empty_no_data' => '暂无今日告警数据', + 'disk_stat' => '用户目录磁盘占用统计', + 'filter_ip' => '筛选实例IP:', + 'export_disk' => '导出当前表格CSV', + 'all_instance' => '全部实例', + 'disk_loading' => '磁盘数据加载中...', + 'no_disk_data' => '暂无磁盘指标数据', + 'no_ip_data' => '该实例下无目录数据', + 'csv_tip' => '正在生成CSV报表,请稍候...', + 'alert_axis' => '告警次数', + 'data_fail' => '数据加载失败,请重新登录', + 'server_fail' => '接口数据加载失败,请检查后端服务', + 'disk_api_fail' => '磁盘接口异常:', + 'disk_request_fail' => '请求df.php接口失败,请检查服务', + 'no_export_data' => '无数据可导出' + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'disk_capacity' => 'Server Disk Capacity', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh All Data', + 'export_csv' => 'Export Alert CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'today_fire' => 'Today Triggered Alerts', + 'unresolved_now' => 'Unresolved Alerts', + 'resolved_today' => 'Resolved Today', + 'instance_total' => 'Affected Instances', + 'recovery_rate' => 'Daily Recovery Rate', + 'today_fire_sub' => 'Total Firing Today', + 'unresolved_sub' => 'Unresolved Now', + 'resolved_sub' => 'Resolved Today', + 'instance_sub' => 'Affected Host Instance', + 'rate_sub' => 'Daily Recovery Rate', + 'top10_alert' => 'Top 10 Alert Frequency Today', + 'active_alert' => 'Active Unresolved Alerts', + 'alert_count' => ' unresolved alerts', + 'all_alert_log' => 'Today Full Alert List', + 'total_alert' => ' alert records', + 'tag' => 'Status', + 'alert_name' => 'Alert Name', + 'instance_addr' => 'Instance IP', + 'severity' => 'Severity', + 'occur_time' => 'Occur Time', + 'empty_normal' => 'No active alerts, system normal', + 'empty_no_data' => 'No alert data today', + 'disk_stat' => 'User Directory Disk Usage', + 'filter_ip' => 'Filter IP: ', + 'export_disk' => 'Export Table CSV', + 'all_instance' => 'All Instances', + 'disk_loading' => 'Loading disk data...', + 'no_disk_data' => 'No disk data available', + 'no_ip_data' => 'No directory data for this instance', + 'csv_tip' => 'Generating CSV file, please wait...', + 'alert_axis' => 'Alert Count', + 'data_fail' => 'Data load failed, please relogin', + 'server_fail' => 'API request failed, check backend service', + 'disk_api_fail' => 'Disk API Error: ', + 'disk_request_fail' => 'Request df.php failed, check service', + 'no_export_data' => 'No data to export' + ] +]; +$t = $langMap[$currentLang]; + +// 解析侧边外链列表 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = [ + "name" => trim($item[0]), + "url" => trim($item[1]) + ]; + } + } +} +?> + + + + + +<?php echo $pageTitle; ?> - Advantest <?php echo $t['page_subtitle']; ?> + + + + + + +
+
+ + +
+
+ +
+ + + + +
+
+
+
+
Advantest
+
+
+
+
+ + -- + +
+ + +
+ +
+ + +
+ +
+
+ +
+ +
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0%
+
+
+
+ + +
+
+
+
+
+
+
+
+ + +
+
+
+
+
0
+
+
+ + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
0
+
+
+ + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+ + + +
+
+
+ + + + + + + + + + + + + + +
IPUsernamePathSize(GB)
+
+
+
+
+
+
+
+
+
+
+ + + + diff --git a/dashbaord.php.local.9 b/dashbaord.php.local.9 new file mode 100644 index 0000000..9b1cfb8 --- /dev/null +++ b/dashbaord.php.local.9 @@ -0,0 +1,954 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +// 刷新登录计时 +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +// 读取全局系统配置(admin后台保存后同步生效) +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} +mysqli_close($connConfig); + +// 赋值全局配置 +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$themeColor = htmlspecialchars($sysConfig['theme_color'] ?? "#409eff"); +$pageSize = $sysConfig['page_size'] ?? "20"; +$footerText = htmlspecialchars($sysConfig['footer_text'] ?? ""); +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +// 解析侧边外链列表 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = [ + "name" => trim($item[0]), + "url" => trim($item[1]) + ]; + } + } +} +?> + + + + + +<?php echo $pageTitle; ?> - Advantest 爱德万测试 - 运维告警监控平台 + + + + + + + + + +
+
+ + 正在生成CSV报表,请稍候... +
+
+ +
+ + + + +
+
+
+
+
Advantest
+
爱德万测试 · 运维告警监控平台
+
+
+
+ + 系统时间:-- + +
+ + +
+ +
+
+ +
+ +
+ +
+
+
+
今日触发告警
+
+
+
0
+
Total Firing Today
+
+
+
+
当前未恢复告警
+
+
+
0
+
Unresolved Now
+
+
+
+
今日恢复告警
+
+
+
0
+
Resolved Today
+
+
+
+
故障实例总数
+
+
+
0
+
Affected Host Instance
+
+
+
+
告警恢复率
+
+
+
0%
+
Daily Recovery Rate
+
+
+ + +
+
+
+
今日告警频次 TOP 10
+
+
+
+
+ + +
+
+
+
当前未恢复活跃告警
+
0 条未恢复故障
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
当前无未恢复告警,系统运行正常
+
+
+
+
+
+ + +
+
+
+
今日全量告警明细列表
+
0 条告警记录
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
暂无今日告警数据
+
+
+
+
+
+
+ + +
+
+
+
+
用户目录磁盘占用统计
+
+ + + +
+
+
+ + + + + + + + + + + + + + +
实例IP用户名目录路径占用容量
+
+
磁盘数据加载中...
+
+
+
+
+
+
+
+
+ + + + diff --git a/dashboard.html b/dashboard.html new file mode 100644 index 0000000..eee766a --- /dev/null +++ b/dashboard.html @@ -0,0 +1,707 @@ + + + + + + 告警监控看板 | Alert Dashboard + + + + + + +
+
+ + 正在生成CSV报表,请稍候... +
+
+ + +
+

告警监控看板

+
+ 最后更新:-- + + +
+
+ +
+ + +
+
+
+ ! + 今日触发告警 +
+
0
+
Firing Alerts
+
+
+
+ + 今日恢复告警 +
+
0
+
Resolved Alerts
+
+
+
+ # + 涉及故障实例 +
+
0
+
Affected Instances
+
+
+
+ % + 恢复率 +
+
0%
+
Recovery Rate
+
+
+ + +
+
+
今日告警次数 TOP 10
+
+
+
+ + +
+
+
告警明细列表
+
0 条记录
+
+
+ + + + + + + + + + + + + + + + +
状态告警名称实例地址级别故障开始时间接收时间
+
+
📊
+
数据加载中...
+
+
+
+
+ +
+ + + + + diff --git a/dashboard.html.6-30 b/dashboard.html.6-30 new file mode 100644 index 0000000..2242270 --- /dev/null +++ b/dashboard.html.6-30 @@ -0,0 +1,711 @@ + + + + + + 告警监控看板 | Alert Dashboard + + + + + + +
+
+ + 正在生成CSV报表,请稍候... +
+
+ + +
+

告警监控看板

+
+ 最后更新:-- + + +
+
+ +
+ + +
+
+
+ ! + 今日触发告警 +
+
0
+
Firing Alerts
+
+
+
+ + 今日恢复告警 +
+
0
+
Resolved Alerts
+
+
+
+ # + 涉及故障实例 +
+
0
+
Affected Instances
+
+
+
+ % + 恢复率 +
+
0%
+
Recovery Rate
+
+
+ + +
+
+
今日告警次数 TOP 10
+
+
+
+ + +
+
+
告警明细列表
+
0 条记录
+
+
+ + + + + + + + + + + + + + + + + +
状态告警名称实例地址级别故障开始时间恢复时间接收时间
+
+
📊
+
数据加载中...
+
+
+
+
+ +
+ + + + + diff --git a/dashboard.html.bak b/dashboard.html.bak new file mode 100644 index 0000000..c21bf10 --- /dev/null +++ b/dashboard.html.bak @@ -0,0 +1,97 @@ + + + + +告警邮件统计看板 + + + + + +

当日告警邮件统计看板

+
+
+

今日触发告警总数

+

0

+
+
+

今日恢复告警总数

+

0

+
+
+

涉及故障实例数

+

0

+
+
+
+
+
+ + + + + + + + + + + + + +
类型告警名称实例级别故障开始恢复时间邮件接收时间
+ + + + + diff --git a/dashboard.html.bak2 b/dashboard.html.bak2 new file mode 100644 index 0000000..30b8167 --- /dev/null +++ b/dashboard.html.bak2 @@ -0,0 +1,663 @@ + + + + + + 告警监控看板 | Alert Dashboard + + + + + + + +
+

告警监控看板

+
+ 最后更新:-- + +
+
+ +
+ + +
+
+
+ ! + 今日触发告警 +
+
0
+
Firing Alerts
+
+
+
+ + 今日恢复告警 +
+
0
+
Resolved Alerts
+
+
+
+ # + 涉及故障实例 +
+
0
+
Affected Instances
+
+
+
+ % + 恢复率 +
+
0%
+
Recovery Rate
+
+
+ + +
+
+
今日告警次数 TOP 10
+
+
+
+ + +
+
+
告警明细列表
+
0 条记录
+
+
+ + + + + + + + + + + + + + + + + +
状态告警名称实例地址级别故障开始时间恢复时间接收时间
+
+
📊
+
数据加载中...
+
+
+
+
+ +
+ + + + + diff --git a/dashboard.php b/dashboard.php new file mode 100644 index 0000000..53ec939 --- /dev/null +++ b/dashboard.php @@ -0,0 +1,1193 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +// 刷新登录计时 +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +// 读取全局系统配置(admin后台保存后同步生效) +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} +mysqli_close($connConfig); + +// 赋值全局配置 +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$themeColor = htmlspecialchars($sysConfig['theme_color'] ?? "#409eff"); +$pageSize = $sysConfig['page_size'] ?? "20"; +$footerText = htmlspecialchars($sysConfig['footer_text'] ?? ""); +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +// 读取语言配置 zh=中文 en=英文 +$currentLang = $sysConfig['lang'] ?? "zh"; + +// 全局多语言词典 +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警监控总览', + 'disk_capacity' => '服务器磁盘容量', + 'docker_mgr' => 'Docker容器管理', + 'alert_list_page' => '历史告警查询', + 'work_order_mgr' => '工单系统', + 'system_manager' => '角色管理', + 'work_order_title' => '工单管理', + 'work_create' => '新建工单', + 'work_edit' => '编辑工单', + 'work_assign' => '分发工单', + 'work_status' => '工单状态', + 'work_creator' => '创建人', + 'work_handler' => '处理人', + 'work_content' => '工单内容/备注', + 'work_title' => '工单标题', + 'work_create_time' => '创建时间', + 'work_update_time' => '更新时间', + 'work_all_list' => '全部工单列表', + 'work_no_data' => '暂无工单记录', + 'work_save' => '保存', + 'work_cancel' => '取消', + 'work_placeholder_title' => '填写故障/需求标题', + 'work_placeholder_content' => '详细描述故障、操作步骤、处理备注', + 'work_select_handler' => '选择处理人(留空暂不分配)', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '后台配置管理', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新全部数据', + 'export_csv' => '导出告警CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'today_fire' => '今日触发告警', + 'unresolved_now' => '当前未恢复告警', + 'resolved_today' => '今日恢复告警', + 'instance_total' => '故障实例总数', + 'recovery_rate' => '告警恢复率', + 'today_fire_sub' => 'Total Firing Today', + 'unresolved_sub' => 'Unresolved Now', + 'resolved_sub' => 'Resolved Today', + 'instance_sub' => 'Affected Host Instance', + 'rate_sub' => 'Daily Recovery Rate', + 'top10_alert' => '今日告警频次 TOP 10', + 'active_alert' => '当前未恢复活跃告警', + 'alert_count' => '条未恢复故障', + 'all_alert_log' => '今日全量告警明细列表', + 'total_alert' => '条告警记录', + 'tag' => '告警状态', + 'alert_name' => '告警名称', + 'instance_addr' => '实例地址', + 'severity' => '告警级别', + 'occur_time' => '故障发生时间', + 'empty_normal' => '当前无未恢复告警,系统运行正常', + 'empty_no_data' => '暂无今日告警数据', + 'disk_stat' => '用户目录磁盘占用统计', + 'filter_ip' => '筛选实例IP:', + 'export_disk' => '导出当前表格CSV', + 'all_instance' => '全部实例', + 'disk_loading' => '磁盘数据加载中...', + 'no_disk_data' => '暂无磁盘指标数据', + 'no_ip_data' => '该实例下无目录数据', + 'csv_tip' => '正在生成CSV报表,请稍候...', + 'alert_axis' => '告警次数', + 'data_fail' => '数据加载失败,请重新登录', + 'server_fail' => '接口数据加载失败,请检查后端服务', + 'disk_api_fail' => '磁盘接口异常:', + 'disk_request_fail' => '请求df.php接口失败,请检查服务', + 'no_export_data' => '无数据可导出' + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'disk_capacity' => 'Server Disk Capacity', + 'docker_mgr' => 'Docker Manager', + 'alert_list_page' => 'Alert Pagination List', + 'work_order_mgr' => 'Work Order System', + 'system_manager' => 'Role & Permission Manage', + 'work_order_title' => 'Work Order Manage', + 'work_create' => 'Create Order', + 'work_edit' => 'Edit Order', + 'work_assign' => 'Assign Order', + 'work_status' => 'Status', + 'work_creator' => 'Creator', + 'work_handler' => 'Handler', + 'work_content' => 'Content / Remark', + 'work_title' => 'Order Title', + 'work_create_time' => 'Create Time', + 'work_update_time' => 'Update Time', + 'work_all_list' => 'All Work Order List', + 'work_no_data' => 'No order data', + 'work_save' => 'Save', + 'work_cancel' => 'Cancel', + 'work_placeholder_title' => 'Fill fault or demand title', + 'work_placeholder_content' => 'Describe fault, steps and handling remark', + 'work_select_handler' => 'Select handler (empty for unassigned)', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh All Data', + 'export_csv' => 'Export Alert CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'today_fire' => 'Today Triggered Alerts', + 'unresolved_now' => 'Unresolved Alerts', + 'resolved_today' => 'Resolved Today', + 'instance_total' => 'Affected Instances', + 'recovery_rate' => 'Daily Recovery Rate', + 'today_fire_sub' => 'Total Firing Today', + 'unresolved_sub' => 'Unresolved Now', + 'resolved_sub' => 'Resolved Today', + 'instance_sub' => 'Affected Host Instance', + 'rate_sub' => 'Daily Recovery Rate', + 'top10_alert' => 'Top 10 Alert Frequency Today', + 'active_alert' => 'Active Unresolved Alerts', + 'alert_count' => ' unresolved alerts', + 'all_alert_log' => 'Today Full Alert List', + 'total_alert' => ' alert records', + 'tag' => 'Status', + 'alert_name' => 'Alert Name', + 'instance_addr' => 'Instance IP', + 'severity' => 'Severity', + 'occur_time' => 'Occur Time', + 'empty_normal' => 'No active alerts, system normal', + 'empty_no_data' => 'No alert data today', + 'disk_stat' => 'User Directory Disk Usage', + 'filter_ip' => 'Filter IP: ', + 'export_disk' => 'Export Table CSV', + 'all_instance' => 'All Instances', + 'disk_loading' => 'Loading disk data...', + 'no_disk_data' => 'No disk data available', + 'no_ip_data' => 'No directory data for this instance', + 'csv_tip' => 'Generating CSV file, please wait...', + 'alert_axis' => 'Alert Count', + 'data_fail' => 'Data load failed, please relogin', + 'server_fail' => 'API request failed, check backend service', + 'disk_api_fail' => 'Disk API Error: ', + 'disk_request_fail' => 'Request df.php failed, check service', + 'no_export_data' => 'No data to export' + ] +]; +$t = $langMap[$currentLang]; + +// 解析侧边外链列表 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = [ + "name" => trim($item[0]), + "url" => trim($item[1]) + ]; + } + } +} +?> + + + + + +<?php echo $pageTitle; ?> - Advantest <?php echo $t['page_subtitle']; ?> + + + + + + +
+
+ + +
+
+
+ + + +
+
+
+
+
Advantest
+
+
+
+
+ + -- + +
+ + +
+ +
+ + +
+ +
+
+ +
+ +
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0%
+
+
+
+ + +
+
+
+
+
+
+
+
+ + +
+
+
+
+
0
+
+
+ + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
0
+
+
+ + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+ + + +
+
+
+ + + + + + + + + + + + + + +
IPUsernamePathSize(GB)
+
+
+
+
+
+
+
+
+
+
+ + + + diff --git a/dashboard.php.1.0.3 b/dashboard.php.1.0.3 new file mode 100644 index 0000000..3bb861d --- /dev/null +++ b/dashboard.php.1.0.3 @@ -0,0 +1,1175 @@ +alert('无访问权限');location.href='login.php';"; + exit; +} + +// 会话超时:30分钟无操作自动登出,与admin后台统一 +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +// 刷新登录计时 +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +// 读取全局系统配置(admin后台保存后同步生效) +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} +mysqli_close($connConfig); + +// 赋值全局配置 +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$themeColor = htmlspecialchars($sysConfig['theme_color'] ?? "#409eff"); +$pageSize = $sysConfig['page_size'] ?? "20"; +$footerText = htmlspecialchars($sysConfig['footer_text'] ?? ""); +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +// 读取语言配置 zh=中文 en=英文 +$currentLang = $sysConfig['lang'] ?? "zh"; + +// 全局多语言词典 +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警监控总览', + 'disk_capacity' => '服务器磁盘容量', + 'docker_mgr' => 'Docker容器管理', + 'alert_list_page' => '历史告警查询', + 'work_order_mgr' => '工单系统', + 'system_manager' => '角色管理', + 'work_order_title' => '工单管理', + 'work_create' => '新建工单', + 'work_edit' => '编辑工单', + 'work_assign' => '分发工单', + 'work_status' => '工单状态', + 'work_creator' => '创建人', + 'work_handler' => '处理人', + 'work_content' => '工单内容/备注', + 'work_title' => '工单标题', + 'work_create_time' => '创建时间', + 'work_update_time' => '更新时间', + 'work_all_list' => '全部工单列表', + 'work_no_data' => '暂无工单记录', + 'work_save' => '保存', + 'work_cancel' => '取消', + 'work_placeholder_title' => '填写故障/需求标题', + 'work_placeholder_content' => '详细描述故障、操作步骤、处理备注', + 'work_select_handler' => '选择处理人(留空暂不分配)', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '后台配置管理', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新全部数据', + 'export_csv' => '导出告警CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'today_fire' => '今日触发告警', + 'unresolved_now' => '当前未恢复告警', + 'resolved_today' => '今日恢复告警', + 'instance_total' => '故障实例总数', + 'recovery_rate' => '告警恢复率', + 'today_fire_sub' => 'Total Firing Today', + 'unresolved_sub' => 'Unresolved Now', + 'resolved_sub' => 'Resolved Today', + 'instance_sub' => 'Affected Host Instance', + 'rate_sub' => 'Daily Recovery Rate', + 'top10_alert' => '今日告警频次 TOP 10', + 'active_alert' => '当前未恢复活跃告警', + 'alert_count' => '条未恢复故障', + 'all_alert_log' => '今日全量告警明细列表', + 'total_alert' => '条告警记录', + 'tag' => '告警状态', + 'alert_name' => '告警名称', + 'instance_addr' => '实例地址', + 'severity' => '告警级别', + 'occur_time' => '故障发生时间', + 'empty_normal' => '当前无未恢复告警,系统运行正常', + 'empty_no_data' => '暂无今日告警数据', + 'disk_stat' => '用户目录磁盘占用统计', + 'filter_ip' => '筛选实例IP:', + 'export_disk' => '导出当前表格CSV', + 'all_instance' => '全部实例', + 'disk_loading' => '磁盘数据加载中...', + 'no_disk_data' => '暂无磁盘指标数据', + 'no_ip_data' => '该实例下无目录数据', + 'csv_tip' => '正在生成CSV报表,请稍候...', + 'alert_axis' => '告警次数', + 'data_fail' => '数据加载失败,请重新登录', + 'server_fail' => '接口数据加载失败,请检查后端服务', + 'disk_api_fail' => '磁盘接口异常:', + 'disk_request_fail' => '请求df.php接口失败,请检查服务', + 'no_export_data' => '无数据可导出' + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'disk_capacity' => 'Server Disk Capacity', + 'docker_mgr' => 'Docker Manager', + 'alert_list_page' => 'Alert Pagination List', + 'work_order_mgr' => 'Work Order System', + 'system_manager' => 'Role & Permission Manage', + 'work_order_title' => 'Work Order Manage', + 'work_create' => 'Create Order', + 'work_edit' => 'Edit Order', + 'work_assign' => 'Assign Order', + 'work_status' => 'Status', + 'work_creator' => 'Creator', + 'work_handler' => 'Handler', + 'work_content' => 'Content / Remark', + 'work_title' => 'Order Title', + 'work_create_time' => 'Create Time', + 'work_update_time' => 'Update Time', + 'work_all_list' => 'All Work Order List', + 'work_no_data' => 'No order data', + 'work_save' => 'Save', + 'work_cancel' => 'Cancel', + 'work_placeholder_title' => 'Fill fault or demand title', + 'work_placeholder_content' => 'Describe fault, steps and handling remark', + 'work_select_handler' => 'Select handler (empty for unassigned)', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh All Data', + 'export_csv' => 'Export Alert CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'today_fire' => 'Today Triggered Alerts', + 'unresolved_now' => 'Unresolved Alerts', + 'resolved_today' => 'Resolved Today', + 'instance_total' => 'Affected Instances', + 'recovery_rate' => 'Daily Recovery Rate', + 'today_fire_sub' => 'Total Firing Today', + 'unresolved_sub' => 'Unresolved Now', + 'resolved_sub' => 'Resolved Today', + 'instance_sub' => 'Affected Host Instance', + 'rate_sub' => 'Daily Recovery Rate', + 'top10_alert' => 'Top 10 Alert Frequency Today', + 'active_alert' => 'Active Unresolved Alerts', + 'alert_count' => ' unresolved alerts', + 'all_alert_log' => 'Today Full Alert List', + 'total_alert' => ' alert records', + 'tag' => 'Status', + 'alert_name' => 'Alert Name', + 'instance_addr' => 'Instance IP', + 'severity' => 'Severity', + 'occur_time' => 'Occur Time', + 'empty_normal' => 'No active alerts, system normal', + 'empty_no_data' => 'No alert data today', + 'disk_stat' => 'User Directory Disk Usage', + 'filter_ip' => 'Filter IP: ', + 'export_disk' => 'Export Table CSV', + 'all_instance' => 'All Instances', + 'disk_loading' => 'Loading disk data...', + 'no_disk_data' => 'No disk data available', + 'no_ip_data' => 'No directory data for this instance', + 'csv_tip' => 'Generating CSV file, please wait...', + 'alert_axis' => 'Alert Count', + 'data_fail' => 'Data load failed, please relogin', + 'server_fail' => 'API request failed, check backend service', + 'disk_api_fail' => 'Disk API Error: ', + 'disk_request_fail' => 'Request df.php failed, check service', + 'no_export_data' => 'No data to export' + ] +]; +$t = $langMap[$currentLang]; + +// 解析侧边外链列表 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = [ + "name" => trim($item[0]), + "url" => trim($item[1]) + ]; + } + } +} +?> + + + + + +<?php echo $pageTitle; ?> - Advantest <?php echo $t['page_subtitle']; ?> + + + + + + +
+
+ + +
+
+
+ + + +
+
+
+
+
Advantest
+
+
+
+
+ + -- + +
+ + +
+ +
+ + +
+ +
+
+ +
+ +
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0%
+
+
+
+ + +
+
+
+
+
+
+
+
+ + +
+
+
+
+
0
+
+
+ + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
0
+
+
+ + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+ + + +
+
+
+ + + + + + + + + + + + + + +
IPUsernamePathSize(GB)
+
+
+
+
+
+
+
+
+
+
+ + + + diff --git a/dashboard.php.1.0.4 b/dashboard.php.1.0.4 new file mode 100644 index 0000000..53ec939 --- /dev/null +++ b/dashboard.php.1.0.4 @@ -0,0 +1,1193 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +// 刷新登录计时 +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +// 读取全局系统配置(admin后台保存后同步生效) +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} +mysqli_close($connConfig); + +// 赋值全局配置 +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$themeColor = htmlspecialchars($sysConfig['theme_color'] ?? "#409eff"); +$pageSize = $sysConfig['page_size'] ?? "20"; +$footerText = htmlspecialchars($sysConfig['footer_text'] ?? ""); +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +// 读取语言配置 zh=中文 en=英文 +$currentLang = $sysConfig['lang'] ?? "zh"; + +// 全局多语言词典 +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警监控总览', + 'disk_capacity' => '服务器磁盘容量', + 'docker_mgr' => 'Docker容器管理', + 'alert_list_page' => '历史告警查询', + 'work_order_mgr' => '工单系统', + 'system_manager' => '角色管理', + 'work_order_title' => '工单管理', + 'work_create' => '新建工单', + 'work_edit' => '编辑工单', + 'work_assign' => '分发工单', + 'work_status' => '工单状态', + 'work_creator' => '创建人', + 'work_handler' => '处理人', + 'work_content' => '工单内容/备注', + 'work_title' => '工单标题', + 'work_create_time' => '创建时间', + 'work_update_time' => '更新时间', + 'work_all_list' => '全部工单列表', + 'work_no_data' => '暂无工单记录', + 'work_save' => '保存', + 'work_cancel' => '取消', + 'work_placeholder_title' => '填写故障/需求标题', + 'work_placeholder_content' => '详细描述故障、操作步骤、处理备注', + 'work_select_handler' => '选择处理人(留空暂不分配)', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '后台配置管理', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新全部数据', + 'export_csv' => '导出告警CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'today_fire' => '今日触发告警', + 'unresolved_now' => '当前未恢复告警', + 'resolved_today' => '今日恢复告警', + 'instance_total' => '故障实例总数', + 'recovery_rate' => '告警恢复率', + 'today_fire_sub' => 'Total Firing Today', + 'unresolved_sub' => 'Unresolved Now', + 'resolved_sub' => 'Resolved Today', + 'instance_sub' => 'Affected Host Instance', + 'rate_sub' => 'Daily Recovery Rate', + 'top10_alert' => '今日告警频次 TOP 10', + 'active_alert' => '当前未恢复活跃告警', + 'alert_count' => '条未恢复故障', + 'all_alert_log' => '今日全量告警明细列表', + 'total_alert' => '条告警记录', + 'tag' => '告警状态', + 'alert_name' => '告警名称', + 'instance_addr' => '实例地址', + 'severity' => '告警级别', + 'occur_time' => '故障发生时间', + 'empty_normal' => '当前无未恢复告警,系统运行正常', + 'empty_no_data' => '暂无今日告警数据', + 'disk_stat' => '用户目录磁盘占用统计', + 'filter_ip' => '筛选实例IP:', + 'export_disk' => '导出当前表格CSV', + 'all_instance' => '全部实例', + 'disk_loading' => '磁盘数据加载中...', + 'no_disk_data' => '暂无磁盘指标数据', + 'no_ip_data' => '该实例下无目录数据', + 'csv_tip' => '正在生成CSV报表,请稍候...', + 'alert_axis' => '告警次数', + 'data_fail' => '数据加载失败,请重新登录', + 'server_fail' => '接口数据加载失败,请检查后端服务', + 'disk_api_fail' => '磁盘接口异常:', + 'disk_request_fail' => '请求df.php接口失败,请检查服务', + 'no_export_data' => '无数据可导出' + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'disk_capacity' => 'Server Disk Capacity', + 'docker_mgr' => 'Docker Manager', + 'alert_list_page' => 'Alert Pagination List', + 'work_order_mgr' => 'Work Order System', + 'system_manager' => 'Role & Permission Manage', + 'work_order_title' => 'Work Order Manage', + 'work_create' => 'Create Order', + 'work_edit' => 'Edit Order', + 'work_assign' => 'Assign Order', + 'work_status' => 'Status', + 'work_creator' => 'Creator', + 'work_handler' => 'Handler', + 'work_content' => 'Content / Remark', + 'work_title' => 'Order Title', + 'work_create_time' => 'Create Time', + 'work_update_time' => 'Update Time', + 'work_all_list' => 'All Work Order List', + 'work_no_data' => 'No order data', + 'work_save' => 'Save', + 'work_cancel' => 'Cancel', + 'work_placeholder_title' => 'Fill fault or demand title', + 'work_placeholder_content' => 'Describe fault, steps and handling remark', + 'work_select_handler' => 'Select handler (empty for unassigned)', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh All Data', + 'export_csv' => 'Export Alert CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'today_fire' => 'Today Triggered Alerts', + 'unresolved_now' => 'Unresolved Alerts', + 'resolved_today' => 'Resolved Today', + 'instance_total' => 'Affected Instances', + 'recovery_rate' => 'Daily Recovery Rate', + 'today_fire_sub' => 'Total Firing Today', + 'unresolved_sub' => 'Unresolved Now', + 'resolved_sub' => 'Resolved Today', + 'instance_sub' => 'Affected Host Instance', + 'rate_sub' => 'Daily Recovery Rate', + 'top10_alert' => 'Top 10 Alert Frequency Today', + 'active_alert' => 'Active Unresolved Alerts', + 'alert_count' => ' unresolved alerts', + 'all_alert_log' => 'Today Full Alert List', + 'total_alert' => ' alert records', + 'tag' => 'Status', + 'alert_name' => 'Alert Name', + 'instance_addr' => 'Instance IP', + 'severity' => 'Severity', + 'occur_time' => 'Occur Time', + 'empty_normal' => 'No active alerts, system normal', + 'empty_no_data' => 'No alert data today', + 'disk_stat' => 'User Directory Disk Usage', + 'filter_ip' => 'Filter IP: ', + 'export_disk' => 'Export Table CSV', + 'all_instance' => 'All Instances', + 'disk_loading' => 'Loading disk data...', + 'no_disk_data' => 'No disk data available', + 'no_ip_data' => 'No directory data for this instance', + 'csv_tip' => 'Generating CSV file, please wait...', + 'alert_axis' => 'Alert Count', + 'data_fail' => 'Data load failed, please relogin', + 'server_fail' => 'API request failed, check backend service', + 'disk_api_fail' => 'Disk API Error: ', + 'disk_request_fail' => 'Request df.php failed, check service', + 'no_export_data' => 'No data to export' + ] +]; +$t = $langMap[$currentLang]; + +// 解析侧边外链列表 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = [ + "name" => trim($item[0]), + "url" => trim($item[1]) + ]; + } + } +} +?> + + + + + +<?php echo $pageTitle; ?> - Advantest <?php echo $t['page_subtitle']; ?> + + + + + + +
+
+ + +
+
+
+ + + +
+
+
+
+
Advantest
+
+
+
+
+ + -- + +
+ + +
+ +
+ + +
+ +
+
+ +
+ +
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0%
+
+
+
+ + +
+
+
+
+
+
+
+
+ + +
+
+
+
+
0
+
+
+ + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
0
+
+
+ + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+ + + +
+
+
+ + + + + + + + + + + + + + +
IPUsernamePathSize(GB)
+
+
+
+
+
+
+
+
+
+
+ + + + diff --git a/dashboard.php.2 b/dashboard.php.2 new file mode 100644 index 0000000..ff7676c --- /dev/null +++ b/dashboard.php.2 @@ -0,0 +1,601 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +// 刷新登录时间 +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; +?> + + + + + +Advantest 爱德万测试 - 运维告警监控平台 + + + + + + +
+
+ + 正在生成CSV报表,请稍候... +
+
+ +
+
+
+
Advantest
+
爱德万测试 · 运维告警监控平台
+
+
+
+ + 系统时间:-- + + + +
+
+ +
+ +
+
+
+
今日触发告警
+
+
+
0
+
Total Firing Today
+
+
+
+
当前未恢复告警
+
+
+
0
+
Unresolved Now
+
+
+
+
今日恢复告警
+
+
+
0
+
Resolved Today
+
+
+
+
故障实例总数
+
+
+
0
+
Affected Host Instance
+
+
+
+
告警恢复率
+
+
+
0%
+
Daily Recovery Rate
+
+
+ + +
+
+
+
今日告警频次 TOP 10
+
+
+
+
+ + +
+
+
+
当前未恢复活跃告警
+
0 条未恢复故障
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
当前无未恢复告警,系统运行正常
+
+
+
+
+
+ + +
+
+
+
今日全量告警明细列表
+
0 条告警记录
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
暂无今日告警数据
+
+
+
+
+
+
+ + + + diff --git a/dashboard.php.2.0版本 b/dashboard.php.2.0版本 new file mode 100644 index 0000000..d9f3496 --- /dev/null +++ b/dashboard.php.2.0版本 @@ -0,0 +1,1267 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +// 刷新登录计时 +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +// 读取全局系统配置(admin后台保存后同步生效) +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} +mysqli_close($connConfig); + +// 赋值全局配置 +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$themeColor = htmlspecialchars($sysConfig['theme_color'] ?? "#409eff"); +$pageSize = $sysConfig['page_size'] ?? "20"; +$footerText = htmlspecialchars($sysConfig['footer_text'] ?? ""); +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +// 读取语言配置 zh=中文 en=英文 +$currentLang = $sysConfig['lang'] ?? "zh"; + +// 全局多语言词典 +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警监控总览', + 'alert_list_page' => '告警明细分页', + 'disk_capacity' => '服务器磁盘容量', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '后台配置管理', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新全部数据', + 'export_csv' => '导出告警CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'today_fire' => '今日触发告警', + 'unresolved_now' => '当前未恢复告警', + 'resolved_today' => '今日恢复告警', + 'instance_total' => '故障实例总数', + 'recovery_rate' => '告警恢复率', + 'today_fire_sub' => 'Total Firing Today', + 'unresolved_sub' => 'Unresolved Now', + 'resolved_sub' => 'Resolved Today', + 'instance_sub' => 'Affected Host Instance', + 'rate_sub' => 'Daily Recovery Rate', + 'top10_alert' => '今日告警频次 TOP 10', + 'active_alert' => '当前未恢复活跃告警', + 'alert_count' => '条未恢复故障', + 'all_alert_log' => '告警全量明细', + 'total_alert' => '条告警记录', + 'tag' => '告警状态', + 'alert_name' => '告警名称', + 'instance_addr' => '实例地址', + 'severity' => '告警级别', + 'occur_time' => '故障发生时间', + 'empty_normal' => '当前无未恢复告警,系统运行正常', + 'empty_no_data' => '暂无告警数据', + 'disk_stat' => '用户目录磁盘占用统计', + 'filter_ip' => '筛选实例IP:', + 'export_disk' => '导出当前表格CSV', + 'all_instance' => '全部实例', + 'disk_loading' => '磁盘数据加载中...', + 'no_disk_data' => '暂无磁盘指标数据', + 'no_ip_data' => '该实例下无目录数据', + 'csv_tip' => '正在生成CSV报表,请稍候...', + 'alert_axis' => '告警次数', + 'data_fail' => '数据加载失败,请重新登录', + 'server_fail' => '接口数据加载失败,请检查后端服务', + 'disk_api_fail' => '磁盘接口异常:', + 'disk_request_fail' => '请求df.php接口失败,请检查服务', + 'no_export_data' => '无数据可导出', + // 分页新增文字 + 'page_title_list' => '告警分页列表', + 'filter_date' => '日期筛选', + 'filter_alert_name' => '告警名称', + 'filter_severity' => '告警级别', + 'filter_status' => '告警状态', + 'btn_search' => '查询', + 'btn_reset' => '重置', + 'page_total' => '共', + 'page_record' => '条记录', + 'page_size' => '每页', + 'page_prev' => '上一页', + 'page_next' => '下一页', + 'page_first' => '首页', + 'page_last' => '末页' + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'alert_list_page' => 'Alert Pagination List', + 'disk_capacity' => 'Server Disk Capacity', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh All Data', + 'export_csv' => 'Export Alert CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'today_fire' => 'Today Triggered Alerts', + 'unresolved_now' => 'Unresolved Alerts', + 'resolved_today' => 'Resolved Today', + 'instance_total' => 'Affected Instances', + 'recovery_rate' => 'Daily Recovery Rate', + 'today_fire_sub' => 'Total Firing Today', + 'unresolved_sub' => 'Unresolved Now', + 'resolved_sub' => 'Resolved Today', + 'instance_sub' => 'Affected Host Instance', + 'rate_sub' => 'Daily Recovery Rate', + 'top10_alert' => 'Top 10 Alert Frequency Today', + 'active_alert' => 'Active Unresolved Alerts', + 'alert_count' => ' unresolved alerts', + 'all_alert_log' => 'Full Alert List', + 'total_alert' => ' alert records', + 'tag' => 'Status', + 'alert_name' => 'Alert Name', + 'instance_addr' => 'Instance IP', + 'severity' => 'Severity', + 'occur_time' => 'Occur Time', + 'empty_normal' => 'No active alerts, system normal', + 'empty_no_data' => 'No alert data', + 'disk_stat' => 'User Directory Disk Usage', + 'filter_ip' => 'Filter IP: ', + 'export_disk' => 'Export Table CSV', + 'all_instance' => 'All Instances', + 'disk_loading' => 'Loading disk data...', + 'no_disk_data' => 'No disk data available', + 'no_ip_data' => 'No directory data for this instance', + 'csv_tip' => 'Generating CSV file, please wait...', + 'alert_axis' => 'Alert Count', + 'data_fail' => 'Data load failed, please relogin', + 'server_fail' => 'API request failed, check backend service', + 'disk_api_fail' => 'Disk API Error: ', + 'disk_request_fail' => 'Request df.php failed, check service', + 'no_export_data' => 'No data to export', + // 分页英文 + 'page_title_list' => 'Alert Pagination List', + 'filter_date' => 'Date', + 'filter_alert_name' => 'Alert Name', + 'filter_severity' => 'Severity', + 'filter_status' => 'Status', + 'btn_search' => 'Search', + 'btn_reset' => 'Reset', + 'page_total' => 'Total ', + 'page_record' => ' records', + 'page_size' => 'Per page', + 'page_prev' => 'Prev', + 'page_next' => 'Next', + 'page_first' => 'First', + 'page_last' => 'Last' + ] +]; +$t = $langMap[$currentLang]; + +// 解析侧边外链列表 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = [ + "name" => trim($item[0]), + "url" => trim($item[1]) + ]; + } + } +} +?> + + + + + +<?php echo $pageTitle; ?> - Advantest <?php echo $t['page_subtitle']; ?> + + + + + + +
+
+ + +
+
+ +
+ + + + +
+
+
+
+
Advantest
+
+
+
+
+ + -- + +
+ + +
+ +
+ + +
+ +
+
+ +
+ +
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0%
+
+
+
+ + +
+
+
+
+
+
+
+
+ + +
+
+
+
+
0
+
+
+ + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + +
+
+ + + + + + + + + + + + + + + +
+
+
+
+
+
+
+ +
+
+ 0 +
+
+ + + + + 1 / 1 + + +
+
+
+
+
+ + +
+
+
+
+
+
+ + + +
+
+
+ + + + + + + + + + + + + + +
IPUsernamePathSize(GB)
+
+
+
+
+
+
+
+
+
+
+ + + + diff --git a/dashboard.php.3 b/dashboard.php.3 new file mode 100644 index 0000000..3f41d62 --- /dev/null +++ b/dashboard.php.3 @@ -0,0 +1,899 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +// 刷新登录时间 +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; +?> + + + + + +Advantest 爱德万测试 - 运维告警监控平台 + + + + + + +
+
+ + 正在生成CSV报表,请稍候... +
+
+ +
+ + + + +
+
+
+
+
Advantest
+
爱德万测试 · 运维告警监控平台
+
+
+
+ + 系统时间:-- + + + +
+
+ +
+ +
+ +
+
+
+
今日触发告警
+
+
+
0
+
Total Firing Today
+
+
+
+
当前未恢复告警
+
+
+
0
+
Unresolved Now
+
+
+
+
今日恢复告警
+
+
+
0
+
Resolved Today
+
+
+
+
故障实例总数
+
+
+
0
+
Affected Host Instance
+
+
+
+
告警恢复率
+
+
+
0%
+
Daily Recovery Rate
+
+
+ + +
+
+
+
今日告警频次 TOP 10
+
+
+
+
+ + +
+
+
+
当前未恢复活跃告警
+
0 条未恢复故障
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
当前无未恢复告警,系统运行正常
+
+
+
+
+
+ + +
+
+
+
今日全量告警明细列表
+
0 条告警记录
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
暂无今日告警数据
+
+
+
+
+
+
+ + +
+
+
+
+
用户目录磁盘占用统计
+
+ + + +
+
+
+ + + + + + + + + + + + + + +
实例IP用户名目录路径占用容量
+
+
磁盘数据加载中...
+
+
+
+
+
+
+
+
+ + + + diff --git a/dashboard.php.4 b/dashboard.php.4 new file mode 100644 index 0000000..21d12c7 --- /dev/null +++ b/dashboard.php.4 @@ -0,0 +1,1066 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +$configFile = "./api/system_config.json"; +$sysConfig = json_decode(file_get_contents($configFile),true); +$themeColor = $sysConfig['theme_color']; +$cardBg = $sysConfig['card_bg']; +$bodyBg = $sysConfig['body_bg']; +$fontFamily = $sysConfig['font_family']; +$customLinks = $sysConfig['sidebar_links']; +?> + + + + + +Advantest 爱德万测试 - 运维告警监控平台 + + + + + + +
+
+ + 正在生成CSV报表,请稍候... +
+
+ +
+ + +
+
+
+
+
Advantest
+
爱德万测试 · 运维告警监控平台
+
+
+
+ + 系统时间:-- + + + +
+
+ +
+
+
+
+
+
今日触发告警
+
+
+
0
+
Total Firing Today
+
+
+
+
当前未恢复告警
+
+
+
0
+
Unresolved Now
+
+
+
+
今日恢复告警
+
+
+
0
+
Resolved Today
+
+
+
+
故障实例总数
+
+
+
0
+
Affected Host Instance
+
+
+
+
告警恢复率
+
+
+
0%
+
Daily Recovery Rate
+
+
+ +
+
+
+
今日告警频次 TOP 10
+
+
+
+
+ +
+
+
+
当前未恢复活跃告警
+
0 条未恢复故障
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
当前无未恢复告警,系统运行正常
+
+
+
+
+
+ +
+
+
+
今日全量告警明细列表
+
0 条告警记录
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
暂无今日告警数据
+
+
+
+
+
+
+ +
+
+
+
+
用户目录磁盘占用统计
+
+ + + +
+
+
+ + + + + + + + + + + + + + +
实例IP用户名目录路径占用容量
+
+
磁盘数据加载中...
+
+
+
+
+
+ +
+
+
+
修改登录密码
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ +
+
+
+
界面主题样式配置
+
+
+
+ + + 十六进制颜色值 +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ +
+
+
+
侧边栏自定义外链管理
+ +
+
+
+ +
+
+
+
+
+
+ + + + diff --git a/dashboard.php.5 b/dashboard.php.5 new file mode 100644 index 0000000..3b21b85 --- /dev/null +++ b/dashboard.php.5 @@ -0,0 +1,916 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +// 刷新登录时间 +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; +?> + + + + + +Advantest 爱德万测试 - 运维告警监控平台 + + + + + + +
+
+ + 正在生成CSV报表,请稍候... +
+
+ +
+ + + + +
+
+
+
+
Advantest
+
爱德万测试 · 运维告警监控平台
+
+
+
+ + 系统时间:-- + + +
+ + +
+ +
+
+ +
+ +
+ +
+
+
+
今日触发告警
+
+
+
0
+
Total Firing Today
+
+
+
+
当前未恢复告警
+
+
+
0
+
Unresolved Now
+
+
+
+
今日恢复告警
+
+
+
0
+
Resolved Today
+
+
+
+
故障实例总数
+
+
+
0
+
Affected Host Instance
+
+
+
+
告警恢复率
+
+
+
0%
+
Daily Recovery Rate
+
+
+ + +
+
+
+
今日告警频次 TOP 10
+
+
+
+
+ + +
+
+
+
当前未恢复活跃告警
+
0 条未恢复故障
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
当前无未恢复告警,系统运行正常
+
+
+
+
+
+ + +
+
+
+
今日全量告警明细列表
+
0 条告警记录
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
暂无今日告警数据
+
+
+
+
+
+
+ + +
+
+
+
+
用户目录磁盘占用统计
+
+ + + +
+
+
+ + + + + + + + + + + + + + +
实例IP用户名目录路径占用容量
+
+
磁盘数据加载中...
+
+
+
+
+
+
+
+
+ + + + diff --git a/dashboard.php.6 b/dashboard.php.6 new file mode 100644 index 0000000..e91b8fe --- /dev/null +++ b/dashboard.php.6 @@ -0,0 +1,970 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +// 刷新登录计时 +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +// 读取全局系统配置(admin后台保存后同步生效) +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} +mysqli_close($connConfig); + +// 赋值全局配置 +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$themeColor = htmlspecialchars($sysConfig['theme_color'] ?? "#409eff"); +$pageSize = $sysConfig['page_size'] ?? "20"; +$footerText = htmlspecialchars($sysConfig['footer_text'] ?? ""); +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +// 解析侧边外链列表 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = [ + "name" => trim($item[0]), + "url" => trim($item[1]) + ]; + } + } +} +?> + + + + + +<?php echo $pageTitle; ?> - Advantest 爱德万测试 - 运维告警监控平台 + + + + + + +
+
+ + 正在生成CSV报表,请稍候... +
+
+ +
+ + + + +
+
+
+
+
Advantest
+
爱德万测试 · 运维告警监控平台
+
+
+
+ + 系统时间:-- + + +
+ + +
+ +
+
+ +
+ +
+ +
+
+
+
今日触发告警
+
+
+
0
+
Total Firing Today
+
+
+
+
当前未恢复告警
+
+
+
0
+
Unresolved Now
+
+
+
+
今日恢复告警
+
+
+
0
+
Resolved Today
+
+
+
+
故障实例总数
+
+
+
0
+
Affected Host Instance
+
+
+
+
告警恢复率
+
+
+
0%
+
Daily Recovery Rate
+
+
+ + +
+
+
+
今日告警频次 TOP 10
+
+
+
+
+ + +
+
+
+
当前未恢复活跃告警
+
0 条未恢复故障
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
当前无未恢复告警,系统运行正常
+
+
+
+
+
+ + +
+
+
+
今日全量告警明细列表
+
0 条告警记录
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
暂无今日告警数据
+
+
+
+
+
+
+ + +
+
+
+
+
用户目录磁盘占用统计
+
+ + + +
+
+
+ + + + + + + + + + + + + + +
实例IP用户名目录路径占用容量
+
+
磁盘数据加载中...
+
+
+
+
+
+
+
+
+ + + + diff --git a/dashboard.php.7 b/dashboard.php.7 new file mode 100644 index 0000000..bfce9ba --- /dev/null +++ b/dashboard.php.7 @@ -0,0 +1,1087 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +// 刷新登录计时 +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +// 读取全局系统配置(admin后台保存后同步生效) +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} +mysqli_close($connConfig); + +// 赋值全局配置 +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$themeColor = htmlspecialchars($sysConfig['theme_color'] ?? "#409eff"); +$pageSize = $sysConfig['page_size'] ?? "20"; +$footerText = htmlspecialchars($sysConfig['footer_text'] ?? ""); +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +// 解析侧边外链列表 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = [ + "name" => trim($item[0]), + "url" => trim($item[1]) + ]; + } + } +} +// 读取用户头像 +$avatarPath = $_SESSION['avatar'] ?? "avatar_default.png"; +?> + + + + + +<?php echo $pageTitle; ?> - Advantest 爱德万测试 - 运维告警监控平台 + + + + + + + +
+
+

更换头像

+ +
+ +
+
+ + +
+
+
+ +
+
+ + 正在生成CSV报表,请稍候... +
+
+ +
+ + + + +
+
+
+
+
Advantest
+
爱德万测试 · 运维告警监控平台
+
+
+
+ + © Hans.wang 版权所有 + +
+ + +
+ 系统时间:-- + + +
+ + +
+ +
+
+ +
+ +
+ +
+
+
+
今日触发告警
+
+
+
0
+
Total Firing Today
+
+
+
+
当前未恢复告警
+
+
+
0
+
Unresolved Now
+
+
+
+
今日恢复告警
+
+
+
0
+
Resolved Today
+
+
+
+
故障实例总数
+
+
+
0
+
Affected Host Instance
+
+
+
+
告警恢复率
+
+
+
0%
+
Daily Recovery Rate
+
+
+ + +
+
+
+
今日告警频次 TOP 10
+
+
+
+
+ + +
+
+
+
当前未恢复活跃告警
+
0 条未恢复故障
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
当前无未恢复告警,系统运行正常
+
+
+
+
+
+ + +
+
+
+
今日全量告警明细列表
+
0 条告警记录
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
暂无今日告警数据
+
+
+
+
+
+
+ + +
+
+
+
+
用户目录磁盘占用统计
+
+ + + +
+
+
+ + + + + + + + + + + + + + +
实例IP用户名目录路径占用容量
+
+
磁盘数据加载中...
+
+
+
+
+
+
+
+
+ + + + diff --git a/dashboard.php.8 b/dashboard.php.8 new file mode 100644 index 0000000..9a5cd31 --- /dev/null +++ b/dashboard.php.8 @@ -0,0 +1,1126 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +// 刷新登录计时 +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$userId = $_SESSION['user_id']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +// 数据库连接 +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$conn = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($conn, "utf8mb4"); + +// 1. 读取全局系统配置 +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($conn, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} + +// 2. 从数据库读取用户头像(解决刷新丢失) +$avatarSql = "SELECT avatar FROM user WHERE id = ?"; +$stmt = mysqli_prepare($conn, $avatarSql); +mysqli_stmt_bind_param($stmt, "i", $userId); +mysqli_stmt_execute($stmt); +$avatarRes = mysqli_stmt_get_result($stmt); +$userAvatarRow = mysqli_fetch_assoc($avatarRes); +// nginx静态资源目录:/static/avatar/ +$avatarPath = !empty($userAvatarRow['avatar']) ? "/static/avatar/" . $userAvatarRow['avatar'] : "/static/avatar/avatar_default.png"; +// 存入session,临时缓存 +$_SESSION['avatar'] = $avatarPath; + +// 赋值全局配置 +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$themeColor = htmlspecialchars($sysConfig['theme_color'] ?? "#409eff"); +$pageSize = $sysConfig['page_size'] ?? "20"; +$footerText = htmlspecialchars($sysConfig['footer_text'] ?? ""); +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +// 解析侧边外链列表 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = [ + "name" => trim($item[0]), + "url" => trim($item[1]) + ]; + } + } +} + +// 头像上传接口处理(POST提交头像) +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['avatar_file'])) { + $uploadDir = $_SERVER['DOCUMENT_ROOT'] . "/static/avatar/"; + if (!file_exists($uploadDir)) mkdir($uploadDir, 0755, true); + $ext = pathinfo($_FILES['avatar_file']['name'], PATHINFO_EXTENSION); + $newFileName = "u" . $userId . "_" . time() . "." . $ext; + $savePath = $uploadDir . $newFileName; + move_uploaded_file($_FILES['avatar_file']['tmp_name'], $savePath); + // 更新数据库头像字段 + $updateSql = "UPDATE user SET avatar = ? WHERE id = ?"; + $updateStmt = mysqli_prepare($conn, $updateSql); + mysqli_stmt_bind_param($updateStmt, "si", $newFileName, $userId); + mysqli_stmt_execute($updateStmt); + $_SESSION['avatar'] = "/static/avatar/" . $newFileName; + echo json_encode(["code" => 0, "msg" => "头像上传成功", "avatar" => $_SESSION['avatar']]); + exit; +} + +mysqli_close($conn); +?> + + + + + +<?php echo $pageTitle; ?> - Advantest 爱德万测试 - 运维告警监控平台 + + + + + + + +
+
+

更换头像

+ +
+ +
+
+ + +
+
+
+ +
+
+ + 正在生成CSV报表,请稍候... +
+
+ +
+ + + + +
+
+
+
+
Advantest
+
爱德万测试 · 运维告警监控平台
+
+
+
+ + 系统时间:-- + + +
+ + +
+ +
+
+ +
+ +
+ +
+
+
+
今日触发告警
+
+
+
0
+
Total Firing Today
+
+
+
+
当前未恢复告警
+
+
+
0
+
Unresolved Now
+
+
+
+
今日恢复告警
+
+
+
0
+
Resolved Today
+
+
+
+
故障实例总数
+
+
+
0
+
Affected Host Instance
+
+
+
+
告警恢复率
+
+
+
0%
+
Daily Recovery Rate
+
+
+ + +
+
+
+
今日告警频次 TOP 10
+
+
+
+
+ + +
+
+
+
当前未恢复活跃告警
+
0 条未恢复故障
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
当前无未恢复告警,系统运行正常
+
+
+
+
+
+ + +
+
+
+
今日全量告警明细列表
+
0 条告警记录
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
暂无今日告警数据
+
+
+
+
+
+
+ + +
+
+
+
+
用户目录磁盘占用统计
+
+ + + +
+
+
+ + + + + + + + + + + + + + +
实例IP用户名目录路径占用容量
+
+
磁盘数据加载中...
+
+
+
+
+
+
+ + +
+
+ + + + diff --git a/dashboard.php.9 b/dashboard.php.9 new file mode 100644 index 0000000..142b238 --- /dev/null +++ b/dashboard.php.9 @@ -0,0 +1,1161 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +// 刷新登录计时 +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +// 读取全局系统配置(admin后台保存后同步生效) +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} +mysqli_close($connConfig); + +// 赋值全局配置 +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$themeColor = htmlspecialchars($sysConfig['theme_color'] ?? "#409eff"); +$pageSize = $sysConfig['page_size'] ?? "20"; +$footerText = htmlspecialchars($sysConfig['footer_text'] ?? ""); +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +// 读取语言配置 zh=中文 en=英文 +$currentLang = $sysConfig['lang'] ?? "zh"; + +// 全局多语言词典 +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警监控总览', + 'disk_capacity' => '服务器磁盘容量', + 'alert_list_page' => '历史告警查询', + 'work_order_mgr' => '工单系统', + 'system_manager' => '角色管理', + 'work_order_title' => '工单管理', + 'work_create' => '新建工单', + 'work_edit' => '编辑工单', + 'work_assign' => '分发工单', + 'work_status' => '工单状态', + 'work_creator' => '创建人', + 'work_handler' => '处理人', + 'work_content' => '工单内容/备注', + 'work_title' => '工单标题', + 'work_create_time' => '创建时间', + 'work_update_time' => '更新时间', + 'work_all_list' => '全部工单列表', + 'work_no_data' => '暂无工单记录', + 'work_save' => '保存', + 'work_cancel' => '取消', + 'work_placeholder_title' => '填写故障/需求标题', + 'work_placeholder_content' => '详细描述故障、操作步骤、处理备注', + 'work_select_handler' => '选择处理人(留空暂不分配)', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '后台配置管理', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新全部数据', + 'export_csv' => '导出告警CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'today_fire' => '今日触发告警', + 'unresolved_now' => '当前未恢复告警', + 'resolved_today' => '今日恢复告警', + 'instance_total' => '故障实例总数', + 'recovery_rate' => '告警恢复率', + 'today_fire_sub' => 'Total Firing Today', + 'unresolved_sub' => 'Unresolved Now', + 'resolved_sub' => 'Resolved Today', + 'instance_sub' => 'Affected Host Instance', + 'rate_sub' => 'Daily Recovery Rate', + 'top10_alert' => '今日告警频次 TOP 10', + 'active_alert' => '当前未恢复活跃告警', + 'alert_count' => '条未恢复故障', + 'all_alert_log' => '今日全量告警明细列表', + 'total_alert' => '条告警记录', + 'tag' => '告警状态', + 'alert_name' => '告警名称', + 'instance_addr' => '实例地址', + 'severity' => '告警级别', + 'occur_time' => '故障发生时间', + 'empty_normal' => '当前无未恢复告警,系统运行正常', + 'empty_no_data' => '暂无今日告警数据', + 'disk_stat' => '用户目录磁盘占用统计', + 'filter_ip' => '筛选实例IP:', + 'export_disk' => '导出当前表格CSV', + 'all_instance' => '全部实例', + 'disk_loading' => '磁盘数据加载中...', + 'no_disk_data' => '暂无磁盘指标数据', + 'no_ip_data' => '该实例下无目录数据', + 'csv_tip' => '正在生成CSV报表,请稍候...', + 'alert_axis' => '告警次数', + 'data_fail' => '数据加载失败,请重新登录', + 'server_fail' => '接口数据加载失败,请检查后端服务', + 'disk_api_fail' => '磁盘接口异常:', + 'disk_request_fail' => '请求df.php接口失败,请检查服务', + 'no_export_data' => '无数据可导出' + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'disk_capacity' => 'Server Disk Capacity', + 'alert_list_page' => 'Alert Pagination List', + 'work_order_mgr' => 'Work Order System', + 'system_manager' => 'Role & Permission Manage', + 'work_order_title' => 'Work Order Manage', + 'work_create' => 'Create Order', + 'work_edit' => 'Edit Order', + 'work_assign' => 'Assign Order', + 'work_status' => 'Status', + 'work_creator' => 'Creator', + 'work_handler' => 'Handler', + 'work_content' => 'Content / Remark', + 'work_title' => 'Order Title', + 'work_create_time' => 'Create Time', + 'work_update_time' => 'Update Time', + 'work_all_list' => 'All Work Order List', + 'work_no_data' => 'No order data', + 'work_save' => 'Save', + 'work_cancel' => 'Cancel', + 'work_placeholder_title' => 'Fill fault or demand title', + 'work_placeholder_content' => 'Describe fault, steps and handling remark', + 'work_select_handler' => 'Select handler (empty for unassigned)', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh All Data', + 'export_csv' => 'Export Alert CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'today_fire' => 'Today Triggered Alerts', + 'unresolved_now' => 'Unresolved Alerts', + 'resolved_today' => 'Resolved Today', + 'instance_total' => 'Affected Instances', + 'recovery_rate' => 'Daily Recovery Rate', + 'today_fire_sub' => 'Total Firing Today', + 'unresolved_sub' => 'Unresolved Now', + 'resolved_sub' => 'Resolved Today', + 'instance_sub' => 'Affected Host Instance', + 'rate_sub' => 'Daily Recovery Rate', + 'top10_alert' => 'Top 10 Alert Frequency Today', + 'active_alert' => 'Active Unresolved Alerts', + 'alert_count' => ' unresolved alerts', + 'all_alert_log' => 'Today Full Alert List', + 'total_alert' => ' alert records', + 'tag' => 'Status', + 'alert_name' => 'Alert Name', + 'instance_addr' => 'Instance IP', + 'severity' => 'Severity', + 'occur_time' => 'Occur Time', + 'empty_normal' => 'No active alerts, system normal', + 'empty_no_data' => 'No alert data today', + 'disk_stat' => 'User Directory Disk Usage', + 'filter_ip' => 'Filter IP: ', + 'export_disk' => 'Export Table CSV', + 'all_instance' => 'All Instances', + 'disk_loading' => 'Loading disk data...', + 'no_disk_data' => 'No disk data available', + 'no_ip_data' => 'No directory data for this instance', + 'csv_tip' => 'Generating CSV file, please wait...', + 'alert_axis' => 'Alert Count', + 'data_fail' => 'Data load failed, please relogin', + 'server_fail' => 'API request failed, check backend service', + 'disk_api_fail' => 'Disk API Error: ', + 'disk_request_fail' => 'Request df.php failed, check service', + 'no_export_data' => 'No data to export' + ] +]; +$t = $langMap[$currentLang]; + +// 解析侧边外链列表 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = [ + "name" => trim($item[0]), + "url" => trim($item[1]) + ]; + } + } +} +?> + + + + + +<?php echo $pageTitle; ?> - Advantest <?php echo $t['page_subtitle']; ?> + + + + + + +
+
+ + +
+
+
+ + + +
+
+
+
+
Advantest
+
+
+
+
+ + -- + +
+ + +
+ +
+ + +
+ +
+
+ +
+ +
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0
+
+
+
+
+
+
+
+
0%
+
+
+
+ + +
+
+
+
+
+
+
+
+ + +
+
+
+
+
0
+
+
+ + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
0
+
+
+ + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+ + + +
+
+
+ + + + + + + + + + + + + + +
IPUsernamePathSize(GB)
+
+
+
+
+
+
+
+
+
+
+ + + + diff --git a/dashboard.php.bak b/dashboard.php.bak new file mode 100644 index 0000000..9dd5f71 --- /dev/null +++ b/dashboard.php.bak @@ -0,0 +1,365 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +// 刷新登录时间 +$_SESSION['login_time'] = time(); +$userName = $_SESSION['username']; +$userRole = $_SESSION['role']; +?> + + + + + +企业运维告警监控平台 + + + + + + +
+
+ + 正在生成CSV报表,请稍候... +
+
+
+

企业运维告警监控平台

+
+ 当前用户: + 系统实时时间:-- + + + +
+
+
+
+
+
+
今日触发告警
+
+
+
0
+
Total Firing Today
+
+
+
+
当前未恢复告警
+
+
+
0
+
Unresolved Now
+
+
+
+
今日恢复告警
+
+
+
0
+
Resolved Today
+
+
+
+
故障实例总数
+
+
+
0
+
Affected Host Instance
+
+
+
+
告警恢复率
+
+
+
0%
+
Daily Recovery Rate
+
+
+
+
+
+ 今日告警频次 TOP 10 +
+
+
+
+
+
+
+ 当前未恢复活跃告警 +
+
0 条未恢复故障
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
当前无未恢复告警,系统运行正常
+
+
+
+
+
+
+
+ 今日全量告警明细列表 +
+
0 条告警记录
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
暂无今日告警数据
+
+
+
+
+
+ + + diff --git a/dashboard2.0.html b/dashboard2.0.html new file mode 100644 index 0000000..5d0112a --- /dev/null +++ b/dashboard2.0.html @@ -0,0 +1,638 @@ + + + + + + 企业运维告警监控平台 + + + + + + + + +
+
+ + 正在生成CSV报表,请稍候... +
+
+ + +
+

企业运维告警监控平台

+
+ 最后更新:-- + + +
+
+ +
+ +
+
+
+
今日触发告警
+
+
+
0
+
Active Firing Alerts
+
+
+
+
今日恢复告警
+
+
+
0
+
Resolved Alerts Today
+
+
+
+
故障实例总数
+
+
+
0
+
Affected Host Instance
+
+
+
+
告警恢复率
+
+
+
0%
+
Daily Recovery Rate
+
+
+ + +
+
+
+ 今日告警频次 TOP 10 +
+
+
+
+ + +
+
+
+ 全量告警明细列表 +
+
0 条告警记录
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
暂无今日告警数据
+
+
+
+
+
+ + + + diff --git a/dashboard3.0.html b/dashboard3.0.html new file mode 100644 index 0000000..948e92a --- /dev/null +++ b/dashboard3.0.html @@ -0,0 +1,644 @@ + + + + + + 企业运维告警监控平台 + + + + + + + + +
+
+ + 正在生成CSV报表,请稍候... +
+
+ + +
+

企业运维告警监控平台

+
+ + 系统实时时间:-- + + +
+
+ +
+ +
+
+
+
今日触发告警
+
+
+
0
+
Active Firing Alerts
+
+
+
+
今日恢复告警
+
+
+
0
+
Resolved Alerts Today
+
+
+
+
故障实例总数
+
+
+
0
+
Affected Host Instance
+
+
+
+
告警恢复率
+
+
+
0%
+
Daily Recovery Rate
+
+
+ + +
+
+
+ 今日告警频次 TOP 10 +
+
+
+
+ + +
+
+
+ 全量告警明细列表 +
+
0 条告警记录
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
暂无今日告警数据
+
+
+
+
+
+ + + + + diff --git a/dashboard4.0.html b/dashboard4.0.html new file mode 100644 index 0000000..e88e806 --- /dev/null +++ b/dashboard4.0.html @@ -0,0 +1,776 @@ + + + + + + 企业运维告警监控平台 + + + + + + + + +
+
+ + 正在生成CSV报表,请稍候... +
+
+ + +
+

企业运维告警监控平台

+
+ 系统实时时间:-- + + +
+
+ +
+ +
+
+
+
今日触发告警
+
+
+
0
+
Total Firing Today
+
+ +
+
+
当前未恢复告警
+
+
+
0
+
Unresolved Now
+
+
+
+
今日恢复告警
+
+
+
0
+
Resolved Today
+
+
+
+
故障实例总数
+
+
+
0
+
Affected Host Instance
+
+
+
+
告警恢复率
+
+
+
0%
+
Daily Recovery Rate
+
+
+ + +
+
+
+ 今日告警频次 TOP 10 +
+
+
+
+ + +
+
+
+ 当前未恢复活跃告警 +
+
0 条未恢复故障
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
当前无未恢复告警,系统运行正常
+
+
+
+
+ + +
+
+
+ 今日全量告警明细列表 +
+
0 条告警记录
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
暂无今日告警数据
+
+
+
+
+
+ + + + + diff --git a/dashboard5.0.html b/dashboard5.0.html new file mode 100644 index 0000000..57d30ea --- /dev/null +++ b/dashboard5.0.html @@ -0,0 +1,749 @@ + + + + + + 企业运维告警监控平台 + + + + + + + + +
+
+ + 正在生成CSV报表,请稍候... +
+
+ + +
+

企业运维告警监控平台

+
+ 系统实时时间:-- + + +
+
+ +
+ +
+
+
+
今日触发告警
+
+
+
0
+
Total Firing Today
+
+ +
+
+
当前未恢复告警
+
+
+
0
+
Unresolved Now
+
+
+
+
今日恢复告警
+
+
+
0
+
Resolved Today
+
+
+
+
故障实例总数
+
+
+
0
+
Affected Host Instance
+
+
+
+
告警恢复率
+
+
+
0%
+
Daily Recovery Rate
+
+
+ + +
+
+
+ 今日告警频次 TOP 10 +
+
+
+
+ + +
+
+
+ 当前未恢复活跃告警 +
+
0 条未恢复故障
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
当前无未恢复告警,系统运行正常
+
+
+
+
+ + +
+
+
+ 今日全量告警明细列表 +
+
0 条告警记录
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
暂无今日告警数据
+
+
+
+
+
+ + + + + diff --git a/disk.html b/disk.html new file mode 100644 index 0000000..b3f27d9 --- /dev/null +++ b/disk.html @@ -0,0 +1,246 @@ + + + + + + + 服务器磁盘目录容量监控 | Dashboard + + + +
+
+
+

用户目录磁盘占用统计

+
多服务器 /serverhome 目录容量实时采集,支持按实例IP筛选、导出表格
+
+
+ + + +
+
+ + + + + + + + + + + + + + + +
实例IP用户名目录路径占用容量
数据加载中...
+
+ + + + diff --git a/docker_mgr.php b/docker_mgr.php new file mode 100644 index 0000000..037a2d9 --- /dev/null +++ b/docker_mgr.php @@ -0,0 +1,1469 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '超级管理员'; + +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} +mysqli_close($connConfig); + +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$themeColor = htmlspecialchars($sysConfig['theme_color'] ?? "#409eff"); +$pageSize = $sysConfig['page_size'] ?? "20"; +$footerText = htmlspecialchars($sysConfig['footer_text'] ?? ""); +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +$currentLang = $sysConfig['lang'] ?? "zh"; + +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警监控总览', + 'alert_list_page' => '历史告警查询', + 'work_order_mgr' => '工单系统', + 'docker_mgr' => 'Docker容器管理', + 'system_manager' => '角色管理', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '后台配置管理', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新全部数据', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'container_list' => '容器列表', + 'image_list' => '镜像列表', + 'container_log' => '容器日志', + 'network_info' => '网络详情', + 'exec_container' => '进入容器执行命令', + 'restart' => '重启', + 'stop' => '停止', + 'remove' => '强制删除', + 'remove_image' => '删除镜像', + 'bind_repo' => '绑定镜像仓库', + 'input_cmd' => '仅允许 ls/pwd/cat/ps/df/free/top/du/whoami/env,禁止rm/wget/curl/chmod等高危指令', + 'execute' => '执行', + 'close' => '关闭', + 'loading' => '加载中...', + 'no_container' => '暂无容器', + 'no_image' => '无本地镜像', + 'request_fail' => '接口请求失败', + 'container_id' => '容器ID', + 'container_name' => '容器名称', + 'image_name' => '镜像', + 'status' => '运行状态', + 'port_mapping' => '端口映射', + 'operate' => '操作', + 'repo' => '镜像仓库', + 'tag' => '镜像标签', + 'image_id' => '镜像ID', + 'size' => '镜像大小', + 'create_time' => '创建时间', + 'confirm_remove' => '确认强制删除容器?操作不可恢复!', + 'confirm_remove_img' => '确认删除本地镜像?不可恢复!', + 'op_success' => '操作成功,已刷新状态', + 'op_failed' => '操作执行失败', + 'loading_mask' => '数据加载中,请稍候...', + 'create_container' => '新建容器', + 'batch_restart' => '批量重启', + 'batch_stop' => '批量停止', + 'batch_remove' => '批量删除', + 'search_placeholder' => '搜索容器名称/镜像', + 'op_menu' => '操作 ▼', + 'view_log' => '查看日志', + 'view_network' => '查看网络', + 'enter_exec' => '交互式终端', + 'stat_total' => '容器总数', + 'stat_running' => '运行中', + 'stat_stopped' => '已停止', + 'stat_image' => '本地镜像', + 'tip_exec_once' => '单次命令执行', + 'tip_websocket' => '实时交互式TTY终端,支持输入、复制、窗口自适应', + 'repo_addr' => '仓库地址', + 'repo_user' => '仓库账号', + 'repo_pwd' => '仓库密码', + 'repo_name' => '仓库名称', + 'bind_repo_title' => '绑定私有镜像仓库' + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'alert_list_page' => 'Alert Pagination List', + 'work_order_mgr' => 'Work Order System', + 'docker_mgr' => 'Docker Manager', + 'system_manager' => 'Role & Permission Manage', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh All Data', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'container_list' => 'Container List', + 'image_list' => 'Image List', + 'container_log' => 'Container Logs', + 'network_info' => 'Network Info', + 'exec_container' => 'Exec Container Command', + 'restart' => 'Restart', + 'stop' => 'Stop', + 'remove' => 'Force Remove', + 'remove_image' => 'Remove Image', + 'bind_repo' => 'Bind Registry', + 'input_cmd' => 'Only allow ls/pwd/cat/ps/df/free/top/du/whoami/env, ban rm/wget/curl/chmod', + 'execute' => 'Run', + 'close' => 'Close', + 'loading' => 'Loading...', + 'no_container' => 'No Containers', + 'no_image' => 'No Local Images', + 'request_fail' => 'API Request Failed', + 'container_id' => 'Container ID', + 'container_name' => 'Name', + 'image_name' => 'Image', + 'status' => 'Status', + 'port_mapping' => 'Ports', + 'operate' => 'Operate', + 'repo' => 'Repository', + 'tag' => 'Tag', + 'image_id' => 'Image ID', + 'size' => 'Size', + 'create_time' => 'Created At', + 'confirm_remove' => 'Confirm force delete container? Irreversible!', + 'confirm_remove_img' => 'Confirm delete local image? Irreversible!', + 'op_success' => 'Operation succeeded, refreshed status', + 'op_failed' => 'Operation failed', + 'loading_mask' => 'Loading data, please wait...', + 'create_container' => 'Create Container', + 'batch_restart' => 'Batch Restart', + 'batch_stop' => 'Batch Stop', + 'batch_remove' => 'Batch Remove', + 'search_placeholder' => 'Search container / image', + 'op_menu' => 'Operate ▼', + 'view_log' => 'Logs', + 'view_network' => 'Network', + 'enter_exec' => 'Interactive Terminal', + 'stat_total' => 'Total Containers', + 'stat_running' => 'Running', + 'stat_stopped' => 'Stopped', + 'stat_image' => 'Local Images', + 'tip_exec_once' => 'Single command execution', + 'tip_websocket' => 'Real-time interactive TTY terminal, input & resize support', + 'repo_addr' => 'Registry Address', + 'repo_user' => 'Username', + 'repo_pwd' => 'Password', + 'repo_name' => 'Registry Name', + 'bind_repo_title' => 'Bind Private Registry' + ] +]; +$t = $langMap[$currentLang]; + +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = [ + "name" => trim($item[0]), + "url" => trim($item[1]) + ]; + } + } +} +$pageSid = session_id(); + +// WebSocket HMAC 签名参数(和docker_api.py密钥完全一致) +$WS_SECRET = "DockerAdminPlatform2026SecretKey123456789"; +$wsUser = $_SESSION['user_id']; +$wsRole = $_SESSION['role']; +$wsTs = time(); +$wsRawSign = $wsUser . "|" . $wsRole . "|" . $wsTs; +$wsSign = hash_hmac("sha256", $wsRawSign, $WS_SECRET); +$wsClientIp = $_SERVER['REMOTE_ADDR']; +?> + + + + + +<?php echo $pageTitle; ?> - Advantest <?php echo $t['page_subtitle']; ?> + + + + + + + + +
+ + +
+ +
+ + +
+
+
+
+
Advantest
+
+
+
+
+ + -- +
+ + +
+ + +
+
+ +
+ 当前页面SID:  |  接口SID:(SID一致,会话互通) +
+ +
+
+
+
+
+ + +
+
+ +
+
+
+
0
+
+
+
+
0
+
+
+
+
0
+
+
+
+
0
+
+
+ +
+
+
+
+ +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + diff --git a/docker_mgr.php.bak b/docker_mgr.php.bak new file mode 100644 index 0000000..64c8e4a --- /dev/null +++ b/docker_mgr.php.bak @@ -0,0 +1,1483 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} +mysqli_close($connConfig); + +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$themeColor = htmlspecialchars($sysConfig['theme_color'] ?? "#409eff"); +$pageSize = $sysConfig['page_size'] ?? "20"; +$footerText = htmlspecialchars($sysConfig['footer_text'] ?? ""); +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +$currentLang = $sysConfig['lang'] ?? "zh"; + +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警监控总览', + 'alert_list_page' => '历史告警查询', + 'work_order_mgr' => '工单系统', + 'docker_mgr' => 'Docker容器管理', + 'system_manager' => '角色管理', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '后台配置管理', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新全部数据', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'container_list' => '容器列表', + 'image_list' => '镜像列表', + 'container_log' => '容器日志', + 'network_info' => '网络详情', + 'exec_container' => '进入容器执行命令', + 'restart' => '重启', + 'stop' => '停止', + 'remove' => '强制删除', + 'input_cmd' => '仅允许 ls/pwd/cat/ps/df/free/top/du/whoami/env,禁止rm/wget/curl/chmod等高危指令', + 'execute' => '执行', + 'close' => '关闭', + 'loading' => '加载中...', + 'no_container' => '暂无容器', + 'no_image' => '无本地镜像', + 'request_fail' => '接口请求失败', + 'container_id' => '容器ID', + 'container_name' => '容器名称', + 'image_name' => '镜像', + 'status' => '运行状态', + 'port_mapping' => '端口映射', + 'operate' => '操作', + 'repo' => '镜像仓库', + 'tag' => '镜像标签', + 'image_id' => '镜像ID', + 'size' => '镜像大小', + 'create_time' => '创建时间', + 'confirm_remove' => '确认强制删除容器?操作不可恢复!', + 'op_success' => '操作成功,已刷新状态', + 'op_failed' => '操作执行失败', + 'loading_mask' => '数据加载中,请稍候...', + 'create_container' => '新建容器', + 'batch_restart' => '批量重启', + 'batch_stop' => '批量停止', + 'batch_remove' => '批量删除', + 'search_placeholder' => '搜索容器名称/镜像', + 'op_menu' => '操作 ▼', + 'view_log' => '查看日志', + 'view_network' => '查看网络', + 'enter_exec' => '进入容器', + 'stat_total' => '容器总数', + 'stat_running' => '运行中', + 'stat_stopped' => '已停止', + 'stat_image' => '本地镜像', + 'tip_exec_once' => '当前为单次命令执行,如需实时交互式终端需后端WebSocket扩展' + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'alert_list_page' => 'Alert Pagination List', + 'work_order_mgr' => 'Work Order System', + 'docker_mgr' => 'Docker Manager', + 'system_manager' => 'Role & Permission Manage', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh All Data', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'container_list' => 'Container List', + 'image_list' => 'Image List', + 'container_log' => 'Container Logs', + 'network_info' => 'Network Info', + 'exec_container' => 'Exec Container Command', + 'restart' => 'Restart', + 'stop' => 'Stop', + 'remove' => 'Force Remove', + 'input_cmd' => 'Only allow ls/pwd/cat/ps/df/free/top/du/whoami/env, ban rm/wget/curl/chmod', + 'execute' => 'Run', + 'close' => 'Close', + 'loading' => 'Loading...', + 'no_container' => 'No Containers', + 'no_image' => 'No Local Images', + 'request_fail' => 'API Request Failed', + 'container_id' => 'Container ID', + 'container_name' => 'Name', + 'image_name' => 'Image', + 'status' => 'Status', + 'port_mapping' => 'Ports', + 'operate' => 'Operate', + 'repo' => 'Repository', + 'tag' => 'Tag', + 'image_id' => 'Image ID', + 'size' => 'Size', + 'create_time' => 'Created At', + 'confirm_remove' => 'Confirm force delete container? Irreversible!', + 'op_success' => 'Operation succeeded, refreshed status', + 'op_failed' => 'Operation failed', + 'loading_mask' => 'Loading data, please wait...', + 'create_container' => 'Create Container', + 'batch_restart' => 'Batch Restart', + 'batch_stop' => 'Batch Stop', + 'batch_remove' => 'Batch Remove', + 'search_placeholder' => 'Search container / image', + 'op_menu' => 'Operate ▼', + 'view_log' => 'Logs', + 'view_network' => 'Network', + 'enter_exec' => 'Exec', + 'stat_total' => 'Total Containers', + 'stat_running' => 'Running', + 'stat_stopped' => 'Stopped', + 'stat_image' => 'Local Images', + 'tip_exec_once' => 'Single command execution only, real-time terminal requires WebSocket backend' + ] +]; +$t = $langMap[$currentLang]; + +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = [ + "name" => trim($item[0]), + "url" => trim($item[1]) + ]; + } + } +} +$pageSid = session_id(); +?> + + + + + +<?php echo $pageTitle; ?> - Advantest <?php echo $t['page_subtitle']; ?> + + + + + +
+ + +
+ +
+ + +
+
+
+
+
Advantest
+
+
+
+
+ + -- +
+ + +
+ + +
+
+ +
+ 当前页面SID:  |  接口SID:(SID一致,会话互通) +
+ +
+
+
+
+
+ +
+
+ + +
+
+
+
0
+
+
+
+
0
+
+
+
+
0
+
+
+
+
0
+
+
+ +
+
+
+
+ + +
+
+ +
+ + + +
+
+
+ + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+ + +
+
+ + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + diff --git a/gen.php b/gen.php new file mode 100644 index 0000000..447f0e0 --- /dev/null +++ b/gen.php @@ -0,0 +1,6 @@ +"; +var_dump(password_verify($raw, $hash)); +?> diff --git a/gen_pwd.php b/gen_pwd.php new file mode 100644 index 0000000..2d522a2 --- /dev/null +++ b/gen_pwd.php @@ -0,0 +1,3 @@ + + + + + + 登录 - 企业运维告警监控平台 + + + + + + + + + + diff --git a/login.php b/login.php new file mode 100644 index 0000000..21dac61 --- /dev/null +++ b/login.php @@ -0,0 +1,275 @@ + 0, 'time' => time()]; +$loginErr = $_SESSION[$lockKey]; +if (time() - $loginErr['time'] > 300) { + $_SESSION[$lockKey] = ['num' => 0, 'time' => time()]; + $loginErr = $_SESSION[$lockKey]; +} + +// 登录提交处理 +if ($_POST) { + $username = trim($_POST['username'] ?? ''); + $pwd = trim($_POST['pwd'] ?? ''); + if ($loginErr['num'] >= 5) { + $errMsg = "密码错误次数过多,请等待5分钟后重试"; + } elseif (!$username || !$pwd) { + $errMsg = "账号与密码不能为空"; + } else { + // 连接monitor权限库查询用户 + $connMonitor = mysqli_connect($dbHost, $dbUser, $dbPass, $dbMonitorName); + if (!$connMonitor) { + $errMsg = "数据库连接失败:" . mysqli_connect_error(); + } else { + mysqli_set_charset($connMonitor, "utf8mb4"); + $u = mysqli_real_escape_string($connMonitor, $username); + // 适配真实表字段,新增is_admin查询 + $sql = "SELECT id,username,password,role_id,is_admin,enable FROM sys_user WHERE username='$u' LIMIT 1"; + $res = mysqli_query($connMonitor, $sql); + // 新增判断:查询成功才读取数据 + if ($res) { + $user = mysqli_fetch_assoc($res); + // 先判断账号是否启用 + if (!$user) { + $_SESSION[$lockKey]['num']++; + $errMsg = "账号或密码输入错误"; + } elseif ($user['enable'] != 1) { + $errMsg = "该账号已被禁用,无法登录"; + } elseif (password_verify($pwd, $user['password'])) { + // 登录成功逻辑 + $_SESSION[$lockKey] = ['num' => 0, 'time' => time()]; + $_SESSION['user_id'] = $user['id']; + $_SESSION['username'] = $user['username']; + $_SESSION['role_id'] = $user['role_id']; + $_SESSION['is_admin'] = $user['is_admin']; + $_SESSION['login_time'] = time(); + mysqli_query($connMonitor, "UPDATE sys_user SET last_login=NOW() WHERE id=" . $user['id']); + mysqli_close($connMonitor); + header("Location: dashboard.php"); + exit; + } else { + $_SESSION[$lockKey]['num']++; + $errMsg = "账号或密码输入错误"; + } + } else { + // 捕获SQL执行失败原因 + $errMsg = "查询用户失败:" . mysqli_error($connMonitor); + } + mysqli_close($connMonitor); + } + } +} +?> + + + + + +Advantest 爱德万测试 - 运维监控登录 + + + + + + + + + + diff --git a/login.php.1.0 b/login.php.1.0 new file mode 100644 index 0000000..f09fecb --- /dev/null +++ b/login.php.1.0 @@ -0,0 +1,278 @@ + 0, 'time' => time()]; +$loginErr = $_SESSION[$lockKey]; +if (time() - $loginErr['time'] > 300) { + $_SESSION[$lockKey] = ['num' => 0, 'time' => time()]; + $loginErr = $_SESSION[$lockKey]; +} + +// 登录提交处理 +if ($_POST) { + $username = trim($_POST['username'] ?? ''); + $pwd = trim($_POST['pwd'] ?? ''); + if ($loginErr['num'] >= 5) { + $errMsg = "密码错误次数过多,请等待5分钟后重试"; + } elseif (!$username || !$pwd) { + $errMsg = "账号与密码不能为空"; + } else { + // 连接monitor权限库查询用户 + $connMonitor = mysqli_connect($dbHost, $dbUser, $dbPass, $dbMonitorName); + if (!$connMonitor) { + $errMsg = "数据库连接失败"; + } else { + mysqli_set_charset($connMonitor, "utf8mb4"); + $u = mysqli_real_escape_string($connMonitor, $username); + // 查询完整用户字段:id、账号、密码、角色ID、是否超级管理员 + $sql = "SELECT id,username,password,role_id,is_admin FROM sys_user WHERE username='$u' LIMIT 1"; + $res = mysqli_query($connMonitor, $sql); + $user = mysqli_fetch_assoc($res); + + // 密码校验(password_hash加密存储) + if ($user && password_verify($pwd, $user['password'])) { + // 清空错误计数 + $_SESSION[$lockKey] = ['num' => 0, 'time' => time()]; + // 写入鉴权必需session参数(适配auth.php) + $_SESSION['user_id'] = $user['id']; + $_SESSION['username'] = $user['username']; + $_SESSION['role_id'] = $user['role_id']; + $_SESSION['is_admin'] = $user['is_admin']; + $_SESSION['login_time'] = time(); + + // 更新最后登录时间(monitor库sys_user表) + mysqli_query($connMonitor, "UPDATE sys_user SET last_login=NOW() WHERE id=" . $user['id']); + mysqli_close($connMonitor); + + header("Location: dashboard.php"); + exit; + } else { + $_SESSION[$lockKey]['num']++; + $errMsg = "账号或密码输入错误"; + } + mysqli_close($connMonitor); + } + } +} +?> + + + + + +Advantest 爱德万测试 - 运维监控登录 + + + + + + + + + + diff --git a/login.php.bak b/login.php.bak new file mode 100644 index 0000000..7cebe54 --- /dev/null +++ b/login.php.bak @@ -0,0 +1,259 @@ + 0, 'time' => time()]; +$loginErr = $_SESSION[$lockKey]; +if (time() - $loginErr['time'] > 300) { + $_SESSION[$lockKey] = ['num' => 0, 'time' => time()]; + $loginErr = $_SESSION[$lockKey]; +} + +// 登录提交处理 +if ($_POST) { + $username = trim($_POST['username'] ?? ''); + $pwd = trim($_POST['pwd'] ?? ''); + if ($loginErr['num'] >= 5) { + $errMsg = "密码错误次数过多,请等待5分钟后重试"; + } elseif (!$username || !$pwd) { + $errMsg = "账号与密码不能为空"; + } else { + $conn = mysqli_connect($dbHost, $dbUser, $dbPass, $dbName); + $u = mysqli_real_escape_string($conn, $username); + $sql = "SELECT id,username,password,role FROM sys_user WHERE username='$u' LIMIT 1"; + $res = mysqli_query($conn, $sql); + $user = mysqli_fetch_assoc($res); + if ($user && password_verify($pwd, $user['password'])) { + $_SESSION[$lockKey] = ['num' => 0, 'time' => time()]; + $_SESSION['user_id'] = $user['id']; + $_SESSION['username'] = $user['username']; + $_SESSION['role'] = $user['role']; + $_SESSION['login_time'] = time(); + mysqli_query($conn, "UPDATE sys_user SET last_login=NOW() WHERE id=" . $user['id']); + header("Location: dashboard.php"); + exit; + } else { + $_SESSION[$lockKey]['num']++; + $errMsg = "账号或密码输入错误"; + } + mysqli_close($conn); + } +} +?> + + + + + +Advantest 爱德万测试 - 运维监控登录 + + + + + + + + + + diff --git a/login.php1 b/login.php1 new file mode 100644 index 0000000..c45eda2 --- /dev/null +++ b/login.php1 @@ -0,0 +1,116 @@ +0,'time'=>time()]; +$loginErr = $_SESSION[$lockKey]; +// 超过5分钟重置计数 +if (time() - $loginErr['time'] > 300) { + $_SESSION[$lockKey] = ['num'=>0,'time'=>time()]; + $loginErr = $_SESSION[$lockKey]; +} + +if ($_POST) { + $username = trim($_POST['username'] ?? ''); + $pwd = trim($_POST['pwd'] ?? ''); + if ($loginErr['num'] >= 5) { + $errMsg = "密码错误次数过多,请5分钟后重试"; + } elseif (!$username || !$pwd) { + $errMsg = "账号密码不能为空"; + } else { + $conn = mysqli_connect($dbHost, $dbUser, $dbPass, $dbName); + $u = mysqli_real_escape_string($conn, $username); + $sql = "SELECT id,username,password,role FROM sys_user WHERE username='$u' LIMIT 1"; + $res = mysqli_query($conn, $sql); + $user = mysqli_fetch_assoc($res); + if ($user && password_verify($pwd, $user['password'])) { + // 登录成功,清空错误计数,写入会话 + $_SESSION[$lockKey] = ['num'=>0,'time'=>time()]; + $_SESSION['user_id'] = $user['id']; + $_SESSION['username'] = $user['username']; + $_SESSION['role'] = $user['role']; + $_SESSION['login_time'] = time(); + // 更新最后登录时间 + mysqli_query($conn, "UPDATE sys_user SET last_login=NOW() WHERE id=".$user['id']); + header("Location: dashboard.php"); + exit; + } else { + $_SESSION[$lockKey]['num']++; + $errMsg = "账号或密码错误"; + } + mysqli_close($conn); + } +} +?> + + + + + +登录 - 企业运维告警监控平台 + + + + + + + + diff --git a/login.php2 b/login.php2 new file mode 100644 index 0000000..c45eda2 --- /dev/null +++ b/login.php2 @@ -0,0 +1,116 @@ +0,'time'=>time()]; +$loginErr = $_SESSION[$lockKey]; +// 超过5分钟重置计数 +if (time() - $loginErr['time'] > 300) { + $_SESSION[$lockKey] = ['num'=>0,'time'=>time()]; + $loginErr = $_SESSION[$lockKey]; +} + +if ($_POST) { + $username = trim($_POST['username'] ?? ''); + $pwd = trim($_POST['pwd'] ?? ''); + if ($loginErr['num'] >= 5) { + $errMsg = "密码错误次数过多,请5分钟后重试"; + } elseif (!$username || !$pwd) { + $errMsg = "账号密码不能为空"; + } else { + $conn = mysqli_connect($dbHost, $dbUser, $dbPass, $dbName); + $u = mysqli_real_escape_string($conn, $username); + $sql = "SELECT id,username,password,role FROM sys_user WHERE username='$u' LIMIT 1"; + $res = mysqli_query($conn, $sql); + $user = mysqli_fetch_assoc($res); + if ($user && password_verify($pwd, $user['password'])) { + // 登录成功,清空错误计数,写入会话 + $_SESSION[$lockKey] = ['num'=>0,'time'=>time()]; + $_SESSION['user_id'] = $user['id']; + $_SESSION['username'] = $user['username']; + $_SESSION['role'] = $user['role']; + $_SESSION['login_time'] = time(); + // 更新最后登录时间 + mysqli_query($conn, "UPDATE sys_user SET last_login=NOW() WHERE id=".$user['id']); + header("Location: dashboard.php"); + exit; + } else { + $_SESSION[$lockKey]['num']++; + $errMsg = "账号或密码错误"; + } + mysqli_close($conn); + } +} +?> + + + + + +登录 - 企业运维告警监控平台 + + + + + + + + diff --git a/logintiaoshi.php b/logintiaoshi.php new file mode 100644 index 0000000..b4ba923 --- /dev/null +++ b/logintiaoshi.php @@ -0,0 +1,139 @@ +0,'time'=>time()]; +$loginErr = $_SESSION[$lockKey]; +// 修复BUG:超过5分钟重置 +if (time() - $loginErr['time'] > 300) { + $_SESSION[$lockKey] = ['num'=>0,'time'=>time()]; + $loginErr = $_SESSION[$lockKey]; +} + +if ($_POST) { + $username = trim($_POST['username'] ?? ''); + $pwd = trim($_POST['pwd'] ?? ''); + + // ===================== 调试输出(帮你定位问题) ===================== + echo "
"; + echo "你输入的账号:" . $username . "
"; + echo "你输入的密码:" . $pwd . "
"; + + $conn = mysqli_connect($dbHost, $dbUser, $dbPass, $dbName); + if (!$conn) { + die("数据库连接失败:" . mysqli_connect_error()); + } + + $u = mysqli_real_escape_string($conn, $username); + $sql = "SELECT id,username,password,role FROM sys_user WHERE username='$u' LIMIT 1"; + $res = mysqli_query($conn, $sql); + $user = mysqli_fetch_assoc($res); + + echo "数据库查到的用户:" . ($user ? $user['username'] : "无此用户") . "
"; + echo "数据库密码哈希:" . ($user ? $user['password'] : "无") . "
"; + + $checkResult = $user ? password_verify($pwd, $user['password']) : false; + echo "密码校验结果:" . var_export($checkResult, true) . "
"; + echo "
"; + exit; + // ===================== 调试结束 ===================== + + if ($loginErr['num'] >= 5) { + $errMsg = "密码错误次数过多,请5分钟后重试"; + } elseif (!$username || !$pwd) { + $errMsg = "账号密码不能为空"; + } else { + $conn = mysqli_connect($dbHost, $dbUser, $dbPass, $dbName); + $u = mysqli_real_escape_string($conn, $username); + $sql = "SELECT id,username,password,role FROM sys_user WHERE username='$u' LIMIT 1"; + $res = mysqli_query($conn, $sql); + $user = mysqli_fetch_assoc($res); + if ($user && password_verify($pwd, $user['password'])) { + $_SESSION[$lockKey] = ['num'=>0,'time'=>time()]; + $_SESSION['user_id'] = $user['id']; + $_SESSION['username'] = $user['username']; + $_SESSION['role'] = $user['role']; + $_SESSION['login_time'] = time(); + mysqli_query($conn, "UPDATE sys_user SET last_login=NOW() WHERE id=".$user['id']); + header("Location: dashboard.php"); + exit; + } else { + $_SESSION[$lockKey]['num']++; + $errMsg = "账号或密码错误"; + } + mysqli_close($conn); + } +} +?> + + + + + +登录 - 企业运维告警监控平台 + + + + + + + + diff --git a/logout.php b/logout.php new file mode 100644 index 0000000..7649023 --- /dev/null +++ b/logout.php @@ -0,0 +1,5 @@ + + + + + + 告警接口可视化控制面板 + + + +
+

告警系统 - 接口可视化操作面板

+ + +
+

1. 临时隐藏单实例告警 clear_single_instance

+
+ + + + + +
+
仅插入恢复日志,下次故障自动重新展示;instance冒号不用手动编码,JS自动处理
+
+ + +
+

2. 永久屏蔽单实例 offline_single_instance

+
+ + + + + +
+
修改monitor_rule状态0,不恢复永远不告警
+
+ + +
+

3. 恢复单实例 restore_single_instance

+
+ + + + + +
+
放开单实例永久屏蔽状态
+
+ + +
+

4. 整条规则全部下线 clear_offline_rule

+
+ + + +
+
+ + +
+

5. 恢复整条规则 restore_rule

+
+ + + +
+
+ + +
+

6. 删除单实例所有告警日志 delete_single_instance_log

+
+ + + + + +
+
+ + +
+

7. 手动同步Prometheus告警(清除脏恢复记录)

+
+ +
+
自动删除故障中残留的手动恢复记录,修复前端不显示告警bug
+
+ + +
+

8. 数据查询接口(查看面板原始数据)

+
+ + + + +
+
+ + +
+

9. 导出今日告警CSV报表

+
+ +
+
+ + +
+

接口返回结果(JSON)

+
等待操作...
+
+
+ + + + diff --git a/php-fpm/www.conf b/php-fpm/www.conf new file mode 100644 index 0000000..47fad43 --- /dev/null +++ b/php-fpm/www.conf @@ -0,0 +1,11 @@ +[www] +user = www-data +group = www-data +listen = 0.0.0.0:9000 +listen.mode = 0660 +pm = dynamic +pm.max_children = 8 +pm.start_servers = 4 +pm.min_spare_servers = 2 +pm.max_spare_servers = 4 +pm.max_requests = 1000 diff --git a/python_api依赖.txt b/python_api依赖.txt new file mode 100644 index 0000000..acb9f6d --- /dev/null +++ b/python_api依赖.txt @@ -0,0 +1,20 @@ +# 1. 系统编译工具 +yum install gcc gcc-c++ python36-devel -y +# 2. 清理冲突socketio包 +pip3 uninstall flask-socketio python-socketio eventlet greenlet -y +# 3. 安装基础依赖 +pip3 install flask docker --user +# 4. docker权限 +usermod -aG docker root +newgrp docker +# 5. 验证docker连通 +python3 -c "import docker;cli=docker.DockerClient();print('Docker连接正常')" +# 6. 后台启动服务 +nohup python3 /opt/alert_dashboard/www/api/docker_api.py > /opt/alert_dashboard/www/api/docker_api.log 2>&1 & +# 7. 防火墙放行端口 +firewall-cmd --add-port=8090/tcp --permanent +firewall-cmd --reload +# 8. 查看运行状态 +sleep 2 +ps aux | grep docker_api.py +tail -n 20 /opt/alert_dashboard/www/api/docker_api.log \ No newline at end of file diff --git a/role_manage.php b/role_manage.php new file mode 100644 index 0000000..bf55158 --- /dev/null +++ b/role_manage.php @@ -0,0 +1,218 @@ +alert('角色名称不能为空');history.back();"; + exit; + } + // 新增角色 + if ($roleId == 0) { + mysqli_query($connConfig, "INSERT INTO sys_role(role_name) VALUES('$roleName')"); + $roleId = mysqli_insert_id($connConfig); + } else { + // 更新角色名 + mysqli_query($connConfig, "UPDATE sys_role SET role_name='$roleName' WHERE id=$roleId"); + // 清空旧权限 + mysqli_query($connConfig, "DELETE FROM sys_role_permission WHERE role_id=$roleId"); + } + // 写入新权限 + foreach ($pages as $page) { + $page = mysqli_real_escape_string($connConfig, $page); + mysqli_query($connConfig, "INSERT INTO sys_role_permission(role_id,page_key) VALUES($roleId,'$page')"); + } + echo ""; + exit; +} +// 删除角色 +if ($_GET['del']) { + $delId = intval($_GET['del']); + mysqli_query($connConfig, "DELETE FROM sys_role_permission WHERE role_id=$delId"); + mysqli_query($connConfig, "DELETE FROM sys_role WHERE id=$delId"); + header("Location: role_manage.php"); + exit; +} +// 获取所有角色 +$roleList = []; +$roleRes = mysqli_query($connConfig, "SELECT * FROM sys_role ORDER BY id DESC"); +while ($r = mysqli_fetch_assoc($roleRes)) $roleList[] = $r; +// 全部页面权限列表 +$allPages = [ + ['key'=>'dashboard','name'=>'告警总览'], + ['key'=>'work_order','name'=>'工单系统'], + ['key'=>'disk','name'=>'磁盘容量'], + ['key'=>'history_query','name'=>'历史查询'], + ['key'=>'smtp_config','name'=>'消息通知配置'], + ['key'=>'role_manage','name'=>'角色管理'], + ['key'=>'user_manage','name'=>'用户管理'], +]; +// 编辑角色时读取已有权限 +$editRole = ['id'=>0,'role_name'=>'','perms'=>[]]; +if (!empty($_GET['edit'])) { + $eid = intval($_GET['edit']); + $er = mysqli_fetch_assoc(mysqli_query($connConfig, "SELECT * FROM sys_role WHERE id=$eid")); + if ($er) { + $editRole = $er; + $permRes = mysqli_query($connConfig, "SELECT page_key FROM sys_role_permission WHERE role_id=$eid"); + while ($p = mysqli_fetch_assoc($permRes)) $editRole['perms'][] = $p['page_key']; + } +} +mysqli_close($connConfig); +?> + + + + + <?php echo $pageTitle; ?> + + + + + +
+ +
+
+
+
+
Advantest
+
+
+
+
+ + + 0):?> + + + -- +
+ + +
+ + +
+
+
+
+
新增/编辑角色
+
+ + +
+ + +
+
+ +
+ +
+ > + +
+ +
+
+ +
+
+
+
角色列表
+ + + + + + + + + + + + + +
ID角色名称操作
+ 编辑 + 删除 +
+
+
+
+
+ + + diff --git a/smtp_config.php b/smtp_config.php new file mode 100644 index 0000000..95b678b --- /dev/null +++ b/smtp_config.php @@ -0,0 +1,536 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRoleId = $_SESSION['role_id']; + +// 全局配置库连接 +$dbConfigHost = "10.150.117.190"; +$dbConfigUser = "root"; +$dbConfigPwd = "hp93000"; +$dbConfigName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbConfigHost, $dbConfigUser, $dbConfigPwd, $dbConfigName); +if(!$connConfig){ + die("配置库连接失败"); +} +mysqli_set_charset($connConfig, "utf8mb4"); + +// 自动创建SMTP配置表,不存在则新建 +mysqli_query($connConfig, "CREATE TABLE IF NOT EXISTS sys_smtp_config ( + id INT PRIMARY KEY AUTO_INCREMENT, + smtp_host VARCHAR(200) NOT NULL DEFAULT '', + smtp_port INT NOT NULL DEFAULT 25, + smtp_ssl TINYINT NOT NULL DEFAULT 0, + smtp_user VARCHAR(200) NOT NULL DEFAULT '', + smtp_pass VARCHAR(200) NOT NULL DEFAULT '', + send_from VARCHAR(200) NOT NULL DEFAULT '' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"); + +$checkRow = mysqli_fetch_assoc(mysqli_query($connConfig, "SELECT id FROM sys_smtp_config LIMIT 1")); +if (empty($checkRow)) { + mysqli_query($connConfig, "INSERT INTO sys_smtp_config (id) VALUES (1)"); +} + +// 自动创建工单推送通知表 +mysqli_query($connConfig, "CREATE TABLE IF NOT EXISTS sys_workorder_notify ( + id INT PRIMARY KEY AUTO_INCREMENT, + dingtalk_webhook VARCHAR(500) NOT NULL DEFAULT '', + dingtalk_secret VARCHAR(200) NOT NULL DEFAULT '', + wecom_webhook VARCHAR(500) NOT NULL DEFAULT '', + wecom_mention VARCHAR(300) NOT NULL DEFAULT '', + notify_open TINYINT NOT NULL DEFAULT 0, + update_time DATETIME NOT NULL DEFAULT NOW() +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"); + +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} + +// 安全读取SMTP配置,杜绝mysqli警告 +$smtpRow = []; +$sqlSmtp = "SELECT * FROM sys_smtp_config WHERE id=1"; +if (!empty(trim($sqlSmtp))) { + $smtpQuery = mysqli_query($connConfig, $sqlSmtp); + if ($smtpQuery !== false && $smtpQuery instanceof mysqli_result) { + $smtpRow = mysqli_fetch_assoc($smtpQuery) ?: []; + } +} +$smtpConfig = $smtpRow ?? []; + +// 安全读取推送通知配置 +$notifyConfig = []; +$notifyQuery = mysqli_query($connConfig, "SELECT * FROM sys_workorder_notify LIMIT 1"); +if ($notifyQuery instanceof mysqli_result) { + $notifyConfig = mysqli_fetch_assoc($notifyQuery) ?: []; +} + +$pageTitle = htmlspecialchars($sysConfig['page_subtitle'] ?? "工单消息通知配置"); +$currentLang = $sysConfig['lang'] ?? "zh"; +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +mysqli_close($connConfig); + +// 多语言词典(菜单文字全部替换:SMTP配置 → 工单消息通知配置) +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '工单消息通知配置', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警总览', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'notify_config' => '工单消息通知配置', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新页面', + 'export_csv' => '导出CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'work_order_mgr' => '工单系统', + 'save_all' => '保存全部通知配置', + 'card_title' => '工单消息推送 & 发件邮箱统一配置', + 'group_mail' => '邮箱SMTP发件设置', + 'smtp_host' => 'SMTP服务器', + 'smtp_port' => '端口', + 'smtp_ssl' => '启用SSL/TLS加密', + 'smtp_account' => '登录账号', + 'smtp_pwd' => '授权密码', + 'smtp_from' => '发件人邮箱', + 'group_push' => '工单变更推送配置', + 'notify_switch' => '开启工单变更自动推送', + 'dingtalk_webhook' => '钉钉Webhook地址', + 'dingtalk_secret' => '钉钉安全密钥(可选)', + 'wecom_webhook' => '企业微信Webhook地址', + 'wecom_mention' => '@提醒人员(多个逗号分隔,all=全员)', + 'placeholder_webhook' => '输入完整Webhook链接', + 'placeholder_secret' => '无安全校验则留空', + 'placeholder_mention' => '填写手机号,all代表所有人', + 'save_success' => '配置保存成功' + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Work Order Notification Config', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'notify_config' => 'Work Order Notification Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh', + 'export_csv' => 'Export CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'work_order_mgr' => 'Work Order System', + 'save_all' => 'Save All Notification Config', + 'card_title' => 'Work Order Push & Mail Sender Config', + 'group_mail' => 'SMTP Mail Sender', + 'smtp_host' => 'SMTP Host', + 'smtp_port' => 'Port', + 'smtp_ssl' => 'Enable SSL/TLS', + 'smtp_account' => 'Account', + 'smtp_pwd' => 'Auth Password', + 'smtp_from' => 'Sender Email', + 'group_push' => 'Work Order Push Setting', + 'notify_switch' => 'Auto push on order change', + 'dingtalk_webhook' => 'DingTalk Webhook', + 'dingtalk_secret' => 'DingTalk Secret (Optional)', + 'wecom_webhook' => 'WeCom Webhook', + 'wecom_mention' => 'Mention user (split by comma, all=everyone)', + 'placeholder_webhook' => 'Full webhook url', + 'placeholder_secret' => 'Leave empty if no secret', + 'placeholder_mention' => 'Mobile number or all', + 'save_success' => 'Config saved successfully' + ] +]; +$t = $langMap[$currentLang]; + +// 解析外链菜单 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = ["name" => trim($item[0]), "url" => trim($item[1])]; + } + } +} + +// 统一保存表单提交逻辑(SMTP+推送一次保存) +if ($_POST['act'] === "save_all") { + // 更新SMTP邮箱配置 + $host = trim($_POST['smtp_host'] ?? ''); + $port = intval($_POST['smtp_port'] ?? 25); + $ssl = intval($_POST['smtp_ssl'] ?? 0); + $user = trim($_POST['smtp_user'] ?? ''); + $pwd = trim($_POST['smtp_pass'] ?? ''); + $from = trim($_POST['smtp_from'] ?? ''); + mysqli_query($connConfig, "UPDATE sys_smtp_config SET smtp_host='$host',smtp_port=$port,smtp_ssl=$ssl,smtp_user='$user',smtp_pass='$pwd',send_from='$from' WHERE id=1"); + + // 更新工单推送配置 + $ding_webhook = trim($_POST['dingtalk_webhook'] ?? ''); + $ding_secret = trim($_POST['dingtalk_secret'] ?? ''); + $wecom_webhook = trim($_POST['wecom_webhook'] ?? ''); + $wecom_mention = trim($_POST['wecom_mention'] ?? ''); + $notify_open = intval($_POST['notify_open'] ?? 0); + $existNotify = mysqli_fetch_assoc(mysqli_query($connConfig, "SELECT id FROM sys_workorder_notify LIMIT 1")); + if ($existNotify) { + mysqli_query($connConfig, "UPDATE sys_workorder_notify SET dingtalk_webhook='$ding_webhook', dingtalk_secret='$ding_secret', wecom_webhook='$wecom_webhook', wecom_mention='$wecom_mention', notify_open=$notify_open, update_time=NOW() WHERE id = {$existNotify['id']}"); + } else { + mysqli_query($connConfig, "INSERT INTO sys_workorder_notify (dingtalk_webhook,dingtalk_secret,wecom_webhook,wecom_mention,notify_open) VALUES ('$ding_webhook','$ding_secret','$wecom_webhook','$wecom_mention',$notify_open)"); + } + echo ""; + exit; +} +?> + + + + + + <?php echo $pageTitle; ?> + + + + + +
+ + + +
+
+
+
+
Advantest
+
+
+
+
+ + -- +
+ + +
+ + +
+
+ +
+ +
+
+
+ + + +
+
+ + +
+
+ + +
+ +
+ +
+ > + +
+
+
+ + +
+
+ + +
+
+ + +
+ + +
+ +
+ +
+ > + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + +
+ +
+
+
+
+
+
+ + + + + diff --git a/smtp_config.php.1.0 b/smtp_config.php.1.0 new file mode 100644 index 0000000..ef292f3 --- /dev/null +++ b/smtp_config.php.1.0 @@ -0,0 +1,444 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); + +// 读取配置库 +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$conn = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($conn, "utf8mb4"); +$currentLang = mysqli_fetch_assoc(mysqli_query($conn, "SELECT v FROM sys_config WHERE k='lang'"))['v'] ?? "zh"; + +// 多语言(统一侧边栏中英对照) +$langMap = [ + 'zh' => [ + 'page_subtitle' => '爱德万测试 · 系统通知配置', + 'menu_monitor' => '监控面板', + 'menu_workorder' => '工单系统', + 'menu_system' => '系统管理', + 'menu_admin' => '后台配置', + 'menu_smtp' => '邮箱SMTP配置', + 'menu_notify' => '工单通知告警配置', + 'smtp_config' => '邮箱SMTP配置', + 'smtp_host' => 'SMTP服务器', + 'smtp_port' => '端口', + 'smtp_ssl' => '启用SSL/TLS', + 'smtp_account' => '发件账号', + 'smtp_pwd' => '授权密码', + 'smtp_from' => '发件人邮箱', + 'save_smtp' => '保存邮箱配置', + 'save_success' => '保存成功', + 'notify_title' => '工单告警通知配置', + 'dingtalk_webhook' => '钉钉Webhook地址', + 'dingtalk_secret' => '钉钉加签密钥(可选)', + 'wecom_webhook' => '企业微信Webhook地址', + 'wecom_mention' => '企业微信@人员(多个用逗号分隔)', + 'notify_switch' => '开启工单自动推送告警', + 'save_notify' => '保存通知配置', + 'placeholder_webhook' => '请输入Webhook完整地址', + 'placeholder_secret' => '不使用加签留空', + 'placeholder_mention' => 'all代表所有人,或填写手机号' + ], + 'en' => [ + 'page_subtitle' => 'Advantest · System Notify Config', + 'menu_monitor' => 'Monitor Panel', + 'menu_workorder' => 'Work Order System', + 'menu_system' => 'System Manage', + 'menu_admin' => 'System Config', + 'menu_smtp' => 'SMTP Mail Config', + 'menu_notify' => 'Work Order Alert Notify', + 'smtp_config' => 'SMTP Mail Config', + 'smtp_host' => 'SMTP Host', + 'smtp_port' => 'Port', + 'smtp_ssl' => 'Enable SSL/TLS', + 'smtp_account' => 'SMTP Account', + 'smtp_pwd' => 'Auth Password', + 'smtp_from' => 'Sender Email', + 'save_smtp' => 'Save Mail Config', + 'save_success' => 'Saved successfully', + 'notify_title' => 'Work Order Alert Notification', + 'dingtalk_webhook' => 'DingTalk Webhook', + 'dingtalk_secret' => 'DingTalk Secret (Optional)', + 'wecom_webhook' => 'WeCom Webhook', + 'wecom_mention' => 'WeCom Mention User (split by comma)', + 'notify_switch' => 'Auto push work order alert', + 'save_notify' => 'Save Notify Config', + 'placeholder_webhook' => 'Input full webhook url', + 'placeholder_secret' => 'Leave empty if no secret', + 'placeholder_mention' => 'all for everyone, or mobile number' + ] +]; +$t = $langMap[$currentLang]; + +// 保存提交处理 +if ($_POST['act'] === "save_smtp") { + $host = trim($_POST['smtp_host'] ?? ''); + $port = intval($_POST['smtp_port'] ?? 25); + $ssl = intval($_POST['smtp_ssl'] ?? 0); + $user = trim($_POST['smtp_user'] ?? ''); + $pwd = trim($_POST['smtp_pass'] ?? ''); + $from = trim($_POST['smtp_from'] ?? ''); + mysqli_query($conn, "UPDATE sys_smtp_config SET smtp_host='$host',smtp_port=$port,smtp_ssl=$ssl,smtp_user='$user',smtp_pass='$pwd',send_from='$from' WHERE id=1"); + echo ""; + exit; +} +if ($_POST['act'] === "save_notify") { + $ding_webhook = trim($_POST['dingtalk_webhook'] ?? ''); + $ding_secret = trim($_POST['dingtalk_secret'] ?? ''); + $wecom_webhook = trim($_POST['wecom_webhook'] ?? ''); + $wecom_mention = trim($_POST['wecom_mention'] ?? ''); + $notify_open = intval($_POST['notify_open'] ?? 0); + // 通知配置表,不存在先建表(首次访问自动创建) + mysqli_query($conn, "CREATE TABLE IF NOT EXISTS sys_workorder_notify ( + id INT PRIMARY KEY AUTO_INCREMENT, + dingtalk_webhook VARCHAR(500) NOT NULL DEFAULT '', + dingtalk_secret VARCHAR(200) NOT NULL DEFAULT '', + wecom_webhook VARCHAR(500) NOT NULL DEFAULT '', + wecom_mention VARCHAR(300) NOT NULL DEFAULT '', + notify_open TINYINT NOT NULL DEFAULT 0, + update_time DATETIME NOT NULL DEFAULT NOW() + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"); + $exist = mysqli_fetch_assoc(mysqli_query($conn, "SELECT id FROM sys_workorder_notify LIMIT 1")); + if ($exist) { + mysqli_query($conn, "UPDATE sys_workorder_notify SET + dingtalk_webhook='$ding_webhook', + dingtalk_secret='$ding_secret', + wecom_webhook='$wecom_webhook', + wecom_mention='$wecom_mention', + notify_open=$notify_open, + update_time=NOW() + WHERE id = {$exist['id']}"); + } else { + mysqli_query($conn, "INSERT INTO sys_workorder_notify + (dingtalk_webhook,dingtalk_secret,wecom_webhook,wecom_mention,notify_open) + VALUES ('$ding_webhook','$ding_secret','$wecom_webhook','$wecom_mention',$notify_open)"); + } + echo ""; + exit; +} + +// 读取SMTP配置 +$smtpRow = []; +$sql = "SELECT * FROM sys_smtp_config WHERE id = 1"; +$res = mysqli_query($conn, $sql); +if ($res instanceof mysqli_result) { + $smtpRow = mysqli_fetch_assoc($res) ?: []; +} +$smtpConfig = $smtpRow; + +// 读取工单通知配置 +$notifyConfig = []; +$notifyRes = mysqli_query($conn, "SELECT * FROM sys_workorder_notify LIMIT 1"); +if ($notifyRes instanceof mysqli_result) { + $notifyConfig = mysqli_fetch_assoc($notifyRes) ?: []; +} +?> + + + + + +System Notify Config - Advantest + + + + + +
+ +
+
+
+
+
Advantest
+
+
+
+
+ + +
+
+
+ +
+
+
+ +
+ + +
+
+ + +
+
+ > + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+ + +
+
+
+ +
+ > + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+
+
+
+ + diff --git a/smtp_config.php.2.0 b/smtp_config.php.2.0 new file mode 100644 index 0000000..00300f5 --- /dev/null +++ b/smtp_config.php.2.0 @@ -0,0 +1,452 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); + +// 读取配置库 +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$conn = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($conn, "utf8mb4"); +$currentLang = mysqli_fetch_assoc(mysqli_query($conn, "SELECT v FROM sys_config WHERE k='lang'"))['v'] ?? "zh"; + +// 多语言(统一侧边栏中英对照) +$langMap = [ + 'zh' => [ + 'page_subtitle' => '爱德万测试 · 系统通知配置', + 'menu_monitor' => '监控面板', + 'menu_workorder' => '工单系统', + 'menu_system' => '系统管理', + 'menu_admin' => '后台配置', + 'menu_smtp' => '邮箱SMTP配置', + 'menu_notify' => '工单通知告警配置', + 'smtp_config' => '邮箱SMTP配置', + 'smtp_host' => 'SMTP服务器', + 'smtp_port' => '端口', + 'smtp_ssl' => '启用SSL/TLS', + 'smtp_account' => '发件账号', + 'smtp_pwd' => '授权密码', + 'smtp_from' => '发件人邮箱', + 'save_smtp' => '保存邮箱配置', + 'save_success' => '保存成功', + 'notify_title' => '工单告警通知配置', + 'dingtalk_webhook' => '钉钉Webhook地址', + 'dingtalk_secret' => '钉钉加签密钥(可选)', + 'wecom_webhook' => '企业微信Webhook地址', + 'wecom_mention' => '企业微信@人员(多个用逗号分隔)', + 'notify_switch' => '开启工单自动推送告警', + 'save_notify' => '保存通知配置', + 'placeholder_webhook' => '请输入Webhook完整地址', + 'placeholder_secret' => '不使用加签留空', + 'placeholder_mention' => 'all代表所有人,或填写手机号' + ], + 'en' => [ + 'page_subtitle' => 'Advantest · System Notify Config', + 'menu_monitor' => 'Monitor Panel', + 'menu_workorder' => 'Work Order System', + 'menu_system' => 'System Manage', + 'menu_admin' => 'System Config', + 'menu_smtp' => 'SMTP Mail Config', + 'menu_notify' => 'Work Order Alert Notify', + 'smtp_config' => 'SMTP Mail Config', + 'smtp_host' => 'SMTP Host', + 'smtp_port' => 'Port', + 'smtp_ssl' => 'Enable SSL/TLS', + 'smtp_account' => 'SMTP Account', + 'smtp_pwd' => 'Auth Password', + 'smtp_from' => 'Sender Email', + 'save_smtp' => 'Save Mail Config', + 'save_success' => 'Saved successfully', + 'notify_title' => 'Work Order Alert Notification', + 'dingtalk_webhook' => 'DingTalk Webhook', + 'dingtalk_secret' => 'DingTalk Secret (Optional)', + 'wecom_webhook' => 'WeCom Webhook', + 'wecom_mention' => 'WeCom Mention User (split by comma)', + 'notify_switch' => 'Auto push work order alert', + 'save_notify' => 'Save Notify Config', + 'placeholder_webhook' => 'Input full webhook url', + 'placeholder_secret' => 'Leave empty if no secret', + 'placeholder_mention' => 'all for everyone, or mobile number' + ] +]; +$t = $langMap[$currentLang]; + +// 保存提交处理 +if ($_POST['act'] === "save_smtp") { + $host = trim($_POST['smtp_host'] ?? ''); + $port = intval($_POST['smtp_port'] ?? 25); + $ssl = intval($_POST['smtp_ssl'] ?? 0); + $user = trim($_POST['smtp_user'] ?? ''); + $pwd = trim($_POST['smtp_pass'] ?? ''); + $from = trim($_POST['smtp_from'] ?? ''); + mysqli_query($conn, "UPDATE sys_smtp_config SET smtp_host='$host',smtp_port=$port,smtp_ssl=$ssl,smtp_user='$user',smtp_pass='$pwd',send_from='$from' WHERE id=1"); + echo ""; + exit; +} +if ($_POST['act'] === "save_notify") { + $ding_webhook = trim($_POST['dingtalk_webhook'] ?? ''); + $ding_secret = trim($_POST['dingtalk_secret'] ?? ''); + $wecom_webhook = trim($_POST['wecom_webhook'] ?? ''); + $wecom_mention = trim($_POST['wecom_mention'] ?? ''); + $notify_open = intval($_POST['notify_open'] ?? 0); + mysqli_query($conn, "CREATE TABLE IF NOT EXISTS sys_workorder_notify ( + id INT PRIMARY KEY AUTO_INCREMENT, + dingtalk_webhook VARCHAR(500) NOT NULL DEFAULT '', + dingtalk_secret VARCHAR(200) NOT NULL DEFAULT '', + wecom_webhook VARCHAR(500) NOT NULL DEFAULT '', + wecom_mention VARCHAR(300) NOT NULL DEFAULT '', + notify_open TINYINT NOT NULL DEFAULT 0, + update_time DATETIME NOT NULL DEFAULT NOW() + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"); + $exist = mysqli_fetch_assoc(mysqli_query($conn, "SELECT id FROM sys_workorder_notify LIMIT 1")); + if ($exist) { + mysqli_query($conn, "UPDATE sys_workorder_notify SET + dingtalk_webhook='$ding_webhook', + dingtalk_secret='$ding_secret', + wecom_webhook='$wecom_webhook', + wecom_mention='$wecom_mention', + notify_open=$notify_open, + update_time=NOW() + WHERE id = {$exist['id']}"); + } else { + mysqli_query($conn, "INSERT INTO sys_workorder_notify + (dingtalk_webhook,dingtalk_secret,wecom_webhook,wecom_mention,notify_open) + VALUES ('$ding_webhook','$ding_secret','$wecom_webhook','$wecom_mention',$notify_open)"); + } + echo ""; + exit; +} + +// 读取SMTP配置 +$smtpRow = []; +$sql = "SELECT * FROM sys_smtp_config WHERE id = 1"; +$res = mysqli_query($conn, $sql); +if ($res instanceof mysqli_result) { + $smtpRow = mysqli_fetch_assoc($res) ?: []; +} +$smtpConfig = $smtpRow; + +// 读取工单通知配置 +$notifyConfig = []; +$notifyRes = mysqli_query($conn, "SELECT * FROM sys_workorder_notify LIMIT 1"); +if ($notifyRes instanceof mysqli_result) { + $notifyConfig = mysqli_fetch_assoc($notifyRes) ?: []; +} +?> + + + + + +System Notify Config - Advantest + + + + + +
+ +
+
+
+
+
Advantest
+
+
+
+
+ + +
+
+
+ +
+
+
+ +
+ + +
+
+ + +
+
+ > + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+ + +
+
+
+ +
+ > + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+
+
+
+ + diff --git a/smtp_config.php.3.0 b/smtp_config.php.3.0 new file mode 100644 index 0000000..9661511 --- /dev/null +++ b/smtp_config.php.3.0 @@ -0,0 +1,545 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRoleId = $_SESSION['role_id']; + +// 全局配置库连接 +$dbConfigHost = "10.150.117.190"; +$dbConfigUser = "root"; +$dbConfigPwd = "hp93000"; +$dbConfigName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbConfigHost, $dbConfigUser, $dbConfigPwd, $dbConfigName); +if(!$connConfig){ + die("配置库连接失败"); +} +mysqli_set_charset($connConfig, "utf8mb4"); + +// 自动创建SMTP配置表,不存在则新建 +mysqli_query($connConfig, "CREATE TABLE IF NOT EXISTS sys_smtp_config ( + id INT PRIMARY KEY AUTO_INCREMENT, + smtp_host VARCHAR(200) NOT NULL DEFAULT '', + smtp_port INT NOT NULL DEFAULT 25, + smtp_ssl TINYINT NOT NULL DEFAULT 0, + smtp_user VARCHAR(200) NOT NULL DEFAULT '', + smtp_pass VARCHAR(200) NOT NULL DEFAULT '', + send_from VARCHAR(200) NOT NULL DEFAULT '' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"); + +$checkRow = mysqli_fetch_assoc(mysqli_query($connConfig, "SELECT id FROM sys_smtp_config LIMIT 1")); +if (empty($checkRow)) { + mysqli_query($connConfig, "INSERT INTO sys_smtp_config (id) VALUES (1)"); +} + +// 自动创建工单推送通知表 +mysqli_query($connConfig, "CREATE TABLE IF NOT EXISTS sys_workorder_notify ( + id INT PRIMARY KEY AUTO_INCREMENT, + dingtalk_webhook VARCHAR(500) NOT NULL DEFAULT '', + dingtalk_secret VARCHAR(200) NOT NULL DEFAULT '', + wecom_webhook VARCHAR(500) NOT NULL DEFAULT '', + wecom_mention VARCHAR(300) NOT NULL DEFAULT '', + notify_open TINYINT NOT NULL DEFAULT 0, + update_time DATETIME NOT NULL DEFAULT NOW() +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"); + +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} + +// 安全读取SMTP配置,杜绝mysqli警告 +$smtpRow = []; +$sqlSmtp = "SELECT * FROM sys_smtp_config WHERE id=1"; +if (!empty(trim($sqlSmtp))) { + $smtpQuery = mysqli_query($connConfig, $sqlSmtp); + if ($smtpQuery !== false && $smtpQuery instanceof mysqli_result) { + $smtpRow = mysqli_fetch_assoc($smtpQuery) ?: []; + } +} +$smtpConfig = $smtpRow ?? []; + +// 安全读取推送通知配置 +$notifyConfig = []; +$notifyQuery = mysqli_query($connConfig, "SELECT * FROM sys_workorder_notify LIMIT 1"); +if ($notifyQuery instanceof mysqli_result) { + $notifyConfig = mysqli_fetch_assoc($notifyQuery) ?: []; +} + +$pageTitle = htmlspecialchars($sysConfig['page_subtitle'] ?? "工单消息通知配置"); +$currentLang = $sysConfig['lang'] ?? "zh"; +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +mysqli_close($connConfig); + +// 多语言词典(菜单文字全部替换:SMTP配置 → 工单消息通知配置) +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '工单消息通知配置', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警总览', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'notify_config' => '工单消息通知配置', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新页面', + 'export_csv' => '导出CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'work_order_mgr' => '工单系统', + 'save_all' => '保存全部通知配置', + 'card_title' => '工单消息推送 & 发件邮箱统一配置', + 'group_mail' => '邮箱SMTP发件设置', + 'smtp_host' => 'SMTP服务器', + 'smtp_port' => '端口', + 'smtp_ssl' => '启用SSL/TLS加密', + 'smtp_account' => '登录账号', + 'smtp_pwd' => '授权密码', + 'smtp_from' => '发件人邮箱', + 'group_push' => '工单变更推送配置', + 'notify_switch' => '开启工单变更自动推送', + 'dingtalk_webhook' => '钉钉Webhook地址', + 'dingtalk_secret' => '钉钉安全密钥(可选)', + 'wecom_webhook' => '企业微信Webhook地址', + 'wecom_mention' => '@提醒人员(多个逗号分隔,all=全员)', + 'placeholder_webhook' => '输入完整Webhook链接', + 'placeholder_secret' => '无安全校验则留空', + 'placeholder_mention' => '填写手机号,all代表所有人', + 'save_success' => '配置保存成功' + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Work Order Notification Config', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'notify_config' => 'Work Order Notification Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh', + 'export_csv' => 'Export CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'work_order_mgr' => 'Work Order System', + 'save_all' => 'Save All Notification Config', + 'card_title' => 'Work Order Push & Mail Sender Config', + 'group_mail' => 'SMTP Mail Sender', + 'smtp_host' => 'SMTP Host', + 'smtp_port' => 'Port', + 'smtp_ssl' => 'Enable SSL/TLS', + 'smtp_account' => 'Account', + 'smtp_pwd' => 'Auth Password', + 'smtp_from' => 'Sender Email', + 'group_push' => 'Work Order Push Setting', + 'notify_switch' => 'Auto push on order change', + 'dingtalk_webhook' => 'DingTalk Webhook', + 'dingtalk_secret' => 'DingTalk Secret (Optional)', + 'wecom_webhook' => 'WeCom Webhook', + 'wecom_mention' => 'Mention user (split by comma, all=everyone)', + 'placeholder_webhook' => 'Full webhook url', + 'placeholder_secret' => 'Leave empty if no secret', + 'placeholder_mention' => 'Mobile number or all', + 'save_success' => 'Config saved successfully' + ] +]; +$t = $langMap[$currentLang]; + +// 解析外链菜单 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = ["name" => trim($item[0]), "url" => trim($item[1])]; + } + } +} + +// 统一保存表单提交逻辑(SMTP+推送一次保存) +if ($_POST['act'] === "save_all") { + // 更新SMTP邮箱配置 + $host = trim($_POST['smtp_host'] ?? ''); + $port = intval($_POST['smtp_port'] ?? 25); + $ssl = intval($_POST['smtp_ssl'] ?? 0); + $user = trim($_POST['smtp_user'] ?? ''); + $pwd = trim($_POST['smtp_pass'] ?? ''); + $from = trim($_POST['smtp_from'] ?? ''); + mysqli_query($connConfig, "UPDATE sys_smtp_config SET smtp_host='$host',smtp_port=$port,smtp_ssl=$ssl,smtp_user='$user',smtp_pass='$pwd',send_from='$from' WHERE id=1"); + + // 更新工单推送配置 + $ding_webhook = trim($_POST['dingtalk_webhook'] ?? ''); + $ding_secret = trim($_POST['dingtalk_secret'] ?? ''); + $wecom_webhook = trim($_POST['wecom_webhook'] ?? ''); + $wecom_mention = trim($_POST['wecom_mention'] ?? ''); + $notify_open = intval($_POST['notify_open'] ?? 0); + $existNotify = mysqli_fetch_assoc(mysqli_query($connConfig, "SELECT id FROM sys_workorder_notify LIMIT 1")); + if ($existNotify) { + mysqli_query($connConfig, "UPDATE sys_workorder_notify SET dingtalk_webhook='$ding_webhook', dingtalk_secret='$ding_secret', wecom_webhook='$wecom_webhook', wecom_mention='$wecom_mention', notify_open=$notify_open, update_time=NOW() WHERE id = {$existNotify['id']}"); + } else { + mysqli_query($connConfig, "INSERT INTO sys_workorder_notify (dingtalk_webhook,dingtalk_secret,wecom_webhook,wecom_mention,notify_open) VALUES ('$ding_webhook','$ding_secret','$wecom_webhook','$wecom_mention',$notify_open)"); + } + echo ""; + exit; +} +?> + + + + + + <?php echo $pageTitle; ?> + + + + + +
+ + + +
+
+
+
+
Advantest
+
+
+
+
+ + -- +
+ + +
+ + +
+
+ +
+ +
+
+
+ + + +
+
+ + +
+
+ + +
+ +
+ +
+ > + +
+
+
+ + +
+
+ + +
+
+ + +
+ + +
+ +
+ +
+ > + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + +
+ +
+
+
+
+
+
+ + + + + diff --git a/smtp_config.php.bak b/smtp_config.php.bak new file mode 100644 index 0000000..594cbda --- /dev/null +++ b/smtp_config.php.bak @@ -0,0 +1,192 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); + +// 读取配置库 +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$conn = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($conn, "utf8mb4"); +$currentLang = mysqli_fetch_assoc(mysqli_query($conn, "SELECT v FROM sys_config WHERE k='lang'"))['v'] ?? "zh"; + +// 多语言 +$langMap = [ + 'zh' => [ + 'page_subtitle' => '爱德万测试 · SMTP邮箱配置', + 'smtp_config' => '邮箱SMTP配置', + 'smtp_host' => 'SMTP服务器', + 'smtp_port' => '端口', + 'smtp_ssl' => '启用SSL/TLS', + 'smtp_account' => '发件账号', + 'smtp_pwd' => '授权密码', + 'smtp_from' => '发件人邮箱', + 'save_smtp' => '保存配置', + 'save_success' => '保存成功', + ], + 'en' => [ + 'page_subtitle' => 'Advantest · SMTP Mail Config', + 'smtp_config' => 'SMTP Mail Config', + 'smtp_host' => 'SMTP Host', + 'smtp_port' => 'Port', + 'smtp_ssl' => 'Enable SSL/TLS', + 'smtp_account' => 'SMTP Account', + 'smtp_pwd' => 'Auth Password', + 'smtp_from' => 'Sender Email', + 'save_smtp' => 'Save Config', + 'save_success' => 'Saved successfully', + ] +]; +$t = $langMap[$currentLang]; + +// 保存提交 +if ($_POST['act'] === "save_smtp") { + $host = trim($_POST['smtp_host'] ?? ''); + $port = intval($_POST['smtp_port'] ?? 25); + $ssl = intval($_POST['smtp_ssl'] ?? 0); + $user = trim($_POST['smtp_user'] ?? ''); + $pwd = trim($_POST['smtp_pass'] ?? ''); + $from = trim($_POST['smtp_from'] ?? ''); + mysqli_query($conn, "UPDATE sys_smtp_config SET smtp_host='$host',smtp_port=$port,smtp_ssl=$ssl,smtp_user='$user',smtp_pass='$pwd',send_from='$from' WHERE id=1"); + echo ""; + exit; +} +// 1. 先判断SQL不为空,避免空查询警告 +$sql = "SELECT * FROM sys_smtp_config WHERE id = 1"; +if (!empty($sql)) { + $res = mysqli_query($conn, $sql); + // 2. 判断查询成功且返回有效结果集再执行fetch + if ($res instanceof mysqli_result) { + $smtpRow = mysqli_fetch_assoc($res); + } else { + $smtpRow = []; + } +} else { + $smtpRow = []; +} +$smtpConfig = $smtpRow ?? []; +?> + + + + + +SMTP Config - Advantest + + + + + +
+ +
+
+
+
+
Advantest
+
+
+
+
+ + +
+
+
+
+
+
+ +
+ + +
+
+ + +
+
+ + > +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+
+
+ + diff --git a/static/css/font-awesome.min.css b/static/css/font-awesome.min.css new file mode 100644 index 0000000..540440c --- /dev/null +++ b/static/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/static/fonts/fontawesome-webfont.eot b/static/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/static/fonts/fontawesome-webfont.eot differ diff --git a/static/fonts/fontawesome-webfont.svg b/static/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/static/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/fonts/fontawesome-webfont.ttf b/static/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/static/fonts/fontawesome-webfont.ttf differ diff --git a/static/fonts/fontawesome-webfont.woff b/static/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/static/fonts/fontawesome-webfont.woff differ diff --git a/static/fonts/fontawesome-webfont.woff2 b/static/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/static/fonts/fontawesome-webfont.woff2 differ diff --git a/static/js/chart.js b/static/js/chart.js new file mode 100644 index 0000000..008464f --- /dev/null +++ b/static/js/chart.js @@ -0,0 +1,14 @@ +/*! + * Chart.js v4.5.1 + * https://www.chartjs.org + * (c) 2025 Chart.js Contributors + * Released under the MIT License + */ +!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).Chart=e()}(this,(function(){"use strict";var t=Object.freeze({__proto__:null,get Colors(){return Jo},get Decimation(){return ta},get Filler(){return ba},get Legend(){return Ma},get SubTitle(){return Pa},get Title(){return ka},get Tooltip(){return Na}});function e(){}const i=(()=>{let t=0;return()=>t++})();function s(t){return null==t}function n(t){if(Array.isArray&&Array.isArray(t))return!0;const e=Object.prototype.toString.call(t);return"[object"===e.slice(0,7)&&"Array]"===e.slice(-6)}function o(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)}function a(t){return("number"==typeof t||t instanceof Number)&&isFinite(+t)}function r(t,e){return a(t)?t:e}function l(t,e){return void 0===t?e:t}const h=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100:+t/e,c=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100*e:+t;function d(t,e,i){if(t&&"function"==typeof t.call)return t.apply(i,e)}function u(t,e,i,s){let a,r,l;if(n(t))if(r=t.length,s)for(a=r-1;a>=0;a--)e.call(i,t[a],a);else for(a=0;at,x:t=>t.x,y:t=>t.y};function v(t){const e=t.split("."),i=[];let s="";for(const t of e)s+=t,s.endsWith("\\")?s=s.slice(0,-1)+".":(i.push(s),s="");return i}function M(t,e){const i=y[e]||(y[e]=function(t){const e=v(t);return t=>{for(const i of e){if(""===i)break;t=t&&t[i]}return t}}(e));return i(t)}function w(t){return t.charAt(0).toUpperCase()+t.slice(1)}const k=t=>void 0!==t,S=t=>"function"==typeof t,P=(t,e)=>{if(t.size!==e.size)return!1;for(const i of t)if(!e.has(i))return!1;return!0};function D(t){return"mouseup"===t.type||"click"===t.type||"contextmenu"===t.type}const C=Math.PI,O=2*C,A=O+C,T=Number.POSITIVE_INFINITY,L=C/180,E=C/2,R=C/4,I=2*C/3,z=Math.log10,F=Math.sign;function V(t,e,i){return Math.abs(t-e)t-e)).pop(),e}function N(t){return!function(t){return"symbol"==typeof t||"object"==typeof t&&null!==t&&!(Symbol.toPrimitive in t||"toString"in t||"valueOf"in t)}(t)&&!isNaN(parseFloat(t))&&isFinite(t)}function H(t,e){const i=Math.round(t);return i-e<=t&&i+e>=t}function j(t,e,i){let s,n,o;for(s=0,n=t.length;sl&&h=Math.min(e,i)-s&&t<=Math.max(e,i)+s}function et(t,e,i){i=i||(i=>t[i]1;)s=o+n>>1,i(s)?o=s:n=s;return{lo:o,hi:n}}const it=(t,e,i,s)=>et(t,i,s?s=>{const n=t[s][e];return nt[s][e]et(t,i,(s=>t[s][e]>=i));function nt(t,e,i){let s=0,n=t.length;for(;ss&&t[n-1]>i;)n--;return s>0||n{const i="_onData"+w(e),s=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value(...e){const n=s.apply(this,e);return t._chartjs.listeners.forEach((t=>{"function"==typeof t[i]&&t[i](...e)})),n}})})))}function rt(t,e){const i=t._chartjs;if(!i)return;const s=i.listeners,n=s.indexOf(e);-1!==n&&s.splice(n,1),s.length>0||(ot.forEach((e=>{delete t[e]})),delete t._chartjs)}function lt(t){const e=new Set(t);return e.size===t.length?t:Array.from(e)}const ht="undefined"==typeof window?function(t){return t()}:window.requestAnimationFrame;function ct(t,e){let i=[],s=!1;return function(...n){i=n,s||(s=!0,ht.call(window,(()=>{s=!1,t.apply(e,i)})))}}function dt(t,e){let i;return function(...s){return e?(clearTimeout(i),i=setTimeout(t,e,s)):t.apply(this,s),e}}const ut=t=>"start"===t?"left":"end"===t?"right":"center",ft=(t,e,i)=>"start"===t?e:"end"===t?i:(e+i)/2,gt=(t,e,i,s)=>t===(s?"left":"right")?i:"center"===t?(e+i)/2:e;function pt(t,e,i){const n=e.length;let o=0,a=n;if(t._sorted){const{iScale:r,vScale:l,_parsed:h}=t,c=t.dataset&&t.dataset.options?t.dataset.options.spanGaps:null,d=r.axis,{min:u,max:f,minDefined:g,maxDefined:p}=r.getUserBounds();if(g){if(o=Math.min(it(h,d,u).lo,i?n:it(e,d,r.getPixelForValue(u)).lo),c){const t=h.slice(0,o+1).reverse().findIndex((t=>!s(t[l.axis])));o-=Math.max(0,t)}o=Z(o,0,n-1)}if(p){let t=Math.max(it(h,r.axis,f,!0).hi+1,i?0:it(e,d,r.getPixelForValue(f),!0).hi+1);if(c){const e=h.slice(t-1).findIndex((t=>!s(t[l.axis])));t+=Math.max(0,e)}a=Z(t,o,n)-o}else a=n-o}return{start:o,count:a}}function mt(t){const{xScale:e,yScale:i,_scaleRanges:s}=t,n={xmin:e.min,xmax:e.max,ymin:i.min,ymax:i.max};if(!s)return t._scaleRanges=n,!0;const o=s.xmin!==e.min||s.xmax!==e.max||s.ymin!==i.min||s.ymax!==i.max;return Object.assign(s,n),o}class xt{constructor(){this._request=null,this._charts=new Map,this._running=!1,this._lastDate=void 0}_notify(t,e,i,s){const n=e.listeners[s],o=e.duration;n.forEach((s=>s({chart:t,initial:e.initial,numSteps:o,currentStep:Math.min(i-e.start,o)})))}_refresh(){this._request||(this._running=!0,this._request=ht.call(window,(()=>{this._update(),this._request=null,this._running&&this._refresh()})))}_update(t=Date.now()){let e=0;this._charts.forEach(((i,s)=>{if(!i.running||!i.items.length)return;const n=i.items;let o,a=n.length-1,r=!1;for(;a>=0;--a)o=n[a],o._active?(o._total>i.duration&&(i.duration=o._total),o.tick(t),r=!0):(n[a]=n[n.length-1],n.pop());r&&(s.draw(),this._notify(s,i,t,"progress")),n.length||(i.running=!1,this._notify(s,i,t,"complete"),i.initial=!1),e+=n.length})),this._lastDate=t,0===e&&(this._running=!1)}_getAnims(t){const e=this._charts;let i=e.get(t);return i||(i={running:!1,initial:!0,items:[],listeners:{complete:[],progress:[]}},e.set(t,i)),i}listen(t,e,i){this._getAnims(t).listeners[e].push(i)}add(t,e){e&&e.length&&this._getAnims(t).items.push(...e)}has(t){return this._getAnims(t).items.length>0}start(t){const e=this._charts.get(t);e&&(e.running=!0,e.start=Date.now(),e.duration=e.items.reduce(((t,e)=>Math.max(t,e._duration)),0),this._refresh())}running(t){if(!this._running)return!1;const e=this._charts.get(t);return!!(e&&e.running&&e.items.length)}stop(t){const e=this._charts.get(t);if(!e||!e.items.length)return;const i=e.items;let s=i.length-1;for(;s>=0;--s)i[s].cancel();e.items=[],this._notify(t,e,Date.now(),"complete")}remove(t){return this._charts.delete(t)}}var bt=new xt; +/*! + * @kurkle/color v0.3.2 + * https://github.com/kurkle/color#readme + * (c) 2023 Jukka Kurkela + * Released under the MIT License + */function _t(t){return t+.5|0}const yt=(t,e,i)=>Math.max(Math.min(t,i),e);function vt(t){return yt(_t(2.55*t),0,255)}function Mt(t){return yt(_t(255*t),0,255)}function wt(t){return yt(_t(t/2.55)/100,0,1)}function kt(t){return yt(_t(100*t),0,100)}const St={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,A:10,B:11,C:12,D:13,E:14,F:15,a:10,b:11,c:12,d:13,e:14,f:15},Pt=[..."0123456789ABCDEF"],Dt=t=>Pt[15&t],Ct=t=>Pt[(240&t)>>4]+Pt[15&t],Ot=t=>(240&t)>>4==(15&t);function At(t){var e=(t=>Ot(t.r)&&Ot(t.g)&&Ot(t.b)&&Ot(t.a))(t)?Dt:Ct;return t?"#"+e(t.r)+e(t.g)+e(t.b)+((t,e)=>t<255?e(t):"")(t.a,e):void 0}const Tt=/^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;function Lt(t,e,i){const s=e*Math.min(i,1-i),n=(e,n=(e+t/30)%12)=>i-s*Math.max(Math.min(n-3,9-n,1),-1);return[n(0),n(8),n(4)]}function Et(t,e,i){const s=(s,n=(s+t/60)%6)=>i-i*e*Math.max(Math.min(n,4-n,1),0);return[s(5),s(3),s(1)]}function Rt(t,e,i){const s=Lt(t,1,.5);let n;for(e+i>1&&(n=1/(e+i),e*=n,i*=n),n=0;n<3;n++)s[n]*=1-e-i,s[n]+=e;return s}function It(t){const e=t.r/255,i=t.g/255,s=t.b/255,n=Math.max(e,i,s),o=Math.min(e,i,s),a=(n+o)/2;let r,l,h;return n!==o&&(h=n-o,l=a>.5?h/(2-n-o):h/(n+o),r=function(t,e,i,s,n){return t===n?(e-i)/s+(e>16&255,o>>8&255,255&o]}return t}(),Ht.transparent=[0,0,0,0]);const e=Ht[t.toLowerCase()];return e&&{r:e[0],g:e[1],b:e[2],a:4===e.length?e[3]:255}}const $t=/^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/;const Yt=t=>t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055,Ut=t=>t<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4);function Xt(t,e,i){if(t){let s=It(t);s[e]=Math.max(0,Math.min(s[e]+s[e]*i,0===e?360:1)),s=Ft(s),t.r=s[0],t.g=s[1],t.b=s[2]}}function qt(t,e){return t?Object.assign(e||{},t):t}function Kt(t){var e={r:0,g:0,b:0,a:255};return Array.isArray(t)?t.length>=3&&(e={r:t[0],g:t[1],b:t[2],a:255},t.length>3&&(e.a=Mt(t[3]))):(e=qt(t,{r:0,g:0,b:0,a:1})).a=Mt(e.a),e}function Gt(t){return"r"===t.charAt(0)?function(t){const e=$t.exec(t);let i,s,n,o=255;if(e){if(e[7]!==i){const t=+e[7];o=e[8]?vt(t):yt(255*t,0,255)}return i=+e[1],s=+e[3],n=+e[5],i=255&(e[2]?vt(i):yt(i,0,255)),s=255&(e[4]?vt(s):yt(s,0,255)),n=255&(e[6]?vt(n):yt(n,0,255)),{r:i,g:s,b:n,a:o}}}(t):Bt(t)}class Jt{constructor(t){if(t instanceof Jt)return t;const e=typeof t;let i;var s,n,o;"object"===e?i=Kt(t):"string"===e&&(o=(s=t).length,"#"===s[0]&&(4===o||5===o?n={r:255&17*St[s[1]],g:255&17*St[s[2]],b:255&17*St[s[3]],a:5===o?17*St[s[4]]:255}:7!==o&&9!==o||(n={r:St[s[1]]<<4|St[s[2]],g:St[s[3]]<<4|St[s[4]],b:St[s[5]]<<4|St[s[6]],a:9===o?St[s[7]]<<4|St[s[8]]:255})),i=n||jt(t)||Gt(t)),this._rgb=i,this._valid=!!i}get valid(){return this._valid}get rgb(){var t=qt(this._rgb);return t&&(t.a=wt(t.a)),t}set rgb(t){this._rgb=Kt(t)}rgbString(){return this._valid?(t=this._rgb)&&(t.a<255?`rgba(${t.r}, ${t.g}, ${t.b}, ${wt(t.a)})`:`rgb(${t.r}, ${t.g}, ${t.b})`):void 0;var t}hexString(){return this._valid?At(this._rgb):void 0}hslString(){return this._valid?function(t){if(!t)return;const e=It(t),i=e[0],s=kt(e[1]),n=kt(e[2]);return t.a<255?`hsla(${i}, ${s}%, ${n}%, ${wt(t.a)})`:`hsl(${i}, ${s}%, ${n}%)`}(this._rgb):void 0}mix(t,e){if(t){const i=this.rgb,s=t.rgb;let n;const o=e===n?.5:e,a=2*o-1,r=i.a-s.a,l=((a*r==-1?a:(a+r)/(1+a*r))+1)/2;n=1-l,i.r=255&l*i.r+n*s.r+.5,i.g=255&l*i.g+n*s.g+.5,i.b=255&l*i.b+n*s.b+.5,i.a=o*i.a+(1-o)*s.a,this.rgb=i}return this}interpolate(t,e){return t&&(this._rgb=function(t,e,i){const s=Ut(wt(t.r)),n=Ut(wt(t.g)),o=Ut(wt(t.b));return{r:Mt(Yt(s+i*(Ut(wt(e.r))-s))),g:Mt(Yt(n+i*(Ut(wt(e.g))-n))),b:Mt(Yt(o+i*(Ut(wt(e.b))-o))),a:t.a+i*(e.a-t.a)}}(this._rgb,t._rgb,e)),this}clone(){return new Jt(this.rgb)}alpha(t){return this._rgb.a=Mt(t),this}clearer(t){return this._rgb.a*=1-t,this}greyscale(){const t=this._rgb,e=_t(.3*t.r+.59*t.g+.11*t.b);return t.r=t.g=t.b=e,this}opaquer(t){return this._rgb.a*=1+t,this}negate(){const t=this._rgb;return t.r=255-t.r,t.g=255-t.g,t.b=255-t.b,this}lighten(t){return Xt(this._rgb,2,t),this}darken(t){return Xt(this._rgb,2,-t),this}saturate(t){return Xt(this._rgb,1,t),this}desaturate(t){return Xt(this._rgb,1,-t),this}rotate(t){return function(t,e){var i=It(t);i[0]=Vt(i[0]+e),i=Ft(i),t.r=i[0],t.g=i[1],t.b=i[2]}(this._rgb,t),this}}function Zt(t){if(t&&"object"==typeof t){const e=t.toString();return"[object CanvasPattern]"===e||"[object CanvasGradient]"===e}return!1}function Qt(t){return Zt(t)?t:new Jt(t)}function te(t){return Zt(t)?t:new Jt(t).saturate(.5).darken(.1).hexString()}const ee=["x","y","borderWidth","radius","tension"],ie=["color","borderColor","backgroundColor"];const se=new Map;function ne(t,e,i){return function(t,e){e=e||{};const i=t+JSON.stringify(e);let s=se.get(i);return s||(s=new Intl.NumberFormat(t,e),se.set(i,s)),s}(e,i).format(t)}const oe={values:t=>n(t)?t:""+t,numeric(t,e,i){if(0===t)return"0";const s=this.chart.options.locale;let n,o=t;if(i.length>1){const e=Math.max(Math.abs(i[0].value),Math.abs(i[i.length-1].value));(e<1e-4||e>1e15)&&(n="scientific"),o=function(t,e){let i=e.length>3?e[2].value-e[1].value:e[1].value-e[0].value;Math.abs(i)>=1&&t!==Math.floor(t)&&(i=t-Math.floor(t));return i}(t,i)}const a=z(Math.abs(o)),r=isNaN(a)?1:Math.max(Math.min(-1*Math.floor(a),20),0),l={notation:n,minimumFractionDigits:r,maximumFractionDigits:r};return Object.assign(l,this.options.ticks.format),ne(t,s,l)},logarithmic(t,e,i){if(0===t)return"0";const s=i[e].significand||t/Math.pow(10,Math.floor(z(t)));return[1,2,3,5,10,15].includes(s)||e>.8*i.length?oe.numeric.call(this,t,e,i):""}};var ae={formatters:oe};const re=Object.create(null),le=Object.create(null);function he(t,e){if(!e)return t;const i=e.split(".");for(let e=0,s=i.length;et.chart.platform.getDevicePixelRatio(),this.elements={},this.events=["mousemove","mouseout","click","touchstart","touchmove"],this.font={family:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",size:12,style:"normal",lineHeight:1.2,weight:null},this.hover={},this.hoverBackgroundColor=(t,e)=>te(e.backgroundColor),this.hoverBorderColor=(t,e)=>te(e.borderColor),this.hoverColor=(t,e)=>te(e.color),this.indexAxis="x",this.interaction={mode:"nearest",intersect:!0,includeInvisible:!1},this.maintainAspectRatio=!0,this.onHover=null,this.onClick=null,this.parsing=!0,this.plugins={},this.responsive=!0,this.scale=void 0,this.scales={},this.showLine=!0,this.drawActiveElementsOnTop=!0,this.describe(t),this.apply(e)}set(t,e){return ce(this,t,e)}get(t){return he(this,t)}describe(t,e){return ce(le,t,e)}override(t,e){return ce(re,t,e)}route(t,e,i,s){const n=he(this,t),a=he(this,i),r="_"+e;Object.defineProperties(n,{[r]:{value:n[e],writable:!0},[e]:{enumerable:!0,get(){const t=this[r],e=a[s];return o(t)?Object.assign({},e,t):l(t,e)},set(t){this[r]=t}}})}apply(t){t.forEach((t=>t(this)))}}var ue=new de({_scriptable:t=>!t.startsWith("on"),_indexable:t=>"events"!==t,hover:{_fallback:"interaction"},interaction:{_scriptable:!1,_indexable:!1}},[function(t){t.set("animation",{delay:void 0,duration:1e3,easing:"easeOutQuart",fn:void 0,from:void 0,loop:void 0,to:void 0,type:void 0}),t.describe("animation",{_fallback:!1,_indexable:!1,_scriptable:t=>"onProgress"!==t&&"onComplete"!==t&&"fn"!==t}),t.set("animations",{colors:{type:"color",properties:ie},numbers:{type:"number",properties:ee}}),t.describe("animations",{_fallback:"animation"}),t.set("transitions",{active:{animation:{duration:400}},resize:{animation:{duration:0}},show:{animations:{colors:{from:"transparent"},visible:{type:"boolean",duration:0}}},hide:{animations:{colors:{to:"transparent"},visible:{type:"boolean",easing:"linear",fn:t=>0|t}}}})},function(t){t.set("layout",{autoPadding:!0,padding:{top:0,right:0,bottom:0,left:0}})},function(t){t.set("scale",{display:!0,offset:!1,reverse:!1,beginAtZero:!1,bounds:"ticks",clip:!0,grace:0,grid:{display:!0,lineWidth:1,drawOnChartArea:!0,drawTicks:!0,tickLength:8,tickWidth:(t,e)=>e.lineWidth,tickColor:(t,e)=>e.color,offset:!1},border:{display:!0,dash:[],dashOffset:0,width:1},title:{display:!1,text:"",padding:{top:4,bottom:4}},ticks:{minRotation:0,maxRotation:50,mirror:!1,textStrokeWidth:0,textStrokeColor:"",padding:3,display:!0,autoSkip:!0,autoSkipPadding:3,labelOffset:0,callback:ae.formatters.values,minor:{},major:{},align:"center",crossAlign:"near",showLabelBackdrop:!1,backdropColor:"rgba(255, 255, 255, 0.75)",backdropPadding:2}}),t.route("scale.ticks","color","","color"),t.route("scale.grid","color","","borderColor"),t.route("scale.border","color","","borderColor"),t.route("scale.title","color","","color"),t.describe("scale",{_fallback:!1,_scriptable:t=>!t.startsWith("before")&&!t.startsWith("after")&&"callback"!==t&&"parser"!==t,_indexable:t=>"borderDash"!==t&&"tickBorderDash"!==t&&"dash"!==t}),t.describe("scales",{_fallback:"scale"}),t.describe("scale.ticks",{_scriptable:t=>"backdropPadding"!==t&&"callback"!==t,_indexable:t=>"backdropPadding"!==t})}]);function fe(){return"undefined"!=typeof window&&"undefined"!=typeof document}function ge(t){let e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e}function pe(t,e,i){let s;return"string"==typeof t?(s=parseInt(t,10),-1!==t.indexOf("%")&&(s=s/100*e.parentNode[i])):s=t,s}const me=t=>t.ownerDocument.defaultView.getComputedStyle(t,null);function xe(t,e){return me(t).getPropertyValue(e)}const be=["top","right","bottom","left"];function _e(t,e,i){const s={};i=i?"-"+i:"";for(let n=0;n<4;n++){const o=be[n];s[o]=parseFloat(t[e+"-"+o+i])||0}return s.width=s.left+s.right,s.height=s.top+s.bottom,s}const ye=(t,e,i)=>(t>0||e>0)&&(!i||!i.shadowRoot);function ve(t,e){if("native"in t)return t;const{canvas:i,currentDevicePixelRatio:s}=e,n=me(i),o="border-box"===n.boxSizing,a=_e(n,"padding"),r=_e(n,"border","width"),{x:l,y:h,box:c}=function(t,e){const i=t.touches,s=i&&i.length?i[0]:t,{offsetX:n,offsetY:o}=s;let a,r,l=!1;if(ye(n,o,t.target))a=n,r=o;else{const t=e.getBoundingClientRect();a=s.clientX-t.left,r=s.clientY-t.top,l=!0}return{x:a,y:r,box:l}}(t,i),d=a.left+(c&&r.left),u=a.top+(c&&r.top);let{width:f,height:g}=e;return o&&(f-=a.width+r.width,g-=a.height+r.height),{x:Math.round((l-d)/f*i.width/s),y:Math.round((h-u)/g*i.height/s)}}const Me=t=>Math.round(10*t)/10;function we(t,e,i,s){const n=me(t),o=_e(n,"margin"),a=pe(n.maxWidth,t,"clientWidth")||T,r=pe(n.maxHeight,t,"clientHeight")||T,l=function(t,e,i){let s,n;if(void 0===e||void 0===i){const o=t&&ge(t);if(o){const t=o.getBoundingClientRect(),a=me(o),r=_e(a,"border","width"),l=_e(a,"padding");e=t.width-l.width-r.width,i=t.height-l.height-r.height,s=pe(a.maxWidth,o,"clientWidth"),n=pe(a.maxHeight,o,"clientHeight")}else e=t.clientWidth,i=t.clientHeight}return{width:e,height:i,maxWidth:s||T,maxHeight:n||T}}(t,e,i);let{width:h,height:c}=l;if("content-box"===n.boxSizing){const t=_e(n,"border","width"),e=_e(n,"padding");h-=e.width+t.width,c-=e.height+t.height}h=Math.max(0,h-o.width),c=Math.max(0,s?h/s:c-o.height),h=Me(Math.min(h,a,l.maxWidth)),c=Me(Math.min(c,r,l.maxHeight)),h&&!c&&(c=Me(h/2));return(void 0!==e||void 0!==i)&&s&&l.height&&c>l.height&&(c=l.height,h=Me(Math.floor(c*s))),{width:h,height:c}}function ke(t,e,i){const s=e||1,n=Me(t.height*s),o=Me(t.width*s);t.height=Me(t.height),t.width=Me(t.width);const a=t.canvas;return a.style&&(i||!a.style.height&&!a.style.width)&&(a.style.height=`${t.height}px`,a.style.width=`${t.width}px`),(t.currentDevicePixelRatio!==s||a.height!==n||a.width!==o)&&(t.currentDevicePixelRatio=s,a.height=n,a.width=o,t.ctx.setTransform(s,0,0,s,0,0),!0)}const Se=function(){let t=!1;try{const e={get passive(){return t=!0,!1}};fe()&&(window.addEventListener("test",null,e),window.removeEventListener("test",null,e))}catch(t){}return t}();function Pe(t,e){const i=xe(t,e),s=i&&i.match(/^(\d+)(\.\d+)?px$/);return s?+s[1]:void 0}function De(t){return!t||s(t.size)||s(t.family)?null:(t.style?t.style+" ":"")+(t.weight?t.weight+" ":"")+t.size+"px "+t.family}function Ce(t,e,i,s,n){let o=e[n];return o||(o=e[n]=t.measureText(n).width,i.push(n)),o>s&&(s=o),s}function Oe(t,e,i,s){let o=(s=s||{}).data=s.data||{},a=s.garbageCollect=s.garbageCollect||[];s.font!==e&&(o=s.data={},a=s.garbageCollect=[],s.font=e),t.save(),t.font=e;let r=0;const l=i.length;let h,c,d,u,f;for(h=0;hi.length){for(h=0;h0&&t.stroke()}}function Re(t,e,i){return i=i||.5,!e||t&&t.x>e.left-i&&t.xe.top-i&&t.y0&&""!==r.strokeColor;let c,d;for(t.save(),t.font=a.string,function(t,e){e.translation&&t.translate(e.translation[0],e.translation[1]),s(e.rotation)||t.rotate(e.rotation),e.color&&(t.fillStyle=e.color),e.textAlign&&(t.textAlign=e.textAlign),e.textBaseline&&(t.textBaseline=e.textBaseline)}(t,r),c=0;ct[0])){const o=i||t;void 0===s&&(s=ti("_fallback",t));const a={[Symbol.toStringTag]:"Object",_cacheable:!0,_scopes:t,_rootScopes:o,_fallback:s,_getTarget:n,override:i=>je([i,...t],e,o,s)};return new Proxy(a,{deleteProperty:(e,i)=>(delete e[i],delete e._keys,delete t[0][i],!0),get:(i,s)=>qe(i,s,(()=>function(t,e,i,s){let n;for(const o of e)if(n=ti(Ue(o,t),i),void 0!==n)return Xe(t,n)?Ze(i,s,t,n):n}(s,e,t,i))),getOwnPropertyDescriptor:(t,e)=>Reflect.getOwnPropertyDescriptor(t._scopes[0],e),getPrototypeOf:()=>Reflect.getPrototypeOf(t[0]),has:(t,e)=>ei(t).includes(e),ownKeys:t=>ei(t),set(t,e,i){const s=t._storage||(t._storage=n());return t[e]=s[e]=i,delete t._keys,!0}})}function $e(t,e,i,s){const a={_cacheable:!1,_proxy:t,_context:e,_subProxy:i,_stack:new Set,_descriptors:Ye(t,s),setContext:e=>$e(t,e,i,s),override:n=>$e(t.override(n),e,i,s)};return new Proxy(a,{deleteProperty:(e,i)=>(delete e[i],delete t[i],!0),get:(t,e,i)=>qe(t,e,(()=>function(t,e,i){const{_proxy:s,_context:a,_subProxy:r,_descriptors:l}=t;let h=s[e];S(h)&&l.isScriptable(e)&&(h=function(t,e,i,s){const{_proxy:n,_context:o,_subProxy:a,_stack:r}=i;if(r.has(t))throw new Error("Recursion detected: "+Array.from(r).join("->")+"->"+t);r.add(t);let l=e(o,a||s);r.delete(t),Xe(t,l)&&(l=Ze(n._scopes,n,t,l));return l}(e,h,t,i));n(h)&&h.length&&(h=function(t,e,i,s){const{_proxy:n,_context:a,_subProxy:r,_descriptors:l}=i;if(void 0!==a.index&&s(t))return e[a.index%e.length];if(o(e[0])){const i=e,s=n._scopes.filter((t=>t!==i));e=[];for(const o of i){const i=Ze(s,n,t,o);e.push($e(i,a,r&&r[t],l))}}return e}(e,h,t,l.isIndexable));Xe(e,h)&&(h=$e(h,a,r&&r[e],l));return h}(t,e,i))),getOwnPropertyDescriptor:(e,i)=>e._descriptors.allKeys?Reflect.has(t,i)?{enumerable:!0,configurable:!0}:void 0:Reflect.getOwnPropertyDescriptor(t,i),getPrototypeOf:()=>Reflect.getPrototypeOf(t),has:(e,i)=>Reflect.has(t,i),ownKeys:()=>Reflect.ownKeys(t),set:(e,i,s)=>(t[i]=s,delete e[i],!0)})}function Ye(t,e={scriptable:!0,indexable:!0}){const{_scriptable:i=e.scriptable,_indexable:s=e.indexable,_allKeys:n=e.allKeys}=t;return{allKeys:n,scriptable:i,indexable:s,isScriptable:S(i)?i:()=>i,isIndexable:S(s)?s:()=>s}}const Ue=(t,e)=>t?t+w(e):e,Xe=(t,e)=>o(e)&&"adapters"!==t&&(null===Object.getPrototypeOf(e)||e.constructor===Object);function qe(t,e,i){if(Object.prototype.hasOwnProperty.call(t,e)||"constructor"===e)return t[e];const s=i();return t[e]=s,s}function Ke(t,e,i){return S(t)?t(e,i):t}const Ge=(t,e)=>!0===t?e:"string"==typeof t?M(e,t):void 0;function Je(t,e,i,s,n){for(const o of e){const e=Ge(i,o);if(e){t.add(e);const o=Ke(e._fallback,i,n);if(void 0!==o&&o!==i&&o!==s)return o}else if(!1===e&&void 0!==s&&i!==s)return null}return!1}function Ze(t,e,i,s){const a=e._rootScopes,r=Ke(e._fallback,i,s),l=[...t,...a],h=new Set;h.add(s);let c=Qe(h,l,i,r||i,s);return null!==c&&((void 0===r||r===i||(c=Qe(h,l,r,c,s),null!==c))&&je(Array.from(h),[""],a,r,(()=>function(t,e,i){const s=t._getTarget();e in s||(s[e]={});const a=s[e];if(n(a)&&o(i))return i;return a||{}}(e,i,s))))}function Qe(t,e,i,s,n){for(;i;)i=Je(t,e,i,s,n);return i}function ti(t,e){for(const i of e){if(!i)continue;const e=i[t];if(void 0!==e)return e}}function ei(t){let e=t._keys;return e||(e=t._keys=function(t){const e=new Set;for(const i of t)for(const t of Object.keys(i).filter((t=>!t.startsWith("_"))))e.add(t);return Array.from(e)}(t._scopes)),e}function ii(t,e,i,s){const{iScale:n}=t,{key:o="r"}=this._parsing,a=new Array(s);let r,l,h,c;for(r=0,l=s;re"x"===t?"y":"x";function ai(t,e,i,s){const n=t.skip?e:t,o=e,a=i.skip?e:i,r=q(o,n),l=q(a,o);let h=r/(r+l),c=l/(r+l);h=isNaN(h)?0:h,c=isNaN(c)?0:c;const d=s*h,u=s*c;return{previous:{x:o.x-d*(a.x-n.x),y:o.y-d*(a.y-n.y)},next:{x:o.x+u*(a.x-n.x),y:o.y+u*(a.y-n.y)}}}function ri(t,e="x"){const i=oi(e),s=t.length,n=Array(s).fill(0),o=Array(s);let a,r,l,h=ni(t,0);for(a=0;a!t.skip))),"monotone"===e.cubicInterpolationMode)ri(t,n);else{let i=s?t[t.length-1]:t[0];for(o=0,a=t.length;o0===t||1===t,di=(t,e,i)=>-Math.pow(2,10*(t-=1))*Math.sin((t-e)*O/i),ui=(t,e,i)=>Math.pow(2,-10*t)*Math.sin((t-e)*O/i)+1,fi={linear:t=>t,easeInQuad:t=>t*t,easeOutQuad:t=>-t*(t-2),easeInOutQuad:t=>(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1),easeInCubic:t=>t*t*t,easeOutCubic:t=>(t-=1)*t*t+1,easeInOutCubic:t=>(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2),easeInQuart:t=>t*t*t*t,easeOutQuart:t=>-((t-=1)*t*t*t-1),easeInOutQuart:t=>(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2),easeInQuint:t=>t*t*t*t*t,easeOutQuint:t=>(t-=1)*t*t*t*t+1,easeInOutQuint:t=>(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2),easeInSine:t=>1-Math.cos(t*E),easeOutSine:t=>Math.sin(t*E),easeInOutSine:t=>-.5*(Math.cos(C*t)-1),easeInExpo:t=>0===t?0:Math.pow(2,10*(t-1)),easeOutExpo:t=>1===t?1:1-Math.pow(2,-10*t),easeInOutExpo:t=>ci(t)?t:t<.5?.5*Math.pow(2,10*(2*t-1)):.5*(2-Math.pow(2,-10*(2*t-1))),easeInCirc:t=>t>=1?t:-(Math.sqrt(1-t*t)-1),easeOutCirc:t=>Math.sqrt(1-(t-=1)*t),easeInOutCirc:t=>(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1),easeInElastic:t=>ci(t)?t:di(t,.075,.3),easeOutElastic:t=>ci(t)?t:ui(t,.075,.3),easeInOutElastic(t){const e=.1125;return ci(t)?t:t<.5?.5*di(2*t,e,.45):.5+.5*ui(2*t-1,e,.45)},easeInBack(t){const e=1.70158;return t*t*((e+1)*t-e)},easeOutBack(t){const e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack(t){let e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:t=>1-fi.easeOutBounce(1-t),easeOutBounce(t){const e=7.5625,i=2.75;return t<1/i?e*t*t:t<2/i?e*(t-=1.5/i)*t+.75:t<2.5/i?e*(t-=2.25/i)*t+.9375:e*(t-=2.625/i)*t+.984375},easeInOutBounce:t=>t<.5?.5*fi.easeInBounce(2*t):.5*fi.easeOutBounce(2*t-1)+.5};function gi(t,e,i,s){return{x:t.x+i*(e.x-t.x),y:t.y+i*(e.y-t.y)}}function pi(t,e,i,s){return{x:t.x+i*(e.x-t.x),y:"middle"===s?i<.5?t.y:e.y:"after"===s?i<1?t.y:e.y:i>0?e.y:t.y}}function mi(t,e,i,s){const n={x:t.cp2x,y:t.cp2y},o={x:e.cp1x,y:e.cp1y},a=gi(t,n,i),r=gi(n,o,i),l=gi(o,e,i),h=gi(a,r,i),c=gi(r,l,i);return gi(h,c,i)}const xi=/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/,bi=/^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/;function _i(t,e){const i=(""+t).match(xi);if(!i||"normal"===i[1])return 1.2*e;switch(t=+i[2],i[3]){case"px":return t;case"%":t/=100}return e*t}const yi=t=>+t||0;function vi(t,e){const i={},s=o(e),n=s?Object.keys(e):e,a=o(t)?s?i=>l(t[i],t[e[i]]):e=>t[e]:()=>t;for(const t of n)i[t]=yi(a(t));return i}function Mi(t){return vi(t,{top:"y",right:"x",bottom:"y",left:"x"})}function wi(t){return vi(t,["topLeft","topRight","bottomLeft","bottomRight"])}function ki(t){const e=Mi(t);return e.width=e.left+e.right,e.height=e.top+e.bottom,e}function Si(t,e){t=t||{},e=e||ue.font;let i=l(t.size,e.size);"string"==typeof i&&(i=parseInt(i,10));let s=l(t.style,e.style);s&&!(""+s).match(bi)&&(console.warn('Invalid font style specified: "'+s+'"'),s=void 0);const n={family:l(t.family,e.family),lineHeight:_i(l(t.lineHeight,e.lineHeight),i),size:i,style:s,weight:l(t.weight,e.weight),string:""};return n.string=De(n),n}function Pi(t,e,i,s){let o,a,r,l=!0;for(o=0,a=t.length;oi&&0===t?0:t+e;return{min:a(s,-Math.abs(o)),max:a(n,o)}}function Ci(t,e){return Object.assign(Object.create(t),e)}function Oi(t,e,i){return t?function(t,e){return{x:i=>t+t+e-i,setWidth(t){e=t},textAlign:t=>"center"===t?t:"right"===t?"left":"right",xPlus:(t,e)=>t-e,leftForLtr:(t,e)=>t-e}}(e,i):{x:t=>t,setWidth(t){},textAlign:t=>t,xPlus:(t,e)=>t+e,leftForLtr:(t,e)=>t}}function Ai(t,e){let i,s;"ltr"!==e&&"rtl"!==e||(i=t.canvas.style,s=[i.getPropertyValue("direction"),i.getPropertyPriority("direction")],i.setProperty("direction",e,"important"),t.prevTextDirection=s)}function Ti(t,e){void 0!==e&&(delete t.prevTextDirection,t.canvas.style.setProperty("direction",e[0],e[1]))}function Li(t){return"angle"===t?{between:J,compare:K,normalize:G}:{between:tt,compare:(t,e)=>t-e,normalize:t=>t}}function Ei({start:t,end:e,count:i,loop:s,style:n}){return{start:t%i,end:e%i,loop:s&&(e-t+1)%i==0,style:n}}function Ri(t,e,i){if(!i)return[t];const{property:s,start:n,end:o}=i,a=e.length,{compare:r,between:l,normalize:h}=Li(s),{start:c,end:d,loop:u,style:f}=function(t,e,i){const{property:s,start:n,end:o}=i,{between:a,normalize:r}=Li(s),l=e.length;let h,c,{start:d,end:u,loop:f}=t;if(f){for(d+=l,u+=l,h=0,c=l;hb||l(n,x,p)&&0!==r(n,x),v=()=>!b||0===r(o,p)||l(o,x,p);for(let t=c,i=c;t<=d;++t)m=e[t%a],m.skip||(p=h(m[s]),p!==x&&(b=l(p,n,o),null===_&&y()&&(_=0===r(p,n)?t:i),null!==_&&v()&&(g.push(Ei({start:_,end:t,loop:u,count:a,style:f})),_=null),i=t,x=p));return null!==_&&g.push(Ei({start:_,end:d,loop:u,count:a,style:f})),g}function Ii(t,e){const i=[],s=t.segments;for(let n=0;nn&&t[o%e].skip;)o--;return o%=e,{start:n,end:o}}(i,n,o,s);if(!0===s)return Fi(t,[{start:a,end:r,loop:o}],i,e);return Fi(t,function(t,e,i,s){const n=t.length,o=[];let a,r=e,l=t[e];for(a=e+1;a<=i;++a){const i=t[a%n];i.skip||i.stop?l.skip||(s=!1,o.push({start:e%n,end:(a-1)%n,loop:s}),e=r=i.stop?a:null):(r=a,l.skip&&(e=a)),l=i}return null!==r&&o.push({start:e%n,end:r%n,loop:s}),o}(i,a,r!s(t[e.axis])));n.lo-=Math.max(0,a);const r=i.slice(n.hi).findIndex((t=>!s(t[e.axis])));n.hi+=Math.max(0,r)}return n}if(o._sharedOptions){const t=a[0],s="function"==typeof t.getRange&&t.getRange(e);if(s){const t=r(a,e,i-s),n=r(a,e,i+s);return{lo:t.lo,hi:n.hi}}}}return{lo:0,hi:a.length-1}}function $i(t,e,i,s,n){const o=t.getSortedVisibleDatasetMetas(),a=i[e];for(let t=0,i=o.length;t{t[a]&&t[a](e[i],n)&&(o.push({element:t,datasetIndex:s,index:l}),r=r||t.inRange(e.x,e.y,n))})),s&&!r?[]:o}var Ki={evaluateInteractionItems:$i,modes:{index(t,e,i,s){const n=ve(e,t),o=i.axis||"x",a=i.includeInvisible||!1,r=i.intersect?Yi(t,n,o,s,a):Xi(t,n,o,!1,s,a),l=[];return r.length?(t.getSortedVisibleDatasetMetas().forEach((t=>{const e=r[0].index,i=t.data[e];i&&!i.skip&&l.push({element:i,datasetIndex:t.index,index:e})})),l):[]},dataset(t,e,i,s){const n=ve(e,t),o=i.axis||"xy",a=i.includeInvisible||!1;let r=i.intersect?Yi(t,n,o,s,a):Xi(t,n,o,!1,s,a);if(r.length>0){const e=r[0].datasetIndex,i=t.getDatasetMeta(e).data;r=[];for(let t=0;tYi(t,ve(e,t),i.axis||"xy",s,i.includeInvisible||!1),nearest(t,e,i,s){const n=ve(e,t),o=i.axis||"xy",a=i.includeInvisible||!1;return Xi(t,n,o,i.intersect,s,a)},x:(t,e,i,s)=>qi(t,ve(e,t),"x",i.intersect,s),y:(t,e,i,s)=>qi(t,ve(e,t),"y",i.intersect,s)}};const Gi=["left","top","right","bottom"];function Ji(t,e){return t.filter((t=>t.pos===e))}function Zi(t,e){return t.filter((t=>-1===Gi.indexOf(t.pos)&&t.box.axis===e))}function Qi(t,e){return t.sort(((t,i)=>{const s=e?i:t,n=e?t:i;return s.weight===n.weight?s.index-n.index:s.weight-n.weight}))}function ts(t,e){const i=function(t){const e={};for(const i of t){const{stack:t,pos:s,stackWeight:n}=i;if(!t||!Gi.includes(s))continue;const o=e[t]||(e[t]={count:0,placed:0,weight:0,size:0});o.count++,o.weight+=n}return e}(t),{vBoxMaxWidth:s,hBoxMaxHeight:n}=e;let o,a,r;for(o=0,a=t.length;o{s[t]=Math.max(e[t],i[t])})),s}return s(t?["left","right"]:["top","bottom"])}function os(t,e,i,s){const n=[];let o,a,r,l,h,c;for(o=0,a=t.length,h=0;ot.box.fullSize)),!0),s=Qi(Ji(e,"left"),!0),n=Qi(Ji(e,"right")),o=Qi(Ji(e,"top"),!0),a=Qi(Ji(e,"bottom")),r=Zi(e,"x"),l=Zi(e,"y");return{fullSize:i,leftAndTop:s.concat(o),rightAndBottom:n.concat(l).concat(a).concat(r),chartArea:Ji(e,"chartArea"),vertical:s.concat(n).concat(l),horizontal:o.concat(a).concat(r)}}(t.boxes),l=r.vertical,h=r.horizontal;u(t.boxes,(t=>{"function"==typeof t.beforeLayout&&t.beforeLayout()}));const c=l.reduce(((t,e)=>e.box.options&&!1===e.box.options.display?t:t+1),0)||1,d=Object.freeze({outerWidth:e,outerHeight:i,padding:n,availableWidth:o,availableHeight:a,vBoxMaxWidth:o/2/c,hBoxMaxHeight:a/2}),f=Object.assign({},n);is(f,ki(s));const g=Object.assign({maxPadding:f,w:o,h:a,x:n.left,y:n.top},n),p=ts(l.concat(h),d);os(r.fullSize,g,d,p),os(l,g,d,p),os(h,g,d,p)&&os(l,g,d,p),function(t){const e=t.maxPadding;function i(i){const s=Math.max(e[i]-t[i],0);return t[i]+=s,s}t.y+=i("top"),t.x+=i("left"),i("right"),i("bottom")}(g),rs(r.leftAndTop,g,d,p),g.x+=g.w,g.y+=g.h,rs(r.rightAndBottom,g,d,p),t.chartArea={left:g.left,top:g.top,right:g.left+g.w,bottom:g.top+g.h,height:g.h,width:g.w},u(r.chartArea,(e=>{const i=e.box;Object.assign(i,t.chartArea),i.update(g.w,g.h,{left:0,top:0,right:0,bottom:0})}))}};class hs{acquireContext(t,e){}releaseContext(t){return!1}addEventListener(t,e,i){}removeEventListener(t,e,i){}getDevicePixelRatio(){return 1}getMaximumSize(t,e,i,s){return e=Math.max(0,e||t.width),i=i||t.height,{width:e,height:Math.max(0,s?Math.floor(e/s):i)}}isAttached(t){return!0}updateConfig(t){}}class cs extends hs{acquireContext(t){return t&&t.getContext&&t.getContext("2d")||null}updateConfig(t){t.options.animation=!1}}const ds="$chartjs",us={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"},fs=t=>null===t||""===t;const gs=!!Se&&{passive:!0};function ps(t,e,i){t&&t.canvas&&t.canvas.removeEventListener(e,i,gs)}function ms(t,e){for(const i of t)if(i===e||i.contains(e))return!0}function xs(t,e,i){const s=t.canvas,n=new MutationObserver((t=>{let e=!1;for(const i of t)e=e||ms(i.addedNodes,s),e=e&&!ms(i.removedNodes,s);e&&i()}));return n.observe(document,{childList:!0,subtree:!0}),n}function bs(t,e,i){const s=t.canvas,n=new MutationObserver((t=>{let e=!1;for(const i of t)e=e||ms(i.removedNodes,s),e=e&&!ms(i.addedNodes,s);e&&i()}));return n.observe(document,{childList:!0,subtree:!0}),n}const _s=new Map;let ys=0;function vs(){const t=window.devicePixelRatio;t!==ys&&(ys=t,_s.forEach(((e,i)=>{i.currentDevicePixelRatio!==t&&e()})))}function Ms(t,e,i){const s=t.canvas,n=s&&ge(s);if(!n)return;const o=ct(((t,e)=>{const s=n.clientWidth;i(t,e),s{const e=t[0],i=e.contentRect.width,s=e.contentRect.height;0===i&&0===s||o(i,s)}));return a.observe(n),function(t,e){_s.size||window.addEventListener("resize",vs),_s.set(t,e)}(t,o),a}function ws(t,e,i){i&&i.disconnect(),"resize"===e&&function(t){_s.delete(t),_s.size||window.removeEventListener("resize",vs)}(t)}function ks(t,e,i){const s=t.canvas,n=ct((e=>{null!==t.ctx&&i(function(t,e){const i=us[t.type]||t.type,{x:s,y:n}=ve(t,e);return{type:i,chart:e,native:t,x:void 0!==s?s:null,y:void 0!==n?n:null}}(e,t))}),t);return function(t,e,i){t&&t.addEventListener(e,i,gs)}(s,e,n),n}class Ss extends hs{acquireContext(t,e){const i=t&&t.getContext&&t.getContext("2d");return i&&i.canvas===t?(function(t,e){const i=t.style,s=t.getAttribute("height"),n=t.getAttribute("width");if(t[ds]={initial:{height:s,width:n,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||"block",i.boxSizing=i.boxSizing||"border-box",fs(n)){const e=Pe(t,"width");void 0!==e&&(t.width=e)}if(fs(s))if(""===t.style.height)t.height=t.width/(e||2);else{const e=Pe(t,"height");void 0!==e&&(t.height=e)}}(t,e),i):null}releaseContext(t){const e=t.canvas;if(!e[ds])return!1;const i=e[ds].initial;["height","width"].forEach((t=>{const n=i[t];s(n)?e.removeAttribute(t):e.setAttribute(t,n)}));const n=i.style||{};return Object.keys(n).forEach((t=>{e.style[t]=n[t]})),e.width=e.width,delete e[ds],!0}addEventListener(t,e,i){this.removeEventListener(t,e);const s=t.$proxies||(t.$proxies={}),n={attach:xs,detach:bs,resize:Ms}[e]||ks;s[e]=n(t,e,i)}removeEventListener(t,e){const i=t.$proxies||(t.$proxies={}),s=i[e];if(!s)return;({attach:ws,detach:ws,resize:ws}[e]||ps)(t,e,s),i[e]=void 0}getDevicePixelRatio(){return window.devicePixelRatio}getMaximumSize(t,e,i,s){return we(t,e,i,s)}isAttached(t){const e=t&&ge(t);return!(!e||!e.isConnected)}}function Ps(t){return!fe()||"undefined"!=typeof OffscreenCanvas&&t instanceof OffscreenCanvas?cs:Ss}var Ds=Object.freeze({__proto__:null,BasePlatform:hs,BasicPlatform:cs,DomPlatform:Ss,_detectPlatform:Ps});const Cs="transparent",Os={boolean:(t,e,i)=>i>.5?e:t,color(t,e,i){const s=Qt(t||Cs),n=s.valid&&Qt(e||Cs);return n&&n.valid?n.mix(s,i).hexString():e},number:(t,e,i)=>t+(e-t)*i};class As{constructor(t,e,i,s){const n=e[i];s=Pi([t.to,s,n,t.from]);const o=Pi([t.from,n,s]);this._active=!0,this._fn=t.fn||Os[t.type||typeof o],this._easing=fi[t.easing]||fi.linear,this._start=Math.floor(Date.now()+(t.delay||0)),this._duration=this._total=Math.floor(t.duration),this._loop=!!t.loop,this._target=e,this._prop=i,this._from=o,this._to=s,this._promises=void 0}active(){return this._active}update(t,e,i){if(this._active){this._notify(!1);const s=this._target[this._prop],n=i-this._start,o=this._duration-n;this._start=i,this._duration=Math.floor(Math.max(o,t.duration)),this._total+=n,this._loop=!!t.loop,this._to=Pi([t.to,e,s,t.from]),this._from=Pi([t.from,s,e])}}cancel(){this._active&&(this.tick(Date.now()),this._active=!1,this._notify(!1))}tick(t){const e=t-this._start,i=this._duration,s=this._prop,n=this._from,o=this._loop,a=this._to;let r;if(this._active=n!==a&&(o||e1?2-r:r,r=this._easing(Math.min(1,Math.max(0,r))),this._target[s]=this._fn(n,a,r))}wait(){const t=this._promises||(this._promises=[]);return new Promise(((e,i)=>{t.push({res:e,rej:i})}))}_notify(t){const e=t?"res":"rej",i=this._promises||[];for(let t=0;t{const a=t[s];if(!o(a))return;const r={};for(const t of e)r[t]=a[t];(n(a.properties)&&a.properties||[s]).forEach((t=>{t!==s&&i.has(t)||i.set(t,r)}))}))}_animateOptions(t,e){const i=e.options,s=function(t,e){if(!e)return;let i=t.options;if(!i)return void(t.options=e);i.$shared&&(t.options=i=Object.assign({},i,{$shared:!1,$animations:{}}));return i}(t,i);if(!s)return[];const n=this._createAnimations(s,i);return i.$shared&&function(t,e){const i=[],s=Object.keys(e);for(let e=0;e{t.options=i}),(()=>{})),n}_createAnimations(t,e){const i=this._properties,s=[],n=t.$animations||(t.$animations={}),o=Object.keys(e),a=Date.now();let r;for(r=o.length-1;r>=0;--r){const l=o[r];if("$"===l.charAt(0))continue;if("options"===l){s.push(...this._animateOptions(t,e));continue}const h=e[l];let c=n[l];const d=i.get(l);if(c){if(d&&c.active()){c.update(d,h,a);continue}c.cancel()}d&&d.duration?(n[l]=c=new As(d,t,l,h),s.push(c)):t[l]=h}return s}update(t,e){if(0===this._properties.size)return void Object.assign(t,e);const i=this._createAnimations(t,e);return i.length?(bt.add(this._chart,i),!0):void 0}}function Ls(t,e){const i=t&&t.options||{},s=i.reverse,n=void 0===i.min?e:0,o=void 0===i.max?e:0;return{start:s?o:n,end:s?n:o}}function Es(t,e){const i=[],s=t._getSortedDatasetMetas(e);let n,o;for(n=0,o=s.length;n0||!i&&e<0)return n.index}return null}function Vs(t,e){const{chart:i,_cachedMeta:s}=t,n=i._stacks||(i._stacks={}),{iScale:o,vScale:a,index:r}=s,l=o.axis,h=a.axis,c=function(t,e,i){return`${t.id}.${e.id}.${i.stack||i.type}`}(o,a,s),d=e.length;let u;for(let t=0;ti[t].axis===e)).shift()}function Ws(t,e){const i=t.controller.index,s=t.vScale&&t.vScale.axis;if(s){e=e||t._parsed;for(const t of e){const e=t._stacks;if(!e||void 0===e[s]||void 0===e[s][i])return;delete e[s][i],void 0!==e[s]._visualValues&&void 0!==e[s]._visualValues[i]&&delete e[s]._visualValues[i]}}}const Ns=t=>"reset"===t||"none"===t,Hs=(t,e)=>e?t:Object.assign({},t);class js{static defaults={};static datasetElementType=null;static dataElementType=null;constructor(t,e){this.chart=t,this._ctx=t.ctx,this.index=e,this._cachedDataOpts={},this._cachedMeta=this.getMeta(),this._type=this._cachedMeta.type,this.options=void 0,this._parsing=!1,this._data=void 0,this._objectData=void 0,this._sharedOptions=void 0,this._drawStart=void 0,this._drawCount=void 0,this.enableOptionSharing=!1,this.supportsDecimation=!1,this.$context=void 0,this._syncList=[],this.datasetElementType=new.target.datasetElementType,this.dataElementType=new.target.dataElementType,this.initialize()}initialize(){const t=this._cachedMeta;this.configure(),this.linkScales(),t._stacked=Is(t.vScale,t),this.addElements(),this.options.fill&&!this.chart.isPluginEnabled("filler")&&console.warn("Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options")}updateIndex(t){this.index!==t&&Ws(this._cachedMeta),this.index=t}linkScales(){const t=this.chart,e=this._cachedMeta,i=this.getDataset(),s=(t,e,i,s)=>"x"===t?e:"r"===t?s:i,n=e.xAxisID=l(i.xAxisID,Bs(t,"x")),o=e.yAxisID=l(i.yAxisID,Bs(t,"y")),a=e.rAxisID=l(i.rAxisID,Bs(t,"r")),r=e.indexAxis,h=e.iAxisID=s(r,n,o,a),c=e.vAxisID=s(r,o,n,a);e.xScale=this.getScaleForId(n),e.yScale=this.getScaleForId(o),e.rScale=this.getScaleForId(a),e.iScale=this.getScaleForId(h),e.vScale=this.getScaleForId(c)}getDataset(){return this.chart.data.datasets[this.index]}getMeta(){return this.chart.getDatasetMeta(this.index)}getScaleForId(t){return this.chart.scales[t]}_getOtherScale(t){const e=this._cachedMeta;return t===e.iScale?e.vScale:e.iScale}reset(){this._update("reset")}_destroy(){const t=this._cachedMeta;this._data&&rt(this._data,this),t._stacked&&Ws(t)}_dataCheck(){const t=this.getDataset(),e=t.data||(t.data=[]),i=this._data;if(o(e)){const t=this._cachedMeta;this._data=function(t,e){const{iScale:i,vScale:s}=e,n="x"===i.axis?"x":"y",o="x"===s.axis?"x":"y",a=Object.keys(t),r=new Array(a.length);let l,h,c;for(l=0,h=a.length;l0&&i._parsed[t-1];if(!1===this._parsing)i._parsed=s,i._sorted=!0,d=s;else{d=n(s[t])?this.parseArrayData(i,s,t,e):o(s[t])?this.parseObjectData(i,s,t,e):this.parsePrimitiveData(i,s,t,e);const a=()=>null===c[l]||f&&c[l]t&&!e.hidden&&e._stacked&&{keys:Es(i,!0),values:null})(e,i,this.chart),h={min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY},{min:c,max:d}=function(t){const{min:e,max:i,minDefined:s,maxDefined:n}=t.getUserBounds();return{min:s?e:Number.NEGATIVE_INFINITY,max:n?i:Number.POSITIVE_INFINITY}}(r);let u,f;function g(){f=s[u];const e=f[r.axis];return!a(f[t.axis])||c>e||d=0;--u)if(!g()){this.updateRangeFromParsed(h,t,f,l);break}return h}getAllParsedValues(t){const e=this._cachedMeta._parsed,i=[];let s,n,o;for(s=0,n=e.length;s=0&&tthis.getContext(i,s,e)),c);return f.$shared&&(f.$shared=r,n[o]=Object.freeze(Hs(f,r))),f}_resolveAnimations(t,e,i){const s=this.chart,n=this._cachedDataOpts,o=`animation-${e}`,a=n[o];if(a)return a;let r;if(!1!==s.options.animation){const s=this.chart.config,n=s.datasetAnimationScopeKeys(this._type,e),o=s.getOptionScopes(this.getDataset(),n);r=s.createResolver(o,this.getContext(t,i,e))}const l=new Ts(s,r&&r.animations);return r&&r._cacheable&&(n[o]=Object.freeze(l)),l}getSharedOptions(t){if(t.$shared)return this._sharedOptions||(this._sharedOptions=Object.assign({},t))}includeOptions(t,e){return!e||Ns(t)||this.chart._animationsDisabled}_getSharedOptions(t,e){const i=this.resolveDataElementOptions(t,e),s=this._sharedOptions,n=this.getSharedOptions(i),o=this.includeOptions(e,n)||n!==s;return this.updateSharedOptions(n,e,i),{sharedOptions:n,includeOptions:o}}updateElement(t,e,i,s){Ns(s)?Object.assign(t,i):this._resolveAnimations(e,s).update(t,i)}updateSharedOptions(t,e,i){t&&!Ns(e)&&this._resolveAnimations(void 0,e).update(t,i)}_setStyle(t,e,i,s){t.active=s;const n=this.getStyle(e,s);this._resolveAnimations(e,i,s).update(t,{options:!s&&this.getSharedOptions(n)||n})}removeHoverStyle(t,e,i){this._setStyle(t,i,"active",!1)}setHoverStyle(t,e,i){this._setStyle(t,i,"active",!0)}_removeDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!1)}_setDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!0)}_resyncElements(t){const e=this._data,i=this._cachedMeta.data;for(const[t,e,i]of this._syncList)this[t](e,i);this._syncList=[];const s=i.length,n=e.length,o=Math.min(n,s);o&&this.parse(0,o),n>s?this._insertElements(s,n-s,t):n{for(t.length+=e,a=t.length-1;a>=o;a--)t[a]=t[a-e]};for(r(n),a=t;a{s[t]=i[t]&&i[t].active()?i[t]._to:this[t]})),s}}function Ys(t,e){const i=t.options.ticks,n=function(t){const e=t.options.offset,i=t._tickSize(),s=t._length/i+(e?0:1),n=t._maxLength/i;return Math.floor(Math.min(s,n))}(t),o=Math.min(i.maxTicksLimit||n,n),a=i.major.enabled?function(t){const e=[];let i,s;for(i=0,s=t.length;io)return function(t,e,i,s){let n,o=0,a=i[0];for(s=Math.ceil(s),n=0;nn)return e}return Math.max(n,1)}(a,e,o);if(r>0){let t,i;const n=r>1?Math.round((h-l)/(r-1)):null;for(Us(e,c,d,s(n)?0:l-n,l),t=0,i=r-1;t"top"===e||"left"===e?t[e]+i:t[e]-i,qs=(t,e)=>Math.min(e||t,t);function Ks(t,e){const i=[],s=t.length/e,n=t.length;let o=0;for(;oa+r)))return h}function Js(t){return t.drawTicks?t.tickLength:0}function Zs(t,e){if(!t.display)return 0;const i=Si(t.font,e),s=ki(t.padding);return(n(t.text)?t.text.length:1)*i.lineHeight+s.height}function Qs(t,e,i){let s=ut(t);return(i&&"right"!==e||!i&&"right"===e)&&(s=(t=>"left"===t?"right":"right"===t?"left":t)(s)),s}class tn extends $s{constructor(t){super(),this.id=t.id,this.type=t.type,this.options=void 0,this.ctx=t.ctx,this.chart=t.chart,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this._margins={left:0,right:0,top:0,bottom:0},this.maxWidth=void 0,this.maxHeight=void 0,this.paddingTop=void 0,this.paddingBottom=void 0,this.paddingLeft=void 0,this.paddingRight=void 0,this.axis=void 0,this.labelRotation=void 0,this.min=void 0,this.max=void 0,this._range=void 0,this.ticks=[],this._gridLineItems=null,this._labelItems=null,this._labelSizes=null,this._length=0,this._maxLength=0,this._longestTextCache={},this._startPixel=void 0,this._endPixel=void 0,this._reversePixels=!1,this._userMax=void 0,this._userMin=void 0,this._suggestedMax=void 0,this._suggestedMin=void 0,this._ticksLength=0,this._borderValue=0,this._cache={},this._dataLimitsCached=!1,this.$context=void 0}init(t){this.options=t.setContext(this.getContext()),this.axis=t.axis,this._userMin=this.parse(t.min),this._userMax=this.parse(t.max),this._suggestedMin=this.parse(t.suggestedMin),this._suggestedMax=this.parse(t.suggestedMax)}parse(t,e){return t}getUserBounds(){let{_userMin:t,_userMax:e,_suggestedMin:i,_suggestedMax:s}=this;return t=r(t,Number.POSITIVE_INFINITY),e=r(e,Number.NEGATIVE_INFINITY),i=r(i,Number.POSITIVE_INFINITY),s=r(s,Number.NEGATIVE_INFINITY),{min:r(t,i),max:r(e,s),minDefined:a(t),maxDefined:a(e)}}getMinMax(t){let e,{min:i,max:s,minDefined:n,maxDefined:o}=this.getUserBounds();if(n&&o)return{min:i,max:s};const a=this.getMatchingVisibleMetas();for(let r=0,l=a.length;rs?s:i,s=n&&i>s?i:s,{min:r(i,r(s,i)),max:r(s,r(i,s))}}getPadding(){return{left:this.paddingLeft||0,top:this.paddingTop||0,right:this.paddingRight||0,bottom:this.paddingBottom||0}}getTicks(){return this.ticks}getLabels(){const t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels||[]}getLabelItems(t=this.chart.chartArea){return this._labelItems||(this._labelItems=this._computeLabelItems(t))}beforeLayout(){this._cache={},this._dataLimitsCached=!1}beforeUpdate(){d(this.options.beforeUpdate,[this])}update(t,e,i){const{beginAtZero:s,grace:n,ticks:o}=this.options,a=o.sampleSize;this.beforeUpdate(),this.maxWidth=t,this.maxHeight=e,this._margins=i=Object.assign({left:0,right:0,top:0,bottom:0},i),this.ticks=null,this._labelSizes=null,this._gridLineItems=null,this._labelItems=null,this.beforeSetDimensions(),this.setDimensions(),this.afterSetDimensions(),this._maxLength=this.isHorizontal()?this.width+i.left+i.right:this.height+i.top+i.bottom,this._dataLimitsCached||(this.beforeDataLimits(),this.determineDataLimits(),this.afterDataLimits(),this._range=Di(this,n,s),this._dataLimitsCached=!0),this.beforeBuildTicks(),this.ticks=this.buildTicks()||[],this.afterBuildTicks();const r=a=n||i<=1||!this.isHorizontal())return void(this.labelRotation=s);const h=this._getLabelSizes(),c=h.widest.width,d=h.highest.height,u=Z(this.chart.width-c,0,this.maxWidth);o=t.offset?this.maxWidth/i:u/(i-1),c+6>o&&(o=u/(i-(t.offset?.5:1)),a=this.maxHeight-Js(t.grid)-e.padding-Zs(t.title,this.chart.options.font),r=Math.sqrt(c*c+d*d),l=Y(Math.min(Math.asin(Z((h.highest.height+6)/o,-1,1)),Math.asin(Z(a/r,-1,1))-Math.asin(Z(d/r,-1,1)))),l=Math.max(s,Math.min(n,l))),this.labelRotation=l}afterCalculateLabelRotation(){d(this.options.afterCalculateLabelRotation,[this])}afterAutoSkip(){}beforeFit(){d(this.options.beforeFit,[this])}fit(){const t={width:0,height:0},{chart:e,options:{ticks:i,title:s,grid:n}}=this,o=this._isVisible(),a=this.isHorizontal();if(o){const o=Zs(s,e.options.font);if(a?(t.width=this.maxWidth,t.height=Js(n)+o):(t.height=this.maxHeight,t.width=Js(n)+o),i.display&&this.ticks.length){const{first:e,last:s,widest:n,highest:o}=this._getLabelSizes(),r=2*i.padding,l=$(this.labelRotation),h=Math.cos(l),c=Math.sin(l);if(a){const e=i.mirror?0:c*n.width+h*o.height;t.height=Math.min(this.maxHeight,t.height+e+r)}else{const e=i.mirror?0:h*n.width+c*o.height;t.width=Math.min(this.maxWidth,t.width+e+r)}this._calculatePadding(e,s,c,h)}}this._handleMargins(),a?(this.width=this._length=e.width-this._margins.left-this._margins.right,this.height=t.height):(this.width=t.width,this.height=this._length=e.height-this._margins.top-this._margins.bottom)}_calculatePadding(t,e,i,s){const{ticks:{align:n,padding:o},position:a}=this.options,r=0!==this.labelRotation,l="top"!==a&&"x"===this.axis;if(this.isHorizontal()){const a=this.getPixelForTick(0)-this.left,h=this.right-this.getPixelForTick(this.ticks.length-1);let c=0,d=0;r?l?(c=s*t.width,d=i*e.height):(c=i*t.height,d=s*e.width):"start"===n?d=e.width:"end"===n?c=t.width:"inner"!==n&&(c=t.width/2,d=e.width/2),this.paddingLeft=Math.max((c-a+o)*this.width/(this.width-a),0),this.paddingRight=Math.max((d-h+o)*this.width/(this.width-h),0)}else{let i=e.height/2,s=t.height/2;"start"===n?(i=0,s=t.height):"end"===n&&(i=e.height,s=0),this.paddingTop=i+o,this.paddingBottom=s+o}}_handleMargins(){this._margins&&(this._margins.left=Math.max(this.paddingLeft,this._margins.left),this._margins.top=Math.max(this.paddingTop,this._margins.top),this._margins.right=Math.max(this.paddingRight,this._margins.right),this._margins.bottom=Math.max(this.paddingBottom,this._margins.bottom))}afterFit(){d(this.options.afterFit,[this])}isHorizontal(){const{axis:t,position:e}=this.options;return"top"===e||"bottom"===e||"x"===t}isFullSize(){return this.options.fullSize}_convertTicksToLabels(t){let e,i;for(this.beforeTickToLabelConversion(),this.generateTickLabels(t),e=0,i=t.length;e{const i=t.gc,s=i.length/2;let n;if(s>e){for(n=0;n({width:r[t]||0,height:l[t]||0});return{first:P(0),last:P(e-1),widest:P(k),highest:P(S),widths:r,heights:l}}getLabelForValue(t){return t}getPixelForValue(t,e){return NaN}getValueForPixel(t){}getPixelForTick(t){const e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getPixelForDecimal(t){this._reversePixels&&(t=1-t);const e=this._startPixel+t*this._length;return Q(this._alignToPixels?Ae(this.chart,e,0):e)}getDecimalForPixel(t){const e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e}getBasePixel(){return this.getPixelForValue(this.getBaseValue())}getBaseValue(){const{min:t,max:e}=this;return t<0&&e<0?e:t>0&&e>0?t:0}getContext(t){const e=this.ticks||[];if(t>=0&&ta*s?a/i:r/s:r*s0}_computeGridLineItems(t){const e=this.axis,i=this.chart,s=this.options,{grid:n,position:a,border:r}=s,h=n.offset,c=this.isHorizontal(),d=this.ticks.length+(h?1:0),u=Js(n),f=[],g=r.setContext(this.getContext()),p=g.display?g.width:0,m=p/2,x=function(t){return Ae(i,t,p)};let b,_,y,v,M,w,k,S,P,D,C,O;if("top"===a)b=x(this.bottom),w=this.bottom-u,S=b-m,D=x(t.top)+m,O=t.bottom;else if("bottom"===a)b=x(this.top),D=t.top,O=x(t.bottom)-m,w=b+m,S=this.top+u;else if("left"===a)b=x(this.right),M=this.right-u,k=b-m,P=x(t.left)+m,C=t.right;else if("right"===a)b=x(this.left),P=t.left,C=x(t.right)-m,M=b+m,k=this.left+u;else if("x"===e){if("center"===a)b=x((t.top+t.bottom)/2+.5);else if(o(a)){const t=Object.keys(a)[0],e=a[t];b=x(this.chart.scales[t].getPixelForValue(e))}D=t.top,O=t.bottom,w=b+m,S=w+u}else if("y"===e){if("center"===a)b=x((t.left+t.right)/2);else if(o(a)){const t=Object.keys(a)[0],e=a[t];b=x(this.chart.scales[t].getPixelForValue(e))}M=b-m,k=M-u,P=t.left,C=t.right}const A=l(s.ticks.maxTicksLimit,d),T=Math.max(1,Math.ceil(d/A));for(_=0;_0&&(o-=s/2)}d={left:o,top:n,width:s+e.width,height:i+e.height,color:t.backdropColor}}x.push({label:v,font:P,textOffset:O,options:{rotation:m,color:i,strokeColor:o,strokeWidth:h,textAlign:f,textBaseline:A,translation:[M,w],backdrop:d}})}return x}_getXAxisLabelAlignment(){const{position:t,ticks:e}=this.options;if(-$(this.labelRotation))return"top"===t?"left":"right";let i="center";return"start"===e.align?i="left":"end"===e.align?i="right":"inner"===e.align&&(i="inner"),i}_getYAxisLabelAlignment(t){const{position:e,ticks:{crossAlign:i,mirror:s,padding:n}}=this.options,o=t+n,a=this._getLabelSizes().widest.width;let r,l;return"left"===e?s?(l=this.right+n,"near"===i?r="left":"center"===i?(r="center",l+=a/2):(r="right",l+=a)):(l=this.right-o,"near"===i?r="right":"center"===i?(r="center",l-=a/2):(r="left",l=this.left)):"right"===e?s?(l=this.left+n,"near"===i?r="right":"center"===i?(r="center",l-=a/2):(r="left",l-=a)):(l=this.left+o,"near"===i?r="left":"center"===i?(r="center",l+=a/2):(r="right",l=this.right)):r="right",{textAlign:r,x:l}}_computeLabelArea(){if(this.options.ticks.mirror)return;const t=this.chart,e=this.options.position;return"left"===e||"right"===e?{top:0,left:this.left,bottom:t.height,right:this.right}:"top"===e||"bottom"===e?{top:this.top,left:0,bottom:this.bottom,right:t.width}:void 0}drawBackground(){const{ctx:t,options:{backgroundColor:e},left:i,top:s,width:n,height:o}=this;e&&(t.save(),t.fillStyle=e,t.fillRect(i,s,n,o),t.restore())}getLineWidthForValue(t){const e=this.options.grid;if(!this._isVisible()||!e.display)return 0;const i=this.ticks.findIndex((e=>e.value===t));if(i>=0){return e.setContext(this.getContext(i)).lineWidth}return 0}drawGrid(t){const e=this.options.grid,i=this.ctx,s=this._gridLineItems||(this._gridLineItems=this._computeGridLineItems(t));let n,o;const a=(t,e,s)=>{s.width&&s.color&&(i.save(),i.lineWidth=s.width,i.strokeStyle=s.color,i.setLineDash(s.borderDash||[]),i.lineDashOffset=s.borderDashOffset,i.beginPath(),i.moveTo(t.x,t.y),i.lineTo(e.x,e.y),i.stroke(),i.restore())};if(e.display)for(n=0,o=s.length;n{this.drawBackground(),this.drawGrid(t),this.drawTitle()}},{z:s,draw:()=>{this.drawBorder()}},{z:e,draw:t=>{this.drawLabels(t)}}]:[{z:e,draw:t=>{this.draw(t)}}]}getMatchingVisibleMetas(t){const e=this.chart.getSortedVisibleDatasetMetas(),i=this.axis+"AxisID",s=[];let n,o;for(n=0,o=e.length;n{const s=i.split("."),n=s.pop(),o=[t].concat(s).join("."),a=e[i].split("."),r=a.pop(),l=a.join(".");ue.route(o,n,l,r)}))}(e,t.defaultRoutes);t.descriptors&&ue.describe(e,t.descriptors)}(t,o,i),this.override&&ue.override(t.id,t.overrides)),o}get(t){return this.items[t]}unregister(t){const e=this.items,i=t.id,s=this.scope;i in e&&delete e[i],s&&i in ue[s]&&(delete ue[s][i],this.override&&delete re[i])}}class sn{constructor(){this.controllers=new en(js,"datasets",!0),this.elements=new en($s,"elements"),this.plugins=new en(Object,"plugins"),this.scales=new en(tn,"scales"),this._typedRegistries=[this.controllers,this.scales,this.elements]}add(...t){this._each("register",t)}remove(...t){this._each("unregister",t)}addControllers(...t){this._each("register",t,this.controllers)}addElements(...t){this._each("register",t,this.elements)}addPlugins(...t){this._each("register",t,this.plugins)}addScales(...t){this._each("register",t,this.scales)}getController(t){return this._get(t,this.controllers,"controller")}getElement(t){return this._get(t,this.elements,"element")}getPlugin(t){return this._get(t,this.plugins,"plugin")}getScale(t){return this._get(t,this.scales,"scale")}removeControllers(...t){this._each("unregister",t,this.controllers)}removeElements(...t){this._each("unregister",t,this.elements)}removePlugins(...t){this._each("unregister",t,this.plugins)}removeScales(...t){this._each("unregister",t,this.scales)}_each(t,e,i){[...e].forEach((e=>{const s=i||this._getRegistryForType(e);i||s.isForType(e)||s===this.plugins&&e.id?this._exec(t,s,e):u(e,(e=>{const s=i||this._getRegistryForType(e);this._exec(t,s,e)}))}))}_exec(t,e,i){const s=w(t);d(i["before"+s],[],i),e[t](i),d(i["after"+s],[],i)}_getRegistryForType(t){for(let e=0;et.filter((t=>!e.some((e=>t.plugin.id===e.plugin.id))));this._notify(s(e,i),t,"stop"),this._notify(s(i,e),t,"start")}}function an(t,e){return e||!1!==t?!0===t?{}:t:null}function rn(t,{plugin:e,local:i},s,n){const o=t.pluginScopeKeys(e),a=t.getOptionScopes(s,o);return i&&e.defaults&&a.push(e.defaults),t.createResolver(a,n,[""],{scriptable:!1,indexable:!1,allKeys:!0})}function ln(t,e){const i=ue.datasets[t]||{};return((e.datasets||{})[t]||{}).indexAxis||e.indexAxis||i.indexAxis||"x"}function hn(t){if("x"===t||"y"===t||"r"===t)return t}function cn(t,...e){if(hn(t))return t;for(const s of e){const e=s.axis||("top"===(i=s.position)||"bottom"===i?"x":"left"===i||"right"===i?"y":void 0)||t.length>1&&hn(t[0].toLowerCase());if(e)return e}var i;throw new Error(`Cannot determine type of '${t}' axis. Please provide 'axis' or 'position' option.`)}function dn(t,e,i){if(i[e+"AxisID"]===t)return{axis:e}}function un(t,e){const i=re[t.type]||{scales:{}},s=e.scales||{},n=ln(t.type,e),a=Object.create(null);return Object.keys(s).forEach((e=>{const r=s[e];if(!o(r))return console.error(`Invalid scale configuration for scale: ${e}`);if(r._proxy)return console.warn(`Ignoring resolver passed as options for scale: ${e}`);const l=cn(e,r,function(t,e){if(e.data&&e.data.datasets){const i=e.data.datasets.filter((e=>e.xAxisID===t||e.yAxisID===t));if(i.length)return dn(t,"x",i[0])||dn(t,"y",i[0])}return{}}(e,t),ue.scales[r.type]),h=function(t,e){return t===e?"_index_":"_value_"}(l,n),c=i.scales||{};a[e]=b(Object.create(null),[{axis:l},r,c[l],c[h]])})),t.data.datasets.forEach((i=>{const n=i.type||t.type,o=i.indexAxis||ln(n,e),r=(re[n]||{}).scales||{};Object.keys(r).forEach((t=>{const e=function(t,e){let i=t;return"_index_"===t?i=e:"_value_"===t&&(i="x"===e?"y":"x"),i}(t,o),n=i[e+"AxisID"]||e;a[n]=a[n]||Object.create(null),b(a[n],[{axis:e},s[n],r[t]])}))})),Object.keys(a).forEach((t=>{const e=a[t];b(e,[ue.scales[e.type],ue.scale])})),a}function fn(t){const e=t.options||(t.options={});e.plugins=l(e.plugins,{}),e.scales=un(t,e)}function gn(t){return(t=t||{}).datasets=t.datasets||[],t.labels=t.labels||[],t}const pn=new Map,mn=new Set;function xn(t,e){let i=pn.get(t);return i||(i=e(),pn.set(t,i),mn.add(i)),i}const bn=(t,e,i)=>{const s=M(e,i);void 0!==s&&t.add(s)};class _n{constructor(t){this._config=function(t){return(t=t||{}).data=gn(t.data),fn(t),t}(t),this._scopeCache=new Map,this._resolverCache=new Map}get platform(){return this._config.platform}get type(){return this._config.type}set type(t){this._config.type=t}get data(){return this._config.data}set data(t){this._config.data=gn(t)}get options(){return this._config.options}set options(t){this._config.options=t}get plugins(){return this._config.plugins}update(){const t=this._config;this.clearCache(),fn(t)}clearCache(){this._scopeCache.clear(),this._resolverCache.clear()}datasetScopeKeys(t){return xn(t,(()=>[[`datasets.${t}`,""]]))}datasetAnimationScopeKeys(t,e){return xn(`${t}.transition.${e}`,(()=>[[`datasets.${t}.transitions.${e}`,`transitions.${e}`],[`datasets.${t}`,""]]))}datasetElementScopeKeys(t,e){return xn(`${t}-${e}`,(()=>[[`datasets.${t}.elements.${e}`,`datasets.${t}`,`elements.${e}`,""]]))}pluginScopeKeys(t){const e=t.id;return xn(`${this.type}-plugin-${e}`,(()=>[[`plugins.${e}`,...t.additionalOptionScopes||[]]]))}_cachedScopes(t,e){const i=this._scopeCache;let s=i.get(t);return s&&!e||(s=new Map,i.set(t,s)),s}getOptionScopes(t,e,i){const{options:s,type:n}=this,o=this._cachedScopes(t,i),a=o.get(e);if(a)return a;const r=new Set;e.forEach((e=>{t&&(r.add(t),e.forEach((e=>bn(r,t,e)))),e.forEach((t=>bn(r,s,t))),e.forEach((t=>bn(r,re[n]||{},t))),e.forEach((t=>bn(r,ue,t))),e.forEach((t=>bn(r,le,t)))}));const l=Array.from(r);return 0===l.length&&l.push(Object.create(null)),mn.has(e)&&o.set(e,l),l}chartOptionScopes(){const{options:t,type:e}=this;return[t,re[e]||{},ue.datasets[e]||{},{type:e},ue,le]}resolveNamedOptions(t,e,i,s=[""]){const o={$shared:!0},{resolver:a,subPrefixes:r}=yn(this._resolverCache,t,s);let l=a;if(function(t,e){const{isScriptable:i,isIndexable:s}=Ye(t);for(const o of e){const e=i(o),a=s(o),r=(a||e)&&t[o];if(e&&(S(r)||vn(r))||a&&n(r))return!0}return!1}(a,e)){o.$shared=!1;l=$e(a,i=S(i)?i():i,this.createResolver(t,i,r))}for(const t of e)o[t]=l[t];return o}createResolver(t,e,i=[""],s){const{resolver:n}=yn(this._resolverCache,t,i);return o(e)?$e(n,e,void 0,s):n}}function yn(t,e,i){let s=t.get(e);s||(s=new Map,t.set(e,s));const n=i.join();let o=s.get(n);if(!o){o={resolver:je(e,i),subPrefixes:i.filter((t=>!t.toLowerCase().includes("hover")))},s.set(n,o)}return o}const vn=t=>o(t)&&Object.getOwnPropertyNames(t).some((e=>S(t[e])));const Mn=["top","bottom","left","right","chartArea"];function wn(t,e){return"top"===t||"bottom"===t||-1===Mn.indexOf(t)&&"x"===e}function kn(t,e){return function(i,s){return i[t]===s[t]?i[e]-s[e]:i[t]-s[t]}}function Sn(t){const e=t.chart,i=e.options.animation;e.notifyPlugins("afterRender"),d(i&&i.onComplete,[t],e)}function Pn(t){const e=t.chart,i=e.options.animation;d(i&&i.onProgress,[t],e)}function Dn(t){return fe()&&"string"==typeof t?t=document.getElementById(t):t&&t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas),t}const Cn={},On=t=>{const e=Dn(t);return Object.values(Cn).filter((t=>t.canvas===e)).pop()};function An(t,e,i){const s=Object.keys(t);for(const n of s){const s=+n;if(s>=e){const o=t[n];delete t[n],(i>0||s>e)&&(t[s+i]=o)}}}class Tn{static defaults=ue;static instances=Cn;static overrides=re;static registry=nn;static version="4.5.1";static getChart=On;static register(...t){nn.add(...t),Ln()}static unregister(...t){nn.remove(...t),Ln()}constructor(t,e){const s=this.config=new _n(e),n=Dn(t),o=On(n);if(o)throw new Error("Canvas is already in use. Chart with ID '"+o.id+"' must be destroyed before the canvas with ID '"+o.canvas.id+"' can be reused.");const a=s.createResolver(s.chartOptionScopes(),this.getContext());this.platform=new(s.platform||Ps(n)),this.platform.updateConfig(s);const r=this.platform.acquireContext(n,a.aspectRatio),l=r&&r.canvas,h=l&&l.height,c=l&&l.width;this.id=i(),this.ctx=r,this.canvas=l,this.width=c,this.height=h,this._options=a,this._aspectRatio=this.aspectRatio,this._layers=[],this._metasets=[],this._stacks=void 0,this.boxes=[],this.currentDevicePixelRatio=void 0,this.chartArea=void 0,this._active=[],this._lastEvent=void 0,this._listeners={},this._responsiveListeners=void 0,this._sortedMetasets=[],this.scales={},this._plugins=new on,this.$proxies={},this._hiddenIndices={},this.attached=!1,this._animationsDisabled=void 0,this.$context=void 0,this._doResize=dt((t=>this.update(t)),a.resizeDelay||0),this._dataChanges=[],Cn[this.id]=this,r&&l?(bt.listen(this,"complete",Sn),bt.listen(this,"progress",Pn),this._initialize(),this.attached&&this.update()):console.error("Failed to create chart: can't acquire context from the given item")}get aspectRatio(){const{options:{aspectRatio:t,maintainAspectRatio:e},width:i,height:n,_aspectRatio:o}=this;return s(t)?e&&o?o:n?i/n:null:t}get data(){return this.config.data}set data(t){this.config.data=t}get options(){return this._options}set options(t){this.config.options=t}get registry(){return nn}_initialize(){return this.notifyPlugins("beforeInit"),this.options.responsive?this.resize():ke(this,this.options.devicePixelRatio),this.bindEvents(),this.notifyPlugins("afterInit"),this}clear(){return Te(this.canvas,this.ctx),this}stop(){return bt.stop(this),this}resize(t,e){bt.running(this)?this._resizeBeforeDraw={width:t,height:e}:this._resize(t,e)}_resize(t,e){const i=this.options,s=this.canvas,n=i.maintainAspectRatio&&this.aspectRatio,o=this.platform.getMaximumSize(s,t,e,n),a=i.devicePixelRatio||this.platform.getDevicePixelRatio(),r=this.width?"resize":"attach";this.width=o.width,this.height=o.height,this._aspectRatio=this.aspectRatio,ke(this,a,!0)&&(this.notifyPlugins("resize",{size:o}),d(i.onResize,[this,o],this),this.attached&&this._doResize(r)&&this.render())}ensureScalesHaveIDs(){u(this.options.scales||{},((t,e)=>{t.id=e}))}buildOrUpdateScales(){const t=this.options,e=t.scales,i=this.scales,s=Object.keys(i).reduce(((t,e)=>(t[e]=!1,t)),{});let n=[];e&&(n=n.concat(Object.keys(e).map((t=>{const i=e[t],s=cn(t,i),n="r"===s,o="x"===s;return{options:i,dposition:n?"chartArea":o?"bottom":"left",dtype:n?"radialLinear":o?"category":"linear"}})))),u(n,(e=>{const n=e.options,o=n.id,a=cn(o,n),r=l(n.type,e.dtype);void 0!==n.position&&wn(n.position,a)===wn(e.dposition)||(n.position=e.dposition),s[o]=!0;let h=null;if(o in i&&i[o].type===r)h=i[o];else{h=new(nn.getScale(r))({id:o,type:r,ctx:this.ctx,chart:this}),i[h.id]=h}h.init(n,t)})),u(s,((t,e)=>{t||delete i[e]})),u(i,(t=>{ls.configure(this,t,t.options),ls.addBox(this,t)}))}_updateMetasets(){const t=this._metasets,e=this.data.datasets.length,i=t.length;if(t.sort(((t,e)=>t.index-e.index)),i>e){for(let t=e;te.length&&delete this._stacks,t.forEach(((t,i)=>{0===e.filter((e=>e===t._dataset)).length&&this._destroyDatasetMeta(i)}))}buildOrUpdateControllers(){const t=[],e=this.data.datasets;let i,s;for(this._removeUnreferencedMetasets(),i=0,s=e.length;i{this.getDatasetMeta(e).controller.reset()}),this)}reset(){this._resetElements(),this.notifyPlugins("reset")}update(t){const e=this.config;e.update();const i=this._options=e.createResolver(e.chartOptionScopes(),this.getContext()),s=this._animationsDisabled=!i.animation;if(this._updateScales(),this._checkEventBindings(),this._updateHiddenIndices(),this._plugins.invalidate(),!1===this.notifyPlugins("beforeUpdate",{mode:t,cancelable:!0}))return;const n=this.buildOrUpdateControllers();this.notifyPlugins("beforeElementsUpdate");let o=0;for(let t=0,e=this.data.datasets.length;t{t.reset()})),this._updateDatasets(t),this.notifyPlugins("afterUpdate",{mode:t}),this._layers.sort(kn("z","_idx"));const{_active:a,_lastEvent:r}=this;r?this._eventHandler(r,!0):a.length&&this._updateHoverStyles(a,a,!0),this.render()}_updateScales(){u(this.scales,(t=>{ls.removeBox(this,t)})),this.ensureScalesHaveIDs(),this.buildOrUpdateScales()}_checkEventBindings(){const t=this.options,e=new Set(Object.keys(this._listeners)),i=new Set(t.events);P(e,i)&&!!this._responsiveListeners===t.responsive||(this.unbindEvents(),this.bindEvents())}_updateHiddenIndices(){const{_hiddenIndices:t}=this,e=this._getUniformDataChanges()||[];for(const{method:i,start:s,count:n}of e){An(t,s,"_removeElements"===i?-n:n)}}_getUniformDataChanges(){const t=this._dataChanges;if(!t||!t.length)return;this._dataChanges=[];const e=this.data.datasets.length,i=e=>new Set(t.filter((t=>t[0]===e)).map(((t,e)=>e+","+t.splice(1).join(",")))),s=i(0);for(let t=1;tt.split(","))).map((t=>({method:t[1],start:+t[2],count:+t[3]})))}_updateLayout(t){if(!1===this.notifyPlugins("beforeLayout",{cancelable:!0}))return;ls.update(this,this.width,this.height,t);const e=this.chartArea,i=e.width<=0||e.height<=0;this._layers=[],u(this.boxes,(t=>{i&&"chartArea"===t.position||(t.configure&&t.configure(),this._layers.push(...t._layers()))}),this),this._layers.forEach(((t,e)=>{t._idx=e})),this.notifyPlugins("afterLayout")}_updateDatasets(t){if(!1!==this.notifyPlugins("beforeDatasetsUpdate",{mode:t,cancelable:!0})){for(let t=0,e=this.data.datasets.length;t=0;--e)this._drawDataset(t[e]);this.notifyPlugins("afterDatasetsDraw")}_drawDataset(t){const e=this.ctx,i={meta:t,index:t.index,cancelable:!0},s=Ni(this,t);!1!==this.notifyPlugins("beforeDatasetDraw",i)&&(s&&Ie(e,s),t.controller.draw(),s&&ze(e),i.cancelable=!1,this.notifyPlugins("afterDatasetDraw",i))}isPointInArea(t){return Re(t,this.chartArea,this._minPadding)}getElementsAtEventForMode(t,e,i,s){const n=Ki.modes[e];return"function"==typeof n?n(this,t,i,s):[]}getDatasetMeta(t){const e=this.data.datasets[t],i=this._metasets;let s=i.filter((t=>t&&t._dataset===e)).pop();return s||(s={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e&&e.order||0,index:t,_dataset:e,_parsed:[],_sorted:!1},i.push(s)),s}getContext(){return this.$context||(this.$context=Ci(null,{chart:this,type:"chart"}))}getVisibleDatasetCount(){return this.getSortedVisibleDatasetMetas().length}isDatasetVisible(t){const e=this.data.datasets[t];if(!e)return!1;const i=this.getDatasetMeta(t);return"boolean"==typeof i.hidden?!i.hidden:!e.hidden}setDatasetVisibility(t,e){this.getDatasetMeta(t).hidden=!e}toggleDataVisibility(t){this._hiddenIndices[t]=!this._hiddenIndices[t]}getDataVisibility(t){return!this._hiddenIndices[t]}_updateVisibility(t,e,i){const s=i?"show":"hide",n=this.getDatasetMeta(t),o=n.controller._resolveAnimations(void 0,s);k(e)?(n.data[e].hidden=!i,this.update()):(this.setDatasetVisibility(t,i),o.update(n,{visible:i}),this.update((e=>e.datasetIndex===t?s:void 0)))}hide(t,e){this._updateVisibility(t,e,!1)}show(t,e){this._updateVisibility(t,e,!0)}_destroyDatasetMeta(t){const e=this._metasets[t];e&&e.controller&&e.controller._destroy(),delete this._metasets[t]}_stop(){let t,e;for(this.stop(),bt.remove(this),t=0,e=this.data.datasets.length;t{e.addEventListener(this,i,s),t[i]=s},s=(t,e,i)=>{t.offsetX=e,t.offsetY=i,this._eventHandler(t)};u(this.options.events,(t=>i(t,s)))}bindResponsiveEvents(){this._responsiveListeners||(this._responsiveListeners={});const t=this._responsiveListeners,e=this.platform,i=(i,s)=>{e.addEventListener(this,i,s),t[i]=s},s=(i,s)=>{t[i]&&(e.removeEventListener(this,i,s),delete t[i])},n=(t,e)=>{this.canvas&&this.resize(t,e)};let o;const a=()=>{s("attach",a),this.attached=!0,this.resize(),i("resize",n),i("detach",o)};o=()=>{this.attached=!1,s("resize",n),this._stop(),this._resize(0,0),i("attach",a)},e.isAttached(this.canvas)?a():o()}unbindEvents(){u(this._listeners,((t,e)=>{this.platform.removeEventListener(this,e,t)})),this._listeners={},u(this._responsiveListeners,((t,e)=>{this.platform.removeEventListener(this,e,t)})),this._responsiveListeners=void 0}updateHoverStyle(t,e,i){const s=i?"set":"remove";let n,o,a,r;for("dataset"===e&&(n=this.getDatasetMeta(t[0].datasetIndex),n.controller["_"+s+"DatasetHoverStyle"]()),a=0,r=t.length;a{const i=this.getDatasetMeta(t);if(!i)throw new Error("No dataset found at index "+t);return{datasetIndex:t,element:i.data[e],index:e}}));!f(i,e)&&(this._active=i,this._lastEvent=null,this._updateHoverStyles(i,e))}notifyPlugins(t,e,i){return this._plugins.notify(this,t,e,i)}isPluginEnabled(t){return 1===this._plugins._cache.filter((e=>e.plugin.id===t)).length}_updateHoverStyles(t,e,i){const s=this.options.hover,n=(t,e)=>t.filter((t=>!e.some((e=>t.datasetIndex===e.datasetIndex&&t.index===e.index)))),o=n(e,t),a=i?t:n(t,e);o.length&&this.updateHoverStyle(o,s.mode,!1),a.length&&s.mode&&this.updateHoverStyle(a,s.mode,!0)}_eventHandler(t,e){const i={event:t,replay:e,cancelable:!0,inChartArea:this.isPointInArea(t)},s=e=>(e.options.events||this.options.events).includes(t.native.type);if(!1===this.notifyPlugins("beforeEvent",i,s))return;const n=this._handleEvent(t,e,i.inChartArea);return i.cancelable=!1,this.notifyPlugins("afterEvent",i,s),(n||i.changed)&&this.render(),this}_handleEvent(t,e,i){const{_active:s=[],options:n}=this,o=e,a=this._getActiveElements(t,s,i,o),r=D(t),l=function(t,e,i,s){return i&&"mouseout"!==t.type?s?e:t:null}(t,this._lastEvent,i,r);i&&(this._lastEvent=null,d(n.onHover,[t,a,this],this),r&&d(n.onClick,[t,a,this],this));const h=!f(a,s);return(h||e)&&(this._active=a,this._updateHoverStyles(a,s,e)),this._lastEvent=l,h}_getActiveElements(t,e,i,s){if("mouseout"===t.type)return[];if(!i)return e;const n=this.options.hover;return this.getElementsAtEventForMode(t,n.mode,n,s)}}function Ln(){return u(Tn.instances,(t=>t._plugins.invalidate()))}function En(){throw new Error("This method is not implemented: Check that a complete date adapter is provided.")}class Rn{static override(t){Object.assign(Rn.prototype,t)}options;constructor(t){this.options=t||{}}init(){}formats(){return En()}parse(){return En()}format(){return En()}add(){return En()}diff(){return En()}startOf(){return En()}endOf(){return En()}}var In={_date:Rn};function zn(t){const e=t.iScale,i=function(t,e){if(!t._cache.$bar){const i=t.getMatchingVisibleMetas(e);let s=[];for(let e=0,n=i.length;et-e)))}return t._cache.$bar}(e,t.type);let s,n,o,a,r=e._length;const l=()=>{32767!==o&&-32768!==o&&(k(a)&&(r=Math.min(r,Math.abs(o-a)||r)),a=o)};for(s=0,n=i.length;sMath.abs(r)&&(l=r,h=a),e[i.axis]=h,e._custom={barStart:l,barEnd:h,start:n,end:o,min:a,max:r}}(t,e,i,s):e[i.axis]=i.parse(t,s),e}function Vn(t,e,i,s){const n=t.iScale,o=t.vScale,a=n.getLabels(),r=n===o,l=[];let h,c,d,u;for(h=i,c=i+s;ht.x,i="left",s="right"):(e=t.base"spacing"!==t,_indexable:t=>"spacing"!==t&&!t.startsWith("borderDash")&&!t.startsWith("hoverBorderDash")};static overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){const e=t.data,{labels:{pointStyle:i,textAlign:s,color:n,useBorderRadius:o,borderRadius:a}}=t.legend.options;return e.labels.length&&e.datasets.length?e.labels.map(((e,r)=>{const l=t.getDatasetMeta(0).controller.getStyle(r);return{text:e,fillStyle:l.backgroundColor,fontColor:n,hidden:!t.getDataVisibility(r),lineDash:l.borderDash,lineDashOffset:l.borderDashOffset,lineJoin:l.borderJoinStyle,lineWidth:l.borderWidth,strokeStyle:l.borderColor,textAlign:s,pointStyle:i,borderRadius:o&&(a||l.borderRadius),index:r}})):[]}},onClick(t,e,i){i.chart.toggleDataVisibility(e.index),i.chart.update()}}}};constructor(t,e){super(t,e),this.enableOptionSharing=!0,this.innerRadius=void 0,this.outerRadius=void 0,this.offsetX=void 0,this.offsetY=void 0}linkScales(){}parse(t,e){const i=this.getDataset().data,s=this._cachedMeta;if(!1===this._parsing)s._parsed=i;else{let n,a,r=t=>+i[t];if(o(i[t])){const{key:t="value"}=this._parsing;r=e=>+M(i[e],t)}for(n=t,a=t+e;nJ(t,r,l,!0)?1:Math.max(e,e*i,s,s*i),g=(t,e,s)=>J(t,r,l,!0)?-1:Math.min(e,e*i,s,s*i),p=f(0,h,d),m=f(E,c,u),x=g(C,h,d),b=g(C+E,c,u);s=(p-x)/2,n=(m-b)/2,o=-(p+x)/2,a=-(m+b)/2}return{ratioX:s,ratioY:n,offsetX:o,offsetY:a}}(u,d,r),x=(i.width-o)/f,b=(i.height-o)/g,_=Math.max(Math.min(x,b)/2,0),y=c(this.options.radius,_),v=(y-Math.max(y*r,0))/this._getVisibleDatasetWeightTotal();this.offsetX=p*y,this.offsetY=m*y,s.total=this.calculateTotal(),this.outerRadius=y-v*this._getRingWeightOffset(this.index),this.innerRadius=Math.max(this.outerRadius-v*l,0),this.updateElements(n,0,n.length,t)}_circumference(t,e){const i=this.options,s=this._cachedMeta,n=this._getCircumference();return e&&i.animation.animateRotate||!this.chart.getDataVisibility(t)||null===s._parsed[t]||s.data[t].hidden?0:this.calculateCircumference(s._parsed[t]*n/O)}updateElements(t,e,i,s){const n="reset"===s,o=this.chart,a=o.chartArea,r=o.options.animation,l=(a.left+a.right)/2,h=(a.top+a.bottom)/2,c=n&&r.animateScale,d=c?0:this.innerRadius,u=c?0:this.outerRadius,{sharedOptions:f,includeOptions:g}=this._getSharedOptions(e,s);let p,m=this._getRotation();for(p=0;p0&&!isNaN(t)?O*(Math.abs(t)/e):0}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart,s=i.data.labels||[],n=ne(e._parsed[t],i.options.locale);return{label:s[t]||"",value:n}}getMaxBorderWidth(t){let e=0;const i=this.chart;let s,n,o,a,r;if(!t)for(s=0,n=i.data.datasets.length;s{const o=t.getDatasetMeta(0).controller.getStyle(n);return{text:e,fillStyle:o.backgroundColor,strokeStyle:o.borderColor,fontColor:s,lineWidth:o.borderWidth,pointStyle:i,hidden:!t.getDataVisibility(n),index:n}}))}return[]}},onClick(t,e,i){i.chart.toggleDataVisibility(e.index),i.chart.update()}}},scales:{r:{type:"radialLinear",angleLines:{display:!1},beginAtZero:!0,grid:{circular:!0},pointLabels:{display:!1},startAngle:0}}};constructor(t,e){super(t,e),this.innerRadius=void 0,this.outerRadius=void 0}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart,s=i.data.labels||[],n=ne(e._parsed[t].r,i.options.locale);return{label:s[t]||"",value:n}}parseObjectData(t,e,i,s){return ii.bind(this)(t,e,i,s)}update(t){const e=this._cachedMeta.data;this._updateRadius(),this.updateElements(e,0,e.length,t)}getMinMax(){const t=this._cachedMeta,e={min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY};return t.data.forEach(((t,i)=>{const s=this.getParsed(i).r;!isNaN(s)&&this.chart.getDataVisibility(i)&&(se.max&&(e.max=s))})),e}_updateRadius(){const t=this.chart,e=t.chartArea,i=t.options,s=Math.min(e.right-e.left,e.bottom-e.top),n=Math.max(s/2,0),o=(n-Math.max(i.cutoutPercentage?n/100*i.cutoutPercentage:1,0))/t.getVisibleDatasetCount();this.outerRadius=n-o*this.index,this.innerRadius=this.outerRadius-o}updateElements(t,e,i,s){const n="reset"===s,o=this.chart,a=o.options.animation,r=this._cachedMeta.rScale,l=r.xCenter,h=r.yCenter,c=r.getIndexAngle(0)-.5*C;let d,u=c;const f=360/this.countVisibleElements();for(d=0;d{!isNaN(this.getParsed(i).r)&&this.chart.getDataVisibility(i)&&e++})),e}_computeAngle(t,e,i){return this.chart.getDataVisibility(t)?$(this.resolveDataElementOptions(t,e).angle||i):0}}var Un=Object.freeze({__proto__:null,BarController:class extends js{static id="bar";static defaults={datasetElementType:!1,dataElementType:"bar",categoryPercentage:.8,barPercentage:.9,grouped:!0,animations:{numbers:{type:"number",properties:["x","y","base","width","height"]}}};static overrides={scales:{_index_:{type:"category",offset:!0,grid:{offset:!0}},_value_:{type:"linear",beginAtZero:!0}}};parsePrimitiveData(t,e,i,s){return Vn(t,e,i,s)}parseArrayData(t,e,i,s){return Vn(t,e,i,s)}parseObjectData(t,e,i,s){const{iScale:n,vScale:o}=t,{xAxisKey:a="x",yAxisKey:r="y"}=this._parsing,l="x"===n.axis?a:r,h="x"===o.axis?a:r,c=[];let d,u,f,g;for(d=i,u=i+s;dt.controller.options.grouped)),o=i.options.stacked,a=[],r=this._cachedMeta.controller.getParsed(e),l=r&&r[i.axis],h=t=>{const e=t._parsed.find((t=>t[i.axis]===l)),n=e&&e[t.vScale.axis];if(s(n)||isNaN(n))return!0};for(const i of n)if((void 0===e||!h(i))&&((!1===o||-1===a.indexOf(i.stack)||void 0===o&&void 0===i.stack)&&a.push(i.stack),i.index===t))break;return a.length||a.push(void 0),a}_getStackCount(t){return this._getStacks(void 0,t).length}_getAxisCount(){return this._getAxis().length}getFirstScaleIdForIndexAxis(){const t=this.chart.scales,e=this.chart.options.indexAxis;return Object.keys(t).filter((i=>t[i].axis===e)).shift()}_getAxis(){const t={},e=this.getFirstScaleIdForIndexAxis();for(const i of this.chart.data.datasets)t[l("x"===this.chart.options.indexAxis?i.xAxisID:i.yAxisID,e)]=!0;return Object.keys(t)}_getStackIndex(t,e,i){const s=this._getStacks(t,i),n=void 0!==e?s.indexOf(e):-1;return-1===n?s.length-1:n}_getRuler(){const t=this.options,e=this._cachedMeta,i=e.iScale,s=[];let n,o;for(n=0,o=e.data.length;n=i?1:-1)}(u,e,r)*a,f===r&&(x-=u/2);const t=e.getPixelForDecimal(0),s=e.getPixelForDecimal(1),o=Math.min(t,s),h=Math.max(t,s);x=Math.max(Math.min(x,h),o),d=x+u,i&&!c&&(l._stacks[e.axis]._visualValues[n]=e.getValueForPixel(d)-e.getValueForPixel(x))}if(x===e.getPixelForValue(r)){const t=F(u)*e.getLineWidthForValue(r)/2;x+=t,u-=t}return{size:u,base:x,head:d,center:d+u/2}}_calculateBarIndexPixels(t,e){const i=e.scale,n=this.options,o=n.skipNull,a=l(n.maxBarThickness,1/0);let r,h;const c=this._getAxisCount();if(e.grouped){const i=o?this._getStackCount(t):e.stackCount,d="flex"===n.barThickness?function(t,e,i,s){const n=e.pixels,o=n[t];let a=t>0?n[t-1]:null,r=t=0;--i)e=Math.max(e,t[i].size(this.resolveDataElementOptions(i))/2);return e>0&&e}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart.data.labels||[],{xScale:s,yScale:n}=e,o=this.getParsed(t),a=s.getLabelForValue(o.x),r=n.getLabelForValue(o.y),l=o._custom;return{label:i[t]||"",value:"("+a+", "+r+(l?", "+l:"")+")"}}update(t){const e=this._cachedMeta.data;this.updateElements(e,0,e.length,t)}updateElements(t,e,i,s){const n="reset"===s,{iScale:o,vScale:a}=this._cachedMeta,{sharedOptions:r,includeOptions:l}=this._getSharedOptions(e,s),h=o.axis,c=a.axis;for(let d=e;d0&&this.getParsed(e-1);for(let i=0;i<_;++i){const g=t[i],_=x?g:{};if(i=b){_.skip=!0;continue}const v=this.getParsed(i),M=s(v[f]),w=_[u]=a.getPixelForValue(v[u],i),k=_[f]=o||M?r.getBasePixel():r.getPixelForValue(l?this.applyStack(r,v,l):v[f],i);_.skip=isNaN(w)||isNaN(k)||M,_.stop=i>0&&Math.abs(v[u]-y[u])>m,p&&(_.parsed=v,_.raw=h.data[i]),d&&(_.options=c||this.resolveDataElementOptions(i,g.active?"active":n)),x||this.updateElement(g,i,_,n),y=v}}getMaxOverflow(){const t=this._cachedMeta,e=t.dataset,i=e.options&&e.options.borderWidth||0,s=t.data||[];if(!s.length)return i;const n=s[0].size(this.resolveDataElementOptions(0)),o=s[s.length-1].size(this.resolveDataElementOptions(s.length-1));return Math.max(i,n,o)/2}draw(){const t=this._cachedMeta;t.dataset.updateControlPoints(this.chart.chartArea,t.iScale.axis),super.draw()}},PieController:class extends $n{static id="pie";static defaults={cutout:0,rotation:0,circumference:360,radius:"100%"}},PolarAreaController:Yn,RadarController:class extends js{static id="radar";static defaults={datasetElementType:"line",dataElementType:"point",indexAxis:"r",showLine:!0,elements:{line:{fill:"start"}}};static overrides={aspectRatio:1,scales:{r:{type:"radialLinear"}}};getLabelAndValue(t){const e=this._cachedMeta.vScale,i=this.getParsed(t);return{label:e.getLabels()[t],value:""+e.getLabelForValue(i[e.axis])}}parseObjectData(t,e,i,s){return ii.bind(this)(t,e,i,s)}update(t){const e=this._cachedMeta,i=e.dataset,s=e.data||[],n=e.iScale.getLabels();if(i.points=s,"resize"!==t){const e=this.resolveDatasetElementOptions(t);this.options.showLine||(e.borderWidth=0);const o={_loop:!0,_fullLoop:n.length===s.length,options:e};this.updateElement(i,void 0,o,t)}this.updateElements(s,0,s.length,t)}updateElements(t,e,i,s){const n=this._cachedMeta.rScale,o="reset"===s;for(let a=e;a0&&this.getParsed(e-1);for(let c=e;c0&&Math.abs(i[f]-_[f])>x,m&&(p.parsed=i,p.raw=h.data[c]),u&&(p.options=d||this.resolveDataElementOptions(c,e.active?"active":n)),b||this.updateElement(e,c,p,n),_=i}this.updateSharedOptions(d,n,c)}getMaxOverflow(){const t=this._cachedMeta,e=t.data||[];if(!this.options.showLine){let t=0;for(let i=e.length-1;i>=0;--i)t=Math.max(t,e[i].size(this.resolveDataElementOptions(i))/2);return t>0&&t}const i=t.dataset,s=i.options&&i.options.borderWidth||0;if(!e.length)return s;const n=e[0].size(this.resolveDataElementOptions(0)),o=e[e.length-1].size(this.resolveDataElementOptions(e.length-1));return Math.max(s,n,o)/2}}});function Xn(t,e,i,s){const n=vi(t.options.borderRadius,["outerStart","outerEnd","innerStart","innerEnd"]);const o=(i-e)/2,a=Math.min(o,s*e/2),r=t=>{const e=(i-Math.min(o,t))*s/2;return Z(t,0,Math.min(o,e))};return{outerStart:r(n.outerStart),outerEnd:r(n.outerEnd),innerStart:Z(n.innerStart,0,a),innerEnd:Z(n.innerEnd,0,a)}}function qn(t,e,i,s){return{x:i+t*Math.cos(e),y:s+t*Math.sin(e)}}function Kn(t,e,i,s,n,o){const{x:a,y:r,startAngle:l,pixelMargin:h,innerRadius:c}=e,d=Math.max(e.outerRadius+s+i-h,0),u=c>0?c+s+i+h:0;let f=0;const g=n-l;if(s){const t=((c>0?c-s:0)+(d>0?d-s:0))/2;f=(g-(0!==t?g*t/(t+s):g))/2}const p=(g-Math.max(.001,g*d-i/C)/d)/2,m=l+p+f,x=n-p-f,{outerStart:b,outerEnd:_,innerStart:y,innerEnd:v}=Xn(e,u,d,x-m),M=d-b,w=d-_,k=m+b/M,S=x-_/w,P=u+y,D=u+v,O=m+y/P,A=x-v/D;if(t.beginPath(),o){const e=(k+S)/2;if(t.arc(a,r,d,k,e),t.arc(a,r,d,e,S),_>0){const e=qn(w,S,a,r);t.arc(e.x,e.y,_,S,x+E)}const i=qn(D,x,a,r);if(t.lineTo(i.x,i.y),v>0){const e=qn(D,A,a,r);t.arc(e.x,e.y,v,x+E,A+Math.PI)}const s=(x-v/u+(m+y/u))/2;if(t.arc(a,r,u,x-v/u,s,!0),t.arc(a,r,u,s,m+y/u,!0),y>0){const e=qn(P,O,a,r);t.arc(e.x,e.y,y,O+Math.PI,m-E)}const n=qn(M,m,a,r);if(t.lineTo(n.x,n.y),b>0){const e=qn(M,k,a,r);t.arc(e.x,e.y,b,m-E,k)}}else{t.moveTo(a,r);const e=Math.cos(k)*d+a,i=Math.sin(k)*d+r;t.lineTo(e,i);const s=Math.cos(S)*d+a,n=Math.sin(S)*d+r;t.lineTo(s,n)}t.closePath()}function Gn(t,e,i,s,n){const{fullCircles:o,startAngle:a,circumference:r,options:l}=e,{borderWidth:h,borderJoinStyle:c,borderDash:d,borderDashOffset:u,borderRadius:f}=l,g="inner"===l.borderAlign;if(!h)return;t.setLineDash(d||[]),t.lineDashOffset=u,g?(t.lineWidth=2*h,t.lineJoin=c||"round"):(t.lineWidth=h,t.lineJoin=c||"bevel");let p=e.endAngle;if(o){Kn(t,e,i,s,p,n);for(let e=0;en?(h=n/l,t.arc(o,a,l,i+h,s-h,!0)):t.arc(o,a,n,i+E,s-E),t.closePath(),t.clip()}(t,e,p),l.selfJoin&&p-a>=C&&0===f&&"miter"!==c&&function(t,e,i){const{startAngle:s,x:n,y:o,outerRadius:a,innerRadius:r,options:l}=e,{borderWidth:h,borderJoinStyle:c}=l,d=Math.min(h/a,G(s-i));if(t.beginPath(),t.arc(n,o,a-h/2,s+d/2,i-d/2),r>0){const e=Math.min(h/r,G(s-i));t.arc(n,o,r+h/2,i-e/2,s+e/2,!0)}else{const e=Math.min(h/2,a*G(s-i));if("round"===c)t.arc(n,o,e,i-C/2,s+C/2,!0);else if("bevel"===c){const a=2*e*e,r=-a*Math.cos(i+C/2)+n,l=-a*Math.sin(i+C/2)+o,h=a*Math.cos(s+C/2)+n,c=a*Math.sin(s+C/2)+o;t.lineTo(r,l),t.lineTo(h,c)}}t.closePath(),t.moveTo(0,0),t.rect(0,0,t.canvas.width,t.canvas.height),t.clip("evenodd")}(t,e,p),o||(Kn(t,e,i,s,p,n),t.stroke())}function Jn(t,e,i=e){t.lineCap=l(i.borderCapStyle,e.borderCapStyle),t.setLineDash(l(i.borderDash,e.borderDash)),t.lineDashOffset=l(i.borderDashOffset,e.borderDashOffset),t.lineJoin=l(i.borderJoinStyle,e.borderJoinStyle),t.lineWidth=l(i.borderWidth,e.borderWidth),t.strokeStyle=l(i.borderColor,e.borderColor)}function Zn(t,e,i){t.lineTo(i.x,i.y)}function Qn(t,e,i={}){const s=t.length,{start:n=0,end:o=s-1}=i,{start:a,end:r}=e,l=Math.max(n,a),h=Math.min(o,r),c=nr&&o>r;return{count:s,start:l,loop:e.loop,ilen:h(a+(h?r-t:t))%o,_=()=>{f!==g&&(t.lineTo(m,g),t.lineTo(m,f),t.lineTo(m,p))};for(l&&(d=n[b(0)],t.moveTo(d.x,d.y)),c=0;c<=r;++c){if(d=n[b(c)],d.skip)continue;const e=d.x,i=d.y,s=0|e;s===u?(ig&&(g=i),m=(x*m+e)/++x):(_(),t.lineTo(e,i),u=s,x=0,f=g=i),p=i}_()}function io(t){const e=t.options,i=e.borderDash&&e.borderDash.length;return!(t._decimated||t._loop||e.tension||"monotone"===e.cubicInterpolationMode||e.stepped||i)?eo:to}const so="function"==typeof Path2D;function no(t,e,i,s){so&&!e.options.segment?function(t,e,i,s){let n=e._path;n||(n=e._path=new Path2D,e.path(n,i,s)&&n.closePath()),Jn(t,e.options),t.stroke(n)}(t,e,i,s):function(t,e,i,s){const{segments:n,options:o}=e,a=io(e);for(const r of n)Jn(t,o,r.style),t.beginPath(),a(t,e,r,{start:i,end:i+s-1})&&t.closePath(),t.stroke()}(t,e,i,s)}class oo extends $s{static id="line";static defaults={borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",borderWidth:3,capBezierPoints:!0,cubicInterpolationMode:"default",fill:!1,spanGaps:!1,stepped:!1,tension:0};static defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};static descriptors={_scriptable:!0,_indexable:t=>"borderDash"!==t&&"fill"!==t};constructor(t){super(),this.animated=!0,this.options=void 0,this._chart=void 0,this._loop=void 0,this._fullLoop=void 0,this._path=void 0,this._points=void 0,this._segments=void 0,this._decimated=!1,this._pointsUpdated=!1,this._datasetIndex=void 0,t&&Object.assign(this,t)}updateControlPoints(t,e){const i=this.options;if((i.tension||"monotone"===i.cubicInterpolationMode)&&!i.stepped&&!this._pointsUpdated){const s=i.spanGaps?this._loop:this._fullLoop;hi(this._points,i,t,s,e),this._pointsUpdated=!0}}set points(t){this._points=t,delete this._segments,delete this._path,this._pointsUpdated=!1}get points(){return this._points}get segments(){return this._segments||(this._segments=zi(this,this.options.segment))}first(){const t=this.segments,e=this.points;return t.length&&e[t[0].start]}last(){const t=this.segments,e=this.points,i=t.length;return i&&e[t[i-1].end]}interpolate(t,e){const i=this.options,s=t[e],n=this.points,o=Ii(this,{property:e,start:s,end:s});if(!o.length)return;const a=[],r=function(t){return t.stepped?pi:t.tension||"monotone"===t.cubicInterpolationMode?mi:gi}(i);let l,h;for(l=0,h=o.length;l"borderDash"!==t};circumference;endAngle;fullCircles;innerRadius;outerRadius;pixelMargin;startAngle;constructor(t){super(),this.options=void 0,this.circumference=void 0,this.startAngle=void 0,this.endAngle=void 0,this.innerRadius=void 0,this.outerRadius=void 0,this.pixelMargin=0,this.fullCircles=0,t&&Object.assign(this,t)}inRange(t,e,i){const s=this.getProps(["x","y"],i),{angle:n,distance:o}=X(s,{x:t,y:e}),{startAngle:a,endAngle:r,innerRadius:h,outerRadius:c,circumference:d}=this.getProps(["startAngle","endAngle","innerRadius","outerRadius","circumference"],i),u=(this.options.spacing+this.options.borderWidth)/2,f=l(d,r-a),g=J(n,a,r)&&a!==r,p=f>=O||g,m=tt(o,h+u,c+u);return p&&m}getCenterPoint(t){const{x:e,y:i,startAngle:s,endAngle:n,innerRadius:o,outerRadius:a}=this.getProps(["x","y","startAngle","endAngle","innerRadius","outerRadius"],t),{offset:r,spacing:l}=this.options,h=(s+n)/2,c=(o+a+l+r)/2;return{x:e+Math.cos(h)*c,y:i+Math.sin(h)*c}}tooltipPosition(t){return this.getCenterPoint(t)}draw(t){const{options:e,circumference:i}=this,s=(e.offset||0)/4,n=(e.spacing||0)/2,o=e.circular;if(this.pixelMargin="inner"===e.borderAlign?.33:0,this.fullCircles=i>O?Math.floor(i/O):0,0===i||this.innerRadius<0||this.outerRadius<0)return;t.save();const a=(this.startAngle+this.endAngle)/2;t.translate(Math.cos(a)*s,Math.sin(a)*s);const r=s*(1-Math.sin(Math.min(C,i||0)));t.fillStyle=e.backgroundColor,t.strokeStyle=e.borderColor,function(t,e,i,s,n){const{fullCircles:o,startAngle:a,circumference:r}=e;let l=e.endAngle;if(o){Kn(t,e,i,s,l,n);for(let e=0;e("string"==typeof e?(i=t.push(e)-1,s.unshift({index:i,label:e})):isNaN(e)&&(i=null),i))(t,e,i,s);return n!==t.lastIndexOf(e)?i:n}function mo(t){const e=this.getLabels();return t>=0&&ts=e?s:t,a=t=>n=i?n:t;if(t){const t=F(s),e=F(n);t<0&&e<0?a(0):t>0&&e>0&&o(0)}if(s===n){let e=0===n?1:Math.abs(.05*n);a(n+e),t||o(s-e)}this.min=s,this.max=n}getTickLimit(){const t=this.options.ticks;let e,{maxTicksLimit:i,stepSize:s}=t;return s?(e=Math.ceil(this.max/s)-Math.floor(this.min/s)+1,e>1e3&&(console.warn(`scales.${this.id}.ticks.stepSize: ${s} would result generating up to ${e} ticks. Limiting to 1000.`),e=1e3)):(e=this.computeTickLimit(),i=i||11),i&&(e=Math.min(i,e)),e}computeTickLimit(){return Number.POSITIVE_INFINITY}buildTicks(){const t=this.options,e=t.ticks;let i=this.getTickLimit();i=Math.max(2,i);const n=function(t,e){const i=[],{bounds:n,step:o,min:a,max:r,precision:l,count:h,maxTicks:c,maxDigits:d,includeBounds:u}=t,f=o||1,g=c-1,{min:p,max:m}=e,x=!s(a),b=!s(r),_=!s(h),y=(m-p)/(d+1);let v,M,w,k,S=B((m-p)/g/f)*f;if(S<1e-14&&!x&&!b)return[{value:p},{value:m}];k=Math.ceil(m/S)-Math.floor(p/S),k>g&&(S=B(k*S/g/f)*f),s(l)||(v=Math.pow(10,l),S=Math.ceil(S*v)/v),"ticks"===n?(M=Math.floor(p/S)*S,w=Math.ceil(m/S)*S):(M=p,w=m),x&&b&&o&&H((r-a)/o,S/1e3)?(k=Math.round(Math.min((r-a)/S,c)),S=(r-a)/k,M=a,w=r):_?(M=x?a:M,w=b?r:w,k=h-1,S=(w-M)/k):(k=(w-M)/S,k=V(k,Math.round(k),S/1e3)?Math.round(k):Math.ceil(k));const P=Math.max(U(S),U(M));v=Math.pow(10,s(l)?P:l),M=Math.round(M*v)/v,w=Math.round(w*v)/v;let D=0;for(x&&(u&&M!==a?(i.push({value:a}),Mr)break;i.push({value:t})}return b&&u&&w!==r?i.length&&V(i[i.length-1].value,r,xo(r,y,t))?i[i.length-1].value=r:i.push({value:r}):b&&w!==r||i.push({value:w}),i}({maxTicks:i,bounds:t.bounds,min:t.min,max:t.max,precision:e.precision,step:e.stepSize,count:e.count,maxDigits:this._maxDigits(),horizontal:this.isHorizontal(),minRotation:e.minRotation||0,includeBounds:!1!==e.includeBounds},this._range||this);return"ticks"===t.bounds&&j(n,this,"value"),t.reverse?(n.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),n}configure(){const t=this.ticks;let e=this.min,i=this.max;if(super.configure(),this.options.offset&&t.length){const s=(i-e)/Math.max(t.length-1,1)/2;e-=s,i+=s}this._startValue=e,this._endValue=i,this._valueRange=i-e}getLabelForValue(t){return ne(t,this.chart.options.locale,this.options.ticks.format)}}class _o extends bo{static id="linear";static defaults={ticks:{callback:ae.formatters.numeric}};determineDataLimits(){const{min:t,max:e}=this.getMinMax(!0);this.min=a(t)?t:0,this.max=a(e)?e:1,this.handleTickRangeOptions()}computeTickLimit(){const t=this.isHorizontal(),e=t?this.width:this.height,i=$(this.options.ticks.minRotation),s=(t?Math.sin(i):Math.cos(i))||.001,n=this._resolveTickFontOptions(0);return Math.ceil(e/Math.min(40,n.lineHeight/s))}getPixelForValue(t){return null===t?NaN:this.getPixelForDecimal((t-this._startValue)/this._valueRange)}getValueForPixel(t){return this._startValue+this.getDecimalForPixel(t)*this._valueRange}}const yo=t=>Math.floor(z(t)),vo=(t,e)=>Math.pow(10,yo(t)+e);function Mo(t){return 1===t/Math.pow(10,yo(t))}function wo(t,e,i){const s=Math.pow(10,i),n=Math.floor(t/s);return Math.ceil(e/s)-n}function ko(t,{min:e,max:i}){e=r(t.min,e);const s=[],n=yo(e);let o=function(t,e){let i=yo(e-t);for(;wo(t,e,i)>10;)i++;for(;wo(t,e,i)<10;)i--;return Math.min(i,yo(t))}(e,i),a=o<0?Math.pow(10,Math.abs(o)):1;const l=Math.pow(10,o),h=n>o?Math.pow(10,n):0,c=Math.round((e-h)*a)/a,d=Math.floor((e-h)/l/10)*l*10;let u=Math.floor((c-d)/Math.pow(10,o)),f=r(t.min,Math.round((h+d+u*Math.pow(10,o))*a)/a);for(;f=10?u=u<15?15:20:u++,u>=20&&(o++,u=2,a=o>=0?1:a),f=Math.round((h+d+u*Math.pow(10,o))*a)/a;const g=r(t.max,f);return s.push({value:g,major:Mo(g),significand:u}),s}class So extends tn{static id="logarithmic";static defaults={ticks:{callback:ae.formatters.logarithmic,major:{enabled:!0}}};constructor(t){super(t),this.start=void 0,this.end=void 0,this._startValue=void 0,this._valueRange=0}parse(t,e){const i=bo.prototype.parse.apply(this,[t,e]);if(0!==i)return a(i)&&i>0?i:null;this._zero=!0}determineDataLimits(){const{min:t,max:e}=this.getMinMax(!0);this.min=a(t)?Math.max(0,t):null,this.max=a(e)?Math.max(0,e):null,this.options.beginAtZero&&(this._zero=!0),this._zero&&this.min!==this._suggestedMin&&!a(this._userMin)&&(this.min=t===vo(this.min,0)?vo(this.min,-1):vo(this.min,0)),this.handleTickRangeOptions()}handleTickRangeOptions(){const{minDefined:t,maxDefined:e}=this.getUserBounds();let i=this.min,s=this.max;const n=e=>i=t?i:e,o=t=>s=e?s:t;i===s&&(i<=0?(n(1),o(10)):(n(vo(i,-1)),o(vo(s,1)))),i<=0&&n(vo(s,-1)),s<=0&&o(vo(i,1)),this.min=i,this.max=s}buildTicks(){const t=this.options,e=ko({min:this._userMin,max:this._userMax},this);return"ticks"===t.bounds&&j(e,this,"value"),t.reverse?(e.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),e}getLabelForValue(t){return void 0===t?"0":ne(t,this.chart.options.locale,this.options.ticks.format)}configure(){const t=this.min;super.configure(),this._startValue=z(t),this._valueRange=z(this.max)-z(t)}getPixelForValue(t){return void 0!==t&&0!==t||(t=this.min),null===t||isNaN(t)?NaN:this.getPixelForDecimal(t===this.min?0:(z(t)-this._startValue)/this._valueRange)}getValueForPixel(t){const e=this.getDecimalForPixel(t);return Math.pow(10,this._startValue+e*this._valueRange)}}function Po(t){const e=t.ticks;if(e.display&&t.display){const t=ki(e.backdropPadding);return l(e.font&&e.font.size,ue.font.size)+t.height}return 0}function Do(t,e,i,s,n){return t===s||t===n?{start:e-i/2,end:e+i/2}:tn?{start:e-i,end:e}:{start:e,end:e+i}}function Co(t){const e={l:t.left+t._padding.left,r:t.right-t._padding.right,t:t.top+t._padding.top,b:t.bottom-t._padding.bottom},i=Object.assign({},e),s=[],o=[],a=t._pointLabels.length,r=t.options.pointLabels,l=r.centerPointLabels?C/a:0;for(let u=0;ue.r&&(r=(s.end-e.r)/o,t.r=Math.max(t.r,e.r+r)),n.starte.b&&(l=(n.end-e.b)/a,t.b=Math.max(t.b,e.b+l))}function Ao(t,e,i){const s=t.drawingArea,{extra:n,additionalAngle:o,padding:a,size:r}=i,l=t.getPointPosition(e,s+n+a,o),h=Math.round(Y(G(l.angle+E))),c=function(t,e,i){90===i||270===i?t-=e/2:(i>270||i<90)&&(t-=e);return t}(l.y,r.h,h),d=function(t){if(0===t||180===t)return"center";if(t<180)return"left";return"right"}(h),u=function(t,e,i){"right"===i?t-=e:"center"===i&&(t-=e/2);return t}(l.x,r.w,d);return{visible:!0,x:l.x,y:c,textAlign:d,left:u,top:c,right:u+r.w,bottom:c+r.h}}function To(t,e){if(!e)return!0;const{left:i,top:s,right:n,bottom:o}=t;return!(Re({x:i,y:s},e)||Re({x:i,y:o},e)||Re({x:n,y:s},e)||Re({x:n,y:o},e))}function Lo(t,e,i){const{left:n,top:o,right:a,bottom:r}=i,{backdropColor:l}=e;if(!s(l)){const i=wi(e.borderRadius),s=ki(e.backdropPadding);t.fillStyle=l;const h=n-s.left,c=o-s.top,d=a-n+s.width,u=r-o+s.height;Object.values(i).some((t=>0!==t))?(t.beginPath(),He(t,{x:h,y:c,w:d,h:u,radius:i}),t.fill()):t.fillRect(h,c,d,u)}}function Eo(t,e,i,s){const{ctx:n}=t;if(i)n.arc(t.xCenter,t.yCenter,e,0,O);else{let i=t.getPointPosition(0,e);n.moveTo(i.x,i.y);for(let o=1;ot,padding:5,centerPointLabels:!1}};static defaultRoutes={"angleLines.color":"borderColor","pointLabels.color":"color","ticks.color":"color"};static descriptors={angleLines:{_fallback:"grid"}};constructor(t){super(t),this.xCenter=void 0,this.yCenter=void 0,this.drawingArea=void 0,this._pointLabels=[],this._pointLabelItems=[]}setDimensions(){const t=this._padding=ki(Po(this.options)/2),e=this.width=this.maxWidth-t.width,i=this.height=this.maxHeight-t.height;this.xCenter=Math.floor(this.left+e/2+t.left),this.yCenter=Math.floor(this.top+i/2+t.top),this.drawingArea=Math.floor(Math.min(e,i)/2)}determineDataLimits(){const{min:t,max:e}=this.getMinMax(!1);this.min=a(t)&&!isNaN(t)?t:0,this.max=a(e)&&!isNaN(e)?e:0,this.handleTickRangeOptions()}computeTickLimit(){return Math.ceil(this.drawingArea/Po(this.options))}generateTickLabels(t){bo.prototype.generateTickLabels.call(this,t),this._pointLabels=this.getLabels().map(((t,e)=>{const i=d(this.options.pointLabels.callback,[t,e],this);return i||0===i?i:""})).filter(((t,e)=>this.chart.getDataVisibility(e)))}fit(){const t=this.options;t.display&&t.pointLabels.display?Co(this):this.setCenterPoint(0,0,0,0)}setCenterPoint(t,e,i,s){this.xCenter+=Math.floor((t-e)/2),this.yCenter+=Math.floor((i-s)/2),this.drawingArea-=Math.min(this.drawingArea/2,Math.max(t,e,i,s))}getIndexAngle(t){return G(t*(O/(this._pointLabels.length||1))+$(this.options.startAngle||0))}getDistanceFromCenterForValue(t){if(s(t))return NaN;const e=this.drawingArea/(this.max-this.min);return this.options.reverse?(this.max-t)*e:(t-this.min)*e}getValueForDistanceFromCenter(t){if(s(t))return NaN;const e=t/(this.drawingArea/(this.max-this.min));return this.options.reverse?this.max-e:this.min+e}getPointLabelContext(t){const e=this._pointLabels||[];if(t>=0&&t=0;n--){const e=t._pointLabelItems[n];if(!e.visible)continue;const o=s.setContext(t.getPointLabelContext(n));Lo(i,o,e);const a=Si(o.font),{x:r,y:l,textAlign:h}=e;Ne(i,t._pointLabels[n],r,l+a.lineHeight/2,a,{color:o.color,textAlign:h,textBaseline:"middle"})}}(this,o),s.display&&this.ticks.forEach(((t,e)=>{if(0!==e||0===e&&this.min<0){r=this.getDistanceFromCenterForValue(t.value);const i=this.getContext(e),a=s.setContext(i),l=n.setContext(i);!function(t,e,i,s,n){const o=t.ctx,a=e.circular,{color:r,lineWidth:l}=e;!a&&!s||!r||!l||i<0||(o.save(),o.strokeStyle=r,o.lineWidth=l,o.setLineDash(n.dash||[]),o.lineDashOffset=n.dashOffset,o.beginPath(),Eo(t,i,a,s),o.closePath(),o.stroke(),o.restore())}(this,a,r,o,l)}})),i.display){for(t.save(),a=o-1;a>=0;a--){const s=i.setContext(this.getPointLabelContext(a)),{color:n,lineWidth:o}=s;o&&n&&(t.lineWidth=o,t.strokeStyle=n,t.setLineDash(s.borderDash),t.lineDashOffset=s.borderDashOffset,r=this.getDistanceFromCenterForValue(e.reverse?this.min:this.max),l=this.getPointPosition(a,r),t.beginPath(),t.moveTo(this.xCenter,this.yCenter),t.lineTo(l.x,l.y),t.stroke())}t.restore()}}drawBorder(){}drawLabels(){const t=this.ctx,e=this.options,i=e.ticks;if(!i.display)return;const s=this.getIndexAngle(0);let n,o;t.save(),t.translate(this.xCenter,this.yCenter),t.rotate(s),t.textAlign="center",t.textBaseline="middle",this.ticks.forEach(((s,a)=>{if(0===a&&this.min>=0&&!e.reverse)return;const r=i.setContext(this.getContext(a)),l=Si(r.font);if(n=this.getDistanceFromCenterForValue(this.ticks[a].value),r.showLabelBackdrop){t.font=l.string,o=t.measureText(s.label).width,t.fillStyle=r.backdropColor;const e=ki(r.backdropPadding);t.fillRect(-o/2-e.left,-n-l.size/2-e.top,o+e.width,l.size+e.height)}Ne(t,s.label,0,-n,l,{color:r.color,strokeColor:r.textStrokeColor,strokeWidth:r.textStrokeWidth})})),t.restore()}drawTitle(){}}const Io={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},zo=Object.keys(Io);function Fo(t,e){return t-e}function Vo(t,e){if(s(e))return null;const i=t._adapter,{parser:n,round:o,isoWeekday:r}=t._parseOpts;let l=e;return"function"==typeof n&&(l=n(l)),a(l)||(l="string"==typeof n?i.parse(l,n):i.parse(l)),null===l?null:(o&&(l="week"!==o||!N(r)&&!0!==r?i.startOf(l,o):i.startOf(l,"isoWeek",r)),+l)}function Bo(t,e,i,s){const n=zo.length;for(let o=zo.indexOf(t);o=e?i[s]:i[n]]=!0}}else t[e]=!0}function No(t,e,i){const s=[],n={},o=e.length;let a,r;for(a=0;a=0&&(e[l].major=!0);return e}(t,s,n,i):s}class Ho extends tn{static id="time";static defaults={bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{source:"auto",callback:!1,major:{enabled:!1}}};constructor(t){super(t),this._cache={data:[],labels:[],all:[]},this._unit="day",this._majorUnit=void 0,this._offsets={},this._normalized=!1,this._parseOpts=void 0}init(t,e={}){const i=t.time||(t.time={}),s=this._adapter=new In._date(t.adapters.date);s.init(e),b(i.displayFormats,s.formats()),this._parseOpts={parser:i.parser,round:i.round,isoWeekday:i.isoWeekday},super.init(t),this._normalized=e.normalized}parse(t,e){return void 0===t?null:Vo(this,t)}beforeLayout(){super.beforeLayout(),this._cache={data:[],labels:[],all:[]}}determineDataLimits(){const t=this.options,e=this._adapter,i=t.time.unit||"day";let{min:s,max:n,minDefined:o,maxDefined:r}=this.getUserBounds();function l(t){o||isNaN(t.min)||(s=Math.min(s,t.min)),r||isNaN(t.max)||(n=Math.max(n,t.max))}o&&r||(l(this._getLabelBounds()),"ticks"===t.bounds&&"labels"===t.ticks.source||l(this.getMinMax(!1))),s=a(s)&&!isNaN(s)?s:+e.startOf(Date.now(),i),n=a(n)&&!isNaN(n)?n:+e.endOf(Date.now(),i)+1,this.min=Math.min(s,n-1),this.max=Math.max(s+1,n)}_getLabelBounds(){const t=this.getLabelTimestamps();let e=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;return t.length&&(e=t[0],i=t[t.length-1]),{min:e,max:i}}buildTicks(){const t=this.options,e=t.time,i=t.ticks,s="labels"===i.source?this.getLabelTimestamps():this._generate();"ticks"===t.bounds&&s.length&&(this.min=this._userMin||s[0],this.max=this._userMax||s[s.length-1]);const n=this.min,o=nt(s,n,this.max);return this._unit=e.unit||(i.autoSkip?Bo(e.minUnit,this.min,this.max,this._getLabelCapacity(n)):function(t,e,i,s,n){for(let o=zo.length-1;o>=zo.indexOf(i);o--){const i=zo[o];if(Io[i].common&&t._adapter.diff(n,s,i)>=e-1)return i}return zo[i?zo.indexOf(i):0]}(this,o.length,e.minUnit,this.min,this.max)),this._majorUnit=i.major.enabled&&"year"!==this._unit?function(t){for(let e=zo.indexOf(t)+1,i=zo.length;e+t.value)))}initOffsets(t=[]){let e,i,s=0,n=0;this.options.offset&&t.length&&(e=this.getDecimalForValue(t[0]),s=1===t.length?1-e:(this.getDecimalForValue(t[1])-e)/2,i=this.getDecimalForValue(t[t.length-1]),n=1===t.length?i:(i-this.getDecimalForValue(t[t.length-2]))/2);const o=t.length<3?.5:.25;s=Z(s,0,o),n=Z(n,0,o),this._offsets={start:s,end:n,factor:1/(s+1+n)}}_generate(){const t=this._adapter,e=this.min,i=this.max,s=this.options,n=s.time,o=n.unit||Bo(n.minUnit,e,i,this._getLabelCapacity(e)),a=l(s.ticks.stepSize,1),r="week"===o&&n.isoWeekday,h=N(r)||!0===r,c={};let d,u,f=e;if(h&&(f=+t.startOf(f,"isoWeek",r)),f=+t.startOf(f,h?"day":o),t.diff(i,e,o)>1e5*a)throw new Error(e+" and "+i+" are too far apart with stepSize of "+a+" "+o);const g="data"===s.ticks.source&&this.getDataTimestamps();for(d=f,u=0;d+t))}getLabelForValue(t){const e=this._adapter,i=this.options.time;return i.tooltipFormat?e.format(t,i.tooltipFormat):e.format(t,i.displayFormats.datetime)}format(t,e){const i=this.options.time.displayFormats,s=this._unit,n=e||i[s];return this._adapter.format(t,n)}_tickFormatFunction(t,e,i,s){const n=this.options,o=n.ticks.callback;if(o)return d(o,[t,e,i],this);const a=n.time.displayFormats,r=this._unit,l=this._majorUnit,h=r&&a[r],c=l&&a[l],u=i[e],f=l&&c&&u&&u.major;return this._adapter.format(t,s||(f?c:h))}generateTickLabels(t){let e,i,s;for(e=0,i=t.length;e0?a:1}getDataTimestamps(){let t,e,i=this._cache.data||[];if(i.length)return i;const s=this.getMatchingVisibleMetas();if(this._normalized&&s.length)return this._cache.data=s[0].controller.getAllParsedValues(this);for(t=0,e=s.length;t=t[r].pos&&e<=t[l].pos&&({lo:r,hi:l}=it(t,"pos",e)),({pos:s,time:o}=t[r]),({pos:n,time:a}=t[l])):(e>=t[r].time&&e<=t[l].time&&({lo:r,hi:l}=it(t,"time",e)),({time:s,pos:o}=t[r]),({time:n,pos:a}=t[l]));const h=n-s;return h?o+(a-o)*(e-s)/h:o}var $o=Object.freeze({__proto__:null,CategoryScale:class extends tn{static id="category";static defaults={ticks:{callback:mo}};constructor(t){super(t),this._startValue=void 0,this._valueRange=0,this._addedLabels=[]}init(t){const e=this._addedLabels;if(e.length){const t=this.getLabels();for(const{index:i,label:s}of e)t[i]===s&&t.splice(i,1);this._addedLabels=[]}super.init(t)}parse(t,e){if(s(t))return null;const i=this.getLabels();return((t,e)=>null===t?null:Z(Math.round(t),0,e))(e=isFinite(e)&&i[e]===t?e:po(i,t,l(e,t),this._addedLabels),i.length-1)}determineDataLimits(){const{minDefined:t,maxDefined:e}=this.getUserBounds();let{min:i,max:s}=this.getMinMax(!0);"ticks"===this.options.bounds&&(t||(i=0),e||(s=this.getLabels().length-1)),this.min=i,this.max=s}buildTicks(){const t=this.min,e=this.max,i=this.options.offset,s=[];let n=this.getLabels();n=0===t&&e===n.length-1?n:n.slice(t,e+1),this._valueRange=Math.max(n.length-(i?0:1),1),this._startValue=this.min-(i?.5:0);for(let i=t;i<=e;i++)s.push({value:i});return s}getLabelForValue(t){return mo.call(this,t)}configure(){super.configure(),this.isHorizontal()||(this._reversePixels=!this._reversePixels)}getPixelForValue(t){return"number"!=typeof t&&(t=this.parse(t)),null===t?NaN:this.getPixelForDecimal((t-this._startValue)/this._valueRange)}getPixelForTick(t){const e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getValueForPixel(t){return Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange)}getBasePixel(){return this.bottom}},LinearScale:_o,LogarithmicScale:So,RadialLinearScale:Ro,TimeScale:Ho,TimeSeriesScale:class extends Ho{static id="timeseries";static defaults=Ho.defaults;constructor(t){super(t),this._table=[],this._minPos=void 0,this._tableRange=void 0}initOffsets(){const t=this._getTimestampsForTable(),e=this._table=this.buildLookupTable(t);this._minPos=jo(e,this.min),this._tableRange=jo(e,this.max)-this._minPos,super.initOffsets(t)}buildLookupTable(t){const{min:e,max:i}=this,s=[],n=[];let o,a,r,l,h;for(o=0,a=t.length;o=e&&l<=i&&s.push(l);if(s.length<2)return[{time:e,pos:0},{time:i,pos:1}];for(o=0,a=s.length;ot-e))}_getTimestampsForTable(){let t=this._cache.all||[];if(t.length)return t;const e=this.getDataTimestamps(),i=this.getLabelTimestamps();return t=e.length&&i.length?this.normalize(e.concat(i)):e.length?e:i,t=this._cache.all=t,t}getDecimalForValue(t){return(jo(this._table,t)-this._minPos)/this._tableRange}getValueForPixel(t){const e=this._offsets,i=this.getDecimalForPixel(t)/e.factor-e.end;return jo(this._table,i*this._tableRange+this._minPos,!0)}}});const Yo=["rgb(54, 162, 235)","rgb(255, 99, 132)","rgb(255, 159, 64)","rgb(255, 205, 86)","rgb(75, 192, 192)","rgb(153, 102, 255)","rgb(201, 203, 207)"],Uo=Yo.map((t=>t.replace("rgb(","rgba(").replace(")",", 0.5)")));function Xo(t){return Yo[t%Yo.length]}function qo(t){return Uo[t%Uo.length]}function Ko(t){let e=0;return(i,s)=>{const n=t.getDatasetMeta(s).controller;n instanceof $n?e=function(t,e){return t.backgroundColor=t.data.map((()=>Xo(e++))),e}(i,e):n instanceof Yn?e=function(t,e){return t.backgroundColor=t.data.map((()=>qo(e++))),e}(i,e):n&&(e=function(t,e){return t.borderColor=Xo(e),t.backgroundColor=qo(e),++e}(i,e))}}function Go(t){let e;for(e in t)if(t[e].borderColor||t[e].backgroundColor)return!0;return!1}var Jo={id:"colors",defaults:{enabled:!0,forceOverride:!1},beforeLayout(t,e,i){if(!i.enabled)return;const{data:{datasets:s},options:n}=t.config,{elements:o}=n,a=Go(s)||(r=n)&&(r.borderColor||r.backgroundColor)||o&&Go(o)||"rgba(0,0,0,0.1)"!==ue.borderColor||"rgba(0,0,0,0.1)"!==ue.backgroundColor;var r;if(!i.forceOverride&&a)return;const l=Ko(t);s.forEach(l)}};function Zo(t){if(t._decimated){const e=t._data;delete t._decimated,delete t._data,Object.defineProperty(t,"data",{configurable:!0,enumerable:!0,writable:!0,value:e})}}function Qo(t){t.data.datasets.forEach((t=>{Zo(t)}))}var ta={id:"decimation",defaults:{algorithm:"min-max",enabled:!1},beforeElementsUpdate:(t,e,i)=>{if(!i.enabled)return void Qo(t);const n=t.width;t.data.datasets.forEach(((e,o)=>{const{_data:a,indexAxis:r}=e,l=t.getDatasetMeta(o),h=a||e.data;if("y"===Pi([r,t.options.indexAxis]))return;if(!l.controller.supportsDecimation)return;const c=t.scales[l.xAxisID];if("linear"!==c.type&&"time"!==c.type)return;if(t.options.parsing)return;let{start:d,count:u}=function(t,e){const i=e.length;let s,n=0;const{iScale:o}=t,{min:a,max:r,minDefined:l,maxDefined:h}=o.getUserBounds();return l&&(n=Z(it(e,o.axis,a).lo,0,i-1)),s=h?Z(it(e,o.axis,r).hi+1,n,i)-n:i-n,{start:n,count:s}}(l,h);if(u<=(i.threshold||4*n))return void Zo(e);let f;switch(s(a)&&(e._data=h,delete e.data,Object.defineProperty(e,"data",{configurable:!0,enumerable:!0,get:function(){return this._decimated},set:function(t){this._data=t}})),i.algorithm){case"lttb":f=function(t,e,i,s,n){const o=n.samples||s;if(o>=i)return t.slice(e,e+i);const a=[],r=(i-2)/(o-2);let l=0;const h=e+i-1;let c,d,u,f,g,p=e;for(a[l++]=t[p],c=0;cu&&(u=f,d=t[s],g=s);a[l++]=d,p=g}return a[l++]=t[h],a}(h,d,u,n,i);break;case"min-max":f=function(t,e,i,n){let o,a,r,l,h,c,d,u,f,g,p=0,m=0;const x=[],b=e+i-1,_=t[e].x,y=t[b].x-_;for(o=e;og&&(g=l,d=o),p=(m*p+a.x)/++m;else{const i=o-1;if(!s(c)&&!s(d)){const e=Math.min(c,d),s=Math.max(c,d);e!==u&&e!==i&&x.push({...t[e],x:p}),s!==u&&s!==i&&x.push({...t[s],x:p})}o>0&&i!==u&&x.push(t[i]),x.push(a),h=e,m=0,f=g=l,c=d=u=o}}return x}(h,d,u,n);break;default:throw new Error(`Unsupported decimation algorithm '${i.algorithm}'`)}e._decimated=f}))},destroy(t){Qo(t)}};function ea(t,e,i,s){if(s)return;let n=e[t],o=i[t];return"angle"===t&&(n=G(n),o=G(o)),{property:t,start:n,end:o}}function ia(t,e,i){for(;e>t;e--){const t=i[e];if(!isNaN(t.x)&&!isNaN(t.y))break}return e}function sa(t,e,i,s){return t&&e?s(t[i],e[i]):t?t[i]:e?e[i]:0}function na(t,e){let i=[],s=!1;return n(t)?(s=!0,i=t):i=function(t,e){const{x:i=null,y:s=null}=t||{},n=e.points,o=[];return e.segments.forEach((({start:t,end:e})=>{e=ia(t,e,n);const a=n[t],r=n[e];null!==s?(o.push({x:a.x,y:s}),o.push({x:r.x,y:s})):null!==i&&(o.push({x:i,y:a.y}),o.push({x:i,y:r.y}))})),o}(t,e),i.length?new oo({points:i,options:{tension:0},_loop:s,_fullLoop:s}):null}function oa(t){return t&&!1!==t.fill}function aa(t,e,i){let s=t[e].fill;const n=[e];let o;if(!i)return s;for(;!1!==s&&-1===n.indexOf(s);){if(!a(s))return s;if(o=t[s],!o)return!1;if(o.visible)return s;n.push(s),s=o.fill}return!1}function ra(t,e,i){const s=function(t){const e=t.options,i=e.fill;let s=l(i&&i.target,i);void 0===s&&(s=!!e.backgroundColor);if(!1===s||null===s)return!1;if(!0===s)return"origin";return s}(t);if(o(s))return!isNaN(s.value)&&s;let n=parseFloat(s);return a(n)&&Math.floor(n)===n?function(t,e,i,s){"-"!==t&&"+"!==t||(i=e+i);if(i===e||i<0||i>=s)return!1;return i}(s[0],e,n,i):["origin","start","end","stack","shape"].indexOf(s)>=0&&s}function la(t,e,i){const s=[];for(let n=0;n=0;--e){const i=n[e].$filler;i&&(i.line.updateControlPoints(o,i.axis),s&&i.fill&&ua(t.ctx,i,o))}},beforeDatasetsDraw(t,e,i){if("beforeDatasetsDraw"!==i.drawTime)return;const s=t.getSortedVisibleDatasetMetas();for(let e=s.length-1;e>=0;--e){const i=s[e].$filler;oa(i)&&ua(t.ctx,i,t.chartArea)}},beforeDatasetDraw(t,e,i){const s=e.meta.$filler;oa(s)&&"beforeDatasetDraw"===i.drawTime&&ua(t.ctx,s,t.chartArea)},defaults:{propagate:!0,drawTime:"beforeDatasetDraw"}};const _a=(t,e)=>{let{boxHeight:i=e,boxWidth:s=e}=t;return t.usePointStyle&&(i=Math.min(i,e),s=t.pointStyleWidth||Math.min(s,e)),{boxWidth:s,boxHeight:i,itemHeight:Math.max(e,i)}};class ya extends $s{constructor(t){super(),this._added=!1,this.legendHitBoxes=[],this._hoveredItem=null,this.doughnutMode=!1,this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this.legendItems=void 0,this.columnSizes=void 0,this.lineWidths=void 0,this.maxHeight=void 0,this.maxWidth=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.height=void 0,this.width=void 0,this._margins=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e,i){this.maxWidth=t,this.maxHeight=e,this._margins=i,this.setDimensions(),this.buildLabels(),this.fit()}setDimensions(){this.isHorizontal()?(this.width=this.maxWidth,this.left=this._margins.left,this.right=this.width):(this.height=this.maxHeight,this.top=this._margins.top,this.bottom=this.height)}buildLabels(){const t=this.options.labels||{};let e=d(t.generateLabels,[this.chart],this)||[];t.filter&&(e=e.filter((e=>t.filter(e,this.chart.data)))),t.sort&&(e=e.sort(((e,i)=>t.sort(e,i,this.chart.data)))),this.options.reverse&&e.reverse(),this.legendItems=e}fit(){const{options:t,ctx:e}=this;if(!t.display)return void(this.width=this.height=0);const i=t.labels,s=Si(i.font),n=s.size,o=this._computeTitleHeight(),{boxWidth:a,itemHeight:r}=_a(i,n);let l,h;e.font=s.string,this.isHorizontal()?(l=this.maxWidth,h=this._fitRows(o,n,a,r)+10):(h=this.maxHeight,l=this._fitCols(o,s,a,r)+10),this.width=Math.min(l,t.maxWidth||this.maxWidth),this.height=Math.min(h,t.maxHeight||this.maxHeight)}_fitRows(t,e,i,s){const{ctx:n,maxWidth:o,options:{labels:{padding:a}}}=this,r=this.legendHitBoxes=[],l=this.lineWidths=[0],h=s+a;let c=t;n.textAlign="left",n.textBaseline="middle";let d=-1,u=-h;return this.legendItems.forEach(((t,f)=>{const g=i+e/2+n.measureText(t.text).width;(0===f||l[l.length-1]+g+2*a>o)&&(c+=h,l[l.length-(f>0?0:1)]=0,u+=h,d++),r[f]={left:0,top:u,row:d,width:g,height:s},l[l.length-1]+=g+a})),c}_fitCols(t,e,i,s){const{ctx:n,maxHeight:o,options:{labels:{padding:a}}}=this,r=this.legendHitBoxes=[],l=this.columnSizes=[],h=o-t;let c=a,d=0,u=0,f=0,g=0;return this.legendItems.forEach(((t,o)=>{const{itemWidth:p,itemHeight:m}=function(t,e,i,s,n){const o=function(t,e,i,s){let n=t.text;n&&"string"!=typeof n&&(n=n.reduce(((t,e)=>t.length>e.length?t:e)));return e+i.size/2+s.measureText(n).width}(s,t,e,i),a=function(t,e,i){let s=t;"string"!=typeof e.text&&(s=va(e,i));return s}(n,s,e.lineHeight);return{itemWidth:o,itemHeight:a}}(i,e,n,t,s);o>0&&u+m+2*a>h&&(c+=d+a,l.push({width:d,height:u}),f+=d+a,g++,d=u=0),r[o]={left:f,top:u,col:g,width:p,height:m},d=Math.max(d,p),u+=m+a})),c+=d,l.push({width:d,height:u}),c}adjustHitBoxes(){if(!this.options.display)return;const t=this._computeTitleHeight(),{legendHitBoxes:e,options:{align:i,labels:{padding:s},rtl:n}}=this,o=Oi(n,this.left,this.width);if(this.isHorizontal()){let n=0,a=ft(i,this.left+s,this.right-this.lineWidths[n]);for(const r of e)n!==r.row&&(n=r.row,a=ft(i,this.left+s,this.right-this.lineWidths[n])),r.top+=this.top+t+s,r.left=o.leftForLtr(o.x(a),r.width),a+=r.width+s}else{let n=0,a=ft(i,this.top+t+s,this.bottom-this.columnSizes[n].height);for(const r of e)r.col!==n&&(n=r.col,a=ft(i,this.top+t+s,this.bottom-this.columnSizes[n].height)),r.top=a,r.left+=this.left+s,r.left=o.leftForLtr(o.x(r.left),r.width),a+=r.height+s}}isHorizontal(){return"top"===this.options.position||"bottom"===this.options.position}draw(){if(this.options.display){const t=this.ctx;Ie(t,this),this._draw(),ze(t)}}_draw(){const{options:t,columnSizes:e,lineWidths:i,ctx:s}=this,{align:n,labels:o}=t,a=ue.color,r=Oi(t.rtl,this.left,this.width),h=Si(o.font),{padding:c}=o,d=h.size,u=d/2;let f;this.drawTitle(),s.textAlign=r.textAlign("left"),s.textBaseline="middle",s.lineWidth=.5,s.font=h.string;const{boxWidth:g,boxHeight:p,itemHeight:m}=_a(o,d),x=this.isHorizontal(),b=this._computeTitleHeight();f=x?{x:ft(n,this.left+c,this.right-i[0]),y:this.top+c+b,line:0}:{x:this.left+c,y:ft(n,this.top+b+c,this.bottom-e[0].height),line:0},Ai(this.ctx,t.textDirection);const _=m+c;this.legendItems.forEach(((y,v)=>{s.strokeStyle=y.fontColor,s.fillStyle=y.fontColor;const M=s.measureText(y.text).width,w=r.textAlign(y.textAlign||(y.textAlign=o.textAlign)),k=g+u+M;let S=f.x,P=f.y;r.setWidth(this.width),x?v>0&&S+k+c>this.right&&(P=f.y+=_,f.line++,S=f.x=ft(n,this.left+c,this.right-i[f.line])):v>0&&P+_>this.bottom&&(S=f.x=S+e[f.line].width+c,f.line++,P=f.y=ft(n,this.top+b+c,this.bottom-e[f.line].height));if(function(t,e,i){if(isNaN(g)||g<=0||isNaN(p)||p<0)return;s.save();const n=l(i.lineWidth,1);if(s.fillStyle=l(i.fillStyle,a),s.lineCap=l(i.lineCap,"butt"),s.lineDashOffset=l(i.lineDashOffset,0),s.lineJoin=l(i.lineJoin,"miter"),s.lineWidth=n,s.strokeStyle=l(i.strokeStyle,a),s.setLineDash(l(i.lineDash,[])),o.usePointStyle){const a={radius:p*Math.SQRT2/2,pointStyle:i.pointStyle,rotation:i.rotation,borderWidth:n},l=r.xPlus(t,g/2);Ee(s,a,l,e+u,o.pointStyleWidth&&g)}else{const o=e+Math.max((d-p)/2,0),a=r.leftForLtr(t,g),l=wi(i.borderRadius);s.beginPath(),Object.values(l).some((t=>0!==t))?He(s,{x:a,y:o,w:g,h:p,radius:l}):s.rect(a,o,g,p),s.fill(),0!==n&&s.stroke()}s.restore()}(r.x(S),P,y),S=gt(w,S+g+u,x?S+k:this.right,t.rtl),function(t,e,i){Ne(s,i.text,t,e+m/2,h,{strikethrough:i.hidden,textAlign:r.textAlign(i.textAlign)})}(r.x(S),P,y),x)f.x+=k+c;else if("string"!=typeof y.text){const t=h.lineHeight;f.y+=va(y,t)+c}else f.y+=_})),Ti(this.ctx,t.textDirection)}drawTitle(){const t=this.options,e=t.title,i=Si(e.font),s=ki(e.padding);if(!e.display)return;const n=Oi(t.rtl,this.left,this.width),o=this.ctx,a=e.position,r=i.size/2,l=s.top+r;let h,c=this.left,d=this.width;if(this.isHorizontal())d=Math.max(...this.lineWidths),h=this.top+l,c=ft(t.align,c,this.right-d);else{const e=this.columnSizes.reduce(((t,e)=>Math.max(t,e.height)),0);h=l+ft(t.align,this.top,this.bottom-e-t.labels.padding-this._computeTitleHeight())}const u=ft(a,c,c+d);o.textAlign=n.textAlign(ut(a)),o.textBaseline="middle",o.strokeStyle=e.color,o.fillStyle=e.color,o.font=i.string,Ne(o,e.text,u,h,i)}_computeTitleHeight(){const t=this.options.title,e=Si(t.font),i=ki(t.padding);return t.display?e.lineHeight+i.height:0}_getLegendItemAt(t,e){let i,s,n;if(tt(t,this.left,this.right)&&tt(e,this.top,this.bottom))for(n=this.legendHitBoxes,i=0;it.chart.options.color,boxWidth:40,padding:10,generateLabels(t){const e=t.data.datasets,{labels:{usePointStyle:i,pointStyle:s,textAlign:n,color:o,useBorderRadius:a,borderRadius:r}}=t.legend.options;return t._getSortedDatasetMetas().map((t=>{const l=t.controller.getStyle(i?0:void 0),h=ki(l.borderWidth);return{text:e[t.index].label,fillStyle:l.backgroundColor,fontColor:o,hidden:!t.visible,lineCap:l.borderCapStyle,lineDash:l.borderDash,lineDashOffset:l.borderDashOffset,lineJoin:l.borderJoinStyle,lineWidth:(h.width+h.height)/4,strokeStyle:l.borderColor,pointStyle:s||l.pointStyle,rotation:l.rotation,textAlign:n||l.textAlign,borderRadius:a&&(r||l.borderRadius),datasetIndex:t.index}}),this)}},title:{color:t=>t.chart.options.color,display:!1,position:"center",text:""}},descriptors:{_scriptable:t=>!t.startsWith("on"),labels:{_scriptable:t=>!["generateLabels","filter","sort"].includes(t)}}};class wa extends $s{constructor(t){super(),this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this._padding=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e){const i=this.options;if(this.left=0,this.top=0,!i.display)return void(this.width=this.height=this.right=this.bottom=0);this.width=this.right=t,this.height=this.bottom=e;const s=n(i.text)?i.text.length:1;this._padding=ki(i.padding);const o=s*Si(i.font).lineHeight+this._padding.height;this.isHorizontal()?this.height=o:this.width=o}isHorizontal(){const t=this.options.position;return"top"===t||"bottom"===t}_drawArgs(t){const{top:e,left:i,bottom:s,right:n,options:o}=this,a=o.align;let r,l,h,c=0;return this.isHorizontal()?(l=ft(a,i,n),h=e+t,r=n-i):("left"===o.position?(l=i+t,h=ft(a,s,e),c=-.5*C):(l=n-t,h=ft(a,e,s),c=.5*C),r=s-e),{titleX:l,titleY:h,maxWidth:r,rotation:c}}draw(){const t=this.ctx,e=this.options;if(!e.display)return;const i=Si(e.font),s=i.lineHeight/2+this._padding.top,{titleX:n,titleY:o,maxWidth:a,rotation:r}=this._drawArgs(s);Ne(t,e.text,0,0,i,{color:e.color,maxWidth:a,rotation:r,textAlign:ut(e.align),textBaseline:"middle",translation:[n,o]})}}var ka={id:"title",_element:wa,start(t,e,i){!function(t,e){const i=new wa({ctx:t.ctx,options:e,chart:t});ls.configure(t,i,e),ls.addBox(t,i),t.titleBlock=i}(t,i)},stop(t){const e=t.titleBlock;ls.removeBox(t,e),delete t.titleBlock},beforeUpdate(t,e,i){const s=t.titleBlock;ls.configure(t,s,i),s.options=i},defaults:{align:"center",display:!1,font:{weight:"bold"},fullSize:!0,padding:10,position:"top",text:"",weight:2e3},defaultRoutes:{color:"color"},descriptors:{_scriptable:!0,_indexable:!1}};const Sa=new WeakMap;var Pa={id:"subtitle",start(t,e,i){const s=new wa({ctx:t.ctx,options:i,chart:t});ls.configure(t,s,i),ls.addBox(t,s),Sa.set(t,s)},stop(t){ls.removeBox(t,Sa.get(t)),Sa.delete(t)},beforeUpdate(t,e,i){const s=Sa.get(t);ls.configure(t,s,i),s.options=i},defaults:{align:"center",display:!1,font:{weight:"normal"},fullSize:!0,padding:0,position:"top",text:"",weight:1500},defaultRoutes:{color:"color"},descriptors:{_scriptable:!0,_indexable:!1}};const Da={average(t){if(!t.length)return!1;let e,i,s=new Set,n=0,o=0;for(e=0,i=t.length;et+e))/s.size,y:n/o}},nearest(t,e){if(!t.length)return!1;let i,s,n,o=e.x,a=e.y,r=Number.POSITIVE_INFINITY;for(i=0,s=t.length;i-1?t.split("\n"):t}function Aa(t,e){const{element:i,datasetIndex:s,index:n}=e,o=t.getDatasetMeta(s).controller,{label:a,value:r}=o.getLabelAndValue(n);return{chart:t,label:a,parsed:o.getParsed(n),raw:t.data.datasets[s].data[n],formattedValue:r,dataset:o.getDataset(),dataIndex:n,datasetIndex:s,element:i}}function Ta(t,e){const i=t.chart.ctx,{body:s,footer:n,title:o}=t,{boxWidth:a,boxHeight:r}=e,l=Si(e.bodyFont),h=Si(e.titleFont),c=Si(e.footerFont),d=o.length,f=n.length,g=s.length,p=ki(e.padding);let m=p.height,x=0,b=s.reduce(((t,e)=>t+e.before.length+e.lines.length+e.after.length),0);if(b+=t.beforeBody.length+t.afterBody.length,d&&(m+=d*h.lineHeight+(d-1)*e.titleSpacing+e.titleMarginBottom),b){m+=g*(e.displayColors?Math.max(r,l.lineHeight):l.lineHeight)+(b-g)*l.lineHeight+(b-1)*e.bodySpacing}f&&(m+=e.footerMarginTop+f*c.lineHeight+(f-1)*e.footerSpacing);let _=0;const y=function(t){x=Math.max(x,i.measureText(t).width+_)};return i.save(),i.font=h.string,u(t.title,y),i.font=l.string,u(t.beforeBody.concat(t.afterBody),y),_=e.displayColors?a+2+e.boxPadding:0,u(s,(t=>{u(t.before,y),u(t.lines,y),u(t.after,y)})),_=0,i.font=c.string,u(t.footer,y),i.restore(),x+=p.width,{width:x,height:m}}function La(t,e,i,s){const{x:n,width:o}=i,{width:a,chartArea:{left:r,right:l}}=t;let h="center";return"center"===s?h=n<=(r+l)/2?"left":"right":n<=o/2?h="left":n>=a-o/2&&(h="right"),function(t,e,i,s){const{x:n,width:o}=s,a=i.caretSize+i.caretPadding;return"left"===t&&n+o+a>e.width||"right"===t&&n-o-a<0||void 0}(h,t,e,i)&&(h="center"),h}function Ea(t,e,i){const s=i.yAlign||e.yAlign||function(t,e){const{y:i,height:s}=e;return it.height-s/2?"bottom":"center"}(t,i);return{xAlign:i.xAlign||e.xAlign||La(t,e,i,s),yAlign:s}}function Ra(t,e,i,s){const{caretSize:n,caretPadding:o,cornerRadius:a}=t,{xAlign:r,yAlign:l}=i,h=n+o,{topLeft:c,topRight:d,bottomLeft:u,bottomRight:f}=wi(a);let g=function(t,e){let{x:i,width:s}=t;return"right"===e?i-=s:"center"===e&&(i-=s/2),i}(e,r);const p=function(t,e,i){let{y:s,height:n}=t;return"top"===e?s+=i:s-="bottom"===e?n+i:n/2,s}(e,l,h);return"center"===l?"left"===r?g+=h:"right"===r&&(g-=h):"left"===r?g-=Math.max(c,u)+n:"right"===r&&(g+=Math.max(d,f)+n),{x:Z(g,0,s.width-e.width),y:Z(p,0,s.height-e.height)}}function Ia(t,e,i){const s=ki(i.padding);return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-s.right:t.x+s.left}function za(t){return Ca([],Oa(t))}function Fa(t,e){const i=e&&e.dataset&&e.dataset.tooltip&&e.dataset.tooltip.callbacks;return i?t.override(i):t}const Va={beforeTitle:e,title(t){if(t.length>0){const e=t[0],i=e.chart.data.labels,s=i?i.length:0;if(this&&this.options&&"dataset"===this.options.mode)return e.dataset.label||"";if(e.label)return e.label;if(s>0&&e.dataIndex{const e={before:[],lines:[],after:[]},n=Fa(i,t);Ca(e.before,Oa(Ba(n,"beforeLabel",this,t))),Ca(e.lines,Ba(n,"label",this,t)),Ca(e.after,Oa(Ba(n,"afterLabel",this,t))),s.push(e)})),s}getAfterBody(t,e){return za(Ba(e.callbacks,"afterBody",this,t))}getFooter(t,e){const{callbacks:i}=e,s=Ba(i,"beforeFooter",this,t),n=Ba(i,"footer",this,t),o=Ba(i,"afterFooter",this,t);let a=[];return a=Ca(a,Oa(s)),a=Ca(a,Oa(n)),a=Ca(a,Oa(o)),a}_createItems(t){const e=this._active,i=this.chart.data,s=[],n=[],o=[];let a,r,l=[];for(a=0,r=e.length;at.filter(e,s,n,i)))),t.itemSort&&(l=l.sort(((e,s)=>t.itemSort(e,s,i)))),u(l,(e=>{const i=Fa(t.callbacks,e);s.push(Ba(i,"labelColor",this,e)),n.push(Ba(i,"labelPointStyle",this,e)),o.push(Ba(i,"labelTextColor",this,e))})),this.labelColors=s,this.labelPointStyles=n,this.labelTextColors=o,this.dataPoints=l,l}update(t,e){const i=this.options.setContext(this.getContext()),s=this._active;let n,o=[];if(s.length){const t=Da[i.position].call(this,s,this._eventPosition);o=this._createItems(i),this.title=this.getTitle(o,i),this.beforeBody=this.getBeforeBody(o,i),this.body=this.getBody(o,i),this.afterBody=this.getAfterBody(o,i),this.footer=this.getFooter(o,i);const e=this._size=Ta(this,i),a=Object.assign({},t,e),r=Ea(this.chart,i,a),l=Ra(i,a,r,this.chart);this.xAlign=r.xAlign,this.yAlign=r.yAlign,n={opacity:1,x:l.x,y:l.y,width:e.width,height:e.height,caretX:t.x,caretY:t.y}}else 0!==this.opacity&&(n={opacity:0});this._tooltipItems=o,this.$context=void 0,n&&this._resolveAnimations().update(this,n),t&&i.external&&i.external.call(this,{chart:this.chart,tooltip:this,replay:e})}drawCaret(t,e,i,s){const n=this.getCaretPosition(t,i,s);e.lineTo(n.x1,n.y1),e.lineTo(n.x2,n.y2),e.lineTo(n.x3,n.y3)}getCaretPosition(t,e,i){const{xAlign:s,yAlign:n}=this,{caretSize:o,cornerRadius:a}=i,{topLeft:r,topRight:l,bottomLeft:h,bottomRight:c}=wi(a),{x:d,y:u}=t,{width:f,height:g}=e;let p,m,x,b,_,y;return"center"===n?(_=u+g/2,"left"===s?(p=d,m=p-o,b=_+o,y=_-o):(p=d+f,m=p+o,b=_-o,y=_+o),x=p):(m="left"===s?d+Math.max(r,h)+o:"right"===s?d+f-Math.max(l,c)-o:this.caretX,"top"===n?(b=u,_=b-o,p=m-o,x=m+o):(b=u+g,_=b+o,p=m+o,x=m-o),y=b),{x1:p,x2:m,x3:x,y1:b,y2:_,y3:y}}drawTitle(t,e,i){const s=this.title,n=s.length;let o,a,r;if(n){const l=Oi(i.rtl,this.x,this.width);for(t.x=Ia(this,i.titleAlign,i),e.textAlign=l.textAlign(i.titleAlign),e.textBaseline="middle",o=Si(i.titleFont),a=i.titleSpacing,e.fillStyle=i.titleColor,e.font=o.string,r=0;r0!==t))?(t.beginPath(),t.fillStyle=n.multiKeyBackground,He(t,{x:e,y:g,w:h,h:l,radius:r}),t.fill(),t.stroke(),t.fillStyle=a.backgroundColor,t.beginPath(),He(t,{x:i,y:g+1,w:h-2,h:l-2,radius:r}),t.fill()):(t.fillStyle=n.multiKeyBackground,t.fillRect(e,g,h,l),t.strokeRect(e,g,h,l),t.fillStyle=a.backgroundColor,t.fillRect(i,g+1,h-2,l-2))}t.fillStyle=this.labelTextColors[i]}drawBody(t,e,i){const{body:s}=this,{bodySpacing:n,bodyAlign:o,displayColors:a,boxHeight:r,boxWidth:l,boxPadding:h}=i,c=Si(i.bodyFont);let d=c.lineHeight,f=0;const g=Oi(i.rtl,this.x,this.width),p=function(i){e.fillText(i,g.x(t.x+f),t.y+d/2),t.y+=d+n},m=g.textAlign(o);let x,b,_,y,v,M,w;for(e.textAlign=o,e.textBaseline="middle",e.font=c.string,t.x=Ia(this,m,i),e.fillStyle=i.bodyColor,u(this.beforeBody,p),f=a&&"right"!==m?"center"===o?l/2+h:l+2+h:0,y=0,M=s.length;y0&&e.stroke()}_updateAnimationTarget(t){const e=this.chart,i=this.$animations,s=i&&i.x,n=i&&i.y;if(s||n){const i=Da[t.position].call(this,this._active,this._eventPosition);if(!i)return;const o=this._size=Ta(this,t),a=Object.assign({},i,this._size),r=Ea(e,t,a),l=Ra(t,a,r,e);s._to===l.x&&n._to===l.y||(this.xAlign=r.xAlign,this.yAlign=r.yAlign,this.width=o.width,this.height=o.height,this.caretX=i.x,this.caretY=i.y,this._resolveAnimations().update(this,l))}}_willRender(){return!!this.opacity}draw(t){const e=this.options.setContext(this.getContext());let i=this.opacity;if(!i)return;this._updateAnimationTarget(e);const s={width:this.width,height:this.height},n={x:this.x,y:this.y};i=Math.abs(i)<.001?0:i;const o=ki(e.padding),a=this.title.length||this.beforeBody.length||this.body.length||this.afterBody.length||this.footer.length;e.enabled&&a&&(t.save(),t.globalAlpha=i,this.drawBackground(n,t,s,e),Ai(t,e.textDirection),n.y+=o.top,this.drawTitle(n,t,e),this.drawBody(n,t,e),this.drawFooter(n,t,e),Ti(t,e.textDirection),t.restore())}getActiveElements(){return this._active||[]}setActiveElements(t,e){const i=this._active,s=t.map((({datasetIndex:t,index:e})=>{const i=this.chart.getDatasetMeta(t);if(!i)throw new Error("Cannot find a dataset at index "+t);return{datasetIndex:t,element:i.data[e],index:e}})),n=!f(i,s),o=this._positionChanged(s,e);(n||o)&&(this._active=s,this._eventPosition=e,this._ignoreReplayEvents=!0,this.update(!0))}handleEvent(t,e,i=!0){if(e&&this._ignoreReplayEvents)return!1;this._ignoreReplayEvents=!1;const s=this.options,n=this._active||[],o=this._getActiveElements(t,n,e,i),a=this._positionChanged(o,t),r=e||!f(o,n)||a;return r&&(this._active=o,(s.enabled||s.external)&&(this._eventPosition={x:t.x,y:t.y},this.update(!0,e))),r}_getActiveElements(t,e,i,s){const n=this.options;if("mouseout"===t.type)return[];if(!s)return e.filter((t=>this.chart.data.datasets[t.datasetIndex]&&void 0!==this.chart.getDatasetMeta(t.datasetIndex).controller.getParsed(t.index)));const o=this.chart.getElementsAtEventForMode(t,n.mode,n,i);return n.reverse&&o.reverse(),o}_positionChanged(t,e){const{caretX:i,caretY:s,options:n}=this,o=Da[n.position].call(this,t,e);return!1!==o&&(i!==o.x||s!==o.y)}}var Na={id:"tooltip",_element:Wa,positioners:Da,afterInit(t,e,i){i&&(t.tooltip=new Wa({chart:t,options:i}))},beforeUpdate(t,e,i){t.tooltip&&t.tooltip.initialize(i)},reset(t,e,i){t.tooltip&&t.tooltip.initialize(i)},afterDraw(t){const e=t.tooltip;if(e&&e._willRender()){const i={tooltip:e};if(!1===t.notifyPlugins("beforeTooltipDraw",{...i,cancelable:!0}))return;e.draw(t.ctx),t.notifyPlugins("afterTooltipDraw",i)}},afterEvent(t,e){if(t.tooltip){const i=e.replay;t.tooltip.handleEvent(e.event,i,e.inChartArea)&&(e.changed=!0)}},defaults:{enabled:!0,external:null,position:"average",backgroundColor:"rgba(0,0,0,0.8)",titleColor:"#fff",titleFont:{weight:"bold"},titleSpacing:2,titleMarginBottom:6,titleAlign:"left",bodyColor:"#fff",bodySpacing:2,bodyFont:{},bodyAlign:"left",footerColor:"#fff",footerSpacing:2,footerMarginTop:6,footerFont:{weight:"bold"},footerAlign:"left",padding:6,caretPadding:2,caretSize:5,cornerRadius:6,boxHeight:(t,e)=>e.bodyFont.size,boxWidth:(t,e)=>e.bodyFont.size,multiKeyBackground:"#fff",displayColors:!0,boxPadding:0,borderColor:"rgba(0,0,0,0)",borderWidth:0,animation:{duration:400,easing:"easeOutQuart"},animations:{numbers:{type:"number",properties:["x","y","width","height","caretX","caretY"]},opacity:{easing:"linear",duration:200}},callbacks:Va},defaultRoutes:{bodyFont:"font",footerFont:"font",titleFont:"font"},descriptors:{_scriptable:t=>"filter"!==t&&"itemSort"!==t&&"external"!==t,_indexable:!1,callbacks:{_scriptable:!1,_indexable:!1},animation:{_fallback:!1},animations:{_fallback:"animation"}},additionalOptionScopes:["interaction"]};return Tn.register(Un,$o,go,t),Tn.helpers={...Hi},Tn._adapters=In,Tn.Animation=As,Tn.Animations=Ts,Tn.animator=bt,Tn.controllers=nn.controllers.items,Tn.DatasetController=js,Tn.Element=$s,Tn.elements=go,Tn.Interaction=Ki,Tn.layouts=ls,Tn.platforms=Ds,Tn.Scale=tn,Tn.Ticks=ae,Object.assign(Tn,Un,$o,go,t,Ds),Tn.Chart=Tn,"undefined"!=typeof window&&(window.Chart=Tn),Tn})); +//# sourceMappingURL=chart.umd.min.js.map diff --git a/static/js/echarts.min.js b/static/js/echarts.min.js new file mode 100644 index 0000000..3b8ed4b --- /dev/null +++ b/static/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:!r.hasGlobalWindow||"Deno"in window||"undefined"!=typeof navigator&&"string"==typeof navigator.userAgent&&navigator.userAgent.indexOf("Node.js")>-1?(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);var s=e.domSupported="undefined"!=typeof document;if(s){var l=document.documentElement.style;e.transform3dSupported=(n.ie&&"transition"in l||n.edge||"WebKitCSSMatrix"in window&&"m11"in new WebKitCSSMatrix||"MozPerspective"in l)&&!("OTransition"in l),e.transformSupported=e.transform3dSupported||n.ie&&+n.version>=9}}(navigator.userAgent,r);var o="sans-serif",a="12px "+o;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 h=0;h=M&&(S=0),S++}function T(){for(var t=[],e=0;e>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 e.clearMarkers=function(){B(n,function(t){t.parentNode&&t.parentNode.removeChild(t)})},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 c=t[u].getBoundingClientRect(),h=2*u,d=c.left,p=c.top;a.push(d,p),l=l&&o&&d===o[h]&&p===o[h+1],s.push(t[u].offsetLeft,t[u].offsetTop)}return l&&r?r:(e.srcCoords=a,e[i]=n?te(s,a):te(a,s))}(s,a,o);if(l)return l(t,n,i),!0}return!1}function re(t){return"CANVAS"===t.nodeName.toUpperCase()}var oe=/([&<>"'])/g,ae={"&":"&","<":"<",">":">",'"':""","'":"'"};function se(t){return null==t?"":(t+"").replace(oe,function(t,e){return ae[e]})}var le=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ue=[],ce=r.browser.firefox&&+r.browser.version.split(".")[0]<39;function he(t,e,n,i){return n=n||{},i?de(t,e,n):ce&&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):de(t,e,n),n}function de(t,e,n){if(r.domSupported&&t.getBoundingClientRect){var i=e.clientX,o=e.clientY;if(re(t)){var a=t.getBoundingClientRect();return n.zrX=i-a.left,void(n.zrY=o-a.top)}if(ie(ue,t,i,o))return n.zrX=ue[0],void(n.zrY=ue[1])}n.zrX=n.zrY=0}function pe(t){return t||window.event}function fe(t,e,n){if(null!=(e=pe(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&&he(t,r,e,n)}else{he(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&&le.test(e.type)&&(e.which=1&a?1:2&a?3:4&a?2:0),e}function ge(t,e,n,i){t.addEventListener(e,n,i)}function ve(t,e,n,i){t.removeEventListener(e,n,i)}var ye=function(t){t.preventDefault(),t.stopPropagation(),t.cancelBubble=!0};function me(t){return 2===t.which||3===t.which}var xe=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=_e(r)/_e(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 we(){return[1,0,0,1,0,0]}function Se(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t}function Me(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 Ie(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 Te(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 Ce(t,e,n,i){void 0===i&&(i=[0,0]);var r=e[0],o=e[2],a=e[4],s=e[1],l=e[3],u=e[5],c=Math.sin(n),h=Math.cos(n);return t[0]=r*h+s*c,t[1]=-r*c+s*h,t[2]=o*h+l*c,t[3]=-o*c+h*l,t[4]=h*(a-i[0])+c*(u-i[1])+i[0],t[5]=h*(u-i[1])-c*(a-i[0])+i[1],t}function De(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 Ae(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 ke(t){var e=[1,0,0,1,0,0];return Me(e,t),e}var Le=Object.freeze({__proto__:null,create:we,identity:Se,copy:Me,mul:Ie,translate:Te,rotate:Ce,scale:De,invert:Ae,clone:ke}),Pe=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}(),Oe=Math.min,Re=Math.max,Ne=Math.abs,Ee=["x","y"],ze=["width","height"],Be=new Pe,Ve=new Pe,Ge=new Pe,Fe=new Pe,He=rn(),We=He.minTv,Ue=He.maxTv,Ye=[0,0],Xe=function(){function t(t,e,n,i){je(this,t,e,n,i)}return t.set=function(t,e,n,i,r){return i<0&&(e+=i,i=-i),r<0&&(n+=r,r=-r),t.x=e,t.y=n,t.width=i,t.height=r,t},t.prototype.union=function(t){var e=Oe(t.x,this.x),n=Oe(t.y,this.y);isFinite(this.x)&&isFinite(this.width)?this.width=Re(t.x+t.width,this.x+this.width)-e:this.width=t.width,isFinite(this.y)&&isFinite(this.height)?this.height=Re(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){return Ke([1,0,0,1,0,0],this,t)},t.prototype.intersect=function(e,n,i){return t.intersect(this,e,n,i)},t.intersect=function(e,n,i,r){i&&Pe.set(i,0,0);var o=r&&r.outIntersectRect||null,a=r&&r.clamp;if(o&&(o.x=o.y=o.width=o.height=NaN),!e||!n)return!1;e instanceof t||(e=je(Qe,e.x,e.y,e.width,e.height)),n instanceof t||(n=je(tn,n.x,n.y,n.width,n.height));var s=!!i;He.reset(r,s);var l=He.touchThreshold,u=e.x+l,c=e.x+e.width-l,h=e.y+l,d=e.y+e.height-l,p=n.x+l,f=n.x+n.width-l,g=n.y+l,v=n.y+n.height-l;if(u>c||h>d||p>f||g>v)return!1;var y=!(c=t.x&&e<=t.x+t.width&&n>=t.y&&n<=t.y+t.height},t.prototype.contain=function(e,n){return t.contain(this,e,n)},t.prototype.clone=function(){return new t(this.x,this.y,this.width,this.height)},t.prototype.copy=function(t){qe(this,t)},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?e.x:0,e?e.y:0,e?e.width:0,e?e.height:0)},t.copy=function(t,e){return t.x=e.x,t.y=e.y,t.width=e.width,t.height=e.height,t},t.applyTransform=function(t,e,n){if(n){if(n[1]<1e-5&&n[1]>-1e-5&&n[2]<1e-5&&n[2]>-1e-5){var i=n[0],r=n[3],o=n[4],a=n[5];return t.x=e.x*i+o,t.y=e.y*r+a,t.width=e.width*i,t.height=e.height*r,t.width<0&&(t.x+=t.width,t.width=-t.width),void(t.height<0&&(t.y+=t.height,t.height=-t.height))}Be.x=Ge.x=e.x,Be.y=Fe.y=e.y,Ve.x=Fe.x=e.x+e.width,Ve.y=Ge.y=e.y+e.height,Be.transform(n),Fe.transform(n),Ve.transform(n),Ge.transform(n),t.x=Oe(Be.x,Ve.x,Ge.x,Fe.x),t.y=Oe(Be.y,Ve.y,Ge.y,Fe.y);var s=Re(Be.x,Ve.x,Ge.x,Fe.x),l=Re(Be.y,Ve.y,Ge.y,Fe.y);t.width=s-t.x,t.height=l-t.y}else t!==e&&qe(t,e)},t.calculateTransform=function(t,e,n){var i=n.width/e.width,r=n.height/e.height;return Te(t=Se(t||[]),t,kt(en,-e.x,-e.y)),De(t,t,kt(en,i,r)),Te(t,t,kt(en,n.x,n.y)),t},t}(),Ze=Xe.create,je=Xe.set,qe=Xe.copy,Ke=Xe.calculateTransform,$e=Xe.applyTransform,Je=Xe.contain,Qe=new Xe(0,0,0,0),tn=new Xe(0,0,0,0),en=[];function nn(t,e,n,i,r,o,a,s){var l=Ne(e-n),u=Ne(i-t),c=Oe(l,u),h=Ee[r],d=Ee[1-r],p=ze[r];e=u||!He.bidirectional)&&(We[h]=-u,We[d]=0,He.useDir&&He.calcDirMTV())))}function rn(){var t=0,e=new Pe,n=new Pe,i={minTv:new Pe,maxTv:new Pe,useDir:!1,dirMinTv:new Pe,touchThreshold:0,bidirectional:!0,negativeSize:!1,reset:function(r,o){i.touchThreshold=0,r&&null!=r.touchThreshold&&(i.touchThreshold=Re(0,r.touchThreshold)),i.negativeSize=!1,o&&(i.minTv.set(1/0,1/0),i.maxTv.set(0,0),i.useDir=!1,r&&null!=r.direction&&(i.useDir=!0,i.dirMinTv.copy(i.minTv),n.copy(i.minTv),t=r.direction,i.bidirectional=null==r.bidirectional||!!r.bidirectional,i.bidirectional||e.set(Math.cos(t),Math.sin(t))))},calcDirMTV:function(){var o=i.minTv,a=i.dirMinTv,s=o.y*o.y+o.x*o.x,l=Math.sin(t),u=Math.cos(t),c=l*o.y+u*o.x;r(c)?r(o.x)&&r(o.y)&&a.set(0,0):(n.x=s*u/c,n.y=s*l/c,r(n.x)&&r(n.y)?a.set(0,0):(i.bidirectional||e.dot(n)>0)&&n.len()=0;u--){var c=i[u];c===n||c.ignore||c.ignoreCoarsePointer||c.parent&&c.parent.ignoreCoarsePointer||(cn.copy(c.getBoundingRect()),c.transform&&cn.applyTransform(c.transform),cn.intersect(l)&&o.push(c))}if(o.length)for(var h=Math.PI/12,d=2*Math.PI,p=0;p=0;o--){var a=t[o],s=void 0;if(a!==r&&!a.ignore&&(s=dn(a,n,i))&&(!e.topTarget&&(e.topTarget=a),s!==on)){e.target=a;break}}}function fn(t,e,n){var i=t.painter;return e<0||e>i.getWidth()||n<0||n>i.getHeight()}B(["click","mousedown","mouseup","mousewheel","dblclick","contextmenu"],function(t){hn.prototype[t]=function(e){var n,i,r=e.zrX,o=e.zrY,a=fn(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||Ft(this._downPoint,[e.zrX,e.zrY])>4)return;this._downPoint=null}this.dispatchToElement(n,t,e)}});function gn(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 vn(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 yn(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+c])>0?a=c+1:l=c}return l}function mn(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+c])<0?l=c:a=c+1}return l}function xn(t,e){var n,i,r=7,o=0,a=[];function s(s){var l=n[s],u=i[s],c=n[s+1],h=i[s+1];i[s]=u+h,s===o-3&&(n[s+1]=n[s+2],i[s+1]=i[s+2]),o--;var d=mn(t[c],t,l,u,0,e);l+=d,0!==(u-=d)&&0!==(h=yn(t[l+u-1],t,c,h,h-1,e))&&(u<=h?function(n,i,o,s){var l=0;for(l=0;l=7||p>=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[p+l]=t[d+l];return void(t[h]=a[c])}var f=r;for(;;){var g=0,v=0,y=!1;do{if(e(a[c],t[u])<0){if(t[h--]=t[u--],g++,v=0,0===--i){y=!0;break}}else if(t[h--]=a[c--],v++,g=0,1===--s){y=!0;break}}while((g|v)=0;l--)t[p+l]=t[d+l];if(0===i){y=!0;break}}if(t[h--]=a[c--],1===--s){y=!0;break}if(0!==(v=s-yn(t[u],a,0,s,s-1,e))){for(s-=v,p=(h-=v)+1,d=(c-=v)+1,l=0;l=7||v>=7);if(y)break;f<0&&(f=0),f+=2}(r=f)<1&&(r=1);if(1===s){for(p=(h-=i)+1,d=(u-=i)+1,l=i-1;l>=0;l--)t[p+l]=t[d+l];t[h]=a[c]}else{if(0===s)throw new Error;for(d=h-(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=gn(t,n,i,e))s&&(l=s),vn(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 bn=!1;function wn(){bn||(bn=!0,console.warn("z / z2 / zlevel of displayable is invalid, which may cause unexpected errors"))}function Sn(t,e){return t.zlevel===e.zlevel?t.z===e.z?t.z2-e.z2:t.z-e.z:t.zlevel-e.zlevel}var Mn=function(){function t(){this._roots=[],this._displayList=[],this._displayListLen=0,this.displayableSortFunc=Sn}return t.prototype.traverse=function(t,e){for(var n=0;n=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}(),In=r.hasGlobalWindow&&(window.requestAnimationFrame&&window.requestAnimationFrame.bind(window)||window.msRequestAnimationFrame&&window.msRequestAnimationFrame.bind(window)||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame)||function(t){return setTimeout(t,16)},Tn={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-Tn.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*Tn.bounceIn(2*t):.5*Tn.bounceOut(2*t-1)+.5}},Cn=Math.pow,Dn=Math.sqrt,An=1e-8,kn=1e-4,Ln=Dn(3),Pn=1/3,On=Ct(),Rn=Ct(),Nn=Ct();function En(t){return t>-1e-8&&tAn||t<-1e-8}function Bn(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 Vn(t,e,n,i,r){var o=1-r;return 3*(((e-t)*o+2*(n-e)*r)*o+(i-n)*r*r)}function Gn(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,c=s*s-3*a*l,h=s*l-9*a*u,d=l*l-3*s*u,p=0;if(En(c)&&En(h)){if(En(s))o[0]=0;else(M=-l/s)>=0&&M<=1&&(o[p++]=M)}else{var f=h*h-4*c*d;if(En(f)){var g=h/c,v=-g/2;(M=-s/a+g)>=0&&M<=1&&(o[p++]=M),v>=0&&v<=1&&(o[p++]=v)}else if(f>0){var y=Dn(f),m=c*s+1.5*a*(-h+y),x=c*s+1.5*a*(-h-y);(M=(-s-((m=m<0?-Cn(-m,Pn):Cn(m,Pn))+(x=x<0?-Cn(-x,Pn):Cn(x,Pn))))/(3*a))>=0&&M<=1&&(o[p++]=M)}else{var _=(2*c*s-3*a*h)/(2*Dn(c*c*c)),b=Math.acos(_)/3,w=Dn(c),S=Math.cos(b),M=(-s-2*w*S)/(3*a),I=(v=(-s+w*(S+Ln*Math.sin(b)))/(3*a),(-s+w*(S-Ln*Math.sin(b)))/(3*a));M>=0&&M<=1&&(o[p++]=M),v>=0&&v<=1&&(o[p++]=v),I>=0&&I<=1&&(o[p++]=I)}}return p}function Fn(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(En(a)){if(zn(o))(c=-s/o)>=0&&c<=1&&(r[l++]=c)}else{var u=o*o-4*a*s;if(En(u))r[0]=-o/(2*a);else if(u>0){var c,h=Dn(u),d=(-o-h)/(2*a);(c=(-o+h)/(2*a))>=0&&c<=1&&(r[l++]=c),d>=0&&d<=1&&(r[l++]=d)}}return l}function Hn(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,c=(l-s)*r+s,h=(c-u)*r+u;o[0]=t,o[1]=a,o[2]=u,o[3]=h,o[4]=h,o[5]=c,o[6]=l,o[7]=i}function Wn(t,e,n,i,r,o,a,s,l,u,c){var h,d,p,f,g,v=.005,y=1/0;On[0]=l,On[1]=u;for(var m=0;m<1;m+=.05)Rn[0]=Bn(t,n,r,a,m),Rn[1]=Bn(e,i,o,s,m),(f=Wt(On,Rn))=0&&f=0&&v=1?1:Gn(0,i,o,1,t,s)&&Bn(0,r,a,1,s[0])}}}var Qn=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||St,this.ondestroy=t.ondestroy||St,this.onrestart=t.onrestart||St,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=Z(t)?t:Tn[t]||Jn(t)},t}(),ti=function(t){this.value=t},ei=function(){function t(){this._len=0}return t.prototype.insert=function(t){var e=new ti(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}(),ni=function(){function t(t){this._list=new ei,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 ti(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}(),ii={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 ri(t){return(t=Math.round(t))<0?0:t>255?255:t}function oi(t){return t<0?0:t>1?1:t}function ai(t){var e=t;return e.length&&"%"===e.charAt(e.length-1)?ri(parseFloat(e)/100*255):ri(parseInt(e,10))}function si(t){var e=t;return e.length&&"%"===e.charAt(e.length-1)?oi(parseFloat(e)/100):oi(parseFloat(e))}function li(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 ui(t,e,n){return t+(e-t)*n}function ci(t,e,n,i,r){return t[0]=e,t[1]=n,t[2]=i,t[3]=r,t}function hi(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t}var di=new ni(20),pi=null;function fi(t,e){pi&&hi(pi,e),pi=di.put(t,pi||e.slice())}function gi(t,e){if(t){e=e||[];var n=di.get(t);if(n)return hi(e,n);var i=(t+="").replace(/ /g,"").toLowerCase();if(i in ii)return hi(e,ii[i]),fi(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?(ci(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),fi(t,e),e):void ci(e,0,0,0,1):7===o||9===o?(r=parseInt(i.slice(1,7),16))>=0&&r<=16777215?(ci(e,(16711680&r)>>16,(65280&r)>>8,255&r,9===o?parseInt(i.slice(7),16)/255:1),fi(t,e),e):void ci(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(","),c=1;switch(l){case"rgba":if(4!==u.length)return 3===u.length?ci(e,+u[0],+u[1],+u[2],1):ci(e,0,0,0,1);c=si(u.pop());case"rgb":return u.length>=3?(ci(e,ai(u[0]),ai(u[1]),ai(u[2]),3===u.length?c:si(u[3])),fi(t,e),e):void ci(e,0,0,0,1);case"hsla":return 4!==u.length?void ci(e,0,0,0,1):(u[3]=si(u[3]),vi(u,e),fi(t,e),e);case"hsl":return 3!==u.length?void ci(e,0,0,0,1):(vi(u,e),fi(t,e),e);default:return}}ci(e,0,0,0,1)}}function vi(t,e){var n=(parseFloat(t[0])%360+360)%360/360,i=si(t[1]),r=si(t[2]),o=r<=.5?r*(i+1):r+i-r*i,a=2*r-o;return ci(e=e||[],ri(255*li(a,o,n+1/3)),ri(255*li(a,o,n)),ri(255*li(a,o,n-1/3)),1),4===t.length&&(e[3]=t[3]),e}function yi(t,e){var n=gi(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 Mi(n,4===n.length?"rgba":"rgb")}}function mi(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]=ri(ui(a[0],s[0],l)),n[1]=ri(ui(a[1],s[1],l)),n[2]=ri(ui(a[2],s[2],l)),n[3]=oi(ui(a[3],s[3],l)),n}}var xi=mi;function _i(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=gi(e[r]),s=gi(e[o]),l=i-r,u=Mi([ri(ui(a[0],s[0],l)),ri(ui(a[1],s[1],l)),ri(ui(a[2],s[2],l)),oi(ui(a[3],s[3],l))],"rgba");return n?{color:u,leftIndex:r,rightIndex:o,value:i}:u}}var bi=_i;function wi(t,e,n,i){var r=gi(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 c=((s-i)/6+l/2)/l,h=((s-r)/6+l/2)/l,d=((s-o)/6+l/2)/l;i===s?e=d-h:r===s?e=1/3+c-d:o===s&&(e=2/3+h-c),e<0&&(e+=1),e>1&&(e-=1)}var p=[360*e,n,u];return null!=t[3]&&p.push(t[3]),p}}(r),null!=e&&(r[0]=function(t){return(t=Math.round(t))<0?0:t>360?360:t}(Z(e)?e(r[0]):e)),null!=n&&(r[1]=si(Z(n)?n(r[1]):n)),null!=i&&(r[2]=si(Z(i)?i(r[2]):i)),Mi(vi(r),"rgba")}function Si(t,e){var n=gi(t);if(n&&null!=e)return n[3]=oi(e),Mi(n,"rgba")}function Mi(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 Ii(t,e){var n=gi(t);return n?(.299*n[0]+.587*n[1]+.114*n[2])*n[3]/255+(1-n[3])*e:0}var Ti=new ni(100);function Ci(t){if(j(t)){var e=Ti.get(t);return e||(e=yi(t,-.1),Ti.put(t,e)),e}if(et(t)){var n=k({},t);return n.colorStops=V(t.colorStops,function(t){return{offset:t.offset,color:yi(t.color,-.1)}}),n}return t}var Di=Object.freeze({__proto__:null,parseCssInt:ai,parseCssFloat:si,parse:gi,lift:yi,toHex:function(t){var e=gi(t);if(e)return((1<<24)+(e[0]<<16)+(e[1]<<8)+ +e[2]).toString(16).slice(1)},fastLerp:mi,fastMapToColor:xi,lerp:_i,mapToColor:bi,modifyHSL:wi,modifyAlpha:Si,stringify:Mi,lum:Ii,random:function(){return Mi([Math.round(255*Math.random()),Math.round(255*Math.random()),Math.round(255*Math.random())],"rgb")},liftColor:Ci}),Ai=Math.round;function ki(t){var e;if(t&&"transparent"!==t){if("string"==typeof t&&t.indexOf("rgba")>-1){var n=gi(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 Li=1e-4;function Pi(t){return t-1e-4}function Oi(t){return Ai(1e3*t)/1e3}function Ri(t){return Ai(1e4*t)/1e4}var Ni={left:"start",right:"end",center:"middle",middle:"middle"};function Ei(t){return t&&!!t.image}function zi(t){return Ei(t)||function(t){return t&&!!t.svgElement}(t)}function Bi(t){return"linear"===t.type}function Vi(t){return"radial"===t.type}function Gi(t){return t&&("linear"===t.type||"radial"===t.type)}function Fi(t){return"url(#"+t+")"}function Hi(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 Wi(t){var e=t.x||0,n=t.y||0,i=(t.rotation||0)*Mt,r=at(t.scaleX,1),o=at(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("+Ai(a*Mt)+"deg, "+Ai(s*Mt)+"deg)"),l.join(" ")}var Ui="undefined"!=typeof Buffer&&"function"==typeof Buffer.from?function(t){return Buffer.from(t).toString("base64")}:"function"==typeof btoa&&"function"==typeof unescape&&"function"==typeof encodeURIComponent?function(t){return btoa(unescape(encodeURIComponent(t)))}:function(t){return null},Yi=Array.prototype.slice;function Xi(t,e,n){return(e-t)*n+t}function Zi(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(z(e)){var l=function(t){return z(t&&t[0])?2:1}(e);a=l,(1===l&&!K(e[0])||2===l&&!K(e[0][0]))&&(o=!0)}else if(K(e)&&!rt(e))a=0;else if(j(e))if(isNaN(+e)){var u=gi(e);u&&(s=u,a=3)}else a=0;else if(et(e)){var c=k({},s);c.colorStops=V(e.colorStops,function(t){return{offset:t.offset,color:gi(t.color)}}),Bi(e)?a=4:Vi(e)&&(a=5),s=c}0===r?this.valType=a:a===this.valType&&6!==a||(o=!0),this.discrete=this.discrete||o;var h={time:t,value:s,rawValue:e,percent:0};return n&&(h.easing=n,h.easingFunc=Z(n)?n:Tn[n]||Jn(n)),i.push(h),h},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=er(i),l=tr(i),u=0;u=0&&!(l[n].percent<=e);n--);n=p(n,u-2)}else{for(n=d;ne);n++);n=p(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:p((e-i.percent)/f,1);r.easingFunc&&(g=r.easingFunc(g));var v=o?this._additiveValue:h?nr:t[c];if(!er(s)&&!h||v||(v=this._additiveValue=[]),this.discrete)t[c]=g<1?i.rawValue:r.rawValue;else if(er(s))1===s?Zi(v,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,Ji(l),i),this._trackKeys.push(a)}s.addKeyframe(t,Ji(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 or(){return(new Date).getTime()}var ar,sr,lr=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=or()-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,In(function e(){t._running&&(In(e),!t._paused&&t.update())})},e.prototype.start=function(){this._running||(this._time=or(),this._pausedTime=0,this._startLoop())},e.prototype.stop=function(){this._running=!1},e.prototype.pause=function(){this._paused||(this._pauseStart=or(),this._paused=!0)},e.prototype.resume=function(){this._paused&&(this._pausedTime+=or()-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 rr(t,e.loop);return this.addAnimator(n),n},e}($t),ur=r.domSupported,cr=(sr={pointerdown:1,pointerup:1,pointermove:1,pointerout:1},{mouse:ar=["click","dblclick","mousewheel","wheel","mouseout","mouseup","mousedown","mousemove","contextmenu"],touch:["touchstart","touchend","touchmove"],pointer:V(ar,function(t){var e=t.replace("mouse","pointer");return sr.hasOwnProperty(e)?e:t})}),hr=["mousemove","mouseup"],dr=["pointermove","pointerup"],pr=!1;function fr(t){var e=t.pointerType;return"pen"===e||"touch"===e}function gr(t){t&&(t.zrByTouch=!0)}function vr(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 yr=function(t,e){this.stopPropagation=St,this.stopImmediatePropagation=St,this.preventDefault=St,this.type=e.type,this.target=this.currentTarget=t.dom,this.pointerType=e.pointerType,this.clientX=e.clientX,this.clientY=e.clientY},mr={mousedown:function(t){t=fe(this.dom,t),this.__mayPointerCapture=[t.zrX,t.zrY],this.trigger("mousedown",t)},mousemove:function(t){t=fe(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=fe(this.dom,t),this.__togglePointerCapture(!1),this.trigger("mouseup",t)},mouseout:function(t){vr(this,(t=fe(this.dom,t)).toElement||t.relatedTarget)||(this.__pointerCapturing&&(t.zrEventControl="no_globalout"),this.trigger("mouseout",t))},wheel:function(t){pr=!0,t=fe(this.dom,t),this.trigger("mousewheel",t)},mousewheel:function(t){pr||(t=fe(this.dom,t),this.trigger("mousewheel",t))},touchstart:function(t){gr(t=fe(this.dom,t)),this.__lastTouchMoment=new Date,this.handler.processGesture(t,"start"),mr.mousemove.call(this,t),mr.mousedown.call(this,t)},touchmove:function(t){gr(t=fe(this.dom,t)),this.handler.processGesture(t,"change"),mr.mousemove.call(this,t)},touchend:function(t){gr(t=fe(this.dom,t)),this.handler.processGesture(t,"end"),mr.mouseup.call(this,t),+new Date-+this.__lastTouchMoment<300&&mr.click.call(this,t)},pointerdown:function(t){mr.mousedown.call(this,t)},pointermove:function(t){fr(t)||mr.mousemove.call(this,t)},pointerup:function(t){mr.mouseup.call(this,t)},pointerout:function(t){fr(t)||mr.mouseout.call(this,t)}};B(["click","dblclick","contextmenu"],function(t){mr[t]=function(e){e=fe(this.dom,e),this.trigger(t,e)}});var xr={pointermove:function(t){fr(t)||xr.mousemove.call(this,t)},pointerup:function(t){xr.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 _r(t,e){var n=e.domHandlers;r.pointerEventsSupported?B(cr.pointer,function(i){wr(e,i,function(e){n[i].call(t,e)})}):(r.touchEventsSupported&&B(cr.touch,function(i){wr(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)})}),B(cr.mouse,function(i){wr(e,i,function(r){r=pe(r),e.touching||n[i].call(t,r)})}))}function br(t,e){function n(n){wr(e,n,function(i){i=pe(i),vr(t,i.target)||(i=function(t,e){return fe(t.dom,new yr(t,e),!0)}(t,i),e.domHandlers[n].call(t,i))},{capture:!0})}r.pointerEventsSupported?B(dr,n):r.touchEventsSupported||B(hr,n)}function wr(t,e,n,i){t.mounted[e]=n,t.listenerOpts[e]=i,ge(t.domTarget,e,n,i)}function Sr(t){var e=t.mounted;for(var n in e)e.hasOwnProperty(n)&&ve(t.domTarget,n,e[n],t.listenerOpts[n]);t.mounted={}}var Mr=function(t,e){this.mounted={},this.listenerOpts={},this.touching=!1,this.domTarget=t,this.domHandlers=e},Ir=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 Mr(e,mr),ur&&(i._globalHandlerScope=new Mr(document,xr)),_r(i,i._localHandlerScope),i}return n(e,t),e.prototype.dispose=function(){Sr(this._localHandlerScope),ur&&Sr(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,ur&&+this.__pointerCapturing^+t){this.__pointerCapturing=t;var e=this._globalHandlerScope;t?br(this,e):Sr(e)}},e}($t),Tr=1;r.hasGlobalWindow&&(Tr=Math.max(window.devicePixelRatio||window.screen&&window.screen.deviceXDPI/window.screen.logicalXDPI||1,1));var Cr=Tr,Dr="#333",Ar="#ccc",kr=Se,Lr=5e-5;function Pr(t){return t>Lr||t<-5e-5}var Or=[],Rr=[],Nr=[1,0,0,1,0,0],Er=Math.abs,zr=function(){function t(){}var e;return t.prototype.getLocalTransform=function(t){return Br(this,t)},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 Pr(this.rotation)||Pr(this.x)||Pr(this.y)||Pr(this.scaleX-1)||Pr(this.scaleY-1)||Pr(this.skewX)||Pr(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):kr(n),t&&(e?Ie(n,t,n):Me(n,t)),this.transform=n,this._resolveGlobalScaleRatio(n),this.invTransform=this.invTransform||[1,0,0,1,0,0],Ae(this.invTransform,n)):n&&(kr(n),this.invTransform=null)},t.prototype._resolveGlobalScaleRatio=function(t){var e=this.globalScaleRatio;if(null!=e&&1!==e){this.getGlobalScale(Or);var n=Or[0]<0?-1:1,i=Or[1]<0?-1:1,r=((Or[0]-n)*e+n)/Or[0]||0,o=((Or[1]-i)*e+i)/Or[1]||0;t[0]*=r,t[1]*=r,t[2]*=o,t[3]*=o}},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&&(t.invTransform=t.invTransform||[1,0,0,1,0,0],Ie(Rr,t.invTransform,e),e=Rr);var n=this.originX,i=this.originY;(n||i)&&(Nr[4]=n,Nr[5]=i,Ie(Rr,e,Nr),Rr[4]-=n,Rr[5]-=i,e=Rr),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&&Yt(n,n,i),n},t.prototype.transformCoordToGlobal=function(t,e){var n=[t,e],i=this.transform;return i&&Yt(n,n,i),n},t.prototype.getLineScale=function(){var t=this.transform;return t&&Er(t[0]-1)>1e-10&&Er(t[3]-1)>1e-10?Math.sqrt(Er(t[0]*t[3]-t[2]*t[1])):1},t.prototype.copyTransform=function(t){Hr(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,c=t.y,h=t.skewX?Math.tan(t.skewX):0,d=t.skewY?Math.tan(-t.skewY):0;if(n||i||a||s){var p=n+a,f=i+s;e[4]=-p*r-h*f*o,e[5]=-f*o-d*p*r}else e[4]=e[5]=0;return e[0]=r,e[3]=o,e[1]=d*r,e[2]=h*o,l&&Ce(e,e,l),e[4]+=n+u,e[5]+=i+c,e},t.initDefaultProps=((e=t.prototype).scaleX=e.scaleY=e.globalScaleRatio=1,void(e.x=e.y=e.originX=e.originY=e.skewX=e.skewY=e.rotation=e.anchorX=e.anchorY=0)),t}(),Br=zr.getLocalTransform;function Vr(){return new zr}var Gr,Fr=["x","y","originX","originY","anchorX","anchorY","rotation","scaleX","scaleY","skewX","skewY"];function Hr(t,e){return L(t,e,Fr)}function Wr(t){Gr||(Gr=new ni(100)),t=t||a;var e=Gr.get(t);return e||(e={font:t,strWidthCache:new ni(500),asciiWidthMap:null,asciiWidthMapTried:!1,stWideCharWidth:c.measureText("国",t).width,asciiCharWidth:c.measureText("a",t).width},Gr.put(t,e)),e}var Ur=0,Yr=5;function Xr(t,e){return t.asciiWidthMapTried||(t.asciiWidthMap=function(t){if(!(Ur>=Yr)){t=t||a;for(var e=[],n=+new Date,i=0;i<=127;i++)e[i]=c.measureText(String.fromCharCode(i),t).width;var r=+new Date-n;return r>16?Ur=Yr:r>2&&Ur++,e}}(t.font),t.asciiWidthMapTried=!0),0<=e&&e<=127?null!=t.asciiWidthMap?t.asciiWidthMap[e]:t.asciiCharWidth:t.stWideCharWidth}function Zr(t,e){var n=t.strWidthCache,i=n.get(e);return null==i&&(i=c.measureText(e,t.font).width,n.put(e,i)),i}function jr(t,e,n,i){var r=Zr(Wr(e),t),o=Jr(e),a=Kr(0,r,n),s=$r(0,o,i);return new Xe(a,s,r,o)}function qr(t,e,n,i){var r=((t||"")+"").split("\n");if(1===r.length)return jr(r[0],e,n,i);for(var o=new Xe(0,0,0,0),a=0;a=0?parseFloat(t)/100*e:parseFloat(t):t}function to(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,c="left",h="top";if(i instanceof Array)l+=Qr(i[0],n.width),u+=Qr(i[1],n.height),c=null,h=null;else switch(i){case"left":l-=r,u+=s,c="right",h="middle";break;case"right":l+=r+a,u+=s,h="middle";break;case"top":l+=a/2,u-=r,c="center",h="bottom";break;case"bottom":l+=a/2,u+=o+r,c="center";break;case"inside":l+=a/2,u+=s,c="center",h="middle";break;case"insideLeft":l+=r,u+=s,h="middle";break;case"insideRight":l+=a-r,u+=s,c="right",h="middle";break;case"insideTop":l+=a/2,u+=r,c="center";break;case"insideBottom":l+=a/2,u+=o-r,c="center",h="bottom";break;case"insideTopLeft":l+=r,u+=r;break;case"insideTopRight":l+=a-r,u+=r,c="right";break;case"insideBottomLeft":l+=r,u+=o-r,h="bottom";break;case"insideBottomRight":l+=a-r,u+=o-r,c="right",h="bottom"}return(t=t||{}).x=l,t.y=u,t.align=c,t.verticalAlign=h,t}var eo="__zr_normal__",no=Fr.concat(["ignore"]),io=G(Fr,function(t,e){return t[e]=!0,t},{ignore:!1}),ro={},oo=new Xe(0,0,0,0),ao=[],so=function(){function t(t){this.id=I(),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;r.copyTransform(e);var u=null!=n.position,c=n.autoOverflowArea,h=void 0;if((c||u)&&(h=oo,n.layoutRect?h.copy(n.layoutRect):h.copy(this.getBoundingRect()),i||h.applyTransform(this.transform)),u){this.calculateTextPosition?this.calculateTextPosition(ro,n,h):to(ro,n,h),r.x=ro.x,r.y=ro.y,o=ro.align,a=ro.verticalAlign;var d=n.origin;if(d&&null!=n.rotation){var p=void 0,f=void 0;"center"===d?(p=.5*h.width,f=.5*h.height):(p=Qr(d[0],h.width),f=Qr(d[1],h.height)),l=!0,r.originX=-r.x+p+(i?0:h.x),r.originY=-r.y+f+(i?0:h.y)}}null!=n.rotation&&(r.rotation=n.rotation);var g=n.offset;g&&(r.x+=g[0],r.y+=g[1],l||(r.originX=-g[0],r.originY=-g[1]));var v=this._innerTextDefaultStyle||(this._innerTextDefaultStyle={});if(c){var y=v.overflowRect=v.overflowRect||new Xe(0,0,0,0);r.getLocalTransform(ao),Ae(ao,ao),Xe.copy(y,h),y.applyTransform(ao)}else v.overflowRect=null;var m=void 0,x=void 0,_=void 0;(null==n.inside?"string"==typeof n.position&&n.position.indexOf("inside")>=0:n.inside)&&this.canBeInsideText()?(m=n.insideFill,x=n.insideStroke,null!=m&&"auto"!==m||(m=this.getInsideTextFill()),null!=x&&"auto"!==x||(x=this.getInsideTextStroke(m),_=!0)):(m=n.outsideFill,x=n.outsideStroke,null!=m&&"auto"!==m||(m=this.getOutsideFill()),null!=x&&"auto"!==x||(x=this.getOutsideStroke(m),_=!0)),(m=m||"#000")===v.fill&&x===v.stroke&&_===v.autoStroke&&o===v.align&&a===v.verticalAlign||(s=!0,v.fill=m,v.stroke=x,v.autoStroke=_,v.align=o,v.verticalAlign=a,e.setDefaultTextStyle(v)),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()?Ar:Dr},t.prototype.getOutsideStroke=function(t){var e=this.__zr&&this.__zr.getBackgroundColor(),n="string"==typeof e&&gi(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,Mi(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||{},k(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($(t))for(var n=W(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(eo,!1,t)},t.prototype.useState=function(t,e,n,i){var r=t===eo;if(this.hasState()||!r){var o=this.currentStates,a=this.stateTransition;if(!(R(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=this._textContent,u=po(this,l,s,i);u&&!this.__inHover&&(this.__inHover=u),this._applyStateObj(t,s,this._normalState,e,go(this,n,a),a);var c=this._textGuide;return l&&l.useState(t,e,n,!!u),c&&c.useState(t,e,n,!!u),r?(this.currentStates=[],this._normalState={}):e?this.currentStates.push(t):this.currentStates=[t],this._updateAnimationTargets(),this.markRedraw(),!u&&this.__inHover&&(this.__inHover=0,this.__dirty&=-2),s}T("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;s=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=R(i,t),o=R(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 d=0;d0||r.force&&!a.length){var w,S=void 0,M=void 0,I=void 0;if(s){M={},d&&(S={});for(_=0;_0}E(so,$t),E(so,zr);var vo=function(t){function e(e){var n=t.call(this)||this;return n.isGroup=!0,n._children=[],n.attr(e),n}return n(e,t),e.prototype.childrenRef=function(){return this._children},e.prototype.children=function(){return this._children.slice()},e.prototype.childAt=function(t){return this._children[t]},e.prototype.childOfName=function(t){for(var e=this._children,n=0;n=0&&(n.splice(i,0,t),this._doAdd(t))}return this},e.prototype.replace=function(t,e){var n=R(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=R(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._disposed||(this.animation.start(),this._stillFrameAccum=0)},t.prototype.refreshHover=function(){this._needsRefreshHover=!0},t.prototype.refreshHoverImmediately=function(){this._disposed||this._refresh({animUpdate:!1,refresh:!1,refreshHover:!0})},t.prototype.resize=function(t){this._disposed||(t=t||{},this.painter.resize(t.width,t.height),this.handler.resize())},t.prototype.clearAnimation=function(){this._disposed||this.animation.clear()},t.prototype.getWidth=function(){if(!this._disposed)return this.painter.getWidth()},t.prototype.getHeight=function(){if(!this._disposed)return this.painter.getHeight()},t.prototype.setCursorStyle=function(t){this._disposed||this.handler.setCursorStyle(t)},t.prototype.findHover=function(t,e){if(!this._disposed)return this.handler.findHover(t,e)},t.prototype.on=function(t,e,n){return this._disposed||this.handler.on(t,e,n),this},t.prototype.off=function(t,e){this._disposed||this.handler.off(t,e)},t.prototype.trigger=function(t,e){this._disposed||this.handler.trigger(t,e)},t.prototype.clear=function(){if(!this._disposed){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}var Vo=function(t,e,n){switch(t){case"center":case"middle":t="50%";break;case"left":case"top":t="0%";break;case"right":case"bottom":t="100%"}return Go(t,e,n)};function Go(t,e,n){return j(t)?Fo(t)?parseFloat(t)/100*e+(n||0):parseFloat(t):null==t?NaN:+t}function Fo(t){return!!(e=t,e.replace(/^\s+|\s+$/g,"")).match(/%$/);var e}function Ho(t,e,n){return isNaN(e)?n?""+t:+t:(e=Co(Do(0,e),20),t=(+t).toFixed(e),n?t:+t)}function Wo(t){return t.sort(function(t,e){return t-e}),t}function Uo(t){if(t=+t,isNaN(t))return 0;if(t>1e-14)for(var e=1,n=0;n<15;n++,e*=10)if(ko(t*e)/e===t)return n;return Yo(t)}function Yo(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(".");return Do(0,(o<0?0:r-1-o)-i)}function Xo(t,e,n){var i=Ao(t[1]-t[0]);if(!isFinite(i)||0===i)return NaN;var r=Ro(2*Ao(n||1)*Ao(i))/No,o=Ro(Ao(e))/No,a=Do(0,Po(-r+o));return isFinite(a)||(a=NaN),a}function Zo(t,e){var n=G(t,function(t,e){return t+(isNaN(e)?0:e)},0);if(0===n)return[];for(var i=Oo(10,e),r=V(t,function(t){return(isNaN(t)?0:t)/n*i*100}),o=100*i,a=V(r,function(t){return Lo(t)}),s=G(a,function(t,e){return t+e},0),l=V(r,function(t,e){return t-a[e]});su&&(u=l[h],c=h);++a[c],l[c]=0,++s}return V(a,function(t){return t/i})}function jo(t,e){var n=Do(Uo(t),Uo(e)),i=t+e;return n>20?i:Ho(i,n)}var qo=Oo(2,53)-1;function Ko(t){var e=2*Eo;return(t%e+e)%e}function $o(t){return t>-1e-4&&t=10&&e++,e}function na(t,e){var n=ea(t),i=Oo(10,n),r=t/i;return Ho(t=(2===e?1: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)}function ia(t,e){var n=(t.length-1)*e+1,i=Lo(n),r=+t[i-1],o=n-i;return o?r+o*(t[i]-r):r}function ra(t){t.sort(function(t,e){return s(t,e,0)?-1:1});for(var e=-1/0,n=1,i=0;i0?t.length:0,this.item=null,this.key=NaN,this},t.prototype.next=function(){return(this._step>0?this._idx=this._end)&&(this.item=this._list[this._idx],this.key=this._idx=this._idx+this._step,!0)},t}();function Ua(t){t.option=t.parentModel=t.ecModel=null}function Ya(){return[1/0,-1/0]}function Xa(t,e){qa(e)&&(et[1]&&(t[1]=e))}function Za(t,e){qa(e)&&et[1]&&(t[1]=e)}function qa(t){return null!=t&&isFinite(t)}function Ka(t,e){return qa(t)&&qa(e)&&t<=e}function $a(t){Ka(t[0],t[1])&&t[0]>t[1]&&(t[0]=t[1])}function Ja(){var t="__ec_once_"+Qa++;return function(e,n){wt(e,t)||(e[t]=1,n())}}var Qa=sa();function ts(t,e,n){var i=mt(),r=0;B(t,function(o){var a=e(o);var s=i.get(a)||0;n&&n(o,s),s||n||(t[r++]=o),i.set(a,s+1)}),n||(t.length=r)}function es(t){return t.value+""}function ns(t){return t+""}function is(t,e){return at(e,!0)?t.seriesIndex+2:0}function rs(t,e,n){var i=t.getData().count();return{progressiveRender:n.progressiveEnabled&&e.incrementalPrepareRender&&i>=n.threshold,large:t.get("large")&&i>=t.get("largeThreshold"),modDataCount:"mod"===t.get("progressiveChunkMode")?t.getData().count():null}}function os(t,e){return{seriesType:t,overallReset:e}}function as(t){return{overallReset:t}}var ss="___EC__COMPONENT__CONTAINER___",ls="___EC__EXTENDED_CLASS___";function us(t){var e={main:"",sub:""};if(t){var n=t.split(".");e.main=n[0]||"",e.sub=n[1]||""}return e}function cs(t,e){t.$constructor=t,t.extend=function(t){var e,i,r=this;return Z(i=r)&&/^class\s/.test(Function.prototype.toString.call(i))?e=function(t){function e(){return t.apply(this,arguments)||this}return n(e,t),e}(r):(e=function(){(t.$constructor||r).apply(this,arguments)},N(e,this)),k(e.prototype,t),e[ls]=!0,e.extend=this.extend,e.superCall=ps,e.superApply=fs,e.superClass=r,e}}function hs(t,e){t.extend=e.extend}var ds=Math.round(10*Math.random());function ps(t,e){for(var n=[],i=2;i=0||r&&R(r,s)<0)){var l=n.getShallow(s,e);null!=l&&(o[t[a][0]]=l)}}return o}}var ys=vs([["fill","color"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["opacity"],["shadowColor"]]),ms=function(){function t(){}return t.prototype.getAreaStyle=function(t,e){return ys(this,t,e)},t}(),xs=new ni(50);function _s(t){if("string"==typeof t){var e=xs.get(t);return e&&e.image}return t}function bs(t,e,n,i,r){if(t){if("string"==typeof t){if(e&&e.__zrImageSrc===t||!n)return e;var o=xs.get(t),a={hostEl:n,cb:i,cbPayload:r};return o?!Ss(e=o.image)&&o.pending.push(a):((e=c.loadImage(t,ws,ws)).__zrImageSrc=t,xs.put(t,e.__cachedImgObj={image:e,pending:[a]})),e}return t}return e}function ws(){var t=this.__cachedImgObj;this.onload=this.onerror=this.__cachedImgObj=null;for(var e=0;e=s;u++)l-=s;var c=Zr(a,n);return c>l&&(n="",c=0),l=t-c,r.ellipsis=n,r.ellipsisWidth=c,r.contentWidth=l,r.containerWidth=t,r}function Cs(t,e,n){var i=n.containerWidth,r=n.contentWidth,o=n.fontMeasureInfo;if(!i)return t.textLine="",void(t.isTruncated=!1);var a=Zr(o,e);if(a<=i)return t.textLine=e,void(t.isTruncated=!1);for(var s=0;;s++){if(a<=r||s>=n.maxIterations){e+=n.ellipsis;break}var l=0===s?Ds(e,r,o):a>0?Math.floor(e.length*r/a):0;a=Zr(o,e=e.substr(0,l))}""===e&&(e=n.placeholder),t.textLine=e,t.isTruncated=!0}function Ds(t,e,n){for(var i=0,r=0,o=t.length;r0&&f+i.accumWidth>i.width&&(o=e.split("\n"),h=!0),i.accumWidth=f}else{var g=Ns(e,c,i.width,i.breakAll,i.accumWidth);i.accumWidth=g.accumWidth+p,a=g.linesWidths,o=g.lines}}o||(o=e.split("\n"));for(var v=Wr(c),y=0;y=32&&e<=591||e>=880&&e<=4351||e>=4608&&e<=5119||e>=7680&&e<=8303}(t)||!!Os[t]}function Ns(t,e,n,i,r){for(var o=[],a=[],s="",l="",u=0,c=0,h=Wr(e),d=0;dn:r+c+f>n)?c?(s||l)&&(g?(s||(s=l,l="",c=u=0),o.push(s),a.push(c-u),l+=p,s="",c=u+=f):(l&&(s+=l,l="",u=0),o.push(s),a.push(c),s=p,c=f)):g?(o.push(l),a.push(u),l=p,u=f):(o.push(p),a.push(f)):(c+=f,g?(l+=p,u+=f):(l&&(s+=l,l="",u=0),s+=p))}else l&&(s+=l,c+=u),o.push(s),a.push(c),s="",l="",u=0,c=0}return l&&(s+=l),s&&(o.push(s),a.push(c)),1===o.length&&(c+=r),{accumWidth:c,lines:o,linesWidths:a}}function Es(t,e,n,i,r,o){if(t.baseX=n,t.baseY=i,t.outerWidth=t.outerHeight=null,e){var a=2*e.width,s=2*e.height;Xe.set(zs,Kr(n,a,r),$r(i,s,o),a,s),Xe.intersect(e,zs,null,Bs);var l=Bs.outIntersectRect;t.outerWidth=l.width,t.outerHeight=l.height,t.baseX=Kr(l.x,l.width,r,!0),t.baseY=$r(l.y,l.height,o,!0)}}var zs=new Xe(0,0,0,0),Bs={outIntersectRect:{},clamp:!0};function Vs(t){return null!=t?t+="":t=""}function Gs(t,e,n,i){var r=new Xe(Kr(t.x||0,e,t.textAlign),$r(t.y||0,n,t.textBaseline),e,n),o=null!=i?i:Fs(t)?t.lineWidth:0;return o>0&&(r.x-=o/2,r.y-=o/2,r.width+=o,r.height+=o),r}function Fs(t){var e=t.stroke;return null!=e&&"none"!==e&&t.lineWidth>0}var Hs="__zr_style_"+Math.round(10*Math.random()),Ws={shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0,shadowColor:"#000",opacity:1,blend:"source-over"},Us={style:{shadowBlur:!0,shadowOffsetX:!0,shadowOffsetY:!0,shadowColor:!0,opacity:!0}};Ws[Hs]=!0;var Ys=["z","z2","invisible"],Xs=["invisible"],Zs=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=W(e),i=0;i1e-4)return s[0]=t-n,s[1]=e-i,l[0]=t+n,void(l[1]=e+i);if(el[0]=Qs(r)*n+t,el[1]=Js(r)*i+e,nl[0]=Qs(o)*n+t,nl[1]=Js(o)*i+e,u(s,el,nl),c(l,el,nl),(r%=tl)<0&&(r+=tl),(o%=tl)<0&&(o+=tl),r>o&&!a?o+=tl:rr&&(il[0]=Qs(p)*n+t,il[1]=Js(p)*i+e,u(s,il,s),c(l,il,l))}var hl={M:1,L:2,C:3,Q:4,A:5,Z:6,R:7},dl=[],pl=[],fl=[],gl=[],vl=[],yl=[],ml=Math.min,xl=Math.max,_l=Math.cos,bl=Math.sin,wl=Math.abs,Sl=Math.PI,Ml=2*Sl,Il="undefined"!=typeof Float32Array,Tl=[];function Cl(t){return Math.round(t/Sl*1e8)/1e8%2*Sl}function Dl(t,e){var n=Cl(t[0]);n<0&&(n+=Ml);var i=n-t[0],r=t[1];r+=i,!e&&r-n>=Ml?r=n+Ml:e&&n-r>=Ml?r=n-Ml:!e&&n>r?r=n+(Ml-Cl(n-r)):e&&n0&&(this._ux=wl(n/Cr/t)||0,this._uy=wl(n/Cr/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(hl.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=wl(t-this._xi),i=wl(e-this._yi),r=n>this._ux||i>this._uy;if(this.addData(hl.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(hl.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(hl.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(),Tl[0]=i,Tl[1]=r,Dl(Tl,o),i=Tl[0];var a=(r=Tl[1])-i;return this.addData(hl.A,t,e,n,n,i,a,0,o?0:1),this._ctx&&this._ctx.arc(t,e,n,i,r,o),this._xi=_l(r)*n+t,this._yi=bl(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(hl.R,t,e,n,i),this},t.prototype.closePath=function(){this._drawPendingPt(),this.addData(hl.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){if(this._saveData){var e=t.length;this.data&&this.data.length===e||!Il||(this.data=new Float32Array(e));for(var n=0;n0&&o))for(var a=0;au.length&&(this._expandData(),u=this.data);for(var c=0;c0&&(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(){fl[0]=fl[1]=vl[0]=vl[1]=Number.MAX_VALUE,gl[0]=gl[1]=yl[0]=yl[1]=-Number.MAX_VALUE;var t,e=this.data,n=0,i=0,r=0,o=0;for(t=0;tn||wl(v)>i||h===e-1)&&(f=Math.sqrt(A*A+v*v),r=g,o=x);break;case hl.C:var y=t[h++],m=t[h++],x=(g=t[h++],t[h++]),_=t[h++],b=t[h++];f=Un(r,o,y,m,g,x,_,b,10),r=_,o=b;break;case hl.Q:f=Kn(r,o,y=t[h++],m=t[h++],g=t[h++],x=t[h++],10),r=g,o=x;break;case hl.A:var w=t[h++],S=t[h++],M=t[h++],I=t[h++],T=t[h++],C=t[h++],D=C+T;h+=1,p&&(a=_l(T)*M+w,s=bl(T)*I+S),f=xl(M,I)*ml(Ml,Math.abs(C)),r=_l(D)*M+w,o=bl(D)*I+S;break;case hl.R:a=r=t[h++],s=o=t[h++],f=2*t[h++]+2*t[h++];break;case hl.Z:var A=a-r;v=s-o;f=Math.sqrt(A*A+v*v),r=a,o=s}f>=0&&(l[c++]=f,u+=f)}return this._pathLen=u,u},t.prototype.rebuildPath=function(t,e){var n,i,r,o,a,s,l,u,c,h,d=this.data,p=this._ux,f=this._uy,g=this._len,v=e<1,y=0,m=0,x=0;if(!v||(this._pathSegLen||this._calculateLength(),l=this._pathSegLen,u=e*this._pathLen))t:for(var _=0;_0&&(t.lineTo(c,h),x=0),b){case hl.M:n=r=d[_++],i=o=d[_++],t.moveTo(r,o);break;case hl.L:a=d[_++],s=d[_++];var S=wl(a-r),M=wl(s-o);if(S>p||M>f){if(v){if(y+(j=l[m++])>u){var I=(u-y)/j;t.lineTo(r*(1-I)+a*I,o*(1-I)+s*I);break t}y+=j}t.lineTo(a,s),r=a,o=s,x=0}else{var T=S*S+M*M;T>x&&(c=a,h=s,x=T)}break;case hl.C:var C=d[_++],D=d[_++],A=d[_++],k=d[_++],L=d[_++],P=d[_++];if(v){if(y+(j=l[m++])>u){Hn(r,C,A,L,I=(u-y)/j,dl),Hn(o,D,k,P,I,pl),t.bezierCurveTo(dl[1],pl[1],dl[2],pl[2],dl[3],pl[3]);break t}y+=j}t.bezierCurveTo(C,D,A,k,L,P),r=L,o=P;break;case hl.Q:C=d[_++],D=d[_++],A=d[_++],k=d[_++];if(v){if(y+(j=l[m++])>u){jn(r,C,A,I=(u-y)/j,dl),jn(o,D,k,I,pl),t.quadraticCurveTo(dl[1],pl[1],dl[2],pl[2]);break t}y+=j}t.quadraticCurveTo(C,D,A,k),r=A,o=k;break;case hl.A:var O=d[_++],R=d[_++],N=d[_++],E=d[_++],z=d[_++],B=d[_++],V=d[_++],G=!d[_++],F=N>E?N:E,H=wl(N-E)>.001,W=z+B,U=!1;if(v)y+(j=l[m++])>u&&(W=z+B*(u-y)/j,U=!0),y+=j;if(H&&t.ellipse?t.ellipse(O,R,N,E,V,z,W,G):t.arc(O,R,F,z,W,G),U)break t;w&&(n=_l(z)*N+O,i=bl(z)*E+R),r=_l(W)*N+O,o=bl(W)*E+R;break;case hl.R:n=r=d[_],i=o=d[_+1],a=d[_++],s=d[_++];var Y=d[_++],X=d[_++];if(v){if(y+(j=l[m++])>u){var Z=u-y;t.moveTo(a,s),t.lineTo(a+ml(Z,Y),s),(Z-=Y)>0&&t.lineTo(a+Y,s+ml(Z,X)),(Z-=X)>0&&t.lineTo(a+xl(Y-Z,0),s+X),(Z-=Y)>0&&t.lineTo(a,s+xl(X-Z,0));break t}y+=j}t.rect(a,s,Y,X);break;case hl.Z:if(v){var j;if(y+(j=l[m++])>u){I=(u-y)/j;t.lineTo(r*(1-I)+n*I,o*(1-I)+i*I);break t}y+=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.prototype.canSave=function(){return!!this._saveData},t.CMD=hl,t.initDefaultProps=((e=t.prototype)._saveData=!0,e._ux=0,e._uy=0,e._pendingPtDist=0,void(e._version=0)),t}();function kl(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+h&&c>i+h&&c>o+h&&c>s+h||ct+h&&u>n+h&&u>r+h&&u>a+h||ue+u&&l>i+u&&l>o+u||lt+u&&s>n+u&&s>r+u||sn||c+ur&&(r+=Nl);var d=Math.atan2(l,s);return d<0&&(d+=Nl),d>=i&&d<=r||d+Nl>=i&&d+Nl<=r}function zl(t,e,n,i,r,o){if(o>e&&o>i||or?s:0}var Bl=Al.CMD,Vl=2*Math.PI;var Gl=[-1,-1,-1],Fl=[-1,-1];function Hl(){var t=Fl[0];Fl[0]=Fl[1],Fl[1]=t}function Wl(t,e,n,i,r,o,a,s,l,u){if(u>e&&u>i&&u>o&&u>s||u1&&Hl(),p=Bn(e,i,o,s,Fl[0]),d>1&&(f=Bn(e,i,o,s,Fl[1]))),2===d?ve&&s>i&&s>o||s=0&&c<=1&&(r[l++]=c);else{var u=a*a-4*o*s;if(En(u))(c=-a/(2*o))>=0&&c<=1&&(r[l++]=c);else if(u>0){var c,h=Dn(u),d=(-a-h)/(2*o);(c=(-a+h)/(2*o))>=0&&c<=1&&(r[l++]=c),d>=0&&d<=1&&(r[l++]=d)}}return l}(e,i,o,s,Gl);if(0===l)return 0;var u=Zn(e,i,o);if(u>=0&&u<=1){for(var c=0,h=Yn(e,i,o,u),d=0;dn||s<-n)return 0;var l=Math.sqrt(n*n-s*s);Gl[0]=-l,Gl[1]=l;var u=Math.abs(i-r);if(u<1e-4)return 0;if(u>=Vl-1e-4){i=0,r=Vl;var c=o?1:-1;return a>=Gl[0]+t&&a<=Gl[1]+t?c:0}if(i>r){var h=i;i=r,r=h}i<0&&(i+=Vl,r+=Vl);for(var d=0,p=0;p<2;p++){var f=Gl[p];if(f+t>a){var g=Math.atan2(s,f);c=o?1:-1;g<0&&(g=Vl+g),(g>=i&&g<=r||g+Vl>=i&&g+Vl<=r)&&(g>Math.PI/2&&g<1.5*Math.PI&&(c=-c),d+=c)}}return d}function Xl(t,e,n,i,r){for(var o,a,s,l,u=t.data,c=t.len(),h=0,d=0,p=0,f=0,g=0,v=0;v1&&(n||(h+=zl(d,p,f,g,i,r))),m&&(f=d=u[v],g=p=u[v+1]),y){case Bl.M:d=f=u[v++],p=g=u[v++];break;case Bl.L:if(n){if(kl(d,p,u[v],u[v+1],e,i,r))return!0}else h+=zl(d,p,u[v],u[v+1],i,r)||0;d=u[v++],p=u[v++];break;case Bl.C:if(n){if(Ll(d,p,u[v++],u[v++],u[v++],u[v++],u[v],u[v+1],e,i,r))return!0}else h+=Wl(d,p,u[v++],u[v++],u[v++],u[v++],u[v],u[v+1],i,r)||0;d=u[v++],p=u[v++];break;case Bl.Q:if(n){if(Pl(d,p,u[v++],u[v++],u[v],u[v+1],e,i,r))return!0}else h+=Ul(d,p,u[v++],u[v++],u[v],u[v+1],i,r)||0;d=u[v++],p=u[v++];break;case Bl.A:var x=u[v++],_=u[v++],b=u[v++],w=u[v++],S=u[v++],M=u[v++];v+=1;var I=!!(1-u[v++]);o=Math.cos(S)*b+x,a=Math.sin(S)*w+_,m?(f=o,g=a):h+=zl(d,p,o,a,i,r);var T=(i-x)*w/b+x;if(n){if(El(x,_,w,S,S+M,I,e,T,r))return!0}else h+=Yl(x,_,w,S,S+M,I,T,r);d=Math.cos(S+M)*b+x,p=Math.sin(S+M)*w+_;break;case Bl.R:if(f=d=u[v++],g=p=u[v++],o=f+u[v++],a=g+u[v++],n){if(kl(f,g,o,g,e,i,r)||kl(o,g,o,a,e,i,r)||kl(o,a,f,a,e,i,r)||kl(f,a,f,g,e,i,r))return!0}else h+=zl(o,g,o,a,i,r),h+=zl(f,a,f,g,i,r);break;case Bl.Z:if(n){if(kl(d,p,f,g,e,i,r))return!0}else h+=zl(d,p,f,g,i,r);d=f,p=g}}return n||(s=p,l=g,Math.abs(s-l)<1e-4)||(h+=zl(d,p,f,g,i,r)||0),0!==h}var Zl=P({fill:"#000",stroke:null,strokePercent:1,fillOpacity:1,strokeOpacity:1,lineDashOffset:0,lineWidth:1,lineCap:"butt",miterLimit:10,strokeNoScale:!1,strokeFirst:!1},Ws),jl={style:P({fill:!0,stroke:!0,strokePercent:!0,fillOpacity:!0,strokeOpacity:!0,lineDashOffset:!0,lineWidth:!0,miterLimit:!0},Us.style)},ql=Fr.concat(["invisible","culling","z","z2","zlevel","parent"]),Kl=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?Dr:e>.2?"#eee":Ar}if(t)return Ar}return Dr},e.prototype.getInsideTextStroke=function(t){var e=this.style.fill;if(j(e)){var n=this.__zr;if(!(!n||!n.isDarkMode())===Ii(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 Al(!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 Xl(t,e,!0,n,i)}(o,a/s,t,e)))return!0}if(this.hasFill())return function(t,e,n){return Xl(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:k(n,t),this.dirtyShape(),this},e.prototype.shapeChanged=function(){return!!(4&this.__dirty)},e.prototype.createStyle=function(t){return _t(Zl,t)},e.prototype._innerSaveToNormal=function(e){t.prototype._innerSaveToNormal.call(this,e);var n=this._normalState;e.shape&&!n.shape&&(n.shape=k({},this.shape))},e.prototype._applyStateObj=function(e,n,i,r,o,a){if(t.prototype._applyStateObj.call(this,e,n,i,r,o,a),1!==this.__inHover){var s,l=!(n&&r);if(n&&n.shape?o?r?s=n.shape:(s=k({},i.shape),k(s,n.shape)):(s=k({},r?this.shape:i.shape),k(s,n.shape)):l&&(s=i.shape),s)if(o){this.shape=k({},this.shape);for(var u={},c=W(s),h=0;hu&&(n*=u/(a=n+i),i*=u/a),r+o>u&&(r*=u/(a=r+o),o*=u/a),i+r>c&&(i*=c/(a=i+r),r*=c/a),n+o>c&&(n*=c/(a=n+o),o*=c/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+c-r),0!==r&&t.arc(s+u-r,l+c-r,r,0,Math.PI/2),t.lineTo(s+o,l+c),0!==o&&t.arc(s+o,l+c-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.closePath()}(t,e):t.rect(n,i,r,o)},e.prototype.isZeroArea=function(){return!this.shape.width||!this.shape.height},e}(Kl);lu.prototype.type="rect";var uu={fill:"#000"},cu={},hu={style:P({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},Us.style)},du=function(t){function e(e){var n=t.call(this)||this;return n.type="text",n._children=[],n._defaultStyle=uu,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;ey&&p){var x=Math.floor(y/d);f=f||v.length>x,m=(v=v.slice(0,x)).length*d}if(r&&c&&null!=g)for(var _=Ts(g,u,e.ellipsis,{minChar:e.truncateMinChar,placeholder:e.placeholder}),b={},w=0;w0,T=0;Tg&&Ps(o,a.substring(g,v),e,f),Ps(o,d[2],e,f,d[1]),g=Ms.lastIndex}gh){var R=o.lines.length;D>0?(I.tokens=I.tokens.slice(0,D),S(I,C,T),o.lines=o.lines.slice(0,M+1)):o.lines=o.lines.slice(0,M),o.isTruncated=o.isTruncated||o.lines.length=0&&"right"===(C=x[T]).align;)this._placeToken(C,t,b,f,I,"right",v),w-=C.width,I-=C.width,T--;for(M+=(s-(M-p)-(g-I)-w)/2;S<=T;)C=x[S],this._placeToken(C,t,b,f,M+C.width/2,"center",v),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,c=i+n/2;"top"===u?c=i+t.height/2:"bottom"===u&&(c=i+n-t.height/2),!t.isLineHolder&&Mu(l)&&this._renderBackground(l,e,"right"===o?r-t.width:"center"===o?r-t.width/2:r,c-t.height/2,t.width,t.height);var h=!!l.backgroundColor,d=t.textPadding;d&&(r=wu(r,o,d),c-=t.height/2-d[0]-t.innerHeight/2);var p=this._getOrCreateChild(Jl),f=p.createStyle();p.useStyle(f);var g=this._defaultStyle,v=!1,y=0,m=!1,x=bu("fill"in l?l.fill:"fill"in e?e.fill:(v=!0,g.fill)),_=_u("stroke"in l?l.stroke:"stroke"in e?e.stroke:h||s||g.autoStroke&&!v?null:(y=2,m=!0,g.stroke)),b=l.textShadowBlur>0||e.textShadowBlur>0;f.text=t.text,f.x=r,f.y=c,b&&(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=st(l.opacity,e.opacity,1),yu(f,l),_&&(f.lineWidth=st(l.lineWidth,e.lineWidth,y),f.lineDash=at(l.lineDash,e.lineDash),f.lineDashOffset=e.lineDashOffset||0,f.stroke=_),x&&(f.fill=x),p.setBoundingRect(Gs(f,t.contentWidth,t.contentHeight,m?0:null))},e.prototype._renderBackground=function(t,e,n,i,r,o){var a,s,l,u=t.backgroundColor,c=t.borderWidth,h=t.borderColor,d=u&&u.image,p=u&&!d,f=t.borderRadius,g=this;if(p||t.lineHeight||c&&h){(a=this._getOrCreateChild(lu)).useStyle(a.createStyle()),a.style.fill=null;var v=a.shape;v.x=n,v.y=i,v.width=r,v.height=o,v.r=f,a.dirtyShape()}if(p)(l=a.style).fill=u||null,l.fillOpacity=at(t.fillOpacity,1);else if(d){(s=this._getOrCreateChild(eu)).onload=function(){g.dirtyStyle()};var y=s.style;y.image=u.image,y.x=n,y.y=i,y.width=r,y.height=o}c&&h&&((l=a.style).lineWidth=c,l.stroke=h,l.strokeOpacity=at(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=st(t.opacity,e.opacity,1)},e.makeFont=function(t){var e="";return mu(t)&&(e=[t.fontStyle,t.fontWeight,vu(t.fontSize),t.fontFamily||"sans-serif"].join(" ")),e&&ht(e)||t.textFont||t.font},e}(Zs),pu={left:!0,right:1,center:1},fu={top:1,bottom:1,middle:1},gu=["fontStyle","fontWeight","fontSize","fontFamily"];function vu(t){return"string"!=typeof t||-1===t.indexOf("px")&&-1===t.indexOf("rem")&&-1===t.indexOf("em")?isNaN(+t)?"12px":t+"px":t}function yu(t,e){for(var n=0;n=0,o=!1;if(t instanceof Kl){var a=Uu(t),s=r&&a.selectFill||a.normalFill,l=r&&a.selectStroke||a.normalStroke;if(ec(s)||ec(l)){var u=(i=i||{}).style||{};"inherit"===u.fill?(o=!0,i=k({},i),(u=k({},u)).fill=s):!ec(u.fill)&&ec(s)?(o=!0,i=k({},i),(u=k({},u)).fill=Ci(s)):!ec(u.stroke)&&ec(l)&&(o||(i=k({},i),u=k({},u)),u.stroke=Ci(l)),i.style=u}}if(i&&null==i.z2){o||(i=k({},i));var c=t.z2EmphasisLift;i.z2=t.z2+(null!=c?c:ju)}return i}(this,0,e,n);if("blur"===t)return function(t,e,n){var i=R(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 Ac(t,e,n){Nc(t,!0),cc(t,pc),Lc(t,e,n)}function kc(t,e,n,i){i?function(t){Nc(t,!1)}(t):Ac(t,e,n)}function Lc(t,e,n){var i=Iu(t);null!=e?(i.focus=e,i.blurScope=n):i.focus&&(i.focus=null)}var Pc=["emphasis","blur","select"],Oc={itemStyle:"getItemStyle",lineStyle:"getLineStyle",areaStyle:"getAreaStyle"};function Rc(t,e,n,i){n=n||"itemStyle";for(var r=0;r1&&(a*=Uc(f),s*=Uc(f));var g=(r===o?-1:1)*Uc((a*a*(s*s)-a*a*(p*p)-s*s*(d*d))/(a*a*(p*p)+s*s*(d*d)))||0,v=g*a*p/s,y=g*-s*d/a,m=(t+n)/2+Xc(h)*v-Yc(h)*y,x=(e+i)/2+Yc(h)*v+Xc(h)*y,_=Kc([1,0],[(d-v)/a,(p-y)/s]),b=[(d-v)/a,(p-y)/s],w=[(-1*d-v)/a,(-1*p-y)/s],S=Kc(b,w);if(qc(b,w)<=-1&&(S=Zc),qc(b,w)>=1&&(S=0),S<0){var M=Math.round(S/Zc*1e6)/1e6;S=2*Zc+M%2*Zc}c.addData(u,m,x,a,s,_,S,h,o)}var Jc=/([mlvhzcqtsa])([^mlvhzcqtsa]*)/gi,Qc=/-?([0-9]*\.)?[0-9]+([eE]-?[0-9]+)?/g;var th=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.applyTransform=function(t){},e}(Kl);function eh(t){return null!=t.setData}function nh(t,e){var n=function(t){var e=new Al;if(!t)return e;var n,i=0,r=0,o=i,a=r,s=Al.CMD,l=t.match(Jc);if(!l)return e;for(var u=0;uk*k+L*L&&(M=T,I=C),{cx:M,cy:I,x0:-c,y0:-h,x1:M*(r/b-1),y1:I*(r/b-1)}}function bh(t,e){var n,i=yh(e.r,0),r=yh(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,c=e.cy,h=!!e.clockwise,d=gh(l-s),p=d>ch&&d%ch;if(p>xh&&(d=p),i>xh)if(d>ch-xh)t.moveTo(u+i*dh(s),c+i*hh(s)),t.arc(u,c,i,s,l,!h),r>xh&&(t.moveTo(u+r*dh(l),c+r*hh(l)),t.arc(u,c,r,l,s,h));else{var f=void 0,g=void 0,v=void 0,y=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*dh(s),L=i*hh(s),P=r*dh(l),O=r*hh(l),R=d>xh;if(R){var N=e.cornerRadius;N&&(n=function(t){var e;if(X(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],v=n[2],y=n[3]);var E=gh(i-r)/2;if(m=mh(E,v),x=mh(E,y),_=mh(E,f),b=mh(E,g),M=w=yh(m,x),I=S=yh(_,b),(w>xh||S>xh)&&(T=i*dh(l),C=i*hh(l),D=r*dh(s),A=r*hh(s),dxh){var U=mh(v,M),Y=mh(y,M),Z=_h(D,A,k,L,i,U,h),j=_h(T,C,P,O,i,Y,h);t.moveTo(u+Z.cx+Z.x0,c+Z.cy+Z.y0),M0&&t.arc(u+Z.cx,c+Z.cy,U,fh(Z.y0,Z.x0),fh(Z.y1,Z.x1),!h),t.arc(u,c,i,fh(Z.cy+Z.y1,Z.cx+Z.x1),fh(j.cy+j.y1,j.cx+j.x1),!h),Y>0&&t.arc(u+j.cx,c+j.cy,Y,fh(j.y1,j.x1),fh(j.y0,j.x0),!h))}else t.moveTo(u+k,c+L),t.arc(u,c,i,s,l,!h);else t.moveTo(u+k,c+L);if(r>xh&&R)if(I>xh){U=mh(f,I),Z=_h(P,O,T,C,r,-(Y=mh(g,I)),h),j=_h(k,L,D,A,r,-U,h);t.lineTo(u+Z.cx+Z.x0,c+Z.cy+Z.y0),I0&&t.arc(u+Z.cx,c+Z.cy,Y,fh(Z.y0,Z.x0),fh(Z.y1,Z.x1),!h),t.arc(u,c,r,fh(Z.cy+Z.y1,Z.cx+Z.x1),fh(j.cy+j.y1,j.cx+j.x1),h),U>0&&t.arc(u+j.cx,c+j.cy,U,fh(j.y1,j.x1),fh(j.y0,j.x0),!h))}else t.lineTo(u+P,c+O),t.arc(u,c,r,l,s,h);else t.lineTo(u+P,c+O)}else t.moveTo(u,c);t.closePath()}}}var wh=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},Sh=function(t){function e(e){return t.call(this,e)||this}return n(e,t),e.prototype.getDefaultShape=function(){return new wh},e.prototype.buildPath=function(t,e){bh(t,e)},e.prototype.isZeroArea=function(){return this.shape.startAngle===this.shape.endAngle||this.shape.r===this.shape.r0},e}(Kl);Sh.prototype.type="sector";var Mh=function(){this.cx=0,this.cy=0,this.r=0,this.r0=0},Ih=function(t){function e(e){return t.call(this,e)||this}return n(e,t),e.prototype.getDefaultShape=function(){return new Mh},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}(Kl);function Th(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=[],c=[],h=[];if(i){a=[1/0,1/0],s=[-1/0,-1/0];for(var d=0,p=t.length;djh[1]){if(r=!1,qh.negativeSize||n)return r;var s=Xh(jh[0]-Zh[1]),l=Xh(Zh[0]-jh[1]);Uh(s,l)>$h.len()&&(s=l||!qh.bidirectional)&&(Pe.scale(Kh,a,-l*i),qh.useDir&&qh.calcDirMTV()))}}return r},t.prototype._getProjMinMaxOnAxis=function(t,e,n){for(var i=this._axes[t],r=this._origin,o=e[0].dot(i)+r[t],a=o,s=o,l=1;l0){var h={duration:c.duration,delay:c.delay||0,easing:c.easing,done:o,force:!!o||!!a,setToFinal:!u,scope:t,during:a};l?e.animateFrom(n,h):e.animateTo(n,h)}else e.stopAnimation(),!l&&e.attr(n),a&&a(1),o&&o()}function rd(t,e,n,i,r,o){id("update",t,e,n,i,r,o)}function od(t,e,n,i,r,o){id("enter",t,e,n,i,r,o)}function ad(t){if(!t.__zr)return!0;for(var e=0;eAo(o[1])?o[0]>0?"right":"left":o[1]>0?"bottom":"top"}function Ad(t){return!t.isGroup}function kd(t,e,n){if(t&&e){var i,r=(i={},t.traverse(function(t){Ad(t)&&t.anid&&(i[t.anid]=t)}),i);e.traverse(function(t){if(Ad(t)&&t.anid){var e=r[t.anid];if(e){var i=o(t);t.attr(o(e)),rd(t,i,n,Iu(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=C(t.shape)),e}}function Ld(t,e){return V(t,function(t){var n=t[0];n=Do(n,e.x),n=Co(n,e.x+e.width);var i=t[1];return i=Do(i,e.y),[n,i=Co(i,e.y+e.height)]})}function Pd(t,e){var n=Do(t.x,e.x),i=Co(t.x+t.width,e.x+e.width),r=Do(t.y,e.y),o=Co(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 Od(t,e,n){var i=k({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),P(r,n),new eu(i)):xd(t.replace("path://",""),i,n,"center")}function Rd(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,v=Ed(f,g,u,c)/p;if(v<0||v>1)return!1;var y=Ed(f,g,h,d)/p;return!(y<0||y>1)}function Ed(t,e,n,i){return t*i-n*e}function zd(t,e,n,i,r){return null==e||(K(e)?Bd[0]=Bd[1]=Bd[2]=Bd[3]=e:(Bd[0]=e[0],Bd[1]=e[1],Bd[2]=e[2],Bd[3]=e[3]),i&&(Bd[0]=Do(0,Bd[0]),Bd[1]=Do(0,Bd[1]),Bd[2]=Do(0,Bd[2]),Bd[3]=Do(0,Bd[3])),n&&(Bd[0]=-Bd[0],Bd[1]=-Bd[1],Bd[2]=-Bd[2],Bd[3]=-Bd[3]),Vd(t,Bd,"x","width",3,1,r&&r[0]||0),Vd(t,Bd,"y","height",0,2,r&&r[1]||0)),t}var Bd=[0,0,0,0];function Vd(t,e,n,i,r,o,a){var s=e[o]+e[r],l=t[i];t[i]+=s,a=Do(0,Co(a,l)),t[i]=0?-e[r]:e[o]>=0?l+e[o]:Ao(s)>1e-8?(l-a)*e[r]/s:0):t[n]-=e[r]}function Gd(t){var e=t.itemTooltipOption,n=t.componentModel,i=t.itemName,r=j(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&&B(W(l),function(t){wt(s,t)||(s[t]=l[t],s.$vars.push(t))});var u=Iu(t.el);u.componentMainType=o,u.componentIndex=a,u.tooltipConfig={name:i,option:P({content:i,encodeHTMLContent:!0,formatterParams:s},r)}}function Fd(t,e){var n;t.isGroup&&(n=e(t)),n||t.traverse(e)}function Hd(t,e){if(t)if(X(t))for(var n=0;ne&&(e=i),ie&&(n=e=0),{min:n,max:e}}function qd(t,e,n){Kd(t,e,n,-1/0)}function Kd(t,e,n,i){if(t.ignoreModelZ)return i;var r=t.getTextContent(),o=t.getTextGuideLine();if(t.isGroup)for(var a=t.childrenRef(),s=0;s-1?Rp:Ep;function Gp(t,e){t=t.toUpperCase(),Bp[t]=new kp(e),zp[t]=e}function Fp(t){return Bp[t]}Gp(Np,{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",custom:"Custom chart",chart:"Chart"}},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:". "}}}}),Gp(Rp,{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:"旭日图",custom:"自定义图表",chart:"图表"}},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 Hp=null;function Wp(){return Hp}function Up(t,e){var n=Wp(),i=e.breakOption,r=e.breakParsed;return!r&&n&&(r=n.parseAxisBreakOption(i,t)),r}function Yp(t){var e=t.brk;return e?e.breaks:[]}function Xp(t){var e=t.brk;return!!e&&e.hasBreaks()}var Zp=1e3,jp=6e4,qp=36e5,Kp=864e5,$p=31536e6,Jp={year:/({yyyy}|{yy})/,month:/({MMMM}|{MMM}|{MM}|{M})/,day:/({dd}|{d})/,hour:/({HH}|{H}|{hh}|{h})/,minute:/({mm}|{m})/,second:/({ss}|{s})/,millisecond:/({SSS}|{S})/},Qp={year:"{yyyy}",month:"{MMM}",day:"{d}",hour:"{HH}:{mm}",minute:"{HH}:{mm}",second:"{HH}:{mm}:{ss}",millisecond:"{HH}:{mm}:{ss} {SSS}"},tf="{yyyy}-{MM}-{dd}",ef={year:"{yyyy}",month:"{yyyy}-{MM}",day:tf,hour:tf+" "+Qp.hour,minute:tf+" "+Qp.minute,second:tf+" "+Qp.second,millisecond:"{yyyy}-{MM}-{dd} {HH}:{mm}:{ss} {SSS}"},nf=["year","month","day","hour","minute","second","millisecond"],rf=["year","half-year","quarter","month","week","half-week","day","half-day","quarter-day","hour","minute","second","millisecond"];function of(t){return j(t)||Z(t)?t:function(t){t=t||{};var e={},n=!0;return B(nf,function(e){n&&(n=null==t[e])}),B(nf,function(i,r){var o=t[i];e[i]={};for(var a=null,s=r;s>=0;s--){var l=nf[s],u=$(o)&&!X(o)?o[l]:o,c=void 0;X(u)?a=(c=u.slice())[0]||"":j(u)?c=[a=u]:(null==a?a=Qp[i]:Jp[l].test(a)||(a=e[l][l][0]+" "+a),c=[a],n&&(c[1]="{primary|"+a+"}")),e[i][l]=c}}),e}(t)}function af(t,e){return"0000".substr(0,e-(t+="").length)+t}function sf(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 lf(t){return t===sf(t)}function uf(t,e,n,i){var r=Qo(t),o=r[df(n)](),a=r[pf(n)]()+1,s=Math.floor((a-1)/3)+1,l=r[ff(n)](),u=r["get"+(n?"UTC":"")+"Day"](),c=r[gf(n)](),h=(c-1)%12+1,d=r[vf(n)](),p=r[yf(n)](),f=r[mf(n)](),g=c>=12?"pm":"am",v=g.toUpperCase(),y=(i instanceof kp?i:Fp(i||Vp)||Bp[Ep]).getModel("time"),m=y.get("month"),x=y.get("monthAbbr"),_=y.get("dayOfWeek"),b=y.get("dayOfWeekAbbr");return(e||"").replace(/{a}/g,g+"").replace(/{A}/g,v+"").replace(/{yyyy}/g,o+"").replace(/{yy}/g,af(o%100+"",2)).replace(/{Q}/g,s+"").replace(/{MMMM}/g,m[a-1]).replace(/{MMM}/g,x[a-1]).replace(/{MM}/g,af(a,2)).replace(/{M}/g,a+"").replace(/{dd}/g,af(l,2)).replace(/{d}/g,l+"").replace(/{eeee}/g,_[u]).replace(/{ee}/g,b[u]).replace(/{e}/g,u+"").replace(/{HH}/g,af(c,2)).replace(/{H}/g,c+"").replace(/{hh}/g,af(h+"",2)).replace(/{h}/g,h+"").replace(/{mm}/g,af(d,2)).replace(/{m}/g,d+"").replace(/{ss}/g,af(p,2)).replace(/{s}/g,p+"").replace(/{SSS}/g,af(f,3)).replace(/{S}/g,f+"")}function cf(t,e){var n=Qo(t),i=n[pf(e)]()+1,r=n[ff(e)](),o=n[gf(e)](),a=n[vf(e)](),s=n[yf(e)](),l=0===n[mf(e)](),u=l&&0===s,c=u&&0===a,h=c&&0===o,d=h&&1===r;return d&&1===i?"year":d?"month":h?"day":c?"hour":u?"minute":l?"second":"millisecond"}function hf(t,e,n){switch(e){case"year":t[_f(n)](0);case"month":t[bf(n)](1);case"day":t[wf(n)](0);case"hour":t[Sf(n)](0);case"minute":t[Mf(n)](0);case"second":t[If(n)](0)}return t}function df(t){return t?"getUTCFullYear":"getFullYear"}function pf(t){return t?"getUTCMonth":"getMonth"}function ff(t){return t?"getUTCDate":"getDate"}function gf(t){return t?"getUTCHours":"getHours"}function vf(t){return t?"getUTCMinutes":"getMinutes"}function yf(t){return t?"getUTCSeconds":"getSeconds"}function mf(t){return t?"getUTCMilliseconds":"getMilliseconds"}function xf(t){return t?"setUTCFullYear":"setFullYear"}function _f(t){return t?"setUTCMonth":"setMonth"}function bf(t){return t?"setUTCDate":"setDate"}function wf(t){return t?"setUTCHours":"setHours"}function Sf(t){return t?"setUTCMinutes":"setMinutes"}function Mf(t){return t?"setUTCSeconds":"setSeconds"}function If(t){return t?"setUTCMilliseconds":"setMilliseconds"}function Tf(t){if(!aa(t))return j(t)?t:"-";var e=(t+"").split(".");return e[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g,"$1,")+(e.length>1?"."+e[1]:"")}function Cf(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 Df=ut;function Af(t,e,n){function i(t){return t&&ht(t)?t:"-"}function r(t){return ca(t)}var o="time"===e,a=t instanceof Date;if(o||a){var s=o?Qo(t):t;if(!isNaN(+s))return uf(s,"{yyyy}-{MM}-{dd} {HH}:{mm}:{ss}",n);if(a)return"-"}if("ordinal"===e)return q(t)?i(t):K(t)&&r(t)?t+"":"-";var l=oa(t);return r(l)?Tf(l):q(t)?i(t):"boolean"==typeof t?t+"":"-"}var kf=["a","b","c","d","e","f","g"],Lf=function(t,e){return"{"+t+(null==e?"":e)+"}"};function Pf(t,e,n){X(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 Nf(t,e){return e=e||"transparent",j(t)?t:$(t)&&t.colorStops&&(t.colorStops[0]||{}).color||e}function Ef(t,e){if("_blank"===e||"blank"===e){var n=window.open();n.opener=null,n.location.href=t}else window.open(t,e)}var zf={},Bf={},Vf=function(){function t(){this._normalMasterList=[],this._nonSeriesBoxMasterList=[]}return t.prototype.create=function(t,e){function n(n,i){var r=[];return B(n,function(n,i){var o=n.create(t,e);r=r.concat(o||[])}),r}this._nonSeriesBoxMasterList=n(zf,!0),this._normalMasterList=n(Bf,!1)},t.prototype.update=function(t,e){B(this._normalMasterList,function(n){n.update&&n.update(t,e)})},t.prototype.getCoordinateSystems=function(){return this._normalMasterList.concat(this._nonSeriesBoxMasterList)},t.register=function(t,e){"matrix"!==t&&"calendar"!==t?Bf[t]=e:zf[t]=e},t.get=function(t){return Bf[t]||zf[t]},t}();var Gf=mt();function Ff(t){var e=t.getShallow("coord",!0),n=1;if(null==e){var i=Gf.get(t.type);i&&i.getCoord2&&(n=2,e=i.getCoord2(t))}return{coord:e,from:n}}function Hf(t,e){var n=t.getShallow("coordinateSystem"),i=t.getShallow("coordinateSystemUsage",!0),r=0;if(n){var o="series"===t.mainType;null==i&&(i=o?"data":"box"),"data"===i?(r=1,o||(r=0)):"box"===i&&(r=2,o||function(t){return!!zf[t]}(n)||(r=0))}return{coordSysType:n,kind:r}}function Wf(t){var e=t.targetModel,n=t.coordSysType,i=t.coordSysProvider,r=t.isDefaultDataCoordSys;t.allowNotFound;var o=Hf(e),a=o.kind,s=o.coordSysType;if(r&&1!==a&&(a=1,s=n),0===a||s!==n)return 0;var l=i(n,e);return l?(1===a?e.coordinateSystem=l:e.boxCoordinateSystem=l,a):0}var Uf=function(t,e){var n=e.getReferringComponents(t,Ea).models[0];return n&&n.coordinateSystem},Yf=B,Xf=["left","right","top","bottom","width","height"],Zf=[["width","left","right"],["height","top","bottom"]];function jf(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 c,h,d=l.getBoundingRect(),p=e.childAt(u+1),f=p&&p.getBoundingRect();if("horizontal"===t){var g=d.width+(f?-f.x+d.x:0);(c=o+g)>i||l.newline?(o=0,c=g,a+=s+n,s=d.height):s=Math.max(s,d.height)}else{var v=d.height+(f?-f.y+d.y:0);(h=a+v)>r||l.newline?(o+=s+n,a=0,h=v,s=d.width):s=Math.max(s,d.width)}l.newline||(l.x=o,l.y=a,l.markRedraw(),"horizontal"===t?o=c+n:a=h+n)})}var qf=jf;Y(jf,"vertical"),Y(jf,"horizontal");function Kf(t,e){return{left:t.getShallow("left",e),top:t.getShallow("top",e),right:t.getShallow("right",e),bottom:t.getShallow("bottom",e),width:t.getShallow("width",e),height:t.getShallow("height",e)}}function $f(t,e){var n=function(t,e){var n,i,r=eg(t,e,{enableLayoutOnlyByCenter:!0}),o=t.getBoxLayoutParams();if(r.type===tg.point)i=r.refPoint,n=Jf(o,{width:e.getWidth(),height:e.getHeight()});else{var a=t.get("center"),s=X(a)?a:[a,a];n=Jf(o,r.refContainer),i=2===r.boxCoordFrom?r.refPoint:[Vo(s[0],n.width)+n.x,Vo(s[1],n.height)+n.y]}return{viewRect:n,center:i}}(t,e),i=n.viewRect,r=n.center,o=t.get("radius");X(o)||(o=[0,o]);var a=Vo(i.width,e.getWidth()),s=Vo(i.height,e.getHeight()),l=Math.min(a,s),u=Vo(o[0],l/2),c=Vo(o[1],l/2);return{cx:r[0],cy:r[1],r0:u,r:c,viewRect:i}}function Jf(t,e,n){n=Df(n||0);var i=e.width,r=e.height,o=Vo(t.left,i),a=Vo(t.top,r),s=Vo(t.right,i),l=Vo(t.bottom,r),u=Vo(t.width,i),c=Vo(t.height,r),h=n[2]+n[0],d=n[1]+n[3],p=t.aspect;switch(isNaN(u)&&(u=i-s-d-o),isNaN(c)&&(c=r-l-h-a),null!=p&&(isNaN(u)&&isNaN(c)&&(p>i/r?u=.8*i:c=.8*r),isNaN(u)&&(u=p*c),isNaN(c)&&(c=u/p)),isNaN(o)&&(o=i-s-u-d),isNaN(a)&&(a=r-l-c-h),t.left||t.right){case"center":o=i/2-u/2-n[3];break;case"right":o=i-u-d}switch(t.top||t.bottom){case"middle":case"center":a=r/2-c/2-n[0];break;case"bottom":a=r-c-h}o=o||0,a=a||0,isNaN(u)&&(u=i-d-o-(s||0)),isNaN(c)&&(c=r-h-a-(l||0));var f=new Xe((e.x||0)+o+n[3],(e.y||0)+a+n[0],u,c);return f.margin=n,f}function Qf(t,e,n){var i=t.getShallow("preserveAspect",!0);if(!i)return e;var r=e.width/e.height;if(Math.abs(Math.atan(n)-Math.atan(r))<1e-9)return e;var o=t.getShallow("preserveAspectAlign",!0),a=t.getShallow("preserveAspectVerticalAlign",!0),s={width:e.width,height:e.height},l="cover"===i;return r>n&&!l||r=2)return o;for(var c=0;c=0;a--)o=D(o,n[a],!0);e.defaultOption=o}return e.defaultOption},e.prototype.getReferringComponents=function(t,e){var n=t+"Index",i=t+"Id";return Ba(this.ecModel,t,{index:this.get(n,!0),id:this.get(i,!0)},e)},e.prototype.getBoxLayoutParams=function(){return Kf(this,!1)},e.prototype.getZLevelKey=function(){return""},e.prototype.setZLevel=function(t){this.option.zlevel=t},e.protoInitialize=((i=e.prototype).type="component",i.id="",i.name="",i.mainType="",i.subType="",void(i.componentIndex=0)),e}(kp);hs(lg,kp),gs(lg),function(t){var e={};t.registerSubTypeDefaulter=function(t,n){var i=us(t);e[i.main]=n},t.determineSubType=function(n,i){var r=i.type;if(!r){var o=us(n).main;t.hasSubTypes(n)&&e[o]&&(r=e[o](i))}return r}}(lg),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 B(t,function(o){var a=n(i,o),s=function(t,e){var n=[];return B(t,function(t){R(e,t)>=0&&n.push(t)}),n}(a.originalDeps=e(o),t);a.entryCount=s.length,0===a.entryCount&&r.push(o),B(s,function(t){R(a.predecessor,t)<0&&a.predecessor.push(t);var e=n(i,t);R(e.successor,t)<0&&e.successor.push(o)})}),{graph:i,noEntryList:r}}(i),s=a.graph,l=a.noEntryList,u={};for(B(t,function(t){u[t]=!0});l.length;){var c=l.pop(),h=s[c],d=!!u[c];d&&(r.call(o,c,h.originalDeps.slice()),delete u[c]),B(h.successor,d?f:p)}B(u,function(){var t="";throw new Error(t)})}function p(t){s[t].entryCount--,0===s[t].entryCount&&l.push(t)}function f(t){u[t]=!0,p(t)}}}(lg,function(t){var e=[];B(lg.getClassesByMainType(t),function(t){e=e.concat(t.dependencies||t.prototype.dependencies||[])}),e=V(e,function(t){return us(t).main}),"dataset"!==t&&R(e,"dataset")<=0&&e.unshift("dataset");return e});var ug={color:{},darkColor:{},size:{}},cg=ug.color={theme:["#5070dd","#b6d634","#505372","#ff994d","#0ca8df","#ffd10a","#fb628b","#785db0","#3fbe95"],neutral00:"#fff",neutral05:"#f4f7fd",neutral10:"#e8ebf0",neutral15:"#dbdee4",neutral20:"#cfd2d7",neutral25:"#c3c5cb",neutral30:"#b7b9be",neutral35:"#aaacb2",neutral40:"#9ea0a5",neutral45:"#929399",neutral50:"#86878c",neutral55:"#797b7f",neutral60:"#6d6e73",neutral65:"#616266",neutral70:"#54555a",neutral75:"#48494d",neutral80:"#3c3c41",neutral85:"#303034",neutral90:"#232328",neutral95:"#17171b",neutral99:"#000",accent05:"#eff1f9",accent10:"#e0e4f2",accent15:"#d0d6ec",accent20:"#c0c9e6",accent25:"#b1bbdf",accent30:"#a1aed9",accent35:"#91a0d3",accent40:"#8292cc",accent45:"#7285c6",accent50:"#6578ba",accent55:"#5c6da9",accent60:"#536298",accent65:"#4a5787",accent70:"#404c76",accent75:"#374165",accent80:"#2e3654",accent85:"#252b43",accent90:"#1b2032",accent95:"#121521",transparent:"rgba(0,0,0,0)",highlight:"rgba(255,231,130,0.8)"};for(var hg in k(cg,{primary:cg.neutral80,secondary:cg.neutral70,tertiary:cg.neutral60,quaternary:cg.neutral50,disabled:cg.neutral20,border:cg.neutral30,borderTint:cg.neutral20,borderShade:cg.neutral40,background:cg.neutral05,backgroundTint:"rgba(234,237,245,0.5)",backgroundTransparent:"rgba(255,255,255,0)",backgroundShade:cg.neutral10,shadow:"rgba(0,0,0,0.2)",shadowTint:"rgba(129,130,136,0.2)",axisLine:cg.neutral70,axisLineTint:cg.neutral40,axisTick:cg.neutral70,axisTickMinor:cg.neutral60,axisLabel:cg.neutral70,axisSplitLine:cg.neutral15,axisMinorSplitLine:cg.neutral05}),cg)if(cg.hasOwnProperty(hg)){var dg=cg[hg];"theme"===hg?ug.darkColor.theme=cg.theme.slice():"highlight"===hg?ug.darkColor.highlight="rgba(255,231,130,0.4)":0===hg.indexOf("accent")?ug.darkColor[hg]=wi(dg,null,function(t){return.5*t},function(t){return Math.min(1,1.3-t)}):ug.darkColor[hg]=wi(dg,null,function(t){return.9*t},function(t){return 1-Math.pow(t,1.5)})}ug.size={xxs:2,xs:5,s:10,m:15,l:20,xl:30,xxl:40,xxxl:50};var pg="";"undefined"!=typeof navigator&&(pg=navigator.platform||"");var fg="rgba(0, 0, 0, 0.2)",gg=ug.color.theme[0],vg=wi(gg,null,null,.9),yg={darkMode:"auto",colorBy:"series",color:ug.color.theme,gradientColor:[vg,gg],aria:{decal:{decals:[{color:fg,dashArrayX:[1,0],dashArrayY:[2,5],symbolSize:1,rotation:Math.PI/6},{color:fg,symbol:"circle",dashArrayX:[[8,8],[0,8,8,0]],dashArrayY:[6,0],symbolSize:.8},{color:fg,dashArrayX:[1,0],dashArrayY:[4,3],rotation:-Math.PI/4},{color:fg,dashArrayX:[[6,6],[0,6,6,0]],dashArrayY:[6,0]},{color:fg,dashArrayX:[[1,0],[1,6]],dashArrayY:[1,0,6,0],rotation:Math.PI/4},{color:fg,symbol:"triangle",dashArrayX:[[9,9],[0,9,9,0]],dashArrayY:[7,2],symbolSize:.75}]}},textStyle:{fontFamily:pg.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},mg=1,xg=2,_g=3,bg=Pa();function wg(t,e,n){var i={},r=Mg(e);if(!r||!t)return i;var o,a,s=[],l=[],u=e.ecModel,c=bg(u).datasetMap,h=r.uid+"_"+n.seriesLayoutBy;B(t=t.slice(),function(e,n){var r=$(e)?e:t[n]={name:e};"ordinal"===r.type&&null==o&&(o=n,a=f(r)),i[r.name]=[]});var d=c.get(h)||c.set(h,{categoryWayDim:a,valueWayDim:0});function p(t,e,n){for(var i=0;ie)return t[i];return t[n-1]}(i,a):n;if((c=c||n)&&c.length){var h=c[l];return r&&(u[r]=h),s.paletteIdx=(l+1)%c.length,h}}var Eg="\0_ec_inner";var zg=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 kp(i),this._locale=new kp(r),this._optionManager=o},e.prototype.setOption=function(t,e,n){var i=Gg(e);this._optionManager.setOption(t,n,i),this._resetOption(null,i)},e.prototype.resetOption=function(t,e){return this._resetOption(t,Gg(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)):kg(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&&B(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=mt(),s=e&&e.replaceMergeMainTypeMap;bg(this).datasetMap=mt(),B(t,function(t,e){null!=t&&(lg.hasClass(e)?e&&(o.push(e),a.set(e,!0)):n[e]=null==n[e]?C(t):D(n[e],t,!0))}),s&&s.each(function(t,e){lg.hasClass(e)&&!a.get(e)&&(o.push(e),a.set(e,!0))}),lg.topologicalTravel(o,lg.getAllClassMainTypes(),function(e){var o=function(t,e,n){var i=Cg.get(e);if(!i)return n;var r=i(t);return r?n.concat(r):n}(this,e,_a(t[e])),a=i.get(e),l=a?s&&s.get(e)?"replaceMerge":"normalMerge":"replaceAll",u=Ia(a,o,l);(function(t,e,n){B(t,function(t){var i=t.newOption;$(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,lg),n[e]=null,i.set(e,null),r.set(e,0);var c,h=[],d=[],p=0;B(u,function(t,n){var i=t.existing,r=t.newOption;if(r){var o="series"===e,a=lg.getClass(e,t.keyInfo.subType,!o);if(!a)return;if("tooltip"===e){if(c)return void 0;c=!0}if(i&&i.constructor===a)i.name=t.keyInfo.name,i.mergeOption(r,this),i.optionUpdated(r,!1);else{var s=k({componentIndex:n},t.keyInfo);k(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?(h.push(i.option),d.push(i),p++):(h.push(void 0),d.push(void 0))},this),n[e]=h,i.set(e,d),r.set(e,p),"series"===e&&Dg(this)},this),this._seriesIndices||Dg(this)},e.prototype.getOption=function(){var t=C(this.option);return B(t,function(e,n){if(lg.hasClass(n)){for(var i=_a(e),r=i.length,o=!1,a=r-1;a>=0;a--)i[a]&&!ka(i[a])?o=!0:(i[a]=null,!o&&r--);i.length=r,t[n]=i}}),delete t[Eg],t},e.prototype.setTheme=function(t){this._theme=new kp(t),this._resetOption("recreate",null)},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 Ug=B,Yg=$,Xg=["areaStyle","lineStyle","nodeStyle","linkStyle","chordStyle","label","labelLine"];function Zg(t){var e=t&&t.itemStyle;if(e)for(var n=0,i=Xg.length;n0?t[n-1].seriesModel:null)}),function(t){B(t,function(e,n){var i=[],r=[NaN,NaN],o=[e.stackResultDimension,e.stackedOverDimension],a=e.data,s=e.isStackedByIndex,l=e.seriesModel.get("stackStrategy")||"samesign";a.modify(o,function(o,u,c){var h,d,p=a.get(e.stackedDimension,c);if(isNaN(p))return r;s?d=a.getRawIndex(c):h=a.get(e.stackedByDimension,c);for(var f=NaN,g=n-1;g>=0;g--){var v=t[g];if(s||(d=v.data.rawIndexOf(v.stackedByDimension,h)),d>=0){var y=v.data.getByRawIndex(v.stackResultDimension,d);if("all"===l||"positive"===l&&y>0||"negative"===l&&y<0||"samesign"===l&&p>=0&&y>0||"samesign"===l&&p<=0&&y<0){p=jo(p,y),f=y;break}}}return i[0]=p,i[1]=f,i})})}(t))})});var hv,dv,pv,fv,gv,vv,yv=function(t){this.data=t.data||(t.sourceFormat===Ou?{}:[]),this.sourceFormat=t.sourceFormat||Nu,this.seriesLayoutBy=t.seriesLayoutBy||Eu,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=p)}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 zv(this.getData(e),t)},t.prototype.formatTooltip=function(t,e,n){},t}();function Gv(t){var e,n;return $(t)?t.type&&(n=t):e=t,{text:e,frag:n}}function Fv(t){return new Hv(t)}var Hv=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=c(this._modBy),s=this._modDataCount||0,l=c(t&&t.modBy),u=t&&t.modDataCount||0;function c(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 h=t&&t.step;if(this._dueEnd=n?n._outputDueEnd:this._count?this._count(this.context):1/0,this._progress){var d=this._dueIndex,p=Math.min(null!=h?this._dueIndex+h:1/0,this._dueEnd);if(!i&&(o||d1&&i>0?s:a}};return o;function a(){return e=t?null:oe},gte:function(t,e){return t>=e}},jv=function(){function t(t,e){if(!K(e)){var n="";0,va(n)}this._opFn=Zv[t],this._rvalFloat=oa(e)}return t.prototype.evaluate=function(t){return K(t)?this._opFn(t,this._rvalFloat):this._opFn(oa(t),this._rvalFloat)},t}(),qv=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=K(t)?t:oa(t),i=K(e)?e:oa(e),r=isNaN(n),o=isNaN(i);if(r&&(n=this._incomparable),o&&(i=this._incomparable),r&&o){var a=j(t),s=j(e);a&&(n=s?t:0),s&&(i=a?e:0)}return ni?-this._resultLT:0},t}(),Kv=function(){function t(t,e){this._rval=e,this._isEQ=t,this._rvalTypeof=typeof e,this._rvalFloat=oa(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=oa(t)===this._rvalFloat)}return this._isEQ?e:!e},t}();function $v(t,e){return"eq"===t||"ne"===t?new Kv("eq"===t,e):wt(Zv,t)?new jv(t,e):null}function Jv(t){var e="",n=-1/0,i=-1/0,r=1/0,o=1/0;return t&&(null!=t.g&&(e+="G"+t.g,n=t.g),null!=t.ge&&(e+="GE"+t.ge,i=t.ge),null!=t.l&&(e+="L"+t.l,r=t.l),null!=t.le&&(e+="LE"+t.le,o=t.le)),{key:e,g:n,ge:i,l:r,le:o}}function Qv(t,e){return e>t.g&&e>=t.ge&&e65535?uy:cy}function gy(t){var e=t.constructor;return e===Array?t.slice():new e(t)}function vy(t,e,n,i,r){var o=py[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=V(o,function(t){return t.property}),u=0;uv[1]&&(v[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.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<=c||isNaN(x))&&(a[s++]=p),p++}d=!0}else if(2===r){f=h[i[0]];var v=h[i[1]],y=t[i[1]][0],m=t[i[1]][1];for(g=0;g=u&&x<=c||isNaN(x))&&(_>=y&&_<=m||isNaN(_))&&(a[s++]=p),p++}d=!0}}if(!d)if(1===r)for(g=0;g=u&&x<=c||isNaN(x))&&(a[s++]=b)}else for(g=0;gt[M][1])&&(w=!1)}w&&(a[s++]=e.getRawIndex(g))}return sv[1]&&(v[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),c=this.getRawIndex(0),h=new(fy(this._rawCount))(Math.min(2*(Math.ceil(s/u)+2),s));h[l++]=c;for(var d=1;dn&&(n=i,r=I)}M>0&&M<_-x&&(h[l++]=Math.min(S,r),r=Math.max(S,r)),h[l++]=r,c=r}return h[l++]=this.getRawIndex(s-1),o._count=l,o._indices=h,o.getRawIndex=this._getRawIdx,o},t.prototype.minmaxDownSample=function(t,e){for(var n=this.clone([t],!0),i=n._chunks,r=Math.floor(1/e),o=i[t],a=this.count(),s=new(fy(this._rawCount))(2*Math.ceil(a/r)),l=0,u=0;ua&&(f=a-u);for(var g=0;gp&&(p=v,d=u+g)}var y=this.getRawIndex(c),m=this.getRawIndex(d);cu-p&&(s=u-p,a.length=s);for(var f=0;fc[1]&&(c[1]=v),h[d++]=y}return r._count=d,r._indices=h,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();rh&&(h=p))}return a[l]=[c,h]},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 Uv(t[i],this._dimensions[i])}ly={arrayRows:t,objectRows:function(t,e,n,i){return Uv(t[e],this._dimensions[i])},keyedColumns:t,original:function(t,e,n,i){var r=t&&(null==t.value?t:t.value);return Uv(r instanceof Array?r[i]:r,this._dimensions[i])},typedArray:function(t,e,n,i){return t[i]}}}(),t}(),my=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(_y(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=Q(a=o.get("data",!0))?Ru:ku,e=[];var c=this._getSourceMetaRawOption()||{},h=l&&l.metaRawOption||{},d=at(c.seriesLayoutBy,h.seriesLayoutBy)||null,p=at(c.sourceHeader,h.sourceHeader),f=at(c.dimensions,h.dimensions);t=d!==h.seriesLayoutBy||!!p!=!!h.sourceHeader||f?[xv(a,{seriesLayoutBy:d,sourceHeader:p,dimensions:f},s)]:[]}else{var g=n;if(r){var v=this._applyTransform(i);t=v.sourceList,e=v.upstreamSignList}else{t=[xv(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&&by(o)}var a,s=[],l=[];return B(t,function(t){t.prepareSource();var e=t.getSource(r||0),n="";null==r||e||by(n),s.push(e),l.push(t._getVersionSign())}),i?e=function(t,e){var n=_a(t),i=n.length,r="";i||va(r);for(var o=0,a=i;o1||n>0&&!t.noHeader;return B(t.blocks,function(t){var n=Ay(t);n>=e&&(e=n+ +(i&&(!n||Cy(t)&&!t.noHeader)))}),e}return 0}function ky(t,e,n,i){var r,o=e.noHeader,a=(r=Ay(e),{html:My[r],richText:Iy[r]}),s=[],l=e.blocks||[];ct(!l||X(l)),l=l||[];var u=t.orderMode;if(e.sortBlocks&&u){l=l.slice();var c={valueAsc:"asc",valueDesc:"desc"};if(wt(c,u)){var h=new qv(c[u],null);l.sort(function(t,e){return h.evaluate(t.sortParam,e.sortParam)})}else"seriesDesc"===u&&l.reverse()}B(l,function(n,r){var o=e.valueFormatter,l=Dy(n)(o?k(k({},t),{valueFormatter:o}):t,n,r>0?a.html:0,i);null!=l&&s.push(l)});var d="richText"===t.renderMode?s.join(a.richText):Oy(i,s.join(""),o?n:a.html);if(o)return d;var p=Af(e.header,"ordinal",t.useUTC),f=Sy(i,t.renderMode).nameStyle,g=wy(i);return"richText"===t.renderMode?Ry(t,p,f)+a.richText+d:Oy(i,'
'+se(p)+"
"+d,n)}function Ly(t,e,n,i){var r=t.renderMode,o=e.noName,a=e.noValue,s=!e.markerType,l=e.name,u=t.useUTC,c=e.valueFormatter||t.valueFormatter||function(t){return V(t=X(t)?t:[t],function(t,e){return Af(t,X(p)?p[e]:p,u)})};if(!o||!a){var h=s?"":t.markupStyleCreator.makeTooltipMarker(e.markerType,e.markerColor||ug.color.secondary,r),d=o?"":Af(l,"ordinal",u),p=e.valueType,f=a?[]:c(e.value,e.rawDataIndex),g=!s||!o,v=!s&&o,y=Sy(i,r),m=y.nameStyle,x=y.valueStyle;return"richText"===r?(s?"":h)+(o?"":Ry(t,d,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(X(e)?e.join(" "):e,o)}(t,f,g,v,x)):Oy(i,(s?"":h)+(o?"":function(t,e,n){return''+se(t)+""}(d,!s,m))+(a?"":function(t,e,n,i){var r=n?"10px":"20px",o=e?"float:right;margin-left:"+r:"";return t=X(t)?t:[t],''+V(t,function(t){return se(t)}).join("  ")+""}(f,g,v,x)),n)}}function Py(t,e,n,i,r,o){if(t)return Dy(t)({useUTC:r,renderMode:n,orderMode:i,markupStyleCreator:e,valueFormatter:t.valueFormatter},t,0,o)}function Oy(t,e,n){return'
'+e+'
'}function Ry(t,e,n){return t.markupStyleCreator.wrapRichTextStyle(e,n)}function Ny(t,e){return Nf(t.getData().getItemVisual(e,"style")[t.visualDrawType])}function Ey(t,e){var n=t.get("padding");return null!=n?n:"richText"===e?[8,10]:10}var zy=function(){function t(){this.richTextStyles={},this._nextStyleNameId=sa()}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=Rf({color:e,type:t,renderMode:n,markerId:i});return j(r)?r:(this.richTextStyles[i]=r.style,r.content)},t.prototype.wrapRichTextStyle=function(t,e){var n={};X(e)?B(e,function(t){return k(n,t)}):k(n,e);var i=this._generateStyleName();return this.richTextStyles[i]=n,"{"+i+"|"+t+"}"},t}();function By(t){var e,n,i,r,o=t.series,a=t.dataIndex,s=t.multipleSeries,l=o.getData(),u=l.mapDimensionsAll("defaultedTooltip"),c=u.length,h=o.getRawValue(a),d=X(h),p=Ny(o,a);if(c>1||d&&!c){var f=function(t,e,n,i,r){var o=e.getData(),a=G(t,function(t,e,n){var i=o.getDimensionInfo(n);return t||i&&!1!==i.tooltip&&null!=i.displayName},!1),s=[],l=[],u=[];function c(t,e){var n=o.getDimensionInfo(e);n&&!1!==n.otherDims.tooltip&&(a?u.push(Ty("nameValue",{markerType:"subItem",markerColor:r,name:n.displayName,value:t,valueType:n.type})):(s.push(t),l.push(n.type)))}return i.length?B(i,function(t){c(zv(o,n,t),t)}):B(t,c),{inlineValues:s,inlineValueTypes:l,blocks:u}}(h,o,a,u,p);e=f.inlineValues,n=f.inlineValueTypes,i=f.blocks,r=f.inlineValues[0]}else if(c){var g=l.getDimensionInfo(u[0]);r=e=zv(l,a,u[0]),n=g.type}else r=e=d?h[0]:h;var v=Aa(o),y=v&&o.name||"",m=l.getName(a),x=s?y:m;return Ty("section",{header:y,noHeader:s||!v,sortParam:r,blocks:[Ty("nameValue",{markerType:"item",markerColor:p,name:x,noName:!ht(x),value:e,valueType:n,rawDataIndex:l.getRawIndex(a)})].concat(i||[])})}var Vy=Pa();function Gy(t,e){return t.getName(e)||t.getId(e)}var Fy="__universalTransitionEnabled",Hy=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e._selectedDataIndicesMap={},e}var i;return n(e,t),e.prototype.init=function(t,e,n){this.seriesIndex=this.componentIndex,this.dataTask=Fv({count:Uy,reset:Yy}),this.dataTask.context={model:this},this.mergeDefaultAndTheme(t,n),(Vy(this).sourceManager=new my(this)).prepareSource();var i=this.getInitialData(t,n);Zy(i,this),this.dataTask.context.data=i,Vy(this).dataBeforeProcessed=i,Wy(this),this._initSelectedMapFromData(i)},e.prototype.mergeDefaultAndTheme=function(t,e){var n=ig(this),i=n?og(t):{},r=this.subType;lg.hasClass(r)&&(r+="Series"),D(t,e.getTheme().get(this.subType)),D(t,this.getDefaultOption()),ba(t,"label",["show"]),this.fillDataTextStyle(t.data),n&&rg(t,i,n)},e.prototype.mergeOption=function(t,e){t=D(this.option,t,!0),this.fillDataTextStyle(t.data);var n=ig(this);n&&rg(this.option,t,n);var i=Vy(this).sourceManager;i.dirty(),i.prepareSource();var r=this.getInitialData(t,e);Zy(r,this),this.dataTask.dirty(),this.dataTask.context.data=r,Vy(this).dataBeforeProcessed=r,Wy(this),this._initSelectedMapFromData(r)},e.prototype.fillDataTextStyle=function(t){if(t&&!Q(t))for(var e=["show"],n=0;n=0&&c<0)&&(u=m,c=y,h=0),y===c&&(l[h++]=f))}return l.length=h,l},e.prototype.formatTooltip=function(t,e,n){return By({series:this,dataIndex:t,multipleSeries:e})},e.prototype.isAnimationEnabled=function(){var t=this.ecModel;if(r.node&&(!t||!t.ssr))return!1;var e=this.getShallow("animation");return e&&this.getData().count()>this.getShallow("animationThreshold")&&(e=!1),!!e},e.prototype.restoreData=function(){this.dataTask.dirty()},e.prototype.getColorFromPalette=function(t,e,n){var i=this.ecModel,r=Og.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[Gy(i,t)])&&!i.getItemModel(t).get(["select","disabled"])},e.prototype.isUniversalTransitionEnabled=function(){if(this[Fy])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){$(r.selectedMap)||(r.selectedMap={});for(var s=r.selectedMap,l=0;l0&&this._innerSelect(t,e)}},e.registerClass=function(t){return lg.registerClass(t)},e.protoInitialize=((i=e.prototype).type="series.__base__",i.seriesIndex=0,i.ignoreStyleOnData=!1,i.hasSymbolVisual=!1,i.defaultSymbol="circle",i.visualStyleAccessPath="itemStyle",void(i.visualDrawType="fill")),e}(lg);function Wy(t){var e=t.name;Aa(t)||(t.name=function(t){var e=t.getRawData(),n=e.mapDimensionsAll("seriesName"),i=[];return B(n,function(t){var n=e.getDimensionInfo(t);n.displayName&&i.push(n.displayName)}),i.join(" ")}(t)||e)}function Uy(t){return t.model.getRawData().count()}function Yy(t){var e=t.model;return e.setData(e.getRawData().cloneShallow()),Xy}function Xy(t,e){e.outputData&&t.end>e.outputData.count()&&e.model.getRawData().cloneShallow(e.outputData)}function Zy(t,e){B(xt(t.CHANGABLE_METHODS,t.DOWNSAMPLE_METHODS),function(n){t.wrapMethod(n,Y(jy,e))})}function jy(t,e){var n=qy(t);return n&&n.setOutputEnd((e||this).count()),e}function qy(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}}E(Hy,Vv),E(Hy,Og),hs(Hy,lg);var Ky=function(){function t(){this.group=new vo,this.uid=Pp("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 $y(){var t=Pa();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"}}cs(Ky),gs(Ky);var Jy=Pa(),Qy=$y(),tm=function(){function t(){this.group=new vo,this.uid=Pp("viewChart"),this.renderTask=Fv({plan:im,reset:rm}),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&&nm(r,i,"emphasis")},t.prototype.downplay=function(t,e,n,i){var r=t.getData(i&&i.dataType);r&&nm(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.updateVisual=function(t,e,n,i){this.render(t,e,n,i)},t.prototype.eachRendered=function(t){Hd(this.group,t)},t.markUpdateMethod=function(t,e){Jy(t).updateMethod=e},t.protoInitialize=void(t.prototype.type="chart"),t}();function em(t,e,n){t&&Ec(t)&&("emphasis"===e?vc:yc)(t,n)}function nm(t,e,n){var i=La(t,e),r=e&&null!=e.highlightKey?function(t){var e=Wu[t];return null==e&&Hu<=32&&(e=Wu[t]=Hu++),e}(e.highlightKey):null;null!=i?B(_a(i),function(e){em(t.getItemGraphicEl(e),n,r)}):t.eachItemGraphicEl(function(t){em(t,n,r)})}function im(t){return Qy(t.model)}function rm(t){var e=t.model,n=t.ecModel,i=t.api,r=t.payload,o=e.pipelineContext.progressiveRender,a=t.view,s=r&&Jy(r).updateMethod,l=o?"incrementalPrepareRender":s&&a[s]?s:"render";return"render"!==l&&a[l](e,n,i,r),om[l]}cs(tm),gs(tm);var om={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)}}},am="\0__throttleOriginMethod",sm="\0__throttleRate",lm="\0__throttleType";function um(t,e,n){var i,r,o,a,s,l=0,u=0,c=null;function h(){u=(new Date).getTime(),c=null,t.apply(o,a||[])}e=e||0;var d=function(){for(var t=[],d=0;d=0?h():c=setTimeout(h,-r),l=i};return d.clear=function(){c&&(clearTimeout(c),c=null)},d.debounceNextCall=function(t){s=t},d}function cm(t,e,n,i){var r=t[e];if(r){var o=r[am]||r,a=r[lm];if(r[sm]!==n||a!==i){if(null==n||!i)return t[e]=o;(r=t[e]=um(o,n,"debounce"===i))[am]=o,r[lm]=i,r[sm]=n}return r}}function hm(t,e){var n=t[e];n&&n[am]&&(n.clear&&n.clear(),t[e]=n[am])}var dm=Pa(),pm={itemStyle:vs(Cp,!0),lineStyle:vs(Mp,!0)},fm={lineStyle:"stroke",itemStyle:"fill"};function gm(t,e){var n=t.visualStyleMapper||pm[e];return n||(console.warn("Unknown style type '"+e+"'."),pm.itemStyle)}function vm(t,e){var n=t.visualDrawType||fm[e];return n||(console.warn("Unknown style type '"+e+"'."),"fill")}var ym={createOnAllSeries:!0,performRawSeries:!0,reset:function(t,e){var n=t.getData(),i=t.visualStyleAccessPath||"itemStyle",r=t.getModel(i),o=gm(t,i)(r),a=r.getShallow("decal");a&&(n.setVisual("decal",a),a.dirty=!0);var s=vm(t,i),l=o[s],u=Z(l)?l:null,c="auto"===o.fill||"auto"===o.stroke;if(!o[s]||u||c){var h=t.getColorFromPalette(t.name,null,e.getSeriesCount());o[s]||(o[s]=h,n.setVisual("colorFromPalette",!0)),o.fill="auto"===o.fill||Z(o.fill)?h:o.fill,o.stroke="auto"===o.stroke||Z(o.stroke)?h: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=k({},o);r[s]=u(i),e.setItemVisual(n,"style",r)}}}},mm=new kp,xm={createOnAllSeries:!0,reset:function(t,e){if(!t.ignoreStyleOnData){var n=t.getData(),i=t.visualStyleAccessPath||"itemStyle",r=gm(t,i),o=n.getVisual("drawType");return{dataEach:n.hasItemOption?function(t,e){var n=t.getRawDataItem(e);if(n&&n[i]){mm.option=n[i];var a=r(mm);k(t.ensureUniqueItemVisual(e,"style"),a),mm.option.decal&&(t.setItemVisual(e,"decal",mm.option.decal),mm.option.decal.dirty=!0),o in a&&t.setItemVisual(e,"colorFromPalette",!1)}}:null}}}},_m={performRawSeries:!0,overallReset:function(t){var e=mt();t.eachSeries(function(t){if(!t.isColorBySeries()){var n=t.type+"-"+t.getColorBy();dm(t).scope=e.get(n)||e.set(n,{})}}),t.eachSeries(function(t){if(!t.isColorBySeries()){var e=t.getRawData(),n={},i=t.getData(),r=dm(t).scope,o=t.visualStyleAccessPath||"itemStyle",a=vm(t,o);i.each(function(t){var e=i.getRawIndex(t);n[e]=t}),e.each(function(o){var s=n[o];if(i.getItemVisual(s,"colorFromPalette")){var l=i.ensureUniqueItemVisual(s,"style"),u=e.getName(o)||o+"",c=e.count();l[a]=t.getColorFromPalette(u,r,c)}})}})}},bm=Math.PI;var wm=function(){function t(t,e,n,i){this._stageTaskMap=mt(),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.__preparePipelineContext?t.__preparePipelineContext(e,n):rs(t,e,n);t.pipelineContext=n.context=i},t.prototype.restorePipelines=function(t,e){var n=this,i=n._pipelineMap=mt();e.eachSeries(function(e){var r="canvas"===t.painter.type&&e.getProgressive(),o=e.uid;i.set(o,{id:o,head:null,tail:null,threshold:e.getProgressiveThreshold(),progressiveEnabled:r&&!(e.preventIncremental&&e.preventIncremental()),blockIndex:-1,step:Math.round(r||700),count:0}),n._pipe(e,e.dataTask)})},t.prototype.prepareStageTasks=function(){var t=this._stageTaskMap,e=this.api.getModel(),n=this.api;B(this._allHandlers,function(i){var r=t.get(i.uid)||t.set(i.uid,{}),o="";ct(!(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))}B(t,function(t,s){if(!i.visualType||i.visualType===t.visualType){var l=o._stageTaskMap.get(t.uid),u=l.seriesTaskMap,c=l.overallTask;if(c){var h,d=c.agentStubMap;d.each(function(t){a(i,t)&&(t.dirty(),h=!0)}),h&&c.dirty(),o.updatePayload(c,n);var p=o.getPerformArgs(c,i.block);d.each(function(t){t.perform(p)}),c.perform(p)&&(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=mt(),s=t.seriesType,l=t.getTargetSeries;function u(e){var s=e.uid,l=a.set(s,o&&o.get(s)||Fv({plan:Cm,reset:Dm,count:Lm}));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||Fv({reset:Sm});o.context={ecModel:n,api:i,overallReset:t.overallReset,scheduler:r};var a=o.agentStubMap,s=o.agentStubMap=mt(),l=t.seriesType,u=t.getTargetSeries,c=t.dirtyOnOverallProgress,h=!1,d="";function p(t){var e=t.uid,n=s.set(e,a&&a.get(e)||(h=!0,Fv({reset:Mm,onDirty:Tm})));n.context={model:t,dirtyOnOverallProgress:c},n.agent=o,n.__block=c,r._pipe(t,n)}ct(!t.createOnAllSeries,d),l?n.eachRawSeriesByType(l,p):u?u(n,i).each(p):B(n.getSeries(),p),h&&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 Z(t)&&(t={overallReset:t,seriesType:Pm(t)}),t.uid=Pp("stageHandler"),e&&(t.visualType=e),t},t}();function Sm(t){t.overallReset(t.ecModel,t.api,t.payload)}function Mm(t){return t.dirtyOnOverallProgress&&Im}function Im(){this.agent.dirty(),this.getDownstream().dirty()}function Tm(){this.agent&&this.agent.dirty()}function Cm(t){return t.plan?t.plan(t.model,t.ecModel,t.api,t.payload):null}function Dm(t){t.useClearVisual&&t.data.clearAllVisual();var e=t.resetDefines=_a(t.reset(t.model,t.ecModel,t.api,t.payload));return e.length>1?V(e,function(t,e){return km(e)}):Am}var Am=km(0);function km(t){return function(e,n){var i=n.data,r=n.resetDefines[t];if(r&&r.dataEach)for(var o=e.start;o0&&c===r.length-u.length){var h=r.slice(0,c);"data"!==h&&(e.mainType=h,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}(),Um=["symbol","symbolSize","symbolRotate","symbolOffset"],Ym=Um.concat(["symbolKeepAspect"]),Xm={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&&Sx(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=Sx(i)?i:0,r=Sx(r)?r:1,o=Sx(o)?o:0,a=Sx(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]:K(e)?[e]:X(e)?e:null:null),o=i.lineDashOffset;if(r){var a=i.strokeNoScale&&t.getLineScale?t.getLineScale():1;a&&1!==a&&(r=V(r,function(t){return t/a}),o/=a)}return[r,o]}var Dx=new Al(!0);function Ax(t){var e=t.stroke;return!(null==e||"none"===e||!(t.lineWidth>0))}function kx(t){return"string"==typeof t&&"none"!==t}function Lx(t){var e=t.fill;return null!=e&&"none"!==e}function Px(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 Ox(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 Rx(t,e,n){var i=bs(e.image,e.__image,n);if(Ss(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)*Mt),o.scaleSelf(e.scaleX||1,e.scaleY||1),r.setTransform(o)}return r}}var Nx=["shadowBlur","shadowOffsetX","shadowOffsetY"],Ex=[["lineCap","butt"],["lineJoin","miter"],["miterLimit",10]];function zx(t,e,n,i,r){var o=!1;if(!i&&e===(n=n||{}))return!1;if(i||e.opacity!==n.opacity){Gx(t,r),o=!0;var a=Math.max(Math.min(e.opacity,1),0);t.globalAlpha=isNaN(a)?Ws.opacity:a}(i||e.blend!==n.blend)&&(o||(Gx(t,r),o=!0),t.globalCompositeOperation=e.blend||Ws.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[e_])if(this._disposed)R_(this.id);else{var i,r,o;if($(e)&&(n=e.lazyUpdate,i=e.silent,r=e.replaceMerge,o=e.transition,e=e.notMerge),this[e_]=!0,D_(this),!this._model||e){var a=new Hg(this._api),s=this._theme,l=this._model=new zg;l.scheduler=this._scheduler,l.ssr=this._ssr,l.init(null,null,null,s,this._locale,a)}this._model.setOption(t,{replaceMerge:r},V_);var u={seriesTransition:o,optionChanged:!0};if(n)this[i_]={silent:i,updateParams:u},this[e_]=!1,this.getZr().wakeUp();else{try{c_(this),p_.update.call(this,null,u)}catch(t){throw this[i_]=null,this[e_]=!1,t}this._ssr||this._zr.flush(),this[i_]=null,this[e_]=!1,y_.call(this,i),m_.call(this,i)}}},e.prototype.setTheme=function(t,e){if(!this[e_])if(this._disposed)R_(this.id);else{var n=this._model;if(n){var i=e&&e.silent,r=null;this[i_]&&(null==i&&(i=this[i_].silent),r=this[i_].updateParams,this[i_]=null),this[e_]=!0,D_(this);try{this._updateTheme(t),n.setTheme(this._theme),c_(this),p_.update.call(this,{type:"setTheme"},r)}catch(t){throw this[e_]=!1,t}this[e_]=!1,y_.call(this,i),m_.call(this,i)}}},e.prototype._updateTheme=function(t){j(t)&&(t=F_[t]),t&&((t=C(t))&&uv(t,!0),this._theme=t)},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||r.hasGlobalWindow&&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(){var t=this._zr;return B(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;B(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 B(i,function(t){t.group.ignore=!1}),o}R_(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(U_[n]){var a=o,s=o,l=-1/0,u=-1/0,h=[],d=t&&t.pixelRatio||this.getDevicePixelRatio();B(W_,function(o,c){if(o.group===n){var d=e?o.getZr().painter.getSvgDom().innerHTML:o.renderToCanvas(C(t)),p=o.getDom().getBoundingClientRect();a=i(p.left,a),s=i(p.top,s),l=r(p.right,l),u=r(p.bottom,u),h.push({dom:d,left:p.left,top:p.top})}});var p=(l*=d)-(a*=d),f=(u*=d)-(s*=d),g=c.createCanvas(),v=bo(g,{renderer:e?"svg":"canvas"});if(v.resize({width:p,height:f}),e){var y="";return B(h,function(t){var e=t.left-a,n=t.top-s;y+=''+t.dom+""}),v.painter.getSvgRoot().innerHTML=y,t.connectedBackgroundColor&&v.painter.setBackgroundColor(t.connectedBackgroundColor),v.refreshImmediately(),v.painter.toDataURL()}return t.connectedBackgroundColor&&v.add(new lu({shape:{x:0,y:0,width:p,height:f},style:{fill:t.connectedBackgroundColor}})),B(h,function(t){var e=new eu({style:{x:t.left*d-a,y:t.top*d-s,image:t.dom}});v.add(e)}),v.refreshImmediately(),g.toDataURL("image/"+(t&&t.type||"png"))}return this.getDataURL(t)}R_(this.id)},e.prototype.convertToPixel=function(t,e,n){return f_(this,"convertToPixel",t,e,n)},e.prototype.convertToLayout=function(t,e,n){return f_(this,"convertToLayout",t,e,n)},e.prototype.convertFromPixel=function(t,e,n){return f_(this,"convertFromPixel",t,e,n)},e.prototype.containPixel=function(t,e){var n;if(!this._disposed)return B(Ra(this._model,t),function(t,i){i.indexOf("Models")>=0&&B(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;R_(this.id)},e.prototype.getVisual=function(t,e){var n=Ra(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?jm(r,o,e):qm(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=this;B(O_,function(e){var n=function(n){var i,r=t.getModel(),o=n.target,a="globalout"===e;if(a?i={}:o&&Qm(o,function(t){var e=Iu(t);if(e&&null!=e.dataIndex){var n=e.dataModel||r.getSeriesByIndex(e.seriesIndex);return i=n&&n.getDataParams(e.dataIndex,e.dataType,o)||{},!0}if(e.eventData)return i=k({},e.eventData),!0},!0),i){var s=i.componentType,l=i.componentIndex;"markLine"!==s&&"markPoint"!==s&&"markArea"!==s||(s="series",l=i.seriesIndex);var u=s&&null!=l&&r.getComponent(s,l),c=u&&t["series"===u.mainType?"_chartsMap":"_componentsMap"][u.__viewId];0,i.event=n,i.type=e,t._$eventProcessor.eventInfo={targetEl:o,packedEvent:i,model:u,view:c},t.trigger(e,i)}};n.zrEventfulCallAtLast=!0,t._zr.on(e,n,t)});var e=this._messageCenter;B(z_,function(n,i){e.on(i,function(e){t.trigger(i,e)})}),function(t,e,n){t.on("selectchanged",function(t){var i=n.getModel();t.isFromClick?(Jm("map","selectchanged",e,i,t),Jm("pie","selectchanged",e,i,t)):"select"===t.fromAction?(Jm("map","selected",e,i,t),Jm("pie","selected",e,i,t)):"unselect"===t.fromAction&&(Jm("map","unselected",e,i,t),Jm("pie","unselected",e,i,t))})}(e,this,this._api)},e.prototype.isDisposed=function(){return this._disposed},e.prototype.clear=function(){this._disposed?R_(this.id):this.setOption({series:[]},!0)},e.prototype.dispose=function(){if(this._disposed)R_(this.id);else{this._disposed=!0,this.getDom()&&Ga(this.getDom(),Z_,"");var t=this,e=t._api,n=t._model;B(t._componentsViews,function(t){t.dispose(n,e)}),B(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 W_[t.id]}},e.prototype.resize=function(t){if(!this[e_])if(this._disposed)R_(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[i_]&&(null==i&&(i=this[i_].silent),n=!0,this[i_]=null),this[e_]=!0,D_(this);try{n&&c_(this),p_.update.call(this,{type:"resize",animation:k({duration:0},t&&t.animation)})}catch(t){throw this[e_]=!1,t}this[e_]=!1,y_.call(this,i),m_.call(this,i)}}},e.prototype.showLoading=function(t,e){if(this._disposed)R_(this.id);else if($(t)&&(e=t,t=""),t=t||"default",this.hideLoading(),H_[t]){var n=H_[t](this._api,e),i=this._zr;this._loadingFX=n,i.add(n)}},e.prototype.hideLoading=function(){this._disposed?R_(this.id):(this._loadingFX&&this._zr.remove(this._loadingFX),this._loadingFX=null)},e.prototype.makeActionFromEvent=function(t){var e=k({},t);return e.type=E_[t.type],e},e.prototype.dispatchAction=function(t,e){if(this._disposed)R_(this.id);else if($(e)||(e={silent:!!e}),N_[t.type]&&this._model)if(this[e_])this._pendingActions.push(t);else{var n=e.silent;v_.call(this,t,n);var i=e.flush;i?this._zr.flush():!1!==i&&r.browser.weChat&&this._throttledZrFlush(),y_.call(this,n),m_.call(this,n)}},e.prototype.updateLabelLayout=function(){tx.trigger("series:layoutlabels",this._model,this._api,{updatedSeries:[]})},e.prototype.appendData=function(t){if(this._disposed)R_(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(ad(t))return;if(t instanceof Kl&&function(t){var e=Uu(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)}})}c_=function(t){var e;e=t._model,ox(e).prepare={};var n=t._scheduler;n.restorePipelines(t._zr,t._model),n.prepareStageTasks(),h_(t,!0),h_(t,!1),n.plan()},h_=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;lat(e.get("hoverLayerThreshold"),yg.hoverLayerThreshold)&&!r.node&&!r.worker;(t._usingTHL||a)&&(e.eachSeries(function(e){if(!e.preventUsingHoverLayer){var n=t._chartsMap[e.__viewId];n.__alive&&n.eachRendered(function(t){var e=t.states.emphasis;e&&2!==e.hoverLayer&&(e.hoverLayer=a?1:0)})}}),t._usingTHL=a)}(t,e),tx.trigger("series:afterupdate",e,n,l)},T_=function(t){t[r_]=!0,t.getZr().wakeUp()},D_=function(t){t[n_]=(t[n_]+1)%1e6},C_=function(t){t[r_]&&(t.getZr().storage.traverse(function(t){ad(t)||e(t)}),t[r_]=!1)},M_=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){vc(e,n),T_(t)},i.prototype.leaveEmphasis=function(e,n){yc(e,n),T_(t)},i.prototype.enterBlur=function(e){mc(e),T_(t)},i.prototype.leaveBlur=function(e){xc(e),T_(t)},i.prototype.enterSelect=function(e){_c(e),T_(t)},i.prototype.leaveSelect=function(e){bc(e),T_(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.prototype.getECUpdateCycleVersion=function(){return t[n_]},i.prototype.usingTHL=function(){return t._usingTHL},i}(Gu))(t)},I_=function(t){function e(t,e){for(var n=0;n=0)){sb.push(n);var a=wm.wrapStageHandler(n,r);a.__prio=e,a.__raw=n,t.push(a)}}function ub(t,e){H_[t]=e}function cb(t,e,n){var i=nx("registerMap");i&&i(t,e,n)}var hb=function(t){var e=(t=C(t)).type,n="";e||va(n);var i=e.split(":");2!==i.length&&va(n);var r=!1;"echarts"===i[0]&&(e=i[1],r=!0),t.__isBuiltIn=r,oy.set(e,t)};function db(t,e,n,i){return{eventContent:{selected:Dc(n),isFromClick:e.isFromClick||!1}}}ab(Jx,ym),ab(Qx,xm),ab(Qx,_m),ab(Jx,Xm),ab(Qx,Zm),ab(7e3,$x),J_(uv),Q_(900,cv),ub("default",function(t,e){P(e=e||{},{text:"loading",textColor:ug.color.primary,fontSize:12,fontWeight:"normal",fontStyle:"normal",fontFamily:"sans-serif",maskColor:"rgba(255,255,255,0.8)",showSpinner:!0,color:ug.color.theme[0],spinnerRadius:10,lineWidth:5,zlevel:0});var n=new vo,i=new lu({style:{fill:e.maskColor},zlevel:e.zlevel,z:1e4});n.add(i);var r,o=new du({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 lu({style:{fill:"none"},textContent:o,textConfig:{position:"right",distance:10},zlevel:e.zlevel,z:10001});return n.add(a),e.showSpinner&&((r=new Vh({shape:{startAngle:-bm/2,endAngle:-bm/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*bm/2}).start("circularInOut"),r.animateShape(!0).when(1e3,{startAngle:3*bm/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}),ib({type:qu,event:qu,update:qu},St),ib({type:Ku,event:Ku,update:Ku},St),ib({type:$u,event:tc,update:$u,action:St,refineEvent:db,publishNonRefinedEvent:!0}),ib({type:Ju,event:tc,update:Ju,action:St,refineEvent:db,publishNonRefinedEvent:!0}),ib({type:Qu,event:tc,update:Qu,action:St,refineEvent:db,publishNonRefinedEvent:!0}),$_("default",{}),$_("dark",Hm);var pb=[],fb={registerPreprocessor:J_,registerProcessor:Q_,registerPostInit:tb,registerPostUpdate:eb,registerUpdateLifecycle:nb,registerAction:ib,registerCoordinateSystem:rb,registerLayout:ob,registerVisual:ab,registerTransform:hb,registerLoading:ub,registerMap:cb,registerImpl:function(t,e){ex[t]=e},PRIORITY:t_,ComponentModel:lg,ComponentView:Ky,SeriesModel:Hy,ChartView:tm,registerComponentModel:function(t){lg.registerClass(t)},registerComponentView:function(t){Ky.registerClass(t)},registerSeriesModel:function(t){Hy.registerClass(t)},registerChartView:function(t){tm.registerClass(t)},registerCustomSeries:function(t,e){rx(t,e)},registerSubTypeDefaulter:function(t,e){lg.registerSubTypeDefaulter(t,e)},registerPainter:function(t,e){wo(t,e)}};function gb(t){X(t)?B(t,function(t){gb(t)}):R(pb,t)>=0||(pb.push(t),Z(t)&&(t={install:t}),t.install(fb))}function vb(t){return null==t?0:t.length||1}function yb(t){return t}var mb=function(){function t(t,e,n,i,r,o){this._old=t,this._new=e,this._oldKeyGetter=n||yb,this._newKeyGetter=i||yb,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===h)this._updateManyToOne&&this._updateManyToOne(u,l),i[s]=null;else if(1===c&&h>1)this._updateOneToMany&&this._updateOneToMany(u,l),i[s]=null;else if(1===c&&1===h)this._update&&this._update(u,l),i[s]=null;else if(c>1&&h>1)this._updateManyToMany&&this._updateManyToMany(u,l),i[s]=null;else if(c>1)for(var d=0;d1)for(var a=0;a30}var kb,Lb,Pb,Ob,Rb,Nb,Eb,zb=$,Bb=V,Vb="undefined"==typeof Int32Array?Array:Int32Array,Gb=["hasItemOption","_nameList","_idList","_invertedIndicesMap","_dimSummary","userOutput","_rawData","_dimValueGetter","_nameDimIdx","_idDimIdx","_nameRepeatCount"],Fb=["_approximateExtent"],Hb=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","minmaxDownSample","lttbDownSample","map"],this.CHANGABLE_METHODS=["filterSelf","selectRange"],this.DOWNSAMPLE_METHODS=["downSample","minmaxDownSample","lttbDownSample"];var i=!1;Tb(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===ku&&!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&&(X(r=this.getVisual(e))?r=r.slice():zb(r)&&(r=k({},r)),i[e]=r),r},t.prototype.setItemVisual=function(t,e,n){var i=this._itemVisuals[t]||{};this._itemVisuals[t]=i,zb(e)?k(i,e):i[e]=n},t.prototype.clearAllVisual=function(){this._visual={},this._itemVisuals=[]},t.prototype.setLayout=function(t,e){zb(t)?k(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?k(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;Tu(n,this.dataType,t,e),this._graphicEls[t]=e},t.prototype.getItemGraphicEl=function(t){return this._graphicEls[t]},t.prototype.eachItemGraphicEl=function(t,e){B(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:Bb(this.dimensions,this._getDimInfo,this),this.hostModel)),Rb(e,this),e._store=this._store,e},t.prototype.wrapMethod=function(t,e){var n=this[t];Z(n)&&(this.__wrappedMethods=this.__wrappedMethods||[],this.__wrappedMethods.push(t),this[t]=function(){var t=n.apply(this,arguments);return e.apply(this,[t].concat(lt(arguments)))})},t.internalField=(kb=function(t){var e=t._invertedIndicesMap;B(e,function(n,i){var r=t._dimInfos[i],o=r.ordinalMeta,a=t._store;if(o){n=e[i]=new Vb(o.categories.length);for(var s=0;s1&&(s+="__ec__"+u),i[e]=s}})),t}();function Wb(t,e){mv(t)||(t=_v(t));var n=(e=e||{}).coordDimensions||[],i=e.dimensionsDefine||t.dimensionsDefine||[],r=mt(),o=[],a=function(t,e,n,i){var r=Math.max(t.dimensionsDetectedCount||1,e.length,n.length,i||0);return B(e,function(t){var e;$(t)&&(e=t.dimsDef)&&(r=Math.max(r,e.length))}),r}(t,n,i,e.dimensionsCount),s=e.canOmitUnusedDimensions&&Ab(a),l=i===t.dimensionsDefine,u=l?Db(t):Cb(i),c=e.encodeDefine;!c&&e.encodeDefaulter&&(c=e.encodeDefaulter(t,a));for(var h=mt(c),d=new hy(a),p=0;p0&&(t.name=t.name+(e-1))}),new Ib({source:t,dimensions:o,fullDimensionCount:a,dimensionOmitted:s})}function Ub(t,e,n){if(n||e.hasKey(t)){for(var i=0;e.hasKey(t+i);)i++;t+=i}return e.set(t,!0),t}var Yb=function(t){this.coordSysDims=[],this.axisMap=mt(),this.categoryAxisMap=mt(),this.coordSysName=t};var Xb={cartesian2d:function(t,e,n,i){var r=t.getReferringComponents("xAxis",Ea).models[0],o=t.getReferringComponents("yAxis",Ea).models[0];e.coordSysDims=["x","y"],n.set("x",r),n.set("y",o),Zb(r)&&(i.set("x",r),e.firstCategoryDimIndex=0),Zb(o)&&(i.set("y",o),null==e.firstCategoryDimIndex&&(e.firstCategoryDimIndex=1))},singleAxis:function(t,e,n,i){var r=t.getReferringComponents("singleAxis",Ea).models[0];e.coordSysDims=["single"],n.set("single",r),Zb(r)&&(i.set("single",r),e.firstCategoryDimIndex=0)},polar:function(t,e,n,i){var r=t.getReferringComponents("polar",Ea).models[0],o=r.findAxisModel("radiusAxis"),a=r.findAxisModel("angleAxis");e.coordSysDims=["radius","angle"],n.set("radius",o),n.set("angle",a),Zb(o)&&(i.set("radius",o),e.firstCategoryDimIndex=0),Zb(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();B(o.parallelAxisIndex,function(t,o){var s=r.getComponent("parallelAxis",t),l=a[o];n.set(l,s),Zb(s)&&(i.set(l,s),null==e.firstCategoryDimIndex&&(e.firstCategoryDimIndex=o))})},matrix:function(t,e,n,i){var r=t.getReferringComponents("matrix",Ea).models[0];e.coordSysDims=["x","y"];var o=r.getDimensionModel("x"),a=r.getDimensionModel("y");n.set("x",o),n.set("y",a),i.set("x",o),i.set("y",a)}};function Zb(t){return"category"===t.get("type")}function jb(t,e,n){var i,r,o,a=(n=n||{}).byIndex,s=n.stackedCoordDimension;!function(t){return!Tb(t.schema)}(e)?(r=e.schema,i=r.dimensions,o=e.store):i=e;var l,u,c,h,d=!(!t||!t.get("stack")),p=!0;function f(t){return"ordinal"!==t.type&&"time"!==t.type}if(B(i,function(t,e){j(t)&&(i[e]=t={name:t}),f(t)||(p=!1)}),B(i,function(t,e){d&&!t.isExtraCoord&&(a||l||!t.ordinalMeta||(l=t),u||!f(t)||p&&("x"===t.coordDim||"angle"===t.coordDim)||s&&s!==t.coordDim||(u=t))}),!u||a||l||(a=!0),u){c="__\0ecstackresult_"+t.id,h="__\0ecstackedover_"+t.id,l&&(l.createInvertedIndices=!0);var g=u.coordDim,v=u.type,y=0;B(i,function(t){t.coordDim===g&&y++});var m={name:c,coordDim:g,coordDimIndex:y,type:v,isExtraCoord:!0,isCalculationCoord:!0,storeDimIndex:i.length},x={name:h,coordDim:h,coordDimIndex:y+1,type:v,isExtraCoord:!0,isCalculationCoord:!0,storeDimIndex:i.length+1};r?(o&&(m.storeDimIndex=o.ensureCalculationDimension(h,v),x.storeDimIndex=o.ensureCalculationDimension(c,v)),r.appendCalculationDimension(m),r.appendCalculationDimension(x)):(i.push(m),i.push(x))}return{stackedDimension:u&&u.name,stackedByDimension:l&&l.name,isStackedByIndex:a,stackedOverDimension:h,stackResultDimension:c}}function qb(t,e){return!!e&&e===t.getCalculationInfo("stackedDimension")}function Kb(t,e){return qb(t,e)?t.getCalculationInfo("stackResultDimension"):e}function $b(t,e,n){n=n||{};var i,r=e.getSourceManager(),o=!1;t?(o=!0,i=_v(t)):o=(i=r.getSource()).sourceFormat===ku;var a=function(t){var e=t.get("coordinateSystem"),n=new Yb(e),i=Xb[e];if(i)return i(t,n,n.axisMap,n.categoryAxisMap),n}(e),s=function(t,e){var n,i=t.get("coordinateSystem"),r=Vf.get(i);return e&&e.coordSysDims&&(n=V(e.coordSysDims,function(t){var n={name:t},i=e.axisMap.get(t);if(i){var r=i.get("type");n.type=bb(r)}return n})),n||(n=r&&(r.getDimensionsInfo?r.getDimensionsInfo():r.dimensions.slice())||["x","y"]),n}(e,a),l=n.useEncodeDefaulter,u=Z(l)?l:l?Y(wg,s,e):null,c=Wb(i,{coordDimensions:s,generateCoord:n.generateCoord,encodeDefine:e.getEncode(),encodeDefaulter:u,canOmitUnusedDimensions:!o}),h=function(t,e,n){var i,r;return n&&B(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}(c.dimensions,n.createInvertedIndices,a),d=o?null:r.getSharedDataStore(c),p=jb(e,{schema:c,store:d}),f=new Hb(c,e);f.setCalculationInfo(p);var g=null!=h&&function(t){if(t.sourceFormat===ku){var e=function(t){var e=0;for(;e=e[0]&&t<=e[1]},getExtent:function(){return this._extents[0].slice()},getExtentUnsafe:function(t){return this._extents[t]},setExtent:function(t,e){hw(this._extents,0,t,e)},setExtent2:function(t,e,n){var i=this._extents;i[t]||(i[t]=i[0].slice()),hw(i,t,e,n)},freeze:function(){0}};function hw(t,e,n,i){Ka(n,i)&&(t[e][0]=n,t[e][1]=i)}function dw(t){return pw(t)||gw(t)}function pw(t){return"interval"===t.type}function fw(t){return"time"===t.type}function gw(t){return"log"===t.type}function vw(t){return"ordinal"===t.type}function yw(t){var e=ea(t),n=Oo(10,e),i=ko(t/n);return i?2===i?i=3:3===i?i=5:i*=2:i=1,Ho(i*n,-e)}function mw(t){return Uo(t)+2}function xw(t,e){return Ro(t)/Ro(e)}function _w(t,e,n){var i=n&&n.lookup;if(i)for(var r=0;r1&&o/a>2&&(r=Math.round(Math.ceil(r/a)*a)),r!==i[0]&&l(i[0],!0,!0);for(var s=r;s<=i[1];s+=a)l(s,!1,s===i[0]||s===i[1]);function l(t,e,i){n({value:t,offInterval:e},i)}s-a!==i[1]&&l(i[1],!0,!0)}var Mw=function(t){function e(n){var i=t.call(this)||this;i.type="ordinal",i.parse=e.parse,rw(i,e.decoratedMethods);var r=n.ordinalMeta;r||(r=new tw({})),X(r)&&(r=new tw({categories:V(r,function(t){return $(t)?t.value:t})})),i._ordinalMeta=r;var o=iw(null,null,n.extent||[0,r.categories.length-1]);return i._mapper=o.mapper,ow(i,o.mapper),i}return n(e,t),e.parse=function(t){return null==t?t=NaN:j(t)?null==(t=this._ordinalMeta.getOrdinal(t))&&(t=NaN):t=ko(t),t},e.prototype.getTicks=function(){var t=[];return Sw(this,0,function(e){t.push(e)}),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=Co(o,e.length);r=0&&t=0&&t=0&&ta[0]&&fr[1]||!isFinite(d)||!isFinite(r[1]))break}else{if(p>h)break;d=Co(d,r[1]),p===h&&(d=r[1])}if(u.push({value:d}),d=Ho(d+n,o),s){var f=s.calcNiceTickMultiple(d,c);f>=0&&(d=Ho(d+f*n,o))}if(u.length>0&&d===u[u.length-1].value)break;if(u.length>3e3)return[]}var g=u.length?u[u.length-1].value:r[1];return i[1]>g&&u.push({value:t.expandToNicedExtent?Ho(g+n,o):i[1]}),l&&a.pruneTicksByBreak(t.pruneByBreak,u,s.breaks,function(t){return t.value},e.interval,i),l&&"none"!==t.breakTicks&&a.addBreaksToTicks(u,s.breaks,i),u},e.prototype.getMinorTicks=function(t){return Iw(this,t,Yp(this),this._cfg.interval)},e.prototype.getLabel=function(t,e){if(null==t)return"";var n=e&&e.precision;return null==n?n=Uo(t.value)||0:"auto"===n&&(n=this._cfg.intervalPrecision),Tf(Ho(t.value,n,!0))},e.type="interval",e}(Jb);Jb.registerClass(Tw);var Cw=function(t){function e(n){var i=t.call(this)||this;i.type="time",i.parse=e.parse,i._locale=n.locale,i._useUTC=n.useUTC,i._interval=0;var r=iw(i,Up(i,n),null);return i.brk=r.brk,i}return n(e,t),e.prototype.getLabel=function(t){return uf(t.value,ef[function(t){switch(t){case"year":case"month":return"day";case"millisecond":return"millisecond";default:return"second"}}(sf(this._minLevelUnit))]||ef.second,this._useUTC,this._locale)},e.prototype.getFormattedLabel=function(t,e,n){return function(t,e,n,i,r){var o=null;if(j(n))o=n;else if(Z(n)){var a={time:t.time,level:t.time?t.time.level:0},s=Wp();s&&s.makeAxisLabelFormatterParamBreak(a,t.break),o=n(t.value,e,a)}else{var l=t.time;if(l){var u=n[l.lowerTimeUnit][l.upperTimeUnit];o=u[Math.min(l.level,u.length-1)]||""}else{var c=cf(t.value,r);o=n[c][c][0]}}return uf(new Date(t.value),o,r,i)}(t,e,n,this._locale,this._useUTC)},e.prototype.getTicks=function(t){t=t||{};var e=this._interval,n=aw(this),i=Wp(),r=this.brk,o=i&&r,a=[];if(!e)return a;var s=this._useUTC;if(o&&"only_break"===t.breakTicks)return Wp().addBreaksToTicks(a,r.breaks,n),a;a=function(t,e,n,i,r,o){var a=3e3,s=rf,l=0;function u(t,e,n,r,s,u,c){for(var h=function(t,e){var n=new Date(0);n[t](1);var i=n.getTime();n[t](1+e);var r=n.getTime()-i;return function(t,e){return Math.max(0,Math.round((e-t)/r))}}(s,t),d=e,p=new Date(d);da){0;break}if(p[s](p[r]()+t),d=p.getTime(),o){var f=o.calcNiceTickMultiple(d,h);f>0&&(p[s](p[r]()+f*t),d=p.getTime())}}c.push({value:d,notAdd:d>i[1]})}function c(t,r,o){var a=[],s=!r.length;if(!Aw(sf(t),i[0],i[1],n)){s&&(r=[{value:Nw(i[0],t,n)},{value:i[1]}]);for(var l=0;l=i[0]&&c<=i[1]&&u(d,c,h,p,f,g,a),"year"===t&&o.length>1&&0===l&&o.unshift({value:o[0].value-d})}}for(l=0;l=i[0]&&x<=i[1]&&p++)}var _=r/e;if(p>1.5*_&&f>_/1.5)break;if(h.push(y),p>_||t===s[g])break}d=[]}}var b=F(V(h,function(t){return F(t,function(t){return t.value>=i[0]&&t.value<=i[1]&&!t.notAdd})}),function(t){return t.length>0}),w=b.length-1,S=[];for(g=0;gi[0])&&S.unshift({value:i[0],time:{level:0,upperTimeUnit:A,lowerTimeUnit:A},notNice:!0});(!D||D.value16?16:t>7.5?7:t>3.5?4:t>1.5?2:1}function Lw(t){return(t/=2592e6)>6?6:t>3?3:t>2?2:1}function Pw(t){return(t/=qp)>12?12:t>6?6:t>3.5?4:t>2?2:1}function Ow(t,e){return(t/=e?jp:Zp)>30?30:t>20?20:t>15?15:t>10?10:t>5?5:t>2?2:1}function Rw(t){return Do(na(t,!0),1)}function Nw(t,e,n){var i=Math.max(0,R(nf,e)-1);return hf(new Date(t),nf[i],n).getTime()}Jb.registerClass(Cw);var Ew=function(t){function e(n){var i=t.call(this)||this;i.type="log",i.parse=Tw.parse,i.base=n.logBase||10;var r=[],o=[],a=i._lookup={from:r,to:o};r[0]=r[1]=o[0]=o[1]=NaN,rw(i,e.mapperMethods);var s=Wp(),l=n.breakOption,u={lookup:a};return s&&s.parseAxisBreakOptionInwardTransform(l,i,{noNegative:!0},2,u),i.powStub=new Tw({breakParsed:u.original}),i.intervalStub=new Tw({breakParsed:u.transformed}),ow(i,i.intervalStub),i}return n(e,t),e.prototype.getTicks=function(t){var e=this.base,n=this.powStub,i=Wp(),r=this.intervalStub,o={lookup:{from:r.getExtent(),to:n.getExtent()}};return V(r.getTicks(t||{}),function(t){var r,a=_w(t.value,e,o);if(i){var s=i.getTicksBreakOutwardTransform(this,t,Yp(n),this._lookup);s&&(r=s.vBreak,a=s.tickVal)}return{value:a,break:r}},this)},e.prototype.getMinorTicks=function(t){return Iw(this,t,Yp(this.powStub),this.intervalStub.getConfig().interval)},e.prototype.getLabel=function(t,e){return this.intervalStub.getLabel(t,e)},e.type="log",e.mapperMethods={needTransform:function(){return!0},normalize:function(t){return this.intervalStub.normalize(xw(t,this.base))},scale:function(t){return _w(this.intervalStub.scale(t),this.base,null)},transformIn:function(t,e){return t=xw(t,this.base),e&&2===e.depth?t:this.intervalStub.transformIn(t,e)},transformOut:function(t,e){var n=e?e.depth:null;return zw.depth=n,Bw.lookup=this._lookup,_w(2===n?t:this.intervalStub.transformOut(t,zw),this.base,Bw)},contain:function(t){return this.powStub.contain(t)},setExtent:function(t,e){this.setExtent2(0,t,e)},setExtent2:function(t,e,n){if(!(!Ka(e,n)||e<=0||n<=0)){var i=Vw,r=Vw;if(0===t){var o=this._lookup;i=o.to,r=o.from}this.powStub.setExtent2(t,i[0]=e,i[1]=n);var a=this.base;this.intervalStub.setExtent2(t,r[0]=xw(e,a),r[1]=xw(n,a))}},getFilter:function(){return{g:0}},sanitize:function(t,e){return Ka(e[0],e[1])&&ca(t)&&t<=0&&(t=e[0]),t},getDefaultStartValue:function(){return 1},getExtent:function(){return this.powStub.getExtent()},getExtentUnsafe:function(t,e){return null===e?this.powStub.getExtentUnsafe(t,null):this.intervalStub.getExtentUnsafe(t,e)}},e}(Jb);Jb.registerClass(Ew);var zw={},Bw={},Vw=[],Gw={value:1,category:1,time:1,log:1},Fw=Pa();function Hw(t){var e=t.get("type");return null!=e&&(wt(Gw,e)||Jb.getClass(e))||(e="value"),e}function Ww(t,e,n){var i;switch(Wp()&&(i=Jw(t,e,n)),e){case"category":return new Mw({ordinalMeta:t.getOrdinalMeta?t.getOrdinalMeta():t.getCategories(),extent:[1/0,-1/0]});case"time":return new Cw({locale:t.ecModel.getLocaleModel(),useUTC:t.ecModel.get("useUTC"),breakOption:i});case"log":return new Ew({logBase:t.get("logBase"),breakOption:i});case"value":return new Tw({breakOption:i});default:return new(Jb.getClass(e)||Tw)({})}}var Uw=1,Yw=2,Xw=3;function Zw(t){var e=t.getLabelModel().get("formatter");if("time"===t.type){var n=of(e);return function(e,i){return t.scale.getFormattedLabel(e,i,n)}}if(j(e))return function(n){var i=t.scale.getLabel(n);return e.replace("{value}",null!=i?i:"")};if(Z(e)){if("category"===t.type)return function(n,i){return e(jw(t,n),n.value-t.scale.getExtent()[0],null)};var i=Wp();return function(n,r){var o=null;return i&&(o=i.makeAxisLabelFormatterParamBreak(o,n.break)),e(jw(t,n),r,o)}}return function(e){return t.scale.getLabel(e)}}function jw(t,e){var n=t.scale;return vw(n)?n.getLabel(e):e.value}function qw(t){var e=t.get("interval");return null==e?"auto":e}function Kw(t){return"middle"===t||"center"===t}function $w(t){return t.getShallow("show")}function Jw(t,e,n){var i=t.get("breaks",!0);if(null!=i){if(!Wp())return void 0;if(!n||!function(t){return"category"!==t}(e))return;return i}}function Qw(t,e,n,i,r,o){var a,s,l=gw(t),u=l?t.intervalStub:t;if(u.setExtent(i[0],i[1]),l){var c=t.powStub,h={depth:2},d=t.transformOut(i[0],h),p=t.transformOut(i[1],h),f=(s=i,[(a=n)[0]!==s[0],a[1]!==s[1]]);e[0]&&!f[0]&&(d=r[0]),e[1]&&!f[1]&&(p=r[1]),c.setExtent(d,p)}u.setConfig(o)}function tS(t,e){return vw(t)?t.getRawOrdinalNumber(e.value):e.value}function eS(t,e){return vw(t)&&!!e.get("boundaryGap")}var nS=function(){function t(){}return t.prototype.needIncludeZero=function(){return!this.option.scale},t.prototype.getCoordSysModel=function(){},t}(),iS=Ja(),rS="|&",oS=Pa(),aS=Pa();function sS(t,e){var n=t.model,i=oS(sx(n.ecModel)).keyed,r=i&&i.get(e);return r&&r.get(n.uid)}function lS(t,e){return cS(sS(t,e))}function uS(t,e){var n=oS(sx(t)).keyed;n&&n.each(function(t,n){t.each(function(t,i){e(t,n,i)})})}function cS(t){return{liPosMinGap:t?t.liPosMinGap:void 0}}function hS(t,e,n){var i=sS(t,e);i&&dS(t.model.ecModel,i.sers,n)}function dS(t,e,n){if(e)for(var i=0;i=0}(u)||(u[0]=u[1]=NaN);var c=[],h=[!1,!1],d=e.get("min",!0);"dataMin"===d?(c[0]=u[0],h[0]=!0):(c[0]=MS(t,Z(d)?d({min:u[0],max:u[1]}):d),h[0]=null!=c[0]);var p=e.get("max",!0);"dataMax"===p?(c[1]=u[1],h[1]=!0):(c[1]=MS(t,Z(p)?p({min:u[0],max:u[1]}):p),h[1]=null!=c[1]);var f=function(t,e){var n;if(vw(t))n=[0,0];else{var i=e.get("boundaryGap");"boolean"==typeof i&&(i=null),n=X(i)?i:[i,i]}return[IS(n[0]),IS(n[1])]}(t,e),g=a?null:u[1]-u[0]||Math.abs(u[0]);null==c[0]&&(c[0]=a?o?u[0]:s?0:NaN:u[0]-f[0]*g),null==c[1]&&(c[1]=a?o?u[1]:s?s-1:NaN:u[1]+f[1]*g),!qa(c[0])&&(c[0]=NaN),!qa(c[1])&&(c[1]=NaN);var v=o||rt(c[0])||rt(c[1])||a&&!s,y=pw(t),m=y&&e.needIncludeZero&&e.needIncludeZero();m&&(c[0]>0&&c[1]>0&&!h[0]&&(c[0]=0),c[0]<0&&c[1]<0&&!h[1]&&(c[1]=0));var x=!1;c[0]>c[1]&&(c.reverse(),x=!0);var _=MS(t,e.get("startValue",!0)),b=null!=_;!ca(_)&&i&&(_=t.getDefaultStartValue?t.getDefaultStartValue():0),ca(_)&&(b||!y||m)&&(_c[1]&&!h[1]&&(c[1]=_,h[1]=!0)),SS(this._i={scale:t,dataMM:u,noZoomEffMM:c,zoomMM:[],fixMM:h,zoomFixMM:[!1,!1],startValue:_,isBlank:v,incl0:m,tggAxInv:x,ctnShp:r},c)}return t.prototype.makeNoZoom=function(){return this._i.noZoomEffMM.slice()},t.prototype.makeFinal=function(){var t=this._i,e=t.zoomMM,n=t.noZoomEffMM,i=t.zoomFixMM,r=t.fixMM,o={fixMM:r,zoomFixMM:i,isBlank:t.isBlank,incl0:t.incl0,tggAxInv:t.tggAxInv,ctnShp:t.ctnShp,effMM:n.slice()},a=o.effMM;return null!=e[0]&&(a[0]=e[0],r[0]=i[0]=!0),null!=e[1]&&(a[1]=e[1],r[1]=i[1]=!0),SS(t,a),o},t.prototype.makeRenderInfo=function(){return{startValue:this._i.startValue}},t.prototype.setZoomMM=function(t,e){this._i.zoomMM[t]=e},t}();function SS(t,e){var n=t.scale,i=t.dataMM;n.sanitize&&(e[0]=n.sanitize(e[0],i),e[1]=n.sanitize(e[1],i),$a(e))}function MS(t,e){return null==e?null:rt(e)?NaN:t.parse(e)}function IS(t){return Qr("boolean"==typeof t?0:t,1)||0}function TS(t){var e=bS(t.scale);return e.extent||(e.extent=[1/0,-1/0]),e}function CS(t,e){var n=t.scale,i=t.model,r=t.dim;n.rawExtentInfo||function(t,e,n,i,r){var o=TS(e),a=o.extent,s=!1;!function(t,e){var n=t.model.ecModel,i=oS(sx(n)).axSer;i&&dS(n,i.get(t.model.uid),e)}(e,function(i){if(i.boxCoordinateSystem){var r=Ff(i).coord,l=o.dimIdxInCoord;if(l>=0){if(X(r)){var u=r[l];null==u||X(u)||Xa(a,t.parse(u))}}else 0}else if(i.coordinateSystem){var c=i.getData();if(c){var h=t.getFilter?t.getFilter():null;B(function(t,e){var n={};return B(t.mapDimensionsAll(e),function(e){n[Kb(t,e)]=!0}),W(n)}(c,n),function(t){var e,n;e=a,Ka((n=c.getApproximateExtent(t,h))[0],n[1])&&(n[0]e[1]&&(e[1]=n[1]))})}i.__requireStartValue&&i.__requireStartValue(e)&&(s=!0)}});var l=function(t,e,n){var i=eS(t,n),r=n.get("containShape",!0);null!=r||i||(r=!0);if(!r)return!1;var o=!1;return fS(e,function(t){o=!!kS.get(t)||o}),o}(t,e,i),u=new wS(t,i,a,s,l);DS(t,u,r),o.extent=null}(n,t,r,i,e)}function DS(t,e,n){t.rawExtentInfo=e,e.from=n}function AS(t,e){kS.set(t,e)}var kS=mt();function LS(t,e,n,i,r){t.rawExtentInfo||function(t,e){var n=t.scale;DS(n,new wS(n,t.model,e,!1,!1),3)}({scale:t,model:e},r||[1/0,-1/0]);var o=t.rawExtentInfo.makeFinal(),a=o.effMM;return t.setExtent(a[0],a[1]),t.setBlank(o.isBlank),i&&o.tggAxInv&&n&&!n.get("legacyMinMaxDontInverseAxis")&&(i.inverse=!i.inverse),o}function PS(t,e,n,i){var r;if(n.ctnShp&&(fS(t,function(e){var n=kS.get(e);if(n){var o=n(t,i);o&&(Za(r=r||[0,0],o[0]),ja(r,o[1]),function(t){Fw(t).noOnMyZero=!0}(t))}}),r)){var o=e.getExtent();if(vw(e))t.onBand||e.setExtent2(1,Co(o[0],o[0]+r[0]),Do(o[1],o[1]+r[1]));else{var a=o.slice();n.zoomFixMM[0]||(a[0]=Co(a[0],e.transformOut(e.transformIn(a[0],null)+r[0],null))),n.zoomFixMM[1]||(a[1]=Do(a[1],e.transformOut(e.transformIn(a[1],null)+r[1],null))),(a[0]o[1])&&e.setExtent2(1,a[0],a[1])}}}function OS(t,e){var n=gw(t),i=n?t.intervalStub:t,r=e.fixMinMax||[],o=n?t.getExtent():null,a=i.getExtent(),s=bw(a,r,e.rawExtentResult);i.setExtent(s[0],s[1]),s=i.getExtent();var l=n?function(t,e){var n=ww(e.splitNumber,10),i=t.getExtent(),r=lw(t);0;var o=Do(ta(r),1);n/r*o<=.5&&(o*=10);var a=mw(o),s=[Ho(Po(i[0]/o)*o,a),Ho(Lo(i[1]/o)*o,a)];return{intervalPrecision:a,interval:o,niceExtent:s}}(i,e):function(t,e){var n=ww(e.splitNumber,5),i=lw(t);0;var r=e.minInterval,o=e.maxInterval,a=na(i/n,!0);null!=r&&ao&&(a=o);var s=mw(a),l=t.getExtent(),u=[Ho(Po(l[0]/a)*a,s),Ho(Lo(l[1]/a)*a,s)];return{interval:a,intervalPrecision:s,niceExtent:u}}(i,e),u=l.intervalPrecision,c=l.interval,h=e.userInterval;null!=h&&(l.interval=h,l.intervalPrecision=mw(h)),r[0]||(s[0]=Ho(Lo(s[0]/c)*c,u)),r[1]||(s[1]=Ho(Po(s[1]/c)*c,u)),null!=h&&(l.niceExtent=s.slice()),Qw(t,r,a,s,o,l)}function RS(t){var e=t.scale,n=t.model,i=n.axis,r=n.ecModel;NS(e,n,i,r,null)}function NS(t,e,n,i,r){var o=LS(t,e,i,n,r),a=pw(t)||fw(t);ES(t,{splitNumber:e.get("splitNumber"),fixMinMax:o.fixMM,userInterval:e.get("interval"),minInterval:a?e.get("minInterval"):null,maxInterval:a?e.get("maxInterval"):null,rawExtentResult:o}),n&&i&&PS(n,t,o,i)}function ES(t,e){zS[t.type](t,e)}var zS={interval:OS,log:OS,time:function(t,e){var n=t.getExtent();if(n[0]===n[1]&&(n[0]-=Kp,n[1]+=Kp),n[1]===-1/0&&n[0]===1/0){var i=new Date;n[1]=+new Date(i.getFullYear(),i.getMonth(),i.getDate()),n[0]=n[1]-Kp}t.setExtent(n[0],n[1]);var r=ww(e.splitNumber,10),o=lw(t)/r,a=e.minInterval,s=e.maxInterval;null!=a&&os&&(o=s);var l=Dw.length,u=Math.min(function(t,e,n,i){for(;n>>1;t[r][1]n&&(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 JS(t,e){return V(F((t=function(t){if(!t.UTF8Encoding)return t;var e=t,n=e.UTF8Scale;return null==n&&(n=1024),B(e.features,function(t){var e=t.geometry,i=e.encodeOffsets,r=e.coordinates;if(i)switch(e.type){case"LineString":e.coordinates=$S(r,i,n);break;case"Polygon":case"MultiLineString":KS(r,i,n);break;case"MultiPolygon":B(r,function(t,e){return KS(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 XS(o[0],o.slice(1)));break;case"MultiPolygon":B(i.coordinates,function(t){t[0]&&r.push(new XS(t[0],t.slice(1)))});break;case"LineString":r.push(new ZS([i.coordinates]));break;case"MultiLineString":r.push(new ZS(i.coordinates))}var a=new jS(n[e||"name"],r,n.cp);return a.properties=n,a})}var QS=Object.freeze({__proto__:null,linearMap:Bo,round:function(t,e,n){return null==e&&(e=10),Ho(t,e,n)},asc:Wo,getPrecision:Uo,getPrecisionSafe:Yo,getPixelPrecision:function(t,e){var n=Lo(Ro(t[1]-t[0])/No),i=ko(Ro(Ao(e[1]-e[0]))/No),r=Co(Do(-n+i,0),20);return isFinite(r)?r:20},getPercentWithPrecision:function(t,e,n){return t[e]&&Zo(t,n)[e]||0},parsePercent:Vo,MAX_SAFE_INTEGER:qo,remRadian:Ko,isRadianAroundZero:$o,parseDate:Qo,quantity:ta,quantityExponent:ea,nice:na,quantile:ia,reformIntervals:ra,isNumeric:aa,numericToNumber:oa}),tM=Object.freeze({__proto__:null,parse:Qo,format:uf,roundTime:hf}),eM=Object.freeze({__proto__:null,extendShape:fd,extendPath:vd,makePath:xd,makeImage:_d,mergePath:wd,resizePath:Sd,createIcon:Od,updateProps:rd,initProps:od,getTransform:Td,clipPointsByRect:Ld,clipRectByRect:Pd,registerShape:yd,getShapeClass:md,Group:vo,Image:eu,Text:du,Circle:ah,Ellipse:lh,Sector:Sh,Ring:Ih,Polygon:Dh,Polyline:kh,Rect:lu,Line:Oh,BezierCurve:zh,Arc:Vh,IncrementalDisplayable:td,CompoundPath:Gh,LinearGradient:Hh,RadialGradient:Wh,BoundingRect:Xe}),nM=Object.freeze({__proto__:null,addCommas:Tf,toCamelCase:Cf,normalizeCssArray:Df,encodeHTML:se,formatTpl:Pf,getTooltipMarker:Rf,formatTime:function(t,e,n){"week"!==t&&"month"!==t&&"quarter"!==t&&"half-year"!==t&&"year"!==t||(t="MM-dd\nyyyy");var i=Qo(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"](),c=i[r+"Seconds"](),h=i[r+"Milliseconds"]();return t=t.replace("MM",af(a,2)).replace("M",a).replace("yyyy",o).replace("yy",af(o%100+"",2)).replace("dd",af(s,2)).replace("d",s).replace("hh",af(l,2)).replace("h",l).replace("mm",af(u,2)).replace("m",u).replace("ss",af(c,2)).replace("s",c).replace("SSS",af(h,3))},capitalFirst:function(t){return t?t.charAt(0).toUpperCase()+t.substr(1):t},truncateText:function(t,e,n,i,r){var o={};return Is(o,t,e,n,i,r),o.text},getTextRect:function(t,e,n,i,r,o,a,s){return new du({style:{text:t,font:e,align:n,verticalAlign:i,padding:r,rich:o,overflow:a?"truncate":null,lineHeight:s}}).getBoundingRect()}}),iM=Object.freeze({__proto__:null,map:V,each:B,indexOf:R,inherits:N,reduce:G,filter:F,bind:U,curry:Y,isArray:X,isString:j,isObject:$,isFunction:Z,extend:k,defaults:P,clone:C,merge:D}),rM=Pa(),oM=Pa(),aM=1,sM=2;function lM(t){return{out:{noPxChangeTryDetermine:[]},kind:t}}function uM(t,e){var n=t.getLabelModel().get("customValues");if(n){var i=t.scale;return{labels:V(hM(n,i),function(e,n){return{formattedLabel:Zw(t)(e,n),rawLabel:i.getLabel(e),tick:e}})}}return"category"===t.type?function(t,e){var n=t.getLabelModel(),i=dM(t,n,e);return!n.get("show")||t.scale.isBlank()?{labels:[]}:i}(t,e):function(t){var e=t.scale.getTicks(),n=Zw(t);return{labels:V(e,function(e,i){return{formattedLabel:n(e,i),rawLabel:t.scale.getLabel(e),tick:e}})}}(t)}function cM(t,e,n){var i=t.scale,r=t.getTickModel().get("customValues");return r?{ticks:hM(r,i)}:"category"===t.type?function(t,e){var n,i,r=pM(t),o=qw(e),a=vM(r,o);if(a)return a;e.get("show")&&!t.scale.isBlank()||(n=[]);if(Z(o))n=_M(t,o,!0);else if("auto"===o){var s=dM(t,t.getLabelModel(),lM(sM));i=s.labelCategoryInterval,n=V(s.labels,function(t){return t.tick})}else n=_M(t,i=o,!0);return yM(r,o,{ticks:n,tickCategoryInterval:i})}(t,e):{ticks:i.getTicks(n)}}function hM(t,e){var n=e.getExtent(),i=[];return B(t,function(t){(t=e.parse(t))>=n[0]&&t<=n[1]&&i.push(t)}),ts(i,ns,null),Wo(i),V(i,function(t){return{value:t}})}function dM(t,e,n){var i,r,o=fM(t),a=qw(e),s=n.kind===aM;if(!s){var l=vM(o,a);if(l)return l}Z(a)?i=_M(t,a,!1):(r="auto"===a?function(t,e){if(e.kind===aM){var n=t.calculateCategoryInterval(e);return e.out.noPxChangeTryDetermine.push(function(){return oM(t).autoInterval=n,!0}),n}var i=oM(t).autoInterval;return null!=i?i:oM(t).autoInterval=t.calculateCategoryInterval(e)}(t,n):a,i=_M(t,r,!1));var u={labels:i,labelCategoryInterval:r};return s?n.out.noPxChangeTryDetermine.push(function(){return yM(o,a,u),!0}):yM(o,a,u),u}var pM=gM("axisTick"),fM=gM("axisLabel");function gM(t){return function(e){return oM(e)[t]||(oM(e)[t]={list:[]})}}function vM(t,e){for(var n=0;ne&&i.axisExtent0===r[0]&&i.axisExtent1===r[1])return o;i.lastTickCount=n,i.lastAutoInterval=e,i.axisExtent0=r[0],i.axisExtent1=r[1]}function _M(t,e,n){var i=Zw(t),r=t.scale,o=[],a=Z(e);return Sw(r,a?0:e,function(t,s){var l=r.getLabel(t);if(a){var u=!!e(t.value,l);if(t.offInterval=!u,!u&&!s)return}o.push(n?t:{formattedLabel:i(t),rawLabel:l,tick:t})}),o}function bM(t,e){e=e||{};var n,i={w:NaN,w2:NaN},r=t.scale,o=e.fromStat,a=e.min,s=(n=sw(r,3))[1]-n[0];ca(s)||(s=NaN);var l=t.getExtent(),u=Ao(l[1]-l[0]);return vw(r)?function(t,e,n,i){var r=e.onBand,o=n+(r?1:0);0===o&&(o=1),t.w=i/o,!r&&n&&i&&(t.w2=t.w*n/i)}(i,t,s,u):o&&function(t,e,n,i,r){0;var o=!1,a=-1/0;B(r.key?[lS(e,r.key)]:function(t,e){var n=[];return uS(t.model.ecModel,function(t){for(var i=0;i0?(e>a&&(a=e),o=!1):-2===e&&(o=!0))}),ca(n)&&n>0&&ca(a)?(t.w=i/n*a,t.w2=a):o&&(t.w=.8*i,t.w2=t.w*n/i)}(i,t,s,u,o),null!=a&&(i.w=ca(i.w)?Do(a,i.w):a),i}var wM=[0,1],SM=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(this.scale.parse(t))},t.prototype.getExtent=function(){return this._extent.slice()},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.scale;return Bo(t=n.normalize(n.parse(t)),wM,MM(this),e)},t.prototype.coordToData=function(t,e){var n=Bo(t,MM(this),wM,e);return this.scale.scale(n)},t.prototype.pointToData=function(t,e){},t.prototype.getTicksCoords=function(t){var e=(t=t||{}).tickModel||this.getTickModel(),n=V(cM(this,e,{breakTicks:t.breakTicks,pruneByBreak:t.pruneByBreak}).ticks,function(t){return{coord:this.dataToCoord(tS(this.scale,t)),tick:t}},this),i=function(t,e,n){var i=e.length;if(!t.onBand||n||!i)return!1;var r=bM(t).w;if(!r)return!1;B(e,function(t){t.coord-=r/2});var o=t.scale.getExtent(),a=e[i-1];a.tick.offInterval&&e.pop();return e.push({coord:a.coord+r,tick:{value:o[1]+1}}),!0}(this,n,e.get("alignWithLabel"));return V(n,function(t){return{coord:t.coord,tickValue:t.tick.value,onBand:i}})},t.prototype.getMinorTicksCoords=function(){if(vw(this.scale))return[];var t=this.model.getModel("minorTick").get("splitNumber");return t>0&&t<100||(t=5),V(this.scale.getMinorTicks(t),function(t){return V(t,function(t){return{coord:this.dataToCoord(t),tickValue:t}},this)},this)},t.prototype.getViewLabels=function(t){return uM(this,t=t||lM(sM)).labels},t.prototype.getLabelModel=function(){return this.model.getModel("axisLabel")},t.prototype.getTickModel=function(){return this.model.getModel("axisTick")},t.prototype.getBandWidth=function(){return bM(this,{min:1}).w},t.prototype.calculateCategoryInterval=function(t){return function(t,e){var n=e.kind,i=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),r=Zw(t),o=(i.axisRotate-i.labelRotate)/180*Math.PI,a=t.scale,s=a.getExtent(),l=a.count();if(s[1]-s[0]<1)return 0;var u=1;l>40&&(u=Math.max(1,Math.floor(l/40)));for(var c=s[0],h=t.dataToCoord(c+1)-t.dataToCoord(c),d=Math.abs(h*Math.cos(o)),p=Math.abs(h*Math.sin(o)),f=0,g=0;c<=s[1];c+=u){var v,y,m=qr(r({value:c}),i.font,"center","top");v=1.3*m.width,y=1.3*m.height,f=Math.max(f,v,7),g=Math.max(g,y,7)}var x=f/d,_=g/p;isNaN(x)&&(x=1/0),isNaN(_)&&(_=1/0);var b=Math.max(0,Math.floor(Math.min(x,_)));if(n===aM)return e.out.noPxChangeTryDetermine.push(U(mM,null,t,b,l)),b;var w=xM(t,b,l);return null!=w?w:b}(this,t=t||lM(sM))},t}();function MM(t){var e=t.getExtent();if(t.onBand){var n=(e[1]-e[0])/t.scale.count()/2;e[0]+=n,e[1]-=n}return e}var IM=2*Math.PI,TM=Al.CMD,CM=["top","right","bottom","left"];function DM(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 AM(t,e,n,i,r,o,a,s,l){a-=t,s-=e;var u=Math.sqrt(a*a+s*s),c=(a/=u)*n+t,h=(s/=u)*n+e;if(Math.abs(i-r)%IM<1e-4)return l[0]=c,l[1]=h,u-n;if(o){var d=i;i=Rl(r),r=Rl(d)}else i=Rl(i),r=Rl(r);i>r&&(r+=IM);var p=Math.atan2(s,a);if(p<0&&(p+=IM),p>=i&&p<=r||p+IM>=i&&p+IM<=r)return l[0]=c,l[1]=h,u-n;var f=n*Math.cos(i)+t,g=n*Math.sin(i)+e,v=n*Math.cos(r)+t,y=n*Math.sin(r)+e,m=(f-a)*(f-a)+(g-s)*(g-s),x=(v-a)*(v-a)+(y-s)*(y-s);return m0){e=e/180*Math.PI,NM.fromArray(t[0]),EM.fromArray(t[1]),zM.fromArray(t[2]),Pe.sub(BM,NM,EM),Pe.sub(VM,zM,EM);var n=BM.len(),i=VM.len();if(!(n<.001||i<.001)){BM.scale(1/n),VM.scale(1/i);var r=BM.dot(VM);if(Math.cos(e)1&&Pe.copy(HM,zM),HM.toArray(t[1])}}}}function UM(t,e,n){if(n<=180&&n>0){n=n/180*Math.PI,NM.fromArray(t[0]),EM.fromArray(t[1]),zM.fromArray(t[2]),Pe.sub(BM,EM,NM),Pe.sub(VM,zM,EM);var i=BM.len(),r=VM.len();if(!(i<.001||r<.001))if(BM.scale(1/i),VM.scale(1/r),BM.dot(e)=a)Pe.copy(HM,zM);else{HM.scaleAndAdd(VM,o/Math.tan(Math.PI/2-s));var l=zM.x!==EM.x?(HM.x-EM.x)/(zM.x-EM.x):(HM.y-EM.y)/(zM.y-EM.y);if(isNaN(l))return;l<0?Pe.copy(HM,EM):l>1&&Pe.copy(HM,zM)}HM.toArray(t[1])}}}function YM(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?.3:Math.max(+a,0)||0,o.shape=o.shape||{},o.shape.smooth=a;var s=i.getModel("lineStyle").getLineStyle();r?t.useStyle(s):o.style=s}function XM(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=Ft(i[0],i[1]),o=Ft(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=Ut([],i[1],i[0],a/r),l=Ut([],i[1],i[2],a/o),u=Ut([],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 c=1;c0&&r&&b(-h/o,0,o);var g,v,y=t[0],m=t[o-1];function x(){g=y.rect[a]-n,v=i-m.rect[a]-m.rect[s]}function _(t,e,n){if(t<0){var i=Math.min(e,-t);if(i>0){b(i*n,0,o);var r=i+t;r<0&&w(-r*n,1)}else w(-t*n,1)}}function b(e,n,i){0!==e&&(c=!0);for(var r=n;r0)for(l=0;l0;l--){b(-(i[l-1]*h),l,o)}}}function S(t){var e=t<0?-1:1;t=Math.abs(t);for(var n=Math.ceil(t/(o-1)),i=0;i0?b(n,0,i+1):b(-n,o-i-1,o),(t-=n)<=0)return}return x(),g<0&&w(-g,.8),v<0&&w(v,.8),x(),_(g,v,1),_(v,g,-1),x(),g<0&&S(-g),v<0&&S(v),c}function oI(t){var e=[];function n(t){if(!t.ignore){var e=t.ensureState("emphasis");null==e.ignore&&(e.ignore=!1)}t.ignore=!0}t.sort(function(t,e){return(e.suggestIgnore?1:0)-(t.suggestIgnore?1:0)||e.priority-t.priority});for(var i=0;i=0&&n.attr(p.oldLayoutSelect),R(u,"emphasis")>=0&&n.attr(p.oldLayoutEmphasis)),rd(n,s,e,a)}else if(n.attr(s),!fp(n).valueAnimation){var c=at(n.style.opacity,1);n.style.opacity=0,od(n,{style:{opacity:c}},e,a)}if(p.oldLayout=s,n.states.select){var h=p.oldLayoutSelect={};pI(h,s,fI),pI(h,n.states.select,fI)}if(n.states.emphasis){var d=p.oldLayoutEmphasis={};pI(d,s,fI),pI(d,n.states.emphasis,fI)}vp(n,a,l,e,e)}if(i&&!i.ignore&&!i.invisible){r=(p=dI(i)).oldLayout;var p,f={points:i.shape.points};r?(i.attr({shape:r}),rd(i,{shape:f},e)):(i.setShape(f),i.style.strokePercent=0,od(i,{style:{strokePercent:1}},e)),p.oldLayout=f}},t}(),vI=Pa();var yI=Math.sin,mI=Math.cos,xI=Math.PI,_I=2*Math.PI,bI=180/xI,wI=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,c=Math.abs(l),h=Pi(c-_I)||(u?l>=_I:-l>=_I),d=l>0?l%_I:l%_I+_I,p=!1;p=!!h||!Pi(c)&&d>=xI==!!u;var f=t+n*mI(o),g=e+i*yI(o);this._start&&this._add("M",f,g);var v=Math.round(r*bI);if(h){var y=1/this._p,m=(u?1:-1)*(_I-y);this._add("A",n,i,v,1,+u,t+n*mI(o+m),e+i*yI(o+m)),y>.01&&this._add("A",n,i,v,0,+u,f,g)}else{var x=t+n*mI(a),_=e+i*yI(a);this._add("A",n,i,v,+p,+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=[],c=this._p,h=1;h"}(r,o)+("style"!==r?se(a):a||"")+(i?""+n+V(i,function(e){return t(e)}).join(n)+n:"")+("")}(t)}function RI(t){return{zrId:t,shadowCache:{},patternCache:{},gradientCache:{},clipPathCache:{},defs:{},cssNodes:{},cssAnims:{},cssStyleCache:{},cssAnimIdx:0,shadowIdx:0,gradientIdx:0,patternIdx:0,clipPathIdx:0}}function NI(t,e,n,i){return PI("svg","root",{width:t,height:e,xmlns:DI,"xmlns:xlink":AI,version:"1.1",baseProfile:"full",viewBox:!!i&&"0 0 "+t+" "+e},n)}var EI=0;function zI(){return EI++}var BI={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"},VI="transform-origin";function GI(t,e,n){var i=k({},t.shape);k(i,e),t.buildPath(n,i);var r=new wI;return r.reset(Hi(t)),n.rebuildPath(r,1),r.generateStr(),r.getStr()}function FI(t,e){var n=e.originX,i=e.originY;(n||i)&&(t[VI]=n+"px "+i+"px")}var HI={fill:"fill",opacity:"opacity",lineWidth:"stroke-width",lineDashOffset:"stroke-dashoffset"};function WI(t,e){var n=e.zrId+"-ani-"+e.cssAnimIdx++;return e.cssAnims[n]=t,n}function UI(t){return j(t)?BI[t]?"cubic-bezier("+BI[t]+")":Jn(t)?t:"":""}function YI(t,e,n,i){var r=t.animators,o=r.length,a=[];if(t instanceof Gh){var s=function(t,e,n){var i,r,o=t.shape.paths,a={};if(B(o,function(t){var e=RI(n.zrId);e.animation=!0,YI(t,{},e,!0);var o=e.cssAnims,s=e.cssNodes,l=W(o),u=l.length;if(u){var c=o[r=l[u-1]];for(var h in c){var d=c[h];a[h]=a[h]||{d:""},a[h].d+=d.d||""}for(var p in s){var f=s[p].animation;f.indexOf(r)>=0&&(i=f)}}}),i){e.d=!1;var s=WI(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 WI(c,n)+" "+r[0]+" both"}for(var v in l){(s=g(l[v]))&&a.push(s)}if(a.length){var y=n.zrId+"-cls-"+zI();n.cssNodes["."+y]={animation:a.join(",")},e.class=y}}function XI(t,e,n,i){var r=JSON.stringify(t),o=n.cssStyleCache[r];o||(o=n.zrId+"-cls-"+zI(),n.cssStyleCache[r]=o,n.cssNodes["."+o+(i?":hover":"")]=t),e.class=e.class?e.class+" "+o:o}var ZI=Math.round;function jI(t){return t&&j(t.src)}function qI(t){return t&&Z(t.toDataURL)}function KI(t,e,n,i){CI(function(r,o){var a="fill"===r||"stroke"===r;a&&Gi(o)?sT(e,t,r,i):a&&zi(o)?lT(n,t,r,i):t[r]=o,a&&i.ssr&&"none"===o&&(t["pointer-events"]="visible")},e,n,!1),function(t,e,n){var i=t.style;if(function(t){return t&&(t.shadowBlur||t.shadowOffsetX||t.shadowOffsetY)}(i)){var r=function(t){var e=t.style,n=t.getGlobalScale();return[e.shadowColor,(e.shadowBlur||0).toFixed(2),(e.shadowOffsetX||0).toFixed(2),(e.shadowOffsetY||0).toFixed(2),n[0],n[1]].join(",")}(t),o=n.shadowCache,a=o[r];if(!a){var s=t.getGlobalScale(),l=s[0],u=s[1];if(!l||!u)return;var c=i.shadowOffsetX||0,h=i.shadowOffsetY||0,d=i.shadowBlur,p=ki(i.shadowColor),f=p.opacity,g=p.color,v=d/2/l+" "+d/2/u;a=n.zrId+"-s"+n.shadowIdx++,n.defs[a]=PI("filter",a,{id:a,x:"-100%",y:"-100%",width:"300%",height:"300%"},[PI("feDropShadow","",{dx:c/l,dy:h/u,stdDeviation:v,"flood-color":g,"flood-opacity":f})]),o[r]=a}e.filter=Fi(a)}}(n,t,i)}function $I(t,e){var n=So(e);n&&(n.each(function(e,n){null!=e&&(t[(kI+n).toLowerCase()]=e+"")}),e.isSilent()&&(t[kI+"silent"]="true"))}function JI(t){return Pi(t[0]-1)&&Pi(t[1])&&Pi(t[2])&&Pi(t[3]-1)}function QI(t,e,n){if(e&&(!function(t){return Pi(t[4])&&Pi(t[5])}(e)||!JI(e))){var i=n?10:1e4;t.transform=JI(e)?"translate("+ZI(e[4]*i)/i+" "+ZI(e[5]*i)/i+")":function(t){return"matrix("+Oi(t[0])+","+Oi(t[1])+","+Oi(t[2])+","+Oi(t[3])+","+Ri(t[4])+","+Ri(t[5])+")"}(e)}}function tT(t,e,n){for(var i=t.points,r=[],o=0;o=0&&a||o;s&&(r=Ci(s))}var l=i.lineWidth;l&&(l/=!i.strokeNoScale&&t.transform?t.transform[0]:1);var u={cursor:"pointer"};r&&(u.fill=r),i.stroke&&(u.stroke=i.stroke),l&&(u["stroke-width"]=l),XI(u,e,n,!0)}}(t,o,e),PI(s,t.id+"",o)}function aT(t,e){return t instanceof Kl?oT(t,e):t instanceof eu?function(t,e){var n=t.style,i=n.image;if(i&&!j(i)&&(jI(i)?i=i.src:qI(i)&&(i=i.toDataURL())),i){var r=n.x||0,o=n.y||0,a={href:i,width:n.width,height:n.height};return r&&(a.x=r),o&&(a.y=o),QI(a,t.transform),KI(a,n,t,e),$I(a,t),e.animation&&YI(t,a,e),PI("image",t.id+"",a)}}(t,e):t instanceof Jl?function(t,e){var n=t.style,i=n.text;if(null!=i&&(i+=""),i&&!isNaN(n.x)&&!isNaN(n.y)){var r=n.font||a,s=n.x||0,l=function(t,e,n){return"top"===n?t+=e/2:"bottom"===n&&(t-=e/2),t}(n.y||0,Jr(r),n.textBaseline),u={"dominant-baseline":"central","text-anchor":Ni[n.textAlign]||n.textAlign};if(mu(n)){var c="",h=n.fontStyle,d=vu(n.fontSize);if(!parseFloat(d))return;var p=n.fontFamily||o,f=n.fontWeight;c+="font-size:"+d+";font-family:"+p+";",h&&"normal"!==h&&(c+="font-style:"+h+";"),f&&"normal"!==f&&(c+="font-weight:"+f+";"),u.style=c}else u.style="font: "+r;return i.match(/\s/)&&(u["xml:space"]="preserve"),s&&(u.x=s),l&&(u.y=l),QI(u,t.transform),KI(u,n,t,e),$I(u,t),e.animation&&YI(t,u,e),PI("text",t.id+"",u,void 0,i)}}(t,e):void 0}function sT(t,e,n,i){var r,o=t[n],a={gradientUnits:o.global?"userSpaceOnUse":"objectBoundingBox"};if(Bi(o))r="linearGradient",a.x1=o.x,a.y1=o.y,a.x2=o.x2,a.y2=o.y2;else{if(!Vi(o))return void 0;r="radialGradient",a.cx=at(o.x,.5),a.cy=at(o.y,.5),a.r=at(o.r,.5)}for(var s=o.colorStops,l=[],u=0,c=s.length;ul?ST(t,null==n[h+1]?null:n[h+1].elm,n,s,h):MT(t,e,a,l))}(n,i,r):xT(r)?(xT(t.text)&&vT(n,""),ST(n,null,r,0,r.length-1)):xT(i)?MT(n,i,0,i.length-1):xT(t.text)&&vT(n,""):t.text!==e.text&&(xT(i)&&MT(n,i,0,i.length-1),vT(n,e.text)))}var CT=0,DT=function(){function t(t,e,n){if(this.type="svg",this.configLayer=function(){},this.storage=e,this._opts=n=k({},n),this.root=t,this._id="zr"+CT++,this._oldVNode=NI(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=LI("svg");IT(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(bT(t,e))TT(t,e);else{var n=t.elm,i=fT(n);wT(e),null!==i&&(hT(i,e.elm,gT(n)),MT(i,[t],0,0))}}(this._oldVNode,t),this._oldVNode=t}},t.prototype.renderOneToVNode=function(t){return aT(t,RI(this._id))},t.prototype.renderToVNode=function(t){t=t||{};var e=this.storage.getDisplayList(!0),n=this._width,i=this._height,r=RI(this._id);r.animation=t.animation,r.willUpdate=t.willUpdate,r.compress=t.compress,r.emphasis=t.emphasis,r.ssr=this._opts.ssr;var o=[],a=this._bgVNode=function(t,e,n,i){var r;if(n&&"none"!==n)if(r=PI("rect","bg",{width:t,height:e,x:"0",y:"0"}),Gi(n))sT({fill:n},r.attrs,"fill",i);else if(zi(n))lT({style:{fill:n},dirty:St,getBoundingRect:function(){return{width:t,height:e}}},r.attrs,"fill",i);else{var o=ki(n),a=o.color,s=o.opacity;r.attrs.fill=a,s<1&&(r.attrs["fill-opacity"]=s)}return r}(n,i,this._backgroundColor,r);a&&o.push(a);var s=t.compress?null:this._mainVNode=PI("g","main",{},[]);this._paintList(e,r,s?s.children:o),s&&o.push(s);var l=V(W(r.defs),function(t){return r.defs[t]});if(l.length&&o.push(PI("defs","defs",{},l)),t.animation){var u=function(t,e,n){var i=(n=n||{}).newline?"\n":"",r=" {"+i,o=i+"}",a=V(W(t),function(e){return e+r+V(W(t[e]),function(n){return n+":"+t[e][n]+";"}).join(i)+o}).join(i),s=V(W(e),function(t){return"@keyframes "+t+r+V(W(e[t]),function(n){return n+r+V(W(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):""}(r.cssNodes,r.cssAnims,{newline:!0});if(u){var c=PI("style","stl",{},[],u);o.push(c)}}return NI(n,i,o,t.useViewBox)},t.prototype.renderToString=function(t){return t=t||{},OI(this.renderToVNode({animation:at(t.cssAnimation,!0),emphasis:at(t.cssEmphasis,!0),willUpdate:!1,compress:!0,useViewBox:at(t.useViewBox,!0)}),{newline:!0})},t.prototype.setBackgroundColor=function(t){this._backgroundColor=t},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&&(!h||!r||h[f]!==r[f]);f--);for(var g=p-1;g>f;g--)i=a[--s-1];for(var v=f+1;v=o)}}for(var u=LT(this),c=u.startIdx;c=0)&&(o=!0)}),o||r.__dirty){var a=n._opts.useDirtyRect&&!kT(r)?r.createRepaintRects(t,e,n._width,n._height):null,s=n._i.layerStack[0],l=!0;if(r.__dirty){l=!1,r.__dirty=!1;var u=r.zlevel===s.zl&&r.zlevel2===s.zl2?n._backgroundColor:null;r.clear(!1,u,a)}VT(r,function(e){var o=n._paintPerCursor(r,e,t,a,l);i=i&&o})}},YT),r.wxa&&FT(this._i,function(t){t&&t.ctx&&t.ctx.draw&&t.ctx.draw()}),i},t.prototype._paintPerCursor=function(t,e,n,i,r){var o=t.ctx;if(i)if(i.length)for(var a=this.dpr,s=0;s=e.endIdx},t.prototype._paintPerCursorInRect=function(t,e,n,i,r){for(var o={inHover:!1,allClipped:!1,prevEl:null,viewWidth:this._width,viewHeight:this._height,beforeBrushParam:{contentRetained:r}},a=t.ctx,s=kT(t),l=s&&c.getTime(),u=e.drawIdx,h=e.notClearIdx,d=h>=0?Math.min(h,u):u;d15){d++;break}}}Wx(a,o),e.drawIdx=Math.max(d,u)},t.prototype.getLayer=function(t,e){return this._ensureLayer(t,0,e)},t.prototype._ensureLayer=function(t,e,n){e=e||0;var i=this._singleCanvas;i&&!this._needsManuallyCompositing&&(t=RT,e=0);var r=GT(this._i,t)[e];return r||(r=ET("zr_"+t+"."+e,this,t,e),this._layerConfig[t]&&D(r,this._layerConfig[t],!0),(n||i&&t!==RT)&&(r.virtual=!0),this._insertLayer(r,t,e,!1),r.initContext()),r},t.prototype.insertLayer=function(t,e){this._insertLayer(e,t,0,!1)},t.prototype._insertLayer=function(t,e,n,i){var r=this._i,o=r.layers,a=r.layerStack,s=this._domRoot,l=null;if((!o[e]||!o[e][n])&&function(t){return!!t&&(!!t.__builtin__||"function"==typeof t.resize&&"function"==typeof t.refresh)}(t)){for(var u=a.length,c=0;c0&&(l=GT(r,a[c-1].zl)[a[c-1].zl2]),a.splice(c,0,{zl:e,zl2:n}),GT(r,e)[n]=t,!i&&!t.virtual)if(l){var h=l.dom;h.nextSibling?s.insertBefore(t.dom,h.nextSibling):s.appendChild(t.dom)}else s.firstChild?s.insertBefore(t.dom,s.firstChild):s.appendChild(t.dom);t.painter||(t.painter=this)}},t.prototype.eachLayer=function(t,e){return FT(this._i,function(n,i){t.call(e,n,i)})},t.prototype.eachBuiltinLayer=function(t,e){return FT(this._i,function(n,i){t.call(e,n,i)},HT)},t.prototype.eachOtherLayer=function(t,e){return FT(this._i,function(n,i){t.call(e,n,i)},WT)},t.prototype.getLayers=function(){var t={};return FT(this._i,function(e,n,i){t[e.id]=e}),t},t.prototype._updateLayerStatus=function(t,e){var n,i=this;if(i._singleCanvas)for(var r=1;r=0;o--){var a=r.get(n[o]);if(a.used){var s=a.endIdxNew;(kT(e)?s=0;i--){var r=e[i];if(r.zl===t){var o=n[t][r.zl2];if(o.__builtin__)continue;if(e.splice(i,1),n[t][r.zl2]=void 0,!o.virtual){var a=o.dom.parentNode;a&&a.removeChild(o.dom)}}}},t.prototype.resize=function(t,e){if(this._domRoot.style){var n=this._domRoot;n.style.display="none";var i=this._opts,r=this.root;null!=t&&(i.width=t),null!=e&&(i.height=e),t=Tx(r,0,i),e=Tx(r,1,i),n.style.display="",this._width===t&&e===this._height||(n.style.width=t+"px",n.style.height=e+"px",FT(this._i,function(n){n.resize(t,e)}),this.refresh({paintAll:!0})),this._width=t,this._height=e}else{if(null==t||null==e)return;this._width=t,this._height=e,this._ensureLayer(RT).resize(t,e)}return this},t.prototype.clearLayer=function(t){B(this._i.layers[t],function(t){t&&!t.__builtin__&&t.clear()})},t.prototype.dispose=function(){this.root.innerHTML="",this.root=this.storage=this._domRoot=this._i=null},t.prototype.getRenderedCanvas=function(t){if(t=t||{},this._singleCanvas&&!this._compositeManually)return this._i.layers[314159][0].dom;var e=new PT("image",this,t.pixelRatio||this.dpr);e.initContext(),e.clear(!1,t.backgroundColor||this._backgroundColor);var n=e.ctx;if(t.pixelRatio<=this.dpr){this.refresh();var i=e.dom.width,r=e.dom.height;FT(this._i,function(t){t.__builtin__?n.drawImage(t.dom,0,0,i,r):t.renderToCanvas&&(n.save(),t.renderToCanvas(n),n.restore())})}else{for(var o={inHover:!1,viewWidth:this._width,viewHeight:this._height,beforeBrushParam:{}},a=this.storage.getDisplayList(!0),s=0,l=a.length;s-1&&(s.style.stroke=s.style.fill,s.style.fill=ug.color.neutral00,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:6,symbolRotate:null,showSymbol:!0,showAllSymbol:"auto",connectNulls:!1,sampling:"none",animationEasing:"linear",progressive:0,hoverLayerThreshold:1/0,universalTransition:{divideShape:"clone"},triggerLineEvent:!1,triggerEvent:!1},e}(Hy);function jT(t,e){var n=t.mapDimensionsAll("defaultedLabel"),i=n.length;if(1===i){var r=zv(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 KT=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,o){this.removeAll();var a=xx(t,-1,-1,2,2,null,o);a.attr({z2:at(r,100),culling:!0,scaleX:i[0]/2,scaleY:i[1]/2}),a.drift=$T,this._symbolType=t,this.add(a)},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(){vc(this.childAt(0))},e.prototype.downplay=function(){yc(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=e.getSymbolZ2(t,n),u=o!==this._symbolType,c=r&&r.disableAnimation;if(u){var h=t.getItemVisual(n,"symbolKeepAspect");this._createSymbol(o,t,n,s,l,h)}else{(p=this.childAt(0)).silent=!1;var d={scaleX:s[0]/2,scaleY:s[1]/2};c?p.attr(d):rd(p,d,a,n),cd(p)}if(this._updateCommon(t,n,s,i,r),u){var p=this.childAt(0);if(!c){d={scaleX:this._sizeX,scaleY:this._sizeY,style:{opacity:p.style.opacity}};p.scaleX=p.scaleY=0,p.style.opacity=0,od(p,d,a,n)}}c&&this.childAt(0).stopAnimation("leave")},e.prototype._updateCommon=function(t,e,n,i,r){var o,a,s,l,u,c,h,d,p,f=this.childAt(0),g=t.hostModel;if(i&&(o=i.emphasisItemStyle,a=i.blurItemStyle,s=i.selectItemStyle,l=i.focus,u=i.blurScope,h=i.labelStatesModels,d=i.hoverScale,p=i.cursorStyle,c=i.emphasisDisabled),!i||t.hasItemOption){var v=i&&i.itemModel?i.itemModel:t.getItemModel(e),y=v.getModel("emphasis");o=y.getModel("itemStyle").getItemStyle(),s=v.getModel(["select","itemStyle"]).getItemStyle(),a=v.getModel(["blur","itemStyle"]).getItemStyle(),l=y.get("focus"),u=y.get("blurScope"),c=y.get("disabled"),h=ap(v),d=y.getShallow("scale"),p=v.getShallow("cursor")}var m=t.getItemVisual(e,"symbolRotate");f.attr("rotation",(m||0)*Math.PI/180||0);var x=bx(t.getItemVisual(e,"symbolOffset"),n);x&&(f.x=x[0],f.y=x[1]),p&&f.attr("cursor",p);var _=t.getItemVisual(e,"style"),b=_.fill;if(f instanceof eu){var w=f.style;f.useStyle(k({image:w.image,x:w.x,y:w.y,width:w.width,height:w.height},_))}else f.__isEmptyBrush?f.useStyle(k({},_)):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;op(f,h,{labelFetcher:g,labelDataIndex:e,defaultText:function(e){return I?t.getName(e):jT(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==d||!0===d?Math.max(1.1,3/this._sizeY):isFinite(d)&&d>0?+d:1;T.scaleX=this._sizeX*C,T.scaleY=this._sizeY*C,this.setSymbolScale(1),kc(this,l,u,c)},e.prototype.setSymbolScale=function(t){this.scaleX=this.scaleY=t},e.prototype.fadeOut=function(t,e,n){var i=this.childAt(0),r=Iu(this).dataIndex,o=n&&n.animation;if(this.silent=i.silent=!0,n&&n.fadeLabel){var a=i.getTextContent();a&&sd(a,{style:{opacity:0}},e,{dataIndex:r,removeOpt:o,cb:function(){i.removeTextContent()}})}else i.removeTextContent();sd(i,{style:{opacity:0},scaleX:0,scaleY:0},e,{dataIndex:r,cb:t,removeOpt:o})},e.getSymbolSize=function(t,e){return _x(t.getItemVisual(e,"symbolSize"))},e.getSymbolZ2=function(t,e){return t.getItemVisual(e,"z2")},e}(vo);function $T(t,e){this.parent.drift(t,e)}function JT(t,e,n,i){return e&&!isNaN(e[0])&&!isNaN(e[1])&&!(i&&i.isIgnore&&i.isIgnore(n))&&!(i&&i.clipShape&&!i.clipShape.contain(e[0],e[1]))&&"none"!==t.getItemVisual(n,"symbol")}function QT(t){return null==t||$(t)||(t={isIgnore:t}),t||{}}function tC(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:ap(e),cursorStyle:e.get("cursor")}}function eC(t,e,n,i,r,o,a){var s=new t(e,n,i,r);return s.setPosition(o),e.setItemGraphicEl(n,s),a.add(s),s}var nC=function(){function t(t){this.group=new vo,this._SymbolCtor=t||KT}return t.prototype.updateData=function(t,e){this._progressiveEls=null,e=QT(e);var n=this.group,i=t.hostModel,r=this._data,o=this._SymbolCtor,a=e.disableAnimation,s=this._seriesScope=tC(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);JT(t,r,i,e)&&eC(o,t,i,s,l,r,n)}).update(function(c,h){var d=r.getItemGraphicEl(h),p=u(c);if(JT(t,p,c,e)){var f=t.getItemVisual(c,"symbol")||"circle",g=d&&d.getSymbolType&&d.getSymbolType();if(!d||g&&g!==f)n.remove(d),(d=new o(t,c,s,l)).setPosition(p);else{d.updateData(t,c,s,l);var v={x:p[0],y:p[1]};a?d.attr(v):rd(d,v,i)}n.add(d),t.setItemGraphicEl(c,d)}else n.remove(d)}).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(t){var e=this._data;if(e)for(var n=this,i=0,r=e.getStore().count();i0?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),c="x"===s||"radius"===s?1:0,h=V(t.dimensions,function(t){return e.mapDimension(t)}),d=!1,p=e.getCalculationInfo("stackResultDimension");return qb(e,h[0])&&(d=!0,h[0]=p),qb(e,h[1])&&(d=!0,h[1]=p),{dataDimsForPoint:h,valueStart:o,valueAxisDim:s,baseAxisDim:a,stacked:!!d,valueDim:l,baseDim:u,baseDataOffset:c,stackedOverDimension:e.getCalculationInfo("stackedOverDimension")}}function rC(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)}function oC(t,e){return!isFinite(t)||!isFinite(e)}var aC=typeof Float32Array!==Cu?Float32Array:void 0,sC=typeof Float64Array!==Cu?Float64Array:void 0;function lC(t){return uC({ctor:aC},t).arr}function uC(t,e){var n=t.arr,i=t.ctor;if(e>qo&&(e=qo),!n||t.typed&&n.length=r||g<0)break;if(oC(y,m)){if(l){g+=o;continue}break}if(g===n)t[o>0?"moveTo":"lineTo"](y,m),h=y,d=m;else{var x=y-u,_=m-c;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===y&&S===m&&v=i||oC(w,S))p=y,f=m;else{T=w-u,C=S-c;var k=y-u,L=w-y,P=m-c,O=S-m,R=void 0,N=void 0;if("x"===s){var E=T>0?1:-1;p=y-E*(R=Math.abs(k))*a,f=m,D=y+E*(N=Math.abs(L))*a,A=m}else if("y"===s){var z=C>0?1:-1;p=y,f=m-z*(R=Math.abs(P))*a,D=y,A=m+z*(N=Math.abs(O))*a}else R=Math.sqrt(k*k+P*P),p=y-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=cC(D=y+T*a*I,hC(w,y)),A=cC(A,hC(S,m)),D=hC(D,cC(w,y)),f=m-(C=(A=hC(A,cC(S,m)))-m)*R/N,p=cC(p=y-(T=D-y)*R/N,hC(u,y)),f=cC(f,hC(c,m)),D=y+(T=y-(p=hC(p,cC(u,y))))*N/R,A=m+(C=m-(f=hC(f,cC(c,m))))*N/R}t.bezierCurveTo(h,d,p,f,y,m),h=D,d=A}else t.lineTo(y,m)}u=y,c=m,g+=o}return v}var pC=function(){this.smooth=0,this.smoothConstraint=!0},fC=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:ug.color.neutral99,fill:null}},e.prototype.getDefaultShape=function(){return new pC},e.prototype.buildPath=function(t,e){var n=e.points,i=0,r=n.length/2;if(e.connectNulls){for(;r>0&&oC(n[2*r-2],n[2*r-1]);r--);for(;i=0){var v=a?(c-i)*g+i:(u-n)*g+n;return a?[t,v]:[v,t]}n=u,i=c;break;case o.C:u=r[l++],c=r[l++],h=r[l++],d=r[l++],p=r[l++],f=r[l++];var y=a?Gn(n,u,h,p,t,s):Gn(i,c,d,f,t,s);if(y>0)for(var m=0;m=0){v=a?Bn(i,c,d,f,x):Bn(n,u,h,p,x);return a?[t,v]:[v,t]}}n=p,i=f}}},e}(Kl),gC=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e}(pC),vC=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 gC},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&&oC(n[2*o-2],n[2*o-1]);o--);for(;r=0,o=t.fill||ug.color.neutral99;DC(i,e);var a=null==i.textFill;return r?a&&(i.textFill=n.insideFill||ug.color.neutral00,!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||ug.color.neutral00),!i.textStroke&&n.outsideStroke&&(i.textStroke=n.outsideStroke)),i.text=e.text,i.rich=e.rich,B(e.rich,function(t){DC(t,t)}),i}function DC(t,e){e&&(wt(e,"fill")&&(t.textFill=e.fill),wt(e,"stroke")&&(t.textStroke=e.fill),wt(e,"lineWidth")&&(t.textStrokeWidth=e.lineWidth),wt(e,"font")&&(t.font=e.font),wt(e,"fontStyle")&&(t.fontStyle=e.fontStyle),wt(e,"fontWeight")&&(t.fontWeight=e.fontWeight),wt(e,"fontSize")&&(t.fontSize=e.fontSize),wt(e,"fontFamily")&&(t.fontFamily=e.fontFamily),wt(e,"align")&&(t.textAlign=e.align),wt(e,"verticalAlign")&&(t.textVerticalAlign=e.verticalAlign),wt(e,"lineHeight")&&(t.textLineHeight=e.lineHeight),wt(e,"width")&&(t.textWidth=e.width),wt(e,"height")&&(t.textHeight=e.height),wt(e,"backgroundColor")&&(t.textBackgroundColor=e.backgroundColor),wt(e,"padding")&&(t.textPadding=e.padding),wt(e,"borderColor")&&(t.textBorderColor=e.borderColor),wt(e,"borderWidth")&&(t.textBorderWidth=e.borderWidth),wt(e,"borderRadius")&&(t.textBorderRadius=e.borderRadius),wt(e,"shadowColor")&&(t.textBoxShadowColor=e.shadowColor),wt(e,"shadowBlur")&&(t.textBoxShadowBlur=e.shadowBlur),wt(e,"shadowOffsetX")&&(t.textBoxShadowOffsetX=e.shadowOffsetX),wt(e,"shadowOffsetY")&&(t.textBoxShadowOffsetY=e.shadowOffsetY),wt(e,"textShadowColor")&&(t.textShadowColor=e.textShadowColor),wt(e,"textShadowBlur")&&(t.textShadowBlur=e.textShadowBlur),wt(e,"textShadowOffsetX")&&(t.textShadowOffsetX=e.textShadowOffsetX),wt(e,"textShadowOffsetY")&&(t.textShadowOffsetY=e.textShadowOffsetY))}function AC(t,e){if(t.length===e.length){for(var n=0;n=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=V(o.stops,function(t){return{coord:l.toGlobalCoord(l.dataToCoord(t.value)),color:t.color}}),c=u.length,h=o.outerColors.slice();c&&u[0].coord>u[c-1].coord&&(u.reverse(),h.reverse());var d=function(t,e){var n,i,r=[],o=t.length;function a(t,e,n){var i=t.coord;return{coord:n,color:_i((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()),p=d.length;if(!p&&c)return u[0].coord<0?h[1]?h[1]:u[c-1].color:h[0]?h[0]:u[0].color;var f=d[0].coord-10,g=d[p-1].coord+10,v=g-f;if(v<.001)return"transparent";B(d,function(t){t.offset=(t.coord-f)/v}),d.push({offset:p?d[p-1].offset:.5,color:h[1]||"transparent"}),d.unshift({offset:p?d[0].offset:.5,color:h[0]||"transparent"});var y=new Hh(0,0,0,0,d,!0);return y[r]=f,y[r+"2"]=g,y}}}function NC(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 B(o.getViewLabels(),function(t){t.tick.offInterval||(s[tS(o.scale,t.tick)]=1)}),function(t){return!s.hasOwnProperty(e.get(a,t))}}}}function EC(t,e){return[t[2*e],t[2*e+1]]}function zC(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);Iu(d).seriesIndex=t.seriesIndex,kc(d,A,k,L);var O=PC(t.get("smooth")),R=t.get("smoothMonotone");if(d.setShape({smooth:O,smoothMonotone:R,connectNulls:b}),p){var N=o.getCalculationInfo("stackedOnSeries"),E=0;p.useStyle(P(s.getAreaStyle(),{fill:T,opacity:.7,lineJoin:"bevel",decal:o.getVisual("style").decal})),N&&(E=PC(N.get("smooth"))),p.setShape({smooth:O,stackedOnSmooth:E,smoothMonotone:R,connectNulls:b}),Rc(p,t,"areaStyle"),Iu(p).seriesIndex=t.seriesIndex,kc(p,A,k,L)}var z=this._changePolyState;o.eachItemGraphicEl(function(t){t&&(t.onHoverStateChange=z)}),this._polyline.onHoverStateChange=z,this._data=o,this._coordSys=i,this._stackedOnPoints=x,this._points=l,this._step=I,this._valueOrigin=y;var B=t.get("triggerEvent"),V=t.get("triggerLineEvent");var G=!0===V||!0===B||"line"===B,F=!0===V||!0===B||"area"===B;this.packEventData(t,d,G),p&&this.packEventData(t,p,F)},e.prototype.packEventData=function(t,e,n){Iu(e).eventData=n?{componentType:"series",componentSubType:"line",componentIndex:t.componentIndex,seriesIndex:t.seriesIndex,seriesName:t.name,seriesType:"line",selfType:e===this._polygon?"area":"line"}:null},e.prototype.highlight=function(t,e,n,i){var r=t.getData(),o=La(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(oC(l,u))return;if(this._clipShapeForSymbol&&!this._clipShapeForSymbol.contain(l,u))return;var c=t.get("zlevel")||0,h=t.get("z")||0;(s=new KT(r,o)).x=l,s.y=u,s.setZ(c,h);var d=s.getSymbolPath().getTextContent();d&&(d.zlevel=c,d.z=h,d.z2=this._polyline.z2+1),s.__temp=!0,r.setItemGraphicEl(o,s),s.stopSymbolAnimation(!0),this.group.add(s)}s.highlight()}else tm.prototype.highlight.call(this,t,e,n,i)},e.prototype.downplay=function(t,e,n,i){var r=t.getData(),o=La(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 tm.prototype.downplay.call(this,t,e,n,i)},e.prototype._changePolyState=function(t){var e=this._polygon;hc(this._polyline,t),e&&hc(e,t)},e.prototype._newPolyline=function(t){var e=this._polyline;return e&&this._lineGroup.remove(e),e=new fC({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 vC({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");Z(l)&&(l=l(null));var u=s.get("animationDelay")||0,c=Z(u)?u(null):u;t.eachItemGraphicEl(function(t,o){var s=t;if(s){var h=[t.x,t.y],d=void 0,p=void 0,f=void 0;if(n)if(r){var g=n,v=e.pointToCoord(h);i?(d=g.startAngle,p=g.endAngle,f=-v[1]/180*Math.PI):(d=g.r0,p=g.r,f=v[0])}else{var y=n;i?(d=y.x,p=y.x+y.width,f=t.x):(d=y.y+y.height,p=y.y,f=t.y)}var m=p===d?0:(f-d)/(p-d);a&&(m=1-m);var x=Z(u)?u(o):l*m+c,_=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(zC(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 du({z2:200})).ignoreClip=!0,o.setTextContent(this._endLabel),o.disableLabelAnimation=!0);var l=function(t){for(var e=t.length/2;e>0&&oC(t[2*e-2],t[2*e-1]);e--);return e-1}(a);l>=0&&(op(o,ap(t,"endLabel"),{inheritColor:n,labelFetcher:t,labelDataIndex:l,defaultText:function(t,e,n){return null!=n?qT(r,n):jT(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"),c=n.hostModel,h=c.get("connectNulls"),d=o.get("precision"),p=o.get("distance")||0,f=a.getBaseAxis(),g=f.isHorizontal(),v=f.inverse,y=e.shape,m=v?g?y.x:y.y+y.height:g?y.x+y.width:y.y,x=(g?p:0)*(v?-1:1),_=(g?0:-p)*(v?-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&&!h){var T=EC(u,S[0]);s.attr({x:T[0]+x,y:T[1]+_}),r&&(I=c.getRawValue(S[0]))}else{(T=l.getPointOn(m,b))&&s.attr({x:T[0]+x,y:T[1]+_});var C=c.getRawValue(S[0]),D=c.getRawValue(S[1]);r&&(I=Ha(n,d,C,D,w.t))}i.lastFrameIndex=S[0]}else{var A=1===t||i.lastFrameIndex>0?S[0]:0;T=EC(u,A);r&&(I=c.getRawValue(A)),s.attr({x:T[0]+x,y:T[1]+_})}if(r){var k=fp(s);"function"==typeof k.setLabelText&&k.setLabelText(I)}}},e.prototype._doUpdateAnimation=function(t,e,n,i,r,o,a){var s=this._polyline,l=this._polygon,u=t.hostModel,c=function(t,e,n,i,r,o,a){for(var s=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),l=[],u=[],c=[],h=[],d=[],p=[],f=[],g=iC(r,e,a),v=t.getLayout("points")||[],y=e.getLayout("points")||[],m=0;m3e3||l&&LC(d,f)>3e3)return s.stopAnimation(),s.setShape({points:p}),void(l&&(l.stopAnimation(),l.setShape({points:p,stackedOnPoints:f})));s.shape.__points=c.current,s.shape.points=h;var g={shape:{points:p}};c.current!==h&&(g.shape.__points=c.next),s.stopAnimation(),rd(s,g,u),l&&(l.setShape({points:h,stackedOnPoints:d}),l.stopAnimation(),rd(l,{shape:{stackedOnPoints:f}},u),s.shape.points!==l.shape.points&&(l.shape.points=s.shape.points));for(var v=[],y=c.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(),c=n.getDevicePixelRatio(),h=Math.abs(u[1]-u[0])*(c||1),d=Math.round(a/h);if(isFinite(d)&&d>1){"lttb"===r?t.setData(i.lttbDownSample(i.mapDimension(l.dim),1/d)):"minmax"===r&&t.setData(i.minmaxDownSample(i.mapDimension(l.dim),1/d));var p=void 0;j(r)?p=FC[r]:Z(r)&&(p=r),p&&t.setData(i.downSample(i.mapDimension(l.dim),1/d,p,HC))}}}}}var UC=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}(SM),YC=null;function XC(){return YC}var ZC="expandAxisBreak",jC="collapseAxisBreak",qC="toggleAxisBreak",KC="axisbreakchanged",$C={type:ZC,event:KC,update:"update",refineEvent:tD},JC={type:jC,event:KC,update:"update",refineEvent:tD},QC={type:qC,event:KC,update:"update",refineEvent:tD};function tD(t,e,n,i){var r=[];return B(t,function(t){r=r.concat(t.eventBreaks)}),{eventContent:{breaks:r}}}var eD=Math.PI,nD=[[1,2,1,2],[5,3,5,3],[8,3,8,3]],iD=[[0,1,0,1],[0,3,0,3],[0,3,0,3]],rD=Pa(),oD=Pa(),aD=function(){function t(t){this.recordMap={},this.resolveAxisNameOverlap=t}return t.prototype.ensureRecord=function(t){var e=t.axis.dim,n=t.componentIndex,i=this.recordMap,r=i[e]||(i[e]=[]);return r[n]||(r[n]={ready:{}})},t}();var sD=[1,0,0,1,0,0],lD=new Xe(0,0,0,0),uD=function(t,e,n,i,r,o){if(Kw(t.nameLocation)){var a=o.stOccupiedRect;a&&cD(function(t,e,n){return t.transform=Xd(t.transform,n),t.localRect=Yd(t.localRect,e),t.rect=Yd(t.rect,e),n&&t.rect.applyTransform(n),t.axisAligned=Wd(n),t.obb=void 0,(t.label=t.label||{}).ignore=!1,t}({},a,o.transGroup.transform),i,r)}else hD(o.labelInfoList,o.dirVec,i,r)};function cD(t,e,n){var i=new Pe;aI(t,e,i,{direction:Math.atan2(n.y,n.x),bidirectional:!1,touchThreshold:.05})&&eI(e,i)}function hD(t,e,n,i){for(var r=Pe.dot(i,e)>=0,o=0,a=t.length;o0?"top":"bottom",i="center"):$o(o-eD)?(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}(),pD=["axisLine","axisTickLabelEstimate","axisTickLabelDetermine","axisName"],fD={axisLine:function(t,e,n,i,r,o,a){var s=i.get(["axisLine","show"]);if("auto"===s&&(s=!0,null!=t.raw.axisLineAutoShow&&(s=!!t.raw.axisLineAutoShow)),s){var l=i.axis.getExtent(),u=o.transform,c=[l[0],0],h=[l[1],0],d=c[0]>h[0];u&&(Yt(c,c,u),Yt(h,h,u));var p=k({lineCap:"round"},i.getModel(["axisLine","lineStyle"]).getLineStyle()),f={strokeContainThreshold:t.raw.strokeContainThreshold||5,silent:!0,z2:1,style:p};if(i.get(["axisLine","breakLine"])&&Xp(i.axis.scale))XC().buildAxisBreakLine(i,r,o,f);else{var g=new Oh(k({shape:{x1:c[0],y1:c[1],x2:h[0],y2:h[1]}},f));Md(g.shape,g.style.lineWidth),g.anid="line",r.add(g)}var v=i.get(["axisLine","symbol"]);if(null!=v){var y=i.get(["axisLine","symbolSize"]);j(v)&&(v=[v,v]),(j(y)||K(y))&&(y=[y,y]);var m=bx(i.get(["axisLine","symbolOffset"])||0,y),x=y[0],_=y[1];B([{rotate:t.rotation+Math.PI/2,offset:m[0],r:0},{rotate:t.rotation-Math.PI/2,offset:m[1],r:Math.sqrt((c[0]-h[0])*(c[0]-h[0])+(c[1]-h[1])*(c[1]-h[1]))}],function(e,n){if("none"!==v[n]&&null!=v[n]){var i=xx(v[n],-x/2,-_/2,x,_,p.stroke,!0),o=e.r+e.offset,a=d?h:c;i.attr({rotation:e.rotate,x:a[0]+o*Math.cos(t.rotation),y:a[1]-o*Math.sin(t.rotation),silent:!0,z2:11}),r.add(i)}})}}},axisTickLabelEstimate:function(t,e,n,i,r,o,a,s){mD(e,r,s)&&gD(t,e,n,i,r,o,a,aM)},axisTickLabelDetermine:function(t,e,n,i,r,o,a,s){mD(e,r,s)&&gD(t,e,n,i,r,o,a,sM);var l=function(t,e,n,i){var r=i.axis,o=i.getModel("axisTick"),a=o.get("show");"auto"===a&&(a=!0,null!=t.raw.axisTickAutoShow&&(a=!!t.raw.axisTickAutoShow));if(!a||r.scale.isBlank())return[];for(var s=o.getModel("lineStyle"),l=t.tickDirection*o.get("length"),u=yD(r.getTicksCoords(),n.transform,l,P(s.getLineStyle(),{stroke:i.get(["axisLine","lineStyle","color"])}),"ticks"),c=0;ci[1],l="start"===e&&!s||"start"!==e&&s;$o(a-eD/2)?(o=l?"bottom":"top",r="center"):$o(a-1.5*eD)?(o=l?"top":"bottom",r="center"):(o="middle",r=a<1.5*eD&&a>eD/2?l?"left":"right":l?"right":"left");return{rotation:a,textAlign:r,textVerticalAlign:o}}(t.rotation,c,b||0,f),null!=(_=t.raw.axisNameAvailableWidth)&&(_=Math.abs(_/Math.sin(x.rotation)),!isFinite(_)&&(_=null)));var w=d.getFont(),S=i.get("nameTruncate",!0)||{},M=S.ellipsis,I=ot(t.raw.nameTruncateMaxWidth,S.maxWidth,_),T=s.nameMarginLevel||0,C=new du({x:v.x,y:v.y,rotation:x.rotation,silent:dD.isLabelSilent(i),style:sp(d,{text:u,font:w,overflow:"truncate",width:I,ellipsis:M,fill:d.getTextColor()||i.get(["axisLine","lineStyle","color"]),align:d.get("align")||x.textAlign,verticalAlign:d.get("verticalAlign")||x.textVerticalAlign}),z2:1});if(Gd({el:C,componentModel:i,itemName:u}),C.__fullText=u,C.anid="name",i.get("triggerEvent")){var D=dD.makeAxisEventDataBase(i);D.targetType="axisName",D.name=u,Iu(C).eventData=D}o.add(C),C.updateTransform(),e.nameEl=C;var A=l.nameLayout=JM({label:C,priority:C.z2,defaultAttr:{ignore:C.ignore},marginDefault:Kw(c)?nD[T]:iD[T]});if(l.nameLocation=c,r.add(C),C.decomposeTransform(),t.shouldNameMoveOverlap&&A){var k=n.ensureRecord(i);0,n.resolveAxisNameOverlap(t,n,i,A,y,k)}}}};function gD(t,e,n,i,r,o,a,s){xD(e)||function(t,e,n,i,r,o){var a=r.axis,s=ot(t.raw.axisLabelShow,r.get(["axisLabel","show"])),l=new vo;n.add(l);var u=lM(i);if(!s||a.scale.isBlank())return void _D(e,[],l,u);var c=r.getModel("axisLabel"),h=a.getViewLabels(u),d=(ot(t.raw.labelRotate,c.get("rotate"))||0)*eD/180,p=dD.innerTextLayout(t.rotation,d,t.labelDirection),f=r.getCategories&&r.getCategories(!0),g=[],v=r.get("triggerEvent"),y=1/0,m=-1/0;B(h,function(t,e){var n,i=t.tick,s=t.formattedLabel,u=t.rawLabel,d=c,x=tS(a.scale,i);if(f&&f[x]){var _=f[x];$(_)&&_.textStyle&&(d=new kp(_.textStyle,c,r.ecModel))}var b=d.getTextColor()||r.get(["axisLine","lineStyle","color"]),w=d.getShallow("align",!0)||p.textAlign,S=at(d.getShallow("alignMinLabel",!0),w),M=at(d.getShallow("alignMaxLabel",!0),w),I=d.getShallow("verticalAlign",!0)||d.getShallow("baseline",!0)||p.textVerticalAlign,T=at(d.getShallow("verticalAlignMinLabel",!0),I),C=at(d.getShallow("verticalAlignMaxLabel",!0),I),D=10+((null===(n=i.time)||void 0===n?void 0:n.level)||0);y=Math.min(y,D),m=Math.max(m,D);var A=new du({x:0,y:0,rotation:0,silent:dD.isLabelSilent(r),z2:D,style:sp(d,{text:s,align:0===e?S:e===h.length-1?M:w,verticalAlign:0===e?T:e===h.length-1?C:I,fill:Z(b)?b("category"===a.type?u:"value"===a.type?x+"":x,e):b})});A.anid="label_"+x;var k=rD(A);if(k.labelInfo=t,k.layoutRotation=p.rotation,Gd({el:A,componentModel:r,itemName:s,formatterParamsExtra:{isTruncated:function(){return A.isTruncated},value:u,tickIndex:e}}),v){var L=dD.makeAxisEventDataBase(r);L.targetType="axisLabel",L.value=u,L.tickIndex=e;var P=t.tick.break;if(P){var O=P.parsedBreak;L.break={start:O.vmin,end:O.vmax}}"category"===a.type&&(L.dataIndex=x),Iu(A).eventData=L,P&&function(t,e,n,i){n.on("click",function(n){var r={type:ZC,breaks:[{start:i.parsedBreak.breakOption.start,end:i.parsedBreak.breakOption.end}]};r[t.axis.dim+"AxisIndex"]=t.componentIndex,e.dispatchAction(r)})}(r,o,A,P)}g.push(A),l.add(A)});var x=V(g,function(t){return{label:t,priority:rD(t).labelInfo.tick.break?t.z2+(m-y+1):t.z2,defaultAttr:{ignore:t.ignore}}});_D(e,x,l,u)}(t,e,r,s,i,a);var l=e.labelLayoutList;!function(t,e,n,i){var r=e.get(["axisLabel","margin"]);B(n,function(n,o){var a=JM(n);if(a){var s=a.label,l=rD(s);a.suggestIgnore=s.ignore,s.ignore=!1,Hr(bD,wD);var u=e.axis;bD.x=u.dataToCoord(tS(u.scale,l.labelInfo.tick)),bD.y=t.labelOffset+t.labelDirection*r,bD.rotation=l.layoutRotation,i.add(bD),bD.updateTransform(),i.remove(bD),bD.decomposeTransform(),Hr(s,bD),s.markRedraw(),KM(a,!0),JM(a)}})}(t,i,l,o),function(t,e,n){var i=Wp();if(!i)return;var r=i.retrieveAxisBreakPairs(n,function(t){return t&&rD(t.label).labelInfo.tick.break},!0),o=t.get(["breakLabelLayout","moveOverlap"],!0);!0!==o&&"auto"!==o||B(r,function(i){XC().adjustBreakLabelPair(t.axis.inverse,e,[JM(n[i[0]]),JM(n[i[1]])])})}(i,t.rotation,l);var u=t.optionHideOverlap;!function(t,e,n){var i=t.axis,r=t.get(["axisLabel","customValues"]);if(function(t){return"category"===t.type&&0===qw(t.getLabelModel())}(i))return;function o(t,o,a){var s=JM(e[o]),l=JM(e[a]),u=i.scale;if(s&&l){if(null==t){if(!n&&r)return;var c=rD(s.label).labelInfo.tick;if(fw(u)&&c.notNice||vw(u)&&c.offInterval)return void vD(s.label)}if(!1===t||s.suggestIgnore)vD(s.label);else if(l.suggestIgnore)vD(l.label);else{var h=.1;if(!n){var d=[0,0,0,0];s=nI({marginForce:d},s),l=nI({marginForce:d},l)}aI(s,l,null,{touchThreshold:h})&&vD(t?l.label:s.label)}}}var a=t.get(["axisLabel","showMinLabel"]),s=t.get(["axisLabel","showMaxLabel"]),l=e.length;o(a,0,1),o(s,l-1,l-2)}(i,l,u),u&&oI(F(l,function(t){return t&&!t.label.ignore})),function(t,e,n,i){var r,o=n.axis,a=e.ensureRecord(n),s=[],l=SD(t.axisName)&&Kw(t.nameLocation);B(i,function(t){var e=JM(t);if(e&&!e.label.ignore){s.push(e);var n=a.transGroup;l&&(n.transform?Ae(sD,n.transform):Se(sD),e.transform&&Ie(sD,sD,e.transform),Xe.copy(lD,e.localRect),lD.applyTransform(sD),r?r.union(lD):Xe.copy(r=new Xe(0,0,0,0),lD))}});var u=Math.abs(a.dirVec.x)>.1?"x":"y",c=a.transGroup[u];if(s.sort(function(t,e){return Math.abs(t.label[u]-c)-Math.abs(e.label[u]-c)}),l&&r){var h=o.getExtent(),d=Math.min(h[0],h[1]),p=Math.max(h[0],h[1])-d;r.union(new Xe(d,0,p,1))}a.stOccupiedRect=r,a.labelInfoList=s}(t,n,i,l)}function vD(t){t&&(t.ignore=!0)}function yD(t,e,n,i,r){for(var o=[],a=[],s=[],l=0;l=0&&n(i,t,e.getStore())})}var p=0;if(d(function(t,e,n){r.set(e.uid,1),o&&o.hasKey(e.uid)||(i=!0),p+=n.count()}),o&&o.keys().length===r.keys().length||(i=!0),i||null==a){uC(CD,p);var f=0;d(function(t,e,n){for(var i=0,r=n.count();i0&&m0?-2:-1,n.serUids=r}else e.liPosMinGap=a}var CD=uC({ctor:sC},50);function DD(t){return function(e,n){var i=bM(e,{fromStat:{key:t}});if(ca(i.w2))return[-i.w2/2,i.w2/2]}}function AD(t){return t+rS}function kD(t,e){return t+rS+e}function LD(t){return ID(),{liPosMinGap:!vw(t.scale)}}var PD="bar",OD="pictorialBar";function RD(t,e,n,i){xS(t,{key:e,seriesType:n,coordSysType:i,getMetrics:LD})}function ND(t){var e=t.scale.rawExtentInfo.makeRenderInfo().startValue;return e}var ED={left:0,right:0,top:0,bottom:0},zD=["25%","25%"],BD="cartesian2d",VD=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.mergeDefaultAndTheme=function(e,n){var i=og(e.outerBounds);t.prototype.mergeDefaultAndTheme.apply(this,arguments),i&&e.outerBounds&&rg(e.outerBounds,i)},e.prototype.mergeOption=function(e,n){t.prototype.mergeOption.apply(this,arguments),this.option.outerBounds&&e.outerBounds&&rg(this.option.outerBounds,e.outerBounds)},e.type="grid",e.dependencies=["xAxis","yAxis"],e.layoutMode="box",e.defaultOption={show:!1,z:0,left:"15%",top:65,right:"10%",bottom:80,containLabel:!1,outerBoundsMode:"auto",outerBounds:ED,outerBoundsContain:"all",outerBoundsClampWidth:zD[0],outerBoundsClampHeight:zD[1],backgroundColor:ug.color.transparent,borderWidth:1,borderColor:ug.color.neutral30},e}(lg),GD=Ja(),FD="__ec_stack_";function HD(t){return t.get("stack")||FD+t.seriesIndex}function WD(t,e){var n=function(t,e){var n=kD(e,BD),i=[],r=bM(t,{fromStat:{key:n},min:1});return hS(t,n,function(t){i.push({barWidth:Vo(t.get("barWidth"),r.w),barMaxWidth:Vo(t.get("barMaxWidth"),r.w),barMinWidth:Vo(t.get("barMinWidth")||(ZD(t)?.5:1),r.w),barGap:t.get("barGap"),barCategoryGap:t.get("barCategoryGap"),defaultBarGap:t.get("defaultBarGap"),stackId:HD(t)})}),{bandWidthResult:r,seriesInfo:i}}(t,e);return n.columnMap=UD(n),n}function UD(t){var e,n,i=t.bandWidthResult.w,r=i,o=0,a=[],s={};B(t.seriesInfo,function(t,i){i||(n=t.defaultBarGap||0);var l=t.stackId;wt(s,l)||o++;var u=s[l];u||(u=s[l]={width:0,maxWidth:0},a.push(l));var c=t.barWidth;c&&!u.width&&(u.width=c,c=Co(r,c),r-=c);var h=t.barMaxWidth;h&&(u.maxWidth=h);var d=t.barMinWidth;d&&(u.minWidth=d);var p=t.barGap;null!=p&&(n=p);var f=t.barCategoryGap;null!=f&&(e=f)}),null==e&&(e=Do(35-4*a.length,15)+"%");var l=Vo(e,i),u=Vo(n,1),c=(r-l)/(o+(o-1)*u);c=Do(c,0),B(a,function(t){var e=s[t],n=e.maxWidth,i=e.minWidth;if(e.width){a=e.width;n&&(a=Co(a,n)),i&&(a=Do(a,i)),e.width=a,r-=a+u*a,o--}else{var a=c;n&&na&&(a=i),a!==c&&(e.width=a,r-=a+u*a,o--)}}),c=Do(c=(r-l)/(o+(o-1)*u),0);var h,d=0;B(a,function(t){var e=s[t];e.width||(e.width=c),h=e,d+=e.width*(1+u)}),h&&(d-=h.width*u);var p={},f=-d/2;return B(a,function(t){var e=s[t];p[t]=p[t]||{bandWidth:i,offset:f,width:e.width},f+=e.width*(1+u)}),p}function YD(t){return{seriesType:t,overallReset:function(e){var n=kD(t,BD);pS(e,n,function(e){var i=WD(e,t);hS(e,n,function(t){var e=i.columnMap[HD(t)];t.getData().setLayout({bandWidth:e.bandWidth,offset:e.offset,size:e.width})})})}}}function XD(t){return{seriesType:t,plan:$y(),reset:function(t){if(function(t){return t.coordinateSystem&&"cartesian2d"===t.coordinateSystem.type}(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"),c=qb(e,l)&&!!e.getCalculationInfo("stackedOnSeries"),h=r.isHorizontal(),d=r.toGlobalCoord(r.dataToCoord(ND(r))),p=ZD(t),f=t.get("barMinHeight")||0,g=u&&e.getDimensionIndex(u),v=e.getLayout("size"),y=e.getLayout("offset");return{progress:function(t,e){for(var i,r=t.count,l=p&&lC(3*r),u=p&&s&&lC(3*r),m=p&&lC(r),x=n.master.getRect(),_=h?x.width:x.height,b=e.getStore(),w=0;null!=(i=t.next());){var S=b.get(c?g:o,i),M=b.get(a,i),I=d,T=void 0;c&&(T=+S-b.get(o,i));var C=void 0,D=void 0,A=void 0,k=void 0;if(h){var L=n.dataToPoint([S,M]);c&&(I=n.dataToPoint([T,M])[0]),C=I,D=L[1]+y,A=L[0]-I,k=v,Ao(A)s){c=(p+u)/2;break}1===d&&(h=f-i[0].tickValue)}null==c&&(u?u&&(c=i[i.length-1].coord):c=i[0].coord),o[n]=t.toGlobalCoord(c)}});else{var a=this.getData(),s=a.getLayout("offset"),l=a.getLayout("size"),u=i.getBaseAxis().isHorizontal()?0:1;o[u]+=s+l/2}return o}return[NaN,NaN]},e.prototype.__requireStartValue=function(t){return this.getBaseAxis()!==t},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",defaultBarGap:"10%"},e}(Hy);Hy.registerClass(qD);var KD=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 $b(null,this,{useEncodeDefaulter:!0,createInvertedIndices:!!this.get("realtimeSort",!0)||null})},e.prototype.getProgressive=function(){return!!this.get("large")&&this.get("progressive")},e.prototype.__preparePipelineContext=function(t,e){var n=rs(this,t,e);return n.progressiveRender&&(n.large=!0),n},e.prototype.brushSelector=function(t,e,n){return n.rect(e.getItemLayout(t))},e.type="series."+PD,e.dependencies=["grid","polar"],e.defaultOption=Op(qD.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:ug.color.primary,borderWidth:2}},realtimeSort:!1}),e}(qD),$D=function(){this.cx=0,this.cy=0,this.r0=0,this.r=0,this.startAngle=0,this.endAngle=2*Math.PI,this.clockwise=!0},JD=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 $D},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,c=e.clockwise,h=2*Math.PI,d=c?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){ud(e,t,Iu(e).dataIndex)})):e.removeAll(),this._data=null,this._isFirstFrame=!0},e.prototype._removeBackground=function(){this.group.remove(this._backgroundGroup),this._backgroundGroup=null},e.type=PD,e}(tm),oA={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=nA(e.x,t.x),s=iA(e.x+e.width,r),l=nA(e.y,t.y),u=iA(e.y+e.height,o),c=sr?s:a,e.y=h&&l>o?u:l,e.width=c?0:s-a,e.height=h?0:u-l,n<0&&(e.x+=e.width,e.width=-e.width),i<0&&(e.y+=e.height,e.height=-e.height),c||h},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=iA(e.r,t.r),o=nA(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}},aA={cartesian2d:function(t,e,n,i,r,o,a,s,l){var u=new lu({shape:k({},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?JD:Sh,c=new u({shape:i,z2:1});c.name="item";var h,d,p=pA(r);if(c.calculateTextPosition=(h=p,d=({isRoundCap:u===JD}||{}).isRoundCap,function(t,e,n){var i=e.position;if(!i||i instanceof Array)return to(t,e,n);var r=h(i),o=null!=e.distance?e.distance:5,a=this.shape,s=a.cx,l=a.cy,u=a.r,c=a.r0,p=(u+c)/2,f=a.startAngle,g=a.endAngle,v=(f+g)/2,y=d?Math.abs(u-c)/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+(c-o)*m(v),b=l+(c-o)*x(v),w="center",S="top";break;case"insideStartArc":_=s+(c+o)*m(v),b=l+(c+o)*x(v),w="center",S="bottom";break;case"startAngle":_=s+p*m(f)+QD(f,o+y,!1),b=l+p*x(f)+tA(f,o+y,!1),w="right",S="middle";break;case"insideStartAngle":_=s+p*m(f)+QD(f,-o+y,!1),b=l+p*x(f)+tA(f,-o+y,!1),w="left",S="middle";break;case"middle":_=s+p*m(v),b=l+p*x(v),w="center",S="middle";break;case"endArc":_=s+(u+o)*m(v),b=l+(u+o)*x(v),w="center",S="bottom";break;case"insideEndArc":_=s+(u-o)*m(v),b=l+(u-o)*x(v),w="center",S="top";break;case"endAngle":_=s+p*m(g)+QD(g,o+y,!0),b=l+p*x(g)+tA(g,o+y,!0),w="left",S="middle";break;case"insideEndAngle":_=s+p*m(g)+QD(g,-o+y,!0),b=l+p*x(g)+tA(g,-o+y,!0),w="right",S="middle";break;default:return to(t,e,n)}return(t=t||{}).x=_,t.y=b,t.align=w,t.verticalAlign=S,t}),o){var f=r?"r":"endAngle",g={};c.shape[f]=r?i.r0:i.startAngle,g[f]=i[f],(s?rd:od)(c,{shape:g},o)}return c}};function sA(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?rd:od)(n,{shape:l},e,r,null),(a?rd:od)(n,{shape:u},e?t.baseAxis.model:null,r)}function lA(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 pA(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 fA(t,e,n,i,r,o,a,s){var l=e.getItemVisual(n,"style");if(s){if(!o.get("roundCap")){var u=t.shape;k(u,eA(i.getModel("itemStyle"),u,!0)),t.setShape(u)}}else{var c=i.get(["itemStyle","borderRadius"])||0;t.setShape("r",c)}t.useStyle(l);var h=i.getShallow("cursor");h&&t.attr("cursor",h);var d=s?a?r.r>=r.r0?"endArc":"startArc":r.endAngle>=r.startAngle?"endAngle":"startAngle":a?function(t,e){if(0===t.height){return e.getOtherAxis(e.getBaseAxis()).inverse?"bottom":"top"}return t.height>0?"bottom":"top"}(r,o.coordinateSystem):function(t,e){if(0===t.width){return e.getOtherAxis(e.getBaseAxis()).inverse?"left":"right"}return t.width>=0?"right":"left"}(r,o.coordinateSystem),p=ap(i);op(t,p,{labelFetcher:o,labelDataIndex:n,defaultText:jT(o.getData(),n),inheritColor:l.fill,defaultOpacity:l.opacity,defaultOutsidePosition:d});var f=t.getTextContent();if(s&&f){var g=i.get(["label","position"]);t.textConfig.inside="middle"===g||null,function(t,e,n,i){if(K(i))t.setTextConfig({rotation:i});else if(X(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 c=1.5*Math.PI-r;"middle"===u&&c>Math.PI/2&&c<1.5*Math.PI&&(c-=Math.PI),t.setTextConfig({rotation:c})}}(t,"outside"===g?d:g,pA(a),i.get(["label","rotate"]))}gp(f,p,o.getRawValue(n),function(t){return qT(e,t)});var v=i.getModel(["emphasis"]);kc(t,v.get("focus"),v.get("blurScope"),v.get("disabled")),Rc(t,i),function(t){return null!=t.startAngle&&null!=t.endAngle&&t.startAngle===t.endAngle}(r)&&(t.style.fill="none",t.style.stroke="none",B(t.states,function(t){t.style&&(t.style.fill=t.style.stroke="none")}))}var gA=function(){},vA=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 gA},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[c]}return-1}(this,t.offsetX,t.offsetY);Iu(this).dataIndex=e>=0?e:null},30,!1);function xA(t,e,n){if(wC(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}}function _A(t){return{seriesType:t,reset:function(t,e){var n=e.findComponents({mainType:"legend"});if(n&&n.length){var i=t.getData();i.filterSelf(function(t){for(var e=i.getName(t),r=0;r=0},t.prototype.indexOfName=function(t){return this._getDataWithEncodedVisual().indexOfName(t)},t.prototype.getItemVisual=function(t,e){return this._getDataWithEncodedVisual().getItemVisual(t,e)},t}(),MA="pie",IA=Pa(),TA=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 SA(U(this.getData,this),U(this.getRawData,this)),this._defaultLabelLine(e)},e.prototype.mergeOption=function(){t.prototype.mergeOption.apply(this,arguments)},e.prototype.getInitialData=function(){return bA(this,{coordDimensions:["value"],encodeDefaulter:Y(Sg,this)})},e.prototype.getDataParams=function(e){var n=this.getData(),i=IA(n),r=i.seats;if(!r){var o=[];n.each(n.mapDimension("value"),function(t){o.push(t)}),r=i.seats=Zo(o,n.hostModel.get("percentPrecision"))}var a=t.prototype.getDataParams.call(this,e);return a.percent=r[e]||0,a.$vars.push("percent"),a},e.prototype._defaultLabelLine=function(t){ba(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."+MA,e.defaultOption={z:2,legendHoverLink:!0,colorBy:"data",center:["50%","50%"],radius:[0,"50%"],clockwise:!0,startAngle:90,endAngle:"auto",padAngle:0,minAngle:0,minShowLabelAngle:0,selectedOffset:10,percentPrecision:2,stillShowZeroSum:!0,coordinateSystemUsage:"box",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%",distanceToLabelLine:5},labelLine:{show:!0,length:15,length2:30,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}(Hy);wA={fullType:TA.type,getCoord2:function(t){return t.getShallow("center")}},Gf.set(wA.fullType,{getCoord2:void 0}).getCoord2=wA.getCoord2;var CA=Math.PI/180;function DA(t,e,n,i,r,o,a,s,l,u){if(!(t.length<2)){for(var c=t.length,h=0;hn?a:o,c=Math.abs(l.label.y-n);if(c>=u.maxY){var h=l.label.x-e-l.len2*r,d=i+l.len,f=Math.abs(h)t.unconstrainedWidth?null:d:null;i.setStyle("width",p)}kA(o,i)}}}function kA(t,e){PA.rect=t,QM(PA,e,LA)}var LA={minMarginForce:[null,0,null,0],marginDefault:[1,0,1,0]},PA={};function OA(t){return"center"===t.position}function RA(t){var e,n,i=t.getData(),r=[],o=!1,a=(t.get("minShowLabelAngle")||0)*CA,s=i.getLayout("viewRect"),l=i.getLayout("r"),u=s.width,c=s.x,h=s.y,d=s.height;function p(t){t.ignore=!0}i.each(function(t){var s=i.getItemGraphicEl(t),h=s.shape,f=s.getTextContent(),g=s.getTextGuideLine(),v=i.getItemModel(t),y=v.getModel("label"),m=y.get("position")||v.get(["emphasis","label","position"]),x=y.get("distanceToLabelLine"),_=y.get("alignTo"),b=Vo(y.get("edgeDistance"),u),w=y.get("bleedMargin");null==w&&(w=Math.min(u,d)>200?10:2);var S=v.getModel("labelLine"),M=S.get("length");M=Vo(M,u);var I=S.get("length2");if(I=Vo(I,u),Math.abs(h.endAngle-h.startAngle)0?"right":"left":L>0?"left":"right"}var G=Math.PI,F=0,H=y.get("rotate");if(K(H))F=H*(G/180);else if("center"===m)F=0;else if("radial"===H||!0===H){F=L<0?-k+G:-k}else if("tangential"===H||"tangential-noflip"===H&&"outside"!==m&&"outer"!==m){var W=Math.atan2(L,P);W<0&&(W=2*G+W),P>0&&"tangential-noflip"!==H&&(W=G+W),F=W-G}if(o=!!F,f.x=T,f.y=C,f.rotation=F,f.setStyle({verticalAlign:"middle"}),O){f.setStyle({align:A});var U=f.states.select;U&&(U.x+=f.x,U.y+=f.y)}else{var Y=new Xe(0,0,0,0);kA(Y,f),r.push({label:f,labelLine:g,position:m,len:M,len2:I,minTurnAngle:S.get("minTurnAngle"),maxSurfaceAngle:S.get("maxSurfaceAngle"),surfaceNormal:new Pe(L,P),linePoints:D,textAlign:A,labelDistance:x,labelAlignTo:_,edgeDistance:b,bleedMargin:w,rect:Y,unconstrainedWidth:Y.width,labelStyleWidth:f.style.width})}s.setTextConfig({inside:O})}}),!o&&t.get("avoidLabelOverlap")&&function(t,e,n,i,r,o,a,s){for(var l=[],u=[],c=Number.MAX_VALUE,h=-Number.MAX_VALUE,d=0;di?c=u=D+b*i/2:(u=D+S,c=r-S),n.setItemLayout(e,{angle:i,startAngle:u,endAngle:c,clockwise:y,cx:o,cy:a,r0:l,r:m?Bo(t,_,[l,s]):s}),D=r}}),T0){for(var l=o.getItemLayout(0),u=1;isNaN(l&&l.startAngle)&&u=n.r0}},e.type=MA,e}(tm);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.getInitialData=function(t,e){return $b(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","matrix"],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:ug.color.primary}},universalTransition:{divideShape:"clone"}},e}(Hy),HA=function(){},WA=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 HA},e.prototype.reset=function(){this.notClear=!1,this._off=0},e.prototype.beforeBrush=function(t){t&&!t.contentRetained&&this.reset()},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,c=i[l+1]-a/2;if(t>=u&&e>=c&&t<=u+o&&e<=c+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,c=0;c=0&&(l.dataIndex=n+(t.startIndex||0))})},t.prototype.remove=function(){this._clear()},t.prototype._clear=function(){this._newAdded=[],this.group.removeAll()},t}(),YA=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,XA(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(),is(e),XA(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)return{update:!0};var r=GC("").reset(t,e,n);r.progress&&r.progress({start:0,end:i.count(),count:i.count()},i),this._symbolDraw.updateLayout(XA(t))},e.prototype.eachRendered=function(t){this._symbolDraw&&this._symbolDraw.eachRendered(t)},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 UA:new nC,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}(tm);function XA(t){return{clipShape:bC(t)}}var ZA=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.getCoordSysModel=function(){return this.getReferringComponents("grid",Ea).models[0]},e.type="cartesian2dAxis",e}(lg);E(ZA,nS);var jA={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:"auto",onZeroAxisIndex:null,lineStyle:{color:ug.color.axisLine,width:1,type:"solid"},symbol:["none","none"],symbolSize:[10,15],breakLine:!0},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,color:ug.color.axisLabel,textMargin:[0,3]},splitLine:{show:!0,showMinLine:!0,showMaxLine:!0,lineStyle:{color:ug.color.axisSplitLine,width:1,type:"solid"}},splitArea:{show:!1,areaStyle:{color:[ug.color.backgroundTint,ug.color.backgroundTransparent]}},breakArea:{show:!0,itemStyle:{color:ug.color.neutral00,borderColor:ug.color.border,borderWidth:1,borderType:[3,3],opacity:.6},zigzagAmplitude:4,zigzagMinSpan:4,zigzagMaxSpan:20,zigzagZ:100,expandOnClick:!0},breakLabelLayout:{moveOverlap:"auto"}},qA=D({boundaryGap:!0,deduplication:null,jitter:0,jitterOverlap:!0,jitterMargin:2,splitLine:{show:!1},axisTick:{alignWithLabel:!1,interval:"auto",show:"auto"},axisLabel:{interval:"auto"}},jA),KA=D({boundaryGap:[0,0],axisLine:{show:"auto"},axisTick:{show:"auto"},splitNumber:5,minorTick:{show:!1,splitNumber:5,length:3,lineStyle:{}},minorSplitLine:{show:!1,lineStyle:{color:ug.color.axisMinorSplitLine,width:1}}},jA),$A={category:qA,value:KA,time:D({splitNumber:6,axisLabel:{rich:{primary:{fontWeight:"bold"}}},splitLine:{show:!1}},KA),log:P({logBase:10},KA)};function JA(t,e,i,r){B(Gw,function(o,a){var s=D(D({},$A[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=ig(this),i=n?og(t):{};D(t,e.getTheme().get(a+"Axis")),D(t,this.getDefaultOption()),t.type=QA(t),n&&rg(t,i,n)},i.prototype.optionUpdated=function(){"category"===this.option.type&&(this.__ordinalMeta=tw.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.prototype.updateAxisBreaks=function(t){var e=XC();return e?e.updateModelAxisBreak(this,t):{breaks:[]}},i.type=e+"Axis."+a,i.defaultOption=s,i}(i);t.registerComponentModel(l)}),t.registerSubTypeDefaulter(e+"Axis",QA)}function QA(t){return t.type||(t.data?"category":"value")}var tk=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 V(this._dimList,function(t){return this._axes[t]},this)},t.prototype.getAxesByScale=function(t){return t=t.toLowerCase(),F(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}(),ek=["x","y"];function nk(t){return("interval"===t.type||"time"===t.type)&&!Xp(t)}var ik=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.type=BD,e.dimensions=ek,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(nk(t)&&nk(e)){var n=sw(t,null),i=sw(e,null),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,c=r[0]-n[0]*l,h=r[1]-i[0]*u,d=this._transform=[l,0,0,u,c,h];this._invTransform=Ae([],d)}}},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 Xe(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 Yt(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,n){if(n=n||[],this._invTransform)return Yt(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(t){t=t||0;var e=this.getAxis("x").getGlobalExtent(),n=this.getAxis("y").getGlobalExtent(),i=Math.min(e[0],e[1])-t,r=Math.min(n[0],n[1])-t,o=Math.max(e[0],e[1])-i+t,a=Math.max(n[0],n[1])-r+t;return new Xe(i,r,o,a)},e}(tk);function rk(t,e){var n=t.scale,i=t.model;var r,o,a,s=LS(n,i,i.ecModel,t,null),l=gw(n),u=gw(e)?e.intervalStub:e,c=l?n.intervalStub:n,h=n.base,d=u.getTicks(),p=u.getTicks({expandToNicedExtent:!0}),f=d.length-1;if(1===f)r=o=0,a=1;else if(2===f){var g=Ao(d[0].value-d[1].value),v=Ao(d[1].value-d[2].value);r=o=0,g===v?a=2:(a=1,g=A[1])return!0})):T[1]?(x=A[1],k(function(){if(R(),S=Ho(w-_*a,b),L(),m<=A[0])return!0})):k(function(){S=Ho(Po(A[0]/_)*_,b),w=Ho(Lo(A[1]/_)*_,b);var t=ko((w-S)/_);if(t<=a){var e=a-t,n=void 0,i=s.incl0||l;if(i&&0===A[0])n=[0,e];else if(i&&0===A[1])n=[e,0];else{var r=Lo(e/2);n=e%2==0?[r,r]:m+x=A[1])return!0}})}Qw(n,T,D,[m,x],C,{interval:_,intervalCount:a,intervalPrecision:b,niceExtent:[S,w]})}var ok,ak=[[3,1],[0,2]],sk=function(){function t(t,e,n){this.type="grid",this._coordsMap={},this._coordsList=[],this._axesMap={},this._axesList=[],this.axisPointerEnabled=!0,this.dimensions=ek,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){for(var e=W(t),n=[],i=e.length-1;i>=0;i--){var r=t[+e[i]];r.__alignTo?n.push(r):RS(r)}B(n,function(t){var e,n;e=t,n=t.__alignTo,Xp(e.scale)||Xp(n.scale)||n.scale.getTicks().length<2?RS(t):rk(t,t.__alignTo.scale)})}B(this._axesList,function(t){CS(t,1);var e=t.scale;vw(e)&&e.setSortInfo(t.model.get("categorySortInfo"))}),i(n.x),i(n.y);var r={};B(n.x,function(t){lk(n,"y",t,r)}),B(n.y,function(t){lk(n,"x",t,r)}),this.resize(this.model,e)},t.prototype.resize=function(t,e,n){var i=eg(t,e),r=this._rect=Jf(t.getBoxLayoutParams(),i.refContainer),o=this._axesMap,a=this._coordsList,s=t.get("containLabel");if(hk(o,r),!n){var l=function(t,e,n,i,r){var o=new aD(gk);return B(n,function(n){return B(n,function(n){if($w(n.model)){var a=!i;n.axisBuilder=function(t,e,n,i,r,o){for(var a=MD(t,n),s=!1,l=!1,u=0;ue?Uw:Xw:Xw}(e.scale,0,!1),i=e&&"category"!==e.type&&"time"!==e.type&&n!==Xw;return i&&"auto"===t&&function(t){return Fw(t).noOnMyZero}(e)&&(i=!1),i}function ck(t){for(var e,n=W(t),i=[],r=n.length-1;r>=0;r--){var o=t[+n[r]];dw(o.scale)&&null==Jw(o.model,o.type,!0)&&(o.model.get("alignTicks")&&null==o.model.get("interval")?i.push(o):e=o)}e||(e=i.pop()),e&&B(i,function(t){t.__alignTo=e})}function hk(t,e){B(t.x,function(t){return dk(t,e.x,e.width)}),B(t.y,function(t){return dk(t,e.y,e.height)})}function dk(t,e,n){var i=[0,n],r=t.inverse?1:0;t.setExtent(i[r],i[1-r]),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)}function pk(t,e,n,i,r,o,a){fk(i,r,aM,e,!1,a);var s=[0,0,0,0];u(0),u(1),c(i,0,NaN),c(i,1,NaN);var l=null==H(s,function(t){return t>0});return zd(i,s,!0,!0,n),hk(r,i),l;function u(t){B(r[dd[t]],function(e){if($w(e.model)){var n=o.ensureRecord(e.model),i=n.labelInfoList;if(i)for(var r=0;r0&&!rt(e)&&e>1e-4&&(t/=e),t}}function fk(t,e,n,i,r,o){var a=n===sM;B(e,function(e){return B(e,function(e){$w(e.model)&&(!function(t,e,n){var i=MD(e,n);t.updateCfg(i)}(e.axisBuilder,t,e.model),e.axisBuilder.build(a?{axisTickLabelDetermine:!0}:{axisTickLabelEstimate:!0},{noPxChange:r}))})});var s={x:0,y:0};function l(e){s[dd[1-e]]=t[pd[e]]<=.5*o.refContainer[pd[e]]?0:1-e==1?2:1}l(0),l(1),B(e,function(t,e){return B(t,function(t){$w(t.model)&&(("all"===i||a)&&t.axisBuilder.build({axisName:!0},{nameMarginLevel:s[e]}),a&&t.axisBuilder.build({axisLine:!0}))})})}var gk=function(t,e,n,i,r,o){var a="x"===n.axis.dim?"y":"x";uD(t,0,0,i,r,o),Kw(t.nameLocation)||B(e.recordMap[a],function(t){t&&t.labelInfoList&&t.dirVec&&hD(t.labelInfoList,t.dirVec,i,r)})};function vk(t,e){var n={axesInfo:{},seriesInvolved:!1,coordSysAxesInfo:{},coordSysMap:{}};return function(t,e,n){var i=e.getComponent("tooltip"),r=e.getComponent("axisPointer"),o=r.get("link",!0)||[],a=[];B(n.getCoordinateSystems(),function(n){if(n.axisPointerEnabled){var s=_k(n.model),l=t.coordSysAxesInfo[s]={};t.coordSysMap[s]=n;var u=n.model.getModel("tooltip",i);if(B(n.getAxes(),Y(p,!1,null)),n.getTooltipAxes&&i&&u.get("show")){var c="axis"===u.get("trigger"),h="cross"===u.get(["axisPointer","type"]),d=n.getTooltipAxes(u.get(["axisPointer","axis"]));(c||h)&&B(d.baseAxes,Y(p,!h||"cross",c)),h&&B(d.otherAxes,Y(p,"cross",!1))}}function p(i,s,c){var h=c.model.getModel("axisPointer",r),d=h.get("show");if(d&&("auto"!==d||i||xk(h))){null==s&&(s=h.get("triggerTooltip")),h=i?function(t,e,n,i,r,o){var a=e.getModel("axisPointer"),s={};B(["type","snap","lineStyle","shadowStyle","label","animation","animationDurationUpdate","animationEasingUpdate","z"],function(t){s[t]=C(a.get(t))}),s.snap="category"!==t.type&&!!o,"cross"===a.get("type")&&(s.type="line");var l=s.label||(s.label={});if(null==l.show&&(l.show=!1),"cross"===r){var u=a.get(["label","show"]);if(l.show=null==u||u,!o){var c=s.lineStyle=a.get("crossStyle");c&&P(l,c.textStyle)}}return t.model.getModel("axisPointer",new kp(s,n,i))}(c,u,r,e,i,s):h;var p=h.get("snap"),f=h.get("triggerEmphasis"),g=_k(c.model),v=s||p||"category"===c.type,y=t.axesInfo[g]={key:g,axis:c,coordSys:n,axisPointerModel:h,triggerTooltip:s,triggerEmphasis:f,involveSeries:v,snap:p,useHandle:xk(h),seriesModels:[],linkGroup:null};l[g]=y,t.seriesInvolved=t.seriesInvolved||v;var m=function(t,e){for(var n=e.model,i=e.dim,r=0;r=0||t===e}function mk(t){var e=(t.ecModel.getComponent("axisPointer")||{}).coordSysAxesInfo;return e&&e.axesInfo[_k(t)]}function xk(t){return!!t.get(["handle","show"])}function _k(t){return t.type+"||"+t.id}var bk={},wk=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(e,n,i,r){this.axisPointerClass&&function(t){var e=mk(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=xk(n);null==o&&(r.status=s?"show":"hide");var l=i.getExtent();(null==a||a>l[1])&&(a=l[1]),a0))return n;var a=r.get("jitterOverlap"),s=r.get("jitterMargin")||0,l=vw(t.scale)?bM(t).w:null;return a?Vk(n,o,l,i):function(t,e,n,i,r,o){var a=zk(t);a.items||(a.items=[]);var s=a.items,l=Gk(s,e,n,i,r,o,1),u=Gk(s,e,n,i,r,o,-1),c=Math.abs(l-n)r/2||h&&d>h/2-i)return Vk(n,r,h,i);return s.push({fixedCoord:e,floatCoord:c,r:i}),c}(t,e,n,i,o,s)}function Vk(t,e,n,i){if(null===n)return t+(Math.random()-.5)*e;var r=n-2*i,o=Math.min(Math.max(0,e),r);return t+(Math.random()-.5)*o}function Gk(t,e,n,i,r,o,a){for(var s=n,l=0;lr/2)return Number.MAX_VALUE;if(1===a&&f>s||-1===a&&f0;return a&&s}(t,n);if(i){var r=n.dim,o=n.orient,a="horizontal"===o&&"category"!==n.type||"vertical"===o&&"category"===n.type,s="y"===r||"single"===r&&a,l="x"===r||"single"===r&&!a;if(s||l)return{progress:function(t,e){var i=e.getLayout("points"),r=!!i;for(var o=t.start;o0&&!d.min?d.min=0:null!=d.min&&d.min<0&&!d.max&&(d.max=0);var p=s;null!=d.color&&(p=P({color:d.color},s));var f=D(C(d),{boundaryGap:t,splitNumber:e,clockwise:n,scale:i,axisLine:r,axisTick:o,axisLabel:a,name:d.text,showName:l,nameLocation:"end",nameGap:c,nameTextStyle:p,triggerEvent:h},!1);if(j(u)){var g=f.name;f.name=u.replace("{value}",null!=g?g:"")}else Z(u)&&(f.name=u(f.name,f));var v=new kp(f,null,this.ecModel);return E(v,nS.prototype),v.mainType="radar",v.componentIndex=this.componentIndex,v.uid=Pp("ec_radar"),v},this);this._indicatorModels=d},e.prototype.getIndicatorModels=function(){return this._indicatorModels},e.type=jk,e.defaultOption={z:0,center:["50%","50%"],radius:"50%",startAngle:90,clockwise:!1,axisName:{show:!0,color:ug.color.axisLabel},boundaryGap:[0,0],splitNumber:5,axisNameGap:15,scale:!1,shape:"polygon",axisLine:D({lineStyle:{color:ug.color.neutral20}},Xk.axisLine),axisLabel:Kk(Xk.axisLabel,!1),axisTick:Kk(Xk.axisTick,!1),splitLine:Kk(Xk.splitLine,!0),splitArea:Kk(Xk.splitArea,!0),indicator:[]},e}(lg),Jk=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,n),this._buildSplitLineAndArea(t)},e.prototype._buildAxes=function(t,e){var n=t.coordinateSystem;B(V(n.getIndicatorAxes(),function(t){var i=t.model.get("showName")?t.name:"";return new dD(t.model,e,{axisName:i,position:[n.cx,n.cy],rotation:t.angle,labelDirection:-1,tickDirection:-1,nameDirection:1})}),function(t){t.build(),this.group.add(t.group)},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"),c=a.get("color"),h=s.get("color"),d=X(c)?c:[c],p=X(h)?h:[h],f=[],g=[];if("circle"===i)for(var v=n[0].getTicksCoords(),y=e.cx,m=e.cy,x=0;x3?1.4:r>1?1.2:1.1,l=i>0?s:1/s;this._checkTriggerMoveZoom(this,"zoom","zoomOnMouseWheel",t,{scale:l,originX:o,originY:a,isAvailableBehavior:null})}if(n){var u=Math.abs(i),c=(i>0?1:-1)*(u>3?.4:u>1?.15:.05);this._checkTriggerMoveZoom(this,"scrollMove","moveOnMouseWheel",t,{scrollDelta:c,originX:o,originY:a,isAvailableBehavior:null})}}}},e.prototype._pinchHandler=function(t){if(!aL(this._zr,"globalPan")&&!cL(t)){var e=t.pinchScale>1?1.1:1/1.1;this._checkTriggerMoveZoom(this,"zoom",null,t,{scale:e,originX:t.pinchX,originY:t.pinchY,isAvailableBehavior:null})}},e.prototype._checkTriggerMoveZoom=function(t,e,n,i,r){t._checkPointer(i,r.originX,r.originY)&&(ye(i.event),i.__ecRoamConsumed=!0,yL(t,e,n,i,r))},e}($t);function cL(t){return t.__ecRoamConsumed}var hL,dL=Pa();function pL(t){var e=dL(t);return e.roam=e.roam||{},e.uniform=e.uniform||{},e}function fL(t,e,n,i){for(var r=pL(t).roam,o=r[e]=r[e]||[],a=0;a=4&&(l={x:parseFloat(h[0]||0),y:parseFloat(h[1]||0),width:parseFloat(h[2]),height:parseFloat(h[3])})}if(l&&null!=a&&null!=s&&(u=VL(l,{x:0,y:0,width:a,height:s}),!e.ignoreViewBox)){var d=i;(i=new vo).add(d),d.scaleX=d.scaleY=u.scale,d.x=u.x,d.y=u.y}return e.ignoreRootClip||null==a||null==s||i.setClipPath(new lu({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=hL[s];if(u&&wt(hL,s)){a=u.call(this,t,e);var c=t.getAttribute("name");if(c){var h={name:c,namedFrom:null,svgNodeTagLower:s,el:a};n.push(h),"g"===s&&(l=h)}else i&&n.push({name:i.name,namedFrom:i,svgNodeTagLower:s,el:a});e.add(a)}}var d=IL[s];if(d&&wt(IL,s)){var p=d.call(this,t),f=t.getAttribute("id");f&&(this._defs[f]=p)}}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 Jl({style:{text:t.textContent},silent:!0,x:this._textX||0,y:this._textY||0});DL(e,n),kL(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(hL={g:function(t,e){var n=new vo;return DL(e,n),kL(t,n,this._defsUsePending,!1,!1),n},rect:function(t,e){var n=new lu;return DL(e,n),kL(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 ah;return DL(e,n),kL(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 Oh;return DL(e,n),kL(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 lh;return DL(e,n),kL(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=AL(i));var r=new Dh({shape:{points:n||[]},silent:!0});return DL(e,r),kL(t,r,this._defsUsePending,!1,!1),r},polyline:function(t,e){var n,i=t.getAttribute("points");i&&(n=AL(i));var r=new kh({shape:{points:n||[]},silent:!0});return DL(e,r),kL(t,r,this._defsUsePending,!1,!1),r},image:function(t,e){var n=new eu;return DL(e,n),kL(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 vo;return DL(e,a),kL(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 vo;return DL(e,a),kL(t,a,this._defsUsePending,!1,!0),this._textX+=parseFloat(r),this._textY+=parseFloat(o),a},path:function(t,e){var n=ih(t.getAttribute("d")||"");return DL(e,n),kL(t,n,this._defsUsePending,!1,!1),n.silent=!0,n}}),t}(),IL={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 Hh(e,n,i,r);return TL(t,o),CL(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 Wh(e,n,i);return TL(t,r),CL(t,r),r}};function TL(t,e){"userSpaceOnUse"===t.getAttribute("gradientUnits")&&(e.global=!0)}function CL(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={};BL(n,o,o);var a=o.stopColor||n.getAttribute("stop-color")||"#000000",s=o.stopOpacity||n.getAttribute("stop-opacity");if(s){var l=gi(a);l&&l[3]&&(l[3]*=si(s),a=Mi(l,"rgba"))}e.colorStops.push({offset:r,color:a})}n=n.nextSibling}}function DL(t,e){t&&t.__inheritedStyle&&(e.__inheritedStyle||(e.__inheritedStyle={}),P(e.__inheritedStyle,t.__inheritedStyle))}function AL(t){for(var e=RL(t),n=[],i=0;i0;o-=2){var a=i[o],s=i[o-1],l=RL(a);switch(r=r||we(),s){case"translate":Te(r,r,[parseFloat(l[0]),parseFloat(l[1]||"0")]);break;case"scale":De(r,r,[parseFloat(l[0]),parseFloat(l[1]||l[0])]);break;case"rotate":Ce(r,r,-parseFloat(l[0])*EL,[parseFloat(l[1]||"0"),parseFloat(l[2]||"0")]);break;case"skewX":Ie(r,[1,0,Math.tan(parseFloat(l[0])*EL),1,0,0],r);break;case"skewY":Ie(r,[1,Math.tan(parseFloat(l[0])*EL),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),BL(t,a,s),i||function(t,e,n){for(var i=0;i1e-6;zP[0]=a?(r[0]-i.x)/o:r[0],zP[1]=a?(r[1]-i.y)/o:r[1],Yt(zP,zP,t.mtRawInv);var s=function(t,e){var n=t.centerOption,i=t.dataRect;0;return!n||t.lgCt?e.slice():[NP(0,e,n,i),NP(1,e,n,i)]}(t,zP);BP(e,s,o),B(n,function(t){t!==e&&BP(t,s.slice(),o)})}(r,e,n,AP)}var AP=Vr(),kP=Vr();function LP(t,e,n){var i=PP(e);i&&(DP(i,e,n,t),dP(i,e))}function PP(t){return t.__ownRoamView?t.__ownRoamView():null}function OP(t,e,n,i){n.setUpdatePayload($d(t));var r=Fu(i,e);r&&r.__updateOnOwnRoam&&r.__updateOnOwnRoam(t,e,i)}function RP(t){return t.scaleX}function NP(t,e,n,i){return n&&i&&i[pd[t]]&&(j(r=n[t])&&Fo(r))?(e[t]-i[dd[t]])/i[pd[t]]*100+"%":e[t];var r}function EP(t,e){return e&&t&&t.getShallow("legacyViewCoordSysCenterBase")?{w:e.getWidth(),h:e.getHeight()}:null}var zP=[];function BP(t,e,n){var i=t.option;i.center=e,i.zoom=n}function VP(t,e){if(e){var n=e.min||0,i=e.max||1/0;t=Math.max(Math.min(i,t),n)}return t}function GP(t,e){var n=e.getShallow("nodeScaleRatio",!0)||1,i=t;return((i.zoom-1)*n+1)/(i.trans[2].scaleX||1)}function FP(t,e,n,i,r,o,a,s){function l(n){var i=t.mainType,r=$d(P({type:YP(i,t.subType,Bu)},n));s&&(r.componentType=i),r[i+"Id"]=t.id,e.dispatchAction(r)}PP(t)?(n.enable(at(t.get("roam"),a),{api:e,zInfo:{component:t},triggerInfo:{roamTrigger:t.get("roamTrigger"),isInSelf:i,isInClip:function(t,e,n){return!r||r.contain(e,n)}}}),n.off("pan").off("zoom").on("pan",function(t){o&&o("pan"),l({dx:t.dx,dy:t.dy})}).on("zoom",function(t){o&&o("zoom"),l({zoom:t.scale,originX:t.originX,originY:t.originY})})):n.disable()}function HP(t){return function(e,n,i){return WP.copy(t.getBoundingRect()),WP.applyTransform(t.getComputedTransform()),WP.contain(n,i)}}var WP=new Xe(0,0,0,0);function UP(t,e,n){var i=YP(e,n,Bu);t.registerAction({type:i,event:i,update:"none"},function(t,i,r){i.eachComponent(Va(t,e,n),function(e){LP(t,e),OP(t,e,i,r)})})}function YP(t,e,n){return(t!==Du?t:"map"===e?"geo":e)+n}function XP(t){return null!=t.zoom}function ZP(t,e,n,i,r,o,a){var s=new nP(null,EP(t.ecModel,e));return pP(s,n,i,r,o),a?fP(s,a.x,a.y,a.width,a.height):fP(s,n,i,r,o),dP(s,t),s}var jP=["rect","circle","line","ellipse","polygon","polyline","path"],qP=mt(jP),KP=mt(jP.concat(["g"])),$P=mt(jP.concat(["g"])),JP=Pa();function QP(t){var e=t.getItemStyle(),n=t.get("areaColor");return null!=n&&(e.fill=n),e}function tO(t){var e=t.style;e&&(e.stroke=e.stroke||e.fill,e.fill=null)}var eO=function(){function t(t){var e=this.group=new vo,n=this._transformGroup=new vo;e.add(n),this.uid=Pp("ec_map_draw"),this._controller=new uL(t.getZr()),n.add(this._regionsGroup=new vo),n.add(this._svgGroup=new vo)}return t.prototype.draw=function(t,e,n,i,r){var o=this,a=t.getData&&t.getData();lO(t)&&e.eachComponent({mainType:"series",subType:"map"},function(e){a||e.getHostGeoModel()!==t||(a=e.getData())});var s,l=t.coordinateSystem,u=l.view,c=this._regionsGroup,h=this._transformGroup,d=!c.childAt(0)||r;l.shouldClip()?(s=sP(null,u),this.group.setClipPath(new lu({shape:s.clone()}))):this.group.removeClipPath(),CP(h,1,u,d?null:t);var p=a&&a.getVisual("visualMeta")&&a.getVisual("visualMeta").length>0;"geoJSON"===l.resourceType?this._buildGeoJSON(u,n,l,t,a,p):"geoSVG"===l.resourceType&&this._buildSVG(u,n,l,t,a,p),FP(t,n,this._controller,function(e,n,i){return t.coordinateSystem.containPoint([n,i])},s,function(){o._mouseDownFlag=!1},!1,!0),this._updateMapSelectHandler(t,c,n,i)},t.prototype.__updateOnOwnRoam=function(t){CP(this._transformGroup,1,t.coordinateSystem.view,null)},t.prototype._buildGeoJSON=function(t,e,n,i,r,o){var a=this._regionsGroupByName=mt(),s=mt(),l=this._regionsGroup,u=n.projection,c=u&&u.stream,h=Br(lP(null,t,0));function d(t,e){return e&&(t=e(t)),t&&Yt([],t,h)}function p(t){for(var e=[],n=!c&&u&&u.project,i=0;i=0)&&(c=t);var h=a?{normal:{align:"center",verticalAlign:"middle"}}:null;op(n,ap(r),{labelFetcher:c,labelDataIndex:u,defaultText:i},h);var d=n.getTextContent();if(d&&(JP(d).ignore=d.ignore,n.textConfig&&a)){var p=n.getBoundingRect().clone();n.textConfig.layoutRect=p,n.textConfig.position=[(a[0]-p.x)/p.width*100+"%",(a[1]-p.y)/p.height*100+"%"]}n.disableLabelAnimation=!0}else n.removeTextContent(),n.removeTextConfig(),n.disableLabelAnimation=null}function rO(t,e,n,i,r,o){e?e.setItemGraphicEl(o,n):Iu(n).eventData={componentType:"geo",componentIndex:t.componentIndex,geoIndex:t.componentIndex,name:i,region:r&&r.option||{}}}function oO(t,e,n,i,r){e||Gd({el:n,componentModel:t,itemName:i,itemTooltipOption:r.get("tooltip")})}function aO(t,e,n,i){e.highDownSilentOnTouch=!!t.get("selectedMode");var r=i.getModel("emphasis"),o=r.get("focus");return kc(e,o,r.get("blurScope"),r.get("disabled")),lO(t)&&function(t,e,n){var i=Iu(t);i.componentMainType=e.mainType,i.componentIndex=e.componentIndex,i.componentHighDownName=n}(e,t,n),o}function sO(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(),B(t,function(t){s.lineStart();for(var e=0;e-1&&(n.style.stroke=n.style.fill,n.style.fill=ug.color.neutral00,n.style.lineWidth=2),n},e.prototype.__ownRoamView=function(){return dO(this)?this.coordinateSystem.view:null},e.type="series."+uO,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:ug.color.tertiary},itemStyle:{borderWidth:.5,borderColor:ug.color.border,areaColor:ug.color.background},emphasis:{label:{show:!0,color:ug.color.primary},itemStyle:{areaColor:ug.color.highlight}},select:{label:{show:!0,color:ug.color.primary},itemStyle:{color:ug.color.highlight}},nameProperty:"name"},e}(Hy);function hO(t){return 0===t.indexOf("i")}function dO(t){return pO(t.seriesGroup)===t&&!t.getHostGeoModel()}function pO(t){return t.f[0]}function fO(t,e){var n={};return t.eachRawSeriesByType(uO,function(i){var r=i.getHostGeoModel(),o=r?"o"+r.id:"i"+i.getMapType(),a=n[o]=n[o]||{f:[],r:[]};t.isSeriesFiltered(i)||e||a.f.push(i),a.r.push(i)}),n}var gO=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.type=uO,e}return n(e,t),e.prototype.render=function(t,e,n,i){if(!i||"mapToggleSelect"!==i.type||i.from!==this.uid){var r=this.group;if(r.removeAll(),!t.getHostGeoModel()){var o=this._mapDraw;o&&i&&"geoRoam"===i.type&&o.resetForLabelLayout(),i&&"geoRoam"===i.type&&"series"===i.componentType&&i.seriesId===t.id?o&&r.add(o.group):dO(t)?(o=o||(this._mapDraw=new eO(n)),r.add(o.group),o.draw(t,e,n,this,i)):this._clearMapDraw(),t.get("showLegendSymbol")&&e.getComponent("legend")&&this._renderSymbols(t)}}},e.prototype.__updateOnOwnRoam=function(t,e,n){var i=this._mapDraw;dO(e)&&i&&i.__updateOnOwnRoam(e)},e.prototype.remove=function(){this._clearMapDraw(),this.group.removeAll()},e.prototype.dispose=function(){this._clearMapDraw()},e.prototype._clearMapDraw=function(){this._mapDraw&&this._mapDraw.remove(),this._mapDraw=null},e.prototype._renderSymbols=function(t){var e=t.originalData,n=this.group;e.each(e.mapDimension("value"),function(i,r){if(!isNaN(i)){var o=e.getItemLayout(r);if(o&&o.point){var a=o.point,s=o.offset,l=new ah({style:{fill:t.getData().getVisual("style").fill},shape:{cx:a[0]+9*s,cy:a[1],r:3},silent:!0,z2:8+(s?0:11)});if(!s){var u=pO(t.seriesGroup).getData(),c=e.getName(r),h=u.indexOfName(c),d=e.getItemModel(r),p=d.getModel("label"),f=u.getItemGraphicEl(h);op(l,ap(d),{labelFetcher:{getFormattedLabel:function(e,n){return t.getFormattedLabel(h,n)}},defaultText:c}),l.disableLabelAnimation=!0,p.get("position")||l.setTextConfig({position:"bottom"}),f.onHoverStateChange=function(t){hc(l,t)}}n.add(l)}}})},e.type=uO,e}(tm),vO={geoJSON:{aspectScale:.75,invertLongitute:!0},geoSVG:{aspectScale:1,invertLongitute:!1}},yO=["lng","lat"],mO=function(t){function e(e,n,i){var r=t.call(this)||this;r.dimensions=yO,r.type="geo",r._nameCoordMap=mt(),r.name=e;var o=i.projection,a=eP(n,i.nameMap,i.nameProperty),s=QL(n),l=(r.resourceType=s?s.type:null,r.regions=a.regions),u=vO[s.type];r._clip=i.clip;var c,h=!o&&u.invertLongitute;if(r.view=new nP(h,EP(i.ecModel,i.api),r),r.map=n,r._regionsMap=a.regionsMap,r.regions=a.regions,r.projection=o,o)for(var d=0;d1?(f.width=p,f.height=p/x):(f.height=p,f.width=p*x),f.y=d[1]-f.height/2,f.x=d[0]-f.width/2;else{var b=t.getBoxLayoutParams();b.aspect=x,f=Qf(t,f=Jf(b,m),x)}fP(n,f.x,f.y,f.width,f.height),dP(n,t)}var bO=function(){function t(){this.dimensions=yO}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"),clip:t.getShallow("clip",!0)}}return t.eachComponent("geo",function(r,o){var a=r.get("map"),s=new mO(a+o,a,k({nameMap:r.get("nameMap"),api:e,ecModel:t},i(r)));n.push(s),r.coordinateSystem=s,s.model=r,s.resize=_O,s.resize(r,e)}),t.eachSeries(function(t){Wf({targetModel:t,coordSysType:"geo",coordSysProvider:function(){var e=t.subType===uO?t.getHostGeoModel():t.getReferringComponents("geo",Ea).models[0];return e&&e.coordinateSystem},allowNotFound:!0})}),B(fO(t,!0),function(r,o){if(hO(o)){var a=r.r[0],s=[];B(r.r,function(t){s.push(t.get("nameMap")),t.seriesGroup=null});var l,u=o.slice(1),c=new mO(u,u,k({nameMap:A(s),api:e,ecModel:t},i(a)));B(r.r,function(t){l=at(l,t.get("scaleLimit"))}),n.push(c),c.resize=_O,c.resize(a,e),B(r.r,function(t){t.coordinateSystem=c,function(t,e){B(e.get("geoCoord"),function(e,n){t.addGeoCoord(n,e)})}(c,t)})}}),n},t.prototype.getFilledRegions=function(t,e,n,i){for(var r=(t||[]).slice(),o=mt(),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,c=a.hierNode.modifier,h=s.hierNode.modifier;s=OO(s),o=RO(o),s&&o;){r=OO(r),a=RO(a),r.hierNode.ancestor=t;var d=s.hierNode.prelim+h-o.hierNode.prelim-u+i(s,o);d>0&&(EO(NO(s,t,n),t,d),u+=d,l+=d),h+=s.hierNode.modifier,u+=o.hierNode.modifier,l+=r.hierNode.modifier,c+=a.hierNode.modifier}s&&!OO(r)&&(r.hierNode.thread=s,r.hierNode.modifier+=h-l),o&&!RO(a)&&(a.hierNode.thread=o,a.hierNode.modifier+=u-c,n=t)}return n}(t,r,t.parentNode.hierNode.defaultAncestor||i[0],e)}function kO(t){var e=t.hierNode.prelim+t.parentNode.hierNode.modifier;t.setLayout({x:e},!0),t.hierNode.modifier+=t.parentNode.hierNode.modifier}function LO(t){return arguments.length?t:zO}function PO(t,e){return t-=Math.PI/2,{x:e*Math.cos(t),y:e*Math.sin(t)}}function OO(t){var e=t.children;return e.length&&t.isExpand?e[e.length-1]:t.hierNode.thread}function RO(t){var e=t.children;return e.length&&t.isExpand?e[0]:t.hierNode.thread}function NO(t,e,n){return t.hierNode.ancestor.parentNode===e.parentNode?t.hierNode.ancestor:n}function EO(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 zO(t,e){return t.parentNode===e.parentNode?1:2}var BO=Pa();function VO(t){var e=t.mainData,n=t.datas;n||(n={main:e},t.datasAttr={main:"data"}),t.datas=t.mainData=null,YO(e,n,t),B(n,function(n){B(e.TRANSFERABLE_METHODS,function(e){n.wrapMethod(e,Y(GO,t))})}),e.wrapMethod("cloneShallow",Y(HO,t)),B(e.CHANGABLE_METHODS,function(n){e.wrapMethod(n,Y(FO,t))}),ct(n[e.dataType]===e)}function GO(t,e){if(BO(i=this).mainData===i){var n=k({},BO(this).datas);n[this.dataType]=e,YO(e,n,t)}else XO(e,this.dataType,BO(this).mainData,t);var i;return e}function FO(t,e){return t.struct&&t.struct.update(),e}function HO(t,e){return B(BO(e).datas,function(n,i){n!==e&&XO(n.cloneShallow(),i,e,t)}),e}function WO(t){var e=BO(this).mainData;return null==t||null==e?e:BO(e).datas[t]}function UO(){var t=BO(this).mainData;return null==t?[{data:t}]:V(W(BO(t).datas),function(e){return{type:e,data:BO(t).datas[e]}})}function YO(t,e,n){BO(t).datas={},B(e,function(e,i){XO(e,i,t,n)})}function XO(t,e,n,i){BO(n).datas[e]=t,BO(t).mainData=n,t.dataType=e,i.struct&&(t[i.structAttr]=i.struct,i.struct[i.datasAttr[e]]=t),t.getLinkedData=WO,t.getLinkedDataAll=UO}var ZO=function(){function t(t,e){this.depth=0,this.height=0,this.dataIndex=-1,this.children=[],this.viewChildren=[],this.isExpand=!1,this.name=t||"",this.hostTree=e}return t.prototype.isRemoved=function(){return this.dataIndex<0},t.prototype.eachNode=function(t,e,n){Z(t)&&(n=e,e=t,t=null),j(t=t||{})&&(t={order:t});var i,r=t.order||"preorder",o=this[t.attr||"children"];"preorder"===r&&(i=e.call(n,this));for(var a=0;!i&&ae&&(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(j(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 KO(t){for(var e=[];t;)(t=t.parentNode)&&e.push(t);return e.reverse()}function $O(t,e){return R(KO(t),e)>=0}function JO(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 QO="tree",tR=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.hasSymbolVisual=!0,n.ignoreStyleOnData=!0,n}return n(e,t),e.prototype.getInitialData=function(t){var e={name:t.name,children:t.data},n=t.leaves||{},i=new kp(n,this,this.ecModel),r=jO.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.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 Ty("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=JO(i,this),n.collapsed=!i.isExpand,n},e.prototype.__ownRoamView=function(){return this.coordinateSystem},e.type="series."+QO,e.layoutMode="box",e.defaultOption={z:2,coordinateSystemUsage:"box",left:"12%",top:"12%",right:"12%",bottom:"12%",layout:"orthogonal",edgeShape:"curve",edgeForkPosition:"50%",roam:!1,roamTrigger:"global",nodeScaleRatio:.4,center:null,zoom:1,orient:"LR",symbol:"emptyCircle",symbolSize:7,expandAndCollapse:!0,initialTreeDepth:2,lineStyle:{color:ug.color.borderTint,width:1.5,curveness:.5},itemStyle:{color:"lightsteelblue",borderWidth:1.5},label:{show:!0},animationEasing:"linear",animationDuration:700,animationDurationUpdate:500},e}(Hy),eR=function(){this.parentPoint=[],this.childPoints=[]},nR=function(t){function e(e){return t.call(this,e)||this}return n(e,t),e.prototype.getDefaultStyle=function(){return{stroke:ug.color.neutral99,fill:null}},e.prototype.getDefaultShape=function(){return new eR},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,c=Vo(e.forkPosition,1),h=[];h[l]=r[l],h[u]=r[u]+(a[u]-r[u])*c,t.moveTo(r[0],r[1]),t.lineTo(h[0],h[1]),t.moveTo(o[0],o[1]),h[l]=o[l],t.lineTo(h[0],h[1]),h[l]=a[l],t.lineTo(h[0],h[1]),t.lineTo(a[0],a[1]);for(var d=1;dm.x)||(_-=Math.PI);var S=b?"left":"right",M=s.getModel("label"),I=M.get("rotate"),T=I*(Math.PI/180),C=v.getTextContent();C&&(v.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?xt(a.getAncestorsIndices(),a.getDescendantIndices()):"ancestor"===D?a.getAncestorsIndices():"descendant"===D?a.getDescendantIndices():null;A&&(Iu(n).focus=A),function(t,e,n,i,r,o,a,s){var l=e.getModel(),u=t.get("edgeShape"),c=t.get("layout"),h=t.getOrient(),d=t.get(["lineStyle","curveness"]),p=t.get("edgeForkPosition"),f=l.getModel("lineStyle").getLineStyle(),g=i.__edge;if("curve"===u)e.parentNode&&e.parentNode!==n&&(g||(g=i.__edge=new zh({shape:uR(c,h,d,r,r)})),rd(g,{shape:uR(c,h,d,o,a)},t));else if("polyline"===u)if("orthogonal"===c){if(e!==n&&e.children&&0!==e.children.length&&!0===e.isExpand){for(var v=e.children,y=[],m=0;m=0;o--)i.push(r[o])}}function hR(t,e){t.eachSeriesByType("tree",function(t){!function(t,e){var n=eg(t,e).refContainer,i=Jf(t.getBoxLayoutParams(),n);t.layoutInfo=i;var r=t.get("layout"),o=0,a=0,s=null;"radial"===r?(o=2*Math.PI,a=Math.min(i.height,i.width)/2,s=LO(function(t,e){return(t.parentNode===e.parentNode?1:2)/t.depth})):(o=i.width,a=i.height,s=LO());var l=t.getData().tree.root,u=l.children[0];if(u){!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)}}(l),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>d.depth&&(d=t)});var p=c===h?1:s(c,h)/2,f=p-c.getLayout().x,g=0,v=0,y=0,m=0;if("radial"===r)g=o/(h.getLayout().x+p+f),v=a/(d.depth-1||1),cR(u,function(t){y=(t.getLayout().x+f)*g,m=(t.depth-1)*v;var e=PO(y,m);t.setLayout({x:e.x,y:e.y,rawX:y,rawY:m},!0)});else{var x=t.getOrient();"RL"===x||"LR"===x?(v=a/(h.getLayout().x+p+f),g=o/(d.depth-1||1),cR(u,function(t){m=(t.getLayout().x+f)*v,y="LR"===x?(t.depth-1)*g:o-(t.depth-1)*g,t.setLayout({x:y,y:m},!0)})):"TB"!==x&&"BT"!==x||(g=o/(h.getLayout().x+p+f),v=a/(d.depth-1||1),cR(u,function(t){y=(t.getLayout().x+f)*g,m="TB"===x?(t.depth-1)*v:a-(t.depth-1)*v,t.setLayout({x:y,y:m},!0)}))}}}(t,e)})}var dR=os(QO,function(t){t.eachSeriesByType(QO,function(t){var e=t.getData();e.tree.eachNode(function(t){var n=t.getModel().getModel("itemStyle").getItemStyle();k(e.ensureUniqueItemVisual(t.dataIndex,"style"),n)})})});var pR=["treemapZoomToNode","treemapRender","treemapMove"];function fR(t){var e=t.getData().tree,n={};e.eachNode(function(e){for(var i=e;i&&i.depth>1;)i=i.parentNode;var r=Rg(t.ecModel,i.name||i.dataIndex+"",n);e.setVisual("decal",r)})}var gR=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};vR(n);var i=t.levels||[],r=this.designatedVisualItemStyle={},o=new kp({itemStyle:r},this,e);i=t.levels=function(t,e){var n,i,r=_a(e.get("color")),o=_a(e.get(["aria","decal","decals"]));if(!r)return;t=t||[],B(t,function(t){var e=new kp(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=V(i||[],function(t){return new kp(t,o,e)},this),s=jO.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 Ty("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=JO(i,this),n.treePathInfo=n.treeAncestors,n},e.prototype.setLayoutInfo=function(t){this.layoutInfo=this.layoutInfo||{},k(this.layoutInfo,t)},e.prototype.mapIdToIndex=function(t){var e=this._idIndexMap;e||(e=this._idIndexMap=mt(),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(){fR(this)},e.type="series.treemap",e.layoutMode="box",e.defaultOption={progressive:0,coordinateSystemUsage:"box",left:ug.size.l,top:ug.size.xxxl,right:ug.size.l,bottom:ug.size.xxxl,sort:!0,clipWindow:"origin",squareRatio:.5*(1+Math.sqrt(5)),leafDepth:null,drillDownIcon:"▶",zoomToNodeRatio:.1024,scaleLimit:{max:5,min:.2},roam:!0,roamTrigger:"global",nodeClick:"zoomToNode",animation:!0,animationDurationUpdate:900,animationEasing:"quinticInOut",breadcrumb:{show:!0,height:22,left:"center",bottom:ug.size.m,emptyItemWidth:25,itemStyle:{color:ug.color.backgroundShade,textStyle:{color:ug.color.secondary}},emphasis:{itemStyle:{color:ug.color.background}}},label:{show:!0,distance:0,padding:5,position:"inside",color:ug.color.neutral00,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:ug.color.neutral00,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}(Hy);function vR(t){var e=0;B(t.children,function(t){vR(t);var n=t.value;X(n)&&(n=n[0]),e+=n});var n=t.value;X(n)&&(n=n[0]),(null==n||isNaN(n))&&(n=e),n<0&&(n=0),X(t.value)?t.value[0]=n:t.value=n}var yR=function(){function t(t){this.group=new vo,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"]),c=eg(t,e).refContainer,h={left:r.get("left"),right:r.get("right"),top:r.get("top"),bottom:r.get("bottom")},d={emptyItemWidth:r.get("emptyItemWidth"),totalWidth:0,renderList:[]},p=Jf(h,c);this._prepare(n,d,l),this._renderContent(t,d,p,a,s,l,u,i),ng(o,h,c)}},t.prototype._prepare=function(t,e,n){for(var i=t;i;i=i.parentNode){var r=Da(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,s){for(var l=0,u=e.emptyItemWidth,c=t.get(["breadcrumb","height"]),h=e.totalWidth,d=e.renderList,p=r.getModel("itemStyle").getItemStyle(),f=d.length-1;f>=0;f--){var g=d[f],v=g.node,y=g.width,m=g.text;h>n.width&&(h-=y-u,y=u,m=null);var x=new Dh({shape:{points:mR(l,0,y,c,f===d.length-1,0===f)},style:P(i.getItemStyle(),{lineJoin:"bevel"}),textContent:new du({style:sp(o,{text:m})}),textConfig:{position:"inside"},z2:1e5,onclick:Y(s,v)});x.disableLabelAnimation=!0,x.getTextContent().ensureState("emphasis").style=sp(a,{text:m}),x.ensureState("emphasis").style=p,kc(x,r.get("focus"),r.get("blurScope"),r.get("disabled")),this.group.add(x),xR(x,t,v),l+=y+8}},t.prototype.remove=function(){this.group.removeAll()},t}();function mR(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 xR(t,e,n){Iu(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&&JO(n,e)}}var _R=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;iqo&&(c=qo),o=r}ca[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?bR(u*i/l,l/(u*r)):1/0}function LR(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]],c=e?t.area/e:0;(r||c>n[l[a]])&&(c=n[l[a]]);for(var h=0,d=t.length;h3||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,i=t.scale,r=this.seriesModel;if("animating"!==this._state){var o=r.getData().tree.root;if(!o)return;var a=o.getLayout();if(!a)return;var s=new Xe(a.x,a.y,a.width,a.height),l=r.layoutInfo,u=RR(l,a),c=u*i,h=(c=NR(c,r))/u,d=[1,0,0,1,0,0];Te(d,d,[-(e-=l.x),-(n-=l.y)]),De(d,d,[h,h]),Te(d,d,[e,n]),s.applyTransform(d),this.api.dispatchAction({type:"treemapRender",from:this.uid,seriesId:this.seriesModel.id,rootRect:{x:s.x,y:s.y,width:s.width,height:s.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&&Ef(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 yR(this.group))).render(t,e,n.node,function(e){"animating"!==i._state&&($O(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}(tm);var UR=B,YR=$,XR=-1,ZR=function(){function t(e){var n=e.mappingMethod,i=e.type,r=this.option=C(e);this.type=i,this.mappingMethod=n,this._normalizeData=iN[n];var o=t.visualHandlers[i];this.applyVisual=o.applyVisual,this.getColorMapper=o.getColorMapper,this._normalizedToVisual=o._normalizedToVisual[n],"piecewise"===n?(jR(r),function(t){var e=t.pieceList;t.hasSpecialVisual=!1,B(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(UR(e,function(t,e){n[t]=e}),!X(i)){var r=[];$(i)?UR(i,function(t,e){var i=n[e];r[null!=i?i:XR]=t}):r[-1]=i,i=nN(t,r)}for(var o=e.length-1;o>=0;o--)null==i[o]&&(delete n[e[o]],e.pop())}(r):jR(r,!0):(ct("linear"!==n||r.dataExtent),jR(r))}return t.prototype.mapValueToVisual=function(t){var e=this._normalizeData(t);return this._normalizedToVisual(e,t)},t.prototype.getNormalizer=function(){return U(this._normalizeData,this)},t.listVisualTypes=function(){return W(t.visualHandlers)},t.isValidType=function(e){return t.visualHandlers.hasOwnProperty(e)},t.eachVisual=function(t,e,n){$(t)?B(t,e,n):e.call(n,t)},t.mapVisual=function(e,n,i){var r,o=X(e)?[]:$(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&&UR(t.visualHandlers,function(t,r){e.hasOwnProperty(r)&&(i[r]=e[r],n=!0)}),n?i:null},t.prepareVisualTypes=function(t){if(X(t))t=t.slice();else{if(!YR(t))return[];var e=[];UR(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 c=e.get("colorMappingBy"),h={type:a.name,dataExtent:u,visual:a.range};"color"!==h.type||"index"!==c&&"id"!==c?h.mappingMethod="linear":(h.mappingMethod="category",h.loop=!0);var d=new ZR(h);return oN(d).drColorMappingBy=c,d}(0,r,o,0,u,p);B(p,function(t,e){if(t.depth>=n.length||t===n[t.depth]){var o=function(t,e,n,i,r,o){var a=k({},e);if(r){var s=r.type,l="color"===s&&oN(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);sN(t,o,n,i)}})}else s=lN(u),c.fill=s}}function lN(t){var e=uN(t,"color");if(e){var n=uN(t,"colorAlpha"),i=uN(t,"colorSaturation");return i&&(e=wi(e,null,null,i)),n&&(e=Si(e,n)),e}}function uN(t,e){var n=t[e];if(null!=n&&"none"!==n)return n}function cN(t,e){var n=t.get(e);return X(n)&&n.length?{name:e,range:n}:null}function hN(t){return"_EC_"+t}var dN=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[hN(t)]){var i=new pN(t,e);return i.hostGraph=this,this.nodes.push(i),n[hN(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[hN(t)]},t.prototype.addEdge=function(t,e,n){var i=this._nodesMap,r=this._edgesMap;if(K(t)&&(t=this.nodes[t]),K(e)&&(e=this.nodes[e]),t instanceof pN||(t=i[hN(t)]),e instanceof pN||(e=i[hN(e)]),t&&e){var o=t.id+"-"+e.id,a=new fN(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 pN&&(t=t.id),e instanceof pN&&(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 pN||(e=this._nodesMap[hN(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&&!t.hasKey(p)&&(t.set(p,!0),o.push(d.node1))}for(s=0;s=0&&!t.hasKey(m)&&(t.set(m,!0),a.push(y.node2))}}}return{edge:t.keys(),node:e.keys()}},t}(),fN=function(){function t(t,e,n){this.dataIndex=-1,this.node1=t,this.node2=e,this.dataIndex=null==n?-1:n}return t.prototype.getModel=function(t){if(!(this.dataIndex<0))return this.hostGraph.edgeData.getItemModel(this.dataIndex).getModel(t)},t.prototype.getAdjacentDataIndices=function(){return{edge:[this.dataIndex],node:[this.node1.dataIndex,this.node2.dataIndex]}},t.prototype.getTrajectoryDataIndices=function(){var t=mt(),e=mt();t.set(this.dataIndex,!0);for(var n=[this.node1],i=[this.node2],r=0;r=0&&!t.hasKey(u)&&(t.set(u,!0),n.push(l.node1))}for(r=0;r=0&&!t.hasKey(d)&&(t.set(d,!0),i.push(h.node2))}return{edge:t.keys(),node:e.keys()}},t}();function gN(t,e){return{getValue:function(n){var i=this[t][e];return i.getStore().get(i.getDimensionIndex(n||"value"),this.dataIndex)},setVisual:function(n,i){this.dataIndex>=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 vN(t,e,n,i,r){for(var o=new dN(i),a=0;a "+d)),u++)}var p,f=n.get("coordinateSystem");if("cartesian2d"===f||"polar"===f||"matrix"===f)p=$b(t,n);else{var g=Vf.get(f),v=g&&g.dimensions||[];R(v,"value")<0&&v.concat(["value"]);var y=Wb(t,{coordDimensions:v,encodeDefine:n.getEncode()}).dimensions;(p=new Hb(y,n)).initData(t)}var m=new Hb(["value"],n);return m.initData(l,s),r&&r(p,m),VO({mainData:p,struct:o,structAttr:"graph",datas:{node:p,edge:m},datasAttr:{node:"data",edge:"edgeData"}}),o.update(),o}E(pN,gN("hostGraph","data")),E(fN,gN("hostGraph","edgeData"));var yN="--\x3e",mN=function(t){return t.get("autoCurveness")||null},xN=function(t,e){var n=mN(t),i=20,r=[];if(K(n))i=n;else if(X(n))return void(t.__curvenessList=n);e>i&&(i=e);var o=i%2?i+2:i+3;r=[];for(var a=0;a "),value:r.value,noValue:null==r.value})}return By({series:this,dataIndex:t,multipleSeries:e})},e.prototype._updateCategoriesData=function(){var t=V(this.option.categories||[],function(t){return null!=t.value?t:k({value:0},t)}),e=new Hb(["value"],this);e.initData(t),this._categoriesData=e,this._categoriesModels=e.mapArray(function(t){return e.getItemModel(t)})},e.prototype.isAnimationEnabled=function(){return t.prototype.isAnimationEnabled.call(this)&&!("force"===this.get("layout")&&this.get(["force","layoutAnimation"]))},e.prototype.__ownRoamView=function(){var t=this.coordinateSystem;return TP(t)&&t},e.type="series."+MN,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:ug.color.neutral50,width:1,opacity:.5},emphasis:{scale:!0,label:{show:!0}},select:{itemStyle:{borderColor:ug.color.primary}}},e}(Hy);function TN(t){return t instanceof Array||(t=[t,t]),t}var CN=os(MN,function(t){t.eachSeriesByType(MN,function(t){var e=t.getGraph(),n=t.getEdgeData(),i=TN(t.get("edgeSymbol")),r=TN(t.get("edgeSymbolSize"));n.setVisual("fromSymbol",i&&i[0]),n.setVisual("toSymbol",i&&i[1]),n.setVisual("fromSymbolSize",r&&r[0]),n.setVisual("toSymbolSize",r&&r[1]),n.setVisual("style",t.getModel("lineStyle").getLineStyle()),n.each(function(t){var i=n.getItemModel(t),r=e.getEdgeByIndex(t),o=TN(i.getShallow("symbol",!0)),a=TN(i.getShallow("symbolSize",!0)),s=i.getModel("lineStyle").getLineStyle(),l=n.ensureUniqueItemVisual(t,"style");switch(k(l,s),l.stroke){case"source":var u=r.node1.getVisual("style");l.stroke=u&&u.fill;break;case"target":u=r.node2.getVisual("style");l.stroke=u&&u.fill}o[0]&&r.setVisual("fromSymbol",o[0]),o[1]&&r.setVisual("toSymbol",o[1]),a[0]&&r.setVisual("fromSymbolSize",a[0]),a[1]&&r.setVisual("toSymbolSize",a[1])})})});function DN(t){var e=t.coordinateSystem;if(!e||"view"===e.type){var n=t.getGraph();n.eachNode(function(t){var e=t.getModel();t.setLayout([+e.get("x"),+e.get("y")])}),AN(n,t)}}function AN(t,e){t.eachEdge(function(t,n){var i=st(t.getModel().get(["lineStyle","curveness"]),-SN(t,e,n,!0),0),r=At(t.node1.getLayout()),o=At(t.node2.getLayout()),a=[r,o];+i&&a.push([(r[0]+o[0])/2-(r[1]-o[1])*i,(r[1]+o[1])/2-(o[0]-r[0])*i]),t.setLayout(a)})}var kN=os(MN,function(t,e){t.eachSeriesByType(MN,function(t){var e=t.get("layout"),n=t.coordinateSystem;if(n&&"view"!==n.type){var i=t.getData(),r=[];B(n.dimensions,function(t){r=r.concat(i.mapDimensionsAll(t))});for(var o=0;o0&&(m[0]=-m[0],m[1]=-m[1]);var _=y[0]<0?-1:1;if("start"!==i.__position&&"end"!==i.__position){var b=-Math.atan2(y[1],y[0]);u[0].8?"left":c[0]<-.8?"right":"center",d=c[1]>.8?"top":c[1]<-.8?"bottom":"middle";break;case"start":i.x=-c[0]*f+l[0],i.y=-c[1]*g+l[1],h=c[0]>.8?"right":c[0]<-.8?"left":"center",d=c[1]>.8?"bottom":c[1]<-.8?"top":"middle";break;case"insideStartTop":case"insideStart":case"insideStartBottom":i.x=f*_+l[0],i.y=l[1]+w,h=y[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,h="center",i.originY=-w;break;case"insideEndTop":case"insideEnd":case"insideEndBottom":i.x=-f*_+u[0],i.y=u[1]+w,h=y[0]>=0?"right":"left",i.originX=f*_,i.originY=-w}i.scaleX=i.scaleY=r,i.setStyle({verticalAlign:i.__verticalAlign||d,align:i.__align||h})}}}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}(vo),QN=function(){function t(t){this.group=new vo,this._LineCtor=t||JN}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=tE(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=tE(t),this._lineData=null,this.group.removeAll()},t.prototype.incrementalUpdate=function(t,e,n){function i(t){t.isGroup||function(t){return t.animators&&t.animators.length>0}(t)||(t.incremental=n,t.ensureState("emphasis").hoverLayer=2)}this._progressiveEls=[];for(var r=t.start;r=0?i+=u:i-=u:f>=0?i-=u:i+=u}return i}function cE(t,e){var n=[],i=jn,r=[[],[],[]],o=[[],[]],a=[];e/=2,t.eachEdge(function(t,s){var l=t.getLayout(),u=t.getVisual("fromSymbol"),c=t.getVisual("toSymbol");l.__original||(l.__original=[At(l[0]),At(l[1])],l[2]&&l.__original.push(At(l[2])));var h=l.__original;if(null!=l[2]){if(Dt(r[0],h[0]),Dt(r[1],h[2]),Dt(r[2],h[1]),u&&"none"!==u){var d=PN(t.node1),p=uE(r,h[0],d*e);i(r[0][0],r[1][0],r[2][0],p,n),r[0][0]=n[3],r[1][0]=n[4],i(r[0][1],r[1][1],r[2][1],p,n),r[0][1]=n[3],r[1][1]=n[4]}if(c&&"none"!==c){d=PN(t.node2),p=uE(r,h[1],d*e);i(r[0][0],r[1][0],r[2][0],p,n),r[1][0]=n[1],r[2][0]=n[2],i(r[0][1],r[1][1],r[2][1],p,n),r[1][1]=n[1],r[2][1]=n[2]}Dt(l[0],r[0]),Dt(l[1],r[2]),Dt(l[2],r[1])}else{if(Dt(o[0],h[0]),Dt(o[1],h[1]),Ot(a,o[1],o[0]),Vt(a,a),u&&"none"!==u){d=PN(t.node1);Pt(o[0],o[0],a,d*e)}if(c&&"none"!==c){d=PN(t.node2);Pt(o[1],o[1],a,-d*e)}Dt(l[0],o[0]),Dt(l[1],o[1])}})}var hE=Pa();function dE(t,e){t&&(hE(t).bridge=e)}var pE=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.type=MN,e}return n(e,t),e.prototype.init=function(t,e){var n=new nC,i=new QN,r=this.group,o=new vo;this._controller=new uL(e.getZr()),o.add(n.group),o.add(i.group),r.add(o),this._symbolDraw=n,this._lineDraw=i,this._mainGroup=o,this._firstRender=!0},e.prototype.render=function(t,e,n){var i=this,r=PP(t),o=!1;this._model=t,this._api=n,this._active=!0;var a=this._mainGroup,s=this._getThumbnailInfo();s&&s.bridge.reset(n);var l=this._symbolDraw,u=this._lineDraw;r&&CP(a,2,r,this._firstRender?null:t),cE(t.getGraph(),LN(t));var c=t.getData();l.updateData(c);var h=t.getEdgeData();u.updateData(h),this._updateNodeAndLinkScale(),r&&FP(t,n,this._controller,function(e,n,i){return t.coordinateSystem.containPoint([n,i])},null),clearTimeout(this._layoutTimeout);var d=t.forceLayout,p=t.get(["force","layoutAnimation"]);d&&(o=!0,this._startForceLayoutIteration(d,n,p));var f=t.get("layout");c.graph.eachNode(function(e){var r=e.dataIndex,o=e.getGraphicEl(),a=e.getModel();if(o){o.off("drag").off("dragend");var s=a.get("draggable");s&&o.on("drag",function(a){switch(f){case"force":d.warmUp(),!i._layouting&&i._startForceLayoutIteration(d,n,p),d.setFixed(r),c.setItemLayout(r,[o.x,o.y]);break;case"circular":c.setItemLayout(r,[o.x,o.y]),e.setLayout({fixed:!0},!0),NN(t,"symbolSize",e,[a.offsetX,a.offsetY]),i.updateLayout(t);break;default:c.setItemLayout(r,[o.x,o.y]),AN(t.getGraph(),t),i.updateLayout(t)}}).on("dragend",function(){d&&d.setUnfixed(r)}),o.setDraggable(s,!!a.get("cursor")),"adjacency"===a.get(["emphasis","focus"])&&(Iu(o).focus=e.getAdjacentDataIndices())}}),c.graph.eachEdge(function(t){var e=t.getGraphicEl(),n=t.getModel().get(["emphasis","focus"]);e&&"adjacency"===n&&(Iu(e).focus={edge:[t.dataIndex],node:[t.node1.dataIndex,t.node2.dataIndex]})});var g="circular"===t.get("layout")&&t.get(["circular","rotateLabel"]),v=c.getLayout("cx"),y=c.getLayout("cy");c.graph.eachNode(function(t){zN(t,g,v,y)}),this._firstRender=!1,o||this._renderThumbnail(t,n,this._symbolDraw,this._lineDraw)},e.prototype.dispose=function(){this.remove(),this._controller&&this._controller.dispose()},e.prototype._startForceLayoutIteration=function(t,e,n){var i=this,r=!1;!function o(){t.step(function(t){i.updateLayout(i._model),!t&&r||(r=!0,i._renderThumbnail(i._model,e,i._symbolDraw,i._lineDraw)),(i._layouting=!t)&&(n?i._layoutTimeout=setTimeout(o,16):o())})}()},e.prototype.__updateOnOwnRoam=function(t,e,n){var i=PP(e);this._active&&i&&(CP(this._mainGroup,2,i,null),XP(t)&&(this._updateNodeAndLinkScale(),cE(e.getGraph(),LN(e)),this._lineDraw.updateLayout(),n.updateLabelLayout()),this._updateThumbnailWindow())},e.prototype._updateNodeAndLinkScale=function(){var t=this._model,e=t.getData(),n=LN(t);e.eachItemGraphicEl(function(t,e){t&&t.setSymbolScale(n)})},e.prototype.updateLayout=function(t){this._active&&(cE(t.getGraph(),LN(t)),this._symbolDraw.updateLayout(),this._lineDraw.updateLayout())},e.prototype.remove=function(){this._active=!1,clearTimeout(this._layoutTimeout),this._layouting=!1,this._layoutTimeout=null,this._symbolDraw&&this._symbolDraw.remove(),this._lineDraw&&this._lineDraw.remove(),this._controller&&this._controller.disable()},e.prototype._getThumbnailInfo=function(){var t=this._model,e=t.coordinateSystem;if("view"===e.type){var n=function(t){if(t)return hE(t).bridge}(t);if(n)return{bridge:n,coordSys:e}}},e.prototype._updateThumbnailWindow=function(){var t=this._getThumbnailInfo();t&&t.bridge.updateWindow(rP(null,t.coordSys),this._api)},e.prototype._renderThumbnail=function(t,e,n,i){var r=this._getThumbnailInfo();if(r){var o=new vo,a=n.group.children(),s=i.group.children(),l=new vo,u=new vo;o.add(u),o.add(l);for(var c=0;c "),value:i.value,noValue:null==i.value})}return Ty("nameValue",{name:i.name,value:i.value,noValue:null==i.value})},e.prototype.getDataParams=function(e,n){var i=t.prototype.getDataParams.call(this,e,n);if("node"===n){var r=this.getData(),o=this.getGraph().getNodeByIndex(e);if(null==i.name&&(i.name=r.getName(e)),null==i.value){var a=o.getLayout().value;i.value=a}}return i},e.type="series."+vE,e.defaultOption={z:2,coordinateSystem:"none",legendHoverLink:!0,colorBy:"data",left:0,top:0,right:0,bottom:0,width:null,height:null,center:["50%","50%"],radius:["70%","80%"],clockwise:!0,startAngle:90,endAngle:"auto",minAngle:0,padAngle:3,itemStyle:{borderRadius:[0,0,5,5]},lineStyle:{width:0,color:"source",opacity:.2},label:{show:!0,position:"outside",distance:5},emphasis:{focus:"adjacency",lineStyle:{opacity:.5}}},e}(Hy),mE=function(t){function e(e,n,i){var r=t.call(this)||this;Iu(r).dataType="node",r.z2=2;var o=new du;return r.setTextContent(o),r.updateData(e,n,i,!0),r}return n(e,t),e.prototype.updateData=function(t,e,n,i){var r=this,o=t.graph.getNodeByIndex(e),a=t.hostModel,s=o.getModel(),l=s.getModel("emphasis"),u=t.getItemLayout(e),c=k(eA(s.getModel("itemStyle"),u,!0),u),h=this;if(isNaN(c.startAngle))h.setShape(c);else{i?h.setShape(c):rd(h,{shape:c},a,e);var d=k(eA(s.getModel("itemStyle"),u,!0),u);r.setShape(d),r.useStyle(t.getItemVisual(e,"style")),Rc(r,s),this._updateLabel(a,s,o),t.setItemGraphicEl(e,h),Rc(h,s,"itemStyle");var p=l.get("focus");kc(this,"adjacency"===p?o.getAdjacentDataIndices():p,l.get("blurScope"),l.get("disabled"))}},e.prototype._updateLabel=function(t,e,n){var i=this.getTextContent(),r=n.getLayout(),o=(r.startAngle+r.endAngle)/2,a=Math.cos(o),s=Math.sin(o),l=e.getModel("label");i.ignore=!l.get("show");var u=ap(e),c=n.getVisual("style");op(i,u,{labelFetcher:{getFormattedLabel:function(n,i,r,o,a,s){return t.getFormattedLabel(n,i,"node",o,st(a,u.normal&&u.normal.get("formatter"),e.get("name")),s)}},labelDataIndex:n.dataIndex,defaultText:n.dataIndex+"",inheritColor:c.fill,defaultOpacity:c.opacity,defaultOutsidePosition:"startArc"});var h,d=l.get("position")||"outside",p=l.get("distance")||0;h="outside"===d?r.r+p:(r.r+r.r0)/2,this.textConfig={inside:"outside"!==d};var f="outside"!==d?l.get("align")||"center":a>0?"left":"right",g="outside"!==d?l.get("verticalAlign")||"middle":s>0?"top":"bottom";i.attr({x:a*h+r.cx,y:s*h+r.cy,rotation:0,style:{align:f,verticalAlign:g}})},e}(Sh),xE=function(t){function e(e,n,i,r){var o=t.call(this)||this;return Iu(o).dataType="edge",o.updateData(e,n,i,r,!0),o}return n(e,t),e.prototype.buildPath=function(t,e){t.moveTo(e.s1[0],e.s1[1]);var n=.7,i=e.clockwise;t.arc(e.cx,e.cy,e.r,e.sStartAngle,e.sEndAngle,!i),t.bezierCurveTo((e.cx-e.s2[0])*n+e.s2[0],(e.cy-e.s2[1])*n+e.s2[1],(e.cx-e.t1[0])*n+e.t1[0],(e.cy-e.t1[1])*n+e.t1[1],e.t1[0],e.t1[1]),t.arc(e.cx,e.cy,e.r,e.tStartAngle,e.tEndAngle,!i),t.bezierCurveTo((e.cx-e.t2[0])*n+e.t2[0],(e.cy-e.t2[1])*n+e.t2[1],(e.cx-e.s1[0])*n+e.s1[0],(e.cy-e.s1[1])*n+e.s1[1],e.s1[0],e.s1[1]),t.closePath()},e.prototype.updateData=function(t,e,n,i,r){var o=t.hostModel,a=e.graph.getEdgeByIndex(n),s=a.getLayout(),l=a.node1.getModel(),u=e.getItemModel(a.dataIndex),c=u.getModel("lineStyle"),h=u.getModel("emphasis"),d=h.get("focus"),p=k(eA(l.getModel("itemStyle"),s,!0),s),f=this;isNaN(p.sStartAngle)||isNaN(p.tStartAngle)?f.setShape(p):(r?(f.setShape(p),_E(f,a,t,c)):(cd(f),_E(f,a,t,c),rd(f,{shape:p},o,n)),kc(this,"adjacency"===d?a.getAdjacentDataIndices():d,h.get("blurScope"),h.get("disabled")),Rc(f,u,"lineStyle"),e.setItemGraphicEl(a.dataIndex,f))},e}(Kl);function _E(t,e,n,i){var r=e.node1,o=e.node2,a=t.style;switch(t.setStyle(i.getLineStyle()),i.get("color")){case"source":a.fill=n.getItemVisual(r.dataIndex,"style").fill,a.decal=r.getVisual("style").decal;break;case"target":a.fill=n.getItemVisual(o.dataIndex,"style").fill,a.decal=o.getVisual("style").decal;break;case"gradient":var s=n.getItemVisual(r.dataIndex,"style").fill,l=n.getItemVisual(o.dataIndex,"style").fill;if(j(s)&&j(l)){var u=t.shape,c=(u.s1[0]+u.s2[0])/2,h=(u.s1[1]+u.s2[1])/2,d=(u.t1[0]+u.t2[0])/2,p=(u.t1[1]+u.t2[1])/2;a.fill=new Hh(c,h,d,p,[{offset:0,color:s},{offset:1,color:l}],!0)}}}var bE=Math.PI/180,wE=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.type=vE,e}return n(e,t),e.prototype.init=function(t,e){},e.prototype.render=function(t,e,n){var i=t.getData(),r=this._data,o=this.group,a=-t.get("startAngle")*bE;if(i.diff(r).add(function(t){if(i.getItemLayout(t)){var e=new mE(i,t,a);Iu(e).dataIndex=t,o.add(e)}}).update(function(e,n){var s=r.getItemGraphicEl(n);i.getItemLayout(e)?(s?s.updateData(i,e,a):s=new mE(i,e,a),o.add(s)):s&&ud(s,t,n)}).remove(function(e){var n=r.getItemGraphicEl(e);n&&ud(n,t,e)}).execute(),!r){var s=t.get("center");this.group.scaleX=.01,this.group.scaleY=.01,this.group.originX=Vo(s[0],n.getWidth()),this.group.originY=Vo(s[1],n.getHeight()),od(this.group,{scaleX:1,scaleY:1},t)}this._data=i,this.renderEdges(t,a)},e.prototype.renderEdges=function(t,e){var n=t.getData(),i=t.getEdgeData(),r=this._edgeData,o=this.group;i.diff(r).add(function(t){var r=new xE(n,i,t,e);Iu(r).dataIndex=t,o.add(r)}).update(function(t,a){var s=r.getItemGraphicEl(a);s.updateData(n,i,t,e),o.add(s)}).remove(function(e){var n=r.getItemGraphicEl(e);n&&ud(n,t,e)}).execute(),this._edgeData=i},e.prototype.dispose=function(){},e.type=vE,e}(tm),SE=Math.PI/180,ME=os(vE,function(t,e){t.eachSeriesByType(vE,function(t){!function(t,e){var n=t.getData(),i=n.graph,r=t.getEdgeData();if(!r.count())return;var o=$f(t,e),a=o.cx,s=o.cy,l=o.r,u=o.r0,c=Math.max((t.get("padAngle")||0)*SE,0),h=Math.max((t.get("minAngle")||0)*SE,0),d=-t.get("startAngle")*SE,p=d+2*Math.PI,f=t.get("clockwise"),g=f?1:-1,v=[d,p];Dl(v,!f);var y=v[0],m=v[1]-y,x=0===n.getSum("value")&&0===r.getSum("value"),_=[],b=0;i.eachEdge(function(t){var e=x?1:t.getValue("value");x&&(e>0||h)&&(b+=2);var n=t.node1.dataIndex,i=t.node2.dataIndex;_[n]=(_[n]||0)+e,_[i]=(_[i]||0)+e});var w=0;if(i.eachNode(function(t){var e=t.getValue("value");isNaN(e)||(_[t.dataIndex]=Math.max(e,_[t.dataIndex]||0)),!x&&(_[t.dataIndex]>0||h)&&b++,w+=_[t.dataIndex]||0}),0===b||0===w)return;c*b>=Math.abs(m)&&(c=Math.max(0,(Math.abs(m)-h*b)/b));(c+h)*b>=Math.abs(m)&&(h=(Math.abs(m)-c*b)/b);var S=(m-c*b*g)/w,M=0,I=0,T=0;i.eachNode(function(t){var e=_[t.dataIndex]||0,n=S*(w?e:1)*g;Math.abs(n)I){var D=M/I;i.eachNode(function(t){var e=t.getLayout().angle;Math.abs(e)>=h?t.setLayout({angle:e*D,ratio:D},!0):t.setLayout({angle:h,ratio:0===h?1:e/h},!0)})}else i.eachNode(function(t){if(!C){var e=t.getLayout().angle;e-Math.min(e/T,1)*Mh&&h>0){var n=C?1:Math.min(e/T,1),i=e-h,r=Math.min(i,Math.min(A,M*n));A-=r,t.setLayout({angle:e-r,ratio:(e-r)/e},!0)}else h>0&&t.setLayout({angle:h,ratio:0===e?1:h/e},!0)}});var k=y,L=[];i.eachNode(function(t){var e=Math.max(t.getLayout().angle,h);t.setLayout({cx:a,cy:s,r0:u,r:l,startAngle:k,endAngle:k+e*g,clockwise:f},!0),L[t.dataIndex]=k,k+=(e+c)*g}),i.eachEdge(function(t){var e=x?1:t.getValue("value"),n=S*(w?e:1)*g,i=t.node1.dataIndex,r=L[i]||0,o=r+Math.abs((t.node1.getLayout().ratio||1)*n)*g,l=[a+u*Math.cos(r),s+u*Math.sin(r)],c=[a+u*Math.cos(o),s+u*Math.sin(o)],h=t.node2.dataIndex,d=L[h]||0,p=d+Math.abs((t.node2.getLayout().ratio||1)*n)*g,v=[a+u*Math.cos(d),s+u*Math.sin(d)],y=[a+u*Math.cos(p),s+u*Math.sin(p)];t.setLayout({s1:l,s2:c,sStartAngle:r,sEndAngle:o,t1:v,t2:y,tStartAngle:d,tEndAngle:p,cx:a,cy:s,r:u,value:e,clockwise:f}),L[i]=o,L[h]=p})}(t,e)})});var IE=function(){this.angle=0,this.width=10,this.r=10,this.x=0,this.y=0},TE=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 IE},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}(Kl);function CE(t,e){var n=null==t?"":t+"";return e&&(j(e)?n=e.replace("{value}",n):Z(e)&&(n=e(t))),n}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){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:Vo(n[0],e.getWidth()),cy:Vo(n[1],e.getHeight()),r:Vo(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"),c=u.get("roundCap")?JD:Sh,h=u.get("show"),d=u.getModel("lineStyle"),p=d.get("width"),f=[s,l];Dl(f,!a);for(var g=(l=f[1])-(s=f[0]),v=s,y=[],m=0;h&&m=t&&(0===e?0:i[e-1][0])Math.PI/2&&(B+=Math.PI):"tangential"===z?B=-M-Math.PI/2:K(z)&&(B=z*Math.PI/180),0===B?h.add(new du({style:sp(x,{text:O,x:N,y:E,verticalAlign:c<-.8?"top":c>.8?"bottom":"middle",align:u<-.4?"left":u>.4?"right":"center"},{inheritColor:R}),silent:!0})):h.add(new du({style:sp(x,{text:O,x:N,y:E,verticalAlign:"middle",align:"center"},{inheritColor:R}),silent:!0,originX:N,originY:E,rotation:B}))}if(m.get("show")&&k!==_){P=(P=m.get("distance"))?P+l:l;for(var V=0;V<=b;V++){u=Math.cos(M),c=Math.sin(M);var G=new Oh({shape:{x1:u*(f-P)+d,y1:c*(f-P)+p,x2:u*(f-S-P)+d,y2:c*(f-S-P)+p},silent:!0,style:D});"auto"===D.stroke&&G.setStyle({stroke:i((k+V/b)/_)}),h.add(G),M+=T}M-=T}else M+=I}},e.prototype._renderPointer=function(t,e,n,i,r,o,a,s,l){var u=this.group,c=this._data,h=this._progressEls,d=[],p=t.get(["pointer","show"]),f=t.getModel("progress"),g=f.get("show"),v=t.getData(),y=v.mapDimension("value"),m=+t.get("min"),x=+t.get("max"),_=[m,x],b=[o,a];function w(e,n){var i,o=v.getItemModel(e).getModel("pointer"),a=Vo(o.get("width"),r.r),s=Vo(o.get("length"),r.r),l=t.get(["pointer","icon"]),u=o.get("offsetCenter"),c=Vo(u[0],r.r),h=Vo(u[1],r.r),d=o.get("keepAspect");return(i=l?xx(l,c-a/2,h-s,a,s,null,d):new TE({shape:{angle:-Math.PI/2,width:a,r:s,x:c,y:h}})).rotation=-(n+Math.PI/2),i.x=r.cx,i.y=r.cy,i}function S(t,e){var n=f.get("roundCap")?JD:Sh,i=f.get("overlap"),a=i?f.get("width"):l/v.count(),u=i?r.r-a:r.r-(t+1)*a,c=i?r.r:r.r-t*a,h=new n({shape:{startAngle:o,endAngle:e,cx:r.cx,cy:r.cy,clockwise:s,r0:u,r:c}});return i&&(h.z2=Bo(v.get(y,t),[m,x],[100,0],!0)),h}(g||p)&&(v.diff(c).add(function(e){var n=v.get(y,e);if(p){var i=w(e,o);od(i,{rotation:-((isNaN(+n)?b[0]:Bo(n,_,b,!0))+Math.PI/2)},t),u.add(i),v.setItemGraphicEl(e,i)}if(g){var r=S(e,o),a=f.get("clip");od(r,{shape:{endAngle:Bo(n,_,b,a)}},t),u.add(r),Tu(t.seriesIndex,v.dataType,e,r),d[e]=r}}).update(function(e,n){var i=v.get(y,e);if(p){var r=c.getItemGraphicEl(n),a=r?r.rotation:o,s=w(e,a);s.rotation=a,rd(s,{rotation:-((isNaN(+i)?b[0]:Bo(i,_,b,!0))+Math.PI/2)},t),u.add(s),v.setItemGraphicEl(e,s)}if(g){var l=h[n],m=S(e,l?l.shape.endAngle:o),x=f.get("clip");rd(m,{shape:{endAngle:Bo(i,_,b,x)}},t),u.add(m),Tu(t.seriesIndex,v.dataType,e,m),d[e]=m}}).execute(),v.each(function(t){var e=v.getItemModel(t),n=e.getModel("emphasis"),r=n.get("focus"),o=n.get("blurScope"),a=n.get("disabled"),s=i(Bo(v.get(y,t),_,[0,1],!0));if(p){var l=v.getItemGraphicEl(t),u=v.getItemVisual(t,"style"),c=u.fill;if(l instanceof eu){var h=l.style;l.useStyle(k({image:h.image,x:h.x,y:h.y,width:h.width,height:h.height},u))}else l.useStyle(u),"pointer"!==l.type&&l.setColor(c);l.setStyle(e.getModel(["pointer","itemStyle"]).getItemStyle()),"auto"===l.style.fill&&l.setStyle("fill",s),l.z2EmphasisLift=0,Rc(l,e),kc(l,r,o,a)}if(g){var f=d[t];f.useStyle(v.getItemVisual(t,"style")),f.setStyle(e.getModel(["progress","itemStyle"]).getItemStyle()),"auto"===f.style.fill&&f.setStyle("fill",s),f.z2EmphasisLift=0,Rc(f,e),kc(f,r,o,a)}}),this._progressEls=d)},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=xx(r,e.cx-i/2+Vo(o[0],e.r),e.cy-i/2+Vo(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"),c=new vo,h=[],d=[],p=t.isAnimationEnabled(),f=t.get(["pointer","showAbove"]);a.diff(this._data).add(function(t){h[t]=new du({silent:!0}),d[t]=new du({silent:!0})}).update(function(t,e){h[t]=o._titleEls[e],d[t]=o._detailEls[e]}).execute(),a.each(function(e){var n=a.getItemModel(e),o=a.get(s,e),g=new vo,v=i(Bo(o,[l,u],[0,1],!0)),y=n.getModel("title");if(y.get("show")){var m=y.get("offsetCenter"),x=r.cx+Vo(m[0],r.r),_=r.cy+Vo(m[1],r.r);(D=h[e]).attr({z2:f?0:2,style:sp(y,{x:x,y:_,text:a.getName(e),align:"center",verticalAlign:"middle"},{inheritColor:v})}),g.add(D)}var b=n.getModel("detail");if(b.get("show")){var w=b.get("offsetCenter"),S=r.cx+Vo(w[0],r.r),M=r.cy+Vo(w[1],r.r),I=Vo(b.get("width"),r.r),T=Vo(b.get("height"),r.r),C=t.get(["progress","show"])?a.getItemVisual(e,"style").fill:v,D=d[e],A=b.get("formatter");D.attr({z2:f?0:2,style:sp(b,{x:S,y:M,text:CE(o,A),width:isNaN(I)?null:I,height:isNaN(T)?null:T,align:"center",verticalAlign:"middle"},{inheritColor:C})}),gp(D,{normal:b},o,function(t){return CE(t,A)}),p&&vp(D,e,a,t,{getFormattedLabel:function(t,e,n,i,r,a){return CE(a?a.interpolatedValue:o,A)}}),g.add(D)}c.add(g)}),this.group.add(c),this._titleEls=h,this._detailEls=d},e.type="gauge",e}(tm),AE=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 bA(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,ug.color.neutral10]],width:10}},progress:{show:!1,overlap:!0,width:10,roundCap:!1,clip:!0},splitLine:{show:!0,length:10,distance:10,lineStyle:{color:ug.color.axisTick,width:3,type:"solid"}},axisTick:{show:!0,splitNumber:5,length:6,distance:10,lineStyle:{color:ug.color.axisTickMinor,width:1,type:"solid"}},axisLabel:{show:!0,distance:15,color:ug.color.axisLabel,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:ug.color.neutral00,borderWidth:0,borderColor:ug.color.theme[0]}},title:{show:!0,offsetCenter:[0,"20%"],color:ug.color.secondary,fontSize:16,valueAnimation:!1},detail:{show:!0,backgroundColor:ug.color.transparent,borderWidth:0,borderColor:ug.color.neutral40,width:100,height:null,padding:[5,10],offsetCenter:[0,"40%"],color:ug.color.primary,fontSize:30,fontWeight:"bold",lineHeight:30,valueAnimation:!1}},e}(Hy);var kE="funnel",LE=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 SA(U(this.getData,this),U(this.getRawData,this)),this._defaultLabelLine(e)},e.prototype.getInitialData=function(t,e){return bA(this,{coordDimensions:["value"],encodeDefaulter:Y(Sg,this)})},e.prototype._defaultLabelLine=function(t){ba(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."+kE,e.defaultOption={coordinateSystemUsage:"box",z:2,legendHoverLink:!0,colorBy:"data",left:80,top:60,right:80,bottom:65,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:ug.color.neutral00,borderWidth:1},emphasis:{label:{show:!0}},select:{itemStyle:{borderColor:ug.color.primary}}},e}(Hy),PE=["itemStyle","opacity"],OE=function(t){function e(e,n){var i=t.call(this)||this,r=i,o=new kh,a=new du;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(PE);l=null==l?1:l,n||cd(i),i.useStyle(t.getItemVisual(e,"style")),i.style.lineJoin="round",n?(i.setShape({points:a.points}),i.style.opacity=0,od(i,{style:{opacity:l}},r,e)):rd(i,{style:{opacity:l},shape:{points:a.points}},r,e),Rc(i,o),this._updateLabel(t,e),kc(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;op(r,ap(a),{labelFetcher:t.hostModel,labelDataIndex:e,defaultOpacity:l.opacity,defaultText:t.getName(e)},{normal:{align:s.textAlign,verticalAlign:s.verticalAlign}});var c="inherit"===a.getModel("label").get("color")?u:null;n.setTextConfig({local:!0,inside:!!s.inside,insideStroke:c,outsideFill:c});var h=s.linePoints;i.setShape({points:h}),n.textGuideLineConfig={anchor:h?new Pe(h[0][0],h[0][1]):null},rd(r,{style:{x:s.x,y:s.y}},o,e),r.attr({rotation:s.rotation,originX:s.x,originY:s.y,z2:10}),ZM(n,jM(a),{stroke:u})},e}(Dh),RE=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.type=kE,e.ignoreLabelLineUpdate=!0,e}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 OE(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){ud(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=kE,e}(tm);var NE=os(kE,function(t,e){t.eachSeriesByType(kE,function(t){var n=t.getData(),i=n.mapDimension("value"),r=t.get("sort"),o=eg(t,e),a=Jf(t.getBoxLayoutParams(),o.refContainer),s=EE(t),l=a.width,u=a.height,c=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();a-1&&(l="left"),e&&R(["left","right"],l)>-1&&(l="bottom")),"left"===l?(p=(h[3][0]+h[0][0])/2,f=(h[3][1]+h[0][1])/2,r=(g=p-y)-5,i="right"):"right"===l?(p=(h[1][0]+h[2][0])/2,f=(h[1][1]+h[2][1])/2,r=(g=p+y)+5,i="left"):"top"===l?(p=(h[3][0]+h[0][0])/2,o=(v=(f=(h[3][1]+h[0][1])/2)-y)-5,i="center"):"bottom"===l?(p=(h[1][0]+h[2][0])/2,o=(v=(f=(h[1][1]+h[2][1])/2)+y)+5,i="center"):"rightTop"===l?(p=e?h[3][0]:h[1][0],f=e?h[3][1]:h[1][1],e?(o=(v=f-y)-5,i="center"):(r=(g=p+y)+5,i="top")):"rightBottom"===l?(p=h[2][0],f=h[2][1],e?(o=(v=f+y)+5,i="center"):(r=(g=p+y)+5,i="bottom")):"leftTop"===l?(p=h[0][0],f=e?h[0][1]:h[1][1],e?(o=(v=f-y)-5,i="center"):(r=(g=p-y)-5,i="right")):"leftBottom"===l?(p=e?h[1][0]:h[3][0],f=e?h[1][1]:h[2][1],e?(o=(v=f+y)+5,i="center"):(r=(g=p-y)-5,i="right")):(p=(h[1][0]+h[2][0])/2,f=(h[1][1]+h[2][1])/2,e?(o=(v=f+y)+5,i="center"):(r=(g=p+y)+5,i="left")),e?r=g=p:o=v=f,a=[[p,f],[g,v]]}c.label={linePoints:a,x:r,y:o,verticalAlign:"middle",textAlign:i,inside:d}})}(n)})});function EE(t){return"horizontal"===t.get("orient")}var zE=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n._dataGroup=new vo,n._initialized=!1,n}return n(e,t),e.prototype.init=function(){this.group.add(this._dataGroup)},e.prototype.render=function(t,e,n,i){var r=this._dataGroup;this._progressiveEls=[],r.removeAll();var o=t.getData(),a=this._data,s=t.coordinateSystem,l=s.dimensions,u=GE(t);if(o.diff(a).add(function(t){FE(VE(o,r,t,l,s),o,t,u)}).update(function(e,n){var i=a.getItemGraphicEl(n);r.add(i);var c=BE(o,e,l,s);o.setItemGraphicEl(e,i),rd(i,{shape:{points:c}},t,e),cd(i),FE(i,o,e,u)}).remove(function(t){var e=a.getItemGraphicEl(t);r.remove(e)}).execute(),!this._initialized){this._initialized=!0;var c=function(t,e,n){var i=t.model,r=t.getRect(),o=new lu({shape:{x:r.x,y:r.y,width:r.width,height:r.height}}),a="horizontal"===i.get("layout")?"width":"height";return o.setShape(a,0),od(o,{shape:{width:r.width,height:r.height}},e,n),o}(s,t,function(){setTimeout(function(){r.removeClipPath()})});r.setClipPath(c)}this._data=o},e.prototype.incrementalPrepareRender=function(t,e,n){this._initialized=!0,this._data=null,this._dataGroup.removeAll()},e.prototype.incrementalRender=function(t,e,n){for(var i=e.getData(),r=e.coordinateSystem,o=this._progressiveEls=[],a=t.start;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&&KE(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 KE(t,e){var n=t._model;return n.get("axisExpandable")&&n.get("axisExpandTriggerOn")===e}var $E="parallel",JE=$E,QE=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&&D(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){B(["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=[];B(F(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=JE,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}(lg),tz=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}(SM);function ez(t,e,n,i,r,o){t=t||0;var a=jo(n[1],-n[0]);if(null!=r&&(r=iz(r,[0,a])),null!=o&&(o=Math.max(o,null!=r?r:0)),"all"===i){var s=Math.abs(jo(e[1],-e[0]));s=iz(s,[0,a]),r=o=iz(s,[r,o]),i=0}e[0]=iz(e[0],n),e[1]=iz(e[1],n);var l=nz(e,i);e[i]+=t;var u,c=r||0,h=n.slice();return l.sign<0?h[0]=jo(h[0],c):h[1]=jo(h[1],-c),e[i]=iz(e[i],h),u=nz(e,i),null!=r&&(u.sign!==l.sign||u.spano&&(e[1-i]=jo(e[i],u.sign*o)),e}function nz(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 iz(t,e){return Math.min(null!=e[1]?e[1]:1/0,Math.max(null!=e[0]?e[0]:-1/0,t))}var rz=function(){function t(t,e,n){this.type=$E,this._axesMap=mt(),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;B(i,function(t,n){var i=r[n],o=e.getComponent("parallelAxis",i),a=Hw(o),s=this._axesMap.set(t,new tz(t,Ww(o,a,!1),[0,0],a,i));s.onBand=eS(s.scale,o),s.inverse=o.get("inverse"),o.axis=s,s.model=o,s.coordinateSystem=o.coordinateSystem=this},this)},t.prototype.update=function(t,e){B(this.dimensions,function(t){var e=this._axesMap.get(t);CS(e,1),RS(e)},this)},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.resize=function(t,e){var n=eg(t,e).refContainer;this._rect=Jf(t.getBoxLayoutParams(),n),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,c=oz(e.get("axisExpandWidth"),l),h=oz(e.get("axisExpandCount")||0,[0,u]),d=e.get("axisExpandable")&&u>3&&u>h&&h>1&&c>0&&s>0,p=e.get("axisExpandWindow");p?(t=oz(p[1]-p[0],l),p[1]=p[0]+t):(t=oz(c*(h-1),l),(p=[c*(e.get("axisExpandCenter")||Lo(u/2))-t/2])[1]=p[0]+t);var f=(s-t)/(u-h);f<3&&(f=0);var g=[Lo(Ho(p[0]/c,1))+1,Po(Ho(p[1]/c,1))-1],v=f/c*p[0];return{layout:o,pixelDimIndex:a,layoutBase:n[i[a]],layoutLength:s,axisBase:n[i[1-a]],axisLength:n[r[1-a]],axisExpandable:d,axisExpandWidth:c,axisCollapseWidth:f,axisExpandWindow:p,axisCount:u,winInnerIndices:g,axisExpandWindow0Pos:v}},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])}),B(n,function(e,n){var o=(i.axisExpandable?sz:az)(n,i),a={horizontal:{x:o.position,y:i.axisLength},vertical:{x:0,y:o.position}},s={horizontal:Eo/2,vertical:0},l=[a[r].x+t.x,a[r].y+t.y],u=s[r],c=[1,0,0,1,0,0];Ce(c,c,u),Te(c,c,l),this._axesLayout[e]={position:l,rotation:u,transform:c,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=[];B(o,function(e){a.push(t.mapDimension(e)),s.push(r.get(e).model)});for(var l=this.hasAxisBrushed(),u=n;ur*(1-c[0])?(l="jump",a=s-r*(1-c[2])):(a=s-r*c[1])>=0&&(a=s-r*(1-c[1]))<=0&&(a=0),(a*=e.axisExpandWidth/u)?ez(a,i,o,"all"):l="none";else{var d=i[1]-i[0];(i=[Do(0,o[1]*s/d-d/2)])[1]=Co(o[1],i[0]+d),i[0]=i[1]-d}return{axisExpandWindow:i,behavior:l}},t}();function oz(t,e){return Co(Do(t,e[0]),e[1])}function az(t,e){var n=e.layoutLength/(e.axisCount-1);return{position:n*t,axisNameAvailableWidth:n,axisLabelShow:!0}}function sz(t,e){var n,i,r=e.layoutLength,o=e.axisExpandWidth,a=e.axisCount,s=e.axisCollapseWidth,l=e.winInnerIndices,u=s,c=!1;return t=0;n--)Wo(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&&Dz(t);var l=C(s);l.brushType=Yz(l.brushType,a),l.panelId=a===cz?null:a.panelId,o=t._creatingCover=_z(t,l),t._covers.push(o)}if(o){var u=jz[Yz(t._brushType,a)];o.__brushOption.range=u.getCreatingRange(Fz(t,o,t._track)),i&&(bz(t,o),u.updateCommon(t,o)),wz(t,o),r={isEnd:i}}}else i&&"single"===s.brushMode&&s.removeOnClick&&Tz(t,e,n)&&Dz(t)&&(r={isEnd:i,removeOnClick:!0});return r}function Yz(t,e){return"auto"===t?e.defaultBrushType:t}var Xz={mousedown:function(t){if(this._dragging)Zz(this,t);else if(!t.target||!t.target.draggable){Hz(t);var e=this.group.transformCoordToLocal(t.offsetX,t.offsetY);this._creatingCover=null,(this._creatingPanel=Tz(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=Tz(t,e,n);if(!t._dragging)for(var a=0;a=0&&(o[r[a].depth]=new kp(r[a],this,e));var s=vN(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 Ty("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 Ty("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.prototype.__ownRoamView=function(){return this.coordinateSystem},e.type="series."+rB,e.layoutMode="box",e.defaultOption={z:2,coordinateSystemUsage:"box",left:"5%",top:"5%",right:"20%",bottom:"5%",orient:"horizontal",nodeWidth:20,nodeGap:8,draggable:!0,layoutIterations:32,roam:!1,roamTrigger:"global",center:null,zoom:1,label:{show:!0,position:"right",fontSize:12},edgeLabel:{show:!1,fontSize:12},levels:[],nodeAlign:"justify",lineStyle:{color:ug.color.neutral50,opacity:.2,curveness:.5},emphasis:{label:{show:!0},lineStyle:{opacity:.5}},select:{itemStyle:{borderColor:ug.color.primary}},animationEasing:"linear",animationDuration:1e3},e}(Hy),aB=function(){this.x1=0,this.y1=0,this.x2=0,this.y2=0,this.cpx1=0,this.cpy1=0,this.cpx2=0,this.cpy2=0,this.extent=0},sB=function(t){function e(e){return t.call(this,e)||this}return n(e,t),e.prototype.getDefaultShape=function(){return new aB},e.prototype.buildPath=function(t,e){var n=e.extent;t.moveTo(e.x1,e.y1),t.bezierCurveTo(e.cpx1,e.cpy1,e.cpx2,e.cpy2,e.x2,e.y2),"vertical"===e.orient?(t.lineTo(e.x2+n,e.y2),t.bezierCurveTo(e.cpx2+n,e.cpy2,e.cpx1+n,e.cpy1,e.x1+n,e.y1)):(t.lineTo(e.x2,e.y2+n),t.bezierCurveTo(e.cpx2,e.cpy2+n,e.cpx1,e.cpy1+n,e.x1,e.y1+n)),t.closePath()},e.prototype.highlight=function(){vc(this)},e.prototype.downplay=function(){yc(this)},e}(Kl),lB=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.type=rB,e._mainGroup=new vo,e}return n(e,t),e.prototype.init=function(t,e){this._controller=new uL(e.getZr()),this.group.add(this._mainGroup),this._firstRender=!0},e.prototype.render=function(t,e,n){var i=t.getGraph(),r=this._mainGroup,o=t.layoutInfo,a=o.width,s=o.height,l=t.getData(),u=t.getData("edge"),c=t.get("orient");r.removeAll(),r.x=o.x,r.y=o.y,this._updateViewCoordSys(t,n),FP(t,n,this._controller,HP(r),null),i.eachEdge(function(e){var n=new sB,i=Iu(n);i.dataIndex=e.dataIndex,i.seriesIndex=t.seriesIndex,i.dataType="edge";var o,l,h,d,p,f,g,v,y=e.getModel(),m=y.getModel("lineStyle"),x=m.get("curveness"),_=e.node1.getLayout(),b=e.node1.getModel(),w=b.get("localX"),S=b.get("localY"),M=e.node2.getLayout(),I=e.node2.getModel(),T=I.get("localX"),C=I.get("localY"),D=e.getLayout();n.shape.extent=Math.max(1,D.dy),n.shape.orient=c,"vertical"===c?(o=(null!=w?w*a:_.x)+D.sy,l=(null!=S?S*s:_.y)+_.dy,h=(null!=T?T*a:M.x)+D.ty,p=o,f=l*(1-x)+(d=null!=C?C*s:M.y)*x,g=h,v=l*x+d*(1-x)):(o=(null!=w?w*a:_.x)+_.dx,l=(null!=S?S*s:_.y)+D.sy,p=o*(1-x)+(h=null!=T?T*a:M.x)*x,f=l,g=o*x+h*(1-x),v=d=(null!=C?C*s:M.y)+D.ty),n.setShape({x1:o,y1:l,x2:h,y2:d,cpx1:p,cpy1:f,cpx2:g,cpy2:v}),n.useStyle(m.getItemStyle()),uB(n.style,c,e);var A=""+y.get("value"),k=ap(y,"edgeLabel");op(n,k,{labelFetcher:{getFormattedLabel:function(e,n,i,r,o,a){return t.getFormattedLabel(e,n,"edge",r,st(o,k.normal&&k.normal.get("formatter"),A),a)}},labelDataIndex:e.dataIndex,defaultText:A}),n.setTextConfig({position:"inside"});var L=y.getModel("emphasis");Rc(n,y,"lineStyle",function(t){var n=t.getItemStyle();return uB(n,c,e),n}),r.add(n),u.setItemGraphicEl(e.dataIndex,n);var P=L.get("focus");kc(n,"adjacency"===P?e.getAdjacentDataIndices():"trajectory"===P?e.getTrajectoryDataIndices():P,L.get("blurScope"),L.get("disabled"))}),i.eachNode(function(e){var n=e.getLayout(),i=e.getModel(),o=i.get("localX"),u=i.get("localY"),c=i.getModel("emphasis"),h=i.get(["itemStyle","borderRadius"])||0,d=new lu({shape:{x:null!=o?o*a:n.x,y:null!=u?u*s:n.y,width:n.dx,height:n.dy,r:h},style:i.getModel("itemStyle").getItemStyle(),z2:10});op(d,ap(i),{labelFetcher:{getFormattedLabel:function(e,n){return t.getFormattedLabel(e,n,"node")}},labelDataIndex:e.dataIndex,defaultText:e.id}),d.disableLabelAnimation=!0,d.setStyle("fill",e.getVisual("color")),d.setStyle("decal",e.getVisual("style").decal),Rc(d,i),r.add(d),l.setItemGraphicEl(e.dataIndex,d),Iu(d).dataType="node";var p=c.get("focus");kc(d,"adjacency"===p?e.getAdjacentDataIndices():"trajectory"===p?e.getTrajectoryDataIndices():p,c.get("blurScope"),c.get("disabled"))}),l.eachItemGraphicEl(function(e,i){l.getItemModel(i).get("draggable")&&(e.drift=function(e,r){this.shape.x+=e,this.shape.y+=r,this.dirty(),n.dispatchAction({type:"dragNode",seriesId:t.id,dataIndex:l.getRawIndex(i),localX:this.shape.x/a,localY:this.shape.y/s})},e.draggable=!0,e.cursor="move")}),!this._data&&t.isAnimationEnabled()&&r.setClipPath(function(t,e,n){var i=new lu({shape:{x:t.x-10,y:t.y-10,width:0,height:t.height+20}});return od(i,{shape:{width:t.width+20}},e,n),i}(r.getBoundingRect(),t,function(){r.removeClipPath()})),this._data=t.getData(),this._firstRender=!1},e.prototype.__updateOnOwnRoam=function(t,e,n){CP(this.group,2,e.coordinateSystem,null)},e.prototype.dispose=function(){this._controller&&this._controller.dispose()},e.prototype._updateViewCoordSys=function(t,e){var n=t.layoutInfo,i=t.coordinateSystem=ZP(t,e,n.x,n.y,n.width,n.height);CP(this.group,2,i,this._firstRender?null:t)},e.type=rB,e}(tm);function uB(t,e,n){switch(t.fill){case"source":t.fill=n.node1.getVisual("color"),t.decal=n.node1.getVisual("style").decal;break;case"target":t.fill=n.node2.getVisual("color"),t.decal=n.node2.getVisual("style").decal;break;case"gradient":var i=n.node1.getVisual("color"),r=n.node2.getVisual("color");j(i)&&j(r)&&(t.fill=new Hh(0,0,+("horizontal"===e),+("vertical"===e),[{color:i,offset:0},{color:r,offset:1}]))}}var cB=os(rB,function(t,e){t.eachSeriesByType(rB,function(t){var n=t.get("nodeWidth"),i=t.get("nodeGap"),r=eg(t,e).refContainer,o=Jf(t.getBoxLayoutParams(),r);t.layoutInfo=o;var a=o.width,s=o.height,l=t.getGraph(),u=l.nodes,c=l.edges;!function(t){B(t,function(t){var e=_B(t.outEdges,xB),n=_B(t.inEdges,xB),i=t.getValue()||0,r=Math.max(e,n,i);t.setLayout({value:r},!0)})}(u),function(t,e,n,i,r,o,a,s,l){(function(t,e,n,i,r,o,a){for(var s=[],l=[],u=[],c=[],h=0,d=0;d=0;y&&v.depth>p&&(p=v.depth),g.setLayout({depth:y?v.depth:h},!0),"vertical"===o?g.setLayout({dy:n},!0):g.setLayout({dx:n},!0);for(var m=0;mh-1?p:h-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--)pB(s,l*=.99,a),dB(s,r,n,i,a),bB(s,l,a),dB(s,r,n,i,a)}(t,e,o,r,i,a,s),function(t,e){var n="vertical"===e?"x":"y";B(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]})}),B(t,function(t){var e=0,n=0;B(t.outEdges,function(t){t.setLayout({sy:e},!0),e+=t.getLayout().dy}),B(t.inEdges,function(t){t.setLayout({ty:n},!0),n+=t.getLayout().dy})})}(t,s)}(u,c,n,i,a,s,0!==F(u,function(t){return 0===t.getLayout().value}).length?0:t.get("layoutIterations"),t.get("orient"),t.get("nodeAlign"))})});function hB(t){var e=t.hostGraph.data.getRawDataItem(t.dataIndex);return null!=e.depth&&e.depth>=0}function dB(t,e,n,i,r){var o="vertical"===r?"x":"y";B(t,function(t){var a,s,l;t.sort(function(t,e){return t.getLayout()[o]-e.getLayout()[o]});for(var u=0,c=t.length,h="vertical"===r?"dx":"dy",d=0;d0&&(a=s.getLayout()[o]+l,"vertical"===r?s.setLayout({x:a},!0):s.setLayout({y:a},!0)),u=s.getLayout()[o]+s.getLayout()[h]+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(d=c-2;d>=0;--d)(l=(s=t[d]).getLayout()[o]+s.getLayout()[h]+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 pB(t,e,n){B(t.slice().reverse(),function(t){B(t,function(t){if(t.outEdges.length){var i=_B(t.outEdges,fB,n)/_B(t.outEdges,xB);if(isNaN(i)){var r=t.outEdges.length;i=r?_B(t.outEdges,gB,n)/r:0}if("vertical"===n){var o=t.getLayout().x+(i-mB(t,n))*e;t.setLayout({x:o},!0)}else{var a=t.getLayout().y+(i-mB(t,n))*e;t.setLayout({y:a},!0)}}})})}function fB(t,e){return mB(t.node2,e)*t.getValue()}function gB(t,e){return mB(t.node2,e)}function vB(t,e){return mB(t.node1,e)*t.getValue()}function yB(t,e){return mB(t.node1,e)}function mB(t,e){return"vertical"===e?t.getLayout().x+t.getLayout().dx/2:t.getLayout().y+t.getLayout().dy/2}function xB(t){return t.getValue()}function _B(t,e,n){for(var i=0,r=t.length,o=-1;++oo&&(o=e)}),B(n,function(e){var n=new ZR({type:"color",mappingMethod:"linear",dataExtent:[r,o],visual:t.get("color")}).mapValueToVisual(e.getLayout().value),i=e.getModel().get(["itemStyle","color"]);null!=i?(e.setVisual("color",i),e.setVisual("style",{fill:i})):(e.setVisual("color",n),e.setVisual("style",{fill:n}))})}i.length&&B(i,function(t){var e=t.getModel().get("lineStyle");t.setVisual("style",e)})})});var SB=function(){function t(){}return t.prototype._hasEncodeRule=function(t){var e=this.getEncode();return e&&null!=e.get(t)},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"),l=t.layout;"category"===a?(l="horizontal",n=r.getOrdinalMeta(),i=!this._hasEncodeRule("x")):"category"===s&&(l="vertical",n=o.getOrdinalMeta(),i=!this._hasEncodeRule("y")),l||(l="time"===s?"vertical":"horizontal"),this._layout=l;var u=["x","y"],c="horizontal"===l?0:1,h=this._baseAxisDim=u[c],d=u[1-c],p=[r,o],f=p[c].get("type"),g=p[1-c].get("type"),v=t.data;if(v&&i){var y=[];B(v,function(t,e){var n;X(t)?(n=t.slice(),t.unshift(e)):X(t.value)?((n=k({},t)).value=n.value.slice(),t.value.unshift(e)):n=t,y.push(n)}),t.data=y}var m=this.defaultValueDimensions,x=[{name:h,type:bb(f),ordinalMeta:n,otherDims:{tooltip:!1,itemName:0},dimsDef:["base"]},{name:d,type:bb(g),dimsDef:m.slice()}];return bA(this,{coordDimensions:x,dimensionsCount:m.length+1,encodeDefaulter:Y(wg,x,this)})},t.prototype.getBaseAxis=function(){var t=this._baseAxisDim;return this.ecModel.getComponent(t+"Axis",this.get(t+"AxisIndex")).axis},t.prototype.getWhiskerBoxesLayout=function(){return this._layout},t}();function MB(t,e){for(var n=e.ends.length,i=0,r=0;rg){var _=[y,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 EB="candlestick",zB=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."+EB,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",borderColorDoji:null,borderWidth:1},emphasis:{itemStyle:{borderWidth:2}},barMaxWidth:null,barMinWidth:null,barWidth:null,large:!0,largeThreshold:600,progressive:3e3,progressiveThreshold:1e4,progressiveChunkMode:"mod",animationEasing:"linear",animationDuration:300},e}(Hy);E(zB,SB,!0);var BB=["itemStyle","borderColor"],VB=["itemStyle","borderColor0"],GB=["itemStyle","borderColorDoji"],FB=["itemStyle","color"],HB=["itemStyle","color0"];function WB(t,e){return e.get(t>0?FB:HB)}function UB(t,e){return e.get(0===t?GB:t>0?BB:VB)}var YB={seriesType:EB,plan:$y(),performRawSeries:!0,reset:function(t,e){if(!e.isSeriesFiltered(t))return!t.pipelineContext.large&&{progress:function(t,e){for(var n;null!=(n=t.next());){var i=e.getItemModel(n),r=e.getItemLayout(n).sign,o=i.getItemStyle();o.fill=WB(r,i),o.stroke=UB(r,i)||o.fill,k(e.ensureUniqueItemVisual(n,"style"),o)}}}}},XB=["color","borderColor"],ZB=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){Hd(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(),l=o&&xC(a,!1,t);this._data||i.removeAll();var u=QB(t);e.diff(n).add(function(n){if(e.hasValue(n)){var a=e.getItemLayout(n),c=o?MB(s,a):0;if(2===c)return;var h=KB(a,n,u,!0);od(h,{shape:{points:a.ends}},t,n),_C(1===c,h,l),$B(h,e,n,r),i.add(h),e.setItemGraphicEl(n,h)}}).update(function(a,c){var h=n.getItemGraphicEl(c);if(e.hasValue(a)){var d=e.getItemLayout(a),p=o?MB(s,d):0;2!==p?(h?(rd(h,{shape:{points:d.ends}},t,a),cd(h)):h=KB(d,a,u),$B(h,e,a,r),_C(1===p,h,l),i.add(h),e.setItemGraphicEl(a,h)):i.remove(h)}else i.remove(h)}).remove(function(t){var e=n.getItemGraphicEl(t);e&&i.remove(e)}).execute(),this._data=e},e.prototype._renderLarge=function(t){this._clear(),nV(t,this.group);var e=t.get("clip",!0)?xC(t.coordinateSystem,!1,t):null;_C(!!e,this.group,e)},e.prototype._incrementalRenderNormal=function(t,e){for(var n,i=e.getData(),r=i.getLayout("isSimpleBox"),o=QB(e);null!=(n=t.next());){var a=KB(i.getItemLayout(n),n,o);$B(a,i,n,r),a.incremental=is(e),this.group.add(a),this._progressiveEls.push(a)}},e.prototype._incrementalRenderLarge=function(t,e){nV(e,this.group,this._progressiveEls,!0)},e.prototype.remove=function(t){this._clear()},e.prototype._clear=function(){this.group.removeAll(),_C(!1,this.group,null),this._data=null},e.type=EB,e}(tm),jB=function(){},qB=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 jB},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}(Kl);function KB(t,e,n,i){var r=t.ends;return new qB({shape:{points:i?JB(r,n,t):r},z2:100})}function $B(t,e,n,i){var r=e.getItemModel(n);t.useStyle(e.getItemVisual(n,"style")),t.style.strokeNoScale=!0;var o=r.getShallow("cursor");o&&t.attr("cursor",o),t.__simpleBox=i,Rc(t,r);var a=e.getItemLayout(n).sign;B(t.states,function(t,e){var n=r.getModel(e),i=WB(a,n),o=UB(a,n)||i,s=t.style||(t.style={});i&&(s.fill=i),o&&(s.stroke=o)});var s=r.getModel("emphasis");kc(t,s.get("focus"),s.get("blurScope"),s.get("disabled"))}function JB(t,e,n){return V(t,function(t){return(t=t.slice())[e]=n.initBaseline,t})}function QB(t){return"horizontal"===t.getWhiskerBoxesLayout()?1:0}var tV=function(){},eV=function(t){function e(e){var n=t.call(this,e)||this;return n.type="largeCandlestickBox",n}return n(e,t),e.prototype.getDefaultShape=function(){return new tV},e.prototype.buildPath=function(t,e){for(var n=e.points,i=0;ig?b[o]:_[o],ends:M,brushRect:D(v,y,p)})}function T(t,n){var i=[];return i[r]=n,i[o]=t,isNaN(n)||isNaN(t)?[NaN,NaN]:e.dataToPoint(i)}function C(t,e,n){var o=e.slice(),a=e.slice();o[r]=Id(o[r]+i/2,1,!1),a[r]=Id(a[r]-i/2,1,!0),n?t.push(o,a):t.push(a,o)}function D(t,e,n){var a=T(t,n),s=T(e,n);return a[r]-=i/2,s[r]-=i/2,{x:a[0],y:a[1],width:o?i:s[0]-a[0],height:o?s[1]-a[1]:i}}function A(t){return t[r]=Id(t[r],1),t}}}}};function sV(t,e,n,i,r,o){return n>i?-1:n0?t.get(r,e-1)<=i?1:-1:1}function lV(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 uV=function(t){function e(e,n){var i=t.call(this)||this,r=new KT(e,n),o=new vo;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 c=void 0;c=Z(u)?u(n):u,i.__t>0&&(c=-o*i.__t),this._animateSymbol(i,o,c,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 Ft(t.__p1,t.__cp1)+Ft(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=Yn,l=Xn;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),c=t.__t<=1?l(e[1],i[1],n[1],r):l(n[1],i[1],e[1],1-r);t.rotation=-Math.atan2(c,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 c=t.__t<=1?u[0]-l[0]:l[0]-u[0],h=t.__t<=1?u[1]-l[1]:l[1]-u[1];t.rotation=-Math.atan2(h,c)-Math.PI/2,this._lastFrame=o,this._lastFramePercent=e,t.ignore=!1}},e}(pV),vV=function(){this.polyline=!1,this.curveness=0,this.segs=[]},yV=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.beforeBrush=function(t){t&&!t.contentRetained&&this.reset()},e.prototype.getDefaultStyle=function(){return{stroke:ug.color.neutral99,fill:null}},e.prototype.getDefaultShape=function(){return new vV},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 h=(s+u)/2-(l-c)*r,d=(l+c)/2-(u-s)*r;t.quadraticCurveTo(h,d,u,c)}else t.lineTo(u,c)}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++],c=i[s++],h=1;h0){if(Pl(u,c,(u+d)/2-(c-p)*r,(c+p)/2-(d-u)*r,d,p,o,t,e))return a}else if(kl(u,c,d,p,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}(),xV={seriesType:"lines",plan:$y(),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,c=r.start;c0&&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)&&xC(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(),is(e)),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=this._lineDraw;if(!(this._finished&&r&&r.updateLayout))return{update:!0};var o=xV.reset(t,e,n);o.progress&&o.progress({start:0,end:i.count(),count:i.count()},i),r.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 mV:new QN(r?i?gV:fV:i?pV:JN),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=tp(t);e&&null!=this._lastZlevel&&e.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}(tm),bV="undefined"==typeof Uint32Array?Array:Uint32Array,wV="undefined"==typeof Float64Array?Array:Float64Array;function SV(t){var e=t.data;e&&e[0]&&e[0][0]&&e[0][0].coord&&(t.data=V(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),A([e,t[0],t[1]])}))}var MV=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||[],SV(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(SV(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=xt(this._flatCoords,e.flatCoords),this._flatCoordsOffset=xt(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 ")}return Ty("nameValue",{name:a,value:r,noValue:null==r||isNaN(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}(Hy);function IV(t){return t instanceof Array||(t=[t,t]),t}var TV={seriesType:"lines",reset:function(t){var e=IV(t.get("symbol")),n=IV(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=IV(n.getShallow("symbol",!0)),r=IV(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 CV=function(){function t(){this.blurSize=30,this.pointSize=20,this.maxOpacity=1,this.minOpacity=0,this._gradientPixels={inRange:null,outOfRange:null};var t=c.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,c=this.canvas,h=c.getContext("2d"),d=t.length;c.width=e,c.height=n;for(var p=0;p0){var I=o(y)?s:l;y>0&&(y=y*S+w),x[_++]=I[M],x[_++]=I[M+1],x[_++]=I[M+2],x[_++]=I[M+3]*y*256}else _+=4}return h.putImageData(m,0,0),c},t.prototype._getBrush=function(){var t=this._brushCanvas||(this._brushCanvas=c.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=ug.color.neutral99,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}();var 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.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||"matrix"===r.type?this._renderOnGridLike(t,n,0,t.getData().count()):SC(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&&(SC(r)?this.render(e,n,i):(this._progressiveEls=[],this._renderOnGridLike(e,i,t.start,t.end,!0)))},e.prototype.eachRendered=function(t){Hd(this._progressiveEls||this.group,t)},e.prototype._renderOnGridLike=function(t,e,n,i,r){var o,a,s,l,u=t.coordinateSystem,c=wC(u,"cartesian2d"),h=wC(u,"matrix");if(c){var d=u.getAxis("x"),p=u.getAxis("y");0,o=bM(d).w+.5,a=bM(p).w+.5,s=d.scale.getExtent(),l=p.scale.getExtent()}for(var f=this.group,g=t.getData(),v=t.getModel(["emphasis","itemStyle"]).getItemStyle(),y=t.getModel(["blur","itemStyle"]).getItemStyle(),m=t.getModel(["select","itemStyle"]).getItemStyle(),x=t.get(["itemStyle","borderRadius"]),_=ap(t),b=t.getModel("emphasis"),w=b.get("focus"),S=b.get("blurScope"),M=b.get("disabled"),I=c||h?[g.mapDimension("x"),g.mapDimension("y"),g.mapDimension("value")]:[g.mapDimension("time"),g.mapDimension("value")],T=n;Ts[1]||kl[1])continue;var L=u.dataToPoint([A,k]);C=new lu({shape:{x:L[0]-o/2,y:L[1]-a/2,width:o,height:a},style:D})}else if(h){if(rt((P=u.dataToLayout([g.get(I[0],T),g.get(I[1],T)]).rect).x))continue;C=new lu({z2:1,shape:P,style:D})}else{if(isNaN(g.get(I[1],T)))continue;var P,O=u.dataToLayout([g.get(I[0],T)]);if(rt((P=O.contentRect||O.rect).x)||rt(P.y))continue;C=new lu({z2:1,shape:P,style:D})}if(g.hasItemOption){var R=g.getItemModel(T),N=R.getModel("emphasis");v=N.getModel("itemStyle").getItemStyle(),y=R.getModel(["blur","itemStyle"]).getItemStyle(),m=R.getModel(["select","itemStyle"]).getItemStyle(),x=R.get(["itemStyle","borderRadius"]),w=N.get("focus"),S=N.get("blurScope"),M=N.get("disabled"),_=ap(R)}C.shape.r=x;var E=t.getRawValue(T),z="-";E&&null!=E[2]&&(z=E[2]+""),op(C,_,{labelFetcher:t,labelDataIndex:T,defaultOpacity:D.opacity,defaultText:z}),C.ensureState("emphasis").style=v,C.ensureState("blur").style=y,C.ensureState("select").style=m,kc(C,w,S,M),C.incremental=is(t,r),r&&(C.states.emphasis.hoverLayer=2),f.add(C),g.setItemGraphicEl(T,C),this._progressiveEls&&this._progressiveEls.push(C)}},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 CV;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 c=Math.max(l.x,0),h=Math.max(l.y,0),d=Math.min(l.width+l.x,i.getWidth()),p=Math.min(l.height+l.y,i.getHeight()),f=d-c,g=p-h,v=[a.mapDimension("lng"),a.mapDimension("lat"),a.mapDimension("value")],y=a.mapArray(v,function(e,n,i){var r=t.dataToPoint([e,n]);return r[0]-=c,r[1]-=h,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=V(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&&i=0?1:-1:o>0?1:-1}(n,o,r,i,h),function(t,e,n,i,r,o,a,s,l,u){var c,h=l.valueDim,d=l.categoryDim,p=Math.abs(n[d.wh]),f=t.getItemVisual(e,"symbolSize");c=X(f)?f.slice():null==f?["100%","100%"]:[f,f];c[d.index]=Vo(c[d.index],p),c[h.index]=Vo(c[h.index],i?p:Math.abs(o)),u.symbolSize=c;var g=u.symbolScale=[c[0]/s,c[1]/s];g[h.index]*=(l.isHorizontal?-1:1)*a}(t,e,r,o,0,h.boundingLength,h.pxSign,u,i,h),function(t,e,n,i,r){var o=t.get(kV)||0;o&&(PV.attr({scaleX:e[0],scaleY:e[1],rotation:n}),PV.updateTransform(),o/=PV.getLineScale(),o*=e[i.valueDim.index]);r.valueLineWidth=o||0}(n,h.symbolScale,l,i,h);var d=h.symbolSize,p=bx(n.get("symbolOffset"),d);return function(t,e,n,i,r,o,a,s,l,u,c,h){var d=c.categoryDim,p=c.valueDim,f=h.pxSign,g=Math.max(e[p.index]+s,0),v=g;if(i){var y=Math.abs(l),m=ot(t.get("symbolMargin"),"15%")+"",x=!1;m.lastIndexOf("!")===m.length-1&&(x=!0,m=m.slice(0,m.length-1));var _=Vo(m,e[p.index]),b=Math.max(g+2*_,0),w=x?0:2*_,S=aa(i),M=S?i:KV((y+w)/b);b=g+2*(_=(y-M*g)/2/(x?M:Math.max(M-1,1))),w=x?0:2*_,S||"fixed"===i||(M=u?KV((Math.abs(u)+w)/b):0),v=M*b-w,h.repeatTimes=M,h.symbolMargin=_}var I=f*(v/2),T=h.pathPosition=[];T[d.index]=n[d.wh]/2,T[p.index]="start"===a?I:"end"===a?l-I:l/2,o&&(T[0]+=o[0],T[1]+=o[1]);var C=h.bundlePosition=[];C[d.index]=n[d.xy],C[p.index]=n[p.xy];var D=h.barRectShape=k({},n);D[p.wh]=f*Math.max(Math.abs(n[p.wh]),Math.abs(T[p.index]+I)),D[d.wh]=n[d.wh];var A=h.clipShape={};A[d.xy]=-n[d.xy],A[d.wh]=c.ecSize[d.wh],A[p.xy]=0,A[p.wh]=n[p.wh]}(n,d,r,o,0,p,s,h.valueLineWidth,h.boundingLength,h.repeatCutLength,i,h),h}function NV(t,e){return t.toGlobalCoord(t.dataToCoord(t.scale.parse(e)))}function EV(t){var e=t.symbolPatternSize,n=xx(t.symbolType,-e/2,-e/2,e,e);return n.attr({culling:!0}),"image"!==n.type&&n.setStyle({strokeNoScale:!0}),n}function zV(t,e,n,i){var r=t.__pictorialBundle,o=n.symbolSize,a=n.valueLineWidth,s=n.pathPosition,l=e.valueDim,u=n.repeatTimes||0,c=0,h=o[e.valueDim.index]+a+2*n.symbolMargin;for(ZV(t,function(t){t.__pictorialAnimationIndex=c,t.__pictorialRepeatTimes=u,c0:i<0)&&(r=u-1-t),e[l.index]=h*(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 BV(t,e,n,i){var r=t.__pictorialBundle,o=t.__pictorialMainPath;o?jV(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=EV(n),r.add(o),jV(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 VV(t,e,n){var i=k({},e.barRectShape),r=t.__pictorialBarRect;r?jV(r,null,{shape:i},e,n):((r=t.__pictorialBarRect=new lu({z2:2,shape:i,silent:!0,style:{stroke:"transparent",fill:"transparent",lineWidth:0}})).disableMorphing=!0,t.add(r))}function GV(t,e,n,i){if(n.symbolClip){var r=t.__pictorialClipPath,o=k({},n.clipShape),a=e.valueDim,s=n.animationModel,l=n.dataIndex;if(r)rd(r,{shape:o},s,l);else{o[a.wh]=0,r=new lu({shape:o}),t.__pictorialBundle.setClipPath(r),t.__pictorialClipPath=r;var u={};u[a.wh]=n.clipShape[a.wh],ep[i?"updateProps":"initProps"](r,{shape:u},s,l)}}}function FV(t,e){var n=t.getItemModel(e);return n.getAnimationDelayParams=HV,n.isAnimationEnabled=WV,n}function HV(t){return{index:t.__pictorialAnimationIndex,count:t.__pictorialRepeatTimes}}function WV(){return this.parentModel.isAnimationEnabled()&&!!this.getShallow("animation")}function UV(t,e,n,i){var r=new vo,o=new vo;return r.add(o),r.__pictorialBundle=o,o.x=n.bundlePosition[0],o.y=n.bundlePosition[1],n.symbolRepeat?zV(r,e,n):BV(r,0,n),VV(r,n,i),GV(r,e,n,i),r.__pictorialShapeStr=XV(t,n),r.__pictorialSymbolMeta=n,r}function YV(t,e,n,i){var r=i.__pictorialBarRect;r&&r.removeTextContent();var o=[];ZV(i,function(t){o.push(t)}),i.__pictorialMainPath&&o.push(i.__pictorialMainPath),i.__pictorialClipPath&&(n=null),B(o,function(t){sd(t,{scaleX:0,scaleY:0},n,e,function(){i.parent&&i.parent.remove(i)})}),t.setItemGraphicEl(e,null)}function XV(t,e){return[t.getItemVisual(e.dataIndex,"symbol")||"none",!!e.symbolRepeat,!!e.symbolClip].join(":")}function ZV(t,e,n){B(t.__pictorialBundle.children(),function(i){i!==t.__pictorialBarRect&&e.call(n,i)})}function jV(t,e,n,i,r,o){e&&t.attr(e),i.symbolClip&&!r?n&&t.attr(n):n&&ep[r?"updateProps":"initProps"](t,n,i.animationModel,i.dataIndex,o)}function qV(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"),c=o.get("focus"),h=o.get("blurScope"),d=o.get("scale");ZV(t,function(t){if(t instanceof eu){var e=t.style;t.useStyle(k({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,d&&(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 p=e.valueDim.posDesc[+(n.boundingLength>0)],f=t.__pictorialBarRect;f.ignoreClip=!0,op(f,ap(r),{labelFetcher:e.seriesModel,labelDataIndex:i,defaultText:jT(e.seriesModel.getData(),i),inheritColor:n.style.fill,defaultOpacity:n.style.opacity,defaultOutsidePosition:p}),kc(t,c,h,o.get("disabled"))}function KV(t){var e=Math.round(t);return Math.abs(t-e)<1e-4?e:Math.ceil(t)}var $V=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."+OD,e.dependencies=["grid"],e.defaultOption=Op(qD.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%",clip:!1,progressive:0,emphasis:{scale:!1},select:{itemStyle:{borderColor:ug.color.primary}}}),e}(qD);var JV="themeRiver",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(e){t.prototype.init.apply(this,arguments),this.legendVisualProvider=new SA(U(this.getData,this),U(this.getRawData,this))},e.prototype.fixData=function(t){var e=t.length,n={},i=Fa(t,function(t){return n.hasOwnProperty(t[0]+"")||(n[t[0]+""]=-1),t[2]}),r=[];i.buckets.each(function(t,e){r.push({name:e,dataList:t})});for(var o=r.length,a=0;ao&&(o=s),i.push(s)}for(var u=0;uo&&(o=h)}return{y0:r,max:o}}(l),c=u.y0,h=n/u.max,d=o.length,p=o[0].indices.length,f=0;fI&&!$o(C-I)&&C0?(r.virtualPiece?r.virtualPiece.updateData(!1,i,t,e,n):(r.virtualPiece=new iG(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=c},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)Ef(a,o.get("target",!0)||"_blank")}n=!0}})})},e.prototype._rootToNode=function(t){t!==this.seriesModel.getViewRoot()&&this.api.dispatchAction({type:sG,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=rG,e}(tm),cG=os(rG,function(t){var e={};t.eachSeriesByType(rG,function(t){var n=t.getData(),i=n.tree;i.eachNode(function(r){var o=r.getModel().getModel("itemStyle").getItemStyle();o.fill||(o.fill=function(t,n,i){if(0===t.depth)return ug.color.neutral50;for(var r=t;r&&r.depth>1;)r=r.parentNode;var o=n.getColorFromPalette(r.name||r.dataIndex+"",e);return t.depth>1&&j(o)&&(o=yi(o,(t.depth-1)/(i-1)*.5)),o}(r,t,i.root.height)),k(n.ensureUniqueItemVisual(r.dataIndex,"style"),o)})})});var hG=Math.PI/180,dG=os(rG,function(t,e){t.eachSeriesByType(rG,function(t){var n=t.get("center"),i=t.get("radius");X(i)||(i=[0,i]),X(n)||(n=[n,n]);var r=e.getWidth(),o=e.getHeight(),a=Math.min(r,o),s=Vo(n[0],r),l=Vo(n[1],o),u=Vo(i[0],a/2),c=Vo(i[1],a/2),h=-t.get("startAngle")*hG,d=t.get("minAngle")*hG,p=t.getData().tree.root,f=t.getViewRoot(),g=f.depth,v=t.get("sort");null!=v&&pG(f,v);var y=0;B(f.children,function(t){!isNaN(t.getValue())&&y++});var m=f.getValue(),x=Math.PI/(m||y)*2,_=f.depth>0,b=f.height-(_?-1:1),w=(c-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!==p){var r=e.getValue(),o=0===m&&M?x:r*x;o0&&(a.during=s?U(OG,{el:e,userDuring:s}):null,a.setToFinal=!0,a.scope=t),k(a,n[o]),a}function CG(t,e,n,i){var r=(i=i||{}).dataIndex,o=i.isInit,a=i.clearStyle,s=n.isAnimationEnabled(),l=IG(t),u=e.style;l.userDuring=e.during;var c={},h={};if(function(t,e,n){for(var i=0;i=0)){var h=t.getAnimationStyleProps(),d=h?h.style:null;if(d){!r&&(r=i.style={});var p=W(n);for(u=0;u0&&t.animateFrom(g,v)}else!function(t,e,n,i,r){if(r){var o=TG("update",t,e,i,n);o.duration>0&&t.animateFrom(r,o)}}(t,e,r||0,n,c);DG(t,e),u?t.dirty():t.markRedraw()}function DG(t,e){for(var n=IG(t).leaveToProps,i=0;i=0){!o&&(o=i[t]={});var d=W(a);for(c=0;ci[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:U(bG,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)},layout:function(e,n){return t.dataToLayout(e,n)}}}},matrix:function(t){var e=t.getRect();return{coordSys:{type:"matrix",x:e.x,y:e.y,width:e.width,height:e.height},api:{coord:function(e,n){return t.dataToPoint(e,n)},layout:function(e,n){return t.dataToLayout(e,n)}}}}};function $G(t){return t instanceof Kl}function JG(t){return t instanceof Zs}var QG=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=rF(t,o,e,n);r||a.removeAll(),o.diff(r).add(function(e){aF(n,null,e,s(e,i),t,a,o)}).remove(function(e){var n=r.getItemGraphicEl(e);n&&AG(n,vG(n).option,t)}).update(function(e,l){var u=r.getItemGraphicEl(l);aF(n,u,e,s(e,i),t,a,o)}).execute();var l=t.get("clip",!0)?xC(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=rF(e,o,n,i),s=this._progressiveEls=[];function l(t){t.isGroup||(t.incremental=is(e),t.ensureState("emphasis").hoverLayer=2)}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=l);var r=x(i,FG).getItemStyle(),o=_(i,FG),a=sp(o,null,null,!0,!0);a.text=o.getShallow("show")?st(t.getFormattedLabel(i,FG),t.getFormattedLabel(i,HG),jT(e,i)):null;var s=lp(o,null,!0);return w(n,r),r=CC(r,a,s),n&&b(r,n),r.legacy=!0,r},visual:function(t,n){if(null==n&&(n=l),wt(fG,t)){var i=e.getItemVisual(n,"style");return i?i[fG[t]]:null}if(wt(gG,t))return e.getItemVisual(n,t)},barLayout:function(t){if("cartesian2d"===a.type){return function(t){if(vw(t.axis.scale)){for(var e=bM(t.axis),n=[],i=0;i=h;f--){var g=e.childAt(f);dF(e,g,r)}}(t,h,n,i,r),a>=0?o.replaceAt(h,a):o.add(h),h}function lF(t,e,n){var i,r=vG(t),o=e.type,a=e.shape,s=e.style;return n.isUniversalTransitionEnabled()||null!=o&&o!==r.customGraphicType||"path"===o&&((i=a)&&(wt(i,"pathData")||wt(i,"d")))&&vF(a)!==r.customPathData||"image"===o&&wt(s,"image")&&s.image!==r.customImagePath}function uF(t,e,n){var i=e?cF(t,e):t,r=e?hF(t,i,FG):t.style,o=t.type,a=i?i.textConfig:null,s=t.textContent,l=s?e?cF(s,e):s:null;if(r&&(n.isLegacy||MC(r,o,!!a,!!l))){n.isLegacy=!0;var u=IC(r,o,!e);!a&&u.textConfig&&(a=u.textConfig),!l&&u.textContent&&(l=u.textContent)}if(!e&&l){var c=l;!c.type&&(c.type="text")}var h=e?n[e]:n.normal;h.cfg=a,h.conOpt=l}function cF(t,e){return e?t?t[e]:null:t}function hF(t,e,n){var i=e&&e.style;return null==i&&n===FG&&t&&(i=t.styleEmphasis),i}function dF(t,e,n){e&&AG(e,vG(t).option,n)}function pF(t,e){var n=t&&t.name;return null!=n?n:"e\0\0"+e}function fF(t,e){var n=this.context,i=null!=t?n.newChildren[t]:null,r=null!=e?n.oldChildren[e]:null;sF(n.api,r,n.dataIndex,i,n.seriesModel,n.group)}function gF(t){var e=this.context,n=e.oldChildren[t];n&&AG(n,vG(n).option,e.seriesModel)}function vF(t){return t&&(t.pathData||t.d)}var yF=Pa(),mF=C,xF=U,_F=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 c=this._moveAnimation=this.determineAnimation(t,e);if(a){var h=Y(bF,e,c);this.updatePointerEl(a,l,h),this.updateLabelEl(a,l,h,e)}else a=this._group=new vo,this.createPointerEl(a,l,t,e),this.createLabelEl(a,l,t,e),n.getZr().add(a);IF(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&&bM(i).w>a)return!0;if(o){var s=mk(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=yF(t).pointerEl=new ep[r.type](mF(e.pointer));t.add(o)}},t.prototype.createLabelEl=function(t,e,n,i){if(e.label){var r=yF(t).labelEl=new du(mF(e.label));t.add(r),SF(r,i)}},t.prototype.updatePointerEl=function(t,e,n){var i=yF(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=yF(t).labelEl;r&&(r.setStyle(e.label.style),n(r,{x:e.label.x,y:e.label.y}),SF(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=Od(o.get("icon"),{cursor:"move",draggable:!0,onmousemove:function(t){ye(t.event)},onmousedown:xF(this._onHandleDragMove,this,0,0),drift:xF(this._onHandleDragMove,this),ondragend:xF(this._onHandleDragEnd,this)}),i.add(r)),IF(r,n,!1),r.setStyle(o.getItemStyle(null,["color","borderColor","borderWidth","opacity","shadowColor","shadowBlur","shadowOffsetX","shadowOffsetY"]));var s=o.get("size");X(s)||(s=[s,s]),r.scaleX=s[0]/2,r.scaleY=s[1]/2,cm(this,"_doDispatchAxisPointer",o.get("throttle")||0,"fixRate"),this._moveHandleToValue(t,e)}},t.prototype._moveHandleToValue=function(t,e){bF(this._axisPointerModel,!e&&this._moveAnimation,this._handle,MF(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(MF(n),[t,e],this._axisModel,this._axisPointerModel);this._payloadInfo=i,n.stopAnimation(),n.attr(MF(i)),yF(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),hm(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 bF(t,e,n,i){wF(yF(n).lastProp,i)||(yF(n).lastProp=i,e?rd(n,i,t):(n.stopAnimation(),n.attr(i)))}function wF(t,e){if($(t)&&$(e)){var n=!0;return B(e,function(e,i){n=n&&wF(t[i],e)}),!!n}return t===e}function SF(t,e){t[e.get(["label","show"])?"show":"hide"]()}function MF(t){return{x:t.x||0,y:t.y||0,rotation:t.rotation||0}}function IF(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 TF(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 CF(t,e,n,i,r){var o=DF(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=Df(a.get("padding")||0),l=a.getFont(),u=qr(o,l),c=r.position,h=u.width+s[1]+s[3],d=u.height+s[0]+s[2],p=r.align;"right"===p&&(c[0]-=h),"center"===p&&(c[0]-=h/2);var f=r.verticalAlign;"bottom"===f&&(c[1]-=d),"middle"===f&&(c[1]-=d/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)}(c,h,d,i);var g=a.get("backgroundColor");g&&"auto"!==g||(g=e.get(["axisLine","lineStyle","color"])),t.label={x:c[0],y:c[1],style:sp(a,{text:o,font:l,fill:a.getTextColor(),padding:s,backgroundColor:g}),z2:10}}function DF(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:jw(e,{value:t}),axisDimension:e.dim,axisIndex:e.index,seriesData:[]};B(i,function(t){var e=n.getSeriesByIndex(t.seriesIndex),i=t.dataIndexInside,r=e&&e.getDataParams(i);r&&s.seriesData.push(r)}),j(a)?o=a.replace("{value}",o):Z(a)&&(o=a(s))}return o}function AF(t,e,n){var i=[1,0,0,1,0,0];return Ce(i,i,n.rotation),Te(i,i,n.position),Cd([t.dataToCoord(e),(n.labelOffset||0)+(n.labelDirection||1)*(n.labelMargin||0)],i)}function kF(t,e,n,i,r,o){var a=dD.innerTextLayout(n.rotation,0,n.labelDirection);n.labelMargin=r.get(["label","margin"]),CF(e,i,r,o,{position:AF(i.axis,t,n),align:a.textAlign,verticalAlign:a.textVerticalAlign})}function LF(t,e,n){return{x1:t[n=n||0],y1:t[1-n],x2:e[n],y2:e[1-n]}}function PF(t,e,n){return{x:t[n=n||0],y:t[1-n],width:e[n],height:e[1-n]}}function OF(t,e,n,i,r,o){return{cx:t,cy:e,r0:n,r:i,startAngle:r,endAngle:o,clockwise:!0}}function RF(t,e,n){return bM(t,{fromStat:{sers:V(e,function(t){return n.getSeriesByIndex(t.seriesIndex)})},min:1}).w}function NF(t,e,n){return[Do(Co(e[0],e[1]),t-n/2),Co(t+n/2,Do(e[0],e[1]))]}var EF=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=o.getGlobalExtent(),u=zF(a,o).getOtherAxis(o).getGlobalExtent(),c=o.toGlobalCoord(o.dataToCoord(e,!0));if(s&&"none"!==s){var h=TF(i),d=BF[s](o,c,l,u,i.get("seriesDataIndices"),i.ecModel);d.style=h,t.graphicKey=d.type,t.pointer=d}kF(e,t,MD(a.getRect(),n),n,i,r)},e.prototype.getHandleTransform=function(t,e,n){var i=MD(e.axis.grid.getRect(),e,{labelInside:!1});i.labelMargin=n.get(["handle","margin"]);var r=AF(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=zF(o,r).getOtherAxis(r).getGlobalExtent(),l="x"===r.dim?0:1,u=[t.x,t.y];u[l]+=e[l],u[l]=Co(a[1],u[l]),u[l]=Do(a[0],u[l]);var c=(s[1]+s[0])/2,h=[c,c];h[l]=u[l];return{x:u[0],y:u[1],rotation:t.rotation,cursorPoint:h,tooltipOption:[{verticalAlign:"middle"},{align:"center"}][l]}},e}(_F);function zF(t,e){var n={};return n[e.dim+"AxisIndex"]=e.index,t.getCartesian(n)}var BF={line:function(t,e,n,i){return{type:"Line",subPixelOptimize:!0,shape:LF([e,i[0]],[e,i[1]],VF(t))}},shadow:function(t,e,n,i,r,o){var a=RF(t,r,o),s=i[1]-i[0],l=NF(e,n,a),u=l[0],c=l[1];return{type:"Rect",shape:PF([u,i[0]],[c-u,s],VF(t))}}};function VF(t){return"x"===t.dim?0:1}var 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.type="axisPointer",e.defaultOption={show:"auto",z:50,type:"line",snap:!1,triggerTooltip:!0,triggerEmphasis:!0,value:null,status:null,link:[],animation:null,animationDurationUpdate:200,lineStyle:{color:ug.color.border,width:1,type:"dashed"},shadowStyle:{color:ug.color.shadowTint},label:{show:!0,formatter:null,precision:"auto",margin:3,color:ug.color.neutral00,padding:[5,7,5,7],backgroundColor:ug.color.accent60,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:ug.color.accent40,throttle:40}},e}(lg),FF=Pa(),HF=B;function WF(t,e,n){if(!r.node){var i=e.getZr();FF(i).records||(FF(i).records={}),function(t,e){if(FF(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);HF(FF(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)})}FF(t).initialized=!0,n("click",Y(YF,"click")),n("mousemove",Y(YF,"mousemove")),n("mousewheel",Y(YF,"mousewheel")),n("globalout",UF)}(i,e),(FF(i).records[t]||(FF(i).records[t]={})).handler=n}}function UF(t,e,n){t.handler("leave",null,n)}function YF(t,e,n,i){e.handler(t,n,i)}function XF(t,e){if(!r.node){var n=e.getZr();(FF(n).records||{})[t]&&(FF(n).records[t]=null)}}var ZF=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|mousewheel";WF("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){XF("axisPointer",e)},e.prototype.dispose=function(t,e){XF("axisPointer",e)},e.type="axisPointer",e}(Ky);function jF(t,e){var n,i=[],r=t.seriesIndex;if(null==r||!(n=e.getSeriesByIndex(r)))return{point:[]};var o=n.getData(),a=La(o,t);if(null==a||a<0||X(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(),c=l.getOtherAxis(u).dim,h=u.dim,d="x"===c||"radius"===c?1:0,p=o.mapDimension(h),f=[];f[d]=o.get(p,a),f[1-d]=o.get(o.getCalculationInfo("stackResultDimension"),a),i=l.dataToPoint(f)||[]}else i=l.dataToPoint(o.getValues(V(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 qF=Pa();function KF(t,e,n){var i=t.currTrigger,r=[t.x,t.y],o=t,a=t.dispatchAction||U(n.dispatchAction,n),s=e.getComponent("axisPointer").coordSysAxesInfo;if(s){eH(r)&&(r=jF({seriesIndex:o.seriesIndex,dataIndex:o.dataIndex},e).point);var l=eH(r),u=o.axesInfo,c=s.axesInfo,h="leave"===i||eH(r),d={},p={},f={list:[],map:{}},g={showPointer:Y(JF,p),showTooltip:Y(QF,f)};B(s.coordSysMap,function(t,e){var n=l||t.containPoint(r);B(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(!h&&n&&(!u||o)){var a=o&&o.value;null!=a||l||(a=i.pointToData(r)),null!=a&&$F(t,a,g,!1,d)}})});var v={};return B(c,function(t,e){var n=t.linkGroup;n&&!p[e]&&B(n.axesInfo,function(e,i){var r=p[i];if(e!==t&&r){var o=r.value;n.mapper&&(o=t.axis.scale.parse(n.mapper(o,tH(e),tH(t)))),v[t.key]=o}})}),B(v,function(t,e){$F(c[e],t,g,!0,d)}),function(t,e,n){var i=n.axesInfo=[];B(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})})}(p,c,d),function(t,e,n,i){if(eH(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=qF(i)[r]||{},a=qF(i)[r]={};B(t,function(t,e){var n=t.axisPointerModel.option;"show"===n.status&&t.triggerEmphasis&&B(n.seriesDataIndices,function(t){a[t.seriesIndex+"|"+t.dataIndex]=t})});var s=[],l=[];function u(t){return{seriesIndex:t.seriesIndex,dataIndex:t.dataIndex}}B(o,function(t,e){!a[e]&&l.push(u(t))}),B(a,function(t,e){!o[e]&&s.push(u(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})}(c,0,n),d}}function $F(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 B(e.seriesModels,function(e,l){var u,c,h=e.getData().mapDimensionsAll(i);if(e.getAxisTooltipData){var d=e.getAxisTooltipData(h,t,n);c=d.dataIndices,u=d.nestestValue}else{if(!(c=e.indicesOfNearest(i,h[0],t,"category"===n.type?.5:null)).length)return;u=e.getData().get(h[0],c[0])}if(ca(u)){var p=t-u,f=Math.abs(p);f<=a&&((f=0&&s<0)&&(a=f,s=p,r=u,o.length=0),B(c,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&&k(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 JF(t,e,n,i){t[e.key]={value:n,payloadBatch:i}}function QF(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=_k(l),c=t.map[u];c||(c=t.map[u]={coordSysId:l.id,coordSysIndex:l.componentIndex,coordSysType:l.type,coordSysMainType:l.mainType,dataByAxis:[]},t.list.push(c)),c.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 tH(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 eH(t){return!t||null==t[0]||isNaN(t[0])||null==t[1]||isNaN(t[1])}function nH(t){wk.registerAxisPointerClass("CartesianAxisPointer",EF),t.registerComponentModel(GF),t.registerComponentView(ZF),t.registerPreprocessor(function(t){if(t){(!t.axisPointer||0===t.axisPointer.length)&&(t.axisPointer={});var e=t.axisPointer.link;e&&!X(e)&&(t.axisPointer.link=[e])}}),t.registerProcessor(t.PRIORITY.PROCESSOR.STATISTIC,{overallReset:function(t,e){t.getComponent("axisPointer").coordSysAxesInfo=vk(t,e)}}),t.registerAction({type:"updateAxisPointer",event:"updateAxisPointer",update:":updateAxisPointer"},KF)}var iH=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=o.getExtent(),l=a.getOtherAxis(o).getExtent(),u=o.dataToCoord(e),c=i.get("type");if(c&&"none"!==c){var h=TF(i),d=rH[c](o,a,u,s,l,i.get("seriesDataIndices"),i.ecModel);d.style=h,t.graphicKey=d.type,t.pointer=d}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,c,h=i.getRadiusAxis().getExtent();if("radius"===o.dim){var d=[1,0,0,1,0,0];Ce(d,d,s),Te(d,d,[i.cx,i.cy]),l=Cd([a,-r],d);var p=e.getModel("axisLabel").get("rotate")||0,f=dD.innerTextLayout(s,p*Math.PI/180,-1);u=f.textAlign,c=f.textVerticalAlign}else{var g=h[1];l=i.coordToPoint([g+r,a]);var v=i.cx,y=i.cy;u=Math.abs(l[0]-v)/g<.3?"center":l[0]>v?"left":"right",c=Math.abs(l[1]-y)/g<.3?"middle":l[1]>y?"top":"bottom"}return{position:l,align:u,verticalAlign:c}}(e,n,0,a,i.get(["label","margin"]));CF(t,n,i,r,p)},e}(_F);var rH={line:function(t,e,n,i,r){return"angle"===t.dim?{type:"Line",shape:LF(e.coordToPoint([r[0],n]),e.coordToPoint([r[1],n]))}:{type:"Circle",shape:{cx:e.cx,cy:e.cy,r:n}}},shadow:function(t,e,n,i,r,o,a){var s,l=Math.PI/180,u=RF(t,o,a);if("angle"===t.dim)s=OF(e.cx,e.cy,r[0],r[1],(-n-u/2)*l,(u/2-n)*l);else{var c=NF(n,i,u),h=c[0],d=c[1];s=OF(e.cx,e.cy,h,d,0,2*Math.PI)}return{type:"Sector",shape:s}}},oH="polar",aH=oH,sH=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=oH,e.dependencies=["radiusAxis","angleAxis"],e.defaultOption={z:0,center:["50%","50%"],radius:"80%"},e}(lg),lH=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.getCoordSysModel=function(){return this.getReferringComponents("polar",Ea).models[0]},e.type="polarAxis",e}(lg);E(lH,nS);var uH=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}(lH),cH=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}(lH),hH=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}(SM);hH.prototype.dataToRadius=SM.prototype.dataToCoord,hH.prototype.radiusToData=SM.prototype.coordToData;var dH=Pa(),pH=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=qr(null==o?"":o+"",e.getFont(),"center","top"),u=Math.max(l.height,7)/s;isNaN(u)&&(u=1/0);var c=Math.max(0,Math.floor(u)),h=dH(t.model),d=h.lastAutoInterval,p=h.lastTickCount;return null!=d&&null!=p&&Math.abs(d-c)<=1&&Math.abs(p-r)<=1&&d>c?c=d:(h.lastTickCount=r,h.lastAutoInterval=c),c},e}(SM);pH.prototype.dataToAngle=SM.prototype.dataToCoord,pH.prototype.angleToData=SM.prototype.coordToData;var fH=["radius","angle"],gH=function(){function t(t){this.dimensions=fH,this.type=oH,this.cx=0,this.cy=0,this._radiusAxis=new hH,this._angleAxis=new pH,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,n){return this.coordToPoint([this._radiusAxis.dataToRadius(t[0],e),this._angleAxis.dataToAngle(t[1],e)],n)},t.prototype.pointToData=function(t,e,n){n=n||[];var i=this.pointToCoord(t);return n[0]=this._radiusAxis.radiusToData(i[0],e),n[1]=this._angleAxis.angleToData(i[1],e),n},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,e){e=e||[];var n=t[0],i=t[1]/180*Math.PI;return e[0]=Math.cos(i)*n+this.cx,e[1]=-Math.sin(i)*n+this.cy,e},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,r=1e-4;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,o=n*n+i*i,a=this.r,s=this.r0;return a!==s&&o-r<=a*a&&o+r>=s*s},x:this.cx-e[1],y:this.cy-e[1],width:2*e[1],height:2*e[1]}},t.prototype.convertToPixel=function(t,e,n){return vH(e)===this?this.dataToPoint(n):null},t.prototype.convertFromPixel=function(t,e,n){return vH(e)===this?this.pointToData(n):null},t}();function vH(t){var e=t.seriesModel,n=t.polarModel;return n&&n.coordinateSystem||e&&e.coordinateSystem}function yH(t,e){var n=this.getAngleAxis(),i=this.getRadiusAxis();if(CS(n,1),CS(i,1),RS(n),RS(i),"category"===n.type&&!n.onBand){var r=n.getExtent(),o=360/n.scale.count();n.inverse?r[1]+=o:r[1]-=o,n.setExtent(r[0],r[1])}}function mH(t,e){var n;if(t.type=Hw(e),t.scale=Ww(e,t.type,!1),t.onBand=eS(t.scale,e),t.inverse=e.get("inverse"),function(t){return"angleAxis"===t.mainType}(e)){t.inverse=t.inverse!==e.get("clockwise");var i=e.get("startAngle"),r=null!==(n=e.get("endAngle"))&&void 0!==n?n:i+(t.inverse?-360:360);t.setExtent(i,r)}e.axis=t,t.model=e}var xH={dimensions:fH,create:function(t,e){var n=[];return t.eachComponent(aH,function(t,i){var r=new gH(i+"");r.update=yH;var o=r.getRadiusAxis(),a=r.getAngleAxis(),s=t.findAxisModel("radiusAxis"),l=t.findAxisModel("angleAxis");mH(o,s),mH(a,l),function(t,e,n){var i=e.get("center"),r=eg(e,n).refContainer;t.cx=Vo(i[0],r.width)+r.x,t.cy=Vo(i[1],r.height)+r.y;var o=t.getRadiusAxis(),a=Math.min(r.width,r.height)/2,s=e.get("radius");null==s?s=[0,"100%"]:X(s)||(s=[0,s]);var l=[Vo(s[0],a),Vo(s[1],a)];o.inverse?o.setExtent(l[1],l[0]):o.setExtent(l[0],l[1])}(r,t,e),n.push(r),t.coordinateSystem=r,r.model=t}),t.eachSeries(function(t){if(t.get("coordinateSystem")===oH){var e=t.getReferringComponents(aH,Ea).models[0];0;var n=t.coordinateSystem=e.coordinateSystem;n&&(yS(n.getRadiusAxis(),t,oH),yS(n.getAngleAxis(),t,oH))}}),n}},_H=["axisLine","axisLabel","axisTick","minorTick","splitLine","minorSplitLine","splitArea"];function bH(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 wH(t){return t.getRadiusAxis().inverse?0:1}function SH(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 MH=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({breakTicks:"none"}),a=n.getMinorTicksCoords(),s=[];B(n.getViewLabels(),function(t){if(!t.tick.offInterval){t=C(t);var e=n.scale;t.coord=n.dataToCoord(tS(e,t.tick)),s.push(t)}}),SH(s),SH(o),B(_H,function(e){!t.get([e,"show"])||n.scale.isBlank()&&"axisLine"!==e||IH[e](this.group,t,i,o,a,r,s)},this)}},e.type="angleAxis",e}(wk),IH={axisLine:function(t,e,n,i,r,o){var a,s=e.getModel(["axisLine","lineStyle"]),l=n.getAngleAxis(),u=Math.PI/180,c=l.getExtent(),h=wH(n),d=h?0:1,p=360===Math.abs(c[1]-c[0])?"Circle":"Arc";(a=0===o[d]?new ep[p]({shape:{cx:n.cx,cy:n.cy,r:o[h],startAngle:-c[0]*u,endAngle:-c[1]*u,clockwise:l.inverse},style:s.getLineStyle(),z2:1,silent:!0}):new Ih({shape:{cx:n.cx,cy:n.cy,r:o[h],r0:o[d]},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[wH(n)],u=V(i,function(t){return new Oh({shape:bH(n,[l,l+s],t.coord)})});t.add(wd(u,{style:P(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[wH(n)],c=[],h=0;hf?"left":"right",y=Math.abs(p[1]-g)/d<.3?"middle":p[1]>g?"top":"bottom";if(s&&s[h]){var m=s[h];$(m)&&m.textStyle&&(a=new kp(m.textStyle,l,l.ecModel))}var x=new du({silent:dD.isLabelSilent(e),style:sp(a,{x:p[0],y:p[1],fill:a.getTextColor()||e.get(["axisLine","lineStyle","color"]),text:i.formattedLabel,align:v,verticalAlign:y})});if(t.add(x),Gd({el:x,componentModel:e,itemName:i.formattedLabel,formatterParamsExtra:{isTruncated:function(){return x.isTruncated},value:i.rawLabel,tickIndex:r}}),c){var _=dD.makeAxisEventDataBase(e);_.targetType="axisLabel",_.value=i.rawLabel,Iu(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=[],c=0;c=0?"p":"n",I=x;y&&(i[o][S]||(i[o][S]={p:x,n:x}),I=i[o][S][M]);var T=void 0,C=void 0,D=void 0,A=void 0;if("radius"===c.dim){var k=c.dataToCoord(w)-x,L=t.dataToCoord(S);Ao(k)=A})}}(t,e,n,i)})})});var PH={startAngle:90,clockwise:!0,splitNumber:12,containShape:!1,axisLabel:{rotate:0}},OH={splitNumber:5},RH=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}(Ky);function NH(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),ot(e.labelInside,t.get(["axisLabel","inside"]))&&(r.labelDirection=-r.labelDirection);var c=t.get(["axisLabel","rotate"]);return r.labelRotate="top"===o?-c:c,r.z2=1,r}var EH=["splitArea","splitLine","breakArea"],zH=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 vo;var s=NH(e),l=new dD(e,i,s);l.build(),o.add(this._axisGroup),o.add(l.group),B(EH,function(t){e.get([t,"show"])&&BH[t](this,this.group,this._axisGroup,e,i)},this),kd(a,this._axisGroup,e),t.prototype.render.call(this,e,n,i,r)},e.prototype.remove=function(){Ik(this)},e.type="singleAxis",e}(wk),BH={splitLine:function(t,e,n,i,r){var o=i.axis;if(!o.scale.isBlank()){var a=i.getModel("splitLine"),s=a.getModel("lineStyle"),l=s.get("color");l=l instanceof Array?l:[l];for(var u=s.get("width"),c=i.coordinateSystem.getRect(),h=o.isHorizontal(),d=[],p=0,f=o.getTicksCoords({tickModel:a,breakTicks:"none",pruneByBreak:"preserve_extent_bound"}),g=[],v=[],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,e,n){n=n||[];var i=this.getAxis();return n[0]=i.coordToData(i.toLocalCoord(t["horizontal"===i.orient?0:1])),n},t.prototype.dataToPoint=function(t,e,n){var i=this.getAxis(),r=this.getRect();n=n||[];var o="horizontal"===i.orient?0:1;return t instanceof Array&&(t=t[0]),n[o]=i.toGlobalCoord(i.dataToCoord(+t)),n[1-o]=0===o?r.y+r.height/2:r.x+r.width/2,n},t.prototype.convertToPixel=function(t,e,n){return HH(e)===this?this.dataToPoint(n):null},t.prototype.convertFromPixel=function(t,e,n){return HH(e)===this?this.pointToData(n):null},t}();function HH(t){var e=t.seriesModel,n=t.singleAxisModel;return n&&n.coordinateSystem||e&&e.coordinateSystem}var WH={create:function(t,e){var n=[];return t.eachComponent(Nk,function(i,r){var o=new FH(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(Nk,Ea).models[0],n=t.coordinateSystem=e&&e.coordinateSystem;n&&yS(n.getAxis(),t,Rk)}}),n},dimensions:GH},UH=["x","y"],YH=["width","height"],XH=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=jH(o),l=qH(a,s),u=qH(a,1-s),c=a.dataToPoint(e)[0],h=i.get("type");if(h&&"none"!==h){var d=TF(i),p=ZH[h](o,c,l,u,i.get("seriesDataIndices"),i.ecModel);p.style=d,t.graphicKey=p.type,t.pointer=p}kF(e,t,NH(n),n,i,r)},e.prototype.getHandleTransform=function(t,e,n){var i=NH(e,{labelInside:!1});i.labelMargin=n.get(["handle","margin"]);var r=AF(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=jH(r),s=qH(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=qH(o,1-a),c=(u[1]+u[0])/2,h=[c,c];return h[a]=l[a],{x:l[0],y:l[1],rotation:t.rotation,cursorPoint:h,tooltipOption:{verticalAlign:"middle"}}},e}(_F),ZH={line:function(t,e,n,i){return{type:"Line",subPixelOptimize:!0,shape:LF([e,i[0]],[e,i[1]],jH(t))}},shadow:function(t,e,n,i,r,o){var a=RF(t,r,o),s=i[1]-i[0],l=NF(e,n,a),u=l[0],c=l[1];return{type:"Rect",shape:PF([u,i[0]],[c-u,s],jH(t))}}};function jH(t){return t.isHorizontal()?0:1}function qH(t,e){var n=t.getRect();return[n[UH[e]],n[UH[e]]+n[YH[e]]]}var KH=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}(Ky);var $H=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=og(e);t.prototype.init.apply(this,arguments),JH(e,r)},e.prototype.mergeOption=function(e){t.prototype.mergeOption.apply(this,arguments),JH(this.option,e)},e.prototype.getCellSize=function(){return this.option.cellSize},e.type="calendar",e.layoutMode="box",e.defaultOption={z:2,left:80,top:60,cellSize:20,orient:"horizontal",splitLine:{show:!0,lineStyle:{color:ug.color.axisLine,width:1,type:"solid"}},itemStyle:{color:ug.color.neutral00,borderWidth:1,borderColor:ug.color.neutral10},dayLabel:{show:!0,firstDay:0,position:"start",margin:ug.size.s,color:ug.color.secondary},monthLabel:{show:!0,position:"start",margin:ug.size.s,align:"center",formatter:null,color:ug.color.secondary},yearLabel:{show:!0,position:null,margin:ug.size.xl,formatter:null,color:ug.color.quaternary,fontFamily:"sans-serif",fontWeight:"bolder",fontSize:20}},e}(lg);function JH(t,e){var n,i=t.cellSize;1===(n=X(i)?i:t.cellSize=[i,i]).length&&(n[1]=n[0]);var r=V([0,1],function(t){return function(t,e){return null!=t[Zf[e][0]]||null!=t[Zf[e][1]]&&null!=t[Zf[e][2]]}(e,t)&&(n[t]="auto"),null!=n[t]&&"auto"!==n[t]});rg(t,e,{type:"box",ignoreSize:r})}var QH=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.dataToCalendarLayout([s],!1).tl,u=new lu({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,c=0;u.time<=e.end.time;c++){d(u.formatedDate),0===c&&(u=o.getDateInfo(e.start.y+"-"+e.start.m));var h=u.date;h.setMonth(h.getMonth()+1),u=o.getDateInfo(h)}function d(e){r._firstDayOfMonth.push(o.getDateInfo(e)),r._firstDayPoints.push(o.dataToCalendarLayout([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)}d(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 kh({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.dataToCalendarLayout([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 j(t)&&t?Of(t,e):Z(t)?t(e):e.nameMap},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,c="horizontal"===n?0:1,h={top:[l,s[c][1]],bottom:[l,s[1-c][1]],left:[s[1-c][0],u],right:[s[c][0],u]},d=e.start.y;+e.end.y>+e.start.y&&(d=d+"-"+e.end.y);var p=r.get("formatter"),f={start:e.start.y,end:e.end.y,nameMap:d},g=this._formatterLabel(p,f),v=new du({z2:30,style:sp(r,{text:g}),silent:r.get("silent")});v.attr(this._yearTextPositionControl(v,h[a],n,a,o)),i.add(v)}},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&&!j(o)||(o&&(e=Fp(o)||e),o=e.get(["time","monthAbbr"])||[]);var c="start"===s?0:1,h="horizontal"===n?0:1;a="start"===s?-a:a;for(var d="center"===l,p=r.get("silent"),f=0;f=r.start.time&&i.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/tW)-Math.floor(n[0].time/tW)+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),c=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:c,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.eachComponent(function(t,e){Wf({targetModel:e,coordSysType:"calendar",coordSysProvider:Uf})}),i},t.dimensions=["time","value"],t}();function nW(t){var e=t.calendarModel,n=t.seriesModel;return e?e.coordinateSystem:n?n.coordinateSystem:null}var iW=1,rW=2,oW=3,aW={none:0,all:1,body:2,corner:3};function sW(t,e,n){var i=e[dd[n]].getCell(t);return!i&&K(t)&&t<0&&(i=e[dd[1-n]].getUnitLayoutInfo(n,Math.round(t))),i}function lW(t){var e=t||[];return e[0]=e[0]||[],e[1]=e[1]||[],e[0][0]=e[0][1]=e[1][0]=e[1][1]=NaN,e}function uW(t,e,n,i,r){cW(t[0],e,r,n,i,0),cW(t[1],e,r,n,i,1)}function cW(t,e,n,i,r,o){t[0]=1/0,t[1]=-1/0;var a=i[o],s=X(a)?a:[a],l=s.length,u=!!n;if(l>=1?(hW(t,e,s,u,r,o,0),l>1&&hW(t,e,s,u,r,o,l-1)):t[0]=t[1]=NaN,u){var c=-r[dd[1-o]].getLocatorCount(o),h=r[dd[o]].getLocatorCount(o)-1;n===aW.body?c=Do(0,c):n===aW.corner&&(h=Co(-1,h)),h=e[0]&&t[0]<=e[1]}function yW(t,e){t.id.set(e[0][0],e[1][0]),t.span.set(e[0][1]-t.id.x+1,e[1][1]-t.id.y+1)}function mW(t,e,n,i){var r=sW(e[i][0],n,i),o=sW(e[i][1],n,i);t[dd[i]]=t[pd[i]]=NaN,r&&o&&(t[dd[i]]=r.xy,t[pd[i]]=o.xy+o.wh-r.xy)}function xW(t,e,n,i){return t[dd[e]]=n,t[dd[1-e]]=i,t}var _W=function(){function t(t,e){this._cells=[],this._levels=[],this.dim=t,this.dimIdx="x"===t?0:1,this._model=e,this._uniqueValueGen=function(t){var e=t.toUpperCase(),n=new RegExp("^"+e+"([0-9]+)$"),i=0;function r(t){var e;null!=t&&(e=t.match(n))&&(i=Do(i,+e[1]+1))}function o(){return""+e+i++}function a(t,e){for(var n=mt(),i=0;i=1,x=n[dd[i]],_=o.getLocatorCount(i)-1,b=new Wa;for(a.resetLayoutIterator(b,i);b.next();)w(b.item);for(o.resetLayoutIterator(b,i);b.next();)w(b.item);function w(t){rt(t.wh)&&(t.wh=y),t.xy=x,t.id[dd[i]]!==_||m||(t.wh=n[dd[i]]+n[pd[i]]-t.xy),x+=t.wh}}function XW(t,e){for(var n=e[dd[t]].resetCellIterator();n.next();){var i=n.item;jW(i.rect,t,i.id,i.span,e),jW(i.rect,1-t,i.id,i.span,e),i.type===oW&&(i.xy=i.rect[dd[t]],i.wh=i.rect[pd[t]])}}function ZW(t,e){t.travelExistingCells(function(t){var n=t.span;if(n){var i=t.spanRect,r=t.id;jW(i,0,r,n,e),jW(i,1,r,n,e)}})}function jW(t,e,n,i,r){t[pd[e]]=0;var o=n[dd[e]]<0?r[dd[1-e]]:r[dd[e]],a=o.getUnitLayoutInfo(e,n[dd[e]]);if(t[dd[e]]=a.xy,t[pd[e]]=a.wh,i[dd[e]]>1){var s=o.getUnitLayoutInfo(e,n[dd[e]]+i[dd[e]]-1);t[pd[e]]=s.xy+s.wh-a.xy}}function qW(t,e){return Math.max(Math.min(t,at(e,1/0)),0)}function KW(t){var e=t.matrixModel,n=t.seriesModel;return e?e.coordinateSystem:n?n.coordinateSystem:null}var $W={inBody:1,inCorner:2,outside:3},JW={x:null,y:null,point:[]};function QW(t,e,n,i,r){var o=n[dd[e]],a=n[dd[1-e]],s=o.getUnitLayoutInfo(e,o.getLocatorCount(e)-1),l=o.getUnitLayoutInfo(e,0),u=a.getUnitLayoutInfo(e,-a.getLocatorCount(e)),c=a.shouldShow()?a.getUnitLayoutInfo(e,-1):null,h=t.point[e]=i[e];if(l||c)if(r!==aW.body)if(r!==aW.corner){var d=l?l.xy:c?c.xy+c.wh:NaN,p=u?u.xy:d,f=s?s.xy+s.wh:d;if(hf){if(!r)return void(t[dd[e]]=$W.outside);h=f}t.point[e]=h,t[dd[e]]=d<=h&&h<=f?$W.inBody:p<=h&&h<=d?$W.inCorner:$W.outside}else c?(t[dd[e]]=$W.inCorner,h=Co(c.xy+c.wh,Do(u.xy,h)),t.point[e]=h):t[dd[e]]=$W.outside;else l?(t[dd[e]]=$W.inBody,h=Co(s.xy+s.wh,Do(l.xy,h)),t.point[e]=h):t[dd[e]]=$W.outside;else t[dd[e]]=$W.outside}function tU(t,e,n,i){var r=1-n;if(t[dd[n]]!==$W.outside)for(i[dd[n]].resetCellIterator(UW);UW.next();){var o=UW.item;if(iU(t.point[n],o.rect,n)&&iU(t.point[r],o.rect,r))return e[n]=o.ordinal,void(e[r]=o.id[dd[r]])}}function eU(t,e,n,i){if(t[dd[n]]!==$W.outside)for((t[dd[n]]===$W.inCorner?i[dd[1-n]]:i[dd[n]]).resetLayoutIterator(WW,n);WW.next();)if(nU(t.point[n],WW.item))return void(e[n]=WW.item.id[dd[n]])}function nU(t,e){return e.xy<=t&&t<=e.xy+e.wh}function iU(t,e,n){return e[dd[n]]<=t&&t<=e[dd[n]]+e[pd[n]]}function rU(t,e){var n;return B(e,function(e){null!=t[e]&&"auto"!==t[e]&&(n=!0)}),n}var oU=["transition","enterFrom","leaveTo"],aU=oU.concat(["enterAnimation","updateAnimation","leaveAnimation"]);function sU(t,e,n){if(n&&(!t[n]&&e[n]&&(t[n]={}),t=t[n],e=e[n]),t&&e)for(var i=n?oU:aU,r=0;r=0;l--){var d,p,f;if(f=null!=(p=Da((d=n[l]).id,null))?r.get(p):null){var g=f.parent,v=(h=cU(g),{}),y=ng(f,d,g===i?{width:o,height:a}:{width:h.width,height:h.height},null,{hv:d.hv,boundingMode:d.bounding},v);if(!cU(f).isNew&&y){for(var m=d.transition,x={},_=0;_=0)?x[b]=w:f[b]=w}rd(f,x,t,0)}else f.attr(v)}}},e.prototype._clear=function(){var t=this,e=this._elMap;e.each(function(n){fU(n,cU(n).option,e,t._lastGraphicModel)}),this._elMap=mt()},e.prototype.dispose=function(){this._clear()},e.type="graphic",e}(Ky);function dU(t){var e=wt(uU,t)?uU[t]:md(t);var n=new e({});return cU(n).type=t,n}function pU(t,e,n,i){var r=dU(n);return e.add(r),i.set(t,r),cU(r).id=t,cU(r).isNew=!0,r}function fU(t,e,n,i){t&&t.parent&&("group"===t.type&&t.traverse(function(t){fU(t,e,n,i)}),AG(t,e,i),n.removeKey(cU(t).id))}function gU(t,e,n,i){t.isGroup||B([["cursor",Zs.prototype.cursor],["zlevel",i||0],["z",n||0],["z2",0]],function(n){var i=n[0];wt(e,i)?t[i]=at(e[i],n[1]):null==t[i]&&(t[i]=n[1])}),B(W(e),function(n){if(0===n.indexOf("on")){var i=e[n];t[n]=Z(i)?i:null}}),wt(e,"draggable")&&(t.draggable=e.draggable),null!=e.name&&(t.name=e.name),null!=e.id&&(t.id=e.id)}var vU=["x","y","radius","angle","single"],yU=Pa(),mU=["cartesian2d","polar","singleAxis"];function xU(t){return t+"Axis"}function _U(t,e){var n,i=mt(),r=[],o=mt();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 bU(t){var e=t.ecModel,n={infoList:[],infoMap:mt()};return t.eachTargetAxis(function(t,i){var r=e.getComponent(xU(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}function wU(t){var e=yU(ax(t));return e.axisProxyMap||(e.axisProxyMap=mt())}function SU(t){if(t)return wU(t.ecModel).get(t.uid)}function MU(t,e){var n=e.getAxisModel().axis.__alignTo;return n&&t.getAxisProxy(n.dim,n.model.componentIndex)?SU(n.model):null}var IU=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}(),TU=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=CU(t);this.settledOption=i,this.mergeDefaultAndTheme(t,n),this._doInit(i)},e.prototype.mergeOption=function(t){var e=CU(t);D(this.option,t,!0),D(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;B([["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=mt();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 B(vU,function(n){var i=this.getReferringComponents(xU(n),za);if(i.specified){e=!0;var r=new IU;B(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 IU;if(o.add(r.componentIndex),t.set(n,o),i=!1,"x"===n||"y"===n){var a=r.getReferringComponents("grid",Ea).models[0];a&&B(e,function(t){r.componentIndex!==t.componentIndex&&a===t.getReferringComponents("grid",Ea).models[0]&&o.add(t.componentIndex)})}}}i&&B(vU,function(e){if(i){var r=n.findComponents({mainType:xU(e),filter:function(t){return"category"===t.get("type",!0)}});if(r[0]){var o=new IU;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");B([["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(xU(e),n))},this),t},e.prototype.eachTargetAxis=function(t,e){this._targetAxisInfoMap.each(function(n,i){B(n.indexList,function(n){t.call(e,i,n)})})},e.prototype.getAxisProxy=function(t,e){return SU(this.getAxisModel(t,e))},e.prototype.getAxisModel=function(t,e){var n=this._targetAxisInfoMap.get(t);if(n&&n.indexMap[e])return this.ecModel.getComponent(xU(t),e)},e.prototype.setRawRange=function(t){var e=this.option,n=this.settledOption;B([["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;B(["start","startValue","end","endValue"],function(n){e[n]=t[n]})},e.prototype.getPercentRange=function(){var t=this.findRepresentativeAxisProxy();if(t)return t.getWindow().percent},e.prototype.getValueRange=function(t,e){if(null!=t||null!=e)return this.getAxisProxy(t,e).getWindow().value;var n=this.findRepresentativeAxisProxy();return n?n.getWindow().value:void 0},e.prototype.findRepresentativeAxisProxy=function(t){if(t)return SU(t);for(var e,n=this._targetAxisInfoMap.keys(),i=0;i=0}(e)){var n=xU(this._dimName),i=e.getReferringComponents(n,Ea).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 C(this._minMaxSpan)},t.prototype.calculateDataWindow=function(t){var e,n=this._extent,i=this.getAxisModel().axis,r=i.scale,o=this._dataZoomModel.getRangePropMode(),a=[0,100],s=[],l=[],u=[!1,!1];B(["start","end"],function(i,c){var h=t[i],d=t[i+"Value"];"percent"===o[c]?(null==h&&(h=a[c]),d=Bo(h,a,n),u[c]=!0):(e=!0,null==d?d=n[c]:(d=r.parse(d),r.sanitize&&(d=r.sanitize(d,n))),h=Bo(d,n,a)),l[c]=null==d||isNaN(d)?n[c]:d,s[c]=null==h||isNaN(h)?a[c]:h}),Wo(l),Wo(s);var c=this._minMaxSpan;function h(t,e,n,i,r){var o=r?"Span":"ValueSpan";ez(0,t,n,"all",c["min"+o],c["max"+o]);for(var a=0;a<2;a++)e[a]=Bo(t[a],n,i,!0),r&&(e[a]=e[a],u[a]=!0);$a(e)}e?h(l,s,n,a,!1):h(s,l,a,n,!0);var d=vw(r)||fw(r),p=i.getExtent(),f=Ao(p[1]-p[0]),g=d?0:Xo(l,f,.5);B([[0,Po],[1,Lo]],function(t){var e=t[0],i=t[1];u[e]&&isFinite(g)&&(l[e]=Ho(l[e],g),l[e]=Co(n[1],Do(n[0],l[e])),s[e]===a[e]&&(l[e]=n[e],d&&(l[e]=i(l[e]))))}),$a(l);var v=[Bo(l[0],n,a,!0),Bo(l[1],n,a,!0)];return $a(v),{value:l,percent:s,percentInverted:v,valuePrecision:g}},t.prototype.reset=function(t,e){if(this.hostedBy(t)){var n=this.getAxisModel().axis;CS(n,2);var i=n.scale.rawExtentInfo;this._extent=i.makeNoZoom(),this._updateMinMaxSpan();var r=t.settledOption;e&&(r=P({start:e[0],end:e[1]},r));var o=this._window=this.calculateDataWindow(r),a=o.percent,s=o.value;0!==a[0]&&i.setZoomMM(0,s[0]),100!==a[1]&&i.setZoomMM(1,s[1])}},t.prototype.filterData=function(t,e){if(this.hostedBy(t)){var n=this._dimName,i=this.getTargetSeriesModels(),r=t.get("filterMode"),o=this._window.value;"none"!==r&&B(i,function(t){var e=t.getData(),i=e.mapDimensionsAll(n);if(i.length){if("weakFilter"===r){var a=e.getStore(),s=V(i,function(t){return e.getDimensionIndex(t)},e);e.filterSelf(function(t){for(var e,n,r,l=0;lo[1];if(c&&!h&&!d)return!0;c&&(r=!0),h&&(e=!0),d&&(n=!0)}return r&&e&&n})}else B(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)}});B(i,function(t){e.setApproximateExtent(o,t)})}})}},t.prototype._updateMinMaxSpan=function(){var t=this._minMaxSpan={},e=this._dataZoomModel,n=this._extent;B(["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=Bo(n[0]+o,n,[0,100],!0):null!=r&&(o=Bo(r,[0,100],n,!0)-n[0]),t[i+"Span"]=r,t[i+"ValueSpan"]=o},this)},t}(),PU={dirtyOnOverallProgress:!0,getTargetSeries:function(t){var e,n=[];e=function(e,i,r,o){if(!SU(r)){var a=new LU(e,i,o,t);n.push(a),function(t,e){wU(t.ecModel).set(t.uid,e)}(r,a)}},t.eachComponent("dataZoom",function(n){n.eachTargetAxis(function(i,r){var o=t.getComponent(xU(i),r);e(i,r,o,n)})});var i=mt();return B(n,function(t){B(t.getTargetSeriesModels(),function(t){i.set(t.uid,t)})}),i},overallReset:function(t,e){t.eachComponent("dataZoom",function(t){var n=[];t.eachTargetAxis(function(e,i){var r=t.getAxisProxy(e,i),o=MU(t,r);o?n.push([r,o]):r.reset(t,null)}),B(n,function(e){e[0].reset(t,e[1].getWindow().percentInverted)}),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.getWindow(),i=n.percent,r=n.value;t.setCalculatedRange({start:i[0],end:i[1],startValue:r[0],endValue:r[1]})}})}};var OU=Ja();function RU(t){OU(t,function(){t.registerProcessor(t.PRIORITY.PROCESSOR.FILTER,PU),function(t){t.registerAction("dataZoom",function(t,e){B(_U(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 NU(t){t.registerComponentModel(DU),t.registerComponentView(kU),RU(t)}var EU=function(){},zU={};function BU(t,e){zU[t]=e}function VU(t){return zU[t]}var GU=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=i.getTheme().get("toolbox"),o=r?r.feature:null;o&&(this._themeFeatureOption=k({},o),r.feature={}),t.prototype.init.call(this,e,n,i),o&&(r.feature=o)},e.prototype.optionUpdated=function(){B(this.option.feature,function(t,e){var n=this._themeFeatureOption,i=VU(e);i&&(i.getDefaultOption&&(i.defaultOption=i.getDefaultOption(this.ecModel)),n&&n[e]&&(D(t,n[e]),n[e]=null),D(t,i.defaultOption))},this)},e.type="toolbox",e.layoutMode={type:"box",ignoreSize:!0},e.defaultOption={show:!0,z:6,orient:"horizontal",left:"right",top:"top",backgroundColor:"transparent",borderColor:ug.color.border,borderRadius:0,borderWidth:0,padding:ug.size.m,itemSize:15,itemGap:ug.size.s,showTitle:!0,iconStyle:{borderColor:ug.color.accent50,color:"none"},emphasis:{iconStyle:{borderColor:ug.color.accent70}},tooltip:{show:!1,position:"bottom"}},e}(lg);function FU(t,e){var n=Df(e.get("padding")),i=e.getItemStyle(["color","opacity"]);return i.fill=e.get("backgroundColor"),new lu({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 HU=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=mt()),u=[];B(s,function(t,e){u.push(e)}),new mb(this._featureNames||[],u).add(f).update(f).remove(Y(f,null)).execute(),this._featureNames=F(u,function(t){return l.hasKey(t)});var c=eg(t,n).refContainer,h=t.getBoxLayoutParams(),d=t.get("padding"),p=Jf(h,c,d);qf(t.get("orient"),r,t.get("itemGap"),p.width,p.height),ng(r,h,c,d),r.add(FU(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&&!Z(l)&&e){var u=l.style||(l.style={}),c=qr(e,du.makeFont(u)),h=t.x+r.x,d=!1;t.y+r.y+o+c.height>n.getHeight()&&(a.position="top",d=!0);var p=d?-5-c.height:o+10;h+c.width/2>n.getWidth()?(a.position=["100%",p],u.align="right"):h-c.width/2<0&&(a.position=[0,p],u.align="left")}})}function f(c,h){var d,p=null!=c&&null==h,f=null!=c&&null!=h,g=null==c,v=p||f?u[c]:u[h],y=s[v],m=p||f?new kp(y,t,e):null,x=m&&m.get("show");if(p){if(!x)return;if(function(t){return 0===t.indexOf("my")}(v))d={onclick:m.option.onclick,featureName:v};else{var _=VU(v);if(!_)return;d=new _}l.set(v,d)}else d=l.get(v);if(g||!x)return WU(d)&&d.dispose&&d.dispose(e,n),void l.removeKey(v);i&&null!=i.newTitle&&i.featureName===v&&(y.title=i.newTitle),p&&(d.uid=Pp("toolbox-feature")),d.model=m,d.ecModel=e,d.api=n,function(i,s,l){var u,c,h=i.getModel("iconStyle"),d=i.getModel(["emphasis","iconStyle"]),p=s instanceof EU&&s.getIcons?s.getIcons():i.get("icon"),f=i.get("title")||{};j(p)?(u={})[l]=p:u=p;j(f)?(c={})[l]=f:c=f;var g=i.iconPaths={};B(u,function(l,u){var p=Od(l,{},{x:-o/2,y:-o/2,width:o,height:o});p.setStyle(h.getItemStyle()),p.ensureState("emphasis").style=d.getItemStyle();var f=new du({style:{text:c[u],align:d.get("textAlign"),borderRadius:d.get("textBorderRadius"),padding:d.get("textPadding"),fill:null,font:pp({fontStyle:d.get("textFontStyle"),fontFamily:d.get("textFontFamily"),fontSize:d.get("textFontSize"),fontWeight:d.get("textFontWeight")},e)},ignore:!0});p.setTextContent(f),Gd({el:p,componentModel:t,itemName:u,formatterParamsExtra:{title:c[u]}}),p.__title=c[u],p.on("mouseover",function(){var e=d.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:d.get("textFill")||e.fill||e.stroke||ug.color.neutral99,backgroundColor:d.get("textBackgroundColor")}),p.setTextConfig({position:d.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])?vc:yc)(p),r.add(p),p.on("click",U(s.onclick,s,e,n,u)),g[u]=p})}(m,d,v),m.setIconStatus=function(t,e){var n=this.option,i=this.iconPaths;n.iconStatus=n.iconStatus||{},n.iconStatus[t]=e,i[t]&&("emphasis"===e?vc:yc)(i[t])},WU(d)&&d.render&&d.render(m,e,n,i)}},e.prototype.updateView=function(t,e,n,i){B(this._features,function(t){t&&t instanceof EU&&t.updateView&&t.updateView(t.model,e,n,i)})},e.prototype.dispose=function(t,e){B(this._features,function(n){n&&n instanceof EU&&n.dispose&&n.dispose(t,e)})},e.type="toolbox",e}(Ky);function WU(t){return t instanceof EU}var UU=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")||ug.color.neutral00,connectedBackgroundColor:n.get("connectedBackgroundColor"),excludeComponents:n.get("excludeComponents"),pixelRatio:n.get("pixelRatio")}),l=r.browser;if("function"!=typeof MouseEvent||!l.newEdge&&(l.ie||l.edge))if(window.navigator.msSaveOrOpenBlob||o){var u=s.split(","),c=u[0].indexOf("base64")>-1,h=o?decodeURIComponent(u[1]):u[1];c&&(h=window.atob(h));var d=i+"."+a;if(window.navigator.msSaveOrOpenBlob){for(var p=h.length,f=new Uint8Array(p);p--;)f[p]=h.charCodeAt(p);var g=new Blob([f]);window.navigator.msSaveOrOpenBlob(g,d)}else{var v=document.createElement("iframe");document.body.appendChild(v);var y=v.contentWindow,m=y.document;m.open("image/svg+xml","replace"),m.write(h),m.close(),y.focus(),m.execCommand("SaveAs",!0,d),document.body.removeChild(v)}}else{var x=n.get("lang"),_='',b=window.open();b.document.write(_),b.document.title=i}else{var w=document.createElement("a");w.download=i+"."+a,w.target="_blank",w.href=s;var S=new MouseEvent("click",{view:document.defaultView,bubbles:!0,cancelable:!1});w.dispatchEvent(S)}},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:ug.color.neutral00,name:"",excludeComponents:["toolbox"],lang:t.getLocaleModel().get(["toolbox","saveAsImage","lang"])}},e}(EU),YU="__ec_magicType_stack__",XU=[["line","bar"],["stack"]],ZU=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 B(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(jU[n]){var o,a={series:[]};B(XU,function(t){R(t,n)>=0&&B(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=jU[n](e,r,t,i);o&&(P(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",c=t.getReferringComponents(u,Ea).models[0].componentIndex;a[u]=a[u]||[];for(var h=0;h<=c;h++)a[u][c]=a[u][c]||{};a[u][c].boundaryGap="bar"===n}}});var s=n;"stack"===n&&(o=D({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}(EU),jU={line:function(t,e,n,i){if("bar"===t)return D({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 D({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")===YU;if("line"===t||"bar"===t)return i.setIconStatus("stack",r?"normal":"emphasis"),D({id:e,stack:r?"":YU},i.get(["option","stack"])||{},!0)}};ib({type:"changeMagicType",event:"magicTypeChanged",update:"prepareAndUpdate"},function(t,e){e.mergeOption(t.newOption)});var qU=new Array(60).join("-"),KU="\t";function $U(t){return t.replace(/^\s\s*/,"").replace(/\s\s*$/,"")}var JU=new RegExp("[\t]+","g");function QU(t,e){var n=t.split(new RegExp("\n*"+qU+"\n*","g")),i={series:[]};return B(n,function(t,n){if(function(t){if(t.slice(0,t.indexOf("\n")).indexOf(KU)>=0)return!0}(t)){var r=function(t){for(var e=t.split(/\n+/g),n=[],i=V($U(e.shift()).split(JU),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=pY[t.brushType](0,n,e);t.__rangeOffset={offset:gY[t.brushType](i.values,t.range,[1,1]),xyMinMax:i.xyMinMax}}}),t},t.prototype.matchOutputRanges=function(t,e,n){B(t,function(t){var i=this.findTargetInfo(t,e);i&&!0!==i&&B(i.coordSyses,function(i){var r=pY[t.brushType](1,i,t.range,!0);n(t,r.values,i,e)})},this)},t.prototype.setInputRanges=function(t,e){B(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=pY[t.brushType](0,s.coordSys,t.coordRange),u=t.__rangeOffset;t.range=u?gY[t.brushType](l.values,u.offset,(n=l.xyMinMax,i=u.xyMinMax,r=yY(n),o=yY(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 V(this._targetInfoList,function(n){var i=n.getPanelRect();return{panelId:n.panelId,defaultBrushType:e?e(n):null,clipPath:Kz(i),isTargetByCursor:Jz(i,t,n.coordSysModel),getLinearBrushOtherExtent:$z(i)}})},t.prototype.controlSeries=function(t,e,n){var i=this.findTargetInfo(t,n);return!0===i||i&&R(i.coordSyses,e.coordinateSystem)>=0},t.prototype.findTargetInfo=function(t,e){for(var n=this._targetInfoList,i=uY(e,t),r=0;rt[1]&&t.reverse(),t}function uY(t,e){return Ra(t,e,{includeMainTypes:aY})}var cY={grid:function(t,e){var n=t.xAxisModels,i=t.yAxisModels,r=t.gridModels,o=mt(),a={},s={};(n||i||r)&&(B(n,function(t){var e=t.axis.grid.model;o.set(e.id,e),a[e.id]=!0}),B(i,function(t){var e=t.axis.grid.model;o.set(e.id,e),s[e.id]=!0}),B(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=[];B(r.getCartesians(),function(t,e){(R(n,t.getAxis("x").model)>=0||R(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:dY.grid,xAxisDeclared:a[t.id],yAxisDeclared:s[t.id]})}))},geo:function(t,e){B(t.geoModels,function(t){var n=t.coordinateSystem;e.push({panelId:"geo--"+t.id,geoModel:t,coordSysModel:t,coordSys:n,coordSyses:[n],getPanelRect:dY.geo})})}},hY=[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}],dY={grid:function(){return this.coordSys.master.getRect().clone()},geo:function(){var t=this.coordSys.view,e=aP(null,t);return $e(e,e,rP(null,t)),e}},pY={lineX:Y(fY,0),lineY:Y(fY,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=[lY([r[0],o[0]]),lY([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:V(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 fY(t,e,n,i){var r=n.getAxis(["x","y"][t]),o=lY(V([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 gY={lineX:Y(vY,0),lineY:Y(vY,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 V(t,function(t,i){return[t[0]-n[0]*e[i][0],t[1]-n[1]*e[i][1]]})}};function vY(t,e,n,i){return[e[0]-i[t]*n[0],e[1]-i[t]*n[1]]}function yY(t){return t?[t[0][1]-t[0][0],t[1][1]-t[1][0]]:[NaN,NaN]}var mY,xY,_Y=B,bY=xa+"toolbox-dataZoom_",wY={x:"width",y:"height"},SY=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 xz(n.getZr()),this._brushController.on("brush",U(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 sY(IY(t),e,{include:["grid"]}),s=a.makePanelOpts(r,function(t){return t.xAxisDeclared&&!t.yAxisDeclared?"lineX":!t.xAxisDeclared&&t.yAxisDeclared?"lineY":"rect"});n._brushController.setPanels(s).enableBrush(!(!o||!s.length)&&{brushType:"auto",brushStyle:t.getModel("brushStyle").getItemStyle()})}(t,e,this,i,n),function(t,e){t.setIconStatus("back",function(t){return rY(t).length}(e)>1?"emphasis":"normal")}(t,e)},e.prototype.onclick=function(t,e,n){MY[n].call(this)},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 sY(IY(this.model),i,{include:["grid"]}).matchOutputRanges(e,i,function(t,e,n){if("cartesian2d"===n.type){var i=n.master.getRect().clone(),o=t.brushType;"rect"===o?(r("x",n,i,e[0]),r("y",n,i,e[1])):r({lineX:"x",lineY:"y"}[o],n,i,e)}}),function(t,e){var n=rY(t);nY(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,o){var a=e.getAxis(t),s=a.model,l=function(t,e,n){var i;return n.eachComponent({mainType:"dataZoom",subType:"select"},function(n){n.getAxisModel(t,e.componentIndex)&&(i=n)}),i}(t,s,i),u=l.findRepresentativeAxisProxy(s).getMinMaxSpan(),c=a.scale.getExtent();null==u.minValueSpan&&null==u.maxValueSpan||(o=ez(0,o.slice(),c,0,u.minValueSpan,u.maxValueSpan));var h=Xo(c,r[wY[t]],.5);l&&(n[l.id]={dataZoomId:l.id,startValue:isFinite(h)?Ho(o[0],h):o[0],endValue:isFinite(h)?Ho(o[1],h):o[1]})}},e.prototype._dispatchZoomAction=function(t){var e=[];_Y(t,function(t,n){e.push(C(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:ug.color.backgroundTint}}},e}(EU),MY={zoom:function(){var t=!this._isZoomActive;this.api.dispatchAction({type:"takeGlobalCursor",key:"dataZoomSelect",dataZoomSelectActive:t})},back:function(){this._dispatchZoomAction(function(t){var e=rY(t),n=e[e.length-1];e.length>1&&e.pop();var i={};return nY(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 IY(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}mY="dataZoom",xY=function(t){var e=t.getComponent("toolbox",0),n=["feature","dataZoom"];if(e&&null!=e.get(n)){var i=e.getModel(n),r=[],o=Ra(t,IY(i));return _Y(o.xAxisModels,function(t){return a(t,"xAxis","xAxisIndex")}),_Y(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:bY+e+o};a[n]=o,r.push(a)}},ct(null==Cg.get(mY)&&xY),Cg.set(mY,xY);var TY=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|mousewheel",alwaysShowContent:!1,renderMode:"auto",confine:null,showDelay:0,hideDelay:100,transitionDuration:.4,displayTransition:!0,enterable:!1,backgroundColor:ug.color.neutral00,shadowBlur:10,shadowColor:"rgba(0, 0, 0, .2)",shadowOffsetX:1,shadowOffsetY:2,borderRadius:4,borderWidth:1,defaultBorderColor:ug.color.border,padding:null,extraCssText:"",axisPointer:{type:"line",axis:"auto",animation:"auto",animationDurationUpdate:200,animationEasingUpdate:"exponentialOut",crossStyle:{color:ug.color.borderShade,width:1,type:"dashed",textStyle:{}}},textStyle:{color:ug.color.tertiary,fontSize:14}},e}(lg);function CY(t){var e=t.get("confine");return null!=e?!!e:"richText"===t.get("renderMode")}function DY(t){if(r.domSupported)for(var e=document.documentElement.style,n=0,i=t.length;n0&&o.push(function(t,e,n){var i="cubic-bezier(0.23,1,0.32,1)",o="",a="";return n&&(a="opacity"+(o=" "+t/2+"s "+i)+",visibility"+o),e||(o=" "+t+"s "+i,a+=(a.length?",":"")+(r.transformSupported?""+PY+o:",left"+o+",top"+o)),LY+":"+a}(a,n,i)),s&&o.push("background-color:"+s),B(["width","color","radius"],function(e){var n="border-"+e,i=Cf(n),r=t.get(i);null!=r&&o.push(n+":"+r+("color"===e?"":"px"))}),o.push(function(t){var e=[],n=t.get("fontSize"),i=t.getTextColor();i&&e.push("color:"+i),e.push("font:"+t.getFont());var r=at(t.get("lineHeight"),Math.round(3*n/2));n&&e.push("line-height:"+r+"px");var o=t.get("textShadowColor"),a=t.get("textShadowBlur")||0,s=t.get("textShadowOffsetX")||0,l=t.get("textShadowOffsetY")||0;return o&&a&&e.push("text-shadow:"+s+"px "+l+"px "+a+"px "+o),B(["decoration","align"],function(n){var i=t.get(n);i&&e.push("text-"+n+":"+i)}),e.join(";")}(d)),null!=p&&o.push("padding:"+Df(p).join("px ")+"px"),o.join(";")+";"}function EY(t,e,n,i,r){var o=e&&e.painter;if(n){var a=o&&o.getViewportRoot();a&&function(t,e,n,i,r){ie(ne,e,i,r,!0)&&ie(t,n,ne[0],ne[1])}(t,a,n,i,r)}else{t[0]=i,t[1]=r;var s=o&&o.getViewportRootOffset();s&&(t[0]+=s.offsetLeft,t[1]+=s.offsetTop)}t[2]=t[0]/e.getWidth(),t[3]=t[1]/e.getHeight()}var zY=function(){function t(t,e){if(this._show=!1,this._styleCoord=[0,0,0,0],this._enterable=!0,this._alwaysShowContent=!1,this._firstShow=!0,this._longHide=!0,r.wxa)return null;var n=document.createElement("div");n.domBelongToZr=!0,this.el=n;var i=this._zr=t.getZr(),o=e.appendTo,a=o&&(j(o)?document.querySelector(o):tt(o)?o:Z(o)&&o(t.getDom()));EY(this._styleCoord,i,a,t.getWidth()/2,t.getHeight()/2),(a||t.getDom()).appendChild(n),this._api=t,this._container=a;var s=this;n.onmouseenter=function(){s._enterable&&(clearTimeout(s._hideTimeout),s._show=!0),s._inContent=!0},n.onmousemove=function(t){if(t=t||window.event,!s._enterable){var e=i.handler;fe(i.painter.getViewportRoot(),t,!0),e.dispatch("mousemove",t)}},n.onmouseleave=function(){s._inContent=!1,s._enterable&&s._show&&s.hideLater(s._hideDelay)}}return t.prototype.update=function(t){if(!this._container){var e=this._api.getDom(),n=(o="position",(a=(r=e).currentStyle||document.defaultView&&document.defaultView.getComputedStyle(r))?o?a[o]:a:null),i=e.style;"absolute"!==i.position&&"absolute"!==n&&(i.position="relative")}var r,o,a,s=t.get("alwaysShowContent");s&&this._moveIfResized(),this._alwaysShowContent=s,this._enableDisplayTransition=t.get("displayTransition")&&t.get("transitionDuration")>0,this.el.className=t.get("className")||""},t.prototype.show=function(t,e){clearTimeout(this._hideTimeout),clearTimeout(this._longHideTimeout);var n=this.el,i=n.style,r=this._styleCoord;n.innerHTML?i.cssText=OY+NY(t,!this._firstShow,this._longHide,this._enableDisplayTransition)+RY(r[0],r[1],!0)+"border-color:"+Nf(e)+";"+(t.get("extraCssText")||"")+";pointer-events:"+(this._enterable?"auto":"none"):i.display="none",this._show=!0,this._firstShow=!1,this._longHide=!1},t.prototype.setContent=function(t,e,n,i,r){var o=this.el;if(null!=t){var a="";if(j(r)&&"item"===n.get("trigger")&&!CY(n)&&(a=function(t,e,n){if(!j(n)||"inside"===n)return"";var i=t.get("backgroundColor"),r=t.get("borderWidth");e=Nf(e);var o,a,s="left"===(o=n)?"right":"right"===o?"left":"top"===o?"bottom":"top",l=Math.max(1.5*Math.round(r),6),u="",c=PY+":";R(["left","right"],s)>-1?(u+="top:50%",c+="translateY(-50%) rotate("+(a="left"===s?-225:-45)+"deg)"):(u+="left:50%",c+="translateX(-50%) rotate("+(a="top"===s?225:45)+"deg)");var h=a*Math.PI/180,d=l+r,p=d*Math.abs(Math.cos(h))+d*Math.abs(Math.sin(h)),f=e+" solid "+r+"px;";return'
'}(n,i,r)),j(t))o.innerHTML=t+a;else if(t){o.innerHTML="",X(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("axis"!==t.get("trigger")&&(this._lastDataByCoordSys=null,this._cbParamsList=null),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=YY(i,n);this._ticket="";var a=i.dataByCoordSys,s=function(t,e,n){var i=Na(t).queryOptionMap,r=i.keys()[0];if(!r||"series"===r)return;var o=Ba(e,r,i.get(r),{useDefault:!1,enableAll:!1,enableNone:!1}),a=o.models[0];if(!a)return;var s,l=n.getViewOfComponentModel(a);if(l.group.traverse(function(e){var n=Iu(e).tooltipConfig;if(n&&n.name===t.name)return s=e,!0}),s)return{componentMainType:r,componentIndex:a.componentIndex,el:s}}(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=HY;u.x=i.x,u.y=i.y,u.update(),Iu(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 c=jF(i,e),h=c.point[0],d=c.point[1];null!=h&&null!=d&&this._tryShow({offsetX:h,offsetY:d,target:c.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._tooltipModel&&r.hideLater(this._tooltipModel.get("hideDelay")),this._lastX=this._lastY=this._lastDataByCoordSys=null,this._cbParamsList=null,i.from!==this.uid&&this._hide(YY(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"===UY([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;if("legend"===Iu(n).ssrType)return;this._lastDataByCoordSys=null,this._cbParamsList=null,Qm(n,function(t){if(t.tooltipDisabled)return r=o=null,!0;r||o||(null!=Iu(t).dataIndex?r=t:null!=Iu(t).tooltipConfig&&(o=t))},!0),r?this._showSeriesItemTooltip(t,r,e):o?this._showComponentItemTooltip(t,o,e):this._hide(e)}else this._lastDataByCoordSys=null,this._cbParamsList=null,this._hide(e)}},e.prototype._showOrMove=function(t,e){var n=t.get("showDelay");e=U(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=UY([e.tooltipOption],i),a=this._renderMode,s=[],l=Ty("section",{blocks:[],noHeader:!0}),u=[],c=new zy;B(t,function(t){B(t.dataByAxis,function(t){var e=n.getComponent(t.axisDim+"Axis",t.axisIndex),r=t.value,o=e.axis,h=o.scale.parse(r);if(e&&null!=r){var d=DF(r,o,n,t.seriesDataIndices,t.valueLabelOpt),p=Ty("section",{header:d,noHeader:!ht(d),sortBlocks:!0,blocks:[]});l.blocks.push(p),B(t.seriesDataIndices,function(r){var o=n.getSeriesByIndex(r.seriesIndex),l=r.dataIndexInside,f=o.getDataParams(l);if(!(f.dataIndex<0)){f.axisDim=t.axisDim,f.axisIndex=t.axisIndex,f.axisType=t.axisType,f.axisId=t.axisId,f.axisValue=jw(e.axis,{value:h}),f.axisValueLabel=d,f.marker=c.makeTooltipMarker("item",Nf(f.color),a);var g=Gv(o.formatTooltip(l,!0,null)),v=g.frag;if(v){var y=UY([o],i).get("valueFormatter");p.blocks.push(y?k({valueFormatter:y},v):v)}g.text&&u.push(g.text),s.push(f)}})}})}),l.blocks.reverse(),u.reverse();var h=e.position,d=o.get("order"),p=Py(l,c,a,d,n.get("useUTC"),o.get("textStyle"));p&&u.unshift(p);var f="richText"===a?"\n\n":"
",g=u.join(f);this._showOrMove(o,function(){this._updateContentNotChangedOnAxis(t,s)?this._updatePosition(o,h,r[0],r[1],this._tooltipContent,s):this._showTooltipContent(o,g,s,Math.random()+"",r[0],r[1],h,null,c)})},e.prototype._showSeriesItemTooltip=function(t,e,n){var i=this._ecModel,r=Iu(e),o=r.seriesIndex,a=i.getSeriesByIndex(o),s=r.dataModel||a,l=r.dataIndex,u=r.dataType,c=s.getData(u),h=this._renderMode,d=t.positionDefault,p=UY([c.getItemModel(l),s,a&&(a.coordinateSystem||{}).model],this._tooltipModel,d?{position:d}:null),f=p.get("trigger");if(null==f||"item"===f){var g=s.getDataParams(l,u),v=new zy;g.marker=v.makeTooltipMarker("item",Nf(g.color),h);var y=Gv(s.formatTooltip(l,!1,u)),m=p.get("order"),x=p.get("valueFormatter"),_=y.frag,b=_?Py(x?k({valueFormatter:x},_):_,v,h,m,i.get("useUTC"),p.get("textStyle")):y.text,w="item_"+s.name+"_"+l;this._showOrMove(p,function(){this._showTooltipContent(p,b,g,w,t.offsetX,t.offsetY,t.position,t.target,v)}),n({type:"showTip",dataIndexInside:l,dataIndex:c.getRawIndex(l),seriesIndex:o,from:this.uid})}},e.prototype._showComponentItemTooltip=function(t,e,n){var i="html"===this._renderMode,r=Iu(e),o=r.tooltipConfig.option||{},a=o.encodeHTMLContent;if(j(o)){o={content:o,formatter:o},a=!0}a&&i&&o.content&&((o=C(o)).content=se(o.content));var s=[o],l=this._ecModel.getComponent(r.componentMainType,r.componentIndex);l&&s.push(l),s.push({formatter:o.content});var u=t.positionDefault,c=UY(s,this._tooltipModel,u?{position:u}:null),h=c.get("content"),d=Math.random()+"",p=new zy;this._showOrMove(c,function(){var n=C(c.get("formatterParams")||{});this._showTooltipContent(c,h,n,d,t.offsetX,t.offsetY,t.position,e,p)}),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 c=t.get("formatter");a=a||t.get("position");var h=e,d=this._getNearestPoint([r,o],n,t.get("trigger"),t.get("borderColor"),t.get("defaultBorderColor",!0)).color;if(c)if(j(c)){var p=t.ecModel.get("useUTC"),f=X(n)?n[0]:n;h=c,f&&f.axisType&&f.axisType.indexOf("time")>=0&&(h=uf(f.axisValue,h,p)),h=Pf(h,n,!0)}else if(Z(c)){var g=U(function(e,i){e===this._ticket&&(u.setContent(i,l,t,d,a),this._updatePosition(t,a,r,o,u,n,s))},this);this._ticket=i,h=c(n,i,g)}else h=c;u.setContent(h,l,t,d,a),u.show(t,d),this._updatePosition(t,a,r,o,u,n,s)}},e.prototype._getNearestPoint=function(t,e,n,i,r){return"axis"===n||X(e)?{color:i||r}:X(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(),c=t.get("align"),h=t.get("verticalAlign"),d=a&&a.getBoundingRect().clone();if(a&&d.applyTransform(a.transform),Z(e)&&(e=e([n,i],o,r.el,d,{viewSize:[s,l],contentSize:u.slice()})),X(e))n=Vo(e[0],s),i=Vo(e[1],l);else if($(e)){var p=e;p.width=u[0],p.height=u[1];var f=Jf(p,{width:s,height:l});n=f.x,i=f.y,c=null,h=null}else if(j(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,c=e.height;switch(t){case"inside":s=e.x+u/2-r/2,l=e.y+c/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+c+a;break;case"left":s=e.x-r-a,l=e.y+c/2-o/2;break;case"right":s=e.x+u+a,l=e.y+c/2-o/2}return[s,l]}(e,d,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,c?null:20,h?null:20);n=g[0],i=g[1]}if(c&&(n-=XY(c)?u[0]/2:"right"===c?u[0]:0),h&&(i-=XY(h)?u[1]/2:"bottom"===h?u[1]:0),CY(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&&B(n,function(n,o){var a=n.dataByAxis||[],s=(t[o]||{}).dataByAxis||[];(r=r&&a.length===s.length)&&B(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)&&B(a,function(t,e){var n=l[e];r=r&&t.seriesIndex===n.seriesIndex&&t.dataIndex===n.dataIndex}),i&&B(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,this._cbParamsList=null,t({type:"hideTip",from:this.uid})},e.prototype.dispose=function(t,e){!r.node&&e.getDom()&&(hm(this,"_updatePosition"),this._tooltipContent.dispose(),XF("itemTooltip",e),this._tooltipContent=null,this._tooltipModel=null,this._lastDataByCoordSys=null,this._cbParamsList=null)},e.type="tooltip",e}(Ky);function UY(t,e,n){var i,r=e.ecModel;n?(i=new kp(n,r,r),i=new kp(e.option,i,r)):i=e;for(var o=t.length-1;o>=0;o--){var a=t[o];a&&(a instanceof kp&&(a=a.get("tooltip",!0)),j(a)&&(a={formatter:a}),a&&(i=new kp(a,i,r)))}return i}function YY(t,e){return t.dispatchAction||U(e.dispatchAction,e)}function XY(t){return"center"===t||"middle"===t}var ZY=["rect","polygon","keep","clear"];function jY(t,e){var n=_a(t?t.brush:[]);if(n.length){var i=[];B(n,function(t){var e=t.hasOwnProperty("toolbox")?t.toolbox:[];e instanceof Array&&(i=i.concat(e))});var r=t&&t.toolbox;X(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),ts(s,function(t){return t+""},null),e&&!s.length&&s.push.apply(s,ZY)}}var qY=B;function KY(t){if(t)for(var e in t)if(t.hasOwnProperty(e))return!0}function $Y(t,e,n){var i={};return qY(e,function(e){var r,o=i[e]=((r=function(){}).prototype.__hidden=r.prototype,new r);qY(t[e],function(t,i){if(ZR.isValidType(i)){var r={type:i,visual:t};n&&n(r,e),o[i]=new ZR(r),"opacity"===i&&((r=C(r)).type="colorAlpha",o.__hidden.__alphaForOpacity=new ZR(r))}})}),i}function JY(t,e,n){var i;B(n,function(t){e.hasOwnProperty(t)&&KY(e[t])&&(i=!0)}),i&&B(n,function(n){e.hasOwnProperty(n)&&KY(e[n])?t[n]=C(e[n]):delete t[n]})}var QY={lineX:tX(0),lineY:tX(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])&&FS(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!!(FS(i,r,o)||FS(i,r+a,o)||FS(i,r,o+s)||FS(i,r+a,o+s)||Xe.create(t).contain(l[0],l[1])||Rd(r,o,r+a,o,i)||Rd(r,o,r,o+s,i)||Rd(r+a,o,r+a,o+s,i)||Rd(r,o+s,r+a,o+s,i))||void 0}}};function tX(t){var e=["x","y"],n=["width","height"];return{point:function(e,n,i){if(e){var r=i.range;return eX(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&&cX(e)}};function cX(t){return new Xe(t[0][0],t[1][0],t[0][1]-t[0][0],t[1][1]-t[1][0])}var hX=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 xz(e.getZr())).on("brush",U(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){oX(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:C(n),$from:e}),t.isEnd&&this.api.dispatchAction({type:"brushEnd",brushId:e,areas:C(n),$from:e})},e.type="brush",e}(Ky),dX=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&&JY(n,t,["inBrush","outOfBrush"]);var i=n.inBrush=n.inBrush||{};n.outOfBrush=n.outOfBrush||{color:this.option.defaultOutOfBrushColor},i.hasOwnProperty("liftZ")||(i.liftZ=5)},e.prototype.setAreas=function(t){t&&(this.areas=V(t,function(t){return pX(this.option,t)},this))},e.prototype.setBrushOption=function(t){this.brushOption=pX(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:ug.color.backgroundTint,borderColor:ug.color.borderTint},throttleType:"fixRate",throttleDelay:0,removeOnClick:!0,z:1e4,defaultOutOfBrushColor:ug.color.disabled},e}(lg);function pX(t,e){return D({brushType:t.brushType,brushMode:t.brushMode,transformable:t.transformable,brushStyle:new kp(t.brushStyle).getItemStyle(),removeOnClick:t.removeOnClick,z:t.z},e,!0)}var fX=["rect","polygon","lineX","lineY","keep","clear"],gX=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,B(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 B(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:fX.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}(EU);var vX=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:"center",top:ug.size.m,backgroundColor:ug.color.transparent,borderColor:ug.color.primary,borderWidth:0,padding:5,itemGap:10,textStyle:{fontSize:18,fontWeight:"bold",color:ug.color.primary},subtextStyle:{fontSize:12,color:ug.color.quaternary}},e}(lg),yX=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=at(t.get("textBaseline"),t.get("textVerticalAlign")),l=new du({style:sp(r,{text:t.get("text"),fill:r.getTextColor()},{disableBox:!0}),z2:10}),u=l.getBoundingRect(),c=t.get("subtext"),h=new du({style:sp(o,{text:c,fill:o.getTextColor(),y:u.height+t.get("itemGap"),verticalAlign:"top"},{disableBox:!0}),z2:10}),d=t.get("link"),p=t.get("sublink"),f=t.get("triggerEvent",!0);l.silent=!d&&!f,h.silent=!p&&!f,d&&l.on("click",function(){Ef(d,"_"+t.get("target"))}),p&&h.on("click",function(){Ef(p,"_"+t.get("subtarget"))}),Iu(l).eventData=Iu(h).eventData=f?{componentType:"title",componentIndex:t.componentIndex}:null,i.add(l),c&&i.add(h);var g=i.getBoundingRect(),v=t.getBoxLayoutParams();v.width=g.width,v.height=g.height;var y=Jf(v,eg(t,n).refContainer,t.get("padding"));a||("middle"===(a=t.get("left")||t.get("right"))&&(a="center"),"right"===a?y.x+=y.width:"center"===a&&(y.x+=y.width/2)),s||("center"===(s=t.get("top")||t.get("bottom"))&&(s="middle"),"bottom"===s?y.y+=y.height:"middle"===s&&(y.y+=y.height/2),s=s||"top"),i.x=y.x,i.y=y.y,i.markRedraw();var m={align:a,verticalAlign:s};l.setStyle(m),h.setStyle(m),g=i.getBoundingRect();var x=y.margin,_=t.getItemStyle(["color","opacity"]);_.fill=t.get("backgroundColor");var b=new lu({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}(Ky);var mX=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=[],B(n,function(e,n){var i,o=Da(Sa(e),"");$(e)?(i=C(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 Hb([{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:ug.size.m,controlPosition:"left",autoPlay:!1,rewind:!1,loop:!0,playInterval:2e3,currentIndex:0,itemStyle:{},label:{color:ug.color.secondary},data:[]},e}(lg),xX=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=Op(mX.defaultOption,{backgroundColor:"rgba(0,0,0,0)",borderColor:ug.color.border,borderWidth:0,orient:"horizontal",inverse:!1,tooltip:{trigger:"item"},symbol:"circle",symbolSize:12,lineStyle:{show:!0,width:2,color:ug.color.accent10},label:{position:"auto",show:!0,interval:"auto",rotate:0,color:ug.color.tertiary},itemStyle:{color:ug.color.accent20,borderWidth:0},checkpointStyle:{symbol:"circle",symbolSize:15,color:ug.color.accent50,borderColor:ug.color.accent50,borderWidth:0,shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0,shadowColor:"rgba(0, 0, 0, 0)",animation:!0,animationDuration:300,animationEasing:"quinticInOut"},controlStyle:{show:!0,showPlayBtn:!0,showPrevBtn:!0,showNextBtn:!0,itemSize:24,itemGap:12,position:"left",playIcon:"path://M15 0C23.2843 0 30 6.71573 30 15C30 23.2843 23.2843 30 15 30C6.71573 30 0 23.2843 0 15C0 6.71573 6.71573 0 15 0ZM15 3C8.37258 3 3 8.37258 3 15C3 21.6274 8.37258 27 15 27C21.6274 27 27 21.6274 27 15C27 8.37258 21.6274 3 15 3ZM11.5 10.6699C11.5 9.90014 12.3333 9.41887 13 9.80371L20.5 14.1338C21.1667 14.5187 21.1667 15.4813 20.5 15.8662L13 20.1963C12.3333 20.5811 11.5 20.0999 11.5 19.3301V10.6699Z",stopIcon:"path://M15 0C23.2843 0 30 6.71573 30 15C30 23.2843 23.2843 30 15 30C6.71573 30 0 23.2843 0 15C0 6.71573 6.71573 0 15 0ZM15 3C8.37258 3 3 8.37258 3 15C3 21.6274 8.37258 27 15 27C21.6274 27 27 21.6274 27 15C27 8.37258 21.6274 3 15 3ZM11.5 10C12.3284 10 13 10.6716 13 11.5V18.5C13 19.3284 12.3284 20 11.5 20C10.6716 20 10 19.3284 10 18.5V11.5C10 10.6716 10.6716 10 11.5 10ZM18.5 10C19.3284 10 20 10.6716 20 11.5V18.5C20 19.3284 19.3284 20 18.5 20C17.6716 20 17 19.3284 17 18.5V11.5C17 10.6716 17.6716 10 18.5 10Z",nextIcon:"path://M0.838834 18.7383C0.253048 18.1525 0.253048 17.2028 0.838834 16.617L7.55635 9.89949L0.838834 3.18198C0.253048 2.59619 0.253048 1.64645 0.838834 1.06066C1.42462 0.474874 2.37437 0.474874 2.96015 1.06066L10.7383 8.83883L10.8412 8.95277C11.2897 9.50267 11.2897 10.2963 10.8412 10.8462L10.7383 10.9602L2.96015 18.7383C2.37437 19.3241 1.42462 19.3241 0.838834 18.7383Z",prevIcon:"path://M10.9602 1.06066C11.5459 1.64645 11.5459 2.59619 10.9602 3.18198L4.24264 9.89949L10.9602 16.617C11.5459 17.2028 11.5459 18.1525 10.9602 18.7383C10.3744 19.3241 9.42462 19.3241 8.83883 18.7383L1.06066 10.9602L0.957771 10.8462C0.509245 10.2963 0.509245 9.50267 0.957771 8.95277L1.06066 8.83883L8.83883 1.06066C9.42462 0.474874 10.3744 0.474874 10.9602 1.06066Z",prevBtnSize:18,nextBtnSize:18,color:ug.color.accent50,borderColor:ug.color.accent50,borderWidth:0},emphasis:{label:{show:!0,color:ug.color.accent60},itemStyle:{color:ug.color.accent60,borderColor:ug.color.accent60},controlStyle:{color:ug.color.accent70,borderColor:ug.color.accent70}},progress:{lineStyle:{color:ug.color.accent30},itemStyle:{color:ug.color.accent40}},data:[]}),e}(mX);E(xX,Vv.prototype);var _X=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}(Ky),bX=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}(SM),wX=Math.PI,SX=Pa(),MX=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 Ty("nameValue",{noName:!0,value:a.scale.getLabel({value:t})})},B(["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 Jf(t.getBoxLayoutParams(),eg(t,e).refContainer,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"},c={horizontal:n>=0||"+"===n?"top":"bottom",vertical:"middle"},h={horizontal:0,vertical:wX/2},d="vertical"===s?l.height:l.width,p=t.getModel("controlStyle"),f=p.get("show",!0),g=f?p.get("itemSize"):0,v=f?p.get("itemGap"):0,y=g+v,m=t.get(["label","rotate"])||0;m=m*wX/180;var x=p.get("position",!0),_=f&&p.get("showPlayBtn",!0),b=f&&p.get("showPrevBtn",!0),w=f&&p.get("showNextBtn",!0),S=0,M=d;"left"===x||"bottom"===x?(_&&(i=[0,0],S+=y),b&&(r=[S,0],S+=y),w&&(o=[M-g,0],M-=y)):(_&&(i=[M-g,0],M-=y),b&&(r=[0,0],S+=y),w&&(o=[M-g,0],M-=y));var I=[S,M];return t.get("inverse")&&I.reverse(),{viewRect:l,mainLength:d,orient:s,rotation:h[s],labelRotation:m,labelPosOpt:n,labelAlign:t.get(["label","align"])||u[s],labelBaseline:t.get(["label","verticalAlign"])||t.get(["label","baseline"])||c[s],playPosition:i,prevBtnPosition:r,nextBtnPosition:o,axisExtent:I,controlSize:g,controlGap:v}},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;Te(o,o,[-a,-s]),Ce(o,o,-wX/2),Te(o,o,[a,s]),(r=r.clone()).applyTransform(o)}var l=v(r),u=v(n.getBoundingRect()),c=v(i.getBoundingRect()),h=[n.x,n.y],d=[i.x,i.y];d[0]=h[0]=l[0][0];var p,f=t.labelPosOpt;null==f||j(f)?(y(h,u,l,1,p="+"===f?0:1),y(d,c,l,1,1-p)):(y(h,u,l,1,p=f>=0?0:1),d[1]=h[1]+f);function g(t){t.originX=l[0][0]-t.x,t.originY=l[1][0]-t.y}function v(t){return[[t.x,t.x+t.width],[t.y,t.y+t.height]]}function y(t,e,n,i,r){t[i]+=n[i][r]-e[i][r]}n.setPosition(h),i.setPosition(d),n.rotation=i.rotation=t.rotation,g(n),g(i)},e.prototype._createAxis=function(t,e){var n=e.getData(),i=e.get("axisType")||e.get("type");"category"!==i&&"time"!==i&&(i="value");var r=Ww(e,i,!1);r.getTicks=function(){return n.mapArray(["value"],function(t){return{value:t}})};var o=n.getDataExtent("value");r.setExtent(o[0],o[1]),ES(r,{fixMinMax:[!0,!0]});var a=new bX("value",r,t.axisExtent,i);return a.model=e,a},e.prototype._createGroup=function(t){var e=this[t]=new vo;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 Oh({shape:{x1:r[0],y1:0,x2:r[1],y2:0},style:k({lineCap:"round"},i.getModel("lineStyle").getLineStyle()),silent:!0,z2:1});e.add(o);var a=this._progressLine=new Oh({shape:{x1:r[0],x2:this._currentPointer?this._currentPointer.x:r[0],y1:0,y2:0},style:P({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=[],B(a,function(t){var a=n.dataToCoord(t.value),s=o.getItemModel(t.value),l=s.getModel("itemStyle"),u=s.getModel(["emphasis","itemStyle"]),c=s.getModel(["progress","itemStyle"]),h={x:a,y:0,onclick:U(r._changeTimeline,r,t.value)},d=IX(s,l,e,h);d.ensureState("emphasis").style=u.getItemStyle(),d.ensureState("progress").style=c.getItemStyle(),Ac(d);var p=Iu(d);s.get("tooltip")?(p.dataIndex=t.value,p.dataModel=i):p.dataIndex=p.dataModel=null,r._tickSymbols.push(d)})},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=[],B(a,function(i){if(!i.tick.offInterval){var a=i.tick.value,s=o.getItemModel(a),l=s.getModel("label"),u=s.getModel(["emphasis","label"]),c=s.getModel(["progress","label"]),h=n.dataToCoord(a),d=new du({x:h,y:0,rotation:t.labelRotation-t.rotation,onclick:U(r._changeTimeline,r,a),silent:!1,style:sp(l,{text:i.formattedLabel,align:t.labelAlign,verticalAlign:t.labelBaseline})});d.ensureState("emphasis").style=sp(u),d.ensureState("progress").style=sp(c),e.add(d),Ac(d),SX(d).dataIndex=a,r._tickLabels.push(d)}})}},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 c(t,n,l,u){if(t){var c=Qr(at(i.get(["controlStyle",n+"BtnSize"]),r),r),h=function(t,e,n,i){var r=i.style,o=Od(t.get(["controlStyle",e]),i||{},new Xe(n[0],n[1],n[2],n[3]));r&&o.setStyle(r);return o}(i,n+"Icon",[0,-c/2,c,c],{x:t[0],y:t[1],originX:r/2,originY:0,rotation:u?-o:0,rectHover:!0,style:a,onclick:l});h.ensureState("emphasis").style=s,e.add(h),Ac(h)}}c(t.nextBtnPosition,"next",U(this._changeTimeline,this,u?"-":"+")),c(t.prevBtnPosition,"prev",U(this._changeTimeline,this,u?"+":"-")),c(t.playPosition,l?"stop":"play",U(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=U(s._handlePointerDrag,s),t.ondragend=U(s._handlePointerDragend,s),TX(t,s._progressLine,o,n,i,!0)},onUpdate:function(t){TX(t,s._progressLine,o,n,i)}};this._currentPointer=IX(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=Wo(this._axis.getExtent().slice());n>i[1]&&(n=i[1]),n=0&&(s[a]=+s[a].toFixed(d)),[s,h]}var zX={min:Y(EX,"min"),max:Y(EX,"max"),average:Y(EX,"average"),median:Y(EX,"median")};function BX(t,e){if(e){var n=t.getData(),i=t.coordinateSystem,r=i&&i.dimensions;if(!function(t){return!isNaN(parseFloat(t.x))&&!isNaN(parseFloat(t.y))}(e)&&!X(e.coord)&&X(r)){var o=VX(e,n,i,t);if((e=C(e)).type&&zX[e.type]&&o.baseAxis&&o.valueAxis){var a=R(r,o.baseAxis.dim),s=R(r,o.valueAxis.dim),l=zX[e.type](n,o.valueAxis.dim,o.baseDataDim,o.valueDataDim,a,s);e.coord=l[0],e.value=l[1]}else e.coord=[null!=e.xAxis?e.xAxis:e.radiusAxis,null!=e.yAxis?e.yAxis:e.angleAxis]}if(null!=e.coord&&X(r))for(var u=e.coord,c=0;c<2;c++)zX[u[c]]&&(u[c]=HX(n,n.mapDimension(r[c]),u[c]));else{e.coord=[];var h=t.getBaseAxis();if(h&&e.type&&zX[e.type]){var d=i.getOtherAxis(h);d&&(e.value=HX(n,n.mapDimension(d.dim),e.type))}}return e}}function VX(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 GX(t,e){return!(t&&t.containData&&e.coord&&!NX(e))||t.containData(e.coord)}function FX(t,e){return t?function(t,n,i,r){return Uv(r<2?t.coord&&t.coord[r]:t.value,e[r])}:function(t,n,i,r){return Uv(t.value,e[r])}}function HX(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 WX=Pa(),UX=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=mt()},e.prototype.render=function(t,e,n){var i=this,r=this.markerGroupMap;r.each(function(t){WX(t).keep=!1}),e.eachSeries(function(t){var r=OX.getMarkerModelFromSeries(t,i.type);r&&i.renderSeries(t,r,e,n)}),r.each(function(t){!WX(t).keep&&i.group.remove(t.group)}),function(t,e,n){t.eachSeries(function(t){var i=OX.getMarkerModelFromSeries(t,n),r=e.get(t.id);if(i&&r&&r.group){var o=Zd(i),a=o.z,s=o.zlevel;qd(r.group,a,s)}})}(e,r,this.type)},e.prototype.markKeep=function(t){WX(t).keep=!0},e.prototype.toggleBlurSeries=function(t,e){var n=this;B(t,function(t){var i=OX.getMarkerModelFromSeries(t,n.type);i&&i.getData().eachItemGraphicEl(function(t){t&&(e?mc(t):xc(t))})})},e.type="marker",e}(Ky);function YX(t,e,n){var i=e.coordinateSystem,r=n.getWidth(),o=n.getHeight(),a=i&&i.getArea&&i.getArea();t.each(function(n){var s,l=t.getItemModel(n),u="coordinate"===l.get("relativeTo"),c=u?a?a.width:0:r,h=u?a?a.height:0:o,d=u&&a?a.x:0,p=u&&a?a.y:0,f=Vo(l.get("x"),c)+d,g=Vo(l.get("y"),h)+p;if(isNaN(f)||isNaN(g)){if(e.getMarkerPosition)s=e.getMarkerPosition(t.getValues(t.dimensions,n));else if(i){var v=t.get(i.dimensions[0],n),y=t.get(i.dimensions[1],n);s=i.dataToPoint([v,y])}}else s=[f,g];isNaN(f)||(s[0]=f),isNaN(g)||(s[1]=g),t.setItemLayout(n,s)})}var XX=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=OX.getMarkerModelFromSeries(t,"markPoint");e&&(YX(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 nC),u=function(t,e,n){var i;i=t?V(t&&t.dimensions,function(t){var n=e.getData();return k(k({},n.getDimensionInfo(n.mapDimension(t))||{}),{name:t,ordinalMeta:null})}):[{name:"value",type:"float"}];var r=new Hb(i,n),o=V(n.get("data"),Y(BX,e));t&&(o=F(o,Y(GX,t)));var a=FX(!!t,i);return r.initData(o,null,a),r}(r,t,e);e.setData(u),YX(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(Z(i)||Z(r)||Z(o)||Z(s)){var c=e.getRawValue(t),h=e.getDataParams(t);Z(i)&&(i=i(c,h)),Z(r)&&(r=r(c,h)),Z(o)&&(o=o(c,h)),Z(s)&&(s=s(c,h))}var d=n.getModel("itemStyle").getItemStyle(),p=n.get("z2"),f=qm(a,"color");d.fill||(d.fill=f),u.setItemVisual(t,{z2:at(p,0),symbol:i,symbolSize:r,symbolRotate:o,symbolOffset:s,symbolKeepAspect:l,style:d})}),l.updateData(u),this.group.add(l.group),u.eachItemGraphicEl(function(t){t.traverse(function(t){Iu(t).dataModel=e})}),this.markKeep(l),l.group.silent=e.get("silent")||t.get("silent")},e.type="markPoint",e}(UX);var ZX=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}(OX),jX=Pa(),qX=function(t,e,n,i){var r,o=t.getData();if(X(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=ot(i.yAxis,i.xAxis);else{var u=VX(i,o,e,t);s=u.valueAxis,l=HX(o,Kb(o,u.valueDataDim),a)}var c="x"===s.dim?0:1,h=1-c,d=C(i),p={coord:[]};d.type=null,d.coord=[],d.coord[h]=-1/0,p.coord[h]=1/0;var f=n.get("precision");f>=0&&K(l)&&(l=+l.toFixed(Math.min(f,20))),d.coord[c]=p.coord[c]=l,r=[d,p,{type:a,valueIndex:i.valueIndex,value:l}]}else r=[]}var g=[BX(t,r[0]),BX(t,r[1]),k({},r[2])];return g[2].type=g[2].type||null,D(g[2],g[0]),D(g[2],g[1]),g};function KX(t){return!isNaN(t)&&!isFinite(t)}function $X(t,e,n,i){var r=1-t,o=i.dimensions[t];return KX(e[r])&&KX(n[r])&&e[t]===n[t]&&i.getAxis(o).containData(e[t])}function JX(t,e){if("cartesian2d"===t.type){var n=e[0].coord,i=e[1].coord;if(n&&i&&($X(1,n,i,t)||$X(0,n,i,t)))return!0}return GX(t,e[0])&&GX(t,e[1])}function QX(t,e,n,i,r){var o,a=i.coordinateSystem,s=t.getItemModel(e),l=Vo(s.get("x"),r.getWidth()),u=Vo(s.get("y"),r.getHeight());if(isNaN(l)||isNaN(u)){if(i.getMarkerPosition)o=i.getMarkerPosition(t.getValues(t.dimensions,e));else{var c=a.dimensions,h=t.get(c[0],e),d=t.get(c[1],e);o=a.dataToPoint([h,d])}if(wC(a,"cartesian2d")){var p=a.getAxis("x"),f=a.getAxis("y");c=a.dimensions;KX(t.get(c[0],e))?o[0]=p.toGlobalCoord(p.getExtent()[n?0:1]):KX(t.get(c[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 tZ=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=OX.getMarkerModelFromSeries(t,"markLine");if(e){var i=e.getData(),r=jX(e).from,o=jX(e).to;r.each(function(e){QX(r,e,!0,t,n),QX(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 QN);this.group.add(l.group);var u=function(t,e,n){var i;i=t?V(t&&t.dimensions,function(t){var n=e.getData();return k(k({},n.getDimensionInfo(n.mapDimension(t))||{}),{name:t,ordinalMeta:null})}):[{name:"value",type:"float"}];var r=new Hb(i,n),o=new Hb(i,n),a=new Hb([],n),s=V(n.get("data"),Y(qX,e,t,n));t&&(s=F(s,Y(JX,t)));var l=FX(!!t,i);return r.initData(V(s,function(t){return t[0]}),null,l),o.initData(V(s,function(t){return t[1]}),null,l),a.initData(V(s,function(t){return t[2]})),a.hasItemOption=!0,{from:r,to:o,line:a}}(r,t,e),c=u.from,h=u.to,d=u.line;jX(e).from=c,jX(e).to=h,e.setData(d);var p=e.get("symbol"),f=e.get("symbolSize"),g=e.get("symbolRotate"),v=e.get("symbolOffset");function y(e,n,r){var o=e.getItemModel(n);QX(e,n,r,t,i);var s=o.getModel("itemStyle").getItemStyle();null==s.fill&&(s.fill=qm(a,"color")),e.setItemVisual(n,{symbolKeepAspect:o.get("symbolKeepAspect"),symbolOffset:at(o.get("symbolOffset",!0),v[r?0:1]),symbolRotate:at(o.get("symbolRotate",!0),g[r?0:1]),symbolSize:at(o.get("symbolSize"),f[r?0:1]),symbol:at(o.get("symbol",!0),p[r?0:1]),style:s})}X(p)||(p=[p,p]),X(f)||(f=[f,f]),X(g)||(g=[g,g]),X(v)||(v=[v,v]),u.from.each(function(t){y(c,t,!0),y(h,t,!1)}),d.each(function(t){var e=d.getItemModel(t),n=e.getModel("lineStyle").getLineStyle();d.setItemLayout(t,[c.getItemLayout(t),h.getItemLayout(t)]);var i=e.get("z2");null==n.stroke&&(n.stroke=c.getItemVisual(t,"style").fill),d.setItemVisual(t,{z2:at(i,0),fromSymbolKeepAspect:c.getItemVisual(t,"symbolKeepAspect"),fromSymbolOffset:c.getItemVisual(t,"symbolOffset"),fromSymbolRotate:c.getItemVisual(t,"symbolRotate"),fromSymbolSize:c.getItemVisual(t,"symbolSize"),fromSymbol:c.getItemVisual(t,"symbol"),toSymbolKeepAspect:h.getItemVisual(t,"symbolKeepAspect"),toSymbolOffset:h.getItemVisual(t,"symbolOffset"),toSymbolRotate:h.getItemVisual(t,"symbolRotate"),toSymbolSize:h.getItemVisual(t,"symbolSize"),toSymbol:h.getItemVisual(t,"symbol"),style:n})}),l.updateData(d),u.line.eachItemGraphicEl(function(t){Iu(t).dataModel=e,t.traverse(function(t){Iu(t).dataModel=e})}),this.markKeep(l),l.group.silent=e.get("silent")||t.get("silent")},e.type="markLine",e}(UX);var eZ=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}(OX),nZ=Pa(),iZ=function(t,e,n,i){var r=i[0],o=i[1];if(r&&o){var a=BX(t,r),s=BX(t,o),l=a.coord,u=s.coord;l[0]=ot(l[0],-1/0),l[1]=ot(l[1],-1/0),u[0]=ot(u[0],1/0),u[1]=ot(u[1],1/0);var c=A([{},a,s]);return c.coord=[a.coord,s.coord],c.x0=a.x,c.y0=a.y,c.x1=s.x,c.y1=s.y,c}};function rZ(t){return!isNaN(t)&&!isFinite(t)}function oZ(t,e,n,i){var r=1-t;return rZ(e[r])&&rZ(n[r])}function aZ(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 wC(t,"cartesian2d")?!(!n||!i||!oZ(1,n,i)&&!oZ(0,n,i))||function(t,e,n){return!(t&&t.containZone&&e.coord&&n.coord&&!NX(e)&&!NX(n))||t.containZone(e.coord,n.coord)}(t,r,o):GX(t,r)||GX(t,o)}function sZ(t,e,n,i,r){var o,a=i.coordinateSystem,s=t.getItemModel(e),l=Vo(s.get(n[0]),r.getWidth()),u=Vo(s.get(n[1]),r.getHeight());if(isNaN(l)||isNaN(u)){if(i.getMarkerPosition){var c=t.getValues(["x0","y0"],e),h=t.getValues(["x1","y1"],e),d=a.clampData(c),p=a.clampData(h),f=[];"x0"===n[0]?f[0]=d[0]>p[0]?h[0]:c[0]:f[0]=d[0]>p[0]?c[0]:h[0],"y0"===n[1]?f[1]=d[1]>p[1]?h[1]:c[1]:f[1]=d[1]>p[1]?c[1]:h[1],o=i.getMarkerPosition(f,n,!0)}else{var g=[m=t.get(n[0],e),x=t.get(n[1],e)];a.clampData&&a.clampData(g,g),o=a.dataToPoint(g,!0)}if(wC(a,"cartesian2d")){var v=a.getAxis("x"),y=a.getAxis("y"),m=t.get(n[0],e),x=t.get(n[1],e);rZ(m)?o[0]=v.toGlobalCoord(v.getExtent()["x0"===n[0]?0:1]):rZ(x)&&(o[1]=y.toGlobalCoord(y.getExtent()["y0"===n[1]?0:1]))}isNaN(l)||(o[0]=l),isNaN(u)||(o[1]=u)}else o=[l,u];return o}var lZ=[["x0","y0"],["x1","y0"],["x1","y1"],["x0","y1"]],uZ=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=OX.getMarkerModelFromSeries(t,"markArea");if(e){var i=e.getData();i.each(function(e){var r=V(lZ,function(r){return sZ(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 vo});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=V(t&&t.dimensions,function(t){var n=e.getData();return k(k({},n.getDimensionInfo(n.mapDimension(t))||{}),{name:t,ordinalMeta:null})});r=V(o,function(t,e){return{name:t,type:a[e%2].type}}),i=new Hb(r,n)}else i=new Hb(r=[{name:"value",type:"float"}],n);var s=V(n.get("data"),Y(iZ,e,t,n));t&&(s=F(s,Y(aZ,t)));var l=t?function(t,e,n,i){return Uv(t.coord[Math.floor(i/2)][i%2],r[i])}:function(t,e,n,i){return Uv(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=V(lZ,function(n){return sZ(u,e,n,t,i)}),o=r.getAxis("x").scale,s=r.getAxis("y").scale,l=o.getExtent(),c=s.getExtent(),h=[o.parse(u.get("x0",e)),o.parse(u.get("x1",e))],d=[s.parse(u.get("y0",e)),s.parse(u.get("y1",e))];Wo(h),Wo(d);var p=!!(l[0]>h[1]||l[1]d[1]||c[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",bottom:ug.size.m,align:"auto",backgroundColor:ug.color.transparent,borderColor:ug.color.border,borderRadius:0,borderWidth:0,padding:5,itemGap:8,itemWidth:25,itemHeight:14,symbolRotate:"inherit",symbolKeepAspect:!0,inactiveColor:ug.color.disabled,inactiveBorderColor:ug.color.disabled,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:ug.color.disabled,inactiveWidth:2,opacity:"inherit",type:"inherit",cap:"inherit",join:"inherit",dashOffset:"inherit",miterLimit:"inherit"},textStyle:{color:ug.color.secondary},selectedMode:!0,selector:!1,selectorLabel:{show:!0,borderRadius:10,padding:[3,5,3,5],fontSize:12,fontFamily:"sans-serif",color:ug.color.tertiary,borderWidth:1,borderColor:ug.color.border},emphasis:{selectorLabel:{show:!0,color:ug.color.quaternary}},selectorPosition:"auto",selectorItemGap:7,selectorButtonGap:10,tooltip:{show:!1},triggerEvent:!1},e}(lg),hZ=Y,dZ=B,pZ=vo,fZ=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 pZ),this.group.add(this._selectorGroup=new pZ),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=eg(t,n).refContainer,u=t.getBoxLayoutParams(),c=t.get("padding"),h=Jf(u,l,c),d=this.layoutInner(t,r,h,i,a,s),p=Jf(P({width:d.width,height:d.height},u),l,c);this.group.x=p.x-d.x,this.group.y=p.y-d.y,this.group.markRedraw(),this.group.add(this._backgroundEl=FU(d,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=mt(),u=e.get("selectedMode"),c=e.get("triggerEvent"),h=[];n.eachRawSeries(function(t){!t.get("legendHoverLink")&&h.push(t.id)}),dZ(e.getData(),function(r,o){var a=this,d=r.get("name");if(!this.newlineDisabled&&(""===d||"\n"===d)){var p=new pZ;return p.newline=!0,void s.add(p)}var f=n.getSeriesByName(d)[0];if(!l.get(d)){if(f){var g=f.getData(),v=g.getVisual("legendLineStyle")||{},y=g.getVisual("legendIcon"),m=g.getVisual("style"),x=this._createItem(f,d,o,r,e,t,v,m,y,u,i);x.on("click",hZ(gZ,d,null,i,h)).on("mouseover",hZ(vZ,f.name,null,i,h)).on("mouseout",hZ(yZ,f.name,null,i,h)),n.ssr&&x.eachChild(function(t){var e=Iu(t);e.seriesIndex=f.seriesIndex,e.dataIndex=o,e.ssrType="legend"}),c&&x.eachChild(function(t){a.packEventData(t,e,f,o,d)}),l.set(d,!0)}else n.eachRawSeries(function(a){var s=this;if(!l.get(d)&&a.legendVisualProvider){var p=a.legendVisualProvider;if(!p.containName(d))return;var f=p.indexOfName(d),g=p.getItemVisual(f,"style"),v=p.getItemVisual(f,"legendIcon"),y=gi(g.fill);y&&0===y[3]&&(y[3]=.2,g=k(k({},g),{fill:Mi(y,"rgba")}));var m=this._createItem(a,d,o,r,e,t,{},g,v,u,i);m.on("click",hZ(gZ,null,d,i,h)).on("mouseover",hZ(vZ,null,d,i,h)).on("mouseout",hZ(yZ,null,d,i,h)),n.ssr&&m.eachChild(function(t){var e=Iu(t);e.seriesIndex=a.seriesIndex,e.dataIndex=o,e.ssrType="legend"}),c&&m.eachChild(function(t){s.packEventData(t,e,a,o,d)}),l.set(d,!0)}},this);0}},this),r&&this._createSelector(r,e,i,o,a)},e.prototype.packEventData=function(t,e,n,i,r){var o={componentType:"legend",componentIndex:e.componentIndex,dataIndex:i,value:r,seriesIndex:n.seriesIndex};Iu(t).eventData=o},e.prototype._createSelector=function(t,e,n,i,r){var o=this.getSelectorGroup();dZ(t,function(t){var i=t.type,r=new du({style:{x:0,y:0,align:"center",verticalAlign:"middle"},onclick:function(){n.dispatchAction({type:"all"===i?"legendAllSelect":"legendInverseSelect",legendId:e.id})}});o.add(r),op(r,{normal:e.getModel("selectorLabel"),emphasis:e.getModel(["emphasis","selectorLabel"])},{defaultText:t.title}),Ac(r)})},e.prototype._createItem=function(t,e,n,i,r,o,a,s,l,u,c){var h=t.visualDrawType,d=r.get("itemWidth"),p=r.get("itemHeight"),f=r.isSelected(e),g=i.get("symbolRotate"),v=i.get("symbolKeepAspect"),y=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),dZ(t,function(n,i){"inherit"===t[i]&&(t[i]=e[i])})}var l=e.getModel("itemStyle"),u=l.getItemStyle(),c=0===t.lastIndexOf("empty",0)?"fill":"stroke",h=l.getShallow("decal");u.decal=h&&"inherit"!==h?Zx(h,a):i.decal,"inherit"===u.fill&&(u.fill=i[r]);"inherit"===u.stroke&&(u.stroke=i[c]);"inherit"===u.opacity&&(u.opacity=("fill"===r?i:n).opacity);s(u,i);var d=e.getModel("lineStyle"),p=d.getLineStyle();if(s(p,n),"auto"===u.fill&&(u.fill=i.fill),"auto"===u.stroke&&(u.stroke=i.fill),"auto"===p.stroke&&(p.stroke=i.fill),!o){var f=e.get("inactiveBorderWidth"),g=u[c];u.lineWidth="auto"===f?i.lineWidth>0&&g?2:0:u.lineWidth,u.fill=e.get("inactiveColor"),u.stroke=e.get("inactiveBorderColor"),p.stroke=d.get("inactiveColor"),p.lineWidth=d.get("inactiveWidth")}return{itemStyle:u,lineStyle:p}}(l=y||l||"roundRect",i,a,s,h,f,c),x=new pZ,_=i.getModel("textStyle");if(!Z(t.getLegendIcon)||y&&"inherit"!==y){var b="inherit"===y&&t.getData().getVisual("symbol")?"inherit"===g?t.getData().getVisual("symbolRotate"):g:0;x.add(function(t){var e=t.icon||"roundRect",n=xx(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=ug.color.neutral00,n.style.lineWidth=2);return n}({itemWidth:d,itemHeight:p,icon:l,iconRotate:b,itemStyle:m.itemStyle,lineStyle:m.lineStyle,symbolKeepAspect:v}))}else x.add(t.getLegendIcon({itemWidth:d,itemHeight:p,icon:l,iconRotate:g,itemStyle:m.itemStyle,lineStyle:m.lineStyle,symbolKeepAspect:v}));var w="left"===o?d+5:-5,S=o,M=r.get("formatter"),I=e;j(M)&&M?I=M.replace("{name}",null!=e?e:""):Z(M)&&(I=M(e));var T=f?_.getTextColor():i.get("inactiveColor");x.add(new du({style:sp(_,{text:I,x:w,y:p/2,fill:T,align:S,verticalAlign:"middle"},{inheritColor:T})}));var C=new lu({shape:x.getBoundingRect(),style:{fill:"transparent"}}),D=i.getModel("tooltip");return D.get("show")&&Gd({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),Ac(x),x.__legendDataIndex=n,x},e.prototype.layoutInner=function(t,e,n,i,r,o){var a=this.getContentGroup(),s=this.getSelectorGroup();qf(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){qf("horizontal",s,t.get("selectorItemGap",!0));var c=s.getBoundingRect(),h=[-c.x,-c.y],d=t.get("selectorButtonGap",!0),p=t.getOrient().index,f=0===p?"width":"height",g=0===p?"height":"width",v=0===p?"y":"x";"end"===o?h[p]+=l[f]+d:u[p]+=c[f]+d,h[1-p]+=l[g]/2-c[g]/2,s.x=h[0],s.y=h[1],a.x=u[0],a.y=u[1];var y={x:0,y:0};return y[f]=l[f]+d+c[f],y[g]=Math.max(l[g],c[g]),y[v]=Math.min(0,c[v]+h[1-p]),y}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}(Ky);function gZ(t,e,n,i){yZ(t,e,n,i),n.dispatchAction({type:"legendToggleSelect",name:null!=t?t:e}),vZ(t,e,n,i)}function vZ(t,e,n,i){n.usingTHL()||n.dispatchAction({type:"highlight",seriesName:t,name:e,excludeSeriesId:i})}function yZ(t,e,n,i){n.usingTHL()||n.dispatchAction({type:"downplay",seriesName:t,name:e,excludeSeriesId:i})}function mZ(t,e,n){var i="allSelect"===t||"inverseSelect"===t,r={},o=[];n.eachComponent({mainType:"legend",query:e},function(n){i?n[t]():n[t](e.name),xZ(n,r),o.push(n.componentIndex)});var a={};return n.eachComponent("legend",function(t){B(r,function(e,n){t[e?"select":"unSelect"](n)}),xZ(t,a)}),i?{selected:a,legendIndex:o}:{name:e.name,selected:a}}function xZ(t,e){var n=e||{};return B(t.getData(),function(e){var i=e.get("name");if("\n"!==i&&""!==i){var r=t.isSelected(i);wt(n,i)?n[i]=n[i]&&r:n[i]=r}}),n}var _Z=as(function(t){var e=t.findComponents({mainType:"legend"});e&&e.length&&t.filterSeries(function(t){for(var n=0;nn[r],f=[-h.x,-h.y];e||(f[i]=l[s]);var g=[0,0],v=[-d.x,-d.y],y=at(t.get("pageButtonGap",!0),t.get("itemGap",!0));p&&("end"===t.get("pageButtonPosition",!0)?v[i]+=n[r]-d[r]:g[i]+=d[r]+y);v[1-i]+=h[o]/2-d[o]/2,l.setPosition(f),u.setPosition(g),c.setPosition(v);var m={x:0,y:0};if(m[r]=p?n[r]:h[r],m[o]=Math.max(h[o],d[o]),m[a]=Math.min(0,d[a]+v[1-i]),u.__rectSize=n[r],p){var x={x:0,y:0};x[r]=Math.max(n[r]-d[r]-y,0),x[o]=m[o],u.setClipPath(new lu({shape:x})),u.__rectSize=x[r]}else c.eachChild(function(t){t.attr({invisible:!0,silent:!0})});var _=this._getPageInfo(t);return null!=_.pageIndex&&rd(l,{x:_.contentPosition[0],y:_.contentPosition[1]},p?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;B(["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",j(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=IZ[r],a=TZ[r],s=this._findTargetItemIndex(e),l=n.children(),u=l[s],c=l.length,h=c?1:0,d={contentPosition:[n.x,n.y],pageCount:h,pageIndex:h-1,pagePrevDataIndex:null,pageNextDataIndex:null};if(!u)return d;var p=m(u);d.contentPosition[r]=-p.s;for(var f=s+1,g=p,v=p,y=null;f<=c;++f)(!(y=m(l[f]))&&v.e>g.s+i||y&&!x(y,g.s))&&(g=v.i>g.i?v:y)&&(null==d.pageNextDataIndex&&(d.pageNextDataIndex=g.i),++d.pageCount),v=y;for(f=s-1,g=p,v=p,y=null;f>=-1;--f)(y=m(l[f]))&&x(v,y.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}(fZ);function DZ(t){gb(bZ),t.registerComponentModel(wZ),t.registerComponentView(CZ),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 AZ=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=Op(TU.defaultOption,{disabled:!1,zoomLock:!1,zoomOnMouseWheel:!0,moveOnMouseMove:!0,moveOnMouseWheel:!1,preventDefaultMouseMove:!0}),e}(TU),kZ=Pa();function LZ(t,e){if(e){t.removeKey(e.model.uid);var n=e.controller;n&&n.dispose()}}function PZ(t,e){t.isDisposed()||t.dispatchAction({type:"dataZoom",animation:{easing:"cubicOut",duration:100},batch:e})}function OZ(t,e,n,i){return t.coordinateSystem.containPoint([n,i])}function RZ(t){t.registerUpdateLifecycle("coordsys:aftercreate",function(t,e){var n=kZ(e),i=n.coordSysRecordMap||(n.coordSysRecordMap=mt());i.each(function(t){t.dataZoomInfoMap=null}),t.eachComponent({mainType:"dataZoom",subType:"inside"},function(t){B(bU(t).infoList,function(n){var r=n.model.uid,o=i.get(r)||i.set(r,function(t,e){var n={model:e,containsPoint:Y(OZ,e),dispatchAction:Y(PZ,t),dataZoomInfoMap:null,controller:null},i=n.controller=new uL(t.getZr());return B(["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=mt())).set(t.uid,{dzReferCoordSysInfo:n,model:t,getRange:null})})}),i.each(function(t){var n,r=t.controller,o=t.dataZoomInfoMap;if(o){var a=o.keys()[0];null!=a&&(n=o.get(a))}if(n){var s=function(t,e,n){var i,r,o,a="type_",s={type_true:2,type_move:1,type_false:0,type_undefined:-1},l=!0;return t.each(function(t){var e=t.model,n=!e.get("disabled",!0)&&(!e.get("zoomLock",!0)||"move");s[a+n]>s[a+i]&&(i=n),l=l&&e.get("preventDefaultMouseMove",!0),r=at(e.get("cursorGrab",!0),r),o=at(e.get("cursorGrabbing",!0),o)}),{controlType:i,opt:{zoomOnMouseWheel:!0,moveOnMouseMove:!0,moveOnMouseWheel:!0,preventDefaultMouseMove:!!l,api:n,zInfo:{component:e.model},triggerInfo:{roamTrigger:null,isInSelf:e.containsPoint},cursorGrab:r,cursorGrabbing:o}}}(o,t,e);r.enable(s.controlType,s.opt),cm(t,"dispatchAction",n.model.get("throttle",!0),"fixRate")}else LZ(i,t)})})}var NZ=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(),function(t,e,n){kZ(t).coordSysRecordMap.each(function(t){var i=t.dataZoomInfoMap.get(e.uid);i&&(i.getRange=n)})}(i,e,{pan:U(EZ.pan,this),zoom:U(EZ.zoom,this),scrollMove:U(EZ.scrollMove,this)}))},e.prototype.dispose=function(){this._clear(),t.prototype.dispose.apply(this,arguments)},e.prototype._clear=function(){!function(t,e){for(var n=kZ(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 c=this.dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan();return ez(0,o,[0,100],0,c.minSpan,c.maxSpan),this.range=o,r[0]!==o[0]||r[1]!==o[1]?o:void 0}},pan:zZ(function(t,e,n,i,r,o){var a=BZ[i]([o.oldX,o.oldY],[o.newX,o.newY],e,r,n);return a.signal*(t[1]-t[0])*a.pixel/a.pixelLength}),scrollMove:zZ(function(t,e,n,i,r,o){return BZ[i]([0,0],[o.scrollDelta,o.scrollDelta],e,r,n).signal*(t[1]-t[0])*o.scrollDelta})};function zZ(t){return function(e,n,i,r){var o=this.range,a=o.slice(),s=e.axisModels[0];if(s)return ez(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 BZ={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 VZ(t){RU(t),t.registerComponentModel(AZ),t.registerComponentView(NZ),RZ(t)}var GZ=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=Op(TU.defaultOption,{show:!0,right:"ph",top:"ph",width:"ph",height:"ph",left:null,bottom:null,borderColor:ug.color.accent10,borderRadius:0,backgroundColor:ug.color.transparent,dataBackground:{lineStyle:{color:ug.color.accent30,width:.5},areaStyle:{color:ug.color.accent20,opacity:.2}},selectedDataBackground:{lineStyle:{color:ug.color.accent40,width:.5},areaStyle:{color:ug.color.accent20,opacity:.3}},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:ug.color.neutral00,borderColor:ug.color.accent20},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:ug.color.accent40,opacity:.5},showDetail:!0,showDataShadow:"auto",realtime:!0,zoomLock:!1,textStyle:{color:ug.color.tertiary},brushSelect:!0,brushStyle:{color:ug.color.accent30,opacity:.3},emphasis:{handleLabel:{show:!0},handleStyle:{borderColor:ug.color.accent40},moveHandleStyle:{opacity:.8}},defaultLocationEdgeGap:15}),e}(TU),FZ=lu,HZ="horizontal",WZ="vertical",UZ=["line","bar","candlestick","scatter"],YZ={easing:"cubicOut",duration:100,delay:0},XZ=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=U(this._onBrush,this),this._onBrushEnd=U(this._onBrushEnd,this)},e.prototype.render=function(e,n,i,r){if(t.prototype.render.apply(this,arguments),cm(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(){hm(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 vo;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=eg(t,e).refContainer,r=this._findCoordRect(),o=t.get("defaultLocationEdgeGap",!0)||0,a=this._orient===HZ?{right:i.width-r.x-r.width,top:i.height-30-o-n,width:r.width,height:30}:{right:o,top:r.y,width:30,height:r.height},s=og(t.option);B(["right","top","width","height"],function(t){"ph"===s[t]&&(s[t]=a[t])});var l=Jf(s,i);this._location={x:l.x,y:l.y},this._size=[l.width,l.height],this._orient===WZ&&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!==HZ||r?n===HZ&&r?{scaleY:a?1:-1,scaleX:-1}:n!==WZ||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]),l=isNaN(s.x)?0:s.x,u=isNaN(s.y)?0:s.y;t.x=e.x-l,t.y=e.y-u,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 FZ({silent:!0,shape:{x:0,y:0,width:e[0],height:e[1]},style:{fill:t.get("backgroundColor")},z2:-40}));var r=new FZ({shape:{x:0,y:0,width:e[0],height:e[1]},style:{fill:"transparent"},z2:0,onclick:U(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(t.thisDim),c=r.getDataExtent(a),h=.3*(c[1]-c[0]);c=[c[0]-h,c[1]+h];var d,p=[0,e[1]],f=[0,e[0]],g=[[e[0],0],[0,0]],v=[],y=f[1]/Math.max(1,r.count()-1),m=e[0]/(u[1]-u[0]),x="time"===t.thisAxis.type,_=-y,b=Math.round(r.count()/e[0]);r.each([t.thisDim,a],function(t,e,n){if(b>0&&n%b)x||(_+=y);else{_=x?(+t-u[0])*m:_+y;var i=null==e||isNaN(e)||""===e,r=i?0:Bo(e,c,p,!0);i&&!d&&n?(g.push([g[g.length-1][0],0]),v.push([v[v.length-1][0],0])):!i&&d&&(g.push([_,0]),v.push([_,0])),i||(g.push([_,r]),v.push([_,r])),d=i}}),s=this._shadowPolygonPts=g,l=this._shadowPolylinePts=v}this._shadowData=r,this._shadowDim=a,this._shadowSize=[e[0],e[1]];for(var w=this.dataZoomModel,S=0;S<3;S++){var M=I(1===S);this._displayables.sliderGroup.add(M),this._displayables.dataShadowSegs.push(M)}}}function I(t){var e=w.getModel(t?"selectedDataBackground":"dataBackground"),n=new vo,i=new Dh({shape:{points:s},segmentIgnoreThreshold:1,style:e.getModel("areaStyle").getAreaStyle(),silent:!0,z2:-20}),r=new kh({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){B(t.getAxisProxy(r,o).getTargetSeriesModels(),function(t){if(!(n||!0!==e&&R(UZ,t.get("type"))<0)){var a,s=i.getComponent(xU(r),o).axis,l=function(t){var e={x:"y",y:"x",radius:"angle",angle:"radius"};return e[t]}(r),u=t.coordinateSystem;null!=l&&u.getOtherAxis&&(a=u.getOtherAxis(s).inverse),l=t.getData().mapDimension(l);var c=t.getData().mapDimension(r);n={thisAxis:s,series:t,thisDim:c,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"),c=e.filler=new FZ({silent:u,style:{fill:a.get("fillerColor")},textConfig:{position:"inside"}});r.add(c),r.add(new FZ({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:ug.color.transparent}})),B([0,1],function(e){var o=a.get("handleIcon");!vx[o]&&o.indexOf("path://")<0&&o.indexOf("image://")<0&&(o="path://"+o);var s,l=xx(o,-1,0,2,2,null,!0);l.attr({cursor:(s=this._orient,"vertical"===s?"ns-resize":"ew-resize"),draggable:!0,drift:U(this._onDragMove,this,e),ondragend:U(this._onDragEnd,this),onmouseover:U(this._onOverDataInfoTriggerArea,this,!0),onmouseout:U(this._onOverDataInfoTriggerArea,this,!1),z2:5});var u=l.getBoundingRect(),c=a.get("handleSize");this._handleHeight=Vo(c,this._size[1]),this._handleWidth=u.width/u.height*this._handleHeight,l.setStyle(a.getModel("handleStyle").getItemStyle()),l.style.strokeNoScale=!0,l.rectHover=!0,l.ensureState("emphasis").style=a.getModel(["emphasis","handleStyle"]).getItemStyle(),Ac(l);var h=a.get("handleColor");null!=h&&(l.style.fill=h),r.add(n[e]=l);var d=a.getModel("textStyle"),p=(a.get("handleLabel")||{}).show||!1;t.add(i[e]=new du({silent:!0,invisible:!p,style:sp(d,{x:0,y:0,text:"",verticalAlign:"middle",align:"center",fill:d.getTextColor(),font:d.getFont()}),z2:10}))},this);var h=c;if(u){var d=Vo(a.get("moveHandleSize"),o[1]),p=e.moveHandle=new lu({style:a.getModel("moveHandleStyle").getItemStyle(),silent:!0,shape:{r:[0,0,2,2],y:o[1]-.5,height:d}}),f=.8*d,g=e.moveHandleIcon=xx(a.get("moveHandleIcon"),-f/2,-f/2,f,f,ug.color.neutral00,!0);g.silent=!0,g.y=o[1]+d/2-.5,p.ensureState("emphasis").style=a.getModel(["emphasis","moveHandleStyle"]).getItemStyle();var v=Math.min(o[1]/2,Math.max(d,10));(h=e.moveZone=new lu({invisible:!0,shape:{y:o[1]-v,height:d+v}})).on("mouseover",function(){s.enterEmphasis(p)}).on("mouseout",function(){s.leaveEmphasis(p)}),r.add(p),r.add(g),r.add(h)}h.attr({draggable:!0,cursor:"grab",drift:U(this._onActualMoveZoneDrift,this),ondragstart:U(this._onActualMoveZoneDragStart,this),ondragend:U(this._onActualMoveZoneDragEnd,this),onmouseover:U(this._onOverDataInfoTriggerArea,this,!0),onmouseout:U(this._onOverDataInfoTriggerArea,this,!1)})},e.prototype._resetInterval=function(){var t=this._range=this.dataZoomModel.getPercentRange(),e=this._getViewExtent();this._handleEnds=[Bo(t[0],[0,100],e,!0),Bo(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];ez(e,i,r,n.get("zoomLock")?"all":t,null!=o.minSpan?Bo(o.minSpan,a,r,!0):null,null!=o.maxSpan?Bo(o.maxSpan,a,r,!0):null);var s=this._range,l=this._range=Wo([Bo(i[0],r,a,!0),Bo(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=Wo(n.slice()),r=this._size;B([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 Pe(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],o=this._handleEnds=[n.x,n.x+n.width],a=this.dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan();ez(0,o,i,0,null!=a.minSpan?Bo(a.minSpan,r,i,!0):null,null!=a.maxSpan?Bo(a.maxSpan,r,i,!0):null),this._range=Wo([Bo(o[0],i,r,!0),Bo(o[1],i,r,!0)]),this._updateView(),this._dispatchZoomAction(!1)}}}},e.prototype._onBrush=function(t){this._brushing&&(ye(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 FZ({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?YZ:null,start:e[0],end:e[1]})},e.prototype._findCoordRect=function(){var t,e=bU(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}(AU);function ZZ(t,e,n,i){var r=t.get("labelFormatter"),o=t.get("labelPrecision");null!=o&&"auto"!==o||(o=n.valuePrecision);var a=n.value[e],s=null==a||isNaN(a)?"":vw(i)||fw(i)?i.getLabel({value:Math.round(a)}):isFinite(o)?Ho(a,o,!0):a+"";return Z(r)?r(a,s):j(r)?r.replace("{value}",s):s}function jZ(t){t.registerComponentModel(GZ),t.registerComponentView(XZ),RU(t)}var qZ=function(t,e,n){var i=C((KZ[t]||{})[e]);return n&&X(i)?i[i.length-1]:i},KZ={color:{active:["#006edd","#e0ffff"],inactive:[ug.color.transparent]},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]}},$Z=ZR.mapVisual,JZ=ZR.eachVisual,QZ=X,tj=B,ej=Wo,nj=Bo,ij=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&&JY(n,t,this.replacableOptionKeys),this.textStyleModel=this.getModel("textStyle"),this.resetItemSize(),this.completeVisualOption()},e.prototype.resetVisual=function(t){var e=this.stateList;t=U(t,this),this.controllerVisuals=$Y(this.option.controller,e,t),this.targetVisuals=$Y(this.option.target,e,t)},e.prototype.getItemSymbol=function(){return null},e.prototype.getTargetSeriesIndices=function(){var t=this,e=this.option.seriesTargets;if(e){var n=[];return tj(e,function(e){if(null!=e.seriesIndex)n.push(e.seriesIndex);else if(null!=e.seriesId){var i;t.ecModel.eachSeries(function(t){t.id===e.seriesId&&(i=t)}),i&&n.push(i.componentIndex)}}),n}var i=this.option.seriesId,r=this.option.seriesIndex;return null==r&&null==i&&(r="all"),V(Ba(this.ecModel,"series",{index:r,id:i},{useDefault:!1,enableAll:!0,enableNone:!1}).models,function(t){return t.componentIndex})},e.prototype.eachTargetSeries=function(t,e){B(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||["<",">"],X(t)&&(t=t.slice(),i=!0);var l=e?t:i?[u(t[0]),u(t[1])]:u(t);return j(s)?s.replace("{value}",i?l[0]:l).replace("{value2}",i?l[1]:l):Z(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=ej([t.min,t.max]);this._dataExtent=e},e.prototype.getDimension=function(t){var e=this,n=this.option.seriesTargets;if(n){var i=H(n,function(n){return null!=n.seriesIndex&&n.seriesIndex===t||null!=n.seriesId&&n.seriesId===e.ecModel.getSeriesByIndex(t).id});if(i)return i.dimension}return this.option.dimension},e.prototype.getDataDimensionIndex=function(t){var e=t.hostModel.seriesIndex,n=this.getDimension(e);if(null!=n)return t.getDimensionIndex(n);for(var i=t.dimensions,r=i.length-1;r>=0;r--){var o=i[r],a=t.getDimensionInfo(o);if(!a.isCalculationCoord)return a.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={});D(i,n),D(r,n);var o=this.isCategory();function a(n){QZ(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]={},tj(i,function(t,e){if(ZR.isValidType(e)){var n=qZ(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";tj(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&&C(e)||(o?r:[r])),null==l.symbolSize&&(l.symbolSize=n&&C(n)||(o?s[0]:[s[0],s[0]])),l.symbol=$Z(l.symbol,function(t){return"none"===t?r:t});var u=l.symbolSize;if(null!=u){var c=-1/0;JZ(u,function(t){t>c&&(c=t)}),l.symbolSize=$Z(u,function(t){return nj(t,[0,c],[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,min:0,max:200,left:0,right:null,top:null,bottom:0,itemWidth:null,itemHeight:null,inverse:!1,orient:"vertical",backgroundColor:ug.color.transparent,borderColor:ug.color.borderTint,contentColor:ug.color.theme[0],inactiveColor:ug.color.disabled,borderWidth:0,padding:ug.size.m,textGap:10,precision:0,textStyle:{color:ug.color.secondary}},e}(lg),rj=[20,140],oj=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]=rj[0]),(null==e[1]||isNaN(e[1]))&&(e[1]=rj[1])},e.prototype._resetRange=function(){var t=this.getExtent(),e=this.option.range;!e||e.auto?(t.auto=1,this.option.range=t):X(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),B(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=Wo((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=aj(this,"outOfRange",this.getExtent()),n=aj(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 vo("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(),l=this._applyTransform("left",n.mainGroup);dj([0,1],function(u){var c=r[u];c.setStyle("fill",e.handlesColor[u]),c.y=t[u];var h=hj(t[u],[0,a[1]],s,!0),d=this.getControllerVisual(h,"symbolSize");c.scaleX=c.scaleY=d/a[0],c.x=a[0]-d/2;var p=Cd(n.handleLabelPoints[u],Td(c,this.group));if("horizontal"===this._orient){var f="left"===l||"top"===l?(a[0]-d)/2:(a[0]-d)/-2;p[1]+=f}o[u].setStyle({x:p[0],y:p[1],text:i.formatValueText(this._dataInterval[u]),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 c=this.getControllerVisual(t,"color",{convertOpacityToAlpha:!0}),h=this.getControllerVisual(t,"symbolSize"),d=hj(t,o,s,!0),p=a[0]-h/2,f={x:u.x,y:u.y};u.y=d,u.x=p;var g=Cd(l.indicatorLabelPoint,Td(u,this.group)),v=l.indicatorLabel;v.attr("invisible",!1);var y=this._applyTransform("left",l.mainGroup),m="horizontal"===this._orient;v.setStyle({text:(n||"")+r.formatValueText(e),verticalAlign:m?y:"middle",align:m?"center":y});var x={x:p,y:d,style:{fill:c}},_={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),v.animateTo(_,b)}else u.attr(x),v.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 c=this._hoverLinkDataIndices,h=[];(e||yj(n))&&(h=this._hoverLinkDataIndices=n.findTargetDataIndices(u));var d=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 wj(t,e,n,i){for(var r=e.targetVisuals[i],o=ZR.prepareVisualTypes(r),a={color:qm(t.getData(),"color")},s=0,l=o.length;s0:t.splitNumber>0)&&!t.calculable?"piecewise":"continuous"}),t.registerAction(xj,_j),B(bj,function(e){t.registerVisual(t.PRIORITY.VISUAL.COMPONENT,e)}),t.registerPreprocessor(Mj))}function Dj(t){t.registerComponentModel(oj),t.registerComponentView(gj),Cj(t)}var Aj=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=[],kj[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=C(r)):(t.dataExtent=this.getExtent(),t.mappingMethod="piecewise",t.pieceList=V(this._pieceList,function(t){return t=C(t),"inRange"!==e&&(t.visual=null),t}))})},e.prototype.completeVisualOption=function(){var e=this.option,n={},i=ZR.listVisualTypes(),r=this.isCategory();function o(t,e,n){return t&&t[e]&&t[e].hasOwnProperty(n)}B(e.pieces,function(t){B(i,function(e){t.hasOwnProperty(e)&&(n[e]=1)})}),B(n,function(t,n){var i=!1;B(this.stateList,function(t){i=i||o(e,t,n)||o(e.target,t,n)},this),!i&&B(this.stateList,function(t){(e[t]||(e[t]={}))[n]=qZ(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,B(i,function(t,e){var n=this.getSelectedMapKey(t);r.hasOwnProperty(n)||(r[n]=!0)},this),"single"===n.selectedMode){var o=!1;B(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=C(t)},e.prototype.getValueState=function(t){var e=ZR.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){ZR.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 B(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=Op(ij.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}(ij),kj={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 Lj(t,e){var n=t.inverse;("vertical"===t.orient?!n:n)&&e.reverse()}var Pj=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=this._getItemAlign(),o=e.itemSize,a=this._getViewData(),s=a.endsText,l=ot(e.get("showLabel",!0),!s),u=!e.get("selectedMode");s&&this._renderEndsText(t,s[0],o,l,r),B(a.viewPieceList,function(a){var s=a.piece,c=new vo;c.onclick=U(this._onItemClick,this,s),this._enableHoverLink(c,a.indexInModelPieceList);var h=e.getRepresentValue(s);if(this._createItemSymbol(c,h,[0,0,o[0],o[1]],u),l){var d=this.visualMapModel.getValueState(h),p=i.get("align")||r;c.add(new du({style:sp(i,{x:"right"===p?-n:o[0]+n,y:o[1]/2,text:s.text,verticalAlign:i.get("verticalAlign")||"middle",align:p,opacity:at(i.get("opacity"),"outOfRange"===d?.5:1)}),silent:u}))}t.add(c)},this),s&&this._renderEndsText(t,s[1],o,l,r),qf(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:cj(i.findTargetDataIndices(e),i)})}},e.prototype._getItemAlign=function(){var t=this.visualMapModel,e=t.option;if("vertical"===e.orient)return uj(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 vo,a=this.visualMapModel.textStyleModel;o.add(new du({style:sp(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=V(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,i){var r=xx(this.getControllerVisual(e,"symbol"),n[0],n[1],n[2],n[3],this.getControllerVisual(e,"color"));r.silent=i,t.add(r)},e.prototype._onItemClick=function(t){var e=this.visualMapModel,n=e.option,i=n.selectedMode;if(i){var r=C(n.selected),o=e.getSelectedMapKey(t);"single"===i||!0===i?(r[o]=!0,B(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}(sj);function Oj(t){t.registerComponentModel(Aj),t.registerComponentView(Pj),Cj(t)}var Rj=function(){function t(t){this._thumbnailModel=t}return t.prototype.reset=function(t){this._renderVersion=t.getECUpdateCycleVersion()},t.prototype.renderContent=function(t){var e=t.api.getViewOfComponentModel(this._thumbnailModel);e&&(t.group.silent=!0,e.renderContent({group:t.group,targetTrans:t.targetTrans,z2Range:jd(t.group),roamType:t.roamType,viewportRect:t.viewportRect,renderVersion:this._renderVersion}))},t.prototype.updateWindow=function(t,e){var n=e.getViewOfComponentModel(this._thumbnailModel);n&&n.updateWindow({targetTrans:t,renderVersion:this._renderVersion})},t}(),Nj=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.preventAutoZ=!0,n}return n(e,t),e.prototype.optionUpdated=function(t,e){this._updateBridge()},e.prototype._updateBridge=function(){var t=this._birdge=this._birdge||new Rj(this);(this._target=null,this.ecModel.eachSeries(function(t){dE(t,null)}),this.shouldShow())&&dE(this.getTarget().baseMapProvider,t)},e.prototype.shouldShow=function(){return this.getShallow("show",!0)},e.prototype.getBridge=function(){return this._birdge},e.prototype.getTarget=function(){if(this._target)return this._target;var t=this.getReferringComponents("series",{useDefault:!1,enableAll:!1,enableNone:!1}).models[0];return t?"graph"!==t.subType&&(t=null):t=this.ecModel.queryComponents({mainType:"series",subType:"graph"})[0],this._target={baseMapProvider:t},this._target},e.type="thumbnail",e.layoutMode="box",e.dependencies=["series","geo"],e.defaultOption={show:!0,right:1,bottom:1,height:"25%",width:"25%",itemStyle:{borderColor:ug.color.border,borderWidth:2},windowStyle:{borderWidth:1,color:ug.color.neutral30,borderColor:ug.color.neutral40,opacity:.3},z:10},e}(lg),Ej=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._api=n,this._model=t,this._coordSys||(this._coordSys=new nP),this._isEnabled()){this._renderVersion=n.getECUpdateCycleVersion();var i=this.group;i.removeAll();var r=t.getModel("itemStyle"),o=r.getItemStyle();null==o.fill&&(o.fill=e.get("backgroundColor")||ug.color.neutral00);var a=eg(t,n).refContainer,s=Jf(Kf(t,!0),a),l=o.lineWidth||0,u=this._contentRect=zd(s.clone(),l/2,!0,!0),c=new vo;i.add(c),c.setClipPath(new lu({shape:u.plain()}));var h=this._targetGroup=new vo;c.add(h);var d=s.plain();d.r=r.getShallow("borderRadius",!0),i.add(this._bgRect=new lu({style:o,shape:d,silent:!1,cursor:"grab"}));var p=t.getModel("windowStyle"),f=p.getShallow("borderRadius",!0);c.add(this._windowRect=new lu({shape:{x:0,y:0,width:0,height:0,r:f},style:p.getItemStyle(),silent:!1,cursor:"grab"})),this._dealRenderContent(),this._dealUpdateWindow(),Bj(t,this)}else this._clear()},e.prototype.renderContent=function(t){this._bridgeRendered=t,this._isEnabled()&&(this._dealRenderContent(),this._dealUpdateWindow(),Bj(this._model,this))},e.prototype._dealRenderContent=function(){var t=this._bridgeRendered;if(t&&t.renderVersion===this._renderVersion){var e=this._targetGroup,n=this._coordSys,i=this._contentRect;if(e.removeAll(),t){var r=t.group,o=r.getBoundingRect();e.add(r),this._bgRect.z2=t.z2Range.min-10,pP(n,o.x,o.y,o.width,o.height);var a=Jf({left:"center",top:"center",aspect:o.width/o.height},i);fP(n,a.x,a.y,a.width,a.height),lP(r,n,0),r.dirty(),this._windowRect.z2=t.z2Range.max+10,this._resetRoamController(t.roamType)}}},e.prototype.updateWindow=function(t){var e=this._bridgeRendered;e&&e.renderVersion===t.renderVersion&&(e.targetTrans=t.targetTrans),this._isEnabled()&&this._dealUpdateWindow()},e.prototype._dealUpdateWindow=function(){var t=this._bridgeRendered;if(t&&t.renderVersion===this._renderVersion){var e=Ae([],t.targetTrans),n=Ie([],rP(null,this._coordSys),e);this._transThisToTarget=Ae([],n);var i=t.viewportRect;(i=i?i.clone():new Xe(0,0,this._api.getWidth(),this._api.getHeight())).applyTransform(n);var r=this._windowRect,o=r.shape.r;r.setShape(P({r:o},i))}},e.prototype._resetRoamController=function(t){var e=this,n=this._api,i=this._roamController;i||(i=this._roamController=new uL(n.getZr())),t&&this._isEnabled()?(i.enable(t,{api:n,zInfo:{component:this._model},triggerInfo:{roamTrigger:null,isInSelf:function(t,n,i){return e._contentRect.contain(n,i)}}}),i.off("pan").off("zoom").on("pan",U(this._onPan,this)).on("zoom",U(this._onZoom,this))):i.disable()},e.prototype._onPan=function(t){var e=this._transThisToTarget;if(this._isEnabled()&&e){var n=Yt([],[t.oldX,t.oldY],e),i=Yt([],[t.oldX-t.dx,t.oldY-t.dy],e);this._api.dispatchAction(zj(this._model.getTarget().baseMapProvider,{dx:i[0]-n[0],dy:i[1]-n[1]}))}},e.prototype._onZoom=function(t){var e=this._transThisToTarget;if(this._isEnabled()&&e){var n=Yt([],[t.originX,t.originY],e);this._api.dispatchAction(zj(this._model.getTarget().baseMapProvider,{zoom:1/t.scale,originX:n[0],originY:n[1]}))}},e.prototype._isEnabled=function(){var t=this._model;return!(!t||!t.shouldShow())&&!!t.getTarget().baseMapProvider},e.prototype._clear=function(){this.group.removeAll(),this._bridgeRendered=null,this._roamController&&this._roamController.disable()},e.prototype.remove=function(){this._clear()},e.prototype.dispose=function(){this._clear()},e.type="thumbnail",e}(Ky);function zj(t,e){var n={type:"series"===t.mainType?t.subType+"Roam":t.mainType+"Roam"};return n[t.mainType+"Id"]=t.id,k(n,e),n}function Bj(t,e){var n=Zd(t);qd(e.group,n.z,n.zlevel)}var Vj={label:{enabled:!0},decal:{show:!1}},Gj=Pa(),Fj=Pa(),Hj=as(function(t,e){var n=t.getModel("aria");if(!n.get("enabled"))return;var i=Fj(t).scope||(Fj(t).scope={}),r=C(Vj);function o(t,e){if(!j(t))return t;var n=t;return B(e,function(t,e){n=n.replace(new RegExp("\\{\\s*"+e+"\\s*\\}","g"),t)}),n}D(r.label,t.getLocaleModel().get("aria"),!1),D(n.option,r,!1),function(){if(n.getModel("decal").get("show")){var e=mt();t.eachSeries(function(t){t.isColorBySeries()||(Gj(t).scope=e.get(t.type)||e.set(t.type,{}))}),t.eachSeries(function(e){if(Z(e.enableAriaDecal))e.enableAriaDecal();else{var n=e.getData();if(e.isColorBySeries()){var r=Rg(e.ecModel,e.name,i,t.getSeriesCount()),o=n.getVisual("decal");n.setVisual("decal",c(o,r))}else{var a=e.getRawData(),s={},l=Gj(e).scope;n.each(function(t){var e=n.getRawIndex(t);s[e]=t});var u=a.count();a.each(function(t){var i=s[t],r=a.getName(t)||t+"",o=Rg(e.ecModel,r,l,u),h=n.getItemVisual(i,"decal");n.setItemVisual(i,"decal",c(h,o))})}}function c(t,e){var n=t?k(k({},e),t):e;return n.dirty=!0,n}})}}(),function(){var i=e.getZr().dom;if(i){var r=t.getLocaleModel().get("aria"),a=n.getModel("label");if(a.option=P(a.option,r),a.get("enabled"))if(i.setAttribute("role","img"),a.get("description"))i.setAttribute("aria-label",a.get("description"));else{var s,l=t.getSeriesCount(),u=a.get(["data","maxCount"])||10,c=a.get(["series","maxCount"])||10,h=Math.min(l,c);if(!(l<1)){var d=function(){var e=t.get("title");return e&&e.length&&(e=e[0]),e&&e.text}();s=d?o(a.get(["general","withTitle"]),{title:d}):a.get(["general","withoutTitle"]);var p=[];s+=o(l>1?a.get(["series","multiple","prefix"]):a.get(["series","single","prefix"]),{seriesCount:l}),t.eachSeries(function(e,n){if(n1?a.get(["series","multiple",r]):a.get(["series","single",r]),{seriesId:e.seriesIndex,seriesName:e.get("name"),seriesType:(_=e.subType,b=t.getLocaleModel().get(["series","typeNames"]),b[_]||b.chart)});var s=e.getData();s.count()>u?i+=o(a.get(["data","partialData"]),{displayCnt:u}):i+=a.get(["data","allData"]);for(var c=a.get(["data","separator","middle"]),d=a.get(["data","separator","end"]),f=a.get(["data","excludeDimensionId"]),g=[],v=0;v":"gt",">=":"gte","=":"eq","!=":"ne","<>":"ne"},Yj=function(){function t(t){if(null==(this._condVal=j(t)?new RegExp(t):it(t)?t:null)){var e="";0,va(e)}}return t.prototype.evaluate=function(t){var e=typeof t;return j(e)?this._condVal.test(t):!!K(e)&&this._condVal.test(t+"")},t}(),Xj=function(){function t(){}return t.prototype.evaluate=function(){return this.value},t}(),Zj=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){aq(t,i)&&aq(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 lq(t,e,n,i,r,o,a,s,l,u){if(aq(t,n)&&aq(e,i)&&aq(r,a)&&aq(o,s))l.push(a,s);else{var c=2/u,h=c*c,d=a-t,p=s-e,f=Math.sqrt(d*d+p*p);d/=f,p/=f;var g=n-t,v=i-e,y=r-a,m=o-s,x=g*g+v*v,_=y*y+m*m;if(x=0&&_-w*w=0)l.push(a,s);else{var S=[],M=[];Hn(t,n,r,a,.5,S),Hn(e,i,o,s,.5,M),lq(S[0],M[0],S[1],M[1],S[2],M[2],S[3],M[3],l,u),lq(S[4],M[4],S[5],M[5],S[6],M[6],S[7],M[7],l,u)}}}}function uq(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),h=uq([l,u],c?0:1,e),d=(c?s:u)/h.length,p=0;p1?null:new Pe(p*l+t,p*u+e)}function pq(t,e,n){var i=new Pe;Pe.sub(i,n,e),i.normalize();var r=new Pe;return Pe.sub(r,t,e),r.dot(i)}function fq(t,e){var n=t[t.length-1];n&&n[0]===e[0]&&n[1]===e[1]||t.push(e)}function gq(t){var e=t.points,n=[],i=[];rl(e,n,i);var r=new Xe(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 Pe,c=new Pe;return o>a?(u.x=c.x=s+o/2,u.y=l,c.y=l+a):(u.y=c.y=l+a/2,u.x=s,c.x=s+o),function(t,e,n){for(var i=t.length,r=[],o=0;or,a=uq([i,r],o?0:1,e),s=o?"width":"height",l=o?"height":"width",u=o?"x":"y",c=o?"y":"x",h=t[s]/a.length,d=0;d0)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,c=0;(t&l)>0&&(u=1),(e&l)>0&&(c=1),s+=l*l*(3*u^c),0===c&&(1===u&&(t=l-1-t,e=l-1-e),a=t,t=e,e=a)}return s}function Pq(t){var e=1/0,n=1/0,i=-1/0,r=-1/0,o=V(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 V(o,function(o,a){return{cp:o,z:Lq(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 Oq(t){return mq(t.path,t.count)}function Rq(t){return X(t[0])}function Nq(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 Eq={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"),c=k({setToFinal:!0},a);Rq(t)&&(s=t,l=e),Rq(e)&&(s=e,l=t);for(var h=s?s===t:t.length>e.length,d=s?Nq(l,s):Nq(h?e:t,[h?t:e]),p=0,f=0;f1e4))for(var r=n.getIndices(),o=0;o0&&i.group.traverse(function(t){t instanceof Kl&&!t.animators.length&&t.animateFrom({style:{opacity:0}},r)})})}function Zq(t){var e=t.getModel("universalTransition").get("seriesKey");return e||t.id}function jq(t){return X(t)?t.sort().join(","):t}function qq(t){if(t.hostModel)return t.hostModel.getModel("universalTransition").get("divideShape")}function Kq(t,e){for(var n=0;na.vmin?n+=a.vmin-i+(t-a.vmin)/(a.vmax-a.vmin)*a.gapReal:n+=t-i,i=a.vmax,r=!1;break}n+=a.vmin-i+a.gapReal,i=a.vmax}return r&&(n+=t-i),n},transformOut:function(t,e){if(e&&2===e.depth)return t;for(var n=Qq,i=tK,r=!0,o=0,a=0;al?s.vmin+(t-l)/(u-l)*(s.vmax-s.vmin):i+t-n,i=s.vmax,r=!1;break}n=u,i=s.vmax}return r&&(o=i+t-n),o}},t}();function Jq(t,e){return new $q(t,e)}var Qq=0,tK=0;function eK(t,e,n,i,r,o){"no"!==t&&B(n,function(n){var a=iK(n,o);if(a)for(var s=e.length-1;s>=0;s--){var l=e[s],u=i(l),c=3*r/4;u>a.vmin-c&&ue[0]&&n=0&&t<.99999})(s)||(s=0),r.gapParsed.type="tpPrct",r.gapParsed.val=s,o=!0}}if(!o){var l=e.parse(t.gap);(!isFinite(l)||l<0)&&(l=0),r.gapParsed.type="tpAbs",r.gapParsed.val=l}}if(r.vmin===r.vmax&&(r.gapParsed.type="tpAbs",r.gapParsed.val=0),n&&n.noNegative&&B(["vmin","vmax"],function(t){r[t]<0&&(r[t]=0)}),r.vmin>r.vmax){var u=r.vmax;r.vmax=r.vmin,r.vmin=u}i.push(r)}}),i.sort(function(t,e){return t.vmin-e.vmin});var r=-1/0;return B(i,function(t,e){r>t.vmin&&(i[e]=null),r=t.vmax}),{breaks:F(i,function(t){return!!t})}}function oK(t,e){return aK(e)===aK(t)}function aK(t){return t.start+"_\0_"+t.end}function sK(t,e,n){var i=[];B(t,function(t,n){var r=e(t);r&&"vmin"===r.type&&i.push([n])}),B(t,function(n,r){var o=e(n);if(o&&"vmax"===o.type){var a=H(i,function(n){return oK(e(t[n[0]]).parsedBreak.breakOption,o.parsedBreak.breakOption)});a&&a.push(r)}});var r=[];return B(i,function(e){2===e.length&&r.push(n?e:[t[e[0]],t[e[1]]])}),r}function lK(t,e,n,i){if(e.break){var r=e.break.parsedBreak,o=H(n,function(t){return oK(t.breakOption,e.break.parsedBreak.breakOption)}),a={lookup:i,depth:2},s={vmin:t.transformOut(r.vmin,a),vmax:t.transformOut(r.vmax,a),breakOption:r.breakOption,gapParsed:C(o.gapParsed),gapReal:r.gapReal};return{tickVal:s[e.break.type],vBreak:{type:e.break.type,parsedBreak:s}}}}function uK(t,e,n,i,r){r.original=rK(t,e,n);var o=r.transformed=rK(t,e,n),a=r.lookup;o.breaks=V(o.breaks,function(t,n){var r={depth:2},o=e.transformIn(t.vmin,r),s=e.transformIn(t.vmax,r),l={type:t.gapParsed.type,val:"tpAbs"===t.gapParsed.type?e.transformIn(t.vmin+t.gapParsed.val,r)-o:t.gapParsed.val};return a.from[i+n]=o,a.to[i+n]=t.vmin,a.from[i+n+1]=s,a.to[i+n+1]=t.vmax,{vmin:o,vmax:s,gapParsed:l,gapReal:t.gapReal,breakOption:t.breakOption}})}var cK={vmin:"start",vmax:"end"};function hK(t,e){return e&&((t=t||{}).break={type:cK[e.type],start:e.parsedBreak.vmin,end:e.parsedBreak.vmax}),t}function dK(){var t;t={createBreakScaleMapper:Jq,pruneTicksByBreak:eK,addBreaksToTicks:nK,parseAxisBreakOption:rK,identifyAxisBreak:oK,serializeAxisBreakIdentifier:aK,retrieveAxisBreakPairs:sK,getTicksBreakOutwardTransform:lK,parseAxisBreakOptionInwardTransform:uK,makeAxisLabelFormatterParamBreak:hK},Hp||(Hp=t)}var pK=Pa();function fK(t,e,n,i,r){var o=n.axis;if(!o.scale.isBlank()&&Wp()){var a=Wp().retrieveAxisBreakPairs(o.scale.getTicks({breakTicks:"only_break"}),function(t){return t.break},!1);if(a.length){var s=n.getModel("breakArea"),l=s.get("zigzagAmplitude"),u=s.get("zigzagMinSpan"),c=s.get("zigzagMaxSpan");u=Math.max(2,u||0),c=Math.max(u,c||0);var h=s.get("expandOnClick"),d=s.get("zigzagZ"),p=s.getModel("itemStyle").getItemStyle(),f=p.stroke,g=p.lineWidth,v=p.lineDash,y=p.fill,m=new vo({ignoreModelZ:!0}),x=o.isHorizontal(),_=pK(e).visualList||(pK(e).visualList=[]);B(_,function(t){return t.shouldRemove=!0});for(var b=function(t){var e=a[t][0].break.parsedBreak,s=[];s[0]=o.toGlobalCoord(o.dataToCoord(e.vmin,!0)),s[1]=o.toGlobalCoord(o.dataToCoord(e.vmax,!0)),s[1]=x;C&&(M=x);var D=[],A=[];D[h]=n,A[h]=r,T||C||(D[h]+=S?-l:l,A[h]-=S?l:-l),D[m]=M,A[m]=M,b.push(D),w.push(A);var k=void 0;if(I=0;e--)t[e].shouldRemove&&t.splice(e,1)}(_)}}}function gK(t,e,n,i){var r=t.axis,o=n.transform;ct(i.style);var a=r.getExtent();r.inverse&&(a=a.slice()).reverse();var s=V(Wp().retrieveAxisBreakPairs(r.scale.getTicks({breakTicks:"only_break"}),function(t){return t.break},!1),function(t){var e=t[0].break.parsedBreak,n=[r.dataToCoord(e.vmin,!0),r.dataToCoord(e.vmax,!0)];return n[0]>n[1]&&n.reverse(),{coordPair:n,brkId:Wp().serializeAxisBreakIdentifier(e.breakOption)}});s.sort(function(t,e){return t.coordPair[0]-e.coordPair[0]});for(var l=a[0],u=null,c=0;c=0?s[0].width:s[1].width)+u.x)/2-l.x,h=Math.min(c,c-u.x),d=Math.max(c,c-u.x);a=(c-(d<0?d:h>0?h:0))/u.x}var p=new Pe,f=new Pe;Pe.scale(p,i,-a),Pe.scale(f,i,1-a),eI(n[0],p),eI(n[1],f)}}function g(t){var e=n[0].localRect,i=new Pe(e[pd[t]]*o[0][0],e[pd[t]]*o[0][1]);return Math.abs(i.y)<1e-5}}function yK(t,e){var n={breaks:[]};return B(e.breaks,function(i){if(i){var r=H(t.get("breaks",!0),function(t){return Wp().identifyAxisBreak(t,i)});if(r){var o=e.type,a={isExpanded:!!r.isExpanded};r.isExpanded=o===ZC||o!==jC&&(o===qC?!r.isExpanded:r.isExpanded),n.breaks.push({start:r.start,end:r.end,isExpanded:!!r.isExpanded,old:a})}}}),n}function mK(){var t;t={adjustBreakLabelPair:vK,buildAxisBreakLine:gK,rectCoordBuildBreakAxis:fK,updateModelAxisBreak:yK},YC||(YC=t)}function xK(t,e){B(t,function(t){if(!t.model.get(["axisLabel","inside"])){var n=function(t){var e,n,i=t.model,r=t.scale;if(!i.get(["axisLabel","show"])||r.isBlank())return;var o=r.getExtent();n=r instanceof Mw?r.count():(e=r.getTicks()).length;var a,s=t.getLabelModel(),l=Zw(t),u=1;n>40&&(u=Math.ceil(n/40));for(var c=0;c=0&&r.push({dataGroupId:e.oldDataGroupIds[n],data:e.oldData[n],divide:qq(e.oldData[n]),groupIdDim:t.dimension})}),B(_a(t.to),function(t){var i=Kq(n.updatedSeries,t);if(i>=0){var r=n.updatedSeries[i].getData();o.push({dataGroupId:e.oldDataGroupIds[i],data:r,divide:qq(r),groupIdDim:t.dimension})}}),r.length>0&&o.length>0&&Xq(r,o,i)}(t,i,n,e)});else{var o=function(t,e){var n=mt(),i=mt(),r=mt();return B(t.oldSeries,function(e,n){var o=t.oldDataGroupIds[n],a=t.oldData[n],s=Zq(e),l=jq(s);i.set(l,{dataGroupId:o,data:a}),X(s)&&B(s,function(t){r.set(t,{key:l,dataGroupId:o,data:a})})}),B(e.updatedSeries,function(t){if(t.isUniversalTransitionEnabled()&&t.isAnimationEnabled()){var e=t.get("dataGroupId"),o=t.getData(),a=Zq(t),s=jq(a),l=i.get(s);if(l)n.set(s,{oldSeries:[{dataGroupId:l.dataGroupId,divide:qq(l.data),data:l.data}],newSeries:[{dataGroupId:e,divide:qq(o),data:o}]});else if(X(a)){var u=[];B(a,function(t){var e=i.get(t);e.data&&u.push({dataGroupId:e.dataGroupId,divide:qq(e.data),data:e.data})}),u.length&&n.set(s,{oldSeries:u,newSeries:[{dataGroupId:e,data:o,divide:qq(o)}]})}else{var c=r.get(a);if(c){var h=n.get(c.key);h||(h={oldSeries:[{dataGroupId:c.dataGroupId,data:c.data,divide:qq(c.data)}],newSeries:[]},n.set(c.key,h)),h.newSeries.push({dataGroupId:e,data:o,divide:qq(o)})}}}}),n}(i,n);B(o.keys(),function(t){var n=o.get(t);Xq(n.oldSeries,n.newSeries,e)})}B(n.updatedSeries,function(t){t[Fy]&&(t[Fy]=!1)})}for(var a=t.getSeries(),s=i.oldSeries=[],l=i.oldDataGroupIds=[],u=i.oldData=[],c=0;c0&&t-1 in e)}var y=e.document,m={type:!0,src:!0,nonce:!0,noModule:!0};function x(e,t,n){var r,i=(n=n||y).createElement("script");for(r in i.text=e,m)t&&t[r]&&(i[r]=t[r]);n.head.appendChild(i).parentNode&&i.parentNode.removeChild(i)}var b="4.0.0",w=/HTML$/i,T=function(e,t){return new T.fn.init(e,t)};function C(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}T.fn=T.prototype={jquery:b,constructor:T,length:0,toArray:function(){return i.call(this)},get:function(e){return null==e?i.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=T.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return T.each(this,e)},map:function(e){return this.pushStack(T.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(i.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(T.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(T.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n+~]|"+E+")"+E+"*"),q=RegExp(E+"|>"),O=/[+~]/,L=y.documentElement,H=L.matches||L.msMatchesSelector;function P(){var e=[];function t(n,r){return e.push(n+" ")>T.expr.cacheLength&&delete t[e.shift()],t[n+" "]=r}return t}function R(e){return e&&void 0!==e.getElementsByTagName&&e}var M="\\["+E+"*("+A+")(?:"+E+"*([*^$|!~]?=)"+E+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+A+"))|)"+E+"*\\]",W=":("+A+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",$={ID:RegExp("^#("+A+")"),CLASS:RegExp("^\\.("+A+")"),TAG:RegExp("^("+A+"|[*])"),ATTR:RegExp("^"+M),PSEUDO:RegExp("^"+W),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+E+"*(even|odd|(([+-]|)(\\d*)n|)"+E+"*(?:([+-]|)"+E+"*(\\d+)|))"+E+"*\\)|)","i")},I=new RegExp(W),F=RegExp("\\\\[\\da-fA-F]{1,6}"+E+"?|\\\\([^\\r\\n\\f])","g"),B=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))};function _(e){return e.replace(F,B)}function U(e){T.error("Syntax error, unrecognized expression: "+e)}var X=RegExp("^"+E+"*,"+E+"*"),z=P();function Y(e,t){var n,r,i,o,a,s,u,l=z[e+" "];if(l)return t?0:l.slice(0);a=e,s=[],u=T.expr.preFilter;while(a){for(o in(!n||(r=X.exec(a)))&&(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=N.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace(D," ")}),a=a.slice(n.length)),$)(r=T.expr.match[o].exec(a))&&(!u[o]||(r=u[o](r)))&&(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?U(e):z(e,s).slice(0)}function G(e){for(var t=0,n=e.length,r="";t1)},removeAttr:function(e){return this.each(function(){T.removeAttr(this,e)})}}),T.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return void 0===e.getAttribute?T.prop(e,t,n):(1===o&&T.isXMLDoc(e)||(i=T.attrHooks[t.toLowerCase()]),void 0!==n)?null===n||!1===n&&0!==t.toLowerCase().indexOf("aria-")?void T.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=e.getAttribute(t))?void 0:r},attrHooks:{},removeAttr:function(e,t){var n,r=0,i=t&&t.match(Q);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),k&&(T.attrHooks.type={set:function(e,t){if("radio"===t&&C(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}});var J=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;function K(e,t){return t?"\0"===e?"\uFFFD":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e}T.escapeSelector=function(e){return(e+"").replace(J,K)};var Z=n.sort,ee=n.splice;function et(e,t){if(e===t)return en=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n?n:1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)?e==y||e.ownerDocument==y&&T.contains(y,e)?-1:t==y||t.ownerDocument==y&&T.contains(y,t)?1:0:4&n?-1:1}T.uniqueSort=function(e){var t,n=[],r=0,i=0;if(en=!1,Z.call(e,et),en){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)ee.call(e,n[r],1)}return e},T.fn.uniqueSort=function(){return this.pushStack(T.uniqueSort(i.apply(this)))};var en,er,ei,eo,ea,es,eu=0,el=0,ec=P(),ef=P(),ep=P(),ed=RegExp(E+"+","g"),eh=RegExp("^"+A+"$"),eg=T.extend({needsContext:RegExp("^"+E+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+E+"*((?:-\\d)?\\d*)"+E+"*\\)|)(?=[^-]|$)","i")},$),ev=/^(?:input|select|textarea|button)$/i,ey=/^h\d$/i,em=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ex=function(){eE()},eb=eS(function(e){return!0===e.disabled&&C(e,"fieldset")},{dir:"parentNode",next:"legend"});function ew(e,t,n,r){var i,o,s,u,l,c,f,p=t&&t.ownerDocument,d=t?t.nodeType:9;if(n=n||[],"string"!=typeof e||!e||1!==d&&9!==d&&11!==d)return n;if(!r&&(eE(t),t=t||eo,es)){if(11!==d&&(l=em.exec(e))){if(i=l[1]){if(9===d)return(s=t.getElementById(i))&&a.call(n,s),n;else if(p&&(s=p.getElementById(i))&&T.contains(t,s))return a.call(n,s),n}else if(l[2])return a.apply(n,t.getElementsByTagName(e)),n;else if((i=l[3])&&t.getElementsByClassName)return a.apply(n,t.getElementsByClassName(i)),n}if(!ep[e+" "]&&(!S||!S.test(e))){if(f=e,p=t,1===d&&(q.test(e)||N.test(e))){((p=O.test(e)&&R(t.parentNode)||t)!=t||k)&&((u=t.getAttribute("id"))?u=T.escapeSelector(u):t.setAttribute("id",u=T.expando)),o=(c=Y(e)).length;while(o--)c[o]=(u?"#"+u:":scope")+" "+G(c[o]);f=c.join(",")}try{return a.apply(n,p.querySelectorAll(f)),n}catch(t){ep(e,!0)}finally{u===T.expando&&t.removeAttribute("id")}}}return eq(e.replace(D,"$1"),t,n,r)}function eT(e){return e[T.expando]=!0,e}function eC(e){return function(t){if("form"in t){if(t.parentNode&&!1===t.disabled){if("label"in t)if("label"in t.parentNode)return t.parentNode.disabled===e;else return t.disabled===e;return t.isDisabled===e||!e!==t.isDisabled&&eb(t)===e}return t.disabled===e}return"label"in t&&t.disabled===e}}function ej(e){return eT(function(t){return t*=1,eT(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function eE(e){var t,n=e?e.ownerDocument||e:y;n!=eo&&9===n.nodeType&&(ea=(eo=n).documentElement,es=!T.isXMLDoc(eo),k&&y!=eo&&(t=eo.defaultView)&&t.top!==t&&t.addEventListener("unload",ex))}for(er in ew.matches=function(e,t){return ew(e,null,null,t)},ew.matchesSelector=function(e,t){if(eE(e),es&&!ep[t+" "]&&(!S||!S.test(t)))try{return H.call(e,t)}catch(e){ep(t,!0)}return ew(t,eo,null,[e]).length>0},T.expr={cacheLength:50,createPseudo:eT,match:eg,find:{ID:function(e,t){if(void 0!==t.getElementById&&es){var n=t.getElementById(e);return n?[n]:[]}},TAG:function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},CLASS:function(e,t){if(void 0!==t.getElementsByClassName&&es)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=_(e[1]),e[3]=_(e[3]||e[4]||e[5]||""),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||U(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&U(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return $.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&I.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{ID:function(e){var t=_(e);return function(e){return e.getAttribute("id")===t}},TAG:function(e){var t=_(e).toLowerCase();return"*"===e?function(){return!0}:function(e){return C(e,t)}},CLASS:function(e){var t=ec[e+" "];return t||(t=RegExp("(^|"+E+")"+e+"("+E+"|$)"))&&ec(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=T.attr(r,e);return null==i?"!="===t:!t||((i+="","="===t)?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i.replace(ed," ")+" ").indexOf(n)>-1:"|="===t&&(i===n||i.slice(0,n.length+1)===n+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,d,h=o!==a?"nextSibling":"previousSibling",g=t.parentNode,v=s&&t.nodeName.toLowerCase(),y=!u&&!s,m=!1;if(g){if(o){while(h){f=t;while(f=f[h])if(s?C(f,v):1===f.nodeType)return!1;d=h="only"===e&&!d&&"nextSibling"}return!0}if(d=[a?g.firstChild:g.lastChild],a&&y){m=(p=(l=(c=g[T.expando]||(g[T.expando]={}))[e]||[])[0]===eu&&l[1])&&l[2],f=p&&g.childNodes[p];while(f=++p&&f&&f[h]||(m=p=0)||d.pop())if(1===f.nodeType&&++m&&f===t){c[e]=[eu,p,m];break}}else if(y&&(m=p=(l=(c=t[T.expando]||(t[T.expando]={}))[e]||[])[0]===eu&&l[1]),!1===m){while(f=++p&&f&&f[h]||(m=p=0)||d.pop())if((s?C(f,v):1===f.nodeType)&&++m&&(y&&((c=f[T.expando]||(f[T.expando]={}))[e]=[eu,m]),f===t))break}return(m-=i)===r||m%r==0&&m/r>=0}}},PSEUDO:function(e,t){var n=T.expr.pseudos[e]||T.expr.setFilters[e.toLowerCase()]||U("unsupported pseudo: "+e);return n[T.expando]?n(t):n}},pseudos:{not:eT(function(e){var t=[],n=[],r=eN(e.replace(D,"$1"));return r[T.expando]?eT(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),t[0]=null,!n.pop()}}),has:eT(function(e){return function(t){return ew(e,t).length>0}}),contains:eT(function(e){return e=_(e),function(t){return(t.textContent||T.text(t)).indexOf(e)>-1}}),lang:eT(function(e){return eh.test(e||"")||U("unsupported lang: "+e),e=_(e).toLowerCase(),function(t){var n;do if(n=es?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===ea},focus:function(e){return e===eo.activeElement&&eo.hasFocus()&&!!(e.type||e.href||~e.tabIndex)},enabled:eC(!1),disabled:eC(!0),checked:function(e){return C(e,"input")&&!!e.checked||C(e,"option")&&!!e.selected},selected:function(e){return k&&e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!T.expr.pseudos.empty(e)},header:function(e){return ey.test(e.nodeName)},input:function(e){return ev.test(e.nodeName)},button:function(e){return C(e,"input")&&"button"===e.type||C(e,"button")},text:function(e){return C(e,"input")&&"text"===e.type},first:ej(function(){return[0]}),last:ej(function(e,t){return[t-1]}),eq:ej(function(e,t,n){return[n<0?n+t:n]}),even:ej(function(e,t){for(var n=0;nt?t:n;--r>=0;)e.push(r);return e}),gt:ej(function(e,t,n){for(var r=n<0?n+t:n;++r1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function eA(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s-1},l,!0),d=[function(e,t,r){var i=!u&&(r||t!=ei)||((n=t).nodeType?f(e,t,r):p(e,t,r));return n=null,i}];c-1&&(e[f]=!(u[f]=d))}}else h=eA(h===u?h.splice(y,h.length):h),o?o(null,u,h,c):a.apply(u,h)})}(c>1&&eD(d),c>1&&G(t.slice(0,c-1).concat({value:" "===t[c-2].type?"*":""})).replace(D,"$1"),r,c0,r=l.length>0,i=function(e,t,i,o,s){var c,f,p,d=0,h="0",g=e&&[],v=[],y=ei,m=e||r&&T.expr.find.TAG("*",s),x=eu+=null==y?1:Math.random()||.1;for(s&&(ei=t==eo||t||s);null!=(c=m[h]);h++){if(r&&c){f=0,t||c.ownerDocument==eo||(eE(c),i=!es);while(p=l[f++])if(p(c,t||eo,i)){a.call(o,c);break}s&&(eu=x)}n&&((c=!p&&c)&&d--,e&&g.push(c))}if(d+=h,n&&h!==d){f=0;while(p=u[f++])p(g,v,t,i);if(e){if(d>0)while(h--)g[h]||v[h]||(v[h]=j.call(o));v=eA(v)}a.apply(o,v),s&&!e&&v.length>0&&d+u.length>1&&T.uniqueSort(o)}return s&&(eu=x,ei=y),g},n?eT(i):i))).selector=e}return c}function eq(e,t,n,r){var i,o,s,u,l,c="function"==typeof e&&e,f=!r&&Y(e=c.selector||e);if(n=n||[],1===f.length){if((o=f[0]=f[0].slice(0)).length>2&&"ID"===(s=o[0]).type&&9===t.nodeType&&es&&T.expr.relative[o[1].type]){if(!(t=(T.expr.find.ID(_(s.matches[0]),t)||[])[0]))return n;c&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=eg.needsContext.test(e)?0:o.length;while(i--){if(s=o[i],T.expr.relative[u=s.type])break;if((l=T.expr.find[u])&&(r=l(_(s.matches[0]),O.test(o[0].type)&&R(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&G(o)))return a.apply(n,r),n;break}}}return(c||eN(e,f))(r,t,!es,n,!t||O.test(e)&&R(t.parentNode)||t),n}function eO(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&T(e).is(n))break;r.push(e)}return r}function eL(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}ek.prototype=T.expr.pseudos,T.expr.setFilters=new ek,eE(),T.find=ew,ew.compile=eN,ew.select=eq,ew.setDocument=eE,ew.tokenize=Y;var eH=T.expr.match.needsContext,eP=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function eR(e){return"<"===e[0]&&">"===e[e.length-1]&&e.length>=3}function eM(e,t,n){return"function"==typeof t?T.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?T.grep(e,function(e){return e===t!==n}):"string"!=typeof t?T.grep(e,function(e){return s.call(t,e)>-1!==n}):T.filter(t,e,n)}T.filter=function(e,t,n){var r=t[0];return(n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType)?T.find.matchesSelector(r,e)?[r]:[]:T.find.matches(e,T.grep(t,function(e){return 1===e.nodeType}))},T.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(T(e).filter(function(){for(t=0;t1?T.uniqueSort(n):n},filter:function(e){return this.pushStack(eM(this,e||[],!1))},not:function(e){return this.pushStack(eM(this,e||[],!0))},is:function(e){return!!eM(this,"string"==typeof e&&eH.test(e)?T(e):e||[],!1).length}});var eW,e$=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(T.fn.init=function(e,t){var n,r;if(!e)return this;if(e.nodeType)return this[0]=e,this.length=1,this;if("function"==typeof e)return void 0!==eW.ready?eW.ready(e):e(T);if(eR(n=e+""))n=[null,e,null];else{if("string"!=typeof e)return T.makeArray(e,this);n=e$.exec(e)}if(n&&(n[1]||!t))if(!n[1])return(r=y.getElementById(n[2]))&&(this[0]=r,this.length=1),this;else{if(t=t instanceof T?t[0]:t,T.merge(this,T.parseHTML(n[1],t&&t.nodeType?t.ownerDocument||t:y,!0)),eP.test(n[1])&&T.isPlainObject(t))for(n in t)"function"==typeof this[n]?this[n](t[n]):this.attr(n,t[n]);return this}return!t||t.jquery?(t||eW).find(e):this.constructor(t).find(e)}).prototype=T.fn,eW=T(y);var eI=/^(?:parents|prev(?:Until|All))/,eF={children:!0,contents:!0,next:!0,prev:!0};function eB(e,t){while((e=e[t])&&1!==e.nodeType);return e}function e_(e){return e}function eU(e){throw e}function eX(e,t,n,r){var i;try{e&&"function"==typeof(i=e.promise)?i.call(e).done(t).fail(n):e&&"function"==typeof(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n(e)}}T.fn.extend({has:function(e){var t=T(e,this),n=t.length;return this.filter(function(){for(var e=0;e-1:1===n.nodeType&&T.find.matchesSelector(n,e))){o.push(n);break}}return this.pushStack(o.length>1?T.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?s.call(T(e),this[0]):s.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(T.uniqueSort(T.merge(this.get(),T(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),T.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return eO(e,"parentNode")},parentsUntil:function(e,t,n){return eO(e,"parentNode",n)},next:function(e){return eB(e,"nextSibling")},prev:function(e){return eB(e,"previousSibling")},nextAll:function(e){return eO(e,"nextSibling")},prevAll:function(e){return eO(e,"previousSibling")},nextUntil:function(e,t,n){return eO(e,"nextSibling",n)},prevUntil:function(e,t,n){return eO(e,"previousSibling",n)},siblings:function(e){return eL((e.parentNode||{}).firstChild,e)},children:function(e){return eL(e.firstChild)},contents:function(e){return null!=e.contentDocument&&r(e.contentDocument)?e.contentDocument:(C(e,"template")&&(e=e.content||e),T.merge([],e.childNodes))}},function(e,t){T.fn[e]=function(n,r){var i=T.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=T.filter(r,i)),this.length>1&&(eF[e]||T.uniqueSort(i),eI.test(e)&&i.reverse()),this.pushStack(i)}}),T.Callbacks=function(e){e="string"==typeof e?(t=e,n={},T.each(t.match(Q)||[],function(e,t){n[t]=!0}),n):T.extend({},e);var t,n,r,i,o,a,s=[],u=[],l=-1,c=function(){for(a=a||e.once,o=r=!0;u.length;l=-1){i=u.shift();while(++l-1)s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?T.inArray(e,s)>-1:s.length>0},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=i="",this},disabled:function(){return!s},lock:function(){return a=u=[],i||r||(s=i=""),this},locked:function(){return!!a},fireWith:function(e,t){return!a&&(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),r||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},T.extend({Deferred:function(t){var n=[["notify","progress",T.Callbacks("memory"),T.Callbacks("memory"),2],["resolve","done",T.Callbacks("once memory"),T.Callbacks("once memory"),0,"resolved"],["reject","fail",T.Callbacks("once memory"),T.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},catch:function(e){return i.then(null,e)},pipe:function(){var e=arguments;return T.Deferred(function(t){T.each(n,function(n,r){var i="function"==typeof e[r[4]]&&e[r[4]];o[r[1]](function(){var e=i&&i.apply(this,arguments);e&&"function"==typeof e.promise?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+"With"](this,i?[e]:arguments)})}),e=null}).promise()},then:function(t,r,i){var o=0;function a(t,n,r,i){return function(){var s=this,u=arguments,l=function(){var e,l;if(!(t=o&&(r!==eU&&(s=void 0,u=[e]),n.rejectWith(s,u))}};t?c():(T.Deferred.getErrorHook&&(c.error=T.Deferred.getErrorHook()),e.setTimeout(c))}}return T.Deferred(function(e){n[0][3].add(a(0,e,"function"==typeof i?i:e_,e.notifyWith)),n[1][3].add(a(0,e,"function"==typeof t?t:e_)),n[2][3].add(a(0,e,"function"==typeof r?r:eU))}).promise()},promise:function(e){return null!=e?T.extend(e,i):i}},o={};return T.each(n,function(e,t){var a=t[2],s=t[5];i[t[1]]=a.add,s&&a.add(function(){r=s},n[3-e][2].disable,n[3-e][3].disable,n[0][2].lock,n[0][3].lock),a.add(t[3].fire),o[t[0]]=function(){return o[t[0]+"With"](this===o?void 0:this,arguments),this},o[t[0]+"With"]=a.fireWith}),i.promise(o),t&&t.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),o=i.call(arguments),a=T.Deferred(),s=function(e){return function(n){r[e]=this,o[e]=arguments.length>1?i.call(arguments):n,--t||a.resolveWith(r,o)}};if(t<=1&&(eX(e,a.done(s(n)).resolve,a.reject,!t),"pending"===a.state()||"function"==typeof(o[n]&&o[n].then)))return a.then();while(n--)eX(o[n],s(n),a.reject);return a.promise()}});var ez=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;T.Deferred.exceptionHook=function(t,n){t&&ez.test(t.name)&&e.console.warn("jQuery.Deferred exception",t,n)},T.readyException=function(t){e.setTimeout(function(){throw t})};var eY=T.Deferred();function eG(){y.removeEventListener("DOMContentLoaded",eG),e.removeEventListener("load",eG),T.ready()}T.fn.ready=function(e){return eY.then(e).catch(function(e){T.readyException(e)}),this},T.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--T.readyWait:T.isReady)||(T.isReady=!0,!0!==e&&--T.readyWait>0||eY.resolveWith(y,[T]))}}),T.ready.then=eY.then,"loading"!==y.readyState?e.setTimeout(T.ready):(y.addEventListener("DOMContentLoaded",eG),e.addEventListener("load",eG));var eV=/-([a-z])/g;function eQ(e,t){return t.toUpperCase()}function eJ(e){return e.replace(eV,eQ)}function eK(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType}function eZ(){this.expando=T.expando+eZ.uid++}eZ.uid=1,eZ.prototype={cache:function(e){var t=e[this.expando];return!t&&(t=Object.create(null),eK(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[eJ(t)]=n;else for(r in t)i[eJ(r)]=t[r];return n},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][eJ(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(eJ):(t=eJ(t))in r?[t]:t.match(Q)||[]).length;while(n--)delete r[t[n]]}(void 0===t||T.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!T.isEmptyObject(t)}};var e0=new eZ,e1=new eZ,e2=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,e3=/[A-Z]/g;function e4(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(e3,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{i=n,n="true"===i||"false"!==i&&("null"===i?null:i===+i+""?+i:e2.test(i)?JSON.parse(i):i)}catch(e){}e1.set(e,t,n)}else n=void 0;return n}T.extend({hasData:function(e){return e1.hasData(e)||e0.hasData(e)},data:function(e,t,n){return e1.access(e,t,n)},removeData:function(e,t){e1.remove(e,t)},_data:function(e,t,n){return e0.access(e,t,n)},_removeData:function(e,t){e0.remove(e,t)}}),T.fn.extend({data:function(e,t){var n,r,i,o=this[0],a=o&&o.attributes;if(void 0===e){if(this.length&&(i=e1.get(o),1===o.nodeType&&!e0.get(o,"hasDataAttrs"))){n=a.length;while(n--)a[n]&&0===(r=a[n].name).indexOf("data-")&&e4(o,r=eJ(r.slice(5)),i[r]);e0.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof e?this.each(function(){e1.set(this,e)}):V(this,function(t){var n;if(o&&void 0===t)return void 0!==(n=e1.get(o,e))||void 0!==(n=e4(o,e))?n:void 0;this.each(function(){e1.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){e1.remove(this,e)})}}),T.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=e0.get(e,t),n&&(!r||Array.isArray(n)?r=e0.set(e,t,T.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=T.queue(e,t),r=n.length,i=n.shift(),o=T._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){T.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return e0.get(e,n)||e0.set(e,n,{empty:T.Callbacks("once memory").add(function(){e0.remove(e,[t+"queue",n])})})}}),T.fn.extend({queue:function(e,t){var n=2;return("string"!=typeof e&&(t=e,e="fx",n--),arguments.length\x20\t\r\n\f]*)/i,tc={thead:["table"],col:["colgroup","table"],tr:["tbody","table"],td:["tr","tbody","table"]};function tf(e,t){var r;return(r=void 0!==e.getElementsByTagName?n.slice.call(e.getElementsByTagName(t||"*")):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&C(e,t))?T.merge([e],r):r}tc.tbody=tc.tfoot=tc.colgroup=tc.caption=tc.thead,tc.th=tc.td;var tp=/^$|^module$|\/(?:java|ecma)script/i;function td(e,t){for(var n=0,r=e.length;n-1)s=s.appendChild(t.createElement(u[c]));s.innerHTML=T.htmlPrefilter(a),T.merge(p,s.childNodes),(s=f.firstChild).textContent=""}else p.push(t.createTextNode(a));f.textContent="",d=0;while(a=p[d++]){if(i&&T.inArray(a,i)>-1){o&&o.push(a);continue}if(l=ts(a),s=tf(f.appendChild(a),"script"),l&&td(s),r){c=0;while(a=s[c++])tp.test(a.type||"")&&r.push(a)}}return f}function tv(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function ty(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function tm(e,t,n,r){t=o(t);var i,a,s,u,l,c,f=0,p=e.length,d=p-1,h=t[0];if("function"==typeof h)return e.each(function(i){var o=e.eq(i);t[0]=h.call(this,i,o.html()),tm(o,t,n,r)});if(p&&(a=(i=tg(t,e[0].ownerDocument,!1,e,r)).firstChild,1===i.childNodes.length&&(i=a),a||r)){for(u=(s=T.map(tf(i,"script"),tv)).length;f=1)){for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(n=0,o=[],a={};n-1:T.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}}return l=this,u0&&td(a,!u&&tf(e,"script")),s},cleanData:function(e){for(var t,n,r,i=T.event.special,o=0;void 0!==(n=e[o]);o++)if(eK(n)){if(t=n[e0.expando]){if(t.events)for(r in t.events)i[r]?T.event.remove(n,r):T.removeEvent(n,r,t.handle);n[e0.expando]=void 0}n[e1.expando]&&(n[e1.expando]=void 0)}}}),T.fn.extend({detach:function(e){return tD(this,e,!0)},remove:function(e){return tD(this,e)},text:function(e){return V(this,function(e){return void 0===e?T.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=e)})},null,e,arguments.length)},append:function(){return tm(this,arguments,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&tk(this,e).appendChild(e)})},prepend:function(){return tm(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=tk(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return tm(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return tm(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(T.cleanData(tf(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return T.clone(this,e,t)})},html:function(e){return V(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!tE.test(e)&&!tc[(tl.exec(e)||["",""])[1].toLowerCase()]){e=T.htmlPrefilter(e);try{for(;nT.inArray(this,e)&&(T.cleanData(tf(this)),n&&n.replaceChild(t,this))},e)}}),T.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){T.fn[e]=function(e){for(var n,r=[],i=T(e),o=i.length-1,s=0;s<=o;s++)n=s===o?this:this.clone(!0),T(i[s])[t](n),a.apply(r,n);return this.pushStack(r)}});var tA=RegExp("^("+e5+")(?!px)[a-z%]+$","i"),tN=/^--/;function tq(t){var n=t.ownerDocument.defaultView;return n||(n=e),n.getComputedStyle(t)}function tO(e,t,n){var r,i=tN.test(t);return(n=n||tq(e))&&(r=n.getPropertyValue(t)||n[t],i&&r&&(r=r.replace(D,"$1")||void 0),""!==r||ts(e)||(r=T.style(e,t))),void 0!==r?r+"":r}var tL=["Webkit","Moz","ms"],tH=y.createElement("div").style;function tP(e){return e in tH?e:function(e){var t=e[0].toUpperCase()+e.slice(1),n=tL.length;while(n--)if((e=tL[n]+t)in tH)return e}(e)||e}var tR,tM,tW=y.createElement("table");function t$(){if(tW&&tW.style){var t,n=y.createElement("col"),r=y.createElement("tr"),i=y.createElement("td");if(tW.style.cssText="position:absolute;left:-11111px;border-collapse:separate;border-spacing:0",r.style.cssText="box-sizing:content-box;border:1px solid;height:1px",i.style.cssText="height:9px;width:9px;padding:0",n.span=2,L.appendChild(tW).appendChild(n).parentNode.appendChild(r).appendChild(i).parentNode.appendChild(i.cloneNode(!0)),0===tW.offsetWidth)return void L.removeChild(tW);t=e.getComputedStyle(r),tM=k||18===Math.round(parseFloat(e.getComputedStyle(n).width)),tR=Math.round(parseFloat(t.height)+parseFloat(t.borderTopWidth)+parseFloat(t.borderBottomWidth))===r.offsetHeight,L.removeChild(tW),tW=null}}T.extend(d,{reliableTrDimensions:function(){return t$(),tR},reliableColDimensions:function(){return t$(),tM}});var tI={position:"absolute",visibility:"hidden",display:"block"},tF={letterSpacing:"0",fontWeight:"400"};function tB(e,t,n){var r=e9.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function t_(e,t,n,r,i,o){var a=+("width"===t),s=0,u=0,l=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(l+=T.css(e,n+e6[a],!0,i)),r?("content"===n&&(u-=T.css(e,"padding"+e6[a],!0,i)),"margin"!==n&&(u-=T.css(e,"border"+e6[a]+"Width",!0,i))):(u+=T.css(e,"padding"+e6[a],!0,i),"padding"!==n?u+=T.css(e,"border"+e6[a]+"Width",!0,i):s+=T.css(e,"border"+e6[a]+"Width",!0,i));return!r&&o>=0&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u+l}function tU(e,t,n){var r=tq(e),i=(k||n)&&"border-box"===T.css(e,"boxSizing",!1,r),o=i,a=tO(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if(tA.test(a)){if(!n)return a;a="auto"}return("auto"===a||k&&i||!d.reliableColDimensions()&&C(e,"col")||!d.reliableTrDimensions()&&C(e,"tr"))&&e.getClientRects().length&&(i="border-box"===T.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+t_(e,t,n||(i?"border":"content"),o,r,a)+"px"}function tX(e,t,n,r,i){return new tX.prototype.init(e,t,n,r,i)}T.extend({cssHooks:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=ti(t),u=tN.test(t),l=e.style;if(u||(t=tP(s)),a=T.cssHooks[t]||T.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];if("string"==(o=typeof n)&&(i=e9.exec(n))&&i[1]&&(n=tn(e,t,i),o="number"),null!=n&&n==n)"number"===o&&(n+=i&&i[3]||(tt(s)?"px":"")),k&&""===n&&0===t.indexOf("background")&&(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n)}},css:function(e,t,n,r){var i,o,a,s=ti(t);return(tN.test(t)||(t=tP(s)),(a=T.cssHooks[t]||T.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=tO(e,t,r)),"normal"===i&&t in tF&&(i=tF[t]),""===n||n)?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),T.each(["height","width"],function(e,t){T.cssHooks[t]={get:function(e,n,r){if(n)return"none"===T.css(e,"display")?function(e,t,n){var r,i,o={};for(i in t)o[i]=e.style[i],e.style[i]=t[i];for(i in r=n.call(e),t)e.style[i]=o[i];return r}(e,tI,function(){return tU(e,t,r)}):tU(e,t,r)},set:function(e,n,r){var i,o=tq(e),a=r&&"border-box"===T.css(e,"boxSizing",!1,o),s=r?t_(e,t,r,a,o):0;return s&&(i=e9.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=T.css(e,t)),tB(e,n,s)}}}),T.each({margin:"",padding:"",border:"Width"},function(e,t){T.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+e6[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(T.cssHooks[e+t].set=tB)}),T.fn.extend({css:function(e,t){return V(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=tq(e),i=t.length;a1)}}),T.Tween=tX,tX.prototype={constructor:tX,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||T.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(tt(n)?"px":"")},cur:function(){var e=tX.propHooks[this.prop];return e&&e.get?e.get(this):tX.propHooks._default.get(this)},run:function(e){var t,n=tX.propHooks[this.prop];return this.options.duration?this.pos=t=T.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):tX.propHooks._default.set(this),this}},tX.prototype.init.prototype=tX.prototype,tX.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=T.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){T.fx.step[e.prop]?T.fx.step[e.prop](e):1===e.elem.nodeType&&(T.cssHooks[e.prop]||null!=e.elem.style[tP(e.prop)])?T.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},T.easing={linear:function(e){return e},swing:function(e){return .5-Math.cos(e*Math.PI)/2},_default:"swing"},T.fx=tX.prototype.init,T.fx.step={};var tz,tY,tG=/^(?:toggle|show|hide)$/,tV=/queueHooks$/;function tQ(){return e.setTimeout(function(){tz=void 0}),tz=Date.now()}function tJ(e,t){var n,r=0,i={height:e};for(t=+!!t;r<4;r+=2-t)i["margin"+(n=e6[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function tK(e,t,n){for(var r,i=(tZ.tweeners[t]||[]).concat(tZ.tweeners["*"]),o=0,a=i.length;o1)},removeProp:function(e){return this.each(function(){delete this[T.propFix[e]||e]})}}),T.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return(1===o&&T.isXMLDoc(e)||(t=T.propFix[t]||t,i=T.propHooks[t]),void 0!==n)?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=e.getAttribute("tabindex");return t?parseInt(t,10):t0.test(e.nodeName)||t1.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),k&&(T.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),T.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){T.propFix[this.toLowerCase()]=this}),T.fn.extend({addClass:function(e){var t,n,r,i,o,a;return"function"==typeof e?this.each(function(t){T(this).addClass(e.call(this,t,t3(this)))}):(t=t4(e)).length?this.each(function(){if(r=t3(this),n=1===this.nodeType&&" "+t2(r)+" "){for(o=0;on.indexOf(" "+i+" ")&&(n+=i+" ");r!==(a=t2(n))&&this.setAttribute("class",a)}}):this},removeClass:function(e){var t,n,r,i,o,a;return"function"==typeof e?this.each(function(t){T(this).removeClass(e.call(this,t,t3(this)))}):arguments.length?(t=t4(e)).length?this.each(function(){if(r=t3(this),n=1===this.nodeType&&" "+t2(r)+" "){for(o=0;o-1)n=n.replace(" "+i+" "," ")}r!==(a=t2(n))&&this.setAttribute("class",a)}}):this:this.attr("class","")},toggleClass:function(e,t){var n,r,i,o;return"function"==typeof e?this.each(function(n){T(this).toggleClass(e.call(this,n,t3(this),t),t)}):"boolean"==typeof t?t?this.addClass(e):this.removeClass(e):(n=t4(e)).length?this.each(function(){for(i=0,o=T(this);i-1)return!0;return!1}}),T.fn.extend({val:function(e){var t,n,r,i=this[0];if(!arguments.length)return i?(t=T.valHooks[i.type]||T.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:null==(n=i.value)?"":n:void 0;return r="function"==typeof e,this.each(function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,T(this).val()):e)?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=T.map(i,function(e){return null==e?"":e+""})),(t=T.valHooks[this.type]||T.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))})}}),T.extend({valHooks:{select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),k&&(T.valHooks.option={get:function(e){var t=e.getAttribute("value");return null!=t?t:t2(T.text(e))}}),T.each(["radio","checkbox"],function(){T.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=T.inArray(T(e).val(),t)>-1}}});var t5=/^(?:focusinfocus|focusoutblur)$/,t9=function(e){e.stopPropagation()};T.extend(T.event,{trigger:function(t,n,r,i){var o,a,s,u,l,f,p,d,h=[r||y],v=c.call(t,"type")?t.type:t,m=c.call(t,"namespace")?t.namespace.split("."):[];if((a=d=s=r=r||y,!(3===r.nodeType||8===r.nodeType||t5.test(v+T.event.triggered)))&&(v.indexOf(".")>-1&&(v=(m=v.split(".")).shift(),m.sort()),l=0>v.indexOf(":")&&"on"+v,(t=t[T.expando]?t:new T.Event(v,"object"==typeof t&&t)).isTrigger=i?2:3,t.namespace=m.join("."),t.rnamespace=t.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=r),n=null==n?[t]:T.makeArray(n,[t]),p=T.event.special[v]||{},i||!p.trigger||!1!==p.trigger.apply(r,n))){if(!i&&!p.noBubble&&!g(r)){for(u=p.delegateType||v,!t5.test(u+v)&&(a=a.parentNode);a;a=a.parentNode)h.push(a),s=a;s===(r.ownerDocument||y)&&h.push(s.defaultView||s.parentWindow||e)}o=0;while((a=h[o++])&&!t.isPropagationStopped())d=a,t.type=o>1?u:p.bindType||v,(f=(e0.get(a,"events")||Object.create(null))[t.type]&&e0.get(a,"handle"))&&f.apply(a,n),(f=l&&a[l])&&f.apply&&eK(a)&&(t.result=f.apply(a,n),!1===t.result&&t.preventDefault());return t.type=v,!i&&!t.isDefaultPrevented()&&(!p._default||!1===p._default.apply(h.pop(),n))&&eK(r)&&l&&"function"==typeof r[v]&&!g(r)&&((s=r[l])&&(r[l]=null),T.event.triggered=v,t.isPropagationStopped()&&d.addEventListener(v,t9),r[v](),t.isPropagationStopped()&&d.removeEventListener(v,t9),T.event.triggered=void 0,s&&(r[l]=s)),t.result}},simulate:function(e,t,n){var r=T.extend(new T.Event,n,{type:e,isSimulated:!0});T.event.trigger(r,null,t)}}),T.fn.extend({trigger:function(e,t){return this.each(function(){T.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return T.event.trigger(e,t,n,!0)}});var t6=e.location,t8={guid:Date.now()},t7=/\?/;T.parseXML=function(t){var n,r;if(!t||"string"!=typeof t)return null;try{n=new e.DOMParser().parseFromString(t,"text/xml")}catch(e){}return r=n&&n.getElementsByTagName("parsererror")[0],(!n||r)&&T.error("Invalid XML: "+(r?T.map(r.childNodes,function(e){return e.textContent}).join("\n"):t)),n};var ne=/\[\]$/,nt=/\r?\n/g,nn=/^(?:submit|button|image|reset|file)$/i,nr=/^(?:input|select|textarea|keygen)/i;T.param=function(e,t){var n,r=[],i=function(e,t){var n="function"==typeof t?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!T.isPlainObject(e))T.each(e,function(){i(this.name,this.value)});else for(n in e)!function e(t,n,r,i){var o;if(Array.isArray(n))T.each(n,function(n,o){r||ne.test(t)?i(t,o):e(t+"["+("object"==typeof o&&null!=o?n:"")+"]",o,r,i)});else if(r||"object"!==h(n))i(t,n);else for(o in n)e(t+"["+o+"]",n[o],r,i)}(n,e[n],t,i);return r.join("&")},T.fn.extend({serialize:function(){return T.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=T.prop(this,"elements");return e?T.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!T(this).is(":disabled")&&nr.test(this.nodeName)&&!nn.test(e)&&(this.checked||!tx.test(e))}).map(function(e,t){var n=T(this).val();return null==n?null:Array.isArray(n)?T.map(n,function(e){return{name:t.name,value:e.replace(nt,"\r\n")}}):{name:t.name,value:n.replace(nt,"\r\n")}}).get()}});var ni=/%20/g,no=/#.*$/,na=/([?&])_=[^&]*/,ns=/^(.*?):[ \t]*([^\r\n]*)$/mg,nu=/^(?:GET|HEAD)$/,nl=/^\/\//,nc={},nf={},np="*/".concat("*"),nd=y.createElement("a");function nh(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(Q)||[];if("function"==typeof n)while(r=o[i++])"+"===r[0]?(e[r=r.slice(1)||"*"]=e[r]||[]).unshift(n):(e[r]=e[r]||[]).push(n)}}function ng(e,t,n,r){var i={},o=e===nf;function a(s){var u;return i[s]=!0,T.each(e[s]||[],function(e,s){var l=s(t,n,r);return"string"!=typeof l||o||i[l]?o?!(u=l):void 0:(t.dataTypes.unshift(l),a(l),!1)}),u}return a(t.dataTypes[0])||!i["*"]&&a("*")}function nv(e,t){var n,r,i=T.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&T.extend(!0,e,r),e}nd.href=t6.href,T.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:t6.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(t6.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":np,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":T.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?nv(nv(e,T.ajaxSettings),t):nv(T.ajaxSettings,e)},ajaxPrefilter:nh(nc),ajaxTransport:nh(nf),ajax:function(t,n){"object"==typeof t&&(n=t,t=void 0),n=n||{};var r,i,o,a,s,u,l,c,f,p,d=T.ajaxSetup({},n),h=d.context||d,g=d.context&&(h.nodeType||h.jquery)?T(h):T.event,v=T.Deferred(),m=T.Callbacks("once memory"),x=d.statusCode||{},b={},w={},C="canceled",j={readyState:0,getResponseHeader:function(e){var t;if(l){if(!a){a={};while(t=ns.exec(o))a[t[1].toLowerCase()+" "]=(a[t[1].toLowerCase()+" "]||[]).concat(t[2])}t=a[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return l?o:null},setRequestHeader:function(e,t){return null==l&&(b[e=w[e.toLowerCase()]=w[e.toLowerCase()]||e]=t),this},overrideMimeType:function(e){return null==l&&(d.mimeType=e),this},statusCode:function(e){var t;if(e)if(l)j.always(e[j.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||C;return r&&r.abort(t),E(0,t),this}};if(v.promise(j),d.url=((t||d.url||t6.href)+"").replace(nl,t6.protocol+"//"),d.type=n.method||n.type||d.method||d.type,d.dataTypes=(d.dataType||"*").toLowerCase().match(Q)||[""],null==d.crossDomain){u=y.createElement("a");try{u.href=d.url,u.href=u.href,d.crossDomain=nd.protocol+"//"+nd.host!=u.protocol+"//"+u.host}catch(e){d.crossDomain=!0}}if(ng(nc,d,n,j),d.data&&d.processData&&"string"!=typeof d.data&&(d.data=T.param(d.data,d.traditional)),l)return j;for(f in(c=T.event&&d.global)&&0==T.active++&&T.event.trigger("ajaxStart"),d.type=d.type.toUpperCase(),d.hasContent=!nu.test(d.type),i=d.url.replace(no,""),d.hasContent?d.data&&d.processData&&0===(d.contentType||"").indexOf("application/x-www-form-urlencoded")&&(d.data=d.data.replace(ni,"+")):(p=d.url.slice(i.length),d.data&&(d.processData||"string"==typeof d.data)&&(i+=(t7.test(i)?"&":"?")+d.data,delete d.data),!1===d.cache&&(i=i.replace(na,"$1"),p=(t7.test(i)?"&":"?")+"_="+t8.guid+++p),d.url=i+p),d.ifModified&&(T.lastModified[i]&&j.setRequestHeader("If-Modified-Since",T.lastModified[i]),T.etag[i]&&j.setRequestHeader("If-None-Match",T.etag[i])),(d.data&&d.hasContent&&!1!==d.contentType||n.contentType)&&j.setRequestHeader("Content-Type",d.contentType),j.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+("*"!==d.dataTypes[0]?", "+np+"; q=0.01":""):d.accepts["*"]),d.headers)j.setRequestHeader(f,d.headers[f]);if(d.beforeSend&&(!1===d.beforeSend.call(h,j,d)||l))return j.abort();if(C="abort",m.add(d.complete),j.done(d.success),j.fail(d.error),r=ng(nf,d,n,j)){if(j.readyState=1,c&&g.trigger("ajaxSend",[j,d]),l)return j;d.async&&d.timeout>0&&(s=e.setTimeout(function(){j.abort("timeout")},d.timeout));try{l=!1,r.send(b,E)}catch(e){if(l)throw e;E(-1,e)}}else E(-1,"No Transport");function E(t,n,a,u){var f,p,y,b,w,C=n;!l&&(l=!0,s&&e.clearTimeout(s),r=void 0,o=u||"",j.readyState=4*(t>0),f=t>=200&&t<300||304===t,a&&(b=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r){for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(d,j,a)),!f&&T.inArray("script",d.dataTypes)>-1&&0>T.inArray("json",d.dataTypes)&&(d.converters["text script"]=function(){}),b=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift()){if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o])){for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}}if(!0!==a)if(a&&e.throws)t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}}return{state:"success",data:t}}(d,b,j,f),f?(d.ifModified&&((w=j.getResponseHeader("Last-Modified"))&&(T.lastModified[i]=w),(w=j.getResponseHeader("etag"))&&(T.etag[i]=w)),204===t||"HEAD"===d.type?C="nocontent":304===t?C="notmodified":(C=b.state,p=b.data,f=!(y=b.error))):(y=C,(t||!C)&&(C="error",t<0&&(t=0))),j.status=t,j.statusText=(n||C)+"",f?v.resolveWith(h,[p,C,j]):v.rejectWith(h,[j,C,y]),j.statusCode(x),x=void 0,c&&g.trigger(f?"ajaxSuccess":"ajaxError",[j,d,f?p:y]),m.fireWith(h,[j,C]),c&&(g.trigger("ajaxComplete",[j,d]),--T.active||T.event.trigger("ajaxStop")))}return j},getJSON:function(e,t,n){return T.get(e,t,n,"json")},getScript:function(e,t){return T.get(e,void 0,t,"script")}}),T.each(["get","post"],function(e,t){T[t]=function(e,n,r,i){return("function"==typeof n||null===n)&&(i=i||r,r=n,n=void 0),T.ajax(T.extend({url:e,type:t,dataType:i,data:n,success:r},T.isPlainObject(e)&&e))}}),T.ajaxPrefilter(function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")}),T._evalUrl=function(e,t,n){return T.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,scriptAttrs:t.crossOrigin?{crossOrigin:t.crossOrigin}:void 0,converters:{"text script":function(){}},dataFilter:function(e){T.globalEval(e,t,n)}})},T.fn.extend({wrapAll:function(e){var t;return this[0]&&("function"==typeof e&&(e=e.call(this[0])),t=T(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return"function"==typeof e?this.each(function(t){T(this).wrapInner(e.call(this,t))}):this.each(function(){var t=T(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t="function"==typeof e;return this.each(function(n){T(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not("body").each(function(){T(this).replaceWith(this.childNodes)}),this}}),T.expr.pseudos.hidden=function(e){return!T.expr.pseudos.visible(e)},T.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},T.ajaxSettings.xhr=function(){return new e.XMLHttpRequest};var ny={0:200};function nm(e){return e.scriptAttrs||!e.headers&&(e.crossDomain||e.async&&0>T.inArray("json",e.dataTypes))}T.ajaxTransport(function(e){var t;return{send:function(n,r){var i,o=e.xhr();if(o.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(i in e.xhrFields)o[i]=e.xhrFields[i];for(i in e.mimeType&&o.overrideMimeType&&o.overrideMimeType(e.mimeType),e.crossDomain||n["X-Requested-With"]||(n["X-Requested-With"]="XMLHttpRequest"),n)o.setRequestHeader(i,n[i]);t=function(e){return function(){t&&(t=o.onload=o.onerror=o.onabort=o.ontimeout=null,"abort"===e?o.abort():"error"===e?r(o.status,o.statusText):r(ny[o.status]||o.status,o.statusText,"text"===(o.responseType||"text")?{text:o.responseText}:{binary:o.response},o.getAllResponseHeaders()))}},o.onload=t(),o.onabort=o.onerror=o.ontimeout=t("error"),t=t("abort");try{o.send(e.hasContent&&e.data||null)}catch(e){if(t)throw e}},abort:function(){t&&t()}}}),T.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},converters:{"text script":function(e){return T.globalEval(e),e}}}),T.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),nm(e)&&(e.type="GET")}),T.ajaxTransport("script",function(e){if(nm(e)){var t,n;return{send:function(r,i){t=T(""; + exit; + } + if ($roleId == 0) { + mysqli_query($conn, "INSERT INTO sys_role(role_name) VALUES('".mysqli_real_escape_string($conn,$roleName)."')"); + $roleId = mysqli_insert_id($conn); + } else { + mysqli_query($conn, "UPDATE sys_role SET role_name='".mysqli_real_escape_string($conn,$roleName)."' WHERE id=$roleId"); + mysqli_query($conn, "DELETE FROM sys_role_permission WHERE role_id=$roleId"); + } + foreach ($pages as $page) { + $page = mysqli_real_escape_string($conn, $page); + mysqli_query($conn, "INSERT IGNORE INTO sys_role_permission(role_id,page_key) VALUES($roleId,'$page')"); + } + echo ""; + exit; +} +if (!empty($_GET['del_role'])) { + $delId = intval($_GET['del_role']); + mysqli_query($conn, "DELETE FROM sys_role_permission WHERE role_id=$delId"); + mysqli_query($conn, "DELETE FROM sys_role WHERE id=$delId"); + header("Location: system_manage.php?tab=role"); + exit; +} +// 修复警告:强制初始化为空数组,in_array不会报null +$editRole = ['id'=>0,'role_name'=>'','perms'=>[]]; +if (!empty($_GET['edit_role'])) { + $eid = intval($_GET['edit_role']); + $er = mysqli_fetch_assoc(mysqli_query($conn, "SELECT * FROM sys_role WHERE id=$eid")); + if ($er) { + $editRole = $er; + $permRes = mysqli_query($conn, "SELECT page_key FROM sys_role_permission WHERE role_id=$eid"); + $permsArr = []; + while ($p = mysqli_fetch_assoc($permRes)) { + $permsArr[] = $p['page_key']; + } + $editRole['perms'] = $permsArr; + } +} +$roleList = []; +$roleRes = mysqli_query($conn, "SELECT * FROM sys_role ORDER BY id DESC"); +while ($r = mysqli_fetch_assoc($roleRes)) $roleList[] = $r; + +// ========== 用户操作逻辑(沿用bak可创建逻辑 + 自动生成uid修复空值) ========== +if ($_POST['act'] == "save_user") { + $uid = intval($_POST['user_id'] ?? 0); + $username = trim($_POST['username']); + $realName = trim($_POST['real_name']); + $roleId = intval($_POST['role_id']); + $pwd = trim($_POST['password']); + $status = intval($_POST['status']); + if (empty($username) || empty($realName) || $roleId == 0) { + echo ""; + exit; + } + if ($uid == 0) { + if (empty($pwd)) { + echo ""; + exit; + } + // 自动生成唯一数字uid,解决空uid问题 + $maxUidRow = mysqli_fetch_assoc(mysqli_query($conn, "SELECT MAX(CAST(uid AS UNSIGNED)) max_uid FROM sys_user")); + $newUid = empty($maxUidRow['max_uid']) ? 1000 : intval($maxUidRow['max_uid']) + 1; + $pwdHash = password_hash($pwd, PASSWORD_DEFAULT); + // INSERT 补充uid字段,不再空白 + $insertSql = "INSERT INTO sys_user(uid,username,real_name,password,role_id,enable,is_admin) + VALUES('$newUid','".mysqli_real_escape_string($conn,$username)."','".mysqli_real_escape_string($conn,$realName)."','$pwdHash',$roleId,$status,0)"; + mysqli_query($conn, $insertSql); + } else { + $updateSql = "UPDATE sys_user SET + username='".mysqli_real_escape_string($conn,$username)."', + real_name='".mysqli_real_escape_string($conn,$realName)."', + role_id=$roleId, + enable=$status + WHERE id=$uid"; + if (!empty($pwd)) { + $pwdHash = password_hash($pwd, PASSWORD_DEFAULT); + $updateSql .= ", password='$pwdHash'"; + } + mysqli_query($conn, $updateSql); + } + echo ""; + exit; +} +if (!empty($_GET['del_user'])) { + $delId = intval($_GET['del_user']); + mysqli_query($conn, "DELETE FROM sys_user_msg WHERE user_id=$delId"); + mysqli_query($conn, "DELETE FROM sys_user WHERE id=$delId"); + header("Location: system_manage.php?tab=user"); + exit; +} +$roleOptionHtml = ""; +$roleDropRes = mysqli_query($conn, "SELECT id,role_name FROM sys_role"); +while ($r = mysqli_fetch_assoc($roleDropRes)) { + $roleOptionHtml .= ""; +} +// 用户列表过滤空uid异常用户 +$userList = []; +$uRes = mysqli_query($conn, "SELECT u.*,r.role_name FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid <> '' ORDER BY u.id DESC"); +while ($u = mysqli_fetch_assoc($uRes)) $userList[] = $u; +$editUser = ['id'=>0,'username'=>'','real_name'=>'','role_id'=>0,'status'=>1]; +if (!empty($_GET['edit_user'])) { + $eid = intval($_GET['edit_user']); + $eu = mysqli_fetch_assoc(mysqli_query($conn, "SELECT * FROM sys_user WHERE id=$eid")); + if ($eu) $editUser = $eu; +} + +$allPagePerms = [ + ['key'=>'dashboard','name'=>'告警总览'], + ['key'=>'work_order','name'=>'工单系统'], + ['key'=>'disk','name'=>'磁盘容量'], + ['key'=>'history_query','name'=>'历史查询'], + ['key'=>'smtp_config','name'=>'消息通知配置'], + ['key'=>'system_manage','name'=>'系统权限管理'], + ['key'=>'docker_mgr','name'=>'Docker容器管理'], +]; +?> + + + + + +<?php echo $pageTitle; ?> + + + + + +
+ +
+
+
+
+
Advantest
+
+
+
+
+ + + 0):?> + + + -- +
+ +
+ + +
+
+
+
+
+
+
角色管理
+
用户管理
+
+ +
+
+ + +
+ + +
+
+ +
+ +
+ > + +
+ +
+
+ +
+
+ + + + + + + + + + + + + +
ID角色名称操作
+ 编辑 + 删除 +
+
+
+ +
+
+ + +
+ + +
+
+ + +
+
+ + + +
+
+ + +
+
+ + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + +
ID登录账号姓名所属角色状态操作
+ 编辑 + 删除 +
+
+
+
+
+
+
+ + + diff --git a/system_manage.php.1.0 b/system_manage.php.1.0 new file mode 100644 index 0000000..786f09f --- /dev/null +++ b/system_manage.php.1.0 @@ -0,0 +1,374 @@ +alert('角色名称不能为空');location.href='system_manage.php?tab=role';"; + exit; + } + if ($roleId == 0) { + mysqli_query($conn, "INSERT INTO sys_role(role_name) VALUES('".mysqli_real_escape_string($conn,$roleName)."')"); + $roleId = mysqli_insert_id($conn); + } else { + mysqli_query($conn, "UPDATE sys_role SET role_name='".mysqli_real_escape_string($conn,$roleName)."' WHERE id=$roleId"); + mysqli_query($conn, "DELETE FROM sys_role_permission WHERE role_id=$roleId"); + } + foreach ($pages as $page) { + $page = mysqli_real_escape_string($conn, $page); + mysqli_query($conn, "INSERT IGNORE INTO sys_role_permission(role_id,page_key) VALUES($roleId,'$page')"); + } + echo ""; + exit; +} +if (!empty($_GET['del_role'])) { + $delId = intval($_GET['del_role']); + mysqli_query($conn, "DELETE FROM sys_role_permission WHERE role_id=$delId"); + mysqli_query($conn, "DELETE FROM sys_role WHERE id=$delId"); + header("Location: system_manage.php?tab=role"); + exit; +} +$editRole = ['id'=>0,'role_name'=>'','perms'=>[]]; +if (!empty($_GET['edit_role'])) { + $eid = intval($_GET['edit_role']); + $er = mysqli_fetch_assoc(mysqli_query($conn, "SELECT * FROM sys_role WHERE id=$eid")); + if ($er) { + $editRole = $er; + $permRes = mysqli_query($conn, "SELECT page_key FROM sys_role_permission WHERE role_id=$eid"); + while ($p = mysqli_fetch_assoc($permRes)) $editRole['perms'][] = $p['page_key']; + } +} +$roleList = []; +$roleRes = mysqli_query($conn, "SELECT * FROM sys_role ORDER BY id DESC"); +while ($r = mysqli_fetch_assoc($roleRes)) $roleList[] = $r; + +// ========== 用户操作逻辑(修复入库逻辑) ========== +if ($_POST['act'] == "save_user") { + $uid = intval($_POST['user_id'] ?? 0); + $username = trim($_POST['username']); + $realName = trim($_POST['real_name']); + $roleId = intval($_POST['role_id']); + $pwd = trim($_POST['password']); + $status = intval($_POST['status']); + if (empty($username) || empty($realName) || $roleId == 0) { + echo ""; + exit; + } + if ($uid == 0) { + // 新建用户必须填写密码,使用password_hash加密(和登录校验一致) + if (empty($pwd)) { + echo ""; + exit; + } + $pwdHash = password_hash($pwd, PASSWORD_DEFAULT); + // 适配monitor库sys_user真实字段:uid自动生成、enable状态、is_admin默认0 + $insertSql = "INSERT INTO sys_user(username,real_name,password,role_id,enable,is_admin) + VALUES('".mysqli_real_escape_string($conn,$username)."','".mysqli_real_escape_string($conn,$realName)."','$pwdHash',$roleId,$status,0)"; + mysqli_query($conn, $insertSql); + } else { + // 编辑用户,密码留空不修改 + $updateSql = "UPDATE sys_user SET + username='".mysqli_real_escape_string($conn,$username)."', + real_name='".mysqli_real_escape_string($conn,$realName)."', + role_id=$roleId, + enable=$status + WHERE id=$uid"; + if (!empty($pwd)) { + $pwdHash = password_hash($pwd, PASSWORD_DEFAULT); + $updateSql .= ", password='$pwdHash'"; + } + mysqli_query($conn, $updateSql); + } + echo ""; + exit; +} +if (!empty($_GET['del_user'])) { + $delId = intval($_GET['del_user']); + mysqli_query($conn, "DELETE FROM sys_user_msg WHERE user_id=$delId"); + mysqli_query($conn, "DELETE FROM sys_user WHERE id=$delId"); + header("Location: system_manage.php?tab=user"); + exit; +} +// 角色下拉选项 +$roleOptionHtml = ""; +$roleDropRes = mysqli_query($conn, "SELECT id,role_name FROM sys_role"); +while ($r = mysqli_fetch_assoc($roleDropRes)) { + $roleOptionHtml .= ""; +} +// 用户列表 +$userList = []; +$uRes = mysqli_query($conn, "SELECT u.*,r.role_name FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id ORDER BY u.id DESC"); +while ($u = mysqli_fetch_assoc($uRes)) $userList[] = $u; +// 编辑用户数据 +$editUser = ['id'=>0,'username'=>'','real_name'=>'','role_id'=>0,'status'=>1]; +if (!empty($_GET['edit_user'])) { + $eid = intval($_GET['edit_user']); + $eu = mysqli_fetch_assoc(mysqli_query($conn, "SELECT * FROM sys_user WHERE id=$eid")); + if ($eu) $editUser = $eu; +} + +// 全部页面权限清单 +$allPagePerms = [ + ['key'=>'dashboard','name'=>'告警总览'], + ['key'=>'work_order','name'=>'工单系统'], + ['key'=>'disk','name'=>'磁盘容量'], + ['key'=>'history_query','name'=>'历史查询'], + ['key'=>'smtp_config','name'=>'消息通知配置'], + ['key'=>'system_manage','name'=>'系统权限管理'], +]; +?> + + + + + <?php echo $pageTitle; ?> + + + + + +
+ +
+
+
+
+
Advantest
+
+
+
+
+ + + 0):?> + + + -- +
+ + +
+ + +
+
+
+
+
+
+
角色管理
+
用户管理
+
+ +
+
+ + +
+ + +
+
+ +
+ +
+ > + +
+ +
+
+ +
+ + + + + + + + + + + + + +
ID角色名称操作
+ 编辑 + 删除 +
+
+ +
+
+ + +
+ + +
+
+ + +
+
+ + + +
+
+ + +
+
+ + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
ID登录账号姓名所属角色状态操作
+ 编辑 + 删除 +
+
+
+
+
+
+ + + diff --git a/system_manage.php.bak b/system_manage.php.bak new file mode 100644 index 0000000..6ed68fb --- /dev/null +++ b/system_manage.php.bak @@ -0,0 +1,378 @@ +alert('角色名称不能为空');location.href='system_manage.php?tab=role';"; + exit; + } + if ($roleId == 0) { + mysqli_query($conn, "INSERT INTO sys_role(role_name) VALUES('$roleName')"); + $roleId = mysqli_insert_id($conn); + } else { + mysqli_query($conn, "UPDATE sys_role SET role_name='$roleName' WHERE id=$roleId"); + mysqli_query($conn, "DELETE FROM sys_role_permission WHERE role_id=$roleId"); + } + foreach ($pages as $page) { + $page = mysqli_real_escape_string($conn, $page); + mysqli_query($conn, "INSERT INTO sys_role_permission(role_id,page_key) VALUES($roleId,'$page')"); + } + echo ""; + exit; +} +// 删除角色 +if (!empty($_GET['del_role'])) { + $delId = intval($_GET['del_role']); + mysqli_query($conn, "DELETE FROM sys_role_permission WHERE role_id=$delId"); + mysqli_query($conn, "DELETE FROM sys_role WHERE id=$delId"); + header("Location: system_manage.php?tab=role"); + exit; +} +// 编辑角色数据 +$editRole = ['id'=>0,'role_name'=>'','perms'=>[]]; +if (!empty($_GET['edit_role'])) { + $eid = intval($_GET['edit_role']); + $er = mysqli_fetch_assoc(mysqli_query($conn, "SELECT * FROM sys_role WHERE id=$eid")); + if ($er) { + $editRole = $er; + $permRes = mysqli_query($conn, "SELECT page_key FROM sys_role_permission WHERE role_id=$eid"); + while ($p = mysqli_fetch_assoc($permRes)) $editRole['perms'][] = $p['page_key']; + } +} +// 角色列表 +$roleList = []; +$roleRes = mysqli_query($conn, "SELECT * FROM sys_role ORDER BY id DESC"); +while ($r = mysqli_fetch_assoc($roleRes)) $roleList[] = $r; + +// ========== 用户操作逻辑 ========== +// 保存用户 +if ($_POST['act'] == "save_user") { + $uid = intval($_POST['user_id'] ?? 0); + $username = trim($_POST['username']); + $realName = trim($_POST['real_name']); + $roleId = intval($_POST['role_id']); + $pwd = trim($_POST['password']); + $status = intval($_POST['status']); + if (empty($username) || empty($realName) || $roleId == 0) { + echo ""; + exit; + } + if ($uid == 0) { + if (empty($pwd)) { + echo ""; + exit; + } + $pwdMd5 = md5($pwd); + mysqli_query($conn, "INSERT INTO sys_user(username,password,real_name,role_id,status,is_admin) VALUES('$username','$pwdMd5','$realName',$roleId,$status,0)"); + } else { + $updateSql = "UPDATE sys_user SET username='$username',real_name='$realName',role_id=$roleId,status=$status WHERE id=$uid"; + if (!empty($pwd)) { + $pwdMd5 = md5($pwd); + $updateSql .= ",password='$pwdMd5'"; + } + mysqli_query($conn, $updateSql); + } + echo ""; + exit; +} +// 删除用户 +if (!empty($_GET['del_user'])) { + $delId = intval($_GET['del_user']); + mysqli_query($conn, "DELETE FROM sys_user_msg WHERE user_id=$delId"); + mysqli_query($conn, "DELETE FROM sys_user WHERE id=$delId"); + header("Location: system_manage.php?tab=user"); + exit; +} +// 用户下拉角色选项 +$roleOptionHtml = ""; +$roleDropRes = mysqli_query($conn, "SELECT id,role_name FROM sys_role"); +while ($r = mysqli_fetch_assoc($roleDropRes)) { + $roleOptionHtml .= ""; +} +// 用户列表 +$userList = []; +$uRes = mysqli_query($conn, "SELECT u.*,r.role_name FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id ORDER BY u.id DESC"); +while ($u = mysqli_fetch_assoc($uRes)) $userList[] = $u; +// 编辑用户数据 +$editUser = ['id'=>0,'username'=>'','real_name'=>'','role_id'=>0,'status'=>1]; +if (!empty($_GET['edit_user'])) { + $eid = intval($_GET['edit_user']); + $eu = mysqli_fetch_assoc(mysqli_query($conn, "SELECT * FROM sys_user WHERE id=$eid")); + if ($eu) $editUser = $eu; +} + +// 全部页面权限清单 +$allPagePerms = [ + ['key'=>'dashboard','name'=>'告警总览'], + ['key'=>'work_order','name'=>'工单系统'], + ['key'=>'disk','name'=>'磁盘容量'], + ['key'=>'history_query','name'=>'历史查询'], + ['key'=>'smtp_config','name'=>'消息通知配置'], + ['key'=>'system_manage','name'=>'系统权限管理'], +]; +mysqli_close($conn); +?> + + + + + <?php echo $pageTitle; ?> + + + + + +
+ +
+
+
+
+
Advantest
+
+
+
+
+ + + 0):?> + + + -- +
+ + +
+ + +
+
+
+
+
+ +
+
角色管理
+
用户管理
+
+ + +
+
+ + +
+ + +
+
+ +
+ +
+ > + +
+ +
+
+ +
+ + + + + + + + + + + + + +
ID角色名称操作
+ 编辑 + 删除 +
+
+ + +
+
+ + +
+ + +
+
+ + +
+
+ + + +
+
+ + +
+
+ + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
ID登录账号姓名所属角色状态操作
+ 编辑 + 删除 +
+
+
+
+
+
+ + + diff --git a/user_manage.php b/user_manage.php new file mode 100644 index 0000000..eb50800 --- /dev/null +++ b/user_manage.php @@ -0,0 +1,225 @@ +alert('账号、姓名、角色不能为空');history.back();";exit; + } + if ($uid == 0) { + // 新建用户密码MD5 + if (empty($pwd)) {echo "";exit;} + $pwdMd5 = md5($pwd); + mysqli_query($connConfig, "INSERT INTO sys_user(username,password,real_name,role_id,status,is_admin) VALUES('$username','$pwdMd5','$realName',$roleId,$status,0)"); + } else { + // 编辑用户,密码为空则不修改 + $updateSql = "UPDATE sys_user SET username='$username',real_name='$realName',role_id=$roleId,status=$status WHERE id=$uid"; + if (!empty($pwd)) { + $pwdMd5 = md5($pwd); + $updateSql .= ",password='$pwdMd5'"; + } + mysqli_query($connConfig, $updateSql); + } + echo "";exit; +} +// 删除用户 +if ($_GET['del']) { + $delId = intval($_GET['del']); + mysqli_query($connConfig, "DELETE FROM sys_user_msg WHERE user_id=$delId"); + mysqli_query($connConfig, "DELETE FROM sys_user WHERE id=$delId"); + header("Location: user_manage.php");exit; +} +// 读取角色下拉 +$roleOpt = ""; +$roleRes = mysqli_query($connConfig, "SELECT id,role_name FROM sys_role"); +while ($r = mysqli_fetch_assoc($roleRes)) { + $roleOpt .= ""; +} +// 用户列表 +$userList = []; +$uRes = mysqli_query($connConfig, "SELECT u.*,r.role_name FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id ORDER BY u.id DESC"); +while ($u = mysqli_fetch_assoc($uRes)) $userList[] = $u; +// 编辑用户 +$editUser = ['id'=>0,'username'=>'','real_name'=>'','role_id'=>'','status'=>1]; +if (!empty($_GET['edit'])) { + $eid = intval($_GET['edit']); + $eu = mysqli_fetch_assoc(mysqli_query($connConfig, "SELECT * FROM sys_user WHERE id=$eid")); + if ($eu) $editUser = $eu; +} +mysqli_close($connConfig); +?> + + + + + <?php echo $pageTitle; ?> + + + + + +
+ +
+
+
+
+
Advantest
+
+
+
+
+ + + 0):?> + + + -- +
+ + +
+ + +
+
+
+
+
新增/编辑用户
+
+ + +
+ + +
+
+ + +
+
+ + + +
+
+ + +
+
+ + + +
+ +
+
+
+
用户列表
+ + + + + + + + + + + + + + + + + + + +
ID登录账号姓名所属角色状态操作
+ 编辑 + 删除 +
+
+
+
+
+ + + diff --git a/work_order.php b/work_order.php new file mode 100644 index 0000000..dfdb1c9 --- /dev/null +++ b/work_order.php @@ -0,0 +1,1005 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRoleId = $_SESSION['role_id']; +$loginUid = $_SESSION['user_id']; + +// 全局配置库连接 +$dbConfigHost = "10.150.117.190"; +$dbConfigUser = "root"; +$dbConfigPwd = "hp93000"; +$dbConfigName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbConfigHost, $dbConfigUser, $dbConfigPwd, $dbConfigName); +if(!$connConfig){ + die("配置库连接失败"); +} +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} + +// 修复SMTP查询警告 +$smtpRow = []; +$sqlSmtp = "SELECT * FROM sys_smtp_config WHERE id=1"; +if (!empty(trim($sqlSmtp))) { + $smtpQuery = mysqli_query($connConfig, $sqlSmtp); + if ($smtpQuery !== false && $smtpQuery instanceof mysqli_result) { + $smtpRow = mysqli_fetch_assoc($smtpQuery) ?: []; + } +} +$smtpConfig = $smtpRow ?? []; + +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$currentLang = $sysConfig['lang'] ?? "zh"; +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +mysqli_close($connConfig); + +// 多语言词典(新增未读、待处理文案) +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警总览', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '系统参数', + 'notify_config' => '工单消息通知配置', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新页面', + 'export_csv' => '导出CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'work_order_mgr' => '工单系统', + 'work_create' => '新建工单', + 'work_edit' => '编辑工单', + 'work_assign' => '分发工单', + 'work_status' => '工单状态', + 'work_creator' => '创建人', + 'work_handler' => '处理人', + 'work_content' => '工单内容/备注', + 'work_title' => '工单标题', + 'create_time' => '创建时间', + 'update_time' => '更新时间', + 'all_work_order' => '全部工单列表', + 'no_work_data' => '暂无工单数据', + 'save' => '保存', + 'cancel' => '取消', + 'title_placeholder' => '填写故障/需求标题', + 'content_placeholder' => '详细描述故障现象、操作步骤、处理方案', + 'select_handler' => '选择处理人(留空暂不分配)', + 'status_1' => '待处理', + 'status_2' => '处理中', + 'status_3' => '已完成', + 'status_4' => '已关闭', + 'no_alert_option' => '不关联任何告警', + 'relate_alert' => '关联告警(可选)', + 'relate_alert_id' => '关联告警ID', + 'notify_title' => '通知配置', + 'notify_user' => '通知接收人', + 'notify_channel' => '通知渠道', + 'channel_mail' => '邮箱', + 'channel_ding' => '钉钉', + 'channel_wecom' => '企业微信', + 'smtp_host' => 'SMTP服务器', + 'smtp_port' => '端口', + 'smtp_ssl' => '开启SSL/TLS', + 'smtp_account' => '发件账号', + 'smtp_pwd' => '授权密码', + 'smtp_from' => '发件邮箱', + 'save_smtp' => '保存通知配置', + 'alert_loading' => '加载活跃告警...', + 'no_alert_data' => '当前无正在触发的告警', + 'user_loading' => '加载用户列表', + 'no_user_data' => '无可用用户', + 'perm_deny' => '权限不足,禁止访问', + 'unread_ticket' => '未读工单', + 'mark_all_read' => '全部标记已读', + 'claim_ticket' => '认领工单', + 'claim_man' => '认领人' + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'notify_config' => 'Work Order Notification Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh', + 'export_csv' => 'Export CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'work_order_mgr' => 'Work Order System', + 'work_create' => 'Create Order', + 'work_edit' => 'Edit Order', + 'work_assign' => 'Assign Order', + 'work_status' => 'Status', + 'work_creator' => 'Creator', + 'work_handler' => 'Handler', + 'work_content' => 'Content / Remark', + 'work_title' => 'Order Title', + 'create_time' => 'Create Time', + 'update_time' => 'Update Time', + 'all_work_order' => 'All Work Orders', + 'no_work_data' => 'No work orders', + 'save' => 'Save', + 'cancel' => 'Cancel', + 'title_placeholder' => 'Fill fault or demand title', + 'content_placeholder' => 'Describe fault, steps and handling plan', + 'select_handler' => 'Select handler (empty for unassigned)', + 'status_1' => 'Pending', + 'status_2' => 'Processing', + 'status_3' => 'Finished', + 'status_4' => 'Closed', + 'no_alert_option' => 'No related alert', + 'relate_alert' => 'Relate Alert (Optional)', + 'relate_alert_id' => 'Relate Alert ID', + 'notify_title' => 'Notification Config', + 'notify_user' => 'Notify Users', + 'notify_channel' => 'Notify Channel', + 'channel_mail' => 'Email', + 'channel_ding' => 'DingTalk', + 'channel_wecom' => 'WeCom', + 'smtp_host' => 'SMTP Host', + 'smtp_port' => 'Port', + 'smtp_ssl' => 'Enable SSL/TLS', + 'smtp_account' => 'SMTP Account', + 'smtp_pwd' => 'Auth Password', + 'smtp_from' => 'Sender Email', + 'save_smtp' => 'Save Notification Config', + 'alert_loading' => 'Loading active alerts...', + 'no_alert_data' => 'No active firing alerts', + 'user_loading' => 'Loading user list...', + 'no_user_data' => 'No available users', + 'perm_deny' => 'Permission denied', + 'unread_ticket' => 'Unread Tickets', + 'mark_all_read' => 'Mark All Read', + 'claim_ticket' => 'Claim Ticket', + 'claim_man' => 'Claimer' + ] +]; +$t = $langMap[$currentLang]; + +// 解析外链菜单 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = ["name" => trim($item[0]), "url" => trim($item[1])]; + } + } +} + +// 工单业务库 monitor +$dbWorkHost = "10.150.117.190"; +$dbWorkUser = "root"; +$dbWorkPwd = "hp93000"; +$dbWorkName = "monitor"; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + die("工单数据库 monitor 连接失败"); +} +mysqli_set_charset($connWork, "utf8mb4"); +// 获取用户角色权限 +$isAdmin = 0; +$permList = ""; +$roleSql = "SELECT r.is_admin, r.perm_list FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +if($stmtRole){ + mysqli_stmt_bind_param($stmtRole, 's', $loginUid); + mysqli_stmt_execute($stmtRole); + $roleRes = mysqli_stmt_get_result($stmtRole); + if ($roleRes instanceof mysqli_result) { + $roleRow = mysqli_fetch_assoc($roleRes); + if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; + } + } +} + +// 读取当前角色页面权限列表(修复分发下拉判断缺失变量) +if ($roleId > 0) { + $permSql = "SELECT page_key FROM sys_role_perm WHERE role_id = ?"; + $stmtPerm = mysqli_prepare($connWork, $permSql); + mysqli_stmt_bind_param($stmtPerm, 'i', $roleId); + mysqli_stmt_execute($stmtPerm); + $pRes = mysqli_stmt_get_result($stmtPerm); + while ($p = mysqli_fetch_assoc($pRes)) { + $allowPages[] = $p['page_key']; + } +} + +// 权限校验临时注释,如需开启取消注释 +//$hasWorkPerm = str_contains($permList, "work_order"); +//if (!$hasWorkPerm) { +// echo ""; +// exit; +//} + +// 加载全部系统用户下拉 +$userOptions = ""; +$userAll = mysqli_query($connWork, "SELECT uid, real_name, username FROM sys_user WHERE enable = 1 ORDER BY real_name ASC"); +if ($userAll instanceof mysqli_result) { + while ($u = mysqli_fetch_assoc($userAll)) { + $userOptions .= ''; + } +} + +// ========== 修复1:统计当前用户未读待处理工单(右上角角标数字) ========== +$unreadCount = 0; +$unreadSql = "SELECT COUNT(*) cnt FROM work_order WHERE assign_uid = ? AND status = 1 AND is_read = 0"; +$stmtUnread = mysqli_prepare($connWork, $unreadSql); +mysqli_stmt_bind_param($stmtUnread, 's', $loginUid); +mysqli_stmt_execute($stmtUnread); +$unreadRes = mysqli_stmt_get_result($stmtUnread); +if($unreadRes){ + $unreadRow = mysqli_fetch_assoc($unreadRes); + $unreadCount = intval($unreadRow['cnt']); +} + +// 分页参数 +$page = isset($_GET['page']) ? intval($_GET['page']) : 1; +$pageSize = intval($sysConfig['page_size'] ?? 20); +if ($pageSize < 1) $pageSize = 20; +$offset = ($page - 1) * $pageSize; +// 所有人查看全部工单,不再按uid过滤 +$whereSql = " 1=1 "; +$bindType = "ii"; +$bindData = [$offset, $pageSize]; + +// 统计工单总数 +$cntSql = "SELECT COUNT(*) total FROM work_order WHERE " . $whereSql; +$stmtCnt = mysqli_prepare($connWork, $cntSql); +$total = 0; +if($stmtCnt){ + mysqli_stmt_execute($stmtCnt); + $cntRes = mysqli_stmt_get_result($stmtCnt); + if ($cntRes instanceof mysqli_result) { + $cntRow = mysqli_fetch_assoc($cntRes); + $total = intval($cntRow['total'] ?? 0); + } +} +$totalPage = $pageSize <= 0 ? 1 : ceil($total / $pageSize); + +// 查询工单列表,带出认领人信息 +$listSql = "SELECT wo.*, +uc.real_name create_name, +ua.real_name assign_name, +uu.real_name claim_name +FROM work_order wo +LEFT JOIN sys_user uc ON wo.create_uid = uc.uid +LEFT JOIN sys_user ua ON wo.assign_uid = ua.uid +LEFT JOIN sys_user uu ON wo.claim_uid = uu.uid +WHERE " . $whereSql . " ORDER BY create_time DESC LIMIT ?, ?"; +$stmtList = mysqli_prepare($connWork, $listSql); +$orderList = []; +if($stmtList){ + mysqli_stmt_bind_param($stmtList, $bindType, ...$bindData); + mysqli_stmt_execute($stmtList); + $listResult = mysqli_stmt_get_result($stmtList); + if ($listResult instanceof mysqli_result) { + while ($row = mysqli_fetch_assoc($listResult)) { + $orderList[] = $row; + } + } +} +mysqli_close($connWork); +?> + + + + + +<?php echo $pageTitle; ?> - Advantest <?php echo $t['work_order_mgr']; ?> + + + + + + +
+
+
+
+ +
+
+
+
+
Advantest
+
+
+
+
+ + + + 0):?> + + + -- +
+ +
+ + +
+
+
+
+
+
+
+ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDOP
+
+ +
+
+
+ + + + + + + + + + + +
+
+ +
+
+
+
+ + + + + + + + + diff --git a/work_order.php.1.0.0 b/work_order.php.1.0.0 new file mode 100644 index 0000000..13db51d --- /dev/null +++ b/work_order.php.1.0.0 @@ -0,0 +1,917 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRoleId = $_SESSION['role_id']; + +// 全局配置库连接 +$dbConfigHost = "10.150.117.190"; +$dbConfigUser = "root"; +$dbConfigPwd = "hp93000"; +$dbConfigName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbConfigHost, $dbConfigUser, $dbConfigPwd, $dbConfigName); +if(!$connConfig){ + die("配置库连接失败"); +} +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} + +// 修复SMTP查询警告 +$smtpRow = []; +$sqlSmtp = "SELECT * FROM sys_smtp_config WHERE id=1"; +if (!empty(trim($sqlSmtp))) { + $smtpQuery = mysqli_query($connConfig, $sqlSmtp); + if ($smtpQuery !== false && $smtpQuery instanceof mysqli_result) { + $smtpRow = mysqli_fetch_assoc($smtpQuery) ?: []; + } +} +$smtpConfig = $smtpRow ?? []; + +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$currentLang = $sysConfig['lang'] ?? "zh"; +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +mysqli_close($connConfig); + +// 多语言词典 +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警总览', + 'disk_capacity' => '磁盘容量', + 'alert_list_page' => '历史告警', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '系统参数', + 'smtp_config' => '邮箱SMTP配置', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新页面', + 'export_csv' => '导出CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'work_order_mgr' => '工单系统', + 'work_create' => '新建工单', + 'work_edit' => '编辑工单', + 'work_assign' => '分发工单', + 'work_status' => '工单状态', + 'work_creator' => '创建人', + 'work_handler' => '处理人', + 'work_content' => '工单内容/备注', + 'work_title' => '工单标题', + 'create_time' => '创建时间', + 'update_time' => '更新时间', + 'all_work_order' => '全部工单列表', + 'no_work_data' => '暂无工单数据', + 'save' => '保存', + 'cancel' => '取消', + 'title_placeholder' => '填写故障/需求标题', + 'content_placeholder' => '详细描述故障现象、操作步骤、处理方案', + 'select_handler' => '选择处理人(留空暂不分配)', + 'status_1' => '待处理', + 'status_2' => '处理中', + 'status_3' => '已完成', + 'status_4' => '已关闭', + 'no_alert_option' => '不关联任何告警', + 'relate_alert' => '关联告警(可选)', + 'relate_alert_id' => '关联告警ID', + 'notify_title' => '通知配置', + 'notify_user' => '通知接收人', + 'notify_channel' => '通知渠道', + 'channel_mail' => '邮箱', + 'channel_ding' => '钉钉', + 'channel_wecom' => '企业微信', + 'smtp_host' => 'SMTP服务器', + 'smtp_port' => '端口', + 'smtp_ssl' => '开启SSL/TLS', + 'smtp_account' => '发件账号', + 'smtp_pwd' => '授权密码', + 'smtp_from' => '发件邮箱', + 'save_smtp' => '保存SMTP配置', + 'alert_loading' => '加载活跃告警...', + 'no_alert_data' => '当前无正在触发的告警', + 'user_loading' => '加载用户列表', + 'no_user_data' => '无可用用户', + 'perm_deny' => '权限不足,禁止访问', + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'disk_capacity' => 'Disk Capacity', + 'alert_list_page' => 'History Alert', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'smtp_config' => 'SMTP Mail Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh', + 'export_csv' => 'Export CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'work_order_mgr' => 'Work Order System', + 'work_create' => 'Create Order', + 'work_edit' => 'Edit Order', + 'work_assign' => 'Assign Order', + 'work_status' => 'Status', + 'work_creator' => 'Creator', + 'work_handler' => 'Handler', + 'work_content' => 'Content / Remark', + 'work_title' => 'Order Title', + 'create_time' => 'Create Time', + 'update_time' => 'Update Time', + 'all_work_order' => 'All Work Orders', + 'no_work_data' => 'No work orders', + 'save' => 'Save', + 'cancel' => 'Cancel', + 'title_placeholder' => 'Fill fault or demand title', + 'content_placeholder' => 'Describe fault, steps and handling plan', + 'select_handler' => 'Select handler (empty for unassigned)', + 'status_1' => 'Pending', + 'status_2' => 'Processing', + 'status_3' => 'Finished', + 'status_4' => 'Closed', + 'no_alert_option' => 'No related alert', + 'relate_alert' => 'Relate Alert (Optional)', + 'relate_alert_id' => 'Relate Alert ID', + 'notify_title' => 'Notification Config', + 'notify_user' => 'Notify Users', + 'notify_channel' => 'Notify Channel', + 'channel_mail' => 'Email', + 'channel_ding' => 'DingTalk', + 'channel_wecom' => 'WeCom', + 'smtp_host' => 'SMTP Host', + 'smtp_port' => 'Port', + 'smtp_ssl' => 'Enable SSL/TLS', + 'smtp_account' => 'SMTP Account', + 'smtp_pwd' => 'Auth Password', + 'smtp_from' => 'Sender Email', + 'save_smtp' => 'Save SMTP Config', + 'alert_loading' => 'Loading active alerts...', + 'no_alert_data' => 'No active firing alerts', + 'user_loading' => 'Loading user list...', + 'no_user_data' => 'No available users', + 'perm_deny' => 'Permission denied', + ] +]; +$t = $langMap[$currentLang]; + +// 解析外链菜单 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = ["name" => trim($item[0]), "url" => trim($item[1])]; + } + } +} + +// 工单业务库 monitor +$dbWorkHost = "10.150.117.190"; +$dbWorkUser = "root"; +$dbWorkPwd = "hp93000"; +$dbWorkName = "monitor"; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + die("工单数据库 monitor 连接失败"); +} +mysqli_set_charset($connWork, "utf8mb4"); +$loginUid = $_SESSION['user_id']; + +// 获取用户角色权限 +$isAdmin = 0; +$permList = ""; +$roleSql = "SELECT r.is_admin, r.perm_list FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +if($stmtRole){ + mysqli_stmt_bind_param($stmtRole, 's', $loginUid); + mysqli_stmt_execute($stmtRole); + $roleRes = mysqli_stmt_get_result($stmtRole); + if ($roleRes instanceof mysqli_result) { + $roleRow = mysqli_fetch_assoc($roleRes); + if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; + } + } +} + +// 权限校验临时注释,如需开启取消注释 +//$hasWorkPerm = str_contains($permList, "work_order"); +//if (!$hasWorkPerm) { +// echo ""; +// exit; +//} + +// 加载全部系统用户下拉 +$userOptions = ""; +$userAll = mysqli_query($connWork, "SELECT uid, real_name, username FROM sys_user WHERE enable = 1 ORDER BY real_name ASC"); +if ($userAll instanceof mysqli_result) { + while ($u = mysqli_fetch_assoc($userAll)) { + $userOptions .= ''; + } +} + +// 分页参数 +$page = isset($_GET['page']) ? intval($_GET['page']) : 1; +$pageSize = intval($sysConfig['page_size'] ?? 20); +if ($pageSize < 1) $pageSize = 20; +$offset = ($page - 1) * $pageSize; + +// 数据权限过滤 +if ($isAdmin === 1) { + $whereSql = " 1=1 "; +} else { + $whereSql = " (create_uid = ? OR assign_uid = ?) "; +} + +// 统计工单总数 +$cntSql = "SELECT COUNT(*) total FROM work_order WHERE " . $whereSql; +$stmtCnt = mysqli_prepare($connWork, $cntSql); +$total = 0; +if($stmtCnt){ + if ($isAdmin !== 1) { + mysqli_stmt_bind_param($stmtCnt, 'ss', $loginUid, $loginUid); + } + mysqli_stmt_execute($stmtCnt); + $cntRes = mysqli_stmt_get_result($stmtCnt); + if ($cntRes instanceof mysqli_result) { + $cntRow = mysqli_fetch_assoc($cntRes); + $total = intval($cntRow['total'] ?? 0); + } +} +$totalPage = $pageSize <= 0 ? 1 : ceil($total / $pageSize); + +// 查询工单列表 +$listSql = "SELECT wo.*, uc.real_name create_name, ua.real_name assign_name +FROM work_order wo +LEFT JOIN sys_user uc ON wo.create_uid = uc.uid +LEFT JOIN sys_user ua ON wo.assign_uid = ua.uid +WHERE " . $whereSql . " ORDER BY create_time DESC LIMIT ?, ?"; +$stmtList = mysqli_prepare($connWork, $listSql); +$orderList = []; +if($stmtList){ + if ($isAdmin === 1) { + mysqli_stmt_bind_param($stmtList, 'ii', $offset, $pageSize); + } else { + mysqli_stmt_bind_param($stmtList, 'ssii', $loginUid, $loginUid, $offset, $pageSize); + } + mysqli_stmt_execute($stmtList); + $listResult = mysqli_stmt_get_result($stmtList); + if ($listResult instanceof mysqli_result) { + while ($row = mysqli_fetch_assoc($listResult)) { + $orderList[] = $row; + } + } +} +mysqli_close($connWork); +?> + + + + + +<?php echo $pageTitle; ?> - Advantest <?php echo $t['work_order_mgr']; ?> + + + + + + +
+
+
+
+ +
+
+
+
+
Advantest
+
+
+
+
+ + -- +
+ + +
+ + +
+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDOP
+
+ +
+
+
+ + + + + +
+
+ + +
+
+
+
+ + + + + + + + + diff --git a/work_order.php.1.0.0优化 b/work_order.php.1.0.0优化 new file mode 100644 index 0000000..92d58d8 --- /dev/null +++ b/work_order.php.1.0.0优化 @@ -0,0 +1,917 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRoleId = $_SESSION['role_id']; + +// 全局配置库连接 +$dbConfigHost = "10.150.117.190"; +$dbConfigUser = "root"; +$dbConfigPwd = "hp93000"; +$dbConfigName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbConfigHost, $dbConfigUser, $dbConfigPwd, $dbConfigName); +if(!$connConfig){ + die("配置库连接失败"); +} +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} + +// 修复SMTP查询警告 +$smtpRow = []; +$sqlSmtp = "SELECT * FROM sys_smtp_config WHERE id=1"; +if (!empty(trim($sqlSmtp))) { + $smtpQuery = mysqli_query($connConfig, $sqlSmtp); + if ($smtpQuery !== false && $smtpQuery instanceof mysqli_result) { + $smtpRow = mysqli_fetch_assoc($smtpQuery) ?: []; + } +} +$smtpConfig = $smtpRow ?? []; + +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$currentLang = $sysConfig['lang'] ?? "zh"; +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +mysqli_close($connConfig); + +// 多语言词典(SMTP配置改为工单消息通知配置) +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警总览', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '系统参数', + 'notify_config' => '工单消息通知配置', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新页面', + 'export_csv' => '导出CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'work_order_mgr' => '工单系统', + 'work_create' => '新建工单', + 'work_edit' => '编辑工单', + 'work_assign' => '分发工单', + 'work_status' => '工单状态', + 'work_creator' => '创建人', + 'work_handler' => '处理人', + 'work_content' => '工单内容/备注', + 'work_title' => '工单标题', + 'create_time' => '创建时间', + 'update_time' => '更新时间', + 'all_work_order' => '全部工单列表', + 'no_work_data' => '暂无工单数据', + 'save' => '保存', + 'cancel' => '取消', + 'title_placeholder' => '填写故障/需求标题', + 'content_placeholder' => '详细描述故障现象、操作步骤、处理方案', + 'select_handler' => '选择处理人(留空暂不分配)', + 'status_1' => '待处理', + 'status_2' => '处理中', + 'status_3' => '已完成', + 'status_4' => '已关闭', + 'no_alert_option' => '不关联任何告警', + 'relate_alert' => '关联告警(可选)', + 'relate_alert_id' => '关联告警ID', + 'notify_title' => '通知配置', + 'notify_user' => '通知接收人', + 'notify_channel' => '通知渠道', + 'channel_mail' => '邮箱', + 'channel_ding' => '钉钉', + 'channel_wecom' => '企业微信', + 'smtp_host' => 'SMTP服务器', + 'smtp_port' => '端口', + 'smtp_ssl' => '开启SSL/TLS', + 'smtp_account' => '发件账号', + 'smtp_pwd' => '授权密码', + 'smtp_from' => '发件邮箱', + 'save_smtp' => '保存通知配置', + 'alert_loading' => '加载活跃告警...', + 'no_alert_data' => '当前无正在触发的告警', + 'user_loading' => '加载用户列表', + 'no_user_data' => '无可用用户', + 'perm_deny' => '权限不足,禁止访问', + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'notify_config' => 'Work Order Notification Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh', + 'export_csv' => 'Export CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'work_order_mgr' => 'Work Order System', + 'work_create' => 'Create Order', + 'work_edit' => 'Edit Order', + 'work_assign' => 'Assign Order', + 'work_status' => 'Status', + 'work_creator' => 'Creator', + 'work_handler' => 'Handler', + 'work_content' => 'Content / Remark', + 'work_title' => 'Order Title', + 'create_time' => 'Create Time', + 'update_time' => 'Update Time', + 'all_work_order' => 'All Work Orders', + 'no_work_data' => 'No work orders', + 'save' => 'Save', + 'cancel' => 'Cancel', + 'title_placeholder' => 'Fill fault or demand title', + 'content_placeholder' => 'Describe fault, steps and handling plan', + 'select_handler' => 'Select handler (empty for unassigned)', + 'status_1' => 'Pending', + 'status_2' => 'Processing', + 'status_3' => 'Finished', + 'status_4' => 'Closed', + 'no_alert_option' => 'No related alert', + 'relate_alert' => 'Relate Alert (Optional)', + 'relate_alert_id' => 'Relate Alert ID', + 'notify_title' => 'Notification Config', + 'notify_user' => 'Notify Users', + 'notify_channel' => 'Notify Channel', + 'channel_mail' => 'Email', + 'channel_ding' => 'DingTalk', + 'channel_wecom' => 'WeCom', + 'smtp_host' => 'SMTP Host', + 'smtp_port' => 'Port', + 'smtp_ssl' => 'Enable SSL/TLS', + 'smtp_account' => 'SMTP Account', + 'smtp_pwd' => 'Auth Password', + 'smtp_from' => 'Sender Email', + 'save_smtp' => 'Save Notification Config', + 'alert_loading' => 'Loading active alerts...', + 'no_alert_data' => 'No active firing alerts', + 'user_loading' => 'Loading user list...', + 'no_user_data' => 'No available users', + 'perm_deny' => 'Permission denied', + ] +]; +$t = $langMap[$currentLang]; + +// 解析外链菜单 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = ["name" => trim($item[0]), "url" => trim($item[1])]; + } + } +} + +// 工单业务库 monitor +$dbWorkHost = "10.150.117.190"; +$dbWorkUser = "root"; +$dbWorkPwd = "hp93000"; +$dbWorkName = "monitor"; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + die("工单数据库 monitor 连接失败"); +} +mysqli_set_charset($connWork, "utf8mb4"); +$loginUid = $_SESSION['user_id']; + +// 获取用户角色权限 +$isAdmin = 0; +$permList = ""; +$roleSql = "SELECT r.is_admin, r.perm_list FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +if($stmtRole){ + mysqli_stmt_bind_param($stmtRole, 's', $loginUid); + mysqli_stmt_execute($stmtRole); + $roleRes = mysqli_stmt_get_result($stmtRole); + if ($roleRes instanceof mysqli_result) { + $roleRow = mysqli_fetch_assoc($roleRes); + if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; + } + } +} + +// 权限校验临时注释,如需开启取消注释 +//$hasWorkPerm = str_contains($permList, "work_order"); +//if (!$hasWorkPerm) { +// echo ""; +// exit; +//} + +// 加载全部系统用户下拉 +$userOptions = ""; +$userAll = mysqli_query($connWork, "SELECT uid, real_name, username FROM sys_user WHERE enable = 1 ORDER BY real_name ASC"); +if ($userAll instanceof mysqli_result) { + while ($u = mysqli_fetch_assoc($userAll)) { + $userOptions .= ''; + } +} + +// 分页参数 +$page = isset($_GET['page']) ? intval($_GET['page']) : 1; +$pageSize = intval($sysConfig['page_size'] ?? 20); +if ($pageSize < 1) $pageSize = 20; +$offset = ($page - 1) * $pageSize; + +// 数据权限过滤 +if ($isAdmin === 1) { + $whereSql = " 1=1 "; +} else { + $whereSql = " (create_uid = ? OR assign_uid = ?) "; +} + +// 统计工单总数 +$cntSql = "SELECT COUNT(*) total FROM work_order WHERE " . $whereSql; +$stmtCnt = mysqli_prepare($connWork, $cntSql); +$total = 0; +if($stmtCnt){ + if ($isAdmin !== 1) { + mysqli_stmt_bind_param($stmtCnt, 'ss', $loginUid, $loginUid); + } + mysqli_stmt_execute($stmtCnt); + $cntRes = mysqli_stmt_get_result($stmtCnt); + if ($cntRes instanceof mysqli_result) { + $cntRow = mysqli_fetch_assoc($cntRes); + $total = intval($cntRow['total'] ?? 0); + } +} +$totalPage = $pageSize <= 0 ? 1 : ceil($total / $pageSize); + +// 查询工单列表 +$listSql = "SELECT wo.*, uc.real_name create_name, ua.real_name assign_name +FROM work_order wo +LEFT JOIN sys_user uc ON wo.create_uid = uc.uid +LEFT JOIN sys_user ua ON wo.assign_uid = ua.uid +WHERE " . $whereSql . " ORDER BY create_time DESC LIMIT ?, ?"; +$stmtList = mysqli_prepare($connWork, $listSql); +$orderList = []; +if($stmtList){ + if ($isAdmin === 1) { + mysqli_stmt_bind_param($stmtList, 'ii', $offset, $pageSize); + } else { + mysqli_stmt_bind_param($stmtList, 'ssii', $loginUid, $loginUid, $offset, $pageSize); + } + mysqli_stmt_execute($stmtList); + $listResult = mysqli_stmt_get_result($stmtList); + if ($listResult instanceof mysqli_result) { + while ($row = mysqli_fetch_assoc($listResult)) { + $orderList[] = $row; + } + } +} +mysqli_close($connWork); +?> + + + + + +<?php echo $pageTitle; ?> - Advantest <?php echo $t['work_order_mgr']; ?> + + + + + + +
+
+
+
+ +
+
+
+
+
Advantest
+
+
+
+
+ + -- +
+ + +
+ + +
+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDOP
+
+ +
+
+
+ + + + + +
+
+ + +
+
+
+
+ + + + + + + + + diff --git a/work_order.php.1.0.1 b/work_order.php.1.0.1 new file mode 100644 index 0000000..08edaed --- /dev/null +++ b/work_order.php.1.0.1 @@ -0,0 +1,916 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRoleId = $_SESSION['role_id']; + +// 全局配置库连接 +$dbConfigHost = "10.150.117.190"; +$dbConfigUser = "root"; +$dbConfigPwd = "hp93000"; +$dbConfigName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbConfigHost, $dbConfigUser, $dbConfigPwd, $dbConfigName); +if(!$connConfig){ + die("配置库连接失败"); +} +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} + +// 修复SMTP查询警告 +$smtpRow = []; +$sqlSmtp = "SELECT * FROM sys_smtp_config WHERE id=1"; +if (!empty(trim($sqlSmtp))) { + $smtpQuery = mysqli_query($connConfig, $sqlSmtp); + if ($smtpQuery !== false && $smtpQuery instanceof mysqli_result) { + $smtpRow = mysqli_fetch_assoc($smtpQuery) ?: []; + } +} +$smtpConfig = $smtpRow ?? []; + +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$currentLang = $sysConfig['lang'] ?? "zh"; +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +mysqli_close($connConfig); + +// 多语言词典(SMTP配置改为工单消息通知配置) +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警总览', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '系统参数', + 'notify_config' => '工单消息通知配置', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新页面', + 'export_csv' => '导出CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'work_order_mgr' => '工单系统', + 'work_create' => '新建工单', + 'work_edit' => '编辑工单', + 'work_assign' => '分发工单', + 'work_status' => '工单状态', + 'work_creator' => '创建人', + 'work_handler' => '处理人', + 'work_content' => '工单内容/备注', + 'work_title' => '工单标题', + 'create_time' => '创建时间', + 'update_time' => '更新时间', + 'all_work_order' => '全部工单列表', + 'no_work_data' => '暂无工单数据', + 'save' => '保存', + 'cancel' => '取消', + 'title_placeholder' => '填写故障/需求标题', + 'content_placeholder' => '详细描述故障现象、操作步骤、处理方案', + 'select_handler' => '选择处理人(留空暂不分配)', + 'status_1' => '待处理', + 'status_2' => '处理中', + 'status_3' => '已完成', + 'status_4' => '已关闭', + 'no_alert_option' => '不关联任何告警', + 'relate_alert' => '关联告警(可选)', + 'relate_alert_id' => '关联告警ID', + 'notify_title' => '通知配置', + 'notify_user' => '通知接收人', + 'notify_channel' => '通知渠道', + 'channel_mail' => '邮箱', + 'channel_ding' => '钉钉', + 'channel_wecom' => '企业微信', + 'smtp_host' => 'SMTP服务器', + 'smtp_port' => '端口', + 'smtp_ssl' => '开启SSL/TLS', + 'smtp_account' => '发件账号', + 'smtp_pwd' => '授权密码', + 'smtp_from' => '发件邮箱', + 'save_smtp' => '保存通知配置', + 'alert_loading' => '加载活跃告警...', + 'no_alert_data' => '当前无正在触发的告警', + 'user_loading' => '加载用户列表', + 'no_user_data' => '无可用用户', + 'perm_deny' => '权限不足,禁止访问', + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'notify_config' => 'Work Order Notification Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh', + 'export_csv' => 'Export CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'work_order_mgr' => 'Work Order System', + 'work_create' => 'Create Order', + 'work_edit' => 'Edit Order', + 'work_assign' => 'Assign Order', + 'work_status' => 'Status', + 'work_creator' => 'Creator', + 'work_handler' => 'Handler', + 'work_content' => 'Content / Remark', + 'work_title' => 'Order Title', + 'create_time' => 'Create Time', + 'update_time' => 'Update Time', + 'all_work_order' => 'All Work Orders', + 'no_work_data' => 'No work orders', + 'save' => 'Save', + 'cancel' => 'Cancel', + 'title_placeholder' => 'Fill fault or demand title', + 'content_placeholder' => 'Describe fault, steps and handling plan', + 'select_handler' => 'Select handler (empty for unassigned)', + 'status_1' => 'Pending', + 'status_2' => 'Processing', + 'status_3' => 'Finished', + 'status_4' => 'Closed', + 'no_alert_option' => 'No related alert', + 'relate_alert' => 'Relate Alert (Optional)', + 'relate_alert_id' => 'Relate Alert ID', + 'notify_title' => 'Notification Config', + 'notify_user' => 'Notify Users', + 'notify_channel' => 'Notify Channel', + 'channel_mail' => 'Email', + 'channel_ding' => 'DingTalk', + 'channel_wecom' => 'WeCom', + 'smtp_host' => 'SMTP Host', + 'smtp_port' => 'Port', + 'smtp_ssl' => 'Enable SSL/TLS', + 'smtp_account' => 'SMTP Account', + 'smtp_pwd' => 'Auth Password', + 'smtp_from' => 'Sender Email', + 'save_smtp' => 'Save Notification Config', + 'alert_loading' => 'Loading active alerts...', + 'no_alert_data' => 'No active firing alerts', + 'user_loading' => 'Loading user list...', + 'no_user_data' => 'No available users', + 'perm_deny' => 'Permission denied', + ] +]; +$t = $langMap[$currentLang]; + +// 解析外链菜单 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = ["name" => trim($item[0]), "url" => trim($item[1])]; + } + } +} + +// 工单业务库 monitor +$dbWorkHost = "10.150.117.190"; +$dbWorkUser = "root"; +$dbWorkPwd = "hp93000"; +$dbWorkName = "monitor"; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + die("工单数据库 monitor 连接失败"); +} +mysqli_set_charset($connWork, "utf8mb4"); +$loginUid = $_SESSION['user_id']; + +// 获取用户角色权限 +$isAdmin = 0; +$permList = ""; +$roleSql = "SELECT r.is_admin, r.perm_list FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +if($stmtRole){ + mysqli_stmt_bind_param($stmtRole, 's', $loginUid); + mysqli_stmt_execute($stmtRole); + $roleRes = mysqli_stmt_get_result($stmtRole); + if ($roleRes instanceof mysqli_result) { + $roleRow = mysqli_fetch_assoc($roleRes); + if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; + } + } +} + +// 权限校验临时注释,如需开启取消注释 +//$hasWorkPerm = str_contains($permList, "work_order"); +//if (!$hasWorkPerm) { +// echo ""; +// exit; +//} + +// 加载全部系统用户下拉 +$userOptions = ""; +$userAll = mysqli_query($connWork, "SELECT uid, real_name, username FROM sys_user WHERE enable = 1 ORDER BY real_name ASC"); +if ($userAll instanceof mysqli_result) { + while ($u = mysqli_fetch_assoc($userAll)) { + $userOptions .= ''; + } +} + +// 分页参数 +$page = isset($_GET['page']) ? intval($_GET['page']) : 1; +$pageSize = intval($sysConfig['page_size'] ?? 20); +if ($pageSize < 1) $pageSize = 20; +$offset = ($page - 1) * $pageSize; + +// 数据权限过滤 +if ($isAdmin === 1) { + $whereSql = " 1=1 "; +} else { + $whereSql = " (create_uid = ? OR assign_uid = ?) "; +} + +// 统计工单总数 +$cntSql = "SELECT COUNT(*) total FROM work_order WHERE " . $whereSql; +$stmtCnt = mysqli_prepare($connWork, $cntSql); +$total = 0; +if($stmtCnt){ + if ($isAdmin !== 1) { + mysqli_stmt_bind_param($stmtCnt, 'ss', $loginUid, $loginUid); + } + mysqli_stmt_execute($stmtCnt); + $cntRes = mysqli_stmt_get_result($stmtCnt); + if ($cntRes instanceof mysqli_result) { + $cntRow = mysqli_fetch_assoc($cntRes); + $total = intval($cntRow['total'] ?? 0); + } +} +$totalPage = $pageSize <= 0 ? 1 : ceil($total / $pageSize); + +// 查询工单列表 +$listSql = "SELECT wo.*, uc.real_name create_name, ua.real_name assign_name +FROM work_order wo +LEFT JOIN sys_user uc ON wo.create_uid = uc.uid +LEFT JOIN sys_user ua ON wo.assign_uid = ua.uid +WHERE " . $whereSql . " ORDER BY create_time DESC LIMIT ?, ?"; +$stmtList = mysqli_prepare($connWork, $listSql); +$orderList = []; +if($stmtList){ + if ($isAdmin === 1) { + mysqli_stmt_bind_param($stmtList, 'ii', $offset, $pageSize); + } else { + mysqli_stmt_bind_param($stmtList, 'ssii', $loginUid, $loginUid, $offset, $pageSize); + } + mysqli_stmt_execute($stmtList); + $listResult = mysqli_stmt_get_result($stmtList); + if ($listResult instanceof mysqli_result) { + while ($row = mysqli_fetch_assoc($listResult)) { + $orderList[] = $row; + } + } +} +mysqli_close($connWork); +?> + + + + + +<?php echo $pageTitle; ?> - Advantest <?php echo $t['work_order_mgr']; ?> + + + + + + +
+
+
+
+ +
+
+
+
+
Advantest
+
+
+
+
+ + -- +
+ + +
+ + +
+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDOP
+
+ +
+
+
+ + + + + +
+
+ + +
+
+
+
+ + + + + + + + + diff --git a/work_order.php.1.0.1开发中 b/work_order.php.1.0.1开发中 new file mode 100644 index 0000000..6022074 --- /dev/null +++ b/work_order.php.1.0.1开发中 @@ -0,0 +1,866 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRoleId = $_SESSION['role_id']; + +// 全局配置库连接 +$dbConfigHost = "10.150.117.190"; +$dbConfigUser = "root"; +$dbConfigPwd = "hp93000"; +$dbConfigName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbConfigHost, $dbConfigUser, $dbConfigPwd, $dbConfigName); +if(!$connConfig){ + die("配置库连接失败"); +} +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} + +// 修复SMTP查询警告 +$smtpRow = []; +$sqlSmtp = "SELECT * FROM sys_smtp_config WHERE id=1"; +if (!empty(trim($sqlSmtp))) { + $smtpQuery = mysqli_query($connConfig, $sqlSmtp); + if ($smtpQuery !== false && $smtpQuery instanceof mysqli_result) { + $smtpRow = mysqli_fetch_assoc($smtpQuery) ?: []; + } +} +$smtpConfig = $smtpRow ?? []; + +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$currentLang = $sysConfig['lang'] ?? "zh"; +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +mysqli_close($connConfig); + +// 多语言词典 +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警总览', + 'disk_capacity' => '磁盘容量', + 'alert_list_page' => '历史告警', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '系统参数', + 'smtp_config' => '邮箱SMTP配置', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新页面', + 'export_csv' => '导出CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'work_order_mgr' => '工单系统', + 'work_create' => '新建工单', + 'work_edit' => '编辑工单', + 'work_assign' => '分发工单', + 'work_status' => '工单状态', + 'work_creator' => '创建人', + 'work_handler' => '处理人', + 'work_content' => '工单内容/备注', + 'work_title' => '工单标题', + 'create_time' => '创建时间', + 'update_time' => '更新时间', + 'all_work_order' => '全部工单列表', + 'no_work_data' => '暂无工单数据', + 'save' => '保存', + 'cancel' => '取消', + 'title_placeholder' => '填写故障/需求标题', + 'content_placeholder' => '详细描述故障现象、操作步骤、处理方案', + 'select_handler' => '选择处理人(留空暂不分配)', + 'status_1' => '待处理', + 'status_2' => '处理中', + 'status_3' => '已完成', + 'status_4' => '已关闭', + 'no_alert_option' => '不关联任何告警', + 'relate_alert' => '关联告警(可选)', + 'relate_alert_id' => '关联告警ID', + 'notify_title' => '通知配置', + 'notify_user' => '通知接收人', + 'notify_channel' => '通知渠道', + 'channel_mail' => '邮箱', + 'channel_ding' => '钉钉', + 'channel_wecom' => '企业微信', + 'smtp_host' => 'SMTP服务器', + 'smtp_port' => '端口', + 'smtp_ssl' => '开启SSL/TLS', + 'smtp_account' => '发件账号', + 'smtp_pwd' => '授权密码', + 'smtp_from' => '发件邮箱', + 'save_smtp' => '保存SMTP配置', + 'alert_loading' => '加载活跃告警...', + 'no_alert_data' => '当前无正在触发的告警', + 'user_loading' => '加载用户列表', + 'no_user_data' => '无可用用户', + 'perm_deny' => '权限不足,禁止访问', + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'disk_capacity' => 'Disk Capacity', + 'alert_list_page' => 'History Alert', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'smtp_config' => 'SMTP Mail Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh', + 'export_csv' => 'Export CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'work_order_mgr' => 'Work Order System', + 'work_create' => 'Create Order', + 'work_edit' => 'Edit Order', + 'work_assign' => 'Assign Order', + 'work_status' => 'Status', + 'work_creator' => 'Creator', + 'work_handler' => 'Handler', + 'work_content' => 'Content / Remark', + 'work_title' => 'Order Title', + 'create_time' => 'Create Time', + 'update_time' => 'Update Time', + 'all_work_order' => 'All Work Orders', + 'no_work_data' => 'No work orders', + 'save' => 'Save', + 'cancel' => 'Cancel', + 'title_placeholder' => 'Fill fault or demand title', + 'content_placeholder' => 'Describe fault, steps and handling plan', + 'select_handler' => 'Select handler (empty for unassigned)', + 'status_1' => 'Pending', + 'status_2' => 'Processing', + 'status_3' => 'Finished', + 'status_4' => 'Closed', + 'no_alert_option' => 'No related alert', + 'relate_alert' => 'Relate Alert (Optional)', + 'relate_alert_id' => 'Relate Alert ID', + 'notify_title' => 'Notification Config', + 'notify_user' => 'Notify Users', + 'notify_channel' => 'Notify Channel', + 'channel_mail' => 'Email', + 'channel_ding' => 'DingTalk', + 'channel_wecom' => 'WeCom', + 'smtp_host' => 'SMTP Host', + 'smtp_port' => 'Port', + 'smtp_ssl' => 'Enable SSL/TLS', + 'smtp_account' => 'SMTP Account', + 'smtp_pwd' => 'Auth Password', + 'smtp_from' => 'Sender Email', + 'save_smtp' => 'Save SMTP Config', + 'alert_loading' => 'Loading active alerts...', + 'no_alert_data' => 'No active firing alerts', + 'user_loading' => 'Loading user list...', + 'no_user_data' => 'No available users', + 'perm_deny' => 'Permission denied', + ] +]; +$t = $langMap[$currentLang]; + +// 解析外链菜单 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = ["name" => trim($item[0]), "url" => trim($item[1])]; + } + } +} + +// 工单业务库 monitor +$dbWorkHost = "10.150.117.190"; +$dbWorkUser = "root"; +$dbWorkPwd = "hp93000"; +$dbWorkName = "monitor"; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + die("工单数据库 monitor 连接失败"); +} +mysqli_set_charset($connWork, "utf8mb4"); +$loginUid = $_SESSION['user_id']; + +// 获取用户角色权限 +$isAdmin = 0; +$permList = ""; +$roleSql = "SELECT r.is_admin, r.perm_list FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +if($stmtRole){ + mysqli_stmt_bind_param($stmtRole, 's', $loginUid); + mysqli_stmt_execute($stmtRole); + $roleRes = mysqli_stmt_get_result($stmtRole); + if ($roleRes instanceof mysqli_result) { + $roleRow = mysqli_fetch_assoc($roleRes); + if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; + } + } +} + +// 权限校验临时注释,如需开启取消注释 +//$hasWorkPerm = str_contains($permList, "work_order"); +//if (!$hasWorkPerm) { +// echo ""; +// exit; +//} + +// 加载全部系统用户下拉 +$userOptions = ""; +$userAll = mysqli_query($connWork, "SELECT uid, real_name, username FROM sys_user WHERE enable = 1 ORDER BY real_name ASC"); +if ($userAll instanceof mysqli_result) { + while ($u = mysqli_fetch_assoc($userAll)) { + $userOptions .= ''; + } +} + +// 分页参数 +$page = isset($_GET['page']) ? intval($_GET['page']) : 1; +$pageSize = intval($sysConfig['page_size'] ?? 20); +if ($pageSize < 1) $pageSize = 20; +$offset = ($page - 1) * $pageSize; + +// 数据权限过滤 +if ($isAdmin === 1) { + $whereSql = " 1=1 "; +} else { + $whereSql = " (create_uid = ? OR assign_uid = ?) "; +} + +// 统计工单总数 +$cntSql = "SELECT COUNT(*) total FROM work_order WHERE " . $whereSql; +$stmtCnt = mysqli_prepare($connWork, $cntSql); +$total = 0; +if($stmtCnt){ + if ($isAdmin !== 1) { + mysqli_stmt_bind_param($stmtCnt, 'ss', $loginUid, $loginUid); + } + mysqli_stmt_execute($stmtCnt); + $cntRes = mysqli_stmt_get_result($stmtCnt); + if ($cntRes instanceof mysqli_result) { + $cntRow = mysqli_fetch_assoc($cntRes); + $total = intval($cntRow['total'] ?? 0); + } +} +$totalPage = $pageSize <= 0 ? 1 : ceil($total / $pageSize); + +// 查询工单列表 +$listSql = "SELECT wo.*, uc.real_name create_name, ua.real_name assign_name +FROM work_order wo +LEFT JOIN sys_user uc ON wo.create_uid = uc.uid +LEFT JOIN sys_user ua ON wo.assign_uid = ua.uid +WHERE " . $whereSql . " ORDER BY create_time DESC LIMIT ?, ?"; +$stmtList = mysqli_prepare($connWork, $listSql); +$orderList = []; +if($stmtList){ + if ($isAdmin === 1) { + mysqli_stmt_bind_param($stmtList, 'ii', $offset, $pageSize); + } else { + mysqli_stmt_bind_param($stmtList, 'ssii', $loginUid, $loginUid, $offset, $pageSize); + } + mysqli_stmt_execute($stmtList); + $listResult = mysqli_stmt_get_result($stmtList); + if ($listResult instanceof mysqli_result) { + while ($row = mysqli_fetch_assoc($listResult)) { + $orderList[] = $row; + } + } +} +mysqli_close($connWork); +?> + + + + + +<?php echo $pageTitle; ?> - Advantest <?php echo $t['work_order_mgr']; ?> + + + + + + +
+
+
+
+ +
+
+
+
+
Advantest
+
+
+
+
+ + -- +
+ + +
+ + +
+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDOP
+
+ +
+
+
+ + + + + +
+
+ + +
+
+
+
+ + + + + + + + + diff --git a/work_order.php.1.0.2 b/work_order.php.1.0.2 new file mode 100644 index 0000000..c32d909 --- /dev/null +++ b/work_order.php.1.0.2 @@ -0,0 +1,952 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRoleId = $_SESSION['role_id']; +$loginUid = $_SESSION['user_id']; + +// 全局配置库连接 +$dbConfigHost = "10.150.117.190"; +$dbConfigUser = "root"; +$dbConfigPwd = "hp93000"; +$dbConfigName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbConfigHost, $dbConfigUser, $dbConfigPwd, $dbConfigName); +if(!$connConfig){ + die("配置库连接失败"); +} +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} + +// 修复SMTP查询警告 +$smtpRow = []; +$sqlSmtp = "SELECT * FROM sys_smtp_config WHERE id=1"; +if (!empty(trim($sqlSmtp))) { + $smtpQuery = mysqli_query($connConfig, $sqlSmtp); + if ($smtpQuery !== false && $smtpQuery instanceof mysqli_result) { + $smtpRow = mysqli_fetch_assoc($smtpQuery) ?: []; + } +} +$smtpConfig = $smtpRow ?? []; + +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$currentLang = $sysConfig['lang'] ?? "zh"; +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +mysqli_close($connConfig); + +// 多语言词典(新增未读、待处理文案) +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警总览', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '系统参数', + 'notify_config' => '工单消息通知配置', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新页面', + 'export_csv' => '导出CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'work_order_mgr' => '工单系统', + 'work_create' => '新建工单', + 'work_edit' => '编辑工单', + 'work_assign' => '分发工单', + 'work_status' => '工单状态', + 'work_creator' => '创建人', + 'work_handler' => '处理人', + 'work_content' => '工单内容/备注', + 'work_title' => '工单标题', + 'create_time' => '创建时间', + 'update_time' => '更新时间', + 'all_work_order' => '全部工单列表', + 'no_work_data' => '暂无工单数据', + 'save' => '保存', + 'cancel' => '取消', + 'title_placeholder' => '填写故障/需求标题', + 'content_placeholder' => '详细描述故障现象、操作步骤、处理方案', + 'select_handler' => '选择处理人(留空暂不分配)', + 'status_1' => '待处理', + 'status_2' => '处理中', + 'status_3' => '已完成', + 'status_4' => '已关闭', + 'no_alert_option' => '不关联任何告警', + 'relate_alert' => '关联告警(可选)', + 'relate_alert_id' => '关联告警ID', + 'notify_title' => '通知配置', + 'notify_user' => '通知接收人', + 'notify_channel' => '通知渠道', + 'channel_mail' => '邮箱', + 'channel_ding' => '钉钉', + 'channel_wecom' => '企业微信', + 'smtp_host' => 'SMTP服务器', + 'smtp_port' => '端口', + 'smtp_ssl' => '开启SSL/TLS', + 'smtp_account' => '发件账号', + 'smtp_pwd' => '授权密码', + 'smtp_from' => '发件邮箱', + 'save_smtp' => '保存通知配置', + 'alert_loading' => '加载活跃告警...', + 'no_alert_data' => '当前无正在触发的告警', + 'user_loading' => '加载用户列表', + 'no_user_data' => '无可用用户', + 'perm_deny' => '权限不足,禁止访问', + 'unread_ticket' => '未读工单', + 'mark_all_read' => '全部标记已读' + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'notify_config' => 'Work Order Notification Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh', + 'export_csv' => 'Export CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'work_order_mgr' => 'Work Order System', + 'work_create' => 'Create Order', + 'work_edit' => 'Edit Order', + 'work_assign' => 'Assign Order', + 'work_status' => 'Status', + 'work_creator' => 'Creator', + 'work_handler' => 'Handler', + 'work_content' => 'Content / Remark', + 'work_title' => 'Order Title', + 'create_time' => 'Create Time', + 'update_time' => 'Update Time', + 'all_work_order' => 'All Work Orders', + 'no_work_data' => 'No work orders', + 'save' => 'Save', + 'cancel' => 'Cancel', + 'title_placeholder' => 'Fill fault or demand title', + 'content_placeholder' => 'Describe fault, steps and handling plan', + 'select_handler' => 'Select handler (empty for unassigned)', + 'status_1' => 'Pending', + 'status_2' => 'Processing', + 'status_3' => 'Finished', + 'status_4' => 'Closed', + 'no_alert_option' => 'No related alert', + 'relate_alert' => 'Relate Alert (Optional)', + 'relate_alert_id' => 'Relate Alert ID', + 'notify_title' => 'Notification Config', + 'notify_user' => 'Notify Users', + 'notify_channel' => 'Notify Channel', + 'channel_mail' => 'Email', + 'channel_ding' => 'DingTalk', + 'channel_wecom' => 'WeCom', + 'smtp_host' => 'SMTP Host', + 'smtp_port' => 'Port', + 'smtp_ssl' => 'Enable SSL/TLS', + 'smtp_account' => 'SMTP Account', + 'smtp_pwd' => 'Auth Password', + 'smtp_from' => 'Sender Email', + 'save_smtp' => 'Save Notification Config', + 'alert_loading' => 'Loading active alerts...', + 'no_alert_data' => 'No active firing alerts', + 'user_loading' => 'Loading user list...', + 'no_user_data' => 'No available users', + 'perm_deny' => 'Permission denied', + 'unread_ticket' => 'Unread Tickets', + 'mark_all_read' => 'Mark All Read' + ] +]; +$t = $langMap[$currentLang]; + +// 解析外链菜单 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = ["name" => trim($item[0]), "url" => trim($item[1])]; + } + } +} + +// 工单业务库 monitor +$dbWorkHost = "10.150.117.190"; +$dbWorkUser = "root"; +$dbWorkPwd = "hp93000"; +$dbWorkName = "monitor"; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + die("工单数据库 monitor 连接失败"); +} +mysqli_set_charset($connWork, "utf8mb4"); + +// 获取用户角色权限 +$isAdmin = 0; +$permList = ""; +$roleSql = "SELECT r.is_admin, r.perm_list FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +if($stmtRole){ + mysqli_stmt_bind_param($stmtRole, 's', $loginUid); + mysqli_stmt_execute($stmtRole); + $roleRes = mysqli_stmt_get_result($stmtRole); + if ($roleRes instanceof mysqli_result) { + $roleRow = mysqli_fetch_assoc($roleRes); + if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; + } + } +} + +// 权限校验临时注释,如需开启取消注释 +//$hasWorkPerm = str_contains($permList, "work_order"); +//if (!$hasWorkPerm) { +// echo ""; +// exit; +//} + +// 加载全部系统用户下拉 +$userOptions = ""; +$userAll = mysqli_query($connWork, "SELECT uid, real_name, username FROM sys_user WHERE enable = 1 ORDER BY real_name ASC"); +if ($userAll instanceof mysqli_result) { + while ($u = mysqli_fetch_assoc($userAll)) { + $userOptions .= ''; + } +} + +// ========== 修复1:统计当前用户未读待处理工单(右上角角标数字) ========== +$unreadCount = 0; +$unreadSql = "SELECT COUNT(*) cnt FROM work_order WHERE assign_uid = ? AND status = 1 AND is_read = 0"; +$stmtUnread = mysqli_prepare($connWork, $unreadSql); +mysqli_stmt_bind_param($stmtUnread, 's', $loginUid); +mysqli_stmt_execute($stmtUnread); +$unreadRes = mysqli_stmt_get_result($stmtUnread); +if($unreadRes){ + $unreadRow = mysqli_fetch_assoc($unreadRes); + $unreadCount = intval($unreadRow['cnt']); +} + +// 分页参数 +$page = isset($_GET['page']) ? intval($_GET['page']) : 1; +$pageSize = intval($sysConfig['page_size'] ?? 20); +if ($pageSize < 1) $pageSize = 20; +$offset = ($page - 1) * $pageSize; + +// ========== 修复1:数据权限过滤 普通用户仅展示创建/分配给自己工单,参数绑定修复 ========== +if ($isAdmin === 1) { + $whereSql = " 1=1 "; +} else { + $whereSql = " (create_uid = ? OR assign_uid = ?) "; +} + +// 统计工单总数 +$cntSql = "SELECT COUNT(*) total FROM work_order WHERE " . $whereSql; +$stmtCnt = mysqli_prepare($connWork, $cntSql); +$total = 0; +if($stmtCnt){ + if ($isAdmin !== 1) { + mysqli_stmt_bind_param($stmtCnt, 'ss', $loginUid, $loginUid); + } + mysqli_stmt_execute($stmtCnt); + $cntRes = mysqli_stmt_get_result($stmtCnt); + if ($cntRes instanceof mysqli_result) { + $cntRow = mysqli_fetch_assoc($cntRes); + $total = intval($cntRow['total'] ?? 0); + } +} +$totalPage = $pageSize <= 0 ? 1 : ceil($total / $pageSize); + +// 查询工单列表(带出is_read未读标记) +$listSql = "SELECT wo.*, uc.real_name create_name, ua.real_name assign_name +FROM work_order wo +LEFT JOIN sys_user uc ON wo.create_uid = uc.uid +LEFT JOIN sys_user ua ON wo.assign_uid = ua.uid +WHERE " . $whereSql . " ORDER BY create_time DESC LIMIT ?, ?"; +$stmtList = mysqli_prepare($connWork, $listSql); +$orderList = []; +if($stmtList){ + if ($isAdmin === 1) { + mysqli_stmt_bind_param($stmtList, 'ii', $offset, $pageSize); + } else { + // 修复参数绑定:2个字符串uid + 2个数字分页参数 + mysqli_stmt_bind_param($stmtList, 'ssii', $loginUid, $loginUid, $offset, $pageSize); + } + mysqli_stmt_execute($stmtList); + $listResult = mysqli_stmt_get_result($stmtList); + if ($listResult instanceof mysqli_result) { + while ($row = mysqli_fetch_assoc($listResult)) { + $orderList[] = $row; + } + } +} +mysqli_close($connWork); +?> + + + + + +<?php echo $pageTitle; ?> - Advantest <?php echo $t['work_order_mgr']; ?> + + + + + + +
+
+
+
+ +
+
+
+
+
Advantest
+
+
+
+
+ + + + 0):?> + + + -- +
+ +
+ + +
+
+
+
+
+
+
+ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDOP
+
+ +
+
+
+ + + + + +
+
+ +
+
+
+
+ + + + + + + + + diff --git a/work_order.php.1.0.3 b/work_order.php.1.0.3 new file mode 100644 index 0000000..572f55f --- /dev/null +++ b/work_order.php.1.0.3 @@ -0,0 +1,955 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRoleId = $_SESSION['role_id']; +$loginUid = $_SESSION['user_id']; + +// 全局配置库连接 +$dbConfigHost = "10.150.117.190"; +$dbConfigUser = "root"; +$dbConfigPwd = "hp93000"; +$dbConfigName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbConfigHost, $dbConfigUser, $dbConfigPwd, $dbConfigName); +if(!$connConfig){ + die("配置库连接失败"); +} +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} + +// 修复SMTP查询警告 +$smtpRow = []; +$sqlSmtp = "SELECT * FROM sys_smtp_config WHERE id=1"; +if (!empty(trim($sqlSmtp))) { + $smtpQuery = mysqli_query($connConfig, $sqlSmtp); + if ($smtpQuery !== false && $smtpQuery instanceof mysqli_result) { + $smtpRow = mysqli_fetch_assoc($smtpQuery) ?: []; + } +} +$smtpConfig = $smtpRow ?? []; + +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$currentLang = $sysConfig['lang'] ?? "zh"; +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +mysqli_close($connConfig); + +// 多语言词典(新增未读、待处理文案) +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警总览', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '系统参数', + 'notify_config' => '工单消息通知配置', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新页面', + 'export_csv' => '导出CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'work_order_mgr' => '工单系统', + 'work_create' => '新建工单', + 'work_edit' => '编辑工单', + 'work_assign' => '分发工单', + 'work_status' => '工单状态', + 'work_creator' => '创建人', + 'work_handler' => '处理人', + 'work_content' => '工单内容/备注', + 'work_title' => '工单标题', + 'create_time' => '创建时间', + 'update_time' => '更新时间', + 'all_work_order' => '全部工单列表', + 'no_work_data' => '暂无工单数据', + 'save' => '保存', + 'cancel' => '取消', + 'title_placeholder' => '填写故障/需求标题', + 'content_placeholder' => '详细描述故障现象、操作步骤、处理方案', + 'select_handler' => '选择处理人(留空暂不分配)', + 'status_1' => '待处理', + 'status_2' => '处理中', + 'status_3' => '已完成', + 'status_4' => '已关闭', + 'no_alert_option' => '不关联任何告警', + 'relate_alert' => '关联告警(可选)', + 'relate_alert_id' => '关联告警ID', + 'notify_title' => '通知配置', + 'notify_user' => '通知接收人', + 'notify_channel' => '通知渠道', + 'channel_mail' => '邮箱', + 'channel_ding' => '钉钉', + 'channel_wecom' => '企业微信', + 'smtp_host' => 'SMTP服务器', + 'smtp_port' => '端口', + 'smtp_ssl' => '开启SSL/TLS', + 'smtp_account' => '发件账号', + 'smtp_pwd' => '授权密码', + 'smtp_from' => '发件邮箱', + 'save_smtp' => '保存通知配置', + 'alert_loading' => '加载活跃告警...', + 'no_alert_data' => '当前无正在触发的告警', + 'user_loading' => '加载用户列表', + 'no_user_data' => '无可用用户', + 'perm_deny' => '权限不足,禁止访问', + 'unread_ticket' => '未读工单', + 'mark_all_read' => '全部标记已读' + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'notify_config' => 'Work Order Notification Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh', + 'export_csv' => 'Export CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'work_order_mgr' => 'Work Order System', + 'work_create' => 'Create Order', + 'work_edit' => 'Edit Order', + 'work_assign' => 'Assign Order', + 'work_status' => 'Status', + 'work_creator' => 'Creator', + 'work_handler' => 'Handler', + 'work_content' => 'Content / Remark', + 'work_title' => 'Order Title', + 'create_time' => 'Create Time', + 'update_time' => 'Update Time', + 'all_work_order' => 'All Work Orders', + 'no_work_data' => 'No work orders', + 'save' => 'Save', + 'cancel' => 'Cancel', + 'title_placeholder' => 'Fill fault or demand title', + 'content_placeholder' => 'Describe fault, steps and handling plan', + 'select_handler' => 'Select handler (empty for unassigned)', + 'status_1' => 'Pending', + 'status_2' => 'Processing', + 'status_3' => 'Finished', + 'status_4' => 'Closed', + 'no_alert_option' => 'No related alert', + 'relate_alert' => 'Relate Alert (Optional)', + 'relate_alert_id' => 'Relate Alert ID', + 'notify_title' => 'Notification Config', + 'notify_user' => 'Notify Users', + 'notify_channel' => 'Notify Channel', + 'channel_mail' => 'Email', + 'channel_ding' => 'DingTalk', + 'channel_wecom' => 'WeCom', + 'smtp_host' => 'SMTP Host', + 'smtp_port' => 'Port', + 'smtp_ssl' => 'Enable SSL/TLS', + 'smtp_account' => 'SMTP Account', + 'smtp_pwd' => 'Auth Password', + 'smtp_from' => 'Sender Email', + 'save_smtp' => 'Save Notification Config', + 'alert_loading' => 'Loading active alerts...', + 'no_alert_data' => 'No active firing alerts', + 'user_loading' => 'Loading user list...', + 'no_user_data' => 'No available users', + 'perm_deny' => 'Permission denied', + 'unread_ticket' => 'Unread Tickets', + 'mark_all_read' => 'Mark All Read' + ] +]; +$t = $langMap[$currentLang]; + +// 解析外链菜单 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = ["name" => trim($item[0]), "url" => trim($item[1])]; + } + } +} + +// 工单业务库 monitor +$dbWorkHost = "10.150.117.190"; +$dbWorkUser = "root"; +$dbWorkPwd = "hp93000"; +$dbWorkName = "monitor"; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + die("工单数据库 monitor 连接失败"); +} +mysqli_set_charset($connWork, "utf8mb4"); + +// 获取用户角色权限 +$isAdmin = 0; +$permList = ""; +$roleSql = "SELECT r.is_admin, r.perm_list FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +if($stmtRole){ + mysqli_stmt_bind_param($stmtRole, 's', $loginUid); + mysqli_stmt_execute($stmtRole); + $roleRes = mysqli_stmt_get_result($stmtRole); + if ($roleRes instanceof mysqli_result) { + $roleRow = mysqli_fetch_assoc($roleRes); + if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; + } + } +} + +// 权限校验临时注释,如需开启取消注释 +//$hasWorkPerm = str_contains($permList, "work_order"); +//if (!$hasWorkPerm) { +// echo ""; +// exit; +//} + +// 加载全部系统用户下拉 +$userOptions = ""; +$userAll = mysqli_query($connWork, "SELECT uid, real_name, username FROM sys_user WHERE enable = 1 ORDER BY real_name ASC"); +if ($userAll instanceof mysqli_result) { + while ($u = mysqli_fetch_assoc($userAll)) { + $userOptions .= ''; + } +} + +// ========== 修复1:统计当前用户未读待处理工单(右上角角标数字) ========== +$unreadCount = 0; +$unreadSql = "SELECT COUNT(*) cnt FROM work_order WHERE assign_uid = ? AND status = 1 AND is_read = 0"; +$stmtUnread = mysqli_prepare($connWork, $unreadSql); +mysqli_stmt_bind_param($stmtUnread, 's', $loginUid); +mysqli_stmt_execute($stmtUnread); +$unreadRes = mysqli_stmt_get_result($stmtUnread); +if($unreadRes){ + $unreadRow = mysqli_fetch_assoc($unreadRes); + $unreadCount = intval($unreadRow['cnt']); +} + +// 分页参数 +$page = isset($_GET['page']) ? intval($_GET['page']) : 1; +$pageSize = intval($sysConfig['page_size'] ?? 20); +if ($pageSize < 1) $pageSize = 20; +$offset = ($page - 1) * $pageSize; + +// ========== 修复1:数据权限过滤 普通用户仅展示创建/分配给自己工单,参数绑定修复 ========== +if ($isAdmin === 1) { + $whereSql = " 1=1 "; +} else { + $whereSql = " (create_uid = ? OR assign_uid = ?) "; +} + +// 统计工单总数 +$cntSql = "SELECT COUNT(*) total FROM work_order WHERE " . $whereSql; +$stmtCnt = mysqli_prepare($connWork, $cntSql); +$total = 0; +if($stmtCnt){ + if ($isAdmin !== 1) { + mysqli_stmt_bind_param($stmtCnt, 'ss', $loginUid, $loginUid); + } + mysqli_stmt_execute($stmtCnt); + $cntRes = mysqli_stmt_get_result($stmtCnt); + if ($cntRes instanceof mysqli_result) { + $cntRow = mysqli_fetch_assoc($cntRes); + $total = intval($cntRow['total'] ?? 0); + } +} +$totalPage = $pageSize <= 0 ? 1 : ceil($total / $pageSize); + +// 查询工单列表(带出is_read未读标记) +$listSql = "SELECT wo.*, uc.real_name create_name, ua.real_name assign_name +FROM work_order wo +LEFT JOIN sys_user uc ON wo.create_uid = uc.uid +LEFT JOIN sys_user ua ON wo.assign_uid = ua.uid +WHERE " . $whereSql . " ORDER BY create_time DESC LIMIT ?, ?"; +$stmtList = mysqli_prepare($connWork, $listSql); +$orderList = []; +if($stmtList){ + if ($isAdmin === 1) { + mysqli_stmt_bind_param($stmtList, 'ii', $offset, $pageSize); + } else { + // 修复参数绑定:2个字符串uid + 2个数字分页参数 + mysqli_stmt_bind_param($stmtList, 'ssii', $loginUid, $loginUid, $offset, $pageSize); + } + mysqli_stmt_execute($stmtList); + $listResult = mysqli_stmt_get_result($stmtList); + if ($listResult instanceof mysqli_result) { + while ($row = mysqli_fetch_assoc($listResult)) { + $orderList[] = $row; + } + } +} +mysqli_close($connWork); +?> + + + + + +<?php echo $pageTitle; ?> - Advantest <?php echo $t['work_order_mgr']; ?> + + + + + + +
+
+
+
+ +
+
+
+
+
Advantest
+
+
+
+
+ + + + 0):?> + + + -- +
+ +
+ + +
+
+
+
+
+
+
+ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDOP
+
+ +
+
+
+ + + + + +
+
+ +
+
+
+
+ + + + + + + + + diff --git a/work_order.php.2.0 b/work_order.php.2.0 new file mode 100644 index 0000000..7fb6884 --- /dev/null +++ b/work_order.php.2.0 @@ -0,0 +1,894 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +// 读取全局配置库(和dashboard共用配置库) +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} +mysqli_close($connConfig); + +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$themeColor = htmlspecialchars($sysConfig['theme_color'] ?? "#409eff"); +$pageSize = $sysConfig['page_size'] ?? "20"; +$footerText = htmlspecialchars($sysConfig['footer_text'] ?? ""); +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +$currentLang = $sysConfig['lang'] ?? "zh"; + +// 多语言词典(继承dashboard全部词条,新增工单词条) +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警监控总览', + 'disk_capacity' => '服务器磁盘容量', + 'alert_list_page' => '历史告警查询', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '后台配置管理', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新全部数据', + 'export_csv' => '导出CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + // 工单新增词条 + 'work_order_mgr' => '工单系统', + 'work_order_title' => '工单管理', + 'work_create' => '新建工单', + 'work_edit' => '编辑工单', + 'work_assign' => '分发工单', + 'work_status' => '工单状态', + 'work_creator' => '创建人', + 'work_handler' => '处理人', + 'work_content' => '工单内容/备注', + 'work_title' => '工单标题', + 'work_create_time' => '创建时间', + 'work_update_time' => '更新时间', + 'work_all_list' => '全部工单列表', + 'work_no_data' => '暂无工单记录', + 'work_save' => '保存', + 'work_cancel' => '取消', + 'work_placeholder_title' => '填写故障/需求标题', + 'work_placeholder_content' => '详细描述故障、操作步骤、处理备注', + 'work_select_handler' => '选择处理人(留空暂不分配)', + 'status_1' => '待处理', + 'status_2' => '处理中', + 'status_3' => '已完成', + 'status_4' => '已关闭' + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'disk_capacity' => 'Server Disk Capacity', + 'alert_list_page' => 'Alert Pagination List', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh All Data', + 'export_csv' => 'Export CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + // 工单英文词条 + 'work_order_mgr' => 'Work Order System', + 'work_order_title' => 'Work Order Manage', + 'work_create' => 'Create Order', + 'work_edit' => 'Edit Order', + 'work_assign' => 'Assign Order', + 'work_status' => 'Status', + 'work_creator' => 'Creator', + 'work_handler' => 'Handler', + 'work_content' => 'Content / Remark', + 'work_title' => 'Order Title', + 'work_create_time' => 'Create Time', + 'work_update_time' => 'Update Time', + 'work_all_list' => 'All Work Order List', + 'work_no_data' => 'No order data', + 'work_save' => 'Save', + 'work_cancel' => 'Cancel', + 'work_placeholder_title' => 'Fill fault or demand title', + 'work_placeholder_content' => 'Describe fault, steps and handling remark', + 'work_select_handler' => 'Select handler (empty for unassigned)', + 'status_1' => 'Pending', + 'status_2' => 'Processing', + 'status_3' => 'Finished', + 'status_4' => 'Closed' + ] +]; +$t = $langMap[$currentLang]; + +// 解析外链菜单 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = [ + "name" => trim($item[0]), + "url" => trim($item[1]) + ]; + } + } +} + +// ========== 工单业务数据库(monitor库)========== +$dbWorkHost = "10.150.117.190"; +$dbWorkUser = "root"; +$dbWorkPwd = "hp93000"; +$dbWorkName = "monitor"; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) die("Work DB connect fail: " . mysqli_connect_error()); +mysqli_set_charset($connWork, "utf8mb4"); +$loginUid = $_SESSION['user_id']; + +// 获取当前用户是否管理员 +$isAdmin = 0; +$roleSql = "SELECT r.is_admin FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtRole)); +if ($roleRow) $isAdmin = intval($roleRow['is_admin']); + +// 获取所有用户下拉 +$userOptions = ""; +$userRes = mysqli_query($connWork, "SELECT uid, real_name, username FROM sys_user WHERE enable = 1"); +while ($u = mysqli_fetch_assoc($userRes)) { + $userOptions .= ''; +} +// 分页参数 +$page = isset($_GET['page']) ? intval($_GET['page']) : 1; +// 强制转为数字,最小10,防止0 +$pageSize = intval($sysConfig['page_size'] ?? 20); +if ($pageSize < 1) $pageSize = 20; +$offset = ($page - 1) * $pageSize; + +// 权限过滤 +if ($isAdmin === 1) { + $whereSql = " 1=1 "; +} else { + $whereSql = " (create_uid = ? OR assign_uid = ?) "; +} + +// 统计总数 +$cntSql = "SELECT COUNT(*) total FROM work_order WHERE " . $whereSql; +$stmtCnt = mysqli_prepare($connWork, $cntSql); +if ($isAdmin !== 1) { + mysqli_stmt_bind_param($stmtCnt, 'ss', $loginUid, $loginUid); +} +mysqli_stmt_execute($stmtCnt); +$cntRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtCnt)); +$total = intval($cntRow['total'] ?? 0); + +// 防除零 +if ($pageSize <= 0) { + $totalPage = 1; +} else { + $totalPage = ceil($total / $pageSize); +} +// 工单列表 +$listSql = "SELECT wo.*, uc.real_name create_name, ua.real_name assign_name +FROM work_order wo +LEFT JOIN sys_user uc ON wo.create_uid = uc.uid +LEFT JOIN sys_user ua ON wo.assign_uid = ua.uid +WHERE " . $whereSql . " ORDER BY create_time DESC LIMIT ?, ?"; +$stmtList = mysqli_prepare($connWork, $listSql); +if ($isAdmin === 1) { + mysqli_stmt_bind_param($stmtList, 'ii', $offset, $pageSize); +} else { + mysqli_stmt_bind_param($stmtList, 'ssii', $loginUid, $loginUid, $offset, $pageSize); +} +mysqli_stmt_execute($stmtList); +$listResult = mysqli_stmt_get_result($stmtList); +$orderList = []; +while ($row = mysqli_fetch_assoc($listResult)) { + $orderList[] = $row; +} +mysqli_close($connWork); +?> + + + + + +<?php echo $pageTitle; ?> - Advantest <?php echo $t['work_order_mgr']; ?> + + + + + + + +
+
+ + +
+
+ +
+ + + +
+
+
+
+
Advantest
+
+
+
+
+ + -- +
+ + +
+ + +
+
+ +
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ID /
+
+
+
+
+
+ + + + + +
+
+ +
+
+
+ 1): ?> + + + / + + + +
+
+
+
+
+
+
+ + + + + + + + + + diff --git a/work_order.php.3.0 b/work_order.php.3.0 new file mode 100644 index 0000000..d6a0ba2 --- /dev/null +++ b/work_order.php.3.0 @@ -0,0 +1,957 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +// 读取全局配置库 +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} +mysqli_close($connConfig); + +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$themeColor = htmlspecialchars($sysConfig['theme_color'] ?? "#409eff"); +$pageSize = $sysConfig['page_size'] ?? "20"; +$footerText = htmlspecialchars($sysConfig['footer_text'] ?? ""); +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +$currentLang = $sysConfig['lang'] ?? "zh"; + +// 多语言词典 +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警监控总览', + 'disk_capacity' => '服务器磁盘容量', + 'alert_list_page' => '历史告警查询', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '后台配置管理', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新全部数据', + 'export_csv' => '导出CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'work_order_mgr' => '工单系统', + 'work_order_title' => '工单管理', + 'work_create' => '新建工单', + 'work_edit' => '编辑工单', + 'work_assign' => '分发工单', + 'work_status' => '工单状态', + 'work_creator' => '创建人', + 'work_handler' => '处理人', + 'work_content' => '工单内容/备注', + 'work_title' => '工单标题', + 'work_create_time' => '创建时间', + 'work_update_time' => '更新时间', + 'work_all_list' => '全部工单列表', + 'work_no_data' => '暂无工单记录', + 'work_save' => '保存', + 'work_cancel' => '取消', + 'work_placeholder_title' => '填写故障/需求标题', + 'work_placeholder_content' => '详细描述故障、操作步骤、处理备注', + 'work_select_handler' => '选择处理人(留空暂不分配)', + 'status_1' => '待处理', + 'status_2' => '处理中', + 'status_3' => '已完成', + 'status_4' => '已关闭', + 'no_alert_choose' => '不关联任何告警', + 'relate_alert' => '关联告警(可选)', + 'relate_alert_id' => '关联告警ID' + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'disk_capacity' => 'Server Disk Capacity', + 'alert_list_page' => 'Alert Pagination List', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh All Data', + 'export_csv' => 'Export CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'work_order_mgr' => 'Work Order System', + 'work_order_title' => 'Work Order Manage', + 'work_create' => 'Create Order', + 'work_edit' => 'Edit Order', + 'work_assign' => 'Assign Order', + 'work_status' => 'Status', + 'work_creator' => 'Creator', + 'work_handler' => 'Handler', + 'work_content' => 'Content / Remark', + 'work_title' => 'Order Title', + 'work_create_time' => 'Create Time', + 'work_update_time' => 'Update Time', + 'work_all_list' => 'All Work Order List', + 'work_no_data' => 'No order data', + 'work_save' => 'Save', + 'work_cancel' => 'Cancel', + 'work_placeholder_title' => 'Fill fault or demand title', + 'work_placeholder_content' => 'Describe fault, steps and handling remark', + 'work_select_handler' => 'Select handler (empty for unassigned)', + 'status_1' => 'Pending', + 'status_2' => 'Processing', + 'status_3' => 'Finished', + 'status_4' => 'Closed', + 'no_alert_choose' => 'No related alert', + 'relate_alert' => 'Relate Alert (Optional)', + 'relate_alert_id' => 'Relate Alert ID' + ] +]; +$t = $langMap[$currentLang]; + +// 解析外链菜单 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = [ + "name" => trim($item[0]), + "url" => trim($item[1]) + ]; + } + } +} + +// ========== 工单业务库 monitor ========== +$dbWorkHost = "10.150.117.190"; +$dbWorkUser = "root"; +$dbWorkPwd = "hp93000"; +$dbWorkName = "monitor"; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) die("Work DB connect fail: " . mysqli_connect_error()); +mysqli_set_charset($connWork, "utf8mb4"); +$loginUid = $_SESSION['user_id']; + +// 获取当前用户是否管理员 +$isAdmin = 0; +$roleSql = "SELECT r.is_admin FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtRole)); +if ($roleRow) $isAdmin = intval($roleRow['is_admin']); + +// 用户下拉 +$userOptions = ""; +$userRes = mysqli_query($connWork, "SELECT uid, real_name, username FROM sys_user WHERE enable = 1"); +while ($u = mysqli_fetch_assoc($userRes)) { + $userOptions .= ''; +} + +// 读取活跃告警下拉(关联工单) +$alertConn = mysqli_connect("10.150.117.190","root","hp93000","alert_mail_stat",3306); +$alertOptions = ''; +if($alertConn){ + mysqli_set_charset($alertConn,"utf8mb4"); + $alertSql = "SELECT alert_id,alert_name,instance FROM alert_firing ORDER BY receive_time DESC LIMIT 100"; + $alertRes = mysqli_query($alertConn,$alertSql); + while($row = mysqli_fetch_assoc($alertRes)){ + $aid = htmlspecialchars($row['alert_id']); + $aname = htmlspecialchars($row['alert_name']); + $ip = htmlspecialchars($row['instance']); + $alertOptions .= ""; + } + mysqli_close($alertConn); +} + +// 分页【修复非数字、除零警告】 +$page = isset($_GET['page']) ? intval($_GET['page']) : 1; +$pageSize = intval($sysConfig['page_size'] ?? 20); +if ($pageSize < 1) $pageSize = 20; +$offset = ($page - 1) * $pageSize; + +// 权限过滤 +if ($isAdmin === 1) { + $whereSql = " 1=1 "; +} else { + $whereSql = " (create_uid = ? OR assign_uid = ?) "; +} + +// 统计总数 +$cntSql = "SELECT COUNT(*) total FROM work_order WHERE " . $whereSql; +$stmtCnt = mysqli_prepare($connWork, $cntSql); +if ($isAdmin !== 1) { + mysqli_stmt_bind_param($stmtCnt, 'ss', $loginUid, $loginUid); +} +mysqli_stmt_execute($stmtCnt); +$cntRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtCnt)); +$total = intval($cntRow['total'] ?? 0); + +// 防除零 +if ($pageSize <= 0) { + $totalPage = 1; +} else { + $totalPage = ceil($total / $pageSize); +} + +// 工单列表查询(带关联告警ID) +$listSql = "SELECT wo.*, uc.real_name create_name, ua.real_name assign_name +FROM work_order wo +LEFT JOIN sys_user uc ON wo.create_uid = uc.uid +LEFT JOIN sys_user ua ON wo.assign_uid = ua.uid +WHERE " . $whereSql . " ORDER BY create_time DESC LIMIT ?, ?"; +$stmtList = mysqli_prepare($connWork, $listSql); +if ($isAdmin === 1) { + mysqli_stmt_bind_param($stmtList, 'ii', $offset, $pageSize); +} else { + mysqli_stmt_bind_param($stmtList, 'ssii', $loginUid, $loginUid, $offset, $pageSize); +} +mysqli_stmt_execute($stmtList); +$listResult = mysqli_stmt_get_result($stmtList); +$orderList = []; +while ($row = mysqli_fetch_assoc($listResult)) { + $orderList[] = $row; +} +mysqli_close($connWork); +?> + + + + + +<?php echo $pageTitle; ?> - Advantest <?php echo $t['work_order_mgr']; ?> + + + + + + +
+
+ + +
+
+ +
+ + +
+
+
+
+
Advantest
+
+
+
+
+ + -- +
+ + +
+ + +
+
+ +
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ID /
+
+
+
+
+
+ + + + + +
+
+
+
+
+ 1): ?> + + + / + + + +
+
+
+
+
+
+
+ + + + + + + + + + diff --git a/work_order.php.4.0 b/work_order.php.4.0 new file mode 100644 index 0000000..7fb6884 --- /dev/null +++ b/work_order.php.4.0 @@ -0,0 +1,894 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +// 读取全局配置库(和dashboard共用配置库) +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} +mysqli_close($connConfig); + +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$themeColor = htmlspecialchars($sysConfig['theme_color'] ?? "#409eff"); +$pageSize = $sysConfig['page_size'] ?? "20"; +$footerText = htmlspecialchars($sysConfig['footer_text'] ?? ""); +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +$currentLang = $sysConfig['lang'] ?? "zh"; + +// 多语言词典(继承dashboard全部词条,新增工单词条) +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警监控总览', + 'disk_capacity' => '服务器磁盘容量', + 'alert_list_page' => '历史告警查询', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '后台配置管理', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新全部数据', + 'export_csv' => '导出CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + // 工单新增词条 + 'work_order_mgr' => '工单系统', + 'work_order_title' => '工单管理', + 'work_create' => '新建工单', + 'work_edit' => '编辑工单', + 'work_assign' => '分发工单', + 'work_status' => '工单状态', + 'work_creator' => '创建人', + 'work_handler' => '处理人', + 'work_content' => '工单内容/备注', + 'work_title' => '工单标题', + 'work_create_time' => '创建时间', + 'work_update_time' => '更新时间', + 'work_all_list' => '全部工单列表', + 'work_no_data' => '暂无工单记录', + 'work_save' => '保存', + 'work_cancel' => '取消', + 'work_placeholder_title' => '填写故障/需求标题', + 'work_placeholder_content' => '详细描述故障、操作步骤、处理备注', + 'work_select_handler' => '选择处理人(留空暂不分配)', + 'status_1' => '待处理', + 'status_2' => '处理中', + 'status_3' => '已完成', + 'status_4' => '已关闭' + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'disk_capacity' => 'Server Disk Capacity', + 'alert_list_page' => 'Alert Pagination List', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh All Data', + 'export_csv' => 'Export CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + // 工单英文词条 + 'work_order_mgr' => 'Work Order System', + 'work_order_title' => 'Work Order Manage', + 'work_create' => 'Create Order', + 'work_edit' => 'Edit Order', + 'work_assign' => 'Assign Order', + 'work_status' => 'Status', + 'work_creator' => 'Creator', + 'work_handler' => 'Handler', + 'work_content' => 'Content / Remark', + 'work_title' => 'Order Title', + 'work_create_time' => 'Create Time', + 'work_update_time' => 'Update Time', + 'work_all_list' => 'All Work Order List', + 'work_no_data' => 'No order data', + 'work_save' => 'Save', + 'work_cancel' => 'Cancel', + 'work_placeholder_title' => 'Fill fault or demand title', + 'work_placeholder_content' => 'Describe fault, steps and handling remark', + 'work_select_handler' => 'Select handler (empty for unassigned)', + 'status_1' => 'Pending', + 'status_2' => 'Processing', + 'status_3' => 'Finished', + 'status_4' => 'Closed' + ] +]; +$t = $langMap[$currentLang]; + +// 解析外链菜单 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = [ + "name" => trim($item[0]), + "url" => trim($item[1]) + ]; + } + } +} + +// ========== 工单业务数据库(monitor库)========== +$dbWorkHost = "10.150.117.190"; +$dbWorkUser = "root"; +$dbWorkPwd = "hp93000"; +$dbWorkName = "monitor"; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) die("Work DB connect fail: " . mysqli_connect_error()); +mysqli_set_charset($connWork, "utf8mb4"); +$loginUid = $_SESSION['user_id']; + +// 获取当前用户是否管理员 +$isAdmin = 0; +$roleSql = "SELECT r.is_admin FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtRole)); +if ($roleRow) $isAdmin = intval($roleRow['is_admin']); + +// 获取所有用户下拉 +$userOptions = ""; +$userRes = mysqli_query($connWork, "SELECT uid, real_name, username FROM sys_user WHERE enable = 1"); +while ($u = mysqli_fetch_assoc($userRes)) { + $userOptions .= ''; +} +// 分页参数 +$page = isset($_GET['page']) ? intval($_GET['page']) : 1; +// 强制转为数字,最小10,防止0 +$pageSize = intval($sysConfig['page_size'] ?? 20); +if ($pageSize < 1) $pageSize = 20; +$offset = ($page - 1) * $pageSize; + +// 权限过滤 +if ($isAdmin === 1) { + $whereSql = " 1=1 "; +} else { + $whereSql = " (create_uid = ? OR assign_uid = ?) "; +} + +// 统计总数 +$cntSql = "SELECT COUNT(*) total FROM work_order WHERE " . $whereSql; +$stmtCnt = mysqli_prepare($connWork, $cntSql); +if ($isAdmin !== 1) { + mysqli_stmt_bind_param($stmtCnt, 'ss', $loginUid, $loginUid); +} +mysqli_stmt_execute($stmtCnt); +$cntRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtCnt)); +$total = intval($cntRow['total'] ?? 0); + +// 防除零 +if ($pageSize <= 0) { + $totalPage = 1; +} else { + $totalPage = ceil($total / $pageSize); +} +// 工单列表 +$listSql = "SELECT wo.*, uc.real_name create_name, ua.real_name assign_name +FROM work_order wo +LEFT JOIN sys_user uc ON wo.create_uid = uc.uid +LEFT JOIN sys_user ua ON wo.assign_uid = ua.uid +WHERE " . $whereSql . " ORDER BY create_time DESC LIMIT ?, ?"; +$stmtList = mysqli_prepare($connWork, $listSql); +if ($isAdmin === 1) { + mysqli_stmt_bind_param($stmtList, 'ii', $offset, $pageSize); +} else { + mysqli_stmt_bind_param($stmtList, 'ssii', $loginUid, $loginUid, $offset, $pageSize); +} +mysqli_stmt_execute($stmtList); +$listResult = mysqli_stmt_get_result($stmtList); +$orderList = []; +while ($row = mysqli_fetch_assoc($listResult)) { + $orderList[] = $row; +} +mysqli_close($connWork); +?> + + + + + +<?php echo $pageTitle; ?> - Advantest <?php echo $t['work_order_mgr']; ?> + + + + + + + +
+
+ + +
+
+ +
+ + + +
+
+
+
+
Advantest
+
+
+
+
+ + -- +
+ + +
+ + +
+
+ +
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ID /
+
+
+
+
+
+ + + + + +
+
+ +
+
+
+ 1): ?> + + + / + + + +
+
+
+
+
+
+
+ + + + + + + + + + diff --git a/work_order.php.5.0 b/work_order.php.5.0 new file mode 100644 index 0000000..abe135f --- /dev/null +++ b/work_order.php.5.0 @@ -0,0 +1,823 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRoleId = $_SESSION['role_id']; + +// 读取全局配置库 alert_mail_stat +$dbConfigHost = "10.150.117.190"; +$dbConfigUser = "root"; +$dbConfigPwd = "hp93000"; +$dbConfigName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbConfigHost, $dbConfigUser, $dbConfigPwd, $dbConfigName); +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} + +// 读取SMTP配置 +$smtpRow = mysqli_fetch_assoc(mysqli_query($connConfig, "SELECT * FROM sys_smtp_config WHERE id=1")); +$smtpConfig = $smtpRow ?? []; + +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$currentLang = $sysConfig['lang'] ?? "zh"; +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +mysqli_close($connConfig); + +// 多语言词典 +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警监控总览', + 'disk_capacity' => '服务器磁盘容量', + 'alert_list_page' => '历史告警查询', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '后台配置管理', + 'smtp_config' => '邮箱SMTP配置', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新全部数据', + 'export_csv' => '导出CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'work_order_mgr' => '工单系统', + 'work_create' => '新建工单', + 'work_edit' => '编辑工单', + 'work_assign' => '分发工单', + 'work_status' => '工单状态', + 'work_creator' => '创建人', + 'work_handler' => '处理人', + 'work_content' => '工单内容/备注', + 'work_title' => '工单标题', + 'work_create_time' => '创建时间', + 'work_update_time' => '更新时间', + 'work_all_list' => '全部工单列表', + 'work_no_data' => '暂无工单记录', + 'work_save' => '保存', + 'work_cancel' => '取消', + 'work_placeholder_title' => '填写故障/需求标题', + 'work_placeholder_content' => '详细描述故障、操作步骤、处理备注', + 'work_select_handler' => '选择处理人(留空暂不分配)', + 'status_1' => '待处理', + 'status_2' => '处理中', + 'status_3' => '已完成', + 'status_4' => '已关闭', + 'no_alert_choose' => '不关联任何告警', + 'relate_alert' => '关联告警(可选)', + 'relate_alert_id' => '关联告警ID', + 'notify_title' => '通知配置', + 'notify_user' => '通知接收人', + 'notify_channel' => '通知渠道', + 'channel_mail' => '邮箱', + 'channel_ding' => '钉钉', + 'channel_wecom' => '企业微信', + 'smtp_host' => 'SMTP服务器', + 'smtp_port' => '端口', + 'smtp_ssl' => '启用SSL/TLS', + 'smtp_account' => '发件账号', + 'smtp_pwd' => '授权密码', + 'smtp_from' => '发件人名称', + 'save_smtp' => '保存SMTP配置', + 'alert_loading' => '加载当前活跃告警...', + 'no_alert_data' => '暂无正在触发的告警', + 'user_loading' => '加载用户列表...', + 'no_user_data' => '无可用用户', + 'perm_deny' => '权限不足,无法访问', + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'disk_capacity' => 'Server Disk Capacity', + 'alert_list_page' => 'Alert Pagination List', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'smtp_config' => 'SMTP Mail Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh All Data', + 'export_csv' => 'Export CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'work_order_mgr' => 'Work Order System', + 'work_create' => 'Create Order', + 'work_edit' => 'Edit Order', + 'work_assign' => 'Assign Order', + 'work_status' => 'Status', + 'work_creator' => 'Creator', + 'work_handler' => 'Handler', + 'work_content' => 'Content / Remark', + 'work_title' => 'Order Title', + 'work_create_time' => 'Create Time', + 'work_update_time' => 'Update Time', + 'work_all_list' => 'All Work Order List', + 'work_no_data' => 'No order data', + 'work_save' => 'Save', + 'work_cancel' => 'Cancel', + 'work_placeholder_title' => 'Fill fault or demand title', + 'work_placeholder_content' => 'Describe fault, steps and handling remark', + 'work_select_handler' => 'Select handler (empty for unassigned)', + 'status_1' => 'Pending', + 'status_2' => 'Processing', + 'status_3' => 'Finished', + 'status_4' => 'Closed', + 'no_alert_choose' => 'No related alert', + 'relate_alert' => 'Relate Alert (Optional)', + 'relate_alert_id' => 'Relate Alert ID', + 'notify_title' => 'Notification Config', + 'notify_user' => 'Notify Users', + 'notify_channel' => 'Notify Channel', + 'channel_mail' => 'Email', + 'channel_ding' => 'DingTalk', + 'channel_wecom' => 'WeCom', + 'smtp_host' => 'SMTP Host', + 'smtp_port' => 'Port', + 'smtp_ssl' => 'Enable SSL/TLS', + 'smtp_account' => 'SMTP Account', + 'smtp_pwd' => 'Auth Password', + 'smtp_from' => 'Sender Name', + 'save_smtp' => 'Save SMTP Config', + 'alert_loading' => 'Loading active alerts...', + 'no_alert_data' => 'No active firing alerts', + 'user_loading' => 'Loading user list...', + 'no_user_data' => 'No available users', + 'perm_deny' => 'Permission denied', + ] +]; +$t = $langMap[$currentLang]; + +// 解析外链菜单 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = ["name" => trim($item[0]), "url" => trim($item[1])]; + } + } +} + +// ========== 工单业务库 monitor ========== +$dbWorkHost = "10.150.117.190"; +$dbWorkUser = "root"; +$dbWorkPwd = "hp93000"; +$dbWorkName = "monitor"; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) die("Work DB connect fail: " . mysqli_connect_error()); +mysqli_set_charset($connWork, "utf8mb4"); +$loginUid = $_SESSION['user_id']; + +// 读取当前用户角色权限 +$permList = ""; +$roleSql = "SELECT r.is_admin, r.perm_list FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtRole)); +$isAdmin = 0; +$permList = ""; +if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; +} +$hasWorkPerm = str_contains($permList, "work_order"); +if (!$hasWorkPerm) { + echo ""; + exit; +} + +// 加载全部系统用户(解决处理人下拉空白) +$userOptions = ""; +$userAll = mysqli_query($connWork, "SELECT uid, real_name, username FROM sys_user WHERE enable = 1 ORDER BY real_name ASC"); +while ($u = mysqli_fetch_assoc($userAll)) { + $userOptions .= ''; +} + +// 分页修复防报错 +$page = isset($_GET['page']) ? intval($_GET['page']) : 1; +$pageSize = intval($sysConfig['page_size'] ?? 20); +if ($pageSize < 1) $pageSize = 20; +$offset = ($page - 1) * $pageSize; + +// 权限过滤 +if ($isAdmin === 1) { + $whereSql = " 1=1 "; +} else { + $whereSql = " (create_uid = ? OR assign_uid = ?) "; +} + +// 统计总数 +$cntSql = "SELECT COUNT(*) total FROM work_order WHERE " . $whereSql; +$stmtCnt = mysqli_prepare($connWork, $cntSql); +if ($isAdmin !== 1) { + mysqli_stmt_bind_param($stmtCnt, 'ss', $loginUid, $loginUid); +} +mysqli_stmt_execute($stmtCnt); +$cntRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtCnt)); +$total = intval($cntRow['total'] ?? 0); +$totalPage = $pageSize <= 0 ? 1 : ceil($total / $pageSize); + +// 工单列表查询 +$listSql = "SELECT wo.*, uc.real_name create_name, ua.real_name assign_name +FROM work_order wo +LEFT JOIN sys_user uc ON wo.create_uid = uc.uid +LEFT JOIN sys_user ua ON wo.assign_uid = ua.uid +WHERE " . $whereSql . " ORDER BY create_time DESC LIMIT ?, ?"; +$stmtList = mysqli_prepare($connWork, $listSql); +if ($isAdmin === 1) { + mysqli_stmt_bind_param($stmtList, 'ii', $offset, $pageSize); +} else { + mysqli_stmt_bind_param($stmtList, 'ssii', $loginUid, $loginUid, $offset, $pageSize); +} +mysqli_stmt_execute($stmtList); +$listResult = mysqli_stmt_get_result($stmtList); +$orderList = []; +while ($row = mysqli_fetch_assoc($listResult)) { + $orderList[] = $row; +} +mysqli_close($connWork); +?> + + + + + +<?php echo $pageTitle; ?> - Advantest <?php echo $t['work_order_mgr']; ?> + + + + + + +
+
+
+
+ +
+
+
+
+
Advantest
+
+
+
+
+ + -- +
+ + +
+ + +
+
+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ID操作
+ + + + + +
+
+
+
+
+ 1): ?> + + + / + + + +
+
+
+
+
+
+
+ + + + + + + + + + diff --git a/work_order.php.6.0 b/work_order.php.6.0 new file mode 100644 index 0000000..8b27ec6 --- /dev/null +++ b/work_order.php.6.0 @@ -0,0 +1,849 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRoleId = $_SESSION['role_id']; + +// 读取全局配置库 alert_mail_stat +$dbConfigHost = "10.150.117.190"; +$dbConfigUser = "root"; +$dbConfigPwd = "hp93000"; +$dbConfigName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbConfigHost, $dbConfigUser, $dbConfigPwd, $dbConfigName); +if(!$connConfig){ + die("配置库连接失败"); +} +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} + +// 读取SMTP配置 +$smtpRow = []; +$smtpQuery = mysqli_query($connConfig, "SELECT * FROM sys_smtp_config WHERE id=1"); +if($smtpQuery){ + $smtpRow = mysqli_fetch_assoc($smtpQuery); +} +$smtpConfig = $smtpRow ?? []; + +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$currentLang = $sysConfig['lang'] ?? "zh"; +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +mysqli_close($connConfig); + +// 多语言词典 +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警总览', + 'disk_capacity' => '磁盘容量', + 'alert_list_page' => '历史告警', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '系统参数', + 'smtp_config' => '邮箱SMTP配置', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新页面', + 'export_csv' => '导出CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'work_order_mgr' => '工单系统', + 'work_create' => '新建工单', + 'work_edit' => '编辑工单', + 'work_assign' => '分发工单', + 'work_status' => '工单状态', + 'work_creator' => '创建人', + 'work_handler' => '处理人', + 'work_content' => '工单内容/备注', + 'work_title' => '工单标题', + 'create_time' => '创建时间', + 'update_time' => '更新时间', + 'all_work_order' => '全部工单列表', + 'no_work_data' => '暂无工单数据', + 'save' => '保存', + 'cancel' => '取消', + 'title_placeholder' => '填写故障/需求标题', + 'content_placeholder' => '详细描述故障现象、操作步骤、处理方案', + 'select_handler' => '选择处理人(留空暂不分配)', + 'status_1' => '待处理', + 'status_2' => '处理中', + 'status_3' => '已完成', + 'status_4' => '已关闭', + 'no_alert_option' => '不关联任何告警', + 'relate_alert' => '关联告警(可选)', + 'relate_alert_id' => '关联告警ID', + 'notify_title' => '通知配置', + 'notify_user' => '通知接收人', + 'notify_channel' => '通知渠道', + 'channel_mail' => '邮箱', + 'channel_ding' => '钉钉', + 'channel_wecom' => '企业微信', + 'smtp_host' => 'SMTP服务器', + 'smtp_port' => '端口', + 'smtp_ssl' => '开启SSL/TLS', + 'smtp_account' => '发件账号', + 'smtp_pwd' => '授权密码', + 'smtp_from' => '发件邮箱', + 'save_smtp' => '保存SMTP配置', + 'alert_loading' => '加载活跃告警...', + 'no_alert_data' => '当前无正在触发的告警', + 'user_loading' => '加载用户列表', + 'no_user_data' => '无可用用户', + 'perm_deny' => '权限不足,禁止访问', + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'disk_capacity' => 'Disk Capacity', + 'alert_list_page' => 'History Alert', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'smtp_config' => 'SMTP Mail Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh', + 'export_csv' => 'Export CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'work_order_mgr' => 'Work Order System', + 'work_create' => 'Create Order', + 'work_edit' => 'Edit Order', + 'work_assign' => 'Assign Order', + 'work_status' => 'Status', + 'work_creator' => 'Creator', + 'work_handler' => 'Handler', + 'work_content' => 'Content / Remark', + 'work_title' => 'Order Title', + 'create_time' => 'Create Time', + 'update_time' => 'Update Time', + 'all_work_order' => 'All Work Orders', + 'no_work_data' => 'No work orders', + 'save' => 'Save', + 'cancel' => 'Cancel', + 'title_placeholder' => 'Fill fault or demand title', + 'content_placeholder' => 'Describe fault, steps and handling plan', + 'select_handler' => 'Select handler (empty for unassigned)', + 'status_1' => 'Pending', + 'status_2' => 'Processing', + 'status_3' => 'Finished', + 'status_4' => 'Closed', + 'no_alert_option' => 'No related alert', + 'relate_alert' => 'Relate Alert (Optional)', + 'relate_alert_id' => 'Relate Alert ID', + 'notify_title' => 'Notification Config', + 'notify_user' => 'Notify Users', + 'notify_channel' => 'Notify Channel', + 'channel_mail' => 'Email', + 'channel_ding' => 'DingTalk', + 'channel_wecom' => 'WeCom', + 'smtp_host' => 'SMTP Host', + 'smtp_port' => 'Port', + 'smtp_ssl' => 'Enable SSL/TLS', + 'smtp_account' => 'SMTP Account', + 'smtp_pwd' => 'Auth Password', + 'smtp_from' => 'Sender Email', + 'save_smtp' => 'Save SMTP Config', + 'alert_loading' => 'Loading active alerts...', + 'no_alert_data' => 'No active firing alerts', + 'user_loading' => 'Loading user list...', + 'no_user_data' => 'No available users', + 'perm_deny' => 'Permission denied', + ] +]; +$t = $langMap[$currentLang]; + +// 解析外链菜单 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = ["name" => trim($item[0]), "url" => trim($item[1])]; + } + } +} + +// ========== 工单业务库 monitor ========== +$dbWorkHost = "10.150.117.190"; +$dbWorkUser = "root"; +$dbWorkPwd = "hp93000"; +$dbWorkName = "monitor"; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + die("工单数据库 monitor 连接失败"); +} +mysqli_set_charset($connWork, "utf8mb4"); +$loginUid = $_SESSION['user_id']; + +// 获取当前用户角色权限 +$isAdmin = 0; +$permList = ""; +$roleSql = "SELECT r.is_admin, r.perm_list FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +if($stmtRole){ + mysqli_stmt_bind_param($stmtRole, 's', $loginUid); + mysqli_stmt_execute($stmtRole); + $roleRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtRole)); + if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; + } +} + +//$hasWorkPerm = str_contains($permList, "work_order"); +//if (!$hasWorkPerm) { +// echo ""; +// exit; +//} + +// 加载全部系统用户(处理人下拉) +$userOptions = ""; +$userAll = mysqli_query($connWork, "SELECT uid, real_name, username FROM sys_user WHERE enable = 1 ORDER BY real_name ASC"); +while ($u = mysqli_fetch_assoc($userAll)) { + $userOptions .= ''; +} + +// 分页修复防报错 +$page = isset($_GET['page']) ? intval($_GET['page']) : 1; +$pageSize = intval($sysConfig['page_size'] ?? 20); +if ($pageSize < 1) $pageSize = 20; +$offset = ($page - 1) * $pageSize; + +// 权限过滤 +if ($isAdmin === 1) { + $whereSql = " 1=1 "; +} else { + $whereSql = " (create_uid = ? OR assign_uid = ?) "; +} + +// 统计总数 +$cntSql = "SELECT COUNT(*) total FROM work_order WHERE " . $whereSql; +$stmtCnt = mysqli_prepare($connWork, $cntSql); +if($stmtCnt){ + if ($isAdmin !== 1) { + mysqli_stmt_bind_param($stmtCnt, 'ss', $loginUid, $loginUid); + } + mysqli_stmt_execute($stmtCnt); + $cntRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtCnt)); + $total = intval($cntRow['total'] ?? 0); +}else{ + $total = 0; +} +$totalPage = $pageSize <= 0 ? 1 : ceil($total / $pageSize); + +// 工单列表查询 +$listSql = "SELECT wo.*, uc.real_name create_name, ua.real_name assign_name +FROM work_order wo +LEFT JOIN sys_user uc ON wo.create_uid = uc.uid +LEFT JOIN sys_user ua ON wo.assign_uid = ua.uid +WHERE " . $whereSql . " ORDER BY create_time DESC LIMIT ?, ?"; +$stmtList = mysqli_prepare($connWork, $listSql); +$orderList = []; +if($stmtList){ + if ($isAdmin === 1) { + mysqli_stmt_bind_param($stmtList, 'ii', $offset, $pageSize); + } else { + mysqli_stmt_bind_param($stmtList, 'ssii', $loginUid, $loginUid, $offset, $pageSize); + } + mysqli_stmt_execute($stmtList); + $listResult = mysqli_stmt_get_result($stmtList); + while ($row = mysqli_fetch_assoc($listResult)) { + $orderList[] = $row; + } +} +mysqli_close($connWork); +?> + + + + + +<?php echo $pageTitle; ?> - Advantest <?php echo $t['work_order_mgr']; ?> + + + + + + +
+
+
+
+ +
+
+
+
+
Advantest
+
+
+
+
+ + -- +
+ + +
+ + +
+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDOP
+
+ +
+
+
+ + + + + +
+
+ +
+
+
+
+ + + + + + + + + + + diff --git a/work_order.php.7.0 b/work_order.php.7.0 new file mode 100644 index 0000000..4550bcf --- /dev/null +++ b/work_order.php.7.0 @@ -0,0 +1,400 @@ +alert('请先登录');location.href='login.php';"; + exit; +} +$loginUid = $_SESSION['user_id']; +$userName = $_SESSION['username']; + +// 兼容低版本PHP str_contains +if (!function_exists('str_contains')) { + function str_contains(string $haystack, string $needle): bool + { + return empty($needle) || strpos($haystack, $needle) !== false; + } +} + +// 数据库连接 +$dbConfHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbMonitor = "monitor"; +$dbAlert = "alert_mail_stat"; + +// 连接monitor库 +$connWork = mysqli_connect($dbConfHost, $dbUser, $dbPwd, $dbMonitor); +if (!$connWork) { + die("数据库连接失败:" . mysqli_connect_error()); +} +mysqli_set_charset($connWork, "utf8mb4"); + +// 获取用户角色权限(双条件匹配uid/username,解决查不到角色) +$isAdmin = 0; +$permList = ""; +$roleSql = "SELECT r.is_admin, r.perm_list FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ? OR u.username = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +if ($stmtRole) { + mysqli_stmt_bind_param($stmtRole, 'ss', $loginUid, $loginUid); + mysqli_stmt_execute($stmtRole); + $resRole = mysqli_stmt_get_result($stmtRole); + // 容错:判断查询结果是否为有效资源,修复mysqli_fetch_assoc布尔报错根源 + if ($resRole) { + $roleRow = mysqli_fetch_assoc($resRole); + if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; + } + } + mysqli_stmt_close($stmtRole); +} + +// 临时注释权限拦截,放开页面访问,测试完成可取消注释 +/* +$hasWorkPerm = str_contains($permList, "work_order"); +if (!$hasWorkPerm) { + echo ""; + exit; +} +*/ + +// 多语言文字库 +$t = [ + 'page_title' => '工单管理', + 'add_work' => '新建工单', + 'edit' => '编辑', + 'delete' => '删除', + 'save' => '保存', + 'cancel' => '取消', + 'reset' => '重置', + 'perm_deny' => '权限不足,无法访问工单页面', + 'relate_alert' => '关联活跃告警', + 'title' => '工单标题', + 'content' => '工单内容', + 'handler' => '处理人', + 'notify_setting' => '通知渠道配置', + 'notify_mail' => '邮箱通知', + 'notify_dingtalk' => '钉钉通知', + 'notify_wecom' => '企业微信通知', + 'no_alert' => '暂无活跃告警数据', + 'tip_ctrl' => '按住Ctrl多选通知渠道', + 'status_pending' => '待处理', + 'status_process' => '处理中', + 'status_done' => '已完成', + 'status_close' => '已关闭', +]; + +// 分页配置 +$page = isset($_GET['page']) ? intval($_GET['page']) : 1; +$pageSize = 10; +$offset = ($page - 1) * $pageSize; + +// 查询工单列表 +$workSql = "SELECT w.*, u.real_name handler_name FROM work_order w LEFT JOIN sys_user u ON w.handler_id = u.id ORDER BY w.id DESC LIMIT ?,?"; +$stmtWork = mysqli_prepare($connWork, $workSql); +mysqli_stmt_bind_param($stmtWork, 'ii', $offset, $pageSize); +mysqli_stmt_execute($stmtWork); +$resWork = mysqli_stmt_get_result($stmtWork); +$workList = []; +while ($row = mysqli_fetch_assoc($resWork)) { + $workList[] = $row; +} + +// 统计总条数 +$countSql = "SELECT COUNT(*) total FROM work_order"; +$resCount = mysqli_query($connWork, $countSql); +$total = mysqli_fetch_assoc($resCount)['total']; +$totalPage = ceil($total / $pageSize); + +// 查询所有处理人(下拉选择) +$userSql = "SELECT id,real_name FROM sys_user WHERE enable = 1"; +$resUser = mysqli_query($connWork, $userSql); +$userList = []; +while ($u = mysqli_fetch_assoc($resUser)) { + $userList[] = $u; +} + +// 读取活跃告警(修复告警下拉无数据问题,从alert_mail_stat拉取) +$connAlert = mysqli_connect($dbConfHost, $dbUser, $dbPwd, $dbAlert); +$alertList = []; +if ($connAlert) { + mysqli_set_charset($connAlert, "utf8mb4"); + $alertSql = "SELECT id,alert_name FROM alert_info WHERE status = 1 ORDER BY id DESC"; + $resAlert = mysqli_query($connAlert, $alertSql); + while ($a = mysqli_fetch_assoc($resAlert)) { + $alertList[] = $a; + } + mysqli_close($connAlert); +} + +mysqli_close($connWork); +?> + + + + + <?php echo $t['page_title']; ?> + + + +
+
+

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
ID状态创建时间操作
暂无工单数据
+ $t['status_pending'],2=>$t['status_process'],3=>$t['status_done'],4=>$t['status_close']]; + echo $statusMap[$w['status']] ?? '未知'; + ?> + + + +
+ + +
+ 1): ?> + 上一页 + + + + + + 下一页 + +
+
+ + + + + + + + diff --git a/work_order.php.8.0 b/work_order.php.8.0 new file mode 100644 index 0000000..b3ed244 --- /dev/null +++ b/work_order.php.8.0 @@ -0,0 +1,936 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRoleId = $_SESSION['role_id']; + +// 读取全局配置库 alert_mail_stat +$dbConfigHost = "10.150.117.190"; +$dbConfigUser = "root"; +$dbConfigPwd = "hp93000"; +$dbConfigName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbConfigHost, $dbConfigUser, $dbConfigPwd, $dbConfigName); +if(!$connConfig){ + die("配置库连接失败"); +} +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} + +// 读取SMTP配置 +$smtpRow = []; +$smtpQuery = mysqli_query($connConfig, "SELECT * FROM sys_smtp_config WHERE id=1"); +if($smtpQuery){ + $smtpRow = mysqli_fetch_assoc($smtpQuery); +} +$smtpConfig = $smtpRow ?? []; + +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$currentLang = $sysConfig['lang'] ?? "zh"; +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +mysqli_close($connConfig); + +// 多语言词典 +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警总览', + 'disk_capacity' => '磁盘容量', + 'alert_list_page' => '历史告警', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '系统参数', + 'smtp_config' => '邮箱SMTP配置', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新页面', + 'export_csv' => '导出CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'work_order_mgr' => '工单系统', + 'work_create' => '新建工单', + 'work_edit' => '编辑工单', + 'work_assign' => '分发工单', + 'work_status' => '工单状态', + 'work_creator' => '创建人', + 'work_handler' => '处理人', + 'work_content' => '工单内容/备注', + 'work_title' => '工单标题', + 'create_time' => '创建时间', + 'update_time' => '更新时间', + 'all_work_order' => '全部工单列表', + 'no_work_data' => '暂无工单数据', + 'save' => '保存', + 'cancel' => '取消', + 'title_placeholder' => '填写故障/需求标题', + 'content_placeholder' => '详细描述故障现象、操作步骤、处理方案', + 'select_handler' => '选择处理人(留空暂不分配)', + 'status_1' => '待处理', + 'status_2' => '处理中', + 'status_3' => '已完成', + 'status_4' => '已关闭', + 'no_alert_option' => '不关联任何告警', + 'relate_alert' => '关联告警(可选)', + 'relate_alert_id' => '关联告警ID', + 'notify_title' => '通知配置', + 'notify_user' => '通知接收人', + 'notify_channel' => '通知渠道', + 'channel_mail' => '邮箱', + 'channel_ding' => '钉钉', + 'channel_wecom' => '企业微信', + 'smtp_host' => 'SMTP服务器', + 'smtp_port' => '端口', + 'smtp_ssl' => '开启SSL/TLS', + 'smtp_account' => '发件账号', + 'smtp_pwd' => '授权密码', + 'smtp_from' => '发件邮箱', + 'save_smtp' => '保存SMTP配置', + 'alert_loading' => '加载活跃告警...', + 'no_alert_data' => '当前无正在触发的告警', + 'user_loading' => '加载用户列表', + 'no_user_data' => '无可用用户', + 'perm_deny' => '权限不足,禁止访问', + 'total_record' => '共', + 'record_unit' => '条', + 'page_text' => '第', + 'page_split' => '/', + 'prev_page' => '上一页', + 'next_page' => '下一页', + 'first_page' => '首页', + 'last_page' => '末页', + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'disk_capacity' => 'Disk Capacity', + 'alert_list_page' => 'History Alert', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'smtp_config' => 'SMTP Mail Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh', + 'export_csv' => 'Export CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'work_order_mgr' => 'Work Order System', + 'work_create' => 'Create Order', + 'work_edit' => 'Edit Order', + 'work_assign' => 'Assign Order', + 'work_status' => 'Status', + 'work_creator' => 'Creator', + 'work_handler' => 'Handler', + 'work_content' => 'Content / Remark', + 'work_title' => 'Order Title', + 'create_time' => 'Create Time', + 'update_time' => 'Update Time', + 'all_work_order' => 'All Work Orders', + 'no_work_data' => 'No work orders', + 'save' => 'Save', + 'cancel' => 'Cancel', + 'title_placeholder' => 'Fill fault or demand title', + 'content_placeholder' => 'Describe fault, steps and handling plan', + 'select_handler' => 'Select handler (empty for unassigned)', + 'status_1' => 'Pending', + 'status_2' => 'Processing', + 'status_3' => 'Finished', + 'status_4' => 'Closed', + 'no_alert_option' => 'No related alert', + 'relate_alert' => 'Relate Alert (Optional)', + 'relate_alert_id' => 'Relate Alert ID', + 'notify_title' => 'Notification Config', + 'notify_user' => 'Notify Users', + 'notify_channel' => 'Notify Channel', + 'channel_mail' => 'Email', + 'channel_ding' => 'DingTalk', + 'channel_wecom' => 'WeCom', + 'smtp_host' => 'SMTP Host', + 'smtp_port' => 'Port', + 'smtp_ssl' => 'Enable SSL/TLS', + 'smtp_account' => 'SMTP Account', + 'smtp_pwd' => 'Auth Password', + 'smtp_from' => 'Sender Email', + 'save_smtp' => 'Save SMTP Config', + 'alert_loading' => 'Loading active alerts...', + 'no_alert_data' => 'No active firing alerts', + 'user_loading' => 'Loading user list...', + 'no_user_data' => 'No available users', + 'perm_deny' => 'Permission denied', + 'total_record' => 'Total ', + 'record_unit' => 'records', + 'page_text' => 'Page ', + 'page_split' => ' / ', + 'prev_page' => 'Prev', + 'next_page' => 'Next', + 'first_page' => 'First', + 'last_page' => 'Last', + ] +]; +$t = $langMap[$currentLang]; + +// 解析外链菜单 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = ["name" => trim($item[0]), "url" => trim($item[1])]; + } + } +} + +// ========== 工单业务库 monitor ========== +$dbWorkHost = "10.150.117.190"; +$dbWorkUser = "root"; +$dbWorkPwd = "hp93000"; +$dbWorkName = "monitor"; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + die("工单数据库 monitor 连接失败"); +} +mysqli_set_charset($connWork, "utf8mb4"); +$loginUid = $_SESSION['user_id']; + +// 获取当前用户角色权限(双条件匹配uid/username,解决同步用户权限不足) +$isAdmin = 0; +$permList = ""; +$roleSql = "SELECT r.is_admin, r.perm_list FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ? OR u.username = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +if($stmtRole){ + mysqli_stmt_bind_param($stmtRole, 'ss', $loginUid, $loginUid); + mysqli_stmt_execute($stmtRole); + $resRole = mysqli_stmt_get_result($stmtRole); + if ($resRole) { + $roleRow = mysqli_fetch_assoc($resRole); + if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; + } + } + mysqli_stmt_close($stmtRole); +} + +//$hasWorkPerm = str_contains($permList, "work_order"); +//if (!$hasWorkPerm) { +// echo ""; +// exit; +//} + +// 加载全部系统用户(处理人下拉) +$userOptions = ""; +$userAll = mysqli_query($connWork, "SELECT uid, real_name, username FROM sys_user WHERE enable = 1 ORDER BY real_name ASC"); +while ($u = mysqli_fetch_assoc($userAll)) { + $userOptions .= ''; +} + +// 分页配置 +$page = isset($_GET['page']) ? intval($_GET['page']) : 1; +$pageSize = intval($sysConfig['page_size'] ?? 20); +if ($pageSize < 1) $pageSize = 20; +$offset = ($page - 1) * $pageSize; + +// 权限过滤 +if ($isAdmin === 1) { + $whereSql = " 1=1 "; +} else { + $whereSql = " (create_uid = ? OR assign_uid = ?) "; +} + +// 统计总数 +$cntSql = "SELECT COUNT(*) total FROM work_order WHERE " . $whereSql; +$stmtCnt = mysqli_prepare($connWork, $cntSql); +$total = 0; +if($stmtCnt){ + if ($isAdmin !== 1) { + mysqli_stmt_bind_param($stmtCnt, 'ss', $loginUid, $loginUid); + } + mysqli_stmt_execute($stmtCnt); + $cntRes = mysqli_stmt_get_result($stmtCnt); + if ($cntRes) { + $cntRow = mysqli_fetch_assoc($cntRes); + $total = intval($cntRow['total'] ?? 0); + } + mysqli_stmt_close($stmtCnt); +} +$totalPage = $pageSize <= 0 ? 1 : ceil($total / $pageSize); + +// 工单列表查询 +$listSql = "SELECT wo.*, uc.real_name create_name, ua.real_name assign_name +FROM work_order wo +LEFT JOIN sys_user uc ON wo.create_uid = uc.uid +LEFT JOIN sys_user ua ON wo.assign_uid = ua.uid +WHERE " . $whereSql . " ORDER BY create_time DESC LIMIT ?, ?"; +$stmtList = mysqli_prepare($connWork, $listSql); +$orderList = []; +if($stmtList){ + if ($isAdmin === 1) { + mysqli_stmt_bind_param($stmtList, 'ii', $offset, $pageSize); + } else { + mysqli_stmt_bind_param($stmtList, 'ssii', $loginUid, $loginUid, $offset, $pageSize); + } + mysqli_stmt_execute($stmtList); + $listResult = mysqli_stmt_get_result($stmtList); + if ($listResult) { + while ($row = mysqli_fetch_assoc($listResult)) { + $orderList[] = $row; + } + } + mysqli_stmt_close($stmtList); +} +mysqli_close($connWork); +?> + + + + + +<?php echo $pageTitle; ?> - Advantest <?php echo $t['work_order_mgr']; ?> + + + + + + +
+
+
+
+ +
+
+
+
+
Advantest
+
+
+
+
+ + -- +
+ + +
+ + +
+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDOP
+
+ +
+
+
+ + + + + +
+
+ + +
+
+ +
+
+ 1): ?> + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ + + + + + + + + + diff --git a/work_order.php.9.0 b/work_order.php.9.0 new file mode 100644 index 0000000..8d5d69e --- /dev/null +++ b/work_order.php.9.0 @@ -0,0 +1,926 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRoleId = $_SESSION['role_id']; + +// 全局配置库连接 +$dbConfigHost = "10.150.117.190"; +$dbConfigUser = "root"; +$dbConfigPwd = "hp93000"; +$dbConfigName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbConfigHost, $dbConfigUser, $dbConfigPwd, $dbConfigName); +if(!$connConfig){ + die("配置库连接失败"); +} +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} + +// 修复SMTP查询警告 +$smtpRow = []; +$sqlSmtp = "SELECT * FROM sys_smtp_config WHERE id=1"; +if (!empty(trim($sqlSmtp))) { + $smtpQuery = mysqli_query($connConfig, $sqlSmtp); + if ($smtpQuery !== false && $smtpQuery instanceof mysqli_result) { + $smtpRow = mysqli_fetch_assoc($smtpQuery) ?: []; + } +} +$smtpConfig = $smtpRow ?? []; + +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$currentLang = $sysConfig['lang'] ?? "zh"; +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +mysqli_close($connConfig); + +// 多语言词典 +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警总览', + 'disk_capacity' => '磁盘容量', + 'alert_list_page' => '历史告警', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '系统参数', + 'smtp_config' => '邮箱SMTP配置', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新页面', + 'export_csv' => '导出CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'work_order_mgr' => '工单系统', + 'work_create' => '新建工单', + 'work_edit' => '编辑工单', + 'work_assign' => '分发工单', + 'work_status' => '工单状态', + 'work_creator' => '创建人', + 'work_handler' => '处理人', + 'work_content' => '工单内容/备注', + 'work_title' => '工单标题', + 'create_time' => '创建时间', + 'update_time' => '更新时间', + 'all_work_order' => '全部工单列表', + 'no_work_data' => '暂无工单数据', + 'save' => '保存', + 'cancel' => '取消', + 'title_placeholder' => '填写故障/需求标题', + 'content_placeholder' => '详细描述故障现象、操作步骤、处理方案', + 'select_handler' => '选择处理人(留空暂不分配)', + 'status_1' => '待处理', + 'status_2' => '处理中', + 'status_3' => '已完成', + 'status_4' => '已关闭', + 'no_alert_option' => '不关联任何告警', + 'relate_alert' => '关联告警(可选)', + 'relate_alert_id' => '关联告警ID', + 'notify_title' => '通知配置', + 'notify_user' => '通知接收人', + 'notify_channel' => '通知渠道', + 'channel_mail' => '邮箱', + 'channel_ding' => '钉钉', + 'channel_wecom' => '企业微信', + 'smtp_host' => 'SMTP服务器', + 'smtp_port' => '端口', + 'smtp_ssl' => '开启SSL/TLS', + 'smtp_account' => '发件账号', + 'smtp_pwd' => '授权密码', + 'smtp_from' => '发件邮箱', + 'save_smtp' => '保存SMTP配置', + 'alert_loading' => '加载活跃告警...', + 'no_alert_data' => '当前无正在触发的告警', + 'user_loading' => '加载用户列表', + 'no_user_data' => '无可用用户', + 'perm_deny' => '权限不足,禁止访问', + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'disk_capacity' => 'Disk Capacity', + 'alert_list_page' => 'History Alert', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'smtp_config' => 'SMTP Mail Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh', + 'export_csv' => 'Export CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'work_order_mgr' => 'Work Order System', + 'work_create' => 'Create Order', + 'work_edit' => 'Edit Order', + 'work_assign' => 'Assign Order', + 'work_status' => 'Status', + 'work_creator' => 'Creator', + 'work_handler' => 'Handler', + 'work_content' => 'Content / Remark', + 'work_title' => 'Order Title', + 'create_time' => 'Create Time', + 'update_time' => 'Update Time', + 'all_work_order' => 'All Work Orders', + 'no_work_data' => 'No work orders', + 'save' => 'Save', + 'cancel' => 'Cancel', + 'title_placeholder' => 'Fill fault or demand title', + 'content_placeholder' => 'Describe fault, steps and handling plan', + 'select_handler' => 'Select handler (empty for unassigned)', + 'status_1' => 'Pending', + 'status_2' => 'Processing', + 'status_3' => 'Finished', + 'status_4' => 'Closed', + 'no_alert_option' => 'No related alert', + 'relate_alert' => 'Relate Alert (Optional)', + 'relate_alert_id' => 'Relate Alert ID', + 'notify_title' => 'Notification Config', + 'notify_user' => 'Notify Users', + 'notify_channel' => 'Notify Channel', + 'channel_mail' => 'Email', + 'channel_ding' => 'DingTalk', + 'channel_wecom' => 'WeCom', + 'smtp_host' => 'SMTP Host', + 'smtp_port' => 'Port', + 'smtp_ssl' => 'Enable SSL/TLS', + 'smtp_account' => 'SMTP Account', + 'smtp_pwd' => 'Auth Password', + 'smtp_from' => 'Sender Email', + 'save_smtp' => 'Save SMTP Config', + 'alert_loading' => 'Loading active alerts...', + 'no_alert_data' => 'No active firing alerts', + 'user_loading' => 'Loading user list...', + 'no_user_data' => 'No available users', + 'perm_deny' => 'Permission denied', + ] +]; +$t = $langMap[$currentLang]; + +// 解析外链菜单 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = ["name" => trim($item[0]), "url" => trim($item[1])]; + } + } +} + +// 工单业务库 monitor +$dbWorkHost = "10.150.117.190"; +$dbWorkUser = "root"; +$dbWorkPwd = "hp93000"; +$dbWorkName = "monitor"; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + die("工单数据库 monitor 连接失败"); +} +mysqli_set_charset($connWork, "utf8mb4"); +$loginUid = $_SESSION['user_id']; + +// 获取用户角色权限 +$isAdmin = 0; +$permList = ""; +$roleSql = "SELECT r.is_admin, r.perm_list FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +if($stmtRole){ + mysqli_stmt_bind_param($stmtRole, 's', $loginUid); + mysqli_stmt_execute($stmtRole); + $roleRes = mysqli_stmt_get_result($stmtRole); + if ($roleRes instanceof mysqli_result) { + $roleRow = mysqli_fetch_assoc($roleRes); + if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; + } + } +} + +// 权限校验临时注释,如需开启取消注释 +//$hasWorkPerm = str_contains($permList, "work_order"); +//if (!$hasWorkPerm) { +// echo ""; +// exit; +//} + +// 加载全部系统用户下拉 +$userOptions = ""; +$userAll = mysqli_query($connWork, "SELECT uid, real_name, username FROM sys_user WHERE enable = 1 ORDER BY real_name ASC"); +if ($userAll instanceof mysqli_result) { + while ($u = mysqli_fetch_assoc($userAll)) { + $userOptions .= ''; + } +} + +// 分页参数 +$page = isset($_GET['page']) ? intval($_GET['page']) : 1; +$pageSize = intval($sysConfig['page_size'] ?? 20); +if ($pageSize < 1) $pageSize = 20; +$offset = ($page - 1) * $pageSize; + +// 数据权限过滤 +if ($isAdmin === 1) { + $whereSql = " 1=1 "; +} else { + $whereSql = " (create_uid = ? OR assign_uid = ?) "; +} + +// 统计工单总数 +$cntSql = "SELECT COUNT(*) total FROM work_order WHERE " . $whereSql; +$stmtCnt = mysqli_prepare($connWork, $cntSql); +$total = 0; +if($stmtCnt){ + if ($isAdmin !== 1) { + mysqli_stmt_bind_param($stmtCnt, 'ss', $loginUid, $loginUid); + } + mysqli_stmt_execute($stmtCnt); + $cntRes = mysqli_stmt_get_result($stmtCnt); + if ($cntRes instanceof mysqli_result) { + $cntRow = mysqli_fetch_assoc($cntRes); + $total = intval($cntRow['total'] ?? 0); + } +} +$totalPage = $pageSize <= 0 ? 1 : ceil($total / $pageSize); + +// 查询工单列表 +$listSql = "SELECT wo.*, uc.real_name create_name, ua.real_name assign_name +FROM work_order wo +LEFT JOIN sys_user uc ON wo.create_uid = uc.uid +LEFT JOIN sys_user ua ON wo.assign_uid = ua.uid +WHERE " . $whereSql . " ORDER BY create_time DESC LIMIT ?, ?"; +$stmtList = mysqli_prepare($connWork, $listSql); +$orderList = []; +if($stmtList){ + if ($isAdmin === 1) { + mysqli_stmt_bind_param($stmtList, 'ii', $offset, $pageSize); + } else { + mysqli_stmt_bind_param($stmtList, 'ssii', $loginUid, $loginUid, $offset, $pageSize); + } + mysqli_stmt_execute($stmtList); + $listResult = mysqli_stmt_get_result($stmtList); + if ($listResult instanceof mysqli_result) { + while ($row = mysqli_fetch_assoc($listResult)) { + $orderList[] = $row; + } + } +} +mysqli_close($connWork); +?> + + + + + +<?php echo $pageTitle; ?> - Advantest <?php echo $t['work_order_mgr']; ?> + + + + + + +
+
+
+
+ +
+
+
+
+
Advantest
+
+
+
+
+ + -- +
+ + +
+ + +
+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDOP
+
+ +
+
+
+ + + + + +
+
+ + +
+
+
+
+ + + + + + + + + + diff --git a/work_order.php.bak b/work_order.php.bak new file mode 100644 index 0000000..a8b0e05 --- /dev/null +++ b/work_order.php.bak @@ -0,0 +1,387 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$loginUid = $_SESSION['user_id']; +$userName = $_SESSION['user_name'] ?? ''; + +$dbHost = '10.150.117.190'; +$dbUser = 'root'; +$dbPwd = 'hp93000'; +$dbName = 'monitor'; +$dbPort = 3306; + +$conn = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName, $dbPort); +if (!$conn) { + die("数据库连接失败:" . mysqli_connect_error() . " 错误码:" . mysqli_connect_errno()); +} +mysqli_set_charset($conn, 'utf8mb4'); + +// 获取当前登录用户角色(是否管理员) +$isAdmin = 0; +$roleSql = "SELECT r.is_admin FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($conn, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtRole)); +if ($roleRow) $isAdmin = intval($roleRow['is_admin']); + +// 获取所有用户(分发下拉框) +$userOptions = ""; +$userRes = mysqli_query($conn, "SELECT uid, real_name, username FROM sys_user WHERE enable = 1"); +while ($u = mysqli_fetch_assoc($userRes)) { + $userOptions .= ''; +} + +// 分页参数 +$page = isset($_GET['page']) ? intval($_GET['page']) : 1; +$pageSize = 15; +$offset = ($page - 1) * $pageSize; + +// 权限过滤SQL +if ($isAdmin === 1) { + $whereSql = " 1=1 "; +} else { + $whereSql = " (create_uid = ? OR assign_uid = ?) "; +} + +// 统计总数 +$cntSql = "SELECT COUNT(*) total FROM work_order WHERE " . $whereSql; +$stmtCnt = mysqli_prepare($conn, $cntSql); +if ($isAdmin !== 1) { + mysqli_stmt_bind_param($stmtCnt, 'ss', $loginUid, $loginUid); +} +mysqli_stmt_execute($stmtCnt); +$cntRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtCnt)); +$total = intval($cntRow['total']); +$totalPage = ceil($total / $pageSize); + +// 工单列表数据 +$listSql = "SELECT wo.*, uc.real_name create_name, ua.real_name assign_name +FROM work_order wo +LEFT JOIN sys_user uc ON wo.create_uid = uc.uid +LEFT JOIN sys_user ua ON wo.assign_uid = ua.uid +WHERE " . $whereSql . " ORDER BY create_time DESC LIMIT ?, ?"; +$stmtList = mysqli_prepare($conn, $listSql); +if ($isAdmin === 1) { + mysqli_stmt_bind_param($stmtList, 'ii', $offset, $pageSize); +} else { + mysqli_stmt_bind_param($stmtList, 'ssii', $loginUid, $loginUid, $offset, $pageSize); +} +mysqli_stmt_execute($stmtList); +$listResult = mysqli_stmt_get_result($stmtList); +$orderList = []; +while ($row = mysqli_fetch_assoc($listResult)) { + $orderList[] = $row; +} +mysqli_close($conn); +?> + + + + + +工单管理 + + + + + + + + + +
+
+

工单管理

+
+ + +
+
+ + +
+
+
工单列表
+ +
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ID工单标题创建人处理人状态创建时间更新时间操作
暂无工单数据
+ + + + + +
+
+ + +
+
+ + + + diff --git a/优化版.php b/优化版.php new file mode 100644 index 0000000..9110dc8 --- /dev/null +++ b/优化版.php @@ -0,0 +1,1114 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); + +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +// ========== 缓存模块:屏蔽权限警告,无写入权限自动降级 ========== +$cacheDir = __DIR__ . '/cache'; +$cacheExpireSec = 300; +$sysConfig = []; + +// 静默创建缓存目录,抑制权限报错 +if (!is_dir($cacheDir)) { + @mkdir($cacheDir, 0755, true); +} +$configCacheFile = $cacheDir . '/sys_config.cache'; + +// 读取缓存,可读且未过期则使用缓存 +if (file_exists($configCacheFile) && is_readable($configCacheFile) && (time() - filemtime($configCacheFile)) < $cacheExpireSec) { + $cacheRaw = @file_get_contents($configCacheFile); + $sysConfig = json_decode($cacheRaw, true) ?: []; +} else { + // 缓存失效/无权限,直接查询数据库 + $dbHost = "10.150.117.190"; + $dbUser = "root"; + $dbPwd = "hp93000"; + $dbName = "alert_mail_stat"; + $connConfig = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); + + if ($connConfig) { + mysqli_set_charset($connConfig, "utf8mb4"); + $configSql = "SELECT k,v FROM sys_config"; + $configRes = mysqli_query($connConfig, $configSql); + + while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = trim($row['v'] ?? ''); + } + mysqli_close($connConfig); + + // 无写入权限静默跳过,不抛出警告 + @file_put_contents($configCacheFile, json_encode($sysConfig, JSON_UNESCAPED_UNICODE)); + } +} + +// ========== 修复标题叠加Bug:纯覆盖赋值,无拼接污染 ========== +$rawPageTitle = trim($sysConfig['page_title'] ?? ''); +$pageTitle = $rawPageTitle === '' ? "告警监控系统" : $rawPageTitle; +$pageTitle = htmlspecialchars($pageTitle); + +$themeColor = htmlspecialchars(trim($sysConfig['theme_color'] ?? "#409eff")); +$pageSize = trim($sysConfig['page_size'] ?? "20"); +$footerText = htmlspecialchars(trim($sysConfig['footer_text'] ?? "")); +$sidebarRawLinks = trim($sysConfig['sidebar_links'] ?? ""); + +// 解析侧边外链,过滤空行空白 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2 && trim($item[0]) !== '' && trim($item[1]) !== '') { + $sidebarLinkList[] = [ + "name" => trim($item[0]), + "url" => trim($item[1]) + ]; + } + } +} +?> + + + + + + <?php echo $pageTitle; ?> - Advantest 爱德万测试 - 运维告警监控平台 + + + + + + + + + + +
+
+ + 正在生成CSV报表,请稍候... +
+
+ +
+ + + + +
+
+
+
+
Advantest
+
爱德万测试 · 运维告警监控平台
+
+
+
+ + + + 系统时间:-- + + +
+ + +
+ +
+
+ +
+ +
+
+
+
+
今日触发告警
+
+
+
0
+
Total Firing Today
+
+
+
+
当前未恢复告警
+
+
+
0
+
Unresolved Now
+
+
+
+
今日恢复告警
+
+
+
0
+
Resolved Today
+
+
+
+
故障实例总数
+
+
+
0
+
Affected Host Instance
+
+
+
+
告警恢复率
+
+
+
0%
+
Daily Recovery Rate
+
+
+ +
+
+
+
今日告警频次 TOP 10
+
+
+
+
+ +
+
+
+
当前未恢复活跃告警
+
0 条未恢复故障
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
当前无未恢复告警,系统运行正常
+
+
+
+
+
+ +
+
+
+
今日全量告警明细列表
+
0 条告警记录
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
暂无今日告警数据
+
+
+
+
+
+
+ + +
+
+
+
+
用户目录磁盘占用统计
+
+ + + +
+
+
+ + + + + + + + + + + + + + +
实例IP用户名目录路径占用容量
+
+
磁盘数据加载中...
+
+
+
+
+
+
+ + + +
+
+ + + + diff --git a/完成版.php b/完成版.php new file mode 100644 index 0000000..9b1cfb8 --- /dev/null +++ b/完成版.php @@ -0,0 +1,954 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +// 刷新登录计时 +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +// 读取全局系统配置(admin后台保存后同步生效) +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($connConfig, "utf8mb4"); +$configSql = "SELECT k,v FROM sys_config"; +$configRes = mysqli_query($connConfig, $configSql); +$sysConfig = []; +while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; +} +mysqli_close($connConfig); + +// 赋值全局配置 +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$themeColor = htmlspecialchars($sysConfig['theme_color'] ?? "#409eff"); +$pageSize = $sysConfig['page_size'] ?? "20"; +$footerText = htmlspecialchars($sysConfig['footer_text'] ?? ""); +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +// 解析侧边外链列表 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2) { + $sidebarLinkList[] = [ + "name" => trim($item[0]), + "url" => trim($item[1]) + ]; + } + } +} +?> + + + + + +<?php echo $pageTitle; ?> - Advantest 爱德万测试 - 运维告警监控平台 + + + + + + + + + +
+
+ + 正在生成CSV报表,请稍候... +
+
+ +
+ + + + +
+
+
+
+
Advantest
+
爱德万测试 · 运维告警监控平台
+
+
+
+ + 系统时间:-- + +
+ + +
+ +
+
+ +
+ +
+ +
+
+
+
今日触发告警
+
+
+
0
+
Total Firing Today
+
+
+
+
当前未恢复告警
+
+
+
0
+
Unresolved Now
+
+
+
+
今日恢复告警
+
+
+
0
+
Resolved Today
+
+
+
+
故障实例总数
+
+
+
0
+
Affected Host Instance
+
+
+
+
告警恢复率
+
+
+
0%
+
Daily Recovery Rate
+
+
+ + +
+
+
+
今日告警频次 TOP 10
+
+
+
+
+ + +
+
+
+
当前未恢复活跃告警
+
0 条未恢复故障
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
当前无未恢复告警,系统运行正常
+
+
+
+
+
+ + +
+
+
+
今日全量告警明细列表
+
0 条告警记录
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
暂无今日告警数据
+
+
+
+
+
+
+ + +
+
+
+
+
用户目录磁盘占用统计
+
+ + + +
+
+
+ + + + + + + + + + + + + + +
实例IP用户名目录路径占用容量
+
+
磁盘数据加载中...
+
+
+
+
+
+
+
+
+ + + + diff --git a/速度优化版.php b/速度优化版.php new file mode 100644 index 0000000..98ded98 --- /dev/null +++ b/速度优化版.php @@ -0,0 +1,991 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +// 刷新登录计时 +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +// ========== 数据库查询缓存优化(大幅提速,无痕窗口也生效) ========== +$cacheDir = __DIR__ . '/cache'; +if (!is_dir($cacheDir)) mkdir($cacheDir, 0755, true); +$configCacheFile = $cacheDir . '/sys_config.cache'; +$cacheExpireSec = 300; // 5分钟缓存,减少数据库查询 +$sysConfig = []; + +// 读取缓存,无缓存/过期则重查数据库 +if (file_exists($configCacheFile) && (time() - filemtime($configCacheFile)) < $cacheExpireSec) { + $cacheRaw = file_get_contents($configCacheFile); + $sysConfig = json_decode($cacheRaw, true) ?: []; +} else { + $dbHost = "10.150.117.190"; + $dbUser = "root"; + $dbPwd = "hp93000"; + $dbName = "alert_mail_stat"; + $connConfig = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); + if ($connConfig) { + mysqli_set_charset($connConfig, "utf8mb4"); + $configSql = "SELECT k,v FROM sys_config"; + $configRes = mysqli_query($connConfig, $configSql); + while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = trim($row['v'] ?? ''); + } + mysqli_close($connConfig); + // 写入缓存 + file_put_contents($configCacheFile, json_encode($sysConfig, JSON_UNESCAPED_UNICODE)); + } +} + +// ========== 修复标题叠加Bug:独立赋值,彻底覆盖旧值,不拼接 ========== +// 强制清空旧内容,纯独立赋值,不存在新旧文字叠加 +$rawPageTitle = trim($sysConfig['page_title'] ?? ''); +$pageTitle = $rawPageTitle === '' ? "告警监控系统" : $rawPageTitle; +$pageTitle = htmlspecialchars($pageTitle); + +$themeColor = htmlspecialchars(trim($sysConfig['theme_color'] ?? "#409eff")); +$pageSize = trim($sysConfig['page_size'] ?? "20"); +$footerText = htmlspecialchars(trim($sysConfig['footer_text'] ?? "")); +$sidebarRawLinks = trim($sysConfig['sidebar_links'] ?? ""); + +// 解析侧边外链列表,彻底过滤空行、空白 +$sidebarLinkList = []; +if (!empty($sidebarRawLinks)) { + $lines = explode("\n", $sidebarRawLinks); + foreach ($lines as $line) { + $line = trim($line); + if (empty($line)) continue; + $item = explode("|", $line, 2); + if (count($item) === 2 && trim($item[0]) !== '' && trim($item[1]) !== '') { + $sidebarLinkList[] = [ + "name" => trim($item[0]), + "url" => trim($item[1]) + ]; + } + } +} +?> + + + + + + +<?php echo $pageTitle; ?> - Advantest 爱德万测试 - 运维告警监控平台 + + + + + + + + + + + +
+
+ + 正在生成CSV报表,请稍候... +
+
+ +
+ + + + +
+
+
+
+
Advantest
+
爱德万测试 · 运维告警监控平台
+
+
+
+ + 系统时间:-- + +
+ + +
+ +
+
+ +
+ +
+
+
+
+
今日触发告警
+
+
+
0
+
Total Firing Today
+
+
+
+
当前未恢复告警
+
+
+
0
+
Unresolved Now
+
+
+
+
今日恢复告警
+
+
+
0
+
Resolved Today
+
+
+
+
故障实例总数
+
+
+
0
+
Affected Host Instance
+
+
+
+
告警恢复率
+
+
+
0%
+
Daily Recovery Rate
+
+
+ +
+
+
+
今日告警频次 TOP 10
+
+
+
+
+ +
+
+
+
当前未恢复活跃告警
+
0 条未恢复故障
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
当前无未恢复告警,系统运行正常
+
+
+
+
+
+ +
+
+
+
今日全量告警明细列表
+
0 条告警记录
+
+
+ + + + + + + + + + + + + + + +
告警状态告警名称实例地址告警级别故障发生时间
+
+
+
暂无今日告警数据
+
+
+
+
+
+
+ +
+
+
+
+
用户目录磁盘占用统计
+
+ + + +
+
+
+ + + + + + + + + + + + + + +
实例IP用户名目录路径占用容量
+
+
磁盘数据加载中...
+
+
+
+
+
+
+
+
+ + + +