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