猎豹浏览器中附带的2个文件【12306抢票插件相关的】

111 222

 

文件路径 F:\Users\venus\AppData\Local\liebao\User Data\Default\Extensions\iojocdfolilckogkigiahnjfmpjinobl\4.3.3_0

 

本地安装的猎豹浏览器版本为:4.3.3_0

 

manifest.json :

{
   "content_scripts": [ {
      "all_frames": true,
      "exclude_globs": [  ],
      "exclude_matches": [  ],
      "include_globs": [  ],
      "js": [ "12306_ticket_helper.user.js" ],
      "matches": [ "http://dynamic.12306.cn/otsweb/*", "https://dynamic.12306.cn/otsweb/*", "https://www.12306.cn/*" ],
      "run_at": "document_idle"
   } ],
   "content_security_policy": "script-src 'self' https://github.com; object-src 'self';",
   "converted_from_user_script": true,
   "description": "\u5E2E\u60A8\u8BA2\u7968\u7684\u5C0F\u52A9\u624B by \u6728\u9C7C :-)",
   "homepage_url": "http://www.fishlee.net/",
   "icons": {
      "16": "icons/icon_16.png",
      "32": "icons/icon_32.png",
      "48": "icons/icon_48.png"
   },
   "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8B5NJl8hQY93eC7Mzpb6zk/aJ8ZlZH6zFGXuZ5HzQIup6pR4du8F4Mt6Y0Dq22IRrFG5lSK5mmTApcgYrCrYMW23jkdsVAy9KnQers4CvIPqNYKl77JnIpg6+a4c+hvjLA3m5Q+R2Pum/ubg4ykrSnfWgIsA3V6uJ1IkcRsDnbQIDAQAB",
   "manifest_version": 2,
   "name": "12306 \u8BA2\u7968\u52A9\u624B (\u730E\u8C79\u6D4F\u89C8\u5668\u4E13\u7248)",
   "permissions": [ "http://www.12306.cn/", "https://*.12306.cn/*", "notifications" ],
   "update_url": "http://www.fishlee.net/service/update/44/update_liebao.xml",
   "version": "4.3.3"
}

 

12306_ticket_helper.user.js:

 
//=======START=======
 
var version = "4.3.3";
var updates = [
    "为了保证大家订票安全,临时和谐了所有和提交订单有关系的功能",
    "其它更新了什么?你懂的"
];
 
var faqUrl = "http://www.fishlee.net/soft/44/faq.html";
//标记
var utility_emabed = false;
 
 
//#region -----------------UI界面--------------------------
 
function initUIDisplay() {
    injectStyle();
}
 
/**
 * 将使用的样式加入到当前页面中
 */
function injectStyle() {
    var s = document.createElement("style");
    s.id = "12306_ticket_helper";
    s.type = "text/css";
    s.textContent = ".fish_running, .fish_clock, .fish_error, .fish_ok {\
    line-height:20px;\
    text-indent:18px;\
    background-repeat:no-repeat;\
    background-position:2px 50%;\
    font-size:12px;\
    }\
    .fish_running{background-image:url(data:image/gif;base64,R0lGODlhEAAQALMPAHp6evf394qKiry8vJOTk83NzYKCgubm5t7e3qysrMXFxe7u7pubm7S0tKOjo////yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCAAPACwAAAAAEAAQAAAETPDJSau9NRDAgWxDYGmdZADCkQnlU7CCOA3oNgXsQG2FRhUAAoWDIU6MGeSDR0m4ghRa7JjIUXCogqQzpRxYhi2HILsOGuJxGcNuTyIAIfkECQgADwAsAAAAABAAEAAABGLwSXmMmjhLAQjSWDAYQHmAz8GVQPIESxZwggIYS0AIATYAvAdh8OIQJwRAQbJkdjAlUCA6KfU0VEmyGWgWnpNfcEAoAo6SmWtBUtCuk9gjwQKeQAeWYQAHIZICKBoKBncTEQAh+QQJCAAPACwAAAAAEAAQAAAEWvDJORejGCtQsgwDAQAGGWSHMK7jgAWq0CGj0VEDIJxPnvAU0a13eAQKrsnI81gqAZ6AUzIonA7JRwFAyAQSgCQsjCmUAIhjDEhlrQTFV+lMGLApWwUzw1jsIwAh+QQJCAAPACwAAAAAEAAQAAAETvDJSau9L4QaBgEAMWgEQh0CqALCZ0pBKhRSkYLvM7Ab/OGThoE2+QExyAdiuexhVglKwdCgqKKTGGBgBc00Np7VcVsJDpVo5ydyJt/wCAAh+QQJCAAPACwAAAAAEAAQAAAEWvDJSau9OAwCABnBtQhdCQjHlQhFWJBCOKWPLAXk8KQIkCwWBcAgMDw4Q5CkgOwohCVCYTIwdAgPolVhWSQAiN1jcLLVQrQbrBV4EcySA8l0Alo0yA8cw+9TIgAh+QQFCAAPACwAAAAAEAAQAAAEWvDJSau9WA4AyAhWMChPwXHCQRUGYARgKQBCzJxAQgXzIC2KFkc1MREoHMTAhwQ0Y5oBgkMhAAqUw8mgWGho0EcCx5DwaAUQrGXATg6zE7bwCQ2sAGZmz7dEAAA7); color: green;}\
    .fish_clock{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAG/SURBVHjapJM/S8NQFMVvpaVfoEKojWL9U3DLIqjoooJDu/sFmnQoiIujQz+Aix3a1FUQXIR2UFA6+WeRUhBprERroGTopg6lSeo7iY1pq4sNHPpy3+8c7n0v9XW7XRrl8SFAlmVvbYFpmynOJHzXKkwlphOmxx4oiiL5sbAsi1KpFOVyuWQwGMzEYjEuGo0Sx3E2qOu6oKqqoChKst1u7zO2wNifDrLZLNbJUCgkLy2vEM/zv7araRrd3lxTq9US2WshnU7TGDZM01zwBwKZxaVlCkd4MtmxQDXlyVbvHXtgwMIDrx3Q6XS2Z2bnufDEJJkWuWIt2/LWwICFxw0wDCM+PTPXB0K4IGiwDhYeeP3fHQjjXIQMq3/mev3J/l0fqIOFxxtAxi+fg/rsBOztSE7QVpwpQT2PN6Dy1mgIYX7KNZcvipQ5yA+Fosum1rA93jMo1R6q7oxX50Va20wMzd4TWHi8t3BSvb/T1bpz4qsbf5vBgIXHDWB3+vj58b5fPj9jc9fcex8U9sCAhcc7Au1mDgtN7VU8Oz7SL0un9PbyTBYzQVijhj0wYOFxP2VJkv71Z8rn807AKM+XAAMArp1CsEFrDIIAAAAASUVORK5CYII=); color: blue;}\
    .fish_error{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJFSURBVHjapJO/T1pRFMe/Dx7ypEXri4lUGUhsHF40hODSpQ61cTH+2HSoZaF1dHSxpU7+Ca04NE7dyuBiapcuLFokTdD4A01awNdBSkAf8ut5zhUoxq3e5OS+nPv5nnvuyfdJpmniPksSBd68aM1pFDMU4xS+ei5GsUHxmSLRJD9+hcx7rVqFZWwMtc3NIGy2Zam31yX19ABdXTdgNuszdd1nptNBlMtviQ0TC0ujg1LgGWNByelctQ4M4G8qhfN4HLmDA6HvpJzq9eJRXx+qlDPz+deUDrd9+i6KoFouazVg2erx4M/uLn5FItGLk5NX/qUliYO+I2o2C4vLBWaYZQ1rRYFyqTQDVXXl02mcb29HbXb7S+/CwjqKRSAaDXlHRqYwOoqdxUUww6zQNApUSqVxuaMDF8kk2hTlgxYIHMMwaHSxEB2/a4g7u7sjzDDLmn8dXF35ZJsNVWrzycTEOtxuYH//lpjWezqbZoZZ1rQ+AXyj3eEQO7a27oj9s7OhVkZoWjqIFXUdD1QVub29L3fEk5MhXF7y2RwzzLKmdQYb+UwGiqLwO6duiVdWxM2GrvfTfOaZYZY1TScmvE7NKsvf3B6PyzE8jB9ra6DJR2TTnBYXSNIcbfN021Mjl8Pv09OzaqXyXIvnE6LAT00RRlLa21cfk1kesgNpULBab5xITiUHokADzJDJioYhjDSUKNafUKlgaHAwXCCHJQ8Pz1JHRyhQm2RhEfzNOT5jhlnWNJ+w0y/918/kPzbrf+M91rUAAwCuQDz94e2kLwAAAABJRU5ErkJggg==); color: blue;}\
    .fish_ok{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHsSURBVHjapFNBSBtBFH2xgoqmKipEC6XkYqhUWXOxUAQhpyJ4Wgi0l0rNsdBbL/WgF2/eV8hNSBF68uhFkOrFhCAGS8mWgmYjG9lCKVGTuP1vsrvuIac68HZm/n/vz5/9fyKu6+IhI8IA5k4kbHsuSAsWBZpnKwh2BTlBySfGdTmcAX7kOJc5r5hfhyw7/86t21/EVVbgmjb6yPG4SqsyONtWGaz0Dk8aYzMf0R+b65ju3+oR7OImrp3vGdluJd646KKj1ZK0H0XXRqfeo390Emg6HUEfOeQqjQwVoNFAOvpkPjYw8kw2NRgfFtQchm8jh1xqggDNJhYHY3Jy41IhmXodrDvZyKWG2m4vA23gcR9wa6m7Jue1YO2PsI1casIB5GPBWM8ilZLyvFzu+BPNwyz29oDM5+W2JhSg8NsqaRSTMHycxfg4MDHRJlUqgCWHO/IvyRGu0gQB5D671Z+mlpiZFXEejjSInrw/OS4wjiWwNFx8ehZnRVNpwlXI/SrXqvbFOfS3TxWRAtNpwxfTRw651AQZSE1Lrfrd6mmhZky96IGejuJgX5rL9HpbrvBKbHbFxunJDa6F67e0X0YsLWHr6uouc/StXi3m/yCRkNTjbXBNG33kkEtN8Jh2Pv3fY9I3vLfwkPFPgAEApRUigcIVl3AAAAAASUVORK5CYII=); color: purple;}\
     .outerbox{border:5px solid #EAE3F7;}\
    .box{border:1px solid #6E41C2;color:#444;margin:auto;}\
    .box .title{padding:5px;line-height:20px;background-color:#B59DE2;color:#fff;}\
    .box .title a {color:white;}\
    .box .content{padding:5px;background-color:#fff;}\
    .box table{border-collapse:collapse; width:98%;}\
    .box table td{padding:5px;}\
    .box input[type=button],.fish_button {padding:5px;}\
    .box .name ,.box .caption,.box .caption td { background-color:#EAE3F7; font-weight:bold;-webkit-transition:all linear 0.2s;-moz-transition:all linear 0.2s;}\
    .fish_sep td {border-top:1px solid #A688DD;}\
    .lineButton { cursor:pointer; border: 1px solid green; border-radius:3px; font-size:12px; line-height: 16px; padding:3px; backround-color: lightgreen; color: green;-webkit-transition:all linear 0.2s;-moz-transition:all linear 0.2s;}\
    .lineButton:hover { color: white; background-color: green;-webkit-transition:all linear 0.1s;-moz-transition:all linear 0.1s; }\
.fishTab {border: 5px solid #E5D9EC;font-size: 12px;}\
.fishTab .innerTab {border-width: 1px;border-style: solid;border-color: #C7AED5;background-color: #fff;}\
.fishTab .tabNav {font-weight:bold;color:#F5F1F8;background-color: #C7AED5;line-height:25px;overflow:hidden;margin:0px;padding:0px;}\
.fishTab .tabNav li {float:left;list-style:none;cursor:pointer;padding-left: 20px;padding-right: 20px;}\
.fishTab .tabNav li:hover {background-color:#DACAE3;}\
.fishTab .tabNav li.current {background-color:#fff;color: #000;}\
.fishTab .tabContent {padding:5px;display:none;}\
.fishTab .tabContent p{margin:10px 0px 10px 0px;}\
.fishTab div.current {display:block;}\
.fishTab div.control {text-align:center;line-height:25px;background-color:#F0EAF4;}\
.fishTab input[type=button] { padding: 5px; }\
.hide {display:none;}\
.fish_button {background-color:#7077DA;font-size:12px; font-family:微软雅黑; color:#fff; border: 1px solid #7077DA;margin-left:5px;margin-right:5px;-webkit-transition:all linear 0.2s;-moz-transition:all linear 0.2s;border-radius:3px;font-size:12px;}\
.fish_button:hover{background:#fff;color:#7077DA;-webkit-transition:all linear 0.1s;-moz-transition:all linear 0.1s;cursor:pointer;}\
tr.steps td{background-color:#E8B7C2!important;-webkit-transition:all linear 0.1s;-moz-transition:all linear 0.1s;}\
tr.stepsok td{background-color:#BDE5BD!important;-webkit-transition:all linear 0.1s;-moz-transition:all linear 0.1s;}\
tr.steps span.indicator {display:inline-block!important;}\
tr.stepsok span.indicator {display:inline-block!important;}\
.highlightrow td { background-color:#D0C0ED!important; color:red; }\
#randCodeTxt{ font-weight: bold; font-size: 18px; text-align: center; padding: 3px 10px 3px 10px; font-family: verdana!important; text-transform: uppercase; }";
 
    document.head.appendChild(s);
}
 
