rebrand as BandagedBD

This commit is contained in:
Zack Rauen 2018-02-05 17:48:19 -05:00
parent 80bedb0730
commit d60461023d
139 changed files with 45 additions and 13600 deletions

View File

@ -1,2 +0,0 @@
#BetterDiscord
BetterDiscord enhances Discord with several features

View File

@ -1,3 +0,0 @@
.guilds {
background:red !important;
}

View File

@ -1,199 +0,0 @@
var emotesTwitch = null, emotesTwitchSub = null, emotesFfz = null, emotesBttv = null, emotesBttv2 = null;
var twitchEmoteUrlStart = "https://static-cdn.jtvnw.net/emoticons/v1/";
var twitchEmoteUrlEnd = "/1.0";
var ffzEmoteUrlStart = "https://cdn.frankerfacez.com/emoticon/";
var ffzEmoteUrlEnd = "/1";
var bttvEmoteUrlStart = "https://cdn.betterttv.net/emote/";
var bttvEmoteUrlEnd = "/1x";
var _emoteModule;
function EmoteModule() {
}
EmoteModule.prototype.init = function() {
_emoteModule.loadEmoteData();
};
EmoteModule.prototype.obsCallback = function(mutation) {
var self = this;
for(var i = 0 ; i < mutation.addedNodes.length ; ++i) {
var next = mutation.addedNodes.item(i);
if (next) {
var nodes = self.getNodes(next);
for(var node in nodes) {
if (nodes.hasOwnProperty(node)) {
self.injectEmote(nodes[node]);
}
}
}
}
};
EmoteModule.prototype.getNodes = function(node) {
var next;
var nodes = [];
var treeWalker = document.createTreeWalker(node, NodeFilter.SHOW_TEXT, null, false);
while((next = treeWalker.nextNode()) != null) {
nodes.push(next);
}
return nodes;
};
EmoteModule.prototype.injectEmote = function(node) {
if (!node.parentElement) {
return;
}
var parent = node.parentElement;
if (parent.tagName != "SPAN") {
return;
}
if(!$(parent.parentElement).hasClass("markup") && !$(parent.parentElement).hasClass("message-content")) { return; }
var parentInnerHTML = parent.innerHTML;
var words = parentInnerHTML.split(/\s+/g);
if (!words) {
return;
}
words.some(function(word) {
if (word.length < 4) {
return;
}
if(emotesTwitch != null) {
if (emotesTwitch.emotes.hasOwnProperty(word)) {
var len = Math.round(word.length / 4);
parentInnerHTML = parentInnerHTML.replace(word, '<img class="emote" alt="' + word.substr(0, len) + "\uFDD9" + word.substr(len, len) + "\uFDD9" + word.substr(len * 2, len) + "\uFDD9" + word.substr(len * 3) + '" src="' + twitchEmoteUrlStart + emotesTwitch.emotes[word].image_id + twitchEmoteUrlEnd + '" />');
return;
}
}
if(emotesTwitchSub != null) {
if (emotesTwitchSub.hasOwnProperty(word)) {
var len = Math.round(word.length / 4);
parentInnerHTML = parentInnerHTML.replace(word, '<img class="emote" alt="' + word.substr(0, len) + "\uFDD9" + word.substr(len, len) + "\uFDD9" + word.substr(len * 2, len) + "\uFDD9" + word.substr(len * 3) + '" src="' + twitchEmoteUrlStart + emotesTwitchSub[word] + twitchEmoteUrlEnd + '" />');
return;
}
}
if(emotesFfz != null) {
if(emotesFfz.hasOwnProperty(word)) {
var len = Math.round(word.length / 4);
parentInnerHTML = parentInnerHTML.replace(word, '<img class="emote" alt="' + word.substr(0, len) + "\uFDD9" + word.substr(len, len) + "\uFDD9" + word.substr(len * 2, len) + "\uFDD9" + word.substr(len * 3) + '" src="' + ffzEmoteUrlStart + emotesFfz[word] + ffzEmoteUrlEnd + '" />');
return;
}
}
if(emotesBttv != null) {
if(emotesBttv.hasOwnProperty(word)) {
var len = Math.round(word.length / 4);
parentInnerHTML = parentInnerHTML.replace(word, '<img class="emote" alt="' + word.substr(0, len) + "\uFDD9" + word.substr(len, len) + "\uFDD9" + word.substr(len * 2, len) + "\uFDD9" + word.substr(len * 3) + '" src="' + bttvEmoteUrlStart + emotesBttv[word] + bttvEmoteUrlEnd + '" />');
return;
}
}
if(emotesBttv2 != null) {
if(emotesBttv2.hasOwnProperty(word)) {
var len = Math.round(word.length / 4);
parentInnerHTML = parentInnerHTML.replace(word, '<img class="emote" alt="' + word.substr(0, len) + "\uFDD9" + word.substr(len, len) + "\uFDD9" + word.substr(len * 2, len) + "\uFDD9" + word.substr(len * 3) + '" src="' + bttvEmoteUrlStart + emotesBttv2[word] + bttvEmoteUrlEnd + '" />');
return;
}
}
});
parent.innerHTML = parentInnerHTML.replace(new RegExp("\uFDD9", "g"), "");
};
EmoteModule.prototype.loadEmoteData = function(type) {
if(_hash == null) {
_utils.getHash(this.loadEmoteData);
return;
}
switch(type) {
default:
_emoteModule.loadEmoteData("twitch");
break;
case "twitch":
_utils.log("Loading twitch global emotes");
$.getJSON('https://twitchemotes.com/api_cache/v2/global.json', function(data) {
_utils.log("Loaded twitch global emotes");
emotesTwitch = data;
_emoteModule.loadEmoteData("twitch-sub");
});
break;
case "twitch-sub":
emotesTwitchSub = {};
_utils.log("Loading twitch subscriber emotes");
$.getJSON('https://twitchemotes.com/api_cache/v2/subscriber.json', function(data) {
$.each(data.channels, function(key, val){
$.each(val.emotes, function(key, val) {
emotesTwitchSub[val.code] = val.image_id;
});
});
_emoteModule.loadEmoteData("ffz");
});
break;
case "ffz":
emotesFfz = {};
_utils.log("Loading FFZ emotes");
$.getJSON('https://cdn.rawgit.com/Jiiks/BetterDiscordApp/'+_hash+'/data/emotedata_ffz.json', function(data) {
emotesFfz = data;
_emoteModule.loadEmoteData("bttv");
});
break;
case "bttv":
emotesBttv = {};
_utils.log("Loading Basic BTTV emotes");
$.getJSON('https://api.betterttv.net/2/emotes', function(data) {
$.each(data.emotes, function(key, val) {
emotesBttv[val.code] = val.id;
});
_emoteModule.loadEmoteData("bttv2");
});
break;
case "bttv2":
emotesBttv2 = {};
_utils.log("Loading BTTV emotes");
$.getJSON('https://cdn.rawgit.com/Jiiks/BetterDiscordApp/'+_hash+'/data/emotedata_bttv.json', function(data) {
emotesBttv2 = data;
});
break;
}
};
var _utils;
var _hash = null;
function Utils() {}
Utils.prototype.getHash = function(callback) {
_utils.log("Getting HASH");
$.getJSON("https://api.github.com/repos/Jiiks/BetterDiscordApp/commits/master", function(data){
_hash = data.sha;
_utils.log("HASH = " + _hash);
callback();
});
};
Utils.prototype.log = function(message) {
console.log("[BetterDiscord] - " + message);
};
(function() {
_utils = new Utils();
_emoteModule = new EmoteModule();
_emoteModule.init();
var mainObserver = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
_emoteModule.obsCallback(mutation);
});
});
mainObserver.observe(document, { childList: true, subtree: true });
})();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1,14 +0,0 @@
"use sctrict"
var pageMod = require('sdk/page-mod');
var data = require("sdk/self").data;
function BdPageMod(options, callbacks) {
pageMod.PageMod({
include: '*.discordapp.com',
contentScriptFile: [data.url('../data/js/jquery-2.1.4.min.js'), data.url('../data/js/main.js')],
contentStyleFile: []
});
}
exports.BdPageMod = BdPageMod;

View File

@ -1,9 +0,0 @@
"use strict"
var _bdPagemod = require('./BdPageMod.js');
function BetterDiscord(args) {
_bdPagemod = new _bdPagemod.BdPageMod();
}
exports.BetterDiscord = BetterDiscord;

View File

@ -1,9 +0,0 @@
"use strict";
var _betterDiscord = require("./BetterDiscord.js");
function main(options, callbacks) {
_betterDiscord = new _betterDiscord.BetterDiscord();
}
exports.main = main;

View File

@ -1,18 +0,0 @@
{
"title": "BetterDiscord",
"name": "betterdiscord",
"version": "0.0.3",
"description": "BetterDiscord enhances Discord with several features",
"main": "lib/main",
"author": "JiCode",
"engines": {
"firefox": ">=40.*"
},
"license": "MIT",
"keywords": [
"jetpack"
],
"installs_allowed_from": [
"https://betterdiscord.net"
]
}

View File

@ -1,19 +0,0 @@
var main = require("../");
exports["test main"] = function(assert) {
assert.pass("Unit test running!");
};
exports["test main async"] = function(assert, done) {
assert.pass("async Unit test running!");
done();
};
exports["test dummy"] = function(assert, done) {
main.dummy("foo", function(text) {
assert.ok((text === "foo"), "Is the text actually 'foo'");
done();
});
};
require("sdk/test").run(exports);

View File

@ -1,46 +0,0 @@
module.exports = function(grunt) {
grunt.initConfig({
sass: {
dist: {
options: {
style: 'expanded'
},
files: {
'dev/css/main.css': 'dev/css/main.sass'
}
}
},
concat: {
js: {
src: 'dev/js/*.js',
dest: 'js/main.js'
},
css: {
src: 'dev/css/*.css',
dest: 'css/main.css'
}
},
uglify: {
options: {
screwIE8: true
},
js: {
files: {
'js/main.min.js': ['js/main.js']
}
}
},
cssmin: {
css: {
src: 'css/main.css',
dest: 'css/main.min.css'
}
}
});
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-css');
grunt.registerTask('default', ['sass', 'concat', 'uglify', 'cssmin']);
};

View File

@ -1,3 +0,0 @@
dist/
pack.bat
run.bat

View File

@ -1,20 +0,0 @@
{
"name": "betterdiscordinstaller",
"description": "Better Discord installer.",
"version": "0.1.1",
"homepage": "https://github.com/Jiiks/BetterDiscordApp",
"license": "MIT",
"main": "index.js",
"dependencies": {
"fs-extra": "^0.30.0",
"readline": "^1.3.0",
"open": "^0.0.5",
"request": "^2.72.0",
"path": "^0.12.7",
"walk": "^2.3.9",
"unzip": "^0.1.11"
},
"devDependencies": {
"electron-prebuilt": "~1.2.8"
}
}

View File

@ -1,71 +0,0 @@
'use strict';
const
fs = require('fs'),
path = require('path'),
walk = require('walk'),
p = require('path');
fs.mkdirPSync = function(dirPath) {
try {
fs.mkdirSync(dirPath);
} catch(err) {
if(err.errno === -4058 || err.errno === -2) {
fs.mkdirPSync(path.dirname(dirPath));
fs.mkdirPSync(dirPath);
} else if(err.errno === -4075) {
return "EXIST";
} else {
return "NOT OK";
}
}
return "OK";
}
class Asar {
constructor(filePath) {
this.path = filePath;
this.files = [];
}
extract(statusCb, progressCb, cb) {
this.walker = walk.walk(this.path, { followLinks: false });
statusCb("Creating Directories");
this.walker.on('file', (root, stat, next) => {
this.files.push(`${root}/${stat.name}`);
try {
fs.statSync(root.replace("app.asar", "app"));
} catch(err) {
fs.mkdirPSync(root.replace("app.asar", "app"));
}
next();
});
this.walker.on('end', () => {
var self = this;
statusCb("Copying files");
var p = 1;
var filecount = this.files.length;
function copy(files, index) {
if(index >= filecount) {
statusCb("Finished extracting app package");
cb(null);
return;
}
setTimeout(() => { self.copyfile(files, index, copy) }, 1);
progressCb(index, filecount);
}
copy(this.files, 0);
});
}
copyfile(files, index, cb) {
fs.writeFileSync(files[index].replace("app.asar", "app"), fs.readFileSync(files[index]));
cb(files, index+1);
}
}
module.exports = Asar;

View File

@ -1,650 +0,0 @@
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
src:local('Open Sans'), local('OpenSans'), url('../font/OpenSans-Regular.ttf') format('TrueType');
}
/* latin-ext */
@font-face {
font-family: 'Inconsolata';
font-style: normal;
font-weight: 400;
src: local('Inconsolata'), url('../font/Inconsolata.woff2') format('woff2');
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Inconsolata';
font-style: normal;
font-weight: 400;
src: local('Inconsolata'), url('../font/Inconsolata.woff2') format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
html, body {
margin:0;
padding:0;
background: rgba(34, 35, 42, 1);
overflow: hidden;
}
html, body {
width:800px;
height:400px;
}
* {
font-family: "Open Sans";
color:#E8E8E8;
outline:none;
user-select: none;
-webkit-user-select: none;
cursor: default;
}
a {
cursor: pointer;
color: dodgerblue;
}
#titleBar {
display:flex;
-webkit-app-region: drag;
pointer-events: none;
width:100%;
height:40px;
background:rgba(34, 35, 42, 0.6);
border-bottom:1px solid #000;
box-shadow:0 1px 0 0 #303030;
background: rgba(23, 23, 23, 0.6);
border:none;
box-shadow: none;
}
#titleBar h3 {
color:#FFF;
}
.icon {
display:inline-block;
width:40px;
height:40px;
padding:5px;
}
.icon-image {
background:blue;
height:30px;
width:30px;
}
.title {
display:inline-block;
height:40px;
line-height:40px;
color:#FFF;
}
.main-container {
display:flex;
width:100%;
height:calc(100% - 40px);
}
.sidebar {
width:200px;
height:358px;
border-right:1px solid #000;
box-shadow:1px 0 0 0 #303030;
background:rgba(44, 45, 56, 0.6);
z-index:90001;
margin-top: 1px;
border:none;
margin:0;
box-shadow: none;
margin-left:1px;
}
.sidebar-inner {
width:100%;
height:100%;
padding:5px;
}
.main {
flex-grow:1;
padding:5px;
transform:translateX(0);
}
.panel-container {
position:absolute;
left:10px;
transition: all 0.5s ease-in-out;
}
.panel {
display:inline-block;
width:580px;
position:absolute;
transition: all 0.5s ease-in-out;
opacity: 0;
}
.main-container.panel-0 #uninstall {
display: inline-block;
}
.main-container.panel-0 #back {
display: none;
}
.main-container.panel-0 #next {
display: inline-block;
}
.main-container.panel-0 #cancel {
display: inline-block;
}
.main-container.panel-1 #uninstall {
display: none;
}
.main-container.panel-1 #back {
display: inline-block;
}
.main-container.panel-1 #next {
display: inline-block;
}
.main-container.panel-1 #cancel {
display: inline-block;
}
.main-container.panel-2 #uninstall {
display: none;
}
.main-container.panel-2 #back {
display: inline-block;
}
.main-container.panel-2 #next {
display: inline-block;
}
.main-container.panel-2 #cancel {
display: inline-block;
}
.main-container.panel-3 #uninstall {
display: none;
}
.main-container.panel-3 #back {
display: none;
}
.main-container.panel-3 #next {
display: none;
}
.main-container.panel-3 #cancel {
display: inline-block;
}
.main-container.panel-0 #li-0:before {
background:dodgerblue;
}
.main-container.panel-0 #li-1:before {
background:gray;
}
.main-container.panel-0 #li-2:before {
background:gray;
}
.main-container.panel-0 #li-3:before {
background:gray;
}
.main-container.panel-1 #li-0:before {
background:#00D443;
}
.main-container.panel-1 #li-1:before {
background:dodgerblue;
}
.main-container.panel-1 #li-2:before {
background:gray;
}
.main-container.panel-1 #li-3:before {
background:gray;
}
.main-container.panel-2 #li-0:before,
.main-container.panel-advanced #li-0:before {
background:#00D443;
}
.main-container.panel-2 #li-1:before,
.main-container.panel-advanced #li-1:before {
background:#00D443;
}
.main-container.panel-2 #li-2:before,
.main-container.panel-advanced #li-2:before {
background:dodgerblue;
}
.main-container.panel-2 #li-3:before,
.main-container.panel-advanced #li-3:before {
background:gray;
}
.main-container.panel-2 #panel-advanced {
pointer-events: none;
}
.main-container.panel-3 #li-0:before {
background:#00D443;
}
.main-container.panel-3 #li-1:before {
background:#00D443;
}
.main-container.panel-3 #li-2:before {
background:#00D443;
}
.main-container.panel-3 #li-3:before {
background:dodgerblue;
}
.main-container.panel-0 .panel-container {
left: 10px;
}
.main-container.panel-1 .panel-container {
left: -590px;
}
.main-container.panel-2 .panel-container,
.main-container.panel-advanced .panel-container {
left: -1180px;
}
.main-container.panel-3 .panel-container {
left: -1770px;
}
.main-container.panel-0 .panel-container #panel-0 {
opacity: 1;
}
.main-container.panel-0 .panel-container #panel-1 {
opacity: 0;
}
.main-container.panel-0 .panel-container #panel-2 {
opacity: 0;
}
.main-container.panel-0 .panel-container #panel-3 {
opacity: 0;
}
.main-container.panel-1 .panel-container #panel-0 {
opacity: 0;
}
.main-container.panel-1 .panel-container #panel-1 {
opacity: 1;
}
.main-container.panel-1 .panel-container #panel-2 {
opacity: 0;
}
.main-container.panel-1 .panel-container #panel-3 {
opacity: 0;
}
.main-container.panel-2 .panel-container #panel-0 {
opacity: 0;
}
.main-container.panel-2 .panel-container #panel-1 {
opacity: 0;
}
.main-container.panel-2 .panel-container #panel-2 {
opacity: 1;
}
.main-container.panel-2 .panel-container #panel-3 {
opacity: 0;
}
.main-container.panel-3 .panel-container #panel-0 {
opacity: 0;
}
.main-container.panel-3 .panel-container #panel-1 {
opacity: 0;
}
.main-container.panel-3 .panel-container #panel-2 {
opacity: 0;
}
.main-container.panel-3 .panel-container #panel-3 {
opacity: 1;
}
.main-container.panel-advanced .controls button {
display: none;
}
.main-container.panel-advanced #panel-advanced {
pointer-events: initial;
}
.main-container.panel-advanced .panel-container #panel-0 {
opacity: 0;
}
.main-container.panel-advanced .panel-container #panel-1 {
opacity: 0;
}
.main-container.panel-advanced .panel-container #panel-2 {
opacity: 0;
}
.main-container.panel-advanced .panel-container #panel-3 {
opacity: 0;
}
.main-container.panel-advanced .panel-container #panel-advanced {
opacity: 1;
}
.main-container .panel-container #panel-advanced textarea {
background: rgba(33, 34, 41, 0.98);
width: 570px;
height: 140px;
resize: none;
border: 1px solid #000;
outline: 1px solid #303030;
}
.main-container .panel-container #panel-advanced button {
float: right;
margin-right: 10px;
margin-top: 5px;
}
.visible {
opacity: 1;
}
#panel-1 {
left:600px;
}
#panel-2 {
left:1200px;
}
#panel-advanced {
left:1200px;
}
#panel-3 {
left:1775px;
}
#licensetext {
width: 100%;
overflow-y: scroll;
white-space: pre-line;
height:280px;
}
#licenseform {
float:right;
margin-top:5px;
margin-right:10px;
}
input[type='radio'] {
cursor:pointer;
}
label {
cursor:pointer;
}
label, input[type='radio']{
font-size: 16px;
display: inline-block;
margin: 0;
margin-left: 3px;
line-height: 25px;
height: 28px;
vertical-align: top;
}
ul {
margin:0;
padding:0;
list-style:none;
}
li {
list-style:none;
color:gray;
}
li.active {
color:#FFF;
}
li.visited {
color:#EBEBEB;
}
.sidebar-inner li:before {
content: "";
display:inline-block;
background:gray;
border-radius: 50%;
width: 10px;
height: 10px;
margin-right:3px;
}
.sidebar-inner li.active:before {
background:dodgerblue;
}
.sidebar-inner li.visited:before {
background:#00D443;
}
.controls {
position:absolute;
bottom:5px;
right:5px;
}
button {
color:gray;
width:60px;
background:#1b1c23;
border-style:solid;
border-color:#000;
border-width:0 1px 1px 0;
padding:5px;
box-shadow:1px 1px 0 0 #303030 inset;
cursor:pointer;
border: none;
box-shadow: none;
}
button:hover {
color:#FFF;
background:#24262f;
}
button:disabled {
background:#292929;
border-color:#191919;
color:gray;
cursor: not-allowed;
}
button:active {
background: #232b2e;
}
button#advanced-settings {
width: 100px;
display: block;
}
::-webkit-scrollbar-thumb {
background:#282828 !important;
}
::-webkit-scrollbar, ::-webkit-scrollbar-track-piece {
background:#383838 !important;
}
input.path {
width: 450px;
height: 23px;
background: rgb(27, 28, 35) none repeat scroll 0% 0%;
border: 1px solid rgb(17, 17, 17);
box-shadow: -1px -1px 0px 0px rgb(50, 49, 49) inset;
border-width: 1px 0px 0px 1px;
border-style: solid;
border-color: #111;
}
.modal {
position: absolute;
background: rgba(29, 29, 29, 0.71);
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 900000;
}
.modal-container {
background: #212229;
width: 600px;
height: 200px;
position: relative;
margin: auto;
top: 100px;
box-shadow: 0px 0px 5px 5px rgba(0, 0, 0, 0.39);
}
.modal-header {
height: 30px;
line-height: 30px;
background: #212229;
padding-left: 10px;
border-bottom: 1px solid #000;
box-shadow: 0 1px 0 0 #303030;
}
.modal-body {
padding:30px;
}
.modal-footer {
position: absolute;
bottom: 0;
left:0;
right: 0;
height: 35px;
padding-top:10px;
background:#212229;
box-shadow: 0 1px 0 0 #303030 inset;
border-top: 1px solid #000;
}
.modal-footer button {
margin-right:5px;
float: right;
}
.splash {
width:300px !important;
height:100px !important;
}
.splash .wrapper {
top:20px;
width:40px;
margin:auto;
position:relative;
}
.splash .wrapper .spinner {
width:30px;
height:30px;
border-radius:30px;
border-width:5px;
border-color:#121212 #404040 #404040 #404040;
border-style:solid;
animation: spin 0.7s linear infinite;
}
.splash .spinnertext {
position: absolute;
bottom: 0;
width: 100%;
display: block;
text-align: center;
bottom: 10px;
color: rgb(171, 171, 171);
-webkit-animation: spinnertext-opacity 2s linear 0s infinite;
}
@-webkit-keyframes spin {
100% {
transform: rotate(360deg);
}
}
@-webkit-keyframes spinnertext-opacity {
0% {opacity: 0}
20% {opacity: 0}
50% {opacity: 1}
100%{opacity: 0}
}
#log {
padding: 10px;
height:294px;
resize: none;
width: 570px;
background: rgba(42, 44, 55, 0.6);
border: none;
-webkit-user-select: text;
word-wrap: break-word;
white-space: pre-line;
overflow: auto;
}
progress {
position: absolute;
bottom: -36px;
left:0;
width:525px;
height: 27px;
-webkit-appearance:none;
}
progress::-webkit-progress-bar {
background:rgba(42, 44, 55, 0.6);
}
progress[value]::-webkit-progress-value {
background-image: -webkit-linear-gradient(left, rgba(73,155,234,1) 0%, rgba(32,124,229,1) 100%);
}
.border {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
border:1px solid #55BBF7;
pointer-events: none;
}
.warning {
color: red;
font-weight: 700;
}

