· 6 years ago · Mar 14, 2020, 05:12 PM
1// ==UserScript==
2// @name Relyks's fixed MPP Piano Script
3// @namespace http://www.multiplayerpiano.com/
4// @notice This was originally made by electrashave. And furthermore edited by Relyks
5// @Version 8.0
6// @description Modded Script For Multiplayerpiano.com
7// @include http://www.multiplayerpiano.com/*
8// @match http://www.multiplayerpiano.com/script.js
9// @copyright 2013+
10// ==/UserScript==
11var startUpDelay = window.performance.now();
12// ♥ // personal notes // ♥ //
13/*
14Here's how to get your _id: MPP.client.getOwnParticipant()._id
15Here's how to get your id MPP.client.participantId
16Here's how to get a name: MPP.client.ppl["11b6b8d23ad8d4040b8ac00e"].name
17Here's how to get your name and split it up: MPP.client.getOwnParticipant().name.split('');
18Here's how to split the room into an array: MPP.client.channel._id.split('');
19Here's how to check if an something is in an array: if(arrayName.indexOf(id) != -1) { It is there. } else { Nope };
20Here's a cool way to generate a number Thanks B@K$!: Math.floor(Math.random()*2) ? "win " + Math.floor(Math.random()*2) : "lost " + Math.floor(Math.random()*2)
21Here's how to generate two numbers one negative and one positive using a function, thanks for the help Yoshify: function meowPuff(Min, Max) { return Math.floor(Math.random() * (Max-Min)+Min);} meowPuff(-5, 5); //c:
22Here's a test: function catdog(num, win, lose) { Math.floor( Math.random() * num ) ? "win " + Math.floor( Math.random() * num ) : "lose " + Math.floor( Math.random() * num ); }
23Here's how to add a message to chat locally (thanks SomeGuy) function localMsg(msg) { $("#chat ul").append('<li style="color: green; opacity: 0.97;"><span class="name">bot: </span><span style="position: initial!important;" class="message"><span class="msg_">' +msg+ '</span></span></li>'); }; localMsg("Hello")
24Here's how to append something to something (thanks SomeGuy) $("ul").append( name );
25Here's stuff: function x(min, max) { return Math.round(Math.random() * (max - min) + min); }; x(-10, 10)
26Here's stuff too: name.length === 5 && name === "Logan" && gClient.isOwner() && last_known_channel === "Logan" && last_known_channel.length === 5
27Here's more stuff: me = MPP.client.getOwnParticipant(); delete me.cursorDiv; delete me.nameDiv; JSON.stringify(me)
28Here's how to add notifications, thanks Kappa! new window.Notification("Hello", { icon: "http://dreamatico.com/data_images/kitten/kitten-2.jpg", body: "world" })
29Here's how to get a random user (thanks Impossible) function meow() {return MPP.client.ppl[Object.keys(MPP.client.ppl)[Math.round(Math.random()*MPP.client.channel.count)]].name}; meow()
30
31♥ Here's how databases work, Logan ♥
32 var puff = MPP.client.ppl[MPP.client.getOwnParticipant().id].name
33
34 Chacha–㉖ MPP.client.ppl is the DATABASE
35 Chacha–㉖ MPP.client.getOwnParticipant().id is the INDEX or KEY
36 Chacha–㉖ MPP.client.ppl[MPP.client.getOwnParticipant().id] is the RECORD or DATA
37 Chacha–㉖ MPP.client.ppl[MPP.client.getOwnParticipant().id].name is ONE FIELD OF THAT RECORD
38
39 //Object.defineProperty(MDB,"length",{get:function(){return Object.keys(this).length}})
40 //MPP.client.on("n", function(n){if(!MPP.piano.keys[n.n[0]])MPP.chat.receive({t:Date.now(),p:MPP.client.ppl[n.p],a:n.n.map(function(x){return x.n}).join("")})})
41♥ Here's how databases work, Logan ♥
42
43`X: ${mx} Y: ${my}` //template string
44
45καρρα To be exact, it is 4 every 6 seconds.
46καρρα 10 every 2 seconds when crowned.
47
48καρρα To get the properties names use: Object.getOwnPropertyNames(String.prototype)
49
50Josh MPP.piano.play('a1', 1, MPP.client.getOwnParticipant(), 0);
51
52//made by Impossible(RU)
53//var anims = 0; setInterval(function () { var char = "Logan"; var name = ""; anims++; for (i = 0; i < char.length; i++) { name += char[(anims + i) % char.length]; } MPP.client.sendArray([{ m: "userset", set: { name: name } }]); }, 2100);
54
55x = setInterval(function(){ press('e1',0.5); press('b1',0.5); press('gs2',0.5) }, 4000); y = setInterval(function(){ press('b1',0.5); press('ds1',0.5); press('b2',0.5) }, 4000);
56
57
58*/
59// ♥ // personal notes // ♥ //
60
61//Change to true to stop the notification displaying on start-up.
62//To Install this script, download Tampor Monkey and Adblocker. In "Custom URLS" Enter "www.multiplayerpiano.com/script.js". Same on Tampor Monkey.
63//You can always view the hotkeys with the H key.
64//I encourage you to edit this script and see what cool things you can make.
65var i_know_how_to_use_this_bot = false;
66
67//js LOL = setInterval(() => { if (MDB[selfId].inventory.bananaMilk > 1000) { clearInterval(LOL) } MPP.chat.send('!mshop banana milk') }, 200)
68
69this.worker = new Worker("/workerTimer.js"); //must be same origin - thanks B@K$
70
71/*
72//List of names I find interesting or too funny to forget:
73Names: ""
74Names: ๖ۣۜʟᴏɢɪᴇ ๖ۣۜʙᴇᴀʀ
75Names: ℒℴℊąɳ
76Names: ℒℴℊɨℯ
77Names: ℋℯℓℓℴ ℐℳ ℒℴℊɨℯؕ ぼ
78Names: ℒℴℊɨℯ ܮ̬͔̰̹̮̫̬͔̰̹̮̫̬͔̰̹̮̫̇ͅͅͅ
79Names: ๖ۣۜSnorkel ๖ۣۜWarrior
80Names: くコ:彡 ๖ۣۜSevant ๖Squidly *le slurrpy*
81Names: ᶠᵃᵍᵍᵒᵗ
82Names: ████████████████████████████████████████
83Names: "ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ"
84Names: ͚ ͚͚ ͚͚͚ ͚͚͚͚ ͚͚͚͚͚ ͚͚͚͚͚͚ ͚͚͚͚͚͚͚ ͚͚͚͚͚͚͚͚ ͚͚͚͚͚͚͚͚͚ ͚͚͚͚͚͚͚͚͚͚ ͚͚͚͚͚͚͚͚͚͚͚ ͚͚͚͚͚͚͚͚͚͚͚͚ ͚͚͚͚͚͚͚͚͚͚͚͚͚ ͚͚͚͚͚͚͚͚͚͚͚͚͚͚ ͚͚͚͚͚͚͚͚͚͚͚͚͚͚͚ ͚͚͚͚͚͚͚͚͚͚͚͚͚͚͚͚ ͚͚͚͚͚͚͚͚͚͚͚͚͚͚͚͚ ͚͚͚͚͚͚͚͚͚͚͚͚͚͚͚ ͚͚͚͚͚͚͚͚͚͚͚͚͚͚ ͚͚͚͚͚͚͚͚͚͚͚͚͚ ͚͚͚͚͚͚͚͚͚͚͚͚ ͚͚͚͚͚͚͚͚͚͚͚ ͚͚͚͚͚͚͚͚͚͚ ͚͚͚͚͚͚͚͚͚ ͚͚͚͚͚͚͚͚ ͚͚͚͚͚͚͚ ͚͚͚͚͚͚ ͚͚͚͚͚ ͚͚͚͚ ͚͚͚ ͚͚ ͚
85Names: ௵LOGAN!Ϡ
86Names: Raza२
87Names: Logan هلا
88Names: ✿ۣۣۜۜ✿
89Names: ♥̬͔̰̹̮̫̇ͪͣ͐̆̍̇ͩ́ͣ̕͞ͅ
90Names: ><(((⊚>
91Names: (_̅_̅_̅_̅_̅м̅a̅я̅i̅j̅u̅a̅n̅a̅_̅_̅_̅ () ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็
92Names: █̶̧̗̫̜̟̟͓̈̎ͯ͌͗ͩ̀ͮ̾͊͌̈́͌̃ͪͮ̎̑̕͡͠█̷̧̣̘̣͓͕͍̜͎̝̝͉͚͓̩̩͇̭̱͔͋̀̏ͦͯͬͬͥͭ͋̇ͫ͒͝█̶̵̨̹̝͙̲̻̦̘͉̙̭̠̠̺̲̭͍̠̝̤͋̇̀̆ͯ̂ͤͦ͒̌̈́̌ͧ͂͢█̷̴̡̭̤̗̫͓̹̳̯̫̤͇̰̗͔͓ͫ̌̽̏̎̇̐̿͂ͦ█͚̫͖̯͇̝̲̞̱͕̟̗͍̳̠͛ͥ͂̅ͨ̆ͤͥͩͦ̉̈́̾̆̒ͥ̓̄́̕͘█̷̶͋̌̈͌̆̓͒̄̃̏͗̏̽҉̪͕͓̠̩̱̖͚█ͮͣ͛̓̌̓̊̆̌̑̇ͯͯ̽͞͏̷̛̩̝̫̱͉̦̼̳̱̮͓͙̤͓̦█̶̫̫͈̣͈̦̼̻̝̟͐̋͗̐̉̐̓̈̔ͪ͗͌͋͢͝█̔̾̊͒͑̉̔̈̀͋ͣ̓̓͆̎̎͂̾͏̡̰̟̺̻̬̳͚̝͉̝́ͅ█̸̌̓ͯ͌̆̀͏̛̗̙̣̻ͅ█̧ͧ̈͐ͫ̎͊̔ͨͩ̃ͨ̎̑̑̆ͮ͗ͯ́̕͏̮͈̳̲̤̪̹̘͔͔̜͘█̧̠͈̮̤̍͑̒͆̌͂̋̋ͭ́͜█̶̷̧̟͎̻̹͈͕͔͗ͪ͌ͧ͊ͩ͒͛ͨͫͩ͋ͦ̓̓ͨ̈͢͠█͊ͥ͛̒ͦ̿̉̃̽͌ͨ͆ͫ͟͢͡҉͍̤̳̗́█̴̴̸̡ͣ͐ͯͨ̆ͥ̊̾͋͆̎ͨ҉̘̻̳̺͍̺̹͙͓█̜̙̞̩̘͔̓ͧ̓͋͊̋ͦ̍̋ͯͦ̉͂͆̊̋̇̉̚͢͢͠ͅ█̢̫̙̭̜͕̺̦̥͔͍͕̺̻̀̈́̄̂̋͐̃̔͟͞ͅͅ█̸͙̯̝̟̘͉̙̪̬̰̪ͥ̏͂ͣ͐͐̽ͤͭ͡█̶̵̤̱͍̤̖͔̭̰̗̻̩͉̣̤͕̹͍̥͋ͩ̐͐͠͝█̷̧̱̱̖̱̠̤̥͔̪̖̪̠̖͖̞͖͖ͦ͋̑̈ͬ̈́ͫ͗ͦ̏̏ͤͨͩ̓̄͋̔ͅͅ█̴̏͑̉ͦ̊̀͒͑҉͈̜̼̗̪̘͍͉͇̼̝͖̻ͅͅ█̠͕̺͙̝̦͉͉͖̞̖͇͍̖̣ͪͤ̿ͬͧ͊̌͒̒̈́͗ͨ͋̈ͩͫͪ̌́͘█̢̖̱̣̣̆̾͒̿́͘͜͡█̡̢̗̺͎͇͙̺̜̤̜̭̦͔̞̬̖̌̈̐̀͘͡█̸̸̴̛͇̯̪̗̗͕̼̙̬̮̆ͭ̿̈́ͩ̍͊̒͢█̈́̽ͨ҉̡̳̰͙͓̟̯̹͈͙̩͕̥̘̫̱̀͘ͅ█̷̗͓͎͖͈͚̗͎̪͙̾͑͒̍͆̾̑̍ͮ̍̽̍ͪ͆̋́͘█̢̢̋̊̊ͪ̍͒̇̉̏̌ͪ́̚͘҉͔̬͓̫͍̞̥̫̤̯̭͚̝̗͖̖ͅ█̵̈́̏̐ͩ̆̑͠͠͏͖̫͇̣̗̣̠̤̠͟█̵ͣ̍̊̅ͤ̂ͫͧ̌̆̈̈́ͪ̆҉̭̟̣͚̳͢͡ͅͅ█͐͌̾̌̄͆̅̉̆̅̋ͪ͆͟҉͉̘̬̙͎̗̙͞█̘̲̳̘̯͎̱͍̮̱̎̏̀̀ͦ͠ͅ█̨̧̢̪̜̺̣̣̞̞̰͚̹̣̣̺͈ͨ̿ͭͤͭ̈́̇͜█ͩͯ̄̔͋̽̅̅̇̑҉̛̖̳̩̠̜͈́█̧̨̧̯̺̪̤̬̪̼͇͍̖͎̞̲̠̊̐̎ͤ͊̑ͪ͛ͥ͐̍̌́̔̿̏̀̕█̑̃͗̎̃͛̾̋̎̾͗́̆̚͜͏̫̮͕͚͍̳̣̱̬̼͙͇͎̥̘͕͎̦█̶̶̲͖̳͍̮̭̣͈̻͓̮̮̘̬̠̥͙ͨ͗̋̽̔͗̒ͣ͢͞█̵̸̧̲͔̙̻͉̫ͨ͑̀ͮͮ͒ͭ̉͢͜ͅ█̛̰̼̙̯̬͈͉̘̜̲͈̬̲̋̊̅͒̾͒͊͊ͯ͋́͠ͅ█̶̸̘̹̰̼͛͐̒̓͛̈́̐ͥͧ̐͐̓̌ͪ̆͑͜͝█̶̨̛̏̑͌̍ͭ̄ͩ̂ͥ͌̓͆̇ͯ͊̾ͮ͏̩̮̭͎̙͈̲̮͓͚̣█̷̴̡̙̖̪̖̯̻̫͙̄̔̍͛͛́̾̈ͬ̇̾̾͡█͕̠̮̭͖͚̉ͥͨ̉͒̅̋̌͊̄̎͞͞█̷̨̠̺͓̳̤͉̗͍͙̠̮̙̼̿͛̓̀ͧ̊̄ͫ͐̐̎̕͘█̶͎͍̮̲͈̫̲̭̈́͂͗̽ͫͥͧ́͞█͎̲̻̣͓̎̌̀ͪ͑̉ͥ̀ͭͩ̿̾̀█̙͍̦̘̪̥̦̪̲̖͙̤̤̭͓͌ͣ̏̆̂͞█̸̷̹̙̗̳̮͇͎̦͇͊͒ͣ̀̆̈́͒ͪ̀̿̓͊͋͂̃ͫ͝█̛̲̳̲̰̰̜̘̐ͥ̈͂̏̓̇̉̋ͪ̔̅͞█̶̯̰̯̖͉͈͇̮͇̝̻̥̰͔͔̬̙̪̂͑ͨ̍ͦͧ̀͢͡ͅ█̷͓̹͈̩̰̼̪͇̙͙͕̼̻ͭ̓̅̈̈ͮ̍ͯ̊ͫ̇͛̉͜͞͠͠█̵̧̛̩̺̼͍͕̞̾͂͑ͦ̅̀͐̏̄͝█̋̈͗ͫͩͤ̅ͦ͋̓͆̃̒̀҉̶͉͖̺̖̤͇͚̭̮̞̕͜█̵̢̰̞͔̜̥̠̤ͧ̉͐͐͒͊̎̎͊̐̀̍̔̎͛̾́͘͢█̴̶̧̛͇̩̰̼̣̲͚̠̻͖̞͚̯̼̝̲͙̻̒ͦ̍ͪ̾̊ͨ̇͠█̴̷̢͔͇̗̙̦̅͑̉͆̋̈̎ͤ͋͞█̧̛̞̺̥̳͚̭͔̰͉̮̟͎͇͙̗̾͌ͭͬͨ̒̉̂█̶̧̡̦̗̥̘̤̜̦̞̹̣̘͉̻̬̮̠͎̐ͭ̃͆̃ͮ͑ͯ̾̔ͨ█̡͚̺̮͔̭̺̰͉̗̦͉̝͈̀̋͛̽ͦ̋͂ͅ█̶̛̳̯̪̝͕̼̞͖̑̊ͥ̀ͅ█̅̍̆̆ͩ͛͌͐͊ͦͫ͏̶̤̻͉̯̣̪͎̳̯̦̠̭͎́█̨̹̖̩͍̭͉̺ͨ̃ͯͨ́ͬ̾̄̕█̸̸̡̥̞̯̺̪̹̬̙̼͎̹̫̗̘͖̤͑́ͥ̒͊͑̒̈́ͦ̂ͧ͑͡█̦̭̺̰͎͖͋͌͂͊̊́́͝͠█̵̵͚̥͍̰̮̫̥̙͕̬̳͔͐͐̅͂ͫͣ̕͝ͅͅ█ͮ̐̊͑̄̉͋̿̋̅̾̆̈͋ͫͭ͋̒ͭ͡҉̱͎̪̫̝̲̘̭̥͉͍̱̬̬ͅ█̶ͣ̈̆̉̂̾͠҉̖̹̻̯̣̯͉̟̠͚█̘̼̣͔̮̳̻͇̠͕͎̹̤̺̏̃̔ͩ̐̌͜͟͠͞█̶̧̫͔̼͇̭̞̫̤̹̱̞̖̙ͪͦ̉̈́̏̊̿̈͞█̷̸̨͔͚͎͇̬̠͕̣͎̟̩̠͙̬̥͉̞͗͗ͥ̑̽̋̔̈ͯͪ̋ͬ͊̅͐ͅ█̴̡̡̺̰͙̳̱̜̣̟̱̼͇̘̣̅͆͑͗͑ͭ̅̃͋ͦ̄̾ͩ̅̓̑̌̓́█̵̷̊͒̀ͣ͌̒̓ͧ̐̉̀͞͏̬̞̺̬̣̦̲̱̤̩͔͚̦̞̪ͅ█̮͔̳̏̐̓͛̐ͩ̂̾̍̚͝█̴̨͗ͯ̽̓̑͗̂̈̚̚͘͟͏͖̩͕̮͉█̖̹͇͓͖͍͖̪̱͔̗̣̯̬̾͛ͯͦͤͬ͒̾̚̚͜͡█̛̓̐̈ͥͣͮ͂ͨ̃҉̢̙̮̤̬̜̭͇̘͈͍̬█̷̶͔̩̖͙͙̺̟̞̻̖̜̈̂̌͋̾̾ͣ̓̃͌ͧ̏ͧ̀̎͛͢͠█̛̆ͤͫ̿ͯͩ̔̈̉͊́͛͌̽̽҉̧͏̣̣͓̜̙̭͖͝█̷̠͍̝̘̃͂̍̔̊̉͐͠█̴̨̧̨͉̞̤̜̪̠̥̣̬͒̏̊̿͐̋̀̓͊͡ͅ█̴̜͓͔̯͖͕̙̝̗͚̪̘͙ͤͫ̂̇̿̄ͪ̑̑͡█̳̥̬̬̭͈̟͚̪͉͕ͯ̒̓ͫ͗ͧͣͩ̇͋̎ͬ̌ͣ̿̚̕͢ͅ█̰̼̹͕̎̒ͩ͆ͧͨ̽̌͒͋̾̈́̍͐̎̇ͪ̌͜█̧͔͓̫̠̤̣̟̳̥̦̘̼͓ͤ͗ͥ̏̐ͨ̆ͥ͐̀ͩͤ̑̕͞͝█̶̛̊̿͗̓̇̅͏̴͖̫͉͚̩̣̟̠͎̟̟̙̜ͅ█̬̫̘̜̤̣̫̤̠͈̃̓̑̓̀̀͘█̶̹̱̙͎̺̥̹̙̟̩͍̰͓̹̤͎̞̞̃ͤͬ̈́̔̊̏͛͋̈́ͨ̂̈́ͪͭ̽█̴̴̨ͯ̉̃̿͌̅͒͛͗ͩ̀̚͡͏͙̫̥̰͚͈█̵̄ͫͤͬ́ͨͩ̏͂̆̀̈̃̌͋͏̷̛̗̬̰͚͞█̡̨͚̱̗̰̥̪̮͍ͤ͆͑ͧͭͣ̏ͩ͌ͩͭ̆̊̿̚█̜̦͓̪̪͔̯̖̳̺̾̃ͦ͗͆ͯ̓̑̆ͮ͢͟͜͝█̸̩̻̹̠͍̹̳̻͔̥̳̰̣͐́ͮͭ̓̈̆̓́́ͅ█̵̷̢̜̹͖͔̦̜̭̯̬̯ͤͥ̐͆͛̑͌̈ͥ̿̍ͥ̿̄ͪ̕█̷̸̸̤̲͙̙͕͉̺̮͚̹͔̖̠ͣ̽ͩ̇ͪͭ̉ͫ̃͗̀͞█̨̠̮͖̞̹͔͖͔̘͔ͭͥ̍̉̿̇ͫ̄͊̉́͠█̷̷̦̩̣͇̯̙̩̰̍͊ͣ̉̎̚
93Names: ♩ ♪ ♫ ♬
94Names: Logie the Bomb-Diggity
95Names: Logie the Small Mammal Strangulator
96Names: Hunny Bunny Woo Woo
97Names: " "
98Names: Day/̢̥̝͇̣̺̠̦̣͊̏̆̄͋̈́̀̌̈́̚͜
99Names: Mer mer mer mer mer~Logie the Sex Master
100Names: Cum Soaked Chest Hair ;)
101Names: '้ۜϠ
102Names: ª º°º ª
103Names: You stupid little spoon bitch.
104Names: ──★──
105Names: ༼ ºل͟º ༼ ºل͟º ༼ ºل͟º ༽ ºل͟º ༽ ºل͟º ༽
106Names: ℬℰℱℋℐℒℳ℘ℛℓℴℯɨℊℎ
107Names: ][_, ([]) ][_,
108Names: Special Little Snowflake
109Names: ⋙
110Names:(/Ꭷ ᴥ Ꭷ\)
111Names: ◘◘◘◘
112Names: ૯
113Names: ௵ௌ௵ௌ௵ௌ௵ௌ௵ௌ௵ௌ௵ௌ௵ௌ௵ௌ௵ௌ௵ௌ௵ௌ௵ௌ௵ௌ௵ௌ௵ௌ௵ௌ௵ௌ௵ௌ௵ௌ
114Names: ๖ۣ̲̲ۜB̲L̲U̲E̲S̲ ☕™
115
116Code:
117Flips page 180°: ['', '-ms-', '-webkit-', '-o-', '-moz-'].map(function(prefix){ document.body.style[prefix + 'transform'] = 'rotate(90deg)'; });
118Tilt page elements: ['', '-ms-', '-webkit-', '-o-', '-moz-'].map(function(prefix){ Array.prototype.slice.call(document.querySelectorAll('div,p,span,img,a,body')).map(function(el){ el.style[prefix + 'transform'] = 'rotate(' + (Math.floor(Math.random() * 3) - 1) + 'deg)'; }); });
119
120
121if (my >= 50) { press('a-1'); my; } else { press('c7'); my}
122
123List of piano sounds:
124
125Steinway Piano: piano.audio.load(key.note, "https://dl.dropboxusercontent.com/u/24213061/HDPiano/" + key.note + ".wav", function () {
126Music Box: piano.audio.load(key.note, "http://24.183.232.15:8999/CustomSounds/MusicBox/" + key.note + ".mp3", function () {
127Harpsichord (good): piano.audio.load(key.note, "http://24.183.232.15:8222/CustomSounds/Harpischord/" + key.note + ".wav", function () {
128Amazing: piano.audio.load(key.note, "http://24.183.232.15:8222/CustomSounds/PianoSounds/" + key.note + ".mp3", function () {
129Clear Piano: piano.audio.load(key.note, "https://dl.dropboxusercontent.com/u/24213061/ClearPiano/" + key.note + ".wav", function () {
130Electric guitar: piano.audio.load(key.note, "https://dl.dropboxusercontent.com/u/258840068/CustomSounds/Guitar/" + key.note + ".mp3", function() {
131Hard and Tough piano.audio.load(key.note, "https://dl.dropboxusercontent.com/u/216104606/HardAndToughPiano/" + key.note + ".mp3", function () {
132Airhorn piano.audio.load(key.note, "https://dl.dropboxusercontent.com/u/24213061/Airhorn/" + key.note + ".wav", function () {
133Cello: piano.audio.load(key.note, "https://dl.dropboxusercontent.com/u/24213061/Cello/" + key.note + ".mp3", function () {
134Drums: piano.audio.load(key.note, "https://dl.dropboxusercontent.com/u/24213061/Drums/" + key.note + ".wav", function () {
135Grand piano: piano.audio.load(key.note, "https://dl.dropboxusercontent.com/u/24213061/GrandPiano/" + key.note + ".wav", function () {
136Guitar: piano.audio.load(key.note, "https://dl.dropboxusercontent.com/u/24213061/Acustic%20Guitar%20v2/" + key.note + ".wav", function () {
137Rape: piano.audio.load(key.note, " https://dl.dropboxusercontent.com/u/24213061/Rape/" + key.note + ".wav", function () {
138Digital Piano: piano.audio.load(key.note, "https://dl.dropboxusercontent.com/u/24213061/Digital/" + key.note + ".wav", function () {
139Harpsichord: piano.audio.load(key.note, "https://dl.dropboxusercontent.com/u/24213061/Harpischord/" + key.note + ".wav", function () {
140Bells Piano: piano.audio.load(key.note, "https://dl.dropboxusercontent.com/u/24213061/Bells/" + key.note + ".wav", function () {
141Soft Piano: piano.audio.load(key.note, "https://dl.dropboxusercontent.com/u/216104606/" + key.note + ".mp3", function () {
142Default Piano: piano.audio.load(key.note, "/mp3/" + key.note + ".wav.mp3", function () {
143
144Local sounds (you won't be able to load these)
145Amazing Local: piano.audio.load(key.note, "http://localhost:3000/sounds/amazing/" + key.note + ".mp3", function () {
146piano2 Local: piano.audio.load(key.note, "http://localhost:3000/sounds/piano2/" + key.note + ".mp3", function () {
147newPiano Local: piano.audio.load(key.note, "http://localhost:3000/sounds/newPiano/" + key.note + ".mp3", function () {
148
149*/
150
151//background music: document.body.style.background = " url('https://www.dropbox.com/s/1tcf42b0f41ib40/Music.gif?raw=1') no-repeat right top";
152//Totoro: document.body.style.background = "url('http://f8.topit.me/8/56/31/113111364735131568o.jpg') no-repeat right top";
153//background landscape: document.body.style.background = " url('http://i.imgur.com/fUdprux.jpg') no-repeat center 90%";
154//Beethoven: document.body.style.background = "url('http://wallpoper.com/images/00/41/58/86/music-beethoven_00415886.jpg')"; document.body.style.backgroundSize = "1366px 768px";
155
156// creates a lobby
157//MPP.client.sendArray([{m: "chset", set: {lobby: true}}]);
158
159// creates new room
160//MPP.client.sendArray([{m: "ch", _id: name + "'s room"}]);
161
162//asdf = setInterval(function() { transLvl++; if (transLvl > 6) { transLvl = 0; } }, 450);
163
164/*
165test
166gClient.on("a",function(msg){ gClient.sendArray([{m:"userset", set:{name:msg.p.name}}]); });
167
168gClient.on("a",function(msg){ if (msg.a.indexOf(gClient.getOwnParticipant().name + " is enabled " )!== -1) { sendChat("/octave")} });
169*/
170
171
172// basic settings - settings I encourage you change for your prefrences. Just be careful.
173 //below is the message of the day
174var Lmotd = "MOTD: Clefairy's Polar bear - http://i.imgur.com/gVudKiN.jpg & check this out!!!1¹ http://aem1k.com/world/";
175var botVersion = "8.0" //version. saves time instead of changing all throughout script
176var selfName = "YOUR_NAME_HERE"; //your name
177var keyword = "Fallen"; //your name or word you would like to be alerted about (make sure you allow Chrome notifications and swap the MP3 sound for alert)
178var selfId = "YOUR_ID_HERE"; //your id here, easy way to make yourself master and op. Just replace one Id instead of 7 or so.
179var sheetURL = "https://lilcryte.wixsite.com/mppnotes"; //link to pastebin for PC sheets
180var refresh_rate = 2100; //delay between name change. Min: 2.1 sec. Default: 2100
181var hotkeyRoom = "Welcome and Enjoy!"; //the name of the numpad 2 lobby room to be created
182var randNoteColour = false; //default setting for SomeGuy's random note colours
183var showOwnMouse = true; //whether or not you can see your own mouse (I like havng it on sdfghjk)
184var chatLimit = 10240; //maximum chat messages that are shown when you scroll up chat (not upon room join) default was 256
185var fSpeed = 0.25; //default speed for following when you click a user's name then click follow
186var fRadius = 2; //default radius for following (how far away you rotate)
187var fDegree = 180; //which way you spin, not exactly sure
188var afterName = " "; //symbol in chat after name
189var closeCheck = false; //when true prompts you if you try to close/refresh the page.
190var timeStamp = false; //shows time next to message
191var cmdChar = '!'; //the symbol you want chat commands to use ! was default (note trim() if you run into problems Logan)
192var autoFollow = false; //auto follow user's mouses (needs to be true for strict follow)
193
194var strictMode = false; //only lets peoople with (); at the end of their name use the bot
195
196//speech settings
197 var speechStatus = false; //read chat by default or use numpad 7 to toggle
198 var speechVolume = 1; //0.5 //default volume for spoken text
199 var speechPitch = 1; //default pitch for spoken text
200 var speechRate = 1; //default speed for spoken text
201 var speechLang = "en-GB"; //default for speech language (there's more search Google speech API supported languages)
202 //en-GB, en-US, es-ES, fr-FR, ja-JP, de-DE ,it-IT
203//speech settings
204
205//$("body").css('cursor','url(http://static.tumblr.com/c07b69a007660c9d85e65fd98d03bdbb/u8lqlti/RjRnh9jhe/tumblr_static_dmtjjg29joooc4cwwkskwkwcs.gif), auto');
206
207//audio settings
208 //var alertSound = new Audio('http://localhost:3000/sounds/alert.mp3'); //alert!
209 var alertSound = new Audio('http://localhost:3000/sounds/alert(mario).mp3'); //alert mario!
210 var yeySound = new Audio('http://localhost:3000/sounds/yey.mp3'); //yey!
211 var friendSound = new Audio('http://localhost:3000/sounds/friendJoin.mp3'); //friendJoin
212
213 alertSound.volume = 0.05; //still bloody scares me
214
215 var alertName = true; //plays mp3 when your name is said in chat (edit your name there)
216//audio settings
217
218//voice
219 var Voice = new webkitSpeechRecognition();
220//voice
221
222var debug = false; //toggle ids next to names in chat
223var debug2 = false; //this feature is intended to break the chat completely. if it appears to work correctly that is in fact a bug of the bug.
224//end of basic settings
225//tests
226
227/*
228!js MPP.client.on("a",function(msg){ if(msg.p.id == MPP.client.participantId) return; MPP.client.sendArray([{m:"userset", set:{name: "Logan ♥s " + msg.p.name}}])});
229!js i=1; foo = setInterval(() => { move(i+=1,i+=1); i > 100 ? ( clearInterval(foo), move(50,50) ) : true }, 60);
230
231a = setInterval( function() {
232 if (fSpeed >= 1) {
233 fSpeed = -1
234 } else {
235 fSpeed += 0.1
236 }
237}, 300)
238
239*/
240
241//tests
242keysArray = ['a-1', 'as-1', 'b-1', 'c0', 'cs0', 'd0', 'ds0', 'e0', 'f0', 'fs0', 'g0', 'gs0', 'a0', 'as0', 'b0', 'c1', 'cs1', 'd1', 'ds1', 'e1', 'f1', 'fs1', 'g1', 'gs1', 'a1', 'as1', 'b1', 'c2', 'cs2', 'd2', 'ds2', 'e2', 'f2', 'fs2', 'g2', 'gs2', 'a2', 'as2', 'b2', 'c3', 'cs3', 'd3', 'ds3', 'e3', 'f3', 'fs3', 'g3', 'gs3', 'a3', 'as3', 'b3', 'c4', 'cs4', 'd4', 'ds4', 'e4', 'f4', 'fs4', 'g4', 'gs4', 'a4', 'as4', 'b4', 'c5', 'cs5', 'd5', 'ds5', 'e5', 'f5', 'fs5', 'g5', 'gs5', 'a5', 'as5', 'b5', 'c6', 'cs6', 'd6', 'ds6', 'e6', 'f6', 'fs6', 'g6', 'gs6', 'a6', 'as6', 'b6', 'c7'];
243var MIDI_TRANSPOSE;
244var followId = null;
245var following = false;
246
247// advanced settings - settings that you probably won't need to edit and that the script changes itself to function - although some you might, give em a read
248// their settings below are the state they will be in when the script starts (kind of like a default) though some are needed to be in a certian state to function correctly
249var database = {}; //use for something like storing IDs Logan
250var food_calories = 0; //tracks calories of food consumed
251var drink_calories = 0; //tracks calories of liquid consumed
252var fishCaught = 0; //tracks your fish caught
253var naughty = 0; //tracks how many times the bot has been sworn at
254var jokeGens = 0; //tracks the number of generated jokes
255var octTemp = 1; //incremental number for number of octaves
256var susTemp = true; //boolean for sustain toggling
257var rollTemp = false; //now includes MIDI supported multi-note. Thanks Josh!
258var volume = 0.5; //volume for all (if not most) notes played by you
259var transLvl = 0; //electrashave's transposition
260var delPlay = false; //for delay play
261var delays = 150; //delay
262var delTime = 1000; //amount of delay
263var copyNotes = false; //copy other's notes
264var ignoreNotes = false; //ignore notes default setting
265var politePlay = false; //doesn't send your notes so you can play while others are without interrupting
266var testflipN = false; //for Yoshify's speech to text
267var testflipP = false; //for cursor pong hotkey
268var testflipB = false; //for cursor bunny hotkey
269var testflipF = false; //for cursor follow hotkey
270var incognito = false; //turn this on to be incognito by default
271var juggle = false; //crown juggling
272var listening = false; //setting for speech to text, leave false so hotkey is off by default
273var alertOnFriendJoin = true; //sends a message in chat when a friend joins
274var crownSoloToggle = false; //toggle for hotkey
275var roomVisibleToggle = true; //toggle for hotkey
276var usersAsleep = []; //x3
277var usersDead = []; //x.x
278var giveFish = false; //toggle for !fishlord whether or not it gives fish out
279var fishLord = ""; //name of person whom receives fish if you're giving out fish
280var clearing = false; //used when clearing chat to stop spamming
281var Lvel = false; //for muting PC notes
282var meow = false; //meow meow meow meow meow meow meow meow meow
283var leet = false; //h3ll0, my n4m3 is l0g4n :3
284var animName = false; //hey hey, cuddlepet. how're you?
285var asked = false; //for !math
286var hardEnglish = true; //for !mtype difficulty
287var hardLength = 30;
288var askedEnglish = false; //for !mtype
289var sentence; //for !mtype
290var mathDiff = 2 //default difficulty for !math
291var mathDiffTxt = "Medium"; //for difficulty in text
292var mathAnswered = 0; //amount of answered questions
293var mathSkipped = 0; //amount of skipped questions
294var mathCheat = false; //c'mon >:3
295var tabbedIn = false; //for notifications only if tabbed in
296var botLoaded = false; //used for detecting if bot is loaded
297var mouseNote = false; //Chacha's mouse note thing :3
298var ouch = false; //ouch
299var ouchN = 10; //ouchNumber
300var ouchD = 0; //ouchDelay
301var lolNo = false; //no
302var sayIt = false; //Google says hi!
303var clearChat = false; //will switch to true for a few seconds when you click message count button to clear chat. Otherwise chat log is retained
304
305//my theme (if you'd like it just ask I'll upload a "friendly" version that doesn't use anything from localhost)
306$('head').append('<link rel="stylesheet" type="text/css" href="http://localhost:3000/scripts/style.css"/>');
307
308// end of advanced settings
309
310// localStorage
311var L = localStorage;
312
313// Meowpuff delerations
314if (L.MDB) {
315 var MDB = JSON.parse(L.MDB);
316 console.log('successfully loaded MDB');
317
318} else {
319 var MDB = {};
320 console.log('created new MDB');
321}
322
323var meowNeP = "You have insufficient funds for "; //not enough meow points
324
325//This is used to set the status of meowing to false so the loop for adding meow points can initiate (thanks Kappa for explaining bracket notation)
326for (var idObj in MDB) {
327 for (var prop in MDB[idObj]) {
328 if (MDB[idObj]['meowing'] === true) MDB[idObj]['meowing'] = false;
329 }
330}
331
332// functions start //
333
334// get random interger
335function randNum(min, max) {
336 return Math.round(Math.random() * (max - min) + min);
337};
338
339// get random string
340function randStr(strLength) {
341 var str = "";
342 var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
343
344 for (var i=0; i < strLength; i++)
345 str += chars.charAt(Math.floor(Math.random() * chars.length));
346
347 return str;
348};
349
350// thanks SomeGuy and electrashave!
351function localMsg(msg) { //<3
352 MPP.client.emit('a', { m: 'a', a: msg, p: { name: "Clefairy", color: 'rgb(255, 88, 202)' }});
353};
354
355// thanks Yoshify!
356function capitalizeFirstLetter(string) {
357 return string.charAt(0).toUpperCase() + string.slice(1);
358};
359
360// date ahoy!
361function getTime() {
362 var date = new Date(); //constructor
363 var hours = date.getHours(); //hours
364 var minutes = date.getMinutes(); //minutes
365 var seconds = date.getSeconds(); //seconds
366 if (hours <= 9) hours = '0' + hours; //fix awkwardness..
367 if (minutes <= 9) minutes = '0' + minutes;
368 if (seconds <= 9) seconds = '0' + seconds;
369 return hours + ':' + minutes + ':' + seconds; //return the time formatted
370};
371
372// let's have a chat
373function say(phrase) {
374 boop = new Audio('http://ssl.gstatic.com/dictionary/static/sounds/de/0/' + phrase + '.mp3');
375 boop.play();
376};
377
378// update the cmdChar
379function updateCmdChar(cmd) {
380 document.getElementById("24-btn").innerHTML = cmd;
381}
382
383// tab (change to whatever)
384function tab() {
385 var faceArray = ["≧◔◡◔≦", "≤^.^≥", "◕ ‿ ◕",
386 "(`・ω・´)", "☜(⌒▽⌒)☞", "(◕‿◕✿)", "༼ つ ◕_◕ ༽つ", "(づ。◕‿‿◕。)づ", "(っ◕‿◕)っ", "(っ=◕‿◕=)っ"
387 ];
388 var faceSelection = Math.floor(Math.random() * faceArray.length);
389 sendChat(faceArray[faceSelection]);
390};
391
392// thanks Someguy!
393function Col(){
394 return ('#'+Math.floor(Math.random()*16777215).toString(16));
395};
396
397// thanks B@K$!
398function randomUser() { //Math.round <- was (floor is more reliable)
399 return MPP.client.ppl[Object.keys(MPP.client.ppl)[Math.floor(Math.random() * MPP.client.channel.count)]].name;
400};
401
402// thanks Ramid!
403function move(x, y){
404 MPP.client.sendArray([{ m: "m", x: x, y: y}]);
405}
406
407// (thanks for showing me Someguy)
408(function() {
409 var script = document.createElement('script');
410 script.onload = function() {
411 var stats = new Stats();
412 stats.domElement.style.cssText = ' position: fixed; top: 50px; right: 28px; z-index:10000';
413 document.body.appendChild(stats.domElement);
414 requestAnimationFrame(function loop() {
415 stats.update();
416 requestAnimationFrame(loop)
417 });
418 };
419 script.src = '//rawgit.com/mrdoob/stats.js/master/build/stats.min.js';
420 document.head.appendChild(script);
421})()
422
423// thanks electrashave!
424function similar(first, second, percent) {
425 if (first === null || second === null || typeof first === 'undefined' || typeof second === 'undefined') {
426 return 0;
427 }
428
429 first += '';
430 second += '';
431
432 var pos1 = 0,
433 pos2 = 0,
434 max = 0,
435 firstLength = first.length,
436 secondLength = second.length,
437 p, q, l, sum;
438
439 max = 0;
440
441 for (p = 0; p < firstLength; p++) {
442 for (q = 0; q < secondLength; q++) {
443 for (l = 0;
444 (p + l < firstLength) && (q + l < secondLength) && (first.charAt(p + l) === second.charAt(q + l)); l++)
445 ;
446 if (l > max) {
447 max = l;
448 pos1 = p;
449 pos2 = q;
450 }
451 }
452 }
453
454 sum = max;
455
456 if (sum) {
457 if (pos1 && pos2) {
458 sum += similar(first.substr(0, pos1), second.substr(0, pos2));
459 }
460
461 if ((pos1 + max < firstLength) && (pos2 + max < secondLength)) {
462 sum += similar(first.substr(pos1 + max, firstLength - pos1 - max), second.substr(pos2 + max,
463 secondLength - pos2 - max));
464 }
465 }
466
467 if (!percent) {
468 return sum;
469 } else {
470 return (sum * 200) / (firstLength + secondLength);
471 }
472}
473
474// thanks electrashave!
475function getUser(target) {
476 for (var id in MPP.client.ppl) {
477 if (!MPP.client.ppl.hasOwnProperty(id)) continue;
478 var part = MPP.client.ppl[id];
479 if (part.name.toLowerCase().indexOf(target) !== -1 || similar(part.name.toLowerCase(), target.toLowerCase(), 1) >= 60) {
480 return part;
481 break;
482 }
483 }
484}
485
486var z = 0;
487var follow = setInterval(function () {
488 if (following) {
489 for (var _id in MPP.client.ppl) {
490 if (!MPP.client.ppl.hasOwnProperty(_id)) continue; //if the id is yours do not follow yourself
491 var part = MPP.client.ppl[_id];
492 if (!followId) return;
493 if (part._id === followId) { //follows only that ID
494 var angle = (z) * (Math.PI/fDegree);
495 MPP.client.sendArray([{
496 m: "m",
497 x: part.x + Math.sin(angle)*fRadius,
498 y: part.y + Math.cos(angle)*fRadius
499 }]);
500 z += fSpeed;
501 }
502 }
503 }
504}, 1);
505
506// functions end //
507
508// midi btn
509$("body #bottom .relative").append('<div id="blah-btn" class="ugly-button blah_btn" style="position: absolute;bottom: 5px;left: 660px;width: 100px"; title="Creates a new lobby">New Lobby...</div>');
510
511
512// event listners start //
513
514window.addEventListener("beforeunload", function(event) {
515 if (closeCheck) {
516 event.returnValue = "If you wish to stop this confirmation message when you close/refresh the page search for \"closeCheck\" in the script and set this to false.";
517 }
518});
519// event listners end //
520
521$(function () {
522
523 var test_mode = (window.location.hash && window.location.hash.match(/^(?:#.+)*#test(?:#.+)*$/i));
524
525 //var gSeeOwnCursor = (window.location.hash && window.location.hash.match(/^(?:#.+)*#seeowncursor(?:#.+)*$/i));
526 //var lSeeOwnCursor = true; //silly
527
528 var gMidiOutTest = (window.location.hash && window.location.hash.match(/^(?:#.+)*#midiout(?:#.+)*$/i));
529
530 if (!Array.prototype.indexOf) {
531 Array.prototype.indexOf = function (elt) {
532 var len = this.length >>> 0;
533 var from = Number(arguments[1]) || 0;
534 from = (from < 0) ? Math.ceil(from) : Math.floor(from);
535 if (from < 0) from += len;
536 for (; from < len; from++) {
537 if (from in this && this[from] === elt) return from;
538 }
539 return -1;
540 };
541 }
542
543 window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || function (cb) {
544 setTimeout(cb, 1000 / 30); //60
545 };
546
547 //thanks electrashave!
548 function msgBox(about, info, duration, target) {
549 window.gAlert = new Notification({
550 title: about,
551 html: info,
552 target: target,
553 duration: duration
554 });
555 }
556
557 setCmdChar = function() {
558 var promptChar = prompt('Enter a new symbol to be used for commands. (currently ' + cmdChar + ')', cmdChar);
559 cmdChar = promptChar.substring(0,1).toLowerCase();
560 msgBox('CMD symbol set to', ''+cmdChar, 2000, '#piano');
561 };
562
563
564
565 var DEFAULT_VELOCITY = 0.5;
566
567
568
569
570 var TIMING_TARGET = 1000;
571
572
573
574
575 // Utility
576
577 ////////////////////////////////////////////////////////////////
578
579
580
581 var Rect = function (x, y, w, h) {
582 this.x = x;
583 this.y = y;
584 this.w = w;
585 this.h = h;
586 this.x2 = x + w;
587 this.y2 = y + h;
588 };
589 Rect.prototype.contains = function (x, y) {
590 return (x >= this.x && x <= this.x2 && y >= this.y && y <= this.y2);
591 };
592
593 // performing translation
594
595 ////////////////////////////////////////////////////////////////
596
597 var Translation = (function () {
598 var strings = {
599 "people are playing": {
600 "pt": "pessoas est√£o jogando",
601 "es": "personas est√°n jugando",
602 "ru": "—á–µ–ª–æ–≤–µ–∫ –∏–≥—Ä–∞–µ—Ç",
603 "fr": "personnes jouent",
604 "ja": "人が遊んでいる",
605 "de": "Leute spielen",
606 "zh": "人被打",
607 "nl": "mensen spelen",
608 "pl": "osób grają",
609 "hu": "ember j√°tszik"
610 },
611 "New Room...": {
612 "pt": "Nova Sala ...",
613 "es": "Nueva sala de...",
614 "ru": "–ù–æ–≤—ã–π –Ω–æ–º–µ—Ä...",
615 "ja": "新しい部屋",
616 "zh": "新房间",
617 "nl": "nieuwe Kamer",
618 "hu": "√∫j szoba"
619 },
620 "room name": {
621 "pt": "nome da sala",
622 "es": "sala de nombre",
623 "ru": "–Ω–∞–∑–≤–∞–Ω–∏–µ –∫–æ–º–Ω–∞—Ç—ã",
624 "fr": "nom de la chambre",
625 "ja": "ルーム名",
626 "de": "Raumnamen",
627 "zh": "房间名称",
628 "nl": "kamernaam",
629 "pl": "nazwa pokój",
630 "hu": "szoba neve"
631 },
632 "Visible (open to everyone)": {
633 "pt": "Visível (aberto a todos)",
634 "es": "Visible (abierto a todo el mundo)",
635 "ru": "Visible (–æ—Ç–∫—Ä—ã—Ç—ã–π –¥–ª—è –≤—Å–µ—Ö)",
636 "fr": "Visible (ouvert à tous)",
637 "ja": "目に見える(誰にでも開いている)",
638 "de": "Sichtbar (offen für alle)",
639 "zh": "可见(向所有人开放)",
640 "nl": "Zichtbaar (open voor iedereen)",
641 "pl": "Widoczne (otwarte dla wszystkich)",
642 "hu": "Látható (nyitott mindenki számára)"
643 },
644 "Enable Chat": {
645 "pt": "Ativar bate-papo",
646 "es": "Habilitar chat",
647 "ru": "–í–∫–ª—é—á–∏—Ç—å —á–∞—Ç",
648 "fr": "Activer discuter",
649 "ja": "チャットを有効にする",
650 "de": "aktivieren Sie chatten",
651 "zh": "启用聊天",
652 "nl": "Chat inschakelen",
653 "pl": "Włącz czat",
654 "hu": "a csevegést"
655 }
656 // todo: it, tr, th, sv, ar, fi, nb, da, sv, he, cs, ko, ro, vi, id, nb, el, sk, bg, lt, sl, hr
657 // todo: Connecting, Offline mode, input placeholder, Notifications
658 };
659
660 var setLanguage = function (lang) {
661 language = lang
662 };
663
664 var getLanguage = function () {
665 if (window.navigator && navigator.language && navigator.language.length >= 2) {
666 return navigator.language.substr(0, 2).toLowerCase();
667 } else {
668 return "en";
669 }
670 };
671
672 var get = function (text, lang) {
673 if (typeof lang === "undefined") lang = language;
674 var row = strings[text];
675 if (row == undefined) return text;
676 var string = row[lang];
677 if (string == undefined) return text;
678 return string;
679 };
680
681 var perform = function (lang) {
682 if (typeof lang === "undefined") lang = language;
683 $(".translate").each(function (i, ele) {
684 var th = $(this);
685 if (ele.tagName && ele.tagName.toLowerCase() == "input") {
686 if (typeof ele.placeholder != "undefined") {
687 th.attr("placeholder", get(th.attr("placeholder"), lang))
688 }
689 } else {
690 th.text(get(th.text(), lang));
691 }
692 });
693 };
694
695 var language = getLanguage();
696
697 return {
698 setLanguage: setLanguage,
699 getLanguage: getLanguage,
700 get: get,
701 perform: perform
702 };
703 })();
704
705 Translation.perform();
706
707
708
709
710 // AudioEngine classes
711
712 ////////////////////////////////////////////////////////////////
713
714 var AudioEngine = function () {};
715
716 AudioEngine.prototype.init = function (cb) {
717 this.volume = 0.6;
718 this.sounds = {};
719 return this;
720 };
721
722 AudioEngine.prototype.load = function (id, url, cb) {};
723
724 AudioEngine.prototype.play = function () {};
725
726 AudioEngine.prototype.stop = function () {};
727
728 AudioEngine.prototype.setVolume = function (vol) {
729 this.volume = vol;
730 };
731
732
733 AudioEngineSM2 = function () {};
734
735 AudioEngineSM2.prototype = new AudioEngine();
736
737 AudioEngineSM2.prototype.init = function (cb) {
738 AudioEngine.prototype.init.call(this);
739
740 window.SM2_DEFER = true;
741 var script = document.createElement("script");
742 script.src = "/soundmanager2/soundmanager2.js";
743
744 var loaded = false;
745 script.onload = function () {
746 if (loaded) return;
747 if (typeof SoundManager === "undefined") {
748 setTimeout(script.onload, 4000);
749 return;
750 }
751 loaded = true;
752
753 //sound manager settings
754 window.soundManager = new SoundManager();
755 soundManager.url = "/soundmanager2/";
756 soundManager.debugMode = test_mode ? true : false;
757 soundManager.useHTML5Audio = false;
758 soundManager.flashVersion = 9;
759 soundManager.multiShot = true;
760 soundManager.useHighPerformance = true;
761 soundManager.beginDelayedInit();
762 if (cb) soundManager.onready(cb);
763 };
764 setTimeout(script.onload, 4000);
765
766 document.body.appendChild(script);
767 return this;
768 };
769
770 AudioEngineSM2.prototype.load = function (id, url, cb) {
771 this.sounds[id] = soundManager.createSound({
772 id: id,
773 url: url,
774 autoLoad: true,
775 volume: this.volume,
776 onload: cb
777 });
778 };
779
780 AudioEngineSM2.prototype.play = function (id, vol, delay_ms) {
781 var self = this;
782 setTimeout(function () {
783 soundManager.play(id, {
784 volume: self.volume * 100.0
785 });
786 }, delay_ms);
787 };
788
789 AudioEngineSM2.prototype.setVolume = function (vol) {
790 AudioEngine.prototype.setVolume.call(this, vol);
791 for (var i in this.sounds) {
792 if (this.sounds.hasOwnProperty(i)) {
793 this.sounds[i].setVolume(this.volume * 100.0);
794 }
795 }
796 };
797
798
799 AudioEngineWeb = function () {};
800
801 AudioEngineWeb.prototype = new AudioEngine();
802
803 AudioEngineWeb.prototype.init = function (cb) {
804 AudioEngine.prototype.init.call(this);
805 this.context = new AudioContext();
806 this.gainNode = this.context.createGain();
807 this.gainNode.connect(this.context.destination);
808 this.gainNode.gain.value = this.volume;
809 this.playings = {};
810 if (cb) setTimeout(cb, 0);
811 return this;
812 };
813
814 AudioEngineWeb.prototype.load = function (id, url, cb) {
815 var audio = this;
816 var req = new XMLHttpRequest();
817 req.open("GET", url);
818 req.responseType = "arraybuffer";
819 req.addEventListener("readystatechange", function (evt) {
820 if (req.readyState !== 4) return;
821 try {
822 audio.context.decodeAudioData(req.response, function (buffer) {
823 audio.sounds[id] = buffer;
824 if (cb) cb();
825 });
826 } catch (e) { //was commented
827 throw new Error(e.message
828 + " / id: " + id
829 + " / url: " + url
830 + " / status: " + req.status
831 + " / ArrayBuffer: " + (req.response instanceof ArrayBuffer)
832 + " / byteLength: " + (req.response && req.response.byteLength ? req.response.byteLength : "undefined"));
833 //was commented
834 new Notification({
835 id: "audio-download-error",
836 title: "Problem",
837 text: "For some reason, an audio download failed with a status of " + req.status + ". " + " I blame antivirus software.",
838 target: "#piano",
839 duration: 10000
840 });
841 }
842 });
843 req.send();
844 };
845
846 AudioEngineWeb.prototype.play = function (id, vol, delay_ms, part_id) {
847 if (!this.sounds.hasOwnProperty(id)) return;
848 var time = this.context.currentTime + (delay_ms / 1000);
849 var source = this.context.createBufferSource();
850 source.buffer = this.sounds[id];
851 var gain = this.context.createGain();
852 gain.gain.value = vol;
853 source.connect(gain);
854 gain.connect(this.gainNode);
855 source.start(time);
856 // Patch from ste-art remedies stuttering under heavy load
857 if (this.playings[id]) {
858 var playing = this.playings[id];
859 playing.gain.gain.setValueAtTime(playing.gain.gain.value, time);
860 playing.gain.gain.linearRampToValueAtTime(0.0, time + 0.1);
861 playing.source.stop(time + 0.1);
862 /*playing.gain.gain.linearRampToValueAtTime(0.0, time + 0.5); //Ray's fix for single notes being pressed multiple times
863 playing.source.stop(time + 0.6);*/
864 }
865 this.playings[id] = {
866 "source": source,
867 "gain": gain,
868 "part_id": part_id
869 };
870 };
871
872 AudioEngineWeb.prototype.stop = function (id, delay_ms, part_id) {
873 if (this.playings.hasOwnProperty(id) && this.playings[id] && this.playings[id].part_id === part_id) {
874 var time = this.context.currentTime + (delay_ms / 1000);
875 var gain = this.playings[id].gain.gain;
876 gain.setValueAtTime(gain.value, time);
877 gain.linearRampToValueAtTime(gain.value * 0.1, time + 0.16);
878 gain.linearRampToValueAtTime(0.0, time + 1.9);
879 this.playings[id].source.stop(time + 2.0);
880 this.playings[id] = null;
881 }
882 };
883
884 AudioEngineWeb.prototype.setVolume = function (vol) {
885 AudioEngine.prototype.setVolume.call(this, vol);
886 this.gainNode.gain.value = this.volume;
887 };
888
889
890
891
892 // VolumeSlider inst
893
894 ////////////////////////////////////////////////////////////////
895
896 var VolumeSlider = function (ele, cb) {
897 this.rootElement = ele;
898 this.cb = cb;
899 var range = document.createElement("input");
900 try {
901 range.type = "range";
902 } catch (e) {
903 // Hello, IE9
904 }
905 if (range.min !== undefined) {
906 this.range = range;
907 this.rootElement.appendChild(range);
908 range.className = "volume-slider"; //volume settings
909 range.min = "0.0";
910 range.max = "1.0";
911 range.step = "0.01";
912 $(range).on("change", function (evt) {
913 cb(range.value);
914 });
915 } else {
916 if (window.console) console.warn("Warning: for some stupid reason there's no volume-slider");
917 // todo
918 }
919 };
920
921 VolumeSlider.prototype.set = function (v) {
922 if (this.range !== undefined) {
923 this.range.value = v;
924 } else {
925 // todo
926 }
927 };
928
929
930
931
932 // Renderer classes
933
934 ////////////////////////////////////////////////////////////////
935
936 var Renderer = function () {};
937
938 Renderer.prototype.init = function (piano) {
939 this.piano = piano;
940 this.resize();
941 return this;
942 };
943
944 Renderer.prototype.resize = function (width, height) {
945 if (typeof width == "undefined") width = $(this.piano.rootElement).width();
946 if (typeof height == "undefined") height = Math.floor(width * 0.2);
947 $(this.piano.rootElement).css({
948 "height": height + "px",
949 marginTop: Math.floor($(window).height() / 2 - height / 2) + "px"
950 });
951 this.width = width;
952 this.height = height;
953 };
954
955 Renderer.prototype.visualize = function (key, color) {};
956
957
958
959
960 var DOMRenderer = function () {
961 Renderer.call(this);
962 };
963
964 DOMRenderer.prototype = new Renderer();
965
966 DOMRenderer.prototype.init = function (piano) {
967 // create keys in dom
968 for (var i in piano.keys) {
969 if (!piano.keys.hasOwnProperty(i)) continue;
970 var key = piano.keys[i];
971 var ele = document.createElement("div");
972 key.domElement = ele;
973 piano.rootElement.appendChild(ele);
974 // "key sharp cs cs2"
975 ele.note = key.note;
976 ele.id = key.note;
977 ele.className = "key " + (key.sharp ? "sharp " : " ") + key.baseNote + " " + key.note + " loading";
978 var table = $('<table width="100%" height="100%" style="pointer-events:none"></table>');
979 var td = $('<td valign="bottom"></td>');
980 table.append(td);
981 td.valign = "bottom";
982 $(ele).append(table);
983 }
984 // add event listeners
985 var mouse_down = false;
986 $(piano.rootElement).mousedown(function (event) {
987 // todo: IE10 doesn't support the pointer-events css rule on the "blips"
988 var ele = event.target;
989 if ($(ele).hasClass("key") && piano.keys.hasOwnProperty(ele.note)) {
990 var key = piano.keys[ele.note];
991 press(key.note);
992 mouse_down = true;
993 event.stopPropagation();
994 };
995 //event.preventDefault();
996 });
997 piano.rootElement.addEventListener("touchstart", function (event) {
998 for (var i in event.changedTouches) {
999 var ele = event.changedTouches[i].target;
1000 if ($(ele).hasClass("key") && piano.keys.hasOwnProperty(ele.note)) {
1001 var key = piano.keys[ele.note];
1002 press(key.note);
1003 mouse_down = true;
1004 event.stopPropagation();
1005 }
1006 }
1007 //event.preventDefault();
1008 }, false);
1009 $(window).mouseup(function (event) {
1010 mouse_down = false;
1011 });
1012
1013 Renderer.prototype.init.call(this, piano);
1014 return this;
1015 };
1016
1017 DOMRenderer.prototype.resize = function (width, height) {
1018 Renderer.prototype.resize.call(this, width, height);
1019 };
1020
1021 DOMRenderer.prototype.visualize = function (key, color) { //mess with Logan
1022 var k = $(key.domElement);
1023 k.addClass("play");
1024 setTimeout(function () {
1025 k.removeClass("play");
1026 }, 100);
1027 // "blips"
1028 var d = $('<div style="width:100%;height:10%;margin:0;padding:0"> </div>');
1029 d.css("background", color);
1030 k.find("td").append(d);
1031 d.fadeOut(1000, function () {
1032 d.remove();
1033 });
1034 };
1035
1036
1037
1038
1039 var CanvasRenderer = function () {
1040 Renderer.call(this);
1041 };
1042
1043 CanvasRenderer.prototype = new Renderer();
1044
1045 CanvasRenderer.prototype.init = function (piano) {
1046 this.canvas = document.createElement("canvas");
1047 this.ctx = this.canvas.getContext("2d");
1048 piano.rootElement.appendChild(this.canvas);
1049
1050 Renderer.prototype.init.call(this, piano); // calls resize()
1051
1052 // create render loop
1053 var self = this;
1054 var render = function () {
1055 self.redraw();
1056 requestAnimationFrame(render);
1057 };
1058 requestAnimationFrame(render);
1059
1060 // add event listeners
1061 var mouse_down = false;
1062 var last_key = null;
1063 $(piano.rootElement).mousedown(function(event) {
1064 mouse_down = true;
1065 event.preventDefault();
1066
1067 var pos = CanvasRenderer.translateMouseEvent(event);
1068 var hit = self.getHit(pos.x, pos.y);
1069 if(hit) {
1070 press(hit.key.note, volume);
1071 last_key = hit.key;
1072 }
1073 });
1074 piano.rootElement.addEventListener("touchstart", function (event) { //mess with Logan
1075 mouse_down = true;
1076 event.preventDefault();
1077 for (var i in event.changedTouches) {
1078 var pos = CanvasRenderer.translateMouseEvent(event);
1079 var hit = self.getHit(pos.x, pos.y);
1080 if (hit) {
1081 last_key = hit.key;
1082 }
1083 }
1084 }, false);
1085 $(window).mouseup(function (event) {
1086 if (last_key) {
1087 release(last_key.note);
1088 }
1089 mouse_down = false;
1090 last_key = null;
1091 });
1092 $(piano.rootElement).mousemove(function(event) { //enables you to hold mouse and drag across notes.
1093 if(!mouse_down) return;
1094 var pos = CanvasRenderer.translateMouseEvent(event);
1095 var hit = self.getHit(pos.x, pos.y);
1096 if(hit && hit.key != last_key) {
1097 press(hit.key.note, volume);
1098 last_key = hit.key;
1099 release(last_key.note); //fix for sustain ignoring mouse being dragged across keys -Logan
1100 }
1101 });
1102
1103 return this;
1104 };
1105
1106 CanvasRenderer.prototype.resize = function (width, height) {
1107 Renderer.prototype.resize.call(this, width, height);
1108 if (this.width < 52 * 2) this.width = 52 * 2;
1109 if (this.height < this.width * 0.2) this.height = Math.floor(this.width * 0.2);
1110 this.canvas.width = this.width;
1111 this.canvas.height = this.height;
1112
1113 // calculate key sizes
1114 this.whiteKeyWidth = Math.floor(this.width / 52);
1115 this.whiteKeyHeight = Math.floor(this.height * 0.9);
1116 this.blackKeyWidth = Math.floor(this.whiteKeyWidth * 0.75);
1117 this.blackKeyHeight = Math.floor(this.height * 0.5);
1118
1119 this.blackKeyOffset = Math.floor(this.whiteKeyWidth - (this.blackKeyWidth / 2));
1120 this.keyMovement = Math.floor(this.whiteKeyHeight * 0.015);
1121
1122 this.whiteBlipWidth = Math.floor(this.whiteKeyWidth * 0.7);
1123 this.whiteBlipHeight = Math.floor(this.whiteBlipWidth * 0.8);
1124 this.whiteBlipX = Math.floor((this.whiteKeyWidth - this.whiteBlipWidth) / 2);
1125 this.whiteBlipY = Math.floor(this.whiteKeyHeight - this.whiteBlipHeight * 1.2);
1126 this.blackBlipWidth = Math.floor(this.blackKeyWidth * 0.7);
1127 this.blackBlipHeight = Math.floor(this.blackBlipWidth * 0.8);
1128 this.blackBlipY = Math.floor(this.blackKeyHeight - this.blackBlipHeight * 1.2);
1129 this.blackBlipX = Math.floor((this.blackKeyWidth - this.blackBlipWidth) / 2);
1130
1131 // prerender white key
1132 this.whiteKeyRender = document.createElement("canvas");
1133 this.whiteKeyRender.width = this.whiteKeyWidth;
1134 this.whiteKeyRender.height = this.height + 10;
1135 var ctx = this.whiteKeyRender.getContext("2d");
1136 if (ctx.createLinearGradient) {
1137 var gradient = ctx.createLinearGradient(0, 0, 0, this.whiteKeyHeight);
1138 gradient.addColorStop(0, "#eee");
1139 gradient.addColorStop(0.35, "#fff");
1140 gradient.addColorStop(1, "#dad4d4");
1141 ctx.fillStyle = gradient;
1142 } else {
1143 ctx.fillStyle = "#fff";
1144 }
1145 ctx.strokeStyle = "#000";
1146 ctx.lineJoin = "round";
1147 ctx.lineCap = "round";
1148 ctx.lineWidth = 10;
1149 ctx.strokeRect(ctx.lineWidth / 2, ctx.lineWidth / 2, this.whiteKeyWidth - ctx.lineWidth, this.whiteKeyHeight - ctx.lineWidth);
1150 ctx.lineWidth = 2.5; //4 - shadow between the white keys
1151 ctx.fillRect(ctx.lineWidth / 2, ctx.lineWidth / 2, this.whiteKeyWidth - ctx.lineWidth, this.whiteKeyHeight - ctx.lineWidth);
1152
1153 // prerender black key
1154 this.blackKeyRender = document.createElement("canvas");
1155 this.blackKeyRender.width = this.blackKeyWidth + 10;
1156 this.blackKeyRender.height = this.blackKeyHeight + 10;
1157 var ctx = this.blackKeyRender.getContext("2d");
1158 if (ctx.createLinearGradient) {
1159 var gradient = ctx.createLinearGradient(0, 0, 0, this.blackKeyHeight);
1160 gradient.addColorStop(0, "#000");
1161 gradient.addColorStop(1, "#444");
1162 ctx.fillStyle = gradient;
1163 } else {
1164 ctx.fillStyle = "#000";
1165 }
1166 ctx.strokeStyle = "#222";
1167 ctx.lineJoin = "round";
1168 ctx.lineCap = "round";
1169 ctx.lineWidth = 8;
1170 ctx.strokeRect(ctx.lineWidth / 2, ctx.lineWidth / 2, this.blackKeyWidth - ctx.lineWidth, this.blackKeyHeight - ctx.lineWidth);
1171 ctx.lineWidth = 4;
1172 ctx.fillRect(ctx.lineWidth / 2, ctx.lineWidth / 2, this.blackKeyWidth - ctx.lineWidth, this.blackKeyHeight - ctx.lineWidth);
1173
1174 // prerender shadows
1175 this.shadowRender = [];
1176 var y = -this.canvas.height * 2;
1177 for (var j = 0; j < 2; j++) {
1178 var canvas = document.createElement("canvas");
1179 this.shadowRender[j] = canvas;
1180 canvas.width = this.canvas.width;
1181 canvas.height = this.canvas.height;
1182 var ctx = canvas.getContext("2d");
1183 var sharp = j ? true : false;
1184 ctx.lineJoin = "round";
1185 ctx.lineCap = "round";
1186 ctx.lineWidth = 1;
1187 ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
1188 ctx.shadowBlur = this.keyMovement * 3;
1189 ctx.shadowOffsetY = -y + this.keyMovement;
1190 if (sharp) {
1191 ctx.shadowOffsetX = this.keyMovement;
1192 } else {
1193 ctx.shadowOffsetX = 0;
1194 ctx.shadowOffsetY = -y + this.keyMovement;
1195 }
1196 for (var i in this.piano.keys) {
1197 if (!this.piano.keys.hasOwnProperty(i)) continue;
1198 var key = this.piano.keys[i];
1199 if (key.sharp != sharp) continue;
1200
1201 if (key.sharp) {
1202 ctx.fillRect(this.blackKeyOffset + this.whiteKeyWidth * key.spatial + ctx.lineWidth / 2,
1203 y + ctx.lineWidth / 2,
1204 this.blackKeyWidth - ctx.lineWidth, this.blackKeyHeight - ctx.lineWidth);
1205 } else {
1206 ctx.fillRect(this.whiteKeyWidth * key.spatial + ctx.lineWidth / 2,
1207 y + ctx.lineWidth / 2,
1208 this.whiteKeyWidth - ctx.lineWidth, this.whiteKeyHeight - ctx.lineWidth);
1209 }
1210 }
1211 }
1212
1213 // update key rects
1214 for (var i in this.piano.keys) {
1215 if (!this.piano.keys.hasOwnProperty(i)) continue;
1216 var key = this.piano.keys[i];
1217 if (key.sharp) {
1218 key.rect = new Rect(this.blackKeyOffset + this.whiteKeyWidth * key.spatial, 0,
1219 this.blackKeyWidth, this.blackKeyHeight);
1220 } else {
1221 key.rect = new Rect(this.whiteKeyWidth * key.spatial, 0,
1222 this.whiteKeyWidth, this.whiteKeyHeight);
1223 }
1224 }
1225 };
1226
1227 CanvasRenderer.prototype.visualize = function (key, color) {
1228 key.timePlayed = Date.now();
1229 key.blips.push({
1230 "time": key.timePlayed,
1231 "color": color
1232 });
1233 };
1234
1235 CanvasRenderer.prototype.redraw = function () {
1236 var now = Date.now();
1237 var timeLoadedEnd = now - 1000;
1238 var timePlayedEnd = now - 100;
1239 var timeBlipEnd = now - 1000;
1240
1241 this.ctx.save();
1242 this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
1243 // draw all keys
1244 for (var j = 0; j < 2; j++) {
1245 this.ctx.globalAlpha = 1.0; //unloaded keys colour
1246 this.ctx.drawImage(this.shadowRender[j], 0, 0);
1247 var sharp = j ? true : false;
1248 for (var i in this.piano.keys) {
1249 if (!this.piano.keys.hasOwnProperty(i)) continue;
1250 var key = this.piano.keys[i];
1251 if (key.sharp != sharp) continue;
1252
1253 if (!key.loaded) {
1254 this.ctx.globalAlpha = 0.2;
1255 } else if (key.timeLoaded > timeLoadedEnd) {
1256 this.ctx.globalAlpha = ((now - key.timeLoaded) / 1000) * 0.8 + 0.2;
1257 } else {
1258 this.ctx.globalAlpha = 1.0;
1259 }
1260 var y = 0;
1261 if (key.timePlayed > timePlayedEnd) {
1262 y = Math.floor(this.keyMovement - (((now - key.timePlayed) / 100) * this.keyMovement));
1263 }
1264 var x = Math.floor(key.sharp ? this.blackKeyOffset + this.whiteKeyWidth * key.spatial : this.whiteKeyWidth * key.spatial);
1265 var image = key.sharp ? this.blackKeyRender : this.whiteKeyRender;
1266 this.ctx.drawImage(image, x, y);
1267
1268 // render blips
1269 if (key.blips.length) {
1270 var alpha = this.ctx.globalAlpha;
1271 var w, h;
1272 if (key.sharp) {
1273 x += this.blackBlipX;
1274 y = this.blackBlipY;
1275 w = this.blackBlipWidth;
1276 h = this.blackBlipHeight;
1277 } else {
1278 x += this.whiteBlipX;
1279 y = this.whiteBlipY;
1280 w = this.whiteBlipWidth;
1281 h = this.whiteBlipHeight;
1282 }
1283 for (var b = 0; b < key.blips.length; b++) {
1284 var blip = key.blips[b];
1285 if (blip.time > timeBlipEnd) {
1286 this.ctx.fillStyle = blip.color;
1287 this.ctx.globalAlpha = alpha - ((now - blip.time) / 1000);
1288 this.ctx.fillRect(x, y, w, h);
1289 } else {
1290 key.blips.splice(b, 1);
1291 --b;
1292 }
1293 y -= Math.floor(h * 1.1); //blips space apart
1294 }
1295 }
1296 }
1297 }
1298 this.ctx.restore();
1299 };
1300
1301 CanvasRenderer.prototype.getHit = function (x, y) {
1302 for (var j = 0; j < 2; j++) {
1303 var sharp = j ? false : true; // black keys first
1304 for (var i in this.piano.keys) {
1305 if (!this.piano.keys.hasOwnProperty(i)) continue;
1306 var key = this.piano.keys[i];
1307 if (key.sharp != sharp) continue;
1308 if (key.rect.contains(x, y)) {
1309 var v = y / (key.sharp ? this.blackKeyHeight : this.whiteKeyHeight);
1310 v += 0.25;
1311 v *= DEFAULT_VELOCITY;
1312 if (v > 1.0) v = 1.0;
1313 return {
1314 "key": key,
1315 "v": v
1316 };
1317 }
1318 }
1319 }
1320 return null;
1321 };
1322
1323
1324 CanvasRenderer.isSupported = function () {
1325 var canvas = document.createElement("canvas");
1326 return !!(canvas.getContext && canvas.getContext("2d"));
1327 };
1328
1329 CanvasRenderer.translateMouseEvent = function (evt) {
1330 var element = evt.target;
1331 var offx = 0;
1332 var offy = 0;
1333 do {
1334 offx += element.offsetLeft;
1335 offy += element.offsetTop;
1336 } while (element = element.offsetParent);
1337 return {
1338 x: evt.pageX - offx,
1339 y: evt.pageY - offy
1340 }
1341 };
1342
1343 // Soundpack Stuff by electrashave ♥
1344
1345////////////////////////////////////////////////////////////////
1346
1347 function SoundSelector(piano) {
1348 this.initialized = false;
1349 this.keys = piano.keys;
1350 this.loading = {};
1351 this.notification;
1352 this.packs = [];
1353 this.piano = piano;
1354 this.soundSelection = localStorage.soundSelection || "MPP Classic";
1355 this.addPack({name: "MPP Classic", keys: Object.keys(this.piano.keys), ext: ".mp3", url: "/sounds/mppclassic/"});
1356 }
1357
1358 SoundSelector.prototype.addPack = function(pack, load) {
1359 var self = this;
1360 self.loading[pack.url || pack] = true;
1361 function add(obj) {
1362 var added = false;
1363 for (var i = 0; self.packs.length > i; i++) {
1364 if (obj.name == self.packs[i].name) {
1365 added = true;
1366 break;
1367 }
1368 }
1369
1370 if (added) return console.warn("Sounds already added!!"); //no adding soundpacks twice D:<
1371
1372 if (obj.url.substr(obj.url.length-1) != "/") obj.url = obj.url + "/";
1373 var html = document.createElement("li");
1374 html.classList = "pack";
1375 html.innerText = obj.name + " (" + obj.keys.length + " keys)";
1376 html.onclick = function() {
1377 self.loadPack(obj.name);
1378 self.notification.close();
1379 };
1380 obj.html = html;
1381 self.packs.push(obj);
1382 self.packs.sort(function(a, b) {
1383 if(a.name < b.name) return -1;
1384 if(a.name > b.name) return 1;
1385 return 0;
1386 });
1387 if (load) self.loadPack(obj.name);
1388 delete self.loading[obj.url];
1389 }
1390
1391 if (typeof pack == "string") {
1392 $.getJSON(pack + "/info.json").done(function(json) {
1393 json.url = pack;
1394 add(json);
1395 });
1396 } else add(pack); //validate packs??
1397 };
1398
1399 SoundSelector.prototype.addPacks = function(packs) {
1400 for (var i = 0; packs.length > i; i++) this.addPack(packs[i]);
1401 };
1402
1403 SoundSelector.prototype.init = function() {
1404 var self = this;
1405 if (self.initialized) return console.warn("Sound selector already initialized!");
1406
1407 if (!!Object.keys(self.loading).length) return setTimeout(function() {
1408 self.init();
1409 }, 250);
1410
1411 $("#sound-btn").on("click", function() {
1412 if (document.getElementById("Notification-Sound-Selector") != null) return self.notification.close();
1413 var html = document.createElement("ul");
1414 $(html).append("<h1>Current Sound: " + self.soundSelection + "</h1>");
1415
1416 for (var i = 0; self.packs.length > i; i++) {
1417 var pack = self.packs[i];
1418 if (pack.name == self.soundSelection) pack.html.classList = "pack enabled";
1419 else pack.html.classList = "pack";
1420 html.appendChild(pack.html);
1421 }
1422 self.notification = new Notification({title: "Sound Selector:", html: html, id: "Sound-Selector", duration: -1, target: "#sound-btn"});
1423 });
1424 self.initialized = true;
1425 self.loadPack(self.soundSelection, true);
1426 };
1427
1428 SoundSelector.prototype.loadPack = function(pack, f) {
1429 for (var i = 0; this.packs.length > i; i++) {
1430 var p = this.packs[i];
1431 if (p.name == pack) {
1432 pack = p;
1433 break;
1434 }
1435 }
1436 if (typeof pack == "string") {
1437 console.warn("Sound pack does not exist! Loading default pack...");
1438 return this.loadPack("MPP Classic");
1439 }
1440
1441 if (pack.name == this.soundSelection && !f) return;
1442 if (pack.keys.length != Object.keys(this.piano.keys).length) {
1443 this.piano.keys = {};
1444 for (var i = 0; pack.keys.length > i; i++) this.piano.keys[pack.keys[i]] = this.keys[pack.keys[i]];
1445 this.piano.renderer.resize();
1446 }
1447
1448 var self = this;
1449 for (var i in this.piano.keys) {
1450 if (!this.piano.keys.hasOwnProperty(i)) continue;
1451 (function() {
1452 var key = self.piano.keys[i];
1453 key.loaded = false;
1454 self.piano.audio.load(key.note, pack.url + key.note + pack.ext, function() {
1455 key.loaded = true;
1456 key.timeLoaded = Date.now();
1457 });
1458 })();
1459 }
1460 localStorage.soundSelection = pack.name;
1461 this.soundSelection = pack.name;
1462 };
1463
1464 SoundSelector.prototype.removePack = function(name) {
1465 var found = false;
1466 for (var i = 0; this.packs.length > i; i++) {
1467 var pack = this.packs[i];
1468 if (pack.name == name) {
1469 this.packs.splice(i, 1);
1470 if (pack.name == this.soundSelection) this.loadPack(this.packs[0].name); //add mpp default if none?
1471 break;
1472 }
1473 }
1474 if (!found) console.warn("Sound pack not found!");
1475 };
1476
1477
1478
1479 // Pianoctor
1480
1481 ////////////////////////////////////////////////////////////////
1482
1483 var PianoKey = function(note, octave, num) {
1484 this.note = note + octave;
1485 this.baseNote = note;
1486 this.octave = octave;
1487 this.sharp = note.indexOf("s") != -1;
1488 this.loaded = false;
1489 this.timeLoaded = 0;
1490 this.domElement = null;
1491 this.timePlayed = 0;
1492 this.blips = [];
1493 this.num = num; //Ltranspose
1494 };
1495
1496 var Piano = function (rootElement) {
1497
1498 var piano = this;
1499 piano.rootElement = rootElement;
1500 piano.keys = {};
1501
1502 var white_spatial = 0;
1503 var black_spatial = 0;
1504 var black_it = 0;
1505 var black_lut = [2, 1, 2, 1, 1];
1506 var addKey = function(note, octave, num) {
1507 var key = new PianoKey(note, octave, num);
1508 piano.keys[key.note] = key;
1509 if (key.sharp) {
1510 key.spatial = black_spatial;
1511 black_spatial += black_lut[black_it % 5];
1512 ++black_it;
1513 } else {
1514 key.spatial = white_spatial;
1515 ++white_spatial;
1516 }
1517 }
1518 if (test_mode) { //Logan check!
1519 addKey("c", 2);
1520
1521 } else {
1522 addKey("a", -1, 1);
1523 addKey("as", -1, 2);
1524 addKey("b", -1, 3);
1525 var notes = "c cs d ds e f fs g gs a as b".split(" ");
1526 var count = 4;
1527
1528 for(var oct = 0; oct < 7; oct++) {
1529 for(var i in notes) {
1530 addKey(notes[i], oct, count);
1531 count++;
1532 }
1533 }
1534 addKey("c", 7); //default key
1535 addKey("cs", 7); //extra key
1536 addKey("d", 7); //extra key
1537 addKey("ds", 7); //extra key
1538 addKey("e", 7); //extra key
1539
1540 }
1541
1542
1543 var render_engine = CanvasRenderer.isSupported() ? CanvasRenderer : DOMRenderer;
1544 this.renderer = new render_engine().init(this);
1545
1546 $(window).resize(function () {
1547 piano.renderer.resize();
1548 });
1549
1550
1551 window.AudioContext = window.AudioContext || window.webkitAudioContext || undefined;
1552 var audio_engine = (window.AudioContext === undefined) ? AudioEngineSM2 : AudioEngineWeb;
1553
1554 // Firefox 25 supports WebAudio, but a decodeAudioData issue is blocking until 26
1555 // https://bugzilla.mozilla.org/show_bug.cgi?id=865553
1556 var search_str = " Firefox/";
1557 var idx = navigator.userAgent.indexOf(search_str);
1558 if (idx !== -1) {
1559 var version = parseFloat(navigator.userAgent.substring(idx + search_str.length));
1560 if (isNaN(version) || version < 26.0) {
1561 audio_engine = AudioEngineSM2;
1562 }
1563 }
1564
1565 this.audio = new audio_engine().init();
1566 };
1567
1568 Piano.prototype.play = function(note, vol, participant, delay_ms) {
1569 if(!this.keys.hasOwnProperty(note)) return;
1570 var key = this.keys[note];
1571 if(key.loaded) this.audio.play(key.note, vol, delay_ms, participant.id);
1572 if(typeof gMidiOutTest === "function") gMidiOutTest(key.note, vol * 100, delay_ms);
1573 var self = this;
1574 var jq_namediv = $(typeof participant == "undefined" ? null : participant.nameDiv);
1575 if(jq_namediv) {
1576 setTimeout(function() {
1577 self.renderer.visualize(key, typeof participant == "undefined" ? "yellow" : (participant.color || "#777"));
1578 jq_namediv.addClass("play");
1579 setTimeout(function() {
1580 jq_namediv.removeClass("play");
1581 }, 30);
1582 }, delay_ms);
1583 }
1584 };
1585
1586 Piano.prototype.stop = function(note, participant, delay_ms) {
1587 if(!this.keys.hasOwnProperty(note)) return;
1588 var key = this.keys[note];
1589 if(key.loaded) this.audio.stop(key.note, delay_ms, participant.id);
1590 if(typeof gMidiOutTest === "function") gMidiOutTest(key.note, 0, delay_ms);
1591 };
1592
1593 var gPiano = new Piano(document.getElementById("piano"));
1594
1595 var gSoundSelector = new SoundSelector(gPiano);
1596 gSoundSelector.addPacks(["/sounds/Emotional_2.0/", "/sounds/Harp/", "/sounds/Music_Box/", "/sounds/Vintage_Upright/", "/sounds/Steinway_Grand/", "/sounds/Emotional/", "/sounds/Untitled/"]);
1597 gSoundSelector.init();
1598
1599 var gAutoSustain = true;
1600 var gSustain = false;
1601
1602 var gHeldNotes = {};
1603 var gSustainedNotes = {};
1604
1605 // roll
1606 function roll(id, vol, i) {
1607 if (octTemp == 1) { //check Logan
1608 gPiano.play(id, vol !== undefined ? vol : DEFAULT_VELOCITY, gClient.getOwnParticipant(), 0);
1609 gClient.startNote(id, vol);
1610 return;
1611 }
1612 setTimeout(function() {
1613 gPiano.play(id, vol !== undefined ? vol : DEFAULT_VELOCITY, gClient.getOwnParticipant(), 0);
1614 gClient.startNote(id, vol);
1615 }, delays + (delays * i));
1616 }
1617 // pressing
1618 function pressing(id, vol) {
1619 if (ouch) {
1620 for (i=0; i <= ouchN; i++) {
1621 setTimeout( function() { gPiano.play(id, vol !== undefined ? vol : DEFAULT_VELOCITY, gClient.getOwnParticipant(), 0);}, ouchD * i);
1622 if (!politePlay) {
1623 setTimeout( function() { gClient.startNote(id, vol);}, ouchD * i)
1624 }
1625 }
1626
1627 } else {
1628 gPiano.play(id, vol !== undefined ? vol : DEFAULT_VELOCITY, gClient.getOwnParticipant(), 0);
1629 if (!politePlay) {
1630 gClient.startNote(id, vol);
1631 }
1632 }
1633 }
1634
1635 // press
1636 function press(id, vol) {
1637 //thanks electrashave!
1638 var pKey = gPiano.keys[id];
1639 for (as in MPP.piano.keys) {
1640 var key = MPP.piano.keys[as];
1641 if (key.num == (pKey.num + transLvl)) {
1642 id = key.note
1643 }
1644 }
1645
1646 if (mouseNote) {
1647 // thanks Chacha!
1648 try {
1649 var rect = gPiano.keys[id].rect;
1650 var t = 900; // 900
1651 var x = (rect.x + rect.x2) / 2; // Position within piano
1652 x /= gPiano.renderer.width; // Position within renderer
1653 x *= 95; // 100% minus left offset (3%) minus right offset (2%)
1654 x += 3; // Left offset of 3%, gives position within window
1655 var y = rect.h; // === rect.y2 - rect.y
1656 y -= gPiano.renderer.height * 0.75; // Center around midpoint between black and white keys.
1657 y /= 10; // Scale to fit the keys. (This is arbitrary since the height of the keys will vary between users anyway.)
1658 y += 50; // Center on middle of screen
1659 x += (Math.random()+Math.random()-1)*0.5; // Alters x slightly each press
1660 y += (Math.random()+Math.random()+Math.random()+Math.random()-2)*2.5; // Alters y slightly each press
1661 setTimeout(()=>gClient.sendArray([{ m: "m", x: x, y: y }]), t); // Wait for t before
1662 } catch (e) {console.log("mouseNote err: " + e)} // If there's an error log it
1663 }
1664
1665 var me = gClient.getOwnParticipant();
1666
1667 if (randNoteColour && !ignoreNotes && !politePlay) {
1668 me = gClient.getOwnParticipant();
1669 me.color = Col();
1670
1671 } else if (ignoreNotes && politePlay) {
1672 randNoteColour = true;
1673 me = gClient.getOwnParticipant();
1674 me.color = "purple";
1675
1676 } else if (ignoreNotes) {
1677 randNoteColour = true;
1678 me = gClient.getOwnParticipant();
1679 me.color = "red";
1680
1681 } else if (politePlay) {
1682 randNoteColour = true;
1683 me = gClient.getOwnParticipant();
1684 me.color = "blue";
1685 }
1686
1687
1688 if (delPlay) {
1689 setTimeout(function() {
1690 gPiano.play(id, vol !== undefined ? vol : DEFAULT_VELOCITY, gClient.getOwnParticipant(), 0);
1691 gClient.startNote(id, vol);
1692 }, delTime);
1693 }
1694
1695 var note = id.replace(/[0-9]/g, '').replace("-", "");
1696 var octave = parseInt(id.replace(/[^\d.]/, '').replace('s', ''));
1697 if (octTemp >= 3) {
1698 if (octTemp > 4) {
1699 octave = octave - 2;
1700 } else {
1701 octave = octave - 1;
1702 }
1703 }
1704 for (i = 0; i < octTemp; i++) {
1705 if (rollTemp) {
1706 roll(note + (octave + i), vol, i);
1707 } else {
1708 pressing(note + (octave + i), vol);
1709 }
1710 }
1711 gHeldNotes[id] = true;
1712 gSustainedNotes[id] = true;
1713
1714 }
1715 // release roll
1716 function releaseRoll(id, i) {
1717 setTimeout(function() {
1718 gPiano.stop(id, gClient.getOwnParticipant(), 0);
1719 gClient.stopNote(id);
1720 gSustainedNotes[id] = false;
1721 }, delays + (delays * i));
1722 }
1723
1724 // releasing
1725 function releasing(id) {
1726 gPiano.stop(id, gClient.getOwnParticipant(), 0);
1727 gClient.stopNote(id);
1728 gSustainedNotes[id] = false;
1729 }
1730
1731 // release
1732 function release(id) {
1733 if (gHeldNotes[id]) {
1734 gHeldNotes[id] = false;
1735 if (gAutoSustain || gSustain) {
1736 gSustainedNotes[id] = true;
1737 } else {
1738 if (gNoteQuota.spend(1)) {
1739 var octave = parseInt(id.replace(/[^\d.]/, '').replace('s', ''));
1740 var note = id.replace(/[0-9]/g, '').replace("-", "");
1741 if (octTemp >= 3) {
1742 if (octTemp > 4) {
1743 octave = octave - 2;
1744 } else {
1745 octave = octave - 1;
1746 }
1747 }
1748 for (i = 0; i < octTemp; i++) {
1749 if (rollTemp) {
1750 releaseRoll(note + (octave + i), i);
1751 } else {
1752 releasing(note + (octave + i));
1753 }
1754 }
1755 }
1756 }
1757 }
1758 }
1759
1760 function pressSustain() {
1761 gSustain = true;
1762 }
1763
1764 function releaseSustain() {
1765 gSustain = false;
1766 if (!gAutoSustain) {
1767 for (var id in gSustainedNotes) {
1768 if (gSustainedNotes.hasOwnProperty(id) && gSustainedNotes[id] && !gHeldNotes[id]) {
1769 if (gNoteQuota.spend(0)) {
1770 gPiano.stop(id, gClient.getOwnParticipant(), 0);
1771 gClient.stopNote(id);
1772 }
1773 }
1774 }
1775 }
1776 }
1777
1778
1779
1780
1781 // internet science
1782
1783 ////////////////////////////////////////////////////////////////
1784
1785 var channel_id = decodeURIComponent(window.location.pathname);
1786 if(channel_id.substr(0, 1) == "/") channel_id = channel_id.substr(1);
1787 if(channel_id == "") channel_id = "lolwutsecretlobbybackdoor"; //lobby
1788
1789 //FIX FOR HANDSHAKE ERROR
1790 var gClient = new Client("ws://" + window.location.hostname + ":443"); //FIX FOR HANDSHAKE ERROR
1791 //FIX FOR HANDSHAKE ERROR
1792
1793 //worker
1794 worker.onmessage = function(event) { if(event.data.args) if(event.data.args.action==0) { gClient.sendArray([{m:"m", x:event.data.args.x, y:event.data.args.y}]); } }
1795 gClient.setChannel(channel_id);
1796 gClient.start();
1797
1798 // Setting status
1799 (function () {
1800 gClient.on("count", function (status) {
1801 $("#status").text(status);
1802 });
1803 gClient.on("count", function (count) {
1804 if (count > 0) {
1805 $("#status").html('<span class="number">' + count + '</span> ' + (count == 1 ? 'player' : 'players'));
1806 document.title = "Ryan's Bot [v" + botVersion + "] (" + count + ")";
1807 } else {
1808 document.title = "Logan's Bot [v" + botVersion + "]";
1809 }
1810 });
1811 })();
1812
1813 // Handle changes to participants
1814 (function () {
1815 gClient.on("participant added", function (part) {
1816
1817 part.displayX = 0.75; //150
1818 part.displayY = 25; //50
1819
1820 // add nameDiv
1821 var div = document.createElement("div");
1822 div.className = "name";
1823 div.participantId = part.id;
1824 div.textContent = part.name || selfName; // ""
1825 div.style.backgroundColor = part.color || "#777";
1826 if (gClient.participantId === part.id) {
1827 $(div).addClass("me");
1828 }
1829 if (gClient.channel && gClient.channel.crown && gClient.channel.crown.participantId === part.id) {
1830 $(div).addClass("owner");
1831 }
1832 if (gPianoMutes.indexOf(part._id) !== -1) {
1833 $(part.nameDiv).addClass("muted-notes");
1834 }
1835 if (gChatMutes.indexOf(part._id) !== -1) {
1836 $(part.nameDiv).addClass("muted-chat");
1837 }
1838 div.style.display = "none";
1839 part.nameDiv = $("#names")[0].appendChild(div);
1840 $(part.nameDiv).fadeIn(500); //2000
1841
1842 // sort names
1843 var arr = $("#names .name");
1844 arr.sort(function (a, b) {
1845 a = a.style.backgroundColor; // todo: sort based on user id instead
1846 b = b.style.backgroundColor;
1847 if (a > b) return 1;
1848 else if (a < b) return -1;
1849 else return 0;
1850 });
1851 $("#names").html(arr);
1852
1853 // add cursorDiv //gSeeOwnCursor
1854 if (gClient.participantId !== part.id || showOwnMouse) {
1855 var div = document.createElement("div");
1856 div.className = "cursor";
1857 div.style.display = "none";
1858 part.cursorDiv = $("#cursors")[0].appendChild(div);
1859 $(part.cursorDiv).fadeIn(500); //2000
1860
1861 //sets mouse position on join (thanks Josh)
1862 part.cursorDiv.style.left = 46.73 + "%";
1863 part.cursorDiv.style.top = 19.60 + "%";
1864
1865 var div = document.createElement("div");
1866 div.className = "name";
1867 div.style.backgroundColor = part.color || "#777"
1868 div.textContent = part.name || selfName; // ""
1869 part.cursorDiv.appendChild(div);
1870
1871 } else {
1872 part.cursorDiv = undefined;
1873 }
1874 });
1875 gClient.on("participant removed", function (part) { //when the participant leaves
1876 // remove nameDiv
1877 var nd = $(part.nameDiv);
1878 var cd = $(part.cursorDiv);
1879 cd.fadeOut(500); //2000
1880 nd.fadeOut(450, function () { //2000
1881 nd.remove();
1882 cd.remove();
1883 part.nameDiv = undefined;
1884 part.cursorDiv = undefined;
1885 });
1886 });
1887 gClient.on("participant update", function (part) {
1888 var name = part.name || "";
1889 var color = part.color || "#777";
1890 part.nameDiv.style.backgroundColor = color;
1891 part.nameDiv.textContent = name;
1892 $(part.cursorDiv)
1893 .find(".name")
1894 .text(name)
1895 .css("background-color", color);
1896 });
1897 gClient.on("ch", function (msg) {
1898 for (var id in gClient.ppl) {
1899 if (gClient.ppl.hasOwnProperty(id)) {
1900 var part = gClient.ppl[id];
1901 if (part.id === gClient.participantId) {
1902 $(part.nameDiv).addClass("me");
1903 } else {
1904 $(part.nameDiv).removeClass("me");
1905 }
1906 if (msg.ch.crown && msg.ch.crown.participantId === part.id) {
1907 $(part.nameDiv).addClass("owner");
1908 $(part.cursorDiv).addClass("owner");
1909 } else {
1910 $(part.nameDiv).removeClass("owner");
1911 $(part.cursorDiv).removeClass("owner");
1912 }
1913 if (gPianoMutes.indexOf(part._id) !== -1) {
1914 $(part.nameDiv).addClass("muted-notes");
1915 } else {
1916 $(part.nameDiv).removeClass("muted-notes");
1917 }
1918 if (gChatMutes.indexOf(part._id) !== -1) {
1919 $(part.nameDiv).addClass("muted-chat");
1920 } else {
1921 $(part.nameDiv).removeClass("muted-chat");
1922 }
1923 }
1924 }
1925 });
1926 })();
1927
1928
1929 // Handle changes to crown
1930 (function () {
1931 var jqcrown = $('<div id="crown"></div>').appendTo(document.body).hide();
1932 var jqcountdown = $('<span></span>').appendTo(jqcrown);
1933 var countdown_interval;
1934 jqcrown.click(function () {
1935 gClient.sendArray([{
1936 m: "chown",
1937 id: gClient.participantId
1938 }]);
1939 });
1940 gClient.on("ch", function (msg) {
1941 if (msg.ch.crown) {
1942 var crown = msg.ch.crown;
1943 if (!crown.participantId || !gClient.ppl[crown.participantId]) {
1944 var land_time = crown.time + 2000 - gClient.serverTimeOffset;
1945 var avail_time = crown.time + 15000 - gClient.serverTimeOffset;
1946 jqcountdown.text("");
1947 jqcrown.show();
1948 if (land_time - Date.now() <= 0) {
1949 jqcrown.css({
1950 "left": crown.endPos.x + "%",
1951 "top": crown.endPos.y + "%"
1952 });
1953 } else {
1954 jqcrown.css({
1955 "left": crown.startPos.x + "%",
1956 "top": crown.startPos.y + "%"
1957 });
1958 jqcrown.addClass("spin");
1959 jqcrown.animate({
1960 "left": crown.endPos.x + "%",
1961 "top": crown.endPos.y + "%"
1962 }, 2000, "linear", function () {
1963 jqcrown.removeClass("spin");
1964 });
1965 }
1966 clearInterval(countdown_interval);
1967 countdown_interval = setInterval(function () {
1968 var time = Date.now();
1969 if (time >= land_time) {
1970 var ms = avail_time - time;
1971 if (ms > 0) {
1972 jqcountdown.text(Math.ceil(ms / 1000) + "s");
1973 } else {
1974 jqcountdown.text("");
1975 clearInterval(countdown_interval);
1976 }
1977 }
1978 }, 1000);
1979 } else {
1980 jqcrown.hide();
1981 }
1982 } else {
1983 jqcrown.hide();
1984 }
1985 });
1986 gClient.on("disconnect", function () {
1987 jqcrown.fadeOut(2000);
1988 });
1989 })();
1990
1991
1992// Josh's playThing
1993 function playThing(notes, veloc, delay, times) {
1994 setTimeout(function() {
1995 gClient.sendArray([{
1996 m: "n",
1997 t: times,
1998 n: [{
1999 n: notes,
2000 v: veloc
2001 }]
2002 }]);
2003 }, delay);
2004 //console.log(notes);
2005 }
2006
2007
2008// Playing notes
2009 gClient.on("n", function(msg) {
2010 var t = msg.t - gClient.serverTimeOffset + TIMING_TARGET - Date.now();
2011 var participant = gClient.findParticipantById(msg.p);
2012 if (gPianoMutes.indexOf(participant._id) !== -1)
2013 return;
2014 for (var i = 0; i < msg.n.length; i++) {
2015 var note = msg.n[i];
2016 var octave = parseInt(note.n.replace( /[^\d.]/, '').replace('s', ''));
2017 if (octave > 7) {
2018 return;
2019 }
2020 var ms = t + (note.d || 0);
2021 if (ms < 0) {
2022 ms = 0;
2023 } else if (ms > 10000) continue;
2024 if (ignoreNotes) {
2025 if (participant.id == gClient.participantId) {
2026 if (note.s) {
2027 gPiano.stop(note.n, participant, ms);
2028 } else {
2029 var vel = (typeof note.v !== "undefined") ? parseFloat(note.v) : DEFAULT_VELOCITY;
2030 if (vel < 0) vel = 0;
2031 else if (vel > 1) vel = 1;
2032 gPiano.play(note.n, vel, participant, ms);
2033 }
2034 }
2035 } else {
2036 if (note.s) {
2037 gPiano.stop(note.n, participant, ms);
2038 } else {
2039 var vel = (typeof note.v !== "undefined") ? parseFloat(note.v) : DEFAULT_VELOCITY;
2040 if (vel < 0) vel = 0;
2041 else if (vel > 1) vel = 1;
2042 gPiano.play(note.n, vel, participant, ms);
2043 if (copyNotes){
2044 playThing(note.n,vel,note.d||0, t);
2045 }
2046 }
2047 }
2048 }
2049 });
2050
2051 // Send cursor updates
2052 // mouse optimizations by Alex
2053 var mx = 0, last_mx = -2.5, my = 0, last_my = -2.5;
2054 setInterval(function() {
2055 if (Math.abs(mx - last_mx) > 0.1 || Math.abs(my - last_my) > 0.1) {
2056 last_mx = mx;
2057 last_my = my;
2058 if (!incognito){
2059 gClient.sendArray([{m: "m", x: mx, y: my}]);
2060 }
2061 }
2062 }, 50);
2063
2064 $(document).mousemove(function(event) {
2065 mx = ((event.pageX / $(window).width()) * 100).toFixed(2);
2066 my = ((event.pageY / $(window).height()) * 100).toFixed(2);
2067 });
2068
2069 // Animate cursors
2070 setInterval(function() {
2071 for (var id in gClient.ppl) {
2072 if (!gClient.ppl.hasOwnProperty(id)) continue;
2073 var part = gClient.ppl[id];
2074 if (part.cursorDiv && (Math.abs(part.x - part.displayX) > 0.1 || Math.abs(part.y - part.displayY) > 0.1)) {
2075 part.displayX += (part.x - part.displayX) * 0.25;
2076 part.displayY += (part.y - part.displayY) * 0.25;
2077 part.cursorDiv.style.left = part.displayX + "%";
2078 part.cursorDiv.style.top = part.displayY + "%";
2079 if (autoFollow && part._id != selfId) {
2080 followId = part._id;
2081 }
2082 }
2083 }
2084 }, 1);
2085
2086 // Room settings button
2087 (function () {
2088 gClient.on("ch", function (msg) {
2089 if (gClient.isOwner()) {
2090 $("#room-settings-btn").show();
2091 $("#room-settings-btn").animate({opacity:0.7},100); //animates it thanks B@K$
2092 } else {
2093 $("#room-settings-btn").css("display","block"); //shows it
2094 $("#room-settings-btn").animate({opacity:0.3},100);
2095 }
2096 });
2097 $("#room-settings-btn").click(function (evt) { //room settings button
2098 if (gClient.channel && gClient.isOwner()) {
2099 var settings = gClient.channel.settings;
2100 openModal("#room-settings");
2101 setTimeout(function () {
2102 $("#room-settings .checkbox[name=visible]").prop("checked", settings.visible);
2103 $("#room-settings .checkbox[name=chat]").prop("checked", settings.chat);
2104 $("#room-settings .checkbox[name=crownsolo]").prop("checked", settings.crownsolo);
2105 }, 100);
2106 }
2107 });
2108 $("#room-settings .submit").click(function () {
2109 var settings = {
2110 visible: $("#room-settings .checkbox[name=visible]").is(":checked"),
2111 chat: $("#room-settings .checkbox[name=chat]").is(":checked"),
2112 crownsolo: $("#room-settings .checkbox[name=crownsolo]").is(":checked")
2113 };
2114 gClient.sendArray([{
2115 m: "chset",
2116 set: settings
2117 }]);
2118 closeModal();
2119 });
2120 $("#room-settings .drop-crown").click(function () {
2121 gClient.sendArray([{
2122 m: "chown"
2123 }]);
2124 closeModal();
2125 });
2126 })();
2127
2128 // Handle notifications
2129 gClient.on("notification", function (msg) {
2130 new Notification(msg);
2131 });
2132
2133 //cursor float
2134 /*gClient.on("ch", function (msg) {
2135 var chidlo = msg.ch._id.toLowerCase();
2136 if (chidlo === "a" || chidlo.substr() === "a") {
2137 $(".cursor").addClass("floating");
2138 } else {
2139
2140 $(".cursor").addClass("floating");
2141
2142 }
2143 });*/
2144
2145 // Don't forget spin
2146 /*gClient.on("ch", function (msg) {
2147 var chidlo = msg.ch._id.toLowerCase();
2148 if (chidlo === "spin" || chidlo.substr(-5) === "/spin") {
2149 $("#piano").addClass("spin");
2150 } else {
2151 $("#piano").removeClass("spin");
2152 }
2153 });*/
2154
2155 // Crownsolo notice
2156 gClient.on("ch", function (msg) {
2157 if (msg.ch.settings.crownsolo) {
2158 if ($("#crownsolo-notice").length == 0) {
2159 $('<div id="crownsolo-notice">').text('Only owner can play mode').appendTo("body").fadeIn(500);
2160 }
2161 } else {
2162 $("#crownsolo-notice").remove();
2163 }
2164 });
2165 gClient.on("disconnect", function () {
2166 $("#crownsolo-notice").remove();
2167 $("#nochat-notice").remove();
2168 });
2169
2170
2171
2172 var gPianoMutes = ["3ed152147e36d229cf5b7cba", "9b8df25492874a938ce9fb74"];
2173
2174 var gChatMutes = [];
2175
2176 //animated name stuff
2177 if (animName) {
2178 setInterval(function() {
2179 if (heyThereKitty == MPP.client.getOwnParticipant().name) return;
2180 updateName(heyThereKitty); //name to print
2181 if (followId == heyThereKittyId) return;
2182 followId = heyThereKittyId;
2183 }, 2100);
2184 }
2185
2186 // thanks Kappa
2187 /*
2188 var i = 0;
2189 setInterval(function() {
2190 MPP.client.sendArray([{
2191 m: "userset"
2192 , set: {
2193 name: selfName.slice(i % selfName.length) + selfName.slice(0, i++ % selfName.length)
2194 }
2195 }]);
2196 }, 2100)
2197 */
2198
2199 var volume_slider = new VolumeSlider(document.getElementById("volume"), function (v) {
2200 gPiano.audio.setVolume(v);
2201 if (window.localStorage) localStorage.volume = v;
2202 });
2203 volume_slider.set(gPiano.audio.volume);
2204
2205 var Note = function (note, octave) {
2206 this.note = note;
2207 this.octave = octave || 0;
2208 };
2209
2210
2211
2212 var n = function (a, b) {
2213 return {
2214 note: new Note(a, b),
2215 held: false
2216 };
2217 };
2218 //Logan, these are the key bindings for on the piano
2219 var key_binding = {
2220 65: n("gs"),
2221 90: n("a"),
2222 83: n("as"),
2223 88: n("b"),
2224 67: n("c", 1),
2225 70: n("cs", 1),
2226 86: n("d", 1),
2227 71: n("ds", 1),
2228 66: n("e", 1),
2229 78: n("f", 1),
2230 74: n("fs", 1),
2231 77: n("g", 1),
2232 75: n("gs", 1),
2233 188: n("a", 1),
2234 76: n("as", 1),
2235 190: n("b", 1),
2236 191: n("c", 2),
2237 222: n("cs", 2),
2238
2239 49: n("gs", 1),
2240 81: n("a", 1),
2241 50: n("as", 1),
2242 87: n("b", 1),
2243 69: n("c", 2),
2244 52: n("cs", 2),
2245 82: n("d", 2),
2246 53: n("ds", 2),
2247 84: n("e", 2),
2248 89: n("f", 2),
2249 55: n("fs", 2),
2250 85: n("g", 2),
2251 56: n("gs", 2),
2252 73: n("a", 2),
2253 57: n("as", 2),
2254 79: n("b", 2),
2255 80: n("c", 3),
2256 189: n("cs", 3),
2257 219: n("d", 3),
2258 187: n("ds", 3),
2259 221: n("e", 3)
2260 };
2261
2262 var capsLockKey = false; //here are some settings, Logan
2263 var gSustain = false;
2264 var keys = [];
2265 var volTemp = 1;
2266
2267 function handleKeyDown(evt) {
2268 var key = evt.keyCode;
2269 keys[key] = true;
2270
2271 // volume changing
2272 if (keys[107]) {
2273 volume > 0.9 ? volume = 1 : volume += 0.1;
2274 msgBox('Note Volume', 'Volume: ' + parseFloat(volume.toFixed(2)), 1000, '#piano');
2275
2276 } else if (keys[109]) {
2277 volume < 0.1 ? volume = 0 : volume -= 0.1;
2278 msgBox('Note Volume', 'Volume: ' + parseFloat(volume.toFixed(2)), 1000, '#piano');
2279 }
2280 // multi-octave toggling
2281 if (keys[38]) {
2282 octTemp > 6 ? octTemp = 7 : ++octTemp;
2283 msgBox('Multi-octave', 'Level ' + octTemp, 1000, '#piano');
2284
2285 } else if (keys[40]) {
2286 octTemp < 2 ? octTemp = 1 : --octTemp;
2287 msgBox('Multi-octave', 'Level ' + octTemp, 1000, '#piano');
2288 }
2289
2290 // roll toggling
2291 if (keys[35] && rollTemp) {
2292 rollTemp = false;
2293 msgBox('Roll', 'Disabled', 1000, '#piano');
2294
2295 } else if (keys[35] && !rollTemp) {
2296 rollTemp = true;
2297 msgBox('Roll', 'Enabled', 1000, '#piano');
2298 }
2299
2300 // sustain toggling
2301 //Insert key
2302 if (keys[45] && !susTemp) {
2303 msgBox('Sustain', 'Enabled', 1000, '#piano');
2304 susTemp = true;
2305
2306 } else if (keys[45] && susTemp) {
2307 msgBox('Sustain', 'Disabled', 1000, '#piano');
2308 susTemp = false;
2309 }
2310 if (!susTemp) {
2311 gAutoSustain = false;
2312 } else if (susTemp) {
2313 gAutoSustain = true;
2314 }
2315
2316 var code = parseInt(evt.keyCode); //move up and make use of more Logan
2317
2318 //numpad5
2319 if (code == 101 || code == 12) { //delay
2320 delPlay = !delPlay; //swaps it
2321 if (!delPlay) {
2322 msgBox('Delay', 'Disabled', 1000, '#piano');
2323 } else {
2324 msgBox('Delay', 'Enabled', 1000, '#piano');
2325 }
2326 //Pagedown
2327 } else if (code == 34) { //ignore
2328 ignoreNotes = !ignoreNotes;
2329 if (!ignoreNotes) {
2330 msgBox('Ignore Notes', 'Disabled', 1000, '#piano');
2331 } else {
2332 msgBox('Ignore Notes', 'Enabled', 1000, '#piano');
2333 }
2334 //Pageup
2335 } else if (code == 33) { //bot on/off [clean this logan]
2336 if (bot == 2) {
2337 bot = 0;
2338 msgBox('Commands', 'Disabled', 1000, '#piano');
2339 } else if (bot == 0) {
2340 bot = 1;
2341 msgBox('Commands', 'For everyone', 1000, '#piano');
2342 } else if (bot == 1) {
2343 bot = 2;
2344 msgBox('Commands', 'Only for you', 1000, '#piano');
2345 }
2346
2347 //numpad *
2348 } else if (code == 106) { //bot on/off //♥ REMOVE AND JUST MAKE NUMPAD - GO TO 0 ♥//
2349 if (timeStamp) {
2350 timeStamp = false;
2351 msgBox('Timestamps', 'Off', 1000, '#piano');
2352 } else {
2353 timeStamp = true;
2354 msgBox('Timestamps', 'On', 1000, '#piano');
2355 }
2356
2357 //numpad 0
2358 } else if (code == 96) { //reconnect
2359 MPP.client.stop();
2360 MPP.client.start();
2361 msgBox('Reconnecting...', '', 2000, '#piano');
2362
2363 //numpad 1
2364 } else if (code == 97) { //private room
2365 var room_name = randStr(28);
2366 changeRoom(room_name, "right", {
2367 "visible": false,
2368 "chat": true,
2369 "crownsolo": false,
2370 "lobby": false
2371 });
2372 //numpad 2
2373 } else if (code == 98) { //illuminati hotkey (until I find a better use)
2374 if (autoFollow) {
2375 autoFollow = false;
2376 following = false;
2377 followId = null;
2378 msgBox('Auto Follow', 'Off', 2000, '#blah-btn');
2379 } else {
2380 autoFollow = true;
2381 following = true;
2382 msgBox('Auto Follow', 'On', 2000, '#blah-btn');
2383 }
2384 //tab
2385 } else if (code == 9) { //hotkeymsg
2386 tab(); //ring ring..
2387
2388 //ctrl
2389 } else if (code == 17) { //drop crown
2390 gClient.sendArray([{
2391 m: "chown"
2392 }]);
2393 msgBox('Dropping crown', '', 1000, '#piano');
2394
2395 //alt
2396 } else if (code == 18) { //pickup crown
2397 gClient.sendArray([{
2398 m: "chown",
2399 id: gClient.participantId
2400 }]);
2401 msgBox('Picking up crown', '', 1000, '#piano');
2402
2403 //H
2404 } else if (code == 72) { //display help
2405 new Notification({id: "volume", title: "Hotkeys (thanks B@K$ for the design)", html: '\
2406 <h3>๖ۣۜHold to display binds and hotkeys...</h3>\
2407 <font color="#FF0066">Page Up:</font>Turns on/off chat commands (excluding !js and !room)<br />\
2408 <font color="#FF0066">Page Down</font> Ignores everyone elses notes<br />\
2409 <font color="#FF0066">End</font> Toggles rolling on multi-octaves<br />\
2410 <font color="#FF0066">Up/Down Arrows</font> Turns sets number of multi-octave<br />\
2411 <font color="#FF0066">Left/Right Arrows</font> electrashave\'s note transposing<br />\
2412 <font color="#FF0066">Insert</font> Toggles sustain (default was backspace)<br />\
2413 <font color="#FF0066">Backspace</font> Alerts you if someone in the friends list array joins<br />\
2414 <font color="#FF0066">Delete</font> Toggles an alert sound and notifcation if "Logan" is said<br />\
2415 <font color="#FF0066">Home *new</font> Toggles Polite Play Mode<br />\
2416 <font color="#FF0066">\\</font> Speech to text for Chrome (click accept then speak)<br />\
2417 <font color="#FF0066">Spacebar</font> Plays low notes while held<br />\
2418 <font color="#FF0066">~</font> Plays high notes while held<br />\
2419 <font color="#FF0066">Tab</font> Sends hotkey message<br />\
2420 <font color="#FF0066">3</font> Toggles owner only mode (need crown)<br />\
2421 <font color="#FF0066">6</font> Toggles room visibility (need crown)<br />\
2422 <font color="#FF0066">Numpad + -</font> Change note volume<br />\
2423 <font color="#FF0066">Numpad *</font> Toggles timestamps in chat<br />\
2424 <font color="#FF0066">Numpad .</font> Meow meow meow<br />\
2425 <font color="#FF0066">Numpad 0</font> Quick reconnect<br />\
2426 <font color="#FF0066">Numpad 1</font> Play Alone<br />\
2427 <font color="#FF0066">Numpad 2</font> Auto Follow<br />\
2428 <font color="#FF0066">Numpad 3</font> Greeting<br />\
2429 <font color="#FF0066">Numpad 4</font> Toggle Bunny<br />\
2430 <font color="#FF0066">Numpad 5</font> Toggles delay<br />\
2431 <font color="#FF0066">Numpad 6</font> Toggles Pong<br />\
2432 <font color="#FF0066">Numpad 7</font> Toggles text to speech<br />\
2433 <font color="#FF0066">Numpad 8</font> Toggles SomeGuy\'s incognito<br />\
2434 <font color="#FF0066">Alt</font> Picks up the crown<br />\
2435 <font color="#FF0066">Ctrl</font> Drops the crown<br />\
2436 <font color="#FF0066">H</font> Displays displays Hotkeys again<br />\
2437 <font color="#FF3399">!lhelp</font> Displays local commands in chat<br />\
2438 To stop this message displaying every time you start the script search for <font color="#FF0066">i_know_how_to_use_this_bot</font> and change <font color="#CC0000">false</font> to <font color="#0066FF">true</font>.<br />\
2439 ', target: "#blah-btn", duration: 600});
2440
2441//--TEST--TEST--TEST////--TEST--TEST--TEST////--TEST--TEST--TEST//
2442 //numpad .
2443 } else if (code == 110) { //hotkey test
2444 if (meow) {
2445 meow = false;
2446 msgBox('Cat Mode', 'Off', 1000, '#blah-btn');
2447 } else {
2448 meow = true;
2449 msgBox('Cat Mode', 'On', 1000, '#blah-btn');
2450 }
2451
2452
2453//--TEST--TEST--TEST////--TEST--TEST--TEST////--TEST--TEST--TEST//
2454
2455
2456 // ♥ Thanks Josh ♥ //
2457 // \ key
2458 } else if (code == 220) { //Yoshify's speech to text
2459 if (listening) {
2460 listening = false;
2461 Voice.stop();
2462 msgBox('Speech to Text', 'Stopping Capture', 3000, '#blah-btn');
2463 } else {
2464 listening = true;
2465 Voice.start();
2466 msgBox('Speech to Text', 'Listening (press again to send)', 3000, '#blah-btn');
2467 }
2468
2469 //numpad 7
2470 } else if (code == 103) { //speech toggle
2471 if (speechStatus) {
2472 speechStatus = false;
2473 speechSynthesis.cancel();
2474 msgBox('Text to Speech', 'Off', 1000, '#blah-btn');
2475 } else {
2476 speechStatus = true;
2477 msgBox('Text to Speech', 'On', 1000, '#blah-btn');
2478 }
2479 //del
2480 } else if (code == 46) { //alert on name said in chat toggle
2481 if (alertName) {
2482 alertName = false;
2483 msgBox('Alert on key-word', 'Off', 1000, '#blah-btn');
2484 } else {
2485 alertName = true;
2486 msgBox('Alert on key-word', 'On', 1000, '#blah-btn');
2487 }
2488 //home
2489 } else if (code == 36) { //politePlay
2490 if (politePlay) {
2491 politePlay = false;
2492 msgBox('Polite Play', 'Off', 1000, '#blah-btn');
2493 } else {
2494 politePlay = true;
2495 msgBox('Polite Play', 'On (others cannot hear your notes)', 1000, '#blah-btn');
2496 }
2497
2498 //backspace
2499 } else if (code == 8) { //alert on friends join toggle
2500 if (alertOnFriendJoin) {
2501 alertOnFriendJoin = false;
2502 msgBox('Alert on Friend Join', 'Off', 1000, '#blah-btn');
2503 } else {
2504 alertOnFriendJoin = true;
2505 msgBox('Alert on Friend Join', 'On', 1000, '#blah-btn');
2506 }
2507 // 3 key
2508 } else if (code == 51) { //owner only
2509 if (crownSoloToggle) {
2510 crownSoloToggle = false;
2511 MPP.client.sendArray([{m: "chset", set: {crownsolo: false}}]);
2512 msgBox('Owner Only', 'Off', 1000, '#blah-btn');
2513 } else {
2514 crownSoloToggle = true;
2515 MPP.client.sendArray([{m: "chset", set: {crownsolo: true}}]);
2516 msgBox('Owner Only', 'On', 1000, '#blah-btn');
2517 }
2518 // 6 key
2519 } else if (code == 54) { //hide room
2520 if (roomVisibleToggle) {
2521 roomVisibleToggle = false;
2522 MPP.client.sendArray([{m: "chset", set: {visible: false}}]);
2523 msgBox('Room Visible', 'No', 1000, '#blah-btn');
2524 } else {
2525 roomVisibleToggle = true;
2526 MPP.client.sendArray([{m: "chset", set: {visible: true}}]);
2527 msgBox('Room Visible', 'Yes', 1000, '#blah-btn');
2528 }
2529
2530
2531 } else if (code == 104) { //mouse updates
2532 if (incognito) {
2533 incognito = false;
2534 msgBox('Incognito', 'Off', 1000, '#blah-btn');
2535 } else {
2536 incognito = true;
2537 msgBox('Incognito', 'On', 1000, '#blah-btn');
2538 }
2539
2540 } else if (code == 105) { //copy notes
2541 if (copyNotes) {
2542 copyNotes = false;
2543 msgBox('Copy Notes', 'Off', 1000, '#blah-btn');
2544 } else {
2545 copyNotes = true;
2546 msgBox('Copy Notes', 'On', 1000, '#blah-btn');
2547 }
2548
2549 } else if (code == 100) { //cursor bunny
2550 testflipB = !testflipB;
2551 if (!testflipB) {
2552 msgBox('Bunny', 'Off', 1000, '#blah-btn');
2553 } else {
2554 setTimeout(function () {
2555 client = MPP.client;
2556 var bunny = new Bunny(client);
2557 worker.onmessage = function(event)
2558 {
2559 if(event.data.args)
2560 if(event.data.args.action==0){
2561 if(testflipB){ bunny.tick(); }
2562 }
2563 }
2564 worker.postMessage({delay:120,args:{action:0}});
2565 }, 120);
2566
2567
2568 var Bunny = function (client) {
2569 this.client = client;
2570
2571 this.vx = 1.5;
2572 this.vy = 2.2;
2573
2574 var self = this;
2575 self.part = self.client.ppl[self.client.participantId];
2576 client.on("ch", function () {
2577 self.part = self.client.ppl[self.client.participantId];
2578 });
2579 }
2580
2581 Bunny.prototype.tick = function () {
2582 if (!this.client.isConnected() || !this.part) return;
2583 this.part.x += this.vx;
2584 this.part.y += this.vy;
2585 if (this.part.x < 0) {
2586 this.vx = -this.vx;
2587 } else if (this.part.x > 100) {
2588 this.vx = -this.vx;
2589 }
2590 if (this.part.y < 0) {
2591 this.vy = -this.vy;
2592 } else if (this.part.y > 0) { //0 makes the ceiling which it bounces off
2593 this.vy = -this.vy;
2594 }
2595 this.client.sendArray([{
2596 m: "m",
2597 x: this.part.x,
2598 y: this.part.y
2599 }]);
2600 this.client.sendArray([{
2601 m: "m",
2602 x: this.part.x,
2603 y: this.part.y
2604 }]);
2605 worker.postMessage({delay:120,args:{action:0}});
2606 };
2607 msgBox('Bunny', 'On', 1000, '#blah-btn');
2608 }
2609
2610 //msgBox('Pong', 'Off', 1000, '#blah-btn');
2611
2612 } else if (code == 102) { //cursor pong
2613 testflipP = !testflipP;
2614 if (!testflipP) {
2615 msgBox('Pong', 'Off', 1000, '#blah-btn');
2616
2617 } else {
2618 //on
2619 setTimeout(function() {
2620 client = MPP.client;
2621 var pong = new Pong(client);
2622 worker.onmessage = function(event) {
2623 if (event.data.args)
2624 if (event.data.args.action == 0) {
2625 if (testflipP) {
2626 pong.tick();
2627 }
2628 }
2629 }
2630 worker.postMessage({
2631 delay: 60
2632 , args: {
2633 action: 0
2634 }
2635 });
2636 }, 60);
2637
2638
2639 var Pong = function(client) {
2640 this.client = client;
2641
2642 this.vx = 0.1875; //0.75
2643 this.vy = 0.275; //1.1
2644
2645 var self = this;
2646 self.part = self.client.ppl[self.client.participantId];
2647 client.on("ch", function() {
2648 self.part = self.client.ppl[self.client.participantId];
2649 });
2650 }
2651
2652 Pong.prototype.tick = function() {
2653 if (!this.client.isConnected() || !this.part) return;
2654 this.part.x += this.vx;
2655 this.part.y += this.vy;
2656 if (this.part.x < 0) {
2657 this.vx = -this.vx;
2658 } else if (this.part.x > 100) {
2659 this.vx = -this.vx;
2660 }
2661 if (this.part.y < 0) {
2662 this.vy = -this.vy;
2663 } else if (this.part.y > 100) {
2664 this.vy = -this.vy;
2665 }
2666
2667 //x is <--> 100 is --> 0 is <--
2668 //y is ^v 0 is ^ 100 is v
2669
2670 this.vx += Math.random() * 0.1 - 0.05;
2671 this.vy += Math.random() * 0.1 - 0.05;
2672 this.client.sendArray([{ //were two of these
2673 m: "m"
2674 , x: this.part.x
2675 , y: this.part.y
2676 }]);
2677 if (this.part.x < -10 || this.part.y < -10 || this.part.x > 110 || this.part.y > 110) {
2678 this.part.x = 50;
2679 this.part.y = 50;
2680 //resets the velocity when setting position
2681 this.vx = -this.vx;
2682 this.vy = -this.vy;
2683 }
2684 worker.postMessage({
2685 delay: 60
2686 , args: {
2687 action: 0
2688 }
2689 });
2690 };
2691 msgBox('Pong', 'On', 1000, '#blah-btn');
2692 }
2693
2694 } else if (code == 99) { //lenny
2695 var msgTmp = $("input").val(); //retain old text
2696 $("body #chat input").val(msgTmp + " Hello everyone! Type in (!help) to get my commands! Remember to stay cool ( ͡◕ ͜ʖ ͡◕)");
2697
2698 //numpad /
2699 } else if (code == 111) { //hotkey spam
2700 for(var key in MPP.piano.keys) MPP.press(key, volume);
2701
2702 //thanks electrashave!
2703 } else if (code == 39) {
2704 transLvl++;
2705 msgBox('Transposing (by electrashave)', 'Transpose level: ' + transLvl, 1000, '#blah-btn');
2706
2707 //thanks electrashave!
2708 } else if (code == 37) {
2709 transLvl--;
2710 msgBox('Transposing (by electrashave)', 'Transpose level: ' + transLvl, 1000, '#blah-btn');
2711 }
2712
2713 if (key_binding[code] !== undefined) {
2714 var binding = key_binding[code];
2715 if (!binding.held) {
2716 binding.held = true;
2717 if (gNoteQuota.spend(0)) {
2718 var note = binding.note;
2719 var octave = 1 + note.octave;
2720 // extra octaves
2721 if (keys[16])++octave;
2722 else if (keys[32])--octave == --octave + -octave;
2723 else if (keys[18])++octave == ++octave + +octave;
2724 else if (keys[192])++octave == ++octave + ++octave;
2725 else if (capsLockKey)--octave;
2726 var note = note.note;
2727 var vol = volume;
2728
2729 if (volume > 5) {
2730 volume = 5;
2731 }
2732 press(note + octave, vol);
2733 }
2734 }
2735
2736 if (++gKeyboardSeq == 3) {
2737 gKnowsYouCanUseKeyboard = true;
2738 if (window.gKnowsYouCanUseKeyboardTimeout) clearTimeout(gKnowsYouCanUseKeyboardTimeout);
2739 if (localStorage) localStorage.knowsYouCanUseKeyboard = true;
2740 if (window.gKnowsYouCanUseKeyboardNotification) gKnowsYouCanUseKeyboardNotification.close();
2741 }
2742
2743 evt.preventDefault();
2744 evt.stopPropagation();
2745 return false;
2746 } else if (code == 20) { // Caps Lock
2747 capsLockKey = true;
2748 evt.preventDefault();
2749 } else if (code === 0x20) { // Space Bar
2750 evt.preventDefault();
2751 } else if (code == 9) { // Tab (don't tab away from the piano)
2752 evt.preventDefault();
2753 } else if (code == 8) { // Backspace (don't navigate Back)
2754 evt.preventDefault();
2755 }
2756 };
2757
2758 //FIX BELOW MESS
2759
2760 var keys = [];
2761
2762 function handleKeyUp(evt) {
2763 var key = evt.keyCode;
2764 keys[key] = false;
2765 var code = parseInt(evt.keyCode);
2766 if (key_binding[code] !== undefined) {
2767 var binding = key_binding[code];
2768 if (binding.held) {
2769 keys[key] = false;
2770 binding.held = false;
2771
2772 if (!gAutoSustain && !gSustain) {
2773 if (gNoteQuota.spend(octTemp)) {
2774 var note = binding.note;
2775 var octave = 1 + note.octave;
2776 // extra octaves
2777 if (keys[16])++octave;
2778 else if (keys[32])--octave == --octave + -octave;
2779 else if (keys[18])++octave == ++octave + +octave;
2780 else if (keys[192])++octave == ++octave + ++octave;
2781 else if (capsLockKey)--octave;
2782 var note = note.note;
2783 release(note + octave); //was missing octave which didn't stop the note - Logan
2784 }
2785 }
2786 }
2787
2788 evt.preventDefault();
2789 evt.stopPropagation();
2790 return false;
2791 } else if (code == 20) { // Caps Lock
2792 capsLockKey = false;
2793 evt.preventDefault();
2794 } else if (code === 0x20) { // Space Bar
2795 evt.preventDefault();
2796 } else if (code == 8) { // Backspace (don't navigate Back)
2797 evt.preventDefault();
2798 }
2799 };
2800
2801 function handleKeyPress(evt) {
2802 evt.preventDefault();
2803 evt.stopPropagation();
2804 if (evt.keyCode == 27 || evt.keyCode == 13) {
2805 //add some stuff here Logan
2806 }
2807 return false;
2808 };
2809
2810 var recapListener = function (evt) {
2811 captureKeyboard();
2812 };
2813
2814 function captureKeyboard() {
2815 $("#piano").off("mousedown", recapListener);
2816 $("#piano").off("touchstart", recapListener);
2817 $(document).on("keydown", handleKeyDown);
2818 $(document).on("keyup", handleKeyUp);
2819 $(window).on("keypress", handleKeyPress);
2820 };
2821
2822 function releaseKeyboard() {
2823 $(document).off("keydown", handleKeyDown);
2824 $(document).off("keyup", handleKeyUp);
2825 $(window).off("keypress", handleKeyPress);
2826 $("#piano").on("mousedown", recapListener);
2827 $("#piano").on("touchstart", recapListener);
2828 };
2829
2830 captureKeyboard();
2831
2832
2833 var velocityFromMouseY = function () {
2834 return 0.1 + (my / 100) * 0.6;
2835 };
2836
2837
2838
2839
2840 // NoteQuota
2841 var gNoteQuota = (function () {
2842 var last_rat = 0;
2843 var nqjq = $("#quota .value");
2844 setInterval(function () {
2845 gNoteQuota.tick();
2846 }, 2000);
2847 return new NoteQuota(function (points) {
2848 // update UI
2849 var rat = (points / this.max) * 100; // 100
2850 if (rat <= last_rat)
2851 nqjq.stop(true, true).css("width", rat.toFixed(0) + "%");
2852 else
2853 nqjq.stop(true, true).animate({
2854 "width": rat.toFixed(0) + "%"
2855 }, 2000, "linear");
2856 last_rat = rat;
2857 });
2858 })();
2859 gClient.on("nq", function (nq_params) {
2860 gNoteQuota.setParams(nq_params);
2861 });
2862 gClient.on("disconnect", function () {
2863 gNoteQuota.setParams(NoteQuota.PARAMS_OFFLINE);
2864 });
2865
2866
2867
2868 // click participant names
2869 (function () {
2870 var ele = document.getElementById("names");
2871 var touchhandler = function (e) {
2872 var target_jq = $(e.target);
2873 if (target_jq.hasClass("name")) {
2874 target_jq.addClass("play");
2875 if (e.target.participantId == gClient.participantId) {
2876 var id = e.target.participantId;
2877 var part = gClient.ppl[id] || null;
2878 if (part) {
2879 participantMenu(part);
2880 e.stopPropagation();
2881 }
2882 } else if (e.target.participantId) {
2883 var id = e.target.participantId;
2884 var part = gClient.ppl[id] || null;
2885 if (part) {
2886 participantMenu(part);
2887 e.stopPropagation();
2888 }
2889 }
2890 }
2891 };
2892 ele.addEventListener("mousedown", touchhandler);
2893 ele.addEventListener("touchstart", touchhandler);
2894 var releasehandler = function (e) {
2895 $("#names .name").removeClass("play");
2896 };
2897 document.body.addEventListener("mouseup", releasehandler);
2898 document.body.addEventListener("touchend", releasehandler);
2899
2900 var removeParticipantMenus = function () {
2901 $(".participant-menu").fadeOut(500);
2902 $(".participantSpotlight").hide(); //what is this?
2903 document.removeEventListener("mousedown", removeParticipantMenus);
2904 document.removeEventListener("touchstart", removeParticipantMenus);
2905 };
2906
2907 var participantMenu = function (part) {
2908 if (!part) return;
2909 removeParticipantMenus();
2910 document.addEventListener("mousedown", removeParticipantMenus);
2911 document.addEventListener("touchstart", removeParticipantMenus);
2912 $("#" + part.id).find(".enemySpotlight").show(); //what is this D:
2913 var menu = $('<div class="participant-menu"></div>');
2914 $("body").append(menu);
2915 // move menu to name position
2916 var jq_nd = $(part.nameDiv);
2917 var pos = jq_nd.position();
2918 menu.css({
2919 "top": pos.top + jq_nd.height() + 15,
2920 "left": pos.left + 6,
2921 "background": part.color || "black"
2922 });
2923 menu.on("mousedown touchstart", function (evt) {
2924 evt.stopPropagation();
2925 var target = $(evt.target);
2926 if (target.hasClass("menu-item")) {
2927 target.addClass("clicked"); //why is this needed?
2928 menu.fadeOut(500, function () {
2929 removeParticipantMenus();
2930 });
2931 }
2932 });
2933 // this spaces stuff out but also can be used for informational purposes
2934 $('<div class="info"></div>').appendTo(menu).text(part._id)
2935 .on("mousedown touchstart", function (evt) {
2936 //prompt("Press CTRL C to copy "+ part.name +"'s ID", part._id);
2937 prompt(part.name.endsWith("s") ? "Press CTRL C to copy "+ part.name +"' ID" : "Press CTRL C to copy "+ part.name +"'s ID", part._id);
2938 });
2939
2940 // added menu items
2941
2942 // rename
2943 if (part._id == gClient.getOwnParticipant()._id) {
2944 $('<div class="menu-item">• Rename</div>').appendTo(menu)
2945 .on("mousedown touchstart", function (evt) {
2946 openModal("#rename", "input[name=name]");
2947 setTimeout(function () {
2948 $("#rename input[name=name]").val(gClient.ppl[gClient.participantId].name);
2949 $("#rename input[name=color]").val(gClient.ppl[gClient.participantId].color);
2950 }, 100);
2951 });
2952 }
2953
2954
2955 // master and unmaster
2956 if (masters.indexOf(part._id) == -1) {
2957 $('<div class="menu-item">• Master</div>').appendTo(menu)
2958 .on("mousedown touchstart", function (evt) {
2959 masters.push(part._id);
2960 gClient.sendArray([{ m: "a", message: "Mastered " + part.name + "."}])
2961 });
2962 } else {
2963 $('<div class="menu-item">• Unmaster</div>').appendTo(menu)
2964 .on("mousedown touchstart", function (evt) {
2965 delete masters[masters.indexOf(part._id)];
2966 gClient.sendArray([{ m: "a", message: "Unmastered " + part.name + "."}])
2967 });
2968 }
2969
2970
2971 // op and deop
2972 if (ops.indexOf(part._id) == -1) {
2973 $('<div class="menu-item">• Op</div>').appendTo(menu)
2974 .on("mousedown touchstart", function (evt) {
2975 ops.push(part._id);
2976 gClient.sendArray([{ m: "a", message: "Opped " + part.name + "."}])
2977 });
2978 } else {
2979 $('<div class="menu-item">• Deop</div>').appendTo(menu)
2980 .on("mousedown touchstart", function (evt) {
2981 delete ops[ops.indexOf(part._id)];
2982 gClient.sendArray([{ m: "a", message: "deopped " + part.name + "."}])
2983 });
2984 }
2985
2986 if (part._id != gClient.getOwnParticipant()._id) {
2987
2988 // follow and rest
2989 if (!followId) {
2990 $('<div class="menu-item">• Follow >.<</div>').appendTo(menu)
2991 .on("mousedown touchstart", function (evt) {
2992 following = true;
2993 followId = part._id;
2994
2995 msgBox('Following', part.name, 2000, '#piano');
2996 });
2997 } else {
2998 $('<div class="menu-item">• Rest <.></div>').appendTo(menu)
2999 .on("mousedown touchstart", function (evt) {
3000 following = false;
3001 followId = null;
3002 msgBox('Stopping', 'Ok...', 2000, '#piano');
3003 });
3004 }
3005
3006 if (gPianoMutes.indexOf(part._id) == -1) {
3007 $('<div class="menu-item">• Mute Notes</div>').appendTo(menu)
3008 .on("mousedown touchstart", function (evt) {
3009 gPianoMutes.push(part._id);
3010 $(part.nameDiv).addClass("muted-notes");
3011 });
3012 } else {
3013 $('<div class="menu-item">• Unmute Notes</div>').appendTo(menu)
3014 .on("mousedown touchstart", function (evt) {
3015 var i;
3016 while ((i = gPianoMutes.indexOf(part._id)) != -1)
3017 gPianoMutes.splice(i, 1);
3018 $(part.nameDiv).removeClass("muted-notes");
3019 });
3020 }
3021 if (gChatMutes.indexOf(part._id) == -1) {
3022 $('<div class="menu-item">• Mute Chat</div>').appendTo(menu)
3023 .on("mousedown touchstart", function (evt) {
3024 gChatMutes.push(part._id);
3025 $(part.nameDiv).addClass("muted-chat");
3026 });
3027 } else {
3028 $('<div class="menu-item">• Unmute Chat</div>').appendTo(menu)
3029 .on("mousedown touchstart", function (evt) {
3030 var i;
3031 while ((i = gChatMutes.indexOf(part._id)) != -1)
3032 gChatMutes.splice(i, 1);
3033 $(part.nameDiv).removeClass("muted-chat");
3034 });
3035 }
3036 if (!(gPianoMutes.indexOf(part._id) >= 0) || !(gChatMutes.indexOf(part._id) >= 0)) {
3037 $('<div class="menu-item">• Mute Completely</div>').appendTo(menu)
3038 .on("mousedown touchstart", function (evt) {
3039 gPianoMutes.push(part._id);
3040 gChatMutes.push(part._id);
3041 $(part.nameDiv).addClass("muted-notes");
3042 $(part.nameDiv).addClass("muted-chat");
3043 });
3044 }
3045 if ((gPianoMutes.indexOf(part._id) >= 0) || (gChatMutes.indexOf(part._id) >= 0)) {
3046 $('<div class="menu-item">• Unmute Completely</div>').appendTo(menu)
3047 .on("mousedown touchstart", function (evt) {
3048 var i;
3049 while ((i = gPianoMutes.indexOf(part._id)) != -1)
3050 gPianoMutes.splice(i, 1);
3051 while ((i = gChatMutes.indexOf(part._id)) != -1)
3052 gChatMutes.splice(i, 1);
3053 $(part.nameDiv).removeClass("muted-notes");
3054 $(part.nameDiv).removeClass("muted-chat");
3055 });
3056 }
3057
3058 // ban and unban
3059 if (banned.indexOf(part._id) == -1) {
3060 $('<div class="menu-item">• Ban</div>').appendTo(menu)
3061 .on("mousedown touchstart", function (evt) {
3062 banned.push(part._id);
3063 msgBox('Banned', part.name, 1000, '#piano');
3064 });
3065 } else {
3066 $('<div class="menu-item">• Unban</div>').appendTo(menu)
3067 .on("mousedown touchstart", function (evt) {
3068 delete banned[banned.indexOf(part._id)];
3069 msgBox('Unbanned', part.name, 1000, '#piano');
3070 });
3071 }
3072
3073 if (gClient.isOwner()) {
3074 $('<div class="menu-item give-crown">• Give Crown</div>').appendTo(menu)
3075 .on("mousedown touchstart", function (evt) {
3076 gClient.sendArray([{
3077 m: "chown",
3078 id: part.id
3079 }]);
3080 });
3081 }
3082 }
3083 menu.fadeIn(500);
3084 };
3085 })();
3086
3087
3088
3089
3090// Notification class
3091
3092////////////////////////////////////////////////////////////////
3093
3094 var Notification = function(par) {
3095 EventEmitter.call(this);
3096
3097 var par = par || {};
3098
3099 this.id = "Notification-" + (par.id || Math.random());
3100 this.title = par.title || "";
3101 this.text = par.text || "";
3102 this.html = par.html || "";
3103 this.target = $(par.target || "#piano");
3104 this.duration = par.duration || 30000;
3105 this["class"] = par["class"] || "classic";
3106
3107 var self = this;
3108 var eles = $("#" + this.id);
3109 if(eles.length > 0) {
3110 eles.remove();
3111 }
3112 this.domElement = $('<div class="notification"><div class="notification-body"><div class="title"></div>' +
3113 '<div class="text"></div></div><div class="x">x</div></div>');
3114 this.domElement[0].id = this.id;
3115 this.domElement.addClass(this["class"]);
3116 this.domElement.find(".title").text(this.title);
3117 if(this.text.length > 0) {
3118 this.domElement.find(".text").text(this.text);
3119 } else if(this.html instanceof HTMLElement) {
3120 this.domElement.find(".text")[0].appendChild(this.html);
3121 } else if(this.html.length > 0) {
3122 this.domElement.find(".text").html(this.html);
3123 }
3124 document.body.appendChild(this.domElement.get(0));
3125
3126 this.position();
3127 this.onresize = function() {
3128 self.position();
3129 };
3130 window.addEventListener("resize", this.onresize);
3131
3132 this.domElement.find(".x").click(function() {
3133 self.close();
3134 });
3135
3136 if(this.duration > 0) {
3137 setTimeout(function() {
3138 self.close();
3139 }, this.duration);
3140 }
3141
3142 return this;
3143 }
3144
3145 mixin(Notification.prototype, EventEmitter.prototype);
3146 Notification.prototype.constructor = Notification;
3147
3148 Notification.prototype.position = function() {
3149 var pos = this.target.offset();
3150 var x = pos.left - (this.domElement.width() / 2) + (this.target.width() / 4);
3151 var y = pos.top - this.domElement.height() - 8;
3152 var width = this.domElement.width();
3153 if(x + width > $("body").width()) {
3154 x -= ((x + width) - $("body").width());
3155 }
3156 if(x < 0) x = 0;
3157 this.domElement.offset({left: x, top: y});
3158 };
3159
3160 Notification.prototype.close = function() {
3161 var self = this;
3162 window.removeEventListener("resize", this.onresize);
3163 this.domElement.fadeOut(500, function() {
3164 self.domElement.remove();
3165 self.emit("close");
3166 });
3167 };
3168
3169
3170
3171
3172 // set variables from settings or set settings
3173
3174 ////////////////////////////////////////////////////////////////
3175
3176 if(!i_know_how_to_use_this_bot) {
3177
3178 new Notification({id: "volume", title: "Hotkeys (thanks B@K$ for the design)", html: '\
3179 <h3>๖ۣۜHold to display binds and hotkeys...</h3>\
3180 <font color="#FF0066">Page Up:</font>Turns on/off chat commands (excluding !js and !room)<br />\
3181 <font color="#FF0066">Page Down</font> Ignores everyone elses notes<br />\
3182 <font color="#FF0066">End</font> Toggles rolling on multi-octaves<br />\
3183 <font color="#FF0066">Up Arrow</font> Turns on / increases multi-octave<br />\
3184 <font color="#FF0066">Down Arrow:</font> Turns on / increases multi-octave<br />\
3185 <font color="#FF0066">Insert</font> Toggles sustain (default was backspace)<br />\
3186 <font color="#FF0066">Backspace</font> Alerts you if someone in the friends list array joins<br />\
3187 <font color="#FF0066">Delete</font> Toggles an alert sound and notifcation if "Logan" is said<br />\
3188 <font color="#FF0066">Home *new</font> Toggles Polite Play Mode<br />\
3189 <font color="#FF0066">\\</font> Speech to text for Chrome (click accept then speak)<br />\
3190 <font color="#FF0066">Spacebar</font> Plays low notes while held<br />\
3191 <font color="#FF0066">~</font> Plays high notes while held<br />\
3192 <font color="#FF0066">Tab</font> Sends hotkey message<br />\
3193 <font color="#FF0066">3</font> Toggles owner only mode (need crown)<br />\
3194 <font color="#FF0066">6</font> Toggles room visibility (need crown)<br />\
3195 <font color="#FF0066">Numpad + -</font> Change note volume<br />\
3196 <font color="#FF0066">Numpad *</font> Toggles timestamps in chat<br />\
3197 <font color="#FF0066">Numpad .</font> Meow meow meow<br />\
3198 <font color="#FF0066">Numpad 0</font> Quick reconnect<br />\
3199 <font color="#FF0066">Numpad 1</font> Play Alone<br />\
3200 <font color="#FF0066">Numpad 2</font> Auto Follow<br />\
3201 <font color="#FF0066">Numpad 3</font> Greeting<br />\
3202 <font color="#FF0066">Numpad 4</font> Toggle Bunny<br />\
3203 <font color="#FF0066">Numpad 5</font> Toggles delay<br />\
3204 <font color="#FF0066">Numpad 6</font> Toggles Pong<br />\
3205 <font color="#FF0066">Numpad 7</font> Toggles text to speech<br />\
3206 <font color="#FF0066">Numpad 8</font> Toggles SomeGuy\'s incognito<br />\
3207 <font color="#FF0066">Alt</font> Picks up the crown<br />\
3208 <font color="#FF0066">Ctrl</font> Drops the crown<br />\
3209 <font color="#FF0066">H</font> Displays displays Hotkeys again<br />\
3210 <font color="#FF3399">!lhelp</font> Displays local commands in chat<br />\
3211 To stop these messages displaying every time you start the script search for <font color="#FF0066">i_know_how_to_use_this_bot</font> and change <font color="#CC0000">false</font> to <font color="#0066FF">true</font>.<br />\
3212 ', target: "#blah-btn", duration: 0});
3213
3214 setTimeout(function() { //I think wrapping this in setTimeout hoists it so it wait for the buttons to be placed
3215 msgBox('Chat log is saved between rooms', 'To clear click Msgs button (i know it\'s on wrong button >.<)', 0, '#4-btn');
3216 }, 0);
3217
3218 }
3219
3220 var gKeyboardSeq = 0;
3221 var gKnowsYouCanUseKeyboard = false;
3222 if (localStorage && localStorage.knowsYouCanUseKeyboard) gKnowsYouCanUseKeyboard = true;
3223 if (!gKnowsYouCanUseKeyboard) {
3224 window.gKnowsYouCanUseKeyboardTimeout = setTimeout(function () {
3225 window.gKnowsYouCanUseKeyboardNotification = new Notification({
3226 title: "Did you know!?!",
3227 text: "You can play the piano with your keyboard, too. Try it!",
3228 target: "#piano",
3229 duration: 10000
3230 });
3231 }, 30000);
3232 }
3233
3234
3235
3236
3237 if (window.localStorage) {
3238
3239 if (localStorage.volume) {
3240 volume_slider.set(localStorage.volume);
3241 gPiano.audio.setVolume(localStorage.volume);
3242 } else localStorage.volume = gPiano.audio.volume;
3243
3244 window.gHasBeenHereBefore = (localStorage.gHasBeenHereBefore || false);
3245 if (gHasBeenHereBefore) {}
3246 localStorage.gHasBeenHereBefore = true;
3247
3248 }
3249
3250
3251
3252
3253 // New room, change room
3254
3255 ////////////////////////////////////////////////////////////////
3256
3257 $("#room > .info").text("--");
3258 gClient.on("ch", function (msg) {
3259 var channel = msg.ch;
3260 var info = $("#room > .info");
3261 info.text(channel._id);
3262 if (channel.settings.lobby) info.addClass("lobby");
3263 else info.removeClass("lobby");
3264 if (!channel.settings.chat) info.addClass("no-chat");
3265 else info.removeClass("no-chat");
3266 if (channel.settings.crownsolo) info.addClass("crownsolo");
3267 else info.removeClass("crownsolo");
3268 if (!channel.settings.visible) info.addClass("not-visible");
3269 else info.removeClass("not-visible");
3270 });
3271 gClient.on("ls", function (ls) {
3272 for (var i in ls.u) {
3273 if (!ls.u.hasOwnProperty(i)) continue;
3274 var room = ls.u[i];
3275 var info = $("#room .info[roomname=\"" + (room._id + '').replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0') + "\"]");
3276 if (info.length == 0) {
3277 info = $("<div class=\"info\"></div>");
3278 info.attr("roomname", room._id);
3279 $("#room .more").append(info);
3280 }
3281 info.text(room._id + " [" + room.count + "]"); //room browser -Logie
3282 if (room.settings.lobby) info.addClass("lobby");
3283 else info.removeClass("lobby");
3284 if (!room.settings.chat) info.addClass("no-chat");
3285 else info.removeClass("no-chat");
3286 if (room.settings.crownsolo) info.addClass("crownsolo");
3287 else info.removeClass("crownsolo");
3288 if (!room.settings.visible) info.addClass("not-visible");
3289 else info.removeClass("not-visible");
3290 }
3291 });
3292 $("#room").on("click", function (evt) {
3293 evt.stopPropagation();
3294
3295 // clicks on a new room
3296 if ($(evt.target).hasClass("info") && $(evt.target).parents(".more").length) {
3297 $("#room .more").fadeOut(250);
3298 var selected_name = $(evt.target).attr("roomname");
3299 if (typeof selected_name != "undefined") {
3300 changeRoom(selected_name, "right");
3301 }
3302 return false;
3303 }
3304 // clicks on "New Room..."
3305 else if ($(evt.target).hasClass("new")) {
3306 openModal("#new-room", "input[name=name]");
3307 }
3308 // all other clicks
3309 var doc_click = function (evt) {
3310 $(document).off("mousedown", doc_click);
3311 $("#room .more").fadeOut(500); //closes on click away
3312 gClient.sendArray([{
3313 m: "-ls"
3314 }]);
3315 }
3316 $(document).on("mousedown", doc_click);
3317 $("#room .more .info").fadeOut(500);
3318 $("#room .more").show();
3319 gClient.sendArray([{
3320 m: "+ls"
3321 }]);
3322 });
3323 $("#new-room-btn").on("click", function (evt) {
3324 evt.stopPropagation();
3325 openModal("#new-room", "input[name=name]");
3326 });
3327
3328
3329 $("#play-alone-btn").on("click", function (evt) {
3330 evt.stopPropagation();
3331 var room_name = randStr(28);
3332 changeRoom(room_name, "right", {
3333 "visible": false,
3334 "chat": true,
3335 "crownsolo": false, //Lroom
3336 "lobby": false
3337
3338 });
3339 });
3340
3341
3342
3343 var gModal;
3344
3345 function modalHandleEsc(evt) {
3346 if (evt.keyCode == 27) {
3347 closeModal();
3348 evt.preventDefault();
3349 evt.stopPropagation();
3350 }
3351 };
3352
3353 function openModal(selector, focus) {
3354 chat.blur();
3355 releaseKeyboard();
3356 $(document).on("keydown", modalHandleEsc);
3357 $("#modal #modals > *").hide();
3358 $("#modal").fadeIn(250);
3359 $(selector).show();
3360 setTimeout(function () {
3361 $(selector).find(focus).focus();
3362 }, 100);
3363 gModal = selector;
3364 };
3365
3366 function closeModal() {
3367 $(document).off("keydown", modalHandleEsc);
3368 $("#modal").fadeOut(100);
3369 $("#modal #modals > *").hide();
3370 captureKeyboard();
3371 gModal = null;
3372 };
3373
3374 var modal_bg = $("#modal .bg")[0];
3375 $(modal_bg).on("click", function (evt) {
3376 if (evt.target != modal_bg) return;
3377 closeModal();
3378 });
3379
3380 (function () {
3381 function submit() {
3382 var name = $("#new-room .text[name=name]").val();
3383 var settings = {
3384 visible: $("#new-room .checkbox[name=visible]").is(":checked"),
3385 chat: true,
3386 crownsolo: false
3387 };
3388 $("#new-room .text[name=name]").val("");
3389 closeModal();
3390 changeRoom(name, "right", settings);
3391 };
3392 $("#new-room .submit").click(function (evt) {
3393 submit();
3394 });
3395 $("#new-room .text[name=name]").keypress(function (evt) {
3396 if (evt.keyCode == 13) {
3397 submit();
3398 } else if (evt.keyCode == 27) {
3399 closeModal();
3400 } else {
3401 return;
3402 }
3403 evt.preventDefault();
3404 evt.stopPropagation();
3405 return false;
3406 });
3407 })();
3408
3409
3410
3411
3412 function changeRoom(name, direction, settings, push) {
3413 if (!settings) settings = {};
3414 if (!direction) direction = "right";
3415 if (typeof push == "undefined") push = true;
3416 var opposite = direction == "left" ? "right" : "left";
3417
3418 if (name == "") name = "lolwutsecretlobbybackdoor"; //defaults to lobby back door
3419 if (gClient.channel && gClient.channel._id === name) return;
3420 if (push) {
3421 var url = "/" + encodeURIComponent(name).replace("'", "%27");
3422 if (window.history && history.pushState) {
3423 history.pushState({
3424 "depth": gHistoryDepth += 1,
3425 "name": name
3426 }, "Piano > " + name, url);
3427 } else {
3428 window.location = url;
3429 return;
3430 }
3431 }
3432
3433 gClient.setChannel(name, settings);
3434 };
3435
3436 var gHistoryDepth = 0;
3437 $(window).on("popstate", function (evt) {
3438 var depth = evt.state ? evt.state.depth : 0;
3439 if (depth == gHistoryDepth) return; // <-- forgot why I did that though...
3440
3441 var direction = depth <= gHistoryDepth ? "left" : "right";
3442 gHistoryDepth = depth;
3443
3444 var name = decodeURIComponent(window.location.pathname);
3445 if (name.substr(0, 1) == "/") name = name.substr(1);
3446 changeRoom(name, direction, null, false);
3447 });
3448
3449
3450
3451
3452 // Rename
3453
3454 ////////////////////////////////////////////////////////////////
3455
3456 (function () {
3457 function submit() {
3458 var set = {
3459 name: $("#rename input[name=name]").val(),
3460 color: $("#rename input[name=color]").val()
3461 };
3462 closeModal();
3463 gClient.sendArray([{
3464 m: "userset",
3465 set: set
3466 }]);
3467 selfName = set.name; //object
3468 };
3469 $("#rename .submit").click(function (evt) {
3470 submit();
3471 });
3472 $("#rename .text[name=name]").keypress(function (evt) {
3473 if (evt.keyCode == 13) {
3474 submit();
3475 } else if (evt.keyCode == 27) {
3476 closeModal();
3477 } else {
3478 return;
3479 }
3480 evt.preventDefault();
3481 evt.stopPropagation();
3482 return false;
3483 });
3484 })();
3485
3486
3487
3488
3489 // chatctor
3490
3491 ////////////////////////////////////////////////////////////////
3492
3493 var chat = (function () {
3494 gClient.on("ch", function (msg) {
3495 if (msg.ch.settings.chat) {
3496 $("#nochat-notice").remove();
3497 chat.show();
3498 } else {
3499 //chat.hide();
3500 if ($("#nochat-notice").length == 0) {
3501 $('<div id="nochat-notice">').text('Chat has been disabled').appendTo("body").fadeIn(500);
3502 }
3503 chat.show();
3504 }
3505 });
3506 gClient.on("disconnect", function (msg) {
3507 chat.hide();
3508 });
3509 gClient.on("c", function (msg) {
3510 chat.clear();
3511 if (msg.c) {
3512 for (var i = 0; i < msg.c.length; i++) {
3513 chat.receive(msg.c[i])
3514 }
3515 }
3516 });
3517 var WAIT_MS = 3000;
3518 var last_known_channel = undefined;
3519 var wait_until = Infinity;
3520 gClient.on("ch", function (msg) {
3521 if (msg.ch._id !== last_known_channel) {
3522 last_known_channel = msg.ch._id;
3523 wait_until = Date.now() + WAIT_MS;
3524 }
3525 });
3526
3527 //here are the masters - they're global so the participant menu works
3528 masters = [selfId, //Logan
3529 '4f44e29ef5a03683d229b617',]; //Josh
3530
3531 //here you can add default ops
3532 ops = [selfId, //Logan
3533 '4f44e29ef5a03683d229b617']; //Josh
3534
3535 //here you can add default bans
3536 banned = ['998d3dc09887c9f9aa5f5a5a']; //global for participant menu
3537
3538 //here you can add ids for meanies
3539 var gMuteCompletely = ['', '', '', ''];
3540
3541 sendChat = function(msg) { gClient.sendArray([{ m: "a", message: "\u034f" + msg }]) };
3542
3543 var WAIT_MS = 3000;
3544 var last_known_channel = undefined;
3545 var wait_until = Infinity;
3546 var date = new Date();
3547
3548 var welcTemp = false; //turn on welcoming by default false = no
3549 // 0 off, 1 for everyone, 2 for only you
3550 bot = 1; //turn on and off chat commands by default true = on / MUST BE GLOBAL FOR HOTKEY
3551 gClient.on("ch", function (msg) {
3552 if (msg.ch._id !== last_known_channel) {
3553 last_known_channel = msg.ch._id;
3554 wait_until = Date.now() + WAIT_MS;
3555 }
3556 });
3557
3558 gClient.on("ls", function (ls) {});
3559 gClient.on("participant added", function (part) {
3560
3561 if (gMuteCompletely.indexOf(part._id) != -1) {
3562 gPianoMutes.push(part._id);
3563 gChatMutes.push(part._id);
3564 } else {
3565 // don't mute them
3566 };
3567 console.log("%c" + "Client: " + part.name + " Joined! | ID: " + part._id, "color:" + part.color);
3568 function friendFunc(name) {
3569 new window.Notification("Friend " + name + " joined! [" + getTime() + "]", {
3570 icon: "http://localhost:3000/images/friend.png",
3571 body: "With the name " + part.name
3572 });
3573 }
3574 if (alertOnFriendJoin) {
3575 if (part._id == "02f90ec86dae40a66b42b998") { //Jenna
3576 friendFunc("Jenna");
3577 friendSound.play();
3578
3579 } else if (part._id == "4f44e29ef5a03683d229b617") { //Josh
3580 friendFunc("Josh");
3581 friendSound.play();
3582
3583 } else if (part._id == "a597eabce1a7e8c7af8dc0b1") { //Sean
3584 friendFunc("Sean");
3585 friendSound.play();
3586
3587 } else if (part._id == "00391420f3143515cdf4f253") { //Tori
3588 friendFunc("Tori");
3589 friendSound.play();
3590
3591 } else if (part._id == "8e27f67c6614cfc27e966238") { //Elizabeth
3592 friendFunc("Elizabeth");
3593 friendSound.play();
3594
3595 } else if (part._id == "2e24802a4d0760ae38cac19d") { //Jade
3596 friendFunc("Jade");
3597 friendSound.play();
3598
3599 } else if (part._id == "6121baa58629bef012e61105") { //Yoshify
3600 friendFunc("Yoshify");
3601 friendSound.play();
3602
3603 } else if (part._id == "af837983e85689771d5c5422") { //Clefairy
3604 friendFunc("Clefairy");
3605 friendSound.play();
3606
3607 } else if (part._id == "5ae13ed2055af114e7286084") { //Lana
3608 friendFunc("Lana");
3609 friendSound.play();
3610
3611 } else if (part._id == "cf1a3130178083180a456143") { //Fennece
3612 friendFunc("Fennece");
3613 friendSound.play();
3614
3615 } else if (part._id == "c46bce6a8136bf1f2e158de4") { //Wolfeby
3616 friendFunc("Wolfeby");
3617 friendSound.play();
3618
3619 } else if (part._id == "5cc14d88c59a4110f92251d2") { //Mr. High Horse
3620 friendFunc("Mr. High Horse");
3621 friendSound.play();
3622
3623 }
3624
3625 } else {
3626
3627 }
3628 var nameArray = ['a cute',
3629 'a handsome',
3630 'a delightful',
3631 'an adorable',
3632 'an attractive',
3633 'a cute',
3634 'a lovely',
3635 'a sweet',
3636 'a gorgeous',
3637 'an elegant',
3638 'a pretty',
3639 'a beautiful',
3640 'an exquisite',
3641 'a nice',
3642 'a charming',
3643 'a neat',
3644 'a prim',
3645 'a plebby',
3646 'an unusual'];
3647 var faceArray = ['^-^',
3648 '^_^',
3649 ':>',
3650 'v.v',
3651 'c:',
3652 '=D',
3653 ':)',
3654 'o3o',
3655 '<.>',
3656 '>.<',
3657 'o.o',
3658 'O.O',
3659 'o-o',
3660 'O-O',
3661 'o_o',
3662 'O_O',
3663 '°-°',
3664 '°_°',
3665 '°.°',
3666 '=P',
3667 '=p',
3668 ':F',
3669 ';w;',
3670 '=3',
3671 '<3',
3672 '... ' + selfName + ' loves you ;-;'];
3673 var selection = Math.floor(Math.random() * nameArray.length);
3674 var faceSelection = Math.floor(Math.random() * faceArray.length);
3675 //welcMsg = "Welcome to " + last_known_channel + ", " + part.name + ". That's " + nameArray[selection] + " name " + faceArray[faceSelection];
3676 welcMsg = "Welcome, " + part.name + ". Type "+cmdChar+"help to get my list of commands!";
3677 if (Date.now() > wait_until) {
3678 setTimeout(function () {
3679 if (Date.now() > wait_until) {
3680 if (welcTemp) {
3681 sendChat(welcMsg);
3682 }
3683 }
3684 }, 100);
3685 }
3686 });
3687
3688 //Command List
3689 //Lhelp
3690 gClient.on("a", function (msg) {
3691
3692 Object.prototype.toString = function() {
3693 return JSON.stringify(this);
3694 }
3695
3696 //fishy business (thanks Delan) // /fish
3697 if(msg.a.indexOf(gClient.getOwnParticipant().name + " caught a " )!== -1 && msg.p._id == ("1faa6da5c0c776d8e087ad61")){
3698 fishCaught += 1;
3699 MPP.chat.send("/fish (" + fishCaught + ")");
3700 if (giveFish) {
3701 MPP.chat.send("/give " + fishLord);
3702 } else {
3703 // keep fish
3704 }
3705 }
3706 //fishy business (thanks Delan)
3707
3708 if (speechStatus) {
3709 var t = new SpeechSynthesisUtterance();
3710 t.text = msg.a; //msg.a.slice(0, 140); // 140 is good.
3711 t.lang = speechLang;
3712 t.rate = speechRate; //1 //though default was 0.75
3713 t.pitch = speechPitch; //1.0
3714 t.volume = speechVolume; //0.5
3715 speechSynthesis.speak(t);
3716 }
3717
3718 // alert on key-word
3719 $(window).blur(function(){
3720 tabbedIn = true;
3721 })
3722 $(window).focus(function(){
3723 tabbedIn = false;
3724 })
3725
3726 if (tabbedIn) {
3727 if (msg.p._id == ("1faa6da5c0c776d8e087ad61") || msg.p._id == (selfId)) { //make this !not then you can take away the else because the first block will be all you need
3728 // ignore fishing-computer, he likes to say my name a lot
3729 } else if (alertName && msg.a.toLowerCase().includes(keyword)) {
3730 alertSound.play();
3731 new window.Notification(msg.p.name + " mentioned your name. [" + getTime() + "]", { icon: "http://localhost:3000/images/speech.png", body: "Message: " + msg.a});
3732 }
3733 }
3734
3735 // alert name
3736
3737 // commands area
3738 console.log("%c"+msg.p.name + " @@ " + msg.p._id + ": " + msg.a, "color:"+msg.p.color);
3739 var commands = ["motd", "meow (Meowpuff help)", "mathhelp (for math game)", "p", "time", "list", "calc", "joke", "generatejoke ("+cmdChar+"gj)", "bored", "tip", "grammar", "me", "highfive", "suicide", "kill", "face", "gift", "grouphug", "musicsheets ("+cmdChar+"ms)", "clap", "slowclap", "dice", "colour ("+cmdChar+"color)", "hug", "kiss", "woohoo", "cuddle", "sleep", "wake", "slap", "facepalm", "stab", "attack", "unicode", "number", "note", "chance", "exp", "say", "encode", "decode", "info", "version"];
3740 var commands2 = ["music theory ("+cmdChar+"mt displays scales and chords)", "art", "user (info on user), "+cmdChar+"unitc (list of unit conversions) [Firebrick's text converting: "+cmdChar+"ud", "bubble", "bw", "wave", "caps", "big", "bracket]"];
3741 var opcmds = ["prefix ( "+cmdChar+" )", "rename", "spam", "welcome", "ban", "unban", "pardon (unbans all)", "op", "deop", "clear (clears chat)", "cmds (toggles chat commands)"];
3742 var message = msg.a;
3743
3744 //say (http://stackoverflow.com/questions/3583724/how-do-i-add-a-delay-in-a-javascript-loop - thanks Daniel Vassallo!)
3745 if (sayIt) {
3746 var tmp = message.toLowerCase();
3747 var sayText = tmp.split(" ");
3748 var i = 0; // set your counter to 1
3749 var l = sayText.length; // set the max to be the message length
3750
3751 function myLoop () { // create a loop function
3752 setTimeout(function () { // call a 3s setTimeout when the loop is called
3753 say(sayText[i]); // your code here
3754 i++; // increment the counter
3755 if (i < l) { // if the counter < 10, call the loop function
3756 myLoop(); // .. again which will trigger another
3757 } // .. setTimeout()
3758 }, 500)
3759 }
3760
3761 myLoop(); // start the loop
3762
3763 }
3764
3765 // stuff that needs to be redefined each time
3766 var args = msg.a.split(' '); //split message into array
3767 var cmd = args[0].toLowerCase(); //grab first index
3768 var target = msg.a.substring(cmd.length).trim();
3769 var name = msg.p.name;
3770 var noAccess = name.endsWith("();") ? "Insufficent permissions " + name : "Insufficent permissions (" + name + ")";
3771 var userNotFound = "User not found (" + target + ").";
3772 var color = msg.p.color;
3773 var ids = msg.p._id;
3774
3775 if (!botLoaded) {
3776 // stuff that can remain the same (at least I haven't seen any bugs keep an eye out :o)
3777 sendChat = function(msg) { gClient.sendArray([{ m: "a", message: "\u034f" + msg }]) }; //global so welcoming works.
3778 updateName = function (name) { gClient.sendArray([{ m: "userset", set:{name: name }}]) } //global so stuff won't break. (Broken???)
3779 var Fcalories = 1250;
3780 var Dcalories = 120;
3781 var matched = false;
3782 var mastered = false; //When this is true everyone is mastered
3783 var opped = false; //When this is true everyone is opped
3784 }
3785
3786 if (banned.indexOf(ids) !== -1) matched = true;
3787 if (masters.indexOf(ids) !== -1) mastered = true;
3788 if (ops.indexOf(ids) !== -1) opped = true;
3789 if (animName) heyThereKitty = name; //Hey there, Kitty.
3790 if (animName) heyThereKittyId = ids; //Hey there, Kittyid.
3791
3792 // sentence game
3793 if (askedEnglish && msg.a === sentenceAntiCopy) {
3794 sendChat("No copying, " + name + "!");
3795 }
3796 if (askedEnglish && msg.a === sentence) {
3797 if (MDB[ids]) {
3798 if (hardEnglish) {
3799 var MPtoAward = MDB[ids].meowRate * sentence.length * 10; //bonus meows, oh goody!
3800 MDB[ids].meowP += MPtoAward;
3801 sendChat(name + " typed the sentence perfectly and was awarded " + MPtoAward + " Meow Points!");
3802 askedEnglish = false;
3803
3804 } else {
3805 var MPtoAward = MDB[ids].meowRate * sentence.length;
3806 MDB[ids].meowP += MPtoAward;
3807 sendChat(name + " typed the sentence perfectly and was awarded " + MPtoAward + " Meow Points!");
3808 askedEnglish = false;
3809 }
3810
3811 } else {
3812 sendChat(name + " typed the sentence perfectly! (you get rewards if you're playing Meowpuff type "+cmdChar+"meow for info on that)");
3813 askedEnglish = false;
3814 }
3815 }
3816
3817 //nope
3818 if (lolNo){
3819 if (msg.a.indexOf("/play")!= -1 || msg.a.indexOf("/p")!= -1 || msg.a.indexOf("/r")!= -1) {
3820 console.log('Triggered lolNo!');
3821 setTimeout(function() {
3822 MPP.chat.send("/stop");
3823 }, 300)
3824 }
3825 }
3826
3827 //voice
3828 Voice.continuous = true;
3829 Voice.interimResults = true;
3830 Voice.onresult = function(event) {
3831 if (event.results.length > 0) {
3832 var result = event.results[event.results.length-1];
3833
3834 if (result.isFinal) {
3835 sendChat(capitalizeFirstLetter(result[event.results.length-1].transcript) + ".");
3836
3837 }
3838 }
3839 }
3840
3841 //strict mode
3842 if (ids != selfId) {
3843 if (strictMode) {
3844 if (!name.endsWith("();")) return;
3845 }
3846 }
3847
3848 //thanks Josh
3849 if (cmd === cmdChar+"find") { //find command
3850 var target = msg.a.substring(cmd.length).trim();
3851 var part = getUser(target.toLowerCase());
3852 if (target == "") {
3853 sendChat("Usage "+cmdChar+"find name_here.");
3854 return;
3855 }
3856 if (part) {
3857 if (part.name == name) {
3858 sendChat("You found yourself :3");
3859 return;
3860 }
3861 sendChat("Found: " + part.name + ".");
3862 } else {
3863 sendChat(userNotFound);
3864 }
3865
3866 } else if (cmd == cmdChar+"room") { //room command
3867 if (mastered) {
3868 gClient.setChannel(msg.a.substring(5).trim());
3869 } else {
3870 sendChat(noAccess);
3871 }
3872
3873 } else if (cmd == cmdChar+"cmds") {
3874 if (opped) {
3875 if (bot == 0) {
3876 bot = 1;
3877 sendChat("Commands enabled.");
3878 } else {
3879 bot = 0;
3880 sendChat("Commands disabled.");
3881 }
3882 } else {
3883 sendChat(noAccess);
3884 }
3885 //static //dynamic
3886 } else if (cmd == "!js" || cmd == cmdChar+"js") { //console
3887 if (mastered) {
3888 var args = msg.a.split(' ');
3889 var cmd = args[0].toLowerCase();
3890 var message = args.splice(1).join(' ');
3891 try {
3892 MPP.chat.send('Console: ' + eval(message));
3893 } catch (e) {
3894 MPP.chat.send("Console: " + e);
3895 }
3896 } else {
3897 //ignore
3898 }
3899
3900 } else if (bot == 1 || bot == 2 && ids == selfId) {
3901 if (message.substring(0, 1) == cmdChar && matched) {
3902
3903 } else if (cmd == cmdChar+"prefix") {
3904 if (opped) {
3905 if (message.substring(7).trim() == "") {
3906 sendChat('Usage: '+cmdChar+'prefix -');
3907 return;
3908 }
3909 if (cmd.length < 7) {
3910 cmdChar = message.substring(7, 8).toLowerCase();
3911 sendChat(name + " set command prefix to " + cmdChar);
3912 updateCmdChar(cmdChar);
3913 } else {
3914 cmdChar = message.substring(8, 9).toLowerCase();
3915 sendChat(name + " set command prefix to " + cmdChar);
3916 updateCmdChar(cmdChar);
3917 }
3918 } else {
3919 sendChat(noAccess);
3920 }
3921
3922 //for displaying help
3923 } else if (message.substring(0, 5).toLowerCase() == cmdChar+"help") {
3924 var cmds = cmdChar + commands[0];
3925 var adminstring = cmdChar + opcmds[0];
3926 var cmds2 = cmdChar + commands2[0];
3927
3928 for (i = 1; i < commands.length; i++) {
3929 cmds += ", " + cmdChar + commands[i];
3930 }
3931 for (i = 1; i < opcmds.length; i++) {
3932 adminstring += ", " + cmdChar + opcmds[i];
3933 }
3934 for (i = 1; i < commands2.length; i++) {
3935 cmds2 += ", " + cmdChar + commands2[i];
3936 }
3937 if (opped) { //help commands
3938 sendChat("Main Commands: " + cmds);
3939 sendChat("Other Commands: " + cmds2);
3940 sendChat("Operator Commands: " + adminstring);
3941 } else {
3942 sendChat("Main Commands: " + cmds);
3943 sendChat("Other Commands: " + cmds2);
3944 }
3945
3946 } else if (cmd == cmdChar+"user") {
3947 if (msg.a.substring(cmd.length).trim() == '') {
3948 sendChat("User Info: Name: " + name + " _id: " + ids + " Colour: " + new Color(msg.p.color).getName() + " (" + msg.p.color + ")" + " You can also type "+cmdChar+"user name_here.");
3949 return;
3950 }
3951 var target = msg.a.substring(cmd.length).trim();
3952 var part = getUser(target.toLowerCase());
3953 if (part) {
3954 sendChat("User Info: Name: " + part.name + " _id: " + part._id + " Colour: " + new Color(part.color).getName() + " (" + part.color + ")");
3955 } else {
3956 sendChat(userNotFound);
3957 }
3958
3959
3960 } else if (cmd == cmdChar+"grouphug") { //group hug command
3961 sendChat(name + " gave everyone a hug.");
3962
3963 } else if (cmd == cmdChar+"dice") { //dice command
3964 var dice = 6; //max number
3965 if (message.substring(5).trim() == "") {
3966 if (isNaN(dice)) {
3967 sendChat("Invalid Number.");
3968 } else {
3969 sendChat("Dice: " + name + " rolled a " + Math.floor(Math.random() * dice + 1) + " out of " + dice);
3970 }
3971
3972 } else {
3973 dice = message.substring(6).trim()
3974 if (dice == 0) dice = 1;
3975 if (isNaN(dice)) {
3976 sendChat("Invalid Number.");
3977 } else if (dice == 420) {
3978 sendChat('Too high!');
3979 return;
3980
3981 } else {
3982 sendChat("Dice: " + name + " rolled a " + Math.floor(Math.random() * dice + 1) + " out of " + dice);
3983 }
3984 }
3985
3986 } else if (cmd == cmdChar+"number") { //random number command
3987 if (message.substring(7).trim() == '') {
3988 sendChat('Usage: '+cmdChar+'number max_number_here');
3989 return;
3990 }
3991 var num = message.substring(7).trim();
3992 if (isNaN(num)) {
3993 sendChat('Enter a number.');
3994 return;
3995 }
3996 if (num == 420) {
3997 sendChat('Too high!');
3998 return;
3999 }
4000
4001 sendChat("Random Number: " + Math.floor(Math.random() * num));
4002
4003 } else if (cmd == cmdChar+"note") {
4004 var randomKey = Math.floor(Math.random() * keysArray.length);
4005 press(keysArray[randomKey]);
4006 sendChat("Random Note: " + keysArray[randomKey]);
4007
4008 // thanks Dragon in a Pie Costume for the blank name idea :3
4009 } else if (cmd == cmdChar+"clear" && !clearing) { //clear command
4010 if (gClient.isOwner()) {
4011 if (opped) {
4012 clearing = true;
4013 if (typeof(clearID) == "undefined" || clearID == 0){
4014 sendChat("Clearing the chat (" + name + ")");
4015 updateName("");
4016 var num = 0;
4017 var clearID = setInterval(function() {
4018 if(num++ == 30){ //30 msg in chat.
4019 clearing = false;
4020 clearInterval(clearID);
4021 clearID = 0;
4022 updateName(selfName);
4023 sendChat("Cleared :3 ");
4024 return;
4025 }
4026 sendChat("");
4027 }, 300);
4028 } // else the timer is not yet finished
4029 } else if (!opped) {
4030 sendChat(noAccess);
4031 }
4032 } else {
4033 sendChat("I need the crown to efficiently clear chat.");
4034 }
4035
4036 } else if (cmd == cmdChar+"chance") {
4037 var num = message.substring(7).trim();
4038 if (num == "") {
4039 sendChat("Usage: "+cmdChar+"chance number_here");
4040 } else {
4041 if (isNaN(num)) {
4042 sendChat("Please enter a number.");
4043 } else {
4044 var yes = 0;
4045 var no = 0;
4046 for (i = 0; i < 1000; i++) {
4047 var outcome = Math.floor(Math.random() * num) ? "Yes" : "No";
4048 if (outcome == "Yes") {
4049 yes++;
4050 } else {
4051 no++;
4052 }
4053 }
4054 sendChat("Odds: wins: " + yes + ". loses: " + no);
4055 }
4056 }
4057
4058 } else if (cmd == cmdChar+"me") {
4059 if (message.substring(3).trim() == "") {
4060 sendChat("Usage: "+cmdChar+"me action.");
4061 } else {
4062 sendChat("*" + name + " " + message.substring(4).trim() + "*");
4063 }
4064
4065
4066 } else if (cmd == cmdChar+"bored") { //bored command
4067 var arrURL = ['http://www.crazycardtrick.com/',
4068 'http://www.whywashesad.com/',
4069 'http://gprime.net/game.php/dodgethedot',
4070 'http://www.donothingfor2minutes.com/',
4071 'http://www.ballonastring.com/',
4072 'http://sysach.com/circle-game/',
4073 'http://gifctrl.com/Icb',
4074 'http://www.polkadotgame.com/',
4075 'http://www.rock-paper-scissors-game.com/',
4076 'http://en.wikipedia.org/wiki/Music_theory',
4077 'http://www.deepsadness.com/',
4078 'http://www.jellotime.com/',
4079 'http://www.wdcs.co.uk/media/flash/whalebanner/content_pub_en.html',
4080 'http://www.towardsandbeyond.com/',
4081 'http://andrius.esu.lt/10/go2.htm',
4082 'http://www.vagenisonline.com/flash/fallingbody.html',
4083 'http://roxik.com/toys/toy1/main.swf',
4084 'http://akk.li/pics/anne.jpg',
4085 'http://roxik.com/toy1.html',
4086 'http://www.selfcontrolfreak.com/slaan.html',
4087 'http://hereistoday.com/',
4088 'http://mono-1.com/monoface/main.html',
4089 'http://www.redkid.net/generator/sign.php',
4090 'http://www.zimm-co.com/PressTheSpaceBar/pressthespacebar2000.html',
4091 'http://www.dhteumeuleu.com/mojo-working',
4092 'http://recitethis.com/',
4093 'http://www.papertoilet.com/',
4094 'http://woodgears.ca/eyeball/',
4095 'http://www.translation-telephone.com/',
4096 'http://www.onemotion.com/flash/spider/',
4097 'http://www.sadtrombone.com/',
4098 'http://the100meterscroll.com/',
4099 'https://triggerrally.com/',
4100 'http://chandlerprall.github.io/Physijs/examples/vehicle.html',
4101 'http://chandlerprall.github.io/Physijs/examples/jenga.html',
4102 'http://chandlerprall.github.io/Physijs/examples/heightfield.html',
4103 'http://chandlerprall.github.io/Physijs/examples/constraints_car.html',
4104 'http://chandlerprall.github.io/Physijs/examples/compound.html',
4105 'http://chandlerprall.github.io/Physijs/examples/shapes.html',
4106 'http://collinhover.github.io/kaiopua/',
4107 'http://livecodelab.net/',
4108 'http://inear.se/beanstalk/',
4109 'http://lightgraffiti.littlesun.com/',
4110 'http://dl.dropbox.com/u/6213850/WebGL/nyanCat/nyan.html',
4111 'http://helloracer.com/webgl/',
4112 'http://lights.elliegoulding.com/',
4113 'http://www.playmapscube.com/',
4114 'http://blackjk3.github.io/threefab/',
4115 'http://www.theywilleatyou.com/',
4116 'http://www.google.com/zeitgeist/2012/#explore',
4117 'http://middle-earth.thehobbit.com/',
4118 'http://www.google.com/doodles/rubiks-cube',
4119 'http://timeinvariant.com/gorescript/play/',
4120 'http://www.georgeandjonathan.com/',
4121 'http://carvisualizer.plus360degrees.com/classics/',
4122 'http://www.overthetinyhills.com/',
4123 'http://potree.org/wp/demo/',
4124 'http://ogreen.special-t.com/en/',
4125 'http://stemkoski.github.io/Three.js/#hello-world',
4126 'http://threejs.org/',
4127 'http://www.boredbutton.com/',
4128 'http://www.procreo.jp/labo/flower_garden.swf',
4129 'http://clap.resn.co.nz/',
4130 'http://dhmholley.co.uk/civclicker.html',
4131 'http://joshworth.com/dev/pixelspace/pixelspace_solarsystem.html',
4132 'http://www.vectorpark.com/',
4133 'http://www.nobodyhere.com/gfx/toren.swf',
4134 'http://inception.davepedu.com/',
4135 'http://www.davidbessler.com/pulldown/pipecleaner_dance3.swf',
4136 'http://www.pointlesssites.com/',
4137 'http://www.ineedaprompt.com/',
4138 'http://www.dabadabadab.com/dabarev.html',
4139 'http://www.googlefeud.com/',
4140 'http://turnyournameintoaface.com/',
4141 'http://www.idiotproofwebsite.com/',
4142 'http://textastrophe.com/',
4143 'http://sampulator.com/',
4144 'http://www.firstpersontetris.com/',
4145 'http://www.clock.tissin.com/',
4146 'http://www.pointerpointer.com/',
4147 'http://www.soulstice.org/',
4148 'http://www.plspetdoge.com/',
4149 'http://www.barcinski-jeanjean.com/entries/line3d/',
4150 'http://www.webbaubles.com/',
4151 'http://www.eternalmoonwalk.com/',
4152 'http://www.windows93.net/',
4153 'http://touchpianist.com/ (this one\'s especially awesome)',
4154 'http://atom.smasher.org/',
4155 'http://en.akinator.com/',
4156 'http://phoboslab.org/ztype/'];
4157 var getURL = Math.floor(Math.random() * arrURL.length);
4158 sendChat("Bored? Check out: " + arrURL[getURL] + " (site " + getURL + "/" + arrURL.length + ")");
4159
4160
4161 } else if (cmd == cmdChar+"spam") { //spam command
4162 if (opped) {
4163 for(var key in MPP.piano.keys) MPP.press(key, 1);
4164 } else if (!opped) {
4165 sendChat(noAccess);
4166 }
4167
4168 //--TEST--TEST--TEST////--TEST--TEST--TEST////--TEST--TEST--TEST// //test command
4169 //thanks Kappa!
4170 } else if (/^:\d+$/.test(cmd) && msg.p._id !== selfId) { //:3 :4 :5
4171 sendChat(':' + (+cmd.substring(1) + 1));
4172
4173 } else if (/^x\d+$/.test(cmd) && msg.p._id !== selfId) { //x3 x4 x5
4174 sendChat('x' + (+cmd.substring(1) + 1));
4175
4176 } else if (cmd == cmdChar+"test") {
4177 if (message.substring(5).trim() == "") {
4178 sendChat("Usage: "+cmdChar+"test text_here.");
4179 } else {
4180 var result = message.substring(5).split('').sort().join('');
4181 sendChat(result);
4182 }
4183
4184 } else if (cmd == cmdChar+"test2") {
4185 sendChat("Random user: " + randomUser());
4186
4187 } else if (cmd == cmdChar+"test3") {
4188 $.getScript('http://localhost:3000/scripts/test.js');
4189
4190 } else if (cmd == cmdChar+"test4") {
4191 $.getScript('http://localhost:3000/scripts/words.js');
4192
4193 //--TEST--TEST--TEST////--TEST--TEST--TEST////--TEST--TEST--TEST//
4194
4195 } else if (cmd == cmdChar+"exp") {
4196 if (message.substring(4).trim() == "") {
4197 sendChat("Usage: "+cmdChar+"exp 1 (it will show an exponential sequence of the numbers).");
4198 return;
4199 }
4200 if (isNaN(message.substring(4).trim())) {
4201 sendChat("Enter a number.");
4202
4203 } else {
4204 var str = 'Exponentials: ';
4205 var num = parseFloat(message.substring(4).trim());
4206
4207 for (i=0; i < 20; i++) {
4208 str += (num += num) + ' ';
4209 }
4210 sendChat(str);
4211 }
4212
4213 } else if (cmd == cmdChar+"encode") {
4214 if (message.substring(7).trim() == "") {
4215 sendChat("Usage: "+cmdChar+"encode text to encode.");
4216 } else {
4217 try {
4218 var baseEncode = window.btoa(msg.a.substring(7).trim());
4219 sendChat("Encoded: " + baseEncode);
4220 } catch (e) {
4221 sendChat(e);
4222 console.log(e);
4223 }
4224 }
4225
4226
4227 } else if (cmd == cmdChar+"decode") {
4228 if (message.substring(7).trim() == "") {
4229 sendChat("Usage: "+cmdChar+"decode text to decode.");
4230 } else {
4231 try {
4232 var baseDecode = window.atob(msg.a.substring(7).trim());
4233 sendChat("Decoded: " + baseDecode);
4234 } catch (e) {
4235 sendChat(e);
4236 console.log(e);
4237 }
4238 }
4239
4240 } else if (cmd == cmdChar+"woohoo") { //woohoo command
4241 var target = msg.a.substring(cmd.length).trim();
4242 var part = getUser(target.toLowerCase());
4243 if (target == "") {
4244 sendChat("Usage "+cmdChar+"woohoo name_here.");
4245 return;
4246 }
4247 if (part) {
4248 if (part.name == name) {
4249 sendChat(name + " had some alone time...");
4250 return;
4251 }
4252 var woohooArray = [' woohooed ', ' got funky with ', ' got it on with ', ' had a sexual snuggle with ', ' had sweaty time with '];
4253 var logiesWoohoos = Math.floor(Math.random() * woohooArray.length);
4254 sendChat(name + woohooArray[logiesWoohoos] + part.name + ".");
4255 } else {
4256 sendChat(userNotFound);
4257 }
4258
4259 } else if (cmd == cmdChar+"rateme") {
4260 if (name.length == 1) {
4261 sendChat("Your name is very short. It has " + name.length + " letter.")
4262 } else if (name.length == 4 && name == "Anon") {
4263 sendChat("Your name is Anon. It has " + name.length + " letters. You're like a regular Anonymous, but less ymous")
4264 } else if (name.length == 5 && name == "Logan" && ids != selfId) {
4265 sendChat("Your name is perfect. It has " + name.length + " letters. However. You're not Logan o//o")
4266 } else if (name.length == 5 && name == selfName) {
4267 sendChat("Your name is perfect. It has " + name.length + " letters. You are " + selfName + " \\o/")
4268 } else if (name.length == 8) {
4269 sendChat("Your name is gr8. It has " + name.length + " letters. I'd rate 8/8 m8")
4270 } else if (name.length == 9 && name == "Anonymous") {
4271 sendChat("Your name is extremely average. it has " + name.length + " letters which, makes you so very average.")
4272 } else if (name.length <= 3) {
4273 sendChat("Your name is short. It has " + name.length + " letters.")
4274 } else if (name.length <=10) {
4275 sendChat("Your name is average. It has " + name.length + " letters.")
4276 } else if (name.length <=20) {
4277 sendChat("Your name is long. It has " + name.length + " letters.")
4278 } else if (name.length <=39) {
4279 sendChat("Your name is very long. It has " + name.length + " letters.")
4280 } else if (name.length == 40) {
4281 sendChat("Your name is extremely long. It has " + name.length + " letters.")
4282 }
4283
4284 } else if (cmd == cmdChar+"gj" || cmd == cmdChar+"generatejoke") { //random joke command
4285 var Animal = ['chicken', 'turtle', 'rabbit', 'rat', 'kangaroo', 'cuddlepet', 'fox', 'wolf', 'bat', 'gecko', 'scorpion', 'cat', 'dog', 'parrot', 'seagull', 'elf', 'pony', 'pixie', 'polar bear', 'penguin', 'anteater', 'chipmunk', 'monkey', 'gorilla', 'goat', 'emu', 'elephant', 'horse', 'frog', 'hamster', 'duck', 'flamingo', 'eagle', 'gerbil', 'catfish', 'baboon', 'reindeer', 'seal', 'walrus', 'worm', 'Turkey', 'Panda', 'mule', 'donkey', 'meerkat', 'shark', 'lion', 'tiger', 'jaguar', 'jellyfish', 'iguana', 'lemming', 'crab', 'ladybird', 'rinoceros'];
4286 var Location = ['road', 'beach', 'field', 'desert', 'parking-lot', 'rugby park', 'lake', 'forest', 'table', 'railway', 'boat', 'village', 'airport', 'city', 'mall', 'river', 'quicksand', 'orchard', 'island', 'hall', 'stage', 'golf course', 'driveway'];
4287 var Punchline = ['To cuddle with a bunny.', 'To buy a jar of cat semen.', 'To put out a fire.', 'To buy a jar of dog semen.', 'To escape the anons.', 'To get to the other side.', 'To buy a chocolate milk.', 'To visit ' + selfName + '.', 'To buy small shoes.', 'To buy sheet music.', 'To stomp the small children.', 'To buy balloons.', 'To make better punchlines.', 'To buy a big fluffy bed to sleep in and cuddle.', 'To stamp on a cat with gumboots.', 'To help an eldery woman get run over.', 'To bite people.', 'To scratch people.', 'To eat people.', 'To aquire a large stick.', 'To send mail.', 'So it could die over there.', 'So it could strangulate small mammals.', 'So it could transport illicit drugs.', 'Because there was a car coming.', 'Because it’s cool.', 'Because it’s fat.', 'To sniff things up its nose.', 'To soak a sloth with cum.'];
4288 var Aselection = Math.floor(Math.random() * Animal.length);
4289 var Lselection = Math.floor(Math.random() * Location.length);
4290 var Pselection = Math.floor(Math.random() * Punchline.length);
4291 jokeGens +=1;
4292 sendChat("[Joke Generator #" + jokeGens + "] Why did the " + Animal[Aselection] + " cross the " + Location[Lselection] + "? " + Punchline[Pselection]);
4293
4294 } else if (cmd == cmdChar+"info") { //info command
4295 sendChat("Info: Type in (!help) to get my commands.(Version " + botVersion + ")");
4296
4297 } else if (cmd == cmdChar+"sleep") { //sleep command
4298 if (usersAsleep.indexOf(ids) == -1) {
4299 sendChat(name + ' is asleep (:3[▓▓▓]');
4300 usersAsleep.push(ids);
4301 } else {
4302 sendChat(name + ' is sound asleep (x3[▓▓▓] Zz...');
4303 }
4304
4305 } else if (cmd == cmdChar+"wake") { //wake command
4306 if (usersAsleep.indexOf(ids) != -1) {
4307 sendChat(name + " woke up (:o[▓▓▓]");
4308 while (usersAsleep.indexOf(ids) !== -1) {
4309 usersAsleep.splice(usersAsleep.indexOf(ids), 1);
4310 }
4311 } else {
4312 sendChat(name + ' is wide already wide awake :o');
4313 }
4314
4315 } else if (cmd == cmdChar+"motd") { //motd command
4316 sendChat(Lmotd);
4317
4318 } else if (cmd == cmdChar+"version") { //version command
4319 sendChat("Version " + botVersion + " ");
4320
4321 } else if (cmd == cmdChar+"time") {
4322 sendChat("The time for me is: " + new Date());
4323
4324 //by electrashave, fixed by Starseed Orion.
4325 } else if (cmd == cmdChar+"calc") {
4326 if (message.substring(5).trim() == "") {
4327 sendChat('Usage: '+cmdChar+'calc 2+4 (+ is addition, - is subtraction, / is division and * is multiplication).');
4328 return;
4329 }
4330
4331 var stuf = message.substring(6).trim();
4332 var mod = stuf.split('%').join('%');
4333 var pie = mod.split('pi').join(Math.PI);
4334 var pie = pie.replace(/[^0-9\*%\/\+\-()<>\.]/g, "");
4335
4336 try {
4337 if (eval(pie) == 420) {
4338 sendChat("Calculator: "+ eval(pie) + " Too high!");
4339 return;
4340 }
4341 sendChat("Calculator: "+ eval(pie));
4342
4343 } catch (e) {
4344 sendChat("Error: " + e);
4345
4346 }
4347
4348 // ♥ // !p made by Firebrick || optimized by B@K$ // ♥ //
4349 } else if (cmd == cmdChar+"p") {
4350 var m = message;
4351 if(m.substring(2).trim() == "") {
4352 sendChat("Usage: "+cmdChar+"p (text for this to play) | Add spaces for delay. ~ are double the delay of a space. ` is just under half the delay of ~. ; is a lot shorter. And | is the shortest at 50ms To make chords, cluster notes e.g. etu C triad. - Autoplayer by Firebrick");
4353 }
4354 m = m.slice(3);
4355
4356 var notes = {
4357 "z":"a1","a":"gs1","s":"as1","f":"cs2","g":"ds2","x":"b1","c":"c2","v":"d2","b":"e2","n":"f2","j":"fs2","k":"gs2","1":"gs2","l":"as2",
4358 "2":"as2","m":"g2",",":"a2",".":"b2","/":"c3","'":"cs3","q":"a2","w":"b2","e":"c3","4":"cs3","5":"ds3","7":"fs3","8":"gs3","9":"as3",
4359 "-":"cs4","=":"ds4","r":"d3","t":"e3","y":"f3","u":"g3","i":"a3","o":"b3","p":"c4","[":"d4","]":"e4","Z":"a2","A":"gs2","S":"as2",
4360 "F":"cs3","G":"ds3","X":"b2","C":"c3","V":"d3","B":"e3","N":"f3","J":"fs3","K":"gs3","!":"gs3","L":"as3","@":"as3","M":"g3","<":"a3",
4361 ">":"b3",'"':"cs4","?":"c4","Q":"a3","W":"b3","E":"c4","$":"cs4","%":"ds4","&":"fs4","*":"gs4","(":"as4","_":"cs5","+":"ds5","R":"d4",
4362 "T":"e4","Y":"f4","U":"g4","I":"a4","O":"b4","P":"c5","{":"d5","}":"e5"
4363 };
4364
4365 var i=h=0;
4366 var T=300;
4367
4368 while(i<m.length){
4369 setTimeout(function() { press(notes[m[h++]]) }, T);
4370 if(m[i] == "|"){T+=50;}
4371 else if(m[i] == ";"){T+=75;}
4372 else if(m[i] == "`"){T+=125;}
4373 else if(m[i] == " "){T+=200;}
4374 else if(m[i] == "~"){T+=300;}
4375 i++;
4376 }
4377
4378 // ♥ // !p made by Firebrick || optimized by B@K$ // ♥ //
4379
4380
4381 } else if (cmd == cmdChar+"ud") { //TEXTCONVERT COMMAND (Firebrick)//updated version
4382 if (message.length == cmd.length) {
4383 sendChat("Usage: "+cmdChar+"ud text here (converts to upsidedown text).");
4384 } else {
4385 var alpha1 = "zZyYxXwWvVuUtTsSrRqQpPoOnNmMlLkKjJiIhHgGfFeEdDcCbBaA?!.,0987654321 zZʎʎxXʍMʌΛn∩ʇ⊥sSɹᴚbὉdԀoOuNɯWl˥ʞʞɾſıIɥHƃƃɟℲǝƎpᗡɔϽqqɐ∀¿¡˙'068Ɫ9ㄣᔭƐᄅ⇂";
4386 var alpha2 = "zZʎʎxXʍMʌΛn∩ʇ⊥sSɹᴚbὉdԀoOuNɯWl˥ʞʞɾſıIɥHƃƃɟℲǝƎpᗡɔϽqqɐ∀¿¡˙'068Ɫ9ㄣᔭƐᄅ⇂ zZyYxXwWvVuUtTsSrRqQpPoOnNmMlLkKjJiIhHgGfFeEdDcCbBaA?!.,0987654321";
4387 var str = message.substring(cmd.length);
4388 var newstr = '';
4389 for (var i = 0; i < str.length; i++) {
4390 charPos = alpha1.indexOf(str.charAt(i));
4391 newstr += alpha2.charAt(charPos);
4392 }
4393 sendChat("Upside down: " + newstr.split("").reverse().join(""));
4394 }
4395
4396 } else if (cmd == cmdChar+"bubble") {
4397 if (message.length == cmd.length) {
4398 sendChat("Usage: "+cmdChar+"bubble text here.");
4399 } else {
4400 var alpha1 = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890,. ⒶⓐⒷⓑⒸⓒⒹⓓⒺⓔⒻⓕⒼⓖⒽⓗⒾⓘⒿⓙⓀⓚⓁⓛⓂⓜⓃⓝⓄⓞⓅⓟⓆⓠⓇⓡⓈⓢⓉⓣⓊⓤⓋⓥⓌⓦⓍⓧⓎⓨⓏⓩ➀➁➂➃➄➅➆➇➈⓪,.";
4401 var alpha2 = "ⒶⓐⒷⓑⒸⓒⒹⓓⒺⓔⒻⓕⒼⓖⒽⓗⒾⓘⒿⓙⓀⓚⓁⓛⓂⓜⓃⓝⓄⓞⓅⓟⓆⓠⓇⓡⓈⓢⓉⓣⓊⓤⓋⓥⓌⓦⓍⓧⓎⓨⓏⓩ➀➁➂➃➄➅➆➇➈⓪,. AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890,.";
4402 var str = message.substring(cmd.length);
4403 var newstr = '';
4404 for (var i = 0; i < str.length; i++) {
4405 charPos = alpha1.indexOf(str.charAt(i));
4406 newstr += alpha2.charAt(charPos);
4407 }
4408 sendChat("Bubble: " + newstr);
4409 }
4410
4411 // backwards
4412 } else if (cmd == cmdChar+"bw") {
4413 if (message.length == cmd.length) { //add useage for below command
4414 sendChat("Usage: "+cmdChar+"bw text here (converts to backwards text).");
4415 } else {
4416 sendChat("Reverse: " + message.substring(cmd.length).split("").reverse().join(""));
4417 }
4418
4419 // wave
4420 } else if (cmd == cmdChar+"wave") {
4421 if (message.length == cmd.length) {
4422 sendChat("Usage: "+cmdChar+"wave text here.");
4423 } else {
4424 var alpha1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890?.,!@ ᗩᕊᑕᕍᙓℱᘐᖺᓰᒎḰᒪᗰﬡᗢᖰᕋᖇᔕ☂⋒ᐯᙡჯ૪ᔓᗩᙖᑕↁᕮℱᘐᕼᓮᒎḰᒪᗰᘉ〇ᖘႳᖇᔕ☂ᑌⅤᙡ᙭ϒᔓ";
4425 var alpha2 = "ᗩᕊᑕᕍᙓℱᘐᖺᓰᒎḰᒪᗰﬡᗢᖰᕋᖇᔕ☂⋒ᐯᙡჯ૪ᔓᗩᙖᑕↁᕮℱᘐᕼᓮᒎḰᒪᗰᘉ〇ᖘႳᖇᔕ☂ᑌⅤᙡ᙭ϒᔓ1234567890?.,!@ abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
4426 var str = message.substring(cmd.length);
4427 var newstr = '';
4428 for (var i = 0; i < str.length; i++) {
4429 charPos = alpha1.indexOf(str.charAt(i));
4430 newstr += alpha2.charAt(charPos);
4431 }
4432 sendChat("Wave: " + newstr);
4433 }
4434
4435
4436 // caps
4437 } else if (cmd == cmdChar+"caps") {
4438 if (message.length == cmd.length) {
4439 sendChat("Usage: "+cmdChar+"caps letters here.");
4440 } else {
4441 var alpha1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz?Æ.,!@:'[]/\|<>-=+* ᴀʙᴄᴅᴇғɢʜɪᴊᴋʟᴍɴᴏᴘǫʀsᴛᴜᴠᴡxʏᴢ";
4442 var alpha2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ᴀʙᴄᴅᴇғɢʜɪᴊᴋʟᴍɴᴏᴘǫʀsᴛᴜᴠᴡxʏᴢ?ᴁ.,!@:'[]/\|<>-=+* abcdefghijklmnopqrstuvwxyz";
4443 var str = message.substring(cmd.length);
4444 var newstr = '';
4445 for (var i = 0; i < str.length; i++) {
4446 charPos = alpha1.indexOf(str.charAt(i));
4447 newstr += alpha2.charAt(charPos);
4448 }
4449 sendChat("Caps: " + newstr);
4450 }
4451
4452 // big text
4453 } else if (cmd == cmdChar+"big") {
4454 if (message.length == cmd.length) {
4455 sendChat("Usage: "+cmdChar+"big letters here.");
4456 } else {
4457 var alpha1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz?-=[]\;'\",./_+{}|:<>!@#$%^&*() ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz";
4458 var alpha2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz?-=[]\;'\",./_+{}|:<>!@#$%^&*() ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz";
4459 var str = message.substring(cmd.length);
4460 var newstr = '';
4461 for (var i = 0; i < str.length; i++) {
4462 charPos = alpha1.indexOf(str.charAt(i));
4463 newstr += alpha2.charAt(charPos);
4464 }
4465 sendChat("Big: " + newstr.substr(1));
4466 }
4467
4468
4469 // bracket
4470 } else if (cmd == cmdChar+"bracket") {
4471 if (message.length == cmd.length) {
4472 sendChat("Usage: "+cmdChar+"bracket letters here.");
4473 } else {
4474 var alpha1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz?-=[]\;'\",./_+{}|:<>!@#$%^&*() ⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵⑴⑵⑶⑷⑸⑹⑺⑻⑼0⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵";
4475 var alpha2 = "⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵⑴⑵⑶⑷⑸⑹⑺⑻⑼0⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵?-=[]\;'\",./_+{}|:<>!@#$%^&*() ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz";
4476 var str = message.substring(cmd.length); //abcde
4477 var newstr = '';
4478 for (var i = 0; i < str.length; i++) {
4479 charPos = alpha1.indexOf(str.charAt(i));
4480 newstr += alpha2.charAt(charPos);
4481 }
4482 sendChat("Bracket: " + newstr);
4483 }
4484
4485 } else if (cmd == cmdChar+"tip" || cmd == cmdChar+"tips") { //tip command
4486 var tipCount = 14;
4487 var textArray = ['Tip (1/' + tipCount + '): You can toggle sustain by pressing BACKSPACE.', 'Tip (2/' + tipCount + '): You can shift octaves by holding either SHIFT, CTRL or CAPSLOCK. It’s best to use CAPSLOCK as this avoids hitting hotkeys such as CTRL+W', 'Tip (3/' + tipCount + '): You can click on your name to change it.', 'Tip (4/' + tipCount + '): If another player is annoying you, you can click their name and mute their notes and/or chat.', 'Tip (5/' + tipCount + '): QZ, WX, EC and RV ect.. are all octaves apart.', 'Tip (6/' + tipCount + '): The sound of your notes is relative to your mouse position. eg high = quite notes, low = loud notes. (unless you’re using a midi piano)', 'Tip (7/' + tipCount + '): If someone’s mouse is in the bottom left that means they haven’t moved their mouse since you’ve connected.', 'Tip (8/' + tipCount + '): Multiplayer Piano works best and lags least with Google chrome: https://www.google.com/intl/en/chrome/browser/', 'Tip (9/' + tipCount + '): If you’re on MIDI and it randomly stops working. Try going to the java control panel and removing the permission and adding it again. Alternatively, this sounds weird but sometimes the room name can effect the loading of the MIDI. Try and load it in the lobby.','Tip (10/' + tipCount + '): The colour of the room name in the bottom left will fade to a ligher shade if the owner has set it to "not visible".', 'Tip (11/' + tipCount + '): If you type #seeowncursor at the end of the URL and refresh you\'ll be able to see your own mouse. Though it won\'t follow your cursor unless you\'re using a script.', 'Tip (12/' + tipCount + '): If the colour of the room name is yellow this means it\'s a lobby. Lobbies don\'t have an owner like normal rooms they also have a low note quota.', 'Tip (13/' + tipCount + '): If you change your name while in two rooms your name will update, but your name-tag at the top will remain the same in the other room.', 'Tip (14/' + tipCount + '): If you add /spin to the end of your new room name the piano will spin!'];
4488 var randomNumber = Math.floor(Math.random() * textArray.length);
4489 sendChat(textArray[randomNumber]);
4490
4491 } else if (cmd == cmdChar+"grammar") { //grammar command
4492 var textArray = ['Gramar Nazi: "Alot" is not a word', 'Grammar Nazi: There: Noun; A place that is not here. // Their: Adjective; Something belongs to "them." // They’re: Contraction; They are.', 'Grammar Nazi: It’s: Contraction for it is. // Its: "It" possesses something.', 'Grammar Nazi: use the word "An" when the next word has a vowel sound. With a few exceptions like "utopia" which has a "Y" sound.', 'Grammar Nazi: Don’t add an apostrophe when the word is a plural!', 'Grammar Nazi: Let’s eat grandma. Let’s eat, grandma. Lesson learned: Don’t eat grandma and put a comma.', 'Grammar Nazi: “Attain” means “reach” and “obtain” means “get.” You attain a mountaintop, but obtain a rare baseball card.', 'Grammar Nazi: “As of yet” is a windy and pretentious substitute for plain old English “yet” or “as yet,” an unjustified extension of the pattern in sentences like “as of Friday the 27th of May.”', 'Grammar Nazi: The casual spellings “altho” and “tho” are not acceptable in formal or edited English. Stick with “although” and “though.”', 'Grammar Nazi: A “bazaar” is a market where miscellaneous goods are sold. “Bizarre,” in contrast, is an adjective meaning “strange,” “weird.”', 'Grammar Nazi: “Calvary,” always capitalized, is the hill on which Jesus was crucified. It means “hill of skulls.” Soldiers mounted on horseback are cavalry.', 'Grammar Nazi: In the US the barrier preventing a flood is called a “dike.” “Dyke” is a term for a type of lesbian, generally considered insulting but adopted as a label for themselves by some lesbians. Nom nom nom', 'Grammar Nazi: Although “dove” is a common form of the past tense of “dive,” a few authorities consider “dived” preferable in formal writing.', 'Grammar Nazi: An “epoch” is a long period of time, like the Pleistocene Epoch', 'Grammar Nazi: Pitfall, a hidden or unsuspected danger or difficulty.', 'Grammar Nazi: When you shift to a new topic or activity, you segue. Many people unfamiliar with the unusual Italian spelling of the word misspell it as “segway.” This error is being encouraged by the deliberately punning name used by the manufacturers of the Segway Human Transporter.', 'Grammar Nazi: Tiramisù is Italian for “pick me up,” and is the name of a popular modern Italian dessert, commonly misspelled as tirimisù, which gives it a slightly Japanese air. The Japanese love tiramisù, but although they sometimes make it with green tea rather than coffee this misspelling isn’t their fault.', 'Grammar Nazi: In formal fencing matches, when someone is hit by an opponent’s sword it is traditional for the person hit to cry out touché (French for “touched”) to acknowledge that fact. In other contexts, we may say touché when somebody scores a point against us in an argument, or otherwise skewers us verbally.', 'Grammar Nazi: “Xmas” is not originally an attempt to exclude Christ from Christmas, but uses an abbreviation of the Greek spelling of the word “Christ” with the “X” representing the Greek letter chi. However, so few people know this that it is probably better not to use this popular abbreviation in religious contexts. So quit your bitching!', 'Grammar Nazi: In some dialects it’s common to say “you’ve got a ways to go before you’ve saved enough to buy a Miata,” but in standard English it’s “a way to go.”', 'Grammar Nazi: Than is a comparision. Then is time based.', 'Grammar Nazi: If you’re dying you need help. If you’re dyeing clothes you might get dirty.', 'Grammar Nazi: '];
4493 var randomNumber = Math.floor(Math.random() * textArray.length);
4494 sendChat(textArray[randomNumber]);
4495
4496 } else if (cmd == cmdChar+"grammer" || cmd == cmdChar+"gramer" || cmd == cmdChar+"gramar") { //grammer command for fun
4497 var textArray = ['Close, but no cigar!', 'Nice going...', 'You moronic fool!', 'Even slurpy squid can spell grammar!', 'Grammar* You imbecile!', 'You sir, are not educated!', 'Did you wake up on the wrong side of the barn?', 'Are you daft?', 'I\'ll slap your mother!'];
4498 var randomNumber = Math.floor(Math.random() * textArray.length);
4499 sendChat(textArray[randomNumber]);
4500
4501 } else if (cmd == cmdChar+"joke") { //joke command
4502 var textArray = ['You can tune a piano but you can’t tuna fish.',
4503 'What sounds does a Bee make? A B#!', 'What do you get when you drop a piano on an army base? A flat major.',
4504 'A note left form a pianist for his wife: “Gone Chopin, (have Liszt), Bach in a Minuet.”',
4505 'What did the pianist say to a tightrope walker? You better C sharp or you’ll B flat.',
4506 'What do you call a fish musician? A piano tuna.',
4507 'Why was the pianist arrested? Because he got into treble.',
4508 'What’s the difference between a piano and an onion? No one cries when you chop up a piano.',
4509 'Did you hear about the circus fire? It was in tents! (Intense)', 'Two guys walk into a bar... the 3rd guy ducked.',
4510 'A blonde gets her haircut while wearing a pair of headphones. The hairdresser asks her to take them off, but she protests that she’ll die without them. The hairdresser sighs, and starts cutting the hair around the headphones. Soon, the blonde falls asleep, and the hairdresser removes the headphones. A few minutes later, the blonde collapses, dead on the floor. Alarmed, the hairdresser puts the headphones to his ear and hears, "Breathe in. Breathe out."',
4511 'Yo Mama’s so fat, it takes 2 trains and a bus to get to her good side.',
4512 'What do you get when you drop a piano down a mine shaft? A flat minor.',
4513 'What do you call a grizzly bear with no teeth? A gummy bear.',
4514 'it’s funny how after an argument is over you start to think about more clever shit you could have said.',
4515 'Wifi went down for five minutes, so I had to talk to my family. They seem like nice people.',
4516 'There are plenty of fish in the sea... too bad I suck at fishing.',
4517 'My friend thinks he is smart. He told me an onion is the only food that makes you cry, so I threw a coconut at his head.',
4518 'How much is this torture device, sir? That\'s a wedding ring...',
4519 'What did the drummer get on his I.Q. Test? Saliva.',
4520 'How does a bass player change a light bulb? He doesn’t. The pianist does it with his left hand.',
4521 'What do you call a beautiful woman on a trombonist’s arm? A tattoo.',
4522 'What is the dynamic range of a bass trombone? On or off.',
4523 'Why did the chicken cross the road? To get away from the bassoon recital.',
4524 'What’s the difference between a bass trombone and a chainsaw? It’s easier to improvise on a chainsaw.',
4525 'Why are a pianist’s fingers like lightning? Because they rarely strike the same place twice.',
4526 'What is Harry Potter’s favourite mint? Dementoes.',
4527 'Give a man a fire and he is warm for a day. Set a man on fire and he is warm for the rest of his life* Quote by Terry Pratchett, Famous author',
4528 'What do you call a Jewish pokémon trainer? Ash.',
4529 'What if a girls tonsils were ticklish and when she was giving you head she laughed non stop?',
4530 'I used to be a banker but I lost interest.',
4531 'I’m glad I know sign language, it’s pretty handy.',
4532 'I couldn’t quite remember how to throw a boomerang, but eventually it came back to me.',
4533 'I don’t trust these stairs because they’re always up to something.',
4534 'Why was the painter killed? He dyed in a car accident.',
4535 '[Patient] Doctor, doctor! People keep Ignoring me! [Doctor] Next patient, please.',
4536 'Why did the sperm cross the road? I accidently put on the wrong sock.',
4537 'I\'m guaranteed to shag the missus up the arse tonight. She\'s dyslexic and thinks it\'s Vaseline Day.',
4538 'You can\'t spell "therapist" without "rapist".',
4539 'If you ever visit the amazon rain forest don\'t forget to cut down shit tons of trees. New studies show that trees block sunlight from animals']; //’ (apostrophe) //Thanks to various people giving me some awesome jokes on MPP!
4540 var randomNumber = Math.floor(Math.random() * textArray.length);
4541 sendChat(textArray[randomNumber]);
4542
4543
4544 //Music theory by Logan
4545 //It's not very optimised and takes up way too much space. I'm not sure how to make it more compact.
4546 //chords
4547 } else if (message.substring(0, 13).toLowerCase() == cmdChar+"music theory" || cmd == cmdChar+"mt") { //music theory command
4548 sendChat("Music Theory Index: "+cmdChar+"chords (list of chords), "+cmdChar+"scales (list of scales C-G), "+cmdChar+"scales2 (list of scales Ab-X), "+cmdChar+"glossary (music terminology) [Unfinished!!]");
4549
4550 } else if (cmd == cmdChar+"chords") { //Chords
4551 sendChat("Chords Index: "+cmdChar+"cmajor, "+cmdChar+"cminor, "+cmdChar+"cmaj7, "+cmdChar+"cmin7, "+cmdChar+"cminmaj, "+cmdChar+"cdom7, "+cmdChar+"cdom7sus4, "+cmdChar+"cdim, "+cmdChar+"cdim7, "+cmdChar+"chalfdim, "+cmdChar+"caug, "+cmdChar+"caug7, "+cmdChar+"caugmaj7, "+cmdChar+"csus2, "+cmdChar+"csus4 [Unfinished!!]");
4552
4553 } else if (cmd == cmdChar+"cmajor") { //C major
4554 sendChat("A major triad is a chord having a root, a major third, and a perfect fifth.");
4555 sendChat("C major triad PC notes - etu");
4556 {setTimeout(function() { press("c2"); press("e2"); press("g2") }, 0);}
4557 {setTimeout(function() { press("c2"); press("e2"); press("g2") }, 3000);}
4558 {setTimeout(function() { press("c2")}, 5000);}
4559 {setTimeout(function() { press("e2")}, 6000);}
4560 {setTimeout(function() { press("g2")}, 7000);}
4561
4562
4563 } else if (cmd == cmdChar+"cdom7") { //C Dominant seventh
4564 sendChat("A dominant seventh chord is a chord composed of a root, major third, perfect fifth, and minor seventh. It can be also viewed as a major triad with an additional minor seventh.");
4565 sendChat("C7 PC notes - etu9");
4566 {setTimeout(function() { press("c2"); press("e2"); press("g2"); press("as2") }, 0);}
4567 {setTimeout(function() { press("c2"); press("e2"); press("g2"); press("as2") }, 3000);}
4568 {setTimeout(function() { press("c2")}, 5000);}
4569 {setTimeout(function() { press("e2")}, 6000);}
4570 {setTimeout(function() { press("g2")}, 7000);}
4571 {setTimeout(function() { press("as2")}, 8000);}
4572
4573 } else if (cmd == cmdChar+"cdom7sus4") { //C Dominant seventh suspended 4th
4574 sendChat("A dominant seventh suspended 4th chord is a chord composed of a root, perfect fourth, perfect fifth, and minor seventh.");
4575 sendChat("C7(sus) PC notes - eyu9");
4576 {setTimeout(function() { press("c2"); press("f2"); press("g2"); press("as2") }, 0);}
4577 {setTimeout(function() { press("c2"); press("f2"); press("g2"); press("as2") }, 3000);}
4578 {setTimeout(function() { press("c2")}, 5000);}
4579 {setTimeout(function() { press("f2")}, 6000);}
4580 {setTimeout(function() { press("g2")}, 7000);}
4581 {setTimeout(function() { press("as2")}, 8000);}
4582
4583 } else if (cmd == cmdChar+"cmaj7") { //C major seventh
4584 sendChat("A major seventh chord is a seventh chord where the \"third\" note is a major third above the root, and the \"seventh\" note is a major seventh above the root (a fifth above the third note).");
4585 sendChat("Cmaj7 PC notes - etuo");
4586 {setTimeout(function() { press("c2"); press("e2"); press("g2"); press("b2") }, 0);}
4587 {setTimeout(function() { press("c2"); press("e2"); press("g2"); press("b2") }, 3000);}
4588 {setTimeout(function() { press("c2")}, 5000);}
4589 {setTimeout(function() { press("e2")}, 6000);}
4590 {setTimeout(function() { press("g2")}, 7000);}
4591 {setTimeout(function() { press("b2")}, 8000);}
4592
4593 } else if (cmd == cmdChar+"cminor") { //C minor
4594 sendChat("A minor triad is a chord having a root, a minor third, and a perfect fifth.");
4595 sendChat("C minor triad PC notes - e5u");
4596 {setTimeout(function() { press("c2"); press("ds2"); press("g2") }, 0);}
4597 {setTimeout(function() { press("c2"); press("ds2"); press("g2") }, 3000);}
4598 {setTimeout(function() { press("c2")}, 5000);}
4599 {setTimeout(function() { press("ds2")}, 6000);}
4600 {setTimeout(function() { press("g2")}, 7000);}
4601
4602 } else if (cmd == cmdChar+"cmin7") { //C minor seventh
4603 sendChat("A minor seventh chord is any non-dominant seventh chord where the \"third\" note is a minor third above the root.");
4604 sendChat("Cmin7 PC notes - e5u9");
4605 {setTimeout(function() { press("c2"); press("ds2"); press("g2"); press("as2") }, 0);}
4606 {setTimeout(function() { press("c2"); press("ds2"); press("g2"); press("as2") }, 3000);}
4607 {setTimeout(function() { press("c2")}, 5000);}
4608 {setTimeout(function() { press("ds2")}, 6000);}
4609 {setTimeout(function() { press("g2")}, 7000);}
4610 {setTimeout(function() { press("as2")}, 8000);}
4611
4612 } else if (cmd == cmdChar+"cminmaj") { //C minor major seventh
4613 sendChat("The minor major seventh chord is a diatonic non-dominant seventh chord in the harmonic minor scale. The chord is built on a root, with the intervals of a minor third, a major third above that note and above that a major third");
4614 sendChat("Cminmaj PC notes - e5uo");
4615 {setTimeout(function() { press("c2"); press("ds2"); press("g2"); press("b2") }, 0);}
4616 {setTimeout(function() { press("c2"); press("ds2"); press("g2"); press("b2") }, 3000);}
4617 {setTimeout(function() { press("c2")}, 5000);}
4618 {setTimeout(function() { press("ds2")}, 6000);}
4619 {setTimeout(function() { press("g2")}, 7000);}
4620 {setTimeout(function() { press("b2")}, 8000);}
4621
4622 } else if (cmd == cmdChar+"cdim") { //C diminished
4623 sendChat("A diminished triad is a triad consisting of two minor thirds above the root.");
4624 sendChat("C diminished triad PC notes - e57");
4625 {setTimeout(function() { press("c2"); press("ds2"); press("fs2") }, 0);}
4626 {setTimeout(function() { press("c2"); press("ds2"); press("fs2") }, 3000);}
4627 {setTimeout(function() { press("c2")}, 5000);}
4628 {setTimeout(function() { press("ds2")}, 6000);}
4629 {setTimeout(function() { press("fs2")}, 7000);}
4630
4631 } else if (cmd == cmdChar+"cdim7") { //C diminished seventh
4632 sendChat("A diminished seventh is an interval produced by narrowing a minor seventh by a chromatic semitone.");
4633 sendChat("Cdim7 PC notes - e57i (this is my favourite chord)");
4634 {setTimeout(function() { press("c2"); press("ds2"); press("fs2"); press("a2") }, 0);}
4635 {setTimeout(function() { press("c2"); press("ds2"); press("fs2"); press("a2") }, 3000);}
4636 {setTimeout(function() { press("c2")}, 5000);}
4637 {setTimeout(function() { press("ds2")}, 6000);}
4638 {setTimeout(function() { press("fs2")}, 7000);}
4639 {setTimeout(function() { press("a2")}, 8000);}
4640
4641 } else if (cmd == cmdChar+"chalfdim") { //C half diminished
4642 sendChat("A half diminished chord is composed by a root note, together with a minor third, a diminished fifth and a minor seventh from root.");
4643 sendChat("Chalfdim PC notes - e579");
4644 {setTimeout(function() { press("c2"); press("ds2"); press("fs2"); press("as2") }, 0);}
4645 {setTimeout(function() { press("c2"); press("ds2"); press("fs2"); press("as2") }, 3000);}
4646 {setTimeout(function() { press("c2")}, 5000);}
4647 {setTimeout(function() { press("ds2")}, 6000);}
4648 {setTimeout(function() { press("fs2")}, 7000);}
4649 {setTimeout(function() { press("as2")}, 8000);}
4650
4651
4652 } else if (cmd == cmdChar+"caug") { //C Augmented
4653 sendChat("An augmented triad is a triad, or chord, consisting of two major thirds (an augmented fifth).");
4654 sendChat("C augmented triad PC notes - et8 (second favourite chord)");
4655 {setTimeout(function() { press("c2"); press("e2"); press("gs2") }, 0);}
4656 {setTimeout(function() { press("c2"); press("e2"); press("gs2") }, 3000);}
4657 {setTimeout(function() { press("c2")}, 5000);}
4658 {setTimeout(function() { press("e2")}, 6000);}
4659 {setTimeout(function() { press("gs2")}, 7000);}
4660
4661 } else if (cmd == cmdChar+"caug7") { //C Augmented seventh
4662 sendChat("An augmented seventh chord is a dominant seventh chord consisting of an augmented triad with a minor seventh.");
4663 sendChat("Caug7 PC notes - et89");
4664 {setTimeout(function() { press("c2"); press("e2"); press("gs2"); press("as2") }, 0);}
4665 {setTimeout(function() { press("c2"); press("e2"); press("gs2"); press("as2") }, 3000);}
4666 {setTimeout(function() { press("c2")}, 5000);}
4667 {setTimeout(function() { press("e2")}, 6000);}
4668 {setTimeout(function() { press("gs2")}, 7000);}
4669 {setTimeout(function() { press("as2")}, 8000);}
4670
4671 } else if (cmd == cmdChar+"caugmaj7") { //C Augmented major seventh
4672 sendChat("An augmented major seventh chord is a nondominant seventh chord and is associated with the augmented scale.");
4673 sendChat("Caugmaj7 PC notes - et8o");
4674 {setTimeout(function() { press("c2"); press("e2"); press("gs2"); press("b2") }, 0);}
4675 {setTimeout(function() { press("c2"); press("e2"); press("gs2"); press("b2") }, 3000);}
4676 {setTimeout(function() { press("c2")}, 5000);}
4677 {setTimeout(function() { press("e2")}, 6000);}
4678 {setTimeout(function() { press("gs2")}, 7000);}
4679 {setTimeout(function() { press("b2")}, 8000);}
4680
4681 } else if (cmd == cmdChar+"csus2") { //C suspended second
4682 sendChat("A suspended second chord (sus2 chord) is a musical chord in which the (major or minor) third is omitted and replaced with a major second.");
4683 sendChat("Csus2 PC notes - eru");
4684 {setTimeout(function() { press("c2"); press("d2"); press("g2") }, 0);}
4685 {setTimeout(function() { press("c2"); press("d2"); press("g2") }, 3000);}
4686 {setTimeout(function() { press("c2")}, 5000);}
4687 {setTimeout(function() { press("d2")}, 6000);}
4688 {setTimeout(function() { press("g2")}, 7000);}
4689
4690 } else if (cmd == cmdChar+"csus4") { //C suspended fourth
4691 sendChat("A suspended fourth chord (sus4 chord or usually referred to as just sus) is a musical chord in which the (major or minor) third is omitted and replaced with a perfect fourth.");
4692 sendChat("Csus PC notes - eyu");
4693 {setTimeout(function() { press("c2"); press("f2"); press("g2") }, 0);}
4694 {setTimeout(function() { press("c2"); press("f2"); press("g2") }, 3000);}
4695 {setTimeout(function() { press("c2")}, 5000);}
4696 {setTimeout(function() { press("f2")}, 6000);}
4697 {setTimeout(function() { press("g2")}, 7000);}
4698 //chords
4699
4700 //scales
4701 } else if (cmd == cmdChar+"scales") { //Scales
4702 sendChat("Scales Index C-F#: "+cmdChar+"scale cmajor, "+cmdChar+"scale cminor, "+cmdChar+"scale charminor, "+cmdChar+"scale cmelminor, "+cmdChar+"scale csmajor, "+cmdChar+"scale csminor, "+cmdChar+"scale csharminor, "+cmdChar+"scale csmelminor, "+cmdChar+"scale dmajor, "+cmdChar+"scale dminor, "+cmdChar+"scale dharminor, "+cmdChar+"scale dmelminor, "+cmdChar+"scale ebmajor, "+cmdChar+"scale ebminor, "+cmdChar+"scale ebharminor, "+cmdChar+"scale ebmelminor, "+cmdChar+"scale emajor, "+cmdChar+"scale eminor, "+cmdChar+"scale eharminor, "+cmdChar+"scale emelminor, "+cmdChar+"scale fmajor, "+cmdChar+"scale fminor, "+cmdChar+"scale fharminor, "+cmdChar+"scale fmelminor, "+cmdChar+"scale fsmajor, "+cmdChar+"scale fsminor, "+cmdChar+"scale fsharminor, "+cmdChar+"scale fsmelminor");
4703
4704 } else if (cmd == cmdChar+"scales2") { //Scales 2
4705 sendChat("Scales Index 2 G-B: "+cmdChar+"scale gmajor, "+cmdChar+"scale gminor, "+cmdChar+"scale gharminor, "+cmdChar+"scale gmelminor "+cmdChar+"scale abmajor, "+cmdChar+"scale abminor, "+cmdChar+"scale abharminor, "+cmdChar+"scale abmelminor, "+cmdChar+"scale amajor, "+cmdChar+"scale aminor, "+cmdChar+"scale aharminor, "+cmdChar+"scale amelminor, "+cmdChar+"scale bbmajor, "+cmdChar+"scale bbminor, "+cmdChar+"scale bbharminor, "+cmdChar+"scale bbmelminor, "+cmdChar+"scale bmajor, "+cmdChar+"scale bminor, "+cmdChar+"scale bharminor, "+cmdChar+"scale bmelminor");
4706
4707 //C scales
4708 } else if (message.substring(0, 13).toLowerCase() == cmdChar+"scale cmajor") { //C major scale
4709 sendChat("The C major scale - it has no flats or sharps - its relative minor is A");
4710 sendChat("The C major PC notes - e r t y u i o p");
4711 {setTimeout(function() { press("c2")}, 0);}
4712 {setTimeout(function() { press("d2")}, 250);}
4713 {setTimeout(function() { press("e2")}, 500);}
4714 {setTimeout(function() { press("f2")}, 750);}
4715 {setTimeout(function() { press("g2")}, 1000);}
4716 {setTimeout(function() { press("a2")}, 1250);}
4717 {setTimeout(function() { press("b2")}, 1500);}
4718 {setTimeout(function() { press("c3")}, 1750);}
4719 {setTimeout(function() { press("b2")}, 2000);}
4720 {setTimeout(function() { press("a2")}, 2250);}
4721 {setTimeout(function() { press("g2")}, 2500);}
4722 {setTimeout(function() { press("f2")}, 2750);}
4723 {setTimeout(function() { press("e2")}, 3000);}
4724 {setTimeout(function() { press("d2")}, 3250);}
4725 {setTimeout(function() { press("c2")}, 3500);}
4726 {setTimeout(function() { press("c2"); press("e2"); press("g2"); press("c3")}, 4000);}
4727
4728 } else if (message.substring(0, 13).toLowerCase() == cmdChar+"scale cminor") { //C minor scale
4729 sendChat("The C minor scale - it has 3 flats - its relative major is Eb");
4730 sendChat("The C minor PC notes - e r 5 y u 8 9 p");
4731 var scale_cminor = [[0,"c2"],[250,"d2"],[250,"ds2"],[250,"f2"],[250,"g2"],[250,"gs2"],[250,"as2"],[250,"c3"],[250,"as2"],[250,"gs2"],[250,"g2"],[250,"f2"],[250,"ds2"],[250,"d2"],[250,"c2"]];
4732 var playID = 0;
4733
4734 function playMisc(arr){
4735 //if(playID != 0){clearInterval(playID);}
4736 if(playID != 0) {clearTimeout(playID);playID=0}
4737 var pNum = 0;
4738 var f = function () {
4739 for(var p=1; p<arr[pNum].length; p++){
4740 MPP.press(arr[pNum][p]);
4741 }
4742 if(++pNum >= arr.length) {clearTimeout(playID);playID=0;return;}
4743 setTimeout(f,arr[pNum][0]);
4744 }
4745 setTimeout(f,arr[pNum][0]);
4746 }
4747
4748 //test Play
4749 playMisc(scale_cminor);
4750
4751 } else if (message.substring(0, 16).toLowerCase() == cmdChar+"scale charminor") { //C harmonic minor scale
4752 sendChat("The C harmonic minor scale - it has 2 flats - it has a major 7th (B)");
4753 sendChat("The C harmonic minor PC notes - e r 5 y u 8 o p");
4754 {setTimeout(function() { press("c2")}, 0);}
4755 {setTimeout(function() { press("d2")}, 250);}
4756 {setTimeout(function() { press("ds2")}, 500);}
4757 {setTimeout(function() { press("f2")}, 750);}
4758 {setTimeout(function() { press("g2")}, 1000);}
4759 {setTimeout(function() { press("gs2")}, 1250);}
4760 {setTimeout(function() { press("b2")}, 1500);}
4761 {setTimeout(function() { press("c3")}, 1750);}
4762 {setTimeout(function() { press("b2")}, 2000);}
4763 {setTimeout(function() { press("gs2")}, 2250);}
4764 {setTimeout(function() { press("g2")}, 2500);}
4765 {setTimeout(function() { press("f2")}, 2750);}
4766 {setTimeout(function() { press("ds2")}, 3000);}
4767 {setTimeout(function() { press("d2")}, 3250);}
4768 {setTimeout(function() { press("c2")}, 3500);}
4769 {setTimeout(function() { press("c2"); press("ds2"); press("g2"); press("c3")}, 4000);}
4770
4771 } else if (message.substring(0, 16).toLowerCase() == cmdChar+"scale cmelminor") { //C melodic minor scale
4772 sendChat("The C melodic minor scale - it has 1 flat ascending and 3 flats descending - it has two patterns ascending and descending.");
4773 sendChat("The C melodic minor PC notes - e r 5 y u i o p 9 8 u y 5 r e");
4774 {setTimeout(function() { press("c2")}, 0);}
4775 {setTimeout(function() { press("d2")}, 250);}
4776 {setTimeout(function() { press("ds2")}, 500);}
4777 {setTimeout(function() { press("f2")}, 750);}
4778 {setTimeout(function() { press("g2")}, 1000);}
4779 {setTimeout(function() { press("a2")}, 1250);}
4780 {setTimeout(function() { press("b2")}, 1500);}
4781 {setTimeout(function() { press("c3")}, 1750);}
4782 {setTimeout(function() { press("as2")}, 2000);}
4783 {setTimeout(function() { press("gs2")}, 2250);}
4784 {setTimeout(function() { press("g2")}, 2500);}
4785 {setTimeout(function() { press("f2")}, 2750);}
4786 {setTimeout(function() { press("ds2")}, 3000);}
4787 {setTimeout(function() { press("d2")}, 3250);}
4788 {setTimeout(function() { press("c2")}, 3500);}
4789 {setTimeout(function() { press("c2"); press("ds2"); press("g2"); press("c3")}, 4000);}
4790 //C scales
4791
4792 //C# scales
4793 } else if (message.substring(0, 14).toLowerCase() == cmdChar+"scale csmajor") { //C# major scale
4794 sendChat("The C# (sharp) major scale - it has 7 sharps - its relative minor is A#");
4795 sendChat("The C# (sharp) major PC notes - 4 5 y 7 8 9 p -");
4796 {setTimeout(function() { press("cs2")}, 0);}
4797 {setTimeout(function() { press("ds2")}, 250);}
4798 {setTimeout(function() { press("f2")}, 500);}
4799 {setTimeout(function() { press("fs2")}, 750);}
4800 {setTimeout(function() { press("gs2")}, 1000);}
4801 {setTimeout(function() { press("as2")}, 1250);}
4802 {setTimeout(function() { press("c3")}, 1500);}
4803 {setTimeout(function() { press("cs3")}, 1750);}
4804 {setTimeout(function() { press("c3")}, 2000);}
4805 {setTimeout(function() { press("as2")}, 2250);}
4806 {setTimeout(function() { press("gs2")}, 2500);}
4807 {setTimeout(function() { press("fs2")}, 2750);}
4808 {setTimeout(function() { press("f2")}, 3000);}
4809 {setTimeout(function() { press("ds2")}, 3250);}
4810 {setTimeout(function() { press("cs2")}, 3500);}
4811 {setTimeout(function() { press("cs2"); press("f2"); press("gs2"); press("cs3")}, 4000);}
4812
4813 } else if (message.substring(0, 14).toLowerCase() == cmdChar+"scale csminor") { //C# minor scale
4814 sendChat("The C# (sharp) minor scale - it has 4 sharps - its relative major is E");
4815 sendChat("The C# (sharp) major PC notes - f g b j k q . 4");
4816 {setTimeout(function() { press("cs2")}, 0);}
4817 {setTimeout(function() { press("ds2")}, 250);}
4818 {setTimeout(function() { press("e2")}, 500);}
4819 {setTimeout(function() { press("fs2")}, 750);}
4820 {setTimeout(function() { press("gs2")}, 1000);}
4821 {setTimeout(function() { press("a2")}, 1250);}
4822 {setTimeout(function() { press("b2")}, 1500);}
4823 {setTimeout(function() { press("cs3")}, 1750);}
4824 {setTimeout(function() { press("b2")}, 2000);}
4825 {setTimeout(function() { press("a2")}, 2250);}
4826 {setTimeout(function() { press("gs2")}, 2500);}
4827 {setTimeout(function() { press("fs2")}, 2750);}
4828 {setTimeout(function() { press("e2")}, 3000);}
4829 {setTimeout(function() { press("ds2")}, 3250);}
4830 {setTimeout(function() { press("cs2")}, 3500);}
4831 {setTimeout(function() { press("cs2"); press("e2"); press("gs2"); press("cs3")}, 4000);}
4832
4833 } else if (message.substring(0, 17).toLowerCase() == cmdChar+"scale csharminor") { //C# harmonic minor scale
4834 sendChat("The C# (sharp) harmonic minor scale - it has 2 flats - it has a major 7th (C)");
4835 sendChat("The C# (sharp) harmonic minor PC notes - 4 5 t 7 8 i p -");
4836 {setTimeout(function() { press("cs2")}, 0);}
4837 {setTimeout(function() { press("ds2")}, 250);}
4838 {setTimeout(function() { press("e2")}, 500);}
4839 {setTimeout(function() { press("fs2")}, 750);}
4840 {setTimeout(function() { press("gs2")}, 1000);}
4841 {setTimeout(function() { press("a2")}, 1250);}
4842 {setTimeout(function() { press("c3")}, 1500);}
4843 {setTimeout(function() { press("cs3")}, 1750);}
4844 {setTimeout(function() { press("c3")}, 2000);}
4845 {setTimeout(function() { press("a2")}, 2250);}
4846 {setTimeout(function() { press("gs2")}, 2500);}
4847 {setTimeout(function() { press("fs2")}, 2750);}
4848 {setTimeout(function() { press("e2")}, 3000);}
4849 {setTimeout(function() { press("ds2")}, 3250);}
4850 {setTimeout(function() { press("cs2")}, 3500);}
4851 {setTimeout(function() { press("cs2"); press("e2"); press("gs2"); press("cs3")}, 4000);}
4852
4853 } else if (message.substring(0, 17).toLowerCase() == cmdChar+"scale csmelminor") { //C# melodic minor scale
4854 sendChat("The C# (sharp) melodic minor scale - it has 7 sharps ascending and 5 sharps descending - it has two patterns ascending and descending.");
4855 sendChat("The C# (sharp) melodic minor PC notes - 4 5 t 7 8 9 p - o i 8 7 t 5 4");
4856 {setTimeout(function() { press("cs2")}, 0);}
4857 {setTimeout(function() { press("ds2")}, 250);}
4858 {setTimeout(function() { press("e2")}, 500);}
4859 {setTimeout(function() { press("fs2")}, 750);}
4860 {setTimeout(function() { press("gs2")}, 1000);}
4861 {setTimeout(function() { press("as2")}, 1250);}
4862 {setTimeout(function() { press("c3")}, 1500);}
4863 {setTimeout(function() { press("cs3")}, 1750);}
4864 {setTimeout(function() { press("b2")}, 2000);}
4865 {setTimeout(function() { press("a2")}, 2250);}
4866 {setTimeout(function() { press("gs2")}, 2500);}
4867 {setTimeout(function() { press("fs2")}, 2750);}
4868 {setTimeout(function() { press("e2")}, 3000);}
4869 {setTimeout(function() { press("ds2")}, 3250);}
4870 {setTimeout(function() { press("cs2")}, 3500);}
4871 {setTimeout(function() { press("cs2"); press("e2"); press("gs2"); press("cs3")}, 4000);}
4872 //C# scales
4873
4874 //D scales
4875 } else if (message.substring(0, 13).toLowerCase() == cmdChar+"scale dmajor") { //D major scale
4876 sendChat("The D major scale - it has 2 sharps - its relative minor is B");
4877 sendChat("The D major scale PC notes - r t 7 u i o - [");
4878 {setTimeout(function() { press("d2")}, 0);}
4879 {setTimeout(function() { press("e2")}, 250);}
4880 {setTimeout(function() { press("fs2")}, 500);}
4881 {setTimeout(function() { press("g2")}, 750);}
4882 {setTimeout(function() { press("a2")}, 1000);}
4883 {setTimeout(function() { press("b2")}, 1250);}
4884 {setTimeout(function() { press("cs3")}, 1500);}
4885 {setTimeout(function() { press("d3")}, 1750);}
4886 {setTimeout(function() { press("cs3")}, 2000);}
4887 {setTimeout(function() { press("b2")}, 2250);}
4888 {setTimeout(function() { press("a2")}, 2500);}
4889 {setTimeout(function() { press("g2")}, 2750);}
4890 {setTimeout(function() { press("fs2")}, 3000);}
4891 {setTimeout(function() { press("e2")}, 3250);}
4892 {setTimeout(function() { press("d2")}, 3500);}
4893 {setTimeout(function() { press("d2"); press("fs2"); press("a2"); press("d3")}, 4000);}
4894
4895 } else if (message.substring(0, 13).toLowerCase() == cmdChar+"scale dminor") { //D minor scale
4896 sendChat("The D minor scale - it has 2 sharps - its relative major is F");
4897 sendChat("The D minor scale PC notes - r t 7 u i o - [");
4898 {setTimeout(function() { press("d2")}, 0);}
4899 {setTimeout(function() { press("e2")}, 250);}
4900 {setTimeout(function() { press("f2")}, 500);}
4901 {setTimeout(function() { press("g2")}, 750);}
4902 {setTimeout(function() { press("a2")}, 1000);}
4903 {setTimeout(function() { press("as2")}, 1250);}
4904 {setTimeout(function() { press("c3")}, 1500);}
4905 {setTimeout(function() { press("d3")}, 1750);}
4906 {setTimeout(function() { press("c3")}, 2000);}
4907 {setTimeout(function() { press("as2")}, 2250);}
4908 {setTimeout(function() { press("a2")}, 2500);}
4909 {setTimeout(function() { press("g2")}, 2750);}
4910 {setTimeout(function() { press("f2")}, 3000);}
4911 {setTimeout(function() { press("e2")}, 3250);}
4912 {setTimeout(function() { press("d2")}, 3500);}
4913 {setTimeout(function() { press("d2"); press("f2"); press("a2"); press("d3")}, 4000);}
4914
4915 } else if (message.substring(0, 16).toLowerCase() == cmdChar+"scale dharminor") { //D harmonic minor scale
4916 sendChat("The D harmonic minor scale - it has 2 sharps - it has a major 7th (C#)");
4917 {setTimeout(function() { press("d2")}, 0);}
4918 {setTimeout(function() { press("e2")}, 250);}
4919 {setTimeout(function() { press("f2")}, 500);}
4920 {setTimeout(function() { press("g2")}, 750);}
4921 {setTimeout(function() { press("a2")}, 1000);}
4922 {setTimeout(function() { press("as2")}, 1250);}
4923 {setTimeout(function() { press("cs3")}, 1500);}
4924 {setTimeout(function() { press("d3")}, 1750);}
4925 {setTimeout(function() { press("cs3")}, 2000);}
4926 {setTimeout(function() { press("as2")}, 2250);}
4927 {setTimeout(function() { press("a2")}, 2500);}
4928 {setTimeout(function() { press("g2")}, 2750);}
4929 {setTimeout(function() { press("f2")}, 3000);}
4930 {setTimeout(function() { press("e2")}, 3250);}
4931 {setTimeout(function() { press("d2")}, 3500);}
4932 {setTimeout(function() { press("d2"); press("f2"); press("a2"); press("d3")}, 4000);}
4933
4934 } else if (message.substring(0, 16).toLowerCase() == cmdChar+"scale dmelminor") { //D melodic minor scale
4935 sendChat("The D melodic minor scale - it has 1 flat ascending and 3 flats descending - it has two patterns ascending and descending.");
4936 {setTimeout(function() { press("d2")}, 0);}
4937 {setTimeout(function() { press("e2")}, 250);}
4938 {setTimeout(function() { press("f2")}, 500);}
4939 {setTimeout(function() { press("g2")}, 750);}
4940 {setTimeout(function() { press("a2")}, 1000);}
4941 {setTimeout(function() { press("b2")}, 1250);}
4942 {setTimeout(function() { press("cs3")}, 1500);}
4943 {setTimeout(function() { press("d3")}, 1750);}
4944 {setTimeout(function() { press("c3")}, 2000);}
4945 {setTimeout(function() { press("as2")}, 2250);}
4946 {setTimeout(function() { press("a2")}, 2500);}
4947 {setTimeout(function() { press("g2")}, 2750);}
4948 {setTimeout(function() { press("f2")}, 3000);}
4949 {setTimeout(function() { press("e2")}, 3250);}
4950 {setTimeout(function() { press("d2")}, 3500);}
4951 {setTimeout(function() { press("d2"); press("f2"); press("a2"); press("d3")}, 4000);}
4952 //D scales
4953
4954 //Eb scales
4955 } else if (message.substring(0, 14).toLowerCase() == cmdChar+"scale ebmajor") { //Eb major scale
4956 sendChat("The Eb (flat) major scale - it has 3 flats - its relative minor is C");
4957 {setTimeout(function() { press("ds2")}, 0);}
4958 {setTimeout(function() { press("f2")}, 250);}
4959 {setTimeout(function() { press("g2")}, 500);}
4960 {setTimeout(function() { press("gs2")}, 750);}
4961 {setTimeout(function() { press("as2")}, 1000);}
4962 {setTimeout(function() { press("c3")}, 1250);}
4963 {setTimeout(function() { press("d3")}, 1500);}
4964 {setTimeout(function() { press("ds3")}, 1750);}
4965 {setTimeout(function() { press("d3")}, 2000);}
4966 {setTimeout(function() { press("c3")}, 2250);}
4967 {setTimeout(function() { press("as2")}, 2500);}
4968 {setTimeout(function() { press("gs2")}, 2750);}
4969 {setTimeout(function() { press("g2")}, 3000);}
4970 {setTimeout(function() { press("f2")}, 3250);}
4971 {setTimeout(function() { press("ds2")}, 3500);}
4972 {setTimeout(function() { press("ds2"); press("g2"); press("as2"); press("ds3")}, 4000);}
4973
4974 } else if (message.substring(0, 14).toLowerCase() == cmdChar+"scale ebminor") { //Eb minor scale
4975 sendChat("The Eb (flat) minor scale - it has 6 flats - its relative major is Gb");
4976 {setTimeout(function() { press("ds2")}, 0);}
4977 {setTimeout(function() { press("f2")}, 250);}
4978 {setTimeout(function() { press("fs2")}, 500);}
4979 {setTimeout(function() { press("gs2")}, 750);}
4980 {setTimeout(function() { press("as2")}, 1000);}
4981 {setTimeout(function() { press("b2")}, 1250);}
4982 {setTimeout(function() { press("cs3")}, 1500);}
4983 {setTimeout(function() { press("ds3")}, 1750);}
4984 {setTimeout(function() { press("cs3")}, 2000);}
4985 {setTimeout(function() { press("b2")}, 2250);}
4986 {setTimeout(function() { press("as2")}, 2500);}
4987 {setTimeout(function() { press("gs2")}, 2750);}
4988 {setTimeout(function() { press("fs2")}, 3000);}
4989 {setTimeout(function() { press("f2")}, 3250);}
4990 {setTimeout(function() { press("ds2")}, 3500);}
4991 {setTimeout(function() { press("ds2"); press("fs2"); press("as2"); press("ds3")}, 4000);}
4992
4993 } else if (message.substring(0, 17).toLowerCase() == cmdChar+"scale ebharminor") { //Eb harmonic minor scale
4994 sendChat("The Eb (flat) harmonic minor scale - it has 5 flats - it has a major 7th (D)");
4995 {setTimeout(function() { press("ds2")}, 0);}
4996 {setTimeout(function() { press("f2")}, 250);}
4997 {setTimeout(function() { press("fs2")}, 500);}
4998 {setTimeout(function() { press("gs2")}, 750);}
4999 {setTimeout(function() { press("as2")}, 1000);}
5000 {setTimeout(function() { press("b2")}, 1250);}
5001 {setTimeout(function() { press("d3")}, 1500);}
5002 {setTimeout(function() { press("ds3")}, 1750);}
5003 {setTimeout(function() { press("d3")}, 2000);}
5004 {setTimeout(function() { press("b2")}, 2250);}
5005 {setTimeout(function() { press("as2")}, 2500);}
5006 {setTimeout(function() { press("gs2")}, 2750);}
5007 {setTimeout(function() { press("fs2")}, 3000);}
5008 {setTimeout(function() { press("f2")}, 3250);}
5009 {setTimeout(function() { press("ds2")}, 3500);}
5010 {setTimeout(function() { press("ds2"); press("fs2"); press("as2"); press("ds3")}, 4000);}
5011
5012 } else if (message.substring(0, 17).toLowerCase() == cmdChar+"scale ebmelminor") { //Eb melodic minor scale
5013 sendChat("The Eb (flat) melodic minor scale - it has 5 flats ascending and 6 flats descending - it has two patterns ascending and descending.");
5014 {setTimeout(function() { press("ds2")}, 0);}
5015 {setTimeout(function() { press("f2")}, 250);}
5016 {setTimeout(function() { press("fs2")}, 500);}
5017 {setTimeout(function() { press("gs2")}, 750);}
5018 {setTimeout(function() { press("as2")}, 1000);}
5019 {setTimeout(function() { press("c3")}, 1250);}
5020 {setTimeout(function() { press("d3")}, 1500);}
5021 {setTimeout(function() { press("ds3")}, 1750);}
5022 {setTimeout(function() { press("cs3")}, 2000);}
5023 {setTimeout(function() { press("b2")}, 2250);}
5024 {setTimeout(function() { press("as2")}, 2500);}
5025 {setTimeout(function() { press("gs2")}, 2750);}
5026 {setTimeout(function() { press("fs2")}, 3000);}
5027 {setTimeout(function() { press("f2")}, 3250);}
5028 {setTimeout(function() { press("ds2")}, 3500);}
5029 {setTimeout(function() { press("ds2"); press("fs2"); press("as2"); press("ds3")}, 4000);}
5030 //Eb scales
5031
5032 //E scales
5033 } else if (message.substring(0, 13).toLowerCase() == cmdChar+"scale emajor") { //E major scale
5034 sendChat("The E major scale - it has 4 sharps - its relative minor is C#");
5035 {setTimeout(function() { press("e2")}, 0);}
5036 {setTimeout(function() { press("fs2")}, 250);}
5037 {setTimeout(function() { press("gs2")}, 500);}
5038 {setTimeout(function() { press("a2")}, 750);}
5039 {setTimeout(function() { press("b2")}, 1000);}
5040 {setTimeout(function() { press("cs3")}, 1250);}
5041 {setTimeout(function() { press("ds3")}, 1500);}
5042 {setTimeout(function() { press("e3")}, 1750);}
5043 {setTimeout(function() { press("ds3")}, 2000);}
5044 {setTimeout(function() { press("cs3")}, 2250);}
5045 {setTimeout(function() { press("b2")}, 2500);}
5046 {setTimeout(function() { press("a2")}, 2750);}
5047 {setTimeout(function() { press("gs2")}, 3000);}
5048 {setTimeout(function() { press("fs2")}, 3250);}
5049 {setTimeout(function() { press("e2")}, 3500);}
5050 {setTimeout(function() { press("e2"); press("gs2"); press("b2"); press("e3")}, 4000);}
5051
5052 } else if (message.substring(0, 13).toLowerCase() == cmdChar+"scale eminor") { //E minor scale
5053 sendChat("The E minor scale - it has 1 sharp - its relative major is G");
5054 {setTimeout(function() { press("e2")}, 0);}
5055 {setTimeout(function() { press("fs2")}, 250);}
5056 {setTimeout(function() { press("g2")}, 500);}
5057 {setTimeout(function() { press("a2")}, 750);}
5058 {setTimeout(function() { press("b2")}, 1000);}
5059 {setTimeout(function() { press("c3")}, 1250);}
5060 {setTimeout(function() { press("d3")}, 1500);}
5061 {setTimeout(function() { press("e3")}, 1750);}
5062 {setTimeout(function() { press("d3")}, 2000);}
5063 {setTimeout(function() { press("c3")}, 2250);}
5064 {setTimeout(function() { press("b2")}, 2500);}
5065 {setTimeout(function() { press("a2")}, 2750);}
5066 {setTimeout(function() { press("g2")}, 3000);}
5067 {setTimeout(function() { press("fs2")}, 3250);}
5068 {setTimeout(function() { press("e2")}, 3500);}
5069 {setTimeout(function() { press("e2"); press("g2"); press("b2"); press("e3")}, 4000);}
5070
5071 } else if (message.substring(0, 16).toLowerCase() == cmdChar+"scale eharminor") { //E harmonic minor scale
5072 sendChat("The E harmonic minor scale - it has 2 sharps - it has a major 7th (D#)");
5073 {setTimeout(function() { press("e2")}, 0);}
5074 {setTimeout(function() { press("fs2")}, 250);}
5075 {setTimeout(function() { press("g2")}, 500);}
5076 {setTimeout(function() { press("a2")}, 750);}
5077 {setTimeout(function() { press("b2")}, 1000);}
5078 {setTimeout(function() { press("c3")}, 1250);}
5079 {setTimeout(function() { press("ds3")}, 1500);}
5080 {setTimeout(function() { press("e3")}, 1750);}
5081 {setTimeout(function() { press("ds3")}, 2000);}
5082 {setTimeout(function() { press("c3")}, 2250);}
5083 {setTimeout(function() { press("b2")}, 2500);}
5084 {setTimeout(function() { press("a2")}, 2750);}
5085 {setTimeout(function() { press("g2")}, 3000);}
5086 {setTimeout(function() { press("fs2")}, 3250);}
5087 {setTimeout(function() { press("e2")}, 3500);}
5088 {setTimeout(function() { press("e2"); press("g2"); press("b2"); press("e3")}, 4000);}
5089
5090 } else if (message.substring(0, 16).toLowerCase() == cmdChar+"scale emelminor") { //E melodic minor scale
5091 sendChat("The E melodic minor scale - it has 3 sharps ascending and 1 sharp descending - it has two patterns ascending and descending.");
5092 {setTimeout(function() { press("e2")}, 0);}
5093 {setTimeout(function() { press("fs2")}, 250);}
5094 {setTimeout(function() { press("g2")}, 500);}
5095 {setTimeout(function() { press("a2")}, 750);}
5096 {setTimeout(function() { press("b2")}, 1000);}
5097 {setTimeout(function() { press("cs3")}, 1250);}
5098 {setTimeout(function() { press("ds3")}, 1500);}
5099 {setTimeout(function() { press("e3")}, 1750);}
5100 {setTimeout(function() { press("d3")}, 2000);}
5101 {setTimeout(function() { press("c3")}, 2250);}
5102 {setTimeout(function() { press("b2")}, 2500);}
5103 {setTimeout(function() { press("a2")}, 2750);}
5104 {setTimeout(function() { press("g2")}, 3000);}
5105 {setTimeout(function() { press("fs2")}, 3250);}
5106 {setTimeout(function() { press("e2")}, 3500);}
5107 {setTimeout(function() { press("e2"); press("g2"); press("b2"); press("e3")}, 4000);}
5108 //E scales
5109
5110 //F scales
5111 } else if (message.substring(0, 13).toLowerCase() == cmdChar+"scale fmajor") { //F major scale
5112 sendChat("The F major scale - it has 1 flat - its relative minor is D");
5113 {setTimeout(function() { press("f2")}, 0);}
5114 {setTimeout(function() { press("g2")}, 250);}
5115 {setTimeout(function() { press("a2")}, 500);}
5116 {setTimeout(function() { press("as2")}, 750);}
5117 {setTimeout(function() { press("c3")}, 1000);}
5118 {setTimeout(function() { press("d3")}, 1250);}
5119 {setTimeout(function() { press("e3")}, 1500);}
5120 {setTimeout(function() { press("f3")}, 1750);}
5121 {setTimeout(function() { press("e3")}, 2000);}
5122 {setTimeout(function() { press("d3")}, 2250);}
5123 {setTimeout(function() { press("c3")}, 2500);}
5124 {setTimeout(function() { press("as2")}, 2750);}
5125 {setTimeout(function() { press("a2")}, 3000);}
5126 {setTimeout(function() { press("g2")}, 3250);}
5127 {setTimeout(function() { press("f2")}, 3500);}
5128 {setTimeout(function() { press("f2"); press("a2"); press("c3"); press("f3")}, 4000);}
5129
5130 } else if (message.substring(0, 13).toLowerCase() == cmdChar+"scale fminor") { //F minor scale
5131 sendChat("The F minor scale - it has 4 flats - its relative major is Ab");
5132 {setTimeout(function() { press("f2")}, 0);}
5133 {setTimeout(function() { press("g2")}, 250);}
5134 {setTimeout(function() { press("gs2")}, 500);}
5135 {setTimeout(function() { press("as2")}, 750);}
5136 {setTimeout(function() { press("c3")}, 1000);}
5137 {setTimeout(function() { press("cs3")}, 1250);}
5138 {setTimeout(function() { press("ds3")}, 1500);}
5139 {setTimeout(function() { press("f3")}, 1750);}
5140 {setTimeout(function() { press("ds3")}, 2000);}
5141 {setTimeout(function() { press("cs3")}, 2250);}
5142 {setTimeout(function() { press("c3")}, 2500);}
5143 {setTimeout(function() { press("as2")}, 2750);}
5144 {setTimeout(function() { press("gs2")}, 3000);}
5145 {setTimeout(function() { press("g2")}, 3250);}
5146 {setTimeout(function() { press("f2")}, 3500);}
5147 {setTimeout(function() { press("f2"); press("gs2"); press("c3"); press("f3")}, 4000);}
5148
5149 } else if (message.substring(0, 16).toLowerCase() == cmdChar+"scale fharminor") { //F harmonic minor scale
5150 sendChat("The F harmonic minor scale - it has 3 flats - it has a major 7th (E)");
5151 {setTimeout(function() { press("f2")}, 0);}
5152 {setTimeout(function() { press("g2")}, 250);}
5153 {setTimeout(function() { press("gs2")}, 500);}
5154 {setTimeout(function() { press("as2")}, 750);}
5155 {setTimeout(function() { press("c3")}, 1000);}
5156 {setTimeout(function() { press("cs3")}, 1250);}
5157 {setTimeout(function() { press("e3")}, 1500);}
5158 {setTimeout(function() { press("f3")}, 1750);}
5159 {setTimeout(function() { press("e3")}, 2000);}
5160 {setTimeout(function() { press("cs3")}, 2250);}
5161 {setTimeout(function() { press("c3")}, 2500);}
5162 {setTimeout(function() { press("as2")}, 2750);}
5163 {setTimeout(function() { press("gs2")}, 3000);}
5164 {setTimeout(function() { press("g2")}, 3250);}
5165 {setTimeout(function() { press("f2")}, 3500);}
5166 {setTimeout(function() { press("f2"); press("gs2"); press("c3"); press("f3")}, 4000);}
5167
5168 } else if (message.substring(0, 16).toLowerCase() == cmdChar+"scale fmelminor") { //F melodic minor scale
5169 sendChat("The F melodic minor scale - it has 2 flats ascending and 4 flats descending - it has two patterns ascending and descending.");
5170 {setTimeout(function() { press("f2")}, 0);}
5171 {setTimeout(function() { press("g2")}, 250);}
5172 {setTimeout(function() { press("gs2")}, 500);}
5173 {setTimeout(function() { press("as2")}, 750);}
5174 {setTimeout(function() { press("c3")}, 1000);}
5175 {setTimeout(function() { press("d3")}, 1250);}
5176 {setTimeout(function() { press("e3")}, 1500);}
5177 {setTimeout(function() { press("f3")}, 1750);}
5178 {setTimeout(function() { press("ds3")}, 2000);}
5179 {setTimeout(function() { press("cs3")}, 2250);}
5180 {setTimeout(function() { press("c3")}, 2500);}
5181 {setTimeout(function() { press("as2")}, 2750);}
5182 {setTimeout(function() { press("gs2")}, 3000);}
5183 {setTimeout(function() { press("g2")}, 3250);}
5184 {setTimeout(function() { press("f2")}, 3500);}
5185 {setTimeout(function() { press("f2"); press("gs2"); press("c3"); press("f3")}, 4000);}
5186 //F scales
5187
5188 //F# scales
5189 } else if (message.substring(0, 14).toLowerCase() == cmdChar+"scale fsmajor") { //F# major scale
5190 sendChat("The F# (sharp) major scale - it has 6 sharps - its relative minor is D#");
5191 {setTimeout(function() { press("fs2")}, 0);}
5192 {setTimeout(function() { press("gs2")}, 250);}
5193 {setTimeout(function() { press("as2")}, 500);}
5194 {setTimeout(function() { press("b2")}, 750);}
5195 {setTimeout(function() { press("cs3")}, 1000);}
5196 {setTimeout(function() { press("ds3")}, 1250);}
5197 {setTimeout(function() { press("f3")}, 1500);}
5198 {setTimeout(function() { press("fs3")}, 1750);}
5199 {setTimeout(function() { press("f3")}, 2000);}
5200 {setTimeout(function() { press("ds3")}, 2250);}
5201 {setTimeout(function() { press("cs3")}, 2500);}
5202 {setTimeout(function() { press("b2")}, 2750);}
5203 {setTimeout(function() { press("as2")}, 3000);}
5204 {setTimeout(function() { press("gs2")}, 3250);}
5205 {setTimeout(function() { press("fs2")}, 3500);}
5206 {setTimeout(function() { press("fs2"); press("as2"); press("cs3"); press("fs3")}, 4000);}
5207
5208 } else if (message.substring(0, 14).toLowerCase() == cmdChar+"scale fsminor") { //F# minor scale
5209 sendChat("The F# (sharp) minor scale - it has 3 sharps - its relative major is A");
5210 {setTimeout(function() { press("fs2")}, 0);}
5211 {setTimeout(function() { press("gs2")}, 250);}
5212 {setTimeout(function() { press("a2")}, 500);}
5213 {setTimeout(function() { press("b2")}, 750);}
5214 {setTimeout(function() { press("cs3")}, 1000);}
5215 {setTimeout(function() { press("d3")}, 1250);}
5216 {setTimeout(function() { press("e3")}, 1500);}
5217 {setTimeout(function() { press("fs3")}, 1750);}
5218 {setTimeout(function() { press("e3")}, 2000);}
5219 {setTimeout(function() { press("d3")}, 2250);}
5220 {setTimeout(function() { press("cs3")}, 2500);}
5221 {setTimeout(function() { press("b2")}, 2750);}
5222 {setTimeout(function() { press("a2")}, 3000);}
5223 {setTimeout(function() { press("gs2")}, 3250);}
5224 {setTimeout(function() { press("fs2")}, 3500);}
5225 {setTimeout(function() { press("fs2"); press("a2"); press("cs3"); press("fs3")}, 4000);}
5226
5227 } else if (message.substring(0, 17).toLowerCase() == cmdChar+"scale fsharminor") { //F# harmonic minor scale
5228 sendChat("The F# (sharp) harmonic minor scale - it has 4 sharps - it has a major 7th (E#)");
5229 {setTimeout(function() { press("fs2")}, 0);}
5230 {setTimeout(function() { press("gs2")}, 250);}
5231 {setTimeout(function() { press("a2")}, 500);}
5232 {setTimeout(function() { press("b2")}, 750);}
5233 {setTimeout(function() { press("cs3")}, 1000);}
5234 {setTimeout(function() { press("d3")}, 1250);}
5235 {setTimeout(function() { press("f3")}, 1500);}
5236 {setTimeout(function() { press("fs3")}, 1750);}
5237 {setTimeout(function() { press("f3")}, 2000);}
5238 {setTimeout(function() { press("d3")}, 2250);}
5239 {setTimeout(function() { press("cs3")}, 2500);}
5240 {setTimeout(function() { press("b2")}, 2750);}
5241 {setTimeout(function() { press("a2")}, 3000);}
5242 {setTimeout(function() { press("gs2")}, 3250);}
5243 {setTimeout(function() { press("fs2")}, 3500);}
5244 {setTimeout(function() { press("fs2"); press("a2"); press("cs3"); press("fs3")}, 4000);}
5245
5246 } else if (message.substring(0, 17).toLowerCase() == cmdChar+"scale fsmelminor") { //F# melodic minor scale
5247 sendChat("The F# (sharp) melodic minor scale - it has 5 sharps ascending and 3 sharps descending - it has two patterns ascending and descending.");
5248 {setTimeout(function() { press("fs2")}, 0);}
5249 {setTimeout(function() { press("gs2")}, 250);}
5250 {setTimeout(function() { press("a2")}, 500);}
5251 {setTimeout(function() { press("b2")}, 750);}
5252 {setTimeout(function() { press("cs3")}, 1000);}
5253 {setTimeout(function() { press("ds3")}, 1250);}
5254 {setTimeout(function() { press("f3")}, 1500);}
5255 {setTimeout(function() { press("fs3")}, 1750);}
5256 {setTimeout(function() { press("e3")}, 2000);}
5257 {setTimeout(function() { press("d3")}, 2250);}
5258 {setTimeout(function() { press("cs3")}, 2500);}
5259 {setTimeout(function() { press("b2")}, 2750);}
5260 {setTimeout(function() { press("a2")}, 3000);}
5261 {setTimeout(function() { press("gs2")}, 3250);}
5262 {setTimeout(function() { press("fs2")}, 3500);}
5263 {setTimeout(function() { press("fs2"); press("a2"); press("cs3"); press("fs3")}, 4000);}
5264 //F# scales
5265
5266 //G scales
5267 } else if (message.substring(0, 13).toLowerCase() == cmdChar+"scale gmajor") { //G major scale
5268 sendChat("The G major scale - it has 1 sharp - its relative minor is E");
5269 {setTimeout(function() { press("g2")}, 0);}
5270 {setTimeout(function() { press("a2")}, 250);}
5271 {setTimeout(function() { press("b2")}, 500);}
5272 {setTimeout(function() { press("c3")}, 750);}
5273 {setTimeout(function() { press("d3")}, 1000);}
5274 {setTimeout(function() { press("e3")}, 1250);}
5275 {setTimeout(function() { press("fs3")}, 1500);}
5276 {setTimeout(function() { press("g3")}, 1750);}
5277 {setTimeout(function() { press("fs3")}, 2000);}
5278 {setTimeout(function() { press("e3")}, 2250);}
5279 {setTimeout(function() { press("d3")}, 2500);}
5280 {setTimeout(function() { press("c3")}, 2750);}
5281 {setTimeout(function() { press("b2")}, 3000);}
5282 {setTimeout(function() { press("a2")}, 3250);}
5283 {setTimeout(function() { press("g2")}, 3500);}
5284 {setTimeout(function() { press("g2"); press("b2"); press("d3"); press("g3")}, 4000);}
5285
5286 } else if (message.substring(0, 14).toLowerCase() == cmdChar+"scale gminor") { //G minor scale
5287 sendChat("The G minor scale - it has 1 sharps - its relative major is Bb");
5288 {setTimeout(function() { press("g2")}, 0);}
5289 {setTimeout(function() { press("a2")}, 250);}
5290 {setTimeout(function() { press("as2")}, 500);}
5291 {setTimeout(function() { press("c3")}, 750);}
5292 {setTimeout(function() { press("d3")}, 1000);}
5293 {setTimeout(function() { press("ds3")}, 1250);}
5294 {setTimeout(function() { press("f3")}, 1500);}
5295 {setTimeout(function() { press("g3")}, 1750);}
5296 {setTimeout(function() { press("f3")}, 2000);}
5297 {setTimeout(function() { press("ds3")}, 2250);}
5298 {setTimeout(function() { press("d3")}, 2500);}
5299 {setTimeout(function() { press("c3")}, 2750);}
5300 {setTimeout(function() { press("as2")}, 3000);}
5301 {setTimeout(function() { press("a2")}, 3250);}
5302 {setTimeout(function() { press("g2")}, 3500);}
5303 {setTimeout(function() { press("g2"); press("as2"); press("d3"); press("g3")}, 4000);}
5304
5305 } else if (message.substring(0, 16).toLowerCase() == cmdChar+"scale gharminor") { //G harmonic minor scale
5306 sendChat("The G harmonic minor scale - it has 3 sharps - it has a major 7th (F#)");
5307 {setTimeout(function() { press("g2")}, 0);}
5308 {setTimeout(function() { press("a2")}, 250);}
5309 {setTimeout(function() { press("as2")}, 500);}
5310 {setTimeout(function() { press("c3")}, 750);}
5311 {setTimeout(function() { press("d3")}, 1000);}
5312 {setTimeout(function() { press("ds3")}, 1250);}
5313 {setTimeout(function() { press("fs3")}, 1500);}
5314 {setTimeout(function() { press("g3")}, 1750);}
5315 {setTimeout(function() { press("fs3")}, 2000);}
5316 {setTimeout(function() { press("ds3")}, 2250);}
5317 {setTimeout(function() { press("d3")}, 2500);}
5318 {setTimeout(function() { press("c3")}, 2750);}
5319 {setTimeout(function() { press("as2")}, 3000);}
5320 {setTimeout(function() { press("a2")}, 3250);}
5321 {setTimeout(function() { press("g2")}, 3500);}
5322 {setTimeout(function() { press("g2"); press("as2"); press("d3"); press("g3")}, 4000);}
5323
5324 } else if (message.substring(0, 16).toLowerCase() == cmdChar+"scale gmelminor") { //G melodic minor scale
5325 sendChat("The G melodic minor scale - it has 1 sharp ascending and 2 sharps descending - it has two patterns ascending and descending.");
5326 {setTimeout(function() { press("g2")}, 0);}
5327 {setTimeout(function() { press("a2")}, 250);}
5328 {setTimeout(function() { press("as2")}, 500);}
5329 {setTimeout(function() { press("c3")}, 750);}
5330 {setTimeout(function() { press("d3")}, 1000);}
5331 {setTimeout(function() { press("e3")}, 1250);}
5332 {setTimeout(function() { press("fs3")}, 1500);}
5333 {setTimeout(function() { press("g3")}, 1750);}
5334 {setTimeout(function() { press("f3")}, 2000);}
5335 {setTimeout(function() { press("ds3")}, 2250);}
5336 {setTimeout(function() { press("d3")}, 2500);}
5337 {setTimeout(function() { press("c3")}, 2750);}
5338 {setTimeout(function() { press("as2")}, 3000);}
5339 {setTimeout(function() { press("a2")}, 3250);}
5340 {setTimeout(function() { press("g2")}, 3500);}
5341 {setTimeout(function() { press("g2"); press("as2"); press("d3"); press("g3")}, 4000);}
5342 //G scales
5343
5344 //Ab Scales
5345 } else if (message.substring(0, 14).toLowerCase() == cmdChar+"scale abmajor") { //Ab major scale
5346 sendChat("The Ab (flat) major scale - it has 4 flats - its relative minor is F");
5347 {setTimeout(function() { press("gs2")}, 0);}
5348 {setTimeout(function() { press("as2")}, 250);}
5349 {setTimeout(function() { press("c3")}, 500);}
5350 {setTimeout(function() { press("cs3")}, 750);}
5351 {setTimeout(function() { press("ds3")}, 1000);}
5352 {setTimeout(function() { press("f3")}, 1250);}
5353 {setTimeout(function() { press("g3")}, 1500);}
5354 {setTimeout(function() { press("gs3")}, 1750);}
5355 {setTimeout(function() { press("g3")}, 2000);}
5356 {setTimeout(function() { press("f3")}, 2250);}
5357 {setTimeout(function() { press("ds3")}, 2500);}
5358 {setTimeout(function() { press("cs3")}, 2750);}
5359 {setTimeout(function() { press("c3")}, 3000);}
5360 {setTimeout(function() { press("as2")}, 3250);}
5361 {setTimeout(function() { press("gs2")}, 3500);}
5362 {setTimeout(function() { press("gs2"); press("c3"); press("ds3"); press("gs3")}, 4000);}
5363
5364 } else if (message.substring(0, 15).toLowerCase() == cmdChar+"scale abminor") { //Ab minor scale
5365 sendChat("The Ab (flat) minor scale - it has 7 flats - its relative major is Cb major or enharmonically, B major");
5366 {setTimeout(function() { press("gs2")}, 0);}
5367 {setTimeout(function() { press("as2")}, 250);}
5368 {setTimeout(function() { press("b2")}, 500);}
5369 {setTimeout(function() { press("cs3")}, 750);}
5370 {setTimeout(function() { press("ds3")}, 1000);}
5371 {setTimeout(function() { press("e3")}, 1250);}
5372 {setTimeout(function() { press("fs3")}, 1500);}
5373 {setTimeout(function() { press("gs3")}, 1750);}
5374 {setTimeout(function() { press("fs3")}, 2000);}
5375 {setTimeout(function() { press("e3")}, 2250);}
5376 {setTimeout(function() { press("ds3")}, 2500);}
5377 {setTimeout(function() { press("cs3")}, 2750);}
5378 {setTimeout(function() { press("b2")}, 3000);}
5379 {setTimeout(function() { press("as2")}, 3250);}
5380 {setTimeout(function() { press("gs2")}, 3500);}
5381 {setTimeout(function() { press("gs2"); press("b2"); press("ds3"); press("gs3")}, 4000);}
5382
5383 } else if (message.substring(0, 17).toLowerCase() == cmdChar+"scale abharminor") { //Ab harmonic minor scale
5384 sendChat("The Ab (flat) harmonic minor scale - it has 4 flats - it has a major 7th (G)");
5385 {setTimeout(function() { press("gs2")}, 0);}
5386 {setTimeout(function() { press("as2")}, 250);}
5387 {setTimeout(function() { press("b2")}, 500);}
5388 {setTimeout(function() { press("cs3")}, 750);}
5389 {setTimeout(function() { press("ds3")}, 1000);}
5390 {setTimeout(function() { press("e3")}, 1250);}
5391 {setTimeout(function() { press("g3")}, 1500);}
5392 {setTimeout(function() { press("gs3")}, 1750);}
5393 {setTimeout(function() { press("g3")}, 2000);}
5394 {setTimeout(function() { press("e3")}, 2250);}
5395 {setTimeout(function() { press("ds3")}, 2500);}
5396 {setTimeout(function() { press("cs3")}, 2750);}
5397 {setTimeout(function() { press("b2")}, 3000);}
5398 {setTimeout(function() { press("as2")}, 3250);}
5399 {setTimeout(function() { press("gs2")}, 3500);}
5400 {setTimeout(function() { press("gs2"); press("b2"); press("ds3"); press("gs3")}, 4000);}
5401
5402 } else if (message.substring(0, 17).toLowerCase() == cmdChar+"scale abmelminor") { //Ab melodic minor scale
5403 sendChat("The Ab (flat) melodic minor scale - it has 3 flats ascending and 4 flats descending - it has two patterns ascending and descending.");
5404 {setTimeout(function() { press("gs2")}, 0);}
5405 {setTimeout(function() { press("as2")}, 250);}
5406 {setTimeout(function() { press("b2")}, 500);}
5407 {setTimeout(function() { press("cs3")}, 750);}
5408 {setTimeout(function() { press("ds3")}, 1000);}
5409 {setTimeout(function() { press("f3")}, 1250);}
5410 {setTimeout(function() { press("g3")}, 1500);}
5411 {setTimeout(function() { press("gs3")}, 1750);}
5412 {setTimeout(function() { press("fs3")}, 2000);}
5413 {setTimeout(function() { press("e3")}, 2250);}
5414 {setTimeout(function() { press("ds3")}, 2500);}
5415 {setTimeout(function() { press("cs3")}, 2750);}
5416 {setTimeout(function() { press("b2")}, 3000);}
5417 {setTimeout(function() { press("as2")}, 3250);}
5418 {setTimeout(function() { press("gs2")}, 3500);}
5419 {setTimeout(function() { press("gs2"); press("b2"); press("ds3"); press("gs3")}, 4000);}
5420 //Ab Scales
5421
5422 //A Scales
5423 } else if (message.substring(0, 13).toLowerCase() == cmdChar+"scale amajor") { //A major scale
5424 sendChat("The A major scale - it has 3 sharps - its relative minor is F#");
5425 {setTimeout(function() { press("a2")}, 0);}
5426 {setTimeout(function() { press("b2")}, 250);}
5427 {setTimeout(function() { press("cs3")}, 500);}
5428 {setTimeout(function() { press("d3")}, 750);}
5429 {setTimeout(function() { press("e3")}, 1000);}
5430 {setTimeout(function() { press("fs3")}, 1250);}
5431 {setTimeout(function() { press("gs3")}, 1500);}
5432 {setTimeout(function() { press("a3")}, 1750);}
5433 {setTimeout(function() { press("gs3")}, 2000);}
5434 {setTimeout(function() { press("fs3")}, 2250);}
5435 {setTimeout(function() { press("e3")}, 2500);}
5436 {setTimeout(function() { press("d3")}, 2750);}
5437 {setTimeout(function() { press("cs3")}, 3000);}
5438 {setTimeout(function() { press("b2")}, 3250);}
5439 {setTimeout(function() { press("a2")}, 3500);}
5440 {setTimeout(function() { press("a2"); press("cs3"); press("e3"); press("a3")}, 4000);}
5441
5442 } else if (message.substring(0, 14).toLowerCase() == cmdChar+"scale aminor") { //A minor scale
5443 sendChat("The A minor scale - it has no sharps or flats - its relative major is C major");
5444 {setTimeout(function() { press("a2")}, 0);}
5445 {setTimeout(function() { press("b2")}, 250);}
5446 {setTimeout(function() { press("c3")}, 500);}
5447 {setTimeout(function() { press("d3")}, 750);}
5448 {setTimeout(function() { press("e3")}, 1000);}
5449 {setTimeout(function() { press("f3")}, 1250);}
5450 {setTimeout(function() { press("g3")}, 1500);}
5451 {setTimeout(function() { press("a3")}, 1750);}
5452 {setTimeout(function() { press("g3")}, 2000);}
5453 {setTimeout(function() { press("f3")}, 2250);}
5454 {setTimeout(function() { press("e3")}, 2500);}
5455 {setTimeout(function() { press("d3")}, 2750);}
5456 {setTimeout(function() { press("c3")}, 3000);}
5457 {setTimeout(function() { press("b2")}, 3250);}
5458 {setTimeout(function() { press("a2")}, 3500);}
5459 {setTimeout(function() { press("a2"); press("c3"); press("e3"); press("a3")}, 4000);}
5460
5461 } else if (message.substring(0, 16).toLowerCase() == cmdChar+"scale aharminor") { //A harmonic minor scale
5462 sendChat("The A harmonic minor scale - it has 1 flat - it has a major 7th (G#)");
5463 {setTimeout(function() { press("a2")}, 0);}
5464 {setTimeout(function() { press("b2")}, 250);}
5465 {setTimeout(function() { press("cs3")}, 500);}
5466 {setTimeout(function() { press("d3")}, 750);}
5467 {setTimeout(function() { press("e3")}, 1000);}
5468 {setTimeout(function() { press("fs3")}, 1250);}
5469 {setTimeout(function() { press("gs3")}, 1500);}
5470 {setTimeout(function() { press("a3")}, 1750);}
5471 {setTimeout(function() { press("gs3")}, 2000);}
5472 {setTimeout(function() { press("fs3")}, 2250);}
5473 {setTimeout(function() { press("e3")}, 2500);}
5474 {setTimeout(function() { press("d3")}, 2750);}
5475 {setTimeout(function() { press("cs3")}, 3000);}
5476 {setTimeout(function() { press("b2")}, 3250);}
5477 {setTimeout(function() { press("a2")}, 3500);}
5478 {setTimeout(function() { press("a2"); press("cs3"); press("e3"); press("a3")}, 4000);}
5479
5480 } else if (message.substring(0, 16).toLowerCase() == cmdChar+"scale amelminor") { //A melodic minor scale
5481 sendChat("The A melodic minor scale - it has 2 sharps ascending and 0 sharps descending - it has two patterns ascending and descending.");
5482 {setTimeout(function() { press("a2")}, 0);}
5483 {setTimeout(function() { press("b2")}, 250);}
5484 {setTimeout(function() { press("c3")}, 500);}
5485 {setTimeout(function() { press("d3")}, 750);}
5486 {setTimeout(function() { press("e3")}, 1000);}
5487 {setTimeout(function() { press("fs3")}, 1250);}
5488 {setTimeout(function() { press("gs3")}, 1500);}
5489 {setTimeout(function() { press("a3")}, 1750);}
5490 {setTimeout(function() { press("g3")}, 2000);}
5491 {setTimeout(function() { press("f3")}, 2250);}
5492 {setTimeout(function() { press("e3")}, 2500);}
5493 {setTimeout(function() { press("d3")}, 2750);}
5494 {setTimeout(function() { press("c3")}, 3000);}
5495 {setTimeout(function() { press("b2")}, 3250);}
5496 {setTimeout(function() { press("a2")}, 3500);}
5497 {setTimeout(function() { press("a2"); press("c3"); press("e3"); press("a3")}, 4000);}
5498 //A Scales
5499
5500 //Bb Scales
5501 } else if (message.substring(0, 14).toLowerCase() == cmdChar+"scale bbmajor") { //Bb major scale
5502 sendChat("The Bb (flat) major scale - it has 2 flats - its relative minor is G");
5503 {setTimeout(function() { press("as2")}, 0);}
5504 {setTimeout(function() { press("c3")}, 250);}
5505 {setTimeout(function() { press("d3")}, 500);}
5506 {setTimeout(function() { press("ds3")}, 750);}
5507 {setTimeout(function() { press("f3")}, 1000);}
5508 {setTimeout(function() { press("g3")}, 1250);}
5509 {setTimeout(function() { press("a3")}, 1500);}
5510 {setTimeout(function() { press("as3")}, 1750);}
5511 {setTimeout(function() { press("a3")}, 2000);}
5512 {setTimeout(function() { press("g3")}, 2250);}
5513 {setTimeout(function() { press("f3")}, 2500);}
5514 {setTimeout(function() { press("ds3")}, 2750);}
5515 {setTimeout(function() { press("d3")}, 3000);}
5516 {setTimeout(function() { press("c3")}, 3250);}
5517 {setTimeout(function() { press("as2")}, 3500);}
5518 {setTimeout(function() { press("as2"); press("d3"); press("f3"); press("as3")}, 4000);}
5519
5520 } else if (message.substring(0, 15).toLowerCase() == cmdChar+"scale bbminor") { //Bb minor scale
5521 sendChat("The Bb (flat) minor scale - it 6 flats - its relative major is Db major");
5522 {setTimeout(function() { press("as2")}, 0);}
5523 {setTimeout(function() { press("c3")}, 250);}
5524 {setTimeout(function() { press("cs3")}, 500);}
5525 {setTimeout(function() { press("ds3")}, 750);}
5526 {setTimeout(function() { press("f3")}, 1000);}
5527 {setTimeout(function() { press("fs3")}, 1250);}
5528 {setTimeout(function() { press("gs3")}, 1500);}
5529 {setTimeout(function() { press("as3")}, 1750);}
5530 {setTimeout(function() { press("gs3")}, 2000);}
5531 {setTimeout(function() { press("fs3")}, 2250);}
5532 {setTimeout(function() { press("f3")}, 2500);}
5533 {setTimeout(function() { press("ds3")}, 2750);}
5534 {setTimeout(function() { press("cs3")}, 3000);}
5535 {setTimeout(function() { press("c3")}, 3250);}
5536 {setTimeout(function() { press("as2")}, 3500);}
5537 {setTimeout(function() { press("as2"); press("cs3"); press("f3"); press("as3")}, 4000);}
5538
5539 } else if (message.substring(0, 17).toLowerCase() == cmdChar+"scale bbharminor") { //Bb harmonic minor scale
5540 sendChat("The Bb (flat) harmonic minor scale - it has 5 flats - it has a major 7th (A)");
5541 {setTimeout(function() { press("as2")}, 0);}
5542 {setTimeout(function() { press("c3")}, 250);}
5543 {setTimeout(function() { press("cs3")}, 500);}
5544 {setTimeout(function() { press("ds3")}, 750);}
5545 {setTimeout(function() { press("f3")}, 1000);}
5546 {setTimeout(function() { press("fs3")}, 1250);}
5547 {setTimeout(function() { press("a3")}, 1500);}
5548 {setTimeout(function() { press("as3")}, 1750);}
5549 {setTimeout(function() { press("a3")}, 2000);}
5550 {setTimeout(function() { press("fs3")}, 2250);}
5551 {setTimeout(function() { press("f3")}, 2500);}
5552 {setTimeout(function() { press("ds3")}, 2750);}
5553 {setTimeout(function() { press("cs3")}, 3000);}
5554 {setTimeout(function() { press("c3")}, 3250);}
5555 {setTimeout(function() { press("as2")}, 3500);}
5556 {setTimeout(function() { press("as2"); press("cs3"); press("f3"); press("as3")}, 4000);}
5557
5558 } else if (message.substring(0, 17).toLowerCase() == cmdChar+"scale bbmelminor") { //Bb melodic minor scale
5559 sendChat("The Bb (flat) melodic minor scale - it has 4 flat ascending and 6 sharps descending - it has two patterns ascending and descending.");
5560 {setTimeout(function() { press("as2")}, 0);}
5561 {setTimeout(function() { press("c3")}, 250);}
5562 {setTimeout(function() { press("cs3")}, 500);}
5563 {setTimeout(function() { press("ds3")}, 750);}
5564 {setTimeout(function() { press("f3")}, 1000);}
5565 {setTimeout(function() { press("g3")}, 1250);}
5566 {setTimeout(function() { press("a3")}, 1500);}
5567 {setTimeout(function() { press("as3")}, 1750);}
5568 {setTimeout(function() { press("gs3")}, 2000);}
5569 {setTimeout(function() { press("fs3")}, 2250);}
5570 {setTimeout(function() { press("f3")}, 2500);}
5571 {setTimeout(function() { press("ds3")}, 2750);}
5572 {setTimeout(function() { press("cs3")}, 3000);}
5573 {setTimeout(function() { press("c3")}, 3250);}
5574 {setTimeout(function() { press("as2")}, 3500);}
5575 {setTimeout(function() { press("as2"); press("cs3"); press("f3"); press("as3")}, 4000);}
5576 //Bb Scales
5577
5578 //B Scales
5579 } else if (message.substring(0, 13).toLowerCase() == cmdChar+"scale bmajor") { //B major scale
5580 sendChat("The B major scale - it has 5 sharps - its relative minor is G#");
5581 {setTimeout(function() { press("b2")}, 0);}
5582 {setTimeout(function() { press("cs3")}, 250);}
5583 {setTimeout(function() { press("ds3")}, 500);}
5584 {setTimeout(function() { press("e3")}, 750);}
5585 {setTimeout(function() { press("fs3")}, 1000);}
5586 {setTimeout(function() { press("gs3")}, 1250);}
5587 {setTimeout(function() { press("as3")}, 1500);}
5588 {setTimeout(function() { press("b3")}, 1750);}
5589 {setTimeout(function() { press("as3")}, 2000);}
5590 {setTimeout(function() { press("gs3")}, 2250);}
5591 {setTimeout(function() { press("fs3")}, 2500);}
5592 {setTimeout(function() { press("e3")}, 2750);}
5593 {setTimeout(function() { press("ds3")}, 3000);}
5594 {setTimeout(function() { press("cs3")}, 3250);}
5595 {setTimeout(function() { press("b2")}, 3500);}
5596 {setTimeout(function() { press("b2"); press("ds3"); press("fs3"); press("b3")}, 4000);}
5597
5598 } else if (message.substring(0, 14).toLowerCase() == cmdChar+"scale bminor") { //B minor scale
5599 sendChat("The B minor scale - it 2 sharps - its relative major is D major");
5600 {setTimeout(function() { press("b2")}, 0);}
5601 {setTimeout(function() { press("cs3")}, 250);}
5602 {setTimeout(function() { press("d3")}, 500);}
5603 {setTimeout(function() { press("e3")}, 750);}
5604 {setTimeout(function() { press("fs3")}, 1000);}
5605 {setTimeout(function() { press("g3")}, 1250);}
5606 {setTimeout(function() { press("a3")}, 1500);}
5607 {setTimeout(function() { press("b3")}, 1750);}
5608 {setTimeout(function() { press("a3")}, 2000);}
5609 {setTimeout(function() { press("g3")}, 2250);}
5610 {setTimeout(function() { press("fs3")}, 2500);}
5611 {setTimeout(function() { press("e3")}, 2750);}
5612 {setTimeout(function() { press("d3")}, 3000);}
5613 {setTimeout(function() { press("cs3")}, 3250);}
5614 {setTimeout(function() { press("b2")}, 3500);}
5615 {setTimeout(function() { press("b2"); press("d3"); press("fs3"); press("b3")}, 4000);}
5616
5617 } else if (message.substring(0, 16).toLowerCase() == cmdChar+"scale bharminor") { //B harmonic minor scale
5618 sendChat("The B harmonic minor scale - it has 3 sharps - it has a major 7th (A#)");
5619 {setTimeout(function() { press("b2")}, 0);}
5620 {setTimeout(function() { press("cs3")}, 250);}
5621 {setTimeout(function() { press("d3")}, 500);}
5622 {setTimeout(function() { press("e3")}, 750);}
5623 {setTimeout(function() { press("fs3")}, 1000);}
5624 {setTimeout(function() { press("g3")}, 1250);}
5625 {setTimeout(function() { press("as3")}, 1500);}
5626 {setTimeout(function() { press("b3")}, 1750);}
5627 {setTimeout(function() { press("as3")}, 2000);}
5628 {setTimeout(function() { press("g3")}, 2250);}
5629 {setTimeout(function() { press("fs3")}, 2500);}
5630 {setTimeout(function() { press("e3")}, 2750);}
5631 {setTimeout(function() { press("d3")}, 3000);}
5632 {setTimeout(function() { press("cs3")}, 3250);}
5633 {setTimeout(function() { press("b2")}, 3500);}
5634 {setTimeout(function() { press("b2"); press("d3"); press("fs3"); press("b3")}, 4000);}
5635
5636 } else if (message.substring(0, 16).toLowerCase() == cmdChar+"scale bmelminor") { //B melodic minor scale
5637 sendChat("The B melodic minor scale - it has 4 sharps ascending and 2 sharps descending - it has two patterns ascending and descending.");
5638 {setTimeout(function() { press("b2")}, 0);}
5639 {setTimeout(function() { press("cs3")}, 250);}
5640 {setTimeout(function() { press("d3")}, 500);}
5641 {setTimeout(function() { press("e3")}, 750);}
5642 {setTimeout(function() { press("fs3")}, 1000);}
5643 {setTimeout(function() { press("gs3")}, 1250);}
5644 {setTimeout(function() { press("as3")}, 1500);}
5645 {setTimeout(function() { press("b3")}, 1750);}
5646 {setTimeout(function() { press("a3")}, 2000);}
5647 {setTimeout(function() { press("g3")}, 2250);}
5648 {setTimeout(function() { press("fs3")}, 2500);}
5649 {setTimeout(function() { press("e3")}, 2750);}
5650 {setTimeout(function() { press("d3")}, 3000);}
5651 {setTimeout(function() { press("cs3")}, 3250);}
5652 {setTimeout(function() { press("b2")}, 3500);}
5653 {setTimeout(function() { press("b2"); press("d3"); press("fs3"); press("b3")}, 4000);}
5654 //B Scales
5655 //scales
5656
5657 //glossary
5658 } else if (cmd == cmdChar+"glossary") { //Glossary
5659 sendChat("Music theory glossary: "+cmdChar+"arpeggio, "+cmdChar+"glissando [Unfinished!!]");
5660
5661 //Arpeggio
5662 } else if (cmd == cmdChar+"arpeggio") { //Arpeggio
5663 sendChat("An arpeggio is a musical technique where notes in a chord are played in sequence, one after the other. This word comes from the Italian word \"arpeggiare\", which means \"to play on a harp\". An alternative translation of this term is \"broken chord\".");
5664 {setTimeout(function() { press("c0")}, 0);} //octave
5665 {setTimeout(function() { press("ds0")}, 200);}
5666 {setTimeout(function() { press("g0")}, 400);}
5667 {setTimeout(function() { press("c1")}, 600);} //octave
5668 {setTimeout(function() { press("ds1")}, 800);}
5669 {setTimeout(function() { press("g1")}, 1000);}
5670 {setTimeout(function() { press("c2")}, 1200);} //octave
5671 {setTimeout(function() { press("ds2")}, 1400);}
5672 {setTimeout(function() { press("g2")}, 1600);}
5673 {setTimeout(function() { press("c3")}, 1800);} //octave
5674 {setTimeout(function() { press("ds3")}, 2000);}
5675 {setTimeout(function() { press("g3")}, 2200);}
5676 {setTimeout(function() { press("c4")}, 2400);} //octave
5677 {setTimeout(function() { press("ds4")}, 2600);}
5678 {setTimeout(function() { press("g4")}, 2800);}
5679 {setTimeout(function() { press("c5")}, 3000);} //octave
5680 {setTimeout(function() { press("ds5")}, 3200);}
5681 {setTimeout(function() { press("g5")}, 3400);}
5682 {setTimeout(function() { press("c6")}, 3600);} //octave
5683 {setTimeout(function() { press("ds6")}, 3800);}
5684 {setTimeout(function() { press("g6")}, 4000);}
5685 {setTimeout(function() { press("c7")}, 4200);} //octave
5686 //Arpeggio
5687
5688 //Glissando
5689 } else if (cmd == cmdChar+"glissando") { //Glissando
5690 sendChat("In music, a glissando is a glide from one pitch to another. It is an Italianized musical term derived from the French \"glisser\", to glide.");
5691 {setTimeout(function() { press("a-1")}, 100);}
5692 {setTimeout(function() { press("b-1")}, 200);}
5693 {setTimeout(function() { press("c0")}, 300);}
5694 {setTimeout(function() { press("d0")}, 400);}
5695 {setTimeout(function() { press("e0")}, 500);}
5696 {setTimeout(function() { press("f0")}, 600);}
5697 {setTimeout(function() { press("g0")}, 700);}
5698 {setTimeout(function() { press("a0")}, 800);}
5699 {setTimeout(function() { press("b0")}, 900);}
5700 {setTimeout(function() { press("c1")}, 1000);}
5701 {setTimeout(function() { press("d1")}, 1100);}
5702 {setTimeout(function() { press("e1")}, 1200);}
5703 {setTimeout(function() { press("f1")}, 1300);}
5704 {setTimeout(function() { press("g1")}, 1400);}
5705 {setTimeout(function() { press("a1")}, 1500);}
5706 {setTimeout(function() { press("b1")}, 1600);}
5707 {setTimeout(function() { press("c2")}, 1700);}
5708 {setTimeout(function() { press("d2")}, 1800);}
5709 {setTimeout(function() { press("e2")}, 1900);}
5710 {setTimeout(function() { press("f2")}, 2000);}
5711 {setTimeout(function() { press("g2")}, 2100);}
5712 {setTimeout(function() { press("a2")}, 2200);}
5713 {setTimeout(function() { press("b2")}, 2300);}
5714 {setTimeout(function() { press("c3")}, 2400);}
5715 {setTimeout(function() { press("d3")}, 2500);}
5716 {setTimeout(function() { press("e3")}, 2600);}
5717 {setTimeout(function() { press("f3")}, 2700);}
5718 {setTimeout(function() { press("g3")}, 2800);}
5719 {setTimeout(function() { press("a3")}, 2900);}
5720 {setTimeout(function() { press("b3")}, 3000);}
5721 {setTimeout(function() { press("c4")}, 3100);}
5722 {setTimeout(function() { press("d4")}, 3200);}
5723 {setTimeout(function() { press("e4")}, 3300);}
5724 {setTimeout(function() { press("f4")}, 3400);}
5725 {setTimeout(function() { press("g4")}, 3500);}
5726 {setTimeout(function() { press("a4")}, 3600);}
5727 {setTimeout(function() { press("b4")}, 3700);}
5728 {setTimeout(function() { press("c5")}, 3800);}
5729 {setTimeout(function() { press("d5")}, 3900);}
5730 {setTimeout(function() { press("e5")}, 4000);}
5731 {setTimeout(function() { press("f5")}, 4100);}
5732 {setTimeout(function() { press("g5")}, 4200);}
5733 {setTimeout(function() { press("a5")}, 4300);}
5734 {setTimeout(function() { press("b5")}, 4400);}
5735 {setTimeout(function() { press("c6")}, 4500);}
5736 {setTimeout(function() { press("d6")}, 4600);}
5737 {setTimeout(function() { press("e6")}, 4700);}
5738 {setTimeout(function() { press("f6")}, 4800);}
5739 {setTimeout(function() { press("g6")}, 4900);}
5740 {setTimeout(function() { press("a6")}, 5000);}
5741 {setTimeout(function() { press("b6")}, 5100);}
5742 {setTimeout(function() { press("c7")}, 5200);}
5743 //Glissando
5744
5745 //Glossary
5746
5747 //Music theory
5748
5749 //Meow game
5750 } else if (cmd == cmdChar+"mp") {
5751 if (message.length == cmd.length) {
5752 // Check if user is in Database
5753 mUser = MDB[ids];
5754
5755 // If user isn't create a new entry
5756 if (!mUser) {
5757 mUser = MDB[ids] = {
5758 name: name,
5759 meowP: 0,
5760 meowRate: 1,
5761 meowTime: 0,
5762 meowing: false,
5763 cheeseMaster: false,
5764 inventory: {
5765 string: 1,
5766 yarn: 0,
5767 wool: 0,
5768 water: 0,
5769 milk: 0,
5770 bananaMilk: 0,
5771 cheese: 0
5772 },
5773 prices: {
5774 string: 50,
5775 yarn: 500,
5776 wool: 2000,
5777 water: 15000,
5778 milk: 50000,
5779 bananaMilk: 100000,
5780 cheese: 25000000000
5781 }
5782 };
5783
5784 // Start their timer (no clue if this is correct or what)
5785 setInterval(function() {
5786 MDB[ids].meowP += MDB[ids].meowRate;
5787 ++MDB[ids].meowTime;
5788 }, 1000);
5789
5790 MDB[ids].meowing = true;
5791 sendChat('✯ Meow! Welcome to Meowpuff, ' + name + '! (type '+cmdChar+'meow for help, if you\'re still confused ask Logan x3)✯');
5792 sendChat('MP [' + mUser.meowP + '] MP rate [' + mUser.meowRate + '] Time [' + mUser.meowTime + ' secs | ' + (mUser.meowTime / 86400).toPrecision(4) + ' days]');
5793
5794 } else {
5795 if (!MDB[ids].meowing) {
5796 setInterval(function() {
5797 MDB[ids].meowP += MDB[ids].meowRate;
5798 ++MDB[ids].meowTime;
5799 }, 1000);
5800 if (MDB[ids].cheeseMaster) {
5801 sendChat('Welcome back, [Cheese Master] ' + name + '! Stats successfully loaded.');
5802 } else {
5803 sendChat('Welcome back, ' + name + '. Stats successfully loaded.');
5804 }
5805 MDB[ids].meowing = true;
5806 }
5807
5808 // working ✓
5809 sendChat('MP [' + mUser.meowP + '] MP rate [' + mUser.meowRate + '] Time [' + mUser.meowTime + ' secs | ' + (mUser.meowTime / 86400).toPrecision(4) + ' days]');
5810 }
5811 //else they entered more information
5812 } else {
5813 var target = msg.a.substring(cmd.length).trim();
5814 var part = getUser(target.toLowerCase());
5815 if (part) {
5816 if (!MDB[part._id] || !MDB[part._id].meowing) {
5817 sendChat(part.name+ ' isn\'t playing Meowpuff. They need to type '+cmdChar+'mp to create or load a save');
5818 return;
5819 }
5820
5821 if (part.name == name) {
5822 sendChat('Your MP [' + MDB[ids].meowP + '] MP rate [' + MDB[ids].meowRate + '] Time [' + MDB[ids].meowTime + ' secs | ' + (MDB[ids].meowTime / 86400).toPrecision(4) + ' days]');
5823 return;
5824 }
5825 sendChat(part.name + '\'s MP [' + MDB[part._id].meowP + '] MP rate [' + MDB[part._id].meowRate + '] Time [' + MDB[part._id].meowTime + ' secs | ' + (MDB[part._id].meowTime / 86400).toPrecision(4) + ' days]');
5826 } else {
5827 sendChat(userNotFound);
5828 }
5829 }
5830
5831 //Meow help
5832 } else if (cmd == cmdChar+"meow") {
5833 if (gClient.isOwner()) sendChat('✯ Meow! Need some help with Meowpuff? Buy items to entice kitties to work for you to gain as many Meow Points as possible x3 ✯');
5834 sendChat(''+cmdChar+'meow (shows help) '+cmdChar+'mp (starts game / shows stats after you have started and '+cmdChar+'mp name_here), \
5835 '+cmdChar+'meowshop ('+cmdChar+'mshop item_name_here visit The Cuddle Kitty shop to buy items to increase your MPS), \
5836 '+cmdChar+'meowinventory ('+cmdChar+'minv shows your Meow Points and purchased items and '+cmdChar+'minv name_here), \
5837 '+cmdChar+'meowsave ('+cmdChar+'msave saves game), \
5838 '+cmdChar+'meowtype ('+cmdChar+'mtype gives you a word challenge), \
5839 '+cmdChar+'meowstats ('+cmdChar+'mstats shows total stats for all players)');
5840 //Meow help
5841
5842 //Meow shop
5843 } else if (cmd == cmdChar+"meowshop" || cmd == cmdChar+"mshop") {
5844 if (!MDB[ids].meowing) {
5845 sendChat('You must start the game again with '+cmdChar+'mp before The Cuddle Kitty shop will let you in!');
5846 return;
5847 }
5848 if (message.substring(cmd.length).trim() == '') {
5849 //optimise
5850 if (gClient.isOwner()) sendChat('✯ Meow ' + name + '! Welcome to The Cuddle Kitty shop! If you need help type '+cmdChar+'meow :3 | MP [' + MDB[ids].meowP + '] ✯');
5851 sendChat(name +'\'s shop (string [' + MDB[ids].prices.string + ' MP] +1 MPS for each piece of string owned) \
5852 (yarn [' + MDB[ids].prices.yarn + ' MP] +10 MPS for each piece of yarn owned) \
5853 (wool [' + MDB[ids].prices.wool + ' MP] +40 MPS for each ball of wool owned) \
5854 (water [' + MDB[ids].prices.water + ' MP] +300 MPS for every bowl of water owned) \
5855 (milk [' + MDB[ids].prices.milk + ' MP] +1000 MPS for every tanker of milk owned) \
5856 (banana milk [' + MDB[ids].prices.bananaMilk + ' MP] +2000 MPS for every tanker of banana milk owned) \
5857 (cheese [' + MDB[ids].prices.cheese + ' MP] +2500000000 MPS for each piece of cheese owned)');
5858 return;
5859
5860 // string
5861 } else if (message.substring(cmd.length).trim() == 'string') {
5862 if (MDB[ids].meowP >= MDB[ids].prices.string) { //Do they have enough meow points?
5863 MDB[ids].meowP -= MDB[ids].prices.string; //Take correct price away
5864 MDB[ids].prices.string += 5 * (MDB[ids].inventory.string) + 50; //Up price next time, might make more cruel
5865 MDB[ids].meowRate += 1; //Add the MPS
5866 MDB[ids].inventory.string += 1; //Add the string to inv
5867 sendChat('String added to ' + name + '\'s inventory! Next one will cost [' + MDB[ids].prices.string + ' MP] (' + MDB[ids].inventory.string + ' string in kitty storage) MP [' + MDB[ids].meowP + ']');
5868 } else { //They don't have enough meow points
5869 //return a positive number
5870 sendChat(meowNeP + ' string. You need ' + Math.abs(MDB[ids].meowP - MDB[ids].prices.string) + ' more MP! (' + MDB[ids].inventory.string + ' string in kitty storage) MP [' + MDB[ids].meowP + ']');
5871 }
5872
5873 // yarn
5874 } else if (message.substring(cmd.length).trim() == 'yarn') {
5875 if (MDB[ids].meowP >= MDB[ids].prices.yarn) {
5876 MDB[ids].meowP -= MDB[ids].prices.yarn;
5877 MDB[ids].prices.yarn += 50 * (MDB[ids].inventory.yarn) + 500;
5878 MDB[ids].meowRate += 10;
5879 MDB[ids].inventory.yarn += 1;
5880 sendChat('Yarn added to ' + name + '\'s inventory! Next one will cost [' + MDB[ids].prices.yarn + ' MP] (' + MDB[ids].inventory.yarn + ' yarn in kitty storage) MP [' + MDB[ids].meowP + ']');
5881 } else {
5882 sendChat(meowNeP + ' yarn. You need ' + Math.abs(MDB[ids].meowP - MDB[ids].prices.yarn) + ' more MP! (' + MDB[ids].inventory.yarn + ' yarn in kitty storage) MP [' + MDB[ids].meowP + ']');
5883 }
5884
5885 // wool
5886 } else if (message.substring(cmd.length).trim() == 'wool') {
5887 if (MDB[ids].meowP >= MDB[ids].prices.wool) {
5888 MDB[ids].meowP -= MDB[ids].prices.wool;
5889 MDB[ids].prices.wool += 200 * (MDB[ids].inventory.wool) + 2000;
5890 MDB[ids].meowRate += 40;
5891 MDB[ids].inventory.wool += 1;
5892 sendChat('Wool added to ' + name + '\'s inventory! Next one will cost [' + MDB[ids].prices.wool + ' MP] (' + MDB[ids].inventory.wool + ' wool in kitty storage) MP [' + MDB[ids].meowP + ']');
5893 } else {
5894 sendChat(meowNeP + ' wool. You need ' + Math.abs(MDB[ids].meowP - MDB[ids].prices.wool) + ' more MP! (' + MDB[ids].inventory.wool + ' wool in kitty storage) MP [' + MDB[ids].meowP + ']');
5895 }
5896
5897 // water
5898 } else if (message.substring(cmd.length).trim() == 'water') {
5899 if (MDB[ids].meowP >= MDB[ids].prices.water) {
5900 MDB[ids].meowP -= MDB[ids].prices.water;
5901 MDB[ids].prices.water += 1500 * (MDB[ids].inventory.water) + 15000;
5902 MDB[ids].meowRate += 300;
5903 MDB[ids].inventory.water += 1;
5904 sendChat('Water added to ' + name + '\'s inventory! Next one will cost [' + MDB[ids].prices.water + ' MP] (' + MDB[ids].inventory.water + ' water in kitty storage) MP [' + MDB[ids].meowP + ']');
5905 } else {
5906 sendChat(meowNeP + ' water. You need ' + Math.abs(MDB[ids].meowP - MDB[ids].prices.water) + ' more MP! (' + MDB[ids].inventory.water + ' water in kitty storage) MP [' + MDB[ids].meowP + ']');
5907 }
5908
5909 // milk
5910 } else if (message.substring(cmd.length).trim() == 'milk') {
5911 if (MDB[ids].meowP >= MDB[ids].prices.milk) {
5912 MDB[ids].meowP -= MDB[ids].prices.milk;
5913 MDB[ids].prices.milk += 5000 * (MDB[ids].inventory.milk) + 50000;
5914 MDB[ids].meowRate += 1000;
5915 MDB[ids].inventory.milk += 1;
5916 sendChat('Milk added to ' + name + '\'s inventory! Next one will cost [' + MDB[ids].prices.milk + ' MP] (' + MDB[ids].inventory.milk + ' milk in kitty storage) MP [' + MDB[ids].meowP + ']');
5917 } else {
5918 sendChat(meowNeP + ' milk. You need ' + Math.abs(MDB[ids].meowP - MDB[ids].prices.milk) + ' more MP! (' + MDB[ids].inventory.milk + ' milk in kitty storage) MP [' + MDB[ids].meowP + ']');
5919 }
5920
5921 // banana milk
5922 } else if (message.substring(cmd.length).trim() == 'banana milk') {
5923 if (MDB[ids].meowP >= MDB[ids].prices.bananaMilk) {
5924 MDB[ids].meowP -= MDB[ids].prices.bananaMilk;
5925 MDB[ids].prices.bananaMilk += 10000 * (MDB[ids].inventory.bananaMilk) + 100000;
5926 MDB[ids].meowRate += 2000;
5927 MDB[ids].inventory.bananaMilk += 1;
5928 sendChat('Banana milk added to ' + name + '\'s inventory! Next one will cost [' + MDB[ids].prices.bananaMilk + ' MP] (' + MDB[ids].inventory.bananaMilk + ' banana milk in kitty storage) MP [' + MDB[ids].meowP + ']');
5929 } else {
5930 sendChat(meowNeP + ' banana milk. You need ' + Math.abs(MDB[ids].meowP - MDB[ids].prices.bananaMilk) + ' more MP! (' + MDB[ids].inventory.bananaMilk + ' banana milk in kitty storage) MP [' + MDB[ids].meowP + ']');
5931 }
5932
5933 // cheese
5934 } else if (message.substring(cmd.length).trim() == 'cheese') {
5935 if (MDB[ids].meowP >= MDB[ids].prices.cheese) {
5936 MDB[ids].meowP -= MDB[ids].prices.cheese;
5937 MDB[ids].prices.cheese += 2500000000 * (MDB[ids].inventory.cheese) + 25000000000;
5938 MDB[ids].meowRate += 500000000;
5939 MDB[ids].inventory.cheese += 1;
5940 MDB[ids].cheeseMaster = true;
5941 sendChat('✯ Cheese added to ' + name + '\'s inventory! Next one will cost [' + MDB[ids].prices.cheese + ' MP] (' + MDB[ids].inventory.cheese + ' cheese in kitty storage) MP [' + MDB[ids].meowP + '] ✯');
5942 } else {
5943 sendChat(meowNeP + ' cheese. You need a whopping ' + Math.abs(MDB[ids].meowP - MDB[ids].prices.cheese) + ' more MP! (' + MDB[ids].inventory.cheese + ' cheese in kitty storage) MP [' + MDB[ids].meowP + ']');
5944 }
5945 }
5946
5947 //item prices: 250000
5948
5949 // kitty storage
5950 } else if (cmd == cmdChar+"meowinventory" || cmd == cmdChar+"minv") {
5951 if (message.length == cmd.length) {
5952 if (!MDB[ids].meowing) {
5953 sendChat('You must start the game again with '+cmdChar+'mp before kitty storage is setup!');
5954 return;
5955 }
5956 if(gClient.isOwner()) sendChat('✯ Meow! Welcome to Kitty Storage! This is where we keep all your purchased items :3 MP [' + MDB[ids].meowP + '] ✯');
5957 sendChat('MP [' + MDB[ids].meowP + '] (string ' + MDB[ids].inventory.string + ') (yarn ' + MDB[ids].inventory.yarn + ') (wool ' + MDB[ids].inventory.wool + ') (water ' + MDB[ids].inventory.water + ') (milk ' + MDB[ids].inventory.milk + ') (banana milk ' + MDB[ids].inventory.bananaMilk + ') (cheese ' + MDB[ids].inventory.cheese + ')');
5958
5959 } else {
5960 var target = msg.a.substring(cmd.length).trim();
5961 var part = getUser(target.toLowerCase());
5962
5963 if (part) {
5964 if (!MDB[part._id] || !MDB[part._id].meowing) {
5965 sendChat(part.name+ ' isn\'t playing Meowpuff. They need to type '+cmdChar+'mp to create or load a save');
5966 return;
5967 }
5968
5969 if (part.name == name) {
5970 sendChat('Your MP [' + MDB[ids].meowP + '] (string ' + MDB[ids].inventory.string + ') (yarn ' + MDB[ids].inventory.yarn + ') (wool ' + MDB[ids].inventory.wool + ') (water ' + MDB[ids].inventory.water + ') (milk ' + MDB[ids].inventory.milk + ') (banana milk ' + MDB[ids].inventory.bananaMilk + ') (cheese ' + MDB[ids].inventory.cheese + ')');
5971 return;
5972 }
5973 sendChat(part.name+'\'s MP [' + MDB[part._id].meowP + '] (string ' + MDB[part._id].inventory.string + ') (yarn ' + MDB[part._id].inventory.yarn + ') (wool ' + MDB[part._id].inventory.wool + ') (water ' + MDB[part._id].inventory.water + ') (milk ' + MDB[part._id].inventory.milk + ') (banana milk ' + MDB[part._id].inventory.bananaMilk + ') (cheese ' + MDB[part._id].inventory.cheese + ')');
5974
5975 } else {
5976 sendChat(userNotFound);
5977 }
5978 }
5979 //Meow save
5980 } else if (cmd == cmdChar+"meowsave" || cmd == cmdChar+"msave") { //notes: I need to set the meowing property to false for all when saving so I use meowing as a check for the timer too!
5981 try {
5982 L.MDB = MDB.toString(); //saves everyone for simplicity
5983 // get the number of people playing
5984 var played = 0;
5985 var playing = 0;
5986 var totalDays = 0;
5987 for (var id in MDB) {
5988 if (MDB[id].meowing) ++playing;
5989 if (!MDB[id].meowing) ++played;
5990 totalDays += MDB[id].meowTime;
5991 }
5992
5993 sendChat('Everyones stats have been saved! [playing: ' + playing + ', total players: ' + played + ' | ' + (totalDays / 86400).toPrecision(4) + ' total days]');
5994
5995 } catch (e) {
5996 sendChat('[There was an error in your code!] You need to start the game before you can play! (type '+cmdChar+'mp) err[' + e + ']'); // this probably won't happen
5997 }
5998 //Meow save
5999
6000 //Meow copy sentence mini-game
6001 } else if (cmd == cmdChar+"meowtype" || cmd == cmdChar+"mtype") {
6002 if (!askedEnglish) {
6003 Array.prototype.random = function(a){ //thanks SomeGuy for prototype
6004 if(this){
6005 var b = Math.floor(Math.random() * this.length);
6006 return this[b];
6007 }
6008 }
6009
6010 // arrays
6011 var colours = ["red", "orange", "yellow", "green", "blue", "purple", "gray", "black", "white"];
6012 var conjunctions = ["for", "and", "but", "or", "yet", "so", "after", "as long as", "before", "by the time", "now that", "once", "since", "till", "until", "when", "whenever", "while", "even if", "than", "rather than", "because", "why", "if", "only if", "unless", "assuming that", "in which case"];
6013 var verbs = ["accept", "ache", "acknowledge", "act", "add", "admire", "admit", "admonish", "advise", "adopt", "affirm", "afford", "agree", "ail", "alert", "allege", "allow", "allude", "amuse", "analyse", "announce", "annoy", "answer", "apologize", "appeal", "appear", "applaud", "appreciate", "approve", "argue", "arrange", "arrest", "arrive", "articulate", "ask", "assert", "assure", "attach", "attack", "attempt", "attend", "attract", "auction", "avoid", "avow", "awake", "babble", "back", "bake", "balance", "balk", "ban", "bang", "bandage", "bar", "bare", "bargain", "bark", "barrage", "barter", "baste", "bat", "bathe", "battle", "bawl", "be", "beam", "bear", "beat", "become", "befriend", "beg", "begin", "behave", "believe", "bellow", "belong", "bend", "berate", "besiege", "bestow", "bet", "bid", "bite", "bleach", "bleed", "bless", "blind", "blink", "blot", "blow", "blurt", "blush", "boast", "bob", "boil", "bolt", "bomb", "book", "bore", "borrow", "bounce", "bow", "box", "brag", "brake", "branch", "brand", "break", "breathe", "breed", "bring", "broadcast", "broil", "bruise", "brush", "bubble", "build", "bump", "burn", "burnish", "bury", "buy", "buzz", "cajole", "calculate", "call", "camp", "care", "carry", "carve", "cause", "caution", "catch", "challenge", "change", "chant", "charge", "chase", "cheat", "check", "cheer", "chew", "chide", "chip", "choke", "chomp", "choose", "chop", "claim", "clap", "clean", "clear", "climb", "clip", "close", "coach", "coil", "collect", "color", "comb", "come", "comfort", "command", "comment", "communicate", "compare", "compete", "complain", "complete", "concede", "concentrate", "concern", "conclude", "concur", "confess", "confide", "confirm", "connect", "consent", "consider", "consist", "contain", "contend", "continue", "cook", "copy", "correct", "cost", "cough", "count", "counter", "cover", "covet", "crack", "crash", "crave", "crawl", "crochet", "cross", "criticize", "croak", "cross-examine", "crowd", "crush", "cry", "cure", "curl", "curse", "curve", "cut", "cycle", "dam", "damage", "dance", "dare", "deal", "debate", "decay", "deceive", "decide", "decipher", "declare", "decorate", "delay", "delight", "deliver", "demand", "deny", "depend", "describe", "desert", "deserve", "desire", "deter", "develop", "dial", "dictate", "die", "dig", "digress", "direct", "disclose", "dislike", "dive", "divide", "divorce", "divulge", "do", "dock", "dole", "dote", "double", "doubt", "drag", "drain", "draw", "dream", "dress", "drip", "drill", "drink", "drive", "drone", "drop", "drown", "dry", "dupe", "dump", "dust", "dye", "earn", "eat", "echo", "edit", "educate", "elope", "embarrass", "emigrate", "emit", "emphasise", "employ", "empty", "enchant", "encode", "encourage", "end", "enjoin", "enjoy", "enter", "entertain", "enunciate", "envy", "equivocate", "escape", "evacuate", "evaporate", "exaggerate", "examine", "excite", "exclaim", "excuse", "exercise", "exist", "expand", "expect", "expel", "exhort", "explain", "explode", "explore", "extend", "extoll", "face", "fade", "fail", "fall", "falter", "fasten", "favor", "fax", "fear", "feed", "feel", "fence", "fetch", "fight", "file", "fill", "film", "find", "fire", "fish", "fit", "fix", "flap", "flash", "flee", "float", "flood", "floss", "flow", "flower", "fly", "fold", "follow", "fool", "force", "foretell", "forget", "forgive", "form", "found", "frame", "freeze", "fret", "frighten", "fry", "fume", "garden", "gasp", "gather", "gaze", "gel", "get", "gild", "give", "glide", "glue", "gnaw", "go", "grab", "grate", "grease", "greet", "grill", "grin", "grip", "groan", "grow", "growl", "grumble", "grunt", "guarantee", "guard", "guess", "guide", "gurgle", "gush", "hail", "hammer", "hand", "handle", "hang", "happen", "harass", "harm", "harness", "hate", "haunt", "have", "head", "heal", "heap", "hear", "heat", "help", "hide", "highlight", "hijack", "hinder", "hint", "hiss", "hit", "hold", "hook", "hoot", "hop", "hope", "hover", "howl", "hug", "hum", "hunt", "hurry", "hurt", "ice", "identify", "ignore", "imagine", "immigrate", "imply", "implore", "impress", "improve", "include", "increase", "infect", "inflate", "influence", "inform", "infuse", "inject", "injure", "inquire", "insist", "inspect", "inspire", "instruct", "intend", "interest", "interfere", "interject", "interrupt", "introduce", "invent", "invest", "invite", "irritate", "iron", "itch", "jab", "jabber", "jail", "jam", "jeer", "jest", "jog", "join", "joke", "jolt", "judge", "juggle", "jump", "keep", "kick", "kill", "kiss", "kneel", "knit", "knock", "knot", "know", "label", "lament", "land", "last", "laugh", "lay", "lead", "lean", "learn", "leave", "lecture", "lend", "let", "level", "license", "lick", "lie", "lift", "light", "lighten", "like", "list", "listen", "live", "load", "loan", "lock", "long", "look", "loosen", "lose", "love", "lower", "mail", "maintain", "make", "man", "manage", "mar", "march", "mark", "marry", "marvel", "mate", "matter", "mean", "measure", "meet", "melt", "memorise", "mend", "mention", "merge", "milk", "mine", "miss", "mix", "moan", "moor", "mourn", "molt", "move", "mow", "mug", "multiply", "mumble", "murder", "mutter", "nag", "nail", "name", "nap", "need", "nest", "nod", "note", "notice", "number", "obey", "object", "observe", "obtain", "occur", "offend", "offer", "ogle", "oil", "omit", "open", "operate", "order", "overflow", "overrun", "owe", "own", "pack", "pad", "paddle", "paint", "pant", "park", "part", "pass", "paste", "pat", "pause", "pay", "peck", "pedal", "peel", "peep", "peer", "peg", "pelt", "perform", "permit", "pester", "pet", "phone", "pick", "pinch", "pine", "place", "plan", "plant", "play", "plead", "please", "pledge", "plow", "plug", "point", "poke", "polish", "ponder", "pop", "possess", "post", "postulate", "pour", "practice", "pray", "preach", "precede", "predict", "prefer", "prepare", "present", "preserve", "press", "pretend", "prevent", "prick", "print", "proceed", "proclaim", "produce", "profess", "program", "promise", "propose", "protect", "protest", "provide", "pry", "pull", "pump", "punch", "puncture", "punish", "push", "put", "question", "quilt", "quit", "quiz", "quote", "race", "radiate", "rain", "raise", "rant", "rain", "rate", "rave", "reach", "realise", "read", "rebuff", "recall", "receive", "recite", "recognise", "recommend", "record", "reduce", "reflect", "refuse", "regret", "reign", "reiterate", "reject", "rejoice", "relate", "relax", "release", "rely", "remain", "remember", "remind", "remove", "repair", "repeat", "replace", "reply", "report", "reprimand", "reproduce", "request", "rescue", "retire", "retort", "return", "reveal", "reverse", "rhyme", "ride", "ring", "rinse", "rise", "risk", "roar", "rob", "rock", "roll", "rot", "row", "rub", "ruin", "rule", "run", "rush", "sack", "sail", "satisfy", "save", "savor", "saw", "say", "scare", "scatter", "scoff", "scold", "scoot", "scorch", "scrape", "scratch", "scream", "screech", "screw", "scribble", "seal", "search", "see", "sell", "send", "sense", "separate", "serve", "set", "settle", "sever", "sew", "shade", "shampoo", "share", "shave", "shelter", "shift", "shiver", "shock", "shoot", "shop", "shout", "show", "shriek", "shrug", "shut", "sigh", "sign", "signal", "sin", "sing", "singe", "sip", "sit", "skate", "skateboard", "sketch", "ski", "skip", "slap", "sleep", "slice", "slide", "slip", "slow", "smash", "smell", "smile", "smoke", "snap", "snarl", "snatch", "sneak", "sneer", "sneeze", "snicker", "sniff", "snore", "snort", "snoop", "snooze", "snow", "soak", "sob", "soothe", "sound", "sow", "span", "spare", "spark", "sparkle", "speak", "speculate", "spell", "spend", "spill", "spin", "spoil", "spot", "spray", "sprout", "sputter", "squash", "squeeze", "stab", "stain" ,"stammer", "stamp", "stand", "star", "stare", "start", "state", "stay", "steer", "step", "stipulate", "stir", "stitch", "stop", "store", "strap", "storm", "stow", "strengthen", "stress", "stretch", "strip", "stroke", "stuff", "stutter", "stray", "strum", "strut", "stun", "stunt", "submerge", "succeed", "suffer", "suggest", "suit", "supply", "support", "suppose", "surmise", "surprise", "surround", "suspect", "suspend", "sway", "swear", "swim", "swing", "switch", "swoop", "sympathize", "talk", "take", "tame", "tap", "taste", "taunt", "teach", "tear", "tease", "telephone", "tell", "tempt", "terrify", "test", "testify", "thank", "thaw", "theorize", "think", "threaten", "throw", "thunder", "tick", "tickle", "tie", "time", "tip", "tire", "toast", "toss", "touch", "tour", "tow", "trace", "track", "trade", "train", "translate", "transport", "trap", "travel", "treat", "tremble", "trick", "trickle", "trim", "trip", "trot", "trouble", "trust", "trounce", "try", "tug", "tumble", "turn", "twist", "type", "understand", "undress", "unfasten", "unite", "unlock", "unpack", "uphold", "upset", "upstage", "urge", "untie", "use", "usurp", "utter", "vacuum", "value", "vanish", "vanquish", "venture", "visit", "voice", "volunteer", "vote", "vouch", "wail", "wait", "wake", "walk", "wallow", "wander", "want", "warm", "warn", "wash", "waste", "watch", "water", "wave", "waver", "wear", "weave", "wed", "weigh", "welcome", "whimper", "whine", "whip", "whirl", "whisper", "whistle", "win", "wink", "wipe", "wish", "wobble", "wonder", "work", "worry", "wrap", "wreck", "wrestle", "wriggle", "write", "writhe", "x-ray", "yawn", "yell", "yelp", "yield", "yodel", "zip", "zoom"];
6014 var determiners = ["the", "a", "another", "some", "any", "my", "our", "their", "her", "his", "its", "each", "every", "certain", "this", "that"];
6015 var nouns = ["account", "achiever", "acoustics", "act", "action", "activity", "actor", "addition", "adjustment", "advertisement", "advice", "aftermath", "afternoon", "afterthought", "agreement", "air", "airplane", "airport", "alarm", "amount", "amusement", "anger", "angle", "animal", "answer", "ant", "ants", "apparatus", "apparel", "apple", "apples", "appliance", "approval", "arch", "argument", "arithmetic", "arm", "army", "art", "attack", "attempt", "attention", "attraction", "aunt", "authority", "babies", "baby", "back", "badge", "bag", "bait", "balance", "ball", "balloon", "balls", "banana", "band", "base", "baseball", "basin", "basket", "basketball", "bat", "bath", "battle", "bead", "beam", "bean", "bear", "bears", "beast", "bed", "bedroom", "beds", "bee", "beef", "beetle", "beggar", "beginner", "behaviour", "belief", "believe", "bell", "bells", "berry", "bike", "bikes", "bird", "birds", "birth", "birthday", "bit", "bite", "blade", "blood", "blow", "board", "boat", "boats", "body", "bomb", "bone", "book", "books", "boot", "border", "bottle", "boundary", "box", "boy", "boys", "brain", "brake", "branch", "brass", "bread", "breakfast", "breath", "brick", "bridge", "brother", "brothers", "brush", "bubble", "bucket", "building", "bulb", "bun", "burn", "burst", "bushes", "business", "butter", "button", "cabbage", "cable", "cactus", "cake", "cakes", "calculator", "calendar", "camera", "camp", "can", "cannon", "canvas", "cap", "caption", "car", "card", "care", "carpenter", "carriage", "cars", "cart", "cast", "cat", "cats", "cattle", "cause", "cave", "celery", "cellar", "cemetery", "cent", "chain", "chair", "chairs", "chalk", "chance", "change", "channel", "cheese", "cherries", "cherry", "chess", "chicken", "chickens", "children", "chin", "church", "circle", "clam", "class", "clock", "clocks", "cloth", "cloud", "clouds", "clover", "club", "coach", "coal", "coast", "coat", "cobweb", "coil", "collar", "color", "comb", "comfort", "committee", "company", "comparison", "competition", "condition", "connection", "control", "cook", "copper", "copy", "cord", "cork", "corn", "cough", "country", "cover", "cow", "cows", "crack", "cracker", "crate", "crayon", "cream", "creator", "creature", "credit", "crib", "crime", "crook", "crow", "crowd", "crown", "crush", "cry", "cub", "cup", "current", "curtain", "curve", "cushion", "dad", "daughter", "day", "death", "debt", "decision", "deer", "degree", "design", "desire", "desk", "destruction", "detail", "development", "digestion", "dime", "dinner", "dinosaurs", "direction", "dirt", "discovery", "discussion", "disease", "disgust", "distance", "distribution", "division", "dock", "doctor", "dog", "dogs", "doll", "dolls", "donkey", "door", "downtown", "drain", "drawer", "dress", "drink", "driving", "drop", "drug", "drum", "duck", "ducks", "dust", "ear", "earth", "earthquake", "edge", "education", "effect", "egg", "eggnog", "eggs", "elbow", "end", "engine", "error", "event", "example", "exchange", "existence", "expansion", "experience", "expert", "eye", "eyes", "face", "fact", "fairies", "fall", "family", "fan", "fang", "farm", "farmer", "father", "faucet", "fear", "feast", "feather", "feeling", "feet", "fiction", "field", "fifth", "fight", "finger", "fire", "fireman", "fish", "flag", "flame", "flesh", "flight", "flock", "floor", "flower", "flowers", "fly", "fog", "fold", "food", "foot", "force", "fork", "form", "fowl", "frame", "friction", "friend", "friends", "frog", "frogs", "front", "fruit", "fuel", "furniture", "alley", "game", "garden", "gate", "geese", "ghost", "giants", "giraffe", "girl", "girls", "glass", "glove", "glue", "goat", "gold", "goldfish", "good-bye", "goose", "government", "governor", "grade", "grain", "grandfather", "grandmother", "grape", "grass", "grip", "ground", "group", "growth", "guide", "guitar", "gun", "hair", "haircut", "hall", "hammer", "hand", "hands", "harmony", "hat", "hate", "head", "health", "hearing", "heart", "heat", "help", "hen", "hill", "history", "hobbies", "hole", "holiday", "home", "honey", "hook", "hope", "horn", "horse", "horses", "hose", "hospital", "hot", "hour", "house", "houses", "humour", "hydrant", "ice", "icicle", "idea", "impulse", "income", "increase", "industry", "ink", "insect", "instrument", "insurance", "interest", "invention", "iron", "island", "jail", "jam", "jar", "jeans", "jelly", "jellyfish", "jewel", "join", "joke", "journey", "judge", "juice", "jump", "K", "kettle", "key", "kick", "kiss", "kite", "kitten", "kittens", "kitty", "knee", "knife", "knot", "knowledge", "labourer", "lace", "ladybug", "lake", "lamp", "land", "language", "laugh", "lawyer", "lead", "leaf", "learning", "leather", "leg", "legs", "letter", "letters", "lettuce", "level", "library", "lift", "light", "limit", "line", "linen", "lip", "liquid", "list", "lizards", "loaf", "lock", "locket", "look", "loss", "love", "low", "lumber", "lunch", "lunchroom", "machine", "magic", "maid", "mailbox", "man", "manager", "map", "marble", "mark", "market", "mask", "mass", "match", "meal", "measure", "meat", "meeting", "memory", "men", "metal", "mice", "middle", "milk", "mind", "mine", "minister", "mint", "minute", "mist", "mitten", "mom", "money", "monkey", "month", "moon", "morning", "mother", "motion", "mountain", "mouth", "move", "muscle", "music", "nail", "name", "nation", "neck", "need", "needle", "nerve", "nest", "net", "news", "night", "noise", "north", "nose", "note", "notebook", "number", "nut", "oatmeal", "observation", "ocean", "offer", "office", "oil", "operation", "opinion", "orange", "oranges", "order", "organization", "ornament", "oven", "owl", "owner", "P", "page", "pail", "pain", "paint", "pan", "pancake", "paper", "parcel", "parent", "park", "part", "partner", "party", "passenger", "paste", "patch", "payment", "peace", "pear", "pen", "pencil", "person", "pest", "pet", "pets", "pickle", "picture", "pie", "pies", "pig", "pigs", "pin", "pipe", "pizzas", "place", "plane", "planes", "plant", "plantation", "plants", "plastic", "plate", "play", "playground", "pleasure", "plot", "plough", "pocket", "point", "poison", "police", "polish", "pollution", "popcorn", "porter", "position", "pot", "potato", "powder", "power", "price", "print", "prison", "process", "produce", "profit", "property", "prose", "protest", "pull", "pump", "punishment", "purpose", "push", "quarter", "quartz", "queen", "question", "quicksand", "quiet", "quill", "quilt", "quince", "quiver", "rabbit", "rabbits", "rail", "railway", "rain", "rainstorm", "rake", "range", "rat", "rate", "ray", "reaction", "reading", "reason", "receipt", "recess", "record", "regret", "relation", "religion", "representative", "request", "respect", "rest", "reward", "rhythm", "rice", "riddle", "rifle", "ring", "rings", "river", "road", "robin", "rock", "rod", "roll", "roof", "room", "root", "rose", "route", "rub", "rule", "run", "sack", "sail", "salt", "sand", "scale", "scarecrow", "scarf", "scene", "scent", "school", "science", "scissors", "screw", "sea", "seashore", "seat", "secretary", "seed", "selection", "self", "sense", "servant", "shade", "shake", "shame", "shape", "sheep", "sheet", "shelf", "ship", "shirt", "shock", "shoe", "shoes", "shop", "show", "side", "sidewalk", "sign", "silk", "silver", "sink", "sister", "sisters", "size", "skate", "skin", "skirt", "sky", "slave", "sleep", "sleet", "slip", "slope", "smash", "smell", "smile", "smoke", "snail", "snails", "snake", "snakes", "sneeze", "snow", "soap", "society", "sock", "soda", "sofa", "son", "song", "songs", "sort", "sound", "soup", "space", "spade", "spark", "spiders", "sponge", "spoon", "spot", "spring", "spy", "square", "squirrel", "stage", "stamp", "star", "start", "statement", "station", "steam", "steel", "stem", "step", "stew", "stick", "sticks", "stitch", "stocking", "stomach", "stone", "stop", "store", "story", "stove", "stranger", "straw", "stream", "street", "stretch", "string", "structure", "substance", "sugar", "suggestion", "suit", "summer", "sun", "support", "surprise", "sweater", "swim", "swing", "system", "table", "tail", "talk", "tank", "taste", "tax", "teaching", "team", "teeth", "temper", "tendency", "tent", "territory", "test", "texture", "theory", "thing", "things", "thought", "thread", "thrill", "throat", "throne", "thumb", "thunder", "ticket", "tiger", "time", "tin", "title", "toad", "toe", "toes", "tomatoes", "tongue", "tooth", "toothbrush", "toothpaste", "top", "touch", "town", "toy", "toys", "trade", "trail", "train", "trains", "tramp", "transport", "tray", "treatment", "tree", "trees", "trick", "trip", "trouble", "trousers", "truck", "trucks", "tub", "turkey", "turn", "twig", "twist", "umbrella", "uncle", "underwear", "unit", "use", "vacation", "value", "van", "vase", "vegetable", "veil", "vein", "verse", "vessel", "vest", "view", "visitor", "voice", "volcano", "volleyball", "voyage", "walk", "wall", "war", "wash", "waste", "watch", "water", "wave", "waves", "wax", "way", "wealth", "weather", "week", "weight", "wheel", "whip", "whistle", "wilderness", "wind", "window", "wine", "wing", "winter", "wire", "wish", "woman", "women", "wood", "wool", "word", "work", "worm", "wound", "wren", "wrench", "wrist", "writer", "writing", "yak", "yam", "yard", "yarn", "year", "yoke", "zebra", "zephyr", "zinc", "zipper", "zoo"];
6016 var adjectives = ["angry", "bewildered", "clumsy", "defeated", "embarrassed", "fierce", "grumpy", "helpless", "itchy", "jealous", "lazy", "mysterious", "nervous", "obnoxious", "panicky", "repulsive", "scary", "thoughtless", "uptight", "worried", "alive", "better", "careful", "clever", "dead", "easy", "famous", "gifted", "helpful", "important", "inexpensive", "mushy", "odd", "powerful", "rich", "shy", "tender", "uninterested", "vast", "wrong", "adorable", "beautiful", "clean", "drab", "elegant", "fancy", "glamorous", "handsome", "long", "magnificent", "old-fashioned", "plain", "quaint", "sparkling", "ugliest", "unsightly", "wide-eyed", "deafening", "faint", "hissing", "loud", "melodic", "noisy", "purring", "quiet", "raspy", "screeching", "thundering", "voiceless", "whispering", "big", "colossal", "fat", "gigantic", "great", "huge", "immense", "large", "little", "mammoth", "massive", "miniature", "petite", "puny", "scrawny", "short", "small", "tall", "teeny", "teeny-tiny", "tiny", "broad", "chubby", "crooked", "curved", "deep", "flat", "high", "hollow", "low", "narrow", "round", "shallow", "skinny", "square", "steep", "straight", "wide", "agreeable", "brave", "calm", "delightful", "eager", "faithful", "gentle", "happy", "jolly", "kind", "lively", "nice", "obedient", "proud", "relieved", "silly", "thankful", "victorious", "witty", "zealous", "abundant", "empty", "few", "full", "heavy", "light", "many", "numerous", "sparse", "substantial", "boiling", "breeze", "broken", "bumpy", "chilly", "cold", "cool", "creepy", "crooked", "cuddly", "curly", "damaged", "damp", "dirty", "dry", "dusty", "filthy", "flaky", "fluffy", "freezing", "hot", "warm", "wet", "bitter", "delicious", "fresh", "greasy", "juicy", "hot", "icy", "loose", "melted", "nutritious", "prickly", "rainy", "rotten", "salty", "sticky", "strong", "sweet", "tart", "tasteless", "uneven", "weak", "wet", "wooden", "yummy", "ancient", "brief", "early", "fast", "late", "long", "modern", "old", "old-fashioned", "quick", "rapid", "short", "slow", "swift", "young"];
6017
6018 //consider cleaning up this code when you have free time
6019
6020 try {
6021 if (!hardEnglish) {
6022 //easy (normal)
6023 var str = determiners.random() + " " + adjectives.random() + " " + verbs.random() + " " + nouns.random() + " " + conjunctions.random() + " " + verbs.random() + " " + nouns.random() + " " + verbs.random() + ".";
6024 sentence = capitalizeFirstLetter(str);
6025 var antiCopy = sentence.split(" ").join(" \u034f\uFFFC");
6026 sentenceAntiCopy = capitalizeFirstLetter(antiCopy);
6027 }
6028 if (hardEnglish) {
6029 //hard (test)
6030 var str = randStr(hardLength);
6031 sentence = str;
6032 var antiCopy = sentence.split("").join("\u034f\uFFFC");
6033 sentenceAntiCopy = antiCopy;
6034 }
6035 sendChat("First person to type this wins: " + sentenceAntiCopy);
6036
6037 } catch(e) {
6038 sendChat('Error in my code: ' + e);
6039 }
6040 askedEnglish = true;
6041
6042 } else {
6043 sendChat("To answer, type the following in chat: " + sentenceAntiCopy);
6044 }
6045
6046 } else if (cmd == cmdChar+"mstats") {
6047 var mp = 0;
6048 var mr = 0;
6049
6050 var string = 0;
6051 var yarn = 0;
6052 var wool = 0;
6053 var water = 0;
6054 var milk = 0;
6055 var bananaMilk = 0;
6056 var cheese = 0;
6057
6058 for (var id in MDB) {
6059 mp += parseInt(MDB[id].meowP);
6060 mr += MDB[id].meowRate;
6061
6062 string += MDB[id].inventory.string;
6063 yarn += MDB[id].inventory.yarn;
6064 wool += MDB[id].inventory.wool;
6065 water += MDB[id].inventory.water;
6066 milk += MDB[id].inventory.milk;
6067 bananaMilk += MDB[id].inventory.bananaMilk;
6068 cheese += MDB[id].inventory.cheese;
6069 }
6070
6071 sendChat("Meowpuff total stats: MP ["+mp+"], MPS ["+mr+"], string ["+string+"], \
6072 yarn ["+yarn+"], wool ["+wool+"], water ["+water+"], milk ["+milk+"], \
6073 banana milk ["+bananaMilk+"], cheese ["+cheese+"].");
6074
6075 //Meow game
6076
6077 // Math *warning* messy code below, brace yourself.
6078 } else if (cmd == cmdChar+"mathhelp") {
6079 sendChat("Math commands: "+cmdChar+"math (for answering/getting new question), "+cmdChar+"mathskip (skips tough/glitched questions), "+cmdChar+"mathdiff (difficulty setting. pick between: 0 very easy, 1 easy, 2 medium, 3 hard and 4 insane 5 asian)");
6080
6081 } else if (cmd == cmdChar+"mathdiff") {
6082 if (message.substring(9).trim() == "" || isNaN(message.substring(9).trim()) || message.substring(9).trim() < -1 || message.substring(9).trim() > 5) {
6083 sendChat("Usage: "+cmdChar+"mathdiff 1 (0 = very easy, 1 = easy, 2 = medium, 3 = hard, 4 = insane)");
6084 } else {
6085 mathDiff = message.substring(9).trim();
6086 if (mathDiff == 0) {
6087 mathDiffTxt = "Very Easy \"Piki-Mode\"";
6088 }
6089 if (mathDiff == 1) {
6090 mathDiffTxt = "Easy";
6091 }
6092 if (mathDiff == 2) {
6093 mathDiffTxt = "Medium";
6094 }
6095 if (mathDiff == 3) {
6096 mathDiffTxt = "Hard";
6097 }
6098 if (mathDiff == 4) {
6099 mathDiffTxt = "Insane";
6100 }
6101 if (mathDiff == 5) {
6102 mathDiffTxt = "Asian";
6103 }
6104 if (mathDiff == -1) {
6105 mathDiffTxt = "The Answer to Life, the Universe, and Everything *cough cough*";
6106 }
6107
6108 sendChat(name + " set the difficulty to " + mathDiffTxt);
6109 asked = false;
6110 }
6111
6112 } else if (cmd == cmdChar+"math") {
6113 if (message.length > 5 && !asked) {
6114 return; //might remove if typing !math 69 bringing up a questions seems easier
6115 }
6116 // difficulty settings
6117 if (mathDiff == 0) {
6118 questions = [randNum(1,10) + " + " + randNum(1,10),
6119 randNum(1,10) + " - " + randNum(1,10),
6120 randNum(1,10) + " - " + randNum(1,10)];
6121 pickQuestion = Math.floor( Math.random() * questions.length );
6122 }
6123
6124 if (mathDiff == 1) {
6125 questions = [randNum(1,50) + " + " + randNum(1,20),
6126 randNum(1,50) + " - " + randNum(1,10),
6127 randNum(1,20) + " * " + randNum(1,2),
6128 randNum(1,20) + " % " + randNum(1,2)];
6129 pickQuestion = Math.floor( Math.random() * questions.length );
6130 }
6131
6132 if (mathDiff == 2) {
6133 questions = [randNum(1,100) + " + " + randNum(1,20),
6134 randNum(1,100) + " - " + randNum(1,20),
6135 randNum(1,20) + " * " + randNum(1,10),
6136 randNum(1,50) + " % " + randNum(1,10)];
6137 pickQuestion = Math.floor( Math.random() * questions.length );
6138 }
6139
6140 if (mathDiff == 3) {
6141 questions = [randNum(1,400) + " + " + randNum(1,20),
6142 randNum(1,400) + " - " + randNum(1,300),
6143 randNum(1,100) + " * " + randNum(1,50),
6144 randNum(1,100) + " % " + randNum(1,50)];
6145 pickQuestion = Math.floor( Math.random() * questions.length );
6146 }
6147
6148 if (mathDiff == 4) {
6149 questions = [randNum(1,1000) + " + " + randNum(1,100),
6150 randNum(1,1000) + " - " + randNum(1,100),
6151 randNum(1,1000) + " * " + randNum(1,100)];
6152 pickQuestion = Math.floor( Math.random() * questions.length );
6153 }
6154
6155 if (mathDiff == 5) {
6156 questions = [randNum(-10000000,10000000) + " + " + randNum(-10000000,10000000),
6157 randNum(-10000000,10000000) + " - " + randNum(-10000000,10000000),
6158 randNum(-10000000,10000000) + " * " + randNum(-10000000,10000000),
6159 randNum(-10000000,10000000) + " / " + randNum(-10000000,10000000),
6160 randNum(-10000000,10000000) + " % " + randNum(-10000000,10000000)];
6161 pickQuestion = Math.floor( Math.random() * questions.length );
6162 }
6163
6164 if (mathDiff == -1) {
6165 questions = [randNum(1,400) + " + " + randNum(1,20),
6166 randNum(1,400) + " - " + randNum(1,300),
6167 randNum(1,400) + " * " + randNum(1,50)];
6168 pickQuestion = Math.floor( Math.random() * questions.length );
6169 }
6170
6171 // difficulty settings
6172 if (!asked) {
6173 // life easter egg
6174 if (mathDiff == -1) {
6175 question = questions[pickQuestion];
6176 while (eval(question) != 42) {
6177 questions = [randNum(1,400) + " + " + randNum(1,400),
6178 randNum(1,400) + " - " + randNum(1,400),
6179 randNum(1,400) + " * " + randNum(1,400)];
6180
6181 pickQuestion = Math.floor( Math.random() * questions.length );
6182 question = questions[pickQuestion];
6183 }
6184
6185 sendChat("What\u034f i\u034fs " + question + "\u034f? (to answer type "+cmdChar+"math <answer>). Difficulty - " + mathDiffTxt);
6186 asked = true;
6187
6188 // cheater >:3
6189 if (mathCheat) setTimeout( function() { MPP.chat.send(""+cmdChar+"math " + eval(question)) }, randNum(1000, 2500));
6190
6191 } else {
6192 question = questions[pickQuestion]; //fix impossible answers
6193 //sendChat("What is " + question + "? (to answer type !math <answer>). Difficulty - " + mathDiffTxt);
6194 sendChat("What\u034f i\u034fs " + question + "\u034f? (to answer type "+cmdChar+"math <answer>). Difficulty - " + mathDiffTxt);
6195 asked = true;
6196
6197 // cheater >:3
6198 if (mathCheat) setTimeout( function() { MPP.chat.send(""+cmdChar+"math " + eval(question)) }, randNum(1000, 2500));
6199 }
6200
6201 } else {
6202 if (message.substring(5).trim() == eval(question)) {
6203 sendChat(name + " answered correctly with " + message.substring(5).trim() + " on " + mathDiffTxt + " difficulty (questions answered " + ++mathAnswered +")");
6204 asked = false;
6205 } else {
6206 sendChat("Try again, " + name + ". The question was " + question + ". Too hard? Type "+cmdChar+"mathhelp");
6207 // cheater >:3
6208 if (mathCheat) setTimeout( function() { MPP.chat.send(cmdChar+"math " + eval(question)) }, randNum(1000, 2500));
6209 }
6210 }
6211
6212 } else if (cmd == cmdChar+"mathskip") {
6213 asked = false;
6214 sendChat("Skipping question. (questions skipped " + ++mathSkipped + ")");
6215
6216 } else if (cmd == cmdChar+"meth") {
6217 sendChat('Did you mean '+cmdChar+'"math"?');
6218
6219 // unit conversions start
6220
6221 } else if (cmd == cmdChar+"unitc") {
6222 sendChat("Unit Conversions: "+cmdChar+"ctof (celsius to fahrenheit), "+cmdChar+"ftoc (fahrenheit to celsius), "+cmdChar+"cmtoinch (centimetres to inches), "+cmdChar+"inchtocm (inches to centimetres), "+cmdChar+"cmtofeet (centimetres to feet), "+cmdChar+"feettocm (feet to centimetre), "+cmdChar+"kmtomile (kilometres to miles), "+cmdChar+"miletokm (miles to kilometres)");
6223
6224 // Celsius to Fahrenheit
6225 } else if (cmd == cmdChar+"ctof") {
6226 var fTemp = message.substring(6).trim() * (9 / 5) + 32;
6227 var outcome = fTemp.toString();
6228 if (message.substring(6).trim() == "" || isNaN(fTemp)) {
6229 sendChat("Usage: "+cmdChar+"ctof <unit> eg: 32.");
6230 } else {
6231 sendChat(message.substring(6).trim() + " Celsius equals: " + outcome.substring(0, 6) + " in Fahrenheit.");
6232 }
6233
6234 // Fahrenheit to Celsius
6235 } else if (cmd == cmdChar+"ftoc") {
6236 var cTemp = (message.substring(6).trim() - 32) * (5 / 9);
6237 var outcome = cTemp.toString();
6238 if (message.substring(6).trim() == "" || isNaN(cTemp)) {
6239 sendChat("Usage: "+cmdChar+"ftoc <unit> eg: 74.");
6240 } else {
6241 sendChat(message.substring(6).trim() + " Fahrenheit equals: " + outcome.substring(0, 6) + " in Celsius.");
6242 }
6243
6244 // Centimetres to Inches
6245 } else if (cmd == cmdChar+"cmtoinch") {
6246 var cmTemp = message.substring(10).trim() * 0.39370;
6247 var outcome = cmTemp.toString();
6248 if (message.substring(10).trim() == "" || isNaN(cmTemp)) {
6249 sendChat("Usage: "+cmdChar+"cmtoinch <unit> eg: 30.");
6250 } else {
6251 sendChat(message.substring(10).trim() + " Centimetres equals: " + outcome.substring(0, 6) + " inches.");
6252 }
6253
6254 // Inches to Centimetres
6255 } else if (cmd == cmdChar+"inchtocm") {
6256 var cmTemp = message.substring(10).trim() / 0.39370;
6257 var outcome = cmTemp.toString();
6258 if (message.substring(10).trim() == "" || isNaN(cmTemp)) {
6259 sendChat("Usage: "+cmdChar+"inches <unit> eg: 6.");
6260 } else {
6261 sendChat(message.substring(10).trim() + " Inches equals: " + outcome.substring(0, 6) + " Centimetres.");
6262 }
6263
6264 // Centimetres to Feet
6265 } else if (cmd == cmdChar+"cmtofeet") {
6266 var cmTemp = message.substring(10).trim() * 0.032808;
6267 var outcome = cmTemp.toString();
6268 if (message.substring(10).trim() == "" || isNaN(cmTemp)) {
6269 sendChat("Usage: "+cmdChar+"cmtofeet <unit> eg: 5.");
6270 } else {
6271 sendChat(message.substring(10).trim() + " Centimetres equals: " + outcome.substring(0, 6) + " feet.");
6272 }
6273
6274 // Feet to Centimetres
6275 } else if (cmd == cmdChar+"feettocm") {
6276 var cmTemp = message.substring(10).trim() / 0.032808;
6277 var outcome = cmTemp.toString();
6278 if (message.substring(10).trim() == "" || isNaN(cmTemp)) {
6279 sendChat("Usage: "+cmdChar+"feettocm <unit> eg: 5.");
6280 } else {
6281 sendChat(message.substring(10).trim() + " Feet equals: " + outcome.substring(0, 6) + " Centimetres.");
6282 }
6283
6284 // Kilometres to Miles
6285 } else if (cmd == cmdChar+"kmtomile") {
6286 var cmTemp = message.substring(10).trim() / 0.62137;
6287 var outcome = cmTemp.toString();
6288 if (message.substring(10).trim() == "" || isNaN(cmTemp)) {
6289 sendChat("Usage: "+cmdChar+"kmtomile <unit> eg: 50.");
6290 } else {
6291 sendChat(message.substring(10).trim() + " Kilometres equals: " + outcome.substring(0, 5) + " Miles.");
6292 }
6293
6294 // Miles to Kilometres
6295 } else if (cmd == cmdChar+"miletokm") {
6296 var cmTemp = message.substring(10).trim() * 0.62137;
6297 var outcome = cmTemp.toString();
6298 if (message.substring(10).trim() == "" || isNaN(cmTemp)) {
6299 sendChat("Usage: "+cmdChar+"miletokm <unit> eg: 80");
6300 } else {
6301 sendChat(message.substring(10).trim() + " Miles equals: " + outcome.substring(0, 5) + " Kilometres.");
6302 }
6303 // unit conversions end
6304
6305 // stab command
6306 } else if (cmd == cmdChar+"stab") {
6307 var target = msg.a.substring(cmd.length).trim();
6308 var part = getUser(target.toLowerCase());
6309 if (target == "") {
6310 sendChat("Usage "+cmdChar+"stab name_here.");
6311 return;
6312 }
6313 if (part) {
6314 if (part.name == name) {
6315 sendChat("\"Ouch!\" says " + part.name);
6316 return;
6317 }
6318 sendChat(name + " stabbed " + part.name +".");
6319 } else {
6320 sendChat(userNotFound);
6321 }
6322
6323 } else if (cmd == cmdChar+"highfive") { //highfive command
6324 var target = msg.a.substring(cmd.length).trim();
6325 var part = getUser(target.toLowerCase());
6326 if (target == "") {
6327 sendChat("Usage "+cmdChar+"highfive name_here.");
6328 return;
6329 }
6330 if (part) {
6331 if (part.name == name) {
6332 sendChat(part.name + " claps in the corner.. by themself.");
6333 return;
6334 }
6335 sendChat(name + " highfived " + part.name + ".");
6336 } else {
6337 sendChat(userNotFound);
6338 }
6339
6340 } else if (cmd == cmdChar+"kiss") { //kiss command
6341 var target = msg.a.substring(cmd.length).trim();
6342 var part = getUser(target.toLowerCase());
6343 if (target == "") {
6344 sendChat("Usage "+cmdChar+"kiss name_here.");
6345 return;
6346 }
6347
6348 if (usersDead.indexOf(ids) !== -1) {
6349 sendChat("Is too weak to kiss anyone... maybe a kiss would wake them up?");
6350 return;
6351 }
6352
6353 if (part) {
6354 if (part.name == name) {
6355 sendChat(name + " scrunches up their face, sucking their bottom lip inside their mouth.");
6356 return;
6357 }
6358
6359 if (usersDead.indexOf(part._id) !== -1) {
6360 sendChat(name + '\'s kiss brought ' + part.name + ' back to life.');
6361 usersDead.splice(usersDead.indexOf(ids), 1);
6362
6363 } else {
6364 var kissArray = ['bottom', 'top'];
6365 var lip = Math.floor(Math.random() * kissArray.length);
6366 var kissTypeArray = ['passionately', 'softly', 'shyly', 'nervously', 'cutely', 'holds and'];
6367 var kissType = Math.floor(Math.random() * kissTypeArray.length);
6368 sendChat(name + " " + kissTypeArray[kissType] + " kisses " + part.name + "'s " + kissArray[lip] + " lip. " + part.name + " blushes shyly.");
6369 }
6370 } else {
6371 sendChat(userNotFound);
6372 }
6373
6374 } else if (cmd == cmdChar+"slap") { //slap command
6375 var target = msg.a.substring(cmd.length).trim();
6376 var part = getUser(target.toLowerCase());
6377 if (target == "") {
6378 sendChat("Usage "+cmdChar+"slap name_here.");
6379 return;
6380 }
6381 if (part) {
6382 if (part.name == name) {
6383 sendChat("You cannot slap yourself, that would be awkward.");
6384 return;
6385 }
6386 sendChat(name + " slapped " + part.name);
6387 } else {
6388 sendChat(userNotFound);
6389 }
6390
6391 } else if (cmd == cmdChar+"cuddle") { //cuddle command
6392 var target = msg.a.substring(cmd.length).trim();
6393 var part = getUser(target.toLowerCase());
6394 if (target == "") {
6395 sendChat("Usage "+cmdChar+"cuddle name_here.");
6396 return;
6397 }
6398 if (part) {
6399 if (part.name == name) {
6400 sendChat("You cannot cuddle yourself, you lonely fuck!");
6401 return;
6402 }
6403 var cuddleArray = ['tightly cuddles', 'softly cuddles', 'shyly cuddles', 'tenderly cuddles', 'cuddles'];
6404 var cuddle = Math.floor(Math.random() * cuddleArray.length);
6405 sendChat(name + " " + cuddleArray[cuddle] + " " + part.name + ".");
6406 } else {
6407 sendChat(userNotFound);
6408 }
6409
6410 } else if (cmd == cmdChar+"hug") { //hug command
6411 var target = msg.a.substring(cmd.length).trim();
6412 var part = getUser(target.toLowerCase());
6413 if (target == "") {
6414 sendChat("Usage "+cmdChar+"hug name_here.");
6415 return;
6416 }
6417 if (part) {
6418 if (part.name == name) {
6419 sendChat("You cannot hug yourself, hug a cuddly anon.");
6420 return;
6421 }
6422 var hugArray = [' tightly squeezes ', ' sprints up and hugs ', ' shyly hugs ', ' gently caresses ', ' tounge hugs '];
6423 var hug = Math.floor(Math.random() * hugArray.length);
6424 sendChat(name + hugArray[hug] + part.name + ".");
6425 } else {
6426 sendChat(userNotFound);
6427 }
6428
6429 } else if (cmd == cmdChar+"rape") { //rape command
6430 var target = msg.a.substring(cmd.length).trim();
6431 var part = getUser(target.toLowerCase());
6432 if (target == "") {
6433 sendChat("Usage "+cmdChar+"rape name_here.");
6434 return;
6435 }
6436 if (part) {
6437 if (part.name == name) {
6438 sendChat("You cannot rape yourself, rape the Anonymous people.");
6439 return;
6440 }
6441 sendChat(name + " raped " + part.name + " ᶘᵒᴥᵒᶅ");
6442 } else {
6443 sendChat(userNotFound);
6444 }
6445
6446 } else if (cmd == cmdChar+"gift") { //gift command
6447 var giftArray = ['a cute kitten!', 'a cute puppy!', 'a potato!', 'a pikachu!', 'a brand new Xbox One!', 'a brand new PS4!', '1 million cows!', 'a slice of bacon!', 'a boating license!', 'a bunch of money!', 'some cake!', 'a box inside of a... BOX!', 'a new phone!', 'a new piano!', 'some chicken nuggets!', 'a brand new Wii U!', 'an evil gerbil!', 'a captains ship!', 'some sfoof! (Semolina Turmeric Cake)', 'some pizza!', 'a new laptop!', 'a piece of cotton', 'a spoon', 'a dribbling cat']; //add more... like 100 :D
6448 var randomNumber = Math.floor(Math.random() * giftArray.length);
6449 var target = msg.a.substring(cmd.length).trim();
6450 var part = getUser(target.toLowerCase());
6451 if (target == "") {
6452 sendChat("Usage "+cmdChar+"gift name_here.");
6453 return;
6454 }
6455 if (part) {
6456 if (part.name == name) {
6457 sendChat("You cannot gift yourself, that would be greedy.");
6458 return;
6459 }
6460 sendChat(name + " gave " + part.name + " " + giftArray[randomNumber]);
6461 } else {
6462 sendChat(userNotFound);
6463 }
6464
6465 } else if (cmd == cmdChar+"attack") { //attack command
6466 var attackArray = ['fondue stick', 'piece of bread', 'rubber chicken', 'piano', 'turtle shell', 'lamp', 'Kkitting needle', 'brake cable', 'totally non-harmful piece of string', 'rake', 'shovel', 'birds nest', 'bit of help from gravity', 'sharp stick', 'stick covered in poop', 'can of softdrink (isn’t too soft)', 'disembodied arm', 'candle stick', 'wet iguana', 'duck', 'spoon', 'boat oar', 'large rock', 'sharp triangle', 'trumpet', 'toy car', 'buzz-saw', 'computer keyboard', 'piece of Ed and Megan’s love', 'scratched CD', 'shoe lace', 'assault rifle', 'Mini-Uzi', 'piece of paper', 'very angry wet cat', 'slug', 'cylinder of Pringles', 'hairbrush'];
6467 var randomNumber = Math.floor(Math.random() * attackArray.length);
6468 var target = msg.a.substring(cmd.length).trim();
6469 var part = getUser(target.toLowerCase());
6470 if (target == "") {
6471 sendChat("Usage "+cmdChar+"attack name_here.");
6472 return;
6473 }
6474 if (part) {
6475 if (part.name == name) {
6476 sendChat("You cannot attack yourself, attack the Anonymous people.");
6477 return;
6478 }
6479 sendChat(name + " attacked " + part.name + " with a " + attackArray[randomNumber] + ".");
6480 } else {
6481 sendChat(userNotFound);
6482 }
6483
6484 } else if (cmd == cmdChar+"colour" || cmd == cmdChar+"color") { //colour command
6485 //thanks electrashave!
6486 if (msg.a.substring(cmd.length).trim() == '') {
6487 sendChat("Your colour is " + new Color(msg.p.color).getName() + " (" + msg.p.color + ") (You can also type "+cmdChar+"colour name_here)");
6488 return;
6489 }
6490
6491 var target = msg.a.substring(cmd.length).trim();
6492 var part = getUser(target.toLowerCase());
6493
6494 if (part) {
6495 sendChat(part.name + "'s colour is " + new Color(part.color).getName() + " (" + part.color + ")");
6496 } else {
6497 sendChat(userNotFound);
6498 }
6499
6500 } else if (cmd == cmdChar+"unicode") { //unicode command
6501 sendChat("Put some of these in your name: ᴥ◕☀☁☂☃☄★☆☇☈☉☊☋☌☍ツ¢¢☍☎☏☐☑☒☓☔☕☖☗☘☙☚☛☜☝☞☟☠␀☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯─━│┃┎┒┝┫┳┻╋╭╮╯╰╱╲╳╴╵╶╷╸╹╺╻╼╽╾╿☰☱☲☳☴☵☶☷░▒▓▔▁▂▃▄▅▆▇█▉▊▋▌▐ ▍▎▏◘☸☹☺☻☼☽☾☿ ♀♁♂♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♠♢♣♤♥♡♦♧♨♩♪♫♬♭♮♯ ๖ۣۜ ∥~∼˜≀π∏ℍℂℕℙℚℝℤℬℰℱℋℐℒℳ℘ℛℓℴℯɨℊℎ√∑∮‖⌊⌉⋕⊤✀✁✂✃✄✆✇✈✉✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣✤✥✦✧✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❍❏❐❑❒❖❡❤❥❦❧❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨➩➪➫➬➭➮➯➰➱➲➳➴➵➶➷➸➹➺➻➼➽➾∧⋉⋊⋈ℵ");
6502
6503 } else if (cmd == cmdChar+"clap" || cmd == cmdChar+"applaud") { //clap command
6504 sendChat(name + " applauds.");
6505
6506 } else if (cmd == cmdChar+"slowclap") { //slow clap command
6507 sendChat(name + " claps slowly in approval");
6508
6509 } else if (cmd == cmdChar+"list") { //list command
6510 var list = "Connected users: ";
6511 for (var id in gClient.ppl) {
6512 list += gClient.ppl[id].name + ", ";
6513 }
6514 sendChat(list);
6515 return;
6516
6517 } else if (cmd == cmdChar+"facepalm") { //facepalm command
6518 sendChat(name + " facepalmed.");
6519
6520 } else if (cmd == cmdChar+"musicsheets" || cmd == cmdChar+"ms") { //musicsheets command
6521 var songArray = ['Logan’s small march: xbm. cbm/ xvj. gj. gj, xbm xbm. cb,/ n,ry k.r wtbk etb,',
6522 'Dramatic song: C E 5 E Y E Y U | S E 5 E 8 U Y U | A E 5 E Y E Y U | (Ctrl M) E 5 E 8 U Y 5',
6523 'Part of Turkich March - [ - o i o i 8 7 i 8 7 y 7 8 y 4 5 t 4 7 y 7 8 i 8 i o - p - [ -',
6524 'C. P. E. Bach Solfeggietto: g c m e 5 r e w m w r u y 5 r 5 e 5 u p = [ p [ p o i u y 5 r',
6525 'Gravity Falls: N V Z V N V Z V N C Z C N C Z C B F Z F B F Z F B F Z F B F Z ',
6526 'My Immortal: z4 tb qi t - t i t f4 tk 48 t - z4 tb qi t o t i t f4 tk 48 t',
6527 'Song of Stroms: v r yi yi b t uo n y ip ip b t uo',
6528 'C minor: c v g n m k l /',
6529 'Skrillex - Scary Monsters: m u y u g9 u [ p 9 y 2 q y 5 nr e 2 m 2 m 2 r u r 2 m y 2 m n',
6530 'B major: x f g b j k l .',
6531 'Colombia Pictures: 8 p 9 y | 4 y 5 e | k / l n | f n g c | acgk',
6532 'Fandango: ttytyt8o ttytytip ttytyt8o ttytytip',
6533 'Eb fun: f n . | g m l | 4 y o | 5 u 9',
6534 'The Entertainer LH: e tup m u9p yn yip tb tup m yu m yu m etup etup',
6535 'Same Love: (Hold G) L M L GC ~ (Hold A) G C G (Hold G) J-M ~ (Hold G) L M L GC ~ (Hold A) G C G (Let go of A) GS',
6536 'Tetris: T W E R R E Q Q E T R E W W E R T E Q Q R Y I U Y T E T R E W W E R T E Q Q',
6537 'Mad World: N8 P 1EU 8 NY U 1E5 R 2 RY 2 RY 8 N P 1EU 8 NY U 1E8 9 2 RY 2 RY',
6538 'E minor: b j m , . / r t',
6539 'Happy Birthday: E E NQR E Y CLT E E CLR E U NQY E E NQP I Y NLT R 9 9 NQI Y CLU NQY',
6540 'Darude Sandstorm: r7i tuo tuo tuo tuo up] tuo tuo tuo tuo up] tuo tuo tuo tuo up] up] uo[ uo[ r7i tuo',
6541 'Yoshi\'s Epic Morrowind: E R 5CGM 5 Y UGL U 9 YSVN 5 R EACG E R 5CGM 5 Y UGL U 9 PGKE 9URM 8YP'];
6542 var randomSong = Math.floor(Math.random() * songArray.length);
6543 sendChat("Songs for PC players: " + sheetURL + " here's a random sample - " + songArray[randomSong] + " (Notes updated 6th June 2015)"); //update when you update link, Logan
6544
6545 } else if (cmd == cmdChar+"suicide") { //suicide command
6546 if (usersDead.indexOf(ids) == -1) {
6547 sendChat(name + " kissed Logan and died x3");
6548 usersDead.push(ids);
6549
6550 } else {
6551 sendChat(name + " is too weak to kiss Logan... Maybe a kiss would wake them up?");
6552 }
6553
6554 } else if (cmd == cmdChar+"kill") { //kill command
6555 var target = msg.a.substring(cmd.length).trim();
6556 var part = getUser(target.toLowerCase());
6557 if (target == "") {
6558 sendChat("Usage "+cmdChar+"kill name_here.");
6559 return;
6560 }
6561 if (part) {
6562 if (part.name == name) {
6563 if (usersDead.indexOf(part._id) == -1) {
6564 sendChat(name + " commitsed suicide!");
6565 usersDead.push(part._id);
6566 } else {
6567 sendChat(name + "'s body twitches... Maybe a kiss would wake them up?");
6568 }
6569 return;
6570 }
6571 if (usersDead.indexOf(part._id) == -1) {
6572 sendChat(name + " killed " + part.name + "!");
6573 usersDead.push(part._id)
6574 } else {
6575 sendChat(part.name + " body twitches... Maybe a kiss would wake them up?");
6576 }
6577 } else {
6578 sendChat(userNotFound);
6579 }
6580
6581 //text art
6582 } else if (cmd == cmdChar+"art") { //art command
6583 sendChat("Small text art (crown not needed): "+cmdChar+"bunny (3 lines), "+cmdChar+"bunny2 (3 lines), "+cmdChar+"bunny3 (3 lines), "+cmdChar+"bunny4 (3 lines), "+cmdChar+"hamster (3 lines), "+cmdChar+"hamster2 (3 lines), "+cmdChar+"table (3 lines). Large text art (crown needed) "+cmdChar+"fishies (9 lines).");
6584
6585 } else if (cmd == cmdChar+"hamster2") { //hamster 2 art command
6586 setTimeout(function() { sendChat("( ) ( )" ); }, 0);
6587 setTimeout(function() { sendChat("(>•.•<)" ); }, 0);
6588 setTimeout(function() { sendChat('(") (")' ); }, 0);
6589
6590 } else if (cmd == cmdChar+"hamster") { //hamster art command
6591 setTimeout(function() { sendChat("( )_( )" ); }, 0);
6592 setTimeout(function() { sendChat("(='.'=)" ); }, 0);
6593 setTimeout(function() { sendChat('(")_(")' ); }, 0);
6594
6595 } else if (cmd == cmdChar+"bunny4") { //bunny 4 art command
6596 setTimeout(function() { sendChat("(\\(\\" ); }, 0);
6597 setTimeout(function() { sendChat("(=\".\")" ); }, 0);
6598 setTimeout(function() { sendChat('("")("")' ); }, 0);
6599
6600 } else if (cmd == cmdChar+"bunny3") { //bunny 3 art command
6601 setTimeout(function() { sendChat("(\\_(\\" ); }, 0);
6602 setTimeout(function() { sendChat("(˚_˚)" ); }, 0);
6603 setTimeout(function() { sendChat("('')('')" ); }, 0);
6604
6605 } else if (cmd == cmdChar+"bunny2") { //bunny 2 art command
6606 setTimeout(function() { sendChat("/)_/)" ); }, 0);
6607 setTimeout(function() { sendChat("(0.0)" ); }, 0);
6608 setTimeout(function() { sendChat("('')('')" ); }, 0);
6609
6610 } else if (cmd == cmdChar+"bunny") { //bunny art command
6611 setTimeout(function() { sendChat("(\\_/)" ); }, 0);
6612 setTimeout(function() { sendChat("(o.o)" ); }, 0);
6613 setTimeout(function() { sendChat("('')('')" ); }, 0);
6614
6615 } else if (cmd == cmdChar+"table") { //table art command
6616 setTimeout(function() { sendChat("(╮°-°)╮┳━━┳" ); }, 0);
6617 setTimeout(function() { sendChat("( ╯°□°)╯ ┻━━┻" ); }, 0);
6618 setTimeout(function() { sendChat("┬──┬ ノ( ゜-゜ノ)" ); }, 0);
6619 //text art
6620
6621 } else if (cmd == cmdChar+"fishies") { //fishies command
6622 if (gClient.isOwner()) {
6623 sendChat("╭━━╮╭━━━┳╮╭╮╭╮╭━━━┳━━━┳╮╭╮╭┳━╮╱╭╮╭━━━┳━━┳━━━┳╮╱╭┳━━┳━━━┳━━━╮ ╭╮" );
6624 sendChat("┃╭╮┃┃╭━╮┃┃┃┃┃┃╰╮╭╮┃╭━╮┃┃┃┃┃┃┃╰╮┃┃┃╭━━┻┫┣┫╭━╮┃┃╱┃┣┫┣┫╭━━┫╭━╮┃ ┃┃" );
6625 sendChat("┃╰╯╰┫┃╱┃┃┃┃┃┃┃╱┃┃┃┃┃╱┃┃┃┃┃┃┃╭╮╰╯┃┃╰━━╮┃┃┃╰━━┫╰━╯┃┃┃┃╰━━┫╰━━╮ ┃┃" );
6626 sendChat("┃╭━╮┃┃╱┃┃╰╯╰╯┃╱┃┃┃┃┃╱┃┃╰╯╰╯┃┃╰╮┃┃┃╭━━╯┃┃╰━━╮┃╭━╮┃┃┃┃╭━━┻━━╮┃ ╰╯" );
6627 sendChat("┃╰━╯┃╰━╯┣╮╭╮╭╯╭╯╰╯┃╰━╯┣╮╭╮╭┫┃╱┃┃┃┃┃╱╱╭┫┣┫╰━╯┃┃╱┃┣┫┣┫╰━━┫╰━╯┃ ╭╮" );
6628 sendChat("╰━━━┻━━━╯╰╯╰╯╱╰━━━┻━━━╯╰╯╰╯╰╯╱╰━╯╰╯╱╱╰━━┻━━━┻╯╱╰┻━━┻━━━┻━━━╯ ╰╯" );
6629 sendChat("╭━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━╮" );
6630 sendChat("╰━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━╯" );
6631 sendChat("><> \\o/" );
6632 } else {
6633 sendChat("I need the crown to show fishies in its entirety!");
6634 }
6635
6636 } else if (cmd == cmdChar+"face") { //face command
6637 var textArray = ['╥﹏╥', '(◕ᴥ◕し)', 'ʕ•ᴥ•ʔ', '(◡‿◡✿)', 'ヽ༼ ಠ益ಠ ༽ノ', '^‿^', 'ᶘ ᵒᴥᵒᶅ', '๏̯͡๏', '^ㅂ^', ' ಠ_ರೃ', '(ノ◕ヮ◕)ノ*:・゚✧', '◕◡◕', 'ಠ▃ಠ', 'ಠ╭╮ಠ', 'ಠ⌣ಠ', 'ಠ◡ಠ', 'ლ(ಠ益ಠლ)', 'ლ(◉◞౪◟◉‵ლ)', '⊙ω⊙', '⊙▂⊙', '╯‵Д′)╯彡┻━┻', '◕ω◕', '⌒▽⌒', '♥◡♥', '。◕‿‿◕。', '。◕ ‿ ◕。', '(´◉◞౪◟◉)', 'Ծ‸ Ծ', '(ᵔᴥᵔ)', '• ε •', '(⌐■_■)', '(┛◉Д◉)┛┻━┻', '(╯°□°)╯︵ ┻━┻ ', '◕ ^ ◕', '(☞゚ ∀゚ )☞', '(づ。◕‿‿◕。)づ', '(ノಠ益ಠ)ノ彡┻━┻', ';一_一', '\(◕ ◡ ◕\)', '°-°', '¶_¶', '( ͡° ͜ʖ ͡°)', '|)^_^(|'];
6638 var randomNumber = Math.floor(Math.random() * textArray.length);
6639 sendChat(textArray[randomNumber]);
6640
6641 } else if (cmd == cmdChar+"say") { //say command
6642 if (message.substring(4).trim() == "") {
6643 sendChat("Usage: "+cmdChar+"say text to say.");
6644 return;
6645 }
6646 sendChat(message.substring(5).trim());
6647
6648 } else if (cmd == cmdChar+"rename") { //rename command
6649 if (message.substring(cmd.length).trim() == 0) {
6650 sendChat('Usage: '+cmdChar+'rename new_name');
6651 return;
6652 }
6653 if (message.substring(7).trim() == 420) {
6654 sendChat('Too high!');
6655 return;
6656 }
6657 if (opped) {
6658 updateName(message.substring(7).trim());
6659 selfName = message.substring(7).trim();
6660
6661 } else {
6662 sendChat(noAccess);
6663 }
6664
6665 } else if (cmd == cmdChar+"welcome") { //welcome command
6666 if (opped) {
6667 if (welcTemp) {
6668 welcTemp = false;
6669 sendChat("Room welcoming disabled.");
6670 } else {
6671 welcTemp = true;
6672 sendChat("Room welcoming enabled.");
6673 }
6674 } else {
6675 sendChat(noAccess);
6676 }
6677 } else if (cmd == cmdChar+"tune") { //tune command
6678 if (opped) {
6679 if (tuneTemp) {
6680 tuneTemp = false;
6681 sendChat("Welcome tune disabled.");
6682 } else {
6683 tuneTemp = true;
6684 sendChat("Welcome tune enabled.");
6685 }
6686 } else {
6687 sendChat(noAccess);
6688 }
6689
6690 } else if (cmd == cmdChar+"ban") { //ban command
6691 var target = msg.a.substring(cmd.length).trim();
6692 var part = getUser(target.toLowerCase());
6693
6694 if (opped) {
6695 if (target == "") {
6696 sendChat("Usage "+cmdChar+"ban name_here.");
6697 return;
6698 }
6699 if (part) {
6700 if (banned.indexOf(part._id) !== -1) {
6701 sendChat(part.name + " is already banned!");
6702 return;
6703 }
6704
6705 if (part._id == selfId) { //Logan
6706 sendChat("Banning " + part.name.substring(0, 4).trim() + "... wait.");
6707 } else if (part._id == "4e28d8736f8a464ada652896") { //Yoshify.
6708 sendChat("You cannot ban " + selfName + "'s friend " + part.name + ".");
6709 } else if (part._id == "d9e6170fd899f2a94adea761") { //StarsPiano
6710 sendChat("You cannot ban " + selfName + "'s friend " + part.name + ".");
6711 } else {
6712 banned.push(part._id);
6713 sendChat(name + " banned " + part.name + ".");
6714 }
6715 } else {
6716 sendChat(userNotFound);
6717 }
6718 } else {
6719 sendChat(noAccess);
6720 }
6721
6722 } else if (cmd == cmdChar+"unban") { //unban command
6723 var target = msg.a.substring(cmd.length).trim();
6724 var part = getUser(target.toLowerCase());
6725
6726 if (opped) {
6727 if (target == "") {
6728 sendChat("Usage "+cmdChar+"unban name_here.");
6729 return;
6730 }
6731 if (part) {
6732 if (banned.indexOf(part._id) == -1) {
6733 sendChat(part.name + " isn't banned!");
6734 return;
6735 }
6736
6737 while (banned.indexOf(part._id) !== -1) {
6738 banned.splice(banned.indexOf(part._id), 1);
6739 sendChat(name + " unbanned " + part.name + ".");
6740 }
6741 while (banned.indexOf(part._id) !== -1) {
6742 delete banned[banned.indexOf(part._id)];
6743 }
6744 } else {
6745 sendChat(userNotFound);
6746 }
6747 } else {
6748 sendChat(noAccess);
6749 }
6750
6751 } else if (cmd == cmdChar+"pardon") { //pardon command
6752 if (mastered || opped) {
6753 banned = [];
6754 sendChat(name + " pardoned everyone from being banned.");
6755 } else {
6756 sendChat(noAccess);
6757 }
6758
6759 } else if (cmd == cmdChar+"op") { //op command
6760 var target = msg.a.substring(cmd.length).trim();
6761 var part = getUser(target.toLowerCase());
6762
6763 if (opped) {
6764 if (target == "") {
6765 sendChat("Usage "+cmdChar+"op name_here.");
6766 return;
6767 }
6768 if (part) {
6769 if (ops.indexOf(part._id) !== -1) {
6770 sendChat(part.name + " is already opped!");
6771 return;
6772 }
6773
6774 sendChat("Opped " + part.name + ".");
6775 ops.push(part._id);
6776
6777 } else {
6778 sendChat(userNotFound);
6779 }
6780 } else {
6781 sendChat(noAccess);
6782 }
6783
6784 } else if (cmd == cmdChar+"deop") { //deop command
6785 var target = msg.a.substring(cmd.length).trim();
6786 var part = getUser(target.toLowerCase());
6787
6788 if (opped) {
6789 if (target == "") {
6790 sendChat("Usage "+cmdChar+"deop name_here.");
6791 return;
6792 }
6793 if (part) {
6794 if (ops.indexOf(part._id) == -1) {
6795 sendChat(part.name + " isn't opped!");
6796 return;
6797 }
6798
6799 if (part._id == selfId) { //Logan
6800 sendChat("You cannot deop " + part.name + ".");
6801 } else if (part._id == "4e28d8736f8a464ada652896") { //Yoshify.
6802 sendChat("You cannot deop " + selfName + "'s friend " + part.name + ".");
6803 } else if (part._id == "d9e6170fd899f2a94adea761") { //StarsPiano
6804 sendChat("You cannot deop " + selfName + "'s friend " + part.name + ".");
6805 } else {
6806 while (ops.indexOf(part._id) !== -1) {
6807 ops.splice(banned.indexOf(part._id), 1); //is this meant to say banned?
6808 }
6809 while (ops.indexOf(part._id) !== -1) {
6810 delete ops[ops.indexOf(part._id)];
6811 }
6812 sendChat("Deopped " + part.name + ".");
6813 }
6814 } else {
6815 sendChat(userNotFound);
6816 }
6817 } else {
6818 sendChat(noAccess);
6819 }
6820 } else if (message.substring(0, 1) == cmdChar) { //alternative error messages
6821 if (message.substring(2).trim() == "") {
6822
6823 } else {
6824 //sendChat("Invalid command. Type !help for a list of commands you have access to."); //shhhhh
6825 }
6826 }
6827 }
6828 botLoaded = true;
6829 });
6830
6831 var Color = function () {
6832 var r, g, b;
6833 if (arguments.length === 1) {
6834 var hexa = arguments[0].toLowerCase();
6835 if (hexa.match(/^#[0-9a-f]{6}$/i)) {
6836 hexa = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(hexa);
6837 if (hexa && hexa.length === 4) {
6838 r = parseInt(hexa[1], 16);
6839 g = parseInt(hexa[2], 16);
6840 b = parseInt(hexa[3], 16);
6841 }
6842 }
6843 } else if (arguments.length === 3) {
6844 r = arguments[0];
6845 g = arguments[1];
6846 b = arguments[2];
6847 }
6848 this.r = ~~r || 0;
6849 this.g = ~~g || 0;
6850 this.b = ~~b || 0;
6851 };
6852
6853 Color.prototype.distance = function (color) {
6854 var d = 0;
6855 d += Math.pow(this.r - color.r, 2);
6856 d += Math.pow(this.g - color.g, 2);
6857 d += Math.pow(this.b - color.b, 2);
6858 return Math.abs(Math.sqrt(d));
6859 };
6860
6861 Color.prototype.toHexa = function () {
6862 var r = this.r.toString(16),
6863 g = this.g.toString(16),
6864 b = this.b.toString(16);
6865 if (r.length == 1) r = "0" + r;
6866 if (g.length == 1) g = "0" + g;
6867 if (b.length == 1) b = "0" + b;
6868 return "#" + r + g + b;
6869 };
6870
6871 Color.prototype.getName = function () {
6872 var hexa = this.toHexa();
6873 var low = 256;
6874 var name;
6875 for (var n in Color.map) {
6876 if (!Color.map.hasOwnProperty(n)) continue;
6877 var color = Color.map[n];
6878 if (color.r === this.r && color.g === this.g && color.b === this.b) {
6879 return n;
6880 }
6881 var dist = this.distance(color);
6882 if (dist < low) {
6883 low = dist;
6884 name = n;
6885 }
6886 }
6887 if (!name) name = this.toHexa();
6888 else name = "a shade of " + name;
6889 return name;
6890 };
6891
6892 Color.map = {};
6893
6894 Color.a = function (hexa, name) {
6895 Color.map[name] = new Color(hexa);
6896 };
6897
6898 Color.a("#7CB9E8", "Aero");
6899 Color.a("#C9FFE5", "Aero blue");
6900 Color.a("#B284BE", "African purple");
6901 Color.a("#5D8AA8", "Air Force blue (RAF)");
6902 Color.a("#00308F", "Air Force blue (USAF)");
6903 Color.a("#72A0C1", "Air superiority blue");
6904 Color.a("#AF002A", "Alabama Crimson");
6905 Color.a("#F0F8FF", "Alice blue");
6906 Color.a("#E32636", "Alizarin crimson");
6907 Color.a("#C46210", "Alloy orange");
6908 Color.a("#EFDECD", "Almond");
6909 Color.a("#E52B50", "Amaranth");
6910 Color.a("#F19CBB", "Amaranth pink");
6911 Color.a("#AB274F", "Dark amaranth");
6912 Color.a("#3B7A57", "Amazon");
6913 Color.a("#FF7E00", "Amber");
6914 Color.a("#FF033E", "American rose");
6915 Color.a("#9966CC", "Amethyst");
6916 Color.a("#A4C639", "Android green");
6917 Color.a("#F2F3F4", "Anti-flash white");
6918 Color.a("#CD9575", "Antique brass");
6919 Color.a("#665D1E", "Antique bronze");
6920 Color.a("#915C83", "Antique fuchsia");
6921 Color.a("#841B2D", "Antique ruby");
6922 Color.a("#FAEBD7", "Antique white");
6923 Color.a("#8DB600", "Apple green");
6924 Color.a("#FBCEB1", "Apricot");
6925 Color.a("#00FFFF", "Aqua");
6926 Color.a("#7FFFD4", "Aquamarine");
6927 Color.a("#4B5320", "Army green");
6928 Color.a("#3B444B", "Arsenic");
6929 Color.a("#8F9779", "Artichoke");
6930 Color.a("#B2BEB5", "Ash grey");
6931 Color.a("#87A96B", "Asparagus");
6932 Color.a("#FDEE00", "Aureolin");
6933 Color.a("#6E7F80", "AuroMetalSaurus");
6934 Color.a("#568203", "Avocado");
6935 Color.a("#007FFF", "Azure");
6936 Color.a("#F0FFFF", "Azure mist/web");
6937 Color.a("#89CFF0", "Baby blue");
6938 Color.a("#A1CAF1", "Baby blue eyes");
6939 Color.a("#FEFEFA", "Baby powder");
6940 Color.a("#FF91AF", "Baker-Miller pink");
6941 Color.a("#21ABCD", "Ball blue");
6942 Color.a("#FAE7B5", "Banana Mania");
6943 Color.a("#FFE135", "Banana yellow");
6944 Color.a("#E0218A", "Barbie pink");
6945 Color.a("#7C0A02", "Barn red");
6946 Color.a("#848482", "Battleship grey");
6947 Color.a("#98777B", "Bazaar");
6948 Color.a("#9F8170", "Beaver");
6949 Color.a("#F5F5DC", "Beige");
6950 Color.a("#2E5894", "B'dazzled blue");
6951 Color.a("#9C2542", "Big dip o’ruby");
6952 Color.a("#FFE4C4", "Bisque");
6953 Color.a("#3D2B1F", "Bistre");
6954 Color.a("#967117", "Bistre brown");
6955 Color.a("#CAE00D", "Bitter lemon");
6956 Color.a("#648C11", "Bitter lime");
6957 Color.a("#FE6F5E", "Bittersweet");
6958 Color.a("#BF4F51", "Bittersweet shimmer");
6959 Color.a("#000000", "Black with no soul!");
6960 Color.a("#3D0C02", "Black bean");
6961 Color.a("#253529", "Black leather jacket");
6962 Color.a("#3B3C36", "Black olive");
6963 Color.a("#FFEBCD", "Blanched almond");
6964 Color.a("#A57164", "Blast-off bronze");
6965 Color.a("#318CE7", "Bleu de France");
6966 Color.a("#ACE5EE", "Blizzard Blue");
6967 Color.a("#FAF0BE", "Blond");
6968 Color.a("#0000FF", "Blue");
6969 Color.a("#1F75FE", "Blue (Crayola)");
6970 Color.a("#0093AF", "Blue (Munsell)");
6971 Color.a("#0087BD", "Blue (NCS)");
6972 Color.a("#333399", "Blue (pigment)");
6973 Color.a("#0247FE", "Blue (RYB)");
6974 Color.a("#A2A2D0", "Blue Bell");
6975 Color.a("#6699CC", "Blue-gray");
6976 Color.a("#0D98BA", "Blue-green");
6977 Color.a("#126180", "Blue sapphire");
6978 Color.a("#8A2BE2", "Blue-violet");
6979 Color.a("#5072A7", "Blue yonder");
6980 Color.a("#4F86F7", "Blueberry");
6981 Color.a("#1C1CF0", "Bluebonnet");
6982 Color.a("#DE5D83", "Blush");
6983 Color.a("#79443B", "Bole Brown");
6984 Color.a("#0095B6", "Bondi blue");
6985 Color.a("#E3DAC9", "Bone");
6986 Color.a("#CC0000", "Boston University Red");
6987 Color.a("#006A4E", "Bottle green");
6988 Color.a("#873260", "Boysenberry");
6989 Color.a("#0070FF", "Brandeis blue");
6990 Color.a("#B5A642", "Brass");
6991 Color.a("#CB4154", "Brick red");
6992 Color.a("#1DACD6", "Bright cerulean");
6993 Color.a("#66FF00", "Bright green");
6994 Color.a("#BF94E4", "Bright lavender");
6995 Color.a("#D891EF", "Bright lilac");
6996 Color.a("#C32148", "Bright maroon");
6997 Color.a("#1974D2", "Bright navy blue");
6998 Color.a("#FF007F", "Bright pink");
6999 Color.a("#08E8DE", "Bright turquoise");
7000 Color.a("#D19FE8", "Bright ube");
7001 Color.a("#F4BBFF", "Brilliant lavender");
7002 Color.a("#FF55A3", "Brilliant rose");
7003 Color.a("#FB607F", "Brink pink");
7004 Color.a("#004225", "British racing green");
7005 Color.a("#CD7F32", "Bronze");
7006 Color.a("#737000", "Bronze Yellow");
7007 Color.a("#964B00", "Brown");
7008 Color.a("#6B4423", "Brown-nose");
7009 Color.a("#FFC1CC", "Bubble gum");
7010 Color.a("#E7FEFF", "Bubbles");
7011 Color.a("#F0DC82", "Buff");
7012 Color.a("#7BB661", "Bud green");
7013 Color.a("#480607", "Bulgarian rose");
7014 Color.a("#800020", "Burgundy");
7015 Color.a("#DEB887", "Burlywood");
7016 Color.a("#CC5500", "Burnt orange");
7017 Color.a("#8A3324", "Burnt umber");
7018 Color.a("#BD33A4", "Byzantine");
7019 Color.a("#702963", "Byzantium");
7020 Color.a("#536872", "Cadet");
7021 Color.a("#5F9EA0", "Cadet blue");
7022 Color.a("#91A3B0", "Cadet grey");
7023 Color.a("#006B3C", "Cadmium green");
7024 Color.a("#ED872D", "Cadmium orange");
7025 Color.a("#E30022", "Cadmium red");
7026 Color.a("#FFF600", "Cadmium yellow");
7027 Color.a("#A67B5B", "Cafe au lait");
7028 Color.a("#4B3621", "Cafe noir");
7029 Color.a("#1E4D2B", "Cal Poly green");
7030 Color.a("#A3C1AD", "Cambridge Blue");
7031 Color.a("#EFBBCC", "Cameo pink");
7032 Color.a("#78866B", "Camouflage green");
7033 Color.a("#FFEF00", "Canary yellow");
7034 Color.a("#FF0800", "Candy apple red");
7035 Color.a("#E4717A", "Candy pink");
7036 Color.a("#592720", "Caput mortuum");
7037 Color.a("#C41E3A", "Cardinal");
7038 Color.a("#00CC99", "Caribbean green");
7039 Color.a("#960018", "Carmine");
7040 Color.a("#EB4C42", "Carmine pink");
7041 Color.a("#FF0038", "Carmine red");
7042 Color.a("#FFA6C9", "Carnation pink");
7043 Color.a("#99BADD", "Carolina blue");
7044 Color.a("#ED9121", "Carrot orange");
7045 Color.a("#00563F", "Castleton green");
7046 Color.a("#062A78", "Catalina blue");
7047 Color.a("#703642", "Catawba");
7048 Color.a("#C95A49", "Cedar Chest");
7049 Color.a("#92A1CF", "Ceil");
7050 Color.a("#ACE1AF", "Celadon");
7051 Color.a("#007BA7", "Celadon blue");
7052 Color.a("#2F847C", "Celadon green");
7053 Color.a("#4997D0", "Celestial blue");
7054 Color.a("#EC3B83", "Cerise pink");
7055 Color.a("#2A52BE", "Cerulean blue");
7056 Color.a("#6D9BC3", "Cerulean frost");
7057 Color.a("#007AA5", "CG Blue");
7058 Color.a("#E03C31", "CG Red");
7059 Color.a("#A0785A", "Chamoisee");
7060 Color.a("#F7E7CE", "Champagne");
7061 Color.a("#36454F", "Charcoal");
7062 Color.a("#232B2B", "Charleston green");
7063 Color.a("#E68FAC", "Charm pink");
7064 Color.a("#DFFF00", "Chartreuse");
7065 Color.a("#7FFF00", "Chartreuse (web)");
7066 Color.a("#DE3163", "Cherry");
7067 Color.a("#FFB7C5", "Cherry blossom pink");
7068 Color.a("#954535", "Chestnut");
7069 Color.a("#A8516E", "China rose");
7070 Color.a("#AA381E", "Chinese red");
7071 Color.a("#856088", "Chinese violet");
7072 Color.a("#7B3F00", "Chocolate");
7073 Color.a("#FFA700", "Chrome yellow");
7074 Color.a("#98817B", "Cinereous");
7075 Color.a("#E4D00A", "Citrine");
7076 Color.a("#9FA91F", "Citron");
7077 Color.a("#7F1734", "Claret");
7078 Color.a("#FBCCE7", "Classic rose");
7079 Color.a("#0047AB", "Cobalt");
7080 Color.a("#D2691E", "Cocoa brown");
7081 Color.a("#965A3E", "Coconut");
7082 Color.a("#6F4E37", "Coffee Brown");
7083 Color.a("#9BDDFF", "Columbia blue");
7084 Color.a("#002E63", "Cool black");
7085 Color.a("#8C92AC", "Cool grey");
7086 Color.a("#B87333", "Copper");
7087 Color.a("#AD6F69", "Copper penny");
7088 Color.a("#CB6D51", "Copper red");
7089 Color.a("#996666", "Copper rose");
7090 Color.a("#FF3800", "Coquelicot");
7091 Color.a("#FF7F50", "Coral");
7092 Color.a("#F88379", "Coral pink");
7093 Color.a("#FF4040", "Coral red");
7094 Color.a("#893F45", "Cordovan");
7095 Color.a("#FBEC5D", "Corn Yellow");
7096 Color.a("#B31B1B", "Cornell Red");
7097 Color.a("#6495ED", "Cornflower blue");
7098 Color.a("#FFF8DC", "Cornsilk");
7099 Color.a("#FFF8E7", "Cosmic latte");
7100 Color.a("#FFBCD9", "Cotton candy");
7101 Color.a("#FFFDD0", "Cream");
7102 Color.a("#DC143C", "Crimson");
7103 Color.a("#BE0032", "Crimson glory");
7104 Color.a("#00B7EB", "Cyan");
7105 Color.a("#58427C", "Cyber grape");
7106 Color.a("#FFD300", "Cyber yellow");
7107 Color.a("#FFFF31", "Daffodil");
7108 Color.a("#F0E130", "Dandelion");
7109 Color.a("#00008B", "Dark blue");
7110 Color.a("#666699", "Dark blue-gray");
7111 Color.a("#654321", "Dark brown");
7112 Color.a("#5D3954", "Dark byzantium");
7113 Color.a("#A40000", "Dark candy apple red");
7114 Color.a("#08457E", "Dark cerulean");
7115 Color.a("#986960", "Dark chestnut");
7116 Color.a("#CD5B45", "Dark coral");
7117 Color.a("#008B8B", "Dark cyan");
7118 Color.a("#536878", "Dark electric blue");
7119 Color.a("#B8860B", "Dark goldenrod");
7120 Color.a("#A9A9A9", "Dark gray");
7121 Color.a("#013220", "Dark green");
7122 Color.a("#00416A", "Dark imperial blue");
7123 Color.a("#1A2421", "Dark jungle green");
7124 Color.a("#BDB76B", "Dark khaki");
7125 Color.a("#734F96", "Dark lavender");
7126 Color.a("#534B4F", "Dark liver");
7127 Color.a("#543D37", "Dark liver (horses)");
7128 Color.a("#8B008B", "Dark magenta");
7129 Color.a("#003366", "Dark midnight blue");
7130 Color.a("#4A5D23", "Dark moss green");
7131 Color.a("#556B2F", "Dark olive green");
7132 Color.a("#FF8C00", "Dark orange");
7133 Color.a("#9932CC", "Dark orchid");
7134 Color.a("#779ECB", "Dark pastel blue");
7135 Color.a("#03C03C", "Dark pastel green");
7136 Color.a("#966FD6", "Dark pastel purple");
7137 Color.a("#C23B22", "Dark pastel red");
7138 Color.a("#E75480", "Dark pink");
7139 Color.a("#003399", "Dark powder blue");
7140 Color.a("#4F3A3C", "Dark puce");
7141 Color.a("#872657", "Dark raspberry");
7142 Color.a("#8B0000", "Dark red");
7143 Color.a("#E9967A", "Dark salmon");
7144 Color.a("#560319", "Dark Scarlet");
7145 Color.a("#8FBC8F", "Dark sea green");
7146 Color.a("#3C1414", "Dark sienna");
7147 Color.a("#8CBED6", "Dark sky blue");
7148 Color.a("#483D8B", "Dark slate blue");
7149 Color.a("#2F4F4F", "Dark slate gray");
7150 Color.a("#177245", "Dark spring green");
7151 Color.a("#918151", "Dark tan");
7152 Color.a("#FFA812", "Dark tangerine");
7153 Color.a("#CC4E5C", "Dark terra cotta");
7154 Color.a("#00CED1", "Dark turquoise");
7155 Color.a("#D1BEA8", "Dark vanilla");
7156 Color.a("#9400D3", "Dark violet");
7157 Color.a("#9B870C", "Dark yellow");
7158 Color.a("#00703C", "Dartmouth green");
7159 Color.a("#555555", "Davy's grey");
7160 Color.a("#D70A53", "Debian red");
7161 Color.a("#A9203E", "Deep carmine");
7162 Color.a("#EF3038", "Deep carmine pink");
7163 Color.a("#E9692C", "Deep carrot orange");
7164 Color.a("#DA3287", "Deep cerise");
7165 Color.a("#B94E48", "Deep chestnut");
7166 Color.a("#C154C1", "Deep fuchsia");
7167 Color.a("#004B49", "Deep jungle green");
7168 Color.a("#F5C71A", "Deep lemon");
7169 Color.a("#9955BB", "Deep lilac");
7170 Color.a("#CC00CC", "Deep magenta");
7171 Color.a("#D473D4", "Deep mauve");
7172 Color.a("#355E3B", "Deep moss green");
7173 Color.a("#FFCBA4", "Deep peach");
7174 Color.a("#A95C68", "Deep puce");
7175 Color.a("#843F5B", "Deep ruby");
7176 Color.a("#FF9933", "Deep saffron");
7177 Color.a("#00BFFF", "Deep sky blue");
7178 Color.a("#4A646C", "Deep Space Sparkle");
7179 Color.a("#7E5E60", "Deep Taupe");
7180 Color.a("#66424D", "Deep Tuscan red");
7181 Color.a("#BA8759", "Deer");
7182 Color.a("#1560BD", "Denim");
7183 Color.a("#EDC9AF", "Desert sand");
7184 Color.a("#EA3C53", "Desire");
7185 Color.a("#B9F2FF", "Diamond");
7186 Color.a("#696969", "Dim gray");
7187 Color.a("#9B7653", "Dirt");
7188 Color.a("#1E90FF", "Dodger blue");
7189 Color.a("#D71868", "Dogwood rose");
7190 Color.a("#85BB65", "Dollar bill");
7191 Color.a("#664C28", "Donkey Brown");
7192 Color.a("#00009C", "Duke blue");
7193 Color.a("#E5CCC9", "Dust storm");
7194 Color.a("#EFDFBB", "Dutch white");
7195 Color.a("#E1A95F", "Earth yellow");
7196 Color.a("#555D50", "Ebony");
7197 Color.a("#1B1B1B", "Logan's old colour </3"); //Logan's old colour </3
7198 Color.a("#614051", "Eggplant");
7199 Color.a("#F0EAD6", "Eggshell");
7200 Color.a("#1034A6", "Egyptian blue");
7201 Color.a("#7DF9FF", "Electric blue");
7202 Color.a("#FF003F", "Electric crimson");
7203 Color.a("#00FF00", "Electric green");
7204 Color.a("#6F00FF", "Electric indigo");
7205 Color.a("#CCFF00", "Electric lime");
7206 Color.a("#BF00FF", "Electric purple");
7207 Color.a("#3F00FF", "Electric ultramarine");
7208 Color.a("#FFFF00", "Electric yellow");
7209 Color.a("#50C878", "Emerald");
7210 Color.a("#6C3082", "Eminence");
7211 Color.a("#1B4D3E", "English green");
7212 Color.a("#B48395", "English lavender");
7213 Color.a("#AB4B52", "English red");
7214 Color.a("#563C5C", "English violet");
7215 Color.a("#96C8A2", "Eton blue");
7216 Color.a("#44D7A8", "Eucalyptus");
7217 Color.a("#801818", "Falu red");
7218 Color.a("#B53389", "Fandango");
7219 Color.a("#DE5285", "Fandango pink");
7220 Color.a("#F400A1", "Fashion fuchsia");
7221 Color.a("#E5AA70", "Fawn");
7222 Color.a("#4D5D53", "Feldgrau");
7223 Color.a("#4F7942", "Fern green");
7224 Color.a("#FF2800", "Ferrari Red");
7225 Color.a("#6C541E", "Field drab");
7226 Color.a("#B22222", "Firebrick");
7227 Color.a("#CE2029", "Fire engine red");
7228 Color.a("#E25822", "Flame");
7229 Color.a("#FC8EAC", "Flamingo pink");
7230 Color.a("#F7E98E", "Flavescent"); //Logan's new stupid colour?
7231 Color.a("#EEDC82", "Flax");
7232 Color.a("#A2006D", "Flirt");
7233 Color.a("#FFFAF0", "Floral white");
7234 Color.a("#FFBF00", "Fluorescent orange");
7235 Color.a("#FF1493", "Fluorescent pink");
7236 Color.a("#FF004F", "Folly");
7237 Color.a("#014421", "Forest green");
7238 Color.a("#228B22", "Forest green (web)");
7239 Color.a("#856D4D", "French bistre");
7240 Color.a("#0072BB", "French blue");
7241 Color.a("#FD3F92", "French fuchsia");
7242 Color.a("#86608E", "French lilac");
7243 Color.a("#9EFD38", "French lime");
7244 Color.a("#FD6C9E", "French pink");
7245 Color.a("#4E1609", "French puce");
7246 Color.a("#C72C48", "French raspberry");
7247 Color.a("#F64A8A", "French rose");
7248 Color.a("#77B5FE", "French sky blue");
7249 Color.a("#8806CE", "French violet");
7250 Color.a("#AC1E44", "French wine");
7251 Color.a("#A6E7FF", "Fresh Air");
7252 Color.a("#FF77FF", "Fuchsia pink");
7253 Color.a("#CC397B", "Fuchsia purple");
7254 Color.a("#C74375", "Fuchsia rose");
7255 Color.a("#E48400", "Fulvous");
7256 Color.a("#CC6666", "Fuzzy Wuzzy");
7257 Color.a("#DCDCDC", "Gainsboro");
7258 Color.a("#E49B0F", "Gamboge");
7259 Color.a("#007F66", "Generic viridian");
7260 Color.a("#F8F8FF", "Ghost white");
7261 Color.a("#FE5A1D", "Giants orange");
7262 Color.a("#B06500", "Ginger");
7263 Color.a("#6082B6", "Glaucous");
7264 Color.a("#E6E8FA", "Glitter");
7265 Color.a("#00AB66", "GO green");
7266 Color.a("#D4AF37", "Gold (metallic)");
7267 Color.a("#FFD700", "Gold (web) (Golden)");
7268 Color.a("#85754E", "Gold Fusion");
7269 Color.a("#996515", "Golden brown");
7270 Color.a("#FCC200", "Golden poppy");
7271 Color.a("#FFDF00", "Golden yellow");
7272 Color.a("#DAA520", "Goldenrod");
7273 Color.a("#A8E4A0", "Granny Smith Apple");
7274 Color.a("#6F2DA8", "Grape");
7275 Color.a("#808080", "Gray");
7276 Color.a("#BEBEBE", "Gray (X11 gray)");
7277 Color.a("#465945", "Gray-asparagus");
7278 Color.a("#1CAC78", "Green (Crayola)");
7279 Color.a("#008000", "Green");
7280 Color.a("#00A877", "Green (Munsell)");
7281 Color.a("#009F6B", "Green (NCS)");
7282 Color.a("#00A550", "Green (pigment)");
7283 Color.a("#66B032", "Green (RYB)");
7284 Color.a("#ADFF2F", "Green-yellow");
7285 Color.a("#A99A86", "Grullo");
7286 Color.a("#663854", "Halaya ube");
7287 Color.a("#446CCF", "Han blue");
7288 Color.a("#5218FA", "Beyonce Purple");
7289 Color.a("#E9D66B", "Hansa yellow");
7290 Color.a("#3FFF00", "Harlequin");
7291 Color.a("#C90016", "Harvard crimson");
7292 Color.a("#DA9100", "Harvest gold");
7293 Color.a("#DF73FF", "Heliotrope");
7294 Color.a("#AA98A9", "Heliotrope gray");
7295 Color.a("#F0FFF0", "Honeydew");
7296 Color.a("#006DB0", "Honolulu blue");
7297 Color.a("#49796B", "Chloe's green");
7298 Color.a("#FF1DCE", "Hot magenta");
7299 Color.a("#FF69B4", "Hot pink");
7300 Color.a("#71A6D2", "Iceberg");
7301 Color.a("#FCF75E", "Icterine");
7302 Color.a("#319177", "Illuminating Emerald");
7303 Color.a("#602F6B", "Imperial");
7304 Color.a("#002395", "Imperial blue");
7305 Color.a("#66023C", "Imperial purple");
7306 Color.a("#ED2939", "Imperial red");
7307 Color.a("#B2EC5D", "Inchworm");
7308 Color.a("#4C516D", "Independence");
7309 Color.a("#138808", "India green");
7310 Color.a("#CD5C5C", "Indian red");
7311 Color.a("#E3A857", "Indian yellow");
7312 Color.a("#4B0082", "Indigo");
7313 Color.a("#002FA7", "International Klein Blue");
7314 Color.a("#FF4F00", "International orange (aerospace)");
7315 Color.a("#BA160C", "International orange (engineering)");
7316 Color.a("#C0362C", "International orange (Golden Gate Bridge)");
7317 Color.a("#5A4FCF", "Iris");
7318 Color.a("#F4F0EC", "Isabelline");
7319 Color.a("#009000", "Islamic green");
7320 Color.a("#B2FFFF", "Italian sky blue");
7321 Color.a("#FFFFF0", "Ivory");
7322 Color.a("#00A86B", "Jade");
7323 Color.a("#9D2933", "Japanese carmine");
7324 Color.a("#264348", "Japanese indigo");
7325 Color.a("#5B3256", "Japanese violet");
7326 Color.a("#D73B3E", "Jasper");
7327 Color.a("#A50B5E", "Jazzberry jam");
7328 Color.a("#DA614E", "Jelly Bean");
7329 Color.a("#343434", "Jet");
7330 Color.a("#F4CA16", "Jonquil");
7331 Color.a("#8AB9F1", "Jordy blue");
7332 Color.a("#BDDA57", "June bud");
7333 Color.a("#29AB87", "Jungle green");
7334 Color.a("#4CBB17", "Kelly green");
7335 Color.a("#7C1C05", "Kenyan copper");
7336 Color.a("#3AB09E", "Keppel");
7337 Color.a("#C3B091", "Khaki");
7338 Color.a("#E79FC4", "Kobi");
7339 Color.a("#354230", "Kombu green");
7340 Color.a("#E8000D", "KU Crimson");
7341 Color.a("#087830", "La Salle Green");
7342 Color.a("#D6CADD", "Languid lavender");
7343 Color.a("#26619C", "Lapis lazuli");
7344 Color.a("#A9BA9D", "Laurel green");
7345 Color.a("#CF1020", "Lava");
7346 Color.a("#B57EDC", "Lavender (floral)");
7347 Color.a("#CCCCFF", "Lavender blue");
7348 Color.a("#FFF0F5", "Lavender blush");
7349 Color.a("#C4C3D0", "Lavender gray");
7350 Color.a("#9457EB", "Lavender indigo");
7351 Color.a("#EE82EE", "Lavender magenta");
7352 Color.a("#E6E6FA", "Lavender mist");
7353 Color.a("#FBAED2", "Lavender pink");
7354 Color.a("#967BB6", "Lavender purple");
7355 Color.a("#FBA0E3", "Lavender rose");
7356 Color.a("#7CFC00", "Lawn green");
7357 Color.a("#FFF700", "Lemon");
7358 Color.a("#FFFACD", "Lemon chiffon");
7359 Color.a("#CCA01D", "Lemon curry");
7360 Color.a("#FDFF00", "Lemon glacier");
7361 Color.a("#E3FF00", "Lemon lime");
7362 Color.a("#F6EABE", "Lemon meringue");
7363 Color.a("#FFF44F", "Lemon yellow");
7364 Color.a("#1A1110", "Licorice");
7365 Color.a("#545AA7", "Liberty");
7366 Color.a("#FDD5B1", "Light apricot");
7367 Color.a("#ADD8E6", "Light blue");
7368 Color.a("#B5651D", "Light brown");
7369 Color.a("#E66771", "Light carmine pink");
7370 Color.a("#F08080", "Light coral");
7371 Color.a("#93CCEA", "Light cornflower blue");
7372 Color.a("#F56991", "Light crimson");
7373 Color.a("#E0FFFF", "Light cyan");
7374 Color.a("#FF5CCD", "Light deep pink");
7375 Color.a("#C8AD7F", "Light French beige");
7376 Color.a("#F984EF", "Light fuchsia pink");
7377 Color.a("#FAFAD2", "Light goldenrod yellow");
7378 Color.a("#D3D3D3", "Light gray");
7379 Color.a("#90EE90", "Light green");
7380 Color.a("#FFB3DE", "Light hot pink");
7381 Color.a("#F0E68C", "Light khaki");
7382 Color.a("#D39BCB", "Light medium orchid");
7383 Color.a("#ADDFAD", "Light moss green");
7384 Color.a("#E6A8D7", "Light orchid");
7385 Color.a("#B19CD9", "Light pastel purple");
7386 Color.a("#FFB6C1", "Light pink");
7387 Color.a("#E97451", "Light red ochre");
7388 Color.a("#FFA07A", "Light salmon");
7389 Color.a("#FF9999", "Light salmon pink");
7390 Color.a("#20B2AA", "Light sea green");
7391 Color.a("#87CEFA", "Light sky blue");
7392 Color.a("#778899", "Light slate gray");
7393 Color.a("#B0C4DE", "Light steel blue");
7394 Color.a("#B38B6D", "Light taupe");
7395 Color.a("#FFFFE0", "Light yellow");
7396 Color.a("#C8A2C8", "Lilac");
7397 Color.a("#BFFF00", "Lime");
7398 Color.a("#32CD32", "Lime green");
7399 Color.a("#9DC209", "Limerick");
7400 Color.a("#195905", "Prostitute green");
7401 Color.a("#FAF0E6", "Linen");
7402 Color.a("#6CA0DC", "Little boy blue");
7403 Color.a("#B86D29", "Liver (dogs)");
7404 Color.a("#6C2E1F", "Liver");
7405 Color.a("#987456", "Liver chestnut");
7406 Color.a("#FFE4CD", "Lumber");
7407 Color.a("#E62020", "Lust");
7408 Color.a("#FF00FF", "Magenta");
7409 Color.a("#CA1F7B", "Magenta (dye)");
7410 Color.a("#D0417E", "Magenta (Pantone)");
7411 Color.a("#FF0090", "Magenta (process)");
7412 Color.a("#9F4576", "Magenta haze");
7413 Color.a("#AAF0D1", "Magic mint");
7414 Color.a("#F8F4FF", "Magnolia");
7415 Color.a("#C04000", "Mahogany");
7416 Color.a("#6050DC", "Majorelle Blue");
7417 Color.a("#0BDA51", "Malachite");
7418 Color.a("#979AAA", "Manatee");
7419 Color.a("#FF8243", "Mango Tango");
7420 Color.a("#74C365", "Mantis"); //The colour of Mantis (#78cb53) - new fav colour
7421 Color.a("#880085", "Mardi Gras");
7422 Color.a("#800000", "Maroon");
7423 Color.a("#E0B0FF", "Mauve");
7424 Color.a("#915F6D", "Mauve taupe");
7425 Color.a("#EF98AA", "Mauvelous");
7426 Color.a("#4C9141", "May green");
7427 Color.a("#73C2FB", "Maya blue");
7428 Color.a("#E5B73B", "Golden");
7429 Color.a("#66DDAA", "Medium aquamarine");
7430 Color.a("#0000CD", "Medium blue");
7431 Color.a("#E2062C", "Medium candy apple red");
7432 Color.a("#AF4035", "Medium carmine");
7433 Color.a("#035096", "Medium electric blue");
7434 Color.a("#1C352D", "Medium jungle green");
7435 Color.a("#BA55D3", "Medium orchid");
7436 Color.a("#9370DB", "Medium purple");
7437 Color.a("#BB3385", "Medium red-violet");
7438 Color.a("#AA4069", "Medium ruby");
7439 Color.a("#3CB371", "Medium sea green");
7440 Color.a("#80DAEB", "Medium sky blue");
7441 Color.a("#7B68EE", "Medium slate blue");
7442 Color.a("#C9DC87", "Medium spring bud");
7443 Color.a("#00FA9A", "Medium spring green");
7444 Color.a("#674C47", "Medium taupe");
7445 Color.a("#48D1CC", "Medium turquoise");
7446 Color.a("#D9603B", "Pale vermilion");
7447 Color.a("#F8B878", "Mellow apricot");
7448 Color.a("#F8DE7E", "Mellow yellow");
7449 Color.a("#FDBCB4", "Melon");
7450 Color.a("#0A7E8C", "Metallic Seaweed");
7451 Color.a("#9C7C38", "Metallic Sunburst");
7452 Color.a("#E4007C", "Mexican pink");
7453 Color.a("#191970", "Midnight blue");
7454 Color.a("#004953", "Midnight green (eagle green)");
7455 Color.a("#FFC40C", "Mikado yellow");
7456 Color.a("#E3F988", "Mindaro");
7457 Color.a("#3EB489", "Mint");
7458 Color.a("#F5FFFA", "Mint cream");
7459 Color.a("#98FF98", "Mint green");
7460 Color.a("#FFE4E1", "Misty rose");
7461 Color.a("#73A9C2", "Moonstone blue");
7462 Color.a("#AE0C00", "Mordant red 19");
7463 Color.a("#8A9A5B", "Moss green");
7464 Color.a("#30BA8F", "Mountain Meadow");
7465 Color.a("#997A8D", "Mountbatten pink");
7466 Color.a("#18453B", "MSU Green");
7467 Color.a("#306030", "Mughal green");
7468 Color.a("#C54B8C", "Mulberry");
7469 Color.a("#FFDB58", "Mustard");
7470 Color.a("#317873", "Myrtle green");
7471 Color.a("#F6ADC6", "Nadeshiko pink");
7472 Color.a("#2A8000", "Napier green");
7473 Color.a("#FFDEAD", "Navajo white");
7474 Color.a("#000080", "Navy");
7475 Color.a("#FFA343", "Neon Carrot");
7476 Color.a("#FE4164", "Neon fuchsia");
7477 Color.a("#39FF14", "Neon green");
7478 Color.a("#214FC6", "New Car");
7479 Color.a("#D7837F", "New York pink");
7480 Color.a("#A4DDED", "Non-photo blue");
7481 Color.a("#059033", "North Texas Green");
7482 Color.a("#E9FFDB", "Nyanza");
7483 Color.a("#0077BE", "Ocean Boat Blue");
7484 Color.a("#CC7722", "Ochre");
7485 Color.a("#43302E", "Old burgundy");
7486 Color.a("#CFB53B", "Old gold");
7487 Color.a("#FDF5E6", "Old lace");
7488 Color.a("#796878", "Old lavender");
7489 Color.a("#673147", "Old mauve");
7490 Color.a("#867E36", "Old moss green");
7491 Color.a("#C08081", "Old rose");
7492 Color.a("#808000", "Olive");
7493 Color.a("#6B8E23", "Olive Drab #3");
7494 Color.a("#3C341F", "Olive Drab #7");
7495 Color.a("#9AB973", "Olivine");
7496 Color.a("#353839", "Onyx");
7497 Color.a("#B784A7", "Opera mauve");
7498 Color.a("#FF7F00", "Orange");
7499 Color.a("#FF7538", "Orange (Crayola)");
7500 Color.a("#FF5800", "Orange (Pantone)");
7501 Color.a("#FB9902", "Orange (RYB)");
7502 Color.a("#FFA500", "Orange (web)");
7503 Color.a("#FF9F00", "Orange peel");
7504 Color.a("#FF4500", "Orange-red");
7505 Color.a("#DA70D6", "Orchid");
7506 Color.a("#F2BDCD", "Orchid pink");
7507 Color.a("#FB4F14", "Orioles orange");
7508 Color.a("#414A4C", "Outer Space");
7509 Color.a("#FF6E4A", "Outrageous Orange");
7510 Color.a("#002147", "Oxford Blue");
7511 Color.a("#990000", "Crimson Red");
7512 Color.a("#006600", "Pakistan green");
7513 Color.a("#273BE2", "Palatinate blue");
7514 Color.a("#682860", "Palatinate purple");
7515 Color.a("#BCD4E6", "Pale aqua");
7516 Color.a("#AFEEEE", "Pale blue");
7517 Color.a("#987654", "Pale brown");
7518 Color.a("#9BC4E2", "Pale cerulean");
7519 Color.a("#DDADAF", "Pale chestnut");
7520 Color.a("#DA8A67", "Pale copper");
7521 Color.a("#ABCDEF", "Pale cornflower blue");
7522 Color.a("#E6BE8A", "Pale gold");
7523 Color.a("#EEE8AA", "Pale goldenrod");
7524 Color.a("#98FB98", "Pale green");
7525 Color.a("#DCD0FF", "Pale lavender");
7526 Color.a("#F984E5", "Pale magenta");
7527 Color.a("#FADADD", "Pale pink");
7528 Color.a("#DDA0DD", "Pale plum");
7529 Color.a("#DB7093", "Nipple");
7530 Color.a("#96DED1", "Pale robin egg blue");
7531 Color.a("#C9C0BB", "Pale silver");
7532 Color.a("#ECEBBD", "Pale spring bud");
7533 Color.a("#BC987E", "Pale taupe");
7534 Color.a("#78184A", "Pansy purple");
7535 Color.a("#009B7D", "Paolo Veronese green");
7536 Color.a("#FFEFD5", "Papaya whip");
7537 Color.a("#E63E62", "Paradise pink");
7538 Color.a("#AEC6CF", "Pastel blue");
7539 Color.a("#836953", "Pastel brown");
7540 Color.a("#CFCFC4", "Pastel gray");
7541 Color.a("#77DD77", "Pastel green");
7542 Color.a("#F49AC2", "Pastel magenta");
7543 Color.a("#FFB347", "Pastel orange");
7544 Color.a("#DEA5A4", "Pastel pink");
7545 Color.a("#B39EB5", "Pastel purple");
7546 Color.a("#FF6961", "Pastel red");
7547 Color.a("#CB99C9", "Pastel violet");
7548 Color.a("#FDFD96", "Pastel yellow");
7549 Color.a("#FFE5B4", "Peach");
7550 Color.a("#FFCC99", "Peach-orange");
7551 Color.a("#FFDAB9", "Peach puff");
7552 Color.a("#FADFAD", "Peach-yellow");
7553 Color.a("#D1E231", "Pear");
7554 Color.a("#EAE0C8", "Pearl");
7555 Color.a("#88D8C0", "Dolphin Aqua");
7556 Color.a("#B768A2", "Pearly purple");
7557 Color.a("#E6E200", "Peridot");
7558 Color.a("#1C39BB", "Persian blue");
7559 Color.a("#00A693", "Persian green");
7560 Color.a("#32127A", "Persian indigo");
7561 Color.a("#D99058", "Persian orange");
7562 Color.a("#F77FBE", "Persian pink");
7563 Color.a("#701C1C", "Persian plum");
7564 Color.a("#CC3333", "Persian red");
7565 Color.a("#FE28A2", "Persian rose");
7566 Color.a("#EC5800", "Persimmon");
7567 Color.a("#CD853F", "Peru");
7568 Color.a("#000F89", "Phthalo blue");
7569 Color.a("#123524", "Phthalo green");
7570 Color.a("#45B1E8", "Picton blue");
7571 Color.a("#C30B4E", "Pictorial carmine");
7572 Color.a("#FDDDE6", "Piggy pink");
7573 Color.a("#01796F", "Pine green");
7574 Color.a("#FFC0CB", "Pink");
7575 Color.a("#D74894", "Pink (Pantone)");
7576 Color.a("#FFDDF4", "Pink lace");
7577 Color.a("#D8B2D1", "Pink lavender");
7578 Color.a("#FF9966", "Pink-orange");
7579 Color.a("#E7ACCF", "Pink pearl");
7580 Color.a("#F78FA7", "Pink Sherbet");
7581 Color.a("#93C572", "Pistachio");
7582 Color.a("#E5E4E2", "Platinum");
7583 Color.a("#8E4585", "Plum");
7584 Color.a("#BE4F62", "Popstar");
7585 Color.a("#FF5A36", "Portland Orange");
7586 Color.a("#B0E0E6", "Powder blue");
7587 Color.a("#FF8F00", "Princeton orange");
7588 Color.a("#003153", "Prussian blue");
7589 Color.a("#DF00FF", "Psychedelic purple");
7590 Color.a("#CC8899", "Puce");
7591 Color.a("#644117", "Pullman Brown (UPS Brown)");
7592 Color.a("#FF7518", "Pumpkin");
7593 Color.a("#800080", "Purple");
7594 Color.a("#9F00C5", "Purple (Munsell)");
7595 Color.a("#A020F0", "Purple");
7596 Color.a("#69359C", "Purple Heart");
7597 Color.a("#9678B6", "Purple mountain majesty");
7598 Color.a("#4E5180", "Purple navy");
7599 Color.a("#FE4EDA", "Purple pizzazz");
7600 Color.a("#50404D", "Purple taupe");
7601 Color.a("#9A4EAE", "Purpureus");
7602 Color.a("#51484F", "Quartz");
7603 Color.a("#436B95", "Queen blue");
7604 Color.a("#E8CCD7", "Queen pink");
7605 Color.a("#8E3A59", "Quinacridone magenta");
7606 Color.a("#FF355E", "Radical Red");
7607 Color.a("#FBAB60", "Rajah");
7608 Color.a("#E30B5D", "Raspberry");
7609 Color.a("#E25098", "Raspberry pink");
7610 Color.a("#B3446C", "Raspberry rose");
7611 Color.a("#826644", "Raw umber");
7612 Color.a("#FF33CC", "Razzle dazzle rose");
7613 Color.a("#E3256B", "Razzmatazz");
7614 Color.a("#8D4E85", "Razzmic Berry");
7615 Color.a("#FF0000", "Red");
7616 Color.a("#EE204D", "Red (Crayola)");
7617 Color.a("#F2003C", "Red (Munsell)");
7618 Color.a("#C40233", "Red (NCS)");
7619 Color.a("#ED1C24", "Red (pigment)");
7620 Color.a("#FE2712", "Red (RYB)");
7621 Color.a("#A52A2A", "Red-brown");
7622 Color.a("#860111", "Red devil");
7623 Color.a("#FF5349", "Red-orange");
7624 Color.a("#E40078", "Red-purple");
7625 Color.a("#C71585", "Red-violet");
7626 Color.a("#A45A52", "Redwood");
7627 Color.a("#522D80", "Regalia");
7628 Color.a("#002387", "Resolution blue");
7629 Color.a("#777696", "Rhythm");
7630 Color.a("#004040", "Rich black");
7631 Color.a("#F1A7FE", "Rich brilliant lavender");
7632 Color.a("#D70040", "Rich carmine");
7633 Color.a("#0892D0", "Rich electric blue");
7634 Color.a("#A76BCF", "Rich lavender");
7635 Color.a("#B666D2", "Rich lilac");
7636 Color.a("#B03060", "Rich maroon");
7637 Color.a("#444C38", "Rifle green");
7638 Color.a("#704241", "Deep Roast coffee");
7639 Color.a("#00CCCC", "Robin egg blue");
7640 Color.a("#8A7F80", "Rocket metallic");
7641 Color.a("#838996", "Roman silver");
7642 Color.a("#F9429E", "Rose bonbon");
7643 Color.a("#674846", "Rose ebony");
7644 Color.a("#B76E79", "Rose gold");
7645 Color.a("#FF66CC", "Rose pink");
7646 Color.a("#C21E56", "Rose red");
7647 Color.a("#905D5D", "Rose taupe");
7648 Color.a("#AB4E52", "Rose vale");
7649 Color.a("#65000B", "Rosewood");
7650 Color.a("#D40000", "Rosso corsa");
7651 Color.a("#BC8F8F", "Rosy brown");
7652 Color.a("#0038A8", "Royal azure");
7653 Color.a("#002366", "Royal blue");
7654 Color.a("#4169E1", "Royal light blue");
7655 Color.a("#CA2C92", "Royal fuchsia");
7656 Color.a("#7851A9", "Royal purple");
7657 Color.a("#FADA5E", "Royal yellow");
7658 Color.a("#CE4676", "Ruber");
7659 Color.a("#D10056", "Rubine red");
7660 Color.a("#E0115F", "Ruby");
7661 Color.a("#9B111E", "Ruby red");
7662 Color.a("#FF0028", "Ruddy");
7663 Color.a("#BB6528", "Ruddy brown");
7664 Color.a("#E18E96", "Ruddy pink");
7665 Color.a("#A81C07", "Rufous");
7666 Color.a("#80461B", "Russet");
7667 Color.a("#679267", "Russian green");
7668 Color.a("#32174D", "Russian violet");
7669 Color.a("#B7410E", "Rust");
7670 Color.a("#DA2C43", "Rusty red");
7671 Color.a("#8B4513", "Saddle brown");
7672 Color.a("#FF6700", "Safety orange (blaze orange)");
7673 Color.a("#EED202", "Safety yellow");
7674 Color.a("#F4C430", "Saffron");
7675 Color.a("#BCB88A", "Sage");
7676 Color.a("#23297A", "St. Patrick's blue");
7677 Color.a("#FA8072", "Salmon");
7678 Color.a("#FF91A4", "Salmon pink");
7679 Color.a("#C2B280", "Sand");
7680 Color.a("#ECD540", "Sandstorm");
7681 Color.a("#F4A460", "Sandy brown");
7682 Color.a("#92000A", "Sangria");
7683 Color.a("#507D2A", "Sap green");
7684 Color.a("#0F52BA", "Sapphire");
7685 Color.a("#0067A5", "Sapphire blue");
7686 Color.a("#CBA135", "Satin sheen gold");
7687 Color.a("#FF2400", "Scarlet");
7688 Color.a("#FFD800", "School bus yellow");
7689 Color.a("#76FF7A", "Screamin' Green");
7690 Color.a("#006994", "Sea blue");
7691 Color.a("#2E8B57", "Sea green");
7692 Color.a("#321414", "Seal brown");
7693 Color.a("#FFF5EE", "Seashell");
7694 Color.a("#FFBA00", "Selective yellow");
7695 Color.a("#704214", "Sepia");
7696 Color.a("#8A795D", "Shadow");
7697 Color.a("#778BA5", "Shadow blue");
7698 Color.a("#FFCFF1", "Shampoo");
7699 Color.a("#009E60", "Shamrock green");
7700 Color.a("#8FD400", "Sheen Green");
7701 Color.a("#D98695", "Shimmering Blush");
7702 Color.a("#FC0FC0", "Shocking pink");
7703 Color.a("#882D17", "Sienna");
7704 Color.a("#C0C0C0", "Silver");
7705 Color.a("#ACACAC", "Silver chalice");
7706 Color.a("#5D89BA", "Silver Lake blue");
7707 Color.a("#C4AEAD", "Silver pink");
7708 Color.a("#BFC1C2", "Silver sand");
7709 Color.a("#CB410B", "Sinopia");
7710 Color.a("#007474", "Skobeloff");
7711 Color.a("#87CEEB", "Sky blue");
7712 Color.a("#CF71AF", "Sky magenta");
7713 Color.a("#6A5ACD", "Slate blue");
7714 Color.a("#708090", "Slate gray");
7715 Color.a("#C84186", "Smitten");
7716 Color.a("#738276", "Smoke");
7717 Color.a("#933D41", "Smokey topaz");
7718 Color.a("#100C08", "Smoky black");
7719 Color.a("#FFFAFA", "Snow");
7720 Color.a("#CEC8EF", "Soap");
7721 Color.a("#893843", "Solid pink");
7722 Color.a("#757575", "Sonic silver");
7723 Color.a("#9E1316", "Spartan Crimson");
7724 Color.a("#1D2951", "Space cadet");
7725 Color.a("#807532", "Spanish bistre");
7726 Color.a("#0070B8", "Spanish blue");
7727 Color.a("#D10047", "Spanish carmine");
7728 Color.a("#E51A4C", "Spanish crimson");
7729 Color.a("#989898", "Spanish gray");
7730 Color.a("#009150", "Spanish green");
7731 Color.a("#E86100", "Spanish orange");
7732 Color.a("#F7BFBE", "Spanish pink");
7733 Color.a("#E60026", "Spanish red");
7734 Color.a("#4C2882", "Spanish violet");
7735 Color.a("#007F5C", "Spanish viridian");
7736 Color.a("#0FC0FC", "Spiro Disco Ball");
7737 Color.a("#A7FC00", "Spring bud");
7738 Color.a("#00FF7F", "Spring green");
7739 Color.a("#007BB8", "Star command blue");
7740 Color.a("#4682B4", "Steel blue");
7741 Color.a("#CC33CC", "Steel pink");
7742 Color.a("#4F666A", "Stormcloud");
7743 Color.a("#E4D96F", "Straw");
7744 Color.a("#FC5A8D", "Strawberry");
7745 Color.a("#FFCC33", "Sunglow");
7746 Color.a("#E3AB57", "Sunray");
7747 Color.a("#FAD6A5", "Sunset");
7748 Color.a("#FD5E53", "Sunset orange");
7749 Color.a("#CF6BA9", "Super pink");
7750 Color.a("#D2B48C", "Tan");
7751 Color.a("#F94D00", "Tangelo");
7752 Color.a("#F28500", "Tangerine");
7753 Color.a("#FFCC00", "Tangerine yellow");
7754 Color.a("#483C32", "Dark Grayish Brown");
7755 Color.a("#8B8589", "Taupe gray");
7756 Color.a("#D0F0C0", "Tea green");
7757 Color.a("#F4C2C2", "Tea rose");
7758 Color.a("#008080", "Teal");
7759 Color.a("#367588", "Teal blue");
7760 Color.a("#99E6B3", "Teal deer");
7761 Color.a("#00827F", "Teal green");
7762 Color.a("#CF3476", "Telemagenta");
7763 Color.a("#CD5700", "Tenne");
7764 Color.a("#E2725B", "Terra cotta");
7765 Color.a("#D8BFD8", "Thistle");
7766 Color.a("#DE6FA1", "Thulian pink");
7767 Color.a("#FC89AC", "Tickle Me Pink");
7768 Color.a("#0ABAB5", "Tiffany Blue");
7769 Color.a("#E08D3C", "Tiger's eye");
7770 Color.a("#DBD7D2", "Timberwolf");
7771 Color.a("#EEE600", "Titanium yellow");
7772 Color.a("#FF6347", "Tomato");
7773 Color.a("#746CC0", "Toolbox");
7774 Color.a("#FFC87C", "Topaz");
7775 Color.a("#FD0E35", "Tractor red");
7776 Color.a("#00755E", "Tropical rain forest");
7777 Color.a("#0073CF", "True Blue");
7778 Color.a("#417DC1", "Tufts Blue");
7779 Color.a("#FF878D", "Tulip");
7780 Color.a("#DEAA88", "Tumbleweed");
7781 Color.a("#B57281", "Turkish rose");
7782 Color.a("#40E0D0", "Turquoise");
7783 Color.a("#00FFEF", "Turquoise blue");
7784 Color.a("#A0D6B4", "Turquoise green");
7785 Color.a("#7C4848", "Tuscan red");
7786 Color.a("#C09999", "Tuscany");
7787 Color.a("#8A496B", "Twilight lavender");
7788 Color.a("#0033AA", "UA blue");
7789 Color.a("#D9004C", "UA red");
7790 Color.a("#8878C3", "Ube");
7791 Color.a("#536895", "UCLA Blue");
7792 Color.a("#FFB300", "UCLA Gold");
7793 Color.a("#3CD070", "UFO Green");
7794 Color.a("#120A8F", "Ultramarine");
7795 Color.a("#4166F5", "Ultramarine blue");
7796 Color.a("#FF6FFF", "Ultra pink");
7797 Color.a("#635147", "Umber");
7798 Color.a("#FFDDCA", "Unbleached silk");
7799 Color.a("#5B92E5", "United Nations blue");
7800 Color.a("#B78727", "University of California Gold");
7801 Color.a("#FFFF66", "Unmellow yellow");
7802 Color.a("#7B1113", "UP Maroon");
7803 Color.a("#AE2029", "Upsdell red");
7804 Color.a("#E1AD21", "Urobilin");
7805 Color.a("#004F98", "USAFA blue");
7806 Color.a("#F77F00", "University of Tennessee Orange");
7807 Color.a("#D3003F", "Utah Crimson");
7808 Color.a("#F3E5AB", "Vanilla");
7809 Color.a("#F38FA9", "Vanilla ice");
7810 Color.a("#C5B358", "Vegas gold");
7811 Color.a("#C80815", "Venetian red");
7812 Color.a("#43B3AE", "Verdigris");
7813 Color.a("#E34234", "Medium vermilion");
7814 Color.a("#D9381E", "Vermilion");
7815 Color.a("#8F00FF", "Violet");
7816 Color.a("#7F00FF", "Violet (color wheel)");
7817 Color.a("#8601AF", "Violet (RYB)");
7818 Color.a("#324AB2", "Logie Bear");
7819 Color.a("#F75394", "Violet-red");
7820 Color.a("#40826D", "Viridian");
7821 Color.a("#009698", "Viridian green");
7822 Color.a("#922724", "Vivid auburn");
7823 Color.a("#9F1D35", "Vivid burgundy");
7824 Color.a("#DA1D81", "Vivid cerise");
7825 Color.a("#CC00FF", "Vivid orchid");
7826 Color.a("#00CCFF", "Vivid sky blue");
7827 Color.a("#FFA089", "Vivid tangerine");
7828 Color.a("#9F00FF", "Vivid violet");
7829 Color.a("#004242", "Warm black");
7830 Color.a("#A4F4F9", "Waterspout");
7831 Color.a("#645452", "Wenge");
7832 Color.a("#F5DEB3", "Wheat");
7833 Color.a("#FFFFFF", "White");
7834 Color.a("#F5F5F5", "White smoke");
7835 Color.a("#A2ADD0", "Wild blue yonder");
7836 Color.a("#D470A2", "Wild orchid");
7837 Color.a("#FF43A4", "Wild Strawberry");
7838 Color.a("#FC6C85", "Wild watermelon");
7839 Color.a("#FD5800", "Willpower orange");
7840 Color.a("#A75502", "Windsor tan");
7841 Color.a("#722F37", "Wine");
7842 Color.a("#C9A0DC", "Wisteria");
7843 Color.a("#C19A6B", "Wood brown");
7844 Color.a("#738678", "Xanadu");
7845 Color.a("#0F4D92", "Yale Blue");
7846 Color.a("#1C2841", "Yankees blue");
7847 Color.a("#FCE883", "Yellow Crayola");
7848 Color.a("#EFCC00", "Yellow Munsell");
7849 Color.a("#FEDF00", "Yellow Pantone");
7850 Color.a("#FEFE33", "Yellow");
7851 Color.a("#9ACD32", "Yellow Green");
7852 Color.a("#FFAE42", "Yellow Orange");
7853 Color.a("#FFF000", "Yellow rose");
7854 Color.a("#0014A8", "Zaffre");
7855 Color.a("#2C1608", "Zinnwaldite brown");
7856 Color.a("#39A78E", "Zomp");
7857
7858 // where it receives the message
7859 gClient.on("a", function (msg) {
7860 chat.receive(msg);
7861 });
7862
7863 $("#chat input").on("focus", function (evt) {
7864 releaseKeyboard();
7865 $("#chat").addClass("chatting");
7866 chat.scrollToBottom();
7867 });
7868
7869 $(document).mousedown(function (evt) {
7870 if (!$("#chat").has(evt.target).length > 0) {
7871 chat.blur();
7872 }
7873 });
7874
7875 document.addEventListener("touchstart", function (event) {
7876 for (var i in event.changedTouches) {
7877 var touch = event.changedTouches[i];
7878 if (!$("#chat").has(touch.target).length > 0) {
7879 chat.blur();
7880 }
7881 }
7882 });
7883
7884 $(document).on("keydown", function (evt) {
7885 if ($("#chat").hasClass("chatting")) {
7886 if (evt.keyCode == 27) {
7887 chat.blur();
7888 evt.preventDefault();
7889 evt.stopPropagation();
7890 } else if (evt.keyCode == 13) {
7891 $("#chat input").focus();
7892 }
7893 } else if (!gModal && (evt.keyCode == 27 || evt.keyCode == 13)) {
7894 $("#chat input").focus();
7895 }
7896 });
7897
7898 $("#chat input").on("keydown", function (evt) {
7899 if (evt.keyCode == 13) {
7900 var message = $(this).val();
7901
7902 // ♥ // local commands // ♥ //
7903
7904 if (message.length == 0) { //close chat if no input
7905 chat.blur();
7906
7907 } else if (message.substring(0, 6).toLowerCase() == cmdChar+"lhelp" || message.substring(0, 6).toLowerCase() == "!lhelp") { //local command list
7908 // thanks Someguy!
7909 localMsg("Local Commands: "+cmdChar+"name, "+cmdChar+"svol (speech volume), "+cmdChar+"spitch (speech pitch), "+cmdChar+"srate (speech speed), "+cmdChar+"sdefault, "+cmdChar+"lobby, "+cmdChar+"juggle (juggles the crown if you have it), "+cmdChar+"givefish (gives fish to fishlord), "+cmdChar+"fishlord (sets person who receives fish), "+cmdChar+"mathcheat (auto answers any "+cmdChar+"math question after a short delay)");
7910 $(this).val(""); //empties chatbox
7911 chat.blur(); //closes chat
7912
7913 } else if (message.substring(0, 5).toLowerCase() == cmdChar+"name" || message.substring(0, 5).toLowerCase() == "!name") { //name
7914 if (message.substring(5).trim() == "") {
7915 msgBox('Rename', 'Usage: '+cmdChar+'name new_name.', 3000, '#piano');
7916
7917 } else {
7918 gClient.sendArray([{
7919 "m": "userset",
7920 "set": {
7921 "name": message.substring(5).trim()
7922 }
7923 }]);
7924 selfName = message.substring(5).trim();
7925 msgBox('Renamed', message.substring(5).trim(), 3000, '#piano');
7926 }
7927 $(this).val("");
7928 chat.blur();
7929
7930 } else if (message.substring(0, 5).toLowerCase() == cmdChar+"svol" || message.substring(0, 5).toLowerCase() == "!svol") { //speech volume
7931 var speechVolumeTEMP = message.substring(6).trim()
7932 if (isNaN(speechVolumeTEMP) || speechVolumeTEMP > 1 || speechVolumeTEMP < 0 || speechVolumeTEMP == '') {
7933 msgBox('Speech Volume [usage]', 'Please enter a number no greater than 1 and no less than 0.', 5000, '#piano');
7934 $(this).val("");
7935 chat.blur();
7936 return;
7937
7938 } else {
7939 speechVolume = speechVolumeTEMP; //sets new variable value
7940 msgBox('Speech Volume', speechVolume, 3000, '#piano');
7941
7942 $(this).val("");
7943 chat.blur();
7944 }
7945
7946 } else if (message.substring(0, 7).toLowerCase() == cmdChar+"spitch" || message.substring(0, 7).toLowerCase() == "!spitch") { //speech pitch
7947 var speechPitchTEMP = message.substring(8).trim()
7948 if (isNaN(speechPitchTEMP) || speechPitchTEMP > 2 || speechPitchTEMP < 0 || speechPitchTEMP == '') {
7949 msgBox('Speech Pitch [usage]', 'Please enter a number no greater than 2 and no less than 0.', 5000, '#piano');
7950 $(this).val("");
7951 chat.blur();
7952 return;
7953
7954 } else {
7955 speechPitch = message.substring(8).trim() //sets new variable value
7956 msgBox('Pitch', speechPitch, 3000, '#piano');
7957 $(this).val("");
7958 chat.blur();
7959 }
7960
7961 } else if (message.substring(0, 6).toLowerCase() == cmdChar+"srate" || message.substring(0, 6).toLowerCase() == "!srate") { //speech rate
7962 var speechRateTEMP = message.substring(7).trim()
7963 if (isNaN(speechRateTEMP) || speechRateTEMP > 2 || speechRateTEMP < 0 || speechRateTEMP == '') {
7964 msgBox('Speech Pitch [usage]', 'Please enter a number no greater than 2 and no less than 0.', 5000, '#piano');
7965 $(this).val("");
7966 chat.blur();
7967 return;
7968
7969 } else {
7970 speechRate = message.substring(7).trim() //sets new variable value
7971 msgBox('Rate', speechRate, 3000, '#piano');
7972 $(this).val("");
7973 chat.blur();
7974 }
7975
7976 } else if (message.substring(0, 9).toLowerCase() == cmdChar+"sdefault" || message.substring(0, 9).toLowerCase() == "!sdefault") { //speech default
7977 speechVolume = 0.5; //default volume for spoken text
7978 speechPitch = 1; //default pitch for spoken text
7979 speechRate = 1; //default speed for spoken text
7980 msgBox('Speech Default', 'Volume, pitch and rate all reset.', 3000, '#piano');
7981 $(this).val("");
7982 chat.blur();
7983
7984 } else if (message.substring(0, 6).toLowerCase() == cmdChar+"lobby" || message.substring(0, 6).toLowerCase() == "!lobby") { //lobby
7985 if (gClient.isOwner()) {
7986 var lobbyConfirm = prompt("Are you sure you want to turn this room into a lobby?\nThis cannot be undone.\n\nEnter \"Yes\" below to continue.");
7987 if (lobbyConfirm == "Yes") {
7988 MPP.client.sendArray([{m: "chset", set: {lobby: true}}]);
7989 msgBox('Room is now a lobby', '', 3000, '#piano');
7990 } else {
7991 alert("Incorrectly entered text or you cancled.");
7992 }
7993
7994 } else {
7995 alert("You're not the owner of this room!");
7996 }
7997
7998 $(this).val("");
7999 chat.blur();
8000
8001 } else if (message.substring(0, 9).toLowerCase() == cmdChar+"givefish" || message.substring(0, 9).toLowerCase() == "!givefish") { //give fish
8002 giveFish = !giveFish;
8003 if (!giveFish) {
8004 msgBox('Give Fish', 'Off', 3000, '#piano');
8005
8006 } else {
8007 msgBox('Give Fish', 'On', 3000, '#piano');
8008 }
8009
8010 $(this).val("");
8011 chat.blur();
8012
8013 } else if (message.substring(0, 9).toLowerCase() == cmdChar+"fishlord" || message.substring(0, 9).toLowerCase() == "!fishlord") { //fish lord
8014 fishLord = message.substring(10).trim();
8015 if (fishLord == '') {
8016 msgBox('Fish Lord [usage]', cmdChar+'fishlord name_here', 3000, '#piano');
8017 $(this).val("");
8018 chat.blur();
8019 return;
8020 }
8021 msgBox('Fish Lord', 'Fish lord: ' + fishLord, 3000, '#piano');
8022 $(this).val("");
8023 chat.blur();
8024
8025 } else if (message.substring(0, 7).toLowerCase() == cmdChar+"juggle" || message.substring(0, 7).toLowerCase() == "!juggle") { //juggle
8026 function jugglePls() {
8027 juggling = setInterval(function() {
8028 gClient.sendArray([{
8029 m: "chown"
8030 }]);
8031 }, 2100); //2300 is good for just the dropping of it
8032 }
8033
8034 if (juggle) {
8035 juggle = false;
8036 clearInterval(juggling);
8037
8038 gClient.sendArray([{
8039 m: "chown",
8040 id: gClient.participantId
8041 }]);
8042 msgBox('Juggle Crown', 'Off', 2000, '#piano');
8043
8044 } else {
8045 juggle = true;
8046 jugglePls();
8047 msgBox('Juggle Crown', 'On', 2000, '#piano');
8048 }
8049
8050 $(this).val("");
8051 chat.blur();
8052
8053 } else if (message.substring(0, 10).toLowerCase() == cmdChar+"mathcheat" || message.substring(0, 10).toLowerCase() == "!mathcheat") { //juggle
8054 if (mathCheat) {
8055 mathCheat = false;
8056 msgBox('Math Cheats', 'Off', 2000, '#piano');
8057 } else {
8058 mathCheat = true;
8059 msgBox('Math Cheats', 'On', 2000, '#piano');
8060 }
8061
8062 $(this).val("");
8063 chat.blur();
8064
8065 // ♥ // local commands // ♥ //
8066
8067 } else if (message.length <= 512) {
8068 if (!meow && !leet) {
8069 //console.log("Triggered first");
8070 chat.send(message);
8071 $(this).val("");
8072 chat.blur();
8073 }
8074 if (message.substring(0,1).trim() != "!" && message.substring(0,1).trim() != "/" && message.substring(0,1).trim() != cmdChar) {
8075 if (meow) {
8076 //thanks electrashave!
8077 leet = false;
8078 var words = ['meow', 'meow', 'mew', 'purr'];
8079 var final = '';
8080 for (var i = 0; words.length > i; i++) {
8081 final += words[Math.floor(Math.random()*words.length)] + ' ';
8082 }
8083 final = final.toLowerCase();
8084 final = final.charAt(0).toUpperCase() + final.slice(1).trim() + '. *' + message.trim() + '*';
8085 chat.send(final);
8086 $(this).val("");
8087 chat.blur();
8088
8089 } else if (!leet){
8090 $(this).val("");
8091 chat.blur();
8092 }
8093
8094 if (leet) {
8095 meow = false;
8096 var alpha1 = "abcdefghijklmnopqrstuvwxyz0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~`?-=[]\;'\",./_+{}|:<>!@#$%^&*()♥°¬";
8097 var alpha2 = "4bcd3fgh1jklmn0pqrstuvwxyz0123456789 4BCD3FGH1JKLMN0PQRSTUVWXYZ0123456789~`?-=[]\;'\",./_+{}|:<>!@#$%^&*()♥°¬";
8098 var str = message;
8099 var newstr = '';
8100 for (var i = 0; i < str.length; i++) {
8101 charPos = alpha1.indexOf(str.charAt(i));
8102 newstr += alpha2.charAt(charPos);
8103 }
8104 chat.send(newstr);
8105 $(this).val("");
8106 chat.blur();
8107
8108 } else if (!meow) {
8109 $(this).val("");
8110 chat.blur();
8111 }
8112
8113 } else if (meow || leet) {
8114 //console.log("Triggered final");
8115 chat.send(message);
8116 $(this).val("");
8117 chat.blur();
8118 }
8119
8120 }
8121
8122 evt.preventDefault();
8123 evt.stopPropagation();
8124 } else if (evt.keyCode == 27) {
8125 chat.blur();
8126 evt.preventDefault();
8127 evt.stopPropagation();
8128 } else if (evt.keyCode == 9) {
8129 evt.preventDefault();
8130 evt.stopPropagation();
8131 }
8132 });
8133
8134 return {
8135 show: function () {
8136 $("#chat").fadeIn();
8137 },
8138
8139 hide: function () {
8140 $("#chat").fadeOut();
8141 },
8142
8143 clear: function () {
8144 if (clearChat) {
8145 $("#chat li").remove();
8146 return;
8147 }
8148 },
8149
8150 scrollToBottom: function () {
8151 var ele = $("#chat ul").get(0);
8152 ele.scrollTop = ele.scrollHeight;
8153 },
8154
8155 blur: function () {
8156 if ($("#chat").hasClass("chatting")) {
8157 $("#chat input").get(0).blur();
8158 $("#chat").removeClass("chatting");
8159 chat.scrollToBottom();
8160 captureKeyboard();
8161 }
8162 },
8163
8164 send: function (message) {
8165 gClient.sendArray([{
8166 m: "a",
8167 message: message
8168 }]);
8169 },
8170
8171
8172 receive: function (msg) {
8173 if (gChatMutes.indexOf(msg.p._id) != -1) return;
8174 msg.a = msg.a.replace(/</g, '<');
8175 msg.p.name = msg.p.name.replace(/</g, '<');
8176 content = msg.a.replace(/((https?\:\/\/|ftp\:\/\/)|(www\.))(\S+)(\w{2,4})(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/gi, function(url) {
8177 nice = url;
8178 if( url.match('^https?:\/\/') ) nice = nice.replace(/^https?:\/\//i,'')
8179 else url = 'http://' + url;
8180
8181 return '<a target="_blank" style="text-decoration: none;" href="'+ url +'">'+ url +'</a>';
8182 });
8183 var final = content;
8184
8185 var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
8186
8187 var li = $('<li><span class="name"/><span style="position: initial!important;" class="message"/>');
8188
8189 li.find(".name").html(msg.p.name + afterName); //fix for <3 showing up as lt;3 using .text instead of .html -thanks Someguy
8190 if (debug) {
8191 li.find(".name").html("[" + msg.p._id + "] " + msg.p.name + afterName);
8192 }
8193 if (timeStamp) {
8194 li.find(".name").html(getTime() + " | " + msg.p.name + afterName);
8195 }
8196 li.find(".message").html(
8197 "<span class='msg_'>"+ final + "</span>"
8198 );
8199
8200 li.css("color", msg.p.color || "white");
8201
8202 $("#chat ul").append(li);
8203
8204 var eles = $("#chat ul li").get();
8205 for (var i = 1; i <= 50 && i <= eles.length; i++) {
8206 eles[eles.length - i].style.opacity = 1.0 - (i * 0.03); //chat fade
8207 }
8208 if (eles.length > 50) {
8209 eles[0].style.display = "none";
8210 }
8211 if (eles.length > chatLimit) { //max chat log history default was 256
8212 $(eles[0]).remove();
8213 }
8214 updateChatLength(eles.length);
8215
8216 // scroll to bottom if not "chatting" or if not scrolled up
8217 if (!$("#chat").hasClass("chatting")) {
8218 chat.scrollToBottom();
8219 } else {
8220 var ele = $("#chat ul").get(0);
8221 if (ele.scrollTop > ele.scrollHeight - ele.offsetHeight - 50)
8222 chat.scrollToBottom();
8223 }
8224 if (debug2) {
8225 // test
8226 //idea to fix, I think it's the way you += the string. You need to replace the orginial with nothing then add the extra chars
8227 //length of msg: $('#chat li .msg_').get(0).innerHTML.length
8228 var myString = $('#chat li:last .msg_').get(0).innerHTML;
8229 var cut = myString.length;
8230 console.log("length: " + cut);
8231 var myArray = myString.split("");
8232 var loopTimer = 70;
8233 console.log('before loop ' + myString);
8234 $('#chat li:last .msg_').get(0).innerHTML = myString.substring(cut, cut);
8235 var frameLooper = setInterval( function() {
8236 console.log('looping ' + myString);
8237 if(myArray.length > 0) {
8238 $('#chat li:last .msg_').get(0).innerHTML += myArray.shift();
8239 } else {
8240 clearInterval(frameLooper);
8241 console.log('clearing loop ' + myString);
8242 return false;
8243 }
8244 }, loopTimer);
8245 console.log('done ' + myString);
8246
8247 //$('#chat li:last .msg_').get(0).innerHTML
8248
8249 // test
8250 }
8251
8252
8253 }
8254 };
8255
8256 })();
8257
8258
8259 clearChatFunc = function() {
8260 chat.clear();
8261 updateChatLength(0);
8262 }
8263
8264
8265 // use midi bridge (old one started here)
8266 $("#blah-btn").on("click", function (evt) {
8267 var pRoom = prompt("Enter the name of your lobby...", hotkeyRoom);
8268 if (!pRoom) return;
8269 var room_name = pRoom;
8270 changeRoom(room_name, "right", {
8271 "visible": true,
8272 "chat": true,
8273 "crownsolo": false,
8274 "lobby": true
8275 });
8276 });
8277
8278 // use midi bridge (old one ended here)
8279
8280
8281 // New MIDI
8282 var gWebMidiWorking;
8283 (function() {
8284
8285 MIDI_TRANSPOSE = -12;
8286
8287 var MIDI_KEY_NAMES = ["a-1", "as-1", "b-1"];
8288 var bare_notes = "c cs d ds e f fs g gs a as b".split(" ");
8289 for(var oct = 0; oct < 7; oct++) {
8290 for(var i in bare_notes) {
8291 MIDI_KEY_NAMES.push(bare_notes[i] + oct);
8292 }
8293 }
8294 MIDI_KEY_NAMES.push("c7");
8295
8296 if (navigator.requestMIDIAccess) {
8297 navigator.requestMIDIAccess().then(
8298 function(midi) {
8299 console.log(midi);
8300 if(midi.inputs.size > 0) {
8301 var inputs = midi.inputs.values();
8302 for(var input_it = inputs.next(); input_it && !input_it.done; input_it = inputs.next()) {
8303 var input = input_it.value;
8304 console.log(input);
8305 input.onmidimessage = function(evt) {
8306 var channel = evt.data[0] & 0xf;
8307 var cmd = evt.data[0] >> 4;
8308 var note_number = evt.data[1];
8309 var vel = evt.data[2];
8310 //console.log(channel, cmd, note_number, vel);
8311 if(cmd == 8 || (cmd == 9 && vel == 0)) {
8312 // NOTE_OFF
8313 release(MIDI_KEY_NAMES[note_number - 9 + MIDI_TRANSPOSE]);
8314 } else if(cmd == 9) {
8315 // NOTE_ON
8316 press(MIDI_KEY_NAMES[note_number - 9 + MIDI_TRANSPOSE], vel / 100);
8317 } else if(cmd == 11) {
8318 // CONTROL_CHANGE
8319 if(!gAutoSustain) {
8320 if(note_number == 64) {
8321 if(vel > 0) {
8322 pressSustain();
8323 } else {
8324 releaseSustain();
8325 }
8326 }
8327 }
8328 }
8329 };
8330 if(!gWebMidiWorking) {
8331 gWebMidiWorking = true;
8332 new Notification({title:"Nice!", text:"Web MIDI is going.", duration:2000}); //MIDI working
8333 }
8334 }
8335 } else {
8336 console.log("no midi inputs");
8337 gWebMidiWorking = false;
8338 }
8339 if(gMidiOutTest && midi.outputs.size > 0) {
8340 var outputs = midi.outputs.values();
8341 for(var output_it = outputs.next(); output_it && !output_it.done; output_it = outputs.next()) {
8342 var output = output_it.value;
8343 console.log(output);
8344 }
8345 gMidiOutTest = function(note_name, vel, delay_ms) {
8346 var note_number = MIDI_KEY_NAMES.indexOf(note_name);
8347 if(note_number == -1) return;
8348 note_number = note_number + 9 - MIDI_TRANSPOSE;
8349
8350 var outputs = midi.outputs.values();
8351 for(var output_it = outputs.next(); output_it && !output_it.done; output_it = outputs.next()) {
8352 var output = output_it.value;
8353 output.send([0x90, note_number, vel], window.performance.now() + delay_ms);
8354 }
8355 }
8356 }
8357 },
8358 function(err){
8359 console.log(err);
8360 gWebMidiWorking = false;
8361 } );
8362 }
8363 })();
8364
8365
8366
8367 //More button
8368 (function () {
8369 var loaded = false;
8370 $("#social").fadeIn(250);
8371 $("#more-button").click(function () {
8372 //stuff goes between here and..
8373 if (leet) {
8374 leet = false;
8375 } else {
8376 leet = true;
8377 }
8378 msgBox('1337 Mode', ''+leet, 2000, '#piano');
8379 });
8380 })();
8381
8382
8383 //api
8384 //window.MPP
8385 MPP = {
8386 press: press,
8387 release: release,
8388 piano: gPiano,
8389 client: gClient,
8390 chat: chat,
8391 msgBox: msgBox,
8392 SoundSelector: gSoundSelector
8393 };
8394
8395
8396});
8397//main end
8398
8399//Thanks B@K$
8400MPP.client.sendArray = function(arr) {
8401 if (arr[0].m == "m") {
8402 logie = this;
8403 logie.participantUpdate({
8404 id: logie.participantId
8405 , x: parseFloat(arr[0].x)
8406 , y: parseFloat(arr[0].y)
8407 , m: "m"
8408 });
8409 }
8410 this.send(JSON.stringify(arr));
8411}
8412
8413// miscellaneous HTML changes
8414 // default place holder for chat
8415 $("#chat .translate").attr("placeholder", "")
8416
8417// miscellaneous HTML changes
8418
8419//HTML Stuff (note: the big buttons are 120px apart and the heart buttons are 25px apart -Logan)
8420//button 1
8421$("body #bottom .relative").append('<div id="1-btn" class="ugly-button 1_btn" style="position: fixed;bottom: 29px;right: 365px;width: 100px">Toggle Piano</div>');
8422$("#1-btn").click(function(){
8423 $("#piano").fadeToggle(1000);
8424});
8425
8426//Joke Generator
8427//button 2
8428$("body #bottom .relative").append('<div id="2-btn" class="ugly-button 2_btn" style="position: fixed;bottom: 29px;right: 245px;width: 100px">Joke Generator</div>');
8429$("#2-btn").click(function(){
8430 var Animal = ['chicken', 'turtle', 'rabbit', 'rat', 'kangaroo', 'cuddlepet', 'fox', 'wolf', 'bat', 'gecko', 'scorpion', 'cat', 'dog', 'parrot', 'seagull', 'elf', 'pony', 'pixie', 'polar bear', 'penguin', 'anteater', 'chipmunk', 'monkey', 'gorilla', 'goat', 'emu', 'elephant', 'horse', 'frog', 'hamster', 'duck', 'flamingo', 'eagle', 'gerbil', 'catfish', 'baboon', 'reindeer', 'seal', 'walrus', 'worm', 'Turkey', 'Panda', 'mule', 'donkey', 'meerkat', 'shark', 'lion', 'tiger', 'jaguar', 'jellyfish', 'igunana', 'lemming', 'crab', 'ladybird', 'rinoceros'];
8431 var Location = ['road', 'beach', 'field', 'desert', 'parking-lot', 'rugby park', 'lake', 'forest', 'table', 'railway', 'boat', 'village', 'airport', 'city', 'mall', 'river', 'quicksand', 'orchard', 'island', 'hall', 'stage', 'golf course', 'driveway'];
8432 var Punchline = ['To cuddle with a bunny.', 'To buy a jar of cat semen.', 'To put out a fire.', 'To buy a jar of dog semen.', 'To escape the anons.', 'To get to the other side.', 'To buy a chocolate milk.', 'To visit ' + selfName + '.', 'To buy small shoes.', 'To buy sheet music.', 'To stomp the small children.', 'To buy balloons.', 'To make better punchlines.', 'To buy a big fluffy bed to sleep in and cuddle.', 'To stamp on a cat with gumboots.', 'To help an eldery woman get run over.', 'To bite people.', 'To scratch people.', 'To eat people.', 'To aquire a large stick.', 'To send mail.', 'So it could die over there.', 'So it could strangulate small mammals.', 'So it could transport illicit drugs.', 'Because there was a car coming.', 'Because it’s cool.', 'Because it’s fat.', 'To sniff things up its nose.'];
8433 var Aselection = Math.floor(Math.random() * Animal.length);
8434 var Lselection = Math.floor(Math.random() * Location.length);
8435 var Pselection = Math.floor(Math.random() * Punchline.length);
8436 jokeGens++;
8437 document.getElementById("2-btn").innerHTML = "Joke Generator " + jokeGens
8438 sendChat("[Joke Generator #" + jokeGens + "] Why did the " + Animal[Aselection] + " cross the " + Location[Lselection] + "? " + Punchline[Pselection]);
8439});
8440
8441//Bunny ASCII Art
8442//button 3
8443$("body #bottom .relative").append('<div id="3-btn" class="ugly-button 3_btn" style="position: fixed;bottom: 29px;right: 125px;width: 100px">Bunny ASCII Art</div>');
8444$("#3-btn").click(function(){
8445 setTimeout(function() { sendChat("(\\_/)" ); }, 0);
8446 setTimeout(function() { sendChat("(o.o)" ); }, 0);
8447 setTimeout(function() { sendChat("('')('')" ); }, 0);
8448});
8449
8450//♥ Test Button ♥
8451//button 4
8452function updateChatLength(num) {
8453 document.getElementById("4-btn").innerHTML = "Msgs: " + num;
8454}
8455$("body #bottom .relative").append('<div id="4-btn" class="ugly-button 4_btn" style="position: fixed;bottom: 29px;right: 5px;width: 100px; text-align:center"; title="Messages shown in chat">Msgs: 0</div>');
8456$("#4-btn").click(function(){
8457 var yayNayChat = confirm("Do you want to clear the chat?");
8458
8459 if (yayNayChat) {
8460 clearChat = true;
8461 clearChatFunc();
8462 clearChat = false;
8463 }
8464});
8465
8466//♥ button 5
8467$("body #bottom .relative").append('<div id="5-btn" class="ugly-button 5_btn" style="position: fixed;color: red;bottom: 2px;right: 5px;width: 10px"; title="Debug Toggle">♥</div>');
8468$("#5-btn").click(function(){
8469 if (debug) {
8470 //off
8471 debug = false;
8472 document.getElementById("5-btn").style.color = "red";
8473 } else {
8474 //on
8475 debug = true;
8476 document.getElementById("5-btn").style.color = "green";
8477 }
8478});
8479
8480//♥ button 6
8481$("body #bottom .relative").append('<div id="6-btn" class="ugly-button 6_btn" style="position: fixed;color: orange;bottom: 2px;right: 30px;width: 10px"; title="I love you :3">♥</div>');
8482$("#6-btn").click(function(){
8483 document.getElementById("6-btn").style.color = Col();
8484 //nothing as of now
8485});
8486
8487//♥ button 7
8488$("body #bottom .relative").append('<div id="7-btn" class="ugly-button 7_btn" style="position: fixed;color: yellow;bottom: 2px;right: 55px;width: 10px"; title="I love you :3">♥</div>');
8489$("#7-btn").click(function(){
8490 document.getElementById("7-btn").style.color = Col();
8491 //nothing as of now
8492});
8493
8494//♥ button 8
8495$("body #bottom .relative").append('<div id="8-btn" class="ugly-button 8_btn" style="position: fixed;color: green;bottom: 2px;right: 80px;width: 10px"; title="I love you :3">♥</div>');
8496$("#8-btn").click(function(){
8497 document.getElementById("8-btn").style.color = Col();
8498 //nothing as of now
8499});
8500
8501//♥ button 9
8502$("body #bottom .relative").append('<div id="9-btn" class="ugly-button 9_btn" style="position: fixed;color: blue;bottom: 2px;right: 105px;width: 10px"; title="I love you :3">♥</div>');
8503$("#9-btn").click(function(){
8504 document.getElementById("9-btn").style.color = Col();
8505 //nothing as of now
8506});
8507
8508//♥ button 10
8509$("body #bottom .relative").append('<div id="10-btn" class="ugly-button 10_btn" style="position: fixed;color: indigo;bottom: 2px;right: 130px;width: 10px"; title="I love you :3">♥</div>');
8510$("#10-btn").click(function(){
8511 document.getElementById("10-btn").style.color = Col();
8512 //nothing as of now
8513});
8514
8515//♥ button 11
8516$("body #bottom .relative").append('<div id="11-btn" class="ugly-button 11_btn" style="position: fixed;color: violet;bottom: 2px;right: 155px;width: 10px"; title="I love you :3">♥</div>');
8517$("#11-btn").click(function(){
8518 document.getElementById("11-btn").style.color = Col();
8519 //nothing as of now
8520});
8521
8522//♥ button 12
8523$("body #bottom .relative").append('<div id="12-btn" class="ugly-button 12_btn" style="position: fixed;color: indigo;bottom: 2px;right: 180px;width: 10px"; title="Debug Toggle">♥</div>');
8524$("#12-btn").click(function(){
8525 document.getElementById("12-btn").style.color = Col();
8526 //nothing as of now
8527});
8528
8529//♥ button 13
8530$("body #bottom .relative").append('<div id="13-btn" class="ugly-button 13_btn" style="position: fixed;color: blue;bottom: 2px;right: 205px;width: 10px"; title="I love you :3">♥</div>');
8531$("#13-btn").click(function(){
8532 document.getElementById("13-btn").style.color = Col();
8533 //nothing as of now
8534});
8535
8536//♥ button 14
8537$("body #bottom .relative").append('<div id="14-btn" class="ugly-button 14_btn" style="position: fixed;color: green;bottom: 2px;right: 230px;width: 10px"; title="I love you :3">♥</div>');
8538$("#14-btn").click(function(){
8539 document.getElementById("14-btn").style.color = Col();
8540 //nothing as of now
8541});
8542
8543//♥ button 15
8544$("body #bottom .relative").append('<div id="15-btn" class="ugly-button 15_btn" style="position: fixed;color: yellow;bottom: 2px;right: 255px;width: 10px"; title="I love you :3">♥</div>');
8545$("#15-btn").click(function(){
8546 document.getElementById("15-btn").style.color = Col();
8547 //nothing as of now
8548});
8549
8550//♥ button 16
8551$("body #bottom .relative").append('<div id="16-btn" class="ugly-button 16_btn" style="position: fixed;color: orange;bottom: 2px;right: 280px;width: 10px"; title="I love you :3">♥</div>');
8552var playingMid = false;
8553document.getElementById("16-btn").style.color = "red";
8554$("#16-btn").click(function(){
8555 if (!playingMid) {
8556 //MIDIjs.play('http://localhost:3000/midis/logan.mid');
8557 playingMid = true;
8558 document.getElementById("16-btn").style.color = "green";
8559 } else {
8560 //MIDIjs.stop();
8561 document.getElementById("16-btn").style.color = "red";
8562 playingMid = false;
8563 }
8564});
8565
8566//♥ button 17
8567$("body #bottom .relative").append('<div id="17-btn" class="ugly-button 17_btn" style="position: fixed;color: red;bottom: 2px;right: 305px;width: 10px"; title="Spin :3">♥</div>');
8568var spinning = false;
8569document.getElementById("17-btn").style.color = "red";
8570$("#17-btn").click(function(){
8571 if (spinning) {
8572 document.getElementById("17-btn").style.color = "red";
8573 $("#piano").removeClass("spin");
8574 spinning = false;
8575 } else {
8576 document.getElementById("17-btn").style.color = "green";
8577 $("#piano").addClass("spin");
8578 spinning = true;
8579 }
8580});
8581
8582//♥ button 18
8583$("body #bottom .relative").append('<div id="18-btn" class="ugly-button 18_btn" style="position: fixed;color: orange;bottom: 2px;right: 330px;width: 10px"; title="Bm">♥</div>');
8584$("#18-btn").click(function(){
8585 document.getElementById("18-btn").style.color = Col();
8586 MPP.press("b1", volume); MPP.press("fs2", volume); MPP.press("d2", volume); MPP.press("b2", volume); MPP.press("b-1", volume);
8587});
8588
8589//♥ button 19
8590$("body #bottom .relative").append('<div id="19-btn" class="ugly-button 19_btn" style="position: fixed;color: yellow;bottom: 2px;right: 355px;width: 10px"; title="B">♥</div>');
8591$("#19-btn").click(function(){
8592 document.getElementById("19-btn").style.color = Col();
8593 MPP.press("b1", volume); MPP.press("fs2", volume); MPP.press("ds2", volume); MPP.press("b2", volume); MPP.press("b-1", volume);
8594});
8595
8596//♥ button 20
8597$("body #bottom .relative").append('<div id="20-btn" class="ugly-button 20_btn" style="position: fixed;color: green;bottom: 2px;right: 380px;width: 10px"; title="F#7(3rd inv)">♥</div>');
8598$("#20-btn").click(function(){
8599 document.getElementById("20-btn").style.color = Col();
8600 MPP.press("cs2", volume); MPP.press("e2", volume); MPP.press("as2", volume); MPP.press("fs0", volume);
8601});
8602
8603//♥ button 21
8604$("body #bottom .relative").append('<div id="21-btn" class="ugly-button 21_btn" style="position: fixed;color: blue;bottom: 2px;right: 405px;width: 10px"; title="C#m">♥</div>');
8605$("#21-btn").click(function(){
8606 document.getElementById("21-btn").style.color = Col();
8607 MPP.press("cs2", volume); MPP.press("e2", volume); MPP.press("gs2", volume); MPP.press("cs0", volume);
8608});
8609
8610//♥ button 22
8611$("body #bottom .relative").append('<div id="22-btn" class="ugly-button 22_btn" style="position: fixed;color: indigo;bottom: 2px;right: 430px;width: 10px"; title="Csus(#4 #5)">♥</div>');
8612$("#22-btn").click(function(){
8613 document.getElementById("22-btn").style.color = Col();
8614 MPP.press("c2", volume); MPP.press("fs2", volume); MPP.press("gs2", volume);
8615});
8616
8617//♥ button 23
8618$("body #bottom .relative").append('<div id="23-btn" class="ugly-button 23_btn" style="position: fixed;color: violet;bottom: 2px;right: 455px;width: 10px"; title="E(2nd inv)">♥</div>');
8619$("#23-btn").click(function(){
8620 document.getElementById("23-btn").style.color = Col();
8621 MPP.press("b1", volume); MPP.press("e2", volume); MPP.press("gs2", volume);
8622});
8623
8624//♥ button 24
8625$("body #bottom .relative").append('<div id="24-btn" class="ugly-button 24_btn" style="position: fixed;bottom: 28px;right: 1072px;width: 10px"; title="cmd symbol">!</div>');
8626$("#24-btn").click(function(){
8627 setCmdChar();
8628 updateCmdChar(cmdChar);
8629
8630});
8631
8632// le label
8633$("body").append('<div id="resource-label" style="position: fixed; bottom: 529px; right: 17px;">Resource Monitor</div>');
8634
8635// thanks http://stackoverflow.com/users/165737/anurag
8636$("body #resource-label").css("fontSize", "11px");
8637
8638console.log(window.performance.now() - startUpDelay);
8639//END OF SCRIPT// //END OF SCRIPT// //END OF SCRIPT// //END OF SCRIPT// //END OF SCRIPT// //END OF SCRIPT/