function injectDom() {
    var html = [];
    html.push('<div id="fishOption" style="width: 600px; display:none; box-shadow: 7px 7px 10px #A67EBC;">');
    html.push('<div class="innerTab">');
    html.push('<ul class="tabNav" default="tabVersion">');
    html.push('<li tab="tabLogin">常规设置</li>');
    html.push('<li tab="tabReg">注册</li>');
    html.push('<li tab="tabFaq">常见问题</li>');
    html.push('<li tab="tabVersion">版本信息</li>');
    html.push('<li tab="tabLog">运行日志</li>');
    html.push('<li tab="tabLoginIE">登录到IE</li>');//获取登录到IE的代码 Add By XPHelper
    html.push('</ul>');
    html.push('<div class="tabContent tabLogin">');
    html.push('<table>');
    html.push('<tr>');
    html.push('<td>重试时间 ');
    html.push('<td>');
    html.push('<td><input type="text" name="login.retryLimit" size="6" value="2000" />');
    html.push('(ms)</td>');
    html.push('<td>');
    html.push('</td>');
    html.push('<td></td>');
    html.push('</tr>');
    html.push('</table>');
    html.push('</div>');
    html.push('<div class="tabContent tabReg" style="text-indent: 20px">');
    html.push('<p>为了阻止地球人他喵地拿作者无偿奉献的助手去卖钱钱,请注册唷。<strong>完全免费申请</strong>。</p>');
    html.push('<p style="color: red;"> <strong style="font-size:16px;">啊嘞……看这里!本助手完全免费啊诸位大人!</strong>任何在第三方网站上出售的软件全他喵的是侵权出售啊!!看到的时候请亲务必记得退款退货打差评向青天大老爷举报啊!!</p>');
    html.push('<p style="color:purple;"> 回家是一个单纯而简单的心愿,希望我们不会变得太复杂……</p>');
    html.push('<p>任何版本之间,功能上没有任何区别,So……不要问作者万一资助的话会有神马新功能,木有的说…… (= ̄ω ̄=) </p>');
    html.push('<p class="registered" style="display:none;">很高兴认识你,,<strong>[email protected]</strong>,谢谢你的出现~~~~已注册版本:<strong>正式版</strong>【<a href="javascript:;" id="unReg">重新注册</a>】</p>');
    html.push('<table class="regTable" style="display:none;width:98%;">');
    html.push('<tr>');
    html.push('<td>请粘贴注册码 【<a href="http://www.fishlee.net/Apps/Cn12306/GetNormalRegKey?v=1" target="_blank" style="color:blue;font-weight:bold;text-decoration:underline;">戳我直接申请注册码啊!为什么你们舍不得戳我啊 ╮(╯▽╰)╭</a>】</td>');
    html.push('</tr><tr>');
    html.push('<td style="text-align:center;"><textarea id="regContent" style="width:98%; height:50px;"></textarea></td>');
    html.push('</tr><tr>');
    html.push('<td><input type="button" id="regButton" value="注册" /></td>');
    html.push('</tr>');
    html.push('</table>');
    html.push('</div>');
    html.push('<div class="tabContent tabVersion" style="text-indent: 20px">');
    html.push('<h4 style="font-size:18px; font-weight:bold; margin: 0px; line-height: 26px; border-bottom: 1px dotted #ccc;">12306 订票助手  (猎豹浏览器专版) <small>ver ' + window.helperVersion + '</small></h4>');
    html.push('<p> 12306 订票助手(猎豹浏览器专版)是一款用于订票的助手软件,专门为猎豹浏览器定制,无需注册。希望在快速的猎豹浏览器的支持下,诸位客官能用得更加顺手 =。= <strong>助手完全免费,无需付费使用,仅接受捐助。</strong> </p>');
    html.push('<p style="color: red;"> <strong style="font-size:16px;">啊嘞……看这里!本助手完全免费啊诸位大人!猎豹浏览器也是免费的啊!!</strong>任何在第三方网站上打包出售的软件全他喵的是侵权出售啊!!看到的时候请亲务必记得退款退货打差评向青天大老爷举报啊!!</p>');
    html.push('<p style="color:purple;"> 回家是一个单纯而简单的心愿,希望我们不会变得太复杂……</p>');
    html.push('<p> 有很多朋友资助作者,正在木有暖气的南方饱受煎熬的作者感激涕零 ≥ω≤。<a href="http://www.fishlee.net/soft/44/donate.html" target="_blank">戳这里了解捐助详情</a>。 </p>');
    html.push('<p style="color: blue;"> <strong style="">那个,诸位票贩子们,放过本助手吧!!你们都去用什么自动识别验证码的好啦!还有铁道部的爷爷们,拜托你们改进下的用户体验吧!你们的订票足够好用的话虽还来用脚本啊!!!!</strong></p>');
    html.push('<p style="font-weight:bold;">当前版本更新内容</p>');
    html.push('<ol>');
    $.each(utility.getPref("updates").split('\t'), function (i, n) {
        html.push("<li style='padding-left:20px;list-style:disc inside;'>" + n + "</li>");
    });
    html.push('</ol>');
    html.push('</div>');
    html.push('<div class="tabContent tabFaq">');
    html.push('<table>');
    html.push('<tr>');
    html.push('<td colspan="4"> 你在订票过程中可能……会遇到各种问题,由于介个12306网站本身呢……木有没有任何介绍 ╮(╯▽╰)╭ ,所以老衲整理了相关问题,供客官参考。如果还有不明白的问题,加群讨论呗  (= ̄ω ̄=) 。 <br /><br />');
    html.push('1.放票非正点也,So在将近放票的时候,务必保持刷新状态哈,而且……当整点没有放票时,不要放弃继续刷新喔;<br />\
2.动车都是11点放票撒,切记切记;<br />\
3.第一波放票悲催地木有订到时,请耐心等待,因为现在放票有N多节点,随时会有票出来,晚很久才放票也正常,铁老大经常秀下限嘀;<br />\
4.如果您的车票很难买,请尽量发动你的七大姑八大姨神马的一堆朋友过来集体帮忙,同时建议用多个浏览器刷票,因为缓存的关系不同的浏览器出现票的时间可能不同;<br />\
5.最新版3.9.0中的预先选择铺位功能有点淡化了……要用的话,使用优选席别,第一个优选的将会被自动选中 ^_^<br />\
<br />\
好了,废话说完鸟,祝大家买票顺利,贫僧只希望不会帮倒忙就好了 ╮(╯▽╰)╭<br />\
如果您还有问题的话,<a href="http://www.fishlee.net/soft/44/tour.html" target="_blank">建议点击这里查看教程~~~~</a>\
');
    html.push('</td></tr>');
    html.push('<tr style="display:none;">');
    html.push('<td><a href="http://www.fishlee.net/soft/44/12306faq.html" target="_blank">订票常见问题</a></td>');
    html.push('<td><a href="http://www.fishlee.net/soft/44/faq.html" target="_blank">助手运行常见问题</a></td>');
    html.push('</tr>');
    html.push('</table>');
    html.push('</div><div class="tabLog tabContent"><div>下面是当前页面的记录。如果您的助手遇到功能上的问题,请全部复制后发成邮件给作者:[email protected] 以便于老衲解决问题。<span style="color:red;font-weight:bold;">请在发送前务必剔除记录中包含的个人隐私如密码等信息。</span></div><textarea id="runningLog" style="width:100%;height:200px;"></textarea></div>');
    //获取登录到IE的代码 Add By XPHelper
    html.push('<div class="tabLoginIE tabContent"><div><strong>先在IE中打开 https://dynamic.12306.cn/otsweb,</strong>再将以下代码复制到IE浏览器的地址栏。确认地址栏最前面有“javascript:”字样,没有请手动加上(IE10会自动删除这样的代码),然后敲回车,等待页面刷新后,即可自动登录。</div><textarea id="LoginIECode" style="width:100%;height:200px;"></textarea></div>');
    html.push('<div class="control">');
    html.push('<input type="button" class="close_button" value="关闭" />');
    html.push('</div>');
    html.push('</div>');
    html.push('</div>');
 
    $("body").append(html.join(""));
 
    var opt = $("#fishOption");
    $("#regButton").click(function () {
        var sn = $.trim($("#regContent").val());
 
        var rt = utility.verifySn(false, "", sn);
        if (rt.result != 0) {
            alert("很抱歉, 注册失败. 代码 " + rt.result + ", " + rt.msg);
        } else {
            utility.setSnInfo("", sn);
            alert("注册成功, 请刷新浏览器。\n注册给 - " + rt.name + " , 注册类型 - " + rt.typeDesc.replace(/<[^>]*>/gi, ""));
 
            try {
                utility.getTopWindow().location.reload();
            } catch (e) {
                alert("权限不足无法刷新页面, 请手动刷新当前页!");
            }
        }
    });
    $("#unReg, a.reSignHelper").live("click", function () {
        if (utility.regInfo.result == 0) {
            if (!confirm("确定要重新注册吗?")) return;
 
            utility.setSnInfo("", "");
            utility.getTopWindow().location.reload();
        } else {
            utility.getTopWindow().utility.showOptionDialog("tabReg");
        }
    });
 
    //初始化设置
    utility.configTab = utility.fishTab(opt);
    opt.find("input[name]").each(function () {
        var el = $(this);
        var key = el.attr("name");
        var value = window.localStorage.getItem(key);
        if (!value) return;
 
        if (el.attr("type") == "checkbox") {
            el.attr("checked", value == "1");
        } else {
            el.val(value);
        }
    }).change(function () {
        var el = $(this);
        var key = el.attr("name");
 
        if (el.attr("type") == "checkbox") {
            window.localStorage.setItem(key, el[0].checked ? 1 : 0);
        } else {
            window.localStorage.setItem(key, el.val());
        }
    });
    $("#configLink, .configLink").live("click", function () {
        var el = $(this);
        var dp = el.attr("tab");
 
        utility.getTopWindow().utility.showLoginIE();
        utility.getTopWindow().utility.showOptionDialog(dp || "");
    });
    //新版本更新显示提示
    if (utility.getPref("helperVersion") != window.helperVersion) {
 
        //检测老版本设置
        if (utility.getAudioUrl().indexOf("github") != -1 || utility.getAudioUrl().indexOf("resbak.") != -1) {
            utility.resetAudioUrl();
        }
 
        utility.setPref("helperVersion", window.helperVersion);
        //仅顶层页面显示
        try {
            if (parent == self)
                utility.showOptionDialog("tabVersion");
        } catch (ex) {
            //跨域了,也是顶级
            utility.showOptionDialog("tabVersion");
        }
    }
 
    //注册
    var result = utility.verifySn(true);
    if (result.result == 0) {
        var info = opt.find(".registered").show().find("strong");
        info.eq(0).html(result.name);
        info.eq(1).html(result.typeDesc);
 
 
    } else {
        opt.find(".regTable").show();
    }
    utility.regInfo = result;
}
 
//#endregion
 