View File

@ -1,36 +0,0 @@
<html>
<head>
<head>
<link rel="stylesheet" href="css/main.css">
<script type="text/javascript" src="js/jquery-2.0.0.min.js"></script>
</head>
</head>
<body>
<div class="border"></div>
<div id="titleBar">
<div class="icon">
<div class="icon-image"></div>
</div>
<div class="title">
Error!
</div>
</div>
<div>
<div id="log" style="width:680px"></div>
</div>
<div>
<button style="position: absolute;right: 10px;bottom: 6px;">OK</button>
</div>
</body>
<script>
const ipcRenderer = require('electron').ipcRenderer;
$(function() {
ipcRenderer.send('async', '{ "arg": "geterror" }');
});
ipcRenderer.on('async-reply', (event, arg) => {
console.log(event);
console.log(arg);
$("#log").text(arg);
});
</script>
</html>

View File

@ -1,153 +0,0 @@
<html>
<head>
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<div class="border"></div>
<div id="titleBar">
<div class="icon">
<div class="icon-image"></div>
</div>
<div class="title">
BetterDiscord Installer - v0.1.1
</div>
</div>
<div class="main-container panel-0">
<div class="sidebar">
<div class="sidebar-inner">
<ul>
<li id="li-0" class="navli">Introduction</li>
<li id="li-1" class="navli">License</li>
<li id="li-2" class="navli">Destination</li>
<li id="li-3" class="navli">Installation</li>
</ul>
</div>
</div>
<div class="main">
<div class="panel-container">
<div class="panel" id="panel-0">
<h2>Welcome to the BetterDiscord setup</h2>
<p style="white-space:pre-line">
The setup will install BetterDiscord on your computer.
Click "Next" to continue or "Cancel" to exit the setup.
BetterDiscord is not in any way affiliated with Discord
For support join the <a href="https://betterdiscord.net/discord" target="_blank">official BetterDiscord support channel</a> in Discord
</p>
<p>
<strong class="warning" style="font-size:12px">
Do not contact Discord support about BetterDiscord issues!
<br>
If Discord breaks, ask in the BetterDiscord support channel!
</strong>
</p>
<input name="cd" id="cd" type="checkbox">
<label style="margin:0; line-height: 18px;" for="cd">I will not contact Discord support about BetterDiscord issues</label>
</div>
<div class="panel" id="panel-1">
<div id="licensetext">
The MIT License (MIT)
Copyright (c) 2015-2016 Jiiks | Jiiks.net
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</div>
<form action="" id="licenseform">
<input type="radio" name="licensegroup" value="Accept" id="accept" disabled="true"><label for="accept">Accept</label>
<input type="radio" name="licensegroup" value="Decline" id="decline" checked="true"><label for="decline">Decline</label>
</form>
</div>
<div class="panel" id="panel-2">
<p style="font-size: 12px;">Setup will install BetterDiscord to the following location:</p>
<input class="path" id="libpath" type="text" style="height:26px;" disabled="true" />
<button id="libpathbtn" style="height:26px;">Browse</button>
<p style="font-size:12px">
*If you wish to install somewhere else then click "Browse" and select your path
</p>
<label for="discordPath" style="display:block; margin-top: 10px; font-size: 12px;">Discord Path:</label>
<input class="path" id="discordPath" type="text" style="height:26px;" disabled="true" />
<button id="path" style="height:26px;">Browse</button>
<p style="font-size:12px">
*If the path is not pointing to the latest version of Discord then click "Browse" and select it
<br>
*If you want to install to ptb/canary then click "Browse" and select it
<br>
*Installer will kill Discord process
</p>
<div class="checkboxGroup">
<input type="checkbox" name="demotes" id="demotes">
<label for="demotes" style="margin:0; line-height: 18px;">Disable emotes completely</label>
</div>
<div class="checkboxGroup">
<input type="checkbox" name="restart" id="restart" checked="true">
<label for="restart" style="margin:0; line-height: 18px;">Restart Discord after installation</label>
</div>
<button id="advanced-settings">Advanced</button>
</div>
<div class="panel" id="panel-advanced">
<span>Advanced settings</span> - <span class="warning">For advanced users only!</span>
<ul>
<li><input type="checkbox" name="aaot" id="aaot"><label for="aaot">Discord window always on top</label></li>
<li><input type="checkbox" name="aframeless" id="aframeless" checked><label for="aframeless">Frameless Discord window</label></li>
<li><input type="checkbox" name="atransparent" id="atransparent"><label for="atransparent">Transparent Discord window</label></li>
<li><input type="checkbox" name="athickframe" id="athickframe"><label for="athickframe">Thick Frame</label></li>
<li><input type="checkbox" name="aprefs" id="aprefs"><label for="aprefs">Use custom Web Preferences:</label></li>
</ul>
<textarea name="" id="" cols="30" rows="10"></textarea>
<button id="advanced-close">Save</button>
</div>
<div class="panel" id="panel-3">
<div name="log" id="log"></div>
<progress id="logpbar" value="0" max="100"></progress>
</div>
</div>
<div class="controls">
<button id="uninstall">Uninstall</button>
<button id="back">Back</button>
<button id="next" >Next</button>
<button id="cancel">Cancel</button>
</div>
</div>
</div>
<div class="modal" id="quit" style="display: none;">
<div class="modal-container">
<div class="modal-header">
<span>Exit Setup?</span>
</div>
<div class="modal-body">
Setup is not complete. If you exit now, BetterDiscord will not be installed.
<br>
Exit Setup?
</div>
<div class="modal-footer">
<button id="modal-exit">
Yes
</button>
<button id="modal-cancel">
No
</button>
</div>
</div>
</div>
</body>
<script type="text/javascript" src="js/jquery-2.0.0.min.js"></script>
<script type="text/javascript" src="js/main.js"></script>
<script type="text/javascript">
$(window).blur(function(){
$(".border").css("border-color", "#F76455");
});
$(window).focus(function(){
$(".border").css("border-color", "#55BBF7");
});
</script>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,202 +0,0 @@
'use strict';
const ipcRenderer = require('electron').ipcRenderer;
var config = {
urls: {
package: "https://github.com/Jiiks/BetterDiscordApp/archive/stable16.zip",
finish: "https://betterdiscord.net/installed"
},
discord: {
lastKnownVersion: "0.0.291"
},
import: "BetterDiscordApp-stable16",
cache: [
"emotes_bttv.json",
"emotes_bttv_2.json",
"emotes_ffz.json",
"emotes_twitch_global.json",
"emotes_twitch_subscriber.json",
"user.json"
]
};
(function() {
//Pass latest config to core application
ipcSendAsync("config", config);
//Get Discord installation path
ipcSendAsync("get", "discordpath" );
//Get BetterDiscord installation path
ipcSendAsync("get", "libpath");
})();
//Listeners
(function() {
$("#cd").on("change", () => {
$("#next").prop("disabled", !$("#cd").prop("checked"));
});
var currentPanel = 0;
function switchPanel() {
var container = $(".panel-container");
var main = $(".main-container");
main.removeClass();
main.addClass(`main-container panel-${currentPanel}`)
switch(currentPanel) {
case 0:
$("#next").text("Next");
//$("#next").prop("disabled", !$("#cd").prop("checked"));
break;
case 1:
$("#next").text("Next");
//$("#next").prop("disabled", !$("#accept").prop("checked"));
break;
case 2:
$("#next").text("Install");
$("#cancel").text("Cancel");
break;
case 3:
$("#cancel").text("Abort");
ipcSendAsync("install");
break;
}
}
$("#next").on("click", function() {
currentPanel++;
switchPanel();
});
$("#back").on("click", function() {
currentPanel--;
switchPanel();
});
$("#cancel").on("click", function() {
$("#quit").show();
});
$("#uninstall").on("click", function() {
});
$("#accept").on("change", function() {
// $("#next").prop("disabled", !$(this).prop("checked"));
});
$("#decline").on("change", function() {
// $("#next").prop("disabled", $(this).prop("checked"));
});
$("#licensetext").on("scroll", function() {
var e = $(this);
if(e.height() + e.scrollTop() >= e[0].scrollHeight) {
$("#accept").prop("disabled", false);
} else {
$("#accept").prop("disabled", true);
$("#decline").prop("checked", true)
// $("#next").prop("disabled", true);
}
});
$(".modal").on("click", function(e) {
if(e.target.className !== "modal") return;
$(this).hide();
});
$("#modal-cancel").on("click", function() {
$(".modal").hide();
});
$("#modal-exit").on("click", function() {
ipcRenderer.send("async", {arg: "quit", data: []});
});
$("#path").on("click", () => {
ipcRenderer.send("async", { arg: "browsedialog", data: "discordpath" });
});
$("#libpathbtn").on("click", () => {
ipcRenderer.send("async", { arg: "browsedialog", data: "libpath" });
});
$("#advanced-settings").on("click", function() {
currentPanel = "advanced";
switchPanel();
});
$("#advanced-close").on("click", function() {
var main = $(".main-container");
currentPanel = 2;
switchPanel();
});
})();
ipcRenderer.on("async-reply", (event, arg) => {
var data = arg.data;
arg = arg.arg;
switch(arg) {
case "discordpath":
$("#discordPath").val(data);
break;
case "libpath":
$("#libpath").val(data);
break;
}
});
/*ipcRenderer.on('async-reply', (event, arg) => {
switch(arg.arg) {
case "exists":
switch(arg.file) {
case "install":
if(arg.exists) {
appendLog("Located app package");
appendLog("Downloading latest BetterDiscord package");
ipcRenderer.send('async', '{"arg": "download", "package": "https://github.com/Jiiks/BetterDiscordApp/archive/stable16.zip" }');
} else {
appendLog("Unable to locate app.asar. Check your install path.");
}
}
break;
case "discordpath":
$("#discordPath").val(arg.path);
break;
case "locate-app.asar":
appendLog(arg.data);
break;
}
});*/
function ipcSendAsync(arg, data) {
ipcRenderer.send("async", { arg: arg, data: data });
}
function install() {
appendLog("Initiating installation");
appendLog("Locating Discord package");
ipcRenderer.send('async', { "arg": "install" });
}
function appendLog(text) {
var log = $("#log");
log.append(text+"\n");
var sh = log[0].scrollHeight - 40;
if(log.height() + log.scrollTop() >= sh) {
log.scrollTop(sh);
}
}
function updatePbar(cur, max) {
var pbar = $("#logpbar");
pbar.val(cur);
pbar.prop("max", max);
}

View File

@ -1,15 +0,0 @@
'use strict';
const ipcRenderer = require('electron').ipcRenderer;
ipcRenderer.on('async-reply', (event, arg) => {
switch(arg) {
case "update":
$(".spinnertext").text("Downloading Update");
break;
}
});
$(function() {
ipcRenderer.send('async', '{ "arg": "update" }');
});

View File

@ -1,16 +0,0 @@
<html>
<head>
<head>
<link rel="stylesheet" href="css/main.css">
<script type="text/javascript" src="js/jquery-2.0.0.min.js"></script>
<script type="text/javascript" src="js/splash.js"></script>
</head>
</head>
<body class="splash">
<div class="border"></div>
<div class="wrapper">
<div class="spinner"></div>
</div>
<span class="spinnertext">Checking for updates...</span>
</body>
</html>

View File

@ -1,8 +0,0 @@
{
"windows": {
"version": "0.1.0"
},
"osx": {
"version": "0.1.1"
}
}

View File

@ -1,45 +0,0 @@
'use strict';
var devMode = false;
const
electron = require('electron'),
app = electron.app,
BrowserWindow = electron.BrowserWindow,
ipcMain = electron.ipcMain,
utils = require('./utils'),
_utils = new utils();
var
mainWindow,
windowOptions = {
width: 300,
height: 100,
fullscreenable: false,
maximizable: false,
frame: false,
resizable: devMode ? true : false,
alwaysOnTop: devMode ? true : false,
transparent: false
};
class Index {
constructor() {
app.on("ready", () => this.appReady());
}
appReady() {
mainWindow = new BrowserWindow(windowOptions);
this.loadInstaller();
}
loadInstaller() {
this.installer = require('./installer_index');
this.installerInstance = new this.installer(app, mainWindow, ipcMain, _utils);
}
}
module.exports = new Index();

View File

@ -1,269 +0,0 @@
'use strict';
//Imports
const
path = require('path'),
dialog = require('electron').dialog,
fs = require("fs"),
fse = require("fs-extra"),
request = require('request'),
unzip = require('unzip'),
readline = require('readline'),
asar = require('./asar');
const platform = (process.platform !== "win32" && process.platform !== "darwin") ? "linux" : process.platform;
var
config = {
urls: {
package: "https://github.com/Jiiks/BetterDiscordApp/archive/stable16.zip",
finish: "https://betterdiscord.net/installed"
},
discord: {
lastKnownVersion: "0.0.292"
},
import: "BetterDiscordApp-stable16",
cache: [
"emotes_bttv.json",
"emotes_bttv_2.json",
"emotes_ffz.json",
"emotes_twitch_global.json",
"emotes_twitch_subscriber.json",
"user.json"
],
paths: {
installPath: "",
libPath: ""
}
};
class Installer {
constructor(app, mainWindow, ipc, utils) {
this.app = app;
this.utils = utils;
this.initConfig();
mainWindow.setSize(800, 400);
mainWindow.center();
mainWindow.loadURL(`file://${__dirname}/data/index.html`);
this.webContents = mainWindow.webContents;
ipc.on('async', (event, arg) => this.receiveAsync(event, arg));
}
initConfig() {
config.paths.installPath = path.normalize(this.utils.installPath(config.discord.lastKnownVersion));
config.paths.libPath = path.normalize(this.utils.libPath());
}
install() {
this.utils.log("Config: " + JSON.stringify(config));
this.appendLog("Initializing");
this.locateAppPackage();
}
locateAppPackage() {
var p = path.normalize(`${config.paths.installPath}/resources`);
var pkg = fs.readdirSync(p).filter(file => {
if(file === "app.asar") {
return true;
}
});
if(pkg.length <= 0) {
//App package not found
this.appendLog("Unable to locate app package, check the logs for errors");
return;
}
this.appendLog("Located app package");
this.downloadBd();
//this.extractAppPackage();
}
downloadBd() {
var self = this;
this.appendLog("Downloading BetterDiscord");
var error = false;
var size = 0;
var downloaded = 0;
var req = request({
method: 'GET',
uri: config.urls.package
});
req.pipe(unzip.Extract({ path: path.normalize(config.paths.libPath) }));
req.on('data', chunk => {
downloaded += chunk.length;
this.updatePb(downloaded, size);
});
req.on('response', data => {
size = data.headers['content-length'];
});
req.on('error', err => {
error = true;
self.utils.log(err);
self.appendLog("Failed to download BetterDiscord package, check the logs for errors");
});
req.on('end', () => {
console.log("got here?");
if(error) {
self.appendLog("Failed to download BetterDiscord package, check the logs for errors");
} else {
self.extractAppPackage();
}
});
}
extractAppPackage() {
var self = this;
try {
if(fs.existsSync(`${config.paths.installPath}/resources/app`)) {
self.appendLog("Deleting old app directory");
setTimeout(() => {
fse.removeSync(`${config.paths.installPath}/resources/app`);
extract();
}, 500);
} else {
extract();
}
} catch(err) {
self.appendLog("Could not delete old app directory, check the logs for errors");
return;
}
function extract() {
try {
self.appendLog("Extracting app package");
var a = new asar(`${config.paths.installPath}/resources/app.asar`);
a.extract(msg => {
self.appendLog(msg);
}, (curIndex, total) => {
self.updatePb(curIndex, total);
}, err => {
if(err === null) {
self.inject();
} else {
self.log(err);
self.appendLog("Failed to extract app package, check the logs for errors");
self.clean();
}
});
}catch(err) {
console.log(err);
}
}
}
inject() {
var self = this;
this.updatePb(0, 5);
this.appendLog("Injecting loader");
var lines = [];
var lr = readline.createInterface({
input: fs.createReadStream(`${config.paths.installPath}/resources/app/index.js`)
});
lr.on('line', line => {
lines.push(line);
if(line.indexOf("'use strict';") > -1) {
lines.push(path.normalize(`var _betterDiscord = require('${config.paths.libPath}/${config.import}');`).replace(/\\/g,"/"));
lines.push("var _betterDiscord2;");
}
if(line.indexOf("mainWindow = new BrowserWindow(mainWindowOptions);") > -1) {
lines.push(` _betterDiscord2 = new _betterDiscord.BetterDiscord(mainWindow, false);`);
}
});
lr.on('close', () => {
fs.writeFileSync(`${config.paths.installPath}/resources/app/index.js`, lines.join('\n'));
self.appendLog("Finished installing BetterDiscord");
self.updatePb(5, 5);
});
}
clean() {
this.appendLog("Cleaning installation");
try {
if(fs.existsSync(`${config.paths.installPath}/resources/app`)) {
self.appendLog("Deleting app directory");
setTimeout(() => {
fse.removeSync(`${config.paths.installPath}/resources/app`);
}, 500);
}
} catch(err) {
self.appendLog("Could not delete old app directory, check the logs for errors");
}
}
appendLog(msg) {
this.utils.log(msg);
this.webContents.executeJavaScript(`appendLog("${msg}");`);
}
updatePb(cur, max) {
this.webContents.executeJavaScript(`updatePbar(${cur}, ${max});`);
}
getData(e) {
switch(e) {
case "discordpath":
return config.paths.installPath;
case "libpath":
return config.paths.libPath;
}
}
receiveAsync(event, arg) {
var data = arg.data || '';
arg = arg.arg;
switch(arg) {
case "get":
this.replyAsync(event, data, this.getData(data));
break;
case "browsedialog":
var path = dialog.showOpenDialog({ properties: ['openDirectory'] });
switch(data) {
case "discordpath":
path = path === undefined ? config.paths.installPath : path[0];
config.paths.installPath = path;
break;
case "libpath":
path = path === undefined ? config.paths.libPath : path[0];
config.paths.libPath = path;
break;
}
this.replyAsync(event, data, path);
break;
case "install":
this.install();
break;
case "quit":
this.app.quit();
break;
}
}
replyAsync(event, arg, data) {
event.sender.send('async-reply', { "arg": arg, "data": data });
}
}
module.exports = Installer;

View File

@ -1,10 +0,0 @@
{
"name": "Install",
"description": "Better Discord enhances Discord.",
"version": "0.1.1",
"homepage": "https://github.com/Jiiks/BetterDiscordApp",
"license": "MIT",
"devDependencies": {
"electron-prebuilt": "^1.0.0"
}
}

View File

@ -1,75 +0,0 @@
'use strict';
class Updater {
constructor(utils) {
this.utils = utils;
}
update() {
var self = this;
var promises = [
new Promise((resolve, reject) => {
downloadResource("/Jiiks/BetterDiscordApp/master/Installers/Electron/src/data/index.html", (error, data)
if(error) {
error(data, true);
reject();
return;
}
self.utils.log("Succesfully loaded index.html");
resolve();
});
}),
new Promise((resolve, reject) => {
downloadResource("/Jiiks/BetterDiscordApp/master/Installers/Electron/src/data/js/main.js", (error, data)
if(error) {
error(data, true);
reject();
return;
}
self.utils.log("Succesfully loaded main.js");
resolve();
});
}),
new Promise((resolve, reject) => {
downloadResource("/Jiiks/BetterDiscordApp/master/Installers/Electron/src/data/css/main.css", (error, dat
if(error) {
error(data, true);
reject();
return;
}
self.utils.log("Succesfully loaded main.css");
resolve();
});
})
];
return Promise.all(promises);
}
checkForUpdates(okCb, errorCb) {
_utils.downloadResource("/Jiiks/BetterDiscordApp/master/Installers/Electron/src/data/vi.json", (error, data) => {
if(error) {
errorCb(data);
return;
}
try {
data = JSON.parse(data);
}catch(err) {
errorCb(err);
return;
}
switch(platform) {
case "win32":
okCb(data.windows.version > vi.windows.version);
break;
case "darwin":
okCb(data.osx.version > vi.osx.version);
break;
}
});
}
}
module.exports = Updater;

View File

@ -1,98 +0,0 @@
'use strict';
const
https = require('https'),
fs = require('fs'),
eol = require('os').EOL,
platform = (process.platform !== "win32" && process.platform !== "darwin") ? "linux" : process.platform;
class Utils {
constructor() {
this.logs = "";
}
log(message) {
var d = new Date();
var ds = ("00" + (d.getDate() + 1)).slice(-2) + "/" +
("00" + d.getMonth()).slice(-2) + "/" +
d.getFullYear() + " " +
("00" + d.getHours()).slice(-2) + ":" +
("00" + d.getMinutes()).slice(-2) + ":" +
("00" + d.getSeconds()).slice(-2);
console.log(`[${ds}] ${message}`);
this.logs += `[${ds}] ${message}${eol}`;
this.saveLogs();
}
printLogs() {
console.log(this.logs);
}
saveLogs() {
fs.writeFileSync("logs.log", this.logs);
}
downloadResource(resource, callback, host) {
https.get({
host: host || "raw.githubusercontent.com",
path: resource,
headers: { 'user-agent': 'Mozilla/5.0' }
},
(response) => {
var data = "";
response.on("data", (chunk) => {
data += chunk;
});
response.on("end", () => {
callback(false, data);
});
response.on("error", (e) => {
callback(true, e);
});
}).on('error', (e) => {
callback(true, e);
});
}
installPath(lastKnownVersion) {
return {
"win32": () => {
var hver = lastKnownVersion;
var path = `${process.env.LOCALAPPDATA}/Discord/app-${lastKnownVersion}\\`;
fs.readdirSync(`${process.env.LOCALAPPDATA}/Discord/`).filter(function(file) {
var tpath = `${process.env.LOCALAPPDATA}/Discord/${file}`;
if(!fs.statSync(tpath).isDirectory()) return;
if(!file.startsWith("app-")) return;
var ver = file.replace("app-", "");
if(ver < hver) return;
hver = ver;
path = tpath;
});
return path;
},
"darwin": () => "/Applications/Discord.app/Contents",
"linux": () => "/usr/share/discord"
}[platform]();
}
libPath() {
return {
"win32": () => {
return `${process.env.APPDATA}/BetterDiscord/lib`;
},
"darwin": () => {
return `${process.env.HOME}/.local/share/BetterDiscord`;
},
"linux": () => {
// FIXME: for a non-root user, a path like OSX's makes more sense
return "/usr/local/share/BetterDiscord";
}
}[platform]();
}
}
module.exports = Utils;

View File

@ -1,3 +0,0 @@
{
"init": "init"
}

View File

