Mac image hide fix
[4Free-FSE.git] / builds / 4-Free.user.js
blob9fe346ba8489778b940faec9aee34692ba9306df
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.9
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,/9j/4AAQSkZJRgABAQEAYABgAAD/4QA6RXhpZgAATU0AKgAAAAgAA1EQAAEAAAABAQAAAFERAAQAAAABAAAAAFESAAQAAAABAAAAAAAAAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCABmAGQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD+f+iiigAruP2ff2aPiF+1d8QoPCfw18F+JPHHiK4AYWOjWEl1JEhZV82QqCIogWXdI5VFzksBzX6Uf8EQf+DYrxh/wUJstK+Jnxem1b4ffBq6jF1p8MKCPWvFqHGxrcOCLe1YfN9odWLgKI0ZX81P6HPD3hL9nP8A4I6/svTfY7fwL8E/hro5DTzyyC3+2ziM7fMlctPeXTpHgbmkmk2ADcQBQB+CP7J//BmB8evivZQX3xW8ceDfhHazxljY26HxFqtu/wDdkjheO2weOUun78ev238PP+DKL9nbR9JgHij4mfGPXtSj/wBbJYXOnaday/8AbJrWZ1/7+muQ/bX/AOD1HwB4D1O+0f4D/DfVPH0sO+KPxF4jnbSdNZw3yyRWqq1xNEw7SNbOD/D6/nx8Xf8Ag7f/AG0PiTqPn6N4r8F/D+PP/HvoHhW1mj/O/F0//j1AH6v6r/wZlfsm6haeXD4i+Ndi/wDz1g1+xZ//AB+yZf0rxH49/wDBkJ4N1KOab4X/AB08TaKyIxhs/FOiwamJm/hVp7drfYPVhC/+7X5uwf8AB0j+3VDOrN8cFlVWBKN4M0Da3scWIOD7EV9Efs6/8Hov7Q3w9vbSH4i+Bfhz8RtKhB897aOfQ9UuDxj98jSwKOD0tu/4UAfNn7b/APwbWftYfsPWF5q154Gj+IvhayQSTa14HlfVo4VwWYyWxRLtFRQS8hg8tf7+Oa+CK/rv/wCCd3/BzP8Asz/t+6rp/h2bXLr4V+PL9kgh0PxaY7aG/mbaNlreqxglJdwiI7RTSH7sRqf/AIK1f8G6HwT/AOCnWm6h4isbG2+GfxckzLH4r0azVY9TkyxI1G2Xat1u3cy5WcbU/eFF8tgD+QmivZv27v2BPid/wTh+P2pfDn4p6C2k6xaEy2d5CTLp2t2u4hLu0mwBLC+O4V0OUkSORWRfGaACiiigAr9gv+DYj/gg3a/txeMI/jr8YNBa6+EPhe9Meg6Rew4t/GWoRN8zOrf62xgcYcfcmlBiJZY54z+d3/BN39iLW/8Agot+2v4B+EOhySWjeKtQA1G/VA/9l6fEplu7nBIUmOBJCqkje+xM5YV/YJ+0N8afhb/wRt/4J333iD+zYtF+H/wl0GKw0bRrZ28y8dQsNpZoxDM0s0pRTK+45dpJDgO1AHmX/BZL/gtJ8Pf+CQHwYt59Qhh8SfEbxBAw8M+EreYRvcBflNzcMAfJtUbjdgs7AqgOHZP5Qv27f+ChXxY/4KQfGi68cfFfxRda5fM8n9n6fGTDpmhQsR/o9nb5KwxgKgJ5dygaR5HJc4/7aP7Y3jr9vf8AaS8TfFL4iakuoeJPE1yZTHCGW106AcRWlujFikESYRVJLYGWZnZmPllADoYXuZljjRpJJGCqqjLMT0AHrX3t+zP/AMGzX7Y/7Teg2ur23wtk8F6PeAmK58X38Wjy8HHzWrk3a56gtCARyCa/Yb/g2a/4IM+H/wBkn4LeH/jz8U/D8OpfGLxjZx6jolrqMAZfBVhKoeLy42+5fSoQ8kjASRKwhURnz/N/XDxH4l03wdod1qmr6hY6XptknmXF3eTrBBAv953YhVHuTQB/KL8Tf+DR79s3wDpf2jTfDHgnxnIOtvovii3jlA9f9L+zqcegJPpmvz9+O/7PPjv9l/4iXXhL4jeEPEXgnxLaLvk07WbCSznMZZlWVQ4G+NirbZFyjAZUkc1/cx8Kv2jPh78dnul8D+O/BvjJrHm5Gh61baibft8/ku238cVwP7fX/BO74V/8FKfgZeeA/in4dh1SzeOQ6bqcAWPVNAuGAAubOcgmOQFVJBDRyBQsiOhKkA/hzr9bv+CGP/Bzl40/Yg8RaH8M/jlqmreN/gq6x6fa6lOXutX8FKMLG8bcvcWaL8rW5y8aBTCf3fkS/AP/AAUZ/YO8Wf8ABNn9r3xZ8JPF+bq60CYSafqa27Qwa5YSDdb3kQJICunDKGby5FkjLFkavD6AP7W/+Cg//BP/AOEv/BZv9jaHQdYvNO1Cw1ezXV/BvjHS/Lu5NKlljDQ3ltIpAlhkUpvjDBZU4yrBHX+PT9s39j/xt+wZ+0r4p+FfxCsYbPxN4VuvIle3cyWt9EwDQ3Vu5Cl4ZYyroSqthsMqsGUfq5/waXf8FlLr4F/F+z/Zj+IesXEngbxxdsPBFxdTgx6DrErFjZKXI2QXjk7UUkC6ZdqZuZHH3F/wdqf8EurX9q/9jNvjh4Z0xX+InwXtWuL54Yh5uqeHtxe5jc4yfsrM10pLbUQXeAWkGAD+XGiiigD+g7/gyV/Y9htfC/xe+Pd/ArXV5cR+BNFkyQ0UcaxXt9kdCrs9gA3YwuO5rzP/AIPSv26ZvG/x98A/s96PqCto/gizXxT4hhifKvql0rx2scikZDw2m51IOCuonPIGP1I/4Nm/hNH8I/8Agil8F4Wt4YbzX7a/167kRcG4N1qFxJE7e4tzAmfRBX8x/wDwWc+Nd5+0H/wVb/aA8TXlyLzf421HTLWYEkPZ2MpsbXH0t7eIfhQB8y17x/wS9+BVj+0z/wAFGfgj4E1azj1DRfEnjTS7bVbWT7tzYi5R7mM/70KyD8a8Hr2r/gnZ+14n7BX7anw/+L8nhw+Ll8C37339kC/+wfbSYZIgvn+VLswZA2fLbO3HGcgA/uSr+N7/AILzf8FL/HH/AAUJ/b48fR6p4gv5Ph34J1670TwjoMU7Lp1na20rwC6EQwDcXG1pXkYM/wC8EYby441X9Ix/wfOf9Wu/+ZI/+9dfgr448Sf8Jl401jWPJNv/AGtezXnlF/MMfmSM+3dgZxnGcDPoKAJ/hx8SvEXwe8c6b4n8J65q/hnxHoswuLDVNLu5LS8s5ACN0csZDKcEjIPQkd6/tU/4JGftSeIv20/+CbHwf+J3i6PZ4o8UaCrarIIlhF3cwyPbyXIRQFQTNEZQqgKBIABgCv54P+COf/Brz8Tv+Cgcek+PPim2qfCn4P3SRXdtJJAE17xNA5DA2cMikQwsnIuZlKkPG0ccysSv9Rvwq+F2gfBD4Y+HvBvhXTYdH8M+FdOt9J0qxiZmS0tYI1jijDMSzbUUDLEscZJJJNAH4Nf8Hwvwc0uDUP2f/iDb2tvFrV1Hq/h6+uQv766t4zbXFshP92N5bsges5r8B6/ZT/g8o/bs0H4/fte+B/g/4avLfUYvg1Z3cmu3NvIzIuqXxgL2h/hZoIbeEkqTte4kQ4ZGUfjXQBZ0bWbzw5rFrqGn3VzY6hYzJcW1zbytFNbyowZHR1IKsrAEEEEEAiv7YP8Agl9+1nYf8FMf+Cavw6+ImsW1jqE3jXQGsPE1m9uot5b6IvaahGYSSBE80cpVGzmN06g1/EtX9J3/AAZLfHJvFH7G/wAYPh3JI0kng3xbb61GWct5UOo2ojCKCcKvmafK2AB80jHvQB+Cv/BQv9la4/Yi/bg+KXwpm+1ND4J8RXVhYS3IAmurHfvtJ2A4zJbPDJx/for7y/4PC/g5bfD/AP4K+f21YxM03j7wRpWu3pVT/ro3udOGffyrCL9KKAP6CP8AgivJDL/wSR/ZxNvt8v8A4V9pAOP74tUD/wDj2a/jd/amiuIP2nfiMl3u+1J4o1NZt33t4u5d2fxzX9YX/BsF8YYfi/8A8EVPhGPtUdxqHhX+0fD98q/8u7QX85hQ+/2Z7dv+BV/NP/wW6+CF1+zz/wAFbf2gvDd1HFDv8Z3utW8cYwsdtqLDULdR9IbqMfhQB8s0UUUAFfpN/wAGrP7FPg/9tH/gqXbr460+HWdD+G/hy68Yx6ZcRCW01G7iuLW2t0nU/eRHuvO29GaBVYFSyn82a/Yv/gyi/wCUlvxI/wCyZXf/AKddMoA/pxLbRk8AdTX4G/8ABaH/AIO3YtIl8QfC39lho7i6hkaw1D4kTBZIFwCJBpUXIf5sKLuT5flcxxuGjnH63f8ABWrVbjRf+CWn7R11aTSW9zD8M/ERjljYq8Z/s24GVI5BHYjkGv4h6ALWta1eeJNYu9R1G7ur/UL+Z7m5ubmVpZrmV2LPI7sSWZmJJYkkkkmqtFFABX7+/wDBjHnd+1F0248KZ/8AK1X4BV/S7/wZSfAV/Bn7DXxQ+IdxbyQTeOvF6abAzpgXFrp9spSRT3Xzry5T2MbUAeL/APB1vqOh2n/BQ/wauptCLg/DqxK7iM7f7T1TH65or5S/4PAfjFb/ABN/4LD3miwLtk+Hfg7SPD1wcEbnk87Ugff5NRQcelFAH1Z/wZM/tmW9hqPxa+AOpXSxyXxj8c6BEUC+a6rHaagNxPLbRYMqAZ2xyt0U1m/8Hpv7A9xpPjz4f/tIaJas2n6xbr4N8T+WiqsF1F5k1jcNj5mMsRniZj8qi1gXOXAr8df2Gv2u/Ef7Bn7W3gP4ueFcSax4J1RL37MzhE1C3YGO5tWba21Z4HliLAEqJCRyAa/si8RaN8Jf+CzH/BOqa1W6PiD4W/Gjw8GjuLd4/tNoSQyMPvpHd2lzGCVYN5c9uVYHaRQB/ELRXtv/AAUL/YK8df8ABNn9qnxF8K/H1lJHqGkv5+nagISlrr2nuzCC+tychopArA4JKSJJG2HjdR4lQAV9af8ABHr9sD9oD9iv9oDxJ4o/Z18CTePvFuoeHJNL1G0j8N3mu/ZbFrq2kabyrZgyfvYoV3t8vz46kV8l1+y3/Bk4f+NiPxQ/7JzN/wCnOwoAp/tTf8Fs/wDgoz8Yf2Z/iF4U8dfAW80fwT4k8Oahpuv35+GOr2YsbCa3eO4mM0jlItkTO29xtXGTwK/HWv7ev+CtJx/wSu/aV/7JZ4m/9NNzX8QtABRRRQBp+CvBmrfEfxlpPh3QdPutW1zXr2HTtOsbWMyT3tzM6xxRRqOWd3ZVAHUkV/bH+wj+zj4d/wCCWf8AwTc8FeBdW1SxsdH+Fnhh7zxHqryn7Kk4WS81K73MAVhM73EgyMqhA7V+NP8AwaT/APBFu88QeL7P9qz4laUsOjaT5kXw8027iJa+uSGjk1ZlPyiOIFkgyGLSF5Bs8mJn+hf+DvT/AIKmQ/s/fsz2v7OvhLUtvjT4qQrdeImgZlfS9CV/9WWUjD3cqeXj5gYYrhWAEiEgH89n7bf7TF9+2V+178SfipqC3EU3jzxDeavFBM+97O3klYwW+e4ih8uMe0Yory2igAr9SP8Ag3C/4Lyyf8Ey/iXJ8M/iVcTXXwN8aXomluQrSTeDr9sJ9tjVcl7ZwFE8QBYbVlj+ZXjn/LeigD+07/gpv/wTB+Ev/BZ39lez0XXrq0+1fZv7V8E+N9I8u6m0iSeNWSeF1O24tJlEfmQ7gkyBGVkkSKaP+Uf/AIKTf8Em/jN/wSy+J39h/Ezw7J/Yt7IV0fxPpwafRdbX5seVPgbZQFJaGQLKoAYrtZWb6K/4Ipf8HGXxF/4JXSWfgfxJb3fxE+CM135smhyT41Dw6JGzNLpsjnCgkmQ2zkRO+4qYXlklb+k79l79tv8AZ1/4K+fAe/j8I614R+JfhzULZBr3hbWLSKa5s1LZEd9p84LKPMQhWZDG5jyjOAGoA/iRr079lj9s74pfsSeMtQ8Q/CnxprHgfWtWsTpt3eacUEk9uZEkMZ3KeN8aHjn5a/oy/bS/4M3/ANn/AOO+p3WrfCnxN4l+C2qXTKxsY0/tzRE6lytvNIlwjMT2ufLXACxgcV+fvxS/4MvP2mvCl5cv4Z8ZfCLxZYI+IM6leWF5Kvq0clsY1+gmagD4r+In/Bb/APay+LPw/wBc8K+I/jn411bw94m0+40rVLGeSLyr21njaKaJ8IDtdGZTg9Ca+Va/UbQf+DQL9sbV9RWG40/4caXGxwbi68TK0a/URRu35LX0Z+zp/wAGRXjrVNQjm+LXxr8J6HaxygvaeEdNuNVkuY88qJ7kWwiYj+LypAD2NAH4XxRNPKscas8jkKqqMliegAr9sv8Agh5/wapeJvjXrGl/FD9p3R9Q8I+CbWVLjTfA9yGt9W1/GGDXq8PaWxPy+WcTyYfIiXY0n7Af8E+v+CC/7NP/AATb1C11jwP4J/tzxpaD934r8USrqmrxH5huhYqsNs212UtbxRFlOGLCvnj/AIK1f8HTPwd/YY0zU/CfwnudJ+MnxVEckSCxufO8O6FNtG1ru6jbE7KzcwW7FsxyI8kDYJAPpb/gqv8A8FSvhl/wRs/ZQj1jUodNfXprU6Z4H8GWOy3fU5YkVURI0AENnACnmSABY12qoMjxxv8Ax6/tLftHeMP2uvjx4o+JXj7V59c8XeML5r7ULuUnBYgKkaDPyRRxqkcaD5UjjRRgKBV/9q/9rj4iftvfGzVPiF8UPE1/4q8VaphHubghY7aJSSkEMagJDCu47Y0AUFicZJJ83oAKKKKACiiigAra+HfxJ8RfCHxpp/iTwnr2teF/EWkyebZappF9LZXtm+CN0c0TK6NgkZUg4JoooA/Sz9lD/g7n/au/Z7sbbTfFl34T+L2kwlE3eI9O8jUY4lUDal1atFuY4yZJ0mYnOSa+3vhn/wAHwng7UQq+Mv2f/E2jkYBfRvE8GpbvU7ZYLfHfjcfrRRQB2msf8HtfwKgsWbT/AIR/Fq6uscR3DafBGT/vLO5/8drwH44/8HwHjDVNNkg+GvwF8N6FeK58u98TeIJtWjdOMZt7eK2Knr0mNFFAH5q/tv8A/Bb39pv/AIKC2l5pvxB+KGsL4WvNyP4b0QLpOkPGWDeXLDBtNwoIBBuGlYY4NfJ9FFABRRRQAUUUUAf/2Q==";
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[91]) && 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[91]) && 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[91]) && listener_obj[75]) {
1528                 e.preventDefault();
1529                 _this.insertAtPos(node, _this.kita_character);
1530             }
1531             if ((listener_obj[17] || listener_obj[91]) && 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                     _this.storeStates();
1780                 } },
1781         ];
1782         _this.setting_items = {};
1783         _this.retrieveStates();
1784         _this.init();
1785         _this.activate();
1786         return _this;
1787     }
1788     SettingsWindow.prototype.setImageAdderFields = function () {
1789         document.getElementById("width_DIA").value = this.setting_items.image_adder_settings.Width;
1790         document.getElementById("height_DIA").value = this.setting_items.image_adder_settings.Height;
1791         document.getElementById("qr_width_DIA").value = this.setting_items.image_adder_settings.QR_Width;
1792         if (document.getElementById("width_DIA").value == "489")
1793             document.getElementById("v_large_DIA").checked = true;
1794         else if (document.getElementById("width_DIA").value == "400")
1795             document.getElementById("large_DIA").checked = true;
1796         else if (document.getElementById("width_DIA").value == "300")
1797             document.getElementById("medium_DIA").checked = true;
1798         else if (document.getElementById("width_DIA").value == "200")
1799             document.getElementById("small_DIA").checked = true;
1800     };
1801     SettingsWindow.prototype.setImageAdderEventListeners = function () {
1802         var _this = this;
1803         document.getElementById("v_large_DIA").addEventListener("click", function () {
1804             document.getElementById("width_DIA").value = "489";
1805             document.getElementById("height_DIA").value = "489";
1806         });
1807         document.getElementById("large_DIA").addEventListener("click", function () {
1808             document.getElementById("width_DIA").value = "400";
1809             document.getElementById("height_DIA").value = "400";
1810         });
1811         document.getElementById("medium_DIA").addEventListener("click", function () {
1812             document.getElementById("width_DIA").value = "300";
1813             document.getElementById("height_DIA").value = "300";
1814         });
1815         document.getElementById("small_DIA").addEventListener("click", function () {
1816             document.getElementById("width_DIA").value = "200";
1817             document.getElementById("height_DIA").value = "200";
1818         });
1819         document.getElementById("SetImageAdderProperties").addEventListener("click", function (evt) {
1820             _this.storeStates();
1821             _this.clearContainer();
1822             _this.rebuildContainer();
1823         });
1824     };
1825     //*...THIS
1826     SettingsWindow.prototype.retrieveStates = function () {
1827         //values used to fill out data fields
1828         this.setting_items.image_hiding_settings = { Expiration_Time: localStorage.getItem("Expiration_Time"), MD5_List_FSE: localStorage.getItem("MD5_List_FSE"), Active: localStorage.getItem("ImageHidingActive") };
1829         this.retrieveWordReplaceStates();
1830         this.retrieveImageAdderStates();
1831         this.retrieveRebuildStates();
1832         this.retrieveCharacterInsertingStates();
1833         this.setting_items.password_settings = (localStorage.getItem("PasswordActive"));
1834     };
1835     SettingsWindow.prototype.retrieveActiveToggles = function () {
1836         if (localStorage.getItem("4F-FSE") === null) {
1837             document.getElementById("check-settings0").checked = true;
1838             document.getElementById("check-settings1").checked = false;
1839             document.getElementById("check-settings2").checked = false;
1840             document.getElementById("check-settings3").checked = false;
1841             document.getElementById("check-settings4").checked = true;
1842             document.getElementById("check-settings5").checked = true;
1843             document.getElementById("check-settings6").checked = true;
1844             localStorage.setItem("4F-FSE", "Success");
1845             this.displayWindow();
1846             return;
1847         }
1848         document.getElementById("check-settings0").checked = localStorage.getItem("ImageHidingActive") === 'true';
1849         document.getElementById("check-settings1").checked = localStorage.getItem("TextReplaceActive") === 'true';
1850         document.getElementById("check-settings2").checked = localStorage.getItem("ImageAdderActive") === 'true';
1851         document.getElementById("check-settings3").checked = localStorage.getItem("ThreadRebuilderActive") === 'true';
1852         document.getElementById("check-settings4").checked = localStorage.getItem("YenActive") === 'true';
1853         document.getElementById("check-settings5").checked = localStorage.getItem("KitaActive") === 'true';
1854         document.getElementById("check-settings6").checked = localStorage.getItem("PasswordActive") === 'true';
1855     };
1856     SettingsWindow.prototype.retrieveWordReplaceStates = function () {
1857         //acquire text filter representation
1858         var storage_index = 0;
1859         var JSON_storage = {};
1860         var storage_key;
1861         var text_filters = [];
1862         var local_store_len = window.localStorage.length;
1863         while (storage_index < local_store_len) {
1864             storage_key = window.localStorage.key(storage_index);
1865             JSON_storage[storage_key] = window.localStorage.getItem(storage_key);
1866             storage_index++;
1867         }
1868         var filters = Generics.getJSONPropertiesByKeyName(JSON_storage, "[0-9]+FLT");
1869         filters.sort();
1870         filters.forEach(function (filter) {
1871             text_filters.push(TextReplacer.formatFilterSettings(JSON_storage[filter]));
1872         });
1873         this.setting_items.word_replace_settings = { Number_of_Filters: localStorage.getItem("filter_quantity"), Text_Filter_List: text_filters, Active: localStorage.getItem("TextReplaceActive") };
1874     };
1875     SettingsWindow.prototype.retrieveImageAdderStates = function () {
1876         this.setting_items.image_adder_settings = { Width: localStorage.getItem("width_DIA"),
1877             Height: localStorage.getItem("height_DIA"),
1878             QR_Width: localStorage.getItem("qr_width_DIA"),
1879             Active: localStorage.getItem("ImageAdderActive") };
1880         if (this.setting_items.image_adder_settings.Height === null)
1881             this.setting_items.image_adder_settings.Height = 400;
1882         if (this.setting_items.image_adder_settings.Width === null)
1883             this.setting_items.image_adder_settings.Width = 400;
1884         if (this.setting_items.image_adder_settings.QR_Width === null)
1885             this.setting_items.image_adder_settings.QR_Width = 480;
1886         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;}";
1887         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;}";
1888     };
1889     SettingsWindow.prototype.retrieveRebuildStates = function () {
1890         if (localStorage.getItem("ArchiveType_FSE") !== "1" && localStorage.getItem("ArchiveType_FSE") !== "0")
1891             localStorage.setItem("ArchiveType_FSE", "1");
1892         this.setting_items.thread_rebuild_settings = { Archive_Type: localStorage.getItem("ArchiveType_FSE"), Active: localStorage.getItem("ThreadRebuilderActive") };
1893     };
1894     SettingsWindow.prototype.retrieveCharacterInsertingStates = function () {
1895         if (localStorage.getItem("Yen_Character") === undefined || localStorage.getItem("Yen_Character") === null)
1896             localStorage.setItem("Yen_Character", "¥");
1897         if (localStorage.getItem("Yen_Color") === undefined || localStorage.getItem("Yen_Color") === null)
1898             localStorage.setItem("Yen_Color", "#9370DB");
1899         if (localStorage.getItem("Kita_Character") === undefined || localStorage.getItem("Kita_Character") === null)
1900             localStorage.setItem("Kita_Character", "キタ━━━(゚∀゚)━━━!!");
1901         if (localStorage.getItem("Kita_Color") === undefined || localStorage.getItem("Kita_Color") === null)
1902             localStorage.setItem("Kita_Color", "#444444");
1903         this.setting_items.character_inserter_settings = { Yen_Active: localStorage.getItem("YenActive"), Yen_Character: localStorage.getItem("Yen_Character"), Yen_Color: localStorage.getItem("Yen_Color"),
1904             Kita_Active: localStorage.getItem("KitaActive"), Kita_Character: localStorage.getItem("Kita_Character"), Kita_Color: localStorage.getItem("Kita_Color") };
1905     };
1906     SettingsWindow.prototype.storeStates = function () {
1907         //image settings
1908         this.storeImageFilterStates();
1909         //Text replace settings
1910         this.storeTextFilterStates();
1911         //Image Adder settings
1912         this.storeImageAdderStates();
1913         //Thread rebuild settings
1914         this.storeRebuildStates();
1915         //character inserter
1916         this.storeCharacterInserterStates();
1917         //Password replace settings
1918         this.storePasswordStates();
1919         this.retrieveStates();
1920     };
1921     SettingsWindow.prototype.storeActiveToggles = function () {
1922         localStorage.setItem("ImageHidingActive", (document.getElementById("check-settings0").checked.toString()));
1923         localStorage.setItem("TextReplaceActive", (document.getElementById("check-settings1").checked.toString()));
1924         localStorage.setItem("ImageAdderActive", (document.getElementById("check-settings2").checked.toString()));
1925         localStorage.setItem("ThreadRebuilderActive", (document.getElementById("check-settings3").checked.toString()));
1926         localStorage.setItem("YenActive", (document.getElementById("check-settings4").checked.toString()));
1927         localStorage.setItem("KitaActive", (document.getElementById("check-settings5").checked.toString()));
1928         localStorage.setItem("PasswordActive", (document.getElementById("check-settings6").checked.toString()));
1929     };
1930     SettingsWindow.prototype.storeImageFilterStates = function () {
1931         if (document.getElementById("Expiration_Time") !== null) {
1932             var time = document.getElementById("Expiration_Time");
1933             var millisecond_time = parseInt(time.value) * Constants.MILLISECONDS_TO_THE_HOUR;
1934             if (millisecond_time == 0 || millisecond_time === null || millisecond_time === undefined)
1935                 millisecond_time = Constants.DEFAULT_HIDE_EXPIRATION_TIME;
1936             localStorage.setItem("Expiration_Time", millisecond_time.toString());
1937             var md5_filters = document.getElementById("MD5_List_FSE").value;
1938             localStorage.setItem("MD5_List_FSE", md5_filters);
1939             Generics.alert4ChanX("Image Settings Saved", "success", 3);
1940         }
1941     };
1942     SettingsWindow.prototype.storeTextFilterStates = function () {
1943         if (document.getElementById("FilterRow0") !== null) {
1944             var f_row_moving = document.getElementById("FilterRow0");
1945             var Number_of_Filters = 0;
1946             var Number_of_Filters_actual = 0;
1947             while (f_row_moving.nextSibling !== null) {
1948                 if (document.getElementById("Pattern" + Number_of_Filters).value !== "")
1949                     Number_of_Filters_actual++;
1950                 Number_of_Filters++;
1951                 f_row_moving = f_row_moving.nextSibling;
1952             }
1953             window.localStorage.setItem("filter_quantity", Number_of_Filters_actual.toString());
1954             for (var pattern_input = 0; pattern_input < Number_of_Filters; pattern_input++) {
1955                 var pattern_to_store = document.getElementById("Pattern" + pattern_input).value;
1956                 var replacement_to_store = document.getElementById("Replacement" + pattern_input).value;
1957                 var setting = 'g';
1958                 try {
1959                     if (pattern_to_store === "") {
1960                         localStorage.removeItem(pattern_input + "FLT");
1961                         continue;
1962                     }
1963                     else if (new RegExp("^\/.*\/\\D+$").test(pattern_to_store)) { }
1964                     else if (new RegExp("^\/.*\/$").test(pattern_to_store)) {
1965                         pattern_to_store = pattern_to_store + setting;
1966                     }
1967                     else if (!new RegExp("^/.*\/\\D$").test(pattern_to_store)) {
1968                         pattern_to_store = "/" + pattern_to_store + "/" + setting;
1969                     }
1970                     //test for breakages, try to cause error
1971                     var error_test = new RegExp(pattern_to_store.substring(0, pattern_to_store.lastIndexOf("/") + 1), pattern_to_store.substring(pattern_to_store.lastIndexOf("/") + 1));
1972                 }
1973                 catch (e) {
1974                     Generics.alert4ChanX("Unrecoverable Regex error on pattern " + pattern_input + " for " + pattern_to_store, "error", undefined);
1975                     continue;
1976                 }
1977                 pattern_to_store = encodeURIComponent(pattern_to_store);
1978                 var save_string = document.getElementById("Active" + pattern_input).checked + '=' + pattern_to_store + '=' + replacement_to_store;
1979                 window.localStorage.setItem(pattern_input + "FLT", save_string);
1980             }
1981             Generics.alert4ChanX("Wordfilters Updated!", "success", 3);
1982         }
1983     };
1984     SettingsWindow.prototype.storeImageAdderStates = function () {
1985         if (document.getElementById("SetImageAdderProperties") !== null) {
1986             var width = document.getElementById("width_DIA").value;
1987             localStorage.setItem("width_DIA", width);
1988             var height = document.getElementById("height_DIA").value;
1989             localStorage.setItem("height_DIA", height);
1990             var qr_width = document.getElementById("qr_width_DIA").value;
1991             localStorage.setItem("qr_width_DIA", qr_width);
1992         }
1993     };
1994     SettingsWindow.prototype.storeRebuildStates = function () {
1995         if (document.getElementById("setArchive") !== null) {
1996             localStorage.setItem("ArchiveType_FSE", document.getElementById("OffsiteArchive").checked === true ? "0" : "1");
1997         }
1998     };
1999     SettingsWindow.prototype.storeCharacterInserterStates = function () {
2000         if (document.getElementById("setCharacter") !== null) {
2001             localStorage.setItem("Kita_Character", document.getElementById("selectiveCharacters").value);
2002             localStorage.setItem("Kita_Color", document.getElementById("HexColorKita_text").value);
2003         }
2004         else if (document.getElementById("setQuote") !== null) {
2005             localStorage.setItem("Yen_Character", document.getElementById("quoteCharacter").value);
2006             localStorage.setItem("Yen_Color", document.getElementById("HexColorYen_text").value);
2007         }
2008     };
2009     SettingsWindow.prototype.storePasswordStates = function () {
2010         //password view settings
2011         if (document.getElementById("check-settings6") !== null)
2012             localStorage.setItem("PasswordActive", "" + document.getElementById("check-settings6").checked);
2013     };
2014     SettingsWindow.prototype.clearContainer = function () {
2015         var disposable = document.getElementById("disposable_container");
2016         if (disposable !== null)
2017             this.contents_div.removeChild(disposable);
2018         else
2019             this.contents_div.removeChild(this.ul_selection_start);
2020     };
2021     SettingsWindow.prototype.rebuildContainer = function () {
2022         this.contents_div.appendChild(this.ul_selection_start);
2023     };
2024     SettingsWindow.prototype.init = function () {
2025         var _this = this;
2026         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}";
2027         this.background_div.setAttribute('class', 'SettingsBackground');
2028         this.background_div.setAttribute('id', 'SettingsBackground');
2029         this.background_div.setAttribute('style', 'display:none');
2030         this.settings_div.setAttribute('class', 'settingsMain');
2031         this.settings_div.setAttribute('id', 'settingsWindow');
2032         this.settings_div.setAttribute('style', 'display:none;width:500px');
2033         this.close_link.setAttribute('href', 'javascript:void(0)');
2034         this.close_div.setAttribute('class', 'closeIcon');
2035         this.close_div.addEventListener('click', function (evt) { return _this.hideWindow(); });
2036         this.title_para.setAttribute('class', 'titleStyle');
2037         this.contents_div.setAttribute('class', 'contentStyle');
2038         this.end_para.setAttribute('class', 'footerStyle');
2039         this.ul_selection_start.setAttribute("ID", "selection_list");
2040         this.generateList(this.contents_div);
2041     };
2042     SettingsWindow.prototype.generateList = function (head_node) {
2043         var _this = this;
2044         this.list_items.forEach(function (list_item, index) {
2045             var li = document.createElement('LI');
2046             li.setAttribute('class', 'settingsItem');
2047             if (list_item.Text.indexOf('View') > -1) {
2048                 var input = document.createElement('INPUT');
2049                 var input_id = 'check-settings' + index;
2050                 input.setAttribute('TYPE', 'checkbox');
2051                 input.setAttribute('ID', 'check-settings' + index);
2052                 li.appendChild(input);
2053                 input.addEventListener('click', function (evt) { return _this.storeActiveToggles(); });
2054                 var a = document.createElement('A');
2055                 a.setAttribute('href', 'javascript:void(0)');
2056                 a.textContent = list_item.Text;
2057                 var a_id = 'tab-settings' + index;
2058                 a.setAttribute('ID', 'tab-settings' + index);
2059                 var setup_func = function (_a_id) {
2060                     a.addEventListener('click', function (evt) { return list_item.ListenerFunc(_a_id); });
2061                     li.appendChild(a);
2062                     _this.ul_selection_start.appendChild(li);
2063                 };
2064                 setup_func(a_id);
2065             }
2066             else {
2067                 var input = document.createElement('INPUT');
2068                 var input_id = 'check-settings' + index;
2069                 input.setAttribute('TYPE', 'checkbox');
2070                 input.setAttribute('ID', 'check-settings' + index);
2071                 input.addEventListener('click', function (evt) { return _this.storeActiveToggles(); });
2072                 var label = document.createElement('LABEL');
2073                 label.appendChild(input);
2074                 var label_text = document.createTextNode(list_item.Text);
2075                 label.appendChild(label_text);
2076                 li.appendChild(label);
2077                 _this.ul_selection_start.appendChild(li);
2078                 input.checked = _this.setting_items.password_settings == 'true';
2079                 var setup_func = function (input_id) {
2080                     label.addEventListener('click', function (evt) { return list_item.ListenerFunc(input_id); });
2081                 };
2082                 setup_func(input_id);
2083             }
2084         });
2085     };
2086     SettingsWindow.prototype.activate = function () {
2087         var _this = this;
2088         document.body.appendChild(this.settings_style);
2089         this.background_div.addEventListener('click', function (evt) { return _this.hideWindow(); });
2090         document.body.appendChild(this.background_div);
2091         this.settings_div.appendChild(this.close_link);
2092         this.close_link.appendChild(this.close_div);
2093         this.title_para.appendChild(this.title_text);
2094         this.settings_div.appendChild(this.title_para);
2095         this.settings_div.appendChild(this.contents_div);
2096         this.contents_div.appendChild(this.ul_selection_start);
2097         this.end_para.appendChild(this.end_text);
2098         this.settings_div.appendChild(this.end_para);
2099         document.body.appendChild(this.settings_div);
2100         this.retrieveActiveToggles();
2101     };
2102     SettingsWindow.prototype.decideAction = function (node) { };
2103     SettingsWindow.prototype.getSettingsArr = function () {
2104         return this.setting_items;
2105     };
2106     SettingsWindow.prototype.displayWindow = function () {
2107         this.background_div.style.display = 'block';
2108         this.settings_div.style.display = 'block';
2109         this.rebuildContainer();
2110     };
2111     SettingsWindow.prototype.hideWindow = function () {
2112         this.background_div.style.display = 'none';
2113         this.settings_div.style.display = 'none';
2114         this.clearContainer();
2115     };
2116     SettingsWindow.prototype.filterWindow = function (disposable_container) {
2117         var _this = this;
2118         var filter_table = document.createElement("table");
2119         filter_table.setAttribute("style", "text-align:center;");
2120         filter_table.setAttribute("id", "filter_table");
2121         disposable_container.appendChild(filter_table);
2122         var top_row = document.createElement("TR");
2123         filter_table.appendChild(top_row);
2124         var table_head_active = document.createElement("th");
2125         top_row.appendChild(table_head_active);
2126         var head_text_active = document.createTextNode("Active");
2127         table_head_active.appendChild(head_text_active);
2128         var table_head_pattern = document.createElement("th");
2129         top_row.appendChild(table_head_pattern);
2130         var headTextPattern = document.createTextNode("Pattern");
2131         table_head_pattern.appendChild(headTextPattern);
2132         var table_head_replacement = document.createElement("th");
2133         top_row.appendChild(table_head_replacement);
2134         var head_text_replacement = document.createTextNode("Replacement");
2135         table_head_replacement.appendChild(head_text_replacement);
2136         //Create the pattern table
2137         //loop to create rows
2138         var Number_of_Filters = parseInt(this.setting_items.word_replace_settings.Number_of_Filters);
2139         console.log(Number_of_Filters);
2140         if (Number_of_Filters === 0 || isNaN(Number_of_Filters))
2141             Number_of_Filters = 6;
2142         for (var i = 0; i < Number_of_Filters; i++) {
2143             var table_row_contents = document.createElement("tr");
2144             table_row_contents.setAttribute("id", "FilterRow" + i);
2145             var table_data_active = document.createElement("td");
2146             var table_checkbox_active = document.createElement("input");
2147             table_checkbox_active.setAttribute("type", "checkbox");
2148             table_checkbox_active.setAttribute("id", "Active" + i);
2149             table_data_active.appendChild(table_checkbox_active);
2150             table_row_contents.appendChild(table_data_active);
2151             var table_data_pattern = document.createElement("td");
2152             var table_input_pattern = document.createElement("input");
2153             table_input_pattern.setAttribute("class", "inputs");
2154             table_input_pattern.setAttribute("id", "Pattern" + i);
2155             table_data_pattern.appendChild(table_input_pattern);
2156             table_row_contents.appendChild(table_data_pattern);
2157             var table_data_replacement = document.createElement("td");
2158             var table_input_replacement = document.createElement("input");
2159             table_input_replacement.setAttribute("class", "inputs");
2160             table_input_replacement.setAttribute("id", "Replacement" + i);
2161             table_data_replacement.appendChild(table_input_replacement);
2162             table_row_contents.appendChild(table_data_replacement);
2163             filter_table.appendChild(table_row_contents);
2164         }
2165         var table_last_contents = document.createElement("tr");
2166         var table_add_collumn = document.createElement("td");
2167         var table_add_row_button = document.createElement("input");
2168         var table_subtract_row_button = document.createElement("input");
2169         table_subtract_row_button.setAttribute("type", "button");
2170         table_subtract_row_button.setAttribute("value", "-");
2171         table_subtract_row_button.setAttribute("style", "padding: 7px 0; margin:5px 0;");
2172         table_add_collumn.appendChild(table_subtract_row_button);
2173         table_subtract_row_button.addEventListener("click", function (evt) { return _this.filterRemoveRow(); });
2174         table_add_row_button.setAttribute("type", "button");
2175         table_add_row_button.setAttribute("value", "+");
2176         table_add_row_button.setAttribute("style", "padding: 7px 0; margin:5px 0;");
2177         table_add_collumn.appendChild(table_add_row_button);
2178         table_add_row_button.addEventListener("click", function (evt) { return _this.filterAddRow(); });
2179         table_last_contents.appendChild(table_add_collumn);
2180         var table_set_collumn = document.createElement("td");
2181         var table_confirm_button = document.createElement("input");
2182         table_confirm_button.setAttribute("type", "button");
2183         table_confirm_button.setAttribute("id", "table_confirm_button");
2184         table_confirm_button.setAttribute("value", "Set Replacements");
2185         table_confirm_button.setAttribute("style", "padding: 7px 0; margin:5px 0;");
2186         //event listeners
2187         table_confirm_button.addEventListener("click", function (evt) {
2188             _this.storeStates();
2189             _this.clearContainer();
2190             _this.rebuildContainer();
2191         });
2192         table_set_collumn.appendChild(table_confirm_button);
2193         table_last_contents.appendChild(table_set_collumn);
2194         var table_close_collumn = document.createElement("td");
2195         var table_close_button = document.createElement("input");
2196         table_close_button.setAttribute("type", "button");
2197         table_close_button.setAttribute("value", "Close Without Saving");
2198         table_close_button.setAttribute("style", "padding: 7px 0; margin:5px 0;");
2199         table_close_button.addEventListener("click", function (evt) {
2200             _this.clearContainer();
2201             _this.rebuildContainer();
2202         });
2203         table_close_collumn.appendChild(table_close_button);
2204         table_last_contents.appendChild(table_close_collumn);
2205         filter_table.appendChild(table_last_contents);
2206     };
2207     SettingsWindow.prototype.filterAddRow = function () {
2208         var _this = this;
2209         var filter_table = document.getElementById("filter_table");
2210         var Number_of_Filters = 0;
2211         var filter_children = document.getElementById("filter_table").firstChild;
2212         while (filter_children.nextSibling) {
2213             filter_children = filter_children.nextSibling;
2214             Number_of_Filters++;
2215         }
2216         var table_row_contents = document.createElement("tr");
2217         table_row_contents.setAttribute("id", "FilterRow" + (Number_of_Filters - 1));
2218         filter_table.removeChild(filter_children);
2219         var table_data_active = document.createElement("td");
2220         var table_checkbox_active = document.createElement("input");
2221         table_checkbox_active.setAttribute("type", "checkbox");
2222         table_checkbox_active.setAttribute("id", "Active" + (Number_of_Filters - 1));
2223         table_data_active.appendChild(table_checkbox_active);
2224         table_row_contents.appendChild(table_data_active);
2225         var table_data_pattern = document.createElement("td");
2226         var table_input_pattern = document.createElement("input");
2227         table_input_pattern.setAttribute("class", "inputs");
2228         table_input_pattern.setAttribute("id", "Pattern" + (Number_of_Filters - 1));
2229         table_data_pattern.appendChild(table_input_pattern);
2230         table_row_contents.appendChild(table_data_pattern);
2231         var table_data_replacement = document.createElement("td");
2232         var table_input_replacement = document.createElement("input");
2233         table_input_replacement.setAttribute("class", "inputs");
2234         table_input_replacement.setAttribute("id", "Replacement" + (Number_of_Filters - 1));
2235         table_data_replacement.appendChild(table_input_replacement);
2236         table_row_contents.appendChild(table_data_replacement);
2237         filter_table.appendChild(table_row_contents);
2238         var table_last_contents = document.createElement("tr");
2239         var table_add_collumn = document.createElement("td");
2240         var table_add_row_button = document.createElement("input");
2241         var table_subtract_row_button = document.createElement("input");
2242         table_subtract_row_button.setAttribute("type", "button");
2243         table_subtract_row_button.setAttribute("value", "-");
2244         table_subtract_row_button.setAttribute("style", "padding: 7px 0; margin:5px 0;");
2245         table_add_collumn.appendChild(table_subtract_row_button);
2246         table_subtract_row_button.addEventListener("click", function (evt) { return _this.filterRemoveRow(); });
2247         table_add_row_button.setAttribute("type", "button");
2248         table_add_row_button.setAttribute("value", "+");
2249         table_add_row_button.setAttribute("style", "padding: 7px 0; margin:5px 0;");
2250         table_add_collumn.appendChild(table_add_row_button);
2251         table_add_row_button.addEventListener("click", function (evt) { return _this.filterAddRow(); });
2252         table_last_contents.appendChild(table_add_collumn);
2253         var table_set_collumn = document.createElement("td");
2254         var table_confirm_button = document.createElement("input");
2255         table_confirm_button.setAttribute("type", "button");
2256         table_confirm_button.setAttribute("id", "table_confirm_button");
2257         table_confirm_button.setAttribute("value", "Set Replacements");
2258         table_confirm_button.setAttribute("style", "padding: 7px 0; margin:5px 0;");
2259         //event listeners
2260         table_confirm_button.addEventListener("click", function (evt) {
2261             _this.storeStates();
2262             _this.clearContainer();
2263             _this.rebuildContainer();
2264         });
2265         table_set_collumn.appendChild(table_confirm_button);
2266         table_last_contents.appendChild(table_set_collumn);
2267         var table_close_collumn = document.createElement("td");
2268         var table_close_button = document.createElement("input");
2269         table_close_button.setAttribute("type", "button");
2270         table_close_button.setAttribute("value", "Close Without Saving");
2271         table_close_button.setAttribute("style", "padding: 7px 0; margin:5px 0;");
2272         table_close_button.addEventListener("click", function (evt) {
2273             _this.clearContainer();
2274             _this.rebuildContainer();
2275         });
2276         table_close_collumn.appendChild(table_close_button);
2277         table_last_contents.appendChild(table_close_collumn);
2278         filter_table.appendChild(table_last_contents);
2279     };
2280     SettingsWindow.prototype.filterRemoveRow = function () {
2281         var filter_table = document.getElementById("filter_table");
2282         var Number_of_Filters = 0;
2283         var filter_children = document.getElementById("filter_table").firstChild;
2284         while (filter_children.nextSibling) {
2285             filter_children = filter_children.nextSibling;
2286             Number_of_Filters++;
2287         }
2288         if (Number_of_Filters != 2) {
2289             filter_table.deleteRow(--Number_of_Filters);
2290         }
2291     };
2292     SettingsWindow.prototype.filterSetTable = function () {
2293         var filter_length = this.setting_items.word_replace_settings.Number_of_Filters;
2294         for (var filter_count = 0; filter_count < filter_length; filter_count++) {
2295             if (this.setting_items.word_replace_settings.Text_Filter_List[filter_count].Active === null ||
2296                 this.setting_items.word_replace_settings.Text_Filter_List[filter_count].Regex === null ||
2297                 this.setting_items.word_replace_settings.Text_Filter_List[filter_count].Replacement === null)
2298                 return;
2299             if (this.setting_items.word_replace_settings.Text_Filter_List[filter_count].Active === "true") {
2300                 document.getElementById("Active" + filter_count).checked = true;
2301             }
2302             else {
2303                 document.getElementById("Active" + filter_count).checked = false;
2304             }
2305             document.getElementById("Pattern" + filter_count).value =
2306                 this.setting_items.word_replace_settings.Text_Filter_List[filter_count].Regex;
2307             document.getElementById("Replacement" + filter_count).value =
2308                 this.setting_items.word_replace_settings.Text_Filter_List[filter_count].Replacement;
2309         }
2310     };
2311     return SettingsWindow;
2312 }(FeatureInterface));
2313 var Main = /** @class */ (function (_super) {
2314     __extends(Main, _super);
2315     function Main() {
2316         var _this = _super.call(this) || this;
2317         _this.features = {}; /*;any bypasses dot notation issues on objects*/
2318         _this.settings = {};
2319         if (!Generics.storageAvailable('localStorage')) {
2320             alert("4F-FSE: local storage error");
2321             return _this;
2322         }
2323         else
2324             _this.activate();
2325         _this.retrieveStates();
2326         _this.init();
2327         _this.decideAction(document.getElementById('delform'));
2328         _this.observeEvents();
2329         return _this;
2330     }
2331     Main.prototype.retrieveStates = function () {
2332         var top_bar = new TopBar();
2333         top_bar.build();
2334         this.settings = top_bar.getSettingsArr();
2335     };
2336     Main.prototype.init = function () {
2337         if (this.settings.image_hiding_settings.Active === "true") {
2338             this.features.image_hider = new ImageHider();
2339         }
2340         if (this.settings.word_replace_settings.Active === "true") {
2341             this.features.text_replacer = new TextReplacer();
2342         }
2343         if (this.settings.image_adder_settings.Active === "true") {
2344             this.features.danbooru_image_adder = new DanbooruImageAdder();
2345         }
2346         if (this.settings.thread_rebuild_settings.Active === "true") {
2347             this.features.thread_rebuilder = new ThreadRebuilder();
2348         }
2349         if (this.settings.character_inserter_settings.Yen_Active === "true" || this.settings.character_inserter_settings.Kita_Active === "true") {
2350             this.features.character_inserter = new CharacterInserter(this.settings.character_inserter_settings.Yen_Active === "true", this.settings.character_inserter_settings.Kita_Active === "true");
2351         }
2352         if (this.settings.password_settings == 'true') {
2353             this.features.password_viewer = new PasswordViewer();
2354         }
2355         for (var feature_key in this.features)
2356             this.features[feature_key].retrieveStates();
2357     };
2358     Main.prototype.activate = function () { console.log("4F-FSE Starting"); };
2359     Main.prototype.storeStates = function () { };
2360     Main.prototype.observeEvents = function () {
2361         var _this = this;
2362         var document_changes = new MutationObserver(function (mutations) {
2363             mutations.forEach(function (mutation) {
2364                 [].forEach.call(mutation.addedNodes, function (node) { return _this.decideAction(node); });
2365             });
2366         }).observe(document.body, { childList: true, subtree: true });
2367     };
2368     Main.prototype.decideAction = function (node) {
2369         if (node === undefined || node.tagName === undefined)
2370             return;
2371         var start = node;
2372         var itterator = document.createNodeIterator(start, NodeFilter.SHOW_ELEMENT);
2373         var node;
2374         while ((node = itterator.nextNode())) {
2375             if (node.tagName !== "BLOCKQUOTE" && node.tagName !== "IMG" && node.tagName !== "VIDEO")
2376                 continue;
2377             for (var feature_key in this.features) {
2378                 this.features[feature_key].decideAction(node);
2379             }
2380         }
2381     };
2382     return Main;
2383 }(FeatureInterface));
2384 document.addEventListener('4chanXInitFinished', function () { new Main(); });