//#region -----------------执行环境兼容----------------------
 
var utility = {
    configTab: null,
    icon: "http://www.12306.cn/mormhweb/images/favicon.ico",
    notifyObj: null,
    timerObj: null,
    regInfo: null,
    isWebKit: function () {
        return navigator.userAgent.indexOf("WebKit") != -1;
    },
    trim: function (data) {
        if (typeof ($) != 'undefined') return $.trim(data);
 
        return data.replace(/(^\s+|\s+$)/g, "");
    },
    getTopWindow: function () {
        try {
            if (parent == self) return self;
            else return parent.window.utility.getTopWindow();
        } catch (e) {
            //跨域的话,也是顶层
            return self;
        }
    },
    init: function () {
        $.extend({
            any: function (array, callback) {
                var flag = false;
                $.each(array, function (i, v) {
                    flag = callback.call(this, i, v);
                    if (flag) return false;
                });
                return flag;
            },
            first: function (array, callback) {
                var result = null;
                $.each(array, function (i, v) {
                    result = callback.call(this, i, v);
                    if (result) return false;
                });
                return result;
            }
        });
        (function (n) { var t = /["\\\x00-\x1f\x7f-\x9f]/g, i = { "\b": "\\b", "\t": "\\t", "\n": "\\n", "\f": "\\f", "\r": "\\r", '"': '\\"', "\\": "\\\\" }, r = Object.prototype.hasOwnProperty; n.toJSON = typeof JSON == "object" && JSON.stringify ? JSON.stringify : function (t) { var i, a, l, v, p, y, f; if (t === null) return "null"; if (i = typeof t, i === "undefined") return undefined; if (i === "number" || i === "boolean") return "" + t; if (i === "string") return n.quoteString(t); if (i === "object") { if (typeof t.toJSON == "function") return n.toJSON(t.toJSON()); if (t.constructor === Date) { var e = t.getUTCMonth() + 1, o = t.getUTCDate(), w = t.getUTCFullYear(), s = t.getUTCHours(), h = t.getUTCMinutes(), c = t.getUTCSeconds(), u = t.getUTCMilliseconds(); return e < 10 && (e = "0" + e), o < 10 && (o = "0" + o), s < 10 && (s = "0" + s), h < 10 && (h = "0" + h), c < 10 && (c = "0" + c), u < 100 && (u = "0" + u), u < 10 && (u = "0" + u), '"' + w + "-" + e + "-" + o + "T" + s + ":" + h + ":" + c + "." + u + 'Z"' } if (t.constructor === Array) { for (a = [], l = 0; l < t.length; l++) a.push(n.toJSON(t[l]) || "null"); return "[" + a.join(",") + "]" } y = []; for (f in t) if (r.call(t, f)) { if (i = typeof f, i === "number") v = '"' + f + '"'; else if (i === "string") v = n.quoteString(f); else continue; (i = typeof t[f], i !== "function" && i !== "undefined") && (p = n.toJSON(t[f]), y.push(v + ":" + p)) } return "{" + y.join(",") + "}" } }, n.evalJSON = typeof JSON == "object" && JSON.parse ? JSON.parse : function (src) { return eval("(" + src + ")") }, n.secureEvalJSON = typeof JSON == "object" && JSON.parse ? JSON.parse : function (src) { var filtered = src.replace(/\\["\\\/bfnrtu]/g, "@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]").replace(/(?:^|:|,)(?:\s*\[)+/g, ""); if (/^[\],:{}\s]*$/.test(filtered)) return eval("(" + src + ")"); throw new SyntaxError("Error parsing JSON, source is not valid."); }, n.quoteString = function (n) { return n.match(t) ? '"' + n.replace(t, function (n) { var t = i[n]; return typeof t == "string" ? t : (t = n.charCodeAt(), "\\u00" + Math.floor(t / 16).toString(16) + (t % 16).toString(16)) }) + '"' : '"' + n + '"' } })(jQuery)
    },
    runningQueue: null,
    appendLog: function (settings) {
        /// <summary>记录日志</summary>
        if (!utility.runningQueue) utility.runningQueue = [];
        var log = { url: settings.url, data: settings.data, response: null, success: null };
        if (log.url.indexOf("Passenger") != -1) return;    //不记录对乘客的请求
 
        utility.runningQueue.push(log);
        settings.log = log;
    },
    showLog: function () {
        if (!utility.runningQueue) {
            alert("当前页面尚未产生日志记录。");
            return;
        }
 
        var log = [];
        $.each(utility.runningQueue, function () {
            log.push("成功:" + (this.success ? "" : "") + "\r\n地址:" + this.url + "\r\n提交数据:" + utility.formatData(this.data) + "\r\n返回数据:" + utility.formatData(this.response));
        });
        $("#runningLog").val(log.join("\r\n----------------------------------\r\n"));
 
        utility.showOptionDialog("tabLog");
    },
    //获取登录到IE的代码 Add By XPHelper
    showLoginIE: function () {
        var strCookie = document.cookie;
        var arrCookie = strCookie.split("; ");
        var IECode = "javascript:";
        var cookie = [];
        for (var i = 0; i < arrCookie.length; i++) {
            var arr = arrCookie[i].split("=");
            if (arr.length < 2 || arr[0].indexOf("helper.") != -1) continue;
            cookie.push("document.cookie=\"" + arr[0] + "=" + arr[1] + "\";");
        }
        IECode += cookie.join("");
        IECode += "self.location.reload();";
        $("#LoginIECode").val(IECode);
    },
    formatData: function (data) {
        if (!data) return "(null)";
        if (typeof (data) == "string") return data;
        var html = [];
        for (var i in data) {
            html.push('"' + i + '":\"' + (this[i] + "").replace(/(\r|\n|")/g, function (a) { "\\" + a; }) + '\"');
        }
        return "{" + html.join(",") + "}";
    },
    notify: function (msg, timeout) {
        console.log("信息提示: " + msg);
        if (window.webkitNotifications) {
            if (window.webkitNotifications.checkPermission() == 0) {
                utility.closeNotify();
 
                if (utility.notifyObj == null)
                    utility.notifyObj = webkitNotifications.createNotification(utility.icon, '订票', msg);
                utility.notifyObj.show();
                if (!timeout || timeout != 0) utility.timerObj = setTimeout(utility.closeNotify, timeout || 5000);
            } else {
                alert("【啊喂!!桌面通知还木有开启!请戳界面中的『点击启用桌面通知』按钮来开启!】\n\n" + msg);
            }
        } else {
            if (typeof (GM_notification) != 'undefined') {
                GM_notification(msg);
            } else {
                console.log("主页面中脚本信息, 无法提示, 写入通知区域.");
                utility.notifyOnTop(msg);
            }
        }
    },
    notifyOnTop: function (msg) {
        window.localStorage.setItem("notify", msg);
    },
    closeNotify: function () {
        if (!utility.notifyObj) return;
 
        utility.notifyObj.cancel();
        if (utility.timerObj) {
            clearTimeout(utility.timerObj);
        }
        utility.timerObj = null;
        utility.notifyObj = null;
    },
    setPref: function (name, value) {
        window.localStorage.setItem(name, value);
    },
    getPref: function (name) {
        return window.localStorage.getItem(name);
    },
    unsafeCallback: function (callback) {
        if (typeof (unsafeInvoke) == "undefined") callback();
        else unsafeInvoke(callback);
    },
    getTimeInfo: function () {
        var d = new Date();
        return d.getHours() + ":" + (d.getMinutes() < 10 ? "0" : "") + d.getMinutes() + ":" + (d.getSeconds() < 10 ? "0" : "") + d.getSeconds();
    },
    savePrefs: function (obj, prefix) {
        var objs = obj.find("input");
        objs.change(function () {
            var type = this.getAttribute("type");
            if (type == "text") utility.setPref(prefix + "_" + this.getAttribute("id"), $(this).val());
            else if (type == "checkbox") utility.setPref(prefix + "_" + this.getAttribute("id"), this.checked ? 1 : 0);
        })
    },
    reloadPrefs: function (obj, prefix) {
        var objs = obj.find("input");
        prefix = prefix || "";
        objs.each(function () {
            var e = $(this);
            var type = e.attr("type");
            var id = e.attr("id");
            var value = utility.getPref(prefix + "_" + id);
            if (typeof (value) == "undefined" || value == null) return;
 
            if (type == "text") e.val(value);
            else if (type == "checkbox") this.checked = value == "1";
            e.change();
        });
        utility.savePrefs(obj, prefix);
    },
    getErrorMsg: function (msg) {
        /// <summary>获得给定信息中的错误信息</summary>
        var m = msg.match(/var\s+message\s*=\s*"([^"]*)/);
        return m && m[1] ? m[1] : "&lt;未知信息&gt;";
    },
    delayInvoke: function (target, callback, timeout) {
        target = target || "#countEle";
        var e = typeof (target) == "string" ? $(target) : target;
        if (timeout <= 0) {
            e.html("正在执行").removeClass("fish_clock").addClass("fish_running");
            callback();
        } else {
            var str = (Math.floor(timeout / 100) / 10) + '';
            if (str.indexOf(".") == -1) str += ".0";
            e.html(str + " 秒后再来!...").removeClass("fish_running").addClass("fish_clock");
            setTimeout(function () {
                utility.delayInvoke(target, callback, timeout - 500);
            }, 500);
        }
    },
    saveList: function (name) {
        /// <summary>将指定列表的值保存到配置中</summary>
        var dom = document.getElementById(name);
        window.localStorage["list_" + name] = utility.getOptionArray(dom).join("\t");
    },
    loadList: function (name) {
        /// <summary>将指定的列表的值从配置中加载</summary>
        var dom = document.getElementById(name);
        var data = window.localStorage["list_" + name];
        if (!data) return;
 
        if (data.indexOf("\t") != -1)
            data = data.split('\t');
        else data = data.split('|');
        $.each(data, function () {
            dom.options[dom.options.length] = new Option(this, this);
        });
    },
    addOption: function (dom, text, value) {
        /// <summary>在指定的列表中加入新的选项</summary>
        dom.options[dom.options.length] = new Option(text, value);
    },
    getOptionArray: function (dom) {
        /// <summary>获得选项的数组格式</summary>
        return $.map(dom.options, function (o) { return o.value; });
    },
    inOptionList: function (dom, value) {
        /// <summary>判断指定的值是否在列表中</summary>
        for (var i = 0; i < dom.options.length; i++) {
            if (dom.options[i].value == value) return true;
        }
        return false;
    },
    getAudioUrl: function () {
        /// <summary>获得音乐地址</summary>
        return window.localStorage["audioUrl"] || (navigator.userAgent.indexOf("Firefox") != -1 ? "http://static.liebao.cn/resources/audio/song.ogg" : "http://static.liebao.cn/resources/audio/song.ogg");
    },
    getFailAudioUrl: function () {
        return (utility.isWebKit() ? "http://static.liebao.cn/resources/audio/" : "http://static.liebao.cn/resources/audio/") + "music3.ogg";
    },
    playFailAudio: function () {
        if (!window.Audio) return;
        new Audio(utility.getFailAudioUrl()).play()
    },
    resetAudioUrl: function () {
        /// <summary>恢复音乐地址为默认</summary>
        window.localStorage.removeItem("audioUrl");
    },
    parseDate: function (s) { /(\d{4})[-/](\d{1,2})[-/](\d{1,2})/.exec(s); return new Date(RegExp.$1, RegExp.$2 - 1, RegExp.$3); },
    getDate: function (s) {
        /// <summary>获得指定日期的天单位</summary>
        return new Date(s.getFullYear(), s.getMonth(), s.getDate());
    },
    formatDate: function (d) {
        /// <summary>格式化日期</summary>
        var y = d.getFullYear();
 
        return y + "-" + utility.formatDateShort(d);
    },
    formatDateShort: function (d) {
        /// <summary>格式化日期</summary>
        var mm = d.getMonth() + 1;
        var d = d.getDate();
 
        return (mm > 9 ? mm : "0" + mm) + "-" + (d > 9 ? d : "0" + d);
    },
    formatTime: function (d) {
        function padTo2Digit(digit) {
            return digit < 10 ? '0' + digit : digit;
        }
        return utility.formatDate(d) + " " + padTo2Digit(d.getHours()) + ":" + padTo2Digit(d.getMinutes()) + ":" + padTo2Digit(d.getSeconds());
    },
    addTimeSpan: function (date, y, mm, d, h, m, s) {
        /// <summary>对指定的日期进行偏移</summary>
        return new Date(date.getFullYear() + y, date.getMonth() + mm, date.getDate() + d, date.getHours() + h, date.getMinutes() + m, date.getSeconds() + s);
    },
    serializeForm: function (form) {
        /// <summary>序列化表单为对象</summary>
        var v = {};
        var o = form.serializeArray();
        for (var i in o) {
            if (typeof (v[o[i].name]) == 'undefined') v[o[i].name] = o[i].value;
            else v[o[i].name] += "," + o[i].value;
        }
        return v;
    },
    getSecondInfo: function (second) {
        var show_time = "";
        var hour = parseInt(second / 3600);  //时
        if (hour > 0) {
            show_time = hour + "小时";
            second = second % 3600;
        }
        var minute = parseInt(second / 60);  //分
        if (minute >= 1) {
            show_time = show_time + minute + "分";
            second = second % 60;
        } else if (hour >= 1 && second > 0) {
            show_time = show_time + "0分";
        }
        if (second > 0) {
            show_time = show_time + second + "秒";
        }
 
        return show_time;
    },
    post: function (url, data, dataType, succCallback, errorCallback) {
        $.ajax({
            url: url,
            data: data,
            timeout: 10000,
            type: "POST",
            success: succCallback,
            error: errorCallback,
            dataType: dataType
        });
    },
    get: function (url, data, dataType, succCallback, errorCallback) {
        $.ajax({
            url: url,
            data: data,
            timeout: 10000,
            type: "GET",
            success: succCallback,
            error: errorCallback,
            dataType: dataType
        });
    },
    showDialog: function (object, optx) {
        /// <summary>显示对话框。其中带有 close_button 样式的控件会自动作为关闭按钮</summary>
        return (function (opt) {
            var dataKey = "fs_dlg_opt";
            if (this.data(dataKey)) {
                //this.data(dataKey).closeDialog();
                return;
            }
 
            opt = $.extend({ bindControl: null, removeDialog: this.attr("autoCreate") == "1", onClose: null, animationMove: 20, speed: "fast", fx: "linear", show: "fadeInDown", hide: "fadeOutUp", onShow: null, timeOut: 0 }, opt);
            this.data("fs_dlg_opt", opt);
            var top = "0px";
            var left = "50%";
 
            this.css({
                "position": opt.parent ? "absolute" : "fixed",
                "left": left,
                "top": top,
                "margin-left": "-" + (this.width() / 2) + "px",
                "margin-top": "0px",
                "z-index": "9999"
            });
            var obj = this;
            this.changeLoadingIcon = function (icon) {
                /// <summary>更改加载对话框的图标</summary>
                obj.removeClass().addClass("loadingDialog loadicon_" + (icon || "tip"));
                return obj;
            };
            this.autoCloseDialog = function (timeout) {
                /// <summary>设置当前对话框在指定时间后自动关闭</summary>
                setTimeout(function () { obj.closeDialog(); }, timeout || 2500);
                return obj;
            };
            this.setLoadingMessage = function (msgHtml) {
                obj.find("div").html(msgHtml);
                return obj;
            };
            this.closeDialog = function () {
                /// <summary>关闭对话框</summary>
                obj.removeData(dataKey);
                obj.animate({ "marginTop": "+=" + opt.animationMove + "px", "opacity": "hide" }, opt.speed, opt.fx, function () {
                    if (opt.bindControl) opt.bindControl.enable();
                    if (opt.onClose) opt.onClose.call(obj);
                    if (opt.removeDialog) obj.remove();
                })
 
                return obj;
            };
            $('.close_button', this).unbind("click").click(obj.closeDialog);
            //auto close
            if (opt.timeOut > 0) {
                var handler = opt.onShow;
                opt.onShow = function () {
                    setTimeout(function () { $(obj).closeDialog(); }, opt.timeOut);
                    if (handler != null) handler.call(this);
                };
            }
            //show it
            if (opt.bindControl) opt.bindControl.disable();
            this.animate({ "marginTop": "+=" + opt.animationMove + "px", "opacity": "show" }, opt.speed, opt.fx, function () { opt.onShow && opt.onShow.call(obj); })
            this.data(dataKey, this);
 
            return this;
        }).call(object, optx);
    },
    fishTab: function (obj, opt) {
        return (function (opt) {
            var self = this;
            opt = $.extend({ switchOnHover: false, switchOnClick: true }, opt);
            this.addClass("fishTab");
 
 
            this.showTab = function (tabid) {
                self.find(".current").removeClass("current");
                self.find("ul.tabNav li[tab=" + tabid + "], div." + tabid).addClass("current");
            };
            self.find(".tabNav li").hover(function () {
                if (!opt.switchOnHover) return;
                self.showTab($(this).attr("tab"));
            }).click(function () {
                if (!opt.switchOnClick) return;
                self.showTab($(this).attr("tab"));
            });
            this.showTab(self.find(".tabNav").attr("default") || self.find(".tabNav li:eq(0)").attr("tab"));
 
            return this;
        }).call(obj, opt);
    },
    getLoginRetryTime: function () {
        return parseInt(window.localStorage.getItem("login.retryLimit")) || 2000;
    },
    showOptionDialog: function (tab) {
        if (tab) utility.configTab.showTab(tab);
        utility.showDialog($("#fishOption"));
    },
    addCookie: function (name, value, expDays) {
        var cook = name + "=" + value + "; path=/; domain=.12306.cn";
        if (expDays > 0) {
            cook += "; expires=" + new Date(new Date().getTime() + expDays * 3600 * 1000 * 24).toGMTString();
        }
        document.cookie = cook;
    },
    getCookie: function (name) {
        var cook = document.cookie;
        var arr = cook.split("; ");
        for (var i = 0; i < arr.length; i++) {
            var arg = arr[i].split('=');
            if (arg[0] == name) return arg[1];
        }
    },
    setSnInfo: function (name, sn) {
        utility.setPref("helper.regUser", name);
        utility.setPref("helper.regSn", sn);
        utility.addCookie("helper.regUser", name, 999);
        utility.addCookie("helper.regSn", sn, 999);
    },
    verifySn: function (skipTimeVerify, name, sn) {
        name = name || utility.getPref("helper.regUser") || utility.getCookie("helper.regUser");
        sn = sn || utility.getPref("helper.regSn") || utility.getCookie("helper.regSn");
        if (!name && sn) return utility.verifySn2(skipTimeVerify, sn);
        if (!name || !sn) return { result: -4, msg: "未注册", name: "猎豹浏览器用户", typeDesc: "正式版" };
 
        utility.setSnInfo(name, sn);
 
        var args = sn.split(',');
        if (!skipTimeVerify) {
            if ((new Date() - args[0]) / 60000 > 5) {
                return { result: -1, msg: "序列号注册已失效" };
            }
        }
        var dec = [];
        var encKey = args[0] + args[1];
        var j = 0;
        for (var i = 0; i < args[2].length; i += 4) {
            dec.push(String.fromCharCode(parseInt(args[2].substr(i, 4), 16) ^ encKey.charCodeAt(j)));
            j++;
            if (j >= encKey.length) j = 0;
        }
        var data = dec.join("");
        data = { result: null, type: data.substring(0, 4), name: data.substring(4) };
        data.result = data.name == name ? 0 : -3;
        data.msg = data.result == 0 ? "成功验证" : "注册无效"
        data.typeDesc = data.type == "NRML" ? "正式版" : (data.type == "GROP" ? "内部版, <span style='color:blue;'>感谢您参与我们之中</span>!" : "<span style='color:red;'>捐助版, 非常感谢您的支持</span>!");
 
        return data;
    },
    verifySn2: function (skipTimeVerify, data) {
        data = utility.trim(data);
        try {
            var nameLen = parseInt(data.substr(0, 2), 16);
            var name = data.substr(2, nameLen);
            data = data.substring(2 + nameLen);
 
            var arr = [];
            for (var i = 0; i < data.length; i++) {
                var c = data.charCodeAt(i);
                if (c >= 97) arr.push(String.fromCharCode(c - 49));
                else arr.push(data.charAt(i));
            }
            data = arr.join("");
            var ticket = parseInt(data.substr(0, 14), 16);
            var key = parseInt(data.substr(14, 1), 16);
            var encKey = ticket.toString(16).toUpperCase() + key.toString().toUpperCase();
            data = data.substring(15);
            var dec = [];
            var j = 0;
            for (var i = 0; i < data.length; i += 4) {
                dec.push(String.fromCharCode(parseInt(data.substr(i, 4), 16) ^ encKey.charCodeAt(j)));
                j++;
                if (j >= encKey.length) j = 0;
            }
            dec = dec.join("").split('|');
            var regVersion = dec[0].substr(0, 4);
            var regName = dec[0].substring(4);
            var bindAcc = dec.slice(1, dec.length);
 
            if (!bindAcc && !skipTimeVerify && (new Date() - ticket) / 60000 > 5) {
                return { result: -1, msg: "注册码已失效, 请重新申请" };
            }
            if (regName != name) {
                return { result: -3, msg: "注册失败,用户名不匹配" };
            }
            var data = { name: name, type: regVersion, bindAcc: bindAcc, ticket: ticket, result: 0, msg: "成功注册" };
            switch (data.type) {
                case "NRML": data.typeDesc = "正式版"; break;
                case "GROP": data.typeDesc = "内部版, <span style='color:blue;'>感谢您参与我们之中</span>!"; break;
                case "DONT": data.typeDesc = "<span style='color:red;'>捐助版, 非常感谢您的支持</span>!"; break;
                case "PART": data.typeDesc = "合作版,欢迎您的使用";
            }
            data.regTime = new Date(ticket);
            data.regVersion = 2;
 
            return data;
        } catch (e) {
            return { result: -4, msg: "数据错误" };
        }
    },
    allPassengers: null,
    getAllPassengers: function (callback, ignoreLocalCache) {
        if (!utility.allPassengers && window.localStorage["pas"] && !ignoreLocalCache) {
            utility.allPassengers = eval("(" + window.localStorage["pas"] + ")");
        }
        if (utility.allPassengers) {
            callback(utility.allPassengers);
            return;
        }
 
        var tw = utility.getTopWindow();
        if (tw != self) return tw.utility.getAllPassengers(callback, ignoreLocalCache);
 
        //开始加载所有乘客
        utility.allPassengers = [];
        var pageIndex = 0;
 
        function loadPage() {
            utility.post("/otsweb/passengerAction.do?method=getPagePassengerAll", { pageSize: 10, pageIndex: pageIndex }, "json", function (json) {
                $.each(json.rows, function () { utility.allPassengers.push(this); });
 
                if (utility.allPassengers.length >= json.recordCount) {
                    callback(utility.allPassengers);
                } else {
                    pageIndex++;
                    setTimeout(loadPage, 1000);
                }
            }, function () {
                setTimeout(loadPage, 3000);
            });
        }
 
        loadPage();
    },
    regCache: {},
    getRegCache: function (value) {
        return utility.regCache[value] || (utility.regCache[value] = new RegExp("^(" + value + ")$", "i"));
    },
    preCompileReg: function (optionList) {
        var data = $.map(optionList, function (e) {
            return e.value;
        });
        return new RegExp("^(" + data.join("|") + ")$", "i");
    },
    enableLog: function () {
        $("body").append('<button style="width:100px;position:fixed;right:0px;top:0px;height:35px;" onclick="utility.showLog();">显示运行日志</button>');
        $(document).ajaxSuccess(function (a, b, c) {
            if (!c.log) return;
            c.log.response = b.responseText;
            c.log.success = true;
        }).ajaxSend(function (a, b, c) {
            utility.appendLog(c);
        }).ajaxError(function (a, b, c) {
            if (!c.log) return;
            c.log.response = b.responseText;
        });
    },
    //获取登录到IE的代码 Add By XPHelper
    enableLoginIE: function () {
        $("body").append('<button style="width:150px;position:fixed;right:0px;top:0px;height:35px;" class="configLink" tab="tabLoginIE">获取登录到IE的代码</button>');
    },
    analyzeForm: function (html) {
        var data = {};
 
        //action
        var m = /<form.*?action="([^"]+)"/.exec(html);
        data.action = m ? RegExp.$1 : "";
 
        //inputs
        data.fields = {};
        var inputs = html.match(/<input\s*(.|\r|\n)*?>/gi);
        $.each(inputs, function () {
            if (!/name=['"]([^'"]+?)['"]/.exec(this)) return;
            var name = RegExp.$1;
            data.fields[RegExp.$1] = !/value=['"]([^'"]+?)['"]/.exec(this) ? "" : RegExp.$1;
        });
 
        //tourflag
        m = /submit_form_confirm\('confirmPassenger','([a-z]+)'\)/.exec(html);
        if (m) data.tourFlag = RegExp.$1;
 
        return data;
    },
    selectionArea: function (opt) {
        var self = this;
        this.options = $.extend({ onAdd: function () { }, onRemove: function () { }, onClear: function () { }, onRemoveConfirm: function () { return true; }, syncToStorageKey: "", defaultList: null, preloadList: null }, opt);
        this.append('<div style="padding: 5px; border: 1px dashed gray; background-color: rgb(238, 238, 238); width:120px;">(还没有添加任何项)</div>');
        this.datalist = [];
 
        this.add = function (data) {
            if ($.inArray(data, self.datalist) > -1) return;
 
            var text = typeof (data) == "string" ? data : data.text;
 
            var html = $('<input type="button" class="lineButton" value="' + text + '" title="点击删除" />');
            self.append(html);
            html.click(self.removeByButton);
            self.datalist.push(data);
            self.syncToStorage();
            self.checkEmpty();
            self.options.onAdd.call(self, data, html);
        };
 
        this.removeByButton = function () {
            var obj = $(this);
            var idx = obj.index() - 1;
            var value = self.datalist[idx];
 
            if (!self.options.onRemoveConfirm.call(self, value, obj, idx)) {
                return;
            }
 
            obj.remove();
            self.datalist.splice(idx, 1);
            self.syncToStorage();
            self.checkEmpty();
            self.options.onRemove.call(self, value, obj);
        };
 
        this.emptyList = function () {
            self.datalist = [];
            self.find("input").remove();
            self.syncToStorage();
            self.checkEmpty();
            self.options.onClear.call(self);
        };
 
        this.isInList = function (data) {
            /// <summary>判断指定的值是否在列表中</summary>
            return $.inArray($.inArray(data, self.datalist)) > -1;
        };
 
        this.isInRegList = function (data) {
            /// <summary>判断指定的值是否在列表中。这里假定是字符串,使用正则进行判断</summary>
            for (var i = 0; i < self.datalist.length; i++) {
                if (utility.getRegCache(self.datalist[i]).test(data)) return true;
            }
            return false;
        };
 
        this.syncToStorage = function () {
            if (!self.options.syncToStorageKey) return;
 
            window.localStorage.setItem(self.options.syncToStorageKey, self.datalist.join("\t"));
        };
 
        this.checkEmpty = function () {
            if (self.find("input").length) {
                self.find("div").hide();
            } else {
                self.find("div").show();
            }
        };
 
        if (self.options.syncToStorageKey) {
            var list = self.options.preloadList;
            if (!list) {
                var list = window.localStorage.getItem(this.options.syncToStorageKey);
                if (!list) list = this.options.defaultList;
                else list = list.split('\t');
            }
 
            if (list) {
                $.each(list, function () { self.add(this + ""); });
            }
        }
 
        return this;
    },
    getUpdateUrl: function () {
        return "http://static.liebao.cn/_softdownload/12306_ticket_helper_for_liebaobrowser.crx";
    }
}
 
