· 6 years ago · Sep 22, 2019, 08:50 PM
1
2
3<!DOCTYPE html>
4<!--[if lt IE 7]><html class="ie6 oldie" lang="zh"><![endif]-->
5<!--[if IE 7]><html class="ie7 oldie" lang="zh"><![endif]-->
6<!--[if IE 8]><html class="ie8 oldie" lang="zh"><![endif]-->
7<!--[if gt IE 8]><!--> <html lang="zh"> <!--<![endif]-->
8<head>
9<meta http-equiv="X-UA-Compatible" content="edge" />
10<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
11<meta name="renderer" content="webkit">
12<!--[if lt IE 7]>
13<meta http-equiv="refresh" content="0; url=http://miwifi.com/cgi-bin/luci/web/ieblock" />
14<![endif]-->
15<!--[if gte IE 9]>
16<style>
17body {
18 filter: none;
19}
20</style>
21<![endif]-->
22 <title>MiWi-Fi Router</title>
23 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
24 <link href="/xiaoqiang/web/css/bc.css?v=0.0.3" rel="stylesheet">
25 <link href="/xiaoqiang/web/css/login.css?v=0.0.3" rel="stylesheet">
26</head>
27<body>
28<div id="doc">
29 <div id="hd">
30 </div>
31 <div id="bd">
32 <div class="mod-login">
33 <div class="title">
34 <img src="/xiaoqiang/web/img/en/bg_login_tit.png?v=0.0.3" height="124">
35 </div>
36 <div class="pic">
37 <img src="/xiaoqiang/web/img/topograph/router_r3l_100.png" >
38 </div>
39 <div class="rtname">
40 Xiaomi_9FE4 (Home)
41 </div>
42 <form id="rtloginform" name="rtloginform" method="post" class="form-login">
43 <div class="form-item">
44 <span class="v"><input id="password" class="ipt-text" type="password" name="router_password" autocomplete="off" placeholder="Enter router admin password" reqMsg="Enter router admin password"></span>
45 <em class="t"></em>
46 </div>
47 <div class="form-contral">
48 <a id="btnRtSubmit" class="btn-login"></a>
49 </div>
50 </form>
51 <div class="mobile-ft">
52 <p>
53 <a target="_blank" href="http://www1.miwifi.com">Offical site</a>
54 </p>
55 </div>
56 </div>
57 </div>
58
59<div id="ft">
60 <p>© 2015 MiWi-Fi Router<p>
61</div>
62
63</div>
64
65<!--[if lt IE 7]>
66<script>
67try{ document.execCommand("BackgroundImageCache",false,true);} catch(e){}
68</script>
69<![endif]-->
70<div class="mask-menu" id="maskMenu" style="position:fixed;left:0;top:0; width:100%; height:100%; z-index:2; display:none;"></div>
71<div id="dropmenu" class="dropmenu" style="z-index:3; display:none;">
72 <ul>
73 <li><a href="#" id="toRename">Change router name</a></li>
74
75 <li><a href="/cgi-bin/luci/web/setting/upgrade">Updating…</a></li>
76
77 <li><a href="#" id="toDownloadClient">Download APP</a></li>
78 <li><a href="#" id="toReboot">Reboot</a></li>
79
80 <li class="last"><a href="/cgi-bin/luci/web/logout">Sign out</a></li>
81 </ul>
82</div>
83<div id="noticebar" class="noticebar" style="z-index:3; display:none;">
84 <i class="ico-arrow"></i>
85 <div class="content"></div>
86</div>
87<script>
88var i18n = {};
89i18n.dialog = {
90 ok: 'OK',
91 cancel: 'Cancel',
92 loading: 'Loading…',
93 dlgtitle: 'Message box'
94};
95i18n.valid = {
96 n_integer: 'Enter a complete {$0}',
97 n_format: 'Use the following format "{$0}"',
98 n_upper: 'Use {$0} characters or less', //注意:{$0}表示允许值,{$1}表示实际值
99 n_lower: 'Use {$0} characters or more',
100 nrange_from: 'Input range vaild',
101 nrange_to: 'Input range vaild',
102 n_useless_zero: 'Look's like there's an additional "0" at the beginning of the value you entered.',
103 d_format: 'Enter format "YYYY-MM-DD"',
104 d_upper: 'Date can't be later than {$0}',
105 d_lower: 'Date can't be earlier than {$0}',
106 daterange_from: 'Start date can't be later than end date.',
107 daterange_to: 'End date can't be earlier than start date',
108 daterange_larger_span: "Can't exceed {$0} days",
109 text_longer: 'Use {$0} characters or less', //'{$1}字太多,最多允许{$0}字'
110 text_shorter: 'Use {$0} characters or more', //'{$1}字太少,最少允许{$0}字'
111 bytetext_longer: 'Use {$0} characters or more', //'{$1}字节太多,最多允许{$0}字节'
112 bytetext_shorter: 'Use {$0} characters or more', //'{$1}字节太少,最少允许{$0}字节'
113 richtext_longer: 'Use {$0} characters or less',
114 richtext_shorter: 'Use {$0} characters or more',
115 _reconfirm: 'Passwords don't match.',
116 _time: 'The format of the date you entered is invalid.',
117 _minute: 'The format of the date you entered is invalid.',
118 _email: 'Check the email address you ented',
119 _mobilecode: 'Check the phone number you entered',
120 _phone: 'Check the phone number you entered',
121 _phonewithext: 'Check the phone number you entered',
122 _phonezone: 'Check the area code you entered',
123 _phonecode: 'Check the phone number you entered',
124 _phoneext: 'Check the phone number extension you entered',
125 _zipcode: 'Check the zip code you entered',
126 _idnumber: 'Check the ID number you entered',
127 _bankcard: 'Check the account number you entered',
128 _cnname: 'Check the name you entered',
129 _vcode: 'Check the verification code you entered',
130 _imgfile: 'Only jpg, jpeg, png, gif, tif, or bmp file types are supported.',
131 _regexp: 'Check input fields',
132 _magic: 'Check input fields',
133 _req_text: 'Enter {$0}.',
134 _req_select: 'Choose {$0}',
135 _req_file: 'Upload {$0}',
136 _logicrequired: '{$0} is invalid.',
137 _ssid: 'The router name you entered is invalid',
138 _macaddr: 'MAC address format is invalid',
139 _weppassword: 'The password you entered is incorrect.',
140 _wifipassword: 'Can't contain Chinese characters.',
141 _ipaddr: 'IP address consists of four numbers, each ranging from 0 to 255, separated by dots (e.g. 120.134.33.9) ',
142 _url: 'Enter full URL (e.g. http://miwifi.com)'
143};
144</script>
145<script src="/js/jquery-1.8.3.js?v=0.0.3"></script>
146<script src="/js/qwrap.js?v=0.0.3"></script>
147<script src="/js/common.js?v=0.0.3"></script>
148<script src="/js/raphael.js?v=0.0.3"></script>
149<script src="/js/crypto-js/rollups/sha1.js?v=0.0.3"></script>
150<script src="/js/crypto-js/rollups/aes.js?v=0.0.3"></script>
151<script src="/js/valid.js?v=0.0.3"></script>
152<script src="/xiaoqiang/web/js/selectbeautify.js?v=0.0.3"></script>
153<script src="/xiaoqiang/web/js/jquery.dialog.js?v=0.0.3"></script>
154<script src="/xiaoqiang/web/js/jquery.cookie.js?v=0.0.3"></script>
155<script>
156(function(){
157 var hardwareModel = 'R3L',
158 R1CM = hardwareModel === 'R1CM',
159 R1CL = hardwareModel === 'R1CL',
160 R1D = hardwareModel === 'R1D',
161 R2D = hardwareModel === 'R2D',
162 R3 = hardwareModel === 'R3';
163 var G_CONFIG = {
164 R1CM : R1CM,
165 R1CL : R1CL,
166 R1D: R1D,
167 R2D: R2D,
168 R3: R3
169 };
170 var G_FEATURES = $.parseJSON('{"hardware":{"disk":"0","usb":"0"},"wifi":{"wifimerge":"1","wifiguest":"0","wifi24":"1","wifi50":"0"},"apps":{"apptc":"0","qos":"1"},"apmode":{"lanapmode":"1","wifiapmode":"1"},"system":{"i18n":"1","downloadlogs":"0","task":"0","shutdown":"0"}}');
171 window['G_CONFIG'] = G_CONFIG;
172 window['G_FEATURES'] = G_FEATURES;
173}())
174</script>
175
176<script>
177// reboot
178var global_api_reboot = {
179 url : '/cgi-bin/luci/api/xqsystem/reboot',
180 param : {"client":"web"}
181};
182function reboot_window( needconfirm ) {
183 console.log( needconfirm );
184 var reboot = function(){
185 $.getJSON( global_api_reboot.url, global_api_reboot.param, function( rsp ) {
186 if( rsp.code !== 0 ){
187 $.alert( rsp.msg ).time( 1.5*1000 );
188 } else {
189 var ip = rsp.lanIp[0].ip;
190 rebootWait( {
191 lanIp : ip,
192 action : 'Reboot router?',
193 refresh : true
194 } );
195 }
196 });
197 };
198 if ( typeof( needconfirm ) !== "undefined" && needconfirm === false ) {
199 reboot();
200 return;
201 }
202 $.confirm('Devices will be disconnected from network while router reboots.',function () {
203 var dlg = this;
204 reboot();
205 dlg.close();
206 return false;
207 });
208}
209// shutdown
210function shutdown_window(){
211 $.confirm('All devices will be disconnected from router.', function () {
212 $.getJSON( '/cgi-bin/luci/api/xqsystem/shutdown', {}, function( rsp ){
213 if( rsp.code !== 0 ){
214 $.alert(rsp.msg).time( 1.5*1000 );
215 } else {
216 $.loadingDialog({
217 title: 'Turn off router',
218 content: 'Wait until router's notification turns off before disconnecting power source.'
219 });
220 }
221 });
222 });
223}
224//reset
225function reset_window( format ){
226
227 var reset = (function( format ){
228 var requestURL = '/cgi-bin/luci/api/xqsystem/reset',
229 requestData = {
230 format: format ? 1 : 0
231 },
232 wait = function(){
233 rebootWait( {
234 action : 'Factory data reset',
235 refresh : true,
236 lanIp: '192.168.31.1'
237 } );
238 },
239 clearCookies = function (){
240 var keys = document.cookie.match(/[^ =;]+(?=\=)/g);
241 if ( keys ) {
242 for (var i = keys.length; i--;){
243 document.cookie = keys[i]+'=0;path=/;expires=' + new Date(0).toUTCString();
244 }
245 }
246 };
247
248 return function(){
249 $.getJSON( requestURL , requestData, function( rsp ) {
250 if ( rsp.code !== 0 ) {
251 $.alert( rsp.msg ).time( 3*1000 );
252 }else{
253 // clear cookies
254 clearCookies();
255 //block wait
256 wait();
257 }
258 });
259 }
260 })( format );
261
262 $.confirm('Restore router to it's factory settings? You can't reverse this action.', function(){
263 reset();
264 });
265}
266</script>
267<script type="text/tmpl" id="tplrename">
268<div class="mod-rename-dlg">
269 <p class="img"><img src="/xiaoqiang/web/img/topograph/router_r3l_100.png"></p>
270 <div class="form-rename">
271 <form action="#" class="form" id="routerNameEdit">
272 <div class="form-item">
273 <label class="k">Name</label>
274 <span class="v">
275 <input type="text" name="routername" id="routername" class="ipt-text" autocomplete="off" datatype="bytetext" maxlength="24" reqMsg="Name" value="{$name}">
276 </span>
277 <em class="t"></em>
278 </div>
279 <div class="form-item">
280 <label class="k">Location</label>
281 <span class="v">
282 <input type="text" name="locale" id="locale" class="ipt-text" autocomplete="off" datatype="bytetext" maxlength="24" reqMsg="Location" value="{$locale}">
283 </span>
284 <em class="t"></em>
285 </div>
286 <div class="form-contral">
287 <button type="submit" class="btn btn-primary btn-l"><span>Save</span></button>
288 </div>
289 </form>
290 </div>
291</div>
292</script>
293<script type="text/tmpl" id="tplshutdown">
294<div class="mod-reboot-dlg">
295 <p class="img"><img src="/xiaoqiang/web/img/ico_shutdown.png"></p>
296 <p class="text">All devices will be disconnected from router's network.</p>
297 <button id="shutdownAction" type="button" class="btn btn-primary btn-l"><span>Turn off router</span></button>
298</div>
299</script>
300<script type="text/tmpl" id="tplreboot">
301<div class="mod-shutdown-dlg">
302 <p class="img"><img src="/xiaoqiang/web/img/ico_reboot.png"></p>
303 <p class="text">Reboot the router and wait 10 seconds. All devices will be disconnected temporarily while the router reboots.</p>
304 <button type="button" id="rebootAction" class="btn btn-primary btn-l"><span>Reboot router?</span></button>
305</div>
306</script>
307<script type="text/tmpl" id="tpldownloadclient">
308<div class="mod-downloadclient-dlg">
309 <table>
310 <tr>
311 <td>
312 <i class="ico-down-client ico-down-pc"></i>
313 <a href="http://bigota.miwifi.com/xiaoqiang/client/xqpc_client.exe">Windows</a>
314 </td>
315 <td class="c1"></td>
316 <td class="c2"></td>
317 <td>
318 <i class="ico-down-client ico-down-mac"></i>
319 <a href="http://bigota.miwifi.com/xiaoqiang/client/xqmac_client.dmg">OSX</a>
320 </td>
321 </tr>
322 <tr class="last">
323 <td>
324 <i class="ico-down-client ico-down-andriod"></i>
325
326 <a href="http://bigota.miwifi.com/xiaoqiang/client/xqapp.apk">Android app</a>
327 <img class="onlineimg" src-local="/xiaoqiang/web/img/2dcode.png" src="http://www1.miwifi.com/statics/img/wf_2dcode_an_dl.png">
328
329 </td>
330 <td class="c1"></td>
331 <td class="c2"></td>
332 <td>
333 <i class="ico-down-client ico-down-iphone"></i>
334 <a href="https://itunes.apple.com/cn/app/id859962702?mt=8&ls=1">iOS</a>
335 <img class="onlineimg" src-local="/xiaoqiang/web/img/2dcode.png" src="http://www1.miwifi.com/statics/img/wf_2dcode_ios_dl.png">
336 </td>
337 </tr>
338 </table>
339</div>
340</script>
341<script>
342var DEBUG = false;
343if ( !window.console || DEBUG == false) {
344 window.console = {
345 log: function(){}
346 };
347}
348
349var Encrypt = {
350 key: 'a2ffa5c9be07488bbb04a3a47d3c5f6a',
351 iv: '64175472480004614961023454661220',
352 nonce: null,
353 init: function(){
354 var nonce = this.nonceCreat();
355 this.nonce = nonce;
356 return this.nonce;
357 },
358 nonceCreat: function(){
359 var type = 0;
360 var deviceId = '60:d8:19:cb:51:d2';
361 var time = Math.floor(new Date().getTime() / 1000);
362 var random = Math.floor(Math.random() * 10000);
363 return [type, deviceId, time, random].join('_');
364 },
365 oldPwd : function(pwd){
366 return CryptoJS.SHA1(this.nonce + CryptoJS.SHA1(pwd + this.key).toString()).toString();
367 },
368 newPwd: function(pwd, newpwd){
369 var key = CryptoJS.SHA1(pwd + this.key).toString();
370 key = CryptoJS.enc.Hex.parse(key).toString();
371 key = key.substr(0, 32);
372 key = CryptoJS.enc.Hex.parse(key);
373 var password = CryptoJS.SHA1(newpwd + this.key).toString();
374 var iv = CryptoJS.enc.Hex.parse(this.iv);
375 var aes = CryptoJS.AES.encrypt(
376 password,
377 key,
378 {iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }
379 ).toString();
380 return aes;
381 }
382};
383
384var pingRouter = function( on, off, ip ){
385 var online = on || function(){},
386 offline = off || function(){},
387 host = ip || location.host,
388 imgUrl = 'http://' + host + '/xiaoqiang/web/img/logo.png',
389 time = 5000,
390 timecounter = 0,
391 img = null,
392 wait = function(){
393 console.log('pingRouter:wait');
394 offline();
395 },
396 done = function(){
397 console.log('pingRouter:done');
398 window.clearInterval( timer );
399 online();
400 },
401 loadImg = function( onload, onerror ){
402 img = new Image();
403 img.onload = onload;
404 img.onerror = onerror;
405 img.src = imgUrl+'?' + (+new Date());
406 },
407 timer = window.setInterval(function() {
408
409 if ( 'onLine' in navigator ) {
410 if ( navigator.onLine ) {
411 loadImg(
412 function(){
413 done();
414 }, function(){
415 wait();
416 }
417 );
418 } else {
419 wait();
420 }
421 }else{
422 loadImg(function(){
423 done();
424 }, function(){
425 wait();
426 });
427 }
428 }, time );
429};
430
431var rebootWait = function ( opt ) {
432 var action = opt.action,
433 ip = opt.lanIp || window.location.host,
434 refresh = opt.refresh || false,
435 tStart = ( +new Date() ),
436 tUse,
437 dlgRebootWait = $.loadingDialog({
438 title : 'Rebooting…',
439 content : 'Waiting to reboot…'
440 }),
441 online = function(){
442 dlgRebootWait.content( 'Settings applied' );
443 dlgRebootWait.time( 3*1000 );
444 if( refresh ){
445 window.setTimeout( 'window.top.location.href="http://'+ip+'";',3000 );
446 }
447 },
448 offline = function(){
449 tUse = Math.round( ( ( +new Date() ) - tStart ) / 1000 );
450 if ( tUse > 150 ) {
451 dlgRebootWait.content( 'Couldn't connect to router automatically. ' );
452 return;
453 }
454 dlgRebootWait.content( action + ', waiting for Wi-Fi restart, ({$time}seconds)'.tmpl({time: tUse}) );
455 };
456
457 window.setTimeout( function(){
458 pingRouter( online, offline, ip );
459 }, 1000 * 60 );
460};
461
462(function( $ ){
463
464 function formInit( container ) {
465 var clsInput = 'form-item form-item-input',
466 clsEmpty = 'form-item form-item-empty',
467 clsDisabled = 'form-item-disabled',
468 clsError = 'form-item-err',
469 clsPassword = 'form-item-pwd';
470
471 container = container || 'body';
472 $(container).find( '.form-item input' ).each(function(){
473 var me = this,
474 $me = $( me ),
475 parent = $( me.parentNode.parentNode ),
476 label = parent.find( '.k' ),
477 offsetX = $me.position().left;
478 if ( !( this.type == 'text' || this.type == 'password' ) ) {
479 return;
480 }
481 // some input do not need init
482 if ($me.hasClass('no-init')) {
483 return;
484 }
485 if ( me.value !=='' ) {
486 parent[0].className = clsInput;
487 } else {
488 parent[0].className = clsEmpty;
489 if ( offsetX > 0 ) {
490 label.css({ 'left': offsetX + 10 });
491 }
492 }
493 if ( me.disabled ) {
494 parent.addClass( clsDisabled );
495 }
496 if ( $me.attr('data-type') === 'password' ) {
497 parent.addClass( clsPassword );
498 parent.append( '<i class="bt-showpwd bt-showpwd-off"></i>' );
499 }
500
501 label.on( 'click', function(e){
502 try {
503 me.focus();
504 } catch ( ex ) {}
505 });
506
507 });
508 var focusHandler = function(){
509 if ( !( this.type == 'text' || this.type == 'password' ) ) {
510 return;
511 }
512 var me = $( this ),
513 parent = $( this.parentNode.parentNode ),
514 label = parent.find( '.k' ),
515 t = parent.find( '.t' ),
516 classname;
517 if (me.hasClass('no-init')) {
518 return;
519 }
520 if ( parent.hasClass( clsPassword ) ) {
521 classname = clsInput + ' ' + clsPassword;
522 } else {
523 classname = clsInput;
524 }
525 if ( parent.hasClass( clsError ) ) {
526 t.hide();
527 }
528 label.css({ 'left': 'auto' });
529 label.hide();
530 parent[0].className = classname;
531 };
532 var blurHandler = function(){
533 var me = this,
534 $me = $( me ),
535 parent = $( me.parentNode.parentNode ),
536 classname,
537 label = parent.find( '.k' ),
538 offsetX = $me.position().left;
539 if ( !( this.type == 'text' || this.type == 'password' ) ) {
540 return;
541 }
542 if ($(this).hasClass('no-init')) {
543 return;
544 }
545 label.show();
546 if ( me.value == '' ) {
547 if ( parent.hasClass( clsPassword ) ) {
548 classname = clsEmpty + ' ' + clsPassword;
549 } else {
550 classname = clsEmpty;
551 }
552 if ( offsetX > 0 ) {
553 label.css({ 'left': offsetX + 10 });
554 } else {
555 label.css({ 'left': 12 });
556 }
557 parent[0].className = classname;
558 }
559 };
560 function addInputEvent() {
561 $(container).find( '.form-item input' )
562 .on( 'focus', focusHandler )
563 .on( 'blur', blurHandler );
564 };
565
566 function delInputEvent() {
567 $(container).find( '.form-item input' ).off( 'focus', focusHandler );
568 $(container).find( '.form-item input' ).off( 'blur', blurHandler );
569 };
570 // del password event
571 $( 'body' ).undelegate( '.bt-showpwd', 'click' );
572 $( 'body' ).delegate( '.bt-showpwd', 'click', function(e) {
573 console.log( 'showpwd' );
574 var me = this,
575 meclass = 'bt-showpwd',
576 formItem = $(this).closest('.form-item'),
577 input = formItem.find('input'),
578 inputValue = input.val(),
579 inputWrap = formItem.find('.v'),
580 newinput = '',
581 inputHTML = inputWrap.html();
582
583 if( input.attr('type') == 'password' ){
584 newinput = inputHTML.replace( /type\s*=\s*('|")?password('|")?/ig, 'type="text"');
585 inputWrap.html( newinput ).find('input')[0].value = inputValue;
586 me.className = meclass + ' bt-showpwd-on';
587 }else{
588 newinput = inputHTML.replace( /type\s*=\s*('|")?text('|")?/ig, 'type="password"');
589 inputWrap.html( newinput ).find('input')[0].value = inputValue;
590 me.className = meclass + ' bt-showpwd-off';
591 }
592
593 setTimeout( function() {
594 delInputEvent();
595 addInputEvent();
596 }, 0 );
597 });
598
599
600
601 addInputEvent();
602 }
603
604 $.formInit = formInit;
605
606})(jQuery);
607
608/**
609* byte format
610*/
611function byteFormat(number, precision, isarray){
612 var val,
613 label,
614 ret;
615 precision = precision || 100,
616 isarray = isarray || false;
617 if (number > 1024 * 1024 * 1024) {
618 val = Math.floor( number / 1024 / 1024 / 1024 * precision ) / precision;
619 label = 'GB';
620 } else if (number > 1024 * 1024 && number < 1024 * 1024 * 1024){
621 val = Math.floor( number / 1024 / 1024 * precision ) / precision;
622 label = 'MB';
623 }else{
624 val = Math.floor( number / 1024 * precision ) / precision;
625 label = 'KB';
626 }
627
628 if (isarray) {
629 ret = [val, label];
630 }else{
631 ret = val + label;
632 }
633
634 return ret;
635}
636
637
638function secondToHour(time){
639 var pint = function(num){
640 return parseInt(num, 10);
641 },
642 hour = pint(time / 3600.0),
643 minute = pint((parseFloat(time / 3600.0) - hour) * 60),
644 second = pint(time) - hour * 3600 - minute * 60,
645 format = hour + 'hr' + minute + 'min' + second + 's';
646 return format;
647}
648
649function secondToDate(second) {
650 var time = parseFloat(second),
651 pint = function(num){
652 return parseInt(num, 10);
653 },
654 day;
655 if (time !== null && time !== "") {
656 if (time > 60 && time < 60 * 60) {
657 time = pint(time / 60.0) + 'min' + pint((parseFloat(time / 60.0) - pint(time / 60.0, 10)) * 60) + 's';
658 }
659 else if (time >= 60 * 60 && time < 60 * 60 * 24) {
660 time = secondToHour(time);
661 }else if (time >= 24* 60 * 60 ) {
662 day = pint(time / (3600.0 * 24) );
663 time = time - (day * 3600 * 24);
664 time = day + 'd' + secondToHour(time);
665 }
666 else {
667 time = pint(time) + 's';
668 }
669 }
670 return time;
671}
672
673(function( $ ){
674 function pint(num){
675 return parseInt(num, 10);
676 }
677
678 function secondToHour(time){
679 var hour = pint(time / 3600.0),
680 minute = pint((parseFloat(time / 3600.0) - hour) * 60),
681 second = pint(time) - hour * 3600 - minute * 60,
682 format = hour + 'hr' + minute + 'min' + second + 's';
683 return format;
684 }
685
686 function secondToDate(second) {
687 var time = parseFloat(second),
688 day;
689 if (time !== null && time !== "") {
690 if (time > 60 && time < 60 * 60) {
691 time = pint(time / 60.0) + 'min' + pint((parseFloat(time / 60.0) - pint(time / 60.0, 10)) * 60) + 's';
692 }
693 else if (time >= 60 * 60 && time < 60 * 60 * 24) {
694 time = secondToHour(time);
695 }else if (time >= 24* 60 * 60 ) {
696 day = pint(time / (3600.0 * 24) );
697 time = time - (day * 3600 * 24);
698 time = day + 'd' + secondToHour(time);
699 }
700 else {
701 time = pint(time) + 's';
702 }
703 }
704 return time;
705 }
706
707 function secondToDate2(second) {
708 var time = parseFloat(second),
709 num = 0,
710 unit = 'd';
711 console.log( second, time );
712 if (!isNaN(time)) {
713 if (time > 60 && time < 60 * 60) {
714 num = Math.floor(time / 60.0);
715 unit = ' mins';
716 } else if (time >= 60 * 60 && time < 60 * 60 * 24) {
717 num = Math.floor(time / 3600.0);
718 unit = 'hr'
719 } else if (time >= 24 * 60 * 60 ) {
720 num = Math.floor( time / (3600.0 * 24) );
721 unit = 'd';
722 } else {
723 num = Math.floor(time);
724 unit = 's';
725 }
726 }
727 return {
728 num: num,
729 unit: unit
730 };
731 }
732
733 $.secondToHour = secondToHour;
734 $.secondToDate = secondToDate;
735 $.secondToDate2 = secondToDate2;
736})( jQuery );
737
738
739$( document ).ajaxSuccess( function( event, xhr, settings ) {
740 var rsp = xhr.responseText;
741 rsp = $.parseJSON( rsp );
742 // console.log(event, xhr, settings);
743 var ignore = [
744 'api\/xqsystem\/login',
745 'api\/xqsystem\/upgrade_rom'
746 ];
747 for (var i = 0; i < ignore.length; i++) {
748 var ignoreTest = new RegExp(ignore[i]);
749 // console.log( ignoreTest );
750 if ( ignoreTest.test( settings.url ) ) {
751 return;
752 }
753 }
754 if ( rsp.code === 401 || rsp.code === 403) {
755 document.location.href = 'http://' + location.host;
756 }
757} );
758
759$.sub( 'wait', function( evt, data ){
760 var selector = data.id;
761 if ( !$.waitStatus) {
762 $.waitStatus = {};
763 }
764 $.waitStatus[selector] = $( selector ).text();
765 $( selector ).addClass('btn-primary-disabled').prop( 'disabled' , true ).find('span').text( 'Just a sec…...' );
766} );
767
768$.sub( 'done', function( evt, data ){
769 var selector = data.id,
770 text = $.waitStatus[selector];
771 $( selector ).removeClass('btn-primary-disabled').prop( 'disabled' , false ).find('span').text( text );
772} );
773
774$.sub( 'loading:start', function(){
775 var isLoading = $('html').hasClass('isloading');
776 if ( isLoading ) {
777 return;
778 }
779 var tplMask = '<div id="panel-loading-mask" class="panel-mask" style="position:fixed;left:0;top:0;style:none;"></div>',
780 tplLoading = ''
781 +'<div id="panel-loading" class="panel-loading" style="style:none;">'
782 + '<img src="/img/loading2.gif">'
783 +'</div>',
784 $mask = $( tplMask ),
785 $loading = $( tplLoading ),
786 zIndex = 10000;
787 $mask.css({
788 'z-index': zIndex,
789 width: $(window).width() + 'px',
790 height: $(window).height() + 'px'
791 });
792 $loading.css({'z-index': zIndex + 1});
793 $mask.appendTo( document.body ).show();
794 $loading.appendTo( document.body ).show();
795 $('html').addClass('isloading');
796} );
797
798$.sub( 'loading:stop', function(){
799 $('html').removeClass('isloading');
800 $('#panel-loading, #panel-loading-mask').remove();
801});
802
803// dialog block loading
804(function( $ ){
805 $.loadingDialog = function( config ){
806 var mix = ObjectH.mix,
807 _config = config || {
808 title: '',
809 content: ''
810 },
811 conf = mix( _config, {
812 width: 390,
813 padding:'25px 30px',
814 title: config.title,
815 content: '<p style="padding-bottom:30px;">{$content}</p><div class="loading-bar"></div>'.tmpl({content: config.content}),
816 cancel: false
817 }, true ),
818 dialog = $.dialog( conf );
819
820 var oldcontent = dialog.content;
821 dialog.content = function( cont ){
822 var _cont = '<p style="padding-bottom:30px;">{$content}</p><div class="loading-bar"></div>'.tmpl({content: cont});
823 return oldcontent.call( dialog, _cont);
824 };
825 return dialog;
826 }
827})(jQuery);
828
829// dialog alert
830(function( $ ){
831 $.alert = function( content, ok ){
832 ok = ok || function(){};
833 return $.dialog({
834 width: 390,
835 padding:'25px 30px',
836 title: 'Attention',
837 content: content,
838 ok: ok,
839 cancel: false
840 });
841 }
842})(jQuery);
843
844// dialog confirm
845(function( $ ){
846 $.confirm = function( content, ok, cancel ){
847 var _cancel = cancel || function(){};
848 return $.dialog({
849 width: 390,
850 padding:'25px 30px',
851 title: 'Confirm info',
852 content: content,
853 ok: ok,
854 cancel: _cancel,
855 lock: true
856 });
857 }
858})(jQuery);
859
860// wechat code dialog
861$(function(){
862 $( '#wechatcode' ).click(function( e ){
863 e.preventDefault();
864 var $this = $( this ),
865 href = $this.attr( 'href' );
866 $.dialog({
867 title: 'Official WeChat',
868 content: '<img width="200" src="'+ href +'">',
869 width: 250,
870 lock: true
871 });
872 });
873});
874
875
876// set sys language
877(function($){
878 $.i18nSet = function( el ){
879 var $lan = $( el ),
880 apiGetLan = '/cgi-bin/luci/api/xqsystem/get_languages',
881 apiSetlan = '/cgi-bin/luci/api/xqsystem/set_language',
882 dtd = $.Deferred();
883
884 $.get(apiGetLan, function( rsp ){
885 var rsp = $.parseJSON( rsp );
886 var selectContent = [];
887 if ( rsp.code == 0 ) {
888 for (var i = 0; i < rsp.list.length; i++) {
889 var item = rsp.list[i],
890 selected = item.lang == rsp.lang ? 'selected' : '',
891 option = '<option value="' + item.lang + '" '+ selected +'>' + item['name'] + '</option>';
892 // clear old conf en item
893 // if ( item.lang != 'en') {
894 selectContent.push(option);
895 // }
896 };
897 $lan.html( selectContent.join('') );
898 dtd.resolve();
899 }
900 });
901
902 $lan.on('change', function( e ){
903 var el = this,
904 val = $(this).val();
905 $.pub('loading:start');
906 $.post(apiSetlan, {language: val}, function( rsp ){
907 var rsp = $.parseJSON( rsp );
908 if ( rsp.code == 0 ) {
909 location.reload( 1 );
910 } else {
911 $.alert( rsp.msg );
912 }
913 $.pub('loading:stop');
914 });
915 });
916
917 return dtd.promise();
918 };
919}(jQuery));
920
921
922
923// global event
924(function($){
925 var dlgReboot,
926 dlgShutdown,
927 dlgRouterName;
928 function getNotice(){
929 $.getJSON('/cgi-bin/luci/api/misystem/messages', function(rsp){
930 if ( rsp.code == 0 ) {
931 var classname;
932 if ( rsp.count > 0 ) {
933 classname = 'ico-notice-new';
934 } else {
935 classname = 'ico-notice';
936 }
937 $('#sysnotice')[0].className = classname;
938 var msgMap = {
939 '1': '<p>Update available: {$version},<a href="/cgi-bin/luci/web/setting/upgrade">Update now</a>。</p>',
940 '3': '<p>Couldn't turn on 5G Wi-Fi<a target="_blank" href="http://www.mi.com/service/contact/">Contact Xiaomi customer support</a></p>',
941 '4': '<p>IP conflict detected, try switching to<a href="/cgi-bin/luci/web/setting/wan#netmode">Wired amplifier mode</a>or<a href="#" id="ipconflict" data-ip="{$ip}">Avoid IP conflicts</p>'
942 };
943 var msgHTML = [];
944 for (var i = rsp.messages.length - 1; i >= 0; i--) {
945 msgHTML.push(msgMap[rsp.messages[i].type].tmpl(rsp.messages[i].data));
946 };
947 $('#noticebar .content').html( msgHTML.join('') );
948
949 if ( rsp.count > 0 ) {
950 $('#sysnotice').trigger('click');
951 }
952 }
953 });
954 }
955 function reNameHandler(e){
956 e.preventDefault();
957 $.getJSON('/cgi-bin/luci/api/misystem/router_name')
958 .done(function( rsp ){
959 if ( rsp.code == 0 ) {
960 var html = StringH.tmpl($('#tplrename').html() , {
961 locale: StringH.encode4HtmlValue(rsp.locale),
962 name: StringH.encode4HtmlValue(rsp.name)
963 });
964 dlgRouterName = $.dialog({
965 width: 390,
966 title: 'Change router name',
967 content: html,
968 lock: true
969 });
970 setTimeout(function(){
971 $.formInit('.mod-rename-dlg');
972 $.selectBeautify({container: '.mod-rename-dlg'});
973 }, 100);
974 }
975 });
976 }
977 function downloadClientHandler(e){
978 e.preventDefault();
979 $.dialog({
980 width: 390,
981 title: 'Download APP',
982 content: $('#tpldownloadclient').html(),
983 lock: true
984 });
985 setTimeout(function(){
986 $('.onlineimg').each(function(){
987 var img = new Image();
988 var el = this;
989 var remote = el.src;
990 var local = $(el).attr('src-local');
991 img.onerror = function(){
992 el.src = local;
993 }
994 img.src = remote;
995 });
996 }, 100);
997 }
998 function rebootHandler(e){
999 e.preventDefault();
1000 dlgReboot = $.dialog({
1001 width: 390,
1002 title: 'Reboot router?',
1003 content: $('#tplreboot').html(),
1004 lock: true
1005 });
1006 }
1007 function shutdownHandler(e){
1008 e.preventDefault();
1009 dlgShutdown = $.dialog({
1010 width: 390,
1011 title: 'Power off',
1012 content: $('#tplshutdown').html(),
1013 lock: true
1014 });
1015 }
1016
1017 function noticeHandler(e){
1018 e.preventDefault();
1019 var that = this,
1020 $this = $(this),
1021 pos = $('#userbar').position(),
1022 right,
1023 wt = 1160,
1024 wwt = $(window).width(),
1025 $arrow = $('#noticebar .ico-arrow');
1026 if ( $this.hasClass('ico-notice-new') ) {
1027 // right = wt - pos.left - 20;
1028 $arrow.css({'right': '10px'});
1029 $('#noticebar').css({'right': (wwt - wt) /2 });
1030 $('#noticebar').toggle();
1031 }
1032 $('#maskMenu').height($(window).height());
1033 $('#maskMenu').show();
1034 }
1035
1036 function sysmenuHandler(e){
1037 e.preventDefault();
1038 var that = this,
1039 $this = $(this);
1040 if ( $this.hasClass('s-dropdown') ){
1041 var ww = $(window).width();
1042 // var rt = (ww - 1160) / 2;
1043 var lt = $this.offset().left + $this.outerWidth() - $('#dropmenu').width();
1044 $('#dropmenu').css({left: lt});
1045 $('#dropmenu').show();
1046 that.className = 'name s-dropup';
1047 }else{
1048 $('#dropmenu').hide();
1049 that.className = 'name s-dropdown';
1050 }
1051 $('#maskMenu').height($(window).height());
1052 $('#maskMenu').show();
1053 }
1054
1055 function maskHandler(e){
1056 e.preventDefault();
1057 $('#noticebar').hide();
1058 $('#dropmenu').hide();
1059 $('#maskMenu').hide();
1060 $('#sysmenu')[0].className = 'name s-dropdown';
1061 }
1062
1063 $(function(){
1064 // notice
1065 $('#sysnotice').click(noticeHandler);
1066 // user dropmenu
1067 $('#sysmenu').click(sysmenuHandler);
1068 // space click
1069 $('#maskMenu').click(maskHandler);
1070 // rename
1071 $( 'body' ).delegate( '#toRename', 'click', reNameHandler );
1072 // toDownloadClient
1073 $( 'body' ).delegate( '#toDownloadClient', 'click', downloadClientHandler );
1074 // toReboot
1075 $( 'body' ).delegate( '#toReboot', 'click', rebootHandler );
1076 // toShutdown
1077 $( 'body' ).delegate( '#toShutdown', 'click', shutdownHandler);
1078
1079 $( 'body' ).delegate( '#shutdownAction', 'click', function( e ){
1080 e.preventDefault();
1081 dlgShutdown.close();
1082 shutdown_window();
1083 } );
1084
1085 $( 'body' ).delegate( '#rebootAction', 'click', function( e ){
1086 e.preventDefault();
1087 dlgReboot.close();
1088 reboot_window();
1089 } );
1090
1091 $( 'body' ).delegate( '#routerNameEdit', 'submit', function( e ){
1092 e.preventDefault();
1093 var validator = Valid.checkAll( this );
1094 var routername = $('#routername').val();
1095 var locale = $('#locale').val();
1096 if ( validator ) {
1097 $.getJSON('/cgi-bin/luci/api/misystem/set_router_name',{
1098 name: routername,
1099 locale: locale
1100 }).done(function(rsp){
1101 if ( rsp.code == 0 ) {
1102 location.reload(1);
1103 } else {
1104 $.alert( rsp.msg )
1105 }
1106 });
1107 }
1108 } );
1109
1110 $( 'body' ).delegate('#ipconflict', 'click', function(e){
1111 e.preventDefault();
1112 var api = '/cgi-bin/luci/api/misystem/r_ip_conflict',
1113 ip = $(this).attr('data-ip');
1114 $.dialog({
1115 title: 'Avoid IP conflicts',
1116 content: 'To perform this action, your IP will be changed to' + ip + '<br>' +'Wi-Fi network will be reset. Network connection may be lost briefly.',
1117 lock: true,
1118 ok: function(){
1119 $.post(api, function(rsp){
1120 rsp = $.parseJSON(rsp);
1121 if (rsp.code !== 0) {
1122 alert(rsp.msg);
1123 }
1124 });
1125 },
1126 cancel: function(){}
1127 });
1128 });
1129
1130 // user logined and has global header get notice
1131 if ( typeof(GLOBALHEADER) !== 'undefined' && GLOBALHEADER === true ) {
1132 getNotice();
1133 }
1134 });
1135})(jQuery);
1136</script>
1137<script src="/js/miwifi-monitor.js"></script>
1138<script>
1139// 流量统计
1140(function(){
1141 var IS_MOBILE = (
1142 navigator.userAgent.match(/Android/i)
1143 || navigator.userAgent.match(/webOS/i)
1144 || navigator.userAgent.match(/iPhone/i)
1145 || navigator.userAgent.match(/iPad/i)
1146 || navigator.userAgent.match(/iPod/i)
1147 || navigator.userAgent.match(/BlackBerry/i)
1148 || navigator.userAgent.match(/Windows Phone/i)
1149 );
1150 var PAGEURL = document.URL.split('/web/')[1];
1151 var PAGE_MONITOR_CONF = {
1152 deviceId: 'c15b1060-98f4-1217-ffe3-ce5385a2e120',
1153 isMobile: IS_MOBILE ? IS_MOBILE[0] : 'pc',
1154 url: PAGEURL ? '/web/' + PAGEURL : '/web/login',
1155 romVersion: '2.8.51',
1156 romChannel: 'release',
1157 hardwareVersion: 'R3L'
1158 };
1159 MIWIFI_MONITOR.setProject('MIWIFIWEB');
1160 MIWIFI_MONITOR.log(PAGE_MONITOR_CONF, 'track');
1161
1162 $(document).ajaxSend(function(event, jqxhr, settings) {
1163 var apiUrl = settings.url.split('/api/')[1],
1164 api = '/api/' + apiUrl.split('?')[0],
1165 apiParams = StringH.queryUrl(apiUrl);
1166
1167 // console.log(apiUrl, api, apiParams);
1168
1169 var API_MONITOR_CONF = ObjectH.mix({element: 'apicall', api: api}, [PAGE_MONITOR_CONF, apiParams]);
1170 // console.log(API_MONITOR_CONF);
1171 MIWIFI_MONITOR.log(API_MONITOR_CONF);
1172 });
1173}());
1174</script>
1175
1176<script>
1177$(function(){
1178 var pwdErrorCount = 0;
1179 $( '#password' ).focus();
1180
1181 $( '#password' ).on( 'keypress', function( e ) {
1182 $('#rtloginform .form-item' ).removeClass( 'form-item-err' );
1183 $('#rtloginform .form-item .t' ).hide();
1184 });
1185
1186 function buildUrl( s, token ){
1187 if (!window.location.origin){
1188 window.location.origin = window.location.protocol+"//"+window.location.host;
1189 }
1190 return window.location.origin + '/cgi-bin/luci/;stok=' + token+ '/web/setting/' + s;
1191 }
1192
1193 function loginHandle ( e ) {
1194 e.preventDefault();
1195 var formObj = document.rtloginform;
1196 var pwd = $( '#password' ).val();
1197 if ( pwd == '') {
1198 return;
1199 }
1200 var nonce = Encrypt.init();
1201 var oldPwd = Encrypt.oldPwd( pwd );
1202 var param = {
1203 username: 'admin',
1204 password: oldPwd,
1205 logtype: 2,
1206 nonce: nonce
1207 };
1208 $.pub('loading:start');
1209 var url = '/cgi-bin/luci/api/xqsystem/login';
1210 $.post( url, param, function( rsp ) {
1211 $.pub('loading:stop');
1212 var rsp = $.parseJSON( rsp );
1213 if ( rsp.code == 0 ) {
1214 var redirect,
1215 token = rsp.token;
1216 if ( /action=wan/.test(location.href) ) {
1217 redirect = buildUrl('wan', token);
1218 } else if ( /action=lannetset/.test(location.href) ) {
1219 redirect = buildUrl('lannetset', token);
1220 } else {
1221 redirect = rsp.url;
1222 }
1223 window.location.href = redirect;
1224 } else if ( rsp.code == 403 ) {
1225 window.location.reload();
1226 } else {
1227 pwdErrorCount ++;
1228 var errMsg = 'The password you entered is invalid.';
1229 if (pwdErrorCount >= 4) {
1230 errMsg = 'Wrong password entered multiple times. Future attempts will be blocked.';
1231 }
1232 Valid.fail( document.getElementById('password'), errMsg, false);
1233 $( formObj )
1234 .addClass( 'shake animated' )
1235 .one( 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function(){
1236 $('#password').focus();
1237 $( this ).removeClass('shake animated');
1238 } );
1239 }
1240 });
1241 }
1242 $( '#rtloginform' ).on( 'submit', loginHandle);
1243 $( '#btnRtSubmit' ).on( 'click', loginHandle);
1244 $.placeholder();
1245});
1246</script>