MonkeyConfig Mod

Enhanced configuration dialog builder with column layout, custom styling, and additional input types

目前为 2025-03-05 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/528923/1548139/MonkeyConfig%20Mod.js

  1. // ==UserScript==
  2. // @name MonkeyConfig Mod
  3. // @namespace http://odyniec.net/
  4. // @description Enhanced configuration dialog builder with column layout, custom styling, and additional input types
  5. // @version 1.0
  6. // ==/UserScript==
  7.  
  8. /*
  9. * MonkeyConfig Modern Reloaded Enhanced
  10. * Based on version 0.1.4 by Michal Wojciechowski (odyniec.net)
  11. * v0.1.4 - January 2020 - David Hosier (https://github.com/david-hosier/MonkeyConfig)
  12. * Enhanced by Bloggerpemula - March 2025
  13. * Additions: Column layout, font size/color customization, new input types (textarea, range, radio, file, button, group)
  14. */
  15.  
  16. function MonkeyConfig() {
  17. var cfg = this,
  18. data,
  19. params,
  20. values = {},
  21. storageKey,
  22. displayed,
  23. openWin, openLayer,
  24. container,
  25. overlay;
  26.  
  27. function init(newData) {
  28. data = newData;
  29.  
  30. if (data) {
  31. params = data.parameters || data.params;
  32. data.buttons = data.buttons === undefined ? ['save', 'defaults', 'cancel'] : data.buttons;
  33. data.fontSize = data.fontSize || '11pt'; // Default font size
  34. data.fontColor = data.fontColor || '#000000'; // Default font color
  35.  
  36. if (data.title === undefined) {
  37. if (typeof GM_getMetadata == 'function') {
  38. var scriptName = GM_getMetadata('name');
  39. data.title = scriptName + ' Configuration';
  40. } else {
  41. data.title = 'Configuration';
  42. }
  43. }
  44. }
  45.  
  46. var safeTitle = data && data.title ? data.title.replace(/[^a-zA-Z0-9]/g, '_') : '';
  47. storageKey = '_MonkeyConfig_' + safeTitle + '_cfg';
  48.  
  49. var storedValues = GM_getValue(storageKey) ? JSON.parse(GM_getValue(storageKey)) : {};
  50.  
  51. for (var name in params) {
  52. if (params[name]['value'] !== undefined) {
  53. set(name, params[name].value);
  54. } else if (storedValues[name] !== undefined) {
  55. set(name, storedValues[name]);
  56. } else if (params[name]['default'] !== undefined) {
  57. set(name, params[name]['default']);
  58. } else {
  59. set(name, '');
  60. }
  61. }
  62.  
  63. if (data.menuCommand) {
  64. var caption = data.menuCommand !== true ? data.menuCommand : data.title;
  65. GM_registerMenuCommand(caption, function () { cfg.open(); });
  66. }
  67.  
  68. cfg.open = open;
  69. cfg.close = close;
  70. cfg.get = get;
  71. cfg.set = function (name, value) { set(name, value); update(); };
  72. }
  73.  
  74. function get(name) { return values[name]; }
  75. function set(name, value) { values[name] = value; }
  76. function setDefaults() {
  77. for (var name in params) {
  78. if (typeof params[name]['default'] !== 'undefined') {
  79. set(name, params[name]['default']);
  80. }
  81. }
  82. }
  83.  
  84. function render() {
  85. var html = '<div class="__MonkeyConfig_container">' +
  86. '<h1>' + data.title + '</h1>' +
  87. '<div class="__MonkeyConfig_columns">' +
  88. '<div class="__MonkeyConfig_left_column">';
  89. // Kolom kiri
  90. for (var name in params) {
  91. if (params[name].column === 'left') {
  92. html += MonkeyConfig.formatters['tr'](name, params[name]);
  93. }
  94. }
  95. html += '</div><div class="__MonkeyConfig_right_column">';
  96.  
  97. // Kolom kanan
  98. for (var name in params) {
  99. if (params[name].column === 'right') {
  100. html += MonkeyConfig.formatters['tr'](name, params[name]);
  101. }
  102. }
  103. html += '</div></div><table class="__MonkeyConfig_default">';
  104.  
  105. // Elemen tanpa kolom (default)
  106. for (var name in params) {
  107. if (!params[name].column) {
  108. html += MonkeyConfig.formatters['tr'](name, params[name]);
  109. }
  110. }
  111.  
  112. html += '<tr><td colspan="2" class="__MonkeyConfig_buttons">' +
  113. '<table><tr>';
  114.  
  115. for (var button in data.buttons) {
  116. html += '<td>';
  117. switch (data.buttons[button]) {
  118. case 'cancel':
  119. html += '<button type="button" id="__MonkeyConfig_button_cancel">' +
  120. '<img src="data:image/png;base64,' + MonkeyConfig.res.icons.cancel + '" />&nbsp;Cancel</button>';
  121. break;
  122. case 'defaults':
  123. html += '<button type="button" id="__MonkeyConfig_button_defaults">' +
  124. '<img src="data:image/png;base64,' + MonkeyConfig.res.icons.arrow_undo + '" />&nbsp;Set&nbsp;Defaults</button>';
  125. break;
  126. case 'save':
  127. html += '<button type="button" id="__MonkeyConfig_button_save">' +
  128. '<img src="data:image/png;base64,' + MonkeyConfig.res.icons.tick + '" />&nbsp;Save</button>';
  129. break;
  130. }
  131. html += '</td>';
  132. }
  133.  
  134. html += '</tr></table></td></tr></table></div>';
  135. return html;
  136. }
  137.  
  138. function update() {
  139. if (!displayed) return;
  140.  
  141. for (var name in params) {
  142. var value = values[name];
  143. var elem = container.querySelector('[name="' + name + '"]');
  144. switch (params[name].type) {
  145. case 'checkbox':
  146. elem.checked = !!value;
  147. break;
  148. case 'custom':
  149. params[name].set(value, container.querySelector('#__MonkeyConfig_parent_' + name));
  150. break;
  151. case 'number':
  152. case 'text':
  153. case 'color':
  154. case 'textarea':
  155. case 'range':
  156. elem.value = value;
  157. break;
  158. case 'radio':
  159. elem = container.querySelector('[name="' + name + '"][value="' + value + '"]');
  160. if (elem) elem.checked = true;
  161. break;
  162. case 'file':
  163. elem.value = ''; // File input tidak bisa di-set langsung
  164. break;
  165. case 'select':
  166. if (elem.tagName.toLowerCase() == 'input' && elem.type == 'checkbox') {
  167. var checkboxes = container.querySelectorAll('input[name="' + name + '"]');
  168. for (var i = 0; i < checkboxes.length; i++) {
  169. checkboxes[i].checked = value.indexOf(checkboxes[i].value) > -1;
  170. }
  171. } else if (elem.multiple) {
  172. var options = container.querySelectorAll('select[name="' + name + '"] option');
  173. for (var i = 0; i < options.length; i++) {
  174. options[i].selected = value.indexOf(options[i].value) > -1;
  175. }
  176. } else {
  177. elem.value = value;
  178. }
  179. break;
  180. }
  181. }
  182. }
  183.  
  184. function saveClick() {
  185. for (var name in params) {
  186. var elem = container.querySelector('[name="' + name + '"]');
  187. switch (params[name].type) {
  188. case 'checkbox':
  189. values[name] = elem.checked;
  190. break;
  191. case 'custom':
  192. values[name] = params[name].get(container.querySelector('#__MonkeyConfig_parent_' + name));
  193. break;
  194. case 'number':
  195. case 'text':
  196. case 'color':
  197. case 'textarea':
  198. case 'range':
  199. values[name] = elem.value;
  200. break;
  201. case 'radio':
  202. values[name] = container.querySelector('[name="' + name + '"]:checked')?.value || '';
  203. break;
  204. case 'file':
  205. values[name] = elem.dataset.value || values[name]; // Simpan nilai dari file yang diunggah
  206. break;
  207. case 'select':
  208. if (elem.tagName.toLowerCase() == 'input' && elem.type == 'checkbox') {
  209. values[name] = [];
  210. var inputs = container.querySelectorAll('input[name="' + name + '"]');
  211. for (var i = 0; i < inputs.length; i++) {
  212. if (inputs[i].checked) values[name].push(inputs[i].value);
  213. }
  214. } else if (elem.multiple) {
  215. values[name] = [];
  216. var options = container.querySelectorAll('select[name="' + name + '"] option');
  217. for (var i = 0; i < options.length; i++) {
  218. if (options[i].selected) values[name].push(options[i].value);
  219. }
  220. } else {
  221. values[name] = elem.value;
  222. }
  223. break;
  224. }
  225. }
  226.  
  227. GM_setValue(storageKey, JSON.stringify(values));
  228. close();
  229. if (data.onSave) data.onSave(values);
  230. location.reload();
  231. }
  232.  
  233. function cancelClick() { close(); }
  234. function defaultsClick() { setDefaults(); update(); }
  235.  
  236. function open(mode, options) {
  237. function openDone() {
  238. var button;
  239. if (button = container.querySelector('#__MonkeyConfig_button_save')) button.addEventListener('click', saveClick, true);
  240. if (button = container.querySelector('#__MonkeyConfig_button_cancel')) button.addEventListener('click', cancelClick, true);
  241. if (button = container.querySelector('#__MonkeyConfig_button_defaults')) button.addEventListener('click', defaultsClick, true);
  242. displayed = true;
  243. update();
  244. }
  245.  
  246. GM_addStyle(MonkeyConfig.res.stylesheets.main.replace(/__FONT_SIZE__/g, data.fontSize).replace(/__FONT_COLOR__/g, data.fontColor));
  247. MonkeyConfig.styleAdded = true;
  248.  
  249. switch (mode) {
  250. case 'window':
  251. var win = window.open('', data.title, 'location=no,status=no');
  252. win.document.head.innerHTML = '<title>' + data.title + '</title><style>' + MonkeyConfig.res.stylesheets.main + '</style>';
  253. win.document.body.className = '__MonkeyConfig_window';
  254. win.document.body.innerHTML = render();
  255. container = win.document.querySelector('.__MonkeyConfig_container');
  256. win.innerWidth = container.clientWidth;
  257. win.resizeBy(0, -win.innerHeight + container.clientHeight);
  258. win.moveBy(Math.round((window.outerWidth - win.outerWidth) / 2), Math.round((window.outerHeight - win.outerHeight) / 2));
  259. openWin = win;
  260. openDone();
  261. break;
  262. case 'layer':
  263. case 'iframe':
  264. default:
  265. var body = document.querySelector('body');
  266. openLayer = document.createElement('div');
  267. openLayer.className = '__MonkeyConfig_layer';
  268. overlay = document.createElement('div');
  269. overlay.className = '__MonkeyConfig_overlay';
  270. overlay.style.cssText = 'left:0;top:0;width:' + window.innerWidth + 'px;height:' + window.innerHeight + 'px;z-index:9999;';
  271. openLayer.innerHTML = render();
  272. openLayer.style.cssText = 'left:' + Math.round((window.innerWidth - openLayer.clientWidth) / 2) + 'px;top:' + Math.round((window.innerHeight - openLayer.clientHeight) / 2) + 'px;z-index:9999;';
  273. body.appendChild(overlay);
  274. body.appendChild(openLayer);
  275. container = document.querySelector('.__MonkeyConfig_container');
  276. openDone();
  277. break;
  278. }
  279. }
  280.  
  281. function close() {
  282. if (openWin) { openWin.close(); openWin = undefined; }
  283. if (openLayer) { openLayer.parentNode.removeChild(openLayer); openLayer = undefined; }
  284. if (overlay) { overlay.parentNode.removeChild(overlay); overlay = undefined; }
  285. displayed = false;
  286. }
  287.  
  288. init(arguments[0]);
  289. }
  290.  
  291. MonkeyConfig.esc = function (string) { return string.replace(/"/g, '&quot;'); };
  292.  
  293. MonkeyConfig.HTML = {
  294. '_field': function (name, options, data) {
  295. return options.type && MonkeyConfig.HTML[options.type] ? options.html ? options.html.replace(/\[FIELD\]/, MonkeyConfig.HTML[options.type](name, options, data)) : MonkeyConfig.HTML[options.type](name, options, data) : '';
  296. },
  297. '_label': function (name, options, data) {
  298. var label = options['label'] || name.substring(0, 1).toUpperCase() + name.substring(1).replace(/_/g, '&nbsp;');
  299. return '<label for="__MonkeyConfig_field_' + name + '">' + label + '</label>';
  300. },
  301. 'checkbox': function (name, options) { return '<input id="__MonkeyConfig_field_' + name + '" type="checkbox" name="' + name + '" />'; },
  302. 'custom': function (name, options) { return options.html || ''; },
  303. 'number': function (name, options) { return '<input id="__MonkeyConfig_field_' + name + '" type="number" class="__MonkeyConfig_field_number" name="' + name + '" min="' + (options.min || '') + '" max="' + (options.max || '') + '" step="' + (options.step || '1') + '" />'; },
  304. 'text': function (name, options) { return '<input id="__MonkeyConfig_field_' + name + '" type="text" class="__MonkeyConfig_field_text" name="' + name + '" />'; },
  305. 'color': function (name, options) { return '<input id="__MonkeyConfig_field_' + name + '" type="color" class="__MonkeyConfig_field_text" name="' + name + '" />'; },
  306. 'textarea': function (name, options) { return '<textarea id="__MonkeyConfig_field_' + name + '" class="__MonkeyConfig_field_text" name="' + name + '" rows="' + (options.rows || 4) + '" cols="' + (options.cols || 20) + '"></textarea>'; },
  307. 'range': function (name, options) { return '<input id="__MonkeyConfig_field_' + name + '" type="range" name="' + name + '" min="' + (options.min || 0) + '" max="' + (options.max || 100) + '" step="' + (options.step || 1) + '" />'; },
  308. 'radio': function (name, options) {
  309. var html = '';
  310. for (var value in options.choices) {
  311. html += '<label><input type="radio" name="' + name + '" value="' + MonkeyConfig.esc(value) + '" /> ' + options.choices[value] + '</label><br/>';
  312. }
  313. return html;
  314. },
  315. 'file': function (name, options) { return '<input id="__MonkeyConfig_field_' + name + '" type="file" name="' + name + '" accept="' + (options.accept || '*/*') + '" />'; },
  316. 'button': function (name, options) { return '<button type="button" id="__MonkeyConfig_field_' + name + '" name="' + name + '">' + (options.label || 'Click') + '</button>'; },
  317. 'group': function (name, options) {
  318. var html = '<fieldset><legend>' + (options.label || name) + '</legend>';
  319. for (var subName in options.params) {
  320. html += MonkeyConfig.formatters['tr'](subName, options.params[subName]);
  321. }
  322. html += '</fieldset>';
  323. return html;
  324. },
  325. 'select': function (name, options) {
  326. var choices = options.choices.constructor == Array ? options.choices.reduce((obj, val) => { obj[val] = val; return obj; }, {}) : options.choices;
  327. var html = '<select id="__MonkeyConfig_field_' + name + '" class="__MonkeyConfig_field_select" name="' + name + '"' + (options.multiple ? ' multiple="multiple"' : '') + '>';
  328. for (var value in choices) {
  329. html += '<option value="' + MonkeyConfig.esc(value) + '">' + choices[value] + '</option>';
  330. }
  331. html += '</select>';
  332. return html;
  333. }
  334. };
  335.  
  336. MonkeyConfig.formatters = {
  337. 'tr': function (name, options, data) {
  338. var html = '<tr>';
  339. if (options.type === 'checkbox') {
  340. html += '<td id="__MonkeyConfig_parent_' + name + '" colspan="2">' + MonkeyConfig.HTML['_field'](name, options, data) + ' ' + MonkeyConfig.HTML['_label'](name, options, data) + '</td>';
  341. } else if (options.type === 'group') {
  342. html += '<td colspan="2">' + MonkeyConfig.HTML['_field'](name, options, data) + '</td>';
  343. } else {
  344. html += '<td>' + MonkeyConfig.HTML['_label'](name, options, data) + '</td><td id="__MonkeyConfig_parent_' + name + '">' + MonkeyConfig.HTML['_field'](name, options, data) + '</td>';
  345. }
  346. html += '</tr>';
  347. return html;
  348. }
  349. };
  350.  
  351. MonkeyConfig.styleAdded = false;
  352.  
  353. MonkeyConfig.res = {
  354. icons: {
  355. 'arrow_undo': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIJSURBVDjLpVM9aJNRFD35GsRSoUKKzQ/B0NJJF3EQlKrVgijSCBmC4NBFKihIcXBwEZdSHVoUwUInFUEkQ1DQ4CKiFsQsTrb5xNpgaZHw2Uog5t5zn0NJNFaw0guX97hwzuPcc17IOYfNlIdNVrhxufR6xJkZjAbSQGXjNAorqixSWFDV3KPhJ+UGLtSQMPryrDscPwLnAHOEOQc6gkbUpIagGmApWIb/pZRX4fjj889nWiSQtgYyBZ1BTUEj6AjPa0P71nb0Jfqwa+futIheHrzRn2yRQCUK/lOQhApBJVQJChHfnkCqOwWEQ+iORJHckUyX5ksvAEyGNuJC+s6xCRXNHNxzKMmQ4luwgjfvZp69uvr2+IZcyJ8rjIporrxURggetnV0QET3rrPxzMNM2+n7p678jUTrCiWhphAjVHR9DlR0WkSzf4IHxg5MSF0zXZEuVKWKSlCBCostS8zeG7oV64wPqxInbw86lbVXKEQ8mkAqmUJ4SxieeVhcnANFC02C7N2h69HO2IXeWC8MDj2JnqaFNAMd8f3HKjx6+LxQRmnOz1OZaxKIaF1VISYwB9ARZoQaYY6o1WpYCVYxt+zDn/XzVBv/MOWXW5J44ubRyVgkelFpmF/4BJVfOVDlVyqLVBZI5manPjajDOdcswfG9k/3X9v3/vfZv7rFBanriIo++J/f+BMT+YWS6hXl7QAAAABJRU5ErkJggg==',
  356. 'cancel': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHdSURBVDjLpZNraxpBFIb3a0ggISmmNISWXmOboKihxpgUNGWNSpvaS6RpKL3Ry//Mh1wgf6PElaCyzq67O09nVjdVlJbSDy8Lw77PmfecMwZg/I/GDw3DCo8HCkZl/RlgGA0e3Yfv7+DbAfLrW+SXOvLTG+SHV/gPbuMZRnsyIDL/OASziMxkkKkUQTJJsLaGn8/iHz6nd+8mQv87Ahg2H9Th/BxZqxEkEgSrq/iVCvLsDK9awtvfxb2zjD2ARID+lVVlabTgWYTv1rFL5fBUtHbbeTJCb3EQ3ovCnRC6xAgzJtOE+ztheYIEkqbFaS3vY2zuIj77AmtYYDusPy8/zuvunJkDKXM7tYWTiyGWFjAqeQnAD6+7ueNx/FLpRGAru7mcoj5ebqzszil7DggeF/DX1BN82rzPqrzbRayIsLhJqMPT2N83Sdy2GApwFqRN7jFPL0tF+10cDd3MTZ2AjNUkGCoyO6y9cRxfQowFUbpufr1ct4ZoHg+Dg067zduTmEbq4yi/UkYidDe+kaTcP4ObJIajksPd/eyx3c+N2rvPbMDPbUFPZSLKzcGjKPrbJaDsu+dQO3msfZzeGY2TCvKGYQhdSYeeJjUt21dIcjXQ7U7Kv599f4j/oF55W4g/2e3b8AAAAASUVORK5CYII=',
  357. 'tick': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGrSURBVDjLvZPZLkNhFIV75zjvYm7VGFNCqoZUJ+roKUUpjRuqp61Wq0NKDMelGGqOxBSUIBKXWtWGZxAvobr8lWjChRgSF//dv9be+9trCwAI/vIE/26gXmviW5bqnb8yUK028qZjPfoPWEj4Ku5HBspgAz941IXZeze8N1bottSo8BTZviVWrEh546EO03EXpuJOdG63otJbjBKHkEp/Ml6yNYYzpuezWL4s5VMtT8acCMQcb5XL3eJE8VgBlR7BeMGW9Z4yT9y1CeyucuhdTGDxfftaBO7G4L+zg91UocxVmCiy51NpiP3n2treUPujL8xhOjYOzZYsQWANyRYlU4Y9Br6oHd5bDh0bCpSOixJiWx71YY09J5pM/WEbzFcDmHvwwBu2wnikg+lEj4mwBe5bC5h1OUqcwpdC60dxegRmR06TyjCF9G9z+qM2uCJmuMJmaNZaUrCSIi6X+jJIBBYtW5Cge7cd7sgoHDfDaAvKQGAlRZYc6ltJlMxX03UzlaRlBdQrzSCwksLRbOpHUSb7pcsnxCCwngvM2Rm/ugUCi84fycr4l2t8Bb6iqTxSCgNIAAAAAElFTkSuQmCC'
  358. },
  359. stylesheets: {
  360. 'main': '\
  361. body.__MonkeyConfig_window { appearance: window !important; -moz-appearance: window !important; background: auto; font-family: sans-serif !important; height: 100% !important; margin: 0 !important; padding: 0 !important; width: 100% !important; }\
  362. div.__MonkeyConfig_container { display: table !important; font-family: sans-serif !important; padding: 0.3em !important; font-size: __FONT_SIZE__ !important; color: __FONT_COLOR__ !important; }\
  363. body.__MonkeyConfig_window div.__MonkeyConfig_container { appearance: window !important; -moz-appearance: window !important; height: 100%; width: 100%; }\
  364. div.__MonkeyConfig_container h1 { border-bottom: solid 1px #999 !important; font-family: sans-serif !important; font-size: 120% !important; margin: 0 !important; padding: 0 0 0.3em 0 !important; }\
  365. div.__MonkeyConfig_columns { display: flex !important; justify-content: space-between !important; margin-bottom: 1em !important; }\
  366. div.__MonkeyConfig_left_column, div.__MonkeyConfig_right_column { width: 48% !important; }\
  367. div.__MonkeyConfig_container table { border-spacing: 0 !important; margin: 0 !important; width: 100% !important; }\
  368. div.__MonkeyConfig_container table td { border: none !important; line-height: 100% !important; padding: 0.3em !important; text-align: left !important; vertical-align: top !important; white-space: nowrap !important; }\
  369. div.__MonkeyConfig_container table td.__MonkeyConfig_buttons { padding: 0.2em 0 !important; }\
  370. .__MonkeyConfig_field_number { width: 5em !important; }\
  371. div.__MonkeyConfig_container td.__MonkeyConfig_buttons table { border-top: solid 1px #999 !important; width: 100% !important; }\
  372. div.__MonkeyConfig_container td.__MonkeyConfig_buttons td { padding: 0.6em 0.3em 0.1em 0.3em !important; text-align: center !important; vertical-align: top; }\
  373. div.__MonkeyConfig_container td.__MonkeyConfig_buttons button { appearance: button !important; -moz-appearance: button !important; background-position: 8px 50% !important; background-repeat: no-repeat !important; padding: 3px 8px 3px 24px !important; white-space: nowrap !important; }\
  374. div.__MonkeyConfig_container td.__MonkeyConfig_buttons button img { vertical-align: middle !important; }\
  375. div.__MonkeyConfig_layer { display: table !important; position: fixed !important; }\
  376. div.__MonkeyConfig_layer div.__MonkeyConfig_container, body.__MonkeyConfig_body > div.__MonkeyConfig_container { background: #eee linear-gradient(180deg, #f8f8f8 0, #ddd 100%) !important; border-radius: 0.5em !important; box-shadow: 2px 2px 16px #000 !important; color: __FONT_COLOR__ !important; font-family: sans-serif !important; font-size: __FONT_SIZE__ !important; padding: 1em 1em 0.4em 1em !important; }\
  377. div.__MonkeyConfig_layer div.__MonkeyConfig_container td, div.__MonkeyConfig_layer div.__MonkeyConfig_container label, div.__MonkeyConfig_layer div.__MonkeyConfig_container input, div.__MonkeyConfig_layer div.__MonkeyConfig_container select, div.__MonkeyConfig_layer div.__MonkeyConfig_container textarea, div.__MonkeyConfig_layer div.__MonkeyConfig_container button { color: __FONT_COLOR__ !important; font-family: sans-serif !important; font-size: __FONT_SIZE__ !important; line-height: 100% !important; margin: 0 !important; vertical-align: baseline !important; }\
  378. div.__MonkeyConfig_container label { line-height: 120% !important; vertical-align: baseline !important; }\
  379. div.__MonkeyConfig_container textarea { vertical-align: text-top !important; width: 100%; }\
  380. div.__MonkeyConfig_layer div.__MonkeyConfig_container input[type="text"] { appearance: textfield !important; -moz-appearance: textfield !important; background: #fff !important; }\
  381. div.__MonkeyConfig_layer div.__MonkeyConfig_container h1 { font-weight: bold !important; text-align: left !important; }\
  382. div.__MonkeyConfig_layer div.__MonkeyConfig_container td.__MonkeyConfig_buttons button, body > div.__MonkeyConfig_container td.__MonkeyConfig_buttons button { appearance: button !important; -moz-appearance: button !important; background: #ccc linear-gradient(180deg, #ddd 0, #ccc 45%, #bbb 50%, #aaa 100%) !important; border-style: solid !important; border-width: 1px !important; border-radius: 0.5em !important; box-shadow: 0 0 1px #000 !important; color: __FONT_COLOR__ !important; font-size: __FONT_SIZE__ !important; }\
  383. div.__MonkeyConfig_layer div.__MonkeyConfig_container td.__MonkeyConfig_buttons button:hover, body > div.__MonkeyConfig_container td.__MonkeyConfig_buttons button:hover { background: #d2d2d2 linear-gradient(180deg, #e2e2e2 0, #d2d2d2 45%, #c2c2c2 50%, #b2b2b2 100%) !important; }\
  384. div.__MonkeyConfig_overlay { background-color: #000 !important; opacity: 0.6 !important; position: fixed !important; }\
  385. iframe#__MonkeyConfig_frame { border: none !important; box-shadow: 2px 2px 16px #000 !important; }\
  386. body.__MonkeyConfig_body { margin: 0 !important; padding: 0 !important; }\
  387. '
  388. }
  389. };