@ -1,261 +0,0 @@
/*
* BetterDiscordApp Installer v0.3.2
*/
var dver = "0.0.284";
var asar = require('asar');
var wrench = require('wrench');
var fs = require('fs');
var readline = require('readline');
var util = require('util');
var _importSplice;
var _functionSplice;
var _functionCallSplice;
var _discordPath;
var _appFolder = "/app";
var _appArchive = "/app.asar";
var _packageJson = _appFolder + "/package.json";
var _index = _appFolder + "/index.js";
var _force = false;
// Get Arguments
process.argv.forEach(function (val, index, array) {
if (val == "--force") {
_force = true;
}
if (val == "-d" || val == "--directory") {
_discordPath = array[(index+1)]
}
});
function install() {
if (typeof _discordPath == 'undefined') {
var _os = process.platform;
if (_os == "win32") {
_importSplice = 89;
_functionCallSplice = 497;
_functionSplice = 601;
_discordPath = process.env.LOCALAPPDATA + "/Discord/app-"+dver+"/resources";
} else if (_os == "darwin") {
_importSplice = 67;
_functionCallSplice = 446;
_functionSplice = 547;
_discordPath = "/Applications/Discord.app/Contents/Resources" // Defaults to Applications directory
} else if (_os == "linux") {
_discordPath = "/opt/DiscordCanary/resources";
_index = "/app/index.js";
}
}
console.log("Looking for discord resources at: " + _discordPath);
fs.exists(_discordPath, function(exists) {
if(exists) {
console.log("Discord resources found at: " + _discordPath + "\nLooking for app folder");
if(fs.existsSync(_discordPath + _appFolder)) {
console.log("Deleting " + _discordPath + _appFolder + " folder.");
wrench.rmdirSyncRecursive(_discordPath + _appFolder);
console.log("Deleted " + _discordPath + _appFolder + " folder.");
}
if(fs.existsSync(_discordPath + "/node_modules/BetterDiscord")) {
console.log("Deleting " + _discordPath + "/node_modules/BetterDiscord" + " folder.");
wrench.rmdirSyncRecursive(_discordPath + "/node_modules/BetterDiscord");
console.log("Deleted " + _discordPath + "/node_modules/BetterDiscord" + " folder.");
}
console.log("Looking for app archive");
if(fs.existsSync(_discordPath + _appArchive)) {
console.log("App archive found at: " + _discordPath + _appArchive);
} else {
console.log("Failed to locate app archive at: " + _discordPath + _appArchive);
process.exit();
}
console.log("Extracting app archive");
asar.extractAll(_discordPath + _appArchive, _discordPath + _appFolder);
console.log("Copying BetterDiscord");
if(_os == "linux") {
fs.mkdirSync(_discordPath + _appFolder + "/node_modules/BetterDiscord");
}
else {
fs.mkdirSync(_discordPath + "/node_modules/BetterDiscord");
}
wrench.copyDirSyncRecursive(__dirname + "/BetterDiscord/", _discordPath + _appFolder + "/node_modules/BetterDiscord/", {forceDelete: true});
if(!fs.existsSync("splice")) {
console.log("Missing splice file");
process.exit();
}
var splice = fs.readFileSync("splice");
fs.exists(_discordPath + _appFolder, function(exists) {
if(exists) {
console.log("Extracted to: " + _discordPath + _appFolder);
console.log("Injecting index.js");
var data = fs.readFileSync(_discordPath + _index).toString().split("\n");
if(_os == "linux") {
data = data.join("\n");
data = data.replace('var _GPUSettings2 = _interopRequireDefault(_GPUSettings);','var _GPUSettings2 = _interopRequireDefault(_GPUSettings);\n\nvar _betterDiscord = require(\'BetterDiscord\');\n');
data = data.replace('mainWindow.setMenuBarVisibility(false);','mainWindow.setMenuBarVisibility(false);\n' + splice + '\n');
data = data.split("\n");
} else {
data.splice(_importSplice, 0, 'var _betterDiscord = require(\'betterdiscord\');\n');
data.splice(_functionCallSplice, 0, splice);
}
fs.writeFile(_discordPath + _index, data.join("\n"), function(err) {
if(err) return console.log(err);
console.log("Injected index.js");
console.log("Deleting old cache files");
var counter = 0;
var _prefsPath = '/Library/Preferences/BetterDiscord/';
var emotes_twitch_global = 'emotes_twitch_global.json';
fs.exists(process.env.HOME + _prefsPath + emotes_twitch_global, (exists) => {
if (exists) {
console.log("Deleting " + emotes_twitch_global);
fs.unlinkSync(process.env.HOME + _prefsPath + emotes_twitch_global, (err) => {
if(err) throw err;
});
console.log("Deleted " + emotes_twitch_global);
}
counter++;
finished();
});
var emotes_twitch_subscriber = 'emotes_twitch_subscriber.json';
fs.exists(process.env.HOME + _prefsPath + emotes_twitch_subscriber, (exists) => {
if (exists) {
console.log("Deleting " + emotes_twitch_subscriber);
fs.unlinkSync(process.env.HOME + _prefsPath + emotes_twitch_subscriber, (err) => {
if(err) throw err;
});
console.log("Deleted " + emotes_twitch_subscriber);
}
counter++;
finished();
});
var emotes_bttv = 'emotes_bttv.json';
fs.exists(process.env.HOME + _prefsPath + emotes_bttv, (exists) => {
if (exists) {
console.log("Deleting " + emotes_bttv);
fs.unlinkSync(process.env.HOME + _prefsPath + emotes_bttv, (err) => {
if(err) throw err;
});
console.log("Deleted " + emotes_bttv);
}
counter++;
finished();
});
var emotes_bttv_2 = "emotes_bttv_2.json";
fs.exists(process.env.HOME + _prefsPath + emotes_bttv_2, (exists) => {
if (exists) {
console.log("Deleting " + emotes_bttv_2);
fs.unlinkSync(process.env.HOME + _prefsPath + emotes_bttv_2, (err) => {
if(err) throw err;
});
console.log("Deleted " + emotes_bttv_2);
}
counter++;
finished();
});
var emotes_ffz = "emotes_ffz.json";
fs.exists(process.env.HOME + _prefsPath + emotes_ffz, (exists) => {
if (exists) {
console.log("Deleting " + emotes_ffz);
fs.unlinkSync(process.env.HOME + _prefsPath + emotes_ffz, (err) => {
if(err) throw err;
});
console.log("Deleted " + emotes_ffz);
}
counter++;
finished();
});
var user_pref = "user.json";
fs.exists(process.env.HOME + _prefsPath + user_pref, (exists) => {
if (exists) {
console.log("Deleting " + user_pref);
fs.unlinkSync(process.env.HOME + _prefsPath + user_pref, (err) => {
if(err) throw err;
});
console.log("Deleted " + user_pref);
}
counter++;
finished();
});
function finished() {
if(counter => 6) {
console.log("Looks like we're done here");
process.exit();
}
}
});
} else {
console.log("Something went wrong. Please try again.");
process.exit();
}
});
} else {
console.log("Discord resources not found at: " + _discordPath);
process.exit();
}
});
}
function init() {
console.log("BetterDiscord Simple Installer v0.3 for Discord "+dver+" by Jiiks.");
console.log("If Discord has updated then download the latest installer.");
var rl = readline.createInterface({ input: process.stdin, output: process.stdout });
if (_force == false) {
rl.question("The following directories will be deleted if they exists: discorpath/app, discordpath/node_modules/BetterDiscord, is this ok? Y/N", function(answer) {
var alc = answer.toLowerCase();
switch(alc) {
case "y":
case "yes":
install();
break;
case "n":
case "no":
process.exit();
break;
}
});
} else {
install();
}
}
init();

View File

@ -1,11 +0,0 @@
@echo off
where node.exe >nul 2>nul
if %errorlevel%==1 (
echo "Node.exe not found, opening your browser..."
start "" "https://nodejs.org/dist/latest/win-x86/node.exe"
pause
) else (
taskkill /f /im "Discord.exe" >nul 2>nul
cmd /k node.exe index.js
)
exit

View File

@ -1,7 +0,0 @@
#!/bin/bash
# As there is no Linux support, this script assumes OS X as the host system.
command -v node > /dev/null || (echo 'Node not found, please download it!' && open 'https://nodejs.org/en/' && sleep 5 && exit)
node index.js
exit

View File

@ -1,63 +0,0 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

View File

