1/* Plugin */
2if (!Object.keys) {
3  Object.keys = (function() {
4    'use strict';
5    var hasOwnProperty = Object.prototype.hasOwnProperty,
6        hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
7        dontEnums = [
8          'toString',
9          'toLocaleString',
10          'valueOf',
11          'hasOwnProperty',
12          'isPrototypeOf',
13          'propertyIsEnumerable',
14          'constructor'
15        ],
16        dontEnumsLength = dontEnums.length;
17
18    return function(obj) {
19      if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
20        throw new TypeError('Object.keys called on non-object');
21      }
22
23      var result = [], prop, i;
24
25      for (prop in obj) {
26        if (hasOwnProperty.call(obj, prop)) {
27          result.push(prop);
28        }
29      }
30
31      if (hasDontEnumBug) {
32        for (i = 0; i < dontEnumsLength; i++) {
33          if (hasOwnProperty.call(obj, dontEnums[i])) {
34            result.push(dontEnums[i]);
35          }
36        }
37      }
38      return result;
39    };
40  }());
41}
42
43var isJsonChanged = function(objNew, objOld){
44	for(var i in objOld){
45		if(typeof objOld[i] == "object"){
46			if(objNew[i].join() != objOld[i].join()){
47				return true;
48			}
49		}
50		else{
51			if(typeof objNew[i] == "undefined" || objOld[i] != objNew[i]){
52				return true;
53			}
54		}
55	}
56
57    return false;
58};
59
60/**
61 * Implements cookie-less JavaScript session variables
62 * v1.0
63 *
64 * By Craig Buckler, Optimalworks.net
65 *
66 * As featured on SitePoint.com
67 * Please use as you wish at your own risk.
68*
69 * Usage:
70 *
71 * // store a session value/object
72 * Session.set(name, object);
73 *
74 * // retreive a session value/object
75 * Session.get(name);
76 *
77 * // clear all session data
78 * Session.clear();
79 *
80 * // dump session data
81 * Session.dump();
82 */
83
84 if (JSON && JSON.stringify && JSON.parse) var Session = Session || (function() {
85
86	// window object
87	var win = window.top || window;
88
89	// session store
90	var store = (win.name ? JSON.parse(win.name) : {});
91
92	// save store on page unload
93	function Save() {
94		win.name = JSON.stringify(store);
95	};
96
97	// page unload event
98	if (window.addEventListener) window.addEventListener("unload", Save, false);
99	else if (window.attachEvent) window.attachEvent("onunload", Save);
100	else window.onunload = Save;
101
102	// public methods
103	return {
104
105		// set a session variable
106		set: function(name, value) {
107			store[name] = value;
108		},
109
110		// get a session value
111		get: function(name) {
112			return (store[name] ? store[name] : undefined);
113		},
114
115		// clear session
116		clear: function() { store = {}; },
117
118		// dump session data
119		dump: function() { return JSON.stringify(store); }
120
121	};
122
123 })();
124
125var ipState = new Array();
126ipState["Static"] =  "<#BOP_ctype_title5#>";
127ipState["DHCP"] =  "<#BOP_ctype_title1#>";
128ipState["Manual"] =  "MAC-IP Binding";
129ipState["OffLine"] =  "Client is disconnected";
130
131var venderArrayRE = /(adobe|amazon|apple|asus|belkin|bizlink|buffalo|dell|d-link|fujitsu|google|hon hai|htc|huawei|ibm|lenovo|nec|microsoft|panasonic|pioneer|ralink|samsung|sony|synology|toshiba|tp-link|vmware)/;
132function transformManufacturerName(_db_manufacturerName) {
133	var manufacturerName = "";
134	var manufacturerMatch = _db_manufacturerName.trim().toLowerCase().match(venderArrayRE);
135	if(Boolean(manufacturerMatch)) {
136		manufacturerName = manufacturerMatch[0];
137	}
138	else {
139		manufacturerName = _db_manufacturerName.trim();
140	}
141	return manufacturerName;
142}
143
144function convType(str){
145	if(str.length == 0)
146		return 0;
147	/*
148	Unknown			0
149	Windows device  1
150	Router			2
151	Router			3
152	NAS/Server		4
153	IP Cam			5
154	Macbook			6
155	Game Console	7
156	Game Console	8
157	Android Phone	9
158	iPhone			10
159	Apple TV		11
160	Set-top Box 	12
161	Windows device  13
162	iMac			14
163	ROG				15
164	Game Console	16
165	Game Console	17
166	Printer			18
167	Windows Phone	19
168	Android Tablet 	20
169	iPad			21
170	Linux Device	22
171	Smart TV		23
172	Repeater		24
173	Kindle			25
174	Scanner			26
175	Chromecast		27
176	ASUS smartphone	28
177	ASUS Pad 		29
178	Windows			30
179	Android			31
180	Mac OS			32
181	Smartphone		33
182	Desktop			34
183	*/
184
185	var siganature = [[], ["win", "pc", "nb"], ["rt-", "dsl-", "pl-"], [], ["nas", "storage"], ["cam"], ["mac", "mbp", "mba"], ["play station", "playstation", "xbox"],
186	[], ["android", "htc"], ["iphone", "ipod"], ["appletv", "apple tv", "apple-tv"], [], [], ["imac"], ["rog"], [], [], ["epson", "fuji xerox", "hp", "canon", "brother"],
187	[], [], ["ipad"], ["linux"], [], ["rp-", "ea-", "wmp-"]];
188	for(var i=0; i<siganature.length; i++){
189		for(var j=0; j<siganature[i].length; j++){
190			if(str.toString().toLowerCase().search(siganature[i][j].toString().toLowerCase()) != -1){
191				return i;
192				break;
193			}
194		}
195	}
196
197	return 0;
198}
199
200<% login_state_hook(); %>
201/* End */
202
203/* get client info form dhcp lease log */
204var leaseArray = {
205	hostname: [],
206	mac: []
207};
208
209var retHostName = function(_mac){
210	return leaseArray.hostname[leaseArray.mac.indexOf(_mac.toUpperCase())] || _mac;
211}
212/* end */
213
214var networkmap_fullscan = '<% nvram_get("networkmap_fullscan"); %>';
215var fromNetworkmapdCache = '<% nvram_get("client_info_tmp"); %>'.replace(/&#62/g, ">").replace(/&#60/g, "<").split('<');
216
217var originDataTmp;
218var originData = {
219	customList: decodeURIComponent('<% nvram_char_to_ascii("", "custom_clientlist"); %>').replace(/&#62/g, ">").replace(/&#60/g, "<").split('<'),
220	asusDevice: decodeURIComponent('<% nvram_char_to_ascii("", "asus_device_list"); %>').replace(/&#62/g, ">").replace(/&#60/g, "<").split('<'),
221	fromDHCPLease: <% dhcpLeaseMacList(); %>,
222	staticList: decodeURIComponent('<% nvram_char_to_ascii("", "dhcp_staticlist"); %>').replace(/&#62/g, ">").replace(/&#60/g, "<").split('<'),
223	fromNetworkmapd: '<% get_client_detail_info(); %>'.replace(/&#62/g, ">").replace(/&#60/g, "<").split('<'),
224	fromBWDPI: <% bwdpi_device_info(); %>.replace(/&#62/g, ">").replace(/&#60/g, "<").split('<'),
225	nmpClient: decodeURIComponent('<% load_clientlist_char_to_ascii(); %>').replace(/&#62/g, ">").replace(/&#60/g, "<").split('<'), //Record the client connected to the router before.
226	wlList_2g: [<% wl_sta_list_2g(); %>],
227	wlList_5g: [<% wl_sta_list_5g(); %>],
228	wlList_5g_2: [<% wl_sta_list_5g_2(); %>],
229	wlListInfo_2g: [<% wl_stainfo_list_2g(); %>],
230	wlListInfo_5g: [<% wl_stainfo_list_5g(); %>],
231	wlListInfo_5g_2: [<% wl_stainfo_list_5g_2(); %>],
232	qosRuleList: decodeURIComponent('<% nvram_char_to_ascii("", "qos_rulelist"); %>').replace(/&#62/g, ">").replace(/&#60/g, "<").split('<'),
233	time_scheduling_enable: decodeURIComponent('<% nvram_char_to_ascii("", "MULTIFILTER_ENABLE"); %>').replace(/&#62/g, ">").replace(/&#60/g, "<").split('>'),
234	time_scheduling_mac: decodeURIComponent('<% nvram_char_to_ascii("", "MULTIFILTER_MAC"); %>').replace(/&#62/g, ">").replace(/&#60/g, "<").split('>'),
235	time_scheduling_devicename: decodeURIComponent('<% nvram_char_to_ascii("", "MULTIFILTER_DEVICENAME"); %>').replace(/&#62/g, ">").replace(/&#60/g, "<").split('>'),
236	time_scheduling_daytime: decodeURIComponent('<% nvram_char_to_ascii("", "MULTIFILTER_MACFILTER_DAYTIME"); %>').replace(/&#62/g, ">").replace(/&#60/g, "<").split('>'),
237	current_time: '<% uptime(); %>',
238	wtf_rulelist: decodeURIComponent('<% nvram_char_to_ascii("", "wtf_rulelist"); %>').replace(/&#62/g, ">").replace(/&#60/g, "<").split('<'),
239	init: true
240}
241
242var totalClientNum = {
243	online: 0,
244	wireless: 0,
245	wired: 0,
246	wireless_ifnames: []
247}
248
249var setClientAttr = function(){
250	this.type = "0";
251	this.defaultType = "0";
252	this.name = "";
253	this.nickName = "";
254	this.ip = "offline";
255	this.mac = "";
256	this.from = "";
257	this.macRepeat = 1;
258	this.group = "";
259	this.rssi = "";
260	this.ssid = "";
261	this.isWL = 0; // 0: wired, 1: 2.4GHz, 2: 5GHz/5GHz-1 3:5GHz-2.
262	this.qosLevel = "";
263	this.curTx = "";
264	this.curRx = "";
265	this.totalTx = "";
266	this.totalRx = "";
267	this.callback = "";
268	this.keeparp = "";
269	this.isGateway = false;
270	this.isWebServer = false;
271	this.isPrinter = false;
272	this.isITunes = false;
273	this.isASUS = false;
274	this.isLogin = false;
275	this.isOnline = false;
276	this.ipMethod = "Static";
277	this.opMode = 0;
278	this.wlConnectTime = "00:00:00";
279	this.vendor = "";
280	this.dpiType = "";
281	this.dpiDevice = "";
282	this.internetMode = "allow";
283	this.internetState = 1; // 1:Allow Internet access, 0:Block Internet access
284	this.wtfast = 0;
285}
286
287var ouiClientListArray = new Array();
288ouiClientListArray = Session.get("ouiDB");
289if(ouiClientListArray == undefined) {
290	ouiClientListArray = [];
291	//Download OUI DB
292	setTimeout(function() {
293		var ouiBDjs = document.createElement("script");
294		ouiBDjs.type = "application/javascript";
295		ouiBDjs.src = "http://nw-dlcdnet.asus.com/plugin/js/ouiDB.js";
296		window.document.body.appendChild(ouiBDjs);
297	}, 1000);
298}
299
300function updateManufacturer(_ouiDBArray) {
301	ouiClientListArray = [];
302	ouiClientListArray = _ouiDBArray;
303	var manufacturer_id = "";
304	var mac = "";
305	var ori_name = "";
306	for(var i = 0; i < clientList.length; i += 1) {
307		mac = clientList[i];
308		manufacturer_id = mac.replace(/\:/g,"").substring(0, 6);
309		if(_ouiDBArray[manufacturer_id] != undefined) {
310			clientList[mac].vendor = transformManufacturerName(_ouiDBArray[manufacturer_id]);
311		}
312		ori_name = clientList[mac].name;
313		clientList[mac].name = replaceClientName(ori_name, mac);
314	}
315
316	Session.set("ouiDB", _ouiDBArray);
317}
318
319function replaceClientName(_name, _mac) {
320	var filterStr = "android";
321	var replaceName = _name.trim();
322	var manufacturer_id = _mac.replace(/\:/g,"").substring(0, 6);
323	var manufacturer_name = "";
324	if(replaceName == _mac) {
325		if(ouiClientListArray[manufacturer_id] != undefined) {
326			manufacturer_name = transformManufacturerName(ouiClientListArray[manufacturer_id]);
327			replaceName = manufacturer_name.toUpperCase().charAt(0) + manufacturer_name.substring(1);
328		}
329	}
330	else {
331		if(replaceName.search(filterStr) != -1) {
332			if(ouiClientListArray[manufacturer_id] != undefined) {
333				manufacturer_name = transformManufacturerName(ouiClientListArray[manufacturer_id]);
334				replaceName = manufacturer_name.toUpperCase().charAt(0) + manufacturer_name.substring(1);
335			}
336		}
337	}
338
339	if(replaceName.length > 32) {
340		replaceName = replaceName.substring(0, 32);
341	}
342	return replaceName;
343}
344
345var clientList = new Array(0);
346var time_scheduling_array = new Array();
347function genClientList(){
348	var updateTimeScheduling = function() {
349		if('<% nvram_get("MULTIFILTER_ALL"); %>' == "1") {
350			if(time_scheduling_array[thisClientMacAddr] != undefined) {
351				if(time_scheduling_array[thisClientMacAddr][0] == "1") {
352					clientList[thisClientMacAddr].internetMode = "block";
353					if(time_scheduling_array[thisClientMacAddr][1] != "<") {
354						clientList[thisClientMacAddr].internetMode = "time";
355						clientList[thisClientMacAddr].internetState = 0;
356						if(clientInternetState(thisClientMacAddr))
357							clientList[thisClientMacAddr].internetState = 1;
358					}
359					else {
360						clientList[thisClientMacAddr].internetState = 0;
361					}
362				}
363			}
364		}
365	};
366
367	leaseArray = {hostname: [], mac: []};
368	for(var i = 0; i < originData.fromDHCPLease.length; i += 1) {
369		var dhcpMac = originData.fromDHCPLease[i][0].toUpperCase();
370		var dhcpName = decodeURIComponent(originData.fromDHCPLease[i][1]);
371		if(dhcpMac != "") {
372			if(dhcpName == "*") {
373				dhcpName = dhcpMac;
374			}
375			leaseArray.mac.push(dhcpMac);
376			leaseArray.hostname.push(dhcpName);
377		}
378	}
379
380	clientList = [];
381	totalClientNum.online = 0;
382	totalClientNum.wireless = 0;
383	for(var i=0; i<wl_nband_title.length; i++) totalClientNum.wireless_ifnames[i] = 0;
384
385	//initial time_scheduling
386	for(var schedulingIdx = 0; schedulingIdx < originData.time_scheduling_mac.length; schedulingIdx += 1) {
387		if(originData.time_scheduling_mac[schedulingIdx] != "") {
388			var scheduling_array =  new Array();
389			scheduling_array[0] =  originData.time_scheduling_enable[schedulingIdx];
390			scheduling_array[1] = originData.time_scheduling_daytime[schedulingIdx];
391			time_scheduling_array[originData.time_scheduling_mac[schedulingIdx]] = scheduling_array;
392		}
393	}
394
395	var wirelessList = "";
396	var wirelessListArray = new Array();
397	var local_mac = '<% nvram_get("lan_hwaddr"); %>';
398	if(fromNetworkmapdCache.length > 1 && networkmap_fullscan == 1) {
399		originData.fromNetworkmapd = fromNetworkmapdCache;
400		var wirelessListCache = cookie.get("wireless_list_" + local_mac + "_temp");
401		if(wirelessListCache != null && wirelessListCache != "") {
402			wirelessList = wirelessListCache;
403		}
404	}
405	else {
406		wirelessList = cookie.get("wireless_list_" + local_mac);
407	}
408
409	//initial wirelessListArray
410	if(wirelessList != null && wirelessList != "") {
411		var wirelessList_row = wirelessList.split("<");
412		for(var i = 0; i < wirelessList_row.length; i += 1) {
413			var wirelessList_col = wirelessList_row[i].split(">");
414			wirelessListArray[wirelessList_col[0]] = "No";
415		}
416	}
417
418	for(var i=0; i<originData.asusDevice.length; i++){
419		var thisClient = originData.asusDevice[i].split(">");
420		var thisClientMacAddr = (typeof thisClient[3] == "undefined") ? false : thisClient[3].toUpperCase();
421
422		if(!thisClientMacAddr || thisClient.length != 8 || thisClient[2] == '<% nvram_get("lan_ipaddr"); %>'){
423			continue;
424		}
425
426		if(typeof clientList[thisClientMacAddr] == "undefined"){
427			clientList.push(thisClientMacAddr);
428			clientList[thisClientMacAddr] = new setClientAttr();
429			clientList[thisClientMacAddr].from = "asusDevice";
430		}
431		else{
432			clientList[thisClientMacAddr].from = "asusDevice";
433		}
434
435		if(!downsize_4m_support) {
436			clientList[thisClientMacAddr].type = "2";// asus default setting router icon
437			clientList[thisClientMacAddr].defaultType = "2";
438		}
439		clientList[thisClientMacAddr].name = thisClient[1];
440		//Exception Handling AiCam type
441		if(thisClient[1].toString().toLowerCase().search("cam") != -1 && !downsize_4m_support) {
442			clientList[thisClientMacAddr].type = "5";// AiCam icon
443			clientList[thisClientMacAddr].defaultType = "5";
444		}
445		clientList[thisClientMacAddr].ip = thisClient[2];
446		clientList[thisClientMacAddr].mac = thisClient[3];
447		clientList[thisClientMacAddr].isGateway = (thisClient[2] == '<% nvram_get("lan_ipaddr"); %>') ? true : false;
448		clientList[thisClientMacAddr].isWebServer = true;
449		clientList[thisClientMacAddr].ssid = thisClient[5];
450		clientList[thisClientMacAddr].isASUS = true;
451		clientList[thisClientMacAddr].opMode = (typeof thisClient[7] == "undefined") ? 0 : thisClient[7]; //0:unknow, 1: router, 2: repeater, 3: AP, 4: Media Bridge
452		if(clientList[thisClientMacAddr].opMode == "2" && !downsize_4m_support) {
453			clientList[thisClientMacAddr].type = "24";
454			clientList[thisClientMacAddr].defaultType = "24";
455		}
456		clientList[thisClientMacAddr].isOnline = true;
457		totalClientNum.online++;
458
459		clientList[thisClientMacAddr].vendor = "Asus";
460		updateTimeScheduling();
461	}
462
463	for(var i=0; i<originData.fromNetworkmapd.length; i++){
464		var thisClient = originData.fromNetworkmapd[i].split(">");
465		var thisClientMacAddr = (typeof thisClient[3] == "undefined") ? false : thisClient[3].toUpperCase();
466
467		if(!thisClientMacAddr || thisClient.length != 8){
468			continue;
469		}
470
471		if(typeof clientList[thisClientMacAddr] == "undefined"){
472			clientList.push(thisClientMacAddr);
473			clientList[thisClientMacAddr] = new setClientAttr();
474			clientList[thisClientMacAddr].from = "networkmapd";
475		}
476		else{
477			//because asusDevice had count, so not need count again.
478			if(clientList[thisClientMacAddr].from == "asusDevice") {
479				clientList[thisClientMacAddr].from = "networkmapd";
480				continue;
481			}
482			else {
483				clientList[thisClientMacAddr].macRepeat++;
484				totalClientNum.online++;
485				continue;
486			}
487		}
488
489		//if the client have created by asusDevice, do not update data.
490		if(clientList[thisClientMacAddr].isASUS) {
491			continue;
492		}
493
494		if(!downsize_4m_support) {
495			clientList[thisClientMacAddr].type = thisClient[0];
496			clientList[thisClientMacAddr].defaultType = thisClient[0];
497		}
498
499		clientList[thisClientMacAddr].ip = thisClient[2];
500		clientList[thisClientMacAddr].mac = thisClient[3];
501
502		var ori_name = (thisClient[1].trim() != "") ? thisClient[1].trim() : retHostName(clientList[thisClientMacAddr].mac);
503		if(clientList[thisClientMacAddr].name == ""){
504			clientList[thisClientMacAddr].name = replaceClientName(ori_name, thisClientMacAddr);
505		}
506
507		if(ori_name != clientList[thisClientMacAddr].mac && clientList[thisClientMacAddr].type == "0" && !downsize_4m_support){
508			clientList[thisClientMacAddr].type = convType(ori_name);
509			clientList[thisClientMacAddr].defaultType = clientList[thisClientMacAddr].type;
510		}
511
512		clientList[thisClientMacAddr].isGateway = (thisClient[2] == '<% nvram_get("lan_ipaddr"); %>') ? true : false;
513		clientList[thisClientMacAddr].isWebServer = (thisClient[4] == 0) ? false : true;
514		clientList[thisClientMacAddr].isPrinter = (thisClient[5] == 0) ? false : true;
515		clientList[thisClientMacAddr].isITunes = (thisClient[6] == 0) ? false : true;
516		clientList[thisClientMacAddr].dpiDevice = (typeof thisClient[7] == "undefined") ? "" : thisClient[7]; //This field just for apple model
517		clientList[thisClientMacAddr].isOnline = true;
518		totalClientNum.online++;
519
520		var ouiVenderName = "";
521		var manufacturer_id = thisClientMacAddr.replace(/\:/g,"").substring(0, 6);
522		if(ouiClientListArray[manufacturer_id] != undefined) {
523			ouiVenderName = transformManufacturerName(ouiClientListArray[manufacturer_id]);
524			ouiVenderName = ouiVenderName.toLowerCase();
525			ouiVenderName = ouiVenderName.toUpperCase().charAt(0) + ouiVenderName.substring(1);
526		}
527		clientList[thisClientMacAddr].vendor = ouiVenderName;
528		updateTimeScheduling();
529	}
530
531	for(var i=0; i<originData.fromBWDPI.length; i++){
532		var thisClient = originData.fromBWDPI[i].split(">");
533		var thisClientMacAddr = (typeof thisClient[0] == "undefined") ? false : thisClient[0].toUpperCase();
534
535		if(typeof clientList[thisClientMacAddr] == "undefined"){
536			continue;
537		}
538
539		//if the client have created by asusDevice, do not update data.
540		if(clientList[thisClientMacAddr].isASUS) {
541			continue;
542		}
543
544		var networkmapd_name = clientList[thisClientMacAddr].name;
545		var bwdpi_name = "";
546
547		if(thisClient[1] != ""){
548			clientList[thisClientMacAddr].name = replaceClientName(thisClient[1], thisClientMacAddr);
549			if(clientList[thisClientMacAddr].type == "0" && !downsize_4m_support) {
550				clientList[thisClientMacAddr].type = convType(thisClient[1]);
551				clientList[thisClientMacAddr].defaultType = clientList[thisClientMacAddr].type;
552			}
553			bwdpi_name = thisClient[1];
554		}
555
556		if(thisClient[2] != "" && thisClient[2] != undefined){
557			var venderMatch = thisClient[2].trim().toLowerCase().match(venderArrayRE);
558			var venderName = "";
559			if(Boolean(venderMatch)) {
560				venderName = venderMatch[0].toLowerCase();
561				venderName = venderName.toUpperCase().charAt(0) + venderName.substring(1);
562				clientList[thisClientMacAddr].vendor = venderName;
563			}
564			else {
565				venderName = thisClient[2].trim().toLowerCase();
566				venderName = venderName.toUpperCase().charAt(0) + venderName.substring(1);
567				clientList[thisClientMacAddr].vendor = venderName;
568			}
569		}
570
571		if(thisClient[3] != "" && thisClient[3] != undefined){
572			clientList[thisClientMacAddr].dpiType = thisClient[3].trim();
573
574			if(!downsize_4m_support) {
575				var dpi_type = [["android device", "9"], ["apple ios device", "10"], ["smarttv", "23"], ["game console", "7"], ["ip network camera", "5"], ["nas", "4"],
576								["router", "2"], ["voip gateway", "2"], ["wireless", "2"], ["printer", "18"], ["scanner", "26"], ["smartphone", "33"], ["tablet", "33"],
577								["voip phone", "33"], ["desktop/laptop", "34"]];
578				for(var idx_dpi_type = 0; idx_dpi_type < dpi_type.length; idx_dpi_type += 1) {
579					if(thisClient[3].trim().toLowerCase() == dpi_type[idx_dpi_type][0]) {
580						clientList[thisClientMacAddr].type = dpi_type[idx_dpi_type][1];
581						clientList[thisClientMacAddr].defaultType = dpi_type[idx_dpi_type][1];
582						break;
583					}
584				}
585			}
586		}
587
588		if(thisClient[4] != "" && thisClient[4] != undefined){
589			clientList[thisClientMacAddr].dpiDevice = thisClient[4].trim();
590
591			if(!downsize_4m_support) {
592				var dpi_name = new Array();
593				dpi_name["desktop/laptop"] = [["mac os", "6"], ["macintosh", "14"], ["windows", "1"], ["linux", "22"]];
594				dpi_name["smartphone"] = [["apple", "10"], ["iphone", "10"], ["windows phone", "19"], ["nokia", "19"], ["mobile", "19"], ["asus", "28"], ["zenfone", "28"], ["padfone", "28"]];
595				dpi_name["smarttv"] = [["apple", "11"], ["chromecast", "27"]];
596				dpi_name["tablet"] = [["apple", "21"], ["ipad", "21"], ["kindle", "25"], ["asus", "29"], ["transformer", "29"], ["fonepad", "29"]];
597				var dpi_type_key = clientList[thisClientMacAddr].dpiType.toLowerCase();
598				var dpi_name_item = dpi_name[dpi_type_key];
599				if(dpi_name_item != undefined) {
600					switch(dpi_type_key) {
601						case "smartphone" :
602							clientList[thisClientMacAddr].type = "9";
603							clientList[thisClientMacAddr].defaultType = "9";
604							break;
605						case "smarttv" :
606							clientList[thisClientMacAddr].type = "23";
607							clientList[thisClientMacAddr].defaultType = "23";
608							break;
609						case "tablet" :
610							clientList[thisClientMacAddr].type = "20";
611							clientList[thisClientMacAddr].defaultType = "20";
612							break;
613					}
614					for(var idx_dpi_name = 0; idx_dpi_name < dpi_name_item.length; idx_dpi_name += 1) {
615						if(clientList[thisClientMacAddr].dpiDevice.toLowerCase().search(dpi_name_item[idx_dpi_name][0]) != -1) {
616							clientList[thisClientMacAddr].type = dpi_name_item[idx_dpi_name][1];
617							clientList[thisClientMacAddr].defaultType = dpi_name_item[idx_dpi_name][1];
618							break;
619						}
620					}
621				}
622			}
623		}
624
625		if(thisClient[3] != "" && thisClient[3] != undefined && thisClient[4] != "" && thisClient[4] != undefined) {
626			var filterStr = "android";
627			var replaceName = clientList[thisClientMacAddr].name;
628			if(networkmapd_name.toLowerCase().search(filterStr) != -1 || bwdpi_name.toLowerCase().search(filterStr) != -1) {
629				if(thisClient[3].toLowerCase().search(filterStr) != -1 && thisClient[4].toLowerCase().search(filterStr) != -1) {
630					replaceName = clientList[thisClientMacAddr].vendor + "(Android)";
631				}
632				else {
633					replaceName = thisClient[4];
634				}
635			}
636			clientList[thisClientMacAddr].name = replaceName;
637		}
638	}
639
640	for(var i=0; i<originData.customList.length; i++){
641		var thisClient = originData.customList[i].split(">");
642		var thisClientMacAddr = (typeof thisClient[1] == "undefined") ? false : thisClient[1].toUpperCase();
643
644		if(!thisClientMacAddr || thisClient.length != 6){
645			continue;
646		}
647
648		if(typeof clientList[thisClientMacAddr] == "undefined"){
649			clientList.push(thisClientMacAddr);
650			clientList[thisClientMacAddr] = new setClientAttr();
651			clientList[thisClientMacAddr].from = "customList";
652		}
653
654		clientList[thisClientMacAddr].nickName = thisClient[0];
655		clientList[thisClientMacAddr].mac = thisClient[1];
656		clientList[thisClientMacAddr].group = thisClient[2];
657		clientList[thisClientMacAddr].type = thisClient[3];
658		clientList[thisClientMacAddr].callback = thisClient[4];
659
660		if(clientList[thisClientMacAddr].vendor == "") {
661			var ouiVenderName = "";
662			var manufacturer_id = thisClientMacAddr.replace(/\:/g,"").substring(0, 6);
663			if(ouiClientListArray[manufacturer_id] != undefined) {
664				ouiVenderName = transformManufacturerName(ouiClientListArray[manufacturer_id]);
665				ouiVenderName = ouiVenderName.toLowerCase();
666				ouiVenderName = ouiVenderName.toUpperCase().charAt(0) + ouiVenderName.substring(1);
667			}
668			clientList[thisClientMacAddr].vendor = ouiVenderName;
669		}
670	}
671
672	for(var i=0; i<originData.wlList_2g.length; i++){
673		var thisClientMacAddr = (typeof originData.wlList_2g[i][0] == "undefined") ? false : originData.wlList_2g[i][0].toUpperCase();
674
675		if(!thisClientMacAddr || typeof clientList[thisClientMacAddr] == "undefined"){
676			continue;
677		}
678
679		if(originData.wlList_2g[i][1] == "Yes") {
680			clientList[thisClientMacAddr].rssi = originData.wlList_2g[i][3];
681			clientList[thisClientMacAddr].isWL = 1;
682
683			totalClientNum.wireless += clientList[thisClientMacAddr].macRepeat;
684			totalClientNum.wireless_ifnames[clientList[thisClientMacAddr].isWL-1] += clientList[thisClientMacAddr].macRepeat;
685			wirelessListArray[thisClientMacAddr] = originData.wlList_2g[i][1];
686		}
687		else {
688			clientList[thisClientMacAddr].isWL = 1;
689			wirelessListArray[thisClientMacAddr] = originData.wlList_2g[i][1];
690		}
691	}
692
693	for(var i=0; i<originData.wlList_5g.length; i++){
694		var thisClientMacAddr = (typeof originData.wlList_5g[i][0] == "undefined") ? false : originData.wlList_5g[i][0].toUpperCase();
695
696		if(!thisClientMacAddr || typeof clientList[thisClientMacAddr] == "undefined"){
697			continue;
698		}
699
700		if(originData.wlList_5g[i][1] == "Yes") {
701			clientList[thisClientMacAddr].rssi = originData.wlList_5g[i][3];
702			clientList[thisClientMacAddr].isWL = 2;
703
704			totalClientNum.wireless += clientList[thisClientMacAddr].macRepeat;
705			totalClientNum.wireless_ifnames[clientList[thisClientMacAddr].isWL-1] += clientList[thisClientMacAddr].macRepeat;
706			wirelessListArray[thisClientMacAddr] = originData.wlList_5g[i][1];
707		}
708		else {
709			if(clientList[thisClientMacAddr].isWL == 0) {
710				clientList[thisClientMacAddr].isWL = 2;
711				wirelessListArray[thisClientMacAddr] = originData.wlList_5g[i][1];
712			}
713		}
714	}
715
716	for(var i=0; i<originData.wlList_5g_2.length; i++){
717		var thisClientMacAddr = (typeof originData.wlList_5g_2[i][0] == "undefined") ? false : originData.wlList_5g_2[i][0].toUpperCase();
718
719		if(!thisClientMacAddr || typeof clientList[thisClientMacAddr] == "undefined"){
720			continue;
721		}
722
723		if(originData.wlList_5g_2[i][1] == "Yes") {
724			clientList[thisClientMacAddr].rssi = originData.wlList_5g_2[i][3];
725			clientList[thisClientMacAddr].isWL = 3;
726
727			totalClientNum.wireless += clientList[thisClientMacAddr].macRepeat;
728			totalClientNum.wireless_ifnames[clientList[thisClientMacAddr].isWL-1] += clientList[thisClientMacAddr].macRepeat;
729			wirelessListArray[thisClientMacAddr] = originData.wlList_5g_2[i][1];
730		}
731		else {
732			if(clientList[thisClientMacAddr].isWL == 0) {
733				clientList[thisClientMacAddr].isWL = 3;
734				wirelessListArray[thisClientMacAddr] = originData.wlList_5g_2[i][1];
735			}
736		}
737	}
738
739	if(typeof login_mac_str == "function"){
740		var thisClientMacAddr = (typeof login_mac_str == "undefined") ? false : login_mac_str().toUpperCase();
741
742		if(typeof clientList[thisClientMacAddr] != "undefined"){
743			clientList[thisClientMacAddr].isLogin = true;
744		}
745	}
746
747	for(var i=0; i<originData.qosRuleList.length; i++){
748		var thisClient = originData.qosRuleList[i].split(">");
749		var thisClientMacAddr = (typeof thisClient[1] == "undefined") ? false : thisClient[1].toUpperCase();
750
751		if(!thisClientMacAddr || typeof clientList[thisClientMacAddr] == "undefined"){
752			continue;
753		}
754
755		if(typeof clientList[thisClientMacAddr] != "undefined"){
756			clientList[thisClientMacAddr].qosLevel = thisClient[5];
757		}
758	}
759
760	for(var i = 0; i < leaseArray.mac.length; i += 1) {
761		if(typeof clientList[leaseArray.mac[i]] != "undefined"){
762			clientList[leaseArray.mac[i]].ipMethod = "DHCP";
763		}
764	}
765
766	for(var i=0; i<originData.staticList.length; i++){
767		if('<% nvram_get("dhcp_static_x"); %>' == "0") break;
768
769		var thisClient = originData.staticList[i].split(">");
770		var thisClientMacAddr = (typeof thisClient[0] == "undefined") ? false : thisClient[0].toUpperCase();
771
772		if(!thisClientMacAddr || typeof clientList[thisClientMacAddr] == "undefined"){
773			continue;
774		}
775
776		if(typeof clientList[thisClientMacAddr] != "undefined"){
777			if(clientList[thisClientMacAddr].ipMethod == "DHCP") {
778				if(clientList[thisClientMacAddr].ip == thisClient[1] || clientList[thisClientMacAddr].ip == "offline")
779					clientList[thisClientMacAddr].ipMethod = "Manual";
780			}
781		}
782	}
783
784	for(var i = 0; i < originData.wtf_rulelist.length; i += 1) {
785		var thisClient = originData.wtf_rulelist[i].split(">");
786		var thisClientMacAddr = (typeof thisClient[1] == "undefined") ? false : thisClient[1].toUpperCase();
787
788		if(!thisClientMacAddr || typeof clientList[thisClientMacAddr] == "undefined") {
789			continue;
790		}
791
792		if(typeof clientList[thisClientMacAddr] != "undefined") {
793			clientList[thisClientMacAddr].wtfast = parseInt(thisClient[0]);
794		}
795	}
796
797	wirelessList = "";
798	Object.keys(wirelessListArray).forEach(function(key) {
799		if(key != "") {
800			var clientMac = key
801			var clientMacState = wirelessListArray[key];
802			wirelessList +=  "<" + clientMac + ">" + clientMacState;
803			if(typeof clientList[clientMac] != "undefined") {
804				var wirelessOnline = (clientMacState.split(">")[0] == "Yes") ? true : false;
805				//If wireless device in sleep mode, but still connect to router. The wireless log still be connected in but in fromNetworkmapd not assigned to IP
806				if(clientList[clientMac].ip == "offline" && wirelessOnline) {
807					clientList[clientMac].isOnline = false;
808					totalClientNum.wireless--;
809					totalClientNum.wireless_ifnames[clientList[clientMac].isWL-1]--;
810				}
811				else { //If wireless device offline, but the device value not delete in fromNetworkmapd in real time, so need update the totalClientNum
812					if(clientList[clientMac].isOnline && !wirelessOnline) {
813						totalClientNum.online--;
814					}
815					clientList[clientMac].isOnline = wirelessOnline;
816				}
817			}
818		}
819	});
820
821	for(var i = 0; i < originData.nmpClient.length; i += 1) {
822
823		var thisClient = originData.nmpClient[i].split(">");
824		var thisClientMacAddr = ((typeof thisClient[0] == "undefined") || thisClient[0] == "" || thisClient[0].length != 12) ? false : thisClient[0].toUpperCase().substring(0, 2) + ":" +
825		thisClient[0].toUpperCase().substring(2, 4) + ":" + thisClient[0].toUpperCase().substring(4, 6) + ":" + thisClient[0].toUpperCase().substring(6, 8) + ":" +
826		thisClient[0].toUpperCase().substring(8, 10) + ":" + thisClient[0].toUpperCase().substring(10, 12);
827
828		if(!thisClientMacAddr) {
829			continue;
830		}
831
832		if(typeof clientList[thisClientMacAddr] == "undefined") {
833			var thisClientType = (typeof thisClient[4] == "undefined") ? "0" : thisClient[4];
834			var thisClientName = (typeof thisClient[2] == "undefined") ? thisClientMacAddr : (thisClient[2].trim() == "") ? thisClientMacAddr : thisClient[2].trim();
835
836			clientList.push(thisClientMacAddr);
837			clientList[thisClientMacAddr] = new setClientAttr();
838			clientList[thisClientMacAddr].from = "nmpClient";
839
840			if(!downsize_4m_support) {
841				clientList[thisClientMacAddr].type = thisClientType;
842				clientList[thisClientMacAddr].defaultType = thisClientType;
843			}
844			clientList[thisClientMacAddr].mac = thisClientMacAddr;
845
846			clientList[thisClientMacAddr].name = replaceClientName(thisClientName, thisClientMacAddr);
847
848			if(thisClientName != thisClientMacAddr && clientList[thisClientMacAddr].type == "0" && !downsize_4m_support) {
849				clientList[thisClientMacAddr].type = convType(thisClientName);
850				clientList[thisClientMacAddr].defaultType = clientList[thisClientMacAddr].type;
851			}
852
853			if(clientList[thisClientMacAddr].vendor == "") {
854				var ouiVenderName = "";
855				var manufacturer_id = transformManufacturerName(thisClientMacAddr.replace(/\:/g,"").substring(0, 6));
856				if(ouiClientListArray[manufacturer_id] != undefined) {
857					ouiVenderName = transformManufacturerName(ouiClientListArray[manufacturer_id]);
858					ouiVenderName = ouiVenderName.toLowerCase();
859					ouiVenderName = ouiVenderName.toUpperCase().charAt(0) + ouiVenderName.substring(1);
860				}
861				clientList[thisClientMacAddr].vendor = ouiVenderName;
862			}
863		}
864		else if(!clientList[thisClientMacAddr].isOnline) {
865			//Avoid <% get_client detail info(); %> not updated but the client actually offline
866			clientList[thisClientMacAddr].from = "nmpClient";
867		}
868	}
869
870	cookie.set("wireless_list_" + local_mac, wirelessList, 1/24/60*3);//3 minutes
871
872	if(stainfo_support) {
873		var updateStaInfo = function(wlLog, wlMode) {
874			for(var i = 0; i < wlLog.length; i += 1) {
875				var thisClientMacAddr = (typeof wlLog[i][0] == "undefined") ? false : wlLog[i][0].toUpperCase();
876
877				if(!thisClientMacAddr || typeof clientList[thisClientMacAddr] == "undefined"){
878					continue;
879				}
880
881				if(clientList[thisClientMacAddr].isOnline && (clientList[thisClientMacAddr].isWL == wlMode)) {
882					clientList[thisClientMacAddr].curTx = (wlLog[i][1].trim() == "") ? "": wlLog[i][1].trim() + " Mbps";
883					clientList[thisClientMacAddr].curRx = (wlLog[i][2].trim() == "") ? "": wlLog[i][2].trim() + " Mbps";
884					clientList[thisClientMacAddr].wlConnectTime = wlLog[i][3];
885				}
886			}
887		};
888		updateStaInfo(originData.wlListInfo_2g, 1);
889		updateStaInfo(originData.wlListInfo_5g, 2);
890		updateStaInfo(originData.wlListInfo_5g_2, 3);
891	}
892
893	totalClientNum.wired = parseInt(totalClientNum.online - totalClientNum.wireless);
894}
895
896//Initialize client list obj immediately
897genClientList();
898
899function getUploadIcon(clientMac) {
900	var result = "NoIcon";
901	$.ajax({
902		url: '/ajax_uploadicon.asp?clientmac=' + clientMac,
903		async: false,
904		dataType: 'script',
905		error: function(xhr){
906			setTimeout("getUploadIcon('" + clientMac + "');", 1000);
907		},
908		success: function(response){
909			result = upload_icon;
910		}
911	});
912	return result
913}
914
915function getUploadIconCount() {
916	var count = 0;
917	$.ajax({
918		url: '/ajax_uploadicon.asp',
919		async: false,
920		dataType: 'script',
921		error: function(xhr){
922			setTimeout("getUploadIconCount();", 1000);
923		},
924		success: function(response){
925			count = upload_icon_count;
926		}
927	});
928	return count
929}
930
931function getUploadIconList() {
932	var list = "";
933	$.ajax({
934		url: '/ajax_uploadicon.asp',
935		async: false,
936		dataType: 'script',
937		error: function(xhr){
938			setTimeout("getUploadIconList();", 1000);
939		},
940		success: function(response){
941			list = upload_icon_list;
942		}
943	});
944	return list
945}
946
947function getVenderIconClassName(venderName) {
948	var vender_class_name = "";
949	if(Boolean(venderName.match(venderArrayRE))) {
950		vender_class_name = venderName;
951		if(venderName == "hon hai") {
952			vender_class_name = "honhai";
953		}
954	}
955	else {
956		vender_class_name = "";
957	}
958	return vender_class_name;
959}
960
961function removeElement(element) {
962    element && element.parentNode && element.parentNode.removeChild(element);
963}
964var temp_clickedObj = null;
965var client_hide_flag = false;
966function hide_edit_client_block() {
967	if(client_hide_flag) {
968		fadeOut(document.getElementById("edit_client_block"), 10, 0);
969		if(temp_clickedObj.className.search("clientIcon") != -1) {
970			temp_clickedObj.className = temp_clickedObj.className.replace("clientIcon_clicked","clientIcon");
971			temp_clickedObj.className = temp_clickedObj.className.replace(" card_clicked", "");
972		}
973		else if(temp_clickedObj.className.search("venderIcon") != -1) {
974			temp_clickedObj.className = temp_clickedObj.className.replace("venderIcon_clicked","venderIcon");
975			temp_clickedObj.className = temp_clickedObj.className.replace(" card_clicked", "");
976		}
977		document.body.onclick = null;
978		temp_clickedObj = null;
979	}
980	client_hide_flag = true;
981}
982function show_edit_client_block() {
983	client_hide_flag = false;
984}
985
986function clientInternetState(mac) {
987	var internetState = false;
988	var currentTimeStr = originData.current_time;
989	var weekArray = ["", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
990	var week = parseInt(weekArray.indexOf(currentTimeStr.substring(0,3)));
991	var hour = parseInt(currentTimeStr.substring(17,19));
992
993	var timeSchedulingArray = time_scheduling_array[mac][1].split("<");
994	for(var i = 0; i < timeSchedulingArray.length; i += 1) {
995		if(!isNaN(parseInt(timeSchedulingArray[i]))) {
996			var week_start = parseInt(timeSchedulingArray[i].substring(0,1));
997			var week_end = parseInt(timeSchedulingArray[i].substring(1,2));
998			var hour_start = parseInt(timeSchedulingArray[i].substring(2,4));
999			var hour_end = parseInt(timeSchedulingArray[i].substring(4,6));
1000			if(week_start == 0 && week_end == 0 && hour_start == 0 && hour_end == 0 || week_start > week_end)
1001				week_end = 7;
1002
1003			if(week_start == 0 && week_end == 7 && hour_start == 0 && hour_end == 0) { //all time setting
1004				internetState = true;
1005				break;
1006			}
1007			else if(week_start == week && week_end == week) {
1008				if(hour_start <= hour && hour_end > hour) {
1009					internetState = true;
1010					break;
1011				}
1012			}
1013			else if(week_start == week && week_end > week) {
1014				if(hour_start <= hour) {
1015					internetState = true;
1016					break;
1017				}
1018			}
1019			else if(week_start < week && week_end > week) {
1020				internetState = true;
1021				break;
1022			}
1023			else if(week_start < week && week_end >= week) {
1024				if(hour_end > hour) {
1025					internetState = true;
1026					break;
1027				}
1028			}
1029		}
1030	}
1031	return internetState;
1032}
1033function card_closeClientListView() {
1034	hide_edit_client_block();
1035}
1036
1037var card_firstTimeOpenBlock = false;
1038var card_custom_usericon_del = "";
1039var userIconBase64 = "NoIcon";
1040function popClientListEditTable(mac, obj, name, ip, callBack) {
1041	card_firstTimeOpenBlock = false;
1042	var clientInfo = clientList[mac];
1043	if(clientInfo == undefined) {
1044		clientInfo = new setClientAttr();
1045		clientInfo.type = "0";
1046		clientInfo.name = "New device";
1047		clientInfo.mac = mac;
1048		clientInfo.defaultType = "0";
1049	}
1050	if(name != "" && name != undefined) {
1051		clientInfo.nickName = name;
1052	}
1053	if(ip != "" && ip != undefined)
1054		clientInfo.ip = ip;
1055
1056	if(obj.className.search("card_clicked") != -1) {
1057		return true;
1058	}
1059
1060	client_hide_flag = false;
1061
1062	var client_manual_dhcp_list_array = new Array();
1063	var client_manual_dhcp_list = decodeURIComponent('<% nvram_char_to_ascii("", "dhcp_staticlist"); %>').replace(/&#62/g, ">").replace(/&#60/g, "<");
1064	var client_manual_dhcp_list_row = client_manual_dhcp_list.split("<");
1065	for(var dhcpIndex = 0; dhcpIndex < client_manual_dhcp_list_row.length; dhcpIndex += 1) {
1066		if(client_manual_dhcp_list_row[dhcpIndex] != "") {
1067			var client_manual_dhcp_list_col = client_manual_dhcp_list_row[dhcpIndex].split(">");
1068			client_manual_dhcp_list_array[client_manual_dhcp_list_col[0]] = client_manual_dhcp_list_col[1];
1069		}
1070	}
1071
1072	if(document.getElementById("edit_client_block") != null) {
1073		removeElement(document.getElementById("edit_client_block"));
1074	}
1075
1076	var divObj = document.createElement("div");
1077	divObj.setAttribute("id","edit_client_block");
1078	divObj.className = "clientlist_content";
1079
1080	var code = "";
1081	code += '<table class="card_table" align="center" cellpadding="5" cellspacing="0" title="">';
1082	code += '<tbody>';
1083
1084	//device title info. start
1085	code += '<tr><td colspan="3" style="background-color:#2B373B;">';
1086	code += '<table style="width:100%" cellpadding="0" cellspacing="0">';
1087	code += '<tr>';
1088	code += '<td>';
1089	code += '<div id="card_client_state_div" class="clientState">';
1090	code += '<span id="card_client_ipMethod" class="ipMethodTag" style="color:#FFFFFF;margin-right:5px;"></span>';
1091	code += '<span id="card_client_login" class="ipMethodTag" style="color:#FFFFFF;margin-right:5px;"></span>';
1092	code += '<span id="card_client_printer" class="ipMethodTag" style="color:#FFFFFF;margin-right:5px;"></span>';
1093	code += '<span id="card_client_iTunes" class="ipMethodTag" style="color:#FFFFFF;margin-right:5px;"></span>';
1094	code += '<span id="card_client_opMode" class="ipMethodTag" style="color:#FFFFFF;margin-right:5px;"></span>';
1095	code += '</div>';
1096	code += '<div id="card_client_interface" style="height:28px;width:28px;float:right;"></div>';
1097	code += '</td>';
1098	code += '</tr>';
1099	code += '</table>';
1100	code += '</td></tr>';
1101	//device title info. end
1102
1103	code += '<tr><td colspan="3"><div class="clientList_line"></div></td></tr>';
1104
1105	//device icon and device info. start
1106	code += '<tr>';
1107	code += '<td style="text-align:center;vertical-align:top;width:85px;">';
1108	if(!downsize_4m_support)
1109		code += '<div id="card_client_preview_icon" class="client_preview_icon" title="Change client icon" onclick="card_show_custom_image();">';
1110	else
1111		code += '<div id="card_client_preview_icon" class="client_preview_icon" title="Change client icon">';
1112	code += '<div id="card_client_image" style="width:85px;height:85px;margin:0 auto;cursor:pointer;"></div>';
1113	code += '<canvas id="card_canvas_user_icon" class="client_canvasUserIcon" width="85px" height="85px"></canvas>';
1114	code += '</div>';
1115	if(!downsize_4m_support) {
1116		code += '<div class="changeClientIcon">';
1117		code += '<span title="Change to default client icon" onclick="card_setDefaultIcon();">Default</span>';//untranslated
1118		code += '<span id="card_changeIconTitle" title="Change client icon" style="margin-left:10px;" onclick="card_show_custom_image();">Change</span>';//untranslated
1119		code += '</div>';
1120	}
1121	code += '</td>';
1122
1123	code += '<td style="vertical-align:top;text-align:center;">';
1124	code += '<div class="clientTitle">';
1125	code += 'Name';
1126	code += '</div>';
1127	code += '<div  class="clientTitle" style="margin-top:10px;">';
1128	code += 'IP';
1129	code += '</div>';
1130	code += '<div  class="clientTitle" style="margin-top:10px;">';
1131	code += 'MAC';
1132	code += '</div>';
1133	code += '<div  class="clientTitle" style="margin-top:10px;">';
1134	code += 'Device';
1135	code += '</div>';
1136	code += '</td>';
1137
1138	code += '<td style="vertical-align:top;width:280px;">';
1139
1140	code += '<div>';
1141	code += '<input id="card_client_name" name="card_client_name" type="text" value="" class="input_32_table" maxlength="32" style="width:275px;">';
1142	code += '</div>';
1143	code += '<div style="margin-top:10px;">';
1144	code += '<input id="client_ipaddr_field" type="text" value="" class="input_32_table client_input_text_disabled" disabled>';
1145	code += '</div>';
1146	code += '<div style="margin-top:10px;">';
1147	code += '<input id="client_macaddr_field" type="text" value="" class="input_32_table client_input_text_disabled" disabled>';
1148	code += '</div>';
1149	code += '<div style="margin-top:10px;">';
1150	code += '<input id="client_manufacturer_field" type="text" value="Loading manufacturer.." class="input_32_table client_input_text_disabled" disabled>';
1151	code += '</div>';
1152	code += '</td>';
1153	code += '</tr>';
1154	//device icon and device info. end
1155
1156	//device icon list start
1157	code += '<tr>';
1158	code += '<td colspan="3">';
1159	code += '<div id="card_custom_image" class="client_icon_list" style="display:none;">';
1160	code += '<table width="99%;" id="tbCardClientListIcon" border="1" align="center" cellpadding="4" cellspacing="0">';
1161	code += '</table>';
1162	code += '</td>';
1163	code += '</tr>';
1164	//device icon list end
1165
1166	code += '<tr>';
1167	code += '<td colspan="3" style="text-align: center;">';
1168	code += '<input class="button_gen" type="button" onclick="card_closeClientListView();" value="<#CTL_Cancel#>">';
1169	code += '<input id="card_client_confirm" class="button_gen" type="button" onclick="card_confirm(\''+callBack+'\');" value="<#CTL_apply#>">';
1170	code += '<img id="card_client_loadingIcon" style="margin-left:5px;display:none;" src="/images/InternetScan.gif">';
1171	code += '</td>';
1172	code += '</tr>';
1173	code += '</tbody></table>';
1174
1175	divObj.innerHTML = code;
1176	obj.parentNode.appendChild(divObj);
1177	//Clear the last record clicked obj
1178	if(temp_clickedObj != null) {
1179		if(temp_clickedObj.className.search("clientIcon") != -1) {
1180			temp_clickedObj.className = temp_clickedObj.className.replace("clientIcon_clicked","clientIcon");
1181			temp_clickedObj.className = temp_clickedObj.className.replace(" card_clicked", "");
1182		}
1183		else if(temp_clickedObj.className.search("venderIcon") != -1) {
1184			temp_clickedObj.className = temp_clickedObj.className.replace("venderIcon_clicked","venderIcon");
1185			temp_clickedObj.className = temp_clickedObj.className.replace(" card_clicked", "");
1186		}
1187		temp_clickedObj = null;
1188	}
1189	temp_clickedObj = obj;
1190	if(obj.className.search("clientIcon") != -1) {
1191		obj.className = obj.className.replace("clientIcon","clientIcon_clicked");
1192		obj.className = obj.className  + " card_clicked";
1193	}
1194	else if(obj.className.search("venderIcon") != -1) {
1195		obj.className = obj.className.replace("venderIcon","venderIcon_clicked");
1196		obj.className = obj.className  + " card_clicked";
1197	}
1198
1199	fadeIn(document.getElementById("edit_client_block"));
1200	document.body.onclick = function() {hide_edit_client_block();}
1201	document.getElementById("edit_client_block").onclick = function() {show_edit_client_block();}
1202
1203	//build device icon list start
1204	var clientListIconArray = [["Windows device", "1"], ["Router", "2"], ["NAS/Server", "4"], ["IP Cam", "5"], ["Macbook", "6"], ["Game Console", "7"], ["Android Phone", "9"], ["iPhone", "10"],
1205	["Apple TV", "11"], ["Set-top Box", "12"], ["iMac", "14"], ["ROG", "15"], ["Printer", "18"], ["Windows Phone", "19"], ["Android Tablet", "20"], ["iPad", "21"], ["Linux Device", "22"],
1206	["Smart TV", "23"], ["Repeater", "24"], ["Kindle", "25"], ["Scanner", "26"], ["Chromecast", "27"], ["ASUS smartphone", "28"], ["ASUS Pad", "29"], ["Windows", "30"], ["Android", "31"], ["Mac OS", "32"]];
1207
1208	var eachColCount = 7;
1209	var colCount = parseInt(clientListIconArray.length / eachColCount) + 1;
1210	for(var rowIndex = 0; rowIndex < colCount; rowIndex += 1) {
1211		var row = document.getElementById("tbCardClientListIcon").insertRow(rowIndex);
1212		row.id = "trCardClientListIcon" + rowIndex;
1213		for(var colIndex = 0; colIndex < eachColCount; colIndex += 1) {
1214			var cell = row.insertCell(-1);
1215			cell.id = "tbCardClientListIcon" + (colIndex + (rowIndex * 7));
1216			var idx = (colIndex + (rowIndex * eachColCount));
1217			if(clientListIconArray[colIndex + (rowIndex * eachColCount)] != undefined) {
1218				cell.innerHTML = '<div class="type' + clientListIconArray[idx][1] + '" onclick="select_image(this.className,\''+clientInfo.vendor+'\');" title="' + clientListIconArray[idx][0] + '"></div>';
1219			}
1220			else {
1221				if(usericon_support) {
1222					if(document.getElementById("tdCardUserIcon") == null) {
1223						cell.id = "tdCardUserIcon";
1224						cell.className = "client_icon_list_td";
1225						cell.innerHTML = '<div id="divCardUserIcon" class="client_upload_div" style="display:none;">+' +
1226						'<input type="file" name="cardUploadIcon" id="cardUploadIcon" class="client_upload_file" onchange="previewCardUploadIcon(this);" title="Upload client icon" /></div>';/*untranslated*/
1227					}
1228				}
1229			}
1230		}
1231	}
1232	//build device icon list end
1233
1234	//settup value
1235	//initial state start
1236	document.getElementById("card_client_preview_icon").ondrop = null;
1237	//initial state end
1238
1239	//device title info. start
1240	document.getElementById("card_client_name").value = (clientInfo.nickName == "") ? clientInfo.name : clientInfo.nickName;
1241
1242	var convRSSI = function(val) {
1243		if(val == "") return "wired";
1244
1245		val = parseInt(val);
1246		if(val >= -50) return 4;
1247		else if(val >= -80)	return Math.ceil((24 + ((val + 80) * 26)/10)/25);
1248		else if(val >= -90)	return Math.ceil((((val + 90) * 26)/10)/25);
1249		else return 1;
1250	};
1251
1252	document.getElementById("card_client_ipMethod").style.display = "none";
1253	document.getElementById("card_client_login").style.display = "none";
1254	document.getElementById("card_client_printer").style.display = "none";
1255	document.getElementById("card_client_iTunes").style.display = "none";
1256	document.getElementById("card_client_opMode").style.display = "none";
1257	if(clientInfo.isOnline) {
1258		var rssi_t = 0;
1259		var connectModeTip = "";
1260		var clientIconHtml = "";
1261		rssi_t = convRSSI(clientInfo.rssi);
1262		if(isNaN(rssi_t)) {
1263			connectModeTip = "<#tm_wired#>";
1264		}
1265		else {
1266			switch(rssi_t) {
1267				case 1:
1268					connectModeTip = "<#Radio#>: <#PASS_score1#>\n";
1269					break;
1270				case 2:
1271					connectModeTip = "<#Radio#>: <#PASS_score2#>\n";
1272					break;
1273				case 3:
1274					connectModeTip = "<#Radio#>: <#PASS_score3#>\n";
1275					break;
1276				case 4:
1277					connectModeTip = "<#Radio#>: <#PASS_score4#>\n";
1278					break;
1279			}
1280			if(stainfo_support) {
1281				if(clientInfo.curTx != "")
1282					connectModeTip += "Tx Rate: " + clientInfo.curTx + "\n"; /*untranslated*/
1283				if(clientInfo.curRx != "")
1284					connectModeTip += "Rx Rate: " + clientInfo.curRx + "\n"; /*untranslated*/
1285				connectModeTip += "<#Access_Time#>: " + clientInfo.wlConnectTime + "";
1286			}
1287		}
1288
1289		if(sw_mode != 4){
1290			clientIconHtml += '<div class="radioIcon radio_' + rssi_t +'" title="' + connectModeTip + '"></div>';
1291			if(clientInfo.isWL != 0) {
1292				var bandClass = (navigator.userAgent.toUpperCase().match(/CHROME\/([\d.]+)/)) ? "band_txt_chrome" : "band_txt";
1293				clientIconHtml += '<div class="band_block"><span class="' + bandClass + '" style="color:#000000;">' + wl_nband_title[clientInfo.isWL-1].replace("Hz", "") + '</span></div>';
1294			}
1295			document.getElementById('card_client_interface').innerHTML = clientIconHtml;
1296			document.getElementById("card_client_interface").title = connectModeTip;
1297		}
1298	}
1299
1300	if(clientInfo.isOnline) {
1301		if(sw_mode == "1") {
1302			document.getElementById("card_client_ipMethod").style.display = "";
1303			document.getElementById("card_client_ipMethod").innerHTML = clientInfo.ipMethod;
1304			document.getElementById("card_client_ipMethod").onmouseover = function() {return overlib(ipState[clientInfo.ipMethod]);};
1305			document.getElementById("card_client_ipMethod").onmouseout = function() {nd();};
1306		}
1307	}
1308	else {
1309		document.getElementById("card_client_ipMethod").style.display = "";
1310		document.getElementById("card_client_ipMethod").innerHTML = "Off Line"; /*untranslated*/
1311		document.getElementById("card_client_ipMethod").onmouseover = function() {return overlib(ipState["OffLine"]);};
1312		document.getElementById("card_client_ipMethod").onmouseout = function() {nd();};
1313		document.getElementById("card_client_interface").style.display = "none";
1314	}
1315	if(clientInfo.isLogin) {
1316		document.getElementById("card_client_login").style.display = "";
1317		document.getElementById("card_client_login").innerHTML = "logged-in-user"; /*untranslated*/
1318	}
1319	if(clientInfo.isPrinter) {
1320		document.getElementById("card_client_printer").style.display = "";
1321		document.getElementById("card_client_printer").innerHTML = "Printer"; /*untranslated*/
1322	}
1323	if(clientInfo.isITunes) {
1324		document.getElementById("card_client_iTunes").style.display = "";
1325		document.getElementById("card_client_iTunes").innerHTML = "iTunes"; /*untranslated*/
1326	}
1327	if(clientInfo.opMode != 0) {
1328		var opModeDes = ["none", "<#wireless_router#>", "<#OP_RE_item#>", "<#OP_AP_item#>", "<#OP_MB_item#>"];
1329		document.getElementById("card_client_opMode").style.display = "";
1330		document.getElementById("card_client_opMode").innerHTML = opModeDes[clientInfo.opMode];
1331	}
1332	//device title info. end
1333
1334	//device icon and device info. start
1335	document.getElementById("client_ipaddr_field").value = clientInfo.ip;
1336	document.getElementById("client_macaddr_field").value = clientInfo.mac;
1337	select_image("type" + parseInt(clientInfo.type), clientInfo.vendor);
1338	if(client_manual_dhcp_list_array[clientInfo.mac] != undefined) { //check mac>ip is combination the the ipLockIcon is manual
1339		var client_manual_ip = client_manual_dhcp_list_array[clientInfo.mac];
1340		//handle device offine but dhcp had been setted.
1341		if(clientInfo.ip == "offline") {
1342			document.getElementById("client_ipaddr_field").value = client_manual_ip;
1343		}
1344	}
1345
1346	var deviceTitle = (clientInfo.dpiDevice == "") ? clientInfo.vendor : clientInfo.dpiDevice;
1347	if(deviceTitle == undefined || deviceTitle == "") {
1348		setTimeout(function(){
1349			if('<% nvram_get("x_Setting"); %>' == '1' && wanConnectStatus && clientInfo.internetState)
1350				oui_query_card(clientInfo.mac);
1351		}, 1000);
1352	}
1353	else {
1354		document.getElementById("client_manufacturer_field").value = deviceTitle;
1355		document.getElementById("client_manufacturer_field").title = "";
1356		if(deviceTitle.length > 38) {
1357			document.getElementById("client_manufacturer_field").value = deviceTitle.substring(0, 36) + "..";
1358			document.getElementById("client_manufacturer_field").title = deviceTitle;
1359		}
1360	}
1361	//device icon and device info. end
1362
1363	//setting user upload icon attribute start.
1364	//1.check rc_support
1365	if(usericon_support) {
1366		//2.check browswer support File Reader and Canvas or not.
1367		if(isSupportFileReader() && isSupportCanvas()) {
1368			document.getElementById("divCardUserIcon").style.display = "";
1369			//Setting drop event
1370			var holder = document.getElementById("card_client_preview_icon");
1371			holder.ondragover = function () { return false; };
1372			holder.ondragend = function () { return false; };
1373			holder.ondrop = function (e) {
1374				e.preventDefault();
1375				var userIconLimitFlag = userIconNumLimit(document.getElementById("client_macaddr_field").value);
1376				if(userIconLimitFlag) {	//not over 100
1377					var file = e.dataTransfer.files[0];
1378					//check image
1379					if(file.type.search("image") != -1) {
1380						var reader = new FileReader();
1381						reader.onload = function (event) {
1382							var img = document.createElement("img");
1383							img.src = event.target.result;
1384							var mimeType = img.src.split(",")[0].split(":")[1].split(";")[0];
1385							var canvas = document.getElementById("card_canvas_user_icon");
1386							var ctx = canvas.getContext("2d");
1387							ctx.clearRect(0,0,85,85);
1388							document.getElementById("card_client_image").style.display = "none";
1389							document.getElementById("card_canvas_user_icon").style.display = "";
1390							setTimeout(function() {
1391								ctx.drawImage(img, 0, 0, 85, 85);
1392								var dataURL = canvas.toDataURL(mimeType);
1393								userIconBase64 = dataURL;
1394							}, 100); //for firefox FPS(Frames per Second) issue need delay
1395						};
1396						reader.readAsDataURL(file);
1397						return false;
1398					}
1399					else {
1400						alert("<#Setting_upload_hint#>");
1401						return false;
1402					}
1403				}
1404				else {	//over 100 then let usee select delete icon or nothing
1405					showUploadIconList();
1406				}
1407			};
1408		}
1409	}
1410	//setting user upload icon attribute end.
1411
1412	//form
1413	if(document.getElementById("card_clientlist_form") != null) {
1414		removeElement(document.getElementById("card_clientlist_form"));
1415	}
1416	var formHTML = "";
1417	var formObj = document.createElement("form");
1418	document.body.appendChild(formObj);
1419	formObj.method = "POST";
1420	formObj.setAttribute("id","card_clientlist_form");
1421	formObj.setAttribute("name","card_clientlist_form");
1422	formObj.action = "/start_apply2.htm";
1423	formObj.target = "hidden_frame";
1424
1425	var currentURL = "";
1426	if(location.pathname == "/")
1427		currentURL = "index.asp";
1428	else
1429		currentURL = location.pathname.substring(location.pathname.lastIndexOf('/') + 1);
1430
1431	formHTML += '<input type="hidden" name="current_page" value=' + currentURL + '>';
1432	formHTML += '<input type="hidden" name="next_page" value=' + currentURL + '>';
1433	formHTML += '<input type="hidden" name="modified" value="0">';
1434	formHTML += '<input type="hidden" name="flag" value="background">';
1435	formHTML += '<input type="hidden" name="action_mode" value="apply">';
1436	formHTML += '<input type="hidden" name="action_script" value="saveNvram">';
1437	formHTML += '<input type="hidden" name="action_wait" value="1">';
1438	formHTML += '<input type="hidden" name="custom_clientlist" value="">';
1439	formHTML += '<input type="hidden" name="custom_usericon" value="">';
1440	formHTML += '<input type="hidden" name="custom_usericon_del" value="" disabled>';
1441	formObj.innerHTML = formHTML;
1442	card_firstTimeOpenBlock = true;
1443}
1444
1445function previewCardUploadIcon(imageObj) {
1446	var userIconLimitFlag = userIconNumLimit(document.getElementById("client_macaddr_field").value);
1447
1448	if(userIconLimitFlag) {	//not over 100
1449		var checkImageExtension = function (imageFileObject) {
1450		var  picExtension= /\.(jpg|jpeg|gif|png|bmp|ico)$/i;  //analy extension
1451			if (picExtension.test(imageFileObject))
1452				return true;
1453			else
1454				return false;
1455		};
1456
1457		//1.check image extension
1458		if (!checkImageExtension(imageObj.value)) {
1459			alert("<#Setting_upload_hint#>");
1460			imageObj.focus();
1461		}
1462		else {
1463			//2.Re-drow image
1464			var fileReader = new FileReader();
1465			fileReader.onload = function (fileReader) {
1466				var img = document.createElement("img");
1467				img.src = fileReader.target.result;
1468				var mimeType = img.src.split(",")[0].split(":")[1].split(";")[0];
1469				var canvas = document.getElementById("card_canvas_user_icon");
1470				var ctx = canvas.getContext("2d");
1471				ctx.clearRect(0,0,85,85);
1472				document.getElementById("card_client_image").style.display = "none";
1473				document.getElementById("card_canvas_user_icon").style.display = "";
1474				setTimeout(function() {
1475					ctx.drawImage(img, 0, 0, 85, 85);
1476					var dataURL = canvas.toDataURL(mimeType);
1477					userIconBase64 = dataURL;
1478				}, 100); //for firefox FPS(Frames per Second) issue need delay
1479			}
1480			fileReader.readAsDataURL(imageObj.files[0]);
1481			userIconHideFlag = true;
1482		}
1483	}
1484	else {	//over 100 then let usee select delete icon or nothing
1485		showUploadIconList();
1486	}
1487}
1488
1489function card_show_custom_image(flag) {
1490	if(!slideFlag) {
1491		var display_state = document.getElementById("card_custom_image").style.display;
1492		if(display_state == "none") {
1493			slideFlag = true;
1494			slideDown("card_custom_image", 500);
1495			document.getElementById("card_changeIconTitle").innerHTML = "<#CTL_close#>";
1496		}
1497		else {
1498			slideFlag = true;
1499			slideUp("card_custom_image", 500);
1500			document.getElementById("card_changeIconTitle").innerHTML = "Change";/*untranslated*/
1501		}
1502	}
1503}
1504function card_confirm(callBack) {
1505	var validClientListForm = function() {
1506		document.getElementById("card_client_name").value = document.getElementById("card_client_name").value.trim();
1507		if(document.getElementById("card_client_name").value.length == 0){
1508			alert("<#File_Pop_content_alert_desc1#>");
1509			document.getElementById("card_client_name").style.display = "";
1510			document.getElementById("card_client_name").focus();
1511			document.getElementById("card_client_name").select();
1512			return false;
1513		}
1514		else if(document.getElementById("card_client_name").value.indexOf(">") != -1 || document.getElementById("card_client_name").value.indexOf("<") != -1){
1515			alert("<#JS_validstr2#> '<', '>'");
1516			document.getElementById("card_client_name").focus();
1517			document.getElementById("card_client_name").select();
1518			document.getElementById("card_client_name").value = "";
1519			return false;
1520		}
1521		else if(!validator.haveFullWidthChar(document.getElementById("card_client_name"))) {
1522			return false;
1523		}
1524		return true;
1525	};
1526	var custom_name = originData.customList;
1527	if(validClientListForm()){
1528		document.card_clientlist_form.custom_clientlist.disabled = false;
1529		// customize device name
1530		var originalCustomListArray = new Array();
1531		var onEditClient = new Array();
1532		var clientTypeNum = "";
1533		if(document.getElementById('card_client_image').className.search("venderIcon") != -1) {
1534			clientTypeNum = "0";
1535		}
1536		else {
1537			clientTypeNum = document.getElementById("card_client_image").className.replace("clientIcon_no_hover type", "");
1538			if(clientTypeNum == "0_viewMode") {
1539				clientTypeNum = "0";
1540			}
1541		}
1542		originalCustomListArray = custom_name;
1543		onEditClient[0] = document.getElementById("card_client_name").value.trim();
1544		onEditClient[1] = document.getElementById("client_macaddr_field").value;
1545		onEditClient[2] = 0;
1546		onEditClient[3] = clientTypeNum;
1547		onEditClient[4] = "";
1548		onEditClient[5] = "";
1549
1550		for(var i=0; i<originalCustomListArray.length; i++){
1551			if(originalCustomListArray[i].split('>')[1] == onEditClient[1]){
1552				onEditClient[4] = originalCustomListArray[i].split('>')[4]; // set back callback for ROG device
1553				onEditClient[5] = originalCustomListArray[i].split('>')[5]; // set back keeparp for ROG device
1554				originalCustomListArray.splice(i, 1); // remove the selected client from original list
1555			}
1556		}
1557
1558		originalCustomListArray.push(onEditClient.join('>'));
1559		custom_name = originalCustomListArray.join('<');
1560		document.card_clientlist_form.custom_clientlist.value = custom_name;
1561
1562		// handle user image
1563		document.card_clientlist_form.custom_usericon.disabled = true;
1564		if(usericon_support) {
1565			document.card_clientlist_form.custom_usericon.disabled = false;
1566			var clientMac = document.getElementById("client_macaddr_field").value.replace(/\:/g, "");
1567			if(userIconBase64 != "NoIcon") {
1568				document.card_clientlist_form.custom_usericon.value = clientMac + ">" + userIconBase64;
1569			}
1570			else {
1571				document.card_clientlist_form.custom_usericon.value = clientMac + ">noupload";
1572			}
1573		}
1574
1575		// submit card_clientlist_form
1576		document.card_clientlist_form.submit();
1577
1578		// display waiting effect
1579		document.getElementById("card_client_loadingIcon").style.display = "";
1580
1581		setTimeout(function() {
1582			var updateClientListObj = function () {
1583				$.ajax({
1584					url: '/update_clients.asp',
1585					dataType: 'script',
1586					error: function(xhr) {
1587						setTimeout("updateClientListObj();", 1000);
1588					},
1589					success: function(response){
1590						genClientList();
1591						switch(callBack) {
1592							case "DHCP" :
1593								showDropdownClientList('setClientIP', 'mac>ip', 'all', 'ClientList_Block_PC', 'pull_arrow', 'all');
1594								showdhcp_staticlist();
1595								break;
1596							case "WOL" :
1597								showDropdownClientList('setClientIP', 'mac', 'all', 'ClientList_Block_PC', 'pull_arrow', 'all');
1598								showwollist();
1599								break;
1600							case "ACL" :
1601								showDropdownClientList('setClientmac', 'mac', 'wl', 'WL_MAC_List_Block', 'pull_arrow', 'all');
1602								show_wl_maclist_x();
1603								break;
1604							case "ParentalControl" :
1605								showDropdownClientList('setClientIP', 'mac', 'all', 'ClientList_Block_PC', 'pull_arrow', 'all');
1606								gen_mainTable();
1607								break;
1608							case "GuestNetwork" :
1609								showDropdownClientList('setClientmac', 'mac', 'wl', 'WL_MAC_List_Block', 'pull_arrow', 'all');
1610								show_wl_maclist_x();
1611								break;
1612							case "WebProtector" :
1613								showDropdownClientList('setClientIP', 'mac', 'all', 'ClientList_Block_PC', 'pull_arrow', 'all');
1614								genMain_table();
1615								break;
1616							case "WTFast" :
1617								showDropdownClientList('setClientmac', 'mac', 'all', 'ClientList_Block_PC', 'pull_arrow', 'all');
1618								show_rulelist();
1619								break;
1620							default :
1621								refreshpage();
1622						}
1623					}
1624				});
1625			};
1626			updateClientListObj();
1627		}, document.card_clientlist_form.action_wait.value * 1000);
1628	}
1629}
1630function card_setDefaultIcon() {
1631	var mac = document.getElementById("client_macaddr_field").value;
1632	var defaultType = "0";
1633	var defaultDpiVender = "";
1634	if(clientList[mac] != undefined) {
1635		defaultType = clientList[mac].defaultType;
1636		defaultDpiVender = clientList[mac].vendor;
1637	}
1638	select_image("type" + defaultType, defaultDpiVender);
1639}
1640
1641//check user icon num is over 100 or not.
1642function userIconNumLimit(mac) {
1643	var flag = true;
1644	var uploadIconMacList = getUploadIconList().replace(/\.log/g, "");
1645	var selectMac = mac.replace(/\:/g, "");
1646	var existFlag = (uploadIconMacList.search(selectMac) == -1) ? false : true;
1647	//check mac exist or not
1648	if(!existFlag) {
1649		var userIconCount = getUploadIconCount();
1650		if(userIconCount >= 100) {	//mac not exist, need check use icnon number whether over 100 or not.
1651			flag = false;
1652		}
1653	}
1654	return flag;
1655}
1656function showUploadIconList() {
1657	var confirmFlag = true;
1658	confirmFlag = confirm("The client icon over upload limting, please remove at least one client icon then try to upload again."); /*untranslated*/
1659	if(confirmFlag) {
1660
1661		hide_edit_client_block();
1662		if(document.getElementById("edit_client_block") != null) {
1663			document.getElementById("edit_client_block").remove();
1664		}
1665
1666		if(document.getElementById("edit_uploadicons_block") != null) {
1667			document.getElementById("edit_uploadicons_block").remove();
1668		}
1669
1670		var divObj = document.createElement("div");
1671		divObj.setAttribute("id","edit_uploadicons_block");
1672		divObj.className = "usericons_content";
1673
1674		var code = "";
1675		code += '<table width="95%" border="1" align="center" cellpadding="4" cellspacing="0" class="FormTable_table" style="margin-top:15px;">';
1676		code += '<thead><tr>';
1677		code += '<td colspan="4">Client upload icon&nbsp;(<#List_limit#>&nbsp;100)</td>'; /*untranslated*/
1678		code += '</tr></thead>';
1679		code += '<tr>';
1680		code += '<th width="45%"><#ParentalCtrl_username#></th>';
1681		code += '<th width="30%"><#ParentalCtrl_hwaddr#></th>';
1682		code += '<th width="15%">Upload icon</th>'; /*untranslated*/
1683		code += '<th width="10%"><#CTL_del#></th>';
1684		code += '</tr>';
1685		code += '</table>';
1686		code += '<div id="card_usericons_block"></div>';
1687		code += '<div style="margin-top:15px;padding-bottom:10px;width:100%;text-align:center;">';
1688		code += '<input class="button_gen" type="button" onclick="uploadIcon_cancel();" value="<#CTL_Cancel#>">';
1689		code += '<input class="button_gen" type="button" onclick="uploadIcon_confirm();" value="<#CTL_ok#>">';
1690		code += '<img id="card_upload_loadingIcon" style="margin-left:5px;display:none;" src="/images/InternetScan.gif">';
1691		code += '</div>	';
1692		divObj.innerHTML = code;
1693		document.body.appendChild(divObj);
1694
1695		document.getElementById("edit_uploadicons_block").style.display = "block";
1696
1697		showUploadIconsTable();
1698		return false;
1699	}
1700	else {
1701		document.getElementById("cardUploadIcon").value = "";
1702		return false;
1703	}
1704}
1705function showUploadIconsTable() {
1706	genClientList();
1707	var uploadIconMacList = getUploadIconList().replace(/\.log/g, "");
1708	var custom_usericon_row = uploadIconMacList.split('>');
1709	var code = "";
1710	var clientIcon = "";
1711	var custom_usericon_length = custom_usericon_row.length;
1712	code +='<table width="95%" cellspacing="0" cellpadding="4" align="center" class="list_table" id="cardUploadIcons_table">';
1713	if(custom_usericon_length == 1) {
1714		code +='<tr><td style="color:#FFCC00;" colspan="4"><#IPConnection_VSList_Norule#></td></tr>';
1715		document.getElementById('edit_uploadicons_block').style.height = "170px";
1716	}
1717	else {
1718		for(var i = 0; i < custom_usericon_length; i += 1) {
1719			if(custom_usericon_row[i] != "") {
1720				var formatMac = custom_usericon_row[i].slice(0,2) + ":" + custom_usericon_row[i].slice(2,4) + ":" + custom_usericon_row[i].slice(4,6) + ":" +
1721								custom_usericon_row[i].slice(6,8) + ":" + custom_usericon_row[i].slice(8,10)+ ":" + custom_usericon_row[i].slice(10,12);
1722				code +='<tr>';
1723				var clientObj = clientList[formatMac];
1724				var clientName = "";
1725				if(clientObj != undefined) {
1726					clientName = (clientObj.nickName.toString() == "") ? clientObj.name.toString() : clientObj.nickName.toString();
1727				}
1728				code +='<td width="45%">'+ clientName +'</td>';
1729				code +='<td width="30%">'+ formatMac +'</td>';
1730				clientIcon = getUploadIcon(custom_usericon_row[i]);
1731				code +='<td width="15%"><img id="imgUploadIcon_'+ i +'" class="card_imgUploadIcon" src="' + clientIcon + '"</td>';
1732				code +='<td width="10%"><input class="remove_btn" onclick="delUploadIcon(this);" value=""/></td></tr>';
1733			}
1734		}
1735		document.getElementById('edit_uploadicons_block').style.height = (61 * custom_usericon_length + 75) + "px";
1736	}
1737	code +='</table>';
1738	document.getElementById("card_usericons_block").innerHTML = code;
1739};
1740function delUploadIcon(rowdata) {
1741	var delIdx = rowdata.parentNode.parentNode.rowIndex;
1742	var delMac = rowdata.parentNode.parentNode.childNodes[1].innerHTML;
1743	document.getElementById("cardUploadIcons_table").deleteRow(delIdx);
1744	card_custom_usericon_del += delMac + ">";
1745	var trCount = document.getElementById("cardUploadIcons_table").rows.length;
1746	document.getElementById('edit_uploadicons_block').style.height = (61 * (trCount + 1) + 75) + "px";
1747	if(trCount == 0) {
1748		var code = "";
1749		code +='<table width="95%" cellspacing="0" cellpadding="4" align="center" class="list_table" id="cardUploadIcons_table">';
1750		code +='<tr><td style="color:#FFCC00;" colspan="4"><#IPConnection_VSList_Norule#></td></tr>';
1751		code +='</table>';
1752		document.getElementById('edit_uploadicons_block').style.height = "170px";
1753		document.getElementById("card_usericons_block").innerHTML = code;
1754	}
1755}
1756function uploadIcon_confirm() {
1757	document.card_clientlist_form.custom_clientlist.disabled = true;
1758	document.card_clientlist_form.custom_usericon.disabled = true;
1759	document.card_clientlist_form.custom_usericon_del.disabled = false;
1760	document.card_clientlist_form.custom_usericon_del.value = card_custom_usericon_del.replace(/\:/g, "");
1761
1762	// submit card_clientlist_form
1763	document.card_clientlist_form.submit();
1764	document.getElementById("card_upload_loadingIcon").style.display = "";
1765	setTimeout(function(){
1766		refreshpage();
1767		card_custom_usericon_del = "";
1768		document.card_clientlist_form.custom_usericon_del.disabled = true;
1769	}, document.card_clientlist_form.action_wait.value * 1000);
1770}
1771function uploadIcon_cancel() {
1772	card_custom_usericon_del = "";
1773	document.getElementById("edit_uploadicons_block").style.display = "none";
1774}
1775
1776function select_image(type,  vender) {
1777	var sequence = type.substring(4,type.length);
1778	document.getElementById("card_client_image").style.display = "none";
1779	document.getElementById("card_canvas_user_icon").style.display = "none";
1780	var icon_type = type;
1781	if(type == "type0") {
1782		icon_type = "type0_viewMode";
1783	}
1784	document.getElementById("card_client_image").style.backgroundSize = "";
1785	document.getElementById("card_client_image").className = "clientIcon_no_hover "+ icon_type;
1786	if(vender != "" && type == "type0" && !downsize_4m_support) {
1787		var venderIconClassName = getVenderIconClassName(vender.toLowerCase());
1788		if(venderIconClassName != "") {
1789			document.getElementById("card_client_image").className = "venderIcon_no_hover "+ venderIconClassName;
1790			document.getElementById("card_client_image").style.backgroundSize = "180%";
1791		}
1792	}
1793
1794	var userImageFlag = false;
1795	if(!card_firstTimeOpenBlock) {
1796		if(usericon_support) {
1797			var clientMac = document.getElementById('client_macaddr_field').value.replace(/\:/g, "");
1798			userIconBase64 = getUploadIcon(clientMac);
1799			if(userIconBase64 != "NoIcon") {
1800				var img = document.createElement("img");
1801				img.src = userIconBase64;
1802				var canvas = document.getElementById("card_canvas_user_icon");
1803				var ctx = canvas.getContext("2d");
1804				ctx.clearRect(0,0,85,85);
1805				document.getElementById("card_client_image").style.display = "none";
1806				document.getElementById("card_canvas_user_icon").style.display = "";
1807				ctx.drawImage(img, 0, 0, 85, 85);
1808				userImageFlag = true;
1809			}
1810		}
1811	}
1812
1813	if(!userImageFlag) {
1814		userIconBase64 = "NoIcon";
1815		document.getElementById("card_client_image").style.display = "";
1816	}
1817}
1818
1819function oui_query_card(mac) {
1820	var queryStr = mac.replace(/\:/g, "").splice(6,6,"");
1821	$.ajax({
1822	    url: 'https://services11.ieee.org/RST/standards-ra-web/rest/assignments/download/?registry=MA-L&format=html&text='+ queryStr,
1823		type: 'GET',
1824		success: function(response) {
1825			if(document.getElementById("edit_client_block") == null) return true;
1826			if(mac != document.getElementById("client_macaddr_field").value) {//avoid click two device quickly
1827				oui_query_card(document.getElementById("client_macaddr_field").value);
1828			}
1829			else {
1830				if(response.search("Sorry!") == -1) {
1831					if(response.search(queryStr) != -1) {
1832						var retData = response.split("pre")[1].split("(hex)")[1].split(queryStr)[0].split("<b>");
1833						document.getElementById("client_manufacturer_field").value = retData[0].trim();
1834						document.getElementById("client_manufacturer_field").title = "";
1835						if(retData[0].trim().length > 38) {
1836							document.getElementById("client_manufacturer_field").value = retData[0].trim().substring(0, 36) + "..";
1837							document.getElementById("client_manufacturer_field").title = retData[0].trim();
1838						}
1839					}
1840				}
1841			}
1842		}
1843	});
1844}
1845
1846/*
1847 * elem
1848 * speed, default is 20, optional
1849 * opacity, default is 100, range is 0~100, optional
1850 */
1851function fadeIn(elem, speed, opacity){
1852	if(elem != null) {
1853		var setOpacity = function(ev, v) {
1854			ev.filters ? ev.style.filter = 'alpha(opacity=' + v + ')' : ev.style.opacity = v / 100;
1855		};
1856		speed = speed || 20;
1857		opacity = opacity || 100;
1858
1859		//initial element display and set opacity is 0
1860		elem.style.display = "block";
1861		setOpacity(elem, 0);
1862
1863		var val = 0;
1864		//loop add 5 the opacity value
1865		(function(){
1866			setOpacity(elem, val);
1867			val += 5;
1868			if (val <= opacity) {
1869				setTimeout(arguments.callee, speed);
1870			}
1871		})();
1872	}
1873}
1874
1875/*
1876 * elem
1877 * speed, default is 20, optional
1878 * opacity, default is 0, range is 0~100, optional
1879 */
1880function fadeOut(elem, speed, opacity) {
1881	if(elem != null) {
1882		var setOpacity = function(ev, v) {
1883			ev.filters ? ev.style.filter = 'alpha(opacity=' + v + ')' : ev.style.opacity = v / 100;
1884		};
1885		speed = speed || 20;
1886		opacity = opacity || 0;
1887
1888		var val = 100;
1889
1890		(function(){
1891			setOpacity(elem, val);
1892			val -= 5;
1893			if (val >= opacity) {
1894				setTimeout(arguments.callee, speed);
1895			}
1896			else if (val < 0) {
1897				elem.style.display = "none";
1898			}
1899		})();
1900	}
1901}
1902
1903var slideFlag = false;
1904function slideDown(objnmae, speed) {
1905	var obj = document.getElementById(objnmae);
1906	var mySpeed = speed || 300;
1907	var intervals = mySpeed / 30; // we are using 30 ms intervals
1908	var holder = document.createElement('div');
1909	var parent = obj.parentNode;
1910	holder.setAttribute('style', 'height: 0px; overflow:hidden');
1911	parent.insertBefore(holder, obj);
1912	parent.removeChild(obj);
1913	holder.appendChild(obj);
1914	obj.style.display = obj.getAttribute("data-original-display") || "";
1915	var height = obj.offsetHeight;
1916	var sepHeight = height / intervals;
1917	var timer = setInterval(function() {
1918		var holderHeight = holder.offsetHeight;
1919		if (holderHeight + sepHeight < height) {
1920			holder.style.height = (holderHeight + sepHeight) + 'px';
1921		}
1922		else {
1923			// clean up
1924			holder.removeChild(obj);
1925			parent.insertBefore(obj, holder);
1926			parent.removeChild(holder);
1927			clearInterval(timer);
1928			slideFlag = false;
1929		}
1930	}, 30);
1931}
1932
1933function slideUp(objnmae, speed) {
1934	var obj = document.getElementById(objnmae);
1935	var mySpeed = speed || 300;
1936	var intervals = mySpeed / 30; // we are using 30 ms intervals
1937	var height = obj.offsetHeight;
1938	var holder = document.createElement('div');
1939	var parent = obj.parentNode;
1940	holder.setAttribute('style', 'height: ' + height + 'px; overflow:hidden');
1941	parent.insertBefore(holder, obj);
1942	parent.removeChild(obj);
1943	holder.appendChild(obj);
1944	var originalDisplay = (obj.style.display !== 'none') ? obj.style.display : '';
1945	obj.setAttribute("data-original-display", originalDisplay);
1946	var sepHeight = height / intervals;
1947	var timer = setInterval(function() {
1948		var holderHeight = holder.offsetHeight;
1949		if (holderHeight - sepHeight > 0) {
1950			holder.style.height = (holderHeight - sepHeight) + 'px';
1951		}
1952		else {
1953			// clean up
1954			obj.style.display = 'none';
1955			holder.removeChild(obj);
1956			parent.insertBefore(obj, holder);
1957			parent.removeChild(holder);
1958			clearInterval(timer);
1959			slideFlag = false;
1960		}
1961	}, 30);
1962}
1963
1964function registerIframeClick(iframeName, action) {
1965	var iframe = document.getElementById(iframeName);
1966	if(iframe != null) {
1967		var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
1968
1969		if (typeof iframeDoc.addEventListener != "undefined") {
1970			iframeDoc.addEventListener("click", action, false);
1971		}
1972		else if (typeof iframeDoc.attachEvent != "undefined") {
1973			iframeDoc.attachEvent ("onclick", action);
1974		}
1975	}
1976}
1977
1978function removeIframeClick(iframeName, action) {
1979	var iframe = document.getElementById(iframeName);
1980	if(iframe != null) {
1981		var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
1982
1983		if (typeof iframeDoc.removeEventListener != "undefined") {
1984			iframeDoc.removeEventListener("click", action, false);
1985		}
1986		else if (typeof iframeDoc.detachEvent != "undefined") {
1987			iframeDoc.detachEvent ("onclick", action);
1988		}
1989	}
1990}
1991
1992var all_list = new Array();//All
1993var wired_list = new Array();
1994var wl1_list = new Array();//2.4G
1995var wl2_list = new Array();//5G
1996var wl3_list = new Array();//5G-2
1997
1998var sorter = {
1999	"indexFlag" : 3 , // default sort is by IP
2000	"all_index" : 3,
2001	"all_display" : true,
2002	"wired_index" : 3,
2003	"wired_display" : true,
2004	"wl1_index" : 3,
2005	"wl1_display" : true,
2006	"wl2_index" : 3,
2007	"wl2_display" : true,
2008	"wl3_index" : 3,
2009	"wl3_display" : true,
2010	"sortingMethod" : "increase",
2011	"sortingMethod_wired" : "increase",
2012	"sortingMethod_wl1" : "increase",
2013	"sortingMethod_wl2" : "increase",
2014	"sortingMethod_wl3" : "increase",
2015
2016	"num_increase" : function(a, b) {
2017		if(sorter.indexFlag == 3) { //IP
2018			var a_num = 0, b_num = 0;
2019			a_num = inet_network(a[sorter.indexFlag]);
2020			b_num = inet_network(b[sorter.indexFlag]);
2021			return parseInt(a_num) - parseInt(b_num);
2022		}
2023		else if(sorter.indexFlag == 5 || sorter.indexFlag == 6 || sorter.indexFlag == 7) { //Interface, Tx, Rx
2024			var a_num = 0, b_num = 0;
2025			a_num = (a[sorter.indexFlag] == "") ? 0 : a[sorter.indexFlag];
2026			b_num = (b[sorter.indexFlag] == "") ? 0 : b[sorter.indexFlag];
2027			return parseInt(a_num) - parseInt(b_num);
2028		}
2029		else {
2030			return parseInt(a[sorter.indexFlag]) - parseInt(b[sorter.indexFlag]);
2031		}
2032	},
2033	"num_decrease" : function(a, b) {
2034		var a_num = 0, b_num = 0;
2035		if(sorter.indexFlag == 3) { //IP
2036			var a_num = 0, b_num = 0;
2037			a_num = inet_network(a[sorter.indexFlag]);
2038			b_num = inet_network(b[sorter.indexFlag]);
2039			return parseInt(b_num) - parseInt(a_num);
2040		}
2041		else if(sorter.indexFlag == 5 || sorter.indexFlag == 6 || sorter.indexFlag == 7) { //Interface, Tx, Rx
2042			var a_num = 0, b_num = 0;
2043			a_num = (a[sorter.indexFlag] == "") ? 0 : a[sorter.indexFlag];
2044			b_num = (b[sorter.indexFlag] == "") ? 0 : b[sorter.indexFlag];
2045			return parseInt(b_num) - parseInt(a_num);
2046		}
2047		else {
2048			return parseInt(b[sorter.indexFlag]) - parseInt(a[sorter.indexFlag]);
2049		}
2050	},
2051	"str_increase" : function(a, b) {
2052		if(a[sorter.indexFlag].toUpperCase() == b[sorter.indexFlag].toUpperCase()) return 0;
2053		else if(a[sorter.indexFlag].toUpperCase() > b[sorter.indexFlag].toUpperCase()) return 1;
2054		else return -1;
2055	},
2056	"str_decrease" : function(a, b) {
2057		if(a[sorter.indexFlag].toUpperCase() == b[sorter.indexFlag].toUpperCase()) return 0;
2058		else if(a[sorter.indexFlag].toUpperCase() > b[sorter.indexFlag].toUpperCase()) return -1;
2059		else return 1;
2060	},
2061	"addBorder" : function(obj) {
2062		var objIndex = obj;
2063		var clickItem = obj.parentNode.id.split("_")[1];
2064		var sorterLastIndex = 0;
2065		var sorterClickIndex = 0;
2066		while( (objIndex = objIndex.previousSibling) != null )
2067			sorterClickIndex++;
2068
2069		switch (clickItem) {
2070			case "all" :
2071				sorterLastIndex = sorter.all_index;
2072				sorter.all_index = sorterClickIndex;
2073				sorter.sortingMethod = (sorter.sortingMethod == "increase") ? "decrease" : "increase";
2074				break;
2075			case "wired" :
2076				sorterLastIndex = sorter.wired_index;
2077				sorter.wired_index = sorterClickIndex;
2078				sorter.sortingMethod_wired = (sorter.sortingMethod_wired == "increase") ? "decrease" : "increase";
2079				break;
2080			case "wl1" :
2081				sorterLastIndex = sorter.wl1_index;
2082				sorter.wl1_index = sorterClickIndex;
2083				sorter.sortingMethod_wl1 = (sorter.sortingMethod_wl1 == "increase") ? "decrease" : "increase";
2084				break;
2085			case "wl2" :
2086				sorterLastIndex = sorter.wl2_index;
2087				sorter.wl2_index = sorterClickIndex;
2088				sorter.sortingMethod_wl2 = (sorter.sortingMethod_wl2 == "increase") ? "decrease" : "increase";
2089				break;
2090			case "wl3" :
2091				sorterLastIndex = sorter.wl3_index;
2092				sorter.wl3_index = sorterClickIndex;
2093				sorter.sortingMethod_wl3 = (sorter.sortingMethod_wl3 == "increase") ? "decrease" : "increase";
2094				break;
2095		}
2096		obj.parentNode.childNodes[sorterLastIndex].style.borderTop = '1px solid #222';
2097		obj.parentNode.childNodes[sorterLastIndex].style.borderBottom = '1px solid #222';
2098	},
2099	"drawBorder" : function(_arrayName) {
2100		var clickItem = _arrayName.split("_")[0];
2101		var clickIndex = 2;
2102		var clickSortingMethod = "increase";
2103		switch (clickItem) {
2104			case "all" :
2105				clickIndex = sorter.all_index;
2106				clickSortingMethod = sorter.sortingMethod;
2107				break;
2108			case "wired" :
2109				clickIndex = sorter.wired_index;
2110				clickSortingMethod = sorter.sortingMethod_wired;
2111				break;
2112			case "wl1" :
2113				clickIndex = sorter.wl1_index;
2114				clickSortingMethod = sorter.sortingMethod_wl1;
2115				break;
2116			case "wl2" :
2117				clickIndex = sorter.wl2_index;
2118				clickSortingMethod = sorter.sortingMethod_wl2;
2119				break;
2120			case "wl3" :
2121				clickIndex = sorter.wl3_index;
2122				clickSortingMethod = sorter.sortingMethod_wl3;
2123				break;
2124		}
2125		var borderTopCss = "";
2126		var borderBottomCss = "";
2127		if(getBrowser_info().ie != undefined || getBrowser_info().ie != null) {
2128			borderTopCss = "3px solid #FC0";
2129			borderBottomCss = "1px solid #FC0";
2130		}
2131		else if(getBrowser_info().firefox != undefined || getBrowser_info().firefox != null) {
2132			borderTopCss = "2px solid #FC0";
2133			borderBottomCss = "1px solid #FC0";
2134		}
2135		else {
2136			borderTopCss = "2px solid #FC0";
2137			borderBottomCss = "2px solid #FC0";
2138		}
2139		if(clickSortingMethod == "increase") {
2140			document.getElementById("tr_"+clickItem+"_title").childNodes[clickIndex].style.borderTop = borderTopCss;
2141			document.getElementById("tr_"+clickItem+"_title").childNodes[clickIndex].style.borderBottom = '1px solid #222';
2142		}
2143		else {
2144			document.getElementById("tr_"+clickItem+"_title").childNodes[clickIndex].style.borderTop = '1px solid #222';
2145			document.getElementById("tr_"+clickItem+"_title").childNodes[clickIndex].style.borderBottom = borderBottomCss;
2146		}
2147	},
2148	"doSorter" : function(_flag, _Method, _arrayName) {
2149		// update variables
2150		sorter.indexFlag = _flag;
2151
2152		// doSorter
2153		if(clienlistViewMode == "All") {
2154			eval(""+_arrayName+".sort(sorter."+_Method+"_"+sorter.sortingMethod+");");
2155		}
2156		else if(clienlistViewMode == "ByInterface") {
2157			switch (_arrayName) {
2158				case "wired_list" :
2159					eval(""+_arrayName+".sort(sorter."+_Method+"_"+sorter.sortingMethod_wired+");");
2160					break;
2161				case "wl1_list" :
2162					eval(""+_arrayName+".sort(sorter."+_Method+"_"+sorter.sortingMethod_wl1+");");
2163					break;
2164				case "wl2_list" :
2165					eval(""+_arrayName+".sort(sorter."+_Method+"_"+sorter.sortingMethod_wl2+");");
2166					break;
2167				case "wl3_list" :
2168					eval(""+_arrayName+".sort(sorter."+_Method+"_"+sorter.sortingMethod_wl3+");");
2169					break;
2170			}
2171		}
2172		drawClientListBlock(_arrayName);
2173		sorter.drawBorder(_arrayName);
2174	}
2175}
2176
2177var edit_client_name_flag = false;
2178var clientlist_view_hide_flag = false;
2179function hide_clientlist_view_block() {
2180	if(clientlist_view_hide_flag) {
2181		fadeOut(document.getElementById("clientlist_viewlist_content"), 10, 0);
2182		document.body.onclick = null;
2183		document.body.onresize = null;
2184		clientListViewMacUploadIcon = [];
2185		removeIframeClick("statusframe", hide_clientlist_view_block);
2186	}
2187	clientlist_view_hide_flag = true;
2188}
2189function show_clientlist_view_block() {
2190	clientlist_view_hide_flag = false;
2191}
2192
2193function closeClientListView() {
2194	fadeOut(document.getElementById("clientlist_viewlist_content"), 10, 0);
2195}
2196
2197var clienlistViewMode = "All";
2198function changeClientListViewMode() {
2199	if(clienlistViewMode == "All")
2200		clienlistViewMode = "ByInterface";
2201	else
2202		clienlistViewMode = "All";
2203
2204	create_clientlist_listview();
2205	sorterClientList();
2206	sorter.all_display = true;
2207	sorter.wired_display = true;
2208	sorter.wl1_display = true;
2209	sorter.wl2_display = true;
2210	sorter.wl3_display = true;
2211}
2212
2213function pop_clientlist_listview() {
2214	if(document.getElementById("clientlist_viewlist_content") != null) {
2215		removeElement(document.getElementById("clientlist_viewlist_content"));
2216	}
2217
2218	var divObj = document.createElement("div");
2219	divObj.setAttribute("id","clientlist_viewlist_content");
2220	divObj.className = "clientlist_viewlist";
2221	divObj.setAttribute("onselectstart","return false");
2222	document.body.appendChild(divObj);
2223	fadeIn(document.getElementById("clientlist_viewlist_content"));
2224	cal_panel_block_clientList("clientlist_viewlist_content", 0.045);
2225
2226	if(document.getElementById("view_clientlist_form") != null) {
2227		removeElement(document.getElementById("view_clientlist_form"));
2228	}
2229	var formObj = document.createElement("form");
2230	formObj.setAttribute("id","view_clientlist_form");
2231	formObj.setAttribute("name","view_clientlist_form");
2232	formObj.action = "/start_apply2.htm";
2233	formObj.target = "hidden_frame";
2234	var formHtml = "";
2235	formHtml += "<input type='hidden' name='modified' value='0'>";
2236	formHtml += "<input type='hidden' name='flag' value='background'>";
2237	formHtml += "<input type='hidden' name='action_mode' value='apply'>";
2238	formHtml += "<input type='hidden' name='action_script' value='saveNvram'>";
2239	formHtml += "<input type='hidden' name='action_wait' value='1'>";
2240	formHtml += "<input type='hidden' name='custom_clientlist' value=''>";
2241	formObj.innerHTML = formHtml;
2242	document.body.appendChild(formObj);
2243
2244	clientlist_view_hide_flag = false;
2245
2246	create_clientlist_listview();
2247	updateClientListBackground();
2248	setTimeout("sorterClientList();updateClientListView();", 500);
2249
2250	registerIframeClick("statusframe", hide_clientlist_view_block);
2251
2252}
2253
2254function exportClientListLog() {
2255	var data = [["Internet access state", "Device Type", "Clients Name", "Clients IP Address", "IP Method", "Clients MAC Address", "Interface", "Tx Rate", "Rx Rate", "Access time"]];
2256	var tempArray = new Array();
2257	var ipStateExport = new Array();
2258	ipStateExport["Static"] =  "Static IP";
2259	ipStateExport["DHCP"] =  "Automatic IP";
2260	ipStateExport["Manual"] =  "MAC-IP Binding";
2261	var setArray = function(array) {
2262		for(var i = 0; i < array.length; i += 1) {
2263			tempArray = [];
2264			tempArray[0] = (array[i][0] == 1) ? "Allow Internet access" : "Block Internet access";
2265			tempArray[1] = array[i][1].replace(",", "");
2266			tempArray[2] = array[i][2];
2267			tempArray[3] = array[i][3];
2268			tempArray[4] = ipStateExport[clientList[array[i][4]].ipMethod];
2269			tempArray[5] = array[i][4];
2270			tempArray[6] = (array[i][9] == 0) ? "Wired" : wl_nband_title[array[i][9] - 1];
2271			tempArray[7] = (array[i][6] == "") ? "-" : array[i][6];
2272			tempArray[8] = (array[i][7] == "") ? "-" : array[i][7];
2273			tempArray[9] = (array[i][9] == 0) ? "-" : array[i][8];
2274			data.push(tempArray);
2275		}
2276	};
2277	switch (clienlistViewMode) {
2278		case "All" :
2279			setArray(all_list);
2280			break;
2281		case "ByInterface" :
2282			setArray(wired_list);
2283			setArray(wl1_list);
2284			setArray(wl2_list);
2285			setArray(wl3_list);
2286			break;
2287	}
2288	var csvContent = '';
2289	data.forEach(function (infoArray, index) {
2290		dataString = infoArray.join(',');
2291		csvContent += index < data.length ? dataString + '\n' : dataString;
2292	});
2293
2294	var download = function(content, fileName, mimeType) {
2295		var a = document.createElement('a');
2296		mimeType = mimeType || 'application/octet-stream';
2297
2298		if (navigator.msSaveBlob) { // IE10
2299			return navigator.msSaveBlob(new Blob([content], { type: mimeType }), fileName);
2300		}
2301		else if ('download' in a) { //html5 A[download]
2302			a.href = 'data:' + mimeType + ',' + encodeURIComponent(content);
2303			a.setAttribute('download', fileName);
2304			document.getElementById("clientlist_viewlist_content").appendChild(a);
2305			setTimeout(function() {
2306				a.click();
2307				document.getElementById("clientlist_viewlist_content").removeChild(a);
2308			}, 66);
2309			return true;
2310		}
2311		else { //do iframe dataURL download (old ch+FF):
2312			var f = document.createElement('iframe');
2313			document.getElementById("clientlist_viewlist_content").appendChild(f);
2314			f.src = 'data:' + mimeType + ',' + encodeURIComponent(content);
2315
2316			setTimeout(function() {
2317				document.getElementById("clientlist_viewlist_content").removeChild(f);
2318				}, 333);
2319			return true;
2320		}
2321	};
2322
2323	download(csvContent, 'ClientList.csv', 'data:text/csv;charset=utf-8');
2324}
2325
2326function sorterClientList() {
2327	//initial sort ip
2328	var indexMapType = ["", "", "str", "num", "str", "num", "num", "num", "str"];
2329	switch (clienlistViewMode) {
2330		case "All" :
2331			sorter.doSorter(sorter.all_index, indexMapType[sorter.all_index], 'all_list');
2332			break;
2333		case "ByInterface" :
2334			sorter.doSorter(sorter.wired_index, indexMapType[sorter.wired_index], 'wired_list');
2335			if(wl_info.band2g_support)
2336				sorter.doSorter(sorter.wl1_index, indexMapType[sorter.wl1_index], 'wl1_list');
2337			if(wl_info.band5g_support)
2338				sorter.doSorter(sorter.wl2_index, indexMapType[sorter.wl2_index], 'wl2_list');
2339			if(wl_info.band5g_2_support)
2340				sorter.doSorter(sorter.wl3_index, indexMapType[sorter.wl3_index], 'wl3_list');
2341			break;
2342	}
2343}
2344
2345function create_clientlist_listview() {
2346	all_list = [];
2347	wired_list = [];
2348	wl1_list = [];
2349	wl2_list = [];
2350	wl3_list = [];
2351
2352	if(document.getElementById("clientlist_viewlist_block") != null) {
2353		removeElement(document.getElementById("clientlist_viewlist_block"));
2354	}
2355
2356	var divObj = document.createElement("div");
2357	divObj.setAttribute("id","clientlist_viewlist_block");
2358
2359	var obj_width_map = [["15%", "20%", "25%", "20%", "20%"],["10%", "10%", "30%", "20%", "20%", "10%"],["6%", "6%", "27%", "20%", "15%", "6%", "6%", "6%", "8%"]];
2360	var obj_width = stainfo_support ? obj_width_map[2] : obj_width_map[1];
2361	var wl_colspan = stainfo_support ? 9 : 6;
2362
2363	var code = "";
2364
2365	var drawSwitchMode = function(mode) {
2366		var drawSwitchModeHtml = "";
2367		drawSwitchModeHtml += "<div style='margin-top:15px;margin-left:15px;'>";
2368		if(mode == "All") {
2369			drawSwitchModeHtml += "<div class='block_filter_pressed clientlist_All'>";
2370			drawSwitchModeHtml += "<div class='block_filter_name' style='color:#93A9B1;'><#All#></div>";
2371			drawSwitchModeHtml += "</div>";
2372			drawSwitchModeHtml += "<div class='block_filter clientlist_ByInterface' style='cursor:pointer'>";
2373			drawSwitchModeHtml += "<div class='block_filter_name' onclick='changeClientListViewMode();'>By interface</div>";/*untranslated*/
2374			drawSwitchModeHtml += "</div>";
2375		}
2376		else {
2377			drawSwitchModeHtml += "<div class='block_filter clientlist_All' style='cursor:pointer'>";
2378			drawSwitchModeHtml += "<div class='block_filter_name' onclick='changeClientListViewMode();'><#All#></div>";
2379			drawSwitchModeHtml += "</div>";
2380			drawSwitchModeHtml += "<div class='block_filter_pressed clientlist_ByInterface'>";
2381			drawSwitchModeHtml += "<div class='block_filter_name' style='color:#93A9B1;'>By interface</div>";/*untranslated*/
2382			drawSwitchModeHtml += "</div>";
2383		}
2384		drawSwitchModeHtml += "</div>";
2385		return drawSwitchModeHtml;
2386	};
2387
2388	code += drawSwitchMode(clienlistViewMode);
2389	code += "<div style='text-align:right;width:30px;position:relative;margin-top:-45px;margin-left:96%;'><img src='/images/button-close.gif' style='width:30px;cursor:pointer' onclick='closeClientListView();'></div>";
2390	code += "<table border='0' align='center' cellpadding='0' cellspacing='0' style='width:100%;padding:15px;'><tbody><tr><td>";
2391
2392	switch (clienlistViewMode) {
2393		case "All" :
2394			code += "<table width='100%' border='1' align='center' cellpadding='0' cellspacing='0' class='FormTable_table' style='margin-top:15px;'>";
2395			code += "<thead><tr height='28px'><td id='td_all_list_title' colspan='" + wl_colspan + "'>All list";/*untranslated*/
2396			code += "<a id='all_expander'class='clientlist_expander' onclick='showHideContent(\"clientlist_all_list_Block\", this);'>[ Hide ]</a>";/*untranslated*/
2397			code += "</td></tr></thead>";
2398			code += "<tr id='tr_all_title' height='40px'>";
2399			code += "<th width=" + obj_width[0] + "><#Internet#></th>";
2400			code += "<th width=" + obj_width[1] + ">Icon</th>";/*untranslated*/
2401			code += "<th width=" + obj_width[2] + " onclick='sorter.addBorder(this);sorter.doSorter(2, \"str\", \"all_list\");' style='cursor:pointer;'><#ParentalCtrl_username#></th>";
2402			code += "<th width=" + obj_width[3] + " onclick='sorter.addBorder(this);sorter.doSorter(3, \"num\", \"all_list\");' style='cursor:pointer;'>Clients IP Address</th>";/*untranslated*/
2403			code += "<th width=" + obj_width[4] + " onclick='sorter.addBorder(this);sorter.doSorter(4, \"str\", \"all_list\");' style='cursor:pointer;'><#ParentalCtrl_hwaddr#></th>";
2404			code += "<th width=" + obj_width[5] + " onclick='sorter.addBorder(this);sorter.doSorter(5, \"num\", \"all_list\");' style='cursor:pointer;'><#wan_interface#></th>";
2405			if(stainfo_support) {
2406				code += "<th width=" + obj_width[6] + " onclick='sorter.addBorder(this);sorter.doSorter(6, \"num\", \"all_list\");' style='cursor:pointer;' title='The transmission rates of your wireless device'>Tx Rate (Mbps)</th>";/*untranslated*/
2407				code += "<th width=" + obj_width[7] + " onclick='sorter.addBorder(this);sorter.doSorter(7, \"num\", \"all_list\");' style='cursor:pointer;' title='The receive rates of your wireless device'>Rx Rate (Mbps)</th>";/*untranslated*/
2408				code += "<th width=" + obj_width[8] + " onclick='sorter.addBorder(this);sorter.doSorter(8, \"str\", \"all_list\");' style='cursor:pointer;'><#Access_Time#></th>";
2409			}
2410			code += "</tr>";
2411			code += "</table>";
2412			code += "<div id='clientlist_all_list_Block'></div>";
2413			break;
2414		case "ByInterface" :
2415			code += "<table width='100%' border='1' align='center' cellpadding='0' cellspacing='0' class='FormTable_table' style='margin-top:15px;'>";
2416			code += "<thead><tr height='28px'><td colspan='" + wl_colspan + "'><#tm_wired#>";
2417			code += "<a id='wired_expander' class='clientlist_expander' onclick='showHideContent(\"clientlist_wired_list_Block\", this);'>[ Hide ]</a>";/*untranslated*/
2418			code += "</td></tr></thead>";
2419			code += "<tr id='tr_wired_title' height='40px'>";
2420			code += "<th width=" + obj_width[0] + "><#Internet#></th>";
2421			code += "<th width=" + obj_width[1] + ">Icon</th>";/*untranslated*/
2422			code += "<th width=" + obj_width[2] + " onclick='sorter.addBorder(this);sorter.doSorter(2, \"str\", \"wired_list\");' style='cursor:pointer;'><#ParentalCtrl_username#></th>";
2423			code += "<th width=" + obj_width[3] + " onclick='sorter.addBorder(this);sorter.doSorter(3, \"num\", \"wired_list\");' style='cursor:pointer;'>Clients IP Address</th>";/*untranslated*/
2424			code += "<th width=" + obj_width[4] + " onclick='sorter.addBorder(this);sorter.doSorter(4, \"str\", \"wired_list\");' style='cursor:pointer;'><#ParentalCtrl_hwaddr#></th>";
2425			code += "<th width=" + obj_width[5] + " ><#wan_interface#></th>";
2426			if(stainfo_support) {
2427				code += "<th width=" + obj_width[6] + " title='The transmission rates of your wireless device'>Tx Rate (Mbps)</th>";/*untranslated*/
2428				code += "<th width=" + obj_width[7] + " title='The receive rates of your wireless device'>Rx Rate (Mbps)</th>";/*untranslated*/
2429				code += "<th width=" + obj_width[8] + "><#Access_Time#></th>";
2430			}
2431			code += "</tr>";
2432			code += "</table>";
2433			code += "<div id='clientlist_wired_list_Block'></div>";
2434
2435			var wl_map = {"2.4 GHz": "1",  "5 GHz": "2", "5 GHz-1": "2", "5 GHz-2": "3"};
2436			obj_width = stainfo_support ? obj_width_map[2] : obj_width_map[1];
2437			for(var i = 0; i < wl_nband_title.length; i += 1) {
2438				code += "<table width='100%' border='1' align='center' cellpadding='0' cellspacing='0' class='FormTable_table' style='margin-top:15px;'>";
2439				code += "<thead><tr height='23px'><td colspan='" + wl_colspan + "'>" + wl_nband_title[i];
2440				code += "<a id='wl" + wl_map[wl_nband_title[i]] + "_expander' class='clientlist_expander' onclick='showHideContent(\"clientlist_wl" + wl_map[wl_nband_title[i]] + "_list_Block\", this);'>[ Hide ]</a>";/*untranslated*/
2441				code += "</td></tr></thead>";
2442				code += "<tr id='tr_wl" + wl_map[wl_nband_title[i]] + "_title' height='40px'>";
2443				code += "<th width=" + obj_width[0] + "><#Internet#></th>";
2444				code += "<th width=" + obj_width[1] + ">Icon</th>";/*untranslated*/
2445				code += "<th width=" + obj_width[2] + " onclick='sorter.addBorder(this);sorter.doSorter(2, \"str\", \"wl"+wl_map[wl_nband_title[i]]+"_list\");' style='cursor:pointer;'><#ParentalCtrl_username#></th>";
2446				code += "<th width=" + obj_width[3] + " onclick='sorter.addBorder(this);sorter.doSorter(3, \"num\", \"wl"+wl_map[wl_nband_title[i]]+"_list\");' style='cursor:pointer;'>Clients IP Address</th>";
2447				code += "<th width=" + obj_width[4] + " onclick='sorter.addBorder(this);sorter.doSorter(4, \"str\", \"wl"+wl_map[wl_nband_title[i]]+"_list\");' style='cursor:pointer;'><#ParentalCtrl_hwaddr#></th>";
2448				code += "<th width=" + obj_width[5] + " onclick='sorter.addBorder(this);sorter.doSorter(5, \"num\", \"wl"+wl_map[wl_nband_title[i]]+"_list\");' style='cursor:pointer;'><#wan_interface#></th>";
2449				if(stainfo_support) {
2450					code += "<th width=" + obj_width[6] + " onclick='sorter.addBorder(this);sorter.doSorter(6, \"num\", \"wl"+wl_map[wl_nband_title[i]]+"_list\");' style='cursor:pointer;' title='The transmission rates of your wireless device'>Tx Rate (Mbps)</th>";/*untranslated*/
2451					code += "<th width=" + obj_width[7] + " onclick='sorter.addBorder(this);sorter.doSorter(7, \"num\", \"wl"+wl_map[wl_nband_title[i]]+"_list\");' style='cursor:pointer;' title='The receive rates of your wireless device'>Rx Rate (Mbps)</th>";/*untranslated*/
2452					code += "<th width=" + obj_width[8] + " onclick='sorter.addBorder(this);sorter.doSorter(8, \"str\", \"wl"+wl_map[wl_nband_title[i]]+"_list\");' style='cursor:pointer;'><#Access_Time#></th>";
2453				}
2454				code += "</tr>";
2455				code += "</table>";
2456				code += "<div id='clientlist_wl" + wl_map[wl_nband_title[i]] + "_list_Block'></div>";
2457			}
2458			break;
2459	}
2460
2461	code += "<div style='text-align:center;margin-top:15px;'><input  type='button' class='button_gen' onclick='exportClientListLog();' value='<#btn_Export#>'></div>";
2462	code += "</td></tr></tbody>";
2463	code += "</table>";
2464
2465	divObj.innerHTML = code;
2466	document.getElementById("clientlist_viewlist_content").appendChild(divObj);
2467
2468	//register event to detect mouse click
2469	document.body.onclick = function() {hide_clientlist_view_block();}
2470	document.body.onresize = function() {
2471		if(document.getElementById("clientlist_viewlist_content") !== null) {
2472			if(document.getElementById("clientlist_viewlist_content").style.display == "block") {
2473				cal_panel_block_clientList("clientlist_viewlist_content", 0.045);
2474			}
2475		}
2476	}
2477
2478	document.getElementById("clientlist_viewlist_content").onclick = function() {show_clientlist_view_block();}
2479
2480	//copy clientList to each sort array
2481	genClientList();
2482	for(var i = 0; i < clientList.length; i += 1) {
2483		if(clientList[clientList[i]].isOnline) {
2484			var deviceTypeName = "Loading manufacturer..";
2485			var manufacturer_id = clientList[i].replace(/\:/g,"").substring(0, 6);
2486			if(ouiClientListArray[manufacturer_id] != undefined) {
2487				var tempDeviceName = transformManufacturerName(ouiClientListArray[manufacturer_id]);
2488				deviceTypeName = tempDeviceName.toUpperCase().charAt(0) + tempDeviceName.substring(1); //Oui Vender name
2489			}
2490			if((clientList[clientList[i]].dpiDevice != "" && clientList[clientList[i]].dpiDevice != undefined)) { //BWDPI device
2491				deviceTypeName = clientList[clientList[i]].dpiDevice;
2492			}
2493			var clientName = (clientList[clientList[i]].nickName == "") ? clientList[clientList[i]].name : clientList[clientList[i]].nickName;
2494			var tempArray = [clientList[clientList[i]].internetState, deviceTypeName, clientName, clientList[clientList[i]].ip,
2495							clientList[clientList[i]].mac, clientList[clientList[i]].rssi, clientList[clientList[i]].curTx, clientList[clientList[i]].curRx,
2496							clientList[clientList[i]].wlConnectTime, clientList[clientList[i]].isWL, clientList[clientList[i]].vendor, clientList[clientList[i]].type,
2497							clientList[clientList[i]].macRepeat];
2498			switch (clienlistViewMode) {
2499				case "All" :
2500					all_list.push(tempArray);
2501					break;
2502				case "ByInterface" :
2503					switch (clientList[clientList[i]].isWL) {
2504						case 0:
2505							wired_list.push(tempArray);
2506							break;
2507						case 1:
2508							wl1_list.push(tempArray);
2509							break;
2510						case 2:
2511							wl2_list.push(tempArray);
2512							break;
2513						case 3:
2514							wl3_list.push(tempArray);
2515							break;
2516					}
2517					break;
2518			}
2519		}
2520	}
2521
2522	if(clienlistViewMode == "All") {
2523		if(!sorter.all_display) {
2524			document.getElementById("clientlist_all_list_Block").style.display = "none";
2525			document.getElementById("all_expander").innerHTML = "[ Show ]";/*untranslated*/
2526		}
2527	}
2528	else {
2529		if(!sorter.wired_display) {
2530			document.getElementById("clientlist_wired_list_Block").style.display = "none";
2531			document.getElementById("wired_expander").innerHTML = "[ Show ]";/*untranslated*/
2532		}
2533		if(!sorter.wl1_display) {
2534			document.getElementById("clientlist_wl1_list_Block").style.display = "none";
2535			document.getElementById("wl1_expander").innerHTML = "[ Show ]";/*untranslated*/
2536		}
2537		if(!sorter.wl2_display) {
2538			document.getElementById("clientlist_wl2_list_Block").style.display = "none";
2539			document.getElementById("wl2_expander").innerHTML = "[ Show ]";/*untranslated*/
2540		}
2541		if(!sorter.wl3_display) {
2542			document.getElementById("clientlist_wl3_list_Block").style.display = "none";
2543			document.getElementById("wl3_expander").innerHTML = "[ Show ]";/*untranslated*/
2544		}
2545	}
2546}
2547
2548var clientListViewMacUploadIcon = new Array();
2549function drawClientListBlock(objID) {
2550	var sortArray = "";
2551	switch(objID) {
2552		case "all_list" :
2553			sortArray = all_list;
2554			break;
2555		case "wired_list" :
2556			sortArray = wired_list;
2557			break;
2558		case "wl1_list" :
2559			sortArray = wl1_list;
2560			break;
2561		case "wl2_list" :
2562			sortArray = wl2_list;
2563			break;
2564		case "wl3_list" :
2565			sortArray = wl3_list;
2566			break;
2567
2568	}
2569	var listViewProfile = function(_profile) {
2570		if(_profile == null)
2571			_profile = ["", "", "", "", "", "", "", "", "", "", "", "", ""];
2572
2573		this.internetState = _profile[0];
2574		this.deviceTypeName = _profile[1];
2575		this.name = _profile[2];
2576		this.ip = _profile[3];
2577		this.mac = _profile[4];
2578		this.rssi = _profile[5];
2579		this.curTx = _profile[6];
2580		this.curRx = _profile[7];
2581		this.wlConnectTime = _profile[8];
2582		this.isWL = _profile[9];
2583		this.vender = _profile[10];
2584		this.type = _profile[11];
2585		this.macRepeat = _profile[12];
2586	}
2587	var convRSSI = function(val) {
2588		if(val == "") return "wired";
2589
2590		val = parseInt(val);
2591		if(val >= -50) return 4;
2592		else if(val >= -80)	return Math.ceil((24 + ((val + 80) * 26)/10)/25);
2593		else if(val >= -90)	return Math.ceil((((val + 90) * 26)/10)/25);
2594		else return 1;
2595	};
2596
2597	if(document.getElementById("clientlist_" + objID + "_Block") != null) {
2598		if(document.getElementById("tb_" + objID) != null) {
2599			removeElement(document.getElementById("tb_" + objID));
2600		}
2601		var obj_width_map = [["15%", "20%", "25%", "20%", "20%"],["10%", "10%", "30%", "20%", "20%", "10%"],["6%", "6%", "27%", "20%", "15%", "6%", "6%", "6%", "8%"]];
2602		//var obj_width = (objID == "wired_list") ? obj_width_map[0] : ((stainfo_support) ? obj_width_map[2] : obj_width_map[1]);
2603		var obj_width = (stainfo_support) ? obj_width_map[2] : obj_width_map[1];
2604		var wl_colspan = stainfo_support ? 9 : 6;
2605		var clientListCode = "";
2606		//user icon
2607		userIconBase64 = "NoIcon";
2608
2609		clientListCode += "<table width='100%' cellspacing='0' cellpadding='0' align='center' class='list_table' id='tb_" + objID + "'>";
2610		if(sortArray.length == 0) {
2611			clientListCode += "<tr id='tr_" + objID + "'><td style='color:#FFCC00;' colspan='" + wl_colspan + "'><#IPConnection_VSList_Norule#></td></tr>";
2612		}
2613		else {
2614			clientlist_sort = new Array();
2615			for(var i = 0; i < sortArray.length; i += 1) {
2616				clientlist_sort.push(new listViewProfile(sortArray[i]));
2617			}
2618
2619			for(var j = 0; j < clientlist_sort.length; j += 1) {
2620				clientListCode += "<tr height='48px'>";
2621
2622				if(usericon_support) {
2623					if(clientListViewMacUploadIcon[clientlist_sort[j].mac] == undefined) {
2624						var clientMac = clientlist_sort[j].mac.replace(/\:/g, "");
2625						userIconBase64 = getUploadIcon(clientMac);
2626						clientListViewMacUploadIcon[clientlist_sort[j].mac] = userIconBase64;
2627					}
2628					else {
2629						userIconBase64 = clientListViewMacUploadIcon[clientlist_sort[j].mac];
2630					}
2631				}
2632
2633				var internetStateCss = "";
2634				var internetStateTip = "";
2635				if(clientlist_sort[j].internetState) {
2636					internetStateCss = "internetAllow" ;
2637					internetStateTip = "Allow Internet access";
2638				}
2639				else {
2640					internetStateCss = "internetBlock";
2641					internetStateTip = "Block Internet access";
2642				}
2643				clientListCode += "<td width='" + obj_width[0] + "' align='center'>";
2644				clientListCode += "<div class=" + internetStateCss + " title=\"" + internetStateTip + "\"></div>";
2645				clientListCode += "</td>";
2646				clientListCode += "<td width='" + obj_width[1] + "' align='center'>";
2647				// display how many clients that hide behind a repeater.
2648				if(clientlist_sort[j].macRepeat > 1){
2649					clientListCode += '<div class="clientlist_circle"';
2650					clientListCode += 'onmouseover="return overlib(\''+clientlist_sort[j].macRepeat+' clients are connecting to <% nvram_get("productid"); %> through this device.\');"';
2651					clientListCode += 'onmouseout="nd();"><div>';
2652					clientListCode += clientlist_sort[j].macRepeat;
2653					clientListCode += '</div></div>';
2654				}
2655
2656				if(userIconBase64 != "NoIcon") {
2657					clientListCode += "<div style='height:42px;width:42px;' title='"+ clientlist_sort[j].deviceTypeName +"'>";
2658					clientListCode += "<img class='imgUserIcon_viewlist' src=" + userIconBase64 + "";
2659					clientListCode += ">";
2660					clientListCode += "</div>";
2661				}
2662				else if( clientlist_sort[j].type != "0" || clientlist_sort[j].vender == "") {
2663					var icon_type = "type" + clientlist_sort[j].type;
2664					if(clientlist_sort[j].type == "0") {
2665						icon_type = "type0_viewMode";
2666					}
2667					clientListCode += "<div style='height:40px;width:40px;cursor:default;' class='clientIcon_no_hover " + icon_type + "' title='"+ clientlist_sort[j].deviceTypeName +"'></div>";
2668				}
2669				else if(clientlist_sort[j].vender != "" ) {
2670					var venderIconClassName = getVenderIconClassName(clientlist_sort[j].vender.toLowerCase());
2671					if(venderIconClassName != "" && !downsize_4m_support) {
2672						clientListCode += "<div style='height:42px;width:42px;background-size:77px;cursor:default;' class='venderIcon_no_hover " + venderIconClassName + "' title='"+ clientlist_sort[j].deviceTypeName +"'></div>";
2673					}
2674					else {
2675						var icon_type = "type" + clientlist_sort[j].type;
2676						if(clientlist_sort[j].type == "0") {
2677							icon_type = "type0_viewMode";
2678						}
2679						clientListCode += "<div style='height:40px;width:40px;cursor:default;' class='clientIcon_no_hover " + icon_type + "' title='"+ clientlist_sort[j].deviceTypeName +"'></div>";
2680					}
2681				}
2682				clientListCode += "</td>";
2683				clientListCode += "<td style='word-wrap:break-word; word-break:break-all;' width='" + obj_width[2] + "'>";
2684				clientListCode += "<div id='div_clientName_"+objID+"_"+j+"' class='viewclientlist_clientName_edit' onclick='editClientName(\""+objID+"_"+j+"\");'>"+clientlist_sort[j].name+"</div>";
2685				clientListCode += "<input id='client_name_"+objID+"_"+j+"' type='text' value='"+clientlist_sort[j].name+"' class='input_25_table' maxlength='32' style='width:95%;margin-left:0px;display:none;' onblur='saveClientName(\""+objID+"_"+j+"\", "+clientlist_sort[j].type+", this);'>";
2686				clientListCode += "</td>";
2687				var ipStyle = ('<% nvram_get("sw_mode"); %>' == "1") ? "line-height:16px;text-align:left;padding-left:10px;" : "line-height:16px;text-align:center;";
2688				clientListCode += "<td width='" + obj_width[3] + "' style='" + ipStyle + "'>";
2689				clientListCode += (clientList[clientlist_sort[j].mac].isWebServer) ? "<a class='link' href='http://"+clientlist_sort[j].ip+"' target='_blank'>"+clientlist_sort[j].ip+"</a>" : clientlist_sort[j].ip;
2690				if('<% nvram_get("sw_mode"); %>' == "1") {
2691					clientListCode += '<span style="float:right;margin-top:-3px;margin-right:5px;" class="ipMethodTag" onmouseover="return overlib(\''
2692					clientListCode += ipState[clientList[clientlist_sort[j].mac].ipMethod];
2693					clientListCode += '\')" onmouseout="nd();">'
2694					clientListCode += clientList[clientlist_sort[j].mac].ipMethod + '</span>';
2695				}
2696
2697				clientListCode += "</td>";
2698				clientListCode += "<td width='" + obj_width[4] + "'>"+clientlist_sort[j].mac+"</td>";
2699				var rssi_t = 0;
2700				rssi_t = convRSSI(clientlist_sort[j].rssi);
2701				clientListCode += "<td width='" + obj_width[5] + "' align='center'><div style='height:28px;width:28px'><div class='radioIcon radio_" + rssi_t + "'></div>";
2702				if(clientlist_sort[j].isWL != 0) {
2703					var bandClass = (navigator.userAgent.toUpperCase().match(/CHROME\/([\d.]+)/)) ? "band_txt_chrome" : "band_txt";
2704					clientListCode += "<div class='band_block'><span class='" + bandClass + "'>" + wl_nband_title[clientlist_sort[j].isWL-1].replace("Hz", "") + "</span></div>";
2705				}
2706				clientListCode += "</div></td>";
2707				if(stainfo_support) {
2708					var txRate = "";
2709					var rxRate = "";
2710					if(clientlist_sort[j].isWL != 0) {
2711						txRate = (clientlist_sort[j].curTx == "") ? "-" : clientlist_sort[j].curTx.replace("Mbps","");
2712						rxRate = (clientlist_sort[j].curRx == "") ? "-" : clientlist_sort[j].curRx.replace("Mbps","");
2713					}
2714					else {
2715						txRate = "-";
2716						rxRate = "-";
2717					}
2718					clientListCode += "<td width='" + obj_width[6] + "'>" + txRate + "</td>";
2719					clientListCode += "<td width='" + obj_width[7] + "'>" + rxRate + "</td>";
2720					clientListCode += "<td width='" + obj_width[8] + "'>"+((clientlist_sort[j].wlConnectTime == "00:00:00") ? "-" : clientlist_sort[j].wlConnectTime)+"</td>";
2721				}
2722				clientListCode += "</tr>";
2723			}
2724		}
2725		clientListCode += "</table>";
2726		document.getElementById("clientlist_" + objID + "_Block").innerHTML = clientListCode;
2727	}
2728}
2729
2730function showHideContent(objnmae, thisObj) {
2731	if(!slideFlag) {
2732		var state = document.getElementById(objnmae).style.display;
2733		var clickItem = objnmae.split("_")[1];
2734		if(state == "none") {
2735			if(clienlistViewMode == "All")
2736				sorter.all_display = true;
2737			else {
2738				switch (clickItem) {
2739					case "wired" :
2740						sorter.wired_display = true;
2741						break;
2742					case "wl1" :
2743						sorter.wl1_display = true;
2744						break;
2745					case "wl2" :
2746						sorter.wl2_display = true;
2747						break;
2748					case "wl3" :
2749						sorter.wl3_display = true;
2750						break;
2751				}
2752			}
2753			slideFlag = true;
2754			slideDown(objnmae, 200);
2755			thisObj.innerHTML = "[ Hide ]";
2756		}
2757		else {
2758			if(clienlistViewMode == "All")
2759				sorter.all_display = false;
2760			else {
2761				switch (clickItem) {
2762					case "wired" :
2763						sorter.wired_display = false;
2764						break;
2765					case "wl1" :
2766						sorter.wl1_display = false;
2767						break;
2768					case "wl2" :
2769						sorter.wl2_display = false;
2770						break;
2771					case "wl3" :
2772						sorter.wl3_display = false;
2773						break;
2774				}
2775			}
2776			slideFlag = true;
2777			slideUp(objnmae, 200);
2778			thisObj.innerHTML = "[ Show ]";
2779		}
2780	}
2781}
2782
2783function updateClientListView(){
2784	$.ajax({
2785		url: '/update_clients.asp',
2786		dataType: 'script',
2787		error: function(xhr) {
2788			setTimeout("updateClientListView();", 1000);
2789		},
2790		success: function(response){
2791			if(document.getElementById("clientlist_viewlist_content").style.display != "none") {
2792				if((isJsonChanged(originData, originDataTmp) || originData.fromNetworkmapd == "") && !edit_client_name_flag && !slideFlag){
2793					create_clientlist_listview();
2794					sorterClientList();
2795					parent.show_client_status(totalClientNum.online);
2796				}
2797				setTimeout("updateClientListView();", 3000);
2798			}
2799		}
2800	});
2801}
2802
2803function cal_panel_block_clientList(obj, multiple) {
2804	var isMobile = function() {
2805		var tmo_support = ('<% nvram_get("rc_support"); %>'.search("tmo") == -1) ? false : true;
2806		if(!tmo_support)
2807			return false;
2808
2809		if(	navigator.userAgent.match(/iPhone/i)	||
2810			navigator.userAgent.match(/iPod/i)		||
2811			navigator.userAgent.match(/iPad/i)		||
2812			(navigator.userAgent.match(/Android/i) && (navigator.userAgent.match(/Mobile/i) || navigator.userAgent.match(/Tablet/i))) ||
2813			(navigator.userAgent.match(/Opera/i) && (navigator.userAgent.match(/Mobi/i) || navigator.userAgent.match(/Mini/i))) ||	// Opera mobile or Opera Mini
2814			navigator.userAgent.match(/IEMobile/i)	||	// IE Mobile
2815			navigator.userAgent.match(/BlackBerry/i)	//BlackBerry
2816		 ) {
2817			return true;
2818		}
2819		else {
2820			return false;
2821		}
2822	};
2823	var blockmarginLeft;
2824	if (window.innerWidth) {
2825		winWidth = window.innerWidth;
2826	}
2827	else if ((document.body) && (document.body.clientWidth)) {
2828		winWidth = document.body.clientWidth;
2829	}
2830
2831	if (document.documentElement  && document.documentElement.clientHeight && document.documentElement.clientWidth) {
2832		winWidth = document.documentElement.clientWidth;
2833	}
2834
2835	if(winWidth > 1050) {
2836		winPadding = (winWidth - 1050) / 2;
2837		winWidth = 1105;
2838		blockmarginLeft = (winWidth * multiple) + winPadding;
2839	}
2840	else if(winWidth <= 1050) {
2841		if(isMobile()) {
2842			if(document.body.scrollLeft < 50) {
2843				blockmarginLeft= (winWidth) * multiple + document.body.scrollLeft;
2844			}
2845			else if(document.body.scrollLeft >320) {
2846				blockmarginLeft = 320;
2847			}
2848			else {
2849				blockmarginLeft = document.body.scrollLeft;
2850			}
2851		}
2852		else {
2853			blockmarginLeft = (winWidth) * multiple + document.body.scrollLeft;
2854		}
2855	}
2856
2857	document.getElementById(obj).style.marginLeft = blockmarginLeft + "px";
2858}
2859
2860function getFilePath(file) {
2861	var currentPath = file;
2862	var pathLength = location.pathname.split("/").length - 1;
2863	for(var i = pathLength; i > 1; i -= 1) {
2864	if(i == 1)
2865		currentPath = ".." + file;
2866	else
2867		currentPath = "../" + file;
2868	}
2869	return currentPath
2870};
2871
2872function editClientName(index) {
2873	document.getElementById("div_clientName_"+index).style.display = "none";
2874	document.getElementById("client_name_"+index).style.display = "";
2875	document.getElementById("client_name_"+index).focus();
2876	edit_client_name_flag = true;
2877}
2878var view_custom_name = decodeURIComponent('<% nvram_char_to_ascii("", "custom_clientlist"); %>').replace(/&#62/g, ">").replace(/&#60/g, "<");
2879function saveClientName(index, type, obj) {
2880
2881	document.getElementById("div_clientName_"+index).style.display = "";
2882	document.getElementById("client_name_"+index).style.display = "none";
2883	edit_client_name_flag = false;
2884
2885	var originalCustomListArray = new Array();
2886	var onEditClient = new Array();
2887	originalCustomListArray = view_custom_name.split('<');
2888
2889	onEditClient[0] = document.getElementById("client_name_"+index).value.trim();
2890	onEditClient[1] = obj.parentNode.parentNode.childNodes[4].innerHTML;
2891	onEditClient[2] = 0;
2892	onEditClient[3] = type;
2893	onEditClient[4] = "";
2894	onEditClient[5] = "";
2895	document.getElementById("div_clientName_"+index).innerHTML = document.getElementById("client_name_"+index).value.trim();
2896
2897	for(var i = 0; i < originalCustomListArray.length; i += 1) {
2898		if(originalCustomListArray[i].split('>')[1] == onEditClient[1]){
2899			onEditClient[4] = originalCustomListArray[i].split('>')[4]; // set back callback for ROG device
2900			onEditClient[5] = originalCustomListArray[i].split('>')[5]; // set back keeparp for ROG device
2901			originalCustomListArray.splice(i, 1); // remove the selected client from original list
2902		}
2903	}
2904	originalCustomListArray.push(onEditClient.join('>'));
2905	view_custom_name = originalCustomListArray.join('<');
2906	document.view_clientlist_form.custom_clientlist.value = view_custom_name;
2907	document.view_clientlist_form.submit();
2908}
2909
2910function updateClientListBackground() {
2911	$.ajax({
2912		url: '/update_networkmapd.asp',
2913		dataType: 'script',
2914		error: function(xhr) {
2915			setTimeout("updateClientListBackground();", 1000);
2916		},
2917		success: function(response) {
2918			var local_mac = '<% nvram_get("lan_hwaddr"); %>';
2919			cookie.set("wireless_list_" + local_mac + "_temp", cookie.get("wireless_list_" + local_mac));
2920			parent.document.networkmapdRefresh.client_info_tmp.value = fromNetworkmapd;
2921			fromNetworkmapdCache = fromNetworkmapd;
2922			cookie.unset("wireless_list_" + local_mac);
2923			parent.document.networkmapdRefresh.submit();
2924			setTimeout("updateClientListBackground();", 180000);
2925		}
2926	});
2927}
2928
2929function removeClient(_mac, _controlObj, _controlPanel) {
2930	if (!e)
2931		var e = window.event;
2932	e.cancelBubble = true;
2933	if (e.stopPropagation)
2934		e.stopPropagation();
2935
2936	if(document.getElementById("remove_nmpclientlist_form") != null) {
2937		removeElement(document.getElementById("remove_nmpclientlist_form"));
2938	}
2939	var formHTML = "";
2940	var formObj = document.createElement("form");
2941	document.body.appendChild(formObj);
2942	formObj.method = "POST";
2943	formObj.setAttribute("id","remove_nmpclientlist_form");
2944	formObj.setAttribute("name","remove_nmpclientlist_form");
2945	formObj.action = "/deleteOfflineClient.cgi";
2946	formObj.target = "hidden_frame";
2947
2948	var currentURL = "";
2949	if(location.pathname == "/")
2950		currentURL = "index.asp";
2951	else
2952		currentURL = location.pathname.substring(location.pathname.lastIndexOf('/') + 1);
2953
2954	formHTML += '<input type="hidden" name="current_page" value=' + currentURL + '>';
2955	formHTML += '<input type="hidden" name="next_page" value=' + currentURL + '>';
2956	formHTML += '<input type="hidden" name="modified" value="0">';
2957	formHTML += '<input type="hidden" name="flag" value="">';
2958	formHTML += '<input type="hidden" name="action_mode" value="">';
2959	formHTML += '<input type="hidden" name="action_script" value="">';
2960	formHTML += '<input type="hidden" name="action_wait" value="1">';
2961	formHTML += '<input type="hidden" name="delete_offline_client" value="">';
2962	formObj.innerHTML = formHTML;
2963
2964	document.remove_nmpclientlist_form.delete_offline_client.value = _mac;
2965
2966	//remove the client Element
2967	if(document.getElementById(_mac) != null) {
2968		removeElement(document.getElementById(_mac));
2969	}
2970
2971	//remove offline title and content
2972	if(document.getElementById(_controlPanel).childNodes.length == "0") {
2973		if(document.getElementById(_controlPanel) != null) {
2974			removeElement(document.getElementById(_controlPanel));
2975		}
2976		if(document.getElementById(_controlObj) != null) {
2977			removeElement(document.getElementById(_controlObj));
2978		}
2979	}
2980	document.remove_nmpclientlist_form.submit();
2981}
2982function expand_hide_Client(_obj, _controlObj) {
2983	if(!slideFlag) {
2984		var display_state = document.getElementById(_controlObj).style.display;
2985		if(display_state == "none") {
2986			slideFlag = true;
2987			slideDown(_controlObj, 100);
2988			document.getElementById(_obj).innerText = "Hide Offline Client List";/*untranslated*/
2989		}
2990		else {
2991			slideFlag = true;
2992			slideUp(_controlObj, 100);
2993			document.getElementById(_obj).innerText = "Show Offline Client List";/*untranslated*/
2994		}
2995	}
2996}
2997
2998function control_dropdown_client_block(_containerID, _pullArrowID) {
2999	event.stopPropagation(); //cancel bubbling
3000	var element = event.target || event.srcElement;
3001	if(element.id == "") {
3002		if(document.getElementById(_containerID) != null && document.getElementById(_pullArrowID) != null) {
3003			var container_state = document.getElementById(_containerID).style.display;
3004			var pullArrow_state = document.getElementById(_pullArrowID).src;
3005			if(container_state == "block") {
3006				document.getElementById(_containerID).style.display = "none";
3007				document.getElementById(_pullArrowID).src = "/images/arrow-down.gif";
3008			}
3009		}
3010	}
3011}
3012
3013//_callBackFunParam = mac>ip>..., _interfaceMode = all(wired, wll), wired, wl, _clientState = all, online, offline
3014function showDropdownClientList(_callBackFun, _callBackFunParam, _interfaceMode, _containerID, _pullArrowID, _clientState) {
3015	document.body.onclick = function() {control_dropdown_client_block(_containerID, _pullArrowID);}
3016	if(clientList.length == 0){
3017		setTimeout(function() {
3018			genClientList();
3019			showDropdownClientList(_callBackFun, _callBackFunParam, _interfaceMode, _containerID, _pullArrowID);
3020		}, 500);
3021		return false;
3022	}
3023
3024	var htmlCode = "";
3025	htmlCode += "<div id='clientlist_online'></div>";
3026	htmlCode += "<div id='clientlist_dropdown_expand' class='clientlist_dropdown_expand' onclick='expand_hide_Client(\"clientlist_dropdown_expand\", \"clientlist_offline\");' onmouseover='over_var=1;' onmouseout='over_var=0;'>Show Offline Client List</div>";
3027	htmlCode += "<div id='clientlist_offline'></div>";
3028	document.getElementById(_containerID).innerHTML = htmlCode;
3029
3030	var param = _callBackFunParam.split(">");
3031	var clientMAC = "";
3032	var clientIP = "";
3033	var getClientValue = function(_attribute, _clienyObj) {
3034		var attribute_value = "";
3035		switch(_attribute) {
3036			case "mac" :
3037				attribute_value = _clienyObj.mac;
3038				break;
3039			case "ip" :
3040				if(clientObj.ip != "offline") {
3041					attribute_value = _clienyObj.ip;
3042				}
3043				break;
3044			case "name" :
3045				attribute_value = (clientObj.nickName == "") ? clientObj.name : clientObj.nickName;
3046				break;
3047		}
3048		return attribute_value;
3049	};
3050
3051	var genClientItem = function(_state) {
3052		var code = "";
3053		var clientName = (clientObj.nickName == "") ? clientObj.name : clientObj.nickName;
3054
3055		code += '<a id=' + clientList[i] + ' title=' + clientList[i] + '>';
3056		if(_state == "online")
3057			code += '<div onclick="' + _callBackFun + '(\'';
3058		else if(_state == "offline")
3059			code += '<div style="color:#A0A0A0" onclick="' + _callBackFun + '(\'';
3060		for(var j = 0; j < param.length; j += 1) {
3061			if(j == 0) {
3062				code += getClientValue(param[j], clientObj);
3063			}
3064			else {
3065				code += '\', \'';
3066				code += getClientValue(param[j], clientObj);
3067			}
3068		}
3069		code += '\');">';
3070		code += '<strong>';
3071		if(clientName.length > 32) {
3072			code += clientName.substring(0, 30) + "..";
3073		}
3074		else {
3075			code += clientName;
3076		}
3077		code += '</strong>';
3078		if(_state == "offline")
3079			code += '<strong title="Remove this client" style="float:right;margin-right:5px;cursor:pointer;" onclick="removeClient(\'' + clientObj.mac + '\', \'clientlist_dropdown_expand\', \'clientlist_offline\')">×</strong>';
3080		code += '</div><!--[if lte IE 6.5]><iframe class="hackiframe2"></iframe><![endif]--></a>';
3081		return code;
3082	};
3083
3084	for(var i = 0; i < clientList.length; i +=1 ) {
3085		var clientObj = clientList[clientList[i]];
3086		switch(_clientState) {
3087			case "all" :
3088				if(_interfaceMode == "wl" && (clientList[clientList[i]].isWL == 0)) {
3089					continue;
3090				}
3091				if(_interfaceMode == "wired" && (clientList[clientList[i]].isWL != 0)) {
3092					continue;
3093				}
3094				if(clientObj.isOnline) {
3095					document.getElementById("clientlist_online").innerHTML += genClientItem("online");
3096				}
3097				else if(clientObj.from == "nmpClient") {
3098					document.getElementById("clientlist_offline").innerHTML += genClientItem("offline");
3099				}
3100				break;
3101			case "online" :
3102				if(_interfaceMode == "wl" && (clientList[clientList[i]].isWL == 0)) {
3103					continue;
3104				}
3105				if(_interfaceMode == "wired" && (clientList[clientList[i]].isWL != 0)) {
3106					continue;
3107				}
3108				if(clientObj.isOnline) {
3109					document.getElementById("clientlist_online").innerHTML += genClientItem("online");
3110				}
3111				break;
3112			case "offline" :
3113				if(_interfaceMode == "wl" && (clientList[clientList[i]].isWL == 0)) {
3114					continue;
3115				}
3116				if(_interfaceMode == "wired" && (clientList[clientList[i]].isWL != 0)) {
3117					continue;
3118				}
3119				if(clientObj.from == "nmpClient") {
3120					document.getElementById("clientlist_offline").innerHTML += genClientItem("offline");
3121				}
3122				break;
3123		}
3124	}
3125
3126	if(document.getElementById("clientlist_offline").childNodes.length == "0") {
3127		if(document.getElementById("clientlist_dropdown_expand") != null) {
3128			removeElement(document.getElementById("clientlist_dropdown_expand"));
3129		}
3130		if(document.getElementById("clientlist_offline") != null) {
3131			removeElement(document.getElementById("clientlist_offline"));
3132		}
3133	}
3134	else {
3135		if(document.getElementById("clientlist_dropdown_expand").innerText == "Show Offline Client List") {
3136			document.getElementById("clientlist_offline").style.display = "none";
3137		}
3138		else {
3139			document.getElementById("clientlist_offline").style.display = "";
3140		}
3141	}
3142	if(document.getElementById("clientlist_online").childNodes.length == "0") {
3143		if(document.getElementById("clientlist_online") != null) {
3144			removeElement(document.getElementById("clientlist_online"));
3145		}
3146	}
3147
3148	if(document.getElementById(_containerID).childNodes.length == "0")
3149		document.getElementById(_pullArrowID).style.display = "none";
3150	else
3151		document.getElementById(_pullArrowID).style.display = "";
3152}
3153