function unsafeInvoke(callback) {
    /// <summary>非沙箱模式下的回调</summary>
    var cb = document.createElement("script");
    cb.type = "text/javascript";
    cb.textContent = buildCallback(callback);
    document.head.appendChild(cb);
}
 
function buildCallback(callback) {
    var content = "";
    if (!utility_emabed) {
        content += "window.helperVersion='" + version + "'; if(typeof(window.utility)!='undefined' && navigator.userAgent.indexOf('Maxthon')==-1){ alert('我勒个去! 检测到您似乎同时运行了两只助手! 请转到『附加组件管理『(Firefox)或『扩展管理』(Chrome)中卸载老版本的助手!');}; \r\nwindow.utility=" + buildObjectJavascriptCode(utility) + "; window.utility.init();\r\n";
        utility_emabed = true;
    }
    content += "window.__cb=" + buildObjectJavascriptCode(callback) + ";\r\n\
    if(typeof(jQuery)!='undefined')window.__cb();\r\n\
    else{\
        var script=document.createElement('script');\r\nscript.src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js';\r\n\
        script.type='text/javascript';\r\n\
        script.addEventListener('load', window.__cb);\r\n\
        document.head.appendChild(script);\r\n\
    }";
 
    return content;
}
 
function buildObjectJavascriptCode(object) {
    /// <summary>将指定的Javascript对象编译为脚本</summary>
    if (!object) return null;
 
    var t = typeof (object);
    if (t == "string") {
        return "\"" + object.replace(/(\r|\n|\\)/gi, function (a, b) {
            switch (b) {
                case "\r":
                    return "\\r";
                case "\n":
                    return "\\n";
                case "\\":
                    return "\\\\";
            }
        }) + "\"";
    }
    if (t != "object") return object + "";
 
    var code = [];
    for (var i in object) {
        var obj = object[i];
        var objType = typeof (obj);
 
        if ((objType == "object" || objType == "string") && obj) {
            code.push(i + ":" + buildObjectJavascriptCode(obj));
        } else {
            code.push(i + ":" + obj);
        }
    }
 
    return "{" + code.join(",") + "}";
}
 
