2 function ventoy_replace_slash(str
) {
3 var str1
= str
.replace(/\\/g
, '/');
4 var str2
= str1
.replace(/\/\//g, '/');
6 if (str2
&& str2
.length
> 0) {
7 if (str2
.substr(-1) === "/") {
8 return str2
.substr(0, str2
.length
- 1);
16 function ventoy_get_ulen(str
) {
17 var c
, b
= 0, l
= str
.length
;
19 c
= str
.charCodeAt(--l
);
20 b
+= (c
< 128) ? 1 : ((c
< 2048) ? 2 : ((c
< 65536) ? 3 : 4));
26 function ventoy_common_check_path(path
) {
27 if (path
.indexOf('//') >= 0) {
31 if (path
.length
<= g_current_dir
.length
) {
35 if (path
.substr(0, g_current_dir
.length
) != g_current_dir
) {
44 function loadContent(page
) {
45 $("#plugson-content").load(page
+ ".html?_=" + (new Date().getTime()), function() {
46 $("body").scrollTop(0);
51 function callVtoyCatchErr(p1
, p2
, p3
) {
52 var url
= '/vtoy/json';
54 var func = function(data
) {};
55 var errfunc = function(xmlHttpRequest
, textStatus
, errorThrown
) {};
57 if (typeof(p1
) === 'string') {
59 } else if (typeof(p1
) === 'object') {
62 if (typeof(p2
) === 'object') {
64 } else if (typeof(p2
) === 'function') {
67 if (typeof(p3
) === 'function') {
71 //vtoy.debug('callVtoy:\t\t\t\t' + JSON.stringify(data));
77 data: JSON
.stringify(data
),
80 complete: function(data
) {
81 //vtoy.debug('callVtoy\'s resp:\t\t' + data.responseText);
87 function callVtoy(p1
, p2
, p3
) {
88 var url
= '/vtoy/json';
90 var func = function(data
) {};
92 if (typeof(p1
) === 'string') {
94 } else if (typeof(p1
) === 'object') {
97 if (typeof(p2
) === 'object') {
99 } else if (typeof(p2
) === 'function') {
102 if (typeof(p3
) === 'function') {
106 //vtoy.debug('callVtoy:\t\t\t\t' + JSON.stringify(data));
112 data: JSON
.stringify(data
),
114 error: function(xmlHttpRequest
, textStatus
, errorThrown
) {
116 if(undefined === errorThrown
)
118 Message
.error(g_vtoy_cur_language
.STR_WEB_REMOTE_ABNORMAL
);
120 else if(undefined === errorThrown
.length
)
124 else if('' == errorThrown
.trim())
133 Message
.error(g_vtoy_cur_language
.STR_WEB_REQUEST_TIMEOUT
);
136 case 'Service Unavailable':
138 Message
.error(g_vtoy_cur_language
.STR_WEB_SERVICE_UNAVAILABLE
);
147 Message
.error(g_vtoy_cur_language
.STR_WEB_COMMUNICATION_ERR
+ errorThrown
);
153 complete: function(data
) {
154 //vtoy.debug('callVtoy\'s resp:\t\t' + data.responseText);
159 function callVtoyASyncTimeout(time
, data
, func
) {
167 data: JSON
.stringify(data
),
169 error: function(xmlHttpRequest
, textStatus
, errorThrown
) {
170 if(undefined === errorThrown
)
173 else if(undefined === errorThrown
.length
)
177 else if('' == errorThrown
.trim())
186 callVtoyASyncTimeout(time
, data
, func
);
189 case 'Service Unavailable':
204 complete: function(data
) {
205 //vtoy.debug('callVtoyASyncTimeout\'s resp:\t' + JSON.stringify(data));
210 function callVtoySync(data
, func
) {
211 //vtoy.debug('callVtoySync:\t\t\t' + JSON.stringify(data));
218 data: JSON
.stringify(data
),
219 success: function VtoyCallFuncWrapper(data
) {
220 if (data
.result
=== 'busy') {
221 var titlestr
= '<span class="fa fa-check-circle" style="color:green; font-weight:bold;"> ' + g_vtoy_cur_language
.STR_INFO
+ '</span>';
222 var msgstr
= '<span style="font-size:14px; font-weight:bold;"> ' + g_vtoy_cur_language
.STR_WEB_SERVICE_BUSY
+ '</span>';
223 Modal
.alert({title:titlestr
, msg:msgstr
, btnok:g_vtoy_cur_language
.STR_BTN_OK
});
228 error: function(xmlHttpRequest
, textStatus
, errorThrown
) {
229 if(undefined === errorThrown
)
231 Message
.error(g_vtoy_cur_language
.STR_WEB_REMOTE_ABNORMAL
);
233 else if(undefined === errorThrown
.length
)
237 else if('' == errorThrown
.trim())
246 Message
.error(g_vtoy_cur_language
.STR_WEB_REQUEST_TIMEOUT
);
249 case 'Service Unavailable':
251 Message
.error(g_vtoy_cur_language
.STR_WEB_SERVICE_UNAVAILABLE
);
260 Message
.error(g_vtoy_cur_language
.STR_WEB_COMMUNICATION_ERR
+ errorThrown
);
266 complete: function(data
) {
267 //vtoy.debug('callVtoySync\'s resp:\t' + JSON.stringify(data));
282 String
.prototype.endsWith = function(str
) {
283 if (str
== null || str
== "" || this.length
== 0 || str
.length
> this.length
)
285 if (this.substring(this.length
- str
.length
) == str
)
291 window
.Message = function() {
292 var _showMsg = function(type
, msg
, time
) {
293 var o
= {type : type
, msg : msg
};
300 var _show = function(options
) {
306 $.extend(ops
, options
);
308 var msg_class
= 'alert-success';
309 if('S' === ops
.type
|| 's' === ops
.type
) {
310 msg_class
= 'alert-success';
311 } else if ('E' === ops
.type
|| 'e' === ops
.type
) {
312 msg_class
= 'alert-danger';
313 } else if ('W' === ops
.type
|| 'w' === ops
.type
) {
314 msg_class
= 'alert-warning';
315 } else if ('I' === ops
.type
|| 'i' === ops
.type
) {
316 msg_class
= 'alert-info';
318 alert("未知的类型,请使用: w-警告;s-成功;e-失败;i-提示");
321 var $messageContainer
= $("#fcss_message");
322 if($messageContainer
.length
=== 0) {
323 $messageContainer
= $('<div id="fcss_message" style="position:fixed; left: 20%; right: 20%; top:0px; z-index:99999999"></div>');
324 $messageContainer
.appendTo($('body'));
326 var $div
= $('<div class="alert ' + msg_class
+ ' alert-dismissible fade in" role="alert" style="margin-bottom: 0; padding-top:10px; padding-bottom: 10px;"></div>');
327 var $btn
= $('<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>');
328 $div
.append($btn
).append(ops
.msg
).appendTo($messageContainer
);
329 setTimeout(function() {
334 var _success = function(msg
, time
) {
335 _showMsg('s', msg
, time
);
337 var _error = function(msg
, time
) {
338 _showMsg('e', msg
, time
|| 5000);
340 var _warn = function(msg
, time
) {
341 _showMsg('w', msg
, time
);
343 var _info = function(msg
, time
) {
344 _showMsg('i', msg
, time
);
357 var g_vtoy_cur_language_en
=
361 "STR_BTN_CANCEL": "Cancel",
363 "STR_RESET": " Reset",
364 "STR_DISCARD": " Discard",
365 "STR_ENABLE": " Enable",
368 "STR_CLEAR": "Clear",
369 "STR_STATUS": "Status",
370 "STR_DEFAULT": "Default",
371 "STR_DEFAULT_SEL": "Default",
372 "STR_RANDOM_SEL": "Random",
373 "STR_OPERATION": "Operation",
374 "STR_VALID": "Valid",
375 "STR_INVALID": "Invalid",
376 "STR_OPT_SETTING": "Option Setting",
377 "STR_OPT_DESC": "Option Description",
381 "STR_SAVE_TIP": "Data in current page has been modified. Do you want to save it?",
382 "STR_SAVE_SUCCESS": "Configuration successfully saved!",
383 "STR_FILE_EXIST": "OK",
384 "STR_FILE_NONEXIST": "Invalid",
385 "STR_FILE_FUZZY": "Fuzzy",
386 "STR_DIR_EXIST": "OK",
387 "STR_DIR_NONEXIST": "Invalid",
388 "STR_DUPLICATE_PATH": "Duplicate path",
389 "STR_DELETE_CONFIRM": "Delete this item, Continue?",
390 "STR_FILE_PATH": "File Path",
391 "STR_DIR_PATH": "Directory Path",
393 "STR_SET_ALIAS": "Set Menu Alias",
394 "STR_ALIAS": "Alias",
395 "STR_SET_TIP": "Set Menu Tip",
397 "STR_SET_CLASS": "Set Menu Class",
398 "STR_CLASS": "Class",
399 "STR_SET_INJECTION": "Set Injection",
400 "STR_SET_AUTO_INS": "Set Auto Install",
401 "STR_SET_AUTO_TEMPLATE": "Template",
403 "STR_SET_PERSISTENCE": "Set Persistence",
404 "STR_SET_PERSISTENCE_DAT": "Dat File",
406 "STR_SET_DUD": "Set DUD",
407 "STR_SET_DUD_FILE": "DUD File",
409 "STR_PASSWORD": "Password",
410 "STR_SET_PASSWORD": "Set Password",
411 "STR_PASSWORD_TYPE": "Password Type",
412 "STR_PASSWORD_VALUE": "Password Value",
415 "STR_WEB_COMMUNICATION_ERR":"Communication error:",
416 "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal",
417 "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out",
418 "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable",
419 "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.",
421 "STR_PLUG_DEVICE": "Device Information",
422 "STR_PLUG_CONTROL": "Global Control Plugin",
423 "STR_PLUG_THEME": "Theme Plugin",
424 "STR_PLUG_ALIAS": "Menu Alias Plugin",
425 "STR_PLUG_CLASS": "Menu Class Plugin",
426 "STR_PLUG_TIP": "Menu Tip Plugin",
427 "STR_PLUG_AUTO_INSTALL": "Auto Install Plugin",
428 "STR_PLUG_PERSISTENCE": "Persistence Plugin",
429 "STR_PLUG_INJECTION": "Injection Plugin",
430 "STR_PLUG_CONF_REPLACE": "Boot Conf Replace Plugin",
431 "STR_PLUG_PASSWORD": "Password Plugin",
432 "STR_PLUG_IMAGELIST": "Image List Plugin",
433 "STR_PLUG_AUTO_MEMDISK": "Auto Memdisk Plugin",
434 "STR_PLUG_DUD": "DUD Plugin",
435 "STR_PLUG_DONATION": "Donation",
437 "STR_PATH_TOO_LONG": "The path exceeds the maximum supported length, please check!",
438 "STR_INPUT_TOO_LONG": "The string exceeds the maximum supported length, please check!",
439 "STR_INVALID_FILE_PATH": "Invalid or nonexist full file path, please check!",
440 "STR_INVALID_FILE_PATH1": "The 1st file path is invalid or nonexist!",
441 "STR_INVALID_FILE_PATH2": "The 2nd file path is invalid or nonexist!",
442 "STR_INVALID_NEW_FILE_PATH": "The full file path of new is invalid or nonexist, please check!",
443 "STR_INVALID_DIR_PATH": "Invalid directory path, please check!",
444 "STR_INVALID_NUMBER": "Please input valid non-negative integer!",
445 "STR_INVALID_AUTOSEL": "autosel exceeds the length of the list!",
446 "STR_INVALID_TIMEOUT": "Please input valid timeout integer!",
447 "STR_INVALID_PERCENT": "Please input integer between 0-100 !",
448 "STR_INVALID_COLOR": "Please input valid color!",
449 "STR_SELECT": "Please Select",
450 "STR_SET_ALIAS_FOR_FILE": "Set Menu Alias For File",
451 "STR_SET_ALIAS_FOR_DIR": "Set Menu Alias For Directory",
452 "STR_SET_TIP_FOR_FILE": "Set Menu Tip For File",
453 "STR_SET_TIP_FOR_DIR": "Set Menu Tip For Directory",
454 "STR_SET_INJECTION_FOR_FILE": "[image] Set injection for a file",
455 "STR_SET_INJECTION_FOR_DIR": "[parent] Set the same injection for all the files under a directory.",
456 "STR_INVALID_ARCHIVE_PATH": "Invalid or nonexist archive file path, please check!",
457 "STR_SET_PWD_FOR_FILE": "[file] Set password for a file.",
458 "STR_SET_PWD_FOR_DIR": "[parent] Set the same password for all the files under a directory.",
459 "STR_SET_AUTO_INSTALL_FOR_FILE": "[image] Set auto install template for a file",
460 "STR_SET_AUTO_INSTALL_FOR_DIR": "[parent] Set the same auto install template for all the files under a directory.",
462 "STR_SET_CLASS_BY_KEY": "[key] Set menu class by filename keyword.",
463 "STR_SET_CLASS_BY_DIR": "[dir] Set menu class for a directory.",
464 "STR_SET_CLASS_BY_PARENT": "[parent] Set menu class for all the files under a directory.",
465 "STR_SET_IMAGE_PWD": "[file] Set Password For A File",
466 "STR_SET_PARENT_PWD": "[parent] Set the same password for all the files under a directory.",
468 "STR_SET_SEARCH_ROOT": "Set Search Root",
469 "STR_SET_DEFAULT_IMAGE": "Set Default Image",
470 "STR_ADD_THEME": "Add Theme",
471 "STR_ADD_FONT": "Set Font",
472 "STR_ADD_FILE_TO_LIST": "Add File To List",
473 "STR_DEFAULT_SELECT": " Default",
474 "STR_AUTO_TEMPLATE": "Auto Install Template",
475 "STR_ADD_AUTO_TEMPLATE": "Add Auto Install Template",
477 "STR_PERSISTENCE_DAT": "Persistence Dat File",
478 "STR_ADD_PERSISTENCE_DAT": "Add Persistence Dat File",
480 "STR_DUD_FILE": "DUD File",
481 "STR_ADD_DUD_FILE": "Add DUD File",
483 "STR_DEL_LAST": "The entry will be deleted if you delete the this last item. Continue?",
485 "STR_CLOSE_TIP": "Service unavailable, the page will close!",
486 "STR_SECURE_BOOT_ENABLE": "Enable",
487 "STR_SECURE_BOOT_DISABLE": "Disable",
488 "STR_SYNTAX_ERROR_TIP": "Syntax error detected in ventoy.json, so the configuration is not loaded!",
489 "STR_INVALID_CONFIG_TIP": "Invalid configuration detected in ventoy.json, so the configuration is not loaded!",
490 "STR_CONFIG_SAVE_ERROR_TIP": "Failed to write ventoy.json file. Check VentoyPlugson.log for more details!",
495 var g_vtoy_cur_language_cn
=
499 "STR_BTN_CANCEL": "取消",
502 "STR_DISCARD": " 丢弃",
509 "STR_DEFAULT_SEL": "默认选择",
510 "STR_RANDOM_SEL": "随机选择",
511 "STR_OPERATION": "操作",
514 "STR_OPT_SETTING": "选项设置",
515 "STR_OPT_DESC": "选项说明",
519 "STR_SAVE_TIP": "当前页面数据已经修改,是否保存?",
520 "STR_SAVE_SUCCESS": "配置保存成功!",
521 "STR_FILE_EXIST": "文件存在",
522 "STR_FILE_NONEXIST": "文件无效",
523 "STR_FILE_FUZZY": "模糊匹配",
524 "STR_DIR_EXIST": "目录存在",
525 "STR_DIR_NONEXIST": "目录无效",
526 "STR_DUPLICATE_PATH": "路径不允许重复",
527 "STR_DELETE_CONFIRM": "确定要删除吗?",
528 "STR_FILE_PATH": "文件路径",
529 "STR_DIR_PATH": "目录路径",
531 "STR_SET_ALIAS": "设置菜单别名",
533 "STR_SET_TIP": "设置菜单提示",
535 "STR_SET_CLASS": "设置菜单类型",
537 "STR_SET_INJECTION": "设置文件注入",
538 "STR_SET_AUTO_INS": "设置自动安装",
539 "STR_SET_AUTO_TEMPLATE": "自动安装脚本",
540 "STR_SET_PERSISTENCE": "设置持久化文件",
541 "STR_SET_PERSISTENCE_DAT": "持久化文件",
543 "STR_SET_DUD": "设置 DUD",
544 "STR_SET_DUD_FILE": "DUD 文件",
546 "STR_PASSWORD": "密码",
547 "STR_SET_PASSWORD": "设置密码",
548 "STR_PASSWORD_TYPE": "密码类型",
549 "STR_PASSWORD_VALUE": "密码内容",
551 "STR_WEB_COMMUNICATION_ERR":"通信失败:",
552 "STR_WEB_REMOTE_ABNORMAL":"通信失败:服务端异常",
553 "STR_WEB_REQUEST_TIMEOUT":"通信失败:请求超时",
554 "STR_WEB_SERVICE_UNAVAILABLE":"通信失败:服务不可用",
555 "STR_WEB_SERVICE_BUSY":"后台服务正忙,请稍后重试",
557 "STR_PLUG_DEVICE": "设备信息",
558 "STR_PLUG_CONTROL": "全局控制插件",
559 "STR_PLUG_THEME": "主题插件",
560 "STR_PLUG_ALIAS": "菜单别名插件",
561 "STR_PLUG_CLASS": "菜单类型插件",
562 "STR_PLUG_TIP": "菜单提示插件",
563 "STR_PLUG_AUTO_INSTALL": "自动安装插件",
564 "STR_PLUG_PERSISTENCE": "数据持久化插件",
565 "STR_PLUG_INJECTION": "文件注入插件",
566 "STR_PLUG_CONF_REPLACE": "启动配置替换插件",
567 "STR_PLUG_PASSWORD": "密码插件",
568 "STR_PLUG_IMAGELIST": "文件列表插件",
569 "STR_PLUG_AUTO_MEMDISK": "自动Memdisk插件",
570 "STR_PLUG_DUD": "Driver Update Disk插件",
571 "STR_PLUG_DONATION": "捐助",
573 "STR_PATH_TOO_LONG": "路径超过最大支持长度,请检查!",
574 "STR_INPUT_TOO_LONG": "字符串超过最大支持长度,请检查!",
575 "STR_INVALID_FILE_PATH": "文件路径不合法或不存在,请检查!",
576 "STR_INVALID_FILE_PATH1": "第1个文件路径不合法或不存在,请检查!",
577 "STR_INVALID_FILE_PATH2": "第2个文件路径不合法或不存在,请检查!",
578 "STR_INVALID_NEW_FILE_PATH": "new 文件路径不合法或不存在,请检查!",
579 "STR_INVALID_DIR_PATH": "文件夹路径不合法,请检查!",
580 "STR_INVALID_NUMBER": "请输入合法的非负整数!",
581 "STR_INVALID_AUTOSEL": "autosel 的值超过了列表实际长度!",
582 "STR_INVALID_TIMEOUT": "请输入合法的超时秒数!",
583 "STR_INVALID_PERCENT": "请输入 0-100 以内的整数!",
584 "STR_INVALID_COLOR": "请输入合法的颜色!",
586 "STR_SET_ALIAS_FOR_FILE": "为文件设置别名",
587 "STR_SET_ALIAS_FOR_DIR": "为目录设置别名",
588 "STR_SET_TIP_FOR_FILE": "为文件设置菜单提示信息",
589 "STR_SET_TIP_FOR_DIR": "为目录设置菜单提示信息",
590 "STR_SET_INJECTION_FOR_FILE": "[image] 为某一个文件设置注入",
591 "STR_SET_INJECTION_FOR_DIR": "[parent] 为某个目录下的所有文件设置相同的注入",
592 "STR_INVALID_ARCHIVE_PATH": "Archive 文件路径非法或不存在,请检查!",
593 "STR_SET_PWD_FOR_FILE": "[file] 为指定文件设置密码",
594 "STR_SET_PWD_FOR_DIR": "[parent] 为某个目录下的所有文件设置相同的密码",
595 "STR_SET_AUTO_INSTALL_FOR_FILE": "[image] 为某个镜像文件设置自动安装脚本",
596 "STR_SET_AUTO_INSTALL_FOR_DIR": "[parent] 为某个目录下的所有文件设置相同的自动安装脚本",
598 "STR_SET_CLASS_BY_KEY": "[key] 通过文件名关键字设置类型",
599 "STR_SET_CLASS_BY_DIR": "[dir] 为某个目录设置类型(只针对该目录本身,不包含里面的文件及子目录)",
600 "STR_SET_CLASS_BY_PARENT": "[parent] 为某个目录下的所有子文件设置类型(只针对文件,不包含目录)",
602 "STR_SET_IMAGE_PWD": "[file] 为某个镜像文件设置密码",
603 "STR_SET_PARENT_PWD": "[parent] 为某个目录下的所有文件设置相同的密码",
607 "STR_SET_SEARCH_ROOT": "设置搜索目录",
608 "STR_SET_DEFAULT_IMAGE": "设置默认镜像文件",
609 "STR_ADD_THEME": "添加主题",
610 "STR_ADD_FONT": "添加字体",
611 "STR_ADD_FILE_TO_LIST": "添加文件",
612 "STR_DEFAULT_SELECT": " 默认选择",
613 "STR_AUTO_TEMPLATE": "自动安装脚本",
614 "STR_ADD_AUTO_TEMPLATE": "添加自动安装脚本",
615 "STR_PERSISTENCE_DAT": "持久化数据文件",
616 "STR_ADD_PERSISTENCE_DAT": "添加持久化数据文件",
617 "STR_DUD_FILE": "DUD 文件",
618 "STR_ADD_DUD_FILE": "添加 DUD 文件",
620 "STR_DEL_LAST": "这是本条目中的最后一项,删除此项将会删除整个条目。是否继续?",
621 "STR_CLOSE_TIP": "后台服务不可用,页面即将关闭!",
622 "STR_SECURE_BOOT_ENABLE": "开启",
623 "STR_SECURE_BOOT_DISABLE": "未开启",
624 "STR_SYNTAX_ERROR_TIP": "ventoy.json 文件中存在语法错误,配置未加载!",
625 "STR_INVALID_CONFIG_TIP": "ventoy.json 文件中存在错误配置,配置未加载!",
626 "STR_CONFIG_SAVE_ERROR_TIP": "ventoy.json 文件写入失败,详细信息请参考 VentoyPlugson.log 文件!",
634 var g_current_language
= 'cn';
635 var g_vtoy_cur_language
= g_vtoy_cur_language_cn
;
636 var g_vtoy_data_default_index
= 6;
638 var g_file_with_extra
= false;
639 var g_dir_with_extra
= false;
640 var g_file_fuzzy_match
= 0;
641 var g_file_modal_callback
;
642 var g_dir_modal_callback
;
644 function ventoy_file_submit(form
, extra
) {
645 var filepath
= $("#FilePath").val();
646 var fileextra
= $("#FileExtra").val();
658 filepath
= ventoy_replace_slash(filepath
);
660 if (!ventoy_common_check_path(filepath
)) {
661 Message
.error(g_vtoy_cur_language
.STR_INVALID_FILE_PATH
);
665 if (g_file_fuzzy_match
&& filepath
.indexOf("*") >= 0) {
667 method : 'check_fuzzy',
670 if (data
.exist
!= 0) {
671 if (typeof(g_file_modal_callback
) === 'function') {
672 g_file_modal_callback(filepath
, -1, fileextra
);
674 $("#SetFileModal").modal('hide');
676 Message
.error(g_vtoy_cur_language
.STR_INVALID_FILE_PATH
);
681 method : 'check_path',
685 if (data
.exist
=== 1) {
686 if (typeof(g_file_modal_callback
) === 'function') {
687 g_file_modal_callback(filepath
, 1, fileextra
);
689 $("#SetFileModal").modal('hide');
691 Message
.error(g_vtoy_cur_language
.STR_INVALID_FILE_PATH
);
698 var g_filepath_validator
= $("#SetFileForm").validate({
710 submitHandler: function(form
) {
711 ventoy_file_submit(form
, g_file_with_extra
);
715 var g_dirpath_validator
= $("#SetDirForm").validate({
727 submitHandler: function(form
) {
728 var dirpath
= $("#DirPath").val();
729 var dirextra
= $("#DirExtra").val();
735 if (g_dir_with_extra
) {
741 dirpath
= ventoy_replace_slash(dirpath
);
743 if (dirpath
.length
> 0 && dirpath
.charCodeAt(dirpath
.length
- 1) === 47) {
744 dirpath
= dirpath
.substring(0, dirpath
.length
- 1);
747 if (!ventoy_common_check_path(dirpath
)) {
748 Message
.error(g_vtoy_cur_language
.STR_INVALID_DIR_PATH
);
753 method : 'check_path',
757 if (data
.exist
=== 1) {
758 if (typeof(g_dir_modal_callback
) === 'function') {
759 g_dir_modal_callback(dirpath
, dirextra
);
761 $("#SetDirModal").modal('hide');
763 Message
.error(g_vtoy_cur_language
.STR_INVALID_DIR_PATH
);
769 function VtoySelectFilePath(cb
, para
) {
770 g_file_fuzzy_match
= para
.fuzzy
;
773 $('div[id=id_div_file_extra]').show();
774 $('#SetFileForm_extra').text(para
.extra_title
);
776 $('div[id=id_div_file_extra]').hide();
779 $('span[id=id_span_filepath_tip1]').each(function(){
780 $(this).text(para
.tip1
);
782 $('span[id=id_span_filepath_tip2]').each(function(){
783 $(this).text(para
.tip2
);
785 $('span[id=id_span_filepath_tip3]').each(function(){
786 $(this).text(para
.tip3
);
789 if (g_current_language
=== 'en') {
790 if (para
.title
.length
=== 0) {
791 $('#SetFileForm #SetFileForm_lang_1').text("Set File Path");
793 $('#SetFileForm #SetFileForm_lang_1').text(para
.title
);
796 $('#SetFileForm #SetFileForm_lang_2').text("File Path");
797 $('#SetFileForm #SetFileForm_lang_3').text(" OK");
798 $('#SetFileForm #SetFileForm_lang_4').text("Cancel");
799 $('#SetFileForm #id_note_setfile_cn').hide();
800 $('#SetFileForm #id_note_setfile_en').show();
802 if (para
.title
.length
=== 0) {
803 $('#SetFileForm #SetFileForm_lang_1').text("设置文件路径");
805 $('#SetFileForm #SetFileForm_lang_1').text(para
.title
);
807 $('#SetFileForm #SetFileForm_lang_2').text("文件路径");
808 $('#SetFileForm #SetFileForm_lang_3').text("确定");
809 $('#SetFileForm #SetFileForm_lang_4').text("取消");
810 $('#SetFileForm #id_note_setfile_cn').show();
811 $('#SetFileForm #id_note_setfile_en').hide();
814 if (para
.tip3
.length
> 0) {
815 if (g_current_language
=== 'en') {
816 $('#SetFileForm #id_note_tip3_en').show();
817 $('#SetFileForm #id_note_tip3_cn').hide();
819 $('#SetFileForm #id_note_tip3_cn').show();
820 $('#SetFileForm #id_note_tip3_en').hide();
823 $('#SetFileForm #id_note_tip3_en').hide();
824 $('#SetFileForm #id_note_tip3_cn').hide();
827 g_file_modal_callback
= cb
;
828 g_file_with_extra
= para
.extra
;
829 g_filepath_validator
.settings
.rules
.FileExtra
.required
= g_file_with_extra
;
830 g_filepath_validator
.resetForm();
831 $("#SetFileModal").modal();
835 function VtoySelectDirPath(cb
, para
) {
836 $('span[id=id_span_dirpath_tip]').each(function(){
837 $(this).text(para
.tip
);
839 $('span[id=id_span_dirpath_tip3]').each(function(){
840 $(this).text(para
.tip3
);
844 $('div[id=id_div_dir_extra]').show();
845 $('label[id=SetDirForm_extra]').text(para
.extra_title
);
847 $('div[id=id_div_dir_extra]').hide();
850 if (g_current_language
=== 'en') {
851 if (para
.title
.length
=== 0) {
852 $('#SetDirForm #SetDirForm_lang_1').text("Set Directory Path");
854 $('#SetDirForm #SetDirForm_lang_1').text(para
.title
);
856 $('#SetDirForm #SetDirForm_lang_2').text("Directory Path");
857 $('#SetDirForm #SetDirForm_lang_3').text(" OK");
858 $('#SetDirForm #SetDirForm_lang_4').text("Cancel");
859 $('#SetDirForm #id_note_setfile_cn').hide();
860 $('#SetDirForm #id_note_setfile_en').show();
862 if (para
.title
.length
=== 0) {
863 $('#SetDirForm #SetDirForm_lang_1').text("设置文件夹路径");
865 $('#SetDirForm #SetDirForm_lang_1').text(para
.title
);
867 $('#SetDirForm #SetDirForm_lang_2').text("文件夹路径");
868 $('#SetDirForm #SetDirForm_lang_3').text("确定");
869 $('#SetDirForm #SetDirForm_lang_4').text("取消");
870 $('#SetDirForm #id_note_setfile_cn').show();
871 $('#SetDirForm #id_note_setfile_en').hide();
874 if (para
.tip3
.length
> 0) {
875 if (g_current_language
=== 'en') {
876 $('#SetDirForm #id_note_tip3_en').show();
877 $('#SetDirForm #id_note_tip3_cn').hide();
879 $('#SetDirForm #id_note_tip3_cn').show();
880 $('#SetDirForm #id_note_tip3_en').hide();
883 $('#SetDirForm #id_note_tip3_en').hide();
884 $('#SetDirForm #id_note_tip3_cn').hide();
887 g_dir_modal_callback
= cb
;
888 g_dir_with_extra
= para
.extra
;
889 g_dirpath_validator
.settings
.rules
.DirExtra
.required
= g_dir_with_extra
;
890 g_dirpath_validator
.resetForm();
891 $("#SetDirModal").modal();
894 function VtoyCommonChangeLanguage(newlang
) {
895 if (newlang
=== 'en') {
896 g_vtoy_cur_language
= g_vtoy_cur_language_en
;
897 ;$.extend($.validator
.messages
, {
898 required: "This field is required",
899 remote: "Please modify this field",
900 maxlength: $.validator
.format("You can enter up to {0} characters"),
901 minlength: $.validator
.format("Must enter at least {0} characters"),
902 rangelength: $.validator
.format("Please input {0} to {1} characters"),
903 range: $.validator
.format("The input range is from {0} to {1}"),
904 max: $.validator
.format("Please input a number less than or equal to {0}"),
905 min: $.validator
.format("Please input a number bigger than or equal to {0}"),
906 utfmaxlen: $.validator
.format("The string exceeds the maximum supported length"),
907 start_slash: $.validator
.format("Must start with /"),
908 noquotes: $.validator
.format("Can not include double quotes"),
909 filenamepart:$.validator
.format("As part of file name, can not include invalid characters"),
910 printascii: $.validator
.format("Can not include non-ascii characters.")
913 $("a[id=id_a_official_doc]").each(function(){
914 var oldlink
= $(this).attr('href');
915 var newlink
= oldlink
.replace("/cn/", "/en/");
916 $(this).attr('href', newlink
);
919 $("span[id=id_span_official_doc]").each(function(){
920 $(this).text(" Plugin Official Document");
923 $('#id_span_language').text("中文");
925 $("tr[id=tr_title_desc_cn]").each(function(){
929 $("tr[id=tr_title_desc_en]").each(function(){
933 $("th[id=id_th_file_path]").each(function(){
934 $(this).text("Full File Path");
937 $("span[id=id_span_desc_cn]").each(function(){
942 g_vtoy_cur_language
= g_vtoy_cur_language_cn
;
943 ;$.extend($.validator
.messages
, {
946 maxlength: $.validator
.format("最多可以输入 {0} 个字符"),
947 minlength: $.validator
.format("最少要输入 {0} 个字符"),
948 rangelength: $.validator
.format("请输入长度在 {0} 到 {1} 之间的字符串"),
949 range: $.validator
.format("取值范围{0}到{1}"),
950 max: $.validator
.format("请输入不大于 {0} 的数值"),
951 min: $.validator
.format("请输入不小于 {0} 的数值"),
952 utfmaxlen: $.validator
.format("超过最大长度"),
953 start_slash: $.validator
.format("必须以反斜杠 / 开头"),
954 noquotes: $.validator
.format("不能包含双引号"),
955 filenamepart:$.validator
.format("作为文件名的一部分,不能包含特殊的符号"),
956 printascii: $.validator
.format("不能包含中文或其他非 ascii 字符。")
959 $("a[id=id_a_official_doc]").each(function(){
960 var oldlink
= $(this).attr('href');
961 var newlink
= oldlink
.replace("/en/", "/cn/");
962 $(this).attr('href', newlink
);
965 $("span[id=id_span_official_doc]").each(function(){
966 $(this).text(" 插件官网文档");
969 $('#id_span_language').text("English");
971 $("tr[id=tr_title_desc_cn]").each(function(){
975 $("tr[id=tr_title_desc_en]").each(function(){
979 $("th[id=id_th_file_path]").each(function(){
980 $(this).text("文件路径");
983 $("span[id=id_span_desc_cn]").each(function(){
988 $("span[id=id_span_menu_device]").text(g_vtoy_cur_language
.STR_PLUG_DEVICE
);
989 $("span[id=id_span_menu_control]").text(g_vtoy_cur_language
.STR_PLUG_CONTROL
);
990 $("span[id=id_span_menu_theme]").text(g_vtoy_cur_language
.STR_PLUG_THEME
);
991 $("span[id=id_span_menu_alias]").text(g_vtoy_cur_language
.STR_PLUG_ALIAS
);
992 $("span[id=id_span_menu_tip]").text(g_vtoy_cur_language
.STR_PLUG_TIP
);
993 $("span[id=id_span_menu_class]").text(g_vtoy_cur_language
.STR_PLUG_CLASS
);
994 $("span[id=id_span_menu_auto_install]").text(g_vtoy_cur_language
.STR_PLUG_AUTO_INSTALL
);
995 $("span[id=id_span_menu_persistence]").text(g_vtoy_cur_language
.STR_PLUG_PERSISTENCE
);
996 $("span[id=id_span_menu_injection]").text(g_vtoy_cur_language
.STR_PLUG_INJECTION
);
997 $("span[id=id_span_menu_conf_replace]").text(g_vtoy_cur_language
.STR_PLUG_CONF_REPLACE
);
998 $("span[id=id_span_menu_password]").text(g_vtoy_cur_language
.STR_PLUG_PASSWORD
);
999 $("span[id=id_span_menu_imagelist]").text(g_vtoy_cur_language
.STR_PLUG_IMAGELIST
);
1000 $("span[id=id_span_menu_auto_memdisk]").text(g_vtoy_cur_language
.STR_PLUG_AUTO_MEMDISK
);
1001 $("span[id=id_span_menu_dud]").text(g_vtoy_cur_language
.STR_PLUG_DUD
);
1002 $('#id_span_save').text(g_vtoy_cur_language
.STR_SAVE
);
1003 $('#id_span_reset').text(g_vtoy_cur_language
.STR_RESET
);
1004 $('#id_span_donation').text(g_vtoy_cur_language
.STR_PLUG_DONATION
);
1006 $("span[id=id_span_btn_add]").each(function(){
1007 $(this).text(g_vtoy_cur_language
.STR_ADD
);
1009 $("span[id=id_span_btn_del]").each(function(){
1010 $(this).text(g_vtoy_cur_language
.STR_DEL
);
1013 $("span[id=id_span_enable]").each(function(){
1014 $(this).text(g_vtoy_cur_language
.STR_ENABLE
);
1017 $("th[id=id_th_operation]").each(function(){
1018 $(this).text(g_vtoy_cur_language
.STR_OPERATION
);
1020 $("th[id=id_th_status]").each(function(){
1021 $(this).text(g_vtoy_cur_language
.STR_STATUS
);
1024 $('span [id=id_span_valid').each(function(){
1025 $(this).text(g_vtoy_cur_language
.STR_VALID
);
1027 $('span [id=id_span_invalid').each(function(){
1028 $(this).text(g_vtoy_cur_language
.STR_INVALID
);
1031 $("td[id=td_title_desc]").each(function(){
1032 $(this).text(g_vtoy_cur_language
.STR_OPT_DESC
);
1035 $("td[id=td_title_setting]").each(function(){
1036 $(this).text(g_vtoy_cur_language
.STR_OPT_SETTING
);
1041 function ventoy_get_status_line(dir
, exist
) {
1044 return '<span id="id_span_dir_nonexist" style="line-height: 1.5;" class="label pull-left bg-red">' + g_vtoy_cur_language
.STR_DIR_NONEXIST
+ '</span>';
1046 return '<span id="id_span_dir_exist" style="line-height: 1.5;" class="label pull-left bg-green">' + g_vtoy_cur_language
.STR_DIR_EXIST
+ '</span>';
1050 return '<span id="id_span_file_fuzzy" style="line-height: 1.5;" class="label pull-left bg-yellow">' + g_vtoy_cur_language
.STR_FILE_FUZZY
+ '</span>';
1051 } else if (exist
=== 1) {
1052 return '<span id="id_span_file_exist" style="line-height: 1.5;" class="label pull-left bg-green">' + g_vtoy_cur_language
.STR_FILE_EXIST
+ '</span>';
1054 return '<span id="id_span_file_nonexist" style="line-height: 1.5;" class="label pull-left bg-red">' + g_vtoy_cur_language
.STR_FILE_NONEXIST
+ '</span>';
1061 var g_type_select_callback
;
1063 var g_type_select_validator
= $("#TypeSelectForm").validate({
1064 submitHandler: function(form
) {
1065 var sel
= parseInt($('input:radio[name=name_select_type_radio]:checked').val());
1066 if (typeof(g_type_select_callback
) === 'function') {
1067 g_type_select_callback(sel
);
1070 $("#TypeSelectModal").modal('hide');
1074 function VtoySelectType(cb
, para
) {
1076 $('#TypeSelectForm #TypeSelForm_lang_1').text(g_vtoy_cur_language
.STR_SELECT
);
1078 if (g_current_language
=== 'en') {
1079 $('#TypeSelectForm #TypeSelForm_lang_2').text(" OK");
1080 $('#TypeSelectForm #TypeSelForm_lang_3').text("Cancel");
1082 $('#TypeSelectForm #TypeSelForm_lang_2').text("确定");
1083 $('#TypeSelectForm #TypeSelForm_lang_3').text("取消");
1086 var $tbl
= $("#id_type_select_table tbody");
1089 for (var i
= 0; i
< para
.length
; i
++) {
1092 if (para
[i
].selected
) {
1093 $tr
= $('<tr><td><label class="radio-inline"><input type="radio" checked="checked" name="name_select_type_radio" value="' + i
+ '"/>' + para
[i
].tip
+ '</label></td></tr>');
1095 $tr
= $('<tr><td><label class="radio-inline"><input type="radio" name="name_select_type_radio" value="' + i
+ '"/>' + para
[i
].tip
+ '</label></td></tr>');
1101 g_type_select_callback
= cb
;
1102 g_type_select_validator
.resetForm();
1103 $("#TypeSelectModal").modal();
1107 var g_set_key_callback
;
1109 var g_set_key_validator
= $("#SetKeyForm").validate({
1122 submitHandler: function(form
) {
1123 var key
= $('input:text[id=SetKeyKey]').val();
1124 var val
= $('input:text[id=SetKeyValue]').val();
1126 if ((!key
) || (!val
))
1131 if (typeof(g_set_key_callback
) === 'function') {
1132 g_set_key_callback(key
, val
);
1135 $("#SetKeyModal").modal('hide');
1139 function VtoySetKey(cb
, para
) {
1141 $('#SetKeyForm #SetKeyForm_lang_1').text(para
.title
);
1142 $('#SetKeyForm #SetKeyForm_lang_2').text(para
.title1
);
1143 $('#SetKeyForm #SetKeyForm_lang_3').text(para
.title2
);
1145 if (g_current_language
=== 'en') {
1146 $('#SetKeyForm #SetKeyForm_lang_4').text(" OK");
1147 $('#SetKeyForm #SetKeyForm_lang_5').text("Cancel");
1149 $('#SetKeyForm #SetKeyForm_lang_4').text("确定");
1150 $('#SetKeyForm #SetKeyForm_lang_5').text("取消");
1153 g_set_key_callback
= cb
;
1154 g_set_key_validator
.resetForm();
1155 $("#SetKeyModal").modal();
1158 var g_valid_color_name
= [
1177 function ventoy_check_color(color
) {
1178 if (/^#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]$/.test(color
)) {
1181 for (var i
= 0; i
< g_valid_color_name
.length
; i
++) {
1182 if (g_valid_color_name
[i
] === color
) {
1191 function ventoy_check_percent(percent
) {
1192 if (percent
.length
> 0) {
1200 function ventoy_check_file_path(isopath
, fuzzy
, cb
) {
1201 if (fuzzy
&& isopath
.indexOf("*") >= 0) {
1203 method : 'check_fuzzy',
1206 if (data
.exist
!= 0) {
1207 if (typeof(cb
) === 'function') {
1211 Message
.error(g_vtoy_cur_language
.STR_INVALID_FILE_PATH
);
1216 method : 'check_path',
1220 if (data
.exist
=== 1) {
1221 if (typeof(cb
) === 'function') {
1225 Message
.error(g_vtoy_cur_language
.STR_INVALID_FILE_PATH
);
1231 function ventoy_random_string(e
) {
1232 var t
= "abcdefhijkmnprstwxyz2345678";
1237 for (i
= 0; i
< e
; i
++) n
+= t
.charAt(Math
.floor(Math
.random() * a
));
1242 var g_set_filefile_callback
;
1244 var g_set_filefile_validator
= $("#SetFileFileForm").validate({
1256 submitHandler: function(form
) {
1257 var path1
= $('input:text[id=FileFilePath1]').val();
1258 var path2
= $('input:text[id=FileFilePath2]').val();
1260 if ((!path1
) || (!path2
))
1265 path1
= ventoy_replace_slash(path1
);
1267 if (!ventoy_common_check_path(path1
)) {
1268 Message
.error(g_vtoy_cur_language
.STR_INVALID_FILE_PATH1
);
1272 path2
= ventoy_replace_slash(path2
);
1274 if (!ventoy_common_check_path(path2
)) {
1275 Message
.error(g_vtoy_cur_language
.STR_INVALID_FILE_PATH2
);
1280 method : 'check_path2',
1287 }, function(retdata
) {
1288 if (retdata
.exist1
!= 0 && retdata
.exist2
!= 0) {
1289 if (typeof(g_set_filefile_callback
) === 'function') {
1290 g_set_filefile_callback(retdata
.exist1
, path1
, path2
);
1293 $("#SetFileFileModal").modal('hide');
1294 } else if (retdata
.exist1
=== 0) {
1295 Message
.error(g_vtoy_cur_language
.STR_INVALID_FILE_PATH1
);
1297 Message
.error(g_vtoy_cur_language
.STR_INVALID_FILE_PATH2
);
1303 function VtoySetFileFile(cb
, para
) {
1305 $('#SetFileFileForm #SetFileFileForm_title').text(para
.title
);
1306 $('#SetFileFileForm #SetFileFileForm_label1').text(para
.label1
);
1307 $('#SetFileFileForm #SetFileFileForm_label2').text(para
.label2
);
1309 if (g_current_language
=== 'en') {
1310 $('#SetFileFileForm #SetFileFileForm_ok').text(" OK");
1311 $('#SetFileFileForm #SetFileFileForm_cancel').text("Cancel");
1313 $('#SetFileFileForm #id_note_filefile_cn').hide();
1314 $('#SetFileFileForm #id_note_filefile_en').show();
1317 $('#SetFileFileForm #SetFileFileForm_ok').text("确定");
1318 $('#SetFileFileForm #SetFileFileForm_cancel').text("取消");
1320 $('#SetFileFileForm #id_note_filefile_en').hide();
1321 $('#SetFileFileForm #id_note_filefile_cn').show();
1324 $('span[id=id_span_filefile_tip1]').each(function(){
1325 $(this).text(para
.tip1
);
1327 $('span[id=id_span_filefile_tip2]').each(function(){
1328 $(this).text(para
.tip2
);
1330 $('span[id=id_span_filefile_tip3]').each(function(){
1331 $(this).text(para
.tip3
);
1334 g_set_filefile_callback
= cb
;
1335 g_set_filefile_validator
.resetForm();
1336 $("#SetFileFileModal").modal();
1340 var g_set_dirfile_callback
;
1342 var g_set_dirfile_validator
= $("#SetDirFileForm").validate({
1354 submitHandler: function(form
) {
1355 var path1
= $('input:text[id=DirFilePath1]').val();
1356 var path2
= $('input:text[id=DirFilePath2]').val();
1358 if ((!path1
) || (!path2
))
1363 path1
= ventoy_replace_slash(path1
);
1365 if (!ventoy_common_check_path(path1
)) {
1366 Message
.error(g_vtoy_cur_language
.STR_INVALID_FILE_PATH1
);
1370 path2
= ventoy_replace_slash(path2
);
1372 if (!ventoy_common_check_path(path2
)) {
1373 Message
.error(g_vtoy_cur_language
.STR_INVALID_FILE_PATH2
);
1378 method : 'check_path2',
1385 }, function(retdata
) {
1386 if (retdata
.exist1
!= 0 && retdata
.exist2
!= 0) {
1387 if (typeof(g_set_dirfile_callback
) === 'function') {
1388 g_set_dirfile_callback(path1
, path2
);
1391 $("#SetDirFileModal").modal('hide');
1392 } else if (retdata
.exist1
=== 0) {
1393 Message
.error(g_vtoy_cur_language
.STR_INVALID_DIR_PATH
);
1395 Message
.error(g_vtoy_cur_language
.STR_INVALID_FILE_PATH2
);
1401 function VtoySetDirFile(cb
, para
) {
1403 $('#SetDirFileModal #SetDirFileForm_title').text(para
.title
);
1404 $('#SetDirFileModal #SetDirFileForm_label1').text(para
.label1
);
1405 $('#SetDirFileModal #SetDirFileForm_label2').text(para
.label2
);
1407 if (g_current_language
=== 'en') {
1408 $('#SetDirFileModal #SetDirFileForm_ok').text(" OK");
1409 $('#SetDirFileModal #SetDirFileForm_cancel').text("Cancel");
1411 $('#SetDirFileModal #id_note_dirfile_cn').hide();
1412 $('#SetDirFileModal #id_note_dirfile_en').show();
1415 $('#SetDirFileModal #SetDirFileForm_ok').text("确定");
1416 $('#SetDirFileModal #SetDirFileForm_cancel').text("取消");
1418 $('#SetDirFileModal #id_note_dirfile_en').hide();
1419 $('#SetDirFileModal #id_note_dirfile_cn').show();
1422 $('span[id=id_span_dirfile_tip1]').each(function(){
1423 $(this).text(para
.tip1
);
1425 $('span[id=id_span_dirfile_tip2]').each(function(){
1426 $(this).text(para
.tip2
);
1429 g_set_dirfile_callback
= cb
;
1430 g_set_dirfile_validator
.resetForm();
1431 $("#SetDirFileModal").modal();
1434 function ventoy_get_xslg_addbtn(mclass
) {
1435 return '<button class="btn btn-xs btn-lg btn-success btn-add ' + mclass
+ '"><span class="fa fa-plus"> </span><span id="id_span_btn_add">'+g_vtoy_cur_language
.STR_ADD
+'</span></button>';
1438 function ventoy_get_xslg_delbtn(mclass
) {
1439 return '<button class="btn btn-xs btn-lg btn-danger btn-del '+mclass
+'"><span class="fa fa-trash"> </span><span id="id_span_btn_del">'+g_vtoy_cur_language
.STR_DEL
+'</span></button>';
1442 function ventoy_get_addbtn(mclass
) {
1443 return '<button class="btn btn-success btn-add ' + mclass
+ '"><span class="fa fa-plus"> </span><span id="id_span_btn_add">'+g_vtoy_cur_language
.STR_ADD
+'</span></button>';
1446 function ventoy_get_delbtn(mclass
) {
1447 return '<button class="btn btn-danger btn-del '+mclass
+'"><span class="fa fa-trash"> </span><span id="id_span_btn_del">'+g_vtoy_cur_language
.STR_DEL
+'</span></button>';
1450 function ventoy_confirm(title
, cb
, data1
, data2
) {
1451 Modal
.confirm({msg:g_vtoy_cur_language
.STR_DEL_LAST
}).on(function(e
) {
1453 if (typeof(cb
) === 'function') {