@ -1,156 +0,0 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
!packages/*/build/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#LightSwitch generated files
GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac desktop service store files
.DS_Store

View File

@ -1,22 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BetterDiscordWI", "BetterDiscordWI\BetterDiscordWI.csproj", "{469F7547-7664-4DE8-A568-E89525981539}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{469F7547-7664-4DE8-A568-E89525981539}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{469F7547-7664-4DE8-A568-E89525981539}.Debug|Any CPU.Build.0 = Debug|Any CPU
{469F7547-7664-4DE8-A568-E89525981539}.Release|Any CPU.ActiveCfg = Release|Any CPU
{469F7547-7664-4DE8-A568-E89525981539}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1"/>
</startup>
</configuration>

View File

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0" name="BetterDiscord Installer"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 KiB

View File

@ -1,174 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{469F7547-7664-4DE8-A568-E89525981539}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>BetterDiscordWI</RootNamespace>
<AssemblyName>BetterDiscordWI</AssemblyName>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Resources\BetterDiscord-icon.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup />
<PropertyGroup>
<ApplicationManifest>App.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
<Reference Include="asardotnet">
<HintPath>asardotnet.dll</HintPath>
</Reference>
<Reference Include="Costura, Version=1.6.2.0, Culture=neutral, PublicKeyToken=9919ef960d84173d, processorArchitecture=MSIL">
<HintPath>..\packages\Costura.Fody.1.6.2\lib\dotnet\Costura.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="components\CTextBox.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="FormMain.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="FormMain.Designer.cs">
<DependentUpon>FormMain.cs</DependentUpon>
</Compile>
<Compile Include="panels\IPanel.cs" />
<Compile Include="panels\Panel0.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="panels\Panel0.Designer.cs">
<DependentUpon>Panel0.cs</DependentUpon>
</Compile>
<Compile Include="panels\Panel1.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="panels\Panel1.Designer.cs">
<DependentUpon>Panel1.cs</DependentUpon>
</Compile>
<Compile Include="panels\Panel2.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="panels\Panel2.Designer.cs">
<DependentUpon>Panel2.cs</DependentUpon>
</Compile>
<Compile Include="panels\Panel3.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="panels\Panel3.Designer.cs">
<DependentUpon>Panel3.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Utils.cs" />
<EmbeddedResource Include="FormMain.resx">
<DependentUpon>FormMain.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="panels\Panel0.resx">
<DependentUpon>Panel0.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="panels\Panel1.resx">
<DependentUpon>Panel1.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="panels\Panel2.resx">
<DependentUpon>Panel2.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="App.manifest" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\bd_logo2.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\bd_logo_64x64.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\bd_logo_64x64_nobg.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\bd_logo_large_nobg.png" />
</ItemGroup>
<ItemGroup>
<Content Include="BetterDiscord-icon.ico" />
<None Include="FodyWeavers.xml" />
<Content Include="Resources\BetterDiscord-icon.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Fody.2.0.0\build\dotnet\Fody.targets" Condition="Exists('..\packages\Fody.2.0.0\build\dotnet\Fody.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Fody.2.0.0\build\dotnet\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.2.0.0\build\dotnet\Fody.targets'))" />
<Error Condition="!Exists('..\packages\Costura.Fody.1.6.2\build\dotnet\Costura.Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.1.6.2\build\dotnet\Costura.Fody.targets'))" />
</Target>
<Import Project="..\packages\Costura.Fody.1.6.2\build\dotnet\Costura.Fody.targets" Condition="Exists('..\packages\Costura.Fody.1.6.2\build\dotnet\Costura.Fody.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Weavers>
<Costura />
</Weavers>

View File

@ -1,137 +0,0 @@
namespace BetterDiscordWI
{
partial class FormMain
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormMain));
this.btnCancel = new System.Windows.Forms.Button();
this.panelContainer = new System.Windows.Forms.Panel();
this.btnNext = new System.Windows.Forms.Button();
this.btnBack = new System.Windows.Forms.Button();
this.lblPanelTitle = new System.Windows.Forms.Label();
this.panel1 = new System.Windows.Forms.Panel();
this.SuspendLayout();
//
// btnCancel
//
this.btnCancel.Location = new System.Drawing.Point(438, 328);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(75, 23);
this.btnCancel.TabIndex = 0;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
//
// panelContainer
//
this.panelContainer.BackColor = System.Drawing.SystemColors.Control;
this.panelContainer.Location = new System.Drawing.Point(0, 52);
this.panelContainer.Name = "panelContainer";
this.panelContainer.Size = new System.Drawing.Size(524, 258);
this.panelContainer.TabIndex = 0;
//
// btnNext
//
this.btnNext.Enabled = false;
this.btnNext.Location = new System.Drawing.Point(357, 328);
this.btnNext.Name = "btnNext";
this.btnNext.Size = new System.Drawing.Size(75, 23);
this.btnNext.TabIndex = 4;
this.btnNext.Text = "Next >";
this.btnNext.UseVisualStyleBackColor = true;
//
// btnBack
//
this.btnBack.Enabled = false;
this.btnBack.Location = new System.Drawing.Point(276, 328);
this.btnBack.Name = "btnBack";
this.btnBack.Size = new System.Drawing.Size(75, 23);
this.btnBack.TabIndex = 5;
this.btnBack.Text = "< Back";
this.btnBack.UseVisualStyleBackColor = true;
//
// lblPanelTitle
//
this.lblPanelTitle.AutoSize = true;
this.lblPanelTitle.BackColor = System.Drawing.SystemColors.Window;
this.lblPanelTitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblPanelTitle.Location = new System.Drawing.Point(61, 16);
this.lblPanelTitle.Name = "lblPanelTitle";
this.lblPanelTitle.Size = new System.Drawing.Size(103, 16);
this.lblPanelTitle.TabIndex = 6;
this.lblPanelTitle.Text = "BetterDiscord";
//
// panel1
//
this.panel1.BackColor = System.Drawing.SystemColors.Window;
this.panel1.BackgroundImage = global::BetterDiscordWI.Properties.Resources.bd_logo_large_nobg;
this.panel1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
this.panel1.Location = new System.Drawing.Point(0, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(64, 46);
this.panel1.TabIndex = 0;
//
// FormMain
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(524, 361);
this.Controls.Add(this.panel1);
this.Controls.Add(this.lblPanelTitle);
this.Controls.Add(this.btnBack);
this.Controls.Add(this.panelContainer);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnNext);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "FormMain";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Setup - BetterDiscord ";
this.TransparencyKey = System.Drawing.Color.LimeGreen;
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Panel panelContainer;
public System.Windows.Forms.Button btnNext;
public System.Windows.Forms.Button btnBack;
public System.Windows.Forms.Label lblPanelTitle;
private System.Windows.Forms.Panel panel1;
public System.Windows.Forms.Button btnCancel;
}
}

View File

@ -1,75 +0,0 @@
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Xml;
using BetterDiscordWI.panels;
namespace BetterDiscordWI {
public partial class FormMain : Form {
private readonly IPanel[] _panels = { new Panel0(), new Panel1(), new Panel2() };
private int _index;
public string DiscordPath;
public bool RestartDiscord = false;
public string Sha;
public bool Finished = false;
public bool ZeresFork = false;
public string DiscordVersion = "Discord";
public bool DesktopModule = false;
public string DiscordInstallPath;
public XmlNodeList ResourceList;
public FormMain() {
InitializeComponent();
Sha = Utils.GetHash();
if (Sha.Length < 1) {
MessageBox.Show(@"Failed to get sha", @"Error", MessageBoxButtons.OK);
Environment.Exit(0);
}
foreach (IPanel ipanel in _panels) {
panelContainer.Controls.Add((UserControl)ipanel);
((UserControl)ipanel).Dock = DockStyle.Fill;
((UserControl)ipanel).Hide();
}
((UserControl)_panels[_index]).Show();
_panels[_index].SetVisible();
btnCancel.Click += (sender, args) => Close();
btnNext.Click += (sender, args) => _panels[_index].BtnNext();
btnBack.Click += (sender, args) => _panels[_index].BtnPrev();
}
public void SwitchPanel(int index) {
((UserControl)_panels[_index]).Hide();
_index = index;
((UserControl)_panels[_index]).Show();
_panels[_index].SetVisible();
}
protected override void OnFormClosing(FormClosingEventArgs e) {
if (Finished) return;
DialogResult dr = MessageBox.Show(@"Setup is not complete. If you exit now, BetterDiscord will not be installed. Exit Setup?", @"Exit Setup?", MessageBoxButtons.YesNo);
if (dr == DialogResult.No) {
e.Cancel = true;
}
}
readonly Pen _borderPen = new Pen(Color.FromArgb(160, 160, 160));
protected override void OnPaint(PaintEventArgs e) {
Graphics g = e.Graphics;
g.FillRectangle(SystemBrushes.Window, new Rectangle(0, 0, Width, 50));
g.DrawLine(_borderPen, 0, 50, Width, 50);
g.DrawLine(SystemPens.Window, 0, 51, Width, 51);
g.DrawLine(_borderPen, 0, 310, Width, 310);
g.DrawLine(SystemPens.Window, 0, 311, Width, 311);
base.OnPaint(e);
}
}
}

View File

@ -1,659 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAQAEBAAAAAAIABoBAAARgAAACAgAAAAACAAqBAAAK4EAAAwMAAAAAAgAKglAABWFQAAQEAAAAAA
IAAoQgAA/joAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAD5AAAA+wAA
APsAAAD7AAAA+wAAAPsAAAD7AAAA+wAAAPsAAAD7AAAA+wAAAPsAAAD7AAAA+wAAAPsAAAD5AAAA+wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAA
APsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
APsAAAD7AAAA/wEBCf8NClr/FBCI/wMCGP8AAAD/AAAA/wAAAP8AAAD/AwIW/xQQif8NClv/AQEK/wAA
AP8AAAD7AAAA+wQDH/8cFr7/HhjN/xkTqf8QDW7/EQ1z/xURkf8VEZH/EQ10/xANbf8YE6j/HhjN/xwW
v/8EAyH/AAAA+wAAAPsPDGn/HhjL/x0Xxv8aFbT/HxnV/x4Y0P8eGMz/HhjM/x4Y0P8fGdT/GhW1/x0X
xf8eGMv/EAxs/wAAAPsAAAD7DQpb/x4YzP8eGMz/HRfK/wcFMP8JB0D/HhjP/x4Yz/8JB0P/BgUu/x0X
yf8eGMz/HhjM/w0LXf8AAAD7AAAA+wgGN/8eGM//HhjM/xoVtf8AAAD/AAAC/x0XyP8dF8r/AAAD/wAA
AP8aFbL/HhjM/x4Yz/8IBzv/AAAA+wAAAPsBAQn/HhjP/x4YzP8eGM7/FBCK/xYRlv8eGM3/HhjN/xYR
l/8UEIn/HhjO/x4YzP8eGND/AQEL/wAAAPsAAAD7AAAA/xcSnP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/FxKf/wAAAP8AAAD7AAAA+wAAAP8LCU3/HhjP/x4Yy/8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMv/HhjP/wsJUP8AAAD/AAAA+wAAAPsAAAD/AAAD/xYRlP8XEp3/GhSw/x4Y
0f8fGdX/HxnV/x4Y0f8aFLH/FxKd/xYRlv8AAAT/AAAA/wAAAPsAAAD7AAAA/wAAAP8AAAD/CQc8/wwK
Uf8EAxn/AwMa/wMDGv8EAxj/DApR/wkHPf8AAAD/AAAA/wAAAP8AAAD7AAAA+wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+wAAAPsAAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAD5AAAA+wAA
APsAAAD7AAAA+wAAAPsAAAD7AAAA+wAAAPsAAAD7AAAA+wAAAPsAAAD7AAAA+wAAAPsAAAD5AAD//wAA
//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//ygA
AAAgAAAAQAAAAAEAIAAAAAAAgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1AAAA+QAAAPkAAAD5AAAA+QAA
APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAA
APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA9QAAAPkAAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAA+QAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
APkAAAD5AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA+QAAAPkAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD5AAAA+QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAD5AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AQAG/wYE
J/8IBjj/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/CAY3/wYE
KP8BAAb/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAPkAAAD/AAAA/wAAAP8AAAD/BgQn/xYR
lf8eGM3/IBnc/yIb5v8OC2L/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/w0L
W/8iG+j/IBnc/x4Yzv8WEpn/BgQq/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAA+QAAAP8AAAD/AAAA/xEN
df8gGt//HhjO/x4Yy/8eGMv/IBna/xwWwf8BAQr/AAAE/wUEI/8JBz//CwlO/wsJTv8JB0D/BQQk/wAA
Bf8BAQj/HBa8/yAa2/8eGMv/HhjL/x4Yzv8hGt//Eg56/wAAAP8AAAD/AAAA/wAAAPkAAAD5AAAA/wAA
AP8SDn7/IBra/x4Yy/8eGMz/HhjP/x0Xxf8IBzv/CghK/xgTov8dGMv/IBnb/yAa3v8gGdr/IBna/yAa
3v8gGdz/HhjM/xgTpf8LCUz/CAY5/xwWwv8eGM//HhjM/x4Yy/8fGdn/Ew+E/wAAAP8AAAD/AAAA+QAA
APkAAAD/AQAF/x8Z1P8eGMv/HhjM/x4Yzf8bFbj/Dgxk/x4Yzv8gGtv/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/yAZ2v8eGM//Dwxm/xoVtP8eGM3/HhjM/x4Yy/8fGdb/AQEK/wAA
AP8AAAD5AAAA+QAAAP8AAAD/HRjK/x4YzP8eGMz/HhjM/x0XyP8fGdX/HhjL/x4Y0P8gGdz/IBnc/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/yAZ3P8gGdz/HhjQ/x4Yy/8fGdX/HRfI/x4YzP8eGMz/HhjM/x4Y
zf8AAAP/AAAA/wAAAPkAAAD5AAAA/wAAAP8cFsH/HhjM/x4YzP8eGMz/HhjM/x4YzP8fGNP/FhGW/wYF
Kv8HBjX/GxW4/x4Yzv8eGMz/HhjM/x4Yzf8bFrz/CAY3/wYFKf8VEZH/HxnU/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HBfF/wAAAP8AAAD/AAAA+QAAAPkAAAD/AAAA/xkUrf8eGMz/HhjM/x4YzP8eGMz/HhjM/xwW
v/8AAAD/AAAA/wAAAP8DAhX/HxnW/x4YzP8eGMz/HxnX/wMDGf8AAAD/AAAA/wAAAP8bFrr/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8aFLL/AAAA/wAAAP8AAAD5AAAA+QAAAP8AAAD/FBCK/x4Yzv8eGMz/HhjM/x4Y
zP8eGM3/FBCJ/wAAAP8AAAD/AAAA/wAAAP8aFbj/HhjM/x4YzP8cFr3/AAAA/wAAAP8AAAD/AAAA/xIP
gP8eGM//HhjM/x4YzP8eGMz/HhjN/xURkv8AAAD/AAAA/wAAAPkAAAD5AAAA/wAAAP8MCVT/IBnZ/x4Y
zP8eGMz/HhjM/x4YzP8aFbP/AAAA/wAAAP8AAAD/AQEK/x4Y0P8eGMz/HhjM/x8Z0/8CAQ3/AAAA/wAA
AP8AAAD/GRSt/x4YzP8eGMz/HhjM/x4YzP8fGdf/DQpb/wAAAP8AAAD/AAAA+QAAAPkAAAD/AAAA/wUE
Jf8gGtz/HhjM/x4YzP8eGMz/HhjM/x8Z1v8RDnb/AgEN/wMCFv8XEp3/HhjR/x4YzP8eGMz/HhjQ/xgT
ov8DAhj/AQEM/xANcf8gGdf/HhjM/x4YzP8eGMz/HhjM/yAa3v8GBSv/AAAA/wAAAP8AAAD5AAAA+QAA
AP8AAAD/AAAC/x0Xyf8eGMv/HhjM/x4YzP8eGMz/HhjL/x8Z1f8fGNL/HxnV/x4Y0P8eGMv/HhjM/x4Y
zP8eGMz/HhjP/x8Z1v8eGNH/HxnV/x4Yy/8eGMz/HhjM/x4YzP8eGMv/HhjM/wAAA/8AAAD/AAAA/wAA
APkAAAD5AAAA/wAAAP8AAAD/FBCJ/x4Yz/8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Yzv8VEZL/AAAA/wAA
AP8AAAD/AAAA+QAAAPkAAAD/AAAA/wAAAP8IBzv/IBre/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/IRrd/wkH
Qf8AAAD/AAAA/wAAAP8AAAD5AAAA+QAAAP8AAAD/AAAA/wAAAf8dF8f/HhjL/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
y/8dGMr/AAAD/wAAAP8AAAD/AAAA/wAAAPkAAAD5AAAA/wAAAP8AAAD/AAAA/w8Ma/8fGNT/HxjT/x4Y
y/8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
y/8fGNP/HxjT/xENc/8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAPkAAAD/AAAA/wAAAP8AAAD/AQEM/yAa
2f8WEZT/GRSu/yAa3P8eGNH/HhjL/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjL/x4Y
0P8gGtz/GhSw/xURkv8hGt3/AgIQ/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAA+QAAAP8AAAD/AAAA/wAA
AP8AAAD/BQQk/xwWvf8ZFKb/CghG/xANcP8bFbb/HhjR/yAZ2v8gGt7/IBre/yAa3v8gGt7/IBnb/x4Y
0f8bFrj/EA1y/woIRv8ZE6L/HBfA/wYEJ/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAD5AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wkHQf8aFa7/GRSn/w0LXP8EBBz/BAQg/wcFL/8IBjn/CAY5/wcF
MP8EBCH/BAMb/w0LWv8ZFKX/GxWw/woIRP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAA
APkAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8BAQj/CQg6/wcGKP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8HBiX/Cgg8/wICCf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD5AAAA+QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAPkAAAD5AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAPkAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD5AAAA+QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPkAAAD5AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA+QAAAPUAAAD5AAAA+QAA
APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAA
APkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD5AAAA+QAAAPkAAAD1AAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAoAAAAMAAAAGAAAAABACAAAAAAAIAlAAAAAAAAAAAAAAAAAAAAAAAAAAAA7wAAAPcAAAD3AAAA9wAA
APcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAA
APcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAA
APcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAAD3AAAA9wAAAPcAAADvAAAA+wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD7AAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAT/AgIR/wQDG/8EAxr/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AwMZ/wQDHP8CAhL/AAAF/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AwIY/woIRP8PDGv/FhKY/xoUsf8bFbP/BQQj/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8EAx7/GhWx/xoU
s/8WEpn/EAxt/woIRv8EAxr/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wEBCP8LCU//GhSz/x8Z1v8fGdb/HxjU/x8Z1f8hGt//GBOk/wMC
Ff8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wIC
Ef8XEpz/IRrh/x8Z1f8fGNT/HxnW/x8Z1/8aFbb/CwlT/wEBC/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD/CAY4/xkUrf8iG+j/HxjS/x4Yyv8eGMv/HhjL/x4Y
zv8fGNL/IRrk/xEOev8BAAf/AAAB/wEBCf8CAhT/BAMe/wUEJP8FBCf/BQQn/wUEJP8EAx7/AgIU/wEB
Cf8AAAH/AAAG/xENcv8iG+H/HxnS/x4Yzv8eGMv/HhjL/x0Xyv8fGNH/Ihvp/xoUsv8IBzz/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAAAP8HBjP/HhjK/yAa3f8eGMz/HhfM/x4Y
zP8dF8r/HxjU/x8Z1v8XEp7/CwhL/wUEJf8HBjT/DApX/xIPfP8XEp7/GhW1/xwWvv8cF8P/HBbD/xwW
vv8bFbb/FxKf/xIOfv8NCln/BwY1/wUEJf8LCEn/FhKa/x8Z1f8fGdX/HRfK/x4XzP8dF8z/HhjM/yAa
3f8eGM7/CAY4/wAAAP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wUEKf8cFr7/HxnX/x4Y
y/8eGMv/HhjM/x0Yyv8fGdb/HRfM/w0KV/8EAxv/Dgth/xcTpP8eGM7/HxnW/x8Z1f8fGNT/HxnV/x8Z
1P8fGNP/HxjT/x8Z1P8fGdX/HxjV/x8Z1f8fGdb/HhjP/xgTpv8OC2T/BAMc/wwJUv8dF8j/HxnX/x0X
yv8eGMz/HhjL/x4Yy/8fGdb/HBfC/wYFLv8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAC/xAM
bP8gGdr/HhjK/x4YzP8eGMz/HhjM/x8Y0/8bFrv/CQc//xIOev8fGNL/IRvm/x8Z1f8eGMv/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x0XzP8eGMz/HhjM/x0XzP8eGMz/HhjL/x8Y1P8hG+b/HxjU/xIO
f/8JBz3/GhW3/x8Y0/8eGMz/HhjM/x0XzP8eGMv/IBnZ/xEOdv8AAAX/AAAA/wAAAP8AAAD3AAAA9QAA
AP8AAAD/AAAB/w4LYv8fGdX/HhfM/x4YzP8dF8z/HhfN/x4XzP8XE6D/GhW3/yAa3P8eGNL/HhfL/x4Y
zP8eF83/HhfM/x4YzP8eF8z/HhfM/x4YzP8eF8z/HhfM/x4XzP8dF8z/HhfM/x4XzP8dF8z/HhfN/x4X
zP8dF8v/HxjS/yAa3P8bFbr/FxKe/x0Xyv8eGM3/HhfM/x4XzP8dF8z/HxnU/xAMbP8AAAT/AAAA/wAA
AP8AAAD3AAAA9QAAAP8AAAD/AAAA/w0KWP8fGdX/HhjM/x0YzP8eGMz/HhjM/x4Xy/8eGM7/HxjS/x4Y
zP8eGMv/HhjO/yAa4P8hGuH/IRrj/yAZ2/8dGMv/HhjM/x0Xy/8eGMz/HhjM/x4YzP8eGMz/HhjL/yAZ
2v8hGuL/IRrh/yEa4f8eGM7/HhjL/x4YzP8fGNL/HhjO/x4Yy/8eGMv/HhjM/x4YzP8eGMz/HxnV/w4L
YP8AAAH/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wsJTf8fGdb/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x0Xy/8eGNH/HRfI/xAMb/8IBjf/CQhD/xURkf8fGdb/HRfL/x4Yy/8eGMz/HhjM/x0X
y/8dF8v/HxnW/xURlf8KCEX/BwY2/w8Ma/8dF8X/HhjS/x0Xy/8eGMz/HhjM/x0XzP8eGMz/HhjM/x0X
zP8eGMz/HxnW/wwJU/8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wkHQP8fGNT/HhfM/x4Y
zP8dF8z/HhfM/x4YzP8dF8z/HhfM/x4Y0P8fGdn/CQc+/wAAAv8AAAD/AAAA/wICEP8SDnv/IRrf/x4Y
y/8eF8z/HhfM/x4Xy/8gGt//Ew+D/wICEv8AAAD/AAAA/wAAAP8IBjr/HxnW/x4Y0f8dF8z/HhfM/x4X
zP8dF8z/HhfM/x4XzP8dF8z/HxnV/woIRv8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wcF
Mf8dF83/HhjM/x0YzP8eGMz/HhjM/x0YzP8eGMz/HhjM/yAa3f8WEpj/AAAA/wAAAP8AAAD/AAAA/wAA
AP8CAQ//HhjM/x8Y0/8eGMz/HhjM/x4Y0f8eGNH/AgIT/wAAAP8AAAD/AAAA/wAAAP8AAAD/FRGP/yAZ
3f8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjQ/wgGNv8AAAD/AAAA/wAAAP8AAAD3AAAA9QAA
AP8AAAD/AAAA/wQDHf8bFrr/HhjO/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x8Z2f8NC17/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/FhKd/yAa3v8eGMz/HhjM/yAZ3P8YE6b/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/DApU/x8Z1/8eGM3/HhjM/x0XzP8eGMz/HhjM/x0XzP8eGM3/HBbA/wUEIv8AAAD/AAAA/wAA
AP8AAAD3AAAA9QAAAP8AAAD/AAAA/wEBCf8XEpv/HxnV/x4YzP8dF8z/HhfM/x4YzP8dF8z/HhfM/yAZ
2/8ODGj/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/GBOm/yAZ3P8eF8z/HhfM/yAZ2v8aFK7/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/Dgtf/yAZ2f8eGM3/HhfM/x4XzP8dF8z/HhfM/x4XzP8fGdP/GBOk/wIB
Dv8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAAAP8RDXb/IRri/x0YzP8eGMz/HhjM/x0Y
zP8eGMz/HhjM/yAZ2/8YE6X/AAAA/wAAAP8AAAD/AAAA/wAAAP8DAhb/HxjW/x4Y0f8eGMz/HhjM/x4Y
0P8gGdr/BAMd/wAAAP8AAAD/AAAA/wAAAP8AAAD/FxKc/yAa3P8eGMv/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8hGt//Eg9//wAAAf8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAAAP8JB0H/Ihvn/x4Y
zP8eGMv/HhjL/x4YzP8eGMv/HhjM/x4Yy/8hGuH/EA1v/wMCFf8AAAT/AQAH/wUEJP8YE6X/IBnb/x4Y
y/8eGMz/HhjM/x4Yy/8gGdn/GRSr/wUEKP8BAAj/AAAE/wICFP8PDGf/IRrh/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4Yy/8iG+j/CwlK/wAAAP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAA
AP8DAhX/HxnV/x4Y0f8eGMz/HhjM/x4YzP8eGMz/HhjM/x0Xy/8eGM7/HxnV/xcSnP8QDGz/EQ12/xoU
s/8fGdj/HRfK/x0Xy/8eGMz/HRfL/x4YzP8dF8r/HxnX/xoVtv8RDnn/Dwxr/xYRmf8fGdT/HhjO/x4Y
y/8eGMz/HRfL/x4YzP8eGMz/HRfL/x4Yz/8fGdn/BAMc/wAAAP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAA
AP8AAAD/AAAA/wAAAP8AAAH/GhWz/yAZ2/8eGMv/HhjM/x4YzP8eGMz/HRfM/x4YzP8eGMv/HhjO/x8Z
1P8fGdX/HxnV/x4Y0/8eGMz/HRfL/x4YzP8eGMz/HhjM/x4XzP8eGMz/HhfM/x4Y0v8fGdT/HxnV/x8Y
1P8eGM7/HhjL/x4XzP8eGMz/HhjM/x4XzP8eGMz/HhjL/yAZ2f8bFrr/AAAC/wAAAP8AAAD/AAAA/wAA
AP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD/EAxs/yAZ3P8eGMz/HhjL/x4YzP8eGMv/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/yAa3v8RDXb/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD/BwYz/x4Yzf8eGNH/HhjM/x4Y
zP8eGMz/HhjM/x0Xy/8eGMz/HhjM/x0Xy/8eGMz/HhjM/x0Xy/8eGMz/HhjM/x0Xy/8eGMz/HRfL/x4Y
zP8eGMz/HRfL/x4YzP8eGMz/HRfL/x4YzP8eGMz/HRfL/x4YzP8eGMz/HRfL/x4YzP8eGMz/HhjQ/x4Y
z/8IBjn/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD/AwMZ/xkU
rP8fGdX/HhjM/x4YzP8eGMz/HRfM/x4YzP8eGMz/HRfM/x4YzP8eGMz/HRfM/x4YzP8eGMz/HRfM/x4Y
zP8eGMz/HhjM/x4XzP8eGMz/HhjM/x4XzP8eGMz/HhjM/x4XzP8eGMz/HhjM/x4XzP8eGMz/HhjM/x4X
zP8eGMz/HxnU/xoUsv8EAxz/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAB/w4LXf8gGdj/HhjL/x4YzP8eGMv/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMv/HxnX/w4LZf8AAAL/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wYFKv8dF8n/HhjN/x4YzP8eGMz/HhjM/x0Xy/8eGMz/HhjM/x0X
y/8eGMz/HhjM/x0Xy/8eGMz/HhjM/x0Xy/8eGMz/HRfL/x4YzP8eGMz/HRfL/x4YzP8eGMz/HRfL/x4Y
zP8eGMz/HRfL/x4YzP8eGMz/HRfL/x4YzP8eGMz/HhjN/wcGMP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAABf8TD4X/IBrg/x4Yzf8fGdf/HRfL/x4Y
y/8eGMz/HRfM/x4YzP8eGMz/HRfM/x4YzP8eGMz/HRfM/x4YzP8eGMz/HhjM/x4XzP8eGMz/HhjM/x4X
zP8eGMz/HhjM/x4XzP8eGMz/HhjM/x4Xy/8eGMr/HxnX/x4Xzv8gGt3/FRCP/wAABv8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8DAxz/IBrg/xwW
vf8VEZP/HRfI/x8Y0/8fGdT/HhjP/x4YzP8eGMv/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjL/x4YzP8eGM7/HxnU/x8Y0/8dF8r/FRGU/xsWuv8hG+T/BQQj/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/EA1u/x8Z0f8cFrz/Dgtj/xANcf8YFKf/HhjS/yAZ3P8gGtz/HxjT/x4Yz/8eGM3/HhjM/x0X
y/8eGMz/HRfL/x4YzP8eGMz/HhfN/x4Yz/8fGNP/IBrc/yAa3P8eGNL/GRSp/xENdP8OC2H/Gxa5/yAZ
0v8RDnb/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AQEJ/woISf8aFbL/IRvX/xURkv8HBjT/CAY3/w8Maf8YE6T/HRjK/x8Z
2f8gGuH/IRvm/yIb6P8hG+f/IRvn/yIb6P8hG+b/IBri/x8Z2v8dGMr/GBOm/w8MbP8IBjj/BwUz/xQQ
jf8hGtX/GxW3/wsJTf8BAQv/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/CwlQ/xkUqf8hGtv/FhKb/wsJ
TP8GBSr/AwIV/wQDH/8HBjT/CghE/wsJT/8MClb/DApW/wsJT/8KCEX/BwY1/wQDIP8DAhT/BgUp/wsJ
Sf8WEZb/IRrc/xoVrP8MClT/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wIB
Df8IBjn/Eg9z/xcTk/8XEpX/Dw1X/wEBBf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wEB
BP8ODFH/FxKV/xcTlP8SD3T/CAc7/wIBDv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAC/wICEP8FBCD/BQQb/wAAAv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAv8EBBn/BQQh/wMCEP8AAAL/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD3AAAA9QAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD3AAAA+wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD7AAAA7wAAAPUAAAD1AAAA9QAAAPUAAAD1AAAA9QAAAPUAAAD1AAAA9QAAAPUAAAD1AAAA9QAA
APUAAAD1AAAA9QAAAPUAAAD1AAAA9QAAAPUAAAD1AAAA9QAAAPUAAAD1AAAA9QAAAPUAAAD1AAAA9QAA
APUAAAD1AAAA9QAAAPUAAAD1AAAA9QAAAPUAAAD1AAAA9QAAAPUAAAD1AAAA9QAAAPUAAAD1AAAA9QAA
APUAAAD1AAAA9QAAAPUAAADvAAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA
AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA
//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA
AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA
//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAA
AAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//AAAAAAAA
//8AAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAAD//wAAAAAAAP//KAAAAEAAAACAAAAAAQAgAAAA
AAAAQgAAAAAAAAAAAAAAAAAAAAAAAAAAAOUAAADzAAAA8wAAAPMAAADzAAAA8wAAAPMAAADzAAAA8wAA
APMAAADzAAAA8wAAAPMAAADzAAAA8wAAAPMAAADzAAAA8wAAAPMAAADzAAAA8wAAAPMAAADzAAAA8wAA
APMAAADzAAAA8wAAAPMAAADzAAAA8wAAAPMAAADzAAAA8wAAAPMAAADzAAAA8wAAAPMAAADzAAAA8wAA
APMAAADzAAAA8wAAAPMAAADzAAAA8wAAAPMAAADzAAAA8wAAAPMAAADzAAAA8wAAAPMAAADzAAAA8wAA
APMAAADzAAAA8wAAAPMAAADzAAAA8wAAAPMAAADzAAAA8wAAAOUAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA8wAAAPMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPMAAADzAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADzAAAA8wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8wAA
APMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAPMAAADzAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADzAAAA8wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8wAAAPMAAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
APMAAADzAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAADzAAAA8wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8wAAAPMAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPMAAADzAAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8EAxj/CghA/w4L
Xf8TD4D/Dwxj/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/w4LXP8TEIP/Dgtf/woI
Qv8EAxv/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAADzAAAA8wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/BAMc/xAN
bf8YE6X/HhjP/yIb6P8jHPD/JR35/yce//8OC1//AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wwK
Uv8mHv//JR37/yMc8f8iG+j/HxnR/xkUqP8RDXH/BQQh/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA8wAAAPMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8EAxj/FBCF/yAZ1/8kHff/Ihzr/yAZ2P8eGM7/HhjM/x4Yyf8gGtn/JBzx/wkHOf8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wcGLv8jHOz/IRrd/x4Yyf8eGMz/HhjO/yAZ1/8iG+n/JB33/yAa2/8UEIv/BAMe/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPMAAADzAAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8NClf/IBrZ/yUd+v8gGdn/HhjK/x4Yy/8eGMz/HhjM/x4YzP8eGMr/HhjJ/yYe
//8lHvz/BgUq/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wUEIv8kHfL/Jx///x4Yyv8eGMr/HhjM/x4YzP8eGMz/HhjL/x4Y
yv8gGdf/JR35/yEa3v8OC2D/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADzAAAA8wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8UEIT/JR36/yEb4f8dGMj/HhjM/x4YzP8eGMz/HhjM/x4Y
y/8eGMn/Ihvp/yMc7/8ZFKr/Dgth/wAAAP8AAAD/AAAA/wMCEv8IBzb/DQtZ/xEOdf8UEIn/FxKY/xgT
oP8YE6D/FxKY/xQQiv8SDnf/DQtb/wgHOP8DAhT/AAAA/wAAAP8AAAD/Dgtc/xkUpv8jHO3/Ihzr/x4Y
yv8eGMv/HhjM/x4YzP8eGMz/HhjM/x0YyP8hGt7/JR78/xURj/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA8wAAAPMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8UEIr/Jh7+/x8Z0v8eGMr/HhjM/x4Y
zP8eGMz/HhjM/x0YyP8fGdX/JR35/xoVsP8HBi//AAAA/wAAAP8IBjX/Eg55/xgTov8dGMj/IRvj/yMc
8P8kHPL/Ixzu/yMc6/8iG+j/Ihvo/yMc6/8jHO7/JBzy/yMc8P8iG+T/HhjK/xgTpf8SD3v/CQc6/wAA
AP8AAAD/BgUo/xkUqf8lHfn/IBnX/x0YyP8eGMz/HhjM/x4YzP8eGMz/HhjK/x4Y0P8lHv7/FhKX/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPMAAADzAAAA/wAAAP8AAAD/AAAA/wAAAP8QDW//Jh7//x4Z
z/8eGMr/HhjM/x4YzP8eGMz/HhjM/x0YyP8hG+H/Ihvr/w4LW/8AAAD/AgEO/xANbv8bFrz/Ihzp/yQd
9P8iG+n/IBra/x8Y0P8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjQ/yAa
2f8iG+j/JB30/yMc6/8cF7//EQ1z/wMCE/8AAAD/DApR/yIb5/8iG+T/HRfH/x4YzP8eGMz/HhjM/x4Y
zP8eGMv/HhjN/yYe//8SD3v/AAAB/wAAAP8AAAD/AAAA/wAAAP8AAADzAAAA8wAAAP8AAAD/AAAA/wAA
AP8CAQr/HxnT/yEa4P8eGMr/HhjM/x4YzP8eGMz/HhjM/x4Yy/8hGt7/HhjL/wcFLf8DAxf/FhGS/yIb
5P8kHfX/IRvi/x4Yzv8eGMv/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Yy/8eGM7/IRrg/yQd9f8iG+b/FxKZ/wQDHP8GBST/HRfE/yEa
4P8eGMr/HhjM/x4YzP8eGMz/HhjM/x4Yy/8gGtv/IRrc/wMDFP8AAAD/AAAA/wAAAP8AAAD/AAAA8wAA
APMAAAD/AAAA/wAAAP8AAAD/AgEK/xwXw/8gGtv/HhjM/x4YzP8eGMz/HhjM/x4YzP8fGNH/HxnT/w8M
Zf8PDWj/Ihvn/yMc8P8fGdL/HhjK/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMr/HxjR/yMc
7/8iHOr/EQ1x/w4MYP8eGM//HxnS/x4YzP8eGMz/HhjM/x4YzP8eGMz/IBrY/x4Yy/8DAxb/AAAA/wAA
AP8AAAD/AAAA/wAAAPMAAADzAAAA/wAAAP8AAAD/AAAA/wAAA/8bFrn/IRrf/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HxjQ/xwWvf8cF8H/Ixzu/x8Z0f8eGMr/HhjM/x4YzP8eGMz/HhjN/x4Yz/8eGM7/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGM7/HhjP/x4Y
zf8eGMz/HhjM/x4YzP8eGMr/HxjP/yMc7v8dF8P/Gxa6/x8Z0P8eGMz/HhjM/x4YzP8eGMz/HhjM/yAa
2/8dF8P/AgEM/wAAAP8AAAD/AAAA/wAAAP8AAADzAAAA8wAAAP8AAAD/AAAA/wAAAP8AAAD/GhWu/yEb
4/8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Yy/8fGND/HxnU/x4Yy/8eGMz/HhjM/x4Yy/8eGMn/IRrg/yMc
7/8iG+b/Ihvp/yMc7v8fGdP/HRjI/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjJ/x8Z
0f8jHO3/Ihvp/yIb5v8jHO7/IRvi/x4Yyf8eGMv/HhjM/x4YzP8eGMv/HxnU/x8Z0P8eGMr/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8hGt//Gxa5/wAAA/8AAAD/AAAA/wAAAP8AAAD/AAAA8wAAAPMAAAD/AAAA/wAA
AP8AAAD/AAAA/xgToP8iG+n/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
y/8eGMr/Ixzt/xwWv/8PDGn/CghA/wsJSf8UEIv/Ihvj/yEa4P8dF8f/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HRfI/yAa3f8iG+b/FRGQ/wsJTP8JCED/Dwxk/xsWuf8jHO7/HhjM/x4Yy/8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/IRvl/xkUq/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
APMAAADzAAAA/wAAAP8AAAD/AAAA/wAAAP8VEY3/Ixzu/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8dF8j/Ixzw/xgUpf8BAQj/AAAA/wAAAP8AAAD/AAAA/woIQP8hGuD/IBrb/x4Y
yv8eGMz/HhjM/x4YzP8eGMz/HhjL/yAZ2P8iG+T/CwlJ/wAAAP8AAAD/AAAA/wAAAP8AAAP/FxKa/yMc
8P8dGMn/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/yMc6/8WEpn/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAADzAAAA8wAAAP8AAAD/AAAA/wAAAP8AAAD/EQ51/yMc8v8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/IRrg/x0Xxv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/DApV/yQd8/8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Yy/8kHfT/Dwxj/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8cFrz/IRvk/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8jHPD/Ew+B/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8wAAAPMAAAD/AAAA/wAAAP8AAAD/AAAA/w4L
XP8jHPH/HhjN/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/yQd9P8PDGL/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8cFrn/IRrg/x4YzP8eGMz/HhjM/x4YzP8gGtz/HRfE/wAA
Af8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/DQtW/yQc8/8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/Ixzy/w8MZv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPMAAADzAAAA/wAA
AP8AAAD/AAAA/wAAAP8KCET/Ihzp/x4Yzv8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
z/8hG+X/CAY0/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/ExCD/yMc8P8eGMz/HhjM/x4Y
zP8eGMz/Ixzt/xURkP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wYFKf8gGt7/HxnS/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjN/yMc7P8MCU3/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAADzAAAA8wAAAP8AAAD/AAAA/wAAAP8AAAD/BQQj/yAZ2P8fGdP/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8fGND/IRvg/wYFLv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/xIP
ff8jHPH/HhjM/x4YzP8eGMz/HhjM/yQc7/8UEIn/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8FBCP/IBrY/x8Z0/8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x8Z0f8hGuD/BwYv/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA8wAAAPMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAv8cFrv/IRrf/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjN/yQc8f8LCk//AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8YE6L/Ihvn/x4YzP8eGMz/HhjM/x4YzP8iG+P/GhWu/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/CghD/yMc7v8eGM7/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8gGtv/HRfF/wEBCv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPMAAADzAAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/FhGU/yMc7v8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8jG+r/GBSj/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8GBSj/Ihvo/x8Y0f8eGMz/HhjM/x4YzP8eGMz/HhjP/yMc
7f8IBzX/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/xcSl/8jHO3/HhjL/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/Ixzq/xgToP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADzAAAA8wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/w8MZP8kHfT/HhjL/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/yQc7/8QDWn/AAAA/wAAAP8AAAD/AAAA/wAAAP8BAQr/HBe//yIb6f8eGMr/HhjM/x4Y
zP8eGMz/HhjM/x4Yyv8iG+b/HhjH/wICEf8AAAD/AAAA/wAAAP8AAAD/AAAA/w4LXP8jHO3/HxjO/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjL/yQd9f8RDnH/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA8wAAAPMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8HBjL/Ihvk/x8Y0P8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Yyv8fGdX/Ixzu/xQQhP8GBSn/AgEL/wMCEf8LCEf/HBa+/yMc
7f8dF8j/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HRfH/yMc6/8dF8X/CwlM/wMCFP8CAQv/BQQm/xIO
fP8jHOz/IBnY/x4Yyf8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Yzv8iHOr/CQc9/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPMAAADzAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AQEI/x0X
xv8gGtz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjJ/x8Y0P8jHO7/IBnX/x0X
wv8dF8b/Ihvn/yEb5P8dF8j/HhjL/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8dF8f/IRrh/yIb
6f8dGMj/HBfB/x8Z1f8jHO//HxnS/x4Yyf8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8gGdj/HhjO/wICD/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADzAAAA8wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8WEpT/Ixzw/x4Yy/8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjL/x8Z1P8gGtz/IBra/x4Yz/8eGMv/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4Yy/8eGM7/IBrZ/yAa3P8fGdX/HhjL/x4Yy/8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMv/Ixzs/xgToP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8wAA
APMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/DApT/yQc8/8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjL/yQd9v8OC2D/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAPMAAADzAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wMCEP8fGdH/IBnY/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x8Z1f8gGtn/BAMa/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADzAAAA8wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/FxKc/yMc7/8eGMv/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
y/8jHOv/GRSm/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8wAAAPMAAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wwKUv8kHfX/HhjL/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMr/JR33/w4LYP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
APMAAADzAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8BAQf/HhjI/yEa3f8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/IBrY/x8Y0v8CAg//AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAADzAAAA8wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/xMP
gf8lHfj/HhjK/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjK/yQd9f8UEYz/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8wAAAPMAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8GBSn/Ihzp/x8Y0f8eGMz/HhjN/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zv8jHO//CAc1/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPMAAADzAAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/xcSnP8jHPH/HRfF/yAZ1/8gGt3/HhjL/x4Y
y/8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjL/x4Y
yv8gGtz/IBnZ/x0Xxf8jHO3/GRSp/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAADzAAAA8wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8HBjP/JB35/x8Z
0v8WEZT/FxOe/yMc7f8iG+f/HhjO/x4Yyv8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMr/HhjN/yIb5f8jHO//GBOj/xURkf8eGM7/JR79/woIQP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA8wAAAPMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/xcTnf8oIP//HBa+/w8MY/8LCU3/FhKX/yIb5v8kHfP/IBrd/x4Yz/8eGMv/HhjM/x4Y
zP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zP8eGMz/HhjL/x4Yzv8gGtv/JB3y/yIb6f8XEp3/DAlP/w4LX/8bFrf/KCD//xkUqv8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPMAAADzAAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8BAQX/FRGM/yYf//8mHv//Eg9+/wUEJf8GBCb/EQ5y/x0X
wv8iG+b/JB3z/yMc7P8hGt7/HxnV/x8Y0P8eGM7/HhjN/x4YzP8eGMz/HhjM/x4YzP8eGMz/HhjM/x4Y
zf8eGM7/HxjQ/x8Z1P8hGt3/Ixzr/yQd8/8iG+f/HRfF/xIOeP8GBSn/BQQj/xEOdv8lHv7/Jx///xYR
lf8CAQr/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADzAAAA8wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8JCEH/Gxa3/ykh
//8lHfj/EQ51/wIBDf8AAAD/BAMZ/w4LYv8XEpr/HBe//x8Z1f8hG+P/Ihvq/yMc7v8kHPL/JBzy/yMc
8P8jHPD/Ixzy/yQd8v8jHO7/Ihzq/yEb5P8fGdb/HBfA/xcTnf8PDGb/BAMd/wAAAP8BAQr/EA1t/yQc
8v8qIf//HBa+/wsJSP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA8wAAAPMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8MClP/GhW0/ygg//8mHv//FxOh/wcFMf8AAAD/AAAA/wAAAP8EAxz/CAc4/wsJ
S/8NC1n/Dwxl/xANb/8RDnX/EQ51/xANb/8PDGb/DQta/wsJTP8IBzn/BAMf/wAAAP8AAAD/AAAA/wYF
K/8WEZr/Jh7//ykg//8bFrr/DQtY/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPMAAADzAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8IBzb/FBCG/yEc1f8mH/f/IBrX/xcS
mf8ODFb/AAEA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8OC1D/FhKW/yAa1P8mH/f/IhzY/xURi/8JBzr/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADzAAAA8wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAQD/BwYj/xAOXf8XE47/GRWL/wUFFf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8EBBD/GBSF/xcTkf8RDmH/CAcm/wEBAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8wAA
APMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAPMAAADzAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADzAAAA8wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8wAAAPMAAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
APMAAADzAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAADzAAAA8wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8wAAAPMAAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPMAAADzAAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAADzAAAA8wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA8wAAAPMAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPMAAADzAAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADzAAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAOUAAADzAAAA8wAAAPMAAADzAAAA8wAAAPMAAADzAAAA8wAAAPMAAADzAAAA8wAA
APMAAADzAAAA8wAAAPMAAADzAAAA8wAAAPMAAADzAAAA8wAAAPMAAADzAAAA8wAAAPMAAADzAAAA8wAA
APMAAADzAAAA8wAAAPMAAADzAAAA8wAAAPMAAADzAAAA8wAAAPMAAADzAAAA8wAAAPMAAADzAAAA8wAA
APMAAADzAAAA8wAAAPMAAADzAAAA8wAAAPMAAADzAAAA8wAAAPMAAADzAAAA8wAAAPMAAADzAAAA8wAA
APMAAADzAAAA8wAAAPMAAADzAAAA8wAAAOUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
</value>
</data>
</root>

View File

@ -1,19 +0,0 @@
using System;
using System.Windows.Forms;
namespace BetterDiscordWI
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FormMain());
}
}
}

View File

@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("BetterDiscordWI")]
[assembly: AssemblyDescription("Better Discord Windows Installer")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Jiiks")]
[assembly: AssemblyProduct("BetterDiscordWI")]
[assembly: AssemblyCopyright("Copyright © 2015-2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("17adafc9-c3e6-49c2-b2c9-d6866e7f4f23")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.2.8.0")]
[assembly: AssemblyFileVersion("0.2.8.0")]

View File

@ -1,103 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace BetterDiscordWI.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BetterDiscordWI.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap bd_logo_64x64 {
get {
object obj = ResourceManager.GetObject("bd_logo_64x64", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap bd_logo_64x64_nobg {
get {
object obj = ResourceManager.GetObject("bd_logo_64x64_nobg", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap bd_logo_large_nobg {
get {
object obj = ResourceManager.GetObject("bd_logo_large_nobg", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap bd_logo2 {
get {
object obj = ResourceManager.GetObject("bd_logo2", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}

View File

@ -1,133 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="bd_logo2" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\bd_logo2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="bd_logo_64x64" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\bd_logo_64x64.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="bd_logo_64x64_nobg" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\bd_logo_64x64_nobg.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="bd_logo_large_nobg" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\bd_logo_large_nobg.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

View File

@ -1,26 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace BetterDiscordWI.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@ -1,7 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 MiB

View File

@ -1,46 +0,0 @@
using System;
using System.Diagnostics;
using System.Net;
using System.Threading;
using System.Windows.Forms;
namespace BetterDiscordWI
{
class Utils
{
public void StartDownload(ProgressBar pb, string url, string name)
{
Thread t = new Thread(() =>
{
WebClient webClient = new WebClient {Headers = {["User-Agent"] = "Mozilla/5.0"}};
webClient.DownloadProgressChanged += delegate(object sender, DownloadProgressChangedEventArgs args)
{
double percentage = (double.Parse(args.BytesReceived.ToString()) /double.Parse(args.TotalBytesToReceive.ToString())) * 100;
Debug.Print(percentage.ToString());
pb.Invoke((MethodInvoker) delegate
{
pb.Value = (int)Math.Truncate(percentage);
});
};
webClient.DownloadFile(new Uri(url), Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\BetterDiscord\\temp\\" + name);
});
t.Start();
}
public static string GetHash()
{
WebClient wc = new WebClient {Headers = {["User-Agent"] = "Mozilla/5.0"}};
string result = wc.DownloadString(@"https://api.github.com/repos/Jiiks/BetterDiscordApp/commits/master");
int start = result.IndexOf("{\"sha\":");
int end = result.IndexOf("\",\"");
return result.Substring(start + 8, end - 8);
}
}
}

View File

@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace BetterDiscordWI.components
{
class CTextBox : TextBox
{
public bool CAutoSize
{
get { return AutoSize; }
set { AutoSize = value; }
}
}
}

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Costura.Fody" version="1.6.2" targetFramework="net451" developmentDependency="true" />
<package id="Fody" version="2.0.0" targetFramework="net451" developmentDependency="true" />
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net451" />
</packages>

View File

@ -1,8 +0,0 @@
namespace BetterDiscordWI.panels {
interface IPanel {
void SetVisible();
FormMain GetParent();
void BtnNext();
void BtnPrev();
}
}

View File

@ -1,100 +0,0 @@
namespace BetterDiscordWI.panels
{
partial class Panel0
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Panel0));
this.label2 = new System.Windows.Forms.Label();
this.richTextBox1 = new System.Windows.Forms.RichTextBox();
this.radioDeclineLicense = new System.Windows.Forms.RadioButton();
this.radioAcceptLicense = new System.Windows.Forms.RadioButton();
this.SuspendLayout();
//
// label2
//
this.label2.Location = new System.Drawing.Point(35, 18);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(455, 31);
this.label2.TabIndex = 5;
this.label2.Text = "Please read the following License Agreement and accept the terms before continuin" +
"g the installation.";
//
// richTextBox1
//
this.richTextBox1.Location = new System.Drawing.Point(38, 54);
this.richTextBox1.Name = "richTextBox1";
this.richTextBox1.ReadOnly = true;
this.richTextBox1.Size = new System.Drawing.Size(452, 169);
this.richTextBox1.TabIndex = 4;
this.richTextBox1.Text = resources.GetString("richTextBox1.Text");
//
// radioDeclineLicense
//
this.radioDeclineLicense.AutoSize = true;
this.radioDeclineLicense.Checked = true;
this.radioDeclineLicense.Location = new System.Drawing.Point(108, 229);
this.radioDeclineLicense.Name = "radioDeclineLicense";
this.radioDeclineLicense.Size = new System.Drawing.Size(61, 17);
this.radioDeclineLicense.TabIndex = 8;
this.radioDeclineLicense.TabStop = true;
this.radioDeclineLicense.Text = "Decline";
this.radioDeclineLicense.UseVisualStyleBackColor = true;
//
// radioAcceptLicense
//
this.radioAcceptLicense.AutoSize = true;
this.radioAcceptLicense.Location = new System.Drawing.Point(38, 229);
this.radioAcceptLicense.Name = "radioAcceptLicense";
this.radioAcceptLicense.Size = new System.Drawing.Size(59, 17);
this.radioAcceptLicense.TabIndex = 7;
this.radioAcceptLicense.Text = "Accept";
this.radioAcceptLicense.UseVisualStyleBackColor = true;
//
// Panel0
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.radioDeclineLicense);
this.Controls.Add(this.radioAcceptLicense);
this.Controls.Add(this.label2);
this.Controls.Add(this.richTextBox1);
this.Name = "Panel0";
this.Size = new System.Drawing.Size(524, 258);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label2;
private System.Windows.Forms.RichTextBox richTextBox1;
private System.Windows.Forms.RadioButton radioDeclineLicense;
private System.Windows.Forms.RadioButton radioAcceptLicense;
}
}

View File

@ -1,31 +0,0 @@
using System.Windows.Forms;
namespace BetterDiscordWI.panels {
public partial class Panel0 : UserControl, IPanel {
public Panel0() {
InitializeComponent();
radioAcceptLicense.CheckedChanged += (sender, args) => {
GetParent().btnNext.Enabled = radioAcceptLicense.Checked;
};
}
public void SetVisible() {
GetParent().btnBack.Visible = false;
GetParent().btnNext.Enabled = false;
GetParent().btnNext.Text = @"Next >";
GetParent().lblPanelTitle.Text = @"BetterDiscord License Agreement";
GetParent().btnNext.Enabled = radioAcceptLicense.Checked;
}
public FormMain GetParent() {
return (FormMain)ParentForm;
}
public void BtnNext() {
GetParent().SwitchPanel(1);
}
public void BtnPrev() {}
}
}

View File

@ -1,131 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="richTextBox1.Text" xml:space="preserve">
<value>Copyright (c) 2015 Jiiks
http://jiiks.net
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</value>
</data>
</root>

View File

@ -1,171 +0,0 @@
namespace BetterDiscordWI.panels
{
partial class Panel1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.btnBrowser = new System.Windows.Forms.Button();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.cbRestart = new System.Windows.Forms.CheckBox();
this.checkBox1 = new System.Windows.Forms.CheckBox();
this.checkBox2 = new System.Windows.Forms.CheckBox();
this.checkBox3 = new System.Windows.Forms.CheckBox();
this.tbPath = new BetterDiscordWI.components.CTextBox();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(20, 17);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(380, 13);
this.label1.TabIndex = 0;
this.label1.Text = "Setup will install BetterDiscord to the following location. Click Install to cont" +
"inue.";
//
// btnBrowser
//
this.btnBrowser.Location = new System.Drawing.Point(406, 46);
this.btnBrowser.Name = "btnBrowser";
this.btnBrowser.Size = new System.Drawing.Size(75, 26);
this.btnBrowser.TabIndex = 2;
this.btnBrowser.Text = "Browse";
this.btnBrowser.UseVisualStyleBackColor = true;
this.btnBrowser.Click += new System.EventHandler(this.btnBrowser_Click);
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(20, 75);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(422, 13);
this.label2.TabIndex = 3;
this.label2.Text = "*If the path is not pointing to the latest version of Discord then click browse a" +
"nd select it.";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(20, 91);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(161, 13);
this.label3.TabIndex = 5;
this.label3.Text = "*Installer will kill Discord process.";
//
// cbRestart
//
this.cbRestart.AutoSize = true;
this.cbRestart.Checked = true;
this.cbRestart.CheckState = System.Windows.Forms.CheckState.Checked;
this.cbRestart.Location = new System.Drawing.Point(23, 117);
this.cbRestart.Name = "cbRestart";
this.cbRestart.Size = new System.Drawing.Size(175, 17);
this.cbRestart.TabIndex = 6;
this.cbRestart.Text = "Restart Discord after installation";
this.cbRestart.UseVisualStyleBackColor = true;
//
// checkBox1
//
this.checkBox1.AutoSize = true;
this.checkBox1.Location = new System.Drawing.Point(23, 140);
this.checkBox1.Name = "checkBox1";
this.checkBox1.Size = new System.Drawing.Size(137, 17);
this.checkBox1.TabIndex = 7;
this.checkBox1.Text = "Install to DiscordCanary";
this.checkBox1.UseVisualStyleBackColor = true;
this.checkBox1.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged);
//
// checkBox2
//
this.checkBox2.AutoSize = true;
this.checkBox2.Location = new System.Drawing.Point(23, 163);
this.checkBox2.Name = "checkBox2";
this.checkBox2.Size = new System.Drawing.Size(436, 17);
this.checkBox2.TabIndex = 8;
this.checkBox2.Text = "Install to DiscordPTB (Can break at any time)(Installer will be updated frequentl" +
"y for this)";
this.checkBox2.UseVisualStyleBackColor = true;
this.checkBox2.CheckedChanged += new System.EventHandler(this.checkBox2_CheckedChanged);
//
// checkBox3
//
this.checkBox3.AutoSize = true;
this.checkBox3.Checked = true;
this.checkBox3.CheckState = System.Windows.Forms.CheckState.Checked;
this.checkBox3.Location = new System.Drawing.Point(23, 187);
this.checkBox3.Name = "checkBox3";
this.checkBox3.Size = new System.Drawing.Size(149, 17);
this.checkBox3.TabIndex = 9;
this.checkBox3.Text = "Use Zere\'s (unofficial) fork";
this.checkBox3.UseVisualStyleBackColor = true;
this.checkBox3.CheckedChanged += new System.EventHandler(this.checkBox3_CheckedChanged);
//
// tbPath
//
this.tbPath.CAutoSize = false;
this.tbPath.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.tbPath.Location = new System.Drawing.Point(23, 46);
this.tbPath.Name = "tbPath";
this.tbPath.Size = new System.Drawing.Size(377, 26);
this.tbPath.TabIndex = 4;
//
// Panel1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.checkBox3);
this.Controls.Add(this.checkBox2);
this.Controls.Add(this.checkBox1);
this.Controls.Add(this.cbRestart);
this.Controls.Add(this.label3);
this.Controls.Add(this.tbPath);
this.Controls.Add(this.label2);
this.Controls.Add(this.btnBrowser);
this.Controls.Add(this.label1);
this.Name = "Panel1";
this.Size = new System.Drawing.Size(524, 258);
this.Load += new System.EventHandler(this.Panel1_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button btnBrowser;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.CheckBox cbRestart;
internal components.CTextBox tbPath;
private System.Windows.Forms.CheckBox checkBox1;
private System.Windows.Forms.CheckBox checkBox2;
private System.Windows.Forms.CheckBox checkBox3;
}
}

View File

@ -1,140 +0,0 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace BetterDiscordWI.panels {
public partial class Panel1: UserControl, IPanel {
public Panel1() {
InitializeComponent();
}
public void SetVisible() {
GetParent().btnBack.Visible = true;
GetParent().btnNext.Enabled = true;
GetParent().btnBack.Enabled = true;
GetParent().btnNext.Text = @"Install";
GetParent().lblPanelTitle.Text = @"BetterDiscord Installation";
PickVersion();
}
public FormMain GetParent() {
return (FormMain)ParentForm;
}
public void BtnNext() {
GetParent().DiscordPath = tbPath.Text;
GetParent().RestartDiscord = cbRestart.Checked;
GetParent().SwitchPanel(2);
GetParent().ZeresFork = checkBox3.Checked;
}
public void BtnPrev() {
GetParent().SwitchPanel(0);
}
private void btnBrowser_Click(object sender, EventArgs e) {
FolderBrowserDialog fbd = new FolderBrowserDialog { SelectedPath = tbPath.Text };
fbd.ShowDialog(GetParent());
tbPath.Text = fbd.SelectedPath;
}
private void checkBox1_CheckedChanged(object sender, EventArgs e) {
PickVersion();
}
private void checkBox2_CheckedChanged(object sender, EventArgs e) {
PickVersion();
}
private void PickVersion() {
string dirPath;
if(checkBox1.Checked) {
dirPath = $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\DiscordCanary";
if(!Directory.Exists(dirPath)) checkBox1.Checked = false;
checkBox2.Checked = false;
} else if(checkBox2.Checked) {
dirPath = $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\DiscordPTB";
if(!Directory.Exists(dirPath)) checkBox2.Checked = false;
checkBox1.Checked = false;
} else {
dirPath = $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\Discord";
}
if (checkBox1.Checked)
GetParent().DiscordVersion = "DiscordCanary";
else if (checkBox2.Checked)
GetParent().DiscordVersion = "DiscordPTB";
else
GetParent().DiscordVersion = "Discord";
if (!Directory.Exists(dirPath)) return;
GetParent().DesktopModule = false;
string otherDir = $"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\{GetParent().DiscordVersion.ToLower()}";
if (Directory.Exists(otherDir))
{
string[] dirs = Directory.GetDirectories(otherDir);
string maxVersion = dirs[0];
Regex matcher = new Regex(@"[0-9]+\.[0-9]+\.[0-9]+");
foreach (string s in dirs)
{
Debug.Print(s);
if (!matcher.IsMatch(s))
continue;
if (string.CompareOrdinal(s, maxVersion) > 0)
{
maxVersion = s;
}
}
string coreModule = $"{maxVersion}\\modules\\discord_desktop_core";
if (Directory.Exists(coreModule))
{
tbPath.Text = coreModule;
GetParent().DesktopModule = true;
}
}
string[] directories = Directory.GetDirectories(dirPath);
string highestVersion = null;
foreach (string s in directories) {
Debug.Print(s);
if(!s.Contains("app-"))
continue;
if(string.IsNullOrEmpty(highestVersion)) {
highestVersion = s;
continue;
}
if(string.CompareOrdinal(s, highestVersion) > 0) {
highestVersion = s;
}
}
GetParent().DiscordInstallPath = highestVersion;
if (!GetParent().DesktopModule)
{
tbPath.Text = highestVersion;
}
}
private void Panel1_Load(object sender, EventArgs e)
{
}
private void checkBox3_CheckedChanged(object sender, EventArgs e)
{
}
}
}

View File

@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1,67 +0,0 @@
namespace BetterDiscordWI.panels
{
partial class Panel2
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.pbMain = new System.Windows.Forms.ProgressBar();
this.rtLog = new System.Windows.Forms.RichTextBox();
this.SuspendLayout();
//
// pbMain
//
this.pbMain.Location = new System.Drawing.Point(3, 267);
this.pbMain.Name = "pbMain";
this.pbMain.Size = new System.Drawing.Size(518, 16);
this.pbMain.TabIndex = 0;
//
// rtLog
//
this.rtLog.Location = new System.Drawing.Point(3, 3);
this.rtLog.Name = "rtLog";
this.rtLog.Size = new System.Drawing.Size(518, 252);
this.rtLog.TabIndex = 1;
this.rtLog.Text = "";
//
// Panel2
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.rtLog);
this.Controls.Add(this.pbMain);
this.Name = "Panel2";
this.Size = new System.Drawing.Size(524, 258);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ProgressBar pbMain;
private System.Windows.Forms.RichTextBox rtLog;
}
}

View File

@ -1,415 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Threading;
using System.Windows.Forms;
using asardotnet;
namespace BetterDiscordWI.panels {
public partial class Panel2: UserControl, IPanel {
private string _dataPath, _tempPath;
private Utils _utils;
public Panel2() {
InitializeComponent();
}
public void SetVisible() {
GetParent().btnBack.Enabled = false;
GetParent().btnNext.Enabled = false;
GetParent().btnBack.Visible = false;
GetParent().btnNext.Visible = false;
GetParent().btnCancel.Enabled = false;
_utils = new Utils();
//KillProcessIfInstalling("Discord");
//KillProcessIfInstalling("DiscordCanary");
//KillProcessIfInstalling("DiscordPTB");
KillRunningProcess();
CreateDirectories();
}
private void KillRunningProcess()
{
AppendLog("Killing " + GetParent().DiscordVersion);
foreach (var process in Process.GetProcessesByName(GetParent().DiscordVersion))
{
process.Kill();
}
}
private void KillProcessIfInstalling(string app) {
if (!GetParent().DiscordPath.Contains(app + "\\")) return;
AppendLog("Killing " + app);
foreach(var process in Process.GetProcessesByName(app)) {
process.Kill();
}
}
private void CreateDirectories() {
Thread t = new Thread(() => {
_dataPath = $"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\BetterDiscord";
_tempPath = $"{_dataPath}\\temp";
AppendLog("Deleting old cached files");
try {
if(File.Exists($"{_dataPath}\\emotes_bttv.json")) {
File.Delete($"{_dataPath}\\emotes_bttv.json");
}
if(File.Exists($"{_dataPath}\\emotes_bttv_2.json")) {
File.Delete($"{_dataPath}\\emotes_bttv_2.json");
}
if(File.Exists($"{_dataPath}\\emotes_ffz.json")) {
File.Delete($"{_dataPath}\\emotes_ffz.json");
}
if(File.Exists($"{_dataPath}\\emotes_twitch_global.json")) {
File.Delete($"{_dataPath}\\emotes_twitch_global.json");
}
if(File.Exists($"{_dataPath}\\emotes_twitch_subscriber.json")) {
File.Delete($"{_dataPath}\\emotes_twitch_subscriber.json");
}
if(File.Exists($"{_dataPath}\\user.json")) {
File.Delete($"{_dataPath}\\user.json");
}
} catch(Exception e) { AppendLog("Failed to delete one or more cached files"); }
if(Directory.Exists(_tempPath)) {
AppendLog("Deleting temp path");
Directory.Delete(_tempPath, true);
}
while(Directory.Exists(_tempPath)) {
Debug.Print("Waiting for dirdel");
Thread.Sleep(100);
}
Directory.CreateDirectory(_tempPath);
String fork = "Jiiks";
if (GetParent().ZeresFork) fork = "rauenzi";
DownloadResource("BetterDiscord.zip", $"https://github.com/{fork}/BetterDiscordApp/archive/stable16.zip");
while(!File.Exists($"{_tempPath}\\BetterDiscord.zip")) {
Debug.Print("Waiting for download");
Thread.Sleep(100);
}
AppendLog("Extracting BetterDiscord");
ZipArchive zar =
ZipFile.OpenRead($"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\BetterDiscord\\temp\\BetterDiscord.zip");
zar.ExtractToDirectory($"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\BetterDiscord\\temp\\");
DeleteDirs();
});
t.Start();
}
private void DeleteDirs() {
int errors = 0;
Thread t1 = new Thread(() => {
string dir = $"{GetParent().DiscordPath}\\resources\\app";
if(Directory.Exists(dir)) {
try {
AppendLog("Deleting " + dir);
Directory.Delete(dir, true);
} catch {
AppendLog($"Error: Failed to Delete the '{dir}\\resources\\app' Directory.");
errors = 1;
Finalize(errors);
}
}
while(Directory.Exists(dir)) {
Debug.Print("Waiting for direl");
Thread.Sleep(100);
}
//C:\Users\Zack\AppData\Roaming\discordcanary
if (!Directory.Exists($"{GetParent().DiscordPath}\\resources\\node_modules\\")) {
Debug.Print("node_modules doesn't exist, creating");
AppendLog("node_modules doesn't exist, creating");
Directory.CreateDirectory($"{GetParent().DiscordPath}\\resources\\node_modules\\");
}
dir = $"{GetParent().DiscordPath}\\resources\\node_modules\\BetterDiscord";
if(Directory.Exists(dir)) {
AppendLog($"Deleting {dir}");
Directory.Delete(dir, true);
}
while(Directory.Exists(dir)) {
Debug.Print("Waiting for direl");
Thread.Sleep(100);
}
AppendLog("Extracting app.asar");
string appAsarPath = $"{GetParent().DiscordPath}\\resources\\app.asar";
if(File.Exists(appAsarPath)) {
AsarArchive archive = new AsarArchive(appAsarPath);
AsarExtractor extractor = new AsarExtractor();
extractor.ExtractAll(archive, $"{GetParent().DiscordPath}\\resources\\app\\");
} else {
AppendLog("Error: app.asar file couldn't be found in 'resources' folder. Installation cannot Continue.");
errors = 1;
Finalize(errors);
}
if(errors == 0) {
AppendLog("Moving BetterDiscord to resources\\node_modules\\");
Directory.Move($"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\BetterDiscord\\temp\\BetterDiscordApp-stable16", $"{GetParent().DiscordPath}\\resources\\node_modules\\BetterDiscord");
try {
Splice();
} catch {
AppendLog("Error: Splicing index.js: Newtonsoft.Json.dll might not be present in the Installer Folder. Installation cannot Continue.");
errors = 1;
Finalize(errors);
}
}
});
Thread t2 = new Thread(() => {
string dir = $"{GetParent().DiscordPath}\\index.js";
if (File.Exists(dir + ".old") && File.Exists(dir))
{
AppendLog($"Restoring original {dir}");
File.Delete(dir);
while (File.Exists(dir))
{
Debug.Print("Waiting for direl");
Thread.Sleep(100);
}
File.Move(dir + ".old", dir);
}
AppendLog($"Making backup of {dir}");
File.Copy(dir, dir + ".old");
File.WriteAllText(dir, "module.exports = require('./core');");
dir = $"{GetParent().DiscordPath}\\core";
if (Directory.Exists(dir))
{
try
{
AppendLog("Deleting " + dir);
Directory.Delete(dir, true);
while (Directory.Exists(dir))
{
Debug.Print("Waiting for direl");
Thread.Sleep(100);
}
}
catch
{
AppendLog($"Error: Failed to Delete the '{dir}\\core' Directory.");
errors = 1;
Finalize(errors);
}
}
AppendLog("Extracting core.asar");
string appAsarPath = $"{GetParent().DiscordPath}\\core.asar";
if (File.Exists(appAsarPath))
{
AsarArchive archive = new AsarArchive(appAsarPath);
AsarExtractor extractor = new AsarExtractor();
extractor.ExtractAll(archive, $"{GetParent().DiscordPath}\\core\\");
}
else
{
AppendLog("Error: core.asar file couldn't be found. Installation cannot Continue.");
errors = 1;
Finalize(errors);
}
dir = $"{GetParent().DiscordPath}\\core\\node_modules\\BetterDiscord";
if (Directory.Exists(dir))
{
AppendLog($"Deleting {dir}");
Directory.Delete(dir, true);
while (Directory.Exists(dir))
{
Debug.Print("Waiting for direl");
Thread.Sleep(100);
}
}
if (errors == 0)
{
AppendLog("Moving BetterDiscord to node_modules");
Directory.Move($"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\BetterDiscord\\temp\\BetterDiscordApp-stable16", dir);
try
{
Splice();
}
catch
{
AppendLog("Error: Splicing mainScreen.js: Newtonsoft.Json.dll might not be present in the Installer Folder. Installation cannot Continue.");
errors = 1;
Finalize(errors);
}
}
});
if (GetParent().DesktopModule) t2.Start();
else t1.Start();
}
private void DownloadResource(string resource, string url) {
AppendLog("Downloading Resource: " + resource);
WebClient webClient = new WebClient {Headers = {["User-Agent"] = "Mozilla/5.0"}};
webClient.DownloadFile(new Uri(url), $"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\BetterDiscord\\temp\\{resource}");
}
private void Splice()
{
string indexloc = null;
if (File.Exists($"{GetParent().DiscordPath}\\resources\\app\\index.js"))
{
indexloc = $"{GetParent().DiscordPath}\\resources\\app\\index.js";
}
else if (File.Exists($"{GetParent().DiscordPath}\\core\\app\\mainScreen.js"))
{
indexloc = $"{GetParent().DiscordPath}\\core\\app\\mainScreen.js";
}
if (indexloc == null)
{
AppendLog($"Error: index.js or mainScreen.js not found");
Finalize(1);
return;
}
//if (!File.Exists(@"splice"))
//{
// AppendLog($"Error: splice install file not found, this should be included with the installer.");
// Finalize(1);
// return;
//}
Thread t = new Thread(() => {
List<string> lines = new List<string>();
AppendLog("Splicing main file");
using (FileStream fs = new FileStream(indexloc, FileMode.Open))
{
using (StreamReader reader = new StreamReader(fs))
{
string line = "";
while ((line = reader.ReadLine()) != null)
{
if (line.Replace(" ", "").Contains("var_url="))
{
lines.Add(line);
lines.Add("var _betterDiscord = require('betterdiscord');");
lines.Add("var _betterDiscord2;");
}
else if (line.Replace(" ", "").Contains("mainWindow=new"))
{
lines.Add(line);
lines.Add("_betterDiscord2 = new _betterDiscord.BetterDiscord(mainWindow);");
}
else
{
lines.Add(line);
}
}
}
}
AppendLog("Writing injection");
File.WriteAllLines(indexloc, lines.ToArray());
AppendLog("Finished installation, verifying installation...");
int errors = 0;
string curPath = $"{GetParent().DiscordPath}\\resources\\app\\index.js";
string curPath2 = $"{GetParent().DiscordPath}\\core\\app\\mainScreen.js";
if (!File.Exists(curPath) && !File.Exists(curPath2))
{
AppendLog($"ERROR: index.js or mainScreen.js not found in {curPath} or {curPath2}");
errors++;
}
if (GetParent().DesktopModule)
curPath = $"{GetParent().DiscordPath}\\core\\node_modules\\BetterDiscord";
else
curPath = $"{GetParent().DiscordPath}\\resources\\node_modules\\BetterDiscord";
if (!Directory.Exists(curPath))
{
AppendLog($"ERROR: DIRECTORY: {curPath} DOES NOT EXIST!");
errors++;
}
string[] bdFiles = { "\\package.json", "\\betterdiscord.js", "\\lib\\BetterDiscord.js", "\\lib\\config.json", "\\lib\\Utils.js" };
foreach (string s in bdFiles.Where(s => !File.Exists(curPath + s)))
{
AppendLog($"ERROR: FILE: {curPath}{s} DOES NOT EXIST");
errors++;
}
Finalize(errors);
});
t.Start();
}
private void Finalize(int errors) {
AppendLog($"Finished installing BetterDiscord with {errors} errors");
Invoke((MethodInvoker)delegate {
GetParent().Finished = true;
GetParent().btnCancel.Text = @"OK";
GetParent().btnCancel.Enabled = true;
});
if(GetParent().RestartDiscord) {
Process.Start($"{GetParent().DiscordInstallPath}\\{GetParent().DiscordVersion}.exe");
}
}
public FormMain GetParent() {
return (FormMain)ParentForm;
}
public void BtnNext() { }
public void BtnPrev() { }
private void AppendLog(string message) {
Invoke((MethodInvoker)delegate {
rtLog.AppendText(message + "\n");
rtLog.SelectionStart = rtLog.Text.Length;
rtLog.ScrollToCaret();
});
}
}
}

View File

@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1,37 +0,0 @@
namespace BetterDiscordWI.panels
{
partial class Panel3
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
}
#endregion
}
}

View File

@ -1,12 +0,0 @@
using System.Windows.Forms;
namespace BetterDiscordWI.panels
{
public partial class Panel3 : UserControl
{
public Panel3()
{
InitializeComponent();
}
}
}

View File

@ -1,2 +0,0 @@
## To Compile Move the DLL's folder to ``BetterDiscordWI\bin``
## Enjoy Building the Installer.

View File

@ -1,66 +0,0 @@
//META{"name":"agif"}*//
var agif = function () {};
// Autoplay GIFs
agif.prototype.convert = function (target) {
// Handle GIF
$(target).find(".image:has(canvas)").each(function () {
var image = $(this);
var canvas = image.children("canvas").first();
// Replace GIF preview with actual image
var src = canvas.attr("src");
if(src !== undefined) {
image.replaceWith($("<img>", {
src: canvas.attr("src"),
width: canvas.attr("width"),
height: canvas.attr("height"),
}).addClass("image kawaii-autogif"));
}
});
// Handle GIFV
$(target).find(".embed-thumbnail-gifv:has(video)").each(function () {
var embed = $(this);
var video = embed.children("video").first();
// Remove the class, embed-thumbnail-gifv, to avoid the "GIF" overlay
embed.removeClass("embed-thumbnail-gifv").addClass("kawaii-autogif");
// Prevent the default behavior of pausing the video
embed.parent().on("mouseout.autoGif", function (event) {
event.stopPropagation();
});
video[0].play();
});
};
agif.prototype.onMessage = function () {};
agif.prototype.onSwitch = function () {};
agif.prototype.start = function () {
this.convert(document);
};
agif.prototype.observer = function (e) {
this.convert(e.target);
};
agif.prototype.load = function () {};
agif.prototype.unload = function () {};
agif.prototype.stop = function () {};
agif.prototype.getSettingsPanel = function () {
return "";
};
agif.prototype.getName = function () {
return "Autogif";
};
agif.prototype.getDescription = function () {
return "Autoplay gifs without having to hover.";
};
agif.prototype.getVersion = function () {
return "1.0.0";
};
agif.prototype.getAuthor = function () {
return "noodlebox";
};