var isChrome = navigator.userAgent.indexOf("AppleWebKit") != -1;
var isFirefox = navigator.userAgent.indexOf("Firefox") != -1;
 
if (location.host == "dynamic.12306.cn" || (location.host == "www.12306.cn" && location.protocol == "https:")) {
 
    //记录更新
    utility.setPref("updates", updates.join("\t"));
    initUIDisplay();
    unsafeInvoke(injectDom);
    entryPoint();
}
 
//#endregion
 
//#region -----------------入口----------------------
 
function entryPoint() {
    var location = window.location;
    var path = location.pathname;
 
    utility.regInfo = utility.verifySn(true);
 
    //
    unsafeInvoke(autoReloadIfError);
    if ((path == "/otsweb/loginAction.do" && location.search != '?method=initForMy12306') || path == "/otsweb/login.jsp") {
        //登录页
        unsafeInvoke(initLogin);
    }
    if (path == "/otsweb/order/querySingleAction.do") {
        if (location.search == "?method=init" && document.getElementById("submitQuery")) {
            unsafeInvoke(initTicketQuery);
            unsafeInvoke(initDirectSubmitOrder);
        }
        if (location.search == "?method=submutOrderRequest") {
            unsafeInvoke(initSubmitOrderQuest);
        }
    }
    if (path == "/otsweb/order/orderAction.do") {
        if (location.search.indexOf("method=cancelMyOrderNotComplete") != -1 && document.getElementById("submitQuery")) {
            unsafeInvoke(initTicketQuery);
            unsafeInvoke(initDirectSubmitOrder);
        }
    }
    if (path == "/otsweb/order/payConfirmOnlineSingleAction.do") {
        if (location.search.indexOf("method=cancelOrder") != -1 && document.getElementById("submitQuery")) {
            unsafeInvoke(initTicketQuery);
            unsafeInvoke(initDirectSubmitOrder);
        }
    }
    if (path == "/otsweb/order/myOrderAction.do") {
        if (location.search.indexOf("method=resign") != -1 && document.getElementById("submitQuery")) {
            unsafeInvoke(initTicketQuery);
            unsafeInvoke(initDirectSubmitOrder);
        }
    }
    if (path == "/otsweb/order/confirmPassengerAction.do") {
        if (location.search == "?method=init") {
            unsafeInvoke(initAutoCommitOrder);
            unsafeInvoke(autoCommitOrderInSandbox);
        }
        if (location.search.indexOf("?method=payOrder") != -1) {
            unsafeInvoke(initPagePayOrder);
            //获取登录到IE的代码 Add By XPHelper
            unsafeInvoke(utility.enableLoginIE);
        }
    }
    if (path == "/otsweb/order/myOrderAction.do") {
        if (location.search.indexOf("?method=laterEpay") != -1 || location.search.indexOf("?method=queryMyOrderNotComplete") != -1) {
            unsafeInvoke(initNotCompleteOrderPage);
            unsafeInvoke(initPayOrder);
            //获取登录到IE的代码 Add By XPHelper
            unsafeInvoke(utility.enableLoginIE);
        }
    }
    if (path == "/otsweb/passengerAction.do") {
        if (location.search.indexOf("?method=initUsualPassenger") != -1) {
            unsafeInvoke(storePasToLocal);
        }
    }
    if (path == "/otsweb/main.jsp" || path == "/otsweb/") {
        //主框架
        console.log("正在注入主框架脚本。");
 
        //跨页面弹窗提示,防止因为页面跳转导致对话框不关闭
        console.log("启动跨页面信息调用检查函数");
        window.setInterval(function () {
            var msg = window.localStorage["notify"];
            if (typeof (msg != 'undefined') && msg) {
                console.log("主窗口拦截提示请求: " + msg);
                window.localStorage.removeItem("notify");
                utility.notify(msg);
            }
        }, 100);
 
        unsafeInvoke(injectMainPageFunction);
    }
}
 
//#endregion
 
//#region 保存联系人
 
function storePasToLocal() {
    var isNew = !window.localStorage["pas"];
 
    utility.getAllPassengers(function (list) {
        window.localStorage.setItem("pas", $.toJSON(list));
 
        if (isNew) {
            alert("恭喜,联系人已经缓存到本地,现在可以去查票咯!");
            self.location = "/otsweb/order/querySingleAction.do?method=init";
        }
    }, true);
}
 
//#endregion
 
//#region 未完成订单查询页面
 
function initNotCompleteOrderPage() {
    return;
    //处理显示时间的
    (function () {
        var tagInputs = $("input[name=cache_tour_flag]");
        var flags = $.map(tagInputs, function (e, i) { return e.value; });
        $.each(flags, function () { $("#showTime_" + this).hide().after("<span id='status_" + this + "'>正在查询...</span>"); });
 
        function doCheck() {
            var flag = flags.shift();
            flags.push(flag);
 
            utility.get("https://dynamic.12306.cn/otsweb/order/myOrderAction.do?method=queryOrderWaitTime&tourFlag=" + flag, null, "json", function (data) {
                var obj = $("#status_" + flag);
                if (data.waitTime == 0 || data.waitTime == -1) {
                    obj.css({ "color": "green" }).html("订票成功!");
                    utility.notifyOnTop("订票成功!请尽快付款!");
                    parent.playAudio();
                    self.location.reload();
                    return;
                }
 
                if (data.waitTime == -2) {
                    utility.notifyOnTop("出票失败!请重新订票!" + data.msg);
                    parent.playFailAudio();
                    obj.css({ "color": "red" }).html("出票失败!" + data.msg);
 
                    return;
                }
                if (data.waitTime == -3) {
                    utility.notifyOnTop("订单已经被取消!");
                    parent.playFailAudio();
                    obj.css({ "color": "red" }).html("订单已经被取消!!");
 
                    return;
                }
                if (data.waitTime == -4) {
                    utility.notifyOnTop("正在处理中....");
                    obj.css({ "color": "blue" }).html("正在处理中....");
                }
 
                if (data.waitTime > 0) {
                    obj.css({ "color": "red" }).html("排队中<br />排队数【" + (data.waitCount || "未知") + "】<br />预计时间【" + utility.getSecondInfo(data.waitTime) + "】<br />不过这时间不<br />怎么靠谱 ╮(╯▽╰)╭");
                } else {
                    obj.css({ "color": "red" }).html("奇怪的状态码 [" + data.waitTime + "]....");
                }
 
 
                setTimeout(doCheck, 2000);
            }, function () {
                utility.notifyOnTop("查询状态错误,正在刷新页面!");
                self.location.reload();
            });
        }
 
        if (flags.length > 0) doCheck();
    })();
}
 
//#endregion
 
