diff --git a/.gitignore b/.gitignore
index 693710211..84e9b6650 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,3 +35,4 @@ build/Release
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules
test/auth.json
+examples/auth.json
diff --git a/.npmignore b/.npmignore
new file mode 100644
index 000000000..d7d6c67e1
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,5 @@
+.vscode/
+docs/
+examples/
+web-dist/
+.travis.yml
\ No newline at end of file
diff --git a/.settings/settings.json b/.vscode/settings.json
similarity index 71%
rename from .settings/settings.json
rename to .vscode/settings.json
index 20af2f68a..81c4b4351 100644
--- a/.settings/settings.json
+++ b/.vscode/settings.json
@@ -1,3 +1,2 @@
// Place your settings in this file to overwrite default and user settings.
-{
-}
\ No newline at end of file
+{ "editor.wrappingColumn": 0 }
\ No newline at end of file
diff --git a/.settings/tasks.json b/.vscode/tasks.json
similarity index 99%
rename from .settings/tasks.json
rename to .vscode/tasks.json
index 95c321163..7606560da 100644
--- a/.settings/tasks.json
+++ b/.vscode/tasks.json
@@ -19,7 +19,7 @@
"isBuildCommand": true,
"isWatching": true,
"args": [
- "src", "--out-dir", "lib", "-w"
+ "src", "--out-dir", "lib", "-w", "--loose=all"
]
}
]
diff --git a/README.md b/README.md
index c0a68bdaa..8521d3207 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,17 @@
-# discord.js
+
+
+
+
+
-[](https://travis-ci.org/hydrabolt/discord.js)
+[](https://travis-ci.org/hydrabolt/discord.js) [](http://discordjs.readthedocs.org/en/latest/?badge=latest)
+
discord.js is a node module used as a way of interfacing with
[Discord](https://discordapp.com/). It is a very useful module for creating
bots.
-**Updating to 3.1.1 is essential as it has new changes to be compatible with Discord's API,
-and to make sure your application still works an update is a good idea.**
+**The examples in the repo are in ES6, either update your node or compile them down to babel yourself if you want to use them!**
### Installation
`npm install --save discord.js`
@@ -31,6 +35,33 @@ mybot.login("email", "password");
```
---
+### What's new in 3.9.0?
+
+Amongst some fixes to web distribution creation, you can now opt for easier string formatting! However, it does modify String globally so you'll have to run:
+
+```js
+Discord.patchStrings()
+```
+
+After you have run this, you can do:
+```
+
+"message".bold.underline.italic
+// generates "*__**message**__*"
+
+```
+
+A full list of modifiers (all chainable):
+
+* bold `**`
+* italic `*`
+* underline `__`
+* strike `~`
+* code ` ` `
+* codeblock` ``` `
+
+---
+
### Related Projects
Here is a list of other Discord APIs:
@@ -42,7 +73,7 @@ Here is a list of other Discord APIs:
[DiscordSharp](https://github.com/Luigifan/DiscordSharp)
#### NodeJS
-[node-discord](https://github.com/izy521/node-discord) (similar to discord.js but lower level)
+[discord.io](https://github.com/izy521/node-discord) (similar to discord.js but lower level)
#### PHP
[DiscordPHP](https://github.com/teamreflex/DiscordPHP)
@@ -55,42 +86,8 @@ Here is a list of other Discord APIs:
---
-### Changes in 3.1.4
-
-No, not π. But instead, pseduo-synchronous messaging was added! This means that
-you can tell your Client to make a queue of "actions" per channel, and it will
-work through them one by one. This is a really useful tool if you need to send
-messages in a specific order without callback hell.
-
-It also allows you to store responses - such as created messages - in the returned
-promise - named action. Example:
-
-```js
-var mybot = new Discord.Client({
- queue : true //enable queueing, disabled by default
-});
-
-mybot.on("message", function(msg){
-
- mybot.sendMessage(msg.channel, "this is message 1");
- var action = mybot.sendMessage(msg.channel, "this is message 2");
- mybot.sendMessage(msg.channel, "this is message 3").then(rmv);
-
- function rmv(){
- if(!action.error){
- mybot.deleteMessage(action.message);
- }
- }
-
-});
-```
-
-This is still in development, and will see many more enhancements in future.
-
----
-
### Links
-**[Documentation](https://github.com/discord-js/discord.js/wiki/Documentation)**
+**[Documentation](http://discordjs.readthedocs.org/en/latest/)**
**[GitHub](https://github.com/discord-js/discord.js)**
@@ -104,5 +101,8 @@ This is still in development, and will see many more enhancements in future.
### Contact
-If you would like to contact me, you can create an issue on the GitHub repo
-or send a DM to **hydrabolt** in [Discord API](https://discord.gg/0SBTUU1wZTYd2XyW).
+If you have an issue or want to know if a feature exists, [read the documentation](http://discordjs.readthedocs.org/en/latest/) before contacting me about any issues! If it's badly/wrongly implemented, let me know!
+
+
+If you would like to contact me, you can create an issue on the GitHub repo, e-mail me via the one available on my NPM profile.
+Or you could just send a DM to **hydrabolt** in [**Discord API**](https://discord.gg/0SBTUU1wZTYd2XyW).
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 000000000..751136e57
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,192 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = _build
+
+# User-friendly check for sphinx-build
+ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
+$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
+endif
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext
+
+help:
+ @echo "Please use \`make ' where is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " applehelp to make an Apple Help Book"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " texinfo to make Texinfo files"
+ @echo " info to make Texinfo files and run them through makeinfo"
+ @echo " gettext to make PO message catalogs"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " xml to make Docutils-native XML files"
+ @echo " pseudoxml to make pseudoxml-XML files for display purposes"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+ @echo " coverage to run coverage check of the documentation (if enabled)"
+
+clean:
+ rm -rf $(BUILDDIR)/*
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/discordjs.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/discordjs.qhc"
+
+applehelp:
+ $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
+ @echo
+ @echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
+ @echo "N.B. You won't be able to view it unless you put it in" \
+ "~/Library/Documentation/Help or install it in your application" \
+ "bundle."
+
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/discordjs"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/discordjs"
+ @echo "# devhelp"
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+latexpdfja:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through platex and dvipdfmx..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo
+ @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+ @echo "Run \`make' in that directory to run these through makeinfo" \
+ "(use \`make info' here to do that automatically)."
+
+info:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo "Running Texinfo files through makeinfo..."
+ make -C $(BUILDDIR)/texinfo info
+ @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+ $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+ @echo
+ @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
+
+coverage:
+ $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
+ @echo "Testing of coverage in the sources finished, look at the " \
+ "results in $(BUILDDIR)/coverage/python.txt."
+
+xml:
+ $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
+ @echo
+ @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
+
+pseudoxml:
+ $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
+ @echo
+ @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 000000000..6ce076bcb
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,284 @@
+# -*- coding: utf-8 -*-
+#
+# discord.js documentation build configuration file, created by
+# sphinx-quickstart on Fri Sep 25 17:25:49 2015.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys
+import os
+import shlex
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = []
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix(es) of source filenames.
+# You can specify multiple suffix as a list of string:
+# source_suffix = ['.rst', '.md']
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'discord.js'
+copyright = u'2015, hydrabolt'
+author = u'hydrabolt'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '3.6'
+# The full version, including alpha/beta/rc tags.
+release = '3.6.1'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+#keep_warnings = False
+
+# If true, `todo` and `todoList` produce output, else they produce nothing.
+todo_include_todos = False
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# " v documentation".
+#html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+#html_extra_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Language to be used for generating the HTML full-text search index.
+# Sphinx supports the following languages:
+# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
+# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
+#html_search_language = 'en'
+
+# A dictionary with options for the search language support, empty by default.
+# Now only 'ja' uses this config value
+#html_search_options = {'type': 'default'}
+
+# The name of a javascript file (relative to the configuration directory) that
+# implements a search results scorer. If empty, the default will be used.
+#html_search_scorer = 'scorer.js'
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'discordjsdoc'
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+
+# Latex figure (float) alignment
+#'figure_align': 'htbp',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+latex_documents = [
+ (master_doc, 'discordjs.tex', u'discord.js Documentation',
+ u'hydrabolt', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ (master_doc, 'discordjs', u'discord.js Documentation',
+ [author], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ (master_doc, 'discordjs', u'discord.js Documentation',
+ author, 'discordjs', 'One line description of project.',
+ 'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+#texinfo_no_detailmenu = False
diff --git a/docs/create_simple_bot.rst b/docs/create_simple_bot.rst
new file mode 100644
index 000000000..f1115cd12
--- /dev/null
+++ b/docs/create_simple_bot.rst
@@ -0,0 +1,132 @@
+Creating a Simple Bot
+=====================
+
+This page will walk you through writing a simple bot and will introduce you to some of the most important functions and objects you will encounter in the API.
+
+Setting up a Project
+--------------------
+
+Before you start creating your bot, you need to create a directory, for example *discordbot*.
+
+After you've done that, open up the directory and have a look at how to `install the module`_. After you've installed the module, you can progress to the next step
+
+Creating the Bot
+----------------
+
+Now we can begin writing the bot. This bot will just server the user their avatar but at a higher resolution - assuming they have one.
+
+Firstly, create a file named ``bot.js`` in the directory you made earlier. Open it up, and type the following lines of code:
+
+.. code-block:: js
+
+ var Discord = require("discord.js");
+ var bot = new Discord.Client();
+
+This code firstly imports the discord.js module, which contains classes to help you create clients for Discord. The second line creates a new Discord Client, which we can manipulate later. Now, we want the client to be alerted when there is a new message and do something, so we can type this:
+
+.. code-block:: js
+
+ bot.on("message", function(message){
+
+ } )
+
+This will simply get our client to listen out for new messages, but not yet do anything. Let's have a look at this:
+
+.. code-block:: js
+
+ bot.on("message", function(message){
+
+ if( message.content === "avatar me!" ){
+
+ }
+
+ } )
+
+This code will now get our client to execute anything inside the if statement as long as the message sent was "avatar me!" We can now get it to see if the user has an avatar:
+
+.. code-block:: js
+
+ bot.on("message", function(message){
+
+ if( message.content === "avatar me!" ){
+
+ var usersAvatar = message.sender.avatarURL;
+
+ if(usersAvatar){
+ // user has an avatar
+ }else{
+ // user doesn't have an avatar
+ }
+
+ }
+
+ } )
+
+This code will now see if the user has an avatar and then do something based on that, let's finalise it:
+
+.. code-block:: js
+
+ bot.on("message", function(message){
+
+ if( message.content === "avatar me!" ){
+
+ var usersAvatar = message.sender.avatarURL;
+
+ if(usersAvatar){
+ // user has an avatar
+
+ bot.reply(message, "your avatar can be found at " + usersAvatar);
+
+ }else{
+ // user doesn't have an avatar
+
+ bot.reply(message, "you don't have an avatar!");
+ }
+
+ }
+
+ } )
+
+Let's have a look at the function we used here; *bot.reply*. This function takes 2 necessary parameters, a message object to reply to and a message to send. The first parameter we already have, and it is the message we have received. The second parameter is what we want to send.
+
+Now that we've finished the listener event, we need to log the client in:
+
+.. code-block:: js
+
+ bot.login("your discord email", "your discord password");
+
+And that's it! Run the code with ``node bot.js`` and wait a few seconds, and then try sending *avatar me!* to any of the channels that the user you provided has details to.
+
+Final Product
+-------------
+.. code-block:: js
+
+ var Discord = require("discord.js");
+ var bot = new Discord.Client();
+
+ bot.on("message", function(message){
+
+ if( message.content === "avatar me!" ){
+
+ var usersAvatar = message.sender.avatarURL;
+
+ if(usersAvatar){
+ // user has an avatar
+
+ bot.reply(message, "your avatar can be found at " + usersAvatar);
+
+ }else{
+ // user doesn't have an avatar
+
+ bot.reply(message, "you don't have an avatar!");
+ }
+
+ }
+
+ } );
+
+ bot.login("your discord email", "your discord password");
+
+.. note:: This page is still a WIP, check back later for more documentation on it.
+
+.. _install the module : http://discordjs.readthedocs.org/en/latest/get_started.html#installation
\ No newline at end of file
diff --git a/docs/docs_channel.rst b/docs/docs_channel.rst
new file mode 100644
index 000000000..063fb0790
--- /dev/null
+++ b/docs/docs_channel.rst
@@ -0,0 +1,75 @@
+.. include:: ./vars.rst
+
+Channel Documentation
+=====================
+
+The Channel Class is used to represent data about a Channel.
+
+Attributes
+----------
+
+client
+~~~~~~
+
+The Discord Client_ that cached the channel
+
+server
+~~~~~~
+
+The Server_ that the channel belongs to
+
+name
+~~~~
+
+The channel's name, as a `String`.
+
+id
+~~
+
+The channel's id, as a `String`.
+
+type
+~~~~
+
+The type of the channel as a `String`, either ``text`` or ``voice``.
+
+topic
+~~~~~
+
+A `String` that is the topic of the channel, if the channel doesn't have a topic this will be `null`.
+
+messages
+~~~~~~~~
+
+An `Array` of Message_ objects received from the channel. There are up to a 1000 messages here, and the older messages will be deleted if necessary.
+
+members
+~~~~~~~
+
+**Aliases** : `users`
+
+The members in the channel's server, an `Array` of User_ objects.
+
+-----
+
+Functions
+---------
+
+.. note:: When concatenated with a String, the object will become the channel's embed code, e.g. ``"this is " + channel`` would be ``this is <#channelid>``
+
+getMessage(key, value)
+~~~~~~~~~~~~~~~~~~~~~~
+
+Gets a Message_ from the channel that matches the specified criteria. E.g:
+
+.. code-block:: js
+
+ channel.getMessage("id", 1243987349) // returns a Message where message.id === 1243987349
+
+- **key** - a `String` that is the key
+- **value** - a `String` that is the value
+
+equals(object)
+~~~~~~~~~~~~~~
+
+Returns a `Boolean` depending on whether the Channel's ID (``channel.id``) equals the object's ID (``object.id``). You should **always**, always use this if you want to compare channels. **NEVER** do ``channel1 == channel2``.
diff --git a/docs/docs_client.rst b/docs/docs_client.rst
new file mode 100644
index 000000000..cb5ed2bab
--- /dev/null
+++ b/docs/docs_client.rst
@@ -0,0 +1,610 @@
+.. include:: ./vars.rst
+
+Client Documentation
+====================
+
+This page contains documentation on the `Discord.Client` class. This should be used when you want to start creating things with the API.
+
+It might be beneficial to use CTRL+F to search for what you're looking for, or use the navigation provided by readthedocs on the left.
+
+Attributes
+----------
+
+options
+~~~~~~~
+An `Object` containing a configuration for the Client. Currently can only be configured like so:
+
+.. code-block:: js
+
+ {
+ queue : false // whether messages should be sent one after the other or
+ // just send straight away.
+ }
+
+token
+~~~~~
+A `String` that is the token received after logging in. It is used to authorise the Client when joining WebSockets or making HTTP requests. Example token:
+
+.. code-block:: js
+
+ ODAzTOc4MTA2BjQ2MjY4ODg.COmrCA.fEtD_Tc0JU6iZJU_11coEWBOQHE
+
+state
+~~~~~
+An `Integer` representing what state of connection the Client is in.
+
+- **0** is idle, meaning the Client has been created but no login attempts have been made.
+- **1** is logging in, meaning the Client is in the process of logging in.
+- **2** is logged in, meaning the Client is logged in but not necessarily ready.
+- **3** is ready, meaning the Client is ready to begin listening.
+- **4** is disconnected, meaning the Client was disconnected due to any reason.
+
+See also ready_.
+
+.. code-block:: js
+
+ if( bot.state === 3 ) // ready to go
+
+user
+~~~~
+A `User`_ object representing the account of the signed in client. This will only be available when the client is in the ready state (3).
+
+.. code-block:: js
+
+ bot.user.username; // username of the account logged in
+
+email
+~~~~~
+A `String` that is the email used to sign the client in.
+
+password
+~~~~~~~~
+A `String` that is the password used to sign the client in.
+
+readyTime
+~~~~~~~~~
+A `Number` representing the unix timestamp from when the client was ready. `Null` if not yet ready.
+
+.. code-block:: js
+
+ bot.readyTime; // 1443378242464
+
+uptime
+~~~~~~
+A `Number` representing how many milliseconds have passed since the client was ready. `Null` if not yet ready.
+
+.. code-block:: js
+
+ if( bot.uptime > 5000 ) // true if the client has been up for more than 5 seconds
+
+ready
+~~~~~
+A `Boolean` that is true if the client is ready. A shortcut to checking if ``bot.state === 3``.
+
+servers
+~~~~~~~
+An `Array` of Server_ objects that the client has access to.
+
+channels
+~~~~~~~~
+An `Array` of Channel_ objects that the client has access to.
+
+users
+~~~~~
+An `Array` of User_ objects that the client has access to.
+
+PMChannels
+~~~~~~~~~~
+An `Array` of PMChannel_ objects the client has access to.
+
+messages
+~~~~~~~~
+An `Array` of Message_ objects the client has received over its uptime.
+
+Functions
+---------
+
+.. note :: Any functions used here that take callbacks as an optional parameter can also be used as Promises_. Promises take the exact same parameters for each use case, except errors are moved to catch statements instead of then. For example, you can do:
+
+.. code-block:: js
+
+ bot.login(email, password).then(success).catch(err);
+
+ function success(token){
+
+ }
+
+ function err(error){
+
+ }
+
+ // OR use callbacks:
+
+ bot.login(email, password, function(error, token){
+
+ });
+
+-----
+
+login(email, password, `callback`)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Logs the client in to set it up. Use this after registering your event listeners to ensure they are called.
+
+- **email** - A `String` which is the email you want to sign in with.
+- **password** - A `String` which is the password you want to sign in with.
+- **callback** - A `function` that can take the following parameters:
+
+ - **error** - An error if one occurred, otherwise it is null.
+ - **token** - if successful, it is the received authorisation token.
+
+logout(`callback`)
+~~~~~~~~~~~~~~~~~~
+
+Logs the client out if it is logged in. If successful, ``bot.state == 4``.
+
+- **callback** - A `function` that can take the following parameters:
+
+ - **error** - An error if one occurred, otherwise it is null.
+
+createServer(name, region, `callback`)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Creates a server with the specified name or region. See valid regions below:
+
+- **name** - A `String` that will be the name of your server.
+- **region** - A `String` that is a valid Discord region. Currently **us-west**, **us-east**, **singapore**, **london**, **sydney** or **amsterdam**. Providing an invalid region will result in an error. To find the latest available regions, check the `official API here`_.
+- **callback** - A `function` that can take the following parameters:
+
+ - **error** - An error if one occurred, otherwise it is null.
+ - **server** - A Server_ that represents the created Server.
+
+joinServer(invite, `callback`)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Accepts a given invite to join a server. The server is automatically cached ASAP.
+
+- **invite** - An `Invite Resolvable`_ which is the invite that should be accepted.
+- **callback** - A `function` that can take the following parameters:
+
+ - **error** - An error if one occurred, otherwise it is null.
+ - **server** - A Server_ that represents the joined Server.
+
+leaveServer(server, `callback`)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Leaves the given server.
+
+- **server** - A `Server Resolvable`_ that represents the server you want to leave.
+- **callback** - A `function` that can take the following parameters:
+
+ - **error** - An error if one occurred, otherwise it is null.
+
+createInvite(channel, options, `callback`)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Creates an invite for the given channel and returns an Invite_.
+
+- **channel** - A `Channel Resolvable`_ that is the channel you want to create an invite for.
+- **options** - An `object` containing configurable options for the invite. See below for possible configurations.
+- **callback** - A `function` that can take the following parameters:
+
+ - **error** - An error if one occurred, otherwise it is null.
+ - **invite** - An Invite_ object that contains the details about the created invite.
+
+.. code-block:: js
+
+ // default configuration of the options variable:
+
+ options = {
+ max_age : 0, //A number signifying the expiry time for the invite. 0 means infinite.
+ max_uses : 0, //A number signifying the amount of uses of the invite. 0 means infinite.
+ temporary : false, //boolean - whether users who use it are kicked unless promoted within 24h.
+ xkcd : false //boolean - whether the invite's URL should be human-readable
+ }
+
+createChannel(server, channelName, channelType, `callback`)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Creates a channel in the given server.
+
+- **server** - A `Server Resolvable`_ that will be the server the channel is created in.
+- **channelName** - A `String` that is the name of the channel.
+- **channelType** - A `String` that is the type of the channel, either **voice** or **text**.
+- **callback** - A `function` that can take the following parameters:
+
+ - **error** - An error if one occurred, otherwise it is null.
+ - **channel** - An Channel_ object that represents the created channel.
+
+deleteChannel(channel, `callback`)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Deletes the specified channel.
+
+- **channel** - A `Channel Resolvable`_ that will be the channel to delete.
+- **callback** - A `function` that can take the following parameters:
+
+ - **error** - An error if one occurred, otherwise it is null.
+
+getChannelLogs(channel, `amount`, `callback`)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Gets previous messages from the specified channel.
+
+- **channel** - A `Channel Resolvable`_ to take logs from.
+- **amount** - A `Number` that defaults to **500**. This is the amount of messages to try and get.
+- **callback** - A `function` that can take the following parameters:
+
+ - **error** - An error if one occurred, otherwise it is null.
+ - **logs** - An `Array` of Message_ objects that represent the previous messages.
+
+.. warning:: If the logs contain messages from a user who is no longer in the server, the user object *MAY* be malformed.
+
+sendMessage(channel, message, `callback`)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Sends a message to the specified channel.
+
+- **channel** - A `Channel Resolvable`_ to send the message to.
+- **message** - A `String` or an Array of strings. If an Array, the array will be joined with a new line as a delimiter and this will be the message to be sent.
+- **callback** - A `function` that can take the following parameters:
+
+ - **error** - An error if one occurred, otherwise it is null.
+ - **message** - A Message_ representing the sent message.
+
+sendFile(channel, file, `fileName`, `callback`)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Sends a file to the specified channel. Note that **fileName is necessary in certain cases** for when a file other than an image is sent. For example, if you send a file containing JS code, fileName should be something like ``myCode.js``.
+
+- **channel** - A `Channel Resolvable`_ to send the file to.
+- **file** - The file to send, either a `Buffer` or `String` - if a String, it should be a relative (`./`) or absolute path to a file.
+- **fileName** - A `String` containing the file's name and extension, used by Discord (I didn't make this please don't shoot me :s) Examples include `picture.png`, `text.txt`, `wowanamazingscript.js`
+
+- **callback** - A `function` that can take the following parameters:
+
+ - **error** - An error if one occurred, otherwise it is null.
+ - **message** - A Message_ representing the sent file.
+
+updateMessage(message, content, `callback`)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Updates/edits a message with new content.
+
+- **message** - A Message_ that should be updated.
+- **content** - A `String` or an Array of strings. If an Array, the array will be joined with a new line as a delimiter and this will be the message to be sent.
+- **callback** - A `function` that can take the following parameters:
+
+ - **error** - An error if one occurred, otherwise it is null.
+ - **message** - A Message_ representing the updated message.
+
+reply(message, yourMessage, `callback`)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Alias for sendMessage, but prepends a mention to whoever sent the specified mention. Useful shortcut for directing a message at a user.
+
+.. code-block:: js
+
+ // example usage:
+
+ the user 'bob' sent a message
+
+ bot.reply(message, "hello");
+ // will send the message '@bob, hello' to the channel the message that bob sent was in.
+
+- **message** - A Message_ that should be replied to.
+- **yourMessage** - A `String` or an Array of strings. If an Array, the array will be joined with a new line as a delimiter and this will be the message to be sent.
+- **callback** - A `function` that can take the following parameters:
+
+ - **error** - An error if one occurred, otherwise it is null.
+ - **message** - A Message_ representing the sent message.
+
+setUsername(newName, `callback`)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Sets the username of the logged in client.
+
+- **newName** - The new name of the client, a `String`.
+- **callback** - A `function` that can take the following parameters:
+
+ - **error** - An error if one occurred, otherwise it is null.
+
+startTyping(channel, *stopTime*)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Makes the client appear to be typing in the specified channel.
+
+- **channel** - A `Channel Resolvable`_ that should be the channel to start typing in
+- **stopTime** - A `Number` in ms which should make the client stop typing after. Allow 5 seconds.
+
+stopTyping(channel)
+~~~~~~~~~~~~~~~~~~~
+
+Makes the client stop typing in a specified channel.
+
+- **channel** - A `Channel Resolvable`_ that should be the channel to stop typing in.
+
+setStatusOnline()
+~~~~~~~~~~~~~~~~~
+
+**Aliases**: ``setStatusActive()`` and ``setStatusHere()``
+
+Sets the client's status to online; green.
+
+setStatusIdle()
+~~~~~~~~~~~~~~~~~
+
+**Aliases**: ``setStatusAway()``
+
+Sets the client's status to idle; orange.
+
+setTopic(channel, topic, `callback`)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Sets the topic of the specified channel
+
+- **channel** - A `Channel Resolvable`_ that is the channel you want to change the topic of
+- **topic** - A `String` that is the topic you want
+- **callback** - A `function` that can take the following parameters:
+
+ - **error** - An error if one occurred, otherwise it is null.
+
+getUser(key, value)
+~~~~~~~~~~~~~~~~~~~
+
+Gets a User_ that matches the specified criteria. E.g:
+
+.. code-block:: js
+
+ bot.getUser("id", 1243987349) // returns a user where user.id === 1243987349
+
+- **key** - a `String` that is the key
+- **value** - a `String` that is the value
+
+getServer(key, value)
+~~~~~~~~~~~~~~~~~~~~~
+
+Gets a Server_ that matches the specified criteria. E.g:
+
+.. code-block:: js
+
+ bot.getServer("id", 1243987349) // returns a server where server.id === 1243987349
+
+- **key** - a `String` that is the key
+- **value** - a `String` that is the value
+
+
+getChannel(key, value)
+~~~~~~~~~~~~~~~~~~~~~~
+
+Gets a Channel_ that matches the specified criteria. E.g:
+
+.. code-block:: js
+
+ bot.getChannel("id", 1243987349) // returns a Channel where channel.id === 1243987349
+
+- **key** - a `String` that is the key
+- **value** - a `String` that is the value
+
+
+getPMChannel(key, value)
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Gets a PMChannel_ that matches the specified criteria. E.g:
+
+.. code-block:: js
+
+ bot.getPMChannel("id", 1243987349) // returns a PMChannel where pmchannel.id === 1243987349
+
+- **key** - a `String` that is the key
+- **value** - a `String` that is the value
+
+setPlayingGame(id)
+~~~~~~~~~~~~~~~~~~
+
+**Aliases** : `playGame`, `playingGame`
+
+Sets the client as playing the specified game name/id.
+
+- **id** - Either a `Number` or a `String`. If it's a Number, it's assumed that you are using a `Discord Game ID`_ and know what you want. If you supply a `String`, it will assume you are entering a game name and try resolving it to a Discord Game ID if it's available. Example:
+
+.. code-block:: js
+
+ client.setPlayingGame(18);
+ // sets the client as playing Minecraft, game ID 18
+
+ client.setPlayingGame("Minecraft");
+ // sets the client as playing Minecraft by resolving the ID to 18
+
+ client.setPlayingGame("my magical made up game")
+ // will stop the client from playing anything as it is unresolved, not a valid game.
+
+-----
+
+Event Management
+----------------
+
+Events are a useful way of listening to events and are available in every API.
+
+Registering Events
+~~~~~~~~~~~~~~~~~~
+
+.. code-block:: js
+
+ bot.on("eventName", function(arg1, arg2...){
+ // code here is called when eventName is emitted.
+ })
+
+.. note:: You can only have one listening function per event
+
+Unregistering Events
+~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: js
+
+ bot.off("eventName")
+ // eventName is no longer listened for
+
+Event Types
+-----------
+
+ready
+~~~~~
+
+Called when the bot is ready and you can begin working with it.
+
+disconnected
+~~~~~~~~~~~~
+
+Called when the bot is disconnected for whatever reason.
+
+error
+~~~~~
+
+Called whenever there is an error.
+
+**Parameters**
+
+- **error** - the encountered error
+
+.. note:: There may be more parameters supplied depending on the errors. Use the ``arguments`` variable to check for this for advanced debugging.
+
+debug
+~~~~~
+
+Called when the client debugs some information that might be useful for a developer but not for an end user.
+
+**Parameters**
+
+- **message** - the debug message as a `String`
+
+message
+~~~~~~~
+
+Called when a message has been received by the client.
+
+**Parameters**
+
+- **message** - the received Message_.
+
+messageDelete
+~~~~~~~~~~~~~
+
+Called when a message has been deleted.
+
+**Parameters**
+
+- **channel** - The Channel_ that the deleted message was in.
+- **message** - *May* be available. If the message wasn't previously cached, this will not be supplied and all you would know is that a message was deleted in the channel. If it is available, it will be in the format of a Message_.
+
+messageUpdate
+~~~~~~~~~~~~~
+
+Called when a message has been updated.
+
+**Parameters**
+
+- **newMessage** - The updated Message_.
+- **oldMessage** - The old Message_ before it was updated.
+
+serverDelete
+~~~~~~~~~~~~
+
+Called when a server is deleted.
+
+**Parameters**
+
+- **server** - The deleted Server_.
+
+channelDelete
+~~~~~~~~~~~~~
+
+Called when a channel is deleted.
+
+**Parameters**
+
+- **channel** - The deleted Channel_.
+
+serverCreate
+~~~~~~~~~~~~
+
+Called when a server is created/joined.
+
+**Parameters**
+
+- **server** - The created Server_.
+
+channelCreate
+~~~~~~~~~~~~
+
+Called when a channel is created.
+
+**Parameters**
+
+- **channel** - The created Channel_.
+
+serverNewMember
+~~~~~~~~~~~~~~~
+
+Called when a new member is added to a server.
+
+**Parameters**
+
+- **user** - The User_ that was added.
+- **server** - The Server_ that the user was added to.
+
+serverRemoveMember
+~~~~~~~~~~~~~~~~~~
+
+Called when a member of a server leaves or is kicked out.
+
+**Parameters**
+
+- **user** - The User_ that was removed.
+- **server** - The Server_ that the user was removed from.
+
+userUpdate
+~~~~~~~~~~
+
+Called when information about a user changes, such as their username.
+
+**Parameters**
+
+- **newUser** - A User_ object representing the changes to the old user (this will be in the cache)
+- **oldUser** - A User_ object representing the user before the update.
+
+presence
+~~~~~~~~
+
+Called when a user goes online/offline/away or starts/stops playing a game.
+
+**Parameters**
+
+- **dataObject** - Instead of separate arguments, presence update takes an object containing the following information:
+
+ - **user** - A User_ representing the User that had a presence update
+ - **status** - The status change as a `String`.
+ - **server** - The Server_ that the presence change occurred in.
+ - **gameId** - A `Number` representing the game they are playing if any. Currently, discord.js has no internal support for converting this into a game name.
+
+unknown
+~~~~~~~
+
+Called when an unknown packet was received or there is no handler for it.
+
+**Parameters**
+
+- **data** - A `JSON Object` which is the message received over WebSocket.
+
+raw
+~~~
+
+Called when a WebSocket message is received and it gives you the message.
+
+**Parameters**
+
+- **data** - A `JSON Object` which is the message received over WebSocket.
+
+.. _official API here : https://discordapp.com/api/voice/regions
+
+.. _Discord Game ID : https://raw.githubusercontent.com/hydrabolt/discord.js/master/ref/gameMap.json
\ No newline at end of file
diff --git a/docs/docs_invite.rst b/docs/docs_invite.rst
new file mode 100644
index 000000000..4c1688b1e
--- /dev/null
+++ b/docs/docs_invite.rst
@@ -0,0 +1,64 @@
+.. include:: ./vars.rst
+
+Invite Documentation
+====================
+
+The Invite Class is used to represent data about an Invite.
+
+Attributes
+----------
+
+max_age
+~~~~~~~
+
+A `Number` in minutes for how long the Invite should be valid for. E.g. a value of ``3600`` is equal to 30 minutes.
+
+code
+~~~~
+
+`String` an alphanumeric code for the Invite.
+
+revoked
+~~~~~~~
+
+`Boolean` that dictates whether the Invite has been cancelled or not
+
+created_at
+~~~~~~~~~~
+
+A unix timestamp as a `Number` which is the time that the invite was created.
+
+temporary
+~~~~~~~~~
+
+`Boolean` that dictates whether the invite is temporary.
+
+uses
+~~~~
+
+`Number` the number of uses of the Invite, a value of ``0`` is none.
+
+max_uses
+~~~~~~~~
+
+`Number` that is the maximum amount of uses of the invite, ``0`` is unlimited.
+
+inviter
+~~~~~~~
+
+The User_ that created the invite.
+
+xkcd
+~~~~
+
+`Boolean` that is true if the invite should be human-readable.
+
+channel
+~~~~~~~
+
+The Channel_ that the invite is inviting to.
+
+URL
+~~~
+
+A `String` that generates a clickable link to the invite.
\ No newline at end of file
diff --git a/docs/docs_message.rst b/docs/docs_message.rst
new file mode 100644
index 000000000..7dbbbfc3d
--- /dev/null
+++ b/docs/docs_message.rst
@@ -0,0 +1,84 @@
+.. include:: ./vars.rst
+
+Message Documentation
+=====================
+
+The Message Class is used to represent data about a Message.
+
+Attributes
+----------
+
+tts
+~~~
+
+A `Boolean` that is ``true`` if the sent message was text-to-speech, otherwise ``false``.
+
+timestamp
+~~~~~~~~~
+
+A `unix timestamp` as a `Number` representing when the message was sent.
+
+mentions
+~~~~~~~~
+
+An `Array` of User_ objects that represent the users mentioned in the message.
+
+everyoneMentioned
+~~~~~~~~~~~~~~~~~
+
+A `Boolean` that is ``true`` if **@everyone** was used, otherwise ``false``.
+
+id
+~~
+
+A `String` UUID of the message, will never change.
+
+.. note:: Currently, message IDs are totally unique. However, in the future they may only be unique within a channel. Make sure to check periodically whether this has changed.
+
+embeds
+~~~~~~
+
+A raw, unhandled `JSON object` that will contain embeds of the message - if any.
+
+editedTimestamp
+~~~~~~~~~~~~~~~
+
+A `unix timestamp` as a `Number` that is when the message was last edited.
+
+content
+~~~~~~~
+
+The actual content of the message as a `String`.
+
+channel
+~~~~~~~
+
+The Channel_ that the message was sent in.
+
+author
+~~~~~~
+
+**Aliases** : `sender`
+
+The User_ that sent the message.
+
+attachments
+~~~~~~~~~~~
+
+A raw, unhandled `JSON object` that will contain attachments of the message - if any.
+
+isPrivate
+~~~~~~~~~
+
+A `Boolean` that is ``true`` if the message was sent in a PM / DM chat, or if it was sent in a group chat it will be ``false``.
+
+Functions
+---------
+
+isMentioned(user)
+~~~~~~~~~~~~~~~~~
+
+A `Boolean` that will return ``true`` if the specified user was mentioned in the message. If everyone is mentioned, this will be false - this function checks specifically for if they were mentioned.
+
+
+- **user** - The User_ that you want to see is mentioned or not.
\ No newline at end of file
diff --git a/docs/docs_pmchannel.rst b/docs/docs_pmchannel.rst
new file mode 100644
index 000000000..3f10acec2
--- /dev/null
+++ b/docs/docs_pmchannel.rst
@@ -0,0 +1,41 @@
+.. include:: ./vars.rst
+
+PMChannel Documentation
+=======================
+
+The PMChannel Class is used to represent data about a Private Message Channel.
+
+.. note:: Beware! The PMChannel class does `not` extend the Channel_ class.
+
+Attributes
+----------
+
+user
+~~~~
+
+The recipient User_ of the PM Channel.
+
+id
+~~
+
+`String` UUID of the PM Channel.
+
+messages
+~~~~~~~~
+
+An `Array` of Message_ objects. Contains all the cached messages sent in this channel up to a limit of 1000. If the limit is reached, the oldest message is removed first to make space for it.
+
+Functions
+---------
+
+getMessage(key, value)
+~~~~~~~~~~~~~~~~~~~~~~
+
+Gets a Message_ from the PM Channel that matches the specified criteria. E.g:
+
+.. code-block:: js
+
+ pmchannel.getMessage("id", 1243987349) // returns a Message where message.id === 1243987349
+
+- **key** - a `String` that is the key
+- **value** - a `String` that is the value
\ No newline at end of file
diff --git a/docs/docs_resolvable.rst b/docs/docs_resolvable.rst
new file mode 100644
index 000000000..ebd1f2211
--- /dev/null
+++ b/docs/docs_resolvable.rst
@@ -0,0 +1,27 @@
+.. include:: ./vars.rst
+
+Resolvable Documentation
+========================
+
+To be robust, discord.js needs to handle a wide amount of ambiguous data that is supplied to it. This means you can use functions much more easily. Anything that is resolvable means it can be normalised without you having to do it explicitly.
+
+Resolvables are not objects or classes, they are just ways of expressing what type of data is expected.
+
+Channel Resolvable
+------------------
+
+A Channel Resolvable is data that can be resolved to a channel ID. Here is what is currently supported:
+
+- A Channel_ object
+- A Server_ object (the #general channel of the server will be used)
+- A `String` representing the channel ID
+- A Message_ (the channel the message was sent in will be used)
+- A User_ (will get the PM channel with the specified user)
+
+.. note:: A User cannot always be specified in certain cases. For example, if using `bot.setTopic`, a User or PM Channel can't be specified as these do not support channel topics.
+
+Server Resolvable
+-----------------
+
+Invite Resolvable
+-----------------
\ No newline at end of file
diff --git a/docs/docs_server.rst b/docs/docs_server.rst
new file mode 100644
index 000000000..0baa9d331
--- /dev/null
+++ b/docs/docs_server.rst
@@ -0,0 +1,107 @@
+.. include:: ./vars.rst
+
+Server Documentation
+==================
+
+The Server Class is used to represent data about a server.
+
+Attributes
+----------
+
+client
+~~~~~~
+
+The Discord Client_ that the Server was cached by.
+
+region
+~~~~~~
+
+The region that the server is in, a `String`.
+
+name
+~~~~
+
+The server's name, as a `String`.
+
+id
+~~
+
+The server's id, as a `String`.
+
+members
+~~~~~~~
+
+**Aliases** : `users`
+
+The members in a server, an `Array` of User_ objects.
+
+channels
+~~~~~~~~
+
+The channels in a server, an `Array` of Channel_ objects.
+
+icon
+~~~~
+
+The icon ID of the server if it has one as a `String`, otherwise it is `null`.
+
+iconURL
+~~~~~~~
+
+A `String` that is the URL of the server icon if it has one, otherwise it is `null`.
+
+afkTimeout
+~~~~~~~~~~
+
+A `Number` that is the AFK Timeout of the Server.
+
+afkChannel
+~~~~~~~~~~
+
+A Channel_ that represents the AFK Channel of the server if it has one, otherwise it is `null`.
+
+defaultChannel
+~~~~~~~~~~~~~~
+
+The **#general** Channel_ of the server.
+
+owner
+~~~~~
+
+A User_ object representing the user that owns the server.
+
+-----
+
+Functions
+---------
+
+.. note:: When concatenated with a String, the object will become the server's name, e.g. ``"this is " + server`` would be ``this is Discord API`` if the server was called `Discord API`.
+
+getChannel(key, value)
+~~~~~~~~~~~~~~~~~~~~~~
+
+Gets a Channel_ that matches the specified criteria. E.g:
+
+.. code-block:: js
+
+ server.getChannel("id", 1243987349) // returns a Channel where channel.id === 1243987349
+
+- **key** - a `String` that is the key
+- **value** - a `String` that is the value
+
+getMember(key, value)
+~~~~~~~~~~~~~~~~~~~~~
+
+Gets a User_ that matches the specified criteria. E.g:
+
+.. code-block:: js
+
+ bot.getUser("id", 1243987349) // returns a user where user.id === 1243987349
+
+- **key** - a `String` that is the key
+- **value** - a `String` that is the value
+
+equals(object)
+~~~~~~~~~~~~~~
+
+Returns a `Boolean` depending on whether the Server's ID (``server.id``) equals the object's ID (``object.id``). You should **always**, always use this if you want to compare servers. **NEVER** do ``server1 == server2``.
diff --git a/docs/docs_user.rst b/docs/docs_user.rst
new file mode 100644
index 000000000..70cf51b2d
--- /dev/null
+++ b/docs/docs_user.rst
@@ -0,0 +1,67 @@
+.. include:: ./vars.rst
+
+User Documentation
+==================
+
+The User Class is used to represent data about users.
+
+Attributes
+----------
+
+username
+~~~~~~~~
+
+A `String` that is the username of the user.
+
+discriminator
+~~~~~~~~~~~~~
+
+Used to differentiate users with the same username, provided by Discord. If you want to differentiate users, we'd recommend using the `id` attribute.
+
+id
+~~
+
+A `String` UUID of the user, will never change.
+
+avatar
+~~~~~~
+
+A `String` that is the user's avatar's ID, or if they don't have one this is `null`.
+
+avatarURL
+~~~~~~~~~
+
+A `String` that points to the user's avatar's URL, or if they don't have an avatar this is `null`.
+
+status
+~~~~~~
+
+The status of the user as a `String`; offline/online/idle.
+
+-----
+
+Functions
+---------
+
+mention()
+~~~~~~~~~
+
+Returns a `String`. This function will generate the mention string for the user, which when sent will preview as a mention. E.g:
+
+.. code-block:: js
+
+ user.mention(); // something like <@3245982345035>
+
+This is mainly used internally by the API to correct mentions when sending messages, however you can use it.
+
+.. note:: You can also just concatenate a User object with strings to get the mention code, as the `toString()` method points to this. This is useful when sending messages.
+
+equals(object)
+~~~~~~~~~~~~~~
+
+Returns a `Boolean` depending on whether the User's ID (``user.id``) equals the object's ID (``object.id``). You should **always**, always use this if you want to compare users. **NEVER** do ``user1 == user2``.
+
+equalsStrict(object)
+~~~~~~~~~~~~~~~~~~~~
+
+Sees if the supplied object has the same username, ID, avatar and discriminator of the user. Mainly used internally. Returns a `Boolean` depending on the result.
diff --git a/docs/get_started.rst b/docs/get_started.rst
new file mode 100644
index 000000000..96c7b1af6
--- /dev/null
+++ b/docs/get_started.rst
@@ -0,0 +1,37 @@
+===========
+Get Started
+===========
+
+Installation
+------------
+
+Linux / OS X
+~~~~~~~~~~~~
+Run ``npm install discord.js --save`` in your project's directory and you should be good to go!
+
+Windows
+~~~~~~~~~~~~
+Unfortunately, the Windows installation process is a little more lengthy. You need to have `Visual Studio Express`_ (or any of the other distributions of it). This is necessary for build tools for the WebSocket dependency.
+
+.. note:: If you are using another version of Visual Studio, such as 2012, replace the flag with ``--msvs_version=2012``
+
+After you have obtained these tools, you need to run ``npm install discord.js --save --msvs_version=2015`` in your working directory. Hopefully this should all go well!
+
+Cloning the Repo
+----------------
+If you want to try some examples or make your own changes to discord.js, you can `clone the repo`_. After that run ``npm install`` to install dependencies.
+
+Running Examples
+~~~~~~~~~~~~~~~~
+If you've cloned the repo, you also have the option to run some examples. You can also do this by just copying the examples_ and then running them. I'd be more than happy to get some pull requests if you want to make any patches ;)
+
+
+Before you run them though, you need to configure the ``examples/auth.json`` file. This should contain valid Discord credentials and passwords.
+
+After you've configured your credentials, just run ``node examples/pingpong.js`` to run the ping pong example.
+
+
+
+.. _Visual Studio Express: https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx
+.. _clone the repo: https://github.com/hydrabolt/discord.js.git
+.. _examples: https://github.com/hydrabolt/discord.js/tree/master/examples
\ No newline at end of file
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 000000000..34e8f71a9
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,49 @@
+.. discord.js documentation master file, created by
+ sphinx-quickstart on Fri Sep 25 17:25:49 2015.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+Welcome to discord.js's documentation!
+======================================
+
+discord.js is an easy-to-use and intuitive JavaScript API for Discord_. It should be able to
+run in node.js / io.js and in the browser.
+
+.. note:: This documentation is still a work-in-progress, apologies if something isn't yet documented!
+
+Contents:
+
+.. _general-docs:
+
+.. toctree::
+ :maxdepth: 2
+ :caption: General
+
+ get_started
+ troubleshooting
+ create_simple_bot
+
+.. _docs:
+
+.. toctree::
+ :maxdepth: 2
+ :caption: Documentation
+
+ docs_resolvable
+ docs_client
+ docs_user
+ docs_server
+ docs_channel
+ docs_pmchannel
+ docs_message
+ docs_invite
+
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`search`
+
+.. _Discord : https://discordapp.com/
diff --git a/docs/make.bat b/docs/make.bat
new file mode 100644
index 000000000..c3d1c3bcc
--- /dev/null
+++ b/docs/make.bat
@@ -0,0 +1,263 @@
+@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=_build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
+set I18NSPHINXOPTS=%SPHINXOPTS% .
+if NOT "%PAPER%" == "" (
+ set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+ set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+ :help
+ echo.Please use `make ^` where ^ is one of
+ echo. html to make standalone HTML files
+ echo. dirhtml to make HTML files named index.html in directories
+ echo. singlehtml to make a single large HTML file
+ echo. pickle to make pickle files
+ echo. json to make JSON files
+ echo. htmlhelp to make HTML files and a HTML help project
+ echo. qthelp to make HTML files and a qthelp project
+ echo. devhelp to make HTML files and a Devhelp project
+ echo. epub to make an epub
+ echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+ echo. text to make text files
+ echo. man to make manual pages
+ echo. texinfo to make Texinfo files
+ echo. gettext to make PO message catalogs
+ echo. changes to make an overview over all changed/added/deprecated items
+ echo. xml to make Docutils-native XML files
+ echo. pseudoxml to make pseudoxml-XML files for display purposes
+ echo. linkcheck to check all external links for integrity
+ echo. doctest to run all doctests embedded in the documentation if enabled
+ echo. coverage to run coverage check of the documentation if enabled
+ goto end
+)
+
+if "%1" == "clean" (
+ for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+ del /q /s %BUILDDIR%\*
+ goto end
+)
+
+
+REM Check if sphinx-build is available and fallback to Python version if any
+%SPHINXBUILD% 2> nul
+if errorlevel 9009 goto sphinx_python
+goto sphinx_ok
+
+:sphinx_python
+
+set SPHINXBUILD=python -m sphinx.__init__
+%SPHINXBUILD% 2> nul
+if errorlevel 9009 (
+ echo.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
+ echo.
+ echo.If you don't have Sphinx installed, grab it from
+ echo.http://sphinx-doc.org/
+ exit /b 1
+)
+
+:sphinx_ok
+
+
+if "%1" == "html" (
+ %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+ goto end
+)
+
+if "%1" == "dirhtml" (
+ %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+ goto end
+)
+
+if "%1" == "singlehtml" (
+ %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+ goto end
+)
+
+if "%1" == "pickle" (
+ %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the pickle files.
+ goto end
+)
+
+if "%1" == "json" (
+ %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the JSON files.
+ goto end
+)
+
+if "%1" == "htmlhelp" (
+ %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+ goto end
+)
+
+if "%1" == "qthelp" (
+ %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+ echo.^> qcollectiongenerator %BUILDDIR%\qthelp\discordjs.qhcp
+ echo.To view the help file:
+ echo.^> assistant -collectionFile %BUILDDIR%\qthelp\discordjs.ghc
+ goto end
+)
+
+if "%1" == "devhelp" (
+ %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished.
+ goto end
+)
+
+if "%1" == "epub" (
+ %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The epub file is in %BUILDDIR%/epub.
+ goto end
+)
+
+if "%1" == "latex" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "latexpdf" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ cd %BUILDDIR%/latex
+ make all-pdf
+ cd %~dp0
+ echo.
+ echo.Build finished; the PDF files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "latexpdfja" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ cd %BUILDDIR%/latex
+ make all-pdf-ja
+ cd %~dp0
+ echo.
+ echo.Build finished; the PDF files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "text" (
+ %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The text files are in %BUILDDIR%/text.
+ goto end
+)
+
+if "%1" == "man" (
+ %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The manual pages are in %BUILDDIR%/man.
+ goto end
+)
+
+if "%1" == "texinfo" (
+ %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
+ goto end
+)
+
+if "%1" == "gettext" (
+ %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
+ goto end
+)
+
+if "%1" == "changes" (
+ %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.The overview file is in %BUILDDIR%/changes.
+ goto end
+)
+
+if "%1" == "linkcheck" (
+ %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+ goto end
+)
+
+if "%1" == "doctest" (
+ %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+ goto end
+)
+
+if "%1" == "coverage" (
+ %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Testing of coverage in the sources finished, look at the ^
+results in %BUILDDIR%/coverage/python.txt.
+ goto end
+)
+
+if "%1" == "xml" (
+ %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The XML files are in %BUILDDIR%/xml.
+ goto end
+)
+
+if "%1" == "pseudoxml" (
+ %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
+ goto end
+)
+
+:end
diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst
new file mode 100644
index 000000000..3f5fa02ad
--- /dev/null
+++ b/docs/troubleshooting.rst
@@ -0,0 +1,10 @@
+Troubleshooting
+===============
+
+Occasionally, the API can stop working for whatever reason. If it was working previously and it stopped working on the same version, it means that there's been a change to the Discord API. In this case, please `make an issue`_ if one relating to a similar issue doesn't exist. Please post a stacktrace if there is one, and be as detailed as possible - *"the API isn't working"* doesn't help at all.
+
+If there is already an issue, feel free to comment that you're also experiencing the same thing. This helps to see how widespread the bug is.
+
+You can try reconnecting before submitting an issue, as sometimes some of the servers may be slightly different.
+
+.. _make an issue : https://github.com/hydrabolt/discord.js/issues
\ No newline at end of file
diff --git a/docs/vars.rst b/docs/vars.rst
new file mode 100644
index 000000000..ad4b9720a
--- /dev/null
+++ b/docs/vars.rst
@@ -0,0 +1,11 @@
+.. _Client : ./docs_client.html
+.. _User : ./docs_user.html
+.. _ready : #ready
+.. _Server : ./docs_server.html
+.. _Channel : ./docs_channel.html
+.. _Message : ./docs_message.html
+.. _PMChannel : ./docs_pmchannel.html
+.. _Invite : ./docs_invite.html
+.. _Channel Resolvable : ./docs_resolvable.html#channel-resolvable
+.. _Invite Resolvable : ./docs_resolvable.html#invite-resolvable
+.. _Promises : https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise
\ No newline at end of file
diff --git a/examples/avatar.js b/examples/avatar.js
index b0eb1bb27..da0fd4792 100644
--- a/examples/avatar.js
+++ b/examples/avatar.js
@@ -4,38 +4,28 @@
var Discord = require("../");
-// Get the email and password
var AuthDetails = require("./auth.json");
var bot = new Discord.Client();
-bot.on("ready", function () {
+bot.on("ready", () => {
console.log("Ready to begin! Serving in " + bot.channels.length + " channels");
});
-bot.on("disconnected", function () {
+bot.on("disconnected", () => {
console.log("Disconnected!");
process.exit(1); //exit node.js with an error
});
-bot.on("message", function (msg) {
- if (msg.content === "$avatar") {
-
- //see if the user has an avatar
- if( msg.sender.avatarURL ){
- bot.reply(msg, msg.sender.avatarURL);
- }else{
- //using reply with a message automatically does:
- // '@sender, ' for you!
- bot.reply(msg, "you don't have an avatar!");
- }
-
- //alert the console
- console.log("served " + msg.sender.username);
-
+bot.on("message", (msg) => {
+
+ if( msg.content === "avatar" ){
+ // if the message was avatar
+ bot.reply( msg, msg.sender.avatarURL );
}
+
});
bot.login(AuthDetails.email, AuthDetails.password);
\ No newline at end of file
diff --git a/examples/catapi.js b/examples/catapi.js
deleted file mode 100644
index ae5b7f6aa..000000000
--- a/examples/catapi.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- this bot will send an image of a cat to a channel.
- may be slow depending on your internet connection.
-*/
-
-var Discord = require("../");
-
-// Get the email and password
-var AuthDetails = require("./auth.json");
-
-var bot = new Discord.Client();
-
-bot.on("ready", function () {
- console.log("Ready to begin! Serving in " + bot.channels.length + " channels");
-});
-
-bot.on("disconnected", function () {
-
- console.log("Disconnected!");
- process.exit(1); //exit node.js with an error
-
-});
-
-bot.on("message", function (msg) {
- if (msg.content === "$cat") {
-
- //send a message to the channel the ping message was sent in.
- bot.sendMessage(msg.channel, "pong!");
-
- //alert the console
- console.log("pong-ed " + msg.sender.username);
-
- }
-});
-
-bot.login(AuthDetails.email, AuthDetails.password);
\ No newline at end of file
diff --git a/examples/permissions.js b/examples/permissions.js
new file mode 100644
index 000000000..e336eca2b
--- /dev/null
+++ b/examples/permissions.js
@@ -0,0 +1,41 @@
+/* this bot will see if a user can send TTS messages */
+
+var Discord = require("../");
+
+var AuthDetails = require("./auth.json");
+
+var bot = new Discord.Client();
+
+bot.on("ready", () => {
+ console.log("Ready to begin!");
+});
+
+bot.on("message", (msg) => {
+
+ if(msg.content === "can I tts?"){
+
+ var user = msg.sender;
+
+ // get the evaluated permissions for a user in the channel they asked
+ var permissions = msg.channel.permissionsOf(user);
+
+ if(permissions.sendTTSMessages){
+
+ bot.reply(msg, "You *can* send TTS messages.");
+
+ }else{
+
+ bot.reply(msg, "You *can't* send TTS messages.");
+
+ }
+
+ }
+
+ /*
+ for a list of more permissions, go to
+ https://github.com/hydrabolt/discord.js/blob/master/src/EvaluatedPermissions.js
+ */
+
+})
+
+bot.login(AuthDetails.email, AuthDetails.password);
\ No newline at end of file
diff --git a/examples/send-files.js b/examples/send-files.js
new file mode 100644
index 000000000..419d77a36
--- /dev/null
+++ b/examples/send-files.js
@@ -0,0 +1,33 @@
+/* this bot will send an image to a channel */
+
+var Discord = require("../");
+
+var AuthDetails = require("./auth.json");
+
+var bot = new Discord.Client();
+
+bot.on("ready", () => {
+ console.log("Ready to begin!");
+});
+
+bot.on("message", (msg) => {
+
+ if (msg.content === "photos") {
+
+ bot.sendFile( msg.channel, "./test/image.png", "photo.png", (err, msg) => {
+ if(err)
+ console.log("couldn't send image:", err);
+ });
+
+ }
+
+ if( msg.content === "file" ) {
+ bot.sendFile( msg.channel, new Buffer("Text in a file!"), "file.txt", (err, msg) => {
+ if(err)
+ console.log("couldn't send file:", err);
+ });
+ }
+
+})
+
+bot.login(AuthDetails.email, AuthDetails.password);
\ No newline at end of file
diff --git a/gruntfile.js b/gruntfile.js
index 2cf6001aa..eab691c49 100644
--- a/gruntfile.js
+++ b/gruntfile.js
@@ -3,9 +3,13 @@ module.exports = function (grunt) {
require('load-grunt-tasks')(grunt);
grunt.initConfig({
-
+ pkg: grunt.file.readJSON("package.json"),
// define source files and their destinations
babel: {
+ options: {
+ loose: "all",
+ compact: true
+ },
dist: {
files: [{
expand: true,
@@ -19,7 +23,7 @@ module.exports = function (grunt) {
browserify: {
dist: {
files: {
- 'web-dist/discord.js': ["lib/index.js"],
+ 'web-dist/discord.<%= pkg.version %>.js': ["lib/index.js"],
},
options: {
browserifyOptions: {
@@ -31,7 +35,7 @@ module.exports = function (grunt) {
uglify: {
min: {
files: {
- "./web-dist/discord.min.js": "./web-dist/discord.js"
+ "./web-dist/discord.min.<%= pkg.version %>.js": "./web-dist/discord.<%= pkg.version %>.js"
}
}
}
@@ -44,5 +48,6 @@ module.exports = function (grunt) {
// register at least this one task
grunt.registerTask('default', ['babel']);
grunt.registerTask('web', ['browserify', "uglify"]);
+ grunt.registerTask("dist", ["babel", "browserify", "uglify"])
};
\ No newline at end of file
diff --git a/lib/ChannelPermissions.js b/lib/ChannelPermissions.js
new file mode 100644
index 000000000..5193b5938
--- /dev/null
+++ b/lib/ChannelPermissions.js
@@ -0,0 +1,180 @@
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var ChannelPermissions = (function () {
+ function ChannelPermissions(data, channel) {
+ _classCallCheck(this, ChannelPermissions);
+
+ var self = this;
+
+ function getBit(x) {
+ return (self.packed >>> x & 1) === 1;
+ }
+
+ this.type = data.type; //either member or role
+ this.id = data.id;
+
+ if (this.type === "member") {
+ this.packed = channel.server.getMember("id", data.id).evalPerms.packed;
+ } else {
+ this.packed = channel.server.getRole(data.id).packed;
+ }
+
+ this.packed = this.packed & ~data.deny;
+ this.packed = this.packed | data.allow;
+
+ this.deny = data.deny;
+ this.allow = data.allow;
+ }
+
+ ChannelPermissions.prototype.getBit = function getBit(x) {
+ return (this.packed >>> x & 1) === 1;
+ };
+
+ ChannelPermissions.prototype.setBit = function setBit() {};
+
+ _createClass(ChannelPermissions, [{
+ key: "createInstantInvite",
+ get: function get() {
+ return this.getBit(0);
+ },
+ set: function set(val) {
+ this.setBit(0, val);
+ }
+ }, {
+ key: "manageRoles",
+ get: function get() {
+ return this.getBit(3);
+ },
+ set: function set(val) {
+ this.setBit(3, val);
+ }
+ }, {
+ key: "manageChannels",
+ get: function get() {
+ return this.getBit(4);
+ },
+ set: function set(val) {
+ this.setBit(4, val);
+ }
+ }, {
+ key: "readMessages",
+ get: function get() {
+ return this.getBit(10);
+ },
+ set: function set(val) {
+ this.setBit(10, val);
+ }
+ }, {
+ key: "sendMessages",
+ get: function get() {
+ return this.getBit(11);
+ },
+ set: function set(val) {
+ this.setBit(11, val);
+ }
+ }, {
+ key: "sendTTSMessages",
+ get: function get() {
+ return this.getBit(12);
+ },
+ set: function set(val) {
+ this.setBit(12, val);
+ }
+ }, {
+ key: "manageMessages",
+ get: function get() {
+ return this.getBit(13);
+ },
+ set: function set(val) {
+ this.setBit(13, val);
+ }
+ }, {
+ key: "embedLinks",
+ get: function get() {
+ return this.getBit(14);
+ },
+ set: function set(val) {
+ this.setBit(14, val);
+ }
+ }, {
+ key: "attachFiles",
+ get: function get() {
+ return this.getBit(15);
+ },
+ set: function set(val) {
+ this.setBit(15, val);
+ }
+ }, {
+ key: "readMessageHistory",
+ get: function get() {
+ return this.getBit(16);
+ },
+ set: function set(val) {
+ this.setBit(16, val);
+ }
+ }, {
+ key: "mentionEveryone",
+ get: function get() {
+ return this.getBit(17);
+ },
+ set: function set(val) {
+ this.setBit(17, val);
+ }
+ }, {
+ key: "voiceConnect",
+ get: function get() {
+ return this.getBit(20);
+ },
+ set: function set(val) {
+ this.setBit(20, val);
+ }
+ }, {
+ key: "voiceSpeak",
+ get: function get() {
+ return this.getBit(21);
+ },
+ set: function set(val) {
+ this.setBit(21, val);
+ }
+ }, {
+ key: "voiceMuteMembers",
+ get: function get() {
+ return this.getBit(22);
+ },
+ set: function set(val) {
+ this.setBit(22, val);
+ }
+ }, {
+ key: "voiceDeafenMembers",
+ get: function get() {
+ return this.getBit(23);
+ },
+ set: function set(val) {
+ this.setBit(23, val);
+ }
+ }, {
+ key: "voiceMoveMembers",
+ get: function get() {
+ return this.getBit(24);
+ },
+ set: function set(val) {
+ this.setBit(24, val);
+ }
+ }, {
+ key: "voiceUseVoiceActivation",
+ get: function get() {
+ return this.getBit(25);
+ },
+ set: function set(val) {
+ this.setBit(25, val);
+ }
+ }]);
+
+ return ChannelPermissions;
+})();
+
+module.exports = ChannelPermissions;
\ No newline at end of file
diff --git a/lib/Client.js b/lib/Client.js
index e12f5a0ee..6f5b8eb32 100644
--- a/lib/Client.js
+++ b/lib/Client.js
@@ -13,6 +13,8 @@ var Message = require("./message.js");
var Invite = require("./invite.js");
var PMChannel = require("./PMChannel.js");
+var gameMap = require("../ref/gameMap.json");
+
//node modules
var request = require("superagent");
var WebSocket = require("ws");
@@ -39,11 +41,11 @@ var Client = (function () {
this.token = token;
this.state = 0;
this.websocket = null;
- this.events = new Map();
+ this.events = {};
this.user = null;
this.alreadySentData = false;
- this.serverCreateListener = new Map();
-
+ this.serverCreateListener = {};
+ this.typingIntervals = {};
this.email = "abc";
this.password = "abc";
@@ -62,1526 +64,1586 @@ var Client = (function () {
this.pmChannelCache = [];
this.readyTime = null;
this.checkingQueue = {};
+ this.userTypingListener = {};
this.queue = {};
+
+ this.__idleTime = null;
+ this.__gameId = null;
}
- _createClass(Client, [{
- key: "sendPacket",
- value: function sendPacket(JSONObject) {
- if (this.websocket.readyState === 1) {
- this.websocket.send(JSON.stringify(JSONObject));
- }
+ Client.prototype.sendPacket = function sendPacket(JSONObject) {
+ if (this.websocket.readyState === 1) {
+ this.websocket.send(JSON.stringify(JSONObject));
}
+ };
- //def debug
- }, {
- key: "debug",
- value: function debug(message) {
- this.trigger("debug", message);
+ //def debug
+
+ Client.prototype.debug = function debug(message) {
+ this.trigger("debug", message);
+ };
+
+ Client.prototype.on = function on(event, fn) {
+ this.events[event] = fn;
+ };
+
+ Client.prototype.off = function off(event) {
+ this.events[event] = null;
+ };
+
+ Client.prototype.keepAlive = function keepAlive() {
+ this.debug("keep alive triggered");
+ this.sendPacket({
+ op: 1,
+ d: Date.now()
+ });
+ };
+
+ //def trigger
+
+ Client.prototype.trigger = function trigger(event) {
+ var args = [];
+ for (var arg in arguments) {
+ args.push(arguments[arg]);
}
- }, {
- key: "on",
- value: function on(event, fn) {
- this.events.set(event, fn);
- }
- }, {
- key: "off",
- value: function off(event, fn) {
- this.events["delete"](event);
- }
- }, {
- key: "keepAlive",
- value: function keepAlive() {
- this.debug("keep alive triggered");
- this.sendPacket({
- op: 1,
- d: Date.now()
- });
+ var evt = this.events[event];
+ if (evt) {
+ evt.apply(this, args.slice(1));
}
+ };
- //def trigger
- }, {
- key: "trigger",
- value: function trigger(event) {
- var args = [];
- for (var arg in arguments) {
- args.push(arguments[arg]);
- }
- var evt = this.events.get(event);
- if (evt) {
- evt.apply(this, args.slice(1));
- }
- }
+ //def login
- //def login
- }, {
- key: "login",
- value: function login() {
- var email = arguments.length <= 0 || arguments[0] === undefined ? "foo@bar.com" : arguments[0];
- var password = arguments.length <= 1 || arguments[1] === undefined ? "pass1234" : arguments[1];
- var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, token) {} : arguments[2];
+ Client.prototype.login = function login() {
+ var email = arguments.length <= 0 || arguments[0] === undefined ? "foo@bar.com" : arguments[0];
+ var password = arguments.length <= 1 || arguments[1] === undefined ? "pass1234" : arguments[1];
+ var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, token) {} : arguments[2];
- var self = this;
+ var self = this;
- return new Promise(function (resolve, reject) {
- if (self.state === 0 || self.state === 4) {
+ return new Promise(function (resolve, reject) {
+ if (self.state === 0 || self.state === 4) {
- self.state = 1; //set the state to logging in
+ self.state = 1; //set the state to logging in
- self.email = email;
- self.password = password;
+ self.email = email;
+ self.password = password;
- request.post(Endpoints.LOGIN).send({
- email: email,
- password: password
- }).end(function (err, res) {
+ request.post(Endpoints.LOGIN).send({
+ email: email,
+ password: password
+ }).end(function (err, res) {
- if (err) {
- self.state = 4; //set state to disconnected
- self.trigger("disconnected");
+ if (err) {
+ self.state = 4; //set state to disconnected
+ self.trigger("disconnected");
+ if (self.websocket) {
self.websocket.close();
+ }
+ callback(err);
+ reject(err);
+ } else {
+ self.state = 2; //set state to logged in (not yet ready)
+ self.token = res.body.token; //set our token
+
+ self.getGateway().then(function (url) {
+ self.createws(url);
+ callback(null, self.token);
+ resolve(self.token);
+ })["catch"](function (err) {
callback(err);
reject(err);
- } else {
- self.state = 2; //set state to logged in (not yet ready)
- self.token = res.body.token; //set our token
-
- getGateway().then(function (url) {
- self.createws(url);
- callback(null, self.token);
- resolve(self.token);
- })["catch"](function (err) {
- callback(err);
- reject(err);
- });
- }
- });
- } else {
- reject(new Error("Client already logging in or ready"));
- }
- });
- }
- }, {
- key: "logout",
- value: function logout() {
- var callback = arguments.length <= 0 || arguments[0] === undefined ? function (err) {} : arguments[0];
-
- var self = this;
-
- return new Promise(function (resolve, reject) {
-
- request.post(Endpoints.LOGOUT).set("authorization", self.token).end(function (err, res) {
-
- if (err) {
- callback(err);
- reject(err);
- } else {
- self.websocket.close();
- self.state = 4;
- callback();
- resolve();
- }
- });
- });
- }
- }, {
- key: "createServer",
- value: function createServer(name, region) {
- var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, server) {} : arguments[2];
-
- var self = this;
- return new Promise(function (resolve, reject) {
-
- request.post(Endpoints.SERVERS).set("authorization", self.token).send({
- name: name,
- region: region
- }).end(function (err, res) {
- if (err) {
- callback(err);
- reject(err);
- } else {
- // potentially redundant in future
- // creating here does NOT give us the channels of the server
- // so we must wait for the guild_create event.
- self.serverCreateListener.set(res.body.id, [resolve, callback]);
- /*var srv = self.addServer(res.body);
- callback(null, srv);
- resolve(srv);*/
- }
- });
- });
- }
- }, {
- key: "createChannel",
- value: function createChannel(server, channelName, channelType) {
- var callback = arguments.length <= 3 || arguments[3] === undefined ? function (err, chann) {} : arguments[3];
-
- var self = this;
-
- return new Promise(function (resolve, reject) {
-
- request.post(Endpoints.SERVERS + "/" + self.resolveServerID(server) + "/channels").set("authorization", self.token).send({
- name: channelName,
- type: channelType
- }).end(function (err, res) {
-
- if (err) {
- callback(err);
- reject(err);
- } else {
- var server = self.getServer("id", res.body.guild_id);
- var chann = self.addChannel(res.body, res.body.guild_id);
- server.addChannel(chann);
- callback(null, chann);
- resolve(chann);
- }
- });
- });
- }
- }, {
- key: "leaveServer",
- value: function leaveServer(server) {
- var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err, server) {} : arguments[1];
-
- var self = this;
-
- return new Promise(function (resolve, reject) {
-
- request.del(Endpoints.SERVERS + "/" + self.resolveServerID(server)).set("authorization", self.token).end(function (err, res) {
-
- if (err) {
- callback(err);
- reject(err);
- } else {
- self.serverCache.splice(self.serverCache.indexOf(server), 1);
- callback(null);
- resolve();
- }
- });
- });
- }
- }, {
- key: "createInvite",
- value: function createInvite(serverOrChannel, options) {
- var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, invite) {} : arguments[2];
-
- var self = this;
-
- return new Promise(function (resolve, reject) {
-
- var destination;
-
- if (serverOrChannel instanceof Server) {
- destination = serverOrChannel.id;
- } else if (serverOrChannel instanceof Channel) {
- destination = serverOrChannel.id;
- } else {
- destination = serverOrChannel;
- }
-
- options = options || {};
- options.max_age = options.maxAge || 0;
- options.max_uses = options.maxUses || 0;
- options.temporary = options.temporary || false;
- options.xkcdpass = options.xkcd || false;
-
- request.post(Endpoints.CHANNELS + "/" + destination + "/invites").set("authorization", self.token).send(options).end(function (err, res) {
- if (err) {
- callback(err);
- reject(err);
- } else {
- var inv = new Invite(res.body, self);
- callback(null, inv);
- resolve(inv);
- }
- });
- });
- }
- }, {
- key: "startPM",
- value: function startPM(user) {
-
- var self = this;
-
- return new Promise(function (resolve, reject) {
- var userId = user;
- if (user instanceof User) {
- userId = user.id;
- }
- request.post(Endpoints.USERS + "/" + self.user.id + "/channels").set("authorization", self.token).send({
- recipient_id: userId
- }).end(function (err, res) {
- if (err) {
- reject(err);
- } else {
- resolve(self.addPMChannel(res.body));
- }
- });
- });
- }
- }, {
- key: "reply",
- value: function reply(destination, message) {
- var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2];
-
- var self = this;
-
- return new Promise(function (response, reject) {
-
- var user = destination.sender;
- self.sendMessage(destination, message, callback, user + ", ").then(response)["catch"](reject);
- });
- }
- }, {
- key: "deleteMessage",
- value: function deleteMessage(message, timeout) {
- var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2];
-
- var self = this;
-
- var prom = new Promise(function (resolve, reject) {
- if (timeout) {
- setTimeout(remove, timeout);
- } else {
- remove();
- }
-
- function remove() {
- if (self.options.queue) {
- if (!self.queue[message.channel.id]) {
- self.queue[message.channel.id] = [];
- }
- self.queue[message.channel.id].push({
- action: "deleteMessage",
- message: message,
- then: good,
- error: bad
});
-
- self.checkQueue(message.channel.id);
- } else {
- self._deleteMessage(message).then(good)["catch"](bad);
}
- }
+ });
+ } else {
+ reject(new Error("Client already logging in or ready"));
+ }
+ });
+ };
- function good() {
- prom.success = true;
+ Client.prototype.logout = function logout() {
+ var callback = arguments.length <= 0 || arguments[0] === undefined ? function (err) {} : arguments[0];
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+
+ request.post(Endpoints.LOGOUT).set("authorization", self.token).end(function (err, res) {
+
+ if (err) {
+ callback(err);
+ reject(err);
+ } else {
+ self.websocket.close();
+ self.state = 4;
+ callback();
+ resolve();
+ }
+ });
+ });
+ };
+
+ Client.prototype.createServer = function createServer(name, region) {
+ var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, server) {} : arguments[2];
+
+ var self = this;
+ return new Promise(function (resolve, reject) {
+
+ request.post(Endpoints.SERVERS).set("authorization", self.token).send({
+ name: name,
+ region: region
+ }).end(function (err, res) {
+ if (err) {
+ callback(err);
+ reject(err);
+ } else {
+ // potentially redundant in future
+ // creating here does NOT give us the channels of the server
+ // so we must wait for the guild_create event.
+ self.serverCreateListener[res.body.id] = [resolve, callback];
+ /*var srv = self.addServer(res.body);
+ callback(null, srv);
+ resolve(srv);*/
+ }
+ });
+ });
+ };
+
+ Client.prototype.createChannel = function createChannel(server, channelName, channelType) {
+ var callback = arguments.length <= 3 || arguments[3] === undefined ? function (err, chann) {} : arguments[3];
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+
+ request.post(Endpoints.SERVERS + "/" + self.resolveServerID(server) + "/channels").set("authorization", self.token).send({
+ name: channelName,
+ type: channelType
+ }).end(function (err, res) {
+
+ if (err) {
+ callback(err);
+ reject(err);
+ } else {
+ var server = self.getServer("id", res.body.guild_id);
+ var chann = self.addChannel(res.body, res.body.guild_id);
+ server.addChannel(chann);
+ callback(null, chann);
+ resolve(chann);
+ }
+ });
+ });
+ };
+
+ Client.prototype.leaveServer = function leaveServer(server) {
+ var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err, server) {} : arguments[1];
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+
+ request.del(Endpoints.SERVERS + "/" + self.resolveServerID(server)).set("authorization", self.token).end(function (err, res) {
+
+ if (err) {
+ callback(err);
+ reject(err);
+ } else {
+ self.serverCache.splice(self.serverCache.indexOf(server), 1);
callback(null);
resolve();
}
+ });
+ });
+ };
- function bad(err) {
- prom.error = err;
+ Client.prototype.createInvite = function createInvite(serverOrChannel, options) {
+ var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, invite) {} : arguments[2];
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+
+ var destination;
+
+ if (serverOrChannel instanceof Server) {
+ destination = serverOrChannel.id;
+ } else if (serverOrChannel instanceof Channel) {
+ destination = serverOrChannel.id;
+ } else {
+ destination = serverOrChannel;
+ }
+
+ options = options || {};
+ options.max_age = options.maxAge || 0;
+ options.max_uses = options.maxUses || 0;
+ options.temporary = options.temporary || false;
+ options.xkcdpass = options.xkcd || false;
+
+ request.post(Endpoints.CHANNELS + "/" + destination + "/invites").set("authorization", self.token).send(options).end(function (err, res) {
+ if (err) {
callback(err);
reject(err);
+ } else {
+ var inv = new Invite(res.body, self);
+ callback(null, inv);
+ resolve(inv);
}
});
+ });
+ };
- return prom;
- }
- }, {
- key: "updateMessage",
- value: function updateMessage(message, content) {
- var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2];
+ Client.prototype.startPM = function startPM(user) {
- var self = this;
+ var self = this;
- var prom = new Promise(function (resolve, reject) {
+ return new Promise(function (resolve, reject) {
+ var userId = user;
+ if (user instanceof User) {
+ userId = user.id;
+ }
+ request.post(Endpoints.USERS + "/" + self.user.id + "/channels").set("authorization", self.token).send({
+ recipient_id: userId
+ }).end(function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ resolve(self.addPMChannel(res.body));
+ }
+ });
+ });
+ };
- content = content instanceof Array ? content.join("\n") : content;
+ Client.prototype.reply = function reply(destination, message, tts) {
+ var callback = arguments.length <= 3 || arguments[3] === undefined ? function (err, msg) {} : arguments[3];
- if (self.options.queue) {
- if (!self.queue[message.channel.id]) {
- self.queue[message.channel.id] = [];
+ var self = this;
+
+ return new Promise(function (response, reject) {
+
+ if (typeof tts === "function") {
+ // tts is a function, which means the developer wants this to be the callback
+ callback = tts;
+ tts = false;
+ }
+
+ var user = destination.sender;
+ self.sendMessage(destination, message, tts, callback, user + ", ").then(response)["catch"](reject);
+ });
+ };
+
+ Client.prototype.deleteMessage = function deleteMessage(message, timeout) {
+ var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2];
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ if (timeout) {
+ setTimeout(remove, timeout);
+ } else {
+ remove();
+ }
+
+ function remove() {
+ request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).end(function (err, res) {
+ if (err) {
+ bad();
+ } else {
+ good();
}
- self.queue[message.channel.id].push({
- action: "updateMessage",
- message: message,
- content: content,
+ });
+ }
+
+ function good() {
+ callback();
+ resolve();
+ }
+
+ function bad(err) {
+ callback(err);
+ reject(err);
+ }
+ });
+ };
+
+ Client.prototype.updateMessage = function updateMessage(message, content) {
+ var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2];
+
+ var self = this;
+
+ var prom = new Promise(function (resolve, reject) {
+
+ content = content instanceof Array ? content.join("\n") : content;
+
+ if (self.options.queue) {
+ if (!self.queue[message.channel.id]) {
+ self.queue[message.channel.id] = [];
+ }
+ self.queue[message.channel.id].push({
+ action: "updateMessage",
+ message: message,
+ content: content,
+ then: good,
+ error: bad
+ });
+
+ self.checkQueue(message.channel.id);
+ } else {
+ self._updateMessage(message, content).then(good)["catch"](bad);
+ }
+
+ function good(msg) {
+ prom.message = msg;
+ callback(null, msg);
+ resolve(msg);
+ }
+
+ function bad(error) {
+ prom.error = error;
+ callback(error);
+ reject(error);
+ }
+ });
+
+ return prom;
+ };
+
+ Client.prototype.setUsername = function setUsername(newName) {
+ var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err) {} : arguments[1];
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ request.patch(Endpoints.API + "/users/@me").set("authorization", self.token).send({
+ avatar: self.user.avatar,
+ email: self.email,
+ new_password: null,
+ password: self.password,
+ username: newName
+ }).end(function (err) {
+ callback(err);
+ if (err) reject(err);else resolve();
+ });
+ });
+ };
+
+ Client.prototype.getChannelLogs = function getChannelLogs(channel) {
+ var amount = arguments.length <= 1 || arguments[1] === undefined ? 500 : arguments[1];
+ var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, logs) {} : arguments[2];
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+
+ var channelID = channel;
+ if (channel instanceof Channel) {
+ channelID = channel.id;
+ }
+
+ request.get(Endpoints.CHANNELS + "/" + channelID + "/messages?limit=" + amount).set("authorization", self.token).end(function (err, res) {
+
+ if (err) {
+ callback(err);
+ reject(err);
+ } else {
+ var logs = [];
+
+ var channel = self.getChannel("id", channelID);
+
+ for (var _iterator = res.body, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
+ var _ref;
+
+ if (_isArray) {
+ if (_i >= _iterator.length) break;
+ _ref = _iterator[_i++];
+ } else {
+ _i = _iterator.next();
+ if (_i.done) break;
+ _ref = _i.value;
+ }
+
+ var message = _ref;
+
+ var mentions = [];
+ for (var _iterator2 = message.mentions, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
+ var _ref2;
+
+ if (_isArray2) {
+ if (_i2 >= _iterator2.length) break;
+ _ref2 = _iterator2[_i2++];
+ } else {
+ _i2 = _iterator2.next();
+ if (_i2.done) break;
+ _ref2 = _i2.value;
+ }
+
+ var mention = _ref2;
+
+ mentions.push(self.addUser(mention));
+ }
+
+ var author = self.addUser(message.author);
+
+ logs.push(new Message(message, channel, mentions, author));
+ }
+ callback(null, logs);
+ resolve(logs);
+ }
+ });
+ });
+ };
+
+ Client.prototype.deleteChannel = function deleteChannel(channel) {
+ var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err) {} : arguments[1];
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+
+ var channelID = channel;
+ if (channel instanceof Channel) {
+ channelID = channel.id;
+ }
+
+ request.del(Endpoints.CHANNELS + "/" + channelID).set("authorization", self.token).end(function (err) {
+ if (err) {
+ callback(err);
+ reject(err);
+ } else {
+ callback(null);
+ resolve();
+ }
+ });
+ });
+ };
+
+ Client.prototype.joinServer = function joinServer(invite) {
+ var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err, server) {} : arguments[1];
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+
+ var id = invite instanceof Invite ? invite.code : invite;
+
+ request.post(Endpoints.API + "/invite/" + id).set("authorization", self.token).end(function (err, res) {
+ if (err) {
+ callback(err);
+ reject(err);
+ } else {
+ if (self.getServer("id", res.body.guild.id)) {
+ resolve(self.getServer("id", res.body.guild.id));
+ } else {
+ self.serverCreateListener[res.body.guild.id] = [resolve, callback];
+ }
+ }
+ });
+ });
+ };
+
+ Client.prototype.setAvatar = function setAvatar(resource) {
+ var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err) {} : arguments[1];
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ if (resource instanceof Buffer) {
+ resource = resource.toString("base64");
+ resource = "data:image/jpg;base64," + resource;
+ }
+
+ request.patch(Endpoints.API + "/users/@me").set("authorization", self.token).send({
+ avatar: resource,
+ email: self.email,
+ new_password: null,
+ password: self.password,
+ username: self.user.username
+ }).end(function (err) {
+ callback(err);
+ if (err) reject(err);else resolve();
+ });
+ });
+ };
+
+ Client.prototype.sendFile = function sendFile(destination, file) {
+ var fileName = arguments.length <= 2 || arguments[2] === undefined ? "image.png" : arguments[2];
+ var callback = arguments.length <= 3 || arguments[3] === undefined ? function (err, msg) {} : arguments[3];
+
+ var self = this;
+
+ var prom = new Promise(function (resolve, reject) {
+
+ var fstream;
+
+ if (typeof file === "string" || file instanceof String) {
+ fstream = fs.createReadStream(file);
+ fileName = file;
+ } else {
+ fstream = file;
+ }
+
+ self.resolveDestination(destination).then(send)["catch"](bad);
+
+ function send(destination) {
+ if (self.options.queue) {
+ //queue send file too
+ if (!self.queue[destination]) {
+ self.queue[destination] = [];
+ }
+
+ self.queue[destination].push({
+ action: "sendFile",
+ attachment: fstream,
+ attachmentName: fileName,
then: good,
error: bad
});
- self.checkQueue(message.channel.id);
+ self.checkQueue(destination);
} else {
- self._updateMessage(message, content).then(good)["catch"](bad);
+ //not queue
+ self._sendFile(destination, fstream, fileName).then(good)["catch"](bad);
}
+ }
- function good(msg) {
- prom.message = msg;
- callback(null, msg);
- resolve(msg);
- }
+ function good(msg) {
+ prom.message = msg;
+ callback(null, msg);
+ resolve(msg);
+ }
- function bad(error) {
- prom.error = error;
- callback(error);
- reject(error);
- }
- });
+ function bad(err) {
+ prom.error = err;
+ callback(err);
+ reject(err);
+ }
+ });
- return prom;
- }
- }, {
- key: "setUsername",
- value: function setUsername(newName) {
- var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err) {} : arguments[1];
+ return prom;
+ };
- var self = this;
+ Client.prototype.sendMessage = function sendMessage(destination, message, tts) {
+ var callback = arguments.length <= 3 || arguments[3] === undefined ? function (err, msg) {} : arguments[3];
+ var premessage = arguments.length <= 4 || arguments[4] === undefined ? "" : arguments[4];
- return new Promise(function (resolve, reject) {
- request.patch(Endpoints.API + "/users/@me").set("authorization", self.token).send({
- avatar: self.user.avatar,
- email: self.email,
- new_password: null,
- password: self.password,
- username: newName
- }).end(function (err) {
- callback(err);
- if (err) reject(err);else resolve();
- });
- });
- }
- }, {
- key: "getChannelLogs",
- value: function getChannelLogs(channel) {
- var amount = arguments.length <= 1 || arguments[1] === undefined ? 500 : arguments[1];
- var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, logs) {} : arguments[2];
+ var self = this;
- var self = this;
+ var prom = new Promise(function (resolve, reject) {
- return new Promise(function (resolve, reject) {
+ if (typeof tts === "function") {
+ // tts is a function, which means the developer wants this to be the callback
+ callback = tts;
+ tts = false;
+ }
- var channelID = channel;
- if (channel instanceof Channel) {
- channelID = channel.id;
- }
+ message = premessage + resolveMessage(message);
+ var mentions = resolveMentions();
+ self.resolveDestination(destination).then(send)["catch"](error);
- request.get(Endpoints.CHANNELS + "/" + channelID + "/messages?limit=" + amount).set("authorization", self.token).end(function (err, res) {
+ function error(err) {
+ callback(err);
+ reject(err);
+ }
- if (err) {
- callback(err);
- reject(err);
- } else {
- var logs = [];
-
- var channel = self.getChannel("id", channelID);
-
- var _iteratorNormalCompletion = true;
- var _didIteratorError = false;
- var _iteratorError = undefined;
-
- try {
- for (var _iterator = res.body[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
- var message = _step.value;
-
- var mentions = [];
- var _iteratorNormalCompletion2 = true;
- var _didIteratorError2 = false;
- var _iteratorError2 = undefined;
-
- try {
- for (var _iterator2 = message.mentions[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
- var mention = _step2.value;
-
- mentions.push(self.addUser(mention));
- }
- } catch (err) {
- _didIteratorError2 = true;
- _iteratorError2 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion2 && _iterator2["return"]) {
- _iterator2["return"]();
- }
- } finally {
- if (_didIteratorError2) {
- throw _iteratorError2;
- }
- }
- }
-
- var author = self.addUser(message.author);
-
- logs.push(new Message(message, channel, mentions, author));
- }
- } catch (err) {
- _didIteratorError = true;
- _iteratorError = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion && _iterator["return"]) {
- _iterator["return"]();
- }
- } finally {
- if (_didIteratorError) {
- throw _iteratorError;
- }
- }
- }
-
- callback(null, logs);
- resolve(logs);
+ function send(destination) {
+ if (self.options.queue) {
+ //we're QUEUEING messages, so sending them sequentially based on servers.
+ if (!self.queue[destination]) {
+ self.queue[destination] = [];
}
- });
- });
- }
- }, {
- key: "deleteChannel",
- value: function deleteChannel(channel) {
- var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err) {} : arguments[1];
- var self = this;
+ self.queue[destination].push({
+ action: "sendMessage",
+ content: message,
+ mentions: mentions,
+ tts: !!tts, //incase it's not a boolean
+ then: mgood,
+ error: mbad
+ });
- return new Promise(function (resolve, reject) {
-
- var channelID = channel;
- if (channel instanceof Channel) {
- channelID = channel.id;
+ self.checkQueue(destination);
+ } else {
+ self._sendMessage(destination, message, tts, mentions).then(mgood)["catch"](mbad);
}
+ }
- request.del(Endpoints.CHANNELS + "/" + channelID).set("authorization", self.token).end(function (err) {
- if (err) {
- callback(err);
- reject(err);
+ function mgood(msg) {
+ prom.message = msg;
+ callback(null, msg);
+ resolve(msg);
+ }
+
+ function mbad(error) {
+ prom.error = error;
+ callback(error);
+ reject(error);
+ }
+
+ function resolveMessage() {
+ var msg = message;
+ if (message instanceof Array) {
+ msg = message.join("\n");
+ }
+ return msg;
+ }
+
+ function resolveMentions() {
+ var _mentions = [];
+ for (var _iterator3 = message.match(/<@[^>]*>/g) || [], _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
+ var _ref3;
+
+ if (_isArray3) {
+ if (_i3 >= _iterator3.length) break;
+ _ref3 = _iterator3[_i3++];
} else {
- callback(null);
- resolve();
+ _i3 = _iterator3.next();
+ if (_i3.done) break;
+ _ref3 = _i3.value;
}
- });
- });
- }
- }, {
- key: "joinServer",
- value: function joinServer(invite) {
- var callback = arguments.length <= 1 || arguments[1] === undefined ? function (err, server) {} : arguments[1];
- var self = this;
+ var mention = _ref3;
- return new Promise(function (resolve, reject) {
+ _mentions.push(mention.substring(2, mention.length - 1));
+ }
+ return _mentions;
+ }
+ });
- var id = invite instanceof Invite ? invite.code : invite;
+ return prom;
+ };
- request.post(Endpoints.API + "/invite/" + id).set("authorization", self.token).end(function (err, res) {
- if (err) {
- callback(err);
- reject(err);
- } else {
- if (self.getServer("id", res.body.guild.id)) {
- resolve(self.getServer("id", res.body.guild.id));
+ //def createws
+
+ Client.prototype.createws = function createws(url) {
+ if (this.websocket) return false;
+
+ var self = this;
+
+ //good to go
+ this.websocket = new WebSocket(url);
+
+ //open
+ this.websocket.onopen = function () {
+ self.trySendConnData(); //try connecting
+ };
+
+ //close
+ this.websocket.onclose = function () {
+ self.trigger("disconnected");
+ };
+
+ //message
+ this.websocket.onmessage = function (e) {
+
+ var dat = false,
+ data = {};
+
+ try {
+ dat = JSON.parse(e.data);
+ data = dat.d;
+ } catch (err) {
+ self.trigger("error", err, e);
+ return;
+ }
+
+ self.trigger("raw", dat);
+
+ //valid message
+ switch (dat.t) {
+
+ case "READY":
+ self.debug("received ready packet");
+
+ self.user = self.addUser(data.user);
+
+ for (var _iterator4 = data.guilds, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
+ var _ref4;
+
+ if (_isArray4) {
+ if (_i4 >= _iterator4.length) break;
+ _ref4 = _iterator4[_i4++];
} else {
- self.serverCreateListener.set(res.body.guild.id, [resolve, callback]);
+ _i4 = _iterator4.next();
+ if (_i4.done) break;
+ _ref4 = _i4.value;
}
+
+ var _server = _ref4;
+
+ var server = self.addServer(_server);
}
- });
- });
- }
- }, {
- key: "sendFile",
- value: function sendFile(destination, file) {
- var fileName = arguments.length <= 2 || arguments[2] === undefined ? "image.png" : arguments[2];
- var callback = arguments.length <= 3 || arguments[3] === undefined ? function (err, msg) {} : arguments[3];
- var self = this;
+ for (var _iterator5 = data.private_channels, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {
+ var _ref5;
- var prom = new Promise(function (resolve, reject) {
-
- var fstream;
-
- if (typeof file === "string" || file instanceof String) {
- fstream = fs.createReadStream(file);
- fileName = file;
- } else {
- fstream = file;
- }
-
- self.resolveDestination(destination).then(send)["catch"](bad);
-
- function send(destination) {
- if (self.options.queue) {
- //queue send file too
- if (!self.queue[destination]) {
- self.queue[destination] = [];
+ if (_isArray5) {
+ if (_i5 >= _iterator5.length) break;
+ _ref5 = _iterator5[_i5++];
+ } else {
+ _i5 = _iterator5.next();
+ if (_i5.done) break;
+ _ref5 = _i5.value;
}
- self.queue[destination].push({
- action: "sendFile",
- attachment: fstream,
- attachmentName: fileName,
- then: good,
- error: bad
- });
+ var _pmc = _ref5;
- self.checkQueue(destination);
+ var pmc = self.addPMChannel(_pmc);
+ }
+
+ self.trigger("ready");
+ self.readyTime = Date.now();
+ self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users.");
+ self.state = 3;
+ setInterval(function () {
+ self.keepAlive.apply(self);
+ }, data.heartbeat_interval);
+
+ break;
+ case "MESSAGE_CREATE":
+ self.debug("received message");
+
+ var mentions = [];
+ data.mentions = data.mentions || []; //for some reason this was not defined at some point?
+ for (var _iterator6 = data.mentions, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) {
+ var _ref6;
+
+ if (_isArray6) {
+ if (_i6 >= _iterator6.length) break;
+ _ref6 = _iterator6[_i6++];
+ } else {
+ _i6 = _iterator6.next();
+ if (_i6.done) break;
+ _ref6 = _i6.value;
+ }
+
+ var mention = _ref6;
+
+ mentions.push(self.addUser(mention));
+ }
+
+ var channel = self.getChannel("id", data.channel_id);
+ if (channel) {
+ var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author)));
+ self.trigger("message", msg);
+ }
+
+ break;
+ case "MESSAGE_DELETE":
+ self.debug("message deleted");
+
+ var channel = self.getChannel("id", data.channel_id);
+ var message = channel.getMessage("id", data.id);
+ if (message) {
+ self.trigger("messageDelete", channel, message);
+ channel.messages.splice(channel.messages.indexOf(message), 1);
} else {
- //not queue
- self._sendFile(destination, fstream, fileName).then(good)["catch"](bad);
+ //don't have the cache of that message ;(
+ self.trigger("messageDelete", channel);
}
- }
+ break;
+ case "MESSAGE_UPDATE":
+ self.debug("message updated");
- function good(msg) {
- prom.message = msg;
- callback(null, msg);
- resolve(msg);
- }
+ var channel = self.getChannel("id", data.channel_id);
+ var formerMessage = channel.getMessage("id", data.id);
- function bad(err) {
- prom.error = err;
- callback(err);
- reject(err);
- }
- });
+ if (formerMessage) {
- return prom;
- }
- }, {
- key: "sendMessage",
- value: function sendMessage(destination, message) {
- var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2];
- var premessage = arguments.length <= 3 || arguments[3] === undefined ? "" : arguments[3];
+ //new message might be partial, so we need to fill it with whatever the old message was.
+ var info = {};
- var self = this;
-
- var prom = new Promise(function (resolve, reject) {
-
- message = premessage + resolveMessage(message);
- var mentions = resolveMentions();
- self.resolveDestination(destination).then(send)["catch"](error);
-
- function error(err) {
- callback(err);
- reject(err);
- }
-
- function send(destination) {
- if (self.options.queue) {
- //we're QUEUEING messages, so sending them sequentially based on servers.
- if (!self.queue[destination]) {
- self.queue[destination] = [];
+ for (var key in formerMessage) {
+ info[key] = formerMessage[key];
}
- self.queue[destination].push({
- action: "sendMessage",
- content: message,
- mentions: mentions,
- then: mgood,
- error: mbad
- });
-
- self.checkQueue(destination);
- } else {
- self._sendMessage(destination, message, mentions).then(mgood)["catch"](mbad);
- }
- }
-
- function mgood(msg) {
- prom.message = msg;
- callback(null, msg);
- resolve(msg);
- }
-
- function mbad(error) {
- prom.error = error;
- callback(error);
- reject(error);
- }
-
- function resolveMessage() {
- var msg = message;
- if (message instanceof Array) {
- msg = message.join("\n");
- }
- return msg;
- }
-
- function resolveMentions() {
- var _mentions = [];
- var _iteratorNormalCompletion3 = true;
- var _didIteratorError3 = false;
- var _iteratorError3 = undefined;
-
- try {
- for (var _iterator3 = (message.match(/<@[^>]*>/g) || [])[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
- var mention = _step3.value;
-
- _mentions.push(mention.substring(2, mention.length - 1));
+ for (var key in data) {
+ info[key] = data[key];
}
- } catch (err) {
- _didIteratorError3 = true;
- _iteratorError3 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion3 && _iterator3["return"]) {
- _iterator3["return"]();
- }
- } finally {
- if (_didIteratorError3) {
- throw _iteratorError3;
- }
- }
- }
-
- return _mentions;
- }
- });
-
- return prom;
- }
-
- //def createws
- }, {
- key: "createws",
- value: function createws(url) {
- if (this.websocket) return false;
-
- var self = this;
-
- //good to go
- this.websocket = new WebSocket(url);
-
- //open
- this.websocket.onopen = function () {
- self.trySendConnData(); //try connecting
- };
-
- //close
- this.websocket.onclose = function () {
- self.trigger("disconnected");
- };
-
- //message
- this.websocket.onmessage = function (e) {
-
- var dat = false,
- data = {};
-
- try {
- dat = JSON.parse(e.data);
- data = dat.d;
- } catch (err) {
- self.trigger("error", err, e);
- return;
- }
-
- //valid message
- switch (dat.t) {
-
- case "READY":
- self.debug("received ready packet");
-
- self.user = self.addUser(data.user);
-
- var _iteratorNormalCompletion4 = true;
- var _didIteratorError4 = false;
- var _iteratorError4 = undefined;
-
- try {
- for (var _iterator4 = data.guilds[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
- var _server = _step4.value;
-
- var server = self.addServer(_server);
- }
- } catch (err) {
- _didIteratorError4 = true;
- _iteratorError4 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion4 && _iterator4["return"]) {
- _iterator4["return"]();
- }
- } finally {
- if (_didIteratorError4) {
- throw _iteratorError4;
- }
- }
- }
-
- var _iteratorNormalCompletion5 = true;
- var _didIteratorError5 = false;
- var _iteratorError5 = undefined;
-
- try {
- for (var _iterator5 = data.private_channels[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
- var _pmc = _step5.value;
-
- var pmc = self.addPMChannel(_pmc);
- }
- } catch (err) {
- _didIteratorError5 = true;
- _iteratorError5 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion5 && _iterator5["return"]) {
- _iterator5["return"]();
- }
- } finally {
- if (_didIteratorError5) {
- throw _iteratorError5;
- }
- }
- }
-
- self.trigger("ready");
- self.readyTime = Date.now();
- self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users.");
- self.state = 3;
- setInterval(function () {
- self.keepAlive.apply(self);
- }, data.heartbeat_interval);
-
- break;
- case "MESSAGE_CREATE":
- self.debug("received message");
var mentions = [];
- data.mentions = data.mentions || []; //for some reason this was not defined at some point?
- var _iteratorNormalCompletion6 = true;
- var _didIteratorError6 = false;
- var _iteratorError6 = undefined;
+ for (var _iterator7 = info.mentions, _isArray7 = Array.isArray(_iterator7), _i7 = 0, _iterator7 = _isArray7 ? _iterator7 : _iterator7[Symbol.iterator]();;) {
+ var _ref7;
- try {
- for (var _iterator6 = data.mentions[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
- var mention = _step6.value;
-
- mentions.push(self.addUser(mention));
- }
- } catch (err) {
- _didIteratorError6 = true;
- _iteratorError6 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion6 && _iterator6["return"]) {
- _iterator6["return"]();
- }
- } finally {
- if (_didIteratorError6) {
- throw _iteratorError6;
- }
- }
- }
-
- var channel = self.getChannel("id", data.channel_id);
- if (channel) {
- var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author)));
- self.trigger("message", msg);
- }
-
- break;
- case "MESSAGE_DELETE":
- self.debug("message deleted");
-
- var channel = self.getChannel("id", data.channel_id);
- var message = channel.getMessage("id", data.id);
- if (message) {
- self.trigger("messageDelete", channel, message);
- channel.messages.splice(channel.messages.indexOf(message), 1);
- } else {
- //don't have the cache of that message ;(
- self.trigger("messageDelete", channel);
- }
- break;
- case "MESSAGE_UPDATE":
- self.debug("message updated");
-
- var channel = self.getChannel("id", data.channel_id);
- var formerMessage = channel.getMessage("id", data.id);
-
- if (formerMessage) {
-
- //new message might be partial, so we need to fill it with whatever the old message was.
- var info = {};
-
- for (var key in formerMessage) {
- info[key] = formerMessage[key];
- }
-
- for (var key in data) {
- info[key] = data[key];
- }
-
- var mentions = [];
- var _iteratorNormalCompletion7 = true;
- var _didIteratorError7 = false;
- var _iteratorError7 = undefined;
-
- try {
- for (var _iterator7 = info.mentions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
- var mention = _step7.value;
-
- mentions.push(self.addUser(mention));
- }
- } catch (err) {
- _didIteratorError7 = true;
- _iteratorError7 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion7 && _iterator7["return"]) {
- _iterator7["return"]();
- }
- } finally {
- if (_didIteratorError7) {
- throw _iteratorError7;
- }
- }
- }
-
- var newMessage = new Message(info, channel, mentions, formerMessage.author);
-
- self.trigger("messageUpdate", newMessage, formerMessage);
-
- channel.messages[channel.messages.indexOf(formerMessage)] = newMessage;
- }
-
- // message isn't in cache, and if it's a partial it could cause
- // all hell to break loose... best to just act as if nothing happened
-
- break;
-
- case "GUILD_DELETE":
-
- var server = self.getServer("id", data.id);
-
- if (server) {
- self.serverCache.splice(self.serverCache.indexOf(server), 1);
- self.trigger("serverDelete", server);
- }
-
- break;
-
- case "CHANNEL_DELETE":
-
- var channel = self.getChannel("id", data.id);
-
- if (channel) {
-
- var server = channel.server;
-
- if (server) {
-
- server.channels.splice(server.channels.indexOf(channel), 1);
- }
-
- self.trigger("channelDelete", channel);
-
- self.serverCache.splice(self.serverCache.indexOf(channel), 1);
- }
-
- break;
-
- case "GUILD_CREATE":
-
- var server = self.getServer("id", data.id);
-
- if (!server) {
- //if server doesn't already exist because duh
- server = self.addServer(data);
- } /*else if(server.channels.length === 0){
-
- var srv = new Server(data, self);
- for(channel of data.channels){
- srv.channels.push(new Channel(channel, data.id));
- }
- self.serverCache[self.serverCache.indexOf(server)] = srv;
-
- }*/
-
- if (self.serverCreateListener.get(data.id)) {
- var cbs = self.serverCreateListener.get(data.id);
- cbs[0](server); //promise then callback
- cbs[1](null, server); //legacy callback
- self.serverCreateListener["delete"](data.id);
- }
-
- self.trigger("serverCreate", server);
-
- break;
-
- case "CHANNEL_CREATE":
-
- var channel = self.getChannel("id", data.id);
-
- if (!channel) {
-
- var chann = self.addChannel(data, data.guild_id);
- var srv = self.getServer("id", data.guild_id);
- if (srv) {
- srv.addChannel(chann);
- }
- self.trigger("channelCreate", chann);
- }
-
- break;
-
- case "GUILD_MEMBER_ADD":
-
- var server = self.getServer("id", data.guild_id);
-
- if (server) {
-
- var user = self.addUser(data.user); //if for whatever reason it doesn't exist..
-
- if (! ~server.members.indexOf(user)) {
- server.members.push(user);
- }
-
- self.trigger("serverNewMember", user);
- }
-
- break;
-
- case "GUILD_MEMBER_REMOVE":
-
- var server = self.getServer("id", data.guild_id);
-
- if (server) {
-
- var user = self.addUser(data.user); //if for whatever reason it doesn't exist..
-
- if (~server.members.indexOf(user)) {
- server.members.splice(server.members.indexOf(user), 1);
- }
-
- self.trigger("serverRemoveMember", user);
- }
-
- break;
-
- case "USER_UPDATE":
-
- if (self.user && data.id === self.user.id) {
-
- var newUser = new User(data); //not actually adding to the cache
-
- self.trigger("userUpdate", newUser, self.user);
-
- if (~self.userCache.indexOf(self.user)) {
- self.userCache[self.userCache.indexOf(self.user)] = newUser;
- }
-
- self.user = newUser;
- }
-
- break;
-
- case "PRESENCE_UPDATE":
-
- var userInCache = self.getUser("id", data.user.id);
-
- if (userInCache) {
- //user exists
- var presenceUser = new User(data.user);
- if (presenceUser.equalsStrict(userInCache)) {
- //they're exactly the same, an actual presence update
- self.trigger("presence", {
- user: userInCache,
- status: data.status,
- server: self.getServer("id", data.guild_id),
- gameId: data.game_id
- });
+ if (_isArray7) {
+ if (_i7 >= _iterator7.length) break;
+ _ref7 = _iterator7[_i7++];
} else {
- //one of their details changed.
- self.trigger("userUpdate", userInCache, presenceUser);
- self.userCache[self.userCache.indexOf(userInCache)] = presenceUser;
- }
- }
-
- break;
-
- default:
- self.debug("received unknown packet");
- self.trigger("unknown", dat);
- break;
-
- }
- };
- }
-
- //def addUser
- }, {
- key: "addUser",
- value: function addUser(data) {
- if (!this.getUser("id", data.id)) {
- this.userCache.push(new User(data));
- }
- return this.getUser("id", data.id);
- }
-
- //def addChannel
- }, {
- key: "addChannel",
- value: function addChannel(data, serverId) {
- if (!this.getChannel("id", data.id)) {
- this.channelCache.push(new Channel(data, this.getServer("id", serverId)));
- }
- return this.getChannel("id", data.id);
- }
- }, {
- key: "addPMChannel",
- value: function addPMChannel(data) {
- if (!this.getPMChannel("id", data.id)) {
- this.pmChannelCache.push(new PMChannel(data, this));
- }
- return this.getPMChannel("id", data.id);
- }
-
- //def addServer
- }, {
- key: "addServer",
- value: function addServer(data) {
-
- var server = this.getServer("id", data.id);
-
- if (!server) {
- server = new Server(data, this);
- this.serverCache.push(server);
- if (data.channels) {
- var _iteratorNormalCompletion8 = true;
- var _didIteratorError8 = false;
- var _iteratorError8 = undefined;
-
- try {
- for (var _iterator8 = data.channels[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
- var channel = _step8.value;
-
- server.channels.push(this.addChannel(channel, server.id));
- }
- } catch (err) {
- _didIteratorError8 = true;
- _iteratorError8 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion8 && _iterator8["return"]) {
- _iterator8["return"]();
- }
- } finally {
- if (_didIteratorError8) {
- throw _iteratorError8;
- }
- }
- }
- }
- }
-
- return server;
- }
-
- //def getUser
- }, {
- key: "getUser",
- value: function getUser(key, value) {
- var _iteratorNormalCompletion9 = true;
- var _didIteratorError9 = false;
- var _iteratorError9 = undefined;
-
- try {
- for (var _iterator9 = this.userCache[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) {
- var user = _step9.value;
-
- if (user[key] === value) {
- return user;
- }
- }
- } catch (err) {
- _didIteratorError9 = true;
- _iteratorError9 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion9 && _iterator9["return"]) {
- _iterator9["return"]();
- }
- } finally {
- if (_didIteratorError9) {
- throw _iteratorError9;
- }
- }
- }
-
- return null;
- }
-
- //def getChannel
- }, {
- key: "getChannel",
- value: function getChannel(key, value) {
- var _iteratorNormalCompletion10 = true;
- var _didIteratorError10 = false;
- var _iteratorError10 = undefined;
-
- try {
- for (var _iterator10 = this.channelCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {
- var channel = _step10.value;
-
- if (channel[key] === value) {
- return channel;
- }
- }
- } catch (err) {
- _didIteratorError10 = true;
- _iteratorError10 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion10 && _iterator10["return"]) {
- _iterator10["return"]();
- }
- } finally {
- if (_didIteratorError10) {
- throw _iteratorError10;
- }
- }
- }
-
- return this.getPMChannel(key, value); //might be a PM
- }
- }, {
- key: "getPMChannel",
- value: function getPMChannel(key, value) {
- var _iteratorNormalCompletion11 = true;
- var _didIteratorError11 = false;
- var _iteratorError11 = undefined;
-
- try {
- for (var _iterator11 = this.pmChannelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) {
- var channel = _step11.value;
-
- if (channel[key] === value) {
- return channel;
- }
- }
- } catch (err) {
- _didIteratorError11 = true;
- _iteratorError11 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion11 && _iterator11["return"]) {
- _iterator11["return"]();
- }
- } finally {
- if (_didIteratorError11) {
- throw _iteratorError11;
- }
- }
- }
-
- return null;
- }
-
- //def getServer
- }, {
- key: "getServer",
- value: function getServer(key, value) {
- var _iteratorNormalCompletion12 = true;
- var _didIteratorError12 = false;
- var _iteratorError12 = undefined;
-
- try {
- for (var _iterator12 = this.serverCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) {
- var server = _step12.value;
-
- if (server[key] === value) {
- return server;
- }
- }
- } catch (err) {
- _didIteratorError12 = true;
- _iteratorError12 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion12 && _iterator12["return"]) {
- _iterator12["return"]();
- }
- } finally {
- if (_didIteratorError12) {
- throw _iteratorError12;
- }
- }
- }
-
- return null;
- }
-
- //def trySendConnData
- }, {
- key: "trySendConnData",
- value: function trySendConnData() {
-
- if (this.token && !this.alreadySentData) {
-
- this.alreadySentData = true;
-
- var data = {
- op: 2,
- d: {
- token: this.token,
- v: 2,
- properties: {
- "$os": "discord.js",
- "$browser": "discord.js",
- "$device": "discord.js",
- "$referrer": "",
- "$referring_domain": ""
- }
- }
- };
- this.websocket.send(JSON.stringify(data));
- }
- }
- }, {
- key: "resolveServerID",
- value: function resolveServerID(resource) {
-
- if (resource instanceof Server) {
- return resource.id;
- } else if (!isNaN(resource) && resource.length && resource.length === 17) {
- return resource;
- }
- }
- }, {
- key: "resolveDestination",
- value: function resolveDestination(destination) {
- var channId = false;
- var self = this;
-
- return new Promise(function (resolve, reject) {
- if (destination instanceof Server) {
- channId = destination.id; //general is the same as server id
- } else if (destination instanceof Channel) {
- channId = destination.id;
- } else if (destination instanceof Message) {
- channId = destination.channel.id;
- } else if (destination instanceof User) {
-
- //check if we have a PM
- var _iteratorNormalCompletion13 = true;
- var _didIteratorError13 = false;
- var _iteratorError13 = undefined;
-
- try {
- for (var _iterator13 = self.pmChannelCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) {
- var pmc = _step13.value;
-
- if (pmc.user.equals(destination)) {
- return pmc.id;
- }
+ _i7 = _iterator7.next();
+ if (_i7.done) break;
+ _ref7 = _i7.value;
}
- //we don't, at this point we're late
- } catch (err) {
- _didIteratorError13 = true;
- _iteratorError13 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion13 && _iterator13["return"]) {
- _iterator13["return"]();
- }
- } finally {
- if (_didIteratorError13) {
- throw _iteratorError13;
- }
- }
+ var mention = _ref7;
+
+ mentions.push(self.addUser(mention));
}
- self.startPM(destination).then(function (pmc) {
- resolve(pmc.id);
- })["catch"](reject);
- } else {
- channId = destination;
+ var newMessage = new Message(info, channel, mentions, formerMessage.author);
+
+ self.trigger("messageUpdate", newMessage, formerMessage);
+
+ channel.messages[channel.messages.indexOf(formerMessage)] = newMessage;
}
- if (channId) resolve(channId);
- });
- }
- }, {
- key: "_sendMessage",
- value: function _sendMessage(destination, content, mentions) {
- var self = this;
+ // message isn't in cache, and if it's a partial it could cause
+ // all hell to break loose... best to just act as if nothing happened
- return new Promise(function (resolve, reject) {
- request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({
- content: content,
- mentions: mentions
- }).end(function (err, res) {
+ break;
- if (err) {
- reject(err);
- } else {
- var data = res.body;
+ case "GUILD_DELETE":
- var mentions = [];
+ var server = self.getServer("id", data.id);
- data.mentions = data.mentions || []; //for some reason this was not defined at some point?
+ if (server) {
+ self.serverCache.splice(self.serverCache.indexOf(server), 1);
+ self.trigger("serverDelete", server);
+ }
- var _iteratorNormalCompletion14 = true;
- var _didIteratorError14 = false;
- var _iteratorError14 = undefined;
+ break;
- try {
- for (var _iterator14 = data.mentions[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) {
- var mention = _step14.value;
+ case "CHANNEL_DELETE":
- mentions.push(self.addUser(mention));
- }
- } catch (err) {
- _didIteratorError14 = true;
- _iteratorError14 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion14 && _iterator14["return"]) {
- _iterator14["return"]();
- }
- } finally {
- if (_didIteratorError14) {
- throw _iteratorError14;
- }
- }
+ var channel = self.getChannel("id", data.id);
+
+ if (channel) {
+
+ var server = channel.server;
+
+ if (server) {
+
+ server.channels.splice(server.channels.indexOf(channel), 1);
}
- var channel = self.getChannel("id", data.channel_id);
- if (channel) {
- var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author)));
- resolve(msg);
+ self.trigger("channelDelete", channel);
+
+ self.serverCache.splice(self.serverCache.indexOf(channel), 1);
+ }
+
+ break;
+
+ case "GUILD_CREATE":
+
+ var server = self.getServer("id", data.id);
+
+ if (!server) {
+ //if server doesn't already exist because duh
+ server = self.addServer(data);
+ } /*else if(server.channels.length === 0){
+
+ var srv = new Server(data, self);
+ for(channel of data.channels){
+ srv.channels.push(new Channel(channel, data.id));
+ }
+ self.serverCache[self.serverCache.indexOf(server)] = srv;
+
+ }*/
+
+ if (self.serverCreateListener[data.id]) {
+ var cbs = self.serverCreateListener[data.id];
+ cbs[0](server); //promise then callback
+ cbs[1](null, server); //legacy callback
+ self.serverCreateListener[data.id] = null;
+ }
+
+ self.trigger("serverCreate", server);
+
+ break;
+
+ case "CHANNEL_CREATE":
+
+ var channel = self.getChannel("id", data.id);
+
+ if (!channel) {
+
+ var chann;
+ if (data.is_private) {
+ chann = self.addPMChannel(data);
+ } else {
+ chann = self.addChannel(data, data.guild_id);
+ }
+ var srv = self.getServer("id", data.guild_id);
+ if (srv) {
+ srv.addChannel(chann);
+ }
+ self.trigger("channelCreate", chann);
+ }
+
+ break;
+
+ case "GUILD_MEMBER_ADD":
+
+ var server = self.getServer("id", data.guild_id);
+
+ if (server) {
+
+ var user = self.addUser(data.user); //if for whatever reason it doesn't exist..
+
+ self.trigger("serverNewMember", server.addMember(user, data.roles), server);
+ }
+
+ break;
+
+ case "GUILD_MEMBER_REMOVE":
+
+ var server = self.getServer("id", data.guild_id);
+
+ if (server) {
+
+ var user = self.addUser(data.user); //if for whatever reason it doesn't exist..
+
+ server.removeMember("id", user.id);
+
+ self.trigger("serverRemoveMember", user, server);
+ }
+
+ break;
+
+ case "USER_UPDATE":
+
+ if (self.user && data.id === self.user.id) {
+
+ var newUser = new User(data); //not actually adding to the cache
+
+ self.trigger("userUpdate", newUser, self.user);
+
+ if (~self.userCache.indexOf(self.user)) {
+ self.userCache[self.userCache.indexOf(self.user)] = newUser;
+ }
+
+ self.user = newUser;
+ }
+
+ break;
+
+ case "PRESENCE_UPDATE":
+
+ var userInCache = self.getUser("id", data.user.id);
+
+ if (userInCache) {
+ //user exists
+
+ data.user.username = data.user.username || userInCache.username;
+ data.user.id = data.user.id || userInCache.id;
+ data.user.discriminator = data.user.discriminator || userInCache.discriminator;
+ data.user.avatar = data.user.avatar || userInCache.avatar;
+
+ var presenceUser = new User(data.user);
+ if (presenceUser.equalsStrict(userInCache)) {
+ //they're exactly the same, an actual presence update
+ self.trigger("presence", {
+ user: userInCache,
+ oldStatus: userInCache.status,
+ status: data.status,
+ server: self.getServer("id", data.guild_id),
+ gameId: data.game_id
+ });
+ userInCache.status = data.status;
+ userInCache.gameId = data.game_id;
+ } else {
+ //one of their details changed.
+ self.userCache[self.userCache.indexOf(userInCache)] = presenceUser;
+ self.trigger("userUpdate", userInCache, presenceUser);
}
}
- });
- });
- }
- }, {
- key: "_sendFile",
- value: function _sendFile(destination, attachment) {
- var attachmentName = arguments.length <= 2 || arguments[2] === undefined ? "DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png" : arguments[2];
- var self = this;
+ break;
- return new Promise(function (resolve, reject) {
- request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).attach("file", attachment, attachmentName).end(function (err, res) {
+ case "CHANNEL_UPDATE":
- if (err) {
- reject(err);
- } else {
+ var channelInCache = self.getChannel("id", data.id),
+ serverInCache = self.getServer("id", data.guild_id);
- var chann = self.getChannel("id", destination);
- if (chann) {
- var msg = chann.addMessage(new Message(res.body, chann, [], self.user));
- resolve(msg);
- }
+ if (channelInCache && serverInCache) {
+
+ var newChann = new Channel(data, serverInCache);
+ newChann.messages = channelInCache.messages;
+
+ self.trigger("channelUpdate", channelInCache, newChann);
+
+ self.channelCache[self.channelCache.indexOf(channelInCache)] = newChann;
}
- });
- });
- }
- }, {
- key: "_updateMessage",
- value: function _updateMessage(message, content) {
- var self = this;
- return new Promise(function (resolve, reject) {
- request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).send({
- content: content,
- mentions: []
- }).end(function (err, res) {
- if (err) {
- reject(err);
- } else {
- var msg = new Message(res.body, message.channel, message.mentions, message.sender);
- resolve(msg);
- message.channel.messages[message.channel.messages.indexOf(message)] = msg;
- }
- });
- });
- }
- }, {
- key: "_deleteMessage",
- value: function _deleteMessage(message) {
- var self = this;
- return new Promise(function (resolve, reject) {
- request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).end(function (err, res) {
- if (err) {
- reject(err);
- } else {
- resolve();
- }
- });
- });
- }
- }, {
- key: "checkQueue",
- value: function checkQueue(channelID) {
- var _this = this;
- var self = this;
+ break;
- if (!this.checkingQueue[channelID]) {
- (function () {
- var doNext = function doNext() {
- if (self.queue[channelID].length === 0) {
- done();
+ case "TYPING_START":
+
+ var userInCache = self.getUser("id", data.user_id);
+ var channelInCache = self.getChannel("id", data.channel_id);
+
+ if (!self.userTypingListener[data.user_id] || self.userTypingListener[data.user_id] === -1) {
+ self.trigger("startTyping", userInCache, channelInCache);
+ }
+
+ self.userTypingListener[data.user_id] = Date.now();
+
+ setTimeout(function () {
+ if (self.userTypingListener[data.user_id] === -1) {
return;
}
- var queuedEvent = self.queue[channelID][0];
- switch (queuedEvent.action) {
- case "sendMessage":
- var msgToSend = queuedEvent;
- self._sendMessage(channelID, msgToSend.content, msgToSend.mentions).then(function (msg) {
- msgToSend.then(msg);
- self.queue[channelID].shift();
- doNext();
- })["catch"](function (err) {
- msgToSend.error(err);
- self.queue[channelID].shift();
- doNext();
- });
- break;
- case "sendFile":
- var fileToSend = queuedEvent;
- self._sendFile(channelID, fileToSend.attachment, fileToSend.attachmentName).then(function (msg) {
- fileToSend.then(msg);
- self.queue[channelID].shift();
- doNext();
- })["catch"](function (err) {
- fileToSend.error(err);
- self.queue[channelID].shift();
- doNext();
- });
- break;
- case "updateMessage":
- var msgToUpd = queuedEvent;
- self._updateMessage(msgToUpd.message, msgToUpd.content).then(function (msg) {
- msgToUpd.then(msg);
- self.queue[channelID].shift();
- doNext();
- })["catch"](function (err) {
- msgToUpd.error(err);
- self.queue[channelID].shift();
- doNext();
- });
- break;
- case "deleteMessage":
- var msgToDel = queuedEvent;
- self._deleteMessage(msgToDel.message).then(function (msg) {
- msgToDel.then(msg);
- self.queue[channelID].shift();
- doNext();
- })["catch"](function (err) {
- msgToDel.error(err);
- self.queue[channelID].shift();
- doNext();
- });
- break;
- default:
- done();
- break;
+ if (Date.now() - self.userTypingListener[data.user_id] > 6000) {
+ // stopped typing
+ self.trigger("stopTyping", userInCache, channelInCache);
+ self.userTypingListener[data.user_id] = -1;
}
- };
+ }, 6000);
- var done = function done() {
- self.checkingQueue[channelID] = false;
- return;
- };
+ break;
- //if we aren't already checking this queue.
- _this.checkingQueue[channelID] = true;
- doNext();
- })();
+ case "GUILD_ROLE_DELETE":
+
+ var server = self.getServer("id", data.guild_id);
+ var role = server.getRole(data.role_id);
+
+ self.trigger("serverRoleDelete", server, role);
+
+ server.removeRole(role.id);
+
+ break;
+
+ case "GUILD_ROLE_UPDATE":
+
+ var server = self.getServer("id", data.guild_id);
+ var role = server.getRole(data.role.id);
+ var newRole = server.updateRole(data.role);
+
+ self.trigger("serverRoleUpdate", server, role, newRole);
+
+ break;
+
+ default:
+ self.debug("received unknown packet");
+ self.trigger("unknown", dat);
+ break;
+
+ }
+ };
+ };
+
+ //def addUser
+
+ Client.prototype.addUser = function addUser(data) {
+ if (!this.getUser("id", data.id)) {
+ this.userCache.push(new User(data));
+ }
+ return this.getUser("id", data.id);
+ };
+
+ //def addChannel
+
+ Client.prototype.addChannel = function addChannel(data, serverId) {
+ if (!this.getChannel("id", data.id)) {
+ this.channelCache.push(new Channel(data, this.getServer("id", serverId)));
+ }
+ return this.getChannel("id", data.id);
+ };
+
+ Client.prototype.addPMChannel = function addPMChannel(data) {
+ if (!this.getPMChannel("id", data.id)) {
+ this.pmChannelCache.push(new PMChannel(data, this));
+ }
+ return this.getPMChannel("id", data.id);
+ };
+
+ Client.prototype.setTopic = function setTopic(channel, topic) {
+ var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err) {} : arguments[2];
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+
+ self.resolveDestination(channel).then(next)["catch"](error);
+
+ function error(e) {
+ callback(e);
+ reject(e);
+ }
+
+ function next(destination) {
+
+ var asChan = self.getChannel("id", destination);
+
+ request.patch(Endpoints.CHANNELS + "/" + destination).set("authorization", self.token).send({
+ name: asChan.name,
+ position: 0,
+ topic: topic
+ }).end(function (err, res) {
+ if (err) {
+ error(err);
+ } else {
+ asChan.topic = res.body.topic;
+ resolve();
+ callback();
+ }
+ });
+ }
+ });
+ };
+
+ //def addServer
+
+ Client.prototype.addServer = function addServer(data) {
+
+ var self = this;
+ var server = this.getServer("id", data.id);
+
+ if (data.unavailable) {
+ self.trigger("unavailable", data);
+ self.debug("Server ID " + data.id + " has been marked unavailable by Discord. It was not cached.");
+ return;
+ }
+
+ if (!server) {
+ server = new Server(data, this);
+ this.serverCache.push(server);
+ if (data.channels) {
+ for (var _iterator8 = data.channels, _isArray8 = Array.isArray(_iterator8), _i8 = 0, _iterator8 = _isArray8 ? _iterator8 : _iterator8[Symbol.iterator]();;) {
+ var _ref8;
+
+ if (_isArray8) {
+ if (_i8 >= _iterator8.length) break;
+ _ref8 = _iterator8[_i8++];
+ } else {
+ _i8 = _iterator8.next();
+ if (_i8.done) break;
+ _ref8 = _i8.value;
+ }
+
+ var channel = _ref8;
+
+ server.channels.push(this.addChannel(channel, server.id));
+ }
}
}
- }, {
+
+ for (var _iterator9 = data.presences, _isArray9 = Array.isArray(_iterator9), _i9 = 0, _iterator9 = _isArray9 ? _iterator9 : _iterator9[Symbol.iterator]();;) {
+ var _ref9;
+
+ if (_isArray9) {
+ if (_i9 >= _iterator9.length) break;
+ _ref9 = _iterator9[_i9++];
+ } else {
+ _i9 = _iterator9.next();
+ if (_i9.done) break;
+ _ref9 = _i9.value;
+ }
+
+ var presence = _ref9;
+
+ var user = self.getUser("id", presence.user.id);
+ user.status = presence.status;
+ user.gameId = presence.game_id;
+ }
+
+ return server;
+ };
+
+ //def getUser
+
+ Client.prototype.getUser = function getUser(key, value) {
+ for (var _iterator10 = this.userCache, _isArray10 = Array.isArray(_iterator10), _i10 = 0, _iterator10 = _isArray10 ? _iterator10 : _iterator10[Symbol.iterator]();;) {
+ var _ref10;
+
+ if (_isArray10) {
+ if (_i10 >= _iterator10.length) break;
+ _ref10 = _iterator10[_i10++];
+ } else {
+ _i10 = _iterator10.next();
+ if (_i10.done) break;
+ _ref10 = _i10.value;
+ }
+
+ var user = _ref10;
+
+ if (user[key] === value) {
+ return user;
+ }
+ }
+ return null;
+ };
+
+ //def getChannel
+
+ Client.prototype.getChannel = function getChannel(key, value) {
+ for (var _iterator11 = this.channelCache, _isArray11 = Array.isArray(_iterator11), _i11 = 0, _iterator11 = _isArray11 ? _iterator11 : _iterator11[Symbol.iterator]();;) {
+ var _ref11;
+
+ if (_isArray11) {
+ if (_i11 >= _iterator11.length) break;
+ _ref11 = _iterator11[_i11++];
+ } else {
+ _i11 = _iterator11.next();
+ if (_i11.done) break;
+ _ref11 = _i11.value;
+ }
+
+ var channel = _ref11;
+
+ if (channel[key] === value) {
+ return channel;
+ }
+ }
+ return this.getPMChannel(key, value); //might be a PM
+ };
+
+ Client.prototype.getPMChannel = function getPMChannel(key, value) {
+ for (var _iterator12 = this.pmChannelCache, _isArray12 = Array.isArray(_iterator12), _i12 = 0, _iterator12 = _isArray12 ? _iterator12 : _iterator12[Symbol.iterator]();;) {
+ var _ref12;
+
+ if (_isArray12) {
+ if (_i12 >= _iterator12.length) break;
+ _ref12 = _iterator12[_i12++];
+ } else {
+ _i12 = _iterator12.next();
+ if (_i12.done) break;
+ _ref12 = _i12.value;
+ }
+
+ var channel = _ref12;
+
+ if (channel[key] === value) {
+ return channel;
+ }
+ }
+ return null;
+ };
+
+ //def getServer
+
+ Client.prototype.getServer = function getServer(key, value) {
+ for (var _iterator13 = this.serverCache, _isArray13 = Array.isArray(_iterator13), _i13 = 0, _iterator13 = _isArray13 ? _iterator13 : _iterator13[Symbol.iterator]();;) {
+ var _ref13;
+
+ if (_isArray13) {
+ if (_i13 >= _iterator13.length) break;
+ _ref13 = _iterator13[_i13++];
+ } else {
+ _i13 = _iterator13.next();
+ if (_i13.done) break;
+ _ref13 = _i13.value;
+ }
+
+ var server = _ref13;
+
+ if (server[key] === value) {
+ return server;
+ }
+ }
+ return null;
+ };
+
+ //def trySendConnData
+
+ Client.prototype.trySendConnData = function trySendConnData() {
+
+ if (this.token && !this.alreadySentData) {
+
+ this.alreadySentData = true;
+
+ var data = {
+ op: 2,
+ d: {
+ token: this.token,
+ v: 3,
+ properties: {
+ "$os": "discord.js",
+ "$browser": "discord.js",
+ "$device": "discord.js",
+ "$referrer": "",
+ "$referring_domain": ""
+ }
+ }
+ };
+ this.websocket.send(JSON.stringify(data));
+ }
+ };
+
+ Client.prototype.resolveServerID = function resolveServerID(resource) {
+
+ if (resource instanceof Server) {
+ return resource.id;
+ } else if (!isNaN(resource) && resource.length && resource.length === 17) {
+ return resource;
+ }
+ };
+
+ Client.prototype.resolveDestination = function resolveDestination(destination) {
+ var channId = false;
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ if (destination instanceof Server) {
+ channId = destination.id; //general is the same as server id
+ } else if (destination instanceof Channel) {
+ channId = destination.id;
+ } else if (destination instanceof Message) {
+ channId = destination.channel.id;
+ } else if (destination instanceof PMChannel) {
+ channId = destination.id;
+ } else if (destination instanceof User) {
+
+ //check if we have a PM
+ for (var _iterator14 = self.pmChannelCache, _isArray14 = Array.isArray(_iterator14), _i14 = 0, _iterator14 = _isArray14 ? _iterator14 : _iterator14[Symbol.iterator]();;) {
+ var _ref14;
+
+ if (_isArray14) {
+ if (_i14 >= _iterator14.length) break;
+ _ref14 = _iterator14[_i14++];
+ } else {
+ _i14 = _iterator14.next();
+ if (_i14.done) break;
+ _ref14 = _i14.value;
+ }
+
+ var pmc = _ref14;
+
+ if (pmc.user && pmc.user.equals(destination)) {
+ resolve(pmc.id);
+ return;
+ }
+ }
+
+ //we don't, at this point we're late
+ self.startPM(destination).then(function (pmc) {
+ resolve(pmc.id);
+ })["catch"](reject);
+ } else {
+ channId = destination;
+ }
+ if (channId) resolve(channId);else reject();
+ });
+ };
+
+ Client.prototype._sendMessage = function _sendMessage(destination, content, tts, mentions) {
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({
+ content: content,
+ mentions: mentions,
+ tts: tts
+ }).end(function (err, res) {
+
+ if (err) {
+ reject(err);
+ } else {
+ var data = res.body;
+
+ var mentions = [];
+
+ data.mentions = data.mentions || []; //for some reason this was not defined at some point?
+
+ for (var _iterator15 = data.mentions, _isArray15 = Array.isArray(_iterator15), _i15 = 0, _iterator15 = _isArray15 ? _iterator15 : _iterator15[Symbol.iterator]();;) {
+ var _ref15;
+
+ if (_isArray15) {
+ if (_i15 >= _iterator15.length) break;
+ _ref15 = _iterator15[_i15++];
+ } else {
+ _i15 = _iterator15.next();
+ if (_i15.done) break;
+ _ref15 = _i15.value;
+ }
+
+ var mention = _ref15;
+
+ mentions.push(self.addUser(mention));
+ }
+
+ var channel = self.getChannel("id", data.channel_id);
+ if (channel) {
+ var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author)));
+ resolve(msg);
+ }
+ }
+ });
+ });
+ };
+
+ Client.prototype._sendFile = function _sendFile(destination, attachment) {
+ var attachmentName = arguments.length <= 2 || arguments[2] === undefined ? "DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png" : arguments[2];
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).attach("file", attachment, attachmentName).end(function (err, res) {
+
+ if (err) {
+ reject(err);
+ } else {
+
+ var chann = self.getChannel("id", destination);
+ if (chann) {
+ var msg = chann.addMessage(new Message(res.body, chann, [], self.user));
+ resolve(msg);
+ }
+ }
+ });
+ });
+ };
+
+ Client.prototype._updateMessage = function _updateMessage(message, content) {
+ var self = this;
+ return new Promise(function (resolve, reject) {
+ request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).send({
+ content: content,
+ mentions: []
+ }).end(function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ var msg = new Message(res.body, message.channel, message.mentions, message.sender);
+ resolve(msg);
+ message.channel.messages[message.channel.messages.indexOf(message)] = msg;
+ }
+ });
+ });
+ };
+
+ Client.prototype.getGateway = function getGateway() {
+ var self = this;
+ return new Promise(function (resolve, reject) {
+ request.get(Endpoints.API + "/gateway").set("authorization", self.token).end(function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ resolve(res.body.url);
+ }
+ });
+ });
+ };
+
+ Client.prototype.setStatusIdle = function setStatusIdle() {
+ this.setStatus("idle");
+ };
+
+ Client.prototype.setStatusOnline = function setStatusOnline() {
+ this.setStatus("online");
+ };
+
+ Client.prototype.setStatusActive = function setStatusActive() {
+ this.setStatusOnline();
+ };
+
+ Client.prototype.setStatusHere = function setStatusHere() {
+ this.setStatusOnline();
+ };
+
+ Client.prototype.setStatusAway = function setStatusAway() {
+ this.setStatusIdle();
+ };
+
+ Client.prototype.startTyping = function startTyping(chann, stopTypeTime) {
+ var self = this;
+
+ this.resolveDestination(chann).then(next);
+
+ function next(channel) {
+ if (self.typingIntervals[channel]) {
+ return;
+ }
+
+ var fn = function fn() {
+ request.post(Endpoints.CHANNELS + "/" + channel + "/typing").set("authorization", self.token).end();
+ };
+
+ fn();
+
+ var interval = setInterval(fn, 3000);
+
+ self.typingIntervals[channel] = interval;
+
+ if (stopTypeTime) {
+ setTimeout(function () {
+ self.stopTyping(channel);
+ }, stopTypeTime);
+ }
+ }
+ };
+
+ Client.prototype.stopTyping = function stopTyping(chann) {
+ var self = this;
+
+ this.resolveDestination(chann).then(next);
+
+ function next(channel) {
+ if (!self.typingIntervals[channel]) {
+ return;
+ }
+
+ clearInterval(self.typingIntervals[channel]);
+
+ delete self.typingIntervals[channel];
+ }
+ };
+
+ Client.prototype.setStatus = function setStatus(stat) {
+
+ var idleTime = stat === "online" ? null : Date.now();
+
+ this.__idleTime = idleTime;
+
+ this.websocket.send(JSON.stringify({
+ op: 3,
+ d: {
+ idle_since: this.__idleTime,
+ game_id: this.__gameId
+ }
+ }));
+ };
+
+ Client.prototype.setPlayingGame = function setPlayingGame(id) {
+
+ if (id instanceof String || typeof id === "string") {
+
+ // working on names
+ var gid = id.trim().toUpperCase();
+
+ id = null;
+
+ for (var _iterator16 = gameMap, _isArray16 = Array.isArray(_iterator16), _i16 = 0, _iterator16 = _isArray16 ? _iterator16 : _iterator16[Symbol.iterator]();;) {
+ var _ref16;
+
+ if (_isArray16) {
+ if (_i16 >= _iterator16.length) break;
+ _ref16 = _iterator16[_i16++];
+ } else {
+ _i16 = _iterator16.next();
+ if (_i16.done) break;
+ _ref16 = _i16.value;
+ }
+
+ var game = _ref16;
+
+ if (game.name.trim().toUpperCase() === gid) {
+
+ id = game.id;
+ break;
+ }
+ }
+ }
+
+ this.__gameId = id;
+
+ this.websocket.send(JSON.stringify({
+ op: 3,
+ d: {
+ idle_since: this.__idleTime,
+ game_id: this.__gameId
+ }
+ }));
+ };
+
+ Client.prototype.playGame = function playGame(id) {
+ this.setPlayingGame(id);
+ };
+
+ Client.prototype.playingGame = function playingGame(id) {
+
+ this.setPlayingGame(id);
+ };
+
+ _createClass(Client, [{
key: "uptime",
get: function get() {
@@ -1617,31 +1679,22 @@ var Client = (function () {
get: function get() {
var msgs = [];
- var _iteratorNormalCompletion15 = true;
- var _didIteratorError15 = false;
- var _iteratorError15 = undefined;
+ for (var _iterator17 = this.channelCache, _isArray17 = Array.isArray(_iterator17), _i17 = 0, _iterator17 = _isArray17 ? _iterator17 : _iterator17[Symbol.iterator]();;) {
+ var _ref17;
- try {
- for (var _iterator15 = this.channelCache[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) {
- var channel = _step15.value;
+ if (_isArray17) {
+ if (_i17 >= _iterator17.length) break;
+ _ref17 = _iterator17[_i17++];
+ } else {
+ _i17 = _iterator17.next();
+ if (_i17.done) break;
+ _ref17 = _i17.value;
+ }
- msgs = msgs.concat(channel.messages);
- }
- } catch (err) {
- _didIteratorError15 = true;
- _iteratorError15 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion15 && _iterator15["return"]) {
- _iterator15["return"]();
- }
- } finally {
- if (_didIteratorError15) {
- throw _iteratorError15;
- }
- }
+ var channel = _ref17;
+
+ msgs = msgs.concat(channel.messages);
}
-
return msgs;
}
}]);
@@ -1649,19 +1702,4 @@ var Client = (function () {
return Client;
})();
-function getGateway() {
-
- var self = this;
-
- return new Promise(function (resolve, reject) {
- request.get(Endpoints.API + "/gateway").end(function (err, res) {
- if (err) {
- reject(err);
- } else {
- resolve(res.body.url);
- }
- });
- });
-}
-
module.exports = Client;
\ No newline at end of file
diff --git a/lib/EvaluatedPermissions.js b/lib/EvaluatedPermissions.js
new file mode 100644
index 000000000..c4720c46b
--- /dev/null
+++ b/lib/EvaluatedPermissions.js
@@ -0,0 +1,187 @@
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var EvaluatedPermissions = (function () {
+ function EvaluatedPermissions(data) {
+ _classCallCheck(this, EvaluatedPermissions);
+
+ var self = this;
+
+ this.packed = data;
+
+ if (this.getBit(3)) this.packed = 4294967295;
+ }
+
+ EvaluatedPermissions.prototype.serialise = function serialise() {
+ return {
+ createInstantInvite: this.createInstantInvite,
+ manageRoles: this.manageRoles,
+ manageChannels: this.manageChannels,
+ readMessages: this.readMessages,
+ sendMessages: this.sendMessage,
+ sendTTSMessages: this.sendTTSMessages,
+ manageMessages: this.manageMessages,
+ embedLinks: this.embedLinks,
+ attachFiles: this.attachFiles,
+ readMessageHistory: this.readMessageHistory,
+ mentionEveryone: this.mentionEveryone,
+ voiceConnect: this.voiceConnect,
+ voiceSpeak: this.voiceSpeak,
+ voiceMuteMembers: this.voiceMuteMembers,
+ voiceDeafenMembers: this.voiceDeafenMembers,
+ voiceMoveMember: this.voiceMoveMembers,
+ voiceUseVoiceActivation: this.voiceUseVoiceActivation
+ };
+ };
+
+ EvaluatedPermissions.prototype.getBit = function getBit(x) {
+ return (this.packed >>> x & 1) === 1;
+ };
+
+ EvaluatedPermissions.prototype.setBit = function setBit() {};
+
+ _createClass(EvaluatedPermissions, [{
+ key: "createInstantInvite",
+ get: function get() {
+ return this.getBit(0);
+ },
+ set: function set(val) {
+ this.setBit(0, val);
+ }
+ }, {
+ key: "manageRoles",
+ get: function get() {
+ return this.getBit(3);
+ },
+ set: function set(val) {
+ this.setBit(3, val);
+ }
+ }, {
+ key: "manageChannels",
+ get: function get() {
+ return this.getBit(4);
+ },
+ set: function set(val) {
+ this.setBit(4, val);
+ }
+ }, {
+ key: "readMessages",
+ get: function get() {
+ return this.getBit(10);
+ },
+ set: function set(val) {
+ this.setBit(10, val);
+ }
+ }, {
+ key: "sendMessages",
+ get: function get() {
+ return this.getBit(11);
+ },
+ set: function set(val) {
+ this.setBit(11, val);
+ }
+ }, {
+ key: "sendTTSMessages",
+ get: function get() {
+ return this.getBit(12);
+ },
+ set: function set(val) {
+ this.setBit(12, val);
+ }
+ }, {
+ key: "manageMessages",
+ get: function get() {
+ return this.getBit(13);
+ },
+ set: function set(val) {
+ this.setBit(13, val);
+ }
+ }, {
+ key: "embedLinks",
+ get: function get() {
+ return this.getBit(14);
+ },
+ set: function set(val) {
+ this.setBit(14, val);
+ }
+ }, {
+ key: "attachFiles",
+ get: function get() {
+ return this.getBit(15);
+ },
+ set: function set(val) {
+ this.setBit(15, val);
+ }
+ }, {
+ key: "readMessageHistory",
+ get: function get() {
+ return this.getBit(16);
+ },
+ set: function set(val) {
+ this.setBit(16, val);
+ }
+ }, {
+ key: "mentionEveryone",
+ get: function get() {
+ return this.getBit(17);
+ },
+ set: function set(val) {
+ this.setBit(17, val);
+ }
+ }, {
+ key: "voiceConnect",
+ get: function get() {
+ return this.getBit(20);
+ },
+ set: function set(val) {
+ this.setBit(20, val);
+ }
+ }, {
+ key: "voiceSpeak",
+ get: function get() {
+ return this.getBit(21);
+ },
+ set: function set(val) {
+ this.setBit(21, val);
+ }
+ }, {
+ key: "voiceMuteMembers",
+ get: function get() {
+ return this.getBit(22);
+ },
+ set: function set(val) {
+ this.setBit(22, val);
+ }
+ }, {
+ key: "voiceDeafenMembers",
+ get: function get() {
+ return this.getBit(23);
+ },
+ set: function set(val) {
+ this.setBit(23, val);
+ }
+ }, {
+ key: "voiceMoveMembers",
+ get: function get() {
+ return this.getBit(24);
+ },
+ set: function set(val) {
+ this.setBit(24, val);
+ }
+ }, {
+ key: "voiceUseVoiceActivation",
+ get: function get() {
+ return this.getBit(25);
+ },
+ set: function set(val) {
+ this.setBit(25, val);
+ }
+ }]);
+
+ return EvaluatedPermissions;
+})();
+
+module.exports = EvaluatedPermissions;
\ No newline at end of file
diff --git a/lib/Member.js b/lib/Member.js
new file mode 100644
index 000000000..813acda1b
--- /dev/null
+++ b/lib/Member.js
@@ -0,0 +1,157 @@
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+var User = require("./user.js");
+var ServerPermissions = require("./ServerPermissions.js");
+var EvaluatedPermissions = require("./EvaluatedPermissions.js");
+
+var Member = (function (_User) {
+ _inherits(Member, _User);
+
+ function Member(user, server, roles) {
+ _classCallCheck(this, Member);
+
+ _User.call(this, user); // should work, we are basically creating a Member that has the same properties as user and a few more
+ this.server = server;
+ this.rawRoles = roles;
+ }
+
+ Member.prototype.permissionsIn = function permissionsIn(channel) {
+
+ if (channel.server.ownerID === this.id) {
+ return new EvaluatedPermissions(4294967295); //all perms
+ }
+
+ var affectingOverwrites = [];
+ var affectingMemberOverwrites = [];
+
+ for (var _iterator = channel.roles, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
+ var _ref;
+
+ if (_isArray) {
+ if (_i >= _iterator.length) break;
+ _ref = _iterator[_i++];
+ } else {
+ _i = _iterator.next();
+ if (_i.done) break;
+ _ref = _i.value;
+ }
+
+ var overwrite = _ref;
+
+ if (overwrite.id === this.id && overwrite.type === "member") {
+ affectingMemberOverwrites.push(overwrite);
+ } else if (this.rawRoles.indexOf(overwrite.id) !== -1) {
+ affectingOverwrites.push(overwrite);
+ }
+ }
+
+ if (affectingOverwrites.length === 0 && affectingMemberOverwrites.length === 0) {
+ return new EvaluatedPermissions(this.evalPerms.packed);
+ }
+
+ var finalPacked = affectingOverwrites.length !== 0 ? affectingOverwrites[0].packed : affectingMemberOverwrites[0].packed;
+
+ for (var _iterator2 = affectingOverwrites, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
+ var _ref2;
+
+ if (_isArray2) {
+ if (_i2 >= _iterator2.length) break;
+ _ref2 = _iterator2[_i2++];
+ } else {
+ _i2 = _iterator2.next();
+ if (_i2.done) break;
+ _ref2 = _i2.value;
+ }
+
+ var overwrite = _ref2;
+
+ finalPacked = finalPacked & ~overwrite.deny;
+ finalPacked = finalPacked | overwrite.allow;
+ }
+
+ for (var _iterator3 = affectingMemberOverwrites, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
+ var _ref3;
+
+ if (_isArray3) {
+ if (_i3 >= _iterator3.length) break;
+ _ref3 = _iterator3[_i3++];
+ } else {
+ _i3 = _iterator3.next();
+ if (_i3.done) break;
+ _ref3 = _i3.value;
+ }
+
+ var overwrite = _ref3;
+
+ finalPacked = finalPacked & ~overwrite.deny;
+ finalPacked = finalPacked | overwrite.allow;
+ }
+
+ return new EvaluatedPermissions(finalPacked);
+ };
+
+ _createClass(Member, [{
+ key: "roles",
+ get: function get() {
+
+ var ufRoles = [this.server.getRole(this.server.id)];
+
+ for (var _iterator4 = this.rawRoles, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
+ var _ref4;
+
+ if (_isArray4) {
+ if (_i4 >= _iterator4.length) break;
+ _ref4 = _iterator4[_i4++];
+ } else {
+ _i4 = _iterator4.next();
+ if (_i4.done) break;
+ _ref4 = _i4.value;
+ }
+
+ var rawRole = _ref4;
+
+ ufRoles.push(this.server.getRole(rawRole));
+ }
+
+ return ufRoles;
+ }
+ }, {
+ key: "evalPerms",
+ get: function get() {
+ var basePerms = this.roles,
+ //cache roles as it can be slightly expensive
+ basePerm = basePerms[0].packed;
+
+ for (var _iterator5 = basePerms, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {
+ var _ref5;
+
+ if (_isArray5) {
+ if (_i5 >= _iterator5.length) break;
+ _ref5 = _iterator5[_i5++];
+ } else {
+ _i5 = _iterator5.next();
+ if (_i5.done) break;
+ _ref5 = _i5.value;
+ }
+
+ var perm = _ref5;
+
+ basePerm = basePerm | perm.packed;
+ }
+
+ return new ServerPermissions({
+ permissions: basePerm
+ });
+ }
+ }]);
+
+ return Member;
+})(User);
+
+module.exports = Member;
\ No newline at end of file
diff --git a/lib/PMChannel.js b/lib/PMChannel.js
index ae44d3d60..06d1c120b 100644
--- a/lib/PMChannel.js
+++ b/lib/PMChannel.js
@@ -11,47 +11,47 @@ var PMChannel = (function () {
this.user = client.getUser("id", data.recipient.id);
this.id = data.id;
this.messages = [];
+ this.client = client;
}
- _createClass(PMChannel, [{
- key: "addMessage",
- value: function addMessage(data) {
- if (!this.getMessage("id", data.id)) {
- this.messages.push(data);
- }
- return this.getMessage("id", data.id);
+ PMChannel.prototype.addMessage = function addMessage(data) {
+ if (!this.getMessage("id", data.id)) {
+ this.messages.push(data);
}
- }, {
- key: "getMessage",
- value: function getMessage(key, value) {
- var _iteratorNormalCompletion = true;
- var _didIteratorError = false;
- var _iteratorError = undefined;
+ return this.getMessage("id", data.id);
+ };
- try {
- for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
- var message = _step.value;
+ PMChannel.prototype.getMessage = function getMessage(key, value) {
- if (message[key] === value) {
- return message;
- }
- }
- } catch (err) {
- _didIteratorError = true;
- _iteratorError = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion && _iterator["return"]) {
- _iterator["return"]();
- }
- } finally {
- if (_didIteratorError) {
- throw _iteratorError;
- }
- }
+ if (this.messages.length > 1000) {
+ this.messages.splice(0, 1);
+ }
+
+ for (var _iterator = this.messages, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
+ var _ref;
+
+ if (_isArray) {
+ if (_i >= _iterator.length) break;
+ _ref = _iterator[_i++];
+ } else {
+ _i = _iterator.next();
+ if (_i.done) break;
+ _ref = _i.value;
}
- return null;
+ var message = _ref;
+
+ if (message[key] === value) {
+ return message;
+ }
+ }
+ return null;
+ };
+
+ _createClass(PMChannel, [{
+ key: "isPrivate",
+ get: function get() {
+ return true;
}
}]);
diff --git a/lib/Permissions.js b/lib/Permissions.js
new file mode 100644
index 000000000..a1f4f3083
--- /dev/null
+++ b/lib/Permissions.js
@@ -0,0 +1,48 @@
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Permission = (function () {
+ function Permission(packedPermissions) {
+ _classCallCheck(this, Permission);
+
+ function getBit(x) {
+ return (this.packed >>> x & 1) === 1;
+ }
+
+ this.packed = packedPermissions;
+
+ this.createInstantInvite = getBit(0);
+ this.banMembers = getBit(1);
+ this.kickMembers = getBit(2);
+ this.manageRoles = getBit(3);
+ this.manageChannels = getBit(4);
+ this.manageServer = getBit(5);
+ this.readMessages = getBit(10);
+ this.sendMessages = getBit(11);
+ this.sendTTSMessages = getBit(12);
+ this.manageMessages = getBit(13);
+ this.embedLinks = getBit(14);
+ this.attachFiles = getBit(15);
+ this.readMessageHistory = getBit(16);
+ this.mentionEveryone = getBit(17);
+
+ this.voiceConnect = getBit(20);
+ this.voiceSpeak = getBit(21);
+ this.voiceMuteMembers = getBit(22);
+ this.voiceDeafenMembers = getBit(23);
+ this.voiceMoveMembers = getBit(24);
+ this.voiceUseVoiceActivation = getBit(26);
+ }
+
+ _createClass(Permission, [{
+ key: "getBit",
+ value: function getBit(x) {
+ return (this.packed >>> x & 1) === 1;
+ }
+ }]);
+
+ return Permission;
+})();
\ No newline at end of file
diff --git a/lib/ServerPermissions.js b/lib/ServerPermissions.js
new file mode 100644
index 000000000..6384f759b
--- /dev/null
+++ b/lib/ServerPermissions.js
@@ -0,0 +1,199 @@
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var ServerPermissions = (function () {
+ function ServerPermissions(data) {
+ _classCallCheck(this, ServerPermissions);
+
+ var self = this;
+
+ function getBit(x) {
+ return (self.packed >>> x & 1) === 1;
+ }
+
+ this.packed = data.permissions;
+ this.name = data.name;
+ this.id = data.id;
+ }
+
+ ServerPermissions.prototype.getBit = function getBit(x) {
+ return (this.packed >>> x & 1) === 1;
+ };
+
+ ServerPermissions.prototype.setBit = function setBit() {
+ //dummy function for now
+ };
+
+ ServerPermissions.prototype.toString = function toString() {
+ return this.name;
+ };
+
+ _createClass(ServerPermissions, [{
+ key: "createInstantInvite",
+ get: function get() {
+ return this.getBit(0);
+ },
+ set: function set(val) {
+ this.setBit(0, val);
+ }
+ }, {
+ key: "banMembers",
+ get: function get() {
+ return this.getBit(1);
+ },
+ set: function set(val) {
+ this.setBit(1, val);
+ }
+ }, {
+ key: "kickMembers",
+ get: function get() {
+ return this.getBit(2);
+ },
+ set: function set(val) {
+ this.setBit(2, val);
+ }
+ }, {
+ key: "manageRoles",
+ get: function get() {
+ return this.getBit(3);
+ },
+ set: function set(val) {
+ this.setBit(3, val);
+ }
+ }, {
+ key: "manageChannels",
+ get: function get() {
+ return this.getBit(4);
+ },
+ set: function set(val) {
+ this.setBit(4, val);
+ }
+ }, {
+ key: "manageServer",
+ get: function get() {
+ return this.getBit(5);
+ },
+ set: function set(val) {
+ this.setBit(5, val);
+ }
+ }, {
+ key: "readMessages",
+ get: function get() {
+ return this.getBit(10);
+ },
+ set: function set(val) {
+ this.setBit(10, val);
+ }
+ }, {
+ key: "sendMessages",
+ get: function get() {
+ return this.getBit(11);
+ },
+ set: function set(val) {
+ this.setBit(11, val);
+ }
+ }, {
+ key: "sendTTSMessages",
+ get: function get() {
+ return this.getBit(12);
+ },
+ set: function set(val) {
+ this.setBit(12, val);
+ }
+ }, {
+ key: "manageMessages",
+ get: function get() {
+ return this.getBit(13);
+ },
+ set: function set(val) {
+ this.setBit(13, val);
+ }
+ }, {
+ key: "embedLinks",
+ get: function get() {
+ return this.getBit(14);
+ },
+ set: function set(val) {
+ this.setBit(14, val);
+ }
+ }, {
+ key: "attachFiles",
+ get: function get() {
+ return this.getBit(15);
+ },
+ set: function set(val) {
+ this.setBit(15, val);
+ }
+ }, {
+ key: "readMessageHistory",
+ get: function get() {
+ return this.getBit(16);
+ },
+ set: function set(val) {
+ this.setBit(16, val);
+ }
+ }, {
+ key: "mentionEveryone",
+ get: function get() {
+ return this.getBit(17);
+ },
+ set: function set(val) {
+ this.setBit(17, val);
+ }
+ }, {
+ key: "voiceConnect",
+ get: function get() {
+ return this.getBit(20);
+ },
+ set: function set(val) {
+ this.setBit(20, val);
+ }
+ }, {
+ key: "voiceSpeak",
+ get: function get() {
+ return this.getBit(21);
+ },
+ set: function set(val) {
+ this.setBit(21, val);
+ }
+ }, {
+ key: "voiceMuteMembers",
+ get: function get() {
+ return this.getBit(22);
+ },
+ set: function set(val) {
+ this.setBit(22, val);
+ }
+ }, {
+ key: "voiceDeafenMembers",
+ get: function get() {
+ return this.getBit(23);
+ },
+ set: function set(val) {
+ this.setBit(23, val);
+ }
+ }, {
+ key: "voiceMoveMembers",
+ get: function get() {
+ return this.getBit(24);
+ },
+ set: function set(val) {
+ this.setBit(24, val);
+ }
+ }, {
+ key: "voiceUseVoiceActivation",
+ get: function get() {
+ return this.getBit(25);
+ },
+ set: function set(val) {
+ this.setBit(25, val);
+ }
+ }]);
+
+ return ServerPermissions;
+})();
+
+module.exports = ServerPermissions;
\ No newline at end of file
diff --git a/lib/channel.js b/lib/channel.js
index f94925f0c..7b8b1c027 100644
--- a/lib/channel.js
+++ b/lib/channel.js
@@ -4,6 +4,8 @@ var _createClass = (function () { function defineProperties(target, props) { for
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+var ChannelPermissions = require("./ChannelPermissions.js");
+
var Channel = (function () {
function Channel(data, server) {
_classCallCheck(this, Channel);
@@ -11,66 +13,115 @@ var Channel = (function () {
this.server = server;
this.name = data.name;
this.type = data.type;
+ this.topic = data.topic;
this.id = data.id;
this.messages = [];
+ this.roles = [];
+
+ if (data.permission_overwrites) for (var _iterator = data.permission_overwrites, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
+ var _ref;
+
+ if (_isArray) {
+ if (_i >= _iterator.length) break;
+ _ref = _iterator[_i++];
+ } else {
+ _i = _iterator.next();
+ if (_i.done) break;
+ _ref = _i.value;
+ }
+
+ var role = _ref;
+
+ this.roles.push(new ChannelPermissions(role, this));
+ }
+
//this.isPrivate = isPrivate; //not sure about the implementation of this...
}
- _createClass(Channel, [{
- key: "equals",
- value: function equals(object) {
- return object && object.id === this.id;
- }
- }, {
- key: "addMessage",
- value: function addMessage(data) {
- if (!this.getMessage("id", data.id)) {
- this.messages.push(data);
- }
- return this.getMessage("id", data.id);
- }
- }, {
- key: "getMessage",
- value: function getMessage(key, value) {
- var _iteratorNormalCompletion = true;
- var _didIteratorError = false;
- var _iteratorError = undefined;
+ Channel.prototype.permissionsOf = function permissionsOf(member) {
- try {
- for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
- var message = _step.value;
-
- if (message[key] === value) {
- return message;
- }
- }
- } catch (err) {
- _didIteratorError = true;
- _iteratorError = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion && _iterator["return"]) {
- _iterator["return"]();
- }
- } finally {
- if (_didIteratorError) {
- throw _iteratorError;
- }
- }
- }
+ var mem = this.server.getMember("id", member.id);
+ if (mem) {
+ return mem.permissionsIn(this);
+ } else {
return null;
}
+ };
+
+ Channel.prototype.equals = function equals(object) {
+ return object && object.id === this.id;
+ };
+
+ Channel.prototype.addMessage = function addMessage(data) {
+
+ if (this.messages.length > 1000) {
+ this.messages.splice(0, 1);
+ }
+
+ if (!this.getMessage("id", data.id)) {
+ this.messages.push(data);
+ }
+
+ return this.getMessage("id", data.id);
+ };
+
+ Channel.prototype.getMessage = function getMessage(key, value) {
+ for (var _iterator2 = this.messages, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
+ var _ref2;
+
+ if (_isArray2) {
+ if (_i2 >= _iterator2.length) break;
+ _ref2 = _iterator2[_i2++];
+ } else {
+ _i2 = _iterator2.next();
+ if (_i2.done) break;
+ _ref2 = _i2.value;
+ }
+
+ var message = _ref2;
+
+ if (message[key] === value) {
+ return message;
+ }
+ }
+ return null;
+ };
+
+ Channel.prototype.toString = function toString() {
+ return "<#" + this.id + ">";
+ };
+
+ _createClass(Channel, [{
+ key: "permissionOverwrites",
+ get: function get() {
+ return this.roles;
+ }
}, {
- key: "toString",
- value: function toString() {
- return "#" + this.name;
+ key: "permissions",
+ get: function get() {
+ return this.roles;
}
}, {
key: "client",
get: function get() {
return this.server.client;
}
+ }, {
+ key: "isPrivate",
+ get: function get() {
+ return false;
+ }
+ }, {
+ key: "users",
+ get: function get() {
+ return this.server.members;
+ }
+ }, {
+ key: "members",
+ get: function get() {
+ return this.server.members;
+ }
}]);
return Channel;
diff --git a/lib/index.js b/lib/index.js
index 6a2f82f05..d0edc45cf 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -9,4 +9,28 @@ var Discord = {
Client: Client
};
+Discord.patchStrings = function () {
+
+ defineProperty("bold", "**");
+ defineProperty("underline", "__");
+ defineProperty("strike", "~~");
+ defineProperty("code", "`");
+ defineProperty("codeblock", "```");
+ defineProperty("newline", "\n");
+
+ Object.defineProperty(String.prototype, "italic", {
+ get: function get() {
+ return "*" + this + "*";
+ }
+ });
+
+ function defineProperty(name, joiner) {
+ Object.defineProperty(String.prototype, name, {
+ get: function get() {
+ return joiner + this + joiner;
+ }
+ });
+ }
+};
+
module.exports = Discord;
\ No newline at end of file
diff --git a/lib/message.js b/lib/message.js
index 24c54fbb3..72c1eb7f2 100644
--- a/lib/message.js
+++ b/lib/message.js
@@ -4,6 +4,8 @@ var _createClass = (function () { function defineProperties(target, props) { for
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+var PMChannel = require("./PMChannel.js");
+
var Message = (function () {
function Message(data, channel, mentions, author) {
_classCallCheck(this, Message);
@@ -18,7 +20,13 @@ var Message = (function () {
this.editedTimestamp = data.edited_timestamp;
this.content = data.content.trim();
this.channel = channel;
- this.author = author;
+
+ if (this.isPrivate) {
+ this.author = this.channel.client.getUser("id", author.id);
+ } else {
+ this.author = this.channel.server.getMember("id", author.id) || this.channel.client.getUser("id", author.id);
+ }
+
this.attachments = data.attachments;
}
@@ -26,44 +34,39 @@ var Message = (function () {
return ( this.channel instanceof PMChannel );
}*/
- _createClass(Message, [{
- key: "isMentioned",
- value: function isMentioned(user) {
- var id = user.id ? user.id : user;
- var _iteratorNormalCompletion = true;
- var _didIteratorError = false;
- var _iteratorError = undefined;
+ Message.prototype.isMentioned = function isMentioned(user) {
+ var id = user.id ? user.id : user;
+ for (var _iterator = this.mentions, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
+ var _ref;
- try {
- for (var _iterator = this.mentions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
- var mention = _step.value;
-
- if (mention.id === id) {
- return true;
- }
- }
- } catch (err) {
- _didIteratorError = true;
- _iteratorError = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion && _iterator["return"]) {
- _iterator["return"]();
- }
- } finally {
- if (_didIteratorError) {
- throw _iteratorError;
- }
- }
+ if (_isArray) {
+ if (_i >= _iterator.length) break;
+ _ref = _iterator[_i++];
+ } else {
+ _i = _iterator.next();
+ if (_i.done) break;
+ _ref = _i.value;
}
- return false;
+ var mention = _ref;
+
+ if (mention.id === id) {
+ return true;
+ }
}
- }, {
+ return false;
+ };
+
+ _createClass(Message, [{
key: "sender",
get: function get() {
return this.author;
}
+ }, {
+ key: "isPrivate",
+ get: function get() {
+ return this.channel.isPrivate;
+ }
}]);
return Message;
diff --git a/lib/server.js b/lib/server.js
index 5bf3beca1..46676d5eb 100644
--- a/lib/server.js
+++ b/lib/server.js
@@ -4,6 +4,9 @@ var _createClass = (function () { function defineProperties(target, props) { for
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+var ServerPermissions = require("./ServerPermissions.js");
+var Member = require("./Member.js");
+
var Server = (function () {
function Server(data, client) {
_classCallCheck(this, Server);
@@ -19,128 +22,224 @@ var Server = (function () {
this.afkTimeout = data.afk_timeout;
this.afkChannelId = data.afk_channel_id;
+ this.roles = [];
+
+ for (var _iterator = data.roles, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
+ var _ref;
+
+ if (_isArray) {
+ if (_i >= _iterator.length) break;
+ _ref = _iterator[_i++];
+ } else {
+ _i = _iterator.next();
+ if (_i.done) break;
+ _ref = _i.value;
+ }
+
+ var permissionGroup = _ref;
+
+ this.roles.push(new ServerPermissions(permissionGroup));
+ }
+
if (!data.members) {
data.members = [client.user];
return;
}
- var _iteratorNormalCompletion = true;
- var _didIteratorError = false;
- var _iteratorError = undefined;
+ for (var _iterator2 = data.members, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
+ var _ref2;
- try {
- for (var _iterator = data.members[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
- var member = _step.value;
+ if (_isArray2) {
+ if (_i2 >= _iterator2.length) break;
+ _ref2 = _iterator2[_i2++];
+ } else {
+ _i2 = _iterator2.next();
+ if (_i2.done) break;
+ _ref2 = _i2.value;
+ }
- // first we cache the user in our Discord Client,
- // then we add it to our list. This way when we
- // get a user from this server's member list,
- // it will be identical (unless an async change occurred)
- // to the client's cache.
- if (member.user) this.members.push(client.addUser(member.user));
- }
- } catch (err) {
- _didIteratorError = true;
- _iteratorError = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion && _iterator["return"]) {
- _iterator["return"]();
- }
- } finally {
- if (_didIteratorError) {
- throw _iteratorError;
- }
- }
+ var member = _ref2;
+
+ // first we cache the user in our Discord Client,
+ // then we add it to our list. This way when we
+ // get a user from this server's member list,
+ // it will be identical (unless an async change occurred)
+ // to the client's cache.
+ if (member.user) this.addMember(client.addUser(member.user), member.roles);
}
}
+ // get/set
+
+ Server.prototype.getRole = function getRole(id) {
+ for (var _iterator3 = this.roles, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
+ var _ref3;
+
+ if (_isArray3) {
+ if (_i3 >= _iterator3.length) break;
+ _ref3 = _iterator3[_i3++];
+ } else {
+ _i3 = _iterator3.next();
+ if (_i3.done) break;
+ _ref3 = _i3.value;
+ }
+
+ var role = _ref3;
+
+ if (role.id === id) {
+ return role;
+ }
+ }
+
+ return null;
+ };
+
+ Server.prototype.updateRole = function updateRole(data) {
+
+ var oldRole = this.getRole(data.id);
+
+ if (oldRole) {
+
+ var index = this.roles.indexOf(oldRole);
+ this.roles[index] = new ServerPermissions(data);
+
+ return this.roles[index];
+ } else {
+ return false;
+ }
+ };
+
+ Server.prototype.removeRole = function removeRole(id) {
+ for (var roleId in this.roles) {
+ if (this.roles[roleId].id === id) {
+ this.roles.splice(roleId, 1);
+ }
+ }
+
+ for (var _iterator4 = this.members, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
+ var _ref4;
+
+ if (_isArray4) {
+ if (_i4 >= _iterator4.length) break;
+ _ref4 = _iterator4[_i4++];
+ } else {
+ _i4 = _iterator4.next();
+ if (_i4.done) break;
+ _ref4 = _i4.value;
+ }
+
+ var member = _ref4;
+
+ for (var roleId in member.rawRoles) {
+ if (member.rawRoles[roleId] === id) {
+ member.rawRoles.splice(roleId, 1);
+ }
+ }
+ }
+ };
+
+ Server.prototype.getChannel = function getChannel(key, value) {
+ for (var _iterator5 = this.channels, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {
+ var _ref5;
+
+ if (_isArray5) {
+ if (_i5 >= _iterator5.length) break;
+ _ref5 = _iterator5[_i5++];
+ } else {
+ _i5 = _iterator5.next();
+ if (_i5.done) break;
+ _ref5 = _i5.value;
+ }
+
+ var channel = _ref5;
+
+ if (channel[key] === value) {
+ return channel;
+ }
+ }
+
+ return null;
+ };
+
+ Server.prototype.getMember = function getMember(key, value) {
+ for (var _iterator6 = this.members, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) {
+ var _ref6;
+
+ if (_isArray6) {
+ if (_i6 >= _iterator6.length) break;
+ _ref6 = _iterator6[_i6++];
+ } else {
+ _i6 = _iterator6.next();
+ if (_i6.done) break;
+ _ref6 = _i6.value;
+ }
+
+ var member = _ref6;
+
+ if (member[key] === value) {
+ return member;
+ }
+ }
+
+ return null;
+ };
+
+ Server.prototype.removeMember = function removeMember(key, value) {
+ for (var _iterator7 = this.members, _isArray7 = Array.isArray(_iterator7), _i7 = 0, _iterator7 = _isArray7 ? _iterator7 : _iterator7[Symbol.iterator]();;) {
+ var _ref7;
+
+ if (_isArray7) {
+ if (_i7 >= _iterator7.length) break;
+ _ref7 = _iterator7[_i7++];
+ } else {
+ _i7 = _iterator7.next();
+ if (_i7.done) break;
+ _ref7 = _i7.value;
+ }
+
+ var member = _ref7;
+
+ if (member[key] === value) {
+ this.members.splice(key, 1);
+ return member;
+ }
+ }
+
+ return false;
+ };
+
+ Server.prototype.addChannel = function addChannel(chann) {
+ if (!this.getChannel("id", chann.id)) {
+ this.channels.push(chann);
+ }
+ return chann;
+ };
+
+ Server.prototype.addMember = function addMember(user, roles) {
+ if (!this.getMember("id", user.id)) {
+ var mem = new Member(user, this, roles);
+ this.members.push(mem);
+ }
+ return mem;
+ };
+
+ Server.prototype.toString = function toString() {
+ return this.name;
+ };
+
+ Server.prototype.equals = function equals(object) {
+ return object.id === this.id;
+ };
+
_createClass(Server, [{
- key: "getChannel",
-
- // get/set
- value: function getChannel(key, value) {
- var _iteratorNormalCompletion2 = true;
- var _didIteratorError2 = false;
- var _iteratorError2 = undefined;
-
- try {
- for (var _iterator2 = this.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
- var channel = _step2.value;
-
- if (channel[key] === value) {
- return channel;
- }
- }
- } catch (err) {
- _didIteratorError2 = true;
- _iteratorError2 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion2 && _iterator2["return"]) {
- _iterator2["return"]();
- }
- } finally {
- if (_didIteratorError2) {
- throw _iteratorError2;
- }
- }
- }
-
- return null;
+ key: "permissionGroups",
+ get: function get() {
+ return this.roles;
}
}, {
- key: "getMember",
- value: function getMember(key, value) {
- var _iteratorNormalCompletion3 = true;
- var _didIteratorError3 = false;
- var _iteratorError3 = undefined;
-
- try {
- for (var _iterator3 = this.members[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
- var member = _step3.value;
-
- if (member[key] === value) {
- return member;
- }
- }
- } catch (err) {
- _didIteratorError3 = true;
- _iteratorError3 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion3 && _iterator3["return"]) {
- _iterator3["return"]();
- }
- } finally {
- if (_didIteratorError3) {
- throw _iteratorError3;
- }
- }
- }
-
- return null;
- }
- }, {
- key: "addChannel",
- value: function addChannel(chann) {
- if (!this.getChannel("id", chann.id)) {
- this.channels.push(chann);
- }
- return chann;
- }
- }, {
- key: "addMember",
- value: function addMember(member) {
- if (!this.getMember("id", member.id)) {
- this.members.push(member);
- }
- return member;
- }
- }, {
- key: "toString",
- value: function toString() {
- return this.name;
+ key: "permissions",
+ get: function get() {
+ return this.roles;
}
}, {
key: "iconURL",
@@ -165,6 +264,11 @@ var Server = (function () {
get: function get() {
return this.client.getUser("id", this.ownerID);
}
+ }, {
+ key: "users",
+ get: function get() {
+ return this.members;
+ }
}]);
return Server;
diff --git a/lib/user.js b/lib/user.js
index 2f363dd1e..2234f030f 100644
--- a/lib/user.js
+++ b/lib/user.js
@@ -12,37 +12,35 @@ var User = (function () {
this.discriminator = data.discriminator;
this.id = data.id;
this.avatar = data.avatar;
+ this.status = data.status || "offline";
+ this.gameId = data.game_id || null;
}
// access using user.avatarURL;
+ User.prototype.mention = function mention() {
+ return "<@" + this.id + ">";
+ };
+
+ User.prototype.toString = function toString() {
+ /*
+ if we embed a user in a String - like so:
+ "Yo " + user + " what's up?"
+ It would generate something along the lines of:
+ "Yo @hydrabolt what's up?"
+ */
+ return this.mention();
+ };
+
+ User.prototype.equals = function equals(object) {
+ return object.id === this.id;
+ };
+
+ User.prototype.equalsStrict = function equalsStrict(object) {
+ return object.id === this.id && object.avatar === this.avatar && object.username === this.username && object.discriminator === this.discriminator;
+ };
+
_createClass(User, [{
- key: "mention",
- value: function mention() {
- return "<@" + this.id + ">";
- }
- }, {
- key: "toString",
- value: function toString() {
- /*
- if we embed a user in a String - like so:
- "Yo " + user + " what's up?"
- It would generate something along the lines of:
- "Yo @hydrabolt what's up?"
- */
- return this.mention();
- }
- }, {
- key: "equals",
- value: function equals(object) {
- return object.id === this.id;
- }
- }, {
- key: "equalsStrict",
- value: function equalsStrict(object) {
- return object.id === this.id && object.avatar === this.avatar && object.username === this.username && object.discriminator === this.discriminator;
- }
- }, {
key: "avatarURL",
get: function get() {
if (!this.avatar) return null;
diff --git a/package.json b/package.json
index 40a91a8c9..5cc1e0db0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "discord.js",
- "version": "3.1.5",
+ "version": "3.9.1",
"description": "A way to interface with the Discord API",
"main": "./lib/index.js",
"scripts": {
diff --git a/ref/gameMap.json b/ref/gameMap.json
new file mode 100644
index 000000000..8b351465f
--- /dev/null
+++ b/ref/gameMap.json
@@ -0,0 +1 @@
+[{"executables":{"win32":["pol.exe"]},"id":0,"name":"FINAL FANTASY XI"},{"executables":{"win32":["ffxiv.exe","ffxiv_dx11.exe"]},"id":1,"name":"FINAL FANTASY XIV"},{"executables":{"win32":["Wow.exe","Wow-64.exe"]},"id":3,"name":"World of Warcraft"},{"executables":{"darwin":["LoLLauncher.app"],"win32":["LolClient.exe","League of Legends.exe"]},"id":4,"name":"League of Legends"},{"executables":{"darwin":["Diablo%20III.app"],"win32":["Diablo III.exe"]},"id":5,"name":"Diablo 3"},{"executables":{"darwin":["dota_osx.app"],"win32":["dota2.exe"]},"id":6,"name":"DOTA 2"},{"executables":{"darwin":["Heroes.app"],"win32":["Heroes of the Storm.exe","HeroesOfTheStorm_x64.exe","HeroesOfTheStorm.exe"]},"id":7,"name":"Heroes of the Storm"},{"executables":{"darwin":["Hearthstone.app"],"win32":["Hearthstone.exe"]},"id":8,"name":"Hearthstone"},{"executables":{"win32":["csgo.exe"]},"id":9,"name":"Counter-Strike: Global Offensive"},{"executables":{"win32":["WorldOfTanks.exe"]},"id":10,"name":"World of Tanks"},{"executables":{"darwin":["gw2.app"],"win32":["gw2.exe"]},"id":11,"name":"Guild Wars 2"},{"executables":{"win32":["dayz.exe"]},"id":12,"name":"Day Z"},{"executables":{"darwin":["starcraft%20ii.app"],"win32":["starcraft ii.exe","SC2_x64.exe","SC2.exe"]},"id":13,"name":"Starcraft II"},{"executables":{"win32":["diablo.exe"]},"id":14,"name":"Diablo"},{"executables":{"win32":["diablo ii.exe"]},"id":15,"name":"Diablo 2"},{"executables":{"win32":["left4dead.exe"]},"id":17,"name":"Left 4 Dead"},{"executables":{"darwin":["minecraft.app"],"win32":["minecraft.exe"]},"id":18,"name":"Minecraft"},{"executables":{"win32":["smite.exe"]},"id":19,"name":"Smite"},{"executables":{"win32":["bf4.exe"]},"id":20,"name":"Battlefield 4"},{"executables":{"win32":["AoK HD.exe","empires2.exe"]},"id":101,"name":"Age of Empire II"},{"executables":{"win32":["age3y.exe"]},"id":102,"name":"Age of Empire III"},{"executables":{"win32":["AlanWake.exe"]},"id":104,"name":"Alan Wake"},{"executables":{"win32":["alan_wakes_american_nightmare.exe"]},"id":105,"name":"Alan Wake's American Nightmare"},{"executables":{"win32":["AlienBreed2Assault.exe"]},"id":106,"name":"Alien Breed 2: Assault"},{"executables":{"win32":["Amnesia.exe"]},"id":107,"name":"Amnesia: The Dark Descent"},{"executables":{"win32":["UDK.exe"]},"id":108,"name":"Antichamber"},{"executables":{"win32":["ArcheAge.exe"]},"id":109,"name":"ArcheAge"},{"executables":{"win32":["arma3.exe"]},"id":110,"name":"Arma III"},{"executables":{"win32":["AC3SP.exe"]},"id":111,"name":"Assassin's Creed 3"},{"executables":{"win32":["Bastion.exe"]},"id":112,"name":"Bastion"},{"executables":{"win32":["BF2.exe"]},"id":113,"name":"Battlefield 2"},{"executables":{"win32":["bf3.exe"]},"id":114,"name":"Battlefield 3"},{"executables":{"win32":["Besiege.exe"]},"id":116,"name":"Besiege"},{"executables":{"win32":["Bioshock.exe"]},"id":117,"name":"Bioshock"},{"executables":{"win32":["Bioshock2.exe"]},"id":118,"name":"BioShock II"},{"executables":{"win32":["BioShockInfinite.exe"]},"id":119,"name":"BioShock Infinite"},{"executables":{"win32":["Borderlands2.exe"]},"id":122,"name":"Borderlands 2"},{"executables":{"win32":["braid.exe"]},"id":123,"name":"Braid"},{"executables":{"win32":["ShippingPC-StormGame.exe"]},"id":124,"name":"Bulletstorm"},{"executables":{},"id":125,"name":"Cabal 2"},{"executables":{"win32":["CabalMain.exe"]},"id":126,"name":"Cabal Online"},{"executables":{"win32":["iw4mp.exe","iw4sp.exe"]},"id":127,"name":"Call of Duty: Modern Warfare 2"},{"executables":{"win32":["t6sp.exe"]},"id":128,"name":"Call of Duty: Black Ops"},{"executables":{"win32":["iw5mp.exe"]},"id":129,"name":"Call of Duty: Modern Warfare 3"},{"executables":{"win32":["RelicCOH.exe"]},"id":132,"name":"Company of Heroes"},{"executables":{"win32":["Crysis64.exe"]},"id":135,"name":"Crysis"},{"executables":{"win32":["Crysis2.exe"]},"id":136,"name":"Crysis 2"},{"executables":{"win32":["Crysis3.exe"]},"id":137,"name":"Crysis 3"},{"executables":{"win32":["Crysis.exe"]},"id":138,"name":"Crysis 4 "},{"executables":{"win32":["DATA.exe"]},"id":140,"name":"Dark Souls"},{"executables":{"win32":["DarkSoulsII.exe"]},"id":141,"name":"Dark Souls II"},{"executables":{"win32":["dfuw.exe"]},"id":142,"name":"Darkfall: Unholy Wars"},{"executables":{"win32":["DCGAME.exe"]},"id":144,"name":"DC Universe Online"},{"executables":{"win32":["DeadIslandGame.exe"]},"id":145,"name":"Dead Island"},{"executables":{"win32":["deadspace2.exe"]},"id":146,"name":"Dead Space 2"},{"executables":{"win32":["LOTDGame.exe"]},"id":147,"name":"Deadlight"},{"executables":{"win32":["dxhr.exe"]},"id":148,"name":"Deus Ex: Human Revolution"},{"executables":{"win32":["DeviMayCry4.exe"]},"id":149,"name":"Devil May Cry 4"},{"executables":{"win32":["DMC-DevilMayCry.exe"]},"id":150,"name":"DmC Devil May Cry"},{"executables":{"win32":["dirt2_game.exe"]},"id":154,"name":"DiRT 2"},{"executables":{"win32":["dirt3_game.exe"]},"id":155,"name":"DiRT 3"},{"executables":{"win32":["dota.exe"]},"id":156,"name":"DOTA"},{"executables":{"win32":["DoubleDragon.exe"]},"id":158,"name":"Double Dragon Neon"},{"executables":{"win32":["DragonAge2.exe"]},"id":159,"name":"Dragon Age II"},{"executables":{"win32":["DragonAgeInquisition.exe"]},"id":160,"name":"Dragon Age: Inquisition"},{"executables":{"win32":["daorigins.exe"]},"id":161,"name":"Dragon Age: Origins"},{"executables":{"win32":["DBXV.exe"]},"id":162,"name":"Dragon Ball XenoVerse"},{"executables":{"win32":["DukeForever.exe"]},"id":163,"name":"Duke Nukem Forever"},{"executables":{"darwin":["Dustforce.app"],"win32":["dustforce.exe"]},"id":164,"name":"Dustforce"},{"executables":{"win32":["EliteDangerous32.exe"]},"id":165,"name":"Elite: Dangerous"},{"executables":{"win32":["exefile.exe"]},"id":166,"name":"Eve Online"},{"executables":{"win32":["eqgame.exe"]},"id":167,"name":"EverQuest"},{"executables":{"win32":["EverQuest2.exe"]},"id":168,"name":"EverQuest II"},{"executables":{},"id":169,"name":"EverQuest Next"},{"executables":{"win32":["Engine.exe"]},"id":170,"name":"F.E.A.R."},{"executables":{"win32":["FEAR2.exe"]},"id":171,"name":"F.E.A.R. 2: Project Origin"},{"executables":{"win32":["fallout3.exe"]},"id":172,"name":"Fallout 3"},{"executables":{"win32":["FalloutNV.exe"]},"id":174,"name":"Fallout: New Vegas"},{"executables":{"win32":["farcry3.exe"]},"id":175,"name":"Far Cry 3"},{"executables":{"win32":["fifa15.exe"]},"id":176,"name":"FIFA 15"},{"executables":{"win32":["FTLGame.exe"]},"id":180,"name":"FTL: Faster Than Light"},{"executables":{"win32":["GTAIV.exe"]},"id":181,"name":"Grand Theft Auto 4"},{"executables":{"win32":["GTA5.exe"]},"id":182,"name":"Grand Theft Auto 5"},{"executables":{"win32":["Gw.exe"]},"id":183,"name":"Guild Wars"},{"executables":{"win32":["H1Z1.exe"]},"id":186,"name":"H1Z1"},{"executables":{"win32":["HL2HL2.exe","hl2.exe"]},"id":188,"name":"Half Life 2"},{"executables":{"win32":["HOMEFRONT.exe"]},"id":195,"name":"Homefront"},{"executables":{"win32":["invisibleinc.exe"]},"id":196,"name":"Invisible Inc."},{"executables":{"win32":["LANoire.exe"]},"id":197,"name":"L.A. Noire"},{"executables":{"win32":["Landmark64.exe"]},"id":198,"name":"Landmark"},{"executables":{"win32":["left4dead2.exe"]},"id":201,"name":"Left 4 Dead 2"},{"executables":{"win32":["lineage.exe"]},"id":203,"name":"Lineage"},{"executables":{"win32":["Magicka.exe"]},"id":206,"name":"Magicka"},{"executables":{"win32":["MapleStory.exe"]},"id":208,"name":"MapleStory"},{"executables":{},"id":209,"name":"Mark of the Ninja"},{"executables":{"win32":["MassEffect.exe"]},"id":210,"name":"Mass Effect"},{"executables":{"win32":["MassEffect2.exe"]},"id":211,"name":"Mass Effect 2"},{"executables":{"win32":["MassEffect3Demo.exe"]},"id":212,"name":"Mass Effect 3"},{"executables":{"win32":["METAL GEAR RISING REVENGEANCE.exe"]},"id":214,"name":"Metal Gear Rising: Revengeance"},{"executables":{"win32":["metro2033.exe"]},"id":215,"name":"Metro 2033"},{"executables":{"win32":["MetroLL.exe"]},"id":216,"name":"Metro Last Light"},{"executables":{"win32":["MK10.exe"]},"id":218,"name":"Mortal Kombat X"},{"executables":{"win32":["speed.exe"]},"id":219,"name":"Need For Speed Most Wanted"},{"executables":{},"id":220,"name":"Neverwinder"},{"executables":{"darwin":["Outlast.app"],"win32":["OLGame.exe"]},"id":221,"name":"Outlast"},{"executables":{"win32":["PapersPlease.exe"]},"id":222,"name":"Papers, Please"},{"executables":{"win32":["payday_win32_release.exe"]},"id":223,"name":"PAYDAY"},{"executables":{"win32":["payday2_win32_release.exe"]},"id":224,"name":"PAYDAY2"},{"executables":{"win32":["PillarsOfEternity.exe"]},"id":225,"name":"Pillars of Eternity"},{"executables":{"win32":["PA.exe"]},"id":226,"name":"Planetary Annihilation"},{"executables":{"win32":["planetside2_x86.exe"]},"id":227,"name":"Planetside 2"},{"executables":{"win32":["hl2P.exe"]},"id":228,"name":"Portal"},{"executables":{"win32":["portal2.exe"]},"id":229,"name":"Portal 2"},{"executables":{"win32":["PrimalCarnageGame.exe"]},"id":231,"name":"Primal Cargnage"},{"executables":{"win32":["pCARS.exe"]},"id":232,"name":"Project Cars"},{"executables":{"win32":["RaceTheSun.exe"]},"id":233,"name":"Race The Sun"},{"executables":{"win32":["Rage.exe"]},"id":234,"name":"RAGE"},{"executables":{"win32":["ragexe.exe"]},"id":235,"name":"Ragnarok Online"},{"executables":{"win32":["rift.exe"]},"id":236,"name":"Rift"},{"executables":{"win32":["Rocksmith2014.exe"]},"id":237,"name":"Rocksmith 2014"},{"executables":{"win32":["SwiftKit-RS.exe","JagexLauncher.exe"]},"id":238,"name":"RuneScape"},{"executables":{"win32":["Shadowgrounds.exe"]},"id":239,"name":"Shadowgrounds"},{"executables":{"win32":["survivor.exe"]},"id":240,"name":"Shadowgrounds: Survivor"},{"executables":{"win32":["ShovelKnight.exe"]},"id":241,"name":"Shovel Knight"},{"executables":{"win32":["SimCity.exe"]},"id":242,"name":"SimCity"},{"executables":{"win32":["SporeApp.exe"]},"id":245,"name":"Spore"},{"executables":{"win32":["StarCitizen.exe"]},"id":246,"name":"Star Citizen"},{"executables":{},"id":247,"name":"Star Trek Online"},{"executables":{"win32":["battlefront.exe"]},"id":248,"name":"Star Wars Battlefront"},{"executables":{"win32":["swtor.exe"]},"id":249,"name":"Star Wars: The Old Republic"},{"executables":{"win32":["starbound.exe","starbound_opengl.exe"]},"id":250,"name":"Starbound"},{"executables":{"win32":["starcraft.exe"]},"id":251,"name":"Starcraft"},{"executables":{"win32":["SSFIV.exe"]},"id":253,"name":"Ultra Street Fighter IV"},{"executables":{"win32":["superhexagon.exe"]},"id":254,"name":"Super Hexagon"},{"executables":{"win32":["swordandsworcery_pc.exe"]},"id":255,"name":"Superbrothers: Sword & Sworcery EP"},{"executables":{"win32":["hl2TF.exe"]},"id":256,"name":"Team Fortress 2"},{"executables":{"win32":["TERA.exe"]},"id":258,"name":"TERA"},{"executables":{"win32":["Terraria.exe"]},"id":259,"name":"Terraria"},{"executables":{"win32":["Bethesda.net_Launcher.exe"]},"id":260,"name":"The Elder Scrolls Online"},{"executables":{"win32":["TESV.exe"]},"id":261,"name":"The Elder Scrolls V: Skyrim"},{"executables":{"win32":["TheSecretWorld.exe"]},"id":262,"name":"The Secret World"},{"executables":{"win32":["TS3.exe","ts3w.exe"]},"id":264,"name":"The Sims 3"},{"executables":{"win32":["WALKINGDEAD101.EXE"]},"id":265,"name":"The Walking Dead"},{"executables":{"win32":["TheWalkingDead2.exe"]},"id":266,"name":"The Walking Dead Season Two"},{"executables":{"win32":["witcher3.exe"]},"id":267,"name":"The Witcher 3"},{"executables":{"win32":["Future Soldier.exe"]},"id":268,"name":"Tom Clancy's Ghost Recon: Future Solider"},{"executables":{"win32":["TombRaider.exe"]},"id":269,"name":"Tomb Raider (2013)"},{"executables":{"win32":["Torchlight.exe"]},"id":271,"name":"Torchlight"},{"executables":{"win32":["Torchlight2.exe"]},"id":272,"name":"Torchlight 2"},{"executables":{"win32":["Shogun2.exe"]},"id":273,"name":"Total War: Shogun 2"},{"executables":{"win32":["Transistor.exe"]},"id":274,"name":"Transistor"},{"executables":{"win32":["trine.exe"]},"id":275,"name":"Trine"},{"executables":{"win32":["trine2_32bit.exe"]},"id":276,"name":"Trine 2"},{"executables":{"win32":["UOKR.exe"]},"id":277,"name":"Ultima Online"},{"executables":{"win32":["aces.exe"]},"id":279,"name":"War Thunder"},{"executables":{"win32":["Warcraft III.exe","wc3.exe"]},"id":281,"name":"Warcraft 3: Reign of Chaos"},{"executables":{"win32":["Warcraft II BNE.exe"]},"id":282,"name":"Warcraft II"},{"executables":{"win32":["Warframe.x64.exe","Warframe.exe"]},"id":283,"name":"Warframe"},{"executables":{"win32":["watch_dogs.exe"]},"id":284,"name":"Watch Dogs"},{"executables":{"win32":["WildStar64.exe"]},"id":285,"name":"WildStar"},{"executables":{"win32":["XComGame.exe"]},"id":288,"name":"XCOM: Enemy Unknown"},{"executables":{"win32":["DFO.exe","dfo.exe"]},"id":289,"name":"Dungeon Fighter Online"},{"executables":{"win32":["aclauncher.exe","acclient.exe"]},"id":290,"name":"Asheron's Call"},{"executables":{"win32":["MapleStory2.exe"]},"id":291,"name":"MapleStory 2"},{"executables":{"win32":["ksp.exe"]},"id":292,"name":"Kerbal Space Program"},{"executables":{"win32":["PINBALL.EXE"]},"id":293,"name":"3D Pinball: Space Cadet"},{"executables":{"win32":["dave.exe"]},"id":294,"name":"Dangerous Dave"},{"executables":{"win32":["iwbtgbeta(slomo).exe","iwbtgbeta(fs).exe"]},"id":295,"name":"I Wanna Be The Guy"},{"executables":{"win32":["MechWarriorOnline.exe "]},"id":296,"name":"Mech Warrior Online"},{"executables":{"win32":["dontstarve_steam.exe"]},"id":297,"name":"Don't Starve"},{"executables":{"win32":["GalCiv3.exe"]},"id":298,"name":"Galactic Civilization 3"},{"executables":{"win32":["Risk of Rain.exe"]},"id":299,"name":"Risk of Rain"},{"executables":{"win32":["Binding_of_Isaac.exe","Isaac-ng.exe"]},"id":300,"name":"The Binding of Isaac"},{"executables":{"win32":["RustClient.exe"]},"id":301,"name":"Rust"},{"executables":{"win32":["Clicker Heroes.exe"]},"id":302,"name":"Clicker Heroes"},{"executables":{"win32":["Brawlhalla.exe"]},"id":303,"name":"Brawlhalla"},{"executables":{"win32":["TownOfSalem.exe"]},"id":304,"name":"Town of Salem"},{"executables":{"win32":["osu!.exe"]},"id":305,"name":"osu!"},{"executables":{"win32":["PathOfExileSteam.exe","PathOfExile.exe"]},"id":306,"name":"Path of Exile"},{"executables":{"win32":["Dolphin.exe"]},"id":307,"name":"Dolphin"},{"executables":{"win32":["RocketLeague.exe"]},"id":308,"name":"Rocket League"},{"executables":{"win32":["TJPP.exe"]},"id":309,"name":"Jackbox Party Pack"},{"executables":{"win32":["KFGame.exe"]},"id":310,"name":"Killing Floor 2"},{"executables":{"win32":["ShooterGame.exe"]},"id":311,"name":"Ark: Survival Evolved"},{"executables":{"win32":["LifeIsStrange.exe"]},"id":312,"name":"Life Is Strange"},{"executables":{"win32":["Client_tos.exe"]},"id":313,"name":"Tree of Savior"},{"executables":{"win32":["olliolli2.exe"]},"id":314,"name":"OlliOlli2"},{"executables":{"win32":["cw.exe"]},"id":315,"name":"Closers Dimension Conflict"},{"executables":{"win32":["ESSTEAM.exe","elsword.exe","x2.exe"]},"id":316,"name":"Elsword"},{"executables":{"win32":["ori.exe"]},"id":317,"name":"Ori and the Blind Forest"},{"executables":{"win32":["Skyforge.exe"]},"id":318,"name":"Skyforge"},{"executables":{"win32":["projectzomboid64.exe","projectzomboid32.exe"]},"id":319,"name":"Project Zomboid"},{"executables":{"win32":["From_The_Depths.exe"]},"id":320,"name":"The Depths"},{"executables":{"win32":["TheCrew.exe"]},"id":321,"name":"The Crew"},{"executables":{"win32":["MarvelHeroes2015.exe"]},"id":322,"name":"Marvel Heroes 2015"},{"executables":{"win32":["timeclickers.exe"]},"id":324,"name":"Time Clickers"},{"executables":{"win32":["eurotrucks2.exe"]},"id":325,"name":"Euro Truck Simulator 2"},{"executables":{"win32":["FarmingSimulator2015Game.exe"]},"id":326,"name":"Farming Simulator 15"},{"executables":{"win32":["strife.exe"]},"id":327,"name":"Strife"},{"executables":{"win32":["Awesomenauts.exe"]},"id":328,"name":"Awesomenauts"},{"executables":{"win32":["Dofus.exe"]},"id":329,"name":"Dofus"},{"executables":{"win32":["Boid.exe"]},"id":330,"name":"Boid"},{"executables":{"win32":["adventure-capitalist.exe"]},"id":331,"name":"AdVenture Capitalist"},{"executables":{"win32":["OrcsMustDie2.exe"]},"id":332,"name":"Orcs Must Die! 2"},{"executables":{"win32":["Mountain.exe"]},"id":333,"name":"Mountain"},{"executables":{"win32":["Valkyria.exe"]},"id":335,"name":"Valkyria Chronicles"},{"executables":{"win32":["ffxiiiimg.exe"]},"id":336,"name":"Final Fantasy XIII"},{"executables":{"win32":["TLR.exe"]},"id":337,"name":"The Last Remnant"},{"executables":{"win32":["Cities.exe"]},"id":339,"name":"Cities Skylines"},{"executables":{"win32":["worldofwarships.exe","WoWSLauncher.exe"]},"id":341,"name":"World of Warships"},{"executables":{"win32":["spacegame-Win64-shipping.exe"]},"id":342,"name":"Fractured Space"},{"executables":{"win32":["thespacegame.exe"]},"id":343,"name":"Ascent - The Space Game"},{"executables":{"win32":["DuckGame.exe"]},"id":344,"name":"Duck Game"},{"executables":{"win32":["PPSSPPWindows.exe"]},"id":345,"name":"PPSSPP"},{"executables":{"win32":["MBAA.exe"]},"id":346,"name":"Melty Blood Actress Again: Current Code"},{"executables":{"win32":["TheWolfAmongUs.exe"]},"id":347,"name":"The Wolf Among Us"},{"executables":{"win32":["SpaceEngineers.exe"]},"id":348,"name":"Space Engineers"},{"executables":{"win32":["Borderlands.exe"]},"id":349,"name":"Borderlands"},{"executables":{"win32":["100orange.exe"]},"id":351,"name":"100% Orange Juice"},{"executables":{"win32":["reflex.exe"]},"id":354,"name":"Reflex"},{"executables":{"win32":["pso2.exe"]},"id":355,"name":"Phantasy Star Online 2"},{"executables":{"win32":["AssettoCorsa.exe"]},"id":356,"name":"Assetto Corsa"},{"executables":{"win32":["iw3mp.exe","iw3sp.exe"]},"id":357,"name":"Call of Duty 4: Modern Warfare"},{"executables":{"win32":["WolfOldBlood_x64.exe"]},"id":358,"name":"Wolfenstein: The Old Blood"},{"executables":{"win32":["castle.exe"]},"id":359,"name":"Castle Crashers"},{"executables":{"win32":["vindictus.exe"]},"id":360,"name":"Vindictus"},{"executables":{"win32":["ShooterGame-Win32-Shipping.exe"]},"id":361,"name":"Dirty Bomb"},{"executables":{"win32":["BatmanAK.exe"]},"id":362,"name":"Batman Arkham Knight"},{"executables":{"win32":["drt.exe"]},"id":363,"name":"Dirt Rally"},{"executables":{"win32":["rFactor.exe"]},"id":364,"name":"rFactor"},{"executables":{"win32":["clonk.exe"]},"id":365,"name":"Clonk Rage"},{"executables":{"win32":["SRHK.exe"]},"id":366,"name":"Shadowrun: Hong Kong"},{"executables":{"win32":["Insurgency.exe"]},"id":367,"name":"Insurgency"},{"executables":{"win32":["StepMania.exe"]},"id":368,"name":"Step Mania"},{"executables":{"win32":["FirefallCLient.exe"]},"id":369,"name":"Firefall"},{"executables":{"win32":["mirrorsedge.exe"]},"id":370,"name":"Mirrors Edge"},{"executables":{"win32":["MgsGroundZeroes.exe"]},"id":371,"name":"Metal Gear Solid V: Ground Zeroes"},{"executables":{"win32":["mgsvtpp.exe"]},"id":372,"name":"Metal Gear Solid V: The Phantom Pain"},{"executables":{"win32":["tld.exe"]},"id":373,"name":"The Long Dark"},{"executables":{"win32":["TKOM.exe"]},"id":374,"name":"Take On Mars"},{"executables":{"win32":["robloxplayerlauncher.exe","Roblox.exe"]},"id":375,"name":"Roblox"},{"executables":{"win32":["eu4.exe"]},"id":376,"name":"Europa Universalis 4"},{"executables":{"win32":["APB.exe"]},"id":377,"name":"APB Reloaded"},{"executables":{"win32":["Robocraft.exe"]},"id":378,"name":"Robocraft"},{"executables":{"win32":["Unity.exe"]},"id":379,"name":"Unity"},{"executables":{"win32":["Simpsons.exe"]},"id":380,"name":"The Simpsons: Hit & Run"},{"executables":{"win32":["Dnlauncher.exe","DragonNest.exe"]},"id":381,"name":"Dragon Nest"},{"executables":{"win32":["Trove.exe"]},"id":382,"name":"Trove"},{"executables":{"win32":["EndlessLegend.exe"]},"id":383,"name":"Endless Legend"},{"executables":{"win32":["TurbineLauncher.exe","dndclient.exe"]},"id":384,"name":"Dungeons & Dragons Online"},{"executables":{"win32":["quakelive.exe","quakelive_steam.exe"]},"id":385,"name":"Quake Live"},{"executables":{"win32":["7DaysToDie.exe"]},"id":386,"name":"7DaysToDie"},{"executables":{"win32":["SpeedRunners.exe"]},"id":387,"name":"SpeedRunners"},{"executables":{"win32":["gamemd.exe"]},"id":388,"name":"Command & Conquer: Red Alert 2"},{"executables":{"win32":["generals.exe"]},"id":389,"name":"Command & Conquer Generals: Zero Hour"},{"executables":{"win32":["Oblivion.exe"]},"id":390,"name":"The Elder Scrolls 4: Oblivion"},{"executables":{"win32":["mgsi.exe"]},"id":391,"name":"Metal Gear Solid"},{"executables":{"win32":["EoCApp.exe"]},"id":392,"name":"Divinity - Original Sin"},{"executables":{"win32":["Torment.exe"]},"id":393,"name":"Planescape: Torment"},{"executables":{"win32":["HexPatch.exe"]},"id":394,"name":"Hex: Shards of Fate"},{"executables":{"win32":["NS3FB.exe"]},"id":395,"name":"Naruto Shippuden Ultimate Ninja Storm 3 Full Burst"},{"executables":{"win32":["NSUNSR.exe"]},"id":396,"name":"Naruto Shippuden Ultimate Ninja Storm Revolution"},{"executables":{"win32":["SaintsRowIV.exe"]},"id":397,"name":"Saints Row IV"},{"executables":{"win32":["Shadowrun.exe"]},"id":398,"name":"Shadowrun"},{"executables":{"win32":["DungeonoftheEndless.exe"]},"id":399,"name":"Dungeon of the Endless"},{"executables":{"win32":["Hon.exe"]},"id":400,"name":"Heroes of Newerth"},{"executables":{"win32":["mabinogi.exe"]},"id":401,"name":"Mabinogi"},{"executables":{"win32":["CoD2MP_s.exe","CoDSP_s.exe"]},"id":402,"name":"Call of Duty 2:"},{"executables":{"win32":["CoDWaWmp.exe","CoDWaw.exe"]},"id":403,"name":"Call of Duty: World at War"},{"executables":{"win32":["heroes.exe"]},"id":404,"name":"Mabinogi Heroes (Vindictus) "},{"executables":{"win32":["KanColleViewer.exe"]},"id":405,"name":"KanColle "},{"executables":{"win32":["cyphers.exe"]},"id":406,"name":"Cyphers"},{"executables":{"win32":["RelicCoH2.exe"]},"id":407,"name":"Company of Heroes 2"},{"executables":{"win32":["MJ.exe"]},"id":408,"name":"セガNET麻雀MJ"},{"executables":{"win32":["ge.exe"]},"id":409,"name":"Granado Espada"},{"executables":{"win32":["NovaRO.exe"]},"id":410,"name":"Nova Ragnarok Online"},{"executables":{"win32":["RivalsofAether.exe"]},"id":411,"name":"Rivals of Aether"},{"executables":{"win32":["bfh.exe"]},"id":412,"name":"Battlefield Hardline"},{"executables":{"win32":["GrowHome.exe"]},"id":413,"name":"Grow Home"},{"executables":{"win32":["patriots.exe"]},"id":414,"name":"Rise of Nations Extended"},{"executables":{"win32":["Railroads.exe"]},"id":415,"name":"Sid Meier's Railroads!"},{"executables":{"win32":["Empire.exe"]},"id":416,"name":"Empire: Total War"},{"executables":{"win32":["Napoleon.exe"]},"id":417,"name":"Napoleon: Total War"},{"executables":{"win32":["gta_sa.exe"]},"id":418,"name":"Grand Theft Auto: San Andreas"},{"executables":{"win32":["MadMax.exe"]},"id":419,"name":"Mad Max"},{"executables":{"win32":["Titanfall.exe"]},"id":420,"name":"Titanfall"},{"executables":{"win32":["age2_x1.exe"]},"id":421,"name":"Age of Empires II: The Conquerors"},{"executables":{"win32":["Rome2.exe"]},"id":422,"name":"Total War: ROME 2"},{"executables":{"win32":["ShadowOfMordor.exe"]},"id":423,"name":"Middle-earth: Shadow of Mordor"},{"executables":{"win32":["Subnautica.exe"]},"id":424,"name":"Subnautica"},{"executables":{"win32":["anno5.exe"]},"id":425,"name":"Anno 2070"},{"executables":{"win32":["carrier.exe"]},"id":426,"name":"Carrier Command Gaea Mission"},{"executables":{"win32":["DarksidersPC.exe"]},"id":427,"name":"Darksiders"},{"executables":{"win32":["Darksiders2.exe"]},"id":428,"name":"Darksiders 2"},{"executables":{"win32":["mudlet.exe"]},"id":429,"name":"Mudlet"},{"executables":{"win32":["DunDefLauncher.exe"]},"id":430,"name":"Dungeon Defenders II"},{"executables":{"win32":["hng.exe"]},"id":431,"name":"Heroes and Generals"},{"executables":{"win32":["WFTOGame.exe"]},"id":432,"name":"War of the Overworld"},{"executables":{"win32":["Talisman.exe"]},"id":433,"name":"Talisman: Digital Edition"},{"executables":{"win32":["limbo.exe"]},"id":434,"name":"Limbo"},{"executables":{"win32":["ibbobb.exe"]},"id":435,"name":"ibb & obb"},{"executables":{"win32":["BattleBlockTheater.exe"]},"id":436,"name":"BattleBlock Theater"},{"executables":{"win32":["iracinglauncher.exe","iracingsim.exe","iracingsim64.exe"]},"id":437,"name":"iRacing"},{"executables":{"win32":["CivilizationV_DX11.exe"]},"id":438,"name":"Civilization V"}]
\ No newline at end of file
diff --git a/src/ChannelPermissions.js b/src/ChannelPermissions.js
new file mode 100644
index 000000000..9d6dce2e4
--- /dev/null
+++ b/src/ChannelPermissions.js
@@ -0,0 +1,87 @@
+class ChannelPermissions{
+ constructor(data, channel){
+
+ var self = this;
+
+ function getBit(x) {
+ return ((self.packed >>> x) & 1) === 1;
+ }
+
+ this.type = data.type; //either member or role
+ this.id = data.id;
+
+ if(this.type === "member"){
+ this.packed = channel.server.getMember("id", data.id).evalPerms.packed;
+ }else{
+ this.packed = channel.server.getRole(data.id).packed;
+ }
+
+ this.packed = this.packed & ~data.deny;
+ this.packed = this.packed | data.allow;
+
+ this.deny = data.deny;
+ this.allow = data.allow;
+
+ }
+
+ get createInstantInvite(){return this.getBit(0);}
+ set createInstantInvite(val){this.setBit(0, val);}
+
+ get manageRoles(){return this.getBit(3);}
+ set manageRoles(val){this.setBit(3, val);}
+
+ get manageChannels(){return this.getBit(4);}
+ set manageChannels(val){this.setBit(4, val);}
+
+ get readMessages(){return this.getBit(10);}
+ set readMessages(val){this.setBit(10, val);}
+
+ get sendMessages(){return this.getBit(11);}
+ set sendMessages(val){this.setBit(11, val);}
+
+ get sendTTSMessages(){return this.getBit(12);}
+ set sendTTSMessages(val){this.setBit(12, val);}
+
+ get manageMessages(){return this.getBit(13);}
+ set manageMessages(val){this.setBit(13, val);}
+
+ get embedLinks(){return this.getBit(14);}
+ set embedLinks(val){this.setBit(14, val);}
+
+ get attachFiles(){return this.getBit(15);}
+ set attachFiles(val){this.setBit(15, val);}
+
+ get readMessageHistory(){return this.getBit(16);}
+ set readMessageHistory(val){this.setBit(16, val);}
+
+ get mentionEveryone(){return this.getBit(17);}
+ set mentionEveryone(val){this.setBit(17, val);}
+
+ get voiceConnect(){return this.getBit(20);}
+ set voiceConnect(val){this.setBit(20, val);}
+
+ get voiceSpeak(){return this.getBit(21);}
+ set voiceSpeak(val){this.setBit(21, val);}
+
+ get voiceMuteMembers(){return this.getBit(22);}
+ set voiceMuteMembers(val){this.setBit(22, val);}
+
+ get voiceDeafenMembers(){return this.getBit(23);}
+ set voiceDeafenMembers(val){this.setBit(23, val);}
+
+ get voiceMoveMembers(){return this.getBit(24);}
+ set voiceMoveMembers(val){this.setBit(24, val);}
+
+ get voiceUseVoiceActivation(){return this.getBit(25);}
+ set voiceUseVoiceActivation(val){this.setBit(25, val);}
+
+ getBit(x) {
+ return ((this.packed >>> x) & 1) === 1;
+ }
+
+ setBit() {
+
+ }
+}
+
+module.exports = ChannelPermissions;
\ No newline at end of file
diff --git a/src/Client.js b/src/Client.js
index 72298886a..b51a9d446 100644
--- a/src/Client.js
+++ b/src/Client.js
@@ -7,6 +7,8 @@ var Message = require("./message.js");
var Invite = require("./invite.js");
var PMChannel = require("./PMChannel.js");
+var gameMap = require("../ref/gameMap.json");
+
//node modules
var request = require("superagent");
var WebSocket = require("ws");
@@ -29,11 +31,11 @@ class Client {
this.token = token;
this.state = 0;
this.websocket = null;
- this.events = new Map();
+ this.events = {};
this.user = null;
this.alreadySentData = false;
- this.serverCreateListener = new Map();
-
+ this.serverCreateListener = {};
+ this.typingIntervals = {};
this.email = "abc";
this.password = "abc";
@@ -52,7 +54,11 @@ class Client {
this.pmChannelCache = [];
this.readyTime = null;
this.checkingQueue = {};
+ this.userTypingListener = {};
this.queue = {};
+
+ this.__idleTime = null;
+ this.__gameId = null;
}
get uptime() {
@@ -103,11 +109,11 @@ class Client {
}
on(event, fn) {
- this.events.set(event, fn);
+ this.events[event] = fn;
}
- off(event, fn) {
- this.events.delete(event);
+ off(event) {
+ this.events[event] = null;
}
keepAlive() {
@@ -124,7 +130,7 @@ class Client {
for (var arg in arguments) {
args.push(arguments[arg]);
}
- var evt = this.events.get(event);
+ var evt = this.events[event];
if (evt) {
evt.apply(this, args.slice(1));
}
@@ -153,14 +159,16 @@ class Client {
if (err) {
self.state = 4; //set state to disconnected
self.trigger("disconnected");
- self.websocket.close();
+ if (self.websocket) {
+ self.websocket.close();
+ }
callback(err);
reject(err);
} else {
self.state = 2; //set state to logged in (not yet ready)
self.token = res.body.token; //set our token
- getGateway().then(function (url) {
+ self.getGateway().then(function (url) {
self.createws(url);
callback(null, self.token);
resolve(self.token);
@@ -225,7 +233,7 @@ class Client {
// potentially redundant in future
// creating here does NOT give us the channels of the server
// so we must wait for the guild_create event.
- self.serverCreateListener.set(res.body.id, [resolve, callback]);
+ self.serverCreateListener[res.body.id] = [resolve, callback];
/*var srv = self.addServer(res.body);
callback(null, srv);
resolve(srv);*/
@@ -359,14 +367,20 @@ class Client {
}
- reply(destination, message, callback = function (err, msg) { }) {
+ reply(destination, message, tts, callback = function (err, msg) { }) {
var self = this;
return new Promise(function (response, reject) {
+ if (typeof tts === "function") {
+ // tts is a function, which means the developer wants this to be the callback
+ callback = tts;
+ tts = false;
+ }
+
var user = destination.sender;
- self.sendMessage(destination, message, callback, user + ", ").then(response).catch(reject);
+ self.sendMessage(destination, message, tts, callback, user + ", ").then(response).catch(reject);
});
@@ -375,8 +389,8 @@ class Client {
deleteMessage(message, timeout, callback = function (err, msg) { }) {
var self = this;
-
- var prom = new Promise(function (resolve, reject) {
+
+ return new Promise(function (resolve, reject) {
if (timeout) {
setTimeout(remove, timeout)
} else {
@@ -384,37 +398,29 @@ class Client {
}
function remove() {
- if(self.options.queue){
- if (!self.queue[message.channel.id]) {
- self.queue[message.channel.id] = [];
- }
- self.queue[message.channel.id].push({
- action: "deleteMessage",
- message: message,
- then: good,
- error: bad
+ request
+ .del(`${Endpoints.CHANNELS}/${message.channel.id}/messages/${message.id}`)
+ .set("authorization", self.token)
+ .end(function (err, res) {
+ if (err) {
+ bad();
+ } else {
+ good();
+ }
});
-
- self.checkQueue(message.channel.id);
- }else{
- self._deleteMessage(message).then(good).catch(bad);
- }
}
-
- function good(){
- prom.success = true;
- callback(null);
+
+ function good() {
+ callback();
resolve();
}
-
- function bad(err){
- prom.error = err;
+
+ function bad(err) {
callback(err);
reject(err);
}
});
-
- return prom;
+
}
updateMessage(message, content, callback = function (err, msg) { }) {
@@ -425,7 +431,7 @@ class Client {
content = (content instanceof Array ? content.join("\n") : content);
- if(self.options.queue){
+ if (self.options.queue) {
if (!self.queue[message.channel.id]) {
self.queue[message.channel.id] = [];
}
@@ -436,26 +442,26 @@ class Client {
then: good,
error: bad
});
-
+
self.checkQueue(message.channel.id);
- }else{
+ } else {
self._updateMessage(message, content).then(good).catch(bad);
}
-
- function good(msg){
- prom.message = msg;
- callback(null, msg);
- resolve(msg);
- }
-
- function bad(error){
- prom.error = error;
- callback(error);
- reject(error);
- }
+
+ function good(msg) {
+ prom.message = msg;
+ callback(null, msg);
+ resolve(msg);
+ }
+
+ function bad(error) {
+ prom.error = error;
+ callback(error);
+ reject(error);
+ }
});
-
+
return prom;
}
@@ -576,7 +582,7 @@ class Client {
if (self.getServer("id", res.body.guild.id)) {
resolve(self.getServer("id", res.body.guild.id));
} else {
- self.serverCreateListener.set(res.body.guild.id, [resolve, callback]);
+ self.serverCreateListener[res.body.guild.id] = [resolve, callback];
}
}
});
@@ -585,6 +591,38 @@ class Client {
}
+ setAvatar(resource, callback = function (err) { }) {
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ if (resource instanceof Buffer) {
+ resource = resource.toString("base64");
+ resource = "data:image/jpg;base64," + resource;
+ }
+
+ request
+ .patch(`${Endpoints.API}/users/@me`)
+ .set("authorization", self.token)
+ .send({
+ avatar: resource,
+ email: self.email,
+ new_password: null,
+ password: self.password,
+ username: self.user.username
+ })
+ .end(function (err) {
+ callback(err);
+ if (err)
+ reject(err);
+ else
+ resolve();
+ });
+
+ });
+
+ }
+
sendFile(destination, file, fileName = "image.png", callback = function (err, msg) { }) {
var self = this;
@@ -603,7 +641,7 @@ class Client {
self.resolveDestination(destination).then(send).catch(bad);
function send(destination) {
- if(self.options.queue){
+ if (self.options.queue) {
//queue send file too
if (!self.queue[destination]) {
self.queue[destination] = [];
@@ -611,14 +649,14 @@ class Client {
self.queue[destination].push({
action: "sendFile",
- attachment : fstream,
- attachmentName : fileName,
+ attachment: fstream,
+ attachmentName: fileName,
then: good,
error: bad
});
self.checkQueue(destination);
- }else{
+ } else {
//not queue
self._sendFile(destination, fstream, fileName).then(good).catch(bad);
}
@@ -637,17 +675,23 @@ class Client {
}
});
-
+
return prom;
}
- sendMessage(destination, message, callback = function (err, msg) { }, premessage = "") {
+ sendMessage(destination, message, tts, callback = function (err, msg) { }, premessage = "") {
var self = this;
var prom = new Promise(function (resolve, reject) {
+ if (typeof tts === "function") {
+ // tts is a function, which means the developer wants this to be the callback
+ callback = tts;
+ tts = false;
+ }
+
message = premessage + resolveMessage(message);
var mentions = resolveMentions();
self.resolveDestination(destination).then(send).catch(error);
@@ -668,13 +712,14 @@ class Client {
action: "sendMessage",
content: message,
mentions: mentions,
+ tts: !!tts, //incase it's not a boolean
then: mgood,
error: mbad
});
self.checkQueue(destination);
} else {
- self._sendMessage(destination, message, mentions).then(mgood).catch(mbad);
+ self._sendMessage(destination, message, tts, mentions).then(mgood).catch(mbad);
}
}
@@ -708,7 +753,7 @@ class Client {
}
});
-
+
return prom;
}
@@ -744,6 +789,8 @@ class Client {
self.trigger("error", err, e);
return;
}
+
+ self.trigger("raw", dat);
//valid message
switch (dat.t) {
@@ -888,11 +935,11 @@ class Client {
}*/
- if (self.serverCreateListener.get(data.id)) {
- var cbs = self.serverCreateListener.get(data.id);
+ if (self.serverCreateListener[data.id]) {
+ var cbs = self.serverCreateListener[data.id];
cbs[0](server); //promise then callback
cbs[1](null, server); //legacy callback
- self.serverCreateListener.delete(data.id);
+ self.serverCreateListener[data.id] = null;
}
self.trigger("serverCreate", server);
@@ -905,7 +952,12 @@ class Client {
if (!channel) {
- var chann = self.addChannel(data, data.guild_id);
+ var chann;
+ if (data.is_private) {
+ chann = self.addPMChannel(data);
+ } else {
+ chann = self.addChannel(data, data.guild_id);
+ }
var srv = self.getServer("id", data.guild_id);
if (srv) {
srv.addChannel(chann);
@@ -923,12 +975,8 @@ class Client {
if (server) {
var user = self.addUser(data.user); //if for whatever reason it doesn't exist..
-
- if (!~server.members.indexOf(user)) {
- server.members.push(user);
- }
- self.trigger("serverNewMember", user);
+ self.trigger("serverNewMember", server.addMember(user, data.roles), server);
}
break;
@@ -941,11 +989,9 @@ class Client {
var user = self.addUser(data.user); //if for whatever reason it doesn't exist..
- if (~server.members.indexOf(user)) {
- server.members.splice(server.members.indexOf(user), 1);
- }
+ server.removeMember("id", user.id);
- self.trigger("serverRemoveMember", user);
+ self.trigger("serverRemoveMember", user, server);
}
break;
@@ -974,24 +1020,95 @@ class Client {
if (userInCache) {
//user exists
+
+ data.user.username = data.user.username || userInCache.username;
+ data.user.id = data.user.id || userInCache.id;
+ data.user.discriminator = data.user.discriminator || userInCache.discriminator;
+ data.user.avatar = data.user.avatar || userInCache.avatar;
+
var presenceUser = new User(data.user);
if (presenceUser.equalsStrict(userInCache)) {
//they're exactly the same, an actual presence update
self.trigger("presence", {
user: userInCache,
+ oldStatus: userInCache.status,
status: data.status,
server: self.getServer("id", data.guild_id),
gameId: data.game_id
});
+ userInCache.status = data.status;
+ userInCache.gameId = data.game_id;
} else {
//one of their details changed.
- self.trigger("userUpdate", userInCache, presenceUser);
self.userCache[self.userCache.indexOf(userInCache)] = presenceUser;
+ self.trigger("userUpdate", userInCache, presenceUser);
}
}
break;
+ case "CHANNEL_UPDATE":
+
+ var channelInCache = self.getChannel("id", data.id),
+ serverInCache = self.getServer("id", data.guild_id);
+
+ if (channelInCache && serverInCache) {
+
+ var newChann = new Channel(data, serverInCache);
+ newChann.messages = channelInCache.messages;
+
+ self.trigger("channelUpdate", channelInCache, newChann);
+
+ self.channelCache[self.channelCache.indexOf(channelInCache)] = newChann;
+ }
+
+ break;
+
+ case "TYPING_START":
+
+ var userInCache = self.getUser("id", data.user_id);
+ var channelInCache = self.getChannel("id", data.channel_id);
+
+ if (!self.userTypingListener[data.user_id] || self.userTypingListener[data.user_id] === -1) {
+ self.trigger("startTyping", userInCache, channelInCache);
+ }
+
+ self.userTypingListener[data.user_id] = Date.now();
+
+ setTimeout(function () {
+ if (self.userTypingListener[data.user_id] === -1) {
+ return;
+ }
+ if (Date.now() - self.userTypingListener[data.user_id] > 6000) {
+ // stopped typing
+ self.trigger("stopTyping", userInCache, channelInCache);
+ self.userTypingListener[data.user_id] = -1;
+ }
+ }, 6000);
+
+ break;
+
+ case "GUILD_ROLE_DELETE":
+
+ var server = self.getServer("id", data.guild_id);
+ var role = server.getRole(data.role_id);
+
+ self.trigger("serverRoleDelete", server, role);
+
+ server.removeRole(role.id);
+
+ break;
+
+ case "GUILD_ROLE_UPDATE":
+
+ var server = self.getServer("id", data.guild_id);
+ var role = server.getRole(data.role.id);
+ var newRole = server.updateRole(data.role);
+
+ self.trigger("serverRoleUpdate", server, role, newRole);
+
+ break;
+
default:
self.debug("received unknown packet");
self.trigger("unknown", dat);
@@ -1025,12 +1142,59 @@ class Client {
}
return this.getPMChannel("id", data.id);
}
+
+ setTopic(channel, topic, callback = function (err) { }) {
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+
+ self.resolveDestination(channel).then(next).catch(error);
+
+ function error(e) {
+ callback(e);
+ reject(e);
+ }
+
+ function next(destination) {
+
+ var asChan = self.getChannel("id", destination);
+
+ request
+ .patch(`${Endpoints.CHANNELS}/${destination}`)
+ .set("authorization", self.token)
+ .send({
+ name: asChan.name,
+ position: 0,
+ topic: topic
+ })
+ .end(function (err, res) {
+ if (err) {
+ error(err);
+ } else {
+ asChan.topic = res.body.topic;
+ resolve();
+ callback();
+ }
+ });
+ }
+
+ });
+
+ }
//def addServer
addServer(data) {
+ var self = this;
var server = this.getServer("id", data.id);
+ if (data.unavailable) {
+ self.trigger("unavailable", data);
+ self.debug("Server ID " + data.id + " has been marked unavailable by Discord. It was not cached.");
+ return;
+ }
+
if (!server) {
server = new Server(data, this);
this.serverCache.push(server);
@@ -1041,6 +1205,12 @@ class Client {
}
}
+ for (var presence of data.presences) {
+ var user = self.getUser("id", presence.user.id);
+ user.status = presence.status;
+ user.gameId = presence.game_id;
+ }
+
return server;
}
@@ -1094,7 +1264,7 @@ class Client {
op: 2,
d: {
token: this.token,
- v: 2,
+ v: 3,
properties: {
"$os": "discord.js",
"$browser": "discord.js",
@@ -1129,12 +1299,15 @@ class Client {
channId = destination.id;
} else if (destination instanceof Message) {
channId = destination.channel.id;
+ } else if (destination instanceof PMChannel) {
+ channId = destination.id;
} else if (destination instanceof User) {
//check if we have a PM
for (var pmc of self.pmChannelCache) {
- if (pmc.user.equals(destination)) {
- return pmc.id;
+ if (pmc.user && pmc.user.equals(destination)) {
+ resolve(pmc.id);
+ return;
}
}
@@ -1148,10 +1321,12 @@ class Client {
}
if (channId)
resolve(channId);
+ else
+ reject();
});
}
- _sendMessage(destination, content, mentions) {
+ _sendMessage(destination, content, tts, mentions) {
var self = this;
@@ -1161,7 +1336,8 @@ class Client {
.set("authorization", self.token)
.send({
content: content,
- mentions: mentions
+ mentions: mentions,
+ tts: tts
})
.end(function (err, res) {
@@ -1189,39 +1365,39 @@ class Client {
});
}
-
- _sendFile(destination, attachment, attachmentName = "DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png"){
-
+
+ _sendFile(destination, attachment, attachmentName = "DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png") {
+
var self = this;
-
- return new Promise(function(resolve, reject){
- request
- .post(`${Endpoints.CHANNELS}/${destination}/messages`)
- .set("authorization", self.token)
- .attach("file", attachment, attachmentName)
- .end(function (err, res) {
- if (err) {
- reject(err);
- } else {
-
- var chann = self.getChannel("id", destination);
- if (chann) {
- var msg = chann.addMessage(new Message(res.body, chann, [], self.user));
- resolve(msg);
- }
+ return new Promise(function (resolve, reject) {
+ request
+ .post(`${Endpoints.CHANNELS}/${destination}/messages`)
+ .set("authorization", self.token)
+ .attach("file", attachment, attachmentName)
+ .end(function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ var chann = self.getChannel("id", destination);
+ if (chann) {
+ var msg = chann.addMessage(new Message(res.body, chann, [], self.user));
+ resolve(msg);
}
- });
+
+ }
+
+ });
});
-
+
}
-
- _updateMessage(message, content){
+
+ _updateMessage(message, content) {
var self = this;
- return new Promise(function(resolve, reject){
+ return new Promise(function (resolve, reject) {
request
.patch(`${Endpoints.CHANNELS}/${message.channel.id}/messages/${message.id}`)
.set("authorization", self.token)
@@ -1240,125 +1416,149 @@ class Client {
});
});
}
-
- _deleteMessage(message){
+
+ getGateway() {
var self = this;
- return new Promise(function(resolve, reject){
+ return new Promise(function (resolve, reject) {
request
- .del(`${Endpoints.CHANNELS}/${message.channel.id}/messages/${message.id}`)
- .set("authorization", self.token)
- .end(function (err, res) {
- if (err) {
- reject(err);
- } else {
- resolve();
- }
- });
+ .get(`${Endpoints.API}/gateway`)
+ .set("authorization", self.token)
+ .end(function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ resolve(res.body.url);
+ }
+ });
});
}
- checkQueue(channelID) {
+ setStatusIdle() {
+ this.setStatus("idle");
+ }
+ setStatusOnline() {
+ this.setStatus("online");
+ }
+
+ setStatusActive() {
+ this.setStatusOnline();
+ }
+
+ setStatusHere() {
+ this.setStatusOnline();
+ }
+
+ setStatusAway() {
+ this.setStatusIdle();
+ }
+
+ startTyping(chann, stopTypeTime) {
var self = this;
-
- if (!this.checkingQueue[channelID]) {
- //if we aren't already checking this queue.
- this.checkingQueue[channelID] = true;
- doNext();
- function doNext() {
- if (self.queue[channelID].length === 0) {
- done();
- return;
- }
- var queuedEvent = self.queue[channelID][0];
- switch (queuedEvent.action) {
- case "sendMessage":
- var msgToSend = queuedEvent;
- self._sendMessage(channelID, msgToSend.content, msgToSend.mentions)
- .then(function (msg) {
- msgToSend.then(msg);
- self.queue[channelID].shift();
- doNext();
- })
- .catch(function (err) {
- msgToSend.error(err);
- self.queue[channelID].shift();
- doNext();
- });
- break;
- case "sendFile":
- var fileToSend = queuedEvent;
- self._sendFile(channelID, fileToSend.attachment, fileToSend.attachmentName)
- .then(function (msg){
- fileToSend.then(msg);
- self.queue[channelID].shift();
- doNext();
- })
- .catch(function(err){
- fileToSend.error(err);
- self.queue[channelID].shift();
- doNext();
- });
- break;
- case "updateMessage":
- var msgToUpd = queuedEvent;
- self._updateMessage(msgToUpd.message, msgToUpd.content)
- .then(function(msg){
- msgToUpd.then(msg);
- self.queue[channelID].shift();
- doNext();
- })
- .catch(function(err){
- msgToUpd.error(err);
- self.queue[channelID].shift();
- doNext();
- });
- break;
- case "deleteMessage":
- var msgToDel = queuedEvent;
- self._deleteMessage(msgToDel.message)
- .then(function(msg){
- msgToDel.then(msg);
- self.queue[channelID].shift();
- doNext();
- })
- .catch(function(err){
- msgToDel.error(err);
- self.queue[channelID].shift();
- doNext();
- });
- break;
- default:
- done();
- break;
- }
+ this.resolveDestination(chann).then(next);
+
+ function next(channel) {
+ if (self.typingIntervals[channel]) {
+ return;
}
- function done() {
- self.checkingQueue[channelID] = false;
- return;
+ var fn = function () {
+ request
+ .post(`${Endpoints.CHANNELS}/${channel}/typing`)
+ .set("authorization", self.token)
+ .end();
+ };
+
+ fn();
+
+ var interval = setInterval(fn, 3000);
+
+ self.typingIntervals[channel] = interval;
+
+ if (stopTypeTime) {
+ setTimeout(function () {
+ self.stopTyping(channel);
+ }, stopTypeTime);
}
}
}
-}
-function getGateway() {
+ stopTyping(chann) {
+ var self = this;
- var self = this;
+ this.resolveDestination(chann).then(next);
+
+ function next(channel) {
+ if (!self.typingIntervals[channel]) {
+ return;
+ }
+
+ clearInterval(self.typingIntervals[channel]);
+
+ delete self.typingIntervals[channel];
+
+ }
+ }
+
+ setStatus(stat) {
+
+ var idleTime = (stat === "online" ? null : Date.now());
+
+ this.__idleTime = idleTime;
+
+ this.websocket.send(JSON.stringify({
+ op: 3,
+ d: {
+ idle_since: this.__idleTime,
+ game_id: this.__gameId
+ }
+ }));
+ }
+
+ setPlayingGame(id) {
+
+ if (id instanceof String || typeof id === `string`) {
+
+ // working on names
+ var gid = id.trim().toUpperCase();
+
+ id = null;
+
+ for (var game of gameMap) {
+
+ if (game.name.trim().toUpperCase() === gid) {
+
+ id = game.id;
+ break;
- return new Promise(function (resolve, reject) {
- request
- .get(`${Endpoints.API}/gateway`)
- .end(function (err, res) {
- if (err) {
- reject(err);
- } else {
- resolve(res.body.url);
}
- });
- });
+ }
+
+ }
+
+ this.__gameId = id;
+
+ this.websocket.send(JSON.stringify({
+ op: 3,
+ d: {
+ idle_since: this.__idleTime,
+ game_id: this.__gameId
+ }
+ }));
+
+ }
+
+ playGame(id) {
+ this.setPlayingGame(id);
+ }
+
+ playingGame(id) {
+
+ this.setPlayingGame(id);
+
+ }
}
module.exports = Client;
\ No newline at end of file
diff --git a/src/EvaluatedPermissions.js b/src/EvaluatedPermissions.js
new file mode 100644
index 000000000..b7ccd1dde
--- /dev/null
+++ b/src/EvaluatedPermissions.js
@@ -0,0 +1,94 @@
+class EvaluatedPermissions {
+ constructor(data) {
+
+ var self = this;
+
+ this.packed = data;
+
+ if(this.getBit(3))
+ this.packed = 4294967295;
+ }
+
+ serialise() {
+ return {
+ createInstantInvite : this.createInstantInvite,
+ manageRoles : this.manageRoles,
+ manageChannels : this.manageChannels,
+ readMessages : this.readMessages,
+ sendMessages : this.sendMessage,
+ sendTTSMessages : this.sendTTSMessages,
+ manageMessages : this.manageMessages,
+ embedLinks : this.embedLinks,
+ attachFiles : this.attachFiles,
+ readMessageHistory : this.readMessageHistory,
+ mentionEveryone : this.mentionEveryone,
+ voiceConnect : this.voiceConnect,
+ voiceSpeak : this.voiceSpeak,
+ voiceMuteMembers : this.voiceMuteMembers,
+ voiceDeafenMembers : this.voiceDeafenMembers,
+ voiceMoveMember : this.voiceMoveMembers,
+ voiceUseVoiceActivation : this.voiceUseVoiceActivation
+ }
+ }
+
+ get createInstantInvite() { return this.getBit(0); }
+ set createInstantInvite(val) { this.setBit(0, val); }
+
+ get manageRoles() { return this.getBit(3); }
+ set manageRoles(val) { this.setBit(3, val); }
+
+ get manageChannels() { return this.getBit(4); }
+ set manageChannels(val) { this.setBit(4, val); }
+
+ get readMessages() { return this.getBit(10); }
+ set readMessages(val) { this.setBit(10, val); }
+
+ get sendMessages() { return this.getBit(11); }
+ set sendMessages(val) { this.setBit(11, val); }
+
+ get sendTTSMessages() { return this.getBit(12); }
+ set sendTTSMessages(val) { this.setBit(12, val); }
+
+ get manageMessages() { return this.getBit(13); }
+ set manageMessages(val) { this.setBit(13, val); }
+
+ get embedLinks() { return this.getBit(14); }
+ set embedLinks(val) { this.setBit(14, val); }
+
+ get attachFiles() { return this.getBit(15); }
+ set attachFiles(val) { this.setBit(15, val); }
+
+ get readMessageHistory() { return this.getBit(16); }
+ set readMessageHistory(val) { this.setBit(16, val); }
+
+ get mentionEveryone() { return this.getBit(17); }
+ set mentionEveryone(val) { this.setBit(17, val); }
+
+ get voiceConnect() { return this.getBit(20); }
+ set voiceConnect(val) { this.setBit(20, val); }
+
+ get voiceSpeak() { return this.getBit(21); }
+ set voiceSpeak(val) { this.setBit(21, val); }
+
+ get voiceMuteMembers() { return this.getBit(22); }
+ set voiceMuteMembers(val) { this.setBit(22, val); }
+
+ get voiceDeafenMembers() { return this.getBit(23); }
+ set voiceDeafenMembers(val) { this.setBit(23, val); }
+
+ get voiceMoveMembers() { return this.getBit(24); }
+ set voiceMoveMembers(val) { this.setBit(24, val); }
+
+ get voiceUseVoiceActivation() { return this.getBit(25); }
+ set voiceUseVoiceActivation(val) { this.setBit(25, val); }
+
+ getBit(x) {
+ return ((this.packed >>> x) & 1) === 1;
+ }
+
+ setBit() {
+
+ }
+}
+
+module.exports = EvaluatedPermissions;
\ No newline at end of file
diff --git a/src/Member.js b/src/Member.js
new file mode 100644
index 000000000..aa48d0327
--- /dev/null
+++ b/src/Member.js
@@ -0,0 +1,78 @@
+var User = require("./user.js");
+var ServerPermissions = require("./ServerPermissions.js");
+var EvaluatedPermissions = require("./EvaluatedPermissions.js");
+
+class Member extends User{
+
+ constructor(user, server, roles){
+ super(user); // should work, we are basically creating a Member that has the same properties as user and a few more
+ this.server = server;
+ this.rawRoles = roles;
+ }
+
+ get roles(){
+
+ var ufRoles = [ this.server.getRole(this.server.id) ];
+
+ for(var rawRole of this.rawRoles){
+ ufRoles.push( this.server.getRole(rawRole) );
+ }
+
+ return ufRoles;
+
+ }
+
+ get evalPerms(){
+ var basePerms = this.roles, //cache roles as it can be slightly expensive
+ basePerm = basePerms[0].packed;
+
+ for(var perm of basePerms){
+ basePerm = basePerm | perm.packed;
+ }
+
+ return new ServerPermissions({
+ permissions : basePerm
+ });
+ }
+
+ permissionsIn(channel){
+
+ if(channel.server.ownerID === this.id){
+ return new EvaluatedPermissions(4294967295); //all perms
+ }
+
+ var affectingOverwrites = [];
+ var affectingMemberOverwrites = [];
+
+ for(var overwrite of channel.roles){
+ if(overwrite.id === this.id && overwrite.type === "member"){
+ affectingMemberOverwrites.push(overwrite);
+ }else if( this.rawRoles.indexOf(overwrite.id) !== -1 ){
+ affectingOverwrites.push(overwrite);
+ }
+ }
+
+
+ if(affectingOverwrites.length === 0 && affectingMemberOverwrites.length === 0){
+ return new EvaluatedPermissions(this.evalPerms.packed);
+ }
+
+ var finalPacked = (affectingOverwrites.length !== 0 ? affectingOverwrites[0].packed : affectingMemberOverwrites[0].packed);
+
+ for(var overwrite of affectingOverwrites){
+ finalPacked = finalPacked & ~overwrite.deny;
+ finalPacked = finalPacked | overwrite.allow;
+ }
+
+ for(var overwrite of affectingMemberOverwrites){
+ finalPacked = finalPacked & ~overwrite.deny;
+ finalPacked = finalPacked | overwrite.allow;
+ }
+
+ return new EvaluatedPermissions(finalPacked);
+
+ }
+
+}
+
+module.exports = Member;
\ No newline at end of file
diff --git a/src/PMChannel.js b/src/PMChannel.js
index 6b069d50b..d2814afe5 100644
--- a/src/PMChannel.js
+++ b/src/PMChannel.js
@@ -3,6 +3,7 @@ class PMChannel {
this.user = client.getUser("id", data.recipient.id);
this.id = data.id;
this.messages = [];
+ this.client = client;
}
addMessage(data){
@@ -13,6 +14,11 @@ class PMChannel {
}
getMessage(key, value){
+
+ if(this.messages.length > 1000){
+ this.messages.splice(0,1);
+ }
+
for(var message of this.messages){
if(message[key] === value){
return message;
@@ -20,6 +26,10 @@ class PMChannel {
}
return null;
}
+
+ get isPrivate(){
+ return true;
+ }
}
module.exports = PMChannel;
\ No newline at end of file
diff --git a/src/ServerPermissions.js b/src/ServerPermissions.js
new file mode 100644
index 000000000..b3fd848ae
--- /dev/null
+++ b/src/ServerPermissions.js
@@ -0,0 +1,90 @@
+class ServerPermissions {
+
+ constructor(data) {
+
+ var self = this;
+
+ function getBit(x) {
+ return ((self.packed >>> x) & 1) === 1;
+ }
+
+ this.packed = data.permissions;
+ this.name = data.name;
+ this.id = data.id;
+
+ }
+
+ get createInstantInvite(){return this.getBit(0);}
+ set createInstantInvite(val){this.setBit(0, val);}
+
+ get banMembers(){return this.getBit(1);}
+ set banMembers(val){this.setBit(1, val);}
+
+ get kickMembers(){return this.getBit(2);}
+ set kickMembers(val){this.setBit(2, val);}
+
+ get manageRoles(){return this.getBit(3);}
+ set manageRoles(val){this.setBit(3, val);}
+
+ get manageChannels(){return this.getBit(4);}
+ set manageChannels(val){this.setBit(4, val);}
+
+ get manageServer(){return this.getBit(5);}
+ set manageServer(val){this.setBit(5, val);}
+
+ get readMessages(){return this.getBit(10);}
+ set readMessages(val){this.setBit(10, val);}
+
+ get sendMessages(){return this.getBit(11);}
+ set sendMessages(val){this.setBit(11, val);}
+
+ get sendTTSMessages(){return this.getBit(12);}
+ set sendTTSMessages(val){this.setBit(12, val);}
+
+ get manageMessages(){return this.getBit(13);}
+ set manageMessages(val){this.setBit(13, val);}
+
+ get embedLinks(){return this.getBit(14);}
+ set embedLinks(val){this.setBit(14, val);}
+
+ get attachFiles(){return this.getBit(15);}
+ set attachFiles(val){this.setBit(15, val);}
+
+ get readMessageHistory(){return this.getBit(16);}
+ set readMessageHistory(val){this.setBit(16, val);}
+
+ get mentionEveryone(){return this.getBit(17);}
+ set mentionEveryone(val){this.setBit(17, val);}
+
+ get voiceConnect(){return this.getBit(20);}
+ set voiceConnect(val){this.setBit(20, val);}
+
+ get voiceSpeak(){return this.getBit(21);}
+ set voiceSpeak(val){this.setBit(21, val);}
+
+ get voiceMuteMembers(){return this.getBit(22);}
+ set voiceMuteMembers(val){this.setBit(22, val);}
+
+ get voiceDeafenMembers(){return this.getBit(23);}
+ set voiceDeafenMembers(val){this.setBit(23, val);}
+
+ get voiceMoveMembers(){return this.getBit(24);}
+ set voiceMoveMembers(val){this.setBit(24, val);}
+
+ get voiceUseVoiceActivation(){return this.getBit(25);}
+ set voiceUseVoiceActivation(val){this.setBit(25, val);}
+
+ getBit(x) {
+ return ((this.packed >>> x) & 1) === 1;
+ }
+
+ setBit(){
+ //dummy function for now
+ }
+
+ toString(){
+ return this.name;
+ }
+}
+
+module.exports = ServerPermissions;
\ No newline at end of file
diff --git a/src/channel.js b/src/channel.js
index d32ab580d..e5bef86e2 100644
--- a/src/channel.js
+++ b/src/channel.js
@@ -1,40 +1,88 @@
+var ChannelPermissions = require("./ChannelPermissions.js");
+
class Channel {
constructor(data, server) {
this.server = server;
this.name = data.name;
this.type = data.type;
+ this.topic = data.topic;
this.id = data.id;
this.messages = [];
+ this.roles = [];
+
+ if(data.permission_overwrites)
+ for (var role of data.permission_overwrites) {
+ this.roles.push( new ChannelPermissions(role, this) );
+ }
+
//this.isPrivate = isPrivate; //not sure about the implementation of this...
}
+ get permissionOverwrites() {
+ return this.roles;
+ }
+
+ get permissions() {
+ return this.roles;
+ }
+
get client() {
return this.server.client;
}
+ permissionsOf(member){
+
+ var mem = this.server.getMember("id", member.id);
+
+ if(mem){
+ return mem.permissionsIn(this);
+ }else{
+ return null;
+ }
+
+ }
+
equals(object) {
return (object && object.id === this.id);
}
-
- addMessage(data){
- if(!this.getMessage("id", data.id)){
- this.messages.push(data);
- }
- return this.getMessage("id", data.id);
- }
-
- getMessage(key, value){
- for(var message of this.messages){
- if(message[key] === value){
- return message;
- }
- }
- return null;
- }
- toString(){
- return "#" + this.name;
+ addMessage(data) {
+
+ if (this.messages.length > 1000) {
+ this.messages.splice(0, 1);
+ }
+
+ if (!this.getMessage("id", data.id)) {
+ this.messages.push(data);
+ }
+
+ return this.getMessage("id", data.id);
+ }
+
+ getMessage(key, value) {
+ for (var message of this.messages) {
+ if (message[key] === value) {
+ return message;
+ }
+ }
+ return null;
+ }
+
+ toString() {
+ return "<#" + this.id + ">";
+ }
+
+ get isPrivate() {
+ return false;
+ }
+
+ get users() {
+ return this.server.members;
+ }
+
+ get members() {
+ return this.server.members;
}
}
diff --git a/src/index.js b/src/index.js
index 28df53ed9..53d7be58e 100644
--- a/src/index.js
+++ b/src/index.js
@@ -7,4 +7,28 @@ var Discord = {
Client : Client
}
+Discord.patchStrings = function () {
+
+ defineProperty("bold", "**");
+ defineProperty("underline", "__");
+ defineProperty("strike", "~~");
+ defineProperty("code", "`");
+ defineProperty("codeblock", "```");
+ defineProperty("newline", "\n");
+
+ Object.defineProperty(String.prototype, "italic", {
+ get: function () {
+ return "*" + this + "*";
+ }
+ });
+
+ function defineProperty(name, joiner) {
+ Object.defineProperty(String.prototype, name, {
+ get: function () {
+ return joiner + this + joiner;
+ }
+ });
+ }
+}
+
module.exports = Discord;
\ No newline at end of file
diff --git a/src/message.js b/src/message.js
index a979e87dd..991ae7677 100644
--- a/src/message.js
+++ b/src/message.js
@@ -1,3 +1,5 @@
+var PMChannel = require("./PMChannel.js");
+
class Message{
constructor(data, channel, mentions, author){
this.tts = data.tts;
@@ -10,7 +12,13 @@ class Message{
this.editedTimestamp = data.edited_timestamp;
this.content = data.content.trim();
this.channel = channel;
- this.author = author;
+
+ if(this.isPrivate){
+ this.author = this.channel.client.getUser("id", author.id);
+ }else{
+ this.author = this.channel.server.getMember("id", author.id) || this.channel.client.getUser("id", author.id);
+ }
+
this.attachments = data.attachments;
}
@@ -27,6 +35,10 @@ class Message{
get sender(){
return this.author;
}
+
+ get isPrivate(){
+ return this.channel.isPrivate;
+ }
}
/*exports.Message.prototype.isPM = function() {
diff --git a/src/server.js b/src/server.js
index 248a04683..458afa5e2 100644
--- a/src/server.js
+++ b/src/server.js
@@ -1,3 +1,6 @@
+var ServerPermissions = require("./ServerPermissions.js");
+var Member = require("./Member.js");
+
class Server {
constructor(data, client) {
this.client = client;
@@ -10,6 +13,12 @@ class Server {
this.icon = data.icon;
this.afkTimeout = data.afk_timeout;
this.afkChannelId = data.afk_channel_id;
+
+ this.roles = [];
+
+ for(var permissionGroup of data.roles){
+ this.roles.push( new ServerPermissions(permissionGroup) );
+ }
if(!data.members){
data.members = [ client.user ];
@@ -24,10 +33,18 @@ class Server {
// it will be identical (unless an async change occurred)
// to the client's cache.
if(member.user)
- this.members.push(client.addUser(member.user));
+ this.addMember(client.addUser(member.user), member.roles);
}
}
+
+ get permissionGroups(){
+ return this.roles;
+ }
+
+ get permissions(){
+ return this.roles;
+ }
get iconURL() {
if (!this.icon)
@@ -50,7 +67,56 @@ class Server {
return this.client.getUser("id", this.ownerID);
}
+ get users() {
+ return this.members;
+ }
+
// get/set
+
+ getRole(id){
+ for (var role of this.roles) {
+ if (role.id === id) {
+ return role;
+ }
+ }
+
+ return null;
+ }
+
+ updateRole(data){
+
+ var oldRole = this.getRole(data.id);
+
+ if(oldRole){
+
+ var index = this.roles.indexOf(oldRole);
+ this.roles[index] = new ServerPermissions(data);
+
+
+ return this.roles[index];
+
+ }else{
+ return false;
+ }
+
+ }
+
+ removeRole(id){
+ for (var roleId in this.roles) {
+ if (this.roles[roleId].id === id) {
+ this.roles.splice(roleId, 1);
+ }
+ }
+
+ for(var member of this.members){
+ for(var roleId in member.rawRoles){
+ if(member.rawRoles[roleId] === id){
+ member.rawRoles.splice(roleId, 1);
+ }
+ }
+ }
+ }
+
getChannel(key, value) {
for (var channel of this.channels) {
if (channel[key] === value) {
@@ -71,6 +137,17 @@ class Server {
return null;
}
+ removeMember(key, value){
+ for (var member of this.members) {
+ if (member[key] === value) {
+ this.members.splice(key, 1);
+ return member;
+ }
+ }
+
+ return false;
+ }
+
addChannel(chann) {
if (!this.getChannel("id", chann.id)) {
this.channels.push(chann);
@@ -78,16 +155,21 @@ class Server {
return chann;
}
- addMember(member){
- if (!this.getMember("id", member.id)){
- this.members.push(member);
+ addMember(user, roles){
+ if (!this.getMember("id", user.id)){
+ var mem = new Member(user, this, roles);
+ this.members.push(mem);
}
- return member;
+ return mem;
}
toString(){
return this.name;
}
+
+ equals(object){
+ return object.id === this.id;
+ }
}
module.exports = Server;
\ No newline at end of file
diff --git a/src/user.js b/src/user.js
index 375ec7c60..30af4f3e6 100644
--- a/src/user.js
+++ b/src/user.js
@@ -4,6 +4,8 @@ class User{
this.discriminator = data.discriminator;
this.id = data.id;
this.avatar = data.avatar;
+ this.status = data.status || "offline";
+ this.gameId = data.game_id || null;
}
// access using user.avatarURL;
diff --git a/test/bot.1.js b/test/bot.1.js
index 253e50c50..b607701eb 100644
--- a/test/bot.1.js
+++ b/test/bot.1.js
@@ -1,32 +1,67 @@
var Discord = require("../");
-var mybot = new Discord.Client({
- queue: true
-});
+var mybot = new Discord.Client();
var fs = require("fs");
+var request = require("request").defaults({ encoding: null });
+
+Discord.patchStrings();
var server, channel, message, sentMessage = false;
+counter = 1;
+
mybot.on("message", function (message) {
-
- if (mybot.user.equals(message.sender)) {
+
+ console.log("Everyone mentioned? " + message.everyoneMentioned);
+ if (message.content.substr(0,3) !== "$$$") {
return;
}
- if (message.content !== "$$$") {
- return;
- }
-
- var action1 = mybot.sendMessage(message.channel, "this is message " + 1);
- var action2 = mybot.sendMessage(message.channel, "this is message " + 2).then(log);
-
- function log() {
- mybot.updateMessage(action1.message, "blurg");
- mybot.sendMessage(message.channel, "This is message 3 million minus the million so basically just 3");
- mybot.deleteMessage(action1.message);
- mybot.sendMessage(message.channel, "This is message RJNGEIKGNER").then(log2);
+ // we can go ahead :)
+
+ var user;
+ if(message.mentions.length > 0){
+ user = message.mentions[0];
+ }else{
+ user = message.sender;
}
+
+ console.log( mybot.getUser("username", "meew0") );
+
+ var perms = JSON.stringify(message.channel.permissionsOf(user).serialise(), null, 4);
+ perms = JSON.parse(perms);
+
+ request.get(message.sender.avatarURL, function(err, resp, body){
+ mybot.setAvatar( new Buffer(body) ).catch(error).then(() => {
+ mybot.reply(message, "I have your avatar now!");
+ });
+ });
+
});
+mybot.on("ready", function () {
+ console.log("im ready");
+
+ for(var server of mybot.servers){
+ if(server.name === "test-server"){
+ mybot.leaveServer(server);
+ }
+ }
+
+});
+
+mybot.on("debug", function(info){
+
+})
+
+mybot.on("unknown", function(info){
+ console.log("warning!", info);
+})
+
+mybot.on("channelUpdate", function(oldChan, newChan){
+
+});
+
+
function dump(msg) {
console.log(msg);
}
diff --git a/web-dist/README.md b/web-dist/README.md
new file mode 100644
index 000000000..053576bab
--- /dev/null
+++ b/web-dist/README.md
@@ -0,0 +1,10 @@
+## Web Distributions
+
+Here you can find the latest web-ready distributions of discord.js. These distributions will allow you to run discord.js
+in your browser, which is very useful for making on-the-go bots or clients. For some reason, request times are also much
+shorter in browsers, so your bots will reply much faster.
+
+Web Distributions aren't always fully functional, and sometimes catching errors is a pain. As discord.js's support for
+browserifying is still maturing, please don't expect that it will work out of the box just yet.
+
+Also, if the versions in this folder are out-dated, you can always run `grunt web` to generate the latest library.
\ No newline at end of file
diff --git a/web-dist/discord.js b/web-dist/discord.3.3.0.js
similarity index 85%
rename from web-dist/discord.js
rename to web-dist/discord.3.3.0.js
index 2eb328b51..6753dcf6b 100644
--- a/web-dist/discord.js
+++ b/web-dist/discord.3.3.0.js
@@ -20,7 +20,7 @@ var WebSocket = require("ws");
var fs = require("fs");
var defaultOptions = {
- cache_tokens: false
+ queue: false
};
var Client = (function () {
@@ -36,10 +36,11 @@ var Client = (function () {
further efforts will be made to connect.
*/
this.options = options;
+ this.options.queue = this.options.queue;
this.token = token;
this.state = 0;
this.websocket = null;
- this.events = new Map();
+ this.events = {};
this.user = null;
this.alreadySentData = false;
this.serverCreateListener = new Map();
@@ -61,6 +62,8 @@ var Client = (function () {
this.serverCache = [];
this.pmChannelCache = [];
this.readyTime = null;
+ this.checkingQueue = {};
+ this.queue = {};
}
_createClass(Client, [{
@@ -80,12 +83,12 @@ var Client = (function () {
}, {
key: "on",
value: function on(event, fn) {
- this.events.set(event, fn);
+ this.events[event] = fn;
}
}, {
key: "off",
- value: function off(event, fn) {
- this.events["delete"](event);
+ value: function off(event) {
+ this.events[event] = null;
}
}, {
key: "keepAlive",
@@ -105,7 +108,7 @@ var Client = (function () {
for (var arg in arguments) {
args.push(arguments[arg]);
}
- var evt = this.events.get(event);
+ var evt = this.events[event];
if (evt) {
evt.apply(this, args.slice(1));
}
@@ -137,7 +140,9 @@ var Client = (function () {
if (err) {
self.state = 4; //set state to disconnected
self.trigger("disconnected");
- self.websocket.close();
+ if (self.websocket) {
+ self.websocket.close();
+ }
callback(err);
reject(err);
} else {
@@ -319,13 +324,19 @@ var Client = (function () {
}
}, {
key: "reply",
- value: function reply(destination, message) {
- var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2];
+ value: function reply(destination, message, tts) {
+ var callback = arguments.length <= 3 || arguments[3] === undefined ? function (err, msg) {} : arguments[3];
var self = this;
return new Promise(function (response, reject) {
+ if (typeof tts === "function") {
+ // tts is a function, which means the developer wants this to be the callback
+ callback = tts;
+ tts = false;
+ }
+
var user = destination.sender;
self.sendMessage(destination, message, callback, user + ", ").then(response)["catch"](reject);
});
@@ -337,7 +348,7 @@ var Client = (function () {
var self = this;
- return new Promise(function (resolve, reject) {
+ var prom = new Promise(function (resolve, reject) {
if (timeout) {
setTimeout(remove, timeout);
} else {
@@ -345,17 +356,37 @@ var Client = (function () {
}
function remove() {
- request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).end(function (err, res) {
- if (err) {
- callback(err);
- reject(err);
- } else {
- callback(null);
- resolve();
+ if (self.options.queue) {
+ if (!self.queue[message.channel.id]) {
+ self.queue[message.channel.id] = [];
}
- });
+ self.queue[message.channel.id].push({
+ action: "deleteMessage",
+ message: message,
+ then: good,
+ error: bad
+ });
+
+ self.checkQueue(message.channel.id);
+ } else {
+ self._deleteMessage(message).then(good)["catch"](bad);
+ }
+ }
+
+ function good() {
+ prom.success = true;
+ callback(null);
+ resolve();
+ }
+
+ function bad(err) {
+ prom.error = err;
+ callback(err);
+ reject(err);
}
});
+
+ return prom;
}
}, {
key: "updateMessage",
@@ -364,26 +395,41 @@ var Client = (function () {
var self = this;
- return new Promise(function (resolve, reject) {
+ var prom = new Promise(function (resolve, reject) {
content = content instanceof Array ? content.join("\n") : content;
- request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).send({
- content: content,
- mentions: []
- }).end(function (err, res) {
- if (err) {
- callback(err);
- reject(err);
- } else {
- var msg = new Message(res.body, message.channel, message.mentions, message.sender);
- callback(null, msg);
- resolve(msg);
-
- message.channel.messages[message.channel.messages.indexOf(message)] = msg;
+ if (self.options.queue) {
+ if (!self.queue[message.channel.id]) {
+ self.queue[message.channel.id] = [];
}
- });
+ self.queue[message.channel.id].push({
+ action: "updateMessage",
+ message: message,
+ content: content,
+ then: good,
+ error: bad
+ });
+
+ self.checkQueue(message.channel.id);
+ } else {
+ self._updateMessage(message, content).then(good)["catch"](bad);
+ }
+
+ function good(msg) {
+ prom.message = msg;
+ callback(null, msg);
+ resolve(msg);
+ }
+
+ function bad(error) {
+ prom.error = error;
+ callback(error);
+ reject(error);
+ }
});
+
+ return prom;
}
}, {
key: "setUsername",
@@ -547,7 +593,7 @@ var Client = (function () {
var self = this;
- return new Promise(function (resolve, reject) {
+ var prom = new Promise(function (resolve, reject) {
var fstream;
@@ -558,40 +604,60 @@ var Client = (function () {
fstream = file;
}
- self.resolveDestination(destination).then(send)["catch"](error);
+ self.resolveDestination(destination).then(send)["catch"](bad);
function send(destination) {
- request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).attach("file", fstream, fileName).end(function (err, res) {
-
- if (err) {
- error(err);
- } else {
-
- var chann = self.getChannel("id", destination);
- if (chann) {
- var msg = chann.addMessage(new Message(res.body, chann, [], self.user));
- callback(null, msg);
- resolve(msg);
- }
+ if (self.options.queue) {
+ //queue send file too
+ if (!self.queue[destination]) {
+ self.queue[destination] = [];
}
- });
+
+ self.queue[destination].push({
+ action: "sendFile",
+ attachment: fstream,
+ attachmentName: fileName,
+ then: good,
+ error: bad
+ });
+
+ self.checkQueue(destination);
+ } else {
+ //not queue
+ self._sendFile(destination, fstream, fileName).then(good)["catch"](bad);
+ }
}
- function error(err) {
+ function good(msg) {
+ prom.message = msg;
+ callback(null, msg);
+ resolve(msg);
+ }
+
+ function bad(err) {
+ prom.error = err;
callback(err);
reject(err);
}
});
+
+ return prom;
}
}, {
key: "sendMessage",
- value: function sendMessage(destination, message) {
- var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err, msg) {} : arguments[2];
- var premessage = arguments.length <= 3 || arguments[3] === undefined ? "" : arguments[3];
+ value: function sendMessage(destination, message, tts) {
+ var callback = arguments.length <= 3 || arguments[3] === undefined ? function (err, msg) {} : arguments[3];
+ var premessage = arguments.length <= 4 || arguments[4] === undefined ? "" : arguments[4];
var self = this;
- return new Promise(function (resolve, reject) {
+ var prom = new Promise(function (resolve, reject) {
+
+ if (typeof tts === "function") {
+ // tts is a function, which means the developer wants this to be the callback
+ callback = tts;
+ tts = false;
+ }
message = premessage + resolveMessage(message);
var mentions = resolveMentions();
@@ -603,55 +669,37 @@ var Client = (function () {
}
function send(destination) {
-
- request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({
- content: message,
- mentions: mentions
- }).end(function (err, res) {
-
- if (err) {
- callback(err);
- reject(err);
- } else {
- var data = res.body;
-
- var mentions = [];
-
- data.mentions = data.mentions || []; //for some reason this was not defined at some point?
-
- var _iteratorNormalCompletion3 = true;
- var _didIteratorError3 = false;
- var _iteratorError3 = undefined;
-
- try {
- for (var _iterator3 = data.mentions[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
- var mention = _step3.value;
-
- mentions.push(self.addUser(mention));
- }
- } catch (err) {
- _didIteratorError3 = true;
- _iteratorError3 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion3 && _iterator3["return"]) {
- _iterator3["return"]();
- }
- } finally {
- if (_didIteratorError3) {
- throw _iteratorError3;
- }
- }
- }
-
- var channel = self.getChannel("id", data.channel_id);
- if (channel) {
- var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author)));
- callback(null, msg);
- resolve(msg);
- }
+ if (self.options.queue) {
+ //we're QUEUEING messages, so sending them sequentially based on servers.
+ if (!self.queue[destination]) {
+ self.queue[destination] = [];
}
- });
+
+ self.queue[destination].push({
+ action: "sendMessage",
+ content: message,
+ mentions: mentions,
+ tts: !!tts, //incase it's not a boolean
+ then: mgood,
+ error: mbad
+ });
+
+ self.checkQueue(destination);
+ } else {
+ self._sendMessage(destination, message, tts, mentions).then(mgood)["catch"](mbad);
+ }
+ }
+
+ function mgood(msg) {
+ prom.message = msg;
+ callback(null, msg);
+ resolve(msg);
+ }
+
+ function mbad(error) {
+ prom.error = error;
+ callback(error);
+ reject(error);
}
function resolveMessage() {
@@ -664,27 +712,27 @@ var Client = (function () {
function resolveMentions() {
var _mentions = [];
- var _iteratorNormalCompletion4 = true;
- var _didIteratorError4 = false;
- var _iteratorError4 = undefined;
+ var _iteratorNormalCompletion3 = true;
+ var _didIteratorError3 = false;
+ var _iteratorError3 = undefined;
try {
- for (var _iterator4 = (message.match(/<@[^>]*>/g) || [])[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
- var mention = _step4.value;
+ for (var _iterator3 = (message.match(/<@[^>]*>/g) || [])[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
+ var mention = _step3.value;
_mentions.push(mention.substring(2, mention.length - 1));
}
} catch (err) {
- _didIteratorError4 = true;
- _iteratorError4 = err;
+ _didIteratorError3 = true;
+ _iteratorError3 = err;
} finally {
try {
- if (!_iteratorNormalCompletion4 && _iterator4["return"]) {
- _iterator4["return"]();
+ if (!_iteratorNormalCompletion3 && _iterator3["return"]) {
+ _iterator3["return"]();
}
} finally {
- if (_didIteratorError4) {
- throw _iteratorError4;
+ if (_didIteratorError3) {
+ throw _iteratorError3;
}
}
}
@@ -692,6 +740,8 @@ var Client = (function () {
return _mentions;
}
});
+
+ return prom;
}
//def createws
@@ -737,15 +787,40 @@ var Client = (function () {
self.user = self.addUser(data.user);
+ var _iteratorNormalCompletion4 = true;
+ var _didIteratorError4 = false;
+ var _iteratorError4 = undefined;
+
+ try {
+ for (var _iterator4 = data.guilds[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
+ var _server = _step4.value;
+
+ var server = self.addServer(_server);
+ }
+ } catch (err) {
+ _didIteratorError4 = true;
+ _iteratorError4 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion4 && _iterator4["return"]) {
+ _iterator4["return"]();
+ }
+ } finally {
+ if (_didIteratorError4) {
+ throw _iteratorError4;
+ }
+ }
+ }
+
var _iteratorNormalCompletion5 = true;
var _didIteratorError5 = false;
var _iteratorError5 = undefined;
try {
- for (var _iterator5 = data.guilds[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
- var _server = _step5.value;
+ for (var _iterator5 = data.private_channels[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
+ var _pmc = _step5.value;
- var server = self.addServer(_server);
+ var pmc = self.addPMChannel(_pmc);
}
} catch (err) {
_didIteratorError5 = true;
@@ -762,31 +837,6 @@ var Client = (function () {
}
}
- var _iteratorNormalCompletion6 = true;
- var _didIteratorError6 = false;
- var _iteratorError6 = undefined;
-
- try {
- for (var _iterator6 = data.private_channels[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
- var _pmc = _step6.value;
-
- var pmc = self.addPMChannel(_pmc);
- }
- } catch (err) {
- _didIteratorError6 = true;
- _iteratorError6 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion6 && _iterator6["return"]) {
- _iterator6["return"]();
- }
- } finally {
- if (_didIteratorError6) {
- throw _iteratorError6;
- }
- }
- }
-
self.trigger("ready");
self.readyTime = Date.now();
self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users.");
@@ -801,27 +851,27 @@ var Client = (function () {
var mentions = [];
data.mentions = data.mentions || []; //for some reason this was not defined at some point?
- var _iteratorNormalCompletion7 = true;
- var _didIteratorError7 = false;
- var _iteratorError7 = undefined;
+ var _iteratorNormalCompletion6 = true;
+ var _didIteratorError6 = false;
+ var _iteratorError6 = undefined;
try {
- for (var _iterator7 = data.mentions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
- var mention = _step7.value;
+ for (var _iterator6 = data.mentions[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
+ var mention = _step6.value;
mentions.push(self.addUser(mention));
}
} catch (err) {
- _didIteratorError7 = true;
- _iteratorError7 = err;
+ _didIteratorError6 = true;
+ _iteratorError6 = err;
} finally {
try {
- if (!_iteratorNormalCompletion7 && _iterator7["return"]) {
- _iterator7["return"]();
+ if (!_iteratorNormalCompletion6 && _iterator6["return"]) {
+ _iterator6["return"]();
}
} finally {
- if (_didIteratorError7) {
- throw _iteratorError7;
+ if (_didIteratorError6) {
+ throw _iteratorError6;
}
}
}
@@ -866,27 +916,27 @@ var Client = (function () {
}
var mentions = [];
- var _iteratorNormalCompletion8 = true;
- var _didIteratorError8 = false;
- var _iteratorError8 = undefined;
+ var _iteratorNormalCompletion7 = true;
+ var _didIteratorError7 = false;
+ var _iteratorError7 = undefined;
try {
- for (var _iterator8 = info.mentions[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
- var mention = _step8.value;
+ for (var _iterator7 = info.mentions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
+ var mention = _step7.value;
mentions.push(self.addUser(mention));
}
} catch (err) {
- _didIteratorError8 = true;
- _iteratorError8 = err;
+ _didIteratorError7 = true;
+ _iteratorError7 = err;
} finally {
try {
- if (!_iteratorNormalCompletion8 && _iterator8["return"]) {
- _iterator8["return"]();
+ if (!_iteratorNormalCompletion7 && _iterator7["return"]) {
+ _iterator7["return"]();
}
} finally {
- if (_didIteratorError8) {
- throw _iteratorError8;
+ if (_didIteratorError7) {
+ throw _iteratorError7;
}
}
}
@@ -1101,27 +1151,27 @@ var Client = (function () {
server = new Server(data, this);
this.serverCache.push(server);
if (data.channels) {
- var _iteratorNormalCompletion9 = true;
- var _didIteratorError9 = false;
- var _iteratorError9 = undefined;
+ var _iteratorNormalCompletion8 = true;
+ var _didIteratorError8 = false;
+ var _iteratorError8 = undefined;
try {
- for (var _iterator9 = data.channels[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) {
- var channel = _step9.value;
+ for (var _iterator8 = data.channels[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
+ var channel = _step8.value;
server.channels.push(this.addChannel(channel, server.id));
}
} catch (err) {
- _didIteratorError9 = true;
- _iteratorError9 = err;
+ _didIteratorError8 = true;
+ _iteratorError8 = err;
} finally {
try {
- if (!_iteratorNormalCompletion9 && _iterator9["return"]) {
- _iterator9["return"]();
+ if (!_iteratorNormalCompletion8 && _iterator8["return"]) {
+ _iterator8["return"]();
}
} finally {
- if (_didIteratorError9) {
- throw _iteratorError9;
+ if (_didIteratorError8) {
+ throw _iteratorError8;
}
}
}
@@ -1135,16 +1185,50 @@ var Client = (function () {
}, {
key: "getUser",
value: function getUser(key, value) {
+ var _iteratorNormalCompletion9 = true;
+ var _didIteratorError9 = false;
+ var _iteratorError9 = undefined;
+
+ try {
+ for (var _iterator9 = this.userCache[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) {
+ var user = _step9.value;
+
+ if (user[key] === value) {
+ return user;
+ }
+ }
+ } catch (err) {
+ _didIteratorError9 = true;
+ _iteratorError9 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion9 && _iterator9["return"]) {
+ _iterator9["return"]();
+ }
+ } finally {
+ if (_didIteratorError9) {
+ throw _iteratorError9;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ //def getChannel
+ }, {
+ key: "getChannel",
+ value: function getChannel(key, value) {
var _iteratorNormalCompletion10 = true;
var _didIteratorError10 = false;
var _iteratorError10 = undefined;
try {
- for (var _iterator10 = this.userCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {
- var user = _step10.value;
+ for (var _iterator10 = this.channelCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {
+ var channel = _step10.value;
- if (user[key] === value) {
- return user;
+ if (channel[key] === value) {
+ return channel;
}
}
} catch (err) {
@@ -1162,19 +1246,17 @@ var Client = (function () {
}
}
- return null;
+ return this.getPMChannel(key, value); //might be a PM
}
-
- //def getChannel
}, {
- key: "getChannel",
- value: function getChannel(key, value) {
+ key: "getPMChannel",
+ value: function getPMChannel(key, value) {
var _iteratorNormalCompletion11 = true;
var _didIteratorError11 = false;
var _iteratorError11 = undefined;
try {
- for (var _iterator11 = this.channelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) {
+ for (var _iterator11 = this.pmChannelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) {
var channel = _step11.value;
if (channel[key] === value) {
@@ -1196,21 +1278,23 @@ var Client = (function () {
}
}
- return this.getPMChannel(key, value); //might be a PM
+ return null;
}
+
+ //def getServer
}, {
- key: "getPMChannel",
- value: function getPMChannel(key, value) {
+ key: "getServer",
+ value: function getServer(key, value) {
var _iteratorNormalCompletion12 = true;
var _didIteratorError12 = false;
var _iteratorError12 = undefined;
try {
- for (var _iterator12 = this.pmChannelCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) {
- var channel = _step12.value;
+ for (var _iterator12 = this.serverCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) {
+ var server = _step12.value;
- if (channel[key] === value) {
- return channel;
+ if (server[key] === value) {
+ return server;
}
}
} catch (err) {
@@ -1231,40 +1315,6 @@ var Client = (function () {
return null;
}
- //def getServer
- }, {
- key: "getServer",
- value: function getServer(key, value) {
- var _iteratorNormalCompletion13 = true;
- var _didIteratorError13 = false;
- var _iteratorError13 = undefined;
-
- try {
- for (var _iterator13 = this.serverCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) {
- var server = _step13.value;
-
- if (server[key] === value) {
- return server;
- }
- }
- } catch (err) {
- _didIteratorError13 = true;
- _iteratorError13 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion13 && _iterator13["return"]) {
- _iterator13["return"]();
- }
- } finally {
- if (_didIteratorError13) {
- throw _iteratorError13;
- }
- }
- }
-
- return null;
- }
-
//def trySendConnData
}, {
key: "trySendConnData",
@@ -1317,13 +1367,13 @@ var Client = (function () {
} else if (destination instanceof User) {
//check if we have a PM
- var _iteratorNormalCompletion14 = true;
- var _didIteratorError14 = false;
- var _iteratorError14 = undefined;
+ var _iteratorNormalCompletion13 = true;
+ var _didIteratorError13 = false;
+ var _iteratorError13 = undefined;
try {
- for (var _iterator14 = self.pmChannelCache[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) {
- var pmc = _step14.value;
+ for (var _iterator13 = self.pmChannelCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) {
+ var pmc = _step13.value;
if (pmc.user.equals(destination)) {
return pmc.id;
@@ -1331,6 +1381,62 @@ var Client = (function () {
}
//we don't, at this point we're late
+ } catch (err) {
+ _didIteratorError13 = true;
+ _iteratorError13 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion13 && _iterator13["return"]) {
+ _iterator13["return"]();
+ }
+ } finally {
+ if (_didIteratorError13) {
+ throw _iteratorError13;
+ }
+ }
+ }
+
+ self.startPM(destination).then(function (pmc) {
+ resolve(pmc.id);
+ })["catch"](reject);
+ } else {
+ channId = destination;
+ }
+ if (channId) resolve(channId);
+ });
+ }
+ }, {
+ key: "_sendMessage",
+ value: function _sendMessage(destination, content, tts, mentions) {
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({
+ content: content,
+ mentions: mentions,
+ tts: tts
+ }).end(function (err, res) {
+
+ if (err) {
+ reject(err);
+ } else {
+ var data = res.body;
+
+ var mentions = [];
+
+ data.mentions = data.mentions || []; //for some reason this was not defined at some point?
+
+ var _iteratorNormalCompletion14 = true;
+ var _didIteratorError14 = false;
+ var _iteratorError14 = undefined;
+
+ try {
+ for (var _iterator14 = data.mentions[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) {
+ var mention = _step14.value;
+
+ mentions.push(self.addUser(mention));
+ }
} catch (err) {
_didIteratorError14 = true;
_iteratorError14 = err;
@@ -1346,15 +1452,152 @@ var Client = (function () {
}
}
- self.startPM(destination).then(function (pmc) {
- resolve(pmc.id);
- })["catch"](reject);
- } else {
- channId = destination;
+ var channel = self.getChannel("id", data.channel_id);
+ if (channel) {
+ var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author)));
+ resolve(msg);
+ }
}
- if (channId) resolve(channId);
+ });
});
}
+ }, {
+ key: "_sendFile",
+ value: function _sendFile(destination, attachment) {
+ var attachmentName = arguments.length <= 2 || arguments[2] === undefined ? "DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png" : arguments[2];
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).attach("file", attachment, attachmentName).end(function (err, res) {
+
+ if (err) {
+ reject(err);
+ } else {
+
+ var chann = self.getChannel("id", destination);
+ if (chann) {
+ var msg = chann.addMessage(new Message(res.body, chann, [], self.user));
+ resolve(msg);
+ }
+ }
+ });
+ });
+ }
+ }, {
+ key: "_updateMessage",
+ value: function _updateMessage(message, content) {
+ var self = this;
+ return new Promise(function (resolve, reject) {
+ request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).send({
+ content: content,
+ mentions: []
+ }).end(function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ var msg = new Message(res.body, message.channel, message.mentions, message.sender);
+ resolve(msg);
+ message.channel.messages[message.channel.messages.indexOf(message)] = msg;
+ }
+ });
+ });
+ }
+ }, {
+ key: "_deleteMessage",
+ value: function _deleteMessage(message) {
+ var self = this;
+ return new Promise(function (resolve, reject) {
+ request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).end(function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ resolve();
+ }
+ });
+ });
+ }
+ }, {
+ key: "checkQueue",
+ value: function checkQueue(channelID) {
+ var _this = this;
+
+ var self = this;
+
+ if (!this.checkingQueue[channelID]) {
+ (function () {
+ var doNext = function doNext() {
+ if (self.queue[channelID].length === 0) {
+ done();
+ return;
+ }
+ var queuedEvent = self.queue[channelID][0];
+ switch (queuedEvent.action) {
+ case "sendMessage":
+ var msgToSend = queuedEvent;
+ self._sendMessage(channelID, msgToSend.content, msgToSend.tts, msgToSend.mentions).then(function (msg) {
+ msgToSend.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ msgToSend.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ case "sendFile":
+ var fileToSend = queuedEvent;
+ self._sendFile(channelID, fileToSend.attachment, fileToSend.attachmentName).then(function (msg) {
+ fileToSend.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ fileToSend.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ case "updateMessage":
+ var msgToUpd = queuedEvent;
+ self._updateMessage(msgToUpd.message, msgToUpd.content).then(function (msg) {
+ msgToUpd.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ msgToUpd.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ case "deleteMessage":
+ var msgToDel = queuedEvent;
+ self._deleteMessage(msgToDel.message).then(function (msg) {
+ msgToDel.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ msgToDel.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ default:
+ done();
+ break;
+ }
+ };
+
+ var done = function done() {
+ self.checkingQueue[channelID] = false;
+ return;
+ };
+
+ //if we aren't already checking this queue.
+ _this.checkingQueue[channelID] = true;
+ doNext();
+ })();
+ }
+ }
}, {
key: "uptime",
get: function get() {
@@ -1509,6 +1752,11 @@ var PMChannel = (function () {
return null;
}
+ }, {
+ key: "isPrivate",
+ get: function get() {
+ return true;
+ }
}]);
return PMChannel;
@@ -1589,6 +1837,11 @@ var Channel = (function () {
get: function get() {
return this.server.client;
}
+ }, {
+ key: "isPrivate",
+ get: function get() {
+ return false;
+ }
}]);
return Channel;
@@ -1651,6 +1904,8 @@ var _createClass = (function () { function defineProperties(target, props) { for
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+var PMChannel = require("./PMChannel.js");
+
var Message = (function () {
function Message(data, channel, mentions, author) {
_classCallCheck(this, Message);
@@ -1711,13 +1966,18 @@ var Message = (function () {
get: function get() {
return this.author;
}
+ }, {
+ key: "isPrivate",
+ get: function get() {
+ return this.channel.isPrivate;
+ }
}]);
return Message;
})();
module.exports = Message;
-},{}],8:[function(require,module,exports){
+},{"./PMChannel.js":3}],8:[function(require,module,exports){
"use strict";
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
diff --git a/web-dist/discord.3.3.1.js b/web-dist/discord.3.3.1.js
new file mode 100644
index 000000000..9992d6869
--- /dev/null
+++ b/web-dist/discord.3.3.1.js
@@ -0,0 +1,3590 @@
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Discord = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o]*>/g) || [])[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
+ var mention = _step3.value;
+
+ _mentions.push(mention.substring(2, mention.length - 1));
+ }
+ } catch (err) {
+ _didIteratorError3 = true;
+ _iteratorError3 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion3 && _iterator3["return"]) {
+ _iterator3["return"]();
+ }
+ } finally {
+ if (_didIteratorError3) {
+ throw _iteratorError3;
+ }
+ }
+ }
+
+ return _mentions;
+ }
+ });
+
+ return prom;
+ }
+
+ //def createws
+ }, {
+ key: "createws",
+ value: function createws(url) {
+ if (this.websocket) return false;
+
+ var self = this;
+
+ //good to go
+ this.websocket = new WebSocket(url);
+
+ //open
+ this.websocket.onopen = function () {
+ self.trySendConnData(); //try connecting
+ };
+
+ //close
+ this.websocket.onclose = function () {
+ self.trigger("disconnected");
+ };
+
+ //message
+ this.websocket.onmessage = function (e) {
+
+ var dat = false,
+ data = {};
+
+ try {
+ dat = JSON.parse(e.data);
+ data = dat.d;
+ } catch (err) {
+ self.trigger("error", err, e);
+ return;
+ }
+
+ //valid message
+ switch (dat.t) {
+
+ case "READY":
+ self.debug("received ready packet");
+
+ self.user = self.addUser(data.user);
+
+ var _iteratorNormalCompletion4 = true;
+ var _didIteratorError4 = false;
+ var _iteratorError4 = undefined;
+
+ try {
+ for (var _iterator4 = data.guilds[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
+ var _server = _step4.value;
+
+ var server = self.addServer(_server);
+ }
+ } catch (err) {
+ _didIteratorError4 = true;
+ _iteratorError4 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion4 && _iterator4["return"]) {
+ _iterator4["return"]();
+ }
+ } finally {
+ if (_didIteratorError4) {
+ throw _iteratorError4;
+ }
+ }
+ }
+
+ var _iteratorNormalCompletion5 = true;
+ var _didIteratorError5 = false;
+ var _iteratorError5 = undefined;
+
+ try {
+ for (var _iterator5 = data.private_channels[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
+ var _pmc = _step5.value;
+
+ var pmc = self.addPMChannel(_pmc);
+ }
+ } catch (err) {
+ _didIteratorError5 = true;
+ _iteratorError5 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion5 && _iterator5["return"]) {
+ _iterator5["return"]();
+ }
+ } finally {
+ if (_didIteratorError5) {
+ throw _iteratorError5;
+ }
+ }
+ }
+
+ self.trigger("ready");
+ self.readyTime = Date.now();
+ self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users.");
+ self.state = 3;
+ setInterval(function () {
+ self.keepAlive.apply(self);
+ }, data.heartbeat_interval);
+
+ break;
+ case "MESSAGE_CREATE":
+ self.debug("received message");
+
+ var mentions = [];
+ data.mentions = data.mentions || []; //for some reason this was not defined at some point?
+ var _iteratorNormalCompletion6 = true;
+ var _didIteratorError6 = false;
+ var _iteratorError6 = undefined;
+
+ try {
+ for (var _iterator6 = data.mentions[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
+ var mention = _step6.value;
+
+ mentions.push(self.addUser(mention));
+ }
+ } catch (err) {
+ _didIteratorError6 = true;
+ _iteratorError6 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion6 && _iterator6["return"]) {
+ _iterator6["return"]();
+ }
+ } finally {
+ if (_didIteratorError6) {
+ throw _iteratorError6;
+ }
+ }
+ }
+
+ var channel = self.getChannel("id", data.channel_id);
+ if (channel) {
+ var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author)));
+ self.trigger("message", msg);
+ }
+
+ break;
+ case "MESSAGE_DELETE":
+ self.debug("message deleted");
+
+ var channel = self.getChannel("id", data.channel_id);
+ var message = channel.getMessage("id", data.id);
+ if (message) {
+ self.trigger("messageDelete", channel, message);
+ channel.messages.splice(channel.messages.indexOf(message), 1);
+ } else {
+ //don't have the cache of that message ;(
+ self.trigger("messageDelete", channel);
+ }
+ break;
+ case "MESSAGE_UPDATE":
+ self.debug("message updated");
+
+ var channel = self.getChannel("id", data.channel_id);
+ var formerMessage = channel.getMessage("id", data.id);
+
+ if (formerMessage) {
+
+ //new message might be partial, so we need to fill it with whatever the old message was.
+ var info = {};
+
+ for (var key in formerMessage) {
+ info[key] = formerMessage[key];
+ }
+
+ for (var key in data) {
+ info[key] = data[key];
+ }
+
+ var mentions = [];
+ var _iteratorNormalCompletion7 = true;
+ var _didIteratorError7 = false;
+ var _iteratorError7 = undefined;
+
+ try {
+ for (var _iterator7 = info.mentions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
+ var mention = _step7.value;
+
+ mentions.push(self.addUser(mention));
+ }
+ } catch (err) {
+ _didIteratorError7 = true;
+ _iteratorError7 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion7 && _iterator7["return"]) {
+ _iterator7["return"]();
+ }
+ } finally {
+ if (_didIteratorError7) {
+ throw _iteratorError7;
+ }
+ }
+ }
+
+ var newMessage = new Message(info, channel, mentions, formerMessage.author);
+
+ self.trigger("messageUpdate", newMessage, formerMessage);
+
+ channel.messages[channel.messages.indexOf(formerMessage)] = newMessage;
+ }
+
+ // message isn't in cache, and if it's a partial it could cause
+ // all hell to break loose... best to just act as if nothing happened
+
+ break;
+
+ case "GUILD_DELETE":
+
+ var server = self.getServer("id", data.id);
+
+ if (server) {
+ self.serverCache.splice(self.serverCache.indexOf(server), 1);
+ self.trigger("serverDelete", server);
+ }
+
+ break;
+
+ case "CHANNEL_DELETE":
+
+ var channel = self.getChannel("id", data.id);
+
+ if (channel) {
+
+ var server = channel.server;
+
+ if (server) {
+
+ server.channels.splice(server.channels.indexOf(channel), 1);
+ }
+
+ self.trigger("channelDelete", channel);
+
+ self.serverCache.splice(self.serverCache.indexOf(channel), 1);
+ }
+
+ break;
+
+ case "GUILD_CREATE":
+
+ var server = self.getServer("id", data.id);
+
+ if (!server) {
+ //if server doesn't already exist because duh
+ server = self.addServer(data);
+ } /*else if(server.channels.length === 0){
+
+ var srv = new Server(data, self);
+ for(channel of data.channels){
+ srv.channels.push(new Channel(channel, data.id));
+ }
+ self.serverCache[self.serverCache.indexOf(server)] = srv;
+
+ }*/
+
+ if (self.serverCreateListener.get(data.id)) {
+ var cbs = self.serverCreateListener.get(data.id);
+ cbs[0](server); //promise then callback
+ cbs[1](null, server); //legacy callback
+ self.serverCreateListener["delete"](data.id);
+ }
+
+ self.trigger("serverCreate", server);
+
+ break;
+
+ case "CHANNEL_CREATE":
+
+ var channel = self.getChannel("id", data.id);
+
+ if (!channel) {
+
+ var chann = self.addChannel(data, data.guild_id);
+ var srv = self.getServer("id", data.guild_id);
+ if (srv) {
+ srv.addChannel(chann);
+ }
+ self.trigger("channelCreate", chann);
+ }
+
+ break;
+
+ case "GUILD_MEMBER_ADD":
+
+ var server = self.getServer("id", data.guild_id);
+
+ if (server) {
+
+ var user = self.addUser(data.user); //if for whatever reason it doesn't exist..
+
+ if (! ~server.members.indexOf(user)) {
+ server.members.push(user);
+ }
+
+ self.trigger("serverNewMember", user, server);
+ }
+
+ break;
+
+ case "GUILD_MEMBER_REMOVE":
+
+ var server = self.getServer("id", data.guild_id);
+
+ if (server) {
+
+ var user = self.addUser(data.user); //if for whatever reason it doesn't exist..
+
+ if (~server.members.indexOf(user)) {
+ server.members.splice(server.members.indexOf(user), 1);
+ }
+
+ self.trigger("serverRemoveMember", user, server);
+ }
+
+ break;
+
+ case "USER_UPDATE":
+
+ if (self.user && data.id === self.user.id) {
+
+ var newUser = new User(data); //not actually adding to the cache
+
+ self.trigger("userUpdate", newUser, self.user);
+
+ if (~self.userCache.indexOf(self.user)) {
+ self.userCache[self.userCache.indexOf(self.user)] = newUser;
+ }
+
+ self.user = newUser;
+ }
+
+ break;
+
+ case "PRESENCE_UPDATE":
+
+ var userInCache = self.getUser("id", data.user.id);
+
+ if (userInCache) {
+ //user exists
+ var presenceUser = new User(data.user);
+ if (presenceUser.equalsStrict(userInCache)) {
+ //they're exactly the same, an actual presence update
+ self.trigger("presence", {
+ user: userInCache,
+ status: data.status,
+ server: self.getServer("id", data.guild_id),
+ gameId: data.game_id
+ });
+ } else {
+ //one of their details changed.
+ self.trigger("userUpdate", userInCache, presenceUser);
+ self.userCache[self.userCache.indexOf(userInCache)] = presenceUser;
+ }
+ }
+
+ break;
+
+ default:
+ self.debug("received unknown packet");
+ self.trigger("unknown", dat);
+ break;
+
+ }
+ };
+ }
+
+ //def addUser
+ }, {
+ key: "addUser",
+ value: function addUser(data) {
+ if (!this.getUser("id", data.id)) {
+ this.userCache.push(new User(data));
+ }
+ return this.getUser("id", data.id);
+ }
+
+ //def addChannel
+ }, {
+ key: "addChannel",
+ value: function addChannel(data, serverId) {
+ if (!this.getChannel("id", data.id)) {
+ this.channelCache.push(new Channel(data, this.getServer("id", serverId)));
+ }
+ return this.getChannel("id", data.id);
+ }
+ }, {
+ key: "addPMChannel",
+ value: function addPMChannel(data) {
+ if (!this.getPMChannel("id", data.id)) {
+ this.pmChannelCache.push(new PMChannel(data, this));
+ }
+ return this.getPMChannel("id", data.id);
+ }
+
+ //def addServer
+ }, {
+ key: "addServer",
+ value: function addServer(data) {
+
+ var server = this.getServer("id", data.id);
+
+ if (!server) {
+ server = new Server(data, this);
+ this.serverCache.push(server);
+ if (data.channels) {
+ var _iteratorNormalCompletion8 = true;
+ var _didIteratorError8 = false;
+ var _iteratorError8 = undefined;
+
+ try {
+ for (var _iterator8 = data.channels[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
+ var channel = _step8.value;
+
+ server.channels.push(this.addChannel(channel, server.id));
+ }
+ } catch (err) {
+ _didIteratorError8 = true;
+ _iteratorError8 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion8 && _iterator8["return"]) {
+ _iterator8["return"]();
+ }
+ } finally {
+ if (_didIteratorError8) {
+ throw _iteratorError8;
+ }
+ }
+ }
+ }
+ }
+
+ return server;
+ }
+
+ //def getUser
+ }, {
+ key: "getUser",
+ value: function getUser(key, value) {
+ var _iteratorNormalCompletion9 = true;
+ var _didIteratorError9 = false;
+ var _iteratorError9 = undefined;
+
+ try {
+ for (var _iterator9 = this.userCache[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) {
+ var user = _step9.value;
+
+ if (user[key] === value) {
+ return user;
+ }
+ }
+ } catch (err) {
+ _didIteratorError9 = true;
+ _iteratorError9 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion9 && _iterator9["return"]) {
+ _iterator9["return"]();
+ }
+ } finally {
+ if (_didIteratorError9) {
+ throw _iteratorError9;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ //def getChannel
+ }, {
+ key: "getChannel",
+ value: function getChannel(key, value) {
+ var _iteratorNormalCompletion10 = true;
+ var _didIteratorError10 = false;
+ var _iteratorError10 = undefined;
+
+ try {
+ for (var _iterator10 = this.channelCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {
+ var channel = _step10.value;
+
+ if (channel[key] === value) {
+ return channel;
+ }
+ }
+ } catch (err) {
+ _didIteratorError10 = true;
+ _iteratorError10 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion10 && _iterator10["return"]) {
+ _iterator10["return"]();
+ }
+ } finally {
+ if (_didIteratorError10) {
+ throw _iteratorError10;
+ }
+ }
+ }
+
+ return this.getPMChannel(key, value); //might be a PM
+ }
+ }, {
+ key: "getPMChannel",
+ value: function getPMChannel(key, value) {
+ var _iteratorNormalCompletion11 = true;
+ var _didIteratorError11 = false;
+ var _iteratorError11 = undefined;
+
+ try {
+ for (var _iterator11 = this.pmChannelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) {
+ var channel = _step11.value;
+
+ if (channel[key] === value) {
+ return channel;
+ }
+ }
+ } catch (err) {
+ _didIteratorError11 = true;
+ _iteratorError11 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion11 && _iterator11["return"]) {
+ _iterator11["return"]();
+ }
+ } finally {
+ if (_didIteratorError11) {
+ throw _iteratorError11;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ //def getServer
+ }, {
+ key: "getServer",
+ value: function getServer(key, value) {
+ var _iteratorNormalCompletion12 = true;
+ var _didIteratorError12 = false;
+ var _iteratorError12 = undefined;
+
+ try {
+ for (var _iterator12 = this.serverCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) {
+ var server = _step12.value;
+
+ if (server[key] === value) {
+ return server;
+ }
+ }
+ } catch (err) {
+ _didIteratorError12 = true;
+ _iteratorError12 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion12 && _iterator12["return"]) {
+ _iterator12["return"]();
+ }
+ } finally {
+ if (_didIteratorError12) {
+ throw _iteratorError12;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ //def trySendConnData
+ }, {
+ key: "trySendConnData",
+ value: function trySendConnData() {
+
+ if (this.token && !this.alreadySentData) {
+
+ this.alreadySentData = true;
+
+ var data = {
+ op: 2,
+ d: {
+ token: this.token,
+ v: 2,
+ properties: {
+ "$os": "discord.js",
+ "$browser": "discord.js",
+ "$device": "discord.js",
+ "$referrer": "",
+ "$referring_domain": ""
+ }
+ }
+ };
+ this.websocket.send(JSON.stringify(data));
+ }
+ }
+ }, {
+ key: "resolveServerID",
+ value: function resolveServerID(resource) {
+
+ if (resource instanceof Server) {
+ return resource.id;
+ } else if (!isNaN(resource) && resource.length && resource.length === 17) {
+ return resource;
+ }
+ }
+ }, {
+ key: "resolveDestination",
+ value: function resolveDestination(destination) {
+ var channId = false;
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ if (destination instanceof Server) {
+ channId = destination.id; //general is the same as server id
+ } else if (destination instanceof Channel) {
+ channId = destination.id;
+ } else if (destination instanceof Message) {
+ channId = destination.channel.id;
+ } else if (destination instanceof User) {
+
+ //check if we have a PM
+ var _iteratorNormalCompletion13 = true;
+ var _didIteratorError13 = false;
+ var _iteratorError13 = undefined;
+
+ try {
+ for (var _iterator13 = self.pmChannelCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) {
+ var pmc = _step13.value;
+
+ if (pmc.user.equals(destination)) {
+ return pmc.id;
+ }
+ }
+
+ //we don't, at this point we're late
+ } catch (err) {
+ _didIteratorError13 = true;
+ _iteratorError13 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion13 && _iterator13["return"]) {
+ _iterator13["return"]();
+ }
+ } finally {
+ if (_didIteratorError13) {
+ throw _iteratorError13;
+ }
+ }
+ }
+
+ self.startPM(destination).then(function (pmc) {
+ resolve(pmc.id);
+ })["catch"](reject);
+ } else {
+ channId = destination;
+ }
+ if (channId) resolve(channId);
+ });
+ }
+ }, {
+ key: "_sendMessage",
+ value: function _sendMessage(destination, content, tts, mentions) {
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({
+ content: content,
+ mentions: mentions,
+ tts: tts
+ }).end(function (err, res) {
+
+ if (err) {
+ reject(err);
+ } else {
+ var data = res.body;
+
+ var mentions = [];
+
+ data.mentions = data.mentions || []; //for some reason this was not defined at some point?
+
+ var _iteratorNormalCompletion14 = true;
+ var _didIteratorError14 = false;
+ var _iteratorError14 = undefined;
+
+ try {
+ for (var _iterator14 = data.mentions[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) {
+ var mention = _step14.value;
+
+ mentions.push(self.addUser(mention));
+ }
+ } catch (err) {
+ _didIteratorError14 = true;
+ _iteratorError14 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion14 && _iterator14["return"]) {
+ _iterator14["return"]();
+ }
+ } finally {
+ if (_didIteratorError14) {
+ throw _iteratorError14;
+ }
+ }
+ }
+
+ var channel = self.getChannel("id", data.channel_id);
+ if (channel) {
+ var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author)));
+ resolve(msg);
+ }
+ }
+ });
+ });
+ }
+ }, {
+ key: "_sendFile",
+ value: function _sendFile(destination, attachment) {
+ var attachmentName = arguments.length <= 2 || arguments[2] === undefined ? "DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png" : arguments[2];
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).attach("file", attachment, attachmentName).end(function (err, res) {
+
+ if (err) {
+ reject(err);
+ } else {
+
+ var chann = self.getChannel("id", destination);
+ if (chann) {
+ var msg = chann.addMessage(new Message(res.body, chann, [], self.user));
+ resolve(msg);
+ }
+ }
+ });
+ });
+ }
+ }, {
+ key: "_updateMessage",
+ value: function _updateMessage(message, content) {
+ var self = this;
+ return new Promise(function (resolve, reject) {
+ request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).send({
+ content: content,
+ mentions: []
+ }).end(function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ var msg = new Message(res.body, message.channel, message.mentions, message.sender);
+ resolve(msg);
+ message.channel.messages[message.channel.messages.indexOf(message)] = msg;
+ }
+ });
+ });
+ }
+ }, {
+ key: "_deleteMessage",
+ value: function _deleteMessage(message) {
+ var self = this;
+ return new Promise(function (resolve, reject) {
+ request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).end(function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ resolve();
+ }
+ });
+ });
+ }
+ }, {
+ key: "checkQueue",
+ value: function checkQueue(channelID) {
+ var _this = this;
+
+ var self = this;
+
+ if (!this.checkingQueue[channelID]) {
+ (function () {
+ var doNext = function doNext() {
+ if (self.queue[channelID].length === 0) {
+ done();
+ return;
+ }
+ var queuedEvent = self.queue[channelID][0];
+ switch (queuedEvent.action) {
+ case "sendMessage":
+ var msgToSend = queuedEvent;
+ self._sendMessage(channelID, msgToSend.content, msgToSend.tts, msgToSend.mentions).then(function (msg) {
+ msgToSend.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ msgToSend.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ case "sendFile":
+ var fileToSend = queuedEvent;
+ self._sendFile(channelID, fileToSend.attachment, fileToSend.attachmentName).then(function (msg) {
+ fileToSend.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ fileToSend.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ case "updateMessage":
+ var msgToUpd = queuedEvent;
+ self._updateMessage(msgToUpd.message, msgToUpd.content).then(function (msg) {
+ msgToUpd.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ msgToUpd.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ case "deleteMessage":
+ var msgToDel = queuedEvent;
+ self._deleteMessage(msgToDel.message).then(function (msg) {
+ msgToDel.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ msgToDel.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ default:
+ done();
+ break;
+ }
+ };
+
+ var done = function done() {
+ self.checkingQueue[channelID] = false;
+ return;
+ };
+
+ //if we aren't already checking this queue.
+ _this.checkingQueue[channelID] = true;
+ doNext();
+ })();
+ }
+ }
+ }, {
+ key: "uptime",
+ get: function get() {
+
+ return this.readyTime ? Date.now() - this.readyTime : null;
+ }
+ }, {
+ key: "ready",
+ get: function get() {
+ return this.state === 3;
+ }
+ }, {
+ key: "servers",
+ get: function get() {
+ return this.serverCache;
+ }
+ }, {
+ key: "channels",
+ get: function get() {
+ return this.channelCache;
+ }
+ }, {
+ key: "users",
+ get: function get() {
+ return this.userCache;
+ }
+ }, {
+ key: "PMChannels",
+ get: function get() {
+ return this.pmChannelCache;
+ }
+ }, {
+ key: "messages",
+ get: function get() {
+
+ var msgs = [];
+ var _iteratorNormalCompletion15 = true;
+ var _didIteratorError15 = false;
+ var _iteratorError15 = undefined;
+
+ try {
+ for (var _iterator15 = this.channelCache[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) {
+ var channel = _step15.value;
+
+ msgs = msgs.concat(channel.messages);
+ }
+ } catch (err) {
+ _didIteratorError15 = true;
+ _iteratorError15 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion15 && _iterator15["return"]) {
+ _iterator15["return"]();
+ }
+ } finally {
+ if (_didIteratorError15) {
+ throw _iteratorError15;
+ }
+ }
+ }
+
+ return msgs;
+ }
+ }]);
+
+ return Client;
+})();
+
+function getGateway() {
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ request.get(Endpoints.API + "/gateway").end(function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ resolve(res.body.url);
+ }
+ });
+ });
+}
+
+module.exports = Client;
+},{"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,"fs":10,"superagent":11,"ws":14}],2:[function(require,module,exports){
+"use strict";
+
+exports.BASE_DOMAIN = "discordapp.com";
+exports.BASE = "https://" + exports.BASE_DOMAIN;
+exports.WEBSOCKET_HUB = "wss://" + exports.BASE_DOMAIN + "/hub";
+
+exports.API = exports.BASE + "/api";
+exports.AUTH = exports.API + "/auth";
+exports.LOGIN = exports.AUTH + "/login";
+exports.LOGOUT = exports.AUTH + "/logout";
+exports.USERS = exports.API + "/users";
+exports.SERVERS = exports.API + "/guilds";
+exports.CHANNELS = exports.API + "/channels";
+},{}],3:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var PMChannel = (function () {
+ function PMChannel(data, client) {
+ _classCallCheck(this, PMChannel);
+
+ this.user = client.getUser("id", data.recipient.id);
+ this.id = data.id;
+ this.messages = [];
+ }
+
+ _createClass(PMChannel, [{
+ key: "addMessage",
+ value: function addMessage(data) {
+ if (!this.getMessage("id", data.id)) {
+ this.messages.push(data);
+ }
+ return this.getMessage("id", data.id);
+ }
+ }, {
+ key: "getMessage",
+ value: function getMessage(key, value) {
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var message = _step.value;
+
+ if (message[key] === value) {
+ return message;
+ }
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator["return"]) {
+ _iterator["return"]();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+
+ return null;
+ }
+ }, {
+ key: "isPrivate",
+ get: function get() {
+ return true;
+ }
+ }]);
+
+ return PMChannel;
+})();
+
+module.exports = PMChannel;
+},{}],4:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Channel = (function () {
+ function Channel(data, server) {
+ _classCallCheck(this, Channel);
+
+ this.server = server;
+ this.name = data.name;
+ this.type = data.type;
+ this.id = data.id;
+ this.messages = [];
+ //this.isPrivate = isPrivate; //not sure about the implementation of this...
+ }
+
+ _createClass(Channel, [{
+ key: "equals",
+ value: function equals(object) {
+ return object && object.id === this.id;
+ }
+ }, {
+ key: "addMessage",
+ value: function addMessage(data) {
+ if (!this.getMessage("id", data.id)) {
+ this.messages.push(data);
+ }
+ return this.getMessage("id", data.id);
+ }
+ }, {
+ key: "getMessage",
+ value: function getMessage(key, value) {
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var message = _step.value;
+
+ if (message[key] === value) {
+ return message;
+ }
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator["return"]) {
+ _iterator["return"]();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+
+ return null;
+ }
+ }, {
+ key: "toString",
+ value: function toString() {
+ return "#" + this.name;
+ }
+ }, {
+ key: "client",
+ get: function get() {
+ return this.server.client;
+ }
+ }, {
+ key: "isPrivate",
+ get: function get() {
+ return false;
+ }
+ }]);
+
+ return Channel;
+})();
+
+module.exports = Channel;
+},{}],5:[function(require,module,exports){
+"use strict";
+
+var request = require("superagent");
+var Endpoints = require("./Endpoints.js");
+var Client = require("./Client.js");
+
+var Discord = {
+ Endpoints: Endpoints,
+ Client: Client
+};
+
+module.exports = Discord;
+},{"./Client.js":1,"./Endpoints.js":2,"superagent":11}],6:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Invite = (function () {
+ function Invite(data, client) {
+ _classCallCheck(this, Invite);
+
+ this.max_age = data.max_age;
+ this.code = data.code;
+ this.server = client.getServer("id", data.guild.id);
+ this.revoked = data.revoked;
+ this.created_at = Date.parse(data.created_at);
+ this.temporary = data.temporary;
+ this.uses = data.uses;
+ this.max_uses = data.uses;
+ this.inviter = client.addUser(data.inviter);
+ this.xkcd = data.xkcdpass;
+ this.channel = client.getChannel("id", data.channel.id);
+ }
+
+ _createClass(Invite, [{
+ key: "URL",
+ get: function get() {
+ var code = this.xkcd ? this.xkcdpass : this.code;
+ return "https://discord.gg/" + code;
+ }
+ }]);
+
+ return Invite;
+})();
+
+module.exports = Invite;
+},{}],7:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var PMChannel = require("./PMChannel.js");
+
+var Message = (function () {
+ function Message(data, channel, mentions, author) {
+ _classCallCheck(this, Message);
+
+ this.tts = data.tts;
+ this.timestamp = Date.parse(data.timestamp);
+ this.nonce = data.nonce;
+ this.mentions = mentions;
+ this.everyoneMentioned = data.mention_everyone;
+ this.id = data.id;
+ this.embeds = data.embeds;
+ this.editedTimestamp = data.edited_timestamp;
+ this.content = data.content.trim();
+ this.channel = channel;
+ this.author = author;
+ this.attachments = data.attachments;
+ }
+
+ /*exports.Message.prototype.isPM = function() {
+ return ( this.channel instanceof PMChannel );
+ }*/
+
+ _createClass(Message, [{
+ key: "isMentioned",
+ value: function isMentioned(user) {
+ var id = user.id ? user.id : user;
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = this.mentions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var mention = _step.value;
+
+ if (mention.id === id) {
+ return true;
+ }
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator["return"]) {
+ _iterator["return"]();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+
+ return false;
+ }
+ }, {
+ key: "sender",
+ get: function get() {
+ return this.author;
+ }
+ }, {
+ key: "isPrivate",
+ get: function get() {
+ return this.channel.isPrivate;
+ }
+ }]);
+
+ return Message;
+})();
+
+module.exports = Message;
+},{"./PMChannel.js":3}],8:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Server = (function () {
+ function Server(data, client) {
+ _classCallCheck(this, Server);
+
+ this.client = client;
+ this.region = data.region;
+ this.ownerID = data.owner_id;
+ this.name = data.name;
+ this.id = data.id;
+ this.members = [];
+ this.channels = [];
+ this.icon = data.icon;
+ this.afkTimeout = data.afk_timeout;
+ this.afkChannelId = data.afk_channel_id;
+
+ if (!data.members) {
+ data.members = [client.user];
+ return;
+ }
+
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = data.members[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var member = _step.value;
+
+ // first we cache the user in our Discord Client,
+ // then we add it to our list. This way when we
+ // get a user from this server's member list,
+ // it will be identical (unless an async change occurred)
+ // to the client's cache.
+ if (member.user) this.members.push(client.addUser(member.user));
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator["return"]) {
+ _iterator["return"]();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+ }
+
+ _createClass(Server, [{
+ key: "getChannel",
+
+ // get/set
+ value: function getChannel(key, value) {
+ var _iteratorNormalCompletion2 = true;
+ var _didIteratorError2 = false;
+ var _iteratorError2 = undefined;
+
+ try {
+ for (var _iterator2 = this.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
+ var channel = _step2.value;
+
+ if (channel[key] === value) {
+ return channel;
+ }
+ }
+ } catch (err) {
+ _didIteratorError2 = true;
+ _iteratorError2 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion2 && _iterator2["return"]) {
+ _iterator2["return"]();
+ }
+ } finally {
+ if (_didIteratorError2) {
+ throw _iteratorError2;
+ }
+ }
+ }
+
+ return null;
+ }
+ }, {
+ key: "getMember",
+ value: function getMember(key, value) {
+ var _iteratorNormalCompletion3 = true;
+ var _didIteratorError3 = false;
+ var _iteratorError3 = undefined;
+
+ try {
+ for (var _iterator3 = this.members[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
+ var member = _step3.value;
+
+ if (member[key] === value) {
+ return member;
+ }
+ }
+ } catch (err) {
+ _didIteratorError3 = true;
+ _iteratorError3 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion3 && _iterator3["return"]) {
+ _iterator3["return"]();
+ }
+ } finally {
+ if (_didIteratorError3) {
+ throw _iteratorError3;
+ }
+ }
+ }
+
+ return null;
+ }
+ }, {
+ key: "addChannel",
+ value: function addChannel(chann) {
+ if (!this.getChannel("id", chann.id)) {
+ this.channels.push(chann);
+ }
+ return chann;
+ }
+ }, {
+ key: "addMember",
+ value: function addMember(member) {
+ if (!this.getMember("id", member.id)) {
+ this.members.push(member);
+ }
+ return member;
+ }
+ }, {
+ key: "toString",
+ value: function toString() {
+ return this.name;
+ }
+ }, {
+ key: "iconURL",
+ get: function get() {
+ if (!this.icon) return null;
+ return "https://discordapp.com/api/guilds/" + this.id + "/icons/" + this.icon + ".jpg";
+ }
+ }, {
+ key: "afkChannel",
+ get: function get() {
+ if (!this.afkChannelId) return false;
+
+ return this.getChannel("id", this.afkChannelId);
+ }
+ }, {
+ key: "defaultChannel",
+ get: function get() {
+ return this.getChannel("name", "general");
+ }
+ }, {
+ key: "owner",
+ get: function get() {
+ return this.client.getUser("id", this.ownerID);
+ }
+ }]);
+
+ return Server;
+})();
+
+module.exports = Server;
+},{}],9:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var User = (function () {
+ function User(data) {
+ _classCallCheck(this, User);
+
+ this.username = data.username;
+ this.discriminator = data.discriminator;
+ this.id = data.id;
+ this.avatar = data.avatar;
+ }
+
+ // access using user.avatarURL;
+
+ _createClass(User, [{
+ key: "mention",
+ value: function mention() {
+ return "<@" + this.id + ">";
+ }
+ }, {
+ key: "toString",
+ value: function toString() {
+ /*
+ if we embed a user in a String - like so:
+ "Yo " + user + " what's up?"
+ It would generate something along the lines of:
+ "Yo @hydrabolt what's up?"
+ */
+ return this.mention();
+ }
+ }, {
+ key: "equals",
+ value: function equals(object) {
+ return object.id === this.id;
+ }
+ }, {
+ key: "equalsStrict",
+ value: function equalsStrict(object) {
+ return object.id === this.id && object.avatar === this.avatar && object.username === this.username && object.discriminator === this.discriminator;
+ }
+ }, {
+ key: "avatarURL",
+ get: function get() {
+ if (!this.avatar) return null;
+ return "https://discordapp.com/api/users/" + this.id + "/avatars/" + this.avatar + ".jpg";
+ }
+ }]);
+
+ return User;
+})();
+
+module.exports = User;
+},{}],10:[function(require,module,exports){
+
+},{}],11:[function(require,module,exports){
+/**
+ * Module dependencies.
+ */
+
+var Emitter = require('emitter');
+var reduce = require('reduce');
+
+/**
+ * Root reference for iframes.
+ */
+
+var root = 'undefined' == typeof window
+ ? (this || self)
+ : window;
+
+/**
+ * Noop.
+ */
+
+function noop(){};
+
+/**
+ * Check if `obj` is a host object,
+ * we don't want to serialize these :)
+ *
+ * TODO: future proof, move to compoent land
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api private
+ */
+
+function isHost(obj) {
+ var str = {}.toString.call(obj);
+
+ switch (str) {
+ case '[object File]':
+ case '[object Blob]':
+ case '[object FormData]':
+ return true;
+ default:
+ return false;
+ }
+}
+
+/**
+ * Determine XHR.
+ */
+
+request.getXHR = function () {
+ if (root.XMLHttpRequest
+ && (!root.location || 'file:' != root.location.protocol
+ || !root.ActiveXObject)) {
+ return new XMLHttpRequest;
+ } else {
+ try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
+ }
+ return false;
+};
+
+/**
+ * Removes leading and trailing whitespace, added to support IE.
+ *
+ * @param {String} s
+ * @return {String}
+ * @api private
+ */
+
+var trim = ''.trim
+ ? function(s) { return s.trim(); }
+ : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); };
+
+/**
+ * Check if `obj` is an object.
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api private
+ */
+
+function isObject(obj) {
+ return obj === Object(obj);
+}
+
+/**
+ * Serialize the given `obj`.
+ *
+ * @param {Object} obj
+ * @return {String}
+ * @api private
+ */
+
+function serialize(obj) {
+ if (!isObject(obj)) return obj;
+ var pairs = [];
+ for (var key in obj) {
+ if (null != obj[key]) {
+ pairs.push(encodeURIComponent(key)
+ + '=' + encodeURIComponent(obj[key]));
+ }
+ }
+ return pairs.join('&');
+}
+
+/**
+ * Expose serialization method.
+ */
+
+ request.serializeObject = serialize;
+
+ /**
+ * Parse the given x-www-form-urlencoded `str`.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function parseString(str) {
+ var obj = {};
+ var pairs = str.split('&');
+ var parts;
+ var pair;
+
+ for (var i = 0, len = pairs.length; i < len; ++i) {
+ pair = pairs[i];
+ parts = pair.split('=');
+ obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
+ }
+
+ return obj;
+}
+
+/**
+ * Expose parser.
+ */
+
+request.parseString = parseString;
+
+/**
+ * Default MIME type map.
+ *
+ * superagent.types.xml = 'application/xml';
+ *
+ */
+
+request.types = {
+ html: 'text/html',
+ json: 'application/json',
+ xml: 'application/xml',
+ urlencoded: 'application/x-www-form-urlencoded',
+ 'form': 'application/x-www-form-urlencoded',
+ 'form-data': 'application/x-www-form-urlencoded'
+};
+
+/**
+ * Default serialization map.
+ *
+ * superagent.serialize['application/xml'] = function(obj){
+ * return 'generated xml here';
+ * };
+ *
+ */
+
+ request.serialize = {
+ 'application/x-www-form-urlencoded': serialize,
+ 'application/json': JSON.stringify
+ };
+
+ /**
+ * Default parsers.
+ *
+ * superagent.parse['application/xml'] = function(str){
+ * return { object parsed from str };
+ * };
+ *
+ */
+
+request.parse = {
+ 'application/x-www-form-urlencoded': parseString,
+ 'application/json': JSON.parse
+};
+
+/**
+ * Parse the given header `str` into
+ * an object containing the mapped fields.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function parseHeader(str) {
+ var lines = str.split(/\r?\n/);
+ var fields = {};
+ var index;
+ var line;
+ var field;
+ var val;
+
+ lines.pop(); // trailing CRLF
+
+ for (var i = 0, len = lines.length; i < len; ++i) {
+ line = lines[i];
+ index = line.indexOf(':');
+ field = line.slice(0, index).toLowerCase();
+ val = trim(line.slice(index + 1));
+ fields[field] = val;
+ }
+
+ return fields;
+}
+
+/**
+ * Return the mime type for the given `str`.
+ *
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+function type(str){
+ return str.split(/ *; */).shift();
+};
+
+/**
+ * Return header field parameters.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function params(str){
+ return reduce(str.split(/ *; */), function(obj, str){
+ var parts = str.split(/ *= */)
+ , key = parts.shift()
+ , val = parts.shift();
+
+ if (key && val) obj[key] = val;
+ return obj;
+ }, {});
+};
+
+/**
+ * Initialize a new `Response` with the given `xhr`.
+ *
+ * - set flags (.ok, .error, etc)
+ * - parse header
+ *
+ * Examples:
+ *
+ * Aliasing `superagent` as `request` is nice:
+ *
+ * request = superagent;
+ *
+ * We can use the promise-like API, or pass callbacks:
+ *
+ * request.get('/').end(function(res){});
+ * request.get('/', function(res){});
+ *
+ * Sending data can be chained:
+ *
+ * request
+ * .post('/user')
+ * .send({ name: 'tj' })
+ * .end(function(res){});
+ *
+ * Or passed to `.send()`:
+ *
+ * request
+ * .post('/user')
+ * .send({ name: 'tj' }, function(res){});
+ *
+ * Or passed to `.post()`:
+ *
+ * request
+ * .post('/user', { name: 'tj' })
+ * .end(function(res){});
+ *
+ * Or further reduced to a single call for simple cases:
+ *
+ * request
+ * .post('/user', { name: 'tj' }, function(res){});
+ *
+ * @param {XMLHTTPRequest} xhr
+ * @param {Object} options
+ * @api private
+ */
+
+function Response(req, options) {
+ options = options || {};
+ this.req = req;
+ this.xhr = this.req.xhr;
+ // responseText is accessible only if responseType is '' or 'text' and on older browsers
+ this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined')
+ ? this.xhr.responseText
+ : null;
+ this.statusText = this.req.xhr.statusText;
+ this.setStatusProperties(this.xhr.status);
+ this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders());
+ // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but
+ // getResponseHeader still works. so we get content-type even if getting
+ // other headers fails.
+ this.header['content-type'] = this.xhr.getResponseHeader('content-type');
+ this.setHeaderProperties(this.header);
+ this.body = this.req.method != 'HEAD'
+ ? this.parseBody(this.text ? this.text : this.xhr.response)
+ : null;
+}
+
+/**
+ * Get case-insensitive `field` value.
+ *
+ * @param {String} field
+ * @return {String}
+ * @api public
+ */
+
+Response.prototype.get = function(field){
+ return this.header[field.toLowerCase()];
+};
+
+/**
+ * Set header related properties:
+ *
+ * - `.type` the content type without params
+ *
+ * A response of "Content-Type: text/plain; charset=utf-8"
+ * will provide you with a `.type` of "text/plain".
+ *
+ * @param {Object} header
+ * @api private
+ */
+
+Response.prototype.setHeaderProperties = function(header){
+ // content-type
+ var ct = this.header['content-type'] || '';
+ this.type = type(ct);
+
+ // params
+ var obj = params(ct);
+ for (var key in obj) this[key] = obj[key];
+};
+
+/**
+ * Parse the given body `str`.
+ *
+ * Used for auto-parsing of bodies. Parsers
+ * are defined on the `superagent.parse` object.
+ *
+ * @param {String} str
+ * @return {Mixed}
+ * @api private
+ */
+
+Response.prototype.parseBody = function(str){
+ var parse = request.parse[this.type];
+ return parse && str && (str.length || str instanceof Object)
+ ? parse(str)
+ : null;
+};
+
+/**
+ * Set flags such as `.ok` based on `status`.
+ *
+ * For example a 2xx response will give you a `.ok` of __true__
+ * whereas 5xx will be __false__ and `.error` will be __true__. The
+ * `.clientError` and `.serverError` are also available to be more
+ * specific, and `.statusType` is the class of error ranging from 1..5
+ * sometimes useful for mapping respond colors etc.
+ *
+ * "sugar" properties are also defined for common cases. Currently providing:
+ *
+ * - .noContent
+ * - .badRequest
+ * - .unauthorized
+ * - .notAcceptable
+ * - .notFound
+ *
+ * @param {Number} status
+ * @api private
+ */
+
+Response.prototype.setStatusProperties = function(status){
+ // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
+ if (status === 1223) {
+ status = 204;
+ }
+
+ var type = status / 100 | 0;
+
+ // status / class
+ this.status = status;
+ this.statusType = type;
+
+ // basics
+ this.info = 1 == type;
+ this.ok = 2 == type;
+ this.clientError = 4 == type;
+ this.serverError = 5 == type;
+ this.error = (4 == type || 5 == type)
+ ? this.toError()
+ : false;
+
+ // sugar
+ this.accepted = 202 == status;
+ this.noContent = 204 == status;
+ this.badRequest = 400 == status;
+ this.unauthorized = 401 == status;
+ this.notAcceptable = 406 == status;
+ this.notFound = 404 == status;
+ this.forbidden = 403 == status;
+};
+
+/**
+ * Return an `Error` representative of this response.
+ *
+ * @return {Error}
+ * @api public
+ */
+
+Response.prototype.toError = function(){
+ var req = this.req;
+ var method = req.method;
+ var url = req.url;
+
+ var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')';
+ var err = new Error(msg);
+ err.status = this.status;
+ err.method = method;
+ err.url = url;
+
+ return err;
+};
+
+/**
+ * Expose `Response`.
+ */
+
+request.Response = Response;
+
+/**
+ * Initialize a new `Request` with the given `method` and `url`.
+ *
+ * @param {String} method
+ * @param {String} url
+ * @api public
+ */
+
+function Request(method, url) {
+ var self = this;
+ Emitter.call(this);
+ this._query = this._query || [];
+ this.method = method;
+ this.url = url;
+ this.header = {};
+ this._header = {};
+ this.on('end', function(){
+ var err = null;
+ var res = null;
+
+ try {
+ res = new Response(self);
+ } catch(e) {
+ err = new Error('Parser is unable to parse the response');
+ err.parse = true;
+ err.original = e;
+ return self.callback(err);
+ }
+
+ self.emit('response', res);
+
+ if (err) {
+ return self.callback(err, res);
+ }
+
+ if (res.status >= 200 && res.status < 300) {
+ return self.callback(err, res);
+ }
+
+ var new_err = new Error(res.statusText || 'Unsuccessful HTTP response');
+ new_err.original = err;
+ new_err.response = res;
+ new_err.status = res.status;
+
+ self.callback(new_err, res);
+ });
+}
+
+/**
+ * Mixin `Emitter`.
+ */
+
+Emitter(Request.prototype);
+
+/**
+ * Allow for extension
+ */
+
+Request.prototype.use = function(fn) {
+ fn(this);
+ return this;
+}
+
+/**
+ * Set timeout to `ms`.
+ *
+ * @param {Number} ms
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.timeout = function(ms){
+ this._timeout = ms;
+ return this;
+};
+
+/**
+ * Clear previous timeout.
+ *
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.clearTimeout = function(){
+ this._timeout = 0;
+ clearTimeout(this._timer);
+ return this;
+};
+
+/**
+ * Abort the request, and clear potential timeout.
+ *
+ * @return {Request}
+ * @api public
+ */
+
+Request.prototype.abort = function(){
+ if (this.aborted) return;
+ this.aborted = true;
+ this.xhr.abort();
+ this.clearTimeout();
+ this.emit('abort');
+ return this;
+};
+
+/**
+ * Set header `field` to `val`, or multiple fields with one object.
+ *
+ * Examples:
+ *
+ * req.get('/')
+ * .set('Accept', 'application/json')
+ * .set('X-API-Key', 'foobar')
+ * .end(callback);
+ *
+ * req.get('/')
+ * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
+ * .end(callback);
+ *
+ * @param {String|Object} field
+ * @param {String} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.set = function(field, val){
+ if (isObject(field)) {
+ for (var key in field) {
+ this.set(key, field[key]);
+ }
+ return this;
+ }
+ this._header[field.toLowerCase()] = val;
+ this.header[field] = val;
+ return this;
+};
+
+/**
+ * Remove header `field`.
+ *
+ * Example:
+ *
+ * req.get('/')
+ * .unset('User-Agent')
+ * .end(callback);
+ *
+ * @param {String} field
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.unset = function(field){
+ delete this._header[field.toLowerCase()];
+ delete this.header[field];
+ return this;
+};
+
+/**
+ * Get case-insensitive header `field` value.
+ *
+ * @param {String} field
+ * @return {String}
+ * @api private
+ */
+
+Request.prototype.getHeader = function(field){
+ return this._header[field.toLowerCase()];
+};
+
+/**
+ * Set Content-Type to `type`, mapping values from `request.types`.
+ *
+ * Examples:
+ *
+ * superagent.types.xml = 'application/xml';
+ *
+ * request.post('/')
+ * .type('xml')
+ * .send(xmlstring)
+ * .end(callback);
+ *
+ * request.post('/')
+ * .type('application/xml')
+ * .send(xmlstring)
+ * .end(callback);
+ *
+ * @param {String} type
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.type = function(type){
+ this.set('Content-Type', request.types[type] || type);
+ return this;
+};
+
+/**
+ * Set Accept to `type`, mapping values from `request.types`.
+ *
+ * Examples:
+ *
+ * superagent.types.json = 'application/json';
+ *
+ * request.get('/agent')
+ * .accept('json')
+ * .end(callback);
+ *
+ * request.get('/agent')
+ * .accept('application/json')
+ * .end(callback);
+ *
+ * @param {String} accept
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.accept = function(type){
+ this.set('Accept', request.types[type] || type);
+ return this;
+};
+
+/**
+ * Set Authorization field value with `user` and `pass`.
+ *
+ * @param {String} user
+ * @param {String} pass
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.auth = function(user, pass){
+ var str = btoa(user + ':' + pass);
+ this.set('Authorization', 'Basic ' + str);
+ return this;
+};
+
+/**
+* Add query-string `val`.
+*
+* Examples:
+*
+* request.get('/shoes')
+* .query('size=10')
+* .query({ color: 'blue' })
+*
+* @param {Object|String} val
+* @return {Request} for chaining
+* @api public
+*/
+
+Request.prototype.query = function(val){
+ if ('string' != typeof val) val = serialize(val);
+ if (val) this._query.push(val);
+ return this;
+};
+
+/**
+ * Write the field `name` and `val` for "multipart/form-data"
+ * request bodies.
+ *
+ * ``` js
+ * request.post('/upload')
+ * .field('foo', 'bar')
+ * .end(callback);
+ * ```
+ *
+ * @param {String} name
+ * @param {String|Blob|File} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.field = function(name, val){
+ if (!this._formData) this._formData = new root.FormData();
+ this._formData.append(name, val);
+ return this;
+};
+
+/**
+ * Queue the given `file` as an attachment to the specified `field`,
+ * with optional `filename`.
+ *
+ * ``` js
+ * request.post('/upload')
+ * .attach(new Blob(['hey!'], { type: "text/html"}))
+ * .end(callback);
+ * ```
+ *
+ * @param {String} field
+ * @param {Blob|File} file
+ * @param {String} filename
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.attach = function(field, file, filename){
+ if (!this._formData) this._formData = new root.FormData();
+ this._formData.append(field, file, filename);
+ return this;
+};
+
+/**
+ * Send `data`, defaulting the `.type()` to "json" when
+ * an object is given.
+ *
+ * Examples:
+ *
+ * // querystring
+ * request.get('/search')
+ * .end(callback)
+ *
+ * // multiple data "writes"
+ * request.get('/search')
+ * .send({ search: 'query' })
+ * .send({ range: '1..5' })
+ * .send({ order: 'desc' })
+ * .end(callback)
+ *
+ * // manual json
+ * request.post('/user')
+ * .type('json')
+ * .send('{"name":"tj"})
+ * .end(callback)
+ *
+ * // auto json
+ * request.post('/user')
+ * .send({ name: 'tj' })
+ * .end(callback)
+ *
+ * // manual x-www-form-urlencoded
+ * request.post('/user')
+ * .type('form')
+ * .send('name=tj')
+ * .end(callback)
+ *
+ * // auto x-www-form-urlencoded
+ * request.post('/user')
+ * .type('form')
+ * .send({ name: 'tj' })
+ * .end(callback)
+ *
+ * // defaults to x-www-form-urlencoded
+ * request.post('/user')
+ * .send('name=tobi')
+ * .send('species=ferret')
+ * .end(callback)
+ *
+ * @param {String|Object} data
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.send = function(data){
+ var obj = isObject(data);
+ var type = this.getHeader('Content-Type');
+
+ // merge
+ if (obj && isObject(this._data)) {
+ for (var key in data) {
+ this._data[key] = data[key];
+ }
+ } else if ('string' == typeof data) {
+ if (!type) this.type('form');
+ type = this.getHeader('Content-Type');
+ if ('application/x-www-form-urlencoded' == type) {
+ this._data = this._data
+ ? this._data + '&' + data
+ : data;
+ } else {
+ this._data = (this._data || '') + data;
+ }
+ } else {
+ this._data = data;
+ }
+
+ if (!obj || isHost(data)) return this;
+ if (!type) this.type('json');
+ return this;
+};
+
+/**
+ * Invoke the callback with `err` and `res`
+ * and handle arity check.
+ *
+ * @param {Error} err
+ * @param {Response} res
+ * @api private
+ */
+
+Request.prototype.callback = function(err, res){
+ var fn = this._callback;
+ this.clearTimeout();
+ fn(err, res);
+};
+
+/**
+ * Invoke callback with x-domain error.
+ *
+ * @api private
+ */
+
+Request.prototype.crossDomainError = function(){
+ var err = new Error('Origin is not allowed by Access-Control-Allow-Origin');
+ err.crossDomain = true;
+ this.callback(err);
+};
+
+/**
+ * Invoke callback with timeout error.
+ *
+ * @api private
+ */
+
+Request.prototype.timeoutError = function(){
+ var timeout = this._timeout;
+ var err = new Error('timeout of ' + timeout + 'ms exceeded');
+ err.timeout = timeout;
+ this.callback(err);
+};
+
+/**
+ * Enable transmission of cookies with x-domain requests.
+ *
+ * Note that for this to work the origin must not be
+ * using "Access-Control-Allow-Origin" with a wildcard,
+ * and also must set "Access-Control-Allow-Credentials"
+ * to "true".
+ *
+ * @api public
+ */
+
+Request.prototype.withCredentials = function(){
+ this._withCredentials = true;
+ return this;
+};
+
+/**
+ * Initiate request, invoking callback `fn(res)`
+ * with an instanceof `Response`.
+ *
+ * @param {Function} fn
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.end = function(fn){
+ var self = this;
+ var xhr = this.xhr = request.getXHR();
+ var query = this._query.join('&');
+ var timeout = this._timeout;
+ var data = this._formData || this._data;
+
+ // store callback
+ this._callback = fn || noop;
+
+ // state change
+ xhr.onreadystatechange = function(){
+ if (4 != xhr.readyState) return;
+
+ // In IE9, reads to any property (e.g. status) off of an aborted XHR will
+ // result in the error "Could not complete the operation due to error c00c023f"
+ var status;
+ try { status = xhr.status } catch(e) { status = 0; }
+
+ if (0 == status) {
+ if (self.timedout) return self.timeoutError();
+ if (self.aborted) return;
+ return self.crossDomainError();
+ }
+ self.emit('end');
+ };
+
+ // progress
+ var handleProgress = function(e){
+ if (e.total > 0) {
+ e.percent = e.loaded / e.total * 100;
+ }
+ self.emit('progress', e);
+ };
+ if (this.hasListeners('progress')) {
+ xhr.onprogress = handleProgress;
+ }
+ try {
+ if (xhr.upload && this.hasListeners('progress')) {
+ xhr.upload.onprogress = handleProgress;
+ }
+ } catch(e) {
+ // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist.
+ // Reported here:
+ // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context
+ }
+
+ // timeout
+ if (timeout && !this._timer) {
+ this._timer = setTimeout(function(){
+ self.timedout = true;
+ self.abort();
+ }, timeout);
+ }
+
+ // querystring
+ if (query) {
+ query = request.serializeObject(query);
+ this.url += ~this.url.indexOf('?')
+ ? '&' + query
+ : '?' + query;
+ }
+
+ // initiate request
+ xhr.open(this.method, this.url, true);
+
+ // CORS
+ if (this._withCredentials) xhr.withCredentials = true;
+
+ // body
+ if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) {
+ // serialize stuff
+ var contentType = this.getHeader('Content-Type');
+ var serialize = request.serialize[contentType ? contentType.split(';')[0] : ''];
+ if (serialize) data = serialize(data);
+ }
+
+ // set header fields
+ for (var field in this.header) {
+ if (null == this.header[field]) continue;
+ xhr.setRequestHeader(field, this.header[field]);
+ }
+
+ // send stuff
+ this.emit('request', this);
+ xhr.send(data);
+ return this;
+};
+
+/**
+ * Faux promise support
+ *
+ * @param {Function} fulfill
+ * @param {Function} reject
+ * @return {Request}
+ */
+
+Request.prototype.then = function (fulfill, reject) {
+ return this.end(function(err, res) {
+ err ? reject(err) : fulfill(res);
+ });
+}
+
+/**
+ * Expose `Request`.
+ */
+
+request.Request = Request;
+
+/**
+ * Issue a request:
+ *
+ * Examples:
+ *
+ * request('GET', '/users').end(callback)
+ * request('/users').end(callback)
+ * request('/users', callback)
+ *
+ * @param {String} method
+ * @param {String|Function} url or callback
+ * @return {Request}
+ * @api public
+ */
+
+function request(method, url) {
+ // callback
+ if ('function' == typeof url) {
+ return new Request('GET', method).end(url);
+ }
+
+ // url first
+ if (1 == arguments.length) {
+ return new Request('GET', method);
+ }
+
+ return new Request(method, url);
+}
+
+/**
+ * GET `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.get = function(url, data, fn){
+ var req = request('GET', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.query(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * HEAD `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.head = function(url, data, fn){
+ var req = request('HEAD', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * DELETE `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.del = function(url, fn){
+ var req = request('DELETE', url);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * PATCH `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} data
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.patch = function(url, data, fn){
+ var req = request('PATCH', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * POST `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} data
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.post = function(url, data, fn){
+ var req = request('POST', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * PUT `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.put = function(url, data, fn){
+ var req = request('PUT', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * Expose `request`.
+ */
+
+module.exports = request;
+
+},{"emitter":12,"reduce":13}],12:[function(require,module,exports){
+
+/**
+ * Expose `Emitter`.
+ */
+
+module.exports = Emitter;
+
+/**
+ * Initialize a new `Emitter`.
+ *
+ * @api public
+ */
+
+function Emitter(obj) {
+ if (obj) return mixin(obj);
+};
+
+/**
+ * Mixin the emitter properties.
+ *
+ * @param {Object} obj
+ * @return {Object}
+ * @api private
+ */
+
+function mixin(obj) {
+ for (var key in Emitter.prototype) {
+ obj[key] = Emitter.prototype[key];
+ }
+ return obj;
+}
+
+/**
+ * Listen on the given `event` with `fn`.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.on =
+Emitter.prototype.addEventListener = function(event, fn){
+ this._callbacks = this._callbacks || {};
+ (this._callbacks[event] = this._callbacks[event] || [])
+ .push(fn);
+ return this;
+};
+
+/**
+ * Adds an `event` listener that will be invoked a single
+ * time then automatically removed.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.once = function(event, fn){
+ var self = this;
+ this._callbacks = this._callbacks || {};
+
+ function on() {
+ self.off(event, on);
+ fn.apply(this, arguments);
+ }
+
+ on.fn = fn;
+ this.on(event, on);
+ return this;
+};
+
+/**
+ * Remove the given callback for `event` or all
+ * registered callbacks.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.off =
+Emitter.prototype.removeListener =
+Emitter.prototype.removeAllListeners =
+Emitter.prototype.removeEventListener = function(event, fn){
+ this._callbacks = this._callbacks || {};
+
+ // all
+ if (0 == arguments.length) {
+ this._callbacks = {};
+ return this;
+ }
+
+ // specific event
+ var callbacks = this._callbacks[event];
+ if (!callbacks) return this;
+
+ // remove all handlers
+ if (1 == arguments.length) {
+ delete this._callbacks[event];
+ return this;
+ }
+
+ // remove specific handler
+ var cb;
+ for (var i = 0; i < callbacks.length; i++) {
+ cb = callbacks[i];
+ if (cb === fn || cb.fn === fn) {
+ callbacks.splice(i, 1);
+ break;
+ }
+ }
+ return this;
+};
+
+/**
+ * Emit `event` with the given args.
+ *
+ * @param {String} event
+ * @param {Mixed} ...
+ * @return {Emitter}
+ */
+
+Emitter.prototype.emit = function(event){
+ this._callbacks = this._callbacks || {};
+ var args = [].slice.call(arguments, 1)
+ , callbacks = this._callbacks[event];
+
+ if (callbacks) {
+ callbacks = callbacks.slice(0);
+ for (var i = 0, len = callbacks.length; i < len; ++i) {
+ callbacks[i].apply(this, args);
+ }
+ }
+
+ return this;
+};
+
+/**
+ * Return array of callbacks for `event`.
+ *
+ * @param {String} event
+ * @return {Array}
+ * @api public
+ */
+
+Emitter.prototype.listeners = function(event){
+ this._callbacks = this._callbacks || {};
+ return this._callbacks[event] || [];
+};
+
+/**
+ * Check if this emitter has `event` handlers.
+ *
+ * @param {String} event
+ * @return {Boolean}
+ * @api public
+ */
+
+Emitter.prototype.hasListeners = function(event){
+ return !! this.listeners(event).length;
+};
+
+},{}],13:[function(require,module,exports){
+
+/**
+ * Reduce `arr` with `fn`.
+ *
+ * @param {Array} arr
+ * @param {Function} fn
+ * @param {Mixed} initial
+ *
+ * TODO: combatible error handling?
+ */
+
+module.exports = function(arr, fn, initial){
+ var idx = 0;
+ var len = arr.length;
+ var curr = arguments.length == 3
+ ? initial
+ : arr[idx++];
+
+ while (idx < len) {
+ curr = fn.call(null, curr, arr[idx], ++idx, arr);
+ }
+
+ return curr;
+};
+},{}],14:[function(require,module,exports){
+
+/**
+ * Module dependencies.
+ */
+
+var global = (function() { return this; })();
+
+/**
+ * WebSocket constructor.
+ */
+
+var WebSocket = global.WebSocket || global.MozWebSocket;
+
+/**
+ * Module exports.
+ */
+
+module.exports = WebSocket ? ws : null;
+
+/**
+ * WebSocket constructor.
+ *
+ * The third `opts` options object gets ignored in web browsers, since it's
+ * non-standard, and throws a TypeError if passed to the constructor.
+ * See: https://github.com/einaros/ws/issues/227
+ *
+ * @param {String} uri
+ * @param {Array} protocols (optional)
+ * @param {Object) opts (optional)
+ * @api public
+ */
+
+function ws(uri, protocols, opts) {
+ var instance;
+ if (protocols) {
+ instance = new WebSocket(uri, protocols);
+ } else {
+ instance = new WebSocket(uri);
+ }
+ return instance;
+}
+
+if (WebSocket) ws.prototype = WebSocket.prototype;
+
+},{}]},{},[5])(5)
+});
\ No newline at end of file
diff --git a/web-dist/discord.3.3.2.js b/web-dist/discord.3.3.2.js
new file mode 100644
index 000000000..ee7512e4b
--- /dev/null
+++ b/web-dist/discord.3.3.2.js
@@ -0,0 +1,3593 @@
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Discord = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o]*>/g) || [])[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
+ var mention = _step3.value;
+
+ _mentions.push(mention.substring(2, mention.length - 1));
+ }
+ } catch (err) {
+ _didIteratorError3 = true;
+ _iteratorError3 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion3 && _iterator3["return"]) {
+ _iterator3["return"]();
+ }
+ } finally {
+ if (_didIteratorError3) {
+ throw _iteratorError3;
+ }
+ }
+ }
+
+ return _mentions;
+ }
+ });
+
+ return prom;
+ }
+
+ //def createws
+ }, {
+ key: "createws",
+ value: function createws(url) {
+ if (this.websocket) return false;
+
+ var self = this;
+
+ //good to go
+ this.websocket = new WebSocket(url);
+
+ //open
+ this.websocket.onopen = function () {
+ self.trySendConnData(); //try connecting
+ };
+
+ //close
+ this.websocket.onclose = function () {
+ self.trigger("disconnected");
+ };
+
+ //message
+ this.websocket.onmessage = function (e) {
+
+ var dat = false,
+ data = {};
+
+ try {
+ dat = JSON.parse(e.data);
+ data = dat.d;
+ } catch (err) {
+ self.trigger("error", err, e);
+ return;
+ }
+
+ //valid message
+ switch (dat.t) {
+
+ case "READY":
+ self.debug("received ready packet");
+
+ self.user = self.addUser(data.user);
+
+ var _iteratorNormalCompletion4 = true;
+ var _didIteratorError4 = false;
+ var _iteratorError4 = undefined;
+
+ try {
+ for (var _iterator4 = data.guilds[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
+ var _server = _step4.value;
+
+ var server = self.addServer(_server);
+ }
+ } catch (err) {
+ _didIteratorError4 = true;
+ _iteratorError4 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion4 && _iterator4["return"]) {
+ _iterator4["return"]();
+ }
+ } finally {
+ if (_didIteratorError4) {
+ throw _iteratorError4;
+ }
+ }
+ }
+
+ var _iteratorNormalCompletion5 = true;
+ var _didIteratorError5 = false;
+ var _iteratorError5 = undefined;
+
+ try {
+ for (var _iterator5 = data.private_channels[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
+ var _pmc = _step5.value;
+
+ var pmc = self.addPMChannel(_pmc);
+ }
+ } catch (err) {
+ _didIteratorError5 = true;
+ _iteratorError5 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion5 && _iterator5["return"]) {
+ _iterator5["return"]();
+ }
+ } finally {
+ if (_didIteratorError5) {
+ throw _iteratorError5;
+ }
+ }
+ }
+
+ self.trigger("ready");
+ self.readyTime = Date.now();
+ self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users.");
+ self.state = 3;
+ setInterval(function () {
+ self.keepAlive.apply(self);
+ }, data.heartbeat_interval);
+
+ break;
+ case "MESSAGE_CREATE":
+ self.debug("received message");
+
+ var mentions = [];
+ data.mentions = data.mentions || []; //for some reason this was not defined at some point?
+ var _iteratorNormalCompletion6 = true;
+ var _didIteratorError6 = false;
+ var _iteratorError6 = undefined;
+
+ try {
+ for (var _iterator6 = data.mentions[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
+ var mention = _step6.value;
+
+ mentions.push(self.addUser(mention));
+ }
+ } catch (err) {
+ _didIteratorError6 = true;
+ _iteratorError6 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion6 && _iterator6["return"]) {
+ _iterator6["return"]();
+ }
+ } finally {
+ if (_didIteratorError6) {
+ throw _iteratorError6;
+ }
+ }
+ }
+
+ var channel = self.getChannel("id", data.channel_id);
+ if (channel) {
+ var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author)));
+ self.trigger("message", msg);
+ }
+
+ break;
+ case "MESSAGE_DELETE":
+ self.debug("message deleted");
+
+ var channel = self.getChannel("id", data.channel_id);
+ var message = channel.getMessage("id", data.id);
+ if (message) {
+ self.trigger("messageDelete", channel, message);
+ channel.messages.splice(channel.messages.indexOf(message), 1);
+ } else {
+ //don't have the cache of that message ;(
+ self.trigger("messageDelete", channel);
+ }
+ break;
+ case "MESSAGE_UPDATE":
+ self.debug("message updated");
+
+ var channel = self.getChannel("id", data.channel_id);
+ var formerMessage = channel.getMessage("id", data.id);
+
+ if (formerMessage) {
+
+ //new message might be partial, so we need to fill it with whatever the old message was.
+ var info = {};
+
+ for (var key in formerMessage) {
+ info[key] = formerMessage[key];
+ }
+
+ for (var key in data) {
+ info[key] = data[key];
+ }
+
+ var mentions = [];
+ var _iteratorNormalCompletion7 = true;
+ var _didIteratorError7 = false;
+ var _iteratorError7 = undefined;
+
+ try {
+ for (var _iterator7 = info.mentions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
+ var mention = _step7.value;
+
+ mentions.push(self.addUser(mention));
+ }
+ } catch (err) {
+ _didIteratorError7 = true;
+ _iteratorError7 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion7 && _iterator7["return"]) {
+ _iterator7["return"]();
+ }
+ } finally {
+ if (_didIteratorError7) {
+ throw _iteratorError7;
+ }
+ }
+ }
+
+ var newMessage = new Message(info, channel, mentions, formerMessage.author);
+
+ self.trigger("messageUpdate", newMessage, formerMessage);
+
+ channel.messages[channel.messages.indexOf(formerMessage)] = newMessage;
+ }
+
+ // message isn't in cache, and if it's a partial it could cause
+ // all hell to break loose... best to just act as if nothing happened
+
+ break;
+
+ case "GUILD_DELETE":
+
+ var server = self.getServer("id", data.id);
+
+ if (server) {
+ self.serverCache.splice(self.serverCache.indexOf(server), 1);
+ self.trigger("serverDelete", server);
+ }
+
+ break;
+
+ case "CHANNEL_DELETE":
+
+ var channel = self.getChannel("id", data.id);
+
+ if (channel) {
+
+ var server = channel.server;
+
+ if (server) {
+
+ server.channels.splice(server.channels.indexOf(channel), 1);
+ }
+
+ self.trigger("channelDelete", channel);
+
+ self.serverCache.splice(self.serverCache.indexOf(channel), 1);
+ }
+
+ break;
+
+ case "GUILD_CREATE":
+
+ var server = self.getServer("id", data.id);
+
+ if (!server) {
+ //if server doesn't already exist because duh
+ server = self.addServer(data);
+ } /*else if(server.channels.length === 0){
+
+ var srv = new Server(data, self);
+ for(channel of data.channels){
+ srv.channels.push(new Channel(channel, data.id));
+ }
+ self.serverCache[self.serverCache.indexOf(server)] = srv;
+
+ }*/
+
+ if (self.serverCreateListener.get(data.id)) {
+ var cbs = self.serverCreateListener.get(data.id);
+ cbs[0](server); //promise then callback
+ cbs[1](null, server); //legacy callback
+ self.serverCreateListener["delete"](data.id);
+ }
+
+ self.trigger("serverCreate", server);
+
+ break;
+
+ case "CHANNEL_CREATE":
+
+ var channel = self.getChannel("id", data.id);
+
+ if (!channel) {
+
+ var chann = self.addChannel(data, data.guild_id);
+ var srv = self.getServer("id", data.guild_id);
+ if (srv) {
+ srv.addChannel(chann);
+ }
+ self.trigger("channelCreate", chann);
+ }
+
+ break;
+
+ case "GUILD_MEMBER_ADD":
+
+ var server = self.getServer("id", data.guild_id);
+
+ if (server) {
+
+ var user = self.addUser(data.user); //if for whatever reason it doesn't exist..
+
+ if (! ~server.members.indexOf(user)) {
+ server.members.push(user);
+ }
+
+ self.trigger("serverNewMember", user, server);
+ }
+
+ break;
+
+ case "GUILD_MEMBER_REMOVE":
+
+ var server = self.getServer("id", data.guild_id);
+
+ if (server) {
+
+ var user = self.addUser(data.user); //if for whatever reason it doesn't exist..
+
+ if (~server.members.indexOf(user)) {
+ server.members.splice(server.members.indexOf(user), 1);
+ }
+
+ self.trigger("serverRemoveMember", user, server);
+ }
+
+ break;
+
+ case "USER_UPDATE":
+
+ if (self.user && data.id === self.user.id) {
+
+ var newUser = new User(data); //not actually adding to the cache
+
+ self.trigger("userUpdate", newUser, self.user);
+
+ if (~self.userCache.indexOf(self.user)) {
+ self.userCache[self.userCache.indexOf(self.user)] = newUser;
+ }
+
+ self.user = newUser;
+ }
+
+ break;
+
+ case "PRESENCE_UPDATE":
+
+ var userInCache = self.getUser("id", data.user.id);
+
+ if (userInCache) {
+ //user exists
+ var presenceUser = new User(data.user);
+ if (presenceUser.equalsStrict(userInCache)) {
+ //they're exactly the same, an actual presence update
+ self.trigger("presence", {
+ user: userInCache,
+ status: data.status,
+ server: self.getServer("id", data.guild_id),
+ gameId: data.game_id
+ });
+ } else {
+ //one of their details changed.
+ self.trigger("userUpdate", userInCache, presenceUser);
+ self.userCache[self.userCache.indexOf(userInCache)] = presenceUser;
+ }
+ }
+
+ break;
+
+ default:
+ self.debug("received unknown packet");
+ self.trigger("unknown", dat);
+ break;
+
+ }
+ };
+ }
+
+ //def addUser
+ }, {
+ key: "addUser",
+ value: function addUser(data) {
+ if (!this.getUser("id", data.id)) {
+ this.userCache.push(new User(data));
+ }
+ return this.getUser("id", data.id);
+ }
+
+ //def addChannel
+ }, {
+ key: "addChannel",
+ value: function addChannel(data, serverId) {
+ if (!this.getChannel("id", data.id)) {
+ this.channelCache.push(new Channel(data, this.getServer("id", serverId)));
+ }
+ return this.getChannel("id", data.id);
+ }
+ }, {
+ key: "addPMChannel",
+ value: function addPMChannel(data) {
+ if (!this.getPMChannel("id", data.id)) {
+ this.pmChannelCache.push(new PMChannel(data, this));
+ }
+ return this.getPMChannel("id", data.id);
+ }
+
+ //def addServer
+ }, {
+ key: "addServer",
+ value: function addServer(data) {
+
+ var server = this.getServer("id", data.id);
+
+ if (!server) {
+ server = new Server(data, this);
+ this.serverCache.push(server);
+ if (data.channels) {
+ var _iteratorNormalCompletion8 = true;
+ var _didIteratorError8 = false;
+ var _iteratorError8 = undefined;
+
+ try {
+ for (var _iterator8 = data.channels[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
+ var channel = _step8.value;
+
+ server.channels.push(this.addChannel(channel, server.id));
+ }
+ } catch (err) {
+ _didIteratorError8 = true;
+ _iteratorError8 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion8 && _iterator8["return"]) {
+ _iterator8["return"]();
+ }
+ } finally {
+ if (_didIteratorError8) {
+ throw _iteratorError8;
+ }
+ }
+ }
+ }
+ }
+
+ return server;
+ }
+
+ //def getUser
+ }, {
+ key: "getUser",
+ value: function getUser(key, value) {
+ var _iteratorNormalCompletion9 = true;
+ var _didIteratorError9 = false;
+ var _iteratorError9 = undefined;
+
+ try {
+ for (var _iterator9 = this.userCache[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) {
+ var user = _step9.value;
+
+ if (user[key] === value) {
+ return user;
+ }
+ }
+ } catch (err) {
+ _didIteratorError9 = true;
+ _iteratorError9 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion9 && _iterator9["return"]) {
+ _iterator9["return"]();
+ }
+ } finally {
+ if (_didIteratorError9) {
+ throw _iteratorError9;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ //def getChannel
+ }, {
+ key: "getChannel",
+ value: function getChannel(key, value) {
+ var _iteratorNormalCompletion10 = true;
+ var _didIteratorError10 = false;
+ var _iteratorError10 = undefined;
+
+ try {
+ for (var _iterator10 = this.channelCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {
+ var channel = _step10.value;
+
+ if (channel[key] === value) {
+ return channel;
+ }
+ }
+ } catch (err) {
+ _didIteratorError10 = true;
+ _iteratorError10 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion10 && _iterator10["return"]) {
+ _iterator10["return"]();
+ }
+ } finally {
+ if (_didIteratorError10) {
+ throw _iteratorError10;
+ }
+ }
+ }
+
+ return this.getPMChannel(key, value); //might be a PM
+ }
+ }, {
+ key: "getPMChannel",
+ value: function getPMChannel(key, value) {
+ var _iteratorNormalCompletion11 = true;
+ var _didIteratorError11 = false;
+ var _iteratorError11 = undefined;
+
+ try {
+ for (var _iterator11 = this.pmChannelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) {
+ var channel = _step11.value;
+
+ if (channel[key] === value) {
+ return channel;
+ }
+ }
+ } catch (err) {
+ _didIteratorError11 = true;
+ _iteratorError11 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion11 && _iterator11["return"]) {
+ _iterator11["return"]();
+ }
+ } finally {
+ if (_didIteratorError11) {
+ throw _iteratorError11;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ //def getServer
+ }, {
+ key: "getServer",
+ value: function getServer(key, value) {
+ var _iteratorNormalCompletion12 = true;
+ var _didIteratorError12 = false;
+ var _iteratorError12 = undefined;
+
+ try {
+ for (var _iterator12 = this.serverCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) {
+ var server = _step12.value;
+
+ if (server[key] === value) {
+ return server;
+ }
+ }
+ } catch (err) {
+ _didIteratorError12 = true;
+ _iteratorError12 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion12 && _iterator12["return"]) {
+ _iterator12["return"]();
+ }
+ } finally {
+ if (_didIteratorError12) {
+ throw _iteratorError12;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ //def trySendConnData
+ }, {
+ key: "trySendConnData",
+ value: function trySendConnData() {
+
+ if (this.token && !this.alreadySentData) {
+
+ this.alreadySentData = true;
+
+ var data = {
+ op: 2,
+ d: {
+ token: this.token,
+ v: 2,
+ properties: {
+ "$os": "discord.js",
+ "$browser": "discord.js",
+ "$device": "discord.js",
+ "$referrer": "",
+ "$referring_domain": ""
+ }
+ }
+ };
+ this.websocket.send(JSON.stringify(data));
+ }
+ }
+ }, {
+ key: "resolveServerID",
+ value: function resolveServerID(resource) {
+
+ if (resource instanceof Server) {
+ return resource.id;
+ } else if (!isNaN(resource) && resource.length && resource.length === 17) {
+ return resource;
+ }
+ }
+ }, {
+ key: "resolveDestination",
+ value: function resolveDestination(destination) {
+ var channId = false;
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ if (destination instanceof Server) {
+ channId = destination.id; //general is the same as server id
+ } else if (destination instanceof Channel) {
+ channId = destination.id;
+ } else if (destination instanceof Message) {
+ channId = destination.channel.id;
+ } else if (destination instanceof User) {
+
+ //check if we have a PM
+ var _iteratorNormalCompletion13 = true;
+ var _didIteratorError13 = false;
+ var _iteratorError13 = undefined;
+
+ try {
+ for (var _iterator13 = self.pmChannelCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) {
+ var pmc = _step13.value;
+
+ if (pmc.user.equals(destination)) {
+ resolve(pmc.id);
+ return;
+ }
+ }
+
+ //we don't, at this point we're late
+ } catch (err) {
+ _didIteratorError13 = true;
+ _iteratorError13 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion13 && _iterator13["return"]) {
+ _iterator13["return"]();
+ }
+ } finally {
+ if (_didIteratorError13) {
+ throw _iteratorError13;
+ }
+ }
+ }
+
+ self.startPM(destination).then(function (pmc) {
+ console.log(pmc);
+ resolve(pmc.id);
+ })["catch"](reject);
+ } else {
+ channId = destination;
+ }
+ if (channId) resolve(channId);
+ });
+ }
+ }, {
+ key: "_sendMessage",
+ value: function _sendMessage(destination, content, tts, mentions) {
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({
+ content: content,
+ mentions: mentions,
+ tts: tts
+ }).end(function (err, res) {
+
+ if (err) {
+ reject(err);
+ } else {
+ var data = res.body;
+
+ var mentions = [];
+
+ data.mentions = data.mentions || []; //for some reason this was not defined at some point?
+
+ var _iteratorNormalCompletion14 = true;
+ var _didIteratorError14 = false;
+ var _iteratorError14 = undefined;
+
+ try {
+ for (var _iterator14 = data.mentions[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) {
+ var mention = _step14.value;
+
+ mentions.push(self.addUser(mention));
+ }
+ } catch (err) {
+ _didIteratorError14 = true;
+ _iteratorError14 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion14 && _iterator14["return"]) {
+ _iterator14["return"]();
+ }
+ } finally {
+ if (_didIteratorError14) {
+ throw _iteratorError14;
+ }
+ }
+ }
+
+ var channel = self.getChannel("id", data.channel_id);
+ if (channel) {
+ var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author)));
+ resolve(msg);
+ }
+ }
+ });
+ });
+ }
+ }, {
+ key: "_sendFile",
+ value: function _sendFile(destination, attachment) {
+ var attachmentName = arguments.length <= 2 || arguments[2] === undefined ? "DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png" : arguments[2];
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).attach("file", attachment, attachmentName).end(function (err, res) {
+
+ if (err) {
+ reject(err);
+ } else {
+
+ var chann = self.getChannel("id", destination);
+ if (chann) {
+ var msg = chann.addMessage(new Message(res.body, chann, [], self.user));
+ resolve(msg);
+ }
+ }
+ });
+ });
+ }
+ }, {
+ key: "_updateMessage",
+ value: function _updateMessage(message, content) {
+ var self = this;
+ return new Promise(function (resolve, reject) {
+ request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).send({
+ content: content,
+ mentions: []
+ }).end(function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ var msg = new Message(res.body, message.channel, message.mentions, message.sender);
+ resolve(msg);
+ message.channel.messages[message.channel.messages.indexOf(message)] = msg;
+ }
+ });
+ });
+ }
+ }, {
+ key: "_deleteMessage",
+ value: function _deleteMessage(message) {
+ var self = this;
+ return new Promise(function (resolve, reject) {
+
+ request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).end(function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ resolve();
+ }
+ });
+ });
+ }
+ }, {
+ key: "checkQueue",
+ value: function checkQueue(channelID) {
+ var _this = this;
+
+ var self = this;
+
+ if (!this.checkingQueue[channelID]) {
+ (function () {
+ var doNext = function doNext() {
+ if (self.queue[channelID].length === 0) {
+ done();
+ return;
+ }
+ var queuedEvent = self.queue[channelID][0];
+ switch (queuedEvent.action) {
+ case "sendMessage":
+ var msgToSend = queuedEvent;
+ self._sendMessage(channelID, msgToSend.content, msgToSend.tts, msgToSend.mentions).then(function (msg) {
+ msgToSend.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ msgToSend.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ case "sendFile":
+ var fileToSend = queuedEvent;
+ self._sendFile(channelID, fileToSend.attachment, fileToSend.attachmentName).then(function (msg) {
+ fileToSend.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ fileToSend.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ case "updateMessage":
+ var msgToUpd = queuedEvent;
+ self._updateMessage(msgToUpd.message, msgToUpd.content).then(function (msg) {
+ msgToUpd.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ msgToUpd.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ case "deleteMessage":
+ var msgToDel = queuedEvent;
+ self._deleteMessage(msgToDel.message).then(function (msg) {
+ msgToDel.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ msgToDel.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ default:
+ done();
+ break;
+ }
+ };
+
+ var done = function done() {
+ self.checkingQueue[channelID] = false;
+ return;
+ };
+
+ //if we aren't already checking this queue.
+ _this.checkingQueue[channelID] = true;
+ doNext();
+ })();
+ }
+ }
+ }, {
+ key: "uptime",
+ get: function get() {
+
+ return this.readyTime ? Date.now() - this.readyTime : null;
+ }
+ }, {
+ key: "ready",
+ get: function get() {
+ return this.state === 3;
+ }
+ }, {
+ key: "servers",
+ get: function get() {
+ return this.serverCache;
+ }
+ }, {
+ key: "channels",
+ get: function get() {
+ return this.channelCache;
+ }
+ }, {
+ key: "users",
+ get: function get() {
+ return this.userCache;
+ }
+ }, {
+ key: "PMChannels",
+ get: function get() {
+ return this.pmChannelCache;
+ }
+ }, {
+ key: "messages",
+ get: function get() {
+
+ var msgs = [];
+ var _iteratorNormalCompletion15 = true;
+ var _didIteratorError15 = false;
+ var _iteratorError15 = undefined;
+
+ try {
+ for (var _iterator15 = this.channelCache[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) {
+ var channel = _step15.value;
+
+ msgs = msgs.concat(channel.messages);
+ }
+ } catch (err) {
+ _didIteratorError15 = true;
+ _iteratorError15 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion15 && _iterator15["return"]) {
+ _iterator15["return"]();
+ }
+ } finally {
+ if (_didIteratorError15) {
+ throw _iteratorError15;
+ }
+ }
+ }
+
+ return msgs;
+ }
+ }]);
+
+ return Client;
+})();
+
+function getGateway() {
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ request.get(Endpoints.API + "/gateway").end(function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ resolve(res.body.url);
+ }
+ });
+ });
+}
+
+module.exports = Client;
+},{"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,"fs":10,"superagent":11,"ws":14}],2:[function(require,module,exports){
+"use strict";
+
+exports.BASE_DOMAIN = "discordapp.com";
+exports.BASE = "https://" + exports.BASE_DOMAIN;
+exports.WEBSOCKET_HUB = "wss://" + exports.BASE_DOMAIN + "/hub";
+
+exports.API = exports.BASE + "/api";
+exports.AUTH = exports.API + "/auth";
+exports.LOGIN = exports.AUTH + "/login";
+exports.LOGOUT = exports.AUTH + "/logout";
+exports.USERS = exports.API + "/users";
+exports.SERVERS = exports.API + "/guilds";
+exports.CHANNELS = exports.API + "/channels";
+},{}],3:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var PMChannel = (function () {
+ function PMChannel(data, client) {
+ _classCallCheck(this, PMChannel);
+
+ this.user = client.getUser("id", data.recipient.id);
+ this.id = data.id;
+ this.messages = [];
+ }
+
+ _createClass(PMChannel, [{
+ key: "addMessage",
+ value: function addMessage(data) {
+ if (!this.getMessage("id", data.id)) {
+ this.messages.push(data);
+ }
+ return this.getMessage("id", data.id);
+ }
+ }, {
+ key: "getMessage",
+ value: function getMessage(key, value) {
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var message = _step.value;
+
+ if (message[key] === value) {
+ return message;
+ }
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator["return"]) {
+ _iterator["return"]();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+
+ return null;
+ }
+ }, {
+ key: "isPrivate",
+ get: function get() {
+ return true;
+ }
+ }]);
+
+ return PMChannel;
+})();
+
+module.exports = PMChannel;
+},{}],4:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Channel = (function () {
+ function Channel(data, server) {
+ _classCallCheck(this, Channel);
+
+ this.server = server;
+ this.name = data.name;
+ this.type = data.type;
+ this.id = data.id;
+ this.messages = [];
+ //this.isPrivate = isPrivate; //not sure about the implementation of this...
+ }
+
+ _createClass(Channel, [{
+ key: "equals",
+ value: function equals(object) {
+ return object && object.id === this.id;
+ }
+ }, {
+ key: "addMessage",
+ value: function addMessage(data) {
+ if (!this.getMessage("id", data.id)) {
+ this.messages.push(data);
+ }
+ return this.getMessage("id", data.id);
+ }
+ }, {
+ key: "getMessage",
+ value: function getMessage(key, value) {
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var message = _step.value;
+
+ if (message[key] === value) {
+ return message;
+ }
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator["return"]) {
+ _iterator["return"]();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+
+ return null;
+ }
+ }, {
+ key: "toString",
+ value: function toString() {
+ return "#" + this.name;
+ }
+ }, {
+ key: "client",
+ get: function get() {
+ return this.server.client;
+ }
+ }, {
+ key: "isPrivate",
+ get: function get() {
+ return false;
+ }
+ }]);
+
+ return Channel;
+})();
+
+module.exports = Channel;
+},{}],5:[function(require,module,exports){
+"use strict";
+
+var request = require("superagent");
+var Endpoints = require("./Endpoints.js");
+var Client = require("./Client.js");
+
+var Discord = {
+ Endpoints: Endpoints,
+ Client: Client
+};
+
+module.exports = Discord;
+},{"./Client.js":1,"./Endpoints.js":2,"superagent":11}],6:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Invite = (function () {
+ function Invite(data, client) {
+ _classCallCheck(this, Invite);
+
+ this.max_age = data.max_age;
+ this.code = data.code;
+ this.server = client.getServer("id", data.guild.id);
+ this.revoked = data.revoked;
+ this.created_at = Date.parse(data.created_at);
+ this.temporary = data.temporary;
+ this.uses = data.uses;
+ this.max_uses = data.uses;
+ this.inviter = client.addUser(data.inviter);
+ this.xkcd = data.xkcdpass;
+ this.channel = client.getChannel("id", data.channel.id);
+ }
+
+ _createClass(Invite, [{
+ key: "URL",
+ get: function get() {
+ var code = this.xkcd ? this.xkcdpass : this.code;
+ return "https://discord.gg/" + code;
+ }
+ }]);
+
+ return Invite;
+})();
+
+module.exports = Invite;
+},{}],7:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var PMChannel = require("./PMChannel.js");
+
+var Message = (function () {
+ function Message(data, channel, mentions, author) {
+ _classCallCheck(this, Message);
+
+ this.tts = data.tts;
+ this.timestamp = Date.parse(data.timestamp);
+ this.nonce = data.nonce;
+ this.mentions = mentions;
+ this.everyoneMentioned = data.mention_everyone;
+ this.id = data.id;
+ this.embeds = data.embeds;
+ this.editedTimestamp = data.edited_timestamp;
+ this.content = data.content.trim();
+ this.channel = channel;
+ this.author = author;
+ this.attachments = data.attachments;
+ }
+
+ /*exports.Message.prototype.isPM = function() {
+ return ( this.channel instanceof PMChannel );
+ }*/
+
+ _createClass(Message, [{
+ key: "isMentioned",
+ value: function isMentioned(user) {
+ var id = user.id ? user.id : user;
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = this.mentions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var mention = _step.value;
+
+ if (mention.id === id) {
+ return true;
+ }
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator["return"]) {
+ _iterator["return"]();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+
+ return false;
+ }
+ }, {
+ key: "sender",
+ get: function get() {
+ return this.author;
+ }
+ }, {
+ key: "isPrivate",
+ get: function get() {
+ return this.channel.isPrivate;
+ }
+ }]);
+
+ return Message;
+})();
+
+module.exports = Message;
+},{"./PMChannel.js":3}],8:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Server = (function () {
+ function Server(data, client) {
+ _classCallCheck(this, Server);
+
+ this.client = client;
+ this.region = data.region;
+ this.ownerID = data.owner_id;
+ this.name = data.name;
+ this.id = data.id;
+ this.members = [];
+ this.channels = [];
+ this.icon = data.icon;
+ this.afkTimeout = data.afk_timeout;
+ this.afkChannelId = data.afk_channel_id;
+
+ if (!data.members) {
+ data.members = [client.user];
+ return;
+ }
+
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = data.members[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var member = _step.value;
+
+ // first we cache the user in our Discord Client,
+ // then we add it to our list. This way when we
+ // get a user from this server's member list,
+ // it will be identical (unless an async change occurred)
+ // to the client's cache.
+ if (member.user) this.members.push(client.addUser(member.user));
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator["return"]) {
+ _iterator["return"]();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+ }
+
+ _createClass(Server, [{
+ key: "getChannel",
+
+ // get/set
+ value: function getChannel(key, value) {
+ var _iteratorNormalCompletion2 = true;
+ var _didIteratorError2 = false;
+ var _iteratorError2 = undefined;
+
+ try {
+ for (var _iterator2 = this.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
+ var channel = _step2.value;
+
+ if (channel[key] === value) {
+ return channel;
+ }
+ }
+ } catch (err) {
+ _didIteratorError2 = true;
+ _iteratorError2 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion2 && _iterator2["return"]) {
+ _iterator2["return"]();
+ }
+ } finally {
+ if (_didIteratorError2) {
+ throw _iteratorError2;
+ }
+ }
+ }
+
+ return null;
+ }
+ }, {
+ key: "getMember",
+ value: function getMember(key, value) {
+ var _iteratorNormalCompletion3 = true;
+ var _didIteratorError3 = false;
+ var _iteratorError3 = undefined;
+
+ try {
+ for (var _iterator3 = this.members[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
+ var member = _step3.value;
+
+ if (member[key] === value) {
+ return member;
+ }
+ }
+ } catch (err) {
+ _didIteratorError3 = true;
+ _iteratorError3 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion3 && _iterator3["return"]) {
+ _iterator3["return"]();
+ }
+ } finally {
+ if (_didIteratorError3) {
+ throw _iteratorError3;
+ }
+ }
+ }
+
+ return null;
+ }
+ }, {
+ key: "addChannel",
+ value: function addChannel(chann) {
+ if (!this.getChannel("id", chann.id)) {
+ this.channels.push(chann);
+ }
+ return chann;
+ }
+ }, {
+ key: "addMember",
+ value: function addMember(member) {
+ if (!this.getMember("id", member.id)) {
+ this.members.push(member);
+ }
+ return member;
+ }
+ }, {
+ key: "toString",
+ value: function toString() {
+ return this.name;
+ }
+ }, {
+ key: "iconURL",
+ get: function get() {
+ if (!this.icon) return null;
+ return "https://discordapp.com/api/guilds/" + this.id + "/icons/" + this.icon + ".jpg";
+ }
+ }, {
+ key: "afkChannel",
+ get: function get() {
+ if (!this.afkChannelId) return false;
+
+ return this.getChannel("id", this.afkChannelId);
+ }
+ }, {
+ key: "defaultChannel",
+ get: function get() {
+ return this.getChannel("name", "general");
+ }
+ }, {
+ key: "owner",
+ get: function get() {
+ return this.client.getUser("id", this.ownerID);
+ }
+ }]);
+
+ return Server;
+})();
+
+module.exports = Server;
+},{}],9:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var User = (function () {
+ function User(data) {
+ _classCallCheck(this, User);
+
+ this.username = data.username;
+ this.discriminator = data.discriminator;
+ this.id = data.id;
+ this.avatar = data.avatar;
+ }
+
+ // access using user.avatarURL;
+
+ _createClass(User, [{
+ key: "mention",
+ value: function mention() {
+ return "<@" + this.id + ">";
+ }
+ }, {
+ key: "toString",
+ value: function toString() {
+ /*
+ if we embed a user in a String - like so:
+ "Yo " + user + " what's up?"
+ It would generate something along the lines of:
+ "Yo @hydrabolt what's up?"
+ */
+ return this.mention();
+ }
+ }, {
+ key: "equals",
+ value: function equals(object) {
+ return object.id === this.id;
+ }
+ }, {
+ key: "equalsStrict",
+ value: function equalsStrict(object) {
+ return object.id === this.id && object.avatar === this.avatar && object.username === this.username && object.discriminator === this.discriminator;
+ }
+ }, {
+ key: "avatarURL",
+ get: function get() {
+ if (!this.avatar) return null;
+ return "https://discordapp.com/api/users/" + this.id + "/avatars/" + this.avatar + ".jpg";
+ }
+ }]);
+
+ return User;
+})();
+
+module.exports = User;
+},{}],10:[function(require,module,exports){
+
+},{}],11:[function(require,module,exports){
+/**
+ * Module dependencies.
+ */
+
+var Emitter = require('emitter');
+var reduce = require('reduce');
+
+/**
+ * Root reference for iframes.
+ */
+
+var root = 'undefined' == typeof window
+ ? (this || self)
+ : window;
+
+/**
+ * Noop.
+ */
+
+function noop(){};
+
+/**
+ * Check if `obj` is a host object,
+ * we don't want to serialize these :)
+ *
+ * TODO: future proof, move to compoent land
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api private
+ */
+
+function isHost(obj) {
+ var str = {}.toString.call(obj);
+
+ switch (str) {
+ case '[object File]':
+ case '[object Blob]':
+ case '[object FormData]':
+ return true;
+ default:
+ return false;
+ }
+}
+
+/**
+ * Determine XHR.
+ */
+
+request.getXHR = function () {
+ if (root.XMLHttpRequest
+ && (!root.location || 'file:' != root.location.protocol
+ || !root.ActiveXObject)) {
+ return new XMLHttpRequest;
+ } else {
+ try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
+ }
+ return false;
+};
+
+/**
+ * Removes leading and trailing whitespace, added to support IE.
+ *
+ * @param {String} s
+ * @return {String}
+ * @api private
+ */
+
+var trim = ''.trim
+ ? function(s) { return s.trim(); }
+ : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); };
+
+/**
+ * Check if `obj` is an object.
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api private
+ */
+
+function isObject(obj) {
+ return obj === Object(obj);
+}
+
+/**
+ * Serialize the given `obj`.
+ *
+ * @param {Object} obj
+ * @return {String}
+ * @api private
+ */
+
+function serialize(obj) {
+ if (!isObject(obj)) return obj;
+ var pairs = [];
+ for (var key in obj) {
+ if (null != obj[key]) {
+ pairs.push(encodeURIComponent(key)
+ + '=' + encodeURIComponent(obj[key]));
+ }
+ }
+ return pairs.join('&');
+}
+
+/**
+ * Expose serialization method.
+ */
+
+ request.serializeObject = serialize;
+
+ /**
+ * Parse the given x-www-form-urlencoded `str`.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function parseString(str) {
+ var obj = {};
+ var pairs = str.split('&');
+ var parts;
+ var pair;
+
+ for (var i = 0, len = pairs.length; i < len; ++i) {
+ pair = pairs[i];
+ parts = pair.split('=');
+ obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
+ }
+
+ return obj;
+}
+
+/**
+ * Expose parser.
+ */
+
+request.parseString = parseString;
+
+/**
+ * Default MIME type map.
+ *
+ * superagent.types.xml = 'application/xml';
+ *
+ */
+
+request.types = {
+ html: 'text/html',
+ json: 'application/json',
+ xml: 'application/xml',
+ urlencoded: 'application/x-www-form-urlencoded',
+ 'form': 'application/x-www-form-urlencoded',
+ 'form-data': 'application/x-www-form-urlencoded'
+};
+
+/**
+ * Default serialization map.
+ *
+ * superagent.serialize['application/xml'] = function(obj){
+ * return 'generated xml here';
+ * };
+ *
+ */
+
+ request.serialize = {
+ 'application/x-www-form-urlencoded': serialize,
+ 'application/json': JSON.stringify
+ };
+
+ /**
+ * Default parsers.
+ *
+ * superagent.parse['application/xml'] = function(str){
+ * return { object parsed from str };
+ * };
+ *
+ */
+
+request.parse = {
+ 'application/x-www-form-urlencoded': parseString,
+ 'application/json': JSON.parse
+};
+
+/**
+ * Parse the given header `str` into
+ * an object containing the mapped fields.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function parseHeader(str) {
+ var lines = str.split(/\r?\n/);
+ var fields = {};
+ var index;
+ var line;
+ var field;
+ var val;
+
+ lines.pop(); // trailing CRLF
+
+ for (var i = 0, len = lines.length; i < len; ++i) {
+ line = lines[i];
+ index = line.indexOf(':');
+ field = line.slice(0, index).toLowerCase();
+ val = trim(line.slice(index + 1));
+ fields[field] = val;
+ }
+
+ return fields;
+}
+
+/**
+ * Return the mime type for the given `str`.
+ *
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+function type(str){
+ return str.split(/ *; */).shift();
+};
+
+/**
+ * Return header field parameters.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function params(str){
+ return reduce(str.split(/ *; */), function(obj, str){
+ var parts = str.split(/ *= */)
+ , key = parts.shift()
+ , val = parts.shift();
+
+ if (key && val) obj[key] = val;
+ return obj;
+ }, {});
+};
+
+/**
+ * Initialize a new `Response` with the given `xhr`.
+ *
+ * - set flags (.ok, .error, etc)
+ * - parse header
+ *
+ * Examples:
+ *
+ * Aliasing `superagent` as `request` is nice:
+ *
+ * request = superagent;
+ *
+ * We can use the promise-like API, or pass callbacks:
+ *
+ * request.get('/').end(function(res){});
+ * request.get('/', function(res){});
+ *
+ * Sending data can be chained:
+ *
+ * request
+ * .post('/user')
+ * .send({ name: 'tj' })
+ * .end(function(res){});
+ *
+ * Or passed to `.send()`:
+ *
+ * request
+ * .post('/user')
+ * .send({ name: 'tj' }, function(res){});
+ *
+ * Or passed to `.post()`:
+ *
+ * request
+ * .post('/user', { name: 'tj' })
+ * .end(function(res){});
+ *
+ * Or further reduced to a single call for simple cases:
+ *
+ * request
+ * .post('/user', { name: 'tj' }, function(res){});
+ *
+ * @param {XMLHTTPRequest} xhr
+ * @param {Object} options
+ * @api private
+ */
+
+function Response(req, options) {
+ options = options || {};
+ this.req = req;
+ this.xhr = this.req.xhr;
+ // responseText is accessible only if responseType is '' or 'text' and on older browsers
+ this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined')
+ ? this.xhr.responseText
+ : null;
+ this.statusText = this.req.xhr.statusText;
+ this.setStatusProperties(this.xhr.status);
+ this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders());
+ // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but
+ // getResponseHeader still works. so we get content-type even if getting
+ // other headers fails.
+ this.header['content-type'] = this.xhr.getResponseHeader('content-type');
+ this.setHeaderProperties(this.header);
+ this.body = this.req.method != 'HEAD'
+ ? this.parseBody(this.text ? this.text : this.xhr.response)
+ : null;
+}
+
+/**
+ * Get case-insensitive `field` value.
+ *
+ * @param {String} field
+ * @return {String}
+ * @api public
+ */
+
+Response.prototype.get = function(field){
+ return this.header[field.toLowerCase()];
+};
+
+/**
+ * Set header related properties:
+ *
+ * - `.type` the content type without params
+ *
+ * A response of "Content-Type: text/plain; charset=utf-8"
+ * will provide you with a `.type` of "text/plain".
+ *
+ * @param {Object} header
+ * @api private
+ */
+
+Response.prototype.setHeaderProperties = function(header){
+ // content-type
+ var ct = this.header['content-type'] || '';
+ this.type = type(ct);
+
+ // params
+ var obj = params(ct);
+ for (var key in obj) this[key] = obj[key];
+};
+
+/**
+ * Parse the given body `str`.
+ *
+ * Used for auto-parsing of bodies. Parsers
+ * are defined on the `superagent.parse` object.
+ *
+ * @param {String} str
+ * @return {Mixed}
+ * @api private
+ */
+
+Response.prototype.parseBody = function(str){
+ var parse = request.parse[this.type];
+ return parse && str && (str.length || str instanceof Object)
+ ? parse(str)
+ : null;
+};
+
+/**
+ * Set flags such as `.ok` based on `status`.
+ *
+ * For example a 2xx response will give you a `.ok` of __true__
+ * whereas 5xx will be __false__ and `.error` will be __true__. The
+ * `.clientError` and `.serverError` are also available to be more
+ * specific, and `.statusType` is the class of error ranging from 1..5
+ * sometimes useful for mapping respond colors etc.
+ *
+ * "sugar" properties are also defined for common cases. Currently providing:
+ *
+ * - .noContent
+ * - .badRequest
+ * - .unauthorized
+ * - .notAcceptable
+ * - .notFound
+ *
+ * @param {Number} status
+ * @api private
+ */
+
+Response.prototype.setStatusProperties = function(status){
+ // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
+ if (status === 1223) {
+ status = 204;
+ }
+
+ var type = status / 100 | 0;
+
+ // status / class
+ this.status = status;
+ this.statusType = type;
+
+ // basics
+ this.info = 1 == type;
+ this.ok = 2 == type;
+ this.clientError = 4 == type;
+ this.serverError = 5 == type;
+ this.error = (4 == type || 5 == type)
+ ? this.toError()
+ : false;
+
+ // sugar
+ this.accepted = 202 == status;
+ this.noContent = 204 == status;
+ this.badRequest = 400 == status;
+ this.unauthorized = 401 == status;
+ this.notAcceptable = 406 == status;
+ this.notFound = 404 == status;
+ this.forbidden = 403 == status;
+};
+
+/**
+ * Return an `Error` representative of this response.
+ *
+ * @return {Error}
+ * @api public
+ */
+
+Response.prototype.toError = function(){
+ var req = this.req;
+ var method = req.method;
+ var url = req.url;
+
+ var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')';
+ var err = new Error(msg);
+ err.status = this.status;
+ err.method = method;
+ err.url = url;
+
+ return err;
+};
+
+/**
+ * Expose `Response`.
+ */
+
+request.Response = Response;
+
+/**
+ * Initialize a new `Request` with the given `method` and `url`.
+ *
+ * @param {String} method
+ * @param {String} url
+ * @api public
+ */
+
+function Request(method, url) {
+ var self = this;
+ Emitter.call(this);
+ this._query = this._query || [];
+ this.method = method;
+ this.url = url;
+ this.header = {};
+ this._header = {};
+ this.on('end', function(){
+ var err = null;
+ var res = null;
+
+ try {
+ res = new Response(self);
+ } catch(e) {
+ err = new Error('Parser is unable to parse the response');
+ err.parse = true;
+ err.original = e;
+ return self.callback(err);
+ }
+
+ self.emit('response', res);
+
+ if (err) {
+ return self.callback(err, res);
+ }
+
+ if (res.status >= 200 && res.status < 300) {
+ return self.callback(err, res);
+ }
+
+ var new_err = new Error(res.statusText || 'Unsuccessful HTTP response');
+ new_err.original = err;
+ new_err.response = res;
+ new_err.status = res.status;
+
+ self.callback(new_err, res);
+ });
+}
+
+/**
+ * Mixin `Emitter`.
+ */
+
+Emitter(Request.prototype);
+
+/**
+ * Allow for extension
+ */
+
+Request.prototype.use = function(fn) {
+ fn(this);
+ return this;
+}
+
+/**
+ * Set timeout to `ms`.
+ *
+ * @param {Number} ms
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.timeout = function(ms){
+ this._timeout = ms;
+ return this;
+};
+
+/**
+ * Clear previous timeout.
+ *
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.clearTimeout = function(){
+ this._timeout = 0;
+ clearTimeout(this._timer);
+ return this;
+};
+
+/**
+ * Abort the request, and clear potential timeout.
+ *
+ * @return {Request}
+ * @api public
+ */
+
+Request.prototype.abort = function(){
+ if (this.aborted) return;
+ this.aborted = true;
+ this.xhr.abort();
+ this.clearTimeout();
+ this.emit('abort');
+ return this;
+};
+
+/**
+ * Set header `field` to `val`, or multiple fields with one object.
+ *
+ * Examples:
+ *
+ * req.get('/')
+ * .set('Accept', 'application/json')
+ * .set('X-API-Key', 'foobar')
+ * .end(callback);
+ *
+ * req.get('/')
+ * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
+ * .end(callback);
+ *
+ * @param {String|Object} field
+ * @param {String} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.set = function(field, val){
+ if (isObject(field)) {
+ for (var key in field) {
+ this.set(key, field[key]);
+ }
+ return this;
+ }
+ this._header[field.toLowerCase()] = val;
+ this.header[field] = val;
+ return this;
+};
+
+/**
+ * Remove header `field`.
+ *
+ * Example:
+ *
+ * req.get('/')
+ * .unset('User-Agent')
+ * .end(callback);
+ *
+ * @param {String} field
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.unset = function(field){
+ delete this._header[field.toLowerCase()];
+ delete this.header[field];
+ return this;
+};
+
+/**
+ * Get case-insensitive header `field` value.
+ *
+ * @param {String} field
+ * @return {String}
+ * @api private
+ */
+
+Request.prototype.getHeader = function(field){
+ return this._header[field.toLowerCase()];
+};
+
+/**
+ * Set Content-Type to `type`, mapping values from `request.types`.
+ *
+ * Examples:
+ *
+ * superagent.types.xml = 'application/xml';
+ *
+ * request.post('/')
+ * .type('xml')
+ * .send(xmlstring)
+ * .end(callback);
+ *
+ * request.post('/')
+ * .type('application/xml')
+ * .send(xmlstring)
+ * .end(callback);
+ *
+ * @param {String} type
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.type = function(type){
+ this.set('Content-Type', request.types[type] || type);
+ return this;
+};
+
+/**
+ * Set Accept to `type`, mapping values from `request.types`.
+ *
+ * Examples:
+ *
+ * superagent.types.json = 'application/json';
+ *
+ * request.get('/agent')
+ * .accept('json')
+ * .end(callback);
+ *
+ * request.get('/agent')
+ * .accept('application/json')
+ * .end(callback);
+ *
+ * @param {String} accept
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.accept = function(type){
+ this.set('Accept', request.types[type] || type);
+ return this;
+};
+
+/**
+ * Set Authorization field value with `user` and `pass`.
+ *
+ * @param {String} user
+ * @param {String} pass
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.auth = function(user, pass){
+ var str = btoa(user + ':' + pass);
+ this.set('Authorization', 'Basic ' + str);
+ return this;
+};
+
+/**
+* Add query-string `val`.
+*
+* Examples:
+*
+* request.get('/shoes')
+* .query('size=10')
+* .query({ color: 'blue' })
+*
+* @param {Object|String} val
+* @return {Request} for chaining
+* @api public
+*/
+
+Request.prototype.query = function(val){
+ if ('string' != typeof val) val = serialize(val);
+ if (val) this._query.push(val);
+ return this;
+};
+
+/**
+ * Write the field `name` and `val` for "multipart/form-data"
+ * request bodies.
+ *
+ * ``` js
+ * request.post('/upload')
+ * .field('foo', 'bar')
+ * .end(callback);
+ * ```
+ *
+ * @param {String} name
+ * @param {String|Blob|File} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.field = function(name, val){
+ if (!this._formData) this._formData = new root.FormData();
+ this._formData.append(name, val);
+ return this;
+};
+
+/**
+ * Queue the given `file` as an attachment to the specified `field`,
+ * with optional `filename`.
+ *
+ * ``` js
+ * request.post('/upload')
+ * .attach(new Blob(['hey!'], { type: "text/html"}))
+ * .end(callback);
+ * ```
+ *
+ * @param {String} field
+ * @param {Blob|File} file
+ * @param {String} filename
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.attach = function(field, file, filename){
+ if (!this._formData) this._formData = new root.FormData();
+ this._formData.append(field, file, filename);
+ return this;
+};
+
+/**
+ * Send `data`, defaulting the `.type()` to "json" when
+ * an object is given.
+ *
+ * Examples:
+ *
+ * // querystring
+ * request.get('/search')
+ * .end(callback)
+ *
+ * // multiple data "writes"
+ * request.get('/search')
+ * .send({ search: 'query' })
+ * .send({ range: '1..5' })
+ * .send({ order: 'desc' })
+ * .end(callback)
+ *
+ * // manual json
+ * request.post('/user')
+ * .type('json')
+ * .send('{"name":"tj"})
+ * .end(callback)
+ *
+ * // auto json
+ * request.post('/user')
+ * .send({ name: 'tj' })
+ * .end(callback)
+ *
+ * // manual x-www-form-urlencoded
+ * request.post('/user')
+ * .type('form')
+ * .send('name=tj')
+ * .end(callback)
+ *
+ * // auto x-www-form-urlencoded
+ * request.post('/user')
+ * .type('form')
+ * .send({ name: 'tj' })
+ * .end(callback)
+ *
+ * // defaults to x-www-form-urlencoded
+ * request.post('/user')
+ * .send('name=tobi')
+ * .send('species=ferret')
+ * .end(callback)
+ *
+ * @param {String|Object} data
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.send = function(data){
+ var obj = isObject(data);
+ var type = this.getHeader('Content-Type');
+
+ // merge
+ if (obj && isObject(this._data)) {
+ for (var key in data) {
+ this._data[key] = data[key];
+ }
+ } else if ('string' == typeof data) {
+ if (!type) this.type('form');
+ type = this.getHeader('Content-Type');
+ if ('application/x-www-form-urlencoded' == type) {
+ this._data = this._data
+ ? this._data + '&' + data
+ : data;
+ } else {
+ this._data = (this._data || '') + data;
+ }
+ } else {
+ this._data = data;
+ }
+
+ if (!obj || isHost(data)) return this;
+ if (!type) this.type('json');
+ return this;
+};
+
+/**
+ * Invoke the callback with `err` and `res`
+ * and handle arity check.
+ *
+ * @param {Error} err
+ * @param {Response} res
+ * @api private
+ */
+
+Request.prototype.callback = function(err, res){
+ var fn = this._callback;
+ this.clearTimeout();
+ fn(err, res);
+};
+
+/**
+ * Invoke callback with x-domain error.
+ *
+ * @api private
+ */
+
+Request.prototype.crossDomainError = function(){
+ var err = new Error('Origin is not allowed by Access-Control-Allow-Origin');
+ err.crossDomain = true;
+ this.callback(err);
+};
+
+/**
+ * Invoke callback with timeout error.
+ *
+ * @api private
+ */
+
+Request.prototype.timeoutError = function(){
+ var timeout = this._timeout;
+ var err = new Error('timeout of ' + timeout + 'ms exceeded');
+ err.timeout = timeout;
+ this.callback(err);
+};
+
+/**
+ * Enable transmission of cookies with x-domain requests.
+ *
+ * Note that for this to work the origin must not be
+ * using "Access-Control-Allow-Origin" with a wildcard,
+ * and also must set "Access-Control-Allow-Credentials"
+ * to "true".
+ *
+ * @api public
+ */
+
+Request.prototype.withCredentials = function(){
+ this._withCredentials = true;
+ return this;
+};
+
+/**
+ * Initiate request, invoking callback `fn(res)`
+ * with an instanceof `Response`.
+ *
+ * @param {Function} fn
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.end = function(fn){
+ var self = this;
+ var xhr = this.xhr = request.getXHR();
+ var query = this._query.join('&');
+ var timeout = this._timeout;
+ var data = this._formData || this._data;
+
+ // store callback
+ this._callback = fn || noop;
+
+ // state change
+ xhr.onreadystatechange = function(){
+ if (4 != xhr.readyState) return;
+
+ // In IE9, reads to any property (e.g. status) off of an aborted XHR will
+ // result in the error "Could not complete the operation due to error c00c023f"
+ var status;
+ try { status = xhr.status } catch(e) { status = 0; }
+
+ if (0 == status) {
+ if (self.timedout) return self.timeoutError();
+ if (self.aborted) return;
+ return self.crossDomainError();
+ }
+ self.emit('end');
+ };
+
+ // progress
+ var handleProgress = function(e){
+ if (e.total > 0) {
+ e.percent = e.loaded / e.total * 100;
+ }
+ self.emit('progress', e);
+ };
+ if (this.hasListeners('progress')) {
+ xhr.onprogress = handleProgress;
+ }
+ try {
+ if (xhr.upload && this.hasListeners('progress')) {
+ xhr.upload.onprogress = handleProgress;
+ }
+ } catch(e) {
+ // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist.
+ // Reported here:
+ // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context
+ }
+
+ // timeout
+ if (timeout && !this._timer) {
+ this._timer = setTimeout(function(){
+ self.timedout = true;
+ self.abort();
+ }, timeout);
+ }
+
+ // querystring
+ if (query) {
+ query = request.serializeObject(query);
+ this.url += ~this.url.indexOf('?')
+ ? '&' + query
+ : '?' + query;
+ }
+
+ // initiate request
+ xhr.open(this.method, this.url, true);
+
+ // CORS
+ if (this._withCredentials) xhr.withCredentials = true;
+
+ // body
+ if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) {
+ // serialize stuff
+ var contentType = this.getHeader('Content-Type');
+ var serialize = request.serialize[contentType ? contentType.split(';')[0] : ''];
+ if (serialize) data = serialize(data);
+ }
+
+ // set header fields
+ for (var field in this.header) {
+ if (null == this.header[field]) continue;
+ xhr.setRequestHeader(field, this.header[field]);
+ }
+
+ // send stuff
+ this.emit('request', this);
+ xhr.send(data);
+ return this;
+};
+
+/**
+ * Faux promise support
+ *
+ * @param {Function} fulfill
+ * @param {Function} reject
+ * @return {Request}
+ */
+
+Request.prototype.then = function (fulfill, reject) {
+ return this.end(function(err, res) {
+ err ? reject(err) : fulfill(res);
+ });
+}
+
+/**
+ * Expose `Request`.
+ */
+
+request.Request = Request;
+
+/**
+ * Issue a request:
+ *
+ * Examples:
+ *
+ * request('GET', '/users').end(callback)
+ * request('/users').end(callback)
+ * request('/users', callback)
+ *
+ * @param {String} method
+ * @param {String|Function} url or callback
+ * @return {Request}
+ * @api public
+ */
+
+function request(method, url) {
+ // callback
+ if ('function' == typeof url) {
+ return new Request('GET', method).end(url);
+ }
+
+ // url first
+ if (1 == arguments.length) {
+ return new Request('GET', method);
+ }
+
+ return new Request(method, url);
+}
+
+/**
+ * GET `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.get = function(url, data, fn){
+ var req = request('GET', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.query(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * HEAD `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.head = function(url, data, fn){
+ var req = request('HEAD', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * DELETE `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.del = function(url, fn){
+ var req = request('DELETE', url);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * PATCH `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} data
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.patch = function(url, data, fn){
+ var req = request('PATCH', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * POST `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} data
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.post = function(url, data, fn){
+ var req = request('POST', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * PUT `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.put = function(url, data, fn){
+ var req = request('PUT', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * Expose `request`.
+ */
+
+module.exports = request;
+
+},{"emitter":12,"reduce":13}],12:[function(require,module,exports){
+
+/**
+ * Expose `Emitter`.
+ */
+
+module.exports = Emitter;
+
+/**
+ * Initialize a new `Emitter`.
+ *
+ * @api public
+ */
+
+function Emitter(obj) {
+ if (obj) return mixin(obj);
+};
+
+/**
+ * Mixin the emitter properties.
+ *
+ * @param {Object} obj
+ * @return {Object}
+ * @api private
+ */
+
+function mixin(obj) {
+ for (var key in Emitter.prototype) {
+ obj[key] = Emitter.prototype[key];
+ }
+ return obj;
+}
+
+/**
+ * Listen on the given `event` with `fn`.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.on =
+Emitter.prototype.addEventListener = function(event, fn){
+ this._callbacks = this._callbacks || {};
+ (this._callbacks[event] = this._callbacks[event] || [])
+ .push(fn);
+ return this;
+};
+
+/**
+ * Adds an `event` listener that will be invoked a single
+ * time then automatically removed.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.once = function(event, fn){
+ var self = this;
+ this._callbacks = this._callbacks || {};
+
+ function on() {
+ self.off(event, on);
+ fn.apply(this, arguments);
+ }
+
+ on.fn = fn;
+ this.on(event, on);
+ return this;
+};
+
+/**
+ * Remove the given callback for `event` or all
+ * registered callbacks.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.off =
+Emitter.prototype.removeListener =
+Emitter.prototype.removeAllListeners =
+Emitter.prototype.removeEventListener = function(event, fn){
+ this._callbacks = this._callbacks || {};
+
+ // all
+ if (0 == arguments.length) {
+ this._callbacks = {};
+ return this;
+ }
+
+ // specific event
+ var callbacks = this._callbacks[event];
+ if (!callbacks) return this;
+
+ // remove all handlers
+ if (1 == arguments.length) {
+ delete this._callbacks[event];
+ return this;
+ }
+
+ // remove specific handler
+ var cb;
+ for (var i = 0; i < callbacks.length; i++) {
+ cb = callbacks[i];
+ if (cb === fn || cb.fn === fn) {
+ callbacks.splice(i, 1);
+ break;
+ }
+ }
+ return this;
+};
+
+/**
+ * Emit `event` with the given args.
+ *
+ * @param {String} event
+ * @param {Mixed} ...
+ * @return {Emitter}
+ */
+
+Emitter.prototype.emit = function(event){
+ this._callbacks = this._callbacks || {};
+ var args = [].slice.call(arguments, 1)
+ , callbacks = this._callbacks[event];
+
+ if (callbacks) {
+ callbacks = callbacks.slice(0);
+ for (var i = 0, len = callbacks.length; i < len; ++i) {
+ callbacks[i].apply(this, args);
+ }
+ }
+
+ return this;
+};
+
+/**
+ * Return array of callbacks for `event`.
+ *
+ * @param {String} event
+ * @return {Array}
+ * @api public
+ */
+
+Emitter.prototype.listeners = function(event){
+ this._callbacks = this._callbacks || {};
+ return this._callbacks[event] || [];
+};
+
+/**
+ * Check if this emitter has `event` handlers.
+ *
+ * @param {String} event
+ * @return {Boolean}
+ * @api public
+ */
+
+Emitter.prototype.hasListeners = function(event){
+ return !! this.listeners(event).length;
+};
+
+},{}],13:[function(require,module,exports){
+
+/**
+ * Reduce `arr` with `fn`.
+ *
+ * @param {Array} arr
+ * @param {Function} fn
+ * @param {Mixed} initial
+ *
+ * TODO: combatible error handling?
+ */
+
+module.exports = function(arr, fn, initial){
+ var idx = 0;
+ var len = arr.length;
+ var curr = arguments.length == 3
+ ? initial
+ : arr[idx++];
+
+ while (idx < len) {
+ curr = fn.call(null, curr, arr[idx], ++idx, arr);
+ }
+
+ return curr;
+};
+},{}],14:[function(require,module,exports){
+
+/**
+ * Module dependencies.
+ */
+
+var global = (function() { return this; })();
+
+/**
+ * WebSocket constructor.
+ */
+
+var WebSocket = global.WebSocket || global.MozWebSocket;
+
+/**
+ * Module exports.
+ */
+
+module.exports = WebSocket ? ws : null;
+
+/**
+ * WebSocket constructor.
+ *
+ * The third `opts` options object gets ignored in web browsers, since it's
+ * non-standard, and throws a TypeError if passed to the constructor.
+ * See: https://github.com/einaros/ws/issues/227
+ *
+ * @param {String} uri
+ * @param {Array} protocols (optional)
+ * @param {Object) opts (optional)
+ * @api public
+ */
+
+function ws(uri, protocols, opts) {
+ var instance;
+ if (protocols) {
+ instance = new WebSocket(uri, protocols);
+ } else {
+ instance = new WebSocket(uri);
+ }
+ return instance;
+}
+
+if (WebSocket) ws.prototype = WebSocket.prototype;
+
+},{}]},{},[5])(5)
+});
\ No newline at end of file
diff --git a/web-dist/discord.3.4.0.js b/web-dist/discord.3.4.0.js
new file mode 100644
index 000000000..1cbe30419
--- /dev/null
+++ b/web-dist/discord.3.4.0.js
@@ -0,0 +1,3641 @@
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Discord = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o]*>/g) || [])[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
+ var mention = _step3.value;
+
+ _mentions.push(mention.substring(2, mention.length - 1));
+ }
+ } catch (err) {
+ _didIteratorError3 = true;
+ _iteratorError3 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion3 && _iterator3["return"]) {
+ _iterator3["return"]();
+ }
+ } finally {
+ if (_didIteratorError3) {
+ throw _iteratorError3;
+ }
+ }
+ }
+
+ return _mentions;
+ }
+ });
+
+ return prom;
+ }
+
+ //def createws
+ }, {
+ key: "createws",
+ value: function createws(url) {
+ if (this.websocket) return false;
+
+ var self = this;
+
+ //good to go
+ this.websocket = new WebSocket(url);
+
+ //open
+ this.websocket.onopen = function () {
+ self.trySendConnData(); //try connecting
+ };
+
+ //close
+ this.websocket.onclose = function () {
+ self.trigger("disconnected");
+ };
+
+ //message
+ this.websocket.onmessage = function (e) {
+
+ var dat = false,
+ data = {};
+
+ try {
+ dat = JSON.parse(e.data);
+ data = dat.d;
+ } catch (err) {
+ self.trigger("error", err, e);
+ return;
+ }
+
+ //valid message
+ switch (dat.t) {
+
+ case "READY":
+ self.debug("received ready packet");
+
+ self.user = self.addUser(data.user);
+
+ var _iteratorNormalCompletion4 = true;
+ var _didIteratorError4 = false;
+ var _iteratorError4 = undefined;
+
+ try {
+ for (var _iterator4 = data.guilds[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
+ var _server = _step4.value;
+
+ var server = self.addServer(_server);
+ }
+ } catch (err) {
+ _didIteratorError4 = true;
+ _iteratorError4 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion4 && _iterator4["return"]) {
+ _iterator4["return"]();
+ }
+ } finally {
+ if (_didIteratorError4) {
+ throw _iteratorError4;
+ }
+ }
+ }
+
+ var _iteratorNormalCompletion5 = true;
+ var _didIteratorError5 = false;
+ var _iteratorError5 = undefined;
+
+ try {
+ for (var _iterator5 = data.private_channels[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
+ var _pmc = _step5.value;
+
+ var pmc = self.addPMChannel(_pmc);
+ }
+ } catch (err) {
+ _didIteratorError5 = true;
+ _iteratorError5 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion5 && _iterator5["return"]) {
+ _iterator5["return"]();
+ }
+ } finally {
+ if (_didIteratorError5) {
+ throw _iteratorError5;
+ }
+ }
+ }
+
+ self.trigger("ready");
+ self.readyTime = Date.now();
+ self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users.");
+ self.state = 3;
+ setInterval(function () {
+ self.keepAlive.apply(self);
+ }, data.heartbeat_interval);
+
+ break;
+ case "MESSAGE_CREATE":
+ self.debug("received message");
+
+ var mentions = [];
+ data.mentions = data.mentions || []; //for some reason this was not defined at some point?
+ var _iteratorNormalCompletion6 = true;
+ var _didIteratorError6 = false;
+ var _iteratorError6 = undefined;
+
+ try {
+ for (var _iterator6 = data.mentions[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
+ var mention = _step6.value;
+
+ mentions.push(self.addUser(mention));
+ }
+ } catch (err) {
+ _didIteratorError6 = true;
+ _iteratorError6 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion6 && _iterator6["return"]) {
+ _iterator6["return"]();
+ }
+ } finally {
+ if (_didIteratorError6) {
+ throw _iteratorError6;
+ }
+ }
+ }
+
+ var channel = self.getChannel("id", data.channel_id);
+ if (channel) {
+ var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author)));
+ self.trigger("message", msg);
+ }
+
+ break;
+ case "MESSAGE_DELETE":
+ self.debug("message deleted");
+
+ var channel = self.getChannel("id", data.channel_id);
+ var message = channel.getMessage("id", data.id);
+ if (message) {
+ self.trigger("messageDelete", channel, message);
+ channel.messages.splice(channel.messages.indexOf(message), 1);
+ } else {
+ //don't have the cache of that message ;(
+ self.trigger("messageDelete", channel);
+ }
+ break;
+ case "MESSAGE_UPDATE":
+ self.debug("message updated");
+
+ var channel = self.getChannel("id", data.channel_id);
+ var formerMessage = channel.getMessage("id", data.id);
+
+ if (formerMessage) {
+
+ //new message might be partial, so we need to fill it with whatever the old message was.
+ var info = {};
+
+ for (var key in formerMessage) {
+ info[key] = formerMessage[key];
+ }
+
+ for (var key in data) {
+ info[key] = data[key];
+ }
+
+ var mentions = [];
+ var _iteratorNormalCompletion7 = true;
+ var _didIteratorError7 = false;
+ var _iteratorError7 = undefined;
+
+ try {
+ for (var _iterator7 = info.mentions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
+ var mention = _step7.value;
+
+ mentions.push(self.addUser(mention));
+ }
+ } catch (err) {
+ _didIteratorError7 = true;
+ _iteratorError7 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion7 && _iterator7["return"]) {
+ _iterator7["return"]();
+ }
+ } finally {
+ if (_didIteratorError7) {
+ throw _iteratorError7;
+ }
+ }
+ }
+
+ var newMessage = new Message(info, channel, mentions, formerMessage.author);
+
+ self.trigger("messageUpdate", newMessage, formerMessage);
+
+ channel.messages[channel.messages.indexOf(formerMessage)] = newMessage;
+ }
+
+ // message isn't in cache, and if it's a partial it could cause
+ // all hell to break loose... best to just act as if nothing happened
+
+ break;
+
+ case "GUILD_DELETE":
+
+ var server = self.getServer("id", data.id);
+
+ if (server) {
+ self.serverCache.splice(self.serverCache.indexOf(server), 1);
+ self.trigger("serverDelete", server);
+ }
+
+ break;
+
+ case "CHANNEL_DELETE":
+
+ var channel = self.getChannel("id", data.id);
+
+ if (channel) {
+
+ var server = channel.server;
+
+ if (server) {
+
+ server.channels.splice(server.channels.indexOf(channel), 1);
+ }
+
+ self.trigger("channelDelete", channel);
+
+ self.serverCache.splice(self.serverCache.indexOf(channel), 1);
+ }
+
+ break;
+
+ case "GUILD_CREATE":
+
+ var server = self.getServer("id", data.id);
+
+ if (!server) {
+ //if server doesn't already exist because duh
+ server = self.addServer(data);
+ } /*else if(server.channels.length === 0){
+
+ var srv = new Server(data, self);
+ for(channel of data.channels){
+ srv.channels.push(new Channel(channel, data.id));
+ }
+ self.serverCache[self.serverCache.indexOf(server)] = srv;
+
+ }*/
+
+ if (self.serverCreateListener[data.id]) {
+ var cbs = self.serverCreateListener[data.id];
+ cbs[0](server); //promise then callback
+ cbs[1](null, server); //legacy callback
+ self.serverCreateListener[data.id] = null;
+ }
+
+ self.trigger("serverCreate", server);
+
+ break;
+
+ case "CHANNEL_CREATE":
+
+ var channel = self.getChannel("id", data.id);
+
+ if (!channel) {
+
+ var chann = self.addChannel(data, data.guild_id);
+ var srv = self.getServer("id", data.guild_id);
+ if (srv) {
+ srv.addChannel(chann);
+ }
+ self.trigger("channelCreate", chann);
+ }
+
+ break;
+
+ case "GUILD_MEMBER_ADD":
+
+ var server = self.getServer("id", data.guild_id);
+
+ if (server) {
+
+ var user = self.addUser(data.user); //if for whatever reason it doesn't exist..
+
+ if (! ~server.members.indexOf(user)) {
+ server.members.push(user);
+ }
+
+ self.trigger("serverNewMember", user, server);
+ }
+
+ break;
+
+ case "GUILD_MEMBER_REMOVE":
+
+ var server = self.getServer("id", data.guild_id);
+
+ if (server) {
+
+ var user = self.addUser(data.user); //if for whatever reason it doesn't exist..
+
+ if (~server.members.indexOf(user)) {
+ server.members.splice(server.members.indexOf(user), 1);
+ }
+
+ self.trigger("serverRemoveMember", user, server);
+ }
+
+ break;
+
+ case "USER_UPDATE":
+
+ if (self.user && data.id === self.user.id) {
+
+ var newUser = new User(data); //not actually adding to the cache
+
+ self.trigger("userUpdate", newUser, self.user);
+
+ if (~self.userCache.indexOf(self.user)) {
+ self.userCache[self.userCache.indexOf(self.user)] = newUser;
+ }
+
+ self.user = newUser;
+ }
+
+ break;
+
+ case "PRESENCE_UPDATE":
+
+ var userInCache = self.getUser("id", data.user.id);
+
+ if (userInCache) {
+ //user exists
+ var presenceUser = new User(data.user);
+ if (presenceUser.equalsStrict(userInCache)) {
+ //they're exactly the same, an actual presence update
+ userInCache.status = data.status;
+ self.trigger("presence", {
+ user: userInCache,
+ status: data.status,
+ server: self.getServer("id", data.guild_id),
+ gameId: data.game_id
+ });
+ } else {
+ //one of their details changed.
+ self.trigger("userUpdate", userInCache, presenceUser);
+ self.userCache[self.userCache.indexOf(userInCache)] = presenceUser;
+ }
+ }
+
+ break;
+
+ default:
+ self.debug("received unknown packet");
+ self.trigger("unknown", dat);
+ break;
+
+ }
+ };
+ }
+
+ //def addUser
+ }, {
+ key: "addUser",
+ value: function addUser(data) {
+ if (!this.getUser("id", data.id)) {
+ this.userCache.push(new User(data));
+ }
+ return this.getUser("id", data.id);
+ }
+
+ //def addChannel
+ }, {
+ key: "addChannel",
+ value: function addChannel(data, serverId) {
+ if (!this.getChannel("id", data.id)) {
+ this.channelCache.push(new Channel(data, this.getServer("id", serverId)));
+ }
+ return this.getChannel("id", data.id);
+ }
+ }, {
+ key: "addPMChannel",
+ value: function addPMChannel(data) {
+ if (!this.getPMChannel("id", data.id)) {
+ this.pmChannelCache.push(new PMChannel(data, this));
+ }
+ return this.getPMChannel("id", data.id);
+ }
+
+ //def addServer
+ }, {
+ key: "addServer",
+ value: function addServer(data) {
+
+ var self = this;
+ var server = this.getServer("id", data.id);
+
+ if (!server) {
+ server = new Server(data, this);
+ this.serverCache.push(server);
+ if (data.channels) {
+ var _iteratorNormalCompletion8 = true;
+ var _didIteratorError8 = false;
+ var _iteratorError8 = undefined;
+
+ try {
+ for (var _iterator8 = data.channels[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
+ var channel = _step8.value;
+
+ server.channels.push(this.addChannel(channel, server.id));
+ }
+ } catch (err) {
+ _didIteratorError8 = true;
+ _iteratorError8 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion8 && _iterator8["return"]) {
+ _iterator8["return"]();
+ }
+ } finally {
+ if (_didIteratorError8) {
+ throw _iteratorError8;
+ }
+ }
+ }
+ }
+ }
+
+ var _iteratorNormalCompletion9 = true;
+ var _didIteratorError9 = false;
+ var _iteratorError9 = undefined;
+
+ try {
+ for (var _iterator9 = data.presences[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) {
+ var presence = _step9.value;
+
+ self.getUser("id", presence.user.id).status = presence.status;
+ }
+ } catch (err) {
+ _didIteratorError9 = true;
+ _iteratorError9 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion9 && _iterator9["return"]) {
+ _iterator9["return"]();
+ }
+ } finally {
+ if (_didIteratorError9) {
+ throw _iteratorError9;
+ }
+ }
+ }
+
+ return server;
+ }
+
+ //def getUser
+ }, {
+ key: "getUser",
+ value: function getUser(key, value) {
+ var _iteratorNormalCompletion10 = true;
+ var _didIteratorError10 = false;
+ var _iteratorError10 = undefined;
+
+ try {
+ for (var _iterator10 = this.userCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {
+ var user = _step10.value;
+
+ if (user[key] === value) {
+ return user;
+ }
+ }
+ } catch (err) {
+ _didIteratorError10 = true;
+ _iteratorError10 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion10 && _iterator10["return"]) {
+ _iterator10["return"]();
+ }
+ } finally {
+ if (_didIteratorError10) {
+ throw _iteratorError10;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ //def getChannel
+ }, {
+ key: "getChannel",
+ value: function getChannel(key, value) {
+ var _iteratorNormalCompletion11 = true;
+ var _didIteratorError11 = false;
+ var _iteratorError11 = undefined;
+
+ try {
+ for (var _iterator11 = this.channelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) {
+ var channel = _step11.value;
+
+ if (channel[key] === value) {
+ return channel;
+ }
+ }
+ } catch (err) {
+ _didIteratorError11 = true;
+ _iteratorError11 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion11 && _iterator11["return"]) {
+ _iterator11["return"]();
+ }
+ } finally {
+ if (_didIteratorError11) {
+ throw _iteratorError11;
+ }
+ }
+ }
+
+ return this.getPMChannel(key, value); //might be a PM
+ }
+ }, {
+ key: "getPMChannel",
+ value: function getPMChannel(key, value) {
+ var _iteratorNormalCompletion12 = true;
+ var _didIteratorError12 = false;
+ var _iteratorError12 = undefined;
+
+ try {
+ for (var _iterator12 = this.pmChannelCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) {
+ var channel = _step12.value;
+
+ if (channel[key] === value) {
+ return channel;
+ }
+ }
+ } catch (err) {
+ _didIteratorError12 = true;
+ _iteratorError12 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion12 && _iterator12["return"]) {
+ _iterator12["return"]();
+ }
+ } finally {
+ if (_didIteratorError12) {
+ throw _iteratorError12;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ //def getServer
+ }, {
+ key: "getServer",
+ value: function getServer(key, value) {
+ var _iteratorNormalCompletion13 = true;
+ var _didIteratorError13 = false;
+ var _iteratorError13 = undefined;
+
+ try {
+ for (var _iterator13 = this.serverCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) {
+ var server = _step13.value;
+
+ if (server[key] === value) {
+ return server;
+ }
+ }
+ } catch (err) {
+ _didIteratorError13 = true;
+ _iteratorError13 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion13 && _iterator13["return"]) {
+ _iterator13["return"]();
+ }
+ } finally {
+ if (_didIteratorError13) {
+ throw _iteratorError13;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ //def trySendConnData
+ }, {
+ key: "trySendConnData",
+ value: function trySendConnData() {
+
+ if (this.token && !this.alreadySentData) {
+
+ this.alreadySentData = true;
+
+ var data = {
+ op: 2,
+ d: {
+ token: this.token,
+ v: 2,
+ properties: {
+ "$os": "discord.js",
+ "$browser": "discord.js",
+ "$device": "discord.js",
+ "$referrer": "",
+ "$referring_domain": ""
+ }
+ }
+ };
+ this.websocket.send(JSON.stringify(data));
+ }
+ }
+ }, {
+ key: "resolveServerID",
+ value: function resolveServerID(resource) {
+
+ if (resource instanceof Server) {
+ return resource.id;
+ } else if (!isNaN(resource) && resource.length && resource.length === 17) {
+ return resource;
+ }
+ }
+ }, {
+ key: "resolveDestination",
+ value: function resolveDestination(destination) {
+ var channId = false;
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ if (destination instanceof Server) {
+ channId = destination.id; //general is the same as server id
+ } else if (destination instanceof Channel) {
+ channId = destination.id;
+ } else if (destination instanceof Message) {
+ channId = destination.channel.id;
+ } else if (destination instanceof User) {
+
+ //check if we have a PM
+ var _iteratorNormalCompletion14 = true;
+ var _didIteratorError14 = false;
+ var _iteratorError14 = undefined;
+
+ try {
+ for (var _iterator14 = self.pmChannelCache[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) {
+ var pmc = _step14.value;
+
+ if (pmc.user.equals(destination)) {
+ resolve(pmc.id);
+ return;
+ }
+ }
+
+ //we don't, at this point we're late
+ } catch (err) {
+ _didIteratorError14 = true;
+ _iteratorError14 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion14 && _iterator14["return"]) {
+ _iterator14["return"]();
+ }
+ } finally {
+ if (_didIteratorError14) {
+ throw _iteratorError14;
+ }
+ }
+ }
+
+ self.startPM(destination).then(function (pmc) {
+ console.log(pmc);
+ resolve(pmc.id);
+ })["catch"](reject);
+ } else {
+ channId = destination;
+ }
+ if (channId) resolve(channId);
+ });
+ }
+ }, {
+ key: "_sendMessage",
+ value: function _sendMessage(destination, content, tts, mentions) {
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({
+ content: content,
+ mentions: mentions,
+ tts: tts
+ }).end(function (err, res) {
+
+ if (err) {
+ reject(err);
+ } else {
+ var data = res.body;
+
+ var mentions = [];
+
+ data.mentions = data.mentions || []; //for some reason this was not defined at some point?
+
+ var _iteratorNormalCompletion15 = true;
+ var _didIteratorError15 = false;
+ var _iteratorError15 = undefined;
+
+ try {
+ for (var _iterator15 = data.mentions[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) {
+ var mention = _step15.value;
+
+ mentions.push(self.addUser(mention));
+ }
+ } catch (err) {
+ _didIteratorError15 = true;
+ _iteratorError15 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion15 && _iterator15["return"]) {
+ _iterator15["return"]();
+ }
+ } finally {
+ if (_didIteratorError15) {
+ throw _iteratorError15;
+ }
+ }
+ }
+
+ var channel = self.getChannel("id", data.channel_id);
+ if (channel) {
+ var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author)));
+ resolve(msg);
+ }
+ }
+ });
+ });
+ }
+ }, {
+ key: "_sendFile",
+ value: function _sendFile(destination, attachment) {
+ var attachmentName = arguments.length <= 2 || arguments[2] === undefined ? "DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png" : arguments[2];
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).attach("file", attachment, attachmentName).end(function (err, res) {
+
+ if (err) {
+ reject(err);
+ } else {
+
+ var chann = self.getChannel("id", destination);
+ if (chann) {
+ var msg = chann.addMessage(new Message(res.body, chann, [], self.user));
+ resolve(msg);
+ }
+ }
+ });
+ });
+ }
+ }, {
+ key: "_updateMessage",
+ value: function _updateMessage(message, content) {
+ var self = this;
+ return new Promise(function (resolve, reject) {
+ request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).send({
+ content: content,
+ mentions: []
+ }).end(function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ var msg = new Message(res.body, message.channel, message.mentions, message.sender);
+ resolve(msg);
+ message.channel.messages[message.channel.messages.indexOf(message)] = msg;
+ }
+ });
+ });
+ }
+ }, {
+ key: "_deleteMessage",
+ value: function _deleteMessage(message) {
+ var self = this;
+ return new Promise(function (resolve, reject) {
+
+ request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).end(function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ resolve();
+ }
+ });
+ });
+ }
+ }, {
+ key: "checkQueue",
+ value: function checkQueue(channelID) {
+ var _this = this;
+
+ var self = this;
+
+ if (!this.checkingQueue[channelID]) {
+ (function () {
+ var doNext = function doNext() {
+ if (self.queue[channelID].length === 0) {
+ done();
+ return;
+ }
+ var queuedEvent = self.queue[channelID][0];
+ switch (queuedEvent.action) {
+ case "sendMessage":
+ var msgToSend = queuedEvent;
+ self._sendMessage(channelID, msgToSend.content, msgToSend.tts, msgToSend.mentions).then(function (msg) {
+ msgToSend.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ msgToSend.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ case "sendFile":
+ var fileToSend = queuedEvent;
+ self._sendFile(channelID, fileToSend.attachment, fileToSend.attachmentName).then(function (msg) {
+ fileToSend.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ fileToSend.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ case "updateMessage":
+ var msgToUpd = queuedEvent;
+ self._updateMessage(msgToUpd.message, msgToUpd.content).then(function (msg) {
+ msgToUpd.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ msgToUpd.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ case "deleteMessage":
+ var msgToDel = queuedEvent;
+ self._deleteMessage(msgToDel.message).then(function (msg) {
+ msgToDel.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ msgToDel.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ default:
+ done();
+ break;
+ }
+ };
+
+ var done = function done() {
+ self.checkingQueue[channelID] = false;
+ return;
+ };
+
+ //if we aren't already checking this queue.
+ _this.checkingQueue[channelID] = true;
+ doNext();
+ })();
+ }
+ }
+ }, {
+ key: "getGateway",
+ value: function getGateway() {
+ var self = this;
+ return new Promise(function (resolve, reject) {
+ request.get(Endpoints.API + "/gateway").set("authorization", self.token).end(function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ resolve(res.body.url);
+ }
+ });
+ });
+ }
+ }, {
+ key: "uptime",
+ get: function get() {
+
+ return this.readyTime ? Date.now() - this.readyTime : null;
+ }
+ }, {
+ key: "ready",
+ get: function get() {
+ return this.state === 3;
+ }
+ }, {
+ key: "servers",
+ get: function get() {
+ return this.serverCache;
+ }
+ }, {
+ key: "channels",
+ get: function get() {
+ return this.channelCache;
+ }
+ }, {
+ key: "users",
+ get: function get() {
+ return this.userCache;
+ }
+ }, {
+ key: "PMChannels",
+ get: function get() {
+ return this.pmChannelCache;
+ }
+ }, {
+ key: "messages",
+ get: function get() {
+
+ var msgs = [];
+ var _iteratorNormalCompletion16 = true;
+ var _didIteratorError16 = false;
+ var _iteratorError16 = undefined;
+
+ try {
+ for (var _iterator16 = this.channelCache[Symbol.iterator](), _step16; !(_iteratorNormalCompletion16 = (_step16 = _iterator16.next()).done); _iteratorNormalCompletion16 = true) {
+ var channel = _step16.value;
+
+ msgs = msgs.concat(channel.messages);
+ }
+ } catch (err) {
+ _didIteratorError16 = true;
+ _iteratorError16 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion16 && _iterator16["return"]) {
+ _iterator16["return"]();
+ }
+ } finally {
+ if (_didIteratorError16) {
+ throw _iteratorError16;
+ }
+ }
+ }
+
+ return msgs;
+ }
+ }]);
+
+ return Client;
+})();
+
+module.exports = Client;
+},{"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,"fs":10,"superagent":11,"ws":14}],2:[function(require,module,exports){
+"use strict";
+
+exports.BASE_DOMAIN = "discordapp.com";
+exports.BASE = "https://" + exports.BASE_DOMAIN;
+exports.WEBSOCKET_HUB = "wss://" + exports.BASE_DOMAIN + "/hub";
+
+exports.API = exports.BASE + "/api";
+exports.AUTH = exports.API + "/auth";
+exports.LOGIN = exports.AUTH + "/login";
+exports.LOGOUT = exports.AUTH + "/logout";
+exports.USERS = exports.API + "/users";
+exports.SERVERS = exports.API + "/guilds";
+exports.CHANNELS = exports.API + "/channels";
+},{}],3:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var PMChannel = (function () {
+ function PMChannel(data, client) {
+ _classCallCheck(this, PMChannel);
+
+ this.user = client.getUser("id", data.recipient.id);
+ this.id = data.id;
+ this.messages = [];
+ }
+
+ _createClass(PMChannel, [{
+ key: "addMessage",
+ value: function addMessage(data) {
+ if (!this.getMessage("id", data.id)) {
+ this.messages.push(data);
+ }
+ return this.getMessage("id", data.id);
+ }
+ }, {
+ key: "getMessage",
+ value: function getMessage(key, value) {
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var message = _step.value;
+
+ if (message[key] === value) {
+ return message;
+ }
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator["return"]) {
+ _iterator["return"]();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+
+ return null;
+ }
+ }, {
+ key: "isPrivate",
+ get: function get() {
+ return true;
+ }
+ }]);
+
+ return PMChannel;
+})();
+
+module.exports = PMChannel;
+},{}],4:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Channel = (function () {
+ function Channel(data, server) {
+ _classCallCheck(this, Channel);
+
+ this.server = server;
+ this.name = data.name;
+ this.type = data.type;
+ this.id = data.id;
+ this.messages = [];
+ //this.isPrivate = isPrivate; //not sure about the implementation of this...
+ }
+
+ _createClass(Channel, [{
+ key: "equals",
+ value: function equals(object) {
+ return object && object.id === this.id;
+ }
+ }, {
+ key: "addMessage",
+ value: function addMessage(data) {
+
+ if (this.messages.length > 1000) {
+ this.messages.splice(0, 1);
+ }
+
+ if (!this.getMessage("id", data.id)) {
+ this.messages.push(data);
+ }
+
+ return this.getMessage("id", data.id);
+ }
+ }, {
+ key: "getMessage",
+ value: function getMessage(key, value) {
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var message = _step.value;
+
+ if (message[key] === value) {
+ return message;
+ }
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator["return"]) {
+ _iterator["return"]();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+
+ return null;
+ }
+ }, {
+ key: "toString",
+ value: function toString() {
+ return "<#" + this.id + ">";
+ }
+ }, {
+ key: "client",
+ get: function get() {
+ return this.server.client;
+ }
+ }, {
+ key: "isPrivate",
+ get: function get() {
+ return false;
+ }
+ }, {
+ key: "users",
+ get: function get() {
+ return this.server.members;
+ }
+ }, {
+ key: "members",
+ get: function get() {
+ return this.server.members;
+ }
+ }]);
+
+ return Channel;
+})();
+
+module.exports = Channel;
+},{}],5:[function(require,module,exports){
+"use strict";
+
+var request = require("superagent");
+var Endpoints = require("./Endpoints.js");
+var Client = require("./Client.js");
+
+var Discord = {
+ Endpoints: Endpoints,
+ Client: Client
+};
+
+module.exports = Discord;
+},{"./Client.js":1,"./Endpoints.js":2,"superagent":11}],6:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Invite = (function () {
+ function Invite(data, client) {
+ _classCallCheck(this, Invite);
+
+ this.max_age = data.max_age;
+ this.code = data.code;
+ this.server = client.getServer("id", data.guild.id);
+ this.revoked = data.revoked;
+ this.created_at = Date.parse(data.created_at);
+ this.temporary = data.temporary;
+ this.uses = data.uses;
+ this.max_uses = data.uses;
+ this.inviter = client.addUser(data.inviter);
+ this.xkcd = data.xkcdpass;
+ this.channel = client.getChannel("id", data.channel.id);
+ }
+
+ _createClass(Invite, [{
+ key: "URL",
+ get: function get() {
+ var code = this.xkcd ? this.xkcdpass : this.code;
+ return "https://discord.gg/" + code;
+ }
+ }]);
+
+ return Invite;
+})();
+
+module.exports = Invite;
+},{}],7:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var PMChannel = require("./PMChannel.js");
+
+var Message = (function () {
+ function Message(data, channel, mentions, author) {
+ _classCallCheck(this, Message);
+
+ this.tts = data.tts;
+ this.timestamp = Date.parse(data.timestamp);
+ this.nonce = data.nonce;
+ this.mentions = mentions;
+ this.everyoneMentioned = data.mention_everyone;
+ this.id = data.id;
+ this.embeds = data.embeds;
+ this.editedTimestamp = data.edited_timestamp;
+ this.content = data.content.trim();
+ this.channel = channel;
+ this.author = author;
+ this.attachments = data.attachments;
+ }
+
+ /*exports.Message.prototype.isPM = function() {
+ return ( this.channel instanceof PMChannel );
+ }*/
+
+ _createClass(Message, [{
+ key: "isMentioned",
+ value: function isMentioned(user) {
+ var id = user.id ? user.id : user;
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = this.mentions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var mention = _step.value;
+
+ if (mention.id === id) {
+ return true;
+ }
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator["return"]) {
+ _iterator["return"]();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+
+ return false;
+ }
+ }, {
+ key: "sender",
+ get: function get() {
+ return this.author;
+ }
+ }, {
+ key: "isPrivate",
+ get: function get() {
+ return this.channel.isPrivate;
+ }
+ }]);
+
+ return Message;
+})();
+
+module.exports = Message;
+},{"./PMChannel.js":3}],8:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Server = (function () {
+ function Server(data, client) {
+ _classCallCheck(this, Server);
+
+ this.client = client;
+ this.region = data.region;
+ this.ownerID = data.owner_id;
+ this.name = data.name;
+ this.id = data.id;
+ this.members = [];
+ this.channels = [];
+ this.icon = data.icon;
+ this.afkTimeout = data.afk_timeout;
+ this.afkChannelId = data.afk_channel_id;
+
+ if (!data.members) {
+ data.members = [client.user];
+ return;
+ }
+
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = data.members[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var member = _step.value;
+
+ // first we cache the user in our Discord Client,
+ // then we add it to our list. This way when we
+ // get a user from this server's member list,
+ // it will be identical (unless an async change occurred)
+ // to the client's cache.
+ if (member.user) this.members.push(client.addUser(member.user));
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator["return"]) {
+ _iterator["return"]();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+ }
+
+ _createClass(Server, [{
+ key: "getChannel",
+
+ // get/set
+ value: function getChannel(key, value) {
+ var _iteratorNormalCompletion2 = true;
+ var _didIteratorError2 = false;
+ var _iteratorError2 = undefined;
+
+ try {
+ for (var _iterator2 = this.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
+ var channel = _step2.value;
+
+ if (channel[key] === value) {
+ return channel;
+ }
+ }
+ } catch (err) {
+ _didIteratorError2 = true;
+ _iteratorError2 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion2 && _iterator2["return"]) {
+ _iterator2["return"]();
+ }
+ } finally {
+ if (_didIteratorError2) {
+ throw _iteratorError2;
+ }
+ }
+ }
+
+ return null;
+ }
+ }, {
+ key: "getMember",
+ value: function getMember(key, value) {
+ var _iteratorNormalCompletion3 = true;
+ var _didIteratorError3 = false;
+ var _iteratorError3 = undefined;
+
+ try {
+ for (var _iterator3 = this.members[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
+ var member = _step3.value;
+
+ if (member[key] === value) {
+ return member;
+ }
+ }
+ } catch (err) {
+ _didIteratorError3 = true;
+ _iteratorError3 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion3 && _iterator3["return"]) {
+ _iterator3["return"]();
+ }
+ } finally {
+ if (_didIteratorError3) {
+ throw _iteratorError3;
+ }
+ }
+ }
+
+ return null;
+ }
+ }, {
+ key: "addChannel",
+ value: function addChannel(chann) {
+ if (!this.getChannel("id", chann.id)) {
+ this.channels.push(chann);
+ }
+ return chann;
+ }
+ }, {
+ key: "addMember",
+ value: function addMember(member) {
+ if (!this.getMember("id", member.id)) {
+ this.members.push(member);
+ }
+ return member;
+ }
+ }, {
+ key: "toString",
+ value: function toString() {
+ return this.name;
+ }
+ }, {
+ key: "iconURL",
+ get: function get() {
+ if (!this.icon) return null;
+ return "https://discordapp.com/api/guilds/" + this.id + "/icons/" + this.icon + ".jpg";
+ }
+ }, {
+ key: "afkChannel",
+ get: function get() {
+ if (!this.afkChannelId) return false;
+
+ return this.getChannel("id", this.afkChannelId);
+ }
+ }, {
+ key: "defaultChannel",
+ get: function get() {
+ return this.getChannel("name", "general");
+ }
+ }, {
+ key: "owner",
+ get: function get() {
+ return this.client.getUser("id", this.ownerID);
+ }
+ }, {
+ key: "users",
+ get: function get() {
+ return this.members;
+ }
+ }]);
+
+ return Server;
+})();
+
+module.exports = Server;
+},{}],9:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var User = (function () {
+ function User(data) {
+ _classCallCheck(this, User);
+
+ this.username = data.username;
+ this.discriminator = data.discriminator;
+ this.id = data.id;
+ this.avatar = data.avatar;
+ this.status = "offline";
+ }
+
+ // access using user.avatarURL;
+
+ _createClass(User, [{
+ key: "mention",
+ value: function mention() {
+ return "<@" + this.id + ">";
+ }
+ }, {
+ key: "toString",
+ value: function toString() {
+ /*
+ if we embed a user in a String - like so:
+ "Yo " + user + " what's up?"
+ It would generate something along the lines of:
+ "Yo @hydrabolt what's up?"
+ */
+ return this.mention();
+ }
+ }, {
+ key: "equals",
+ value: function equals(object) {
+ return object.id === this.id;
+ }
+ }, {
+ key: "equalsStrict",
+ value: function equalsStrict(object) {
+ return object.id === this.id && object.avatar === this.avatar && object.username === this.username && object.discriminator === this.discriminator;
+ }
+ }, {
+ key: "avatarURL",
+ get: function get() {
+ if (!this.avatar) return null;
+ return "https://discordapp.com/api/users/" + this.id + "/avatars/" + this.avatar + ".jpg";
+ }
+ }]);
+
+ return User;
+})();
+
+module.exports = User;
+},{}],10:[function(require,module,exports){
+
+},{}],11:[function(require,module,exports){
+/**
+ * Module dependencies.
+ */
+
+var Emitter = require('emitter');
+var reduce = require('reduce');
+
+/**
+ * Root reference for iframes.
+ */
+
+var root = 'undefined' == typeof window
+ ? (this || self)
+ : window;
+
+/**
+ * Noop.
+ */
+
+function noop(){};
+
+/**
+ * Check if `obj` is a host object,
+ * we don't want to serialize these :)
+ *
+ * TODO: future proof, move to compoent land
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api private
+ */
+
+function isHost(obj) {
+ var str = {}.toString.call(obj);
+
+ switch (str) {
+ case '[object File]':
+ case '[object Blob]':
+ case '[object FormData]':
+ return true;
+ default:
+ return false;
+ }
+}
+
+/**
+ * Determine XHR.
+ */
+
+request.getXHR = function () {
+ if (root.XMLHttpRequest
+ && (!root.location || 'file:' != root.location.protocol
+ || !root.ActiveXObject)) {
+ return new XMLHttpRequest;
+ } else {
+ try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
+ }
+ return false;
+};
+
+/**
+ * Removes leading and trailing whitespace, added to support IE.
+ *
+ * @param {String} s
+ * @return {String}
+ * @api private
+ */
+
+var trim = ''.trim
+ ? function(s) { return s.trim(); }
+ : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); };
+
+/**
+ * Check if `obj` is an object.
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api private
+ */
+
+function isObject(obj) {
+ return obj === Object(obj);
+}
+
+/**
+ * Serialize the given `obj`.
+ *
+ * @param {Object} obj
+ * @return {String}
+ * @api private
+ */
+
+function serialize(obj) {
+ if (!isObject(obj)) return obj;
+ var pairs = [];
+ for (var key in obj) {
+ if (null != obj[key]) {
+ pairs.push(encodeURIComponent(key)
+ + '=' + encodeURIComponent(obj[key]));
+ }
+ }
+ return pairs.join('&');
+}
+
+/**
+ * Expose serialization method.
+ */
+
+ request.serializeObject = serialize;
+
+ /**
+ * Parse the given x-www-form-urlencoded `str`.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function parseString(str) {
+ var obj = {};
+ var pairs = str.split('&');
+ var parts;
+ var pair;
+
+ for (var i = 0, len = pairs.length; i < len; ++i) {
+ pair = pairs[i];
+ parts = pair.split('=');
+ obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
+ }
+
+ return obj;
+}
+
+/**
+ * Expose parser.
+ */
+
+request.parseString = parseString;
+
+/**
+ * Default MIME type map.
+ *
+ * superagent.types.xml = 'application/xml';
+ *
+ */
+
+request.types = {
+ html: 'text/html',
+ json: 'application/json',
+ xml: 'application/xml',
+ urlencoded: 'application/x-www-form-urlencoded',
+ 'form': 'application/x-www-form-urlencoded',
+ 'form-data': 'application/x-www-form-urlencoded'
+};
+
+/**
+ * Default serialization map.
+ *
+ * superagent.serialize['application/xml'] = function(obj){
+ * return 'generated xml here';
+ * };
+ *
+ */
+
+ request.serialize = {
+ 'application/x-www-form-urlencoded': serialize,
+ 'application/json': JSON.stringify
+ };
+
+ /**
+ * Default parsers.
+ *
+ * superagent.parse['application/xml'] = function(str){
+ * return { object parsed from str };
+ * };
+ *
+ */
+
+request.parse = {
+ 'application/x-www-form-urlencoded': parseString,
+ 'application/json': JSON.parse
+};
+
+/**
+ * Parse the given header `str` into
+ * an object containing the mapped fields.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function parseHeader(str) {
+ var lines = str.split(/\r?\n/);
+ var fields = {};
+ var index;
+ var line;
+ var field;
+ var val;
+
+ lines.pop(); // trailing CRLF
+
+ for (var i = 0, len = lines.length; i < len; ++i) {
+ line = lines[i];
+ index = line.indexOf(':');
+ field = line.slice(0, index).toLowerCase();
+ val = trim(line.slice(index + 1));
+ fields[field] = val;
+ }
+
+ return fields;
+}
+
+/**
+ * Return the mime type for the given `str`.
+ *
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+function type(str){
+ return str.split(/ *; */).shift();
+};
+
+/**
+ * Return header field parameters.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function params(str){
+ return reduce(str.split(/ *; */), function(obj, str){
+ var parts = str.split(/ *= */)
+ , key = parts.shift()
+ , val = parts.shift();
+
+ if (key && val) obj[key] = val;
+ return obj;
+ }, {});
+};
+
+/**
+ * Initialize a new `Response` with the given `xhr`.
+ *
+ * - set flags (.ok, .error, etc)
+ * - parse header
+ *
+ * Examples:
+ *
+ * Aliasing `superagent` as `request` is nice:
+ *
+ * request = superagent;
+ *
+ * We can use the promise-like API, or pass callbacks:
+ *
+ * request.get('/').end(function(res){});
+ * request.get('/', function(res){});
+ *
+ * Sending data can be chained:
+ *
+ * request
+ * .post('/user')
+ * .send({ name: 'tj' })
+ * .end(function(res){});
+ *
+ * Or passed to `.send()`:
+ *
+ * request
+ * .post('/user')
+ * .send({ name: 'tj' }, function(res){});
+ *
+ * Or passed to `.post()`:
+ *
+ * request
+ * .post('/user', { name: 'tj' })
+ * .end(function(res){});
+ *
+ * Or further reduced to a single call for simple cases:
+ *
+ * request
+ * .post('/user', { name: 'tj' }, function(res){});
+ *
+ * @param {XMLHTTPRequest} xhr
+ * @param {Object} options
+ * @api private
+ */
+
+function Response(req, options) {
+ options = options || {};
+ this.req = req;
+ this.xhr = this.req.xhr;
+ // responseText is accessible only if responseType is '' or 'text' and on older browsers
+ this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined')
+ ? this.xhr.responseText
+ : null;
+ this.statusText = this.req.xhr.statusText;
+ this.setStatusProperties(this.xhr.status);
+ this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders());
+ // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but
+ // getResponseHeader still works. so we get content-type even if getting
+ // other headers fails.
+ this.header['content-type'] = this.xhr.getResponseHeader('content-type');
+ this.setHeaderProperties(this.header);
+ this.body = this.req.method != 'HEAD'
+ ? this.parseBody(this.text ? this.text : this.xhr.response)
+ : null;
+}
+
+/**
+ * Get case-insensitive `field` value.
+ *
+ * @param {String} field
+ * @return {String}
+ * @api public
+ */
+
+Response.prototype.get = function(field){
+ return this.header[field.toLowerCase()];
+};
+
+/**
+ * Set header related properties:
+ *
+ * - `.type` the content type without params
+ *
+ * A response of "Content-Type: text/plain; charset=utf-8"
+ * will provide you with a `.type` of "text/plain".
+ *
+ * @param {Object} header
+ * @api private
+ */
+
+Response.prototype.setHeaderProperties = function(header){
+ // content-type
+ var ct = this.header['content-type'] || '';
+ this.type = type(ct);
+
+ // params
+ var obj = params(ct);
+ for (var key in obj) this[key] = obj[key];
+};
+
+/**
+ * Parse the given body `str`.
+ *
+ * Used for auto-parsing of bodies. Parsers
+ * are defined on the `superagent.parse` object.
+ *
+ * @param {String} str
+ * @return {Mixed}
+ * @api private
+ */
+
+Response.prototype.parseBody = function(str){
+ var parse = request.parse[this.type];
+ return parse && str && (str.length || str instanceof Object)
+ ? parse(str)
+ : null;
+};
+
+/**
+ * Set flags such as `.ok` based on `status`.
+ *
+ * For example a 2xx response will give you a `.ok` of __true__
+ * whereas 5xx will be __false__ and `.error` will be __true__. The
+ * `.clientError` and `.serverError` are also available to be more
+ * specific, and `.statusType` is the class of error ranging from 1..5
+ * sometimes useful for mapping respond colors etc.
+ *
+ * "sugar" properties are also defined for common cases. Currently providing:
+ *
+ * - .noContent
+ * - .badRequest
+ * - .unauthorized
+ * - .notAcceptable
+ * - .notFound
+ *
+ * @param {Number} status
+ * @api private
+ */
+
+Response.prototype.setStatusProperties = function(status){
+ // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
+ if (status === 1223) {
+ status = 204;
+ }
+
+ var type = status / 100 | 0;
+
+ // status / class
+ this.status = status;
+ this.statusType = type;
+
+ // basics
+ this.info = 1 == type;
+ this.ok = 2 == type;
+ this.clientError = 4 == type;
+ this.serverError = 5 == type;
+ this.error = (4 == type || 5 == type)
+ ? this.toError()
+ : false;
+
+ // sugar
+ this.accepted = 202 == status;
+ this.noContent = 204 == status;
+ this.badRequest = 400 == status;
+ this.unauthorized = 401 == status;
+ this.notAcceptable = 406 == status;
+ this.notFound = 404 == status;
+ this.forbidden = 403 == status;
+};
+
+/**
+ * Return an `Error` representative of this response.
+ *
+ * @return {Error}
+ * @api public
+ */
+
+Response.prototype.toError = function(){
+ var req = this.req;
+ var method = req.method;
+ var url = req.url;
+
+ var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')';
+ var err = new Error(msg);
+ err.status = this.status;
+ err.method = method;
+ err.url = url;
+
+ return err;
+};
+
+/**
+ * Expose `Response`.
+ */
+
+request.Response = Response;
+
+/**
+ * Initialize a new `Request` with the given `method` and `url`.
+ *
+ * @param {String} method
+ * @param {String} url
+ * @api public
+ */
+
+function Request(method, url) {
+ var self = this;
+ Emitter.call(this);
+ this._query = this._query || [];
+ this.method = method;
+ this.url = url;
+ this.header = {};
+ this._header = {};
+ this.on('end', function(){
+ var err = null;
+ var res = null;
+
+ try {
+ res = new Response(self);
+ } catch(e) {
+ err = new Error('Parser is unable to parse the response');
+ err.parse = true;
+ err.original = e;
+ return self.callback(err);
+ }
+
+ self.emit('response', res);
+
+ if (err) {
+ return self.callback(err, res);
+ }
+
+ if (res.status >= 200 && res.status < 300) {
+ return self.callback(err, res);
+ }
+
+ var new_err = new Error(res.statusText || 'Unsuccessful HTTP response');
+ new_err.original = err;
+ new_err.response = res;
+ new_err.status = res.status;
+
+ self.callback(new_err, res);
+ });
+}
+
+/**
+ * Mixin `Emitter`.
+ */
+
+Emitter(Request.prototype);
+
+/**
+ * Allow for extension
+ */
+
+Request.prototype.use = function(fn) {
+ fn(this);
+ return this;
+}
+
+/**
+ * Set timeout to `ms`.
+ *
+ * @param {Number} ms
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.timeout = function(ms){
+ this._timeout = ms;
+ return this;
+};
+
+/**
+ * Clear previous timeout.
+ *
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.clearTimeout = function(){
+ this._timeout = 0;
+ clearTimeout(this._timer);
+ return this;
+};
+
+/**
+ * Abort the request, and clear potential timeout.
+ *
+ * @return {Request}
+ * @api public
+ */
+
+Request.prototype.abort = function(){
+ if (this.aborted) return;
+ this.aborted = true;
+ this.xhr.abort();
+ this.clearTimeout();
+ this.emit('abort');
+ return this;
+};
+
+/**
+ * Set header `field` to `val`, or multiple fields with one object.
+ *
+ * Examples:
+ *
+ * req.get('/')
+ * .set('Accept', 'application/json')
+ * .set('X-API-Key', 'foobar')
+ * .end(callback);
+ *
+ * req.get('/')
+ * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
+ * .end(callback);
+ *
+ * @param {String|Object} field
+ * @param {String} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.set = function(field, val){
+ if (isObject(field)) {
+ for (var key in field) {
+ this.set(key, field[key]);
+ }
+ return this;
+ }
+ this._header[field.toLowerCase()] = val;
+ this.header[field] = val;
+ return this;
+};
+
+/**
+ * Remove header `field`.
+ *
+ * Example:
+ *
+ * req.get('/')
+ * .unset('User-Agent')
+ * .end(callback);
+ *
+ * @param {String} field
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.unset = function(field){
+ delete this._header[field.toLowerCase()];
+ delete this.header[field];
+ return this;
+};
+
+/**
+ * Get case-insensitive header `field` value.
+ *
+ * @param {String} field
+ * @return {String}
+ * @api private
+ */
+
+Request.prototype.getHeader = function(field){
+ return this._header[field.toLowerCase()];
+};
+
+/**
+ * Set Content-Type to `type`, mapping values from `request.types`.
+ *
+ * Examples:
+ *
+ * superagent.types.xml = 'application/xml';
+ *
+ * request.post('/')
+ * .type('xml')
+ * .send(xmlstring)
+ * .end(callback);
+ *
+ * request.post('/')
+ * .type('application/xml')
+ * .send(xmlstring)
+ * .end(callback);
+ *
+ * @param {String} type
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.type = function(type){
+ this.set('Content-Type', request.types[type] || type);
+ return this;
+};
+
+/**
+ * Set Accept to `type`, mapping values from `request.types`.
+ *
+ * Examples:
+ *
+ * superagent.types.json = 'application/json';
+ *
+ * request.get('/agent')
+ * .accept('json')
+ * .end(callback);
+ *
+ * request.get('/agent')
+ * .accept('application/json')
+ * .end(callback);
+ *
+ * @param {String} accept
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.accept = function(type){
+ this.set('Accept', request.types[type] || type);
+ return this;
+};
+
+/**
+ * Set Authorization field value with `user` and `pass`.
+ *
+ * @param {String} user
+ * @param {String} pass
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.auth = function(user, pass){
+ var str = btoa(user + ':' + pass);
+ this.set('Authorization', 'Basic ' + str);
+ return this;
+};
+
+/**
+* Add query-string `val`.
+*
+* Examples:
+*
+* request.get('/shoes')
+* .query('size=10')
+* .query({ color: 'blue' })
+*
+* @param {Object|String} val
+* @return {Request} for chaining
+* @api public
+*/
+
+Request.prototype.query = function(val){
+ if ('string' != typeof val) val = serialize(val);
+ if (val) this._query.push(val);
+ return this;
+};
+
+/**
+ * Write the field `name` and `val` for "multipart/form-data"
+ * request bodies.
+ *
+ * ``` js
+ * request.post('/upload')
+ * .field('foo', 'bar')
+ * .end(callback);
+ * ```
+ *
+ * @param {String} name
+ * @param {String|Blob|File} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.field = function(name, val){
+ if (!this._formData) this._formData = new root.FormData();
+ this._formData.append(name, val);
+ return this;
+};
+
+/**
+ * Queue the given `file` as an attachment to the specified `field`,
+ * with optional `filename`.
+ *
+ * ``` js
+ * request.post('/upload')
+ * .attach(new Blob(['hey!'], { type: "text/html"}))
+ * .end(callback);
+ * ```
+ *
+ * @param {String} field
+ * @param {Blob|File} file
+ * @param {String} filename
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.attach = function(field, file, filename){
+ if (!this._formData) this._formData = new root.FormData();
+ this._formData.append(field, file, filename);
+ return this;
+};
+
+/**
+ * Send `data`, defaulting the `.type()` to "json" when
+ * an object is given.
+ *
+ * Examples:
+ *
+ * // querystring
+ * request.get('/search')
+ * .end(callback)
+ *
+ * // multiple data "writes"
+ * request.get('/search')
+ * .send({ search: 'query' })
+ * .send({ range: '1..5' })
+ * .send({ order: 'desc' })
+ * .end(callback)
+ *
+ * // manual json
+ * request.post('/user')
+ * .type('json')
+ * .send('{"name":"tj"})
+ * .end(callback)
+ *
+ * // auto json
+ * request.post('/user')
+ * .send({ name: 'tj' })
+ * .end(callback)
+ *
+ * // manual x-www-form-urlencoded
+ * request.post('/user')
+ * .type('form')
+ * .send('name=tj')
+ * .end(callback)
+ *
+ * // auto x-www-form-urlencoded
+ * request.post('/user')
+ * .type('form')
+ * .send({ name: 'tj' })
+ * .end(callback)
+ *
+ * // defaults to x-www-form-urlencoded
+ * request.post('/user')
+ * .send('name=tobi')
+ * .send('species=ferret')
+ * .end(callback)
+ *
+ * @param {String|Object} data
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.send = function(data){
+ var obj = isObject(data);
+ var type = this.getHeader('Content-Type');
+
+ // merge
+ if (obj && isObject(this._data)) {
+ for (var key in data) {
+ this._data[key] = data[key];
+ }
+ } else if ('string' == typeof data) {
+ if (!type) this.type('form');
+ type = this.getHeader('Content-Type');
+ if ('application/x-www-form-urlencoded' == type) {
+ this._data = this._data
+ ? this._data + '&' + data
+ : data;
+ } else {
+ this._data = (this._data || '') + data;
+ }
+ } else {
+ this._data = data;
+ }
+
+ if (!obj || isHost(data)) return this;
+ if (!type) this.type('json');
+ return this;
+};
+
+/**
+ * Invoke the callback with `err` and `res`
+ * and handle arity check.
+ *
+ * @param {Error} err
+ * @param {Response} res
+ * @api private
+ */
+
+Request.prototype.callback = function(err, res){
+ var fn = this._callback;
+ this.clearTimeout();
+ fn(err, res);
+};
+
+/**
+ * Invoke callback with x-domain error.
+ *
+ * @api private
+ */
+
+Request.prototype.crossDomainError = function(){
+ var err = new Error('Origin is not allowed by Access-Control-Allow-Origin');
+ err.crossDomain = true;
+ this.callback(err);
+};
+
+/**
+ * Invoke callback with timeout error.
+ *
+ * @api private
+ */
+
+Request.prototype.timeoutError = function(){
+ var timeout = this._timeout;
+ var err = new Error('timeout of ' + timeout + 'ms exceeded');
+ err.timeout = timeout;
+ this.callback(err);
+};
+
+/**
+ * Enable transmission of cookies with x-domain requests.
+ *
+ * Note that for this to work the origin must not be
+ * using "Access-Control-Allow-Origin" with a wildcard,
+ * and also must set "Access-Control-Allow-Credentials"
+ * to "true".
+ *
+ * @api public
+ */
+
+Request.prototype.withCredentials = function(){
+ this._withCredentials = true;
+ return this;
+};
+
+/**
+ * Initiate request, invoking callback `fn(res)`
+ * with an instanceof `Response`.
+ *
+ * @param {Function} fn
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.end = function(fn){
+ var self = this;
+ var xhr = this.xhr = request.getXHR();
+ var query = this._query.join('&');
+ var timeout = this._timeout;
+ var data = this._formData || this._data;
+
+ // store callback
+ this._callback = fn || noop;
+
+ // state change
+ xhr.onreadystatechange = function(){
+ if (4 != xhr.readyState) return;
+
+ // In IE9, reads to any property (e.g. status) off of an aborted XHR will
+ // result in the error "Could not complete the operation due to error c00c023f"
+ var status;
+ try { status = xhr.status } catch(e) { status = 0; }
+
+ if (0 == status) {
+ if (self.timedout) return self.timeoutError();
+ if (self.aborted) return;
+ return self.crossDomainError();
+ }
+ self.emit('end');
+ };
+
+ // progress
+ var handleProgress = function(e){
+ if (e.total > 0) {
+ e.percent = e.loaded / e.total * 100;
+ }
+ self.emit('progress', e);
+ };
+ if (this.hasListeners('progress')) {
+ xhr.onprogress = handleProgress;
+ }
+ try {
+ if (xhr.upload && this.hasListeners('progress')) {
+ xhr.upload.onprogress = handleProgress;
+ }
+ } catch(e) {
+ // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist.
+ // Reported here:
+ // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context
+ }
+
+ // timeout
+ if (timeout && !this._timer) {
+ this._timer = setTimeout(function(){
+ self.timedout = true;
+ self.abort();
+ }, timeout);
+ }
+
+ // querystring
+ if (query) {
+ query = request.serializeObject(query);
+ this.url += ~this.url.indexOf('?')
+ ? '&' + query
+ : '?' + query;
+ }
+
+ // initiate request
+ xhr.open(this.method, this.url, true);
+
+ // CORS
+ if (this._withCredentials) xhr.withCredentials = true;
+
+ // body
+ if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) {
+ // serialize stuff
+ var contentType = this.getHeader('Content-Type');
+ var serialize = request.serialize[contentType ? contentType.split(';')[0] : ''];
+ if (serialize) data = serialize(data);
+ }
+
+ // set header fields
+ for (var field in this.header) {
+ if (null == this.header[field]) continue;
+ xhr.setRequestHeader(field, this.header[field]);
+ }
+
+ // send stuff
+ this.emit('request', this);
+ xhr.send(data);
+ return this;
+};
+
+/**
+ * Faux promise support
+ *
+ * @param {Function} fulfill
+ * @param {Function} reject
+ * @return {Request}
+ */
+
+Request.prototype.then = function (fulfill, reject) {
+ return this.end(function(err, res) {
+ err ? reject(err) : fulfill(res);
+ });
+}
+
+/**
+ * Expose `Request`.
+ */
+
+request.Request = Request;
+
+/**
+ * Issue a request:
+ *
+ * Examples:
+ *
+ * request('GET', '/users').end(callback)
+ * request('/users').end(callback)
+ * request('/users', callback)
+ *
+ * @param {String} method
+ * @param {String|Function} url or callback
+ * @return {Request}
+ * @api public
+ */
+
+function request(method, url) {
+ // callback
+ if ('function' == typeof url) {
+ return new Request('GET', method).end(url);
+ }
+
+ // url first
+ if (1 == arguments.length) {
+ return new Request('GET', method);
+ }
+
+ return new Request(method, url);
+}
+
+/**
+ * GET `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.get = function(url, data, fn){
+ var req = request('GET', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.query(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * HEAD `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.head = function(url, data, fn){
+ var req = request('HEAD', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * DELETE `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.del = function(url, fn){
+ var req = request('DELETE', url);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * PATCH `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} data
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.patch = function(url, data, fn){
+ var req = request('PATCH', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * POST `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} data
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.post = function(url, data, fn){
+ var req = request('POST', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * PUT `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.put = function(url, data, fn){
+ var req = request('PUT', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * Expose `request`.
+ */
+
+module.exports = request;
+
+},{"emitter":12,"reduce":13}],12:[function(require,module,exports){
+
+/**
+ * Expose `Emitter`.
+ */
+
+module.exports = Emitter;
+
+/**
+ * Initialize a new `Emitter`.
+ *
+ * @api public
+ */
+
+function Emitter(obj) {
+ if (obj) return mixin(obj);
+};
+
+/**
+ * Mixin the emitter properties.
+ *
+ * @param {Object} obj
+ * @return {Object}
+ * @api private
+ */
+
+function mixin(obj) {
+ for (var key in Emitter.prototype) {
+ obj[key] = Emitter.prototype[key];
+ }
+ return obj;
+}
+
+/**
+ * Listen on the given `event` with `fn`.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.on =
+Emitter.prototype.addEventListener = function(event, fn){
+ this._callbacks = this._callbacks || {};
+ (this._callbacks[event] = this._callbacks[event] || [])
+ .push(fn);
+ return this;
+};
+
+/**
+ * Adds an `event` listener that will be invoked a single
+ * time then automatically removed.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.once = function(event, fn){
+ var self = this;
+ this._callbacks = this._callbacks || {};
+
+ function on() {
+ self.off(event, on);
+ fn.apply(this, arguments);
+ }
+
+ on.fn = fn;
+ this.on(event, on);
+ return this;
+};
+
+/**
+ * Remove the given callback for `event` or all
+ * registered callbacks.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.off =
+Emitter.prototype.removeListener =
+Emitter.prototype.removeAllListeners =
+Emitter.prototype.removeEventListener = function(event, fn){
+ this._callbacks = this._callbacks || {};
+
+ // all
+ if (0 == arguments.length) {
+ this._callbacks = {};
+ return this;
+ }
+
+ // specific event
+ var callbacks = this._callbacks[event];
+ if (!callbacks) return this;
+
+ // remove all handlers
+ if (1 == arguments.length) {
+ delete this._callbacks[event];
+ return this;
+ }
+
+ // remove specific handler
+ var cb;
+ for (var i = 0; i < callbacks.length; i++) {
+ cb = callbacks[i];
+ if (cb === fn || cb.fn === fn) {
+ callbacks.splice(i, 1);
+ break;
+ }
+ }
+ return this;
+};
+
+/**
+ * Emit `event` with the given args.
+ *
+ * @param {String} event
+ * @param {Mixed} ...
+ * @return {Emitter}
+ */
+
+Emitter.prototype.emit = function(event){
+ this._callbacks = this._callbacks || {};
+ var args = [].slice.call(arguments, 1)
+ , callbacks = this._callbacks[event];
+
+ if (callbacks) {
+ callbacks = callbacks.slice(0);
+ for (var i = 0, len = callbacks.length; i < len; ++i) {
+ callbacks[i].apply(this, args);
+ }
+ }
+
+ return this;
+};
+
+/**
+ * Return array of callbacks for `event`.
+ *
+ * @param {String} event
+ * @return {Array}
+ * @api public
+ */
+
+Emitter.prototype.listeners = function(event){
+ this._callbacks = this._callbacks || {};
+ return this._callbacks[event] || [];
+};
+
+/**
+ * Check if this emitter has `event` handlers.
+ *
+ * @param {String} event
+ * @return {Boolean}
+ * @api public
+ */
+
+Emitter.prototype.hasListeners = function(event){
+ return !! this.listeners(event).length;
+};
+
+},{}],13:[function(require,module,exports){
+
+/**
+ * Reduce `arr` with `fn`.
+ *
+ * @param {Array} arr
+ * @param {Function} fn
+ * @param {Mixed} initial
+ *
+ * TODO: combatible error handling?
+ */
+
+module.exports = function(arr, fn, initial){
+ var idx = 0;
+ var len = arr.length;
+ var curr = arguments.length == 3
+ ? initial
+ : arr[idx++];
+
+ while (idx < len) {
+ curr = fn.call(null, curr, arr[idx], ++idx, arr);
+ }
+
+ return curr;
+};
+},{}],14:[function(require,module,exports){
+
+/**
+ * Module dependencies.
+ */
+
+var global = (function() { return this; })();
+
+/**
+ * WebSocket constructor.
+ */
+
+var WebSocket = global.WebSocket || global.MozWebSocket;
+
+/**
+ * Module exports.
+ */
+
+module.exports = WebSocket ? ws : null;
+
+/**
+ * WebSocket constructor.
+ *
+ * The third `opts` options object gets ignored in web browsers, since it's
+ * non-standard, and throws a TypeError if passed to the constructor.
+ * See: https://github.com/einaros/ws/issues/227
+ *
+ * @param {String} uri
+ * @param {Array} protocols (optional)
+ * @param {Object) opts (optional)
+ * @api public
+ */
+
+function ws(uri, protocols, opts) {
+ var instance;
+ if (protocols) {
+ instance = new WebSocket(uri, protocols);
+ } else {
+ instance = new WebSocket(uri);
+ }
+ return instance;
+}
+
+if (WebSocket) ws.prototype = WebSocket.prototype;
+
+},{}]},{},[5])(5)
+});
\ No newline at end of file
diff --git a/web-dist/discord.3.6.3.js b/web-dist/discord.3.6.3.js
new file mode 100644
index 000000000..0d9f9341a
--- /dev/null
+++ b/web-dist/discord.3.6.3.js
@@ -0,0 +1,3879 @@
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Discord = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o]*>/g) || [])[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
+ var mention = _step3.value;
+
+ _mentions.push(mention.substring(2, mention.length - 1));
+ }
+ } catch (err) {
+ _didIteratorError3 = true;
+ _iteratorError3 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion3 && _iterator3["return"]) {
+ _iterator3["return"]();
+ }
+ } finally {
+ if (_didIteratorError3) {
+ throw _iteratorError3;
+ }
+ }
+ }
+
+ return _mentions;
+ }
+ });
+
+ return prom;
+ }
+
+ //def createws
+ }, {
+ key: "createws",
+ value: function createws(url) {
+ if (this.websocket) return false;
+
+ var self = this;
+
+ //good to go
+ this.websocket = new WebSocket(url);
+
+ //open
+ this.websocket.onopen = function () {
+ self.trySendConnData(); //try connecting
+ };
+
+ //close
+ this.websocket.onclose = function () {
+ self.trigger("disconnected");
+ };
+
+ //message
+ this.websocket.onmessage = function (e) {
+
+ var dat = false,
+ data = {};
+
+ try {
+ dat = JSON.parse(e.data);
+ data = dat.d;
+ } catch (err) {
+ self.trigger("error", err, e);
+ return;
+ }
+
+ self.trigger("raw", dat);
+
+ //valid message
+ switch (dat.t) {
+
+ case "READY":
+ self.debug("received ready packet");
+
+ self.user = self.addUser(data.user);
+
+ var _iteratorNormalCompletion4 = true;
+ var _didIteratorError4 = false;
+ var _iteratorError4 = undefined;
+
+ try {
+ for (var _iterator4 = data.guilds[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
+ var _server = _step4.value;
+
+ var server = self.addServer(_server);
+ }
+ } catch (err) {
+ _didIteratorError4 = true;
+ _iteratorError4 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion4 && _iterator4["return"]) {
+ _iterator4["return"]();
+ }
+ } finally {
+ if (_didIteratorError4) {
+ throw _iteratorError4;
+ }
+ }
+ }
+
+ var _iteratorNormalCompletion5 = true;
+ var _didIteratorError5 = false;
+ var _iteratorError5 = undefined;
+
+ try {
+ for (var _iterator5 = data.private_channels[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
+ var _pmc = _step5.value;
+
+ var pmc = self.addPMChannel(_pmc);
+ }
+ } catch (err) {
+ _didIteratorError5 = true;
+ _iteratorError5 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion5 && _iterator5["return"]) {
+ _iterator5["return"]();
+ }
+ } finally {
+ if (_didIteratorError5) {
+ throw _iteratorError5;
+ }
+ }
+ }
+
+ self.trigger("ready");
+ self.readyTime = Date.now();
+ self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users.");
+ self.state = 3;
+ setInterval(function () {
+ self.keepAlive.apply(self);
+ }, data.heartbeat_interval);
+
+ break;
+ case "MESSAGE_CREATE":
+ self.debug("received message");
+
+ var mentions = [];
+ data.mentions = data.mentions || []; //for some reason this was not defined at some point?
+ var _iteratorNormalCompletion6 = true;
+ var _didIteratorError6 = false;
+ var _iteratorError6 = undefined;
+
+ try {
+ for (var _iterator6 = data.mentions[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
+ var mention = _step6.value;
+
+ mentions.push(self.addUser(mention));
+ }
+ } catch (err) {
+ _didIteratorError6 = true;
+ _iteratorError6 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion6 && _iterator6["return"]) {
+ _iterator6["return"]();
+ }
+ } finally {
+ if (_didIteratorError6) {
+ throw _iteratorError6;
+ }
+ }
+ }
+
+ var channel = self.getChannel("id", data.channel_id);
+ if (channel) {
+ var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author)));
+ self.trigger("message", msg);
+ }
+
+ break;
+ case "MESSAGE_DELETE":
+ self.debug("message deleted");
+
+ var channel = self.getChannel("id", data.channel_id);
+ var message = channel.getMessage("id", data.id);
+ if (message) {
+ self.trigger("messageDelete", channel, message);
+ channel.messages.splice(channel.messages.indexOf(message), 1);
+ } else {
+ //don't have the cache of that message ;(
+ self.trigger("messageDelete", channel);
+ }
+ break;
+ case "MESSAGE_UPDATE":
+ self.debug("message updated");
+
+ var channel = self.getChannel("id", data.channel_id);
+ var formerMessage = channel.getMessage("id", data.id);
+
+ if (formerMessage) {
+
+ //new message might be partial, so we need to fill it with whatever the old message was.
+ var info = {};
+
+ for (var key in formerMessage) {
+ info[key] = formerMessage[key];
+ }
+
+ for (var key in data) {
+ info[key] = data[key];
+ }
+
+ var mentions = [];
+ var _iteratorNormalCompletion7 = true;
+ var _didIteratorError7 = false;
+ var _iteratorError7 = undefined;
+
+ try {
+ for (var _iterator7 = info.mentions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
+ var mention = _step7.value;
+
+ mentions.push(self.addUser(mention));
+ }
+ } catch (err) {
+ _didIteratorError7 = true;
+ _iteratorError7 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion7 && _iterator7["return"]) {
+ _iterator7["return"]();
+ }
+ } finally {
+ if (_didIteratorError7) {
+ throw _iteratorError7;
+ }
+ }
+ }
+
+ var newMessage = new Message(info, channel, mentions, formerMessage.author);
+
+ self.trigger("messageUpdate", newMessage, formerMessage);
+
+ channel.messages[channel.messages.indexOf(formerMessage)] = newMessage;
+ }
+
+ // message isn't in cache, and if it's a partial it could cause
+ // all hell to break loose... best to just act as if nothing happened
+
+ break;
+
+ case "GUILD_DELETE":
+
+ var server = self.getServer("id", data.id);
+
+ if (server) {
+ self.serverCache.splice(self.serverCache.indexOf(server), 1);
+ self.trigger("serverDelete", server);
+ }
+
+ break;
+
+ case "CHANNEL_DELETE":
+
+ var channel = self.getChannel("id", data.id);
+
+ if (channel) {
+
+ var server = channel.server;
+
+ if (server) {
+
+ server.channels.splice(server.channels.indexOf(channel), 1);
+ }
+
+ self.trigger("channelDelete", channel);
+
+ self.serverCache.splice(self.serverCache.indexOf(channel), 1);
+ }
+
+ break;
+
+ case "GUILD_CREATE":
+
+ var server = self.getServer("id", data.id);
+
+ if (!server) {
+ //if server doesn't already exist because duh
+ server = self.addServer(data);
+ } /*else if(server.channels.length === 0){
+
+ var srv = new Server(data, self);
+ for(channel of data.channels){
+ srv.channels.push(new Channel(channel, data.id));
+ }
+ self.serverCache[self.serverCache.indexOf(server)] = srv;
+
+ }*/
+
+ if (self.serverCreateListener[data.id]) {
+ var cbs = self.serverCreateListener[data.id];
+ cbs[0](server); //promise then callback
+ cbs[1](null, server); //legacy callback
+ self.serverCreateListener[data.id] = null;
+ }
+
+ self.trigger("serverCreate", server);
+
+ break;
+
+ case "CHANNEL_CREATE":
+
+ var channel = self.getChannel("id", data.id);
+
+ if (!channel) {
+
+ var chann = self.addChannel(data, data.guild_id);
+ var srv = self.getServer("id", data.guild_id);
+ if (srv) {
+ srv.addChannel(chann);
+ }
+ self.trigger("channelCreate", chann);
+ }
+
+ break;
+
+ case "GUILD_MEMBER_ADD":
+
+ var server = self.getServer("id", data.guild_id);
+
+ if (server) {
+
+ var user = self.addUser(data.user); //if for whatever reason it doesn't exist..
+
+ if (! ~server.members.indexOf(user)) {
+ server.members.push(user);
+ }
+
+ self.trigger("serverNewMember", user, server);
+ }
+
+ break;
+
+ case "GUILD_MEMBER_REMOVE":
+
+ var server = self.getServer("id", data.guild_id);
+
+ if (server) {
+
+ var user = self.addUser(data.user); //if for whatever reason it doesn't exist..
+
+ if (~server.members.indexOf(user)) {
+ server.members.splice(server.members.indexOf(user), 1);
+ }
+
+ self.trigger("serverRemoveMember", user, server);
+ }
+
+ break;
+
+ case "USER_UPDATE":
+
+ if (self.user && data.id === self.user.id) {
+
+ var newUser = new User(data); //not actually adding to the cache
+
+ self.trigger("userUpdate", newUser, self.user);
+
+ if (~self.userCache.indexOf(self.user)) {
+ self.userCache[self.userCache.indexOf(self.user)] = newUser;
+ }
+
+ self.user = newUser;
+ }
+
+ break;
+
+ case "PRESENCE_UPDATE":
+
+ var userInCache = self.getUser("id", data.user.id);
+
+ if (userInCache) {
+ //user exists
+ var presenceUser = new User(data.user);
+ if (presenceUser.equalsStrict(userInCache)) {
+ //they're exactly the same, an actual presence update
+ userInCache.status = data.status;
+ self.trigger("presence", {
+ user: userInCache,
+ status: data.status,
+ server: self.getServer("id", data.guild_id),
+ gameId: data.game_id
+ });
+ } else {
+ //one of their details changed.
+ self.trigger("userUpdate", userInCache, presenceUser);
+ self.userCache[self.userCache.indexOf(userInCache)] = presenceUser;
+ }
+ }
+
+ break;
+
+ case "CHANNEL_UPDATE":
+
+ var channelInCache = self.getChannel("id", data.id),
+ serverInCache = self.getServer("id", data.guild_id);
+
+ if (channelInCache && serverInCache) {
+
+ var newChann = new Channel(data, serverInCache);
+ newChann.messages = channelInCache.messages;
+
+ self.trigger("channelUpdate", channelInCache, newChann);
+
+ self.channelCache[self.channelCache.indexOf(channelInCache)] = newChann;
+ }
+
+ break;
+
+ default:
+ self.debug("received unknown packet");
+ self.trigger("unknown", dat);
+ break;
+
+ }
+ };
+ }
+
+ //def addUser
+ }, {
+ key: "addUser",
+ value: function addUser(data) {
+ if (!this.getUser("id", data.id)) {
+ this.userCache.push(new User(data));
+ }
+ return this.getUser("id", data.id);
+ }
+
+ //def addChannel
+ }, {
+ key: "addChannel",
+ value: function addChannel(data, serverId) {
+ if (!this.getChannel("id", data.id)) {
+ this.channelCache.push(new Channel(data, this.getServer("id", serverId)));
+ }
+ return this.getChannel("id", data.id);
+ }
+ }, {
+ key: "addPMChannel",
+ value: function addPMChannel(data) {
+ if (!this.getPMChannel("id", data.id)) {
+ this.pmChannelCache.push(new PMChannel(data, this));
+ }
+ return this.getPMChannel("id", data.id);
+ }
+ }, {
+ key: "setTopic",
+ value: function setTopic(channel, topic) {
+ var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err) {} : arguments[2];
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+
+ self.resolveDestination(channel).then(next)["catch"](error);
+
+ function error(e) {
+ callback(e);
+ reject(e);
+ }
+
+ function next(destination) {
+
+ var asChan = self.getChannel("id", destination);
+
+ request.patch(Endpoints.CHANNELS + "/" + destination).set("authorization", self.token).send({
+ name: asChan.name,
+ position: 0,
+ topic: topic
+ }).end(function (err, res) {
+ if (err) {
+ error(err);
+ } else {
+ asChan.topic = res.body.topic;
+ resolve();
+ callback();
+ }
+ });
+ }
+ });
+ }
+
+ //def addServer
+ }, {
+ key: "addServer",
+ value: function addServer(data) {
+
+ var self = this;
+ var server = this.getServer("id", data.id);
+
+ if (data.unavailable) {
+ self.trigger("unavailable", data);
+ self.debug("Server ID " + data.id + " has been marked unavailable by Discord. It was not cached.");
+ return;
+ }
+
+ if (!server) {
+ server = new Server(data, this);
+ this.serverCache.push(server);
+ if (data.channels) {
+ var _iteratorNormalCompletion8 = true;
+ var _didIteratorError8 = false;
+ var _iteratorError8 = undefined;
+
+ try {
+ for (var _iterator8 = data.channels[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
+ var channel = _step8.value;
+
+ server.channels.push(this.addChannel(channel, server.id));
+ }
+ } catch (err) {
+ _didIteratorError8 = true;
+ _iteratorError8 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion8 && _iterator8["return"]) {
+ _iterator8["return"]();
+ }
+ } finally {
+ if (_didIteratorError8) {
+ throw _iteratorError8;
+ }
+ }
+ }
+ }
+ }
+
+ var _iteratorNormalCompletion9 = true;
+ var _didIteratorError9 = false;
+ var _iteratorError9 = undefined;
+
+ try {
+ for (var _iterator9 = data.presences[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) {
+ var presence = _step9.value;
+
+ self.getUser("id", presence.user.id).status = presence.status;
+ }
+ } catch (err) {
+ _didIteratorError9 = true;
+ _iteratorError9 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion9 && _iterator9["return"]) {
+ _iterator9["return"]();
+ }
+ } finally {
+ if (_didIteratorError9) {
+ throw _iteratorError9;
+ }
+ }
+ }
+
+ return server;
+ }
+
+ //def getUser
+ }, {
+ key: "getUser",
+ value: function getUser(key, value) {
+ var _iteratorNormalCompletion10 = true;
+ var _didIteratorError10 = false;
+ var _iteratorError10 = undefined;
+
+ try {
+ for (var _iterator10 = this.userCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {
+ var user = _step10.value;
+
+ if (user[key] === value) {
+ return user;
+ }
+ }
+ } catch (err) {
+ _didIteratorError10 = true;
+ _iteratorError10 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion10 && _iterator10["return"]) {
+ _iterator10["return"]();
+ }
+ } finally {
+ if (_didIteratorError10) {
+ throw _iteratorError10;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ //def getChannel
+ }, {
+ key: "getChannel",
+ value: function getChannel(key, value) {
+ var _iteratorNormalCompletion11 = true;
+ var _didIteratorError11 = false;
+ var _iteratorError11 = undefined;
+
+ try {
+ for (var _iterator11 = this.channelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) {
+ var channel = _step11.value;
+
+ if (channel[key] === value) {
+ return channel;
+ }
+ }
+ } catch (err) {
+ _didIteratorError11 = true;
+ _iteratorError11 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion11 && _iterator11["return"]) {
+ _iterator11["return"]();
+ }
+ } finally {
+ if (_didIteratorError11) {
+ throw _iteratorError11;
+ }
+ }
+ }
+
+ return this.getPMChannel(key, value); //might be a PM
+ }
+ }, {
+ key: "getPMChannel",
+ value: function getPMChannel(key, value) {
+ var _iteratorNormalCompletion12 = true;
+ var _didIteratorError12 = false;
+ var _iteratorError12 = undefined;
+
+ try {
+ for (var _iterator12 = this.pmChannelCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) {
+ var channel = _step12.value;
+
+ if (channel[key] === value) {
+ return channel;
+ }
+ }
+ } catch (err) {
+ _didIteratorError12 = true;
+ _iteratorError12 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion12 && _iterator12["return"]) {
+ _iterator12["return"]();
+ }
+ } finally {
+ if (_didIteratorError12) {
+ throw _iteratorError12;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ //def getServer
+ }, {
+ key: "getServer",
+ value: function getServer(key, value) {
+ var _iteratorNormalCompletion13 = true;
+ var _didIteratorError13 = false;
+ var _iteratorError13 = undefined;
+
+ try {
+ for (var _iterator13 = this.serverCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) {
+ var server = _step13.value;
+
+ if (server[key] === value) {
+ return server;
+ }
+ }
+ } catch (err) {
+ _didIteratorError13 = true;
+ _iteratorError13 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion13 && _iterator13["return"]) {
+ _iterator13["return"]();
+ }
+ } finally {
+ if (_didIteratorError13) {
+ throw _iteratorError13;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ //def trySendConnData
+ }, {
+ key: "trySendConnData",
+ value: function trySendConnData() {
+
+ if (this.token && !this.alreadySentData) {
+
+ this.alreadySentData = true;
+
+ var data = {
+ op: 2,
+ d: {
+ token: this.token,
+ v: 3,
+ properties: {
+ "$os": "discord.js",
+ "$browser": "discord.js",
+ "$device": "discord.js",
+ "$referrer": "",
+ "$referring_domain": ""
+ }
+ }
+ };
+ this.websocket.send(JSON.stringify(data));
+ }
+ }
+ }, {
+ key: "resolveServerID",
+ value: function resolveServerID(resource) {
+
+ if (resource instanceof Server) {
+ return resource.id;
+ } else if (!isNaN(resource) && resource.length && resource.length === 17) {
+ return resource;
+ }
+ }
+ }, {
+ key: "resolveDestination",
+ value: function resolveDestination(destination) {
+ var channId = false;
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ if (destination instanceof Server) {
+ channId = destination.id; //general is the same as server id
+ } else if (destination instanceof Channel) {
+ channId = destination.id;
+ } else if (destination instanceof Message) {
+ channId = destination.channel.id;
+ } else if (destination instanceof PMChannel) {
+ channId = destination.id;
+ } else if (destination instanceof User) {
+
+ //check if we have a PM
+ var _iteratorNormalCompletion14 = true;
+ var _didIteratorError14 = false;
+ var _iteratorError14 = undefined;
+
+ try {
+ for (var _iterator14 = self.pmChannelCache[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) {
+ var pmc = _step14.value;
+
+ if (pmc.user.equals(destination)) {
+ resolve(pmc.id);
+ return;
+ }
+ }
+
+ //we don't, at this point we're late
+ } catch (err) {
+ _didIteratorError14 = true;
+ _iteratorError14 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion14 && _iterator14["return"]) {
+ _iterator14["return"]();
+ }
+ } finally {
+ if (_didIteratorError14) {
+ throw _iteratorError14;
+ }
+ }
+ }
+
+ self.startPM(destination).then(function (pmc) {
+ resolve(pmc.id);
+ })["catch"](reject);
+ } else {
+ channId = destination;
+ }
+ if (channId) resolve(channId);else reject();
+ });
+ }
+ }, {
+ key: "_sendMessage",
+ value: function _sendMessage(destination, content, tts, mentions) {
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({
+ content: content,
+ mentions: mentions,
+ tts: tts
+ }).end(function (err, res) {
+
+ if (err) {
+ reject(err);
+ } else {
+ var data = res.body;
+
+ var mentions = [];
+
+ data.mentions = data.mentions || []; //for some reason this was not defined at some point?
+
+ var _iteratorNormalCompletion15 = true;
+ var _didIteratorError15 = false;
+ var _iteratorError15 = undefined;
+
+ try {
+ for (var _iterator15 = data.mentions[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) {
+ var mention = _step15.value;
+
+ mentions.push(self.addUser(mention));
+ }
+ } catch (err) {
+ _didIteratorError15 = true;
+ _iteratorError15 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion15 && _iterator15["return"]) {
+ _iterator15["return"]();
+ }
+ } finally {
+ if (_didIteratorError15) {
+ throw _iteratorError15;
+ }
+ }
+ }
+
+ var channel = self.getChannel("id", data.channel_id);
+ if (channel) {
+ var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author)));
+ resolve(msg);
+ }
+ }
+ });
+ });
+ }
+ }, {
+ key: "_sendFile",
+ value: function _sendFile(destination, attachment) {
+ var attachmentName = arguments.length <= 2 || arguments[2] === undefined ? "DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png" : arguments[2];
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).attach("file", attachment, attachmentName).end(function (err, res) {
+
+ if (err) {
+ reject(err);
+ } else {
+
+ var chann = self.getChannel("id", destination);
+ if (chann) {
+ var msg = chann.addMessage(new Message(res.body, chann, [], self.user));
+ resolve(msg);
+ }
+ }
+ });
+ });
+ }
+ }, {
+ key: "_updateMessage",
+ value: function _updateMessage(message, content) {
+ var self = this;
+ return new Promise(function (resolve, reject) {
+ request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).send({
+ content: content,
+ mentions: []
+ }).end(function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ var msg = new Message(res.body, message.channel, message.mentions, message.sender);
+ resolve(msg);
+ message.channel.messages[message.channel.messages.indexOf(message)] = msg;
+ }
+ });
+ });
+ }
+ }, {
+ key: "_deleteMessage",
+ value: function _deleteMessage(message) {
+ var self = this;
+ return new Promise(function (resolve, reject) {
+
+ request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).end(function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ resolve();
+ }
+ });
+ });
+ }
+ }, {
+ key: "checkQueue",
+ value: function checkQueue(channelID) {
+ var _this = this;
+
+ var self = this;
+
+ if (!this.checkingQueue[channelID]) {
+ (function () {
+ var doNext = function doNext() {
+ if (self.queue[channelID].length === 0) {
+ done();
+ return;
+ }
+ var queuedEvent = self.queue[channelID][0];
+ switch (queuedEvent.action) {
+ case "sendMessage":
+ var msgToSend = queuedEvent;
+ self._sendMessage(channelID, msgToSend.content, msgToSend.tts, msgToSend.mentions).then(function (msg) {
+ msgToSend.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ msgToSend.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ case "sendFile":
+ var fileToSend = queuedEvent;
+ self._sendFile(channelID, fileToSend.attachment, fileToSend.attachmentName).then(function (msg) {
+ fileToSend.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ fileToSend.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ case "updateMessage":
+ var msgToUpd = queuedEvent;
+ self._updateMessage(msgToUpd.message, msgToUpd.content).then(function (msg) {
+ msgToUpd.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ msgToUpd.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ case "deleteMessage":
+ var msgToDel = queuedEvent;
+ self._deleteMessage(msgToDel.message).then(function (msg) {
+ msgToDel.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ msgToDel.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ default:
+ done();
+ break;
+ }
+ };
+
+ var done = function done() {
+ self.checkingQueue[channelID] = false;
+ return;
+ };
+
+ //if we aren't already checking this queue.
+ _this.checkingQueue[channelID] = true;
+ doNext();
+ })();
+ }
+ }
+ }, {
+ key: "getGateway",
+ value: function getGateway() {
+ var self = this;
+ return new Promise(function (resolve, reject) {
+ request.get(Endpoints.API + "/gateway").set("authorization", self.token).end(function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ resolve(res.body.url);
+ }
+ });
+ });
+ }
+ }, {
+ key: "setStatusIdle",
+ value: function setStatusIdle() {
+ this.setStatus("idle");
+ }
+ }, {
+ key: "setStatusOnline",
+ value: function setStatusOnline() {
+ this.setStatus("online");
+ }
+ }, {
+ key: "setStatusActive",
+ value: function setStatusActive() {
+ this.setStatusOnline();
+ }
+ }, {
+ key: "setStatusHere",
+ value: function setStatusHere() {
+ this.setStatusOnline();
+ }
+ }, {
+ key: "setStatusAway",
+ value: function setStatusAway() {
+ this.setStatusIdle();
+ }
+ }, {
+ key: "startTyping",
+ value: function startTyping(chann, stopTypeTime) {
+ var self = this;
+
+ this.resolveDestination(chann).then(next);
+
+ function next(channel) {
+ if (self.typingIntervals[channel]) {
+ return;
+ }
+
+ var fn = function fn() {
+ request.post(Endpoints.CHANNELS + "/" + channel + "/typing").set("authorization", self.token).end();
+ };
+
+ fn();
+
+ var interval = setInterval(fn, 3000);
+
+ self.typingIntervals[channel] = interval;
+
+ if (stopTypeTime) {
+ setTimeout(function () {
+ self.stopTyping(channel);
+ }, stopTypeTime);
+ }
+ }
+ }
+ }, {
+ key: "stopTyping",
+ value: function stopTyping(chann) {
+ var self = this;
+
+ this.resolveDestination(chann).then(next);
+
+ function next(channel) {
+ if (!self.typingIntervals[channel]) {
+ return;
+ }
+
+ clearInterval(self.typingIntervals[channel]);
+
+ delete self.typingIntervals[channel];
+ }
+ }
+ }, {
+ key: "setStatus",
+ value: function setStatus(stat) {
+
+ var idleTime = stat === "online" ? null : Date.now();
+
+ this.__idleTime = idleTime;
+
+ this.websocket.send(JSON.stringify({
+ op: 3,
+ d: {
+ idle_since: this.__idleTime,
+ game_id: this.__gameId
+ }
+ }));
+ }
+ }, {
+ key: "setPlayingGame",
+ value: function setPlayingGame(id) {
+
+ if (id instanceof String || typeof id === "string") {
+
+ // working on names
+ var gid = id.trim().toUpperCase();
+
+ id = null;
+
+ var _iteratorNormalCompletion16 = true;
+ var _didIteratorError16 = false;
+ var _iteratorError16 = undefined;
+
+ try {
+ for (var _iterator16 = gameMap[Symbol.iterator](), _step16; !(_iteratorNormalCompletion16 = (_step16 = _iterator16.next()).done); _iteratorNormalCompletion16 = true) {
+ var game = _step16.value;
+
+ if (game.name.trim().toUpperCase() === gid) {
+
+ id = game.id;
+ break;
+ }
+ }
+ } catch (err) {
+ _didIteratorError16 = true;
+ _iteratorError16 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion16 && _iterator16["return"]) {
+ _iterator16["return"]();
+ }
+ } finally {
+ if (_didIteratorError16) {
+ throw _iteratorError16;
+ }
+ }
+ }
+ }
+
+ this.__gameId = id;
+
+ this.websocket.send(JSON.stringify({
+ op: 3,
+ d: {
+ idle_since: this.__idleTime,
+ game_id: this.__gameId
+ }
+ }));
+ }
+ }, {
+ key: "playGame",
+ value: function playGame(id) {
+ this.setPlayingGame(id);
+ }
+ }, {
+ key: "playingGame",
+ value: function playingGame(id) {
+
+ this.setPlayingGame(id);
+ }
+ }, {
+ key: "uptime",
+ get: function get() {
+
+ return this.readyTime ? Date.now() - this.readyTime : null;
+ }
+ }, {
+ key: "ready",
+ get: function get() {
+ return this.state === 3;
+ }
+ }, {
+ key: "servers",
+ get: function get() {
+ return this.serverCache;
+ }
+ }, {
+ key: "channels",
+ get: function get() {
+ return this.channelCache;
+ }
+ }, {
+ key: "users",
+ get: function get() {
+ return this.userCache;
+ }
+ }, {
+ key: "PMChannels",
+ get: function get() {
+ return this.pmChannelCache;
+ }
+ }, {
+ key: "messages",
+ get: function get() {
+
+ var msgs = [];
+ var _iteratorNormalCompletion17 = true;
+ var _didIteratorError17 = false;
+ var _iteratorError17 = undefined;
+
+ try {
+ for (var _iterator17 = this.channelCache[Symbol.iterator](), _step17; !(_iteratorNormalCompletion17 = (_step17 = _iterator17.next()).done); _iteratorNormalCompletion17 = true) {
+ var channel = _step17.value;
+
+ msgs = msgs.concat(channel.messages);
+ }
+ } catch (err) {
+ _didIteratorError17 = true;
+ _iteratorError17 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion17 && _iterator17["return"]) {
+ _iterator17["return"]();
+ }
+ } finally {
+ if (_didIteratorError17) {
+ throw _iteratorError17;
+ }
+ }
+ }
+
+ return msgs;
+ }
+ }]);
+
+ return Client;
+})();
+
+module.exports = Client;
+
+},{"../ref/gameMap.json":15,"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,"fs":10,"superagent":11,"ws":14}],2:[function(require,module,exports){
+"use strict";
+
+exports.BASE_DOMAIN = "discordapp.com";
+exports.BASE = "https://" + exports.BASE_DOMAIN;
+exports.WEBSOCKET_HUB = "wss://" + exports.BASE_DOMAIN + "/hub";
+
+exports.API = exports.BASE + "/api";
+exports.AUTH = exports.API + "/auth";
+exports.LOGIN = exports.AUTH + "/login";
+exports.LOGOUT = exports.AUTH + "/logout";
+exports.USERS = exports.API + "/users";
+exports.SERVERS = exports.API + "/guilds";
+exports.CHANNELS = exports.API + "/channels";
+
+},{}],3:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var PMChannel = (function () {
+ function PMChannel(data, client) {
+ _classCallCheck(this, PMChannel);
+
+ this.user = client.getUser("id", data.recipient.id);
+ this.id = data.id;
+ this.messages = [];
+ }
+
+ _createClass(PMChannel, [{
+ key: "addMessage",
+ value: function addMessage(data) {
+ if (!this.getMessage("id", data.id)) {
+ this.messages.push(data);
+ }
+ return this.getMessage("id", data.id);
+ }
+ }, {
+ key: "getMessage",
+ value: function getMessage(key, value) {
+
+ if (this.messages.length > 1000) {
+ this.messages.splice(0, 1);
+ }
+
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var message = _step.value;
+
+ if (message[key] === value) {
+ return message;
+ }
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator["return"]) {
+ _iterator["return"]();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+
+ return null;
+ }
+ }, {
+ key: "isPrivate",
+ get: function get() {
+ return true;
+ }
+ }]);
+
+ return PMChannel;
+})();
+
+module.exports = PMChannel;
+
+},{}],4:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Channel = (function () {
+ function Channel(data, server) {
+ _classCallCheck(this, Channel);
+
+ this.server = server;
+ this.name = data.name;
+ this.type = data.type;
+ this.topic = data.topic;
+ this.id = data.id;
+ this.messages = [];
+ //this.isPrivate = isPrivate; //not sure about the implementation of this...
+ }
+
+ _createClass(Channel, [{
+ key: "equals",
+ value: function equals(object) {
+ return object && object.id === this.id;
+ }
+ }, {
+ key: "addMessage",
+ value: function addMessage(data) {
+
+ if (this.messages.length > 1000) {
+ this.messages.splice(0, 1);
+ }
+
+ if (!this.getMessage("id", data.id)) {
+ this.messages.push(data);
+ }
+
+ return this.getMessage("id", data.id);
+ }
+ }, {
+ key: "getMessage",
+ value: function getMessage(key, value) {
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var message = _step.value;
+
+ if (message[key] === value) {
+ return message;
+ }
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator["return"]) {
+ _iterator["return"]();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+
+ return null;
+ }
+ }, {
+ key: "toString",
+ value: function toString() {
+ return "<#" + this.id + ">";
+ }
+ }, {
+ key: "client",
+ get: function get() {
+ return this.server.client;
+ }
+ }, {
+ key: "isPrivate",
+ get: function get() {
+ return false;
+ }
+ }, {
+ key: "users",
+ get: function get() {
+ return this.server.members;
+ }
+ }, {
+ key: "members",
+ get: function get() {
+ return this.server.members;
+ }
+ }]);
+
+ return Channel;
+})();
+
+module.exports = Channel;
+
+},{}],5:[function(require,module,exports){
+"use strict";
+
+var request = require("superagent");
+var Endpoints = require("./Endpoints.js");
+var Client = require("./Client.js");
+
+var Discord = {
+ Endpoints: Endpoints,
+ Client: Client
+};
+
+module.exports = Discord;
+
+},{"./Client.js":1,"./Endpoints.js":2,"superagent":11}],6:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Invite = (function () {
+ function Invite(data, client) {
+ _classCallCheck(this, Invite);
+
+ this.max_age = data.max_age;
+ this.code = data.code;
+ this.server = client.getServer("id", data.guild.id);
+ this.revoked = data.revoked;
+ this.created_at = Date.parse(data.created_at);
+ this.temporary = data.temporary;
+ this.uses = data.uses;
+ this.max_uses = data.uses;
+ this.inviter = client.addUser(data.inviter);
+ this.xkcd = data.xkcdpass;
+ this.channel = client.getChannel("id", data.channel.id);
+ }
+
+ _createClass(Invite, [{
+ key: "URL",
+ get: function get() {
+ var code = this.xkcd ? this.xkcdpass : this.code;
+ return "https://discord.gg/" + code;
+ }
+ }]);
+
+ return Invite;
+})();
+
+module.exports = Invite;
+
+},{}],7:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var PMChannel = require("./PMChannel.js");
+
+var Message = (function () {
+ function Message(data, channel, mentions, author) {
+ _classCallCheck(this, Message);
+
+ this.tts = data.tts;
+ this.timestamp = Date.parse(data.timestamp);
+ this.nonce = data.nonce;
+ this.mentions = mentions;
+ this.everyoneMentioned = data.mention_everyone;
+ this.id = data.id;
+ this.embeds = data.embeds;
+ this.editedTimestamp = data.edited_timestamp;
+ this.content = data.content.trim();
+ this.channel = channel;
+ this.author = author;
+ this.attachments = data.attachments;
+ }
+
+ /*exports.Message.prototype.isPM = function() {
+ return ( this.channel instanceof PMChannel );
+ }*/
+
+ _createClass(Message, [{
+ key: "isMentioned",
+ value: function isMentioned(user) {
+ var id = user.id ? user.id : user;
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = this.mentions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var mention = _step.value;
+
+ if (mention.id === id) {
+ return true;
+ }
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator["return"]) {
+ _iterator["return"]();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+
+ return false;
+ }
+ }, {
+ key: "sender",
+ get: function get() {
+ return this.author;
+ }
+ }, {
+ key: "isPrivate",
+ get: function get() {
+ return this.channel.isPrivate;
+ }
+ }]);
+
+ return Message;
+})();
+
+module.exports = Message;
+
+},{"./PMChannel.js":3}],8:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Server = (function () {
+ function Server(data, client) {
+ _classCallCheck(this, Server);
+
+ this.client = client;
+ this.region = data.region;
+ this.ownerID = data.owner_id;
+ this.name = data.name;
+ this.id = data.id;
+ this.members = [];
+ this.channels = [];
+ this.icon = data.icon;
+ this.afkTimeout = data.afk_timeout;
+ this.afkChannelId = data.afk_channel_id;
+
+ if (!data.members) {
+ data.members = [client.user];
+ return;
+ }
+
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = data.members[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var member = _step.value;
+
+ // first we cache the user in our Discord Client,
+ // then we add it to our list. This way when we
+ // get a user from this server's member list,
+ // it will be identical (unless an async change occurred)
+ // to the client's cache.
+ if (member.user) this.members.push(client.addUser(member.user));
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator["return"]) {
+ _iterator["return"]();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+ }
+
+ _createClass(Server, [{
+ key: "getChannel",
+
+ // get/set
+ value: function getChannel(key, value) {
+ var _iteratorNormalCompletion2 = true;
+ var _didIteratorError2 = false;
+ var _iteratorError2 = undefined;
+
+ try {
+ for (var _iterator2 = this.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
+ var channel = _step2.value;
+
+ if (channel[key] === value) {
+ return channel;
+ }
+ }
+ } catch (err) {
+ _didIteratorError2 = true;
+ _iteratorError2 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion2 && _iterator2["return"]) {
+ _iterator2["return"]();
+ }
+ } finally {
+ if (_didIteratorError2) {
+ throw _iteratorError2;
+ }
+ }
+ }
+
+ return null;
+ }
+ }, {
+ key: "getMember",
+ value: function getMember(key, value) {
+ var _iteratorNormalCompletion3 = true;
+ var _didIteratorError3 = false;
+ var _iteratorError3 = undefined;
+
+ try {
+ for (var _iterator3 = this.members[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
+ var member = _step3.value;
+
+ if (member[key] === value) {
+ return member;
+ }
+ }
+ } catch (err) {
+ _didIteratorError3 = true;
+ _iteratorError3 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion3 && _iterator3["return"]) {
+ _iterator3["return"]();
+ }
+ } finally {
+ if (_didIteratorError3) {
+ throw _iteratorError3;
+ }
+ }
+ }
+
+ return null;
+ }
+ }, {
+ key: "addChannel",
+ value: function addChannel(chann) {
+ if (!this.getChannel("id", chann.id)) {
+ this.channels.push(chann);
+ }
+ return chann;
+ }
+ }, {
+ key: "addMember",
+ value: function addMember(member) {
+ if (!this.getMember("id", member.id)) {
+ this.members.push(member);
+ }
+ return member;
+ }
+ }, {
+ key: "toString",
+ value: function toString() {
+ return this.name;
+ }
+ }, {
+ key: "equals",
+ value: function equals(object) {
+ return object.id === this.id;
+ }
+ }, {
+ key: "iconURL",
+ get: function get() {
+ if (!this.icon) return null;
+ return "https://discordapp.com/api/guilds/" + this.id + "/icons/" + this.icon + ".jpg";
+ }
+ }, {
+ key: "afkChannel",
+ get: function get() {
+ if (!this.afkChannelId) return false;
+
+ return this.getChannel("id", this.afkChannelId);
+ }
+ }, {
+ key: "defaultChannel",
+ get: function get() {
+ return this.getChannel("name", "general");
+ }
+ }, {
+ key: "owner",
+ get: function get() {
+ return this.client.getUser("id", this.ownerID);
+ }
+ }, {
+ key: "users",
+ get: function get() {
+ return this.members;
+ }
+ }]);
+
+ return Server;
+})();
+
+module.exports = Server;
+
+},{}],9:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var User = (function () {
+ function User(data) {
+ _classCallCheck(this, User);
+
+ this.username = data.username;
+ this.discriminator = data.discriminator;
+ this.id = data.id;
+ this.avatar = data.avatar;
+ this.status = "offline";
+ }
+
+ // access using user.avatarURL;
+
+ _createClass(User, [{
+ key: "mention",
+ value: function mention() {
+ return "<@" + this.id + ">";
+ }
+ }, {
+ key: "toString",
+ value: function toString() {
+ /*
+ if we embed a user in a String - like so:
+ "Yo " + user + " what's up?"
+ It would generate something along the lines of:
+ "Yo @hydrabolt what's up?"
+ */
+ return this.mention();
+ }
+ }, {
+ key: "equals",
+ value: function equals(object) {
+ return object.id === this.id;
+ }
+ }, {
+ key: "equalsStrict",
+ value: function equalsStrict(object) {
+ return object.id === this.id && object.avatar === this.avatar && object.username === this.username && object.discriminator === this.discriminator;
+ }
+ }, {
+ key: "avatarURL",
+ get: function get() {
+ if (!this.avatar) return null;
+ return "https://discordapp.com/api/users/" + this.id + "/avatars/" + this.avatar + ".jpg";
+ }
+ }]);
+
+ return User;
+})();
+
+module.exports = User;
+
+},{}],10:[function(require,module,exports){
+
+},{}],11:[function(require,module,exports){
+/**
+ * Module dependencies.
+ */
+
+var Emitter = require('emitter');
+var reduce = require('reduce');
+
+/**
+ * Root reference for iframes.
+ */
+
+var root = 'undefined' == typeof window
+ ? (this || self)
+ : window;
+
+/**
+ * Noop.
+ */
+
+function noop(){};
+
+/**
+ * Check if `obj` is a host object,
+ * we don't want to serialize these :)
+ *
+ * TODO: future proof, move to compoent land
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api private
+ */
+
+function isHost(obj) {
+ var str = {}.toString.call(obj);
+
+ switch (str) {
+ case '[object File]':
+ case '[object Blob]':
+ case '[object FormData]':
+ return true;
+ default:
+ return false;
+ }
+}
+
+/**
+ * Determine XHR.
+ */
+
+request.getXHR = function () {
+ if (root.XMLHttpRequest
+ && (!root.location || 'file:' != root.location.protocol
+ || !root.ActiveXObject)) {
+ return new XMLHttpRequest;
+ } else {
+ try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
+ }
+ return false;
+};
+
+/**
+ * Removes leading and trailing whitespace, added to support IE.
+ *
+ * @param {String} s
+ * @return {String}
+ * @api private
+ */
+
+var trim = ''.trim
+ ? function(s) { return s.trim(); }
+ : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); };
+
+/**
+ * Check if `obj` is an object.
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api private
+ */
+
+function isObject(obj) {
+ return obj === Object(obj);
+}
+
+/**
+ * Serialize the given `obj`.
+ *
+ * @param {Object} obj
+ * @return {String}
+ * @api private
+ */
+
+function serialize(obj) {
+ if (!isObject(obj)) return obj;
+ var pairs = [];
+ for (var key in obj) {
+ if (null != obj[key]) {
+ pairs.push(encodeURIComponent(key)
+ + '=' + encodeURIComponent(obj[key]));
+ }
+ }
+ return pairs.join('&');
+}
+
+/**
+ * Expose serialization method.
+ */
+
+ request.serializeObject = serialize;
+
+ /**
+ * Parse the given x-www-form-urlencoded `str`.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function parseString(str) {
+ var obj = {};
+ var pairs = str.split('&');
+ var parts;
+ var pair;
+
+ for (var i = 0, len = pairs.length; i < len; ++i) {
+ pair = pairs[i];
+ parts = pair.split('=');
+ obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
+ }
+
+ return obj;
+}
+
+/**
+ * Expose parser.
+ */
+
+request.parseString = parseString;
+
+/**
+ * Default MIME type map.
+ *
+ * superagent.types.xml = 'application/xml';
+ *
+ */
+
+request.types = {
+ html: 'text/html',
+ json: 'application/json',
+ xml: 'application/xml',
+ urlencoded: 'application/x-www-form-urlencoded',
+ 'form': 'application/x-www-form-urlencoded',
+ 'form-data': 'application/x-www-form-urlencoded'
+};
+
+/**
+ * Default serialization map.
+ *
+ * superagent.serialize['application/xml'] = function(obj){
+ * return 'generated xml here';
+ * };
+ *
+ */
+
+ request.serialize = {
+ 'application/x-www-form-urlencoded': serialize,
+ 'application/json': JSON.stringify
+ };
+
+ /**
+ * Default parsers.
+ *
+ * superagent.parse['application/xml'] = function(str){
+ * return { object parsed from str };
+ * };
+ *
+ */
+
+request.parse = {
+ 'application/x-www-form-urlencoded': parseString,
+ 'application/json': JSON.parse
+};
+
+/**
+ * Parse the given header `str` into
+ * an object containing the mapped fields.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function parseHeader(str) {
+ var lines = str.split(/\r?\n/);
+ var fields = {};
+ var index;
+ var line;
+ var field;
+ var val;
+
+ lines.pop(); // trailing CRLF
+
+ for (var i = 0, len = lines.length; i < len; ++i) {
+ line = lines[i];
+ index = line.indexOf(':');
+ field = line.slice(0, index).toLowerCase();
+ val = trim(line.slice(index + 1));
+ fields[field] = val;
+ }
+
+ return fields;
+}
+
+/**
+ * Return the mime type for the given `str`.
+ *
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+function type(str){
+ return str.split(/ *; */).shift();
+};
+
+/**
+ * Return header field parameters.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function params(str){
+ return reduce(str.split(/ *; */), function(obj, str){
+ var parts = str.split(/ *= */)
+ , key = parts.shift()
+ , val = parts.shift();
+
+ if (key && val) obj[key] = val;
+ return obj;
+ }, {});
+};
+
+/**
+ * Initialize a new `Response` with the given `xhr`.
+ *
+ * - set flags (.ok, .error, etc)
+ * - parse header
+ *
+ * Examples:
+ *
+ * Aliasing `superagent` as `request` is nice:
+ *
+ * request = superagent;
+ *
+ * We can use the promise-like API, or pass callbacks:
+ *
+ * request.get('/').end(function(res){});
+ * request.get('/', function(res){});
+ *
+ * Sending data can be chained:
+ *
+ * request
+ * .post('/user')
+ * .send({ name: 'tj' })
+ * .end(function(res){});
+ *
+ * Or passed to `.send()`:
+ *
+ * request
+ * .post('/user')
+ * .send({ name: 'tj' }, function(res){});
+ *
+ * Or passed to `.post()`:
+ *
+ * request
+ * .post('/user', { name: 'tj' })
+ * .end(function(res){});
+ *
+ * Or further reduced to a single call for simple cases:
+ *
+ * request
+ * .post('/user', { name: 'tj' }, function(res){});
+ *
+ * @param {XMLHTTPRequest} xhr
+ * @param {Object} options
+ * @api private
+ */
+
+function Response(req, options) {
+ options = options || {};
+ this.req = req;
+ this.xhr = this.req.xhr;
+ // responseText is accessible only if responseType is '' or 'text' and on older browsers
+ this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined')
+ ? this.xhr.responseText
+ : null;
+ this.statusText = this.req.xhr.statusText;
+ this.setStatusProperties(this.xhr.status);
+ this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders());
+ // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but
+ // getResponseHeader still works. so we get content-type even if getting
+ // other headers fails.
+ this.header['content-type'] = this.xhr.getResponseHeader('content-type');
+ this.setHeaderProperties(this.header);
+ this.body = this.req.method != 'HEAD'
+ ? this.parseBody(this.text ? this.text : this.xhr.response)
+ : null;
+}
+
+/**
+ * Get case-insensitive `field` value.
+ *
+ * @param {String} field
+ * @return {String}
+ * @api public
+ */
+
+Response.prototype.get = function(field){
+ return this.header[field.toLowerCase()];
+};
+
+/**
+ * Set header related properties:
+ *
+ * - `.type` the content type without params
+ *
+ * A response of "Content-Type: text/plain; charset=utf-8"
+ * will provide you with a `.type` of "text/plain".
+ *
+ * @param {Object} header
+ * @api private
+ */
+
+Response.prototype.setHeaderProperties = function(header){
+ // content-type
+ var ct = this.header['content-type'] || '';
+ this.type = type(ct);
+
+ // params
+ var obj = params(ct);
+ for (var key in obj) this[key] = obj[key];
+};
+
+/**
+ * Parse the given body `str`.
+ *
+ * Used for auto-parsing of bodies. Parsers
+ * are defined on the `superagent.parse` object.
+ *
+ * @param {String} str
+ * @return {Mixed}
+ * @api private
+ */
+
+Response.prototype.parseBody = function(str){
+ var parse = request.parse[this.type];
+ return parse && str && (str.length || str instanceof Object)
+ ? parse(str)
+ : null;
+};
+
+/**
+ * Set flags such as `.ok` based on `status`.
+ *
+ * For example a 2xx response will give you a `.ok` of __true__
+ * whereas 5xx will be __false__ and `.error` will be __true__. The
+ * `.clientError` and `.serverError` are also available to be more
+ * specific, and `.statusType` is the class of error ranging from 1..5
+ * sometimes useful for mapping respond colors etc.
+ *
+ * "sugar" properties are also defined for common cases. Currently providing:
+ *
+ * - .noContent
+ * - .badRequest
+ * - .unauthorized
+ * - .notAcceptable
+ * - .notFound
+ *
+ * @param {Number} status
+ * @api private
+ */
+
+Response.prototype.setStatusProperties = function(status){
+ // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
+ if (status === 1223) {
+ status = 204;
+ }
+
+ var type = status / 100 | 0;
+
+ // status / class
+ this.status = status;
+ this.statusType = type;
+
+ // basics
+ this.info = 1 == type;
+ this.ok = 2 == type;
+ this.clientError = 4 == type;
+ this.serverError = 5 == type;
+ this.error = (4 == type || 5 == type)
+ ? this.toError()
+ : false;
+
+ // sugar
+ this.accepted = 202 == status;
+ this.noContent = 204 == status;
+ this.badRequest = 400 == status;
+ this.unauthorized = 401 == status;
+ this.notAcceptable = 406 == status;
+ this.notFound = 404 == status;
+ this.forbidden = 403 == status;
+};
+
+/**
+ * Return an `Error` representative of this response.
+ *
+ * @return {Error}
+ * @api public
+ */
+
+Response.prototype.toError = function(){
+ var req = this.req;
+ var method = req.method;
+ var url = req.url;
+
+ var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')';
+ var err = new Error(msg);
+ err.status = this.status;
+ err.method = method;
+ err.url = url;
+
+ return err;
+};
+
+/**
+ * Expose `Response`.
+ */
+
+request.Response = Response;
+
+/**
+ * Initialize a new `Request` with the given `method` and `url`.
+ *
+ * @param {String} method
+ * @param {String} url
+ * @api public
+ */
+
+function Request(method, url) {
+ var self = this;
+ Emitter.call(this);
+ this._query = this._query || [];
+ this.method = method;
+ this.url = url;
+ this.header = {};
+ this._header = {};
+ this.on('end', function(){
+ var err = null;
+ var res = null;
+
+ try {
+ res = new Response(self);
+ } catch(e) {
+ err = new Error('Parser is unable to parse the response');
+ err.parse = true;
+ err.original = e;
+ return self.callback(err);
+ }
+
+ self.emit('response', res);
+
+ if (err) {
+ return self.callback(err, res);
+ }
+
+ if (res.status >= 200 && res.status < 300) {
+ return self.callback(err, res);
+ }
+
+ var new_err = new Error(res.statusText || 'Unsuccessful HTTP response');
+ new_err.original = err;
+ new_err.response = res;
+ new_err.status = res.status;
+
+ self.callback(new_err, res);
+ });
+}
+
+/**
+ * Mixin `Emitter`.
+ */
+
+Emitter(Request.prototype);
+
+/**
+ * Allow for extension
+ */
+
+Request.prototype.use = function(fn) {
+ fn(this);
+ return this;
+}
+
+/**
+ * Set timeout to `ms`.
+ *
+ * @param {Number} ms
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.timeout = function(ms){
+ this._timeout = ms;
+ return this;
+};
+
+/**
+ * Clear previous timeout.
+ *
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.clearTimeout = function(){
+ this._timeout = 0;
+ clearTimeout(this._timer);
+ return this;
+};
+
+/**
+ * Abort the request, and clear potential timeout.
+ *
+ * @return {Request}
+ * @api public
+ */
+
+Request.prototype.abort = function(){
+ if (this.aborted) return;
+ this.aborted = true;
+ this.xhr.abort();
+ this.clearTimeout();
+ this.emit('abort');
+ return this;
+};
+
+/**
+ * Set header `field` to `val`, or multiple fields with one object.
+ *
+ * Examples:
+ *
+ * req.get('/')
+ * .set('Accept', 'application/json')
+ * .set('X-API-Key', 'foobar')
+ * .end(callback);
+ *
+ * req.get('/')
+ * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
+ * .end(callback);
+ *
+ * @param {String|Object} field
+ * @param {String} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.set = function(field, val){
+ if (isObject(field)) {
+ for (var key in field) {
+ this.set(key, field[key]);
+ }
+ return this;
+ }
+ this._header[field.toLowerCase()] = val;
+ this.header[field] = val;
+ return this;
+};
+
+/**
+ * Remove header `field`.
+ *
+ * Example:
+ *
+ * req.get('/')
+ * .unset('User-Agent')
+ * .end(callback);
+ *
+ * @param {String} field
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.unset = function(field){
+ delete this._header[field.toLowerCase()];
+ delete this.header[field];
+ return this;
+};
+
+/**
+ * Get case-insensitive header `field` value.
+ *
+ * @param {String} field
+ * @return {String}
+ * @api private
+ */
+
+Request.prototype.getHeader = function(field){
+ return this._header[field.toLowerCase()];
+};
+
+/**
+ * Set Content-Type to `type`, mapping values from `request.types`.
+ *
+ * Examples:
+ *
+ * superagent.types.xml = 'application/xml';
+ *
+ * request.post('/')
+ * .type('xml')
+ * .send(xmlstring)
+ * .end(callback);
+ *
+ * request.post('/')
+ * .type('application/xml')
+ * .send(xmlstring)
+ * .end(callback);
+ *
+ * @param {String} type
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.type = function(type){
+ this.set('Content-Type', request.types[type] || type);
+ return this;
+};
+
+/**
+ * Set Accept to `type`, mapping values from `request.types`.
+ *
+ * Examples:
+ *
+ * superagent.types.json = 'application/json';
+ *
+ * request.get('/agent')
+ * .accept('json')
+ * .end(callback);
+ *
+ * request.get('/agent')
+ * .accept('application/json')
+ * .end(callback);
+ *
+ * @param {String} accept
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.accept = function(type){
+ this.set('Accept', request.types[type] || type);
+ return this;
+};
+
+/**
+ * Set Authorization field value with `user` and `pass`.
+ *
+ * @param {String} user
+ * @param {String} pass
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.auth = function(user, pass){
+ var str = btoa(user + ':' + pass);
+ this.set('Authorization', 'Basic ' + str);
+ return this;
+};
+
+/**
+* Add query-string `val`.
+*
+* Examples:
+*
+* request.get('/shoes')
+* .query('size=10')
+* .query({ color: 'blue' })
+*
+* @param {Object|String} val
+* @return {Request} for chaining
+* @api public
+*/
+
+Request.prototype.query = function(val){
+ if ('string' != typeof val) val = serialize(val);
+ if (val) this._query.push(val);
+ return this;
+};
+
+/**
+ * Write the field `name` and `val` for "multipart/form-data"
+ * request bodies.
+ *
+ * ``` js
+ * request.post('/upload')
+ * .field('foo', 'bar')
+ * .end(callback);
+ * ```
+ *
+ * @param {String} name
+ * @param {String|Blob|File} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.field = function(name, val){
+ if (!this._formData) this._formData = new root.FormData();
+ this._formData.append(name, val);
+ return this;
+};
+
+/**
+ * Queue the given `file` as an attachment to the specified `field`,
+ * with optional `filename`.
+ *
+ * ``` js
+ * request.post('/upload')
+ * .attach(new Blob(['hey!'], { type: "text/html"}))
+ * .end(callback);
+ * ```
+ *
+ * @param {String} field
+ * @param {Blob|File} file
+ * @param {String} filename
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.attach = function(field, file, filename){
+ if (!this._formData) this._formData = new root.FormData();
+ this._formData.append(field, file, filename);
+ return this;
+};
+
+/**
+ * Send `data`, defaulting the `.type()` to "json" when
+ * an object is given.
+ *
+ * Examples:
+ *
+ * // querystring
+ * request.get('/search')
+ * .end(callback)
+ *
+ * // multiple data "writes"
+ * request.get('/search')
+ * .send({ search: 'query' })
+ * .send({ range: '1..5' })
+ * .send({ order: 'desc' })
+ * .end(callback)
+ *
+ * // manual json
+ * request.post('/user')
+ * .type('json')
+ * .send('{"name":"tj"})
+ * .end(callback)
+ *
+ * // auto json
+ * request.post('/user')
+ * .send({ name: 'tj' })
+ * .end(callback)
+ *
+ * // manual x-www-form-urlencoded
+ * request.post('/user')
+ * .type('form')
+ * .send('name=tj')
+ * .end(callback)
+ *
+ * // auto x-www-form-urlencoded
+ * request.post('/user')
+ * .type('form')
+ * .send({ name: 'tj' })
+ * .end(callback)
+ *
+ * // defaults to x-www-form-urlencoded
+ * request.post('/user')
+ * .send('name=tobi')
+ * .send('species=ferret')
+ * .end(callback)
+ *
+ * @param {String|Object} data
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.send = function(data){
+ var obj = isObject(data);
+ var type = this.getHeader('Content-Type');
+
+ // merge
+ if (obj && isObject(this._data)) {
+ for (var key in data) {
+ this._data[key] = data[key];
+ }
+ } else if ('string' == typeof data) {
+ if (!type) this.type('form');
+ type = this.getHeader('Content-Type');
+ if ('application/x-www-form-urlencoded' == type) {
+ this._data = this._data
+ ? this._data + '&' + data
+ : data;
+ } else {
+ this._data = (this._data || '') + data;
+ }
+ } else {
+ this._data = data;
+ }
+
+ if (!obj || isHost(data)) return this;
+ if (!type) this.type('json');
+ return this;
+};
+
+/**
+ * Invoke the callback with `err` and `res`
+ * and handle arity check.
+ *
+ * @param {Error} err
+ * @param {Response} res
+ * @api private
+ */
+
+Request.prototype.callback = function(err, res){
+ var fn = this._callback;
+ this.clearTimeout();
+ fn(err, res);
+};
+
+/**
+ * Invoke callback with x-domain error.
+ *
+ * @api private
+ */
+
+Request.prototype.crossDomainError = function(){
+ var err = new Error('Origin is not allowed by Access-Control-Allow-Origin');
+ err.crossDomain = true;
+ this.callback(err);
+};
+
+/**
+ * Invoke callback with timeout error.
+ *
+ * @api private
+ */
+
+Request.prototype.timeoutError = function(){
+ var timeout = this._timeout;
+ var err = new Error('timeout of ' + timeout + 'ms exceeded');
+ err.timeout = timeout;
+ this.callback(err);
+};
+
+/**
+ * Enable transmission of cookies with x-domain requests.
+ *
+ * Note that for this to work the origin must not be
+ * using "Access-Control-Allow-Origin" with a wildcard,
+ * and also must set "Access-Control-Allow-Credentials"
+ * to "true".
+ *
+ * @api public
+ */
+
+Request.prototype.withCredentials = function(){
+ this._withCredentials = true;
+ return this;
+};
+
+/**
+ * Initiate request, invoking callback `fn(res)`
+ * with an instanceof `Response`.
+ *
+ * @param {Function} fn
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.end = function(fn){
+ var self = this;
+ var xhr = this.xhr = request.getXHR();
+ var query = this._query.join('&');
+ var timeout = this._timeout;
+ var data = this._formData || this._data;
+
+ // store callback
+ this._callback = fn || noop;
+
+ // state change
+ xhr.onreadystatechange = function(){
+ if (4 != xhr.readyState) return;
+
+ // In IE9, reads to any property (e.g. status) off of an aborted XHR will
+ // result in the error "Could not complete the operation due to error c00c023f"
+ var status;
+ try { status = xhr.status } catch(e) { status = 0; }
+
+ if (0 == status) {
+ if (self.timedout) return self.timeoutError();
+ if (self.aborted) return;
+ return self.crossDomainError();
+ }
+ self.emit('end');
+ };
+
+ // progress
+ var handleProgress = function(e){
+ if (e.total > 0) {
+ e.percent = e.loaded / e.total * 100;
+ }
+ self.emit('progress', e);
+ };
+ if (this.hasListeners('progress')) {
+ xhr.onprogress = handleProgress;
+ }
+ try {
+ if (xhr.upload && this.hasListeners('progress')) {
+ xhr.upload.onprogress = handleProgress;
+ }
+ } catch(e) {
+ // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist.
+ // Reported here:
+ // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context
+ }
+
+ // timeout
+ if (timeout && !this._timer) {
+ this._timer = setTimeout(function(){
+ self.timedout = true;
+ self.abort();
+ }, timeout);
+ }
+
+ // querystring
+ if (query) {
+ query = request.serializeObject(query);
+ this.url += ~this.url.indexOf('?')
+ ? '&' + query
+ : '?' + query;
+ }
+
+ // initiate request
+ xhr.open(this.method, this.url, true);
+
+ // CORS
+ if (this._withCredentials) xhr.withCredentials = true;
+
+ // body
+ if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) {
+ // serialize stuff
+ var contentType = this.getHeader('Content-Type');
+ var serialize = request.serialize[contentType ? contentType.split(';')[0] : ''];
+ if (serialize) data = serialize(data);
+ }
+
+ // set header fields
+ for (var field in this.header) {
+ if (null == this.header[field]) continue;
+ xhr.setRequestHeader(field, this.header[field]);
+ }
+
+ // send stuff
+ this.emit('request', this);
+ xhr.send(data);
+ return this;
+};
+
+/**
+ * Faux promise support
+ *
+ * @param {Function} fulfill
+ * @param {Function} reject
+ * @return {Request}
+ */
+
+Request.prototype.then = function (fulfill, reject) {
+ return this.end(function(err, res) {
+ err ? reject(err) : fulfill(res);
+ });
+}
+
+/**
+ * Expose `Request`.
+ */
+
+request.Request = Request;
+
+/**
+ * Issue a request:
+ *
+ * Examples:
+ *
+ * request('GET', '/users').end(callback)
+ * request('/users').end(callback)
+ * request('/users', callback)
+ *
+ * @param {String} method
+ * @param {String|Function} url or callback
+ * @return {Request}
+ * @api public
+ */
+
+function request(method, url) {
+ // callback
+ if ('function' == typeof url) {
+ return new Request('GET', method).end(url);
+ }
+
+ // url first
+ if (1 == arguments.length) {
+ return new Request('GET', method);
+ }
+
+ return new Request(method, url);
+}
+
+/**
+ * GET `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.get = function(url, data, fn){
+ var req = request('GET', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.query(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * HEAD `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.head = function(url, data, fn){
+ var req = request('HEAD', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * DELETE `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.del = function(url, fn){
+ var req = request('DELETE', url);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * PATCH `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} data
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.patch = function(url, data, fn){
+ var req = request('PATCH', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * POST `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} data
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.post = function(url, data, fn){
+ var req = request('POST', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * PUT `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.put = function(url, data, fn){
+ var req = request('PUT', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * Expose `request`.
+ */
+
+module.exports = request;
+
+},{"emitter":12,"reduce":13}],12:[function(require,module,exports){
+
+/**
+ * Expose `Emitter`.
+ */
+
+module.exports = Emitter;
+
+/**
+ * Initialize a new `Emitter`.
+ *
+ * @api public
+ */
+
+function Emitter(obj) {
+ if (obj) return mixin(obj);
+};
+
+/**
+ * Mixin the emitter properties.
+ *
+ * @param {Object} obj
+ * @return {Object}
+ * @api private
+ */
+
+function mixin(obj) {
+ for (var key in Emitter.prototype) {
+ obj[key] = Emitter.prototype[key];
+ }
+ return obj;
+}
+
+/**
+ * Listen on the given `event` with `fn`.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.on =
+Emitter.prototype.addEventListener = function(event, fn){
+ this._callbacks = this._callbacks || {};
+ (this._callbacks[event] = this._callbacks[event] || [])
+ .push(fn);
+ return this;
+};
+
+/**
+ * Adds an `event` listener that will be invoked a single
+ * time then automatically removed.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.once = function(event, fn){
+ var self = this;
+ this._callbacks = this._callbacks || {};
+
+ function on() {
+ self.off(event, on);
+ fn.apply(this, arguments);
+ }
+
+ on.fn = fn;
+ this.on(event, on);
+ return this;
+};
+
+/**
+ * Remove the given callback for `event` or all
+ * registered callbacks.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.off =
+Emitter.prototype.removeListener =
+Emitter.prototype.removeAllListeners =
+Emitter.prototype.removeEventListener = function(event, fn){
+ this._callbacks = this._callbacks || {};
+
+ // all
+ if (0 == arguments.length) {
+ this._callbacks = {};
+ return this;
+ }
+
+ // specific event
+ var callbacks = this._callbacks[event];
+ if (!callbacks) return this;
+
+ // remove all handlers
+ if (1 == arguments.length) {
+ delete this._callbacks[event];
+ return this;
+ }
+
+ // remove specific handler
+ var cb;
+ for (var i = 0; i < callbacks.length; i++) {
+ cb = callbacks[i];
+ if (cb === fn || cb.fn === fn) {
+ callbacks.splice(i, 1);
+ break;
+ }
+ }
+ return this;
+};
+
+/**
+ * Emit `event` with the given args.
+ *
+ * @param {String} event
+ * @param {Mixed} ...
+ * @return {Emitter}
+ */
+
+Emitter.prototype.emit = function(event){
+ this._callbacks = this._callbacks || {};
+ var args = [].slice.call(arguments, 1)
+ , callbacks = this._callbacks[event];
+
+ if (callbacks) {
+ callbacks = callbacks.slice(0);
+ for (var i = 0, len = callbacks.length; i < len; ++i) {
+ callbacks[i].apply(this, args);
+ }
+ }
+
+ return this;
+};
+
+/**
+ * Return array of callbacks for `event`.
+ *
+ * @param {String} event
+ * @return {Array}
+ * @api public
+ */
+
+Emitter.prototype.listeners = function(event){
+ this._callbacks = this._callbacks || {};
+ return this._callbacks[event] || [];
+};
+
+/**
+ * Check if this emitter has `event` handlers.
+ *
+ * @param {String} event
+ * @return {Boolean}
+ * @api public
+ */
+
+Emitter.prototype.hasListeners = function(event){
+ return !! this.listeners(event).length;
+};
+
+},{}],13:[function(require,module,exports){
+
+/**
+ * Reduce `arr` with `fn`.
+ *
+ * @param {Array} arr
+ * @param {Function} fn
+ * @param {Mixed} initial
+ *
+ * TODO: combatible error handling?
+ */
+
+module.exports = function(arr, fn, initial){
+ var idx = 0;
+ var len = arr.length;
+ var curr = arguments.length == 3
+ ? initial
+ : arr[idx++];
+
+ while (idx < len) {
+ curr = fn.call(null, curr, arr[idx], ++idx, arr);
+ }
+
+ return curr;
+};
+},{}],14:[function(require,module,exports){
+
+/**
+ * Module dependencies.
+ */
+
+var global = (function() { return this; })();
+
+/**
+ * WebSocket constructor.
+ */
+
+var WebSocket = global.WebSocket || global.MozWebSocket;
+
+/**
+ * Module exports.
+ */
+
+module.exports = WebSocket ? ws : null;
+
+/**
+ * WebSocket constructor.
+ *
+ * The third `opts` options object gets ignored in web browsers, since it's
+ * non-standard, and throws a TypeError if passed to the constructor.
+ * See: https://github.com/einaros/ws/issues/227
+ *
+ * @param {String} uri
+ * @param {Array} protocols (optional)
+ * @param {Object) opts (optional)
+ * @api public
+ */
+
+function ws(uri, protocols, opts) {
+ var instance;
+ if (protocols) {
+ instance = new WebSocket(uri, protocols);
+ } else {
+ instance = new WebSocket(uri);
+ }
+ return instance;
+}
+
+if (WebSocket) ws.prototype = WebSocket.prototype;
+
+},{}],15:[function(require,module,exports){
+module.exports=[{"executables":{"win32":["pol.exe"]},"id":0,"name":"FINAL FANTASY XI"},{"executables":{"win32":["ffxiv.exe","ffxiv_dx11.exe"]},"id":1,"name":"FINAL FANTASY XIV"},{"executables":{"win32":["Wow.exe","Wow-64.exe"]},"id":3,"name":"World of Warcraft"},{"executables":{"darwin":["LoLLauncher.app"],"win32":["LolClient.exe","League of Legends.exe"]},"id":4,"name":"League of Legends"},{"executables":{"darwin":["Diablo%20III.app"],"win32":["Diablo III.exe"]},"id":5,"name":"Diablo 3"},{"executables":{"darwin":["dota_osx.app"],"win32":["dota2.exe"]},"id":6,"name":"DOTA 2"},{"executables":{"darwin":["Heroes.app"],"win32":["Heroes of the Storm.exe","HeroesOfTheStorm_x64.exe","HeroesOfTheStorm.exe"]},"id":7,"name":"Heroes of the Storm"},{"executables":{"darwin":["Hearthstone.app"],"win32":["Hearthstone.exe"]},"id":8,"name":"Hearthstone"},{"executables":{"win32":["csgo.exe"]},"id":9,"name":"Counter-Strike: Global Offensive"},{"executables":{"win32":["WorldOfTanks.exe"]},"id":10,"name":"World of Tanks"},{"executables":{"darwin":["gw2.app"],"win32":["gw2.exe"]},"id":11,"name":"Guild Wars 2"},{"executables":{"win32":["dayz.exe"]},"id":12,"name":"Day Z"},{"executables":{"darwin":["starcraft%20ii.app"],"win32":["starcraft ii.exe","SC2_x64.exe","SC2.exe"]},"id":13,"name":"Starcraft II"},{"executables":{"win32":["diablo.exe"]},"id":14,"name":"Diablo"},{"executables":{"win32":["diablo ii.exe"]},"id":15,"name":"Diablo 2"},{"executables":{"win32":["left4dead.exe"]},"id":17,"name":"Left 4 Dead"},{"executables":{"darwin":["minecraft.app"],"win32":["minecraft.exe"]},"id":18,"name":"Minecraft"},{"executables":{"win32":["smite.exe"]},"id":19,"name":"Smite"},{"executables":{"win32":["bf4.exe"]},"id":20,"name":"Battlefield 4"},{"executables":{"win32":["AoK HD.exe","empires2.exe"]},"id":101,"name":"Age of Empire II"},{"executables":{"win32":["age3y.exe"]},"id":102,"name":"Age of Empire III"},{"executables":{"win32":["AlanWake.exe"]},"id":104,"name":"Alan Wake"},{"executables":{"win32":["alan_wakes_american_nightmare.exe"]},"id":105,"name":"Alan Wake's American Nightmare"},{"executables":{"win32":["AlienBreed2Assault.exe"]},"id":106,"name":"Alien Breed 2: Assault"},{"executables":{"win32":["Amnesia.exe"]},"id":107,"name":"Amnesia: The Dark Descent"},{"executables":{"win32":["UDK.exe"]},"id":108,"name":"Antichamber"},{"executables":{"win32":["ArcheAge.exe"]},"id":109,"name":"ArcheAge"},{"executables":{"win32":["arma3.exe"]},"id":110,"name":"Arma III"},{"executables":{"win32":["AC3SP.exe"]},"id":111,"name":"Assassin's Creed 3"},{"executables":{"win32":["Bastion.exe"]},"id":112,"name":"Bastion"},{"executables":{"win32":["BF2.exe"]},"id":113,"name":"Battlefield 2"},{"executables":{"win32":["bf3.exe"]},"id":114,"name":"Battlefield 3"},{"executables":{"win32":["Besiege.exe"]},"id":116,"name":"Besiege"},{"executables":{"win32":["Bioshock.exe"]},"id":117,"name":"Bioshock"},{"executables":{"win32":["Bioshock2.exe"]},"id":118,"name":"BioShock II"},{"executables":{"win32":["BioShockInfinite.exe"]},"id":119,"name":"BioShock Infinite"},{"executables":{"win32":["Borderlands2.exe"]},"id":122,"name":"Borderlands 2"},{"executables":{"win32":["braid.exe"]},"id":123,"name":"Braid"},{"executables":{"win32":["ShippingPC-StormGame.exe"]},"id":124,"name":"Bulletstorm"},{"executables":{},"id":125,"name":"Cabal 2"},{"executables":{"win32":["CabalMain.exe"]},"id":126,"name":"Cabal Online"},{"executables":{"win32":["iw4mp.exe","iw4sp.exe"]},"id":127,"name":"Call of Duty: Modern Warfare 2"},{"executables":{"win32":["t6sp.exe"]},"id":128,"name":"Call of Duty: Black Ops"},{"executables":{"win32":["iw5mp.exe"]},"id":129,"name":"Call of Duty: Modern Warfare 3"},{"executables":{"win32":["RelicCOH.exe"]},"id":132,"name":"Company of Heroes"},{"executables":{"win32":["Crysis64.exe"]},"id":135,"name":"Crysis"},{"executables":{"win32":["Crysis2.exe"]},"id":136,"name":"Crysis 2"},{"executables":{"win32":["Crysis3.exe"]},"id":137,"name":"Crysis 3"},{"executables":{"win32":["Crysis.exe"]},"id":138,"name":"Crysis 4 "},{"executables":{"win32":["DATA.exe"]},"id":140,"name":"Dark Souls"},{"executables":{"win32":["DarkSoulsII.exe"]},"id":141,"name":"Dark Souls II"},{"executables":{"win32":["dfuw.exe"]},"id":142,"name":"Darkfall: Unholy Wars"},{"executables":{"win32":["DCGAME.exe"]},"id":144,"name":"DC Universe Online"},{"executables":{"win32":["DeadIslandGame.exe"]},"id":145,"name":"Dead Island"},{"executables":{"win32":["deadspace2.exe"]},"id":146,"name":"Dead Space 2"},{"executables":{"win32":["LOTDGame.exe"]},"id":147,"name":"Deadlight"},{"executables":{"win32":["dxhr.exe"]},"id":148,"name":"Deus Ex: Human Revolution"},{"executables":{"win32":["DeviMayCry4.exe"]},"id":149,"name":"Devil May Cry 4"},{"executables":{"win32":["DMC-DevilMayCry.exe"]},"id":150,"name":"DmC Devil May Cry"},{"executables":{"win32":["dirt2_game.exe"]},"id":154,"name":"DiRT 2"},{"executables":{"win32":["dirt3_game.exe"]},"id":155,"name":"DiRT 3"},{"executables":{"win32":["dota.exe"]},"id":156,"name":"DOTA"},{"executables":{"win32":["DoubleDragon.exe"]},"id":158,"name":"Double Dragon Neon"},{"executables":{"win32":["DragonAge2.exe"]},"id":159,"name":"Dragon Age II"},{"executables":{"win32":["DragonAgeInquisition.exe"]},"id":160,"name":"Dragon Age: Inquisition"},{"executables":{"win32":["daorigins.exe"]},"id":161,"name":"Dragon Age: Origins"},{"executables":{"win32":["DBXV.exe"]},"id":162,"name":"Dragon Ball XenoVerse"},{"executables":{"win32":["DukeForever.exe"]},"id":163,"name":"Duke Nukem Forever"},{"executables":{"darwin":["Dustforce.app"],"win32":["dustforce.exe"]},"id":164,"name":"Dustforce"},{"executables":{"win32":["EliteDangerous32.exe"]},"id":165,"name":"Elite: Dangerous"},{"executables":{"win32":["exefile.exe"]},"id":166,"name":"Eve Online"},{"executables":{"win32":["eqgame.exe"]},"id":167,"name":"EverQuest"},{"executables":{"win32":["EverQuest2.exe"]},"id":168,"name":"EverQuest II"},{"executables":{},"id":169,"name":"EverQuest Next"},{"executables":{"win32":["Engine.exe"]},"id":170,"name":"F.E.A.R."},{"executables":{"win32":["FEAR2.exe"]},"id":171,"name":"F.E.A.R. 2: Project Origin"},{"executables":{"win32":["fallout3.exe"]},"id":172,"name":"Fallout 3"},{"executables":{"win32":["FalloutNV.exe"]},"id":174,"name":"Fallout: New Vegas"},{"executables":{"win32":["farcry3.exe"]},"id":175,"name":"Far Cry 3"},{"executables":{"win32":["fifa15.exe"]},"id":176,"name":"FIFA 15"},{"executables":{"win32":["FTLGame.exe"]},"id":180,"name":"FTL: Faster Than Light"},{"executables":{"win32":["GTAIV.exe"]},"id":181,"name":"Grand Theft Auto 4"},{"executables":{"win32":["GTA5.exe"]},"id":182,"name":"Grand Theft Auto 5"},{"executables":{"win32":["Gw.exe"]},"id":183,"name":"Guild Wars"},{"executables":{"win32":["H1Z1.exe"]},"id":186,"name":"H1Z1"},{"executables":{"win32":["HL2HL2.exe","hl2.exe"]},"id":188,"name":"Half Life 2"},{"executables":{"win32":["HOMEFRONT.exe"]},"id":195,"name":"Homefront"},{"executables":{"win32":["invisibleinc.exe"]},"id":196,"name":"Invisible Inc."},{"executables":{"win32":["LANoire.exe"]},"id":197,"name":"L.A. Noire"},{"executables":{"win32":["Landmark64.exe"]},"id":198,"name":"Landmark"},{"executables":{"win32":["left4dead2.exe"]},"id":201,"name":"Left 4 Dead 2"},{"executables":{"win32":["lineage.exe"]},"id":203,"name":"Lineage"},{"executables":{"win32":["Magicka.exe"]},"id":206,"name":"Magicka"},{"executables":{"win32":["MapleStory.exe"]},"id":208,"name":"MapleStory"},{"executables":{},"id":209,"name":"Mark of the Ninja"},{"executables":{"win32":["MassEffect.exe"]},"id":210,"name":"Mass Effect"},{"executables":{"win32":["MassEffect2.exe"]},"id":211,"name":"Mass Effect 2"},{"executables":{"win32":["MassEffect3Demo.exe"]},"id":212,"name":"Mass Effect 3"},{"executables":{"win32":["METAL GEAR RISING REVENGEANCE.exe"]},"id":214,"name":"Metal Gear Rising: Revengeance"},{"executables":{"win32":["metro2033.exe"]},"id":215,"name":"Metro 2033"},{"executables":{"win32":["MetroLL.exe"]},"id":216,"name":"Metro Last Light"},{"executables":{"win32":["MK10.exe"]},"id":218,"name":"Mortal Kombat X"},{"executables":{"win32":["speed.exe"]},"id":219,"name":"Need For Speed Most Wanted"},{"executables":{},"id":220,"name":"Neverwinder"},{"executables":{"darwin":["Outlast.app"],"win32":["OLGame.exe"]},"id":221,"name":"Outlast"},{"executables":{"win32":["PapersPlease.exe"]},"id":222,"name":"Papers, Please"},{"executables":{"win32":["payday_win32_release.exe"]},"id":223,"name":"PAYDAY"},{"executables":{"win32":["payday2_win32_release.exe"]},"id":224,"name":"PAYDAY2"},{"executables":{"win32":["PillarsOfEternity.exe"]},"id":225,"name":"Pillars of Eternity"},{"executables":{"win32":["PA.exe"]},"id":226,"name":"Planetary Annihilation"},{"executables":{"win32":["planetside2_x86.exe"]},"id":227,"name":"Planetside 2"},{"executables":{"win32":["hl2P.exe"]},"id":228,"name":"Portal"},{"executables":{"win32":["portal2.exe"]},"id":229,"name":"Portal 2"},{"executables":{"win32":["PrimalCarnageGame.exe"]},"id":231,"name":"Primal Cargnage"},{"executables":{"win32":["pCARS.exe"]},"id":232,"name":"Project Cars"},{"executables":{"win32":["RaceTheSun.exe"]},"id":233,"name":"Race The Sun"},{"executables":{"win32":["Rage.exe"]},"id":234,"name":"RAGE"},{"executables":{"win32":["ragexe.exe"]},"id":235,"name":"Ragnarok Online"},{"executables":{"win32":["rift.exe"]},"id":236,"name":"Rift"},{"executables":{"win32":["Rocksmith2014.exe"]},"id":237,"name":"Rocksmith 2014"},{"executables":{"win32":["SwiftKit-RS.exe","JagexLauncher.exe"]},"id":238,"name":"RuneScape"},{"executables":{"win32":["Shadowgrounds.exe"]},"id":239,"name":"Shadowgrounds"},{"executables":{"win32":["survivor.exe"]},"id":240,"name":"Shadowgrounds: Survivor"},{"executables":{"win32":["ShovelKnight.exe"]},"id":241,"name":"Shovel Knight"},{"executables":{"win32":["SimCity.exe"]},"id":242,"name":"SimCity"},{"executables":{"win32":["SporeApp.exe"]},"id":245,"name":"Spore"},{"executables":{"win32":["StarCitizen.exe"]},"id":246,"name":"Star Citizen"},{"executables":{},"id":247,"name":"Star Trek Online"},{"executables":{"win32":["battlefront.exe"]},"id":248,"name":"Star Wars Battlefront"},{"executables":{"win32":["swtor.exe"]},"id":249,"name":"Star Wars: The Old Republic"},{"executables":{"win32":["starbound.exe","starbound_opengl.exe"]},"id":250,"name":"Starbound"},{"executables":{"win32":["starcraft.exe"]},"id":251,"name":"Starcraft"},{"executables":{"win32":["SSFIV.exe"]},"id":253,"name":"Ultra Street Fighter IV"},{"executables":{"win32":["superhexagon.exe"]},"id":254,"name":"Super Hexagon"},{"executables":{"win32":["swordandsworcery_pc.exe"]},"id":255,"name":"Superbrothers: Sword & Sworcery EP"},{"executables":{"win32":["hl2TF.exe"]},"id":256,"name":"Team Fortress 2"},{"executables":{"win32":["TERA.exe"]},"id":258,"name":"TERA"},{"executables":{"win32":["Terraria.exe"]},"id":259,"name":"Terraria"},{"executables":{"win32":["Bethesda.net_Launcher.exe"]},"id":260,"name":"The Elder Scrolls Online"},{"executables":{"win32":["TESV.exe"]},"id":261,"name":"The Elder Scrolls V: Skyrim"},{"executables":{"win32":["TheSecretWorld.exe"]},"id":262,"name":"The Secret World"},{"executables":{"win32":["TS3.exe","ts3w.exe"]},"id":264,"name":"The Sims 3"},{"executables":{"win32":["WALKINGDEAD101.EXE"]},"id":265,"name":"The Walking Dead"},{"executables":{"win32":["TheWalkingDead2.exe"]},"id":266,"name":"The Walking Dead Season Two"},{"executables":{"win32":["witcher3.exe"]},"id":267,"name":"The Witcher 3"},{"executables":{"win32":["Future Soldier.exe"]},"id":268,"name":"Tom Clancy's Ghost Recon: Future Solider"},{"executables":{"win32":["TombRaider.exe"]},"id":269,"name":"Tomb Raider (2013)"},{"executables":{"win32":["Torchlight.exe"]},"id":271,"name":"Torchlight"},{"executables":{"win32":["Torchlight2.exe"]},"id":272,"name":"Torchlight 2"},{"executables":{"win32":["Shogun2.exe"]},"id":273,"name":"Total War: Shogun 2"},{"executables":{"win32":["Transistor.exe"]},"id":274,"name":"Transistor"},{"executables":{"win32":["trine.exe"]},"id":275,"name":"Trine"},{"executables":{"win32":["trine2_32bit.exe"]},"id":276,"name":"Trine 2"},{"executables":{"win32":["UOKR.exe"]},"id":277,"name":"Ultima Online"},{"executables":{"win32":["aces.exe"]},"id":279,"name":"War Thunder"},{"executables":{"win32":["Warcraft III.exe","wc3.exe"]},"id":281,"name":"Warcraft 3: Reign of Chaos"},{"executables":{"win32":["Warcraft II BNE.exe"]},"id":282,"name":"Warcraft II"},{"executables":{"win32":["Warframe.x64.exe","Warframe.exe"]},"id":283,"name":"Warframe"},{"executables":{"win32":["watch_dogs.exe"]},"id":284,"name":"Watch Dogs"},{"executables":{"win32":["WildStar64.exe"]},"id":285,"name":"WildStar"},{"executables":{"win32":["XComGame.exe"]},"id":288,"name":"XCOM: Enemy Unknown"},{"executables":{"win32":["DFO.exe","dfo.exe"]},"id":289,"name":"Dungeon Fighter Online"},{"executables":{"win32":["aclauncher.exe","acclient.exe"]},"id":290,"name":"Asheron's Call"},{"executables":{"win32":["MapleStory2.exe"]},"id":291,"name":"MapleStory 2"},{"executables":{"win32":["ksp.exe"]},"id":292,"name":"Kerbal Space Program"},{"executables":{"win32":["PINBALL.EXE"]},"id":293,"name":"3D Pinball: Space Cadet"},{"executables":{"win32":["dave.exe"]},"id":294,"name":"Dangerous Dave"},{"executables":{"win32":["iwbtgbeta(slomo).exe","iwbtgbeta(fs).exe"]},"id":295,"name":"I Wanna Be The Guy"},{"executables":{"win32":["MechWarriorOnline.exe "]},"id":296,"name":"Mech Warrior Online"},{"executables":{"win32":["dontstarve_steam.exe"]},"id":297,"name":"Don't Starve"},{"executables":{"win32":["GalCiv3.exe"]},"id":298,"name":"Galactic Civilization 3"},{"executables":{"win32":["Risk of Rain.exe"]},"id":299,"name":"Risk of Rain"},{"executables":{"win32":["Binding_of_Isaac.exe","Isaac-ng.exe"]},"id":300,"name":"The Binding of Isaac"},{"executables":{"win32":["RustClient.exe"]},"id":301,"name":"Rust"},{"executables":{"win32":["Clicker Heroes.exe"]},"id":302,"name":"Clicker Heroes"},{"executables":{"win32":["Brawlhalla.exe"]},"id":303,"name":"Brawlhalla"},{"executables":{"win32":["TownOfSalem.exe"]},"id":304,"name":"Town of Salem"},{"executables":{"win32":["osu!.exe"]},"id":305,"name":"osu!"},{"executables":{"win32":["PathOfExileSteam.exe","PathOfExile.exe"]},"id":306,"name":"Path of Exile"},{"executables":{"win32":["Dolphin.exe"]},"id":307,"name":"Dolphin"},{"executables":{"win32":["RocketLeague.exe"]},"id":308,"name":"Rocket League"},{"executables":{"win32":["TJPP.exe"]},"id":309,"name":"Jackbox Party Pack"},{"executables":{"win32":["KFGame.exe"]},"id":310,"name":"Killing Floor 2"},{"executables":{"win32":["ShooterGame.exe"]},"id":311,"name":"Ark: Survival Evolved"},{"executables":{"win32":["LifeIsStrange.exe"]},"id":312,"name":"Life Is Strange"},{"executables":{"win32":["Client_tos.exe"]},"id":313,"name":"Tree of Savior"},{"executables":{"win32":["olliolli2.exe"]},"id":314,"name":"OlliOlli2"},{"executables":{"win32":["cw.exe"]},"id":315,"name":"Closers Dimension Conflict"},{"executables":{"win32":["ESSTEAM.exe","elsword.exe","x2.exe"]},"id":316,"name":"Elsword"},{"executables":{"win32":["ori.exe"]},"id":317,"name":"Ori and the Blind Forest"},{"executables":{"win32":["Skyforge.exe"]},"id":318,"name":"Skyforge"},{"executables":{"win32":["projectzomboid64.exe","projectzomboid32.exe"]},"id":319,"name":"Project Zomboid"},{"executables":{"win32":["From_The_Depths.exe"]},"id":320,"name":"The Depths"},{"executables":{"win32":["TheCrew.exe"]},"id":321,"name":"The Crew"},{"executables":{"win32":["MarvelHeroes2015.exe"]},"id":322,"name":"Marvel Heroes 2015"},{"executables":{"win32":["timeclickers.exe"]},"id":324,"name":"Time Clickers"},{"executables":{"win32":["eurotrucks2.exe"]},"id":325,"name":"Euro Truck Simulator 2"},{"executables":{"win32":["FarmingSimulator2015Game.exe"]},"id":326,"name":"Farming Simulator 15"},{"executables":{"win32":["strife.exe"]},"id":327,"name":"Strife"},{"executables":{"win32":["Awesomenauts.exe"]},"id":328,"name":"Awesomenauts"},{"executables":{"win32":["Dofus.exe"]},"id":329,"name":"Dofus"},{"executables":{"win32":["Boid.exe"]},"id":330,"name":"Boid"},{"executables":{"win32":["adventure-capitalist.exe"]},"id":331,"name":"AdVenture Capitalist"},{"executables":{"win32":["OrcsMustDie2.exe"]},"id":332,"name":"Orcs Must Die! 2"},{"executables":{"win32":["Mountain.exe"]},"id":333,"name":"Mountain"},{"executables":{"win32":["Valkyria.exe"]},"id":335,"name":"Valkyria Chronicles"},{"executables":{"win32":["ffxiiiimg.exe"]},"id":336,"name":"Final Fantasy XIII"},{"executables":{"win32":["TLR.exe"]},"id":337,"name":"The Last Remnant"},{"executables":{"win32":["Cities.exe"]},"id":339,"name":"Cities Skylines"},{"executables":{"win32":["worldofwarships.exe","WoWSLauncher.exe"]},"id":341,"name":"World of Warships"},{"executables":{"win32":["spacegame-Win64-shipping.exe"]},"id":342,"name":"Fractured Space"},{"executables":{"win32":["thespacegame.exe"]},"id":343,"name":"Ascent - The Space Game"},{"executables":{"win32":["DuckGame.exe"]},"id":344,"name":"Duck Game"},{"executables":{"win32":["PPSSPPWindows.exe"]},"id":345,"name":"PPSSPP"},{"executables":{"win32":["MBAA.exe"]},"id":346,"name":"Melty Blood Actress Again: Current Code"},{"executables":{"win32":["TheWolfAmongUs.exe"]},"id":347,"name":"The Wolf Among Us"},{"executables":{"win32":["SpaceEngineers.exe"]},"id":348,"name":"Space Engineers"},{"executables":{"win32":["Borderlands.exe"]},"id":349,"name":"Borderlands"},{"executables":{"win32":["100orange.exe"]},"id":351,"name":"100% Orange Juice"},{"executables":{"win32":["reflex.exe"]},"id":354,"name":"Reflex"},{"executables":{"win32":["pso2.exe"]},"id":355,"name":"Phantasy Star Online 2"},{"executables":{"win32":["AssettoCorsa.exe"]},"id":356,"name":"Assetto Corsa"},{"executables":{"win32":["iw3mp.exe","iw3sp.exe"]},"id":357,"name":"Call of Duty 4: Modern Warfare"},{"executables":{"win32":["WolfOldBlood_x64.exe"]},"id":358,"name":"Wolfenstein: The Old Blood"},{"executables":{"win32":["castle.exe"]},"id":359,"name":"Castle Crashers"},{"executables":{"win32":["vindictus.exe"]},"id":360,"name":"Vindictus"},{"executables":{"win32":["ShooterGame-Win32-Shipping.exe"]},"id":361,"name":"Dirty Bomb"},{"executables":{"win32":["BatmanAK.exe"]},"id":362,"name":"Batman Arkham Knight"},{"executables":{"win32":["drt.exe"]},"id":363,"name":"Dirt Rally"},{"executables":{"win32":["rFactor.exe"]},"id":364,"name":"rFactor"},{"executables":{"win32":["clonk.exe"]},"id":365,"name":"Clonk Rage"},{"executables":{"win32":["SRHK.exe"]},"id":366,"name":"Shadowrun: Hong Kong"},{"executables":{"win32":["Insurgency.exe"]},"id":367,"name":"Insurgency"},{"executables":{"win32":["StepMania.exe"]},"id":368,"name":"Step Mania"},{"executables":{"win32":["FirefallCLient.exe"]},"id":369,"name":"Firefall"},{"executables":{"win32":["mirrorsedge.exe"]},"id":370,"name":"Mirrors Edge"},{"executables":{"win32":["MgsGroundZeroes.exe"]},"id":371,"name":"Metal Gear Solid V: Ground Zeroes"},{"executables":{"win32":["mgsvtpp.exe"]},"id":372,"name":"Metal Gear Solid V: The Phantom Pain"},{"executables":{"win32":["tld.exe"]},"id":373,"name":"The Long Dark"},{"executables":{"win32":["TKOM.exe"]},"id":374,"name":"Take On Mars"},{"executables":{"win32":["robloxplayerlauncher.exe","Roblox.exe"]},"id":375,"name":"Roblox"},{"executables":{"win32":["eu4.exe"]},"id":376,"name":"Europa Universalis 4"},{"executables":{"win32":["APB.exe"]},"id":377,"name":"APB Reloaded"},{"executables":{"win32":["Robocraft.exe"]},"id":378,"name":"Robocraft"},{"executables":{"win32":["Unity.exe"]},"id":379,"name":"Unity"},{"executables":{"win32":["Simpsons.exe"]},"id":380,"name":"The Simpsons: Hit & Run"},{"executables":{"win32":["Dnlauncher.exe","DragonNest.exe"]},"id":381,"name":"Dragon Nest"},{"executables":{"win32":["Trove.exe"]},"id":382,"name":"Trove"},{"executables":{"win32":["EndlessLegend.exe"]},"id":383,"name":"Endless Legend"},{"executables":{"win32":["TurbineLauncher.exe","dndclient.exe"]},"id":384,"name":"Dungeons & Dragons Online"},{"executables":{"win32":["quakelive.exe","quakelive_steam.exe"]},"id":385,"name":"Quake Live"},{"executables":{"win32":["7DaysToDie.exe"]},"id":386,"name":"7DaysToDie"},{"executables":{"win32":["SpeedRunners.exe"]},"id":387,"name":"SpeedRunners"},{"executables":{"win32":["gamemd.exe"]},"id":388,"name":"Command & Conquer: Red Alert 2"},{"executables":{"win32":["generals.exe"]},"id":389,"name":"Command & Conquer Generals: Zero Hour"},{"executables":{"win32":["Oblivion.exe"]},"id":390,"name":"The Elder Scrolls 4: Oblivion"},{"executables":{"win32":["mgsi.exe"]},"id":391,"name":"Metal Gear Solid"},{"executables":{"win32":["EoCApp.exe"]},"id":392,"name":"Divinity - Original Sin"},{"executables":{"win32":["Torment.exe"]},"id":393,"name":"Planescape: Torment"},{"executables":{"win32":["HexPatch.exe"]},"id":394,"name":"Hex: Shards of Fate"},{"executables":{"win32":["NS3FB.exe"]},"id":395,"name":"Naruto Shippuden Ultimate Ninja Storm 3 Full Burst"},{"executables":{"win32":["NSUNSR.exe"]},"id":396,"name":"Naruto Shippuden Ultimate Ninja Storm Revolution"},{"executables":{"win32":["SaintsRowIV.exe"]},"id":397,"name":"Saints Row IV"},{"executables":{"win32":["Shadowrun.exe"]},"id":398,"name":"Shadowrun"},{"executables":{"win32":["DungeonoftheEndless.exe"]},"id":399,"name":"Dungeon of the Endless"},{"executables":{"win32":["Hon.exe"]},"id":400,"name":"Heroes of Newerth"},{"executables":{"win32":["mabinogi.exe"]},"id":401,"name":"Mabinogi"},{"executables":{"win32":["CoD2MP_s.exe","CoDSP_s.exe"]},"id":402,"name":"Call of Duty 2:"},{"executables":{"win32":["CoDWaWmp.exe","CoDWaw.exe"]},"id":403,"name":"Call of Duty: World at War"},{"executables":{"win32":["heroes.exe"]},"id":404,"name":"Mabinogi Heroes (Vindictus) "},{"executables":{"win32":["KanColleViewer.exe"]},"id":405,"name":"KanColle "},{"executables":{"win32":["cyphers.exe"]},"id":406,"name":"Cyphers"},{"executables":{"win32":["RelicCoH2.exe"]},"id":407,"name":"Company of Heroes 2"},{"executables":{"win32":["MJ.exe"]},"id":408,"name":"セガNET麻雀MJ"},{"executables":{"win32":["ge.exe"]},"id":409,"name":"Granado Espada"},{"executables":{"win32":["NovaRO.exe"]},"id":410,"name":"Nova Ragnarok Online"},{"executables":{"win32":["RivalsofAether.exe"]},"id":411,"name":"Rivals of Aether"},{"executables":{"win32":["bfh.exe"]},"id":412,"name":"Battlefield Hardline"},{"executables":{"win32":["GrowHome.exe"]},"id":413,"name":"Grow Home"},{"executables":{"win32":["patriots.exe"]},"id":414,"name":"Rise of Nations Extended"},{"executables":{"win32":["Railroads.exe"]},"id":415,"name":"Sid Meier's Railroads!"},{"executables":{"win32":["Empire.exe"]},"id":416,"name":"Empire: Total War"},{"executables":{"win32":["Napoleon.exe"]},"id":417,"name":"Napoleon: Total War"},{"executables":{"win32":["gta_sa.exe"]},"id":418,"name":"Grand Theft Auto: San Andreas"},{"executables":{"win32":["MadMax.exe"]},"id":419,"name":"Mad Max"},{"executables":{"win32":["Titanfall.exe"]},"id":420,"name":"Titanfall"},{"executables":{"win32":["age2_x1.exe"]},"id":421,"name":"Age of Empires II: The Conquerors"},{"executables":{"win32":["Rome2.exe"]},"id":422,"name":"Total War: ROME 2"},{"executables":{"win32":["ShadowOfMordor.exe"]},"id":423,"name":"Middle-earth: Shadow of Mordor"},{"executables":{"win32":["Subnautica.exe"]},"id":424,"name":"Subnautica"},{"executables":{"win32":["anno5.exe"]},"id":425,"name":"Anno 2070"},{"executables":{"win32":["carrier.exe"]},"id":426,"name":"Carrier Command Gaea Mission"},{"executables":{"win32":["DarksidersPC.exe"]},"id":427,"name":"Darksiders"},{"executables":{"win32":["Darksiders2.exe"]},"id":428,"name":"Darksiders 2"},{"executables":{"win32":["mudlet.exe"]},"id":429,"name":"Mudlet"},{"executables":{"win32":["DunDefLauncher.exe"]},"id":430,"name":"Dungeon Defenders II"},{"executables":{"win32":["hng.exe"]},"id":431,"name":"Heroes and Generals"},{"executables":{"win32":["WFTOGame.exe"]},"id":432,"name":"War of the Overworld"},{"executables":{"win32":["Talisman.exe"]},"id":433,"name":"Talisman: Digital Edition"},{"executables":{"win32":["limbo.exe"]},"id":434,"name":"Limbo"},{"executables":{"win32":["ibbobb.exe"]},"id":435,"name":"ibb & obb"},{"executables":{"win32":["BattleBlockTheater.exe"]},"id":436,"name":"BattleBlock Theater"},{"executables":{"win32":["iracinglauncher.exe","iracingsim.exe","iracingsim64.exe"]},"id":437,"name":"iRacing"},{"executables":{"win32":["CivilizationV_DX11.exe"]},"id":438,"name":"Civilization V"}]
+},{}]},{},[5])(5)
+});
\ No newline at end of file
diff --git a/web-dist/discord.3.7.1.js b/web-dist/discord.3.7.1.js
new file mode 100644
index 000000000..0d9f9341a
--- /dev/null
+++ b/web-dist/discord.3.7.1.js
@@ -0,0 +1,3879 @@
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Discord = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o]*>/g) || [])[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
+ var mention = _step3.value;
+
+ _mentions.push(mention.substring(2, mention.length - 1));
+ }
+ } catch (err) {
+ _didIteratorError3 = true;
+ _iteratorError3 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion3 && _iterator3["return"]) {
+ _iterator3["return"]();
+ }
+ } finally {
+ if (_didIteratorError3) {
+ throw _iteratorError3;
+ }
+ }
+ }
+
+ return _mentions;
+ }
+ });
+
+ return prom;
+ }
+
+ //def createws
+ }, {
+ key: "createws",
+ value: function createws(url) {
+ if (this.websocket) return false;
+
+ var self = this;
+
+ //good to go
+ this.websocket = new WebSocket(url);
+
+ //open
+ this.websocket.onopen = function () {
+ self.trySendConnData(); //try connecting
+ };
+
+ //close
+ this.websocket.onclose = function () {
+ self.trigger("disconnected");
+ };
+
+ //message
+ this.websocket.onmessage = function (e) {
+
+ var dat = false,
+ data = {};
+
+ try {
+ dat = JSON.parse(e.data);
+ data = dat.d;
+ } catch (err) {
+ self.trigger("error", err, e);
+ return;
+ }
+
+ self.trigger("raw", dat);
+
+ //valid message
+ switch (dat.t) {
+
+ case "READY":
+ self.debug("received ready packet");
+
+ self.user = self.addUser(data.user);
+
+ var _iteratorNormalCompletion4 = true;
+ var _didIteratorError4 = false;
+ var _iteratorError4 = undefined;
+
+ try {
+ for (var _iterator4 = data.guilds[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
+ var _server = _step4.value;
+
+ var server = self.addServer(_server);
+ }
+ } catch (err) {
+ _didIteratorError4 = true;
+ _iteratorError4 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion4 && _iterator4["return"]) {
+ _iterator4["return"]();
+ }
+ } finally {
+ if (_didIteratorError4) {
+ throw _iteratorError4;
+ }
+ }
+ }
+
+ var _iteratorNormalCompletion5 = true;
+ var _didIteratorError5 = false;
+ var _iteratorError5 = undefined;
+
+ try {
+ for (var _iterator5 = data.private_channels[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
+ var _pmc = _step5.value;
+
+ var pmc = self.addPMChannel(_pmc);
+ }
+ } catch (err) {
+ _didIteratorError5 = true;
+ _iteratorError5 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion5 && _iterator5["return"]) {
+ _iterator5["return"]();
+ }
+ } finally {
+ if (_didIteratorError5) {
+ throw _iteratorError5;
+ }
+ }
+ }
+
+ self.trigger("ready");
+ self.readyTime = Date.now();
+ self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users.");
+ self.state = 3;
+ setInterval(function () {
+ self.keepAlive.apply(self);
+ }, data.heartbeat_interval);
+
+ break;
+ case "MESSAGE_CREATE":
+ self.debug("received message");
+
+ var mentions = [];
+ data.mentions = data.mentions || []; //for some reason this was not defined at some point?
+ var _iteratorNormalCompletion6 = true;
+ var _didIteratorError6 = false;
+ var _iteratorError6 = undefined;
+
+ try {
+ for (var _iterator6 = data.mentions[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
+ var mention = _step6.value;
+
+ mentions.push(self.addUser(mention));
+ }
+ } catch (err) {
+ _didIteratorError6 = true;
+ _iteratorError6 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion6 && _iterator6["return"]) {
+ _iterator6["return"]();
+ }
+ } finally {
+ if (_didIteratorError6) {
+ throw _iteratorError6;
+ }
+ }
+ }
+
+ var channel = self.getChannel("id", data.channel_id);
+ if (channel) {
+ var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author)));
+ self.trigger("message", msg);
+ }
+
+ break;
+ case "MESSAGE_DELETE":
+ self.debug("message deleted");
+
+ var channel = self.getChannel("id", data.channel_id);
+ var message = channel.getMessage("id", data.id);
+ if (message) {
+ self.trigger("messageDelete", channel, message);
+ channel.messages.splice(channel.messages.indexOf(message), 1);
+ } else {
+ //don't have the cache of that message ;(
+ self.trigger("messageDelete", channel);
+ }
+ break;
+ case "MESSAGE_UPDATE":
+ self.debug("message updated");
+
+ var channel = self.getChannel("id", data.channel_id);
+ var formerMessage = channel.getMessage("id", data.id);
+
+ if (formerMessage) {
+
+ //new message might be partial, so we need to fill it with whatever the old message was.
+ var info = {};
+
+ for (var key in formerMessage) {
+ info[key] = formerMessage[key];
+ }
+
+ for (var key in data) {
+ info[key] = data[key];
+ }
+
+ var mentions = [];
+ var _iteratorNormalCompletion7 = true;
+ var _didIteratorError7 = false;
+ var _iteratorError7 = undefined;
+
+ try {
+ for (var _iterator7 = info.mentions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
+ var mention = _step7.value;
+
+ mentions.push(self.addUser(mention));
+ }
+ } catch (err) {
+ _didIteratorError7 = true;
+ _iteratorError7 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion7 && _iterator7["return"]) {
+ _iterator7["return"]();
+ }
+ } finally {
+ if (_didIteratorError7) {
+ throw _iteratorError7;
+ }
+ }
+ }
+
+ var newMessage = new Message(info, channel, mentions, formerMessage.author);
+
+ self.trigger("messageUpdate", newMessage, formerMessage);
+
+ channel.messages[channel.messages.indexOf(formerMessage)] = newMessage;
+ }
+
+ // message isn't in cache, and if it's a partial it could cause
+ // all hell to break loose... best to just act as if nothing happened
+
+ break;
+
+ case "GUILD_DELETE":
+
+ var server = self.getServer("id", data.id);
+
+ if (server) {
+ self.serverCache.splice(self.serverCache.indexOf(server), 1);
+ self.trigger("serverDelete", server);
+ }
+
+ break;
+
+ case "CHANNEL_DELETE":
+
+ var channel = self.getChannel("id", data.id);
+
+ if (channel) {
+
+ var server = channel.server;
+
+ if (server) {
+
+ server.channels.splice(server.channels.indexOf(channel), 1);
+ }
+
+ self.trigger("channelDelete", channel);
+
+ self.serverCache.splice(self.serverCache.indexOf(channel), 1);
+ }
+
+ break;
+
+ case "GUILD_CREATE":
+
+ var server = self.getServer("id", data.id);
+
+ if (!server) {
+ //if server doesn't already exist because duh
+ server = self.addServer(data);
+ } /*else if(server.channels.length === 0){
+
+ var srv = new Server(data, self);
+ for(channel of data.channels){
+ srv.channels.push(new Channel(channel, data.id));
+ }
+ self.serverCache[self.serverCache.indexOf(server)] = srv;
+
+ }*/
+
+ if (self.serverCreateListener[data.id]) {
+ var cbs = self.serverCreateListener[data.id];
+ cbs[0](server); //promise then callback
+ cbs[1](null, server); //legacy callback
+ self.serverCreateListener[data.id] = null;
+ }
+
+ self.trigger("serverCreate", server);
+
+ break;
+
+ case "CHANNEL_CREATE":
+
+ var channel = self.getChannel("id", data.id);
+
+ if (!channel) {
+
+ var chann = self.addChannel(data, data.guild_id);
+ var srv = self.getServer("id", data.guild_id);
+ if (srv) {
+ srv.addChannel(chann);
+ }
+ self.trigger("channelCreate", chann);
+ }
+
+ break;
+
+ case "GUILD_MEMBER_ADD":
+
+ var server = self.getServer("id", data.guild_id);
+
+ if (server) {
+
+ var user = self.addUser(data.user); //if for whatever reason it doesn't exist..
+
+ if (! ~server.members.indexOf(user)) {
+ server.members.push(user);
+ }
+
+ self.trigger("serverNewMember", user, server);
+ }
+
+ break;
+
+ case "GUILD_MEMBER_REMOVE":
+
+ var server = self.getServer("id", data.guild_id);
+
+ if (server) {
+
+ var user = self.addUser(data.user); //if for whatever reason it doesn't exist..
+
+ if (~server.members.indexOf(user)) {
+ server.members.splice(server.members.indexOf(user), 1);
+ }
+
+ self.trigger("serverRemoveMember", user, server);
+ }
+
+ break;
+
+ case "USER_UPDATE":
+
+ if (self.user && data.id === self.user.id) {
+
+ var newUser = new User(data); //not actually adding to the cache
+
+ self.trigger("userUpdate", newUser, self.user);
+
+ if (~self.userCache.indexOf(self.user)) {
+ self.userCache[self.userCache.indexOf(self.user)] = newUser;
+ }
+
+ self.user = newUser;
+ }
+
+ break;
+
+ case "PRESENCE_UPDATE":
+
+ var userInCache = self.getUser("id", data.user.id);
+
+ if (userInCache) {
+ //user exists
+ var presenceUser = new User(data.user);
+ if (presenceUser.equalsStrict(userInCache)) {
+ //they're exactly the same, an actual presence update
+ userInCache.status = data.status;
+ self.trigger("presence", {
+ user: userInCache,
+ status: data.status,
+ server: self.getServer("id", data.guild_id),
+ gameId: data.game_id
+ });
+ } else {
+ //one of their details changed.
+ self.trigger("userUpdate", userInCache, presenceUser);
+ self.userCache[self.userCache.indexOf(userInCache)] = presenceUser;
+ }
+ }
+
+ break;
+
+ case "CHANNEL_UPDATE":
+
+ var channelInCache = self.getChannel("id", data.id),
+ serverInCache = self.getServer("id", data.guild_id);
+
+ if (channelInCache && serverInCache) {
+
+ var newChann = new Channel(data, serverInCache);
+ newChann.messages = channelInCache.messages;
+
+ self.trigger("channelUpdate", channelInCache, newChann);
+
+ self.channelCache[self.channelCache.indexOf(channelInCache)] = newChann;
+ }
+
+ break;
+
+ default:
+ self.debug("received unknown packet");
+ self.trigger("unknown", dat);
+ break;
+
+ }
+ };
+ }
+
+ //def addUser
+ }, {
+ key: "addUser",
+ value: function addUser(data) {
+ if (!this.getUser("id", data.id)) {
+ this.userCache.push(new User(data));
+ }
+ return this.getUser("id", data.id);
+ }
+
+ //def addChannel
+ }, {
+ key: "addChannel",
+ value: function addChannel(data, serverId) {
+ if (!this.getChannel("id", data.id)) {
+ this.channelCache.push(new Channel(data, this.getServer("id", serverId)));
+ }
+ return this.getChannel("id", data.id);
+ }
+ }, {
+ key: "addPMChannel",
+ value: function addPMChannel(data) {
+ if (!this.getPMChannel("id", data.id)) {
+ this.pmChannelCache.push(new PMChannel(data, this));
+ }
+ return this.getPMChannel("id", data.id);
+ }
+ }, {
+ key: "setTopic",
+ value: function setTopic(channel, topic) {
+ var callback = arguments.length <= 2 || arguments[2] === undefined ? function (err) {} : arguments[2];
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+
+ self.resolveDestination(channel).then(next)["catch"](error);
+
+ function error(e) {
+ callback(e);
+ reject(e);
+ }
+
+ function next(destination) {
+
+ var asChan = self.getChannel("id", destination);
+
+ request.patch(Endpoints.CHANNELS + "/" + destination).set("authorization", self.token).send({
+ name: asChan.name,
+ position: 0,
+ topic: topic
+ }).end(function (err, res) {
+ if (err) {
+ error(err);
+ } else {
+ asChan.topic = res.body.topic;
+ resolve();
+ callback();
+ }
+ });
+ }
+ });
+ }
+
+ //def addServer
+ }, {
+ key: "addServer",
+ value: function addServer(data) {
+
+ var self = this;
+ var server = this.getServer("id", data.id);
+
+ if (data.unavailable) {
+ self.trigger("unavailable", data);
+ self.debug("Server ID " + data.id + " has been marked unavailable by Discord. It was not cached.");
+ return;
+ }
+
+ if (!server) {
+ server = new Server(data, this);
+ this.serverCache.push(server);
+ if (data.channels) {
+ var _iteratorNormalCompletion8 = true;
+ var _didIteratorError8 = false;
+ var _iteratorError8 = undefined;
+
+ try {
+ for (var _iterator8 = data.channels[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
+ var channel = _step8.value;
+
+ server.channels.push(this.addChannel(channel, server.id));
+ }
+ } catch (err) {
+ _didIteratorError8 = true;
+ _iteratorError8 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion8 && _iterator8["return"]) {
+ _iterator8["return"]();
+ }
+ } finally {
+ if (_didIteratorError8) {
+ throw _iteratorError8;
+ }
+ }
+ }
+ }
+ }
+
+ var _iteratorNormalCompletion9 = true;
+ var _didIteratorError9 = false;
+ var _iteratorError9 = undefined;
+
+ try {
+ for (var _iterator9 = data.presences[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) {
+ var presence = _step9.value;
+
+ self.getUser("id", presence.user.id).status = presence.status;
+ }
+ } catch (err) {
+ _didIteratorError9 = true;
+ _iteratorError9 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion9 && _iterator9["return"]) {
+ _iterator9["return"]();
+ }
+ } finally {
+ if (_didIteratorError9) {
+ throw _iteratorError9;
+ }
+ }
+ }
+
+ return server;
+ }
+
+ //def getUser
+ }, {
+ key: "getUser",
+ value: function getUser(key, value) {
+ var _iteratorNormalCompletion10 = true;
+ var _didIteratorError10 = false;
+ var _iteratorError10 = undefined;
+
+ try {
+ for (var _iterator10 = this.userCache[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {
+ var user = _step10.value;
+
+ if (user[key] === value) {
+ return user;
+ }
+ }
+ } catch (err) {
+ _didIteratorError10 = true;
+ _iteratorError10 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion10 && _iterator10["return"]) {
+ _iterator10["return"]();
+ }
+ } finally {
+ if (_didIteratorError10) {
+ throw _iteratorError10;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ //def getChannel
+ }, {
+ key: "getChannel",
+ value: function getChannel(key, value) {
+ var _iteratorNormalCompletion11 = true;
+ var _didIteratorError11 = false;
+ var _iteratorError11 = undefined;
+
+ try {
+ for (var _iterator11 = this.channelCache[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) {
+ var channel = _step11.value;
+
+ if (channel[key] === value) {
+ return channel;
+ }
+ }
+ } catch (err) {
+ _didIteratorError11 = true;
+ _iteratorError11 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion11 && _iterator11["return"]) {
+ _iterator11["return"]();
+ }
+ } finally {
+ if (_didIteratorError11) {
+ throw _iteratorError11;
+ }
+ }
+ }
+
+ return this.getPMChannel(key, value); //might be a PM
+ }
+ }, {
+ key: "getPMChannel",
+ value: function getPMChannel(key, value) {
+ var _iteratorNormalCompletion12 = true;
+ var _didIteratorError12 = false;
+ var _iteratorError12 = undefined;
+
+ try {
+ for (var _iterator12 = this.pmChannelCache[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) {
+ var channel = _step12.value;
+
+ if (channel[key] === value) {
+ return channel;
+ }
+ }
+ } catch (err) {
+ _didIteratorError12 = true;
+ _iteratorError12 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion12 && _iterator12["return"]) {
+ _iterator12["return"]();
+ }
+ } finally {
+ if (_didIteratorError12) {
+ throw _iteratorError12;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ //def getServer
+ }, {
+ key: "getServer",
+ value: function getServer(key, value) {
+ var _iteratorNormalCompletion13 = true;
+ var _didIteratorError13 = false;
+ var _iteratorError13 = undefined;
+
+ try {
+ for (var _iterator13 = this.serverCache[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) {
+ var server = _step13.value;
+
+ if (server[key] === value) {
+ return server;
+ }
+ }
+ } catch (err) {
+ _didIteratorError13 = true;
+ _iteratorError13 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion13 && _iterator13["return"]) {
+ _iterator13["return"]();
+ }
+ } finally {
+ if (_didIteratorError13) {
+ throw _iteratorError13;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ //def trySendConnData
+ }, {
+ key: "trySendConnData",
+ value: function trySendConnData() {
+
+ if (this.token && !this.alreadySentData) {
+
+ this.alreadySentData = true;
+
+ var data = {
+ op: 2,
+ d: {
+ token: this.token,
+ v: 3,
+ properties: {
+ "$os": "discord.js",
+ "$browser": "discord.js",
+ "$device": "discord.js",
+ "$referrer": "",
+ "$referring_domain": ""
+ }
+ }
+ };
+ this.websocket.send(JSON.stringify(data));
+ }
+ }
+ }, {
+ key: "resolveServerID",
+ value: function resolveServerID(resource) {
+
+ if (resource instanceof Server) {
+ return resource.id;
+ } else if (!isNaN(resource) && resource.length && resource.length === 17) {
+ return resource;
+ }
+ }
+ }, {
+ key: "resolveDestination",
+ value: function resolveDestination(destination) {
+ var channId = false;
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ if (destination instanceof Server) {
+ channId = destination.id; //general is the same as server id
+ } else if (destination instanceof Channel) {
+ channId = destination.id;
+ } else if (destination instanceof Message) {
+ channId = destination.channel.id;
+ } else if (destination instanceof PMChannel) {
+ channId = destination.id;
+ } else if (destination instanceof User) {
+
+ //check if we have a PM
+ var _iteratorNormalCompletion14 = true;
+ var _didIteratorError14 = false;
+ var _iteratorError14 = undefined;
+
+ try {
+ for (var _iterator14 = self.pmChannelCache[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) {
+ var pmc = _step14.value;
+
+ if (pmc.user.equals(destination)) {
+ resolve(pmc.id);
+ return;
+ }
+ }
+
+ //we don't, at this point we're late
+ } catch (err) {
+ _didIteratorError14 = true;
+ _iteratorError14 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion14 && _iterator14["return"]) {
+ _iterator14["return"]();
+ }
+ } finally {
+ if (_didIteratorError14) {
+ throw _iteratorError14;
+ }
+ }
+ }
+
+ self.startPM(destination).then(function (pmc) {
+ resolve(pmc.id);
+ })["catch"](reject);
+ } else {
+ channId = destination;
+ }
+ if (channId) resolve(channId);else reject();
+ });
+ }
+ }, {
+ key: "_sendMessage",
+ value: function _sendMessage(destination, content, tts, mentions) {
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).send({
+ content: content,
+ mentions: mentions,
+ tts: tts
+ }).end(function (err, res) {
+
+ if (err) {
+ reject(err);
+ } else {
+ var data = res.body;
+
+ var mentions = [];
+
+ data.mentions = data.mentions || []; //for some reason this was not defined at some point?
+
+ var _iteratorNormalCompletion15 = true;
+ var _didIteratorError15 = false;
+ var _iteratorError15 = undefined;
+
+ try {
+ for (var _iterator15 = data.mentions[Symbol.iterator](), _step15; !(_iteratorNormalCompletion15 = (_step15 = _iterator15.next()).done); _iteratorNormalCompletion15 = true) {
+ var mention = _step15.value;
+
+ mentions.push(self.addUser(mention));
+ }
+ } catch (err) {
+ _didIteratorError15 = true;
+ _iteratorError15 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion15 && _iterator15["return"]) {
+ _iterator15["return"]();
+ }
+ } finally {
+ if (_didIteratorError15) {
+ throw _iteratorError15;
+ }
+ }
+ }
+
+ var channel = self.getChannel("id", data.channel_id);
+ if (channel) {
+ var msg = channel.addMessage(new Message(data, channel, mentions, self.addUser(data.author)));
+ resolve(msg);
+ }
+ }
+ });
+ });
+ }
+ }, {
+ key: "_sendFile",
+ value: function _sendFile(destination, attachment) {
+ var attachmentName = arguments.length <= 2 || arguments[2] === undefined ? "DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png" : arguments[2];
+
+ var self = this;
+
+ return new Promise(function (resolve, reject) {
+ request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization", self.token).attach("file", attachment, attachmentName).end(function (err, res) {
+
+ if (err) {
+ reject(err);
+ } else {
+
+ var chann = self.getChannel("id", destination);
+ if (chann) {
+ var msg = chann.addMessage(new Message(res.body, chann, [], self.user));
+ resolve(msg);
+ }
+ }
+ });
+ });
+ }
+ }, {
+ key: "_updateMessage",
+ value: function _updateMessage(message, content) {
+ var self = this;
+ return new Promise(function (resolve, reject) {
+ request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).send({
+ content: content,
+ mentions: []
+ }).end(function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ var msg = new Message(res.body, message.channel, message.mentions, message.sender);
+ resolve(msg);
+ message.channel.messages[message.channel.messages.indexOf(message)] = msg;
+ }
+ });
+ });
+ }
+ }, {
+ key: "_deleteMessage",
+ value: function _deleteMessage(message) {
+ var self = this;
+ return new Promise(function (resolve, reject) {
+
+ request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization", self.token).end(function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ resolve();
+ }
+ });
+ });
+ }
+ }, {
+ key: "checkQueue",
+ value: function checkQueue(channelID) {
+ var _this = this;
+
+ var self = this;
+
+ if (!this.checkingQueue[channelID]) {
+ (function () {
+ var doNext = function doNext() {
+ if (self.queue[channelID].length === 0) {
+ done();
+ return;
+ }
+ var queuedEvent = self.queue[channelID][0];
+ switch (queuedEvent.action) {
+ case "sendMessage":
+ var msgToSend = queuedEvent;
+ self._sendMessage(channelID, msgToSend.content, msgToSend.tts, msgToSend.mentions).then(function (msg) {
+ msgToSend.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ msgToSend.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ case "sendFile":
+ var fileToSend = queuedEvent;
+ self._sendFile(channelID, fileToSend.attachment, fileToSend.attachmentName).then(function (msg) {
+ fileToSend.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ fileToSend.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ case "updateMessage":
+ var msgToUpd = queuedEvent;
+ self._updateMessage(msgToUpd.message, msgToUpd.content).then(function (msg) {
+ msgToUpd.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ msgToUpd.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ case "deleteMessage":
+ var msgToDel = queuedEvent;
+ self._deleteMessage(msgToDel.message).then(function (msg) {
+ msgToDel.then(msg);
+ self.queue[channelID].shift();
+ doNext();
+ })["catch"](function (err) {
+ msgToDel.error(err);
+ self.queue[channelID].shift();
+ doNext();
+ });
+ break;
+ default:
+ done();
+ break;
+ }
+ };
+
+ var done = function done() {
+ self.checkingQueue[channelID] = false;
+ return;
+ };
+
+ //if we aren't already checking this queue.
+ _this.checkingQueue[channelID] = true;
+ doNext();
+ })();
+ }
+ }
+ }, {
+ key: "getGateway",
+ value: function getGateway() {
+ var self = this;
+ return new Promise(function (resolve, reject) {
+ request.get(Endpoints.API + "/gateway").set("authorization", self.token).end(function (err, res) {
+ if (err) {
+ reject(err);
+ } else {
+ resolve(res.body.url);
+ }
+ });
+ });
+ }
+ }, {
+ key: "setStatusIdle",
+ value: function setStatusIdle() {
+ this.setStatus("idle");
+ }
+ }, {
+ key: "setStatusOnline",
+ value: function setStatusOnline() {
+ this.setStatus("online");
+ }
+ }, {
+ key: "setStatusActive",
+ value: function setStatusActive() {
+ this.setStatusOnline();
+ }
+ }, {
+ key: "setStatusHere",
+ value: function setStatusHere() {
+ this.setStatusOnline();
+ }
+ }, {
+ key: "setStatusAway",
+ value: function setStatusAway() {
+ this.setStatusIdle();
+ }
+ }, {
+ key: "startTyping",
+ value: function startTyping(chann, stopTypeTime) {
+ var self = this;
+
+ this.resolveDestination(chann).then(next);
+
+ function next(channel) {
+ if (self.typingIntervals[channel]) {
+ return;
+ }
+
+ var fn = function fn() {
+ request.post(Endpoints.CHANNELS + "/" + channel + "/typing").set("authorization", self.token).end();
+ };
+
+ fn();
+
+ var interval = setInterval(fn, 3000);
+
+ self.typingIntervals[channel] = interval;
+
+ if (stopTypeTime) {
+ setTimeout(function () {
+ self.stopTyping(channel);
+ }, stopTypeTime);
+ }
+ }
+ }
+ }, {
+ key: "stopTyping",
+ value: function stopTyping(chann) {
+ var self = this;
+
+ this.resolveDestination(chann).then(next);
+
+ function next(channel) {
+ if (!self.typingIntervals[channel]) {
+ return;
+ }
+
+ clearInterval(self.typingIntervals[channel]);
+
+ delete self.typingIntervals[channel];
+ }
+ }
+ }, {
+ key: "setStatus",
+ value: function setStatus(stat) {
+
+ var idleTime = stat === "online" ? null : Date.now();
+
+ this.__idleTime = idleTime;
+
+ this.websocket.send(JSON.stringify({
+ op: 3,
+ d: {
+ idle_since: this.__idleTime,
+ game_id: this.__gameId
+ }
+ }));
+ }
+ }, {
+ key: "setPlayingGame",
+ value: function setPlayingGame(id) {
+
+ if (id instanceof String || typeof id === "string") {
+
+ // working on names
+ var gid = id.trim().toUpperCase();
+
+ id = null;
+
+ var _iteratorNormalCompletion16 = true;
+ var _didIteratorError16 = false;
+ var _iteratorError16 = undefined;
+
+ try {
+ for (var _iterator16 = gameMap[Symbol.iterator](), _step16; !(_iteratorNormalCompletion16 = (_step16 = _iterator16.next()).done); _iteratorNormalCompletion16 = true) {
+ var game = _step16.value;
+
+ if (game.name.trim().toUpperCase() === gid) {
+
+ id = game.id;
+ break;
+ }
+ }
+ } catch (err) {
+ _didIteratorError16 = true;
+ _iteratorError16 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion16 && _iterator16["return"]) {
+ _iterator16["return"]();
+ }
+ } finally {
+ if (_didIteratorError16) {
+ throw _iteratorError16;
+ }
+ }
+ }
+ }
+
+ this.__gameId = id;
+
+ this.websocket.send(JSON.stringify({
+ op: 3,
+ d: {
+ idle_since: this.__idleTime,
+ game_id: this.__gameId
+ }
+ }));
+ }
+ }, {
+ key: "playGame",
+ value: function playGame(id) {
+ this.setPlayingGame(id);
+ }
+ }, {
+ key: "playingGame",
+ value: function playingGame(id) {
+
+ this.setPlayingGame(id);
+ }
+ }, {
+ key: "uptime",
+ get: function get() {
+
+ return this.readyTime ? Date.now() - this.readyTime : null;
+ }
+ }, {
+ key: "ready",
+ get: function get() {
+ return this.state === 3;
+ }
+ }, {
+ key: "servers",
+ get: function get() {
+ return this.serverCache;
+ }
+ }, {
+ key: "channels",
+ get: function get() {
+ return this.channelCache;
+ }
+ }, {
+ key: "users",
+ get: function get() {
+ return this.userCache;
+ }
+ }, {
+ key: "PMChannels",
+ get: function get() {
+ return this.pmChannelCache;
+ }
+ }, {
+ key: "messages",
+ get: function get() {
+
+ var msgs = [];
+ var _iteratorNormalCompletion17 = true;
+ var _didIteratorError17 = false;
+ var _iteratorError17 = undefined;
+
+ try {
+ for (var _iterator17 = this.channelCache[Symbol.iterator](), _step17; !(_iteratorNormalCompletion17 = (_step17 = _iterator17.next()).done); _iteratorNormalCompletion17 = true) {
+ var channel = _step17.value;
+
+ msgs = msgs.concat(channel.messages);
+ }
+ } catch (err) {
+ _didIteratorError17 = true;
+ _iteratorError17 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion17 && _iterator17["return"]) {
+ _iterator17["return"]();
+ }
+ } finally {
+ if (_didIteratorError17) {
+ throw _iteratorError17;
+ }
+ }
+ }
+
+ return msgs;
+ }
+ }]);
+
+ return Client;
+})();
+
+module.exports = Client;
+
+},{"../ref/gameMap.json":15,"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,"fs":10,"superagent":11,"ws":14}],2:[function(require,module,exports){
+"use strict";
+
+exports.BASE_DOMAIN = "discordapp.com";
+exports.BASE = "https://" + exports.BASE_DOMAIN;
+exports.WEBSOCKET_HUB = "wss://" + exports.BASE_DOMAIN + "/hub";
+
+exports.API = exports.BASE + "/api";
+exports.AUTH = exports.API + "/auth";
+exports.LOGIN = exports.AUTH + "/login";
+exports.LOGOUT = exports.AUTH + "/logout";
+exports.USERS = exports.API + "/users";
+exports.SERVERS = exports.API + "/guilds";
+exports.CHANNELS = exports.API + "/channels";
+
+},{}],3:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var PMChannel = (function () {
+ function PMChannel(data, client) {
+ _classCallCheck(this, PMChannel);
+
+ this.user = client.getUser("id", data.recipient.id);
+ this.id = data.id;
+ this.messages = [];
+ }
+
+ _createClass(PMChannel, [{
+ key: "addMessage",
+ value: function addMessage(data) {
+ if (!this.getMessage("id", data.id)) {
+ this.messages.push(data);
+ }
+ return this.getMessage("id", data.id);
+ }
+ }, {
+ key: "getMessage",
+ value: function getMessage(key, value) {
+
+ if (this.messages.length > 1000) {
+ this.messages.splice(0, 1);
+ }
+
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var message = _step.value;
+
+ if (message[key] === value) {
+ return message;
+ }
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator["return"]) {
+ _iterator["return"]();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+
+ return null;
+ }
+ }, {
+ key: "isPrivate",
+ get: function get() {
+ return true;
+ }
+ }]);
+
+ return PMChannel;
+})();
+
+module.exports = PMChannel;
+
+},{}],4:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Channel = (function () {
+ function Channel(data, server) {
+ _classCallCheck(this, Channel);
+
+ this.server = server;
+ this.name = data.name;
+ this.type = data.type;
+ this.topic = data.topic;
+ this.id = data.id;
+ this.messages = [];
+ //this.isPrivate = isPrivate; //not sure about the implementation of this...
+ }
+
+ _createClass(Channel, [{
+ key: "equals",
+ value: function equals(object) {
+ return object && object.id === this.id;
+ }
+ }, {
+ key: "addMessage",
+ value: function addMessage(data) {
+
+ if (this.messages.length > 1000) {
+ this.messages.splice(0, 1);
+ }
+
+ if (!this.getMessage("id", data.id)) {
+ this.messages.push(data);
+ }
+
+ return this.getMessage("id", data.id);
+ }
+ }, {
+ key: "getMessage",
+ value: function getMessage(key, value) {
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var message = _step.value;
+
+ if (message[key] === value) {
+ return message;
+ }
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator["return"]) {
+ _iterator["return"]();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+
+ return null;
+ }
+ }, {
+ key: "toString",
+ value: function toString() {
+ return "<#" + this.id + ">";
+ }
+ }, {
+ key: "client",
+ get: function get() {
+ return this.server.client;
+ }
+ }, {
+ key: "isPrivate",
+ get: function get() {
+ return false;
+ }
+ }, {
+ key: "users",
+ get: function get() {
+ return this.server.members;
+ }
+ }, {
+ key: "members",
+ get: function get() {
+ return this.server.members;
+ }
+ }]);
+
+ return Channel;
+})();
+
+module.exports = Channel;
+
+},{}],5:[function(require,module,exports){
+"use strict";
+
+var request = require("superagent");
+var Endpoints = require("./Endpoints.js");
+var Client = require("./Client.js");
+
+var Discord = {
+ Endpoints: Endpoints,
+ Client: Client
+};
+
+module.exports = Discord;
+
+},{"./Client.js":1,"./Endpoints.js":2,"superagent":11}],6:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Invite = (function () {
+ function Invite(data, client) {
+ _classCallCheck(this, Invite);
+
+ this.max_age = data.max_age;
+ this.code = data.code;
+ this.server = client.getServer("id", data.guild.id);
+ this.revoked = data.revoked;
+ this.created_at = Date.parse(data.created_at);
+ this.temporary = data.temporary;
+ this.uses = data.uses;
+ this.max_uses = data.uses;
+ this.inviter = client.addUser(data.inviter);
+ this.xkcd = data.xkcdpass;
+ this.channel = client.getChannel("id", data.channel.id);
+ }
+
+ _createClass(Invite, [{
+ key: "URL",
+ get: function get() {
+ var code = this.xkcd ? this.xkcdpass : this.code;
+ return "https://discord.gg/" + code;
+ }
+ }]);
+
+ return Invite;
+})();
+
+module.exports = Invite;
+
+},{}],7:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var PMChannel = require("./PMChannel.js");
+
+var Message = (function () {
+ function Message(data, channel, mentions, author) {
+ _classCallCheck(this, Message);
+
+ this.tts = data.tts;
+ this.timestamp = Date.parse(data.timestamp);
+ this.nonce = data.nonce;
+ this.mentions = mentions;
+ this.everyoneMentioned = data.mention_everyone;
+ this.id = data.id;
+ this.embeds = data.embeds;
+ this.editedTimestamp = data.edited_timestamp;
+ this.content = data.content.trim();
+ this.channel = channel;
+ this.author = author;
+ this.attachments = data.attachments;
+ }
+
+ /*exports.Message.prototype.isPM = function() {
+ return ( this.channel instanceof PMChannel );
+ }*/
+
+ _createClass(Message, [{
+ key: "isMentioned",
+ value: function isMentioned(user) {
+ var id = user.id ? user.id : user;
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = this.mentions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var mention = _step.value;
+
+ if (mention.id === id) {
+ return true;
+ }
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator["return"]) {
+ _iterator["return"]();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+
+ return false;
+ }
+ }, {
+ key: "sender",
+ get: function get() {
+ return this.author;
+ }
+ }, {
+ key: "isPrivate",
+ get: function get() {
+ return this.channel.isPrivate;
+ }
+ }]);
+
+ return Message;
+})();
+
+module.exports = Message;
+
+},{"./PMChannel.js":3}],8:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Server = (function () {
+ function Server(data, client) {
+ _classCallCheck(this, Server);
+
+ this.client = client;
+ this.region = data.region;
+ this.ownerID = data.owner_id;
+ this.name = data.name;
+ this.id = data.id;
+ this.members = [];
+ this.channels = [];
+ this.icon = data.icon;
+ this.afkTimeout = data.afk_timeout;
+ this.afkChannelId = data.afk_channel_id;
+
+ if (!data.members) {
+ data.members = [client.user];
+ return;
+ }
+
+ var _iteratorNormalCompletion = true;
+ var _didIteratorError = false;
+ var _iteratorError = undefined;
+
+ try {
+ for (var _iterator = data.members[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+ var member = _step.value;
+
+ // first we cache the user in our Discord Client,
+ // then we add it to our list. This way when we
+ // get a user from this server's member list,
+ // it will be identical (unless an async change occurred)
+ // to the client's cache.
+ if (member.user) this.members.push(client.addUser(member.user));
+ }
+ } catch (err) {
+ _didIteratorError = true;
+ _iteratorError = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion && _iterator["return"]) {
+ _iterator["return"]();
+ }
+ } finally {
+ if (_didIteratorError) {
+ throw _iteratorError;
+ }
+ }
+ }
+ }
+
+ _createClass(Server, [{
+ key: "getChannel",
+
+ // get/set
+ value: function getChannel(key, value) {
+ var _iteratorNormalCompletion2 = true;
+ var _didIteratorError2 = false;
+ var _iteratorError2 = undefined;
+
+ try {
+ for (var _iterator2 = this.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
+ var channel = _step2.value;
+
+ if (channel[key] === value) {
+ return channel;
+ }
+ }
+ } catch (err) {
+ _didIteratorError2 = true;
+ _iteratorError2 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion2 && _iterator2["return"]) {
+ _iterator2["return"]();
+ }
+ } finally {
+ if (_didIteratorError2) {
+ throw _iteratorError2;
+ }
+ }
+ }
+
+ return null;
+ }
+ }, {
+ key: "getMember",
+ value: function getMember(key, value) {
+ var _iteratorNormalCompletion3 = true;
+ var _didIteratorError3 = false;
+ var _iteratorError3 = undefined;
+
+ try {
+ for (var _iterator3 = this.members[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
+ var member = _step3.value;
+
+ if (member[key] === value) {
+ return member;
+ }
+ }
+ } catch (err) {
+ _didIteratorError3 = true;
+ _iteratorError3 = err;
+ } finally {
+ try {
+ if (!_iteratorNormalCompletion3 && _iterator3["return"]) {
+ _iterator3["return"]();
+ }
+ } finally {
+ if (_didIteratorError3) {
+ throw _iteratorError3;
+ }
+ }
+ }
+
+ return null;
+ }
+ }, {
+ key: "addChannel",
+ value: function addChannel(chann) {
+ if (!this.getChannel("id", chann.id)) {
+ this.channels.push(chann);
+ }
+ return chann;
+ }
+ }, {
+ key: "addMember",
+ value: function addMember(member) {
+ if (!this.getMember("id", member.id)) {
+ this.members.push(member);
+ }
+ return member;
+ }
+ }, {
+ key: "toString",
+ value: function toString() {
+ return this.name;
+ }
+ }, {
+ key: "equals",
+ value: function equals(object) {
+ return object.id === this.id;
+ }
+ }, {
+ key: "iconURL",
+ get: function get() {
+ if (!this.icon) return null;
+ return "https://discordapp.com/api/guilds/" + this.id + "/icons/" + this.icon + ".jpg";
+ }
+ }, {
+ key: "afkChannel",
+ get: function get() {
+ if (!this.afkChannelId) return false;
+
+ return this.getChannel("id", this.afkChannelId);
+ }
+ }, {
+ key: "defaultChannel",
+ get: function get() {
+ return this.getChannel("name", "general");
+ }
+ }, {
+ key: "owner",
+ get: function get() {
+ return this.client.getUser("id", this.ownerID);
+ }
+ }, {
+ key: "users",
+ get: function get() {
+ return this.members;
+ }
+ }]);
+
+ return Server;
+})();
+
+module.exports = Server;
+
+},{}],9:[function(require,module,exports){
+"use strict";
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var User = (function () {
+ function User(data) {
+ _classCallCheck(this, User);
+
+ this.username = data.username;
+ this.discriminator = data.discriminator;
+ this.id = data.id;
+ this.avatar = data.avatar;
+ this.status = "offline";
+ }
+
+ // access using user.avatarURL;
+
+ _createClass(User, [{
+ key: "mention",
+ value: function mention() {
+ return "<@" + this.id + ">";
+ }
+ }, {
+ key: "toString",
+ value: function toString() {
+ /*
+ if we embed a user in a String - like so:
+ "Yo " + user + " what's up?"
+ It would generate something along the lines of:
+ "Yo @hydrabolt what's up?"
+ */
+ return this.mention();
+ }
+ }, {
+ key: "equals",
+ value: function equals(object) {
+ return object.id === this.id;
+ }
+ }, {
+ key: "equalsStrict",
+ value: function equalsStrict(object) {
+ return object.id === this.id && object.avatar === this.avatar && object.username === this.username && object.discriminator === this.discriminator;
+ }
+ }, {
+ key: "avatarURL",
+ get: function get() {
+ if (!this.avatar) return null;
+ return "https://discordapp.com/api/users/" + this.id + "/avatars/" + this.avatar + ".jpg";
+ }
+ }]);
+
+ return User;
+})();
+
+module.exports = User;
+
+},{}],10:[function(require,module,exports){
+
+},{}],11:[function(require,module,exports){
+/**
+ * Module dependencies.
+ */
+
+var Emitter = require('emitter');
+var reduce = require('reduce');
+
+/**
+ * Root reference for iframes.
+ */
+
+var root = 'undefined' == typeof window
+ ? (this || self)
+ : window;
+
+/**
+ * Noop.
+ */
+
+function noop(){};
+
+/**
+ * Check if `obj` is a host object,
+ * we don't want to serialize these :)
+ *
+ * TODO: future proof, move to compoent land
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api private
+ */
+
+function isHost(obj) {
+ var str = {}.toString.call(obj);
+
+ switch (str) {
+ case '[object File]':
+ case '[object Blob]':
+ case '[object FormData]':
+ return true;
+ default:
+ return false;
+ }
+}
+
+/**
+ * Determine XHR.
+ */
+
+request.getXHR = function () {
+ if (root.XMLHttpRequest
+ && (!root.location || 'file:' != root.location.protocol
+ || !root.ActiveXObject)) {
+ return new XMLHttpRequest;
+ } else {
+ try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
+ }
+ return false;
+};
+
+/**
+ * Removes leading and trailing whitespace, added to support IE.
+ *
+ * @param {String} s
+ * @return {String}
+ * @api private
+ */
+
+var trim = ''.trim
+ ? function(s) { return s.trim(); }
+ : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); };
+
+/**
+ * Check if `obj` is an object.
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api private
+ */
+
+function isObject(obj) {
+ return obj === Object(obj);
+}
+
+/**
+ * Serialize the given `obj`.
+ *
+ * @param {Object} obj
+ * @return {String}
+ * @api private
+ */
+
+function serialize(obj) {
+ if (!isObject(obj)) return obj;
+ var pairs = [];
+ for (var key in obj) {
+ if (null != obj[key]) {
+ pairs.push(encodeURIComponent(key)
+ + '=' + encodeURIComponent(obj[key]));
+ }
+ }
+ return pairs.join('&');
+}
+
+/**
+ * Expose serialization method.
+ */
+
+ request.serializeObject = serialize;
+
+ /**
+ * Parse the given x-www-form-urlencoded `str`.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function parseString(str) {
+ var obj = {};
+ var pairs = str.split('&');
+ var parts;
+ var pair;
+
+ for (var i = 0, len = pairs.length; i < len; ++i) {
+ pair = pairs[i];
+ parts = pair.split('=');
+ obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
+ }
+
+ return obj;
+}
+
+/**
+ * Expose parser.
+ */
+
+request.parseString = parseString;
+
+/**
+ * Default MIME type map.
+ *
+ * superagent.types.xml = 'application/xml';
+ *
+ */
+
+request.types = {
+ html: 'text/html',
+ json: 'application/json',
+ xml: 'application/xml',
+ urlencoded: 'application/x-www-form-urlencoded',
+ 'form': 'application/x-www-form-urlencoded',
+ 'form-data': 'application/x-www-form-urlencoded'
+};
+
+/**
+ * Default serialization map.
+ *
+ * superagent.serialize['application/xml'] = function(obj){
+ * return 'generated xml here';
+ * };
+ *
+ */
+
+ request.serialize = {
+ 'application/x-www-form-urlencoded': serialize,
+ 'application/json': JSON.stringify
+ };
+
+ /**
+ * Default parsers.
+ *
+ * superagent.parse['application/xml'] = function(str){
+ * return { object parsed from str };
+ * };
+ *
+ */
+
+request.parse = {
+ 'application/x-www-form-urlencoded': parseString,
+ 'application/json': JSON.parse
+};
+
+/**
+ * Parse the given header `str` into
+ * an object containing the mapped fields.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function parseHeader(str) {
+ var lines = str.split(/\r?\n/);
+ var fields = {};
+ var index;
+ var line;
+ var field;
+ var val;
+
+ lines.pop(); // trailing CRLF
+
+ for (var i = 0, len = lines.length; i < len; ++i) {
+ line = lines[i];
+ index = line.indexOf(':');
+ field = line.slice(0, index).toLowerCase();
+ val = trim(line.slice(index + 1));
+ fields[field] = val;
+ }
+
+ return fields;
+}
+
+/**
+ * Return the mime type for the given `str`.
+ *
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+function type(str){
+ return str.split(/ *; */).shift();
+};
+
+/**
+ * Return header field parameters.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function params(str){
+ return reduce(str.split(/ *; */), function(obj, str){
+ var parts = str.split(/ *= */)
+ , key = parts.shift()
+ , val = parts.shift();
+
+ if (key && val) obj[key] = val;
+ return obj;
+ }, {});
+};
+
+/**
+ * Initialize a new `Response` with the given `xhr`.
+ *
+ * - set flags (.ok, .error, etc)
+ * - parse header
+ *
+ * Examples:
+ *
+ * Aliasing `superagent` as `request` is nice:
+ *
+ * request = superagent;
+ *
+ * We can use the promise-like API, or pass callbacks:
+ *
+ * request.get('/').end(function(res){});
+ * request.get('/', function(res){});
+ *
+ * Sending data can be chained:
+ *
+ * request
+ * .post('/user')
+ * .send({ name: 'tj' })
+ * .end(function(res){});
+ *
+ * Or passed to `.send()`:
+ *
+ * request
+ * .post('/user')
+ * .send({ name: 'tj' }, function(res){});
+ *
+ * Or passed to `.post()`:
+ *
+ * request
+ * .post('/user', { name: 'tj' })
+ * .end(function(res){});
+ *
+ * Or further reduced to a single call for simple cases:
+ *
+ * request
+ * .post('/user', { name: 'tj' }, function(res){});
+ *
+ * @param {XMLHTTPRequest} xhr
+ * @param {Object} options
+ * @api private
+ */
+
+function Response(req, options) {
+ options = options || {};
+ this.req = req;
+ this.xhr = this.req.xhr;
+ // responseText is accessible only if responseType is '' or 'text' and on older browsers
+ this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined')
+ ? this.xhr.responseText
+ : null;
+ this.statusText = this.req.xhr.statusText;
+ this.setStatusProperties(this.xhr.status);
+ this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders());
+ // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but
+ // getResponseHeader still works. so we get content-type even if getting
+ // other headers fails.
+ this.header['content-type'] = this.xhr.getResponseHeader('content-type');
+ this.setHeaderProperties(this.header);
+ this.body = this.req.method != 'HEAD'
+ ? this.parseBody(this.text ? this.text : this.xhr.response)
+ : null;
+}
+
+/**
+ * Get case-insensitive `field` value.
+ *
+ * @param {String} field
+ * @return {String}
+ * @api public
+ */
+
+Response.prototype.get = function(field){
+ return this.header[field.toLowerCase()];
+};
+
+/**
+ * Set header related properties:
+ *
+ * - `.type` the content type without params
+ *
+ * A response of "Content-Type: text/plain; charset=utf-8"
+ * will provide you with a `.type` of "text/plain".
+ *
+ * @param {Object} header
+ * @api private
+ */
+
+Response.prototype.setHeaderProperties = function(header){
+ // content-type
+ var ct = this.header['content-type'] || '';
+ this.type = type(ct);
+
+ // params
+ var obj = params(ct);
+ for (var key in obj) this[key] = obj[key];
+};
+
+/**
+ * Parse the given body `str`.
+ *
+ * Used for auto-parsing of bodies. Parsers
+ * are defined on the `superagent.parse` object.
+ *
+ * @param {String} str
+ * @return {Mixed}
+ * @api private
+ */
+
+Response.prototype.parseBody = function(str){
+ var parse = request.parse[this.type];
+ return parse && str && (str.length || str instanceof Object)
+ ? parse(str)
+ : null;
+};
+
+/**
+ * Set flags such as `.ok` based on `status`.
+ *
+ * For example a 2xx response will give you a `.ok` of __true__
+ * whereas 5xx will be __false__ and `.error` will be __true__. The
+ * `.clientError` and `.serverError` are also available to be more
+ * specific, and `.statusType` is the class of error ranging from 1..5
+ * sometimes useful for mapping respond colors etc.
+ *
+ * "sugar" properties are also defined for common cases. Currently providing:
+ *
+ * - .noContent
+ * - .badRequest
+ * - .unauthorized
+ * - .notAcceptable
+ * - .notFound
+ *
+ * @param {Number} status
+ * @api private
+ */
+
+Response.prototype.setStatusProperties = function(status){
+ // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
+ if (status === 1223) {
+ status = 204;
+ }
+
+ var type = status / 100 | 0;
+
+ // status / class
+ this.status = status;
+ this.statusType = type;
+
+ // basics
+ this.info = 1 == type;
+ this.ok = 2 == type;
+ this.clientError = 4 == type;
+ this.serverError = 5 == type;
+ this.error = (4 == type || 5 == type)
+ ? this.toError()
+ : false;
+
+ // sugar
+ this.accepted = 202 == status;
+ this.noContent = 204 == status;
+ this.badRequest = 400 == status;
+ this.unauthorized = 401 == status;
+ this.notAcceptable = 406 == status;
+ this.notFound = 404 == status;
+ this.forbidden = 403 == status;
+};
+
+/**
+ * Return an `Error` representative of this response.
+ *
+ * @return {Error}
+ * @api public
+ */
+
+Response.prototype.toError = function(){
+ var req = this.req;
+ var method = req.method;
+ var url = req.url;
+
+ var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')';
+ var err = new Error(msg);
+ err.status = this.status;
+ err.method = method;
+ err.url = url;
+
+ return err;
+};
+
+/**
+ * Expose `Response`.
+ */
+
+request.Response = Response;
+
+/**
+ * Initialize a new `Request` with the given `method` and `url`.
+ *
+ * @param {String} method
+ * @param {String} url
+ * @api public
+ */
+
+function Request(method, url) {
+ var self = this;
+ Emitter.call(this);
+ this._query = this._query || [];
+ this.method = method;
+ this.url = url;
+ this.header = {};
+ this._header = {};
+ this.on('end', function(){
+ var err = null;
+ var res = null;
+
+ try {
+ res = new Response(self);
+ } catch(e) {
+ err = new Error('Parser is unable to parse the response');
+ err.parse = true;
+ err.original = e;
+ return self.callback(err);
+ }
+
+ self.emit('response', res);
+
+ if (err) {
+ return self.callback(err, res);
+ }
+
+ if (res.status >= 200 && res.status < 300) {
+ return self.callback(err, res);
+ }
+
+ var new_err = new Error(res.statusText || 'Unsuccessful HTTP response');
+ new_err.original = err;
+ new_err.response = res;
+ new_err.status = res.status;
+
+ self.callback(new_err, res);
+ });
+}
+
+/**
+ * Mixin `Emitter`.
+ */
+
+Emitter(Request.prototype);
+
+/**
+ * Allow for extension
+ */
+
+Request.prototype.use = function(fn) {
+ fn(this);
+ return this;
+}
+
+/**
+ * Set timeout to `ms`.
+ *
+ * @param {Number} ms
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.timeout = function(ms){
+ this._timeout = ms;
+ return this;
+};
+
+/**
+ * Clear previous timeout.
+ *
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.clearTimeout = function(){
+ this._timeout = 0;
+ clearTimeout(this._timer);
+ return this;
+};
+
+/**
+ * Abort the request, and clear potential timeout.
+ *
+ * @return {Request}
+ * @api public
+ */
+
+Request.prototype.abort = function(){
+ if (this.aborted) return;
+ this.aborted = true;
+ this.xhr.abort();
+ this.clearTimeout();
+ this.emit('abort');
+ return this;
+};
+
+/**
+ * Set header `field` to `val`, or multiple fields with one object.
+ *
+ * Examples:
+ *
+ * req.get('/')
+ * .set('Accept', 'application/json')
+ * .set('X-API-Key', 'foobar')
+ * .end(callback);
+ *
+ * req.get('/')
+ * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
+ * .end(callback);
+ *
+ * @param {String|Object} field
+ * @param {String} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.set = function(field, val){
+ if (isObject(field)) {
+ for (var key in field) {
+ this.set(key, field[key]);
+ }
+ return this;
+ }
+ this._header[field.toLowerCase()] = val;
+ this.header[field] = val;
+ return this;
+};
+
+/**
+ * Remove header `field`.
+ *
+ * Example:
+ *
+ * req.get('/')
+ * .unset('User-Agent')
+ * .end(callback);
+ *
+ * @param {String} field
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.unset = function(field){
+ delete this._header[field.toLowerCase()];
+ delete this.header[field];
+ return this;
+};
+
+/**
+ * Get case-insensitive header `field` value.
+ *
+ * @param {String} field
+ * @return {String}
+ * @api private
+ */
+
+Request.prototype.getHeader = function(field){
+ return this._header[field.toLowerCase()];
+};
+
+/**
+ * Set Content-Type to `type`, mapping values from `request.types`.
+ *
+ * Examples:
+ *
+ * superagent.types.xml = 'application/xml';
+ *
+ * request.post('/')
+ * .type('xml')
+ * .send(xmlstring)
+ * .end(callback);
+ *
+ * request.post('/')
+ * .type('application/xml')
+ * .send(xmlstring)
+ * .end(callback);
+ *
+ * @param {String} type
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.type = function(type){
+ this.set('Content-Type', request.types[type] || type);
+ return this;
+};
+
+/**
+ * Set Accept to `type`, mapping values from `request.types`.
+ *
+ * Examples:
+ *
+ * superagent.types.json = 'application/json';
+ *
+ * request.get('/agent')
+ * .accept('json')
+ * .end(callback);
+ *
+ * request.get('/agent')
+ * .accept('application/json')
+ * .end(callback);
+ *
+ * @param {String} accept
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.accept = function(type){
+ this.set('Accept', request.types[type] || type);
+ return this;
+};
+
+/**
+ * Set Authorization field value with `user` and `pass`.
+ *
+ * @param {String} user
+ * @param {String} pass
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.auth = function(user, pass){
+ var str = btoa(user + ':' + pass);
+ this.set('Authorization', 'Basic ' + str);
+ return this;
+};
+
+/**
+* Add query-string `val`.
+*
+* Examples:
+*
+* request.get('/shoes')
+* .query('size=10')
+* .query({ color: 'blue' })
+*
+* @param {Object|String} val
+* @return {Request} for chaining
+* @api public
+*/
+
+Request.prototype.query = function(val){
+ if ('string' != typeof val) val = serialize(val);
+ if (val) this._query.push(val);
+ return this;
+};
+
+/**
+ * Write the field `name` and `val` for "multipart/form-data"
+ * request bodies.
+ *
+ * ``` js
+ * request.post('/upload')
+ * .field('foo', 'bar')
+ * .end(callback);
+ * ```
+ *
+ * @param {String} name
+ * @param {String|Blob|File} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.field = function(name, val){
+ if (!this._formData) this._formData = new root.FormData();
+ this._formData.append(name, val);
+ return this;
+};
+
+/**
+ * Queue the given `file` as an attachment to the specified `field`,
+ * with optional `filename`.
+ *
+ * ``` js
+ * request.post('/upload')
+ * .attach(new Blob(['hey!'], { type: "text/html"}))
+ * .end(callback);
+ * ```
+ *
+ * @param {String} field
+ * @param {Blob|File} file
+ * @param {String} filename
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.attach = function(field, file, filename){
+ if (!this._formData) this._formData = new root.FormData();
+ this._formData.append(field, file, filename);
+ return this;
+};
+
+/**
+ * Send `data`, defaulting the `.type()` to "json" when
+ * an object is given.
+ *
+ * Examples:
+ *
+ * // querystring
+ * request.get('/search')
+ * .end(callback)
+ *
+ * // multiple data "writes"
+ * request.get('/search')
+ * .send({ search: 'query' })
+ * .send({ range: '1..5' })
+ * .send({ order: 'desc' })
+ * .end(callback)
+ *
+ * // manual json
+ * request.post('/user')
+ * .type('json')
+ * .send('{"name":"tj"})
+ * .end(callback)
+ *
+ * // auto json
+ * request.post('/user')
+ * .send({ name: 'tj' })
+ * .end(callback)
+ *
+ * // manual x-www-form-urlencoded
+ * request.post('/user')
+ * .type('form')
+ * .send('name=tj')
+ * .end(callback)
+ *
+ * // auto x-www-form-urlencoded
+ * request.post('/user')
+ * .type('form')
+ * .send({ name: 'tj' })
+ * .end(callback)
+ *
+ * // defaults to x-www-form-urlencoded
+ * request.post('/user')
+ * .send('name=tobi')
+ * .send('species=ferret')
+ * .end(callback)
+ *
+ * @param {String|Object} data
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.send = function(data){
+ var obj = isObject(data);
+ var type = this.getHeader('Content-Type');
+
+ // merge
+ if (obj && isObject(this._data)) {
+ for (var key in data) {
+ this._data[key] = data[key];
+ }
+ } else if ('string' == typeof data) {
+ if (!type) this.type('form');
+ type = this.getHeader('Content-Type');
+ if ('application/x-www-form-urlencoded' == type) {
+ this._data = this._data
+ ? this._data + '&' + data
+ : data;
+ } else {
+ this._data = (this._data || '') + data;
+ }
+ } else {
+ this._data = data;
+ }
+
+ if (!obj || isHost(data)) return this;
+ if (!type) this.type('json');
+ return this;
+};
+
+/**
+ * Invoke the callback with `err` and `res`
+ * and handle arity check.
+ *
+ * @param {Error} err
+ * @param {Response} res
+ * @api private
+ */
+
+Request.prototype.callback = function(err, res){
+ var fn = this._callback;
+ this.clearTimeout();
+ fn(err, res);
+};
+
+/**
+ * Invoke callback with x-domain error.
+ *
+ * @api private
+ */
+
+Request.prototype.crossDomainError = function(){
+ var err = new Error('Origin is not allowed by Access-Control-Allow-Origin');
+ err.crossDomain = true;
+ this.callback(err);
+};
+
+/**
+ * Invoke callback with timeout error.
+ *
+ * @api private
+ */
+
+Request.prototype.timeoutError = function(){
+ var timeout = this._timeout;
+ var err = new Error('timeout of ' + timeout + 'ms exceeded');
+ err.timeout = timeout;
+ this.callback(err);
+};
+
+/**
+ * Enable transmission of cookies with x-domain requests.
+ *
+ * Note that for this to work the origin must not be
+ * using "Access-Control-Allow-Origin" with a wildcard,
+ * and also must set "Access-Control-Allow-Credentials"
+ * to "true".
+ *
+ * @api public
+ */
+
+Request.prototype.withCredentials = function(){
+ this._withCredentials = true;
+ return this;
+};
+
+/**
+ * Initiate request, invoking callback `fn(res)`
+ * with an instanceof `Response`.
+ *
+ * @param {Function} fn
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.end = function(fn){
+ var self = this;
+ var xhr = this.xhr = request.getXHR();
+ var query = this._query.join('&');
+ var timeout = this._timeout;
+ var data = this._formData || this._data;
+
+ // store callback
+ this._callback = fn || noop;
+
+ // state change
+ xhr.onreadystatechange = function(){
+ if (4 != xhr.readyState) return;
+
+ // In IE9, reads to any property (e.g. status) off of an aborted XHR will
+ // result in the error "Could not complete the operation due to error c00c023f"
+ var status;
+ try { status = xhr.status } catch(e) { status = 0; }
+
+ if (0 == status) {
+ if (self.timedout) return self.timeoutError();
+ if (self.aborted) return;
+ return self.crossDomainError();
+ }
+ self.emit('end');
+ };
+
+ // progress
+ var handleProgress = function(e){
+ if (e.total > 0) {
+ e.percent = e.loaded / e.total * 100;
+ }
+ self.emit('progress', e);
+ };
+ if (this.hasListeners('progress')) {
+ xhr.onprogress = handleProgress;
+ }
+ try {
+ if (xhr.upload && this.hasListeners('progress')) {
+ xhr.upload.onprogress = handleProgress;
+ }
+ } catch(e) {
+ // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist.
+ // Reported here:
+ // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context
+ }
+
+ // timeout
+ if (timeout && !this._timer) {
+ this._timer = setTimeout(function(){
+ self.timedout = true;
+ self.abort();
+ }, timeout);
+ }
+
+ // querystring
+ if (query) {
+ query = request.serializeObject(query);
+ this.url += ~this.url.indexOf('?')
+ ? '&' + query
+ : '?' + query;
+ }
+
+ // initiate request
+ xhr.open(this.method, this.url, true);
+
+ // CORS
+ if (this._withCredentials) xhr.withCredentials = true;
+
+ // body
+ if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) {
+ // serialize stuff
+ var contentType = this.getHeader('Content-Type');
+ var serialize = request.serialize[contentType ? contentType.split(';')[0] : ''];
+ if (serialize) data = serialize(data);
+ }
+
+ // set header fields
+ for (var field in this.header) {
+ if (null == this.header[field]) continue;
+ xhr.setRequestHeader(field, this.header[field]);
+ }
+
+ // send stuff
+ this.emit('request', this);
+ xhr.send(data);
+ return this;
+};
+
+/**
+ * Faux promise support
+ *
+ * @param {Function} fulfill
+ * @param {Function} reject
+ * @return {Request}
+ */
+
+Request.prototype.then = function (fulfill, reject) {
+ return this.end(function(err, res) {
+ err ? reject(err) : fulfill(res);
+ });
+}
+
+/**
+ * Expose `Request`.
+ */
+
+request.Request = Request;
+
+/**
+ * Issue a request:
+ *
+ * Examples:
+ *
+ * request('GET', '/users').end(callback)
+ * request('/users').end(callback)
+ * request('/users', callback)
+ *
+ * @param {String} method
+ * @param {String|Function} url or callback
+ * @return {Request}
+ * @api public
+ */
+
+function request(method, url) {
+ // callback
+ if ('function' == typeof url) {
+ return new Request('GET', method).end(url);
+ }
+
+ // url first
+ if (1 == arguments.length) {
+ return new Request('GET', method);
+ }
+
+ return new Request(method, url);
+}
+
+/**
+ * GET `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.get = function(url, data, fn){
+ var req = request('GET', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.query(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * HEAD `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.head = function(url, data, fn){
+ var req = request('HEAD', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * DELETE `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.del = function(url, fn){
+ var req = request('DELETE', url);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * PATCH `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} data
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.patch = function(url, data, fn){
+ var req = request('PATCH', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * POST `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} data
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.post = function(url, data, fn){
+ var req = request('POST', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * PUT `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.put = function(url, data, fn){
+ var req = request('PUT', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * Expose `request`.
+ */
+
+module.exports = request;
+
+},{"emitter":12,"reduce":13}],12:[function(require,module,exports){
+
+/**
+ * Expose `Emitter`.
+ */
+
+module.exports = Emitter;
+
+/**
+ * Initialize a new `Emitter`.
+ *
+ * @api public
+ */
+
+function Emitter(obj) {
+ if (obj) return mixin(obj);
+};
+
+/**
+ * Mixin the emitter properties.
+ *
+ * @param {Object} obj
+ * @return {Object}
+ * @api private
+ */
+
+function mixin(obj) {
+ for (var key in Emitter.prototype) {
+ obj[key] = Emitter.prototype[key];
+ }
+ return obj;
+}
+
+/**
+ * Listen on the given `event` with `fn`.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.on =
+Emitter.prototype.addEventListener = function(event, fn){
+ this._callbacks = this._callbacks || {};
+ (this._callbacks[event] = this._callbacks[event] || [])
+ .push(fn);
+ return this;
+};
+
+/**
+ * Adds an `event` listener that will be invoked a single
+ * time then automatically removed.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.once = function(event, fn){
+ var self = this;
+ this._callbacks = this._callbacks || {};
+
+ function on() {
+ self.off(event, on);
+ fn.apply(this, arguments);
+ }
+
+ on.fn = fn;
+ this.on(event, on);
+ return this;
+};
+
+/**
+ * Remove the given callback for `event` or all
+ * registered callbacks.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.off =
+Emitter.prototype.removeListener =
+Emitter.prototype.removeAllListeners =
+Emitter.prototype.removeEventListener = function(event, fn){
+ this._callbacks = this._callbacks || {};
+
+ // all
+ if (0 == arguments.length) {
+ this._callbacks = {};
+ return this;
+ }
+
+ // specific event
+ var callbacks = this._callbacks[event];
+ if (!callbacks) return this;
+
+ // remove all handlers
+ if (1 == arguments.length) {
+ delete this._callbacks[event];
+ return this;
+ }
+
+ // remove specific handler
+ var cb;
+ for (var i = 0; i < callbacks.length; i++) {
+ cb = callbacks[i];
+ if (cb === fn || cb.fn === fn) {
+ callbacks.splice(i, 1);
+ break;
+ }
+ }
+ return this;
+};
+
+/**
+ * Emit `event` with the given args.
+ *
+ * @param {String} event
+ * @param {Mixed} ...
+ * @return {Emitter}
+ */
+
+Emitter.prototype.emit = function(event){
+ this._callbacks = this._callbacks || {};
+ var args = [].slice.call(arguments, 1)
+ , callbacks = this._callbacks[event];
+
+ if (callbacks) {
+ callbacks = callbacks.slice(0);
+ for (var i = 0, len = callbacks.length; i < len; ++i) {
+ callbacks[i].apply(this, args);
+ }
+ }
+
+ return this;
+};
+
+/**
+ * Return array of callbacks for `event`.
+ *
+ * @param {String} event
+ * @return {Array}
+ * @api public
+ */
+
+Emitter.prototype.listeners = function(event){
+ this._callbacks = this._callbacks || {};
+ return this._callbacks[event] || [];
+};
+
+/**
+ * Check if this emitter has `event` handlers.
+ *
+ * @param {String} event
+ * @return {Boolean}
+ * @api public
+ */
+
+Emitter.prototype.hasListeners = function(event){
+ return !! this.listeners(event).length;
+};
+
+},{}],13:[function(require,module,exports){
+
+/**
+ * Reduce `arr` with `fn`.
+ *
+ * @param {Array} arr
+ * @param {Function} fn
+ * @param {Mixed} initial
+ *
+ * TODO: combatible error handling?
+ */
+
+module.exports = function(arr, fn, initial){
+ var idx = 0;
+ var len = arr.length;
+ var curr = arguments.length == 3
+ ? initial
+ : arr[idx++];
+
+ while (idx < len) {
+ curr = fn.call(null, curr, arr[idx], ++idx, arr);
+ }
+
+ return curr;
+};
+},{}],14:[function(require,module,exports){
+
+/**
+ * Module dependencies.
+ */
+
+var global = (function() { return this; })();
+
+/**
+ * WebSocket constructor.
+ */
+
+var WebSocket = global.WebSocket || global.MozWebSocket;
+
+/**
+ * Module exports.
+ */
+
+module.exports = WebSocket ? ws : null;
+
+/**
+ * WebSocket constructor.
+ *
+ * The third `opts` options object gets ignored in web browsers, since it's
+ * non-standard, and throws a TypeError if passed to the constructor.
+ * See: https://github.com/einaros/ws/issues/227
+ *
+ * @param {String} uri
+ * @param {Array} protocols (optional)
+ * @param {Object) opts (optional)
+ * @api public
+ */
+
+function ws(uri, protocols, opts) {
+ var instance;
+ if (protocols) {
+ instance = new WebSocket(uri, protocols);
+ } else {
+ instance = new WebSocket(uri);
+ }
+ return instance;
+}
+
+if (WebSocket) ws.prototype = WebSocket.prototype;
+
+},{}],15:[function(require,module,exports){
+module.exports=[{"executables":{"win32":["pol.exe"]},"id":0,"name":"FINAL FANTASY XI"},{"executables":{"win32":["ffxiv.exe","ffxiv_dx11.exe"]},"id":1,"name":"FINAL FANTASY XIV"},{"executables":{"win32":["Wow.exe","Wow-64.exe"]},"id":3,"name":"World of Warcraft"},{"executables":{"darwin":["LoLLauncher.app"],"win32":["LolClient.exe","League of Legends.exe"]},"id":4,"name":"League of Legends"},{"executables":{"darwin":["Diablo%20III.app"],"win32":["Diablo III.exe"]},"id":5,"name":"Diablo 3"},{"executables":{"darwin":["dota_osx.app"],"win32":["dota2.exe"]},"id":6,"name":"DOTA 2"},{"executables":{"darwin":["Heroes.app"],"win32":["Heroes of the Storm.exe","HeroesOfTheStorm_x64.exe","HeroesOfTheStorm.exe"]},"id":7,"name":"Heroes of the Storm"},{"executables":{"darwin":["Hearthstone.app"],"win32":["Hearthstone.exe"]},"id":8,"name":"Hearthstone"},{"executables":{"win32":["csgo.exe"]},"id":9,"name":"Counter-Strike: Global Offensive"},{"executables":{"win32":["WorldOfTanks.exe"]},"id":10,"name":"World of Tanks"},{"executables":{"darwin":["gw2.app"],"win32":["gw2.exe"]},"id":11,"name":"Guild Wars 2"},{"executables":{"win32":["dayz.exe"]},"id":12,"name":"Day Z"},{"executables":{"darwin":["starcraft%20ii.app"],"win32":["starcraft ii.exe","SC2_x64.exe","SC2.exe"]},"id":13,"name":"Starcraft II"},{"executables":{"win32":["diablo.exe"]},"id":14,"name":"Diablo"},{"executables":{"win32":["diablo ii.exe"]},"id":15,"name":"Diablo 2"},{"executables":{"win32":["left4dead.exe"]},"id":17,"name":"Left 4 Dead"},{"executables":{"darwin":["minecraft.app"],"win32":["minecraft.exe"]},"id":18,"name":"Minecraft"},{"executables":{"win32":["smite.exe"]},"id":19,"name":"Smite"},{"executables":{"win32":["bf4.exe"]},"id":20,"name":"Battlefield 4"},{"executables":{"win32":["AoK HD.exe","empires2.exe"]},"id":101,"name":"Age of Empire II"},{"executables":{"win32":["age3y.exe"]},"id":102,"name":"Age of Empire III"},{"executables":{"win32":["AlanWake.exe"]},"id":104,"name":"Alan Wake"},{"executables":{"win32":["alan_wakes_american_nightmare.exe"]},"id":105,"name":"Alan Wake's American Nightmare"},{"executables":{"win32":["AlienBreed2Assault.exe"]},"id":106,"name":"Alien Breed 2: Assault"},{"executables":{"win32":["Amnesia.exe"]},"id":107,"name":"Amnesia: The Dark Descent"},{"executables":{"win32":["UDK.exe"]},"id":108,"name":"Antichamber"},{"executables":{"win32":["ArcheAge.exe"]},"id":109,"name":"ArcheAge"},{"executables":{"win32":["arma3.exe"]},"id":110,"name":"Arma III"},{"executables":{"win32":["AC3SP.exe"]},"id":111,"name":"Assassin's Creed 3"},{"executables":{"win32":["Bastion.exe"]},"id":112,"name":"Bastion"},{"executables":{"win32":["BF2.exe"]},"id":113,"name":"Battlefield 2"},{"executables":{"win32":["bf3.exe"]},"id":114,"name":"Battlefield 3"},{"executables":{"win32":["Besiege.exe"]},"id":116,"name":"Besiege"},{"executables":{"win32":["Bioshock.exe"]},"id":117,"name":"Bioshock"},{"executables":{"win32":["Bioshock2.exe"]},"id":118,"name":"BioShock II"},{"executables":{"win32":["BioShockInfinite.exe"]},"id":119,"name":"BioShock Infinite"},{"executables":{"win32":["Borderlands2.exe"]},"id":122,"name":"Borderlands 2"},{"executables":{"win32":["braid.exe"]},"id":123,"name":"Braid"},{"executables":{"win32":["ShippingPC-StormGame.exe"]},"id":124,"name":"Bulletstorm"},{"executables":{},"id":125,"name":"Cabal 2"},{"executables":{"win32":["CabalMain.exe"]},"id":126,"name":"Cabal Online"},{"executables":{"win32":["iw4mp.exe","iw4sp.exe"]},"id":127,"name":"Call of Duty: Modern Warfare 2"},{"executables":{"win32":["t6sp.exe"]},"id":128,"name":"Call of Duty: Black Ops"},{"executables":{"win32":["iw5mp.exe"]},"id":129,"name":"Call of Duty: Modern Warfare 3"},{"executables":{"win32":["RelicCOH.exe"]},"id":132,"name":"Company of Heroes"},{"executables":{"win32":["Crysis64.exe"]},"id":135,"name":"Crysis"},{"executables":{"win32":["Crysis2.exe"]},"id":136,"name":"Crysis 2"},{"executables":{"win32":["Crysis3.exe"]},"id":137,"name":"Crysis 3"},{"executables":{"win32":["Crysis.exe"]},"id":138,"name":"Crysis 4 "},{"executables":{"win32":["DATA.exe"]},"id":140,"name":"Dark Souls"},{"executables":{"win32":["DarkSoulsII.exe"]},"id":141,"name":"Dark Souls II"},{"executables":{"win32":["dfuw.exe"]},"id":142,"name":"Darkfall: Unholy Wars"},{"executables":{"win32":["DCGAME.exe"]},"id":144,"name":"DC Universe Online"},{"executables":{"win32":["DeadIslandGame.exe"]},"id":145,"name":"Dead Island"},{"executables":{"win32":["deadspace2.exe"]},"id":146,"name":"Dead Space 2"},{"executables":{"win32":["LOTDGame.exe"]},"id":147,"name":"Deadlight"},{"executables":{"win32":["dxhr.exe"]},"id":148,"name":"Deus Ex: Human Revolution"},{"executables":{"win32":["DeviMayCry4.exe"]},"id":149,"name":"Devil May Cry 4"},{"executables":{"win32":["DMC-DevilMayCry.exe"]},"id":150,"name":"DmC Devil May Cry"},{"executables":{"win32":["dirt2_game.exe"]},"id":154,"name":"DiRT 2"},{"executables":{"win32":["dirt3_game.exe"]},"id":155,"name":"DiRT 3"},{"executables":{"win32":["dota.exe"]},"id":156,"name":"DOTA"},{"executables":{"win32":["DoubleDragon.exe"]},"id":158,"name":"Double Dragon Neon"},{"executables":{"win32":["DragonAge2.exe"]},"id":159,"name":"Dragon Age II"},{"executables":{"win32":["DragonAgeInquisition.exe"]},"id":160,"name":"Dragon Age: Inquisition"},{"executables":{"win32":["daorigins.exe"]},"id":161,"name":"Dragon Age: Origins"},{"executables":{"win32":["DBXV.exe"]},"id":162,"name":"Dragon Ball XenoVerse"},{"executables":{"win32":["DukeForever.exe"]},"id":163,"name":"Duke Nukem Forever"},{"executables":{"darwin":["Dustforce.app"],"win32":["dustforce.exe"]},"id":164,"name":"Dustforce"},{"executables":{"win32":["EliteDangerous32.exe"]},"id":165,"name":"Elite: Dangerous"},{"executables":{"win32":["exefile.exe"]},"id":166,"name":"Eve Online"},{"executables":{"win32":["eqgame.exe"]},"id":167,"name":"EverQuest"},{"executables":{"win32":["EverQuest2.exe"]},"id":168,"name":"EverQuest II"},{"executables":{},"id":169,"name":"EverQuest Next"},{"executables":{"win32":["Engine.exe"]},"id":170,"name":"F.E.A.R."},{"executables":{"win32":["FEAR2.exe"]},"id":171,"name":"F.E.A.R. 2: Project Origin"},{"executables":{"win32":["fallout3.exe"]},"id":172,"name":"Fallout 3"},{"executables":{"win32":["FalloutNV.exe"]},"id":174,"name":"Fallout: New Vegas"},{"executables":{"win32":["farcry3.exe"]},"id":175,"name":"Far Cry 3"},{"executables":{"win32":["fifa15.exe"]},"id":176,"name":"FIFA 15"},{"executables":{"win32":["FTLGame.exe"]},"id":180,"name":"FTL: Faster Than Light"},{"executables":{"win32":["GTAIV.exe"]},"id":181,"name":"Grand Theft Auto 4"},{"executables":{"win32":["GTA5.exe"]},"id":182,"name":"Grand Theft Auto 5"},{"executables":{"win32":["Gw.exe"]},"id":183,"name":"Guild Wars"},{"executables":{"win32":["H1Z1.exe"]},"id":186,"name":"H1Z1"},{"executables":{"win32":["HL2HL2.exe","hl2.exe"]},"id":188,"name":"Half Life 2"},{"executables":{"win32":["HOMEFRONT.exe"]},"id":195,"name":"Homefront"},{"executables":{"win32":["invisibleinc.exe"]},"id":196,"name":"Invisible Inc."},{"executables":{"win32":["LANoire.exe"]},"id":197,"name":"L.A. Noire"},{"executables":{"win32":["Landmark64.exe"]},"id":198,"name":"Landmark"},{"executables":{"win32":["left4dead2.exe"]},"id":201,"name":"Left 4 Dead 2"},{"executables":{"win32":["lineage.exe"]},"id":203,"name":"Lineage"},{"executables":{"win32":["Magicka.exe"]},"id":206,"name":"Magicka"},{"executables":{"win32":["MapleStory.exe"]},"id":208,"name":"MapleStory"},{"executables":{},"id":209,"name":"Mark of the Ninja"},{"executables":{"win32":["MassEffect.exe"]},"id":210,"name":"Mass Effect"},{"executables":{"win32":["MassEffect2.exe"]},"id":211,"name":"Mass Effect 2"},{"executables":{"win32":["MassEffect3Demo.exe"]},"id":212,"name":"Mass Effect 3"},{"executables":{"win32":["METAL GEAR RISING REVENGEANCE.exe"]},"id":214,"name":"Metal Gear Rising: Revengeance"},{"executables":{"win32":["metro2033.exe"]},"id":215,"name":"Metro 2033"},{"executables":{"win32":["MetroLL.exe"]},"id":216,"name":"Metro Last Light"},{"executables":{"win32":["MK10.exe"]},"id":218,"name":"Mortal Kombat X"},{"executables":{"win32":["speed.exe"]},"id":219,"name":"Need For Speed Most Wanted"},{"executables":{},"id":220,"name":"Neverwinder"},{"executables":{"darwin":["Outlast.app"],"win32":["OLGame.exe"]},"id":221,"name":"Outlast"},{"executables":{"win32":["PapersPlease.exe"]},"id":222,"name":"Papers, Please"},{"executables":{"win32":["payday_win32_release.exe"]},"id":223,"name":"PAYDAY"},{"executables":{"win32":["payday2_win32_release.exe"]},"id":224,"name":"PAYDAY2"},{"executables":{"win32":["PillarsOfEternity.exe"]},"id":225,"name":"Pillars of Eternity"},{"executables":{"win32":["PA.exe"]},"id":226,"name":"Planetary Annihilation"},{"executables":{"win32":["planetside2_x86.exe"]},"id":227,"name":"Planetside 2"},{"executables":{"win32":["hl2P.exe"]},"id":228,"name":"Portal"},{"executables":{"win32":["portal2.exe"]},"id":229,"name":"Portal 2"},{"executables":{"win32":["PrimalCarnageGame.exe"]},"id":231,"name":"Primal Cargnage"},{"executables":{"win32":["pCARS.exe"]},"id":232,"name":"Project Cars"},{"executables":{"win32":["RaceTheSun.exe"]},"id":233,"name":"Race The Sun"},{"executables":{"win32":["Rage.exe"]},"id":234,"name":"RAGE"},{"executables":{"win32":["ragexe.exe"]},"id":235,"name":"Ragnarok Online"},{"executables":{"win32":["rift.exe"]},"id":236,"name":"Rift"},{"executables":{"win32":["Rocksmith2014.exe"]},"id":237,"name":"Rocksmith 2014"},{"executables":{"win32":["SwiftKit-RS.exe","JagexLauncher.exe"]},"id":238,"name":"RuneScape"},{"executables":{"win32":["Shadowgrounds.exe"]},"id":239,"name":"Shadowgrounds"},{"executables":{"win32":["survivor.exe"]},"id":240,"name":"Shadowgrounds: Survivor"},{"executables":{"win32":["ShovelKnight.exe"]},"id":241,"name":"Shovel Knight"},{"executables":{"win32":["SimCity.exe"]},"id":242,"name":"SimCity"},{"executables":{"win32":["SporeApp.exe"]},"id":245,"name":"Spore"},{"executables":{"win32":["StarCitizen.exe"]},"id":246,"name":"Star Citizen"},{"executables":{},"id":247,"name":"Star Trek Online"},{"executables":{"win32":["battlefront.exe"]},"id":248,"name":"Star Wars Battlefront"},{"executables":{"win32":["swtor.exe"]},"id":249,"name":"Star Wars: The Old Republic"},{"executables":{"win32":["starbound.exe","starbound_opengl.exe"]},"id":250,"name":"Starbound"},{"executables":{"win32":["starcraft.exe"]},"id":251,"name":"Starcraft"},{"executables":{"win32":["SSFIV.exe"]},"id":253,"name":"Ultra Street Fighter IV"},{"executables":{"win32":["superhexagon.exe"]},"id":254,"name":"Super Hexagon"},{"executables":{"win32":["swordandsworcery_pc.exe"]},"id":255,"name":"Superbrothers: Sword & Sworcery EP"},{"executables":{"win32":["hl2TF.exe"]},"id":256,"name":"Team Fortress 2"},{"executables":{"win32":["TERA.exe"]},"id":258,"name":"TERA"},{"executables":{"win32":["Terraria.exe"]},"id":259,"name":"Terraria"},{"executables":{"win32":["Bethesda.net_Launcher.exe"]},"id":260,"name":"The Elder Scrolls Online"},{"executables":{"win32":["TESV.exe"]},"id":261,"name":"The Elder Scrolls V: Skyrim"},{"executables":{"win32":["TheSecretWorld.exe"]},"id":262,"name":"The Secret World"},{"executables":{"win32":["TS3.exe","ts3w.exe"]},"id":264,"name":"The Sims 3"},{"executables":{"win32":["WALKINGDEAD101.EXE"]},"id":265,"name":"The Walking Dead"},{"executables":{"win32":["TheWalkingDead2.exe"]},"id":266,"name":"The Walking Dead Season Two"},{"executables":{"win32":["witcher3.exe"]},"id":267,"name":"The Witcher 3"},{"executables":{"win32":["Future Soldier.exe"]},"id":268,"name":"Tom Clancy's Ghost Recon: Future Solider"},{"executables":{"win32":["TombRaider.exe"]},"id":269,"name":"Tomb Raider (2013)"},{"executables":{"win32":["Torchlight.exe"]},"id":271,"name":"Torchlight"},{"executables":{"win32":["Torchlight2.exe"]},"id":272,"name":"Torchlight 2"},{"executables":{"win32":["Shogun2.exe"]},"id":273,"name":"Total War: Shogun 2"},{"executables":{"win32":["Transistor.exe"]},"id":274,"name":"Transistor"},{"executables":{"win32":["trine.exe"]},"id":275,"name":"Trine"},{"executables":{"win32":["trine2_32bit.exe"]},"id":276,"name":"Trine 2"},{"executables":{"win32":["UOKR.exe"]},"id":277,"name":"Ultima Online"},{"executables":{"win32":["aces.exe"]},"id":279,"name":"War Thunder"},{"executables":{"win32":["Warcraft III.exe","wc3.exe"]},"id":281,"name":"Warcraft 3: Reign of Chaos"},{"executables":{"win32":["Warcraft II BNE.exe"]},"id":282,"name":"Warcraft II"},{"executables":{"win32":["Warframe.x64.exe","Warframe.exe"]},"id":283,"name":"Warframe"},{"executables":{"win32":["watch_dogs.exe"]},"id":284,"name":"Watch Dogs"},{"executables":{"win32":["WildStar64.exe"]},"id":285,"name":"WildStar"},{"executables":{"win32":["XComGame.exe"]},"id":288,"name":"XCOM: Enemy Unknown"},{"executables":{"win32":["DFO.exe","dfo.exe"]},"id":289,"name":"Dungeon Fighter Online"},{"executables":{"win32":["aclauncher.exe","acclient.exe"]},"id":290,"name":"Asheron's Call"},{"executables":{"win32":["MapleStory2.exe"]},"id":291,"name":"MapleStory 2"},{"executables":{"win32":["ksp.exe"]},"id":292,"name":"Kerbal Space Program"},{"executables":{"win32":["PINBALL.EXE"]},"id":293,"name":"3D Pinball: Space Cadet"},{"executables":{"win32":["dave.exe"]},"id":294,"name":"Dangerous Dave"},{"executables":{"win32":["iwbtgbeta(slomo).exe","iwbtgbeta(fs).exe"]},"id":295,"name":"I Wanna Be The Guy"},{"executables":{"win32":["MechWarriorOnline.exe "]},"id":296,"name":"Mech Warrior Online"},{"executables":{"win32":["dontstarve_steam.exe"]},"id":297,"name":"Don't Starve"},{"executables":{"win32":["GalCiv3.exe"]},"id":298,"name":"Galactic Civilization 3"},{"executables":{"win32":["Risk of Rain.exe"]},"id":299,"name":"Risk of Rain"},{"executables":{"win32":["Binding_of_Isaac.exe","Isaac-ng.exe"]},"id":300,"name":"The Binding of Isaac"},{"executables":{"win32":["RustClient.exe"]},"id":301,"name":"Rust"},{"executables":{"win32":["Clicker Heroes.exe"]},"id":302,"name":"Clicker Heroes"},{"executables":{"win32":["Brawlhalla.exe"]},"id":303,"name":"Brawlhalla"},{"executables":{"win32":["TownOfSalem.exe"]},"id":304,"name":"Town of Salem"},{"executables":{"win32":["osu!.exe"]},"id":305,"name":"osu!"},{"executables":{"win32":["PathOfExileSteam.exe","PathOfExile.exe"]},"id":306,"name":"Path of Exile"},{"executables":{"win32":["Dolphin.exe"]},"id":307,"name":"Dolphin"},{"executables":{"win32":["RocketLeague.exe"]},"id":308,"name":"Rocket League"},{"executables":{"win32":["TJPP.exe"]},"id":309,"name":"Jackbox Party Pack"},{"executables":{"win32":["KFGame.exe"]},"id":310,"name":"Killing Floor 2"},{"executables":{"win32":["ShooterGame.exe"]},"id":311,"name":"Ark: Survival Evolved"},{"executables":{"win32":["LifeIsStrange.exe"]},"id":312,"name":"Life Is Strange"},{"executables":{"win32":["Client_tos.exe"]},"id":313,"name":"Tree of Savior"},{"executables":{"win32":["olliolli2.exe"]},"id":314,"name":"OlliOlli2"},{"executables":{"win32":["cw.exe"]},"id":315,"name":"Closers Dimension Conflict"},{"executables":{"win32":["ESSTEAM.exe","elsword.exe","x2.exe"]},"id":316,"name":"Elsword"},{"executables":{"win32":["ori.exe"]},"id":317,"name":"Ori and the Blind Forest"},{"executables":{"win32":["Skyforge.exe"]},"id":318,"name":"Skyforge"},{"executables":{"win32":["projectzomboid64.exe","projectzomboid32.exe"]},"id":319,"name":"Project Zomboid"},{"executables":{"win32":["From_The_Depths.exe"]},"id":320,"name":"The Depths"},{"executables":{"win32":["TheCrew.exe"]},"id":321,"name":"The Crew"},{"executables":{"win32":["MarvelHeroes2015.exe"]},"id":322,"name":"Marvel Heroes 2015"},{"executables":{"win32":["timeclickers.exe"]},"id":324,"name":"Time Clickers"},{"executables":{"win32":["eurotrucks2.exe"]},"id":325,"name":"Euro Truck Simulator 2"},{"executables":{"win32":["FarmingSimulator2015Game.exe"]},"id":326,"name":"Farming Simulator 15"},{"executables":{"win32":["strife.exe"]},"id":327,"name":"Strife"},{"executables":{"win32":["Awesomenauts.exe"]},"id":328,"name":"Awesomenauts"},{"executables":{"win32":["Dofus.exe"]},"id":329,"name":"Dofus"},{"executables":{"win32":["Boid.exe"]},"id":330,"name":"Boid"},{"executables":{"win32":["adventure-capitalist.exe"]},"id":331,"name":"AdVenture Capitalist"},{"executables":{"win32":["OrcsMustDie2.exe"]},"id":332,"name":"Orcs Must Die! 2"},{"executables":{"win32":["Mountain.exe"]},"id":333,"name":"Mountain"},{"executables":{"win32":["Valkyria.exe"]},"id":335,"name":"Valkyria Chronicles"},{"executables":{"win32":["ffxiiiimg.exe"]},"id":336,"name":"Final Fantasy XIII"},{"executables":{"win32":["TLR.exe"]},"id":337,"name":"The Last Remnant"},{"executables":{"win32":["Cities.exe"]},"id":339,"name":"Cities Skylines"},{"executables":{"win32":["worldofwarships.exe","WoWSLauncher.exe"]},"id":341,"name":"World of Warships"},{"executables":{"win32":["spacegame-Win64-shipping.exe"]},"id":342,"name":"Fractured Space"},{"executables":{"win32":["thespacegame.exe"]},"id":343,"name":"Ascent - The Space Game"},{"executables":{"win32":["DuckGame.exe"]},"id":344,"name":"Duck Game"},{"executables":{"win32":["PPSSPPWindows.exe"]},"id":345,"name":"PPSSPP"},{"executables":{"win32":["MBAA.exe"]},"id":346,"name":"Melty Blood Actress Again: Current Code"},{"executables":{"win32":["TheWolfAmongUs.exe"]},"id":347,"name":"The Wolf Among Us"},{"executables":{"win32":["SpaceEngineers.exe"]},"id":348,"name":"Space Engineers"},{"executables":{"win32":["Borderlands.exe"]},"id":349,"name":"Borderlands"},{"executables":{"win32":["100orange.exe"]},"id":351,"name":"100% Orange Juice"},{"executables":{"win32":["reflex.exe"]},"id":354,"name":"Reflex"},{"executables":{"win32":["pso2.exe"]},"id":355,"name":"Phantasy Star Online 2"},{"executables":{"win32":["AssettoCorsa.exe"]},"id":356,"name":"Assetto Corsa"},{"executables":{"win32":["iw3mp.exe","iw3sp.exe"]},"id":357,"name":"Call of Duty 4: Modern Warfare"},{"executables":{"win32":["WolfOldBlood_x64.exe"]},"id":358,"name":"Wolfenstein: The Old Blood"},{"executables":{"win32":["castle.exe"]},"id":359,"name":"Castle Crashers"},{"executables":{"win32":["vindictus.exe"]},"id":360,"name":"Vindictus"},{"executables":{"win32":["ShooterGame-Win32-Shipping.exe"]},"id":361,"name":"Dirty Bomb"},{"executables":{"win32":["BatmanAK.exe"]},"id":362,"name":"Batman Arkham Knight"},{"executables":{"win32":["drt.exe"]},"id":363,"name":"Dirt Rally"},{"executables":{"win32":["rFactor.exe"]},"id":364,"name":"rFactor"},{"executables":{"win32":["clonk.exe"]},"id":365,"name":"Clonk Rage"},{"executables":{"win32":["SRHK.exe"]},"id":366,"name":"Shadowrun: Hong Kong"},{"executables":{"win32":["Insurgency.exe"]},"id":367,"name":"Insurgency"},{"executables":{"win32":["StepMania.exe"]},"id":368,"name":"Step Mania"},{"executables":{"win32":["FirefallCLient.exe"]},"id":369,"name":"Firefall"},{"executables":{"win32":["mirrorsedge.exe"]},"id":370,"name":"Mirrors Edge"},{"executables":{"win32":["MgsGroundZeroes.exe"]},"id":371,"name":"Metal Gear Solid V: Ground Zeroes"},{"executables":{"win32":["mgsvtpp.exe"]},"id":372,"name":"Metal Gear Solid V: The Phantom Pain"},{"executables":{"win32":["tld.exe"]},"id":373,"name":"The Long Dark"},{"executables":{"win32":["TKOM.exe"]},"id":374,"name":"Take On Mars"},{"executables":{"win32":["robloxplayerlauncher.exe","Roblox.exe"]},"id":375,"name":"Roblox"},{"executables":{"win32":["eu4.exe"]},"id":376,"name":"Europa Universalis 4"},{"executables":{"win32":["APB.exe"]},"id":377,"name":"APB Reloaded"},{"executables":{"win32":["Robocraft.exe"]},"id":378,"name":"Robocraft"},{"executables":{"win32":["Unity.exe"]},"id":379,"name":"Unity"},{"executables":{"win32":["Simpsons.exe"]},"id":380,"name":"The Simpsons: Hit & Run"},{"executables":{"win32":["Dnlauncher.exe","DragonNest.exe"]},"id":381,"name":"Dragon Nest"},{"executables":{"win32":["Trove.exe"]},"id":382,"name":"Trove"},{"executables":{"win32":["EndlessLegend.exe"]},"id":383,"name":"Endless Legend"},{"executables":{"win32":["TurbineLauncher.exe","dndclient.exe"]},"id":384,"name":"Dungeons & Dragons Online"},{"executables":{"win32":["quakelive.exe","quakelive_steam.exe"]},"id":385,"name":"Quake Live"},{"executables":{"win32":["7DaysToDie.exe"]},"id":386,"name":"7DaysToDie"},{"executables":{"win32":["SpeedRunners.exe"]},"id":387,"name":"SpeedRunners"},{"executables":{"win32":["gamemd.exe"]},"id":388,"name":"Command & Conquer: Red Alert 2"},{"executables":{"win32":["generals.exe"]},"id":389,"name":"Command & Conquer Generals: Zero Hour"},{"executables":{"win32":["Oblivion.exe"]},"id":390,"name":"The Elder Scrolls 4: Oblivion"},{"executables":{"win32":["mgsi.exe"]},"id":391,"name":"Metal Gear Solid"},{"executables":{"win32":["EoCApp.exe"]},"id":392,"name":"Divinity - Original Sin"},{"executables":{"win32":["Torment.exe"]},"id":393,"name":"Planescape: Torment"},{"executables":{"win32":["HexPatch.exe"]},"id":394,"name":"Hex: Shards of Fate"},{"executables":{"win32":["NS3FB.exe"]},"id":395,"name":"Naruto Shippuden Ultimate Ninja Storm 3 Full Burst"},{"executables":{"win32":["NSUNSR.exe"]},"id":396,"name":"Naruto Shippuden Ultimate Ninja Storm Revolution"},{"executables":{"win32":["SaintsRowIV.exe"]},"id":397,"name":"Saints Row IV"},{"executables":{"win32":["Shadowrun.exe"]},"id":398,"name":"Shadowrun"},{"executables":{"win32":["DungeonoftheEndless.exe"]},"id":399,"name":"Dungeon of the Endless"},{"executables":{"win32":["Hon.exe"]},"id":400,"name":"Heroes of Newerth"},{"executables":{"win32":["mabinogi.exe"]},"id":401,"name":"Mabinogi"},{"executables":{"win32":["CoD2MP_s.exe","CoDSP_s.exe"]},"id":402,"name":"Call of Duty 2:"},{"executables":{"win32":["CoDWaWmp.exe","CoDWaw.exe"]},"id":403,"name":"Call of Duty: World at War"},{"executables":{"win32":["heroes.exe"]},"id":404,"name":"Mabinogi Heroes (Vindictus) "},{"executables":{"win32":["KanColleViewer.exe"]},"id":405,"name":"KanColle "},{"executables":{"win32":["cyphers.exe"]},"id":406,"name":"Cyphers"},{"executables":{"win32":["RelicCoH2.exe"]},"id":407,"name":"Company of Heroes 2"},{"executables":{"win32":["MJ.exe"]},"id":408,"name":"セガNET麻雀MJ"},{"executables":{"win32":["ge.exe"]},"id":409,"name":"Granado Espada"},{"executables":{"win32":["NovaRO.exe"]},"id":410,"name":"Nova Ragnarok Online"},{"executables":{"win32":["RivalsofAether.exe"]},"id":411,"name":"Rivals of Aether"},{"executables":{"win32":["bfh.exe"]},"id":412,"name":"Battlefield Hardline"},{"executables":{"win32":["GrowHome.exe"]},"id":413,"name":"Grow Home"},{"executables":{"win32":["patriots.exe"]},"id":414,"name":"Rise of Nations Extended"},{"executables":{"win32":["Railroads.exe"]},"id":415,"name":"Sid Meier's Railroads!"},{"executables":{"win32":["Empire.exe"]},"id":416,"name":"Empire: Total War"},{"executables":{"win32":["Napoleon.exe"]},"id":417,"name":"Napoleon: Total War"},{"executables":{"win32":["gta_sa.exe"]},"id":418,"name":"Grand Theft Auto: San Andreas"},{"executables":{"win32":["MadMax.exe"]},"id":419,"name":"Mad Max"},{"executables":{"win32":["Titanfall.exe"]},"id":420,"name":"Titanfall"},{"executables":{"win32":["age2_x1.exe"]},"id":421,"name":"Age of Empires II: The Conquerors"},{"executables":{"win32":["Rome2.exe"]},"id":422,"name":"Total War: ROME 2"},{"executables":{"win32":["ShadowOfMordor.exe"]},"id":423,"name":"Middle-earth: Shadow of Mordor"},{"executables":{"win32":["Subnautica.exe"]},"id":424,"name":"Subnautica"},{"executables":{"win32":["anno5.exe"]},"id":425,"name":"Anno 2070"},{"executables":{"win32":["carrier.exe"]},"id":426,"name":"Carrier Command Gaea Mission"},{"executables":{"win32":["DarksidersPC.exe"]},"id":427,"name":"Darksiders"},{"executables":{"win32":["Darksiders2.exe"]},"id":428,"name":"Darksiders 2"},{"executables":{"win32":["mudlet.exe"]},"id":429,"name":"Mudlet"},{"executables":{"win32":["DunDefLauncher.exe"]},"id":430,"name":"Dungeon Defenders II"},{"executables":{"win32":["hng.exe"]},"id":431,"name":"Heroes and Generals"},{"executables":{"win32":["WFTOGame.exe"]},"id":432,"name":"War of the Overworld"},{"executables":{"win32":["Talisman.exe"]},"id":433,"name":"Talisman: Digital Edition"},{"executables":{"win32":["limbo.exe"]},"id":434,"name":"Limbo"},{"executables":{"win32":["ibbobb.exe"]},"id":435,"name":"ibb & obb"},{"executables":{"win32":["BattleBlockTheater.exe"]},"id":436,"name":"BattleBlock Theater"},{"executables":{"win32":["iracinglauncher.exe","iracingsim.exe","iracingsim64.exe"]},"id":437,"name":"iRacing"},{"executables":{"win32":["CivilizationV_DX11.exe"]},"id":438,"name":"Civilization V"}]
+},{}]},{},[5])(5)
+});
\ No newline at end of file
diff --git a/web-dist/discord.3.8.4.js b/web-dist/discord.3.8.4.js
new file mode 100644
index 000000000..f05aef245
--- /dev/null
+++ b/web-dist/discord.3.8.4.js
@@ -0,0 +1,1534 @@
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Discord = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o>> x & 1) === 1;}this.type = data.type; //either member or role
+this.id = data.id;if(this.type === "member"){this.packed = channel.server.getMember("id",data.id).evalPerms.packed;}else {this.packed = channel.server.getRole(data.id).packed;}this.packed = this.packed & ~data.deny;this.packed = this.packed | data.allow;this.deny = data.deny;this.allow = data.allow;}ChannelPermissions.prototype.getBit = function getBit(x){return (this.packed >>> x & 1) === 1;};ChannelPermissions.prototype.setBit = function setBit(){};_createClass(ChannelPermissions,[{key:"createInstantInvite",get:function get(){return this.getBit(0);},set:function set(val){this.setBit(0,val);}},{key:"manageRoles",get:function get(){return this.getBit(3);},set:function set(val){this.setBit(3,val);}},{key:"manageChannels",get:function get(){return this.getBit(4);},set:function set(val){this.setBit(4,val);}},{key:"readMessages",get:function get(){return this.getBit(10);},set:function set(val){this.setBit(10,val);}},{key:"sendMessages",get:function get(){return this.getBit(11);},set:function set(val){this.setBit(11,val);}},{key:"sendTTSMessages",get:function get(){return this.getBit(12);},set:function set(val){this.setBit(12,val);}},{key:"manageMessages",get:function get(){return this.getBit(13);},set:function set(val){this.setBit(13,val);}},{key:"embedLinks",get:function get(){return this.getBit(14);},set:function set(val){this.setBit(14,val);}},{key:"attachFiles",get:function get(){return this.getBit(15);},set:function set(val){this.setBit(15,val);}},{key:"readMessageHistory",get:function get(){return this.getBit(16);},set:function set(val){this.setBit(16,val);}},{key:"mentionEveryone",get:function get(){return this.getBit(17);},set:function set(val){this.setBit(17,val);}},{key:"voiceConnect",get:function get(){return this.getBit(20);},set:function set(val){this.setBit(20,val);}},{key:"voiceSpeak",get:function get(){return this.getBit(21);},set:function set(val){this.setBit(21,val);}},{key:"voiceMuteMembers",get:function get(){return this.getBit(22);},set:function set(val){this.setBit(22,val);}},{key:"voiceDeafenMembers",get:function get(){return this.getBit(23);},set:function set(val){this.setBit(23,val);}},{key:"voiceMoveMembers",get:function get(){return this.getBit(24);},set:function set(val){this.setBit(24,val);}},{key:"voiceUseVoiceActivation",get:function get(){return this.getBit(25);},set:function set(val){this.setBit(25,val);}}]);return ChannelPermissions;})();module.exports = ChannelPermissions;
+
+},{}],2:[function(require,module,exports){
+//discord.js modules
+"use strict";var _createClass=(function(){function defineProperties(target,props){for(var i=0;i < props.length;i++) {var descriptor=props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if("value" in descriptor)descriptor.writable = true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};})();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}var Endpoints=require("./Endpoints.js");var User=require("./user.js");var Server=require("./server.js");var Channel=require("./channel.js");var Message=require("./message.js");var Invite=require("./invite.js");var PMChannel=require("./PMChannel.js");var gameMap=require("../ref/gameMap.json"); //node modules
+var request=require("superagent");var WebSocket=require("ws");var fs=require("fs");var defaultOptions={queue:false};var Client=(function(){function Client(){var options=arguments.length <= 0 || arguments[0] === undefined?defaultOptions:arguments[0];var token=arguments.length <= 1 || arguments[1] === undefined?undefined:arguments[1];_classCallCheck(this,Client); /*
+ When created, if a token is specified the Client will
+ try connecting with it. If the token is incorrect, no
+ further efforts will be made to connect.
+ */this.options = options;this.options.queue = this.options.queue;this.token = token;this.state = 0;this.websocket = null;this.events = {};this.user = null;this.alreadySentData = false;this.serverCreateListener = {};this.typingIntervals = {};this.email = "abc";this.password = "abc"; /*
+ State values:
+ 0 - idle
+ 1 - logging in
+ 2 - logged in
+ 3 - ready
+ 4 - disconnected
+ */this.userCache = [];this.channelCache = [];this.serverCache = [];this.pmChannelCache = [];this.readyTime = null;this.checkingQueue = {};this.userTypingListener = {};this.queue = {};this.__idleTime = null;this.__gameId = null;}Client.prototype.sendPacket = function sendPacket(JSONObject){if(this.websocket.readyState === 1){this.websocket.send(JSON.stringify(JSONObject));}}; //def debug
+Client.prototype.debug = function debug(message){this.trigger("debug",message);};Client.prototype.on = function on(event,fn){this.events[event] = fn;};Client.prototype.off = function off(event){this.events[event] = null;};Client.prototype.keepAlive = function keepAlive(){this.debug("keep alive triggered");this.sendPacket({op:1,d:Date.now()});}; //def trigger
+Client.prototype.trigger = function trigger(event){var args=[];for(var arg in arguments) {args.push(arguments[arg]);}var evt=this.events[event];if(evt){evt.apply(this,args.slice(1));}}; //def login
+Client.prototype.login = function login(){var email=arguments.length <= 0 || arguments[0] === undefined?"foo@bar.com":arguments[0];var password=arguments.length <= 1 || arguments[1] === undefined?"pass1234":arguments[1];var callback=arguments.length <= 2 || arguments[2] === undefined?function(err,token){}:arguments[2];var self=this;return new Promise(function(resolve,reject){if(self.state === 0 || self.state === 4){self.state = 1; //set the state to logging in
+self.email = email;self.password = password;request.post(Endpoints.LOGIN).send({email:email,password:password}).end(function(err,res){if(err){self.state = 4; //set state to disconnected
+self.trigger("disconnected");if(self.websocket){self.websocket.close();}callback(err);reject(err);}else {self.state = 2; //set state to logged in (not yet ready)
+self.token = res.body.token; //set our token
+self.getGateway().then(function(url){self.createws(url);callback(null,self.token);resolve(self.token);})["catch"](function(err){callback(err);reject(err);});}});}else {reject(new Error("Client already logging in or ready"));}});};Client.prototype.logout = function logout(){var callback=arguments.length <= 0 || arguments[0] === undefined?function(err){}:arguments[0];var self=this;return new Promise(function(resolve,reject){request.post(Endpoints.LOGOUT).set("authorization",self.token).end(function(err,res){if(err){callback(err);reject(err);}else {self.websocket.close();self.state = 4;callback();resolve();}});});};Client.prototype.createServer = function createServer(name,region){var callback=arguments.length <= 2 || arguments[2] === undefined?function(err,server){}:arguments[2];var self=this;return new Promise(function(resolve,reject){request.post(Endpoints.SERVERS).set("authorization",self.token).send({name:name,region:region}).end(function(err,res){if(err){callback(err);reject(err);}else { // potentially redundant in future
+// creating here does NOT give us the channels of the server
+// so we must wait for the guild_create event.
+self.serverCreateListener[res.body.id] = [resolve,callback]; /*var srv = self.addServer(res.body);
+ callback(null, srv);
+ resolve(srv);*/}});});};Client.prototype.createChannel = function createChannel(server,channelName,channelType){var callback=arguments.length <= 3 || arguments[3] === undefined?function(err,chann){}:arguments[3];var self=this;return new Promise(function(resolve,reject){request.post(Endpoints.SERVERS + "/" + self.resolveServerID(server) + "/channels").set("authorization",self.token).send({name:channelName,type:channelType}).end(function(err,res){if(err){callback(err);reject(err);}else {var server=self.getServer("id",res.body.guild_id);var chann=self.addChannel(res.body,res.body.guild_id);server.addChannel(chann);callback(null,chann);resolve(chann);}});});};Client.prototype.leaveServer = function leaveServer(server){var callback=arguments.length <= 1 || arguments[1] === undefined?function(err,server){}:arguments[1];var self=this;return new Promise(function(resolve,reject){request.del(Endpoints.SERVERS + "/" + self.resolveServerID(server)).set("authorization",self.token).end(function(err,res){if(err){callback(err);reject(err);}else {self.serverCache.splice(self.serverCache.indexOf(server),1);callback(null);resolve();}});});};Client.prototype.createInvite = function createInvite(serverOrChannel,options){var callback=arguments.length <= 2 || arguments[2] === undefined?function(err,invite){}:arguments[2];var self=this;return new Promise(function(resolve,reject){var destination;if(serverOrChannel instanceof Server){destination = serverOrChannel.id;}else if(serverOrChannel instanceof Channel){destination = serverOrChannel.id;}else {destination = serverOrChannel;}options = options || {};options.max_age = options.maxAge || 0;options.max_uses = options.maxUses || 0;options.temporary = options.temporary || false;options.xkcdpass = options.xkcd || false;request.post(Endpoints.CHANNELS + "/" + destination + "/invites").set("authorization",self.token).send(options).end(function(err,res){if(err){callback(err);reject(err);}else {var inv=new Invite(res.body,self);callback(null,inv);resolve(inv);}});});};Client.prototype.startPM = function startPM(user){var self=this;return new Promise(function(resolve,reject){var userId=user;if(user instanceof User){userId = user.id;}request.post(Endpoints.USERS + "/" + self.user.id + "/channels").set("authorization",self.token).send({recipient_id:userId}).end(function(err,res){if(err){reject(err);}else {resolve(self.addPMChannel(res.body));}});});};Client.prototype.reply = function reply(destination,message,tts){var callback=arguments.length <= 3 || arguments[3] === undefined?function(err,msg){}:arguments[3];var self=this;return new Promise(function(response,reject){if(typeof tts === "function"){ // tts is a function, which means the developer wants this to be the callback
+callback = tts;tts = false;}var user=destination.sender;self.sendMessage(destination,message,tts,callback,user + ", ").then(response)["catch"](reject);});};Client.prototype.deleteMessage = function deleteMessage(message,timeout){var callback=arguments.length <= 2 || arguments[2] === undefined?function(err,msg){}:arguments[2];var self=this;return new Promise(function(resolve,reject){if(timeout){setTimeout(remove,timeout);}else {remove();}function remove(){request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization",self.token).end(function(err,res){if(err){bad();}else {good();}});}function good(){callback();resolve();}function bad(err){callback(err);reject(err);}});};Client.prototype.updateMessage = function updateMessage(message,content){var callback=arguments.length <= 2 || arguments[2] === undefined?function(err,msg){}:arguments[2];var self=this;var prom=new Promise(function(resolve,reject){content = content instanceof Array?content.join("\n"):content;if(self.options.queue){if(!self.queue[message.channel.id]){self.queue[message.channel.id] = [];}self.queue[message.channel.id].push({action:"updateMessage",message:message,content:content,then:good,error:bad});self.checkQueue(message.channel.id);}else {self._updateMessage(message,content).then(good)["catch"](bad);}function good(msg){prom.message = msg;callback(null,msg);resolve(msg);}function bad(error){prom.error = error;callback(error);reject(error);}});return prom;};Client.prototype.setUsername = function setUsername(newName){var callback=arguments.length <= 1 || arguments[1] === undefined?function(err){}:arguments[1];var self=this;return new Promise(function(resolve,reject){request.patch(Endpoints.API + "/users/@me").set("authorization",self.token).send({avatar:self.user.avatar,email:self.email,new_password:null,password:self.password,username:newName}).end(function(err){callback(err);if(err)reject(err);else resolve();});});};Client.prototype.getChannelLogs = function getChannelLogs(channel){var amount=arguments.length <= 1 || arguments[1] === undefined?500:arguments[1];var callback=arguments.length <= 2 || arguments[2] === undefined?function(err,logs){}:arguments[2];var self=this;return new Promise(function(resolve,reject){var channelID=channel;if(channel instanceof Channel){channelID = channel.id;}request.get(Endpoints.CHANNELS + "/" + channelID + "/messages?limit=" + amount).set("authorization",self.token).end(function(err,res){if(err){callback(err);reject(err);}else {var logs=[];var channel=self.getChannel("id",channelID);for(var _iterator=res.body,_isArray=Array.isArray(_iterator),_i=0,_iterator=_isArray?_iterator:_iterator[Symbol.iterator]();;) {var _ref;if(_isArray){if(_i >= _iterator.length)break;_ref = _iterator[_i++];}else {_i = _iterator.next();if(_i.done)break;_ref = _i.value;}var message=_ref;var mentions=[];for(var _iterator2=message.mentions,_isArray2=Array.isArray(_iterator2),_i2=0,_iterator2=_isArray2?_iterator2:_iterator2[Symbol.iterator]();;) {var _ref2;if(_isArray2){if(_i2 >= _iterator2.length)break;_ref2 = _iterator2[_i2++];}else {_i2 = _iterator2.next();if(_i2.done)break;_ref2 = _i2.value;}var mention=_ref2;mentions.push(self.addUser(mention));}var author=self.addUser(message.author);logs.push(new Message(message,channel,mentions,author));}callback(null,logs);resolve(logs);}});});};Client.prototype.deleteChannel = function deleteChannel(channel){var callback=arguments.length <= 1 || arguments[1] === undefined?function(err){}:arguments[1];var self=this;return new Promise(function(resolve,reject){var channelID=channel;if(channel instanceof Channel){channelID = channel.id;}request.del(Endpoints.CHANNELS + "/" + channelID).set("authorization",self.token).end(function(err){if(err){callback(err);reject(err);}else {callback(null);resolve();}});});};Client.prototype.joinServer = function joinServer(invite){var callback=arguments.length <= 1 || arguments[1] === undefined?function(err,server){}:arguments[1];var self=this;return new Promise(function(resolve,reject){var id=invite instanceof Invite?invite.code:invite;request.post(Endpoints.API + "/invite/" + id).set("authorization",self.token).end(function(err,res){if(err){callback(err);reject(err);}else {if(self.getServer("id",res.body.guild.id)){resolve(self.getServer("id",res.body.guild.id));}else {self.serverCreateListener[res.body.guild.id] = [resolve,callback];}}});});};Client.prototype.sendFile = function sendFile(destination,file){var fileName=arguments.length <= 2 || arguments[2] === undefined?"image.png":arguments[2];var callback=arguments.length <= 3 || arguments[3] === undefined?function(err,msg){}:arguments[3];var self=this;var prom=new Promise(function(resolve,reject){var fstream;if(typeof file === "string" || file instanceof String){fstream = fs.createReadStream(file);fileName = file;}else {fstream = file;}self.resolveDestination(destination).then(send)["catch"](bad);function send(destination){if(self.options.queue){ //queue send file too
+if(!self.queue[destination]){self.queue[destination] = [];}self.queue[destination].push({action:"sendFile",attachment:fstream,attachmentName:fileName,then:good,error:bad});self.checkQueue(destination);}else { //not queue
+self._sendFile(destination,fstream,fileName).then(good)["catch"](bad);}}function good(msg){prom.message = msg;callback(null,msg);resolve(msg);}function bad(err){prom.error = err;callback(err);reject(err);}});return prom;};Client.prototype.sendMessage = function sendMessage(destination,message,tts){var callback=arguments.length <= 3 || arguments[3] === undefined?function(err,msg){}:arguments[3];var premessage=arguments.length <= 4 || arguments[4] === undefined?"":arguments[4];var self=this;var prom=new Promise(function(resolve,reject){if(typeof tts === "function"){ // tts is a function, which means the developer wants this to be the callback
+callback = tts;tts = false;}message = premessage + resolveMessage(message);var mentions=resolveMentions();self.resolveDestination(destination).then(send)["catch"](error);function error(err){callback(err);reject(err);}function send(destination){if(self.options.queue){ //we're QUEUEING messages, so sending them sequentially based on servers.
+if(!self.queue[destination]){self.queue[destination] = [];}self.queue[destination].push({action:"sendMessage",content:message,mentions:mentions,tts:!!tts, //incase it's not a boolean
+then:mgood,error:mbad});self.checkQueue(destination);}else {self._sendMessage(destination,message,tts,mentions).then(mgood)["catch"](mbad);}}function mgood(msg){prom.message = msg;callback(null,msg);resolve(msg);}function mbad(error){prom.error = error;callback(error);reject(error);}function resolveMessage(){var msg=message;if(message instanceof Array){msg = message.join("\n");}return msg;}function resolveMentions(){var _mentions=[];for(var _iterator3=message.match(/<@[^>]*>/g) || [],_isArray3=Array.isArray(_iterator3),_i3=0,_iterator3=_isArray3?_iterator3:_iterator3[Symbol.iterator]();;) {var _ref3;if(_isArray3){if(_i3 >= _iterator3.length)break;_ref3 = _iterator3[_i3++];}else {_i3 = _iterator3.next();if(_i3.done)break;_ref3 = _i3.value;}var mention=_ref3;_mentions.push(mention.substring(2,mention.length - 1));}return _mentions;}});return prom;}; //def createws
+Client.prototype.createws = function createws(url){if(this.websocket)return false;var self=this; //good to go
+this.websocket = new WebSocket(url); //open
+this.websocket.onopen = function(){self.trySendConnData(); //try connecting
+}; //close
+this.websocket.onclose = function(){self.trigger("disconnected");}; //message
+this.websocket.onmessage = function(e){var dat=false,data={};try{dat = JSON.parse(e.data);data = dat.d;}catch(err) {self.trigger("error",err,e);return;}self.trigger("raw",dat); //valid message
+switch(dat.t){case "READY":self.debug("received ready packet");self.user = self.addUser(data.user);for(var _iterator4=data.guilds,_isArray4=Array.isArray(_iterator4),_i4=0,_iterator4=_isArray4?_iterator4:_iterator4[Symbol.iterator]();;) {var _ref4;if(_isArray4){if(_i4 >= _iterator4.length)break;_ref4 = _iterator4[_i4++];}else {_i4 = _iterator4.next();if(_i4.done)break;_ref4 = _i4.value;}var _server=_ref4;var server=self.addServer(_server);}for(var _iterator5=data.private_channels,_isArray5=Array.isArray(_iterator5),_i5=0,_iterator5=_isArray5?_iterator5:_iterator5[Symbol.iterator]();;) {var _ref5;if(_isArray5){if(_i5 >= _iterator5.length)break;_ref5 = _iterator5[_i5++];}else {_i5 = _iterator5.next();if(_i5.done)break;_ref5 = _i5.value;}var _pmc=_ref5;var pmc=self.addPMChannel(_pmc);}self.trigger("ready");self.readyTime = Date.now();self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users.");self.state = 3;setInterval(function(){self.keepAlive.apply(self);},data.heartbeat_interval);break;case "MESSAGE_CREATE":self.debug("received message");var mentions=[];data.mentions = data.mentions || []; //for some reason this was not defined at some point?
+for(var _iterator6=data.mentions,_isArray6=Array.isArray(_iterator6),_i6=0,_iterator6=_isArray6?_iterator6:_iterator6[Symbol.iterator]();;) {var _ref6;if(_isArray6){if(_i6 >= _iterator6.length)break;_ref6 = _iterator6[_i6++];}else {_i6 = _iterator6.next();if(_i6.done)break;_ref6 = _i6.value;}var mention=_ref6;mentions.push(self.addUser(mention));}var channel=self.getChannel("id",data.channel_id);if(channel){var msg=channel.addMessage(new Message(data,channel,mentions,self.addUser(data.author)));self.trigger("message",msg);}break;case "MESSAGE_DELETE":self.debug("message deleted");var channel=self.getChannel("id",data.channel_id);var message=channel.getMessage("id",data.id);if(message){self.trigger("messageDelete",channel,message);channel.messages.splice(channel.messages.indexOf(message),1);}else { //don't have the cache of that message ;(
+self.trigger("messageDelete",channel);}break;case "MESSAGE_UPDATE":self.debug("message updated");var channel=self.getChannel("id",data.channel_id);var formerMessage=channel.getMessage("id",data.id);if(formerMessage){ //new message might be partial, so we need to fill it with whatever the old message was.
+var info={};for(var key in formerMessage) {info[key] = formerMessage[key];}for(var key in data) {info[key] = data[key];}var mentions=[];for(var _iterator7=info.mentions,_isArray7=Array.isArray(_iterator7),_i7=0,_iterator7=_isArray7?_iterator7:_iterator7[Symbol.iterator]();;) {var _ref7;if(_isArray7){if(_i7 >= _iterator7.length)break;_ref7 = _iterator7[_i7++];}else {_i7 = _iterator7.next();if(_i7.done)break;_ref7 = _i7.value;}var mention=_ref7;mentions.push(self.addUser(mention));}var newMessage=new Message(info,channel,mentions,formerMessage.author);self.trigger("messageUpdate",newMessage,formerMessage);channel.messages[channel.messages.indexOf(formerMessage)] = newMessage;} // message isn't in cache, and if it's a partial it could cause
+// all hell to break loose... best to just act as if nothing happened
+break;case "GUILD_DELETE":var server=self.getServer("id",data.id);if(server){self.serverCache.splice(self.serverCache.indexOf(server),1);self.trigger("serverDelete",server);}break;case "CHANNEL_DELETE":var channel=self.getChannel("id",data.id);if(channel){var server=channel.server;if(server){server.channels.splice(server.channels.indexOf(channel),1);}self.trigger("channelDelete",channel);self.serverCache.splice(self.serverCache.indexOf(channel),1);}break;case "GUILD_CREATE":var server=self.getServer("id",data.id);if(!server){ //if server doesn't already exist because duh
+server = self.addServer(data);} /*else if(server.channels.length === 0){
+
+ var srv = new Server(data, self);
+ for(channel of data.channels){
+ srv.channels.push(new Channel(channel, data.id));
+ }
+ self.serverCache[self.serverCache.indexOf(server)] = srv;
+
+ }*/if(self.serverCreateListener[data.id]){var cbs=self.serverCreateListener[data.id];cbs[0](server); //promise then callback
+cbs[1](null,server); //legacy callback
+self.serverCreateListener[data.id] = null;}self.trigger("serverCreate",server);break;case "CHANNEL_CREATE":var channel=self.getChannel("id",data.id);if(!channel){var chann;if(data.is_private){chann = self.addPMChannel(data);}else {chann = self.addChannel(data,data.guild_id);}var srv=self.getServer("id",data.guild_id);if(srv){srv.addChannel(chann);}self.trigger("channelCreate",chann);}break;case "GUILD_MEMBER_ADD":var server=self.getServer("id",data.guild_id);if(server){var user=self.addUser(data.user); //if for whatever reason it doesn't exist..
+self.trigger("serverNewMember",server.addMember(user,data.roles),server);}break;case "GUILD_MEMBER_REMOVE":var server=self.getServer("id",data.guild_id);if(server){var user=self.addUser(data.user); //if for whatever reason it doesn't exist..
+server.removeMember("id",user.id);self.trigger("serverRemoveMember",user,server);}break;case "USER_UPDATE":if(self.user && data.id === self.user.id){var newUser=new User(data); //not actually adding to the cache
+self.trigger("userUpdate",newUser,self.user);if(~self.userCache.indexOf(self.user)){self.userCache[self.userCache.indexOf(self.user)] = newUser;}self.user = newUser;}break;case "PRESENCE_UPDATE":var userInCache=self.getUser("id",data.user.id);if(userInCache){ //user exists
+data.user.username = data.user.username || userInCache.username;data.user.id = data.user.id || userInCache.id;data.user.discriminator = data.user.discriminator || userInCache.discriminator;data.user.avatar = data.user.avatar || userInCache.avatar;var presenceUser=new User(data.user);if(presenceUser.equalsStrict(userInCache)){ //they're exactly the same, an actual presence update
+self.trigger("presence",{user:userInCache,oldStatus:userInCache.status,status:data.status,server:self.getServer("id",data.guild_id),gameId:data.game_id});userInCache.status = data.status;userInCache.gameId = data.game_id;}else { //one of their details changed.
+self.userCache[self.userCache.indexOf(userInCache)] = presenceUser;self.trigger("userUpdate",userInCache,presenceUser);}}break;case "CHANNEL_UPDATE":var channelInCache=self.getChannel("id",data.id),serverInCache=self.getServer("id",data.guild_id);if(channelInCache && serverInCache){var newChann=new Channel(data,serverInCache);newChann.messages = channelInCache.messages;self.trigger("channelUpdate",channelInCache,newChann);self.channelCache[self.channelCache.indexOf(channelInCache)] = newChann;}break;case "TYPING_START":var userInCache=self.getUser("id",data.user_id);var channelInCache=self.getChannel("id",data.channel_id);if(!self.userTypingListener[data.user_id] || self.userTypingListener[data.user_id] === -1){self.trigger("startTyping",userInCache,channelInCache);}self.userTypingListener[data.user_id] = Date.now();setTimeout(function(){if(self.userTypingListener[data.user_id] === -1){return;}if(Date.now() - self.userTypingListener[data.user_id] > 6000){ // stopped typing
+self.trigger("stopTyping",userInCache,channelInCache);self.userTypingListener[data.user_id] = -1;}},6000);break;case "GUILD_ROLE_DELETE":var server=self.getServer("id",data.guild_id);var role=server.getRole(data.role_id);self.trigger("serverRoleDelete",server,role);server.removeRole(role.id);break;case "GUILD_ROLE_UPDATE":var server=self.getServer("id",data.guild_id);var role=server.getRole(data.role.id);var newRole=server.updateRole(data.role);self.trigger("serverRoleUpdate",server,role,newRole);break;default:self.debug("received unknown packet");self.trigger("unknown",dat);break;}};}; //def addUser
+Client.prototype.addUser = function addUser(data){if(!this.getUser("id",data.id)){this.userCache.push(new User(data));}return this.getUser("id",data.id);}; //def addChannel
+Client.prototype.addChannel = function addChannel(data,serverId){if(!this.getChannel("id",data.id)){this.channelCache.push(new Channel(data,this.getServer("id",serverId)));}return this.getChannel("id",data.id);};Client.prototype.addPMChannel = function addPMChannel(data){if(!this.getPMChannel("id",data.id)){this.pmChannelCache.push(new PMChannel(data,this));}return this.getPMChannel("id",data.id);};Client.prototype.setTopic = function setTopic(channel,topic){var callback=arguments.length <= 2 || arguments[2] === undefined?function(err){}:arguments[2];var self=this;return new Promise(function(resolve,reject){self.resolveDestination(channel).then(next)["catch"](error);function error(e){callback(e);reject(e);}function next(destination){var asChan=self.getChannel("id",destination);request.patch(Endpoints.CHANNELS + "/" + destination).set("authorization",self.token).send({name:asChan.name,position:0,topic:topic}).end(function(err,res){if(err){error(err);}else {asChan.topic = res.body.topic;resolve();callback();}});}});}; //def addServer
+Client.prototype.addServer = function addServer(data){var self=this;var server=this.getServer("id",data.id);if(data.unavailable){self.trigger("unavailable",data);self.debug("Server ID " + data.id + " has been marked unavailable by Discord. It was not cached.");return;}if(!server){server = new Server(data,this);this.serverCache.push(server);if(data.channels){for(var _iterator8=data.channels,_isArray8=Array.isArray(_iterator8),_i8=0,_iterator8=_isArray8?_iterator8:_iterator8[Symbol.iterator]();;) {var _ref8;if(_isArray8){if(_i8 >= _iterator8.length)break;_ref8 = _iterator8[_i8++];}else {_i8 = _iterator8.next();if(_i8.done)break;_ref8 = _i8.value;}var channel=_ref8;server.channels.push(this.addChannel(channel,server.id));}}}for(var _iterator9=data.presences,_isArray9=Array.isArray(_iterator9),_i9=0,_iterator9=_isArray9?_iterator9:_iterator9[Symbol.iterator]();;) {var _ref9;if(_isArray9){if(_i9 >= _iterator9.length)break;_ref9 = _iterator9[_i9++];}else {_i9 = _iterator9.next();if(_i9.done)break;_ref9 = _i9.value;}var presence=_ref9;var user=self.getUser("id",presence.user.id);user.status = presence.status;user.gameId = presence.game_id;}return server;}; //def getUser
+Client.prototype.getUser = function getUser(key,value){for(var _iterator10=this.userCache,_isArray10=Array.isArray(_iterator10),_i10=0,_iterator10=_isArray10?_iterator10:_iterator10[Symbol.iterator]();;) {var _ref10;if(_isArray10){if(_i10 >= _iterator10.length)break;_ref10 = _iterator10[_i10++];}else {_i10 = _iterator10.next();if(_i10.done)break;_ref10 = _i10.value;}var user=_ref10;if(user[key] === value){return user;}}return null;}; //def getChannel
+Client.prototype.getChannel = function getChannel(key,value){for(var _iterator11=this.channelCache,_isArray11=Array.isArray(_iterator11),_i11=0,_iterator11=_isArray11?_iterator11:_iterator11[Symbol.iterator]();;) {var _ref11;if(_isArray11){if(_i11 >= _iterator11.length)break;_ref11 = _iterator11[_i11++];}else {_i11 = _iterator11.next();if(_i11.done)break;_ref11 = _i11.value;}var channel=_ref11;if(channel[key] === value){return channel;}}return this.getPMChannel(key,value); //might be a PM
+};Client.prototype.getPMChannel = function getPMChannel(key,value){for(var _iterator12=this.pmChannelCache,_isArray12=Array.isArray(_iterator12),_i12=0,_iterator12=_isArray12?_iterator12:_iterator12[Symbol.iterator]();;) {var _ref12;if(_isArray12){if(_i12 >= _iterator12.length)break;_ref12 = _iterator12[_i12++];}else {_i12 = _iterator12.next();if(_i12.done)break;_ref12 = _i12.value;}var channel=_ref12;if(channel[key] === value){return channel;}}return null;}; //def getServer
+Client.prototype.getServer = function getServer(key,value){for(var _iterator13=this.serverCache,_isArray13=Array.isArray(_iterator13),_i13=0,_iterator13=_isArray13?_iterator13:_iterator13[Symbol.iterator]();;) {var _ref13;if(_isArray13){if(_i13 >= _iterator13.length)break;_ref13 = _iterator13[_i13++];}else {_i13 = _iterator13.next();if(_i13.done)break;_ref13 = _i13.value;}var server=_ref13;if(server[key] === value){return server;}}return null;}; //def trySendConnData
+Client.prototype.trySendConnData = function trySendConnData(){if(this.token && !this.alreadySentData){this.alreadySentData = true;var data={op:2,d:{token:this.token,v:3,properties:{"$os":"discord.js","$browser":"discord.js","$device":"discord.js","$referrer":"","$referring_domain":""}}};this.websocket.send(JSON.stringify(data));}};Client.prototype.resolveServerID = function resolveServerID(resource){if(resource instanceof Server){return resource.id;}else if(!isNaN(resource) && resource.length && resource.length === 17){return resource;}};Client.prototype.resolveDestination = function resolveDestination(destination){var channId=false;var self=this;return new Promise(function(resolve,reject){if(destination instanceof Server){channId = destination.id; //general is the same as server id
+}else if(destination instanceof Channel){channId = destination.id;}else if(destination instanceof Message){channId = destination.channel.id;}else if(destination instanceof PMChannel){channId = destination.id;}else if(destination instanceof User){ //check if we have a PM
+for(var _iterator14=self.pmChannelCache,_isArray14=Array.isArray(_iterator14),_i14=0,_iterator14=_isArray14?_iterator14:_iterator14[Symbol.iterator]();;) {var _ref14;if(_isArray14){if(_i14 >= _iterator14.length)break;_ref14 = _iterator14[_i14++];}else {_i14 = _iterator14.next();if(_i14.done)break;_ref14 = _i14.value;}var pmc=_ref14;if(pmc.user && pmc.user.equals(destination)){resolve(pmc.id);return;}} //we don't, at this point we're late
+self.startPM(destination).then(function(pmc){resolve(pmc.id);})["catch"](reject);}else {channId = destination;}if(channId)resolve(channId);else reject();});};Client.prototype._sendMessage = function _sendMessage(destination,content,tts,mentions){var self=this;return new Promise(function(resolve,reject){request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization",self.token).send({content:content,mentions:mentions,tts:tts}).end(function(err,res){if(err){reject(err);}else {var data=res.body;var mentions=[];data.mentions = data.mentions || []; //for some reason this was not defined at some point?
+for(var _iterator15=data.mentions,_isArray15=Array.isArray(_iterator15),_i15=0,_iterator15=_isArray15?_iterator15:_iterator15[Symbol.iterator]();;) {var _ref15;if(_isArray15){if(_i15 >= _iterator15.length)break;_ref15 = _iterator15[_i15++];}else {_i15 = _iterator15.next();if(_i15.done)break;_ref15 = _i15.value;}var mention=_ref15;mentions.push(self.addUser(mention));}var channel=self.getChannel("id",data.channel_id);if(channel){var msg=channel.addMessage(new Message(data,channel,mentions,self.addUser(data.author)));resolve(msg);}}});});};Client.prototype._sendFile = function _sendFile(destination,attachment){var attachmentName=arguments.length <= 2 || arguments[2] === undefined?"DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png":arguments[2];var self=this;return new Promise(function(resolve,reject){request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization",self.token).attach("file",attachment,attachmentName).end(function(err,res){if(err){reject(err);}else {var chann=self.getChannel("id",destination);if(chann){var msg=chann.addMessage(new Message(res.body,chann,[],self.user));resolve(msg);}}});});};Client.prototype._updateMessage = function _updateMessage(message,content){var self=this;return new Promise(function(resolve,reject){request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization",self.token).send({content:content,mentions:[]}).end(function(err,res){if(err){reject(err);}else {var msg=new Message(res.body,message.channel,message.mentions,message.sender);resolve(msg);message.channel.messages[message.channel.messages.indexOf(message)] = msg;}});});};Client.prototype.getGateway = function getGateway(){var self=this;return new Promise(function(resolve,reject){request.get(Endpoints.API + "/gateway").set("authorization",self.token).end(function(err,res){if(err){reject(err);}else {resolve(res.body.url);}});});};Client.prototype.setStatusIdle = function setStatusIdle(){this.setStatus("idle");};Client.prototype.setStatusOnline = function setStatusOnline(){this.setStatus("online");};Client.prototype.setStatusActive = function setStatusActive(){this.setStatusOnline();};Client.prototype.setStatusHere = function setStatusHere(){this.setStatusOnline();};Client.prototype.setStatusAway = function setStatusAway(){this.setStatusIdle();};Client.prototype.startTyping = function startTyping(chann,stopTypeTime){var self=this;this.resolveDestination(chann).then(next);function next(channel){if(self.typingIntervals[channel]){return;}var fn=function fn(){request.post(Endpoints.CHANNELS + "/" + channel + "/typing").set("authorization",self.token).end();};fn();var interval=setInterval(fn,3000);self.typingIntervals[channel] = interval;if(stopTypeTime){setTimeout(function(){self.stopTyping(channel);},stopTypeTime);}}};Client.prototype.stopTyping = function stopTyping(chann){var self=this;this.resolveDestination(chann).then(next);function next(channel){if(!self.typingIntervals[channel]){return;}clearInterval(self.typingIntervals[channel]);delete self.typingIntervals[channel];}};Client.prototype.setStatus = function setStatus(stat){var idleTime=stat === "online"?null:Date.now();this.__idleTime = idleTime;this.websocket.send(JSON.stringify({op:3,d:{idle_since:this.__idleTime,game_id:this.__gameId}}));};Client.prototype.setPlayingGame = function setPlayingGame(id){if(id instanceof String || typeof id === "string"){ // working on names
+var gid=id.trim().toUpperCase();id = null;for(var _iterator16=gameMap,_isArray16=Array.isArray(_iterator16),_i16=0,_iterator16=_isArray16?_iterator16:_iterator16[Symbol.iterator]();;) {var _ref16;if(_isArray16){if(_i16 >= _iterator16.length)break;_ref16 = _iterator16[_i16++];}else {_i16 = _iterator16.next();if(_i16.done)break;_ref16 = _i16.value;}var game=_ref16;if(game.name.trim().toUpperCase() === gid){id = game.id;break;}}}this.__gameId = id;this.websocket.send(JSON.stringify({op:3,d:{idle_since:this.__idleTime,game_id:this.__gameId}}));};Client.prototype.playGame = function playGame(id){this.setPlayingGame(id);};Client.prototype.playingGame = function playingGame(id){this.setPlayingGame(id);};_createClass(Client,[{key:"uptime",get:function get(){return this.readyTime?Date.now() - this.readyTime:null;}},{key:"ready",get:function get(){return this.state === 3;}},{key:"servers",get:function get(){return this.serverCache;}},{key:"channels",get:function get(){return this.channelCache;}},{key:"users",get:function get(){return this.userCache;}},{key:"PMChannels",get:function get(){return this.pmChannelCache;}},{key:"messages",get:function get(){var msgs=[];for(var _iterator17=this.channelCache,_isArray17=Array.isArray(_iterator17),_i17=0,_iterator17=_isArray17?_iterator17:_iterator17[Symbol.iterator]();;) {var _ref17;if(_isArray17){if(_i17 >= _iterator17.length)break;_ref17 = _iterator17[_i17++];}else {_i17 = _iterator17.next();if(_i17.done)break;_ref17 = _i17.value;}var channel=_ref17;msgs = msgs.concat(channel.messages);}return msgs;}}]);return Client;})();module.exports = Client;
+
+},{"../ref/gameMap.json":19,"./Endpoints.js":3,"./PMChannel.js":6,"./channel.js":8,"./invite.js":10,"./message.js":11,"./server.js":12,"./user.js":13,"fs":14,"superagent":15,"ws":18}],3:[function(require,module,exports){
+"use strict";exports.BASE_DOMAIN = "discordapp.com";exports.BASE = "https://" + exports.BASE_DOMAIN;exports.WEBSOCKET_HUB = "wss://" + exports.BASE_DOMAIN + "/hub";exports.API = exports.BASE + "/api";exports.AUTH = exports.API + "/auth";exports.LOGIN = exports.AUTH + "/login";exports.LOGOUT = exports.AUTH + "/logout";exports.USERS = exports.API + "/users";exports.SERVERS = exports.API + "/guilds";exports.CHANNELS = exports.API + "/channels";
+
+},{}],4:[function(require,module,exports){
+"use strict";var _createClass=(function(){function defineProperties(target,props){for(var i=0;i < props.length;i++) {var descriptor=props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if("value" in descriptor)descriptor.writable = true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};})();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}var EvaluatedPermissions=(function(){function EvaluatedPermissions(data){_classCallCheck(this,EvaluatedPermissions);var self=this;function getBit(x){if((self.packed >>> 3 & 1) === 1){return true;}return (self.packed >>> x & 1) === 1;}this.packed = data;}EvaluatedPermissions.prototype.getBit = function getBit(x){return (this.packed >>> x & 1) === 1;};EvaluatedPermissions.prototype.setBit = function setBit(){};_createClass(EvaluatedPermissions,[{key:"createInstantInvite",get:function get(){return this.getBit(0);},set:function set(val){this.setBit(0,val);}},{key:"manageRoles",get:function get(){return this.getBit(3);},set:function set(val){this.setBit(3,val);}},{key:"manageChannels",get:function get(){return this.getBit(4);},set:function set(val){this.setBit(4,val);}},{key:"readMessages",get:function get(){return this.getBit(10);},set:function set(val){this.setBit(10,val);}},{key:"sendMessages",get:function get(){return this.getBit(11);},set:function set(val){this.setBit(11,val);}},{key:"sendTTSMessages",get:function get(){return this.getBit(12);},set:function set(val){this.setBit(12,val);}},{key:"manageMessages",get:function get(){return this.getBit(13);},set:function set(val){this.setBit(13,val);}},{key:"embedLinks",get:function get(){return this.getBit(14);},set:function set(val){this.setBit(14,val);}},{key:"attachFiles",get:function get(){return this.getBit(15);},set:function set(val){this.setBit(15,val);}},{key:"readMessageHistory",get:function get(){return this.getBit(16);},set:function set(val){this.setBit(16,val);}},{key:"mentionEveryone",get:function get(){return this.getBit(17);},set:function set(val){this.setBit(17,val);}},{key:"voiceConnect",get:function get(){return this.getBit(20);},set:function set(val){this.setBit(20,val);}},{key:"voiceSpeak",get:function get(){return this.getBit(21);},set:function set(val){this.setBit(21,val);}},{key:"voiceMuteMembers",get:function get(){return this.getBit(22);},set:function set(val){this.setBit(22,val);}},{key:"voiceDeafenMembers",get:function get(){return this.getBit(23);},set:function set(val){this.setBit(23,val);}},{key:"voiceMoveMembers",get:function get(){return this.getBit(24);},set:function set(val){this.setBit(24,val);}},{key:"voiceUseVoiceActivation",get:function get(){return this.getBit(25);},set:function set(val){this.setBit(25,val);}}]);return EvaluatedPermissions;})();module.exports = EvaluatedPermissions;
+
+},{}],5:[function(require,module,exports){
+"use strict";var _createClass=(function(){function defineProperties(target,props){for(var i=0;i < props.length;i++) {var descriptor=props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if("value" in descriptor)descriptor.writable = true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};})();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}function _inherits(subClass,superClass){if(typeof superClass !== "function" && superClass !== null){throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);}subClass.prototype = Object.create(superClass && superClass.prototype,{constructor:{value:subClass,enumerable:false,writable:true,configurable:true}});if(superClass)Object.setPrototypeOf?Object.setPrototypeOf(subClass,superClass):subClass.__proto__ = superClass;}var User=require("./user.js");var ServerPermissions=require("./ServerPermissions.js");var EvaluatedPermissions=require("./EvaluatedPermissions.js");var Member=(function(_User){_inherits(Member,_User);function Member(user,server,roles){_classCallCheck(this,Member);_User.call(this,user); // should work, we are basically creating a Member that has the same properties as user and a few more
+this.server = server;this.rawRoles = roles;}Member.prototype.permissionsIn = function permissionsIn(channel){if(channel.server.ownerID === this.id){return new EvaluatedPermissions(4294967295); //all perms
+}var affectingOverwrites=[];var affectingMemberOverwrites=[];for(var _iterator=channel.roles,_isArray=Array.isArray(_iterator),_i=0,_iterator=_isArray?_iterator:_iterator[Symbol.iterator]();;) {var _ref;if(_isArray){if(_i >= _iterator.length)break;_ref = _iterator[_i++];}else {_i = _iterator.next();if(_i.done)break;_ref = _i.value;}var overwrite=_ref;if(overwrite.id === this.id && overwrite.type === "member"){affectingMemberOverwrites.push(overwrite);}else if(this.rawRoles.indexOf(overwrite.id) !== -1){affectingOverwrites.push(overwrite);}}for(var _iterator2=affectingOverwrites,_isArray2=Array.isArray(_iterator2),_i2=0,_iterator2=_isArray2?_iterator2:_iterator2[Symbol.iterator]();;) {var _ref2;if(_isArray2){if(_i2 >= _iterator2.length)break;_ref2 = _iterator2[_i2++];}else {_i2 = _iterator2.next();if(_i2.done)break;_ref2 = _i2.value;}var perm=_ref2;console.log("hey",perm.attachFiles);}if(affectingOverwrites.length === 0 && affectingMemberOverwrites.length === 0){return new EvaluatedPermissions(this.evalPerms.packed);}var finalPacked=affectingOverwrites.length !== 0?affectingOverwrites[0].packed:affectingMemberOverwrites[0].packed;for(var _iterator3=affectingOverwrites,_isArray3=Array.isArray(_iterator3),_i3=0,_iterator3=_isArray3?_iterator3:_iterator3[Symbol.iterator]();;) {var _ref3;if(_isArray3){if(_i3 >= _iterator3.length)break;_ref3 = _iterator3[_i3++];}else {_i3 = _iterator3.next();if(_i3.done)break;_ref3 = _i3.value;}var overwrite=_ref3;finalPacked = finalPacked & ~overwrite.deny;finalPacked = finalPacked | overwrite.allow;}for(var _iterator4=affectingMemberOverwrites,_isArray4=Array.isArray(_iterator4),_i4=0,_iterator4=_isArray4?_iterator4:_iterator4[Symbol.iterator]();;) {var _ref4;if(_isArray4){if(_i4 >= _iterator4.length)break;_ref4 = _iterator4[_i4++];}else {_i4 = _iterator4.next();if(_i4.done)break;_ref4 = _i4.value;}var overwrite=_ref4;finalPacked = finalPacked & ~overwrite.deny;finalPacked = finalPacked | overwrite.allow;}return new EvaluatedPermissions(finalPacked);};_createClass(Member,[{key:"roles",get:function get(){var ufRoles=[this.server.getRole(this.server.id)];for(var _iterator5=this.rawRoles,_isArray5=Array.isArray(_iterator5),_i5=0,_iterator5=_isArray5?_iterator5:_iterator5[Symbol.iterator]();;) {var _ref5;if(_isArray5){if(_i5 >= _iterator5.length)break;_ref5 = _iterator5[_i5++];}else {_i5 = _iterator5.next();if(_i5.done)break;_ref5 = _i5.value;}var rawRole=_ref5;ufRoles.push(this.server.getRole(rawRole));}return ufRoles;}},{key:"evalPerms",get:function get(){var basePerms=this.roles, //cache roles as it can be slightly expensive
+basePerm=basePerms[0].packed;for(var _iterator6=basePerms,_isArray6=Array.isArray(_iterator6),_i6=0,_iterator6=_isArray6?_iterator6:_iterator6[Symbol.iterator]();;) {var _ref6;if(_isArray6){if(_i6 >= _iterator6.length)break;_ref6 = _iterator6[_i6++];}else {_i6 = _iterator6.next();if(_i6.done)break;_ref6 = _i6.value;}var perm=_ref6;basePerm = basePerm | perm.packed;}return new ServerPermissions({permissions:basePerm});}}]);return Member;})(User);module.exports = Member;
+
+},{"./EvaluatedPermissions.js":4,"./ServerPermissions.js":7,"./user.js":13}],6:[function(require,module,exports){
+"use strict";var _createClass=(function(){function defineProperties(target,props){for(var i=0;i < props.length;i++) {var descriptor=props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if("value" in descriptor)descriptor.writable = true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};})();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}var PMChannel=(function(){function PMChannel(data,client){_classCallCheck(this,PMChannel);this.user = client.getUser("id",data.recipient.id);this.id = data.id;this.messages = [];this.client = client;}PMChannel.prototype.addMessage = function addMessage(data){if(!this.getMessage("id",data.id)){this.messages.push(data);}return this.getMessage("id",data.id);};PMChannel.prototype.getMessage = function getMessage(key,value){if(this.messages.length > 1000){this.messages.splice(0,1);}for(var _iterator=this.messages,_isArray=Array.isArray(_iterator),_i=0,_iterator=_isArray?_iterator:_iterator[Symbol.iterator]();;) {var _ref;if(_isArray){if(_i >= _iterator.length)break;_ref = _iterator[_i++];}else {_i = _iterator.next();if(_i.done)break;_ref = _i.value;}var message=_ref;if(message[key] === value){return message;}}return null;};_createClass(PMChannel,[{key:"isPrivate",get:function get(){return true;}}]);return PMChannel;})();module.exports = PMChannel;
+
+},{}],7:[function(require,module,exports){
+"use strict";var _createClass=(function(){function defineProperties(target,props){for(var i=0;i < props.length;i++) {var descriptor=props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if("value" in descriptor)descriptor.writable = true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};})();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}var ServerPermissions=(function(){function ServerPermissions(data){_classCallCheck(this,ServerPermissions);var self=this;function getBit(x){return (self.packed >>> x & 1) === 1;}this.packed = data.permissions;this.name = data.name;this.id = data.id;}ServerPermissions.prototype.getBit = function getBit(x){return (this.packed >>> x & 1) === 1;};ServerPermissions.prototype.setBit = function setBit(){ //dummy function for now
+};ServerPermissions.prototype.toString = function toString(){return this.name;};_createClass(ServerPermissions,[{key:"createInstantInvite",get:function get(){return this.getBit(0);},set:function set(val){this.setBit(0,val);}},{key:"banMembers",get:function get(){return this.getBit(1);},set:function set(val){this.setBit(1,val);}},{key:"kickMembers",get:function get(){return this.getBit(2);},set:function set(val){this.setBit(2,val);}},{key:"manageRoles",get:function get(){return this.getBit(3);},set:function set(val){this.setBit(3,val);}},{key:"manageChannels",get:function get(){return this.getBit(4);},set:function set(val){this.setBit(4,val);}},{key:"manageServer",get:function get(){return this.getBit(5);},set:function set(val){this.setBit(5,val);}},{key:"readMessages",get:function get(){return this.getBit(10);},set:function set(val){this.setBit(10,val);}},{key:"sendMessages",get:function get(){return this.getBit(11);},set:function set(val){this.setBit(11,val);}},{key:"sendTTSMessages",get:function get(){return this.getBit(12);},set:function set(val){this.setBit(12,val);}},{key:"manageMessages",get:function get(){return this.getBit(13);},set:function set(val){this.setBit(13,val);}},{key:"embedLinks",get:function get(){return this.getBit(14);},set:function set(val){this.setBit(14,val);}},{key:"attachFiles",get:function get(){return this.getBit(15);},set:function set(val){this.setBit(15,val);}},{key:"readMessageHistory",get:function get(){return this.getBit(16);},set:function set(val){this.setBit(16,val);}},{key:"mentionEveryone",get:function get(){return this.getBit(17);},set:function set(val){this.setBit(17,val);}},{key:"voiceConnect",get:function get(){return this.getBit(20);},set:function set(val){this.setBit(20,val);}},{key:"voiceSpeak",get:function get(){return this.getBit(21);},set:function set(val){this.setBit(21,val);}},{key:"voiceMuteMembers",get:function get(){return this.getBit(22);},set:function set(val){this.setBit(22,val);}},{key:"voiceDeafenMembers",get:function get(){return this.getBit(23);},set:function set(val){this.setBit(23,val);}},{key:"voiceMoveMembers",get:function get(){return this.getBit(24);},set:function set(val){this.setBit(24,val);}},{key:"voiceUseVoiceActivation",get:function get(){return this.getBit(25);},set:function set(val){this.setBit(25,val);}}]);return ServerPermissions;})();module.exports = ServerPermissions;
+
+},{}],8:[function(require,module,exports){
+"use strict";var _createClass=(function(){function defineProperties(target,props){for(var i=0;i < props.length;i++) {var descriptor=props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if("value" in descriptor)descriptor.writable = true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};})();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}var ChannelPermissions=require("./ChannelPermissions.js");var Channel=(function(){function Channel(data,server){_classCallCheck(this,Channel);this.server = server;this.name = data.name;this.type = data.type;this.topic = data.topic;this.id = data.id;this.messages = [];this.roles = [];if(data.permission_overwrites)for(var _iterator=data.permission_overwrites,_isArray=Array.isArray(_iterator),_i=0,_iterator=_isArray?_iterator:_iterator[Symbol.iterator]();;) {var _ref;if(_isArray){if(_i >= _iterator.length)break;_ref = _iterator[_i++];}else {_i = _iterator.next();if(_i.done)break;_ref = _i.value;}var role=_ref;this.roles.push(new ChannelPermissions(role,this));} //this.isPrivate = isPrivate; //not sure about the implementation of this...
+}Channel.prototype.permissionsOf = function permissionsOf(member){var mem=this.server.getMember("id",member.id);if(mem){return mem.permissionsIn(this);}else {return null;}};Channel.prototype.equals = function equals(object){return object && object.id === this.id;};Channel.prototype.addMessage = function addMessage(data){if(this.messages.length > 1000){this.messages.splice(0,1);}if(!this.getMessage("id",data.id)){this.messages.push(data);}return this.getMessage("id",data.id);};Channel.prototype.getMessage = function getMessage(key,value){for(var _iterator2=this.messages,_isArray2=Array.isArray(_iterator2),_i2=0,_iterator2=_isArray2?_iterator2:_iterator2[Symbol.iterator]();;) {var _ref2;if(_isArray2){if(_i2 >= _iterator2.length)break;_ref2 = _iterator2[_i2++];}else {_i2 = _iterator2.next();if(_i2.done)break;_ref2 = _i2.value;}var message=_ref2;if(message[key] === value){return message;}}return null;};Channel.prototype.toString = function toString(){return "<#" + this.id + ">";};_createClass(Channel,[{key:"permissionOverwrites",get:function get(){return this.roles;}},{key:"permissions",get:function get(){return this.roles;}},{key:"client",get:function get(){return this.server.client;}},{key:"isPrivate",get:function get(){return false;}},{key:"users",get:function get(){return this.server.members;}},{key:"members",get:function get(){return this.server.members;}}]);return Channel;})();module.exports = Channel;
+
+},{"./ChannelPermissions.js":1}],9:[function(require,module,exports){
+"use strict";var request=require("superagent");var Endpoints=require("./Endpoints.js");var Client=require("./Client.js");var Discord={Endpoints:Endpoints,Client:Client};module.exports = Discord;
+
+},{"./Client.js":2,"./Endpoints.js":3,"superagent":15}],10:[function(require,module,exports){
+"use strict";var _createClass=(function(){function defineProperties(target,props){for(var i=0;i < props.length;i++) {var descriptor=props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if("value" in descriptor)descriptor.writable = true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};})();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}var Invite=(function(){function Invite(data,client){_classCallCheck(this,Invite);this.max_age = data.max_age;this.code = data.code;this.server = client.getServer("id",data.guild.id);this.revoked = data.revoked;this.created_at = Date.parse(data.created_at);this.temporary = data.temporary;this.uses = data.uses;this.max_uses = data.uses;this.inviter = client.addUser(data.inviter);this.xkcd = data.xkcdpass;this.channel = client.getChannel("id",data.channel.id);}_createClass(Invite,[{key:"URL",get:function get(){var code=this.xkcd?this.xkcdpass:this.code;return "https://discord.gg/" + code;}}]);return Invite;})();module.exports = Invite;
+
+},{}],11:[function(require,module,exports){
+"use strict";var _createClass=(function(){function defineProperties(target,props){for(var i=0;i < props.length;i++) {var descriptor=props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if("value" in descriptor)descriptor.writable = true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};})();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}var PMChannel=require("./PMChannel.js");var Message=(function(){function Message(data,channel,mentions,author){_classCallCheck(this,Message);this.tts = data.tts;this.timestamp = Date.parse(data.timestamp);this.nonce = data.nonce;this.mentions = mentions;this.everyoneMentioned = data.mention_everyone;this.id = data.id;this.embeds = data.embeds;this.editedTimestamp = data.edited_timestamp;this.content = data.content.trim();this.channel = channel;if(this.isPrivate){this.author = this.channel.client.getUser("id",author.id);}else {this.author = this.channel.server.getMember("id",author.id) || this.channel.client.getUser("id",author.id);}this.attachments = data.attachments;} /*exports.Message.prototype.isPM = function() {
+ return ( this.channel instanceof PMChannel );
+}*/Message.prototype.isMentioned = function isMentioned(user){var id=user.id?user.id:user;for(var _iterator=this.mentions,_isArray=Array.isArray(_iterator),_i=0,_iterator=_isArray?_iterator:_iterator[Symbol.iterator]();;) {var _ref;if(_isArray){if(_i >= _iterator.length)break;_ref = _iterator[_i++];}else {_i = _iterator.next();if(_i.done)break;_ref = _i.value;}var mention=_ref;if(mention.id === id){return true;}}return false;};_createClass(Message,[{key:"sender",get:function get(){return this.author;}},{key:"isPrivate",get:function get(){return this.channel.isPrivate;}}]);return Message;})();module.exports = Message;
+
+},{"./PMChannel.js":6}],12:[function(require,module,exports){
+"use strict";var _createClass=(function(){function defineProperties(target,props){for(var i=0;i < props.length;i++) {var descriptor=props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if("value" in descriptor)descriptor.writable = true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};})();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}var ServerPermissions=require("./ServerPermissions.js");var Member=require("./Member.js");var Server=(function(){function Server(data,client){_classCallCheck(this,Server);this.client = client;this.region = data.region;this.ownerID = data.owner_id;this.name = data.name;this.id = data.id;this.members = [];this.channels = [];this.icon = data.icon;this.afkTimeout = data.afk_timeout;this.afkChannelId = data.afk_channel_id;this.roles = [];for(var _iterator=data.roles,_isArray=Array.isArray(_iterator),_i=0,_iterator=_isArray?_iterator:_iterator[Symbol.iterator]();;) {var _ref;if(_isArray){if(_i >= _iterator.length)break;_ref = _iterator[_i++];}else {_i = _iterator.next();if(_i.done)break;_ref = _i.value;}var permissionGroup=_ref;this.roles.push(new ServerPermissions(permissionGroup));}if(!data.members){data.members = [client.user];return;}for(var _iterator2=data.members,_isArray2=Array.isArray(_iterator2),_i2=0,_iterator2=_isArray2?_iterator2:_iterator2[Symbol.iterator]();;) {var _ref2;if(_isArray2){if(_i2 >= _iterator2.length)break;_ref2 = _iterator2[_i2++];}else {_i2 = _iterator2.next();if(_i2.done)break;_ref2 = _i2.value;}var member=_ref2; // first we cache the user in our Discord Client,
+// then we add it to our list. This way when we
+// get a user from this server's member list,
+// it will be identical (unless an async change occurred)
+// to the client's cache.
+if(member.user)this.addMember(client.addUser(member.user),member.roles);}} // get/set
+Server.prototype.getRole = function getRole(id){for(var _iterator3=this.roles,_isArray3=Array.isArray(_iterator3),_i3=0,_iterator3=_isArray3?_iterator3:_iterator3[Symbol.iterator]();;) {var _ref3;if(_isArray3){if(_i3 >= _iterator3.length)break;_ref3 = _iterator3[_i3++];}else {_i3 = _iterator3.next();if(_i3.done)break;_ref3 = _i3.value;}var role=_ref3;if(role.id === id){return role;}}return null;};Server.prototype.updateRole = function updateRole(data){var oldRole=this.getRole(data.id);if(oldRole){var index=this.roles.indexOf(oldRole);this.roles[index] = new ServerPermissions(data);return this.roles[index];}else {return false;}};Server.prototype.removeRole = function removeRole(id){for(var roleId in this.roles) {if(this.roles[roleId].id === id){this.roles.splice(roleId,1);}}for(var _iterator4=this.members,_isArray4=Array.isArray(_iterator4),_i4=0,_iterator4=_isArray4?_iterator4:_iterator4[Symbol.iterator]();;) {var _ref4;if(_isArray4){if(_i4 >= _iterator4.length)break;_ref4 = _iterator4[_i4++];}else {_i4 = _iterator4.next();if(_i4.done)break;_ref4 = _i4.value;}var member=_ref4;for(var roleId in member.rawRoles) {if(member.rawRoles[roleId] === id){member.rawRoles.splice(roleId,1);}}}};Server.prototype.getChannel = function getChannel(key,value){for(var _iterator5=this.channels,_isArray5=Array.isArray(_iterator5),_i5=0,_iterator5=_isArray5?_iterator5:_iterator5[Symbol.iterator]();;) {var _ref5;if(_isArray5){if(_i5 >= _iterator5.length)break;_ref5 = _iterator5[_i5++];}else {_i5 = _iterator5.next();if(_i5.done)break;_ref5 = _i5.value;}var channel=_ref5;if(channel[key] === value){return channel;}}return null;};Server.prototype.getMember = function getMember(key,value){for(var _iterator6=this.members,_isArray6=Array.isArray(_iterator6),_i6=0,_iterator6=_isArray6?_iterator6:_iterator6[Symbol.iterator]();;) {var _ref6;if(_isArray6){if(_i6 >= _iterator6.length)break;_ref6 = _iterator6[_i6++];}else {_i6 = _iterator6.next();if(_i6.done)break;_ref6 = _i6.value;}var member=_ref6;if(member[key] === value){return member;}}return null;};Server.prototype.removeMember = function removeMember(key,value){for(var _iterator7=this.members,_isArray7=Array.isArray(_iterator7),_i7=0,_iterator7=_isArray7?_iterator7:_iterator7[Symbol.iterator]();;) {var _ref7;if(_isArray7){if(_i7 >= _iterator7.length)break;_ref7 = _iterator7[_i7++];}else {_i7 = _iterator7.next();if(_i7.done)break;_ref7 = _i7.value;}var member=_ref7;if(member[key] === value){this.members.splice(key,1);return member;}}return false;};Server.prototype.addChannel = function addChannel(chann){if(!this.getChannel("id",chann.id)){this.channels.push(chann);}return chann;};Server.prototype.addMember = function addMember(user,roles){if(!this.getMember("id",user.id)){var mem=new Member(user,this,roles);this.members.push(mem);}return mem;};Server.prototype.toString = function toString(){return this.name;};Server.prototype.equals = function equals(object){return object.id === this.id;};_createClass(Server,[{key:"permissionGroups",get:function get(){return this.roles;}},{key:"permissions",get:function get(){return this.roles;}},{key:"iconURL",get:function get(){if(!this.icon)return null;return "https://discordapp.com/api/guilds/" + this.id + "/icons/" + this.icon + ".jpg";}},{key:"afkChannel",get:function get(){if(!this.afkChannelId)return false;return this.getChannel("id",this.afkChannelId);}},{key:"defaultChannel",get:function get(){return this.getChannel("name","general");}},{key:"owner",get:function get(){return this.client.getUser("id",this.ownerID);}},{key:"users",get:function get(){return this.members;}}]);return Server;})();module.exports = Server;
+
+},{"./Member.js":5,"./ServerPermissions.js":7}],13:[function(require,module,exports){
+"use strict";var _createClass=(function(){function defineProperties(target,props){for(var i=0;i < props.length;i++) {var descriptor=props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if("value" in descriptor)descriptor.writable = true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};})();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}var User=(function(){function User(data){_classCallCheck(this,User);this.username = data.username;this.discriminator = data.discriminator;this.id = data.id;this.avatar = data.avatar;this.status = data.status || "offline";this.gameId = data.game_id || null;} // access using user.avatarURL;
+User.prototype.mention = function mention(){return "<@" + this.id + ">";};User.prototype.toString = function toString(){ /*
+ if we embed a user in a String - like so:
+ "Yo " + user + " what's up?"
+ It would generate something along the lines of:
+ "Yo @hydrabolt what's up?"
+ */return this.mention();};User.prototype.equals = function equals(object){return object.id === this.id;};User.prototype.equalsStrict = function equalsStrict(object){return object.id === this.id && object.avatar === this.avatar && object.username === this.username && object.discriminator === this.discriminator;};_createClass(User,[{key:"avatarURL",get:function get(){if(!this.avatar)return null;return "https://discordapp.com/api/users/" + this.id + "/avatars/" + this.avatar + ".jpg";}}]);return User;})();module.exports = User;
+
+},{}],14:[function(require,module,exports){
+
+},{}],15:[function(require,module,exports){
+/**
+ * Module dependencies.
+ */
+
+var Emitter = require('emitter');
+var reduce = require('reduce');
+
+/**
+ * Root reference for iframes.
+ */
+
+var root;
+if (typeof window !== 'undefined') { // Browser window
+ root = window;
+} else if (typeof self !== 'undefined') { // Web Worker
+ root = self;
+} else { // Other environments
+ root = this;
+}
+
+/**
+ * Noop.
+ */
+
+function noop(){};
+
+/**
+ * Check if `obj` is a host object,
+ * we don't want to serialize these :)
+ *
+ * TODO: future proof, move to compoent land
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api private
+ */
+
+function isHost(obj) {
+ var str = {}.toString.call(obj);
+
+ switch (str) {
+ case '[object File]':
+ case '[object Blob]':
+ case '[object FormData]':
+ return true;
+ default:
+ return false;
+ }
+}
+
+/**
+ * Determine XHR.
+ */
+
+request.getXHR = function () {
+ if (root.XMLHttpRequest
+ && (!root.location || 'file:' != root.location.protocol
+ || !root.ActiveXObject)) {
+ return new XMLHttpRequest;
+ } else {
+ try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
+ }
+ return false;
+};
+
+/**
+ * Removes leading and trailing whitespace, added to support IE.
+ *
+ * @param {String} s
+ * @return {String}
+ * @api private
+ */
+
+var trim = ''.trim
+ ? function(s) { return s.trim(); }
+ : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); };
+
+/**
+ * Check if `obj` is an object.
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api private
+ */
+
+function isObject(obj) {
+ return obj === Object(obj);
+}
+
+/**
+ * Serialize the given `obj`.
+ *
+ * @param {Object} obj
+ * @return {String}
+ * @api private
+ */
+
+function serialize(obj) {
+ if (!isObject(obj)) return obj;
+ var pairs = [];
+ for (var key in obj) {
+ if (null != obj[key]) {
+ pairs.push(encodeURIComponent(key)
+ + '=' + encodeURIComponent(obj[key]));
+ }
+ }
+ return pairs.join('&');
+}
+
+/**
+ * Expose serialization method.
+ */
+
+ request.serializeObject = serialize;
+
+ /**
+ * Parse the given x-www-form-urlencoded `str`.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function parseString(str) {
+ var obj = {};
+ var pairs = str.split('&');
+ var parts;
+ var pair;
+
+ for (var i = 0, len = pairs.length; i < len; ++i) {
+ pair = pairs[i];
+ parts = pair.split('=');
+ obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
+ }
+
+ return obj;
+}
+
+/**
+ * Expose parser.
+ */
+
+request.parseString = parseString;
+
+/**
+ * Default MIME type map.
+ *
+ * superagent.types.xml = 'application/xml';
+ *
+ */
+
+request.types = {
+ html: 'text/html',
+ json: 'application/json',
+ xml: 'application/xml',
+ urlencoded: 'application/x-www-form-urlencoded',
+ 'form': 'application/x-www-form-urlencoded',
+ 'form-data': 'application/x-www-form-urlencoded'
+};
+
+/**
+ * Default serialization map.
+ *
+ * superagent.serialize['application/xml'] = function(obj){
+ * return 'generated xml here';
+ * };
+ *
+ */
+
+ request.serialize = {
+ 'application/x-www-form-urlencoded': serialize,
+ 'application/json': JSON.stringify
+ };
+
+ /**
+ * Default parsers.
+ *
+ * superagent.parse['application/xml'] = function(str){
+ * return { object parsed from str };
+ * };
+ *
+ */
+
+request.parse = {
+ 'application/x-www-form-urlencoded': parseString,
+ 'application/json': JSON.parse
+};
+
+/**
+ * Parse the given header `str` into
+ * an object containing the mapped fields.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function parseHeader(str) {
+ var lines = str.split(/\r?\n/);
+ var fields = {};
+ var index;
+ var line;
+ var field;
+ var val;
+
+ lines.pop(); // trailing CRLF
+
+ for (var i = 0, len = lines.length; i < len; ++i) {
+ line = lines[i];
+ index = line.indexOf(':');
+ field = line.slice(0, index).toLowerCase();
+ val = trim(line.slice(index + 1));
+ fields[field] = val;
+ }
+
+ return fields;
+}
+
+/**
+ * Return the mime type for the given `str`.
+ *
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+function type(str){
+ return str.split(/ *; */).shift();
+};
+
+/**
+ * Return header field parameters.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function params(str){
+ return reduce(str.split(/ *; */), function(obj, str){
+ var parts = str.split(/ *= */)
+ , key = parts.shift()
+ , val = parts.shift();
+
+ if (key && val) obj[key] = val;
+ return obj;
+ }, {});
+};
+
+/**
+ * Initialize a new `Response` with the given `xhr`.
+ *
+ * - set flags (.ok, .error, etc)
+ * - parse header
+ *
+ * Examples:
+ *
+ * Aliasing `superagent` as `request` is nice:
+ *
+ * request = superagent;
+ *
+ * We can use the promise-like API, or pass callbacks:
+ *
+ * request.get('/').end(function(res){});
+ * request.get('/', function(res){});
+ *
+ * Sending data can be chained:
+ *
+ * request
+ * .post('/user')
+ * .send({ name: 'tj' })
+ * .end(function(res){});
+ *
+ * Or passed to `.send()`:
+ *
+ * request
+ * .post('/user')
+ * .send({ name: 'tj' }, function(res){});
+ *
+ * Or passed to `.post()`:
+ *
+ * request
+ * .post('/user', { name: 'tj' })
+ * .end(function(res){});
+ *
+ * Or further reduced to a single call for simple cases:
+ *
+ * request
+ * .post('/user', { name: 'tj' }, function(res){});
+ *
+ * @param {XMLHTTPRequest} xhr
+ * @param {Object} options
+ * @api private
+ */
+
+function Response(req, options) {
+ options = options || {};
+ this.req = req;
+ this.xhr = this.req.xhr;
+ // responseText is accessible only if responseType is '' or 'text' and on older browsers
+ this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined')
+ ? this.xhr.responseText
+ : null;
+ this.statusText = this.req.xhr.statusText;
+ this.setStatusProperties(this.xhr.status);
+ this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders());
+ // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but
+ // getResponseHeader still works. so we get content-type even if getting
+ // other headers fails.
+ this.header['content-type'] = this.xhr.getResponseHeader('content-type');
+ this.setHeaderProperties(this.header);
+ this.body = this.req.method != 'HEAD'
+ ? this.parseBody(this.text ? this.text : this.xhr.response)
+ : null;
+}
+
+/**
+ * Get case-insensitive `field` value.
+ *
+ * @param {String} field
+ * @return {String}
+ * @api public
+ */
+
+Response.prototype.get = function(field){
+ return this.header[field.toLowerCase()];
+};
+
+/**
+ * Set header related properties:
+ *
+ * - `.type` the content type without params
+ *
+ * A response of "Content-Type: text/plain; charset=utf-8"
+ * will provide you with a `.type` of "text/plain".
+ *
+ * @param {Object} header
+ * @api private
+ */
+
+Response.prototype.setHeaderProperties = function(header){
+ // content-type
+ var ct = this.header['content-type'] || '';
+ this.type = type(ct);
+
+ // params
+ var obj = params(ct);
+ for (var key in obj) this[key] = obj[key];
+};
+
+/**
+ * Force given parser
+ *
+ * Sets the body parser no matter type.
+ *
+ * @param {Function}
+ * @api public
+ */
+
+Response.prototype.parse = function(fn){
+ this.parser = fn;
+ return this;
+};
+
+/**
+ * Parse the given body `str`.
+ *
+ * Used for auto-parsing of bodies. Parsers
+ * are defined on the `superagent.parse` object.
+ *
+ * @param {String} str
+ * @return {Mixed}
+ * @api private
+ */
+
+Response.prototype.parseBody = function(str){
+ var parse = this.parser || request.parse[this.type];
+ return parse && str && (str.length || str instanceof Object)
+ ? parse(str)
+ : null;
+};
+
+/**
+ * Set flags such as `.ok` based on `status`.
+ *
+ * For example a 2xx response will give you a `.ok` of __true__
+ * whereas 5xx will be __false__ and `.error` will be __true__. The
+ * `.clientError` and `.serverError` are also available to be more
+ * specific, and `.statusType` is the class of error ranging from 1..5
+ * sometimes useful for mapping respond colors etc.
+ *
+ * "sugar" properties are also defined for common cases. Currently providing:
+ *
+ * - .noContent
+ * - .badRequest
+ * - .unauthorized
+ * - .notAcceptable
+ * - .notFound
+ *
+ * @param {Number} status
+ * @api private
+ */
+
+Response.prototype.setStatusProperties = function(status){
+ // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
+ if (status === 1223) {
+ status = 204;
+ }
+
+ var type = status / 100 | 0;
+
+ // status / class
+ this.status = this.statusCode = status;
+ this.statusType = type;
+
+ // basics
+ this.info = 1 == type;
+ this.ok = 2 == type;
+ this.clientError = 4 == type;
+ this.serverError = 5 == type;
+ this.error = (4 == type || 5 == type)
+ ? this.toError()
+ : false;
+
+ // sugar
+ this.accepted = 202 == status;
+ this.noContent = 204 == status;
+ this.badRequest = 400 == status;
+ this.unauthorized = 401 == status;
+ this.notAcceptable = 406 == status;
+ this.notFound = 404 == status;
+ this.forbidden = 403 == status;
+};
+
+/**
+ * Return an `Error` representative of this response.
+ *
+ * @return {Error}
+ * @api public
+ */
+
+Response.prototype.toError = function(){
+ var req = this.req;
+ var method = req.method;
+ var url = req.url;
+
+ var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')';
+ var err = new Error(msg);
+ err.status = this.status;
+ err.method = method;
+ err.url = url;
+
+ return err;
+};
+
+/**
+ * Expose `Response`.
+ */
+
+request.Response = Response;
+
+/**
+ * Initialize a new `Request` with the given `method` and `url`.
+ *
+ * @param {String} method
+ * @param {String} url
+ * @api public
+ */
+
+function Request(method, url) {
+ var self = this;
+ Emitter.call(this);
+ this._query = this._query || [];
+ this.method = method;
+ this.url = url;
+ this.header = {};
+ this._header = {};
+ this.on('end', function(){
+ var err = null;
+ var res = null;
+
+ try {
+ res = new Response(self);
+ } catch(e) {
+ err = new Error('Parser is unable to parse the response');
+ err.parse = true;
+ err.original = e;
+ return self.callback(err);
+ }
+
+ self.emit('response', res);
+
+ if (err) {
+ return self.callback(err, res);
+ }
+
+ if (res.status >= 200 && res.status < 300) {
+ return self.callback(err, res);
+ }
+
+ var new_err = new Error(res.statusText || 'Unsuccessful HTTP response');
+ new_err.original = err;
+ new_err.response = res;
+ new_err.status = res.status;
+
+ self.callback(new_err, res);
+ });
+}
+
+/**
+ * Mixin `Emitter`.
+ */
+
+Emitter(Request.prototype);
+
+/**
+ * Allow for extension
+ */
+
+Request.prototype.use = function(fn) {
+ fn(this);
+ return this;
+}
+
+/**
+ * Set timeout to `ms`.
+ *
+ * @param {Number} ms
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.timeout = function(ms){
+ this._timeout = ms;
+ return this;
+};
+
+/**
+ * Clear previous timeout.
+ *
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.clearTimeout = function(){
+ this._timeout = 0;
+ clearTimeout(this._timer);
+ return this;
+};
+
+/**
+ * Abort the request, and clear potential timeout.
+ *
+ * @return {Request}
+ * @api public
+ */
+
+Request.prototype.abort = function(){
+ if (this.aborted) return;
+ this.aborted = true;
+ this.xhr.abort();
+ this.clearTimeout();
+ this.emit('abort');
+ return this;
+};
+
+/**
+ * Set header `field` to `val`, or multiple fields with one object.
+ *
+ * Examples:
+ *
+ * req.get('/')
+ * .set('Accept', 'application/json')
+ * .set('X-API-Key', 'foobar')
+ * .end(callback);
+ *
+ * req.get('/')
+ * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
+ * .end(callback);
+ *
+ * @param {String|Object} field
+ * @param {String} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.set = function(field, val){
+ if (isObject(field)) {
+ for (var key in field) {
+ this.set(key, field[key]);
+ }
+ return this;
+ }
+ this._header[field.toLowerCase()] = val;
+ this.header[field] = val;
+ return this;
+};
+
+/**
+ * Remove header `field`.
+ *
+ * Example:
+ *
+ * req.get('/')
+ * .unset('User-Agent')
+ * .end(callback);
+ *
+ * @param {String} field
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.unset = function(field){
+ delete this._header[field.toLowerCase()];
+ delete this.header[field];
+ return this;
+};
+
+/**
+ * Get case-insensitive header `field` value.
+ *
+ * @param {String} field
+ * @return {String}
+ * @api private
+ */
+
+Request.prototype.getHeader = function(field){
+ return this._header[field.toLowerCase()];
+};
+
+/**
+ * Set Content-Type to `type`, mapping values from `request.types`.
+ *
+ * Examples:
+ *
+ * superagent.types.xml = 'application/xml';
+ *
+ * request.post('/')
+ * .type('xml')
+ * .send(xmlstring)
+ * .end(callback);
+ *
+ * request.post('/')
+ * .type('application/xml')
+ * .send(xmlstring)
+ * .end(callback);
+ *
+ * @param {String} type
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.type = function(type){
+ this.set('Content-Type', request.types[type] || type);
+ return this;
+};
+
+/**
+ * Set Accept to `type`, mapping values from `request.types`.
+ *
+ * Examples:
+ *
+ * superagent.types.json = 'application/json';
+ *
+ * request.get('/agent')
+ * .accept('json')
+ * .end(callback);
+ *
+ * request.get('/agent')
+ * .accept('application/json')
+ * .end(callback);
+ *
+ * @param {String} accept
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.accept = function(type){
+ this.set('Accept', request.types[type] || type);
+ return this;
+};
+
+/**
+ * Set Authorization field value with `user` and `pass`.
+ *
+ * @param {String} user
+ * @param {String} pass
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.auth = function(user, pass){
+ var str = btoa(user + ':' + pass);
+ this.set('Authorization', 'Basic ' + str);
+ return this;
+};
+
+/**
+* Add query-string `val`.
+*
+* Examples:
+*
+* request.get('/shoes')
+* .query('size=10')
+* .query({ color: 'blue' })
+*
+* @param {Object|String} val
+* @return {Request} for chaining
+* @api public
+*/
+
+Request.prototype.query = function(val){
+ if ('string' != typeof val) val = serialize(val);
+ if (val) this._query.push(val);
+ return this;
+};
+
+/**
+ * Write the field `name` and `val` for "multipart/form-data"
+ * request bodies.
+ *
+ * ``` js
+ * request.post('/upload')
+ * .field('foo', 'bar')
+ * .end(callback);
+ * ```
+ *
+ * @param {String} name
+ * @param {String|Blob|File} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.field = function(name, val){
+ if (!this._formData) this._formData = new root.FormData();
+ this._formData.append(name, val);
+ return this;
+};
+
+/**
+ * Queue the given `file` as an attachment to the specified `field`,
+ * with optional `filename`.
+ *
+ * ``` js
+ * request.post('/upload')
+ * .attach(new Blob(['hey!'], { type: "text/html"}))
+ * .end(callback);
+ * ```
+ *
+ * @param {String} field
+ * @param {Blob|File} file
+ * @param {String} filename
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.attach = function(field, file, filename){
+ if (!this._formData) this._formData = new root.FormData();
+ this._formData.append(field, file, filename);
+ return this;
+};
+
+/**
+ * Send `data`, defaulting the `.type()` to "json" when
+ * an object is given.
+ *
+ * Examples:
+ *
+ * // querystring
+ * request.get('/search')
+ * .end(callback)
+ *
+ * // multiple data "writes"
+ * request.get('/search')
+ * .send({ search: 'query' })
+ * .send({ range: '1..5' })
+ * .send({ order: 'desc' })
+ * .end(callback)
+ *
+ * // manual json
+ * request.post('/user')
+ * .type('json')
+ * .send('{"name":"tj"})
+ * .end(callback)
+ *
+ * // auto json
+ * request.post('/user')
+ * .send({ name: 'tj' })
+ * .end(callback)
+ *
+ * // manual x-www-form-urlencoded
+ * request.post('/user')
+ * .type('form')
+ * .send('name=tj')
+ * .end(callback)
+ *
+ * // auto x-www-form-urlencoded
+ * request.post('/user')
+ * .type('form')
+ * .send({ name: 'tj' })
+ * .end(callback)
+ *
+ * // defaults to x-www-form-urlencoded
+ * request.post('/user')
+ * .send('name=tobi')
+ * .send('species=ferret')
+ * .end(callback)
+ *
+ * @param {String|Object} data
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.send = function(data){
+ var obj = isObject(data);
+ var type = this.getHeader('Content-Type');
+
+ // merge
+ if (obj && isObject(this._data)) {
+ for (var key in data) {
+ this._data[key] = data[key];
+ }
+ } else if ('string' == typeof data) {
+ if (!type) this.type('form');
+ type = this.getHeader('Content-Type');
+ if ('application/x-www-form-urlencoded' == type) {
+ this._data = this._data
+ ? this._data + '&' + data
+ : data;
+ } else {
+ this._data = (this._data || '') + data;
+ }
+ } else {
+ this._data = data;
+ }
+
+ if (!obj || isHost(data)) return this;
+ if (!type) this.type('json');
+ return this;
+};
+
+/**
+ * Invoke the callback with `err` and `res`
+ * and handle arity check.
+ *
+ * @param {Error} err
+ * @param {Response} res
+ * @api private
+ */
+
+Request.prototype.callback = function(err, res){
+ var fn = this._callback;
+ this.clearTimeout();
+ fn(err, res);
+};
+
+/**
+ * Invoke callback with x-domain error.
+ *
+ * @api private
+ */
+
+Request.prototype.crossDomainError = function(){
+ var err = new Error('Origin is not allowed by Access-Control-Allow-Origin');
+ err.crossDomain = true;
+ this.callback(err);
+};
+
+/**
+ * Invoke callback with timeout error.
+ *
+ * @api private
+ */
+
+Request.prototype.timeoutError = function(){
+ var timeout = this._timeout;
+ var err = new Error('timeout of ' + timeout + 'ms exceeded');
+ err.timeout = timeout;
+ this.callback(err);
+};
+
+/**
+ * Enable transmission of cookies with x-domain requests.
+ *
+ * Note that for this to work the origin must not be
+ * using "Access-Control-Allow-Origin" with a wildcard,
+ * and also must set "Access-Control-Allow-Credentials"
+ * to "true".
+ *
+ * @api public
+ */
+
+Request.prototype.withCredentials = function(){
+ this._withCredentials = true;
+ return this;
+};
+
+/**
+ * Initiate request, invoking callback `fn(res)`
+ * with an instanceof `Response`.
+ *
+ * @param {Function} fn
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.end = function(fn){
+ var self = this;
+ var xhr = this.xhr = request.getXHR();
+ var query = this._query.join('&');
+ var timeout = this._timeout;
+ var data = this._formData || this._data;
+
+ // store callback
+ this._callback = fn || noop;
+
+ // state change
+ xhr.onreadystatechange = function(){
+ if (4 != xhr.readyState) return;
+
+ // In IE9, reads to any property (e.g. status) off of an aborted XHR will
+ // result in the error "Could not complete the operation due to error c00c023f"
+ var status;
+ try { status = xhr.status } catch(e) { status = 0; }
+
+ if (0 == status) {
+ if (self.timedout) return self.timeoutError();
+ if (self.aborted) return;
+ return self.crossDomainError();
+ }
+ self.emit('end');
+ };
+
+ // progress
+ var handleProgress = function(e){
+ if (e.total > 0) {
+ e.percent = e.loaded / e.total * 100;
+ }
+ self.emit('progress', e);
+ };
+ if (this.hasListeners('progress')) {
+ xhr.onprogress = handleProgress;
+ }
+ try {
+ if (xhr.upload && this.hasListeners('progress')) {
+ xhr.upload.onprogress = handleProgress;
+ }
+ } catch(e) {
+ // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist.
+ // Reported here:
+ // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context
+ }
+
+ // timeout
+ if (timeout && !this._timer) {
+ this._timer = setTimeout(function(){
+ self.timedout = true;
+ self.abort();
+ }, timeout);
+ }
+
+ // querystring
+ if (query) {
+ query = request.serializeObject(query);
+ this.url += ~this.url.indexOf('?')
+ ? '&' + query
+ : '?' + query;
+ }
+
+ // initiate request
+ xhr.open(this.method, this.url, true);
+
+ // CORS
+ if (this._withCredentials) xhr.withCredentials = true;
+
+ // body
+ if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) {
+ // serialize stuff
+ var contentType = this.getHeader('Content-Type');
+ var serialize = request.serialize[contentType ? contentType.split(';')[0] : ''];
+ if (serialize) data = serialize(data);
+ }
+
+ // set header fields
+ for (var field in this.header) {
+ if (null == this.header[field]) continue;
+ xhr.setRequestHeader(field, this.header[field]);
+ }
+
+ // send stuff
+ this.emit('request', this);
+ xhr.send(data);
+ return this;
+};
+
+/**
+ * Faux promise support
+ *
+ * @param {Function} fulfill
+ * @param {Function} reject
+ * @return {Request}
+ */
+
+Request.prototype.then = function (fulfill, reject) {
+ return this.end(function(err, res) {
+ err ? reject(err) : fulfill(res);
+ });
+}
+
+/**
+ * Expose `Request`.
+ */
+
+request.Request = Request;
+
+/**
+ * Issue a request:
+ *
+ * Examples:
+ *
+ * request('GET', '/users').end(callback)
+ * request('/users').end(callback)
+ * request('/users', callback)
+ *
+ * @param {String} method
+ * @param {String|Function} url or callback
+ * @return {Request}
+ * @api public
+ */
+
+function request(method, url) {
+ // callback
+ if ('function' == typeof url) {
+ return new Request('GET', method).end(url);
+ }
+
+ // url first
+ if (1 == arguments.length) {
+ return new Request('GET', method);
+ }
+
+ return new Request(method, url);
+}
+
+/**
+ * GET `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.get = function(url, data, fn){
+ var req = request('GET', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.query(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * HEAD `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.head = function(url, data, fn){
+ var req = request('HEAD', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * DELETE `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.del = function(url, fn){
+ var req = request('DELETE', url);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * PATCH `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} data
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.patch = function(url, data, fn){
+ var req = request('PATCH', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * POST `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} data
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.post = function(url, data, fn){
+ var req = request('POST', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * PUT `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.put = function(url, data, fn){
+ var req = request('PUT', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * Expose `request`.
+ */
+
+module.exports = request;
+
+},{"emitter":16,"reduce":17}],16:[function(require,module,exports){
+
+/**
+ * Expose `Emitter`.
+ */
+
+module.exports = Emitter;
+
+/**
+ * Initialize a new `Emitter`.
+ *
+ * @api public
+ */
+
+function Emitter(obj) {
+ if (obj) return mixin(obj);
+};
+
+/**
+ * Mixin the emitter properties.
+ *
+ * @param {Object} obj
+ * @return {Object}
+ * @api private
+ */
+
+function mixin(obj) {
+ for (var key in Emitter.prototype) {
+ obj[key] = Emitter.prototype[key];
+ }
+ return obj;
+}
+
+/**
+ * Listen on the given `event` with `fn`.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.on =
+Emitter.prototype.addEventListener = function(event, fn){
+ this._callbacks = this._callbacks || {};
+ (this._callbacks[event] = this._callbacks[event] || [])
+ .push(fn);
+ return this;
+};
+
+/**
+ * Adds an `event` listener that will be invoked a single
+ * time then automatically removed.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.once = function(event, fn){
+ var self = this;
+ this._callbacks = this._callbacks || {};
+
+ function on() {
+ self.off(event, on);
+ fn.apply(this, arguments);
+ }
+
+ on.fn = fn;
+ this.on(event, on);
+ return this;
+};
+
+/**
+ * Remove the given callback for `event` or all
+ * registered callbacks.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.off =
+Emitter.prototype.removeListener =
+Emitter.prototype.removeAllListeners =
+Emitter.prototype.removeEventListener = function(event, fn){
+ this._callbacks = this._callbacks || {};
+
+ // all
+ if (0 == arguments.length) {
+ this._callbacks = {};
+ return this;
+ }
+
+ // specific event
+ var callbacks = this._callbacks[event];
+ if (!callbacks) return this;
+
+ // remove all handlers
+ if (1 == arguments.length) {
+ delete this._callbacks[event];
+ return this;
+ }
+
+ // remove specific handler
+ var cb;
+ for (var i = 0; i < callbacks.length; i++) {
+ cb = callbacks[i];
+ if (cb === fn || cb.fn === fn) {
+ callbacks.splice(i, 1);
+ break;
+ }
+ }
+ return this;
+};
+
+/**
+ * Emit `event` with the given args.
+ *
+ * @param {String} event
+ * @param {Mixed} ...
+ * @return {Emitter}
+ */
+
+Emitter.prototype.emit = function(event){
+ this._callbacks = this._callbacks || {};
+ var args = [].slice.call(arguments, 1)
+ , callbacks = this._callbacks[event];
+
+ if (callbacks) {
+ callbacks = callbacks.slice(0);
+ for (var i = 0, len = callbacks.length; i < len; ++i) {
+ callbacks[i].apply(this, args);
+ }
+ }
+
+ return this;
+};
+
+/**
+ * Return array of callbacks for `event`.
+ *
+ * @param {String} event
+ * @return {Array}
+ * @api public
+ */
+
+Emitter.prototype.listeners = function(event){
+ this._callbacks = this._callbacks || {};
+ return this._callbacks[event] || [];
+};
+
+/**
+ * Check if this emitter has `event` handlers.
+ *
+ * @param {String} event
+ * @return {Boolean}
+ * @api public
+ */
+
+Emitter.prototype.hasListeners = function(event){
+ return !! this.listeners(event).length;
+};
+
+},{}],17:[function(require,module,exports){
+
+/**
+ * Reduce `arr` with `fn`.
+ *
+ * @param {Array} arr
+ * @param {Function} fn
+ * @param {Mixed} initial
+ *
+ * TODO: combatible error handling?
+ */
+
+module.exports = function(arr, fn, initial){
+ var idx = 0;
+ var len = arr.length;
+ var curr = arguments.length == 3
+ ? initial
+ : arr[idx++];
+
+ while (idx < len) {
+ curr = fn.call(null, curr, arr[idx], ++idx, arr);
+ }
+
+ return curr;
+};
+},{}],18:[function(require,module,exports){
+
+/**
+ * Module dependencies.
+ */
+
+var global = (function() { return this; })();
+
+/**
+ * WebSocket constructor.
+ */
+
+var WebSocket = global.WebSocket || global.MozWebSocket;
+
+/**
+ * Module exports.
+ */
+
+module.exports = WebSocket ? ws : null;
+
+/**
+ * WebSocket constructor.
+ *
+ * The third `opts` options object gets ignored in web browsers, since it's
+ * non-standard, and throws a TypeError if passed to the constructor.
+ * See: https://github.com/einaros/ws/issues/227
+ *
+ * @param {String} uri
+ * @param {Array} protocols (optional)
+ * @param {Object) opts (optional)
+ * @api public
+ */
+
+function ws(uri, protocols, opts) {
+ var instance;
+ if (protocols) {
+ instance = new WebSocket(uri, protocols);
+ } else {
+ instance = new WebSocket(uri);
+ }
+ return instance;
+}
+
+if (WebSocket) ws.prototype = WebSocket.prototype;
+
+},{}],19:[function(require,module,exports){
+module.exports=[{"executables":{"win32":["pol.exe"]},"id":0,"name":"FINAL FANTASY XI"},{"executables":{"win32":["ffxiv.exe","ffxiv_dx11.exe"]},"id":1,"name":"FINAL FANTASY XIV"},{"executables":{"win32":["Wow.exe","Wow-64.exe"]},"id":3,"name":"World of Warcraft"},{"executables":{"darwin":["LoLLauncher.app"],"win32":["LolClient.exe","League of Legends.exe"]},"id":4,"name":"League of Legends"},{"executables":{"darwin":["Diablo%20III.app"],"win32":["Diablo III.exe"]},"id":5,"name":"Diablo 3"},{"executables":{"darwin":["dota_osx.app"],"win32":["dota2.exe"]},"id":6,"name":"DOTA 2"},{"executables":{"darwin":["Heroes.app"],"win32":["Heroes of the Storm.exe","HeroesOfTheStorm_x64.exe","HeroesOfTheStorm.exe"]},"id":7,"name":"Heroes of the Storm"},{"executables":{"darwin":["Hearthstone.app"],"win32":["Hearthstone.exe"]},"id":8,"name":"Hearthstone"},{"executables":{"win32":["csgo.exe"]},"id":9,"name":"Counter-Strike: Global Offensive"},{"executables":{"win32":["WorldOfTanks.exe"]},"id":10,"name":"World of Tanks"},{"executables":{"darwin":["gw2.app"],"win32":["gw2.exe"]},"id":11,"name":"Guild Wars 2"},{"executables":{"win32":["dayz.exe"]},"id":12,"name":"Day Z"},{"executables":{"darwin":["starcraft%20ii.app"],"win32":["starcraft ii.exe","SC2_x64.exe","SC2.exe"]},"id":13,"name":"Starcraft II"},{"executables":{"win32":["diablo.exe"]},"id":14,"name":"Diablo"},{"executables":{"win32":["diablo ii.exe"]},"id":15,"name":"Diablo 2"},{"executables":{"win32":["left4dead.exe"]},"id":17,"name":"Left 4 Dead"},{"executables":{"darwin":["minecraft.app"],"win32":["minecraft.exe"]},"id":18,"name":"Minecraft"},{"executables":{"win32":["smite.exe"]},"id":19,"name":"Smite"},{"executables":{"win32":["bf4.exe"]},"id":20,"name":"Battlefield 4"},{"executables":{"win32":["AoK HD.exe","empires2.exe"]},"id":101,"name":"Age of Empire II"},{"executables":{"win32":["age3y.exe"]},"id":102,"name":"Age of Empire III"},{"executables":{"win32":["AlanWake.exe"]},"id":104,"name":"Alan Wake"},{"executables":{"win32":["alan_wakes_american_nightmare.exe"]},"id":105,"name":"Alan Wake's American Nightmare"},{"executables":{"win32":["AlienBreed2Assault.exe"]},"id":106,"name":"Alien Breed 2: Assault"},{"executables":{"win32":["Amnesia.exe"]},"id":107,"name":"Amnesia: The Dark Descent"},{"executables":{"win32":["UDK.exe"]},"id":108,"name":"Antichamber"},{"executables":{"win32":["ArcheAge.exe"]},"id":109,"name":"ArcheAge"},{"executables":{"win32":["arma3.exe"]},"id":110,"name":"Arma III"},{"executables":{"win32":["AC3SP.exe"]},"id":111,"name":"Assassin's Creed 3"},{"executables":{"win32":["Bastion.exe"]},"id":112,"name":"Bastion"},{"executables":{"win32":["BF2.exe"]},"id":113,"name":"Battlefield 2"},{"executables":{"win32":["bf3.exe"]},"id":114,"name":"Battlefield 3"},{"executables":{"win32":["Besiege.exe"]},"id":116,"name":"Besiege"},{"executables":{"win32":["Bioshock.exe"]},"id":117,"name":"Bioshock"},{"executables":{"win32":["Bioshock2.exe"]},"id":118,"name":"BioShock II"},{"executables":{"win32":["BioShockInfinite.exe"]},"id":119,"name":"BioShock Infinite"},{"executables":{"win32":["Borderlands2.exe"]},"id":122,"name":"Borderlands 2"},{"executables":{"win32":["braid.exe"]},"id":123,"name":"Braid"},{"executables":{"win32":["ShippingPC-StormGame.exe"]},"id":124,"name":"Bulletstorm"},{"executables":{},"id":125,"name":"Cabal 2"},{"executables":{"win32":["CabalMain.exe"]},"id":126,"name":"Cabal Online"},{"executables":{"win32":["iw4mp.exe","iw4sp.exe"]},"id":127,"name":"Call of Duty: Modern Warfare 2"},{"executables":{"win32":["t6sp.exe"]},"id":128,"name":"Call of Duty: Black Ops"},{"executables":{"win32":["iw5mp.exe"]},"id":129,"name":"Call of Duty: Modern Warfare 3"},{"executables":{"win32":["RelicCOH.exe"]},"id":132,"name":"Company of Heroes"},{"executables":{"win32":["Crysis64.exe"]},"id":135,"name":"Crysis"},{"executables":{"win32":["Crysis2.exe"]},"id":136,"name":"Crysis 2"},{"executables":{"win32":["Crysis3.exe"]},"id":137,"name":"Crysis 3"},{"executables":{"win32":["Crysis.exe"]},"id":138,"name":"Crysis 4 "},{"executables":{"win32":["DATA.exe"]},"id":140,"name":"Dark Souls"},{"executables":{"win32":["DarkSoulsII.exe"]},"id":141,"name":"Dark Souls II"},{"executables":{"win32":["dfuw.exe"]},"id":142,"name":"Darkfall: Unholy Wars"},{"executables":{"win32":["DCGAME.exe"]},"id":144,"name":"DC Universe Online"},{"executables":{"win32":["DeadIslandGame.exe"]},"id":145,"name":"Dead Island"},{"executables":{"win32":["deadspace2.exe"]},"id":146,"name":"Dead Space 2"},{"executables":{"win32":["LOTDGame.exe"]},"id":147,"name":"Deadlight"},{"executables":{"win32":["dxhr.exe"]},"id":148,"name":"Deus Ex: Human Revolution"},{"executables":{"win32":["DeviMayCry4.exe"]},"id":149,"name":"Devil May Cry 4"},{"executables":{"win32":["DMC-DevilMayCry.exe"]},"id":150,"name":"DmC Devil May Cry"},{"executables":{"win32":["dirt2_game.exe"]},"id":154,"name":"DiRT 2"},{"executables":{"win32":["dirt3_game.exe"]},"id":155,"name":"DiRT 3"},{"executables":{"win32":["dota.exe"]},"id":156,"name":"DOTA"},{"executables":{"win32":["DoubleDragon.exe"]},"id":158,"name":"Double Dragon Neon"},{"executables":{"win32":["DragonAge2.exe"]},"id":159,"name":"Dragon Age II"},{"executables":{"win32":["DragonAgeInquisition.exe"]},"id":160,"name":"Dragon Age: Inquisition"},{"executables":{"win32":["daorigins.exe"]},"id":161,"name":"Dragon Age: Origins"},{"executables":{"win32":["DBXV.exe"]},"id":162,"name":"Dragon Ball XenoVerse"},{"executables":{"win32":["DukeForever.exe"]},"id":163,"name":"Duke Nukem Forever"},{"executables":{"darwin":["Dustforce.app"],"win32":["dustforce.exe"]},"id":164,"name":"Dustforce"},{"executables":{"win32":["EliteDangerous32.exe"]},"id":165,"name":"Elite: Dangerous"},{"executables":{"win32":["exefile.exe"]},"id":166,"name":"Eve Online"},{"executables":{"win32":["eqgame.exe"]},"id":167,"name":"EverQuest"},{"executables":{"win32":["EverQuest2.exe"]},"id":168,"name":"EverQuest II"},{"executables":{},"id":169,"name":"EverQuest Next"},{"executables":{"win32":["Engine.exe"]},"id":170,"name":"F.E.A.R."},{"executables":{"win32":["FEAR2.exe"]},"id":171,"name":"F.E.A.R. 2: Project Origin"},{"executables":{"win32":["fallout3.exe"]},"id":172,"name":"Fallout 3"},{"executables":{"win32":["FalloutNV.exe"]},"id":174,"name":"Fallout: New Vegas"},{"executables":{"win32":["farcry3.exe"]},"id":175,"name":"Far Cry 3"},{"executables":{"win32":["fifa15.exe"]},"id":176,"name":"FIFA 15"},{"executables":{"win32":["FTLGame.exe"]},"id":180,"name":"FTL: Faster Than Light"},{"executables":{"win32":["GTAIV.exe"]},"id":181,"name":"Grand Theft Auto 4"},{"executables":{"win32":["GTA5.exe"]},"id":182,"name":"Grand Theft Auto 5"},{"executables":{"win32":["Gw.exe"]},"id":183,"name":"Guild Wars"},{"executables":{"win32":["H1Z1.exe"]},"id":186,"name":"H1Z1"},{"executables":{"win32":["HL2HL2.exe","hl2.exe"]},"id":188,"name":"Half Life 2"},{"executables":{"win32":["HOMEFRONT.exe"]},"id":195,"name":"Homefront"},{"executables":{"win32":["invisibleinc.exe"]},"id":196,"name":"Invisible Inc."},{"executables":{"win32":["LANoire.exe"]},"id":197,"name":"L.A. Noire"},{"executables":{"win32":["Landmark64.exe"]},"id":198,"name":"Landmark"},{"executables":{"win32":["left4dead2.exe"]},"id":201,"name":"Left 4 Dead 2"},{"executables":{"win32":["lineage.exe"]},"id":203,"name":"Lineage"},{"executables":{"win32":["Magicka.exe"]},"id":206,"name":"Magicka"},{"executables":{"win32":["MapleStory.exe"]},"id":208,"name":"MapleStory"},{"executables":{},"id":209,"name":"Mark of the Ninja"},{"executables":{"win32":["MassEffect.exe"]},"id":210,"name":"Mass Effect"},{"executables":{"win32":["MassEffect2.exe"]},"id":211,"name":"Mass Effect 2"},{"executables":{"win32":["MassEffect3Demo.exe"]},"id":212,"name":"Mass Effect 3"},{"executables":{"win32":["METAL GEAR RISING REVENGEANCE.exe"]},"id":214,"name":"Metal Gear Rising: Revengeance"},{"executables":{"win32":["metro2033.exe"]},"id":215,"name":"Metro 2033"},{"executables":{"win32":["MetroLL.exe"]},"id":216,"name":"Metro Last Light"},{"executables":{"win32":["MK10.exe"]},"id":218,"name":"Mortal Kombat X"},{"executables":{"win32":["speed.exe"]},"id":219,"name":"Need For Speed Most Wanted"},{"executables":{},"id":220,"name":"Neverwinder"},{"executables":{"darwin":["Outlast.app"],"win32":["OLGame.exe"]},"id":221,"name":"Outlast"},{"executables":{"win32":["PapersPlease.exe"]},"id":222,"name":"Papers, Please"},{"executables":{"win32":["payday_win32_release.exe"]},"id":223,"name":"PAYDAY"},{"executables":{"win32":["payday2_win32_release.exe"]},"id":224,"name":"PAYDAY2"},{"executables":{"win32":["PillarsOfEternity.exe"]},"id":225,"name":"Pillars of Eternity"},{"executables":{"win32":["PA.exe"]},"id":226,"name":"Planetary Annihilation"},{"executables":{"win32":["planetside2_x86.exe"]},"id":227,"name":"Planetside 2"},{"executables":{"win32":["hl2P.exe"]},"id":228,"name":"Portal"},{"executables":{"win32":["portal2.exe"]},"id":229,"name":"Portal 2"},{"executables":{"win32":["PrimalCarnageGame.exe"]},"id":231,"name":"Primal Cargnage"},{"executables":{"win32":["pCARS.exe"]},"id":232,"name":"Project Cars"},{"executables":{"win32":["RaceTheSun.exe"]},"id":233,"name":"Race The Sun"},{"executables":{"win32":["Rage.exe"]},"id":234,"name":"RAGE"},{"executables":{"win32":["ragexe.exe"]},"id":235,"name":"Ragnarok Online"},{"executables":{"win32":["rift.exe"]},"id":236,"name":"Rift"},{"executables":{"win32":["Rocksmith2014.exe"]},"id":237,"name":"Rocksmith 2014"},{"executables":{"win32":["SwiftKit-RS.exe","JagexLauncher.exe"]},"id":238,"name":"RuneScape"},{"executables":{"win32":["Shadowgrounds.exe"]},"id":239,"name":"Shadowgrounds"},{"executables":{"win32":["survivor.exe"]},"id":240,"name":"Shadowgrounds: Survivor"},{"executables":{"win32":["ShovelKnight.exe"]},"id":241,"name":"Shovel Knight"},{"executables":{"win32":["SimCity.exe"]},"id":242,"name":"SimCity"},{"executables":{"win32":["SporeApp.exe"]},"id":245,"name":"Spore"},{"executables":{"win32":["StarCitizen.exe"]},"id":246,"name":"Star Citizen"},{"executables":{},"id":247,"name":"Star Trek Online"},{"executables":{"win32":["battlefront.exe"]},"id":248,"name":"Star Wars Battlefront"},{"executables":{"win32":["swtor.exe"]},"id":249,"name":"Star Wars: The Old Republic"},{"executables":{"win32":["starbound.exe","starbound_opengl.exe"]},"id":250,"name":"Starbound"},{"executables":{"win32":["starcraft.exe"]},"id":251,"name":"Starcraft"},{"executables":{"win32":["SSFIV.exe"]},"id":253,"name":"Ultra Street Fighter IV"},{"executables":{"win32":["superhexagon.exe"]},"id":254,"name":"Super Hexagon"},{"executables":{"win32":["swordandsworcery_pc.exe"]},"id":255,"name":"Superbrothers: Sword & Sworcery EP"},{"executables":{"win32":["hl2TF.exe"]},"id":256,"name":"Team Fortress 2"},{"executables":{"win32":["TERA.exe"]},"id":258,"name":"TERA"},{"executables":{"win32":["Terraria.exe"]},"id":259,"name":"Terraria"},{"executables":{"win32":["Bethesda.net_Launcher.exe"]},"id":260,"name":"The Elder Scrolls Online"},{"executables":{"win32":["TESV.exe"]},"id":261,"name":"The Elder Scrolls V: Skyrim"},{"executables":{"win32":["TheSecretWorld.exe"]},"id":262,"name":"The Secret World"},{"executables":{"win32":["TS3.exe","ts3w.exe"]},"id":264,"name":"The Sims 3"},{"executables":{"win32":["WALKINGDEAD101.EXE"]},"id":265,"name":"The Walking Dead"},{"executables":{"win32":["TheWalkingDead2.exe"]},"id":266,"name":"The Walking Dead Season Two"},{"executables":{"win32":["witcher3.exe"]},"id":267,"name":"The Witcher 3"},{"executables":{"win32":["Future Soldier.exe"]},"id":268,"name":"Tom Clancy's Ghost Recon: Future Solider"},{"executables":{"win32":["TombRaider.exe"]},"id":269,"name":"Tomb Raider (2013)"},{"executables":{"win32":["Torchlight.exe"]},"id":271,"name":"Torchlight"},{"executables":{"win32":["Torchlight2.exe"]},"id":272,"name":"Torchlight 2"},{"executables":{"win32":["Shogun2.exe"]},"id":273,"name":"Total War: Shogun 2"},{"executables":{"win32":["Transistor.exe"]},"id":274,"name":"Transistor"},{"executables":{"win32":["trine.exe"]},"id":275,"name":"Trine"},{"executables":{"win32":["trine2_32bit.exe"]},"id":276,"name":"Trine 2"},{"executables":{"win32":["UOKR.exe"]},"id":277,"name":"Ultima Online"},{"executables":{"win32":["aces.exe"]},"id":279,"name":"War Thunder"},{"executables":{"win32":["Warcraft III.exe","wc3.exe"]},"id":281,"name":"Warcraft 3: Reign of Chaos"},{"executables":{"win32":["Warcraft II BNE.exe"]},"id":282,"name":"Warcraft II"},{"executables":{"win32":["Warframe.x64.exe","Warframe.exe"]},"id":283,"name":"Warframe"},{"executables":{"win32":["watch_dogs.exe"]},"id":284,"name":"Watch Dogs"},{"executables":{"win32":["WildStar64.exe"]},"id":285,"name":"WildStar"},{"executables":{"win32":["XComGame.exe"]},"id":288,"name":"XCOM: Enemy Unknown"},{"executables":{"win32":["DFO.exe","dfo.exe"]},"id":289,"name":"Dungeon Fighter Online"},{"executables":{"win32":["aclauncher.exe","acclient.exe"]},"id":290,"name":"Asheron's Call"},{"executables":{"win32":["MapleStory2.exe"]},"id":291,"name":"MapleStory 2"},{"executables":{"win32":["ksp.exe"]},"id":292,"name":"Kerbal Space Program"},{"executables":{"win32":["PINBALL.EXE"]},"id":293,"name":"3D Pinball: Space Cadet"},{"executables":{"win32":["dave.exe"]},"id":294,"name":"Dangerous Dave"},{"executables":{"win32":["iwbtgbeta(slomo).exe","iwbtgbeta(fs).exe"]},"id":295,"name":"I Wanna Be The Guy"},{"executables":{"win32":["MechWarriorOnline.exe "]},"id":296,"name":"Mech Warrior Online"},{"executables":{"win32":["dontstarve_steam.exe"]},"id":297,"name":"Don't Starve"},{"executables":{"win32":["GalCiv3.exe"]},"id":298,"name":"Galactic Civilization 3"},{"executables":{"win32":["Risk of Rain.exe"]},"id":299,"name":"Risk of Rain"},{"executables":{"win32":["Binding_of_Isaac.exe","Isaac-ng.exe"]},"id":300,"name":"The Binding of Isaac"},{"executables":{"win32":["RustClient.exe"]},"id":301,"name":"Rust"},{"executables":{"win32":["Clicker Heroes.exe"]},"id":302,"name":"Clicker Heroes"},{"executables":{"win32":["Brawlhalla.exe"]},"id":303,"name":"Brawlhalla"},{"executables":{"win32":["TownOfSalem.exe"]},"id":304,"name":"Town of Salem"},{"executables":{"win32":["osu!.exe"]},"id":305,"name":"osu!"},{"executables":{"win32":["PathOfExileSteam.exe","PathOfExile.exe"]},"id":306,"name":"Path of Exile"},{"executables":{"win32":["Dolphin.exe"]},"id":307,"name":"Dolphin"},{"executables":{"win32":["RocketLeague.exe"]},"id":308,"name":"Rocket League"},{"executables":{"win32":["TJPP.exe"]},"id":309,"name":"Jackbox Party Pack"},{"executables":{"win32":["KFGame.exe"]},"id":310,"name":"Killing Floor 2"},{"executables":{"win32":["ShooterGame.exe"]},"id":311,"name":"Ark: Survival Evolved"},{"executables":{"win32":["LifeIsStrange.exe"]},"id":312,"name":"Life Is Strange"},{"executables":{"win32":["Client_tos.exe"]},"id":313,"name":"Tree of Savior"},{"executables":{"win32":["olliolli2.exe"]},"id":314,"name":"OlliOlli2"},{"executables":{"win32":["cw.exe"]},"id":315,"name":"Closers Dimension Conflict"},{"executables":{"win32":["ESSTEAM.exe","elsword.exe","x2.exe"]},"id":316,"name":"Elsword"},{"executables":{"win32":["ori.exe"]},"id":317,"name":"Ori and the Blind Forest"},{"executables":{"win32":["Skyforge.exe"]},"id":318,"name":"Skyforge"},{"executables":{"win32":["projectzomboid64.exe","projectzomboid32.exe"]},"id":319,"name":"Project Zomboid"},{"executables":{"win32":["From_The_Depths.exe"]},"id":320,"name":"The Depths"},{"executables":{"win32":["TheCrew.exe"]},"id":321,"name":"The Crew"},{"executables":{"win32":["MarvelHeroes2015.exe"]},"id":322,"name":"Marvel Heroes 2015"},{"executables":{"win32":["timeclickers.exe"]},"id":324,"name":"Time Clickers"},{"executables":{"win32":["eurotrucks2.exe"]},"id":325,"name":"Euro Truck Simulator 2"},{"executables":{"win32":["FarmingSimulator2015Game.exe"]},"id":326,"name":"Farming Simulator 15"},{"executables":{"win32":["strife.exe"]},"id":327,"name":"Strife"},{"executables":{"win32":["Awesomenauts.exe"]},"id":328,"name":"Awesomenauts"},{"executables":{"win32":["Dofus.exe"]},"id":329,"name":"Dofus"},{"executables":{"win32":["Boid.exe"]},"id":330,"name":"Boid"},{"executables":{"win32":["adventure-capitalist.exe"]},"id":331,"name":"AdVenture Capitalist"},{"executables":{"win32":["OrcsMustDie2.exe"]},"id":332,"name":"Orcs Must Die! 2"},{"executables":{"win32":["Mountain.exe"]},"id":333,"name":"Mountain"},{"executables":{"win32":["Valkyria.exe"]},"id":335,"name":"Valkyria Chronicles"},{"executables":{"win32":["ffxiiiimg.exe"]},"id":336,"name":"Final Fantasy XIII"},{"executables":{"win32":["TLR.exe"]},"id":337,"name":"The Last Remnant"},{"executables":{"win32":["Cities.exe"]},"id":339,"name":"Cities Skylines"},{"executables":{"win32":["worldofwarships.exe","WoWSLauncher.exe"]},"id":341,"name":"World of Warships"},{"executables":{"win32":["spacegame-Win64-shipping.exe"]},"id":342,"name":"Fractured Space"},{"executables":{"win32":["thespacegame.exe"]},"id":343,"name":"Ascent - The Space Game"},{"executables":{"win32":["DuckGame.exe"]},"id":344,"name":"Duck Game"},{"executables":{"win32":["PPSSPPWindows.exe"]},"id":345,"name":"PPSSPP"},{"executables":{"win32":["MBAA.exe"]},"id":346,"name":"Melty Blood Actress Again: Current Code"},{"executables":{"win32":["TheWolfAmongUs.exe"]},"id":347,"name":"The Wolf Among Us"},{"executables":{"win32":["SpaceEngineers.exe"]},"id":348,"name":"Space Engineers"},{"executables":{"win32":["Borderlands.exe"]},"id":349,"name":"Borderlands"},{"executables":{"win32":["100orange.exe"]},"id":351,"name":"100% Orange Juice"},{"executables":{"win32":["reflex.exe"]},"id":354,"name":"Reflex"},{"executables":{"win32":["pso2.exe"]},"id":355,"name":"Phantasy Star Online 2"},{"executables":{"win32":["AssettoCorsa.exe"]},"id":356,"name":"Assetto Corsa"},{"executables":{"win32":["iw3mp.exe","iw3sp.exe"]},"id":357,"name":"Call of Duty 4: Modern Warfare"},{"executables":{"win32":["WolfOldBlood_x64.exe"]},"id":358,"name":"Wolfenstein: The Old Blood"},{"executables":{"win32":["castle.exe"]},"id":359,"name":"Castle Crashers"},{"executables":{"win32":["vindictus.exe"]},"id":360,"name":"Vindictus"},{"executables":{"win32":["ShooterGame-Win32-Shipping.exe"]},"id":361,"name":"Dirty Bomb"},{"executables":{"win32":["BatmanAK.exe"]},"id":362,"name":"Batman Arkham Knight"},{"executables":{"win32":["drt.exe"]},"id":363,"name":"Dirt Rally"},{"executables":{"win32":["rFactor.exe"]},"id":364,"name":"rFactor"},{"executables":{"win32":["clonk.exe"]},"id":365,"name":"Clonk Rage"},{"executables":{"win32":["SRHK.exe"]},"id":366,"name":"Shadowrun: Hong Kong"},{"executables":{"win32":["Insurgency.exe"]},"id":367,"name":"Insurgency"},{"executables":{"win32":["StepMania.exe"]},"id":368,"name":"Step Mania"},{"executables":{"win32":["FirefallCLient.exe"]},"id":369,"name":"Firefall"},{"executables":{"win32":["mirrorsedge.exe"]},"id":370,"name":"Mirrors Edge"},{"executables":{"win32":["MgsGroundZeroes.exe"]},"id":371,"name":"Metal Gear Solid V: Ground Zeroes"},{"executables":{"win32":["mgsvtpp.exe"]},"id":372,"name":"Metal Gear Solid V: The Phantom Pain"},{"executables":{"win32":["tld.exe"]},"id":373,"name":"The Long Dark"},{"executables":{"win32":["TKOM.exe"]},"id":374,"name":"Take On Mars"},{"executables":{"win32":["robloxplayerlauncher.exe","Roblox.exe"]},"id":375,"name":"Roblox"},{"executables":{"win32":["eu4.exe"]},"id":376,"name":"Europa Universalis 4"},{"executables":{"win32":["APB.exe"]},"id":377,"name":"APB Reloaded"},{"executables":{"win32":["Robocraft.exe"]},"id":378,"name":"Robocraft"},{"executables":{"win32":["Unity.exe"]},"id":379,"name":"Unity"},{"executables":{"win32":["Simpsons.exe"]},"id":380,"name":"The Simpsons: Hit & Run"},{"executables":{"win32":["Dnlauncher.exe","DragonNest.exe"]},"id":381,"name":"Dragon Nest"},{"executables":{"win32":["Trove.exe"]},"id":382,"name":"Trove"},{"executables":{"win32":["EndlessLegend.exe"]},"id":383,"name":"Endless Legend"},{"executables":{"win32":["TurbineLauncher.exe","dndclient.exe"]},"id":384,"name":"Dungeons & Dragons Online"},{"executables":{"win32":["quakelive.exe","quakelive_steam.exe"]},"id":385,"name":"Quake Live"},{"executables":{"win32":["7DaysToDie.exe"]},"id":386,"name":"7DaysToDie"},{"executables":{"win32":["SpeedRunners.exe"]},"id":387,"name":"SpeedRunners"},{"executables":{"win32":["gamemd.exe"]},"id":388,"name":"Command & Conquer: Red Alert 2"},{"executables":{"win32":["generals.exe"]},"id":389,"name":"Command & Conquer Generals: Zero Hour"},{"executables":{"win32":["Oblivion.exe"]},"id":390,"name":"The Elder Scrolls 4: Oblivion"},{"executables":{"win32":["mgsi.exe"]},"id":391,"name":"Metal Gear Solid"},{"executables":{"win32":["EoCApp.exe"]},"id":392,"name":"Divinity - Original Sin"},{"executables":{"win32":["Torment.exe"]},"id":393,"name":"Planescape: Torment"},{"executables":{"win32":["HexPatch.exe"]},"id":394,"name":"Hex: Shards of Fate"},{"executables":{"win32":["NS3FB.exe"]},"id":395,"name":"Naruto Shippuden Ultimate Ninja Storm 3 Full Burst"},{"executables":{"win32":["NSUNSR.exe"]},"id":396,"name":"Naruto Shippuden Ultimate Ninja Storm Revolution"},{"executables":{"win32":["SaintsRowIV.exe"]},"id":397,"name":"Saints Row IV"},{"executables":{"win32":["Shadowrun.exe"]},"id":398,"name":"Shadowrun"},{"executables":{"win32":["DungeonoftheEndless.exe"]},"id":399,"name":"Dungeon of the Endless"},{"executables":{"win32":["Hon.exe"]},"id":400,"name":"Heroes of Newerth"},{"executables":{"win32":["mabinogi.exe"]},"id":401,"name":"Mabinogi"},{"executables":{"win32":["CoD2MP_s.exe","CoDSP_s.exe"]},"id":402,"name":"Call of Duty 2:"},{"executables":{"win32":["CoDWaWmp.exe","CoDWaw.exe"]},"id":403,"name":"Call of Duty: World at War"},{"executables":{"win32":["heroes.exe"]},"id":404,"name":"Mabinogi Heroes (Vindictus) "},{"executables":{"win32":["KanColleViewer.exe"]},"id":405,"name":"KanColle "},{"executables":{"win32":["cyphers.exe"]},"id":406,"name":"Cyphers"},{"executables":{"win32":["RelicCoH2.exe"]},"id":407,"name":"Company of Heroes 2"},{"executables":{"win32":["MJ.exe"]},"id":408,"name":"セガNET麻雀MJ"},{"executables":{"win32":["ge.exe"]},"id":409,"name":"Granado Espada"},{"executables":{"win32":["NovaRO.exe"]},"id":410,"name":"Nova Ragnarok Online"},{"executables":{"win32":["RivalsofAether.exe"]},"id":411,"name":"Rivals of Aether"},{"executables":{"win32":["bfh.exe"]},"id":412,"name":"Battlefield Hardline"},{"executables":{"win32":["GrowHome.exe"]},"id":413,"name":"Grow Home"},{"executables":{"win32":["patriots.exe"]},"id":414,"name":"Rise of Nations Extended"},{"executables":{"win32":["Railroads.exe"]},"id":415,"name":"Sid Meier's Railroads!"},{"executables":{"win32":["Empire.exe"]},"id":416,"name":"Empire: Total War"},{"executables":{"win32":["Napoleon.exe"]},"id":417,"name":"Napoleon: Total War"},{"executables":{"win32":["gta_sa.exe"]},"id":418,"name":"Grand Theft Auto: San Andreas"},{"executables":{"win32":["MadMax.exe"]},"id":419,"name":"Mad Max"},{"executables":{"win32":["Titanfall.exe"]},"id":420,"name":"Titanfall"},{"executables":{"win32":["age2_x1.exe"]},"id":421,"name":"Age of Empires II: The Conquerors"},{"executables":{"win32":["Rome2.exe"]},"id":422,"name":"Total War: ROME 2"},{"executables":{"win32":["ShadowOfMordor.exe"]},"id":423,"name":"Middle-earth: Shadow of Mordor"},{"executables":{"win32":["Subnautica.exe"]},"id":424,"name":"Subnautica"},{"executables":{"win32":["anno5.exe"]},"id":425,"name":"Anno 2070"},{"executables":{"win32":["carrier.exe"]},"id":426,"name":"Carrier Command Gaea Mission"},{"executables":{"win32":["DarksidersPC.exe"]},"id":427,"name":"Darksiders"},{"executables":{"win32":["Darksiders2.exe"]},"id":428,"name":"Darksiders 2"},{"executables":{"win32":["mudlet.exe"]},"id":429,"name":"Mudlet"},{"executables":{"win32":["DunDefLauncher.exe"]},"id":430,"name":"Dungeon Defenders II"},{"executables":{"win32":["hng.exe"]},"id":431,"name":"Heroes and Generals"},{"executables":{"win32":["WFTOGame.exe"]},"id":432,"name":"War of the Overworld"},{"executables":{"win32":["Talisman.exe"]},"id":433,"name":"Talisman: Digital Edition"},{"executables":{"win32":["limbo.exe"]},"id":434,"name":"Limbo"},{"executables":{"win32":["ibbobb.exe"]},"id":435,"name":"ibb & obb"},{"executables":{"win32":["BattleBlockTheater.exe"]},"id":436,"name":"BattleBlock Theater"},{"executables":{"win32":["iracinglauncher.exe","iracingsim.exe","iracingsim64.exe"]},"id":437,"name":"iRacing"},{"executables":{"win32":["CivilizationV_DX11.exe"]},"id":438,"name":"Civilization V"}]
+},{}]},{},[9])(9)
+});
\ No newline at end of file
diff --git a/web-dist/discord.3.9.0.js b/web-dist/discord.3.9.0.js
new file mode 100644
index 000000000..3122c5739
--- /dev/null
+++ b/web-dist/discord.3.9.0.js
@@ -0,0 +1,1534 @@
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Discord = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o>> x & 1) === 1;}this.type = data.type; //either member or role
+this.id = data.id;if(this.type === "member"){this.packed = channel.server.getMember("id",data.id).evalPerms.packed;}else {this.packed = channel.server.getRole(data.id).packed;}this.packed = this.packed & ~data.deny;this.packed = this.packed | data.allow;this.deny = data.deny;this.allow = data.allow;}ChannelPermissions.prototype.getBit = function getBit(x){return (this.packed >>> x & 1) === 1;};ChannelPermissions.prototype.setBit = function setBit(){};_createClass(ChannelPermissions,[{key:"createInstantInvite",get:function get(){return this.getBit(0);},set:function set(val){this.setBit(0,val);}},{key:"manageRoles",get:function get(){return this.getBit(3);},set:function set(val){this.setBit(3,val);}},{key:"manageChannels",get:function get(){return this.getBit(4);},set:function set(val){this.setBit(4,val);}},{key:"readMessages",get:function get(){return this.getBit(10);},set:function set(val){this.setBit(10,val);}},{key:"sendMessages",get:function get(){return this.getBit(11);},set:function set(val){this.setBit(11,val);}},{key:"sendTTSMessages",get:function get(){return this.getBit(12);},set:function set(val){this.setBit(12,val);}},{key:"manageMessages",get:function get(){return this.getBit(13);},set:function set(val){this.setBit(13,val);}},{key:"embedLinks",get:function get(){return this.getBit(14);},set:function set(val){this.setBit(14,val);}},{key:"attachFiles",get:function get(){return this.getBit(15);},set:function set(val){this.setBit(15,val);}},{key:"readMessageHistory",get:function get(){return this.getBit(16);},set:function set(val){this.setBit(16,val);}},{key:"mentionEveryone",get:function get(){return this.getBit(17);},set:function set(val){this.setBit(17,val);}},{key:"voiceConnect",get:function get(){return this.getBit(20);},set:function set(val){this.setBit(20,val);}},{key:"voiceSpeak",get:function get(){return this.getBit(21);},set:function set(val){this.setBit(21,val);}},{key:"voiceMuteMembers",get:function get(){return this.getBit(22);},set:function set(val){this.setBit(22,val);}},{key:"voiceDeafenMembers",get:function get(){return this.getBit(23);},set:function set(val){this.setBit(23,val);}},{key:"voiceMoveMembers",get:function get(){return this.getBit(24);},set:function set(val){this.setBit(24,val);}},{key:"voiceUseVoiceActivation",get:function get(){return this.getBit(25);},set:function set(val){this.setBit(25,val);}}]);return ChannelPermissions;})();module.exports = ChannelPermissions;
+
+},{}],2:[function(require,module,exports){
+//discord.js modules
+"use strict";var _createClass=(function(){function defineProperties(target,props){for(var i=0;i < props.length;i++) {var descriptor=props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if("value" in descriptor)descriptor.writable = true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};})();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}var Endpoints=require("./Endpoints.js");var User=require("./user.js");var Server=require("./server.js");var Channel=require("./channel.js");var Message=require("./message.js");var Invite=require("./invite.js");var PMChannel=require("./PMChannel.js");var gameMap=require("../ref/gameMap.json"); //node modules
+var request=require("superagent");var WebSocket=require("ws");var fs=require("fs");var defaultOptions={queue:false};var Client=(function(){function Client(){var options=arguments.length <= 0 || arguments[0] === undefined?defaultOptions:arguments[0];var token=arguments.length <= 1 || arguments[1] === undefined?undefined:arguments[1];_classCallCheck(this,Client); /*
+ When created, if a token is specified the Client will
+ try connecting with it. If the token is incorrect, no
+ further efforts will be made to connect.
+ */this.options = options;this.options.queue = this.options.queue;this.token = token;this.state = 0;this.websocket = null;this.events = {};this.user = null;this.alreadySentData = false;this.serverCreateListener = {};this.typingIntervals = {};this.email = "abc";this.password = "abc"; /*
+ State values:
+ 0 - idle
+ 1 - logging in
+ 2 - logged in
+ 3 - ready
+ 4 - disconnected
+ */this.userCache = [];this.channelCache = [];this.serverCache = [];this.pmChannelCache = [];this.readyTime = null;this.checkingQueue = {};this.userTypingListener = {};this.queue = {};this.__idleTime = null;this.__gameId = null;}Client.prototype.sendPacket = function sendPacket(JSONObject){if(this.websocket.readyState === 1){this.websocket.send(JSON.stringify(JSONObject));}}; //def debug
+Client.prototype.debug = function debug(message){this.trigger("debug",message);};Client.prototype.on = function on(event,fn){this.events[event] = fn;};Client.prototype.off = function off(event){this.events[event] = null;};Client.prototype.keepAlive = function keepAlive(){this.debug("keep alive triggered");this.sendPacket({op:1,d:Date.now()});}; //def trigger
+Client.prototype.trigger = function trigger(event){var args=[];for(var arg in arguments) {args.push(arguments[arg]);}var evt=this.events[event];if(evt){evt.apply(this,args.slice(1));}}; //def login
+Client.prototype.login = function login(){var email=arguments.length <= 0 || arguments[0] === undefined?"foo@bar.com":arguments[0];var password=arguments.length <= 1 || arguments[1] === undefined?"pass1234":arguments[1];var callback=arguments.length <= 2 || arguments[2] === undefined?function(err,token){}:arguments[2];var self=this;return new Promise(function(resolve,reject){if(self.state === 0 || self.state === 4){self.state = 1; //set the state to logging in
+self.email = email;self.password = password;request.post(Endpoints.LOGIN).send({email:email,password:password}).end(function(err,res){if(err){self.state = 4; //set state to disconnected
+self.trigger("disconnected");if(self.websocket){self.websocket.close();}callback(err);reject(err);}else {self.state = 2; //set state to logged in (not yet ready)
+self.token = res.body.token; //set our token
+self.getGateway().then(function(url){self.createws(url);callback(null,self.token);resolve(self.token);})["catch"](function(err){callback(err);reject(err);});}});}else {reject(new Error("Client already logging in or ready"));}});};Client.prototype.logout = function logout(){var callback=arguments.length <= 0 || arguments[0] === undefined?function(err){}:arguments[0];var self=this;return new Promise(function(resolve,reject){request.post(Endpoints.LOGOUT).set("authorization",self.token).end(function(err,res){if(err){callback(err);reject(err);}else {self.websocket.close();self.state = 4;callback();resolve();}});});};Client.prototype.createServer = function createServer(name,region){var callback=arguments.length <= 2 || arguments[2] === undefined?function(err,server){}:arguments[2];var self=this;return new Promise(function(resolve,reject){request.post(Endpoints.SERVERS).set("authorization",self.token).send({name:name,region:region}).end(function(err,res){if(err){callback(err);reject(err);}else { // potentially redundant in future
+// creating here does NOT give us the channels of the server
+// so we must wait for the guild_create event.
+self.serverCreateListener[res.body.id] = [resolve,callback]; /*var srv = self.addServer(res.body);
+ callback(null, srv);
+ resolve(srv);*/}});});};Client.prototype.createChannel = function createChannel(server,channelName,channelType){var callback=arguments.length <= 3 || arguments[3] === undefined?function(err,chann){}:arguments[3];var self=this;return new Promise(function(resolve,reject){request.post(Endpoints.SERVERS + "/" + self.resolveServerID(server) + "/channels").set("authorization",self.token).send({name:channelName,type:channelType}).end(function(err,res){if(err){callback(err);reject(err);}else {var server=self.getServer("id",res.body.guild_id);var chann=self.addChannel(res.body,res.body.guild_id);server.addChannel(chann);callback(null,chann);resolve(chann);}});});};Client.prototype.leaveServer = function leaveServer(server){var callback=arguments.length <= 1 || arguments[1] === undefined?function(err,server){}:arguments[1];var self=this;return new Promise(function(resolve,reject){request.del(Endpoints.SERVERS + "/" + self.resolveServerID(server)).set("authorization",self.token).end(function(err,res){if(err){callback(err);reject(err);}else {self.serverCache.splice(self.serverCache.indexOf(server),1);callback(null);resolve();}});});};Client.prototype.createInvite = function createInvite(serverOrChannel,options){var callback=arguments.length <= 2 || arguments[2] === undefined?function(err,invite){}:arguments[2];var self=this;return new Promise(function(resolve,reject){var destination;if(serverOrChannel instanceof Server){destination = serverOrChannel.id;}else if(serverOrChannel instanceof Channel){destination = serverOrChannel.id;}else {destination = serverOrChannel;}options = options || {};options.max_age = options.maxAge || 0;options.max_uses = options.maxUses || 0;options.temporary = options.temporary || false;options.xkcdpass = options.xkcd || false;request.post(Endpoints.CHANNELS + "/" + destination + "/invites").set("authorization",self.token).send(options).end(function(err,res){if(err){callback(err);reject(err);}else {var inv=new Invite(res.body,self);callback(null,inv);resolve(inv);}});});};Client.prototype.startPM = function startPM(user){var self=this;return new Promise(function(resolve,reject){var userId=user;if(user instanceof User){userId = user.id;}request.post(Endpoints.USERS + "/" + self.user.id + "/channels").set("authorization",self.token).send({recipient_id:userId}).end(function(err,res){if(err){reject(err);}else {resolve(self.addPMChannel(res.body));}});});};Client.prototype.reply = function reply(destination,message,tts){var callback=arguments.length <= 3 || arguments[3] === undefined?function(err,msg){}:arguments[3];var self=this;return new Promise(function(response,reject){if(typeof tts === "function"){ // tts is a function, which means the developer wants this to be the callback
+callback = tts;tts = false;}var user=destination.sender;self.sendMessage(destination,message,tts,callback,user + ", ").then(response)["catch"](reject);});};Client.prototype.deleteMessage = function deleteMessage(message,timeout){var callback=arguments.length <= 2 || arguments[2] === undefined?function(err,msg){}:arguments[2];var self=this;return new Promise(function(resolve,reject){if(timeout){setTimeout(remove,timeout);}else {remove();}function remove(){request.del(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization",self.token).end(function(err,res){if(err){bad();}else {good();}});}function good(){callback();resolve();}function bad(err){callback(err);reject(err);}});};Client.prototype.updateMessage = function updateMessage(message,content){var callback=arguments.length <= 2 || arguments[2] === undefined?function(err,msg){}:arguments[2];var self=this;var prom=new Promise(function(resolve,reject){content = content instanceof Array?content.join("\n"):content;if(self.options.queue){if(!self.queue[message.channel.id]){self.queue[message.channel.id] = [];}self.queue[message.channel.id].push({action:"updateMessage",message:message,content:content,then:good,error:bad});self.checkQueue(message.channel.id);}else {self._updateMessage(message,content).then(good)["catch"](bad);}function good(msg){prom.message = msg;callback(null,msg);resolve(msg);}function bad(error){prom.error = error;callback(error);reject(error);}});return prom;};Client.prototype.setUsername = function setUsername(newName){var callback=arguments.length <= 1 || arguments[1] === undefined?function(err){}:arguments[1];var self=this;return new Promise(function(resolve,reject){request.patch(Endpoints.API + "/users/@me").set("authorization",self.token).send({avatar:self.user.avatar,email:self.email,new_password:null,password:self.password,username:newName}).end(function(err){callback(err);if(err)reject(err);else resolve();});});};Client.prototype.getChannelLogs = function getChannelLogs(channel){var amount=arguments.length <= 1 || arguments[1] === undefined?500:arguments[1];var callback=arguments.length <= 2 || arguments[2] === undefined?function(err,logs){}:arguments[2];var self=this;return new Promise(function(resolve,reject){var channelID=channel;if(channel instanceof Channel){channelID = channel.id;}request.get(Endpoints.CHANNELS + "/" + channelID + "/messages?limit=" + amount).set("authorization",self.token).end(function(err,res){if(err){callback(err);reject(err);}else {var logs=[];var channel=self.getChannel("id",channelID);for(var _iterator=res.body,_isArray=Array.isArray(_iterator),_i=0,_iterator=_isArray?_iterator:_iterator[Symbol.iterator]();;) {var _ref;if(_isArray){if(_i >= _iterator.length)break;_ref = _iterator[_i++];}else {_i = _iterator.next();if(_i.done)break;_ref = _i.value;}var message=_ref;var mentions=[];for(var _iterator2=message.mentions,_isArray2=Array.isArray(_iterator2),_i2=0,_iterator2=_isArray2?_iterator2:_iterator2[Symbol.iterator]();;) {var _ref2;if(_isArray2){if(_i2 >= _iterator2.length)break;_ref2 = _iterator2[_i2++];}else {_i2 = _iterator2.next();if(_i2.done)break;_ref2 = _i2.value;}var mention=_ref2;mentions.push(self.addUser(mention));}var author=self.addUser(message.author);logs.push(new Message(message,channel,mentions,author));}callback(null,logs);resolve(logs);}});});};Client.prototype.deleteChannel = function deleteChannel(channel){var callback=arguments.length <= 1 || arguments[1] === undefined?function(err){}:arguments[1];var self=this;return new Promise(function(resolve,reject){var channelID=channel;if(channel instanceof Channel){channelID = channel.id;}request.del(Endpoints.CHANNELS + "/" + channelID).set("authorization",self.token).end(function(err){if(err){callback(err);reject(err);}else {callback(null);resolve();}});});};Client.prototype.joinServer = function joinServer(invite){var callback=arguments.length <= 1 || arguments[1] === undefined?function(err,server){}:arguments[1];var self=this;return new Promise(function(resolve,reject){var id=invite instanceof Invite?invite.code:invite;request.post(Endpoints.API + "/invite/" + id).set("authorization",self.token).end(function(err,res){if(err){callback(err);reject(err);}else {if(self.getServer("id",res.body.guild.id)){resolve(self.getServer("id",res.body.guild.id));}else {self.serverCreateListener[res.body.guild.id] = [resolve,callback];}}});});};Client.prototype.sendFile = function sendFile(destination,file){var fileName=arguments.length <= 2 || arguments[2] === undefined?"image.png":arguments[2];var callback=arguments.length <= 3 || arguments[3] === undefined?function(err,msg){}:arguments[3];var self=this;var prom=new Promise(function(resolve,reject){var fstream;if(typeof file === "string" || file instanceof String){fstream = fs.createReadStream(file);fileName = file;}else {fstream = file;}self.resolveDestination(destination).then(send)["catch"](bad);function send(destination){if(self.options.queue){ //queue send file too
+if(!self.queue[destination]){self.queue[destination] = [];}self.queue[destination].push({action:"sendFile",attachment:fstream,attachmentName:fileName,then:good,error:bad});self.checkQueue(destination);}else { //not queue
+self._sendFile(destination,fstream,fileName).then(good)["catch"](bad);}}function good(msg){prom.message = msg;callback(null,msg);resolve(msg);}function bad(err){prom.error = err;callback(err);reject(err);}});return prom;};Client.prototype.sendMessage = function sendMessage(destination,message,tts){var callback=arguments.length <= 3 || arguments[3] === undefined?function(err,msg){}:arguments[3];var premessage=arguments.length <= 4 || arguments[4] === undefined?"":arguments[4];var self=this;var prom=new Promise(function(resolve,reject){if(typeof tts === "function"){ // tts is a function, which means the developer wants this to be the callback
+callback = tts;tts = false;}message = premessage + resolveMessage(message);var mentions=resolveMentions();self.resolveDestination(destination).then(send)["catch"](error);function error(err){callback(err);reject(err);}function send(destination){if(self.options.queue){ //we're QUEUEING messages, so sending them sequentially based on servers.
+if(!self.queue[destination]){self.queue[destination] = [];}self.queue[destination].push({action:"sendMessage",content:message,mentions:mentions,tts:!!tts, //incase it's not a boolean
+then:mgood,error:mbad});self.checkQueue(destination);}else {self._sendMessage(destination,message,tts,mentions).then(mgood)["catch"](mbad);}}function mgood(msg){prom.message = msg;callback(null,msg);resolve(msg);}function mbad(error){prom.error = error;callback(error);reject(error);}function resolveMessage(){var msg=message;if(message instanceof Array){msg = message.join("\n");}return msg;}function resolveMentions(){var _mentions=[];for(var _iterator3=message.match(/<@[^>]*>/g) || [],_isArray3=Array.isArray(_iterator3),_i3=0,_iterator3=_isArray3?_iterator3:_iterator3[Symbol.iterator]();;) {var _ref3;if(_isArray3){if(_i3 >= _iterator3.length)break;_ref3 = _iterator3[_i3++];}else {_i3 = _iterator3.next();if(_i3.done)break;_ref3 = _i3.value;}var mention=_ref3;_mentions.push(mention.substring(2,mention.length - 1));}return _mentions;}});return prom;}; //def createws
+Client.prototype.createws = function createws(url){if(this.websocket)return false;var self=this; //good to go
+this.websocket = new WebSocket(url); //open
+this.websocket.onopen = function(){self.trySendConnData(); //try connecting
+}; //close
+this.websocket.onclose = function(){self.trigger("disconnected");}; //message
+this.websocket.onmessage = function(e){var dat=false,data={};try{dat = JSON.parse(e.data);data = dat.d;}catch(err) {self.trigger("error",err,e);return;}self.trigger("raw",dat); //valid message
+switch(dat.t){case "READY":self.debug("received ready packet");self.user = self.addUser(data.user);for(var _iterator4=data.guilds,_isArray4=Array.isArray(_iterator4),_i4=0,_iterator4=_isArray4?_iterator4:_iterator4[Symbol.iterator]();;) {var _ref4;if(_isArray4){if(_i4 >= _iterator4.length)break;_ref4 = _iterator4[_i4++];}else {_i4 = _iterator4.next();if(_i4.done)break;_ref4 = _i4.value;}var _server=_ref4;var server=self.addServer(_server);}for(var _iterator5=data.private_channels,_isArray5=Array.isArray(_iterator5),_i5=0,_iterator5=_isArray5?_iterator5:_iterator5[Symbol.iterator]();;) {var _ref5;if(_isArray5){if(_i5 >= _iterator5.length)break;_ref5 = _iterator5[_i5++];}else {_i5 = _iterator5.next();if(_i5.done)break;_ref5 = _i5.value;}var _pmc=_ref5;var pmc=self.addPMChannel(_pmc);}self.trigger("ready");self.readyTime = Date.now();self.debug("cached " + self.serverCache.length + " servers, " + self.channelCache.length + " channels, " + self.pmChannelCache.length + " PMs and " + self.userCache.length + " users.");self.state = 3;setInterval(function(){self.keepAlive.apply(self);},data.heartbeat_interval);break;case "MESSAGE_CREATE":self.debug("received message");var mentions=[];data.mentions = data.mentions || []; //for some reason this was not defined at some point?
+for(var _iterator6=data.mentions,_isArray6=Array.isArray(_iterator6),_i6=0,_iterator6=_isArray6?_iterator6:_iterator6[Symbol.iterator]();;) {var _ref6;if(_isArray6){if(_i6 >= _iterator6.length)break;_ref6 = _iterator6[_i6++];}else {_i6 = _iterator6.next();if(_i6.done)break;_ref6 = _i6.value;}var mention=_ref6;mentions.push(self.addUser(mention));}var channel=self.getChannel("id",data.channel_id);if(channel){var msg=channel.addMessage(new Message(data,channel,mentions,self.addUser(data.author)));self.trigger("message",msg);}break;case "MESSAGE_DELETE":self.debug("message deleted");var channel=self.getChannel("id",data.channel_id);var message=channel.getMessage("id",data.id);if(message){self.trigger("messageDelete",channel,message);channel.messages.splice(channel.messages.indexOf(message),1);}else { //don't have the cache of that message ;(
+self.trigger("messageDelete",channel);}break;case "MESSAGE_UPDATE":self.debug("message updated");var channel=self.getChannel("id",data.channel_id);var formerMessage=channel.getMessage("id",data.id);if(formerMessage){ //new message might be partial, so we need to fill it with whatever the old message was.
+var info={};for(var key in formerMessage) {info[key] = formerMessage[key];}for(var key in data) {info[key] = data[key];}var mentions=[];for(var _iterator7=info.mentions,_isArray7=Array.isArray(_iterator7),_i7=0,_iterator7=_isArray7?_iterator7:_iterator7[Symbol.iterator]();;) {var _ref7;if(_isArray7){if(_i7 >= _iterator7.length)break;_ref7 = _iterator7[_i7++];}else {_i7 = _iterator7.next();if(_i7.done)break;_ref7 = _i7.value;}var mention=_ref7;mentions.push(self.addUser(mention));}var newMessage=new Message(info,channel,mentions,formerMessage.author);self.trigger("messageUpdate",newMessage,formerMessage);channel.messages[channel.messages.indexOf(formerMessage)] = newMessage;} // message isn't in cache, and if it's a partial it could cause
+// all hell to break loose... best to just act as if nothing happened
+break;case "GUILD_DELETE":var server=self.getServer("id",data.id);if(server){self.serverCache.splice(self.serverCache.indexOf(server),1);self.trigger("serverDelete",server);}break;case "CHANNEL_DELETE":var channel=self.getChannel("id",data.id);if(channel){var server=channel.server;if(server){server.channels.splice(server.channels.indexOf(channel),1);}self.trigger("channelDelete",channel);self.serverCache.splice(self.serverCache.indexOf(channel),1);}break;case "GUILD_CREATE":var server=self.getServer("id",data.id);if(!server){ //if server doesn't already exist because duh
+server = self.addServer(data);} /*else if(server.channels.length === 0){
+
+ var srv = new Server(data, self);
+ for(channel of data.channels){
+ srv.channels.push(new Channel(channel, data.id));
+ }
+ self.serverCache[self.serverCache.indexOf(server)] = srv;
+
+ }*/if(self.serverCreateListener[data.id]){var cbs=self.serverCreateListener[data.id];cbs[0](server); //promise then callback
+cbs[1](null,server); //legacy callback
+self.serverCreateListener[data.id] = null;}self.trigger("serverCreate",server);break;case "CHANNEL_CREATE":var channel=self.getChannel("id",data.id);if(!channel){var chann;if(data.is_private){chann = self.addPMChannel(data);}else {chann = self.addChannel(data,data.guild_id);}var srv=self.getServer("id",data.guild_id);if(srv){srv.addChannel(chann);}self.trigger("channelCreate",chann);}break;case "GUILD_MEMBER_ADD":var server=self.getServer("id",data.guild_id);if(server){var user=self.addUser(data.user); //if for whatever reason it doesn't exist..
+self.trigger("serverNewMember",server.addMember(user,data.roles),server);}break;case "GUILD_MEMBER_REMOVE":var server=self.getServer("id",data.guild_id);if(server){var user=self.addUser(data.user); //if for whatever reason it doesn't exist..
+server.removeMember("id",user.id);self.trigger("serverRemoveMember",user,server);}break;case "USER_UPDATE":if(self.user && data.id === self.user.id){var newUser=new User(data); //not actually adding to the cache
+self.trigger("userUpdate",newUser,self.user);if(~self.userCache.indexOf(self.user)){self.userCache[self.userCache.indexOf(self.user)] = newUser;}self.user = newUser;}break;case "PRESENCE_UPDATE":var userInCache=self.getUser("id",data.user.id);if(userInCache){ //user exists
+data.user.username = data.user.username || userInCache.username;data.user.id = data.user.id || userInCache.id;data.user.discriminator = data.user.discriminator || userInCache.discriminator;data.user.avatar = data.user.avatar || userInCache.avatar;var presenceUser=new User(data.user);if(presenceUser.equalsStrict(userInCache)){ //they're exactly the same, an actual presence update
+self.trigger("presence",{user:userInCache,oldStatus:userInCache.status,status:data.status,server:self.getServer("id",data.guild_id),gameId:data.game_id});userInCache.status = data.status;userInCache.gameId = data.game_id;}else { //one of their details changed.
+self.userCache[self.userCache.indexOf(userInCache)] = presenceUser;self.trigger("userUpdate",userInCache,presenceUser);}}break;case "CHANNEL_UPDATE":var channelInCache=self.getChannel("id",data.id),serverInCache=self.getServer("id",data.guild_id);if(channelInCache && serverInCache){var newChann=new Channel(data,serverInCache);newChann.messages = channelInCache.messages;self.trigger("channelUpdate",channelInCache,newChann);self.channelCache[self.channelCache.indexOf(channelInCache)] = newChann;}break;case "TYPING_START":var userInCache=self.getUser("id",data.user_id);var channelInCache=self.getChannel("id",data.channel_id);if(!self.userTypingListener[data.user_id] || self.userTypingListener[data.user_id] === -1){self.trigger("startTyping",userInCache,channelInCache);}self.userTypingListener[data.user_id] = Date.now();setTimeout(function(){if(self.userTypingListener[data.user_id] === -1){return;}if(Date.now() - self.userTypingListener[data.user_id] > 6000){ // stopped typing
+self.trigger("stopTyping",userInCache,channelInCache);self.userTypingListener[data.user_id] = -1;}},6000);break;case "GUILD_ROLE_DELETE":var server=self.getServer("id",data.guild_id);var role=server.getRole(data.role_id);self.trigger("serverRoleDelete",server,role);server.removeRole(role.id);break;case "GUILD_ROLE_UPDATE":var server=self.getServer("id",data.guild_id);var role=server.getRole(data.role.id);var newRole=server.updateRole(data.role);self.trigger("serverRoleUpdate",server,role,newRole);break;default:self.debug("received unknown packet");self.trigger("unknown",dat);break;}};}; //def addUser
+Client.prototype.addUser = function addUser(data){if(!this.getUser("id",data.id)){this.userCache.push(new User(data));}return this.getUser("id",data.id);}; //def addChannel
+Client.prototype.addChannel = function addChannel(data,serverId){if(!this.getChannel("id",data.id)){this.channelCache.push(new Channel(data,this.getServer("id",serverId)));}return this.getChannel("id",data.id);};Client.prototype.addPMChannel = function addPMChannel(data){if(!this.getPMChannel("id",data.id)){this.pmChannelCache.push(new PMChannel(data,this));}return this.getPMChannel("id",data.id);};Client.prototype.setTopic = function setTopic(channel,topic){var callback=arguments.length <= 2 || arguments[2] === undefined?function(err){}:arguments[2];var self=this;return new Promise(function(resolve,reject){self.resolveDestination(channel).then(next)["catch"](error);function error(e){callback(e);reject(e);}function next(destination){var asChan=self.getChannel("id",destination);request.patch(Endpoints.CHANNELS + "/" + destination).set("authorization",self.token).send({name:asChan.name,position:0,topic:topic}).end(function(err,res){if(err){error(err);}else {asChan.topic = res.body.topic;resolve();callback();}});}});}; //def addServer
+Client.prototype.addServer = function addServer(data){var self=this;var server=this.getServer("id",data.id);if(data.unavailable){self.trigger("unavailable",data);self.debug("Server ID " + data.id + " has been marked unavailable by Discord. It was not cached.");return;}if(!server){server = new Server(data,this);this.serverCache.push(server);if(data.channels){for(var _iterator8=data.channels,_isArray8=Array.isArray(_iterator8),_i8=0,_iterator8=_isArray8?_iterator8:_iterator8[Symbol.iterator]();;) {var _ref8;if(_isArray8){if(_i8 >= _iterator8.length)break;_ref8 = _iterator8[_i8++];}else {_i8 = _iterator8.next();if(_i8.done)break;_ref8 = _i8.value;}var channel=_ref8;server.channels.push(this.addChannel(channel,server.id));}}}for(var _iterator9=data.presences,_isArray9=Array.isArray(_iterator9),_i9=0,_iterator9=_isArray9?_iterator9:_iterator9[Symbol.iterator]();;) {var _ref9;if(_isArray9){if(_i9 >= _iterator9.length)break;_ref9 = _iterator9[_i9++];}else {_i9 = _iterator9.next();if(_i9.done)break;_ref9 = _i9.value;}var presence=_ref9;var user=self.getUser("id",presence.user.id);user.status = presence.status;user.gameId = presence.game_id;}return server;}; //def getUser
+Client.prototype.getUser = function getUser(key,value){for(var _iterator10=this.userCache,_isArray10=Array.isArray(_iterator10),_i10=0,_iterator10=_isArray10?_iterator10:_iterator10[Symbol.iterator]();;) {var _ref10;if(_isArray10){if(_i10 >= _iterator10.length)break;_ref10 = _iterator10[_i10++];}else {_i10 = _iterator10.next();if(_i10.done)break;_ref10 = _i10.value;}var user=_ref10;if(user[key] === value){return user;}}return null;}; //def getChannel
+Client.prototype.getChannel = function getChannel(key,value){for(var _iterator11=this.channelCache,_isArray11=Array.isArray(_iterator11),_i11=0,_iterator11=_isArray11?_iterator11:_iterator11[Symbol.iterator]();;) {var _ref11;if(_isArray11){if(_i11 >= _iterator11.length)break;_ref11 = _iterator11[_i11++];}else {_i11 = _iterator11.next();if(_i11.done)break;_ref11 = _i11.value;}var channel=_ref11;if(channel[key] === value){return channel;}}return this.getPMChannel(key,value); //might be a PM
+};Client.prototype.getPMChannel = function getPMChannel(key,value){for(var _iterator12=this.pmChannelCache,_isArray12=Array.isArray(_iterator12),_i12=0,_iterator12=_isArray12?_iterator12:_iterator12[Symbol.iterator]();;) {var _ref12;if(_isArray12){if(_i12 >= _iterator12.length)break;_ref12 = _iterator12[_i12++];}else {_i12 = _iterator12.next();if(_i12.done)break;_ref12 = _i12.value;}var channel=_ref12;if(channel[key] === value){return channel;}}return null;}; //def getServer
+Client.prototype.getServer = function getServer(key,value){for(var _iterator13=this.serverCache,_isArray13=Array.isArray(_iterator13),_i13=0,_iterator13=_isArray13?_iterator13:_iterator13[Symbol.iterator]();;) {var _ref13;if(_isArray13){if(_i13 >= _iterator13.length)break;_ref13 = _iterator13[_i13++];}else {_i13 = _iterator13.next();if(_i13.done)break;_ref13 = _i13.value;}var server=_ref13;if(server[key] === value){return server;}}return null;}; //def trySendConnData
+Client.prototype.trySendConnData = function trySendConnData(){if(this.token && !this.alreadySentData){this.alreadySentData = true;var data={op:2,d:{token:this.token,v:3,properties:{"$os":"discord.js","$browser":"discord.js","$device":"discord.js","$referrer":"","$referring_domain":""}}};this.websocket.send(JSON.stringify(data));}};Client.prototype.resolveServerID = function resolveServerID(resource){if(resource instanceof Server){return resource.id;}else if(!isNaN(resource) && resource.length && resource.length === 17){return resource;}};Client.prototype.resolveDestination = function resolveDestination(destination){var channId=false;var self=this;return new Promise(function(resolve,reject){if(destination instanceof Server){channId = destination.id; //general is the same as server id
+}else if(destination instanceof Channel){channId = destination.id;}else if(destination instanceof Message){channId = destination.channel.id;}else if(destination instanceof PMChannel){channId = destination.id;}else if(destination instanceof User){ //check if we have a PM
+for(var _iterator14=self.pmChannelCache,_isArray14=Array.isArray(_iterator14),_i14=0,_iterator14=_isArray14?_iterator14:_iterator14[Symbol.iterator]();;) {var _ref14;if(_isArray14){if(_i14 >= _iterator14.length)break;_ref14 = _iterator14[_i14++];}else {_i14 = _iterator14.next();if(_i14.done)break;_ref14 = _i14.value;}var pmc=_ref14;if(pmc.user && pmc.user.equals(destination)){resolve(pmc.id);return;}} //we don't, at this point we're late
+self.startPM(destination).then(function(pmc){resolve(pmc.id);})["catch"](reject);}else {channId = destination;}if(channId)resolve(channId);else reject();});};Client.prototype._sendMessage = function _sendMessage(destination,content,tts,mentions){var self=this;return new Promise(function(resolve,reject){request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization",self.token).send({content:content,mentions:mentions,tts:tts}).end(function(err,res){if(err){reject(err);}else {var data=res.body;var mentions=[];data.mentions = data.mentions || []; //for some reason this was not defined at some point?
+for(var _iterator15=data.mentions,_isArray15=Array.isArray(_iterator15),_i15=0,_iterator15=_isArray15?_iterator15:_iterator15[Symbol.iterator]();;) {var _ref15;if(_isArray15){if(_i15 >= _iterator15.length)break;_ref15 = _iterator15[_i15++];}else {_i15 = _iterator15.next();if(_i15.done)break;_ref15 = _i15.value;}var mention=_ref15;mentions.push(self.addUser(mention));}var channel=self.getChannel("id",data.channel_id);if(channel){var msg=channel.addMessage(new Message(data,channel,mentions,self.addUser(data.author)));resolve(msg);}}});});};Client.prototype._sendFile = function _sendFile(destination,attachment){var attachmentName=arguments.length <= 2 || arguments[2] === undefined?"DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png":arguments[2];var self=this;return new Promise(function(resolve,reject){request.post(Endpoints.CHANNELS + "/" + destination + "/messages").set("authorization",self.token).attach("file",attachment,attachmentName).end(function(err,res){if(err){reject(err);}else {var chann=self.getChannel("id",destination);if(chann){var msg=chann.addMessage(new Message(res.body,chann,[],self.user));resolve(msg);}}});});};Client.prototype._updateMessage = function _updateMessage(message,content){var self=this;return new Promise(function(resolve,reject){request.patch(Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id).set("authorization",self.token).send({content:content,mentions:[]}).end(function(err,res){if(err){reject(err);}else {var msg=new Message(res.body,message.channel,message.mentions,message.sender);resolve(msg);message.channel.messages[message.channel.messages.indexOf(message)] = msg;}});});};Client.prototype.getGateway = function getGateway(){var self=this;return new Promise(function(resolve,reject){request.get(Endpoints.API + "/gateway").set("authorization",self.token).end(function(err,res){if(err){reject(err);}else {resolve(res.body.url);}});});};Client.prototype.setStatusIdle = function setStatusIdle(){this.setStatus("idle");};Client.prototype.setStatusOnline = function setStatusOnline(){this.setStatus("online");};Client.prototype.setStatusActive = function setStatusActive(){this.setStatusOnline();};Client.prototype.setStatusHere = function setStatusHere(){this.setStatusOnline();};Client.prototype.setStatusAway = function setStatusAway(){this.setStatusIdle();};Client.prototype.startTyping = function startTyping(chann,stopTypeTime){var self=this;this.resolveDestination(chann).then(next);function next(channel){if(self.typingIntervals[channel]){return;}var fn=function fn(){request.post(Endpoints.CHANNELS + "/" + channel + "/typing").set("authorization",self.token).end();};fn();var interval=setInterval(fn,3000);self.typingIntervals[channel] = interval;if(stopTypeTime){setTimeout(function(){self.stopTyping(channel);},stopTypeTime);}}};Client.prototype.stopTyping = function stopTyping(chann){var self=this;this.resolveDestination(chann).then(next);function next(channel){if(!self.typingIntervals[channel]){return;}clearInterval(self.typingIntervals[channel]);delete self.typingIntervals[channel];}};Client.prototype.setStatus = function setStatus(stat){var idleTime=stat === "online"?null:Date.now();this.__idleTime = idleTime;this.websocket.send(JSON.stringify({op:3,d:{idle_since:this.__idleTime,game_id:this.__gameId}}));};Client.prototype.setPlayingGame = function setPlayingGame(id){if(id instanceof String || typeof id === "string"){ // working on names
+var gid=id.trim().toUpperCase();id = null;for(var _iterator16=gameMap,_isArray16=Array.isArray(_iterator16),_i16=0,_iterator16=_isArray16?_iterator16:_iterator16[Symbol.iterator]();;) {var _ref16;if(_isArray16){if(_i16 >= _iterator16.length)break;_ref16 = _iterator16[_i16++];}else {_i16 = _iterator16.next();if(_i16.done)break;_ref16 = _i16.value;}var game=_ref16;if(game.name.trim().toUpperCase() === gid){id = game.id;break;}}}this.__gameId = id;this.websocket.send(JSON.stringify({op:3,d:{idle_since:this.__idleTime,game_id:this.__gameId}}));};Client.prototype.playGame = function playGame(id){this.setPlayingGame(id);};Client.prototype.playingGame = function playingGame(id){this.setPlayingGame(id);};_createClass(Client,[{key:"uptime",get:function get(){return this.readyTime?Date.now() - this.readyTime:null;}},{key:"ready",get:function get(){return this.state === 3;}},{key:"servers",get:function get(){return this.serverCache;}},{key:"channels",get:function get(){return this.channelCache;}},{key:"users",get:function get(){return this.userCache;}},{key:"PMChannels",get:function get(){return this.pmChannelCache;}},{key:"messages",get:function get(){var msgs=[];for(var _iterator17=this.channelCache,_isArray17=Array.isArray(_iterator17),_i17=0,_iterator17=_isArray17?_iterator17:_iterator17[Symbol.iterator]();;) {var _ref17;if(_isArray17){if(_i17 >= _iterator17.length)break;_ref17 = _iterator17[_i17++];}else {_i17 = _iterator17.next();if(_i17.done)break;_ref17 = _i17.value;}var channel=_ref17;msgs = msgs.concat(channel.messages);}return msgs;}}]);return Client;})();module.exports = Client;
+
+},{"../ref/gameMap.json":19,"./Endpoints.js":3,"./PMChannel.js":6,"./channel.js":8,"./invite.js":10,"./message.js":11,"./server.js":12,"./user.js":13,"fs":14,"superagent":15,"ws":18}],3:[function(require,module,exports){
+"use strict";exports.BASE_DOMAIN = "discordapp.com";exports.BASE = "https://" + exports.BASE_DOMAIN;exports.WEBSOCKET_HUB = "wss://" + exports.BASE_DOMAIN + "/hub";exports.API = exports.BASE + "/api";exports.AUTH = exports.API + "/auth";exports.LOGIN = exports.AUTH + "/login";exports.LOGOUT = exports.AUTH + "/logout";exports.USERS = exports.API + "/users";exports.SERVERS = exports.API + "/guilds";exports.CHANNELS = exports.API + "/channels";
+
+},{}],4:[function(require,module,exports){
+"use strict";var _createClass=(function(){function defineProperties(target,props){for(var i=0;i < props.length;i++) {var descriptor=props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if("value" in descriptor)descriptor.writable = true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};})();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}var EvaluatedPermissions=(function(){function EvaluatedPermissions(data){_classCallCheck(this,EvaluatedPermissions);var self=this;this.packed = data;if(this.getBit(3))this.packed = 4294967295;}EvaluatedPermissions.prototype.serialise = function serialise(){return {createInstantInvite:this.createInstantInvite,manageRoles:this.manageRoles,manageChannels:this.manageChannels,readMessages:this.readMessages,sendMessages:this.sendMessage,sendTTSMessages:this.sendTTSMessages,manageMessages:this.manageMessages,embedLinks:this.embedLinks,attachFiles:this.attachFiles,readMessageHistory:this.readMessageHistory,mentionEveryone:this.mentionEveryone,voiceConnect:this.voiceConnect,voiceSpeak:this.voiceSpeak,voiceMuteMembers:this.voiceMuteMembers,voiceDeafenMembers:this.voiceDeafenMembers,voiceMoveMember:this.voiceMoveMembers,voiceUseVoiceActivation:this.voiceUseVoiceActivation};};EvaluatedPermissions.prototype.getBit = function getBit(x){return (this.packed >>> x & 1) === 1;};EvaluatedPermissions.prototype.setBit = function setBit(){};_createClass(EvaluatedPermissions,[{key:"createInstantInvite",get:function get(){return this.getBit(0);},set:function set(val){this.setBit(0,val);}},{key:"manageRoles",get:function get(){return this.getBit(3);},set:function set(val){this.setBit(3,val);}},{key:"manageChannels",get:function get(){return this.getBit(4);},set:function set(val){this.setBit(4,val);}},{key:"readMessages",get:function get(){return this.getBit(10);},set:function set(val){this.setBit(10,val);}},{key:"sendMessages",get:function get(){return this.getBit(11);},set:function set(val){this.setBit(11,val);}},{key:"sendTTSMessages",get:function get(){return this.getBit(12);},set:function set(val){this.setBit(12,val);}},{key:"manageMessages",get:function get(){return this.getBit(13);},set:function set(val){this.setBit(13,val);}},{key:"embedLinks",get:function get(){return this.getBit(14);},set:function set(val){this.setBit(14,val);}},{key:"attachFiles",get:function get(){return this.getBit(15);},set:function set(val){this.setBit(15,val);}},{key:"readMessageHistory",get:function get(){return this.getBit(16);},set:function set(val){this.setBit(16,val);}},{key:"mentionEveryone",get:function get(){return this.getBit(17);},set:function set(val){this.setBit(17,val);}},{key:"voiceConnect",get:function get(){return this.getBit(20);},set:function set(val){this.setBit(20,val);}},{key:"voiceSpeak",get:function get(){return this.getBit(21);},set:function set(val){this.setBit(21,val);}},{key:"voiceMuteMembers",get:function get(){return this.getBit(22);},set:function set(val){this.setBit(22,val);}},{key:"voiceDeafenMembers",get:function get(){return this.getBit(23);},set:function set(val){this.setBit(23,val);}},{key:"voiceMoveMembers",get:function get(){return this.getBit(24);},set:function set(val){this.setBit(24,val);}},{key:"voiceUseVoiceActivation",get:function get(){return this.getBit(25);},set:function set(val){this.setBit(25,val);}}]);return EvaluatedPermissions;})();module.exports = EvaluatedPermissions;
+
+},{}],5:[function(require,module,exports){
+"use strict";var _createClass=(function(){function defineProperties(target,props){for(var i=0;i < props.length;i++) {var descriptor=props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if("value" in descriptor)descriptor.writable = true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};})();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}function _inherits(subClass,superClass){if(typeof superClass !== "function" && superClass !== null){throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);}subClass.prototype = Object.create(superClass && superClass.prototype,{constructor:{value:subClass,enumerable:false,writable:true,configurable:true}});if(superClass)Object.setPrototypeOf?Object.setPrototypeOf(subClass,superClass):subClass.__proto__ = superClass;}var User=require("./user.js");var ServerPermissions=require("./ServerPermissions.js");var EvaluatedPermissions=require("./EvaluatedPermissions.js");var Member=(function(_User){_inherits(Member,_User);function Member(user,server,roles){_classCallCheck(this,Member);_User.call(this,user); // should work, we are basically creating a Member that has the same properties as user and a few more
+this.server = server;this.rawRoles = roles;}Member.prototype.permissionsIn = function permissionsIn(channel){if(channel.server.ownerID === this.id){return new EvaluatedPermissions(4294967295); //all perms
+}var affectingOverwrites=[];var affectingMemberOverwrites=[];for(var _iterator=channel.roles,_isArray=Array.isArray(_iterator),_i=0,_iterator=_isArray?_iterator:_iterator[Symbol.iterator]();;) {var _ref;if(_isArray){if(_i >= _iterator.length)break;_ref = _iterator[_i++];}else {_i = _iterator.next();if(_i.done)break;_ref = _i.value;}var overwrite=_ref;if(overwrite.id === this.id && overwrite.type === "member"){affectingMemberOverwrites.push(overwrite);}else if(this.rawRoles.indexOf(overwrite.id) !== -1){affectingOverwrites.push(overwrite);}}if(affectingOverwrites.length === 0 && affectingMemberOverwrites.length === 0){return new EvaluatedPermissions(this.evalPerms.packed);}var finalPacked=affectingOverwrites.length !== 0?affectingOverwrites[0].packed:affectingMemberOverwrites[0].packed;for(var _iterator2=affectingOverwrites,_isArray2=Array.isArray(_iterator2),_i2=0,_iterator2=_isArray2?_iterator2:_iterator2[Symbol.iterator]();;) {var _ref2;if(_isArray2){if(_i2 >= _iterator2.length)break;_ref2 = _iterator2[_i2++];}else {_i2 = _iterator2.next();if(_i2.done)break;_ref2 = _i2.value;}var overwrite=_ref2;finalPacked = finalPacked & ~overwrite.deny;finalPacked = finalPacked | overwrite.allow;}for(var _iterator3=affectingMemberOverwrites,_isArray3=Array.isArray(_iterator3),_i3=0,_iterator3=_isArray3?_iterator3:_iterator3[Symbol.iterator]();;) {var _ref3;if(_isArray3){if(_i3 >= _iterator3.length)break;_ref3 = _iterator3[_i3++];}else {_i3 = _iterator3.next();if(_i3.done)break;_ref3 = _i3.value;}var overwrite=_ref3;finalPacked = finalPacked & ~overwrite.deny;finalPacked = finalPacked | overwrite.allow;}return new EvaluatedPermissions(finalPacked);};_createClass(Member,[{key:"roles",get:function get(){var ufRoles=[this.server.getRole(this.server.id)];for(var _iterator4=this.rawRoles,_isArray4=Array.isArray(_iterator4),_i4=0,_iterator4=_isArray4?_iterator4:_iterator4[Symbol.iterator]();;) {var _ref4;if(_isArray4){if(_i4 >= _iterator4.length)break;_ref4 = _iterator4[_i4++];}else {_i4 = _iterator4.next();if(_i4.done)break;_ref4 = _i4.value;}var rawRole=_ref4;ufRoles.push(this.server.getRole(rawRole));}return ufRoles;}},{key:"evalPerms",get:function get(){var basePerms=this.roles, //cache roles as it can be slightly expensive
+basePerm=basePerms[0].packed;for(var _iterator5=basePerms,_isArray5=Array.isArray(_iterator5),_i5=0,_iterator5=_isArray5?_iterator5:_iterator5[Symbol.iterator]();;) {var _ref5;if(_isArray5){if(_i5 >= _iterator5.length)break;_ref5 = _iterator5[_i5++];}else {_i5 = _iterator5.next();if(_i5.done)break;_ref5 = _i5.value;}var perm=_ref5;basePerm = basePerm | perm.packed;}return new ServerPermissions({permissions:basePerm});}}]);return Member;})(User);module.exports = Member;
+
+},{"./EvaluatedPermissions.js":4,"./ServerPermissions.js":7,"./user.js":13}],6:[function(require,module,exports){
+"use strict";var _createClass=(function(){function defineProperties(target,props){for(var i=0;i < props.length;i++) {var descriptor=props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if("value" in descriptor)descriptor.writable = true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};})();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}var PMChannel=(function(){function PMChannel(data,client){_classCallCheck(this,PMChannel);this.user = client.getUser("id",data.recipient.id);this.id = data.id;this.messages = [];this.client = client;}PMChannel.prototype.addMessage = function addMessage(data){if(!this.getMessage("id",data.id)){this.messages.push(data);}return this.getMessage("id",data.id);};PMChannel.prototype.getMessage = function getMessage(key,value){if(this.messages.length > 1000){this.messages.splice(0,1);}for(var _iterator=this.messages,_isArray=Array.isArray(_iterator),_i=0,_iterator=_isArray?_iterator:_iterator[Symbol.iterator]();;) {var _ref;if(_isArray){if(_i >= _iterator.length)break;_ref = _iterator[_i++];}else {_i = _iterator.next();if(_i.done)break;_ref = _i.value;}var message=_ref;if(message[key] === value){return message;}}return null;};_createClass(PMChannel,[{key:"isPrivate",get:function get(){return true;}}]);return PMChannel;})();module.exports = PMChannel;
+
+},{}],7:[function(require,module,exports){
+"use strict";var _createClass=(function(){function defineProperties(target,props){for(var i=0;i < props.length;i++) {var descriptor=props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if("value" in descriptor)descriptor.writable = true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};})();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}var ServerPermissions=(function(){function ServerPermissions(data){_classCallCheck(this,ServerPermissions);var self=this;function getBit(x){return (self.packed >>> x & 1) === 1;}this.packed = data.permissions;this.name = data.name;this.id = data.id;}ServerPermissions.prototype.getBit = function getBit(x){return (this.packed >>> x & 1) === 1;};ServerPermissions.prototype.setBit = function setBit(){ //dummy function for now
+};ServerPermissions.prototype.toString = function toString(){return this.name;};_createClass(ServerPermissions,[{key:"createInstantInvite",get:function get(){return this.getBit(0);},set:function set(val){this.setBit(0,val);}},{key:"banMembers",get:function get(){return this.getBit(1);},set:function set(val){this.setBit(1,val);}},{key:"kickMembers",get:function get(){return this.getBit(2);},set:function set(val){this.setBit(2,val);}},{key:"manageRoles",get:function get(){return this.getBit(3);},set:function set(val){this.setBit(3,val);}},{key:"manageChannels",get:function get(){return this.getBit(4);},set:function set(val){this.setBit(4,val);}},{key:"manageServer",get:function get(){return this.getBit(5);},set:function set(val){this.setBit(5,val);}},{key:"readMessages",get:function get(){return this.getBit(10);},set:function set(val){this.setBit(10,val);}},{key:"sendMessages",get:function get(){return this.getBit(11);},set:function set(val){this.setBit(11,val);}},{key:"sendTTSMessages",get:function get(){return this.getBit(12);},set:function set(val){this.setBit(12,val);}},{key:"manageMessages",get:function get(){return this.getBit(13);},set:function set(val){this.setBit(13,val);}},{key:"embedLinks",get:function get(){return this.getBit(14);},set:function set(val){this.setBit(14,val);}},{key:"attachFiles",get:function get(){return this.getBit(15);},set:function set(val){this.setBit(15,val);}},{key:"readMessageHistory",get:function get(){return this.getBit(16);},set:function set(val){this.setBit(16,val);}},{key:"mentionEveryone",get:function get(){return this.getBit(17);},set:function set(val){this.setBit(17,val);}},{key:"voiceConnect",get:function get(){return this.getBit(20);},set:function set(val){this.setBit(20,val);}},{key:"voiceSpeak",get:function get(){return this.getBit(21);},set:function set(val){this.setBit(21,val);}},{key:"voiceMuteMembers",get:function get(){return this.getBit(22);},set:function set(val){this.setBit(22,val);}},{key:"voiceDeafenMembers",get:function get(){return this.getBit(23);},set:function set(val){this.setBit(23,val);}},{key:"voiceMoveMembers",get:function get(){return this.getBit(24);},set:function set(val){this.setBit(24,val);}},{key:"voiceUseVoiceActivation",get:function get(){return this.getBit(25);},set:function set(val){this.setBit(25,val);}}]);return ServerPermissions;})();module.exports = ServerPermissions;
+
+},{}],8:[function(require,module,exports){
+"use strict";var _createClass=(function(){function defineProperties(target,props){for(var i=0;i < props.length;i++) {var descriptor=props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if("value" in descriptor)descriptor.writable = true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};})();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}var ChannelPermissions=require("./ChannelPermissions.js");var Channel=(function(){function Channel(data,server){_classCallCheck(this,Channel);this.server = server;this.name = data.name;this.type = data.type;this.topic = data.topic;this.id = data.id;this.messages = [];this.roles = [];if(data.permission_overwrites)for(var _iterator=data.permission_overwrites,_isArray=Array.isArray(_iterator),_i=0,_iterator=_isArray?_iterator:_iterator[Symbol.iterator]();;) {var _ref;if(_isArray){if(_i >= _iterator.length)break;_ref = _iterator[_i++];}else {_i = _iterator.next();if(_i.done)break;_ref = _i.value;}var role=_ref;this.roles.push(new ChannelPermissions(role,this));} //this.isPrivate = isPrivate; //not sure about the implementation of this...
+}Channel.prototype.permissionsOf = function permissionsOf(member){var mem=this.server.getMember("id",member.id);if(mem){return mem.permissionsIn(this);}else {return null;}};Channel.prototype.equals = function equals(object){return object && object.id === this.id;};Channel.prototype.addMessage = function addMessage(data){if(this.messages.length > 1000){this.messages.splice(0,1);}if(!this.getMessage("id",data.id)){this.messages.push(data);}return this.getMessage("id",data.id);};Channel.prototype.getMessage = function getMessage(key,value){for(var _iterator2=this.messages,_isArray2=Array.isArray(_iterator2),_i2=0,_iterator2=_isArray2?_iterator2:_iterator2[Symbol.iterator]();;) {var _ref2;if(_isArray2){if(_i2 >= _iterator2.length)break;_ref2 = _iterator2[_i2++];}else {_i2 = _iterator2.next();if(_i2.done)break;_ref2 = _i2.value;}var message=_ref2;if(message[key] === value){return message;}}return null;};Channel.prototype.toString = function toString(){return "<#" + this.id + ">";};_createClass(Channel,[{key:"permissionOverwrites",get:function get(){return this.roles;}},{key:"permissions",get:function get(){return this.roles;}},{key:"client",get:function get(){return this.server.client;}},{key:"isPrivate",get:function get(){return false;}},{key:"users",get:function get(){return this.server.members;}},{key:"members",get:function get(){return this.server.members;}}]);return Channel;})();module.exports = Channel;
+
+},{"./ChannelPermissions.js":1}],9:[function(require,module,exports){
+"use strict";var request=require("superagent");var Endpoints=require("./Endpoints.js");var Client=require("./Client.js");var Discord={Endpoints:Endpoints,Client:Client};Discord.patchStrings = function(){defineProperty("bold","**");defineProperty("underline","__");defineProperty("strike","~~");defineProperty("code","`");defineProperty("codeblock","```");defineProperty("newline","\n");Object.defineProperty(String.prototype,"italic",{get:function get(){return "*" + this + "*";}});function defineProperty(name,joiner){Object.defineProperty(String.prototype,name,{get:function get(){return joiner + this + joiner;}});}};module.exports = Discord;
+
+},{"./Client.js":2,"./Endpoints.js":3,"superagent":15}],10:[function(require,module,exports){
+"use strict";var _createClass=(function(){function defineProperties(target,props){for(var i=0;i < props.length;i++) {var descriptor=props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if("value" in descriptor)descriptor.writable = true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};})();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}var Invite=(function(){function Invite(data,client){_classCallCheck(this,Invite);this.max_age = data.max_age;this.code = data.code;this.server = client.getServer("id",data.guild.id);this.revoked = data.revoked;this.created_at = Date.parse(data.created_at);this.temporary = data.temporary;this.uses = data.uses;this.max_uses = data.uses;this.inviter = client.addUser(data.inviter);this.xkcd = data.xkcdpass;this.channel = client.getChannel("id",data.channel.id);}_createClass(Invite,[{key:"URL",get:function get(){var code=this.xkcd?this.xkcdpass:this.code;return "https://discord.gg/" + code;}}]);return Invite;})();module.exports = Invite;
+
+},{}],11:[function(require,module,exports){
+"use strict";var _createClass=(function(){function defineProperties(target,props){for(var i=0;i < props.length;i++) {var descriptor=props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if("value" in descriptor)descriptor.writable = true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};})();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}var PMChannel=require("./PMChannel.js");var Message=(function(){function Message(data,channel,mentions,author){_classCallCheck(this,Message);this.tts = data.tts;this.timestamp = Date.parse(data.timestamp);this.nonce = data.nonce;this.mentions = mentions;this.everyoneMentioned = data.mention_everyone;this.id = data.id;this.embeds = data.embeds;this.editedTimestamp = data.edited_timestamp;this.content = data.content.trim();this.channel = channel;if(this.isPrivate){this.author = this.channel.client.getUser("id",author.id);}else {this.author = this.channel.server.getMember("id",author.id) || this.channel.client.getUser("id",author.id);}this.attachments = data.attachments;} /*exports.Message.prototype.isPM = function() {
+ return ( this.channel instanceof PMChannel );
+}*/Message.prototype.isMentioned = function isMentioned(user){var id=user.id?user.id:user;for(var _iterator=this.mentions,_isArray=Array.isArray(_iterator),_i=0,_iterator=_isArray?_iterator:_iterator[Symbol.iterator]();;) {var _ref;if(_isArray){if(_i >= _iterator.length)break;_ref = _iterator[_i++];}else {_i = _iterator.next();if(_i.done)break;_ref = _i.value;}var mention=_ref;if(mention.id === id){return true;}}return false;};_createClass(Message,[{key:"sender",get:function get(){return this.author;}},{key:"isPrivate",get:function get(){return this.channel.isPrivate;}}]);return Message;})();module.exports = Message;
+
+},{"./PMChannel.js":6}],12:[function(require,module,exports){
+"use strict";var _createClass=(function(){function defineProperties(target,props){for(var i=0;i < props.length;i++) {var descriptor=props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if("value" in descriptor)descriptor.writable = true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};})();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}var ServerPermissions=require("./ServerPermissions.js");var Member=require("./Member.js");var Server=(function(){function Server(data,client){_classCallCheck(this,Server);this.client = client;this.region = data.region;this.ownerID = data.owner_id;this.name = data.name;this.id = data.id;this.members = [];this.channels = [];this.icon = data.icon;this.afkTimeout = data.afk_timeout;this.afkChannelId = data.afk_channel_id;this.roles = [];for(var _iterator=data.roles,_isArray=Array.isArray(_iterator),_i=0,_iterator=_isArray?_iterator:_iterator[Symbol.iterator]();;) {var _ref;if(_isArray){if(_i >= _iterator.length)break;_ref = _iterator[_i++];}else {_i = _iterator.next();if(_i.done)break;_ref = _i.value;}var permissionGroup=_ref;this.roles.push(new ServerPermissions(permissionGroup));}if(!data.members){data.members = [client.user];return;}for(var _iterator2=data.members,_isArray2=Array.isArray(_iterator2),_i2=0,_iterator2=_isArray2?_iterator2:_iterator2[Symbol.iterator]();;) {var _ref2;if(_isArray2){if(_i2 >= _iterator2.length)break;_ref2 = _iterator2[_i2++];}else {_i2 = _iterator2.next();if(_i2.done)break;_ref2 = _i2.value;}var member=_ref2; // first we cache the user in our Discord Client,
+// then we add it to our list. This way when we
+// get a user from this server's member list,
+// it will be identical (unless an async change occurred)
+// to the client's cache.
+if(member.user)this.addMember(client.addUser(member.user),member.roles);}} // get/set
+Server.prototype.getRole = function getRole(id){for(var _iterator3=this.roles,_isArray3=Array.isArray(_iterator3),_i3=0,_iterator3=_isArray3?_iterator3:_iterator3[Symbol.iterator]();;) {var _ref3;if(_isArray3){if(_i3 >= _iterator3.length)break;_ref3 = _iterator3[_i3++];}else {_i3 = _iterator3.next();if(_i3.done)break;_ref3 = _i3.value;}var role=_ref3;if(role.id === id){return role;}}return null;};Server.prototype.updateRole = function updateRole(data){var oldRole=this.getRole(data.id);if(oldRole){var index=this.roles.indexOf(oldRole);this.roles[index] = new ServerPermissions(data);return this.roles[index];}else {return false;}};Server.prototype.removeRole = function removeRole(id){for(var roleId in this.roles) {if(this.roles[roleId].id === id){this.roles.splice(roleId,1);}}for(var _iterator4=this.members,_isArray4=Array.isArray(_iterator4),_i4=0,_iterator4=_isArray4?_iterator4:_iterator4[Symbol.iterator]();;) {var _ref4;if(_isArray4){if(_i4 >= _iterator4.length)break;_ref4 = _iterator4[_i4++];}else {_i4 = _iterator4.next();if(_i4.done)break;_ref4 = _i4.value;}var member=_ref4;for(var roleId in member.rawRoles) {if(member.rawRoles[roleId] === id){member.rawRoles.splice(roleId,1);}}}};Server.prototype.getChannel = function getChannel(key,value){for(var _iterator5=this.channels,_isArray5=Array.isArray(_iterator5),_i5=0,_iterator5=_isArray5?_iterator5:_iterator5[Symbol.iterator]();;) {var _ref5;if(_isArray5){if(_i5 >= _iterator5.length)break;_ref5 = _iterator5[_i5++];}else {_i5 = _iterator5.next();if(_i5.done)break;_ref5 = _i5.value;}var channel=_ref5;if(channel[key] === value){return channel;}}return null;};Server.prototype.getMember = function getMember(key,value){for(var _iterator6=this.members,_isArray6=Array.isArray(_iterator6),_i6=0,_iterator6=_isArray6?_iterator6:_iterator6[Symbol.iterator]();;) {var _ref6;if(_isArray6){if(_i6 >= _iterator6.length)break;_ref6 = _iterator6[_i6++];}else {_i6 = _iterator6.next();if(_i6.done)break;_ref6 = _i6.value;}var member=_ref6;if(member[key] === value){return member;}}return null;};Server.prototype.removeMember = function removeMember(key,value){for(var _iterator7=this.members,_isArray7=Array.isArray(_iterator7),_i7=0,_iterator7=_isArray7?_iterator7:_iterator7[Symbol.iterator]();;) {var _ref7;if(_isArray7){if(_i7 >= _iterator7.length)break;_ref7 = _iterator7[_i7++];}else {_i7 = _iterator7.next();if(_i7.done)break;_ref7 = _i7.value;}var member=_ref7;if(member[key] === value){this.members.splice(key,1);return member;}}return false;};Server.prototype.addChannel = function addChannel(chann){if(!this.getChannel("id",chann.id)){this.channels.push(chann);}return chann;};Server.prototype.addMember = function addMember(user,roles){if(!this.getMember("id",user.id)){var mem=new Member(user,this,roles);this.members.push(mem);}return mem;};Server.prototype.toString = function toString(){return this.name;};Server.prototype.equals = function equals(object){return object.id === this.id;};_createClass(Server,[{key:"permissionGroups",get:function get(){return this.roles;}},{key:"permissions",get:function get(){return this.roles;}},{key:"iconURL",get:function get(){if(!this.icon)return null;return "https://discordapp.com/api/guilds/" + this.id + "/icons/" + this.icon + ".jpg";}},{key:"afkChannel",get:function get(){if(!this.afkChannelId)return false;return this.getChannel("id",this.afkChannelId);}},{key:"defaultChannel",get:function get(){return this.getChannel("name","general");}},{key:"owner",get:function get(){return this.client.getUser("id",this.ownerID);}},{key:"users",get:function get(){return this.members;}}]);return Server;})();module.exports = Server;
+
+},{"./Member.js":5,"./ServerPermissions.js":7}],13:[function(require,module,exports){
+"use strict";var _createClass=(function(){function defineProperties(target,props){for(var i=0;i < props.length;i++) {var descriptor=props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if("value" in descriptor)descriptor.writable = true;Object.defineProperty(target,descriptor.key,descriptor);}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor;};})();function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}var User=(function(){function User(data){_classCallCheck(this,User);this.username = data.username;this.discriminator = data.discriminator;this.id = data.id;this.avatar = data.avatar;this.status = data.status || "offline";this.gameId = data.game_id || null;} // access using user.avatarURL;
+User.prototype.mention = function mention(){return "<@" + this.id + ">";};User.prototype.toString = function toString(){ /*
+ if we embed a user in a String - like so:
+ "Yo " + user + " what's up?"
+ It would generate something along the lines of:
+ "Yo @hydrabolt what's up?"
+ */return this.mention();};User.prototype.equals = function equals(object){return object.id === this.id;};User.prototype.equalsStrict = function equalsStrict(object){return object.id === this.id && object.avatar === this.avatar && object.username === this.username && object.discriminator === this.discriminator;};_createClass(User,[{key:"avatarURL",get:function get(){if(!this.avatar)return null;return "https://discordapp.com/api/users/" + this.id + "/avatars/" + this.avatar + ".jpg";}}]);return User;})();module.exports = User;
+
+},{}],14:[function(require,module,exports){
+
+},{}],15:[function(require,module,exports){
+/**
+ * Module dependencies.
+ */
+
+var Emitter = require('emitter');
+var reduce = require('reduce');
+
+/**
+ * Root reference for iframes.
+ */
+
+var root;
+if (typeof window !== 'undefined') { // Browser window
+ root = window;
+} else if (typeof self !== 'undefined') { // Web Worker
+ root = self;
+} else { // Other environments
+ root = this;
+}
+
+/**
+ * Noop.
+ */
+
+function noop(){};
+
+/**
+ * Check if `obj` is a host object,
+ * we don't want to serialize these :)
+ *
+ * TODO: future proof, move to compoent land
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api private
+ */
+
+function isHost(obj) {
+ var str = {}.toString.call(obj);
+
+ switch (str) {
+ case '[object File]':
+ case '[object Blob]':
+ case '[object FormData]':
+ return true;
+ default:
+ return false;
+ }
+}
+
+/**
+ * Determine XHR.
+ */
+
+request.getXHR = function () {
+ if (root.XMLHttpRequest
+ && (!root.location || 'file:' != root.location.protocol
+ || !root.ActiveXObject)) {
+ return new XMLHttpRequest;
+ } else {
+ try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}
+ try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
+ }
+ return false;
+};
+
+/**
+ * Removes leading and trailing whitespace, added to support IE.
+ *
+ * @param {String} s
+ * @return {String}
+ * @api private
+ */
+
+var trim = ''.trim
+ ? function(s) { return s.trim(); }
+ : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); };
+
+/**
+ * Check if `obj` is an object.
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api private
+ */
+
+function isObject(obj) {
+ return obj === Object(obj);
+}
+
+/**
+ * Serialize the given `obj`.
+ *
+ * @param {Object} obj
+ * @return {String}
+ * @api private
+ */
+
+function serialize(obj) {
+ if (!isObject(obj)) return obj;
+ var pairs = [];
+ for (var key in obj) {
+ if (null != obj[key]) {
+ pairs.push(encodeURIComponent(key)
+ + '=' + encodeURIComponent(obj[key]));
+ }
+ }
+ return pairs.join('&');
+}
+
+/**
+ * Expose serialization method.
+ */
+
+ request.serializeObject = serialize;
+
+ /**
+ * Parse the given x-www-form-urlencoded `str`.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function parseString(str) {
+ var obj = {};
+ var pairs = str.split('&');
+ var parts;
+ var pair;
+
+ for (var i = 0, len = pairs.length; i < len; ++i) {
+ pair = pairs[i];
+ parts = pair.split('=');
+ obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
+ }
+
+ return obj;
+}
+
+/**
+ * Expose parser.
+ */
+
+request.parseString = parseString;
+
+/**
+ * Default MIME type map.
+ *
+ * superagent.types.xml = 'application/xml';
+ *
+ */
+
+request.types = {
+ html: 'text/html',
+ json: 'application/json',
+ xml: 'application/xml',
+ urlencoded: 'application/x-www-form-urlencoded',
+ 'form': 'application/x-www-form-urlencoded',
+ 'form-data': 'application/x-www-form-urlencoded'
+};
+
+/**
+ * Default serialization map.
+ *
+ * superagent.serialize['application/xml'] = function(obj){
+ * return 'generated xml here';
+ * };
+ *
+ */
+
+ request.serialize = {
+ 'application/x-www-form-urlencoded': serialize,
+ 'application/json': JSON.stringify
+ };
+
+ /**
+ * Default parsers.
+ *
+ * superagent.parse['application/xml'] = function(str){
+ * return { object parsed from str };
+ * };
+ *
+ */
+
+request.parse = {
+ 'application/x-www-form-urlencoded': parseString,
+ 'application/json': JSON.parse
+};
+
+/**
+ * Parse the given header `str` into
+ * an object containing the mapped fields.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function parseHeader(str) {
+ var lines = str.split(/\r?\n/);
+ var fields = {};
+ var index;
+ var line;
+ var field;
+ var val;
+
+ lines.pop(); // trailing CRLF
+
+ for (var i = 0, len = lines.length; i < len; ++i) {
+ line = lines[i];
+ index = line.indexOf(':');
+ field = line.slice(0, index).toLowerCase();
+ val = trim(line.slice(index + 1));
+ fields[field] = val;
+ }
+
+ return fields;
+}
+
+/**
+ * Return the mime type for the given `str`.
+ *
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+function type(str){
+ return str.split(/ *; */).shift();
+};
+
+/**
+ * Return header field parameters.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function params(str){
+ return reduce(str.split(/ *; */), function(obj, str){
+ var parts = str.split(/ *= */)
+ , key = parts.shift()
+ , val = parts.shift();
+
+ if (key && val) obj[key] = val;
+ return obj;
+ }, {});
+};
+
+/**
+ * Initialize a new `Response` with the given `xhr`.
+ *
+ * - set flags (.ok, .error, etc)
+ * - parse header
+ *
+ * Examples:
+ *
+ * Aliasing `superagent` as `request` is nice:
+ *
+ * request = superagent;
+ *
+ * We can use the promise-like API, or pass callbacks:
+ *
+ * request.get('/').end(function(res){});
+ * request.get('/', function(res){});
+ *
+ * Sending data can be chained:
+ *
+ * request
+ * .post('/user')
+ * .send({ name: 'tj' })
+ * .end(function(res){});
+ *
+ * Or passed to `.send()`:
+ *
+ * request
+ * .post('/user')
+ * .send({ name: 'tj' }, function(res){});
+ *
+ * Or passed to `.post()`:
+ *
+ * request
+ * .post('/user', { name: 'tj' })
+ * .end(function(res){});
+ *
+ * Or further reduced to a single call for simple cases:
+ *
+ * request
+ * .post('/user', { name: 'tj' }, function(res){});
+ *
+ * @param {XMLHTTPRequest} xhr
+ * @param {Object} options
+ * @api private
+ */
+
+function Response(req, options) {
+ options = options || {};
+ this.req = req;
+ this.xhr = this.req.xhr;
+ // responseText is accessible only if responseType is '' or 'text' and on older browsers
+ this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined')
+ ? this.xhr.responseText
+ : null;
+ this.statusText = this.req.xhr.statusText;
+ this.setStatusProperties(this.xhr.status);
+ this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders());
+ // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but
+ // getResponseHeader still works. so we get content-type even if getting
+ // other headers fails.
+ this.header['content-type'] = this.xhr.getResponseHeader('content-type');
+ this.setHeaderProperties(this.header);
+ this.body = this.req.method != 'HEAD'
+ ? this.parseBody(this.text ? this.text : this.xhr.response)
+ : null;
+}
+
+/**
+ * Get case-insensitive `field` value.
+ *
+ * @param {String} field
+ * @return {String}
+ * @api public
+ */
+
+Response.prototype.get = function(field){
+ return this.header[field.toLowerCase()];
+};
+
+/**
+ * Set header related properties:
+ *
+ * - `.type` the content type without params
+ *
+ * A response of "Content-Type: text/plain; charset=utf-8"
+ * will provide you with a `.type` of "text/plain".
+ *
+ * @param {Object} header
+ * @api private
+ */
+
+Response.prototype.setHeaderProperties = function(header){
+ // content-type
+ var ct = this.header['content-type'] || '';
+ this.type = type(ct);
+
+ // params
+ var obj = params(ct);
+ for (var key in obj) this[key] = obj[key];
+};
+
+/**
+ * Force given parser
+ *
+ * Sets the body parser no matter type.
+ *
+ * @param {Function}
+ * @api public
+ */
+
+Response.prototype.parse = function(fn){
+ this.parser = fn;
+ return this;
+};
+
+/**
+ * Parse the given body `str`.
+ *
+ * Used for auto-parsing of bodies. Parsers
+ * are defined on the `superagent.parse` object.
+ *
+ * @param {String} str
+ * @return {Mixed}
+ * @api private
+ */
+
+Response.prototype.parseBody = function(str){
+ var parse = this.parser || request.parse[this.type];
+ return parse && str && (str.length || str instanceof Object)
+ ? parse(str)
+ : null;
+};
+
+/**
+ * Set flags such as `.ok` based on `status`.
+ *
+ * For example a 2xx response will give you a `.ok` of __true__
+ * whereas 5xx will be __false__ and `.error` will be __true__. The
+ * `.clientError` and `.serverError` are also available to be more
+ * specific, and `.statusType` is the class of error ranging from 1..5
+ * sometimes useful for mapping respond colors etc.
+ *
+ * "sugar" properties are also defined for common cases. Currently providing:
+ *
+ * - .noContent
+ * - .badRequest
+ * - .unauthorized
+ * - .notAcceptable
+ * - .notFound
+ *
+ * @param {Number} status
+ * @api private
+ */
+
+Response.prototype.setStatusProperties = function(status){
+ // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
+ if (status === 1223) {
+ status = 204;
+ }
+
+ var type = status / 100 | 0;
+
+ // status / class
+ this.status = this.statusCode = status;
+ this.statusType = type;
+
+ // basics
+ this.info = 1 == type;
+ this.ok = 2 == type;
+ this.clientError = 4 == type;
+ this.serverError = 5 == type;
+ this.error = (4 == type || 5 == type)
+ ? this.toError()
+ : false;
+
+ // sugar
+ this.accepted = 202 == status;
+ this.noContent = 204 == status;
+ this.badRequest = 400 == status;
+ this.unauthorized = 401 == status;
+ this.notAcceptable = 406 == status;
+ this.notFound = 404 == status;
+ this.forbidden = 403 == status;
+};
+
+/**
+ * Return an `Error` representative of this response.
+ *
+ * @return {Error}
+ * @api public
+ */
+
+Response.prototype.toError = function(){
+ var req = this.req;
+ var method = req.method;
+ var url = req.url;
+
+ var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')';
+ var err = new Error(msg);
+ err.status = this.status;
+ err.method = method;
+ err.url = url;
+
+ return err;
+};
+
+/**
+ * Expose `Response`.
+ */
+
+request.Response = Response;
+
+/**
+ * Initialize a new `Request` with the given `method` and `url`.
+ *
+ * @param {String} method
+ * @param {String} url
+ * @api public
+ */
+
+function Request(method, url) {
+ var self = this;
+ Emitter.call(this);
+ this._query = this._query || [];
+ this.method = method;
+ this.url = url;
+ this.header = {};
+ this._header = {};
+ this.on('end', function(){
+ var err = null;
+ var res = null;
+
+ try {
+ res = new Response(self);
+ } catch(e) {
+ err = new Error('Parser is unable to parse the response');
+ err.parse = true;
+ err.original = e;
+ return self.callback(err);
+ }
+
+ self.emit('response', res);
+
+ if (err) {
+ return self.callback(err, res);
+ }
+
+ if (res.status >= 200 && res.status < 300) {
+ return self.callback(err, res);
+ }
+
+ var new_err = new Error(res.statusText || 'Unsuccessful HTTP response');
+ new_err.original = err;
+ new_err.response = res;
+ new_err.status = res.status;
+
+ self.callback(new_err, res);
+ });
+}
+
+/**
+ * Mixin `Emitter`.
+ */
+
+Emitter(Request.prototype);
+
+/**
+ * Allow for extension
+ */
+
+Request.prototype.use = function(fn) {
+ fn(this);
+ return this;
+}
+
+/**
+ * Set timeout to `ms`.
+ *
+ * @param {Number} ms
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.timeout = function(ms){
+ this._timeout = ms;
+ return this;
+};
+
+/**
+ * Clear previous timeout.
+ *
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.clearTimeout = function(){
+ this._timeout = 0;
+ clearTimeout(this._timer);
+ return this;
+};
+
+/**
+ * Abort the request, and clear potential timeout.
+ *
+ * @return {Request}
+ * @api public
+ */
+
+Request.prototype.abort = function(){
+ if (this.aborted) return;
+ this.aborted = true;
+ this.xhr.abort();
+ this.clearTimeout();
+ this.emit('abort');
+ return this;
+};
+
+/**
+ * Set header `field` to `val`, or multiple fields with one object.
+ *
+ * Examples:
+ *
+ * req.get('/')
+ * .set('Accept', 'application/json')
+ * .set('X-API-Key', 'foobar')
+ * .end(callback);
+ *
+ * req.get('/')
+ * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
+ * .end(callback);
+ *
+ * @param {String|Object} field
+ * @param {String} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.set = function(field, val){
+ if (isObject(field)) {
+ for (var key in field) {
+ this.set(key, field[key]);
+ }
+ return this;
+ }
+ this._header[field.toLowerCase()] = val;
+ this.header[field] = val;
+ return this;
+};
+
+/**
+ * Remove header `field`.
+ *
+ * Example:
+ *
+ * req.get('/')
+ * .unset('User-Agent')
+ * .end(callback);
+ *
+ * @param {String} field
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.unset = function(field){
+ delete this._header[field.toLowerCase()];
+ delete this.header[field];
+ return this;
+};
+
+/**
+ * Get case-insensitive header `field` value.
+ *
+ * @param {String} field
+ * @return {String}
+ * @api private
+ */
+
+Request.prototype.getHeader = function(field){
+ return this._header[field.toLowerCase()];
+};
+
+/**
+ * Set Content-Type to `type`, mapping values from `request.types`.
+ *
+ * Examples:
+ *
+ * superagent.types.xml = 'application/xml';
+ *
+ * request.post('/')
+ * .type('xml')
+ * .send(xmlstring)
+ * .end(callback);
+ *
+ * request.post('/')
+ * .type('application/xml')
+ * .send(xmlstring)
+ * .end(callback);
+ *
+ * @param {String} type
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.type = function(type){
+ this.set('Content-Type', request.types[type] || type);
+ return this;
+};
+
+/**
+ * Set Accept to `type`, mapping values from `request.types`.
+ *
+ * Examples:
+ *
+ * superagent.types.json = 'application/json';
+ *
+ * request.get('/agent')
+ * .accept('json')
+ * .end(callback);
+ *
+ * request.get('/agent')
+ * .accept('application/json')
+ * .end(callback);
+ *
+ * @param {String} accept
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.accept = function(type){
+ this.set('Accept', request.types[type] || type);
+ return this;
+};
+
+/**
+ * Set Authorization field value with `user` and `pass`.
+ *
+ * @param {String} user
+ * @param {String} pass
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.auth = function(user, pass){
+ var str = btoa(user + ':' + pass);
+ this.set('Authorization', 'Basic ' + str);
+ return this;
+};
+
+/**
+* Add query-string `val`.
+*
+* Examples:
+*
+* request.get('/shoes')
+* .query('size=10')
+* .query({ color: 'blue' })
+*
+* @param {Object|String} val
+* @return {Request} for chaining
+* @api public
+*/
+
+Request.prototype.query = function(val){
+ if ('string' != typeof val) val = serialize(val);
+ if (val) this._query.push(val);
+ return this;
+};
+
+/**
+ * Write the field `name` and `val` for "multipart/form-data"
+ * request bodies.
+ *
+ * ``` js
+ * request.post('/upload')
+ * .field('foo', 'bar')
+ * .end(callback);
+ * ```
+ *
+ * @param {String} name
+ * @param {String|Blob|File} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.field = function(name, val){
+ if (!this._formData) this._formData = new root.FormData();
+ this._formData.append(name, val);
+ return this;
+};
+
+/**
+ * Queue the given `file` as an attachment to the specified `field`,
+ * with optional `filename`.
+ *
+ * ``` js
+ * request.post('/upload')
+ * .attach(new Blob(['hey!'], { type: "text/html"}))
+ * .end(callback);
+ * ```
+ *
+ * @param {String} field
+ * @param {Blob|File} file
+ * @param {String} filename
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.attach = function(field, file, filename){
+ if (!this._formData) this._formData = new root.FormData();
+ this._formData.append(field, file, filename);
+ return this;
+};
+
+/**
+ * Send `data`, defaulting the `.type()` to "json" when
+ * an object is given.
+ *
+ * Examples:
+ *
+ * // querystring
+ * request.get('/search')
+ * .end(callback)
+ *
+ * // multiple data "writes"
+ * request.get('/search')
+ * .send({ search: 'query' })
+ * .send({ range: '1..5' })
+ * .send({ order: 'desc' })
+ * .end(callback)
+ *
+ * // manual json
+ * request.post('/user')
+ * .type('json')
+ * .send('{"name":"tj"})
+ * .end(callback)
+ *
+ * // auto json
+ * request.post('/user')
+ * .send({ name: 'tj' })
+ * .end(callback)
+ *
+ * // manual x-www-form-urlencoded
+ * request.post('/user')
+ * .type('form')
+ * .send('name=tj')
+ * .end(callback)
+ *
+ * // auto x-www-form-urlencoded
+ * request.post('/user')
+ * .type('form')
+ * .send({ name: 'tj' })
+ * .end(callback)
+ *
+ * // defaults to x-www-form-urlencoded
+ * request.post('/user')
+ * .send('name=tobi')
+ * .send('species=ferret')
+ * .end(callback)
+ *
+ * @param {String|Object} data
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.send = function(data){
+ var obj = isObject(data);
+ var type = this.getHeader('Content-Type');
+
+ // merge
+ if (obj && isObject(this._data)) {
+ for (var key in data) {
+ this._data[key] = data[key];
+ }
+ } else if ('string' == typeof data) {
+ if (!type) this.type('form');
+ type = this.getHeader('Content-Type');
+ if ('application/x-www-form-urlencoded' == type) {
+ this._data = this._data
+ ? this._data + '&' + data
+ : data;
+ } else {
+ this._data = (this._data || '') + data;
+ }
+ } else {
+ this._data = data;
+ }
+
+ if (!obj || isHost(data)) return this;
+ if (!type) this.type('json');
+ return this;
+};
+
+/**
+ * Invoke the callback with `err` and `res`
+ * and handle arity check.
+ *
+ * @param {Error} err
+ * @param {Response} res
+ * @api private
+ */
+
+Request.prototype.callback = function(err, res){
+ var fn = this._callback;
+ this.clearTimeout();
+ fn(err, res);
+};
+
+/**
+ * Invoke callback with x-domain error.
+ *
+ * @api private
+ */
+
+Request.prototype.crossDomainError = function(){
+ var err = new Error('Origin is not allowed by Access-Control-Allow-Origin');
+ err.crossDomain = true;
+ this.callback(err);
+};
+
+/**
+ * Invoke callback with timeout error.
+ *
+ * @api private
+ */
+
+Request.prototype.timeoutError = function(){
+ var timeout = this._timeout;
+ var err = new Error('timeout of ' + timeout + 'ms exceeded');
+ err.timeout = timeout;
+ this.callback(err);
+};
+
+/**
+ * Enable transmission of cookies with x-domain requests.
+ *
+ * Note that for this to work the origin must not be
+ * using "Access-Control-Allow-Origin" with a wildcard,
+ * and also must set "Access-Control-Allow-Credentials"
+ * to "true".
+ *
+ * @api public
+ */
+
+Request.prototype.withCredentials = function(){
+ this._withCredentials = true;
+ return this;
+};
+
+/**
+ * Initiate request, invoking callback `fn(res)`
+ * with an instanceof `Response`.
+ *
+ * @param {Function} fn
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.end = function(fn){
+ var self = this;
+ var xhr = this.xhr = request.getXHR();
+ var query = this._query.join('&');
+ var timeout = this._timeout;
+ var data = this._formData || this._data;
+
+ // store callback
+ this._callback = fn || noop;
+
+ // state change
+ xhr.onreadystatechange = function(){
+ if (4 != xhr.readyState) return;
+
+ // In IE9, reads to any property (e.g. status) off of an aborted XHR will
+ // result in the error "Could not complete the operation due to error c00c023f"
+ var status;
+ try { status = xhr.status } catch(e) { status = 0; }
+
+ if (0 == status) {
+ if (self.timedout) return self.timeoutError();
+ if (self.aborted) return;
+ return self.crossDomainError();
+ }
+ self.emit('end');
+ };
+
+ // progress
+ var handleProgress = function(e){
+ if (e.total > 0) {
+ e.percent = e.loaded / e.total * 100;
+ }
+ self.emit('progress', e);
+ };
+ if (this.hasListeners('progress')) {
+ xhr.onprogress = handleProgress;
+ }
+ try {
+ if (xhr.upload && this.hasListeners('progress')) {
+ xhr.upload.onprogress = handleProgress;
+ }
+ } catch(e) {
+ // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist.
+ // Reported here:
+ // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context
+ }
+
+ // timeout
+ if (timeout && !this._timer) {
+ this._timer = setTimeout(function(){
+ self.timedout = true;
+ self.abort();
+ }, timeout);
+ }
+
+ // querystring
+ if (query) {
+ query = request.serializeObject(query);
+ this.url += ~this.url.indexOf('?')
+ ? '&' + query
+ : '?' + query;
+ }
+
+ // initiate request
+ xhr.open(this.method, this.url, true);
+
+ // CORS
+ if (this._withCredentials) xhr.withCredentials = true;
+
+ // body
+ if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) {
+ // serialize stuff
+ var contentType = this.getHeader('Content-Type');
+ var serialize = request.serialize[contentType ? contentType.split(';')[0] : ''];
+ if (serialize) data = serialize(data);
+ }
+
+ // set header fields
+ for (var field in this.header) {
+ if (null == this.header[field]) continue;
+ xhr.setRequestHeader(field, this.header[field]);
+ }
+
+ // send stuff
+ this.emit('request', this);
+ xhr.send(data);
+ return this;
+};
+
+/**
+ * Faux promise support
+ *
+ * @param {Function} fulfill
+ * @param {Function} reject
+ * @return {Request}
+ */
+
+Request.prototype.then = function (fulfill, reject) {
+ return this.end(function(err, res) {
+ err ? reject(err) : fulfill(res);
+ });
+}
+
+/**
+ * Expose `Request`.
+ */
+
+request.Request = Request;
+
+/**
+ * Issue a request:
+ *
+ * Examples:
+ *
+ * request('GET', '/users').end(callback)
+ * request('/users').end(callback)
+ * request('/users', callback)
+ *
+ * @param {String} method
+ * @param {String|Function} url or callback
+ * @return {Request}
+ * @api public
+ */
+
+function request(method, url) {
+ // callback
+ if ('function' == typeof url) {
+ return new Request('GET', method).end(url);
+ }
+
+ // url first
+ if (1 == arguments.length) {
+ return new Request('GET', method);
+ }
+
+ return new Request(method, url);
+}
+
+/**
+ * GET `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.get = function(url, data, fn){
+ var req = request('GET', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.query(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * HEAD `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.head = function(url, data, fn){
+ var req = request('HEAD', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * DELETE `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.del = function(url, fn){
+ var req = request('DELETE', url);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * PATCH `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} data
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.patch = function(url, data, fn){
+ var req = request('PATCH', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * POST `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} data
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.post = function(url, data, fn){
+ var req = request('POST', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * PUT `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.put = function(url, data, fn){
+ var req = request('PUT', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * Expose `request`.
+ */
+
+module.exports = request;
+
+},{"emitter":16,"reduce":17}],16:[function(require,module,exports){
+
+/**
+ * Expose `Emitter`.
+ */
+
+module.exports = Emitter;
+
+/**
+ * Initialize a new `Emitter`.
+ *
+ * @api public
+ */
+
+function Emitter(obj) {
+ if (obj) return mixin(obj);
+};
+
+/**
+ * Mixin the emitter properties.
+ *
+ * @param {Object} obj
+ * @return {Object}
+ * @api private
+ */
+
+function mixin(obj) {
+ for (var key in Emitter.prototype) {
+ obj[key] = Emitter.prototype[key];
+ }
+ return obj;
+}
+
+/**
+ * Listen on the given `event` with `fn`.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.on =
+Emitter.prototype.addEventListener = function(event, fn){
+ this._callbacks = this._callbacks || {};
+ (this._callbacks[event] = this._callbacks[event] || [])
+ .push(fn);
+ return this;
+};
+
+/**
+ * Adds an `event` listener that will be invoked a single
+ * time then automatically removed.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.once = function(event, fn){
+ var self = this;
+ this._callbacks = this._callbacks || {};
+
+ function on() {
+ self.off(event, on);
+ fn.apply(this, arguments);
+ }
+
+ on.fn = fn;
+ this.on(event, on);
+ return this;
+};
+
+/**
+ * Remove the given callback for `event` or all
+ * registered callbacks.
+ *
+ * @param {String} event
+ * @param {Function} fn
+ * @return {Emitter}
+ * @api public
+ */
+
+Emitter.prototype.off =
+Emitter.prototype.removeListener =
+Emitter.prototype.removeAllListeners =
+Emitter.prototype.removeEventListener = function(event, fn){
+ this._callbacks = this._callbacks || {};
+
+ // all
+ if (0 == arguments.length) {
+ this._callbacks = {};
+ return this;
+ }
+
+ // specific event
+ var callbacks = this._callbacks[event];
+ if (!callbacks) return this;
+
+ // remove all handlers
+ if (1 == arguments.length) {
+ delete this._callbacks[event];
+ return this;
+ }
+
+ // remove specific handler
+ var cb;
+ for (var i = 0; i < callbacks.length; i++) {
+ cb = callbacks[i];
+ if (cb === fn || cb.fn === fn) {
+ callbacks.splice(i, 1);
+ break;
+ }
+ }
+ return this;
+};
+
+/**
+ * Emit `event` with the given args.
+ *
+ * @param {String} event
+ * @param {Mixed} ...
+ * @return {Emitter}
+ */
+
+Emitter.prototype.emit = function(event){
+ this._callbacks = this._callbacks || {};
+ var args = [].slice.call(arguments, 1)
+ , callbacks = this._callbacks[event];
+
+ if (callbacks) {
+ callbacks = callbacks.slice(0);
+ for (var i = 0, len = callbacks.length; i < len; ++i) {
+ callbacks[i].apply(this, args);
+ }
+ }
+
+ return this;
+};
+
+/**
+ * Return array of callbacks for `event`.
+ *
+ * @param {String} event
+ * @return {Array}
+ * @api public
+ */
+
+Emitter.prototype.listeners = function(event){
+ this._callbacks = this._callbacks || {};
+ return this._callbacks[event] || [];
+};
+
+/**
+ * Check if this emitter has `event` handlers.
+ *
+ * @param {String} event
+ * @return {Boolean}
+ * @api public
+ */
+
+Emitter.prototype.hasListeners = function(event){
+ return !! this.listeners(event).length;
+};
+
+},{}],17:[function(require,module,exports){
+
+/**
+ * Reduce `arr` with `fn`.
+ *
+ * @param {Array} arr
+ * @param {Function} fn
+ * @param {Mixed} initial
+ *
+ * TODO: combatible error handling?
+ */
+
+module.exports = function(arr, fn, initial){
+ var idx = 0;
+ var len = arr.length;
+ var curr = arguments.length == 3
+ ? initial
+ : arr[idx++];
+
+ while (idx < len) {
+ curr = fn.call(null, curr, arr[idx], ++idx, arr);
+ }
+
+ return curr;
+};
+},{}],18:[function(require,module,exports){
+
+/**
+ * Module dependencies.
+ */
+
+var global = (function() { return this; })();
+
+/**
+ * WebSocket constructor.
+ */
+
+var WebSocket = global.WebSocket || global.MozWebSocket;
+
+/**
+ * Module exports.
+ */
+
+module.exports = WebSocket ? ws : null;
+
+/**
+ * WebSocket constructor.
+ *
+ * The third `opts` options object gets ignored in web browsers, since it's
+ * non-standard, and throws a TypeError if passed to the constructor.
+ * See: https://github.com/einaros/ws/issues/227
+ *
+ * @param {String} uri
+ * @param {Array} protocols (optional)
+ * @param {Object) opts (optional)
+ * @api public
+ */
+
+function ws(uri, protocols, opts) {
+ var instance;
+ if (protocols) {
+ instance = new WebSocket(uri, protocols);
+ } else {
+ instance = new WebSocket(uri);
+ }
+ return instance;
+}
+
+if (WebSocket) ws.prototype = WebSocket.prototype;
+
+},{}],19:[function(require,module,exports){
+module.exports=[{"executables":{"win32":["pol.exe"]},"id":0,"name":"FINAL FANTASY XI"},{"executables":{"win32":["ffxiv.exe","ffxiv_dx11.exe"]},"id":1,"name":"FINAL FANTASY XIV"},{"executables":{"win32":["Wow.exe","Wow-64.exe"]},"id":3,"name":"World of Warcraft"},{"executables":{"darwin":["LoLLauncher.app"],"win32":["LolClient.exe","League of Legends.exe"]},"id":4,"name":"League of Legends"},{"executables":{"darwin":["Diablo%20III.app"],"win32":["Diablo III.exe"]},"id":5,"name":"Diablo 3"},{"executables":{"darwin":["dota_osx.app"],"win32":["dota2.exe"]},"id":6,"name":"DOTA 2"},{"executables":{"darwin":["Heroes.app"],"win32":["Heroes of the Storm.exe","HeroesOfTheStorm_x64.exe","HeroesOfTheStorm.exe"]},"id":7,"name":"Heroes of the Storm"},{"executables":{"darwin":["Hearthstone.app"],"win32":["Hearthstone.exe"]},"id":8,"name":"Hearthstone"},{"executables":{"win32":["csgo.exe"]},"id":9,"name":"Counter-Strike: Global Offensive"},{"executables":{"win32":["WorldOfTanks.exe"]},"id":10,"name":"World of Tanks"},{"executables":{"darwin":["gw2.app"],"win32":["gw2.exe"]},"id":11,"name":"Guild Wars 2"},{"executables":{"win32":["dayz.exe"]},"id":12,"name":"Day Z"},{"executables":{"darwin":["starcraft%20ii.app"],"win32":["starcraft ii.exe","SC2_x64.exe","SC2.exe"]},"id":13,"name":"Starcraft II"},{"executables":{"win32":["diablo.exe"]},"id":14,"name":"Diablo"},{"executables":{"win32":["diablo ii.exe"]},"id":15,"name":"Diablo 2"},{"executables":{"win32":["left4dead.exe"]},"id":17,"name":"Left 4 Dead"},{"executables":{"darwin":["minecraft.app"],"win32":["minecraft.exe"]},"id":18,"name":"Minecraft"},{"executables":{"win32":["smite.exe"]},"id":19,"name":"Smite"},{"executables":{"win32":["bf4.exe"]},"id":20,"name":"Battlefield 4"},{"executables":{"win32":["AoK HD.exe","empires2.exe"]},"id":101,"name":"Age of Empire II"},{"executables":{"win32":["age3y.exe"]},"id":102,"name":"Age of Empire III"},{"executables":{"win32":["AlanWake.exe"]},"id":104,"name":"Alan Wake"},{"executables":{"win32":["alan_wakes_american_nightmare.exe"]},"id":105,"name":"Alan Wake's American Nightmare"},{"executables":{"win32":["AlienBreed2Assault.exe"]},"id":106,"name":"Alien Breed 2: Assault"},{"executables":{"win32":["Amnesia.exe"]},"id":107,"name":"Amnesia: The Dark Descent"},{"executables":{"win32":["UDK.exe"]},"id":108,"name":"Antichamber"},{"executables":{"win32":["ArcheAge.exe"]},"id":109,"name":"ArcheAge"},{"executables":{"win32":["arma3.exe"]},"id":110,"name":"Arma III"},{"executables":{"win32":["AC3SP.exe"]},"id":111,"name":"Assassin's Creed 3"},{"executables":{"win32":["Bastion.exe"]},"id":112,"name":"Bastion"},{"executables":{"win32":["BF2.exe"]},"id":113,"name":"Battlefield 2"},{"executables":{"win32":["bf3.exe"]},"id":114,"name":"Battlefield 3"},{"executables":{"win32":["Besiege.exe"]},"id":116,"name":"Besiege"},{"executables":{"win32":["Bioshock.exe"]},"id":117,"name":"Bioshock"},{"executables":{"win32":["Bioshock2.exe"]},"id":118,"name":"BioShock II"},{"executables":{"win32":["BioShockInfinite.exe"]},"id":119,"name":"BioShock Infinite"},{"executables":{"win32":["Borderlands2.exe"]},"id":122,"name":"Borderlands 2"},{"executables":{"win32":["braid.exe"]},"id":123,"name":"Braid"},{"executables":{"win32":["ShippingPC-StormGame.exe"]},"id":124,"name":"Bulletstorm"},{"executables":{},"id":125,"name":"Cabal 2"},{"executables":{"win32":["CabalMain.exe"]},"id":126,"name":"Cabal Online"},{"executables":{"win32":["iw4mp.exe","iw4sp.exe"]},"id":127,"name":"Call of Duty: Modern Warfare 2"},{"executables":{"win32":["t6sp.exe"]},"id":128,"name":"Call of Duty: Black Ops"},{"executables":{"win32":["iw5mp.exe"]},"id":129,"name":"Call of Duty: Modern Warfare 3"},{"executables":{"win32":["RelicCOH.exe"]},"id":132,"name":"Company of Heroes"},{"executables":{"win32":["Crysis64.exe"]},"id":135,"name":"Crysis"},{"executables":{"win32":["Crysis2.exe"]},"id":136,"name":"Crysis 2"},{"executables":{"win32":["Crysis3.exe"]},"id":137,"name":"Crysis 3"},{"executables":{"win32":["Crysis.exe"]},"id":138,"name":"Crysis 4 "},{"executables":{"win32":["DATA.exe"]},"id":140,"name":"Dark Souls"},{"executables":{"win32":["DarkSoulsII.exe"]},"id":141,"name":"Dark Souls II"},{"executables":{"win32":["dfuw.exe"]},"id":142,"name":"Darkfall: Unholy Wars"},{"executables":{"win32":["DCGAME.exe"]},"id":144,"name":"DC Universe Online"},{"executables":{"win32":["DeadIslandGame.exe"]},"id":145,"name":"Dead Island"},{"executables":{"win32":["deadspace2.exe"]},"id":146,"name":"Dead Space 2"},{"executables":{"win32":["LOTDGame.exe"]},"id":147,"name":"Deadlight"},{"executables":{"win32":["dxhr.exe"]},"id":148,"name":"Deus Ex: Human Revolution"},{"executables":{"win32":["DeviMayCry4.exe"]},"id":149,"name":"Devil May Cry 4"},{"executables":{"win32":["DMC-DevilMayCry.exe"]},"id":150,"name":"DmC Devil May Cry"},{"executables":{"win32":["dirt2_game.exe"]},"id":154,"name":"DiRT 2"},{"executables":{"win32":["dirt3_game.exe"]},"id":155,"name":"DiRT 3"},{"executables":{"win32":["dota.exe"]},"id":156,"name":"DOTA"},{"executables":{"win32":["DoubleDragon.exe"]},"id":158,"name":"Double Dragon Neon"},{"executables":{"win32":["DragonAge2.exe"]},"id":159,"name":"Dragon Age II"},{"executables":{"win32":["DragonAgeInquisition.exe"]},"id":160,"name":"Dragon Age: Inquisition"},{"executables":{"win32":["daorigins.exe"]},"id":161,"name":"Dragon Age: Origins"},{"executables":{"win32":["DBXV.exe"]},"id":162,"name":"Dragon Ball XenoVerse"},{"executables":{"win32":["DukeForever.exe"]},"id":163,"name":"Duke Nukem Forever"},{"executables":{"darwin":["Dustforce.app"],"win32":["dustforce.exe"]},"id":164,"name":"Dustforce"},{"executables":{"win32":["EliteDangerous32.exe"]},"id":165,"name":"Elite: Dangerous"},{"executables":{"win32":["exefile.exe"]},"id":166,"name":"Eve Online"},{"executables":{"win32":["eqgame.exe"]},"id":167,"name":"EverQuest"},{"executables":{"win32":["EverQuest2.exe"]},"id":168,"name":"EverQuest II"},{"executables":{},"id":169,"name":"EverQuest Next"},{"executables":{"win32":["Engine.exe"]},"id":170,"name":"F.E.A.R."},{"executables":{"win32":["FEAR2.exe"]},"id":171,"name":"F.E.A.R. 2: Project Origin"},{"executables":{"win32":["fallout3.exe"]},"id":172,"name":"Fallout 3"},{"executables":{"win32":["FalloutNV.exe"]},"id":174,"name":"Fallout: New Vegas"},{"executables":{"win32":["farcry3.exe"]},"id":175,"name":"Far Cry 3"},{"executables":{"win32":["fifa15.exe"]},"id":176,"name":"FIFA 15"},{"executables":{"win32":["FTLGame.exe"]},"id":180,"name":"FTL: Faster Than Light"},{"executables":{"win32":["GTAIV.exe"]},"id":181,"name":"Grand Theft Auto 4"},{"executables":{"win32":["GTA5.exe"]},"id":182,"name":"Grand Theft Auto 5"},{"executables":{"win32":["Gw.exe"]},"id":183,"name":"Guild Wars"},{"executables":{"win32":["H1Z1.exe"]},"id":186,"name":"H1Z1"},{"executables":{"win32":["HL2HL2.exe","hl2.exe"]},"id":188,"name":"Half Life 2"},{"executables":{"win32":["HOMEFRONT.exe"]},"id":195,"name":"Homefront"},{"executables":{"win32":["invisibleinc.exe"]},"id":196,"name":"Invisible Inc."},{"executables":{"win32":["LANoire.exe"]},"id":197,"name":"L.A. Noire"},{"executables":{"win32":["Landmark64.exe"]},"id":198,"name":"Landmark"},{"executables":{"win32":["left4dead2.exe"]},"id":201,"name":"Left 4 Dead 2"},{"executables":{"win32":["lineage.exe"]},"id":203,"name":"Lineage"},{"executables":{"win32":["Magicka.exe"]},"id":206,"name":"Magicka"},{"executables":{"win32":["MapleStory.exe"]},"id":208,"name":"MapleStory"},{"executables":{},"id":209,"name":"Mark of the Ninja"},{"executables":{"win32":["MassEffect.exe"]},"id":210,"name":"Mass Effect"},{"executables":{"win32":["MassEffect2.exe"]},"id":211,"name":"Mass Effect 2"},{"executables":{"win32":["MassEffect3Demo.exe"]},"id":212,"name":"Mass Effect 3"},{"executables":{"win32":["METAL GEAR RISING REVENGEANCE.exe"]},"id":214,"name":"Metal Gear Rising: Revengeance"},{"executables":{"win32":["metro2033.exe"]},"id":215,"name":"Metro 2033"},{"executables":{"win32":["MetroLL.exe"]},"id":216,"name":"Metro Last Light"},{"executables":{"win32":["MK10.exe"]},"id":218,"name":"Mortal Kombat X"},{"executables":{"win32":["speed.exe"]},"id":219,"name":"Need For Speed Most Wanted"},{"executables":{},"id":220,"name":"Neverwinder"},{"executables":{"darwin":["Outlast.app"],"win32":["OLGame.exe"]},"id":221,"name":"Outlast"},{"executables":{"win32":["PapersPlease.exe"]},"id":222,"name":"Papers, Please"},{"executables":{"win32":["payday_win32_release.exe"]},"id":223,"name":"PAYDAY"},{"executables":{"win32":["payday2_win32_release.exe"]},"id":224,"name":"PAYDAY2"},{"executables":{"win32":["PillarsOfEternity.exe"]},"id":225,"name":"Pillars of Eternity"},{"executables":{"win32":["PA.exe"]},"id":226,"name":"Planetary Annihilation"},{"executables":{"win32":["planetside2_x86.exe"]},"id":227,"name":"Planetside 2"},{"executables":{"win32":["hl2P.exe"]},"id":228,"name":"Portal"},{"executables":{"win32":["portal2.exe"]},"id":229,"name":"Portal 2"},{"executables":{"win32":["PrimalCarnageGame.exe"]},"id":231,"name":"Primal Cargnage"},{"executables":{"win32":["pCARS.exe"]},"id":232,"name":"Project Cars"},{"executables":{"win32":["RaceTheSun.exe"]},"id":233,"name":"Race The Sun"},{"executables":{"win32":["Rage.exe"]},"id":234,"name":"RAGE"},{"executables":{"win32":["ragexe.exe"]},"id":235,"name":"Ragnarok Online"},{"executables":{"win32":["rift.exe"]},"id":236,"name":"Rift"},{"executables":{"win32":["Rocksmith2014.exe"]},"id":237,"name":"Rocksmith 2014"},{"executables":{"win32":["SwiftKit-RS.exe","JagexLauncher.exe"]},"id":238,"name":"RuneScape"},{"executables":{"win32":["Shadowgrounds.exe"]},"id":239,"name":"Shadowgrounds"},{"executables":{"win32":["survivor.exe"]},"id":240,"name":"Shadowgrounds: Survivor"},{"executables":{"win32":["ShovelKnight.exe"]},"id":241,"name":"Shovel Knight"},{"executables":{"win32":["SimCity.exe"]},"id":242,"name":"SimCity"},{"executables":{"win32":["SporeApp.exe"]},"id":245,"name":"Spore"},{"executables":{"win32":["StarCitizen.exe"]},"id":246,"name":"Star Citizen"},{"executables":{},"id":247,"name":"Star Trek Online"},{"executables":{"win32":["battlefront.exe"]},"id":248,"name":"Star Wars Battlefront"},{"executables":{"win32":["swtor.exe"]},"id":249,"name":"Star Wars: The Old Republic"},{"executables":{"win32":["starbound.exe","starbound_opengl.exe"]},"id":250,"name":"Starbound"},{"executables":{"win32":["starcraft.exe"]},"id":251,"name":"Starcraft"},{"executables":{"win32":["SSFIV.exe"]},"id":253,"name":"Ultra Street Fighter IV"},{"executables":{"win32":["superhexagon.exe"]},"id":254,"name":"Super Hexagon"},{"executables":{"win32":["swordandsworcery_pc.exe"]},"id":255,"name":"Superbrothers: Sword & Sworcery EP"},{"executables":{"win32":["hl2TF.exe"]},"id":256,"name":"Team Fortress 2"},{"executables":{"win32":["TERA.exe"]},"id":258,"name":"TERA"},{"executables":{"win32":["Terraria.exe"]},"id":259,"name":"Terraria"},{"executables":{"win32":["Bethesda.net_Launcher.exe"]},"id":260,"name":"The Elder Scrolls Online"},{"executables":{"win32":["TESV.exe"]},"id":261,"name":"The Elder Scrolls V: Skyrim"},{"executables":{"win32":["TheSecretWorld.exe"]},"id":262,"name":"The Secret World"},{"executables":{"win32":["TS3.exe","ts3w.exe"]},"id":264,"name":"The Sims 3"},{"executables":{"win32":["WALKINGDEAD101.EXE"]},"id":265,"name":"The Walking Dead"},{"executables":{"win32":["TheWalkingDead2.exe"]},"id":266,"name":"The Walking Dead Season Two"},{"executables":{"win32":["witcher3.exe"]},"id":267,"name":"The Witcher 3"},{"executables":{"win32":["Future Soldier.exe"]},"id":268,"name":"Tom Clancy's Ghost Recon: Future Solider"},{"executables":{"win32":["TombRaider.exe"]},"id":269,"name":"Tomb Raider (2013)"},{"executables":{"win32":["Torchlight.exe"]},"id":271,"name":"Torchlight"},{"executables":{"win32":["Torchlight2.exe"]},"id":272,"name":"Torchlight 2"},{"executables":{"win32":["Shogun2.exe"]},"id":273,"name":"Total War: Shogun 2"},{"executables":{"win32":["Transistor.exe"]},"id":274,"name":"Transistor"},{"executables":{"win32":["trine.exe"]},"id":275,"name":"Trine"},{"executables":{"win32":["trine2_32bit.exe"]},"id":276,"name":"Trine 2"},{"executables":{"win32":["UOKR.exe"]},"id":277,"name":"Ultima Online"},{"executables":{"win32":["aces.exe"]},"id":279,"name":"War Thunder"},{"executables":{"win32":["Warcraft III.exe","wc3.exe"]},"id":281,"name":"Warcraft 3: Reign of Chaos"},{"executables":{"win32":["Warcraft II BNE.exe"]},"id":282,"name":"Warcraft II"},{"executables":{"win32":["Warframe.x64.exe","Warframe.exe"]},"id":283,"name":"Warframe"},{"executables":{"win32":["watch_dogs.exe"]},"id":284,"name":"Watch Dogs"},{"executables":{"win32":["WildStar64.exe"]},"id":285,"name":"WildStar"},{"executables":{"win32":["XComGame.exe"]},"id":288,"name":"XCOM: Enemy Unknown"},{"executables":{"win32":["DFO.exe","dfo.exe"]},"id":289,"name":"Dungeon Fighter Online"},{"executables":{"win32":["aclauncher.exe","acclient.exe"]},"id":290,"name":"Asheron's Call"},{"executables":{"win32":["MapleStory2.exe"]},"id":291,"name":"MapleStory 2"},{"executables":{"win32":["ksp.exe"]},"id":292,"name":"Kerbal Space Program"},{"executables":{"win32":["PINBALL.EXE"]},"id":293,"name":"3D Pinball: Space Cadet"},{"executables":{"win32":["dave.exe"]},"id":294,"name":"Dangerous Dave"},{"executables":{"win32":["iwbtgbeta(slomo).exe","iwbtgbeta(fs).exe"]},"id":295,"name":"I Wanna Be The Guy"},{"executables":{"win32":["MechWarriorOnline.exe "]},"id":296,"name":"Mech Warrior Online"},{"executables":{"win32":["dontstarve_steam.exe"]},"id":297,"name":"Don't Starve"},{"executables":{"win32":["GalCiv3.exe"]},"id":298,"name":"Galactic Civilization 3"},{"executables":{"win32":["Risk of Rain.exe"]},"id":299,"name":"Risk of Rain"},{"executables":{"win32":["Binding_of_Isaac.exe","Isaac-ng.exe"]},"id":300,"name":"The Binding of Isaac"},{"executables":{"win32":["RustClient.exe"]},"id":301,"name":"Rust"},{"executables":{"win32":["Clicker Heroes.exe"]},"id":302,"name":"Clicker Heroes"},{"executables":{"win32":["Brawlhalla.exe"]},"id":303,"name":"Brawlhalla"},{"executables":{"win32":["TownOfSalem.exe"]},"id":304,"name":"Town of Salem"},{"executables":{"win32":["osu!.exe"]},"id":305,"name":"osu!"},{"executables":{"win32":["PathOfExileSteam.exe","PathOfExile.exe"]},"id":306,"name":"Path of Exile"},{"executables":{"win32":["Dolphin.exe"]},"id":307,"name":"Dolphin"},{"executables":{"win32":["RocketLeague.exe"]},"id":308,"name":"Rocket League"},{"executables":{"win32":["TJPP.exe"]},"id":309,"name":"Jackbox Party Pack"},{"executables":{"win32":["KFGame.exe"]},"id":310,"name":"Killing Floor 2"},{"executables":{"win32":["ShooterGame.exe"]},"id":311,"name":"Ark: Survival Evolved"},{"executables":{"win32":["LifeIsStrange.exe"]},"id":312,"name":"Life Is Strange"},{"executables":{"win32":["Client_tos.exe"]},"id":313,"name":"Tree of Savior"},{"executables":{"win32":["olliolli2.exe"]},"id":314,"name":"OlliOlli2"},{"executables":{"win32":["cw.exe"]},"id":315,"name":"Closers Dimension Conflict"},{"executables":{"win32":["ESSTEAM.exe","elsword.exe","x2.exe"]},"id":316,"name":"Elsword"},{"executables":{"win32":["ori.exe"]},"id":317,"name":"Ori and the Blind Forest"},{"executables":{"win32":["Skyforge.exe"]},"id":318,"name":"Skyforge"},{"executables":{"win32":["projectzomboid64.exe","projectzomboid32.exe"]},"id":319,"name":"Project Zomboid"},{"executables":{"win32":["From_The_Depths.exe"]},"id":320,"name":"The Depths"},{"executables":{"win32":["TheCrew.exe"]},"id":321,"name":"The Crew"},{"executables":{"win32":["MarvelHeroes2015.exe"]},"id":322,"name":"Marvel Heroes 2015"},{"executables":{"win32":["timeclickers.exe"]},"id":324,"name":"Time Clickers"},{"executables":{"win32":["eurotrucks2.exe"]},"id":325,"name":"Euro Truck Simulator 2"},{"executables":{"win32":["FarmingSimulator2015Game.exe"]},"id":326,"name":"Farming Simulator 15"},{"executables":{"win32":["strife.exe"]},"id":327,"name":"Strife"},{"executables":{"win32":["Awesomenauts.exe"]},"id":328,"name":"Awesomenauts"},{"executables":{"win32":["Dofus.exe"]},"id":329,"name":"Dofus"},{"executables":{"win32":["Boid.exe"]},"id":330,"name":"Boid"},{"executables":{"win32":["adventure-capitalist.exe"]},"id":331,"name":"AdVenture Capitalist"},{"executables":{"win32":["OrcsMustDie2.exe"]},"id":332,"name":"Orcs Must Die! 2"},{"executables":{"win32":["Mountain.exe"]},"id":333,"name":"Mountain"},{"executables":{"win32":["Valkyria.exe"]},"id":335,"name":"Valkyria Chronicles"},{"executables":{"win32":["ffxiiiimg.exe"]},"id":336,"name":"Final Fantasy XIII"},{"executables":{"win32":["TLR.exe"]},"id":337,"name":"The Last Remnant"},{"executables":{"win32":["Cities.exe"]},"id":339,"name":"Cities Skylines"},{"executables":{"win32":["worldofwarships.exe","WoWSLauncher.exe"]},"id":341,"name":"World of Warships"},{"executables":{"win32":["spacegame-Win64-shipping.exe"]},"id":342,"name":"Fractured Space"},{"executables":{"win32":["thespacegame.exe"]},"id":343,"name":"Ascent - The Space Game"},{"executables":{"win32":["DuckGame.exe"]},"id":344,"name":"Duck Game"},{"executables":{"win32":["PPSSPPWindows.exe"]},"id":345,"name":"PPSSPP"},{"executables":{"win32":["MBAA.exe"]},"id":346,"name":"Melty Blood Actress Again: Current Code"},{"executables":{"win32":["TheWolfAmongUs.exe"]},"id":347,"name":"The Wolf Among Us"},{"executables":{"win32":["SpaceEngineers.exe"]},"id":348,"name":"Space Engineers"},{"executables":{"win32":["Borderlands.exe"]},"id":349,"name":"Borderlands"},{"executables":{"win32":["100orange.exe"]},"id":351,"name":"100% Orange Juice"},{"executables":{"win32":["reflex.exe"]},"id":354,"name":"Reflex"},{"executables":{"win32":["pso2.exe"]},"id":355,"name":"Phantasy Star Online 2"},{"executables":{"win32":["AssettoCorsa.exe"]},"id":356,"name":"Assetto Corsa"},{"executables":{"win32":["iw3mp.exe","iw3sp.exe"]},"id":357,"name":"Call of Duty 4: Modern Warfare"},{"executables":{"win32":["WolfOldBlood_x64.exe"]},"id":358,"name":"Wolfenstein: The Old Blood"},{"executables":{"win32":["castle.exe"]},"id":359,"name":"Castle Crashers"},{"executables":{"win32":["vindictus.exe"]},"id":360,"name":"Vindictus"},{"executables":{"win32":["ShooterGame-Win32-Shipping.exe"]},"id":361,"name":"Dirty Bomb"},{"executables":{"win32":["BatmanAK.exe"]},"id":362,"name":"Batman Arkham Knight"},{"executables":{"win32":["drt.exe"]},"id":363,"name":"Dirt Rally"},{"executables":{"win32":["rFactor.exe"]},"id":364,"name":"rFactor"},{"executables":{"win32":["clonk.exe"]},"id":365,"name":"Clonk Rage"},{"executables":{"win32":["SRHK.exe"]},"id":366,"name":"Shadowrun: Hong Kong"},{"executables":{"win32":["Insurgency.exe"]},"id":367,"name":"Insurgency"},{"executables":{"win32":["StepMania.exe"]},"id":368,"name":"Step Mania"},{"executables":{"win32":["FirefallCLient.exe"]},"id":369,"name":"Firefall"},{"executables":{"win32":["mirrorsedge.exe"]},"id":370,"name":"Mirrors Edge"},{"executables":{"win32":["MgsGroundZeroes.exe"]},"id":371,"name":"Metal Gear Solid V: Ground Zeroes"},{"executables":{"win32":["mgsvtpp.exe"]},"id":372,"name":"Metal Gear Solid V: The Phantom Pain"},{"executables":{"win32":["tld.exe"]},"id":373,"name":"The Long Dark"},{"executables":{"win32":["TKOM.exe"]},"id":374,"name":"Take On Mars"},{"executables":{"win32":["robloxplayerlauncher.exe","Roblox.exe"]},"id":375,"name":"Roblox"},{"executables":{"win32":["eu4.exe"]},"id":376,"name":"Europa Universalis 4"},{"executables":{"win32":["APB.exe"]},"id":377,"name":"APB Reloaded"},{"executables":{"win32":["Robocraft.exe"]},"id":378,"name":"Robocraft"},{"executables":{"win32":["Unity.exe"]},"id":379,"name":"Unity"},{"executables":{"win32":["Simpsons.exe"]},"id":380,"name":"The Simpsons: Hit & Run"},{"executables":{"win32":["Dnlauncher.exe","DragonNest.exe"]},"id":381,"name":"Dragon Nest"},{"executables":{"win32":["Trove.exe"]},"id":382,"name":"Trove"},{"executables":{"win32":["EndlessLegend.exe"]},"id":383,"name":"Endless Legend"},{"executables":{"win32":["TurbineLauncher.exe","dndclient.exe"]},"id":384,"name":"Dungeons & Dragons Online"},{"executables":{"win32":["quakelive.exe","quakelive_steam.exe"]},"id":385,"name":"Quake Live"},{"executables":{"win32":["7DaysToDie.exe"]},"id":386,"name":"7DaysToDie"},{"executables":{"win32":["SpeedRunners.exe"]},"id":387,"name":"SpeedRunners"},{"executables":{"win32":["gamemd.exe"]},"id":388,"name":"Command & Conquer: Red Alert 2"},{"executables":{"win32":["generals.exe"]},"id":389,"name":"Command & Conquer Generals: Zero Hour"},{"executables":{"win32":["Oblivion.exe"]},"id":390,"name":"The Elder Scrolls 4: Oblivion"},{"executables":{"win32":["mgsi.exe"]},"id":391,"name":"Metal Gear Solid"},{"executables":{"win32":["EoCApp.exe"]},"id":392,"name":"Divinity - Original Sin"},{"executables":{"win32":["Torment.exe"]},"id":393,"name":"Planescape: Torment"},{"executables":{"win32":["HexPatch.exe"]},"id":394,"name":"Hex: Shards of Fate"},{"executables":{"win32":["NS3FB.exe"]},"id":395,"name":"Naruto Shippuden Ultimate Ninja Storm 3 Full Burst"},{"executables":{"win32":["NSUNSR.exe"]},"id":396,"name":"Naruto Shippuden Ultimate Ninja Storm Revolution"},{"executables":{"win32":["SaintsRowIV.exe"]},"id":397,"name":"Saints Row IV"},{"executables":{"win32":["Shadowrun.exe"]},"id":398,"name":"Shadowrun"},{"executables":{"win32":["DungeonoftheEndless.exe"]},"id":399,"name":"Dungeon of the Endless"},{"executables":{"win32":["Hon.exe"]},"id":400,"name":"Heroes of Newerth"},{"executables":{"win32":["mabinogi.exe"]},"id":401,"name":"Mabinogi"},{"executables":{"win32":["CoD2MP_s.exe","CoDSP_s.exe"]},"id":402,"name":"Call of Duty 2:"},{"executables":{"win32":["CoDWaWmp.exe","CoDWaw.exe"]},"id":403,"name":"Call of Duty: World at War"},{"executables":{"win32":["heroes.exe"]},"id":404,"name":"Mabinogi Heroes (Vindictus) "},{"executables":{"win32":["KanColleViewer.exe"]},"id":405,"name":"KanColle "},{"executables":{"win32":["cyphers.exe"]},"id":406,"name":"Cyphers"},{"executables":{"win32":["RelicCoH2.exe"]},"id":407,"name":"Company of Heroes 2"},{"executables":{"win32":["MJ.exe"]},"id":408,"name":"セガNET麻雀MJ"},{"executables":{"win32":["ge.exe"]},"id":409,"name":"Granado Espada"},{"executables":{"win32":["NovaRO.exe"]},"id":410,"name":"Nova Ragnarok Online"},{"executables":{"win32":["RivalsofAether.exe"]},"id":411,"name":"Rivals of Aether"},{"executables":{"win32":["bfh.exe"]},"id":412,"name":"Battlefield Hardline"},{"executables":{"win32":["GrowHome.exe"]},"id":413,"name":"Grow Home"},{"executables":{"win32":["patriots.exe"]},"id":414,"name":"Rise of Nations Extended"},{"executables":{"win32":["Railroads.exe"]},"id":415,"name":"Sid Meier's Railroads!"},{"executables":{"win32":["Empire.exe"]},"id":416,"name":"Empire: Total War"},{"executables":{"win32":["Napoleon.exe"]},"id":417,"name":"Napoleon: Total War"},{"executables":{"win32":["gta_sa.exe"]},"id":418,"name":"Grand Theft Auto: San Andreas"},{"executables":{"win32":["MadMax.exe"]},"id":419,"name":"Mad Max"},{"executables":{"win32":["Titanfall.exe"]},"id":420,"name":"Titanfall"},{"executables":{"win32":["age2_x1.exe"]},"id":421,"name":"Age of Empires II: The Conquerors"},{"executables":{"win32":["Rome2.exe"]},"id":422,"name":"Total War: ROME 2"},{"executables":{"win32":["ShadowOfMordor.exe"]},"id":423,"name":"Middle-earth: Shadow of Mordor"},{"executables":{"win32":["Subnautica.exe"]},"id":424,"name":"Subnautica"},{"executables":{"win32":["anno5.exe"]},"id":425,"name":"Anno 2070"},{"executables":{"win32":["carrier.exe"]},"id":426,"name":"Carrier Command Gaea Mission"},{"executables":{"win32":["DarksidersPC.exe"]},"id":427,"name":"Darksiders"},{"executables":{"win32":["Darksiders2.exe"]},"id":428,"name":"Darksiders 2"},{"executables":{"win32":["mudlet.exe"]},"id":429,"name":"Mudlet"},{"executables":{"win32":["DunDefLauncher.exe"]},"id":430,"name":"Dungeon Defenders II"},{"executables":{"win32":["hng.exe"]},"id":431,"name":"Heroes and Generals"},{"executables":{"win32":["WFTOGame.exe"]},"id":432,"name":"War of the Overworld"},{"executables":{"win32":["Talisman.exe"]},"id":433,"name":"Talisman: Digital Edition"},{"executables":{"win32":["limbo.exe"]},"id":434,"name":"Limbo"},{"executables":{"win32":["ibbobb.exe"]},"id":435,"name":"ibb & obb"},{"executables":{"win32":["BattleBlockTheater.exe"]},"id":436,"name":"BattleBlock Theater"},{"executables":{"win32":["iracinglauncher.exe","iracingsim.exe","iracingsim64.exe"]},"id":437,"name":"iRacing"},{"executables":{"win32":["CivilizationV_DX11.exe"]},"id":438,"name":"Civilization V"}]
+},{}]},{},[9])(9)
+});
\ No newline at end of file
diff --git a/web-dist/discord.min.3.3.0.js b/web-dist/discord.min.3.3.0.js
new file mode 100644
index 000000000..71f1235d5
--- /dev/null
+++ b/web-dist/discord.min.3.3.0.js
@@ -0,0 +1,2 @@
+!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Discord=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g]*>/g)||[])[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;a.push(h.substring(2,h.length-1))}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return a}"function"==typeof c&&(d=c,c=!1),b=e+n(b);var p=o();f.resolveDestination(a).then(k)["catch"](j)});return g}},{key:"createws",value:function(a){if(this.websocket)return!1;var b=this;this.websocket=new o(a),this.websocket.onopen=function(){b.trySendConnData()},this.websocket.onclose=function(){b.trigger("disconnected")},this.websocket.onmessage=function(a){var c=!1,d={};try{c=JSON.parse(a.data),d=c.d}catch(e){return void b.trigger("error",e,a)}switch(c.t){case"READY":b.debug("received ready packet"),b.user=b.addUser(d.user);var f=!0,g=!1,i=void 0;try{for(var j,l=d.guilds[Symbol.iterator]();!(f=(j=l.next()).done);f=!0)var m=j.value,n=b.addServer(m)}catch(e){g=!0,i=e}finally{try{!f&&l["return"]&&l["return"]()}finally{if(g)throw i}}var o=!0,p=!1,q=void 0;try{for(var r,s=d.private_channels[Symbol.iterator]();!(o=(r=s.next()).done);o=!0){var t=r.value;b.addPMChannel(t)}}catch(e){p=!0,q=e}finally{try{!o&&s["return"]&&s["return"]()}finally{if(p)throw q}}b.trigger("ready"),b.readyTime=Date.now(),b.debug("cached "+b.serverCache.length+" servers, "+b.channelCache.length+" channels, "+b.pmChannelCache.length+" PMs and "+b.userCache.length+" users."),b.state=3,setInterval(function(){b.keepAlive.apply(b)},d.heartbeat_interval);break;case"MESSAGE_CREATE":b.debug("received message");var u=[];d.mentions=d.mentions||[];var v=!0,w=!1,x=void 0;try{for(var y,z=d.mentions[Symbol.iterator]();!(v=(y=z.next()).done);v=!0){var A=y.value;u.push(b.addUser(A))}}catch(e){w=!0,x=e}finally{try{!v&&z["return"]&&z["return"]()}finally{if(w)throw x}}var B=b.getChannel("id",d.channel_id);if(B){var C=B.addMessage(new k(d,B,u,b.addUser(d.author)));b.trigger("message",C)}break;case"MESSAGE_DELETE":b.debug("message deleted");var B=b.getChannel("id",d.channel_id),D=B.getMessage("id",d.id);D?(b.trigger("messageDelete",B,D),B.messages.splice(B.messages.indexOf(D),1)):b.trigger("messageDelete",B);break;case"MESSAGE_UPDATE":b.debug("message updated");var B=b.getChannel("id",d.channel_id),E=B.getMessage("id",d.id);if(E){var F={};for(var G in E)F[G]=E[G];for(var G in d)F[G]=d[G];var u=[],H=!0,I=!1,J=void 0;try{for(var K,L=F.mentions[Symbol.iterator]();!(H=(K=L.next()).done);H=!0){var A=K.value;u.push(b.addUser(A))}}catch(e){I=!0,J=e}finally{try{!H&&L["return"]&&L["return"]()}finally{if(I)throw J}}var M=new k(F,B,u,E.author);b.trigger("messageUpdate",M,E),B.messages[B.messages.indexOf(E)]=M}break;case"GUILD_DELETE":var n=b.getServer("id",d.id);n&&(b.serverCache.splice(b.serverCache.indexOf(n),1),b.trigger("serverDelete",n));break;case"CHANNEL_DELETE":var B=b.getChannel("id",d.id);if(B){var n=B.server;n&&n.channels.splice(n.channels.indexOf(B),1),b.trigger("channelDelete",B),b.serverCache.splice(b.serverCache.indexOf(B),1)}break;case"GUILD_CREATE":var n=b.getServer("id",d.id);if(n||(n=b.addServer(d)),b.serverCreateListener.get(d.id)){var N=b.serverCreateListener.get(d.id);N[0](n),N[1](null,n),b.serverCreateListener["delete"](d.id)}b.trigger("serverCreate",n);break;case"CHANNEL_CREATE":var B=b.getChannel("id",d.id);if(!B){var O=b.addChannel(d,d.guild_id),P=b.getServer("id",d.guild_id);P&&P.addChannel(O),b.trigger("channelCreate",O)}break;case"GUILD_MEMBER_ADD":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)||n.members.push(Q),b.trigger("serverNewMember",Q)}break;case"GUILD_MEMBER_REMOVE":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)&&n.members.splice(n.members.indexOf(Q),1),b.trigger("serverRemoveMember",Q)}break;case"USER_UPDATE":if(b.user&&d.id===b.user.id){var R=new h(d);b.trigger("userUpdate",R,b.user),~b.userCache.indexOf(b.user)&&(b.userCache[b.userCache.indexOf(b.user)]=R),b.user=R}break;case"PRESENCE_UPDATE":var S=b.getUser("id",d.user.id);if(S){var T=new h(d.user);T.equalsStrict(S)?b.trigger("presence",{user:S,status:d.status,server:b.getServer("id",d.guild_id),gameId:d.game_id}):(b.trigger("userUpdate",S,T),b.userCache[b.userCache.indexOf(S)]=T)}break;default:b.debug("received unknown packet"),b.trigger("unknown",c)}}}},{key:"addUser",value:function(a){return this.getUser("id",a.id)||this.userCache.push(new h(a)),this.getUser("id",a.id)}},{key:"addChannel",value:function(a,b){return this.getChannel("id",a.id)||this.channelCache.push(new j(a,this.getServer("id",b))),this.getChannel("id",a.id)}},{key:"addPMChannel",value:function(a){return this.getPMChannel("id",a.id)||this.pmChannelCache.push(new m(a,this)),this.getPMChannel("id",a.id)}},{key:"addServer",value:function(a){var b=this.getServer("id",a.id);if(!b&&(b=new i(a,this),this.serverCache.push(b),a.channels)){var c=!0,d=!1,e=void 0;try{for(var f,g=a.channels[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;b.channels.push(this.addChannel(h,b.id))}}catch(j){d=!0,e=j}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}}return b}},{key:"getUser",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.userCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.channelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return this.getPMChannel(a,b)}},{key:"getPMChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.pmChannelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getServer",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.serverCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"trySendConnData",value:function(){if(this.token&&!this.alreadySentData){this.alreadySentData=!0;var a={op:2,d:{token:this.token,v:2,properties:{$os:"discord.js",$browser:"discord.js",$device:"discord.js",$referrer:"",$referring_domain:""}}};this.websocket.send(JSON.stringify(a))}}},{key:"resolveServerID",value:function(a){return a instanceof i?a.id:!isNaN(a)&&a.length&&17===a.length?a:void 0}},{key:"resolveDestination",value:function(a){var b=!1,c=this;return new Promise(function(d,e){if(a instanceof i)b=a.id;else if(a instanceof j)b=a.id;else if(a instanceof k)b=a.channel.id;else if(a instanceof h){var f=!0,g=!1,l=void 0;try{for(var m,n=c.pmChannelCache[Symbol.iterator]();!(f=(m=n.next()).done);f=!0){var o=m.value;if(o.user.equals(a))return o.id}}catch(p){g=!0,l=p}finally{try{!f&&n["return"]&&n["return"]()}finally{if(g)throw l}}c.startPM(a).then(function(a){d(a.id)})["catch"](e)}else b=a;b&&d(b)})}},{key:"_sendMessage",value:function(a,b,c,d){var e=this;return new Promise(function(f,h){n.post(g.CHANNELS+"/"+a+"/messages").set("authorization",e.token).send({content:b,mentions:d,tts:c}).end(function(a,b){if(a)h(a);else{var c=b.body,d=[];c.mentions=c.mentions||[];var g=!0,i=!1,j=void 0;try{for(var l,m=c.mentions[Symbol.iterator]();!(g=(l=m.next()).done);g=!0){var n=l.value;d.push(e.addUser(n))}}catch(a){i=!0,j=a}finally{try{!g&&m["return"]&&m["return"]()}finally{if(i)throw j}}var o=e.getChannel("id",c.channel_id);if(o){var p=o.addMessage(new k(c,o,d,e.addUser(c.author)));f(p)}}})})}},{key:"_sendFile",value:function(a,b){var c=arguments.length<=2||void 0===arguments[2]?"DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png":arguments[2],d=this;return new Promise(function(e,f){n.post(g.CHANNELS+"/"+a+"/messages").set("authorization",d.token).attach("file",b,c).end(function(b,c){if(b)f(b);else{var g=d.getChannel("id",a);if(g){var h=g.addMessage(new k(c.body,g,[],d.user));e(h)}}})})}},{key:"_updateMessage",value:function(a,b){var c=this;return new Promise(function(d,e){n.patch(g.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",c.token).send({content:b,mentions:[]}).end(function(b,c){if(b)e(b);else{var f=new k(c.body,a.channel,a.mentions,a.sender);d(f),a.channel.messages[a.channel.messages.indexOf(a)]=f}})})}},{key:"_deleteMessage",value:function(a){var b=this;return new Promise(function(c,d){n.del(g.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",b.token).end(function(a,b){a?d(a):c()})})}},{key:"checkQueue",value:function(a){var b=this,c=this;this.checkingQueue[a]||!function(){var d=function f(){if(0===c.queue[a].length)return void e();var b=c.queue[a][0];switch(b.action){case"sendMessage":var d=b;c._sendMessage(a,d.content,d.tts,d.mentions).then(function(b){d.then(b),c.queue[a].shift(),f()})["catch"](function(b){d.error(b),c.queue[a].shift(),f()});break;case"sendFile":var g=b;c._sendFile(a,g.attachment,g.attachmentName).then(function(b){g.then(b),c.queue[a].shift(),f()})["catch"](function(b){g.error(b),c.queue[a].shift(),f()});break;case"updateMessage":var h=b;c._updateMessage(h.message,h.content).then(function(b){h.then(b),c.queue[a].shift(),f()})["catch"](function(b){h.error(b),c.queue[a].shift(),f()});break;case"deleteMessage":var i=b;c._deleteMessage(i.message).then(function(b){i.then(b),c.queue[a].shift(),f()})["catch"](function(b){i.error(b),c.queue[a].shift(),f()});break;default:e()}},e=function(){c.checkingQueue[a]=!1};b.checkingQueue[a]=!0,d()}()}},{key:"uptime",get:function(){return this.readyTime?Date.now()-this.readyTime:null}},{key:"ready",get:function(){return 3===this.state}},{key:"servers",get:function(){return this.serverCache}},{key:"channels",get:function(){return this.channelCache}},{key:"users",get:function(){return this.userCache}},{key:"PMChannels",get:function(){return this.pmChannelCache}},{key:"messages",get:function(){var a=[],b=!0,c=!1,d=void 0;try{for(var e,f=this.channelCache[Symbol.iterator]();!(b=(e=f.next()).done);b=!0){var g=e.value;a=a.concat(g.messages)}}catch(h){c=!0,d=h}finally{try{!b&&f["return"]&&f["return"]()}finally{if(c)throw d}}return a}}]),a}();b.exports=r},{"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,fs:10,superagent:11,ws:14}],2:[function(a,b,c){"use strict";c.BASE_DOMAIN="discordapp.com",c.BASE="https://"+c.BASE_DOMAIN,c.WEBSOCKET_HUB="wss://"+c.BASE_DOMAIN+"/hub",c.API=c.BASE+"/api",c.AUTH=c.API+"/auth",c.LOGIN=c.AUTH+"/login",c.LOGOUT=c.AUTH+"/logout",c.USERS=c.API+"/users",c.SERVERS=c.API+"/guilds",c.CHANNELS=c.API+"/channels"},{}],3:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c"}},{key:"toString",value:function(){return this.mention()}},{key:"equals",value:function(a){return a.id===this.id}},{key:"equalsStrict",value:function(a){return a.id===this.id&&a.avatar===this.avatar&&a.username===this.username&&a.discriminator===this.discriminator}},{key:"avatarURL",get:function(){return this.avatar?"https://discordapp.com/api/users/"+this.id+"/avatars/"+this.avatar+".jpg":null}}]),a}();b.exports=f},{}],10:[function(a,b,c){},{}],11:[function(a,b,c){function d(){}function e(a){var b={}.toString.call(a);switch(b){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function f(a){return a===Object(a)}function g(a){if(!f(a))return a;var b=[];for(var c in a)null!=a[c]&&b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")}function h(a){for(var b,c,d={},e=a.split("&"),f=0,g=e.length;g>f;++f)c=e[f],b=c.split("="),d[decodeURIComponent(b[0])]=decodeURIComponent(b[1]);return d}function i(a){var b,c,d,e,f=a.split(/\r?\n/),g={};f.pop();for(var h=0,i=f.length;i>h;++h)c=f[h],b=c.indexOf(":"),d=c.slice(0,b).toLowerCase(),e=r(c.slice(b+1)),g[d]=e;return g}function j(a){return a.split(/ *; */).shift()}function k(a){return p(a.split(/ *; */),function(a,b){var c=b.split(/ *= */),d=c.shift(),e=c.shift();return d&&e&&(a[d]=e),a},{})}function l(a,b){b=b||{},this.req=a,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=i(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function m(a,b){var c=this;o.call(this),this._query=this._query||[],this.method=a,this.url=b,this.header={},this._header={},this.on("end",function(){var a=null,b=null;try{b=new l(c)}catch(d){return a=new Error("Parser is unable to parse the response"),a.parse=!0,a.original=d,c.callback(a)}if(c.emit("response",b),a)return c.callback(a,b);if(b.status>=200&&b.status<300)return c.callback(a,b);var e=new Error(b.statusText||"Unsuccessful HTTP response");e.original=a,e.response=b,e.status=b.status,c.callback(e,b)})}function n(a,b){return"function"==typeof b?new m("GET",a).end(b):1==arguments.length?new m("GET",a):new m(a,b)}var o=a("emitter"),p=a("reduce"),q="undefined"==typeof window?this||self:window;n.getXHR=function(){if(!(!q.XMLHttpRequest||q.location&&"file:"==q.location.protocol&&q.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(a){}return!1};var r="".trim?function(a){return a.trim()}:function(a){return a.replace(/(^\s*|\s*$)/g,"")};n.serializeObject=g,n.parseString=h,n.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},n.serialize={"application/x-www-form-urlencoded":g,"application/json":JSON.stringify},n.parse={"application/x-www-form-urlencoded":h,"application/json":JSON.parse},l.prototype.get=function(a){return this.header[a.toLowerCase()]},l.prototype.setHeaderProperties=function(a){var b=this.header["content-type"]||"";this.type=j(b);var c=k(b);for(var d in c)this[d]=c[d]},l.prototype.parseBody=function(a){var b=n.parse[this.type];return b&&a&&(a.length||a instanceof Object)?b(a):null},l.prototype.setStatusProperties=function(a){1223===a&&(a=204);var b=a/100|0;this.status=a,this.statusType=b,this.info=1==b,this.ok=2==b,this.clientError=4==b,this.serverError=5==b,this.error=4==b||5==b?this.toError():!1,this.accepted=202==a,this.noContent=204==a,this.badRequest=400==a,this.unauthorized=401==a,this.notAcceptable=406==a,this.notFound=404==a,this.forbidden=403==a},l.prototype.toError=function(){var a=this.req,b=a.method,c=a.url,d="cannot "+b+" "+c+" ("+this.status+")",e=new Error(d);return e.status=this.status,e.method=b,e.url=c,e},n.Response=l,o(m.prototype),m.prototype.use=function(a){return a(this),this},m.prototype.timeout=function(a){return this._timeout=a,this},m.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},m.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0,this.xhr.abort(),
+this.clearTimeout(),this.emit("abort"),this)},m.prototype.set=function(a,b){if(f(a)){for(var c in a)this.set(c,a[c]);return this}return this._header[a.toLowerCase()]=b,this.header[a]=b,this},m.prototype.unset=function(a){return delete this._header[a.toLowerCase()],delete this.header[a],this},m.prototype.getHeader=function(a){return this._header[a.toLowerCase()]},m.prototype.type=function(a){return this.set("Content-Type",n.types[a]||a),this},m.prototype.accept=function(a){return this.set("Accept",n.types[a]||a),this},m.prototype.auth=function(a,b){var c=btoa(a+":"+b);return this.set("Authorization","Basic "+c),this},m.prototype.query=function(a){return"string"!=typeof a&&(a=g(a)),a&&this._query.push(a),this},m.prototype.field=function(a,b){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b),this},m.prototype.attach=function(a,b,c){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b,c),this},m.prototype.send=function(a){var b=f(a),c=this.getHeader("Content-Type");if(b&&f(this._data))for(var d in a)this._data[d]=a[d];else"string"==typeof a?(c||this.type("form"),c=this.getHeader("Content-Type"),"application/x-www-form-urlencoded"==c?this._data=this._data?this._data+"&"+a:a:this._data=(this._data||"")+a):this._data=a;return!b||e(a)?this:(c||this.type("json"),this)},m.prototype.callback=function(a,b){var c=this._callback;this.clearTimeout(),c(a,b)},m.prototype.crossDomainError=function(){var a=new Error("Origin is not allowed by Access-Control-Allow-Origin");a.crossDomain=!0,this.callback(a)},m.prototype.timeoutError=function(){var a=this._timeout,b=new Error("timeout of "+a+"ms exceeded");b.timeout=a,this.callback(b)},m.prototype.withCredentials=function(){return this._withCredentials=!0,this},m.prototype.end=function(a){var b=this,c=this.xhr=n.getXHR(),f=this._query.join("&"),g=this._timeout,h=this._formData||this._data;this._callback=a||d,c.onreadystatechange=function(){if(4==c.readyState){var a;try{a=c.status}catch(d){a=0}if(0==a){if(b.timedout)return b.timeoutError();if(b.aborted)return;return b.crossDomainError()}b.emit("end")}};var i=function(a){a.total>0&&(a.percent=a.loaded/a.total*100),b.emit("progress",a)};this.hasListeners("progress")&&(c.onprogress=i);try{c.upload&&this.hasListeners("progress")&&(c.upload.onprogress=i)}catch(j){}if(g&&!this._timer&&(this._timer=setTimeout(function(){b.timedout=!0,b.abort()},g)),f&&(f=n.serializeObject(f),this.url+=~this.url.indexOf("?")?"&"+f:"?"+f),c.open(this.method,this.url,!0),this._withCredentials&&(c.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof h&&!e(h)){var k=this.getHeader("Content-Type"),l=n.serialize[k?k.split(";")[0]:""];l&&(h=l(h))}for(var m in this.header)null!=this.header[m]&&c.setRequestHeader(m,this.header[m]);return this.emit("request",this),c.send(h),this},m.prototype.then=function(a,b){return this.end(function(c,d){c?b(c):a(d)})},n.Request=m,n.get=function(a,b,c){var d=n("GET",a);return"function"==typeof b&&(c=b,b=null),b&&d.query(b),c&&d.end(c),d},n.head=function(a,b,c){var d=n("HEAD",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.del=function(a,b){var c=n("DELETE",a);return b&&c.end(b),c},n.patch=function(a,b,c){var d=n("PATCH",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.post=function(a,b,c){var d=n("POST",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.put=function(a,b,c){var d=n("PUT",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},b.exports=n},{emitter:12,reduce:13}],12:[function(a,b,c){function d(a){return a?e(a):void 0}function e(a){for(var b in d.prototype)a[b]=d.prototype[b];return a}b.exports=d,d.prototype.on=d.prototype.addEventListener=function(a,b){return this._callbacks=this._callbacks||{},(this._callbacks[a]=this._callbacks[a]||[]).push(b),this},d.prototype.once=function(a,b){function c(){d.off(a,c),b.apply(this,arguments)}var d=this;return this._callbacks=this._callbacks||{},c.fn=b,this.on(a,c),this},d.prototype.off=d.prototype.removeListener=d.prototype.removeAllListeners=d.prototype.removeEventListener=function(a,b){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var c=this._callbacks[a];if(!c)return this;if(1==arguments.length)return delete this._callbacks[a],this;for(var d,e=0;ed;++d)c[d].apply(this,b)}return this},d.prototype.listeners=function(a){return this._callbacks=this._callbacks||{},this._callbacks[a]||[]},d.prototype.hasListeners=function(a){return!!this.listeners(a).length}},{}],13:[function(a,b,c){b.exports=function(a,b,c){for(var d=0,e=a.length,f=3==arguments.length?c:a[d++];e>d;)f=b.call(null,f,a[d],++d,a);return f}},{}],14:[function(a,b,c){function d(a,b,c){var d;return d=b?new f(a,b):new f(a)}var e=function(){return this}(),f=e.WebSocket||e.MozWebSocket;b.exports=f?d:null,f&&(d.prototype=f.prototype)},{}]},{},[5])(5)});
\ No newline at end of file
diff --git a/web-dist/discord.min.3.3.1.js b/web-dist/discord.min.3.3.1.js
new file mode 100644
index 000000000..2079f39b6
--- /dev/null
+++ b/web-dist/discord.min.3.3.1.js
@@ -0,0 +1,2 @@
+!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Discord=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g]*>/g)||[])[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;a.push(h.substring(2,h.length-1))}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return a}"function"==typeof c&&(d=c,c=!1),b=e+n(b);var p=o();f.resolveDestination(a).then(k)["catch"](j)});return g}},{key:"createws",value:function(a){if(this.websocket)return!1;var b=this;this.websocket=new o(a),this.websocket.onopen=function(){b.trySendConnData()},this.websocket.onclose=function(){b.trigger("disconnected")},this.websocket.onmessage=function(a){var c=!1,d={};try{c=JSON.parse(a.data),d=c.d}catch(e){return void b.trigger("error",e,a)}switch(c.t){case"READY":b.debug("received ready packet"),b.user=b.addUser(d.user);var f=!0,g=!1,i=void 0;try{for(var j,l=d.guilds[Symbol.iterator]();!(f=(j=l.next()).done);f=!0)var m=j.value,n=b.addServer(m)}catch(e){g=!0,i=e}finally{try{!f&&l["return"]&&l["return"]()}finally{if(g)throw i}}var o=!0,p=!1,q=void 0;try{for(var r,s=d.private_channels[Symbol.iterator]();!(o=(r=s.next()).done);o=!0){var t=r.value;b.addPMChannel(t)}}catch(e){p=!0,q=e}finally{try{!o&&s["return"]&&s["return"]()}finally{if(p)throw q}}b.trigger("ready"),b.readyTime=Date.now(),b.debug("cached "+b.serverCache.length+" servers, "+b.channelCache.length+" channels, "+b.pmChannelCache.length+" PMs and "+b.userCache.length+" users."),b.state=3,setInterval(function(){b.keepAlive.apply(b)},d.heartbeat_interval);break;case"MESSAGE_CREATE":b.debug("received message");var u=[];d.mentions=d.mentions||[];var v=!0,w=!1,x=void 0;try{for(var y,z=d.mentions[Symbol.iterator]();!(v=(y=z.next()).done);v=!0){var A=y.value;u.push(b.addUser(A))}}catch(e){w=!0,x=e}finally{try{!v&&z["return"]&&z["return"]()}finally{if(w)throw x}}var B=b.getChannel("id",d.channel_id);if(B){var C=B.addMessage(new k(d,B,u,b.addUser(d.author)));b.trigger("message",C)}break;case"MESSAGE_DELETE":b.debug("message deleted");var B=b.getChannel("id",d.channel_id),D=B.getMessage("id",d.id);D?(b.trigger("messageDelete",B,D),B.messages.splice(B.messages.indexOf(D),1)):b.trigger("messageDelete",B);break;case"MESSAGE_UPDATE":b.debug("message updated");var B=b.getChannel("id",d.channel_id),E=B.getMessage("id",d.id);if(E){var F={};for(var G in E)F[G]=E[G];for(var G in d)F[G]=d[G];var u=[],H=!0,I=!1,J=void 0;try{for(var K,L=F.mentions[Symbol.iterator]();!(H=(K=L.next()).done);H=!0){var A=K.value;u.push(b.addUser(A))}}catch(e){I=!0,J=e}finally{try{!H&&L["return"]&&L["return"]()}finally{if(I)throw J}}var M=new k(F,B,u,E.author);b.trigger("messageUpdate",M,E),B.messages[B.messages.indexOf(E)]=M}break;case"GUILD_DELETE":var n=b.getServer("id",d.id);n&&(b.serverCache.splice(b.serverCache.indexOf(n),1),b.trigger("serverDelete",n));break;case"CHANNEL_DELETE":var B=b.getChannel("id",d.id);if(B){var n=B.server;n&&n.channels.splice(n.channels.indexOf(B),1),b.trigger("channelDelete",B),b.serverCache.splice(b.serverCache.indexOf(B),1)}break;case"GUILD_CREATE":var n=b.getServer("id",d.id);if(n||(n=b.addServer(d)),b.serverCreateListener.get(d.id)){var N=b.serverCreateListener.get(d.id);N[0](n),N[1](null,n),b.serverCreateListener["delete"](d.id)}b.trigger("serverCreate",n);break;case"CHANNEL_CREATE":var B=b.getChannel("id",d.id);if(!B){var O=b.addChannel(d,d.guild_id),P=b.getServer("id",d.guild_id);P&&P.addChannel(O),b.trigger("channelCreate",O)}break;case"GUILD_MEMBER_ADD":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)||n.members.push(Q),b.trigger("serverNewMember",Q,n)}break;case"GUILD_MEMBER_REMOVE":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)&&n.members.splice(n.members.indexOf(Q),1),b.trigger("serverRemoveMember",Q,n)}break;case"USER_UPDATE":if(b.user&&d.id===b.user.id){var R=new h(d);b.trigger("userUpdate",R,b.user),~b.userCache.indexOf(b.user)&&(b.userCache[b.userCache.indexOf(b.user)]=R),b.user=R}break;case"PRESENCE_UPDATE":var S=b.getUser("id",d.user.id);if(S){var T=new h(d.user);T.equalsStrict(S)?b.trigger("presence",{user:S,status:d.status,server:b.getServer("id",d.guild_id),gameId:d.game_id}):(b.trigger("userUpdate",S,T),b.userCache[b.userCache.indexOf(S)]=T)}break;default:b.debug("received unknown packet"),b.trigger("unknown",c)}}}},{key:"addUser",value:function(a){return this.getUser("id",a.id)||this.userCache.push(new h(a)),this.getUser("id",a.id)}},{key:"addChannel",value:function(a,b){return this.getChannel("id",a.id)||this.channelCache.push(new j(a,this.getServer("id",b))),this.getChannel("id",a.id)}},{key:"addPMChannel",value:function(a){return this.getPMChannel("id",a.id)||this.pmChannelCache.push(new m(a,this)),this.getPMChannel("id",a.id)}},{key:"addServer",value:function(a){var b=this.getServer("id",a.id);if(!b&&(b=new i(a,this),this.serverCache.push(b),a.channels)){var c=!0,d=!1,e=void 0;try{for(var f,g=a.channels[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;b.channels.push(this.addChannel(h,b.id))}}catch(j){d=!0,e=j}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}}return b}},{key:"getUser",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.userCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.channelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return this.getPMChannel(a,b)}},{key:"getPMChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.pmChannelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getServer",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.serverCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"trySendConnData",value:function(){if(this.token&&!this.alreadySentData){this.alreadySentData=!0;var a={op:2,d:{token:this.token,v:2,properties:{$os:"discord.js",$browser:"discord.js",$device:"discord.js",$referrer:"",$referring_domain:""}}};this.websocket.send(JSON.stringify(a))}}},{key:"resolveServerID",value:function(a){return a instanceof i?a.id:!isNaN(a)&&a.length&&17===a.length?a:void 0}},{key:"resolveDestination",value:function(a){var b=!1,c=this;return new Promise(function(d,e){if(a instanceof i)b=a.id;else if(a instanceof j)b=a.id;else if(a instanceof k)b=a.channel.id;else if(a instanceof h){var f=!0,g=!1,l=void 0;try{for(var m,n=c.pmChannelCache[Symbol.iterator]();!(f=(m=n.next()).done);f=!0){var o=m.value;if(o.user.equals(a))return o.id}}catch(p){g=!0,l=p}finally{try{!f&&n["return"]&&n["return"]()}finally{if(g)throw l}}c.startPM(a).then(function(a){d(a.id)})["catch"](e)}else b=a;b&&d(b)})}},{key:"_sendMessage",value:function(a,b,c,d){var e=this;return new Promise(function(f,h){n.post(g.CHANNELS+"/"+a+"/messages").set("authorization",e.token).send({content:b,mentions:d,tts:c}).end(function(a,b){if(a)h(a);else{var c=b.body,d=[];c.mentions=c.mentions||[];var g=!0,i=!1,j=void 0;try{for(var l,m=c.mentions[Symbol.iterator]();!(g=(l=m.next()).done);g=!0){var n=l.value;d.push(e.addUser(n))}}catch(a){i=!0,j=a}finally{try{!g&&m["return"]&&m["return"]()}finally{if(i)throw j}}var o=e.getChannel("id",c.channel_id);if(o){var p=o.addMessage(new k(c,o,d,e.addUser(c.author)));f(p)}}})})}},{key:"_sendFile",value:function(a,b){var c=arguments.length<=2||void 0===arguments[2]?"DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png":arguments[2],d=this;return new Promise(function(e,f){n.post(g.CHANNELS+"/"+a+"/messages").set("authorization",d.token).attach("file",b,c).end(function(b,c){if(b)f(b);else{var g=d.getChannel("id",a);if(g){var h=g.addMessage(new k(c.body,g,[],d.user));e(h)}}})})}},{key:"_updateMessage",value:function(a,b){var c=this;return new Promise(function(d,e){n.patch(g.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",c.token).send({content:b,mentions:[]}).end(function(b,c){if(b)e(b);else{var f=new k(c.body,a.channel,a.mentions,a.sender);d(f),a.channel.messages[a.channel.messages.indexOf(a)]=f}})})}},{key:"_deleteMessage",value:function(a){var b=this;return new Promise(function(c,d){n.del(g.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",b.token).end(function(a,b){a?d(a):c()})})}},{key:"checkQueue",value:function(a){var b=this,c=this;this.checkingQueue[a]||!function(){var d=function f(){if(0===c.queue[a].length)return void e();var b=c.queue[a][0];switch(b.action){case"sendMessage":var d=b;c._sendMessage(a,d.content,d.tts,d.mentions).then(function(b){d.then(b),c.queue[a].shift(),f()})["catch"](function(b){d.error(b),c.queue[a].shift(),f()});break;case"sendFile":var g=b;c._sendFile(a,g.attachment,g.attachmentName).then(function(b){g.then(b),c.queue[a].shift(),f()})["catch"](function(b){g.error(b),c.queue[a].shift(),f()});break;case"updateMessage":var h=b;c._updateMessage(h.message,h.content).then(function(b){h.then(b),c.queue[a].shift(),f()})["catch"](function(b){h.error(b),c.queue[a].shift(),f()});break;case"deleteMessage":var i=b;c._deleteMessage(i.message).then(function(b){i.then(b),c.queue[a].shift(),f()})["catch"](function(b){i.error(b),c.queue[a].shift(),f()});break;default:e()}},e=function(){c.checkingQueue[a]=!1};b.checkingQueue[a]=!0,d()}()}},{key:"uptime",get:function(){return this.readyTime?Date.now()-this.readyTime:null}},{key:"ready",get:function(){return 3===this.state}},{key:"servers",get:function(){return this.serverCache}},{key:"channels",get:function(){return this.channelCache}},{key:"users",get:function(){return this.userCache}},{key:"PMChannels",get:function(){return this.pmChannelCache}},{key:"messages",get:function(){var a=[],b=!0,c=!1,d=void 0;try{for(var e,f=this.channelCache[Symbol.iterator]();!(b=(e=f.next()).done);b=!0){var g=e.value;a=a.concat(g.messages)}}catch(h){c=!0,d=h}finally{try{!b&&f["return"]&&f["return"]()}finally{if(c)throw d}}return a}}]),a}();b.exports=r},{"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,fs:10,superagent:11,ws:14}],2:[function(a,b,c){"use strict";c.BASE_DOMAIN="discordapp.com",c.BASE="https://"+c.BASE_DOMAIN,c.WEBSOCKET_HUB="wss://"+c.BASE_DOMAIN+"/hub",c.API=c.BASE+"/api",c.AUTH=c.API+"/auth",c.LOGIN=c.AUTH+"/login",c.LOGOUT=c.AUTH+"/logout",c.USERS=c.API+"/users",c.SERVERS=c.API+"/guilds",c.CHANNELS=c.API+"/channels"},{}],3:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c"}},{key:"toString",value:function(){return this.mention()}},{key:"equals",value:function(a){return a.id===this.id}},{key:"equalsStrict",value:function(a){return a.id===this.id&&a.avatar===this.avatar&&a.username===this.username&&a.discriminator===this.discriminator}},{key:"avatarURL",get:function(){return this.avatar?"https://discordapp.com/api/users/"+this.id+"/avatars/"+this.avatar+".jpg":null}}]),a}();b.exports=f},{}],10:[function(a,b,c){},{}],11:[function(a,b,c){function d(){}function e(a){var b={}.toString.call(a);switch(b){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function f(a){return a===Object(a)}function g(a){if(!f(a))return a;var b=[];for(var c in a)null!=a[c]&&b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")}function h(a){for(var b,c,d={},e=a.split("&"),f=0,g=e.length;g>f;++f)c=e[f],b=c.split("="),d[decodeURIComponent(b[0])]=decodeURIComponent(b[1]);return d}function i(a){var b,c,d,e,f=a.split(/\r?\n/),g={};f.pop();for(var h=0,i=f.length;i>h;++h)c=f[h],b=c.indexOf(":"),d=c.slice(0,b).toLowerCase(),e=r(c.slice(b+1)),g[d]=e;return g}function j(a){return a.split(/ *; */).shift()}function k(a){return p(a.split(/ *; */),function(a,b){var c=b.split(/ *= */),d=c.shift(),e=c.shift();return d&&e&&(a[d]=e),a},{})}function l(a,b){b=b||{},this.req=a,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=i(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function m(a,b){var c=this;o.call(this),this._query=this._query||[],this.method=a,this.url=b,this.header={},this._header={},this.on("end",function(){var a=null,b=null;try{b=new l(c)}catch(d){return a=new Error("Parser is unable to parse the response"),a.parse=!0,a.original=d,c.callback(a)}if(c.emit("response",b),a)return c.callback(a,b);if(b.status>=200&&b.status<300)return c.callback(a,b);var e=new Error(b.statusText||"Unsuccessful HTTP response");e.original=a,e.response=b,e.status=b.status,c.callback(e,b)})}function n(a,b){return"function"==typeof b?new m("GET",a).end(b):1==arguments.length?new m("GET",a):new m(a,b)}var o=a("emitter"),p=a("reduce"),q="undefined"==typeof window?this||self:window;n.getXHR=function(){if(!(!q.XMLHttpRequest||q.location&&"file:"==q.location.protocol&&q.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(a){}return!1};var r="".trim?function(a){return a.trim()}:function(a){return a.replace(/(^\s*|\s*$)/g,"")};n.serializeObject=g,n.parseString=h,n.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},n.serialize={"application/x-www-form-urlencoded":g,"application/json":JSON.stringify},n.parse={"application/x-www-form-urlencoded":h,"application/json":JSON.parse},l.prototype.get=function(a){return this.header[a.toLowerCase()]},l.prototype.setHeaderProperties=function(a){var b=this.header["content-type"]||"";this.type=j(b);var c=k(b);for(var d in c)this[d]=c[d]},l.prototype.parseBody=function(a){var b=n.parse[this.type];return b&&a&&(a.length||a instanceof Object)?b(a):null},l.prototype.setStatusProperties=function(a){1223===a&&(a=204);var b=a/100|0;this.status=a,this.statusType=b,this.info=1==b,this.ok=2==b,this.clientError=4==b,this.serverError=5==b,this.error=4==b||5==b?this.toError():!1,this.accepted=202==a,this.noContent=204==a,this.badRequest=400==a,this.unauthorized=401==a,this.notAcceptable=406==a,this.notFound=404==a,this.forbidden=403==a},l.prototype.toError=function(){var a=this.req,b=a.method,c=a.url,d="cannot "+b+" "+c+" ("+this.status+")",e=new Error(d);return e.status=this.status,e.method=b,e.url=c,e},n.Response=l,o(m.prototype),m.prototype.use=function(a){return a(this),this},m.prototype.timeout=function(a){return this._timeout=a,this},m.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},m.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0,this.xhr.abort(),
+this.clearTimeout(),this.emit("abort"),this)},m.prototype.set=function(a,b){if(f(a)){for(var c in a)this.set(c,a[c]);return this}return this._header[a.toLowerCase()]=b,this.header[a]=b,this},m.prototype.unset=function(a){return delete this._header[a.toLowerCase()],delete this.header[a],this},m.prototype.getHeader=function(a){return this._header[a.toLowerCase()]},m.prototype.type=function(a){return this.set("Content-Type",n.types[a]||a),this},m.prototype.accept=function(a){return this.set("Accept",n.types[a]||a),this},m.prototype.auth=function(a,b){var c=btoa(a+":"+b);return this.set("Authorization","Basic "+c),this},m.prototype.query=function(a){return"string"!=typeof a&&(a=g(a)),a&&this._query.push(a),this},m.prototype.field=function(a,b){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b),this},m.prototype.attach=function(a,b,c){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b,c),this},m.prototype.send=function(a){var b=f(a),c=this.getHeader("Content-Type");if(b&&f(this._data))for(var d in a)this._data[d]=a[d];else"string"==typeof a?(c||this.type("form"),c=this.getHeader("Content-Type"),"application/x-www-form-urlencoded"==c?this._data=this._data?this._data+"&"+a:a:this._data=(this._data||"")+a):this._data=a;return!b||e(a)?this:(c||this.type("json"),this)},m.prototype.callback=function(a,b){var c=this._callback;this.clearTimeout(),c(a,b)},m.prototype.crossDomainError=function(){var a=new Error("Origin is not allowed by Access-Control-Allow-Origin");a.crossDomain=!0,this.callback(a)},m.prototype.timeoutError=function(){var a=this._timeout,b=new Error("timeout of "+a+"ms exceeded");b.timeout=a,this.callback(b)},m.prototype.withCredentials=function(){return this._withCredentials=!0,this},m.prototype.end=function(a){var b=this,c=this.xhr=n.getXHR(),f=this._query.join("&"),g=this._timeout,h=this._formData||this._data;this._callback=a||d,c.onreadystatechange=function(){if(4==c.readyState){var a;try{a=c.status}catch(d){a=0}if(0==a){if(b.timedout)return b.timeoutError();if(b.aborted)return;return b.crossDomainError()}b.emit("end")}};var i=function(a){a.total>0&&(a.percent=a.loaded/a.total*100),b.emit("progress",a)};this.hasListeners("progress")&&(c.onprogress=i);try{c.upload&&this.hasListeners("progress")&&(c.upload.onprogress=i)}catch(j){}if(g&&!this._timer&&(this._timer=setTimeout(function(){b.timedout=!0,b.abort()},g)),f&&(f=n.serializeObject(f),this.url+=~this.url.indexOf("?")?"&"+f:"?"+f),c.open(this.method,this.url,!0),this._withCredentials&&(c.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof h&&!e(h)){var k=this.getHeader("Content-Type"),l=n.serialize[k?k.split(";")[0]:""];l&&(h=l(h))}for(var m in this.header)null!=this.header[m]&&c.setRequestHeader(m,this.header[m]);return this.emit("request",this),c.send(h),this},m.prototype.then=function(a,b){return this.end(function(c,d){c?b(c):a(d)})},n.Request=m,n.get=function(a,b,c){var d=n("GET",a);return"function"==typeof b&&(c=b,b=null),b&&d.query(b),c&&d.end(c),d},n.head=function(a,b,c){var d=n("HEAD",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.del=function(a,b){var c=n("DELETE",a);return b&&c.end(b),c},n.patch=function(a,b,c){var d=n("PATCH",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.post=function(a,b,c){var d=n("POST",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.put=function(a,b,c){var d=n("PUT",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},b.exports=n},{emitter:12,reduce:13}],12:[function(a,b,c){function d(a){return a?e(a):void 0}function e(a){for(var b in d.prototype)a[b]=d.prototype[b];return a}b.exports=d,d.prototype.on=d.prototype.addEventListener=function(a,b){return this._callbacks=this._callbacks||{},(this._callbacks[a]=this._callbacks[a]||[]).push(b),this},d.prototype.once=function(a,b){function c(){d.off(a,c),b.apply(this,arguments)}var d=this;return this._callbacks=this._callbacks||{},c.fn=b,this.on(a,c),this},d.prototype.off=d.prototype.removeListener=d.prototype.removeAllListeners=d.prototype.removeEventListener=function(a,b){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var c=this._callbacks[a];if(!c)return this;if(1==arguments.length)return delete this._callbacks[a],this;for(var d,e=0;ed;++d)c[d].apply(this,b)}return this},d.prototype.listeners=function(a){return this._callbacks=this._callbacks||{},this._callbacks[a]||[]},d.prototype.hasListeners=function(a){return!!this.listeners(a).length}},{}],13:[function(a,b,c){b.exports=function(a,b,c){for(var d=0,e=a.length,f=3==arguments.length?c:a[d++];e>d;)f=b.call(null,f,a[d],++d,a);return f}},{}],14:[function(a,b,c){function d(a,b,c){var d;return d=b?new f(a,b):new f(a)}var e=function(){return this}(),f=e.WebSocket||e.MozWebSocket;b.exports=f?d:null,f&&(d.prototype=f.prototype)},{}]},{},[5])(5)});
\ No newline at end of file
diff --git a/web-dist/discord.min.3.3.2.js b/web-dist/discord.min.3.3.2.js
new file mode 100644
index 000000000..9a41bcaad
--- /dev/null
+++ b/web-dist/discord.min.3.3.2.js
@@ -0,0 +1,2 @@
+!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Discord=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g]*>/g)||[])[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;a.push(h.substring(2,h.length-1))}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return a}"function"==typeof c&&(d=c,c=!1),b=e+n(b);var p=o();f.resolveDestination(a).then(k)["catch"](j)});return g}},{key:"createws",value:function(a){if(this.websocket)return!1;var b=this;this.websocket=new o(a),this.websocket.onopen=function(){b.trySendConnData()},this.websocket.onclose=function(){b.trigger("disconnected")},this.websocket.onmessage=function(a){var c=!1,d={};try{c=JSON.parse(a.data),d=c.d}catch(e){return void b.trigger("error",e,a)}switch(c.t){case"READY":b.debug("received ready packet"),b.user=b.addUser(d.user);var f=!0,g=!1,i=void 0;try{for(var j,l=d.guilds[Symbol.iterator]();!(f=(j=l.next()).done);f=!0)var m=j.value,n=b.addServer(m)}catch(e){g=!0,i=e}finally{try{!f&&l["return"]&&l["return"]()}finally{if(g)throw i}}var o=!0,p=!1,q=void 0;try{for(var r,s=d.private_channels[Symbol.iterator]();!(o=(r=s.next()).done);o=!0){var t=r.value;b.addPMChannel(t)}}catch(e){p=!0,q=e}finally{try{!o&&s["return"]&&s["return"]()}finally{if(p)throw q}}b.trigger("ready"),b.readyTime=Date.now(),b.debug("cached "+b.serverCache.length+" servers, "+b.channelCache.length+" channels, "+b.pmChannelCache.length+" PMs and "+b.userCache.length+" users."),b.state=3,setInterval(function(){b.keepAlive.apply(b)},d.heartbeat_interval);break;case"MESSAGE_CREATE":b.debug("received message");var u=[];d.mentions=d.mentions||[];var v=!0,w=!1,x=void 0;try{for(var y,z=d.mentions[Symbol.iterator]();!(v=(y=z.next()).done);v=!0){var A=y.value;u.push(b.addUser(A))}}catch(e){w=!0,x=e}finally{try{!v&&z["return"]&&z["return"]()}finally{if(w)throw x}}var B=b.getChannel("id",d.channel_id);if(B){var C=B.addMessage(new k(d,B,u,b.addUser(d.author)));b.trigger("message",C)}break;case"MESSAGE_DELETE":b.debug("message deleted");var B=b.getChannel("id",d.channel_id),D=B.getMessage("id",d.id);D?(b.trigger("messageDelete",B,D),B.messages.splice(B.messages.indexOf(D),1)):b.trigger("messageDelete",B);break;case"MESSAGE_UPDATE":b.debug("message updated");var B=b.getChannel("id",d.channel_id),E=B.getMessage("id",d.id);if(E){var F={};for(var G in E)F[G]=E[G];for(var G in d)F[G]=d[G];var u=[],H=!0,I=!1,J=void 0;try{for(var K,L=F.mentions[Symbol.iterator]();!(H=(K=L.next()).done);H=!0){var A=K.value;u.push(b.addUser(A))}}catch(e){I=!0,J=e}finally{try{!H&&L["return"]&&L["return"]()}finally{if(I)throw J}}var M=new k(F,B,u,E.author);b.trigger("messageUpdate",M,E),B.messages[B.messages.indexOf(E)]=M}break;case"GUILD_DELETE":var n=b.getServer("id",d.id);n&&(b.serverCache.splice(b.serverCache.indexOf(n),1),b.trigger("serverDelete",n));break;case"CHANNEL_DELETE":var B=b.getChannel("id",d.id);if(B){var n=B.server;n&&n.channels.splice(n.channels.indexOf(B),1),b.trigger("channelDelete",B),b.serverCache.splice(b.serverCache.indexOf(B),1)}break;case"GUILD_CREATE":var n=b.getServer("id",d.id);if(n||(n=b.addServer(d)),b.serverCreateListener.get(d.id)){var N=b.serverCreateListener.get(d.id);N[0](n),N[1](null,n),b.serverCreateListener["delete"](d.id)}b.trigger("serverCreate",n);break;case"CHANNEL_CREATE":var B=b.getChannel("id",d.id);if(!B){var O=b.addChannel(d,d.guild_id),P=b.getServer("id",d.guild_id);P&&P.addChannel(O),b.trigger("channelCreate",O)}break;case"GUILD_MEMBER_ADD":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)||n.members.push(Q),b.trigger("serverNewMember",Q,n)}break;case"GUILD_MEMBER_REMOVE":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)&&n.members.splice(n.members.indexOf(Q),1),b.trigger("serverRemoveMember",Q,n)}break;case"USER_UPDATE":if(b.user&&d.id===b.user.id){var R=new h(d);b.trigger("userUpdate",R,b.user),~b.userCache.indexOf(b.user)&&(b.userCache[b.userCache.indexOf(b.user)]=R),b.user=R}break;case"PRESENCE_UPDATE":var S=b.getUser("id",d.user.id);if(S){var T=new h(d.user);T.equalsStrict(S)?b.trigger("presence",{user:S,status:d.status,server:b.getServer("id",d.guild_id),gameId:d.game_id}):(b.trigger("userUpdate",S,T),b.userCache[b.userCache.indexOf(S)]=T)}break;default:b.debug("received unknown packet"),b.trigger("unknown",c)}}}},{key:"addUser",value:function(a){return this.getUser("id",a.id)||this.userCache.push(new h(a)),this.getUser("id",a.id)}},{key:"addChannel",value:function(a,b){return this.getChannel("id",a.id)||this.channelCache.push(new j(a,this.getServer("id",b))),this.getChannel("id",a.id)}},{key:"addPMChannel",value:function(a){return this.getPMChannel("id",a.id)||this.pmChannelCache.push(new m(a,this)),this.getPMChannel("id",a.id)}},{key:"addServer",value:function(a){var b=this.getServer("id",a.id);if(!b&&(b=new i(a,this),this.serverCache.push(b),a.channels)){var c=!0,d=!1,e=void 0;try{for(var f,g=a.channels[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;b.channels.push(this.addChannel(h,b.id))}}catch(j){d=!0,e=j}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}}return b}},{key:"getUser",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.userCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.channelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return this.getPMChannel(a,b)}},{key:"getPMChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.pmChannelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getServer",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.serverCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"trySendConnData",value:function(){if(this.token&&!this.alreadySentData){this.alreadySentData=!0;var a={op:2,d:{token:this.token,v:2,properties:{$os:"discord.js",$browser:"discord.js",$device:"discord.js",$referrer:"",$referring_domain:""}}};this.websocket.send(JSON.stringify(a))}}},{key:"resolveServerID",value:function(a){return a instanceof i?a.id:!isNaN(a)&&a.length&&17===a.length?a:void 0}},{key:"resolveDestination",value:function(a){var b=!1,c=this;return new Promise(function(d,e){if(a instanceof i)b=a.id;else if(a instanceof j)b=a.id;else if(a instanceof k)b=a.channel.id;else if(a instanceof h){var f=!0,g=!1,l=void 0;try{for(var m,n=c.pmChannelCache[Symbol.iterator]();!(f=(m=n.next()).done);f=!0){var o=m.value;if(o.user.equals(a))return void d(o.id)}}catch(p){g=!0,l=p}finally{try{!f&&n["return"]&&n["return"]()}finally{if(g)throw l}}c.startPM(a).then(function(a){console.log(a),d(a.id)})["catch"](e)}else b=a;b&&d(b)})}},{key:"_sendMessage",value:function(a,b,c,d){var e=this;return new Promise(function(f,h){n.post(g.CHANNELS+"/"+a+"/messages").set("authorization",e.token).send({content:b,mentions:d,tts:c}).end(function(a,b){if(a)h(a);else{var c=b.body,d=[];c.mentions=c.mentions||[];var g=!0,i=!1,j=void 0;try{for(var l,m=c.mentions[Symbol.iterator]();!(g=(l=m.next()).done);g=!0){var n=l.value;d.push(e.addUser(n))}}catch(a){i=!0,j=a}finally{try{!g&&m["return"]&&m["return"]()}finally{if(i)throw j}}var o=e.getChannel("id",c.channel_id);if(o){var p=o.addMessage(new k(c,o,d,e.addUser(c.author)));f(p)}}})})}},{key:"_sendFile",value:function(a,b){var c=arguments.length<=2||void 0===arguments[2]?"DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png":arguments[2],d=this;return new Promise(function(e,f){n.post(g.CHANNELS+"/"+a+"/messages").set("authorization",d.token).attach("file",b,c).end(function(b,c){if(b)f(b);else{var g=d.getChannel("id",a);if(g){var h=g.addMessage(new k(c.body,g,[],d.user));e(h)}}})})}},{key:"_updateMessage",value:function(a,b){var c=this;return new Promise(function(d,e){n.patch(g.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",c.token).send({content:b,mentions:[]}).end(function(b,c){if(b)e(b);else{var f=new k(c.body,a.channel,a.mentions,a.sender);d(f),a.channel.messages[a.channel.messages.indexOf(a)]=f}})})}},{key:"_deleteMessage",value:function(a){var b=this;return new Promise(function(c,d){n.del(g.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",b.token).end(function(a,b){a?d(a):c()})})}},{key:"checkQueue",value:function(a){var b=this,c=this;this.checkingQueue[a]||!function(){var d=function f(){if(0===c.queue[a].length)return void e();var b=c.queue[a][0];switch(b.action){case"sendMessage":var d=b;c._sendMessage(a,d.content,d.tts,d.mentions).then(function(b){d.then(b),c.queue[a].shift(),f()})["catch"](function(b){d.error(b),c.queue[a].shift(),f()});break;case"sendFile":var g=b;c._sendFile(a,g.attachment,g.attachmentName).then(function(b){g.then(b),c.queue[a].shift(),f()})["catch"](function(b){g.error(b),c.queue[a].shift(),f()});break;case"updateMessage":var h=b;c._updateMessage(h.message,h.content).then(function(b){h.then(b),c.queue[a].shift(),f()})["catch"](function(b){h.error(b),c.queue[a].shift(),f()});break;case"deleteMessage":var i=b;c._deleteMessage(i.message).then(function(b){i.then(b),c.queue[a].shift(),f()})["catch"](function(b){i.error(b),c.queue[a].shift(),f()});break;default:e()}},e=function(){c.checkingQueue[a]=!1};b.checkingQueue[a]=!0,d()}()}},{key:"uptime",get:function(){return this.readyTime?Date.now()-this.readyTime:null}},{key:"ready",get:function(){return 3===this.state}},{key:"servers",get:function(){return this.serverCache}},{key:"channels",get:function(){return this.channelCache}},{key:"users",get:function(){return this.userCache}},{key:"PMChannels",get:function(){return this.pmChannelCache}},{key:"messages",get:function(){var a=[],b=!0,c=!1,d=void 0;try{for(var e,f=this.channelCache[Symbol.iterator]();!(b=(e=f.next()).done);b=!0){var g=e.value;a=a.concat(g.messages)}}catch(h){c=!0,d=h}finally{try{!b&&f["return"]&&f["return"]()}finally{if(c)throw d}}return a}}]),a}();b.exports=r},{"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,fs:10,superagent:11,ws:14}],2:[function(a,b,c){"use strict";c.BASE_DOMAIN="discordapp.com",c.BASE="https://"+c.BASE_DOMAIN,c.WEBSOCKET_HUB="wss://"+c.BASE_DOMAIN+"/hub",c.API=c.BASE+"/api",c.AUTH=c.API+"/auth",c.LOGIN=c.AUTH+"/login",c.LOGOUT=c.AUTH+"/logout",c.USERS=c.API+"/users",c.SERVERS=c.API+"/guilds",c.CHANNELS=c.API+"/channels"},{}],3:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c"}},{key:"toString",value:function(){return this.mention()}},{key:"equals",value:function(a){return a.id===this.id}},{key:"equalsStrict",value:function(a){return a.id===this.id&&a.avatar===this.avatar&&a.username===this.username&&a.discriminator===this.discriminator}},{key:"avatarURL",get:function(){return this.avatar?"https://discordapp.com/api/users/"+this.id+"/avatars/"+this.avatar+".jpg":null}}]),a}();b.exports=f},{}],10:[function(a,b,c){},{}],11:[function(a,b,c){function d(){}function e(a){var b={}.toString.call(a);switch(b){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function f(a){return a===Object(a)}function g(a){if(!f(a))return a;var b=[];for(var c in a)null!=a[c]&&b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")}function h(a){for(var b,c,d={},e=a.split("&"),f=0,g=e.length;g>f;++f)c=e[f],b=c.split("="),d[decodeURIComponent(b[0])]=decodeURIComponent(b[1]);return d}function i(a){var b,c,d,e,f=a.split(/\r?\n/),g={};f.pop();for(var h=0,i=f.length;i>h;++h)c=f[h],b=c.indexOf(":"),d=c.slice(0,b).toLowerCase(),e=r(c.slice(b+1)),g[d]=e;return g}function j(a){return a.split(/ *; */).shift()}function k(a){return p(a.split(/ *; */),function(a,b){var c=b.split(/ *= */),d=c.shift(),e=c.shift();return d&&e&&(a[d]=e),a},{})}function l(a,b){b=b||{},this.req=a,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=i(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function m(a,b){var c=this;o.call(this),this._query=this._query||[],this.method=a,this.url=b,this.header={},this._header={},this.on("end",function(){var a=null,b=null;try{b=new l(c)}catch(d){return a=new Error("Parser is unable to parse the response"),a.parse=!0,a.original=d,c.callback(a)}if(c.emit("response",b),a)return c.callback(a,b);if(b.status>=200&&b.status<300)return c.callback(a,b);var e=new Error(b.statusText||"Unsuccessful HTTP response");e.original=a,e.response=b,e.status=b.status,c.callback(e,b)})}function n(a,b){return"function"==typeof b?new m("GET",a).end(b):1==arguments.length?new m("GET",a):new m(a,b)}var o=a("emitter"),p=a("reduce"),q="undefined"==typeof window?this||self:window;n.getXHR=function(){if(!(!q.XMLHttpRequest||q.location&&"file:"==q.location.protocol&&q.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(a){}return!1};var r="".trim?function(a){return a.trim()}:function(a){return a.replace(/(^\s*|\s*$)/g,"")};n.serializeObject=g,n.parseString=h,n.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},n.serialize={"application/x-www-form-urlencoded":g,"application/json":JSON.stringify},n.parse={"application/x-www-form-urlencoded":h,"application/json":JSON.parse},l.prototype.get=function(a){return this.header[a.toLowerCase()]},l.prototype.setHeaderProperties=function(a){var b=this.header["content-type"]||"";this.type=j(b);var c=k(b);for(var d in c)this[d]=c[d]},l.prototype.parseBody=function(a){var b=n.parse[this.type];return b&&a&&(a.length||a instanceof Object)?b(a):null},l.prototype.setStatusProperties=function(a){1223===a&&(a=204);var b=a/100|0;this.status=a,this.statusType=b,this.info=1==b,this.ok=2==b,this.clientError=4==b,this.serverError=5==b,this.error=4==b||5==b?this.toError():!1,this.accepted=202==a,this.noContent=204==a,this.badRequest=400==a,this.unauthorized=401==a,this.notAcceptable=406==a,this.notFound=404==a,this.forbidden=403==a},l.prototype.toError=function(){var a=this.req,b=a.method,c=a.url,d="cannot "+b+" "+c+" ("+this.status+")",e=new Error(d);return e.status=this.status,e.method=b,e.url=c,e},n.Response=l,o(m.prototype),m.prototype.use=function(a){return a(this),this},m.prototype.timeout=function(a){return this._timeout=a,this},m.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},m.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0,
+this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this)},m.prototype.set=function(a,b){if(f(a)){for(var c in a)this.set(c,a[c]);return this}return this._header[a.toLowerCase()]=b,this.header[a]=b,this},m.prototype.unset=function(a){return delete this._header[a.toLowerCase()],delete this.header[a],this},m.prototype.getHeader=function(a){return this._header[a.toLowerCase()]},m.prototype.type=function(a){return this.set("Content-Type",n.types[a]||a),this},m.prototype.accept=function(a){return this.set("Accept",n.types[a]||a),this},m.prototype.auth=function(a,b){var c=btoa(a+":"+b);return this.set("Authorization","Basic "+c),this},m.prototype.query=function(a){return"string"!=typeof a&&(a=g(a)),a&&this._query.push(a),this},m.prototype.field=function(a,b){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b),this},m.prototype.attach=function(a,b,c){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b,c),this},m.prototype.send=function(a){var b=f(a),c=this.getHeader("Content-Type");if(b&&f(this._data))for(var d in a)this._data[d]=a[d];else"string"==typeof a?(c||this.type("form"),c=this.getHeader("Content-Type"),"application/x-www-form-urlencoded"==c?this._data=this._data?this._data+"&"+a:a:this._data=(this._data||"")+a):this._data=a;return!b||e(a)?this:(c||this.type("json"),this)},m.prototype.callback=function(a,b){var c=this._callback;this.clearTimeout(),c(a,b)},m.prototype.crossDomainError=function(){var a=new Error("Origin is not allowed by Access-Control-Allow-Origin");a.crossDomain=!0,this.callback(a)},m.prototype.timeoutError=function(){var a=this._timeout,b=new Error("timeout of "+a+"ms exceeded");b.timeout=a,this.callback(b)},m.prototype.withCredentials=function(){return this._withCredentials=!0,this},m.prototype.end=function(a){var b=this,c=this.xhr=n.getXHR(),f=this._query.join("&"),g=this._timeout,h=this._formData||this._data;this._callback=a||d,c.onreadystatechange=function(){if(4==c.readyState){var a;try{a=c.status}catch(d){a=0}if(0==a){if(b.timedout)return b.timeoutError();if(b.aborted)return;return b.crossDomainError()}b.emit("end")}};var i=function(a){a.total>0&&(a.percent=a.loaded/a.total*100),b.emit("progress",a)};this.hasListeners("progress")&&(c.onprogress=i);try{c.upload&&this.hasListeners("progress")&&(c.upload.onprogress=i)}catch(j){}if(g&&!this._timer&&(this._timer=setTimeout(function(){b.timedout=!0,b.abort()},g)),f&&(f=n.serializeObject(f),this.url+=~this.url.indexOf("?")?"&"+f:"?"+f),c.open(this.method,this.url,!0),this._withCredentials&&(c.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof h&&!e(h)){var k=this.getHeader("Content-Type"),l=n.serialize[k?k.split(";")[0]:""];l&&(h=l(h))}for(var m in this.header)null!=this.header[m]&&c.setRequestHeader(m,this.header[m]);return this.emit("request",this),c.send(h),this},m.prototype.then=function(a,b){return this.end(function(c,d){c?b(c):a(d)})},n.Request=m,n.get=function(a,b,c){var d=n("GET",a);return"function"==typeof b&&(c=b,b=null),b&&d.query(b),c&&d.end(c),d},n.head=function(a,b,c){var d=n("HEAD",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.del=function(a,b){var c=n("DELETE",a);return b&&c.end(b),c},n.patch=function(a,b,c){var d=n("PATCH",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.post=function(a,b,c){var d=n("POST",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.put=function(a,b,c){var d=n("PUT",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},b.exports=n},{emitter:12,reduce:13}],12:[function(a,b,c){function d(a){return a?e(a):void 0}function e(a){for(var b in d.prototype)a[b]=d.prototype[b];return a}b.exports=d,d.prototype.on=d.prototype.addEventListener=function(a,b){return this._callbacks=this._callbacks||{},(this._callbacks[a]=this._callbacks[a]||[]).push(b),this},d.prototype.once=function(a,b){function c(){d.off(a,c),b.apply(this,arguments)}var d=this;return this._callbacks=this._callbacks||{},c.fn=b,this.on(a,c),this},d.prototype.off=d.prototype.removeListener=d.prototype.removeAllListeners=d.prototype.removeEventListener=function(a,b){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var c=this._callbacks[a];if(!c)return this;if(1==arguments.length)return delete this._callbacks[a],this;for(var d,e=0;ed;++d)c[d].apply(this,b)}return this},d.prototype.listeners=function(a){return this._callbacks=this._callbacks||{},this._callbacks[a]||[]},d.prototype.hasListeners=function(a){return!!this.listeners(a).length}},{}],13:[function(a,b,c){b.exports=function(a,b,c){for(var d=0,e=a.length,f=3==arguments.length?c:a[d++];e>d;)f=b.call(null,f,a[d],++d,a);return f}},{}],14:[function(a,b,c){function d(a,b,c){var d;return d=b?new f(a,b):new f(a)}var e=function(){return this}(),f=e.WebSocket||e.MozWebSocket;b.exports=f?d:null,f&&(d.prototype=f.prototype)},{}]},{},[5])(5)});
\ No newline at end of file
diff --git a/web-dist/discord.min.3.4.0.js b/web-dist/discord.min.3.4.0.js
new file mode 100644
index 000000000..9028bea6a
--- /dev/null
+++ b/web-dist/discord.min.3.4.0.js
@@ -0,0 +1,2 @@
+!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Discord=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g]*>/g)||[])[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;a.push(h.substring(2,h.length-1))}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return a}"function"==typeof c&&(d=c,c=!1),b=e+n(b);var p=o();f.resolveDestination(a).then(k)["catch"](j)});return g}},{key:"createws",value:function(a){if(this.websocket)return!1;var b=this;this.websocket=new n(a),this.websocket.onopen=function(){b.trySendConnData()},this.websocket.onclose=function(){b.trigger("disconnected")},this.websocket.onmessage=function(a){var c=!1,d={};try{c=JSON.parse(a.data),d=c.d}catch(e){return void b.trigger("error",e,a)}switch(c.t){case"READY":b.debug("received ready packet"),b.user=b.addUser(d.user);var f=!0,h=!1,i=void 0;try{for(var k,l=d.guilds[Symbol.iterator]();!(f=(k=l.next()).done);f=!0)var m=k.value,n=b.addServer(m)}catch(e){h=!0,i=e}finally{try{!f&&l["return"]&&l["return"]()}finally{if(h)throw i}}var o=!0,p=!1,q=void 0;try{for(var r,s=d.private_channels[Symbol.iterator]();!(o=(r=s.next()).done);o=!0){var t=r.value;b.addPMChannel(t)}}catch(e){p=!0,q=e}finally{try{!o&&s["return"]&&s["return"]()}finally{if(p)throw q}}b.trigger("ready"),b.readyTime=Date.now(),b.debug("cached "+b.serverCache.length+" servers, "+b.channelCache.length+" channels, "+b.pmChannelCache.length+" PMs and "+b.userCache.length+" users."),b.state=3,setInterval(function(){b.keepAlive.apply(b)},d.heartbeat_interval);break;case"MESSAGE_CREATE":b.debug("received message");var u=[];d.mentions=d.mentions||[];var v=!0,w=!1,x=void 0;try{for(var y,z=d.mentions[Symbol.iterator]();!(v=(y=z.next()).done);v=!0){var A=y.value;u.push(b.addUser(A))}}catch(e){w=!0,x=e}finally{try{!v&&z["return"]&&z["return"]()}finally{if(w)throw x}}var B=b.getChannel("id",d.channel_id);if(B){var C=B.addMessage(new j(d,B,u,b.addUser(d.author)));b.trigger("message",C)}break;case"MESSAGE_DELETE":b.debug("message deleted");var B=b.getChannel("id",d.channel_id),D=B.getMessage("id",d.id);D?(b.trigger("messageDelete",B,D),B.messages.splice(B.messages.indexOf(D),1)):b.trigger("messageDelete",B);break;case"MESSAGE_UPDATE":b.debug("message updated");var B=b.getChannel("id",d.channel_id),E=B.getMessage("id",d.id);if(E){var F={};for(var G in E)F[G]=E[G];for(var G in d)F[G]=d[G];var u=[],H=!0,I=!1,J=void 0;try{for(var K,L=F.mentions[Symbol.iterator]();!(H=(K=L.next()).done);H=!0){var A=K.value;u.push(b.addUser(A))}}catch(e){I=!0,J=e}finally{try{!H&&L["return"]&&L["return"]()}finally{if(I)throw J}}var M=new j(F,B,u,E.author);b.trigger("messageUpdate",M,E),B.messages[B.messages.indexOf(E)]=M}break;case"GUILD_DELETE":var n=b.getServer("id",d.id);n&&(b.serverCache.splice(b.serverCache.indexOf(n),1),b.trigger("serverDelete",n));break;case"CHANNEL_DELETE":var B=b.getChannel("id",d.id);if(B){var n=B.server;n&&n.channels.splice(n.channels.indexOf(B),1),b.trigger("channelDelete",B),b.serverCache.splice(b.serverCache.indexOf(B),1)}break;case"GUILD_CREATE":var n=b.getServer("id",d.id);if(n||(n=b.addServer(d)),b.serverCreateListener[d.id]){var N=b.serverCreateListener[d.id];N[0](n),N[1](null,n),b.serverCreateListener[d.id]=null}b.trigger("serverCreate",n);break;case"CHANNEL_CREATE":var B=b.getChannel("id",d.id);if(!B){var O=b.addChannel(d,d.guild_id),P=b.getServer("id",d.guild_id);P&&P.addChannel(O),b.trigger("channelCreate",O)}break;case"GUILD_MEMBER_ADD":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)||n.members.push(Q),b.trigger("serverNewMember",Q,n)}break;case"GUILD_MEMBER_REMOVE":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)&&n.members.splice(n.members.indexOf(Q),1),b.trigger("serverRemoveMember",Q,n)}break;case"USER_UPDATE":if(b.user&&d.id===b.user.id){var R=new g(d);b.trigger("userUpdate",R,b.user),~b.userCache.indexOf(b.user)&&(b.userCache[b.userCache.indexOf(b.user)]=R),b.user=R}break;case"PRESENCE_UPDATE":var S=b.getUser("id",d.user.id);if(S){var T=new g(d.user);T.equalsStrict(S)?(S.status=d.status,b.trigger("presence",{user:S,status:d.status,server:b.getServer("id",d.guild_id),gameId:d.game_id})):(b.trigger("userUpdate",S,T),b.userCache[b.userCache.indexOf(S)]=T)}break;default:b.debug("received unknown packet"),b.trigger("unknown",c)}}}},{key:"addUser",value:function(a){return this.getUser("id",a.id)||this.userCache.push(new g(a)),this.getUser("id",a.id)}},{key:"addChannel",value:function(a,b){return this.getChannel("id",a.id)||this.channelCache.push(new i(a,this.getServer("id",b))),this.getChannel("id",a.id)}},{key:"addPMChannel",value:function(a){return this.getPMChannel("id",a.id)||this.pmChannelCache.push(new l(a,this)),this.getPMChannel("id",a.id)}},{key:"addServer",value:function(a){var b=this,c=this.getServer("id",a.id);if(!c&&(c=new h(a,this),this.serverCache.push(c),a.channels)){var d=!0,e=!1,f=void 0;try{for(var g,i=a.channels[Symbol.iterator]();!(d=(g=i.next()).done);d=!0){var j=g.value;c.channels.push(this.addChannel(j,c.id))}}catch(k){e=!0,f=k}finally{try{!d&&i["return"]&&i["return"]()}finally{if(e)throw f}}}var l=!0,m=!1,n=void 0;try{for(var o,p=a.presences[Symbol.iterator]();!(l=(o=p.next()).done);l=!0){var q=o.value;b.getUser("id",q.user.id).status=q.status}}catch(k){m=!0,n=k}finally{try{!l&&p["return"]&&p["return"]()}finally{if(m)throw n}}return c}},{key:"getUser",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.userCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.channelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return this.getPMChannel(a,b)}},{key:"getPMChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.pmChannelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getServer",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.serverCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"trySendConnData",value:function(){if(this.token&&!this.alreadySentData){this.alreadySentData=!0;var a={op:2,d:{token:this.token,v:2,properties:{$os:"discord.js",$browser:"discord.js",$device:"discord.js",$referrer:"",$referring_domain:""}}};this.websocket.send(JSON.stringify(a))}}},{key:"resolveServerID",value:function(a){return a instanceof h?a.id:!isNaN(a)&&a.length&&17===a.length?a:void 0}},{key:"resolveDestination",value:function(a){var b=!1,c=this;return new Promise(function(d,e){if(a instanceof h)b=a.id;else if(a instanceof i)b=a.id;else if(a instanceof j)b=a.channel.id;else if(a instanceof g){var f=!0,k=!1,l=void 0;try{for(var m,n=c.pmChannelCache[Symbol.iterator]();!(f=(m=n.next()).done);f=!0){var o=m.value;if(o.user.equals(a))return void d(o.id)}}catch(p){k=!0,l=p}finally{try{!f&&n["return"]&&n["return"]()}finally{if(k)throw l}}c.startPM(a).then(function(a){console.log(a),d(a.id)})["catch"](e)}else b=a;b&&d(b)})}},{key:"_sendMessage",value:function(a,b,c,d){var e=this;return new Promise(function(g,h){m.post(f.CHANNELS+"/"+a+"/messages").set("authorization",e.token).send({content:b,mentions:d,tts:c}).end(function(a,b){if(a)h(a);else{var c=b.body,d=[];c.mentions=c.mentions||[];var f=!0,i=!1,k=void 0;try{for(var l,m=c.mentions[Symbol.iterator]();!(f=(l=m.next()).done);f=!0){var n=l.value;d.push(e.addUser(n))}}catch(a){i=!0,k=a}finally{try{!f&&m["return"]&&m["return"]()}finally{if(i)throw k}}var o=e.getChannel("id",c.channel_id);if(o){var p=o.addMessage(new j(c,o,d,e.addUser(c.author)));g(p)}}})})}},{key:"_sendFile",value:function(a,b){var c=arguments.length<=2||void 0===arguments[2]?"DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png":arguments[2],d=this;return new Promise(function(e,g){m.post(f.CHANNELS+"/"+a+"/messages").set("authorization",d.token).attach("file",b,c).end(function(b,c){if(b)g(b);else{var f=d.getChannel("id",a);if(f){var h=f.addMessage(new j(c.body,f,[],d.user));e(h)}}})})}},{key:"_updateMessage",value:function(a,b){var c=this;return new Promise(function(d,e){m.patch(f.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",c.token).send({content:b,mentions:[]}).end(function(b,c){if(b)e(b);else{var f=new j(c.body,a.channel,a.mentions,a.sender);d(f),a.channel.messages[a.channel.messages.indexOf(a)]=f}})})}},{key:"_deleteMessage",value:function(a){var b=this;return new Promise(function(c,d){m.del(f.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",b.token).end(function(a,b){a?d(a):c()})})}},{key:"checkQueue",value:function(a){var b=this,c=this;this.checkingQueue[a]||!function(){var d=function f(){if(0===c.queue[a].length)return void e();var b=c.queue[a][0];switch(b.action){case"sendMessage":var d=b;c._sendMessage(a,d.content,d.tts,d.mentions).then(function(b){d.then(b),c.queue[a].shift(),f()})["catch"](function(b){d.error(b),c.queue[a].shift(),f()});break;case"sendFile":var g=b;c._sendFile(a,g.attachment,g.attachmentName).then(function(b){g.then(b),c.queue[a].shift(),f()})["catch"](function(b){g.error(b),c.queue[a].shift(),f()});break;case"updateMessage":var h=b;c._updateMessage(h.message,h.content).then(function(b){h.then(b),c.queue[a].shift(),f()})["catch"](function(b){h.error(b),c.queue[a].shift(),f()});break;case"deleteMessage":var i=b;c._deleteMessage(i.message).then(function(b){i.then(b),c.queue[a].shift(),f()})["catch"](function(b){i.error(b),c.queue[a].shift(),f()});break;default:e()}},e=function(){c.checkingQueue[a]=!1};b.checkingQueue[a]=!0,d()}()}},{key:"getGateway",value:function(){var a=this;return new Promise(function(b,c){m.get(f.API+"/gateway").set("authorization",a.token).end(function(a,d){a?c(a):b(d.body.url)})})}},{key:"uptime",get:function(){return this.readyTime?Date.now()-this.readyTime:null}},{key:"ready",get:function(){return 3===this.state}},{key:"servers",get:function(){return this.serverCache}},{key:"channels",get:function(){return this.channelCache}},{key:"users",get:function(){return this.userCache}},{key:"PMChannels",get:function(){return this.pmChannelCache}},{key:"messages",get:function(){var a=[],b=!0,c=!1,d=void 0;try{for(var e,f=this.channelCache[Symbol.iterator]();!(b=(e=f.next()).done);b=!0){var g=e.value;a=a.concat(g.messages)}}catch(h){c=!0,d=h}finally{try{!b&&f["return"]&&f["return"]()}finally{if(c)throw d}}return a}}]),a}();b.exports=q},{"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,fs:10,superagent:11,ws:14}],2:[function(a,b,c){"use strict";c.BASE_DOMAIN="discordapp.com",c.BASE="https://"+c.BASE_DOMAIN,c.WEBSOCKET_HUB="wss://"+c.BASE_DOMAIN+"/hub",c.API=c.BASE+"/api",c.AUTH=c.API+"/auth",c.LOGIN=c.AUTH+"/login",c.LOGOUT=c.AUTH+"/logout",c.USERS=c.API+"/users",c.SERVERS=c.API+"/guilds",c.CHANNELS=c.API+"/channels"},{}],3:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c1e3&&this.messages.splice(0,1),this.getMessage("id",a.id)||this.messages.push(a),this.getMessage("id",a.id)}},{key:"getMessage",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.messages[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"toString",value:function(){return"<#"+this.id+">"}},{key:"client",get:function(){return this.server.client}},{key:"isPrivate",get:function(){return!1}},{key:"users",get:function(){return this.server.members}},{key:"members",get:function(){return this.server.members}}]),a}();b.exports=f},{}],5:[function(a,b,c){"use strict";var d=(a("superagent"),a("./Endpoints.js")),e=a("./Client.js"),f={Endpoints:d,Client:e};b.exports=f},{"./Client.js":1,"./Endpoints.js":2,superagent:11}],6:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c"}},{key:"toString",value:function(){return this.mention()}},{key:"equals",value:function(a){return a.id===this.id}},{key:"equalsStrict",value:function(a){return a.id===this.id&&a.avatar===this.avatar&&a.username===this.username&&a.discriminator===this.discriminator}},{key:"avatarURL",get:function(){return this.avatar?"https://discordapp.com/api/users/"+this.id+"/avatars/"+this.avatar+".jpg":null}}]),a}();b.exports=f},{}],10:[function(a,b,c){},{}],11:[function(a,b,c){function d(){}function e(a){var b={}.toString.call(a);switch(b){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function f(a){return a===Object(a)}function g(a){if(!f(a))return a;var b=[];for(var c in a)null!=a[c]&&b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")}function h(a){for(var b,c,d={},e=a.split("&"),f=0,g=e.length;g>f;++f)c=e[f],b=c.split("="),d[decodeURIComponent(b[0])]=decodeURIComponent(b[1]);return d}function i(a){var b,c,d,e,f=a.split(/\r?\n/),g={};f.pop();for(var h=0,i=f.length;i>h;++h)c=f[h],b=c.indexOf(":"),d=c.slice(0,b).toLowerCase(),e=r(c.slice(b+1)),g[d]=e;return g}function j(a){return a.split(/ *; */).shift()}function k(a){return p(a.split(/ *; */),function(a,b){var c=b.split(/ *= */),d=c.shift(),e=c.shift();return d&&e&&(a[d]=e),a},{})}function l(a,b){b=b||{},this.req=a,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=i(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function m(a,b){var c=this;o.call(this),this._query=this._query||[],this.method=a,this.url=b,this.header={},this._header={},this.on("end",function(){var a=null,b=null;try{b=new l(c)}catch(d){return a=new Error("Parser is unable to parse the response"),a.parse=!0,a.original=d,c.callback(a)}if(c.emit("response",b),a)return c.callback(a,b);if(b.status>=200&&b.status<300)return c.callback(a,b);var e=new Error(b.statusText||"Unsuccessful HTTP response");e.original=a,e.response=b,e.status=b.status,c.callback(e,b)})}function n(a,b){return"function"==typeof b?new m("GET",a).end(b):1==arguments.length?new m("GET",a):new m(a,b)}var o=a("emitter"),p=a("reduce"),q="undefined"==typeof window?this||self:window;n.getXHR=function(){if(!(!q.XMLHttpRequest||q.location&&"file:"==q.location.protocol&&q.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(a){}return!1};var r="".trim?function(a){return a.trim()}:function(a){return a.replace(/(^\s*|\s*$)/g,"")};n.serializeObject=g,n.parseString=h,n.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},n.serialize={"application/x-www-form-urlencoded":g,"application/json":JSON.stringify},n.parse={"application/x-www-form-urlencoded":h,"application/json":JSON.parse},l.prototype.get=function(a){return this.header[a.toLowerCase()]},l.prototype.setHeaderProperties=function(a){var b=this.header["content-type"]||"";this.type=j(b);var c=k(b);for(var d in c)this[d]=c[d]},l.prototype.parseBody=function(a){var b=n.parse[this.type];return b&&a&&(a.length||a instanceof Object)?b(a):null},l.prototype.setStatusProperties=function(a){1223===a&&(a=204);var b=a/100|0;this.status=a,this.statusType=b,this.info=1==b,this.ok=2==b,this.clientError=4==b,this.serverError=5==b,this.error=4==b||5==b?this.toError():!1,this.accepted=202==a,this.noContent=204==a,this.badRequest=400==a,
+this.unauthorized=401==a,this.notAcceptable=406==a,this.notFound=404==a,this.forbidden=403==a},l.prototype.toError=function(){var a=this.req,b=a.method,c=a.url,d="cannot "+b+" "+c+" ("+this.status+")",e=new Error(d);return e.status=this.status,e.method=b,e.url=c,e},n.Response=l,o(m.prototype),m.prototype.use=function(a){return a(this),this},m.prototype.timeout=function(a){return this._timeout=a,this},m.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},m.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0,this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this)},m.prototype.set=function(a,b){if(f(a)){for(var c in a)this.set(c,a[c]);return this}return this._header[a.toLowerCase()]=b,this.header[a]=b,this},m.prototype.unset=function(a){return delete this._header[a.toLowerCase()],delete this.header[a],this},m.prototype.getHeader=function(a){return this._header[a.toLowerCase()]},m.prototype.type=function(a){return this.set("Content-Type",n.types[a]||a),this},m.prototype.accept=function(a){return this.set("Accept",n.types[a]||a),this},m.prototype.auth=function(a,b){var c=btoa(a+":"+b);return this.set("Authorization","Basic "+c),this},m.prototype.query=function(a){return"string"!=typeof a&&(a=g(a)),a&&this._query.push(a),this},m.prototype.field=function(a,b){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b),this},m.prototype.attach=function(a,b,c){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b,c),this},m.prototype.send=function(a){var b=f(a),c=this.getHeader("Content-Type");if(b&&f(this._data))for(var d in a)this._data[d]=a[d];else"string"==typeof a?(c||this.type("form"),c=this.getHeader("Content-Type"),"application/x-www-form-urlencoded"==c?this._data=this._data?this._data+"&"+a:a:this._data=(this._data||"")+a):this._data=a;return!b||e(a)?this:(c||this.type("json"),this)},m.prototype.callback=function(a,b){var c=this._callback;this.clearTimeout(),c(a,b)},m.prototype.crossDomainError=function(){var a=new Error("Origin is not allowed by Access-Control-Allow-Origin");a.crossDomain=!0,this.callback(a)},m.prototype.timeoutError=function(){var a=this._timeout,b=new Error("timeout of "+a+"ms exceeded");b.timeout=a,this.callback(b)},m.prototype.withCredentials=function(){return this._withCredentials=!0,this},m.prototype.end=function(a){var b=this,c=this.xhr=n.getXHR(),f=this._query.join("&"),g=this._timeout,h=this._formData||this._data;this._callback=a||d,c.onreadystatechange=function(){if(4==c.readyState){var a;try{a=c.status}catch(d){a=0}if(0==a){if(b.timedout)return b.timeoutError();if(b.aborted)return;return b.crossDomainError()}b.emit("end")}};var i=function(a){a.total>0&&(a.percent=a.loaded/a.total*100),b.emit("progress",a)};this.hasListeners("progress")&&(c.onprogress=i);try{c.upload&&this.hasListeners("progress")&&(c.upload.onprogress=i)}catch(j){}if(g&&!this._timer&&(this._timer=setTimeout(function(){b.timedout=!0,b.abort()},g)),f&&(f=n.serializeObject(f),this.url+=~this.url.indexOf("?")?"&"+f:"?"+f),c.open(this.method,this.url,!0),this._withCredentials&&(c.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof h&&!e(h)){var k=this.getHeader("Content-Type"),l=n.serialize[k?k.split(";")[0]:""];l&&(h=l(h))}for(var m in this.header)null!=this.header[m]&&c.setRequestHeader(m,this.header[m]);return this.emit("request",this),c.send(h),this},m.prototype.then=function(a,b){return this.end(function(c,d){c?b(c):a(d)})},n.Request=m,n.get=function(a,b,c){var d=n("GET",a);return"function"==typeof b&&(c=b,b=null),b&&d.query(b),c&&d.end(c),d},n.head=function(a,b,c){var d=n("HEAD",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.del=function(a,b){var c=n("DELETE",a);return b&&c.end(b),c},n.patch=function(a,b,c){var d=n("PATCH",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.post=function(a,b,c){var d=n("POST",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.put=function(a,b,c){var d=n("PUT",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},b.exports=n},{emitter:12,reduce:13}],12:[function(a,b,c){function d(a){return a?e(a):void 0}function e(a){for(var b in d.prototype)a[b]=d.prototype[b];return a}b.exports=d,d.prototype.on=d.prototype.addEventListener=function(a,b){return this._callbacks=this._callbacks||{},(this._callbacks[a]=this._callbacks[a]||[]).push(b),this},d.prototype.once=function(a,b){function c(){d.off(a,c),b.apply(this,arguments)}var d=this;return this._callbacks=this._callbacks||{},c.fn=b,this.on(a,c),this},d.prototype.off=d.prototype.removeListener=d.prototype.removeAllListeners=d.prototype.removeEventListener=function(a,b){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var c=this._callbacks[a];if(!c)return this;if(1==arguments.length)return delete this._callbacks[a],this;for(var d,e=0;ed;++d)c[d].apply(this,b)}return this},d.prototype.listeners=function(a){return this._callbacks=this._callbacks||{},this._callbacks[a]||[]},d.prototype.hasListeners=function(a){return!!this.listeners(a).length}},{}],13:[function(a,b,c){b.exports=function(a,b,c){for(var d=0,e=a.length,f=3==arguments.length?c:a[d++];e>d;)f=b.call(null,f,a[d],++d,a);return f}},{}],14:[function(a,b,c){function d(a,b,c){var d;return d=b?new f(a,b):new f(a)}var e=function(){return this}(),f=e.WebSocket||e.MozWebSocket;b.exports=f?d:null,f&&(d.prototype=f.prototype)},{}]},{},[5])(5)});
\ No newline at end of file
diff --git a/web-dist/discord.min.3.6.3.js b/web-dist/discord.min.3.6.3.js
new file mode 100644
index 000000000..84ac649e8
--- /dev/null
+++ b/web-dist/discord.min.3.6.3.js
@@ -0,0 +1,2 @@
+!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Discord=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g]*>/g)||[])[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;a.push(h.substring(2,h.length-1))}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return a}"function"==typeof c&&(d=c,c=!1),b=e+n(b);var p=o();f.resolveDestination(a).then(k)["catch"](j)});return g}},{key:"createws",value:function(a){if(this.websocket)return!1;var b=this;this.websocket=new o(a),this.websocket.onopen=function(){b.trySendConnData()},this.websocket.onclose=function(){b.trigger("disconnected")},this.websocket.onmessage=function(a){var c=!1,d={};try{c=JSON.parse(a.data),d=c.d}catch(e){return void b.trigger("error",e,a)}switch(b.trigger("raw",c),c.t){case"READY":b.debug("received ready packet"),b.user=b.addUser(d.user);var f=!0,h=!1,k=void 0;try{for(var l,m=d.guilds[Symbol.iterator]();!(f=(l=m.next()).done);f=!0)var n=l.value,o=b.addServer(n)}catch(e){h=!0,k=e}finally{try{!f&&m["return"]&&m["return"]()}finally{if(h)throw k}}var p=!0,q=!1,r=void 0;try{for(var s,t=d.private_channels[Symbol.iterator]();!(p=(s=t.next()).done);p=!0){var u=s.value;b.addPMChannel(u)}}catch(e){q=!0,r=e}finally{try{!p&&t["return"]&&t["return"]()}finally{if(q)throw r}}b.trigger("ready"),b.readyTime=Date.now(),b.debug("cached "+b.serverCache.length+" servers, "+b.channelCache.length+" channels, "+b.pmChannelCache.length+" PMs and "+b.userCache.length+" users."),b.state=3,setInterval(function(){b.keepAlive.apply(b)},d.heartbeat_interval);break;case"MESSAGE_CREATE":b.debug("received message");var v=[];d.mentions=d.mentions||[];var w=!0,x=!1,y=void 0;try{for(var z,A=d.mentions[Symbol.iterator]();!(w=(z=A.next()).done);w=!0){var B=z.value;v.push(b.addUser(B))}}catch(e){x=!0,y=e}finally{try{!w&&A["return"]&&A["return"]()}finally{if(x)throw y}}var C=b.getChannel("id",d.channel_id);if(C){var D=C.addMessage(new j(d,C,v,b.addUser(d.author)));b.trigger("message",D)}break;case"MESSAGE_DELETE":b.debug("message deleted");var C=b.getChannel("id",d.channel_id),E=C.getMessage("id",d.id);E?(b.trigger("messageDelete",C,E),C.messages.splice(C.messages.indexOf(E),1)):b.trigger("messageDelete",C);break;case"MESSAGE_UPDATE":b.debug("message updated");var C=b.getChannel("id",d.channel_id),F=C.getMessage("id",d.id);if(F){var G={};for(var H in F)G[H]=F[H];for(var H in d)G[H]=d[H];var v=[],I=!0,J=!1,K=void 0;try{for(var L,M=G.mentions[Symbol.iterator]();!(I=(L=M.next()).done);I=!0){var B=L.value;v.push(b.addUser(B))}}catch(e){J=!0,K=e}finally{try{!I&&M["return"]&&M["return"]()}finally{if(J)throw K}}var N=new j(G,C,v,F.author);b.trigger("messageUpdate",N,F),C.messages[C.messages.indexOf(F)]=N}break;case"GUILD_DELETE":var o=b.getServer("id",d.id);o&&(b.serverCache.splice(b.serverCache.indexOf(o),1),b.trigger("serverDelete",o));break;case"CHANNEL_DELETE":var C=b.getChannel("id",d.id);if(C){var o=C.server;o&&o.channels.splice(o.channels.indexOf(C),1),b.trigger("channelDelete",C),b.serverCache.splice(b.serverCache.indexOf(C),1)}break;case"GUILD_CREATE":var o=b.getServer("id",d.id);if(o||(o=b.addServer(d)),b.serverCreateListener[d.id]){var O=b.serverCreateListener[d.id];O[0](o),O[1](null,o),b.serverCreateListener[d.id]=null}b.trigger("serverCreate",o);break;case"CHANNEL_CREATE":var C=b.getChannel("id",d.id);if(!C){var P=b.addChannel(d,d.guild_id),Q=b.getServer("id",d.guild_id);Q&&Q.addChannel(P),b.trigger("channelCreate",P)}break;case"GUILD_MEMBER_ADD":var o=b.getServer("id",d.guild_id);if(o){var R=b.addUser(d.user);~o.members.indexOf(R)||o.members.push(R),b.trigger("serverNewMember",R,o)}break;case"GUILD_MEMBER_REMOVE":var o=b.getServer("id",d.guild_id);if(o){var R=b.addUser(d.user);~o.members.indexOf(R)&&o.members.splice(o.members.indexOf(R),1),b.trigger("serverRemoveMember",R,o)}break;case"USER_UPDATE":if(b.user&&d.id===b.user.id){var S=new g(d);b.trigger("userUpdate",S,b.user),~b.userCache.indexOf(b.user)&&(b.userCache[b.userCache.indexOf(b.user)]=S),b.user=S}break;case"PRESENCE_UPDATE":var T=b.getUser("id",d.user.id);if(T){var U=new g(d.user);U.equalsStrict(T)?(T.status=d.status,b.trigger("presence",{user:T,status:d.status,server:b.getServer("id",d.guild_id),gameId:d.game_id})):(b.trigger("userUpdate",T,U),b.userCache[b.userCache.indexOf(T)]=U)}break;case"CHANNEL_UPDATE":var V=b.getChannel("id",d.id),W=b.getServer("id",d.guild_id);if(V&&W){var X=new i(d,W);X.messages=V.messages,b.trigger("channelUpdate",V,X),b.channelCache[b.channelCache.indexOf(V)]=X}break;default:b.debug("received unknown packet"),b.trigger("unknown",c)}}}},{key:"addUser",value:function(a){return this.getUser("id",a.id)||this.userCache.push(new g(a)),this.getUser("id",a.id)}},{key:"addChannel",value:function(a,b){return this.getChannel("id",a.id)||this.channelCache.push(new i(a,this.getServer("id",b))),this.getChannel("id",a.id)}},{key:"addPMChannel",value:function(a){return this.getPMChannel("id",a.id)||this.pmChannelCache.push(new l(a,this)),this.getPMChannel("id",a.id)}},{key:"setTopic",value:function(a,b){var c=arguments.length<=2||void 0===arguments[2]?function(a){}:arguments[2],d=this;return new Promise(function(e,g){function h(a){c(a),g(a)}function i(a){var g=d.getChannel("id",a);n.patch(f.CHANNELS+"/"+a).set("authorization",d.token).send({name:g.name,position:0,topic:b}).end(function(a,b){a?h(a):(g.topic=b.body.topic,e(),c())})}d.resolveDestination(a).then(i)["catch"](h)})}},{key:"addServer",value:function(a){var b=this,c=this.getServer("id",a.id);if(a.unavailable)return b.trigger("unavailable",a),void b.debug("Server ID "+a.id+" has been marked unavailable by Discord. It was not cached.");if(!c&&(c=new h(a,this),this.serverCache.push(c),a.channels)){var d=!0,e=!1,f=void 0;try{for(var g,i=a.channels[Symbol.iterator]();!(d=(g=i.next()).done);d=!0){var j=g.value;c.channels.push(this.addChannel(j,c.id))}}catch(k){e=!0,f=k}finally{try{!d&&i["return"]&&i["return"]()}finally{if(e)throw f}}}var l=!0,m=!1,n=void 0;try{for(var o,p=a.presences[Symbol.iterator]();!(l=(o=p.next()).done);l=!0){var q=o.value;b.getUser("id",q.user.id).status=q.status}}catch(k){m=!0,n=k}finally{try{!l&&p["return"]&&p["return"]()}finally{if(m)throw n}}return c}},{key:"getUser",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.userCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.channelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return this.getPMChannel(a,b)}},{key:"getPMChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.pmChannelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getServer",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.serverCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"trySendConnData",value:function(){if(this.token&&!this.alreadySentData){this.alreadySentData=!0;var a={op:2,d:{token:this.token,v:3,properties:{$os:"discord.js",$browser:"discord.js",$device:"discord.js",$referrer:"",$referring_domain:""}}};this.websocket.send(JSON.stringify(a))}}},{key:"resolveServerID",value:function(a){return a instanceof h?a.id:!isNaN(a)&&a.length&&17===a.length?a:void 0}},{key:"resolveDestination",value:function(a){var b=!1,c=this;return new Promise(function(d,e){if(a instanceof h)b=a.id;else if(a instanceof i)b=a.id;else if(a instanceof j)b=a.channel.id;else if(a instanceof l)b=a.id;else if(a instanceof g){var f=!0,k=!1,m=void 0;try{for(var n,o=c.pmChannelCache[Symbol.iterator]();!(f=(n=o.next()).done);f=!0){var p=n.value;if(p.user.equals(a))return void d(p.id)}}catch(q){k=!0,m=q}finally{try{!f&&o["return"]&&o["return"]()}finally{if(k)throw m}}c.startPM(a).then(function(a){d(a.id)})["catch"](e)}else b=a;b?d(b):e()})}},{key:"_sendMessage",value:function(a,b,c,d){var e=this;return new Promise(function(g,h){n.post(f.CHANNELS+"/"+a+"/messages").set("authorization",e.token).send({content:b,mentions:d,tts:c}).end(function(a,b){if(a)h(a);else{var c=b.body,d=[];c.mentions=c.mentions||[];var f=!0,i=!1,k=void 0;try{for(var l,m=c.mentions[Symbol.iterator]();!(f=(l=m.next()).done);f=!0){var n=l.value;d.push(e.addUser(n))}}catch(a){i=!0,k=a}finally{try{!f&&m["return"]&&m["return"]()}finally{if(i)throw k}}var o=e.getChannel("id",c.channel_id);if(o){var p=o.addMessage(new j(c,o,d,e.addUser(c.author)));g(p)}}})})}},{key:"_sendFile",value:function(a,b){var c=arguments.length<=2||void 0===arguments[2]?"DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png":arguments[2],d=this;return new Promise(function(e,g){n.post(f.CHANNELS+"/"+a+"/messages").set("authorization",d.token).attach("file",b,c).end(function(b,c){if(b)g(b);else{var f=d.getChannel("id",a);if(f){var h=f.addMessage(new j(c.body,f,[],d.user));e(h)}}})})}},{key:"_updateMessage",value:function(a,b){var c=this;return new Promise(function(d,e){n.patch(f.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",c.token).send({content:b,mentions:[]}).end(function(b,c){if(b)e(b);else{var f=new j(c.body,a.channel,a.mentions,a.sender);d(f),a.channel.messages[a.channel.messages.indexOf(a)]=f}})})}},{key:"_deleteMessage",value:function(a){var b=this;return new Promise(function(c,d){n.del(f.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",b.token).end(function(a,b){a?d(a):c()})})}},{key:"checkQueue",value:function(a){var b=this,c=this;this.checkingQueue[a]||!function(){var d=function f(){if(0===c.queue[a].length)return void e();var b=c.queue[a][0];switch(b.action){case"sendMessage":var d=b;c._sendMessage(a,d.content,d.tts,d.mentions).then(function(b){d.then(b),c.queue[a].shift(),f()})["catch"](function(b){d.error(b),c.queue[a].shift(),f()});break;case"sendFile":var g=b;c._sendFile(a,g.attachment,g.attachmentName).then(function(b){g.then(b),c.queue[a].shift(),f()})["catch"](function(b){g.error(b),c.queue[a].shift(),f()});break;case"updateMessage":var h=b;c._updateMessage(h.message,h.content).then(function(b){h.then(b),c.queue[a].shift(),f()})["catch"](function(b){h.error(b),c.queue[a].shift(),f()});break;case"deleteMessage":var i=b;c._deleteMessage(i.message).then(function(b){i.then(b),c.queue[a].shift(),f()})["catch"](function(b){i.error(b),c.queue[a].shift(),f()});break;default:e()}},e=function(){c.checkingQueue[a]=!1};b.checkingQueue[a]=!0,d()}()}},{key:"getGateway",value:function(){var a=this;return new Promise(function(b,c){n.get(f.API+"/gateway").set("authorization",a.token).end(function(a,d){a?c(a):b(d.body.url)})})}},{key:"setStatusIdle",value:function(){this.setStatus("idle")}},{key:"setStatusOnline",value:function(){this.setStatus("online")}},{key:"setStatusActive",value:function(){this.setStatusOnline()}},{key:"setStatusHere",value:function(){this.setStatusOnline()}},{key:"setStatusAway",value:function(){this.setStatusIdle()}},{key:"startTyping",value:function(a,b){function c(a){if(!d.typingIntervals[a]){var c=function(){n.post(f.CHANNELS+"/"+a+"/typing").set("authorization",d.token).end()};c();var e=setInterval(c,3e3);d.typingIntervals[a]=e,b&&setTimeout(function(){d.stopTyping(a)},b)}}var d=this;this.resolveDestination(a).then(c)}},{key:"stopTyping",value:function(a){function b(a){c.typingIntervals[a]&&(clearInterval(c.typingIntervals[a]),delete c.typingIntervals[a])}var c=this;this.resolveDestination(a).then(b)}},{key:"setStatus",value:function(a){var b="online"===a?null:Date.now();this.__idleTime=b,this.websocket.send(JSON.stringify({op:3,d:{idle_since:this.__idleTime,game_id:this.__gameId}}))}},{key:"setPlayingGame",value:function(a){if(a instanceof String||"string"==typeof a){var b=a.trim().toUpperCase();a=null;var c=!0,d=!1,e=void 0;try{for(var f,g=m[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h.name.trim().toUpperCase()===b){a=h.id;break}}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}}this.__gameId=a,this.websocket.send(JSON.stringify({op:3,d:{idle_since:this.__idleTime,game_id:this.__gameId}}))}},{key:"playGame",value:function(a){this.setPlayingGame(a)}},{key:"playingGame",value:function(a){this.setPlayingGame(a)}},{key:"uptime",get:function(){return this.readyTime?Date.now()-this.readyTime:null}},{key:"ready",get:function(){return 3===this.state}},{key:"servers",get:function(){return this.serverCache}},{key:"channels",get:function(){return this.channelCache}},{key:"users",get:function(){return this.userCache}},{key:"PMChannels",get:function(){return this.pmChannelCache}},{key:"messages",get:function(){var a=[],b=!0,c=!1,d=void 0;try{for(var e,f=this.channelCache[Symbol.iterator]();!(b=(e=f.next()).done);b=!0){var g=e.value;a=a.concat(g.messages)}}catch(h){c=!0,d=h}finally{try{!b&&f["return"]&&f["return"]()}finally{if(c)throw d}}return a}}]),a}();b.exports=r},{"../ref/gameMap.json":15,"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,fs:10,superagent:11,ws:14}],2:[function(a,b,c){"use strict";c.BASE_DOMAIN="discordapp.com",c.BASE="https://"+c.BASE_DOMAIN,c.WEBSOCKET_HUB="wss://"+c.BASE_DOMAIN+"/hub",c.API=c.BASE+"/api",c.AUTH=c.API+"/auth",c.LOGIN=c.AUTH+"/login",c.LOGOUT=c.AUTH+"/logout",c.USERS=c.API+"/users",c.SERVERS=c.API+"/guilds",c.CHANNELS=c.API+"/channels"},{}],3:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c1e3&&this.messages.splice(0,1);var c=!0,d=!1,e=void 0;try{for(var f,g=this.messages[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"isPrivate",get:function(){return!0}}]),a}();b.exports=f},{}],4:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c1e3&&this.messages.splice(0,1),this.getMessage("id",a.id)||this.messages.push(a),this.getMessage("id",a.id)}},{key:"getMessage",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.messages[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"toString",value:function(){return"<#"+this.id+">"}},{key:"client",get:function(){return this.server.client}},{key:"isPrivate",get:function(){return!1}},{key:"users",get:function(){return this.server.members}},{key:"members",get:function(){return this.server.members}}]),a}();b.exports=f},{}],5:[function(a,b,c){"use strict";var d=(a("superagent"),a("./Endpoints.js")),e=a("./Client.js"),f={Endpoints:d,Client:e};b.exports=f},{"./Client.js":1,"./Endpoints.js":2,superagent:11}],6:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c"}},{key:"toString",value:function(){return this.mention()}},{key:"equals",value:function(a){return a.id===this.id}},{key:"equalsStrict",value:function(a){return a.id===this.id&&a.avatar===this.avatar&&a.username===this.username&&a.discriminator===this.discriminator}},{key:"avatarURL",get:function(){return this.avatar?"https://discordapp.com/api/users/"+this.id+"/avatars/"+this.avatar+".jpg":null}}]),a}();b.exports=f},{}],10:[function(a,b,c){},{}],11:[function(a,b,c){function d(){}function e(a){var b={}.toString.call(a);switch(b){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function f(a){return a===Object(a)}function g(a){if(!f(a))return a;var b=[];for(var c in a)null!=a[c]&&b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")}function h(a){for(var b,c,d={},e=a.split("&"),f=0,g=e.length;g>f;++f)c=e[f],b=c.split("="),d[decodeURIComponent(b[0])]=decodeURIComponent(b[1]);return d}function i(a){var b,c,d,e,f=a.split(/\r?\n/),g={};f.pop();for(var h=0,i=f.length;i>h;++h)c=f[h],b=c.indexOf(":"),d=c.slice(0,b).toLowerCase(),e=r(c.slice(b+1)),g[d]=e;return g}function j(a){return a.split(/ *; */).shift()}function k(a){return p(a.split(/ *; */),function(a,b){var c=b.split(/ *= */),d=c.shift(),e=c.shift();return d&&e&&(a[d]=e),a},{})}function l(a,b){b=b||{},this.req=a,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,
+this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=i(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function m(a,b){var c=this;o.call(this),this._query=this._query||[],this.method=a,this.url=b,this.header={},this._header={},this.on("end",function(){var a=null,b=null;try{b=new l(c)}catch(d){return a=new Error("Parser is unable to parse the response"),a.parse=!0,a.original=d,c.callback(a)}if(c.emit("response",b),a)return c.callback(a,b);if(b.status>=200&&b.status<300)return c.callback(a,b);var e=new Error(b.statusText||"Unsuccessful HTTP response");e.original=a,e.response=b,e.status=b.status,c.callback(e,b)})}function n(a,b){return"function"==typeof b?new m("GET",a).end(b):1==arguments.length?new m("GET",a):new m(a,b)}var o=a("emitter"),p=a("reduce"),q="undefined"==typeof window?this||self:window;n.getXHR=function(){if(!(!q.XMLHttpRequest||q.location&&"file:"==q.location.protocol&&q.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(a){}return!1};var r="".trim?function(a){return a.trim()}:function(a){return a.replace(/(^\s*|\s*$)/g,"")};n.serializeObject=g,n.parseString=h,n.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},n.serialize={"application/x-www-form-urlencoded":g,"application/json":JSON.stringify},n.parse={"application/x-www-form-urlencoded":h,"application/json":JSON.parse},l.prototype.get=function(a){return this.header[a.toLowerCase()]},l.prototype.setHeaderProperties=function(a){var b=this.header["content-type"]||"";this.type=j(b);var c=k(b);for(var d in c)this[d]=c[d]},l.prototype.parseBody=function(a){var b=n.parse[this.type];return b&&a&&(a.length||a instanceof Object)?b(a):null},l.prototype.setStatusProperties=function(a){1223===a&&(a=204);var b=a/100|0;this.status=a,this.statusType=b,this.info=1==b,this.ok=2==b,this.clientError=4==b,this.serverError=5==b,this.error=4==b||5==b?this.toError():!1,this.accepted=202==a,this.noContent=204==a,this.badRequest=400==a,this.unauthorized=401==a,this.notAcceptable=406==a,this.notFound=404==a,this.forbidden=403==a},l.prototype.toError=function(){var a=this.req,b=a.method,c=a.url,d="cannot "+b+" "+c+" ("+this.status+")",e=new Error(d);return e.status=this.status,e.method=b,e.url=c,e},n.Response=l,o(m.prototype),m.prototype.use=function(a){return a(this),this},m.prototype.timeout=function(a){return this._timeout=a,this},m.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},m.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0,this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this)},m.prototype.set=function(a,b){if(f(a)){for(var c in a)this.set(c,a[c]);return this}return this._header[a.toLowerCase()]=b,this.header[a]=b,this},m.prototype.unset=function(a){return delete this._header[a.toLowerCase()],delete this.header[a],this},m.prototype.getHeader=function(a){return this._header[a.toLowerCase()]},m.prototype.type=function(a){return this.set("Content-Type",n.types[a]||a),this},m.prototype.accept=function(a){return this.set("Accept",n.types[a]||a),this},m.prototype.auth=function(a,b){var c=btoa(a+":"+b);return this.set("Authorization","Basic "+c),this},m.prototype.query=function(a){return"string"!=typeof a&&(a=g(a)),a&&this._query.push(a),this},m.prototype.field=function(a,b){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b),this},m.prototype.attach=function(a,b,c){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b,c),this},m.prototype.send=function(a){var b=f(a),c=this.getHeader("Content-Type");if(b&&f(this._data))for(var d in a)this._data[d]=a[d];else"string"==typeof a?(c||this.type("form"),c=this.getHeader("Content-Type"),"application/x-www-form-urlencoded"==c?this._data=this._data?this._data+"&"+a:a:this._data=(this._data||"")+a):this._data=a;return!b||e(a)?this:(c||this.type("json"),this)},m.prototype.callback=function(a,b){var c=this._callback;this.clearTimeout(),c(a,b)},m.prototype.crossDomainError=function(){var a=new Error("Origin is not allowed by Access-Control-Allow-Origin");a.crossDomain=!0,this.callback(a)},m.prototype.timeoutError=function(){var a=this._timeout,b=new Error("timeout of "+a+"ms exceeded");b.timeout=a,this.callback(b)},m.prototype.withCredentials=function(){return this._withCredentials=!0,this},m.prototype.end=function(a){var b=this,c=this.xhr=n.getXHR(),f=this._query.join("&"),g=this._timeout,h=this._formData||this._data;this._callback=a||d,c.onreadystatechange=function(){if(4==c.readyState){var a;try{a=c.status}catch(d){a=0}if(0==a){if(b.timedout)return b.timeoutError();if(b.aborted)return;return b.crossDomainError()}b.emit("end")}};var i=function(a){a.total>0&&(a.percent=a.loaded/a.total*100),b.emit("progress",a)};this.hasListeners("progress")&&(c.onprogress=i);try{c.upload&&this.hasListeners("progress")&&(c.upload.onprogress=i)}catch(j){}if(g&&!this._timer&&(this._timer=setTimeout(function(){b.timedout=!0,b.abort()},g)),f&&(f=n.serializeObject(f),this.url+=~this.url.indexOf("?")?"&"+f:"?"+f),c.open(this.method,this.url,!0),this._withCredentials&&(c.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof h&&!e(h)){var k=this.getHeader("Content-Type"),l=n.serialize[k?k.split(";")[0]:""];l&&(h=l(h))}for(var m in this.header)null!=this.header[m]&&c.setRequestHeader(m,this.header[m]);return this.emit("request",this),c.send(h),this},m.prototype.then=function(a,b){return this.end(function(c,d){c?b(c):a(d)})},n.Request=m,n.get=function(a,b,c){var d=n("GET",a);return"function"==typeof b&&(c=b,b=null),b&&d.query(b),c&&d.end(c),d},n.head=function(a,b,c){var d=n("HEAD",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.del=function(a,b){var c=n("DELETE",a);return b&&c.end(b),c},n.patch=function(a,b,c){var d=n("PATCH",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.post=function(a,b,c){var d=n("POST",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.put=function(a,b,c){var d=n("PUT",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},b.exports=n},{emitter:12,reduce:13}],12:[function(a,b,c){function d(a){return a?e(a):void 0}function e(a){for(var b in d.prototype)a[b]=d.prototype[b];return a}b.exports=d,d.prototype.on=d.prototype.addEventListener=function(a,b){return this._callbacks=this._callbacks||{},(this._callbacks[a]=this._callbacks[a]||[]).push(b),this},d.prototype.once=function(a,b){function c(){d.off(a,c),b.apply(this,arguments)}var d=this;return this._callbacks=this._callbacks||{},c.fn=b,this.on(a,c),this},d.prototype.off=d.prototype.removeListener=d.prototype.removeAllListeners=d.prototype.removeEventListener=function(a,b){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var c=this._callbacks[a];if(!c)return this;if(1==arguments.length)return delete this._callbacks[a],this;for(var d,e=0;ed;++d)c[d].apply(this,b)}return this},d.prototype.listeners=function(a){return this._callbacks=this._callbacks||{},this._callbacks[a]||[]},d.prototype.hasListeners=function(a){return!!this.listeners(a).length}},{}],13:[function(a,b,c){b.exports=function(a,b,c){for(var d=0,e=a.length,f=3==arguments.length?c:a[d++];e>d;)f=b.call(null,f,a[d],++d,a);return f}},{}],14:[function(a,b,c){function d(a,b,c){var d;return d=b?new f(a,b):new f(a)}var e=function(){return this}(),f=e.WebSocket||e.MozWebSocket;b.exports=f?d:null,f&&(d.prototype=f.prototype)},{}],15:[function(a,b,c){b.exports=[{executables:{win32:["pol.exe"]},id:0,name:"FINAL FANTASY XI"},{executables:{win32:["ffxiv.exe","ffxiv_dx11.exe"]},id:1,name:"FINAL FANTASY XIV"},{executables:{win32:["Wow.exe","Wow-64.exe"]},id:3,name:"World of Warcraft"},{executables:{darwin:["LoLLauncher.app"],win32:["LolClient.exe","League of Legends.exe"]},id:4,name:"League of Legends"},{executables:{darwin:["Diablo%20III.app"],win32:["Diablo III.exe"]},id:5,name:"Diablo 3"},{executables:{darwin:["dota_osx.app"],win32:["dota2.exe"]},id:6,name:"DOTA 2"},{executables:{darwin:["Heroes.app"],win32:["Heroes of the Storm.exe","HeroesOfTheStorm_x64.exe","HeroesOfTheStorm.exe"]},id:7,name:"Heroes of the Storm"},{executables:{darwin:["Hearthstone.app"],win32:["Hearthstone.exe"]},id:8,name:"Hearthstone"},{executables:{win32:["csgo.exe"]},id:9,name:"Counter-Strike: Global Offensive"},{executables:{win32:["WorldOfTanks.exe"]},id:10,name:"World of Tanks"},{executables:{darwin:["gw2.app"],win32:["gw2.exe"]},id:11,name:"Guild Wars 2"},{executables:{win32:["dayz.exe"]},id:12,name:"Day Z"},{executables:{darwin:["starcraft%20ii.app"],win32:["starcraft ii.exe","SC2_x64.exe","SC2.exe"]},id:13,name:"Starcraft II"},{executables:{win32:["diablo.exe"]},id:14,name:"Diablo"},{executables:{win32:["diablo ii.exe"]},id:15,name:"Diablo 2"},{executables:{win32:["left4dead.exe"]},id:17,name:"Left 4 Dead"},{executables:{darwin:["minecraft.app"],win32:["minecraft.exe"]},id:18,name:"Minecraft"},{executables:{win32:["smite.exe"]},id:19,name:"Smite"},{executables:{win32:["bf4.exe"]},id:20,name:"Battlefield 4"},{executables:{win32:["AoK HD.exe","empires2.exe"]},id:101,name:"Age of Empire II"},{executables:{win32:["age3y.exe"]},id:102,name:"Age of Empire III"},{executables:{win32:["AlanWake.exe"]},id:104,name:"Alan Wake"},{executables:{win32:["alan_wakes_american_nightmare.exe"]},id:105,name:"Alan Wake's American Nightmare"},{executables:{win32:["AlienBreed2Assault.exe"]},id:106,name:"Alien Breed 2: Assault"},{executables:{win32:["Amnesia.exe"]},id:107,name:"Amnesia: The Dark Descent"},{executables:{win32:["UDK.exe"]},id:108,name:"Antichamber"},{executables:{win32:["ArcheAge.exe"]},id:109,name:"ArcheAge"},{executables:{win32:["arma3.exe"]},id:110,name:"Arma III"},{executables:{win32:["AC3SP.exe"]},id:111,name:"Assassin's Creed 3"},{executables:{win32:["Bastion.exe"]},id:112,name:"Bastion"},{executables:{win32:["BF2.exe"]},id:113,name:"Battlefield 2"},{executables:{win32:["bf3.exe"]},id:114,name:"Battlefield 3"},{executables:{win32:["Besiege.exe"]},id:116,name:"Besiege"},{executables:{win32:["Bioshock.exe"]},id:117,name:"Bioshock"},{executables:{win32:["Bioshock2.exe"]},id:118,name:"BioShock II"},{executables:{win32:["BioShockInfinite.exe"]},id:119,name:"BioShock Infinite"},{executables:{win32:["Borderlands2.exe"]},id:122,name:"Borderlands 2"},{executables:{win32:["braid.exe"]},id:123,name:"Braid"},{executables:{win32:["ShippingPC-StormGame.exe"]},id:124,name:"Bulletstorm"},{executables:{},id:125,name:"Cabal 2"},{executables:{win32:["CabalMain.exe"]},id:126,name:"Cabal Online"},{executables:{win32:["iw4mp.exe","iw4sp.exe"]},id:127,name:"Call of Duty: Modern Warfare 2"},{executables:{win32:["t6sp.exe"]},id:128,name:"Call of Duty: Black Ops"},{executables:{win32:["iw5mp.exe"]},id:129,name:"Call of Duty: Modern Warfare 3"},{executables:{win32:["RelicCOH.exe"]},id:132,name:"Company of Heroes"},{executables:{win32:["Crysis64.exe"]},id:135,name:"Crysis"},{executables:{win32:["Crysis2.exe"]},id:136,name:"Crysis 2"},{executables:{win32:["Crysis3.exe"]},id:137,name:"Crysis 3"},{executables:{win32:["Crysis.exe"]},id:138,name:"Crysis 4 "},{executables:{win32:["DATA.exe"]},id:140,name:"Dark Souls"},{executables:{win32:["DarkSoulsII.exe"]},id:141,name:"Dark Souls II"},{executables:{win32:["dfuw.exe"]},id:142,name:"Darkfall: Unholy Wars"},{executables:{win32:["DCGAME.exe"]},id:144,name:"DC Universe Online"},{executables:{win32:["DeadIslandGame.exe"]},id:145,name:"Dead Island"},{executables:{win32:["deadspace2.exe"]},id:146,name:"Dead Space 2"},{executables:{win32:["LOTDGame.exe"]},id:147,name:"Deadlight"},{executables:{win32:["dxhr.exe"]},id:148,name:"Deus Ex: Human Revolution"},{executables:{win32:["DeviMayCry4.exe"]},id:149,name:"Devil May Cry 4"},{executables:{win32:["DMC-DevilMayCry.exe"]},id:150,name:"DmC Devil May Cry"},{executables:{win32:["dirt2_game.exe"]},id:154,name:"DiRT 2"},{executables:{win32:["dirt3_game.exe"]},id:155,name:"DiRT 3"},{executables:{win32:["dota.exe"]},id:156,name:"DOTA"},{executables:{win32:["DoubleDragon.exe"]},id:158,name:"Double Dragon Neon"},{executables:{win32:["DragonAge2.exe"]},id:159,name:"Dragon Age II"},{executables:{win32:["DragonAgeInquisition.exe"]},id:160,name:"Dragon Age: Inquisition"},{executables:{win32:["daorigins.exe"]},id:161,name:"Dragon Age: Origins"},{executables:{win32:["DBXV.exe"]},id:162,name:"Dragon Ball XenoVerse"},{executables:{win32:["DukeForever.exe"]},id:163,name:"Duke Nukem Forever"},{executables:{darwin:["Dustforce.app"],win32:["dustforce.exe"]},id:164,name:"Dustforce"},{executables:{win32:["EliteDangerous32.exe"]},id:165,name:"Elite: Dangerous"},{executables:{win32:["exefile.exe"]},id:166,name:"Eve Online"},{executables:{win32:["eqgame.exe"]},id:167,name:"EverQuest"},{executables:{win32:["EverQuest2.exe"]},id:168,name:"EverQuest II"},{executables:{},id:169,name:"EverQuest Next"},{executables:{win32:["Engine.exe"]},id:170,name:"F.E.A.R."},{executables:{win32:["FEAR2.exe"]},id:171,name:"F.E.A.R. 2: Project Origin"},{executables:{win32:["fallout3.exe"]},id:172,name:"Fallout 3"},{executables:{win32:["FalloutNV.exe"]},id:174,name:"Fallout: New Vegas"},{executables:{win32:["farcry3.exe"]},id:175,name:"Far Cry 3"},{executables:{win32:["fifa15.exe"]},id:176,name:"FIFA 15"},{executables:{win32:["FTLGame.exe"]},id:180,name:"FTL: Faster Than Light"},{executables:{win32:["GTAIV.exe"]},id:181,name:"Grand Theft Auto 4"},{executables:{win32:["GTA5.exe"]},id:182,name:"Grand Theft Auto 5"},{executables:{win32:["Gw.exe"]},id:183,name:"Guild Wars"},{executables:{win32:["H1Z1.exe"]},id:186,name:"H1Z1"},{executables:{win32:["HL2HL2.exe","hl2.exe"]},id:188,name:"Half Life 2"},{executables:{win32:["HOMEFRONT.exe"]},id:195,name:"Homefront"},{executables:{win32:["invisibleinc.exe"]},id:196,name:"Invisible Inc."},{executables:{win32:["LANoire.exe"]},id:197,name:"L.A. Noire"},{executables:{win32:["Landmark64.exe"]},id:198,name:"Landmark"},{executables:{win32:["left4dead2.exe"]},id:201,name:"Left 4 Dead 2"},{executables:{win32:["lineage.exe"]},id:203,name:"Lineage"},{executables:{win32:["Magicka.exe"]},id:206,name:"Magicka"},{executables:{win32:["MapleStory.exe"]},id:208,name:"MapleStory"},{executables:{},id:209,name:"Mark of the Ninja"},{executables:{win32:["MassEffect.exe"]},id:210,name:"Mass Effect"},{executables:{win32:["MassEffect2.exe"]},id:211,name:"Mass Effect 2"},{executables:{win32:["MassEffect3Demo.exe"]},id:212,name:"Mass Effect 3"},{executables:{win32:["METAL GEAR RISING REVENGEANCE.exe"]},id:214,name:"Metal Gear Rising: Revengeance"},{executables:{win32:["metro2033.exe"]},id:215,name:"Metro 2033"},{executables:{win32:["MetroLL.exe"]},id:216,name:"Metro Last Light"},{executables:{win32:["MK10.exe"]},id:218,name:"Mortal Kombat X"},{executables:{win32:["speed.exe"]},id:219,name:"Need For Speed Most Wanted"},{executables:{},id:220,name:"Neverwinder"},{executables:{darwin:["Outlast.app"],win32:["OLGame.exe"]},id:221,name:"Outlast"},{executables:{win32:["PapersPlease.exe"]},id:222,name:"Papers, Please"},{executables:{win32:["payday_win32_release.exe"]},id:223,name:"PAYDAY"},{executables:{win32:["payday2_win32_release.exe"]},id:224,name:"PAYDAY2"},{executables:{win32:["PillarsOfEternity.exe"]},id:225,name:"Pillars of Eternity"},{executables:{win32:["PA.exe"]},id:226,name:"Planetary Annihilation"},{executables:{win32:["planetside2_x86.exe"]},id:227,name:"Planetside 2"},{executables:{win32:["hl2P.exe"]},id:228,name:"Portal"},{executables:{win32:["portal2.exe"]},id:229,name:"Portal 2"},{executables:{win32:["PrimalCarnageGame.exe"]},id:231,name:"Primal Cargnage"},{executables:{win32:["pCARS.exe"]},id:232,name:"Project Cars"},{executables:{win32:["RaceTheSun.exe"]},id:233,name:"Race The Sun"},{executables:{win32:["Rage.exe"]},id:234,name:"RAGE"},{executables:{win32:["ragexe.exe"]},id:235,name:"Ragnarok Online"},{executables:{win32:["rift.exe"]},id:236,name:"Rift"},{executables:{win32:["Rocksmith2014.exe"]},id:237,name:"Rocksmith 2014"},{executables:{win32:["SwiftKit-RS.exe","JagexLauncher.exe"]},id:238,name:"RuneScape"},{executables:{win32:["Shadowgrounds.exe"]},id:239,name:"Shadowgrounds"},{executables:{win32:["survivor.exe"]},id:240,name:"Shadowgrounds: Survivor"},{executables:{win32:["ShovelKnight.exe"]},id:241,name:"Shovel Knight"},{executables:{win32:["SimCity.exe"]},id:242,name:"SimCity"},{executables:{win32:["SporeApp.exe"]},id:245,name:"Spore"},{executables:{win32:["StarCitizen.exe"]},id:246,name:"Star Citizen"},{executables:{},id:247,name:"Star Trek Online"},{executables:{win32:["battlefront.exe"]},id:248,name:"Star Wars Battlefront"},{executables:{win32:["swtor.exe"]},id:249,name:"Star Wars: The Old Republic"},{executables:{win32:["starbound.exe","starbound_opengl.exe"]},id:250,name:"Starbound"},{executables:{win32:["starcraft.exe"]},id:251,name:"Starcraft"},{executables:{win32:["SSFIV.exe"]},id:253,name:"Ultra Street Fighter IV"},{executables:{win32:["superhexagon.exe"]},id:254,name:"Super Hexagon"},{executables:{win32:["swordandsworcery_pc.exe"]},id:255,name:"Superbrothers: Sword & Sworcery EP"},{executables:{win32:["hl2TF.exe"]},id:256,name:"Team Fortress 2"},{executables:{win32:["TERA.exe"]},id:258,name:"TERA"},{executables:{win32:["Terraria.exe"]},id:259,name:"Terraria"},{executables:{win32:["Bethesda.net_Launcher.exe"]},id:260,name:"The Elder Scrolls Online"},{executables:{win32:["TESV.exe"]},id:261,name:"The Elder Scrolls V: Skyrim"},{executables:{win32:["TheSecretWorld.exe"]},id:262,name:"The Secret World"},{executables:{win32:["TS3.exe","ts3w.exe"]},id:264,name:"The Sims 3"},{executables:{win32:["WALKINGDEAD101.EXE"]},id:265,name:"The Walking Dead"},{executables:{win32:["TheWalkingDead2.exe"]},id:266,name:"The Walking Dead Season Two"},{executables:{win32:["witcher3.exe"]},id:267,name:"The Witcher 3"},{executables:{win32:["Future Soldier.exe"]},id:268,name:"Tom Clancy's Ghost Recon: Future Solider"},{executables:{win32:["TombRaider.exe"]},id:269,name:"Tomb Raider (2013)"},{executables:{win32:["Torchlight.exe"]},id:271,name:"Torchlight"},{executables:{win32:["Torchlight2.exe"]},id:272,name:"Torchlight 2"},{executables:{win32:["Shogun2.exe"]},id:273,name:"Total War: Shogun 2"},{executables:{win32:["Transistor.exe"]},id:274,name:"Transistor"},{executables:{win32:["trine.exe"]},id:275,name:"Trine"},{executables:{win32:["trine2_32bit.exe"]},id:276,name:"Trine 2"},{executables:{win32:["UOKR.exe"]},id:277,name:"Ultima Online"},{executables:{win32:["aces.exe"]},id:279,name:"War Thunder"},{executables:{win32:["Warcraft III.exe","wc3.exe"]},id:281,name:"Warcraft 3: Reign of Chaos"},{executables:{win32:["Warcraft II BNE.exe"]},id:282,name:"Warcraft II"},{executables:{win32:["Warframe.x64.exe","Warframe.exe"]},id:283,name:"Warframe"},{executables:{win32:["watch_dogs.exe"]},id:284,name:"Watch Dogs"},{executables:{win32:["WildStar64.exe"]},id:285,name:"WildStar"},{executables:{win32:["XComGame.exe"]},id:288,name:"XCOM: Enemy Unknown"},{executables:{win32:["DFO.exe","dfo.exe"]},id:289,name:"Dungeon Fighter Online"},{executables:{win32:["aclauncher.exe","acclient.exe"]},id:290,name:"Asheron's Call"},{executables:{win32:["MapleStory2.exe"]},id:291,name:"MapleStory 2"},{executables:{win32:["ksp.exe"]},id:292,name:"Kerbal Space Program"},{executables:{win32:["PINBALL.EXE"]},id:293,name:"3D Pinball: Space Cadet"},{executables:{win32:["dave.exe"]},id:294,name:"Dangerous Dave"},{executables:{win32:["iwbtgbeta(slomo).exe","iwbtgbeta(fs).exe"]},id:295,name:"I Wanna Be The Guy"},{executables:{win32:["MechWarriorOnline.exe "]},id:296,name:"Mech Warrior Online"},{executables:{win32:["dontstarve_steam.exe"]},id:297,name:"Don't Starve"},{executables:{win32:["GalCiv3.exe"]},id:298,name:"Galactic Civilization 3"},{executables:{win32:["Risk of Rain.exe"]},id:299,name:"Risk of Rain"},{executables:{win32:["Binding_of_Isaac.exe","Isaac-ng.exe"]},id:300,name:"The Binding of Isaac"},{executables:{win32:["RustClient.exe"]},id:301,name:"Rust"},{executables:{win32:["Clicker Heroes.exe"]},id:302,name:"Clicker Heroes"},{executables:{win32:["Brawlhalla.exe"]},id:303,name:"Brawlhalla"},{executables:{win32:["TownOfSalem.exe"]},id:304,name:"Town of Salem"},{executables:{win32:["osu!.exe"]},id:305,name:"osu!"},{executables:{win32:["PathOfExileSteam.exe","PathOfExile.exe"]},id:306,name:"Path of Exile"},{executables:{win32:["Dolphin.exe"]},id:307,name:"Dolphin"},{executables:{win32:["RocketLeague.exe"]},id:308,name:"Rocket League"},{executables:{win32:["TJPP.exe"]},id:309,name:"Jackbox Party Pack"},{executables:{win32:["KFGame.exe"]},id:310,name:"Killing Floor 2"},{executables:{win32:["ShooterGame.exe"]},id:311,name:"Ark: Survival Evolved"},{executables:{win32:["LifeIsStrange.exe"]},id:312,name:"Life Is Strange"},{executables:{win32:["Client_tos.exe"]},id:313,name:"Tree of Savior"},{executables:{win32:["olliolli2.exe"]},id:314,name:"OlliOlli2"},{executables:{win32:["cw.exe"]},id:315,name:"Closers Dimension Conflict"},{executables:{win32:["ESSTEAM.exe","elsword.exe","x2.exe"]},id:316,name:"Elsword"},{executables:{win32:["ori.exe"]},id:317,name:"Ori and the Blind Forest"},{executables:{win32:["Skyforge.exe"]},id:318,name:"Skyforge"},{executables:{win32:["projectzomboid64.exe","projectzomboid32.exe"]},id:319,name:"Project Zomboid"},{executables:{win32:["From_The_Depths.exe"]},id:320,name:"The Depths"},{executables:{win32:["TheCrew.exe"]},id:321,name:"The Crew"},{executables:{win32:["MarvelHeroes2015.exe"]},id:322,name:"Marvel Heroes 2015"},{executables:{win32:["timeclickers.exe"]},id:324,name:"Time Clickers"},{executables:{win32:["eurotrucks2.exe"]},id:325,name:"Euro Truck Simulator 2"},{executables:{win32:["FarmingSimulator2015Game.exe"]},id:326,name:"Farming Simulator 15"},{executables:{win32:["strife.exe"]},id:327,name:"Strife"},{executables:{win32:["Awesomenauts.exe"]},id:328,name:"Awesomenauts"},{executables:{win32:["Dofus.exe"]},id:329,name:"Dofus"},{executables:{win32:["Boid.exe"]},id:330,name:"Boid"},{executables:{win32:["adventure-capitalist.exe"]},id:331,name:"AdVenture Capitalist"},{executables:{win32:["OrcsMustDie2.exe"]},id:332,name:"Orcs Must Die! 2"},{executables:{win32:["Mountain.exe"]},id:333,name:"Mountain"},{executables:{win32:["Valkyria.exe"]},id:335,name:"Valkyria Chronicles"},{executables:{win32:["ffxiiiimg.exe"]},id:336,name:"Final Fantasy XIII"},{executables:{win32:["TLR.exe"]},id:337,name:"The Last Remnant"},{executables:{win32:["Cities.exe"]},id:339,name:"Cities Skylines"},{executables:{win32:["worldofwarships.exe","WoWSLauncher.exe"]},id:341,name:"World of Warships"},{executables:{win32:["spacegame-Win64-shipping.exe"]},id:342,name:"Fractured Space"},{executables:{win32:["thespacegame.exe"]},id:343,name:"Ascent - The Space Game"},{executables:{win32:["DuckGame.exe"]},id:344,name:"Duck Game"},{executables:{win32:["PPSSPPWindows.exe"]},id:345,name:"PPSSPP"},{executables:{win32:["MBAA.exe"]},id:346,name:"Melty Blood Actress Again: Current Code"},{executables:{win32:["TheWolfAmongUs.exe"]},id:347,name:"The Wolf Among Us"},{executables:{win32:["SpaceEngineers.exe"]},id:348,name:"Space Engineers"},{executables:{win32:["Borderlands.exe"]},id:349,name:"Borderlands"},{executables:{win32:["100orange.exe"]},id:351,name:"100% Orange Juice"},{executables:{win32:["reflex.exe"]},id:354,name:"Reflex"},{executables:{win32:["pso2.exe"]},id:355,name:"Phantasy Star Online 2"},{executables:{win32:["AssettoCorsa.exe"]},id:356,name:"Assetto Corsa"},{executables:{win32:["iw3mp.exe","iw3sp.exe"]},id:357,name:"Call of Duty 4: Modern Warfare"},{executables:{win32:["WolfOldBlood_x64.exe"]},id:358,name:"Wolfenstein: The Old Blood"},{executables:{win32:["castle.exe"]},id:359,name:"Castle Crashers"},{executables:{win32:["vindictus.exe"]},id:360,name:"Vindictus"},{executables:{win32:["ShooterGame-Win32-Shipping.exe"]},id:361,name:"Dirty Bomb"},{executables:{win32:["BatmanAK.exe"]},id:362,name:"Batman Arkham Knight"},{executables:{win32:["drt.exe"]},id:363,name:"Dirt Rally"},{executables:{win32:["rFactor.exe"]},id:364,name:"rFactor"},{executables:{win32:["clonk.exe"]},id:365,name:"Clonk Rage"},{executables:{win32:["SRHK.exe"]},id:366,name:"Shadowrun: Hong Kong"},{executables:{win32:["Insurgency.exe"]},id:367,name:"Insurgency"},{executables:{win32:["StepMania.exe"]},id:368,name:"Step Mania"},{executables:{win32:["FirefallCLient.exe"]},id:369,name:"Firefall"},{executables:{win32:["mirrorsedge.exe"]},id:370,name:"Mirrors Edge"},{executables:{win32:["MgsGroundZeroes.exe"]},id:371,name:"Metal Gear Solid V: Ground Zeroes"},{executables:{win32:["mgsvtpp.exe"]},id:372,name:"Metal Gear Solid V: The Phantom Pain"},{executables:{win32:["tld.exe"]},id:373,name:"The Long Dark"},{executables:{win32:["TKOM.exe"]},id:374,name:"Take On Mars"},{executables:{win32:["robloxplayerlauncher.exe","Roblox.exe"]},id:375,name:"Roblox"},{executables:{win32:["eu4.exe"]},id:376,name:"Europa Universalis 4"},{executables:{win32:["APB.exe"]},id:377,name:"APB Reloaded"},{executables:{win32:["Robocraft.exe"]},id:378,name:"Robocraft"},{executables:{win32:["Unity.exe"]},id:379,name:"Unity"},{executables:{win32:["Simpsons.exe"]},id:380,name:"The Simpsons: Hit & Run"},{executables:{win32:["Dnlauncher.exe","DragonNest.exe"]},id:381,name:"Dragon Nest"},{executables:{win32:["Trove.exe"]},id:382,name:"Trove"},{executables:{win32:["EndlessLegend.exe"]},id:383,name:"Endless Legend"},{executables:{win32:["TurbineLauncher.exe","dndclient.exe"]},id:384,name:"Dungeons & Dragons Online"},{executables:{win32:["quakelive.exe","quakelive_steam.exe"]},id:385,name:"Quake Live"},{executables:{win32:["7DaysToDie.exe"]},id:386,name:"7DaysToDie"},{executables:{win32:["SpeedRunners.exe"]},id:387,name:"SpeedRunners"},{executables:{win32:["gamemd.exe"]},id:388,name:"Command & Conquer: Red Alert 2"},{executables:{win32:["generals.exe"]},id:389,name:"Command & Conquer Generals: Zero Hour"},{executables:{win32:["Oblivion.exe"]},id:390,name:"The Elder Scrolls 4: Oblivion"},{executables:{win32:["mgsi.exe"]},id:391,name:"Metal Gear Solid"},{executables:{win32:["EoCApp.exe"]},id:392,name:"Divinity - Original Sin"},{executables:{win32:["Torment.exe"]},id:393,name:"Planescape: Torment"},{executables:{win32:["HexPatch.exe"]},id:394,name:"Hex: Shards of Fate"},{executables:{win32:["NS3FB.exe"]},id:395,name:"Naruto Shippuden Ultimate Ninja Storm 3 Full Burst"},{executables:{win32:["NSUNSR.exe"]},id:396,name:"Naruto Shippuden Ultimate Ninja Storm Revolution"},{executables:{win32:["SaintsRowIV.exe"]},id:397,name:"Saints Row IV"},{executables:{win32:["Shadowrun.exe"]},id:398,name:"Shadowrun"},{executables:{win32:["DungeonoftheEndless.exe"]},id:399,name:"Dungeon of the Endless"},{executables:{win32:["Hon.exe"]},id:400,name:"Heroes of Newerth"},{executables:{win32:["mabinogi.exe"]},id:401,name:"Mabinogi"},{executables:{win32:["CoD2MP_s.exe","CoDSP_s.exe"]},id:402,name:"Call of Duty 2:"},{executables:{win32:["CoDWaWmp.exe","CoDWaw.exe"]},id:403,name:"Call of Duty: World at War"},{executables:{win32:["heroes.exe"]},id:404,name:"Mabinogi Heroes (Vindictus) "},{executables:{win32:["KanColleViewer.exe"]},id:405,name:"KanColle "},{executables:{win32:["cyphers.exe"]},id:406,name:"Cyphers"},{executables:{win32:["RelicCoH2.exe"]},id:407,name:"Company of Heroes 2"},{executables:{win32:["MJ.exe"]},id:408,name:"セガNET麻雀MJ"},{executables:{win32:["ge.exe"]},id:409,name:"Granado Espada"},{executables:{win32:["NovaRO.exe"]},id:410,name:"Nova Ragnarok Online"},{executables:{win32:["RivalsofAether.exe"]},id:411,name:"Rivals of Aether"},{executables:{win32:["bfh.exe"]},id:412,name:"Battlefield Hardline"},{executables:{win32:["GrowHome.exe"]},id:413,name:"Grow Home"},{executables:{win32:["patriots.exe"]},id:414,name:"Rise of Nations Extended"},{executables:{win32:["Railroads.exe"]},id:415,name:"Sid Meier's Railroads!"},{executables:{win32:["Empire.exe"]},id:416,name:"Empire: Total War"},{executables:{win32:["Napoleon.exe"]},id:417,name:"Napoleon: Total War"},{executables:{win32:["gta_sa.exe"]},id:418,name:"Grand Theft Auto: San Andreas"},{executables:{win32:["MadMax.exe"]},id:419,name:"Mad Max"},{executables:{win32:["Titanfall.exe"]},id:420,name:"Titanfall"},{executables:{win32:["age2_x1.exe"]},id:421,name:"Age of Empires II: The Conquerors"},{executables:{win32:["Rome2.exe"]},id:422,name:"Total War: ROME 2"},{executables:{win32:["ShadowOfMordor.exe"]},id:423,name:"Middle-earth: Shadow of Mordor"},{executables:{win32:["Subnautica.exe"]},id:424,name:"Subnautica"},{executables:{win32:["anno5.exe"]},id:425,name:"Anno 2070"},{executables:{win32:["carrier.exe"]},id:426,name:"Carrier Command Gaea Mission"},{executables:{win32:["DarksidersPC.exe"]},id:427,name:"Darksiders"},{executables:{win32:["Darksiders2.exe"]},id:428,name:"Darksiders 2"},{executables:{win32:["mudlet.exe"]},id:429,name:"Mudlet"},{executables:{win32:["DunDefLauncher.exe"]},id:430,name:"Dungeon Defenders II"},{executables:{win32:["hng.exe"]},id:431,name:"Heroes and Generals"},{executables:{win32:["WFTOGame.exe"]},id:432,name:"War of the Overworld"},{executables:{win32:["Talisman.exe"]},id:433,name:"Talisman: Digital Edition"},{executables:{win32:["limbo.exe"]},id:434,name:"Limbo"},{executables:{win32:["ibbobb.exe"]},id:435,name:"ibb & obb"},{executables:{win32:["BattleBlockTheater.exe"]},id:436,name:"BattleBlock Theater"},{executables:{win32:["iracinglauncher.exe","iracingsim.exe","iracingsim64.exe"]},id:437,name:"iRacing"},{executables:{win32:["CivilizationV_DX11.exe"]},id:438,name:"Civilization V"}]},{}]},{},[5])(5)});
\ No newline at end of file
diff --git a/web-dist/discord.min.3.7.1.js b/web-dist/discord.min.3.7.1.js
new file mode 100644
index 000000000..84ac649e8
--- /dev/null
+++ b/web-dist/discord.min.3.7.1.js
@@ -0,0 +1,2 @@
+!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Discord=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g]*>/g)||[])[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;a.push(h.substring(2,h.length-1))}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return a}"function"==typeof c&&(d=c,c=!1),b=e+n(b);var p=o();f.resolveDestination(a).then(k)["catch"](j)});return g}},{key:"createws",value:function(a){if(this.websocket)return!1;var b=this;this.websocket=new o(a),this.websocket.onopen=function(){b.trySendConnData()},this.websocket.onclose=function(){b.trigger("disconnected")},this.websocket.onmessage=function(a){var c=!1,d={};try{c=JSON.parse(a.data),d=c.d}catch(e){return void b.trigger("error",e,a)}switch(b.trigger("raw",c),c.t){case"READY":b.debug("received ready packet"),b.user=b.addUser(d.user);var f=!0,h=!1,k=void 0;try{for(var l,m=d.guilds[Symbol.iterator]();!(f=(l=m.next()).done);f=!0)var n=l.value,o=b.addServer(n)}catch(e){h=!0,k=e}finally{try{!f&&m["return"]&&m["return"]()}finally{if(h)throw k}}var p=!0,q=!1,r=void 0;try{for(var s,t=d.private_channels[Symbol.iterator]();!(p=(s=t.next()).done);p=!0){var u=s.value;b.addPMChannel(u)}}catch(e){q=!0,r=e}finally{try{!p&&t["return"]&&t["return"]()}finally{if(q)throw r}}b.trigger("ready"),b.readyTime=Date.now(),b.debug("cached "+b.serverCache.length+" servers, "+b.channelCache.length+" channels, "+b.pmChannelCache.length+" PMs and "+b.userCache.length+" users."),b.state=3,setInterval(function(){b.keepAlive.apply(b)},d.heartbeat_interval);break;case"MESSAGE_CREATE":b.debug("received message");var v=[];d.mentions=d.mentions||[];var w=!0,x=!1,y=void 0;try{for(var z,A=d.mentions[Symbol.iterator]();!(w=(z=A.next()).done);w=!0){var B=z.value;v.push(b.addUser(B))}}catch(e){x=!0,y=e}finally{try{!w&&A["return"]&&A["return"]()}finally{if(x)throw y}}var C=b.getChannel("id",d.channel_id);if(C){var D=C.addMessage(new j(d,C,v,b.addUser(d.author)));b.trigger("message",D)}break;case"MESSAGE_DELETE":b.debug("message deleted");var C=b.getChannel("id",d.channel_id),E=C.getMessage("id",d.id);E?(b.trigger("messageDelete",C,E),C.messages.splice(C.messages.indexOf(E),1)):b.trigger("messageDelete",C);break;case"MESSAGE_UPDATE":b.debug("message updated");var C=b.getChannel("id",d.channel_id),F=C.getMessage("id",d.id);if(F){var G={};for(var H in F)G[H]=F[H];for(var H in d)G[H]=d[H];var v=[],I=!0,J=!1,K=void 0;try{for(var L,M=G.mentions[Symbol.iterator]();!(I=(L=M.next()).done);I=!0){var B=L.value;v.push(b.addUser(B))}}catch(e){J=!0,K=e}finally{try{!I&&M["return"]&&M["return"]()}finally{if(J)throw K}}var N=new j(G,C,v,F.author);b.trigger("messageUpdate",N,F),C.messages[C.messages.indexOf(F)]=N}break;case"GUILD_DELETE":var o=b.getServer("id",d.id);o&&(b.serverCache.splice(b.serverCache.indexOf(o),1),b.trigger("serverDelete",o));break;case"CHANNEL_DELETE":var C=b.getChannel("id",d.id);if(C){var o=C.server;o&&o.channels.splice(o.channels.indexOf(C),1),b.trigger("channelDelete",C),b.serverCache.splice(b.serverCache.indexOf(C),1)}break;case"GUILD_CREATE":var o=b.getServer("id",d.id);if(o||(o=b.addServer(d)),b.serverCreateListener[d.id]){var O=b.serverCreateListener[d.id];O[0](o),O[1](null,o),b.serverCreateListener[d.id]=null}b.trigger("serverCreate",o);break;case"CHANNEL_CREATE":var C=b.getChannel("id",d.id);if(!C){var P=b.addChannel(d,d.guild_id),Q=b.getServer("id",d.guild_id);Q&&Q.addChannel(P),b.trigger("channelCreate",P)}break;case"GUILD_MEMBER_ADD":var o=b.getServer("id",d.guild_id);if(o){var R=b.addUser(d.user);~o.members.indexOf(R)||o.members.push(R),b.trigger("serverNewMember",R,o)}break;case"GUILD_MEMBER_REMOVE":var o=b.getServer("id",d.guild_id);if(o){var R=b.addUser(d.user);~o.members.indexOf(R)&&o.members.splice(o.members.indexOf(R),1),b.trigger("serverRemoveMember",R,o)}break;case"USER_UPDATE":if(b.user&&d.id===b.user.id){var S=new g(d);b.trigger("userUpdate",S,b.user),~b.userCache.indexOf(b.user)&&(b.userCache[b.userCache.indexOf(b.user)]=S),b.user=S}break;case"PRESENCE_UPDATE":var T=b.getUser("id",d.user.id);if(T){var U=new g(d.user);U.equalsStrict(T)?(T.status=d.status,b.trigger("presence",{user:T,status:d.status,server:b.getServer("id",d.guild_id),gameId:d.game_id})):(b.trigger("userUpdate",T,U),b.userCache[b.userCache.indexOf(T)]=U)}break;case"CHANNEL_UPDATE":var V=b.getChannel("id",d.id),W=b.getServer("id",d.guild_id);if(V&&W){var X=new i(d,W);X.messages=V.messages,b.trigger("channelUpdate",V,X),b.channelCache[b.channelCache.indexOf(V)]=X}break;default:b.debug("received unknown packet"),b.trigger("unknown",c)}}}},{key:"addUser",value:function(a){return this.getUser("id",a.id)||this.userCache.push(new g(a)),this.getUser("id",a.id)}},{key:"addChannel",value:function(a,b){return this.getChannel("id",a.id)||this.channelCache.push(new i(a,this.getServer("id",b))),this.getChannel("id",a.id)}},{key:"addPMChannel",value:function(a){return this.getPMChannel("id",a.id)||this.pmChannelCache.push(new l(a,this)),this.getPMChannel("id",a.id)}},{key:"setTopic",value:function(a,b){var c=arguments.length<=2||void 0===arguments[2]?function(a){}:arguments[2],d=this;return new Promise(function(e,g){function h(a){c(a),g(a)}function i(a){var g=d.getChannel("id",a);n.patch(f.CHANNELS+"/"+a).set("authorization",d.token).send({name:g.name,position:0,topic:b}).end(function(a,b){a?h(a):(g.topic=b.body.topic,e(),c())})}d.resolveDestination(a).then(i)["catch"](h)})}},{key:"addServer",value:function(a){var b=this,c=this.getServer("id",a.id);if(a.unavailable)return b.trigger("unavailable",a),void b.debug("Server ID "+a.id+" has been marked unavailable by Discord. It was not cached.");if(!c&&(c=new h(a,this),this.serverCache.push(c),a.channels)){var d=!0,e=!1,f=void 0;try{for(var g,i=a.channels[Symbol.iterator]();!(d=(g=i.next()).done);d=!0){var j=g.value;c.channels.push(this.addChannel(j,c.id))}}catch(k){e=!0,f=k}finally{try{!d&&i["return"]&&i["return"]()}finally{if(e)throw f}}}var l=!0,m=!1,n=void 0;try{for(var o,p=a.presences[Symbol.iterator]();!(l=(o=p.next()).done);l=!0){var q=o.value;b.getUser("id",q.user.id).status=q.status}}catch(k){m=!0,n=k}finally{try{!l&&p["return"]&&p["return"]()}finally{if(m)throw n}}return c}},{key:"getUser",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.userCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.channelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return this.getPMChannel(a,b)}},{key:"getPMChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.pmChannelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getServer",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.serverCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"trySendConnData",value:function(){if(this.token&&!this.alreadySentData){this.alreadySentData=!0;var a={op:2,d:{token:this.token,v:3,properties:{$os:"discord.js",$browser:"discord.js",$device:"discord.js",$referrer:"",$referring_domain:""}}};this.websocket.send(JSON.stringify(a))}}},{key:"resolveServerID",value:function(a){return a instanceof h?a.id:!isNaN(a)&&a.length&&17===a.length?a:void 0}},{key:"resolveDestination",value:function(a){var b=!1,c=this;return new Promise(function(d,e){if(a instanceof h)b=a.id;else if(a instanceof i)b=a.id;else if(a instanceof j)b=a.channel.id;else if(a instanceof l)b=a.id;else if(a instanceof g){var f=!0,k=!1,m=void 0;try{for(var n,o=c.pmChannelCache[Symbol.iterator]();!(f=(n=o.next()).done);f=!0){var p=n.value;if(p.user.equals(a))return void d(p.id)}}catch(q){k=!0,m=q}finally{try{!f&&o["return"]&&o["return"]()}finally{if(k)throw m}}c.startPM(a).then(function(a){d(a.id)})["catch"](e)}else b=a;b?d(b):e()})}},{key:"_sendMessage",value:function(a,b,c,d){var e=this;return new Promise(function(g,h){n.post(f.CHANNELS+"/"+a+"/messages").set("authorization",e.token).send({content:b,mentions:d,tts:c}).end(function(a,b){if(a)h(a);else{var c=b.body,d=[];c.mentions=c.mentions||[];var f=!0,i=!1,k=void 0;try{for(var l,m=c.mentions[Symbol.iterator]();!(f=(l=m.next()).done);f=!0){var n=l.value;d.push(e.addUser(n))}}catch(a){i=!0,k=a}finally{try{!f&&m["return"]&&m["return"]()}finally{if(i)throw k}}var o=e.getChannel("id",c.channel_id);if(o){var p=o.addMessage(new j(c,o,d,e.addUser(c.author)));g(p)}}})})}},{key:"_sendFile",value:function(a,b){var c=arguments.length<=2||void 0===arguments[2]?"DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png":arguments[2],d=this;return new Promise(function(e,g){n.post(f.CHANNELS+"/"+a+"/messages").set("authorization",d.token).attach("file",b,c).end(function(b,c){if(b)g(b);else{var f=d.getChannel("id",a);if(f){var h=f.addMessage(new j(c.body,f,[],d.user));e(h)}}})})}},{key:"_updateMessage",value:function(a,b){var c=this;return new Promise(function(d,e){n.patch(f.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",c.token).send({content:b,mentions:[]}).end(function(b,c){if(b)e(b);else{var f=new j(c.body,a.channel,a.mentions,a.sender);d(f),a.channel.messages[a.channel.messages.indexOf(a)]=f}})})}},{key:"_deleteMessage",value:function(a){var b=this;return new Promise(function(c,d){n.del(f.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",b.token).end(function(a,b){a?d(a):c()})})}},{key:"checkQueue",value:function(a){var b=this,c=this;this.checkingQueue[a]||!function(){var d=function f(){if(0===c.queue[a].length)return void e();var b=c.queue[a][0];switch(b.action){case"sendMessage":var d=b;c._sendMessage(a,d.content,d.tts,d.mentions).then(function(b){d.then(b),c.queue[a].shift(),f()})["catch"](function(b){d.error(b),c.queue[a].shift(),f()});break;case"sendFile":var g=b;c._sendFile(a,g.attachment,g.attachmentName).then(function(b){g.then(b),c.queue[a].shift(),f()})["catch"](function(b){g.error(b),c.queue[a].shift(),f()});break;case"updateMessage":var h=b;c._updateMessage(h.message,h.content).then(function(b){h.then(b),c.queue[a].shift(),f()})["catch"](function(b){h.error(b),c.queue[a].shift(),f()});break;case"deleteMessage":var i=b;c._deleteMessage(i.message).then(function(b){i.then(b),c.queue[a].shift(),f()})["catch"](function(b){i.error(b),c.queue[a].shift(),f()});break;default:e()}},e=function(){c.checkingQueue[a]=!1};b.checkingQueue[a]=!0,d()}()}},{key:"getGateway",value:function(){var a=this;return new Promise(function(b,c){n.get(f.API+"/gateway").set("authorization",a.token).end(function(a,d){a?c(a):b(d.body.url)})})}},{key:"setStatusIdle",value:function(){this.setStatus("idle")}},{key:"setStatusOnline",value:function(){this.setStatus("online")}},{key:"setStatusActive",value:function(){this.setStatusOnline()}},{key:"setStatusHere",value:function(){this.setStatusOnline()}},{key:"setStatusAway",value:function(){this.setStatusIdle()}},{key:"startTyping",value:function(a,b){function c(a){if(!d.typingIntervals[a]){var c=function(){n.post(f.CHANNELS+"/"+a+"/typing").set("authorization",d.token).end()};c();var e=setInterval(c,3e3);d.typingIntervals[a]=e,b&&setTimeout(function(){d.stopTyping(a)},b)}}var d=this;this.resolveDestination(a).then(c)}},{key:"stopTyping",value:function(a){function b(a){c.typingIntervals[a]&&(clearInterval(c.typingIntervals[a]),delete c.typingIntervals[a])}var c=this;this.resolveDestination(a).then(b)}},{key:"setStatus",value:function(a){var b="online"===a?null:Date.now();this.__idleTime=b,this.websocket.send(JSON.stringify({op:3,d:{idle_since:this.__idleTime,game_id:this.__gameId}}))}},{key:"setPlayingGame",value:function(a){if(a instanceof String||"string"==typeof a){var b=a.trim().toUpperCase();a=null;var c=!0,d=!1,e=void 0;try{for(var f,g=m[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h.name.trim().toUpperCase()===b){a=h.id;break}}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}}this.__gameId=a,this.websocket.send(JSON.stringify({op:3,d:{idle_since:this.__idleTime,game_id:this.__gameId}}))}},{key:"playGame",value:function(a){this.setPlayingGame(a)}},{key:"playingGame",value:function(a){this.setPlayingGame(a)}},{key:"uptime",get:function(){return this.readyTime?Date.now()-this.readyTime:null}},{key:"ready",get:function(){return 3===this.state}},{key:"servers",get:function(){return this.serverCache}},{key:"channels",get:function(){return this.channelCache}},{key:"users",get:function(){return this.userCache}},{key:"PMChannels",get:function(){return this.pmChannelCache}},{key:"messages",get:function(){var a=[],b=!0,c=!1,d=void 0;try{for(var e,f=this.channelCache[Symbol.iterator]();!(b=(e=f.next()).done);b=!0){var g=e.value;a=a.concat(g.messages)}}catch(h){c=!0,d=h}finally{try{!b&&f["return"]&&f["return"]()}finally{if(c)throw d}}return a}}]),a}();b.exports=r},{"../ref/gameMap.json":15,"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,fs:10,superagent:11,ws:14}],2:[function(a,b,c){"use strict";c.BASE_DOMAIN="discordapp.com",c.BASE="https://"+c.BASE_DOMAIN,c.WEBSOCKET_HUB="wss://"+c.BASE_DOMAIN+"/hub",c.API=c.BASE+"/api",c.AUTH=c.API+"/auth",c.LOGIN=c.AUTH+"/login",c.LOGOUT=c.AUTH+"/logout",c.USERS=c.API+"/users",c.SERVERS=c.API+"/guilds",c.CHANNELS=c.API+"/channels"},{}],3:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c1e3&&this.messages.splice(0,1);var c=!0,d=!1,e=void 0;try{for(var f,g=this.messages[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"isPrivate",get:function(){return!0}}]),a}();b.exports=f},{}],4:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c1e3&&this.messages.splice(0,1),this.getMessage("id",a.id)||this.messages.push(a),this.getMessage("id",a.id)}},{key:"getMessage",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.messages[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"toString",value:function(){return"<#"+this.id+">"}},{key:"client",get:function(){return this.server.client}},{key:"isPrivate",get:function(){return!1}},{key:"users",get:function(){return this.server.members}},{key:"members",get:function(){return this.server.members}}]),a}();b.exports=f},{}],5:[function(a,b,c){"use strict";var d=(a("superagent"),a("./Endpoints.js")),e=a("./Client.js"),f={Endpoints:d,Client:e};b.exports=f},{"./Client.js":1,"./Endpoints.js":2,superagent:11}],6:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c"}},{key:"toString",value:function(){return this.mention()}},{key:"equals",value:function(a){return a.id===this.id}},{key:"equalsStrict",value:function(a){return a.id===this.id&&a.avatar===this.avatar&&a.username===this.username&&a.discriminator===this.discriminator}},{key:"avatarURL",get:function(){return this.avatar?"https://discordapp.com/api/users/"+this.id+"/avatars/"+this.avatar+".jpg":null}}]),a}();b.exports=f},{}],10:[function(a,b,c){},{}],11:[function(a,b,c){function d(){}function e(a){var b={}.toString.call(a);switch(b){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function f(a){return a===Object(a)}function g(a){if(!f(a))return a;var b=[];for(var c in a)null!=a[c]&&b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")}function h(a){for(var b,c,d={},e=a.split("&"),f=0,g=e.length;g>f;++f)c=e[f],b=c.split("="),d[decodeURIComponent(b[0])]=decodeURIComponent(b[1]);return d}function i(a){var b,c,d,e,f=a.split(/\r?\n/),g={};f.pop();for(var h=0,i=f.length;i>h;++h)c=f[h],b=c.indexOf(":"),d=c.slice(0,b).toLowerCase(),e=r(c.slice(b+1)),g[d]=e;return g}function j(a){return a.split(/ *; */).shift()}function k(a){return p(a.split(/ *; */),function(a,b){var c=b.split(/ *= */),d=c.shift(),e=c.shift();return d&&e&&(a[d]=e),a},{})}function l(a,b){b=b||{},this.req=a,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,
+this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=i(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function m(a,b){var c=this;o.call(this),this._query=this._query||[],this.method=a,this.url=b,this.header={},this._header={},this.on("end",function(){var a=null,b=null;try{b=new l(c)}catch(d){return a=new Error("Parser is unable to parse the response"),a.parse=!0,a.original=d,c.callback(a)}if(c.emit("response",b),a)return c.callback(a,b);if(b.status>=200&&b.status<300)return c.callback(a,b);var e=new Error(b.statusText||"Unsuccessful HTTP response");e.original=a,e.response=b,e.status=b.status,c.callback(e,b)})}function n(a,b){return"function"==typeof b?new m("GET",a).end(b):1==arguments.length?new m("GET",a):new m(a,b)}var o=a("emitter"),p=a("reduce"),q="undefined"==typeof window?this||self:window;n.getXHR=function(){if(!(!q.XMLHttpRequest||q.location&&"file:"==q.location.protocol&&q.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(a){}return!1};var r="".trim?function(a){return a.trim()}:function(a){return a.replace(/(^\s*|\s*$)/g,"")};n.serializeObject=g,n.parseString=h,n.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},n.serialize={"application/x-www-form-urlencoded":g,"application/json":JSON.stringify},n.parse={"application/x-www-form-urlencoded":h,"application/json":JSON.parse},l.prototype.get=function(a){return this.header[a.toLowerCase()]},l.prototype.setHeaderProperties=function(a){var b=this.header["content-type"]||"";this.type=j(b);var c=k(b);for(var d in c)this[d]=c[d]},l.prototype.parseBody=function(a){var b=n.parse[this.type];return b&&a&&(a.length||a instanceof Object)?b(a):null},l.prototype.setStatusProperties=function(a){1223===a&&(a=204);var b=a/100|0;this.status=a,this.statusType=b,this.info=1==b,this.ok=2==b,this.clientError=4==b,this.serverError=5==b,this.error=4==b||5==b?this.toError():!1,this.accepted=202==a,this.noContent=204==a,this.badRequest=400==a,this.unauthorized=401==a,this.notAcceptable=406==a,this.notFound=404==a,this.forbidden=403==a},l.prototype.toError=function(){var a=this.req,b=a.method,c=a.url,d="cannot "+b+" "+c+" ("+this.status+")",e=new Error(d);return e.status=this.status,e.method=b,e.url=c,e},n.Response=l,o(m.prototype),m.prototype.use=function(a){return a(this),this},m.prototype.timeout=function(a){return this._timeout=a,this},m.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},m.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0,this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this)},m.prototype.set=function(a,b){if(f(a)){for(var c in a)this.set(c,a[c]);return this}return this._header[a.toLowerCase()]=b,this.header[a]=b,this},m.prototype.unset=function(a){return delete this._header[a.toLowerCase()],delete this.header[a],this},m.prototype.getHeader=function(a){return this._header[a.toLowerCase()]},m.prototype.type=function(a){return this.set("Content-Type",n.types[a]||a),this},m.prototype.accept=function(a){return this.set("Accept",n.types[a]||a),this},m.prototype.auth=function(a,b){var c=btoa(a+":"+b);return this.set("Authorization","Basic "+c),this},m.prototype.query=function(a){return"string"!=typeof a&&(a=g(a)),a&&this._query.push(a),this},m.prototype.field=function(a,b){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b),this},m.prototype.attach=function(a,b,c){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b,c),this},m.prototype.send=function(a){var b=f(a),c=this.getHeader("Content-Type");if(b&&f(this._data))for(var d in a)this._data[d]=a[d];else"string"==typeof a?(c||this.type("form"),c=this.getHeader("Content-Type"),"application/x-www-form-urlencoded"==c?this._data=this._data?this._data+"&"+a:a:this._data=(this._data||"")+a):this._data=a;return!b||e(a)?this:(c||this.type("json"),this)},m.prototype.callback=function(a,b){var c=this._callback;this.clearTimeout(),c(a,b)},m.prototype.crossDomainError=function(){var a=new Error("Origin is not allowed by Access-Control-Allow-Origin");a.crossDomain=!0,this.callback(a)},m.prototype.timeoutError=function(){var a=this._timeout,b=new Error("timeout of "+a+"ms exceeded");b.timeout=a,this.callback(b)},m.prototype.withCredentials=function(){return this._withCredentials=!0,this},m.prototype.end=function(a){var b=this,c=this.xhr=n.getXHR(),f=this._query.join("&"),g=this._timeout,h=this._formData||this._data;this._callback=a||d,c.onreadystatechange=function(){if(4==c.readyState){var a;try{a=c.status}catch(d){a=0}if(0==a){if(b.timedout)return b.timeoutError();if(b.aborted)return;return b.crossDomainError()}b.emit("end")}};var i=function(a){a.total>0&&(a.percent=a.loaded/a.total*100),b.emit("progress",a)};this.hasListeners("progress")&&(c.onprogress=i);try{c.upload&&this.hasListeners("progress")&&(c.upload.onprogress=i)}catch(j){}if(g&&!this._timer&&(this._timer=setTimeout(function(){b.timedout=!0,b.abort()},g)),f&&(f=n.serializeObject(f),this.url+=~this.url.indexOf("?")?"&"+f:"?"+f),c.open(this.method,this.url,!0),this._withCredentials&&(c.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof h&&!e(h)){var k=this.getHeader("Content-Type"),l=n.serialize[k?k.split(";")[0]:""];l&&(h=l(h))}for(var m in this.header)null!=this.header[m]&&c.setRequestHeader(m,this.header[m]);return this.emit("request",this),c.send(h),this},m.prototype.then=function(a,b){return this.end(function(c,d){c?b(c):a(d)})},n.Request=m,n.get=function(a,b,c){var d=n("GET",a);return"function"==typeof b&&(c=b,b=null),b&&d.query(b),c&&d.end(c),d},n.head=function(a,b,c){var d=n("HEAD",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.del=function(a,b){var c=n("DELETE",a);return b&&c.end(b),c},n.patch=function(a,b,c){var d=n("PATCH",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.post=function(a,b,c){var d=n("POST",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.put=function(a,b,c){var d=n("PUT",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},b.exports=n},{emitter:12,reduce:13}],12:[function(a,b,c){function d(a){return a?e(a):void 0}function e(a){for(var b in d.prototype)a[b]=d.prototype[b];return a}b.exports=d,d.prototype.on=d.prototype.addEventListener=function(a,b){return this._callbacks=this._callbacks||{},(this._callbacks[a]=this._callbacks[a]||[]).push(b),this},d.prototype.once=function(a,b){function c(){d.off(a,c),b.apply(this,arguments)}var d=this;return this._callbacks=this._callbacks||{},c.fn=b,this.on(a,c),this},d.prototype.off=d.prototype.removeListener=d.prototype.removeAllListeners=d.prototype.removeEventListener=function(a,b){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var c=this._callbacks[a];if(!c)return this;if(1==arguments.length)return delete this._callbacks[a],this;for(var d,e=0;ed;++d)c[d].apply(this,b)}return this},d.prototype.listeners=function(a){return this._callbacks=this._callbacks||{},this._callbacks[a]||[]},d.prototype.hasListeners=function(a){return!!this.listeners(a).length}},{}],13:[function(a,b,c){b.exports=function(a,b,c){for(var d=0,e=a.length,f=3==arguments.length?c:a[d++];e>d;)f=b.call(null,f,a[d],++d,a);return f}},{}],14:[function(a,b,c){function d(a,b,c){var d;return d=b?new f(a,b):new f(a)}var e=function(){return this}(),f=e.WebSocket||e.MozWebSocket;b.exports=f?d:null,f&&(d.prototype=f.prototype)},{}],15:[function(a,b,c){b.exports=[{executables:{win32:["pol.exe"]},id:0,name:"FINAL FANTASY XI"},{executables:{win32:["ffxiv.exe","ffxiv_dx11.exe"]},id:1,name:"FINAL FANTASY XIV"},{executables:{win32:["Wow.exe","Wow-64.exe"]},id:3,name:"World of Warcraft"},{executables:{darwin:["LoLLauncher.app"],win32:["LolClient.exe","League of Legends.exe"]},id:4,name:"League of Legends"},{executables:{darwin:["Diablo%20III.app"],win32:["Diablo III.exe"]},id:5,name:"Diablo 3"},{executables:{darwin:["dota_osx.app"],win32:["dota2.exe"]},id:6,name:"DOTA 2"},{executables:{darwin:["Heroes.app"],win32:["Heroes of the Storm.exe","HeroesOfTheStorm_x64.exe","HeroesOfTheStorm.exe"]},id:7,name:"Heroes of the Storm"},{executables:{darwin:["Hearthstone.app"],win32:["Hearthstone.exe"]},id:8,name:"Hearthstone"},{executables:{win32:["csgo.exe"]},id:9,name:"Counter-Strike: Global Offensive"},{executables:{win32:["WorldOfTanks.exe"]},id:10,name:"World of Tanks"},{executables:{darwin:["gw2.app"],win32:["gw2.exe"]},id:11,name:"Guild Wars 2"},{executables:{win32:["dayz.exe"]},id:12,name:"Day Z"},{executables:{darwin:["starcraft%20ii.app"],win32:["starcraft ii.exe","SC2_x64.exe","SC2.exe"]},id:13,name:"Starcraft II"},{executables:{win32:["diablo.exe"]},id:14,name:"Diablo"},{executables:{win32:["diablo ii.exe"]},id:15,name:"Diablo 2"},{executables:{win32:["left4dead.exe"]},id:17,name:"Left 4 Dead"},{executables:{darwin:["minecraft.app"],win32:["minecraft.exe"]},id:18,name:"Minecraft"},{executables:{win32:["smite.exe"]},id:19,name:"Smite"},{executables:{win32:["bf4.exe"]},id:20,name:"Battlefield 4"},{executables:{win32:["AoK HD.exe","empires2.exe"]},id:101,name:"Age of Empire II"},{executables:{win32:["age3y.exe"]},id:102,name:"Age of Empire III"},{executables:{win32:["AlanWake.exe"]},id:104,name:"Alan Wake"},{executables:{win32:["alan_wakes_american_nightmare.exe"]},id:105,name:"Alan Wake's American Nightmare"},{executables:{win32:["AlienBreed2Assault.exe"]},id:106,name:"Alien Breed 2: Assault"},{executables:{win32:["Amnesia.exe"]},id:107,name:"Amnesia: The Dark Descent"},{executables:{win32:["UDK.exe"]},id:108,name:"Antichamber"},{executables:{win32:["ArcheAge.exe"]},id:109,name:"ArcheAge"},{executables:{win32:["arma3.exe"]},id:110,name:"Arma III"},{executables:{win32:["AC3SP.exe"]},id:111,name:"Assassin's Creed 3"},{executables:{win32:["Bastion.exe"]},id:112,name:"Bastion"},{executables:{win32:["BF2.exe"]},id:113,name:"Battlefield 2"},{executables:{win32:["bf3.exe"]},id:114,name:"Battlefield 3"},{executables:{win32:["Besiege.exe"]},id:116,name:"Besiege"},{executables:{win32:["Bioshock.exe"]},id:117,name:"Bioshock"},{executables:{win32:["Bioshock2.exe"]},id:118,name:"BioShock II"},{executables:{win32:["BioShockInfinite.exe"]},id:119,name:"BioShock Infinite"},{executables:{win32:["Borderlands2.exe"]},id:122,name:"Borderlands 2"},{executables:{win32:["braid.exe"]},id:123,name:"Braid"},{executables:{win32:["ShippingPC-StormGame.exe"]},id:124,name:"Bulletstorm"},{executables:{},id:125,name:"Cabal 2"},{executables:{win32:["CabalMain.exe"]},id:126,name:"Cabal Online"},{executables:{win32:["iw4mp.exe","iw4sp.exe"]},id:127,name:"Call of Duty: Modern Warfare 2"},{executables:{win32:["t6sp.exe"]},id:128,name:"Call of Duty: Black Ops"},{executables:{win32:["iw5mp.exe"]},id:129,name:"Call of Duty: Modern Warfare 3"},{executables:{win32:["RelicCOH.exe"]},id:132,name:"Company of Heroes"},{executables:{win32:["Crysis64.exe"]},id:135,name:"Crysis"},{executables:{win32:["Crysis2.exe"]},id:136,name:"Crysis 2"},{executables:{win32:["Crysis3.exe"]},id:137,name:"Crysis 3"},{executables:{win32:["Crysis.exe"]},id:138,name:"Crysis 4 "},{executables:{win32:["DATA.exe"]},id:140,name:"Dark Souls"},{executables:{win32:["DarkSoulsII.exe"]},id:141,name:"Dark Souls II"},{executables:{win32:["dfuw.exe"]},id:142,name:"Darkfall: Unholy Wars"},{executables:{win32:["DCGAME.exe"]},id:144,name:"DC Universe Online"},{executables:{win32:["DeadIslandGame.exe"]},id:145,name:"Dead Island"},{executables:{win32:["deadspace2.exe"]},id:146,name:"Dead Space 2"},{executables:{win32:["LOTDGame.exe"]},id:147,name:"Deadlight"},{executables:{win32:["dxhr.exe"]},id:148,name:"Deus Ex: Human Revolution"},{executables:{win32:["DeviMayCry4.exe"]},id:149,name:"Devil May Cry 4"},{executables:{win32:["DMC-DevilMayCry.exe"]},id:150,name:"DmC Devil May Cry"},{executables:{win32:["dirt2_game.exe"]},id:154,name:"DiRT 2"},{executables:{win32:["dirt3_game.exe"]},id:155,name:"DiRT 3"},{executables:{win32:["dota.exe"]},id:156,name:"DOTA"},{executables:{win32:["DoubleDragon.exe"]},id:158,name:"Double Dragon Neon"},{executables:{win32:["DragonAge2.exe"]},id:159,name:"Dragon Age II"},{executables:{win32:["DragonAgeInquisition.exe"]},id:160,name:"Dragon Age: Inquisition"},{executables:{win32:["daorigins.exe"]},id:161,name:"Dragon Age: Origins"},{executables:{win32:["DBXV.exe"]},id:162,name:"Dragon Ball XenoVerse"},{executables:{win32:["DukeForever.exe"]},id:163,name:"Duke Nukem Forever"},{executables:{darwin:["Dustforce.app"],win32:["dustforce.exe"]},id:164,name:"Dustforce"},{executables:{win32:["EliteDangerous32.exe"]},id:165,name:"Elite: Dangerous"},{executables:{win32:["exefile.exe"]},id:166,name:"Eve Online"},{executables:{win32:["eqgame.exe"]},id:167,name:"EverQuest"},{executables:{win32:["EverQuest2.exe"]},id:168,name:"EverQuest II"},{executables:{},id:169,name:"EverQuest Next"},{executables:{win32:["Engine.exe"]},id:170,name:"F.E.A.R."},{executables:{win32:["FEAR2.exe"]},id:171,name:"F.E.A.R. 2: Project Origin"},{executables:{win32:["fallout3.exe"]},id:172,name:"Fallout 3"},{executables:{win32:["FalloutNV.exe"]},id:174,name:"Fallout: New Vegas"},{executables:{win32:["farcry3.exe"]},id:175,name:"Far Cry 3"},{executables:{win32:["fifa15.exe"]},id:176,name:"FIFA 15"},{executables:{win32:["FTLGame.exe"]},id:180,name:"FTL: Faster Than Light"},{executables:{win32:["GTAIV.exe"]},id:181,name:"Grand Theft Auto 4"},{executables:{win32:["GTA5.exe"]},id:182,name:"Grand Theft Auto 5"},{executables:{win32:["Gw.exe"]},id:183,name:"Guild Wars"},{executables:{win32:["H1Z1.exe"]},id:186,name:"H1Z1"},{executables:{win32:["HL2HL2.exe","hl2.exe"]},id:188,name:"Half Life 2"},{executables:{win32:["HOMEFRONT.exe"]},id:195,name:"Homefront"},{executables:{win32:["invisibleinc.exe"]},id:196,name:"Invisible Inc."},{executables:{win32:["LANoire.exe"]},id:197,name:"L.A. Noire"},{executables:{win32:["Landmark64.exe"]},id:198,name:"Landmark"},{executables:{win32:["left4dead2.exe"]},id:201,name:"Left 4 Dead 2"},{executables:{win32:["lineage.exe"]},id:203,name:"Lineage"},{executables:{win32:["Magicka.exe"]},id:206,name:"Magicka"},{executables:{win32:["MapleStory.exe"]},id:208,name:"MapleStory"},{executables:{},id:209,name:"Mark of the Ninja"},{executables:{win32:["MassEffect.exe"]},id:210,name:"Mass Effect"},{executables:{win32:["MassEffect2.exe"]},id:211,name:"Mass Effect 2"},{executables:{win32:["MassEffect3Demo.exe"]},id:212,name:"Mass Effect 3"},{executables:{win32:["METAL GEAR RISING REVENGEANCE.exe"]},id:214,name:"Metal Gear Rising: Revengeance"},{executables:{win32:["metro2033.exe"]},id:215,name:"Metro 2033"},{executables:{win32:["MetroLL.exe"]},id:216,name:"Metro Last Light"},{executables:{win32:["MK10.exe"]},id:218,name:"Mortal Kombat X"},{executables:{win32:["speed.exe"]},id:219,name:"Need For Speed Most Wanted"},{executables:{},id:220,name:"Neverwinder"},{executables:{darwin:["Outlast.app"],win32:["OLGame.exe"]},id:221,name:"Outlast"},{executables:{win32:["PapersPlease.exe"]},id:222,name:"Papers, Please"},{executables:{win32:["payday_win32_release.exe"]},id:223,name:"PAYDAY"},{executables:{win32:["payday2_win32_release.exe"]},id:224,name:"PAYDAY2"},{executables:{win32:["PillarsOfEternity.exe"]},id:225,name:"Pillars of Eternity"},{executables:{win32:["PA.exe"]},id:226,name:"Planetary Annihilation"},{executables:{win32:["planetside2_x86.exe"]},id:227,name:"Planetside 2"},{executables:{win32:["hl2P.exe"]},id:228,name:"Portal"},{executables:{win32:["portal2.exe"]},id:229,name:"Portal 2"},{executables:{win32:["PrimalCarnageGame.exe"]},id:231,name:"Primal Cargnage"},{executables:{win32:["pCARS.exe"]},id:232,name:"Project Cars"},{executables:{win32:["RaceTheSun.exe"]},id:233,name:"Race The Sun"},{executables:{win32:["Rage.exe"]},id:234,name:"RAGE"},{executables:{win32:["ragexe.exe"]},id:235,name:"Ragnarok Online"},{executables:{win32:["rift.exe"]},id:236,name:"Rift"},{executables:{win32:["Rocksmith2014.exe"]},id:237,name:"Rocksmith 2014"},{executables:{win32:["SwiftKit-RS.exe","JagexLauncher.exe"]},id:238,name:"RuneScape"},{executables:{win32:["Shadowgrounds.exe"]},id:239,name:"Shadowgrounds"},{executables:{win32:["survivor.exe"]},id:240,name:"Shadowgrounds: Survivor"},{executables:{win32:["ShovelKnight.exe"]},id:241,name:"Shovel Knight"},{executables:{win32:["SimCity.exe"]},id:242,name:"SimCity"},{executables:{win32:["SporeApp.exe"]},id:245,name:"Spore"},{executables:{win32:["StarCitizen.exe"]},id:246,name:"Star Citizen"},{executables:{},id:247,name:"Star Trek Online"},{executables:{win32:["battlefront.exe"]},id:248,name:"Star Wars Battlefront"},{executables:{win32:["swtor.exe"]},id:249,name:"Star Wars: The Old Republic"},{executables:{win32:["starbound.exe","starbound_opengl.exe"]},id:250,name:"Starbound"},{executables:{win32:["starcraft.exe"]},id:251,name:"Starcraft"},{executables:{win32:["SSFIV.exe"]},id:253,name:"Ultra Street Fighter IV"},{executables:{win32:["superhexagon.exe"]},id:254,name:"Super Hexagon"},{executables:{win32:["swordandsworcery_pc.exe"]},id:255,name:"Superbrothers: Sword & Sworcery EP"},{executables:{win32:["hl2TF.exe"]},id:256,name:"Team Fortress 2"},{executables:{win32:["TERA.exe"]},id:258,name:"TERA"},{executables:{win32:["Terraria.exe"]},id:259,name:"Terraria"},{executables:{win32:["Bethesda.net_Launcher.exe"]},id:260,name:"The Elder Scrolls Online"},{executables:{win32:["TESV.exe"]},id:261,name:"The Elder Scrolls V: Skyrim"},{executables:{win32:["TheSecretWorld.exe"]},id:262,name:"The Secret World"},{executables:{win32:["TS3.exe","ts3w.exe"]},id:264,name:"The Sims 3"},{executables:{win32:["WALKINGDEAD101.EXE"]},id:265,name:"The Walking Dead"},{executables:{win32:["TheWalkingDead2.exe"]},id:266,name:"The Walking Dead Season Two"},{executables:{win32:["witcher3.exe"]},id:267,name:"The Witcher 3"},{executables:{win32:["Future Soldier.exe"]},id:268,name:"Tom Clancy's Ghost Recon: Future Solider"},{executables:{win32:["TombRaider.exe"]},id:269,name:"Tomb Raider (2013)"},{executables:{win32:["Torchlight.exe"]},id:271,name:"Torchlight"},{executables:{win32:["Torchlight2.exe"]},id:272,name:"Torchlight 2"},{executables:{win32:["Shogun2.exe"]},id:273,name:"Total War: Shogun 2"},{executables:{win32:["Transistor.exe"]},id:274,name:"Transistor"},{executables:{win32:["trine.exe"]},id:275,name:"Trine"},{executables:{win32:["trine2_32bit.exe"]},id:276,name:"Trine 2"},{executables:{win32:["UOKR.exe"]},id:277,name:"Ultima Online"},{executables:{win32:["aces.exe"]},id:279,name:"War Thunder"},{executables:{win32:["Warcraft III.exe","wc3.exe"]},id:281,name:"Warcraft 3: Reign of Chaos"},{executables:{win32:["Warcraft II BNE.exe"]},id:282,name:"Warcraft II"},{executables:{win32:["Warframe.x64.exe","Warframe.exe"]},id:283,name:"Warframe"},{executables:{win32:["watch_dogs.exe"]},id:284,name:"Watch Dogs"},{executables:{win32:["WildStar64.exe"]},id:285,name:"WildStar"},{executables:{win32:["XComGame.exe"]},id:288,name:"XCOM: Enemy Unknown"},{executables:{win32:["DFO.exe","dfo.exe"]},id:289,name:"Dungeon Fighter Online"},{executables:{win32:["aclauncher.exe","acclient.exe"]},id:290,name:"Asheron's Call"},{executables:{win32:["MapleStory2.exe"]},id:291,name:"MapleStory 2"},{executables:{win32:["ksp.exe"]},id:292,name:"Kerbal Space Program"},{executables:{win32:["PINBALL.EXE"]},id:293,name:"3D Pinball: Space Cadet"},{executables:{win32:["dave.exe"]},id:294,name:"Dangerous Dave"},{executables:{win32:["iwbtgbeta(slomo).exe","iwbtgbeta(fs).exe"]},id:295,name:"I Wanna Be The Guy"},{executables:{win32:["MechWarriorOnline.exe "]},id:296,name:"Mech Warrior Online"},{executables:{win32:["dontstarve_steam.exe"]},id:297,name:"Don't Starve"},{executables:{win32:["GalCiv3.exe"]},id:298,name:"Galactic Civilization 3"},{executables:{win32:["Risk of Rain.exe"]},id:299,name:"Risk of Rain"},{executables:{win32:["Binding_of_Isaac.exe","Isaac-ng.exe"]},id:300,name:"The Binding of Isaac"},{executables:{win32:["RustClient.exe"]},id:301,name:"Rust"},{executables:{win32:["Clicker Heroes.exe"]},id:302,name:"Clicker Heroes"},{executables:{win32:["Brawlhalla.exe"]},id:303,name:"Brawlhalla"},{executables:{win32:["TownOfSalem.exe"]},id:304,name:"Town of Salem"},{executables:{win32:["osu!.exe"]},id:305,name:"osu!"},{executables:{win32:["PathOfExileSteam.exe","PathOfExile.exe"]},id:306,name:"Path of Exile"},{executables:{win32:["Dolphin.exe"]},id:307,name:"Dolphin"},{executables:{win32:["RocketLeague.exe"]},id:308,name:"Rocket League"},{executables:{win32:["TJPP.exe"]},id:309,name:"Jackbox Party Pack"},{executables:{win32:["KFGame.exe"]},id:310,name:"Killing Floor 2"},{executables:{win32:["ShooterGame.exe"]},id:311,name:"Ark: Survival Evolved"},{executables:{win32:["LifeIsStrange.exe"]},id:312,name:"Life Is Strange"},{executables:{win32:["Client_tos.exe"]},id:313,name:"Tree of Savior"},{executables:{win32:["olliolli2.exe"]},id:314,name:"OlliOlli2"},{executables:{win32:["cw.exe"]},id:315,name:"Closers Dimension Conflict"},{executables:{win32:["ESSTEAM.exe","elsword.exe","x2.exe"]},id:316,name:"Elsword"},{executables:{win32:["ori.exe"]},id:317,name:"Ori and the Blind Forest"},{executables:{win32:["Skyforge.exe"]},id:318,name:"Skyforge"},{executables:{win32:["projectzomboid64.exe","projectzomboid32.exe"]},id:319,name:"Project Zomboid"},{executables:{win32:["From_The_Depths.exe"]},id:320,name:"The Depths"},{executables:{win32:["TheCrew.exe"]},id:321,name:"The Crew"},{executables:{win32:["MarvelHeroes2015.exe"]},id:322,name:"Marvel Heroes 2015"},{executables:{win32:["timeclickers.exe"]},id:324,name:"Time Clickers"},{executables:{win32:["eurotrucks2.exe"]},id:325,name:"Euro Truck Simulator 2"},{executables:{win32:["FarmingSimulator2015Game.exe"]},id:326,name:"Farming Simulator 15"},{executables:{win32:["strife.exe"]},id:327,name:"Strife"},{executables:{win32:["Awesomenauts.exe"]},id:328,name:"Awesomenauts"},{executables:{win32:["Dofus.exe"]},id:329,name:"Dofus"},{executables:{win32:["Boid.exe"]},id:330,name:"Boid"},{executables:{win32:["adventure-capitalist.exe"]},id:331,name:"AdVenture Capitalist"},{executables:{win32:["OrcsMustDie2.exe"]},id:332,name:"Orcs Must Die! 2"},{executables:{win32:["Mountain.exe"]},id:333,name:"Mountain"},{executables:{win32:["Valkyria.exe"]},id:335,name:"Valkyria Chronicles"},{executables:{win32:["ffxiiiimg.exe"]},id:336,name:"Final Fantasy XIII"},{executables:{win32:["TLR.exe"]},id:337,name:"The Last Remnant"},{executables:{win32:["Cities.exe"]},id:339,name:"Cities Skylines"},{executables:{win32:["worldofwarships.exe","WoWSLauncher.exe"]},id:341,name:"World of Warships"},{executables:{win32:["spacegame-Win64-shipping.exe"]},id:342,name:"Fractured Space"},{executables:{win32:["thespacegame.exe"]},id:343,name:"Ascent - The Space Game"},{executables:{win32:["DuckGame.exe"]},id:344,name:"Duck Game"},{executables:{win32:["PPSSPPWindows.exe"]},id:345,name:"PPSSPP"},{executables:{win32:["MBAA.exe"]},id:346,name:"Melty Blood Actress Again: Current Code"},{executables:{win32:["TheWolfAmongUs.exe"]},id:347,name:"The Wolf Among Us"},{executables:{win32:["SpaceEngineers.exe"]},id:348,name:"Space Engineers"},{executables:{win32:["Borderlands.exe"]},id:349,name:"Borderlands"},{executables:{win32:["100orange.exe"]},id:351,name:"100% Orange Juice"},{executables:{win32:["reflex.exe"]},id:354,name:"Reflex"},{executables:{win32:["pso2.exe"]},id:355,name:"Phantasy Star Online 2"},{executables:{win32:["AssettoCorsa.exe"]},id:356,name:"Assetto Corsa"},{executables:{win32:["iw3mp.exe","iw3sp.exe"]},id:357,name:"Call of Duty 4: Modern Warfare"},{executables:{win32:["WolfOldBlood_x64.exe"]},id:358,name:"Wolfenstein: The Old Blood"},{executables:{win32:["castle.exe"]},id:359,name:"Castle Crashers"},{executables:{win32:["vindictus.exe"]},id:360,name:"Vindictus"},{executables:{win32:["ShooterGame-Win32-Shipping.exe"]},id:361,name:"Dirty Bomb"},{executables:{win32:["BatmanAK.exe"]},id:362,name:"Batman Arkham Knight"},{executables:{win32:["drt.exe"]},id:363,name:"Dirt Rally"},{executables:{win32:["rFactor.exe"]},id:364,name:"rFactor"},{executables:{win32:["clonk.exe"]},id:365,name:"Clonk Rage"},{executables:{win32:["SRHK.exe"]},id:366,name:"Shadowrun: Hong Kong"},{executables:{win32:["Insurgency.exe"]},id:367,name:"Insurgency"},{executables:{win32:["StepMania.exe"]},id:368,name:"Step Mania"},{executables:{win32:["FirefallCLient.exe"]},id:369,name:"Firefall"},{executables:{win32:["mirrorsedge.exe"]},id:370,name:"Mirrors Edge"},{executables:{win32:["MgsGroundZeroes.exe"]},id:371,name:"Metal Gear Solid V: Ground Zeroes"},{executables:{win32:["mgsvtpp.exe"]},id:372,name:"Metal Gear Solid V: The Phantom Pain"},{executables:{win32:["tld.exe"]},id:373,name:"The Long Dark"},{executables:{win32:["TKOM.exe"]},id:374,name:"Take On Mars"},{executables:{win32:["robloxplayerlauncher.exe","Roblox.exe"]},id:375,name:"Roblox"},{executables:{win32:["eu4.exe"]},id:376,name:"Europa Universalis 4"},{executables:{win32:["APB.exe"]},id:377,name:"APB Reloaded"},{executables:{win32:["Robocraft.exe"]},id:378,name:"Robocraft"},{executables:{win32:["Unity.exe"]},id:379,name:"Unity"},{executables:{win32:["Simpsons.exe"]},id:380,name:"The Simpsons: Hit & Run"},{executables:{win32:["Dnlauncher.exe","DragonNest.exe"]},id:381,name:"Dragon Nest"},{executables:{win32:["Trove.exe"]},id:382,name:"Trove"},{executables:{win32:["EndlessLegend.exe"]},id:383,name:"Endless Legend"},{executables:{win32:["TurbineLauncher.exe","dndclient.exe"]},id:384,name:"Dungeons & Dragons Online"},{executables:{win32:["quakelive.exe","quakelive_steam.exe"]},id:385,name:"Quake Live"},{executables:{win32:["7DaysToDie.exe"]},id:386,name:"7DaysToDie"},{executables:{win32:["SpeedRunners.exe"]},id:387,name:"SpeedRunners"},{executables:{win32:["gamemd.exe"]},id:388,name:"Command & Conquer: Red Alert 2"},{executables:{win32:["generals.exe"]},id:389,name:"Command & Conquer Generals: Zero Hour"},{executables:{win32:["Oblivion.exe"]},id:390,name:"The Elder Scrolls 4: Oblivion"},{executables:{win32:["mgsi.exe"]},id:391,name:"Metal Gear Solid"},{executables:{win32:["EoCApp.exe"]},id:392,name:"Divinity - Original Sin"},{executables:{win32:["Torment.exe"]},id:393,name:"Planescape: Torment"},{executables:{win32:["HexPatch.exe"]},id:394,name:"Hex: Shards of Fate"},{executables:{win32:["NS3FB.exe"]},id:395,name:"Naruto Shippuden Ultimate Ninja Storm 3 Full Burst"},{executables:{win32:["NSUNSR.exe"]},id:396,name:"Naruto Shippuden Ultimate Ninja Storm Revolution"},{executables:{win32:["SaintsRowIV.exe"]},id:397,name:"Saints Row IV"},{executables:{win32:["Shadowrun.exe"]},id:398,name:"Shadowrun"},{executables:{win32:["DungeonoftheEndless.exe"]},id:399,name:"Dungeon of the Endless"},{executables:{win32:["Hon.exe"]},id:400,name:"Heroes of Newerth"},{executables:{win32:["mabinogi.exe"]},id:401,name:"Mabinogi"},{executables:{win32:["CoD2MP_s.exe","CoDSP_s.exe"]},id:402,name:"Call of Duty 2:"},{executables:{win32:["CoDWaWmp.exe","CoDWaw.exe"]},id:403,name:"Call of Duty: World at War"},{executables:{win32:["heroes.exe"]},id:404,name:"Mabinogi Heroes (Vindictus) "},{executables:{win32:["KanColleViewer.exe"]},id:405,name:"KanColle "},{executables:{win32:["cyphers.exe"]},id:406,name:"Cyphers"},{executables:{win32:["RelicCoH2.exe"]},id:407,name:"Company of Heroes 2"},{executables:{win32:["MJ.exe"]},id:408,name:"セガNET麻雀MJ"},{executables:{win32:["ge.exe"]},id:409,name:"Granado Espada"},{executables:{win32:["NovaRO.exe"]},id:410,name:"Nova Ragnarok Online"},{executables:{win32:["RivalsofAether.exe"]},id:411,name:"Rivals of Aether"},{executables:{win32:["bfh.exe"]},id:412,name:"Battlefield Hardline"},{executables:{win32:["GrowHome.exe"]},id:413,name:"Grow Home"},{executables:{win32:["patriots.exe"]},id:414,name:"Rise of Nations Extended"},{executables:{win32:["Railroads.exe"]},id:415,name:"Sid Meier's Railroads!"},{executables:{win32:["Empire.exe"]},id:416,name:"Empire: Total War"},{executables:{win32:["Napoleon.exe"]},id:417,name:"Napoleon: Total War"},{executables:{win32:["gta_sa.exe"]},id:418,name:"Grand Theft Auto: San Andreas"},{executables:{win32:["MadMax.exe"]},id:419,name:"Mad Max"},{executables:{win32:["Titanfall.exe"]},id:420,name:"Titanfall"},{executables:{win32:["age2_x1.exe"]},id:421,name:"Age of Empires II: The Conquerors"},{executables:{win32:["Rome2.exe"]},id:422,name:"Total War: ROME 2"},{executables:{win32:["ShadowOfMordor.exe"]},id:423,name:"Middle-earth: Shadow of Mordor"},{executables:{win32:["Subnautica.exe"]},id:424,name:"Subnautica"},{executables:{win32:["anno5.exe"]},id:425,name:"Anno 2070"},{executables:{win32:["carrier.exe"]},id:426,name:"Carrier Command Gaea Mission"},{executables:{win32:["DarksidersPC.exe"]},id:427,name:"Darksiders"},{executables:{win32:["Darksiders2.exe"]},id:428,name:"Darksiders 2"},{executables:{win32:["mudlet.exe"]},id:429,name:"Mudlet"},{executables:{win32:["DunDefLauncher.exe"]},id:430,name:"Dungeon Defenders II"},{executables:{win32:["hng.exe"]},id:431,name:"Heroes and Generals"},{executables:{win32:["WFTOGame.exe"]},id:432,name:"War of the Overworld"},{executables:{win32:["Talisman.exe"]},id:433,name:"Talisman: Digital Edition"},{executables:{win32:["limbo.exe"]},id:434,name:"Limbo"},{executables:{win32:["ibbobb.exe"]},id:435,name:"ibb & obb"},{executables:{win32:["BattleBlockTheater.exe"]},id:436,name:"BattleBlock Theater"},{executables:{win32:["iracinglauncher.exe","iracingsim.exe","iracingsim64.exe"]},id:437,name:"iRacing"},{executables:{win32:["CivilizationV_DX11.exe"]},id:438,name:"Civilization V"}]},{}]},{},[5])(5)});
\ No newline at end of file
diff --git a/web-dist/discord.min.3.8.4.js b/web-dist/discord.min.3.8.4.js
new file mode 100644
index 000000000..6d0ae74a4
--- /dev/null
+++ b/web-dist/discord.min.3.8.4.js
@@ -0,0 +1,3 @@
+!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Discord=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g>>a&1)},a.prototype.setBit=function(){},e(a,[{key:"createInstantInvite",get:function(){return this.getBit(0)},set:function(a){this.setBit(0,a)}},{key:"manageRoles",get:function(){return this.getBit(3)},set:function(a){this.setBit(3,a)}},{key:"manageChannels",get:function(){return this.getBit(4)},set:function(a){this.setBit(4,a)}},{key:"readMessages",get:function(){return this.getBit(10)},set:function(a){this.setBit(10,a)}},{key:"sendMessages",get:function(){return this.getBit(11)},set:function(a){this.setBit(11,a)}},{key:"sendTTSMessages",get:function(){return this.getBit(12)},set:function(a){this.setBit(12,a)}},{key:"manageMessages",get:function(){return this.getBit(13)},set:function(a){this.setBit(13,a)}},{key:"embedLinks",get:function(){return this.getBit(14)},set:function(a){this.setBit(14,a)}},{key:"attachFiles",get:function(){return this.getBit(15)},set:function(a){this.setBit(15,a)}},{key:"readMessageHistory",get:function(){return this.getBit(16)},set:function(a){this.setBit(16,a)}},{key:"mentionEveryone",get:function(){return this.getBit(17)},set:function(a){this.setBit(17,a)}},{key:"voiceConnect",get:function(){return this.getBit(20)},set:function(a){this.setBit(20,a)}},{key:"voiceSpeak",get:function(){return this.getBit(21)},set:function(a){this.setBit(21,a)}},{key:"voiceMuteMembers",get:function(){return this.getBit(22)},set:function(a){this.setBit(22,a)}},{key:"voiceDeafenMembers",get:function(){return this.getBit(23)},set:function(a){this.setBit(23,a)}},{key:"voiceMoveMembers",get:function(){return this.getBit(24)},set:function(a){this.setBit(24,a)}},{key:"voiceUseVoiceActivation",get:function(){return this.getBit(25)},set:function(a){this.setBit(25,a)}}]),a}();b.exports=f},{}],2:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c=k.length)break;n=k[m++]}else{if(m=k.next(),m.done)break;n=m.value}for(var o=n,p=[],q=o.mentions,r=Array.isArray(q),s=0,q=r?q:q[Symbol.iterator]();;){var t;if(r){if(s>=q.length)break;t=q[s++]}else{if(s=q.next(),s.done)break;t=s.value}var u=t;p.push(d.addUser(u))}var v=d.addUser(o.author);f.push(new j(o,i,p,v))}c(null,f),e(f)}})})},a.prototype.deleteChannel=function(a){var b=arguments.length<=1||void 0===arguments[1]?function(a){}:arguments[1],c=this;return new Promise(function(d,e){var g=a;a instanceof i&&(g=a.id),n.del(f.CHANNELS+"/"+g).set("authorization",c.token).end(function(a){a?(b(a),e(a)):(b(null),d())})})},a.prototype.joinServer=function(a){var b=arguments.length<=1||void 0===arguments[1]?function(a,b){}:arguments[1],c=this;return new Promise(function(d,e){var g=a instanceof k?a.code:a;n.post(f.API+"/invite/"+g).set("authorization",c.token).end(function(a,f){a?(b(a),e(a)):c.getServer("id",f.body.guild.id)?d(c.getServer("id",f.body.guild.id)):c.serverCreateListener[f.body.guild.id]=[d,b]})})},a.prototype.sendFile=function(a,b){var c=arguments.length<=2||void 0===arguments[2]?"image.png":arguments[2],d=arguments.length<=3||void 0===arguments[3]?function(a,b){}:arguments[3],e=this,f=new Promise(function(g,h){function i(a){e.options.queue?(e.queue[a]||(e.queue[a]=[]),e.queue[a].push({action:"sendFile",attachment:l,attachmentName:c,then:j,error:k}),e.checkQueue(a)):e._sendFile(a,l,c).then(j)["catch"](k)}function j(a){f.message=a,d(null,a),g(a)}function k(a){f.error=a,d(a),h(a)}var l;"string"==typeof b||b instanceof String?(l=p.createReadStream(b),c=b):l=b,e.resolveDestination(a).then(i)["catch"](k)});return f},a.prototype.sendMessage=function(a,b,c){var d=arguments.length<=3||void 0===arguments[3]?function(a,b){}:arguments[3],e=arguments.length<=4||void 0===arguments[4]?"":arguments[4],f=this,g=new Promise(function(h,i){function j(a){d(a),i(a)}function k(a){f.options.queue?(f.queue[a]||(f.queue[a]=[]),f.queue[a].push({action:"sendMessage",content:b,mentions:p,tts:!!c,then:l,error:m}),f.checkQueue(a)):f._sendMessage(a,b,c,p).then(l)["catch"](m)}function l(a){g.message=a,d(null,a),h(a)}function m(a){g.error=a,d(a),i(a)}function n(){var a=b;return b instanceof Array&&(a=b.join("\n")),a}function o(){for(var a=[],c=b.match(/<@[^>]*>/g)||[],d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;a.push(g.substring(2,g.length-1))}return a}"function"==typeof c&&(d=c,c=!1),b=e+n(b);var p=o();f.resolveDestination(a).then(k)["catch"](j)});return g},a.prototype.createws=function(a){if(this.websocket)return!1;var b=this;this.websocket=new o(a),this.websocket.onopen=function(){b.trySendConnData()},this.websocket.onclose=function(){b.trigger("disconnected")},this.websocket.onmessage=function(a){var c=!1,d={};try{c=JSON.parse(a.data),d=c.d}catch(e){return void b.trigger("error",e,a)}switch(b.trigger("raw",c),c.t){case"READY":b.debug("received ready packet"),b.user=b.addUser(d.user);for(var f=d.guilds,h=Array.isArray(f),k=0,f=h?f:f[Symbol.iterator]();;){var l;if(h){if(k>=f.length)break;l=f[k++]}else{if(k=f.next(),k.done)break;l=k.value}var m=l,n=b.addServer(m)}for(var o=d.private_channels,p=Array.isArray(o),q=0,o=p?o:o[Symbol.iterator]();;){var r;if(p){if(q>=o.length)break;r=o[q++]}else{if(q=o.next(),q.done)break;r=q.value}var s=r;b.addPMChannel(s)}b.trigger("ready"),b.readyTime=Date.now(),b.debug("cached "+b.serverCache.length+" servers, "+b.channelCache.length+" channels, "+b.pmChannelCache.length+" PMs and "+b.userCache.length+" users."),b.state=3,setInterval(function(){b.keepAlive.apply(b)},d.heartbeat_interval);break;case"MESSAGE_CREATE":b.debug("received message");var t=[];d.mentions=d.mentions||[];for(var u=d.mentions,v=Array.isArray(u),w=0,u=v?u:u[Symbol.iterator]();;){var x;if(v){if(w>=u.length)break;x=u[w++]}else{if(w=u.next(),w.done)break;x=w.value}var y=x;t.push(b.addUser(y))}var z=b.getChannel("id",d.channel_id);if(z){var A=z.addMessage(new j(d,z,t,b.addUser(d.author)));b.trigger("message",A)}break;case"MESSAGE_DELETE":b.debug("message deleted");var z=b.getChannel("id",d.channel_id),B=z.getMessage("id",d.id);B?(b.trigger("messageDelete",z,B),z.messages.splice(z.messages.indexOf(B),1)):b.trigger("messageDelete",z);break;case"MESSAGE_UPDATE":b.debug("message updated");var z=b.getChannel("id",d.channel_id),C=z.getMessage("id",d.id);if(C){var D={};for(var E in C)D[E]=C[E];for(var E in d)D[E]=d[E];for(var t=[],F=D.mentions,G=Array.isArray(F),H=0,F=G?F:F[Symbol.iterator]();;){var I;if(G){if(H>=F.length)break;I=F[H++]}else{if(H=F.next(),H.done)break;I=H.value}var y=I;t.push(b.addUser(y))}var J=new j(D,z,t,C.author);b.trigger("messageUpdate",J,C),z.messages[z.messages.indexOf(C)]=J}break;case"GUILD_DELETE":var n=b.getServer("id",d.id);n&&(b.serverCache.splice(b.serverCache.indexOf(n),1),b.trigger("serverDelete",n));break;case"CHANNEL_DELETE":var z=b.getChannel("id",d.id);if(z){var n=z.server;n&&n.channels.splice(n.channels.indexOf(z),1),b.trigger("channelDelete",z),b.serverCache.splice(b.serverCache.indexOf(z),1)}break;case"GUILD_CREATE":var n=b.getServer("id",d.id);if(n||(n=b.addServer(d)),b.serverCreateListener[d.id]){var K=b.serverCreateListener[d.id];K[0](n),K[1](null,n),b.serverCreateListener[d.id]=null}b.trigger("serverCreate",n);break;case"CHANNEL_CREATE":var z=b.getChannel("id",d.id);if(!z){var L;L=d.is_private?b.addPMChannel(d):b.addChannel(d,d.guild_id);var M=b.getServer("id",d.guild_id);M&&M.addChannel(L),b.trigger("channelCreate",L)}break;case"GUILD_MEMBER_ADD":var n=b.getServer("id",d.guild_id);if(n){var N=b.addUser(d.user);b.trigger("serverNewMember",n.addMember(N,d.roles),n)}break;case"GUILD_MEMBER_REMOVE":var n=b.getServer("id",d.guild_id);if(n){var N=b.addUser(d.user);n.removeMember("id",N.id),b.trigger("serverRemoveMember",N,n)}break;case"USER_UPDATE":if(b.user&&d.id===b.user.id){var O=new g(d);b.trigger("userUpdate",O,b.user),~b.userCache.indexOf(b.user)&&(b.userCache[b.userCache.indexOf(b.user)]=O),b.user=O}break;case"PRESENCE_UPDATE":var P=b.getUser("id",d.user.id);if(P){d.user.username=d.user.username||P.username,d.user.id=d.user.id||P.id,d.user.discriminator=d.user.discriminator||P.discriminator,d.user.avatar=d.user.avatar||P.avatar;var Q=new g(d.user);Q.equalsStrict(P)?(b.trigger("presence",{user:P,oldStatus:P.status,status:d.status,server:b.getServer("id",d.guild_id),gameId:d.game_id}),P.status=d.status,P.gameId=d.game_id):(b.userCache[b.userCache.indexOf(P)]=Q,b.trigger("userUpdate",P,Q))}break;case"CHANNEL_UPDATE":var R=b.getChannel("id",d.id),S=b.getServer("id",d.guild_id);if(R&&S){var T=new i(d,S);T.messages=R.messages,b.trigger("channelUpdate",R,T),b.channelCache[b.channelCache.indexOf(R)]=T}break;case"TYPING_START":var P=b.getUser("id",d.user_id),R=b.getChannel("id",d.channel_id);b.userTypingListener[d.user_id]&&-1!==b.userTypingListener[d.user_id]||b.trigger("startTyping",P,R),b.userTypingListener[d.user_id]=Date.now(),setTimeout(function(){-1!==b.userTypingListener[d.user_id]&&Date.now()-b.userTypingListener[d.user_id]>6e3&&(b.trigger("stopTyping",P,R),b.userTypingListener[d.user_id]=-1)},6e3);break;case"GUILD_ROLE_DELETE":var n=b.getServer("id",d.guild_id),U=n.getRole(d.role_id);b.trigger("serverRoleDelete",n,U),n.removeRole(U.id);break;case"GUILD_ROLE_UPDATE":var n=b.getServer("id",d.guild_id),U=n.getRole(d.role.id),V=n.updateRole(d.role);b.trigger("serverRoleUpdate",n,U,V);break;default:b.debug("received unknown packet"),b.trigger("unknown",c)}}},a.prototype.addUser=function(a){return this.getUser("id",a.id)||this.userCache.push(new g(a)),this.getUser("id",a.id)},a.prototype.addChannel=function(a,b){return this.getChannel("id",a.id)||this.channelCache.push(new i(a,this.getServer("id",b))),this.getChannel("id",a.id)},a.prototype.addPMChannel=function(a){return this.getPMChannel("id",a.id)||this.pmChannelCache.push(new l(a,this)),this.getPMChannel("id",a.id)},a.prototype.setTopic=function(a,b){var c=arguments.length<=2||void 0===arguments[2]?function(a){}:arguments[2],d=this;return new Promise(function(e,g){function h(a){c(a),g(a)}function i(a){var g=d.getChannel("id",a);n.patch(f.CHANNELS+"/"+a).set("authorization",d.token).send({name:g.name,position:0,topic:b}).end(function(a,b){a?h(a):(g.topic=b.body.topic,e(),c())})}d.resolveDestination(a).then(i)["catch"](h)})},a.prototype.addServer=function(a){var b=this,c=this.getServer("id",a.id);if(a.unavailable)return b.trigger("unavailable",a),void b.debug("Server ID "+a.id+" has been marked unavailable by Discord. It was not cached.");if(!c&&(c=new h(a,this),this.serverCache.push(c),a.channels))for(var d=a.channels,e=Array.isArray(d),f=0,d=e?d:d[Symbol.iterator]();;){var g;if(e){if(f>=d.length)break;g=d[f++]}else{if(f=d.next(),f.done)break;g=f.value}var i=g;c.channels.push(this.addChannel(i,c.id))}for(var j=a.presences,k=Array.isArray(j),l=0,j=k?j:j[Symbol.iterator]();;){var m;if(k){if(l>=j.length)break;m=j[l++]}else{if(l=j.next(),l.done)break;m=l.value}var n=m,o=b.getUser("id",n.user.id);o.status=n.status,o.gameId=n.game_id}return c},a.prototype.getUser=function(a,b){for(var c=this.userCache,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;if(g[a]===b)return g}return null},a.prototype.getChannel=function(a,b){for(var c=this.channelCache,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;if(g[a]===b)return g}return this.getPMChannel(a,b)},a.prototype.getPMChannel=function(a,b){for(var c=this.pmChannelCache,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;if(g[a]===b)return g}return null},a.prototype.getServer=function(a,b){for(var c=this.serverCache,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;if(g[a]===b)return g}return null},a.prototype.trySendConnData=function(){if(this.token&&!this.alreadySentData){this.alreadySentData=!0;var a={op:2,d:{token:this.token,v:3,properties:{$os:"discord.js",$browser:"discord.js",$device:"discord.js",$referrer:"",$referring_domain:""}}};this.websocket.send(JSON.stringify(a))}},a.prototype.resolveServerID=function(a){return a instanceof h?a.id:!isNaN(a)&&a.length&&17===a.length?a:void 0},a.prototype.resolveDestination=function(a){var b=!1,c=this;return new Promise(function(d,e){if(a instanceof h)b=a.id;else if(a instanceof i)b=a.id;else if(a instanceof j)b=a.channel.id;else if(a instanceof l)b=a.id;else if(a instanceof g){for(var f=c.pmChannelCache,k=Array.isArray(f),m=0,f=k?f:f[Symbol.iterator]();;){var n;if(k){if(m>=f.length)break;n=f[m++]}else{if(m=f.next(),m.done)break;n=m.value}var o=n;if(o.user&&o.user.equals(a))return void d(o.id)}c.startPM(a).then(function(a){d(a.id)})["catch"](e)}else b=a;b?d(b):e()})},a.prototype._sendMessage=function(a,b,c,d){var e=this;return new Promise(function(g,h){n.post(f.CHANNELS+"/"+a+"/messages").set("authorization",e.token).send({content:b,mentions:d,tts:c}).end(function(a,b){if(a)h(a);else{var c=b.body,d=[];c.mentions=c.mentions||[];for(var f=c.mentions,i=Array.isArray(f),k=0,f=i?f:f[Symbol.iterator]();;){var l;if(i){if(k>=f.length)break;l=f[k++]}else{if(k=f.next(),k.done)break;l=k.value}var m=l;d.push(e.addUser(m))}var n=e.getChannel("id",c.channel_id);if(n){var o=n.addMessage(new j(c,n,d,e.addUser(c.author)));g(o)}}})})},a.prototype._sendFile=function(a,b){var c=arguments.length<=2||void 0===arguments[2]?"DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png":arguments[2],d=this;return new Promise(function(e,g){n.post(f.CHANNELS+"/"+a+"/messages").set("authorization",d.token).attach("file",b,c).end(function(b,c){if(b)g(b);else{var f=d.getChannel("id",a);if(f){var h=f.addMessage(new j(c.body,f,[],d.user));e(h)}}})})},a.prototype._updateMessage=function(a,b){var c=this;return new Promise(function(d,e){n.patch(f.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",c.token).send({content:b,mentions:[]}).end(function(b,c){if(b)e(b);else{var f=new j(c.body,a.channel,a.mentions,a.sender);d(f),a.channel.messages[a.channel.messages.indexOf(a)]=f}})})},a.prototype.getGateway=function(){var a=this;return new Promise(function(b,c){n.get(f.API+"/gateway").set("authorization",a.token).end(function(a,d){a?c(a):b(d.body.url)})})},a.prototype.setStatusIdle=function(){this.setStatus("idle")},a.prototype.setStatusOnline=function(){this.setStatus("online")},a.prototype.setStatusActive=function(){this.setStatusOnline()},a.prototype.setStatusHere=function(){this.setStatusOnline()},a.prototype.setStatusAway=function(){this.setStatusIdle()},a.prototype.startTyping=function(a,b){function c(a){if(!d.typingIntervals[a]){var c=function(){n.post(f.CHANNELS+"/"+a+"/typing").set("authorization",d.token).end()};c();var e=setInterval(c,3e3);d.typingIntervals[a]=e,b&&setTimeout(function(){d.stopTyping(a)},b)}}var d=this;this.resolveDestination(a).then(c)},a.prototype.stopTyping=function(a){function b(a){c.typingIntervals[a]&&(clearInterval(c.typingIntervals[a]),delete c.typingIntervals[a])}var c=this;this.resolveDestination(a).then(b)},a.prototype.setStatus=function(a){var b="online"===a?null:Date.now();this.__idleTime=b,this.websocket.send(JSON.stringify({op:3,d:{idle_since:this.__idleTime,game_id:this.__gameId}}))},a.prototype.setPlayingGame=function(a){if(a instanceof String||"string"==typeof a){var b=a.trim().toUpperCase();a=null;for(var c=m,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;if(g.name.trim().toUpperCase()===b){a=g.id;break}}}this.__gameId=a,this.websocket.send(JSON.stringify({op:3,d:{idle_since:this.__idleTime,game_id:this.__gameId}}))},a.prototype.playGame=function(a){this.setPlayingGame(a)},a.prototype.playingGame=function(a){this.setPlayingGame(a)},e(a,[{key:"uptime",get:function(){return this.readyTime?Date.now()-this.readyTime:null}},{key:"ready",get:function(){return 3===this.state}},{key:"servers",get:function(){return this.serverCache}},{key:"channels",get:function(){return this.channelCache}},{key:"users",get:function(){return this.userCache}},{key:"PMChannels",get:function(){return this.pmChannelCache}},{key:"messages",get:function(){for(var a=[],b=this.channelCache,c=Array.isArray(b),d=0,b=c?b:b[Symbol.iterator]();;){var e;if(c){if(d>=b.length)break;e=b[d++]}else{if(d=b.next(),d.done)break;e=d.value}var f=e;a=a.concat(f.messages)}return a}}]),a}();b.exports=r},{"../ref/gameMap.json":19,"./Endpoints.js":3,"./PMChannel.js":6,"./channel.js":8,"./invite.js":10,"./message.js":11,"./server.js":12,"./user.js":13,fs:14,superagent:15,ws:18}],3:[function(a,b,c){"use strict";c.BASE_DOMAIN="discordapp.com",c.BASE="https://"+c.BASE_DOMAIN,c.WEBSOCKET_HUB="wss://"+c.BASE_DOMAIN+"/hub",c.API=c.BASE+"/api",c.AUTH=c.API+"/auth",c.LOGIN=c.AUTH+"/login",c.LOGOUT=c.AUTH+"/logout",c.USERS=c.API+"/users",c.SERVERS=c.API+"/guilds",c.CHANNELS=c.API+"/channels"},{}],4:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c>>a&1)},a.prototype.setBit=function(){},e(a,[{key:"createInstantInvite",get:function(){return this.getBit(0)},set:function(a){this.setBit(0,a)}},{key:"manageRoles",get:function(){return this.getBit(3)},set:function(a){this.setBit(3,a)}},{key:"manageChannels",get:function(){return this.getBit(4)},set:function(a){this.setBit(4,a)}},{key:"readMessages",get:function(){return this.getBit(10)},set:function(a){this.setBit(10,a)}},{key:"sendMessages",get:function(){return this.getBit(11)},set:function(a){this.setBit(11,a)}},{key:"sendTTSMessages",get:function(){return this.getBit(12)},set:function(a){this.setBit(12,a)}},{key:"manageMessages",get:function(){return this.getBit(13)},set:function(a){this.setBit(13,a)}},{key:"embedLinks",get:function(){return this.getBit(14)},set:function(a){this.setBit(14,a)}},{key:"attachFiles",get:function(){return this.getBit(15)},set:function(a){this.setBit(15,a)}},{key:"readMessageHistory",get:function(){return this.getBit(16)},set:function(a){this.setBit(16,a)}},{key:"mentionEveryone",get:function(){return this.getBit(17)},set:function(a){this.setBit(17,a)}},{key:"voiceConnect",get:function(){return this.getBit(20)},set:function(a){this.setBit(20,a)}},{key:"voiceSpeak",get:function(){return this.getBit(21)},set:function(a){this.setBit(21,a)}},{key:"voiceMuteMembers",get:function(){return this.getBit(22)},set:function(a){this.setBit(22,a)}},{key:"voiceDeafenMembers",get:function(){return this.getBit(23)},set:function(a){this.setBit(23,a)}},{key:"voiceMoveMembers",get:function(){return this.getBit(24)},set:function(a){this.setBit(24,a)}},{key:"voiceUseVoiceActivation",get:function(){return this.getBit(25)},set:function(a){this.setBit(25,a)}}]),a}();b.exports=f},{}],5:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function e(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}var f=function(){function a(a,b){for(var c=0;c=d.length)break;g=d[f++]}else{if(f=d.next(),f.done)break;g=f.value}var h=g;h.id===this.id&&"member"===h.type?c.push(h):-1!==this.rawRoles.indexOf(h.id)&&b.push(h)}for(var j=b,k=Array.isArray(j),l=0,j=k?j:j[Symbol.iterator]();;){var m;if(k){if(l>=j.length)break;m=j[l++]}else{if(l=j.next(),l.done)break;m=l.value}var n=m;console.log("hey",n.attachFiles)}if(0===b.length&&0===c.length)return new i(this.evalPerms.packed);for(var o=0!==b.length?b[0].packed:c[0].packed,p=b,q=Array.isArray(p),r=0,p=q?p:p[Symbol.iterator]();;){var s;if(q){if(r>=p.length)break;s=p[r++]}else{if(r=p.next(),r.done)break;s=r.value}var h=s;o&=~h.deny,o|=h.allow}for(var t=c,u=Array.isArray(t),v=0,t=u?t:t[Symbol.iterator]();;){var w;if(u){if(v>=t.length)break;w=t[v++]}else{if(v=t.next(),v.done)break;w=v.value}var h=w;o&=~h.deny,o|=h.allow}return new i(o)},f(b,[{key:"roles",get:function(){for(var a=[this.server.getRole(this.server.id)],b=this.rawRoles,c=Array.isArray(b),d=0,b=c?b:b[Symbol.iterator]();;){var e;if(c){if(d>=b.length)break;e=b[d++]}else{if(d=b.next(),d.done)break;e=d.value}var f=e;a.push(this.server.getRole(f))}return a}},{key:"evalPerms",get:function(){for(var a=this.roles,b=a[0].packed,c=a,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;b|=g.packed}return new h({permissions:b})}}]),b}(g);b.exports=j},{"./EvaluatedPermissions.js":4,"./ServerPermissions.js":7,"./user.js":13}],6:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c1e3&&this.messages.splice(0,1);for(var c=this.messages,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;if(g[a]===b)return g}return null},e(a,[{key:"isPrivate",get:function(){return!0}}]),a}();b.exports=f},{}],7:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c>>a&1)},a.prototype.setBit=function(){},a.prototype.toString=function(){return this.name},e(a,[{key:"createInstantInvite",get:function(){return this.getBit(0)},set:function(a){this.setBit(0,a)}},{key:"banMembers",get:function(){return this.getBit(1)},set:function(a){this.setBit(1,a)}},{key:"kickMembers",get:function(){return this.getBit(2)},set:function(a){this.setBit(2,a)}},{key:"manageRoles",get:function(){return this.getBit(3)},set:function(a){this.setBit(3,a)}},{key:"manageChannels",get:function(){return this.getBit(4)},set:function(a){this.setBit(4,a)}},{key:"manageServer",get:function(){return this.getBit(5)},set:function(a){this.setBit(5,a)}},{key:"readMessages",get:function(){return this.getBit(10)},set:function(a){this.setBit(10,a)}},{key:"sendMessages",get:function(){return this.getBit(11)},set:function(a){this.setBit(11,a)}},{key:"sendTTSMessages",get:function(){return this.getBit(12)},set:function(a){this.setBit(12,a)}},{key:"manageMessages",get:function(){return this.getBit(13)},set:function(a){this.setBit(13,a)}},{key:"embedLinks",
+get:function(){return this.getBit(14)},set:function(a){this.setBit(14,a)}},{key:"attachFiles",get:function(){return this.getBit(15)},set:function(a){this.setBit(15,a)}},{key:"readMessageHistory",get:function(){return this.getBit(16)},set:function(a){this.setBit(16,a)}},{key:"mentionEveryone",get:function(){return this.getBit(17)},set:function(a){this.setBit(17,a)}},{key:"voiceConnect",get:function(){return this.getBit(20)},set:function(a){this.setBit(20,a)}},{key:"voiceSpeak",get:function(){return this.getBit(21)},set:function(a){this.setBit(21,a)}},{key:"voiceMuteMembers",get:function(){return this.getBit(22)},set:function(a){this.setBit(22,a)}},{key:"voiceDeafenMembers",get:function(){return this.getBit(23)},set:function(a){this.setBit(23,a)}},{key:"voiceMoveMembers",get:function(){return this.getBit(24)},set:function(a){this.setBit(24,a)}},{key:"voiceUseVoiceActivation",get:function(){return this.getBit(25)},set:function(a){this.setBit(25,a)}}]),a}();b.exports=f},{}],8:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c=e.length)break;i=e[h++]}else{if(h=e.next(),h.done)break;i=h.value}var j=i;this.roles.push(new f(j,this))}}return a.prototype.permissionsOf=function(a){var b=this.server.getMember("id",a.id);return b?b.permissionsIn(this):null},a.prototype.equals=function(a){return a&&a.id===this.id},a.prototype.addMessage=function(a){return this.messages.length>1e3&&this.messages.splice(0,1),this.getMessage("id",a.id)||this.messages.push(a),this.getMessage("id",a.id)},a.prototype.getMessage=function(a,b){for(var c=this.messages,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;if(g[a]===b)return g}return null},a.prototype.toString=function(){return"<#"+this.id+">"},e(a,[{key:"permissionOverwrites",get:function(){return this.roles}},{key:"permissions",get:function(){return this.roles}},{key:"client",get:function(){return this.server.client}},{key:"isPrivate",get:function(){return!1}},{key:"users",get:function(){return this.server.members}},{key:"members",get:function(){return this.server.members}}]),a}();b.exports=g},{"./ChannelPermissions.js":1}],9:[function(a,b,c){"use strict";var d=(a("superagent"),a("./Endpoints.js")),e=a("./Client.js"),f={Endpoints:d,Client:e};b.exports=f},{"./Client.js":2,"./Endpoints.js":3,superagent:15}],10:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;if(g.id===b)return!0}return!1},e(a,[{key:"sender",get:function(){return this.author}},{key:"isPrivate",get:function(){return this.channel.isPrivate}}]),a}());b.exports=f},{"./PMChannel.js":6}],12:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c=e.length)break;i=e[h++]}else{if(h=e.next(),h.done)break;i=h.value}var j=i;this.roles.push(new f(j))}if(!b.members)return void(b.members=[c.user]);for(var k=b.members,l=Array.isArray(k),m=0,k=l?k:k[Symbol.iterator]();;){var n;if(l){if(m>=k.length)break;n=k[m++]}else{if(m=k.next(),m.done)break;n=m.value}var o=n;o.user&&this.addMember(c.addUser(o.user),o.roles)}}return a.prototype.getRole=function(a){for(var b=this.roles,c=Array.isArray(b),d=0,b=c?b:b[Symbol.iterator]();;){var e;if(c){if(d>=b.length)break;e=b[d++]}else{if(d=b.next(),d.done)break;e=d.value}var f=e;if(f.id===a)return f}return null},a.prototype.updateRole=function(a){var b=this.getRole(a.id);if(b){var c=this.roles.indexOf(b);return this.roles[c]=new f(a),this.roles[c]}return!1},a.prototype.removeRole=function(a){for(var b in this.roles)this.roles[b].id===a&&this.roles.splice(b,1);for(var c=this.members,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;for(var b in g.rawRoles)g.rawRoles[b]===a&&g.rawRoles.splice(b,1)}},a.prototype.getChannel=function(a,b){for(var c=this.channels,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;if(g[a]===b)return g}return null},a.prototype.getMember=function(a,b){for(var c=this.members,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;if(g[a]===b)return g}return null},a.prototype.removeMember=function(a,b){for(var c=this.members,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;if(g[a]===b)return this.members.splice(a,1),g}return!1},a.prototype.addChannel=function(a){return this.getChannel("id",a.id)||this.channels.push(a),a},a.prototype.addMember=function(a,b){if(!this.getMember("id",a.id)){var c=new g(a,this,b);this.members.push(c)}return c},a.prototype.toString=function(){return this.name},a.prototype.equals=function(a){return a.id===this.id},e(a,[{key:"permissionGroups",get:function(){return this.roles}},{key:"permissions",get:function(){return this.roles}},{key:"iconURL",get:function(){return this.icon?"https://discordapp.com/api/guilds/"+this.id+"/icons/"+this.icon+".jpg":null}},{key:"afkChannel",get:function(){return this.afkChannelId?this.getChannel("id",this.afkChannelId):!1}},{key:"defaultChannel",get:function(){return this.getChannel("name","general")}},{key:"owner",get:function(){return this.client.getUser("id",this.ownerID)}},{key:"users",get:function(){return this.members}}]),a}();b.exports=h},{"./Member.js":5,"./ServerPermissions.js":7}],13:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c"},a.prototype.toString=function(){return this.mention()},a.prototype.equals=function(a){return a.id===this.id},a.prototype.equalsStrict=function(a){return a.id===this.id&&a.avatar===this.avatar&&a.username===this.username&&a.discriminator===this.discriminator},e(a,[{key:"avatarURL",get:function(){return this.avatar?"https://discordapp.com/api/users/"+this.id+"/avatars/"+this.avatar+".jpg":null}}]),a}();b.exports=f},{}],14:[function(a,b,c){},{}],15:[function(a,b,c){function d(){}function e(a){var b={}.toString.call(a);switch(b){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function f(a){return a===Object(a)}function g(a){if(!f(a))return a;var b=[];for(var c in a)null!=a[c]&&b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")}function h(a){for(var b,c,d={},e=a.split("&"),f=0,g=e.length;g>f;++f)c=e[f],b=c.split("="),d[decodeURIComponent(b[0])]=decodeURIComponent(b[1]);return d}function i(a){var b,c,d,e,f=a.split(/\r?\n/),g={};f.pop();for(var h=0,i=f.length;i>h;++h)c=f[h],b=c.indexOf(":"),d=c.slice(0,b).toLowerCase(),e=r(c.slice(b+1)),g[d]=e;return g}function j(a){return a.split(/ *; */).shift()}function k(a){return q(a.split(/ *; */),function(a,b){var c=b.split(/ *= */),d=c.shift(),e=c.shift();return d&&e&&(a[d]=e),a},{})}function l(a,b){b=b||{},this.req=a,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=i(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function m(a,b){var c=this;p.call(this),this._query=this._query||[],this.method=a,this.url=b,this.header={},this._header={},this.on("end",function(){var a=null,b=null;try{b=new l(c)}catch(d){return a=new Error("Parser is unable to parse the response"),a.parse=!0,a.original=d,c.callback(a)}if(c.emit("response",b),a)return c.callback(a,b);if(b.status>=200&&b.status<300)return c.callback(a,b);var e=new Error(b.statusText||"Unsuccessful HTTP response");e.original=a,e.response=b,e.status=b.status,c.callback(e,b)})}function n(a,b){return"function"==typeof b?new m("GET",a).end(b):1==arguments.length?new m("GET",a):new m(a,b)}var o,p=a("emitter"),q=a("reduce");o="undefined"!=typeof window?window:"undefined"!=typeof self?self:this,n.getXHR=function(){if(!(!o.XMLHttpRequest||o.location&&"file:"==o.location.protocol&&o.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(a){}return!1};var r="".trim?function(a){return a.trim()}:function(a){return a.replace(/(^\s*|\s*$)/g,"")};n.serializeObject=g,n.parseString=h,n.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},n.serialize={"application/x-www-form-urlencoded":g,"application/json":JSON.stringify},n.parse={"application/x-www-form-urlencoded":h,"application/json":JSON.parse},l.prototype.get=function(a){return this.header[a.toLowerCase()]},l.prototype.setHeaderProperties=function(a){var b=this.header["content-type"]||"";this.type=j(b);var c=k(b);for(var d in c)this[d]=c[d]},l.prototype.parse=function(a){return this.parser=a,this},l.prototype.parseBody=function(a){var b=this.parser||n.parse[this.type];return b&&a&&(a.length||a instanceof Object)?b(a):null},l.prototype.setStatusProperties=function(a){1223===a&&(a=204);var b=a/100|0;this.status=this.statusCode=a,this.statusType=b,this.info=1==b,this.ok=2==b,this.clientError=4==b,this.serverError=5==b,this.error=4==b||5==b?this.toError():!1,this.accepted=202==a,this.noContent=204==a,this.badRequest=400==a,this.unauthorized=401==a,this.notAcceptable=406==a,this.notFound=404==a,this.forbidden=403==a},l.prototype.toError=function(){var a=this.req,b=a.method,c=a.url,d="cannot "+b+" "+c+" ("+this.status+")",e=new Error(d);return e.status=this.status,e.method=b,e.url=c,e},n.Response=l,p(m.prototype),m.prototype.use=function(a){return a(this),this},m.prototype.timeout=function(a){return this._timeout=a,this},m.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},m.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0,this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this)},m.prototype.set=function(a,b){if(f(a)){for(var c in a)this.set(c,a[c]);return this}return this._header[a.toLowerCase()]=b,this.header[a]=b,this},m.prototype.unset=function(a){return delete this._header[a.toLowerCase()],delete this.header[a],this},m.prototype.getHeader=function(a){return this._header[a.toLowerCase()]},m.prototype.type=function(a){return this.set("Content-Type",n.types[a]||a),this},m.prototype.accept=function(a){return this.set("Accept",n.types[a]||a),this},m.prototype.auth=function(a,b){var c=btoa(a+":"+b);return this.set("Authorization","Basic "+c),this},m.prototype.query=function(a){return"string"!=typeof a&&(a=g(a)),a&&this._query.push(a),this},m.prototype.field=function(a,b){return this._formData||(this._formData=new o.FormData),this._formData.append(a,b),this},m.prototype.attach=function(a,b,c){return this._formData||(this._formData=new o.FormData),this._formData.append(a,b,c),this},m.prototype.send=function(a){var b=f(a),c=this.getHeader("Content-Type");if(b&&f(this._data))for(var d in a)this._data[d]=a[d];else"string"==typeof a?(c||this.type("form"),c=this.getHeader("Content-Type"),"application/x-www-form-urlencoded"==c?this._data=this._data?this._data+"&"+a:a:this._data=(this._data||"")+a):this._data=a;return!b||e(a)?this:(c||this.type("json"),this)},m.prototype.callback=function(a,b){var c=this._callback;this.clearTimeout(),c(a,b)},m.prototype.crossDomainError=function(){var a=new Error("Origin is not allowed by Access-Control-Allow-Origin");a.crossDomain=!0,this.callback(a)},m.prototype.timeoutError=function(){var a=this._timeout,b=new Error("timeout of "+a+"ms exceeded");b.timeout=a,this.callback(b)},m.prototype.withCredentials=function(){return this._withCredentials=!0,this},m.prototype.end=function(a){var b=this,c=this.xhr=n.getXHR(),f=this._query.join("&"),g=this._timeout,h=this._formData||this._data;this._callback=a||d,c.onreadystatechange=function(){if(4==c.readyState){var a;try{a=c.status}catch(d){a=0}if(0==a){if(b.timedout)return b.timeoutError();if(b.aborted)return;return b.crossDomainError()}b.emit("end")}};var i=function(a){a.total>0&&(a.percent=a.loaded/a.total*100),b.emit("progress",a)};this.hasListeners("progress")&&(c.onprogress=i);try{c.upload&&this.hasListeners("progress")&&(c.upload.onprogress=i)}catch(j){}if(g&&!this._timer&&(this._timer=setTimeout(function(){b.timedout=!0,b.abort()},g)),f&&(f=n.serializeObject(f),this.url+=~this.url.indexOf("?")?"&"+f:"?"+f),c.open(this.method,this.url,!0),this._withCredentials&&(c.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof h&&!e(h)){var k=this.getHeader("Content-Type"),l=n.serialize[k?k.split(";")[0]:""];l&&(h=l(h))}for(var m in this.header)null!=this.header[m]&&c.setRequestHeader(m,this.header[m]);return this.emit("request",this),c.send(h),this},m.prototype.then=function(a,b){return this.end(function(c,d){c?b(c):a(d)})},n.Request=m,n.get=function(a,b,c){var d=n("GET",a);return"function"==typeof b&&(c=b,b=null),b&&d.query(b),c&&d.end(c),d},n.head=function(a,b,c){var d=n("HEAD",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.del=function(a,b){var c=n("DELETE",a);return b&&c.end(b),c},n.patch=function(a,b,c){var d=n("PATCH",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.post=function(a,b,c){var d=n("POST",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.put=function(a,b,c){var d=n("PUT",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},b.exports=n},{emitter:16,reduce:17}],16:[function(a,b,c){function d(a){return a?e(a):void 0}function e(a){for(var b in d.prototype)a[b]=d.prototype[b];return a}b.exports=d,d.prototype.on=d.prototype.addEventListener=function(a,b){return this._callbacks=this._callbacks||{},(this._callbacks[a]=this._callbacks[a]||[]).push(b),this},d.prototype.once=function(a,b){function c(){d.off(a,c),b.apply(this,arguments)}var d=this;return this._callbacks=this._callbacks||{},c.fn=b,this.on(a,c),this},d.prototype.off=d.prototype.removeListener=d.prototype.removeAllListeners=d.prototype.removeEventListener=function(a,b){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var c=this._callbacks[a];if(!c)return this;if(1==arguments.length)return delete this._callbacks[a],this;for(var d,e=0;ed;++d)c[d].apply(this,b)}return this},d.prototype.listeners=function(a){return this._callbacks=this._callbacks||{},this._callbacks[a]||[]},d.prototype.hasListeners=function(a){return!!this.listeners(a).length}},{}],17:[function(a,b,c){b.exports=function(a,b,c){for(var d=0,e=a.length,f=3==arguments.length?c:a[d++];e>d;)f=b.call(null,f,a[d],++d,a);return f}},{}],18:[function(a,b,c){function d(a,b,c){var d;return d=b?new f(a,b):new f(a)}var e=function(){return this}(),f=e.WebSocket||e.MozWebSocket;b.exports=f?d:null,f&&(d.prototype=f.prototype)},{}],19:[function(a,b,c){b.exports=[{executables:{win32:["pol.exe"]},id:0,name:"FINAL FANTASY XI"},{executables:{win32:["ffxiv.exe","ffxiv_dx11.exe"]},id:1,name:"FINAL FANTASY XIV"},{executables:{win32:["Wow.exe","Wow-64.exe"]},id:3,name:"World of Warcraft"},{executables:{darwin:["LoLLauncher.app"],win32:["LolClient.exe","League of Legends.exe"]},id:4,name:"League of Legends"},{executables:{darwin:["Diablo%20III.app"],win32:["Diablo III.exe"]},id:5,name:"Diablo 3"},{executables:{darwin:["dota_osx.app"],win32:["dota2.exe"]},id:6,name:"DOTA 2"},{executables:{darwin:["Heroes.app"],win32:["Heroes of the Storm.exe","HeroesOfTheStorm_x64.exe","HeroesOfTheStorm.exe"]},id:7,name:"Heroes of the Storm"},{executables:{darwin:["Hearthstone.app"],win32:["Hearthstone.exe"]},id:8,name:"Hearthstone"},{executables:{win32:["csgo.exe"]},id:9,name:"Counter-Strike: Global Offensive"},{executables:{win32:["WorldOfTanks.exe"]},id:10,name:"World of Tanks"},{executables:{darwin:["gw2.app"],win32:["gw2.exe"]},id:11,name:"Guild Wars 2"},{executables:{win32:["dayz.exe"]},id:12,name:"Day Z"},{executables:{darwin:["starcraft%20ii.app"],win32:["starcraft ii.exe","SC2_x64.exe","SC2.exe"]},id:13,name:"Starcraft II"},{executables:{win32:["diablo.exe"]},id:14,name:"Diablo"},{executables:{win32:["diablo ii.exe"]},id:15,name:"Diablo 2"},{executables:{win32:["left4dead.exe"]},id:17,name:"Left 4 Dead"},{executables:{darwin:["minecraft.app"],win32:["minecraft.exe"]},id:18,name:"Minecraft"},{executables:{win32:["smite.exe"]},id:19,name:"Smite"},{executables:{win32:["bf4.exe"]},id:20,name:"Battlefield 4"},{executables:{win32:["AoK HD.exe","empires2.exe"]},id:101,name:"Age of Empire II"},{executables:{win32:["age3y.exe"]},id:102,name:"Age of Empire III"},{executables:{win32:["AlanWake.exe"]},id:104,name:"Alan Wake"},{executables:{win32:["alan_wakes_american_nightmare.exe"]},id:105,name:"Alan Wake's American Nightmare"},{executables:{win32:["AlienBreed2Assault.exe"]},id:106,name:"Alien Breed 2: Assault"},{executables:{win32:["Amnesia.exe"]},id:107,name:"Amnesia: The Dark Descent"},{executables:{win32:["UDK.exe"]},id:108,name:"Antichamber"},{executables:{win32:["ArcheAge.exe"]},id:109,name:"ArcheAge"},{executables:{win32:["arma3.exe"]},id:110,name:"Arma III"},{executables:{win32:["AC3SP.exe"]},id:111,name:"Assassin's Creed 3"},{executables:{win32:["Bastion.exe"]},id:112,name:"Bastion"},{executables:{win32:["BF2.exe"]},id:113,name:"Battlefield 2"},{executables:{win32:["bf3.exe"]},id:114,name:"Battlefield 3"},{executables:{win32:["Besiege.exe"]},id:116,name:"Besiege"},{executables:{win32:["Bioshock.exe"]},id:117,name:"Bioshock"},{executables:{win32:["Bioshock2.exe"]},id:118,name:"BioShock II"},{executables:{win32:["BioShockInfinite.exe"]},id:119,name:"BioShock Infinite"},{executables:{win32:["Borderlands2.exe"]},id:122,name:"Borderlands 2"},{executables:{win32:["braid.exe"]},id:123,name:"Braid"},{executables:{win32:["ShippingPC-StormGame.exe"]},id:124,name:"Bulletstorm"},{executables:{},id:125,name:"Cabal 2"},{executables:{win32:["CabalMain.exe"]},id:126,name:"Cabal Online"},{executables:{win32:["iw4mp.exe","iw4sp.exe"]},id:127,name:"Call of Duty: Modern Warfare 2"},{executables:{win32:["t6sp.exe"]},id:128,name:"Call of Duty: Black Ops"},{executables:{win32:["iw5mp.exe"]},id:129,name:"Call of Duty: Modern Warfare 3"},{executables:{win32:["RelicCOH.exe"]},id:132,name:"Company of Heroes"},{executables:{win32:["Crysis64.exe"]},id:135,name:"Crysis"},{executables:{win32:["Crysis2.exe"]},id:136,name:"Crysis 2"},{executables:{win32:["Crysis3.exe"]},id:137,name:"Crysis 3"},{executables:{win32:["Crysis.exe"]},id:138,name:"Crysis 4 "},{executables:{win32:["DATA.exe"]},id:140,name:"Dark Souls"},{executables:{win32:["DarkSoulsII.exe"]},id:141,name:"Dark Souls II"},{executables:{win32:["dfuw.exe"]},id:142,name:"Darkfall: Unholy Wars"},{executables:{win32:["DCGAME.exe"]},id:144,name:"DC Universe Online"},{executables:{win32:["DeadIslandGame.exe"]},id:145,name:"Dead Island"},{executables:{win32:["deadspace2.exe"]},id:146,name:"Dead Space 2"},{executables:{win32:["LOTDGame.exe"]},id:147,name:"Deadlight"},{executables:{win32:["dxhr.exe"]},id:148,name:"Deus Ex: Human Revolution"},{executables:{win32:["DeviMayCry4.exe"]},id:149,name:"Devil May Cry 4"},{executables:{win32:["DMC-DevilMayCry.exe"]},id:150,name:"DmC Devil May Cry"},{executables:{win32:["dirt2_game.exe"]},id:154,name:"DiRT 2"},{executables:{win32:["dirt3_game.exe"]},id:155,name:"DiRT 3"},{executables:{win32:["dota.exe"]},id:156,name:"DOTA"},{executables:{win32:["DoubleDragon.exe"]},id:158,name:"Double Dragon Neon"},{executables:{win32:["DragonAge2.exe"]},id:159,name:"Dragon Age II"},{executables:{win32:["DragonAgeInquisition.exe"]},id:160,name:"Dragon Age: Inquisition"},{executables:{win32:["daorigins.exe"]},id:161,name:"Dragon Age: Origins"},{executables:{win32:["DBXV.exe"]},id:162,name:"Dragon Ball XenoVerse"},{executables:{win32:["DukeForever.exe"]},id:163,name:"Duke Nukem Forever"},{executables:{darwin:["Dustforce.app"],win32:["dustforce.exe"]},id:164,name:"Dustforce"},{executables:{win32:["EliteDangerous32.exe"]},id:165,name:"Elite: Dangerous"},{executables:{win32:["exefile.exe"]},id:166,name:"Eve Online"},{executables:{win32:["eqgame.exe"]},id:167,name:"EverQuest"},{executables:{win32:["EverQuest2.exe"]},id:168,name:"EverQuest II"},{executables:{},id:169,name:"EverQuest Next"},{executables:{win32:["Engine.exe"]},id:170,name:"F.E.A.R."},{executables:{win32:["FEAR2.exe"]},id:171,name:"F.E.A.R. 2: Project Origin"},{executables:{win32:["fallout3.exe"]},id:172,name:"Fallout 3"},{executables:{win32:["FalloutNV.exe"]},id:174,name:"Fallout: New Vegas"},{executables:{win32:["farcry3.exe"]},id:175,name:"Far Cry 3"},{executables:{win32:["fifa15.exe"]},id:176,name:"FIFA 15"},{executables:{win32:["FTLGame.exe"]},id:180,name:"FTL: Faster Than Light"},{executables:{win32:["GTAIV.exe"]},id:181,name:"Grand Theft Auto 4"},{executables:{win32:["GTA5.exe"]},id:182,name:"Grand Theft Auto 5"},{executables:{win32:["Gw.exe"]},id:183,name:"Guild Wars"},{executables:{win32:["H1Z1.exe"]},id:186,name:"H1Z1"},{executables:{win32:["HL2HL2.exe","hl2.exe"]},id:188,name:"Half Life 2"},{executables:{win32:["HOMEFRONT.exe"]},id:195,name:"Homefront"},{executables:{win32:["invisibleinc.exe"]},id:196,name:"Invisible Inc."},{executables:{win32:["LANoire.exe"]},id:197,name:"L.A. Noire"},{executables:{win32:["Landmark64.exe"]},id:198,name:"Landmark"},{executables:{win32:["left4dead2.exe"]},id:201,name:"Left 4 Dead 2"},{executables:{win32:["lineage.exe"]},id:203,name:"Lineage"},{executables:{win32:["Magicka.exe"]},id:206,name:"Magicka"},{executables:{win32:["MapleStory.exe"]},id:208,name:"MapleStory"},{executables:{},id:209,name:"Mark of the Ninja"},{executables:{win32:["MassEffect.exe"]},id:210,name:"Mass Effect"},{executables:{win32:["MassEffect2.exe"]},id:211,name:"Mass Effect 2"},{executables:{win32:["MassEffect3Demo.exe"]},id:212,name:"Mass Effect 3"},{executables:{win32:["METAL GEAR RISING REVENGEANCE.exe"]},id:214,name:"Metal Gear Rising: Revengeance"},{executables:{win32:["metro2033.exe"]},id:215,name:"Metro 2033"},{executables:{win32:["MetroLL.exe"]},id:216,name:"Metro Last Light"},{executables:{win32:["MK10.exe"]},id:218,name:"Mortal Kombat X"},{executables:{win32:["speed.exe"]},id:219,name:"Need For Speed Most Wanted"},{executables:{},id:220,name:"Neverwinder"},{executables:{darwin:["Outlast.app"],win32:["OLGame.exe"]},id:221,name:"Outlast"},{executables:{win32:["PapersPlease.exe"]},id:222,name:"Papers, Please"},{executables:{win32:["payday_win32_release.exe"]},id:223,name:"PAYDAY"},{executables:{win32:["payday2_win32_release.exe"]},id:224,name:"PAYDAY2"},{executables:{win32:["PillarsOfEternity.exe"]},id:225,name:"Pillars of Eternity"},{executables:{win32:["PA.exe"]},id:226,name:"Planetary Annihilation"},{executables:{win32:["planetside2_x86.exe"]},id:227,name:"Planetside 2"},{executables:{win32:["hl2P.exe"]},id:228,name:"Portal"},{executables:{win32:["portal2.exe"]},id:229,name:"Portal 2"},{executables:{win32:["PrimalCarnageGame.exe"]},id:231,name:"Primal Cargnage"},{executables:{win32:["pCARS.exe"]},id:232,name:"Project Cars"},{executables:{win32:["RaceTheSun.exe"]},id:233,name:"Race The Sun"},{executables:{win32:["Rage.exe"]},id:234,name:"RAGE"},{executables:{win32:["ragexe.exe"]},id:235,name:"Ragnarok Online"},{executables:{win32:["rift.exe"]},id:236,name:"Rift"},{executables:{win32:["Rocksmith2014.exe"]},id:237,name:"Rocksmith 2014"},{executables:{win32:["SwiftKit-RS.exe","JagexLauncher.exe"]},id:238,name:"RuneScape"},{executables:{win32:["Shadowgrounds.exe"]},id:239,name:"Shadowgrounds"},{executables:{win32:["survivor.exe"]},id:240,name:"Shadowgrounds: Survivor"},{executables:{win32:["ShovelKnight.exe"]},id:241,name:"Shovel Knight"},{executables:{win32:["SimCity.exe"]},id:242,name:"SimCity"},{executables:{win32:["SporeApp.exe"]},id:245,name:"Spore"},{executables:{win32:["StarCitizen.exe"]},id:246,name:"Star Citizen"},{executables:{},id:247,name:"Star Trek Online"},{executables:{win32:["battlefront.exe"]},id:248,name:"Star Wars Battlefront"},{executables:{win32:["swtor.exe"]},id:249,name:"Star Wars: The Old Republic"},{executables:{win32:["starbound.exe","starbound_opengl.exe"]},id:250,name:"Starbound"},{executables:{win32:["starcraft.exe"]},id:251,name:"Starcraft"},{executables:{win32:["SSFIV.exe"]},id:253,name:"Ultra Street Fighter IV"},{executables:{win32:["superhexagon.exe"]},id:254,name:"Super Hexagon"},{executables:{win32:["swordandsworcery_pc.exe"]},id:255,name:"Superbrothers: Sword & Sworcery EP"},{executables:{win32:["hl2TF.exe"]},id:256,name:"Team Fortress 2"},{executables:{win32:["TERA.exe"]},id:258,name:"TERA"},{executables:{win32:["Terraria.exe"]},id:259,name:"Terraria"},{executables:{win32:["Bethesda.net_Launcher.exe"]},id:260,name:"The Elder Scrolls Online"},{executables:{win32:["TESV.exe"]},id:261,name:"The Elder Scrolls V: Skyrim"},{executables:{win32:["TheSecretWorld.exe"]},id:262,name:"The Secret World"},{executables:{win32:["TS3.exe","ts3w.exe"]},id:264,name:"The Sims 3"},{executables:{win32:["WALKINGDEAD101.EXE"]},id:265,name:"The Walking Dead"},{executables:{win32:["TheWalkingDead2.exe"]},id:266,name:"The Walking Dead Season Two"},{executables:{win32:["witcher3.exe"]},id:267,name:"The Witcher 3"},{executables:{win32:["Future Soldier.exe"]},id:268,name:"Tom Clancy's Ghost Recon: Future Solider"},{executables:{win32:["TombRaider.exe"]},id:269,name:"Tomb Raider (2013)"},{executables:{win32:["Torchlight.exe"]},id:271,name:"Torchlight"},{executables:{win32:["Torchlight2.exe"]},id:272,name:"Torchlight 2"},{executables:{win32:["Shogun2.exe"]},id:273,name:"Total War: Shogun 2"},{executables:{win32:["Transistor.exe"]},id:274,name:"Transistor"},{executables:{win32:["trine.exe"]},id:275,name:"Trine"},{executables:{win32:["trine2_32bit.exe"]},id:276,name:"Trine 2"},{executables:{win32:["UOKR.exe"]},id:277,name:"Ultima Online"},{executables:{win32:["aces.exe"]},id:279,name:"War Thunder"},{executables:{win32:["Warcraft III.exe","wc3.exe"]},id:281,name:"Warcraft 3: Reign of Chaos"},{executables:{win32:["Warcraft II BNE.exe"]},id:282,name:"Warcraft II"},{executables:{win32:["Warframe.x64.exe","Warframe.exe"]},id:283,name:"Warframe"},{executables:{win32:["watch_dogs.exe"]},id:284,name:"Watch Dogs"},{executables:{win32:["WildStar64.exe"]},id:285,name:"WildStar"},{executables:{win32:["XComGame.exe"]},id:288,name:"XCOM: Enemy Unknown"},{executables:{win32:["DFO.exe","dfo.exe"]},id:289,name:"Dungeon Fighter Online"},{executables:{win32:["aclauncher.exe","acclient.exe"]},id:290,name:"Asheron's Call"},{executables:{win32:["MapleStory2.exe"]},id:291,name:"MapleStory 2"},{executables:{win32:["ksp.exe"]},id:292,name:"Kerbal Space Program"},{executables:{win32:["PINBALL.EXE"]},id:293,name:"3D Pinball: Space Cadet"},{executables:{win32:["dave.exe"]},id:294,name:"Dangerous Dave"},{executables:{win32:["iwbtgbeta(slomo).exe","iwbtgbeta(fs).exe"]},id:295,name:"I Wanna Be The Guy"},{executables:{win32:["MechWarriorOnline.exe "]},id:296,name:"Mech Warrior Online"},{executables:{win32:["dontstarve_steam.exe"]},id:297,name:"Don't Starve"},{executables:{win32:["GalCiv3.exe"]},id:298,name:"Galactic Civilization 3"},{executables:{win32:["Risk of Rain.exe"]},id:299,name:"Risk of Rain"},{executables:{win32:["Binding_of_Isaac.exe","Isaac-ng.exe"]},id:300,name:"The Binding of Isaac"},{executables:{win32:["RustClient.exe"]},id:301,name:"Rust"},{executables:{win32:["Clicker Heroes.exe"]},id:302,name:"Clicker Heroes"},{executables:{win32:["Brawlhalla.exe"]},id:303,name:"Brawlhalla"},{executables:{win32:["TownOfSalem.exe"]},id:304,name:"Town of Salem"},{executables:{win32:["osu!.exe"]},id:305,name:"osu!"},{executables:{win32:["PathOfExileSteam.exe","PathOfExile.exe"]
+},id:306,name:"Path of Exile"},{executables:{win32:["Dolphin.exe"]},id:307,name:"Dolphin"},{executables:{win32:["RocketLeague.exe"]},id:308,name:"Rocket League"},{executables:{win32:["TJPP.exe"]},id:309,name:"Jackbox Party Pack"},{executables:{win32:["KFGame.exe"]},id:310,name:"Killing Floor 2"},{executables:{win32:["ShooterGame.exe"]},id:311,name:"Ark: Survival Evolved"},{executables:{win32:["LifeIsStrange.exe"]},id:312,name:"Life Is Strange"},{executables:{win32:["Client_tos.exe"]},id:313,name:"Tree of Savior"},{executables:{win32:["olliolli2.exe"]},id:314,name:"OlliOlli2"},{executables:{win32:["cw.exe"]},id:315,name:"Closers Dimension Conflict"},{executables:{win32:["ESSTEAM.exe","elsword.exe","x2.exe"]},id:316,name:"Elsword"},{executables:{win32:["ori.exe"]},id:317,name:"Ori and the Blind Forest"},{executables:{win32:["Skyforge.exe"]},id:318,name:"Skyforge"},{executables:{win32:["projectzomboid64.exe","projectzomboid32.exe"]},id:319,name:"Project Zomboid"},{executables:{win32:["From_The_Depths.exe"]},id:320,name:"The Depths"},{executables:{win32:["TheCrew.exe"]},id:321,name:"The Crew"},{executables:{win32:["MarvelHeroes2015.exe"]},id:322,name:"Marvel Heroes 2015"},{executables:{win32:["timeclickers.exe"]},id:324,name:"Time Clickers"},{executables:{win32:["eurotrucks2.exe"]},id:325,name:"Euro Truck Simulator 2"},{executables:{win32:["FarmingSimulator2015Game.exe"]},id:326,name:"Farming Simulator 15"},{executables:{win32:["strife.exe"]},id:327,name:"Strife"},{executables:{win32:["Awesomenauts.exe"]},id:328,name:"Awesomenauts"},{executables:{win32:["Dofus.exe"]},id:329,name:"Dofus"},{executables:{win32:["Boid.exe"]},id:330,name:"Boid"},{executables:{win32:["adventure-capitalist.exe"]},id:331,name:"AdVenture Capitalist"},{executables:{win32:["OrcsMustDie2.exe"]},id:332,name:"Orcs Must Die! 2"},{executables:{win32:["Mountain.exe"]},id:333,name:"Mountain"},{executables:{win32:["Valkyria.exe"]},id:335,name:"Valkyria Chronicles"},{executables:{win32:["ffxiiiimg.exe"]},id:336,name:"Final Fantasy XIII"},{executables:{win32:["TLR.exe"]},id:337,name:"The Last Remnant"},{executables:{win32:["Cities.exe"]},id:339,name:"Cities Skylines"},{executables:{win32:["worldofwarships.exe","WoWSLauncher.exe"]},id:341,name:"World of Warships"},{executables:{win32:["spacegame-Win64-shipping.exe"]},id:342,name:"Fractured Space"},{executables:{win32:["thespacegame.exe"]},id:343,name:"Ascent - The Space Game"},{executables:{win32:["DuckGame.exe"]},id:344,name:"Duck Game"},{executables:{win32:["PPSSPPWindows.exe"]},id:345,name:"PPSSPP"},{executables:{win32:["MBAA.exe"]},id:346,name:"Melty Blood Actress Again: Current Code"},{executables:{win32:["TheWolfAmongUs.exe"]},id:347,name:"The Wolf Among Us"},{executables:{win32:["SpaceEngineers.exe"]},id:348,name:"Space Engineers"},{executables:{win32:["Borderlands.exe"]},id:349,name:"Borderlands"},{executables:{win32:["100orange.exe"]},id:351,name:"100% Orange Juice"},{executables:{win32:["reflex.exe"]},id:354,name:"Reflex"},{executables:{win32:["pso2.exe"]},id:355,name:"Phantasy Star Online 2"},{executables:{win32:["AssettoCorsa.exe"]},id:356,name:"Assetto Corsa"},{executables:{win32:["iw3mp.exe","iw3sp.exe"]},id:357,name:"Call of Duty 4: Modern Warfare"},{executables:{win32:["WolfOldBlood_x64.exe"]},id:358,name:"Wolfenstein: The Old Blood"},{executables:{win32:["castle.exe"]},id:359,name:"Castle Crashers"},{executables:{win32:["vindictus.exe"]},id:360,name:"Vindictus"},{executables:{win32:["ShooterGame-Win32-Shipping.exe"]},id:361,name:"Dirty Bomb"},{executables:{win32:["BatmanAK.exe"]},id:362,name:"Batman Arkham Knight"},{executables:{win32:["drt.exe"]},id:363,name:"Dirt Rally"},{executables:{win32:["rFactor.exe"]},id:364,name:"rFactor"},{executables:{win32:["clonk.exe"]},id:365,name:"Clonk Rage"},{executables:{win32:["SRHK.exe"]},id:366,name:"Shadowrun: Hong Kong"},{executables:{win32:["Insurgency.exe"]},id:367,name:"Insurgency"},{executables:{win32:["StepMania.exe"]},id:368,name:"Step Mania"},{executables:{win32:["FirefallCLient.exe"]},id:369,name:"Firefall"},{executables:{win32:["mirrorsedge.exe"]},id:370,name:"Mirrors Edge"},{executables:{win32:["MgsGroundZeroes.exe"]},id:371,name:"Metal Gear Solid V: Ground Zeroes"},{executables:{win32:["mgsvtpp.exe"]},id:372,name:"Metal Gear Solid V: The Phantom Pain"},{executables:{win32:["tld.exe"]},id:373,name:"The Long Dark"},{executables:{win32:["TKOM.exe"]},id:374,name:"Take On Mars"},{executables:{win32:["robloxplayerlauncher.exe","Roblox.exe"]},id:375,name:"Roblox"},{executables:{win32:["eu4.exe"]},id:376,name:"Europa Universalis 4"},{executables:{win32:["APB.exe"]},id:377,name:"APB Reloaded"},{executables:{win32:["Robocraft.exe"]},id:378,name:"Robocraft"},{executables:{win32:["Unity.exe"]},id:379,name:"Unity"},{executables:{win32:["Simpsons.exe"]},id:380,name:"The Simpsons: Hit & Run"},{executables:{win32:["Dnlauncher.exe","DragonNest.exe"]},id:381,name:"Dragon Nest"},{executables:{win32:["Trove.exe"]},id:382,name:"Trove"},{executables:{win32:["EndlessLegend.exe"]},id:383,name:"Endless Legend"},{executables:{win32:["TurbineLauncher.exe","dndclient.exe"]},id:384,name:"Dungeons & Dragons Online"},{executables:{win32:["quakelive.exe","quakelive_steam.exe"]},id:385,name:"Quake Live"},{executables:{win32:["7DaysToDie.exe"]},id:386,name:"7DaysToDie"},{executables:{win32:["SpeedRunners.exe"]},id:387,name:"SpeedRunners"},{executables:{win32:["gamemd.exe"]},id:388,name:"Command & Conquer: Red Alert 2"},{executables:{win32:["generals.exe"]},id:389,name:"Command & Conquer Generals: Zero Hour"},{executables:{win32:["Oblivion.exe"]},id:390,name:"The Elder Scrolls 4: Oblivion"},{executables:{win32:["mgsi.exe"]},id:391,name:"Metal Gear Solid"},{executables:{win32:["EoCApp.exe"]},id:392,name:"Divinity - Original Sin"},{executables:{win32:["Torment.exe"]},id:393,name:"Planescape: Torment"},{executables:{win32:["HexPatch.exe"]},id:394,name:"Hex: Shards of Fate"},{executables:{win32:["NS3FB.exe"]},id:395,name:"Naruto Shippuden Ultimate Ninja Storm 3 Full Burst"},{executables:{win32:["NSUNSR.exe"]},id:396,name:"Naruto Shippuden Ultimate Ninja Storm Revolution"},{executables:{win32:["SaintsRowIV.exe"]},id:397,name:"Saints Row IV"},{executables:{win32:["Shadowrun.exe"]},id:398,name:"Shadowrun"},{executables:{win32:["DungeonoftheEndless.exe"]},id:399,name:"Dungeon of the Endless"},{executables:{win32:["Hon.exe"]},id:400,name:"Heroes of Newerth"},{executables:{win32:["mabinogi.exe"]},id:401,name:"Mabinogi"},{executables:{win32:["CoD2MP_s.exe","CoDSP_s.exe"]},id:402,name:"Call of Duty 2:"},{executables:{win32:["CoDWaWmp.exe","CoDWaw.exe"]},id:403,name:"Call of Duty: World at War"},{executables:{win32:["heroes.exe"]},id:404,name:"Mabinogi Heroes (Vindictus) "},{executables:{win32:["KanColleViewer.exe"]},id:405,name:"KanColle "},{executables:{win32:["cyphers.exe"]},id:406,name:"Cyphers"},{executables:{win32:["RelicCoH2.exe"]},id:407,name:"Company of Heroes 2"},{executables:{win32:["MJ.exe"]},id:408,name:"セガNET麻雀MJ"},{executables:{win32:["ge.exe"]},id:409,name:"Granado Espada"},{executables:{win32:["NovaRO.exe"]},id:410,name:"Nova Ragnarok Online"},{executables:{win32:["RivalsofAether.exe"]},id:411,name:"Rivals of Aether"},{executables:{win32:["bfh.exe"]},id:412,name:"Battlefield Hardline"},{executables:{win32:["GrowHome.exe"]},id:413,name:"Grow Home"},{executables:{win32:["patriots.exe"]},id:414,name:"Rise of Nations Extended"},{executables:{win32:["Railroads.exe"]},id:415,name:"Sid Meier's Railroads!"},{executables:{win32:["Empire.exe"]},id:416,name:"Empire: Total War"},{executables:{win32:["Napoleon.exe"]},id:417,name:"Napoleon: Total War"},{executables:{win32:["gta_sa.exe"]},id:418,name:"Grand Theft Auto: San Andreas"},{executables:{win32:["MadMax.exe"]},id:419,name:"Mad Max"},{executables:{win32:["Titanfall.exe"]},id:420,name:"Titanfall"},{executables:{win32:["age2_x1.exe"]},id:421,name:"Age of Empires II: The Conquerors"},{executables:{win32:["Rome2.exe"]},id:422,name:"Total War: ROME 2"},{executables:{win32:["ShadowOfMordor.exe"]},id:423,name:"Middle-earth: Shadow of Mordor"},{executables:{win32:["Subnautica.exe"]},id:424,name:"Subnautica"},{executables:{win32:["anno5.exe"]},id:425,name:"Anno 2070"},{executables:{win32:["carrier.exe"]},id:426,name:"Carrier Command Gaea Mission"},{executables:{win32:["DarksidersPC.exe"]},id:427,name:"Darksiders"},{executables:{win32:["Darksiders2.exe"]},id:428,name:"Darksiders 2"},{executables:{win32:["mudlet.exe"]},id:429,name:"Mudlet"},{executables:{win32:["DunDefLauncher.exe"]},id:430,name:"Dungeon Defenders II"},{executables:{win32:["hng.exe"]},id:431,name:"Heroes and Generals"},{executables:{win32:["WFTOGame.exe"]},id:432,name:"War of the Overworld"},{executables:{win32:["Talisman.exe"]},id:433,name:"Talisman: Digital Edition"},{executables:{win32:["limbo.exe"]},id:434,name:"Limbo"},{executables:{win32:["ibbobb.exe"]},id:435,name:"ibb & obb"},{executables:{win32:["BattleBlockTheater.exe"]},id:436,name:"BattleBlock Theater"},{executables:{win32:["iracinglauncher.exe","iracingsim.exe","iracingsim64.exe"]},id:437,name:"iRacing"},{executables:{win32:["CivilizationV_DX11.exe"]},id:438,name:"Civilization V"}]},{}]},{},[9])(9)});
\ No newline at end of file
diff --git a/web-dist/discord.min.3.9.0.js b/web-dist/discord.min.3.9.0.js
new file mode 100644
index 000000000..97652caf4
--- /dev/null
+++ b/web-dist/discord.min.3.9.0.js
@@ -0,0 +1,3 @@
+!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Discord=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g>>a&1)},a.prototype.setBit=function(){},e(a,[{key:"createInstantInvite",get:function(){return this.getBit(0)},set:function(a){this.setBit(0,a)}},{key:"manageRoles",get:function(){return this.getBit(3)},set:function(a){this.setBit(3,a)}},{key:"manageChannels",get:function(){return this.getBit(4)},set:function(a){this.setBit(4,a)}},{key:"readMessages",get:function(){return this.getBit(10)},set:function(a){this.setBit(10,a)}},{key:"sendMessages",get:function(){return this.getBit(11)},set:function(a){this.setBit(11,a)}},{key:"sendTTSMessages",get:function(){return this.getBit(12)},set:function(a){this.setBit(12,a)}},{key:"manageMessages",get:function(){return this.getBit(13)},set:function(a){this.setBit(13,a)}},{key:"embedLinks",get:function(){return this.getBit(14)},set:function(a){this.setBit(14,a)}},{key:"attachFiles",get:function(){return this.getBit(15)},set:function(a){this.setBit(15,a)}},{key:"readMessageHistory",get:function(){return this.getBit(16)},set:function(a){this.setBit(16,a)}},{key:"mentionEveryone",get:function(){return this.getBit(17)},set:function(a){this.setBit(17,a)}},{key:"voiceConnect",get:function(){return this.getBit(20)},set:function(a){this.setBit(20,a)}},{key:"voiceSpeak",get:function(){return this.getBit(21)},set:function(a){this.setBit(21,a)}},{key:"voiceMuteMembers",get:function(){return this.getBit(22)},set:function(a){this.setBit(22,a)}},{key:"voiceDeafenMembers",get:function(){return this.getBit(23)},set:function(a){this.setBit(23,a)}},{key:"voiceMoveMembers",get:function(){return this.getBit(24)},set:function(a){this.setBit(24,a)}},{key:"voiceUseVoiceActivation",get:function(){return this.getBit(25)},set:function(a){this.setBit(25,a)}}]),a}();b.exports=f},{}],2:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c=k.length)break;n=k[m++]}else{if(m=k.next(),m.done)break;n=m.value}for(var o=n,p=[],q=o.mentions,r=Array.isArray(q),s=0,q=r?q:q[Symbol.iterator]();;){var t;if(r){if(s>=q.length)break;t=q[s++]}else{if(s=q.next(),s.done)break;t=s.value}var u=t;p.push(d.addUser(u))}var v=d.addUser(o.author);f.push(new j(o,i,p,v))}c(null,f),e(f)}})})},a.prototype.deleteChannel=function(a){var b=arguments.length<=1||void 0===arguments[1]?function(a){}:arguments[1],c=this;return new Promise(function(d,e){var g=a;a instanceof i&&(g=a.id),n.del(f.CHANNELS+"/"+g).set("authorization",c.token).end(function(a){a?(b(a),e(a)):(b(null),d())})})},a.prototype.joinServer=function(a){var b=arguments.length<=1||void 0===arguments[1]?function(a,b){}:arguments[1],c=this;return new Promise(function(d,e){var g=a instanceof k?a.code:a;n.post(f.API+"/invite/"+g).set("authorization",c.token).end(function(a,f){a?(b(a),e(a)):c.getServer("id",f.body.guild.id)?d(c.getServer("id",f.body.guild.id)):c.serverCreateListener[f.body.guild.id]=[d,b]})})},a.prototype.sendFile=function(a,b){var c=arguments.length<=2||void 0===arguments[2]?"image.png":arguments[2],d=arguments.length<=3||void 0===arguments[3]?function(a,b){}:arguments[3],e=this,f=new Promise(function(g,h){function i(a){e.options.queue?(e.queue[a]||(e.queue[a]=[]),e.queue[a].push({action:"sendFile",attachment:l,attachmentName:c,then:j,error:k}),e.checkQueue(a)):e._sendFile(a,l,c).then(j)["catch"](k)}function j(a){f.message=a,d(null,a),g(a)}function k(a){f.error=a,d(a),h(a)}var l;"string"==typeof b||b instanceof String?(l=p.createReadStream(b),c=b):l=b,e.resolveDestination(a).then(i)["catch"](k)});return f},a.prototype.sendMessage=function(a,b,c){var d=arguments.length<=3||void 0===arguments[3]?function(a,b){}:arguments[3],e=arguments.length<=4||void 0===arguments[4]?"":arguments[4],f=this,g=new Promise(function(h,i){function j(a){d(a),i(a)}function k(a){f.options.queue?(f.queue[a]||(f.queue[a]=[]),f.queue[a].push({action:"sendMessage",content:b,mentions:p,tts:!!c,then:l,error:m}),f.checkQueue(a)):f._sendMessage(a,b,c,p).then(l)["catch"](m)}function l(a){g.message=a,d(null,a),h(a)}function m(a){g.error=a,d(a),i(a)}function n(){var a=b;return b instanceof Array&&(a=b.join("\n")),a}function o(){for(var a=[],c=b.match(/<@[^>]*>/g)||[],d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;a.push(g.substring(2,g.length-1))}return a}"function"==typeof c&&(d=c,c=!1),b=e+n(b);var p=o();f.resolveDestination(a).then(k)["catch"](j)});return g},a.prototype.createws=function(a){if(this.websocket)return!1;var b=this;this.websocket=new o(a),this.websocket.onopen=function(){b.trySendConnData()},this.websocket.onclose=function(){b.trigger("disconnected")},this.websocket.onmessage=function(a){var c=!1,d={};try{c=JSON.parse(a.data),d=c.d}catch(e){return void b.trigger("error",e,a)}switch(b.trigger("raw",c),c.t){case"READY":b.debug("received ready packet"),b.user=b.addUser(d.user);for(var f=d.guilds,h=Array.isArray(f),k=0,f=h?f:f[Symbol.iterator]();;){var l;if(h){if(k>=f.length)break;l=f[k++]}else{if(k=f.next(),k.done)break;l=k.value}var m=l,n=b.addServer(m)}for(var o=d.private_channels,p=Array.isArray(o),q=0,o=p?o:o[Symbol.iterator]();;){var r;if(p){if(q>=o.length)break;r=o[q++]}else{if(q=o.next(),q.done)break;r=q.value}var s=r;b.addPMChannel(s)}b.trigger("ready"),b.readyTime=Date.now(),b.debug("cached "+b.serverCache.length+" servers, "+b.channelCache.length+" channels, "+b.pmChannelCache.length+" PMs and "+b.userCache.length+" users."),b.state=3,setInterval(function(){b.keepAlive.apply(b)},d.heartbeat_interval);break;case"MESSAGE_CREATE":b.debug("received message");var t=[];d.mentions=d.mentions||[];for(var u=d.mentions,v=Array.isArray(u),w=0,u=v?u:u[Symbol.iterator]();;){var x;if(v){if(w>=u.length)break;x=u[w++]}else{if(w=u.next(),w.done)break;x=w.value}var y=x;t.push(b.addUser(y))}var z=b.getChannel("id",d.channel_id);if(z){var A=z.addMessage(new j(d,z,t,b.addUser(d.author)));b.trigger("message",A)}break;case"MESSAGE_DELETE":b.debug("message deleted");var z=b.getChannel("id",d.channel_id),B=z.getMessage("id",d.id);B?(b.trigger("messageDelete",z,B),z.messages.splice(z.messages.indexOf(B),1)):b.trigger("messageDelete",z);break;case"MESSAGE_UPDATE":b.debug("message updated");var z=b.getChannel("id",d.channel_id),C=z.getMessage("id",d.id);if(C){var D={};for(var E in C)D[E]=C[E];for(var E in d)D[E]=d[E];for(var t=[],F=D.mentions,G=Array.isArray(F),H=0,F=G?F:F[Symbol.iterator]();;){var I;if(G){if(H>=F.length)break;I=F[H++]}else{if(H=F.next(),H.done)break;I=H.value}var y=I;t.push(b.addUser(y))}var J=new j(D,z,t,C.author);b.trigger("messageUpdate",J,C),z.messages[z.messages.indexOf(C)]=J}break;case"GUILD_DELETE":var n=b.getServer("id",d.id);n&&(b.serverCache.splice(b.serverCache.indexOf(n),1),b.trigger("serverDelete",n));break;case"CHANNEL_DELETE":var z=b.getChannel("id",d.id);if(z){var n=z.server;n&&n.channels.splice(n.channels.indexOf(z),1),b.trigger("channelDelete",z),b.serverCache.splice(b.serverCache.indexOf(z),1)}break;case"GUILD_CREATE":var n=b.getServer("id",d.id);if(n||(n=b.addServer(d)),b.serverCreateListener[d.id]){var K=b.serverCreateListener[d.id];K[0](n),K[1](null,n),b.serverCreateListener[d.id]=null}b.trigger("serverCreate",n);break;case"CHANNEL_CREATE":var z=b.getChannel("id",d.id);if(!z){var L;L=d.is_private?b.addPMChannel(d):b.addChannel(d,d.guild_id);var M=b.getServer("id",d.guild_id);M&&M.addChannel(L),b.trigger("channelCreate",L)}break;case"GUILD_MEMBER_ADD":var n=b.getServer("id",d.guild_id);if(n){var N=b.addUser(d.user);b.trigger("serverNewMember",n.addMember(N,d.roles),n)}break;case"GUILD_MEMBER_REMOVE":var n=b.getServer("id",d.guild_id);if(n){var N=b.addUser(d.user);n.removeMember("id",N.id),b.trigger("serverRemoveMember",N,n)}break;case"USER_UPDATE":if(b.user&&d.id===b.user.id){var O=new g(d);b.trigger("userUpdate",O,b.user),~b.userCache.indexOf(b.user)&&(b.userCache[b.userCache.indexOf(b.user)]=O),b.user=O}break;case"PRESENCE_UPDATE":var P=b.getUser("id",d.user.id);if(P){d.user.username=d.user.username||P.username,d.user.id=d.user.id||P.id,d.user.discriminator=d.user.discriminator||P.discriminator,d.user.avatar=d.user.avatar||P.avatar;var Q=new g(d.user);Q.equalsStrict(P)?(b.trigger("presence",{user:P,oldStatus:P.status,status:d.status,server:b.getServer("id",d.guild_id),gameId:d.game_id}),P.status=d.status,P.gameId=d.game_id):(b.userCache[b.userCache.indexOf(P)]=Q,b.trigger("userUpdate",P,Q))}break;case"CHANNEL_UPDATE":var R=b.getChannel("id",d.id),S=b.getServer("id",d.guild_id);if(R&&S){var T=new i(d,S);T.messages=R.messages,b.trigger("channelUpdate",R,T),b.channelCache[b.channelCache.indexOf(R)]=T}break;case"TYPING_START":var P=b.getUser("id",d.user_id),R=b.getChannel("id",d.channel_id);b.userTypingListener[d.user_id]&&-1!==b.userTypingListener[d.user_id]||b.trigger("startTyping",P,R),b.userTypingListener[d.user_id]=Date.now(),setTimeout(function(){-1!==b.userTypingListener[d.user_id]&&Date.now()-b.userTypingListener[d.user_id]>6e3&&(b.trigger("stopTyping",P,R),b.userTypingListener[d.user_id]=-1)},6e3);break;case"GUILD_ROLE_DELETE":var n=b.getServer("id",d.guild_id),U=n.getRole(d.role_id);b.trigger("serverRoleDelete",n,U),n.removeRole(U.id);break;case"GUILD_ROLE_UPDATE":var n=b.getServer("id",d.guild_id),U=n.getRole(d.role.id),V=n.updateRole(d.role);b.trigger("serverRoleUpdate",n,U,V);break;default:b.debug("received unknown packet"),b.trigger("unknown",c)}}},a.prototype.addUser=function(a){return this.getUser("id",a.id)||this.userCache.push(new g(a)),this.getUser("id",a.id)},a.prototype.addChannel=function(a,b){return this.getChannel("id",a.id)||this.channelCache.push(new i(a,this.getServer("id",b))),this.getChannel("id",a.id)},a.prototype.addPMChannel=function(a){return this.getPMChannel("id",a.id)||this.pmChannelCache.push(new l(a,this)),this.getPMChannel("id",a.id)},a.prototype.setTopic=function(a,b){var c=arguments.length<=2||void 0===arguments[2]?function(a){}:arguments[2],d=this;return new Promise(function(e,g){function h(a){c(a),g(a)}function i(a){var g=d.getChannel("id",a);n.patch(f.CHANNELS+"/"+a).set("authorization",d.token).send({name:g.name,position:0,topic:b}).end(function(a,b){a?h(a):(g.topic=b.body.topic,e(),c())})}d.resolveDestination(a).then(i)["catch"](h)})},a.prototype.addServer=function(a){var b=this,c=this.getServer("id",a.id);if(a.unavailable)return b.trigger("unavailable",a),void b.debug("Server ID "+a.id+" has been marked unavailable by Discord. It was not cached.");if(!c&&(c=new h(a,this),this.serverCache.push(c),a.channels))for(var d=a.channels,e=Array.isArray(d),f=0,d=e?d:d[Symbol.iterator]();;){var g;if(e){if(f>=d.length)break;g=d[f++]}else{if(f=d.next(),f.done)break;g=f.value}var i=g;c.channels.push(this.addChannel(i,c.id))}for(var j=a.presences,k=Array.isArray(j),l=0,j=k?j:j[Symbol.iterator]();;){var m;if(k){if(l>=j.length)break;m=j[l++]}else{if(l=j.next(),l.done)break;m=l.value}var n=m,o=b.getUser("id",n.user.id);o.status=n.status,o.gameId=n.game_id}return c},a.prototype.getUser=function(a,b){for(var c=this.userCache,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;if(g[a]===b)return g}return null},a.prototype.getChannel=function(a,b){for(var c=this.channelCache,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;if(g[a]===b)return g}return this.getPMChannel(a,b)},a.prototype.getPMChannel=function(a,b){for(var c=this.pmChannelCache,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;if(g[a]===b)return g}return null},a.prototype.getServer=function(a,b){for(var c=this.serverCache,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;if(g[a]===b)return g}return null},a.prototype.trySendConnData=function(){if(this.token&&!this.alreadySentData){this.alreadySentData=!0;var a={op:2,d:{token:this.token,v:3,properties:{$os:"discord.js",$browser:"discord.js",$device:"discord.js",$referrer:"",$referring_domain:""}}};this.websocket.send(JSON.stringify(a))}},a.prototype.resolveServerID=function(a){return a instanceof h?a.id:!isNaN(a)&&a.length&&17===a.length?a:void 0},a.prototype.resolveDestination=function(a){var b=!1,c=this;return new Promise(function(d,e){if(a instanceof h)b=a.id;else if(a instanceof i)b=a.id;else if(a instanceof j)b=a.channel.id;else if(a instanceof l)b=a.id;else if(a instanceof g){for(var f=c.pmChannelCache,k=Array.isArray(f),m=0,f=k?f:f[Symbol.iterator]();;){var n;if(k){if(m>=f.length)break;n=f[m++]}else{if(m=f.next(),m.done)break;n=m.value}var o=n;if(o.user&&o.user.equals(a))return void d(o.id)}c.startPM(a).then(function(a){d(a.id)})["catch"](e)}else b=a;b?d(b):e()})},a.prototype._sendMessage=function(a,b,c,d){var e=this;return new Promise(function(g,h){n.post(f.CHANNELS+"/"+a+"/messages").set("authorization",e.token).send({content:b,mentions:d,tts:c}).end(function(a,b){if(a)h(a);else{var c=b.body,d=[];c.mentions=c.mentions||[];for(var f=c.mentions,i=Array.isArray(f),k=0,f=i?f:f[Symbol.iterator]();;){var l;if(i){if(k>=f.length)break;l=f[k++]}else{if(k=f.next(),k.done)break;l=k.value}var m=l;d.push(e.addUser(m))}var n=e.getChannel("id",c.channel_id);if(n){var o=n.addMessage(new j(c,n,d,e.addUser(c.author)));g(o)}}})})},a.prototype._sendFile=function(a,b){var c=arguments.length<=2||void 0===arguments[2]?"DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png":arguments[2],d=this;return new Promise(function(e,g){n.post(f.CHANNELS+"/"+a+"/messages").set("authorization",d.token).attach("file",b,c).end(function(b,c){if(b)g(b);else{var f=d.getChannel("id",a);if(f){var h=f.addMessage(new j(c.body,f,[],d.user));e(h)}}})})},a.prototype._updateMessage=function(a,b){var c=this;return new Promise(function(d,e){n.patch(f.CHANNELS+"/"+a.channel.id+"/messages/"+a.id).set("authorization",c.token).send({content:b,mentions:[]}).end(function(b,c){if(b)e(b);else{var f=new j(c.body,a.channel,a.mentions,a.sender);d(f),a.channel.messages[a.channel.messages.indexOf(a)]=f}})})},a.prototype.getGateway=function(){var a=this;return new Promise(function(b,c){n.get(f.API+"/gateway").set("authorization",a.token).end(function(a,d){a?c(a):b(d.body.url)})})},a.prototype.setStatusIdle=function(){this.setStatus("idle")},a.prototype.setStatusOnline=function(){this.setStatus("online")},a.prototype.setStatusActive=function(){this.setStatusOnline()},a.prototype.setStatusHere=function(){this.setStatusOnline()},a.prototype.setStatusAway=function(){this.setStatusIdle()},a.prototype.startTyping=function(a,b){function c(a){if(!d.typingIntervals[a]){var c=function(){n.post(f.CHANNELS+"/"+a+"/typing").set("authorization",d.token).end()};c();var e=setInterval(c,3e3);d.typingIntervals[a]=e,b&&setTimeout(function(){d.stopTyping(a)},b)}}var d=this;this.resolveDestination(a).then(c)},a.prototype.stopTyping=function(a){function b(a){c.typingIntervals[a]&&(clearInterval(c.typingIntervals[a]),delete c.typingIntervals[a])}var c=this;this.resolveDestination(a).then(b)},a.prototype.setStatus=function(a){var b="online"===a?null:Date.now();this.__idleTime=b,this.websocket.send(JSON.stringify({op:3,d:{idle_since:this.__idleTime,game_id:this.__gameId}}))},a.prototype.setPlayingGame=function(a){if(a instanceof String||"string"==typeof a){var b=a.trim().toUpperCase();a=null;for(var c=m,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;if(g.name.trim().toUpperCase()===b){a=g.id;break}}}this.__gameId=a,this.websocket.send(JSON.stringify({op:3,d:{idle_since:this.__idleTime,game_id:this.__gameId}}))},a.prototype.playGame=function(a){this.setPlayingGame(a)},a.prototype.playingGame=function(a){this.setPlayingGame(a)},e(a,[{key:"uptime",get:function(){return this.readyTime?Date.now()-this.readyTime:null}},{key:"ready",get:function(){return 3===this.state}},{key:"servers",get:function(){return this.serverCache}},{key:"channels",get:function(){return this.channelCache}},{key:"users",get:function(){return this.userCache}},{key:"PMChannels",get:function(){return this.pmChannelCache}},{key:"messages",get:function(){for(var a=[],b=this.channelCache,c=Array.isArray(b),d=0,b=c?b:b[Symbol.iterator]();;){var e;if(c){if(d>=b.length)break;e=b[d++]}else{if(d=b.next(),d.done)break;e=d.value}var f=e;a=a.concat(f.messages)}return a}}]),a}();b.exports=r},{"../ref/gameMap.json":19,"./Endpoints.js":3,"./PMChannel.js":6,"./channel.js":8,"./invite.js":10,"./message.js":11,"./server.js":12,"./user.js":13,fs:14,superagent:15,ws:18}],3:[function(a,b,c){"use strict";c.BASE_DOMAIN="discordapp.com",c.BASE="https://"+c.BASE_DOMAIN,c.WEBSOCKET_HUB="wss://"+c.BASE_DOMAIN+"/hub",c.API=c.BASE+"/api",c.AUTH=c.API+"/auth",c.LOGIN=c.AUTH+"/login",c.LOGOUT=c.AUTH+"/logout",c.USERS=c.API+"/users",c.SERVERS=c.API+"/guilds",c.CHANNELS=c.API+"/channels"},{}],4:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c>>a&1)},a.prototype.setBit=function(){},e(a,[{key:"createInstantInvite",get:function(){return this.getBit(0)},set:function(a){this.setBit(0,a)}},{key:"manageRoles",get:function(){return this.getBit(3)},set:function(a){this.setBit(3,a)}},{key:"manageChannels",get:function(){return this.getBit(4)},set:function(a){this.setBit(4,a)}},{key:"readMessages",get:function(){return this.getBit(10)},set:function(a){this.setBit(10,a)}},{key:"sendMessages",get:function(){return this.getBit(11)},set:function(a){this.setBit(11,a)}},{key:"sendTTSMessages",get:function(){return this.getBit(12)},set:function(a){this.setBit(12,a)}},{key:"manageMessages",get:function(){return this.getBit(13)},set:function(a){this.setBit(13,a)}},{key:"embedLinks",get:function(){return this.getBit(14)},set:function(a){this.setBit(14,a)}},{key:"attachFiles",get:function(){return this.getBit(15)},set:function(a){this.setBit(15,a)}},{key:"readMessageHistory",get:function(){return this.getBit(16)},set:function(a){this.setBit(16,a)}},{key:"mentionEveryone",get:function(){return this.getBit(17)},set:function(a){this.setBit(17,a)}},{key:"voiceConnect",get:function(){return this.getBit(20)},set:function(a){this.setBit(20,a)}},{key:"voiceSpeak",get:function(){return this.getBit(21)},set:function(a){this.setBit(21,a)}},{key:"voiceMuteMembers",get:function(){return this.getBit(22)},set:function(a){this.setBit(22,a)}},{key:"voiceDeafenMembers",get:function(){return this.getBit(23)},set:function(a){this.setBit(23,a)}},{key:"voiceMoveMembers",get:function(){return this.getBit(24)},set:function(a){this.setBit(24,a)}},{key:"voiceUseVoiceActivation",get:function(){return this.getBit(25)},set:function(a){this.setBit(25,a)}}]),a}();b.exports=f},{}],5:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}function e(a,b){if("function"!=typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function, not "+typeof b);a.prototype=Object.create(b&&b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),b&&(Object.setPrototypeOf?Object.setPrototypeOf(a,b):a.__proto__=b)}var f=function(){function a(a,b){for(var c=0;c=d.length)break;g=d[f++]}else{if(f=d.next(),f.done)break;g=f.value}var h=g;h.id===this.id&&"member"===h.type?c.push(h):-1!==this.rawRoles.indexOf(h.id)&&b.push(h)}if(0===b.length&&0===c.length)return new i(this.evalPerms.packed);for(var j=0!==b.length?b[0].packed:c[0].packed,k=b,l=Array.isArray(k),m=0,k=l?k:k[Symbol.iterator]();;){var n;if(l){if(m>=k.length)break;n=k[m++]}else{if(m=k.next(),m.done)break;n=m.value}var h=n;j&=~h.deny,j|=h.allow}for(var o=c,p=Array.isArray(o),q=0,o=p?o:o[Symbol.iterator]();;){var r;if(p){if(q>=o.length)break;r=o[q++]}else{if(q=o.next(),q.done)break;r=q.value}var h=r;j&=~h.deny,j|=h.allow}return new i(j)},f(b,[{key:"roles",get:function(){for(var a=[this.server.getRole(this.server.id)],b=this.rawRoles,c=Array.isArray(b),d=0,b=c?b:b[Symbol.iterator]();;){var e;if(c){if(d>=b.length)break;e=b[d++]}else{if(d=b.next(),d.done)break;e=d.value}var f=e;a.push(this.server.getRole(f))}return a}},{key:"evalPerms",get:function(){for(var a=this.roles,b=a[0].packed,c=a,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;b|=g.packed}return new h({permissions:b})}}]),b}(g);b.exports=j},{"./EvaluatedPermissions.js":4,"./ServerPermissions.js":7,"./user.js":13}],6:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c1e3&&this.messages.splice(0,1);for(var c=this.messages,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;if(g[a]===b)return g}return null},e(a,[{key:"isPrivate",get:function(){return!0}}]),a}();b.exports=f},{}],7:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c>>a&1)},a.prototype.setBit=function(){},a.prototype.toString=function(){return this.name},e(a,[{key:"createInstantInvite",get:function(){return this.getBit(0)},set:function(a){this.setBit(0,a)}},{key:"banMembers",get:function(){return this.getBit(1)},set:function(a){this.setBit(1,a)}},{key:"kickMembers",get:function(){return this.getBit(2)},set:function(a){this.setBit(2,a)}},{key:"manageRoles",get:function(){return this.getBit(3)},set:function(a){this.setBit(3,a)}},{key:"manageChannels",get:function(){return this.getBit(4)},set:function(a){this.setBit(4,a);
+}},{key:"manageServer",get:function(){return this.getBit(5)},set:function(a){this.setBit(5,a)}},{key:"readMessages",get:function(){return this.getBit(10)},set:function(a){this.setBit(10,a)}},{key:"sendMessages",get:function(){return this.getBit(11)},set:function(a){this.setBit(11,a)}},{key:"sendTTSMessages",get:function(){return this.getBit(12)},set:function(a){this.setBit(12,a)}},{key:"manageMessages",get:function(){return this.getBit(13)},set:function(a){this.setBit(13,a)}},{key:"embedLinks",get:function(){return this.getBit(14)},set:function(a){this.setBit(14,a)}},{key:"attachFiles",get:function(){return this.getBit(15)},set:function(a){this.setBit(15,a)}},{key:"readMessageHistory",get:function(){return this.getBit(16)},set:function(a){this.setBit(16,a)}},{key:"mentionEveryone",get:function(){return this.getBit(17)},set:function(a){this.setBit(17,a)}},{key:"voiceConnect",get:function(){return this.getBit(20)},set:function(a){this.setBit(20,a)}},{key:"voiceSpeak",get:function(){return this.getBit(21)},set:function(a){this.setBit(21,a)}},{key:"voiceMuteMembers",get:function(){return this.getBit(22)},set:function(a){this.setBit(22,a)}},{key:"voiceDeafenMembers",get:function(){return this.getBit(23)},set:function(a){this.setBit(23,a)}},{key:"voiceMoveMembers",get:function(){return this.getBit(24)},set:function(a){this.setBit(24,a)}},{key:"voiceUseVoiceActivation",get:function(){return this.getBit(25)},set:function(a){this.setBit(25,a)}}]),a}();b.exports=f},{}],8:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c=e.length)break;i=e[h++]}else{if(h=e.next(),h.done)break;i=h.value}var j=i;this.roles.push(new f(j,this))}}return a.prototype.permissionsOf=function(a){var b=this.server.getMember("id",a.id);return b?b.permissionsIn(this):null},a.prototype.equals=function(a){return a&&a.id===this.id},a.prototype.addMessage=function(a){return this.messages.length>1e3&&this.messages.splice(0,1),this.getMessage("id",a.id)||this.messages.push(a),this.getMessage("id",a.id)},a.prototype.getMessage=function(a,b){for(var c=this.messages,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;if(g[a]===b)return g}return null},a.prototype.toString=function(){return"<#"+this.id+">"},e(a,[{key:"permissionOverwrites",get:function(){return this.roles}},{key:"permissions",get:function(){return this.roles}},{key:"client",get:function(){return this.server.client}},{key:"isPrivate",get:function(){return!1}},{key:"users",get:function(){return this.server.members}},{key:"members",get:function(){return this.server.members}}]),a}();b.exports=g},{"./ChannelPermissions.js":1}],9:[function(a,b,c){"use strict";var d=(a("superagent"),a("./Endpoints.js")),e=a("./Client.js"),f={Endpoints:d,Client:e};f.patchStrings=function(){function a(a,b){Object.defineProperty(String.prototype,a,{get:function(){return b+this+b}})}a("bold","**"),a("underline","__"),a("strike","~~"),a("code","`"),a("codeblock","```"),a("newline","\n"),Object.defineProperty(String.prototype,"italic",{get:function(){return"*"+this+"*"}})},b.exports=f},{"./Client.js":2,"./Endpoints.js":3,superagent:15}],10:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;if(g.id===b)return!0}return!1},e(a,[{key:"sender",get:function(){return this.author}},{key:"isPrivate",get:function(){return this.channel.isPrivate}}]),a}());b.exports=f},{"./PMChannel.js":6}],12:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c=e.length)break;i=e[h++]}else{if(h=e.next(),h.done)break;i=h.value}var j=i;this.roles.push(new f(j))}if(!b.members)return void(b.members=[c.user]);for(var k=b.members,l=Array.isArray(k),m=0,k=l?k:k[Symbol.iterator]();;){var n;if(l){if(m>=k.length)break;n=k[m++]}else{if(m=k.next(),m.done)break;n=m.value}var o=n;o.user&&this.addMember(c.addUser(o.user),o.roles)}}return a.prototype.getRole=function(a){for(var b=this.roles,c=Array.isArray(b),d=0,b=c?b:b[Symbol.iterator]();;){var e;if(c){if(d>=b.length)break;e=b[d++]}else{if(d=b.next(),d.done)break;e=d.value}var f=e;if(f.id===a)return f}return null},a.prototype.updateRole=function(a){var b=this.getRole(a.id);if(b){var c=this.roles.indexOf(b);return this.roles[c]=new f(a),this.roles[c]}return!1},a.prototype.removeRole=function(a){for(var b in this.roles)this.roles[b].id===a&&this.roles.splice(b,1);for(var c=this.members,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;for(var b in g.rawRoles)g.rawRoles[b]===a&&g.rawRoles.splice(b,1)}},a.prototype.getChannel=function(a,b){for(var c=this.channels,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;if(g[a]===b)return g}return null},a.prototype.getMember=function(a,b){for(var c=this.members,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;if(g[a]===b)return g}return null},a.prototype.removeMember=function(a,b){for(var c=this.members,d=Array.isArray(c),e=0,c=d?c:c[Symbol.iterator]();;){var f;if(d){if(e>=c.length)break;f=c[e++]}else{if(e=c.next(),e.done)break;f=e.value}var g=f;if(g[a]===b)return this.members.splice(a,1),g}return!1},a.prototype.addChannel=function(a){return this.getChannel("id",a.id)||this.channels.push(a),a},a.prototype.addMember=function(a,b){if(!this.getMember("id",a.id)){var c=new g(a,this,b);this.members.push(c)}return c},a.prototype.toString=function(){return this.name},a.prototype.equals=function(a){return a.id===this.id},e(a,[{key:"permissionGroups",get:function(){return this.roles}},{key:"permissions",get:function(){return this.roles}},{key:"iconURL",get:function(){return this.icon?"https://discordapp.com/api/guilds/"+this.id+"/icons/"+this.icon+".jpg":null}},{key:"afkChannel",get:function(){return this.afkChannelId?this.getChannel("id",this.afkChannelId):!1}},{key:"defaultChannel",get:function(){return this.getChannel("name","general")}},{key:"owner",get:function(){return this.client.getUser("id",this.ownerID)}},{key:"users",get:function(){return this.members}}]),a}();b.exports=h},{"./Member.js":5,"./ServerPermissions.js":7}],13:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c"},a.prototype.toString=function(){return this.mention()},a.prototype.equals=function(a){return a.id===this.id},a.prototype.equalsStrict=function(a){return a.id===this.id&&a.avatar===this.avatar&&a.username===this.username&&a.discriminator===this.discriminator},e(a,[{key:"avatarURL",get:function(){return this.avatar?"https://discordapp.com/api/users/"+this.id+"/avatars/"+this.avatar+".jpg":null}}]),a}();b.exports=f},{}],14:[function(a,b,c){},{}],15:[function(a,b,c){function d(){}function e(a){var b={}.toString.call(a);switch(b){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function f(a){return a===Object(a)}function g(a){if(!f(a))return a;var b=[];for(var c in a)null!=a[c]&&b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")}function h(a){for(var b,c,d={},e=a.split("&"),f=0,g=e.length;g>f;++f)c=e[f],b=c.split("="),d[decodeURIComponent(b[0])]=decodeURIComponent(b[1]);return d}function i(a){var b,c,d,e,f=a.split(/\r?\n/),g={};f.pop();for(var h=0,i=f.length;i>h;++h)c=f[h],b=c.indexOf(":"),d=c.slice(0,b).toLowerCase(),e=r(c.slice(b+1)),g[d]=e;return g}function j(a){return a.split(/ *; */).shift()}function k(a){return q(a.split(/ *; */),function(a,b){var c=b.split(/ *= */),d=c.shift(),e=c.shift();return d&&e&&(a[d]=e),a},{})}function l(a,b){b=b||{},this.req=a,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=i(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function m(a,b){var c=this;p.call(this),this._query=this._query||[],this.method=a,this.url=b,this.header={},this._header={},this.on("end",function(){var a=null,b=null;try{b=new l(c)}catch(d){return a=new Error("Parser is unable to parse the response"),a.parse=!0,a.original=d,c.callback(a)}if(c.emit("response",b),a)return c.callback(a,b);if(b.status>=200&&b.status<300)return c.callback(a,b);var e=new Error(b.statusText||"Unsuccessful HTTP response");e.original=a,e.response=b,e.status=b.status,c.callback(e,b)})}function n(a,b){return"function"==typeof b?new m("GET",a).end(b):1==arguments.length?new m("GET",a):new m(a,b)}var o,p=a("emitter"),q=a("reduce");o="undefined"!=typeof window?window:"undefined"!=typeof self?self:this,n.getXHR=function(){if(!(!o.XMLHttpRequest||o.location&&"file:"==o.location.protocol&&o.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(a){}return!1};var r="".trim?function(a){return a.trim()}:function(a){return a.replace(/(^\s*|\s*$)/g,"")};n.serializeObject=g,n.parseString=h,n.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},n.serialize={"application/x-www-form-urlencoded":g,"application/json":JSON.stringify},n.parse={"application/x-www-form-urlencoded":h,"application/json":JSON.parse},l.prototype.get=function(a){return this.header[a.toLowerCase()]},l.prototype.setHeaderProperties=function(a){var b=this.header["content-type"]||"";this.type=j(b);var c=k(b);for(var d in c)this[d]=c[d]},l.prototype.parse=function(a){return this.parser=a,this},l.prototype.parseBody=function(a){var b=this.parser||n.parse[this.type];return b&&a&&(a.length||a instanceof Object)?b(a):null},l.prototype.setStatusProperties=function(a){1223===a&&(a=204);var b=a/100|0;this.status=this.statusCode=a,this.statusType=b,this.info=1==b,this.ok=2==b,this.clientError=4==b,this.serverError=5==b,this.error=4==b||5==b?this.toError():!1,this.accepted=202==a,this.noContent=204==a,this.badRequest=400==a,this.unauthorized=401==a,this.notAcceptable=406==a,this.notFound=404==a,this.forbidden=403==a},l.prototype.toError=function(){var a=this.req,b=a.method,c=a.url,d="cannot "+b+" "+c+" ("+this.status+")",e=new Error(d);return e.status=this.status,e.method=b,e.url=c,e},n.Response=l,p(m.prototype),m.prototype.use=function(a){return a(this),this},m.prototype.timeout=function(a){return this._timeout=a,this},m.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},m.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0,this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this)},m.prototype.set=function(a,b){if(f(a)){for(var c in a)this.set(c,a[c]);return this}return this._header[a.toLowerCase()]=b,this.header[a]=b,this},m.prototype.unset=function(a){return delete this._header[a.toLowerCase()],delete this.header[a],this},m.prototype.getHeader=function(a){return this._header[a.toLowerCase()]},m.prototype.type=function(a){return this.set("Content-Type",n.types[a]||a),this},m.prototype.accept=function(a){return this.set("Accept",n.types[a]||a),this},m.prototype.auth=function(a,b){var c=btoa(a+":"+b);return this.set("Authorization","Basic "+c),this},m.prototype.query=function(a){return"string"!=typeof a&&(a=g(a)),a&&this._query.push(a),this},m.prototype.field=function(a,b){return this._formData||(this._formData=new o.FormData),this._formData.append(a,b),this},m.prototype.attach=function(a,b,c){return this._formData||(this._formData=new o.FormData),this._formData.append(a,b,c),this},m.prototype.send=function(a){var b=f(a),c=this.getHeader("Content-Type");if(b&&f(this._data))for(var d in a)this._data[d]=a[d];else"string"==typeof a?(c||this.type("form"),c=this.getHeader("Content-Type"),"application/x-www-form-urlencoded"==c?this._data=this._data?this._data+"&"+a:a:this._data=(this._data||"")+a):this._data=a;return!b||e(a)?this:(c||this.type("json"),this)},m.prototype.callback=function(a,b){var c=this._callback;this.clearTimeout(),c(a,b)},m.prototype.crossDomainError=function(){var a=new Error("Origin is not allowed by Access-Control-Allow-Origin");a.crossDomain=!0,this.callback(a)},m.prototype.timeoutError=function(){var a=this._timeout,b=new Error("timeout of "+a+"ms exceeded");b.timeout=a,this.callback(b)},m.prototype.withCredentials=function(){return this._withCredentials=!0,this},m.prototype.end=function(a){var b=this,c=this.xhr=n.getXHR(),f=this._query.join("&"),g=this._timeout,h=this._formData||this._data;this._callback=a||d,c.onreadystatechange=function(){if(4==c.readyState){var a;try{a=c.status}catch(d){a=0}if(0==a){if(b.timedout)return b.timeoutError();if(b.aborted)return;return b.crossDomainError()}b.emit("end")}};var i=function(a){a.total>0&&(a.percent=a.loaded/a.total*100),b.emit("progress",a)};this.hasListeners("progress")&&(c.onprogress=i);try{c.upload&&this.hasListeners("progress")&&(c.upload.onprogress=i)}catch(j){}if(g&&!this._timer&&(this._timer=setTimeout(function(){b.timedout=!0,b.abort()},g)),f&&(f=n.serializeObject(f),this.url+=~this.url.indexOf("?")?"&"+f:"?"+f),c.open(this.method,this.url,!0),this._withCredentials&&(c.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof h&&!e(h)){var k=this.getHeader("Content-Type"),l=n.serialize[k?k.split(";")[0]:""];l&&(h=l(h))}for(var m in this.header)null!=this.header[m]&&c.setRequestHeader(m,this.header[m]);return this.emit("request",this),c.send(h),this},m.prototype.then=function(a,b){return this.end(function(c,d){c?b(c):a(d)})},n.Request=m,n.get=function(a,b,c){var d=n("GET",a);return"function"==typeof b&&(c=b,b=null),b&&d.query(b),c&&d.end(c),d},n.head=function(a,b,c){var d=n("HEAD",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.del=function(a,b){var c=n("DELETE",a);return b&&c.end(b),c},n.patch=function(a,b,c){var d=n("PATCH",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.post=function(a,b,c){var d=n("POST",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.put=function(a,b,c){var d=n("PUT",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},b.exports=n},{emitter:16,reduce:17}],16:[function(a,b,c){function d(a){return a?e(a):void 0}function e(a){for(var b in d.prototype)a[b]=d.prototype[b];return a}b.exports=d,d.prototype.on=d.prototype.addEventListener=function(a,b){return this._callbacks=this._callbacks||{},(this._callbacks[a]=this._callbacks[a]||[]).push(b),this},d.prototype.once=function(a,b){function c(){d.off(a,c),b.apply(this,arguments)}var d=this;return this._callbacks=this._callbacks||{},c.fn=b,this.on(a,c),this},d.prototype.off=d.prototype.removeListener=d.prototype.removeAllListeners=d.prototype.removeEventListener=function(a,b){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var c=this._callbacks[a];if(!c)return this;if(1==arguments.length)return delete this._callbacks[a],this;for(var d,e=0;ed;++d)c[d].apply(this,b)}return this},d.prototype.listeners=function(a){return this._callbacks=this._callbacks||{},this._callbacks[a]||[]},d.prototype.hasListeners=function(a){return!!this.listeners(a).length}},{}],17:[function(a,b,c){b.exports=function(a,b,c){for(var d=0,e=a.length,f=3==arguments.length?c:a[d++];e>d;)f=b.call(null,f,a[d],++d,a);return f}},{}],18:[function(a,b,c){function d(a,b,c){var d;return d=b?new f(a,b):new f(a)}var e=function(){return this}(),f=e.WebSocket||e.MozWebSocket;b.exports=f?d:null,f&&(d.prototype=f.prototype)},{}],19:[function(a,b,c){b.exports=[{executables:{win32:["pol.exe"]},id:0,name:"FINAL FANTASY XI"},{executables:{win32:["ffxiv.exe","ffxiv_dx11.exe"]},id:1,name:"FINAL FANTASY XIV"},{executables:{win32:["Wow.exe","Wow-64.exe"]},id:3,name:"World of Warcraft"},{executables:{darwin:["LoLLauncher.app"],win32:["LolClient.exe","League of Legends.exe"]},id:4,name:"League of Legends"},{executables:{darwin:["Diablo%20III.app"],win32:["Diablo III.exe"]},id:5,name:"Diablo 3"},{executables:{darwin:["dota_osx.app"],win32:["dota2.exe"]},id:6,name:"DOTA 2"},{executables:{darwin:["Heroes.app"],win32:["Heroes of the Storm.exe","HeroesOfTheStorm_x64.exe","HeroesOfTheStorm.exe"]},id:7,name:"Heroes of the Storm"},{executables:{darwin:["Hearthstone.app"],win32:["Hearthstone.exe"]},id:8,name:"Hearthstone"},{executables:{win32:["csgo.exe"]},id:9,name:"Counter-Strike: Global Offensive"},{executables:{win32:["WorldOfTanks.exe"]},id:10,name:"World of Tanks"},{executables:{darwin:["gw2.app"],win32:["gw2.exe"]},id:11,name:"Guild Wars 2"},{executables:{win32:["dayz.exe"]},id:12,name:"Day Z"},{executables:{darwin:["starcraft%20ii.app"],win32:["starcraft ii.exe","SC2_x64.exe","SC2.exe"]},id:13,name:"Starcraft II"},{executables:{win32:["diablo.exe"]},id:14,name:"Diablo"},{executables:{win32:["diablo ii.exe"]},id:15,name:"Diablo 2"},{executables:{win32:["left4dead.exe"]},id:17,name:"Left 4 Dead"},{executables:{darwin:["minecraft.app"],win32:["minecraft.exe"]},id:18,name:"Minecraft"},{executables:{win32:["smite.exe"]},id:19,name:"Smite"},{executables:{win32:["bf4.exe"]},id:20,name:"Battlefield 4"},{executables:{win32:["AoK HD.exe","empires2.exe"]},id:101,name:"Age of Empire II"},{executables:{win32:["age3y.exe"]},id:102,name:"Age of Empire III"},{executables:{win32:["AlanWake.exe"]},id:104,name:"Alan Wake"},{executables:{win32:["alan_wakes_american_nightmare.exe"]},id:105,name:"Alan Wake's American Nightmare"},{executables:{win32:["AlienBreed2Assault.exe"]},id:106,name:"Alien Breed 2: Assault"},{executables:{win32:["Amnesia.exe"]},id:107,name:"Amnesia: The Dark Descent"},{executables:{win32:["UDK.exe"]},id:108,name:"Antichamber"},{executables:{win32:["ArcheAge.exe"]},id:109,name:"ArcheAge"},{executables:{win32:["arma3.exe"]},id:110,name:"Arma III"},{executables:{win32:["AC3SP.exe"]},id:111,name:"Assassin's Creed 3"},{executables:{win32:["Bastion.exe"]},id:112,name:"Bastion"},{executables:{win32:["BF2.exe"]},id:113,name:"Battlefield 2"},{executables:{win32:["bf3.exe"]},id:114,name:"Battlefield 3"},{executables:{win32:["Besiege.exe"]},id:116,name:"Besiege"},{executables:{win32:["Bioshock.exe"]},id:117,name:"Bioshock"},{executables:{win32:["Bioshock2.exe"]},id:118,name:"BioShock II"},{executables:{win32:["BioShockInfinite.exe"]},id:119,name:"BioShock Infinite"},{executables:{win32:["Borderlands2.exe"]},id:122,name:"Borderlands 2"},{executables:{win32:["braid.exe"]},id:123,name:"Braid"},{executables:{win32:["ShippingPC-StormGame.exe"]},id:124,name:"Bulletstorm"},{executables:{},id:125,name:"Cabal 2"},{executables:{win32:["CabalMain.exe"]},id:126,name:"Cabal Online"},{executables:{win32:["iw4mp.exe","iw4sp.exe"]},id:127,name:"Call of Duty: Modern Warfare 2"},{executables:{win32:["t6sp.exe"]},id:128,name:"Call of Duty: Black Ops"},{executables:{win32:["iw5mp.exe"]},id:129,name:"Call of Duty: Modern Warfare 3"},{executables:{win32:["RelicCOH.exe"]},id:132,name:"Company of Heroes"},{executables:{win32:["Crysis64.exe"]},id:135,name:"Crysis"},{executables:{win32:["Crysis2.exe"]},id:136,name:"Crysis 2"},{executables:{win32:["Crysis3.exe"]},id:137,name:"Crysis 3"},{executables:{win32:["Crysis.exe"]},id:138,name:"Crysis 4 "},{executables:{win32:["DATA.exe"]},id:140,name:"Dark Souls"},{executables:{win32:["DarkSoulsII.exe"]},id:141,name:"Dark Souls II"},{executables:{win32:["dfuw.exe"]},id:142,name:"Darkfall: Unholy Wars"},{executables:{win32:["DCGAME.exe"]},id:144,name:"DC Universe Online"},{executables:{win32:["DeadIslandGame.exe"]},id:145,name:"Dead Island"},{executables:{win32:["deadspace2.exe"]},id:146,name:"Dead Space 2"},{executables:{win32:["LOTDGame.exe"]},id:147,name:"Deadlight"},{executables:{win32:["dxhr.exe"]},id:148,name:"Deus Ex: Human Revolution"},{executables:{win32:["DeviMayCry4.exe"]},id:149,name:"Devil May Cry 4"},{executables:{win32:["DMC-DevilMayCry.exe"]},id:150,name:"DmC Devil May Cry"},{executables:{win32:["dirt2_game.exe"]},id:154,name:"DiRT 2"},{executables:{win32:["dirt3_game.exe"]},id:155,name:"DiRT 3"},{executables:{win32:["dota.exe"]},id:156,name:"DOTA"},{executables:{win32:["DoubleDragon.exe"]},id:158,name:"Double Dragon Neon"},{executables:{win32:["DragonAge2.exe"]},id:159,name:"Dragon Age II"},{executables:{win32:["DragonAgeInquisition.exe"]},id:160,name:"Dragon Age: Inquisition"},{executables:{win32:["daorigins.exe"]},id:161,name:"Dragon Age: Origins"},{executables:{win32:["DBXV.exe"]},id:162,name:"Dragon Ball XenoVerse"},{executables:{win32:["DukeForever.exe"]},id:163,name:"Duke Nukem Forever"},{executables:{darwin:["Dustforce.app"],win32:["dustforce.exe"]},id:164,name:"Dustforce"},{executables:{win32:["EliteDangerous32.exe"]},id:165,name:"Elite: Dangerous"},{executables:{win32:["exefile.exe"]},id:166,name:"Eve Online"},{executables:{win32:["eqgame.exe"]},id:167,name:"EverQuest"},{executables:{win32:["EverQuest2.exe"]},id:168,name:"EverQuest II"},{executables:{},id:169,name:"EverQuest Next"},{executables:{win32:["Engine.exe"]},id:170,name:"F.E.A.R."},{executables:{win32:["FEAR2.exe"]},id:171,name:"F.E.A.R. 2: Project Origin"},{executables:{win32:["fallout3.exe"]},id:172,name:"Fallout 3"},{executables:{win32:["FalloutNV.exe"]},id:174,name:"Fallout: New Vegas"},{executables:{win32:["farcry3.exe"]},id:175,name:"Far Cry 3"},{executables:{win32:["fifa15.exe"]},id:176,name:"FIFA 15"},{executables:{win32:["FTLGame.exe"]},id:180,name:"FTL: Faster Than Light"},{executables:{win32:["GTAIV.exe"]},id:181,name:"Grand Theft Auto 4"},{executables:{win32:["GTA5.exe"]},id:182,name:"Grand Theft Auto 5"},{executables:{win32:["Gw.exe"]},id:183,name:"Guild Wars"},{executables:{win32:["H1Z1.exe"]},id:186,name:"H1Z1"},{executables:{win32:["HL2HL2.exe","hl2.exe"]},id:188,name:"Half Life 2"},{executables:{win32:["HOMEFRONT.exe"]},id:195,name:"Homefront"},{executables:{win32:["invisibleinc.exe"]},id:196,name:"Invisible Inc."},{executables:{win32:["LANoire.exe"]},id:197,name:"L.A. Noire"},{executables:{win32:["Landmark64.exe"]},id:198,name:"Landmark"},{executables:{win32:["left4dead2.exe"]},id:201,name:"Left 4 Dead 2"},{executables:{win32:["lineage.exe"]},id:203,name:"Lineage"},{executables:{win32:["Magicka.exe"]},id:206,name:"Magicka"},{executables:{win32:["MapleStory.exe"]},id:208,name:"MapleStory"},{executables:{},id:209,name:"Mark of the Ninja"},{executables:{win32:["MassEffect.exe"]},id:210,name:"Mass Effect"},{executables:{win32:["MassEffect2.exe"]},id:211,name:"Mass Effect 2"},{executables:{win32:["MassEffect3Demo.exe"]},id:212,name:"Mass Effect 3"},{executables:{win32:["METAL GEAR RISING REVENGEANCE.exe"]},id:214,name:"Metal Gear Rising: Revengeance"},{executables:{win32:["metro2033.exe"]},id:215,name:"Metro 2033"},{executables:{win32:["MetroLL.exe"]},id:216,name:"Metro Last Light"},{executables:{win32:["MK10.exe"]},id:218,name:"Mortal Kombat X"},{executables:{win32:["speed.exe"]},id:219,name:"Need For Speed Most Wanted"},{executables:{},id:220,name:"Neverwinder"},{executables:{darwin:["Outlast.app"],win32:["OLGame.exe"]},id:221,name:"Outlast"},{executables:{win32:["PapersPlease.exe"]},id:222,name:"Papers, Please"},{executables:{win32:["payday_win32_release.exe"]},id:223,name:"PAYDAY"},{executables:{win32:["payday2_win32_release.exe"]},id:224,name:"PAYDAY2"},{executables:{win32:["PillarsOfEternity.exe"]},id:225,name:"Pillars of Eternity"},{executables:{win32:["PA.exe"]},id:226,name:"Planetary Annihilation"},{executables:{win32:["planetside2_x86.exe"]},id:227,name:"Planetside 2"},{executables:{win32:["hl2P.exe"]},id:228,name:"Portal"},{executables:{win32:["portal2.exe"]},id:229,name:"Portal 2"},{executables:{win32:["PrimalCarnageGame.exe"]},id:231,name:"Primal Cargnage"},{executables:{win32:["pCARS.exe"]},id:232,name:"Project Cars"},{executables:{win32:["RaceTheSun.exe"]},id:233,name:"Race The Sun"},{executables:{win32:["Rage.exe"]},id:234,name:"RAGE"},{executables:{win32:["ragexe.exe"]},id:235,name:"Ragnarok Online"},{executables:{win32:["rift.exe"]},id:236,name:"Rift"},{executables:{win32:["Rocksmith2014.exe"]},id:237,name:"Rocksmith 2014"},{executables:{win32:["SwiftKit-RS.exe","JagexLauncher.exe"]},id:238,name:"RuneScape"},{executables:{win32:["Shadowgrounds.exe"]},id:239,name:"Shadowgrounds"},{executables:{win32:["survivor.exe"]},id:240,name:"Shadowgrounds: Survivor"},{executables:{win32:["ShovelKnight.exe"]},id:241,name:"Shovel Knight"},{executables:{win32:["SimCity.exe"]},id:242,name:"SimCity"},{executables:{win32:["SporeApp.exe"]},id:245,name:"Spore"},{executables:{win32:["StarCitizen.exe"]},id:246,name:"Star Citizen"},{executables:{},id:247,name:"Star Trek Online"},{executables:{win32:["battlefront.exe"]},id:248,name:"Star Wars Battlefront"},{executables:{win32:["swtor.exe"]},id:249,name:"Star Wars: The Old Republic"},{executables:{win32:["starbound.exe","starbound_opengl.exe"]},id:250,name:"Starbound"},{executables:{win32:["starcraft.exe"]},id:251,name:"Starcraft"},{executables:{win32:["SSFIV.exe"]},id:253,name:"Ultra Street Fighter IV"},{executables:{win32:["superhexagon.exe"]},id:254,name:"Super Hexagon"},{executables:{win32:["swordandsworcery_pc.exe"]},id:255,name:"Superbrothers: Sword & Sworcery EP"},{executables:{win32:["hl2TF.exe"]},id:256,name:"Team Fortress 2"},{executables:{win32:["TERA.exe"]},id:258,name:"TERA"},{executables:{win32:["Terraria.exe"]},id:259,name:"Terraria"},{executables:{win32:["Bethesda.net_Launcher.exe"]},id:260,name:"The Elder Scrolls Online"},{executables:{win32:["TESV.exe"]},id:261,name:"The Elder Scrolls V: Skyrim"},{executables:{win32:["TheSecretWorld.exe"]},id:262,name:"The Secret World"},{executables:{win32:["TS3.exe","ts3w.exe"]},id:264,name:"The Sims 3"},{executables:{win32:["WALKINGDEAD101.EXE"]},id:265,name:"The Walking Dead"},{executables:{win32:["TheWalkingDead2.exe"]},id:266,name:"The Walking Dead Season Two"},{executables:{win32:["witcher3.exe"]},id:267,name:"The Witcher 3"},{executables:{win32:["Future Soldier.exe"]},id:268,name:"Tom Clancy's Ghost Recon: Future Solider"},{executables:{win32:["TombRaider.exe"]},id:269,name:"Tomb Raider (2013)"},{executables:{win32:["Torchlight.exe"]},id:271,name:"Torchlight"},{executables:{win32:["Torchlight2.exe"]},id:272,name:"Torchlight 2"},{executables:{win32:["Shogun2.exe"]},id:273,name:"Total War: Shogun 2"},{executables:{win32:["Transistor.exe"]},id:274,name:"Transistor"},{executables:{win32:["trine.exe"]},id:275,name:"Trine"},{executables:{win32:["trine2_32bit.exe"]},id:276,name:"Trine 2"},{executables:{win32:["UOKR.exe"]},id:277,name:"Ultima Online"},{executables:{win32:["aces.exe"]},id:279,name:"War Thunder"},{executables:{win32:["Warcraft III.exe","wc3.exe"]},id:281,name:"Warcraft 3: Reign of Chaos"},{executables:{win32:["Warcraft II BNE.exe"]},id:282,name:"Warcraft II"},{executables:{win32:["Warframe.x64.exe","Warframe.exe"]},id:283,name:"Warframe"},{executables:{win32:["watch_dogs.exe"]},id:284,name:"Watch Dogs"},{executables:{win32:["WildStar64.exe"]},id:285,name:"WildStar"},{executables:{win32:["XComGame.exe"]},id:288,name:"XCOM: Enemy Unknown"},{executables:{win32:["DFO.exe","dfo.exe"]},id:289,name:"Dungeon Fighter Online"},{executables:{win32:["aclauncher.exe","acclient.exe"]},id:290,name:"Asheron's Call"},{executables:{win32:["MapleStory2.exe"]},id:291,name:"MapleStory 2"},{executables:{win32:["ksp.exe"]},id:292,name:"Kerbal Space Program"},{executables:{win32:["PINBALL.EXE"]},id:293,name:"3D Pinball: Space Cadet"},{executables:{win32:["dave.exe"]},id:294,name:"Dangerous Dave"},{executables:{win32:["iwbtgbeta(slomo).exe","iwbtgbeta(fs).exe"]},
+id:295,name:"I Wanna Be The Guy"},{executables:{win32:["MechWarriorOnline.exe "]},id:296,name:"Mech Warrior Online"},{executables:{win32:["dontstarve_steam.exe"]},id:297,name:"Don't Starve"},{executables:{win32:["GalCiv3.exe"]},id:298,name:"Galactic Civilization 3"},{executables:{win32:["Risk of Rain.exe"]},id:299,name:"Risk of Rain"},{executables:{win32:["Binding_of_Isaac.exe","Isaac-ng.exe"]},id:300,name:"The Binding of Isaac"},{executables:{win32:["RustClient.exe"]},id:301,name:"Rust"},{executables:{win32:["Clicker Heroes.exe"]},id:302,name:"Clicker Heroes"},{executables:{win32:["Brawlhalla.exe"]},id:303,name:"Brawlhalla"},{executables:{win32:["TownOfSalem.exe"]},id:304,name:"Town of Salem"},{executables:{win32:["osu!.exe"]},id:305,name:"osu!"},{executables:{win32:["PathOfExileSteam.exe","PathOfExile.exe"]},id:306,name:"Path of Exile"},{executables:{win32:["Dolphin.exe"]},id:307,name:"Dolphin"},{executables:{win32:["RocketLeague.exe"]},id:308,name:"Rocket League"},{executables:{win32:["TJPP.exe"]},id:309,name:"Jackbox Party Pack"},{executables:{win32:["KFGame.exe"]},id:310,name:"Killing Floor 2"},{executables:{win32:["ShooterGame.exe"]},id:311,name:"Ark: Survival Evolved"},{executables:{win32:["LifeIsStrange.exe"]},id:312,name:"Life Is Strange"},{executables:{win32:["Client_tos.exe"]},id:313,name:"Tree of Savior"},{executables:{win32:["olliolli2.exe"]},id:314,name:"OlliOlli2"},{executables:{win32:["cw.exe"]},id:315,name:"Closers Dimension Conflict"},{executables:{win32:["ESSTEAM.exe","elsword.exe","x2.exe"]},id:316,name:"Elsword"},{executables:{win32:["ori.exe"]},id:317,name:"Ori and the Blind Forest"},{executables:{win32:["Skyforge.exe"]},id:318,name:"Skyforge"},{executables:{win32:["projectzomboid64.exe","projectzomboid32.exe"]},id:319,name:"Project Zomboid"},{executables:{win32:["From_The_Depths.exe"]},id:320,name:"The Depths"},{executables:{win32:["TheCrew.exe"]},id:321,name:"The Crew"},{executables:{win32:["MarvelHeroes2015.exe"]},id:322,name:"Marvel Heroes 2015"},{executables:{win32:["timeclickers.exe"]},id:324,name:"Time Clickers"},{executables:{win32:["eurotrucks2.exe"]},id:325,name:"Euro Truck Simulator 2"},{executables:{win32:["FarmingSimulator2015Game.exe"]},id:326,name:"Farming Simulator 15"},{executables:{win32:["strife.exe"]},id:327,name:"Strife"},{executables:{win32:["Awesomenauts.exe"]},id:328,name:"Awesomenauts"},{executables:{win32:["Dofus.exe"]},id:329,name:"Dofus"},{executables:{win32:["Boid.exe"]},id:330,name:"Boid"},{executables:{win32:["adventure-capitalist.exe"]},id:331,name:"AdVenture Capitalist"},{executables:{win32:["OrcsMustDie2.exe"]},id:332,name:"Orcs Must Die! 2"},{executables:{win32:["Mountain.exe"]},id:333,name:"Mountain"},{executables:{win32:["Valkyria.exe"]},id:335,name:"Valkyria Chronicles"},{executables:{win32:["ffxiiiimg.exe"]},id:336,name:"Final Fantasy XIII"},{executables:{win32:["TLR.exe"]},id:337,name:"The Last Remnant"},{executables:{win32:["Cities.exe"]},id:339,name:"Cities Skylines"},{executables:{win32:["worldofwarships.exe","WoWSLauncher.exe"]},id:341,name:"World of Warships"},{executables:{win32:["spacegame-Win64-shipping.exe"]},id:342,name:"Fractured Space"},{executables:{win32:["thespacegame.exe"]},id:343,name:"Ascent - The Space Game"},{executables:{win32:["DuckGame.exe"]},id:344,name:"Duck Game"},{executables:{win32:["PPSSPPWindows.exe"]},id:345,name:"PPSSPP"},{executables:{win32:["MBAA.exe"]},id:346,name:"Melty Blood Actress Again: Current Code"},{executables:{win32:["TheWolfAmongUs.exe"]},id:347,name:"The Wolf Among Us"},{executables:{win32:["SpaceEngineers.exe"]},id:348,name:"Space Engineers"},{executables:{win32:["Borderlands.exe"]},id:349,name:"Borderlands"},{executables:{win32:["100orange.exe"]},id:351,name:"100% Orange Juice"},{executables:{win32:["reflex.exe"]},id:354,name:"Reflex"},{executables:{win32:["pso2.exe"]},id:355,name:"Phantasy Star Online 2"},{executables:{win32:["AssettoCorsa.exe"]},id:356,name:"Assetto Corsa"},{executables:{win32:["iw3mp.exe","iw3sp.exe"]},id:357,name:"Call of Duty 4: Modern Warfare"},{executables:{win32:["WolfOldBlood_x64.exe"]},id:358,name:"Wolfenstein: The Old Blood"},{executables:{win32:["castle.exe"]},id:359,name:"Castle Crashers"},{executables:{win32:["vindictus.exe"]},id:360,name:"Vindictus"},{executables:{win32:["ShooterGame-Win32-Shipping.exe"]},id:361,name:"Dirty Bomb"},{executables:{win32:["BatmanAK.exe"]},id:362,name:"Batman Arkham Knight"},{executables:{win32:["drt.exe"]},id:363,name:"Dirt Rally"},{executables:{win32:["rFactor.exe"]},id:364,name:"rFactor"},{executables:{win32:["clonk.exe"]},id:365,name:"Clonk Rage"},{executables:{win32:["SRHK.exe"]},id:366,name:"Shadowrun: Hong Kong"},{executables:{win32:["Insurgency.exe"]},id:367,name:"Insurgency"},{executables:{win32:["StepMania.exe"]},id:368,name:"Step Mania"},{executables:{win32:["FirefallCLient.exe"]},id:369,name:"Firefall"},{executables:{win32:["mirrorsedge.exe"]},id:370,name:"Mirrors Edge"},{executables:{win32:["MgsGroundZeroes.exe"]},id:371,name:"Metal Gear Solid V: Ground Zeroes"},{executables:{win32:["mgsvtpp.exe"]},id:372,name:"Metal Gear Solid V: The Phantom Pain"},{executables:{win32:["tld.exe"]},id:373,name:"The Long Dark"},{executables:{win32:["TKOM.exe"]},id:374,name:"Take On Mars"},{executables:{win32:["robloxplayerlauncher.exe","Roblox.exe"]},id:375,name:"Roblox"},{executables:{win32:["eu4.exe"]},id:376,name:"Europa Universalis 4"},{executables:{win32:["APB.exe"]},id:377,name:"APB Reloaded"},{executables:{win32:["Robocraft.exe"]},id:378,name:"Robocraft"},{executables:{win32:["Unity.exe"]},id:379,name:"Unity"},{executables:{win32:["Simpsons.exe"]},id:380,name:"The Simpsons: Hit & Run"},{executables:{win32:["Dnlauncher.exe","DragonNest.exe"]},id:381,name:"Dragon Nest"},{executables:{win32:["Trove.exe"]},id:382,name:"Trove"},{executables:{win32:["EndlessLegend.exe"]},id:383,name:"Endless Legend"},{executables:{win32:["TurbineLauncher.exe","dndclient.exe"]},id:384,name:"Dungeons & Dragons Online"},{executables:{win32:["quakelive.exe","quakelive_steam.exe"]},id:385,name:"Quake Live"},{executables:{win32:["7DaysToDie.exe"]},id:386,name:"7DaysToDie"},{executables:{win32:["SpeedRunners.exe"]},id:387,name:"SpeedRunners"},{executables:{win32:["gamemd.exe"]},id:388,name:"Command & Conquer: Red Alert 2"},{executables:{win32:["generals.exe"]},id:389,name:"Command & Conquer Generals: Zero Hour"},{executables:{win32:["Oblivion.exe"]},id:390,name:"The Elder Scrolls 4: Oblivion"},{executables:{win32:["mgsi.exe"]},id:391,name:"Metal Gear Solid"},{executables:{win32:["EoCApp.exe"]},id:392,name:"Divinity - Original Sin"},{executables:{win32:["Torment.exe"]},id:393,name:"Planescape: Torment"},{executables:{win32:["HexPatch.exe"]},id:394,name:"Hex: Shards of Fate"},{executables:{win32:["NS3FB.exe"]},id:395,name:"Naruto Shippuden Ultimate Ninja Storm 3 Full Burst"},{executables:{win32:["NSUNSR.exe"]},id:396,name:"Naruto Shippuden Ultimate Ninja Storm Revolution"},{executables:{win32:["SaintsRowIV.exe"]},id:397,name:"Saints Row IV"},{executables:{win32:["Shadowrun.exe"]},id:398,name:"Shadowrun"},{executables:{win32:["DungeonoftheEndless.exe"]},id:399,name:"Dungeon of the Endless"},{executables:{win32:["Hon.exe"]},id:400,name:"Heroes of Newerth"},{executables:{win32:["mabinogi.exe"]},id:401,name:"Mabinogi"},{executables:{win32:["CoD2MP_s.exe","CoDSP_s.exe"]},id:402,name:"Call of Duty 2:"},{executables:{win32:["CoDWaWmp.exe","CoDWaw.exe"]},id:403,name:"Call of Duty: World at War"},{executables:{win32:["heroes.exe"]},id:404,name:"Mabinogi Heroes (Vindictus) "},{executables:{win32:["KanColleViewer.exe"]},id:405,name:"KanColle "},{executables:{win32:["cyphers.exe"]},id:406,name:"Cyphers"},{executables:{win32:["RelicCoH2.exe"]},id:407,name:"Company of Heroes 2"},{executables:{win32:["MJ.exe"]},id:408,name:"セガNET麻雀MJ"},{executables:{win32:["ge.exe"]},id:409,name:"Granado Espada"},{executables:{win32:["NovaRO.exe"]},id:410,name:"Nova Ragnarok Online"},{executables:{win32:["RivalsofAether.exe"]},id:411,name:"Rivals of Aether"},{executables:{win32:["bfh.exe"]},id:412,name:"Battlefield Hardline"},{executables:{win32:["GrowHome.exe"]},id:413,name:"Grow Home"},{executables:{win32:["patriots.exe"]},id:414,name:"Rise of Nations Extended"},{executables:{win32:["Railroads.exe"]},id:415,name:"Sid Meier's Railroads!"},{executables:{win32:["Empire.exe"]},id:416,name:"Empire: Total War"},{executables:{win32:["Napoleon.exe"]},id:417,name:"Napoleon: Total War"},{executables:{win32:["gta_sa.exe"]},id:418,name:"Grand Theft Auto: San Andreas"},{executables:{win32:["MadMax.exe"]},id:419,name:"Mad Max"},{executables:{win32:["Titanfall.exe"]},id:420,name:"Titanfall"},{executables:{win32:["age2_x1.exe"]},id:421,name:"Age of Empires II: The Conquerors"},{executables:{win32:["Rome2.exe"]},id:422,name:"Total War: ROME 2"},{executables:{win32:["ShadowOfMordor.exe"]},id:423,name:"Middle-earth: Shadow of Mordor"},{executables:{win32:["Subnautica.exe"]},id:424,name:"Subnautica"},{executables:{win32:["anno5.exe"]},id:425,name:"Anno 2070"},{executables:{win32:["carrier.exe"]},id:426,name:"Carrier Command Gaea Mission"},{executables:{win32:["DarksidersPC.exe"]},id:427,name:"Darksiders"},{executables:{win32:["Darksiders2.exe"]},id:428,name:"Darksiders 2"},{executables:{win32:["mudlet.exe"]},id:429,name:"Mudlet"},{executables:{win32:["DunDefLauncher.exe"]},id:430,name:"Dungeon Defenders II"},{executables:{win32:["hng.exe"]},id:431,name:"Heroes and Generals"},{executables:{win32:["WFTOGame.exe"]},id:432,name:"War of the Overworld"},{executables:{win32:["Talisman.exe"]},id:433,name:"Talisman: Digital Edition"},{executables:{win32:["limbo.exe"]},id:434,name:"Limbo"},{executables:{win32:["ibbobb.exe"]},id:435,name:"ibb & obb"},{executables:{win32:["BattleBlockTheater.exe"]},id:436,name:"BattleBlock Theater"},{executables:{win32:["iracinglauncher.exe","iracingsim.exe","iracingsim64.exe"]},id:437,name:"iRacing"},{executables:{win32:["CivilizationV_DX11.exe"]},id:438,name:"Civilization V"}]},{}]},{},[9])(9)});
\ No newline at end of file
diff --git a/web-dist/discord.min.js b/web-dist/discord.min.js
deleted file mode 100644
index 37ba4d200..000000000
--- a/web-dist/discord.min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Discord=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g]*>/g)||[])[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;a.push(h.substring(2,h.length-1))}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return a}b=d+l(b);var o=m();e.resolveDestination(a).then(j)["catch"](i)})}},{key:"createws",value:function(a){if(this.websocket)return!1;var b=this;this.websocket=new o(a),this.websocket.onopen=function(){b.trySendConnData()},this.websocket.onclose=function(){b.trigger("disconnected")},this.websocket.onmessage=function(a){var c=!1,d={};try{c=JSON.parse(a.data),d=c.d}catch(e){return void b.trigger("error",e,a)}switch(c.t){case"READY":b.debug("received ready packet"),b.user=b.addUser(d.user);var f=!0,g=!1,i=void 0;try{for(var j,l=d.guilds[Symbol.iterator]();!(f=(j=l.next()).done);f=!0)var m=j.value,n=b.addServer(m)}catch(e){g=!0,i=e}finally{try{!f&&l["return"]&&l["return"]()}finally{if(g)throw i}}var o=!0,p=!1,q=void 0;try{for(var r,s=d.private_channels[Symbol.iterator]();!(o=(r=s.next()).done);o=!0){var t=r.value;b.addPMChannel(t)}}catch(e){p=!0,q=e}finally{try{!o&&s["return"]&&s["return"]()}finally{if(p)throw q}}b.trigger("ready"),b.readyTime=Date.now(),b.debug("cached "+b.serverCache.length+" servers, "+b.channelCache.length+" channels, "+b.pmChannelCache.length+" PMs and "+b.userCache.length+" users."),b.state=3,setInterval(function(){b.keepAlive.apply(b)},d.heartbeat_interval);break;case"MESSAGE_CREATE":b.debug("received message");var u=[];d.mentions=d.mentions||[];var v=!0,w=!1,x=void 0;try{for(var y,z=d.mentions[Symbol.iterator]();!(v=(y=z.next()).done);v=!0){var A=y.value;u.push(b.addUser(A))}}catch(e){w=!0,x=e}finally{try{!v&&z["return"]&&z["return"]()}finally{if(w)throw x}}var B=b.getChannel("id",d.channel_id);if(B){var C=B.addMessage(new k(d,B,u,b.addUser(d.author)));b.trigger("message",C)}break;case"MESSAGE_DELETE":b.debug("message deleted");var B=b.getChannel("id",d.channel_id),D=B.getMessage("id",d.id);D?(b.trigger("messageDelete",B,D),B.messages.splice(B.messages.indexOf(D),1)):b.trigger("messageDelete",B);break;case"MESSAGE_UPDATE":b.debug("message updated");var B=b.getChannel("id",d.channel_id),E=B.getMessage("id",d.id);if(E){var F={};for(var G in E)F[G]=E[G];for(var G in d)F[G]=d[G];var u=[],H=!0,I=!1,J=void 0;try{for(var K,L=F.mentions[Symbol.iterator]();!(H=(K=L.next()).done);H=!0){var A=K.value;u.push(b.addUser(A))}}catch(e){I=!0,J=e}finally{try{!H&&L["return"]&&L["return"]()}finally{if(I)throw J}}var M=new k(F,B,u,E.author);b.trigger("messageUpdate",M,E),B.messages[B.messages.indexOf(E)]=M}break;case"GUILD_DELETE":var n=b.getServer("id",d.id);n&&(b.serverCache.splice(b.serverCache.indexOf(n),1),b.trigger("serverDelete",n));break;case"CHANNEL_DELETE":var B=b.getChannel("id",d.id);if(B){var n=B.server;n&&n.channels.splice(n.channels.indexOf(B),1),b.trigger("channelDelete",B),b.serverCache.splice(b.serverCache.indexOf(B),1)}break;case"GUILD_CREATE":var n=b.getServer("id",d.id);if(n||(n=b.addServer(d)),b.serverCreateListener.get(d.id)){var N=b.serverCreateListener.get(d.id);N[0](n),N[1](null,n),b.serverCreateListener["delete"](d.id)}b.trigger("serverCreate",n);break;case"CHANNEL_CREATE":var B=b.getChannel("id",d.id);if(!B){var O=b.addChannel(d,d.guild_id),P=b.getServer("id",d.guild_id);P&&P.addChannel(O),b.trigger("channelCreate",O)}break;case"GUILD_MEMBER_ADD":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)||n.members.push(Q),b.trigger("serverNewMember",Q)}break;case"GUILD_MEMBER_REMOVE":var n=b.getServer("id",d.guild_id);if(n){var Q=b.addUser(d.user);~n.members.indexOf(Q)&&n.members.splice(n.members.indexOf(Q),1),b.trigger("serverRemoveMember",Q)}break;case"USER_UPDATE":if(b.user&&d.id===b.user.id){var R=new h(d);b.trigger("userUpdate",R,b.user),~b.userCache.indexOf(b.user)&&(b.userCache[b.userCache.indexOf(b.user)]=R),b.user=R}break;case"PRESENCE_UPDATE":var S=b.getUser("id",d.user.id);if(S){var T=new h(d.user);T.equalsStrict(S)?b.trigger("presence",{user:S,status:d.status,server:b.getServer("id",d.guild_id),gameId:d.game_id}):(b.trigger("userUpdate",S,T),b.userCache[b.userCache.indexOf(S)]=T)}break;default:b.debug("received unknown packet"),b.trigger("unknown",c)}}}},{key:"addUser",value:function(a){return this.getUser("id",a.id)||this.userCache.push(new h(a)),this.getUser("id",a.id)}},{key:"addChannel",value:function(a,b){return this.getChannel("id",a.id)||this.channelCache.push(new j(a,this.getServer("id",b))),this.getChannel("id",a.id)}},{key:"addPMChannel",value:function(a){return this.getPMChannel("id",a.id)||this.pmChannelCache.push(new m(a,this)),this.getPMChannel("id",a.id)}},{key:"addServer",value:function(a){var b=this.getServer("id",a.id);if(!b&&(b=new i(a,this),this.serverCache.push(b),a.channels)){var c=!0,d=!1,e=void 0;try{for(var f,g=a.channels[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;b.channels.push(this.addChannel(h,b.id))}}catch(j){d=!0,e=j}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}}return b}},{key:"getUser",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.userCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.channelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return this.getPMChannel(a,b)}},{key:"getPMChannel",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.pmChannelCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"getServer",value:function(a,b){var c=!0,d=!1,e=void 0;try{for(var f,g=this.serverCache[Symbol.iterator]();!(c=(f=g.next()).done);c=!0){var h=f.value;if(h[a]===b)return h}}catch(i){d=!0,e=i}finally{try{!c&&g["return"]&&g["return"]()}finally{if(d)throw e}}return null}},{key:"trySendConnData",value:function(){if(this.token&&!this.alreadySentData){this.alreadySentData=!0;var a={op:2,d:{token:this.token,v:2,properties:{$os:"discord.js",$browser:"discord.js",$device:"discord.js",$referrer:"",$referring_domain:""}}};this.websocket.send(JSON.stringify(a))}}},{key:"resolveServerID",value:function(a){return a instanceof i?a.id:!isNaN(a)&&a.length&&17===a.length?a:void 0}},{key:"resolveDestination",value:function(a){var b=!1,c=this;return new Promise(function(d,e){if(a instanceof i)b=a.id;else if(a instanceof j)b=a.id;else if(a instanceof k)b=a.channel.id;else if(a instanceof h){var f=!0,g=!1,l=void 0;try{for(var m,n=c.pmChannelCache[Symbol.iterator]();!(f=(m=n.next()).done);f=!0){var o=m.value;if(o.user.equals(a))return o.id}}catch(p){g=!0,l=p}finally{try{!f&&n["return"]&&n["return"]()}finally{if(g)throw l}}c.startPM(a).then(function(a){d(a.id)})["catch"](e)}else b=a;b&&d(b)})}},{key:"uptime",get:function(){return this.readyTime?Date.now()-this.readyTime:null}},{key:"ready",get:function(){return 3===this.state}},{key:"servers",get:function(){return this.serverCache}},{key:"channels",get:function(){return this.channelCache}},{key:"users",get:function(){return this.userCache}},{key:"PMChannels",get:function(){return this.pmChannelCache}},{key:"messages",get:function(){var a=[],b=!0,c=!1,d=void 0;try{for(var e,f=this.channelCache[Symbol.iterator]();!(b=(e=f.next()).done);b=!0){var g=e.value;a=a.concat(g.messages)}}catch(h){c=!0,d=h}finally{try{!b&&f["return"]&&f["return"]()}finally{if(c)throw d}}return a}}]),a}();b.exports=r},{"./Endpoints.js":2,"./PMChannel.js":3,"./channel.js":4,"./invite.js":6,"./message.js":7,"./server.js":8,"./user.js":9,fs:10,superagent:11,ws:14}],2:[function(a,b,c){"use strict";c.BASE_DOMAIN="discordapp.com",c.BASE="https://"+c.BASE_DOMAIN,c.WEBSOCKET_HUB="wss://"+c.BASE_DOMAIN+"/hub",c.API=c.BASE+"/api",c.AUTH=c.API+"/auth",c.LOGIN=c.AUTH+"/login",c.LOGOUT=c.AUTH+"/logout",c.USERS=c.API+"/users",c.SERVERS=c.API+"/guilds",c.CHANNELS=c.API+"/channels"},{}],3:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var e=function(){function a(a,b){for(var c=0;c"}},{key:"toString",value:function(){return this.mention()}},{key:"equals",value:function(a){return a.id===this.id}},{key:"equalsStrict",value:function(a){return a.id===this.id&&a.avatar===this.avatar&&a.username===this.username&&a.discriminator===this.discriminator}},{key:"avatarURL",get:function(){return this.avatar?"https://discordapp.com/api/users/"+this.id+"/avatars/"+this.avatar+".jpg":null}}]),a}();b.exports=f},{}],10:[function(a,b,c){},{}],11:[function(a,b,c){function d(){}function e(a){var b={}.toString.call(a);switch(b){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function f(a){return a===Object(a)}function g(a){if(!f(a))return a;var b=[];for(var c in a)null!=a[c]&&b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")}function h(a){for(var b,c,d={},e=a.split("&"),f=0,g=e.length;g>f;++f)c=e[f],b=c.split("="),d[decodeURIComponent(b[0])]=decodeURIComponent(b[1]);return d}function i(a){var b,c,d,e,f=a.split(/\r?\n/),g={};f.pop();for(var h=0,i=f.length;i>h;++h)c=f[h],b=c.indexOf(":"),d=c.slice(0,b).toLowerCase(),e=r(c.slice(b+1)),g[d]=e;return g}function j(a){return a.split(/ *; */).shift()}function k(a){return p(a.split(/ *; */),function(a,b){var c=b.split(/ *= */),d=c.shift(),e=c.shift();return d&&e&&(a[d]=e),a},{})}function l(a,b){b=b||{},this.req=a,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=i(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function m(a,b){var c=this;o.call(this),this._query=this._query||[],this.method=a,this.url=b,this.header={},this._header={},this.on("end",function(){var a=null,b=null;try{b=new l(c)}catch(d){return a=new Error("Parser is unable to parse the response"),a.parse=!0,a.original=d,c.callback(a)}if(c.emit("response",b),a)return c.callback(a,b);if(b.status>=200&&b.status<300)return c.callback(a,b);var e=new Error(b.statusText||"Unsuccessful HTTP response");e.original=a,e.response=b,e.status=b.status,c.callback(e,b)})}function n(a,b){return"function"==typeof b?new m("GET",a).end(b):1==arguments.length?new m("GET",a):new m(a,b)}var o=a("emitter"),p=a("reduce"),q="undefined"==typeof window?this||self:window;n.getXHR=function(){if(!(!q.XMLHttpRequest||q.location&&"file:"==q.location.protocol&&q.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(a){}return!1};var r="".trim?function(a){return a.trim()}:function(a){return a.replace(/(^\s*|\s*$)/g,"")};n.serializeObject=g,n.parseString=h,n.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},n.serialize={"application/x-www-form-urlencoded":g,"application/json":JSON.stringify},n.parse={"application/x-www-form-urlencoded":h,"application/json":JSON.parse},l.prototype.get=function(a){return this.header[a.toLowerCase()]},l.prototype.setHeaderProperties=function(a){var b=this.header["content-type"]||"";this.type=j(b);var c=k(b);for(var d in c)this[d]=c[d]},l.prototype.parseBody=function(a){var b=n.parse[this.type];return b&&a&&(a.length||a instanceof Object)?b(a):null},l.prototype.setStatusProperties=function(a){1223===a&&(a=204);var b=a/100|0;this.status=a,this.statusType=b,this.info=1==b,this.ok=2==b,this.clientError=4==b,this.serverError=5==b,this.error=4==b||5==b?this.toError():!1,this.accepted=202==a,this.noContent=204==a,this.badRequest=400==a,this.unauthorized=401==a,this.notAcceptable=406==a,this.notFound=404==a,this.forbidden=403==a},l.prototype.toError=function(){var a=this.req,b=a.method,c=a.url,d="cannot "+b+" "+c+" ("+this.status+")",e=new Error(d);return e.status=this.status,e.method=b,e.url=c,e},n.Response=l,o(m.prototype),m.prototype.use=function(a){return a(this),this},m.prototype.timeout=function(a){return this._timeout=a,this},m.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},m.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0,this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this)},m.prototype.set=function(a,b){if(f(a)){for(var c in a)this.set(c,a[c]);return this}return this._header[a.toLowerCase()]=b,this.header[a]=b,this},m.prototype.unset=function(a){return delete this._header[a.toLowerCase()],delete this.header[a],this},m.prototype.getHeader=function(a){return this._header[a.toLowerCase()]},m.prototype.type=function(a){return this.set("Content-Type",n.types[a]||a),this},m.prototype.accept=function(a){return this.set("Accept",n.types[a]||a),this},m.prototype.auth=function(a,b){var c=btoa(a+":"+b);return this.set("Authorization","Basic "+c),this},m.prototype.query=function(a){return"string"!=typeof a&&(a=g(a)),a&&this._query.push(a),this},m.prototype.field=function(a,b){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b),this},m.prototype.attach=function(a,b,c){return this._formData||(this._formData=new q.FormData),this._formData.append(a,b,c),this},m.prototype.send=function(a){var b=f(a),c=this.getHeader("Content-Type");if(b&&f(this._data))for(var d in a)this._data[d]=a[d];else"string"==typeof a?(c||this.type("form"),c=this.getHeader("Content-Type"),"application/x-www-form-urlencoded"==c?this._data=this._data?this._data+"&"+a:a:this._data=(this._data||"")+a):this._data=a;return!b||e(a)?this:(c||this.type("json"),this)},m.prototype.callback=function(a,b){var c=this._callback;this.clearTimeout(),c(a,b)},m.prototype.crossDomainError=function(){var a=new Error("Origin is not allowed by Access-Control-Allow-Origin");a.crossDomain=!0,this.callback(a)},m.prototype.timeoutError=function(){var a=this._timeout,b=new Error("timeout of "+a+"ms exceeded");b.timeout=a,this.callback(b)},m.prototype.withCredentials=function(){return this._withCredentials=!0,this},m.prototype.end=function(a){var b=this,c=this.xhr=n.getXHR(),f=this._query.join("&"),g=this._timeout,h=this._formData||this._data;this._callback=a||d,c.onreadystatechange=function(){if(4==c.readyState){var a;try{a=c.status}catch(d){a=0}if(0==a){if(b.timedout)return b.timeoutError();if(b.aborted)return;return b.crossDomainError()}b.emit("end")}};var i=function(a){a.total>0&&(a.percent=a.loaded/a.total*100),b.emit("progress",a)};this.hasListeners("progress")&&(c.onprogress=i);try{c.upload&&this.hasListeners("progress")&&(c.upload.onprogress=i)}catch(j){}if(g&&!this._timer&&(this._timer=setTimeout(function(){b.timedout=!0,b.abort()},g)),f&&(f=n.serializeObject(f),this.url+=~this.url.indexOf("?")?"&"+f:"?"+f),c.open(this.method,this.url,!0),this._withCredentials&&(c.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof h&&!e(h)){var k=this.getHeader("Content-Type"),l=n.serialize[k?k.split(";")[0]:""];l&&(h=l(h))}for(var m in this.header)null!=this.header[m]&&c.setRequestHeader(m,this.header[m]);return this.emit("request",this),
-c.send(h),this},m.prototype.then=function(a,b){return this.end(function(c,d){c?b(c):a(d)})},n.Request=m,n.get=function(a,b,c){var d=n("GET",a);return"function"==typeof b&&(c=b,b=null),b&&d.query(b),c&&d.end(c),d},n.head=function(a,b,c){var d=n("HEAD",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.del=function(a,b){var c=n("DELETE",a);return b&&c.end(b),c},n.patch=function(a,b,c){var d=n("PATCH",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.post=function(a,b,c){var d=n("POST",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},n.put=function(a,b,c){var d=n("PUT",a);return"function"==typeof b&&(c=b,b=null),b&&d.send(b),c&&d.end(c),d},b.exports=n},{emitter:12,reduce:13}],12:[function(a,b,c){function d(a){return a?e(a):void 0}function e(a){for(var b in d.prototype)a[b]=d.prototype[b];return a}b.exports=d,d.prototype.on=d.prototype.addEventListener=function(a,b){return this._callbacks=this._callbacks||{},(this._callbacks[a]=this._callbacks[a]||[]).push(b),this},d.prototype.once=function(a,b){function c(){d.off(a,c),b.apply(this,arguments)}var d=this;return this._callbacks=this._callbacks||{},c.fn=b,this.on(a,c),this},d.prototype.off=d.prototype.removeListener=d.prototype.removeAllListeners=d.prototype.removeEventListener=function(a,b){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var c=this._callbacks[a];if(!c)return this;if(1==arguments.length)return delete this._callbacks[a],this;for(var d,e=0;ed;++d)c[d].apply(this,b)}return this},d.prototype.listeners=function(a){return this._callbacks=this._callbacks||{},this._callbacks[a]||[]},d.prototype.hasListeners=function(a){return!!this.listeners(a).length}},{}],13:[function(a,b,c){b.exports=function(a,b,c){for(var d=0,e=a.length,f=3==arguments.length?c:a[d++];e>d;)f=b.call(null,f,a[d],++d,a);return f}},{}],14:[function(a,b,c){function d(a,b,c){var d;return d=b?new f(a,b):new f(a)}var e=function(){return this}(),f=e.WebSocket||e.MozWebSocket;b.exports=f?d:null,f&&(d.prototype=f.prototype)},{}]},{},[5])(5)});
\ No newline at end of file