captcha-web-sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +127 -0
- package/dist/index.html +9 -0
- package/dist/tac/css/tac.css +7 -0
- package/dist/tac/images/dun.jpeg +0 -0
- package/dist/tac/images/icon.png +0 -0
- package/dist/tac/js/tac.min.js +1 -0
- package/examples/frameworks.md +202 -0
- package/index.d.ts +109 -0
- package/package.json +70 -0
- package/readme.md +462 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
木兰宽松许可证, 第2版
|
|
2
|
+
|
|
3
|
+
木兰宽松许可证, 第2版
|
|
4
|
+
2020年1月 http://license.coscl.org.cn/MulanPSL2
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第2版(“本许可证”)的如下条款的约束:
|
|
8
|
+
|
|
9
|
+
0. 定义
|
|
10
|
+
|
|
11
|
+
“软件”是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。
|
|
12
|
+
|
|
13
|
+
“贡献”是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。
|
|
14
|
+
|
|
15
|
+
“贡献者”是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。
|
|
16
|
+
|
|
17
|
+
“法人实体”是指提交贡献的机构及其“关联实体”。
|
|
18
|
+
|
|
19
|
+
“关联实体”是指,对“本许可证”下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。
|
|
20
|
+
|
|
21
|
+
1. 授予版权许可
|
|
22
|
+
|
|
23
|
+
每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。
|
|
24
|
+
|
|
25
|
+
2. 授予专利许可
|
|
26
|
+
|
|
27
|
+
每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。
|
|
28
|
+
|
|
29
|
+
3. 无商标许可
|
|
30
|
+
|
|
31
|
+
“本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。
|
|
32
|
+
|
|
33
|
+
4. 分发限制
|
|
34
|
+
|
|
35
|
+
您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。
|
|
36
|
+
|
|
37
|
+
5. 免责声明与责任限制
|
|
38
|
+
|
|
39
|
+
“软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。
|
|
40
|
+
|
|
41
|
+
6. 语言
|
|
42
|
+
“本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文版为准。
|
|
43
|
+
|
|
44
|
+
条款结束
|
|
45
|
+
|
|
46
|
+
如何将木兰宽松许可证,第2版,应用到您的软件
|
|
47
|
+
|
|
48
|
+
如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步:
|
|
49
|
+
|
|
50
|
+
1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字;
|
|
51
|
+
|
|
52
|
+
2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中;
|
|
53
|
+
|
|
54
|
+
3, 请将如下声明文本放入每个源文件的头部注释中。
|
|
55
|
+
|
|
56
|
+
Copyright (c) [Year] [name of copyright holder]
|
|
57
|
+
[Software Name] is licensed under Mulan PSL v2.
|
|
58
|
+
You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
59
|
+
You may obtain a copy of Mulan PSL v2 at:
|
|
60
|
+
http://license.coscl.org.cn/MulanPSL2
|
|
61
|
+
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
62
|
+
See the Mulan PSL v2 for more details.
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
Mulan Permissive Software License,Version 2
|
|
66
|
+
|
|
67
|
+
Mulan Permissive Software License,Version 2 (Mulan PSL v2)
|
|
68
|
+
January 2020 http://license.coscl.org.cn/MulanPSL2
|
|
69
|
+
|
|
70
|
+
Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v2 (this License) with the following terms and conditions:
|
|
71
|
+
|
|
72
|
+
0. Definition
|
|
73
|
+
|
|
74
|
+
Software means the program and related documents which are licensed under this License and comprise all Contribution(s).
|
|
75
|
+
|
|
76
|
+
Contribution means the copyrightable work licensed by a particular Contributor under this License.
|
|
77
|
+
|
|
78
|
+
Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License.
|
|
79
|
+
|
|
80
|
+
Legal Entity means the entity making a Contribution and all its Affiliates.
|
|
81
|
+
|
|
82
|
+
Affiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, ‘control’ means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity.
|
|
83
|
+
|
|
84
|
+
1. Grant of Copyright License
|
|
85
|
+
|
|
86
|
+
Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not.
|
|
87
|
+
|
|
88
|
+
2. Grant of Patent License
|
|
89
|
+
|
|
90
|
+
Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed. The patent license shall not apply to any modification of the Contribution, and any other combination which includes the Contribution. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken.
|
|
91
|
+
|
|
92
|
+
3. No Trademark License
|
|
93
|
+
|
|
94
|
+
No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in Section 4.
|
|
95
|
+
|
|
96
|
+
4. Distribution Restriction
|
|
97
|
+
|
|
98
|
+
You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software.
|
|
99
|
+
|
|
100
|
+
5. Disclaimer of Warranty and Limitation of Liability
|
|
101
|
+
|
|
102
|
+
THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO MATTER HOW IT’S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
|
103
|
+
|
|
104
|
+
6. Language
|
|
105
|
+
|
|
106
|
+
THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL.
|
|
107
|
+
|
|
108
|
+
END OF THE TERMS AND CONDITIONS
|
|
109
|
+
|
|
110
|
+
How to Apply the Mulan Permissive Software License,Version 2 (Mulan PSL v2) to Your Software
|
|
111
|
+
|
|
112
|
+
To apply the Mulan PSL v2 to your work, for easy identification by recipients, you are suggested to complete following three steps:
|
|
113
|
+
|
|
114
|
+
i Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner;
|
|
115
|
+
|
|
116
|
+
ii Create a file named “LICENSE” which contains the whole context of this License in the first directory of your software package;
|
|
117
|
+
|
|
118
|
+
iii Attach the statement to the appropriate annotated syntax at the beginning of each source file.
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
Copyright (c) [Year] [name of copyright holder]
|
|
122
|
+
[Software Name] is licensed under Mulan PSL v2.
|
|
123
|
+
You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
124
|
+
You may obtain a copy of Mulan PSL v2 at:
|
|
125
|
+
http://license.coscl.org.cn/MulanPSL2
|
|
126
|
+
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
127
|
+
See the Mulan PSL v2 for more details.
|
package/dist/index.html
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<!doctype html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Document</title><script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script><script defer="defer" src="tac/js/tac.min.js"></script><link href="tac/css/tac.css" rel="stylesheet"></head><body><div id="captcha-box"></div><script>$(function () {
|
|
2
|
+
// 样式配置
|
|
3
|
+
const config = {
|
|
4
|
+
requestCaptchaDataUrl: "http://localhost:8080/gen",
|
|
5
|
+
validCaptchaUrl: "http://localhost:8080/check",
|
|
6
|
+
bindEl: "#captcha-box"
|
|
7
|
+
}
|
|
8
|
+
new TAC(config).init();
|
|
9
|
+
});</script></body></html>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
#captcha-web-sdk-parent{box-shadow:0 0 11px 0 #999;width:318px;height:318px;overflow:hidden;position:relative;z-index:997;box-sizing:border-box;border-radius:5px;padding:8px}#captcha-web-sdk-parent #captcha-web-sdk-box{height:260px;width:100%;position:relative;overflow:hidden}#captcha-web-sdk-parent #captcha-web-sdk-box .loading{width:120px;height:20px;-webkit-mask:linear-gradient(90deg, #000 70%, rgba(0, 0, 0, 0) 0) 0/20%;background:linear-gradient(#f7b645 0 0) 0/0% no-repeat rgba(221,221,221,.4196078431);animation:cartoon 1s infinite steps(6);margin:120px auto}@keyframes cartoon{100%{background-size:120%}}#captcha-web-sdk-parent #captcha-web-sdk-box #captcha-web-sdk{transform-style:preserve-3d;will-change:transform;transition-duration:.45s;transform:translateX(-300px)}#captcha-web-sdk-parent #captcha-web-sdk-bg-img{background-color:#fff;background-position:top;background-size:cover;z-index:-1;width:100%;height:100%;top:0;left:0;position:absolute;border-radius:6px}#captcha-web-sdk-parent .slider-bottom{height:19px;width:100%}#captcha-web-sdk-parent .slider-bottom .close-btn{width:20px;height:20px;background-image:url(../../tac/images/icon.png);background-repeat:no-repeat;background-position:0 -14px;float:right;margin-right:2px;cursor:pointer}#captcha-web-sdk-parent .slider-bottom .refresh-btn{width:20px;height:20px;background-image:url(../../tac/images/icon.png);background-position:0 -167px;background-repeat:no-repeat;float:right;margin-right:10px;cursor:pointer}#captcha-web-sdk-parent .slider-bottom .logo{height:30px;float:left}#captcha-web-sdk-parent .slider-move-shadow{animation:myanimation 2s infinite;height:100%;width:5px;background-color:#fff;position:absolute;top:0;left:0;filter:opacity(0.5);box-shadow:1px 1px 1px #fff;border-radius:50%}#captcha-web-sdk-parent #captcha-web-sdk-slider-move-track-mask{border-width:1px;border-style:solid;border-color:#00f4ab;width:0;height:32px;background-color:#a9ffe5;opacity:.5;position:absolute;top:-1px;left:-1px;border-radius:5px}
|
|
2
|
+
#captcha-web-sdk{text-align:left;box-sizing:content-box;width:300px;height:260px;z-index:999}#captcha-web-sdk .slider-bottom .logo{height:30px}#captcha-web-sdk .slider-bottom{height:19px;width:100%}#captcha-web-sdk .content .captcha-web-sdk-tips{height:25px;width:100%;position:absolute;bottom:-25px;left:0;z-index:999;font-size:15px;line-height:25px;color:#fff;text-align:center;transition:bottom .3s ease-in-out}#captcha-web-sdk .content .captcha-web-sdk-tips.captcha-web-sdk-tips-error{background-color:#ff5d39}#captcha-web-sdk .content .captcha-web-sdk-tips.captcha-web-sdk-tips-success{background-color:#39c522}#captcha-web-sdk .content .captcha-web-sdk-tips.captcha-web-sdk-tips-on{bottom:0}#captcha-web-sdk .content #captcha-web-sdk-loading{z-index:9999;background-color:#f5f5f5;text-align:center;height:100%;overflow:hidden;position:relative;display:flex;justify-content:center;align-items:center}#captcha-web-sdk .content #captcha-web-sdk-loading img{display:block;width:45px;height:45px}#captcha-web-sdk #captcha-web-sdk-slider-bg-canvas{position:absolute;left:0;top:0;width:100%;height:100%;border-radius:5px}#captcha-web-sdk #captcha-web-sdk-slider-bg-div{position:absolute;left:0;top:0;width:100%;height:100%;border-radius:5px}#captcha-web-sdk #captcha-web-sdk-slider-bg-div .captcha-web-sdk-slider-bg-div-slice{position:absolute}@keyframes myanimation{from{left:0}to{left:289px}}
|
|
3
|
+
#captcha-web-sdk.captcha-web-sdk-slider{z-index:999;position:absolute;left:0;top:0;user-select:none}#captcha-web-sdk.captcha-web-sdk-slider .content{width:100%;height:180px;position:relative;overflow:hidden}#captcha-web-sdk.captcha-web-sdk-slider .bg-img-div{width:100%;height:100%;position:absolute;transform:translate(0px, 0px)}#captcha-web-sdk.captcha-web-sdk-slider .bg-img-div img{height:100%;width:100%;border-radius:5px}#captcha-web-sdk.captcha-web-sdk-slider .slider-img-div{height:100%;position:absolute;left:0;transform:translate(0px, 0px)}#captcha-web-sdk.captcha-web-sdk-slider .slider-img-div #captcha-web-sdk-slider-move-img{height:100%}#captcha-web-sdk.captcha-web-sdk-slider .slider-move{height:34px;width:100%;margin:11px 0;position:relative}#captcha-web-sdk.captcha-web-sdk-slider .slider-move-track{position:relative;height:32px;line-height:32px;text-align:center;background:#f5f5f5;color:#999;transition:0s;font-size:14px;box-sizing:content-box;border:1px solid #f5f5f5;border-radius:4px}#captcha-web-sdk.captcha-web-sdk-slider .refresh-btn,#captcha-web-sdk.captcha-web-sdk-slider .close-btn{display:inline-block}#captcha-web-sdk.captcha-web-sdk-slider .slider-move{line-height:38px;font-size:14px;text-align:center;white-space:nowrap;color:#88949d;-moz-user-select:none;-webkit-user-select:none;user-select:none;filter:opacity(0.8)}#captcha-web-sdk.captcha-web-sdk-slider .slider-move .slider-move-btn{transform:translate(0px, 0px);position:absolute;top:-6px;left:0;width:63px;height:45px;background-color:#fff;background-repeat:no-repeat;background-size:contain;border-radius:5px}#captcha-web-sdk.captcha-web-sdk-slider .slider-tip{margin-bottom:5px;font-weight:bold;font-size:15px;line-height:normal;color:#000}#captcha-web-sdk.captcha-web-sdk-slider .slider-move-btn:hover{cursor:pointer}
|
|
4
|
+
#captcha-web-sdk.captcha-web-sdk-rotate .rotate-img-div{height:100%;text-align:center}#captcha-web-sdk.captcha-web-sdk-rotate .rotate-img-div img{height:100%;transform:rotate(0deg);display:inline-block}
|
|
5
|
+
#captcha-web-sdk.captcha-web-sdk-concat .captcha-web-sdk-slider-concat-img-div{background-size:100% 180px;position:absolute;transform:translate(0px, 0px);z-index:1;width:100%}#captcha-web-sdk.captcha-web-sdk-concat .captcha-web-sdk-slider-concat-bg-img{width:100%;height:100%;position:absolute;transform:translate(0px, 0px);background-size:100% 180px}
|
|
6
|
+
#captcha-web-sdk.captcha-web-sdk-word-click{box-sizing:border-box}#captcha-web-sdk.captcha-web-sdk-word-click .click-tip{position:relative;height:40px;width:100%}#captcha-web-sdk.captcha-web-sdk-word-click .click-tip .tip-img{height:35px;position:absolute;right:15px}#captcha-web-sdk.captcha-web-sdk-word-click .click-tip #captcha-web-sdk-click-track-font{font-size:18px;display:inline-block;height:40px;line-height:40px;position:absolute}#captcha-web-sdk.captcha-web-sdk-word-click .slider-bottom{position:relative;top:6px}#captcha-web-sdk.captcha-web-sdk-word-click .content #bg-img-click-mask{width:100%;height:100%;position:absolute;left:0;top:0}#captcha-web-sdk.captcha-web-sdk-word-click .content #bg-img-click-mask .click-span{position:absolute;left:0;top:0;border-radius:50px;background-color:#409eff;width:20px;height:20px;text-align:center;line-height:20px;color:#fff;border:2px solid #fff;box-sizing:content-box}#captcha-web-sdk.captcha-web-sdk-word-click .click-confirm-btn{width:100%;height:35px;border-radius:4px;background-image:linear-gradient(173deg, hsl(38.09, 91%, 57.89%) 0%, hsl(38.09, 89.38%, 71.74%) 100%);font-size:15px;text-align:center;box-sizing:border-box;line-height:35px;color:#fff;margin-top:3px}#captcha-web-sdk.captcha-web-sdk-word-click .click-confirm-btn:hover{cursor:pointer}
|
|
7
|
+
#captcha-web-sdk.captcha-web-sdk-disable{z-index:999;position:absolute;left:0;top:0}#captcha-web-sdk.captcha-web-sdk-disable .content{width:100%;height:180px;position:relative;overflow:hidden}#captcha-web-sdk.captcha-web-sdk-disable .content .bg-img-div{background-image:url(../../tac/images/dun.jpeg);width:100%;height:100%;overflow:hidden}#captcha-web-sdk.captcha-web-sdk-disable .content .bg-img-div #content-span{color:#fff;overflow:hidden;margin-top:132px;display:block;text-align:center}
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("CaptchaWebSdk",[],e):"object"==typeof exports?exports.CaptchaWebSdk=e():t.CaptchaWebSdk=e()}(this,(function(){return function(){"use strict";var t={d:function(e,n){for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},o:function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r:function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};function n(t){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},n(t)}function r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){for(var r=0;r<e.length;r++){var i=e[r];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,(a=i.key,o=void 0,o=function(t,e){if("object"!==n(t)||null===t)return t;var r=t[Symbol.toPrimitive];if(void 0!==r){var i=r.call(t,e||"default");if("object"!==n(i))return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(a,"string"),"symbol"===n(o)?o:String(o)),i)}var a,o}function a(t,e,n){return e&&i(t.prototype,e),n&&i(t,n),Object.defineProperty(t,"prototype",{writable:!1}),t}t.r(e),t.d(e,{CaptchaConfig:function(){return vt},CaptchaWebSdk:function(){return mt},default:function(){return gt}});function o(t){t.preventDefault&&t.preventDefault()}function c(t){y(t).each((function(t){t.addEventListener("touchmove",o,{passive:!1}),t.addEventListener("mousemove",o,{passive:!1})}))}function s(t){return null!==t.pageX&&void 0!==t.pageX?{x:Math.round(t.pageX),y:Math.round(t.pageY)}:(t.changedTouches?e=t.changedTouches:t.targetTouches?e=t.targetTouches:t.originalEvent&&t.originalEvent.targetTouches&&(e=t.originalEvent.targetTouches),null!==e[0].pageX&&void 0!==e[0].pageX?{x:Math.round(e[0].pageX),y:Math.round(e[0].pageY)}:{x:Math.round(e[0].clientX),y:Math.round(e[0].clientY)});var e}function u(t,e){var n=s(e),r=n.x,i=n.y;t.currentCaptchaData.startX=r,t.currentCaptchaData.startY=i;var a=t.currentCaptchaData.trackList;t.currentCaptchaData.startTime=new Date;var o=t.currentCaptchaData.startTime;a.push({x:n.x,y:n.y,type:"down",t:(new Date).getTime()-o.getTime()}),t.__m__=l.bind(null,t),t.__u__=f.bind(null,t),window.addEventListener("mousemove",t.__m__),window.addEventListener("mouseup",t.__u__),window.addEventListener("touchmove",t.__m__,!1),window.addEventListener("touchend",t.__u__,!1),t&&t.doDown&&t.doDown(e,t)}function l(t,e){e.touches&&e.touches.length>0&&(e=e.touches[0]);var n=s(e),r=n.x,i=n.y,a=t.currentCaptchaData.startX,o=t.currentCaptchaData.startY,c=t.currentCaptchaData.startTime,u=t.currentCaptchaData.end,l=(t.currentCaptchaData.bgImageWidth,t.currentCaptchaData.trackList),d=r-a,f=i-o,h={x:n.x,y:n.y,type:"move",t:(new Date).getTime()-c.getTime()};l.push(h),d<0?d=0:d>u&&(d=u),t.currentCaptchaData.moveX=d,t.currentCaptchaData.moveY=f,t.doMove&&t.doMove(e,t)}function d(t){t&&(t.__m__&&(window.removeEventListener("mousemove",t.__m__),window.removeEventListener("touchmove",t.__m__)),t.__u__&&(window.removeEventListener("mouseup",t.__u__),window.removeEventListener("touchend",t.__u__)))}function f(t,e){d(t);var n=s(e);t.currentCaptchaData.stopTime=new Date;var r=t.currentCaptchaData.startTime,i=t.currentCaptchaData.trackList,a={x:n.x,y:n.y,type:"up",t:(new Date).getTime()-r.getTime()};i.push(a),t.doUp&&t.doUp(e,t),t.endCallback(t.currentCaptchaData,t)}function h(t,e,n,r,i){var a={startTime:new Date,trackList:[],movePercent:0,clickCount:0,bgImageWidth:Math.round(t),bgImageHeight:Math.round(e),templateImageWidth:Math.round(n),templateImageHeight:Math.round(r),end:i};return a}function p(t,e){y(t).find("#captcha-web-sdk-tips").removeClass("captcha-web-sdk-tips-on"),e&&setTimeout(e,.35)}function v(t,e,n,r){var i=y(t).find("#captcha-web-sdk-tips");i.text(e),1===n?(i.removeClass("captcha-web-sdk-tips-error"),i.addClass("captcha-web-sdk-tips-success")):(i.removeClass("captcha-web-sdk-tips-success"),i.addClass("captcha-web-sdk-tips-error")),i.addClass("captcha-web-sdk-tips-on"),setTimeout(r,1e3)}var b=function(){function t(){r(this,t)}return a(t,[{key:"showTips",value:function(t,e,n){v(this.el,t,e,n)}},{key:"closeTips",value:function(t,e){p(this.el,t)}}]),t}();function y(t,e){return new m(t,e)}var m=function(){function t(e,i){if(r(this,t),i&&"object"===n(i)&&void 0!==i.nodeType)return this.dom=i,void(this.domStr=e);if(e instanceof t)this.dom=e.dom,this.domStr=e.domStr;else if("string"==typeof e)this.dom=document.querySelector(e),this.domStr=e;else{if("object"!==("undefined"==typeof document?"undefined":n(document))||void 0===document.nodeType)throw new Error("不支持的类型");this.dom=e,this.domStr=e.nodeName}}return a(t,[{key:"each",value:function(t){this.getTarget().querySelectorAll("*").forEach(t)}},{key:"removeClass",value:function(t){var e=this.getTarget();if(e.classList)e.classList.remove(t);else{var n=e.className,r=new RegExp("(?:^|\\s)"+t+"(?!\\S)","g");e.className=n.replace(r,"")}return this}},{key:"addClass",value:function(t){var e=this.getTarget();if(e.classList)e.classList.add(t);else{var n=e.className;-1===n.indexOf(t)&&(e.className=n+" "+t)}return this}},{key:"find",value:function(e){var n=this.getTarget().querySelector(e);return n?new t(e,n):null}},{key:"children",value:function(e){for(var n=this.getTarget().childNodes,r=0;r<n.length;r++)if(1===n[r].nodeType&&n[r].matches(e))return new t(e,n[r]);return null}},{key:"remove",value:function(){return this.getTarget().remove(),null}},{key:"css",value:function(t,e){if("string"==typeof t&&"string"==typeof e)this.getTarget().style[t]=e;else if("object"===n(t))for(var r in t)t.hasOwnProperty(r)&&(this.getTarget().style[r]=t[r]);else if("string"==typeof t&&void 0===e)return window.getComputedStyle(element)[t]}},{key:"attr",value:function(t,e){return void 0===e?this.getTarget().getAttribute(t):(this.getTarget().setAttribute(t,e),this)}},{key:"text",value:function(t){return this.getTarget().innerText=t,this}},{key:"html",value:function(t){return this.getTarget().innerHtml=t,this}},{key:"is",value:function(e){return e&&"object"===n(e)&&void 0!==e.nodeType?this.dom===e:e instanceof t?this.dom===e.dom:void 0}},{key:"append",value:function(t){if("string"==typeof t)this.getTarget().insertAdjacentHTML("beforeend",t);else{if(!(t instanceof HTMLElement))throw new Error("Invalid content type");this.getTarget().appendChild(t)}return this}},{key:"click",value:function(t){return this.on("click",t),this}},{key:"mousedown",value:function(t){return this.on("mousedown",t),this}},{key:"touchstart",value:function(t){return this.on("touchstart",t),this}},{key:"on",value:function(t,e){return this.getTarget().addEventListener(t,e,{passive:!0}),this}},{key:"width",value:function(){return this.getTarget().offsetWidth}},{key:"height",value:function(){return this.getTarget().offsetHeight}},{key:"getTarget",value:function(){if(this.dom)return this.dom;throw new Error("dom不存在: ["+this.domStr+"]")}}]),t}();function g(t){return g="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},g(t)}function w(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,(i=r.key,a=void 0,a=function(t,e){if("object"!==g(t)||null===t)return t;var n=t[Symbol.toPrimitive];if(void 0!==n){var r=n.call(t,e||"default");if("object"!==g(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(i,"string"),"symbol"===g(a)?a:String(a)),r)}var i,a}function k(t,e){return k=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},k(t,e)}function C(t){var e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}();return function(){var n,r=S(t);if(e){var i=S(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return function(t,e){if(e&&("object"===g(e)||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t)}(this,n)}}function S(t){return S=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)},S(t)}var T=function(t){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),Object.defineProperty(t,"prototype",{writable:!1}),e&&k(t,e)}(a,t);var e,n,r,i=C(a);function a(t,e){var n;return function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,a),(n=i.call(this)).boxEl=t,n.styleConfig=e,n.type="SLIDER",n.currentCaptchaData={},n}return e=a,n=[{key:"init",value:function(t,e,n){return this.destroy(),this.boxEl.append(function(t){return'\n<div id="captcha-web-sdk" class="captcha-web-sdk-slider">\n <div class="slider-tip">\n <span id="captcha-web-sdk-slider-move-track-font" style="font-size: '.concat(t.i18n.slider_title_size,'">').concat(t.i18n.slider_title,'</span>\n </div>\n <div class="content">\n <div class="bg-img-div">\n <img id="captcha-web-sdk-slider-bg-img" src="" alt/>\n <canvas id="captcha-web-sdk-slider-bg-canvas"></canvas>\n <div id="captcha-web-sdk-slider-bg-div"></div>\n </div>\n <div class="slider-img-div" id="captcha-web-sdk-slider-img-div">\n <img id="captcha-web-sdk-slider-move-img" src="" alt/>\n </div>\n <div class="captcha-web-sdk-tips" id="captcha-web-sdk-tips"></div>\n </div>\n <div class="slider-move">\n <div class="slider-move-track">\n <div id="captcha-web-sdk-slider-move-track-mask"></div>\n <div class="slider-move-shadow"></div>\n </div>\n <div class="slider-move-btn" id="captcha-web-sdk-slider-move-btn">\n </div>\n </div>\n\n</div>\n')}(this.styleConfig)),this.el=this.boxEl.find("#captcha-web-sdk"),this.loadStyle(),this.el.find("#captcha-web-sdk-slider-move-btn").mousedown(u.bind(null,this)),this.el.find("#captcha-web-sdk-slider-move-btn").touchstart(u.bind(null,this)),this.loadCaptchaForData(this,t),this.endCallback=e,n&&n(this),this}},{key:"showTips",value:function(t,e,n){v(this.el,t,e,n)}},{key:"closeTips",value:function(t){p(this.el,t)}},{key:"destroy",value:function(){var t=this.boxEl.children("#captcha-web-sdk");t&&t.remove(),d()}},{key:"doMove",value:function(){var t=this.currentCaptchaData.moveX;this.el.find("#captcha-web-sdk-slider-move-btn").css("transform","translate("+t+"px, 0px)"),this.el.find("#captcha-web-sdk-slider-img-div").css("transform","translate("+t+"px, 0px)"),this.el.find("#captcha-web-sdk-slider-move-track-mask").css("width",t+"px")}},{key:"loadStyle",value:function(){var t="",e="#00f4ab",n="#a9ffe5",r=this.styleConfig;r&&(t=r.btnUrl,n=r.moveTrackMaskBgColor,e=r.moveTrackMaskBorderColor),this.el.find(".slider-move .slider-move-btn").css("background-image","url("+t+")"),this.el.find("#captcha-web-sdk-slider-move-track-mask").css("border-color",e),this.el.find("#captcha-web-sdk-slider-move-track-mask").css("background-color",n)}},{key:"loadCaptchaForData",value:function(t,e){var n=t.el.find("#captcha-web-sdk-slider-bg-img"),r=t.el.find("#captcha-web-sdk-slider-move-img");n.attr("src",e.data.backgroundImage),r.attr("src",e.data.templateImage),n.on("load",(function(){t.currentCaptchaData=h(n.width(),n.height(),r.width(),r.height(),242),t.currentCaptchaData.currentCaptchaId=e.data.id}))}}],n&&w(e.prototype,n),r&&w(e,r),Object.defineProperty(e,"prototype",{writable:!1}),a}(b),E=T;function _(t){return _="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_(t)}function O(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,(i=r.key,a=void 0,a=function(t,e){if("object"!==_(t)||null===t)return t;var n=t[Symbol.toPrimitive];if(void 0!==n){var r=n.call(t,e||"default");if("object"!==_(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(i,"string"),"symbol"===_(a)?a:String(a)),r)}var i,a}function j(t,e){return j=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},j(t,e)}function R(t){var e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}();return function(){var n,r=D(t);if(e){var i=D(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return function(t,e){if(e&&("object"===_(e)||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t)}(this,n)}}function D(t){return D=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)},D(t)}var x=function(t){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),Object.defineProperty(t,"prototype",{writable:!1}),e&&j(t,e)}(a,t);var e,n,r,i=R(a);function a(t,e){var n;return function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,a),(n=i.call(this)).boxEl=t,n.styleConfig=e,n.type="ROTATE",n.currentCaptchaData={},n}return e=a,n=[{key:"init",value:function(t,e,n){return this.destroy(),this.boxEl.append(function(t){return'\n<div id="captcha-web-sdk" class="captcha-web-sdk-slider captcha-web-sdk-rotate">\n <div class="slider-tip">\n <span id="captcha-web-sdk-slider-move-track-font" style="font-size: '.concat(t.i18n.rotate_title_size,'">').concat(t.i18n.rotate_title,'</span>\n </div>\n <div class="content">\n <div class="bg-img-div">\n <img id="captcha-web-sdk-slider-bg-img" src="" alt/>\n <canvas id="captcha-web-sdk-slider-bg-canvas"></canvas>\n </div>\n <div class="rotate-img-div" id="captcha-web-sdk-slider-img-div">\n <img id="captcha-web-sdk-slider-move-img" src="" alt/>\n </div>\n <div class="captcha-web-sdk-tips" id="captcha-web-sdk-tips"></div>\n </div>\n <div class="slider-move">\n <div class="slider-move-track">\n <div id="captcha-web-sdk-slider-move-track-mask"></div>\n <div class="slider-move-shadow"></div>\n </div>\n <div class="slider-move-btn" id="captcha-web-sdk-slider-move-btn">\n </div>\n </div>\n</div>\n')}(this.styleConfig)),this.el=this.boxEl.find("#captcha-web-sdk"),this.loadStyle(),this.el.find("#captcha-web-sdk-slider-move-btn").mousedown(u.bind(null,this)),this.el.find("#captcha-web-sdk-slider-move-btn").touchstart(u.bind(null,this)),this.loadCaptchaForData(this,t),this.endCallback=e,n&&n(this),this}},{key:"destroy",value:function(){var t=this.boxEl.children("#captcha-web-sdk");t&&t.remove(),d()}},{key:"doMove",value:function(){var t=this.currentCaptchaData.moveX;this.el.find("#captcha-web-sdk-slider-move-btn").css("transform","translate("+t+"px, 0px)"),this.el.find("#captcha-web-sdk-slider-move-img").css("transform","rotate("+t/(this.currentCaptchaData.end/360)+"deg)"),this.el.find("#captcha-web-sdk-slider-move-track-mask").css("width",t+"px")}},{key:"loadStyle",value:function(){var t="",e="#00f4ab",n="#a9ffe5",r=this.styleConfig;r&&(t=r.btnUrl,n=r.moveTrackMaskBgColor,e=r.moveTrackMaskBorderColor),this.el.find(".slider-move .slider-move-btn").css("background-image","url("+t+")"),this.el.find("#captcha-web-sdk-slider-move-track-mask").css("border-color",e),this.el.find("#captcha-web-sdk-slider-move-track-mask").css("background-color",n)}},{key:"loadCaptchaForData",value:function(t,e){var n=t.el.find("#captcha-web-sdk-slider-bg-img"),r=t.el.find("#captcha-web-sdk-slider-move-img");n.attr("src",e.data.backgroundImage),r.attr("src",e.data.templateImage),n.on("load",(function(){t.currentCaptchaData=h(n.width(),n.height(),r.width(),r.height(),242),t.currentCaptchaData.currentCaptchaId=e.data.id}))}}],n&&O(e.prototype,n),r&&O(e,r),Object.defineProperty(e,"prototype",{writable:!1}),a}(b),A=x;function P(t){return P="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},P(t)}function B(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,(i=r.key,a=void 0,a=function(t,e){if("object"!==P(t)||null===t)return t;var n=t[Symbol.toPrimitive];if(void 0!==n){var r=n.call(t,e||"default");if("object"!==P(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(i,"string"),"symbol"===P(a)?a:String(a)),r)}var i,a}function M(t,e){return M=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},M(t,e)}function q(t){var e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}();return function(){var n,r=W(t);if(e){var i=W(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return function(t,e){if(e&&("object"===P(e)||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t)}(this,n)}}function W(t){return W=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)},W(t)}var F=function(t){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),Object.defineProperty(t,"prototype",{writable:!1}),e&&M(t,e)}(a,t);var e,n,r,i=q(a);function a(t,e){var n;return function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,a),(n=i.call(this)).boxEl=y(t),n.styleConfig=e,n.type="CONCAT",n.currentCaptchaData={},n}return e=a,n=[{key:"init",value:function(t,e,n){return this.destroy(),this.boxEl.append(function(t){return'\n <div id="captcha-web-sdk" class="captcha-web-sdk-slider captcha-web-sdk-concat">\n <div class="slider-tip">\n <span id="captcha-web-sdk-slider-move-track-font" style="font-size: '.concat(t.i18n.concat_title_size,'">').concat(t.i18n.concat_title,'</span>\n </div>\n <div class="content">\n <div class="captcha-web-sdk-slider-concat-img-div" id="captcha-web-sdk-slider-concat-img-div">\n <img id="captcha-web-sdk-slider-concat-slider-img" src="" alt/>\n </div>\n <div class="captcha-web-sdk-slider-concat-bg-img"></div>\n <div class="captcha-web-sdk-tips" id="captcha-web-sdk-tips"></div>\n </div>\n <div class="slider-move">\n <div class="slider-move-track">\n <div id="captcha-web-sdk-slider-move-track-mask"></div>\n <div class="slider-move-shadow"></div>\n </div>\n <div class="slider-move-btn" id="captcha-web-sdk-slider-move-btn">\n </div>\n </div>\n</div>\n ')}(this.styleConfig)),this.el=this.boxEl.find("#captcha-web-sdk"),this.loadStyle(),this.el.find("#captcha-web-sdk-slider-move-btn").mousedown(u.bind(null,this)),this.el.find("#captcha-web-sdk-slider-move-btn").touchstart(u.bind(null,this)),c(this.el),window.currentCaptcha=this,this.loadCaptchaForData(this,t),this.endCallback=e,n&&n(this),this}},{key:"destroy",value:function(){d();var t=this.boxEl.children("#captcha-web-sdk");t&&t.remove()}},{key:"doMove",value:function(){var t=this.currentCaptchaData.moveX;this.el.find("#captcha-web-sdk-slider-move-btn").css("transform","translate("+t+"px, 0px)"),this.el.find("#captcha-web-sdk-slider-concat-img-div").css("background-position-x",t+"px"),this.el.find("#captcha-web-sdk-slider-move-track-mask").css("width",t+"px")}},{key:"loadStyle",value:function(){var t="",e="#00f4ab",n="#a9ffe5",r=this.styleConfig;r&&(t=r.btnUrl,n=r.moveTrackMaskBgColor,e=r.moveTrackMaskBorderColor),this.el.find(".slider-move .slider-move-btn").css("background-image","url("+t+")"),this.el.find("#captcha-web-sdk-slider-move-track-mask").css("border-color",e),this.el.find("#captcha-web-sdk-slider-move-track-mask").css("background-color",n)}},{key:"loadCaptchaForData",value:function(t,e){var n=t.el.find(".captcha-web-sdk-slider-concat-bg-img"),r=t.el.find("#captcha-web-sdk-slider-concat-img-div");n.css("background-image","url("+e.data.backgroundImage+")"),r.css("background-image","url("+e.data.backgroundImage+")"),r.css("background-position","0px 0px");var i=e.data.backgroundImageHeight,a=(i-e.data.data.randomY)/i*180;r.css("height",a+"px"),t.currentCaptchaData=h(n.width(),n.height(),r.width(),r.height(),242),t.currentCaptchaData.currentCaptchaId=e.data.id}}],n&&B(e.prototype,n),r&&B(e,r),Object.defineProperty(e,"prototype",{writable:!1}),a}(b),L=F;function I(t){return I="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},I(t)}function Y(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,(i=r.key,a=void 0,a=function(t,e){if("object"!==I(t)||null===t)return t;var n=t[Symbol.toPrimitive];if(void 0!==n){var r=n.call(t,e||"default");if("object"!==I(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(i,"string"),"symbol"===I(a)?a:String(a)),r)}var i,a}var U=function(){function t(e,n){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.boxEl=e,this.styleConfig=n,this.type="DISABLE",this.currentCaptchaData={}}var e,n,r;return e=t,n=[{key:"init",value:function(t,e,n){return this.destroy(),this.boxEl.append(function(t){return'\n <div id="captcha-web-sdk" class="captcha-web-sdk-disable">\n <div class="slider-tip">\n <span id="captcha-web-sdk-slider-move-track-font" style="font-size: '.concat(t.i18n.disable_title_size,'">').concat(t.i18n.disable_title,'</span>\n </div>\n <div class="content">\n <div class="bg-img-div">\n\x3c!-- <svg width="100" height="100" viewBox="0 0 100 100">--\x3e\n\x3c!-- <polygon points="50,10 90,90 10,90" fill="none" stroke="#FF9900" stroke-width="4"/>--\x3e\n\x3c!-- <path d="M50 35V65 M50 75V75" stroke="#FF9900" stroke-width="4" stroke-linecap="round"/>--\x3e\n\x3c!-- </svg>--\x3e\n <span id="content-span"></span>\n </div>\n </div>\n </div>\n ')}(this.styleConfig)),this.el=this.boxEl.find("#captcha-web-sdk"),this.loadCaptchaForData(this,t),this.endCallback=e,n&&n(this),this}},{key:"destroy",value:function(){var t=this.boxEl.find("#captcha-web-sdk");t&&t.remove()}},{key:"loadCaptchaForData",value:function(t,e){var n=e.msg||e.message||t.styleConfig.i18n.disable_default_message;t.el.find("#content-span").text(n)}}],n&&Y(e.prototype,n),r&&Y(e,r),Object.defineProperty(e,"prototype",{writable:!1}),t}(),X=U;function G(t){return G="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},G(t)}function H(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,(i=r.key,a=void 0,a=function(t,e){if("object"!==G(t)||null===t)return t;var n=t[Symbol.toPrimitive];if(void 0!==n){var r=n.call(t,e||"default");if("object"!==G(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(i,"string"),"symbol"===G(a)?a:String(a)),r)}var i,a}function z(t,e){return z=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},z(t,e)}function N(t){var e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}();return function(){var n,r=K(t);if(e){var i=K(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return function(t,e){if(e&&("object"===G(e)||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t)}(this,n)}}function K(t){return K=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)},K(t)}var V=function(t){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),Object.defineProperty(t,"prototype",{writable:!1}),e&&z(t,e)}(a,t);var e,n,r,i=N(a);function a(t,e){var n;return function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,a),(n=i.call(this)).boxEl=t,n.styleConfig=e,n.type="IMAGE_CLICK",n.currentCaptchaData={},n}return e=a,n=[{key:"init",value:function(t,e,n){var r=this;this.destroy(),this.boxEl.append(function(t){return'\n<div id="captcha-web-sdk" class="captcha-web-sdk-slider captcha-web-sdk-word-click">\n <div class="click-tip">\n <span id="captcha-web-sdk-click-track-font" style="font-size: '.concat(t.i18n.image_click_title_size,'">').concat(t.i18n.image_click_title,'</span>\n <img src="" id="captcha-web-sdk-tip-img" class="tip-img">\n </div>\n <div class="content">\n <div class="bg-img-div">\n <img id="captcha-web-sdk-slider-bg-img" src="" alt/>\n <canvas id="captcha-web-sdk-slider-bg-canvas"></canvas>\n <div id="bg-img-click-mask"></div>\n </div>\n <div class="captcha-web-sdk-tips" id="captcha-web-sdk-tips"></div>\n </div>\n <div class="click-confirm-btn">').concat(t.i18n.image_click_confirm_text,"</div>\n</div>\n")}(this.styleConfig)),this.el=this.boxEl.find("#captcha-web-sdk"),this.loadCaptchaForData(this,t),this.endCallback=e;var i=l.bind(null,this);return this.el.find("#bg-img-click-mask").click((function(t){if("click-span"!==t.target.className){r.currentCaptchaData.clickCount++;var e=r.currentCaptchaData.trackList;1===r.currentCaptchaData.clickCount&&(r.currentCaptchaData.startTime=new Date,window.addEventListener("mousemove",i),r.currentCaptchaData.startX=t.offsetX,r.currentCaptchaData.startY=t.offsetY);var n=r.currentCaptchaData.startTime;e.push({x:Math.round(t.offsetX),y:Math.round(t.offsetY),type:"click",t:(new Date).getTime()-n.getTime()});var a=t.offsetX-10,o=t.offsetY-10;r.el.find("#bg-img-click-mask").append("<span class='click-span' style='left:"+a+"px;top: "+o+"px'>"+r.currentCaptchaData.clickCount+"</span>")}})),this.el.find(".click-confirm-btn").click((function(){r.currentCaptchaData.clickCount>0&&(r.currentCaptchaData.stopTime=new Date,window.removeEventListener("mousemove",i),r.endCallback(r.currentCaptchaData,r))})),n&&n(this),this}},{key:"destroy",value:function(){var t=this.boxEl.children("#captcha-web-sdk");t&&t.remove(),d()}},{key:"loadCaptchaForData",value:function(t,e){var n=t.el.find("#captcha-web-sdk-slider-bg-img"),r=t.el.find("#captcha-web-sdk-tip-img");n.on("load",(function(){t.currentCaptchaData=h(n.width(),n.height(),r.width(),r.height()),t.currentCaptchaData.currentCaptchaId=e.data.id})),n.attr("src",e.data.backgroundImage),r.attr("src",e.data.templateImage)}}],n&&H(e.prototype,n),r&&H(e,r),Object.defineProperty(e,"prototype",{writable:!1}),a}(b);function J(t){return J="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},J(t)}function Z(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,(i=r.key,a=void 0,a=function(t,e){if("object"!==J(t)||null===t)return t;var n=t[Symbol.toPrimitive];if(void 0!==n){var r=n.call(t,e||"default");if("object"!==J(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(i,"string"),"symbol"===J(a)?a:String(a)),r)}var i,a}function Q(t,e){return Q=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},Q(t,e)}function $(t){var e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}();return function(){var n,r=tt(t);if(e){var i=tt(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return function(t,e){if(e&&("object"===J(e)||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t)}(this,n)}}function tt(t){return tt=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)},tt(t)}var et=function(t){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),Object.defineProperty(t,"prototype",{writable:!1}),e&&Q(t,e)}(a,t);var e,n,r,i=$(a);function a(t,e){var n;return function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,a),(n=i.call(this,t,e)).type="WORD_IMAGE_CLICK",n}return e=a,n&&Z(e.prototype,n),r&&Z(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e}(V),nt=et;function rt(t){return function(t){if(Array.isArray(t))return it(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(!t)return;if("string"==typeof t)return it(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);"Object"===n&&t.constructor&&(n=t.constructor.name);if("Map"===n||"Set"===n)return Array.from(t);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return it(t,e)}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function it(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=new Array(e);n<e;n++)r[n]=t[n];return r}var at={required_bind_el:"[TAC] 必须配置 [bindEl] 用于将验证码绑定到该元素上",required_request_captcha_data_url:"[TAC] 必须配置 [requestCaptchaDataUrl] 请求验证码接口",required_valid_captcha_url:"[TAC] 必须配置 [validCaptchaUrl] 验证验证码接口",invalid_captcha_data:"[TAC] 后台验证码接口数据错误",unknown_captcha_type:"[TAC] 未知的验证码类型[%s]",default_valid_success_log:"验证码校验成功,请重写 [config.validSuccess] 方法,用于自定义逻辑处理",tips_success:"验证成功,耗时%s秒",tips_error:"验证失败,请重新尝试!",tips_4001:"验证码已失效,请刷新后重试!",tips_network_error:"网络异常,请稍后重试!",slider_title:"拖动滑块完成拼图",concat_title:"拖动滑块完成拼图",image_click_title:"请依次点击:",image_click_confirm_text:"确定",rotate_title:"拖动滑块完成拼图",disable_title:"当前验证码不可用",disable_default_message:"接口异常",slider_title_size:"15px",concat_title_size:"15px",image_click_title_size:"20px",rotate_title_size:"15px",disable_title_size:"15px"};function ot(t){for(var e=arguments.length,n=new Array(e>1?e-1:0),r=1;r<e;r++)n[r-1]=arguments[r];if("string"!=typeof t)return"";var i=0;return t.replace(/%s/g,(function(){var t=n[i];return i+=1,null==t?"":String(t)}))}function ct(){for(var t=arguments.length,e=new Array(t),n=0;n<t;n++)e[n]=arguments[n];return Object.assign.apply(Object,[{},at].concat(rt(e.filter(Boolean))))}var st={btnUrl:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIwAAABkCAYAAABU19jRAAAJcUlEQVR4nO2d63MT1xmHf9rV6mr5fgNMuSW+ENsY8N0EE2BMhinJNB8y/dD2Qz/0v+gMf0w/JHTKNJAhICwbsA02TpNAHEMgQIwNBSEb8F2rvXTeY1kjYyA+TmVJmfeZ8YiRWa9299E57/mdI63Dtm3E+RjAKTDMaj4F8AU9uyzMCQBn+EQxb+EjAF+RMH8AcJrPFLMGvCSMzWeKWSN/I2GiAFx8xpi1oPBZYiTQWRhGChaGkYKFYaRgYRgpWBhGChaGkYKFYaRgYRgpWBhGChaGkYKFYaRgYRgpWBhGChaGkYKFYaRgYRgpWBhGChaGkYKFYaRgYRgpWBhGChaGkYKFYaRgYRgpWBhGCiefrtShGwZiup74+4qqwu12Z/W7lIVJEfN6FDfv3sPXfYOIRRfpm1UQKC7EkQ+PYFtRcdZKw8KkiLsPJ/CfgSFcH7yOxWhU7MSluYQoR44fxdaCoqyUhoVJEfZ8FN99c1N0Sx6PR+zEMAz0XAgBNtB14hi25OXDkWXHxUVvinA4ln6ScTqdsGwbvRd7EPwyiEcvXyDbvpyHhUkRaq4fe/c3wEWSWFZiJySNYZroCYYQPHsBY1OTWSWNevLkyb/TYwa8lt8UAb8ftluDW9UwPj4hDs0Rb3JUVRXd09j9nwELKKgoR4HXlw2Hb3INkyK8mob9NdUwLROq4sCVKwMrdqRpGkzTFN0TaWR2HcKu0rKMr2lYmBTi1jS01dUt7UBx4PKlfvHP5JaGuqseIY0DjmOHsKukNKOPiYVJMU5VRXt9PSwboO+fvHJ5QEiiKEvlIz3S86HuHiiqAhw9iJ0lpRnb0rAwG4CqKHh/Tz0UhwOWaWGg/5oofEkmJLU4wfPdQia765CQJhNHJCzMBkEtSVtdLRw2YNo2hgaGEDMMMWpahrwJBUMUCkM9djgjE2EWZgOhFqW5rlbMKdm2heHBYUT1mCiAEW9pKKfpPh8Sj5mYCLMwG4zLqWJfTZWQgL5S++uhYURjBrR4S0MtUSYnwixMGvBoGvZUV4quh0S4Pjgsaho1XtOIcM8wxJCb+qmu33dljDS/CWEeTb/E/Pw89EUdebkBVBQWrnnbWVjQoMAtsT9asGDQhf8VUbnX5UJ9VaVoZahVuXZ1cMXoiaSJxWIiEab/dPj4UXFczjRrk/VJ70/hp/jhuxF89o9TGP1+FH6fD9OxGHw5Pnicb34/PJ2dweitu7hwLojvb47A9rhQmJeXGLm8iQeP/4uRH27h88/+iZhhYs40UFZQsK7XrqkqigvyYbk18VrHH74+EX74YAzRqI66mupE15UmzKwW5kEkgtFvRxA8ex7hJ2HMzczgzu0f8fjxExRt2YzcgB9udfUJjuo6Tv/7HE6f+pe4GHd//AkwLRhuDeXFRW+U5v7EI4yMjKI3GMLt0Tt4cO8BAoEcWJoTZYXrl6asqBC6U0GOy42HY+MrZi1JmoWFRZQW5sNyuVBeUpxOabJ7aiASjiB4/iKmnj+H5loaacwvLOL2jRF4AjnY8dc/I/DKbTdoSHvr8SO8DD/DzPSMWHrg1JwYvHZdpK2NVZWU26/aF3VDTyLP0N/bh4mJR3C7XZiZnRVdht/nx7u7tsOzzg5qORFWHAocigO9vX2Jronwej24cXMEbq8XrfW169rH/4usnq02o1FEo9FEE47luN22sTAzC0OPrd7ItnHn9h0MDg3D6/WKbZdHJqYRg26ar92XDgvD39zA2Ng4VKdTbEf7mpmeRX/fAPRfeRch+luNNTXICeSu+h3ti7okUzdgp3luO6uFUTUN9lLmnniOCkdKVnML8uB0r76rD72Di4qL4NI0IUnydpZlw/WmGsY00bRvDzZvKhfFKLAU9VOG8v7BdijW+i8kLX649yyMz0+fwVQksur3NILyejzw5efCoaT3kmW1MN68AMq2bBIXXtd18WMZBt6r242DBzvgda3uWhQ4xNzOkeNdohZYXFjA4vwCfD4/Sio2i9bjdeSoGirKylFYXirykehiFHpUR2FJCbZu+x1yXlMrrQWSZWwygv6Ll3DxXBCX+66u6I7o2DRFRWtbM1o62xNdb7rI7lGSqqBs+zZMTj4XLYY/x49t7+zABx8eReWO7ciLL41ctZmqoqRiE/x+P6amp5FbkI9jx7tw+GgncqmbesPuPAEfduzcgenZOTg0FaWby/GXP/0RdZXvrOvlkyzjzyfR81UIoQs9IpRJniqglszt0tDc1oS9bc2o37lTLMhKI2bW35HtRXQRs3MLmH/xUrzzVb8HJQUFyHX/crJCQ+JwOALFqaKspGjNRWtkbg5zc7PQXC5szl/f6Ig6MFqiSavuqHCmumuFLIYBt+ZEY0sTGtua0VBTJQK/NKPzLfzSQEKWL4NiiG5a1gpZzPhMdnNrE/a3N2NPVaUI+jIAnacGNhiShdbx9pzrFgunSA4tqeUQRbuqoLW9BQ0tjSINzhBZBCzMBvPzVAS950KiG6KWJVkWGnXRELrjQBtqG/eioTqzZAELs3FQy3Iv/BR9wUtiUtGOr+tNhoptGt1V7atD4+4aEehlGizMBnH/WRj9wcuiG7LjI7Vllm8d3nnoAKoaakXq+0tzWumChUkxdlyWge4rYt0uzRMpSck01SzUDR3s7MC7e2pFRqSmOZx7GyxMCrESLcsldAd7oCgrEx6xrldRRM1SvbceHfV1K0K7TISFSREx28L41KRIcGmdruOVz82KBFd1oqWjBe/tb0ArLd3McFnAwqSOiclJ9JwP4fLFXtEtJXdDywluU2uTGDpTgZupNcur8GerU8R0eBJDV6+LRVbJLYdIcF2aSHD3tzaL9b20zjdbYGFShB0z4HY6V9QtFNLRXFATxf2U4FZXZkLcLwULkyJoaUXMNMV6HbyS4O6jicQMS3DXCguTInJKC9HU0YoPOg8k1uy0t7eivnmfSHB9WSgLwZOPKcKwLcT0GL69cxe3b46KoK6+ZS92V2zNyAR3jfBsdaox6LPSpiVyf/rEo/rq11JlFzxbnWoomEMW5CtrhWsYRgoWhpGChWGkYGEYKVgYRgoWhpGChWGkYGEYKVgYRgoWhpGChWGkYGEYKVgYRgoWhpGChWGkYGEYKVgYRgoWhpGChWGkYGEYKVgYRgoWhpGChWGkYGEYKVgYRgr6qGx6b4/BZBXUwnzCl4xZI5844g3MCQBn+Kwxb+EjAGcdST3SxwBO8RljXsOnAL4AgP8BXnVIgIvemwsAAAAASUVORK5CYII=",moveTrackMaskBgColor:"#89d2ff",moveTrackMaskBorderColor:"#0298f8",i18n:at};function ut(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function lt(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?ut(Object(n),!0).forEach((function(e){dt(t,e,n[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):ut(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))}))}return t}function dt(t,e,n){return(e=pt(e))in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function ft(t){return ft="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},ft(t)}function ht(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,pt(r.key),r)}}function pt(t){var e=function(t,e){if("object"!==ft(t)||null===t)return t;var n=t[Symbol.toPrimitive];if(void 0!==n){var r=n.call(t,e||"default");if("object"!==ft(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"===ft(e)?e:String(e)}var vt=function(){function t(e){if(function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.i18n=ct(e.i18n),!e.bindEl)throw new Error(this.i18n.required_bind_el);if(!e.requestCaptchaDataUrl)throw new Error(this.i18n.required_request_captcha_data_url);if(!e.validCaptchaUrl)throw new Error(this.i18n.required_valid_captcha_url);this.bindEl=e.bindEl,this.domBindEl=y(e.bindEl),this.requestCaptchaDataUrl=e.requestCaptchaDataUrl,this.validCaptchaUrl=e.validCaptchaUrl,e.validSuccess&&(this.validSuccess=e.validSuccess),e.validFail&&(this.validFail=e.validFail),e.requestHeaders?this.requestHeaders=e.requestHeaders:this.requestHeaders={},e.btnCloseFun&&(this.btnCloseFun=e.btnCloseFun),e.btnRefreshFun&&(this.btnRefreshFun=e.btnRefreshFun),this.requestChain=[],this.timeToTimestamp=void 0===e.timeToTimestamp||e.timeToTimestamp,this.insertRequestChain(0,{preRequest:function(t,e,n,r){if(this.timeToTimestamp&&e.data)for(var i in e.data)e.data[i]instanceof Date&&(e.data[i]=e.data[i].getTime());return!0}})}var e,n,r;return e=t,(n=[{key:"addRequestChain",value:function(t){this.requestChain.push(t)}},{key:"insertRequestChain",value:function(t,e){this.requestChain.splice(t,0,e)}},{key:"removeRequestChain",value:function(t){this.requestChain.splice(t,1)}},{key:"requestCaptchaData",value:function(){var t=this,e={};return e.headers=this.requestHeaders||{},e.data={},e.headers["Content-Type"]="application/json;charset=UTF-8",e.method="POST",e.url=this.requestCaptchaDataUrl,this._preRequest("requestCaptchaData",e),this.doSendRequest(e).then((function(n){return t._postRequest("requestCaptchaData",e,n),n}))}},{key:"doSendRequest",value:function(t){if(t.headers)for(var e in t.headers)if(t.headers[e].indexOf("application/json")>-1){"string"!=typeof t.data&&(t.data=JSON.stringify(t.data));break}return(n=t,new Promise((function(t,e){var r=new XMLHttpRequest;if(r.open(n.method||"GET",n.url),n.headers)for(var i in n.headers)n.headers.hasOwnProperty(i)&&r.setRequestHeader(i,n.headers[i]);r.onreadystatechange=function(){if(r.readyState===XMLHttpRequest.DONE)if(r.status>=200&&r.status<=500){var n=r.getResponseHeader("Content-Type");n&&-1!==n.indexOf("application/json")?t(JSON.parse(r.responseText)):t(r.responseText)}else e(new Error("Request failed with status: "+r.status))},r.onerror=function(){e(new Error("Network Error"))},r.send(n.data)}))).then((function(t){try{return JSON.parse(t)}catch(e){return t}}));var n}},{key:"_preRequest",value:function(t,e,n,r){for(var i=0;i<this.requestChain.length;i++){var a=this.requestChain[i];if(a.preRequest&&!a.preRequest(t,e,this,n,r))break}}},{key:"_postRequest",value:function(t,e,n,r,i){for(var a=0;a<this.requestChain.length;a++){var o=this.requestChain[a];if(o.postRequest&&!o.postRequest(t,e,n,this,r,i))break}}},{key:"validCaptcha",value:function(t,e,n,r){var i,a=this,o=ct(this.i18n,null==n||null===(i=n.styleConfig)||void 0===i?void 0:i.i18n),c={id:t,data:e},s={};return s.headers=this.requestHeaders||{},s.data=c,s.headers["Content-Type"]="application/json;charset=UTF-8",s.method="POST",s.url=this.validCaptchaUrl,this._preRequest("validCaptcha",s,n,r),this.doSendRequest(s).then((function(t){return a._postRequest("validCaptcha",s,t,n,r),t})).then((function(t){if(200==t.code){var i=(e.stopTime-e.startTime)/1e3;n.showTips(ot(o.tips_success,i),1,(function(){return a.validSuccess(t,n,r)}))}else{var c=o.tips_error;4001===t.code&&(c=o.tips_4001),n.showTips(c,0,(function(){return a.validFail(t,n,r)}))}})).catch((function(t){var e=o.tips_network_error||o.tips_error;t&&"object"===ft(t)&&4001===t.code&&(e=o.tips_4001),n.showTips(e,0,(function(){return a.validFail(t,n,r)}))}))}},{key:"validSuccess",value:function(t,e,n){window.currentCaptchaRes=t,n.destroyWindow()}},{key:"validFail",value:function(t,e,n){n.reloadCaptcha()}}])&&ht(e.prototype,n),r&&ht(e,r),Object.defineProperty(e,"prototype",{writable:!1}),t}();function bt(t){return bt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},bt(t)}function yt(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,(i=r.key,a=void 0,a=function(t,e){if("object"!==bt(t)||null===t)return t;var n=t[Symbol.toPrimitive];if(void 0!==n){var r=n.call(t,e||"default");if("object"!==bt(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(i,"string"),"symbol"===bt(a)?a:String(a)),r)}var i,a}var mt=function(){function t(e,n){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.config=function(t){return t instanceof vt?t:new vt(t)}(e),this.config.btnRefreshFun&&(this.btnRefreshFun=this.config.btnRefreshFun),this.config.btnCloseFun&&(this.btnCloseFun=this.config.btnCloseFun),this.style=function(t,e){var n=lt(lt({},st),t);return n.i18n=ct(at,e,null==t?void 0:t.i18n),n}(n,this.config.i18n)}var e,n,r;return e=t,n=[{key:"init",value:function(){var t=this;return this.destroyWindow(),this.config.domBindEl.append('\n <div id="captcha-web-sdk-parent">\n <div id="captcha-web-sdk-bg-img"></div>\n <div id="captcha-web-sdk-box">\n <div id="captcha-web-sdk-loading" class="loading"></div>\n </div>\n \x3c!-- 底部 --\x3e\n <div class="slider-bottom">\n <img class="logo" id="captcha-web-sdk-logo" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAMAAAAM7l6QAAAAMFBMVEVHcEz3tkX3tkX3tkX3tkX3tkX3tkX3tkX3tkX3tkX3tkX3tkX3tkX3tkX3tkX3tkVmTmjZAAAAD3RSTlMASbTm8wh12hOGoCNiyTV98jvOAAABB0lEQVR42nVT0aIFEQiMorD0/397Lc5a7J0n1UylgIniLRKyDcbBDudZH2DYCAabn3PmTrjeUX+7rJGWx0SqVpzReAfTtKU5fgVCNfxWjB69USUDGwoOiauHpZEpSr0tCx8ILb3Dm3WgBbAlifAJk6+Ww6wqEUmpmIorQVZ1JtqKnDMjkb7AgIpO/wMCaQbuBuEtsBUxhuD9daUaZnApiQB8NAKotMwirGGr6mbXpPnHLHDmy6oy3FgP+1j8IBdVklFc01xUJwv3NR0rIeXV5zpzdlruiijzNq/ufOeKWzZLP3160u5P8RjT1M+HHFtx+PwGyOZqT/D8ROOfjOInTLBIHjy/hvwHxkwPu5cCE1QAAAAASUVORK5CYII=" id="captcha-web-sdk-logo"></img>\n <div class="close-btn" id="captcha-web-sdk-slider-close-btn"></div>\n <div class="refresh-btn" id="captcha-web-sdk-slider-refresh-btn"></div>\n </div>\n </div>\n '),this.domTemplate=this.config.domBindEl.find("#captcha-web-sdk-parent"),c(this.domTemplate),this.loadStyle(),this.config.domBindEl.find("#captcha-web-sdk-slider-refresh-btn").click((function(e){t.btnRefreshFun(e,t)})),this.config.domBindEl.find("#captcha-web-sdk-slider-close-btn").click((function(e){t.btnCloseFun(e,t)})),this.reloadCaptcha(),this}},{key:"btnRefreshFun",value:function(t,e){e.reloadCaptcha()}},{key:"btnCloseFun",value:function(t,e){e.destroyWindow()}},{key:"reloadCaptcha",value:function(){var t=this;this.showLoading(),this.destroyCaptcha((function(){t.createCaptcha()}))}},{key:"showLoading",value:function(){this.config.domBindEl.find("#captcha-web-sdk-loading").css("display","block")}},{key:"closeLoading",value:function(){this.config.domBindEl.find("#captcha-web-sdk-loading").css("display","none")}},{key:"loadStyle",value:function(){var t=this.style.bgUrl,e=this.style.logoUrl;t&&this.config.domBindEl.find("#captcha-web-sdk-bg-img").css("background-image","url("+t+")"),e&&""!==e?this.config.domBindEl.find("#captcha-web-sdk-logo").attr("src",e):null===e&&this.config.domBindEl.find("#captcha-web-sdk-logo").css("display","none")}},{key:"destroyWindow",value:function(){this.C&&(this.C.destroy(),this.C=void 0),this.domTemplate&&this.domTemplate.remove()}},{key:"openCaptcha",value:function(){var t=this;setTimeout((function(){t.C.el.css("transform","translateX(0)")}),10)}},{key:"createCaptcha",value:function(){var t=this;this.config.requestCaptchaData().then((function(e){var n;if(t.closeLoading(),!e.code)throw new Error(t.style.i18n.invalid_captcha_data);var r=200===e.code?null===(n=e.data)||void 0===n?void 0:n.type:"DISABLED",i=function(t,e){var n=e.config.domBindEl.find("#captcha-web-sdk-box"),r=e.style;switch(t){case"SLIDER":return new E(n,r);case"ROTATE":return new A(n,r);case"CONCAT":return new L(n,r);case"WORD_IMAGE_CLICK":return new nt(n,r);case"DISABLED":return new X(n,r);default:return null}}(r,t);if(null==i)throw new Error(ot(t.style.i18n.unknown_captcha_type,r));i.init(e,(function(e,n){var r=n.currentCaptchaData,i={bgImageWidth:r.bgImageWidth,bgImageHeight:r.bgImageHeight,templateImageWidth:r.templateImageWidth,templateImageHeight:r.templateImageHeight,startTime:r.startTime.getTime(),stopTime:r.stopTime.getTime(),trackList:r.trackList};"ROTATE_DEGREE"!==n.type&&"ROTATE"!==n.type||(i.bgImageWidth=n.currentCaptchaData.end),r.data&&(i.data=r.data);var a=n.currentCaptchaData.currentCaptchaId;n.currentCaptchaData=void 0,t.config.validCaptcha(a,i,n,t)})),t.C=i,t.openCaptcha()}))}},{key:"destroyCaptcha",value:function(t){var e=this;this.C?(this.C.el.css("transform","translateX(300px)"),setTimeout((function(){e.C.destroy(),t&&t()}),500)):t()}}],n&&yt(e.prototype,n),r&&yt(e,r),Object.defineProperty(e,"prototype",{writable:!1}),t}();"undefined"!=typeof window&&(window.TAC=mt,window.CaptchaConfig=vt);var gt=mt;return e}()}));
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# Framework Usage Examples
|
|
2
|
+
|
|
3
|
+
## General Notes
|
|
4
|
+
|
|
5
|
+
- `bindEl` 对应的 DOM 节点必须已经挂载
|
|
6
|
+
- 请只在客户端初始化,不要在 SSR 阶段执行 `new TAC(...)`
|
|
7
|
+
- 销毁页面或组件时,调用 `tac.destroyWindow()`
|
|
8
|
+
- React Native 需要通过 `WebView` 使用,本 SDK 不能直接运行在原生视图树里
|
|
9
|
+
|
|
10
|
+
## Next.js
|
|
11
|
+
|
|
12
|
+
### App Router
|
|
13
|
+
|
|
14
|
+
`app/layout.tsx`
|
|
15
|
+
|
|
16
|
+
```tsx
|
|
17
|
+
import "captcha-web-sdk/style.css";
|
|
18
|
+
|
|
19
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
20
|
+
return (
|
|
21
|
+
<html lang="en">
|
|
22
|
+
<body>{children}</body>
|
|
23
|
+
</html>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`app/components/captcha-box.tsx`
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
"use client";
|
|
32
|
+
|
|
33
|
+
import { useEffect } from "react";
|
|
34
|
+
import TAC from "captcha-web-sdk";
|
|
35
|
+
|
|
36
|
+
export default function CaptchaBox() {
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
const tac = new TAC({
|
|
39
|
+
requestCaptchaDataUrl: "/api/captcha/gen",
|
|
40
|
+
validCaptchaUrl: "/api/captcha/check",
|
|
41
|
+
bindEl: "#captcha-box"
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
tac.init();
|
|
45
|
+
|
|
46
|
+
return () => {
|
|
47
|
+
tac.destroyWindow();
|
|
48
|
+
};
|
|
49
|
+
}, []);
|
|
50
|
+
|
|
51
|
+
return <div id="captcha-box" />;
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## React
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
import { useEffect } from "react";
|
|
59
|
+
import TAC from "captcha-web-sdk";
|
|
60
|
+
import "captcha-web-sdk/style.css";
|
|
61
|
+
|
|
62
|
+
export default function CaptchaBox() {
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
const tac = new TAC({
|
|
65
|
+
requestCaptchaDataUrl: "/captcha/gen",
|
|
66
|
+
validCaptchaUrl: "/captcha/check",
|
|
67
|
+
bindEl: "#captcha-box",
|
|
68
|
+
validSuccess: (res, c, tacInstance) => {
|
|
69
|
+
tacInstance.destroyWindow();
|
|
70
|
+
console.log("success", res);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
tac.init();
|
|
75
|
+
|
|
76
|
+
return () => {
|
|
77
|
+
tac.destroyWindow();
|
|
78
|
+
};
|
|
79
|
+
}, []);
|
|
80
|
+
|
|
81
|
+
return <div id="captcha-box" />;
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Vue 3
|
|
86
|
+
|
|
87
|
+
```vue
|
|
88
|
+
<template>
|
|
89
|
+
<div id="captcha-box"></div>
|
|
90
|
+
</template>
|
|
91
|
+
|
|
92
|
+
<script setup>
|
|
93
|
+
import { onMounted, onBeforeUnmount } from "vue";
|
|
94
|
+
import TAC from "captcha-web-sdk";
|
|
95
|
+
import "captcha-web-sdk/style.css";
|
|
96
|
+
|
|
97
|
+
let tac;
|
|
98
|
+
|
|
99
|
+
onMounted(() => {
|
|
100
|
+
tac = new TAC({
|
|
101
|
+
requestCaptchaDataUrl: "/captcha/gen",
|
|
102
|
+
validCaptchaUrl: "/captcha/check",
|
|
103
|
+
bindEl: "#captcha-box"
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
tac.init();
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
onBeforeUnmount(() => {
|
|
110
|
+
tac?.destroyWindow();
|
|
111
|
+
});
|
|
112
|
+
</script>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Vue 2
|
|
116
|
+
|
|
117
|
+
```vue
|
|
118
|
+
<template>
|
|
119
|
+
<div id="captcha-box"></div>
|
|
120
|
+
</template>
|
|
121
|
+
|
|
122
|
+
<script>
|
|
123
|
+
import TAC from "captcha-web-sdk";
|
|
124
|
+
import "captcha-web-sdk/style.css";
|
|
125
|
+
|
|
126
|
+
export default {
|
|
127
|
+
name: "CaptchaBox",
|
|
128
|
+
data() {
|
|
129
|
+
return {
|
|
130
|
+
tac: null
|
|
131
|
+
};
|
|
132
|
+
},
|
|
133
|
+
mounted() {
|
|
134
|
+
this.tac = new TAC({
|
|
135
|
+
requestCaptchaDataUrl: "/captcha/gen",
|
|
136
|
+
validCaptchaUrl: "/captcha/check",
|
|
137
|
+
bindEl: "#captcha-box"
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
this.tac.init();
|
|
141
|
+
},
|
|
142
|
+
beforeDestroy() {
|
|
143
|
+
if (this.tac) {
|
|
144
|
+
this.tac.destroyWindow();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
</script>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## React Native
|
|
152
|
+
|
|
153
|
+
React Native 中不能直接使用 DOM 版 SDK。推荐通过 `react-native-webview` 在 WebView 中加载。
|
|
154
|
+
|
|
155
|
+
```tsx
|
|
156
|
+
import React from "react";
|
|
157
|
+
import { WebView } from "react-native-webview";
|
|
158
|
+
|
|
159
|
+
const html = `
|
|
160
|
+
<!DOCTYPE html>
|
|
161
|
+
<html>
|
|
162
|
+
<head>
|
|
163
|
+
<meta charset="utf-8" />
|
|
164
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
165
|
+
<link rel="stylesheet" href="https://your-cdn.example.com/tac/css/tac.css" />
|
|
166
|
+
</head>
|
|
167
|
+
<body>
|
|
168
|
+
<div id="captcha-box"></div>
|
|
169
|
+
<script src="https://your-cdn.example.com/tac/js/tac.min.js"></script>
|
|
170
|
+
<script>
|
|
171
|
+
const tac = new window.TAC({
|
|
172
|
+
requestCaptchaDataUrl: "https://your-api.example.com/captcha/gen",
|
|
173
|
+
validCaptchaUrl: "https://your-api.example.com/captcha/check",
|
|
174
|
+
bindEl: "#captcha-box",
|
|
175
|
+
validSuccess: function (res, c, tacInstance) {
|
|
176
|
+
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
177
|
+
type: "captcha-success",
|
|
178
|
+
payload: res
|
|
179
|
+
}));
|
|
180
|
+
tacInstance.destroyWindow();
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
tac.init();
|
|
185
|
+
</script>
|
|
186
|
+
</body>
|
|
187
|
+
</html>
|
|
188
|
+
`;
|
|
189
|
+
|
|
190
|
+
export default function CaptchaWebView() {
|
|
191
|
+
return (
|
|
192
|
+
<WebView
|
|
193
|
+
originWhitelist={["*"]}
|
|
194
|
+
source={{ html }}
|
|
195
|
+
onMessage={(event) => {
|
|
196
|
+
const data = JSON.parse(event.nativeEvent.data);
|
|
197
|
+
console.log(data);
|
|
198
|
+
}}
|
|
199
|
+
/>
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
```
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
export interface CaptchaI18nConfig {
|
|
2
|
+
required_bind_el?: string;
|
|
3
|
+
required_request_captcha_data_url?: string;
|
|
4
|
+
required_valid_captcha_url?: string;
|
|
5
|
+
invalid_captcha_data?: string;
|
|
6
|
+
unknown_captcha_type?: string;
|
|
7
|
+
default_valid_success_log?: string;
|
|
8
|
+
tips_success?: string;
|
|
9
|
+
tips_error?: string;
|
|
10
|
+
tips_4001?: string;
|
|
11
|
+
tips_network_error?: string;
|
|
12
|
+
slider_title?: string;
|
|
13
|
+
concat_title?: string;
|
|
14
|
+
image_click_title?: string;
|
|
15
|
+
image_click_confirm_text?: string;
|
|
16
|
+
rotate_title?: string;
|
|
17
|
+
disable_title?: string;
|
|
18
|
+
disable_default_message?: string;
|
|
19
|
+
slider_title_size?: string;
|
|
20
|
+
concat_title_size?: string;
|
|
21
|
+
image_click_title_size?: string;
|
|
22
|
+
rotate_title_size?: string;
|
|
23
|
+
disable_title_size?: string;
|
|
24
|
+
[key: string]: unknown;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface CaptchaStyleOptions {
|
|
28
|
+
btnUrl?: string | null;
|
|
29
|
+
bgUrl?: string | null;
|
|
30
|
+
logoUrl?: string | null;
|
|
31
|
+
moveTrackMaskBgColor?: string;
|
|
32
|
+
moveTrackMaskBorderColor?: string;
|
|
33
|
+
i18n?: CaptchaI18nConfig;
|
|
34
|
+
[key: string]: unknown;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface CaptchaRequestParams {
|
|
38
|
+
url: string;
|
|
39
|
+
method?: string;
|
|
40
|
+
headers?: Record<string, string>;
|
|
41
|
+
data?: unknown;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface CaptchaRequestChain {
|
|
45
|
+
preRequest?: (
|
|
46
|
+
type: string,
|
|
47
|
+
requestParam: CaptchaRequestParams,
|
|
48
|
+
config: CaptchaConfig,
|
|
49
|
+
captcha?: unknown,
|
|
50
|
+
tac?: CaptchaWebSdk
|
|
51
|
+
) => boolean | void;
|
|
52
|
+
postRequest?: (
|
|
53
|
+
type: string,
|
|
54
|
+
requestParam: CaptchaRequestParams,
|
|
55
|
+
response: unknown,
|
|
56
|
+
config: CaptchaConfig,
|
|
57
|
+
captcha?: unknown,
|
|
58
|
+
tac?: CaptchaWebSdk
|
|
59
|
+
) => boolean | void;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface CaptchaConfigOptions {
|
|
63
|
+
bindEl: string;
|
|
64
|
+
requestCaptchaDataUrl: string;
|
|
65
|
+
validCaptchaUrl: string;
|
|
66
|
+
i18n?: CaptchaI18nConfig;
|
|
67
|
+
requestHeaders?: Record<string, string>;
|
|
68
|
+
timeToTimestamp?: boolean;
|
|
69
|
+
validSuccess?: (response: any, captcha: any, tac: CaptchaWebSdk) => void;
|
|
70
|
+
validFail?: (response: any, captcha: any, tac: CaptchaWebSdk) => void;
|
|
71
|
+
btnRefreshFun?: (event: any, tac: CaptchaWebSdk) => void;
|
|
72
|
+
btnCloseFun?: (event: any, tac: CaptchaWebSdk) => void;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export class CaptchaConfig {
|
|
76
|
+
constructor(args: CaptchaConfigOptions);
|
|
77
|
+
bindEl: string;
|
|
78
|
+
requestCaptchaDataUrl: string;
|
|
79
|
+
validCaptchaUrl: string;
|
|
80
|
+
requestHeaders: Record<string, string>;
|
|
81
|
+
addRequestChain(chain: CaptchaRequestChain): void;
|
|
82
|
+
insertRequestChain(index: number, chain: CaptchaRequestChain): void;
|
|
83
|
+
removeRequestChain(index: number): void;
|
|
84
|
+
requestCaptchaData(): Promise<any>;
|
|
85
|
+
validCaptcha(currentCaptchaId: string, data: any, captcha?: any, tac?: CaptchaWebSdk): Promise<any>;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export class CaptchaWebSdk {
|
|
89
|
+
constructor(config: CaptchaConfig | CaptchaConfigOptions, style?: CaptchaStyleOptions | null);
|
|
90
|
+
config: CaptchaConfig;
|
|
91
|
+
style: CaptchaStyleOptions;
|
|
92
|
+
init(): CaptchaWebSdk;
|
|
93
|
+
reloadCaptcha(): void;
|
|
94
|
+
destroyWindow(): void;
|
|
95
|
+
openCaptcha(): void;
|
|
96
|
+
createCaptcha(): void;
|
|
97
|
+
destroyCaptcha(callback?: () => void): void;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
declare global {
|
|
101
|
+
interface Window {
|
|
102
|
+
TAC: typeof CaptchaWebSdk;
|
|
103
|
+
CaptchaConfig: typeof CaptchaConfig;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
declare const TAC: typeof CaptchaWebSdk;
|
|
108
|
+
|
|
109
|
+
export default TAC;
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "captcha-web-sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Captcha browser SDK with browser-global and npm import support",
|
|
5
|
+
"main": "./dist/tac/js/tac.min.js",
|
|
6
|
+
"types": "./index.d.ts",
|
|
7
|
+
"style": "./dist/tac/css/tac.css",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./index.d.ts",
|
|
11
|
+
"import": "./dist/tac/js/tac.min.js",
|
|
12
|
+
"require": "./dist/tac/js/tac.min.js",
|
|
13
|
+
"default": "./dist/tac/js/tac.min.js"
|
|
14
|
+
},
|
|
15
|
+
"./style.css": "./dist/tac/css/tac.css"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"index.d.ts",
|
|
20
|
+
"examples"
|
|
21
|
+
],
|
|
22
|
+
"sideEffects": [
|
|
23
|
+
"**/*.css",
|
|
24
|
+
"**/*.scss"
|
|
25
|
+
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"start": "webpack serve --mode development",
|
|
28
|
+
"build": "webpack --mode production --progress",
|
|
29
|
+
"build:dev": "webpack --mode development",
|
|
30
|
+
"build:prod": "webpack --mode production --progress",
|
|
31
|
+
"buildprod": "npm run build:prod",
|
|
32
|
+
"release:check": "npm run build && npm pack --dry-run",
|
|
33
|
+
"prepublishOnly": "npm run release:check"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"captcha",
|
|
37
|
+
"sdk",
|
|
38
|
+
"slider-captcha"
|
|
39
|
+
],
|
|
40
|
+
"author": "",
|
|
41
|
+
"license": "MulanPSL-2.0",
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=18"
|
|
44
|
+
},
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"registry": "https://registry.npmjs.org/"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@babel/core": "^7.22.17",
|
|
50
|
+
"@babel/preset-env": "^7.22.15",
|
|
51
|
+
"babel-loader": "^9.1.3",
|
|
52
|
+
"clean-webpack-plugin": "^4.0.0",
|
|
53
|
+
"css-loader": "^6.8.1",
|
|
54
|
+
"file-loader": "^6.2.0",
|
|
55
|
+
"html-webpack-plugin": "^5.5.3",
|
|
56
|
+
"javascript-obfuscator": "^4.1.0",
|
|
57
|
+
"mini-css-extract-plugin": "^2.7.6",
|
|
58
|
+
"sass": "^1.69.7",
|
|
59
|
+
"sass-loader": "^13.3.2",
|
|
60
|
+
"style-loader": "^3.3.3",
|
|
61
|
+
"terser-webpack-plugin": "^5.3.10",
|
|
62
|
+
"url-loader": "^4.1.1",
|
|
63
|
+
"webpack": "^5.88.2",
|
|
64
|
+
"webpack-bundle-analyzer": "^4.9.1",
|
|
65
|
+
"webpack-cli": "^5.1.4",
|
|
66
|
+
"webpack-dev-server": "^4.15.1",
|
|
67
|
+
"webpack-merge": "^5.10.0"
|
|
68
|
+
},
|
|
69
|
+
"packageManager": "npm@10.8.2"
|
|
70
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
# captcha-web-sdk 验证码前端 SDK
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
| 条目 | |
|
|
6
|
+
| -------- | ------------------------------------------------------------ |
|
|
7
|
+
| 兼容性 | Chrome、Firefox、Safari、Opera、主流手机浏览器、iOS 及 Android上的内嵌Webview |
|
|
8
|
+
| 框架支持 | H5、Angular、React、Vue2、Vue3、Next.js、React Native(WebView) |
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
## 本地打包
|
|
12
|
+
|
|
13
|
+
1. 安装依赖
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
2. 执行 SDK 生产打包
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm run build
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
3. 发包前检查
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm run release:check
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
4. 打包产物在 `dist` 目录下,核心文件如下:
|
|
32
|
+
|
|
33
|
+
- `dist/tac/js/tac.min.js`
|
|
34
|
+
- `dist/tac/css/tac.css`
|
|
35
|
+
- `dist/tac/images/*`
|
|
36
|
+
|
|
37
|
+
## 作为 SDK 接入
|
|
38
|
+
|
|
39
|
+
### 方式一: 浏览器 script 直引
|
|
40
|
+
|
|
41
|
+
```html
|
|
42
|
+
<link rel="stylesheet" href="/tac/css/tac.css" />
|
|
43
|
+
<script src="/tac/js/tac.min.js"></script>
|
|
44
|
+
|
|
45
|
+
<div id="captcha-box"></div>
|
|
46
|
+
<script>
|
|
47
|
+
const tac = new TAC({
|
|
48
|
+
requestCaptchaDataUrl: "/gen",
|
|
49
|
+
validCaptchaUrl: "/check",
|
|
50
|
+
bindEl: "#captcha-box"
|
|
51
|
+
});
|
|
52
|
+
tac.init();
|
|
53
|
+
</script>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 方式二: npm 包方式引入
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npm install captcha-web-sdk
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
import TAC, { CaptchaWebSdk, CaptchaConfig } from "captcha-web-sdk";
|
|
64
|
+
import "captcha-web-sdk/style.css";
|
|
65
|
+
|
|
66
|
+
const tac = new TAC({
|
|
67
|
+
requestCaptchaDataUrl: "/gen",
|
|
68
|
+
validCaptchaUrl: "/check",
|
|
69
|
+
bindEl: "#captcha-box"
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
tac.init();
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
说明:
|
|
76
|
+
|
|
77
|
+
- 默认导出为 `TAC`,等价于 `CaptchaWebSdk`
|
|
78
|
+
- 仍然兼容浏览器全局变量 `window.TAC` 和 `window.CaptchaConfig`
|
|
79
|
+
- 如果你还在使用历史的 `load.min.js` 初始化方式,本仓库当前打包产物依然兼容该模式
|
|
80
|
+
|
|
81
|
+
## 配置参数表
|
|
82
|
+
|
|
83
|
+
构造函数签名:
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
const tac = new TAC(config, style);
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
其中:
|
|
90
|
+
|
|
91
|
+
- `config` 是业务配置,负责接口地址、请求头、回调函数等
|
|
92
|
+
- `style` 是展示配置,负责按钮、背景、logo、文案和字号等
|
|
93
|
+
|
|
94
|
+
### 1. config 参数表
|
|
95
|
+
|
|
96
|
+
| 参数名 | 类型 | 必填 | 默认值 | 说明 | 示例 |
|
|
97
|
+
| ------ | ---- | ---- | ------ | ---- | ---- |
|
|
98
|
+
| `bindEl` | `string` | 是 | 无 | 验证码挂载容器的选择器,必须能被 `document.querySelector` 找到 | `"#captcha-box"` |
|
|
99
|
+
| `requestCaptchaDataUrl` | `string` | 是 | 无 | 获取验证码数据的后端接口地址,SDK 默认用 `POST + application/json` 请求 | `"/captcha/gen"` |
|
|
100
|
+
| `validCaptchaUrl` | `string` | 是 | 无 | 提交验证码校验结果的后端接口地址,SDK 默认用 `POST + application/json` 请求 | `"/captcha/check"` |
|
|
101
|
+
| `requestHeaders` | `Record<string, string>` | 否 | `{}` | 发送到两个接口的公共请求头 | `{ Authorization: "Bearer xxx" }` |
|
|
102
|
+
| `timeToTimestamp` | `boolean` | 否 | `true` | 是否自动把请求数据中的 `Date` 转成时间戳 | `false` |
|
|
103
|
+
| `i18n` | `Partial<CaptchaI18nConfig>` | 否 | 默认内置文案 | 运行时错误提示和状态文案覆盖配置 | `{ tips_error: "校验失败" }` |
|
|
104
|
+
| `validSuccess` | `(res, captcha, tac) => void` | 否 | 默认打印日志并销毁窗口 | 验证成功回调 | `(res, c, tac) => tac.destroyWindow()` |
|
|
105
|
+
| `validFail` | `(res, captcha, tac) => void` | 否 | `tac.reloadCaptcha()` | 验证失败回调 | `(res, c, tac) => tac.reloadCaptcha()` |
|
|
106
|
+
| `btnRefreshFun` | `(event, tac) => void` | 否 | `tac.reloadCaptcha()` | 点击刷新按钮后的回调 | `(e, tac) => tac.reloadCaptcha()` |
|
|
107
|
+
| `btnCloseFun` | `(event, tac) => void` | 否 | `tac.destroyWindow()` | 点击关闭按钮后的回调 | `(e, tac) => tac.destroyWindow()` |
|
|
108
|
+
|
|
109
|
+
### 2. style 参数表
|
|
110
|
+
|
|
111
|
+
| 参数名 | 类型 | 必填 | 默认值 | 说明 | 示例 |
|
|
112
|
+
| ------ | ---- | ---- | ------ | ---- | ---- |
|
|
113
|
+
| `btnUrl` | `string \| null` | 否 | 内置 base64 按钮图 | 滑块按钮图片地址 | `"https://cdn.example.com/btn.png"` |
|
|
114
|
+
| `bgUrl` | `string \| null` | 否 | 无 | 验证码弹窗背景图地址 | `"https://cdn.example.com/bg.jpg"` |
|
|
115
|
+
| `logoUrl` | `string \| null` | 否 | 内置 logo | 底部 logo 地址,传 `null` 可隐藏 logo | `null` |
|
|
116
|
+
| `moveTrackMaskBgColor` | `string` | 否 | `#89d2ff` | 滑动轨道填充背景色 | `"#f7b645"` |
|
|
117
|
+
| `moveTrackMaskBorderColor` | `string` | 否 | `#0298f8` | 滑动轨道边框颜色 | `"#ef9c0d"` |
|
|
118
|
+
| `i18n` | `Partial<CaptchaI18nConfig>` | 否 | 默认内置文案 | UI 文案和字号覆盖配置 | `{ slider_title: "请拖动滑块" }` |
|
|
119
|
+
|
|
120
|
+
### 3. i18n 参数表
|
|
121
|
+
|
|
122
|
+
支持 `%s` 占位符的参数:
|
|
123
|
+
|
|
124
|
+
- `unknown_captcha_type`
|
|
125
|
+
- `tips_success`
|
|
126
|
+
|
|
127
|
+
#### 3.1 通用提示文案
|
|
128
|
+
|
|
129
|
+
| 参数名 | 默认值 | 用途 |
|
|
130
|
+
| ------ | ------ | ---- |
|
|
131
|
+
| `required_bind_el` | `[TAC] 必须配置 [bindEl] 用于将验证码绑定到该元素上` | 缺少 `bindEl` 时抛出的错误文案 |
|
|
132
|
+
| `required_request_captcha_data_url` | `[TAC] 必须配置 [requestCaptchaDataUrl] 请求验证码接口` | 缺少生成接口地址时抛出的错误文案 |
|
|
133
|
+
| `required_valid_captcha_url` | `[TAC] 必须配置 [validCaptchaUrl] 验证验证码接口` | 缺少校验接口地址时抛出的错误文案 |
|
|
134
|
+
| `invalid_captcha_data` | `[TAC] 后台验证码接口数据错误` | 获取验证码接口返回结构异常时的错误文案 |
|
|
135
|
+
| `unknown_captcha_type` | `[TAC] 未知的验证码类型[%s]` | 后端返回未知验证码类型时的错误文案 |
|
|
136
|
+
| `default_valid_success_log` | `验证码校验成功,请重写 [config.validSuccess] 方法,用于自定义逻辑处理` | 未自定义成功回调时的默认日志文案 |
|
|
137
|
+
| `tips_success` | `验证成功,耗时%s秒` | 验证成功的提示文案 |
|
|
138
|
+
| `tips_error` | `验证失败,请重新尝试!` | 普通失败提示文案 |
|
|
139
|
+
| `tips_4001` | `验证码已失效,请刷新后重试!` | 验证码失效提示文案 |
|
|
140
|
+
| `tips_network_error` | `网络异常,请稍后重试!` | 网络异常提示文案 |
|
|
141
|
+
|
|
142
|
+
#### 3.2 UI 文案与字号
|
|
143
|
+
|
|
144
|
+
| 参数名 | 默认值 | 用途 |
|
|
145
|
+
| ------ | ------ | ---- |
|
|
146
|
+
| `slider_title` | `拖动滑块完成拼图` | 滑块验证码标题 |
|
|
147
|
+
| `concat_title` | `拖动滑块完成拼图` | 拼接验证码标题 |
|
|
148
|
+
| `image_click_title` | `请依次点击:` | 点选验证码标题 |
|
|
149
|
+
| `image_click_confirm_text` | `确定` | 点选验证码确认按钮文案 |
|
|
150
|
+
| `rotate_title` | `拖动滑块完成拼图` | 旋转验证码标题 |
|
|
151
|
+
| `disable_title` | `当前验证码不可用` | 禁用态标题 |
|
|
152
|
+
| `disable_default_message` | `接口异常` | 禁用态默认提示 |
|
|
153
|
+
| `slider_title_size` | `15px` | 滑块验证码标题字号 |
|
|
154
|
+
| `concat_title_size` | `15px` | 拼接验证码标题字号 |
|
|
155
|
+
| `image_click_title_size` | `20px` | 点选验证码标题字号 |
|
|
156
|
+
| `rotate_title_size` | `15px` | 旋转验证码标题字号 |
|
|
157
|
+
| `disable_title_size` | `15px` | 禁用态标题字号 |
|
|
158
|
+
|
|
159
|
+
### 4. 高级能力: 请求链 requestChain
|
|
160
|
+
|
|
161
|
+
如果你要在请求前后统一加签名、改请求体、打印日志,可以使用 `CaptchaConfig` 实例上的请求链能力。
|
|
162
|
+
|
|
163
|
+
| 方法名 | 参数 | 说明 |
|
|
164
|
+
| ------ | ---- | ---- |
|
|
165
|
+
| `addRequestChain(chain)` | `{ preRequest?, postRequest? }` | 在链尾追加一个处理器 |
|
|
166
|
+
| `insertRequestChain(index, chain)` | `index, chain` | 在指定位置插入处理器 |
|
|
167
|
+
| `removeRequestChain(index)` | `index` | 删除指定位置的处理器 |
|
|
168
|
+
|
|
169
|
+
请求链回调签名:
|
|
170
|
+
|
|
171
|
+
| 回调 | 签名 | 说明 |
|
|
172
|
+
| ---- | ---- | ---- |
|
|
173
|
+
| `preRequest` | `(type, requestParam, config, captcha, tac) => boolean \| void` | 请求发送前执行,可修改 `requestParam` |
|
|
174
|
+
| `postRequest` | `(type, requestParam, response, config, captcha, tac) => boolean \| void` | 请求完成后执行,可统一处理返回结果 |
|
|
175
|
+
|
|
176
|
+
`type` 可能值:
|
|
177
|
+
|
|
178
|
+
- `requestCaptchaData`
|
|
179
|
+
- `validCaptcha`
|
|
180
|
+
|
|
181
|
+
`requestParam` 结构:
|
|
182
|
+
|
|
183
|
+
```js
|
|
184
|
+
{
|
|
185
|
+
url: "/captcha/gen",
|
|
186
|
+
method: "POST",
|
|
187
|
+
headers: {
|
|
188
|
+
"Content-Type": "application/json;charset=UTF-8"
|
|
189
|
+
},
|
|
190
|
+
data: {}
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### 5. 最小可用配置
|
|
195
|
+
|
|
196
|
+
```js
|
|
197
|
+
import TAC from "captcha-web-sdk";
|
|
198
|
+
import "captcha-web-sdk/style.css";
|
|
199
|
+
|
|
200
|
+
const tac = new TAC({
|
|
201
|
+
bindEl: "#captcha-box",
|
|
202
|
+
requestCaptchaDataUrl: "/captcha/gen",
|
|
203
|
+
validCaptchaUrl: "/captcha/check"
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
tac.init();
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### 6. 完整配置示例
|
|
210
|
+
|
|
211
|
+
```js
|
|
212
|
+
import TAC from "captcha-web-sdk";
|
|
213
|
+
import "captcha-web-sdk/style.css";
|
|
214
|
+
|
|
215
|
+
const tac = new TAC(
|
|
216
|
+
{
|
|
217
|
+
bindEl: "#captcha-box",
|
|
218
|
+
requestCaptchaDataUrl: "/captcha/gen",
|
|
219
|
+
validCaptchaUrl: "/captcha/check",
|
|
220
|
+
requestHeaders: {
|
|
221
|
+
Authorization: "Bearer your-token"
|
|
222
|
+
},
|
|
223
|
+
timeToTimestamp: true,
|
|
224
|
+
i18n: {
|
|
225
|
+
tips_error: "验证失败,请重新再试一次",
|
|
226
|
+
tips_network_error: "网络开小差了,请稍后重试"
|
|
227
|
+
},
|
|
228
|
+
validSuccess: (res, captcha, tacInstance) => {
|
|
229
|
+
tacInstance.destroyWindow();
|
|
230
|
+
console.log("校验成功:", res);
|
|
231
|
+
},
|
|
232
|
+
validFail: (res, captcha, tacInstance) => {
|
|
233
|
+
tacInstance.reloadCaptcha();
|
|
234
|
+
},
|
|
235
|
+
btnRefreshFun: (event, tacInstance) => {
|
|
236
|
+
tacInstance.reloadCaptcha();
|
|
237
|
+
},
|
|
238
|
+
btnCloseFun: (event, tacInstance) => {
|
|
239
|
+
tacInstance.destroyWindow();
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
logoUrl: null,
|
|
244
|
+
btnUrl: "https://cdn.example.com/captcha/btn.png",
|
|
245
|
+
bgUrl: "https://cdn.example.com/captcha/bg.jpg",
|
|
246
|
+
moveTrackMaskBgColor: "#f7b645",
|
|
247
|
+
moveTrackMaskBorderColor: "#ef9c0d",
|
|
248
|
+
i18n: {
|
|
249
|
+
slider_title: "拖动滑块完成验证",
|
|
250
|
+
image_click_confirm_text: "确认"
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
tac.init();
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## 国际化配置
|
|
259
|
+
|
|
260
|
+
现在支持两种国际化覆盖方式:
|
|
261
|
+
|
|
262
|
+
- `config.i18n`: 适合接口提示、运行时错误等文案
|
|
263
|
+
- `style.i18n`: 适合按钮、标题、禁用态等 UI 文案
|
|
264
|
+
|
|
265
|
+
两者都会和默认文案自动合并,`style.i18n` 优先级最高。
|
|
266
|
+
|
|
267
|
+
```js
|
|
268
|
+
import TAC from "captcha-web-sdk";
|
|
269
|
+
import "captcha-web-sdk/style.css";
|
|
270
|
+
|
|
271
|
+
const tac = new TAC(
|
|
272
|
+
{
|
|
273
|
+
requestCaptchaDataUrl: "/gen",
|
|
274
|
+
validCaptchaUrl: "/check",
|
|
275
|
+
bindEl: "#captcha-box",
|
|
276
|
+
i18n: {
|
|
277
|
+
required_bind_el: "[TAC] bindEl is required",
|
|
278
|
+
required_request_captcha_data_url: "[TAC] requestCaptchaDataUrl is required",
|
|
279
|
+
required_valid_captcha_url: "[TAC] validCaptchaUrl is required",
|
|
280
|
+
invalid_captcha_data: "[TAC] Invalid captcha payload",
|
|
281
|
+
unknown_captcha_type: "[TAC] Unknown captcha type[%s]",
|
|
282
|
+
tips_success: "Verified in %s seconds",
|
|
283
|
+
tips_error: "Verification failed, please try again",
|
|
284
|
+
tips_4001: "Captcha expired, please refresh and retry",
|
|
285
|
+
tips_network_error: "Network error, please try again later"
|
|
286
|
+
},
|
|
287
|
+
validSuccess: (res, c, tacInstance) => {
|
|
288
|
+
tacInstance.destroyWindow();
|
|
289
|
+
console.log("captcha ok", res);
|
|
290
|
+
}
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
i18n: {
|
|
294
|
+
slider_title: "Drag the slider to complete the puzzle",
|
|
295
|
+
concat_title: "Drag the slider to complete the puzzle",
|
|
296
|
+
image_click_title: "Click in order:",
|
|
297
|
+
image_click_confirm_text: "Confirm",
|
|
298
|
+
rotate_title: "Drag the slider to rotate",
|
|
299
|
+
disable_title: "Captcha unavailable",
|
|
300
|
+
disable_default_message: "Request failed"
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
tac.init();
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## 多框架示例
|
|
309
|
+
|
|
310
|
+
完整示例见 [examples/frameworks.md](./examples/frameworks.md)
|
|
311
|
+
|
|
312
|
+
- Next.js: 仅在 Client Component 中初始化,CSS 放到 `app/layout.tsx` 或 `pages/_app.tsx`
|
|
313
|
+
- React: 在 `useEffect` 中初始化,在清理函数里销毁
|
|
314
|
+
- Vue3: 在 `onMounted` 中初始化,在 `onBeforeUnmount` 中销毁
|
|
315
|
+
- Vue2: 在 `mounted` 中初始化,在 `beforeDestroy` 中销毁
|
|
316
|
+
- React Native: 通过 `react-native-webview` 加载 H5 页面或内联 HTML,不支持直接在原生运行时中挂载 DOM 版 SDK
|
|
317
|
+
|
|
318
|
+
## 发布到 npm
|
|
319
|
+
|
|
320
|
+
### 首次发布前
|
|
321
|
+
|
|
322
|
+
1. 登录 npm
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
npm login
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
2. 确认包名还未被占用
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
npm view captcha-web-sdk version
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
如果返回 `404 Not Found`,说明当前包名还没有被注册。
|
|
335
|
+
|
|
336
|
+
3. 执行发包前检查
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
npm run release:check
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### 手动发布
|
|
343
|
+
|
|
344
|
+
```bash
|
|
345
|
+
npm publish
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### CI 自动发布
|
|
349
|
+
|
|
350
|
+
仓库内已提供 GitHub Actions 工作流:
|
|
351
|
+
|
|
352
|
+
- 推送 `v*` 标签时自动发布
|
|
353
|
+
- 也支持手动触发 `workflow_dispatch`
|
|
354
|
+
|
|
355
|
+
如果你的源码仓库托管在 Gitee,`.github/workflows` 不会自动执行,需要将同样的步骤迁移到 Gitee Go 或其他 CI 平台。
|
|
356
|
+
|
|
357
|
+
使用前需要在仓库 Secrets 中配置:
|
|
358
|
+
|
|
359
|
+
- `NPM_TOKEN`
|
|
360
|
+
|
|
361
|
+
示例发布命令:
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
git tag v1.0.0
|
|
365
|
+
git push origin v1.0.0
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
## 安装
|
|
370
|
+
|
|
371
|
+
1. 将打包好的`tac`目录放到自己项目中,如果是vue、react等框架,将tac目录放到public目录中、或者放到某个可以访问到地方,比如 oss 之类的可以被浏览器访问到的地方
|
|
372
|
+
|
|
373
|
+
2. 引入初始化函数 `load.js`,如果你仍然使用该初始化方式,请将该文件与 SDK 产物一起托管
|
|
374
|
+
|
|
375
|
+
```html
|
|
376
|
+
<script src="load.min.js"></script>
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
**注: 如果是web框架,将该引入代码放到 `public/index.html`**
|
|
380
|
+
|
|
381
|
+
## 使用方法
|
|
382
|
+
|
|
383
|
+
2. 创建一个div块用于渲染验证码, 该div用于装载验证码
|
|
384
|
+
|
|
385
|
+
```html
|
|
386
|
+
<div id="captcha-box"></div>
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
3. 在需要调用验证码的时候执行加载验证码方法
|
|
390
|
+
|
|
391
|
+
```js
|
|
392
|
+
function login() {
|
|
393
|
+
// config 对象为TAC验证码的一些配置和验证的回调
|
|
394
|
+
const config = {
|
|
395
|
+
// 生成接口 (必选项,必须配置, 要符合captcha-web-sdk默认验证码生成接口规范)
|
|
396
|
+
requestCaptchaDataUrl: "/gen",
|
|
397
|
+
// 验证接口 (必选项,必须配置, 要符合captcha-web-sdk默认验证码校验接口规范)
|
|
398
|
+
validCaptchaUrl: "/check",
|
|
399
|
+
// 验证码绑定的div块 (必选项,必须配置)
|
|
400
|
+
bindEl: "#captcha-box",
|
|
401
|
+
// 验证成功回调函数(必选项,必须配置)
|
|
402
|
+
validSuccess: (res, c, tac) => {
|
|
403
|
+
// 销毁验证码服务
|
|
404
|
+
tac.destroyWindow();
|
|
405
|
+
console.log("验证成功,后端返回的数据为", res);
|
|
406
|
+
// 调用具体的login方法
|
|
407
|
+
login(res.data.token)
|
|
408
|
+
},
|
|
409
|
+
// 验证失败的回调函数(可忽略,如果不自定义 validFail 方法时,会使用默认的)
|
|
410
|
+
validFail: (res, c, tac) => {
|
|
411
|
+
console.log("验证码验证失败回调...")
|
|
412
|
+
// 验证失败后重新拉取验证码
|
|
413
|
+
tac.reloadCaptcha();
|
|
414
|
+
},
|
|
415
|
+
// 刷新按钮回调事件
|
|
416
|
+
btnRefreshFun: (el, tac) => {
|
|
417
|
+
console.log("刷新按钮触发事件...")
|
|
418
|
+
tac.reloadCaptcha();
|
|
419
|
+
},
|
|
420
|
+
// 关闭按钮回调事件
|
|
421
|
+
btnCloseFun: (el, tac) => {
|
|
422
|
+
console.log("关闭按钮触发事件...")
|
|
423
|
+
tac.destroyWindow();
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
// 一些样式配置, 可不传
|
|
427
|
+
let style = {
|
|
428
|
+
logoUrl: null;// 去除logo
|
|
429
|
+
// logoUrl: "/xx/xx/xxx.png" // 替换成自定义的logo
|
|
430
|
+
}
|
|
431
|
+
// 参数1 为 tac文件是目录地址, 目录里包含 tac的js和css等文件
|
|
432
|
+
// 参数2 为 tac验证码相关配置
|
|
433
|
+
// 参数3 为 tac窗口一些样式配置
|
|
434
|
+
window.initTAC("./tac", config, style).then(tac => {
|
|
435
|
+
tac.init(); // 调用init则显示验证码
|
|
436
|
+
}).catch(e => {
|
|
437
|
+
console.log("初始化tac失败", e);
|
|
438
|
+
})
|
|
439
|
+
}
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### 对滑块的按钮和背景设置为自定义的一些样式
|
|
443
|
+
|
|
444
|
+
```js
|
|
445
|
+
// 这里分享一些作者自己调的样式供参考
|
|
446
|
+
const style = {
|
|
447
|
+
// 按钮样式
|
|
448
|
+
btnUrl: "https://example.com/captcha/btn3.png",
|
|
449
|
+
// 背景样式
|
|
450
|
+
bgUrl: "https://example.com/captcha/btn3-bg.jpg",
|
|
451
|
+
// logo地址
|
|
452
|
+
logoUrl: "https://example.com/captcha/logo.png",
|
|
453
|
+
// 滑动边框样式
|
|
454
|
+
moveTrackMaskBgColor: "#f7b645",
|
|
455
|
+
moveTrackMaskBorderColor: "#ef9c0d"
|
|
456
|
+
}
|
|
457
|
+
window.initTAC("./tac", config, style).then(tac => {
|
|
458
|
+
tac.init(); // 调用init则显示验证码
|
|
459
|
+
}).catch(e => {
|
|
460
|
+
console.log("初始化tac失败", e);
|
|
461
|
+
})
|
|
462
|
+
```
|