//#region 提交页面出错
 
function initSubmitOrderQuest() {
    if ($("div.error_text").length > 0) {
        parent.window.resubmitForm();
    }
}
 
//#endregion
 
//#region 订票页面,声音提示
 
function initPagePayOrder() {
    new Audio(utility.getAudioUrl()).play();
}
 
//#endregion
 
//#region -----------------出错自动刷新----------------------
 
function autoReloadIfError() {
    if ($.trim($("h1:first").text()) == "错误") {
        $("h1:first").css({ color: 'red', 'font-size': "18px" }).html("&gt;_&lt; 啊吖!,敢踹我出门啦。。。2秒后我一定会回来的 ╮(╯▽╰)╭");
        setTimeout(function () {
            self.location.reload();
        }, 2000);
    }
}
 
//#endregion
 
//#region -----------------主框架----------------------
 
function injectMainPageFunction() {
    //资源
    var main = $("#main")[0];
    main.onload = function () {
        var location = null;
        try {
            location = main.contentWindow.location + '';
        } catch (e) {
            //出错了,跨站
        }
        if (!location || location == "http://www.12306.cn/mormhweb/logFiles/error.html") {
            resubmitForm();
        }
    }
 
    if (window.webkitNotifications && window.webkitNotifications.checkPermission() != 0) {
        if (confirm("喂!快戳『点击启用桌面通知』,不然提示会阻碍操作,导致运行变慢,然后就没票了!\n\n如果是第一次看到介句话,点击『取消』并按提示操作。如果反复邂逅这个对话框,就戳『确定』以打开助手主页的常见问题并查找解决办法。\n\n搜狗高速浏览器暂不支持保存此权限,每次访问时可能都会邂逅这个对话框……")) {
            window.open("http://www.fishlee.net/soft/44/faq.html");
        }
    }
 
    window.resubmitForm = function () {
        var form = $("#orderForm");
        if (form.length == 0 || form.attr("success") != "0") return;
 
        utility.notify("页面出错了!正在重新预定!");
        setTimeout(function () { document.getElementById("orderForm").submit(); }, 3000);
    }
    window.playAudio = function () {
        new Audio(utility.getAudioUrl()).play();
    };
    window.playFailAudio = function () {
        utility.playFailAudio();
    };
}
 
//#endregion
 
//#region -----------------自动提交----------------------
function initAutoCommitOrder() {
    var count = 0;
    var breakFlag = 0;
    var randCode = "";
    var submitFlag = false;
    var tourFlag = 'dc';
    var randEl = $("#rand");
 
    //启用日志
    utility.enableLog();
 
    //#region 如果系统出错,那么重新提交
 
    if ($(".error_text").length > 0 && parent.$("#orderForm").length > 0) {
        parent.resubmitForm();
 
        return;
    }
 
    //#endregion
 
    //获得tourflag
    (function () {
        /'(dc|fc|wc|gc)'/.exec($("div.tj_btn :button:eq(2)")[0].onclick + '');
        tourFlag = RegExp.$1;
    })();
 
    function stop(msg) {
        setCurOperationInfo(false, "错误 - " + msg);
        setTipMessage(msg);
        $("div.tj_btn button, div.tj_btn input").each(function () {
            this.disabled = false;
            $(this).removeClass().addClass("long_button_u");
        });
        $("#btnCancelAuto").hide();
    }
 
    var reloadCode = function () {
        $("#img_rrand_code").click();
        $("#rand").val("")[0].select();
    };
 
    var getSleepTime = function () {
        return 1000 * Math.max(parseInt($("#pauseTime").val()), 1);
    };
 
    //订单等待时间过久的警告
    var waitTimeTooLong_alert = false;
 
    function submitForm() {
        randEl[0].blur();
        stopCheckCount();
        if (!window.submit_form_check || !submit_form_check("confirmPassenger")) {
            setCurOperationInfo(false, "您的表单没有填写完整!");
            stop("请填写完整表单");
            return;
        }
 
        count++;
        setCurOperationInfo(true, "第 " + count + " 次提交");
        if (breakFlag) {
            stop("已取消自动提交");
            breakFlag = 0;
            return;
        }
        $("#btnCancelAuto").show().removeClass().addClass("long_button_u_down")[0].disabled = false; //阻止被禁用
        breakFlag = 0;
        waitTimeTooLong_alert = false;
 
        $("#confirmPassenger").ajaxSubmit({
            url: 'confirmPassengerAction.do?method=checkOrderInfo&rand=' + $("#rand").val(),
            type: "POST",
            data: { tFlag: tourFlag },
            dataType: "json",
            timeout: 10000,
            success: function (data) {
                if ('Y' != data.errMsg || 'N' == data.checkHuimd || 'N' == data.check608) {
                    setCurOperationInfo(false, data.msg || data.errMsg);
                    stop(data.msg || data.errMsg);
                    reloadCode();
                }
                else {
                    queryQueueCount();
                }
            },
            error: function (msg) {
                setCurOperationInfo(false, "当前请求发生错误");
                utility.delayInvoke(null, submitForm, 1000);
            }
        });
    }
 
    function queryQueueCount() {
        var queryLeftData = {
            train_date: $("#start_date").val(),
            train_no: $("#train_no").val(),
            station: $("#station_train_code").val(),
            seat: $("#passenger_1_seat").val(),
            from: $("#from_station_telecode").val(),
            to: $("#to_station_telecode").val(),
            ticket: $("#left_ticket").val()
        };
        utility.get("/otsweb/order/confirmPassengerAction.do?method=getQueueCount", queryLeftData, "json", function (data) {
            console.log(data);
            if (data.op_2) {
                var errmsg = "排队人数过多,系统禁止排队,稍等自动重试 (排队人数=" + data.count + ")";
                setCurOperationInfo(true, errmsg);
                stop(errmsg);
 
                utility.delayInvoke(null, queryQueueCount, 1000);
 
 
                return;
            }
 
            setTimeout(submitConfirmOrder, 2000 + Math.random() * 1000);
        }, function () { utility.delayInvoke(null, queryLeftTickets, 2000); });
    }
 
    function submitConfirmOrder() {
        var url;
        if (tourFlag == 'dc') {
            // 异步下单-单程
            url = 'confirmPassengerAction.do?method=confirmSingleForQueueOrder';
        } else if (tourFlag == 'wc') {
            // 异步下单-往程
            url = 'confirmPassengerAction.do?method=confirmPassengerInfoGoForQueue';
        } else if (tourFlag == 'fc') {
            // 异步下单-返程
            url = 'confirmPassengerAction.do?method=confirmPassengerInfoBackForQueue';
        } else if (tourFlag == 'gc') {
            // 异步下单-改签
            url = 'confirmPassengerResignAction.do?method=confirmPassengerInfoResignForQueue';
        }
 
        jQuery.ajax({
            url: url,
            data: $('#confirmPassenger').serialize(),
            type: "POST",
            timeout: 10000,
            dataType: 'json',
            success: function (msg) {
                console.log(msg);
 
                var errmsg = msg.errMsg;
                if (errmsg != 'Y') {
                    if (errmsg.indexOf("包含未付款订单") != -1) {
                        alert("您有未支付订单! 等啥呢, 赶紧点确定支付去.");
                        window.location.replace("/otsweb/order/myOrderAction.do?method=queryMyOrderNotComplete&leftmenu=Y");
                        return;
                    }
                    if (errmsg.indexOf("重复提交") != -1) {
                        stop("重复提交错误,已刷新TOKEN,请重新输入验证码提交");
                        reloadToken();
                        reloadCode();
                        return;
                    }
                    if (errmsg.indexOf("后台处理异常") != -1 || errmsg.indexOf("非法请求") != -1) {
                        if (lastform) {
                            utility.notifyOnTop("后台处理异常,已自动重新提交表单,请填写验证码并提交!");
                            lastform.submit();
                        } else {
                            stop("后台处理异常,请返回查询页重新预定!");
                        }
                        return;
                    }
                    if (errmsg.indexOf("包含排队中") != -1) {
                        console.log("惊现排队中的订单, 进入轮询状态");
                        waitingForQueueComplete();
                        return;
                    }
 
 
                    setCurOperationInfo(false, errmsg);
                    stop(errmsg);
                    reloadCode();
                } else {
                    utility.notifyOnTop("订单提交成功, 正在等待队列完成操作,请及时注意订单状态");
                    waitingForQueueComplete();
                }
            },
            error: function (msg) {
                setCurOperationInfo(false, "当前请求发生错误");
                utility.delayInvoke(null, submitForm, 3000);
            }
        });
    }
 
    function reloadToken(submit) {
        setCurOperationInfo(true, "正在刷新TOKEN....");
        utility.post("/otsweb/order/confirmPassengerAction.do?method=init", null, "text", function (text) {
            if (!/TOKEN"\s*value="([a-f\d]+)"/i.test(text)) {
                setCurOperationInfo(false, "无法获得TOKEN,正在重试");
                utility.delayInvoke("#countEle", reloadToken, 1000);
            } else {
                var token = RegExp.$1;
                setCurOperationInfo(false, "已获得TOKEN - " + token);
                console.log("已刷新TOKEN=" + token);
                $("input[name=org.apache.struts.taglib.html.TOKEN]").val(token);
            }
        }, function () { utility.delayInvoke("#countEle", reloadToken, 1000); });
    }
 
    function waitingForQueueComplete() {
        setCurOperationInfo(true, "订单提交成功, 正在等待队列完成操作....");
 
        $.ajax({
            url: '/otsweb/order/myOrderAction.do?method=queryOrderWaitTime&tourFlag=' + tourFlag + '&' + Math.random(),
            data: {},
            type: 'GET',
            timeout: 10000,
            dataType: 'json',
            success: function (json) {
                console.log(json);
 
                if (json.waitTime == -1 || json.waitTime == 0) {
                    utility.notifyOnTop("订票成功!");
                    if (json.orderId)
                        window.location.replace("/otsweb/order/confirmPassengerAction.do?method=payOrder&orderSequence_no=" + json.orderId);
                    else window.location.replace('/otsweb/order/myOrderAction.do?method=queryMyOrderNotComplete&leftmenu=Y');
                } else if (json.waitTime == -3) {
                    var msg = "很抱歉, 铁道部无齿地撤销了您的订单, 赶紧重新下!";
                    utility.notify(msg);
                    setCurOperationInfo(false, msg);
                    stop(msg);
                    reloadCode();
                } else if (json.waitTime == -2) {
                    var msg = "很抱歉, 铁道部说您占座失败 : " + json.msg + ', 赶紧重新来过!';
                    reloadToken();
                    utility.notify(msg);
                    setCurOperationInfo(false, msg);
                    stop(msg);
                    reloadCode();
                }
                else if (json.waitTime < 0) {
                    var msg = '很抱歉, 未知的状态信息 : waitTime=' + json.waitTime + ', 可能已成功,请验证未支付订单.';
                    setTipMessage(msg);
                    utility.notifyOnTop(msg);
                    location.href = '/otsweb/order/myOrderAction.do?method=queryMyOrderNotComplete&leftmenu=Y';
                } else {
                    var msg = "订单需要 " + utility.getSecondInfo(json.waitTime) + " 处理完成, 请等待,不过你知道的,铁道部说的一直不怎么准。(排队人数=" + (json.waitCount || "未知") + "";
                    if (json.waitTime > 1800) {
                        msg += "<span style='color:red; font-weight: bold;'>警告:排队时间大于30分钟,请不要放弃电话订票或用小号重新排队等其它方式继续订票!</span>";
                    }
                    setTipMessage(msg);
 
                    if (json.waitTime > 1800 && !waitTimeTooLong_alert) {
                        waitTimeTooLong_alert = true;
                        utility.notifyOnTop("警告!排队时间大于30分钟,成功率较低,请尽快电话订票或用小号重新排队!");
                    }
 
                    utility.delayInvoke("#countEle", waitingForQueueComplete, 3000);
                }
            },
            error: function (json) {
                utility.notifyOnTop("请求发生异常,可能是登录状态不对,请验证。如果没有问题,请手动进入未完成订单页面查询。");
                self.location.reload();
            }
        });
    }
 
 
    //$("div.tj_btn").append("<button class='long_button_u_down' type='button' id='btnAutoSubmit'>自动提交</button> <button class='long_button_u_down' type='button' id='btnCancelAuto' style='display:none;'>取消自动</button>");
    $("#btnAutoSubmit").click(function () {
        count = 0;
        breakFlag = 0;
        submitFlag = true;
        submitForm();
    });
    $("#btnCancelAuto").click(function () {
        $(this).hide();
        breakFlag = 1;
        submitFlag = false;
    });
    randEl.keyup(function (e) {
        return;
        if (document.getElementById("autoStartCommit").checked && !breakFlag) {
        if (e.charCode == 13 || randEl.val().length == 4) submitForm();
        }
    });
 
    //清除上次保存的预定信息
    var lastform = null;
    if (parent) {
        lastform = parent.$("#orderForm");
        lastform.attr("success", "1");
    }
 
    //进度提示框
    //$("table.table_qr tr:last").before("<tr style='display:none;'><td style='border-top:1px dotted #ccc;height:100px;' colspan='9' id='orderCountCell'></td></tr><tr><td style='border-top:1px dotted #ccc;' colspan='9'><ul id='tipScript'>" +
    //"<li class='fish_clock' id='countEle' style='font-weight:bold;'>等待操作</li>" +
    //"<li style='color:green;'><strong>操作信息</strong>:<span>休息中</span></li>" +
    //"<li style='color:green;'><strong>最后操作时间</strong>:<span>--</span></li></ul></td></tr>");
 
    var tip = $("#tipScript li");
    var errorCount = 0;
 
    //以下是函数
    function setCurOperationInfo(running, msg) {
        var ele = $("#countEle");
        ele.removeClass().addClass(running ? "fish_running" : "fish_clock").html(msg || (running ? "正在操作中……" : "等待中……"));
    }
 
    function setTipMessage(msg) {
        tip.eq(2).find("span").html(utility.getTimeInfo());
        tip.eq(1).find("span").html(msg);
    }
 
    //提交频率差别
    $(".table_qr tr:last").before("<tr><td colspan='9'><span style='display:none;'>自动提交失败时休息时间:<input type='text' size='4' class='input_20txt' style='text-align:center;' value='3' id='pauseTime' />秒 (不得低于1)  <label><input type='checkbox' id='autoStartCommit' /> 输入验证码后立刻开始自动提交</label></span> <label><input type='checkbox' id='showHelp' /> 显示帮助</label></td></tr>");
    document.getElementById("autoStartCommit").checked = typeof (window.localStorage["disableAutoStartCommit"]) == 'undefined';
    document.getElementById("showHelp").checked = typeof (window.localStorage["showHelp"]) != 'undefined';
    $("#autoStartCommit").change(function () {
        if (this.checked) window.localStorage.removeItem("disableAutoStartCommit");
        else window.localStorage.setItem("disableAutoStartCommit", "1");
    });
    $("#showHelp").change(function () {
        if (this.checked) {
            window.localStorage.setItem("showHelp", "1");
            $("table.table_qr tr:last").show();
        }
        else {
            window.localStorage.removeItem("showHelp");
            $("table.table_qr tr:last").hide();
        }
    }).change();
 
    //#region 自动刷新席位预定请求数
 
    var stopCheckCount = null;
 
    (function () {
        var data = { train_date: $("#start_date").val(), station: $("#station_train_code").val(), seat: "", from: $("#from_station_telecode").val(), to: $("#to_station_telecode").val(), ticket: $("#left_ticket").val() };
        var url = "confirmPassengerAction.do?method=getQueueCount";
        var allSeats = $("#passenger_1_seat option");
        var queue = [];
        var checkCountStopped = false;
 
        function beginCheck() {
            if (checkCountStopped) return;
 
            var html = [];
            html.push("当前实时排队状态(每隔2秒轮询):");
 
 
            allSeats.each(function () {
                queue.push({ id: this.value, name: this.text });
                html.push("席位【<span style='color:blue; font-weight: bold;'>" + this.text + "</span>】状态:<span id='queueStatus_" + this.value + "'>等待查询中....</span>");
            });
            $("#orderCountCell").html(html.join("<br />"));
            if (queue.length > 0) executeQueue();
        }
        function checkTicketAvailable() {
            var queryLeftData = {
                'orderRequest.train_date': $('#start_date').val(),
                'orderRequest.from_station_telecode': $('#from_station_telecode').val(),
                'orderRequest.to_station_telecode': $('#to_station_telecode').val(),
                'orderRequest.train_no': $('#train_no').val(),
                'trainPassType': 'QB',
                'trainClass': 'QB#D#Z#T#K#QT#',
                'includeStudent': 00,
                'seatTypeAndNum': '',
                'orderRequest.start_time_str': '00:00--24:00'
            };
            utility.get("/otsweb/order/querySingleAction.do?method=queryLeftTicket", queryLeftData, "text", function (text) {
                window.ticketAvailable = '';
                if (/(([\da-zA-Z]\*{5,5}\d{4,4})+)/gi.test(text)) {
                    window.ticketAvailable = RegExp.$1;
                }
            }, function () { });
        }
        function executeQueue() {
            if (checkCountStopped) return;
 
            var type = queue.shift();
            queue.push(type);
 
            data.seat = type.id;
            var strLeftTicket = '';
            checkTicketAvailable();
            if (window.ticketAvailable) {
                strLeftTicket = window.ticketAvailable;
            }
            utility.get(url, data, "json", function (data) {
                var msg = "余票:<strong>" + getTicketCountDesc(strLeftTicket, type.id) + "</strong>";
                msg += ",当前排队【<span style='color:blue; font-weight: bold;'>" + data.count + "</span>】,";
                if (data.op_2) {
                    msg += "<span style='color:blue; font-weight: red;'>排队人数已经超过余票数,可能无法提交</span>。";
                } else {
                    if (data.countT > 0) {
                        msg += "排队人数已超过系统参数,<span style='color:red; font-weight: bold;'>排队有危险</span>";
                        //} else if (data.op_1) {
                        //    msg += "排队人数已超过系统参数,<span style='color:red; font-weight: bold;'>排队有危险</span>";
                    } else {
                        msg += "请尽快提交";
                    }
 
                }
                msg += "&nbsp;&nbsp;&nbsp;&nbsp;(" + utility.getTimeInfo() + ")";
 
                $("#queueStatus_" + type.id).html(msg);
                setTimeout(executeQueue, 2000);
            }, function () {
                setTimeout(executeQueue, 3000);
            });
        }
 
        stopCheckCount = function () {
            checkCountStopped = true;
        }
 
        //beginCheck();
    })();
 
    //#endregion
 
 
    //#region 自动选择联系人、自动选择上次选择的人
    function autoSelectPassenger() {
        var pp = localStorage.getItem("preSelectPassenger") || "";
        var pseat = (localStorage.getItem("autoSelect_preSelectSeatType") || "").split('|')[0];
        if (pp) {
            pp = pp.split("|");
 
            $.each(pp, function () {
                if (!this) return true;
                console.log("[INFO][自动选择乘客] 自动选定-" + this);
                $("#" + this + "._checkbox_class").attr("checked", true).click().attr("checked", true);    //为啥设置两次?我也不知道,反正一次不对。
                return true;
            });
            if (pseat) {
                $(".passenger_class").each(function () { $(this).find("select:eq(0)").val(pseat).change(); });
            }
        }
    };
 
    $(window).ajaxComplete(function (e, xhr, s) {
        if (s.url.indexOf("getpassengerJson") != -1) {
            console.log("[INFO][自动选择乘客] 系统联系人加载完成,正在检测预先选定");
            autoSelectPassenger();
        }
    });
    //如果已经加载完成,那么直接选定
    if ($("#showPassengerFilter div").length) {
        console.log("[INFO][自动选择乘客] OOPS,居然加载完成了?直接选定联系人");
        autoSelectPassenger();
    }
    //#endregion
 
    //#region 自动定位到随机码中
 
    (function () {
        var obj = document.getElementById("rand");
 
        var oldOnload = window.onload;
        window.onload = function () {
            if (oldOnload) oldOnload();
            obj.select();
        };
        obj.select();
    })();
 
    //#endregion
 
    //#region 显示内部的选择上下铺
 
    (function () {
        //添加上下铺显示
        $("tr.passenger_class").each(function () {
            var tr = $(this);
            var id = tr.attr("id");
 
            tr.find("td:eq(2)").append("<select id='" + id + "_seat_detail' name='" + id + "_seat_detail'><option value='0'>随机</option><option value='2'>上铺</option><option value='2'>中铺</option><option value='1'>下铺</option></select>");
        });
 
        var seatSelector = $("select[name$=_seat]");
        seatSelector.change(function () {
            var self = $(this);
            var val = self.val();
            var l = self.next();
 
            if (val == "2" || val == "3" || val == "4" || val == "6") {
                l.show();
            } else
                l.hide();
            var preseat = utility.getPref("preselectseatlevel");
            if (preseat) {
                l.val(preseat).change();
            }
        }).change();
 
    })();
 
    //#endregion
 
    parent.$("#main").css("height", ($(document).height() + 300) + "px");
    parent.window.setHeight(parent.window);
}
 