View File

@ -1,97 +0,0 @@
//META{"name":"customGamePlugin"}*//
/*
* #####################READ THIS!################################
* #####################READ THIS!################################
*
* This plugin is discontinued and no longer works due to Discord having custom game title built in and is kept for archiving purposes only.
*
* #####################READ THIS!################################
* #####################READ THIS!################################
*/
function customGamePlugin() {}
customGamePlugin.prototype.load = function() {
};
customGamePlugin.prototype.unload = function() {
};
customGamePlugin.prototype.start = function() {
return;
var self = this;
this.enabled = true;
this.interval = setInterval(function() {
self.setPlaying();
}, 60000);
this.setPlaying();
};
customGamePlugin.prototype.stop = function() {
return;
var gp = this.game;
this.game = "";
this.setPlaying();
this.game = gp;
clearInterval(this.interval);
this.enabled = false;
};
customGamePlugin.prototype.getName = function() {
return "Custom Game";
};
customGamePlugin.prototype.getDescription = function() {
return "Set custom game as your playing status";
};
customGamePlugin.prototype.getVersion = function() {
return "1.0";
};
customGamePlugin.prototype.getAuthor = function() {
return "Jiiks";
};
customGamePlugin.prototype.getSettingsPanel = function() {
if(this.game == null) this.game = "";
return '<label for="cgPluginGame">Game: </label> ' +
'<input type="text" placeholder="Game.." name="cgPluginGame" id="cgPluginGame" value="'+this.game+'">' +
'<button onclick="BdApi.getPlugin(\'Custom Game\').setGame()">Apply</button>';
};
customGamePlugin.prototype.setGame = function(game) {
if(game == null) {
game = document.getElementById("cgPluginGame").value;
}
this.game = game;
this.setPlaying();
};
customGamePlugin.prototype.setPlaying = function() {
if(!this.enabled) return;
if(this.uid == null) {
if($(".account .avatar-small").css("background-image") == undefined)return;
this.uid = $(".account .avatar-small").css("background-image").match(/\d+/);
}
if(this.game == null) this.game = "";
var minner = $('.channel-members .member[data-reactid*="'+this.uid+'"]').find(".member-inner")
var mgame = minner.find(".member-game");
if(this.game != "") {
if(mgame.length) {
mgame.find("strong").text(this.game);
} else {
minner.append('<div class="member-game"><span>Playing: </span><strong>'+this.game+'</strong></div>');
}
} else {
if(mgame.length) {
mgame.remove();
}
}
BdApi.setPlaying(this.game);
};

