Bug fixes and mac image hiding compatibility
[4Free-FSE.git] / builds / 4-Free.user.js
blobe60014c87dc85bf072ae9e64002f3a3fe16dc3c5
1 var __extends = (this && this.__extends) || (function () {
2     var extendStatics = Object.setPrototypeOf ||
3         ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
4         function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
5     return function (d, b) {
6         extendStatics(d, b);
7         function __() { this.constructor = d; }
8         d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
9     };
10 })();
11 // ==UserScript==
12 // @name         4Free-FSE [4chan X Enhancement]
13 // @author       ECHibiki - /qa/
14 // @description  4Free - Free Stuff Enhancments. 7 additional features on top of 4chanX
15 // @version      1.3.8
16 // @namespace    http://verniy.xyz/
17 // @match                *://boards.4chan.org/*
18 // @updateURL    https://raw.githubusercontent.com/ECHibiki/4Free-FSE/master/builds/4-Free.user.js
19 // @downloadURL  https://raw.githubusercontent.com/ECHibiki/4Free-FSE/master/builds/4-Free.user.js
20 // @grant         GM_xmlhttpRequest
21 // @run-at document-start
22 // @icon  data:image/jpeg;base64,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
23 // ==/UserScript==
25 Uses:
26         https://github.com/ccd0/4chan-x/wiki/4chan-X-API
27         https://github.com/ECHibiki/4chan-UserScripts/blob/master/MD5%20Filters%20by%20QAJPYOtGo.txt
30     ## About 4chanX-FSE
31     4chanX-Free Stuff Enhancements is a userscript that operates with 4chanX to give it additional features. These enhancements were written by me from early 2017 up to 2018 as a way to teach myself how to work with JavaScript while giving something back to the community I took part in.
32     Some of these features are simple, like the password viewer, others are more complex using multiple concurent AJAX calls such as the thread rebuilder or the image adder. <br/>
33     Below is a description of the features this package has to offer.
35     ### Danbooru Image Adder
36     #### Adds images to your posts
37     Adds an image to your post taken from the danbooru's image collection.<br/>
38     Supply it with tags via an autocomplete, set the rating(s/q/e) and it will give an image for you to post with.
40     ### Kita-Yen
41     #### Color text
42     Converts the colors of special symbols from plain black into other prettier colors(yen == purple, kita == dark grey).<br/>
43     #### Hotkeys for Convinience
44     <strong>Press ctrl+\ for ¥</strong>
45     Highlights the whole line in purple much like how greentext works<br/>
46     <strong>Press ctrl+k for キタ━━━(゚∀゚)━━━!!</strong>
47     Highlights just the word in dark gray<br/>
49     ### 4chan-Ignoring-Enhancements
50     #### Hides images.
51     Gives the ability to hide images with ___ctrl+shift+click___. Stores in browser memory for new sessions.<br/>
52     Also includes over 20,000 MD5 filters of things like frogs, goldface, guro done by from QAJPYOtGo<br/>
53     https://github.com/ECHibiki/4chan-UserScripts/blob/master/MD5%20Filters%20by%20QAJPYOtGo.txt
54     #### Word Filters
55     Also includes the ability to do word replacements with a regex replacement system.<br>
57     ### Thread Rebuilder
58     #### Rebuild dead threads from scratch
59     Rebuild a thread from 4chan's archive.<br/>
60     Simple system that could use some additions(using 4chan's offsite archives for example)
62     ### Visible Password
63     #### Shows your 4chan post/delete password
64     * Displays your 4chan password in an inputbox.
65     * Top left is the post password, Bottom right is the delete password.
66     * Edit the input boxes to change them.
68     __Note:__ some 4chan boards don't allow custom post passwords. May require cookie manipulation, but this has not yet been tested...
71 var Constants = /** @class */ (function () {
72     function Constants() {
73     }
74     Constants.DEFAULT_HIDE_EXPIRATION_TIME = 172800000;
75     Constants.MILLISECONDS_TO_THE_HOUR = 3600000;
76     Constants.HELP_ICON_SOURCE = "data:image/jpeg;base64,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";
77     return Constants;
78 }());
79 //unassociated functions
80 var Generics = /** @class */ (function () {
81     function Generics() {
82     }
83     Generics.storageAvailable = function (storage_type) {
84         try {
85             var storage = window[storage_type];
86             storage.setItem('x', 'x');
87             storage.removeItem('x');
88             return 1;
89         }
90         catch (e) {
91             return e;
92         }
93     };
94     //What Browser
95     Generics.detectBrowser = function () {
96         if ((navigator.userAgent.indexOf('Opera') || navigator.userAgent.indexOf('OPR')) != -1) {
97             console.log('Opera');
98             return 0;
99         }
100         else if (navigator.userAgent.indexOf('Chrome') != -1) {
101             console.log('Chrome');
102             return 1;
103         }
104         else if (navigator.userAgent.indexOf('Safari') != -1) {
105             console.log('Safari');
106             return 2;
107         }
108         else if (navigator.userAgent.indexOf('Firefox') != -1) {
109             console.log('FireFox');
110             return 3;
111         }
112         else if (navigator.userAgent.indexOf('MSIE') != -1) {
113             console.log('IE');
114             return 4;
115         }
116         else {
117             console.log('Other');
118             return -1;
119         }
120     };
121     //gets json keys by regex test
122     Generics.getJSONPropertiesByKeyName = function (JSON_obj, regex_string) {
123         var regex = new RegExp("^" + regex_string + "$");
124         var rtnArray = Array();
125         for (var key in JSON_obj)
126             if (regex.test(key))
127                 rtnArray.push(key);
128         return rtnArray;
129     };
130     //send alert to 4chanx
131     Generics.alert4ChanX = function (message, type, time) {
132         var detail = { type: type, content: message, lifetime: time };
133         var event = new CustomEvent('CreateNotification', { bubbles: true, detail: detail });
134         document.dispatchEvent(event);
135     };
136     Generics.getJSON = function (url, callback, extra) {
137         var all_extra = [];
138         for (var _i = 3; _i < arguments.length; _i++) {
139             all_extra[_i - 3] = arguments[_i];
140         }
141         var xhr = new XMLHttpRequest();
142         xhr.open('GET', url, true);
143         xhr.responseType = 'json';
144         xhr.onload = function () {
145             var status = xhr.status;
146             if (status == 200) {
147                 callback.apply(void 0, [null, xhr.response, extra].concat(all_extra));
148             }
149             else {
150                 callback(status);
151             }
152         };
153         xhr.send();
154     };
155     return Generics;
156 }());
157 var FeatureInterface = /** @class */ (function () {
158     function FeatureInterface() {
159     }
160     return FeatureInterface;
161 }());
162 var TopBar = /** @class */ (function () {
163     function TopBar() {
164         this.shortcuts_container = document.getElementById("shortcuts");
165         this.shortcuts_menu = document.getElementById("shortcut-menu");
166         this.fse_icon_container = document.createElement("SPAN");
167         this.fse_icon_node = document.createElement("A");
168         this.fse_style_node = document.createElement("STYLE");
169         this.fa_fse_style = ".fa_jpy::before{content:'\f157'}";
170         this.fse_style_node.innerHTML = this.fa_fse_style;
171         this.fse_icon_container.setAttribute("class", "shortcut brackets-wrap");
172         this.fse_icon_node.setAttribute("class", "fa fa-jpy");
173         this.fse_icon_node.setAttribute("href", "javascript:void(0);");
174         this.fse_icon_node.setAttribute("title", "4F-FSE Settings");
175         this.fse_icon_node.textContent = "4F-FSE Settings";
176         this.settings_window = new SettingsWindow();
177     }
178     TopBar.prototype.build = function () {
179         var _this = this;
180         document.head.appendChild(this.fse_style_node);
181         this.fse_icon_container.appendChild(this.fse_icon_node);
182         this.shortcuts_container.insertBefore(this.fse_icon_container, this.shortcuts_menu);
183         //https://stackoverflow.com/questions/44606399/typescript-how-to-access-the-class-instance-from-event-handler-method
184         this.fse_icon_node.addEventListener("click", function (evt) { return _this.open4FSettings(_this.settings_window); });
185     };
186     TopBar.prototype.open4FSettings = function (settings_window) {
187         settings_window.displayWindow();
188     };
189     TopBar.prototype.getSettingsArr = function () {
190         return this.settings_window.getSettingsArr();
191     };
192     return TopBar;
193 }());
194 var ImageHider = /** @class */ (function (_super) {
195     __extends(ImageHider, _super);
196     function ImageHider() {
197         var _this = _super.call(this) || this;
198         _this.blank_png = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAACXBIWXMAALiMAAC4jAHM9rsvAAAAG3RFWHRTb2Z0d2FyZQBDZWxzeXMgU3R1ZGlvIFRvb2zBp+F8AAAAo0lEQVR42u3RAQ0AAAjDMO5f9LFBSCdhTdvRnQIEiIAAERAgAgJEQIC4AERAgAgIEAEBIiBABERAgAgIEAEBIiBABERAgAgIEAEBIiBABERAgAgIEAEBIiBABERAgAgIEAEBIiBABERAgAgIEAEBIiBABERAgAgIEAEBIiBABERAgAgIEAEBIiBABERAgAgIEAEBIiBABAQIECACAkRAgAjI9xbzUCtI4axs4wAAAABJRU5ErkJggg==";
199         _this.listener_obj = {};
200         _this.retrieveStates();
201         _this.init();
202         _this.activate();
203         return _this;
204     }
205     //retrieve from memory the hidden images
206     //Images are stored in memory as f<ID_NUMBER>IMG and recalled using the storage_key
207     //Function makes a check to see if the hiding time limit for the thread has expired or not.
208     //Note: Must have the DOM itterate through before retrieval
209     ImageHider.prototype.retrieveStates = function () {
210         var _this = this;
211         var storage_position = 0;
212         var JSON_storage = {}; /*;any bypasses dot notation issues on objects*/
213         var storage_key;
214         var local_store_size = window.localStorage.length;
215         while (storage_position < local_store_size) {
216             storage_key = window.localStorage.key(storage_position);
217             JSON_storage[storage_key] = window.localStorage.getItem(storage_key);
218             storage_position++;
219         }
220         this.threads_to_hide = Generics.getJSONPropertiesByKeyName(JSON_storage, '[0-9]+IMG');
221         //aquire each time to check for changes
222         this.hide_expiration_time = parseInt(JSON_storage.Expiration_Time);
223         if (this.hide_expiration_time === null)
224             this.hide_expiration_time = Constants.DEFAULT_HIDE_EXPIRATION_TIME;
225         var md5_filters = JSON_storage.MD5_List_FSE;
226         if (md5_filters !== undefined && md5_filters !== null) {
227             this.md5_filters_arr = md5_filters.split('\n');
228             //remove trailing and starting slash
229             this.md5_filters_arr.forEach(function (md5, index) {
230                 md5 = md5.trim();
231                 _this.md5_filters_arr[index] = md5.substring(1, md5.length - 1);
232             });
233         }
234     };
235     ImageHider.prototype.storeStates = function () {
236         var item_pairs = [];
237         for (var _i = 0; _i < arguments.length; _i++) {
238             item_pairs[_i] = arguments[_i];
239         }
240         window.localStorage.setItem(item_pairs[0], item_pairs[1]);
241     };
242     ImageHider.prototype.init = function () {
243         this.hotkeyListeners();
244     };
245     //hide image onclick listener.
246     //Method 404's a given image. This 404'ing allows image dissabling to be toggled on and off.
247     //Post number associated with the image is stored in local storage.
248     ImageHider.prototype.hideOnClick = function (event) {
249         var _this = this;
250         var is_hidden = event.target.src.substring(21, 29) == ",iVBORw0";
251         var hide_group_id;
252         if ((this.listener_obj[17] && this.listener_obj[16]) && !is_hidden) {
253             event.preventDefault();
254             event.stopPropagation();
255             hide_group_id = event.target.getAttribute('hide-grouping');
256             this.storeStates(hide_group_id, "" + Date.now());
257             [].slice.call(document.querySelectorAll('img[hide-grouping="' + hide_group_id + '"]')).forEach(function (image_node) {
258                 image_node.setAttribute('hidden-src', image_node.src);
259                 image_node.src = _this.blank_png;
260             });
261         }
262         else if (this.listener_obj[17] && this.listener_obj[16]) {
263             event.preventDefault();
264             event.stopPropagation();
265             hide_group_id = event.target.getAttribute('hide-grouping');
266             window.localStorage.removeItem(hide_group_id);
267             event.target.src = event.target.getAttribute('hidden-src');
268             [].slice.call(document.querySelectorAll('img[hide-grouping="' + hide_group_id + '"]')).forEach(function (image_node) {
269                 image_node.src = image_node.getAttribute('hidden-src');
270             });
271         }
272         this.retrieveStates();
273         return true;
274     };
275     //hotkeys for ctrl[17] and shift[16]
276     ImageHider.prototype.hotkeyListeners = function () {
277         var _this = this;
278         window.addEventListener("keydown", function (e) {
279             _this.listener_obj[e.keyCode] = true;
280         }, { passive: false, capture: false, once: false });
281         window.addEventListener("keyup", function (e) {
282             _this.listener_obj[e.keyCode] = false;
283         }, { passive: false, capture: false, once: false });
284     };
285     ImageHider.prototype.decideAction = function (node) {
286         //tagname is always upper in HTML, in xml it's displayed as written.
287         if (node.tagName === 'IMG' || node.tagName === 'VIDEO') {
288             if (node.id === "ihover") {
289                 this.hideHoverImageNode(node);
290                 return;
291             }
292             if (node.getAttribute('data-md5') !== null) {
293                 this.hideImageNode(node);
294             }
295         }
296     };
297     //Activate
298     ImageHider.prototype.activate = function () {
299         console.log("4F-FSE: ImageHider Active");
300     };
301     ImageHider.prototype.hideImageNode = function (image_node) {
302         var _this = this;
303         var sister_node = image_node.parentNode.parentNode.parentNode.getElementsByClassName('catalog-thumb')[0]; // the catalog sister to index
304         var sister_node_non_exist = false;
305         if (sister_node === undefined) {
306             sister_node_non_exist = true;
307         }
308         var image_node_already_run = false;
309         if (/\d+IMG/.test(image_node.getAttribute('hide-grouping'))) {
310             image_node_already_run = true;
311             if (!sister_node_non_exist) {
312                 if (/\d+IMG/.test(sister_node.getAttribute('hide-grouping'))) {
313                     return;
314                 }
315             }
316         }
317         if (!image_node_already_run)
318             image_node.setAttribute('hide-grouping', image_node.parentNode.parentNode.id.substring(1) + 'IMG');
319         if (!sister_node_non_exist)
320             sister_node.setAttribute('hide-grouping', image_node.parentNode.parentNode.id.substring(1) + 'IMG');
321         if (!image_node_already_run)
322             image_node.addEventListener('click', function (evt) { return _this.hideOnClick(evt); });
323         if (!sister_node_non_exist)
324             sister_node.addEventListener('click', function (evt) { return _this.hideOnClick(evt); });
325         var threadstore_len = this.threads_to_hide.length;
326         var node_group_id = image_node.getAttribute('hide-grouping');
327         for (var thread = 0; thread < threadstore_len; thread++) {
328             if (node_group_id == this.threads_to_hide[thread]) {
329                 if (!image_node_already_run) {
330                     image_node.setAttribute('hidden-src', image_node.src);
331                     image_node.src = this.blank_png;
332                 }
333                 if (!sister_node_non_exist) {
334                     sister_node.setAttribute('hidden-src', sister_node.src);
335                     sister_node.src = this.blank_png;
336                 }
337                 return;
338             }
339         }
340         //index node holds the MD5
341         var node_md5 = image_node.getAttribute('data-md5');
342         if (this.md5_filters_arr !== undefined) {
343             var md5_filters_arr_len = this.md5_filters_arr.length;
344             for (var md5 = 0; md5 < md5_filters_arr_len; md5++) {
345                 if (node_md5 == this.md5_filters_arr[md5]) {
346                     this.threads_to_hide.push();
347                     if (!image_node_already_run) {
348                         image_node.setAttribute('hidden-src', image_node.src);
349                         image_node.src = this.blank_png;
350                     }
351                     if (!sister_node_non_exist) {
352                         sister_node.setAttribute('hidden-src', sister_node.src);
353                         sister_node.src = this.blank_png;
354                     }
355                     return;
356                 }
357             }
358         }
359     };
360     ImageHider.prototype.hideHoverImageNode = function (image_node) {
361         var unprocessed_id = image_node.getAttribute('data-full-i-d');
362         var proccessed_id = unprocessed_id.substring(unprocessed_id.indexOf('.') + 1);
363         var image_node_id = proccessed_id + 'IMG';
364         if (image_node === undefined)
365             return;
366         for (var thread = 0, threadstore_len = this.threads_to_hide.length; thread < threadstore_len; thread++) {
367             if (image_node_id == this.threads_to_hide[thread]) {
368                 image_node.removeAttribute('src');
369                 return;
370             }
371         }
372         //thread node holds the MD5
373         var node_md5;
374         // if(is_embeded_post) node_md5 = image_node.getAttribute('data-md5');
375         /*else */ node_md5 = document.getElementById('f' + proccessed_id).getElementsByTagName('IMG')[0].getAttribute('data-md5');
376         if (this.md5_filters_arr !== undefined) {
377             for (var md5 = 0, md5_filters_arr_len = this.md5_filters_arr.length; md5 < md5_filters_arr_len; md5++) {
378                 if (node_md5 == this.md5_filters_arr[md5]) {
379                     image_node.removeAttribute('src');
380                     return;
381                 }
382             }
383         }
384     };
385     return ImageHider;
386 }(FeatureInterface));
387 var TextReplacer = /** @class */ (function (_super) {
388     __extends(TextReplacer, _super);
389     function TextReplacer() {
390         var _this = _super.call(this) || this;
391         _this.text_filters = []; //object
392         _this.filtered_threads = [];
393         _this.retrieveStates();
394         _this.init();
395         _this.activate();
396         return _this;
397     }
398     TextReplacer.prototype.init = function () {
399         this.filtered_threads = [];
400     };
401     ;
402     TextReplacer.prototype.activate = function () { console.log("4F-FSE: TextReplacer Active"); };
403     TextReplacer.prototype.decideAction = function (node) {
404         if (node.tagName == "BLOCKQUOTE") {
405             if (node.className == "postMessage") {
406                 var blockquote_id = node.id;
407                 var already_filtered = false;
408                 this.filtered_threads.forEach(function (thread_id) {
409                     if (thread_id == blockquote_id) {
410                         already_filtered = true;
411                         return;
412                     }
413                 });
414             }
415             else
416                 return;
417             if (!already_filtered && this.text_filters.length !== 0) {
418                 var itterator = document.createNodeIterator(node, NodeFilter.SHOW_TEXT);
419                 var localNode;
420                 while ((localNode = itterator.nextNode())) {
421                     for (var filter = 0; filter < this.number_of_filters; filter++) {
422                         if (this.text_filters[filter].Active === "true") {
423                             var last_slash_index = this.text_filters[filter].Regex.lastIndexOf("/");
424                             var filter_text = this.text_filters[filter].Regex.substring(1, last_slash_index);
425                             var flag = this.text_filters[filter].Regex.substring(last_slash_index + 1);
426                             var regex = new RegExp(filter_text, flag);
427                             var node_text = localNode.textContent;
428                             if (regex.test(node_text)) {
429                                 localNode.textContent = node_text.replace(regex, this.text_filters[filter].Replacement);
430                                 this.filtered_threads.push(blockquote_id);
431                             }
432                         }
433                     }
434                 }
435             }
436         }
437     };
438     TextReplacer.prototype.retrieveStates = function () {
439         var _this = this;
440         var storage_index = 0;
441         var JSON_storage = {};
442         var storage_key;
443         while (storage_index < window.localStorage.length) {
444             storage_key = window.localStorage.key(storage_index);
445             JSON_storage[storage_key] = window.localStorage.getItem(storage_key);
446             storage_index++;
447         }
448         this.number_of_filters = JSON_storage["filter_quantity"];
449         var filters = Generics.getJSONPropertiesByKeyName(JSON_storage, "[0-9]+FLT");
450         filters.sort();
451         filters.forEach(function (filter) {
452             _this.text_filters.push(TextReplacer.formatFilterSettings(JSON_storage[filter]));
453         });
454     };
455     //Splits the saved settings into components
456     TextReplacer.formatFilterSettings = function (input) {
457         var processed_input = (input.split('=')).map(function (x) { return decodeURIComponent(x); });
458         return { Active: processed_input[0], Regex: processed_input[1], Replacement: processed_input[2] };
459     };
460     TextReplacer.prototype.storeStates = function () { };
461     return TextReplacer;
462 }(FeatureInterface));
463 var DanbooruImageAdder = /** @class */ (function (_super) {
464     __extends(DanbooruImageAdder, _super);
465     function DanbooruImageAdder() {
466         var _this = _super.call(this) || this;
467         _this.timeout_functions = [];
468         _this.img_URL = "";
469         _this.post_number = 0;
470         _this.page_number = 0;
471         _this.json_page_numbers_used = [];
472         _this.previous_images = [];
473         _this.json_numbers_used = [];
474         _this.previous_page = 9001;
475         _this.subdomain_regex = new RegExp("http(|s)://");
476         _this.maximum_attempts = 20;
477         _this.time_max = 10;
478         _this.time = 10;
479         _this.init();
480         return _this;
481     }
482     DanbooruImageAdder.prototype.init = function () {
483         var _this = this;
484         this.time = this.time_max;
485         this.number_of_attempts = this.maximum_attempts;
486         document.addEventListener("QRDialogCreation", function (evt) {
487             _this.enhance4ChanX_HTML();
488             _this.enhanced4ChanXListeners();
489         });
490     };
491     DanbooruImageAdder.prototype.enhance4ChanX_HTML = function () {
492         var qr_window = document.getElementById("qr");
493         /*Should I auto open things for the user?*/
494         // var imagedump_opener:any = document.getElementById("dump-button");
495         // if(imagedump_opener !== null){imagedump_opener.click();}
496         // else{return;}
497         //image setting html elements.
498         var qr_image_adder_table = document.createElement("TABLE");
499         qr_image_adder_table.setAttribute("id", "qrImages");
500         qr_image_adder_table.setAttribute("style", "text-align:center");
501         qr_window.appendChild(qr_image_adder_table);
502         var options_row = document.createElement("TR");
503         options_row.setAttribute("ID", "or");
504         options_row.setAttribute("style", "margin:5px;");
505         qr_image_adder_table.appendChild(options_row);
506         var checkbox_safe = document.createElement("INPUT");
507         checkbox_safe.setAttribute("id", "safe");
508         checkbox_safe.setAttribute("type", "checkbox");
509         checkbox_safe.checked = true;
510         var checkbox_safe_text = document.createTextNode("Safe");
511         var checkbox_questionable = document.createElement("INPUT");
512         checkbox_questionable.setAttribute("id", "questionable");
513         checkbox_questionable.setAttribute("type", "checkbox");
514         var checkbox_questionable_text = document.createTextNode("Questionable");
515         var checkbox_explicit = document.createElement("INPUT");
516         checkbox_explicit.setAttribute("id", "explicit");
517         checkbox_explicit.setAttribute("type", "checkbox");
518         var checkbox_explicit_text = document.createTextNode("Explicit");
519         options_row.appendChild(checkbox_safe_text);
520         options_row.appendChild(checkbox_safe);
521         options_row.appendChild(checkbox_questionable_text);
522         options_row.appendChild(checkbox_questionable);
523         options_row.appendChild(checkbox_explicit_text);
524         options_row.appendChild(checkbox_explicit);
525         var image_tagging_row = document.createElement("TR");
526         this.help_icon_container = document.createElement("A");
527         this.help_icon_container.href = "javascript:void(0)";
528         this.help_icon_container.title = "Click to View Help!";
529         var help_icon = document.createElement("IMG");
530         help_icon.setAttribute("class", "help_icon");
531         help_icon.src = Constants.HELP_ICON_SOURCE;
532         this.help_icon_container.appendChild(help_icon);
533         image_tagging_row.appendChild(this.help_icon_container);
534         var tooltip_div = document.createElement("DIV");
535         tooltip_div.innerHTML = "Insert Tags to search from danbooru in the text box to the side.<br/>The URL for the image will be bellow. Some browsers such as chrome allow you to select this text<br/>Do Not Use \"order:\" tags<br/>Do Not Use \"rating:\" tags<br/>For more speed uncheck all boxes!<hr/>Submit bugs to <a href='https://github.com/ECHibiki/4chan-UserScripts'>my Github</a>";
536         (tooltip_div).setAttribute("class", "tooltip-4F");
537         (tooltip_div).setAttribute("id", "tooltipIA");
538         qr_window.appendChild(tooltip_div);
539         var second_row_nodes = [
540             document.createTextNode("Tags: "),
541             document.createElement("INPUT"),
542             document.createElement("INPUT"),
543             document.createElement("A"),
544             document.createElement("INPUT"),
545         ];
546         second_row_nodes.forEach(function (node) {
547             image_tagging_row.appendChild(node);
548         });
549         qr_image_adder_table.appendChild(image_tagging_row);
550         var auto_complete_row = document.createElement("TR");
551         auto_complete_row.setAttribute("ID", "auto-complete-row");
552         auto_complete_row.setAttribute("style", "margin:5px;");
553         qr_image_adder_table.appendChild(auto_complete_row);
554         second_row_nodes[1].setAttribute("ID", "tag_input");
555         var option_text_size = 18;
556         second_row_nodes[1].setAttribute("style", "width:44.9%;" + "font-size:" + option_text_size + "px");
557         second_row_nodes[3].setAttribute("ID", "timer");
558         second_row_nodes[3].setAttribute("style", "width:20%;margin:0 5px");
559         second_row_nodes[4].setAttribute("ID", "urlContainer");
560         second_row_nodes[4].setAttribute("style", "width:75%;margin:5px -25px");
561         second_row_nodes[4].setAttribute("disabled", "");
562         second_row_nodes[2].setAttribute("ID", "imageButton");
563         second_row_nodes[2].setAttribute("type", "button");
564         second_row_nodes[2].setAttribute("value", "Set Image");
565         //textarea expansion;
566         qr_window.getElementsByTagName("TEXTAREA")[0].style.width = "110%";
567         qr_window.appendChild(document.createElement("hr"));
568     };
569     DanbooruImageAdder.prototype.enhanced4ChanXListeners = function () {
570         var _this = this;
571         this.highQualityImages();
572         document.getElementById("qr-filerm").addEventListener("click", function (evt) { return _this.clearImage(); });
573         var qr_reference = document.getElementById("qr");
574         var tooltip_div = document.getElementById("tooltipIA");
575         this.help_icon_container.addEventListener("click", function (evt) {
576             if (_this.tool_tip_visible)
577                 tooltip_div.setAttribute("style", "z-index:9;padding:5px;border:1px solid black;background-color:white;word-wrap:break-word;display:none;position:absolute;");
578             else
579                 tooltip_div.setAttribute("style", "z-index:9;padding:5px;border:1px solid black;background-color:white;word-wrap:break-word;display:block;position:absolute;"
580                     + "left:" + (evt.clientX - qr_reference.getBoundingClientRect().x) +
581                     "px;top:" + (evt.clientY - qr_reference.getBoundingClientRect().y) + "px;");
582             _this.tool_tip_visible = !_this.tool_tip_visible;
583         });
584         var tag_input = document.getElementById("tag_input");
585         tag_input.addEventListener("input", function (evt) {
586             _this.setTagInterface(tag_input, document.getElementById("auto-complete-row"));
587         });
588         document.getElementById("imageButton").addEventListener("click", function (evt) { return _this.activate(); });
589     };
590     DanbooruImageAdder.prototype.highQualityImages = function () {
591         var _this = this;
592         var imagedump_file_list = document.getElementById("dump-list");
593         //used for setting and unsetting high resolution thumbs for dump list.
594         var dumplist_image = "";
595         var previous_dumplist_image = "";
596         var observer = new MutationObserver(function (mutate) {
597             dumplist_image = imagedump_file_list.firstChild.style.backgroundImage;
598             if (dumplist_image !== previous_dumplist_image && _this.img_URL !== "") {
599                 imagedump_file_list.firstChild.style.backgroundImage = "url(" + _this.img_URL + ")";
600                 previous_dumplist_image = imagedump_file_list.firstChild.style.backgroundImage;
601             }
602             else if (_this.img_URL == "") { }
603         });
604         observer.observe(imagedump_file_list, { attributes: true, subtree: true, childList: true, characterData: true });
605     };
606     DanbooruImageAdder.prototype.activate = function () {
607         var _this = this;
608         //on setimage click clear flags, timers and start another search
609         this.json_page_numbers_used = Array();
610         this.previous_page = 9001;
611         //reset a failed_to_find_required_tags boolean
612         this.primed_for_fail = false;
613         for (var i = 0; i < this.timeout_functions.length; i++) {
614             clearInterval(this.timeout_functions[i]);
615         }
616         this.tag_incorrect_state = false;
617         this.timeout = false;
618         //freeze interface to prevent mid opperation changes
619         document.getElementById("tag_input").setAttribute("disabled", "1");
620         document.getElementById("imageButton").setAttribute("disabled", "1");
621         this.time = this.time_max;
622         this.timeout_functions.push(setInterval(function () { return _this.counterFunction(); }, 1000));
623         //start the search
624         this.setImage(this);
625     };
626     //remove the high quallity image from the dump list
627     DanbooruImageAdder.prototype.clearImage = function () {
628         var imagedump_file_list = document.getElementById("dump-list");
629         imagedump_file_list.firstChild.style.backgroundImage = "url()"; //trigger mutation event
630         this.img_URL = ""; //get mutation to set to dead
631     };
632     DanbooruImageAdder.prototype.setTagInterface = function (tag_input_node, auto_complete_row) {
633         var tags = tag_input_node.value;
634         if (this.old_tags_before_change !== tags) {
635             this.previous_images = [];
636             var tag_carat_position = tag_input_node.selectionStart - 1;
637             var closest_tag = (function () {
638                 var current_chararcter = tags.charAt(tag_carat_position);
639                 var i = 0;
640                 var right_most = tag_carat_position;
641                 while (current_chararcter != " " && current_chararcter != "" && current_chararcter !== undefined) {
642                     i++;
643                     current_chararcter = tags.charAt(tag_carat_position + i);
644                     if (current_chararcter != " " && current_chararcter != "")
645                         right_most = tag_carat_position + i;
646                 }
647                 right_most += 1;
648                 current_chararcter = tags.charAt(tag_carat_position);
649                 i = 0;
650                 var leftMost = tag_carat_position;
651                 while (current_chararcter != " " && current_chararcter != "" && current_chararcter !== undefined) {
652                     i++;
653                     current_chararcter = tags.charAt(tag_carat_position - i);
654                     if (current_chararcter != " " && current_chararcter != "")
655                         leftMost = tag_carat_position - i;
656                 }
657                 return tags.substring(leftMost, right_most);
658             })();
659             var xhr = new GM_xmlhttpRequest(({
660                 method: "GET",
661                 url: "https://danbooru.donmai.us/tags.json?search[name_matches]=" + closest_tag + "*&search[order]=count",
662                 responseType: "json",
663                 onload: function (data) {
664                     data = data.response;
665                     var tagArray = tags.split(" ");
666                     while (auto_complete_row.hasChildNodes()) {
667                         auto_complete_row.removeChild(auto_complete_row.lastChild);
668                     }
669                     var qr_width = document.getElementById("qr").offsetWidth;
670                     var tag_table = document.createElement("TABLE");
671                     tag_table.setAttribute("style", "border:1px solid black;margin-top:5px");
672                     var tag_row = document.createElement("TR");
673                     for (var i = 0; i < 5; i++) {
674                         var a = document.createElement("A");
675                         var tagText = data["" + i];
676                         if (tagText == "" || tagText === undefined)
677                             break;
678                         tagText = tagText["name"];
679                         var a_txt = document.createTextNode(data[i]["name"]);
680                         var tag_data = document.createElement("TD");
681                         tag_data.setAttribute("style", "padding:5px;font-size:15px;font-weight:bold;border:1px solid black;");
682                         a.appendChild(a_txt);
683                         tag_data.appendChild(a);
684                         tag_row.appendChild(tag_data);
685                         tag_table.appendChild(tag_row);
686                         auto_complete_row.appendChild(tag_table);
687                         if (tag_table.offsetWidth > qr_width - 10) {
688                             tag_row.removeChild(tag_data);
689                             tag_table = document.createElement("TABLE");
690                             tag_row = document.createElement("TR");
691                             tag_row.appendChild(tag_data);
692                             tag_table.appendChild(tag_row);
693                             tag_table.setAttribute("style", "border:1px solid black;");
694                             auto_complete_row.appendChild(tag_table);
695                         }
696                         a.addEventListener("click", function (evt) {
697                             tagArray[tagArray.indexOf(closest_tag)] = this.textContent;
698                             document.getElementById("tag_input").value = tagArray.join(" ");
699                         });
700                     }
701                 }
702             }));
703         }
704         this.old_tags_before_change = tag_input_node.value;
705     };
706     //a series of calls on other functions that leads to the image being searched for
707     DanbooruImageAdder.prototype.setImage = function (this_) {
708         //Set image tags.
709         var tags = document.getElementById("tag_input").value.trim();
710         if (tags.indexOf(":") > -1) {
711             Generics.alert4ChanX("Character ':' not used for functional purpose", "warning");
712         }
713         var tags_arr = tags.split(" ");
714         var xhr_image_load = new GM_xmlhttpRequest(({
715             method: "GET",
716             //returns a list of all tags and their properties
717             url: "https://danbooru.donmai.us/tags.json?search[name]=" + tags_arr.join() + "&search[order]=count",
718             responseType: "json",
719             onload: function (data) {
720                 this_.json_tag = this_.verifyTags(data, tags_arr);
721                 if (this_.failed_to_find_required_tags_state)
722                     return;
723                 //set the end
724                 var end_URL = this_.ratingURL(this_.json_tag);
725                 var URL = this_.setPostAndPage(end_URL);
726                 this_.send_URL = URL;
727                 //final check, sends final request after function or calls this function again
728                 Generics.getJSON(URL, function (err, data, tags, _this_) { return this_.checkPageFromDanbooru(err, data, tags, _this_); }, tags_arr, this_);
729             }
730         }));
731     };
732     //make 4chanX alerts on issues, and account for error cases.
733     DanbooruImageAdder.prototype.verifyTags = function (data, tags) {
734         data = data.response;
735         this.json_tag = data;
736         this.failed_to_find_required_tags_state = false;
737         //if data has a null or undefined case, return an error
738         if (data.length == 0) {
739             Generics.alert4ChanX("All tags incorrect", "error", 10);
740             this.failed_to_find_required_tags_state = true;
741             document.getElementById("timer").textContent = "";
742             document.getElementById("tag_input").removeAttribute("disabled");
743             document.getElementById("imageButton").removeAttribute("disabled");
744             return this.json_tag;
745         }
746         else if (data.length != tags.length && !this.tag_incorrect_state) {
747             this.tag_incorrect_state = true;
748             if (document.getElementById("tag_input").value.trim() == "")
749                 Generics.alert4ChanX("No Tags", "info", 2);
750             else
751                 Generics.alert4ChanX("One Tag Incorrect", "warning");
752         }
753         //tag size. Smallest tag is placed at bottom of JSON
754         this.smallest_tag_size = parseInt(data[data.length - 1]["post_count"]);
755         return this.json_tag;
756     };
757     //evaluate the rating restrictions to account for danbooru's tagging limitations
758     DanbooruImageAdder.prototype.ratingURL = function (tags) {
759         var URL = "";
760         //evaluate the 3! possible permutations
761         if (document.getElementById("safe").checked) {
762             if (document.getElementById("questionable").checked) {
763                 if (document.getElementById("explicit").checked) {
764                     if (tags.length > 1)
765                         URL = "&utf8=%E2%9C%93&tags=" + tags[tags.length - 2]["name"] + "+" + tags[tags.length - 1]["name"];
766                     else
767                         URL = "&utf8=%E2%9C%93&tags=" + tags[tags.length - 1]["name"];
768                 }
769                 else {
770                     URL = "&utf8=%E2%9C%93&tags=" + "-rating%3Aexplicit" + "+" + tags[tags.length - 1]["name"];
771                 }
772             }
773             else if (document.getElementById("explicit").checked) {
774                 URL = "&utf8=%E2%9C%93&tags=" + "-rating%3Aquestionable" + "+" + tags[tags.length - 1]["name"];
775             }
776             else {
777                 URL = "&utf8=%E2%9C%93&tags=" + "rating%3Asafe" + "+" + tags[tags.length - 1]["name"];
778             }
779         }
780         else if (document.getElementById("questionable").checked) {
781             if (document.getElementById("explicit").checked) {
782                 URL = "&utf8=%E2%9C%93&tags=" + "-rating%3Asafe" + "+" + tags[tags.length - 1]["name"];
783             }
784             else {
785                 URL = "&utf8=%E2%9C%93&tags=" + "rating%3Aquestionable" + "+" + tags[tags.length - 1]["name"];
786             }
787         }
788         else if (document.getElementById("explicit").checked) {
789             URL = "&utf8=%E2%9C%93&tags=" + "rating%3Aexplicit" + "+" + tags[tags.length - 1]["name"];
790         }
791         else {
792             if (tags.length > 1)
793                 URL = "&utf8=%E2%9C%93&tags=" + tags[tags.length - 2]["name"] + "+" + tags[tags.length - 1]["name"];
794             else
795                 URL = "&utf8=%E2%9C%93&tags=" + tags[tags.length - 1]["name"];
796         }
797         return URL;
798     };
799     //set where to search
800     DanbooruImageAdder.prototype.setPostAndPage = function (end_URL) {
801         this.post_number = 0;
802         //page
803         if (this.top_page != this.top_page_max)
804             this.smallest_tag_size = this.top_page * 20;
805         if (this.smallest_tag_size == 0)
806             this.smallest_tag_size = 100;
807         var escape_cond = true;
808         this.page_number = ((Math.floor(Math.random() * 10000)) % Math.ceil(this.smallest_tag_size / 20)) % 1000; //1000 is max page search limit
809         if (this.page_number == 0 && this.previous_page == 0) {
810             this.primed_for_fail = true;
811         }
812         this.json_numbers_used.push(this.page_number);
813         this.previous_page = this.page_number;
814         var URL = "https://danbooru.donmai.us/posts.json?page=" + this.page_number + end_URL;
815         return URL;
816     };
817     //check if valid url location
818     DanbooruImageAdder.prototype.checkPageFromDanbooru = function (err, data, tags, this_arr) {
819         if (err != null) {
820             console.log('Something went wrong: ' + err);
821             Generics.alert4ChanX("Danbooru Server Did Not Perform request -- Error: " + err, "error");
822             document.getElementById("timer").textContent = "";
823             document.getElementById("tag_input").removeAttribute("disabled");
824             document.getElementById("imageButton").removeAttribute("disabled");
825         }
826         else {
827             do {
828                 var duplicate = false;
829                 //check for repeating images found
830                 this_arr.previous_images.forEach(function (item) {
831                     if (item[0] == this_arr.page_number && item[1] == this_arr.post_number) {
832                         duplicate = true;
833                         this_arr.post_number++;
834                     }
835                 });
836             } while (duplicate);
837             if (this_arr.primed_for_fail) {
838                 Generics.alert4ChanX("No Results: All found for tags \"" + document.getElementById("tag_input").value + "\"", "error");
839                 this_arr.reset_search_timer_fields();
840                 return;
841             }
842             else if ((data.length < this_arr.post_number + 1) && this_arr.number_of_attempts > 0) {
843                 if (this_arr.top_page > this_arr.page_number) {
844                     this_arr.top_page = this_arr.page_number + this_arr.post_number / 20;
845                 }
846                 this_arr.number_of_attempts--;
847                 //posts
848                 this_arr.post_number = 0;
849                 document.getElementById("timer").textContent = this_arr.number_of_attempts + "|" + this_arr.time;
850                 this_arr.setImage(this_arr);
851             }
852             else if (this_arr.number_of_attempts > 0) {
853                 //ALL PARAMETERS WILL BE RESET INSIDE JSON
854                 document.getElementById("timer").textContent = this_arr.number_of_attempts + "|" + this_arr.time;
855                 Generics.getJSON(this_arr.send_URL, function (err, data, tags, _this_arr) { return this_arr.setImageFromDanbooru(err, data, tags, _this_arr); }, tags, this_arr);
856             }
857             else {
858                 Generics.alert4ChanX("Not found", "error");
859                 this_arr.reset_search_timer_fields();
860                 return;
861             }
862         }
863     };
864     DanbooruImageAdder.prototype.reset_search_timer_fields = function () {
865         this.top_page = this.top_page_max;
866         this.number_of_attempts = this.maximum_attempts;
867         document.getElementById("timer").textContent = "";
868         document.getElementById("tag_input").removeAttribute("disabled");
869         document.getElementById("imageButton").removeAttribute("disabled");
870     };
871     //finally draw from the JSON page to generate and place the post into the 4chanX dumplist
872     DanbooruImageAdder.prototype.setImageFromDanbooru = function (err, data, tags, this_arr) {
873         if (err != null) {
874             console.log('Something went wrong: ' + err);
875             Generics.alert4ChanX("Danbooru Server Did Not Perform request -- Error: " + err, "error");
876             document.getElementById("timer").textContent = "";
877             document.getElementById("tag_input").removeAttribute("disabled");
878             document.getElementById("imageButton").removeAttribute("disabled");
879         }
880         else {
881             this_arr.json_page = data;
882             var image_found = false;
883             for (this_arr.post_number = this_arr.post_number; this_arr.post_number < 20; this_arr.post_number++) {
884                 if (this_arr.timeout) {
885                     //Case1: Took too long to scan the page.
886                     //Result: Kills search
887                     Generics.alert4ChanX("timeout after " + this_arr.time + " seconds", "error");
888                     for (var i = 0; i < this_arr.timeout_functions.length; i++) {
889                         clearInterval(this_arr.timeout_functions[i]);
890                     }
891                     this_arr.reset_search_timer_fields();
892                     return;
893                 }
894                 else if (this_arr.json_page["" + this_arr.post_number] == undefined) {
895                     //Case2: reaches an undefined page.
896                     //Result: Switches to a new page
897                     this_arr.top_page = this_arr.page_number;
898                     //this_arr.number_of_attempts--;
899                     this_arr.setImage(this_arr);
900                     return;
901                 }
902                 //set the page to search
903                 var end_URL = this_arr.json_page["" + this_arr.post_number].file_url;
904                 var URL = "https://danbooru.donmai.us" + end_URL;
905                 if (this_arr.subdomain_regex.test(end_URL))
906                     URL = end_URL;
907                 //place url in visible box
908                 this_arr.urlContainterFunction(URL);
909                 /*
912     :{id: 3038118, created_at: "2018-03-02T15:27:56.469-05:00", uploader_id: 49091, score: 6,…}
913     approver_id:null
914     bit_flags:0
915     children_ids:null
916     created_at:"2018-03-02T15:27:56.469-05:00"
917     down_score:0
918     fav_count:10
919     fav_string:"fav:553974 fav:467363 fav:455311 fav:490034 fav:505064 fav:482030 fav:351935 fav:66907 fav:467355 fav:519151"
920     file_ext:"jpg"
921     file_size:30492
922     file_url:"/data/__miyuki_kantai_collection_drawn_by_kumadano__7a12a196cc1aa9f794bca81a2a14bb81.jpg"
923     has_active_children:false
924     has_children:false
925     has_large:false
926     has_visible_children:false
927     id:3038118
928     image_height:800
929     image_width:450
930     is_banned:false
931     is_deleted:false
932     is_flagged:false
933     is_note_locked:false
934     is_pending:false
935     is_rating_locked:false
936     is_status_locked:false
937     large_file_url:"/data/__miyuki_kantai_collection_drawn_by_kumadano__7a12a196cc1aa9f794bca81a2a14bb81.jpg"
938     last_comment_bumped_at:null
939     last_commented_at:null
940     last_noted_at:null
941     md5:"7a12a196cc1aa9f794bca81a2a14bb81"
942     parent_id:null
943     pixiv_id:null
944     pool_string:""
945     preview_file_url:"/data/preview/7a12a196cc1aa9f794bca81a2a14bb81.jpg"
946     rating:"s"
947     score:6
948     source:"https://twitter.com/kumadano/status/969629578137251840"
949     tag_count:28
950     tag_count_artist:1
951     tag_count_character:1
952     tag_count_copyright:1
953     tag_count_general:24
954     tag_count_meta:1
955     tag_string:"1girl black_legwear blue_sailor_collar blue_skirt brown_eyes brown_hair commentary_request full_body grin kantai_collection kumadano miyuki_(kantai_collection) pleated_skirt ribbon sailor_collar school_uniform serafuku short_hair short_sleeves simple_background skirt smile socks solo standing wavy_hair white_background wrists_extended"
956     tag_string_artist:"kumadano"
957     tag_string_character:"miyuki_(kantai_collection)"
958     tag_string_copyright:"kantai_collection"
959     tag_string_general:"1girl black_legwear blue_sailor_collar blue_skirt brown_eyes brown_hair full_body grin pleated_skirt ribbon sailor_collar school_uniform serafuku short_hair short_sleeves simple_background skirt smile socks solo standing wavy_hair white_background wrists_extended"
960     tag_string_meta:"commentary_request"
961     up_score:6
962     updated_at:"2018-03-03T09:09:32.357-05:00"
963     uploader_id:49091
964     uploader_name:"---"
966                 */
967                 var failed_to_find_required_tags = false;
968                 if (end_URL === undefined ||
969                     end_URL.indexOf(".mp4") > -1 || end_URL.indexOf(".webm") > -1 || end_URL.indexOf(".swf") > -1 || end_URL.indexOf(".zip") > -1) {
970                     continue;
971                 }
972                 else {
973                     tags.forEach(function (tag) {
974                         //if tag contains an order then whatever
975                         if (tag.indexOf("order:") > -1) { }
976                         else if (tag.indexOf("rating:") > -1) {
977                             if (tag.charAt(7) !== this_arr.json_page["" + this_arr.post_number]["rating"]) {
978                                 failed_to_find_required_tags = true;
979                             }
980                         }
981                         else if (this_arr.json_page["" + this_arr.post_number]["tag_string"].indexOf(tag) == -1) {
982                             failed_to_find_required_tags = true;
983                         }
984                     });
985                 }
986                 if (failed_to_find_required_tags) {
987                     continue;
988                 }
989                 else {
990                     if (this_arr.json_page["" + this_arr.post_number].file_size >= 4000000) {
991                         var end_URL = this_arr.json_page["" + this_arr.post_number].large_file_url;
992                         var URL = "https://danbooru.donmai.us" + end_URL;
993                         if (this_arr.subdomain_regex.test(end_URL))
994                             URL = end_URL;
995                     }
996                     document.getElementById("timer").textContent = "...";
997                     this_arr.img_URL = URL;
998                     var xhr = new GM_xmlhttpRequest(({
999                         method: "GET",
1000                         url: URL,
1001                         responseType: "arraybuffer",
1002                         onload: function (response) {
1003                             //is it a non existent image?
1004                             if (response.response.byteLength <= 387) {
1005                                 Generics.alert4ChanX("Image Does Not Exist on Danbooru(404 error)\nDanbooru seems to be updating image servers???", "error");
1006                             }
1007                             var blob;
1008                             if (end_URL.indexOf(".jpg") > -1)
1009                                 blob = new Blob([response.response], { type: "image/jpeg" });
1010                             else if (end_URL.indexOf(".png") > -1)
1011                                 blob = new Blob([response.response], { type: "image/png" });
1012                             else if (end_URL.indexOf(".gif") > -1)
1013                                 blob = new Blob([response.response], { type: "image/gif" });
1014                             var counter = document.getElementById("timer");
1015                             while (counter.hasChildNodes())
1016                                 counter.removeChild(counter.lastChild);
1017                             this_arr.reset_search_timer_fields();
1018                             this_arr.time = this_arr.time_max;
1019                             var name = end_URL.replace(/(data|cached)/g, "");
1020                             name = name.replace(/\//g, "");
1021                             //SEND RESULTING RESPONSE TO 4CHANX FILES === QRSetFile
1022                             var detail = { file: blob, name: name };
1023                             if (typeof cloneInto === 'function') {
1024                                 detail = cloneInto(detail, document.defaultView);
1025                             }
1026                             document.dispatchEvent(new CustomEvent('QRSetFile', { bubbles: true, detail: detail }));
1027                         }
1028                     }));
1029                     //end function;
1030                     image_found = true;
1031                     //SET PAGE&POST AS FOUND
1032                     this_arr.previous_images.push([this_arr.page_number, this_arr.post_number]);
1033                     this_arr.post_number = 9001;
1034                 }
1035             }
1036             if (!image_found) {
1037                 // this_arr.top_page = this_arr.page_number;
1038                 // //this_arr.number_of_attempts--;
1039                 this_arr.setImage(this_arr);
1040             }
1041         }
1042     };
1043     DanbooruImageAdder.prototype.urlContainterFunction = function (url) {
1044         var url_box = document.getElementById("urlContainer");
1045         url_box.value = url;
1046     };
1047     DanbooruImageAdder.prototype.counterFunction = function () {
1048         if (!this.timeout) {
1049             this.time--;
1050             if (this.time < 0) {
1051                 this.timeout = true;
1052                 this.time = this.time_max;
1053             }
1054         }
1055     };
1056     DanbooruImageAdder.prototype.decideAction = function (node) { };
1057     DanbooruImageAdder.prototype.retrieveStates = function () { };
1058     DanbooruImageAdder.prototype.storeStates = function () {
1059         var items = [];
1060         for (var _i = 0; _i < arguments.length; _i++) {
1061             items[_i] = arguments[_i];
1062         }
1063     };
1064     return DanbooruImageAdder;
1065 }(FeatureInterface));
1066 var ThreadRebuilder = /** @class */ (function (_super) {
1067     __extends(ThreadRebuilder, _super);
1068     function ThreadRebuilder() {
1069         var _this = _super.call(this) || this;
1070         _this.board = "qa";
1071         _this.thread_data = [['Comment'], ['Image URLs'], ['Image Names'], ['Post No.']];
1072         _this.semaphore = 1;
1073         _this.semaphore_posts = 1;
1074         _this.use_offsite_archive = false;
1075         _this.window_displayed = false;
1076         _this.in_sequence = false;
1077         _this.tool_top_visible = false;
1078         _this.thread_data_length = 0;
1079         _this.posts_created = 0;
1080         _this.checked = false;
1081         _this.init();
1082         return _this;
1083     }
1084     ThreadRebuilder.prototype.init = function () {
1085         var board_uproces = window.location.pathname;
1086         this.board = board_uproces.substring(1, board_uproces.length - 1);
1087         this.activate();
1088     };
1089     ThreadRebuilder.prototype.retrieveStates = function () {
1090         this.use_offsite_archive = localStorage.getItem("ArchiveType") == "0" ? true : false;
1091     };
1092     ThreadRebuilder.prototype.storeStates = function () {
1093         var items = [];
1094         for (var _i = 0; _i < arguments.length; _i++) {
1095             items[_i] = arguments[_i];
1096         }
1097     };
1098     ThreadRebuilder.prototype.activate = function () {
1099         var _this = this;
1100         document.addEventListener("QRDialogCreation", function (e) { return _this.enhance4ChanX(); });
1101         document.addEventListener('QRPostSuccessful', function (e) {
1102             if (_this.in_sequence) {
1103                 document.getElementById("dump-list").childNodes[1].click();
1104                 _this.setPropperLinking(document.getElementById("qr").getElementsByTagName("TEXTAREA")[0].value);
1105             }
1106         }, false);
1107     };
1108     ThreadRebuilder.prototype.decideAction = function (node) { };
1109     ThreadRebuilder.prototype.enhance4ChanX = function () {
1110         var _this = this;
1111         var qr_window = document.getElementById("qr");
1112         if (document.getElementById("qrRebuilder") !== null)
1113             qr_window.removeChild(document.getElementById("qrRebuilder"));
1114         var thread_rebuilder_table = document.createElement("TABLE");
1115         thread_rebuilder_table.setAttribute("id", "qrRebuilder");
1116         thread_rebuilder_table.setAttribute("style", "text-align:center");
1117         qr_window.appendChild(thread_rebuilder_table);
1118         var thread_row = document.createElement("TR");
1119         var option_text_size = 18;
1120         var help_icon_container = document.createElement("A");
1121         help_icon_container.href = "javascript:void(0)";
1122         help_icon_container.title = "Click to View Help!";
1123         var help_icon = document.createElement("IMG");
1124         help_icon.setAttribute("style", "height:" + option_text_size * 1.25 + "px;margin:-4px 10px");
1125         help_icon.src = Constants.HELP_ICON_SOURCE;
1126         help_icon_container.appendChild(help_icon);
1127         thread_row.appendChild(help_icon_container);
1128         var tooltip_div = document.createElement("DIV");
1129         tooltip_div.innerHTML = "Insert the thread number of the post to rebuild<br/>Must be in either the 4chan archives or archived.moe<hr/>Submit bugs to <a href='https://github.com/ECHibiki/4chan-UserScripts'>my Github</a>";
1130         tooltip_div.setAttribute("style", "z-index:9;padding:5px;border:1px solid black;background-color:white;word-wrap:break-word;display:none;position:absolute;");
1131         help_icon_container.addEventListener("click", function (evt) {
1132             if (_this.tool_top_visible)
1133                 tooltip_div.setAttribute("style", "z-index:9;padding:5px;border:1px solid black;background-color:white;word-wrap:break-word;display:none;position:absolute;");
1134             else
1135                 tooltip_div.setAttribute("style", "z-index:9;padding:5px;border:1px solid black;background-color:white;word-wrap:break-word;display:block;position:absolute;"
1136                     + "left:" + (evt.clientX - qr_window.getBoundingClientRect().x) +
1137                     "px;top:" + (evt.clientY - qr_window.getBoundingClientRect().y) + "px;");
1138             _this.tool_top_visible = !_this.tool_top_visible;
1139         });
1140         qr_window.appendChild(tooltip_div);
1141         var second_row_nodes = [
1142             document.createTextNode("Thread: "),
1143             document.createElement("INPUT"),
1144             document.createElement("INPUT"),
1145         ];
1146         second_row_nodes.forEach(function (node) {
1147             thread_row.appendChild(node);
1148         });
1149         thread_rebuilder_table.appendChild(thread_row);
1150         second_row_nodes[1].setAttribute("ID", "threadInput");
1151         second_row_nodes[1].setAttribute("style", "width:35.0%");
1152         second_row_nodes[2].setAttribute("ID", "threadButton");
1153         second_row_nodes[2].setAttribute("type", "button");
1154         second_row_nodes[2].setAttribute("value", "Set Rebuild Queue");
1155         second_row_nodes[2].addEventListener("click", function () {
1156             _this.in_sequence = true;
1157             _this.killAll();
1158             _this.getThread(second_row_nodes[1].value);
1159             _this.postID = setInterval(function () { return _this.postRoutine(); }, 1000);
1160             if (_this.timeListen === undefined)
1161                 _this.timeListen = setInterval(function () { return _this.timeListenerFunction(); }, 1000);
1162         });
1163         qr_window.appendChild(document.createElement("hr"));
1164     };
1165     ;
1166     ThreadRebuilder.prototype.postRoutine = function () {
1167         var _this = this;
1168         if (this.semaphore == 0) {
1169             this.semaphore++;
1170             this.thread_data_length = this.thread_data[0].length;
1171             this.fillID = setInterval(function () { return _this.fillRoutine(); }, 10);
1172             this.stopRoutine();
1173         }
1174     };
1175     ;
1176     ThreadRebuilder.prototype.stopRoutine = function () {
1177         clearInterval(this.postID);
1178     };
1179     ;
1180     ThreadRebuilder.prototype.fillRoutine = function () {
1181         if (this.posts_created >= this.thread_data_length) {
1182             this.semaphore_posts = 0;
1183             this.stopFillRoutine();
1184         }
1185         else if (this.semaphore_posts == 1) {
1186             this.semaphore_posts--;
1187             this.createPost(this.thread_data[0][this.posts_created], this.thread_data[1][this.posts_created], this.thread_data[2][this.posts_created]);
1188             this.posts_created++;
1189         }
1190     };
1191     ;
1192     ThreadRebuilder.prototype.stopFillRoutine = function () {
1193         clearInterval(this.fillID);
1194     };
1195     ThreadRebuilder.prototype.setPropperLinking = function (text) {
1196         var _this = this;
1197         var search_regex = RegExp(">>\\d+", "g");
1198         var result;
1199         var index_old = -1;
1200         var link_arr = Array();
1201         while ((result = search_regex.exec(text)) != null) {
1202             var end_index = search_regex.lastIndex;
1203             var post_no = result.toString().replace(/>/g, "");
1204             link_arr.push([post_no, end_index]);
1205         }
1206         //hunt down the text of what it linked to
1207         //Get the links inside of the origonal message to show text contents
1208         var responding_text = Array();
1209         if (this.use_offsite_archive)
1210             var URL = "https://www.archived.moe/_/api/chan/thread/?board=" + this.board + "&num=" + document.getElementById("threadInput").value;
1211         else
1212             var URL = "https://a.4cdn.org/" + this.board + "/thread/" + document.getElementById("threadInput").value + ".json";
1213         var xhr = new GM_xmlhttpRequest(({
1214             method: "GET",
1215             url: URL,
1216             responseType: "json",
1217             onload: function (data) {
1218                 if (_this.use_offsite_archive)
1219                     data = data.response["" + document.getElementById("threadInput").value]["posts"];
1220                 else
1221                     data = data.response["posts"];
1222                 if (data == undefined) {
1223                     alert("Invalid Thread ID: " + document.getElementById("threadInput").value + ". ");
1224                 }
1225                 else {
1226                     link_arr.forEach(function (link_item) {
1227                         for (var data_entry = 0; data_entry < data.length; data_entry++) {
1228                             if (parseInt(link_item[0]) == parseInt(data[data_entry]["no"])) {
1229                                 if (_this.use_offsite_archive && data[data_entry]["comment_processed"] !== undefined)
1230                                     responding_text.push([[post_no, end_index], data[data_entry]["comment_processed"].replace(/(&gt;&gt;|https:\/\/www\.archived\.moe\/.*\/thread\/.*\/#)\d+/g, ""), link_item["media"]["safe_media_hash"]]);
1231                                 else if (data[data_entry]["com"] !== undefined)
1232                                     responding_text.push([[post_no, end_index], data[data_entry]["com"].replace(/(&gt;&gt;|#p)\d+/g, ""), data[data_entry]["md5"]]);
1233                                 else
1234                                     responding_text.push([[post_no, end_index], undefined, data[data_entry]["md5"]]);
1235                                 break;
1236                             }
1237                         }
1238                     });
1239                     var current_url = window.location.href;
1240                     var hash_index = current_url.lastIndexOf("#") != -1 ? current_url.lastIndexOf("#") : window.location.href.length;
1241                     var current_thread = window.location.href.substring(current_url.lastIndexOf("/") + 1, hash_index);
1242                     var current_url = "https://a.4cdn.org/" + _this.board + "/thread/" + current_thread + ".json";
1243                     //open current thread to hunt down the text found in links
1244                     var xhr = new GM_xmlhttpRequest(({
1245                         method: "GET",
1246                         url: current_url,
1247                         responseType: "json",
1248                         onload: function (data) {
1249                             data = data.response["posts"];
1250                             if (data == undefined) {
1251                                 alert("Invalid Thread ID: " + document.getElementById("threadInput").value + ". ");
1252                             }
1253                             else {
1254                                 responding_text.forEach(function (response_item) {
1255                                     for (var data_entry = 0; data_entry < data.length; data_entry++) {
1256                                         if (data[data_entry]["com"] !== undefined && (response_item[1] == data[data_entry]["com"].replace(/(&gt;&gt;|#p)\d+/g, "") || response_item[1] == null)
1257                                             && (response_item[2] == data[data_entry]["md5"] || response_item[2] == null)) {
1258                                             var start_index = response_item[0][0].legth - response_item[0][1];
1259                                             text = text.substring(0, start_index) + ">>" + data[data_entry]["no"] + text.substring(response_item[0][1]);
1260                                             break;
1261                                         }
1262                                         else if (response_item[2] !== undefined && response_item[2] == data[data_entry]["md5"]) {
1263                                             var start_index = response_item[0][0].legth - response_item[0][1];
1264                                             text = text.substring(0, start_index) + ">>" + data[data_entry]["no"] + text.substring(response_item[0][1]);
1265                                             break;
1266                                         }
1267                                     }
1268                                 });
1269                                 document.getElementById("qr").getElementsByTagName("TEXTAREA")[0].value = text;
1270                                 document.getElementById("add-post").click();
1271                                 _this.semaphore_posts++;
1272                             }
1273                         }
1274                     }));
1275                 }
1276             }
1277         }));
1278     };
1279     ;
1280     //2) GET ARCHIVED THREAD
1281     ThreadRebuilder.prototype.getThread = function (threadNo) {
1282         var _this = this;
1283         this.thread_data = [[], [], [], []];
1284         if (this.use_offsite_archive)
1285             var URL = "https://www.archived.moe/_/api/chan/thread/?board=" + this.board + "&num=" + document.getElementById("threadInput").value;
1286         else
1287             var URL = "https://a.4cdn.org/" + this.board + "/thread/" + document.getElementById("threadInput").value + ".json";
1288         var xhr = new GM_xmlhttpRequest(({
1289             method: "GET",
1290             url: URL,
1291             responseType: "json",
1292             onload: function (data) {
1293                 var starting_post = -1;
1294                 if (_this.use_offsite_archive) {
1295                     starting_post = 0;
1296                     data = data.response["" + document.getElementById("threadInput").value];
1297                 }
1298                 else {
1299                     starting_post = 1;
1300                     data = data.response;
1301                 }
1302                 if (data == undefined) {
1303                     alert("Invalid Thread ID: " + threadNo + ".\n4chan Archive ");
1304                 }
1305                 else {
1306                     if (_this.use_offsite_archive)
1307                         data["posts"] = data.values(data["posts"]);
1308                     var len = data["posts"].length;
1309                     for (var post_number = starting_post; post_number < len; post_number++) {
1310                         var comment = undefined;
1311                         if (_this.use_offsite_archive)
1312                             comment = data["posts"][post_number]["comment"];
1313                         else
1314                             comment = data["posts"][post_number]["com"];
1315                         if (comment !== undefined && comment !== null)
1316                             _this.thread_data[0].push(comment);
1317                         else
1318                             _this.thread_data[0].push("");
1319                         var filename = undefined;
1320                         if (_this.use_offsite_archive) {
1321                             if (data["posts"][post_number]["media"] !== null)
1322                                 filename = "" + data["posts"][post_number]["media"]["media_filename"];
1323                         }
1324                         else
1325                             filename = "" + data["posts"][post_number]["tim"] + data["posts"][post_number]["ext"];
1326                         if (filename !== undefined && filename !== null && filename.indexOf("undefined") == -1)
1327                             if (_this.use_offsite_archive)
1328                                 if (data["posts"][post_number]["media"] !== null)
1329                                     _this.thread_data[1].push(data["posts"][post_number]["media"]["remote_media_link"]);
1330                                 else
1331                                     _this.thread_data[1].push("");
1332                             else
1333                                 _this.thread_data[1].push("https://i.4cdn.org/" + _this.board + "/" + filename);
1334                         else
1335                             _this.thread_data[1].push("");
1336                         if (_this.use_offsite_archive) {
1337                             if (data["posts"][post_number]["media"] !== null)
1338                                 _this.thread_data[2].push(data["posts"][post_number]["media"]["media_id"]);
1339                         }
1340                         else
1341                             _this.thread_data[2].push(data["posts"][post_number]["filename"]);
1342                         if (_this.use_offsite_archive)
1343                             _this.thread_data[3].push(data["posts"][post_number]["num"]);
1344                         else
1345                             _this.thread_data[3].push(data["posts"][post_number]["no"]);
1346                     }
1347                 }
1348                 _this.semaphore--;
1349             }
1350         }));
1351     };
1352     ;
1353     //3) RIP POSTS AND IMAGES
1354     ThreadRebuilder.prototype.createPost = function (text, imageURL, imageName) {
1355         var _this = this;
1356         if (imageURL != "") {
1357             var response_type = "arraybuffer";
1358             if (this.use_offsite_archive)
1359                 response_type = "text";
1360             var xhr = new GM_xmlhttpRequest(({
1361                 method: "GET",
1362                 url: imageURL,
1363                 responseType: response_type,
1364                 onload: function (response) {
1365                     if (_this.use_offsite_archive) {
1366                         var parser = new DOMParser();
1367                         var content_attribute = parser.parseFromString(response.response, "text/html").getElementsByTagName("META")[0].getAttribute("content");
1368                         var redirect_url = content_attribute.substring(content_attribute.indexOf("http"));
1369                         var xhr = new GM_xmlhttpRequest(({ method: "GET", url: redirect_url, responseType: "arraybuffer",
1370                             onload: function (response) {
1371                                 _this.inputImage(response, text, imageURL, imageName);
1372                             }
1373                         }));
1374                     }
1375                     else {
1376                         _this.inputImage(response, text, imageURL, imageName);
1377                     }
1378                 }
1379             }));
1380         }
1381         else {
1382             text = this.createPostComment(text);
1383             this.setPropperLinking(text);
1384         }
1385     };
1386     ThreadRebuilder.prototype.inputImage = function (response, text, imageURL, imageName) {
1387         var blob;
1388         var ext = ".jpg";
1389         if (imageURL.indexOf(".jpg") > -1) {
1390             blob = new Blob([response.response], { type: "image/jpeg" });
1391             ext = ".jpg";
1392         }
1393         else if (imageURL.indexOf(".png") > -1) {
1394             blob = new Blob([response.response], { type: "image/png" });
1395             ext = ".png";
1396         }
1397         else if (imageURL.indexOf(".gif") > -1) {
1398             blob = new Blob([response.response], { type: "image/gif" });
1399             ext = ".gif";
1400         }
1401         else if (imageURL.indexOf(".webm") > -1) {
1402             blob = new Blob([response.response], { type: "video/webm" });
1403             ext = ".webm";
1404         }
1405         var name = imageName + ext;
1406         //SEND RESULTING RESPONSE TO 4CHANX FILES === QRSetFile
1407         var detail = { file: blob, name: name };
1408         detail = cloneInto(detail, document.defaultView);
1409         document.dispatchEvent(new CustomEvent('QRSetFile', { bubbles: true, detail: detail }));
1410         if (text !== "" && text !== undefined) {
1411             text = this.createPostComment(text);
1412             this.setPropperLinking(text);
1413         }
1414         else {
1415             document.getElementById("add-post").click();
1416             this.semaphore_posts++;
1417         }
1418     };
1419     //4) CREATE POST QUEUE
1420     ThreadRebuilder.prototype.createPostComment = function (text) {
1421         var dummy = document.createElement("DIV");
1422         dummy.innerHTML = text;
1423         var inside_node = dummy.firstChild;
1424         var return_text = "";
1425         do {
1426             if (inside_node.tagName == "BR")
1427                 return_text += "\n";
1428             else
1429                 return_text += inside_node.textContent;
1430         } while ((inside_node = inside_node.nextSibling));
1431         return return_text;
1432     };
1433     ;
1434     ThreadRebuilder.prototype.timeListenerFunction = function () {
1435         var time = parseInt(document.getElementById("qr-filename-container").nextSibling.value.replace(/[a-zA-Z]+/g, ""));
1436         if (time <= 5) {
1437             this.checked = false;
1438         }
1439         else if (time > 5) {
1440             this.checked = true;
1441         }
1442     };
1443     ThreadRebuilder.prototype.killAll = function () {
1444         this.thread_data_length = 0;
1445         this.posts_created = 0;
1446         this.stopRoutine();
1447         this.postID = undefined;
1448         this.semaphore = 1;
1449         this.semaphore_posts = 1;
1450         this.stopFillRoutine();
1451         this.fillID = undefined;
1452         this.thread_data = [['Comment'], ['Image URLs'], ['Image Names'], ['Post No.']];
1453         //CLEAR DUMP LIST
1454         var qr_dumplist = document.getElementById("dump-list").childNodes;
1455         var qr_dumplist_len = qr_dumplist.length;
1456         var current_preview = 0;
1457         while (qr_dumplist_len - current_preview > 1) {
1458             qr_dumplist[0].firstChild.click();
1459             current_preview++;
1460         }
1461     };
1462     return ThreadRebuilder;
1463 }(FeatureInterface));
1464 var CharacterInserter = /** @class */ (function (_super) {
1465     __extends(CharacterInserter, _super);
1466     function CharacterInserter(use_kita, use_yen) {
1467         var _this = _super.call(this) || this;
1468         _this.kita_character = "キタ━━━(゚∀゚)━━━!!";
1469         _this.kita_hash_color = "#444444";
1470         _this.yen_character = "¥";
1471         _this.yen_hash_color = "#9370DB";
1472         _this.use_yen = use_yen;
1473         _this.use_kita = use_kita;
1474         _this.retrieveStates();
1475         _this.init();
1476         _this.activate();
1477         return _this;
1478     }
1479     CharacterInserter.prototype.init = function () {
1480         this.addStyle();
1481         this.hotkeyListeners();
1482     };
1483     CharacterInserter.prototype.activate = function () {
1484         console.log("4F-FSE: CharacterInserter Active - " + (this.use_kita ? "Character Coloring+" : "") + (this.use_yen ? " Line Coloring" : ""));
1485     };
1486     CharacterInserter.prototype.decideAction = function (node) {
1487         if (node.tagName == "BLOCKQUOTE")
1488             this.colorCharacters(node);
1489     };
1490     CharacterInserter.prototype.retrieveStates = function () {
1491         if (localStorage.getItem("Yen_Character") === undefined || localStorage.getItem("Yen_Character") === null)
1492             this.yen_character = "¥";
1493         else
1494             this.yen_character = localStorage.getItem("Yen_Character");
1495         if (localStorage.getItem("Yen_Color") === undefined || localStorage.getItem("Yen_Color") === null)
1496             this.yen_hash_color = "#9370DB";
1497         else
1498             this.yen_hash_color = localStorage.getItem("Yen_Color");
1499         if (localStorage.getItem("Kita_Character") === undefined || localStorage.getItem("Kita_Character") === null)
1500             this.kita_character = "キタ━━━(゚∀゚)━━━!!";
1501         else
1502             this.kita_character = localStorage.getItem("Kita_Character");
1503         if (localStorage.getItem("Kita_Color") === undefined || localStorage.getItem("Kita_Color") === null)
1504             this.kita_hash_color = "#444444";
1505         else
1506             this.kita_hash_color = localStorage.getItem("Kita_Color");
1507     };
1508     CharacterInserter.prototype.storeStates = function () {
1509         var items = [];
1510         for (var _i = 0; _i < arguments.length; _i++) {
1511             items[_i] = arguments[_i];
1512         }
1513     };
1514     //color styling
1515     CharacterInserter.prototype.addStyle = function () {
1516         var style = document.createElement("STYLE");
1517         style.innerHTML = ".the_m_word{color:" + this.yen_hash_color + "} \n.the_k_word{color:" + this.kita_hash_color + "}";
1518         document.head.appendChild(style);
1519     };
1520     //hotkeys for kita and yen
1521     CharacterInserter.prototype.hotkeyListeners = function () {
1522         var _this = this;
1523         var listener_obj = {};
1524         window.addEventListener("keydown", function (e) {
1525             listener_obj[e.keyCode] = true;
1526             var node = document.activeElement;
1527             if (listener_obj[17] && listener_obj[75]) {
1528                 e.preventDefault();
1529                 _this.insertAtPos(node, _this.kita_character);
1530             }
1531             if (listener_obj[17] && listener_obj[220]) {
1532                 e.preventDefault();
1533                 _this.insertAtPos(node, _this.yen_character);
1534             }
1535         }, { passive: false, capture: false, once: false });
1536         window.addEventListener("keyup", function (e) {
1537             listener_obj[e.keyCode] = false;
1538         }, { passive: false, capture: false, once: false });
1539     };
1540     CharacterInserter.prototype.insertAtPos = function (node, buzzwords) {
1541         var sel_start = node.selectionStart;
1542         var sel_end = node.selectionEnd;
1543         var node_text = node.value;
1544         node.value = node_text.substr(0, sel_start) + buzzwords + node_text.substr(sel_end);
1545         node.selectionStart = sel_start + buzzwords.length;
1546         node.selectionEnd = sel_end + buzzwords.length;
1547     };
1548     //insertion logic
1549     CharacterInserter.prototype.colorCharacters = function (root) {
1550         if (root.nodeType !== Node.ELEMENT_NODE) {
1551             return;
1552         }
1553         if (root.textContent.indexOf(this.yen_character) <= -1 && root.textContent.indexOf(this.kita_character) <= -1) {
1554             return;
1555         }
1556         var txtItterator = document.createNodeIterator(root, NodeFilter.SHOW_TEXT);
1557         var text_node;
1558         while ((text_node = txtItterator.nextNode())) {
1559             //disregard text inside of A tag links and already colored text
1560             if (text_node.parentNode.tagName == "A" || /the_[a-z]_word/g.test(text_node.parentNode.className))
1561                 continue;
1562             this.setColor(text_node, txtItterator);
1563         }
1564     };
1565     //give color to text inside of nodes.
1566     // first scan for yen symbols and then check the front of the text for not nested kita.
1567     CharacterInserter.prototype.setColor = function (text_node, txtItterator) {
1568         var start_text_node = text_node;
1569         var result;
1570         var yen_node = this.use_kita ? this.searchYen(text_node) : false;
1571         if (yen_node != false) {
1572             //jump to internal node
1573             text_node = txtItterator.nextNode();
1574             //scan for nested kita
1575             do {
1576                 result = this.use_kita ? this.searchKita(text_node) : false;
1577                 if (result != false) {
1578                     //jump foreward to point after kita inserted
1579                     text_node = txtItterator.nextNode();
1580                     text_node = txtItterator.nextNode();
1581                 }
1582             } while (result != false);
1583         }
1584         //scan for outside kita from start
1585         do {
1586             result = this.use_kita ? this.searchKita(start_text_node) : false;
1587             start_text_node = result.nextSibling;
1588         } while (result != false && start_text_node !== undefined);
1589     };
1590     //find the location of a yen, split the text from above that position, create a span element and place split into this span.
1591     //Then take the initial text node and insert into it from after the text node.
1592     CharacterInserter.prototype.searchYen = function (text_node) {
1593         var yenIndex = text_node.textContent.indexOf(this.yen_character);
1594         if (yenIndex > -1) {
1595             var splitNode = text_node.splitText(yenIndex);
1596             var span = document.createElement('span');
1597             span.className = "the_m_word";
1598             span.appendChild(splitNode);
1599             text_node.parentNode.insertBefore(span, text_node.nextSibling);
1600             return span;
1601         }
1602         return false;
1603     };
1604     //find the location of a kita, isolate it by splitting from the point where the kita ends and the point where it begins.
1605     //Now that there are 3 text nodes, take the middle one from the start position index split, add the text which goes to the point of the rightmost split,
1606     //then refer back to the parent and place it after the leftmost string.
1607     CharacterInserter.prototype.searchKita = function (text_node) {
1608         var kIndex = text_node.textContent.indexOf(this.kita_character);
1609         if (kIndex > -1) {
1610             var far_split_note = text_node.splitText(kIndex + this.kita_character.length);
1611             var splitNode = text_node.splitText(kIndex);
1612             var span = document.createElement('span');
1613             span.className = "the_k_word";
1614             span.appendChild(splitNode);
1615             text_node.parentNode.insertBefore(span, text_node.nextSibling);
1616             return span;
1617         }
1618         return false;
1619     };
1620     return CharacterInserter;
1621 }(FeatureInterface));
1622 var PasswordViewer = /** @class */ (function (_super) {
1623     __extends(PasswordViewer, _super);
1624     function PasswordViewer() {
1625         var _this = _super.call(this) || this;
1626         _this.post_id = "postPassword";
1627         _this.del_id = "delPassword";
1628         _this.label_post = document.createElement('LABEL');
1629         _this.label_del = document.createElement('LABEL');
1630         _this.init();
1631         _this.activate();
1632         return _this;
1633     }
1634     PasswordViewer.prototype.init = function () {
1635         this.node_post = document.getElementById(this.post_id);
1636         this.node_del = document.getElementById(this.del_id);
1637         this.node_post_parent = this.node_post.parentNode;
1638         this.node_del_parent = this.node_del.parentNode;
1639         this.label_post.textContent = 'Post: ';
1640         this.label_del.textContent = 'Delete: ';
1641     };
1642     //activate displays passwords
1643     PasswordViewer.prototype.activate = function () {
1644         console.log("4F-FSE: PasswordViewer Active");
1645         this.node_post_parent.insertBefore(this.label_post, this.node_post);
1646         this.node_del_parent.insertBefore(this.label_del, this.node_del);
1647         this.node_post.removeAttribute('type');
1648         this.node_del.removeAttribute('type');
1649         document.getElementsByClassName('deleteform')[0].style.display = 'inline';
1650         this.node_del.style.display = 'inline';
1651         this.label_del.style.display = 'inline';
1652         this.label_del.style.paddingLeft = '10px';
1653     };
1654     PasswordViewer.prototype.decideAction = function (node) { };
1655     PasswordViewer.prototype.retrieveStates = function () { };
1656     ;
1657     PasswordViewer.prototype.storeStates = function () { };
1658     ;
1659     return PasswordViewer;
1660 }(FeatureInterface));
1661 var SettingsWindow = /** @class */ (function (_super) {
1662     __extends(SettingsWindow, _super);
1663     function SettingsWindow() {
1664         var _this = _super.call(this) || this;
1665         _this.background_div = document.createElement('DIV');
1666         _this.settings_div = document.createElement('DIV');
1667         _this.close_div = document.createElement('DIV');
1668         _this.contents_div = document.createElement('DIV');
1669         _this.ul_selection_start = document.createElement('UL');
1670         _this.close_link = document.createElement('A');
1671         _this.title_para = document.createElement('P');
1672         _this.title_text = document.createTextNode('4F-FSE Settings');
1673         _this.end_para = document.createElement('P');
1674         _this.end_text = document.createTextNode('Refresh to view changes');
1675         _this.settings_style = document.createElement('STYLE');
1676         //to change order change, this AND...*
1677         _this.list_items = [
1678             { Text: " | View 『Image Hiding』 Settings", ListenerFunc: function (a_id) {
1679                     _this.clearContainer();
1680                     _this.contents_div.innerHTML =
1681                         "\n\t\t\t\t<div id=\"disposable_container\">\n\t\t\t\t\t\t\t\t <label>Non-MD5 Expiration Time(hours): </label>\n\t\t\t\t\t\t\t\t <input id=\"Expiration_Time\">\n\t\t\t\t\t\t\t\t <hr>\n\t\t\t\t\t\t\t\t <label>MD5 Filters:</label>\n\t\t\t\t\t\t\t\t <br>\n\t\t\t\t\t\t\t\t <textarea style=\"width:98%;height:217px\" placeholder=\"Enter MD5 like on 4chanX... \n\t\t\t\t\t\t\t\t/abc123/\n\t\t\t\t\t\t\t\t/def890/\" id=\"MD5_List_FSE\"></textarea>\n\t\t\t\t\t\t\t\t<hr>\n\t\t\t\t</div>\n\t\t\t\t";
1682                     document.getElementById("Expiration_Time").value = "" + (_this.setting_items.image_hiding_settings.Expiration_Time / Constants.MILLISECONDS_TO_THE_HOUR);
1683                     document.getElementById("MD5_List_FSE").value = _this.setting_items.image_hiding_settings.MD5_List_FSE;
1684                     var set_button = document.createElement('INPUT');
1685                     document.getElementById("disposable_container").appendChild(set_button);
1686                     set_button.setAttribute('VALUE', "Set Image Settings");
1687                     set_button.addEventListener("click", function (evt) {
1688                         _this.storeStates();
1689                         _this.clearContainer();
1690                         _this.rebuildContainer();
1691                     });
1692                     set_button.setAttribute('TYPE', 'button');
1693                 }
1694             },
1695             { Text: " | View 『Word Replacement』 Settings", ListenerFunc: function (a_id) {
1696                     _this.clearContainer();
1697                     var disposable_container = document.createElement("DIV");
1698                     disposable_container.setAttribute("ID", "disposable_container");
1699                     _this.contents_div.appendChild(disposable_container);
1700                     _this.filterWindow(disposable_container);
1701                     _this.filterSetTable();
1702                 }
1703             },
1704             { Text: " | View 『Danbooru Image Adder』 Settings", ListenerFunc: function (a_id) {
1705                     _this.clearContainer();
1706                     var disposable_container = document.createElement("DIV");
1707                     disposable_container.setAttribute("id", "disposable_container");
1708                     _this.contents_div.appendChild(disposable_container);
1709                     disposable_container.innerHTML = "\n\t\t\t<table style=\"text-align:center;margin-left:5px\">\n\t\t\t\t<tr>\n\t\t\t\t\t<td>\n\t\t\t\t\t\t<label>Very Large: </label>\n\t\t\t\t\t</td>\n\t\t\t\t\t<td>\n\t\t\t\t\t\t<input id=\"v_large_DIA\" name=\"preivew-size\" style=\"display:inline\" type=\"radio\">\n\t\t\t\t\t</td>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td>\n\t\t\t\t\t\t<label>Large: </label>\n\t\t\t\t\t</td>\n\t\t\t\t\t<td>\n\t\t\t\t\t\t<input id=\"large_DIA\" name=\"preivew-size\" style=\"display:inline\" type=\"radio\">\n\t\t\t\t\t</td>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td>\n\t\t\t\t\t\t<label>Medium: </label>\n\t\t\t\t\t</td>\n\t\t\t\t\t<td>\n\t\t\t\t\t\t<input id=\"medium_DIA\" name=\"preivew-size\" style=\"display:inline\" type=\"radio\">\n\t\t\t\t\t</td>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td>\n\t\t\t\t\t\t<label>Small: </label>\n\t\t\t\t\t</td>\n\t\t\t\t\t<td>\n\t\t\t\t\t\t<input id=\"small_DIA\" name=\"preivew-size\" style=\"display:inline\" type=\"radio\">\n\t\t\t\t\t</td>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td>\n\t\t\t\t\t\t<label>Width: </label>\n\t\t\t\t\t</td>\n\t\t\t\t\t<td>\n\t\t\t\t\t\t<input id=\"width_DIA\" name=\"preivew-size\" style=\"width:20%\"  type=\"text\">\n\t\t\t\t\t</td>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td>\n\t\t\t\t\t\t<label>Height: </label>\n\t\t\t\t\t</td>\n\t\t\t\t\t<td>\n\t\t\t\t\t\t<input id=\"height_DIA\" name=\"preivew-size\" style=\"width:20%\"  type=\"text\">\n\t\t\t\t\t</td>\n\t\t\t\t</tr>\n\t\t\t</table>\t\n\t\t\n\t\t\t<hr>\n\t\t\t\n\t\t\t<label>Quick Reply Min Width: </label>\n\t\t\t<input id=\"qr_width_DIA\" name=\"preivew-size\" style=\"width:20%\" type=\"text\">\n\t\t\n\t\t\t<hr>\n\t\t\n\t\t\t<input id=\"SetImageAdderProperties\" value=\"Set Preview Size\" type=\"button\">\n\t\t\t";
1710                     _this.setImageAdderFields();
1711                     _this.setImageAdderEventListeners();
1712                 }
1713             },
1714             { Text: " | View 『Thread Rebuilder』 Settings", ListenerFunc: function (a_id) {
1715                     _this.clearContainer();
1716                     var disposable_container = document.createElement("DIV");
1717                     disposable_container.setAttribute("id", "disposable_container");
1718                     _this.contents_div.appendChild(disposable_container);
1719                     disposable_container.innerHTML =
1720                         "\n\t\t\t\t<label>Use 4chan Archives: </label>\n\t\t\t\t<input name=\"ArchiveSettings\" id=\"OnsiteArchive\" type=\"radio\">\n\t\t\t\t<br>\n\t\t\t\t<label>Use Offsite Archives: </label>\n\t\t\t\t<input name=\"ArchiveSettings\" id=\"OffsiteArchive\" type=\"radio\">\n\t\t\t\t<br>\n\t\t\t\t<input id=\"setArchive\" value=\"Set Archive\" type=\"button\">\n\t\t\t";
1721                     (document.getElementById("setArchive")).addEventListener("click", function () {
1722                         _this.storeStates();
1723                         _this.clearContainer();
1724                         _this.rebuildContainer();
1725                     });
1726                     if (_this.setting_items.thread_rebuild_settings.Archive_Type === "0")
1727                         document.getElementById("OffsiteArchive").checked = true;
1728                     else if (_this.setting_items.thread_rebuild_settings.Archive_Type === "1")
1729                         document.getElementById("OnsiteArchive").checked = true;
1730                 }
1731             },
1732             { Text: " | View 『¥ Text』 Settings [Customizable]", ListenerFunc: function (a_id) {
1733                     _this.clearContainer();
1734                     var disposable_container = document.createElement("DIV");
1735                     disposable_container.setAttribute("id", "disposable_container");
1736                     _this.contents_div.appendChild(disposable_container);
1737                     disposable_container.innerHTML =
1738                         "\n\t\t\t\t<label>\u00A5Quote Character: </label>\n\t\t\t\t<input name=\"quoteCharacter\" id=\"quoteCharacter\" type=\"text\" value=\"\u00A5\">\n\t\t\t\t<br>\n\t\t\t\t<label>RGB Hex Color: </label>\n\t\t\t\t<input name=\"HexColorYen\" id=\"HexColorYen_text\" type=\"text\">\n\t\t\t\t<input name=\"HexColorYen\" id=\"SelectColorYen\" type=\"color\">\n\t\t\t\t<br>\n\t\t\t\t<input id=\"setQuote\" value=\"Set Quote Settings\" type=\"button\">\n\t\t\t";
1739                     document.getElementById("SelectColorYen").addEventListener("input", function (evt) {
1740                         document.getElementById("HexColorYen_text").value =
1741                             (document.getElementById("SelectColorYen").value);
1742                     });
1743                     document.getElementById("setQuote").addEventListener("click", function (e) {
1744                         _this.storeStates();
1745                         _this.clearContainer();
1746                         _this.rebuildContainer();
1747                     });
1748                     if (_this.setting_items.character_inserter_settings.Yen_Character !== undefined)
1749                         document.getElementById("quoteCharacter").value = _this.setting_items.character_inserter_settings.Yen_Character;
1750                     if (_this.setting_items.character_inserter_settings.Yen_Color !== undefined)
1751                         document.getElementById("HexColorYen_text").value = _this.setting_items.character_inserter_settings.Yen_Color;
1752                     document.getElementById("SelectColorYen").value = _this.setting_items.character_inserter_settings.Yen_Color;
1753                 }
1754             },
1755             { Text: " | View 『Kita』 Settings [Customizable]", ListenerFunc: function (a_id) {
1756                     _this.clearContainer();
1757                     var disposable_container = document.createElement("DIV");
1758                     disposable_container.setAttribute("id", "disposable_container");
1759                     _this.contents_div.appendChild(disposable_container);
1760                     disposable_container.innerHTML =
1761                         "\t\t\t\t\t\t\t\t\n\t\t\t\t<script src=\"http://jscolor.js\"></script>\n\t\t\t\t<label>Kita Characters: </label>\n\t\t\t\t<input name=\"selectiveCharacter\" id=\"selectiveCharacters\" type=\"text\" value=\"\uFF77\uFF80\u2501\u2501\u2501(\uFF9F\u2200\uFF9F)\u2501\u2501\u2501!!\">\n\t\t\t\t<br>\n\t\t\t\t<label>RGB Hex Color: </label>\n\t\t\t\t<input name=\"HexColorKita\" id=\"HexColorKita_text\" type=\"text\">\n\t\t\t\t<input name=\"HexColorKita\" id=\"SelectColorKita\" type=\"color\">\n\t\t\t\t<br>\n\t\t\t\t<input id=\"setCharacter\" value=\"Set Character Settings\" type=\"button\">\n\t\t\t";
1762                     document.getElementById("SelectColorKita").addEventListener("input", function (evt) {
1763                         document.getElementById("HexColorKita_text").value =
1764                             (document.getElementById("SelectColorKita").value);
1765                     });
1766                     document.getElementById("setCharacter").addEventListener("click", function (e) {
1767                         _this.storeStates();
1768                         _this.clearContainer();
1769                         _this.rebuildContainer();
1770                     });
1771                     if (_this.setting_items.character_inserter_settings.Kita_Character !== undefined)
1772                         document.getElementById("selectiveCharacters").value = _this.setting_items.character_inserter_settings.Kita_Character;
1773                     if (_this.setting_items.character_inserter_settings.Kita_Color !== undefined)
1774                         document.getElementById("HexColorKita_text").value = _this.setting_items.character_inserter_settings.Kita_Color;
1775                     document.getElementById("SelectColorKita").value = _this.setting_items.character_inserter_settings.Kita_Color;
1776                 }
1777             },
1778             { Text: " | Set 『Visible Password』", ListenerFunc: function (input_id) {
1779                     var input = document.getElementById(input_id);
1780                     var is_check = !input.checked;
1781                     document.getElementById(input_id).checked = is_check;
1782                     _this.storeStates();
1783                 } },
1784         ];
1785         _this.setting_items = {};
1786         _this.retrieveStates();
1787         _this.init();
1788         _this.activate();
1789         return _this;
1790     }
1791     SettingsWindow.prototype.setImageAdderFields = function () {
1792         document.getElementById("width_DIA").value = this.setting_items.image_adder_settings.Width;
1793         document.getElementById("height_DIA").value = this.setting_items.image_adder_settings.Height;
1794         document.getElementById("qr_width_DIA").value = this.setting_items.image_adder_settings.QR_Width;
1795         if (document.getElementById("width_DIA").value == "489")
1796             document.getElementById("v_large_DIA").checked = true;
1797         else if (document.getElementById("width_DIA").value == "400")
1798             document.getElementById("large_DIA").checked = true;
1799         else if (document.getElementById("width_DIA").value == "300")
1800             document.getElementById("medium_DIA").checked = true;
1801         else if (document.getElementById("width_DIA").value == "200")
1802             document.getElementById("small_DIA").checked = true;
1803     };
1804     SettingsWindow.prototype.setImageAdderEventListeners = function () {
1805         var _this = this;
1806         document.getElementById("v_large_DIA").addEventListener("click", function () {
1807             document.getElementById("width_DIA").value = "489";
1808             document.getElementById("height_DIA").value = "489";
1809         });
1810         document.getElementById("large_DIA").addEventListener("click", function () {
1811             document.getElementById("width_DIA").value = "400";
1812             document.getElementById("height_DIA").value = "400";
1813         });
1814         document.getElementById("medium_DIA").addEventListener("click", function () {
1815             document.getElementById("width_DIA").value = "300";
1816             document.getElementById("height_DIA").value = "300";
1817         });
1818         document.getElementById("small_DIA").addEventListener("click", function () {
1819             document.getElementById("width_DIA").value = "200";
1820             document.getElementById("height_DIA").value = "200";
1821         });
1822         document.getElementById("SetImageAdderProperties").addEventListener("click", function (evt) {
1823             _this.storeStates();
1824             _this.clearContainer();
1825             _this.rebuildContainer();
1826         });
1827     };
1828     //*...THIS
1829     SettingsWindow.prototype.retrieveStates = function () {
1830         //values used to fill out data fields
1831         this.setting_items.image_hiding_settings = { Expiration_Time: localStorage.getItem("Expiration_Time"), MD5_List_FSE: localStorage.getItem("MD5_List_FSE"), Active: localStorage.getItem("ImageHidingActive") };
1832         this.retrieveWordReplaceStates();
1833         this.retrieveImageAdderStates();
1834         this.retrieveRebuildStates();
1835         this.retrieveCharacterInsertingStates();
1836         this.setting_items.password_settings = (localStorage.getItem("PasswordActive"));
1837     };
1838     SettingsWindow.prototype.retrieveActiveToggles = function () {
1839         if (localStorage.getItem("4F-FSE") === null) {
1840             document.getElementById("check-settings0").checked = true;
1841             document.getElementById("check-settings1").checked = false;
1842             document.getElementById("check-settings2").checked = false;
1843             document.getElementById("check-settings3").checked = false;
1844             document.getElementById("check-settings4").checked = true;
1845             document.getElementById("check-settings5").checked = true;
1846             document.getElementById("check-settings6").checked = true;
1847             localStorage.setItem("4F-FSE", "Success");
1848             this.displayWindow();
1849             return;
1850         }
1851         document.getElementById("check-settings0").checked = localStorage.getItem("ImageHidingActive") === 'true';
1852         document.getElementById("check-settings1").checked = localStorage.getItem("TextReplaceActive") === 'true';
1853         document.getElementById("check-settings2").checked = localStorage.getItem("ImageAdderActive") === 'true';
1854         document.getElementById("check-settings3").checked = localStorage.getItem("ThreadRebuilderActive") === 'true';
1855         document.getElementById("check-settings4").checked = localStorage.getItem("YenActive") === 'true';
1856         document.getElementById("check-settings5").checked = localStorage.getItem("KitaActive") === 'true';
1857         document.getElementById("check-settings6").checked = localStorage.getItem("PasswordActive") === 'true';
1858     };
1859     SettingsWindow.prototype.retrieveWordReplaceStates = function () {
1860         //acquire text filter representation
1861         var storage_index = 0;
1862         var JSON_storage = {};
1863         var storage_key;
1864         var text_filters = [];
1865         var local_store_len = window.localStorage.length;
1866         while (storage_index < local_store_len) {
1867             storage_key = window.localStorage.key(storage_index);
1868             JSON_storage[storage_key] = window.localStorage.getItem(storage_key);
1869             storage_index++;
1870         }
1871         var filters = Generics.getJSONPropertiesByKeyName(JSON_storage, "[0-9]+FLT");
1872         filters.sort();
1873         filters.forEach(function (filter) {
1874             text_filters.push(TextReplacer.formatFilterSettings(JSON_storage[filter]));
1875         });
1876         this.setting_items.word_replace_settings = { Number_of_Filters: localStorage.getItem("filter_quantity"), Text_Filter_List: text_filters, Active: localStorage.getItem("TextReplaceActive") };
1877     };
1878     SettingsWindow.prototype.retrieveImageAdderStates = function () {
1879         this.setting_items.image_adder_settings = { Width: localStorage.getItem("width_DIA"),
1880             Height: localStorage.getItem("height_DIA"),
1881             QR_Width: localStorage.getItem("qr_width_DIA"),
1882             Active: localStorage.getItem("ImageAdderActive") };
1883         if (this.setting_items.image_adder_settings.Height === null)
1884             this.setting_items.image_adder_settings.Height = 400;
1885         if (this.setting_items.image_adder_settings.Width === null)
1886             this.setting_items.image_adder_settings.Width = 400;
1887         if (this.setting_items.image_adder_settings.QR_Width === null)
1888             this.setting_items.image_adder_settings.QR_Width = 480;
1889         document.getElementById("fourchanx-css").textContent += ".qr-preview { height:" + this.setting_items.image_adder_settings.Height + "px; width: " + this.setting_items.image_adder_settings.Width + "px; left:8%;background-size: cover;}";
1890         document.getElementById("fourchanx-css").textContent += "#dump-list { min-height: " + (this.setting_items.image_adder_settings.Width - 20) + "px; width: " + (this.setting_items.image_adder_settings.QR_Width) + "px;}";
1891     };
1892     SettingsWindow.prototype.retrieveRebuildStates = function () {
1893         if (localStorage.getItem("ArchiveType_FSE") !== "1" && localStorage.getItem("ArchiveType_FSE") !== "0")
1894             localStorage.setItem("ArchiveType_FSE", "1");
1895         this.setting_items.thread_rebuild_settings = { Archive_Type: localStorage.getItem("ArchiveType_FSE"), Active: localStorage.getItem("ThreadRebuilderActive") };
1896     };
1897     SettingsWindow.prototype.retrieveCharacterInsertingStates = function () {
1898         if (localStorage.getItem("Yen_Character") === undefined || localStorage.getItem("Yen_Character") === null)
1899             localStorage.setItem("Yen_Character", "¥");
1900         if (localStorage.getItem("Yen_Color") === undefined || localStorage.getItem("Yen_Color") === null)
1901             localStorage.setItem("Yen_Color", "#9370DB");
1902         if (localStorage.getItem("Kita_Character") === undefined || localStorage.getItem("Kita_Character") === null)
1903             localStorage.setItem("Kita_Character", "キタ━━━(゚∀゚)━━━!!");
1904         if (localStorage.getItem("Kita_Color") === undefined || localStorage.getItem("Kita_Color") === null)
1905             localStorage.setItem("Kita_Color", "#444444");
1906         this.setting_items.character_inserter_settings = { Yen_Active: localStorage.getItem("YenActive"), Yen_Character: localStorage.getItem("Yen_Character"), Yen_Color: localStorage.getItem("Yen_Color"),
1907             Kita_Active: localStorage.getItem("KitaActive"), Kita_Character: localStorage.getItem("Kita_Character"), Kita_Color: localStorage.getItem("Kita_Color") };
1908     };
1909     SettingsWindow.prototype.storeStates = function () {
1910         //image settings
1911         this.storeImageFilterStates();
1912         //Text replace settings
1913         this.storeTextFilterStates();
1914         //Image Adder settings
1915         this.storeImageAdderStates();
1916         //Thread rebuild settings
1917         this.storeRebuildStates();
1918         //character inserter
1919         this.storeCharacterInserterStates();
1920         //Password replace settings
1921         this.storePasswordStates();
1922         this.retrieveStates();
1923     };
1924     SettingsWindow.prototype.storeActiveToggles = function () {
1925         localStorage.setItem("ImageHidingActive", (document.getElementById("check-settings0").checked.toString()));
1926         localStorage.setItem("TextReplaceActive", (document.getElementById("check-settings1").checked.toString()));
1927         localStorage.setItem("ImageAdderActive", (document.getElementById("check-settings2").checked.toString()));
1928         localStorage.setItem("ThreadRebuilderActive", (document.getElementById("check-settings3").checked.toString()));
1929         localStorage.setItem("YenActive", (document.getElementById("check-settings4").checked.toString()));
1930         localStorage.setItem("KitaActive", (document.getElementById("check-settings5").checked.toString()));
1931         localStorage.setItem("PasswordActive", (document.getElementById("check-settings6").checked.toString()));
1932     };
1933     SettingsWindow.prototype.storeImageFilterStates = function () {
1934         if (document.getElementById("Expiration_Time") !== null) {
1935             var time = document.getElementById("Expiration_Time");
1936             var millisecond_time = parseInt(time.value) * Constants.MILLISECONDS_TO_THE_HOUR;
1937             if (millisecond_time == 0 || millisecond_time === null || millisecond_time === undefined)
1938                 millisecond_time = Constants.DEFAULT_HIDE_EXPIRATION_TIME;
1939             localStorage.setItem("Expiration_Time", millisecond_time.toString());
1940             var md5_filters = document.getElementById("MD5_List_FSE").value;
1941             localStorage.setItem("MD5_List_FSE", md5_filters);
1942             Generics.alert4ChanX("Image Settings Saved", "success", 3);
1943         }
1944     };
1945     SettingsWindow.prototype.storeTextFilterStates = function () {
1946         if (document.getElementById("FilterRow0") !== null) {
1947             var f_row_moving = document.getElementById("FilterRow0");
1948             var Number_of_Filters = 0;
1949             var Number_of_Filters_actual = 0;
1950             while (f_row_moving.nextSibling !== null) {
1951                 if (document.getElementById("Pattern" + Number_of_Filters).value !== "")
1952                     Number_of_Filters_actual++;
1953                 Number_of_Filters++;
1954                 f_row_moving = f_row_moving.nextSibling;
1955             }
1956             window.localStorage.setItem("filter_quantity", Number_of_Filters_actual.toString());
1957             for (var pattern_input = 0; pattern_input < Number_of_Filters; pattern_input++) {
1958                 var pattern_to_store = document.getElementById("Pattern" + pattern_input).value;
1959                 var replacement_to_store = document.getElementById("Replacement" + pattern_input).value;
1960                 var setting = 'g';
1961                 try {
1962                     if (pattern_to_store === "") {
1963                         localStorage.removeItem(pattern_input + "FLT");
1964                         continue;
1965                     }
1966                     else if (new RegExp("^\/.*\/\\D+$").test(pattern_to_store)) { }
1967                     else if (new RegExp("^\/.*\/$").test(pattern_to_store)) {
1968                         pattern_to_store = pattern_to_store + setting;
1969                     }
1970                     else if (!new RegExp("^/.*\/\\D$").test(pattern_to_store)) {
1971                         pattern_to_store = "/" + pattern_to_store + "/" + setting;
1972                     }
1973                     //test for breakages, try to cause error
1974                     var error_test = new RegExp(pattern_to_store.substring(0, pattern_to_store.lastIndexOf("/") + 1), pattern_to_store.substring(pattern_to_store.lastIndexOf("/") + 1));
1975                 }
1976                 catch (e) {
1977                     Generics.alert4ChanX("Unrecoverable Regex error on pattern " + pattern_input + " for " + pattern_to_store, "error", undefined);
1978                     continue;
1979                 }
1980                 pattern_to_store = encodeURIComponent(pattern_to_store);
1981                 var save_string = document.getElementById("Active" + pattern_input).checked + '=' + pattern_to_store + '=' + replacement_to_store;
1982                 window.localStorage.setItem(pattern_input + "FLT", save_string);
1983             }
1984             Generics.alert4ChanX("Wordfilters Updated!", "success", 3);
1985         }
1986     };
1987     SettingsWindow.prototype.storeImageAdderStates = function () {
1988         if (document.getElementById("SetImageAdderProperties") !== null) {
1989             var width = document.getElementById("width_DIA").value;
1990             localStorage.setItem("width_DIA", width);
1991             var height = document.getElementById("height_DIA").value;
1992             localStorage.setItem("height_DIA", height);
1993             var qr_width = document.getElementById("qr_width_DIA").value;
1994             localStorage.setItem("qr_width_DIA", qr_width);
1995         }
1996     };
1997     SettingsWindow.prototype.storeRebuildStates = function () {
1998         if (document.getElementById("setArchive") !== null) {
1999             localStorage.setItem("ArchiveType_FSE", document.getElementById("OffsiteArchive").checked === true ? "0" : "1");
2000         }
2001     };
2002     SettingsWindow.prototype.storeCharacterInserterStates = function () {
2003         if (document.getElementById("setCharacter") !== null) {
2004             localStorage.setItem("Kita_Character", document.getElementById("selectiveCharacters").value);
2005             localStorage.setItem("Kita_Color", document.getElementById("HexColorKita_text").value);
2006         }
2007         else if (document.getElementById("setQuote") !== null) {
2008             localStorage.setItem("Yen_Character", document.getElementById("quoteCharacter").value);
2009             localStorage.setItem("Yen_Color", document.getElementById("HexColorYen_text").value);
2010         }
2011     };
2012     SettingsWindow.prototype.storePasswordStates = function () {
2013         //password view settings
2014         if (document.getElementById("check-settings6") !== null)
2015             localStorage.setItem("PasswordActive", "" + document.getElementById("check-settings6").checked);
2016     };
2017     SettingsWindow.prototype.clearContainer = function () {
2018         var disposable = document.getElementById("disposable_container");
2019         if (disposable !== null)
2020             this.contents_div.removeChild(disposable);
2021         else
2022             this.contents_div.removeChild(this.ul_selection_start);
2023     };
2024     SettingsWindow.prototype.rebuildContainer = function () {
2025         this.contents_div.appendChild(this.ul_selection_start);
2026     };
2027     SettingsWindow.prototype.init = function () {
2028         var _this = this;
2029         this.settings_style.innerHTML = ".inputs{\n\t\t\t\t\t\t\t\t\t\t\tbackground-color:rgb(200,200,200);margin:5px 7px;width:100px;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t.SettingsBackground{\n\t\t\t\t\t\t\t\t\t\t\tposition:fixed;width:100%;height:100%;background-color:rgba(200,200,200,0.3);top:0;left:0; z-index:9\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t.settingsItem{\n\t\t\t\t\t\t\t\t\t\t\tfont-size:18px;list-style:katakana-iroha outside;padding:2px;color:#2e2345;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t.settingsItem input{\n\t\t\t\t\t\t\t\t\t\t\ttransform: scale(1.2);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t.settingsMain{\n\t\t\t\t\t\t\t\t\t\t\tborder:solid 1px black;position:fixed;background-color:rgb(200,200,200);left:40%;top:20%;margin-bottom:0; z-index:10\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t.closeIcon{\n\t\t\t\t\t\t\t\t\t\t\tborder:solid 1px black;position:absolute;width:25px;height:25px;background-color:rgba(255,100,90,0.9); right:3px;top:3px; z-index:10\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t.titleStyle{\n\t\t\t\t\t\t\t\t\t\t\tfont-size: 20px;padding: 12px 0px 9px 22px\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t.tooltip-4F{\n\t\t\t\t\t\t\t\t\t\t\tz-index:9;padding:5px;border:1px solid black;background-color:white;word-wrap:break-word;display:none;position:absolute;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t.help_icon{\n\t\t\t\t\t\t\t\t\t\t\theight:22.5px;margin:-4px 10px\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t.footerStyle{\n\t\t\t\t\t\t\t\t\t\t\tpadding-left: 12px;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t.contentStyle{\n\t\t\t\t\t\t\t\t\t\t\tbackground-color:white;margin:0 0;padding:5px 25px;\n\t\t\t\t\t\t\t\t\t\t}";
2030         this.background_div.setAttribute('class', 'SettingsBackground');
2031         this.background_div.setAttribute('id', 'SettingsBackground');
2032         this.background_div.setAttribute('style', 'display:none');
2033         this.settings_div.setAttribute('class', 'settingsMain');
2034         this.settings_div.setAttribute('id', 'settingsWindow');
2035         this.settings_div.setAttribute('style', 'display:none;width:500px');
2036         this.close_link.setAttribute('href', 'javascript:void(0)');
2037         this.close_div.setAttribute('class', 'closeIcon');
2038         this.close_div.addEventListener('click', function (evt) { return _this.hideWindow(); });
2039         this.title_para.setAttribute('class', 'titleStyle');
2040         this.contents_div.setAttribute('class', 'contentStyle');
2041         this.end_para.setAttribute('class', 'footerStyle');
2042         this.ul_selection_start.setAttribute("ID", "selection_list");
2043         this.generateList(this.contents_div);
2044     };
2045     SettingsWindow.prototype.generateList = function (head_node) {
2046         var _this = this;
2047         this.list_items.forEach(function (list_item, index) {
2048             var li = document.createElement('LI');
2049             li.setAttribute('class', 'settingsItem');
2050             if (list_item.Text.indexOf('View') > -1) {
2051                 var input = document.createElement('INPUT');
2052                 var input_id = 'check-settings' + index;
2053                 input.setAttribute('TYPE', 'checkbox');
2054                 input.setAttribute('ID', 'check-settings' + index);
2055                 li.appendChild(input);
2056                 input.addEventListener('click', function (evt) { return _this.storeActiveToggles(); });
2057                 var a = document.createElement('A');
2058                 a.setAttribute('href', 'javascript:void(0)');
2059                 a.textContent = list_item.Text;
2060                 var a_id = 'tab-settings' + index;
2061                 a.setAttribute('ID', 'tab-settings' + index);
2062                 var setup_func = function (_a_id) {
2063                     a.addEventListener('click', function (evt) { return list_item.ListenerFunc(_a_id); });
2064                     li.appendChild(a);
2065                     _this.ul_selection_start.appendChild(li);
2066                 };
2067                 setup_func(a_id);
2068             }
2069             else {
2070                 var input = document.createElement('INPUT');
2071                 var input_id = 'check-settings' + index;
2072                 input.setAttribute('TYPE', 'checkbox');
2073                 input.setAttribute('ID', 'check-settings' + index);
2074                 input.addEventListener('click', function (evt) { return _this.storeActiveToggles(); });
2075                 li.appendChild(input);
2076                 var label = document.createElement('LABEL');
2077                 label.textContent = list_item.Text;
2078                 li.appendChild(label);
2079                 _this.ul_selection_start.appendChild(li);
2080                 input.checked = _this.setting_items.password_settings == 'true';
2081                 var setup_func = function (input_id) {
2082                     label.addEventListener('click', function (evt) { return list_item.ListenerFunc(input_id); });
2083                 };
2084                 setup_func(input_id);
2085             }
2086         });
2087     };
2088     SettingsWindow.prototype.activate = function () {
2089         var _this = this;
2090         document.body.appendChild(this.settings_style);
2091         this.background_div.addEventListener('click', function (evt) { return _this.hideWindow(); });
2092         document.body.appendChild(this.background_div);
2093         this.settings_div.appendChild(this.close_link);
2094         this.close_link.appendChild(this.close_div);
2095         this.title_para.appendChild(this.title_text);
2096         this.settings_div.appendChild(this.title_para);
2097         this.settings_div.appendChild(this.contents_div);
2098         this.contents_div.appendChild(this.ul_selection_start);
2099         this.end_para.appendChild(this.end_text);
2100         this.settings_div.appendChild(this.end_para);
2101         document.body.appendChild(this.settings_div);
2102         this.retrieveActiveToggles();
2103     };
2104     SettingsWindow.prototype.decideAction = function (node) { };
2105     SettingsWindow.prototype.getSettingsArr = function () {
2106         return this.setting_items;
2107     };
2108     SettingsWindow.prototype.displayWindow = function () {
2109         this.background_div.style.display = 'block';
2110         this.settings_div.style.display = 'block';
2111         this.rebuildContainer();
2112     };
2113     SettingsWindow.prototype.hideWindow = function () {
2114         this.background_div.style.display = 'none';
2115         this.settings_div.style.display = 'none';
2116         this.clearContainer();
2117     };
2118     SettingsWindow.prototype.filterWindow = function (disposable_container) {
2119         var _this = this;
2120         var filter_table = document.createElement("table");
2121         filter_table.setAttribute("style", "text-align:center;");
2122         filter_table.setAttribute("id", "filter_table");
2123         disposable_container.appendChild(filter_table);
2124         var top_row = document.createElement("TR");
2125         filter_table.appendChild(top_row);
2126         var table_head_active = document.createElement("th");
2127         top_row.appendChild(table_head_active);
2128         var head_text_active = document.createTextNode("Active");
2129         table_head_active.appendChild(head_text_active);
2130         var table_head_pattern = document.createElement("th");
2131         top_row.appendChild(table_head_pattern);
2132         var headTextPattern = document.createTextNode("Pattern");
2133         table_head_pattern.appendChild(headTextPattern);
2134         var table_head_replacement = document.createElement("th");
2135         top_row.appendChild(table_head_replacement);
2136         var head_text_replacement = document.createTextNode("Replacement");
2137         table_head_replacement.appendChild(head_text_replacement);
2138         //Create the pattern table
2139         //loop to create rows
2140         var Number_of_Filters = parseInt(this.setting_items.word_replace_settings.Number_of_Filters);
2141         console.log(Number_of_Filters);
2142         if (Number_of_Filters === 0 || isNaN(Number_of_Filters))
2143             Number_of_Filters = 6;
2144         for (var i = 0; i < Number_of_Filters; i++) {
2145             var table_row_contents = document.createElement("tr");
2146             table_row_contents.setAttribute("id", "FilterRow" + i);
2147             var table_data_active = document.createElement("td");
2148             var table_checkbox_active = document.createElement("input");
2149             table_checkbox_active.setAttribute("type", "checkbox");
2150             table_checkbox_active.setAttribute("id", "Active" + i);
2151             table_data_active.appendChild(table_checkbox_active);
2152             table_row_contents.appendChild(table_data_active);
2153             var table_data_pattern = document.createElement("td");
2154             var table_input_pattern = document.createElement("input");
2155             table_input_pattern.setAttribute("class", "inputs");
2156             table_input_pattern.setAttribute("id", "Pattern" + i);
2157             table_data_pattern.appendChild(table_input_pattern);
2158             table_row_contents.appendChild(table_data_pattern);
2159             var table_data_replacement = document.createElement("td");
2160             var table_input_replacement = document.createElement("input");
2161             table_input_replacement.setAttribute("class", "inputs");
2162             table_input_replacement.setAttribute("id", "Replacement" + i);
2163             table_data_replacement.appendChild(table_input_replacement);
2164             table_row_contents.appendChild(table_data_replacement);
2165             filter_table.appendChild(table_row_contents);
2166         }
2167         var table_last_contents = document.createElement("tr");
2168         var table_add_collumn = document.createElement("td");
2169         var table_add_row_button = document.createElement("input");
2170         var table_subtract_row_button = document.createElement("input");
2171         table_subtract_row_button.setAttribute("type", "button");
2172         table_subtract_row_button.setAttribute("value", "-");
2173         table_subtract_row_button.setAttribute("style", "padding: 7px 0; margin:5px 0;");
2174         table_add_collumn.appendChild(table_subtract_row_button);
2175         table_subtract_row_button.addEventListener("click", function (evt) { return _this.filterRemoveRow(); });
2176         table_add_row_button.setAttribute("type", "button");
2177         table_add_row_button.setAttribute("value", "+");
2178         table_add_row_button.setAttribute("style", "padding: 7px 0; margin:5px 0;");
2179         table_add_collumn.appendChild(table_add_row_button);
2180         table_add_row_button.addEventListener("click", function (evt) { return _this.filterAddRow(); });
2181         table_last_contents.appendChild(table_add_collumn);
2182         var table_set_collumn = document.createElement("td");
2183         var table_confirm_button = document.createElement("input");
2184         table_confirm_button.setAttribute("type", "button");
2185         table_confirm_button.setAttribute("id", "table_confirm_button");
2186         table_confirm_button.setAttribute("value", "Set Replacements");
2187         table_confirm_button.setAttribute("style", "padding: 7px 0; margin:5px 0;");
2188         //event listeners
2189         table_confirm_button.addEventListener("click", function (evt) {
2190             _this.storeStates();
2191             _this.clearContainer();
2192             _this.rebuildContainer();
2193         });
2194         table_set_collumn.appendChild(table_confirm_button);
2195         table_last_contents.appendChild(table_set_collumn);
2196         var table_close_collumn = document.createElement("td");
2197         var table_close_button = document.createElement("input");
2198         table_close_button.setAttribute("type", "button");
2199         table_close_button.setAttribute("value", "Close Without Saving");
2200         table_close_button.setAttribute("style", "padding: 7px 0; margin:5px 0;");
2201         table_close_button.addEventListener("click", function (evt) {
2202             _this.clearContainer();
2203             _this.rebuildContainer();
2204         });
2205         table_close_collumn.appendChild(table_close_button);
2206         table_last_contents.appendChild(table_close_collumn);
2207         filter_table.appendChild(table_last_contents);
2208     };
2209     SettingsWindow.prototype.filterAddRow = function () {
2210         var _this = this;
2211         var filter_table = document.getElementById("filter_table");
2212         var Number_of_Filters = 0;
2213         var filter_children = document.getElementById("filter_table").firstChild;
2214         while (filter_children.nextSibling) {
2215             filter_children = filter_children.nextSibling;
2216             Number_of_Filters++;
2217         }
2218         var table_row_contents = document.createElement("tr");
2219         table_row_contents.setAttribute("id", "FilterRow" + (Number_of_Filters - 1));
2220         filter_table.removeChild(filter_children);
2221         var table_data_active = document.createElement("td");
2222         var table_checkbox_active = document.createElement("input");
2223         table_checkbox_active.setAttribute("type", "checkbox");
2224         table_checkbox_active.setAttribute("id", "Active" + (Number_of_Filters - 1));
2225         table_data_active.appendChild(table_checkbox_active);
2226         table_row_contents.appendChild(table_data_active);
2227         var table_data_pattern = document.createElement("td");
2228         var table_input_pattern = document.createElement("input");
2229         table_input_pattern.setAttribute("class", "inputs");
2230         table_input_pattern.setAttribute("id", "Pattern" + (Number_of_Filters - 1));
2231         table_data_pattern.appendChild(table_input_pattern);
2232         table_row_contents.appendChild(table_data_pattern);
2233         var table_data_replacement = document.createElement("td");
2234         var table_input_replacement = document.createElement("input");
2235         table_input_replacement.setAttribute("class", "inputs");
2236         table_input_replacement.setAttribute("id", "Replacement" + (Number_of_Filters - 1));
2237         table_data_replacement.appendChild(table_input_replacement);
2238         table_row_contents.appendChild(table_data_replacement);
2239         filter_table.appendChild(table_row_contents);
2240         var table_last_contents = document.createElement("tr");
2241         var table_add_collumn = document.createElement("td");
2242         var table_add_row_button = document.createElement("input");
2243         var table_subtract_row_button = document.createElement("input");
2244         table_subtract_row_button.setAttribute("type", "button");
2245         table_subtract_row_button.setAttribute("value", "-");
2246         table_subtract_row_button.setAttribute("style", "padding: 7px 0; margin:5px 0;");
2247         table_add_collumn.appendChild(table_subtract_row_button);
2248         table_subtract_row_button.addEventListener("click", function (evt) { return _this.filterRemoveRow(); });
2249         table_add_row_button.setAttribute("type", "button");
2250         table_add_row_button.setAttribute("value", "+");
2251         table_add_row_button.setAttribute("style", "padding: 7px 0; margin:5px 0;");
2252         table_add_collumn.appendChild(table_add_row_button);
2253         table_add_row_button.addEventListener("click", function (evt) { return _this.filterAddRow(); });
2254         table_last_contents.appendChild(table_add_collumn);
2255         var table_set_collumn = document.createElement("td");
2256         var table_confirm_button = document.createElement("input");
2257         table_confirm_button.setAttribute("type", "button");
2258         table_confirm_button.setAttribute("id", "table_confirm_button");
2259         table_confirm_button.setAttribute("value", "Set Replacements");
2260         table_confirm_button.setAttribute("style", "padding: 7px 0; margin:5px 0;");
2261         //event listeners
2262         table_confirm_button.addEventListener("click", function (evt) {
2263             _this.storeStates();
2264             _this.clearContainer();
2265             _this.rebuildContainer();
2266         });
2267         table_set_collumn.appendChild(table_confirm_button);
2268         table_last_contents.appendChild(table_set_collumn);
2269         var table_close_collumn = document.createElement("td");
2270         var table_close_button = document.createElement("input");
2271         table_close_button.setAttribute("type", "button");
2272         table_close_button.setAttribute("value", "Close Without Saving");
2273         table_close_button.setAttribute("style", "padding: 7px 0; margin:5px 0;");
2274         table_close_button.addEventListener("click", function (evt) {
2275             _this.clearContainer();
2276             _this.rebuildContainer();
2277         });
2278         table_close_collumn.appendChild(table_close_button);
2279         table_last_contents.appendChild(table_close_collumn);
2280         filter_table.appendChild(table_last_contents);
2281     };
2282     SettingsWindow.prototype.filterRemoveRow = function () {
2283         var filter_table = document.getElementById("filter_table");
2284         var Number_of_Filters = 0;
2285         var filter_children = document.getElementById("filter_table").firstChild;
2286         while (filter_children.nextSibling) {
2287             filter_children = filter_children.nextSibling;
2288             Number_of_Filters++;
2289         }
2290         if (Number_of_Filters != 2) {
2291             filter_table.deleteRow(--Number_of_Filters);
2292         }
2293     };
2294     SettingsWindow.prototype.filterSetTable = function () {
2295         var filter_length = this.setting_items.word_replace_settings.Number_of_Filters;
2296         for (var filter_count = 0; filter_count < filter_length; filter_count++) {
2297             if (this.setting_items.word_replace_settings.Text_Filter_List[filter_count].Active === null ||
2298                 this.setting_items.word_replace_settings.Text_Filter_List[filter_count].Regex === null ||
2299                 this.setting_items.word_replace_settings.Text_Filter_List[filter_count].Replacement === null)
2300                 return;
2301             if (this.setting_items.word_replace_settings.Text_Filter_List[filter_count].Active === "true") {
2302                 document.getElementById("Active" + filter_count).checked = true;
2303             }
2304             else {
2305                 document.getElementById("Active" + filter_count).checked = false;
2306             }
2307             document.getElementById("Pattern" + filter_count).value =
2308                 this.setting_items.word_replace_settings.Text_Filter_List[filter_count].Regex;
2309             document.getElementById("Replacement" + filter_count).value =
2310                 this.setting_items.word_replace_settings.Text_Filter_List[filter_count].Replacement;
2311         }
2312     };
2313     return SettingsWindow;
2314 }(FeatureInterface));
2315 var Main = /** @class */ (function (_super) {
2316     __extends(Main, _super);
2317     function Main() {
2318         var _this = _super.call(this) || this;
2319         _this.features = {}; /*;any bypasses dot notation issues on objects*/
2320         _this.settings = {};
2321         if (!Generics.storageAvailable('localStorage')) {
2322             alert("4F-FSE: local storage error");
2323             return _this;
2324         }
2325         else
2326             _this.activate();
2327         _this.retrieveStates();
2328         _this.init();
2329         _this.decideAction(document.getElementById('delform'));
2330         _this.observeEvents();
2331         return _this;
2332     }
2333     Main.prototype.retrieveStates = function () {
2334         var top_bar = new TopBar();
2335         top_bar.build();
2336         this.settings = top_bar.getSettingsArr();
2337     };
2338     Main.prototype.init = function () {
2339         if (this.settings.image_hiding_settings.Active === "true") {
2340             this.features.image_hider = new ImageHider();
2341         }
2342         if (this.settings.word_replace_settings.Active === "true") {
2343             this.features.text_replacer = new TextReplacer();
2344         }
2345         if (this.settings.image_adder_settings.Active === "true") {
2346             this.features.danbooru_image_adder = new DanbooruImageAdder();
2347         }
2348         if (this.settings.thread_rebuild_settings.Active === "true") {
2349             this.features.thread_rebuilder = new ThreadRebuilder();
2350         }
2351         if (this.settings.character_inserter_settings.Yen_Active === "true" || this.settings.character_inserter_settings.Kita_Active === "true") {
2352             this.features.character_inserter = new CharacterInserter(this.settings.character_inserter_settings.Yen_Active === "true", this.settings.character_inserter_settings.Kita_Active === "true");
2353         }
2354         if (this.settings.password_settings == 'true') {
2355             this.features.password_viewer = new PasswordViewer();
2356         }
2357         for (var feature_key in this.features)
2358             this.features[feature_key].retrieveStates();
2359     };
2360     Main.prototype.activate = function () { console.log("4F-FSE Starting"); };
2361     Main.prototype.storeStates = function () { };
2362     Main.prototype.observeEvents = function () {
2363         var _this = this;
2364         var document_changes = new MutationObserver(function (mutations) {
2365             mutations.forEach(function (mutation) {
2366                 [].forEach.call(mutation.addedNodes, function (node) { return _this.decideAction(node); });
2367             });
2368         }).observe(document.body, { childList: true, subtree: true });
2369     };
2370     Main.prototype.decideAction = function (node) {
2371         if (node === undefined || node.tagName === undefined)
2372             return;
2373         var start = node;
2374         var itterator = document.createNodeIterator(start, NodeFilter.SHOW_ELEMENT);
2375         var node;
2376         while ((node = itterator.nextNode())) {
2377             if (node.tagName !== "BLOCKQUOTE" && node.tagName !== "IMG" && node.tagName !== "VIDEO")
2378                 continue;
2379             for (var feature_key in this.features) {
2380                 this.features[feature_key].decideAction(node);
2381             }
2382         }
2383     };
2384     return Main;
2385 }(FeatureInterface));
2386 document.addEventListener('4chanXInitFinished', function () { new Main(); });