function autoCommitOrderInSandbox() {
    //自动提示?
    if (window.localStorage["bookTip"]) {
        window.localStorage.removeItem("bookTip");
        if (window.Audio) {
            new window.Audio(utility.getAudioUrl()).play();
        }
        utility.notify("已经自动进入订票页面!请继续完成订单!");
    }
}
 
//#endregion
 
//#region -----------------自动刷新----------------------
 
function initTicketQuery() {
    //初始化
    if (!window.localStorage["pas"]) {
        alert("亲,请进入我的12306->常用联系人并稍等片刻以更新缓存~");
        //self.location = "/otsweb/passengerAction.do?method=initUsualPassenger12306";
        return;
    }
 
 
    //启用日志
    utility.enableLog();
 
    var initialized = false;
    var seatLevelOrder = null;
    var orderButtonClass = ".btn130_2";    //预定按钮的选择器
 
    //#region 参数配置和常规工具界面
 
    var queryCount = 0;
    var timer = null;
    var isTicketAvailable = false;
    var audio = null; //通知声音
    var timerCountDown = 0;
    var timeCount = 0;
    var autoBook = false;
    //初始化表单
    var form = $("form[name=querySingleForm] .cx_from:first");
    form.find("tr:last").after("<tr class='append_row'><td colspan='9' id='queryFunctionRow'><label title='勾选此选项的话,每次你查询后,助手会帮你把始发站、到达站、日期等进行记录,下次进入查询页面后,将会帮您自动填写好'><input type='checkbox' id='keepinfo' checked='checked' />记住信息</label> <label title='勾选此选项后,假定查询的结果中没有符合你要求的车次,那么助手将会自动进行重新查询'><input checked='checked' type='checkbox' id='autoRequery' />自动重新查询</label>,每隔 <input style='width:50px;' type='number' min='5' value='5' size='4' id='refereshInterval' style='text-align:center;' />秒(最低5) " +
        "<label title='勾选的话,当有票可定时,助手会放歌骚扰你'><input type='checkbox' checked='checked' id='chkAudioOn'>声音提示</label> <input type='button' id='chkSeatOnly' value='仅座票' class='lineButton' title='快速设置席别过滤按钮,点击后可快速勾选所有的座票,包括硬座软座一等座等等' /><input type='button' id='chkSleepOnly' value='仅卧铺' title='快速设置席别过滤按钮,点击后可快速勾选所有的卧铺,包括硬卧软卧什么的' class='lineButton' /><input type='button' id='chkAllSeat' value='全部席别' class='lineButton' title='快速勾选所有的席别' />" +
        "<input type='button' id='enableNotify' onclick='window.webkitNotifications.requestPermission();' value='点击启用桌面通知' style='line-height:25px;padding:5px;' /> <span id='refreshinfo'>已刷新 0 次,最后查询:--</span> <span id='refreshtimer'></span></td></tr>" +
        "<tr class='append_row'><td colspan='9'><label title='设置有票时放的歌是不是放到天荒地老至死不渝'><input type='checkbox' checked='checked' id='chkAudioLoop'>声音循环</label>" +
        "<span style='font-weight:bold;margin-left:10px;color:blue;' title='点击预定按钮时,有时候等待一会儿系统会提示服务器忙;勾选此选项后,如果出现这种情况,助手将会进行自动重新预定'><label><input type='checkbox' id='chkAutoResumitOrder' checked='checked' />预定失败时自动重试</label></span>" +
        "<span style='font-weight:bold;margin-left:10px;color:blue;' title='有时候系统忙,查询会提示查询失败;勾选此选项后,如果出现这种情况,助手将会进行自动刷新查询'><label><input type='checkbox' id='chkAutoRequery' checked='checked' />查询失败时自动重试</label></span>" +
        "<span style='font-weight:bold;margin-left:10px;color:pruple;' title='以服务器时间为准,未获得服务器时间之前,此选项不可用。启用智能加速模式时,在非正点附近时(大于0小于59分)按照正常速度刷新;当在正点附近时(大于等于59分时),暂停刷新并等到正点即刻刷新。'><label><input disabled='disabled' type='checkbox' id='chkSmartSpeed' />智能正点刷新模式</label></span>" +
        "</td></tr>" +
        "<tr class='append_row'><td id='filterFunctionRow' colspan='9'>" +
        "<span style='font-weight:bold;color:red;'><label title='不可以预定的车次过滤掉的选项(隐藏起来不显示,无票的车次)'><input type='checkbox' id='chkFilterNonBookable' />过滤不可预订的车次</label></span>" +
        "<span style='font-weight:bold;margin-left:10px;color:red;'><label title='有时候虽然整趟车可以预定,但是有票的席别都是你不要的,如果勾选此选项,也将会过滤掉'><input type='checkbox' id='chkFilterNonNeeded' />过滤不需要的席别</label></span>" +
        "<span style='font-weight:bold;margin-left:10px;color:blue;display: none;'><label><input disabled='disabled' type='checkbox' id='chkFilterByTrain' />开启按车次过滤</label></span>" +
        "</td></tr>" +
        "<tr><td colspan='9' id='opFunctionRow'><input type='button' class='fish_button' disabled='disabled' value='停止声音' id='btnStopSound' /><input  type='button' class='fish_button' disabled='disabled'  value='停止刷新' id='btnStopRefresh' /><input  type='button' class='fish_button' type='button' value='设置' id='configLink' /> <input type='button' class='fish_button' id='resetSettings' value='清空助手设置' /> <input type='button' class='fish_button configLink' value='IE登录' /> 【<a href='http://www.fishlee.net/soft/44/tour.html' style='color:purple;font-weight:bold;' target='_blank'>啊嘞……遇到不明白的啦?戳这里看教程呗</a>】<span style='margin-left:20px;color:purple;font-weight:bold;' id='serverMsg'></span></td> </tr>"
    );
 
    if (!window.Audio) {
        $("#chkAudioOn, #chkAudioLoop, #btnStopSound").remove();
    } else {
        $("#btnStopSound").click(function () {
            if (audio) {
                audio.pause();
            }
            this.disabled = true;
        });
    }
    $("#resetSettings").click(function () {
        if (confirm("确定要清空助手的所有设置吗?")) {
            window.localStorage.clear();
            self.location.reload();
            return false;
        }
    });
 
    //操作控制
    $("#btnStopRefresh").click(function () { resetTimer(); });
    $("#chkSmartSpeed").change(function () {
    });
 
    //#endregion
 
    //#region 显示座级选择UI
    var ticketType = new Array();
    var seatOptionTypeMap = {
        "3": "9",
        "4": "P",
        "5": "M",
        "6": "O",
        "7": "6",
        "8": "4",
        "9": "3",
        "10": "2",
        "11": "1",
        "12": "empty",
        "13": "QT"
    };
    $(".hdr tr:eq(2) td").each(function (i, e) {
        ticketType.push(false);
        if (i < 3) return;
 
        var obj = $(this);
        ticketType[i] = (window.localStorage["typefilter_" + i] || "true") == "true";
 
        //修改文字,避免换行
        obj.attr("otext", obj.text());
        var cap = $.trim(obj.text());
        if (cap.length > 2) {
            cap = cap.replace("座", "").replace("高级软卧", "高软");
            obj.html(cap);
        }
 
        //加入复选框
        var c = $("<input id='seatoption_" + seatOptionTypeMap[i] + "' type='checkbox' typecode='" + seatOptionTypeMap[i] + "' name='seatoption'/>").attr("checked", ticketType[i]);
        c[0].ticketTypeId = i;
        c.change(
            function () {
                ticketType[this.ticketTypeId] = this.checked;
                window.localStorage["typefilter_" + this.ticketTypeId] = this.checked;
            }).appendTo(obj);
    });
 
    //座级选择
    $("#chkSeatOnly").click(function () {
        $(".hdr tr:eq(2) td").each(function (i, e) {
            var obj = $(this);
            var txt = obj.attr("otext");
            obj.find("input").attr("checked", typeof (txt) != 'undefined' && txt && txt.indexOf("") != -1).change();
        });
    });
    $("#chkSleepOnly").click(function () {
        $(".hdr tr:eq(2) td").each(function (i, e) {
            var obj = $(this);
            var txt = obj.attr("otext");
            obj.find("input").attr("checked", typeof (txt) != 'undefined' && txt && txt.indexOf("") != -1).change();
        });
    });
    $("#chkAllSeat").click(function () {
        $(":checkbox[name=seatoption]").attr("checked", true).change();
    });
    //#endregion
 
    //#region 显示额外的功能区
    var extrahtml = [];
    extrahtml.push("<div class='outerbox' id='helperbox' style='width:auto;'><div class='box'><div class='title' style='position:relative;'>辅助工具 [<a href='#querySingleForm'>返回订票列表</a>] <div style='color:#066DFF;position:absolute;background-color: #eee;border: 1px solid purple;right:0px;top:0px;padding:2px;margin:2px;' title='时间依赖于本地时间保持在线刷新时间即时计算。受限于您的网速,并不十分准确(需要扣除网速的影响)' id='servertime'>服务器时间:<strong>----</strong>,本地时间:<strong>----</strong>,服务器比本地 <strong>----</strong></div></div>\
<table id='helpertooltable' style='width:100%;'><colgroup><col style='width:110px;' /><col style='width:370px;' /><col style='width:110px;' /><col style='width:auto;' /></colgroup>\
<tr class='fish_sep musicFunc' id='helperbox_bottom'><td class='name'>自定义音乐地址</td><td colspan='3'><input type='text' id='txtMusicUrl' value='" + utility.getAudioUrl() + "' onfocus='this.select();' style='width:50%;' /> <input type='button' onclick='new Audio(document.getElementById(\"txtMusicUrl\").value).play();' value='测试'/><input type='button' onclick='utility.resetAudioUrl(); document.getElementById(\"txtMusicUrl\").value=utility.getAudioUrl();' value='恢复默认'/> (地址第一次使用可能会需要等待一会儿)</td></tr>\
<tr class='fish_sep musicFunc'><td class='name'>可用音乐地址</td><td colspan='3'>");
 
    var host1 = "http://static.liebao.cn/resources/audio/";
    //var host2 = "https://github.com/iccfish/12306_ticket_helper/raw/master/res/";
    var musics = [["music1.ogg", "超级玛丽"], ["music2.ogg", "蓝精灵"]];
    $.each(musics, function () {
        extrahtml.push("<a href='javascript:;' url='" + host1 + this[0] + "' class='murl'>" + this[1] + "</a>&nbsp;&nbsp;&nbsp;&nbsp;");
        //extrahtml.push("<a href='javascript:;' url='" + host2 + this[0] + "' class='murl'>" + this[1] + "</a>(HTTPS)&nbsp;&nbsp;&nbsp;&nbsp;");
    });
 
    extrahtml.push("</td></tr><tr class='fish_sep'><td colspan='4'><input type='button' value='添加自定义车票时间段' id='btnDefineTimeRange' />\
<input type='button' value='清除自定义车票时间段' id='btnClearDefineTimeRange' /></td></tr>\
<tr class='fish_sep'><td style='text-align:center;' colspan='4'><a href='http://www.fishlee.net/soft/44/' target='_blank' style='color:purple;'>12306.CN 订票助手</a> | <a href='http://www.fishlee.net/soft/44/announcement.html' style='color:blue;' target='_blank'>免责声明</a> | <a href='"+ utility.getUpdateUrl() + "' target='_blank' style='color:purple;'>下载新版</a> | <a style='font-weight:bold;color:red;' href='http://www.fishlee.net/soft/44/donate.html' target='_blank'>捐助作者</a> | 版本 v" + window.helperVersion + ",许可于 <strong>" + utility.regInfo.name + ",类型 - " + utility.regInfo.typeDesc + "</strong> 【<a href='javascript:;' class='reSignHelper'>重新注册</a>】</td></tr>\
        </table></div></div>");
 
    $("body").append(extrahtml.join(""));
    $("a.murl").live("click", function () {
        $("#txtMusicUrl").val(this.getAttribute("url")).change();
    });
    $("#stopBut").before("<div class='jmp_cd' style='text-align:center;'><button class='fish_button' id='btnFilter'>加入黑名单</button><button class='fish_button' id='btnAutoBook'>自动预定本车次</button></div>");
    $("#txtMusicUrl").change(function () { window.localStorage["audioUrl"] = this.value; });
    $("form[name=querySingleForm]").attr("id", "querySingleForm");
 
    //#endregion
 
    //#region 添加自定义时间段
    function addCustomTimeRange() {
        var s = parseInt(prompt("请输入自定义时间段的起始时间(请填入小时,0-23)", "0"));
        if (isNaN(s) || s < 0 || s > 23) {
            alert("起始时间不正确 >_<"); return;
        }
        var e = parseInt(prompt("请输入自定义时间段的结束时间(请填入小时,1-24)", "24"));
        if (isNaN(e) || e < 0 || e > 24) {
            alert("结束时间不正确 >_<"); return;
        }
        var range = (s > 9 ? "" : "0") + s + ":00--" + (e > 9 ? "" : "0") + e + ":00";
        if (confirm("您想要记住这个时间段吗?")) {
            window.localStorage["customTimeRange"] = (window.localStorage["customTimeRange"] ? window.localStorage["customTimeRange"] + "|" : "") + range;
        };
        addCustomeTimeRangeToList(range);
    }
    function addCustomeTimeRangeToList(g) {
        var obj = document.getElementById("startTime");
        obj.options[obj.options.length] = new Option(g, g);
        obj.selectedIndex = obj.options.length - 1;
    }
    if (window.localStorage["customTimeRange"]) {
        var ctrs = window.localStorage["customTimeRange"].split("|");
        $.each(ctrs, function () { addCustomeTimeRangeToList(this); });
    }
    $("#btnClearDefineTimeRange").click(function () {
        if (!confirm("确定要清除自定义的时间段吗?清除后请刷新页面。")) return;
        window.localStorage.removeItem("customTimeRange");
    });
    $("#btnDefineTimeRange").click(addCustomTimeRange);
    //#endregion
 
    //#region 过滤车次
    var stopHover = window.onStopHover;
    window.onStopHover = function (info) {
        $("#stopDiv").attr("info", $.trim($("#id_" + info.split('#')[0]).text()));
        stopHover.call(this, info);
        $("#onStopHover").css("overflow", "hide");
    };
 
    $("#btnFilter").click(function () {
        //加入黑名单
        var trainNo = $("#stopDiv").attr("info").split('#')[0];
        if (!trainNo || !confirm("确定要将车次【" + trainNo + "】加入黑名单?以后的查询将不再显示此车次。")) return;
 
        list_blacklist.add(trainNo);
    });
    $("#btnAutoBook").click(function () {
        //加入自动预定列表
        var trainNo = $("#stopDiv").attr("info").split('#')[0];
        if (isTrainInBlackList(trainNo)) {
            alert("指定的车次在黑名单里呢……");
            return;
        }
 
        if (!trainNo || !confirm("确定要将车次【" + trainNo + "】加入自动预定列表?如果下次查询有符合要求的席别将会自动进入预定页面。")) return;
 
        list_autoorder.add(trainNo);
    });
    //清除进入指定页面后提示的标记位
    if (window.localStorage["bookTip"]) window.localStorage.removeItem("bookTip");
    //#endregion
 
    //#region 自动重新查询
 
    var clickButton = null;//点击的查询按钮

你可能感兴趣的:(12306)