View File

@ -1,35 +0,0 @@
//META{"name":"GuildsScroller"}*//
function GuildsScroller() {}
GuildsScroller.prototype.load = function() {
};
GuildsScroller.prototype.unload = function() {
};
GuildsScroller.prototype.start = function() {
$(".guilds").wrap('<div class="scroller-wrap fade dark"></div>').wrap('<div class="scroller" style="overflow-x:hidden;"></div>');
};
GuildsScroller.prototype.stop = function() {
$(".guilds").unwrap().unwrap();
};
GuildsScroller.prototype.update = function() {
};
GuildsScroller.prototype.getName = function() {
return "Guilds Scrollbar";
};
GuildsScroller.prototype.getDescription = function() {
return "Adds a scrollbar to guilds/servers list";
};
GuildsScroller.prototype.getVersion = function() {
return "1.0";
};
GuildsScroller.prototype.getAuthor = function() {
return "Jiiks";
};

View File

@ -1,95 +0,0 @@
//META{"name":"clockPlugin"}*//
//Original clock code from http://cssdeck.com/labs/minimal-css3-digital-clock
var clockPlugin = function () {};
clockPlugin.prototype.start = function () {
BdApi.clearCSS("clockPluginCss");
BdApi.injectCSS("clockPluginCss", '#clockPluginClock { position:absolute; color:#FFF; background:#333333; padding:0 12px 0 13px; min-width:55px; max-width:55px; z-index:100; }');
var self = this;
this.clock = $("<div/>", { id: "clockPluginClock" });
$("body").append(this.clock);
this.pad = function(x) {
return x < 10 ? '0'+x : x;
};
this.ticktock = function() {
var d = new Date();
var h = self.pad(d.getHours());
var m = self.pad(d.getMinutes());
var s = self.pad(d.getSeconds());
var current_time = [h,m,s].join(':');
self.clock.html(current_time);
};
this.ticktock12 = function() {
var suffix = "AM";
var d = new Date();
var h = d.getHours();
var m = self.pad(d.getMinutes());
var s = self.pad(d.getSeconds());
if(h >= 12) {
h -= 12;
suffix = "PM";
}
if(h == 0) {
h = 12;
}
h = self.pad(h);
var current_time = [h,m,s].join(":") + suffix;
self.clock.html(current_time);
};
this.ticktock();
this.interval = setInterval(this.ticktock, 1000);
};
clockPlugin.prototype.load = function () {
};
clockPlugin.prototype.unload = function () {}
;
clockPlugin.prototype.stop = function () {
BdApi.clearCSS("clockPluginCss");
clearInterval(this.interval);
this.clock.remove();
};
clockPlugin.prototype.onMessage = function () {
};
clockPlugin.prototype.onSwitch = function () {
};
clockPlugin.prototype.observer = function (e) {
};
clockPlugin.prototype.getSettingsPanel = function () {
return "";
};
clockPlugin.prototype.getName = function () {
return "Clock Plugin";
};
clockPlugin.prototype.getDescription = function () {
return "Adds a clock to Discord";
};
clockPlugin.prototype.getVersion = function () {
return "0.1.0";
};
clockPlugin.prototype.getAuthor = function () {
return "Jiiks";
};

View File

@ -1,84 +0,0 @@
//META{"name":"crr"}*//
function crr() {}
crr.prototype.start = function () {
this.crrMt = new MutationObserver(function(mutations) {
if($(".roles").length > 0) {
if($("#ccpicker").length < 1) {
var selectedRole = $(".roles").find("li.selected");
var roleId = selectedRole.data("reactid").split("$").slice(-1)[0];
var serverId = $(".guilds .active").data("reactid").split("$").slice(-1)[0];
var rgb = selectedRole.css("color").match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+))?\)$/);
function hex(x) {
return ("0" + parseInt(x).toString(16)).slice(-2);
}
var curColour = "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
var picker = $("<input/>", {
type: "color",
class: "swatch default",
id: "ccpicker"
});
$(".color-picker .swatches").append(picker);
picker.prop("value", curColour);
picker.on("change", function() {
var token = localStorage["token"].replace(/"/g, "");
var newColour = parseInt($(this).prop("value").slice(1), 16);
$.ajax({
type: 'GET',
url: 'https://discordapp.com/api/guilds/'+serverId+'/roles?token='+token,
success: function(data) {
for(var i = 0 ; i < data.length ; i++) {
if(data[i]["id"] == roleId) {
var request = new XMLHttpRequest();
request.open('PATCH', 'https://discordapp.com/api/guilds/'+serverId+'/roles/'+roleId+'?token='+localStorage["token"].replace(/"/g, ""), false);
request.setRequestHeader("Content-type","application/json");
request.send('{"color": '+newColour+', "hoist": '+data[i]["hoist"]+', "name": "'+data[i]["name"]+'", "permissions": '+data[i]["permissions"]+'}');
break;
}
}
}
});
});
}
}
});
this.crrMt.observe(document, {childList:true, subtree:true})
};
crr.prototype.stop = function () {
this.crrMt.disconnect();
};
crr.prototype.load = function () {
//Called when plugin is loaded
};
crr.prototype.unload = function () {
//Called when plugin is unloaded
};
crr.prototype.getName = function () {
return "Custom Role Colours";
};
crr.prototype.getDescription = function () {
return "Set custom role colours";
};
crr.prototype.getVersion = function () {
return "1.0";
};
crr.prototype.getAuthor = function () {
return "Jiiks, Pohky";
};
crr.prototype.getSettingsPanel = function () {
return '';
};

View File

@ -1,50 +0,0 @@
//META{"name":"dblClickEdit"}*//
var dblClickEdit = function () {};
dblClickEdit.prototype.onMessage = function () {
};
dblClickEdit.prototype.onSwitch = function () {
};
dblClickEdit.prototype.start = function () {
$(document).on("dblclick.dce", function(e) {
var target = $(e.target);
if(target.parents(".message").length > 0) {
var msg = target.parents(".message").first();
var opt = msg.find(".btn-option");
opt.click();
$.each($(".popout .btn-item"), (index, value) => {
var option = $(value);
if(option.text() === "Edit") {
option.click();
}
});
}
});
};
dblClickEdit.prototype.load = function () {};
dblClickEdit.prototype.unload = function () {
$(document).off("dblclick.dce");
};
dblClickEdit.prototype.stop = function () {
$(document).off("dblclick.dce");
};
dblClickEdit.prototype.getSettingsPanel = function () {
return "";
};
dblClickEdit.prototype.getName = function () {
return "Double click edit";
};
dblClickEdit.prototype.getDescription = function () {
return "Double click messages to edit them";
};
dblClickEdit.prototype.getVersion = function () {
return "0.1.1";
};
dblClickEdit.prototype.getAuthor = function () {
return "Jiiks";
};

View File

@ -1,84 +0,0 @@
//META{"name":"emoteBlacklist"}*//
var emoteBlacklist = function () {};
emoteBlacklist.prototype.onMessage = function () {
};
emoteBlacklist.prototype.onSwitch = function () {
};
emoteBlacklist.prototype.start = function () {
window.ebEnabled = true;
var self = this;
var em = bdPluginStorage.get("emoteBlacklist", "blacklist");
if(em === null) return;
em.forEach(function(emote) {
self.remove(emote);
self.add(emote);
});
};
emoteBlacklist.prototype.add = function(emote) {
window.bemotes.push(emote);
};
emoteBlacklist.prototype.remove = function(emote) {
var index = bemotes.indexOf(emote);
if(index > -1) {
window.bemotes.splice(index, 1);
}
}
emoteBlacklist.prototype.load = function () {};
emoteBlacklist.prototype.unload = function () {
};
emoteBlacklist.prototype.stop = function () {
window.ebEnabled = false;
this.clear();
};
emoteBlacklist.prototype.clear = function() {
var self = this;
var em = bdPluginStorage.get("emoteBlacklist", "blacklist");
if(em === null) return;
em.forEach(function(emote) {
self.remove(emote);
});
};
emoteBlacklist.prototype.getSettingsPanel = function () {
var em = bdPluginStorage.get("emoteBlacklist", "blacklist");
var html = '';
html += '<h2>Emote Blacklist</2>';
html += '<textarea id="emoteBlistTa" style="width:100%; min-height:200px;">';
if(em !== null) {
em.forEach(function(item) {
html += item + "\n";
});
}
html += '</textarea>';
html += '<button onclick="emoteBlacklist.prototype.save()">Save</button>';
html += '<span>Add emote names here to blacklist(1 per line)</span>';
return html;
};
emoteBlacklist.prototype.save = function() {
this.clear();
var blist = [];
$("#emoteBlistTa").val().split("\n").forEach(function(item) {
blist.push(item);
});
bdPluginStorage.set("emoteBlacklist", "blacklist", blist);
if(window.ebEnabled) {
this.start();
}
};
emoteBlacklist.prototype.getName = function () {
return "Emote Blacklist";
};
emoteBlacklist.prototype.getDescription = function () {
return "Blacklist emotes locally";
};
emoteBlacklist.prototype.getVersion = function () {
return "0.1.0";
};
emoteBlacklist.prototype.getAuthor = function () {
return "Jiiks";
};

View File

@ -1,61 +0,0 @@
//META{"name":"mediaSupport"}*//
var mediaSupport = function () {};
mediaSupport.prototype.convert = function () {
$(".message a").each(function() {
var t = $(this);
var href = t.attr("href");
if(href == undefined) return true;
href = href.replace("http:", "https:");
if(!href.endsWith(".mp4") && !href.endsWith(".webm") && !href.endsWith(".ogg") && !href.endsWith(".mp3") && !href.endsWith(".wav")) return true;
var video = true;
var type = "webm";
if(href.endsWith(".mp4")) type = "mp4";
if(href.endsWith(".ogg")) type = "ogg";
if(href.endsWith(".mp3")) {
type = "mpeg";
video = false;
}
if(href.endsWith(".wav")) {
type = "wav";
video = false;
}
if(video) {
t.replaceWith('<video width="480" height="320" src="'+encodeURI(href)+'" type="video/'+type+'" controls></video>');
} else {
t.replaceWith('<audio src="'+encodeURI(href)+'" type="audio/'+type+'" controls></audio>');
}
});
};
mediaSupport.prototype.onMessage = function () {
setTimeout(this.convert(), 2000);
};
mediaSupport.prototype.onSwitch = function () {
this.convert();
};
mediaSupport.prototype.start = function () {
this.convert();
};
mediaSupport.prototype.load = function () {};
mediaSupport.prototype.unload = function () {};
mediaSupport.prototype.stop = function () {};
mediaSupport.prototype.getSettingsPanel = function () {
return "";
};
mediaSupport.prototype.getName = function () {
return "Media Support";
};
mediaSupport.prototype.getDescription = function () {
return "Add support for html5 media";
};
mediaSupport.prototype.getVersion = function () {
return "0.1.0";
};
mediaSupport.prototype.getAuthor = function () {
return "Jiiks";
};

View File

@ -1,57 +0,0 @@
//META{"name":"properTimestamps"}*//
var properTimestamps = function () {};
properTimestamps.prototype.convert = function () {
$(".timestamp").each(function() {
var t = $(this);
if(t.data("24") != undefined) return;
var text = t.text();
var matches = /(.*)?at\s+(\d{1,2}):(\d{1,2})\s+(.*)/.exec(text);
if(matches == null) return false;
if(matches.length < 5) return false;
var h = parseInt(matches[2]);
if(matches[4] == "AM") {
if(h == 12) h -= 12;
}else if(matches[4] == "PM") {
if(h < 12) h += 12;
}
matches[2] = ('0' + h).slice(-2);
t.text(matches[1] + matches[2] + ":" + matches[3]);
t.data("24", true);
});
};
properTimestamps.prototype.onMessage = function () {
this.convert();
};
properTimestamps.prototype.onSwitch = function () {
this.convert();
};
properTimestamps.prototype.start = function () {
this.convert();
};
properTimestamps.prototype.load = function () {};
properTimestamps.prototype.unload = function () {};
properTimestamps.prototype.stop = function () {};
properTimestamps.prototype.getSettingsPanel = function () {
return "";
};
properTimestamps.prototype.getName = function () {
return "Proper Timestamps";
};
properTimestamps.prototype.getDescription = function () {
return "24 hours timestamps";
};
properTimestamps.prototype.getVersion = function () {
return "0.1.0";
};
properTimestamps.prototype.getAuthor = function () {
return "Jiiks";
};

View File

@ -1,63 +0,0 @@
//META{"name":"typingSoundPlugin"}*//
function typingSoundPlugin() {}
typingSoundPlugin.prototype.load = function() {
if($("#tsp-ts").length) return;
$("head").append('<audio id="tsp-ts"><source src="//betterdiscord.net/stuff/ts4.wav"></audio>');
this.ts = $("#tsp-ts");
if($("#tsp-bs").length) return;
$("head").append('<audio id="tsp-bs"><source src="//betterdiscord.net/stuff/bs.wav"></audio>');
this.bs = $("#tsp-bs");
};
typingSoundPlugin.prototype.unload = function() {
$("#tsp-ts").remove();
$("#tsp-bs").remove();
};
typingSoundPlugin.prototype.start = function() {
var self = this;
$(document).on("keypress.ts", function(e) {
self.ts.trigger("pause");
self.bs.trigger("pause");
self.ts.prop("currentTime", 0);
self.bs.prop("currentTime", 0);
self.ts.trigger("play");
});
$(document).on("keydown.ts", function(e) {
if(e.keyCode == 8) {
self.bs.trigger("pause");
self.bs.prop("currentTime", 0);
self.bs.trigger("play");
return;
}
});
};
typingSoundPlugin.prototype.stop = function() {
$(document).off("keypress.ts");
$(document).off("keydown.ts");
};
typingSoundPlugin.prototype.getName = function() {
return "Osu Sounds for Rai";
};
typingSoundPlugin.prototype.getDescription = function() {
return "Plays Osu chat sounds when you type, can be used to play any sounds.";
};
typingSoundPlugin.prototype.getVersion = function() {
return "1.0";
};
typingSoundPlugin.prototype.getAuthor = function() {
return "Jiiks";
};
typingSoundPlugin.prototype.getSettingsPanel = function() {
return "";
};

View File

@ -1 +0,0 @@
Superseded by Media Support: https://github.com/Jiiks/BetterDiscordApp/blob/master/Plugins/mediaSupport.js

135
README.md
View File

@ -1,109 +1,54 @@
Note that this whole branch is deprecated. all further development is going on here: https://github.com/Jiiks/BetterDiscordApp/tree/v2
# BandagedBD
# BetterDiscordApp
BandagedBD (Bandaged BetterDiscord) is a fork of the original [BetterDiscord](https://github.com/Jiiks/BetterDiscordApp) by Jiiks. This has a number of improvements over the original which is currently undergoing a full rewrite. In the interim, the current version has been unmaintained hence this fork existing. I will continue to maintain this fork until BDv2 comes out. I am helping to develop BDv2 as well so as release gets closer this fork will become less and less active.
# If you have issues then join the BD Discord server: [Here](https://discord.gg/0Tmfo5ZbORCRqbAd)
# Installation
# Do not contact Discord support about BD issues.
### Windows
Grab the `exe` file from the latest release on the [releases page](https://github.com/rauenzi/BetterDiscordApp/releases). Be sure you leave the last checkbox "Use Zere's Fork" checked when installing.
## All plugins must be named `*.plugin.js` and all themes must be named `*.theme.css`
### macOS/OS X
Grab the `zip` file from the latest release on the [releases page](https://github.com/rauenzi/BetterDiscordApp/releases).
Better Discord App enhances the Discord desktop app with new features.
### Linux
See this link: https://gist.github.com/ObserverOfTime/d7e60eb9aa7fe837545c8cb77cf31172
![ss](http://i.imgur.com/Gj6oD7z.png)
# What's Different
## Windows Universal Installer
* Download the latest installer from [releases](https://github.com/Jiiks/BetterDiscordApp/releases)
* Follow the instructions
* .NET 4.0 required https://www.microsoft.com/en-us/download/details.aspx?id=30653
* Windows Installer users asar.net https://github.com/Jiiks/asar.net
## New Settings
![Settings](https://i.zackrauen.com/nkb9Qi.png)
## Auto Installation
* Download the latest package from [releases](https://github.com/Jiiks/BetterDiscordApp/releases)
* Run the installer
* Installer requires [node](https://nodejs.org/en/download/) download the binaries and place in the same folder as the installer if you don't have node installed.
* Installer uses [asar](https://github.com/atom/asar) which is bundled with the installer.
* Installer uses [wrench](https://github.com/ryanmcgrath/wrench-js) which is bundled with the installer.
## UI
- Redesigned plugin and theme cards with additional classes for themes to use
- Additional tab in settings with additional settings.
- CustomCSS editor from CodeMirror has been removed due to being bloated and having high cpu usage. Replaced with another lightweight editor
## Manual Installation
* Extract app.asar
* Add BetterDiscord as a dependency
* Add init to Discord load event
* Move BetterDiscord to node_modules
## Features
## Plugins/Themes Related
- Prevent broken plugins from halting BD from loading
- Speed up the loading process
- Show startup errors in a modal
**Emotes:**
BetterDiscord adds all [Twitch.tv](http://twitch.tv), most [FrankerFaceZ](http://frankerfacez.com) and [BetterTTV](http://betterttv.net) emotes to Discord. Supported emotes: https://betterdiscord.net/emotes
![Startup](https://i.zackrauen.com/PwlQcp.gif)
**Quick Emote Menu:**
Quick Emote Menu adds a menu for quickly adding twitch emotes and your favorite emotes.
- Add `try...catch` blocks to help prevent errors from crashing BD and Discord
- Fix internal functions that some functions rely on such as `onSwitch` and `onMessage`
- Add `source` and `website` as options for plugin and theme METAs
- Allow themes to use spaces and apostrophes in their names
- Prettier errors in console, useful for debugging
**Emote Autocapitalize:**
Automatically capitalize [Twitch.tv](http://twitch.tv) global emotes.
## Emote Module
- Emotes load asynchronously in the background (does not prevent the mod from loading anymore)
- Several bug fixes including tooltips, modifiers and emote menu
- Consolidate emotes to a single file
- Revamp how emotes are injected—speedup
**Emote Autocomplete:**
Automatically completes/suggests emotes.(soon)
**Minimal Mode:**
Minimal mode makes elements smaller and hides certain elements.
**Voice Chat Mode:**
Only display voice channels
**Public Servers:**
Public server listing provided by: [DiscordServers.com](https://www.discordservers.com/)
![ss](http://i.imgur.com/BVUZlu9.png)
**Custom CSS**
BetterDiscord supports custom CSS for styling Discord to your liking.
**Custom Themes**
BetterDiscord comes with a theme loader for loading your own or downloading themes made by others.
**Plugins**
BetterDiscord comes with a JavaScript plugin loader for loading your own or downloading plugins made by others.
**Spoilers**
Add spoilers to your chat, simply add [!s] to your message.
**Save Logs Locally:**
Save chatlogs locally.(soon)
## Adding your server to public servers
As of JS1.60 the public server list is supplied by [DiscordServers.com](https://www.discordservers.com/)
Add your server there and it will appear in the list!
## BetterDiscord Uses the following API's
* https://twitchemotes.com/apidocs for Twitch emotes
* https://api.betterttv.net/emotes for [BetterTTV](https://nightdev.com/betterttv/) emotes
## Credits
* MacOS Installer by [Candunc](https://github.com/Candunc)
* Emote titles by [pendo324](https://github.com/pendo324)
* Majority of FFZ emote work by [Pohky](https://github.com/pohky) and [DeathStrikeV](https://github.com/DeathStrikeV)
* Majority of BTTV emote work by [EhsanKia](https://github.com/EhsanKia)
## License
The MIT License (MIT)
Copyright (c) 2015-present Jiiks | [Jiiks.net](https://jiiks.net)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
## Misc
- Fix Minimal Mode
- Fix React errors when opening settings
- Fix selected class disappearing when clicking an open tab
- Create new alert modal for `BdApi`
- Add toasts as notification option and in `BdApi`
- Remove most jQuery dependency for speedup
- Attach to settings when entering from right click
- Remove broken PublicServers

View File

@ -1 +0,0 @@
module.exports = require('./lib/BetterDiscord');

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

View File

@ -1,480 +0,0 @@
/* BetterDiscordApp Core JavaScript
* Version: 1.53
* Author: Jiiks | http://jiiks.net
* Date: 27/08/2015 - 16:36
* Last Update: 01/05/2016
* https://github.com/Jiiks/BetterDiscordApp
*/
var settingsPanel, emoteModule, utils, quickEmoteMenu, opublicServers, voiceMode, pluginModule, themeModule, customCssEditor;
var jsVersion = 1.72;
var supportedVersion = "0.2.5";
var mainObserver;
var twitchEmoteUrlStart = "https://static-cdn.jtvnw.net/emoticons/v1/";
var twitchEmoteUrlEnd = "/1.0";
var ffzEmoteUrlStart = "https://cdn.frankerfacez.com/emoticon/";
var ffzEmoteUrlEnd = "/1";
var bttvEmoteUrlStart = "https://cdn.betterttv.net/emote/";
var bttvEmoteUrlEnd = "/1x";
var mainCore;
var settings = {
"Save logs locally": { "id": "bda-gs-0", "info": "Saves chat logs locally", "implemented": false, "hidden": false, "cat": "core"},
"Public Servers": { "id": "bda-gs-1", "info": "Display public servers button", "implemented": true, "hidden": false, "cat": "core"},
"Minimal Mode": { "id": "bda-gs-2", "info": "Hide elements and reduce the size of elements.", "implemented": true, "hidden": false, "cat": "core"},
"Voice Mode": { "id": "bda-gs-4", "info": "Only show voice chat", "implemented": true, "hidden": false, "cat": "core"},
"Hide Channels": { "id": "bda-gs-3", "info": "Hide channels in minimal mode", "implemented": true, "hidden": false, "cat": "core"},
"Dark Mode": { "id": "bda-gs-5", "info": "Make certain elements dark by default(wip)", "implemented": true, "hidden": false, "cat": "core"},
"Override Default Emotes": { "id": "bda-es-5", "info": "Override default emotes", "implemented": false, "hidden": false, "cat": "core"},
"Voice Disconnect": { "id": "bda-dc-0", "info": "Disconnect from voice server when closing Discord", "implemented": true, "hidden": false, "cat": "core"},
"Custom css live update": { "id": "bda-css-0", "info": "", "implemented": true, "hidden": true, "cat": "core"},
"Custom css auto udpate": { "id": "bda-css-1", "info": "", "implemented": true, "hidden": true, "cat": "core"},
"24 Hour Timestamps": { "id": "bda-gs-6", "info": "Replace 12hr timestamps with proper ones", "implemented": true, "hidden": false, "cat": "core"},
"Coloured Text": { "id": "bda-gs-7", "info": "Make text colour the same as role colour", "implemented": true, "hidden": false, "cat": "core"},
"Twitch Emotes": { "id": "bda-es-7", "info": "Show Twitch emotes", "implemented": true, "hidden": false, "cat": "emote"},
"FrankerFaceZ Emotes": { "id": "bda-es-1", "info": "Show FrankerFaceZ Emotes", "implemented": true, "hidden": false, "cat": "emote"},
"BetterTTV Emotes": { "id": "bda-es-2", "info": "Show BetterTTV Emotes", "implemented": true, "hidden": false, "cat": "emote"},
"Emote Menu": { "id": "bda-es-0", "info": "Show Twitch/Favourite emotes in emote menu", "implemented": true, "hidden": false, "cat": "emote"},
"Emoji Menu": { "id": "bda-es-9", "info": "Show Discord emoji menu", "implemented": true, "hidden": false, "cat": "emote"},
"Emote Autocomplete": { "id": "bda-es-3", "info": "Autocomplete emote commands", "implemented": false, "hidden": false, "cat": "emote"},
"Emote Auto Capitalization": { "id": "bda-es-4", "info": "Autocapitalize emote commands", "implemented": true, "hidden": false, "cat": "emote"},
"Show Names": { "id": "bda-es-6", "info": "Show emote names on hover", "implemented": true, "hidden": false, "cat": "emote"},
"Show emote modifiers": { "id": "bda-es-8", "info": "Enable emote mods", "implemented": true, "hidden": false, "cat": "emote"},
};
var links = {
"Jiiks.net": { "text": "Jiiks.net", "href": "thtp://jiiks.net", "target": "_blank" },
"twitter": { "text": "Twitter", "href": "http://twitter.com/jiiksi", "target": "_blank" },
"github": { "text": "Github", "href": "http://github.com/jiiks", "target": "_blank" }
};
var defaultCookie = {
"version": jsVersion,
"bda-gs-0": false,
"bda-gs-1": true,
"bda-gs-2": false,
"bda-gs-3": false,
"bda-gs-4": false,
"bda-gs-5": true,
"bda-gs-6": false,
"bda-gs-7": false,
"bda-es-0": true,
"bda-es-1": true,
"bda-es-2": true,
"bda-es-3": false,
"bda-es-4": false,
"bda-es-5": true,
"bda-es-6": true,
"bda-es-7": true,
"bda-es-8": true,
"bda-jd": true,
"bda-es-8": true,
"bda-dc-0": false,
"bda-css-0": false,
"bda-css-1": false,
"bda-es-9": true
};
var bdchangelog = {
"changes": {
"a": {
"title": "v1.72 : Public Servers",
"text": "Public servers now have categories, description, tags, dark mode and more!",
"img": ""
},
"b": {
"title": "v1.72 : Import/Export",
"text": "Import/Export buttons now disappear in themes/plugins tabs to avoid confusion",
"img": ""
},
"c": {
"title": "v1.72 : Changelog",
"text": "You can now reopen this changelog from the settings",
"img": ""
},
"d": {
"title": "v1.71 : Hide Twitch emotes",
"text": "Hide all emotes option now toggles Twitch emotes instead!",
"img": ""
},
"e": {
"title": "v1.71 : Override FFZ emote",
"text": "Use the <code class=\"inline\">:bttv</code> emote modifier to override a FFZ emote with a BTTV one!",
"img": ""
},
"f": {
"title": "v1.70 : 0.2.8 Support",
"text": "Added support for Core version 0.2.8.",
"img": ""
},
"g": {
"title": "v1.70 : Setting Import/Export",
"text": "You can now import and export your settings!",
"img": ""
},
"h": {
"title": "v1.70 : Public Server List Infinite Scroll",
"text": "Public server list now has the ability to load more than 20 servers.",
"img": ""
},
"i": {
"title": "v1.70 : 24 hour timestamps",
"text": "Replace 12 hour timestamp with 24 hour timestamps!",
"img": ""
},
"j": {
"title": "v1.70 : Coloured text",
"text": "Make text colour the same as role colour!",
"img": ""
}
},
"fixes": {
"a": {
"title": "v1.72 : Settings panel",
"text": "Settings panel will now show no matter how you open it!",
"img": ""
},
"b": {
"title": "v1.72 : Fixed emote edit bug",
"text": "Edits now appear properly even with emotes!",
"img": ""
},
"c": {
"title": "v1.72 : Public servers",
"text": "Public servers button is visible again!",
"img": ""
},
"d": {
"title": "v1.72 : Public servers",
"text": "Updated public servers api endpoint url for fetching correct serverlist.",
"img": ""
},
"e": {
"title": "v1.71 : Fixed emotes and edit",
"text": "Emotes work again! So does editing emotes!",
"img": ""
},
"f": {
"title": "Spoilers are currently broken :(",
"text": "Ps. I know this in the fixes section :o",
"img": ""
}
}
};
var settingsCookie = {};
function Core() {}
Core.prototype.init = function () {
var self = this;
var lVersion = (typeof(version) === "undefined") ? bdVersion : version;
if (lVersion < supportedVersion) {
this.alert("Not Supported", "BetterDiscord v" + lVersion + "(your version)" + " is not supported by the latest js(" + jsVersion + ").<br><br> Please download the latest version from <a href='https://betterdiscord.net' target='_blank'>BetterDiscord.net</a>");
return;
}
utils = new Utils();
var sock = new BdWSocket();
sock.start();
utils.getHash();
emoteModule = new EmoteModule();
quickEmoteMenu = new QuickEmoteMenu();
voiceMode = new VoiceMode();
emoteModule.init();
this.initSettings();
this.initObserver();
//Incase were too fast
function gwDefer() {
console.log(new Date().getTime() + " Defer");
if ($(".guilds-wrapper .guilds").children().length > 0) {
console.log(new Date().getTime() + " Defer Loaded");
var guilds = $(".guilds>li:first-child");
var showChannelsButton = $("<button/>", {
class: "btn",
id: "bd-show-channels",
text: "R",
css: {
"cursor": "pointer"
},
click: function () {
settingsCookie["bda-gs-3"] = false;
$("body").removeClass("bd-minimal-chan");
self.saveSettings();
}
});
$(".guilds-wrapper").prepend(showChannelsButton);
opublicServers = new PublicServers();
customCssEditor = new CustomCssEditor();
pluginModule = new PluginModule();
pluginModule.loadPlugins();
if (typeof (themesupport2) !== "undefined") {
themeModule = new ThemeModule();
themeModule.loadThemes();
}
settingsPanel = new SettingsPanel();
settingsPanel.init();
quickEmoteMenu.init(false);
$("#tc-settings-button").on("click", function () {
settingsPanel.show();
});
window.addEventListener("beforeunload", function(){
if(settingsCookie["bda-dc-0"]){
$('.btn.btn-disconnect').click();
}
});
$(document).on("mousedown", function(e) {
//bd modal hiders
});
opublicServers.init();
emoteModule.autoCapitalize();
/*Display new features in BetterDiscord*/
if (settingsCookie["version"] < jsVersion) {
var cl = self.constructChangelog();
$("body").append(cl);
settingsCookie["version"] = jsVersion;
self.saveSettings();
}
$("head").append("<style>.CodeMirror{ min-width:100%; }</style>");
$("head").append('<style id="bdemotemenustyle"></style>');
} else {
setTimeout(gwDefer, 100);
}
}
$(document).ready(function () {
setTimeout(gwDefer, 1000);
});
};
Core.prototype.initSettings = function () {
if ($.cookie("better-discord") == undefined) {
settingsCookie = defaultCookie;
this.saveSettings();
} else {
this.loadSettings();
for (var setting in defaultCookie) {
if (settingsCookie[setting] == undefined) {
settingsCookie[setting] = defaultCookie[setting];
this.saveSettings();
}
}
}
};
Core.prototype.saveSettings = function () {
$.cookie("better-discord", JSON.stringify(settingsCookie), {
expires: 365,
path: '/'
});
};
Core.prototype.loadSettings = function () {
settingsCookie = JSON.parse($.cookie("better-discord"));
};
var botlist = ["119598467310944259"]; //Temp
Core.prototype.initObserver = function () {
mainObserver = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if(settingsPanel !== undefined)
settingsPanel.inject(mutation);
if($(mutation.target).find(".emoji-picker").length) {
var fc = mutation.target.firstChild;
if(fc.classList.contains("popout")) {
quickEmoteMenu.obsCallback($(fc));
}
}
if (typeof pluginModule !== "undefined") pluginModule.rawObserver(mutation);
if (mutation.target.getAttribute('class') != null) {
//console.log(mutation.target)
if(mutation.target.classList.contains('title-wrap') || mutation.target.classList.contains('chat')){
// quickEmoteMenu.obsCallback();
voiceMode.obsCallback();
if (typeof pluginModule !== "undefined") pluginModule.channelSwitch();
}
if (mutation.target.getAttribute('class').indexOf('scroller messages') != -1) {
if (typeof pluginModule !== "undefined") pluginModule.newMessage();
}
if(settingsCookie["bda-gs-6"]) {
$(".timestamp").not("[data-24]").each(function() {
var t = $(this);
t.attr("data-24", true);
var text = t.text();
var matches = /(.*)?at\s+(\d{1,2}):(\d{1,2})\s+(.*)/.exec(text);
if(matches == null) return true;
if(matches.length < 5) return true;
var h = parseInt(matches[2]);
if(matches[4] == "AM") {
if(h == 12) h -= 12;
}else if(matches[4] == "PM") {
if(h < 12) h += 12;
}
matches[2] = ('0' + h).slice(-2);
t.text(matches[1] + " at " + matches[2] + ":" + matches[3]);
});
}
if(settingsCookie["bda-gs-7"]) {
$(".user-name").not("[data-colour]").each(function() {
var t = $(this);
var color = t.css("color");
if(color == "rgb(255, 255, 255)") return true;
t.closest(".message-group").find(".markup").not("[data-colour]").each(function() {
$(this).attr("data-colour", true);
$(this).css("color", color);
});
});
}
}
emoteModule.obsCallback(mutation);
});
});
//noinspection JSCheckFunctionSignatures
mainObserver.observe(document, {
childList: true,
subtree: true
});
};
Core.prototype.constructChangelog = function () {
var changeLog = '' +
'<div id="bd-wn-modal" class="modal" style="opacity:1;">' +
' <div class="modal-inner">' +
' <div id="bdcl" class="markdown-modal change-log"> ' +
' <div class="markdown-modal-header">' +
' <strong>What\'s new in BetterDiscord JS' + jsVersion + '</strong>' +
' <button class="markdown-modal-close" onclick=\'$("#bd-wn-modal").remove();\'></button>' +
' </div><!--header-->' +
' <div class="scroller-wrap">' +
' <div class="scroller">';
if (bdchangelog.changes != null) {
changeLog += '' +
'<h1 class="changelog-added">' +
' <span>New Stuff</span>' +
'</h1>' +
'<ul>';
for (var change in bdchangelog.changes) {
change = bdchangelog.changes[change];
changeLog += '' +
'<li>' +
' <strong>' + change.title + '</strong>' +
' <div>' + change.text + '</div>' +
'</li>';
}
changeLog += '</ul>';
}
if (bdchangelog.fixes != null) {
changeLog += '' +
'<h1 class="changelog-fixed">' +
' <span>Fixed</span>' +
'</h1>' +
'<ul>';
for (var fix in bdchangelog.fixes) {
fix = bdchangelog.fixes[fix];
changeLog += '' +
'<li>' +
' <strong>' + fix.title + '</strong>' +
' <div>' + fix.text + '</div>' +
'</li>';
}
changeLog += '</ul>';
}
if (bdchangelog.upcoming != null) {
changeLog += '' +
'<h1 class="changelog-in-progress">' +
' <span>Coming Soon</span>' +
'</h1>' +
'<ul>';
for (var upc in bdchangelog.upcoming) {
upc = bdchangelog.upcoming[upc];
changeLog += '' +
'<li>' +
' <strong>' + upc.title + '</strong>' +
' <div>' + upc.text + '</div>' +
'</li>';
}
changeLog += '</ul>';
}
changeLog += '' +
' </div><!--scoller-->' +
' </div><!--scroller-wrap-->' +
' <div class="footer">' +
' </div><!--footer-->' +
' </div><!--change-log-->' +
' </div><!--modal-inner-->' +
'</div><!--modal-->';
return changeLog;
};
Core.prototype.alert = function (title, text) {
var id = '';
for( var i=0; i < 5; i++ )
id += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".charAt(Math.floor(Math.random() * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".length));
var bdAlert = '\
<div id="bda-alert-'+id+'" class="modal bda-alert" style="opacity:1" data-bdalert="'+id+'">\
<div class="modal-inner" style="box-shadow:0 0 8px -2px #000;">\
<div class="markdown-modal">\
<div class="markdown-modal-header">\
<strong style="float:left"><span>BetterDiscord - </span><span>'+title+'</span></strong>\
<span></span>\
<button class="markdown-modal-close" onclick=\'document.getElementById("bda-alert-'+id+'").remove(); utils.removeBackdrop("'+id+'");\'></button>\
</div>\
<div class="scroller-wrap fade">\
<div style="font-weight:700" class="scroller">'+text+'</div>\
</div>\
<div class="markdown-modal-footer">\
<span style="float:right"> for support.</span>\
<a style="float:right" href="https://discord.gg/0Tmfo5ZbOR9NxvDd" target="_blank">#support</a>\
<span style="float:right">Join </span>\
</div>\
</div>\
</div>\
</div>\
';
$("body").append(bdAlert);
utils.addBackdrop(id);
};

View File

@ -1,257 +0,0 @@
/* BetterDiscordApp EmoteModule JavaScript
* Version: 1.5
* Author: Jiiks | http://jiiks.net
* Date: 26/08/2015 - 15:29
* Last Update: 14/10/2015 - 09:48
* https://github.com/Jiiks/BetterDiscordApp
* Note: Due to conflicts autocapitalize only supports global emotes
*/
/*
* =Changelog=
* -v1.5
* --Twitchemotes.com api
*/
var emotesFfz = {};
var emotesBTTV = {};
var emotesTwitch = {
"emotes": {
"emote": {
"image_id": 0
}
}
}; //for ide
var subEmotesTwitch = {};
function EmoteModule() {}
EmoteModule.prototype.init = function () {};
EmoteModule.prototype.getBlacklist = function () {
$.getJSON("https://cdn.rawgit.com/Jiiks/betterDiscordApp/" + _hash + "/data/emotefilter.json", function (data) {
bemotes = data.blacklist;
});
};
EmoteModule.prototype.obsCallback = function (mutation) {
var self = this;
//if (!settingsCookie["bda-es-7"]) return;
$(".emoji").each(function() {
var t = $(this);
if(t.attr("src").indexOf(".png") != -1) {
t.replaceWith(t.attr("alt"));
}
});
for (var i = 0; i < mutation.addedNodes.length; ++i) {
var next = mutation.addedNodes.item(i);
if (next) {
var nodes = self.getNodes(next);
for (var node in nodes) {
if (nodes.hasOwnProperty(node)) {
var elem = nodes[node].parentElement;
if (elem && elem.classList.contains('edited')) {
self.injectEmote(elem);
} else {
self.injectEmote(nodes[node]);
}
}
}
}
}
};
EmoteModule.prototype.getNodes = function (node) {
var next;
var nodes = [];
var treeWalker = document.createTreeWalker(node, NodeFilter.SHOW_TEXT, null, false);
while (next = treeWalker.nextNode()) {
nodes.push(next);
}
return nodes;
};
var bemotes = [];
var spoilered = [];
EmoteModule.prototype.injectEmote = function(node) {
var self = this;
if (!node.parentElement) return;
var parent = $(node).parent();
if(!parent.hasClass("markup") && !parent.hasClass("message-content")) return;
function inject() {
var contents = parent.contents();
contents.each(function(i) {
if(contents[i] == undefined) return;
var nodeValue = contents[i].nodeValue;
if(nodeValue == null) return;
//if(nodeValue.indexOf("react-") > -1) return;
if(contents[i].nodeType == 8) return;
contents.splice(i, 1);
var words = nodeValue.split(/([^\s]+)([\s]|$)/g).filter(function(e){ return e});
var splice = 0;
var doInject = false;
var text = null;
words.forEach(function(w, index, a) {
if(w.indexOf("[!s]") > -1) {
w = w.replace("[!s]", "");
parent.data("spoilered", false);
parent.addClass("spoiler");
}
var allowedClasses = ["flip", "spin", "pulse", "spin2", "spin3", "1spin", "2spin", "3spin", "tr", "bl", "br", "shake", "shake2", "shake3", "flap"];
var useEmoteClass = false;
var emoteClass = "";
var skipffz = false;
var sw = w;
if(w.indexOf(":") > -1) {
var split = w.split(":");
if(split[0] != "" && split[1] != "") {
if(allowedClasses.indexOf(split[1]) > -1) {
sw = split[0];
emoteClass = settingsCookie["bda-es-8"] ? "emote" + split[1] : "";
}
if(split[1] == "bttv") {
sw = split[0];
skipffz = true;
}
}
}
if ($.inArray(sw, bemotes) != -1) return;
if(typeof emotesTwitch !== 'undefind' && settingsCookie["bda-es-7"]) {
if(emotesTwitch.emotes.hasOwnProperty(sw) && sw.length >= 4) {
if(text != null) { contents.splice(i + splice++, 0, document.createTextNode(text)); text = null;}
var url = twitchEmoteUrlStart + emotesTwitch.emotes[sw].image_id + twitchEmoteUrlEnd;
contents.splice(i + splice++, 0, self.createEmoteElement(sw, url, emoteClass));
doInject = true;
return;
}
}
if(typeof subEmotesTwitch !== 'undefined' && settingsCookie["bda-es-7"]) {
if(subEmotesTwitch.hasOwnProperty(sw) && sw.length >= 4) {
if(text != null) { contents.splice(i + splice++, 0, document.createTextNode(text)); text = null;}
var url = twitchEmoteUrlStart + subEmotesTwitch[sw] + twitchEmoteUrlEnd;
contents.splice(i + splice++, 0, self.createEmoteElement(sw, url, emoteClass));
doInject = true;
return;
}
}
if (typeof emotesBTTV !== 'undefined' && settingsCookie["bda-es-2"]) {
if(emotesBTTV.hasOwnProperty(sw) && sw.length >= 3) {
if(text != null) { contents.splice(i + splice++, 0, document.createTextNode(text)); text = null;}
var url = emotesBTTV[sw];
contents.splice(i + splice++, 0, self.createEmoteElement(sw, url, emoteClass));
doInject = true;
return;
}
}
if ((typeof emotesFfz !== 'undefined' && settingsCookie["bda-es-1"]) && (!skipffz || !emotesBTTV2.hasOwnProperty(sw))) {
if(emotesFfz.hasOwnProperty(sw) && sw.length >= 4) {
if(text != null) { contents.splice(i + splice++, 0, document.createTextNode(text)); text = null;}
var url = ffzEmoteUrlStart + emotesFfz[sw] + ffzEmoteUrlEnd;
contents.splice(i + splice++, 0, self.createEmoteElement(sw, url, emoteClass));
doInject = true;
return;
}
}
if (typeof emotesBTTV2 !== 'undefined' && settingsCookie["bda-es-2"]) {
if(emotesBTTV2.hasOwnProperty(sw) && sw.length >= 4) {
if(text != null) { contents.splice(i + splice++, 0, document.createTextNode(text)); text = null;}
var url = bttvEmoteUrlStart + emotesBTTV2[sw] + bttvEmoteUrlEnd;
if(skipffz && emotesFfz.hasOwnProperty(sw)) sw = sw + ":bttv";
contents.splice(i + splice++, 0, self.createEmoteElement(sw, url, emoteClass));
doInject = true;
return;
}
}
if(text == null) {
text = w;
} else {
text += "" + w;
}
if(index === a.length - 1) {
contents.splice(i + splice, 0, document.createTextNode(text));
}
});
if(doInject) {
var oldHeight = parent.outerHeight();
parent.html(contents);
var scrollPane = $(".scroller.messages").first();
scrollPane.scrollTop(scrollPane.scrollTop() + (parent.outerHeight() - oldHeight));
}
});
}
inject();
if(parent.children().hasClass("edited")) {
setTimeout(inject, 250);
}
};
EmoteModule.prototype.createEmoteElement = function(word, url, mod) {
var len = Math.round(word.length / 4);
var name = word.substr(0, len) + "\uFDD9" + word.substr(len, len) + "\uFDD9" + word.substr(len * 2, len) + "\uFDD9" + word.substr(len * 3);
var html = '<span class="emotewrapper"><img draggable="false" style="max-height:32px;" class="emote '+ mod +'" alt="' + name + '" src="' + url + '"/><input onclick=\'quickEmoteMenu.favorite(\"' + name + '\", \"' + url + '\");\' class="fav" title="Favorite!" type="button"></span>';
return $.parseHTML(html.replace(new RegExp("\uFDD9", "g"), ""))[0];
};
EmoteModule.prototype.autoCapitalize = function () {
var self = this;
$('body').delegate($(".channel-textarea-inner textarea:first"), 'keyup change paste', function () {
if (!settingsCookie["bda-es-4"]) return;
var text = $(".channel-textarea-inner textarea:first").val();
if (text == undefined) return;
var lastWord = text.split(" ").pop();
if (lastWord.length > 3) {
if (lastWord == "danSgame") return;
var ret = self.capitalize(lastWord.toLowerCase());
if (ret !== null && ret !== undefined) {
$(".channel-textarea-inner textarea:first").val(text.replace(lastWord, ret));
}
}
});
};
EmoteModule.prototype.capitalize = function (value) {
var res = emotesTwitch.emotes;
for (var p in res) {
if (res.hasOwnProperty(p) && value == (p + '').toLowerCase()) {
return p;
}
}
};

View File

@ -1,378 +0,0 @@
/* BetterDiscordApp PublicSevers JavaScripts
* Version: 1.0
* Author: Jiiks | http://jiiks.net
* Date: 27/08/2015 - 14:16
* https://github.com/Jiiks/BetterDiscordApp
*/
function PublicServers() {
}
PublicServers.prototype.getPanel = function () {
return this.container;
};
PublicServers.prototype.init = function () {
this.filtered = ["134680912691462144", "86004744966914048"];
this.bdServer = null;
this.loadingServers = false;
var self = this;
var guilds = $(".guilds>:first-child");
guilds.after($("<div></div>", {
class: "guild",
id: "bd-pub-li",
css: {
"height": "20px",
"display": settingsCookie["bda-gs-1"] == true ? "" : "none"
}
}).append($("<div/>", {
class: "guild-inner",
css: {
"height": "20px",
"border-radius": "4px"
}
}).append($("<a/>").append($("<div/>", {
css: {
"line-height": "20px",
"font-size": "12px"
},
text: "public",
id: "bd-pub-button"
})))));
$("#bd-pub-button").on("click", function () {
self.show();
});
var panelBase = '\
<div id="pubs-container">\
<div id="pubs-spinner">\
<span class="spinner" type="wandering-cubes">\
<span class="spinner-inner spinner-wandering-cubes">\
<span class="spinner-item"></span>\
<span class="spinner-item"></span>\
</span>\
</span>\
</div>\
<div id="pubs-header">\
<h2 id="pubs-header-title">Public Servers</h2>\
<button id="pubs-searchbtn">Search</button>\
<input id="pubs-sterm" type="text" placeholder="Search Term...">\
<div id="pubs-select-dropdown" class="bd-dropdown">\
<button class="bd-dropdown-select" id="pubs-cat-select">All</button>\
<div class="bd-dropdown-list">\
<ul>\
<li class="pubs-cat-select-li" data-val="all">All</li>\
<li class="pubs-cat-select-li" data-val="1">FPS Games</li>\
<li class="pubs-cat-select-li" data-val="2">MMO Games</li>\
<li class="pubs-cat-select-li" data-val="3">MOBA Games</li>\
<li class="pubs-cat-select-li" data-val="4">Strategy Games</li>\
<li class="pubs-cat-select-li" data-val="5">Sports Games</li>\
<li class="pubs-cat-select-li" data-val="6">Puzzle Games</li>\
<li class="pubs-cat-select-li" data-val="7">Retro Games</li>\
<li class="pubs-cat-select-li" data-val="8">Party Games</li>\
<li class="pubs-cat-select-li" data-val="9">Tabletop Games</li>\
<li class="pubs-cat-select-li" data-val="10">Sandbox Games</li>\
<li class="pubs-cat-select-li" data-val="11">Community</li>\
<li class="pubs-cat-select-li" data-val="12">Language</li>\
<li class="pubs-cat-select-li" data-val="13">Programming</li>\
<li class="pubs-cat-select-li" data-val="14">Other</li>\
<li class="pubs-cat-select-li" data-val="15">Simulation Games</li>\
</ul>\
</div>\
</div>\
</div>\
<div class="server-row server-pinned" style="display:none;">\
<div class="server-icon" style="background-image:url(https://cdn.discordapp.comi/cons/86004744966914048/6e5729ed5c12d5af558d80d7a194c3f9.jpg)"></div>\
<div class="server-info server-name"><span>BetterDiscord</span><span id="server-bd-tag">Official BetterDiscord server</span></div>\
<div class="server-info server-members"><span></span></div>\
<div class="server-info server-region"><span></span></div>\
<div class="server-info">\
<button data-server-invite-code="0Tmfo5ZbORCRqbAd">Join</button>\
</div>\
</div>\
<div class="scroller-wrap">\
<div class="scroller" id="pubs-scroller">\
<div id="pubs-list" class="servers-listing">\
</div>\
<div style="background:#FFF; padding: 5px 0; display:none;" id="pubs-spinner-bottom">\
<div>\
<span class="spinner" type="wandering-cubes">\
<span class="spinner-inner spinner-wandering-cubes">\
<span class="spinner-item"></span>\
<span class="spinner-item"></span>\
</span>\
</span>\
</div>\
</div>\
</div>\
</div>\
<div id="pubs-footer">\
<span style="color:#FFF; font-size:10px; font-weight:700; margin-left:5px;">Tip: Hover over server name for description if available</span>\
<div>Server list provided by <a href="https://discordservers.com" target="_blank">DiscordServers.com</a></div>\
</div>\
';
this.container = panelBase;
if($("#bd-pub-li").length < 1) {
setTimeout(function() {
self.init();
}, 250);
}
};
PublicServers.prototype.getPinnedServer = function() {
var self = this;
var dataset = {
"sort": [{"online": "desc"}],
"size": 1,
"query": {
"query_string": {
"default_operator": "AND",
"query": "BetterDiscord"
}
}
};
$.ajax({
type: "POST",
dataType: "json",
url: "https://search-discordservers-izrtub5nprzrl76ugyy6hdooe4.us-west-1.es.amazonaws.com/discord_servers/_search",
crossDomain: true,
data: JSON.stringify(dataset),
success: function(data) {
try {
var s = data.hits.hits[0]._source;
if(s.identifier == "86004744966914048") {
self.bdServer = s;
self.showPinnedServer();
}
}catch(err) {
self.bdServer = null;
}
}
});
};
PublicServers.prototype.hidePinnedServer = function() {
$("#pubs-container .scroller-wrap").css({"margin-top": "0", "height": "500px"});
$(".server-pinned").hide();
};
PublicServers.prototype.showPinnedServer = function() {
$(".server-pinned .server-icon").css("background-image", "url("+this.bdServer.icon+")");
$(".server-pinned .server-members span").text(this.bdServer.online + "/"+this.bdServer.members+" Members");
$(".server-pinned .server-region span").text(this.bdServer.region);
$(".server-pinned .server-info button").data("server-invite-code", this.bdServer.invite_code);
$("#pubs-container .scroller-wrap").css({"margin-top": "75px", "height": "425px"});
$(".server-pinned").show();
};
PublicServers.prototype.show = function () {
var self = this;
this.hidePinnedServer();
$("#pubs-cat-select").text("All");
this.selectedCategory = "all";
$("#pubs-container .scroller-wrap").css({"margin-top": "0", "height": "500px"});
$(".server-pinned").hide();
$(".app").append(this.getPanel());
if(this.bdServer == null) {
this.getPinnedServer();
} else {
this.showPinnedServer();
}
self.search(0, true);
$("#pubs-searchbtn").off("click").on("click", function() {
self.search();
});
$("#pubs-sterm").off("keyup").on("keyup", function(e) {
if (e.keyCode == 13) {
self.search(0, true);
}
});
$("#pubs-cat-select").off("click").on("click", function() {
$("#pubs-select-dropdown").addClass("open");
});
$(".pubs-cat-select-li").off("click").on("click", function() {
$("#pubs-select-dropdown").removeClass("open");
$("#pubs-cat-select").text($(this).text());
if(self.selectedCategory != $(this).data("val")) {
self.selectedCategory = $(this).data("val");
self.search(0, true);
}
});
$("#pubs-container").off("mouseup").on("mouseup", function() {
$("#pubs-select-dropdown").removeClass("open");
});
var self = this;
$(document).on("mouseup.bdps",function(e) {
if(!$("#bd-pub-button").is(e.target) && !$("#pubs-container").is(e.target) && $("#pubs-container").has(e.target).length === 0) {
self.hide();
}
});
$("#pubs-scroller").off("scroll.pubs").on("scroll.pubs", function() {
if(self.loadingServers) return;
var list = $("#pubs-list");
if($(this).scrollTop() + 550 < list.height()) return;
if(list.children().length % 20 != 0) return;
self.loadingServers = true;
$("#pubs-spinner-bottom").show();
self.search(list.children().length, false);
});
};
PublicServers.prototype.hide = function() {
$("#pubs-container").remove();
$(document).off("mouseup.bdps");
};
PublicServers.prototype.loadServers = function(dataset, search, clear) {
this.loadingServers = true;
var self = this;
$("#pubs-searchbtn").prop("disabled", true);
$("#pubs-sterm").prop("disabled", true);
if(clear) $("#pubs-list").empty();
$("#pubs-spinner").show();
$.ajax({
type: "POST",
dataType: "json",
url: "https://search-discordservers-izrtub5nprzrl76ugyy6hdooe4.us-west-1.es.amazonaws.com/discord_servers/_search",
crossDomain: true,
data: JSON.stringify(dataset),
success: function(data) {
var hits = data.hits.hits;
if(search) {
$("#pubs-header-title").text("Public Servers - Search Results: " + hits.length);
} else {
$("#pubs-header-title").text("Public Servers");
}
hits.forEach(function(hit) {
var source = hit._source;
var icode = source.invite_code.replace(/ /g,'');
var html = '<div class="server-row">';
html += '<div class="server-icon" style="background-image:url(' + source.icon + ')"></div>';
html += '<div class="server-info server-name">';
html += '<div class="server-information">';
if(source.is_official) {
html += '<span class="server-official">Official!</span>';
}
html += '<span class="server-name-span">' + source.name + '</span>';
var tags = [];
source.categories.forEach(function(tag) {
tags.push(tag.name);
});
html += '<span class="server-tags">'+tags.join(", ")+'</span>';
html += '<span class="server-description">'+(source.description == undefined ? "No Description" : source.description)+'</span>';
html += '</div>';
html += '</div>';
html += '<div class="server-info server-members">';
html += '<span>' + source.online + '/' + source.members + ' Members</span>';
html += '</div>';
html += '<div class="server-info server-region">';
html += '<span>' + source.region + '</span>';
html += '</div>';
html += '<div class="server-info">';
html += '<button data-server-invite-code='+icode+'>Join</button>';
html += '</div>';
html += '</div>';
$("#pubs-list").append(html);
$("button[data-server-invite-code="+icode+"]").on("click", function(){
self.joinServer(icode);
});
});
if(search) {
$("#pubs-header-title").text("Public Servers - Search Results: " + $("#pubs-list").children().length);
}
},
done: function() {
$("#pubs-spinner").hide();
$("#pubs-spinner-bottom").hide();
$("#pubs-searchbtn").prop("disabled", false);
$("#pubs-sterm").prop("disabled", false);
self.loadingServers = false;
},
always: function() {
$("#pubs-spinner").hide();
$("#pubs-spinner-bottom").hide();
$("#pubs-searchbtn").prop("disabled", false);
$("#pubs-sterm").prop("disabled", false);
self.loadingServers = false;
},
error: function() {
$("#pubs-spinner").hide();
$("#pubs-spinner-bottom").hide();
$("#pubs-searchbtn").prop("disabled", false);
$("#pubs-sterm").prop("disabled", false);
self.loadingServers = false;
},
complete: function() {
$("#pubs-spinner").hide();
$("#pubs-spinner-bottom").hide();
$("#pubs-searchbtn").prop("disabled", false);
$("#pubs-sterm").prop("disabled", false);
self.loadingServers = false;
}
});
};
PublicServers.prototype.search = function(start, clear) {
var sterm = $("#pubs-sterm").val();
var dataset = {
"sort": [{ "online": "desc" }],
"from": start,
"size": 20,
"query": {
"filtered": {
"query": {
"query_string": {
"default_operator": "AND",
"query": sterm ? sterm : "*"
}
},
"filter": {
"bool": {
"must_not": [{
"terms": {
"identifier": this.filtered
}
}]
}
}
}
}
};
if(this.selectedCategory != "all") {
dataset.query.filtered.filter.bool.must = [{ "term": { "categories.id": this.selectedCategory } }]
}
this.loadServers(dataset, true, clear);
};
//Workaround for joining a server
PublicServers.prototype.joinServer = function (code) {
$(".guilds-add").click();
$(".action.join .btn").click();
$(".create-guild-container input").val(code);
$(".form.join-server .btn-primary").click();
};

Some files were not shown because too many files have changed in this diff Show More