[tor-commits] [tor-messenger-build/master] Switch to Tor Browser 6.5

arlo at torproject.org arlo at torproject.org
Tue Jan 24 23:59:04 UTC 2017


commit 1eb04e3a93a72627cea0d3ffdcd1ad3fcd13fdd7
Author: Arlo Breault <arlolra at gmail.com>
Date:   Tue Jan 24 14:45:25 2017 -0800

    Switch to Tor Browser 6.5
    
     * Use the tor-browser-45.7.0esr-6.5-1-build1 tag on tor-browser
    
     * Use the THUNDERBIRD_45_7_0_RELEASE tag on comm-esr45
    
     * Update tor-browser to 6.5
    
     * Update tor-launcher to 0.2.10.3
---
 ChangeLog                                          |    6 +-
 .../0001-Set-Tor-Messenger-preferences.patch       |   20 +-
 ...0002-Trac-16489-Prevent-account-autologin.patch |    4 +-
 ...Support-Special-Characters-input-prompt-o.patch |    4 +-
 ...Better-error-reporting-for-failed-outgoin.patch |    6 +-
 .../0005-Trac-13312-OTR-over-Twitter-DMs.patch     |    4 +-
 ...-Fix-tab-strip-background-colour-on-OS-X..patch |    4 +-
 ...-XMPP-createConversation-should-handle-in.patch |    6 +-
 ...-Set-_userVCard-own-property-when-downloa.patch |   39 -
 .../0008-XMPP-in-band-registration.patch           |  396 +
 .../instantbird/0009-Remove-search-from-UI.patch   |   64 +
 .../0009-XMPP-in-band-registration.patch           |  396 -
 .../0010-Add-Tor-Messenger-branding.patch          | 5134 +++++++++++
 .../instantbird/0010-Remove-search-from-UI.patch   |   64 -
 projects/instantbird/0011-Account-picture.patch    |   26 +
 .../0011-Add-Tor-Messenger-branding.patch          | 5134 -----------
 projects/instantbird/0012-Account-picture.patch    |   26 -
 .../0012-Modify-protocol-defaults.patch            |   48 +
 .../instantbird/0013-Modify-IRC-defaults.patch     |   65 +
 .../0013-Modify-protocol-defaults.patch            |   48 -
 .../instantbird/0014-Modify-IRC-defaults.patch     |   65 -
 projects/instantbird/0014-Modify-themes.patch      |   78 +
 .../instantbird/0015-Modify-XMPP-defaults.patch    |   48 +
 projects/instantbird/0015-Modify-themes.patch      |   78 -
 .../instantbird/0016-Modify-XMPP-defaults.patch    |   48 -
 projects/instantbird/0016-Remove-logging-UI.patch  |   43 +
 projects/instantbird/0017-Cert-override.patch      |   64 +
 projects/instantbird/0017-Remove-logging-UI.patch  |   43 -
 projects/instantbird/0018-Cert-override.patch      |   64 -
 .../0018-Display-all-traffic-over-Tor.patch        |   38 +
 .../0019-Display-all-traffic-over-Tor.patch        |   38 -
 .../instantbird/0019-Trac-17480-Content-sink.patch |  111 +
 .../0020-SASL-ECDSA-NIST256P-CHALLENGE.patch       | 8919 ++++++++++++++++++++
 .../instantbird/0020-Trac-17480-Content-sink.patch |  111 -
 ...-msg-is-not-defined-error-in-irc.js-chang.patch |   29 +
 .../0021-SASL-ECDSA-NIST256P-CHALLENGE.patch       | 8919 --------------------
 ...-msg-is-not-defined-error-in-irc.js-chang.patch |   29 -
 ...Contact-list-entries-should-adapt-their-h.patch |  322 +
 ...1187281-Only-show-close-button-on-Windows.patch |   25 +
 ...Contact-list-entries-should-adapt-their-h.patch |  322 -
 ...1187281-Only-show-close-button-on-Windows.patch |   25 -
 ...-Remove-old-Yahoo-Messenger-support.-r-al.patch | 2398 ++++++
 ...-Remove-old-Yahoo-Messenger-support.-r-al.patch | 2398 ------
 ...-Use-built-in-functions-instead-of-an-svg.patch |   57 +
 ...-Add-a-pref-to-disable-JavaScript-in-brow.patch |   52 +
 ...-Use-built-in-functions-instead-of-an-svg.patch |   57 -
 ...-Add-a-pref-to-disable-JavaScript-in-brow.patch |   52 -
 projects/instantbird/config                        |   39 +-
 ...0001-Trac-19910-Prevents-STARTTLS-in-XMPP.patch |    2 +-
 .../mozilla/0002-Trac-16475-Block-flash-too.patch  |    2 +-
 ...Avoid-the-need-to-download-the-font-Osaka.patch |    4 +-
 ...Update-OS-X-toolchain-to-work-with-ESR-45.patch |    2 +-
 projects/mozilla/0005-OSX-package-as-tar.bz2.patch |    2 +-
 projects/mozilla/0006-Updater-fixups-for-TM.patch  |    2 +-
 ...ing-exceptions-even-w-inPrivateBrowsingMo.patch |    2 +-
 projects/mozilla/config                            |    2 +-
 projects/tor-browser/config                        |    2 +-
 ...emove-special-handling-for-Instantbird-Th.patch |   71 -
 ...-Set-CurProcD-for-Thunderbird-Instantbird.patch |   42 -
 projects/tor-launcher/build                        |    2 -
 projects/tor-launcher/config                       |    4 +-
 rbm.conf                                           |    2 +-
 tools/update-responses/config.yml                  |    2 +-
 63 files changed, 17977 insertions(+), 18132 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a84147b..decc29e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
-Tor Messenger 0.3.0b3 --
+Tor Messenger 0.4.0b1 --
  * All Platforms
+   * Use the tor-browser-45.7.0esr-6.5-1-build1 tag on tor-browser
+   * Use the THUNDERBIRD_45_7_0_RELEASE tag on comm-esr45
+   * Update tor-browser to 6.5
+   * Update tor-launcher to 0.2.10.3
  * Windows
    * Fix automatic generation of complete MAR files
    * Trac 21231: Enable intl-api
diff --git a/projects/instantbird/0001-Set-Tor-Messenger-preferences.patch b/projects/instantbird/0001-Set-Tor-Messenger-preferences.patch
index 4843fbb..c3d47cf 100644
--- a/projects/instantbird/0001-Set-Tor-Messenger-preferences.patch
+++ b/projects/instantbird/0001-Set-Tor-Messenger-preferences.patch
@@ -1,14 +1,14 @@
-From 5f249d152ab95c0a71ff80cbb4c6b8d6acca2154 Mon Sep 17 00:00:00 2001
+From 3f6a583ee1ea833dbf46ebc957917993a4736946 Mon Sep 17 00:00:00 2001
 From: Sukhbir Singh <sukhbir at torproject.org>
 Date: Mon, 10 Oct 2016 19:48:41 -0700
-Subject: [PATCH 01/27] Set Tor Messenger preferences
+Subject: [PATCH 01/26] Set Tor Messenger preferences
 
 ---
- im/app/profile/all-instantbird.js | 427 ++++++++++++++++++++++++++++++++++++--
- 1 file changed, 405 insertions(+), 22 deletions(-)
+ im/app/profile/all-instantbird.js | 425 ++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 403 insertions(+), 22 deletions(-)
 
 diff --git a/im/app/profile/all-instantbird.js b/im/app/profile/all-instantbird.js
-index b7a397017..45a6bec79 100644
+index b7a397017..7b91410f9 100644
 --- a/im/app/profile/all-instantbird.js
 +++ b/im/app/profile/all-instantbird.js
 @@ -1,3 +1,54 @@
@@ -183,7 +183,7 @@ index b7a397017..45a6bec79 100644
  
  // We have an Error Console menu item by default so let's display chrome errors
  pref("javascript.options.showInConsole", true);
-@@ -300,14 +362,335 @@ pref("browser.tabs.tabClipWidth", 140);
+@@ -300,14 +362,333 @@ pref("browser.tabs.tabClipWidth", 140);
  // 3  at the end of the tabstrip
  pref("browser.tabs.closeButtons", 1);
  
@@ -318,8 +318,6 @@ index b7a397017..45a6bec79 100644
 +pref("webgl.disable-fail-if-major-performance-caveat", true);
 +pref("dom.battery.enabled", false); // fingerprinting due to differing OS implementations
 +pref("dom.network.enabled",false); // fingerprinting due to differing OS implementations
-+pref("browser.display.max_font_attempts",10);
-+pref("browser.display.max_font_count",10);
 +pref("gfx.downloadable_fonts.fallback_delay", -1);
 +pref("general.appname.override", "Netscape");
 +pref("general.appversion.override", "5.0 (Windows)");
@@ -355,6 +353,7 @@ index b7a397017..45a6bec79 100644
 +// bug 18950 for more details.
 +pref("browser.reader.detectedFirstArticle", true);
 +pref("reader.parse-on-load.enabled", false);
++pref("privacy.use_utc_timezone", true);
 +
 +// Third party stuff
 +//pref("network.cookie.cookieBehavior", 1);  // TM
@@ -496,9 +495,8 @@ index b7a397017..45a6bec79 100644
 +pref("media.audio_data.enabled", false);
 +
 +// If true, remote JAR files will not be opened, regardless of content type
-+// Patch done by Jeff Gibat (iSEC). We bind it to the security slider but allow
-+// jar: in default mode.
-+pref("network.jar.block-remote-files", false);
++// Patch written by Jeff Gibat (iSEC).
++pref("network.jar.block-remote-files", true);
 +
 +// Enable TLS 1.1 and 1.2:
 +// https://trac.torproject.org/projects/tor/ticket/11253
diff --git a/projects/instantbird/0002-Trac-16489-Prevent-account-autologin.patch b/projects/instantbird/0002-Trac-16489-Prevent-account-autologin.patch
index 42676ec..01dec0c 100644
--- a/projects/instantbird/0002-Trac-16489-Prevent-account-autologin.patch
+++ b/projects/instantbird/0002-Trac-16489-Prevent-account-autologin.patch
@@ -1,7 +1,7 @@
-From 2097122d0d75213f13a2b69c45f4c1e91ea8264d Mon Sep 17 00:00:00 2001
+From 93d819d685fa99d607a71d370c8f45f2e99d5493 Mon Sep 17 00:00:00 2001
 From: Arlo Breault <arlolra at gmail.com>
 Date: Mon, 16 Nov 2015 20:37:53 -0800
-Subject: [PATCH 02/27] Trac 16489: Prevent account autologin
+Subject: [PATCH 02/26] Trac 16489: Prevent account autologin
 
 ---
  chat/components/src/imAccounts.js |  2 +-
diff --git a/projects/instantbird/0003-Trac-17896-Support-Special-Characters-input-prompt-o.patch b/projects/instantbird/0003-Trac-17896-Support-Special-Characters-input-prompt-o.patch
index 494672e..a8ecd56 100644
--- a/projects/instantbird/0003-Trac-17896-Support-Special-Characters-input-prompt-o.patch
+++ b/projects/instantbird/0003-Trac-17896-Support-Special-Characters-input-prompt-o.patch
@@ -1,7 +1,7 @@
-From 9156c76d9d9632392b2cc6069d5606525b0bf933 Mon Sep 17 00:00:00 2001
+From 2c8933abb0b1eec048c0205cf49729856e8c84e7 Mon Sep 17 00:00:00 2001
 From: aleth <aleth at instantbird.org>
 Date: Sat, 30 Jan 2016 20:56:38 +0100
-Subject: [PATCH 03/27] Trac 17896: Support "Special Characters" input prompt
+Subject: [PATCH 03/26] Trac 17896: Support "Special Characters" input prompt
  on OS X
 
  * Bug 1151784 - Add Edit menu to the conversation window on OS X. r=nhnt11,florian
diff --git a/projects/instantbird/0004-Trac-17494-Better-error-reporting-for-failed-outgoin.patch b/projects/instantbird/0004-Trac-17494-Better-error-reporting-for-failed-outgoin.patch
index 4138a9f..882602d 100644
--- a/projects/instantbird/0004-Trac-17494-Better-error-reporting-for-failed-outgoin.patch
+++ b/projects/instantbird/0004-Trac-17494-Better-error-reporting-for-failed-outgoin.patch
@@ -1,7 +1,7 @@
-From 266389c24e1e4eb65f0c40abe414d4b4471992d3 Mon Sep 17 00:00:00 2001
+From 71ced3fd410481505db5506ba0107cdd21438db7 Mon Sep 17 00:00:00 2001
 From: Arlo Breault <arlolra at gmail.com>
 Date: Tue, 2 Feb 2016 16:04:51 -0800
-Subject: [PATCH 04/27] Trac 17494: Better error reporting for failed outgoing
+Subject: [PATCH 04/26] Trac 17494: Better error reporting for failed outgoing
  messages
 
  * Bug 1245325 - Better error reporting for failed outgoing messages. r=clokep
@@ -35,7 +35,7 @@ index 7f824e534..293ab01d4 100644
  # LOCALIZATION NOTE (tooltip.*):
  #   These are the titles of lines of information that will appear in
 diff --git a/chat/protocols/xmpp/xmpp.jsm b/chat/protocols/xmpp/xmpp.jsm
-index 67cab7743..0022be35f 100644
+index 7c3fcd7e6..282575938 100644
 --- a/chat/protocols/xmpp/xmpp.jsm
 +++ b/chat/protocols/xmpp/xmpp.jsm
 @@ -679,11 +679,18 @@ var XMPPConversationPrototype = {
diff --git a/projects/instantbird/0005-Trac-13312-OTR-over-Twitter-DMs.patch b/projects/instantbird/0005-Trac-13312-OTR-over-Twitter-DMs.patch
index e7c829f..bd3d4b8 100644
--- a/projects/instantbird/0005-Trac-13312-OTR-over-Twitter-DMs.patch
+++ b/projects/instantbird/0005-Trac-13312-OTR-over-Twitter-DMs.patch
@@ -1,7 +1,7 @@
-From 298868aee8d58055e6e210a922cf55beec70db4f Mon Sep 17 00:00:00 2001
+From 41c6168d9c347a34c67249cdab427736df0c3930 Mon Sep 17 00:00:00 2001
 From: Arlo Breault <arlolra at gmail.com>
 Date: Tue, 15 Mar 2016 17:40:42 -0700
-Subject: [PATCH 05/27] Trac 13312: OTR over Twitter DMs
+Subject: [PATCH 05/26] Trac 13312: OTR over Twitter DMs
 
 ---
  chat/components/src/imConversations.js |   3 +-
diff --git a/projects/instantbird/0006-Bug-1218193-Fix-tab-strip-background-colour-on-OS-X..patch b/projects/instantbird/0006-Bug-1218193-Fix-tab-strip-background-colour-on-OS-X..patch
index 2391576..c47f16d 100644
--- a/projects/instantbird/0006-Bug-1218193-Fix-tab-strip-background-colour-on-OS-X..patch
+++ b/projects/instantbird/0006-Bug-1218193-Fix-tab-strip-background-colour-on-OS-X..patch
@@ -1,7 +1,7 @@
-From 6372d7ec1de855dd5ce01c732412e4882651e83b Mon Sep 17 00:00:00 2001
+From c632159066e0cdc81d7ac5b69e4d7fb1aea3922a Mon Sep 17 00:00:00 2001
 From: Nihanth Subramanya <nhnt11 at gmail.com>
 Date: Sun, 9 Oct 2016 21:53:04 -0700
-Subject: [PATCH 06/27] Bug 1218193 - Fix tab strip background colour on OS X.
+Subject: [PATCH 06/26] Bug 1218193 - Fix tab strip background colour on OS X.
  r=aleth
 
 ---
diff --git a/projects/instantbird/0007-Bug-1246431-XMPP-createConversation-should-handle-in.patch b/projects/instantbird/0007-Bug-1246431-XMPP-createConversation-should-handle-in.patch
index 691159a..a1a6cc9 100644
--- a/projects/instantbird/0007-Bug-1246431-XMPP-createConversation-should-handle-in.patch
+++ b/projects/instantbird/0007-Bug-1246431-XMPP-createConversation-should-handle-in.patch
@@ -1,7 +1,7 @@
-From 47cb0f9b3ca87aea8dcaf0e578f4fbeab6efb9c9 Mon Sep 17 00:00:00 2001
+From bb331ed68d8150a72ee30734891f02e824c08a6d Mon Sep 17 00:00:00 2001
 From: Arlo Breault <arlolra at gmail.com>
 Date: Sun, 9 Oct 2016 21:57:07 -0700
-Subject: [PATCH 07/27] Bug 1246431 - XMPP createConversation should handle
+Subject: [PATCH 07/26] Bug 1246431 - XMPP createConversation should handle
  incoming messages from the server properly. r=aleth
 
 ---
@@ -9,7 +9,7 @@ Subject: [PATCH 07/27] Bug 1246431 - XMPP createConversation should handle
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/chat/protocols/xmpp/xmpp.jsm b/chat/protocols/xmpp/xmpp.jsm
-index 0022be35f..4420a1d17 100644
+index 282575938..71f777009 100644
 --- a/chat/protocols/xmpp/xmpp.jsm
 +++ b/chat/protocols/xmpp/xmpp.jsm
 @@ -2108,7 +2108,7 @@ var XMPPAccountPrototype = {
diff --git a/projects/instantbird/0008-Bug-1298574-Set-_userVCard-own-property-when-downloa.patch b/projects/instantbird/0008-Bug-1298574-Set-_userVCard-own-property-when-downloa.patch
deleted file mode 100644
index ecdefbe..0000000
--- a/projects/instantbird/0008-Bug-1298574-Set-_userVCard-own-property-when-downloa.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 834f9254f3d0eb39c26c430fcefb6f661f2bc2e9 Mon Sep 17 00:00:00 2001
-From: Arlo Breault <arlolra at gmail.com>
-Date: Sun, 28 Aug 2016 08:57:41 -0700
-Subject: [PATCH 08/27] Bug 1298574 - Set _userVCard own property when
- downloading vCard fails. r=aleth
-
- * This prevents an infinite req / res cycle.
----
- chat/protocols/xmpp/xmpp.jsm | 14 ++++++++++++++
- 1 file changed, 14 insertions(+)
-
-diff --git a/chat/protocols/xmpp/xmpp.jsm b/chat/protocols/xmpp/xmpp.jsm
-index 4420a1d17..71f777009 100644
---- a/chat/protocols/xmpp/xmpp.jsm
-+++ b/chat/protocols/xmpp/xmpp.jsm
-@@ -2243,6 +2243,20 @@ var XMPPAccountPrototype = {
-                                  .replace(/.{74}/g, "$&\n");
-       }
-     }
-+    else {
-+      // Downloading the vCard failed.
-+      if (this.handleErrors({
-+          itemNotFound: () => false,  // OK, no vCard exists yet.
-+          default: () => true
-+        })(aStanza)) {
-+        this.WARN("Unexpected error retrieving the user's vcard, " +
-+          "so we won't attempt to set it either.");
-+        return;
-+      }
-+      // Set this so that we don't get into an infinite loop trying to download
-+      // the vcard again. The check in sendVCard is for hasOwnProperty.
-+      this._userVCard = null;
-+    }
-     this._sendVCard();
-   },
- 
--- 
-2.11.0
-
diff --git a/projects/instantbird/0008-XMPP-in-band-registration.patch b/projects/instantbird/0008-XMPP-in-band-registration.patch
new file mode 100644
index 0000000..c617e2c
--- /dev/null
+++ b/projects/instantbird/0008-XMPP-in-band-registration.patch
@@ -0,0 +1,396 @@
+From 5b90c85e4c5e3d7d49006ee299417d9ceeca62ac Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir at torproject.org>
+Date: Mon, 10 Oct 2016 18:42:25 -0700
+Subject: [PATCH 08/26] XMPP in-band registration
+
+---
+ chat/locales/en-US/xmpp.properties                 |   5 +
+ chat/protocols/xmpp/xmpp-session.jsm               |  78 +++++++++++
+ im/content/accountWizard.js                        |   8 ++
+ im/content/accountWizard.xul                       |   1 +
+ im/content/jar.mn                                  |   2 +
+ im/content/xmppRegister.js                         | 142 +++++++++++++++++++++
+ im/content/xmppRegister.xul                        |  27 ++++
+ .../en-US/chrome/instantbird/accountWizard.dtd     |   2 +
+ 8 files changed, 265 insertions(+)
+ create mode 100644 im/content/xmppRegister.js
+ create mode 100644 im/content/xmppRegister.xul
+
+diff --git a/chat/locales/en-US/xmpp.properties b/chat/locales/en-US/xmpp.properties
+index 293ab01d4..237d20c92 100644
+--- a/chat/locales/en-US/xmpp.properties
++++ b/chat/locales/en-US/xmpp.properties
+@@ -13,6 +13,9 @@ connection.initializingEncryption=Initializing encryption
+ connection.authenticating=Authenticating
+ connection.gettingResource=Getting resource
+ connection.downloadingRoster=Downloading contact list
++connection.registering=Registering new account
++connection.gettingRegistration=Getting registration form
++connection.onRegistrationSuccess=Account registered
+ 
+ # LOCALIZATION NOTE (connection.error.*)
+ #   These will show in the account manager if an error occurs during the
+@@ -33,6 +36,8 @@ connection.error.notSendingPasswordInClear=The server only supports authenticati
+ connection.error.authenticationFailure=Authentication failure
+ connection.error.notAuthorized=Not authorized (Did you enter the wrong password?)
+ connection.error.failedToGetAResource=Failed to get a resource
++connection.error.noRegistrationSupport=The server does not support in-band registration
++connection.error.registrationCancel=Registration canceled
+ 
+ 
+ # LOCALIZATION NOTE (conversation.error.notDelivered):
+diff --git a/chat/protocols/xmpp/xmpp-session.jsm b/chat/protocols/xmpp/xmpp-session.jsm
+index 24618ee0c..246ec2b7c 100644
+--- a/chat/protocols/xmpp/xmpp-session.jsm
++++ b/chat/protocols/xmpp/xmpp-session.jsm
+@@ -11,6 +11,8 @@ Cu.import("resource:///modules/socket.jsm");
+ Cu.import("resource:///modules/xmpp-xml.jsm");
+ Cu.import("resource:///modules/xmpp-authmechs.jsm");
+ 
++const registerWindow = "chrome://instantbird/content/xmppRegister.xul";
++
+ XPCOMUtils.defineLazyGetter(this, "_", () =>
+   l10nHelper("chrome://chat/locale/xmpp.properties")
+ );
+@@ -68,6 +70,7 @@ XMPPSession.prototype = {
+                               Stanza.node("ping", Stanza.NS.ping)),
+                     this.cancelDisconnectTimer, this);
+   },
++  nodes: {},
+   _lastReceiveTime: 0,
+   _lastSendTime: 0,
+   checkPingTimer(aJustSentSomething = false) {
+@@ -271,6 +274,69 @@ XMPPSession.prototype = {
+       this.onXmppStanza = this.stanzaListeners.startAuth;
+       this.onXmppStanza(aStanza);
+     },
++    onRegisterResponse: function(aStanza) {
++      let error = this._account.parseError(aStanza);
++      if (error) {
++        this.onError(null, aStanza.getElement(["error"]).innerText);
++        return;
++      }
++      if (aStanza.attributes["type"] == "result") {
++        this._account.reportConnecting(_("connection.onRegistrationSuccess"));
++        this._account.prefs.setBoolPref("register", false);
++        this._account.connect();
++      }
++      return;
++    },
++    startRegister: function(aStanza) {
++      // Some servers do not support in-band registration. In that case,
++      // complain and quit the registration process.
++      let error = this._account.parseError(aStanza);
++      if (error) {
++        this.onError(null, _("connection.error.noRegistrationSupport"));
++        return;
++      }
++
++      // Clear the existing elements from previous registrations.
++      for (let elem in this.nodes)
++        delete this.nodes[elem];
++
++      this._account.reportConnecting(_("connection.gettingRegistration"));
++      let registerStanza = aStanza.getChildrenByNS(Stanza.NS.register)[0];
++      // If we get registration data, show the form, else quit.
++      if (registerStanza.getElement(["x"])) {
++        this.nodes["username"] = this._jid.node;
++        registerStanza.wrappedJSObject = registerStanza;
++        let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"]
++                   .getService(Ci.nsIWindowWatcher);
++        let win = ww.openWindow(null, registerWindow, "",
++                                "centerscreen,chrome,modal,minimizable=no", registerStanza);
++      } else {
++        this.onError(null, _("connection.error.noRegistrationSupport"));
++        return;
++      }
++
++      // If the user cancelled the form, we should stop the registration.
++      if (this.nodes["cancel"]) {
++        this.onError(null, _("connection.error.registrationCancel"));
++        return;
++      }
++
++      let xml = '<?xml version="1.0"?>';
++      let fieldNodes = [];
++      for (let key in this.nodes) {
++        let node = Stanza.node("field", null, {"var": key});
++        let childNode = Stanza.node("value");
++        childNode.addText(this.nodes[key]);
++        node.addChild(childNode);
++        fieldNodes.push(node);
++      }
++      let registerResponse = Stanza.iq("set", null, this._domain,
++                                       Stanza.node("query", Stanza.NS.register, null,
++                                                   Stanza.node("x", Stanza.NS.xdata,
++                                                               {"type": "submit"}, fieldNodes)));
++      this.sendStanza(registerResponse);
++      this.onXmppStanza = this.stanzaListeners.onRegisterResponse;
++    },
+     startTLS: function(aStanza) {
+       if (aStanza.localName != "proceed") {
+         this._networkError(_("connection.error.failedToStartTLS"));
+@@ -283,6 +349,18 @@ XMPPSession.prototype = {
+       this.onXmppStanza = this.stanzaListeners.startAuth;
+     },
+     startAuth: function(aStanza) {
++      // If the user has requested for a new account, we try to perform
++      // in-band registration first (if the server supports it) and then
++      // we authenticate.
++      if (this._account.getBool("register")) {
++        this._account.reportConnecting(_("connection.registering"));
++        let register = Stanza.iq("get", null, null,
++                                 Stanza.node("query", Stanza.NS.register));
++        this.sendStanza(register);
++        this.onXmppStanza = this.stanzaListeners.startRegister;
++        return;
++      }
++
+       if (aStanza.localName != "features") {
+         this.ERROR("Unexpected stanza " + aStanza.localName + ", expected 'features'");
+         this._networkError(_("connection.error.incorrectResponse"));
+diff --git a/im/content/accountWizard.js b/im/content/accountWizard.js
+index ed3b8f0f7..7c26d0d6e 100644
+--- a/im/content/accountWizard.js
++++ b/im/content/accountWizard.js
+@@ -119,6 +119,12 @@ var accountWizard = {
+       return;
+     }
+ 
++    if (this.proto.id == "prpl-jabber") {
++      document.getElementById("registerXMPP").hidden = false;
++    } else {
++      document.getElementById("registerXMPP").hidden = true;
++    }
++
+     let bundle = document.getElementById("accountsBundle");
+     let usernameInfo;
+     let emptyText = this.proto.usernameEmptyText;
+@@ -424,6 +430,8 @@ var accountWizard = {
+       acc.alias = this.alias;
+     //FIXME: newMailNotification
+ 
++    acc.setBool("register", document.getElementById("registerXMPP").checked);
++
+     for (let i = 0; i < this.prefs.length; ++i) {
+       let option = this.prefs[i];
+       let opt = option.opt;
+diff --git a/im/content/accountWizard.xul b/im/content/accountWizard.xul
+index 9eb5352a6..759f42b38 100644
+--- a/im/content/accountWizard.xul
++++ b/im/content/accountWizard.xul
+@@ -65,6 +65,7 @@
+     <vbox id="userNameBox"/>
+     <separator/>
+     <description id="duplicateAccount" hidden="true">&accountUsernameDuplicate.label;</description>
++    <checkbox id="registerXMPP" label="&registerXMPP.label;" hidden="true" />
+   </wizardpage>
+ 
+   <wizardpage id="accountpassword" pageid="accountpassword" next="accountadvanced"
+diff --git a/im/content/jar.mn b/im/content/jar.mn
+index 98d9a09a9..20ea9dce7 100644
+--- a/im/content/jar.mn
++++ b/im/content/jar.mn
+@@ -61,6 +61,8 @@ instantbird.jar:
+ *	content/instantbird/viewlog.xul
+ 	content/instantbird/viewlog.js
+ 	content/instantbird/viewlog.css
++	content/instantbird/xmppRegister.xul
++	content/instantbird/xmppRegister.js
+ #ifdef XP_MACOSX
+ *	content/instantbird/hiddenWindow.xul
+ 	content/instantbird/menus-mac.xul
+diff --git a/im/content/xmppRegister.js b/im/content/xmppRegister.js
+new file mode 100644
+index 000000000..52852f045
+--- /dev/null
++++ b/im/content/xmppRegister.js
+@@ -0,0 +1,142 @@
++const { interfaces: Ci, utils: Cu, classes: Cc } = Components;
++
++Cu.import("resource:///modules/imXPCOMUtils.jsm");
++Cu.import("resource:///modules/xmpp-session.jsm");
++
++XPCOMUtils.defineLazyGetter(this, "_", function()
++  l10nHelper("chrome://branding/locale/brand.properties")
++);
++
++let registerAccount = {
++  createElement: function(aType, aID, aValue) {
++    let element = document.createElement(aType);
++    if (aID)
++      element.setAttribute("id", aID);
++    if (aValue)
++      element.setAttribute("value", aValue);
++    return element;
++  },
++
++  createRow: function() {
++    let row = document.createElement("row");
++    row.setAttribute("align", "baseline");
++    return row;
++  },
++
++  onLoad: function() {
++    document.documentElement.getButton("accept").disabled = true;
++
++    this.rows = document.getElementById("register-rows");
++    this.groupbox = document.getElementById("register-groupbox");
++
++    this.nodes = XMPPSession.prototype.nodes;
++    this.registerStanza = window.arguments[0].wrappedJSObject;
++    this.dataStanza = this.registerStanza.getElement(["x"]);
++
++    let instructions = this.dataStanza.getElement(["instructions"]);
++    if (instructions) {
++      let instructionLabel = this.createElement("caption");
++      instructionLabel.setAttribute("label", instructions.innerText);
++      this.groupbox.appendChild(instructionLabel);
++    }
++
++    let title = this.dataStanza.getElement(["title"]);
++    if (title)
++      document.title = title.innerText;
++    else
++      document.title = _("brandShortName");
++
++    for each (let ele in this.dataStanza.getElements(["field"])) {
++      let attrib = ele.attributes;
++      let fieldType = attrib["type"];
++      switch (fieldType) {
++
++        case "text-single":
++        case "text-private":
++          let textRow = this.createRow();
++          let textLabel = this.createElement("label", null,
++                                             ele.getElement(["required"]) ?
++                                             attrib["label"] + " *" : attrib["label"]);
++
++          let textBox = this.createElement("textbox", attrib["var"],
++                                           ele.getElement(["value"]) ?
++                                           ele.getElement(["value"]).innerText : "");
++
++          if (attrib["var"] == "username")
++            textBox.setAttribute("value", this.nodes["username"]);
++          if (attrib["var"] == "url")
++            textBox.setAttribute("readonly", "true");
++
++          if (fieldType == "text-private") {
++            textBox.setAttribute("type", "password");
++            textBox.setAttribute("oninput", "onInput(this);");
++          }
++
++          textRow.appendChild(textLabel);
++          textRow.appendChild(textBox);
++          this.rows.appendChild(textRow);
++          break;
++
++        case "fixed":
++          let fixedRow = this.createRow();
++          let fixedLabel = this.createElement("label", null, ele.getElement(["value"]).innerText);
++          fixedRow.appendChild(fixedLabel);
++          this.rows.appendChild(fixedRow);
++          break;
++      }
++    }
++
++    // Some forms have an OCR field. In that case, show the OCR image
++    // and provide input for the same.
++    let ocr = this.dataStanza.getElements(["field"]).find(e => e.attributes["var"] == "ocr");
++    if (ocr) {
++      let ocrRow = this.createRow();
++
++      let ocrImage = this.createElement("image");
++      ocrImage.setAttribute("src", "data:image/png;base64," + this.registerStanza.getElement(["data"]).innerText);
++
++      // OCR will always be a required entry.
++      let ocrLabel = this.createElement("label", null, ocr.attributes["label"] + " *");
++      let ocrInput = this.createElement("textbox", ocr.attributes["var"], null);
++
++      ocrRow.appendChild(ocrLabel);
++      this.rows.appendChild(ocrRow);
++
++      let ocrBox = document.createElement("hbox");
++      ocrBox.setAttribute("flex", "1");
++      let spacer = document.createElement("spacer");
++      spacer.setAttribute("flex", "1");
++
++      ocrBox.appendChild(ocrImage);
++      ocrBox.appendChild(spacer);
++      ocrBox.appendChild(ocrInput);
++      this.groupbox.appendChild(ocrBox);
++    }
++    // Set focus on the password field.
++    if (document.getElementById("password")) {
++      document.getElementById("password").focus();
++    }
++  },
++
++  onSave: function() {
++    for each (let elements in this.dataStanza.getElements(["field"])) {
++      if (elements.attributes["var"] != undefined) {
++        let variable = elements.attributes["var"];
++        if (document.getElementById(variable))
++          this.nodes[variable] = document.getElementById(variable).value;
++        else
++          this.nodes[variable] = elements.getElement(["value"]).innerText;
++      }
++    }
++    delete this.nodes["cancel"];
++  },
++
++  onCancel: function() {
++    // The form was cancelled so we quit the registration.
++    this.nodes["cancel"] = true;
++  },
++};
++
++function onInput(e) {
++  document.documentElement.getButton("accept").disabled = !e.value;
++}
+diff --git a/im/content/xmppRegister.xul b/im/content/xmppRegister.xul
+new file mode 100644
+index 000000000..e2bd36750
+--- /dev/null
++++ b/im/content/xmppRegister.xul
+@@ -0,0 +1,27 @@
++<?xml version="1.0" ?>
++<?xml-stylesheet href="chrome://global/skin/" type="text/css" ?>
++
++<dialog
++  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
++  id="registerDialog"
++  onload="registerAccount.onLoad()"
++  buttons="accept,cancel"
++  ondialogaccept="return registerAccount.onSave()"
++  ondialogcancel="registerAccount.onCancel()">
++
++  <script type="application/javascript" src="chrome://instantbird/content/xmppRegister.js" />
++
++  <groupbox id="register-groupbox" flex="1">
++
++    <grid flex="1">
++      <columns>
++        <column flex="1" />
++      </columns>
++
++      <rows id="register-rows" />
++
++    </grid>
++
++  </groupbox>
++
++</dialog>
+diff --git a/im/locales/en-US/chrome/instantbird/accountWizard.dtd b/im/locales/en-US/chrome/instantbird/accountWizard.dtd
+index 43d0f19e3..c46fb2f95 100644
+--- a/im/locales/en-US/chrome/instantbird/accountWizard.dtd
++++ b/im/locales/en-US/chrome/instantbird/accountWizard.dtd
+@@ -31,3 +31,5 @@
+ <!ENTITY accountSummaryTitle.label   "Summary">
+ <!ENTITY accountSummaryInfo.label    "A summary of the information you entered is displayed below. Please check it before the account is created.">
+ <!ENTITY accountSummary.connectAutomatically.label "Connect this account automatically.">
++
++<!ENTITY registerXMPP.label "Create this new account on the server">
+-- 
+2.11.0
+
diff --git a/projects/instantbird/0009-Remove-search-from-UI.patch b/projects/instantbird/0009-Remove-search-from-UI.patch
new file mode 100644
index 0000000..8165fee
--- /dev/null
+++ b/projects/instantbird/0009-Remove-search-from-UI.patch
@@ -0,0 +1,64 @@
+From beecf3b5d4a6f682eab932640068097a297ae943 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir at torproject.org>
+Date: Mon, 10 Oct 2016 18:47:48 -0700
+Subject: [PATCH 09/26] Remove search from UI
+
+---
+ im/content/nsContextMenu.js         | 18 +-----------------
+ im/content/preferences/advanced.xul | 11 -----------
+ 2 files changed, 1 insertion(+), 28 deletions(-)
+
+diff --git a/im/content/nsContextMenu.js b/im/content/nsContextMenu.js
+index 5261b793f..f667793be 100644
+--- a/im/content/nsContextMenu.js
++++ b/im/content/nsContextMenu.js
+@@ -468,23 +468,7 @@ nsContextMenu.prototype = {
+     if (selectedText.length > 15)
+       selectedText = selectedText.substr(0,15) + this.ellipsis;
+ 
+-    var engine = Services.search.defaultEngine;
+-    if (!engine)
+-      return false;
+-
+-    // format "Search <engine> for <selection>" string to show in menu
+-    var bundle = document.getElementById("bundle_instantbird");
+-    var menuLabel = bundle.getFormattedString("contextMenuSearchText",
+-                                              [engine.name,
+-                                               selectedText]);
+-    document.getElementById("context-searchselect").label = menuLabel;
+-    document.getElementById("context-searchselect").accessKey =
+-      bundle.getString("contextMenuSearchText.accesskey");
+-    menuLabel = bundle.getFormattedString("contextMenuSearchWith",
+-                                          [selectedText]);
+-    document.getElementById("context-searchselect-with").label = menuLabel;
+-
+-    return true;
++    return false;
+   },
+ 
+   // Returns true if anything is selected.
+diff --git a/im/content/preferences/advanced.xul b/im/content/preferences/advanced.xul
+index fad67c190..cfe2405ea 100644
+--- a/im/content/preferences/advanced.xul
++++ b/im/content/preferences/advanced.xul
+@@ -143,17 +143,6 @@
+                       preference="layout.spellcheckDefault"/>
+           </groupbox>
+ 
+-          <!-- Search engines -->
+-          <groupbox id="searchEnginesGroup" orient="horizontal" align="center">
+-            <caption label="&searchEnginesGroup.label;"/>
+-
+-            <description control="manageSearchEnginesButton"
+-                         flex="1">&searchEnginesDesc.label;</description>
+-            <button id="manageSearchEnginesButton" label="&searchEngines.label;"
+-                    accesskey="&searchEngines.accesskey;"
+-                    oncommand="gAdvancedPane.showSearchEngineManager();"/>
+-          </groupbox>
+-
+           <!-- Advanced Configuration -->
+           <groupbox>
+             <caption label="&configEditDesc.label;"/>
+-- 
+2.11.0
+
diff --git a/projects/instantbird/0009-XMPP-in-band-registration.patch b/projects/instantbird/0009-XMPP-in-band-registration.patch
deleted file mode 100644
index c1a3b5b..0000000
--- a/projects/instantbird/0009-XMPP-in-band-registration.patch
+++ /dev/null
@@ -1,396 +0,0 @@
-From 8ecb2062a225865364f01b702da30d2578931b9e Mon Sep 17 00:00:00 2001
-From: Sukhbir Singh <sukhbir at torproject.org>
-Date: Mon, 10 Oct 2016 18:42:25 -0700
-Subject: [PATCH 09/27] XMPP in-band registration
-
----
- chat/locales/en-US/xmpp.properties                 |   5 +
- chat/protocols/xmpp/xmpp-session.jsm               |  78 +++++++++++
- im/content/accountWizard.js                        |   8 ++
- im/content/accountWizard.xul                       |   1 +
- im/content/jar.mn                                  |   2 +
- im/content/xmppRegister.js                         | 142 +++++++++++++++++++++
- im/content/xmppRegister.xul                        |  27 ++++
- .../en-US/chrome/instantbird/accountWizard.dtd     |   2 +
- 8 files changed, 265 insertions(+)
- create mode 100644 im/content/xmppRegister.js
- create mode 100644 im/content/xmppRegister.xul
-
-diff --git a/chat/locales/en-US/xmpp.properties b/chat/locales/en-US/xmpp.properties
-index 293ab01d4..237d20c92 100644
---- a/chat/locales/en-US/xmpp.properties
-+++ b/chat/locales/en-US/xmpp.properties
-@@ -13,6 +13,9 @@ connection.initializingEncryption=Initializing encryption
- connection.authenticating=Authenticating
- connection.gettingResource=Getting resource
- connection.downloadingRoster=Downloading contact list
-+connection.registering=Registering new account
-+connection.gettingRegistration=Getting registration form
-+connection.onRegistrationSuccess=Account registered
- 
- # LOCALIZATION NOTE (connection.error.*)
- #   These will show in the account manager if an error occurs during the
-@@ -33,6 +36,8 @@ connection.error.notSendingPasswordInClear=The server only supports authenticati
- connection.error.authenticationFailure=Authentication failure
- connection.error.notAuthorized=Not authorized (Did you enter the wrong password?)
- connection.error.failedToGetAResource=Failed to get a resource
-+connection.error.noRegistrationSupport=The server does not support in-band registration
-+connection.error.registrationCancel=Registration canceled
- 
- 
- # LOCALIZATION NOTE (conversation.error.notDelivered):
-diff --git a/chat/protocols/xmpp/xmpp-session.jsm b/chat/protocols/xmpp/xmpp-session.jsm
-index 24618ee0c..246ec2b7c 100644
---- a/chat/protocols/xmpp/xmpp-session.jsm
-+++ b/chat/protocols/xmpp/xmpp-session.jsm
-@@ -11,6 +11,8 @@ Cu.import("resource:///modules/socket.jsm");
- Cu.import("resource:///modules/xmpp-xml.jsm");
- Cu.import("resource:///modules/xmpp-authmechs.jsm");
- 
-+const registerWindow = "chrome://instantbird/content/xmppRegister.xul";
-+
- XPCOMUtils.defineLazyGetter(this, "_", () =>
-   l10nHelper("chrome://chat/locale/xmpp.properties")
- );
-@@ -68,6 +70,7 @@ XMPPSession.prototype = {
-                               Stanza.node("ping", Stanza.NS.ping)),
-                     this.cancelDisconnectTimer, this);
-   },
-+  nodes: {},
-   _lastReceiveTime: 0,
-   _lastSendTime: 0,
-   checkPingTimer(aJustSentSomething = false) {
-@@ -271,6 +274,69 @@ XMPPSession.prototype = {
-       this.onXmppStanza = this.stanzaListeners.startAuth;
-       this.onXmppStanza(aStanza);
-     },
-+    onRegisterResponse: function(aStanza) {
-+      let error = this._account.parseError(aStanza);
-+      if (error) {
-+        this.onError(null, aStanza.getElement(["error"]).innerText);
-+        return;
-+      }
-+      if (aStanza.attributes["type"] == "result") {
-+        this._account.reportConnecting(_("connection.onRegistrationSuccess"));
-+        this._account.prefs.setBoolPref("register", false);
-+        this._account.connect();
-+      }
-+      return;
-+    },
-+    startRegister: function(aStanza) {
-+      // Some servers do not support in-band registration. In that case,
-+      // complain and quit the registration process.
-+      let error = this._account.parseError(aStanza);
-+      if (error) {
-+        this.onError(null, _("connection.error.noRegistrationSupport"));
-+        return;
-+      }
-+
-+      // Clear the existing elements from previous registrations.
-+      for (let elem in this.nodes)
-+        delete this.nodes[elem];
-+
-+      this._account.reportConnecting(_("connection.gettingRegistration"));
-+      let registerStanza = aStanza.getChildrenByNS(Stanza.NS.register)[0];
-+      // If we get registration data, show the form, else quit.
-+      if (registerStanza.getElement(["x"])) {
-+        this.nodes["username"] = this._jid.node;
-+        registerStanza.wrappedJSObject = registerStanza;
-+        let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"]
-+                   .getService(Ci.nsIWindowWatcher);
-+        let win = ww.openWindow(null, registerWindow, "",
-+                                "centerscreen,chrome,modal,minimizable=no", registerStanza);
-+      } else {
-+        this.onError(null, _("connection.error.noRegistrationSupport"));
-+        return;
-+      }
-+
-+      // If the user cancelled the form, we should stop the registration.
-+      if (this.nodes["cancel"]) {
-+        this.onError(null, _("connection.error.registrationCancel"));
-+        return;
-+      }
-+
-+      let xml = '<?xml version="1.0"?>';
-+      let fieldNodes = [];
-+      for (let key in this.nodes) {
-+        let node = Stanza.node("field", null, {"var": key});
-+        let childNode = Stanza.node("value");
-+        childNode.addText(this.nodes[key]);
-+        node.addChild(childNode);
-+        fieldNodes.push(node);
-+      }
-+      let registerResponse = Stanza.iq("set", null, this._domain,
-+                                       Stanza.node("query", Stanza.NS.register, null,
-+                                                   Stanza.node("x", Stanza.NS.xdata,
-+                                                               {"type": "submit"}, fieldNodes)));
-+      this.sendStanza(registerResponse);
-+      this.onXmppStanza = this.stanzaListeners.onRegisterResponse;
-+    },
-     startTLS: function(aStanza) {
-       if (aStanza.localName != "proceed") {
-         this._networkError(_("connection.error.failedToStartTLS"));
-@@ -283,6 +349,18 @@ XMPPSession.prototype = {
-       this.onXmppStanza = this.stanzaListeners.startAuth;
-     },
-     startAuth: function(aStanza) {
-+      // If the user has requested for a new account, we try to perform
-+      // in-band registration first (if the server supports it) and then
-+      // we authenticate.
-+      if (this._account.getBool("register")) {
-+        this._account.reportConnecting(_("connection.registering"));
-+        let register = Stanza.iq("get", null, null,
-+                                 Stanza.node("query", Stanza.NS.register));
-+        this.sendStanza(register);
-+        this.onXmppStanza = this.stanzaListeners.startRegister;
-+        return;
-+      }
-+
-       if (aStanza.localName != "features") {
-         this.ERROR("Unexpected stanza " + aStanza.localName + ", expected 'features'");
-         this._networkError(_("connection.error.incorrectResponse"));
-diff --git a/im/content/accountWizard.js b/im/content/accountWizard.js
-index ed3b8f0f7..7c26d0d6e 100644
---- a/im/content/accountWizard.js
-+++ b/im/content/accountWizard.js
-@@ -119,6 +119,12 @@ var accountWizard = {
-       return;
-     }
- 
-+    if (this.proto.id == "prpl-jabber") {
-+      document.getElementById("registerXMPP").hidden = false;
-+    } else {
-+      document.getElementById("registerXMPP").hidden = true;
-+    }
-+
-     let bundle = document.getElementById("accountsBundle");
-     let usernameInfo;
-     let emptyText = this.proto.usernameEmptyText;
-@@ -424,6 +430,8 @@ var accountWizard = {
-       acc.alias = this.alias;
-     //FIXME: newMailNotification
- 
-+    acc.setBool("register", document.getElementById("registerXMPP").checked);
-+
-     for (let i = 0; i < this.prefs.length; ++i) {
-       let option = this.prefs[i];
-       let opt = option.opt;
-diff --git a/im/content/accountWizard.xul b/im/content/accountWizard.xul
-index 9eb5352a6..759f42b38 100644
---- a/im/content/accountWizard.xul
-+++ b/im/content/accountWizard.xul
-@@ -65,6 +65,7 @@
-     <vbox id="userNameBox"/>
-     <separator/>
-     <description id="duplicateAccount" hidden="true">&accountUsernameDuplicate.label;</description>
-+    <checkbox id="registerXMPP" label="&registerXMPP.label;" hidden="true" />
-   </wizardpage>
- 
-   <wizardpage id="accountpassword" pageid="accountpassword" next="accountadvanced"
-diff --git a/im/content/jar.mn b/im/content/jar.mn
-index 98d9a09a9..20ea9dce7 100644
---- a/im/content/jar.mn
-+++ b/im/content/jar.mn
-@@ -61,6 +61,8 @@ instantbird.jar:
- *	content/instantbird/viewlog.xul
- 	content/instantbird/viewlog.js
- 	content/instantbird/viewlog.css
-+	content/instantbird/xmppRegister.xul
-+	content/instantbird/xmppRegister.js
- #ifdef XP_MACOSX
- *	content/instantbird/hiddenWindow.xul
- 	content/instantbird/menus-mac.xul
-diff --git a/im/content/xmppRegister.js b/im/content/xmppRegister.js
-new file mode 100644
-index 000000000..52852f045
---- /dev/null
-+++ b/im/content/xmppRegister.js
-@@ -0,0 +1,142 @@
-+const { interfaces: Ci, utils: Cu, classes: Cc } = Components;
-+
-+Cu.import("resource:///modules/imXPCOMUtils.jsm");
-+Cu.import("resource:///modules/xmpp-session.jsm");
-+
-+XPCOMUtils.defineLazyGetter(this, "_", function()
-+  l10nHelper("chrome://branding/locale/brand.properties")
-+);
-+
-+let registerAccount = {
-+  createElement: function(aType, aID, aValue) {
-+    let element = document.createElement(aType);
-+    if (aID)
-+      element.setAttribute("id", aID);
-+    if (aValue)
-+      element.setAttribute("value", aValue);
-+    return element;
-+  },
-+
-+  createRow: function() {
-+    let row = document.createElement("row");
-+    row.setAttribute("align", "baseline");
-+    return row;
-+  },
-+
-+  onLoad: function() {
-+    document.documentElement.getButton("accept").disabled = true;
-+
-+    this.rows = document.getElementById("register-rows");
-+    this.groupbox = document.getElementById("register-groupbox");
-+
-+    this.nodes = XMPPSession.prototype.nodes;
-+    this.registerStanza = window.arguments[0].wrappedJSObject;
-+    this.dataStanza = this.registerStanza.getElement(["x"]);
-+
-+    let instructions = this.dataStanza.getElement(["instructions"]);
-+    if (instructions) {
-+      let instructionLabel = this.createElement("caption");
-+      instructionLabel.setAttribute("label", instructions.innerText);
-+      this.groupbox.appendChild(instructionLabel);
-+    }
-+
-+    let title = this.dataStanza.getElement(["title"]);
-+    if (title)
-+      document.title = title.innerText;
-+    else
-+      document.title = _("brandShortName");
-+
-+    for each (let ele in this.dataStanza.getElements(["field"])) {
-+      let attrib = ele.attributes;
-+      let fieldType = attrib["type"];
-+      switch (fieldType) {
-+
-+        case "text-single":
-+        case "text-private":
-+          let textRow = this.createRow();
-+          let textLabel = this.createElement("label", null,
-+                                             ele.getElement(["required"]) ?
-+                                             attrib["label"] + " *" : attrib["label"]);
-+
-+          let textBox = this.createElement("textbox", attrib["var"],
-+                                           ele.getElement(["value"]) ?
-+                                           ele.getElement(["value"]).innerText : "");
-+
-+          if (attrib["var"] == "username")
-+            textBox.setAttribute("value", this.nodes["username"]);
-+          if (attrib["var"] == "url")
-+            textBox.setAttribute("readonly", "true");
-+
-+          if (fieldType == "text-private") {
-+            textBox.setAttribute("type", "password");
-+            textBox.setAttribute("oninput", "onInput(this);");
-+          }
-+
-+          textRow.appendChild(textLabel);
-+          textRow.appendChild(textBox);
-+          this.rows.appendChild(textRow);
-+          break;
-+
-+        case "fixed":
-+          let fixedRow = this.createRow();
-+          let fixedLabel = this.createElement("label", null, ele.getElement(["value"]).innerText);
-+          fixedRow.appendChild(fixedLabel);
-+          this.rows.appendChild(fixedRow);
-+          break;
-+      }
-+    }
-+
-+    // Some forms have an OCR field. In that case, show the OCR image
-+    // and provide input for the same.
-+    let ocr = this.dataStanza.getElements(["field"]).find(e => e.attributes["var"] == "ocr");
-+    if (ocr) {
-+      let ocrRow = this.createRow();
-+
-+      let ocrImage = this.createElement("image");
-+      ocrImage.setAttribute("src", "data:image/png;base64," + this.registerStanza.getElement(["data"]).innerText);
-+
-+      // OCR will always be a required entry.
-+      let ocrLabel = this.createElement("label", null, ocr.attributes["label"] + " *");
-+      let ocrInput = this.createElement("textbox", ocr.attributes["var"], null);
-+
-+      ocrRow.appendChild(ocrLabel);
-+      this.rows.appendChild(ocrRow);
-+
-+      let ocrBox = document.createElement("hbox");
-+      ocrBox.setAttribute("flex", "1");
-+      let spacer = document.createElement("spacer");
-+      spacer.setAttribute("flex", "1");
-+
-+      ocrBox.appendChild(ocrImage);
-+      ocrBox.appendChild(spacer);
-+      ocrBox.appendChild(ocrInput);
-+      this.groupbox.appendChild(ocrBox);
-+    }
-+    // Set focus on the password field.
-+    if (document.getElementById("password")) {
-+      document.getElementById("password").focus();
-+    }
-+  },
-+
-+  onSave: function() {
-+    for each (let elements in this.dataStanza.getElements(["field"])) {
-+      if (elements.attributes["var"] != undefined) {
-+        let variable = elements.attributes["var"];
-+        if (document.getElementById(variable))
-+          this.nodes[variable] = document.getElementById(variable).value;
-+        else
-+          this.nodes[variable] = elements.getElement(["value"]).innerText;
-+      }
-+    }
-+    delete this.nodes["cancel"];
-+  },
-+
-+  onCancel: function() {
-+    // The form was cancelled so we quit the registration.
-+    this.nodes["cancel"] = true;
-+  },
-+};
-+
-+function onInput(e) {
-+  document.documentElement.getButton("accept").disabled = !e.value;
-+}
-diff --git a/im/content/xmppRegister.xul b/im/content/xmppRegister.xul
-new file mode 100644
-index 000000000..e2bd36750
---- /dev/null
-+++ b/im/content/xmppRegister.xul
-@@ -0,0 +1,27 @@
-+<?xml version="1.0" ?>
-+<?xml-stylesheet href="chrome://global/skin/" type="text/css" ?>
-+
-+<dialog
-+  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-+  id="registerDialog"
-+  onload="registerAccount.onLoad()"
-+  buttons="accept,cancel"
-+  ondialogaccept="return registerAccount.onSave()"
-+  ondialogcancel="registerAccount.onCancel()">
-+
-+  <script type="application/javascript" src="chrome://instantbird/content/xmppRegister.js" />
-+
-+  <groupbox id="register-groupbox" flex="1">
-+
-+    <grid flex="1">
-+      <columns>
-+        <column flex="1" />
-+      </columns>
-+
-+      <rows id="register-rows" />
-+
-+    </grid>
-+
-+  </groupbox>
-+
-+</dialog>
-diff --git a/im/locales/en-US/chrome/instantbird/accountWizard.dtd b/im/locales/en-US/chrome/instantbird/accountWizard.dtd
-index 43d0f19e3..c46fb2f95 100644
---- a/im/locales/en-US/chrome/instantbird/accountWizard.dtd
-+++ b/im/locales/en-US/chrome/instantbird/accountWizard.dtd
-@@ -31,3 +31,5 @@
- <!ENTITY accountSummaryTitle.label   "Summary">
- <!ENTITY accountSummaryInfo.label    "A summary of the information you entered is displayed below. Please check it before the account is created.">
- <!ENTITY accountSummary.connectAutomatically.label "Connect this account automatically.">
-+
-+<!ENTITY registerXMPP.label "Create this new account on the server">
--- 
-2.11.0
-
diff --git a/projects/instantbird/0010-Add-Tor-Messenger-branding.patch b/projects/instantbird/0010-Add-Tor-Messenger-branding.patch
new file mode 100644
index 0000000..3ef898e
--- /dev/null
+++ b/projects/instantbird/0010-Add-Tor-Messenger-branding.patch
@@ -0,0 +1,5134 @@
+From 21890c548091d7f43e89f2df1816c468f2a2cdf5 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir at torproject.org>
+Date: Mon, 10 Oct 2016 18:56:27 -0700
+Subject: [PATCH 10/26] Add Tor Messenger branding
+
+---
+ im/app/macbuild/Contents/Info.plist.in             |   2 +-
+ im/branding/messenger/Makefile.in                  |  49 ++
+ im/branding/messenger/background.png               | Bin 0 -> 1143 bytes
+ im/branding/messenger/branding.nsi                 |  13 +
+ im/branding/messenger/configure.sh                 |   5 +
+ im/branding/messenger/content/about-credits.png    | Bin 0 -> 15182 bytes
+ im/branding/messenger/content/about-footer.png     | Bin 0 -> 764 bytes
+ im/branding/messenger/content/about-logo.png       | Bin 0 -> 6681 bytes
+ im/branding/messenger/content/about-logo at 2x.png    | Bin 0 -> 13886 bytes
+ im/branding/messenger/content/about-wordmark.png   | Bin 0 -> 3754 bytes
+ im/branding/messenger/content/about.png            | Bin 0 -> 9880 bytes
+ im/branding/messenger/content/aboutDialog.css      |  48 ++
+ im/branding/messenger/content/icon64.png           | Bin 0 -> 6661 bytes
+ im/branding/messenger/default16.png                | Bin 0 -> 932 bytes
+ im/branding/messenger/disk.icns                    | Bin 0 -> 43113 bytes
+ im/branding/messenger/dsstore                      | Bin 0 -> 12292 bytes
+ im/branding/messenger/gtk/blistWindow.png          | Bin 0 -> 1003 bytes
+ im/branding/messenger/gtk/blistWindow16.png        | Bin 0 -> 576 bytes
+ im/branding/messenger/gtk/blistWindow48.png        | Bin 0 -> 2089 bytes
+ im/branding/messenger/gtk/convWindow.png           | Bin 0 -> 1126 bytes
+ im/branding/messenger/gtk/convWindow16.png         | Bin 0 -> 637 bytes
+ im/branding/messenger/gtk/convWindow48.png         | Bin 0 -> 1563 bytes
+ im/branding/messenger/gtk/default.png              | Bin 0 -> 867 bytes
+ im/branding/messenger/gtk/default16.png            | Bin 0 -> 520 bytes
+ im/branding/messenger/gtk/default48.png            | Bin 0 -> 1178 bytes
+ im/branding/messenger/instantbird.icns             | Bin 0 -> 21624 bytes
+ im/branding/messenger/instantbird.ico              | Bin 0 -> 7262 bytes
+ im/branding/messenger/jar.mn                       |  14 +
+ im/branding/messenger/locales/en-US/brand.dtd      |  10 +
+ .../messenger/locales/en-US/brand.properties       |   7 +
+ im/branding/messenger/locales/jar.mn               |  10 +
+ im/branding/messenger/locales/moz.build            |   8 +
+ im/branding/messenger/moz.build                    |   8 +
+ im/branding/messenger/mozicon128.png               | Bin 0 -> 16878 bytes
+ im/branding/messenger/mozicon16.xpm                | 193 +++++++
+ im/branding/messenger/mozicon50.xpm                | 314 +++++++++++
+ im/branding/messenger/windows/blistWindow.ico      | Bin 0 -> 9662 bytes
+ im/branding/messenger/windows/convWindow.ico       | Bin 0 -> 10058 bytes
+ im/branding/messenger/windows/default.ico          | Bin 0 -> 7262 bytes
+ im/branding/messenger/wizHeader.bmp                | Bin 0 -> 25818 bytes
+ im/branding/messenger/wizHeaderRTL.bmp             | Bin 0 -> 25818 bytes
+ im/branding/messenger/wizWatermark.bmp             | Bin 0 -> 154542 bytes
+ im/content/aboutDialog-appUpdater.js               | 576 +++++++++++++++++++++
+ im/content/aboutDialog.css                         | 105 ++--
+ im/content/aboutDialog.js                          |  80 +++
+ im/content/aboutDialog.xul                         | 257 +++++----
+ im/content/browserMountPoints.inc                  |  12 +
+ im/content/jar.mn                                  |   3 +-
+ .../en-US/chrome/instantbird/aboutDialog.dtd       | 139 ++++-
+ im/locales/en-US/updater/updater.ini               |   2 +-
+ 50 files changed, 1695 insertions(+), 160 deletions(-)
+ create mode 100644 im/branding/messenger/Makefile.in
+ create mode 100644 im/branding/messenger/background.png
+ create mode 100755 im/branding/messenger/branding.nsi
+ create mode 100644 im/branding/messenger/configure.sh
+ create mode 100755 im/branding/messenger/content/about-credits.png
+ create mode 100644 im/branding/messenger/content/about-footer.png
+ create mode 100644 im/branding/messenger/content/about-logo.png
+ create mode 100644 im/branding/messenger/content/about-logo at 2x.png
+ create mode 100644 im/branding/messenger/content/about-wordmark.png
+ create mode 100644 im/branding/messenger/content/about.png
+ create mode 100644 im/branding/messenger/content/aboutDialog.css
+ create mode 100644 im/branding/messenger/content/icon64.png
+ create mode 100644 im/branding/messenger/default16.png
+ create mode 100644 im/branding/messenger/disk.icns
+ create mode 100755 im/branding/messenger/dsstore
+ create mode 100644 im/branding/messenger/gtk/blistWindow.png
+ create mode 100644 im/branding/messenger/gtk/blistWindow16.png
+ create mode 100644 im/branding/messenger/gtk/blistWindow48.png
+ create mode 100644 im/branding/messenger/gtk/convWindow.png
+ create mode 100644 im/branding/messenger/gtk/convWindow16.png
+ create mode 100644 im/branding/messenger/gtk/convWindow48.png
+ create mode 100644 im/branding/messenger/gtk/default.png
+ create mode 100644 im/branding/messenger/gtk/default16.png
+ create mode 100644 im/branding/messenger/gtk/default48.png
+ create mode 100644 im/branding/messenger/instantbird.icns
+ create mode 100644 im/branding/messenger/instantbird.ico
+ create mode 100644 im/branding/messenger/jar.mn
+ create mode 100644 im/branding/messenger/locales/en-US/brand.dtd
+ create mode 100644 im/branding/messenger/locales/en-US/brand.properties
+ create mode 100755 im/branding/messenger/locales/jar.mn
+ create mode 100644 im/branding/messenger/locales/moz.build
+ create mode 100644 im/branding/messenger/moz.build
+ create mode 100644 im/branding/messenger/mozicon128.png
+ create mode 100644 im/branding/messenger/mozicon16.xpm
+ create mode 100644 im/branding/messenger/mozicon50.xpm
+ create mode 100644 im/branding/messenger/windows/blistWindow.ico
+ create mode 100644 im/branding/messenger/windows/convWindow.ico
+ create mode 100644 im/branding/messenger/windows/default.ico
+ create mode 100644 im/branding/messenger/wizHeader.bmp
+ create mode 100644 im/branding/messenger/wizHeaderRTL.bmp
+ create mode 100644 im/branding/messenger/wizWatermark.bmp
+ create mode 100644 im/content/aboutDialog-appUpdater.js
+ create mode 100644 im/content/aboutDialog.js
+ create mode 100644 im/content/browserMountPoints.inc
+
+diff --git a/im/app/macbuild/Contents/Info.plist.in b/im/app/macbuild/Contents/Info.plist.in
+index 615e4e6b8..ac61e6134 100644
+--- a/im/app/macbuild/Contents/Info.plist.in
++++ b/im/app/macbuild/Contents/Info.plist.in
+@@ -11,7 +11,7 @@
+ 	<key>CFBundleIconFile</key>
+ 	<string>instantbird.icns</string>
+ 	<key>CFBundleIdentifier</key>
+-	<string>org.instantbird</string>
++	<string>org.mozilla.tor messenger</string>
+ 	<key>CFBundleInfoDictionaryVersion</key>
+ 	<string>6.0</string>
+ 	<key>CFBundleName</key>
+diff --git a/im/branding/messenger/Makefile.in b/im/branding/messenger/Makefile.in
+new file mode 100644
+index 000000000..b4309568e
+--- /dev/null
++++ b/im/branding/messenger/Makefile.in
+@@ -0,0 +1,49 @@
++# This Source Code Form is subject to the terms of the Mozilla Public
++# License, v. 2.0. If a copy of the MPL was not distributed with this
++# file, You can obtain one at http://mozilla.org/MPL/2.0/.
++
++# Branding Makefile for nightlies/unofficial branding
++
++include $(topsrcdir)/config/rules.mk
++
++export::
++	$(NSINSTALL) -D $(DIST)/branding
++ifeq ($(OS_ARCH),WINNT)
++	cp $(srcdir)/instantbird.ico   $(DIST)/branding/instantbird.ico
++	cp $(srcdir)/instantbird.ico   $(DIST)/branding/app.ico
++	cp $(srcdir)/branding.nsi      $(DIST)/branding/branding.nsi
++	cp $(srcdir)/wizHeader.bmp     $(DIST)/branding/wizHeader.bmp
++	cp $(srcdir)/wizHeaderRTL.bmp  $(DIST)/branding/wizHeaderRTL.bmp
++	cp $(srcdir)/wizWatermark.bmp  $(DIST)/branding/wizWatermark.bmp
++endif
++ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
++	cp $(srcdir)/instantbird.icns  $(DIST)/branding/instantbird.icns
++	cp $(srcdir)/dsstore           $(DIST)/branding/dsstore
++	cp $(srcdir)/background.png    $(DIST)/branding/background.png
++	cp $(srcdir)/disk.icns         $(DIST)/branding/disk.icns
++#	cp $(srcdir)/license.r         $(DIST)/branding/license.r
++endif
++ifdef MOZ_WIDGET_GTK
++	cp $(srcdir)/mozicon128.png    $(DIST)/branding/mozicon128.png
++	cp $(srcdir)/mozicon16.xpm     $(DIST)/branding/mozicon16.xpm
++	cp $(srcdir)/mozicon50.xpm     $(DIST)/branding/mozicon50.xpm
++	cp $(srcdir)/default16.png     $(DIST)/branding/default16.png
++endif
++
++# Now sort out the branding specific icons
++ifeq ($(OS_ARCH),WINNT)
++	cp $(srcdir)/windows/blistWindow.ico $(DIST)/branding/blistWindow.ico
++	cp $(srcdir)/windows/convWindow.ico  $(DIST)/branding/convWindow.ico
++	cp $(srcdir)/windows/default.ico     $(DIST)/branding/default.ico
++endif
++ifdef MOZ_WIDGET_GTK
++	cp $(srcdir)/gtk/blistWindow.png    $(DIST)/branding/blistWindow.png
++	cp $(srcdir)/gtk/blistWindow16.png  $(DIST)/branding/blistWindow16.png
++	cp $(srcdir)/gtk/blistWindow48.png  $(DIST)/branding/blistWindow48.png
++	cp $(srcdir)/gtk/convWindow.png     $(DIST)/branding/convWindow.png
++	cp $(srcdir)/gtk/convWindow16.png   $(DIST)/branding/convWindow16.png
++	cp $(srcdir)/gtk/convWindow48.png   $(DIST)/branding/convWindow48.png
++	cp $(srcdir)/gtk/default.png        $(DIST)/branding/default.png
++	cp $(srcdir)/gtk/default16.png      $(DIST)/branding/default16.png
++	cp $(srcdir)/gtk/default48.png      $(DIST)/branding/default48.png
++endif
+diff --git a/im/branding/messenger/background.png b/im/branding/messenger/background.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..e52f31d051010215470ae91fc84a6d29d8645efa
+GIT binary patch
+literal 1143
+zcmeAS at N?(olHy`uVBq!ia0y~yV4MKNIvh+uk)*3dQyCao>^xl at Ln`LHxx&cHz`$`p
+zA^rckS&yY#68IF7*cF^29NIQC at FX%y9%3?TVNK!SJ|Q4BK~YD+nS2RZb^!_u=wWAI
+z`2Qd1T27!B8W#Lte_QYcM=NU%2lovDu?>nk3C<A*fKKL3WRyO{WY#jk5-g*RrBPgr
+nhAgd8IdLJ|3(S81|1&c<eez%YX0_TEAeX_@)z4*}Q$iB}lQ?mb
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/branding.nsi b/im/branding/messenger/branding.nsi
+new file mode 100755
+index 000000000..4683827fa
+--- /dev/null
++++ b/im/branding/messenger/branding.nsi
+@@ -0,0 +1,13 @@
++# This Source Code Form is subject to the terms of the Mozilla Public
++# License, v. 2.0. If a copy of the MPL was not distributed with this
++# file, You can obtain one at http://mozilla.org/MPL/2.0/.
++
++# NSIS defines for nightly builds.
++
++# BrandFullNameInternal is used for some registry and file system values that
++# should not contain release that may be in the BrandFullName (e.g. Beta 1, etc.)
++!define BrandFullNameInternal "Tor Messenger"
++!define CompanyName           "Tor Project"
++!define URLInfoAbout          "https://www.torproject.org"
++!define URLUpdateInfo         "https://www.torproject.org"
++
+diff --git a/im/branding/messenger/configure.sh b/im/branding/messenger/configure.sh
+new file mode 100644
+index 000000000..7e580518b
+--- /dev/null
++++ b/im/branding/messenger/configure.sh
+@@ -0,0 +1,5 @@
++# This Source Code Form is subject to the terms of the Mozilla Public
++# License, v. 2.0. If a copy of the MPL was not distributed with this
++# file, You can obtain one at http://mozilla.org/MPL/2.0/.
++
++MOZ_APP_DISPLAYNAME="Tor Messenger"
+diff --git a/im/branding/messenger/content/about-credits.png b/im/branding/messenger/content/about-credits.png
+new file mode 100755
+index 0000000000000000000000000000000000000000..5df30c77fd5f82a1de8fe54f7ddb00bf48006669
+GIT binary patch
+literal 15182
+zcmX9_1yozl)5Qty?k+`(JH=gE+ at -ina4RkaeuV<XrNtpo++B)8DefAILyFt?_<uPs
+z56I!X&F;+HxjS<=PD?`(3!NMt4h{}WSxN3a92~qf at Ov-_1-Q>5wz&X5ki2A+bwI!?
+z2=p-)_#4e#$<Pb<|Ap5#ybNo$AMhcWx4eP(2RB=9UrSFLIA331E(cd9FKbJ88!k6b
+zyX;eOayU3zIAytaI(|7Po&G^N`u;ahoy|)mC+Qr9m&9kr*As^BN(lTM%IHz)GRF4#
+zmt9fKC&qsETZNxw3ad<&R6ofqrQ*xT2(r*&F#hzQWYMr1u47oKvl&UL3Z4&?n4)R6
+z{W0^Fe9%*HQYasm8EAW|dpADS?FBh9Q513C43nn+q9a#zgl8p at to~r4d1LXT9lmyl
+zQ+TGt;lX|%^l6LaDcEX4_~#&;w~tSq7j$wvr2B95*;%%*hORDG+W|eHeC9=7-4X{X
+z4mD%;gvJA;x*97?hh3gMjh+<K^LojSq?@Gg<<8gJdwONX_<D&1U0yqWK>#zN(P;rc
+zP7dx|Jb8WHEQv<yxo$N<a)m~h{>#@QyN9^EAgg6)eD?6K9Hbt;BH=GXWXbv`-X6vW
+zbZ{JF+nIKGY)jmD91>iF=o9QA!NI|lBA!T7Fx$uH#h=!LCm-LAw1JP9Pc2O%FYm;k
+zo}T!qLz!7kND8{T^1MYSdV1i>b>h86O)sA^70?Uh-s6Su&a`U{co*{iX3 at qiU|oz8
+z{I(}ly!5x|KeP#w9=rVD^dL#|I&)LM(L1c~|1=^k+};0!Kp<qM8)|>%=6(iT9pc~U
+zZk})T*P|a~mXwx4iCSIZpNKl!<SxnSem^h<91i^BCY-L)h7;$EwUe`xh}piCVIjm-
+z_*Pg*hfO0X?$RC2T2&cAg7SFt*E?%#%aU at K%@yj|>c1AMu0HXZ%hSRlY-?-FKlkV=
+z(mM=)#02!N0UAe!EY~>8nui!hl4tlazH|nGH7|l5Zp!B7bgka!X1yaw2F`S0FN(xW
+zxLT2vlvG-quxN&LtJaN|b8P$97lu;s`hw_tIHnX4p0{gddX7V9=n(9lSq7Uah6dWj
+zkc_L_EksN#tckX>ct_z%6tkS*41ZpJew~hWwYAL+y+8W*D2yrkVxK-Ot!2>XY&T6K
+z*i3x at 1+_rN;uuc6%x>;=3v%H@=?C2q{=N<ZN~FwbbgFD2K!~O0*g&Qx=>g^`6VG=P
+zf}GC0wRW_r_yG0oP8t1z!20FuyRqx<dnk4r at 8+1BB$}P`RSqm8aX%*|y{AIZg?Gc|
+z^KroNF5R5TVBtJ%#$G~BR~p5oWZ%#w8jXZw&olKgpNgFk%ISlNV-jWUq^<RzK|akj
+zrk%XWr1=f6!f3-Yl$5sdF8kL^wkjOe at Yd4gyYyrXb5+WK-<y+P!b{oDdneBKOs6x-
+zcOgt^^vGKDY!Qc9d&5@<Gut;6X?++A6K!sRfnpNhu{pItWrU`i7c;GA430gD+>ve)
+z7^q|aeuZYEMafi|w59|}YHDiYEIFqea42vPGh|P^6%-UaA<YDF0+YO`s at uTejMM@X
+zPQ9xi`o`I?)y4&c(g1<`TPzo}7g)ORzaKs27W4`OVL161QZ6y(BfPy19A+Kglo(|g
+z at eAA9$XA+FZD%ksG2Q<i%%oWVK>VsSTF|nGj4MsbOX!6($g7=0DTAZAQu_V-cj3Ki
+z7G%}!kOe(`3w6$83OM#(8rnp+osG3Wsh>-!?rkz!VoUCJex_n at s+B+>Nk4z`qM)*H
+zG!RP1{lJWON;^S7^xI<B at j`-=2t;RD5_HKQ;p1|~xv!h%mvn+KBaNlHfBbRzV5E<l
+z-+ at FeiE=}QGF$z)xbOxTTSs3%W33d3zrw=8BBfE*TDkYpt!+JUu4Tl8FQq^BG(H)V
+zW0Fx*b9qp~<uY{P65Gf17cG_IO~pd`1jaVK^n2Rp`?eP!lR_K6v!Y{RVetzHXzS_<
+zK&9jm5fK-C?xc0ZsqNO<z=M~@uO_ai>)00Gs4EjSD<c;W0_7#-oeaitvxP{^1{tqJ
+zBv~4Wv32fMIsRJW5p3R1$K~A|)$67r`!w8cp-Hn?<DuW;ILBU5Q4xP;x?lqYdn${j
+zMr8qF2xo6smt<CU_E??}C3d~*nkY84I4f0w+*=Ctw2W9!hO0pr&Xr{PpsNe<<jKiN
+zvSg98s87oBraH*;bF#bqGO1&go52)Y82a~++TSMq`V at s)Wpa-_G&_|wHFmQl>Kw*R
+z&O<vKPDurGKODk(Ewn_X<38#UB3jC6AGb1KnX#e;;8GHppmNS85IB`IH#a*^bdki+
+z&Vvdsf)2ybjme)>co=5YH3lQE(DWBY(5Lb*Yvx3Z3<vJgn2EF3^Yb~(;^e}mX?yBy
+z#)Lh#kupEOys(mDYKXZCl9QAFfKy at IJ1@FA_?|{Y1?~sivvqTHrT-mF6quQr(Y_{K
+zi3l#WP>ql(K at IunXD#84**k(9d&#AKU+v!couP}gOZeDrrAFqR_uA!?ullS(cZfu^
+zB`$W1gPR*m{?rs1Ql=Us{ulo+d}WaiEzZxAyc9ob-F|ejhP7Z@?INwMt$9&rGzJeh
+z7p|Y7AhO=>)%KxKk`)&bW~%V$80hW at ov&FySt-d$1}4AgE6RzasaR&&&djJ+TYNtv
+z_)P>tGH7<CYBhlv9Jw=><T0d<D4_yK(w{It)j2CHgF_dttTUGHv55)RBbI|#P&1Fz
+zTe#oWFJL<LwZp-jG!@<|E~u=nTXq`^9C`R~8o>ALWEsfVZ6PYolC(2DGt&#?l>N`o
+z;b$PbL%}J9&`>E;Q`1-Y^z at 6Hj}Hk$Uj6vykS$cX*@Stpf_za*Yw72c;l`Kh>NnMh
+z1{Bd=6i=>4u_F2Hp$<AxkAjVG5qs(AR^}+tu>a~T#!dX7-!w|esHm7S)wqu1hRZ7}
+zQ%x=6eo$)EVHJ{l5sR|YBJg(ehxq(wBB<y>O8&jeLZ?rQI`1R~3yk|s$Kg#?|B(E2
+z_VowTef9!(W{`a?<5qKKt*KNLi;a4$mE-8c=M#+by?g8AbYn?YK7BKquiWPqY~cmW
+zAXYB;Ifk+TB!S-hk6**c)3E`#OR(M4tC6P3X%F{;7g~x>k<=a6H8wjDYYwvMwERsh
+zJ_}7oQ(&3ce;+9o_=9;DRS89tK_!Tphkv7beo_)sh(Sgzws7xG#t8S9foG(_syrTo
+z{Kc>m(V$dWZ8hjq- at r{4J&3hy+995_duW`V4S?88#AY9&q3PaHoauhdmEP at S4Sfr6
+z;@L6#p!d_$!rZ&Luj5GtC`U(6T(GS#3n6{=MYpG(bvvB6al3K38di*ZR7Gl$=}P-O
+z<%R+^Pf at s(WIn3l#3KbX)87`r5`JA9`9k6ZSa`zSXhsACGdl|uNgoPbLgHS1Wc*XC
+z;AWJQmRB0*%)T%-%LA(NQpj8ef@*5WH0_5a_o7gj$NNx!yQ0YXkKTh)XWPQwiFd_K
+zlX4BWY1`h&?hxdH*U%x_<j<4cJm7w_tPkp4TqNyJr-9=gdN8cmR at BS?n;R-R@>Bbl
+zK}g%En(1H|`kRWN41Z_L``_H=qobJvunrN}g9hqrDr4_)5HH;hR-YZ<SEq!h`k-Pm
+zh#A^-s%lA#s(E$K<tFHX;aFQiKIwGX{;LKxFm>ePdB<H$=NrT44**>JK#*&o=3a^y
+zoYxJJq9Y~C)av{|R)%$FrBfh+U4qI|qHmv1FbuPE{%7;FL|H$G+Sg`o4>lz7E`9o!
+zxzI<snF)|GZ&7u6Ue)Ib2U@@~<+#2V{$A(>Q2*KayaUp3IrpMX_ at 25SG@Zfa36zPM
+z=iX<2W at bUxv`SjAgz6 at yM<;OUQ;Kno06 at OlAS6e(6Y|9g-D6w;=F?3UaTXuJO-Wlm
+z*6a$yqsFMTSEF}DREi`Pa%$dMM`+&k9#Hbh at egu;3ouK~H#eXP_`48XtW-KXSi!wl
+zrt>KMIzvwc?bT(014QoewgjmEkN0ferivi#D#y23F$Cqm%WA{Taj)(^bbSvj|L7uR
+zSIf5V>wooD>Tlq6AJdyBM?MjXfcg;0LVw$Ob>h!`eij_W*$ae&OaB49V;r&hq^=Hu
+zHIfy*;HZtsCRbFkKos<|XW%&t;piv`ek{*+;onDc6t57Y at uGu&aKD15`d!*B7c6fF
+zjGt8a#)edF62FD)`qAQW)2*M^rHt*>awHgVL_?0gmBitO+w+TZ-=NlEaC{lZXx``O
+zu-~cL2+Y%`tjTiZLYkJ8)g_U=qB5)vI%}inSg2u#eZ=uD?V;+P-{J0iIlgRekKWv%
+zxh^gE#Qk;dos_+&b}Eg$hK`y3KcZf+se+;+86_oSt_C9P=$`mLAc`|tPJh4Ay4etY
+zxPgc{-EbV;YOl at -6z8J~ggT$LK1Z=>Ikr9Xx9(W~r_#$QrZP;Me-uu09C>5<J|G7o
+zV?FNXzu@~-RwVTE#axz!3#r0j at 0arbg$qIHUrLZh{sMDkj|Zjrl&tnwL-|_n9TK`+
+zl|SduTdv)PCV~j}qsh$nMx1Uqoa5}L#s5$ycsFv*R*$DtT|ZCc#6GE5k`6UA%I-(J
+z(%GOH%p9f+3(Am!UF#`W{9d+BV at I>F<bHcs37dd80sP`B+=J#_nzlwvA))v!|JO>c
+z&@ryE<o>1EjJI6xJ``{r3u*7 at SCNhOY7xJ$u`p5>4+*H0REGbmWQJgNq$hmOqgHWi
+z;vOb#h-y$^y~s_cE5t;^OnpwGupH_b0*huzo$N&n?8zcr>pZ;K7?PEGMuw{>*=h~x
+zjdl}92o0p-sIEL-jSp+tYHo^@Iu-tUv*PY*wR)jO076nx+0m4rMEasMN!TmAz73mh
+z^Gyo^#zKbAIl2M6gAlI%1EoJ3$cj3fA)%tA`PX1))LT4!2tWSuCrj#X;H5unjGGmG
+zvkfNnv&;q$XRV29_EXI|&I|OUiz0^`KG<qi3q;CG6b*a6wJa9EHAhc<>EeqsWm;w)
+z269hEZ2h)l<okPqtYbKgn!POPt*CcVRn<IKQnI>>S~!V6FQMO7DfPFWOOdQoRqWSp
+zp=VoDFIzQQjd8tV!*#b0FVFN&lZH4w2H29JIL9ZtWWU(`tnQz5F7qo`|3p6aVfvti
+zT(@lgC9!1Hz2nnaW`@0=q5~Mu<@>ll+l?lX^Non-roVRaPt$~@&)Yvgpb|Cx37kd1
+zWUs9-!ks5dN=%c=I06<|9EC+)&VQ$Uy-%?_gaEEh(!+DC0VLlSw3p;|{*2*fvAN3@
+z{r<du0|b%Kl>bmD$WewN3s&l2Ed6If^7+SBX2WJ?f4Cn~x&S+elTKO9dyRIjei{3W
+zSNCz)gmj=Z#I;>TZN}gt=<2 at lp>Ha!4OQyLixNF6c2P#qTL9^R_jfoIx7JxCG_cjZ
+zk-6J!-{e0(XC&PG_)8$=JJ!(SRqj@`r`r5P(Oa8;y8u?Hg at s8M@cj3|f#&_vTICFH
+z(OXCMp79%@4^C2s%be;qTdfS?V!nQlyOtTb+ at Sktc(bfP0-2nqz^_2)iBQSt`c-EX
+zQ3n%#GpNx6 at mjz27V*Rumn!(#HOV9#A>a at zt#xBh^IL_z{j&}7&8a8Zgc at jaD52?G
+zQ|iI at b5EqOQz`<A&$?WTpda<oq}fDimj^+<-^&I<ZTBn#neJlCcsH89bf`w56lyek
+z83x87L-_5FE0vPpLg)-OB`3C*wKcQW<}8sBwN=_S{;8weMo}s+AM>DF!r0N47At~D
+zJGkgkB~KG$i8v}ioM;fZ4bIt{iuKm1AWid(vJP<UQu>{K9lAG4j+K0h$;Rv{5zRo9
+zB^N=xS43Lz729P-7EiB{N~l?Ta_O5<-m=*$R9E3?P#ZJvSc6IXnSh at Jlc;auHlF)J
+z;cH>Y8FF%kF52aii+Oz`pMfhM=Nkx=^6o{TD#5Dx`i_84(PHCqy}ABn1S%YIa4^7^
+zecs2LOp at e3(1-4nURLFx8ymepUjkGX81d;+M`$ByaX|$R#XF!qehr^bOewQ+NLDQ_
+z8HmN$TDo&Z7&)5t5>Zf8{vqeV{8GW<D6B;T=v$s$kA=zi7wy|8ZoApt&uDR37meOg
+zs1QWRhr0P%7sJ?#DG#d1qjQ!}SO_HGA#LXd2S;Lu=WCWkk3}GQgnt^tclJO{hvU;(
+zdzyLSOzkDFplzeZ1d8~TzcYl*REv|L64wN-kM$c2+NN#$ZlWxHhyRTwQ+qCUt?c=A
+z7nqP30yzqo06og~F)%}R#J0ZXHyRiIh!aRGq5bKMl<HuQr27^bpy%$wYLfZfT*)Hl
+zI-6CF8OvIKHUIc*HL*yX25JzNHvf&DG!NRcetb56;-!5or|FXg)wFbmz9c-3_ at 5!s
+z;-X(3tt-Z3<8IN3<M3td$htkeS<aV0lIH*6zO$zw?^+dxdtM#LX`*j|g!%k(7W9ex
+z<zm=l2vP3kdDB<q<`UKetA+Vfci-r*KJ2tFUG!j61_rFF@&Bl8(zQ{~RuC751(#K*
+zfWhFw8w2Ur)sLdZ9W;Da_^ch8<nEz7{x+`7YYQG#kw2Y9oSfmgVB_LluMjn{w>r8H
+zKc~w+joY36ym>92cr&XlvSoiZu8h1cUS7-x_pqq5p>7;<@|S<PFa4<NmoL22LUPR9
+zExs8OVofMK>^TU&p1=C3rlPwJmdET3TfeHVUnqn;%|5{0W+aDvc?sDbE(3X+?u{OC
+zLF1d9ZM-dFQQZRn3v^qX{M1P>_Mh!#*PB&Xk*aFv=)GWKaiZghf#thlcCwf3&&LR=
+zj2Mw~bwon%lS>@@^7QdR{v%jX->u0_9TEfc30D7k)yO?Uf`;cFH_OEgLe~S_A0fwo
+zATC>-^d|fhFC&3 at J-icSH`SG at mr-s{RK5S1H#=GAoR3KerYSh#+^EUfuis8KPp@{w
+z3U%F3A<2aNxZ7MuT)p|;&K#-lM{ANY$LspovvOB+Vh$bdekKmRB{?gyycqaLNLNs~
+zVg2BmeI{jb at rRCN_FCTUl7C=i+`s!S$n16Xk!jOZc+dN+j~@@u5dTwRoCfCtrJ`BM
+z8;oH}YJb~pR0xGA&2wq;MPBmb7C(v596WIo4)yWw)cQGmRR?kpx7aByCHCY2As#i(
+zMtel}%P%Ps(?9z}qQ*k$ILCg}j|;*694lwf>l at 7p?i_u2rFlEop-+-HFT1XAha^Jh
+zvv#fwg#5U97<tA)xr^85CNZVH;$zqO5`8sIXY|>eR2n?|2JJd_V=B2>au(}H(PgDq
+zHL1>ZBYMtRC6 at X%yDcA#IU+^%wIfvw=ZXk&`Jb-}LvK~rVI-ki+vfv>!$PSPIYCl=
+znM-WMO&jhL{*M<gfx#Xxb~s`UG~6Ey;f2 at Ftd@4xHk_L9RflGDqV`JynmQjikr+Za
+zpFc=EJsy~cZYI=2iOgBtFs9`3sG(*pdEF0vF)d!hq30u^_g<6TeiDa%aw|Stt^L?i
+zL9|m;Vs(@Ul$IQ65I>2n3`uFaFG?y}x<u-;!ewp+q7QJosYCE<o=k at 9J=0s;V3h9F
+zo%ZIH=bhn>qtMO->FICofqY1k%wq54{g|w+vgm_mvbPCY@}bGkkJa8jIh$K2nh56y
+zW(kLWu|rvzQBTuxanRN4b~kFNeAS&Iqc)&OwjEvRzZv5Tf8Jm76xRIIYg|@YgRrHs
+z`tX%G5~Gia at K4KrTSCh|Cv<kfD?b0}mhQCc$>Vo9WnS2%Ys};+zk(^%1<?ef<2I6R
+z#(#&z=CWD(mu8~UOCOC3N{&RcO0?HH!cP>DWI*CmVox4D7fmG-1%;y|d8xwzx4rt^
+zVn==(&eosu#CRo3%ZrY?qE3=S?}Muh&lbi!C4hib7L*DOn()~ArECtD7}mSzwx;Lp
+z%^to#WCUrsAn)Vt_H*FMhGyqK_{8m4cN~ee^Zjcd#==sT{P)H8e70SxKj!5=AS=r$
+zVaf&vlc&K6XRX^mJuj6^!@vU at TDh1}zE%EHl$yqHKvp)P)y^W0 at b#OQl{k=RmCVe~
+z4 at D?${qcJj9)&NhtG(FfP^9;C)BR|A-`<7?k&vwH&s(H+>&x~#YxU8FBa(kN_-4)b
+z_s`Vk2+^R^u}~G$&iwj}35?S_b?T`%o!$KsW<Retk=;7J`n}cL-X#{$Nv%rq*h|zW
+z$=}M$UsWA`P9mc+?<Jb#isjn+ZxZWlbri?#jx_)7IMA at W5G(_ViBXn#;%Cql|1`G{
+zQ&GV*@j{`*n1cLn0gTyi@%MMJF!d^!KNjkbgzyQOV2KG!bd2PILI2JqFZ5xzTfL<z
+zbLgK6eLvT_pM$;bhd0zhgb-O5aO70*UrkWdBdyX#?Xc|BH>R8UkRW=c`jcp<p|vcb
+z5o8%JYpRUSCoDOF5GI2uf}p387ml-A=7hp?+XMFYviRZov4wLt^A}p7jmLM84o|C`
+zY4uX&leMvP0!@p2QGpAb_zD$N)@)~tH6tS<5E8=i3E1C~KOAy|L5vB%*v4zXk^QoH
+zg7edNcs+h#+$&f4F3zZYTEq+WgI=}Cz_8SX2H{}0-ve*9M9d at aNFi@B!Bf}MELQHD
+z^(GgSA1Z4mvcW_ba*-})LDm=kd5>4K$NrC*R=dqPJJ}o+d}q))9~Zv-`#)!woiEQA
+zO)e`vw<p^r??0a|^`9qEEg~Ya#=la#a4S-jXv<o^3#;FM`ET;8=#LID4iTL2$tm>J
+zs;ciAH6JM;E@>yD=nF&jRolE-khD{=4>$hNFq4oa$MqLQec~zD0E~I~-sGCHF24Rf
+zSIZ%O_k)<Mj=uc#Z=GQ#w<VR1fTH`usqRqCnF-zPTjuL*eEv*1FIBAk$KAvrm~rSN
+zQ$`h6$m!>#w{?L+{bIiVziLb92(LB5x0#q^6d at wD_V19jv<bPEaOv%D=l7?(`d6>M
+z2SSfW+pZ(w4zrBf&M4V<qt4F7*KcAn>Rnb)dNeh<-0YIBtqImPZi04kg1=;a)fZlB
+z6!^m&D=%wuxv!cqEPma?75xxnma_9kblA`~xXPd_b}Hn0Z8ZpnDgw>18Js%VvSbUZ
+z8)^EFlMo#b6Gh}^)eBGNzX at 9re&XG-c6+lcc&Ou6!D!Tx%peUcG~^=YN3`OYf_JVm
+zA5((|JjcpOE at S+MwYg!*YoGZl2b3OfIggR?MkoXt?n083kZ+umCA2ic1~STWY(2=r
+zn86AapY<>~ef}%EN44=4<S}yn^&va1(JA}xGGk*{zw16^zS;@?BYlH&9j8485&{we
+z{G`N<Nl!kNRTgu%GIy_lh8uEyc}~5kQgE8oJ6~_V&u5P?PMh|cbw<=Ohr@=alFpkF
+z4D(OY($M<+V4+5E at zg&>nkS3QpY3tHUH4f?0*%Uo=5^(M$GOdqze(1YD9uN{Z4-XU
+zL3LW-hg~=4YpScOB?0AMj5x><QpCHgtgQH*uymU*zC?Kq`h^b5;c?X^>?VPh4Wzht
+zOE_nC8+q4;?KP*2sKT6}xBli+xs75XnORw+#@wbKg1Wu0-a`CV(rkuKnTKu(#fgP<
+zeqK$GkR+c;c*L{N1iCJJw=CJl5nfj!X at ahgMf#vpFJ7)KTdG0NFey8GR!*RHVyJ{J
+z02k3qn=R-<pR2(T*~70Mki(8GmWXjEOyT4`X?{c^c_rRUB6;UB?(8}QsTN}crA!$g
+zKVC^{P at YlX6zFgTA#;pvEp!JI-aZG1!dO^k#t&|7;|~S at Fxwlqew)`-jfb}E%*T{~
+zpd3jxGSG!3|9H0$SVqUgP1lg3)IB0~(7DLvo$?E=&SL|9+z)z$PjJze?m%y at KKQ{0
+z at ZS;#{N&-KnkvgLLUL;L`;yvGCUtCT!)OV;ycyPtfp?P=zUSSNkJk>f%gj^BRAd at 3
+zUz(S$(C%mjFI7&LYH&l--0ZTEqLUMqYWg2M%t<c18<&l-bHBBRAtrT`2Z+$b at vSYI
+ztv&jm1?I(olc>jAEfP2}>a{WH7oJ9epN3Q$11%flRubYlTU#;t&`+p&dxIo_rNK26
+z<dqAYmV*_{Yyc3*5MZL9#q{U+uKTmb_ib*{&dtrS#)n5tTHno?5G=)%aH!ESo9g<_
+z%JYUiZnDbsR7?5Aj at 2yoEQ2|jygo_T?d#5SuIwGmgd|a)aNn6|TWDJoRjVG_XET0w
+zak(0>qI-tUQw;{cY;teJl(4<pytGCwXkI7(<7|{u>jNt9kiu_2$go87OV&-W1v4+F
+zT-qA`4GWSt80-8IHVm*5pS*xW9*FTFwywI(T$Zh1PUq*V>}60iCUt8lcYN8$JMTET
+z_q;$Yd2MYXj)2AQ<zYk9&W<Hp$gQNYF-_}N^6Gq&<P?!WFh;;yOx|cM)B-!K$tK};
+z-&aaT`a^=uW#5+B{k`JB8C7Ao+t&}B3^|9em2<5C$xid48QRRx<_X<xkSsB5fQ<~M
+z{A at 4ZtG4Cx2cMs#xjs!wh~L(mBTm<rWf`B|^Rurr4hwly*%(nepV at A7ab2H?O+G)F
+zeoovgS^Hkp6JJkUzja((wNdxg-kaW$8tre;zFR0gu<NgzCLDs3EyUF~1ru#N?hBET
+zkpWGpEcZp48ZkVBkxxJQk5ZOICiO)0bEt~HuUPS)cplr+Y`oN<-u0kD*gdqil>Tel
+zORzWYD%&*}^CUf>pdwK;XVkn(<nd$I&5;z!48Mi%c;F7nxA;Yx-y{e=p3GevNjz(A
+zp&OCcciq|&%kKf3+&@J7U&cL|cwab1LV4fv4|PG4>dsm<t|dZ0%c2I><}O9hRI5 at f
+zx?jH+%<cRvr`vGrKRsPm8UJ3NXm4bL(#oEP37Cv0Gbt5Sab;x!A}aQI-c3i00msnc
+zT&3YpE9Cg?7#Gc4@!rHMsy`^Ur&(QuNmoXzmt)#Jn&8&EeVjT+U4l(tB3Qcmr1!6V
+zm&<gC=fh2ZzOk^Q0L(mcSd at nep(Z7b#rfCn`v89Gy~*qLxIua%v98SPmCys>jr&ne
+z|9}`89mDpnG{C}(sy&i{aB$?^uUdecV{Hv at tgpeg^124ACjHBaF3ys^B8^uB^4bEr
+zh0J(`U7{-VqS{K^H81yp$7?HW|C<Srz$5!D508$3#Nf5q87OoYl&8ilD}D-{)Ljs|
+zOh{#Wu5Cn>H6^8~Yhe4epJthN@@uP&+Wc{w>Ty`;8B=yaix7m0)%PwUORi<NrDN|u
+zA*#9(_4S5f^QQu3S!*J!MBTyQZZFt%5gbIqE;m1#FJdSA_;H`ze at -WRGo^Bp3w`s`
+z)38YGi!dLaW~5<V!>9D70Hcig+24Aav|8*oBL=be6|4dyJQeTTG=9x|e*(Tc+Ap9H
+z=&1mT>5r75>)Ya4X>zd!n%6+nSsUoBaI8>+klY!t#HZc7OlQlH+pj6OV`t~wc=`7|
+zca@|zZj(`O&to=BuD at wXvk*>~$H%BhHd8K;40#Ouom=2gp$5ipNL^K~b%3wH9ao(T
+z7lEMxhzUlAESE55j5Q8<4GcD}xj3FT`a-j99ba}7ndzI`ATu35()T at nI+-p@>#92s
+z*~La9{$XbLqbm<OsIS at dUUBJWb9EA0^PW|=d3lQ;x61?+R9a1v0Lg)=@0vVwDqW`9
+zdt+nc9AXj>(!s$L{+u|u?EWfCHJrMxy(!^lYrlVF*!8t*I=8u;vGJ3taE1y`0YL&%
+zS$qsy8GF;o?=^`?mxmqqCY$=R@~6jtE6uYPeU^tLbJNp0VrTTF>=tcY at nINTrenI@
+zUR(=Lr}8H5BaV92E|%IK1PagP at M7JyN(IRZTP1tz2Iu(ahT;^%?QPi4ynS&l(rQ-s
+z^as&Uih*8*9sVr;2oy#s=JPoM73aOKt~?JZBXPoAy$F9|kmS_X*WTauNiADkO5xrd
+zRd`tC-Z|&;;G0wIrcO)5pKRD}U5u%CT&*7kgx3A=R5RvNC$j!sCDFpsA?3y-dEIc{
+z)WZr{p2EiB2g_pr%4^suIb);pM;6w(!rmJ#A1X65l<f%EKAyH~fW_55nC29#&+#v?
+zlqJQWp(a|LbhqB#PppWnZi%S{|9$@o{+WF|n4YbaK&HZuX?=NqfS1y&1 at spO2<o$p
+zZbp<N3Wh}L1b_C0n!$ouj#wzelp2Y`i%ny&hxV3hb>mUdA1X88w7oGBk3piN#parX
+z_4O|)XQ=nle*e01SA&ma7t<%|h!W6H{;{!f&SH at JL1dXzS@3_CB_Z3FCDr|)Q#MXL
+zJ9oslEGmR+6MV4~_Hhmiy<3(5Nu#0gPKv4m8WK-tfOt(oc`+jZFmd1gh3Dw#2ttXF
+z`>stWe*r~@!h~gZ{3J)0{m4zLE!0=gm*e+wQIqyYvZ*5?*xvpXCo%Jz4;MFPPusDk
+zd7zt;IzxS9g_nD at Q5$PuVCVj)&jWc$ElEP``l6m at b*j9JE-T|ts*+sE*Sf54Yj`+h
+z9FT-rEuunEVtQh1T%HE2-AC`+h0xZR at 43$gP8LgV8{}k4dX)gH4|^OO9u}3B#thSh
+z<|Kzc?)+I;s1LgHoQIfV^jz!=tCo~=qCr~<%k6q?<NskT1>Ky&Q!YqtluA8uakV?2
+zIONuMhkkx}>JIJsX&n-;qW*hRv&OAh at NdR=GgWUM;&<`uaoo~qmXas7_&#}Kp>v4T
+z;?NSbI)~0>D7*gGCmWHDzv}t2x`c#t=5OS+AH7L!9{G at w!H=C4?0$K)X`@7EpTeZl
+zUwi7FDB8M2D@}lx0?3vZcq)=aC8nUOOH`- at 0(^JRlL^APheBG9rKd29;feFJRzbMM
+zedp6~Qttnd@!!8&j4q+MnA_<@7af+*aVi2?eJS#mTubj|y<}r`hAjQYr+mddI`SXR
+z)(2~7LWpJc9ZZdqOSHb+eliz3SCk5<5<WffM_3?efyC_i2{$FUv>T*H*ob^9NwiTn
+zWLX6Ff?orP8#T&8i4lKmMv-O^*0Jr3H|$XYHbu?FrADvbS`GJ(B3VEsCCwzo39>!Y
+zhI9q+Me_!>{ZbQuJePEB`x{D1eVsrH^!v~47Mk&~rh=#ekHhv{Z)2b5PPP^cf2PBr
+zv+!dbBuGAi=85@!8O!7_*3)F=xp at NI8!+E(!xX~>Yog1<K;`xTzDH3U=@)}YEk-pS
+zN=96CD<n*BS;e^_{pi<L^6vQT%8IJ5uaJa<#N))qBNlhpE&b7a^>;v#aU8DfR&`<%
+z9OV7(w6{T`E7(pd;(HfG+wHdQW53;o1gEwiGYZOwN7%xt<#1BO;M6>4!sYsg!#kh_
+z<ilK|GHx)mrLUQ5b%SBOJ02INDNMO}?`zW29&(0{{{g>|1%L+=-!+nwU{|2zcr7J0
+z20rU9{D(31Mj at Yt`<W|}1u*xerxqysTZu9&;r7pA>VB{(kPkjdTg*2`h{1TtBm7hD
+z|7J}67La1CJ98%<Cdv`!jdfTC=wN)^u**hQhGxhmF*eP0f>0T{iN7n6TN`WK(V{_m
+zR7HjTG6$FYC|?u;xm}||t9x*cfkCm`uf7JPq at ByhuANnXsH>-8LYkcb9wzzhq+J%a
+z)ZGXH9HUcZ>;mIR$y<Q))to*u>8<Z}xR5-Ao2b>}%?{vb0x^GChl`2At4=Uh2RJ}O
+zbMx%dk}}|*va+&(C~V?)u<qY+7JCev*u&C%22wN!4hYWq;}(ZZ55TlIjC2M^(-LP-
+zTf0NQP6h1?hTPBQ4)Qh_80-WuG}c=B*Y0*ej;sucAxFf69h4#XEgEA*xOO$@c**wv
+zu*ANl>$69SB&5Ajjhg0nacvzW>5(%PplQ9E^*)y9Sqzh6zB?ue^t)K{;c7p{B5e~K
+zxr at WUkOg|DyL;dNgV`ApCy;ROZ^h6I at lO;HV8-<G#iz%pC~_$uA;ejL`)JAMg}qmk
+z<0V at wBPNW~>+H4h&%xUyz7m6_l3*v^QH<$j(rwu at 69upuVZNOsESZEfT6?Cmtil{p
+zSw6WLe#MKgo!dnhC<DsR=Zd`Rn5f=q1X=5%K?2TJL~gRGy}K7jdeEds?iPC)#670I
+zI|q;L$yt9<p49xxXs-I&wPVKY at 2TV97z1!0*r5d8oHF6ZxnJ%oFE20Knu<)y?zl^i
+zq-aH#?T-il6frQNp|$h(zA^U8vw%*@n)nX}480e5jjk40(wgwK9RKyDmt)HXRwELo
+z``Xg?hA6I1+;9^vpjcxwEKD?LuA(#BfKT^X(fdB86tu<dlRCB3z)`-JlrM!Q4GzZA
+z?}S!^HjgX0Y at IE>5yXhXlO9rRelk9_ffd`$*0zLL?JF0mG(ksbV*w{lQ7Jw+Jq4sW
+z84w7U<o!&t=iwhV at hR(*<wg$ku8!ji_`yAwt6YB4S&Xnr61q*rl?VTyV^Rx6L+lFC
+zeBbuv{2^ICCeKXX_g6F>d<MgpzBeEk^q`Ey9sGE9dBaQhE>o at KcKr$|aCug|%lGrl
+zzsQ4_K9swh&}3D;CXXYG8?Q}iRBLMo-0+9)K#G;_hx+a3Pg-G`&%+yD6K7_8%8w?m
+zYP^hW3!c~=;X#NS{TGX2>~1lkw{K;<y!d)8+~>Kzm)cWK>dxSg;?9<oPK`HLJ0!TD
+z8>FkPGo((EsE(jwrd3YXY!A6y{n5Qs?oZ3XVMQ;Nnk4xKv=v8pcb+;V-8urRrhnt^
+z_F;K!Yv-<8E%?dA63i*D!!knUf`hSIos&$s#zrTc${fqKdff8lL7$FV#66+?poN{B
+zYGb&q%I<Tj&AzlBX-bS<DI*_+{V#ubZV#XpH#h6w{m$t6A@%fcmR<U7=5E~>*P9g=
+zqz$yL#%tEAp}#LdF(0ruI-VFaI}#9_4XJhxF)HHZ_cIuT2`VaxzpvKQMfQMABXJGV
+z1vp(w!j90cDV1QArHaZn!HSC=L1<EEel5Z!zW;uCw6#A-gRqa6$8IE_&J6D2*v0fa
+zttnoh``rwr{PCunmwS3lKzRzl)XF?@|Mw?<|7zpVNLB?Oe#l2pPD)~j8%yW3hV4&y
+z<uMerJZenfkrPWJCEx7(TP*OnwY5a2M{lm8jw1qcSOf!7ST-dOkkN?1H5izQOF<{Y
+zEN})LRZ(K-2*PG5FCR6f6q6`X=?+A_zq$o)n=9cY6D6D1+X$FHK10ilbrR_#zqKA$
+z$kB^f8>AQK2z$sJ{rx)=5D?J7lIKT%dsP!Ep@$oe!POGBzrQas^#QjxK*FoU&A*rR
+zGeNkNet_gQDo={%?P&6&4S#mJpqJgS><*q;GwCiVCFTBfp@#T^Wf_$4<t{FCPv>TU
+zUI(lW4!Q`;e}^a2z`goinK4BL5bn*lwYB}r%cJfrEmiE^OE=!ek-W7ae2l#SN_(+`
+zwvZ5UGFgwM^n)J)!h+DQ8r0}v%C1X>jb?#H&izS}P!YC1G2R`9G?m$qO;Eba7b<1g
+zN%nKD^@(Bv6fG*^AdC`FHk!d#R8}gN&MJuJV*i+R*l9b0c!`RN{`;<&jN-Cly8tnD
+z26hmW7t*M?sKa{h9v#_NTTySSUyP(dyiA=oRzr&7_*PGCHk88dNZXc@|L$;L{h{|<
+z4<RsdxVxM<`bfWRq7an0-R5*>!Ac)67`d&z9g#&N2juPT9oc<9SHm^=@hy2z3X^Kf
+zK~Vy`<i`Cu8&`a;^ww4OnxL>FY|aC<rL6dixwp7h%8I^$YkjRtHt|V}C>e$7jz6{U
+zBh=-%Wg$c2HU9L0MvaV%OZ69x(uhno=Ec?3;|^Hv+40l*O;@u4sL&e>el6$$n>lvT
+z4U9XK_h$bI4J2E!?v1H*>Sa<g67S5el+?(u#6za1b?2)cceI9iqoWmCpQl_4Dg;M@
+zr8 at qXp;SKT>njRoW7*U%X>n!L3%M-sngpISE?=LlP{0FA2a1w$UaT!Ff`P^6R<qGP
+zz>o4phkr at 5{Tg{ER^or(b*3gz6RuarTTF}+CsFE(ED7~cK)O>ZvRVL9=<b}fwY4=@
+z_Jo3GYfjqOUey?P_bMP^)Ac!BZ3S6ubOi&ux=GQ>I?wBV*U0vv`HP|3gg-|$&H1+j
+z<0;#uo1eE?zO at Nn)Xk%Wx5?P)bKAMCy^3x91#m$~_Rh}yUadKqQ&5IXwV}@Y!^-5u
+z#6*XOo3k3k#d<rOUW@;VRWtOwHBxDBN*6r*|ADH9rZYR9GKjR7QS&Sx-QH*Tb-WQb
+zBqialU at my$P5Cz+(D!s0l~q&}{rovI4u$DS<~MVU)ve#pH&c&(eCuduXP1Z at o-5{C
+zRKf1z;zE==E59={Zdiqpx0`bwhiq)On^yb>Uc=aGHhY<gxY*QcOWT;JU$|2Kl?pf(
+zm6x++PeCV~1)Xf_4aG9XL>A0LpSpk|GD~(~U|?z<^x}3W**c54Qojar+re#+ at E4qF
+zf+wLSBk?4IUc=bLN4GtAsmDhs#tDwHS~jp0--g0>HNBAIj~sor8B5<&o8{-ES>acQ
+zQl0q?^EGdTJfuHAKeN*zX-eKPmN at 9~+dz71Np?>EDNN#k>)3CXCrBEO<1!gOSy&9I
+zOnJ4-yy(8>f8Ae~dt<P4o6H at 9q#Xmdz?BuB4d0F6?DqC{3b?%BYeTi!-98NNocdiI
+zc$_rTeHD!W0TW6|87+~g<#2AH5{WH1>k)(U9(BCV_ZI}SL+Gz0xJCvjD%$0O^|&&|
+z_5iEdtTZ_orU#!iE}Vw!eo+*pk_hldlLi#iKvm)mq{V8Ij3M=}rz6?;Kr8=0`ow!D
+zC-htgb>SXAdcDJI+gKD$pAa<&=;VI_o<@NE3%ag;YvdSf;CSN(Jb9(55qvZ+ at kyH2
+z_k6Qg7cMt97tnwKIHMp=U32>=g11}vh%!&M=8Og|jJ+db at +<zON!;_%d#Iy($z<zK
+z<GWX}UX2y~7Z6Z-n_Ozjtp}cKnC`IR^V|WO<P%UIqY-wu_>L<B=&5#-#7->$mRx0^
+z9g@~uPU)ULol(8tH*M+oC(7{iliFKDxbJa`<J<aiZ@#|z*S#_$eopA~9ob5gSBb;E
+z`YgZc!i3vu%M3uWtfwSyR_~fzP+eB`zbH}{0vsWMyUTChhTYD}V4zj1JBlcPCL3`W
+z#CE-k+9~tZ=hOFkwWw_Q$M^@dS6!gln}Hn<uCCkd9G4Zt1#o?n3)E#rFoVm~kr_Yk
+zL*VuClBl4d9*+BF5B&YZLn{z6%FL;-wn at C^IEaY^1>&$_ at l6MN0=pV<j{&_X?~Zj-
+zxqChO_x~Jt02M-%9DQ$^zF8)o%txx>5u(UxSjXxeG(R*nFz`VHkmfqUfdL)#ifenK
+z*OWwtdbZ%i7?vohxOL5D?d(8nF9Ux?zujq}8A35O&s(R+<`j{>R~dE<oz+iLw}9E~
+zw at Eu6omVuB)6=LnCLu<R>;%cffdBw;fhk#zg|XXxPPR9DBTRgjY#JIG#*d8Hio_jV
+ze;88iI`8oCGKEIxIfm?3$FU2|q;R=AL^k8=v%UgFq9rK`5N5&q*DG$CnI)M5>U`E&
+zwnH8{&HxD)Bt*{@_1yhc41iSiW{sflf~oIM&pj2c&VTQVW)3<a3p;Z&PV==!QoR9B
+z!fltM3JEM?J#zF$%x5*Llt5zzSd}aa*A_a8<Y7gcfP=z&HRjYNjyK<r0z?VXZS<-P
+zc*TW<Tk4vdZ>+}Zwl_28M177)fhBwHXdgsK^l46HIJMF{l*lQ*!QD<{YZMScr%Z?`
+z6&B}ZI;(kf#{J&_-zsamL at BUi6kR*7=A(lorLsmoI_m1Gv&E;VFsE97QQGx0H{bAQ
+zU|^t##BFm~IbQr3(HVFH$hV1spfH$O?nI^xZwMR{{@6HEa#gQ#L|@*~f$?@v1&Qaa
+zY`~bDzTdoq=l?8$)8x9Al{ma({c at Z9VsPZYUgnV1*yNHdlEin|=2}rwV#`RL*u?|P
+zNFZaZ5#eLKq0jMR at 2sZO#QsF~5-?y#<h1Nw*~%~N<}V81SY4xqF=7thi8$V#aKxOv
+z8x~ul?h*A&7d)#txyxnii7bH&XTcRX9Yg_{SW$WHl&G6l6IU>Mn&=e&#L&nvG6KAy
+z%klv5XsCpO0d2XhK`~{i?vdi&cp|~`g#OJ|K$q*<%PLNsLWGTNM2ihU(f at FUk5GPQ
+zWqJ893U^K#YiAo(ConGq$?@{;@luB!3~|U(|BzH%TpR_QE~@j~8})DPL!cY9YF(bd
+zZ_F3QSdnO=N=^=Op at FNYIIom#*6{YXQwg|UH5}A at l{I#RIN00A%732`rISm<En*GX
+zN#bFPR5D7R15RxCxJu@`*?JahOD}-+ASSQpi|m2)-LgIYaa$$bc8 at S2Eu><O5GEzd
+zR{pu4#cdr&nx1Sgue6I#qSFS2#K4t3M~>c~>i5P*z8)dd%Hra;8L&hYcgSCv3<J;?
+zbd-qifSzWUW6W{n<68>PR+DU~|2w#04|_Ma($3CYdwvxsr#GtU9EFXIjoU>SY<PvH
+z4Ko at PmQ()*wIt-J`pdZAVX1n;?aZWHbksRTjK5Vhcm at 0BFf0l|q~CwNt8t5#!D~N?
+zSO=LSV-b~UQ5fr%j^ovsz0w`B5 at lk^yleoPt&N$%VJP#ehJ8Y+b$E|rQ1!1~iA<)r
+zj!C at z-ZSVfFa|D`#oFYdNfiyrJDd)&e;N%L3jw}!G5lSwv^0agJyJM1yeR|eGzf_w
+zA(|No&^s3^z;oz^Jzia!I1<oiwLtxWJ+ie-Y)cU<FP+>fcuh_)+Y}%V>6s;l81*+6
+zKyyJrKw#ELS9dN4jIN91!6chPsH+ms7=poy4LM2yYHaERv;2RB^Y%-VxmH_>UWrKa
+ze<Lyn{$@d|XhS->i5PTNGO at 8mtRA!o111aV2I+Gt6SmpTE3UOJVj5)cI0`D*x7@!;
+z(}r1+0zLT at Ko5~_GqG4yp&Z=vQ5hk9ppXe0k>UK-3**N3RTKP3>@{y_hwQQf at h}xC
+zVO9AJ>u7--;Z4DSQCcc0 at M!5HV>c5lkw5`?8Nc>CCrTUyjnZ{b+Fbv@#COy-+zb#0
+z<w>(_DJrsX4g*9B9LftyZ20MrAV+L6tns+4G6jBl6`;Zj8GFAxNLUgsJaV{9YymJU
+zx$q*^09930nT4y!9bpeTIknk_SX_EDTq#{$h8_465bk?ICQxJ;Ev~1jkkyJ$wabd~
+zN)rL(NP%iN&M(gnM8{7Tse%mA)+Ti8XsxI)YJ=Ee^(#4LrK2MuFaV_$%wOnq&VXU)
+z<fwT*i9Ziu6Z~S2PvPtkO-cn$))YG!8EJpDRG(Ea3%Zd10FWGdwj$Q}- at kw3{{~Bl
+za7E(L7C9Krps~llCzP0ig-6}Q7m?;cqX^}Bfh!WX0=G|#P#zIeUR!4YjF<=gn+GKW
+z?qR^Gn#zg_zI6_HZA!XG)Rr*R#hn$OLNq!xd2Q#Q8NN>)K<tHQm1HLE5Xx(Tc#nlA
+z-ObI-_0;es0K|;@s6Z&MeROoh&}+dn(sG1IA76yTf>DUu*W()*UBvos3I>dbDUFCJ
+zO+_*wBWIY))>g%;LPvPa7QY>k2L<lvbjKcw_Q`H5GN5danGd>+w2_8AgfhFsrsks5
+z$v8CPemrj?zwwT901o_RJg$h<5ikNS=%_6ZP6kNcMDl3m6^@(9807Iqkwdu_ap&cL
+z(p3VyiZ at 9}ehoJ?Siu at zQL&r{ZAIRq2zA4tQ&XRHrjzS^+7q9mfUg6pZ+9LfhR?09
+zBqZhTts$<&RDwg6Eo(f!x9I{9A?M;#)BNgQrVGHG^E13-mL4g_#|jJ%VQG17 at dfZ&
+zpRh$Qd_bO^Q<iNz#ObKb709WBzQIet-pflcL;qUje-DlV4*R+6ji%in9F$p-D*WR4
+z9M0+}1JYdpPr$_IVB%N>w2?c*#B0m9-wL3 at Nn+3blQ8jFes#b!qlX6v?r at qMVScat
+zi_wm9Fki{U8JZUeLEsS;tw4!*_cQe6IUFutIWY>iweE)Lb)6oYE<@o@{NBy#>eY_|
+QXJ6rz<u&9WG8W<g2ZjpLi~s-t
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/content/about-footer.png b/im/branding/messenger/content/about-footer.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..94d9124a3500e9b495b89a6a20d92085f53444d8
+GIT binary patch
+literal 764
+zcmeAS at N?(olHy`uVBq!ia0y~yVAKJ!jX2nV<g;tfw15;#x}&cn1H<|g=B!;Wfqcml
+z*NBqf{Irtt#G+IN$CUh}R0Yr6#Prml)Wnp^!jq{s3=B+to-U3d6}OW9{Qqx%SVMw!
+zae at dBD}#W8&tgXdF1Ldk5?Txj4Q||P0zte9j0}t>Q3<_GKwcXU1IL1kOxYqmKwb)i
+z14FM^1W<ENlOi(%Q^uA9QedMbfkrK6y#_Y;1VaOZl<o$Qp{&kq3 at ifN0>=Gp5KA?H
+za!HMkz_w^ee8FR<LO|kCD=8kZRSSV0K(T58Q+KY31jGhL29^sM+(_=*hGg}M14;6{
+zZD8vHfMIEJ>kyKAb*bfBCea9)#Rnnb$OZCKG;$ENnt}t^2;H-{RAmrhhwK)djzp2b
+z5!x3r8gbZ%5~1E2 at c6+QdKX@VenpCEWPhM|5Gf7l1lWK*%i1gliWVGBVPmjhWLYoC
+T<2 at aid>K4l{an^LB{Ts5l2O&#
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/content/about-logo.png b/im/branding/messenger/content/about-logo.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..c6e4c49370087bf5bdafb3ff801d77163db29d54
+GIT binary patch
+literal 6681
+zcmbVRWmFVQ)Lxneq>&Ek1_5CaSVB6ayG2TBDd`qbQlz_^rO~AqkdRioOKR!PWk25U
+z*Z2FIbMM?UbDsHg at 0^)?p69F9Tcu}sG<X02;F*fDyv|dE|L3^aPqWUFGtN`M^psQ4
+z!+jcoxbMF_t$`3_V^078?czU2YsA1!eA=Y;QZVw;b+hyGvG%Y9`1ttnJGwe~+E_zu
+z`Q1G1vyLQbo-nB@^0Ioq*@w%15W3l*wbSF;0BragvvRbU!YOe at 1dcMG&_VSFtLhb^
+zZbO;Xnk$v(N7AK<Y083z=%1t1j<4-23!vz#jf2-w+#Y_LPJG10O at 9z|vqIG|#mWFy
+zg~W}ZuVS*qn963t%U#GKu3V5^sNb^i+Pz+Z^2ncKv54#a;AJFX9q(|%|HG>3n6z;O
+zNhPa5=h9XUdC{Z9UZj;|6!vt5x?25A$!JBG+~h-HRBNOUs1JvsIK`L?6bs}F3XVz+
+z6#qC8c^3+AaXmz~N(c|yBUr}qg1<2O{i*|g3(E_F?-u6H9p)B!D!k{f^pvp+eT##~
+zLI73LBdpv7%YUpuh|Z?DEJs!xTAIK!a5sniMA7a}8;PjskH1cT*<39cq%WLeQjdFG
+z6U!B)??CQVbT`)T%iDZfuh67GZ%|VQgmh=}#a`<k<y3l577_ts02~My!92%_6UB<B
+z*|FF#k2syTjCPAFS$;v7k(%FuF0<r873v#PiuM3G3Dz>f*gmMevQ77Rc4k9?UeBne
+z3bWi)O%884O5Uhu=nZ_g+-69&49ns?^6uQe!!qa++*(99SWJ=!s68yLYwSg~_fTpx
+zV5=6!b0v6vIf*6`$UW_tMQJ?yU5+vIgCq-ZnT5aoVF)EuXo=CUK(Dz%W};9*>78q7
+zk>nizI at _6A8+fwGmrP!=BoOwvxDV5C%dJDZY5Oj8+!tj(N#+geeaTF^Mj1B}t#Xh+
+zj>Hq>M)=mSl*#{#>P)(mJ(P==rytS!=Z!ukM!^d>)}+W~g|&T9C^B5 at BVVxuYmX{v
+z<0O4;R}Y=mIAsGrS^|g^>0`XH7;WRKj(#$B6<zn1N2n-Su*o2|!&?vmAz=;Sk}=5F
+zn=IAOPdi)Qk+c;N+A;ZQe?`z_u)|grZkSoFj}DZR$=4$-R`1VOs|wf<R(IbgfhVdg
+zearFZO67t0oN=!ioCX(&k*+EkD5P22hvY_}*6cwI at zy;&x!k6{LE&ThN!&u^l&QAT
+z+1G5fP}K6sd&6bai#kb!5ig70T3H7IslqQ3<H3%mmw3m%<0#*WpR7QiV4Dt+ODS`z
+z>PRbm#)9(@C`Gp6evP$uu08NBQr(Dx?08>0PWy`_8iICtRewD%l(sOw?^80)jzmGD
+z+NorL7!dD*9W64~LhG3YZ9>?-94~e}*~1YoE2*k`;y2Fdvm~l!O at -V_s45h{ZEcYB
+zfA5R&LD!2r^<;N~wBt9XQ68ll4lcT5-g5So*~g?~KHO3r^E|`e1t2swU;%3ZIY)k>
+z8I`aqwXg{%@1TV-iSmm(C`HV}j{HO&UR?18bfrg6daDzcH?HuZ0HM)+nl#~oZL*j=
+zBU%78KlOYM@^?q?H-M+(QR%)=r^6{aJ9Jj9I9BlsIhi6|=;h?Uz$|x*U9H&YB2Xu2
+zJ5Xm!f)rxK=jp`%g#RJ?r*5lh=uV<eLqs-!Pd30M7W<raHsNRGqR5f7iRtg)NrlKe
+z{pt^1hRhGb-*6k3)SGf5gQBcZBo2<#F^A`gg&;Jsx8c-ccw%qyGWEp~O)O_OXO&Zn
+z?D#-FG(={$8{S!t;IO)(Q&z(<@qrYk{g@)XhVQ$V=|X6B8f2xK5#dYwnv2k$G^eU|
+ze_br9+Sp3vAkPEw3F%kn2JElftOpq8>J1&GDZNGh#PnJ9>%m+^)fw`1?>RNs_9&)T
+zq%-DVe>4{+WU6hG at 6m^jvv at hk%1lzA5?15g4^HDzC53dZ8C*-?EVGt|;&O0fLqE#m
+zhnO=jTCRR}%ji);m_P<Mi#eCT++qmK)Uho-6Vyu)(|xd~<yWPZNVa)!k;PMmMCFe1
+z(Wn6Q-+MRSC*WC%)g!%b!3Rq?w9;Cy+X`b@$AKfQBuC}s+;^FyB6 at d>h6eZJwoXop
+zr1_om$N>FZ(fUKLK%G<CpWHhVMbYmthvMY5Cd&Rp+1uC{YliBNj{VfSef#5Q7NP!J
+z5J1$K at MzG)4utM$*Zn<GPFqA5J)p4KNPDwGa_O1vD>OvbGKc=H at e@40k^W>1d+X%1
+zPOUST;<?Nyy7ePnAq=*>wZ>~|kz*#E9rvE^KwqO?Gvbj3_p()XC}MOmS!1!g&DE}H
+zgm1GSH_x~_mX_AzIW7m?Y!&s`zfR+?Fjow+KJTp1-}7 at 8t?@Z}G&9z<n>zp{t8SM%
+zm=2_ez8M*;(&96&6=gywF||YcHD-T?<lUBGBvfKOMa*SuoT9U5`|#v%tsE+A$?viH
+z9$C=oHwP5_Jm(XtN#rB3hd_LurAfY~@hqb(_5NKkIaE2D+=26kSMNsAJn6o#pu?LA
+zL1W_+v+D+&X%jjcbicU_P at VmfTNm&z-3Ol+iU(DhDn;ne%s at Dk#GZ*a<<*oeksyID
+z^dHUd*Qc>fZ_j^6Nvuz=a{h*}>(|OGF;?3B&}H;MC+}bG(n|+VUE9Cgf9qgmpCx&_
+zI|#f<vm_geS6d6aW4|U63e?<2WNu7{qrji9A1mvE8yjrfe(UsX-hV at 22~fo1Uv;d#
+zyp+whqO02s#f7<lq5O6qVfa_i058vyeOsv<2(8&)zVc<`m<;gyj6gtaQ`;EIe}iD^
+zoDX(64Z}C-`3L)lpKIRkf{B*Rza0=_cb9z at 1cMBSS>@URq(DyYFnQoF{Br^E=$JJh
+z2HXOhoU_f8R~9Bx--I9W_Oq62E6#dHiiSoO*ta6+OVy~sSgm8-Esc;G`qvWSQf-d$
+z_<bc>ueonjlDF5Ci@?d`y*7Dds-ygRC4^&ty^cujFLIFOVTFG^d^iMM1`A58&p#S<
+zarq1|R}#^?Ow5ozWa0bdn^O*PTTK~pGSZ7wcuc3`t>fpt0?({LQ>IrsB04yWFw31h
+z9 at W29dn+6c=VF{}FD%i;1RU`;<$j76ZqeSm--HQ%Ac*ZmQ{^d)FLg^Az)x5rs_B-e
+z_}5J_U13T1kSSt5cYi#v=1e&7mb3PO{iouGTX42GR$0OuABHPIK6QBdX?H at FjZLsy
+zE+Ns9ZQVM%vyt)EviOAB-?6UmLOWGd)elk~C)=${6%Q78ZvzP!Uv(!2-5TGb`M0jk
+z$=;Mx$A{1b)|l1r$Uti0RJQIDDvcqIZ1BctmW>DZkA;ZE#bchGu`J#fQk_H`M7{AE
+zkPV2de){@J2Yz0a_>Gx$c6phNOQT2S^!otAJnG%~CQ>VlqI;&@g9A)2D1AT#mrCJG
+zF!o26p$;iqQ9ldF`^9>3hXsYv>-Ev*wG4?f>9ZI`yUXkMCcrg`K)!%evx-f+_F3{n
+zYPSX)!UNo3|3*-nJ-^yz&p?0`N~t?2hO;>*avR!@2!)aE|9m9O1URkOS5syG2z1eP
+z2vWH7`a$v01$gy1TNE!k*MemduRuFcde~hK7QS$L_AE%CNWuaA=H(6$J~%kuJ7A6a
+zHgHCea0l^{rd!HbOcUwN2h&LbqORn9NP4cVgBt6L;J<XY>T&M;-<@E}1dH9DVv0J8
+zHgAQo1z2AjIMi=O)lPiGyK;V(`AK^&gz9asXc8vjozZFnQGQLLHhSJml8Nr3ZSa9i
+ztAzD<)NO$AWYf_Y6R?%}E;th`*l14Csb%QnvNMWCCIgX<Dv&)g{Sj$-D>2@?;_~Nk
+z{Y*g!c>hDz9<x`2h~XJK&)92Qbg_ZwmdF#h2Gjb=ffDHmJdpRF8brz*vR0HB;3vG;
+zt_O)M=LruGUL=6>2_RN|E^Q*RF?N^P(Qh3zVL?IPrRv-yikaINk`vnX>LzjTh4yNY
+zrAPRKuY4l!HA2%wwb6tG_Fp={#5(lW;bUvRW{1p#r~^Z+E$CI**C$9=vO4z>!v#oo
+z86BGx3 at K^70n?tG+VkB<2f|Gj6(0^dd_SwdD{mAtac#?nVYg>EchEJ$M;CTx5Z%VJ
+zv at 2oAoxJZ>-1{<3Y_Vs(9ye6!Mm#$1JC=_DUBG;h9qF1cXfriXdKb&lcDx>A-MeuA
+zC~VTcArEcCY`&V23GHJ0F_)IxGU97e&xD5v?99ei(~T$_?-Vz<;nlr_ntsRS+3LLp
+zKszV-uxD{$`h9IzOrZ2#Cm+jnMbWx9{mVZZCXrleC@@^5=6%qK+TuJUQ`+8y$+q^I
+zc0HimXjd at 3Tp+$Q2M{~_aozfvuei<q4VCxn;^Uu1lW-D1jl=v!24Gx_G^(>LfpDOO
+z|NIc8C$xKJl`*+YJq825NgKu&=%SpkM`zuzyF-2YbBxM1#}XpXc at a3?>9!rXsT{tc
+z`M7G2o_zbO(b5^jp?Otm2pXfMZTBci4tu>Rv(bRE<k`!BVUZ9nZoQz>j^CiI>6t6>
+z|L;hAkMcD~QW8^8&qrT;C8Jf(CAgU)gPCO8ZlkJ&ksH^(;lZXNje+4%${tv;op=Ga
+zCMKir6{%Uf!t06c#$d)~)<mMopC)@>BI}+z^o-E_`n}L%=FCZy3^0}+7vN%ecx4d$
+zB@!Yc)|3jT2*Sih;3r?cG%XrFzgk*oRV|zfq~3a}Pjn(S@)}F7A-FfdOJUb((ByM+
+zN|u0)b7a^U1ak3|{Mz`;6;k002pyHgLN3m~wn9vD@(cm{jhlm?RCI|viged`0A at z}
+z4lgT&{35}Sk4 at u>=8efIEQ2NVcz<R%gmDdbjh6bYkawXJ`afYY?4rgMjWZKnj!YAb
+zQ4L`<x|c$DUVkx_KS6GqM$$z_Cz@}omI9L!7giMtucIk|cU^eJxry_}bYXkC8qV`V
+zeA?JW16cwb+dWOc6-7Ia&H?~}GU(2=?-;F$o#vs&jLwc3+pUnzYDlVGj$cxR1;*Lf
+zbizdzU>py8lK54SJ(i+Bp?L at WRu0oOo8Alw?0pdbEP8OhSj9;5-c>8}S!B<HDNaaS
+z3N8CGId2Dzs_|x|yWPk5GB;3~|1|;!M;$=1B1{5=A7ojLa0ZYMdMCMt)5^gPZog*U
+zMs(SIdEDx}huIb1z=3Q2vrQQdiuwLw^-$AZR(NuT;MmA-hdkG8OkD!#o64TyAStjF
+z`jkNfW8WMNe`9HPG4P7>o6{0#1V-Qg7PnTN#Hf8 at ZrfCKxE)M6!f+8?L*<N(wq#!P
+zBSedki$6mAyueEjwl&s;)gSk=SvVQxZ5=!O3LENQdH3-OqxHRWWSv9JZ_;Y7FJw*E
+z_M;K7jNlt2H&2+v^K>WRm(t+5RnG_xnGuvU6$46FN|VZo_a54vtPkf)kqwZ(=n98-
+z<dNDGVNnFP6n>^hN=ZAQPx1f5tpitSo6~>7$ZM0xevvf8)>k5U{xRL%6x1PcuOm!U
+zN+mf9(SQ7qzcc9+R8=#kDuO|!kA2ObsC6V_ajZIQeFuejV!9xQH8KFx=cCAO3Q_)A
+zl~)88nN6fjTX$7JYpRQCN63y`78?5(44eMmY}Isev36QhB$q%W&XH()uWqN*oZ4U2
+zP!39W0BoB-6Nv8?g>}X6Ztw-u(7SZx)1s3Vf|qkB%za)V@?=ox<ucC=bb;o0y4xc8
+zs+x!SA%c6BSIDmCFZX(2+2_{OIpy_MEfbRLxzq$g`xAe5yp5BSpnmLj%VK7fc+PA|
+z4j{PTr-}a(8RxcJ0xqv9_XX>#DYlf)+}d>2AE>TAL=&4es3&7`G_h at UceVI4=o3dN
+zrCPVM6vH(Q3`%B7ZWk_~AL5aQdZ^)vo}uiW?kuO2AZj|`(<c)Ww&U1Xu<_Z-_)pFG
+z#4-izoAJnyfB at O3m!s(*Vu8?bIZod29{CepJvzx;B5=h6nX6!KPMLoD;)g0_CxfI|
+z_FT`TimuCdM_m|l>10fx?2s#0>t*&W3>Nyv#^E?DL;btfhK>7fukZ at in+i2Dtoz`T
+zO%SD`iONY!Uzic^T<^|(&e;a0q=!Jk(mu(0Mv9|BFjY at bf__~6G1DDXeO1gX>qqxz
+zz6gOj`YjT8>&#PAv>s5<#G1Sj+*~*mpv8*hNu at qEO`f_AotU*U7NI=4PbL-?G_JJm
+zkF7YF+mWk!;EVUS{9Sz3OH7*o<8vePgG%Y~@Mm#htG+ky-nSC)1jvU6BT)$9?N*SP
+z#`^xS)8Nhb-``Bqf`@2Njxtp!woc|EAdA)I%yrm0Cg^!xmgUAwFFx{q at 2Y@aS<nng
+zM9t(wmTcenTc-XpgV}!-^kZ&s)84C(dH3&=xbXTBO##!d03y6+n+v+*1eeG+ssNnS
+zt)2(h#xfi-7pRlLM at Fj&viHNW-{0MM#R($&Ct|?lF at BmCucls_KY=5a698#y<XB>(
+zt{ujHK1IYsL(iTQkDQA55H8hgapIyj<lEN3cfKWJ)#A>=gaMa|c6U9o>*ODL{+;$j
+zN9C89&z*E`%ttoFWr|X#>M4lU%L*_j)RrTVRxsKj5ZaXcF{5iiDTpxeR>k*5)>^-#
+z!F&JY2yQY<BW(clOq>TlM4V{lni%K!3)9jLOQLy{-%jS$7p>ExOhEp022kyf$GAs7
+zOx}oDSJyc(EQzrF?NrQ#8yZacRy8zt$AY7|b-I2_Jy(r_ at xFG)Ls;s3bd5?5EB&L~
+zNhVn;2di3G@?xVtA?a*w7`k^C6+_saZL}mjAECS$Z=jZ;QdP5ZZ>~E4cYg(PXv%5k
+zd14Zbme;rZ8DIG{KWTlGJ?JKR#T at 8on{wUg>;@`g|E7$1#Qm&cuVMW{@=j3luCC56
+z=4{&(0?ErL3Qu{JgUe%J;8&Y9=c@?JA8dGlJ{p=Baq(7v%C)#TT%2fE5%<5*5zye_
+zXj&VjG~ic-zS5UjxNP~4h-z6xmj}fzRIgb0+VhFH8N>$?bU2D8DV~YL!%eLny>Hs2
+zwC7WzOBjOQy=YTUO}Zk<Z<e&cc>Dr=0AOK3P#sU!%@}xXVQZ6A=ab-pD0bnF+`T-~
+zLwqg!;2>tMwE$dOUl#CNdSr~AZ~Qdh2*A{zYo-K05EIgAnV5Wv|Ja;n*r=xM_x8G^
+z^Hz_qKtyqpkv!qw!(~X4{90;OM4qNed?(&Lk&Gs(zwX3Bsh1a?x%p7b+kjt#6ORAU
+zBq|*wb_Gw(cmfS4dMZsk+c5~ev1XT?+3;a8>(hBox2C<JAOxJze&WVWwLCK!P(hZ5
+zOKw56x!)>hEqfB6{erwd1=?mc9`+4v23zrZw_=!Tn3?spUD}aNX0LqCynLaVURaMf
+zDqLHzbzHbiJu9i_D1xP?$Wp9u+|~3S>N1k8MJ~;POxd&RJ|e|Z&v*Q^L)uJx8TG5#
+zTG>-RecKra#B-djKONE)lz5#HX6HgUoUatxs;G!I{o>cVIOpgye4Jxx0^5Tct_ZO(
+zx@!inFK;;bcqTB<26&uwwr8?w3uSqJ6g8+Ha`HIgViMl;<kgz}LyAo9srCr%iiak+
+zEusuc- at drZd%e){^n|tN{rj*LB^wWrwj9TlJ;1XtFu??4BWb$^Py-7kUQguTYi#w<
+zaCDyxg!c at pn<iSS at -D)Y{_)(hBLR1Nkf9Zgj43Kg`VNj}W%tY7Y&?)+h4`jBT49B@
+zWod+Z5YEvJzTTO5Ts8Ei^h&9EL~OmHyYI8x2662GNp at oLe=5<hd2ck8KQszdgp@<y
+zX-;($7<Ns!x#A16ZXMwZr-N_c65%zZm$L+3NLWq1Ri`q-J#v-gJ;|-47nJc>l$-I0
+z;O7YbCYlbM7M{>Fc;D6RN&V9E^fCbRTQTkQ3hG_SwN!}r;l_nsVGVR|8P6H3v%?=>
+zx1;!+li89OhEs=3|6IP=-d>n{ed&cFye(bj?yUTS6z at rT(YOAhou%?JL+{RO3d$xc
+z`SIuGiLpMa at r&N~GNmZNctA~rrA~EQP)eT9)s4VI*AD2zk6#X##w2o?kH6md;#eA1
+z9M=M!h;(O1KseW7YY&R4-2Oa%--$~}nHb92isffH0<tMv1KQI<E~UooyONitb{K<4
+z`@{WmH(g$7S+J%AGkH5vZ~j_l<38h(PeYFh`&+(=Q2RleUl&@l at yYegR@@~0<M4HI
+z{ocHN(Ox`VGk6?L=ljt1iIV2Ji=JVL&SU1PY0p<@7ZB}-w7+;OPH-oHw>NAgeth7X
+zQbKSwss;T#tex(P!Sj?<Av<=!yXttjihk$8(Bhu|KEghNCoPfh>Kn$LIv~-SC}d<$
+zRr=e4iKMbCwy5Q!?=m)fYyF(0eh8S`Gsrp&w^6HKo*Y48h9jMr-%+kb)MsX|EA)F2
+zYTv&4cvd?<-pAE=ex}o*J$tYn^%AMFVsN*9v*$k)vw<}kbXqFW`PR^#9rv}dHQnxe
+zSw*K4^VFny^+0ntwca?>U%YJN*^xQ2vIm{ntuOl^obLJH8mW1&nmDOi)cA#=ViSK0
+z`xA${=~H>LKN;AC)6P~{MK^1C?#tGjSrt?qP?ES2Pi`B at Kg&xyOWS*GKK6lQMOSS^
+z6XzXPjU#%6Z-hq3ZdDzjrD4mBcZ&$@#jKRc8;%KTZ at L+_pll3f%jG-)1OGr&pBc>G
+z#&{mmSM#X!j65Z^4Jw0fx(D5dQz(W0{X0iW;qoJ8<^LmP{2%p0Xb*)Ex|&hQsr=mW
+QNyY)FD7=-gk+TZ_9|IdT#sB~S
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/content/about-logo at 2x.png b/im/branding/messenger/content/about-logo at 2x.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..99d626ef66ac6183e1c348306d7ba30970db7038
+GIT binary patch
+literal 13886
+zcmdUWg;yI-xORXdKfEnYkU}Z$POuhtEAGXMYj7wODO%j2xLa`xR@~i5a3@%C`O@$H
+z6Zg(JdvbOsBRlijJnyqVRF!3LFv&0h0054htfV>sfE4)e!azejDHv$zMEtyR{UrAp
+z15tc2%)=4)|2fI(x&i<w`~NPa1|M}>#6wayDIGTrM at u)bsfz^w3<k5=IM}+HnL1gp
+zIl5S7oC=cx0Mr0E$&a5sGf&pQslWxl-3NGena`WRkGN47uVjO$|3l`cPNjQOV9m*Z
+z-=)(%z3lR{Vcq2J-g{yCt2X55h}kyFeo1?}p|Frqjgmw5OT46d0ZCV&q%0s6 at P=A;
+zTOf7S(EXGORr=kiV%Uu4lYh2VcK4{8c1P-|U}u>|@i@}!|Al3U?~+2?y!ljbf&h)Y
+zsF@>s*D1klfP|Z$lDM9%YEDp(vma2|C1ApW57?N3ca)M^3ynLV1+IgA{a!JU3804s
+z_Tsi83vB+vs$&bsBL~Kq9dX&^&@Sq-;GW*yez{KF7=Dh#XN<!PoQ--gE~+gLJNTHG
+z5fW*oho5OWp7n-YW3)x1s|Z;mFcV(UOMv79bci(taa`lCu+ at 3Car^Xb?$0IHwtM#i
+z(R|U9?(>kTHRoF5rZ!Cc9kw at Jf2=8D*(JM<Vw)5N&&bBi9>t+}0IFf0gs#;l*JXX(
+zk$2BMMR>;Duc1hEKA!;vG(!B-_ylCT&0pLoEiXC1l;gYKKq>e3+X}Ta-O}7E+nFoj
+zbxJ(MIY+57O>mQVBPM|Q at 0IML2Ei2DNLHimnn)ZX0Jo}yu?_BkmQ at 9>Yk81>XJfUF
+z!KH1=<PIpcAQ&?cdt^a7At%*VV5LtjLy!%;NGMcREePVwcB=Jx6U2*6wBTkSodZ`@
+zM@(q@`>C#y0#!>0(VrBM)dHD8_qoittUVL*k at NM>G#@UHDKm-_;5CK(qXyDXaErT0
+zzO+<}g4qBeF1V#TNjx8JpsodH!Z5`bd7eTAUQo!Fsi6KE7Yti#_|QrHdp|gI4Pc;n
+zAF3;F6M?I>xr)+4?F&l|3Hb{_k#jEr%;xGZaF-R57@@3g1NludPeBQ at i6UrX9x*<^
+zDV15nL_;Qkd!DNZcO^axT at AUj!MB(T3v0A*1Kn%-QJWw!f6f&@^!N)kq`{h%1y0(i
+zAiTGWF0KZlMvjbW_Q+ZS5l!y(wM$?!#%QwdQ3nPSikRJDv-=7=bbVbxo8V+tm<80v
+z{B~BrTzs!iv5xxoeSdK`+f|m#;WW1ZxSTwybHSMu-8U>QR}D$F^q=rFF+T=!i-v5`
+zim!t|ypGrXO!de42q_O9(3lkj7kBYx0x-G`xZ+$Ia6S|4ilQi9XUS~8 at -Ur07=_H$
+z{yNKqb6kvk2B^c(RXB<!fxgRvqG3zIP%lYo7^#)7{Z(p-#*EPdE at 2?qb;q6nh-Fta
+zxCM&T|1eIgjuytz#{275TY>oZ7&z6t7+KW}a*V;IlhXFV<5UcVKW{<yH>1bd4B*+}
+zpl9ExGIckMEQQQ at Wu~5w?^O=BRp%ZI8!=GX0N=){aV#16Q+aDxnF4B8UE4f29n<c!
+zNb}40R<D9=(l+Pom))REsI^P$p(@f at 0b=!8ho3~ppZJD0w`t<{dyZE=8axh9dwAUA
+zCRi{5H0N8`0 at UyaUgo;Fs1a*d5c-$wF;e%6xYfjf6j6QA!8?k>`uG+&G6^>{7r;b=
+zGU;5=QyCB9LQQ{5;;4nJL1IYn1Rl-MJAcI7O38CtpPh7nx`K*1|JUXhHiS$Vh}rU_
+zJ3hGM5)kg1BgOpnN1_J*I3yV>(s-(GbGihOxCGYbW~ADN6oeWVY+i4zYD-5)zZmt(
+z$Vj99QiMR#A3d=GdSNeUAMOzA$d26z+UjIACRsZKDJ&yecW2qUF7!J;@~0Qe{GmdR
+z-DbIMpXZ?zA`E=vR<#Ml>gjx+_WPscV<Zmb?RK76yM?HaZ&;~26M%NICB0VqR*X|L
+zY<`}wR0 at 5pg?*s<kMYqy^#w(dRw)2`hQhWd<6E^2gffo6=~NJ_2Wr$<Q?m?C)GI*d
+zkZh{nnVk#?u&S8_6TK!)rm=k4CyO*b{-^gG4U(v^_lW%+*C&5Y?tVem^V at qJ_u8c$
+z^SW(hB~t91qEM>@kl96HOUC9#<o9-<4^kH{n<n6ZlfRGWpgZahRrA$A5<uIlA+!y8
+zF}DneaoBw`L}|t!1Jzq6S~~(os4xNG&U<=A18k4bt_NSM*KrXpXwc&^serSCyQ^E=
+ztzgV9P=yW!+rX`mUaC|<cKe$@*9V1>5i0k%>h??kU{>cqk0XHUZ<dr~JHzHNJD%#}
+zwABjZEv^QuyD>m$VY`ZR6&z>-sT(}|!+C`#4h_t2n%F;5ft*q~5k#sobit-#KTR<Z
+znb!QQ5IHrtcxr0gi67wSYxkjoKeoPe+`jxdA$TEZZ4KLBn4God;r*n*&BHI4P9D80
+zeMOwiHSWoUogd4ZHE{%~`z)~r5rI1A-mp)uweyxX;l;RtVy;NmI-Cjyrq)noyrZ&>
+z2D*O1ztdYvs}tx&apnWf^h`#r&D^kt7V at KtK0q0FNUlk*ZAX?P#I7j{rVoDuR{vtZ
+zjl4V4a$SXi6gnc!_D at 4l!eB7d{X-9+upLlfpM>RJS=$T8iv-kfO>sgZM${kca|xAJ
+z9znm`cDkO6w(n#2T?+RLD@|-=24vY@*zax<l5qQ3mGTFp3OEhc-UQZyJI&xo0<%eO
+z1A}d-XlDAR7q3Xf<`G>LDJhRL6qNbvF-YbN9%7oiYXY<?aGq($pOLKv4uT8ct6}@x
+zfILokJx*MY*YHF-AR2`kr1deOLvKx&-<utp5BxcoR at DyZGiu-6H1Qh9>#2hTC+Zuv
+zyHk37Uwy9KfC>)m`C1K?JtHl)pnIISA1|i>HwMx~oU17AgcZ|%W>P3-*ePaY`l<{&
+zbdh$h)pFcxLq85PUZVbTrF(0Q4d-ZH1}C#HO4r!pwb!nk-z%HJKcXKFpO0gIh~`%o
+z>vLZIyfs^j{|cgEA-!9LW!?&Kt1 at kjYeQdcfz+9I=dvwc3)w+;7F$3EyK&3O6TLPX
+z8&Mijq{Y1 at M9?2xUCv?TQKD<kq<)b6M5a2#sP3nj++cpa9Pl>qSY-cSYcE#PLfQj9
+zf0j`JilQ7e4SLe#C8A%O+0JTLaWRogJ0Mv`uDc6p?T1HubYqlRav?=$>=ke~^9pcf
+zUH1N(E<?JZYjno+I%+%5g-<^?VwtFaL#c^{46)&ZvKFUw#<hI6>;exFaA4`C$%5!W
+zvVDyg`PJVC-1l>Qt*DmSNLES<Y26$Ym|xl$D=#rDb}c+`+sy1w%VE!x;N<$nfWh<4
+z<bo-<lAmKy;>aTBkZyNN9YXf}iseF#!dOqNnV$#2KR1RYk at k<@V_Sw8gZmxt$JLK8
+zQ9a#3?e%krMTOcF6zNX$x{b4>a-+DUbL>c>;fOX=upVAfm<y;I15N|d`m=jC>`6v^
+ztx7H0u7&vQL$!^9zfdUFQt!+y0<0#!x73;TG|%#rC%qx{b<ownQi6UAWtywr#>+Mt
+zHF3T5gONdXzp4Ry%d2}Qa>CXgcw~)-&6dr#f?N}9(OR+YQUo#|@^?<ojc;+e2ul6#
+z{)Gzx`0HU?PmsFVbcnyFDVCk*kj*`6X)0&_M*C8~m#e=Q*@^dF=EGLZb at MKIe!*|V
+z-WM#9_4-W3y|e)jgWSm}*d3*2IArH|wqdJFPE%ge3UzRvhTe_ml6=- at V~A^}>>;N3
+zo-|p7SUXnp6gXM0_T{J9(+5wla?5#wfFOXSN?7A%bZsSMX7&|gppKa9+Z<nX!R*h3
+zfz{O?#JYPxfp~Z0>R1TLu2=)CfXg;gmS5{|MY(MVo2}|VZQ5ON{hRVx??d6#1M%s|
+zlS^{eRv}GDRF_$OO(<bNTmLx432OB^>~SF!B6beFqX+*WlH03`#(fYZxLunGGthN0
+z%eFVb`3zxvZruvd=N+8dYoufz<0(G^_C|xGE~At04Uy}tIjM{q8Cs#>pI~_ at q-KO{
+zsARgntbuWj at 9$0LCK5u8iNSQ07hcV0ncH8Sv#N9_ZP}VFb$vESp&!>jU!uZd8aAvl
+zw{raU&fdkCZjID@?J%o>fud!->Unzeu%cV6;(~}ujy=$b3|rmat at xsUBYXJ^Z4m;y
+z+nvhHZoG+cJPx8?c>nZ7qs!x!=PcD`c36<^5IQ_wvxk1sHzMZs4*kihR1IADRX_|g
+zk3O)KOvb5zJlkMv at xB%Qo<`Gz1FYqe+ni0*4nAAlpWjE}AMHN+e#EN_5X#x&iR`iZ
+zrh%|$Watx)-;!)8P~C52vux}F6^KY&tsa!sHJex+BSm+(#m5K(^Ua<DFby_93JpMk
+z<J%>T{?n(!)3|%Sr_aq7U(Bu;pmJq>e*RwikNl8pBUe<DzQeN|4*vyk%-3);ox1K?
+zhkWUq at OH+WFa<XGU6Qik5Sxhc<K>u;zMQ*7FQq4MxX#<>^x%NMS@~qR6ro|-J?kh!
+zhs1)(GezCJDSFq$zxh4dsJ|XHhx3<p9+5dOEI&RD_A!4`>|7nE<8~Kq>9;ZRk4vz&
+z3uGoHt+TpSR at cSNE@JdH9uP(=Z-LgNgFxBv$ISDO=6EO?2vsXU$h~Kw+0*6W#cR?C
+zh9K=m32pvN(J>6$ygnwe;F(GiMV)gT?Kx10?I!jwSEXBt;0(XLk^+8 at UI`Te)@C-Y
+zPiFcX_vI!%i|N*lOg%8|@|KE%8>snS`WYA-ate|u6hJ383M!r#qWBw`$Uxjf7#Za{
+zagkN<1y_)G3~pV_q#@$X3IJDq(E@&-Kr-{)ElKRA5x!5{A{<+0RM&E~qF+D@>H^1K
+zxSma3giN82mfT{zb`<#<EBvXdjj?@!I-%il(zJQcbYNTrk`Qh_0YN$Ici0-8q0YI?
+zDr(2Jv|lwv*Y at qz^qm%P{Of9LdnOgE;Cs>;zrKhHe);2EG6H at Rcf8!N;Jk+t^F#`i
+zx3>&fZ)x2KihvhSg9MU63p>Pp&h2jobxxE+Jw>l8?jNMe=yJl2syN0+m;Z2%i|nOu
+z^(6tx^!~E_lA(OJu-4TPYH_&Zf;<1%Q|nSmWc#|bNFa1<<yXs8D%TV^or^2O5|z2)
+zHq at s=y{*KXcyfInb{RTWeeKWuFYHZ<nd>~uk}MDvM31d at snE-*&1bJ;_o&*;l(&bJ
+zp~9}M1bb@~D~|~W&R|<HDNXmvG&Ht+U2n?`lE-_<SutL!)XA$4c>~9JH`dUoN_Rz>
+zOLe|eiR~^zX25T}*oh at -0U^i)=<k?55lB47O#B22N>8=rkcT>|d?NZjB;$GI%7)$|
+zyiFEAp$iO6MMW6i8{@C9*5PhUc<59|){)PZt1Feu)y1w#r`p&z;tki at HX+EXFAT@4
+z30V at +^`ysP-~37TgS)@wQ$48)EW at -V@Wmmo$ufTBz9vhLk1g8WesJf=uoz1hL8)qC
+z;g&MdW((i-cS8yrZkZ~J>S?j!Wqlfd%71x?8OhiAj!vn$Wz6b~?I$w1kmY*{5B|2k
+zoT|bYlYq=Kc{3tbN6q*udTde{Q?LJhj{CeSMMl#nAgHRX=eKHjG2zyk%Da2KomFd1
+zf7UG9Aa=6r;<-ib!amN&eXE!Sk6Yz<!w{tX)1Y<QN!Rx_26fZLw&D`pQC~yU%uL*D
+zU5coaT*p~FU+B^pkmEu&9xaG*99S06n4g*N#wSRjsu)dxE#{7Dc~`cyN&Cnm4~Fs*
+zjJ2?h!FK{K0*rva1-YDz7-s$5skQjKe)PlHSmWPDR%VQmfWDmwgKgc?sC^C{jNonQ
+zM83I`hZk=ea3$4AKP1Wou)9$NR!K~PzYnW;$G@?Z<DW`(=I}t~nH!r9Pg?NLoiaN2
+zv1MitKZ*Dk#U`8S6aLd53-99|;%~D#+oBEQwf+fkf`j=5l&~9moPZb3`_Y{gULLv-
+zlhs$&<J*Zp=G^D{hSU=nZ~h=W!LW;6Ngl#bEuXCjJR8#8sNt~NeUr(V=RA}pK!cqj
+z2{fbMdm~(ZlP_&l2FBZ>_r%E-w?P1h_GJP4bohI^HZL!IH^)-)QXQmbTg~1(HGC17
+z=n5e|b<nlIsb4dnbY_7RkY45v{rbJ%gSvmdp6TZ7_Hh?anY9kt#aSF)*LUZGjt?e_
+zmv7r5h>iSs>2N%&7C9yv!Xc8w<S!D2XInX?=Tv1qfa8 at c;0ZAnWX4=yMf)Odr2Cdp
+zh?yj&8~O2;^LGF5Wa9L=O;|=-CvQ8dyuL^U4PDK@^EL at YGQ#SCg=k}(N)Y!D<GSF!
+z)fCPq(9RC(<(=tg5oAtv!>ljzZ#Q($<il}j{V>-nq0R0XNtE>aTSTTXTHhI-tn(J$
+z&>!`$k17=p9Cqsf_7`N_6U{Ang6q&x?O)WzN7sF!eURFTj~Q_V^Gdik`!Wb|XkfHJ
+zv0w*eF{i;`3nLwCU%mag+ixS_1P$d)<VH)0zE_mzS<>s}P4tYf*d0~h38YyCoO+7P
+zxq7vTG3_iNn$F`tQgXB+lr7m0okFE*KKHox%7aRz=P`uswCE!=F28yKt;1+w2Ue^i
+z=>6b_PD&bl1lLJ2=9u0~X#lLga7Cv+J-9g3rRQPzw at x!i(+Ajz9Kb^=*+1ZP#xTqj
+z-^jW&ULRh{y-ooiodnC|$iqM8U~Rsb6-=<&BJCewiXjzvd_PGy7Qh9{!^v}3^JtDe
+z35|?$u#XbmKrRf7n=3~0mdZ&@9gVbeYmiRw2R-Tfo-ZwJfub6_Cz at lB;F!Jao2)!O
+z0rUrOZ{(2)luc>oCoe)GrTpNyhRp%R^x7crX|K93Y{clats9MYs4$-iXFew{gk~r?
+zdOTUT2XI~PmS at 1Cwc~SZ;+521ftu)On`c=QNm#mQRSMmBIqRS<4!6DcBU%6#=TrWY
+z3rw?}-~Mmip?|l4$Nm&XdO3=HEPr!5(Hrdo4Xf$OOXk`Zz;sxn#gi3;M=shpH*yw?
+zfUK<VY#yCjG4`7JVD^f&&(P=>7{G1`qphi2;TNSKy3e}oINH6pZ}B<&z at 070s`Hy`
+zr{M8kqQyjAk8!s^2g^#?@8bEQ%RaW0V4sA1|LDDx=k;xx^V5Z+2k~F at h3Fx;$$oo#
+zz53un7St|v at 2!QZju`DjH|G?Apar9#lZ=Fb$gZiXu9KlBl)t_v_5N>x%FvH$u4bIK
+za~s0B+sKnG at s?3|$*oymU2(H at EZn^cW}qpnKsW17_<Qy87@&Mn;=Y10tqzges|n#0
+zNPoAWK40cQiUA;~|4fhC{fMZeRfP0j*AW-4qI~%<Be<$mX6*#vb5z{*DwAQfr(Fjx
+za4P~2gB92S<F~4%D<yn;CMRf6#xh5!vge6~``zHAAbPdEvI9m%Q{7Ht<J*=mqV1+7
+zcx<Hr-=){E=F&v_+n>|JqF=`8{GLFK^H8eV!~uxmkWb0_x|od}^C;)G)RqDhV6Sq7
+z^@D|mSV4VRY^v)}-+HjSHyQhmtF^I9f{94hM<H}u{|!)IjbXsieXjdR%4Y!b^up8S
+zebtrbRa`{=Hr{p3?s**7!D$fd#KHnbZe?}vhT9r&X<8klntT`qF+y#mnCkGQ-{P%$
+z7SA)Mo!`_!l at Vhbg!b&P|DF+fyt`<O(Uw0{fXnp{Dy*^ChS%;{HU};N#<TP31xE}=
+znl0W7yHP3ci~{44{W^x0EI!jq!9rMVm_0pqR4I8kktY);4CRN3{Ghik^7P(hXnQ6r
+zk?9jMOx4x&y7YOJyZB at z-^cX*ib;gRKsRkF+<(nu$(@m$Vwk1x4X8FrvZ0$Gshti8
+zUCR%d0y6K`_`j%J{syRBMPrb+*pWMAJqg*UQIBNeFm+9U5ft at _(eT>7#KUpHnyM61
+z6<l+v31wt*obXR6J9uY at u_jK-1TZ#Mq8#X>^{QgmZ?t$IDLfMA`jHZj_u$d}Z4ILF
+zc|Dm&iI8G|K8w;@64iv}E<}7pHv33|fKH<2cUdQUi=51#Vt%8s=S{9sJ?5_Cp0)+f
+zQ%O8hHKcG><+=Tw6Hr2=fG)wn*>a>@+}rb^mg7!hJfI6u_!!jp6Sa24(6a|U%Dg;u
+zj6#=Etg$0*?KFo%KY<$%r^g|XiY+<#n+Jyu%m#r;icxJynSj>^v-bv$+I;CtqN;-b
+zPQjTDTs#9B(P`UjnMKeO$CvKt at 9zdN18I3tf0dKRnAaF{#l(wh$LZC(G814S-ll)N
+zgYj^eYgixP;FGQuH6xu}(rN at f0DZJLUd9bUf-*|RRO)=svS~FD!tSFvUfx5@(hvq5
+z$a-V4i292$B?oH&YEtQC2KH872ra87zP75bk at EnqW~?$KOEG at c?)P_`J72J+@<0j?
+zzCE74_`I-=&F0hWYU{V^#dwf1R~N|Bz<kF6US)gOFh&VC{Ms6Ti7GI?1(Nb|r&1P`
+zoc`4WYGKIaeNgA=^R}z<wE|dn%h8jR5&Ga+I$kubt at zR7lV-E5=dLf{bugys^?v~$
+zp8N9!sfn}kG6$ZBrKT$oN=&cdh%lx{O1}El$)E9-;8bNqH*m?>$3D~$0Hn|PQm+LR
+zNUZFA=>Yj6I!o&y1=c%Ji%3=aqEdIMyP{2I<vzcZV94O!E5GC7S_?DbFzZc at y(-!Q
+z%&7IVQK#gw{W>**{x`e_TQ^^)imMlD9smbj$SXX2**QcO@|NiS&nl&y&c^Fo=%%W-
+zgYav?qF_=Vyql|nZL)l`i*tXT3gntEZ at tuA-Y%NFBSlL`4f%9kyp(iIjtKe^qcTY&
+zP7~dbkUk>LyD at jcrVjh5<fT%6q~7 at yawFC#aS8jwlkOGINYkz|mQ-T{_t!O;;_qmT
+zvw4!V8H#q21O;)P5-awHCY7SbKXS4r^z>OU0Om8YxdTh~K_Bl*9%O#!@tdJ at _tn>P
+zM<c4D#|{Kh82U?_KRc_dy+YADlj6$L8J%ZoEEPlvA65mBC{B at z>lvjcsBW?ACKO_I
+zmofs_jJ=V<$<$qkXt~XH(Ydb%Xponf0HtZREFXmDo5C~!J;<eA2QCAT at FEq?{KzGR
+zr(tzsRS7+zzOk646pjjH{O<)t5;UWQg*-VrTCKk&*AokG+}QR&-S|r;2dKZC-Mlfy
+zMOoQL<^GV~o4x*K*HNr7GY;H?`RSm-LItq_rTc~xAxk8v1Xf#;(%Y=MUJ7CFUeTti
+zLL=9?2m<rfohg1X@@^$b9x8k#8%vNKn+nLYL!~BM6OWF at x7?2Y5KpIj*JfvTm1Q!x
+zdZ7^O2NQjyd-sme)h at kzUk#!WKIpSEJ>!%;xj2QeDNFC_%x>DF%|!xdD}uRO`@qPr
+zy{ZW)1al at AIT6*-y&cZ&Ingll(d*<lMd{K9*y07dJmv*}`WU$p at wd!YNYuO|LQ#%N
+zBUta%se<syxLqu>leq!G_bh<70}sm7H1JujWm8f?HU$NwuBDi*Cx#hA at r2I+$*;pD
+zvu+ugI&9xL84tcRQnNux18J4VNX7plpLfddXdJ(e4Srlo{Bh8d^R6fgp()Af$N&zT
+zAowd9<e!e;cdxLsgmY~){OCzS8NAOu#mM||BJH&0Ov{ezOP2(82;|z%6a45Iax^{^
+z7a1PxY4TCQ!+PP!Ul|;jSykM#_;{JQW5WwpzDE%NxKq>PUm|<$5BFisGjN<XfTC!Z
+z2Q at 3RDVJB!RAQX-0FBL at 5G5Ixi-^OtXZ}07OF&v34#E`GV0F!DYiz&TlDCcNF10zV
+zemnGQsQ6A<RkT=1L8Ch8q3?&k(Dc!wzRayK`?xSK?~^-C8n-t~l>A8Q-MduxBKRwb
+zJr)KyDFBdMh0Jjob%nk3X6OxfD&HD7;)0Z0=s-(3axg+nY-&Pgo<(RyC~wbedJ#~p
+za+&q1;5jM>nU%4{^ecm<3cV7TtMlSK1b9OUATdR98t>rwE&M#19ha at G^d8H_OJD~Z
+z$~erdv?kUyp?n?qnlR7+-wrr*>6`B5?Lm}>FBd#x`7sp{iTUcu(9;G^_jH at l`;3OC
+z|0&`OA(ov|RSoo|98cc>g~<Am at RRmi9<x2VTI!~^24HNJaG_G`0 at q`Fz`B*KFd+0l
+z$=}tr|0!o2AZ%X9yG;H8aD=H-JH+jEb>^`t?J0qC^Q=3HQnra=T58 at Kws@|O7&8+}
+zWTPx;+_V;N6_$q{UUI)9n`GYN*6H!W?f!K)gk6+_qcjFdNQ9yyob%{8OqEi5n6&FY
+zPIRGoiTf9wQj)=YI^_&hv;I3}HUDBo-Va6A$6~5c==naO7hSK311F_aVy{|6Ly!!3
+z*frUUWXCc*J}9OlJgtR+XBGTa?-pz-W<-D^aUiA{z+!JjAG08H at 0+ummBm6tOH-KP
+zjixv>X&?sYv1#Yzws_%pJw448Z7hg8ANMRu+<SO~h5+ at 1u<#k@>bXr04-jr>oDM6{
+zjhB#Za6s%|(8L4?^=U->(QO@=g&H1}7<YB2GUT)saL+g-lP=(CdGMHfGn(j$hF@@j
+z4TzV at V$aU0nr2hS3IY`6puFW49&06KNr!{_&PXNT&)?o)iMtvYpkgQf#>pAa3OU8X
+zCk^$b9TlR|<Mv2_`-};_Eh?(EXCPvQ*bAsIlmb>)mDzs|Pl*Fa4AxK8-F=$E+4Bd4
+zb`4T1mqcReQiA)43v1MzR>8lQ#GvI at 2UD3o&D-{#Jnr$FR-teLng;u6o>akw!9sJ!
+zKk6*4T?qIeF_X0OiC#bDAyjIoZWV>KP{$OO+175Ffq2J2-M#KoZVg_%=WxU(8*o&!
+zuObKogw_AJ01M!V*Gs&$%-$x=DoiZ^#eFtW6t|>SiX6RkSj4rECpZ$jcku^@mH+Po
+zGZ75zD!pS2^+f`b>j at cz%T12Q>YB<D)jRa?%@Cn=j}!_2EGa=dD!`w%P)ynCyY9BJ
+z>c)C=i(9oH0VNxHJ5nbZVJ3U2Jlo1lT*@qan4&wq5OD2lO#uffxkuZETw`f0-3D)k
+zQQ2A{0v^3&Wc=NHDr9HD#vKjUw+8Oc^3Yc_bR^uAh;_R9i%yy`d}r?R&cH|NLNMvm
+z!=Y>rqJ`6l?=_%&xRw=anf2eE?FLEdTh at HjdErzqHlBuC<*k98NES^65y-&S2r+?n
+z%+-*E0o?+Q*YgiO at X{x<!|hqfJ4xlTTEPPZ=7|*L at HeYJXNlY7R2QO=X#Pj$MYSIp
+z77iL|V1)(&s at i~tct1yN?1H%W-akE>(cdd?Ei7s^e|7f8yTbPI-|E?aR&P{mM4p`L
+zw=_{|Y1~`cS9AJXnB15Kkcug_P;~hdaE(mDUn<&vl_SfBzF>@s!$`S9kns=zu`4w6
+zVKpPhhpnDitYurxs01qz&)ykF6eN>IWn=<RCPc*qHy7GSIdojoI8E)m1ITxe3xl1n
+zI at Fsq=8;vgH&?!uWUgG<Kd+h}TF2E7^7k;#m^y$m1>5}DPbnvM?E6Q#eTx~?V34yV
+z4@^48BB1X2)p^LV)0wPblP*@3jyVEL1Y^c+VYv=XJy%?soPJ96{pz>&hxaq_SP0g%
+z*f2b;5G${3xHk8~1Bvdr6Vq;{ybIRK9Q|W!+Gm(y$?T&`@BCGrse`^ty)pX?U(_F6
+zs~$Si{b~0_;!&raMXkHo*Xem}2Y5Hg2_q1DL^>E&M0fUtzTs46B^u9zb;)6AH+|L=
+zQ{9=-DE$?Y4M-mu>XG{C16q!-$Ox=EwgOOGlJHo)=$)R-2km}n_WHs3Aw;83UWjy3
+zSm<Cn&7CrHAsKrM$S)WDqKXiD-?OJ7Js2agAhCaLCV7P{yQy7Y09OyRn9ESnDB3|T
+zqU$DLbN}QrOZs;|3u!r&3#~s&q1Elv-<{aS?f?3f6ymvWXI*{k^8L<;cUH~&l*6?u
+z{tE#3mZ-1XoWKw;=EgAbH-4j#r#7axSiMOu%zow2XNUcxZ{I|RXNGjQE^vlk`;Sb;
+z?y7w~8?iW)-0G*B{CSgAfE~3K++ux7&%SLU$gkhhq-PhP1mn^N^v8z8`gbAFQ5o$f
+zIL|?f?f0SL_9u7X#{gq>?E6;4*%<Bqo%{jy7PV}Vv9+DND1XCy9DgHlhV~!Cba58U
+z3(i#@{aeTbO3vuw2yJ_<oD2+x{BGxGu*7^9HII9oIx>;!l><p7NV16u6FzY);-R1n
+z?eUA{(frBYEx-xd9u!#s-1$yV^7C}A?eEo1qQ<?^peN^V7o%Mh4Gg9N*GqM(|FGA-
+zH at _SamvhyeZB=7Ei#v*X at W*_>otG#MF*ZFtIgK~_5uwTgeDb}5_H}PV+0cLlvDs38
+zUJIo7vJ2 at 6^Z;rKJ~mMwB;dsw+2QnTKeRlqP??I_oXy#5kXvRVEf^)2`cU70A$~F{
+z<TE<|sKz}1Jr+g#v$q%o2fIgw(zU&|t$k&VG;nZoR0ONaz^>F_`rI?qHDGm$GN4d>
+zrTUhEqW8Ie`k at 3h8pmntjoJDV0%@Kl=C<wxtb^qm$pTEqK5lkaY~wN+0g at XC1F(gS
+z4xVO%y5cS9*c}&G@@VGpUk&|nC^Z~Ezx6f%`uzr8K4r=#^&hMdm&U63iE}Ls#*eUc
+zD2)CnK!ixX`^)BPDHYCV=oFEjwbKu!@<=-CTE4(r2i|K<=H1c2SOdJuR$HBd<02)#
+zWWUMO<gug&N*xHty(O>5=LV3wA;Hr-r)Ir}a at 2%=@)5_uuGu;oUh~uA?ZM8%C2)Mi
+zq6ULxr&`s}x^mH1)L&a)JWNj&=9Y~s2lqBmw8<jbf43Tk$Q2OW2^)Yz&LMr$KU?H1
+z0Zv4h<T=gXxnk*rA!W~G=&tAXvr`R${At}mUQRP_%o2(A at JSp0GmDP(2aKnmg5(g1
+zXsZ#Tq{e=@lV$^8J8~mw_WU+=rl_ZS-8`+`noj*cOSzN@)=uQNzuPIp&Q012Z^g<w
+zR?61dtrp{jgpoW`LWK={TAX(o&;BqCm`s6b;+A<V2 at L#5Gll4Sal}k&co`(AIt%mf
+zM-H at ZLJtIt@?y^ZEY+DT6KqWtn+#;%vqjLr-A{FgmOJi_6?Z*^{dR*2n^<D59~Qml
+zFuM$o(%ulBw0}Ke$I+AN9b4$R%!n>t5JY449to2 at v9$>;XXCR(5P9U1NOE+SwRDbb
+zZ#0<!&ID|^F%K`X1K8skDBQ~Y**YhlJG{^zlEO9SY&j!D^L=V!0L$wn3#>@!Wm>Mc
+zp*W|)>?4)2f-9GS+X$ad%ly>L5hza9T`|qtpka~I#`lQ_AMK^l^y7IX#PxF}K%luu
+z??Jw<uBi8FCTfpQaNhnZOS-^?jQrQrr>)1j?!%*H*o2;5e!z`I at 5~{gW4Sz1vnyfU
+z7c)!V>m<|`gNrcdYnJA}ZB=YV!O8cgXoxIcA2I2e5 at hCchCSIRu~@4wE(#<;JP9)p
+ztA}oGQDq*HZGSlf^>dd~h~4Ho?*~d_$+aqp;Sd=oo^w78H1)P at qBGalZ^>#F0|ctH
+zUS0-S9r%fwx at lv{Z^U5xf}5bY!LxsF^Lx_5U-9KXAYTt2n`7+Puc<P9^ei5 at EA`B`
+z=;D`Ol6y>c-E=PegC{-heSROCYVq*(Hp at XYWLu)`l|tQ(8u9gH7VNj6C>~oEjXg|=
+z#9{enwd~$uDAs6Rj<&bh-=bpl(^mBP3K#5oNyjfX_3zCaqijP^FQWvx2M_<)OUxaO
+zI_&G{Jf<OXq3Y*s)ODM0a9-Fu)$(B)RKdm_ea-NJvp-ugqBs<U6CYx at cPBywxu=v~
+zCdmcbY;5%H`JPonkYP2pSE41Ep=h`JV`sT|WO$;;vBHM}>e}UOvaG3mOU?W3+cec=
+z{(yU+$K~|(CM_g5Q&!5j43YS0s^(oqkE-1E-?n$g#(Tl0^jWP9h=ub=6tn%hYJFy6
+z^}eEf5_mYfxZYGjq<GUJvXOw+V@(nj{hbm2q5!h0wq;M}x~&1co?YVH)Lg87b^Q;~
+zH(9 at m+}ai$4s<^IPJ(~tmRKW&hbO1rzjO#%H9C*m3HXwnKKxf<xV3+BohAQ1KMLg=
+zmV-fS$yq&|K|*s1*(9|npajWmpoc!WcOZqde7;}!KJ|QAE4*Cvp;^}Q1S9|KUY`iZ
+z;S7<7XVL;d{$eO~6(%i1uyaTaR*9UP$*-<@f at 9xXp+4NqK5&W96xI-DG8+Yq<Sn-j
+z*)kwnNH^@Vp)44bo+#KLXb3V6-(y#;?E)w$9~teI_xDfEvlQQJYJr&75z&hg^rLj%
+z7t}8C%a?*b2!e!_D2_?{W5m{vq_a(|N%ui8S6upam-xH;#cIP(DR639&2C$OGAeb*
+z?kLypsQmNOu+~6=3Mo5eTc8;)^ZtkA8_R$u=a1)?4IG88j7;hP|Fc(SXt|YdR+10X
+zczaWMQMwju$+bjLCpuw^b>uXx#*BY$CcCXbL`0n at AX&lB1pw^&@7fvV7eSZmYQ at SS
+z7F0+ac^G`caGjgX+8x4yZyiFQpRF}Hi^=XROrnP%*_O`*ak!a=TRc_o>w55aa~wy-
+zsJiwKL#?!XvDgJXjyZ6tT$(@UkVLj;^x9Js2b7qJRwI}Y%7lyn&RPdRIc;VB#_~;X
+z16;-E^4rI)z7z^_J~I6#q3hF-Z=#)~Qu1e6&jyc6DiidsX4}I?00fsbvBdgvxWiB`
+zwjZt8DcgBN*weMOlmcYBg;ispVYa6%;K{*=c_<W5#s|xMV5c}ahaz}QjEMXJ!cu*_
+z6dUo$^p?LkA8+c<W%E3 at 7%10|hWHN at lseU5dAm1KKX+KN?dz-?dG>>U$}{;OIsH1I
+zGMDXd=-F&EZy5m-g?1wY4_$zwU)*lQ!PWU~<gMN?+1L+_2@!2z4l2L<1Y&94IuFOf
+z#22za1g~<MXFGw{yjaoq5(F2`J*Em=7nL#YoLa#1Lz!HF at 1H36&x at H5&@f;Np<$^q
+zeEQt)6&pl-u=~~Sdl6cG=@gwY|9fM8zE1?b!@P%3`81@=ht1!Ox7DMEW&{elSY27R
+zX_O$#B-acY_}napQZ)R;LRhPMYXus)Re+C;4SAaRvc0ZJ67hOFrYb&bVo6_tly5u1
+zD{(YFAjewFQD_yFc>#MTfVQD)gAf0E&Y_N~=Qud|E0Zl!_|}=w-)99@@1v5AjV$O~
+zhGsbDL)esAo>;4?a^|<WhOpvQL-E7s*KwaY7RfT6yerujjc`7;@NEM_o!wg+>1ov8
+z;oe%V5*VsZM2jV!W5Z78a4s?OY<8Bj!)04Y?S7a&80aP2Rn-5^LL#UvSrU^f&?0oY
+z-jiv~yPUi2th7UbAbQVgl3!!Fv$2ED>PFbeR`)>)m5d{#;#TzUoHPX+>1fnHgk`yQ
+zcG`S&OCozQV at 6bQFhftn2a?S6X=vyoa3I_|;m;E)20ac?)33U^n1OZHKl(pMhJ*X_
+z$Ac!=tLw;HrOOl-0JAUbG|wb<;Qj!82uCa7umD`9Kgr;Kl;6T)kcNiKz%ccpE}8Qj
+zy2=sO+LqAtnT|M6t+HjLi#LTfDtr(hhs+lgllL;^%-QA}CRZMh75J_HB~rG502 at LW
+zHuci*NV9%M@!>?C4S)-dW_yW{4e28R3laO7dXZ-!xR4R?m|gZNGhZi-syJw9;IC1#
+zcJst^=liiBz2-`C2(*?8GNEa0>h-$RHW=+CH1gR_w~g#sp0W14k#2UNN03IHLWbiZ
+z87snAlPX{*=`#R$&fAKlC^>Axz9@#f8yWC0gf;Z2*WU020rgk?Rs0d*;V;-5F5BUJ
+zG<r-G1B`(@kZaE%j*A_n&Pd^TXJl at -Vg`P={&r4ile?g(aQa|@)A#iOIuL5T1CXK!
+zxfk)znTuG7S#;sR+8$o%8;{X^a+r^8DtYTFJ+ at G0OPz=nL1`$(cuV!$0qEqIenW1e
+zEua<Y`1T&SidXTAu at ych{gNd*-+!t4_~xu|-2E<cv;{X)A9u9MTQ6?-2T+)xtMeE<
+zwU%RF3<Ldaw at 0uhuiZzfEwx&D3s&``{R7xqZ)PqJNDtqF;?uBlP#{iwhmSoZ3*XLP
+zJMDdDsg#vkifq0OK)<^+P8r{GhuUl}N`D4?B0k&~o5B<RUYnQ8-}=z2?Nl&}!)DK3
+zfjW=;@^@TwG=im>v at QdC9erD24I+!`PWsq2>d;~F@!XU<`gOHCBE^7YpfONw#~$-A
+zrZbfhc}hMW_w2-K_=g$)h4rinYB*Ma)<bT#Wf^?*Z7ONGdeDggQ+OK){ld}eb7ygd
+zps7mmAFBzEn}REFz<?R1pT%05l~Ys^jv}9C_G>rh1VrteI)X_>F9+E{tEf%Tg!A6_
+z`6TH+_56E6*|!n>r^QnU9FAgwchps_KKG63S4FBbC&4x_)6T!i2c7A0SM at owa;$@k
+zyi?|oO{6(7RwbN)t65Z0r~WYb(h(>jYW1uwFrtr6$1?2Y=F6(gXvBxS2M34Z1 at Nz2
+z+17|WM*#F6X>DSdJ;Kl}i at R+ertWqkE{{**_v*Bp0T;4BC4D1$rx{~CS7}G$f#hVV
+z+Xl!?r+v!Z-=_}hndzG8dTB>c7J@&X{ubEP8#TmYk>o!clKcJ+6!H3I<2c*k-Te?s
+zz(gR~(=n-*#Q*TK9s->Shc#G5y8Om<rhqax#XGW{KnLTIQbA%P`~IC;S8XyrJi_n4
+z74(T!@i|CR^>w389 at K!)n|)*3 at h5MNcH|nSfLhdZ?j%eNQ%8z}w*LJpv$agk*nj>n
+zg0-cub_+ACZ54+3YY1FbU;Y=dFqwE>wW`};&9L0f#m%>|{<^N`vl*uDNNG|E>K-+V
+zW=`z=5&Z(*zp`Vl!k7*&m_%O*zZ$~GS2J_P8tsd8_TcRQGN}|`V<r7A#Z02MOQi-D
+z*A<~6d^X1~Q`hI;`-8ui2{6urGa?3=+aGwEdLl~^79NU<>MIT`UVk*&)BEr?j9A|!
+z(%Ip4KQd55q(3nMLjqS1Hcx<gt!i?f(8pQfzh6n~%X=G7;^OmMDPv8xMn(xpXHK;$
+zXvI18shfhU<{LYMt9BCyT`rx^rM at jm;kIF{0;$ikDv3VVVKL-vncz1YV-p>7*0}d^
+zcwbLdf4xT)Y<ZW1R39^BNVfI0^c;?MimKK8Z6Ar^Kzjkf`u^lhf0obR2|n_cj%M0r
+z4>$A`{gxH!y0;-fY$n8nO^1bo=89uS??H}<s(-L)V$aDSdUK||lp>txQ7tHIPv(N;
+zr1iEg08&1+5a(|%cly)c7UNJ~NP8N%eYw}lA&P!1?6kL;8p8Q@;FXHAt(K^Yw&;Kd
+z_st{hmxz8;P!4haW+dJV;fiN at 61ap}MxOTyIq;JAC4fK1hvQT=KSz1UR!axH!UsNq
+zNO;W``SxNHOL7}-TfQP1b!$$8Sq3Vh6nz$PLPeEMbo>RPa-qgvyC(6;4G8=jjM8mc
+zw>ck*yh3@)jJEC{O6Faf`OXlf`NT$#{Bpxz-bm7aFb3AVK*~%K?q49?>F?*qdp93A
+zgyZb5C+UmXZ{C{~fvVx`5D_egw$&vaOfJDCx4wue%>+R2#tj5v00FpPJOIR094U`J
+zaDQ(~|6x|j{ic+Mhy1be+AwJk;j2Ahl?h**DXBV=PVI;G|C)<?bP?YxEV)%#+ND}W
+zF>?qtJ~9BX49sBGg7aJX40rk%5}CcYeYnJJJ-O|@fB8SW&9bR=8A^XgIkggxX=rkY
+z>K{>?#~yWhB{EWEE+Yd9+ZfBYXZ=Ly!Xm)}a29j~XymigsG}$^mq8n{8Pzyfc at qb+
+z1Ihee$C0^Ca|beDR-2kfcmDr-j|(>H0jJP_vMJ)%azAnnPz086Ouk-8NviLEM}>_y
+zD8{aFS_OSZ^cU|!&jNV8(E#6n3 at D#+jK~M^H2e;iZOy7dAg(=ArAc%9k>Rs(?4U6i
+i1I_=1vbpqvH|z8$)kZMoi1^kEASb0PS at p>z=>GwBVb%Ho
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/content/about-wordmark.png b/im/branding/messenger/content/about-wordmark.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..52923b6cf08acd09bf329142cab8066a8fbe4794
+GIT binary patch
+literal 3754
+zcmZu!c{~#iA09IdA&ur*ku!Jhb2itIGr8qzYwk0W#H`$Ri;{k3u2t$M$6TdR$gvQ~
+zeUwnFxyc-F at 1O7I^L{^{=lgu0=db6V?;lUPy{*M5E)gyO0C36 at W$Fk3uqgh$FLAQ}
+z-AiLj7ylAl6w=a(^Y7f at yq@+~gTqm7Q2+pN<-cHQjCTzBYYIo3xkg_J!$imWMxp_+
+zv9Zblp+QmpzTs%)u*e%vejA7Y0KBr6rU<87CG at 9p1jrY`)OR?rWDfg1whu|15uy?4
+zY99>A`FNQOl9aiby+gT-h&1&5F!oz}8OfA~i$vl~Z_ehvh;XovKxA=}`STH;79X-y
+zc}$M?Z(5IxT-|y8>*`JIc81ts{_p1=|K5Hc`Zkuqm}O0UzYwk?#{2&$r=WtB%%Nqu
+z;Q9{KT at hZQF)r}5A3&5Z^XCE0vcPut?@HN=Z$VGkm9 at u1_2*rE&iQ!wi0d(AqL1DH
+z48WIZcg_|HQ6;Fp)LE*Kuzrww4;l0is0zT%69VHaf%q!6i~=nn`-j(kZftAUb?9{F
+zHtL5<4V_)dx@$7Ta85m at TuJ(h9DgISAMr6_aZ57X7dIFNxXr%S#_G!ZhQ)wakv2yZ
+z!1f+Iuqn{U$rpN=bW9x_y6^kM$_E<$Y)}i%Vhe0fizqorVl;t5*(t2Q0iQri%OUl;
+zwJPB}B8)%OZGL|p))~1lmOVfbOX*_Bh~P>#Ou$<G`@S4CG<N><JdWSLw`bLN6bNM-
+z1&sKO57ybGg-o#~0(k-5z#FWLrI32*aMgqOL%w}r?ErNb_Hkk~1!`yH9e<}?_Mk1{
+zcYT-w(E~FjPwiPLtL at Ni5{dg!aiTx7ey<;AOXZ+G1y3-FUMCg~YSkz0g2m5iOu1!Y
+zoU5Wau7OgZ!5+Ahg)M51M2;Fjx9KS>rHvB`?F at w~b9^$dFJidX-p~tL!-dY4t(0Lp
+z7pR_#+xS~t<K07{t{A`^cZ;2OL*Gi#5p}yloE8UL0XeaFyHN}|A7LjjP+mYN>j9Cw
+zn_x!8Vbh!WZ+*HkwVL-G&WYuW$m+$$?5J!rr;h11Zuc-Q)xf5T at HaG^1uhfEG+Eo@
+zEGAqw at 26KFp_c1x#cuHXg&8U#m-`zU0 at ABqT6j>VVEYmaetcR1r?S{>&zIEqZAxeK
+zWFg);NbDj$g`Zz2xmviKlqx5tV3{dI^~R|u at yd%aklXy+-)rhFo7Fczc$p(79_X;*
+z4;kvztyys*NiU=q(qSCa)*G027DV)nwOa6-<iZE<w)c-ceROIscB`2K at Hm>^c$x{Q
+zR-hTyMJTAy4~K-?@QAuNwEI3 at c36AiBHgN+JhpIzvq@-A<n8i2bj2FH*(3_kjNQxU
+zxBaYR?2K8~OcW=$`yHrWLTgzTUuh<BrA<innz;`RC*X|lJLVmXhF+sJhN)WHjD3s(
+z*cQP%sXz?rG+3N&EB_JPvSCN`md5-Xbw3mzLqV?WYvteEj4gv4poM~+%L&^Ykg$|5
+zz*|$vPu;M+1iKrApFs`LS#RZEy$?hp)<x|Nl)*WsIl9V&Bpy#)y_y!|IY+M6CiWN(
+zJyI~z8sd4x_6YyE-f~1R;PaTI?Ays3Q)^+`r)jDxvc>H3MIBfSYfPP;12%VCH6rdD
+zHnq^U<()MLWVx<G>|4-Fl4JhXNqycKSW at zo)-%je0)NpT6x=!I4rjC?<$WOT^HNW_
+zEJ`$&?krIqelA=)QVzkxes_6e#)?2=)g_mq2J3Eq()zMLs8Pp at 1{H at gGRGzz0@59a
+z&MqHLEgFQ>3+NWNK8hJ*DU~>leFZ$c<UhyWpT9(gK-mp|1}QVCtGQ{hUOzTr3sO>*
+zrs6}CN4zhz-K~E6)rJHSuKvO+XVnjPEm+9Dx!UIT8m&*zqhIxTqN=@i3vwqn%6A80
+zt1DVfUZ2pioCU>neX8>X6(lU`)l{Oyn!(5Fu4mc@##KN@$j+~D$6NAZ4+H0ItSQct
+zai+R;Abal`#RYyspk{>gAE)w5{BVa#u%O(r(?>UiPO7FLsNgLoO at _zsD6;mELGq=C
+zS~_R;H5m1`2{?o4<Rdhy%j;s6v1MkcP>6H6 at S9WZop2$qzG${z84I<x79vk|)QSsH
+zHL+GaqVKx(>DTO<s}s)%?Cfw)4&fP+KXz-<m{W__Aj>+V$uC{x5B0CHdRpE&as;aC
+zSDkvI0Z5ei=kR>#C#rxoW!980Kk_<<&$UV3AijC?%w2N<rL^&ko!2C!Y5H82bgRs&
+ztB=42epkyCU+3856IS(bFgW at O+$KETre#Cby=s?o{a>zlwb$&)L8{gdkEz=Y;$t>)
+zupeC_4VU$Spn)w-gFg+3&bPG<9q|1X7vj$@q|>7VJSUUawD+Flg18TS-i6%U29Mm-
+z5(bu}E~++><~O at L<4{XJ7tB4=e`kiNPh9{ZY>E+kN5eMrX26Rv1N6J9T$L|-4%WVM
+zFiCI8!gXy9-CMu-nZc>7bV}6`WuKqc5M#lYr+_;lO$-|lBunkWdpO`#Wq`!QQ8ynB
+z$XxN0*M at xH$jp4D?Duz~#Y;0vUSH4)$<v9|sg<!w)zq11uF6e6M~h`t^Q at 2m%c|5x
+z+LihHE{BglIy9PS2SH>=QJmjv+0S^n9ZL>pxSins3`Fy;TI<Ci(+j-v9!!8~0F2}Y
+z=G4NM at ocQF0hrdlXWV~?$IX>rOxAM(F!>j(QeH{8zg=ME+UwwYFD)md3+~nLyB}bB
+zW at i?ks9zx$%^^d)d|aWbKlW`-ue$<pD<Uad*@(HzJHGdYmFdY}Yv(N6P}DKL_48ir
+zV0ACq<sn$f{sjT~>`#<jXuR;1=Skk at W%psfQqfGrxS-%~Bm5`kGCNah=GqbzPfsBV
+z=^^$Ti_}64{qc at il@Snat*1N+esQnA0psfNz4TYYxfAyfXNT&jFAfs5HE!~>8R!bq
+z9D^^xEFqWcTsSZ}-Zet<TKgG0^)D!7(*V6<Tte_qsI|STkD at ziHl@!e#iOni;y>Kj
+zrr^F*)umD4(RbrYgJ<K6?+3!fEft1KxvQ6Wv2W=;v19g)wgxfh<s=5aRpJ%m?1?jM
+zu8FNZ*H5uZ5lQzA-ePkXDCWGt!O|qFn&P(svMS_ZgPGb&+ghX`2M||55Axo(cGe|4
+z(I^8Pat>hbQ`VmctfhN71i9Y!-Q|CRbG}Y1I2C{f<F~bBo{jxrnM<W(bnw@&vt^Ud
+zH5PR%SPS-L(NI1-T}z?!Xh at A+vbj_X^q!w*<$z*z!d`Ck$;CdGHQ|TD*qxEAzd7w6
+zr>B4C?1S7lJo^Cl)j>ElR0hsYEEKLJzO_p3AIh{S at DsEWBbek?Zw)g}R|<4u=;#(z
+zVd=@@9X;!QUl7_-Ph at -rvYz0I@SN7ug3ltC7qyqp$SctWQ9+H>(jKLxpNYpjWNyq+
+zmkn8>rBGSxnc2iExyNg<`P1L0Oo3eT8u6vZ?z{?QP4hhUK%Ae`wHkFD^U2H9HcKyU
+zjU~rb>jvQ%?=DKxl3TS&zB7%zkzigmdN0TUqZTX_3KR9#OaeDK5VPczQX8QsK2wxi
+z9HWRyF?i*U=jWeAf+^rzbC2+~BVR_e6y!?0GWwR~q8?d0uVOMIPe0TmM%KPS{@xQB
+zE at mU>XXXu#8%q)j- at B(KhPSYum<Qv5YaETm^6aH$(TAaNr7lE3uzU<Q1S#y|ftaOX
+zk7qxiSENNLa at BPYIfk>sPxzSwru4eZFQMc|(^l8M$<W+8iC>+M9xrKYqh3T858hqP
+z>!Uz=1M4Cu&Q&hCRKdkAVEmQuoFZ}4y!-x$Y|JT_RG!*JpRtVMwGvtk<T?^i at jg!{
+zxQJF{KNcBfWj>L~4$!NSM}g^Pf`Lh~^3VAUAP-j!auOAadvITsvWK-aQHc-qj~#!;
+z|LAhs9PK(CkZq-~IcIgKc at Z)<)v0#C|66IKk~)R at l{Y0KFL&h*{FslP{jgE4VUuP8
+zw at Gajs*F7%BOAT#NY3>p`GAqk+w*qL=0!Z&sGHN;TMQcqq0rl}*{@UCoJ8`^#dGz8
+zKl+|+6%I2`?rSbdpTrc277 at 1wWq6W*As8n0jvm6(k>6q}dY>mniwjYK)H$U|eeV5S
+zvv|wAHbnyw!S%w;so2%w0<;s4sF#E6kb+@*A|yRMH!C9Rfqnjgf?6;nQ*ZR{5^3Na
+z{#B~^=<PU-jRMKLk9Qr>x~)BY$=l*W*i(rfmqmlrV}55D7B9w$&rrqlb_0<Sss112
+z8nWIduXoJC$h1vi4Zh|Z0Z8>)1=o{Hd8%Tmg{WoI at g^rIo{JINvBt8i!Ie15|5Al{
+zjcjaqSvKF%SL5+~yqcKv1xI7P3-0rO3?XwO0a5l~_0vi$?)jlR2~J}Y)k8uvQf;DZ
+zBfQeKFyq8IVnMlkgHyZEO}J_tllF<6vW}fseIxFto0m|!z&Y?jTp9Vey9IU0Kk{VP
+zxc|ARL-6L0p$kezBldI6FKseQSJxR35i`xZ;-4kGlGtwErK88n);^1`^k`e6|LuHt
+z+PkD_CFKW9Dq{UM-PK81YBuf-j<xkZ)>Msjly~JBQstXxlG9rD$KGh*-3+$;*fQCc
+zpN|TO^GtcUS9?acqlPX?aR=Q0W?<;hvBfpoxT|Ku1g6QhdfL==b*d2OBANV5&s><~
+z`{8j63B6H`GMHgeI-(#V)2^am;UXCI7T*u?VT*SPhM_sY6hZ;T-^GciL at D5zMPd?q
+zMN+x)+UU#SY+b_-MhQb*=t(P#{vvs+KG^N{8SfuQEK7FNO6ompDWPf3C}=BN<3~4W
+zlp;|y)_ZiO9N0QxWD&?H!XC53;4xCi)+S$xF#4Zu)B3hbH9G#)o?-g#?k}rtO4UCr
+zdx5zyp_^pdj$)@~`7~esC0)3Y>DM?T4vbN*yFe3YcTx5K*0BFIa~zjXct=DJZnCLD
+R|Mp6NrJ1eiE2K~Ie*nv{{Ivi8
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/content/about.png b/im/branding/messenger/content/about.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..5d7f5797038d8c2727457cc4512401a3404ecc5c
+GIT binary patch
+literal 9880
+zcmZvCWmHt(_xB7#haeKt3P^W%Bdv7DfON|s9YZ52B^}ZY5<|lP(k(HBln6+J#LztR
+z{k?hK{O?-#-gEEz?0wEYd#`hLoX?u?ln8JsaRC4Tfr_$%HUI#WLA8HjW1^lwc^@X!
+z3mqb-qKl2X0<f*4QQtW3%0>_r9`WA|lw-;ELH(rgR5bL|akKUGw)C(8czb(uIk-AO
+zK3KZjaJhNdWgkmW0syZ7Dhjf?J~>CLz8Ta5nH!rH*7^n($;QYCBDq&G*k(0k(Nv$u
+zpdlDEJAC}Gp+WPylQW;iW^c<*+7F3|G^aj@!G6J)E1b_DMnXKlUU at Rap%ec_^IWfy
+zs$%26O0<`q-LI`>=c{7tLHh1HR5bF at w|DGU4aY at u%V56_CzAU=9wn*~s{k!OT8noY
+zcyX1}-;*fKcEvBS_DTF+E$<QP0t%wpJzaJkaBB3%Hu(e|ffyRgT2a*b^2Sx5WsRel
+zH%q>k4u=GfWyD&HKuzk+ne at GNEhFBUj}Kc-3qx!*gLg4!xPq7$_64vhxqm4#jcV*t
+znpqkw%_{6&&ufI*#4Z<pVZuymEfm7h;n=g3m(vH-C;rFkN)-;2fia<<DF-7~VNE1=
+z)78KQ#~K6igbwGreA7T3&`5nYlWHuA#y3Dz5Qo_-l5n at +(gCgx)?7Sd`|^yWD$TZH
+zp)*6>m)l%8HrG;El|&c^YIE4O8+}AUByQF_(EW3lb)tg0Tbdllu}1qA!{S^(Z*3Nj
+zX@=S>R^ek3z|fY`!lwR(H#Z_iEd-A>pVqva7_MgDHQfKSB}m|m-62aKKnxg@*{Z_V
+z*E?pO8OP#6`)%1$ab3|2mn+ff$w$CfEL+}&%cFrmx8I3Y-V(akostF at 36O(a7hTva
+z*)?y?h4-Xi>9`jvq96{Ydb|@ekK|1|lz;xgritM%C_n8k-_Gf at u-w;EF&-uZ4ACeN
+zL<TO$X~t(5806urc`Tasvh0Cn*%!eKU48%F0PCX#xys&c-W#Oevhna8UMc9}Wpz*w
+z-R=GIgN3iY)G{On#A<G7zhz^-`jq-e%=7B-3LB7YA5>;_oVcr at R*loaTgbx*AWMo$
+z=lKEou>N+h4j^dRqI98L<TDNFJTd2wzqAy7`$q{4{M_F3U9N}Ky4*n>=%L>=aadW^
+z;aKB#tp<@ddiNjZEgCr5bw(sbzfBk*{g$8p at G3f|>D&C#+0`6jtwgLm3S*7pqfEvX
+zn_EWn^u#hZSHD94uWTcbWIfa1<bmrD7Co*4z+ZG*2W#5=?9%ApO<E5Y^^?6@)4;QB
+z;5v+q?jE7yks+*gcbh)t2OBQBJlAgy?fzt+^3=H0s1mXIaz-2n3bZ#J;o0u+E^OsP
+zG2E~>j64Z6_6r*r!|4ESANP`ek4^J3P&<vK#o$lds&zCy4$yGgb0%T9DKh+5=3VaW
+z;1P@)AbJQRiP at EPq7rCvFkVT$@vbVZnFz3OQfAcKHHgO~#(~so6V-{_>t)t`jISza
+zr*w2GC{@)m0W}L|Ejub|kZxb#26AX^J{(=@EYf+&|4<s;-PTi}Oy?)tew6L4u3t&U
+zTaN;1WIbraJYWgj5%zV5)%V~`_cr%yP1liO&iB^$^4J$xO#>!2#Pllbej!u6$i|(N
+zxo|pO_pwZ*Ydtq<{n>>+;l}z+os+Ys{u8tFdd1RrtY<<Ybl`$9eGW`{OxCxAh&amH
+zm!j0azt@|jefKK4{@3YuQd>_&kJ7mA7A_JG_mO~QzvY7yRX{xmb~NX_f}`;!k7Z4Z
+z$Fm+Mx=4xbEupY%LpkfGyR5wmH|5b9cNG8!bT^LyR at UQ>6~i65`gN_Tsc#TzIi^1W
+zqZwH3A4 at -gXK1<qG8||vn&=uTEcR`x>FanLtZ2G;u(k|Chf92V<|P3zrSURpcXEu3
+zKk1D`f~Tb7xwZ-rREP*(2FrWHf$swp`032e-Xos~4pH)=Rv8|`c&EQg9e2uFZ&>Gd
+z{$1603sS8!C(G6e*MhbN;eS%Vf9kFL_NtnfHO!j8lqUVIDsv>WRRzTY-J at W(+%nQi
+zsY4i`3D)0EP=7@;@w%;Gf406iCWRRu{&C=Ak7h5Xg+GK$;M9E4<ufr3R1{_EG^2sW
+znehYip9*mFyDNOXV>7$y8+0h5MwnSkb9714hfJuqbJ;V?!We)&YRH;WnAkQK+T^oF
+zny4(xZOVyuf^Ery=czvUOu5*z at AP#e+bhcbhGr at tyF&Gn<N68_=x`2!+Sj$qtBUZP
+z`epa>fs1R#(<QC{I_OLN%=Ux!TadidQw|0JHGUO_)@vY-ym1k&>E>G4??ImZ_r9mM
+zloOTBwklcmRi(JL8V2ej3mofsIlpg~AJ>?<a%GgTo0THb;rNoRd{^={m(r11NdJ|M
+z5}PdfH&T{uB=MBrM7){stMR^h40N5B`sZu04P!*l&;xlugteY^^I2G-wJpsA<|ZXZ
+zJ*<DT6b%wUDNJyOS>02HLF1=~d(5XYAcB&D7;rb;Dj{XW>c*={W!-h+8cF`uF?r;b
+z6X_m)by)0VXfFs9xKeyNA8~G1nn&31v-}GnWALGlx1fO at Mtu=puzwNY<5IFymn_%F
+z()Mh;(m-8`7p_VwuH$owSZL&g8#Blf7nW*KKu)mvu4(K;qsU+P)<yeDbvBrur;`iP
+ze1@{k$GJEA*D>mGO58+T6 at HBHPYaC-t90up^EnpOQ1$x4Lh<QgGZ~@>1~IB0)J-^@
+zx)GMb?7sjO!v;&@bZhUJco?H^*G#dv>!w4Ps7NDFDtMoRRTOGu@@r>vqSY4D4MWR_
+zWcZCcVd~an93V7*q5hs=Vr=Zqby{Tty2MR&W+e&KksN8@!D=e<FZQtXqs^gd$tA?_
+zan+uHn`@@Cx!0ES%9mA{X`CSmsvBjLa_GB5?sJ{I_EC(kHq($gR$jujTVGdB@%q61
+zypSXZQfc-3EJPQ%bi?1-0jj7#t%-+y9G_ylfXl}(^CQbFW}I2Rzd50CnO?>};+$S^
+zq%{vI-DAP3bQ&+JB&&2RD9yhKs?fxp6xHB86FJa3nxR?yj5i6+zswpnea?u+MqAn6
+zHsW^*GB?tq?B!kpMm>{(ybz!ZPaP2bye!<?+&tz;zAfVt{MW#acE0&Fr`p)`rg@;=
+zFGh=I`|`@TRs0G!lbSbZG1uE9)q{c;IyA=}_HP%f?Y1cmZ~e~JPSreRW~D^x$&Cpk
+zR<jZz?BEUXOA!)Btnk&WwE@%XKQ{|0wJ at inT$UTqIfEp;e>umk at DQ`dTd2Qbet`VG
+zDKg9-Je81$gvZ3Ehj)ojFwjQH_FE2PL+HL|6iZy6<DFV?HMK{!s<I-<PNke`BC)^F
+zzB;}3a9mF7z<B9cm2lJ{m?*7ds-l*H^FsaVsL9{gDP;=|?d9=IZL>2}$Giw at OE;Y0
+z&hShXmL)FVsSS7KU70-=$?vy1Jy3=>){(qFJx{I=#Ov(B^$OH%?<Euy{<sc0c_bC8
+z<*cQ3*5Q|ES=_hPCGAcKoG{*dPIN;H{=iTxHfcr}*P=I+Z!zus2-n}sJeOQ-o;TgU
+zwaL+Ohl5{=l2umryMF$7r9M#nqMCF)r~Gu#Tsq=m!I9-d(g{#(sGa-+?{&?(vKD$z
+z=|lbFrx$=R(d!V3AHH^i&MUgqUB?4e0$4``ESFX4BKa_Vzs%SGz+BAKB3nmSzq&7u
+zP6J4&$A$KD0oe&Tutwv(_rt+-z^h-dV(rtP+WvK*nrm^Vi1apPEI4YjM<3XRjavNk
+zgHp)*O*hdk^jLPk)hh%Eb(03UorclW?**EaRE-eURAL84^=Xsr0sao;_{x;THy~-J
+zJ86FM3D;Pz*v=lDGj`yE{lcga;VXFNo!TaNecg3+jXEB_v7UfARWr+~!)-S(<f6`?
+zn=l*EOS`0dhFvpZ+tkWgob<cY*05zpfA5w}CHYI&Fedy?U#F at m_lOfoi)}Y2oEc8w
+z*7ptD;@{PqG$?^ne+Os1M?9=KcaN8lvo6E7<PRU&62LIUV;7(&H2Qe3(u;gd#(8nS
+zY#dtCLUKdvY()N!NMa5 at n{yR!ZuG7=H+js!8uY5X(Is_x%~D7JH#t32!%enOa?wvM
+zbK!K&FXiyHy<2VL`CfUN*pO<k4MziTTFC?lN(IYkE|8t+#tAyA>76&?3ZR2k6Lupy
+zUDDg=4DE3z?M>yAYT~$DlklP5(n at KeepEI+RPL?`HQBLFHwG1FlKl207v>yPN1g8+
+ze_i3S*By9}jsOhB>whz{+%wzwV>z#r{+j3k`K!}|lJc#w0#04)KN;gfuYGimQcd&d
+zDF8G_ at 0+xa7iiF7ElPYiCN&xr(RnEQ2=;crJX*7}OYW4*)xOpqGhhT2yj{Y9iiaIM
+z94%U1trA5v2CBKg7-|+mqT!iysdEKXY_lf=iE0v?wGNNFddKBm#7Ugp-mqz_EYgf0
+zy8;f^oVG#y87`Tl3MgKYNfBJLi24&59!a=a!)Sk&q<H9o(aHD5l9}Pbx2EiG(!VKV
+z%1mPrLMJ#kFzOejGI{p$!fCqgFw;Z9tcqU`66{*jlE*YrtmH at oX3uvPz<$AZ-Vu$1
+zBC1zM*rj<pWa7bUHSD;LK#N+GnBVKsYnuf#?t-J9VQOm>H#cK8YCw18`{X2X&2&)m
+z>F9#Mir?_mG2Peyp02g^b$=}d?|<h5u9PSXfmniw0eFnjdoNsSn6Pp0LT?LHjD1#p
+zeuBmgQDmF_$^Zj+NvFR_1&*Ub&WBB!@}>xccV>(&K(~pseb^B2f=~hn8lr-cD%wu3
+zf6XVTs{O&5B at 3uYE(I9G3(^W?RQoKTNT at 5*mga&kLq&JG&6WlH($^#7=)@?NmSPA{
+zDPd!KWy=7#O~6mHVMzvR>Rf9S-^~wu;cx#?ovO|bdEo4_CH`FFh07(4vJ at 8F?qpag
+zCEFWPo27CJa8Cm8p~h6OX-c~5^grGx`Wupf?<v|mK3^`-#zMAaTmV4#@?6B2P)Vrj
+zsQxW#y0k{+=;>cdDVTe27kEK)_gGisDP6ZO8z$d=+h!{SPPZf{dXFpb0l$V>79Alr
+z+j*R$;}Nm9RS|My`Y4tBbZm_GP$Iyyl`5z&t0cRfU#hbk$98v74}Gf!7?(pK>Q*O&
+zM&k#-hgw3aWU>^2>O7Zm(u0%pa=300X`y4fj3DsXw;$rrv<r+OBR@;LJ4^z?Qsk}(
+zk8507p?7d)UQ11?X(?)?()`(8n))yjF)w^wa*3s{^_=E7MWOo- at y+};s{OHiXgRqk
+zLz3 at tDAFAY`P{%Rukz9KrFU|P9))B^Kyt1J%>~3umCGWD07~g{WIn>m%tC?B`dqb_
+zmsv(n2B-KfzD`^{-)-zWzsC<kxLkH9T&;(BgPxa0^97n($W}(4#ZyS{yeK55B$RZl
+zRx%CAnPv{7rvh|c&G8lV>)*`2*ZKi!FD71seBg1ls_#81PvRN;=}NPVNL*xX>r at m1
+zaEXKo!Iy2^HPUcG3$Jzc`ahP*^Z>qg1S<DdJ1nRodxPP|d;eQ8G`Uwe0!LMNc!q^D
+z|IQX{y5Ez$Ko1kRK{sKS1{gLK0NJauN6m^s1^+JbgvPwhG6MbFM+6m5*x1IwLo-7d
+zjgu`^kInA;x>ekv9nNItlk_wICrrO59K+QoryrUFbDxEri1t`8<du3q&wi`j=#aJ3
+zfATG3XLGi}M>tb1{~7t~mVlz+&XvK+Vs=45_H_q_Eq at Z=Cu=ip<noZdP2`6>^zm$w
+zh&YB%P+q*Zonk8B%o%-O40;9i at EP`^NdS at O;OI5T{SX at p3F!y-kw8XFD1JX{Q;LUD
+zq|^kR9{t35a?K`9?HI;_tFD`%H!aqdS#X;A(Oz*y&~uSRJy+^inYBDT>(y{Ro`43q
+zZyJs6KUmaUB#PPbM^h_G0nFEA*q4L2iNM!H0~mI!)NPbp*xMOnzdkbe{_uOr%akz@
+zcdM<3lRlvZ^S?i7roISvXhv=D746WXoTr1W^_L1}LvfK1JJ!5ljUt;RzlGm=OdrOe
+zveP}2=)G3Nbx<`sd9&a#Qr2#}WWVSDWdQolq;mH{YoAet=B4bM_irD2CxcE{<uyZr
+zM*)nksX3JVw8jhLN7c7dy1A>UWwCOO-*@F_xUGi)v$HMEBUyWE4>0!6XgJVZl6`V?
+zk$lJH5zXg1ot>Sn{-NJr#^qZ-=GsTW$n4#OpWZde7ZN0o-0!=aLH3M|R&UDr68D!+
+z-?}xD)<MU1!0a=!2CN36!mEW6>t2dluYmQlQb()OhHdK at gIIdI#V-nA#%JT~S*d9k
+z)e)q1e2K at R^36hB{klH`E+wX=?4|Yv#S(nWC+psgA9hj2ravm2WjVGUO1$I~iKbI{
+zINZPevkzd42`3KTBh}whMM6~1vkMMZ+mssr`r4l`2==e#*3YX_BG&YNSpJR!A8@=0
+zJ0MA)6e_xhvCf&KiOswFf at -duVk7B0BB*OEvAX<ad!BoCF+{S}wrVaAq-T9djI82%
+z#&iwDDVZlAzQ<KV1Cuw}rSyI5M(-^nr86zd at UF1>{ZSUd(NIDnpdJ}J1#A6rgnjD|
+zp-N^CtK?*31b7v#t8fCJMQVAE3+h-;W|yF;O>s5M){$}b04Ph#U%9=K{9d~DqylbM
+zjP9Ih|CmshQQJ%h&KhUP^~`DG2->k(^e>2xie}jPaprCtMo;_Kk at oW4xJuwHSw!5e
+zF=|e!;=O}-;|K^UQC=RL>VRZyeY)7X&EMY9Y2z?+bV2{?9<_EYWL|Gpgve*&`D@@Q
+z_WpgniF?Ktyy>%hp9sH$-`Qln2?=KcpH7<XJ3JfzuwuE1d|}S-Os8243Mh%=ouX$a
+zDJ)xxI<g!yAd!Wo+KujInQ<J4VtxWSQZ$%^_}h*$AmNGZq+7L at X-c2b;k9B`Wns^3
+zwdJ4LPH2v2;3i7qaCa4`F!s4>-B1WA at H(|0Q3vfgTp-EDzX%w}qJoo%(89L+BMn9T
+z9dn#?vtpmWT81$7lzLc;nI}F~VR=6K)?j!SpW<peI1(AgV?y+1bNz^$9?zh)PUg%E
+zt!#D%7#x81m20NSD1+YQm|ZsVnRbrQgz3M?_Yc;OadR#Gu8OJ3fWx`g$e_yARjgF&
+zQSGCCr!j#kDZ-UC?qBN19)!>`1o=oFr}2Y*ko-Pfzw6sMR1m~mHZQ3pUP5sXXQU8$
+z5E$4i>%}s$oYBc at cKRm&4})C1W_mpfvGE{r7^#qi4u7|-2Z<5m)*~CF#>jt)le??;
+zEU`VaT5Q5e=Cjv!7EArjf4={)9<lnRJQ=X4;`D^3XX}lg3Mvz1dFKSM=s&0ujI{`h
+zr~2;EqiJnZr|)=tf15hrRiWrd3<&uzXC<%ktb;~K6nDRjb-yh0$t{TRYhC!|fuMNH
+zZvLFE^}C{V#vP0AV7BZ&SG7460J;PsSN;dFd>oY%ZPZY&kZb6?TVH8>mRSc$)H8>s
+zYN_VU=S@$U7&`qbt*@otp}m5#J>CSv;-wcPo?$6W={WzwH(3ko?N`^1ER~P>s;^;!
+zwe8U%pv;>3czo~oq+}_q5TJne3gGw-n-vh7b<h{SHQujD7jzkD?-KQuOv9<8u!MA3
+zTp*8dWHR-7BsDWDML82(vC+ at LR_k;{SrI3%XNn3yM^$|sGE1BBm1@%T57Me!GsGp^
+zI8fQFM3l#Wzp9;pDf#-)E0uUCBuH?&uJoWl>k*_JJI1|Qrtfa&q`03g{7zBdo&4J{
+zmJH$(L+}kd?)zTbbpwkGY5q%3RMxC3b}s%YFSYO1LQ7kl<&(c+wy;eIdQTzw4ecu)
+z at k7k$e+8DARk_ at gxv%}bQ)85ofZ(3c&u}fv7Wvdp7fM%Slaq<$_*hl7Vt*)ajws(1
+z`@iW>eQCEU<yEFI>JrwUD91_b)?Z7T824Cfxx>a4w9 at YyH*97N+Tf&&(#v6=eNrG>
+zp81vXuPeCwN_UO0gO@%SwQrYISC%7|>8QQL6;wpRwY{B~FSjse7b(3yC~PVS0UVDe
+zSbqo9XVJTwdX{^`pKO$V_8deS2}G<?YWd6%K+8oH$t;PD&+xM%MsQDNViIC-5`O0Y
+z{ENX7x}GG|9so{y`(Wh~xX-%urL$9!4<Phk{za7i&}*9WuNf*3qoYyf!uYyYcym>p
+z_MLymPb!8T`k~L!Syack1~J-$_<Vz$$Q{K(rAN^jl7Z7l(G&mrS04F*5;dE>3}I_Y
+z>V%A!#HYlk^HB!+>X!j0xT)=E86l=@yW5)lbt2ujlfN=64EkJSvCUEL)w7@*6Eq)V
+z2eS5B<X^p6(JxN21_)*YP*uo at Fqcj7Ry(=<L<9>LAjZnA(aOMV<lAU#&?Y$LJUiXM
+zFZdS0O}__bKslkB2cke-o%#YqHbz+ksPiu54oDjyDW&3HfhTJQ$RWUI at yso$EKN2`
+zOOx=ZpMRQoA#L4uQ%mkzr0|#C`^IzK(XmSBSn8GQH=p<H=KTn~kM~$)bB!x<G!*{!
+z6kCA^Ni~Pbx$;Jt_r=jqJA at LI4vt*vMh{Ml26`pwUQJ?nNaikS$tUhZ7WI+B9EDme
+z!=tuc&BYA_P$J&SQr$Ok>F?gQ<FUF>Xv_0f!i|t^{CIYxXM9#kT3)F at 3QL$QDPo|i
+z!q%iyn|sgRn|3Mtg6v`UNh-ii&(F8eI|&b3Fv%@*wOdHww`Yog)1J~|(MsQU4Q|h|
+z3Ja;+-I8E2-SMdOl7N+cIFB;5|L(IHvu)jm8O8}er22hA0-q{+vwi(H`}&jKq2&#m
+zUZ53RL2?0RsLUZZ9;FC&g+YixN6^#eJU%jobjWc?TK~>3N86E_2lM69&C6#PE6P&9
+zLkKE_M<mA#i4r9qtnv=ru^^AGgdPSbAJ+CO8Be4hb;P8^G!}Sc?n#awUQyAS_YraL
+z9Mhi*fN3c6<h~QF`;VjJeO&BUds#@cFF^WfbpD~a?9M?Ev8VXScvB=M^-45ct#77s
+z0O84!6Q;ubUD{|wYNVLHkGO&sT-ldf<C))k(w~=i)ur_2 at 8$9S>>}QwqHR(%F=+*$
+zJYe#qWQtw(eKdBAE<hpB8K4lFNA#RL6R>zKrnI^D9sYv&BAkfm8z95ee*S39UB!tJ
+zRTGLHj-3<8h}Mz`+ZJ1f3UeY*g(9P>!MN+ifNGq>vgduF$|ran;n6}kP!u*9z!DzK
+z at xNxwxC9*g=a-<K=LNX at hCj3AW!NS at W-4=qvlu<)UKDkbM<4`VAEwY2)Vm1q;J=I+
+zxoe?XjM+0={)3h#Q?>1<fRh4XaTX!J7I5diXszhL;sE8L2Vqbg<$CZ>uh{BK1M*Jp
+zkv4E)C_iudH8}M23V)wSPC at w_cL+1ud!&{vQt8F1^xj?n^`n4I0B+;I?JM&HgG<dk
+zB0gLW+#Py#;|IJ3i8^U__EY8puEg6OU_eRKNekMMZz}s}2D*$Eb|ViJC&74899~Ei
+zFY>rS5bZjMd+2KW7roXMBOoS#07zTRV-i0Je0&{s-VK_&@Tlexsw4JN29Vs`GP&z!
+zZPfwOJ*Dh$Pj%q$&+oHCWQ|~!o>?D$f=J{pSk`5~1ZB|byY1E$>;j|fkXk1bk~t}^
+zM2xFjNm4<W&n;1~n+%QHkl5@!U%>BYV4bXUuBq>m2T+U*+F~@vkg09Muh9S;C_P=*
+z#2ARbYkSE&!MFG%QxNQzzO)#fdDrqK@%XNpJ{?X^@E?k~R2264;vgDPCaMpl&bBdm
+z#Htq_gDCt^L5=ri*3ROj)Z~$q&0syp^5zHqH0&hO|ETu(Mw%`@x<Y7eyj$?@oMIIz
+zP%8eH#I?E*je;Ls=W#60d>w#9Tz^5ANlG+xNQgh&`qiCqGF(U_7Q2gk_WD02YO~bh
+zWG~ZpuB!!xU_cWO$0Q=7FDN!=0a+h#udTR;-hvE at MUk1NRE!Ej|4l6i!^7a;r|1!!
+z#d*L6 at Ml^1?WepWVtR&TBE3KIAZfJ6qV%ng>RDA~(D at 8!UW4Sv$Mr at yJBD)+k=#W&
+z5snt=>5$au$i;U$k=k^>pEVe3U(VihD3E*LaQrLbJ#ay68@&^Emn0rnfTDVnTg1ze
+zy_HS!gn at P~xzZ!B<50?Hxr3hbE*bJ24K#y~U+3X-e4pcb?N`$03dNom0n24=u at 7@*
+z$Kd5es)UPSG}d~*WKtV at rw+ZxD;>(%gQb;C-)*Q+ at wwCg-&NKBRa)tBt=}l0)DBgL
+z`-o3 at xT2GRPCV}(IWy8;E?raGzF$2y9j}ayg+68+v5+!p^{Q?VT6Y(2nT`+sk>}~C
+z*_&*5#1*h=5Jc{<!{hJ|L=Wk%eH<TFc&N(UCK__ygJH|R7KhGDL6DH5>+30`*bXw4
+zYvPF&-ZH|4 at syI$6+_qoxRxWFQnM2BTE>=$8fj)xuy^gR)|rUv>tua at u(>Gd`!#Se
+z6HY&#?Wo-Hfs5(#-VDBb$6`l(DssxHKDbj$Vym)3lkwo~f49-eJo~onOliYFGzVdD
+zN&~nTKMhP!Zz~a->Uwb=GM^m_J at BwMF%SlpAw8U5@({eRrURDl7^M at 5b`Z=m3^O|%
+z8f9G8!q7Gb;BFyV_<46oc<{mYqUQ#00)Bzy4M|rp&##o;o4^~=Q^}1(jwv;AKoxJu
+zCsoYtdv0~Y at 60d|*x-RzQVA!NOhqW;BCpr9;m^MD#y7O)k`A$rD)@S`kz7bVSo>Z4
+z-c=y^wcW;SMw5Qv4Tx!Da=bowNjn1;l-t)O<%a2swKlxbwmx+Ku5l at SF;YGQ?CUgq
+z#NtE at nDr-V6&r$7iP2%<B61RqpiANmnFFHUfMCRt|LzB_Z-lm5lT#twHfQ(FA{mEV
+zJ^ko~0R;Vrnn>r!DP%}g$a}Ja<A5X3f|cugY&=FlDI%n8Q<5hNQrCw*9TN)s%g_iV
+zZ;;qkTMfqt05Ea>I}4zg(5XINk`sT?Rp(awtcQv2hv{#W^{(l`1C8>|nZfV!F3Cn4
+zGwwS3P(kP308e_rIYb0WtUfimFsKs-E#;V+kttk3Vy2j#oYaG4Y at Y32mK*@aq%FO^
+zjtwnY=U4bK^UzQE;n`4KNjcNMM+5uuj%V+7a!gSX91fc1wMV%8jJg8#LqxdekDl&^
+zk0!dQUWB_ChqbNySmkY7L$WvOuOtpQQoZ_m=!{^DfUAii(|<PSOr0TXEioLa<WMz;
+zNS%L&2j{M(x~l(*>%gITdaRho!K$1W<iS}iN5#bO6_AG?nY?-t<&g2YS?Gb5|4qqV
+zxvNFq->WBb=typ&b0?IdqREA>o*JU|+N3B138_XNh~^pCGlSeBR---Mpy*G~hEkSJ
+zs(|N_&72{bzwYriDF1aJu8qdgce%B4(oK4P+*dEHK at PD5b`5ursi)YR-Y4I=`WF(y
+zT&L5Ec0(Y4?*@D%GwWWBTp&+o&fhHg!zIR3GwyiKfd*DzPilI9jZggmj^_-F at w`Y1
+zR44S}EJY at 1aI?+kkDLTp_w}RSa)YGD3OSoe9{E;ZH|A^2o;M6Qn?~J;TZ=Eg;X at TA
+zA;Ewk<y*kZA@$6qBw61g=u^7oDjsh~`6VNU#Pm)1K(&D+2E at XRgNa2dyzN56+d|D-
+zY8OZSy_5Ft2O(QpGhBYj;v at zv?PpcvzwP{BjT4!EWY<*V(e_L|7Cbs%JSYGvyAW$3
+zmamM+wq(H!wbP=#z{>;{)CQ61)Q8^cnXZ>^N!DX$C9d>Nb<zOOHh8tx|M03Ge^dfD
+z-~~i<J^h*bdk>rR6FsZ1(ULJnTnn={L0Az_neFYQkc!7N{QP|SMy=~Qu#`aia+Hzm
+z&(&OO@>c(UZ#G70yQN9adt0d*t50tv4xR_1%67R?JTIL5sW!W){n;5k=HvF#1g+L|
+zg)KwfU}8LO_ex at 8H_YQUUSEW)-hQ%6HiD(vj$_GK9PbR{9C%wJnyMvmtM{+ENSIE|
+z5;E~_ItOkQnJLgmCUq{l<-piG6HCucAq@?L*O;YPX^BD`v2gEmS1ni9{^IFT#xxVW
+z9hi(o7VkM*hZJt$-miHfb)J)3AHwsFK=jr=tJOk09O%*+FEW4d%Kgx9{C2*;`rqKO
+zD~L(c`=Mi3dopMoKC(eQIbp!h1ep+|knm<^I<a6?LCgMf*%N}2t?LQ?OXuL&6YKyz
+z8h&F(oAG?LmR%WT;TmAMgx#HkAa(AFx{a=M_fXI7pm+-B=U-I-<7>v_1n0Hs;1uXQ
+zu!RB9W5!RHf3Taf(zS8CjjjTE3RR(ACMWkFd+y>(*oelMzScGziVpwPIXaY*vlgwQ
+zPFWn5A*=$6JU_b$aZ57!Ik9OiMKchYmh18oar3lRdd)G&Sjs8b!`wI)kc5Q;ZS#dD
+zn&)saWy;j5)p}f#k4Ia=Fi+3WD}zgSSt$ZVGZ~PgILkE|hcnaufB<a%;QBd^KJ_YM
+zGSpZnq|{$k3>K>dvxN&uBxEM*qz#A~pmBe?TVvZ`Y&g)E1i-#LsYV4H{iyb9`?6+`
+z<~*d%Ey_^-mNYss)5(GT943PXmU at gfD)ZIb?Frkl)Lwd`%6wzy0=I5?MA9a##u>R~
+zkL0v%@rd3A<rwkT+!>7j8uLWnbSI9mKs+LC%oS}{@E5(9ZF6Du3QTgluFq|k$GrOd
+z8#x9$&*<QB)KX(fT at 7a$BU8NNlOH87Q-#3#-oIvz7E-81^FNZ<T6;L#i4G9Gf-^?6
+z;z2|^Thn(1KD<2+4%y>f8%SF5Z_gMX%g0!-yfVRAaaAV_=E-z(VrxKUgS<~Xtgrsm
+zCTH}1Nxx&+1^G>?wB#RpYaKXPY^3w1t0F#x77TKjs9E`4oA5|}?*0m|87M|%#TsF3
+zTKRpAI#>zI3`%xw@&_$Fsjnh2%(J&|zzf_Ka<|1mEFRfY_3?##d0slqXLJv>UoWQf
+zYOkywG0AOaV8?f8$Sc3U6LldvyhumXVXyyx5X*Y=38c9%^r8M*a~*Yx44|U;PN7x~
+H9QywNYWoZa
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/content/aboutDialog.css b/im/branding/messenger/content/aboutDialog.css
+new file mode 100644
+index 000000000..9a3c04eb3
+--- /dev/null
++++ b/im/branding/messenger/content/aboutDialog.css
+@@ -0,0 +1,48 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++#clientBox {
++  background-color: #F7F7F7;
++  color: #222222;
++}
++
++#leftBox {
++  background-image: url("chrome://branding/content/about-logo.png");
++  background-position: right top;
++  background-repeat: no-repeat;
++  background-size: 180px;
++  /* min-width and min-height create room for the logo */
++  min-width: 210px;
++  min-height: 210px;
++  margin-top: 20px;
++  -moz-margin-start: 30px;
++}
++
++
++ at media (min-resolution: 2dppx) {
++  #leftBox {
++    background-image: url("chrome://branding/content/about-logo@2x.png");
++  }
++}
++
++#rightBox {
++  margin-left: 30px;
++  margin-right: 30px;
++}
++
++#updateDeck > hbox > label:not([class="text-link"]) {
++  color: #909090;
++}
++
++#trademark {
++  display: none;
++}
++
++#contributeDesc {
++  display: none;
++}
++
++#communityDesc {
++  display: none;
++}
+diff --git a/im/branding/messenger/content/icon64.png b/im/branding/messenger/content/icon64.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..37a25b24f28233b6812f9e2e03ce73400ef18bfc
+GIT binary patch
+literal 6661
+zcmV+g8v5mlP)<h;3K|Lk000e1NJLTq002M$002M;1^@s6s%dfF00004b3#c}2nYxW
+zd<bNS00009a7bBm0008?0008?0f4QnRR9108FWQhbW?9;ba!ELWdL_~cP?peYja~^
+zaAhuUa%Y?FJQ at H18G=bfK~#90<(qkQT-BBCf9Kv?bE!(Dl4Ok~*^({c2^%nA2W*Hj
+zVF>ORLT8{EVulbiBzYw1c6UNv2*HGIAV5M$@*shP5D3KJ(9i^$(FEHV&lAQVxh!jz
+zN-EWK>kjArQBr9(#v$~2>+QAny1IkzJ>Pfs*?XUJb_ppZ|3ArAAqu--X*(=ygJsJ9
+zbb~$)5klM`gm_X2 at m(QA`Ploq5F#eTie at 3!0|$UF16zS*NGboHR$xtSZLPfj{`=*s
+zRjXt;9PV>EonHckloAV;XJC6Tywe01YyoxT|7)LUSAEPPg!tB}r=I#R>2#W!ni|T>
+z%b7oae(>IV?|pRtyZe^v4WiEhmjKs>q<kg>)Q)|}C*=c#5GrsQFi+F8%7TJ|YM??<
+zl!|0BS(?dY;y^2Kc<|T?GyyM4DZ3|l->TWOXaDSb-}@dv{NWF|=9+7$uC6AV&7$i%
+z<<H&B^tYQc%~8imOS0MBleX*cNq`W-4}8Y&_g`38Sa_b->n-$py|~?O0Q&p;X=!O;
+zU|`@#ud#u at 0?z>Jq?G%G5MQaOsd at 0$TW=MqREmB3_OW*DT5h}THdIxmB>6UrUcaAf
+z+ZXZZf4}yyVHj6QDa{Gn`1c?{2r<j!@%%6p3Y{Mghn;@Ef7~;MVX$r6HcWHEb{$C$
+zg+igKJMOqc*tSi3dpqsz?QGk&4MkD7 at x~j`GHp0|IyvO3<lcMlmC<PQnshq-pqv2g
+z#~KBM5S4zv|JMx-4cq6<o42C2w$@otP=F9(+_MJ{9y}KC0M#p3t{ervqoV^M1iN<a
+z;_0WKCZ&Yw3`|1^!KIg8DqJqtorQ&kvnP7l$3lP*BH(a1ZmX%OIWTwb+$+N2usRmB
+z5MmS&nM~%GzIDP0Cop5ij8Wi+j;3ky*kg}z-+lLyPNxCz`~94G=9z(XI(@wmVw}_e
+zn+Xs?%nSqq+vd%ix4NpT%B?6$9_&OtKXk3Owsykz1p)ySW%6cSbkRi<f^TncCz(tF
+zuxZmKZn@<aqR}V-kw^r~vg+&V>Wap`@7TlOD&f+8&a%?d(%;wB)fG(EXdwg>`I*Ul
+zkJsy^zP_Hewl+FCI<Rd!f6wRhVVdR<!4FASR~NV6emhlFRix8toKENVL?SWndq+pW
+zY7qpgkxWHl8a7ow-a}<oP0bgos;WNJipG*4gqU;)bai!6R#rwN5}~ZDjNQ9;lg(y<
+zoOK)x_>t1m(jwh%_k(3+Wsf&EH;)UalM}F72w*mFE-(*ppx^?M|NBkKA3jvGq^hcF
+z6sWN>7WB}$l#;Hlt_eS at C`!K9olYl}m6bF#H35)JCiB3L20UPSz219 at ii)0SZf at Qp
+zrL at OBFrI)M at DqS@fH??!KoSTb=zeq;;fJHuODe0641Of&L?VIT at 6Vric6QR=-#_YE
+zpU+1i5Fne)(%;{Y+wDdO!N?FAkH^`$b0<>DqX92{KHpv8aQN|PG`juh at _^N%0=No@
+z01XH_fB|3zf~I#`DLD5DaY1$CeBtqUjtE}Ybq*amL{Co-hG8&c#tceIN=PP??A^N;
+zUDttJkC&B|QBhGrDwU$Arzh_qv)L at sXq29wp8R_?O~dJQl1inH1RelYRkvD}b*hvy
+zJJ~bC1gsWQf$M-G1T)Fang)RRK=e=?`K_1vhbQ*pnm&CxrKP1nu2)j26roUvAyNQ(
+zdV1KiXV0jQc|0C6narr6F=x&kJRVQp^Kad{6|dKeX__PwiAkO1(Tb|751OWV)nxaz
+zLGS@!72pMC0Bt}V2m|hcEUA~8xu`vX3!t#D5CGe at X=!O87K;%Ig(xa2qNJn*hr=<d
+z*M?*$Hjk9UhYyoZr<pZt7Rh81UDxy0 at o|V{SyyVBw%Ihz2PV2d<O99{_<#@sjT`|W
+z2_T5Q*~0vciNCTSXY#tP)6vmEXJ=>Lo5x}?g25mThl5lqMQ3N{Q8lo)w-<mdTege}
+zc^{|Pw*6zL)A at Kdn~jaVr?Fa;k~4FF0$|uX3GAeS*4)o*fKOGyTZbh(cI=q&L!F(S
+zq*5sc1_nN|>HfXI14t<Yz at 5O#vG){U?uc_YFw#ylhvPI#nadaz0hi7OZIZ}8)bkUW
+z`v0^ThH;74>unf&T_HE-ha^MJ4*<|IfJ|Eyhup&tl>6cH4LLGCDe?Jylcv at mL7awR
+z+&%W91`G#UL5iH?17PD}PV_rrS|M!j1ar_z7e}Bn0KeG*J)b~lH#RornkNK%_wN0$
+z_&=$bruiAK*SjE<O1(XFO(AFYIg#`Zp8JvpuC5f3L-Cx+&nX3ML<iIr!oMwoiyL!R
+z at o`BY5TK%>0-w*9zm`s?8Jc9(*Vm7__Yp<0ZTs4h7c^jG%(2NWMMd`YU`kL78}|0V
+z at ue_l3he9vbI`xJH8`^-r|<W{_6~@~;ZPjX$28T4>gsCzem_-JRkXIY($mvJCX>m7
+zb~>FD7Z)G16<DUZbdKL&?oK8J(5?Z^K+T9}T9KUGo+LkYjO*}0U#{2Zl)|nqFvd9T
+zy26|SNT55FBV$Mp#UW*Ucmw0{cs~8DsHmX4ynIwdky4IxvJP@)>juI;4~1?QE&;-p
+z*rthPn%I^NQX&*lW2RFrcFy`6h6q?P`~?ilrmMum>_h!IFaU=Kz?M)Sf|JUjxgXk+
+z3_mbJ1W at A5>4{~-*ZVS%FmgnsO-LJ%8go<}F>1U)GzBz8q6vwLjVdIXlKa~VdU$<v
+z0d7EMbi4sSm30vs=ggq~xLP8$WmHs#@j5}nLL-YXGDtnevroUp1HX7taXK|U)|;r)
+z$gRANk^?cM*MSlV!od-9mbL_BEocnG^iXc>zaNACqfFci-8nsyC`yXr;)#=}k(RJY
+z&thbBKJ(=Z`1ZZuClK^u>nUV5h165ndK#&xkh+1LHIRnRBM-gE+O?aw>iTopv-JaB
+zd|`XN!W!90ZrtakB|)e?36TH<T%#M&lZI^_FpvemBj+0$!#RKOafof(`T75m#OYO8
+za?xjKKitVh4a<1`w|_z!Ix?&0jw968)7<srCwcDqt*pA~0?uA?98+sbTpo{e=1 at xW
+z#>kf^vLf()A0)Fds~9|v(H~D5ITAkT14}}w7Z#Mm>=Fojazo&6k$5~lZozbHW;rFK
+zkxlEY`Qv?j;ae-YXZ2lNzx+B{4m1w}&mavQJ(=X at fB6kNcSX7WTgzE|ay=fGgR-(h
+zoK9`_5CI#3JnaUW-?m}*;CyCI2{_f!jg&yk0BmlD?m?dvi^G9KaB>CI1i^KTR$<#V
+zu~>|BIz6d1Oe<B{zkM&^pqI<Pb}|3)<em770$jH2Iv&3735;}#f!-K5U4K8Zz63Yi
+zbOEOvUxU+;15#QV#Io#2u8C`8hSg#-un54Esuv7&GZzBql;m_|GBhN*346LBoq=_m
+zRFY|nk^;e^dPyVzu?+O4p*I7Wj}RKAlne|E5DJARoLAJ93jTXTC+YrvT$)W|eFguz
+z=4-sVWG;{X>?vM&=5-XHw7ihZulzI(H6<t`(pObg0OZI%dSi$H!yZnK`ZCbem&*o^
+zFNIy*InW~|k%s3st5i13;J}W3{Qey`VSk#2GAMHA6mp)vCk4Ga#4{5HkWu1xyKy*1
+zkG~- at yly48x)g1psyd7`GI$+=bI(43xyP09heuu@(U;(hU-}f&DvKDKMO&7Q5W*Oq
+z)~t~Sfjv?pOo>ZT6o#}lsnDGf_??0irU(M=;d{EF at RzMB(~h6bH}1U|Rnz$XBX{xB
+z*Ic~SqR^dDkmT}spF<D{3g(pxw!N>h at jWM<{R(2lw??X}s-u?Jg%J6BZdcBf)A9Zh
+zjxRUv%R?SkUA>g6ulh7~RpY?}7>0!q7-Q#ke-Z*qfaTB}sEV4`_xm-v(+Vz4aC|8g
+zdlh;I6xMAN6jepI=lS2 at bUBeyviO`u{L}xslBYMj*wd}DsY7FbpGr?g!H@#e7VL~l
+zc7KrN^?hERddtPu4^#%yInYCDnkI%}Af+5fgb)JF=^zy!$O9iqf&-h<(BvtzX<A4y
+zN4u#tvX#~1Er-fiq~`RFbwCID6;h^6O~9tB%jVA;;I!pSx%r_x at OhnJ<d(baOoGd<
+z|3}{6zMI$H*~qeal3qP$`T$Ms7K)}(KdXU-OBZtbd8hN|hyKW)*S<udUu9aUL0yHw
+z>&ndoLZQ%vAT+0g^uWMi_{-4O)kAA at E3F6HXlskn*51cJB11B%lT7NQ(mI)pK_;Cg
+zlg`?zA`;^_M^}r$Z{Kx)pgG-PJu`8Jv-5z#h68ZZJ>O@=$`we{K$-?SHt*!xW!JF2
+z<$0uKpr=w?cj343nr)ogIBaZBZM2zt#@WnXyny?@aVt-3`6FdzA at pQ|_0PS|x<{X5
+z%ZA-dt#C4Ls!hYx at TlFQp*G*WHcnYtm}D|dcSkRVZlF3eq(dW(Ku2JUoJukLci+GO
+zg#`t_2&Ym%7$2zC$oR|iU5C$|sfNWQlm2j#ip#BW=J}^#XOejW$fgD at APJU%!_IR1
+z{omxO3%^U~P?pAsiUfN5;G8cnr}4x_p1A8l?)$fUxb+wRibF`wIC}w0&YVlEvx{dQ
+zdx^&$d6Adi%}`ojLAcn5Q<%6F3%6?HoZ_OzP-stCWD9~=g(~(Dw$+AYpue92pKpIp
+zAkZ=4(|>wb?oHWFR7IW8IaQZBs18eh@~t&F0y0TtCV|YR5mF*E3G7S)JCh{nRk{71
+zukzMDNqeuPBPJ0-;gmBM5Dt1d_mcB@<(XI5y?H0n%;q)dcX8<zOL^*<@AAbJC)2j0
+ziCr6-*w*Ucon$$0#w$^3XFypQS+5toUR0M0hr at A19h_F1s;b7K(WpHk0U1ktur?aR
+z>2gg-fTAdzHcRD|b+54PjZJy5QcoiRJChtm%+#tNt5;vhe{D8-eXn5Y=Rbp{NTiYF
+z{EN?`Xi5>kzWevX1Q^3axHQSdpFf2sp7<s!zpwz_+k?J!GiEG?s;bzw{h^>os+1B{
+zRg*v$OtL%d at p%5SC7NKjQ8g(6ey_^HnGV+6bQjq~9H}Rf*_;!UdJeojXcbr{ixxF-
+z-e(uk-Id{ro36-%ED8BI>!LH+ at X9;%v~|J=E0AUutX$IJbf_#}eiFBQ|MU2SNo>Og
+zQk|Xj_V#`x0tPoqqemnl5D4tjb-i^<vYbxCHz^78r at JweasKeDr*l at 2&E>?me(w=}
+z`_Nx_<F#EJJlKsnm_DXbSr(mh8j)!gBLEt#_`*`WJ`Ybn_7c*_f;ptQ1%%et7>_*i
+z8kb%6Q*OTbal8d?yrBSH=`@<AeI!jJ5_mkG-3%`MPnfMoqtR}U$FshFAn}hIw3(dm
+z+>T3~c-i`_6Wu)W%m3uli)T>iSGnSAXA|p=v;X~e-gt8#ZHIeFr?X6%5~Q;;&M#kj
+zXq1UdBTGeTfF<Xh%%7ipjms`u%%Klj*}3gKcJ7R_YiE?cz9jQbtmE7jCo^|$4Zrx=
+z3&<$}+-^6PWlh+wi6os)V_BBz^?G*zop6L2p~Aw#uM`v%JhWuV5<I<oI468~(ii{b
+z?Ieo7lpo)58Kz~E$r_|G1{vKXr5kj0$65RMTeP(F@$hTEp{U3=oU~+f$M^O(v+7H?
+zp{lvaGi}-ws%uIpj}&v<tSZWi0~8nfXm5>i?W+GncIIq23Xkt{x$?_tJ9q9R7K<G!
+zE-wBy at OU&DoqT&d5D2{9(a{l0r_-UdXDYiB3FZVQuI5^HlAlLkYUlUAe}hXdIUR at Q
+zqQE=6kZ at dW32q5bKDCh*b1!7s=g#2r>n at _AB9ym;sTCov{Q7cS4ycI~6Yx3ldtCUv
+zPTbDnW<L7ZdSpo{4wq}9rsT!v^HESxfTn3kDT&A9#9}erZucHw$58diktVDMRaJdv
+z at 7}#v%$hZem%FD>;Ix_Q9ltB9DT2=}F5uzE*E3^A1q&9`jeF+g1$AuS)<n~LE%d#&
+zg{v=E&-?|ATzbuCnO;8yVH;d<_8c5oC_<p?1~0z2V=({ErM}6e&MPnPLanKV!7a6X
+zqAvspflyUk9uEZ$2a0Ltq7u;D+>BuunQ%C~9ym1At|OMoRaRD>*4Nkf><K5F5Og>k
+zXhO20tc6O~#G3(4Z941T9N^~<e3kO@;q*0?(z*MtXW75EnUxom<M(KomSpFF0XFVS
+zQBWA<(yuIK{+!{OgN}}VzVxM^05JE|xp=&8;{8c7X&uY5(K8v0tbt{in1+FAm{_KT
+zWtvEPJSL$C6jik}RY|Cd=#x^$)9LINk4Qiy5-EzsVrxR7&@~MW4Je9&Q?a?Q^dKdU
+ziA!AG+Ld5`yTZ>O_$n@!gN+;C<IewhhK6bni;s8XbvtmmU87RlXlsJkcO*y|8kbyp
+z2A?{uk;5&$Tz>ganYZL*dRjZUd)=>y)Kv}+86$th8gp)Du?(GTIzu*<!bqpdW-?^c
+z84O*gqoa>CYt|BvrvVmzXrW{z5;?uMxA)1~+S<~Zn%wHSM=@DZ(nO&)@myi;YkdT#
+zRN!=KY<cGZpF6#X+6w2W(ict5g(W$-DqtEWhuQ{MzdKELT(b16c|82^t32 at bS{}Xa
+z=WKgr18W}rcTPHe{)E7XLh7h<(?D8AKA&i5>ES!y`5m+8)$-1!1F2YVV(HP8$?eiK
+z?cx3V_oM4Nnx<hWZl3F_Cnenz<_F794{>1MK?XWnSao43wG~c){C(3j$r at Q~Y3HZ5
+zs-`lf*u{m5gRJ<JkGEcZ2Y at +q8@TERH?a7kWqjjv*YVV^o*3WjmN5u^Sg}Tf-?#5D
+zH{SSb7A={{KYV^6nyT1v6m^2pXfzfG1pc6D+N+y3ZOWCHYZ at 8h;ragQB&8cgD5KQn
+zP`T!FWn6Gt5pJh8?!F=vkdR4dNT<?dG8r=I3<7~76s8opIQ{qn094zep}vYQfBm1h
+z_{K}P>pORI=Rf}hOV^Qk;Mq~YN0NbMvT4%+zVn^mvHaqNEIVgD$4xEC<2%|y$?e6(
+z#dqqu{=w$WoAV163A{Yhe;lo55TS at s>ToFIu1%zf-1K(rb!*U(S%wal$+YSzTzJ`M
+zS^2%IdG at jY;-9bl0oi0K2XwHvhb?26jOU-<%8!2ZCoa8uDNB~jWJaVIB^NowQ4<i2
+zMlE1tadGkOU0q$hyLRo$r<RuD=A~pKJM~J$1U-GMYT3E)W*fuKu5wBt=dW1I*KWCn
+z-COr_)5;%_8W<RKe#QtgvKW~Rcir_Y4?g%ZSKoLp3s0HO)QZrksQFPWfM_(@rK;-d
+z;c)n#ci(+Cvv1$Nyd@~A$~Ha1tEm~7LYr{;>Z7V<4LWCYv`H5Sy_~h|ByRZOm9!o1
+z;+re)V4$}@Zw1mcXm9D_h8rHF`Cu2<eS0|z=1--nG&ly4_-F(SlJKt6>HN=dIDGGp
+z9XpbL{p()=@<bfAi+L_NmwxFxD)T>*ns#m-P*vo(@g49uIPKKqxZ&nY(X&~;e$Cy)
+zx?)JvV8i;|Tzl;=X_#5f<zG9S1#@bcQZ&*2y#%n1>GuMWNMxaDn#+26dae%!gC%F3
+zbrxQ4zOV#MSS)ZgF-_|{=3Sx<J7YY*Db7m=*5$_c1o2-_r`fTmiQnG;EZyxf7M?nt
+z7hl}L7q2*jIdf~MuL|Rsq at HKRihob__oq%erfTtMH2RjNY0sCImfoIBCJ(Gzw~o%v
+z&b(hhb at 8^@$P3vMIV?+#(E`91 at QnvQ!pl2^<oM}jTz&nyOq*WDj-64i`}T4cojRT4
+zYD*>s50J?i8W8`RelZe>M2-Va at 9*!wB#}rgibNvX!i5XRt>T811aq`zDwN)%e)r37
+zcd@(6%kN&e2WgE-ZiWaMB*!+gG#&1tH=bg8bumHzhipLuOPAgvrIdlcX-_vAjqZ&^
+zBJp4_81wu6?{sx_Er0y+$EP(mHi}bDIVE4{5GTl+*71bxIJ31TrigLndgCNxDHH^K
+zdB>Lb^wx;5H%Np)GOe<RNLeA8`r$^M$rud!faKr2sU3|*4 at V-AKdY+RR#a5fY#7FZ
+z=H}+J_V3?cR##U?U0ofuwY4~%PWlM3-VRYL`lwS5Q!cvE#Ka34X-gvz^o`2)CL)6o
+z1>i>m9w3?2(KI#l*Q_Z&mR<d5G at 1d{M<S7T9S+9_;c$3IHk&=Mt*z~(rlzJU(==Vx
+z)z#G3*Hc+piSF~!>zRX!q?BGNMJJ`A7Z14!mTlV%WNfT#jOU+x8K*<Rp$VLtf>RSX
+zHE^ilawxc54xCO6mrKLtavZs#gOW<=sH&QRzr(M_B9RC{6}jrusX(o1n)T^)dS*JE
+zE;minV_B9^6a~NEkKgad=kt-xX0bB^1Vw^USC-zG0Lz6#D3%JAux(3Pwvd*kTBbE2
+zQbiHA+wIJHy)H8laLYizD+&v}YB1<?27_L;pukN*frtM76puXe+QC;7ncBbW?*=20
+zNC21y%mm7T;z2DkO*3p+R?xC6uWj2dA%s*_HLI#>LesPXAw)m9vfUWaO|Fz at 8*p&S
+zp+gCB^^FCC8u+lIrYVJ*riO(OK_FmR_U<=z<GfGgm!pwLL<}~#94G^(06}t9sg6Mf
+zumA%{0ewIR5FI?GhL*8DPWi-sIy+VdNm0oy%W34?vN@=BG#dRx8uoty-->+5A3!F=
+P00000NkvXXu0mjfAMoz!
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/default16.png b/im/branding/messenger/default16.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..09dcf2a708548e619042d9fdbbc75ed7ad338052
+GIT binary patch
+literal 932
+zcmV;V16%xwP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
+zd<bNS00009a7bBm0002J0002J0UcV#`Tzg`8FWQhbW?9;ba!ELWdL_~cP?peYja~^
+zaAhuUa%Y?FJQ at H110hL7K~y-6jg!w$Ty+%1Ki|iDGehSM^NSfQogzO31zRntqD~c?
+zxG*u0YN8PrlE!KvF)U16;L^muz_?I1E^L~*XhM|6#0K3!Q|b>$DnTS*VJKl*XC5=d
+z49u4|@47Hfy3oX%oaE*#&P~oeM~Mjkca&0QZ*T9^et!G2TiHV88r0Ok3ADAfy%h`w
+zM_kwKTVG#~d!DxmEDj9~b=PXO{^8Td`S9b*ukI8IR}hgpK6uvd>Fevekxr*2olZ-4
+zceel%jYb8K(a})}27?lbL?oF^&WH#~CTRpl%7>hI`TLFwd;XSityaTv9CEoFKA#WU
+zw%Od=L at 9;V8l}{JI2>+u9A_7qWK1TxH2oUuiHI$Jzh7dpm;eHZ&*!V}_rtQRPelX+
+z=-Me0Dj(7@{^%ZEp(?vhzV3(C8r!x>rBe9){yOiu?pTLX51GK$n#1$ODhwWnt|%0$
+zuw8<Z{`*|AC4 at g<@#ET2Vl63-9gR at UWm#F;xNZUqI~Da_*e|R(P_Bikc?JWm4)@C7
+z0S)Rdv0#jBBFXDxuW;k)cXal*;d*Y+0OtQZFdM33q0I!XFTR879Avv3;+K3o>-4ix
+zv=J0Xi~|<u<|&s;%q{%E%39V^BEra%EtiJd58l`)HgWdN3sjsOi?j0tx}TuQba|||
+zh07POv394(t=$8(2q;CdSe!KgZsvklHoYW0$tvG|@g<q%Rq{n)VBldQjf$UsxJhq&
+z6orQ!i_x4&5Rb<(3}Z@(2udmI^r at 5i^L^TGHcDjnAD~*P(BwPhu)#(fL6%nYq#o%+
+z?^p1&rs(9^THU%`k8&s!I&<ckr)P&!yF?G}5)YdgN}-fu`qu`|jla#$Gqa3O470uR
+zJ6~O#p-`wS8~^;ZR4UCaE&ulUH+N#>!aZ0%KbFtJv`mgP26+6`gAAQ}ijUs^gsW56
+znV5J9(`?Y@{Uyp|GGmEEVmg~W_VtO5HU?WY?TvfXyecd63xoqM=SQETxjBSs8hD;~
+z|J6oB<OQwuyM|$$Y{K1$8^%V$l-mK*2q>juO3|dXd+#sm*JcX;?-SDi0000<MNUMn
+GLSTYp0<*CI
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/disk.icns b/im/branding/messenger/disk.icns
+new file mode 100644
+index 0000000000000000000000000000000000000000..327a662f196a293449b0851869ed7699a4ce9ded
+GIT binary patch
+literal 43113
+zcmeHw2UrtL7w#q at By^OfprWWK#YT~4rz0q$(xgal78HA9lTZ~@q)M?MDj*%{NJo$=
+zf*^_%dqG87Xi4rYh=LN-U-7y3x!*ttJ7?xSQ_h^7op)!~&SH-f1V!4}S?rR9AO<`Q
+z3FJO<Umy68$Aw|hh`jep=mFn7y*(qLZ!|%l7}NuS&;#`#-()flk9>=bl_Ocm14Go-
+zm;u6oE|U72To)ihC~-o}Pz;UwZiw=3Xc(?{G{0^y)Wg9M6B9$FQYqAK8jUcV|C_uA
+zV&X7OrcptLR`AnJ>q8RsjOOp_>EV!CZ|a#$ZGA_j#I&|jhs2NsqZR1uf$;LC3Z_=3
+zR-RTSRzwNBu_TgzR89tR)Ad%Co=6f?6BBW{C5ZfMelbvS6H`-hNlPnZ6H8M|6Qaj(
+z2}kn-Wj!WVmLQvnt~ir%4241&K=PAE3fR{R{vR+=FwrxX#G4rFgNhCfx6oKQdC1g6
+z-o(U2(!^L-&)CFdOap`F0by`Z-c%m^n&?X6 at p{Hc+?Ngj)dQh-kYFNjDkX1>lGKxv
+zWI`I?O9PI`A+f<hV|jUbeLP-Ll1UPge`&zs#zYQv2Zx9rL}N)~06<0}Mk)xJ=S%46
+z6%*@4jzDLBlY{1=6Lg0gV7M<POfiBlHfnvt- at pV%e!=&!ybq}SYLg?DIr8^Q2aPn(
+zg!sb^q)WGWBMsQsJ6r(7^v48n2<nQIAINow2!kMiKVN^rA-Q)1zqgk#G&D4b{EYpL
+z=^v5zf%*Wb;a{<_q328c_R|d`_VY)7)fG3*haePw2!aGbM{^8+F!wq7IGQ**WcoNd
+z)((LWm7_yhf}=we#&xJ~$904o<2n}1!F6av<2tlA;95mJaIKu{aIK8txK;>4KA4F<
+zc_6-!MtlAmd=UBAg5$u at 1)mO%i9dZHe%wb898d5W0&(L$Yr!$S50W4H66`FTKs!Kc
+zt+-Z9;q#KNg2H=T1x`i21(-ZS9t!!nOre1RDL5oJv=;fHj{R|_B0p=X5Cm{!k at lnk
+zuPXNCr*~u^1FP)S?I-KvdWHv9Uk^?%h5{TK7)l^Dtq&*FOnnF3*Wl=}JmQbQcoQ4;
+zG-SxsL=JcW6C(M`v9YP7o}@7)Mr_!VfK(>HiAah|N(>(Z572LHA}=n<AwF!#h?$dh
+z`z6TYV#6c<tJ#BpfFT1X`6VEJd`!zA4TK!`62683#PG?w- at +G9g;e89u-gTS0pTkN
+z5Fht}OMU@?K|vv5m%=Vx4Zn8n#?8p6xNAzT&<we><|j{@p0>8OJ$wG*<*T=E- at X6P
+z{-M{K!v*5nUen*(OYZ9*80_oqqf%3H20rz{G*rO?62yhxS>My~xwESy*-4R!Rocmc
+zczuvSLsf|Z8N=>oa#vSRv$?#242qLw{d at +Ek3iNW4`eK-Ui5Vjv}-P1$<4(nz>Y&f
+zc2ppHtpQ~0UT+5m2GgWa%%J~JXbc3Q<ALn+b`r$R8~m|<ur(&wL|TBAk!!9vmVKV;
+zV^El0TOgbl-8DE+eJLR+#P8ghb5}1r=Dfe24Aam9M=(T)UnI46aNt%(m?xYS?Hzb6
+z=2BDii#!UjN_QNP$`$rg$TzMA)!jaK#^d^#s|2sTJC6V<C77KEaVl30Qu;{Oed=yE
+z`erq~KeHNM2pt8;)JQHOgxb~sQ#jy&n1I~t*FT0v$0$h4%Y}myrwbAx9_uz5jhd|)
+z5fvMM^?J5z$jvKZzQ>XFD-j_;ycnm~;B47%Y#9 at koSvO>CAqk_Ga>dR5Z6i*AT+b<
+z2LcWASkvYv;STOb|DBW at _n*}QVXF!da`<%;Y3y~n20rQe`8UYjRV|&bs(|p_79ixk
+z)<dGPeGJ^b$>OBrmAL4b<g|N0)@1=?^OMQ0G?t#Gdu7dJ%FtlnCo-r?-+nX<p+)nC
+z{AlPw0v3i)a at GDcG{u({hOjDSkDH%7g`0>^p(gicOw0QaP8ed{T==s6?Yocd9iKZo
+zyFI%w-9xwdVTi$~kxHZZ((rc|f}V5gqz=Lqc*qreIH*+MerdHUAP9TrRrS*rVw+1V
+z)aKH{QvaZSHSj}(mIfakSpT#kPTxRpdt6iLa-e%}+Y^h`nrAm+HKo0t7YYLfDv#eh
+zEk9euSY2K9{L at 8H5)6Lb9w*lWZu=o8cputvr(iDh_ssoHVfH7`aub{TLI3gQ-udFL
+z869(fecNB2j=A?|M(h-zWA5ZQ4;^*!nQV+0E<sTgBd=TyD9ot24`dwJxOJPliqZyE
+z1HFxrWrr?|Gxu6U{f$bi4Yb#*Z8LVtJCW!&&fGh8XloY-ZrNaaMBQkUgVuV}@#b!#
+zyYaS1)b8+%EYsybn)@kzBSUW|mzuptk1vyw``+9)m>L~Cq;KJ(cj7GJh{LvCP~>su
+zzTMi`(r%aak+8_RyQfaH0r5C<H?b$|#vOhU>~ZjN9AdTK%pFswtG5T<k2~_H{8DUA
+zQXUYFH+K!q&6=?LsS`xEOd$Kg+=m7S$nSgp-#7Q&`&|#X0&^$)eRD6E#N2nCA8+m*
+zb at BAf{mCH}QF`VM>rTf`VD4Dp-Fxh1T_7CSoW&^YG|5p@#{$nja7qXWa5MN6&RpDb
+za at 5S35U-xVg+fi^C7 at W@c((-T9&#LK<!@)=1+E{P&!)G9Z_W~JnPuC at Tlp#up3 at cw
+zbX?956(_Lr<MViznQA#)*|bGx$&XepKaXEcZSL}IYi$l%@6c5H!OGPZ3(gZ-C}coz
+zy?kc-*4FQ>Tvv*)2)8xmpxI{o1Eu4v960sun<d1=bRv8l4mcmq`N7InS1yvZu{Y5-
+z*pc>swUw^|P92`esqY!%)L#@V1WsM~$(yJ5fK$JZIQ1al)ERJVckg#10V8+YM{q>%
+zF`bhO**PJT8FV2#1j(kRCZ}a(<>VDrCkld-k^aZ7u7*n<w=ch at d|VAq3A at Py{?4*<
+zx#zIt()x8kCU~$}l?7sCfea}_RuIJKOSu#22RnNN#66)MfgsjM>W!$xz#D-CrxKbM
+z3gXG8oxPTqlpiQ1T}!))h2~b#5(&|_BNLm8i)go5pd~Fd%J~y%sn5zDH`4BML95%r
+zdA>66Qo)1T$Fv3kNUMX^H$duV>!Y>JhxFS&edzey)!7MmV+Y<XgB*K3Xp9}}phHjX
+z?Ok>;TkU_M2&v}=_yq)z{1`)$7eNfXJTNzj3(doYo}{h;_XbDm+S}kVzOGMQ7ce1p
+zHTY83Hml7_tJiNl=~6yY*MS{-JanD(t#q@#)ODZHIqv`)@#Qt6bv3lGHoKS;5dF2T
+zW{!46VUd~N>gw;EoRf9$H|vTUt*hJbRP;jWa7Bf7_hcL#*QW*242)yzS;7lL#!NG;
+zO$$cqN#>WgSg5jK^O}?|_0*rc)80X4Og&eM%wO#6V-x(fo~kPr1 at 3VS`&Lgs=jep!
+zykD;8!DggSztl4);A=g(-H`4?*&RSkc#8otoA-e*+NNe^um!>FjOlqRg2h>D&s~H)
+zSVzY_Hl{ie5YE8ppm)fnurR_Um&>H9a5#Jo6%j$aPP_?6Vxpp=qY1Z&v6#5H_;@%0
+zm6!-8xg-;B<5E(RBmA6AHLgO8k_M!R+u8YW0jjVNE`p0uckjX_a4B>TE`!T46&010
+za22Y$8om$LpdLIR)Dr4Y4<8chNe%ELmqyZK#>VoTcpq!!%Mea-<FTvB*+ms_6*Qb2
+zdH{pe5J(I+pdLLUHWD7gPl#ZGh-z*owGdlTZEd7y#OLq}+{@OQyclmo$x9GU-o!UP
+zr>Lq9u7MvAYl(I6Lt;G<=pr@}zvU*jkXi|CF3)hU+Mm^Ag&$D91mV{oxSm~9*6{ib
+z at h$w0 at SfNXe;|A$enNG05I++-QC(fcZbA<VT;G$4eW?EaGXuE6!M^s|+a8-PK};Jx
+zqSFd1n%;l-K%6KKkxW4H5C#Z?sG%VO#f5sB#z^gLDhxA{41;inXCqRJDxbE0%}Ye|
+z5xR*Z`iAoozvVpx^7b_s#q5?0h47Mk9 at o>0t6C>6?0CgQ3W at 3sGWWOMjdj`-3R--d
+z=gq8=`_EudXt;y$`Fp+a*dh~X=#GjscaVSJd1>4sl~9ODa{Jln?9!U&AHP)^2IU at Z
+zr}3%@6vp19>#qi=RG5Yxd{dEC)Pf)lzA8&PqJ&h#@Ip+^z1mkF3Ev7bzQMmX9^)G|
+zB|CYW2QUrO-_g;Jv?S$iMT)a3sF2)F|M=Xpy4Qr!ej6zc40`QL4-iLsfVE3b#VjX|
+zAV&l)6*LN#(q5JBt_kY2+9o(Lzr5k?rymMJA`5oqoZ6|ebOsv=zhJ{o=i-4O3WeIW
+z*eO6EDE{X4$IsrKqhYBZYckJn35A%~?g~pTtbFwT(})EjB^mBen9TD0ZrF|m!Ykwz
+zmQ6#sK+~ACgDb1$tzypUDqOyK_k)3T=UIUBxi;H(8z|5Qrz<H%Rgc>{Mmy+By8xV5
+zL=Ev}atiYDaxyqihy%}UaLxOWsrb6<aWUtWkMw|QQM>AMf(<~+s2mMXE3SU}kvOiC
+zVKV0U5?MKdJVs7Vf%^=^A?E9S&_r!H+p>^Lf!- at a2E9P*_B7^SF_jE~aB76>8723d
+zKN7wT2)GwZ?mWjYwb}(hD9l0;z~wZG1aY$L@;P9vx at -m(Vs!NLx7*x|0Fj>*T(^`A
+zhL|NaU2kTU*0g^5JW?8 at MtHCQKrYu3S+k0uK$J(xts+8b{47=?gq!8(WTdi`kAVPT
+zS6Uk=77cwF0Fid<f`JWgITL-StoB(4DAY(B<9f;c{nsU>SGg(><RKX%#DHEbCCmmx
+zj3UQ&C at tZ`kU$LQ;WjFQGtgQR>!=b8EO7g|*xd5Em!oxqdzgFs2Zx3R&d--uP#~-#
+zDq!U06+}r8>l`_mC1BlPsi~qkFWLpdVBG5ak?IXTFHJbC6by!yk#Br{#lu(daDmvt
+zQc&N(5HJ<;=~=536kJxJ6y#t9)JjkxHYPNSsH_|h1Tm}==Rv^m7oH3vV|4IU`R$Xc
+z!4QkQSzuB at W&NAZPQ(Raz(U~wJcOrE`h5ie*lOY`oQ&8U-es#-fzuKmJ7Wc_gtVL#
+zH at MDb=fSu_Xz^+aFiOhX%2XFE(DJKoLX(TC9=#g|o7U4iFi1g4Hk81~1Hi=A!K=B~
+z&IQXMtTVaL5Q<AePC<Zc(M%T5uMox^LaiM_z}{D9oY at STe$AfCsm1pnw<Ep^3u+0#
+zz!f-UDAx#@yLy#0nn^-o)jAee2#?|xTCj!>g+`r&Ao-ColI61%wA6+J;prtcO&^Kf
+za1Zam;Lvbk>Ms~Ui{%$FfC-h*T5+ at ogq}7X<qJVJ$f)S3%L&p4IhBuJ&n$iL^b-tB
+z2h%@@XvR^<A%TZkm at otg!y>wr=_-UqLAl5v=&a8TGXe!xC*I61t8Mw*4KgwGf)!ej
+z3rnf=3%sBj3!wzMkY4O=%#Sdaya?g7+ at o{K>)JX&T2ya8JOqKnj4vw#0)oyhjfEg{
+zBysPPqDULbAYeT at -m!U=51)4tdeFVSpodsMqYhlDP4o>23{Ve(7?>9?TEyrLLHQ%b
+zTYPKJsvs~B^nBtAs_I{M_w>NMDDoiEe3YSzfXwO$|A2sy1G91H^AHmQ0~%snEF&Yr
+z=mnNchR+ at SttIgXl!G7^N#lT|qUwfM-C&U#CPM%LEEHYy4=pXd3J at -a9bP||o7oFu
+z!AVKZXJVW!BQ3K8bq2zq?)CM7`5|!SWyvR0K}qB-f^Qe!Z+r`22xJIUfR93b?;GHM
+z<9=DBA3zEY^*&;~b=?wvoIAvfUoIoFWZ at zyNl6hR#KwSQ<>H#o$-y~|Ys)ED1Qi%>
+z3P~dfI8(bzsU<a!-y@(X#Bk9RY7-#<8&zGM9_$MTEDyXG9O8f4`Jl~KwRN(~776mP
+zGt8HkTfI(ESzS|Im``Z-jQMLVU9aAXOG?WwwwIOa at t|Rc-c+Wa)(isHv-fI7X>HR7
+zA{o;MMi at -N4A!MzfCCuAt7<Fa{rpJ*gg_3z3qI%1dV8Jrbo0M_^=den-!MgQl#q{Z
+zdi(xUC)|qz6~3f&VM7G~ro6wOd0qzrJ`|BvR at d~AK!*EJ2r$Fb!s?rT06FB|!@9fS
+z{^tVF{-L)>F}$}D9i(;E#?yud`uoVeJ)f?w at _4-`oazq1KGtLh>Vh^<J9+a?`NQVV
+zWH51HM$Q;R#n<YJ!u;U?CjXTC59_kSLjwK10#JSt#2CI?w_*dO?gXwkt?KP3_x84j
+z$$Pa71)l5yfWY)~Lkxkfsk=nyR at S$6f>RpY&jbMbQv%Z(?t~BmSp35CYZ~jK6R%$M
+z^FI^7a4kAICI-I6ow)i6^}(SHq`Kb0H)q!Pw{`br*t|f_zn%5@;bxM75N at +)Y<^Wk
+zTQ{MPy}utUjZ!FGQ303kHe>`60@(b5Vhg-CCO*iHy%Ol_=MjMM54{>gxW%2Uy?2P#
+zk!rEYzwGG7D=)e`d#i0K5!mj=g6r0j0bp2cJr`ei|Iv#c(2mIb2aJmLt3iI(D<7r@
+z_!9y+g7&Ulp`6|Hpfor6df<hCK-U0N;7uYZu&r|Uz+nHgD+Y at CQ7^kYJG&bkvk>H-
+zC&kgbRs{gJukV*sT+{fn7qkIkU_Kbi&q6K+21M1><z5U33JTq|{On45&FsgI8fvTV
+z-MQ==792zjL|uv{#;_$Gl6g1KPbPOh2#SBz1$Sb)nh!@K;N+(zar>15z_2t4N-3#*
+z{05vyhy(B-hEjhq7``|+wxO>0GJsxstwE~7Y4i1rs)mO8NBdS8oD2>PzIZX{G9ivF
+zHa3YM(K66S?&<DoZzpx4U!4d+u=`p|la8r?f-6{srIpq_e%l9%O$5;QFNYCAX2mx&
+zlwIB-9y-t@)%ZrwG%PeSv;4_=DK*7a7N<ku5Y&wugm_$%mvq$turd<xx9E>2&mp*A
+z0N;kyK~t}BxRO!!u<3mt0?RN&sknKC7&bTlVTQr#R0^$8>M^Za-SKi*Xc$Rquj;!T
+z+f|x-eS$+{2?^ZE0jq9ze0bM*=Zc$?t>I?nRgz2O&m-7_FTs3o6Tnv77m-z7|MX)&
+z3}&H>;DkXfjJ`^|BzM(oz0p$|h4N6kkusR9cJj*Q2yM+arBgK8>rg`#T{tW{Ha_9@
+z6)i(6l_kQ97K;ea7n(PB?u=PM?FjtPo2m@&EdjunAGw)R+0gt6LB|1mrcy6n4<}w-
+ze$7KUi3X^&`!bD#{XGGjJj1Wa1`m3!zDFCPQLBhL8_W(9JkFigT`4LwZ;rqWK0d+>
+z%uH7PRL|j|obA6I6kYXHbZ*t7mQK(pc%<M|nj0yS7%qD4hOKe)(7-^2+~a|s{`Ql)
+zfvys*l-hN6Jp*L&0PV5wPFbln8x+-)774(!UFI+da?DQ|LVU!B2Vg=43cb-aw%~qa
+zYZn2yToi=@Q_&YCuahD~ZUid^^z at TU6dL=wyZc+MEj5j(lukFf1R5YQyL*S8MmVlp
+zt){6cI?r8*VZk)fG=R!T{Zy9+=2-p^PTMQKsOIsr9vGRY5-E&SY9;%==<9?Vi?820
+zzP^s!o4>YYu&1-LzfON~4p?d|U$bx6);c?TXz!yp$|x!<b{EDjTF9wTGz|Q?p&-Ii
+z(hp*l-0qW9T>JP18JzaOB?y7a at LEjGEsl6|QDo$1+rF->l~E0!sFXpPg?{JY;J^oh
+zQqf>{S2uZZ;I5~UiiE^cQ4cYUFzd!TPf*;h#-b>PRes>~vm+p-q^{{z-!LeVitR9y
+zunLGFMlHPMFB{*Rr=_jB(dfv<%kmijv!7hJ)(!OC`vO0MjaIO$)LL=RrI^KRmQ4s|
+z&y%|`j!J$I^QxU8Y4_ at z-t;5oBvBdr1Lx^DMaGbB3E8W at Yt2c%=6!s($p({8h|leN
+zeM~FjtkL at Qri2@X&E`_F?h=eEq+}MddA~t0$xllYj;Q!Scm?ar8RZR6-wq(xKsXvT
+zPI$AfdjctT-gUK;LmeF-UOs*hwNAT$HUw^s=*?NR*8I3%TwX)_=NieCt};w3SFTdm
+z*5K!l?L$EOTFa78sRPh8yRKzdK5A|U?1Kxqu3;?SutwiFG=UU{@mIV#K<woFe8*m9
+zOXfgdZ||$5)ROua9dH+_|A?DBlbq64-R-(c_*I$6<xBtb@>I8tpyo<WH*%^PTRwm>
+z-~zZRT<0!Powb%X5{U5(u_rXk$%M`sT_1L<+bL{L=<MqJ__^y-acpAJ?Pz&fd3llo
+z%X)1+T|FHU%&~`5%J9kkWo7yqZ9j-f<!Dsi{l~2x6i|5*4L1<AQch7}e+)5kc2bnN
+z<+C0D*1S_YvEYt}re@?@z_h$Quvh|M!mHs`umT&nzL1q)y+&4Hi^CxTW!N*ksm}7<
+z2AV(}jwz^l+}a6%U1_*CTNkcVUVAE at m?W8US=+Uv`$Md%NnCbrUSUy~sn(U2Pw$S&
+zD8~=b`a3_oZhP{u`d(2^dQ$9-tD%8D4sueTk#qaInma*yeh^O6J-(>6=~*|4>PBPg
+zygF~Ws+y8V(rrTWtn{;**B>2JbWgpVl$o2CS6FbxXye6drvq;CUT>*j4uEj)z?1aj
+z`uh7HnrxAM0h)r+UYi?cBIyg^bi9-9)-^rvAyPePm}U(&Wmpq^AvG0FVNFdxs<mOq
+z&CJx4l+1KEU#K8IGt5X!*{#KIm185g4(JDGcyLPY>Fx&2Rl36 at V&ek@`QyX<aC6BE
+z;9RGBA*Hnb=}R(!>Pch%bdzh|Chg6-!RhI68a5+wFCi_Hl(sNCH$N{sJu^E<(Y62e
+zWo5mReq`eC6}Hf1NAd&XJ4ok!ZYaEAxB3D&8SMy4D{E+e)la2*(U=<@u at c+1ZZQo@
+z&4kl2898?{+|r>8Li(J{6uV=Cw0F0*C?<3va}lJVU0t2|CI(5*U+un*Kz25QX{Yi9
+zFfB6+&8TQ>c{2d6d|7%5G#J<G>uxo at kdp0_F()(G{y;yK@*&M+<)x3na))6$atsYq
+zntR@!@J4XDn at Zvjs(>o5vb~xO?DajkDqwvXwPc!>k%6v}M^bjyxy(6PDSLL4DT9=c
+z1rAad-h$I%cURB5gw4j8PrJL{dmln at dYkVholpWe8+KpM0rrXDuu&g+3Cz(k-eF+q
+z9GjheHfv6H>OPwu%D})-N5$cl?$3I=yZYLKmF(^`fqwW9W`+QfTfux&9RRIA5S3rk
+z)cTQfp2pT!vX6VN_D)k{gCjSxbG+}&$VuIA(Tg~Z!Ol98+{vb%{svgdxwyFp?nHlz
+z*^B`7J*!Of)B-?CCt?bK`F*1L(AYb29QbBwnVFmI*mpTQFZWCiUvBDNv!OxYeaL-X
+zPtLD(dT`Hvqi^}kZbB!zBYgt`H1M)2!)Gf1QYXb1*FAmq831um-{tHR;8U}-vE1q4
+zpOlw>I+r&ub=OYX0OE9d$=$6Xs#dys*Q(pQNS&z6RS3 at D>-*UOx&TMhGpVG$`FR)B
+zm&Wln?}!lBIukoPD+ at RxvmoCik10RR-i!ud$h~k6zWc=uUCV at r9{~)yJ8iuO4M!b(
+z`yeNDholdL*EyGRuc75d57m#x`L at ty8M}y<<t}?`hx2iFiVEEFxeL;4t!W5Q517Gp
+zb-&Eae$vtH(uwK4t<?=mH1xhM|Ej4txGIs<^GhplY<)$h`qQSjmtEAJ$sxVne(!FZ
+z!+~+x#YKgr0<OX|vt0md1PV;zUO(^ba_z+QB^kU1P?V4L1vhNu&qH`|ql+1pj{#I5
+zjk~Kh;iNn#&w4%c-FqDl`p0J$+$}DG3t5ZOcN|1&2n at 0dOxjRg-R_;3{v?Y=1nJYG
+z;;7y00g}AgrR=IFZEyO6XhM{h+;BTFb}lhBL(AQJ51zl7nq630T2h+5?P%{Ouv88%
+znTTX?*#)k>y5TO&z-`+~q{%-&E{Snk1F+WHh3DRHdiHi8m?qU-mlkX#Gn0i=MAg8^
+z$i$8mb}KG1B|+8X+O?=SK&$7Ml$BRj)jWLkq~+PmH|?J~DOtM<5VWqQ(u8A*0Bz0Q
+z8~G2OK6^hHN|R`>PQB!AymAIBj%m8U0&$6 at vdVhaOC?uGN=wVgE6B^qty-t3vE9V(
+z0PGbMk(gb1(>fc$>S-=ZhSdR<;-Tomy5{E}D3 at r<KiB0%2e{g5uUoNDfQN&dUvR<l
+z4SIV|oVgg0lAD!yGtAfXl#{LTRt;6<4eM5~k~hdhkjSkSsqP4p%89t*`j+P(DOYH`
+zl=cU?i4hmiyAe(vJAM*&KYQ_dLSb9KHx1YGuBE;rFZVf;weML~#<@)(t2!~Uq at nf2
+zXKDnEqx)^s{i3YQw6yd)We?lh2d{yI{V(rl`Rjm$nx}7<HMYL&q(+0g8HT`L9ChGT
+zO-`^r|2bfeK56BT+g^239}in;ZSG|g!Ltw(ziwbgWz)0QJtOh&9~NA*S`Oj`cZ6nF
+zKYjj&Onm~n{X;|1O?z1oz0~|lZcX#^w|&FWpBnGp+6SWXGIkO9wJk5+^*4dUpC6aT
+zA6WxpWgR06>snsCA0ScdK{-2{?j<>|KMOIhIT%w^_q63XSRQEX!SxM%dU7w>RTX4d
+ze>}FJI3qSPnh<j~_H5kE_|pma_ at u17yG6;K8bGc at ycHD|d?ld(E+Q2Z?h;E#rKo%N
+zNM$bNaD{87YZbBD<GxP~t~5I-@<!~r&7iy*XTn1gito359=oaxjjpzyro>ZmgT0TU
+zula9h at rGCp{I4byRo8=Sd~mV){kp0PH3L-QQ)SX+D_$>%mD%KcM0#mW;~OOHm$mAz
+zOQ$4i7E<B*J2&>s^MaV!_0B|Pm)AXcj|>FlVscEvY>=?Ku`u$$axaK!#`g2E;F9xc
+zJ4iRY`i)#;46kI9s7OLEb&EYF0ul-v2P72SZ)o{6s+u^GkVtVIE at to3(j?*vF9<JU
+z8<KMOL1SCT7eL|w2>~QgPE(TrAi1S1<+L;?qNwAQ^m}zpFFJdBNn{czB5A;7kT8@*
+z!BG(-PQS1kfUP(h0S5i^_uX)>C)u;lr9XRsv9I%4RaT%1kjfHo6*s<Y?*`c#DL8WH
+zhZl9ZVcI~j-aGxlv$r2R`vL}h`p@>ACwn5!v+Lvgmyb&#3>eQq_)V8eo;-W;{MqxM
+z7opFCo_Vz4pFMlt_M|-4lJzu%XEcqgYJA*KS4*e~eh^w4_`szG|Dd+Mv7s_~FW+g1
+zk;(3MRb9<}V)Y~NVZ498rZV*i|7nN;YnN1h- at E!Q_%KwJr#kVTfzYOLC8R3f>V*5g
+z)ubv+Nwf(wSftq=Sybs(#ZVOG=R$ztVrLj;Ah`HN6}eV1R2E#>$^eq6gcp>%R$+>Q
+zZ1k!%F?u#ZMJ`pC%DhkwF9@?CEDy*~k+!v(DBDO7Uy&Q6>;++^{O*)hR+6ev7xaNd
+z{{pcJTUl9t$4>#|S>l~}&$SW-YXONC>{5v-%R09b#Lsm}FLkYC^fuDlVQOw!W`(ub
+zX{>MTjU>qM6axunoJcMK32yAQ*|qQB;j$yxLr#0_9B+aIrD-k;y&wio$N1t3mr86=
+z at X=!@;X<MdiIGS+b^K^Z5vh`)qBP}%07!&3j4CWAR=}0m;#(JvpFDNX8F%XB at e47<
+zpu82B;y7DoZwMplpIvsQBEQnJ%B=!ZmVH6~ELiU|iz<N2{VEbFT`D}P075yYFw$z;
+zIlyw--pna=E5BQTs;VGWxs@~A%fGREwhzR}x#e_pW^Tc`qI1PJi#!U61=zgoSZ_T(
+zUx*PkL&@rhi>LeP0M9cXUhZygL{~Qwk%%QZJE#a?0>Qc>1M?NObY>I|?FCUL`1y}@
+z`;T=S^`?K!x>Y*cjjZ(i53C!<7uF5j(^;lJZKh53 at YUP@z`C)0Vclq-LR92^TK|l7
+zQ`n=Uk=OZGShq_$n;QR|b&CqJ(z5?!*6oU~|NqadTYFR8d8t2V-Cma8j*7f)vEYwc
+zw~r4JuU)!)`HHdNpR#ToJs<BUUb+;1CG at 5#|LQ+x-CkuzUJQ!~xfExQ=KV9)ZAMSe
+zi^Q0q(1dXRct`QyXWeG@^mHc0T=9=h2nu&s7DN3O?Z#dZb1N`BF5WjpQ%#nU`PXPS
+zw)WWADBsA~_=~$#RF#D$rQJAst7Btt21Ldux|*wk^&j5JXg9Xr-h!Ce8-X|CZ)sa@
+zQ-M_>p<kojxXGEfVx#;c5>Kk?n{QH4Rn?GX$Dk&s-2}$cZs1xuH6}LhVo>~cRSi>9
+zO<0vtT|-uogBklB at 8$)eOM8*qvL>Y6U@}Kn{;k-!Yv=tyAvT+vZU&WLQrA$FTfRt;
+zhZWGT%=i^DGE0RQuauG&^@h+ACe{engk&48r!qP=HqPIPpo-PDFxOWHSiEX#>guZN
+zSII12BqYesH=Tn82Q64BBL~Z4SFM)iLo>n<+st+5r`$a}PJ8)CW1y~y$u{P`zPcy?
+ze$7%(8PrwN%+hSDs*0;BtD35cva*t*;)V_D*KQ&hz=k{qCUa0szO~QV+FDzl)Zect
+zb>Ot-$fZZMF*PQD8;!h-%#fNhs+(9^8f&VYQ$?$28Ig>6jdn^vi`jw)JKJBjG(M;-
+z*vqsdUEY%})yCAG9vc^PNXyblgP at 92*=}xSVW6dPRu!eZooLJluHiRB$*$9+)1E(j
+zQdgblz-W?KYHrv?pJywGi;uQZ)3r8GC#W*3Xzj4Dw$$3DsjlLs%CK$64r623h}#V7
+zK`q-h-7w{0{T%}q+uM0XE^^Jt36~zt)*2TdVW_&%*h*iGpvtDAreh?_vB}avM^jZr
+z#X}XNqNQU at Fyc0!xv{6`S(u!l-DTC8PAPdg1tC%e2rM0%4IW at 6-%beKqOP*Z%u-KP
+zg`moz2KHUyx7%8n8gAdDs;sK!s)|z6CmM0 at 6z6->{`y(TaWT%tCvNBF<m82~i9w+0
+z@@zG+zMAT)s at hhTJJf+aX)cBiqLo<mZLO^>%}ot8l(jU}iE60LCPZVlowAt5*Uz5R
+zS4Qt9rR2gnnA~XPKm>eZo{e#E at I$J*=0;dUV5_y2iIxVyK2r<b(VV7jU~X+~Wh25k
+zTY94=tbtP3CYZ9Bn3%1H?!9>0aKEf5GlP_aPSkKgz$YZy2!jlLbtkkp5j1CQx3)Id
+zoDGrs8lj4&MS`0&bqvkyn4y`|7#FP7f;CZkdW4-!=IT&V>!aGryZMA%LLNF(;{XCp
+zk86A9s;f=Zn!DX*D<A8%!J#VXZf7d5xb~(^o8_U+d~G+^GIK9c-l%0lFypq^g1t~%
+zRuFS$m(Dur#dElsQ7D#S>`Az`^E<W>H_zL$7AN(9*4up-Rq*zu&opUm?XCQCT6uTS
+z`tBbU;}MYEx)V0XTI%zP%kU8(W)v2SV`5>$b9lW*N<InIMl#YNZds<YmMygZ^N07@
+zm^)x$eizT$ty>ugefyXbJ6^tRi_#V1lGvzcV5qx<o1JwUHy^(Mksl+#E|B&Urfrix
+zY3t(c3zwI*zj~2`&3OEvwr~^w#x+m_xn$a!mbS<B^^GxROL&Cj)zmapMLd3mWy1su
+zn`|R&7u}|-h2P)O+7yYq{h++GJYH%cmqdTp3tQ~jSM?7nOH1xWIm*viu;y2JHZ0)T
+zIJWAObQc+}WJ`Wj7shhCx;Q_l_{st(y6e-s+Z;-bbyfF@@^bRa(+=^nE?xZ_ESu7H
+zL!$m70|Rck+KLOPqc^h4?%jQ`Y{{FB_Sf}BoMH84cMA$j?q1lwcsgqK@?T}yB)9AA
+zAQ~>*p}{~X^P4q$I`1MSD+kQAPaobqZ;s&5e{#Pn?d(orUa4)mjH{RY0?UT&4;0$E
+z)xgC_NQ^rz!N=p6`KHz4?2^wuynWHqRI-KtkkMi`R&kw^0kJFi<bRoD)7H^3AsNrp
+zo2FiR=T2sF^z{?0^P at k#X>Dq#4Pa(jw$aYjKQc2X3|jtMB%9$zeN&PNMuXGoE-8n@
+zb0ve&#g at j}>N{u8hejr6!?~DZC2j?mUuD at C5tdC+-I%nK!9;duU?CxgH#b9Wx+tT7
+zM at 3n2PEKx?&(V{o;6qqJSPT|tTe at 6UW4o^Imc^K3b-zHft<&B~G!ru4F at HsTeok&q
+zwD=6`{ks*p_>N}W$;nGu2W}F_<5`%QnD8);oskjCfWb1cF>@|f-fA|44BWv<h&IJ-
+z=0pog>utPSvhy;JPM>GC+tJa<X`2x5u3K5D$~eA|0ZQkamio$qjKs(*LFe4zBm3;k
+zjb*UVM|wmXZiHx4F(6q=*sAdCk66pP!P?5g-f`bPr+wQ6d8|TK8SZ7;-9qjH_Y1s!
+z-q!r&(ZiamihCu+S49OGo`TuPq(mFa*qUI)YHb4+zUS<)x3;pfw}tl$IqkRCnZv_w
+z-$r23DEZX>=4IPcu&7p3dGBsvey-o5B}Zo7Lx3md*_cLnHtj8Dwgeljo%zyLHg-fC
+zVcXq~`}gg(vvb&lw;{js<`a#3_3BwO0$Wvfx3D1RoT!M$HIYPQ`ZO`m#x%mS>1?;K
+zh3&AmcDr}k*%IwwTa-QcGsoUq*s!<nMX>O6pC`bU0cv?^Q9-V^=wkQViE at Dm?4(@V
+zc71a at 2Os-64%UmdeD3+&7O at h2q~<Yb%JS0Uf;*>$MNTK=r>GrAa3<o~SiW#=`UYn9
+zyUshz*<~Z9{-N_j`_ot@$gZTe8lV)Xoe)@ZHa<5m&0r at 2GZEFs_=ReNcc9Ge&+nSE
+z+ji;tH=o|Udf9k;3uZ at F<-Ow4IBQP13vqclxfymU2+X8Jn~AZx{q8;9yJzgNU8eA=
+z{q>91mWS!aIIZ~7(g<)84~fr%bI at 5wmLfnC5p8T=iME{<_Ivhv?cv*NyF~WGn-^`(
+zj~_kAwqsj=HE`uj>#HewgdB9X3qOK05zof{jc2p4LVz53?8Icc0nC$z+6R@{2lyoB
+z2_K2b$R*{V+*lEm$yqiV8~Z)`_V4%D$FtvFOr{61dSIUArCBG0rCg)301P^h#6g#3
+z<M_(5IoR3naoq3ZzMtF4UUXFlGI|~$U0#@a&L{3pu1gN4z*zvW;B-hf_OB${p5424
+z?cL|@#C5=4WWxsprn&-HPHtXm@||4Q98A%v#ccp)LV|7D7=mrz-o2naPJ{zoPEH3L
+zgg3r>+)#TT^m_rA3FhXx=U|FYN!>?)CgRt)#`0@>oDLi~bm;IQ_%Q2{y$d!sR#ldl
+z0k=>@C<Ge=^7G+5;Fa&f^23za&j~hDb1VDZ4i5GXRx_6#J9?7f>T%{QxI64(aM;y|
+zn}B$`ot~9*&wXtg(s#c=uq~BYv2 at 9DNhUliJGe)YZw4O^H`ny(Gv|v*uhZ1GbUf*C
+z(Mc`=!TJS)jfa2UVku?Ay~o^rf+G{6!_K=LaWK_UkrSUkPjI%t%o)>{$0JC;Nw9Uk
+zY$(r7h-*T!{ztI=N3adw8~7i=_P-Krw&Mu4{RqKk^7{mv&d&(8^>hd}NniQ|o4D8i
+zO0XTLPq2}Gg<v~AOt2YDPO#ZbK(P79(IeO_hY2>D8*~UZZO<PGHm~i&1RI~C<zW|3
+z7Z2Fe-vjbI<L>3==1O#dNUlU80ZTk(KTNY>0L{kg!WP5|m^Q}$n704+xBajgZ~V;=
+z|1oV}@5>n7-?nO(qWWKA+AeZQJ^pj1?Uwn>KWEx*o_7iSQ>N|m|HJ#+o)^ZQlKyk1
+ztuFkqiIJY{A2V&;uM+ldQ`b<}Svl{|nYP!ld)3snwUmsP^RM}1rmX=sUZ-lQsA??=
+z@%=H=_F#|Y8fAygG5`$q+xy!9)An(nm6oiHgMubl^}+rg)8=DkA+K#`C!xUzK`54A
+zW7?RW+gh7Q8{62+^CeEUxs9ne+S<lY&dAnbdGaLN+L(KL&so_RD(Kr<;x7Nvel|QA
+zwzM&k*=D~I>|&i{4;$}zGOhcFm5trHRW|G)<9Dt7j6K7B@;0}&+qML3OlDzPAtSqV
+zk%-L7mEtInPjWJ*>~q9UYa82 at JYf*)!j;m}QW7hcFIzMn4IWR##=CNhwY{yCrG>=;
+zG(9#9*VmV1Vq;^w^%4ZJ6KC?xn86432jiSm3vx13lWv7yyl`5LS&5l0>4nX50J*^q
+zbQB{GiI<m$mjjy5;!;<ZmmYs3)Yp9@<LcwW9&}kQZ0iYY8|$T)5#78n4>vayvY$gd
+zAT25Ca)7%A!`ee`8}#UtTG+F;wibdY(4B1D+`LGBUg%I`lrp=j*VQn$H8|y?Fv(yA
+zJqn8n*(p|HZEM1XJ`K$B0)%E{;UxeJ+`8)Wj8jYaHtm;~rgao{CfEp1&R1c(ooscP
+z(VhUs7i=J&Mg$;iT;K-$#2_O<R)MVm!<n#q34LaYIDm^b*JQ+iXL-RW at Ei^>T|_}v
+zXa&d>g+ZfHXc7vA=Ogj5OhYASB}In^9NDOUl;Dhk_pO+mkZN&S%g8{$pb=aQGa5RQ
+z23=bZ0Z1YWY{^6sF(@<>VFt{{%ne;jiMbZ+<8kT)$r*iEYEmkyCsu+PN5Bd&pwSqx
+zwR3-cCKQt<2q+r{fXo2#utQh|0v5%|Nu0^V2c1p05$1b_<m>{YPe at P7L)EKrFcZNt
+zGAJ*b_oMnaDB`X!I|Bj7hJ}>4bG at XQ@mNM2BQJ at 6I&>gB=<HEbH5t(bv$)xDXcWu-
+z;nimP8@|lAnMrsNMrhgX#;WpgRA|QS{frEFJQKsrg6W!dWs#-}rehhnXV0EBOF)2e
+zzSuOtL1C~sJo7JcP>%epB$lO2D7OdqigE+d{_#=aTd_D67HDssDc+|bH8tkcx>+nU
+zMV2oWT|AqYgYB0nC}bZQ&0{vF3+p1Z at QvJz6fXwvh_DcEc}8YtD81$;yF^k#<kd at I
+z#}ozm7O&OP-1w^uREWTAHWK?{HfTped^C)84Zh&*eP{s=BU)R2XB&fKVt9z(Sx=9B
+z8p1rk%0Cgn_A!P^PFW5P5~naT{&d9U19-v(PZI3nzz6wM+|Bi2k-B~<;G8GHnc#73
+zGdtUF at lWeS*h$lbr=!F|{cKU&98bBsxq1sODlEy%j8bDg6y|f<h2-jDF3Zn~{tfy`
+zm3KOcYXK+P*xPzK7b}OrQYAIWvm`(3cI+vZwP6>$j+w5T!676ok6-gE>=WZakkD3X
+zE^ZQ!5HrV#LuN)g8>B^M<3+QJvQy$C16EDfSu23Y&z9M0bwKFX>8C~7o96S7_~!BA
+zmb;xgb at IsmJzMd!y$UiCqQgV?;P7)LR1GZmop828{T}^fBtMIfGy^l8Maz}s%xkm&
+zGwW#V^{_y9b2B@~Bd465VbW5r-=v>Zmd|pTiD8>=MI<=$!Y73B9O&uR0Y0Y*r{I%j
+zTefY}-HiE;eM0{d`=q#hHc5bCCT`wA0_-fde>U?%(Zw_H?Azc|&hRmCPXHjFnDICq
+zAfB)c!1<uiIA$E{LdBnxPf9AwW)o*g&Yr=z@)Uex3k!>&u!yLb*c?_?Ri~53mg2eH
+z8X7ALGlpFk@%VlR3#09u)fLw)#Ly?7 at FV1t`m#C1*%E*m*W4q*z$-X=)&dbxQ85vI
+zCKg58MVn1=#@W?n#d+Cj$??(GuZ9Nso;~g6vTGI(hCcg*L$-NoYHnOg6l9${my?4L
+zKYQL>LBRz=1hIJ{^Z4;Bj7H#Qk~KGq^RiMCV<N9zy6AuYj2p?>f`5)S=Oo+{{tNe{
+zwUjsyD<sIyHBX2%k3m>OOjH;anmrRTtSdUiHUDg8T4HQu#N}XrA1`;3v*|2>9lHf4
+zVV=J1 at Y<%eeEvLG2%hgQ1kEQ1&6z(Br(IKX=aeA(f!KHe7ZTv(<>3OG%n~p>dRX}9
+zl#`y0tgw*J{5cDR at M`51CF!nWXp^fqu7m_$@b++ZHkv75e28##`A;b)L%nq(^Up7s
+zvv5B1y1S(XxrwJ&LfZaeK^M+?x*gv-eU9lt7(S*zmvUkm-Q8uhLv`u-g>!@#u*&5Z
+z-N{IeKC=d+<mrFzwC5ou7Gd*)1ZVg-xCdr<C4G{;T_$Fmr4|XFUBtJLO)@7hBPAjB
+znwJVz_N15RUP%^dTg2+oC$)cpakA1=5MAW8m`_BQZAE at oN<z%dh|trTOiTA#FW^+#
+zbp$3jqfhD6Wt_(B?6TgeEFrS^v<R>0BKD=lBlZ;H at 3w_w9`8);-6vp at Gs=)I=fpm`
+zv&+`jUU$th5l>MbF#uCEVn6{Gyb0U+=Ns%h2~f}keE{>*ja?4AY&Xd-6BTt6;}&1c
+zDUlN!6>%j50C~6^-)Vl}6zt-RA#UfT&pA!|#yRbAw9r&oAtvS`&b35 at du0ZK6bSm=
+z1@!n4XV}#lL)tc%F73oMhIZP2z<$eW>1AT##3h_!d<wU3hKB|DojdJH0KOA;cgDDE
+z6Q#>K%^%A;?LEBTNMp6^ils}JEn6~k^^K4q{|jf&c({;=;PJIEgR_h7ieF=#jLogh
+zbv8&X6BAiDeZG;Qk+JDcGc$8bD{C7&2SC{!ICS**NoThmGQY?;EnFclxqy$I2{(>$
+zn#Ly}IA2UcUUB1ABO5J=UuK*H=8MXx{Kq)`x25a9EnWZDZt1cd$2jff0gRJj?D#ER
+zJCH41+BYZL(zO|3oD{E4xTPyZ73{KF6Y}Ght_@&I*9xBr87E&kkVo|N4~)}UDG)yw
+zroW}jT@)nXJ3^mvA|Q+t$F9k at bR8XLoOCB=oGcN>X}RyXEnVkj0OQ1LG{Kgxot$7x
+z7mxW5jMH^H0kEZuL(47d`z>8Dr*(LIAuNh_t*I02;p*ptBDtI)c at f<RL~t5)J%x2X
+zYNg0OvZ;&d3hM>tYfN;>rd_hT9l)cy at Zh<M5a*e)JHsLOPVOD#7YX@!nurVuTf4v;
+zEPf0*Tq9!0b at b`!<G<U#ydeP<JU)K(s0Tdn6bXz8qcP*Z2RDz%*^0);j~-DiM&!H?
+zM`OPG2G1!)!u*%t#g87I9g$0Pj7EI-9RZ#m27=Pa`y9R#g2RmA)`RqheiRMIlyeT}
+z-$h4Edpc`a4xZaLad;;(EDxGkN~3klBXVpEJ^8?J53=OblT&vh`FZN-$!UiW`Ml?J
+z<z9$<`6s&at7stK at Z(eVM>C`$4X8`6`DnD^2Bh13w2=m++k7<Idtia+&{1tae)q0}
+zAg0tG<40qL^uVhn?v5V)_)WEeAhxU@<40pCCIFvq_t0nq+MxSj<oz!bhiBk at Eey+p
+zt7|3<4+?FkgJnjJWh$BzhK+0H;z0YNnK-9S9M~CAkkhaqK!J`>f7bT283|8cRtST9
+zC%=`cUke<MHA8DquGnvK+6f3^DHwBn0fM;4j>?;8Xzq(K@@zb`Z0xA3=7iRd9c69&
+z&^GYo>965~Fl7Jr0Q}P{1rf#`52->SV~=S&(U->^TSJF>!MlRKg#J(J5dRh(?a`pC
+z&VFFH9oCJEXi(d+0mmo0bjgw>OF>vRE+8 at Ag>mxHgRyA<5I|ZYE&!gp_)CF7I;7_L
+z>v7 at Dn>QoJBi|#3qmhUR{6F$F{Qq#;QSnH|*Dvd%RhWK7Ki;8bY)_19)jv9*zC8`h
+z_h$iZ at cxgqOqRL#B;cTa5(LU8L-<44bD5uLhai=)!{iUu{g8dY at u&Lt4E&Jm??q69
+zkrTwE!G-?W;m^xKjs2McphM_;=Rem^D`1<n@?dUs>n~`b4^cfjg`-yt)=AE8^kIKl
+z@<foH;xF;sRlkh&za)IM^e6fSpZqVdzntge+MnoO^6Hnd{+EQkTYsW|?Z^KG_LuYY
+z+x|rVw&8b`{W9L~CL96}1D-V4_Wv&AZ>6XD{lozhrqca^=Y>a4?f}t#Q|kU`v~1Q%
+zo1ZayiuG4b?f_Y{f2%uxKk?(q9pDtZKk#tV$sOSAhTpH!Z{_$fd<jd}2E^!Hy8o7v
+zNfP&fE3ip|{D(>M{tZ!|`6SvQNE^JtZc4+ at sY&&lkG&|Hih at wUW7H=Jr>55Z0S6cf
+zp3P1_oST|UpD`_&KG|g;!_6sne>7UfWY=KK>0?SdHUBourr-L|^vbDGItKNn_$2yg
+zKN^#AYW|(n0ZzI5qtPaHfO1pq{=l=G%qD67DR+P1eU{FX=r@~c_eY~m>Hw$Q{Q(Df
+za}o!5ddl4&jg~awlG|{nFhoqb`=imy=sQ4s($tLkai|Yx&^5s6W#dv#&B5~#l3}7k
+z%%sl@{JpZglbT5NaGVHz=Hc(@?;a*eCM<*0yT7M~E>fTIgu0PPP4Le6DGx)(=;}9~
+zdiMt$Ah_Y0PB=Ezvp=M9sS$J?;F*8m{w8sN|HS=G;sF1N`=in5I>3M8{=hrk={dle
+zV;QWe8;9 at dIlzD7{s4=Nkb4saiMLZ%=`qM;{fU%=IQ7mksiyAV!2@*k8_*}N|7K|@
+z?sW7Y82p=R=weZ?&~bq7|HS>#Xz>%TK{8zV2eUt<Rql at 5rty6*FvinuvcD^M!27-G
+z;bYE8Zany_1!xnVP(NSoU)4e%?Cr!3P`HhLmcJ_L(wMORQvb&N(P-r1x7+?uhK*f+
+zwU+e3h9-7^|H%D;8KB1xbw?upk^2KPz^fBFK(~M7{%Eu~<Tjn}13L5{xj!1MkmGyh
+z;20N2-(vo<q-G)q$Wi#0wa|xaT{uDgd28rr_{)+v5)<fO*z%XP(1+_(nLxk98~Pdk
+zvV^RU`mq42pZ~HJ`f!6zKk7&6|C`w#QYwnak1R0iz*OFNGrldTmwt4BXpev9{%Ev>
+zA4w2~OaILM(P%}}e=q>%#PMx3rAM{=-|I(l6;G+g@!+i at Kj`QGSF=B)ByU%KKLF4o
+zt>cS0rAJ+wKj>fiuV#Np#rh1tAAo4psl4y+`^Fq}#Ev%r6vpV^xj!%i^8|Myj}0j7
+zzJKTbfc_As at ATvT1@-Z*8xq;a8z7o_YVSMzrg`MQLcWo$4x at d5W>5G&$&?<y792kS
+z7<lMzT9}e at bV!dI04S{BRNr_qz8Zb1;|2f<yZqm*eT|l4$O=E!08u!Nf3fsGsvQi#
+zlT2gvqw!|{X6@^13H+GH4gfUssed^8K?;$;%J9ttp%_>K{^9Hg(VstUi~*t;*#Fhq
+z7or;pb^N$7^~X*hyP0Gp#nk?7oj+y(pm2Qu?&5ExUhT`q3;;Bq_upOoj_7Y&IA#E#
+z at m#m3wz+>mub<2EZ2+S2+~NP&{>%7TzMX-9evf~wKb?=|n*%^Ib36ZI{}VrBj03_j
+zb6fq(=@;<-en9`|<OA%N<=OF%&p&Q6$JL)l{a-D<j*Nt%y<_yFFwDGb>2Iq1VeI^c
+zhyk;iY~Sn;=$9J1TkkI at _z6U}_ILV4{_Xs)dF5FB49q+W!3)U$U7&`G%wYXC1H~|L
+z3$6QC><?1QW*uSPvHk}?O>p^+>VH=M=X<1uxS7A%9~#FwOKh!G{#4)mJW|2F`v;Yl
+z3r@$6IsahU_=IKDO<XdY+rg`cr!stOyL;YhlY$682Y7Pbr~?GgisqWTbj>Cs at YZY(
+zFYmKI3*HljpJf7aZ?7}(A at Iom4J(9rSsA}hz)>g$Jjcw1lIyh$%xrh<adZUlOqqfJ
+zaQE)Ev)HjkNoKLYG^TIe524Ulmgxe*6021=>lzrDOkFTC)YVa6CoL+-&4$B#ZGNDi
+z0msHYTX>nw8bwugjR`kb|Bc9v8mda`<W?*e<Yi}K_}2YkPd6IN#LhEozQ{7km9p|v
+z7i3pTEf-rjhnJIijP)T_h-P49X6NFYHE*HtVv(r}i-i{o&6&x~&WvL~eQSQ8ABDnT
+z at ht4%;fOQ&`30sb at bk~)<C)IEipP#?{o!E<Y+(4cW9;l4oKqDz*xA`wnDLB=_Hor8
+jZUGc{q9%CAB at Tz5ssON&r{#gCihi$sxC#Eh{PTYRP<hO*
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/dsstore b/im/branding/messenger/dsstore
+new file mode 100755
+index 0000000000000000000000000000000000000000..f5079c58c35136c16e717389f0efb550e14db991
+GIT binary patch
+literal 12292
+zcmeI0O=}cO6o%h65tYQzYa)JJ(7}ZYGTn)|YPc}O5fd&!A;g{FboXS^H#1$sbk8WR
+z2JYtWE(nVHA2eIHV*Y_kb?L(2;6mT}7-x*}19Tze6jOC->YP)3>Z$Ikt_I*O^pbht
+zIDq}kS{|Nau|v{&oxezXT#NSe=noaKc9?&vP9s7H2mv7=1cZPP_}vI_&(>-GSN46Y
+zl~M=@fn7;JuMcHrEvrrrtTamp3v&dZoMf{}tn&b1e9BH%og7$cT-m2RJ$TO5b4Lu%
+zx>H})=9E<@2Uc2lc-9 at ByRzp_D4w}G{mRB%jv^L=ltN%f0`}})UTUd0YJGNofB3;9
+z<K at 9$`1 at +jSxjG#iv?gJ171x~Pwmp>8`mPGTKeha-?iK6+^6m~yoPsgVls`hz6-%v
+z<hNTYYqI6-(5Jtiud6OQIA>eZxT#z(!|xCJX{UD at _lKI3tY5+)Q&}TYMVoq??7CoW
+z3)?TIsbWhfjSJha9)cMNSCgrwEHCO=5vAS4b}=fqHqW;gFJLcQW=c^#-e`7JFH8K6
+z8NkTy2Wzuio5vmxZ8c@!pj*#|t(fvh*U at V#32bdnFH`@AsXu*xmvy^*&Tuh3I~IO8
+z<{OT>G2xbQ3ME9SBgO`r=t7}~3<-R6D4RIMuR&8-Vm(JeyNqRol$HsO;Ll*J^I%)&
+zn89ptL$!MCMjng>gjqX0mi$dG*W)xRRK8wbtbH1=tvpwAFG(7>|Lo4`bTlKCIe*^2
+z=r^*;>Wbg4$9~e*_s+M|gXk|kb4jD$O_F at Wl0H!0<}{h4d0`1ZS7%;OYYAK09%(QZ
+z+<)>v{#$F}*qhhb_wHXno#0q*jSnSU%^Tf3Tx+RrTF=6!O0%_YBaC`!E6Mv=sG@%=
+zV?zq{b;GfS9miNg6{ksmr`f1rj<Yt;e37|9n+jI3!g|}xug at 84n;AXHdw<!q>7EMC
+zd5(2%v5Tm2PFGCefeSovfd|9DgKdEaI`H6of%9JQ0^leqmGm91Gt;53+*v-O>!9=b
+zLWG<2cx2Wg>kUu#e}hp9A at H*V^xn;MT)zWc;T|L30Spf*gut#M;7!(6Y6~2)+graF
+zJm1;)t^nL()=Aq9tTZkxw25vvuiccx7k1rNcDkyQ11qUvk`Dm}gA_tQ2nYcoAOwVf
+Z5D)@FKnMr{As_^VfDjM at Lg1GY_y}e49k~Di
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/gtk/blistWindow.png b/im/branding/messenger/gtk/blistWindow.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..093a44c49f8cb3134bd712538e3fd48b4d50ea6e
+GIT binary patch
+literal 1003
+zcmV<H0~Gv;P)<h;3K|Lk000e1NJLTq001BW001Ef1^@s6xF)Gl00009a7bBm000XU
+z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?19(Y9
+zK~#9!tXNHG6G0Sylf-D$+MkF*sThA^d$9>xF!<M03Y7|)Lp>?l-aS-`_j>hWdlB{0
+zsz<H%>d7dyf?7 at DB{ZlJL!e at sNU7CmS>M~8q`RBl$!?Mdk7YKq^L_KZnfGSGBuN6h
+z_T;^*1s_4(>)6nde+9c^F{=a+G=dNEF#2ATZa>kZ=(9*>x*-G*co-k!0#Fc;nIIP_
+zV at d#lNn)Bs0P3@^=)*`NYV at N+Aa}F@;J}r8!Ii8|fOmX`-VBYkDI*e^5OCQ)=sRVX
+z0Dj~FcD4d|(Koy6A~K?0pk)GlYo*mQ|MCsBdo4ln at 5a~eO#nUJ47$5&CP0fbj3i?E
+z5KQR7pTE+AlTmwqL4tP)sa68b9BX3@;Ou?)xT@|&AR<d70sa&#-{*1wiz$FiM)-Lz
+zVp2W<7k at FX{*~grvMQbiDM4#v-yWq+fOqdpu)Ms{r>za(;t+#Cx8V?k87_q&q8Yqs
+zP0L(fDudsi)Pj>y`yP^tCrnlFIk*&>E!VW&8Ub%Blb<y6wKem84<DI^GveU6U1Lq#
+z6c-uohW6dc?DaF(8<C at RVPHXrK~<A&pqB{;J<-GDeDG_{np&xpp$a}C&|>rpC7q!`
+zR-pv72Tn8S+^@8^daM!X=rEj6&?WkaNL-3Ac~_JcCdsZHSXu3&FnEyUA-{1>a9Cka
+zL<m?9UNYKhB0JNkkT5Go1*p?#pI^DmDnO`xZjjuR;7bYt<>U+Mx0Hk^$z+!#S^ivJ
+zy9T_nB1}#~r8N=?A&~&%Sx}N=PO^K%Yox#)FE}H-{K}w-qy*`V_1U-Y0yx~o${Eq7
+zU3c+=2h3sa|CqEtg4<m^Z3`?am*Z=9oU!C5>!%+|LR5}B4=CG|WT$;@lx!#rCgF%<
+zNmjPu;%7K$6`bOK7L!!*H^%L$lIKNfI3<%(l2GWFvLL<Qa`{&dB>iJf$tw8yeg<=M
+zSi)y&J`cdDldv*#Ykh~BK-A at eEx6y0IvAKHr@rG1-oB|1TxFBr=hsK|XF at tOPKmx6
+zyCJT8b_ at wHO(x`r#gS^2t&vtCH<3Ukz)T6hzc!%NRanYqA!+AkMCXLr2HX$m6g+Bn
+zS2Qg~{3=C<)th{fTI>OpT+v0<((Rbv8HTx6OIUHP+%y8G8+JW62#@+df;4yA{}KEb
+ZU;usYPgZ|=XGQ=3002ovPDHLkV1h<i#x4K=
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/gtk/blistWindow16.png b/im/branding/messenger/gtk/blistWindow16.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..fe889085c49b13f1f90a31a7adf3f706e4181ec4
+GIT binary patch
+literal 576
+zcmV-G0>Ax<P)<h;3K|Lk000e1NJLTq000mG000pP1^@s6)UPbW00009a7bBm000XU
+z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?0nJH7
+zK~#9!gjC-vLva-Ue7RN&ZER6&nIwC$Ny>x#c=JG^=1t;1SYEvP5AcQuc~qm8;>82r
+zC_mPuFlmZqvWcl_)Ymz8*KBvYoI2m{x%ZsUr|<cE at 3}%s3B7HcDpuMC$UC%GA$DKq
+zS5#js@(Bp&qHTeE1f}hO+)qTIA_4+WX<!Tfw`n3-%MlQmkGsb&u5N+UyF^31ApetO
+zj7Wkaa8l0wa&MNcU5VJ!Z^dArK(o`3;Fa8^(85QzJinj-%yxb$i9jH*A#r#Fn9abr
+zPr&O@)7+}RjF!>A&bhrKv9}MT(?Bu_EU!o;61ns!6ZCUruK^nB3c>Aef$K;yX(E{m
+zy-I#!uwNj0UnruZ5s2tWY_-2}nV!A65-Qka%03Sd3ADCmW7c4DLcnIr`;h1sLa{i!
+z$6;9{qNxJ#xPdN at Fp}s_IlI8+QAm3A83wnt0GSV=3dvgV37igUoCqBbwJb;kGFl4k
+zb_r~*OH#jZR>I-z&2U at 2Jz`bKd}67)L!jP{*_;klz}%cvug=I=*hoaq<j;biw)vle
+z`9*06PQBsbF^(IaQ2jLWOz at C28HuJ%W3c2n>xkH`nn$(&K~P`&Ex-Uq0;zA9+4Nih
+O0000<MNUMnLSTYHI|Xk5
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/gtk/blistWindow48.png b/im/branding/messenger/gtk/blistWindow48.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..3a14f1d68536c0098d47381bc1a5ce329041b481
+GIT binary patch
+literal 2089
+zcmV+^2-f$BP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00004b3#c}2nYxW
+zd<bNS00009a7bBm000XU000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdL_~cP?peYja~^
+zaAhuUa%Y?FJQ at H12c}6xK~!jg#hPhsRM!>9f9Jk8w#UYfF*Xi(jBRYQ#KJKJVjv|z
+zNh5U=CA3N-+7MD2+DJ{SHtCmss47)zCGx3K)lhIzLYmf17ZkNo6DdkUmpG{nUf8jX
+zZE%boyv__>=Dm0OVQd!9_GWC-|F?PXoOAzo&OOV$_X+cWqi0I*wQc<w(Nc>zt3Z|u
+zEYh$5Kp>!D5OgP6ofl{jlXv!2bzPh5*pjN^OXrFf*_N?KYxxGSKE>hxi#W$j(|&dD
+z>fXVWEF`ONxTVNvD9>|R>u&*>sSFwgLC}Xy$9Z9I&DGvy6kSi?P~$p};raL(5&0R@
+zOXDu!23igVGtHkrTiHJ8M#0qt>RQTHB2GPU|D5Q#gw`}W+IZ~gn$C-fWK|-8x|WjN
+zh||a?L>@qd8bjHQb!{cP63ND$KwWF;lL&v{?k$;k$VT&8U0dn5;|ax_z>(I{1E7xr
+z=DbsL4+E`#UDvkkyRihK#z1)4P!AY)jaqWBHS(4H)m_JDzlfN?ku$yuv5h7mCz_?+
+zUXzO#J at gNlOpFU@X_~w|o8`+xR8)je38N}y1QfDiUv<~{+aKOBfj^$9O7q)+4~Y`6
+zp%9!nkx5Ta>=l)pYqMj=I5|1ae371wQ`S^|?Sb`8p_vDF{9k at M_yeMlcWij;t*p4@
+z0Y*j)-uQbKfk4UyJ`vU$>DRw^`-7V!z0~Y0vXpTF$eOLy)RaMMYntm(3h%Y~{O5vm
+zAsP<>%VfoY`?~w!HV at c_`8-j`heE>HGoGYI=)Y#r*B9Sg+JT{d&9yF#e>f at g3rvgW
+zW_}2S8#60p_7J7F>AY<6-n+ at SJge`UVq@(@#PhKs&A(oEIM?VfahsEJ^M#s+6dN8<
+zq@^b`A2dBy$==nyg9^a5j6KoF1B{KPmPtoPBGb{OX3e1=+njpuPVxXF*ER3{#is5j
+z7DN3yk at +kuWPS~%m(X-e92K^mB=c!Fv-El{IQ;on7E=@P$qn^ues|C&IF?`%qMraz
+zht8HP0oKKm%gRbEC1x$SMZmG)Z@;y%EqA(OgPOPN6O5~6!{N5FLS<NNCr($ov?w(f
+z+^%=N$zgaPIsMZO4*rq2B4VJoDbZ3JPbw$dp}05{Pb31FUWd|>TRQD6$$L>d(AgGW
+zPitqR3h!a#qqcUEjEsbV1%L=_esB`gyd^(2m|9^Qxt?fDS*buO5*f<Qc6j*V8+g6(
+z4H^m_+&muXG39RZv!PVNiB~Eh*Nw4)0-K#X1FTv(g=bb>6VVhGTYT|L0V-ESF1Ngb
+z)I6|oaRLD$*CdI}ir1^zw0VNs+6e}S490H=X&JCE*CstZ_P<=QR&nY?a&e#xC|{GH
+zwbf*&v{_L`*duOHSuHFs76z`kUrL|artrG>YZVZ1Z8b%Rf?Wp;(!K7MQvOn5+in*f
+zfZ$gel53?>M1GO*_zw-T6GWV^LfG>ogLJP8qnZ(8=XdV;0!VqXgr=roazcS<443Uv
+zPM%P+RbhIB;3(Xf_PrADRSH{o8GLq+L3)Pkp#Q)`tMiC{B$kBM;f>0*K7;-NgV9lg
+zkx_L=uVX04%yL+?$R<DEp|H at Rpuk3=@JROxTXqUtb}B+4m<&Q at b~vt*hrVD6G-!Bs
+z_N%cmMSHu4jt&ojK>TcAJK*;#{C-7O7eG4ROif8~h{_cq^7EqyyvG9`S4lhug!koe
+zTUnvfP9M|#(Ab!wxjCKAP7|%?XKU#5S=7`_CY8BdKs%zA2tZwH>4%^<T)O0;p&<jy
+znjhk(sadwn!soMCy3|To$&-OV!&BAWo5FQKoMR`OGB&idB;E?SK~9cM^_nTl$}CJz
+zB<b-W3=e3=gPPD}I4-hsgoTAfRQXtNG{<22)a~`-Ssg>eb3cIdW@^^2o1nbhLgW_l
+z>mO-4PHTG3IrMfCbF(4}a`VHfv}Bc{yjoarPt?^A^rTt!HzzPS<are4=3bxA;?rBk
+z at lJQGp$Ry7!lCWo4*fmuY-<OG2g2TI`;UzhD63LbZ&9pXFUU+T(Y!cwAz}gux_B=1
+z%gRD*-8zm)m_);y4)4EVGd{-}?`Y^a?a*=B;h#mq_T7pVYn5M_^1_Ua37|ES>Sa at 2
+zp3Rnr!sPwKaQsD!o{RGrtTVXYt9k90HpMHPw(dU9&Ar-m5OV?;5wu$Bvv+t*?K(SG
+zRZU?i7!Sa)Uxbq0Iwp%N7xiYv)T_X5ATrS>I^2zgH(#-7eEY7QiAF$+eD!i;@1G({
+z?Eb2&?Fdf-NmZQ-CqFsz0HXDy5aWX5n`^rND(GjDF*w(NO#%53=Z5B~>Ym?#>;qh$
+z=KOz<F!vm3E&Z~fUk0+{$u<1LLC at nVavVL`eOA|BKBvz{doP-<j*}nNyGou%Px&ex
+z!>9+=&L73NIH?W$vHew7+Y<@8x)9p8_Uff8gWV5kt-lZW=S(j)ZlL9-*~WrRZpcFl
+zpBfxGTe8HkcwXRXqTDB>h#+uC8FDb$4?yPhu}3ImJ}&Te;DHouX at L(kyrK>J_xr1^
+z4yD3lUK;<GTgn$(%HFQEvk_z!PzDrm>&z(td<<L$eO^R0n2zzz6Zdz_xo-atr at __;
+Tj-n}$00000NkvXXu0mjfBt!I9
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/gtk/convWindow.png b/im/branding/messenger/gtk/convWindow.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..b550c92d33106cbb5ce9373ad6380b716dbb199d
+GIT binary patch
+literal 1126
+zcmV-s1eyDZP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800009a7bBm000XU
+z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?1M^8l
+zK~#9!v{y}ROi>j6o(@s<Q#1sn6Veiqwi=1SVy2CiSj at sgLa0bcSZIj_3si)Kpc3rR
+zArkQuwP+I}Oc#EN at TR)aK}vsUDASgxYF+2NzW4fO`rf=ZukA at r=FYt{_k8#KeCJ+C
+z2mvQ@>y;;yK7y(ilIA4*q>EH04U<-HDC(D;>?_#;Aj4kzI6}G=smVwF9|5Uy4S<ZZ
+z;lmi2)RC51dBhZe>TY&r0Y*o<R1j6R0LXZuYJ8e;zOxgEGyqLef#1J at XmoIX#tdNQ
+zOdxw6ke4T+AU`RPZHXY_0H`OIjS1F7hH7esZqQEB(}9v=R!JG#fk*_vC-?K1PkHl}
+zz_WUHK4;@QcSy*~H4R5V%LyF-884-e%bM{sl>*W~FE*~*>I%S<*I_(<RfjE`CHQ>9
+z6O#Z0c;GR(zEWEaT@`3;1J)GfVE^_*t^l082nE2++XC6y5^3DBpAXETP&{BfJ;%KA
+ztiWhWE`_0dk2H)Y2!Pk4eks#tBatEF%W?~Gtn9Qaqt|OgxLy-d#+<+$)`X<Y;ffol
+zGM!%U?E0~gmR8g0AbTKS^{2+DjNtAPjG+V=fY)kuO_3jW&OLOQghxp$^zW0*Il=Ey
+zJDV<Cw;Jhu`utJZ$ZZ*F!fcsP1-dYROyh)arKB()OLtE!ZX+w<a!V%b*GZOZp2P{}
+zb-fDm3LJ%C*6K9NHQ!2 at 5m6ifS)*T#2Q+aSf;8GCV=6G2G(BTze(DrpDK)2WKY*<1
+z)&OG0iD-0)2U<Qi$0d at P;jB5pk|G+LIAMVF<r`LkDFkdqzJ$dK<H^XQw%)^L9^e-1
+z^GQku%MC&&6s6hFhVvHz6EmD8WzR3*(Nlr;4xo6Io)fZ0#rm<2pAd>s?(4>UFy0F~
+zz5>r11&(iji2OzVl&a&({iCRlR%jr$X-OE;?tBLiNJ%$fPz_B2y?=mr?U9trv*UX+
+z-hO}*in+5<t$Bdi at R8F^F5M95`#UlUoSlW1YX=4vC?24$6ebXL#%f3=n(@=S+=bxE
+zy$W>3(4NQx+!0@=ve~^CA;|CRQUVZpH%M&#{pgJYz*i*lLOBi3*lofk#aYcc at P%S(
+zB|m$+ at V?FRebQ`oE3UG8gm4mZN!f*<fxNT#f at L=?esF3aJdBFT6Qu+K$v|)hb3LEG
+zyBCuuPD|>6Boa&dG9nOVcHwwQ<it$pQp(8#mE){d$rF4 at U9LW@Oogd+Q*e-8Cycj!
+z88O!wi6iLfajJTQd7{)VH at NBa^-*@UiH`0b$gysmBW<OV>Y2E9Uz%5YWz&2>a{4?^
+s025H}5ru|$%4%kZ$$QOC_xmrv00?oW3{)JdtN;K207*qoM6N<$f-q+VE&u=k
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/gtk/convWindow16.png b/im/branding/messenger/gtk/convWindow16.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..b00685591157aa0ae7ed8e5f928ec75d78d67bc1
+GIT binary patch
+literal 637
+zcmV- at 0)qXCP)<h;3K|Lk000e1NJLTq000pH000pP1^@s6J8eh$00009a7bBm000XU
+z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?0t!h)
+zK~#9!oRrT?8$lGuznjFMr$)q!L~2{CH#Y<imLBxbgIFO7Lg`8Gy$E`gR{wxj{R at ma
+z74?v-P;@I)BUOo1TZ at fG6QhBe#!?B2GQPLYG}(27;Dg7^+su64&xt04fRoIwdwjG6
+zq?zmuUM5jSG&_VY_tP>!s at u+<l8&<yFz*PFo};8~>c?~%sHp*}s&2vh2^6(JB*0+r
+zu^2GFAdo&R-eQQ}47}{rOsJF|1yYc3p at 6=zae>zz at 5-f))hz?h+85#X|BtAFQ*#lZ
+zfs8)8cPF{H0LCT+$RW!ESvz>tW;u3q at OiMUEF^WD#FzEYNKvhxHkzNf2_vqOHr_`b
+zawZ;SF*&vZ(^IMZ{g=n)PTbrd9POJ$uJ>Dx6d|gO_H?!q8<?J-fVUE;Ankpn!R59M
+z+svAq+Y}mpE0D_pjTF(z3Cw+UEl~FeaN90<E67=khNi~^4PI&<IbfkKngLxeMwH1?
+z6hCyl34L%Z#@yE_9AqL11Ob<XoVK=FCo_{3cUJY=w%9aV%)>$z<~C1SLiTDnE94PR
+zSPQ-J%P`mMpM4zX5La`;d4&no&O at gTbH2IXJ_Mdv3musoEj5i>ub4pHw1nj};+!UQ
+zX-(kguB{syQgp4JwxgfkUyV5Z74T#1mg-aA_fpvYz9Wpup{tK<zZi7$a|sY6dM&^J
+X2WQK{e}VKq00000NkvXXu0mjfp?Mj=
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/gtk/convWindow48.png b/im/branding/messenger/gtk/convWindow48.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..c7591490a3cf3254306b6fc387173ace69428289
+GIT binary patch
+literal 1563
+zcmV+$2ITpPP)<h;3K|Lk000e1NJLTq001!n001!v1^@s6bDTjO00009a7bBm000XU
+z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?1*l0x
+zK~#9!)LL(B6J;2GZmT160z**T>|D`I`LveB#EBnP2*v~wY~nB^>NYhoMnB*re$W^<
+z_)1917o#R<H#H#+BAAQ>HPG?_X9ChzKZp}(ZTYL~y0`>0hv)O$y;ttu-d*3jUW-1-
+zo9ngj-95ke`S*L?t0c=Zcr6Ei at P#dY%JlavX1so$R4oWpIDiLII)WpFqf_9r1dce4
+z!w4#Q+d!c5LwKOkSEUYF95EbG1XQdG2&Vj~;EFqyeROZ9V1z+1w~2YM@|9$c0f~AF
+zf~`K?bUD;dj*z>GSfxP#0ImKfbp}B4GzC9CKU9?^7=S^$8_diAOiu&k at -pNvspo})
+zaZXnkKyx!dho3%6 at Nk!7_X^u(F-s730B+m>NTmRdpHLNdDg-Fl4ba;w49FIUDF_5W
+z*=NM;g2|&YDz5_ZLdZ(no{_-suQ)ZufD|i&Kmb&<zT_w7^8n+Yx?6b>*|M32R592Q
+zM8p;Z0%#>_zz6Zv6u`tG*|XKRv&yTlNQ%4J$S|LNc at SlBkV*r5_>ns2t(Qk|yyv;{
+zr_LrI^7=;Qv;Tg8cixsN#YaHzRt;P+8{{(&xllcY+;!rh?K77%#!wQU?(--=d;Bw_
+z3!OR}hdukfS3GysNNi6aH4Fy9E_3a`MUQHXSaBz2g^T)GzhLf<?yIjA`1ly!Ve3}A
+z5X7k75<~oqsi|@R+qVqD_RWKyEBw=R3f_$l8@{6gO76UJrR8NB5iNlzOIu_KUOMgz
+z!1{H4b+ZNmu>sLZl!OYPkGWEipTScH&37r2)WQ;`l%_!5VCzz}_(>n@%7o;=<d`!4
+zLlV~9DIj{q6Fq(CPT`tlCzp%Ur-3llii!?TF$h4dik%q<zrP|4Q8KG#KOsQKYAQrM
+z1Q~8XnmE%~G;4T>FHy0(UDEp)z`zTV$kYu!tB#E-X7eE<<?d(;zyod0_XmEvl7-xr
+zj3X;->z9P*`|NH+RWqH|6+0|+Zen83{@pls3C|}BRA91YJ$BZv*wkAFo|lxa&x!b0
+z|IlgH1o8dDfumyz33TI5igjB6mfelVI{_N;$t}xn&H3jh{&p8W6S>^E3lan{u`Fp4
+z2VuG;Vn#d2ubucd2`Rhc9)Pty08LA5T%r+R9vAK01sZBXAt2prC1_u5eI3${IDtsA
+z?GX+{^_huQy**&Byq#q7G-PPM7gNxB36{2$P04DOh?{K+ at bRGSPy~bO4h2~%m6DaC
+z8P6i+SG9Q)Czr2dqckbQ)+Z%cwZia|visp9b70jojR(Ere6T6scT1%XaHc at ORqN$`
+zSC?ntsS(ct{#qdeUwt#i1BvUKqQiQZqSYl3PO}8b#T>w~lPZ{R_uljjMEZOJ-h6)}
+zG~EI4Ttw1>ehqbZnh6Xb9PZE=Tg&fc!-Kt&UoWe4ec^B9T4!X~@VJyPw5N<n6`{)g
+zR>~}T5VaDr#!JsiFCvH-U$LWByMDp}c+ChP_>gy9;QU{6aQ;%VWQ`9#moxo6<+Ou9
+zyituc{+u_S?|tpK=P_YLJG7!vWFY=`;^V4cjJ;5C<p)cVHo)~;=bLsm)&)d^Me{x9
+z=4S1yrFt5m#DA=|_Cu_YIF65xzmS!{b5keAzupbw$Al<*3hy1Vvjni08Lr|3^LIV0
+z5EW{QSbS&~2wP-L2f!l_sx at P$MK-ad7PDE=sjd2xif>Qdy4LBm45xprnI(>(J4I~W
+z$;7p2Z^{vecofOu)=j4L*|SYEVM}mU83GsYv&ps6Kg%#P>sZ+=%R*);e;ryQ=@<k9
+z(#nF~adrP=mZ*tJPZk!`KEV*6KKOod5w0@#jcZC`y=i5sKcXY5!}xpD6$lf{M9exv
+z2P;h^E++aHA|0Rrf*7qD1P3V0d^N<fM}XUaNa(sT8gZ}w`}D5>0|2EURzt&&-P8a8
+N002ovPDHLkV1iKg)G7b~
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/gtk/default.png b/im/branding/messenger/gtk/default.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..fae92d073092cf16936d9917e8ddefbb92c223d7
+GIT binary patch
+literal 867
+zcmV-p1DyPcP)<h;3K|Lk000e1NJLTq001BW000;W1^@s6n^XTZ00009a7bBm000XU
+z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?0`N&h
+zK~#9!tX4~F6HyfYZr*)qlSairODJNyu(7Bcb<qfl;38z<&V_X$xU=23cH!Rm3(Qt3
+zlDZa*xF`rptG2W#O*9$}YSUC|lbAT3o0$nWGk5Z84jks at GL!E+ at 52;DK|AvJjU!AC
+zU580e8eS=oE(@BtdaAPB>VH`?0t6bQ$6eAW=|OZZFG%A=B;FAL0_GORNUx(e@`-eo
+zh$LGQAaHJNTxM~p4E)Li*_?vXUpjB8_bwOU_X0zM3?p9kY#|Sb#GEAo0-vSFL*rK)
+zn?Nd~ApNC1bB6|i;3yE9WVN#-EKxl_>I7uq*&OhENx|>k?tOn|iZsNG*Na3TS|^|-
+z+p_3(ZZ!wDl4=Fm`=g%icA#&-ngkC^<RXLH)o?veBw{*&xR`KO;N=pK%K*DO>e(m<
+zd}INs_fT6Tc-aQ+CnEQPqU*W4pFT5#XVbvv4?vNuu2$uimiB-hO3VT!YX2bM6fE8=
+z(s%!Wu|Pc>9 at 3mmYb<qnyKV;0d<1 at eYd`KqGGcR;Kn=O`Ze6V;L86>M(3p6l<bSBz
+zsc<iGuNj4xu^=<H7B8T%)qMr<Trq_**XUuJtcH!*-b)$rvgQN=M|uY)s|LTX;pYk`
+z(9oYJ##v9mJ><ziu<>qU+~nb;O&bse(F0SH-2=Pa!00jHc!(O5L%4SW=T4i9i|MZ<
+z#71<UUM!cDT0^pOE$@6{ez>TrJ^k{I$iX9*Or4MqrnF8VX&k*5&Z?6wwWdg|^dD`{
+zBZ0%f<rx$BineD!ClHo>9HLN+-C<aGqF{|0OR3mdIC$%oBsB*Q>(j6)0WQNdo^IYy
+zW4H7Qc)zN^NgnVC8D85B@)GOK;EUQ~QeV~B!fQLv)zp46o_9~#{J3?EiGycOwwl?R
+zSYObVhr&Krv3cI^t at c8Pws4A|32mcISZu`8%@$N at G~0b{Y%qpL^dI+IZp9RWv{nTT
+tplz(_)7pBDuisI<eWmiU8yEc-U;wC;5=tFXE+zl~002ovPDHLkV1f~Ki825H
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/gtk/default16.png b/im/branding/messenger/gtk/default16.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..b436a77b5256d665852dac863b0925d615fb5dbc
+GIT binary patch
+literal 520
+zcmV+j0{8uiP)<h;3K|Lk000e1NJLTq000mG000aK1^@s6Yv(<I00009a7bBm000XU
+z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?0hLKa
+zK~#9!d{RwILQxPsH|=Sul~D=Ohg4v+kO()m(N=9+w9lX5PpE%T|Dd+j!rB&8V79R+
+zp at k4q6oRElnS?LpHS at 05_k`-eyqSCNoHOsvTwxdn6b^5kL*x=<Yh*EW<Bsf{Y<qpN
+z`KUI95+HJt+$PyzLkB8VpiHLg27&<rpBM0XI$}E{lI#c&d6(jiS{=yd4CD*=6~QrJ
+zIVv#XH<uSA5*G*8jyNsOxZ3fF0sR|jHG%3I at cAKQ?*QN at vgVRPD@y|5X*1k%(#QOj
+zOjeS==r0QQL~L1=>m*cq0VZZiXcV}l+|amyOGBcE&be_YzRKjMd^g#S=LhMz5ch~M
+z)uRrz-u7Vwf5PFgVoj5t1<a8|=I}50{(J at 1Ow~y4L5e33jR at 50269(2$xR~*hOEkc
+z9*evh6G}J90wJ~H?goZ|bjCorBD-$~cb;<y?@XpK-m*a4o-`k3>r_CoMB_b`kFEWX
+zj at o4N>PldbuR at zCdQ_qI9{UBi3;i>b(7YbxXgd3pleQQ95nuq_*Ms-&nRs~s0000<
+KMNUMnLSTa0qT@~g
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/gtk/default48.png b/im/branding/messenger/gtk/default48.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..8381428f20e3bdfd3cdedfa63efa369c0eeb4b80
+GIT binary patch
+literal 1178
+zcmV;L1ZDe)P)<h;3K|Lk000e1NJLTq001xm001Ni1^@s6&qcWk00009a7bBm000XU
+z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?1Sd&E
+zK~#9!)LBhW6JZdZ-9iER5<f5!kPl5DD$pPo^#C4BJeeN6)4$-=i}(-V4=8#tCYlI%
+zglLITE`WuI0S!<^Fg1cuAe8d4&UD`mrTfly`>`cXGTC%@yF1U!GxN^8t7w`AnaHb&
+zypwqFpmvHQ{jNi;mE1lejsesls{dZwULceAE9n40qsc%ost>glGLv=Geo_R}?<fE?
+zoV?tP+5yf8f$2l-K`_Cr0my;jGU=svB9OJT0SJEgpmxFW2t~waMJ*Np8t)O at tWEZo
+zjV*vbs{kv1HCPVm=azpTy~mvoaHax}Zv9wwPC>N|<SByi*#>~d`-JDqxhL*K0cPh(
+zH8ebZ7uQt-)YmA`*pT$rNvd>-lrjMj#y_z#{NuP5Gd`PAS`5(Mk`#yu#1R03Hh#|Y
+zQ!@Z#QyN5fog+N~xpm!=UIPfgYXTq=HX!3XdHvm}2Em`X%ibH;6liH;FW*NHJ&6FQ
+zOg at wuKR9fU=lgpAVZ1LI0oV*5z2?dTC^`X9jIk{#vj>9cMA2ZXlZV!d7yz-dF39d2
+z9MVh`B~i%O&?3NA*q&i77eGZNR-^M+l?tryB>+rb#43|2e)u at fTNxkS0hpTxn4h+9
+zd at NG?SayE_%uMLOt%RscWm+O#M0*whQHK(ilWlzHx5?BDmq`fo>g$wFKTbZ3v37V>
+zK_64%Qo?f8hKwh#lP9ww5qw^7mcLH6Fj4TTqV+Y&!Xoee#kuSmZwN(_XvK-K!Y8hS
+zD$DOEpRkcFXG*6PfQ?P5LtE99J+<y!?WdxUs;Kav3k#sMB=^P?7W3CmS4bDM5mn5l
+zk}grnIe at A<`FU!^ncgU<iqXx)?D`tLvC5UyT;f}d#)|+2Zt10dgF=388FyN!m1wwv
+zt;Jd1`|Zv0euySD1Aug7qp&qMImdVMdQ+Qqb9bjh;k+N~M)TqTNGGtH*w#j)_6Hd9
+zBz2zKlC^>ibr)hsT9&+tGZ?^d|GNPoX*(U?*wG|L%~!}`E+9JCZI at YEA#Lv7R${X=
+zhYjiDkB<O|9W_>HxS&D&@iWcQoS at d3h8c!7#xUcTO=JPPyKJxD0E}XryBW at 21ga|a
+znK;Q#g=u%f7--1*Deo<O{sQpUufYQ5$4(?O0PW2>01J79#&;*4G$_=WPPngLCe>g1
+z1M^~O8G-C-kdKMFvYIeo>_WQRFP58I1^{oS+`Uk(D+ZNqhiSG>Q3izZ?Dk?t5pYmw
+z8@@X}Sy=$wL?#I%g>X%PZOyjD2O3Z_{Q|Ymj^XhU=uBd?Y2QBX`vCpdW5WSb$<K#_
+zQ{}LPC39$X4SMlCQ>i{fc{%RtgTvkDv_3W at e5C<6{8AI21KOu)tq2#Xh^oTy`UZ?V
+sf3W{P)5sBkfY^~s>kG+o%Rd1I0QP0BQ%`-CG5`Po07*qoM6N<$g47Tg^Z)<=
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/instantbird.icns b/im/branding/messenger/instantbird.icns
+new file mode 100644
+index 0000000000000000000000000000000000000000..0843171076ce097029359a04103f98c0f74bc4d6
+GIT binary patch
+literal 21624
+zcmeHO3v`p!mfq+5DTsP!&GHgJ5m9{L6S<;;;U)BMDTwkM6hT1b3i2$b<t>oD=p#+i
+zrfJ#$Ev2Qe{Ar<3YI(oPv-v~0isR_LqqF9&J9nH}y6%h)>b=tWP8v$nrlmj=*R0h5
+z{rCR%KKt8epJzh4WZ}vfqJLbsBzD*fM7`f9yc%!vCyVZ`tW=yXMR6%kr$OoIg6MRX
+zI=>=KV;Qhqg}W*WKPB#Tx(Xq?oE~D0&I*O9&J(%zE42R<@e0LRqcCUVQDRQlVMzOH
+zi5Xlc6>?S+H at IA<73OkQ5vy>X2UdZWZXk{2M2-dkr3CY35upf3k#etd*LHiB#bmZ*
+z+jkTdDO9nGs3cG6S!z$zFMR9uh*Y`f_-S(%uS?tE+=2Ex(ca}yGzCe^XGG-4nyA^a
+zrs8c%9+5Lgk(}1(X$7(rIeY!~TsUt7YFD^*`D>*zpSd>Ajy~j4w!%x|XI993eoDCw
+zy|a@|;RVrARWhHvxy*{(cH1aR;f1kL2W0-*hSE$xPAgdzUbZ&spv<PE3B-^Agjr`C
+zmDz&)424`4uw^K$blC}+MQzDcOhh}OZ<~2qX20ESQK&K<)vzcmA?l3GrskRv#F2(Z
+zFl{(5vk7L4l1l8j(*(oHJo(=6F}jyt7&>I=&|$+zj?0r-WU?7FDI^*$b;x1iBZfRa
+zpiin+^T42|UmCkjreqU3os5X^i_MXx at E0HNXVpr520k}B2hGjGycNx9i(Td;2KRMn
+z`M?*#vq7Dk4pS0QA-L_4Hkl27IA6>AJv$cSv|?dQB$!I4XUR<WaG{ppKO{U$re!82
+z0h7c9hvin8kA1RFv6emfGAwDLO+4CAjulP%muuNm;hE at mS-KLBGQd0^>hpaREgSes
+zrc9fF7z~)lcxFI<wo=RbkIInQq+%mx1uUY?Z!=_iYOj{v4+|y0;DW(vR9Mk?i%ie#
+zLz`D1%z?#eAT-zl?WJlhdnDW}vxpr=g*!;#3!uKz?|_z`gTofUPHIFL=OnXCPt<5x
+zpD_>?19yq=v>n>WS}i?^=Txt^K#kCztktr<V<D8GIaL5nfO7vqEe*r70J@;tXp(8v
+zAuSCCmV4cC4Zs%x4g{DbKo`6>0UQeOL4Y}Ff**k?3Fz}c2LR0zu7cj=0|%KfxaD47
+z0q^p`&*C{f9lj!gsp(AtMgUx5R3w+TY_wRw$n{~wML9XvE1Xk&=x_v%C<NRnU{?03
+z5#Ff66Y!o7CX|?*@LwtLkF;!nsDm+GX at c4I$TZ+6<^!Wq?dc-7GMJ8IQmhb`1DGqL
+zQT`MWO3W3uD=HN at hHH=*#kWkDDwwUC1c;&SI|S1qG6#h4rV3c*r@&IBWsi==j9CYR
+zD-rWV1e%l#%N~sT%b0%iM3R`n<igUij^7HCOUwH{F#@xB8m2rZei_zfYD5w&<yxul
+zqc4oZ#GkaIX~AF-8zK^6%Fy!u1NvCBntqQwGd$c5j~ugt_2z;{Qe=YHqxWEWoNm~&
+zPd at taLj(Hvf9Rn>Pdq(z_~>min+#v7f_Ec!kBo`&UT+#)A+tAjiiJ;3;5pOde7H+y
+zi%Ttvu?a6(Z1CYunMZCETSk at GI&6v*|Ei3{XmGjAW;?JCIgNxpZ`YEc0>r)-wE?>l
+zRism{!qyM604$N&lKf0~n#h5PzkHAhV3Eut-p$DpyVm~gKo>q{1X?JwS-CdFj6UWo
+zeCsRsr+7h%&O&nw?NX#&Z$H;JsTs_m-HKGWRQF)K4-zyPM0?7VFyp*YkM~7HiWXUB
+zB72w8tK6FQ;i^S*roK8p0sHoAGbUqQM`M&+HCC!ssMN4K4y#9iVk~TQ!l#J=wGowG
+z*Hh8NWk;Gf0NR;DIG4PQw~ABA(X1v4Rh$mj?FrbOcR<g<9<Mledt32nMKL(@5fi6G
+zX*{tKXJM0Jnc^zII9gHG6k<DFI{}+yDPqQ~@Its_a4IY$ITcXCk|s+NXU-g3Ok&?q
+zDv)Fq4yTPtvL<5ktog5(QwnfrMLvb?_a4b+rPoGTo;Y>Z+__UGVx1mO^4iPjK8Lfy
+zg`naHS6r?NXZ)10`;l}a_`burEz-S893D5j419i*%R(b%QP>5K>h`!3)LtG4Zv4G;
+z<tvgJfjLy}Q7?Z=>}-7zM337;yixTiD!WvNyF$Z0m3iE!h&%^X!cF0*%G~Z+6zn8~
+zhH40BAe^m&!v&SjR*(m7<;2_|Lc>z}1bPv4ccFT(yYATG+Uot))rStBI9sIBW!w+k
+zd1}v#hm{@Xq>VAD`kt|yldT1NPXOIXRKHEtoOam_F*$n8>g2rr7aS^ia6NG6sFJ(J
+zvAIAm#UvFT&js-|%29cZeM709$L&06SIM1=lx!+LUmov*n{kiZrcxaS%#)?^(~dP&
+zdj4Tay%kBG$J}#URemOK^#MKKP<YX*(iL10RDQ8w^+7$`v==}lZU`!?i94!i=_fN)
+z+z&2isO&=a2|Zg=nyH#_*1Ih#I~I3Z&&=m6$P*U?4-n_-GkUi9Fc3Eu`6WCH&+FOR
+zYKw|(;<y>b%gxu{vwYDzbLY&OJ!k&AOQQ4iEVja|QUh)WFxwpZun!i`njA4ARi_y<
+zamIpZhn~e$m_UII=n5S3a`e)wcU~WzrQ?xrF3mynYO}f(oq|t^UC$R!8R>v&?y77M
+zA2zAjA}^a%b|}`SXYY>B*YPnkqakj-U{Y~2K(7p0dbTL4P{&8l`XEbB*(Nms1C40e
+zRy~WJR-$9!?*ZSNuF at s!-u3A!I}($LHsi{5Y}yBqHeEC#KiE9*Ndqu at grZ~PS7hp`
+z*oc}p8gSKc!{-2yH!5{(+|mp^TYmvaJ&u(Iw6bLAY5HCr8?yvLdAbT14cOV$7Cp_}
+zhZZX!Bwxp=1lodX9YtACo#RH8yK&B`ly26u<)aVi=uOy50DEvZKvmb9^)$Ig$3`xL
+zU_}S$EVz$BSyHQ`sd#P{pa<YyDAQ`;x)MS?01>ww@|c4<nuq7<H1tS-MJ6;qq at yVS
+zkERJO(S9e;cYuxuS_{<e4N?qr4$yF*N05=|94P>21C#-t6rgCo-v>@Kp=b5puvY-r
+z`QSJ3+~Vz+NMUn&Q-no8ZK4MPv<eW(Mj>o at vumXfT`1z7F{%=72BO0C>x^(m6(++y
+z&0AnGin#*)NXO)8z<ZH^+aM;(@t8E=sN~q?DD at W6iw5t-K*f~@mIIh9%TW8ubhT+Z
+zu(~y=z^ip^;!2EFlG|$#b9J}CF|s4y!d!?w0?vzQ0t<7erNC6BW3Mj5d?^s~6icIS
+zeKOEJIyT`w%*#{+qWVO_nyZQ33WH0>M@@boQ+e|lSlmg31-mCE36^r5G-}dZG3VDG
+z2X8&ridd?pF^Mo{pex}SI?d<_GZ%hfhszPOiiPGzYgcT7*P-`Ree|MvZ%&;Q6&XHu
+zTx8_L$<t>qT)IuqK7=pTdG7@(JFq6+>rGQD^epidEbdgXi5%Gy=fhokX1!=pjRHMy
+zHTY1cp2rqpGod<c7*}kn<XopmRy4I7)jF05cRMz#EH8xZZgnA2BRB2 at D$Ac>fnTwn
+z$7G$fs<;whwq;H*0V at J#I)aVNgG+&XyUOcRCK`bkBDJG7)l558UjE*g6fZ;$8+N!|
+zs&qPj#;7D8B--Liph|U?cgDs0z)UYlm&(+zJqhnl8ijb|5b0!6h1#pWrmD!1k-T}`
+z>I7`T8w?*}B|FfuFK{1F>4M>09M+7$%qngJJ{dF6a~4~&=LTS>lRje#jK^^m at Ttk5
+z$4$VeCBo?5MyGsgoH*Go>}b{vFki{1Y~QrP`2%ilQ!jbXf1E}s#E+|<eBdUe8<!YU
+zh$%ytEyORXo^62B^wRqHgczLuBJ^cD at j8ziXH8L(UK8_Sl5suGe^}g?^Th#ZReKfb
+z_3Jh#q at -_J;XV7kwleDJcGr8{s_Hg)AbLFYB?be|eorE%;&)^aUJW?=Rd>UkpZzw{
+zgh^bZ*(zx?8ZK%6NRp(HG&vIEVV at DxXm-IWNe#rpc)3 at +K&*#mpHxST^BRdX$B4oX
+zOH9KL(MhN^bOt~7p(#HHp^~VFD&dV0za*8RCI6jNOr$ABd>$u$6iY>vFM*nK$;6q&
+z3(yK at d)N+XyHK}F#Pi4@?S`}+VeFDqz&R4$+u>&=fE)z0N!2`C%7&CB)pDDZMK<X$
+z&ysNU)MQF0cqXD|P^NT>TP56Zq1W*YiNbISYcizs+zcArzr!-53)})3OADA=$URcL
+zvIjCwT&Y3$YOp2X`8#fswvtKu1W(f7O$VM=@DInN^r^tYut90krO$Xe?0DM)$s~#A
+zKYI~uggw%w&#%jPehxeKP3a5B21=KH?|c3MPqA4`f8a)xs#(&Y3&4aCJpTeC1f%q&
+zSAeMr at wRIjK+_z+7b;zXfJRMx*ZD=vrc6vtS#o3?)|7oyZ_qD}H*QV6g(Rx-Dbm4(
+zAk2)qm{ALh^f7vcTZKkc%#4a<NSE+T#&~$VPb(^ImazL_Brqx(TzxQVLN-!X(@1I3
+zDI4R6q0f-SpxLEk7)m4vS<F`H5JuZXJEV^U%*~ioRl+;Vt6)k&6*6vSnnFyQEGdIZ
+zB*i;1GRY|-6eF~is!(1o<zuw7FrhP%7d9Ks2}tP at HX1zBKx?N{kWvsZ*DEDU*jRuh
+zN!U>EjE7GiiNvTBYMita6Owo$?Ut;(5FHm&4C{{POBPNVd_dMiOu<azlEk-3M$Q;7
+z at s5aKz+%dgl7VTQlnS>3;$adh6fdAXv=tDRm?loTi*pUKmo#BD(BrWzHQytO0S-Ti
+zC^y?MzM$BbS1cnMdlz-Tx+~CKf$j=)SD?EB-4*DrK&LA3>*rrv5|@(gD0dyMb{05H
+zDQjkrdbmfYn%<ccdvr#^zR&)*G0^MUpU&pK|MER|M$kd)UXf|1{}PDU5BvGE;&&hF
+zAj<8T*s!%nuKMwGsC;Id@~hh;3fSry!xtUW1u|aUKkx2<!EO~CxZ&eK at jHQin-`Av
+zQg`+mR`}OWFtzLQdGwtWfxmvH-N>Cae4Wz&HY>p2{<5<q9r|50-FG_~M5rA`y%ppC
+z7<%1m215?s3c*c%|Ml%#nu%d+f4phPTXZ;d3!BoAt}FeGEdR2olO+gCxT7U^gR!-A
+z at WIZ^g5F14x9c+fKf`aHz;C|nGP<^b{<`*N3C#Y!ZL6+CiaK728 at rM#V5}n at ZOCf_
+zHtAaMbo(cBeAhCy6Rqy=+L;6??KJ3W_}sk#6IjsIJnhEYgAYO5yheBVmfJ3WBR)cI
+z{d(l<_T9VOa&1m)`nx{qa*~b$UVXk*0?8eD2f@}5=9j?GpMt>AVaN?F`8B~fa66=L
+z{Nb4v39RYZHz?M+8~pc%a_%>GW<qlU>zlDq3g at o#-}8%fzp?Rp0e*?m7ll6CQ~>t-
+zP*%Mq*HCW)V_QNYmGQrpc-ceB*^=zf;v8iE))ES>JQDoRgqG5eO`O9^{E*NpC&9lf
+zw3L2qS8)ou{g4nVPZRqt#FTz?Z_s^ydZ?Av^mM2x{rD{OvY#GmrGQ3<n$nNYNn`x<
+zP%C at sH=(BV<13>_{q#^P`J at dsr5|51_3+a}t*jsl@&_&*_vm$^+x>LC<G`J?4kW7V
+zq-!wTzQIS5q59M#Q2zUH{x1w<2oZ)~Iiz7B;tE9b1o$=o9mo<A>|@Xq9SR9oAd)p+
+z{!M{Qp}>CX=jDGP6kLHg3cd71ztH=?zYX^Brv*wb_}DHVJw0_T_+)Jvn!AtRKWS?X
+zK7udtUVlvuK3f}xuUdQz&+6NlgAH68f4%eK86NT(fM1Jh`MMbF{<eyLrA76TM~@J{
+z3H-0eT6Ug7{U+q6asKpVXjPsdtBYFE)2Sd6`iK9pHT~T`_&WquySAz|Jw*kT&_DRK
+z<!$IG)!!wU+K=<v(ueRPps!yEK>zoD3ucd7#&!q%62!EYF2R%?Jp=Tf$QDe_8?pa=
+zT0nN9f4bolM9JCSw}2i9B58BzFQeM&Jki_DPC*mCS=+%cTI2_f)))9khqm3$!|+vb
+z`M<XZTy)JDJr-2 at KO27C%oJEy)DHi(Gpn9jP<v-zMLIXPM_|$xXjveBkPq<s^nR!E
+zcJD^tZh5=~O?x8yk2d at uZ~0BByQ0!B-}?RZkD2&vrxULst>{~k`y%w4V{hpEDRI at k
+zx_2k2y)LU-^8Z}t*K_|Ezmhjqe(`fl_W<&>Z_g(_>EEtnZGUr+pX;JqmOXH at yI)*j
+z+;j0y0mkE}Z$7WxJUs9T6F8PYHNI~&cZ&Q*n6QUN&Y1b$qL{UDYnRTS5%CYYr#sl-
+zZZvBv>Ac;)Vi?rc6cS`(BYJ+j-;nKs43k#=g5+J0e|L!P3UpVXy8_)6=&nF_1^)k4
+G;Qs)bIk at Kl
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/instantbird.ico b/im/branding/messenger/instantbird.ico
+new file mode 100644
+index 0000000000000000000000000000000000000000..51fed13f752340320417fa83145ad7896b2af839
+GIT binary patch
+literal 7262
+zcmds6O=}ZD7+z-&JvJ9buwq0J1<@dgC>A3MRs<=6f`SsMs92C7NH3Ny_<{IE6hRQw
+zf_m~2FP;P!FM1L36N0}W#~#%2c{VfYY%;Txq?>}KJb7nlciwrPci#EfCJ5Hxue3G5
+zcQKfn2!eG%5NroZz!boG*C+h(p#dxc(^AUdUxVT<VTqQy9!Lw?6o4`iDb!)(6h1xu
+zA|6)0i`wN_JiB^J+&w#)N376C1<?FW>(qkhi$E11&n95DvzI?TmEy*cH0Gv$i+ksO
+ziboe;i6=9=hS7t*$;IC1a=q44!?TS(p6~T%<8SJDeRBzZ7lHDiI?$%S7%uDS<>$NS
+z<Ns#P^cfGLL+Li#=U*O-zwV#;S at 4Yqo|y)8o8j!o$1;3zLyBj!QoO86asPZ8x6h<=
+z-^?AB)A2Vsw8$?@12qoC|LuYlGm}yro{(by+BPoj%jVh5TVK2RYb}vSL!)mE(K#uO
+zZC>WAxzi5IALA7w$2=SsT^i7?=4mU#&o897u-DF8YZ#Wl9*5`GWcck}mX4}T1Gq<-
+z{NK;F^WyZ*(ekH`x#LN!GWev{SUku4Z at Hcqh)HMf@$o;oO^Q=HkYB}Ku<iLhQp{q`
+z=y+$?@WUO~IB>o1tV<|YoZPvVn0@&8>pb$=qZ`{=Oy8Dr#+>NPXK=4u`P<g)y!dN<
+z<qg?$p1EY74=p_pz}=cVVtzUud&Vbk{#pm~$`b#i4mn_rZ+qV=TJO~#*!_))KXtg)
+zF83HLf_vG<KQ(8~xQvoN=Y-jpQ4SGL3(wfepZmYjzEd70e~y8zPu98jXM6nrSN_aV
+zJ?HYaT#NFG|C1TFFXn09-0AP^ZfBp4y{v)!FIwh><nzv0Tsa`c!S(rS;C}6jJ?g`+
+zuWj?U&OHG9n>`w^XYd^2^qHpyj_38VyD#KI55M;NN=5OHtoQYq%@r4(V;HxU<Pz62
+zmw#37h&?qWXCPR64nbq`9_8_$>^p<#VD9mZ*T*@|k at w`DdKbX8eGHgKzIQ*Zk2%0|
+z0At#H{yedzUGLgswGY$sUBLcc%kxfApMO*i6;RhZ57?d>veqNB&z#C3a at WC~^;MI*
+zE~CB#P at BCi=R?+<&VxJ7j2UNU@=Dem&AHp+e#OaOkA?X at lLu$|AaD2kijHRk+>$xl
+z&D*?I8r<Wcba0IOo*OQmTpRto$-gh|S_hsl0rvUOonPErc;3bttMh-KZobSro~byG
+zcoy^juR+J0HnrAhjy{Wa1-1oDU#nSW4ov%a`tHL=8HiU|M-BaXbKS??yuS)M7;o}U
+zt?ed<Jj(PBRDlMt(tILk=IDy^WEgGew*WA|BA^b$KohX(;yt1URDsekeVT0!;Q~j{
+zU`#g0Xrn(taEKN^n2jqNDjUGY{2^^Y*-grhciAy at 9V)w~?GHc1C4M^=t|I!wCrZBi
+xw1%IU?Qoq~^w;Dy`fn+_L<@euXu%iqATXem<V(hAjthwfW3)=YlyS&-`~^IDi|7CV
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/jar.mn b/im/branding/messenger/jar.mn
+new file mode 100644
+index 000000000..929e7c998
+--- /dev/null
++++ b/im/branding/messenger/jar.mn
+@@ -0,0 +1,14 @@
++# This Source Code Form is subject to the terms of the Mozilla Public
++# License, v. 2.0. If a copy of the MPL was not distributed with this
++# file, You can obtain one at http://mozilla.org/MPL/2.0/.
++
++instantbird.jar:
++% content branding %content/branding/
++	content/branding/about-credits.png	(content/about-credits.png)
++	content/branding/about-footer.png	(content/about-footer.png)
++	content/branding/about.png		(content/about.png)
++	content/branding/icon64.png		(content/icon64.png)
++	content/branding/aboutDialog.css	(content/aboutDialog.css)
++	content/branding/about-logo.png		(content/about-logo.png)
++	content/branding/about-logo at 2x.png	(content/about-logo at 2x.png)
++	content/branding/about-wordmark.png	(content/about-wordmark.png)
+diff --git a/im/branding/messenger/locales/en-US/brand.dtd b/im/branding/messenger/locales/en-US/brand.dtd
+new file mode 100644
+index 000000000..4dc69f244
+--- /dev/null
++++ b/im/branding/messenger/locales/en-US/brand.dtd
+@@ -0,0 +1,10 @@
++<!-- This Source Code Form is subject to the terms of the Mozilla Public
++   - License, v. 2.0. If a copy of the MPL was not distributed with this
++   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
++
++<!-- nightly branding -->
++
++<!ENTITY  brandShortName        "Tor Messenger">
++<!ENTITY  brandFullName         "Tor Messenger - Beta">
++<!ENTITY  brandMotto            "'Cause geeks can also do magic!">
++<!ENTITY  vendorShortName       "Tor Project">
+diff --git a/im/branding/messenger/locales/en-US/brand.properties b/im/branding/messenger/locales/en-US/brand.properties
+new file mode 100644
+index 000000000..c09000fdb
+--- /dev/null
++++ b/im/branding/messenger/locales/en-US/brand.properties
+@@ -0,0 +1,7 @@
++# This Source Code Form is subject to the terms of the Mozilla Public
++# License, v. 2.0. If a copy of the MPL was not distributed with this
++# file, You can obtain one at http://mozilla.org/MPL/2.0/.
++
++brandShortName=Tor Messenger
++brandFullName=Tor Messenger - Beta
++vendorShortName=Tor Project
+diff --git a/im/branding/messenger/locales/jar.mn b/im/branding/messenger/locales/jar.mn
+new file mode 100755
+index 000000000..4fb707f30
+--- /dev/null
++++ b/im/branding/messenger/locales/jar.mn
+@@ -0,0 +1,10 @@
++#filter substitution
++# This Source Code Form is subject to the terms of the Mozilla Public
++# License, v. 2.0. If a copy of the MPL was not distributed with this
++# file, You can obtain one at http://mozilla.org/MPL/2.0/.
++
++
++ at AB_CD@.jar:
++% locale branding @AB_CD@ %locale/@AB_CD@/branding/
++	locale/@AB_CD@/branding/brand.dtd		(%brand.dtd)
++	locale/@AB_CD@/branding/brand.properties	(%brand.properties)
+diff --git a/im/branding/messenger/locales/moz.build b/im/branding/messenger/locales/moz.build
+new file mode 100644
+index 000000000..e59008d87
+--- /dev/null
++++ b/im/branding/messenger/locales/moz.build
+@@ -0,0 +1,8 @@
++# vim: set filetype=python:
++# This Source Code Form is subject to the terms of the Mozilla Public
++# License, v. 2.0. If a copy of the MPL was not distributed with this
++# file, You can obtain one at http://mozilla.org/MPL/2.0/.
++
++JAR_MANIFESTS += ['jar.mn']
++
++DEFINES['MOZ_DISTRIBUTION_ID_UNQUOTED'] = CONFIG['MOZ_DISTRIBUTION_ID']
+diff --git a/im/branding/messenger/moz.build b/im/branding/messenger/moz.build
+new file mode 100644
+index 000000000..bd8ad850b
+--- /dev/null
++++ b/im/branding/messenger/moz.build
+@@ -0,0 +1,8 @@
++# vim: set filetype=python:
++# This Source Code Form is subject to the terms of the Mozilla Public
++# License, v. 2.0. If a copy of the MPL was not distributed with this
++# file, You can obtain one at http://mozilla.org/MPL/2.0/.
++
++DIRS += ['locales']
++
++JAR_MANIFESTS += ['jar.mn']
+diff --git a/im/branding/messenger/mozicon128.png b/im/branding/messenger/mozicon128.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..5f94a95e5048b89b1957d2d86ebf22c43ec4b899
+GIT binary patch
+literal 16878
+zcmXtA1yCH%(>>hX-QAs_!QDN$bHRhVLxAA!!QI_0aKSCOySw{$zkk(tRdZW=ceUFy
+z)6 at O7=e>(mRhB_PBt!%N04Q>@lIq}N;C~Gs7W_UaVmbysK)Z;`X~KhFzVH at 5!RH80
+zvU)B60L;;U4Pus-Xczn;fvc3RtA?YMtB2_iOMr)m2P at FQ*2Ub^$&%IahjrG45Fr3S
+z4v>=+)AY<f%kj!K(8_r1J>1ZLoi&_))$X>qJPS1mh8~Cw{3(fHp at BVwfj3PsE;z|w
+zNJYN&mwys at HyH6}8Ts!9DR&A4Ie59hqyop9iAJ+N9&Xi-8 at C_Ml@*npm96oBp4#4z
+zY!$7|?u%Q&DX&SF+*@Lb;yuTwPq<!;0u#U_aiGh~w(EJf|L at -IKW3fi5A@jr at Q0Gy
+z#9J0$l`eTdr2`)^LeXyn=K@)`Xnw=71NN{r-Ad70_zj36;-HuS9+MYAcg=ZFxvxYJ
+z8+7R6LWl;4^v6o!=w{Ic^k~>PIPZ$^7*ONaKhd!Uazjsp90AS869QL+SJuq=y&rlE
+z_h){eR#07!=;CWAzSSiq;aZj281T at Z=go_{o$f3Nvd|QNcuVJ=n+pmG7E#GWvg6e=
+z+YgDv`IVlkP+Mv91z`S|dJuoGpa!JV?f0cWet^x;ho|U)T|;piMB#H<woEg{hYdGH
+zj~?<os|P*3Uk0c!rf_O$y=%$IjV!LLtaKD7OTR$oac?<bF}ji?ysBTF^9yMT2h%_Q
+zR&?##blM>geS&oIFf=3qh~zmg`DaZGS7=qX-A)Q- at Hyt1;Scl3#F6 at qUOp~PxFB^_
+zVQxbB!)OBF>i&IZn=z1O|GL_Cg!Y^QUxfS0cz%9<&Fe6SKS$Zf?|!}ul$w at y8{_C3
+zqQKe?J;$x0jDjlkxW;@<2eGM0c0<m-O0z$O#F=TD`1Cmdk1gI7l+jn^nt=)paO`-R
+z%~K{vl$^CBe_w_<gLwdS2GKHD-jE1Q;q<9M1qHU9x2)E!o{wj6MNDMz&24VRfp$lH
+zHo%sb!N0V%9P7C4bDRJQ#MjOfZWa>U`z@|NsUbqqU4j~e8Uu&E#-NLXja+l!<IO@*
+znp4%{dCicewz0LPN|41?+QAJ+-vQKNc#?V=$uA3ySa)K3_U->**nGe6xPE;{Mn(N`
+zQeJv<kmY!DoA;TW<<J2fzwOm_i6;;?Ar7y7i0+4b`w&f8I(MLuywjDv`h*7G8Dfj7
+zuf0#Nq9V0(-9d;Htvyftr|F>_!}0NPes_0HPft(zn)=Wz<y;Wc+*BP|G_q|VU2$@~
+z(9|=<7GFih_sy4u*0QQ93n!;|S!!_!38+Tvse@(fJj?yj6!0im|5LIx&q|*G@?gcy
+z*KYN0`c6<;eolq-Z&i$rjtYzaT+)1lxzbrfLKj~OiVmy{iavAiEG#SgxwB)|Wpr7#
+zEAugF!#!GK*eP4APPcOn8z>V57noL*T!Ox%xW&-tbz0rp;QM at 2b;VU&Tpad#(HS>8
+ztA5dbNQx~r@&K<WVXgHfO&kIHB|CF0iEi`H7+dc^ZNR%Nw$!qLp58Np(i|!uA0J(b
+zcyO-(l`1 at k4!kqlbO~_fQb9q1&DPG&m07PLw4<Y=Yd|HB at 9fiw-?tzXEmi57fjI^p
+zS9}fa4Z+F(fGcl==}ne8xPYG7pe>$CCiV*K?g98fnqa7leOK=jFRz(Wh<;#c&T#u-
+zZZt5HuDP`}KxXltvX3_f?!9sbApSEc(2+6f2ap{fduV6~8yB~L9yfySRj?@e?(wnF
+z<!}<~sp;9d9|q59H-_&3$DbN=#KE}NUzml3#lUq&%D`jYO^+qM_NZeLE#OHaGc!}M
+zcQYVn>d@!mZvs{KkHqev$8K13 at odIW&rz$!ZVvmErZ`r^4$blGFG(is={Wu`ZEDTF
+z%)~;TSCYaP>1E~R+jDszccBAul9c}z7Ito*J#R+nyuc0AU4tGB9z|lMxnx=Dn<=p4
+zq@<*L8KO2GeoX~;gplG-q4>|mii!#m*I79_HEr$iiVCb8zKf5A1#MV3xVXbYWq75z
+zw*6H7X*WOdZR-y<R#xdb?u*{f4+J??b at c(T^TYr%8&_6WYg<>(VH9Wk0yZ(e!sjDU
+ze2^~TAj7ihcX at I&H#cJ;`v2j%!4#7p$(M+T-JMfL)iH2}0ee9broWXwH{p;&D^>Ac
+zKOEWK$Ll3oYleRN4;tmtBuz%Q{1PC|T&aqOk~C6REj)RsE`*(PyMYHUFR%B(ct*(B
+z{wShr1Ea{Hci{&c3k%7DYqkwEB*di1>lp)r=&dkej8$!;)dZpc(;!)*;=!XRFjLyx
+zoT>yk88u|K-%-;^K=??8b%_L7WczL}{xi+i*7lIqs4M*|Ir~Dr2Ib)2-ILQ(ppA_u
+zXi7-WcaMsUB12JG at 98<S92_!kCmj8gNCe&Yx^-4Oej_6zGtarL>+9(7nQ~p_Vts{I
+zgX$^*uAB at HORE_g3e#*WYcT;NDHG(#^uK)@Z34~>yH3TzMGW at O7AwR>UvV9so$clN
+zTx|EeUKF;rdMx!^TwILnlulT=yuSOp6<BQv-$Nr(h(N9#x_5 at S9E|rLyON%|4cn8^
+zt%#Doyu3IG<c#MCrUeB-eEar|_M9i1!yNY7^Q{d*6px74&SZBuhMSw4J>bLF+s9|Q
+z%Zuyl?C$j$yOM?iH71t!l}8?+GK?&2H2Bhm=PFK0N at _fv!(3k4NJKFVT7x39q9Qpt
+znLM=b@^Sa^l>i@~oETN5OpcI{Q2FN-SG at Y{zkiY%8XE3d>ka|4$F409^<Xp1DQmYP
+zsrtTS{JBZdfuzx;kQZUN{@9HUeZk5G|5$<^Tfm_;+fFGj3Ijhzdb!aWZLUOV3=?#C
+zJF~PT>*2wtq at -lNF=y47!@hkObnM>wS=rQdCpXCcf*C2P<Ky!hN|g$V15`>Ouu~b9
+zP%()2qv_hm7k%Z6{Ma4)xBe`kP^yxrtf!~9p%AlZr$oJVEgQegHx!gt6)*ig)`VS_
+zn-J`RG?!ik5WPqPDlfi0f>BXX3y2in*iv8CHa0dC1b({;b#Xyf;ficQ^_741@~$MK
+z7o!N{Ni~9}cg|V3>>6(9<YRBl&!?!pqBEbijQz5}D at q!7NT`q`uBC+|B{e7$$@K`1
+zxkZ(g(UO!LCtcvHdPqDu_ilckgVQyidbuW>)85tg;QH6^oFU>Gbba6R0WrGbd2#cL
+z|Im{u8Kl_(#1Qfc|EO%_kCE59gIq4WbHY{aNpNs*3R!)a{ocw6-8*U;eI73u@)l=j
+z#TioyIywlm?4NYO-~x;-_U9pAAI=LK8g4=njNv&{RaLL5zmnHUEZ#e4X~iwswK$M}
+zS;puu$1rKOfo6r1ucqsR4UJERsD^h3keaZ at 16tB)4{F_iEIcmEsp at GcXlZHnkZ~4+
+z{t7!%y5&VnM4)0s#}Jl~!PG8-zr*o)ID=r8s4Fdv`1tU*n#zqC+{SnJH8nLgf^>Cr
+zo7vciO}>$Y at 1;YB_nkYvzu-bH)Sqh_ghM4hGEL+W4H*HOK at TYc%dF_AhOP-o at tdqa
+z>nn1Zn0mw(d>z?VIqhVd9|;$fC6A_#j>-p~GDHb*c5Y4rJda&nzM3pB;Kb9^+NyHm
+zozb5 at Fd!a^4i1_wYr8!5XNzsNi>wuum2s^rAcxl8y?gIR#;Doyith?wPel8z!b5K1
+z3!Z1lCv+zfiQVxq-D@{O?Oz6Xsrh^)ax~MwsFAOHxk}$IaS73omvjX>X)jq~n;%Nm
+z8NdnW=;ETJwH0rUyK!+$rYSWw^^C)u0v#Sa*6}fuJW5y$H0q-qd0Z*-F+k|x{p=ZT
+z6pBC2SR!936WW>z3wOcuag_(o4t~TTSEgN_f%D=}A~84`X<}d4p~Q%nVzo{otf&}Z
+zR_cQ3mc5h1UpIH&e0YNxSn%vDE%%S$@OOt|dD5Y at R|T}~-T8@`b?X3~>#@L0yXA&3
+zaOi2VTMjne<BLK<L at X;S>)UqP`qAF7+S%E;-0Db1Lqqd#aS=@r#H|E|c{V^G!EHx-
+z at 6fTUa>a87rFv#bPKtc-O$3$-<TFp-_ica(+Boc2$YAf^uwtThP=7<`lF1pQrsGCL
+zpowF40=mPvKCfD6eCxtZZ!rMmxY08+Gh%LT_eC#9yI+1_MnXGwUBmX9#A`B236WZ#
+zE>xQ%mUne!|Ch3PCD`$)(czu$j%KQcMA_NDs;Hp(`T1dePev|ErW1bx at D8&3?>q71
+z(qTrHyV=j;D+SIEK>1=+)tQ?VUA01F7&}0fK#+e4{CYw=nhBMSCug>qw_Cx=%uMXY
+zL;+m_Y;ZYLHekggAtBMT6(r*nCp?BCLzv?}K06!#s6Bm22We|*SvD(CV-n!1r`EFo
+z1Ox<*j*jpjdoE#$k|_)q$@-$=vN><GT2BdBec4oF`u=>sbpaYj{z1Ki^aD)sH2RXu
+zjU)u+ub}ObtdHq}>UEhb9kQ~rjxR5#E~apd4nD^}c7wop!z7b-Vq(H>v&T=DC`XYt
+z&I@^aJrtOUw_?|#AGg1 at O=!}r3yVBNh4ht^>fK&c!rmVi=6H7{p{_7#I!FW;;CVKP
+zHjY<C5Iq$BT;E@@Z)j);h5}$fHvook46Lk^7ndg|0yW}5Tie3wYL?eus1Z<L&s6IO
+zV3~G%Uqy}B4U?p-cV;|9!RWg=sV1!NCB7=w`b at xhg-%^WqpmLsYRM0q;}S&r(J>lT
+zVA6`lF~E-eO<(_u>(O+XyQcg|0+o!aR*GJum71nzGEN&XGjwpf{H=$9f-t7R at 6{bM
+z@{h691Q|qU&8aA2m^c}7#GrYr7gc;E1S{yr4zgGxuuYHvg^zPJ^v}nSpGiBg%gZqi
+zMB~T<8x9Ii1cl|jy?HGyEzYZ!b;H|W=*cby?j3vW*u7^zx6;n_6GG=lWH>Ohw5hpy
+z9eRyx*@YRrYK!|4)qG$?svh%dXC`8~Nn+I7YOQrWFanVXnIQrHjdjBmw66ahI9hFA
+zd)6)6{n@?lWlVW95?j1?#Kpz^=mF<j^$N~H2;76^QZuF0WZe(}sswQpa<$ebmyU6B
+z)k)Ui4oI8al`SHZWw=YJrw3y&-jhm at -Fr}_ceUpy&UNBur)q-ndhm*ehsFrk|7idD
+zNOyf=<!wifR$~mvWth-<CfZ;?9&9V<?0khv`l2mI6!2U?%@vz_y*3m=q9z}0U{0ob
+z7CyxSdA}so6EIjW775yI4Hu^Xg~CDJ{)M*R6UT(3#-uY3#p8Q4{o`g}B=}1vm_V$p
+zz&SDQgO3;wKit{W*m%>X(*YWrJl!MiYl+_nB$L+weU;$AT2K>%u0H!mjEF9Z&J+wt
+z5b51#v!JMmTJZ2Ie9+=4iAVC4VIXddv?FSm_^zgsLU&v>Ej349m{g!?iGc>%ez!9t
+zDieDtd>1dhvxE%yWeR}5d1V&1*B9v_?sDS2GPne|d>uMEDj$k&lL?-mv(?tiHgDEa
+zNW(?Z+09K+vL*Hf4#Zsy0H?p&=3f&1*arCDT!`0A)nBOKYY=3Ocf$3RgQ81AZa#k+
+z#tZ()7!iR?g{o?4aj%-&Kv^o7IYQZ8hQz|?`vH)Pa*2yBsq>IV(Cgg#+QDlJd624`
+zw=0I>w9Vb-M!?JfcP^Zl%PEqrOlMT<F`h6Ajy5VPDn^(2bH_z3Ef0n{v8hOgi)^Xt
+z2XQ@?W{}9_KTG1qP-pCgM-??t3BpO#Y~*|p*9ga1C#|(&rDMoM8qpmDp+p3*<kzwC
+zZXF7L{|<yf!e#fkFi;jarY=#+3SSj|5#!oLcm^Y4adY!s4!GVfELnyzA8+qT at Cxv%
+zW`ki$Ir9Ab)_~ZD>hwEJjYIv_hr%2kHix~@<_9(4YGr%P`)L7qm6Eh+{4Kw!iJOUE
+zON)V#(QKp3D>*gQtZ}*Fm3EZZtaWvhtB^fGwhB@@4rERc1UGUBJNfkoc9~28c^Qzb
+zsFAIoKE+IaX&#0yMQ?z~MIZOGMp;&g(<23)z49+3!yx5+59!jPy%!dpPtI<n?{%2T
+z5Fa>`&aJMFeZ0TQ(0CCeNU4?8)Ex8$LDB7SKvdS&n9ZLk?qda-;amH3c1#+7x8&8B
+zjj&&%w^SS)W&c8&sH;~Q@^vWJK at HOU&)R8SDG}kE(${<_+?4(Y<)2C%Bymb4lu&^V
+z;x24w=k>A}7a>bUpsrYw?(S~A?Sq!<3_u$A>5&)}lrA|UY;9sPp4 at FNKJ>jX=h%!6
+zD+0}3N(}3_Ec&h#o!l`c;rsm0>O;Vk?N|J<dBNOSVMyo%dQ`22I2U3=jxl;WStjB%
+z*k}b)4?Nf2kRV>ApkuL0i|M?;!jNgwu!nxv$Zx_}xBM{&Elo|Ty1M)hC}d0=TC5M3
+zo1zDy*g-V9*2>r430WbEhE1R0^N}d(mbuSRQ99Qdd9$L{OJ>%Ezp6~t1^x@`yCrNL
+z!>$~{AP-oo2_yYI6&g4tEtW8bd8f-S1dtmfMAZ(Z>GGmU4b1eeUhx&$^3b(>f!9d|
+zipwB- at 8HV8CQj#t21&kf0qx_c`_rM-IyyV)X!a7~)eGPwX{ousGpUO2yS6+|uP%g3
+zj8X(4K~VXiA8+3jG*F6jeJ{^3k|@iMQk9^g*@qym2%ac0(SUJBu_Lq*4^9w25tx-N
+z?k!zvGbIB*>^lM~Gn6*JQy at P-XA$H90C2F0nhNM#kPAq}wMrs{&9c+FLKf30UgTS$
+ztv=P?ybFHQFLaO6rq8k!&)d-;pXw!*+-DG8_s(GzH#HIQuqZ0Yo_12Iam*xRta81E
+zO73x|t-lM1F3%3imX^=$7g<TOG&d5K<!Gs#k9&VFjVLRx9XPMIhG9S<DKCY|+Tgu2
+zgp-gVgq{7@|1TkYGH=mtyQVYu>!Q;4?+WQ$qJJ_)yCJCHodC9$k=N6kxEPGGXBAqV
+z9(zbwBVvw_EyT^=d%4yT>MN&pp>rHOJ3-$4mpGw-v<b%DeurocUH))BM`RSr+cWqV
+z9#tIn at b8mhiw2{7ABU^_>t9G$tNOSgdE-kUq`%dbh}^BS_pvuXg2vIs4qMSa!#>|P
+zMX6}UzgHcMo=z2<JLw#-#wdi<S+2YvTpI_4k>t##JnKoZ(&tIe{<1-AY0^L8#T#Pf
+zFNQop>U$75zKIFrC`^m(pLFVo_*^O_^~_db?Mh$#e9LU6V3Jj+<76>FR=Ap-u0B7Q
+z76Bq77?(6geN4sW?riw5Z0EU-BG){xeSt<?^EFX3JXqj03BTuV9pl})@<hvJ53M$j
+z4=()T{-+7RPdC%7L|AuUHqX2#j*-e`1B3~EyWFHO*T^)dwH}S|Z59oQG8?-*K*7G6
+zsr5ySSRL9fVK)}|)Ofp{Z=GIWfG9CV;3?(R-;6oyp+JeRxd)0LjX<~hy|%txc$@<G
+zch_Ki&rWc#Uktbx($w`Z$U$UU2?`)*>onItS6RO=E{W7vE9zi_X?N%NisrFAD+j-O
+zxa2cv?@cqLsGj?L@(2CkU}tAvoA>$E{p)yN+Xw6Tcz0auu<@n;lI!!X7$9^zP4 at iM
+z745atBQtwqOjdDx++ujZ4aKPdAB|n#Prv!}YJBx}yNWJ;wH?Q@`-YaM*mr2=ZirAp
+zS+}ei+;10GBJ`-`*q1qzg+~&yQ0F{a_wvHY;+p4Iwkb+*_s3KtYhDBY8Pz^&-p at cA
+zc>np170%V=!;WlDPczOxKvw$z^)Cgv`$wl~gT=F%$YZzu^SFI0Iz5Zo at 7BCkhZj~p
+z|0ATc&E|mFbALx`HskK&055Y5tjv-hL#5gcZ+FsBNbBRsIE8zfuQxYU8tf5()-itV
+zkJqjvCFFKYpPlJMb1aygR5gCR^x2!6?q!iZk;yPhW|f at +^)VKM<3_vEN5XpDUmram
+z2w_5`kRmuV at 8+2;m&H|8=}EW~JL3wIJ7oS3j at k7m2G~-jr!V#f9tS9Imn4q~KczwT
+zkNT)?PIEDzgB!vu{D$r#_hGl`y=}P-ztfKArG60y|5X7X1rVI}zhYtUd3U1T^_#?c
+z)Q&^ldv#BkQzbSb|0&scd%w29T(AoP0;}1n;CmkVd)RY->Nh6L*>e58Gd_5gM2GbC
+zw~dvYdk{7uw23m2mcUU^&YZw8{-8GQJ|rv4Fbb(TeY=V1-Cnuv86WQL%4l8R>|`3p
+z6aA!$B|aW7-Z}_pGnO6vg;*i~_D|<vsyST&aBuvvZyf%RearSP^jUk0&*AhtOMLxD
+za#+;FzEVlzF`4Zbtx;hM0_`n;;X&>Et|>Xt>kfLMFCIM=>TEMFtl3e2m58bOpkx54
+z|IWmK+ihIwS}+)xNxg%h2*f1$RZupX+>lLj!F_xpXXdfezSp797 at jMEm5lSu0PmU6
+z?Muqq8gj5cap(GQeYP90ebvu<z?L08mQRV2!)LTPRL%F99Q1)-YzgE0pn#|T&FHIy
+zR{ZEry>QyL6J2d at 58BqbFYlW%{x?^2fJDI&t-D(&DXHSO3SV#38A3!BD(9}hzkOx#
+zQ)%HJ^~L?|gwK at XBt+^7DiBS90<QDcP{sg4MCLeSYwQ<H(A2vi0e*=XH=&f)JO>D3
+zSllquWXj)WrN{B_z*LzBP+bd`{HRf5OCaKzZffWH_2bV&Oy|>W-oo{Zam)2{7Hj{p
+zYWurjue1umzlF3P6Ni&Shc294nu<Xl1>By?cq!vDfl9g>e;RTTBnt4=zqbg9p|D_#
+zZ5pT0W&^BXSUeo3IG#R|Xoa2#yK=bTBq2q;VC3Ia`M8zPm4XoCw2%?HosXg<JkHjg
+z*%_h|Cnz~_lCi(7P|osw^=S*6z1ec2i!I-s#y;TIRNwJX*Ste$sal`JLaWMet<3A}
+zc|ARAwwkKk9#zQ!<5v at RdjyBWKNkNYe6L4lFuM(DgBD%*2-N9IB1?Y0rRr*2UJ=&9
+zr|S#VGx3t~o{?hqfJFBKR8FqQY=3+Ff+nh{%huq6x(Z^{HE at 8b$d%19?V``W-f~6G
+znOpI-Nk7%j9IpHDPuLtPSf0=Jnl$TqaLh9sYNyLDdR<pYo!C2>%2f*59O?pECSi&M
+z)>zxhd}rpHG!9J32vCe<r_NM`Hv5ITx#2K2p}$r4FPf5BY3m>PnrJ&=gPZ6XzfF#@
+zs5RlCkq3e3$FO0WAL*z>%GqXp++}T0zzh2l$oVTmh6Amg>S=3}n2NzPNks0_9&8|O
+z$XXz}$?UpBg#A&r&F9xxv`zerYXy%_Y=-h$WYwK!HKz%ATo!wi&x=7{Crhd at 5jw8#
+zQEH{=CP4gMARutnlBw>?Z7qWua%3uk7w+g0WtfRh8hHhp<t?tbst$QN4zv{Vrbxrt
+z7v!vmZ*1jNCBbAOw=TZ at 6#93YpI7FPG-9Z3{g1ggXO|j3i-voxO8B|O+81whxSzI<
+zmFiB}|7bi1j9DNdPZ_Z$*XN00j85M!MHu<GnmGNPa@>1(j8S{{i_ at _5mtYuE$sInn
+zo+xHMveYiKkROQHR_gPNT?5sZ`~rq6!ez)-k%_?0p&$qfz#u71m|lNck~-Pcb?Wbt
+zAUb?c=xQ14un|+E_<TNNqpvLgsuZDGj48)>TKT*|^*Mq!^^UDn&G69#lRB>I^gR(X
+z4afd$fwpEvA5Balt*97j;XFAR2k~SS#?2CPvkl{}FhPeXmMVJu8a3-L>X<ZD0>|5%
+zw~=TsH_9j!Ym{G#4d{q?L at tdh92U@K=nlySMGwhPRXnDq<+k=MAu*U_oe at Do_r2Yf
+z!F6B&Gg5)bh-*WD+{-ySGI{Hvqy2CsPmOPt^HFQUOpP%^yabc^t<P8c^C%BusY|7y
+z7Y8$ZVEgAlmJCjdYZ)<trfmA)WsZK!p~aVY%oT6yQ;!Uxx5R#PTcwtZv^!9GGVHY5
+z`gh3Lt}*>r(9_)P#|1dsIy_D!_<vA%I1bB7j+*24NCnz~A(d-NX^@x(Vm>@F1C4v9
+zpLhz<B8;P3xwZ>nd8eg6SRE^GeWk%YV&uh;7PD^I-uH6m)9Qi&sbO~H{2N_ih^+8X
+zm`?T-k8wL;U|I`->jO&nQyDA&Qtg#==V%LRO2|86w{sA~+=w!D*E+9(0<-X|=BR}B
+zO~s_hNVqU<uh+;{y$*^yS>n;~QZE;7v|hQjPe&wZ=NTr~#rI;Yt~lbWdBPDq3j6F-
+zE!rF`@hW2dAp0^cz#&adJGwOJ6eq}3e$J|Om5zrqmDAKGZS*WKfd{#t6Wba){cUS1
+zQCOx5uDq;rrzIl52EjPfBvW?o>j=;mGbCiGi?s;ow96+t*53{1xqrOqX_eGpfkQ}o
+z=(H|aHu#&>hM<YDS0?FB23(YgEP$`D=0V?>|6>vm3VN(Iy&bE)-GfrO+PTc562LDm
+zRGF=xFj-d)$<RV{`K}d(BwZyGMNJq}KrinO%yRvf(}n)Cio<5iCh+f8+xf at zQ;!sU
+zpr_E#Orf7-Awt0n^^8rhF0&kS>bOJW2iZ&R7g|E4>GhnPb5RHg=B{kc=bshuhVqf?
+zR(Y<yi^+AJGUnd-V)a}(yS0WlqEke!MY~iwM&7KSuA3xJh+W!OAwaA74OvLfY{pq`
+zjM=Tc&)duP>qPC1jrKfi-XjC=OcHxy>$TskOTN?IK`v=52UWJBqXBDADrakLF+6CZ
+zBhP7hQ*x!OJC~O)glzBIFu5Q18g{;3SPX^@yT3<bLuhHjf``AQ5NI*BWb+-m@;83?
+znW(!5S~Zd`%mM~i{isrQY;57GBUXS2WX1ckaMdy$HumTF#l;aD^)CY&p!D at ViZ#}l
+z7#;70GD`PqZWf}i7^6jSlGJszI#k<Sy1fdAXjwER&=V!s#h2@&DaJjxMM3|PwAu4A
+zE>JUQqwqUqemJ4)Z8bb7K&46SPUgLXgV1*E+|2UWt>Z~{??2v)G7IV5?0})6aif->
+z!~4<8?H5WPuUVp7<IyT0D-CCUyX at W*yUETwWP!M*+i|LZgX2wMP*At2fHw`><4M(e
+zK3Ao*CAe7HOD9Yn#Pk1L01z(zCC#s|;ec0n(ye?lQR%UM?by&&;Fo`5KDIgz#(v`I
+z;wFfdbi50Xp*2`4#nYPiU;B=I`*LONwB7s$i>w&e?!L|F=h^ZTmp2oInGjfGS%Qco
+z(;g6Wy#~FpaNM-kKCXnhbGh+=)N?!=ibxxEO at Z91e^h<aqNL`i>(`2Bx#?M0wjMs8
+z1&n)MjF&eP&2}C7;STmZ!d)M;kR=sE(X+jlpO*|!MO at z*-D`Z3S|sd+?h4`BFPL<!
+zo6$<d)PNK^>z)L8UE7!scB^AtaXo)s0=#2#Yy4Zt*q4^=*c-oDjxb+&YG_kd`QDqQ
+zSM~{zn{PRI`N8QMP4&WK>kiCo at i=l|!+epmU)$VN5lR`z2g1#pT;XipJMj}|oN40h
+zKKjh(7z+%QP2NE(ntvbu+k_aC2$>TrlGLtnz+pXOr|^6BZ^gUf#MHl=HC+!Ta?Xqv
+zjPTeT!P->)-dlp6TeQapV4U)FEoY;*tA5>Kyjyh`nSr>RB?3OI3oak$XA at 1={Rz=p
+zz$4q!RSFp;`ju5=y1vz9x#huUduH$J3&`tzzxr*vm960+#r{mhqVBLRs8_PEV?)~B
+z4bTd!Jl{uwoGsr`CM_V#Ej&hF4S^0hwB0w&T at W5r1H}I#&I`Kcwz3-?A=fbFQL+VP
+z!kYB$%?*{h-`fcCHILp-GQ at -HOd>{I-aQdGPAk5GaovQ6?J{}$1(mF3&tJwGn!So}
+zzh>gU#MhUb1?Gy6CV(=tT|O{TFFNC218%UV9F<kKoYhE)y`9wuCS4Dj8nq4MX;jNP
+zl96gUL(gmNt(;8a^ER$Edi-D08tiXWA8n618BLy}yqG_?>^3&s;^8iQ!gY+6<Tq#F
+z{bZ=lY!{q)xPQl{%a9l2u$*Zk6GsJM$g8SaN;nHtBecMw?kUmvbPbSmLW8T1GIb5T
+z_!{m0@^eigy_@!loYl`)pq($340C0*b^IQS6CUVsl2zZT>8j~<g)>+eJg7=r^AW!c
+z*DtiF1YAHWi`r6zL#Wimap9AlkdhvAN77aO+O+n&%dYzRZiLr(IAt<(yfEHIckxLD
+z_sDz5Ej1|W63vZVqQrKnzuBH?EaZuFXzYYpQ4w$FSQ at Y{0Nd)&PmKRn4I6uikd-$~
+zUUTJ`!+<(F%!U*#s$zC=QHC=^QfnSdos+=};>_L0_S=&NRp8+E(&j>*g<%BUDi(k0
+zj}=I`sKC?^mNk#Vsc?if%!6qUt_T1k>@5E2683;>{YzFFm#sF=Oxs?ZtvP;)RB+CO
+z_IX~b9Y%2q%^>tQ4Xpt$9mAih*vRW!GMgXHM%!^R;U_2Lt^T{}q`q4UzI%yD^~;)=
+z=Q78Jt+5|`8+}KoV~OM%oPSiYVFuZi)33C&CX|ZvT=|Jfbn^oalHs at 9JJFCRcBV-G
+z at n`<9h7&LO7WKw>TdIe_f%d-W$Y0k8)SRGYv7zFT1faOse6r6L&Hj<yncfoI>`vUF
+zBqQmjopO+6M^8EvwhLp;=|1VIT4bS;&08HA|8mc)2LuK!e!L05ZKA3~K~s&WY8(C4
+z>G8(s^**ZfecK&#7O<xl6gbjrjom;Yn)dMyABOz_&wlf{Ysh(Gtd`75j!HeSU6;)b
+zF|h3fDa#Nw`)^USFX`M8e!^}1o5`{PoqN_-mE$$H(*TnaOs_0J2G{<#Aw?wrwkwy`
+zd^!eH at 2A#)PRLG)-E%62+;4b|YvUqlc!qv*Mi2{{I4%b=I#!qWe?q2^y>_J0t*Xx3
+z=^1Zs!q~DwU^<0XO^-JWX<UefHQoB@!c3#TaCuFQ>40d$iLuta-Gc_0Wl?M!;GTM-
+zY4 at wG1gKA$051cl#7lh=mjNIx9cXCR{x_P6BItF}Iu)}3>5V8{ihzzk7%EEbdAejk
+zF`lh8!q;=H78=;%VEbyxXAs-lm(+^uW9V)*VQ=#Cb_@`@KZ>R{zs`T~r$k|gMMPXP
+z2zb{Mdb^r1aGOUA4Ybg~TR&Z#`&<Asl=xkb&_^t8Lca(8az1wAcQ*$H+T9In!lS$K
+z6BAJ-z+Zc2LwPg6sneLFx+~s!+$hpnid8b*8G8tQHMV|acVoS$mac(CA3h><EE>Lx
+zsTC?r2#c<Y9Cwe%QSpC1skdzgs_NmI426|KvQOh}50x(N^L<Do24ok_st;u8XFksa
+z2oGM8`S>m6m#iuo8<Ul5o`fPAFWxKOARb?Pw)|(0hdCp(?2~Vgz53|W))x7QMPl_2
+zUcZ<6WymPXwk>S7D9HD2jE~bA<G5MK5)sKjyj;H!VZqGE;s_NwLTou|*Gx3su~7rx
+z^J452=waL<)2&B--5)Ey!NuBvyXL+A4&xUlEx)djBT(I(H~rY0_ER3On)Urh8mH_i
+zaFr78m&+K})n}KNy#`i470-3F?#oJmIYst?<BiHR)^eI^$q-sv9*++Xtn$>DZR-$5
+z7kR at pLEWI_>q_pj`l^|sm2-|<FEbXhjw=gX=87qAD3{KlR=>m6z<m{ZhHEUu6m&!!
+ztO^!dO$|kRdxW4qRpb?}sV+H3M{F&P_Jadk(B*8gXr(-op8th<?%O<}yPa27iLfbQ
+zNlKjd`>@TtC_DOY7+wpQgQ4wyPDtp|vdnWZUTNAdhhq1wH*S4((9_nI!>|T{tAq?q
+zvM{v;Oe1-%hbE(-W0@{OKu3)z%vYuV-nh)`=H|u{B}ob1(Kdau)m>d5i7Lo7_wL)j
+z6*?16E^3_GdTkXRSGoLT%!HifW?*`B*@#dnIkh3nk$JUoJeP|Ly?42 at 5zXS|LFr6g
+zJZ+Ly)A+OE<^#e1xQnN%rjd(UODGY4tgg9r(BzVObtq#*ogsT2vDrPY^RaF2r4?Yk
+z2v}_;GXp(H*lm&?oVTtv?4Ctcu-hu*+~O{Bd5E#NN5u48K#;CD!v_Wf=cdi;8Cc8%
+znEw_X!htigVEwP&i!~m+lFVlMoqKO%@XlgePi3XTNL5p_agLb19Z~Z|`Qgo?W}8!c
+z9$fDEwuy@%n&=gzj$!ivrflEfs7u6Q{lzIkQFnD(?1PcO>g$osWij}qUp8BodU7%+
+zV!3 at T^N=xgt3$tLjOotT0)4iqrzLc#baMY5ueI)AWbye;3C~o+^mAj-Zqq&Rd^K~q
+zXBYk4evr!$5rWG~d$z4C)+_q-$}^ijihRpO&EV+3ddi_c8B>Uq^4JYQ+4ZDt{D*f`
+zfn>MQr91Pkqwc^|IVSmus{k4>v!$}K($*m$Kom at -z{bYCSxaE7`9b=pT-iPz{&#_{
+z`LP`yk^7M6)d$`e+kIk2M#%9B7HK|3vq<dvP-W)ag6YGerhh7wJiaiq;QkcacN5#6
+z?mw6EVnzPZbDkmiH&sERf8- at H7Hp)Q-5R=Ryf(09lFerH3H9w;N2HWY(yH+mt)`BA
+zS$^_!^a+D3pO{f=PNF!P6pRD6R(>VZfQxO*H at cK$3%pv9T<B?Tl-5-+D}g*i5uDl5
+zl;n27fd!G`1<XZc54hDtU<V-c6UU}`dwU-|JUpm_DN*Q<I(3QGt8nd2Cr2Fbfpd61
+z%bS at 6jXH;uf_YmPowZV0INVzOhwfW0Xn73Z(-S?z at guQ0dZTwJ9lg8BDmPyr^nIS!
+zyL-0>m{|MH8<e7;5fh(XY%_RE!%GY!Y`i;h09i^@nmXcIW$6{F96W9`*s$RP3naWL
+ziGdLXkZ7!+tHqb2!c(~t<hoTgdHL`XbrQHGJKi_{0Qc^}@qusQrWQ%+?dumYx&xP{
+zf1-BG*@(Zuisw&r8!qCtG&jF at w6rYr*vu5zK^8mlj}ySifHyzx?Q{Xc at 35i)6<LzA
+zd*)>N!<+Bx&l)|$;V4RPHy>$B%`WuoLA8Bj5w#uhaRDzo*>d>9b?8<3Wkfli%#)4*
+zkBE*nn^H=K4D<PBqfCf at a|rf-EM55!d#<~8v4ZIHt=ak0x3Kb_AZBbJi(7DMrUsTZ
+z!sd?u?Elzy;-BWW*9 at PXoK()t%KGAYMP5<ypsB6xPqc(!2OlvwxKd+2Vz5*STv1b+
+z<MjY9{L_nz;mg*ASVnsKt>PMLtqW?J2L@&IKl1rMMu0FvH{xh<LJhggjg|bTRbCn$
+z!wjX0yU7|Q&U;RLwhMOqk)n1*y=(&#pYQslJ&zdL{x)Cop6;Z^4Y~akmA0m#$5JOO
+zUaEc+nf^w|z-gMY2c5br3ShrR((z)((4zAaeUl1H={q9%U027RRmVu>NfD0Q{R^~9
+zoit*1pbjS9;%awp%EZF4hnQ0W*thPz$xe at t^%j<w<-EMUkjBB4&P8f+=i1cnj8+VK
+zHkW(2ScPX->F({Out2T3Es~X0GnsxHOfPo;Nou*FPt?qAI`Vko454<ss&`%O+5XqK
+zS+ghi7jvfw4zoiU$JMCI7_YZI$~{RKSzqh-+f-=XNc~)e0pGQ7POuNrV?)6-R&8GV
+z+z|H0VP|U0{Qpspg3!euU*7}z6ZK?zXe>(BpaG%c`RMGO)z#;(q;b|8J44asm6e5+
+zl}w!#){(;fbQP%PcpAMu(EhK!e6OfO<z?_rm)&`ThgmiQ=9ABuAGe};2iG7z^1x^n
+zHp`(M@{#0`ET0!IOBX&8;nZ+O1|+9t9H!^1;<0OQ;$Odp$TFhQwyw5WFWPpmt0cyL
+zIP5F>%Q>E&9hE+tM7SA{v;TWITmhKb1V>WS-L|2_Yr$wu_~XKc;6`fV%v(v=5Jr^*
+zRTS6|hScLH^o#M at uSkMfgZn@1Sy@>>80v@=-s2Eyg|s2D0gY4%f2D+lg+IA{9_$V#
+za|9X9-E(Z?6-Hx;HB==ifj4ua?$hhFjjqSs4!ye-rh2Ty;_`e?8zgbJ14yfC*!^^q
+zm0Lx6gIJAnCW}GvwRRT;$94Pk&h2N}9^2|757!#yHHgSVdx!l!e$~F<VGs#7zGwZa
+zHm!sOHLcl<b);5whFP*4ZV4|<EvfnReyUz0NDKMjXcP3EEi5ctcCKF#MB}oI3MzT$
+zwx%^k-_+g-V+i<Yyxql-P;1cUz3l;g9~!OWeBN?}S- at 0iEMk5q>`tZaOr**T4N>=C
+znaI7rGyH6h7iOm$5Q=k%gnBK$xQm93!5NJ=Z0_A2DoA|(+jN61IRX1a%wJsE_xrgO
+z6$ktNY2bInmg{G9BCj*fvd?a^e1 at 3frvt~<S4xs(sUu}}sSBKU>Y?jxvOR^wC{vq0
+z;%H?5B(*0Al|*In$$L!+${DXi-FbFz$oTm9^v*0SNCSc3fmwubmkz;RaZ7#byfL;U
+z#)h*qXrSz)VspKomZ;^l)uv(69w%@!pv=FGHtza+>EDVvmkj;JE8=byU!ndJS^COT
+z$g9vDCisLCPsdPo!mCu$%gq)o%N?c8;oM=NdVQk7lI!W88<Px1|9Cm~P>Q8%OVjP)
+zrpQFFM%vXin~{C97^k_)UZe+i#AV|SrOd??O3GM36*tPAMdFi5w(dBk0yANwEM^>5
+z98DxhgBp{;$k!P}KgB?tg^@1CH+_8jY(z#(>|0q}Y}r$Ds+cF at _ixN-(>PXzD}6uX
+z1v1!$XsyYu*wf8c)Wi4ESv()}yKO`ww4D#rxS at w|f5KquTw#4bsMs31zTB$i3mBr<
+zWb#I3>%r4A{BRi|KvmAUv|QJRvRfiBeSh(*GVXQ6#u(35#5R7p4A?Ji-5ALier-Qh
+z_>{lBXnkJkt(C?wBi_zh{(G4Jd#OIuk#hgYoa>cGYU_IGx=qs}AE_wdAN at X-ik-zR
+z(d+H!okxST13fk)j1?_rqz0I?<iN(jP!9(QK}aZFD^3^K7$TFtpZj7aralm&LRNe%
+zn|*RZdC~m{8;bt6M>lo-2a6~H6I;q at 11>nbzUZf<nX46I)<i1G>LmX6g`o(tQleBc
+za!fwm&gwj+PFT63MkR}%@v|sBcg3%Or+#BnT8x<M=zxxhbs}cR%?1~h{Z6!vn8iav
+z-We$?X>_`>{q~^xXGp7CV3H~5;O||}tI<|JT=hQ{B$Wy}Qk8npO~P82+NjS40|d4S
+zEju{+oVtJkzZnA!lTOW_V`BSeq^+txQ>*q8<zU^ly$z85G0C)E-S5<g2cwl$mKb#d
+zo83Ytg))X_edk9nIx`#kC~?k=Kj%N<vgSa^wDr2kbL<4ah`L&;^I`<4sOLr!4kxRv
+zK&WFgO(m}=?w1=XoC$l|f)|!^jSFKnSz4g=xHq`@W*muul;NdjU&X{<Yk3m%8FBCn
+zaeT;0mjRz~Lbv0%0A>9zX=r|T*rYGZNM}p#=(EtCGDeY3{B~y5O#cXwVabxz-SNZw
+zAI?{AV_lG>wu^hveRhKwKxl1-j5 at jcQA${LtM2g+4<gy_VMwWP&pRN-a)#y|WSHkE
+zKGzUU&XjdgyM>dV;Myhc!OZC_|0k4KkGB*KnSpNLdWl6C+Sa3wUY!Z9Lu*K-c0g`p
+zZ3lkff$)Uy!7p2{Tehrl&9*P!!mNA8nzr`;T2aMa6`LBmSYRc&!4^M(0^Z!TpU67)
+zELgkFplmA4+}vEQVr8hnkD+u<n(#9_kFR8q7Ct_LU`FO&qTl4$VQH_n%S33(8PF*-
+zsH}QwztHO}V&iI!^d{i&uz#12Cf8s^4^3-ySW^9(#x1vq@)S~LOd)iSovL>3Zy at J0
+z)|==G-)?tYQx-%zPzIg<aGJR%GoRO~5u-=+Tle!lo at KiQy?(NXi=|V&IcxcfWSR2k
+zbM`ZIcdI$H at 2A-<UGY{_I6d=}HtuA at EOCbozo?&4(W;WxO4+RhLe?&JvL?um$4D0*
+zo~<-TgNY=;{ci-+#sp<B6zTh;y*~$Zb-BkB42zS*HwAs}BsmidKMm%Z&MffO|6Us%
+zI175NGb$XuEcJ+<YjC*QcC?mo_Bs=GK6XvOv5ABP2gboUd at __vCa(6}2xod+9$xl5
+z>p>F)6>GJP>x{`PoEaqk!v0XTP`9;3`*b=DA^x%!GY8xqRmmIq^<|#_oUrj!-sxbZ
+z(#2qyYL2wT{WlLj^2dTzBTrVz$Z!nNj2jqzTzxN!J+E(Iuni9UTpE}jW(+q4Q~B5x
+z&DBANoDzf*+8q_L2jf+RMP-5QV+Xfkt3AI!j=<=Mk3)|&?{!hE806Twb0UhhJGa|a
+z<iW6BM`I?w^*gRuVlZIxaCuk4V>egkAx+C^N3qn~jyppkoBA2*KC2|ArZzK$Ek*E4
+zy3lT=iNSAIh)o^dh^*>hK1kI&|E4##*Yr!_zEeItkh8ld at gxfKyY-^;T#hk~t`&>#
+z-HJ=?ZJ0u at vX0N<(z*yxdD7}H#s`t(*<mH$XK-$=nEV)G+cp!PItgQb-)T{O4|i5H
+zIaw?bxY$vL+61WP&9XNZ6YH-9EU&DLrn2Y{qZq7ZF<UBqDyo<55?WtoB|?o^3VjQU
+zV2lQqF_kt|gtBcu(^Qn|jj{H0S7!9SE`47aupbO#x^;WKSwjACq#G#uagCx~`+-w$
+zli2a1F7mpM#K3s1VQ^&Setrb4PUXi9;-O_AMty{;?!y3k&BEcWFwFG7e}BO607N5J
+zsn(bGLPWrw1Jdfw`$_4d#~zzvq^;SPO)&oiCF1Zl88iOPj-}P}$%M$bZ6}X^$<;<S
+z-P|2XW(oQD6AK|n at WL~j>}^Zss6%eIi?HUk^Y;41Kok4<hBh*M#%jVDO&%#?uo{Tj
+z^dHr*|J=P7whl~`1S>y={p$TnqD4`;e`r2-AAa|5PzubL2Rv8bLDpt at aY=Xzqt^7^
+z6Q<S(Aq2*@I5>2ite!3Vo4h#~lR9oEP_3`s4dpe^l32C)4iVS9jW6>P^NR0>{nJ(y
+zv3-n;k{1eXh8#%%v&=UIawhEoS-kd?#HewV2#HI2SQ&#o79&2jCv@}B_*mbL9ZF-K
+z8^t|^P(}QAW%v&p<{*yFNw=8tdP1rl&j=i_{!&0W72O`r>v*{A#)y^x0|ebWhxZq=
+zCnH3Ah?O+bjSRUR5^YS9aXiK0!4K_8y3qW{q0!ON0l?PPtfJ&9!_L%hpT}4Q$nvtP
+zXqDZRBSm#$<LFOMY+*j8W^NGszi^~~rW)yjg^0b2BVLu0TMegdlJvp-vcGBrKH%&;
+z at 2fcsh88|cYHoMQL_w`R_e8L8SjjrjZP%&MdQGkZyh^6vo#vr14P)Qu&>@=A^Ps^#
+zQ;I+NiHV7M%jXZR#mRPSZ3)%-t;+nBG<MjxrTs9j_#cl3N9{Bjilu{E*i4(7_>8_q
+z)+$)R!{LZgh{C=m`{Fh4ql{<nM3ItF^L(3Q3RCuzt6WFNCx at rTy?GI2{wNHlBXA`y
+zyDWGbMg)IOTet$epQ$-R_5acX65NAwru*)k_}8SqA<;)Q^j1}!(Xpo43ih?wul^_6
+z>wD73a=JcT@@=7&ShyLwgo7*sK?{lSQQEen6}ODQi{!b$0XeBO<t>2_F1QOWgVkxf
+z_wCbeA&#HBY+g5!_k*Fme)?Q_pKG5DmI_>8e#$ZqnZ>+Tskz5e8T}1MYmZ&Bhog|i
+z86KCg at L4F^A57GU)w<MD6eu|Gv|K)V3Y|iL^AjkO$Mz>^celqW)WoMDoTuJPa(pBr
+zJcs^I5)cyG6I3?~a=s{vLrKA#Rn?L#>-k00>-<HE1}42^??RAt+XJl^vSg&NSAT2*
+zyz(b&Amrtdo(3lHoNvk-RdM>qRXLh*!n|1CuhF9|L)>1spW1^#QvAdYN^!)H=*X}E
+zwH4osdV4>sz;dJgNV;4TuntXA`yj4w<hMTVm8&lY(m7lP&{jf`Q)~TNnz9<g*Z)$G
+zaE=Ydvo6vs6nGUDpgY9oe at BN(CNvuGdBpJXc9wOvYCR#R>#7b#*5mtywG}FDaCltx
+zI^FaL%hZWoP;&$BG8pzRSiC~k4`x~t*s#*mdp5MSJ(+50!4=NXtBAgHJN7&u{DH+M
+zbfhl5*0kd|m)`c7MfpX?yyNwLp{DI^6rvhyN}NdxQJXaUf{BP^u;z3dks-_mty^QL
+zrS<d|lzM%As=f0=ke=a=J-~aJ1BtB43lVU${trL^W=glH(p#8JD9g1Qu+BNOdVoa{
+ze%uMNp&OpNC}7o&ZoL^y(AN)`I8OY&vFH&P%}T>;i_JKhu8`u9(w~x}fWFhm1B{QW
+znzf at Ut6}=A{@o at Hk8cE>kF7r at P^@pC25YY$E~tEOUK-0PSj5zz-Ebh}p+I$zAb1Pz
+zzy~9A0J!HKMRM_w>J=5kVA<R&7|TzQ;^XTstgKWB-Tb9u{?_!9Mj=(PjZ}rHSSX3v
+zD%Cw*n&sCp2b`QTVWcZt-=WJPK{mm93Xw|_8_3GZCb<2+_zWmADpM;IBPkR%2pj}1
+zrV}vc-hC&>qQD%PboO<G2Y^FDr$oMLA~!;yBv=dbZ~q6+<K10$mVB{1uj9sekKgNm
+z9lyW7-!+<&v`kY|Xw;h&IwyCNf30IK1QA`k{!9lQPVSE7SrD7#2BInjeYvOU at +*sW
+zAV2cpsP3>CMH2r7qakm`5e at jh0_&;rzdKUptJ<(>dr(KE1k-*qG9taWycD%JF)=yr
+z>kHg1FU>7zXh;NiRaIYK at PcQTf4OLChh?S@`5u05o at z-h#%HpgJmCVy^ZjC%yF?Uw
+zIv;*);F9F027lNHdy*J)=D0f)$z?IvmxP0tuo1&x<&pqDU*10;;y{g+rKN{ey37mH
+zv$K at oNd@l~?(Ze3SgkYxca8WWb4a9xJ7d0mpXaq=jJS?ws4?e5HH+ki at U4mL^wYqf
+zn;N>t6+u3Q_+yl;9`TqCASj9%gvW(|4Fp$mslbXunWT}urjL)0{cBGl*SjON>wg+5
+zU^#HQXn+W~$~tgPy86zbW|KP4O*F4bZ#b?wkQ`MGR}?EbjJ9>(F|v9t7|!wT0Y$YM
+z;F*UG2<Jh_kc9R7nz!z72^J5ama3PpfUlioUa#w?q7rvA%2a!GQdz66qXPmfX>4q4
+z at cCw2m2l^*uy-*yDkSN&M%97~KGS^>GT5DK7rhLI?>1R}-9hxd{shFwa5|ubi3=ku
+z0WV-X?0NOA!JtFTaFGcP78ZAC_Zrr4asBo2()#n`ou3%><m3dbWXuPvn+FEoBns5l
+z&XOn|2q?0t%QXecFiDbs=9(gD{t8QWu%Zk1<m?Va0Nq8L1+Ia+LPS6YxRgPOj|LZ7
+zK at BJ!fj?&FrUR9g<^-UE`b>Y5lg6nK5ff+Q#DSQwB17$`a)r;98{q(XQ!+|QC}2G#
+zbck4RKRM~tmA at +{-Ne6XX4^Ws9K;#1jH7~hh%U-Z9YM)(Bg)T@>bxDcyPZ1Qr88b)
+zRFo{k#*fx={xe4RPLxiiek+~&Rn4=^sKFYOR@<d>3DD{}?^(trDoX8Qq+iz%MjQkI
+z3i-w*^nan}F<d-fq{?%U^EbXNsW>`4ShshsT<Q{$%!wW&T}p!)nQ6hPmndH>1O)|k
+zw$`4MBj{mOd+5Xu4-E;nb<M%Uy+yU;Y?fP{A;n at gCPSS89V7UJJPcX24-ob}*~YHy
+zARMhJcY5>E$>zzI74gl%*B?(L52<&PQ6x_byy3EZ`2mUNpJ%JMBPs0(u}z|k;=_l5
+z7zVusCohKufG-mDJ62)a;zFjvj~=SPij)kiIfVf$B^Bp<LAlscU)zy(oQLWd<VQ;?
+zI3g;f&!RZXWXq8lirJO8-WjkN!s69&)GK7m5g2&-All~kLz(SP!G^p$yooHb?+^?8
+z8)~tK!?+qlQTIpuh=PxgR;AyAjGCpPdSiyb_wLWwVMi_`PmzZKE91T{y43<RQ5lMr
+z<jXTk%H<if7>X$+&YuVX00 at o${udyW9Y=~I6g?bWTnC$`m|h;dp$d^TvEbOa+<_w%
+z$(iiTm8k(+hr9$4{%cve$_wiqNJJOS6*djq$93aH<B1);76u84iAV$e;V5VwU%`$X
+zx?MYbQ$cyOWAB5Gwr>f|wyku>DkA1;s<3Njm5sg*-%-{>HV`_y{`sC1o{ZeI!gWUi
+zU18m{GSn8D3u!WoHH>f-jV~%ij=xK;yTeHBEc#7>e2ZZmZCGG$eBgTs{>Ik9>d+Xk
+z9n)(Bvp(E!B{nPH2wW+Sjy^m1TU4u at z90V=kN|K01E)|}q5 at UGW*g%gdJaG;g~5!U
+z<B6(p5K0_`5-~j_HC1kYI?VjE1MKnCH}5w6Rr(kJa at BPmfDvN&G?`l$u=J<qTNkia
+zZ4l%D9D$RLGd(gq*T(|zNctfekloJ^Uj_p5zwZDsJmTqZ at h;E;U0=<9q^|<tU-!BK
+X7r#1Y+t^fI00000NkvXXu0mjfaq#|@
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/mozicon16.xpm b/im/branding/messenger/mozicon16.xpm
+new file mode 100644
+index 000000000..3434739f6
+--- /dev/null
++++ b/im/branding/messenger/mozicon16.xpm
+@@ -0,0 +1,193 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++/* XPM */
++static char *instantbird___[] = {
++/* columns rows colors chars-per-pixel */
++"16 16 167 2",
++"   c black",
++".  c #020100",
++"X  c #030101",
++"o  c #020202",
++"O  c gray1",
++"+  c gray2",
++"@  c #060606",
++"#  c #070707",
++"$  c #0B0B0B",
++"%  c #0C0C0C",
++"&  c #15100C",
++"*  c #101010",
++"=  c #111111",
++"-  c gray7",
++";  c #151515",
++":  c gray9",
++">  c gray11",
++",  c gray12",
++"<  c #2A1400",
++"1  c #301E18",
++"2  c #212020",
++"3  c gray13",
++"4  c #232323",
++"5  c #272121",
++"6  c gray14",
++"7  c #252525",
++"8  c gray15",
++"9  c gray16",
++"0  c #2F2F2F",
++"q  c #33302D",
++"w  c gray20",
++"e  c #343434",
++"r  c #353535",
++"t  c gray22",
++"y  c #3A3A3A",
++"u  c #46120C",
++"i  c #501F15",
++"p  c #521E14",
++"a  c #4D261A",
++"s  c #562217",
++"d  c #572318",
++"f  c #582418",
++"g  c #693200",
++"h  c #6A3200",
++"j  c #773800",
++"k  c #7D3B00",
++"l  c #7A3C0F",
++"z  c #512E20",
++"x  c #5B2F28",
++"c  c #423122",
++"v  c #553127",
++"b  c #543A24",
++"n  c #543129",
++"m  c #663520",
++"M  c #6E3E27",
++"N  c #613628",
++"B  c #723E29",
++"V  c #7F4919",
++"C  c #6F432B",
++"Z  c #7C4222",
++"A  c #794523",
++"S  c #74402B",
++"D  c #76422C",
++"F  c #75452E",
++"G  c #78472F",
++"H  c #63453C",
++"J  c #6F483A",
++"K  c #764430",
++"L  c #744731",
++"P  c #754A31",
++"I  c #754B32",
++"U  c #774B35",
++"Y  c #774C37",
++"T  c #794834",
++"R  c #474544",
++"E  c #464646",
++"W  c #494949",
++"Q  c #4B4B4B",
++"!  c #5B5047",
++"~  c gray37",
++"^  c #714E40",
++"/  c #77574A",
++"(  c #7E5E4C",
++")  c #8D440F",
++"_  c #914500",
++"`  c #964700",
++"'  c #984700",
++"]  c #9B4900",
++"[  c #994A03",
++"{  c #93470D",
++"}  c #924C0E",
++"|  c #8A4211",
++" . c #85461C",
++".. c #924B15",
++"X. c #A04C00",
++"o. c #A34F05",
++"O. c #A95000",
++"+. c #AA5000",
++"@. c #AD5200",
++"#. c #A4540E",
++"$. c #BB5800",
++"%. c #A75711",
++"&. c #AB5C15",
++"*. c #AA5C16",
++"=. c #A75C1A",
++"-. c #A4591E",
++";. c #B15E14",
++":. c #834928",
++">. c #914F23",
++",. c #865121",
++"<. c #865224",
++"1. c #8C522F",
++"2. c #935A27",
++"3. c #814D33",
++"4. c #8A5332",
++"5. c #8B5635",
++"6. c #83563A",
++"7. c #86543A",
++"8. c #8D593C",
++"9. c #936134",
++"0. c #B76822",
++"q. c #B96923",
++"w. c #BA6A24",
++"e. c #BF6D24",
++"r. c #BC6E29",
++"t. c #BE6F28",
++"y. c #B97335",
++"u. c #8E6147",
++"i. c #8A634F",
++"p. c #8B644F",
++"a. c #9B6746",
++"s. c #916844",
++"d. c #996A41",
++"f. c #9E6947",
++"g. c #967156",
++"h. c #A06C48",
++"j. c #B07C53",
++"k. c #967C66",
++"l. c #937B69",
++"z. c #A17F65",
++"x. c #B18866",
++"c. c #BB926C",
++"v. c #A78B74",
++"b. c #E79146",
++"n. c #FFA759",
++"m. c #C59F79",
++"M. c #D6A26D",
++"N. c #C5A37F",
++"B. c #CFA87C",
++"V. c #D4A775",
++"C. c #D8A976",
++"Z. c #F8AC67",
++"A. c #FFB36F",
++"S. c #EAB67A",
++"D. c #EEBA7D",
++"F. c #F2BE7F",
++"G. c #FFB97A",
++"H. c #FFBA7D",
++"J. c #FFBB7E",
++"K. c #BDA68B",
++"L. c #C6AC8D",
++"P. c #D6B286",
++"I. c #C9B190",
++"U. c #FFC490",
++"Y. c #F2D09C",
++"T. c #ECD6AA",
++"R. c None",
++/* pixels */
++"R.R.R.R.R.R.R.R.R.R.R.R.9 R.R.R.",
++"R.R.R.R.R.R.8 4 O O + Q W k.R.R.",
++"R.R.R.R.9 y y 7   =   ~ $ * : R.",
++"R.G.Z.c t r 6 = : 4 + @   o R.R.",
++"J.n.;.& # -     @           @ R.",
++"A.b.O.k < .       % > #     X R.",
++"H.e.] $.X._ j h g V ,.z H ( U i ",
++"U.%.+.' ) | @.' ` [ &.C L.u.j.P ",
++"R.} o...v.p.{ m L l *.A g.6.I a ",
++"R.b #. .N.c.5.l.z.B.Y n 5 2 3 = ",
++"R., <.&.Z f.T I.x.a.h.v w r e R.",
++"R.R.q 2.=.4.:.>.1.7.x / ^ J N u ",
++"R.R.R.R 9.-.0.q.w.M K.i.Y.C.3.B ",
++"R.R.R.> E s.r.t.t.G T.P.K 8.D.D ",
++"R.R.R.R.R.0 ! d.y.F m.V.M.S.F.S ",
++"R.R.R.R.R.R.R.; : 1 R.R.s d f p "
++};
+diff --git a/im/branding/messenger/mozicon50.xpm b/im/branding/messenger/mozicon50.xpm
+new file mode 100644
+index 000000000..76e799c60
+--- /dev/null
++++ b/im/branding/messenger/mozicon50.xpm
+@@ -0,0 +1,314 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++/* XPM */
++static char *instantbird___[] = {
++/* columns rows colors chars-per-pixel */
++"48 48 256 2",
++"   c #000000",
++".  c #0C0503",
++"X  c #0B0B0B",
++"o  c #1A0902",
++"O  c #141414",
++"+  c #1B1B1B",
++"@  c #1F1515",
++"#  c #1C1108",
++"$  c #2A0B0A",
++"%  c #350201",
++"&  c #3D0B07",
++"*  c #380907",
++"=  c #371B03",
++"-  c #381A00",
++";  c #3E140F",
++":  c #231815",
++">  c #381613",
++",  c #372414",
++"<  c #242424",
++"1  c #2C2C2C",
++"2  c #3A2B2B",
++"3  c #392828",
++"4  c #353535",
++"5  c #3A3A3A",
++"6  c #3E3535",
++"7  c #420E0A",
++"8  c #44120D",
++"9  c #4A160F",
++"0  c #541C0E",
++"q  c #451511",
++"w  c #481711",
++"e  c #4D1B14",
++"r  c #461814",
++"t  c #501D13",
++"y  c #4F270F",
++"u  c #552800",
++"i  c #5A200C",
++"p  c #4B231D",
++"a  c #492018",
++"s  c #542115",
++"d  c #582312",
++"f  c #53241B",
++"g  c #592519",
++"h  c #5B2B1E",
++"j  c #572A1D",
++"k  c #64280A",
++"l  c #702B01",
++"z  c #693200",
++"x  c #753302",
++"c  c #7A3808",
++"v  c #632B13",
++"b  c #632B18",
++"n  c #6C3416",
++"m  c #783817",
++"M  c #452A28",
++"N  c #562C23",
++"B  c #5B2D23",
++"V  c #5A332A",
++"C  c #4B3E3E",
++"Z  c #643323",
++"A  c #6B3A27",
++"S  c #61362A",
++"D  c #6C3D2A",
++"F  c #693624",
++"G  c #723E2A",
++"H  c #653D33",
++"J  c #534239",
++"K  c #6F412E",
++"L  c #73462D",
++"P  c #79522F",
++"I  c #634C38",
++"U  c #7C4A33",
++"Y  c #744C3A",
++"T  c #784A37",
++"R  c #6E5137",
++"E  c #7C513C",
++"W  c #454545",
++"Q  c #4C4C4C",
++"!  c #484040",
++"~  c #514646",
++"^  c #545353",
++"/  c #5A5A5A",
++"(  c #5A524A",
++")  c #734F43",
++"_  c #775545",
++"`  c #696159",
++"'  c #646464",
++"]  c #6B6B6A",
++"[  c #727272",
++"{  c #7C726A",
++"}  c #8C0000",
++"|  c #AE0000",
++" . c #813C01",
++".. c #833907",
++"X. c #E20000",
++"o. c #F80000",
++"O. c #DA2D04",
++"+. c #8C4303",
++"@. c #964700",
++"#. c #974801",
++"$. c #9B4B02",
++"%. c #9D4F09",
++"&. c #90480D",
++"*. c #9F5009",
++"=. c #8C4918",
++"-. c #954C14",
++";. c #8E531E",
++":. c #93541B",
++">. c #9D551B",
++",. c #9D581A",
++"<. c #A44E01",
++"1. c #A14601",
++"2. c #AD5403",
++"3. c #A3530C",
++"4. c #A55105",
++"5. c #B35400",
++"6. c #BD5900",
++"7. c #B85700",
++"8. c #A65710",
++"9. c #AB5C15",
++"0. c #A55A17",
++"q. c #AF6019",
++"w. c #B2631C",
++"e. c #8B563A",
++"r. c #8C5A3C",
++"t. c #855535",
++"y. c #925E3E",
++"u. c #915E31",
++"i. c #8D6037",
++"p. c #97623F",
++"a. c #AC662B",
++"s. c #B66721",
++"d. c #B76925",
++"f. c #BA6B24",
++"g. c #BE6F28",
++"h. c #B56728",
++"j. c #A76D38",
++"k. c #B77337",
++"l. c #C35D00",
++"z. c #C95F00",
++"x. c #CD6100",
++"c. c #D26300",
++"v. c #D36B0F",
++"b. c #D66D10",
++"n. c #C1722B",
++"m. c #815640",
++"M. c #8F5D41",
++"N. c #835E4C",
++"B. c #865C44",
++"V. c #8D654D",
++"C. c #936444",
++"Z. c #9B6D4A",
++"A. c #9A6746",
++"S. c #856B57",
++"D. c #946E53",
++"F. c #977455",
++"G. c #8C7057",
++"H. c #A26E49",
++"J. c #A8754C",
++"K. c #AA7B54",
++"L. c #B37F55",
++"P. c #987866",
++"I. c #EF8323",
++"U. c #FF993E",
++"Y. c #FF973C",
++"T. c #B2865A",
++"R. c #B7875A",
++"E. c #9D8570",
++"W. c #9E856D",
++"Q. c #A5846A",
++"!. c #B88C64",
++"~. c #A78D76",
++"^. c #B1987E",
++"/. c #D68A48",
++"(. c #C78C58",
++"). c #FF9C41",
++"_. c #F39641",
++"`. c #EB9A52",
++"'. c #FFA14D",
++"]. c #FFA555",
++"[. c #FCA659",
++"{. c #FFA95B",
++"}. c #C08F60",
++"|. c #C49262",
++" X c #CB9C69",
++".X c #C99968",
++"XX c #D29F6A",
++"oX c #C29D76",
++"OX c #CFA36D",
++"+X c #D5A46D",
++"@X c #DAA66F",
++"#X c #CCA377",
++"$X c #DDAB73",
++"%X c #D3A776",
++"&X c #DDB07C",
++"*X c #FEAC63",
++"=X c #FFB069",
++"-X c #E2B177",
++";X c #E7B57A",
++":X c #E8B77B",
++">X c #EEBA7D",
++",X c #FFB573",
++"<X c #F2BE7F",
++"1X c #FFB97B",
++"2X c #E8A467",
++"3X c #8B8B8B",
++"4X c #868686",
++"5X c #959595",
++"6X c #9F9F9F",
++"7X c #AE9A83",
++"8X c #B9A186",
++"9X c #B8A991",
++"0X c #BDB398",
++"qX c #AAAAAA",
++"wX c gray63",
++"eX c gray69",
++"rX c #C4A886",
++"tX c #D6AF82",
++"yX c #D8B88A",
++"uX c #D7BE95",
++"iX c #C7B998",
++"pX c #E8BC82",
++"aX c #F6BE82",
++"sX c #CBBEA3",
++"dX c #DBC29B",
++"fX c #EFC68F",
++"gX c #F2C284",
++"hX c #F3C68A",
++"jX c #FFC38D",
++"kX c #F8C68C",
++"lX c #E7C694",
++"zX c #F4CC93",
++"xX c #F5CF98",
++"cX c #FFC490",
++"vX c #F5D29C",
++"bX c #DAC9A7",
++"nX c #DCD2B5",
++"mX c #EDD9AE",
++"MX c #F6D6A2",
++"NX c #F7D9A6",
++"BX c #F7DBA9",
++"VX c #F8DEAD",
++"CX c #E3DCBE",
++"ZX c #E8CFA3",
++"AX c #F9E3B3",
++"SX c #FAE6B8",
++"DX c #FAE9BD",
++"FX c #F3E3BA",
++"GX c #F7EBC3",
++"HX c #FBEEC4",
++"JX c #F4EFCB",
++"KX c #FCF0C7",
++"LX c #FCF3CC",
++"PX c #FBF7D3",
++"IX c #E8E6C6",
++"UX c None",
++/* pixels */
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX| } ",
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX+ + UXUXUXUXo.X.UXUXUX",
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX4 ' eX[ X UXo.UXUXUXUXUX",
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXX + + O           UXUXUXUXUX5 6X5 qXqXE.O.UXUXUXUXUXUX",
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX+ 1 4 5 5 +                   UX1 wX3XQ / qX(.P.X UXUXUXUXUX",
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXO < 5 5 5 5 5 1                     X 5X3X] Q O [ 6X5X' . UXUXUXUX",
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUX< 5 5 5 5 5 5 5 1                     / 3X] Q 1 X   ^ 5X3XO UXUXUXUX",
++"UXUXUXUXUXUXUXUXUXUXUXUXX 4 5 5 5 5 5 5 5 5 5         + X         4X] Q 1 X       < Q O UXUXUXUX",
++"UXUXUXUXUXUXUXUXUX1X2X: 5 5 5 5 5 5 5 5 5 5 5         O 4 1     O ] Q 1 X             O UXUXUXUX",
++"UXUXUXUXUXjX=X{.].`., 5 5 5 5 5 5 5 5 5 5 5 <         X 1 4 +   X W 1 X             O UXUXUXUXUX",
++"UXUXUXjX=X'.].'.[.y 5 5 5 5 5 5 5 4 + < 5 4       O < < 4 4 +     O X             X UXUXUXUXUXUX",
++"UXUXjX*XY.*X).*X:.  5 5 1 4 5 5 5       X .     < 4 4 X + X                         UXUXUXUXUXUX",
++"UXcX*X).*X*XU.n.z X 5 4 X   + 5 1               X O +                                 UXUXUXUXUX",
++"UX=X].'.=X'._.#. .. O       O 1 X                                                       UXUXUXUX",
++"jX=X'.].=X].v. at .@.u                                                                     UXUXUXUX",
++"1X=X].'.=X`.x.$. at .@.-                                         O X                         UXUXUX",
++",X=X*XY.=Xq.5.l.#. at .@.z o                                   X 4 4 +                       UXUXUX",
++",X=X=XU.].#. at .l.l.#. at .@. at .z - o                       1 4 + . 4 4 4 X                     . UXUX",
++"aX=X=X{.I.#. at .$.x.l.$. at .@. at .@. at .@.x u - o .           < 4 4 4 4 4 4 X   . o > > p N N N j s % UX",
++"jX=X=X=Xb.5. at .@.$.z.c.5. at .@. at .@. at .@. at .@. at .@. at .@.+. .x c ;.:.:.>.,.0.y % ) 9XbXFXSXVXvXzX$Xg L 9 ",
++"UX=X=X=X2.c.$. at .@.#.7.c.z.<. at .@. at .@. at .@. at .@. at .@. at .@. at .#.9.9.9.9.9.9.n N N P.GXDXVXMXzX+Xs K.|.e ",
++"UX1X=X=X#.7.x.$. at .@. at .$.l.c.z.2.$. at .@. at .@. at .@. at .@. at .@. at .%.9.9.9.9.9.-.V IXS.N rXNXxX.Xs T.>XXX8 ",
++"UXUX=X*X$. at .l.x.$. at .@. at .@.<...k c.6.<. at .@. at .@. at .@. at .@. at .@.$.8.9.9.9.9.p LXGXrXS T L.g !.<X<X$X7 ",
++"UXUX,X`.$. at .$.x.x.<. at .@. at .l w * c c.c.c.6.2.$. at .@. at .@. at .@.$.9.9.9.9.9.a HXSXVXlXD.F .X<X<X<X-X7 ",
++"UXUXjX/.%.$.$.<.c.c.<.$.x e sXH _ c 5.l.c.c.1.d x @.$.$.$.*.9.9.9.9.9.e FXVXMXzXhX-X<X<X<X<X>X8 ",
++"UXUXUX/.3.$.$.$.4.x.c.l e CXnXH GXZ  .$.%.2.k 8 N.j v c $.$.3.w.q.q.q.a dXNXxXhX<X<X;X+X|.L.H.8 ",
++"UXUXUX!.3.%.%.%.%.3.k _ JXLXbXS SXZXs +.%.%.r 7X) KXuXB.e v &.w.w.w.w.f Y D f 8 * * * * $ $ o UX",
++"UXUXUXUX=.3.3.3.3.3.v 8XKXDXdXS BXMXtX0 %..._ JXN bXAXVXvX!.f p J I R V 3 : @ + + + + + + O X UX",
++"UXUXUXUX, 0.3.3.3.3.%.t mXAXyXB vXzXhXR.i d nXLXW.Y VXMXvXzXgX(.h M ! Q 4 < < < < < < < < O X UX",
++"UXUXUXUXO P 8.8.8.8.8.c m.MXtXB hXgX<X<Xy.N LXHXmXe uXvXzXgX<X<X<XA.% M 1 < < < < < < < < X O UX",
++"UXUXUXUXO ! ;.9.9.9.9.8.0 #X%X7 G y.K..XM.7XHXDXAXD.E zXhX<XXXC.s A 8 4 1 1 1 1 1 1 1 1 1 . UXUX",
++"UXUXUXUXUX< ( 0.9.9.9.9.-.d :XOXR.Z.t.D q GXDXAXBXlXq A.A e F C. X}.a 4 4 4 4 4 4 4 4 5 < X UXUX",
++"UXUXUXUXUXX ^ I 9.9.9.9.9.m e.<X<X<X>X XZ B rXVXMXxXF.C.T.+X-X>X<XF 2 5 5 5 5 5 5 Q ^ Q O O UXUX",
++"UXUXUXUXUXO 4 W L w.w.w.w.q.v R.<X<X<X<Xe.v m b !.hXpX<X<XZ.M.C.r.r 3 3 3 3 2 2 C ~ ~ 6 . UXUXUX",
++"UXUXUXUXUXUXO 5 W P w.w.w.w.9.0 +X<X$XF m g.n.g.=.n H.>X<Xf q ~.9X8X^.~.Q.P.D.V.B.m.T K A b % UX",
++"UXUXUXUXUXUXO + Q Q t.w.w.w.w.>.d H.d >.w.w.g.n.n.g.=.b p.e 9XN sXLXHXDXAXVXNXvXxXzXhXaX at Xg h UX",
++"UXUXUXUXUXUXUXX 1 Q Q u.s.s.s.s.=.m s.s.s.s.s.g.n.n.f.s.=.8 PX0XN 8XDXAXVXNXvXxXzXhXgX|.e Z.A.UX",
++"UXUXUXUXUXUXUXUXX 5 ^ ^ i.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.w PXKXiXV Q.VXNXvXxXzXhXgXJ.9 K.;XA.UX",
++"UXUXUXUXUXUXUXUX+ X Q / / _ d.f.f.f.f.f.f.f.f.f.f.f.f.f.f.w LXHXDXuXH V.vXvXzXhXaXe.t T.:X<Xy.UX",
++"UXUXUXUXUXUXUXUXUXO X Q / / ` a.g.g.g.g.g.g.g.g.g.g.g.g.f.w HXDXAXVXuXY T fXhX:XA A |.>X<X<Xe.UX",
++"UXUXUXUXUXUXUXUXUXUX+ X W ' ' ` j.g.g.g.g.g.g.g.g.g.g.g.f.e DXSXVXBXMXyXB.Z  Xg r.+X<X<X<X<Xt.UX",
++"UXUXUXUXUXUXUXUXUXUXUX+ X 5 ' ' ' S.j.n.n.n.n.n.n.n.n.n.d.f SXAXBXMXvXzXpXC.t K.$X<X<X<X<X<XU UX",
++"UXUXUXUXUXUXUXUXUXUXUXUX+ X O Q ] ] ] S.k.n.n.n.n.n.n.n.h.N AXBXMXvXzXhXgX;X X:X<X<X<X<X<X<XL UX",
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUX+ X + Q ] ] ] G.k.n.n.n.n.n.h.V BXMXvXzXhXgX<X<X<X<X<X<X<X<X<X<XD UX",
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX+ X X < Q ' [ { G.J.k.n.a.f oX#X%X&X;X>X<X<X<X<X<X<X<X<X<X<XF UX",
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX+ + X X . X O + O # = $ > > ; 8 7 & & & 7 8 e g Z G U e.9 UX",
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX+ + + + + + + + UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
++"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX"
++};
+diff --git a/im/branding/messenger/windows/blistWindow.ico b/im/branding/messenger/windows/blistWindow.ico
+new file mode 100644
+index 0000000000000000000000000000000000000000..83dfe4415cbff4b4a642bd9d1dfa3c8e28b92999
+GIT binary patch
+literal 9662
+zcmd6sdu$X%7{HhK!2e7%LG9k{?e(thU3*mmSTPm~fg%v)AxJ4fAP8tc9)$vJL0hN@
+z1xgE4p!Du)n at 9*E1dUX{M?s+S?%f47K@<KrzIY_44WHk)x4XSt=Js~Cca7IfXCL3p
+z{Jw8yzWHXB;|Ad0;K3aJ7rBF395;yLI1eU##LdG*&(ryHh1v&+kzk1s4m3EzfeuVR
+zVfqcz-*TdBde%WQBuiz|$&{>a{>Qc_9bx}F$n-s?`<TFF!ZN`wEVIOR-Ty?g_EPoU
+z at k8@7$h`yGy<?JBPd}=wUcBD=bgDQXsOQ_7hlP-TIks~vh1^=5?uwy6P2TlGk3P_T
+zA0F7QwPqpn)iiQz^|*p#%H0QKwWt{OPcdS1`__eE-?AWO$@angd;IJ%Z5cx|*D})(
+zSBVOl;6e-s<{|sPM(mz3JR7i`{!AwmU`vmMaBz_kZbjz*#P5g%rXp95!e%7T82em*
+z+Me1vz_LHh8|3}V2y?8AZOx2+<>!Yvrz`yVWrgc89rBfpIP9%2`NOkwHW*ErUu};1
+zj`K~BF=1$b>2L(u2dMlj3Qr<GSV_6HlfcovKdQs&M&L_FrBw&MwCJ2TN_<RVr#!!G
+z#0e|xN*T|tH^33{M|J4-gS~D6WEAD4R1bbq0odEtQX99l>-4i_g?@#_YVNI{3F5`3
+zs16hhUEBxu?Tdh)`l59`hPlBuw-^NfD(qv~K2&!ouszoP-rC6%^H+|rG=5_B^{p!g
+z_mN5vmA;T;I^oN at s4j1g2Yz&ZVtt->Nppx_IvMOAE(77aoxS#mj}Pxq{HW+4L;_2*
+zKU&gfenpqu>WSb!Tmj;hW_J5sO&}br1^a<2u(z%T;oy3397jKJWglBUo;@lP at -J5S
+zah<(LzR>+?1^8BvN|_#1muL4Ja38G#@j}elV)2-M7VIK^XQbsRWLM*N=h+7EG|dHH
+z3dWPtA2c^Izuscpw#Ib1PwZkSSQ@(yDc7V2jj6nM$6M+TnhQDm7C`1Vb*bi7>%(zB
+z1LN(T3NtguxtMu+J7gU!2lA77=<oB(N5<>4stEGln;@-u*&nX}X-(72VP at Sl-p}A1
+zz1E^KG365U2kk{MoiI~ImA$+doL#%k%{k-{F6;q&?L6RLDd_b>=qLG^MPT2v9DSoH
+zU5?{k at Mo1Nfu5;)FC5(n8DsS0JicV4p5N5=(+y;!vjOe%l-~;-b-)*Tdu^_>SKwbQ
+z00;I{Qm#ngSCpYMj^wg^k- at c-pEBGKyRrwOc-8>dJxlyJ-^d at jKCcGXsZAhW(zlh+
+zzSb1Gq(gxl92nCk(Si64j~`lt$S3Bn86D?;Xsz(>C<SNdHfDRavT5e|aeUdE%b4}4
+zIz`9NFY3L{7$JN6s*2;dmGw!@(T`HxpskOeJ=z*S`YCN)n)@3@{HOC=Bls%E>a#2R
+z2kZ;?7d3J1+Gbhfw{4gcSC59B-W^Z6eqo<@aBQeHRycL?ysB{^UhR$DD4ta2rJ0;!
+zPzJO5jMgvo|FiUDoaY)$u`7CJ9j#Q`v19yhhFg-wSlV%>QLTf;Naw)O^UU7(O)KX<
+zwAvCs#eiyE=&#J~jcwRxYI*j&l;SsvK~e5fBH8TL#g_QJTc*dgZ~vqkGG53s)DQf)
+z!62O76<1!%hq2oQVyB-F2`<yVSMIahms;cB_Tc&>v{wNCl1Enue&R3?PO<&4!X)QQ
+zqVyaWJ<AW=)x4MVcO6 at 2i9e@hA=7?BX9L();(9PLH%<@!<so3-G#?z7_A<+9*y8q&
+zqzBH0MvaVAkBBj at uiX5e%yr^@eGZH%$j-uNo4|qRF08h7p4BV1S8`i-8;|nLZxT5s
+z=Rj`VG_yQr<ZqMDQMhAs+y_ at Mbw>Y at yZJRk<H%Q84C48O=LTjt*|HITc`S46HGTI$
+z{%)oYIF7sxvvhUH-S7&~zLQy=?E}rqULAV5`H@&=?RB#ATUW<MX`e{@TRJoHRg3}e
+z*4Hua!LzY$Q+p?~?6<{mD}7c?`or_BX=p=J=jUm(IqBI$-+_{X#|WVOTWMx8Y=1gm
+zi$ODdY3BP;nsn_EBZ0RK12Y8Wv2;64e0qIwi at pOfkW4>vh5|Xr&-P2H at hkCqg#6bs
+zyZ2|C2GuD*eoOv-ozA|HzF)g<>>8+p(x+E^sKqA78q9df;yAlQdl8BO`UGd9FvWaw
+z+?p`<PNoZ;dy{X8J<B(NkTOyFo<sXM+KbBjX*?GT{*L_rM3Zza?X^jU&WyF+fULp*
+z+#CqNaca7U`x(0blj8<b-pO$fQC@>BP)-fum%saR-XrH&3<Wu^Q_gEB$59-Y$Gq>P
+z_joV8$NIE6y-ww?hALyU(@D=6TsP at C@}n6z?(yDS($m3llHNtK9jax!pmE4f11Rs5
+Q?WWjKu`9ikQq=DM0qh`X{r~^~
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/windows/convWindow.ico b/im/branding/messenger/windows/convWindow.ico
+new file mode 100644
+index 0000000000000000000000000000000000000000..a22977ca8e9d1f0ad31da2508341a0aca8c11093
+GIT binary patch
+literal 10058
+zcmd5?O^X~w7_O~8>@j;$Jn0Y*Q4rh>3Mz!`svr`?CCGw^GEq at 9s6zq<(U1;VL4qH<
+zU{FDfilP#P at ggW5nxN=KS??Yi`~!RRpq9^5(=}6DUHwr#wH+tC`*wXl&-+nT-9(55
+z{99QO_&X4H91`MsA;c{ZREZ}ctgrehr9=!#e!a2^Ng-oM2FW4H64p_+AVbI?#=7&)
+zQD7lv8*9ijd8Q$J<f;3XAVWyn6+hNnD%RbF4#BIEAKp{R=Vz6C`za;gcw7O;UU~U}
+zUr;xOj3CPfBc2UzwwW;_(;lLMnK2NK{mQ127dFh=Avy=<%))JtopNl$0k~=V3=(Gd
+zZ?}~^yKb)=>v^{gZqo<2mm$HnmzU4P!t0x7Z16Q{VDA(=^4;h4x@(tCsSr81`Irx{
+zudY=t6!^nphp{%kI9(Gq3i_S@?vv@*iX1TQLrh$ICUlJ-j8pQ=gJzu|{OlaSVW*A*
+za4>&^<Dd8w?mx4=Z at -@_&q!bi-+zkz%H%;$JXU?a0Dk6hcn%m2&bh_-i1o|<_}%qu
+zi36~AkD>n$hjbnvaI70kA^U1m-@|V`)5Z_o^4N~OzH%CSA8a;6oC+f>&+7v--rido
+z!?9%h>en+r;0(ojnZZwu^4MU|`pef<a{0Axxjn}j2P~DpX-?AzKYwPh4KP6aVh?`C
+z#y9UMdG~cn-g~2xqlcRLeE+^mz*}AzPUOYO{g`J~EIIK7&VS<P{e2d{`p$v!s#P~_
+z*Z9f9h|TB6Pc<*{lgAFt`k21dkKR7>eT;LjjGtKb-4EKkAIWE7OB+*{=VLc3dGg5o
+zTyX9rS3jEC*RpxeSRxmzZr1P3=jP`?-bZdw^7yUYxZr&+!8?c-UlC6Qhs at i@<b-Aa
+zgU1i6wUg_?!g1QC_anbHZc}o2r;<<Kwbwr{ttt8H!}^Tjz01nmS`NU at T*$o~z|+l%
+z^B-QU+&AhPIIeA6CYMe(VRqZe!L6H?-JIxy1Gxt7>(v~v_qcwTJC>}ttn~}_z=V5W
+zjeV^)a`4|V;M3Z5+T!WjkLOZ*4w<j7-us>PyT(#ouCOip?WeN6+WUfj at N;-%r8IA^
+z9ALkec`*Qo)awVw2aGH3tK<<|PHetVvX_oy++BRw>^itnpggqe%=0zP1!KQv4*Kp2
+z%=ATxua5)m#n_E4+h2Xq)ekBCQ21iU<>9-_^_~yS=iRc!p_CK8eW`ChB)rpmVx*|k
+z_dSb4IiC1FVB+#x=qK)}!_T&999cX*b~#JTWAo^9U*bEJi^nMs40fZ at UiJliY2P<`
+z%ZFDsn(%KK+^z<Xk}r797+>_l0cWdYZ at 0|5(UObZl-UL;-=BDQ;=Aa6=LK`1`K~uI
+zc&juxtV3MxlkWtc`$sfh&F2|0jjM3G_2`>=d4QY#b`jGjv_0M#tJbsXcko;pLoNrF
+z(Z8G<#y|8o<EyJ*XanA at oA(~Wjq$zg!`W0<%fs;DIYd6#OY~ms`&Pp}n%_wnFYR&9
+zjo<KV#l!H4uNgm`>~HWJjd_L;`qS8^4?V_uLGf?!R%y&PfMh-Jpshw#IAYXee)=Te
+zCoWr<H>&OHI2T-E_=WaJ`^4_@!rFs^59613+T==xe#9LmUtLTw%D}c-A*H)!jP;bt
+z7nMo{jx}-aALze?So{-u7yoN3fzAq at 78*({rsCg1|4og47^XFcv21i+lrx`RNJYwe
+zS5Ioupj)Hp$xOw1m{*srbu+9&99jc^&a%<qtN9!#cp80EDm4G2g+0!}UK~ezW|)pT
+Xhq<U>paaw}+)-+kEllhVFQWV(oC5s(
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/windows/default.ico b/im/branding/messenger/windows/default.ico
+new file mode 100644
+index 0000000000000000000000000000000000000000..51fed13f752340320417fa83145ad7896b2af839
+GIT binary patch
+literal 7262
+zcmds6O=}ZD7+z-&JvJ9buwq0J1<@dgC>A3MRs<=6f`SsMs92C7NH3Ny_<{IE6hRQw
+zf_m~2FP;P!FM1L36N0}W#~#%2c{VfYY%;Txq?>}KJb7nlciwrPci#EfCJ5Hxue3G5
+zcQKfn2!eG%5NroZz!boG*C+h(p#dxc(^AUdUxVT<VTqQy9!Lw?6o4`iDb!)(6h1xu
+zA|6)0i`wN_JiB^J+&w#)N376C1<?FW>(qkhi$E11&n95DvzI?TmEy*cH0Gv$i+ksO
+ziboe;i6=9=hS7t*$;IC1a=q44!?TS(p6~T%<8SJDeRBzZ7lHDiI?$%S7%uDS<>$NS
+z<Ns#P^cfGLL+Li#=U*O-zwV#;S at 4Yqo|y)8o8j!o$1;3zLyBj!QoO86asPZ8x6h<=
+z-^?AB)A2Vsw8$?@12qoC|LuYlGm}yro{(by+BPoj%jVh5TVK2RYb}vSL!)mE(K#uO
+zZC>WAxzi5IALA7w$2=SsT^i7?=4mU#&o897u-DF8YZ#Wl9*5`GWcck}mX4}T1Gq<-
+z{NK;F^WyZ*(ekH`x#LN!GWev{SUku4Z at Hcqh)HMf@$o;oO^Q=HkYB}Ku<iLhQp{q`
+z=y+$?@WUO~IB>o1tV<|YoZPvVn0@&8>pb$=qZ`{=Oy8Dr#+>NPXK=4u`P<g)y!dN<
+z<qg?$p1EY74=p_pz}=cVVtzUud&Vbk{#pm~$`b#i4mn_rZ+qV=TJO~#*!_))KXtg)
+zF83HLf_vG<KQ(8~xQvoN=Y-jpQ4SGL3(wfepZmYjzEd70e~y8zPu98jXM6nrSN_aV
+zJ?HYaT#NFG|C1TFFXn09-0AP^ZfBp4y{v)!FIwh><nzv0Tsa`c!S(rS;C}6jJ?g`+
+zuWj?U&OHG9n>`w^XYd^2^qHpyj_38VyD#KI55M;NN=5OHtoQYq%@r4(V;HxU<Pz62
+zmw#37h&?qWXCPR64nbq`9_8_$>^p<#VD9mZ*T*@|k at w`DdKbX8eGHgKzIQ*Zk2%0|
+z0At#H{yedzUGLgswGY$sUBLcc%kxfApMO*i6;RhZ57?d>veqNB&z#C3a at WC~^;MI*
+zE~CB#P at BCi=R?+<&VxJ7j2UNU@=Dem&AHp+e#OaOkA?X at lLu$|AaD2kijHRk+>$xl
+z&D*?I8r<Wcba0IOo*OQmTpRto$-gh|S_hsl0rvUOonPErc;3bttMh-KZobSro~byG
+zcoy^juR+J0HnrAhjy{Wa1-1oDU#nSW4ov%a`tHL=8HiU|M-BaXbKS??yuS)M7;o}U
+zt?ed<Jj(PBRDlMt(tILk=IDy^WEgGew*WA|BA^b$KohX(;yt1URDsekeVT0!;Q~j{
+zU`#g0Xrn(taEKN^n2jqNDjUGY{2^^Y*-grhciAy at 9V)w~?GHc1C4M^=t|I!wCrZBi
+xw1%IU?Qoq~^w;Dy`fn+_L<@euXu%iqATXem<V(hAjthwfW3)=YlyS&-`~^IDi|7CV
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/wizHeader.bmp b/im/branding/messenger/wizHeader.bmp
+new file mode 100644
+index 0000000000000000000000000000000000000000..7fbaa640c6e7d06647f2f665f415c516b30d2bf3
+GIT binary patch
+literal 25818
+zcmeI42|QHm`@oOns_YELo at J0FvV|7141>YgBO&{iC8?yOq;A at z&<%+wDWZkMEiDqa
+z<+lIocDt1}?LtL${?E)|90ot#-~E4nzdoPye%?8rdCoiI at q9h+{vHeZ-5`XOjNqyc
+zuWWdkz>5nZ!xcgH!u{I<*o&or3reIP+yex|9~>Z<PcS4H{`emFfBOqQeE4wh-o5kZ
+z&)3%0R#sM)mzS57mBF>Ty1JpEp{1qe@#DvzK7AVF at BjAgTSrINlPB%BZ$Iem{eu4#
+z5r=qh{1fuqw{L+Du-dwHtFN!GnVFfkwzh(Tg1ET2u&^+hOjcG_*3&mIok?Xdd}Cr(
+zBqe36S(CGQ^WL<y{3T1W!o%0ko43NzanWq^Fr8`hlqjxbX*-gntvHz`r|e46_7xPi
+zc=YHw-co`g-W&g!{QUWI2)Xs^*W1|G$jHd>^Yd$IY0aKJ+uq*Z)6+9xL7;C`vUSJ?
+z-N0Q6ffYjHR?1U-v}c7I+AW#wnQjxj-7$8L$MOoFwY7em8-sIxi`sKDzWmQ+$6ll~
+zyifVHgPjem7T>$~2yZFD5buq at D?_zeUthm^_39~8rU(iO>gnmZySvB4#KgwNM#Uz$
+z#_yQ3s9bOH>8Xp)u`^lGC9U%MuHU=2U+UW2+_~=ThgGKrK(UE&3Wm1Ju3!HHZz;hL
+z?~T7D- at 0`xCnsn6^yv_I5Oom|5z(v^5gqFko2{47pq+4*GfS#?q#eAx=hnwx0ON06
+zo0>b*aTt?oUU1UGG)4|9TU&48EhQM at z44tg^fS($JsTb#4)hER41$7!03f8Wh-jyU
+znbYFyv=*HiDT`CQ)5<RHyZZ^lnAMLFKqXY%w~xyU&ud;$_nMQWk<;pP=dR){B^ctp
+z at jY^HZ!ffd(AGgu#m&tvxG#m!BR1&99M_0DJ$e>V^<PtRw&KBOz*u;b8I6E(<Au&8
+z6?b%LO9jPg^4k8s8ON6%eKG{2vD^B(lP!2l35IxYj9LEr_3M!%N1)x4mX`MR_6}gB
+z`3pi#B8$~yejQ5|R1Zlhs5|=j^PxXKm9jAAUg=6cctvAogqlfIQq4=pg#CgNG{=NJ
+z at dxhUG0vR3`B2pvyrl#~yf?-yLk~tnLqknX&Bw=Q9xJ){E!2*zRE at 45V;0hkNZNk5
+z?pe<f7RJ4|I#UibDe3r{I<NZqe8<`|AAp<x)^mI!)+X+2BX_s1Y<P!}H22FYDQm!6
+zN-)HGV{G!JOP8ors+^phSAVkhOID4jQHiV at dlu4;Ub?mX^s8RLSb6_L%HDbzWfw+N
+zcJ9^gZLM7yO`T~hj4>s5#V5N_riX{*oLzD94Pdkk&duL*9B(PX5bupK$Zc(HVPRp=
+z1~M27Xa-%~Jf{0^QI0tAy;)c{c5z0 at g?C?SAH83ZUnL=HANg}d$-h4CzR?YpY9 at xU
+zkr|E4j=rE6N6BjV25hNIKJn5fq9AuyHQrK!A>JGRPKJ(XZf-90LLm;Fot>SW8M^*E
+z6vJxRSs|c8L^lSmYz-zr1&eiY05xbP2UYRQdBm+PY<&7=S=K%Y8N0QmXR054K6w9A
+z$(@e{{TMeuG_o*4MQZA?fh5oHURP}sS+F&$9B(PX5buqDCttsQT}MY}+O%nQ%w(_Q
+zvr#_y=s*rSBB<nJ;FKmnb|TX at PYyi}x8O>NI;k1oh-Jl~YKfW2;uIhCS+QYB+ZX?w
+zCnfK&`}ECIFMDgB_EbOoTz>!4UKYljD_vV#IsxMv7Dfn2r^Iq$vV*o|{JIUrcuNU}
+zcyEj<fBEtyEiDb2K?p)fI-Y5AK}Yae)F8pYIUSsxQ1Os5BbKBYDj!e*0I>*E4Lu??
+zYlY0z5RcSjFnvZ1%Tv*CQ=Z~hd#CNU&aaK_pKAW<D8Kcpu=Qzn<6j$V at 1|DVSXy#9
+zW><4a)|vSk4PI+%+*7Lc>8S`}ux9OUyrl#~yf;RbZ{EDAqM~ALZ9QksoT)BJG7GBk
+znPi<Iqq$&ZeP8bpNHUTtgyh^PAx9KE3dp(<N`?^&GS7k@%k)M21VydL3eGYrZenCx
+zlB6|R##&02DlJcyQJ~6BrphT&l~nCiHR$SEbTth-5t5#U7A<M{j`i#JT)1!zZz;hL
+z?~PIAl#~=rO-+~x)v}K!`&HmGiIFEH?Yy|+5gQQ*&=;BRk}fD_t!o*dQhp8QMWMHu
+zc=&#F at l}|KS&o}ci`)N)keI~`jx=l5EEg9S4-XIcr4|+ze0+Q`EyQUf!I0A@!)e~X
+ze{W)9LZ{Pb(dSG0mP^h*#Lf~vWqgv3!8xtKZFz0`lB!2ADvvI at LYW?-Z5&w8^Z+Jf
+zpr^9yT6bnkry)IwU&LC)Fx1#>jYE7vcz$zY)kCOSHO*pG)nLwbm;`gMG#U*igkbe5
+zF)@+TI)WjmPlnT6y?S-><jIaM9%PSQB%cHLEHEwJ&}ALavkJ*FVx+3gh>}!thsiRs
+ziWgaq{_BgLV{JXq;Vi!WG5z at 63H-C;if;sNZ>EOlYnUw(lXccGi?fd_ at LqR}BxPx2
+zWCR_ik&=><5)^>{rXdCr42L*mgtr+P8HR?26xVdox%=^1n7&g$(qZL^mrytIPMU2W
+zx7UBmS?JSXm8znS|GK^P4KI3OGUmV^pQ!WGDEfh$FLq+nFi-{t4Zaztv at DlEhjaW-
+zCTeQBu;e&Wf|((xPOn`X)EI)j1j7-a4N*f?rcaL$_ADKe1r>e5x7NYTO8TjGK4D7?
+z9d?b~|HnjO>&a>^=iYod`MjsF^^t&xMdX&69haGN+w2ho6o!UW-!7S7*xbZ~I(6z)
+z)sYi0+_r7o5ZefbLmV>PTiErYX)s&TyF|dP7 at sH2NY$DdRSJ_UH$P at Izv36M0ywY?
+z2v}hKT~xt+((H5rl2vKboind{ed4x=N!b?P>de2+Trh-zU+SrjxU%~O4k;oM)>Cz@
+zXf!)$_e at Pqq0$~HiHL~63fB-D35G))GThsD at 7_sLlY~4<_+0i3WT$)~DSFAJHf-&o
+z at b@=@VpiCK?#8ALWuu5m`iW3 at qME<&!i>7V+Qp at 5iCITrl>&zF(7#!J;FhlSVnLFX
+z>NIC#r*I>eSUuMz8ivklYBNYAMM+6HSP|h&z|hgrafpos!yyhC?rqE6mjG}Qqi}*#
+z0XzRh&E^%f3RseR`sHV+Dl6{26DC>jzsFqDwV0Q|ryh)z<h9%^PPUFu&r_W`x8X%k
+z+09pht4gFOo&quqUc)4kcNu<=NmgNK&j?r1^B0z|;o&u%z-P)YWGo=8&o8LW$FIi6
+zr#x|@JcTm7wzdgxCczNzjS=L;L+$*oML*H=*qO((iaYoQ_uNywl1|ztLG_Q{o@{$B
+zDnUKo))Sdg!7uOmlfy1n;d~y~0|MeUqT*Km at tOLTF@j`=iCU377MtKMuVcQLcbRm+
+zVJZJgEQ>2Rq#e2n!3_PL)u%fW4n2e(EX>d_mQ~ot7F!18ntE+8a9ANuw#8dYFvNRf
+zIQjAul#%-k{LO8*6U*Z~k8uUx92a<*+p&n-Hk(_{hoUp@)Z>>VvQ19SWdSKVw{7k?
+zx5{zz8pj1)gOWVDOD77L3rq<bXS$mGB_IGm_8=1z#H4L^w>*PU2uzk{T<C;$6*{gf
+z>)&FXB=%KW!5MEU!4U5a4*A<RbX7g-z2_Z-4VP^WGdq_d!8eeA-?$uh_i1dhd1Srx
+zW(5lfnTg6eaWRe{K{uFXuwq^(xa<qKY_j_bV_(9$0z(PkgZL~WNv(OpT)lwZ88EMt
+zQuEl{Z?jk0;pDnkY=9uhC^GPt5)AR);E?aMqv40qpz<DwL&PQ<vEPjZUPb&{5j)mf
+z&|uj*Yl5s7_ju!R4u_ZkeVY*XYQ(;<?=HL8U;(~Ud|o*|OUT$ZzUqZJfzsO_;&N-{
+z)V-7qLPezLjAbSGxj9)S7rdneL%cUQ<h)iU!_bPa(4j$Wa}mFb%uLH01jn%ynSTNC
+zzl2y9A)a*zeb1n~gSoM9O?2KZ;<XQgkj+rcrC>6}@nXl9eV6~VnY)4{Z6CI&1{%i5
+zf~%r3j<l$q%Z@$6qLHXeIY5o1`0yExu4XcX3`2Xw`xN5WjL>$mIUo*&$h<Sm!1HfG
+zTq+UUoddT<K!+6ofb1%i%}`{<GUGXct9KrdRdjR=NH4wdmfbMIbb*ATySe`+n2b%X
+zd#$4GiMN at EL%cTz%fH_50|*QyLr)<=*O}1RaNLhFH4CmFu7?quoB=(%z{mp3*0C9~
+zLy=#}RY+uxy3X8^b2rYu`2tJA?1pjuxetj|Pvo at xrZZB4b~IVp#p5j{7~;J#Sl)SY
+zfT7aLr-<i?eo#5c+<GQJ(9nMASN6A!1L$@jX6eX`WW*>Q(F;ek{Sb9`M8$zul{UpD
+zOx-q0jTS?p#i`gWR<>WNL{AozHxm^%Bg;~CjeT7M*Cb|EY^Z3-J>Qnq)V}fj+q6bl
+z6nUj)x=>2hD<XOm-co`g-W!AErL}zweGj18TY9<d`f>T3MiyK}9QO{TN8N$USb=E!
+zBMKIXC<Pfmq5rJ)pr3H`36>uq!6Z7&j=~iZZ1EUBetds99t05>&m%1?rYA0AMv|T*
+zA~{EpWG*0PCQ7D~WgT`G9>rTqFvNQUC%^wV5QOHxpe}n+sPvf7+^U8GwA_qn%tb_0
+z5bmG)A&mA at R#p}ODk>`S^76uxAPb=(tT%CSagFvd*1go!RGf`{BEgW;CoD}@Pang;
+zL#S~!Q#M(31#w`FE$ICbNX<eNZN`X>%?DVqaREtS2xm25uN=F;NCJH7;lqcV_7V&^
+zeZtaw{f0(VG0}PMLv0F}Lh!*}p81W4M@?T9YQ7E;lpo38W7G=>2#`pmNs}gxr9A8+
+z7}i*V;jnIDDK|7S(K!{NjJ- at DtP+)4 at oHe?PSO~Q<Nv8LJUl!P9y}P<Sc2iOZec0w
+z?lIAMl%mvprVwxtHQfG9(4AG0YWjdv*;OKdg31sMX~O~1e+t@=?}1}gBUwr?9LX~%
+z+Vd4%c at hmegig;!Lo3nX3REW(rDZ;3)}?}S(3HUjCOBx%Y~8rHU}X<_D$uflJjDI%
+zw@`EbJ;*{rLU7D~Bufc~BYB3U|LZLpe++dkL9JM!IBO^BS&G83P=urbT}s$YICJJq
+z7%Rxj%fmiGEWuF>HZ;5dJx|yuV{B{;K!(IHz8I&>&CPw{#EDVNBp8n39M-KT9cW5D
+z>Q;(c=cE1yQS)6;seaRNPlH8vj3HozgaHHrHp5_j6xfEQtE&seFf5={S67Ev6%!M~
+zA{Mrcj~h1*yE}2>L{55`29EiUZX>~PbpNpKLLc?wBQ*IW>Q;ifm!ghEs84B+l8FnT
+zz++^w?7Kjv3b$Z$3<MrT9h;A&q$KQX!s=o8_=E|}c>oyQLzF^1vx~6>`0UP|JKNja
+zM=_INIEr%y-};84m!6>8n$Yk{)UO=%De6!)vV|rQj}DW89+rS1BsglyW&#4l9uR{M
+z!Xyo*hdLHc!ofgsSd73tGc)tqvuA_N8F)u99Pq_=NU)@F?HPLb_b!^9y}rIa5F0`d
+zG#Eg*0vtR;U;<G}p-`|Ogj-PME?l^96pVm9DJiMDyL(s at 35LVEWz0%An4gf40Ov6J
+zBCr1k8zAiPhmgZFgs$n3K|Sn5ggwZ^Vw8}OSg>FL>_>$El#yywg5j8PjZ(0#t`6Wq
+zyy3$S!w3vvf)vkiSQ(yZ!-)|Z%&e at e?c2A<$HzmI!r{4LZ6Fv9>z40VLO>Q36+yH>
+z!UrKRggy4da>FZOc$t@%$HoXXE$kyLE-nToV1)LwwY7C5qX>p0dFF5FVMlmjVIdqf
+zgJA?TdH at g-bWLF}i6 at 4aVZJmZBm@Q!Q011ClmJGkJOLU!WHF(j!FKWQa7+ODG^3b9
+zFdW4>|G_Qje^gafg@%R#0SHS#3K*el0<$=xqN31#T3J~wUAnZnxf#y*W4{NY4j$IG
+zZ{I#xON5YyCold|w4dMom8QW#2=Y;EAsCM0oPYFIS6A25r%&POQloq;)SSQ^&Kbi4
+zi~uH_ISz<S)i6PmlfQO%_o3$eIKhz9C;wH=s#U8XN}&e>)hRr=7HoOnfi7SERZXp9
+z>(=*eZJ#-<BN%e}<iD+fXBZtldK8|gi8ti+>u>AVzq7EorK{Tz9et{!W8eYA1Vg-|
+fegwI@`%7KjLxSOtz-sI^5^*?oU;VF^M3Daj@(2r_
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/wizHeaderRTL.bmp b/im/branding/messenger/wizHeaderRTL.bmp
+new file mode 100644
+index 0000000000000000000000000000000000000000..2c882095562c025edf6b2db2de264f586fea16cf
+GIT binary patch
+literal 25818
+zcmeI42Uru!_P`hHA{|0+0#Ze)VxdY)Na!FPX;MW&6cm*!DxxSL(kv(-h=2$ppr{C9
+z at 6UeKzls%6FFvIxSoWQ;umpkJ<=y-L-g{p%-(i{To@{pJmosx_=1fd!j{=b1G!u@>
+z at RtRDv*C{e5rrdy6vFif+}L052{@qa^gmt$Y=-~i0O9f34A~6(YM`sD>&cTRmo8m8
+zdGcgMMMYUzSxHF=93c;9;QZ64PeF%Zef|9Tv!kQy&71cRA3pEw{6g?uEUWg{?69Mw
+z<L1qq04gIR!`Ih${`~oxnwoNQav~xke0+RxguJGv)?5P%Ds at 44_^R00%?SyaDJg}C
+ziTh$>Gs40)dwa**+C>|gglOq_D=0aOic^F|$wH!560-L4Y94|j<ff(@EDMKV!T()`
+zA3uJqudh!_OS7}H15jLCT+^maGcYh9lgZA`&c42WKH)2^f;Q{;@09aDBs|qlQqfU;
+zUa+oZ^gO5a7Jl1l5qVB4%iPx2`fNQDkaZ<&-<_z^r?J&<*Vg|t{`6;DjNP}MJb9U5
+zQCL=O^bEVZyU(9LpOTWIqoc#k&8?xK0T?49B9<;)8nJYlOVoC==n|didX44haFNvt
+z2v4oubGs|^dS}Yzj-+$#>ly|?;lze!jJ&oVJ=(;wa0nKBlnkFed$xc7erPkn at Mg`L
+z6&xJAxHp9_UgEekO?TOe>CtD0iiCDZSn`pA`(Jir7%z2fV!#-8{M|3+hr=}S%Pc89
+zMX)F=t2P>j*REZQi;IJfPF-CcdcV-#6cQTd7?G?SbxeI((?~+nSsId9a`5q23}XgZ
+zV=u<v8a~G!ePy$}ARw~=NaE=5jCs)RJ$bb(3x{CA2{UYJYV!8>hQ^ahr3UsV`;hh8
+z5ml;@jm$-8W=z1EeTScQ1IGOOUv}N<0*u=(b*w)6%+PBK4~a~Yb#h54Us2hN)59`W
+z;d$G$DhL*ZWz~o=Y-ngOGc)7o=kN7bzy^JNd;<(acPTG9O+<wBS9wQg)V%5ejKz=o
+zFs`qCq;DH1sp7f3;-!1y32s44^PtQnMR(%sKj9>)kwqJ~9b{QJ1Pe}p;l+y=O-xKA
+zB_&;5T|Ik~i%+mtXvwt2rwEGBoYk)3DJS3dRKM&7j0YZmNvgS{X|h;tUihYl4~b{n
+z0b1zZ+kB$b85S`?IcL|LY{M|xt|(i(v4CJvSXS-N7(ROR$ji%1P*4yo5Ew$Dcr8;7
+zJ*p6Pg189H`^_ad>CA_3fU&B%E4k{jl8%p&({I@~I(A&^+<LKNV-p=C7^IAbpQNhS
+z!qmFeb?@Pf<Lb(oHG5bV4#9#mW%%jSr*-SrVSS(zJvq<w*(e`!Tt2jJR3dD&-qA1N
+z;-~NREnUfnPRl4cxkhG#HRj#>vhyEZ=~o9Zt~t at BMOiB(W#^uBbXD!!1qrp0F<AtQ
+z!m?^i8J3rq^YZc<8ymw25YkNVEpoxfaFJb9&9Avc%A*)RgJqzB#atXPR5$}_Jj#ox
+zZmTbT=twH85tp at zPOCinqWjR(uYhsi-L9NojL8=|HuPE}n4e|nULIkx)7nz!_#>f9
+z(^wV`!Ge#>@cHxS=H}+g%F2}9q`M$qI<T5i1ZFH&pC8LBVNWt%FB?<?mt+>zD2AU@
+zi#mhJ)Zki@$p%4rcXhK^n%8d|c9)1sQqs!LHNO8=*V04B_~dI5hVf?S_N$$Y7(J3s
+z at sKFmlvTb#n+X<$Wz|MzxOeYf2?+ at p&RbYm=sK>D3OLFrLM9t!bwk02Tvhu{o0h<@
+z;3ef*0)~fKpmJE9nCS))RbSfj5@;S>*40QW*h$FHN-y2N-tpt?hwkIgKbJrFkbk`;
+zyQz8W at ki?`?yWj-V`=W?pp0`q$@Q)qjyuO!8F-{39D3gVi7X3;V8KUV`10jTeSLjX
+zQ&aFrwQ1oJew7k_M{pt8<nT#4#2#(Iyhk{CZ*Alex0m-Rlk+$rrWYxt;qSij7(Pny
+z+;W;nz)VESMpD5^Si)M6WG*UUE+%O%E^R3xV<9PPAth%ar$|;(qbaL{Sd&C&%E%c;
+zMW<{^%B!opNU$g at t2P2dm{60Ek#To-*R)(H=2I@}a~KzrYay2i4Tb_ZK*+4F`(Wyy
+z%`0RvO)oGu??UDcx|_1P=5=_%jb(=(gLi@}uR8XgN6<`Pf6m;&Y2Lhfwzjq|E-v5z
+zTUl96o;(>=uUHn#s0uzD!=9cV at IhfvZ(-{$>Ty8CyPQ#`NV_`3RrYdwA5--*s_bDz
+z;Vn(87->bvtdsXDn(4#8+&f(`Xs`%Ko5XD*r{zD>KAs%0D=?=i`tXyrr#>2arOL_A
+zh3VFz306J;ppA`<l#~>FgT8(HHmcIFrt)wM!JAQ4RkgEskaS8H at +f5#?m6+YIw3Gc
+zO<ufH-zh=GAVN&h6{c83<ri at Cn;vWabnJCc`O~k3zkf+T*TOGK_S;s!Xy<iGM1h8R
+ztdNwwqJF4FNS0rEBcJg6*|TSBjhs|eRA5Q#)vH&miDgu!9*$vERTVH)w_hdTc92o{
+z9rGp$SS~Mp3=H{1DA0I%B{xKtJi*#Y9m?vEwR=y$`&RR^yX?tV&y~4?;?^mb+p%dF
+zOvgXtk}ho>uLx!06hnChU6?y(k|s=;P*+zss?xBg@^B1cJwn^em4CqjzQMw+8e|i`
+z3mVDf^Pl-dDba_Y<GtL<>Q+7pJ05<M#<yLkTECV3-X^JF?--GteUm=7jSu`le`QUp
+zvCsC&+(x>3WLSZOmE(~TOwUF}MzSWBQI&cKLx^RWZ%Gw*%j0(1&nT14wvl8V3LkXB
+z<Vw!Xb^$TUy5p}loo$EpBQQ%Do#4rOD|w}D6Z4LrZTr3=y=?r%xjQem?7d50_XYnZ
+zq49Ifk=KTvDf}dJwdv-TmayPYHZn4j9XXLmBuh)nQI&=@m4`6=`t|EHY7D<?F_%L=
+zgXD2bIHXlwgLaZWY5ky6NSu<|)IwhgyxgJhv}v+RFep#di`6$>bnab;s*aaOWM;*)
+zZWzMD^8NbSW&@W*a7X1e>}Jsx&9q;l;~1kp*G*a3Kv-CwM3NF0mk=M4goTB5b#=kP
+zVofr{OFe|)i}xME?gzjEC))1CWxVyC2?Ewu?(0sy>4c`T`uP`<r1hSw?+PA#@s2O!
+zl6IYFlS@~o?wZ6kcXR#`K at p4NFWM^}e~#F8WUA)EDI&Cq+R*|F3h at ypWJt=cN;-Z@
+zGyMg`DdQ&0o-lb17w>FtK5cGZjVatJTwL;8T(TsRN=ZrGj~_pX7l;KlhcL`&>V$4^
+zf=%vt+8#{CIUO1kc$?Gb@^~pXNkyls`>)Qt?-r4=F1`0*W9j87qBi5nS$&!g#k{hP
+z0>WnY3lj`&V|hfZxm1J48EuBEa6`DQxNoJ{!U{};6`Uf|kAan at UFq0xrhP@_tHA85
+zFhk=IR{_h0u!29&Em at Zq&nIZ!-rmWAWQZ4eFvI4LXh2yvSkxHGPE0tRDmVh~at7QU
+zV|QQ-C5KZXP)LGW-`pxDZN0bQ9-kO>jA<IDV>zeCX- at xta0K4tn3DoMA+Pd6&ROwe
+z$T|3Z03Zx9VWI#ZY6{8OZLYjt^gDg&0{k8<N(x^&#JweDE#J1bPs9tvf|`RFre6St
+zJ<zjpSY^}2W<L^e8v!^rg?(qNvN`4bWt5$TL at Y?scAQoPNWdK=@Gf2aZg9Ar;-D3A
+zm}lV1cm^1fybdvnfE2ap#%mZ%LXb_?jm{1At(1t}Hqm);$69fKkWtkQXl?z21<4RE
+zG6TbR9cbtgH0baTsBgqF3!&^r7G6XAZX(ot`b!2GuK;^*bjO+OL;~(2K9>=f8icx^
+zQDJC)to1Ho&oV~g7qMu3*IoO%=itN6)x{T-W(7(pxeH3#S%hY<tbT)IRM!uF_39n*
+z0<oYb1H+1YXh<bppr#SaY{c^%;(G(3<_!WuEkHcaBL24#(_F;;G-6XY=qdwe#`Dk_
+zf}_g_P}rlCPtf>k`;W>8Z=6E6 at QYY^tSU;q^f{*d8BF;YdM3vld4XY6((--#mTia3
+zzMB0EzyCm29P48UYfOmCv0i}t22fA{T0Onx^u2~SRUzcv1D8fXhbe$VgEyf#MnP)2
+zv^+Jv?6`vZ0z;b>`>wUX^c>bPuB>j6nc=5ry9Op#0V4$MGkbpawSj$4w_5rDf*mR?
+zyNCqdLF`HfC^?kVZO{J};#`A}a|X^crH85Ux)k9IA%kJ$(G23^Hjq)U%dR?q{^NI8
+z5{8Zu!WN-p+;YAhRzXw at mZ}*?E-t*SpyJBr#JmRj?eOs30fyRJ+7QpC0Z`7>^nMRo
+zPB29#&`gq$xoePF(TH{^qOlNBaX}Pl9CBvL7K at av!j#AnisVQI%5r(@*s0VwAq7i8
+zk`YPVOkKx~=D9j5`QWC~3t3IiGcL5IoNr4!^9kmDbZryFr at 5I}L at +M_`)WVKZD;!!
+z`j?|Kwxbgqd)*o!=2A;<KkcE19OTx}Um7MLGXfAfOGHow89$|eU-6*-5EKpzOfzTB
+z)YH?OK7BeIA;C21q)C(d^~NH|lrdvPc?4z%i5mz at m<ouR at CqAq3mWqZ&li`Xt&GcN
+zQ(|5N{S2dO`WRa6L#_6r5LH2^1kEV`v at 0C|Xr7K}_#r~7$XFagKaAo2!+aS4goPwn
+zgy7-f!5G2}+PHD!hEpGO4#LWrKRf#>Rs;PEqig95gDOzn4Em9};{`(AMITrU0L(;`
+z9FcL82h}ry7o41&n3kBB7{*XQK!CvekjBPFHYFl8(9baL1f8Kz8EUw*&mgDxHX!Z|
+zeHLhzMsG0xT7vcy%o3tiiQESEq7r$0whq)lKf~OsbaXC7D0yEWL#0ih5Ziv&RN9b8
+z#s7^uXU?2q^C4IR{S2?a?z2OqU40C}vk~__LbpS`rDMmA!<$3^HF4s^sZ*yy0RP_z
+zjqz3x*Glm5*=kS&{S1HpM7K7fAxBXCEEHT*ut}|S)PB!LnD9izbYX1|LKWrZ<;RQ}
+z1C<T!p|-X*1jLLT3tr{$30h9*_c%B>hQB=WS#WnAKYq-HL%at18Nxf>cc824Q1=oP
+zOfk3uwa7(n3edR;w-9MVa48{@5W)wgrKKTo80bL&8YKADgkfPol#H618ej(n;LK>l
+z!|F4h%*n|i{`hQ7r~w9s at T#o~O*(_R6{DuRQNME3co*tfg6fAA3J3^d3;`n~3?Li<
+z6y~D<SQs$?VT{K3@#7T~6o4VN77y+y1gYUh3r#U2G{(G-j}IHmXlr0FL+stRThPQt
+z)Tsz{E<$PfsC)6x8MaZ-crs$dU}8r=1eQ6cH%*x`FxUqp1Y8g)iVgE&ybrjbb)7L|
+z2JB{JM2F?UT$7TL*zt&e2Se;0_gm4N%V=otfWxb}TZ<e3^D9F!!Wk at K4B=-oet`q+
+zDlmliVtpxuk3%FknCP$=K_@;wzPY)1wB=xB{o(BJm-^`HLGQJq)%U;oEeZidKnyd#
+zet7i%7(h6JK{ED!(5ONjFhr~3!$L62sHi9=7{O3sulR=#AAWfZ_REoKfB-|rx2C73
+zD=8^4(qjaOF=U)agKZPw4>4LM{3uFta`Lbkfir9sU$SHg^s6skykPuXcAiNMjFKVT
+z>B^NW5cUbyg^|Q95CaI~#y=fTz-Err)YM-v!bZn!+qPw9W^UZL5gOjkPIep=6KsPn
+zjh-R)_S)K7i139OF`OZ^qL6?sV_V8-fp{Ja6 at DZP#|Y~g at O3CCD9Fvt1%_}#__4l0
+z56OPPv<CiNhHz5|`#gO3Fsv at XvII8d2ZrFRK#zyx`XvMHD(q&0-wA_3Nq&AlU<?lr
+zS5#Dlt#XO^)w7rVpSQPPSXda-CuU##wFdqIL;O~-!wi1l5`M3ZMx%kd10D=Ev<H9y
+z4H`+<iweEm>C>n2y=X8U3bc!hi{ZFq$BsjX4&@gXiTb_}o_74pm#_Gp*%=}=@OLmA
+z`Z*Br|K`mbI1asppMgD1uuB{^%v4ubL*ogZB-O#&!2Y|x|Btq|pST)3^QSfN|HJT4
+zKNeFcEiJ`{i_nW^XVcf~d%mHmsXwPp>sY(?pN}3f`w9^J2v$)0k1~V`e)#YqbgF;+
+zF(~@5v-4+0#%BuUv6@;#KtTP=m+UxiX5YpCG(%?324>mwqp9ijn>U}CtFidi|89mX
+S4u at dz*$fF*)PJ!Wg8U1LdkXge
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/wizWatermark.bmp b/im/branding/messenger/wizWatermark.bmp
+new file mode 100644
+index 0000000000000000000000000000000000000000..03352038cfaf2532ee6cc997680807a3abcd5d5b
+GIT binary patch
+literal 154542
+zcmeI51$-387soFi0)YS_1W5?4#UnUD10+F$dvOWw?(P~ONP at d-+;A=4mbMfqRA`G+
+zpymJn-OXh(*`3|nlY~HSKTDXM+q<24-yM7N=1skT{hcgT>cb2FO5xvD{Ht!EQdy{6
+z5mKqf;`2L>D$PGlgu*{|c6LRJ7WMV@?bfZ^i1a!Jj~w4=)Uw8-c2*r7TVeF+bU5==
+z9jQ`P6`a29W^TIqX5-B_8*aQ=fBjA9^*8IjQJ-tCy;*bhb;#A%tFOFXb>;QS%db~n
+zdcES(>*W_;FT419>4jHI&c9lW^W3XN=Uy#5`)a|NSM$%jns at r;T%1WS=On(Io%nKA
+z!poTnFK5KRoDuh8dfba?u`i~^zL*k|R;LthYisL5g$mWGRjX5{PQ!)`8=g+bh+ZRR
+zwip>&Yt)enqmt5rFZ&4Bnv(>eaapCo at J+Ygs&U^)Tijrs*0=?%ot&J!y}jGEZ98Ph
+z5Fk#sqxbM>fg?A1kB(%8pU&X|4d#kjm#Ew$46J#$QMARS8%5jT(w)}032S?M`|{<>
+zw{PD*-Qbc3^&2*^<%qS_N1aG#tlY=B`!5r-cJ*i(e*3Lb+^ESft66JtUwB0;bJXPG
+z%6yKfGEY<7Xo&s&{Ra;ooSu{i4j<Qg#42?~oh}Wr!lx8zvtG<PYj)qwx8G9SXt)KH
+zxw>exZMQt`v#Hx|ux4?i;f{Z)uF2D;?H-zrNAS>5?S?O{J92-8QHkY8C1td;Sm$kG
+z)`$ta at zOBd%Sl%)b?HVwEmc=79dV}%>S0}n&#gaVSH)2Y8I3QSo|3%|a#=5rf4Jq&
+z+Z5cIZn?tJtsFPH<=UP(Q at YVDpK7{pd782wICONY;j6tzo at 7OuVZ&vEPjOk#I&cH5
+z#kesFV+UfSGRG)PI}l5*%rg#d^taRE=rMF!;}Kgcj*QQ+WW@>lYGk5H<tfHJc4NZU
+zyK2^Qxapw#+8Z_QE1GdP#jP21FQb(??Wd7(_vx4Fakr*2Pt($kUYQAx;K9S%4qaSh
+z#9_$ob3Co=YKmD8TzGifw{HpV&7#U&U9^ds#dNr55j9Kd%G`Jzi>W~O9z3qu at C}tm
+zMt_coX_{?wG!nD!GA?}kw{H!=4V9W&tCqTSV-%(xh{=|2sMOS2HHzC5DmCL-cOE*s
+z?ub3*M}3wBnNlW!EO}dsSvT*yY{z&1sBz!byL2nZ4Grr2)Rj5Wpqdc(Aj6Nr?T5^*
+z{@GU70?OnvTcM6(*1m0~g0&bo2Ho0mH&vM5P%F$sQ&;902e$#Jg9i<6H*|r|h+|xF
+zeb$jVO7;@7u2OHv&hOQ%`M7Usv}zQ$W_~0EH|>^_%ABgy$ovSIB4H}?G%el1`Wyp;
+z2L}ya<T?C!xe*Cp<e96&U@`0B6}s;F{vU#SyQnfJMO&>zH63nr%h{fJ%5)gfsu|jL
+zD?~jYcu313ORJ7J`9&h8nablmM$Fp9EnxS(e+<B_eD+g40ZL1E^6aM;H`TEiJ^MLO
+z*U at j_;K0GlD-VyL0{Maiu63r1S=%|(+H>!pw8otdlif0?K{;T^%1R at mzF@e5tQBay
+zK+GC3+ipD<;?|79*q%9^9}!gM%1gI$+=fku at mU842Mu0WW%wz9D8Beh_rO(L)**@a
+z_x$jW4&1a`o>3>e2Z)XigJyUQJ^aOE<z~<$D3r^3-odMTfBXlyQIn^t%mt;}M7Yyv
+zvYSQSb>R3~!*+9pkVztov=8I5p0FWy-;e*u;D!cOt3+jRb0 at n~nX)9S)cCdyCY}8p
+zvFE$~nxn^n5%q?Imm3~mHglgvC8n^4E;+par+22p&9!adPKPZr5$++|Z}wOo(Yya3
+zzri724Ufs>lu7oBb>G7+*ZpVjKJe2!Ep9a2n#z0^8HiCGOY;1PcseY7CcD*UsG`a4
+z$<fb(!!H9g&Wgh#%#^7FO7!NNEA*Va<-q-S#^C-Wliiad|LVW~ECG$bG at IrCBv7jV
+zac;TpJSy}cSl?F{ZG%g93hvYjbKzw7CAEcl%4GNXWTQmZ$Xvl>_rz0w^jVuoK_gIR
+zSe*H!5-2q&g3G$?pcRLHekX$)8q}Sl%A7mdtu<wl$E}ZT19!4}+_5LUL*iJ_X4aH)
+zav+w=x_Pe!habE%6>hF=19v(srF2sbD$kTffP3tb2fbEB3qXIp^i*;l&81r_0SoJD
+zV%&b6XC8U*?(om4aHCtU?wQlBTJrpecsfjAmndb*!o|(CZQxFa5!;3_2Y=|bGP382
+zh#ojKT{8Uby6|YhGM&t<1ro5buPtU>FKFVChwqHRoj#M at BX{5Gy)qJKuayxLcgI=#
+zo!wg?Q-YkDFKrwfh*{TYI`Sx3KYWLp+~Cr!#+_!9-Ln&4jM#Cl&#K7YI2qinC+~1{
+zZcK7idT6ZqWF=smvx%5>mAb*l9=(^r4V9X>GUrZqn;bW$KIbGp8 at A;_zmUkjt0P(5
+zfg?BAXRAZA!)DVQh6L<gnp5G>KsldY#~-~n6>b<dh;19V(_w16M1d*GdCh8H+EqLA
+zYEJxLLpCM#4~fLtZ*>apMtzrC+otM!nE47MkR^X>ikJq9SLl4=m-i{SQIl)B<=UP(
+z9dwh at EtnrsY|6sLEx)pRcFb>sH^dKE6Gd24+%?<Jw6GM~x|bRfV?J34WOeUA5z~Ns
+ziPm7P5I1M`^Sggwax9+gR#>{FaL<bTW$^l#;I&Z$*F>?nEBkSr1|TnNHqBv3AX|}c
+z6fq6tb at M;@Si at Rb>E_ at zdiGOLna?=+)8NqPLF=M|aVF#LyYgg7pFT9%f`FN?Kmyr$
+zrld~JjZQszFN6Ca(W)_(d74gkPdobUkkF{X>!P%*HMsjMJ?2)LQz=p6f}EN!oyrcN
+z!l8jIS!+i;d4KA0YTOUsse9(hZMSmV#!PlEzxZnMf$KxpM}akq`|J4!oZSLwg2e&*
+ztaZ$A1ro?vVTf2z7M5O-zrGjXMz{P}+T&&?yH{L%F>%l3VH=``;$(1lp1#8|cSCWq
+zX-rn91_L)-739=>nY-#JDk3&;{J|?lxHZ#Z3THnRnz9hwD=z#!e#hAn8>5DAjAC)O
+z8MEF#Yb`dZf^d#JO@?o~4Gn6^!O`ZEm4LI)c!8|Q<$-ViRI^r6y7j at WW2vvk#TLw#
+zmY;h%Zd>BWO;KRY;`Z;q)XK((n_v=|yI}J%d%q`3ec5c9!;nCpnp3!<+j;eusNX(F
+z;YP!qs_i!6WcT$q%TE6~c1!%IuxPMmao6oI&B8)Bh-MS-TBOay!#~rN-DbW53FNIi
+zlNA>YZ$9@^^lu-uxSw#^ZsoZ3n(SVh at NjH+%;@mw(P7bA+$h=`BCGlhr)lE`+{$#B
+zcJc|k_EV5k^QCLU`CQR$KJ!D&?;lv)7=^JtbD}|2Sh^MBUKo9E?B?jP;n8EjIvMw{
+z&{L(ndvX&=Ba2q<H7oj$1*s>yOALxKpR5G(`7NOmV*^{x{TTcE2RYn~!d&6(XNoBc
+zH91c9+knL*^H1Iyw<UTUSTneXgdB4#)s{_|I9#U2p!o at ZY2B%vRr|&yrJK#BISdKp
+z_g^lS9%8nf|1tItHEYx2<}UROyZL&~(W?`-#*7DR2KRs^`<)B=bCX9SD>WRo=*+WJ
+zivg2yoB0YPP#|C>l^Yw_cHyVEryrznL#3wGsxhV8u*vSQ8!u)aI6rY~3{Dnz&sp0X
+zbJb^)Bo0?=F?H$rmr|xI#e*ZwCo6#hfvd$bM9lV!KgB=&5ch`(aLY_~Z at Tu^jD2S&
+zZHvLl;_f(Zot*>6Zx5T)dYu-ea)l~d$j at fe9EJo6v{=ImkcM|$`YGYh4=nCzQCCfQ
+z>E`0zc=eCzyA!5tkD0t(&6?mw(QYwtv6ZzqO$j&9tlw&#lig;%0tpms#b3S$)`@?9
+z;N$-Fy;h}`JU^mv_ET-jl04ZRdhzk}UGY<Q#!lT4!{TnxVX8`Y5RD;rn^EDgOVsJc
+zT#!@qrCSik11*ZuuFLlm|N7VDxXJA2+A}{*-x)g%pf%?d4em+XqP-dq<(6U^X=&-z
+zZQ5RiUhB<p1rl&;vyn=Y4eY*hKMAb=`WHo8T)LrSi88cwuZp`nV^=KB6x=&vCTxx<
+z?e#UA0CCvL+NbY=W6+?cTKg%zNr51z=1cc>{AIa&ul{`c?|=2heVk|8KxaSq{qS~q
+z<To?-#Ln2QW=(OAS%2KUWE(MDHpbSj#*o#qWKRk%?i4rX$$L^18yI0eSqZqe4`)S6
+z!~4E at aOUrSS={KSrRu6_G^pazEromEz1K at mUY@-tcGjL)7WeR#`<?SQrO)LCvSh0>
+zHtei+xlr=_NUGA!TiMNK(;S8b+&f}R9N`Wxh}n1j!P#g3D#49 at nzpM(2i?D at ZBW_C
+z?mgc<Uv%u;oV~Gg_QbNd2h7{*n6n-?0W>n3Q at ts>uW=Xhvy<J_Hzr-kZ{{nIK%q`M
+zs8rd&fg2CcKL6JwxcA)obK&8nx%*=0;AC)jpSad8OAYp+;&4tEzu8CbsErbDy;Y8z
+zEaWdb;FS4fCE(t9r&z*>Ie7EoIk0~I?-^d{hDwd9S?K%-w{-8k at nqq_`1$)|=k1SG
+z;|6OD?l!>-t*mqmqVp6CSQPPtcy*YdGUt|V;AXRF4nqQky6)z(K6LBh`4|7{i(6pZ
+zu<hyt0vfDY+>JU+<UW**EKs!diUjoz1!BJqU at gWi_F8Y|E0BOk_r0uyY54H1M;BiF
+ztHq6?{Y>3Y({|P9D2$YD(fkN8RNH*v-lBtX3lGLEI1ooz<L{ikG2V at W=~JWvh0Aqb
+zd+t~2*IEv@^vZ5QPR*AdU+?D%{K)NJF24Lv32w}f2xdP|J$|?0^sU8*;uhg#aL?Ki
+zQO2_?_i=1wsj59UUHMbH)Hm5H3wI$ucV##A+hB$(kU-&{e3vQ5?mh-<18|@E<!xx(
+z)g_1H7UQJ255!FkKjvPd70Z+xu2d&@^NnW;Z5z}zId78!va(x{Q}bov-bc7HKmP6G
+zORqGnd8Ipvs9BiGoRscUk6x{fy148}{L;g5Ebj4Z_BrSC<35Outlw_h&hK8c-t)u@
+z`ME2*)mwk2uFQeENdJ at Ola)Z>-bYz!)9{J!o?L$YpI*36{QNBB)Y;`n<H4H6J#^ug
+zY&m at CFLMK!(damGokG72oR!@?uk~y;&0$EOaNlEG;h+5e$(7gtU4E4s_j66pJh`g|
+z4XRp+swv&ae)wbciKG?B;=!85-FtF~t$lUwBWR?xO|@Z5k5KP<;+5U}(#>1yn^L;3
+zn#;AgT022y&IV51`}OLZ{{*<vEk7^9jroy7cOR`jk+AYuJWdvO`$6+8MN4Jbryz`7
+z9cS%2M}004XNh9m+=cwymE9C~#xKjzYr(n|mO==mPindI#SuTKSu4T4 at A{7bz500k
+zs^e<b6t`c8aRRL3OP2!vtD?V6anr#p24p9@(N$9yZ9P|Z7w&f=W1hf at 1xN6C%Wfco
+zOAt@%1Y1~fR#HU$`0KT|8rHnh4IK;4Gk<^Bb@@)n$%GKFW^gY*9P87tznH8brdavT
+zTdq8zivh(8`8i8{^;y}S)^bz+`=rd0`!O7V7eSUX4W|Qc3u{h$8vWC6- at N@#2KSl2
+z-fcg3eeKDFHDH~L8%2BZzKAkaItj3fFTLsy+5g>ht(%VIwV#S`D_+^HoJAVliE;|(
+zOSJqVAVrzt#tmtd81l20Hk=8FnESt9|L0>0?$@c>?$b}-Y)QJj?o<L!7Wdrk$K8u@
+z_WTmCZq{|yu?PQ1&3>xeZl*Hllx}6X(^P0We;f at lr3{n^D?H)k1oeQ<-`Dqsf*rPI
+zE5Tn<5&Phe8~=P1;KnEnJ at cgBUv7>+9~zOc4kuVA<DR-<pR+4xBR>{2##TKiY%tYA
+ze(uU{^_~<Og}J`cFzx+PMOYzmavOdGH3J%V)cgh~&#lw;Y$bbhdu0So99X~mD8?QC
+z<gc)p(;K1^)<-6=xW_Enk~KTWEglQn#<u$SHOIx%VQMElg2jM}{WfrMli5#?zQ@!5
+zM7^ySO@%j;x?SJw6zsIav2<SxOC9rx2 at jv%eE$)+QM764j(PCwrs%|tQ3+tp;vO(%
+zm5p60e^V at C5{6B}(nA-?Vn8u&fo+4j;r?0e=vYvhbN8f>!mY1ljK3eHPa!)4ZbQYc
+zJcVwZcR7|Bpp!B|llbWAt at j^qqG%`Mj=1-8Saias=mfCV;*M08?vBB8EG)dlaM_rA
+z?g5+6rdkZB2)A)7y9>16qFgv8xs$Zf25?mJ6@@8Omt|1qjjdQBY&hwcr?)?RB)G5t
+z^WU-C--pL0hQ}nZxYtL<H)%J9{T4S|s#2E&cYhPxHV7uW(N&XL`<YU at spne-n-n0w
+zPE|*__c~mt&$0A5(~dRtEjqJMpu at IorF7TWVn#`ipWgZK5xB3v{cz~o&CLK!&Sc!7
+zCu4o;OZuClKUmXmSj3~3YNJG+DT{L4T(9-q=`cFkP10cF)WkJ#H99tENp*@#;SKmT
+z2p=70{6*DDzlE at p5~}Y#=$@fa)2E07sKK(8?4z>OQM;-I!dqu?=E<LT{{494&AS7a
+zuWpS?+!C9};tn|yQKqt-zbPW;&O?_cJbj<Cpg^-2P%zmI!v<p8KwWG}m2Ty@$z(Tu
+z-;lvvUSrA)j{_qJ3UV`sJHC#d63Yvg=T!bgA;x}cOqle;+1H6ahy?Pt+nlvTFD}89
+z>}zaCt!=COw4R$KJI9jq+;4whd-;0L`3qa)6V)e!d)eNjZbbqGKP9-d&r);7rc+!~
+z7O`!Enl-zSpIQ4!wQ5vhF5Z)ZTe^W;kfdzx9g6fg;NJTvPRJ1bC=%B9FJ2gYU2xK0
+zLqPD6F_+{m;-)ZPn at w4Z^-x0D%DP(Bz!}5${5U1%1($Wqy$8F`oZFs|xGh1;n&6%j
+zwl|jx#|<?r*!+b8x1PDHwn5ccE=f&xr}fHiHc2FGowZ(G|5XqjN*@q_8dr?+kzCgJ
+zHBd&8C%<eAU-Dfv{rEL*O7aD5aDcZ-UTrMMGJKa+YBFi)j_*O4oLtr$jz{iHNZOH*
+z#NwW~EZiZRoWChN%geWa<o!PdhH6~g+=cwywVw+8Heh~)o&6MKTzhHZ>Et=4c(8hx
+zA2hgJVd{(oR(u!DsA)?vp^Udhin42~^$s3gR4O?KK_r`?T)yGBL7VST%39Wr97BT8
+zW2bf|Cb75&O<iFl>u(BA=`?8Z`DY(45K|V>>?fV<X4j91OE(uccOgG_sV~LNXRT?x
+z9Nar#4<pDHohzMWWo|H4DJGQh7w-=mV(}AQTdvDeNcSuQvWyzLa<eIew|y(1OfKzt
+ztT!Bw*qM|>ad!@$DerFzR{b+K9%pSEq$aylx at u{>kl#|){@li~e&P1v5HHH6TdyMq
+zoMdVPbWC`nfe at r5Z(xYMo9=EfD5Lk~)newbo%gtu<yr3n>m*d;iA~$`oi@{g<Lc(W
+z{md;Tlig%7pcuDyAwOL%B)zg*a<ZFj4w$^-3?{n=Y`pGKu at _CGIDm>SZ|!Lyg>od2
+zu+Gc00F7FLeXdKuYWo81#K{)N*x1*s)^`4gz4v7(YguQjEB^Y%6A at s&H8!qVJvnjV
+zi=MUn#yxy0GyBOkWibXfG^k2uKS}PI4c%gG$C=2ZS#~Vi4aT&rkhx(}wc;bZ80a{e
+zuq at M`qBV?5vz7Mwbu3&Z>9=#JU90obQ3oFCq)cwG%bK!B29*F<Z#)@Ux}uKvs?)%Q
+z*Is|13UhVQmbPt3>6uHf>{hQBQc${;;HKF}0e2}P=QztId&9iV*K!e)NLq?XmyFUe
+zZ2%Q`o~Fy~T!SbDnLrjtU*E4+jye38W>ZOk%X&fh?t&i8WS(VbUw!t5!(@I$JRO$G
+zP%U}=h<e44Xmyyvh5X#fZu!#9=6%A+r)bM$vV&;?r)m=m_B<>;f!nl9*<Zt3go>h2
+z at 1yzs7TY@O&{~l6XU*BLVc*bk$9`ios4$FrKr95u9Gt>VZ*wi!bobetT7|i0I!uh4
+zOm=Inj+1e7*M1s<n=a(1W~kI_y*T?FW}R|yl2Z<3DcrR{_x*qi1gNN?%0O9z+KQ!P
+zsxYbu{Br)TdvbV<v&yE!yBCps_B>7eg2N`9_(PmEg)z1cI)=;?F$q+u+3WP<Kkxqg
+zktod7^CL#%<}T#NT$p$|O!;ItH~S;@{8Xe$UqO!8OMBN=#rqyL6;PSqDc<vd<5z<$
+zY&ZsBY<fu8DWAXp at a+>L{^Vv#d8A&fJNBP@``w3c|NGxvoFd%pWVg0k&KjA^mTu*^
+z6;5_bN+9}q!+z^A4i$@(#9+ at dfRMqY??))Y?CH at yJbMX6>P at 64cfl4d#_X9C`L|?t
+zl67KAZm`Xws9f9FR+}Aq;NJiK_x;EJefRNyYTW;Rq`0rY{rBq2cbA^MJ^$zHGrzw~
+zeDZhPqd%kW{}J)SZ^yrTa^&`-LpL7mzjlAm<sWul_<q}&Z#O61*%)_oL-dVxk=H^_
+zTv>Va(z3(n7w<p2a8J^_oe8tI#m?LuGi_7U<n^Z}tUWPq_0cgakBnS;aM<GgL+0-d
+zp1W(nteyR)Z|gl}OOJ_R-N$e0I%a*Rk?T4PThn&%sy4wZTlHVoqR$ffy!Tmi31XDO
+zZJpJ(NT;p(GSzYa(3pb$E4Z6vag&j+M90>X4q^9p`HblGsY2GacGYv`Y3P)zo at 0)>
+zSsiO<aj1zHIGuwZDsECgd8AGuj6eQ66p2#lgvq6Q%Qb9yG&o#x;HkWIXV~P>VT?yo
+z0-aTHpWtqb6LhBEfEzFpm&)&F9j{On^?R?8nn!@LC4Zv at 1|!B7i}yN&T{f)j6xEzo
+zHq|OOofI5)W2!#YvchbV+iYZ24WBP=<w9sP<%o>FB~SH<2H-B-achoJeH2=JVX$1M
+z^Ww1wf1VNla(dj0X|dXADdkyEc&C{)1l4Qxg>1Pb>)4!M1(zNYql|crTk};8ZtWG8
+zk(~Mb1BZr9i~0k5l#m_03GS(BgIng6R+!+7d7Hvlo!&Nd=RFzqTDBrx(d<HHEp_5k
+z*Lt(L`wnyE<5s#;=NU)lCB1-W`?=WsH|ZtCtuESeFVX at x=0~`R`P?HZMCE~TM}I5k
+z#o3&Wh$4$?Q1L!T#H@?;KJ4r@)+&pf_K6A;U9Yk=1`P~JT73SMb}xf7udvZG-I4~S
+zo7Ute$DJ`*TUb=Jw5)1nRn^AE)7IA0&d$@`-ZM)UPX`CjtXVxB9lf$=_s)^S+sVm0
+zXHM^2xx91d_Rf>X$Hm1bZ(bi)SD$?Oe3T<*@0=X<%u`yMYU|`zwEJEy?!nP+E!Q{}
+z at 1d|!hMcQ4pFCmr?PbYcG#6|3dd4;-*tbH9J5gP_XR^3W-cO5ujyz((J}KfaC}$>~
+zdJ09{c$~+7hu(GU(O<_Nc>*>2m_xseKJ*J_RYvW9FmnITBlrCbH53e)hVTAy*sdQi
+za|&~pA=|$nvh6#}l at Ho-2X+ydcW}(j at t)!0;$5|BEl<x{US74ly=(dS)T&;+c8waf
+zYu2n?t5$8394tY7!%YT-qZ3XGBO9=GsO#1u#JSpd%$Tt8GGT}8zJ5KI&W(IXe4fMi
+z8jE`&wxnTjYin`_x4w!0g!c!G;J8Lanf39hSt~6MBeUFbPNYK3gA8To{Qm97Y+io$
+zPdMCz2R60a^UJSOZD+vL<fL at 74L2%t+Hj9Pcz<BnrC~d7k3RJC#8ZZ=#Ele-{MS)k
+z<jl{R!6{hKCoNIel24VAPkXLBXV075mw`(^Dp|GHz@;Zczj;M{BNMmh#Kk>znu^Uz
+z*oIrCpVoI>Qjg^k^z5}NrvHX>L$=)*x&Mdp$A6s?{ai_o(&3&KV>ur4tgJjywA1b|
+zK3|v#ZP0ry{FYOKIs>-$HR`sWHuJy@?Z)mJuUsr{x}yQX4c6*Sh>}ZpO2eJpEhqi7
+zaYr8ZSdjvn5>E-Nh{Ve<X!F(Kd%hie<k6(azl_hmVZVURKyEkAx@<Q$pBia)7?xCg
+z3#sk0Ahx341nz9F6mIAI%{q+Qu;%>l>V+qF-ojZEaAU=&z?~+o$;oE!Y{QLiIooj0
+z!H7G#pEfA$LQi?tOpzxqK<|+FftxN4-FbV=p$C(rOfz+&P^3W<IZpG?&Gtz%+6oiK
+z-qt(hqEFBq8KnvrbQ!N+BUYW-e&-ELSgBu4;xd=GN7my0Mzf;<({KZ~l78BhQ@{0I
+z8QE)PgpQ&u!p)ZYe(TSGJBqw%CsSDI(J&t2QkY{y<?ilXJ#7y9Xq|!J&A01xTal|^
+zb1q7$NL1Gi+D%(@{3fxE*afpjjRPMRx3(rvF5T-0?yIj!>0X(-pGIr)1<6|nl78Co
+z9p8X;m$?VpOxe+6`Kc6wGH|6o>bWv%z{c~#cHJ3w^l{p?@@=Pb{N`C(SM~O;mKL;i
+zBF2ER at xV>_OLml^DHWfmK(lV+Hg3K4hhV{x)?X7`d}ub2q%}Ep^}sgV at S7^=r!7g{
+zPa`AlnX!NN3yJQtDzaQ%^{(_#XuA|{RjTH|>TPHE4_n`5!4YH7_goo`dLB*u_!EX$
+zG|5Rg`nhW{j-uGz-K$y}9C9g%c>(Q#0e$SRs`VMaF5=KnZ;9zLyaA-(#xmi1|FF2(
+zh8wsA4L7>w{C=87!Gb|I>8Fj^d#m5-$ev4&^9O(yp4sy>_Ndssa?`O5dM|4`b(g{D
+zd##QQ4!=BN at Anf<{w^;%g`dLWOI%o>8T0b;G5H}#60(3^%7{JC^IS(IhOSG6h9ks@
+z;l|k6*J#pl`s%3Lbdflg9ce8a8QiQV)$P<n@@-K+P2)P19dUE|X&MC!wB-XsWBZ3h
+z*6lopn=o-CUJ2J?ZOYUcT(jexz)_pJFFk1heFz6qLgOxwp}v>-OLEq#6e{H9ZR!I9
+z&!IbRLI2QqZ6X>eah5yHIjD1v58n2APujHq?o%u#)vg*&UPg*#N30<$796n+x3Hg<
+zyp4raKaHzknRMjdfHhHIou`m~eF^#wAcF-<cdQyXAz;J?1Gx7NiBm&A`is7l$^9K?
+zN6?hefQ?O6Pfru$7Q+?CeAPg53-yXM`b^&x8TI5HHCaz_-=uNobL8PW7B}&(NpWkJ
+zl_i&MG6YjM+{u->WIye~E2>}_x+!tsnyA)e`TJ^7=_w4@*i|oBrlV)z#DEbSzh0_e
+zAJ0JO(a&=g;Jl at U3ZW)9<sl|3j_El2fVC~h$gps!HpCYM*(n&fwHB?(rJFbeV3&ud
+zG~AliMr^|k?>&Nk8r+`i=%<~3H6!9d at VcnrwNYhi=yn3B5I4O|!@ZMd^GSgt_2Ulc
+zP}V6g>FE8^hthzpZPltM+@?FkWW_P4#*0+pdw83 at HJV*dN<27G7Z7a2jeZ*O+LVG@
+z&wg5pf+cwrhN3-c+qpsOqWUa5%6%KD+>8&{*w=6?+u5 at PxNlNk-U)Q|z)f~04zp%l
+zBR3BZQ^FRI?Y`thtMOaw_gY#tV0>}!J{Y;!$r{ENFW)g`kplJz{`~`sTfJRuvNIoX
+zKaJMpv~;6rQ%5eT^l7|)8Wb$^<9{0x8Z~%bRPFZDxHMghwR0)lT52+m`xPaTkV!GG
+zK9EwkMaKjJl)6Mm4kcX%dX)f9791Q<v`uz28?vr?yP0KuhZHQ+$<ev7g)Z;bVo}W5
+z8bff?nw;X+tDlBNqe2A>t3DO!)6h?wu;=QK^-;i`D<6MT!r+b9X2!pqbn1_u%aa-p
+z*jTRKXtgd#fwKj1Hn}mVOgt)dtJ8Hs=Xr;vC=22N9n)|VBc2LMdjAdIa34{ojLBGY
+ze_yZ25*0d;^`vm(l!E)$_i*3D_S23&d}mBQEmgy<8FVi>`{%F?QA5{9wH_79O>o{K
+zZMX(YurcVmFb<ZnrE3q*kymax9`|RtkyyrFpmax+nhrDf3E=WCS43j$Gv;urrK5!^
+za2m=ydDPW7cvms{;HF&P$hq5Mfm^SBS}FyL{{1v4Sf(AhIecRjaF_JrhzMC|(tjPD
+z=9V#7f=NlIxlwhyuPjk*kiJTOv7lf*mA6QcSBpt)rtIWXPOX^jvnBzW*h!joNfIhk
+z&sMEkw{6?Db?esk>({Sr#34?t0Wl>}v^5(;8{AJ*D_9tPnzrFio(L1`(^g%2J~Aw3
+z#Kx$8OAlhHg*eTS`M3i=sO{7AG+2VkQ1j8d%QqbB=*+Pc5<f^LCRYJ}XzE&y-K-nB
+zrkIa9a32c~#Xsof)dZ}`QMYbggK3L@*|3;-JK|W}Y6mY&KTX?kEAFSU4L1hef{8E;
+zy62qyZsevYu&x=z-<_~%<z94}+hBtwn1}ff+g8?h6jt~eCKmE7XlN at n8Pj&^Zk^CE
+zz7s#l*|}z$<RdUJu#%yN_?N{oSbGjV9$t0d9;=!T*<#5vODI{fGjaXF?WeH~H at qba
+z8g7ij1o|}je%jiruf}an7!?*hVq;`>XFi3t<9Dei!ZhZHv?fPCjWt*j^p4~&VH4P7
+z at aEFBhG9v9SVW3qEIjiSZ(F;|ysir+d+!}*?dN*1@$+i|+Nj1`wrp9^&_j?&JP3>R
+z&~jC8J0B)+-Ipf8Hc}vjD*jUi-y)aucf?UAPQreg#t|RwmJ9l6+7UOSKBaD&NM$b2
+zr!9)TKRP^mbXauIu$A1Dz!-H_)Ng8YM9sXXi4Du6pZ8sN1-*JmNiRDMnp6zcOH}KR
+z2{>*sFY3wh$5OIneSpT%v}w}{h8~zMM;!%66K$s*8yI#|$+A|oXxyS*s$yrdmuSj}
+z`;QOATbE#kxImwls-Kp+;l{kDU?L1I?kDd)I|i)7ql;DSLIubMD%2Z6r at 3iOPD{5;
+zKTYsf>%4?HF|^qg{U#b#*mJn}K?&b}#$FaWbn<LoNZ8)qJ19ua8pgwhqOPDbJKP&8
+zHJvO at 4`LSVj00}A;f7;Xw&6bY_`N{EBG#wzC&H5ZX)De=9=ADqY<P6Pg?rHf<0hl$
+zf|F|dG at fBOHCQ4m!c4UQ5M=}wS<r`Mb>g=v+;oyi=ro|*sMljL6j=nivpZ)UbhT<t
+zgMxz4F)MHA!9}Sv5|-`UW~Fqc&S%KZl1#T;;D}GqPh)3BNM)X)Pt&+q6!g<(9=tSe
+zOEhp-ZKO6!5TCF!Uwr17)*SKNE52d5rr`!|ldl<pWl{GfiEul^HTV~&mW{E?TDwf`
+z!Ocg9)$Tl(jVEDO*IIsleui>Ze@`b?sT(RZ8ZS-{VixX-7wihnDp*jN%lFd+6JctD
+zCCw%^q~Q*|{B*+BnDJYphpjyd>n3gjY6i_%eo?!QfY#&!gC*?(z%*MCrWRWC^BybC
+zR%<iQ0Cf%Oc5&9Q#;0uAN?#dqNTJjjkN$}`J&37Pv$xipu4ZRRfr16Dx`@N%RQ<H%
+z?Wo`<Ib~*qr(l_X;`+p`F~D7~J--n_0)}rqM-9ul21~TzMz>sBlc&vkPb$OSA(v{j
+zUuZz}E|75EycNqCanSS_5GYi>hafTJGA#ZU#VzQkQB^q_Zs2BTMsyl1g<XF(d3)@n
+zZ877+Be5|G_tCiv1gMt?F%x05;id*ld<9Dy<A!+Ak%OHuR}sq1i#XEOwn|we4g(O=
+zue6(fT$~=nG;TA2x at gm@pC)gxv at GWC<n1wF-MrsI?sE|tIB*SFA|$pnUX*%8nA)&B
+zA=Lsvny<7D4A^wTtK}@N$2_Tg(RdG!@&?m3CSO<%V9#^s2&LuWJCA`|+i>gbrztR4
+z+J5Kt^xX+lcEkX;Yaz~JC`iNBzUHF%U+FYA*I<b%SWvp@%m^8UnY^DSFIz16ga#vD
+z at eY)ul0fd<o=uuG2?z*i(4YZKO;MwlQGCd!NB&dp$_0|(E<=~8_Y$SJHCsXp6)gJn
+z(?XJdoVqi1>W-MM6V^$|q)ywJYp=Z_E5cB^X-&S2F<6pPu*^u)ewwVI0=!jV`HVtm
+z4%kw;Y16<K$p>abN-I9(Y07*GcUUsXbIjoz_xJ at IFtWG>{WRqUOS|vAopa#yG_c+o
+zTf8F2>Js!}kTC1$cPaL1V#9J~MHotVx~<%oks<pLmU2TEC*xs^zTsbe)u1_ZV69&%
+zWe58><zXmJxic~}JqQe+zfJ2~HMw-_)lXv$mNs5|G-Frn^j)#R3wKHBPb&EiU4K2r
+zK8 at Doq;v~bgz4y~$reN9QZnF9c=6IXFwdU78iTrdvu4edp)O at WdeEPAE8C65$_*Fr
+zXnywDd+JITJ6sstPg{8O{EXePz+Kr_(s#$$@Uzs?7^PcaST4UJ>=X9WsQgir%lieT
+zLbkQ_YTVc#6JBVwaX>>}LfJu|r96P0Q0Q~z19P`V(LGHB{j?MXi^lpim4fBbdrXc{
+zecI+Lk7w_Row+A=Oz077iTyPSm+LH;_f$9B%mP69ei}RCPXB&dzx7v3Rv#=cN%E<U
+zjaSK%zD=7305mzk8cjAjX|OHU30yg1awlB)DoGW&r at VKM3(4+P*@hdHxqLs3od{cc
+z;^Le=v9tEX`nHyIpEzLAF?Io<*kDPoep=djSQ1DZ%OPO`r^NmZ%kYaAuj}X6OjDHk
+ze}KEV>>+r%{3Xn^q--)R>^MHRL3~r}H^8l~$qnkKZNKsB+<mcg_Qp=z7UAH?e*|1`
+zgx!3dGViJ9%KcB$PlL}KRF6`^WJ?qLs1zwur*UIB%7i^Cb9BjNXv at Q8KOMaFuGGw(
+zjavu%Dr49b(r|;8V=lh at kJjXv84*r|Y34np^l2+jU782h`(j)4nN5FF5a={ETrlq`
+zSO6&BPZO-%$Dlh+JuG3}D_ls)IB=%9!|=+(qjrM^P5ea%`eWP!D|w4bA1qCoFnpTj
+z at n}tx!3M0HnmD!!!)am5aoK8V<#p`NV{A~x;$|&auwAT_!P4&Azt7(vi*xp#nB1<M
+z=>R0d!Lja!D}S<v<${J=-+r3FV9A6EmeB_vRd2UIW}r%?ifIma_uBRAb0`z+T+oQD
+zSFfHl>Y_4yQ$C7*F4cKJ)t#+bNcJ{caoU#bM^noN`cDc)(WVWzSf3`<Pg@;zWr2ou
+zyCITFQU9KcI0j4N6=BK!w3LQB*?$`Km1jbOr4-R=hHvnPR;TN7B`)YOqAXCLX5G4t
+zrD)2>W74yT^dU$U_Y#}nu<TO8mR?zX=Mm8O3+UW#hFj5=DVtn~8g5QMO=GaM at 9rOq
+z4#q7!5I1jMOr8Q9>q;cU%F26H!UK7OB|$$;e&xQ5hb69LbVgzUI~)f|wS6g))J(*?
+zy4I*u$4{Q7{HJ96B}H3jYFke}EJzZ)L>o;(lYmV at zWarZQCBE#g$kCnF;^EIiUaPB
+z!<Wz}3Ies7k7q57xduyu1%OIc?wiCDCR`n2%%ac$)y1Voty;pe3~&Y<(2f_DIOJLP
+zU3*z- at wH8nuN_-&5u6Ub^8`4^Wy|g}=x&2-!!7KmB^xXq`u^#X!*Pobp<Ku2b>lD1
+zKu=(K)c1UYCGpDr>u-qqG^L+*N$oCApidL@(*y=f^0K0zf-)vGvb*q?9SP*)?2P_Y
+zL*+~{@gaW{D^|=y;-D!M2jE~cheU#{oSQqg3KxJTmzLQ%PN%bGuXFb48{k$q+&cSd
+zzkOJr at XgZ0alqYm^fG~P=p|h4z=%cOU`fzVlUK07KFvsjB{(L9m8Qb7oHJ)NZ|?^3
+z;1qs}W||z08#gW_eZb>7x2p+7sQXu6Q^B$UONV;d0 at iUsBhs!MUj;OK({b!aMr(3X
+zx&;arOpc(RcJ#-;mK}*-2G)mS^Ly~8FKukAhn{&TFjx|-+=oLgR>1;odCJU)W<^*^
+zKaDpLhRKms`ZU>zu;B1pFf3Hk$A%<x<nZzItgn!x!rKUIUteEo)P=MLv?41zY$MC^
+zO$l51IMiR9EoigUnYHO^?taA88VtmyMc9ul1-Gc5Mkd0-lCCd58V}q(#_`R+k(j`q
+z^K}|530Cf7(4DHECY}i6d03*jr7VpxTLD9HZl^RwXvsE^j*i|{s-&WvTp~^Lf1NsY
+z+@%lJ%|7wq3Nu<Pa1f`H#MpaJlA=uGt at 3b8Ua`B)se8Yww;E({i~DIOfBt*rvG^6o
+z;(@zh5sqgGB*Q*y?JZY+g%OKhhUEeUi`K)EVFpVvFW_ss)%XLhiY*PYW%I6B(N`f+
+zRK*4#SkdVwaX at t-Fwf||B%W&z3?bW=>Q8~n1neYqXoF{LWVZ<xG~A at 0w&m;%u*TVU
+za){LX)?w%>@yh+Z8e2rQue|TIo4K<J79}h9Q}xrN4VK0qecZ6`I^`?-&@NZ5>}xPP
+z`o%_y4;ZTy<Q;T;L5L6E at ts3<zS*92zP8zd!etQCkFo}as(9OKdz1*$?i8%qdrr_#
+z1M8?q&sU#FSan>@x=;y at YgW+Dp0oa*JAbniVF!LvTc66W2n#pJ!;-*YX~fR&ss+vA
+zyHHE6rP=q>#ihEpcYO-W_<%y%nE67hEvC&bfth;hcdSomQ%l3>T{{G>&)O<n;b~of
+zZ$`B>;TwuOrQz00j-a2m{ld+V6A7!2#}AmkmOfe#=rt*f>>w#v04U#2OPLwb$HNje
+zSn9v#T)Dc#l}uG2wa{=DC;(@{^%bI_w>8v#G^*dYSsmX-@;Aa14eNmNiw<pe&b*qF
+z_`IagK!IS%rG-t+ERB{aq)cwJuf|{B*S7bZZ{GfQO|vUB+i+w1 at 0iEW)|^ZT!FeK~
+za4G(l$Iyx&{_!PN2?<t&>Dy0}SFpf7jkvI0aOOpqSw{;gFw7u=!pvi#LN)8uX-M&L
+z0*xCt at bj<Nq-EV^?P at jaTr;po_2zxOTLgQy8eS!6Or<sxE3}<nuHBq6?H88rw7f*8
+zkYZgn6zR6vqx%l`9{b#Ssdp%b;|^<UPweiIFCS()YL+iw*T<(`{rV~V!5V{h5$gQV
+z1`~yF^&pAekS#pzYRqtG8K&Rad?R-%#L>z3@{4!CO*axHr5i)A?dPtqJ(&R9gJ-Yj
+zzH*2hGJiMMu$(nm(l*@8%6+juP0&wEQLtzX%h7Ppi~FO+u&`YD{H0PNh=;96v0}A+
+z>ou(3q<NiY9jXWP at M<0mb`{!8E!%#6sm`m4b=|1pwO_oQw7xN1-vUUFy}ehiTt04Y
+zHA<GORk332ym{U7r9Q|D+;VuhAo29l_N$@#QBHm<tc&o6=j%_N$L_JTCMWu|m|y-{
+z7m={;R041pDa|j``8}GSeDsz$)DkQJ6d0DLC|ET8G{K56`F`4%tygQdo{6qLm4JM}
+zDod?wWx6{xnU_6qRkl`P`M*9$c7E5Fpz`~nFqBUc{nWyuij7T0d;7B4vXyjlDvEcw
+z&yq-~?LMvDyBG!<-?Fd6S%8LQbRE1HtiMT(d;8g|p^*u|Jzy$^=bROJh#VhsluUEW
+z7%VC2r>PYzA`eT86Mt_%Zkt;vem8 at gBul3zcAgWmwhVJ>w>@{qT{v^J-Ik~G9_7>w
+zyHm=#lAB02a_si&QVYf{b2iHoxIRmZO$MJ9Svk9tdlYYV<K0I!ZcW3D$~@-b?;D~L
+z)`Rt_xcr6q)n<{>?V^9xdcriVhow=Q&ieRIkW%}zvZ7(jJT2_1PlH&XCqzLu44Hx7
+z>T!rBL*IZ?UjB5Ug?$}+zm*14CSSBJ)t{T5<9B{$ac at 6+X=79ZaQ7Ish<iUG7wk@?
+z)7<ig<?;#^47!OvZF$1uHpADu7UGZW_{p&Fw94PkuI_x2JJeli3c5g#L*g at kw|)Gy
+zNmPcqZ?^KWt2 at s~(D=H2L;l3~*hSlKzWYdU$3A$nDLMhH*PV#TotHCjg4EV(Izp{J
+z{X?xS7p&YDF94M9r)|FVdgR)eDh-BV?pwDUr~oa!tv$NhH(1KbBv*%>2A0j9>h848
+zQw$n0`Md1aBiS_lQUME3Tkpwiri=+&=Hk at J)f)`F_5LGpU;pR7?WZq<#UucChyMJ5
+z05%ZcbL}BrM<8XeL`Pw)3u|^FY(?DtRs&b%a^=@!QUbKFscv1okG<b2u at Lfh-KUcm
+zxq(Z~u*iI!c1k7HfOzY2gYBDdG}UQSp5u?&#<tp}zh41&%>75<v57d>9F25zs>@An
+zk1=bg%N;Ti#yV<9)lcJjSlapR%VEopm#^7h-!2VWG3zpe?3=COiUJk5VX%z+mTUWM
+zTqzA-6We#ek-&Z{t2P>yzgQb3TY_2@?#|7c!I5 at NR;zgXFs|GibK{>6J5Qh6tYO`v
+z+XQYF^0^1Z{`wl~Q;J(?ST6Rkl)Q3(dBoj-o(rH;<^Hl{q=lzt-XL4=N%nyoWO5BV
+z93!boeI0!OnKN%2{^)pF{3Ehqih7~bH*Z3&yqa<N+x|-<TMS<B9Wb#_xvqjyq at _zM
+z`3%bBUFIW8SB?Q{o1QacfBboCT;i6v#8n4Q*k|E8#F)D^TD_E8*@`ftPuq3-&%yKe
+zma5!clBPuCr7p-N``I;GCX*NP5$bc7E_<b586Pjh+9hZsH(#rgo~Xx?sWrevM?_b&
+z(JxwLZ*13eja}ddlb_ZVI6H>8<ZH4s>Gan4MBr{5#Hr_zFrWGZl^86MZu#LKUW^Ml
+z;nR2+%ou2<6a~};xwVbgWV?X%3iFO}v<!|k{m7*yU#YnE!XHHEPqtJbGxcPZliHjT
+zdz at W-O{4+SU)zSu6y{Xl+iV-~d*gF9?A(@+xODd+?kX)r?!EG(VBS+~Sbpl!o9UZl
+zd|QmQm-Tbbg>I3hu64=&24tKJtJ9RJ)Q{(B&Yu<9aP==Nh!Ef=tI>(02^iO at g<$1l
+zTYIj)1ogU~t5j**Yx4Gl#9Ds*F?hG3OT`mmwBe5X{oR5+NliLT$(F;H%TX>81=%&o
+z#(R?Tf-KG~I^j|{(lp-LpRZR8yYZZ=4%mj9#SP;b8_$X2yqGY?w&hmKVjQ5w%eI~$
+zzK1(e=<Mp3^xI3pL>N|to&Nj7>f at JM_MGD+;f7QWF=iV{L2k6%_}rn%&e#1wnquYt
+zxO3AL+&pf(`$jv(lWb*2=66`@S*tRGYy;Mt{%js*)8>G6=UA(rS1kM9wrI3PoI+48
+zU7?*g9x*UP6ikGL$KUKYXo*XHMTWS--&7am*4EyWZT&+{m{ZK&a&ee260eis%<adq
+zmWL#XBRFD;BdE#gDkl@>-8Nu at P0()ZjuBR0U$E?R3y4$BuP>=Al+MmnuF;E5gzdTX
+zeb3RW+=}R<$z;0O7Fm3)O7*vCxXh&4Oeq?Ab<zaX47<$Lkh9#$+NK(euZS6~05_Sb
+zCpEc^f2gr%i*45Jk6Cp)ZQ1*VWuMzpr^<z2gau{L%F1is#cz+_eh at r$eX+8Nz9RSq
+z^<{EFwrRG`*xV({2h~2t)EILKeh?E|hEX%@TRH2`7v~py&0tLgF|;ESxJ2hKXt)I_
+zS9%#3X5HqXRp&U%p4X({3gRs)&k!e49OLTNtX$Qu;&_EI77i%L15l8aW+WM<{QYR1
+zUAyf^<&5b|!JUXPjGAHJ%IV9QDaK+|Oxcs=PU at A6$=e|bM%;pw>$q&W&8ovmOHxHk
+z7hwTq?Pb6Lg}e;8&C=U4UmLW at HvT3n$W#=l{{fnyK>#L{^dkhEJMA`%n#{NG6sa>u
+zt?6R<WY5_^ZCVL;++ at q?)cY9H5jUG`sjzj+9abG9EPGt$LsSU8*A0~oXMwgj<$A<e
+zcv|FXX;pEgjo&J%#2X)v(X at aI_@bpImI;E7#FtXk42yU493z%bPM5}N)5>J4X{m<W
+zy4gDZ=^tv{YL`{VD9fH#)g3KUoEGjJkN4t~>y829+<}%~4YO{zf}eP)Oc at l<w#bG7
+zGU2zfmK!9Nk8{4JtUGS0hFd5r|4^%-J(itfEPJ6LHVtC>I~LVB;{|cbWnwIxnpu_^
+zY~5g~Fxdt{RPrNa9L<(i6M{3~r?M37A(oF@@z%sbgBZz6HQZKB*Q!r7;=PugV=a4K
+zx9EK<t<KgF;&dvBfv(=N)Br2rh1%4TG^fj7RMZ9#!B?PION-OCKwGiI%6j*rE1qN;
+zZp+sDEj!0s^tzE&d{e(UDu)K*q)NqDI5xH{-q)(m{Pagmp9tfV48__y7iTqk^(G_K
+zTWQ>X2h&QKhC6)_)2FD450N6PjkoZ!aBhx@`jeDmikJq_4NJR1YCyrabl~X!{W{H{
+z3*2NHZb~7Y0=}Vq);2XP^0&9FG{&mYN-F1!5WqY&Dc1&YNrSKK<*Fas4O*f0{`cTr
+zs+wFh;!Y>Tv?lL#CKYRkdKMntExe~#`h{3FS(DLDyliQ}OLset7mRy4x8+PLK%RZ3
+zZYJh-#Ia{eKTR{@rbDpwX5IUiDrbNyXETeE{VZ$E&1i51=|M;Rld#4^xvX;q at +YrH
+zEk8_l(@?Kxly11wk9GG87VRS}Tkf)Kk`arrfHJ)_32QDm10tPx6CWtov$iLw7d>fw
+z_R2Kes@^x#@a%EbqGPN@(0+?%8!Y at nKF1S^6aj7n7 at 6uT*?9_5uwHrcx^|O026swL
+zp4 at Po9yEq;T~1rHJ!%oS<#U89NHbPxnTnLo-@$t&e`c%7QILZ5){76Yq>*fcCDU-5
+zinT at eixwRsEL!ZcXtGWquFv`s(^xtgneYaA)(&NZK~{Vo`SCg3<W8pHR`t4R_}Sx{
+zs#BaQXuqoI236zLU*w5dEn`s1v(xue`=Xp>&aj)s;s~r at B}*D*8g4^CcRR0YdrTFu
+zMb$Xui{#5 at 3d1fC0d9S{q{aQV1vthV&iR_CH>myXgLY3tvO6uW;a1AJ_YGCov#K_S
+zRn0cBqR0$kTC~#wpI*Od&08E-{Hu;yzucPLG-MiXU94}Yx+JNB4yu}cv9+|$*A at K@
+zXvIlQt`{1U-^^8z)(IFzm$|XN2*eFHpLNgcs?PDMR{K;<LUoEFGu(jTb_T$`o4Ycu
+z(~#w45i41rF4J(QVvW95$5>U%Ju1JonSr2Qc?51U{xW%KRrrIsBv$u~TfRS0vx}vA
+zRikXft!CZhs;Wbjs>M!~-x|HLpV at Byw77HBn<pM^A!gOFi)0ZiaYsNFER!{Ef)TeW
+zaC>IxPMhkrgoYf&@RM}Qr4%WL?>xbdIlwKb$;BgXQwbsS{0<DoKS at 8$zBtEP&pu1d
+zv(G-zEmQ=!1tadv!^ng=#iD at pFWNSFIg4M4m2J;@VwZ2YO(=mc^`~HUjIxZ87tJ79
+zYoE at zE$un(_38zVB+Hh`R(J9ZH%-4eAdmnwX2b%V*4S9ANA4lzn#L>aNE>sTl$Aoa
+zVaqO&{jlJ8KehJ>Is~H)w;+S&OCkZ3T+#<4K<VF{?RU`b8I3dsqQdVwHD1Q;gil<#
+zU%QJ6*~n4?x4Pke{N4;#AORF-0Hqwo0r5Make4yHIaZs at WgU9*BHcwrrs0P7iLkSG
+z1v$;+muQ#8D8;zNF~)FI@?D3re0Sdw_nu&(I&n%M)o|~>^LW+CGuRg?lfz}RkM*`<
+zh{|J>AT#(L+k)-I<=Wn%rrM{g#zD6lx2WNc{N+Vh(l=!D6zrA5W;Qd2Y1djgT)~|N
+zb5!z0E60Xn))jodhM!Nh$7cB6r`u|18t&77y+3gCr!}XN$c7pOcV^~G^KLw7!d(e9
+zL+<Igle;HW=ir4JKc8xk&BWyh at g@}Y at M(C$MY72P**|5)(bzWqX4Cv;+5kpUf)Z-*
+zr6C-3*_h!sbNYvf3pHZqhaXRN>#D_l{@FkKuiYV@*w>y?Z?b?5HO8;p;ZaiKe*X)#
+z9a8w}Qac2L`3k<67Pzz5=6mHmdHeqD4<CV>cx;Zk|I6n1GivYLkqM!iO%_%hifY(;
+zRLVXAnV7W+OEgQ|<hZj|<oI=T%u)C5zaQ`X`w_S={{3>_rE75E8>aEj4cu_NKV;V0
+z+<8;C@|l%2JY%qcOc*vfYx~08#C3S}`u)HA_`h54|Bbr$<F@#uEgBcT;TrGUOLiag
+ztkYBc6 at _)(7j_$FqCv!jd<8#cTHMw-I4<=2ja_-^>7V=0Uxe?+Z5p?(zzt9A-G<H0
+zl2yW2Nv15<@|rOLI0G(C$XZGhK6&|;T}eqh6O(o%Bmp<P_|Dn5yI5I{OXrjVp7~gt
+zYJ?^K4wwpej(Qx2X27?4|530exWgl313Qg{Yq%7wyd?u)SmmrFJL$G;$0WGz%5c_t
+zIOXyspz(M7qEMIojdf5~Rn3AO$1+*DrdB2LrP3synuN7wZq9}&Rcdqt<#mTo)M(I0
+zCuQ8wFlg-2yH7G3Yijyy5}G=H#7Nw^JM2_hdW&hc={c$Q=mlA`)e?Ush{4{(A;-=W
+zRe7djjrmHQbWD4Lk*w|OaXig}W_F2va9Gfo85uHT<HcwHP*r)RVx2y{GQrzo3~tM^
+zx?Bly`(Uc74O)zfy!V)FZb((-nTj=QJ0u{Ic9#aTMsuTbX~7m%CE-HFT817weMh4^
+zB{L&*(lb-Bh6Ag#V=D8 at hT(>;US(TN314y#_CgvuJ at nSwci;Z^Kd4VxRXM?(d04{`
+zR0c<yeq<PHn at 0TY9=P=D1q_S(@t1r5`yWo|PJx at K%5Q3BM#vm@=3$-w9W(a*(HA$W
+zAXP=a#|#1Mf`tRu9Zn#W$=~laxbFftQ<GzkJM*xHnKvu^bPnsw8ooO$3bqko<z5!_
+z2=Hq?2DSIvL-BDxJ=Ws>_`mNoH93nr^RP}&EeiKV(hE1bkyhC_#{XR0Y-G0Vb*j|p
+z*=fMs86o?2CSAYs>=kXezZ}+$R;ubRR$+^T+A~x&C#$NBRe6n2RUM?N)K68uhpJp>
+zN3UMRn~heV{$q+Y8&k}GT(N-h#R4W2Ri6`!22L&-IHgG7)FREN6=^=bu=<=)xW&xE
+zEoXbQnC;PWu1BkRg<8%l)M~zas|D_ at 7P<#5at~VU7PQ1IXsKK4Wd&QWD9~<gzV at 5)
+zcHHLDg+GI)7wc>-H(6MCvJedm<44?!wrJ2|<bX*TW}P+qA$8}ds*O`s309T=T2;1_
+zs&rdbiI%FO%~XXOs@&_U3RYL;tEzITpmHvw%2`a6y^tzfK2?_7D!c3|YkQT2l}gu<
+zH*a1qqYqCdhnH6s?;4e>*Q;2wN%`8%%hhR9wqEDb4SSYs)W5jj(4tL87xtg%(R_w`
+z%lQR^mKJCmlCS-SydAf?bl%Or3{H&}8wOYITj`?@$2N<#r>ne2sY_Yej;dk-YJ9F$
+zRJn?)vbw5lvZ_=Tx>y<edH($Qy}iASq^$(C%so|Qk1Af(D*4o{P`y$4S^*_J{R<SR
+znk!e;ELq^>s)`&z33UqRD<)vQN>y)xs>URh=TKFJp6c>g#7|YQhRUV9Du;)<=vmns
+z%gGeqFIcdk at vQNx$e`5ukt}NdhXo20&=dp*mC9MAa#N{Fs8kg>9F-7P&bt00bsbxw
+zm#Rc_HOkzjRgMK!b~#iQmZm_F=D$&>P$9539=A at Q@;C5_YGPeoU9)7#0=VVMm8)F2
+za`EEDbL7Y&Ar~8!D!WSMs!|nJsmdrV_#D=&RCQ*nyoRgFby1g4w30arX{uR?$9^W!
+zrAwDK3F|Z}+Qo_$GeVGP0kf!7xmBuyDphfnssg{@qf=C4qPnLFtf+O-dRpS0`O*$+
+zYilqftTSfOMkzL_(5+P}N0lnCO68$amDX1K3VN_6O~WVnF at P>xwk!p0lF}_-QOkeI
+zt;SJlJ34|++8v)qQ)^8Avt`RxsZu2Y=!{vk at eZJ&$(1XYG5O83-?g-~M0pW|&X`4;
+zmUpNEGA%NLGY+9ifkwQ+W9_0vi`v`UqiHBoq=<ZVE%hnI$_-Skh*6dK&`$z%oFzrv
+z0Nfa-(?n#?o?VKj&Uh|m8i}TdKE)hRA^{XYDas^XhBfMh^5x45ZYW$B<JpwM!os3L
+zg$g>ca&Mqmxq;ldF at Q23dPtyDsZ#Q+ at u`3&y+kbylo<BX7@$W7K=63H5?quzBe{ra
+zq>arNIPw*U&a{_bef5>Wtg~i?mR^0hySoE7+ECCZG3;MN>clE_10^d6lq^}2eS|rz
+zL;@(4I$28<ZM4Po5qa|Dv9q(Imx6!^t8r8v`SRrx*B*i=nlHr?K&xjkYiV7y at HuEH
+zq)M)Qyr4LfOY`_zC|_mQR#?yGm7*Gz;Z7T61WJ at Bp;tE;N;!F^GM|cZqd%!EbLP8*
+z5};EaGN5TS4mo3{N%#}Gu2J#I(3Jm3%-US8b;(=ub5zChl<_HWczAfow8)abu2P|G
+z1uuD^GM@@q<F!HOU*>V<kK`qQ8DTDNAV78P?CgxHUj7$kKE>Bj?aR>A`4Pp9u0HMj
+z%RJHik-P*jg at hgybmI^#24d)+quXYDcNf2aPPj=}qeOGZbn^K!f0}L*fDV>+>U5T0
+zsT-<Pse%^7);2>}YNea#KCcI%uMT|1utp^Vi$~0%d|nyPgsFuk2?cFfHICjwCY0M}
+zmu2*pQTMW}4Zv-l;P@=K6D^G~tnsQC-#Pp&Wc39kl5MOBbgAAKHy-`EFF**HBnvQO
+z6O?P^)i~OEv(Dr*dQV`nFU1-k;XpT=TcXh=GlTw&KqIM`d=#_BJP4g2gVGfWb{01j
+zFBoK*o9WLBG*XN18454O4RsuM+5*}z at P(C{lateDmq&AgsRW<~0Y_-PXj!HonFD4C
+zm?dDAfLQ`&3792dmVj9TW(k-jV3vSc0%i%AC193-SpsGWm?dDAfLQ`&3792dmVj9T
+zW(k-jV3vSc0%i%AC193-SpsGWm?dDAfLQ`&3792dmVj9TW(k-jV1NW*Vhwk%u+hb0
+zC^t7Z7Z(>eOfbd+h5>0Xe<gh+fRz+*D&iwL;2Z<~j$m(ZfET0mNxAtc21o#oI<dk+
+zL^~xyYW;-)&oY1IlS=^Wp-_rb=<-5Xj`7LUX-<F=34kVAWGs3GQ?7R)2L}fp;gmS6
+zku<M`R3hq6dk@*6qgwKTb&ff6<`g6e3#n4LN`%awg#<#&XqSM9BALut`#)f!*Ucss
+zRkQ@*lxVYGI96gAFpPER0?_ml&gh7HC{*Am>?u$sLgqEF8IUhc5=P3DEH{7_9BZ86
+zRYn4Ds%UtRq`zzqWHbq&h2<h<BU9m&z0mABn$faoPLEassG{MffF&yq%i>M-VVN at 6
+zR8;anFWtPShNN`T<pWf_V!mulDx9(xcx|NAr_jHVT^Hd51KKvdJj17p7&62|F!F`B
+zJq&)Kmxkje at o32SRHDnx!WD#N at d`iWZjyr630-}GmuYBO;l~D at 0jbx+_<VgvzkuE^
+zL<ecsV2<k5t79gD<^o&Z;2khti2?T`=zs|*lS?5^*=zV6qG>|_FDifvC<`u88$f{r
+zA4i!}wT at REdyoMu16dnHB;D@@3NBpY!1NO<VZ*{`yW!;<Bw6B0hFTOp3NK9?NrO(%
+z0`6p29Wu}}EEk{Mw;*#dWfB9j*o~d!2xUQox;li65 at eEWqHxg>H|lmgf})fUAkBiV
+zm;BzE0?O<qUNE#-nW1h+(U1a-c)*1yh{_rhOoTQ5vYSpC4;_6c;*uA<<PqajV8U&J
+zhawlKoLPd(!}uZ&4DG-80XynFdDet4npX-M0Z1|}sy-#EQB=GF&=|HOdCK7m?j)?q
+zU+C_>U^P2z1Eg59aK&NNdjgpoe~AK)?jK%1^Z>z>TgE|(#evoY11nPA1rQZpvaAtC
+zkNq?C`z_zwM3V=IhOvfN(z=a<W{iuQ)tKSMAonOFE51#@np~nkVEn6_&c9HzW=*`P
+zD1$KE5<eOZpA=}si_5Yg23;xfZ<;U$?-I9Xj#5vaf^j0)r3LGBc#};iDDqP*O2`eR
+z0O}FQ5EFvfFcdv%_69*%KvsN-R?_&fwtSX>Ra~^$cMQG6G-A!R6!MA8AfF2G>2)cF
+zD~?I)zALID0c#Xw!DtJkHrykwoE64!>u^L0o{~X;$|OTCxa`ehtlSuJuUIBAhJA!N
+z4i+~ww}Rh6H3f|y4%AxE@<A_z+5lnPNw&C^ht6e<8c*<)jDN}E(<{s+%Z*HHf6FLe
+z=yDL;Xf^b$TJa{}ZIQvvWesIQ#)m6Np<aC1o4HuIkx(xS9%}MSD086t1}_8NEA&k8
+zsz|Zsf<|Ooj3`Ym7Qqj)_>_maOl2ZbXPQcDDo8)QMDa9W*o%P%z)68dycBDJrky4u
+zBL|f8W$%>1D)kXs#tbC~Sfj~T-Q)$}vQCHbMOw&;C8#_s1ynxXB=cX!3jxI+nlzcR
+z%zngWjeec+$w>cSP|la$DGyZUQ^@Vpj#Hp9Ak8{UQ$EaP&E3N#{n_dJL`qP3K!&Ey
+zkHiBaeG_ch{ph?Ysj<b}#jH&@V{2Gm4E~mK#N<w$H05uA;ei2NWrK4^zlg!Ln4^*y
+zF>Ar91p0`KA4pHu#KPp0bkd-zg>D=j2IVa^-UKmd6zWgg3>ouA>BU;U%<BA<8jO8H
+zaRIlI;!N%lv&M|7G1C6D-%WqkAkNM?rgQeua2w3}vo6$-vvSrti>>?(q)?N;u;)o<
+z#O&iR6`~Ngpj>~#SCmb^!C{50<vA+(lx2-Dce>o*T<G;h)WZg_rgP$YJu5 at qoIb1t
+zpmF(0$_VtdnCCJKbXrfur^8#Jgtd}lD}RreH6|9*A$RN}FxG?ZoI=pJja1;UHIg^e
+zVjq#g!#Y{ZLsasq7&KziQ>lV!5g=1encRtH{fnVYUP5`+N>J*&hs)Zu2IMjY3Z~0?
+zji~_|_7$H*;Ukj^lYAt at S|>y$H*i5CGTl_lP~9jm(HK?1R_zODnz`@Br(&(I^$0id
+zN+MB#Lt};+OiWe7zyS7>T=Zz2F?;n1l{`xFV&pwitd*2mo%cu;Y6#rOWE=2xvKWvH
+M8kRGe!I94Y0Z~OtP5=M^
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/content/aboutDialog-appUpdater.js b/im/content/aboutDialog-appUpdater.js
+new file mode 100644
+index 000000000..f223f061e
+--- /dev/null
++++ b/im/content/aboutDialog-appUpdater.js
+@@ -0,0 +1,576 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++// Note: this file is included in aboutDialog.xul if MOZ_UPDATER is defined.
++
++Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
++Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
++Components.utils.import("resource://gre/modules/AddonManager.jsm");
++
++XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
++                                  "resource://gre/modules/UpdateUtils.jsm");
++
++var gAppUpdater;
++
++function onUnload(aEvent) {
++  if (gAppUpdater.isChecking)
++    gAppUpdater.checker.stopChecking(Components.interfaces.nsIUpdateChecker.CURRENT_CHECK);
++  // Safe to call even when there isn't a download in progress.
++  gAppUpdater.removeDownloadListener();
++  gAppUpdater = null;
++}
++
++
++function appUpdater()
++{
++  this.updateDeck = document.getElementById("updateDeck");
++
++  // Hide the update deck when there is already an update window open to avoid
++  // syncing issues between them.
++  if (Services.wm.getMostRecentWindow("Update:Wizard")) {
++    this.updateDeck.hidden = true;
++    return;
++  }
++
++  XPCOMUtils.defineLazyServiceGetter(this, "aus",
++                                     "@mozilla.org/updates/update-service;1",
++                                     "nsIApplicationUpdateService");
++  XPCOMUtils.defineLazyServiceGetter(this, "checker",
++                                     "@mozilla.org/updates/update-checker;1",
++                                     "nsIUpdateChecker");
++  XPCOMUtils.defineLazyServiceGetter(this, "um",
++                                     "@mozilla.org/updates/update-manager;1",
++                                     "nsIUpdateManager");
++
++  this.bundle = Services.strings.
++                createBundle("chrome://browser/locale/browser.properties");
++
++  let manualURL = Services.urlFormatter.formatURLPref("app.update.url.manual");
++  let manualLink = document.getElementById("manualLink");
++  manualLink.value = manualURL;
++  manualLink.href = manualURL;
++  document.getElementById("failedLink").href = manualURL;
++
++  if (this.updateDisabledAndLocked) {
++    this.selectPanel("adminDisabled");
++    return;
++  }
++
++  if (this.isPending || this.isApplied) {
++    this.selectPanel("apply");
++    return;
++  }
++
++  if (this.aus.isOtherInstanceHandlingUpdates) {
++    this.selectPanel("otherInstanceHandlingUpdates");
++    return;
++  }
++
++  if (this.isDownloading) {
++    this.startDownload();
++    // selectPanel("downloading") is called from setupDownloadingUI().
++    return;
++  }
++
++  // Honor the "Never check for updates" option by not only disabling background
++  // update checks, but also in the About dialog, by presenting a
++  // "Check for updates" button.
++  // If updates are found, the user is then asked if he wants to "Update to <version>".
++  if (!this.updateEnabled) {
++    this.selectPanel("checkForUpdates");
++    return;
++  }
++
++  // That leaves the options
++  // "Check for updates, but let me choose whether to install them", and
++  // "Automatically install updates".
++  // In both cases, we check for updates without asking.
++  // In the "let me choose" case, we ask before downloading though, in onCheckComplete.
++  this.checkForUpdates();
++}
++
++appUpdater.prototype =
++{
++  // true when there is an update check in progress.
++  isChecking: false,
++
++  // true when there is an update already staged / ready to be applied.
++  get isPending() {
++    if (this.update) {
++      return this.update.state == "pending" ||
++             this.update.state == "pending-service";
++    }
++    return this.um.activeUpdate &&
++           (this.um.activeUpdate.state == "pending" ||
++            this.um.activeUpdate.state == "pending-service");
++  },
++
++  // true when there is an update already installed in the background.
++  get isApplied() {
++    if (this.update)
++      return this.update.state == "applied" ||
++             this.update.state == "applied-service";
++    return this.um.activeUpdate &&
++           (this.um.activeUpdate.state == "applied" ||
++            this.um.activeUpdate.state == "applied-service");
++  },
++
++  // true when there is an update download in progress.
++  get isDownloading() {
++    if (this.update)
++      return this.update.state == "downloading";
++    return this.um.activeUpdate &&
++           this.um.activeUpdate.state == "downloading";
++  },
++
++  // true when updating is disabled by an administrator.
++  get updateDisabledAndLocked() {
++    return !this.updateEnabled &&
++           Services.prefs.prefIsLocked("app.update.enabled");
++  },
++
++  // true when updating is enabled.
++  get updateEnabled() {
++    try {
++      return Services.prefs.getBoolPref("app.update.enabled");
++    }
++    catch (e) { }
++    return true; // Firefox default is true
++  },
++
++  // true when updating in background is enabled.
++  get backgroundUpdateEnabled() {
++    return this.updateEnabled &&
++           gAppUpdater.aus.canStageUpdates;
++  },
++
++  // true when updating is automatic.
++  get updateAuto() {
++    try {
++      return Services.prefs.getBoolPref("app.update.auto");
++    }
++    catch (e) { }
++    return true; // Firefox default is true
++  },
++
++  /**
++   * Sets the panel of the updateDeck.
++   *
++   * @param  aChildID
++   *         The id of the deck's child to select, e.g. "apply".
++   */
++  selectPanel: function(aChildID) {
++    let panel = document.getElementById(aChildID);
++
++    let button = panel.querySelector("button");
++    if (button) {
++      if (aChildID == "downloadAndInstall") {
++        let updateVersion = gAppUpdater.update.displayVersion;
++        button.label = this.bundle.formatStringFromName("update.downloadAndInstallButton.label", [updateVersion], 1);
++        button.accessKey = this.bundle.GetStringFromName("update.downloadAndInstallButton.accesskey");
++      }
++      this.updateDeck.selectedPanel = panel;
++      if (!document.commandDispatcher.focusedElement || // don't steal the focus
++          document.commandDispatcher.focusedElement.localName == "button") // except from the other buttons
++        button.focus();
++
++    } else {
++      this.updateDeck.selectedPanel = panel;
++    }
++  },
++
++  /**
++   * Check for updates
++   */
++  checkForUpdates: function() {
++    this.selectPanel("checkingForUpdates");
++    this.isChecking = true;
++    this.checker.checkForUpdates(this.updateCheckListener, true);
++    // after checking, onCheckComplete() is called
++  },
++
++  /**
++   * Check for addon compat, or start the download right away
++   */
++  doUpdate: function() {
++    // skip the compatibility check if the update doesn't provide appVersion,
++    // or the appVersion is unchanged, e.g. nightly update
++#ifdef TOR_BROWSER_UPDATE
++    let pkgVersion = TOR_BROWSER_VERSION;
++#else
++    let pkgVersion = Services.appinfo.version;
++#endif
++    if (!this.update.appVersion ||
++        Services.vc.compare(gAppUpdater.update.appVersion, pkgVersion) == 0) {
++      this.startDownload();
++    } else {
++      this.checkAddonCompatibility();
++    }
++  },
++
++  /**
++   * Handles oncommand for the "Restart to Update" button
++   * which is presented after the download has been downloaded.
++   */
++  buttonRestartAfterDownload: function() {
++    if (!this.isPending && !this.isApplied)
++      return;
++
++      // Notify all windows that an application quit has been requested.
++      let cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"].
++                       createInstance(Components.interfaces.nsISupportsPRBool);
++      Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
++
++      // Something aborted the quit process.
++      if (cancelQuit.data)
++        return;
++
++      let appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"].
++                       getService(Components.interfaces.nsIAppStartup);
++
++      // If already in safe mode restart in safe mode (bug 327119)
++      if (Services.appinfo.inSafeMode) {
++        appStartup.restartInSafeMode(Components.interfaces.nsIAppStartup.eAttemptQuit);
++        return;
++      }
++
++      appStartup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit |
++                      Components.interfaces.nsIAppStartup.eRestart);
++    },
++
++  /**
++   * Handles oncommand for the "Apply Update…" button
++   * which is presented if we need to show the billboard or license.
++   */
++  buttonApplyBillboard: function() {
++    const URI_UPDATE_PROMPT_DIALOG = "chrome://mozapps/content/update/updates.xul";
++    var ary = null;
++    ary = Components.classes["@mozilla.org/supports-array;1"].
++          createInstance(Components.interfaces.nsISupportsArray);
++    ary.AppendElement(this.update);
++    var openFeatures = "chrome,centerscreen,dialog=no,resizable=no,titlebar,toolbar=no";
++    Services.ww.openWindow(null, URI_UPDATE_PROMPT_DIALOG, "", openFeatures, ary);
++    window.close(); // close the "About" window; updates.xul takes over.
++  },
++
++  /**
++   * Implements nsIUpdateCheckListener. The methods implemented by
++   * nsIUpdateCheckListener are in a different scope from nsIIncrementalDownload
++   * to make it clear which are used by each interface.
++   */
++  updateCheckListener: {
++    /**
++     * See nsIUpdateService.idl
++     */
++    onCheckComplete: function(aRequest, aUpdates, aUpdateCount) {
++      gAppUpdater.isChecking = false;
++      gAppUpdater.update = gAppUpdater.aus.
++                           selectUpdate(aUpdates, aUpdates.length);
++      if (!gAppUpdater.update) {
++        gAppUpdater.selectPanel("noUpdatesFound");
++        return;
++      }
++
++      if (gAppUpdater.update.unsupported) {
++        if (gAppUpdater.update.detailsURL) {
++          let unsupportedLink = document.getElementById("unsupportedLink");
++          unsupportedLink.href = gAppUpdater.update.detailsURL;
++        }
++        gAppUpdater.selectPanel("unsupportedSystem");
++        return;
++      }
++
++      if (!gAppUpdater.aus.canApplyUpdates) {
++        gAppUpdater.selectPanel("manualUpdate");
++        return;
++      }
++
++      // Firefox no longer displays a license for updates and the licenseURL
++      // check is just in case a distibution does.
++      if (gAppUpdater.update.billboardURL || gAppUpdater.update.licenseURL) {
++        gAppUpdater.selectPanel("applyBillboard");
++        return;
++      }
++
++      if (gAppUpdater.updateAuto) // automatically download and install
++        gAppUpdater.doUpdate();
++      else // ask
++        gAppUpdater.selectPanel("downloadAndInstall");
++    },
++
++    /**
++     * See nsIUpdateService.idl
++     */
++    onError: function(aRequest, aUpdate) {
++      // Errors in the update check are treated as no updates found. If the
++      // update check fails repeatedly without a success the user will be
++      // notified with the normal app update user interface so this is safe.
++      gAppUpdater.isChecking = false;
++      gAppUpdater.selectPanel("noUpdatesFound");
++    },
++
++    /**
++     * See nsISupports.idl
++     */
++    QueryInterface: function(aIID) {
++      if (!aIID.equals(Components.interfaces.nsIUpdateCheckListener) &&
++          !aIID.equals(Components.interfaces.nsISupports))
++        throw Components.results.NS_ERROR_NO_INTERFACE;
++      return this;
++    }
++  },
++
++  /**
++   * Checks the compatibility of add-ons for the application update.
++   */
++  checkAddonCompatibility: function() {
++    try {
++      var hotfixID = Services.prefs.getCharPref(PREF_EM_HOTFIX_ID);
++    }
++    catch (e) { }
++
++    var self = this;
++    AddonManager.getAllAddons(function(aAddons) {
++      self.addons = [];
++      self.addonsCheckedCount = 0;
++      aAddons.forEach(function(aAddon) {
++        // Protect against code that overrides the add-ons manager and doesn't
++        // implement the isCompatibleWith or the findUpdates method.
++        if (!("isCompatibleWith" in aAddon) || !("findUpdates" in aAddon)) {
++          let errMsg = "Add-on doesn't implement either the isCompatibleWith " +
++                       "or the findUpdates method!";
++          if (aAddon.id)
++            errMsg += " Add-on ID: " + aAddon.id;
++          Components.utils.reportError(errMsg);
++          return;
++        }
++
++        // If an add-on isn't appDisabled and isn't userDisabled then it is
++        // either active now or the user expects it to be active after the
++        // restart. If that is the case and the add-on is not installed by the
++        // application and is not compatible with the new application version
++        // then the user should be warned that the add-on will become
++        // incompatible. If an addon's type equals plugin it is skipped since
++        // checking plugins compatibility information isn't supported and
++        // getting the scope property of a plugin breaks in some environments
++        // (see bug 566787). The hotfix add-on is also ignored as it shouldn't
++        // block the user from upgrading.
++        try {
++#ifdef TOR_BROWSER_UPDATE
++          let compatVersion = self.update.platformVersion;
++#else
++          let compatVersion = self.update.appVersion;
++#endif
++          if (aAddon.type != "plugin" && aAddon.id != hotfixID &&
++              !aAddon.appDisabled && !aAddon.userDisabled &&
++              aAddon.scope != AddonManager.SCOPE_APPLICATION &&
++              aAddon.isCompatible &&
++              !aAddon.isCompatibleWith(compatVersion,
++                                       self.update.platformVersion))
++            self.addons.push(aAddon);
++        }
++        catch (e) {
++          Components.utils.reportError(e);
++        }
++      });
++      self.addonsTotalCount = self.addons.length;
++      if (self.addonsTotalCount == 0) {
++        self.startDownload();
++        return;
++      }
++
++      self.checkAddonsForUpdates();
++    });
++  },
++
++  /**
++   * Checks if there are updates for add-ons that are incompatible with the
++   * application update.
++   */
++  checkAddonsForUpdates: function() {
++    this.addons.forEach(function(aAddon) {
++#ifdef TOR_BROWSER_UPDATE
++      let compatVersion = this.update.platformVersion;
++#else
++      let compatVersion = this.update.appVersion;
++#endif
++      aAddon.findUpdates(this, AddonManager.UPDATE_WHEN_NEW_APP_DETECTED,
++                         compatVersion,
++                         this.update.platformVersion);
++    }, this);
++  },
++
++  /**
++   * See XPIProvider.jsm
++   */
++  onCompatibilityUpdateAvailable: function(aAddon) {
++    for (var i = 0; i < this.addons.length; ++i) {
++      if (this.addons[i].id == aAddon.id) {
++        this.addons.splice(i, 1);
++        break;
++      }
++    }
++  },
++
++  /**
++   * See XPIProvider.jsm
++   */
++  onUpdateAvailable: function(aAddon, aInstall) {
++#ifdef TOR_BROWSER_UPDATE
++    let compatVersion = this.update.platformVersion;
++#else
++    let compatVersion = this.update.appVersion;
++#endif
++    if (!Services.blocklist.isAddonBlocklisted(aAddon,
++                                               compatVersion,
++                                               this.update.platformVersion)) {
++      // Compatibility or new version updates mean the same thing here.
++      this.onCompatibilityUpdateAvailable(aAddon);
++    }
++  },
++
++  /**
++   * See XPIProvider.jsm
++   */
++  onUpdateFinished: function(aAddon) {
++    ++this.addonsCheckedCount;
++
++    if (this.addonsCheckedCount < this.addonsTotalCount)
++      return;
++
++    if (this.addons.length == 0) {
++      // Compatibility updates or new version updates were found for all add-ons
++      this.startDownload();
++      return;
++    }
++
++    this.selectPanel("applyBillboard");
++  },
++
++  /**
++   * Starts the download of an update mar.
++   */
++  startDownload: function() {
++    if (!this.update)
++      this.update = this.um.activeUpdate;
++    this.update.QueryInterface(Components.interfaces.nsIWritablePropertyBag);
++    this.update.setProperty("foregroundDownload", "true");
++
++    this.aus.pauseDownload();
++    let state = this.aus.downloadUpdate(this.update, false);
++    if (state == "failed") {
++      this.selectPanel("downloadFailed");
++      return;
++    }
++
++    this.setupDownloadingUI();
++  },
++
++  /**
++   * Switches to the UI responsible for tracking the download.
++   */
++  setupDownloadingUI: function() {
++    this.downloadStatus = document.getElementById("downloadStatus");
++    this.downloadStatus.value =
++      DownloadUtils.getTransferTotal(0, this.update.selectedPatch.size);
++    this.selectPanel("downloading");
++    this.aus.addDownloadListener(this);
++  },
++
++  removeDownloadListener: function() {
++    if (this.aus) {
++      this.aus.removeDownloadListener(this);
++    }
++  },
++
++  /**
++   * See nsIRequestObserver.idl
++   */
++  onStartRequest: function(aRequest, aContext) {
++  },
++
++  /**
++   * See nsIRequestObserver.idl
++   */
++  onStopRequest: function(aRequest, aContext, aStatusCode) {
++    switch (aStatusCode) {
++    case Components.results.NS_ERROR_UNEXPECTED:
++      if (this.update.selectedPatch.state == "download-failed" &&
++          (this.update.isCompleteUpdate || this.update.patchCount != 2)) {
++        // Verification error of complete patch, informational text is held in
++        // the update object.
++        this.removeDownloadListener();
++        this.selectPanel("downloadFailed");
++        break;
++      }
++      // Verification failed for a partial patch, complete patch is now
++      // downloading so return early and do NOT remove the download listener!
++      break;
++    case Components.results.NS_BINDING_ABORTED:
++      // Do not remove UI listener since the user may resume downloading again.
++      break;
++    case Components.results.NS_OK:
++      this.removeDownloadListener();
++      if (this.backgroundUpdateEnabled) {
++        this.selectPanel("applying");
++        let update = this.um.activeUpdate;
++        let self = this;
++        Services.obs.addObserver(function (aSubject, aTopic, aData) {
++          // Update the UI when the background updater is finished
++          let status = aData;
++          if (status == "applied" || status == "applied-service" ||
++              status == "pending" || status == "pending-service") {
++            // If the update is successfully applied, or if the updater has
++            // fallen back to non-staged updates, show the "Restart to Update"
++            // button.
++            self.selectPanel("apply");
++          } else if (status == "failed") {
++            // Background update has failed, let's show the UI responsible for
++            // prompting the user to update manually.
++            self.selectPanel("downloadFailed");
++          } else if (status == "downloading") {
++            // We've fallen back to downloading the full update because the
++            // partial update failed to get staged in the background.
++            // Therefore we need to keep our observer.
++            self.setupDownloadingUI();
++            return;
++          }
++          Services.obs.removeObserver(arguments.callee, "update-staged");
++        }, "update-staged", false);
++      } else {
++        this.selectPanel("apply");
++      }
++      break;
++    default:
++      this.removeDownloadListener();
++      this.selectPanel("downloadFailed");
++      break;
++    }
++  },
++
++  /**
++   * See nsIProgressEventSink.idl
++   */
++  onStatus: function(aRequest, aContext, aStatus, aStatusArg) {
++  },
++
++  /**
++   * See nsIProgressEventSink.idl
++   */
++  onProgress: function(aRequest, aContext, aProgress, aProgressMax) {
++    this.downloadStatus.value =
++      DownloadUtils.getTransferTotal(aProgress, aProgressMax);
++  },
++
++  /**
++   * See nsISupports.idl
++   */
++  QueryInterface: function(aIID) {
++    if (!aIID.equals(Components.interfaces.nsIProgressEventSink) &&
++        !aIID.equals(Components.interfaces.nsIRequestObserver) &&
++        !aIID.equals(Components.interfaces.nsISupports))
++      throw Components.results.NS_ERROR_NO_INTERFACE;
++    return this;
++  }
++};
+diff --git a/im/content/aboutDialog.css b/im/content/aboutDialog.css
+index 25070608b..a065c8e88 100644
+--- a/im/content/aboutDialog.css
++++ b/im/content/aboutDialog.css
+@@ -1,66 +1,91 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
+ #aboutDialog {
+-  padding: 0px 0px 10px 0px;
++  width: 620px;
+ }
+ 
+-#modes {
+-  min-height: 380px;
++#rightBox {
++  background-image: url("chrome://branding/content/about-wordmark.png");
++  background-position: left top;
++  background-repeat: no-repeat;
++  /* padding-top creates room for the wordmark */
++  padding-top: 38px;
++  margin-top:20px;
+ }
+ 
+-#clientBox {
+-  background-color: #FFFFFF;
+-  background-image: url("chrome://branding/content/about.png");
+-  background-repeat: no-repeat;
+-  padding-top: 220px;
+-  color: #000000;
++#rightBox:-moz-locale-dir(rtl) {
++  background-position: 100% 0;
+ }
+ 
+-#versionWrapper {
+-  margin: 0px 0px 3px 20px;
++#bottomBox > hbox:not(#newBottom) {
++  display: none;
+ }
+ 
+-#versionField {
+-  background-color: #FFFFFF;
+-  -moz-appearance: none;
+-  border: none;
++#version {
+   font-weight: bold;
+-  color: #909090;
++  margin-top: 10px;
++  -moz-margin-start: 0;
++  -moz-user-select: text;
++  -moz-user-focus: normal;
++  cursor: text;
+ }
+ 
+-#geckoVersionField,
+-#libpurpleVersionField {
+-  background-color: #FFFFFF;
+-  -moz-appearance: none;
+-  border: none;
+-  color: #909090;
+-  padding-top: 3px !important;
+-  padding-left: 10px !important;
++#version:-moz-locale-dir(rtl) {
++  direction: ltr;
++  text-align: right;
++  margin-right: 0;
+ }
+ 
+-#copyright {
+-  margin: 10px 20px 3px 20px;
++#distribution,
++#distributionId {
++  display: none;
++  margin-top: 0;
++  margin-bottom: 0;
+ }
+ 
+-#userAgentField {
+-  margin: 0px 0px 3px 20px !important;
+-  background-color: #FFFFFF;
+-  -moz-appearance: none;
+-  border: none;
++.text-blurb {
++  margin-bottom: 10px;
++  -moz-margin-start: 0;
++  -moz-padding-start: 0;
+ }
+ 
+-#groove {
+-  margin-top: 0px;
++#updateButton,
++#updateDeck > hbox > label {
++  -moz-margin-start: 0;
++  -moz-padding-start: 0;
+ }
+ 
+-#creditsIframe {
+-   cursor: default;
+-   -moz-user-select: none;
++.update-throbber {
++  width: 16px;
++  min-height: 16px;
++  -moz-margin-end: 3px;
++  list-style-image: url("chrome://global/skin/icons/loading_16.png");
+ }
+ 
+-button[dlgtype="extra2"] {
+-  margin-left: 13px;
++.text-link,
++.text-link:focus {
++  margin: 0px;
++  padding: 0px;
+ }
+ 
+-button[dlgtype="accept"] {
+-  margin-right: 13px;
++.bottom-link,
++.bottom-link:focus {
++  text-align: center;
++  margin: 0 40px;
+ }
+ 
++#currentChannel {
++  margin: 0;
++  padding: 0;
++  font-weight: bold;
++}
++
++#trademarkTor {
++  font-size: xx-small;
++  text-align: center;
++  color: #999999;
++  margin-top: 10px;
++  margin-bottom: 10px;
++}
+diff --git a/im/content/aboutDialog.js b/im/content/aboutDialog.js
+new file mode 100644
+index 000000000..e265f239c
+--- /dev/null
++++ b/im/content/aboutDialog.js
+@@ -0,0 +1,80 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++// Services = object with smart getters for common XPCOM services
++Components.utils.import("resource://gre/modules/Services.jsm");
++Components.utils.import("resource://gre/modules/AppConstants.jsm");
++
++const PREF_EM_HOTFIX_ID = "extensions.hotfix.id";
++
++#ifdef TOR_BROWSER_VERSION
++# Add double-quotes back on (stripped by JarMaker.py).
++#expand const TOR_BROWSER_VERSION = "__TOR_BROWSER_VERSION__";
++#endif
++
++function init(aEvent)
++{
++  if (aEvent.target != document)
++    return;
++
++  try {
++    var distroId = Services.prefs.getCharPref("distribution.id");
++    if (distroId) {
++      var distroVersion = Services.prefs.getCharPref("distribution.version");
++
++      var distroIdField = document.getElementById("distributionId");
++      distroIdField.value = distroId + " - " + distroVersion;
++      distroIdField.style.display = "block";
++
++      try {
++        // This is in its own try catch due to bug 895473 and bug 900925.
++        var distroAbout = Services.prefs.getComplexValue("distribution.about",
++          Components.interfaces.nsISupportsString);
++        var distroField = document.getElementById("distribution");
++        distroField.value = distroAbout;
++        distroField.style.display = "block";
++      }
++      catch (ex) {
++        // Pref is unset
++        Components.utils.reportError(ex);
++      }
++    }
++  }
++  catch (e) {
++    // Pref is unset
++  }
++
++  // Include the build ID and display warning if this is an "a#" (nightly or aurora) build
++  let version = Services.appinfo.version;
++  if (/a\d+$/.test(version)) {
++    document.getElementById("experimental").hidden = false;
++    document.getElementById("communityDesc").hidden = true;
++  }
++
++#ifdef TOR_BROWSER_VERSION
++  let versionElem = document.getElementById("version");
++  if (versionElem) {
++    versionElem.textContent = TOR_BROWSER_VERSION +
++                              " (based on Instantbird " +
++                              version + ")";
++  }
++#endif
++
++  if (AppConstants.MOZ_UPDATER) {
++    gAppUpdater = new appUpdater();
++
++    let defaults = Services.prefs.getDefaultBranch("");
++    let channelLabel = document.getElementById("currentChannel");
++    let currentChannelText = document.getElementById("currentChannelText");
++    channelLabel.value = UpdateUtils.UpdateChannel;
++    if (/^release($|\-)/.test(channelLabel.value))
++        currentChannelText.hidden = true;
++  }
++
++  if (AppConstants.platform == "macosx") {
++    // it may not be sized at this point, and we need its width to calculate its position
++    window.sizeToContent();
++    window.moveTo((screen.availWidth / 2) - (window.outerWidth / 2), screen.availHeight / 5);
++  }
++}
+diff --git a/im/content/aboutDialog.xul b/im/content/aboutDialog.xul
+index aa3b80ec9..ba924b9ad 100644
+--- a/im/content/aboutDialog.xul
++++ b/im/content/aboutDialog.xul
+@@ -1,130 +1,173 @@
+ <?xml version="1.0"?> <!-- -*- Mode: HTML -*- -->
++
+ # This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ 
+ <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+ <?xml-stylesheet href="chrome://instantbird/content/aboutDialog.css" type="text/css"?>
+-#ifdef XP_MACOSX
+-<?xul-overlay href="chrome://instantbird/content/menus.xul"?>
+-#endif
++<?xml-stylesheet href="chrome://branding/content/aboutDialog.css" type="text/css"?>
+ 
+ <!DOCTYPE window [
+ <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
+ %brandDTD;
+ <!ENTITY % aboutDialogDTD SYSTEM "chrome://instantbird/locale/aboutDialog.dtd" >
+ %aboutDialogDTD;
+-<!ENTITY copyrightYear "2015">
++]>
++
+ #ifdef XP_MACOSX
+- <!ENTITY % instantbirdDTD SYSTEM "chrome://instantbird/locale/instantbird.dtd">
+- %instantbirdDTD;
++<?xul-overlay href="chrome://instantbird/content/macBrowserOverlay.xul"?>
+ #endif
+-]>
+ 
+-<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
++<window xmlns:html="http://www.w3.org/1999/xhtml"
++        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+         id="aboutDialog"
+-        windowtype="Messenger:About"
+-        buttons="accept,extra2"
+-        onload="onLoad();"
+-        title="&aboutDialog.title;" creditslabel="&credits.label;" creditsaccesskey="&credits.accesskey;"
+-        aboutlabel="&aboutLink.label;" aboutaccesskey="&aboutLink.accesskey;" versionlabel="&aboutVersion;"
+-        style="width: 299px; height: 330px;">
+-
++        windowtype="Browser:About"
++        onload="init(event);"
++#ifdef MOZ_UPDATER
++        onunload="onUnload(event);"
++#endif
+ #ifdef XP_MACOSX
+-#include menus.xul.inc
++        inwindowmenu="false"
++#else
++        title="&aboutDialog.title;"
+ #endif
++        role="dialog"
++        aria-describedby="version distribution distributionId communityDesc contributeDesc trademark"
++        >
+ 
+-    <script type="application/x-javascript">
+-      <![CDATA[
+-        var gSelectedPage;
+-
+-        function onLoad() {
+-          var xai = Components.classes["@mozilla.org/xre/app-info;1"]
+-                              .getService(Components.interfaces.nsIXULAppInfo);
+-
+-          var versionField = document.getElementById("versionField");
+-          versionField.value = versionField.value + xai.version
+-                             + ' (' + xai.appBuildID + ')';
+-
+-          versionField = document.getElementById("geckoVersionField");
+-          versionField.value = versionField.value + xai.platformVersion
+-                             + ' (' + xai.platformBuildID + ')';
+-
+-          versionField = document.getElementById("libpurpleVersionField");
+-          if ("@instantbird.org/libpurple/core;1" in Components.classes) {
+-            var pcs = Components.classes["@instantbird.org/libpurple/core;1"]
+-                                .getService(Components.interfaces.purpleICoreService);
+-            versionField.value = versionField.value + pcs.version;
+-          }
+-          else {
+-            versionField.hidden = true;
+-          }
+-
+-          versionField = document.getElementById("userAgentField");
+-          versionField.value = navigator.userAgent;
+-
+-          var button = document.documentElement.getButton("extra2");
+-          button.setAttribute("label", document.documentElement.getAttribute("creditslabel"));
+-          button.setAttribute("accesskey", document.documentElement.getAttribute("creditsaccesskey"));
+-          gSelectedPage = 0;
+-          button.addEventListener("command", switchPage);
+-          document.documentElement.getButton("accept").focus();
+-        }
+-
+-        function uninit(aEvent)
+-        {
+-          if (aEvent.target != document)
+-            return;
+-          var iframe = document.getElementById("creditsIframe");
+-          iframe.setAttribute("src", "");
+-        }
+-
+-        function switchPage(aEvent)
+-        {
+-          var button = aEvent.target;
+-          if (button.localName != "button")
+-            return;
+-
+-          var iframe = document.getElementById("creditsIframe");
+-          if (gSelectedPage == 0) {
+-            iframe.setAttribute("src", "chrome://instantbird/content/credits.xhtml");
+-            button.setAttribute("label", document.documentElement.getAttribute("aboutlabel"));
+-            button.setAttribute("accesskey", document.documentElement.getAttribute("aboutaccesskey"));
+-            gSelectedPage = 1;
+-          }
+-          else {
+-            iframe.setAttribute("src", "");
+-            button.setAttribute("label", document.documentElement.getAttribute("creditslabel"));
+-            button.setAttribute("accesskey", document.documentElement.getAttribute("creditsaccesskey"));
+-            gSelectedPage = 0;
+-          }
+-          var modes = document.getElementById("modes");
+-          modes.setAttribute("selectedIndex", gSelectedPage);
+-        }
+-      ]]>
+-    </script>
+-
+-    <deck id="modes" flex="1">
+-      <vbox flex="1" id="clientBox">
+-        <vbox id="versionWrapper" flex="1">
+-          <textbox id="versionField" readonly="true" class="plain" tabindex="2"
+-                   value="&aboutVersion; "/>
+-          <textbox id="geckoVersionField" readonly="true" class="plain"
+-                   tabindex="3" value="&geckoVersion; "/>
+-          <textbox id="libpurpleVersionField" readonly="true" class="plain"
+-                   tabindex="4" value="&libpurpleVersion; "/>
++  <script type="application/javascript" src="chrome://instantbird/content/aboutDialog.js"/>
++#ifdef MOZ_UPDATER
++  <script type="application/javascript" src="chrome://instantbird/content/aboutDialog-appUpdater.js"/>
++#endif
++  <vbox id="aboutDialogContainer">
++    <hbox id="clientBox">
++      <vbox id="leftBox" flex="1"/>
++      <vbox id="rightBox" flex="1">
++#expand <label id="version">__MOZ_APP_VERSION_DISPLAY__</label>
++        <label id="distribution" class="text-blurb"/>
++        <label id="distributionId" class="text-blurb"/>
++
++        <vbox id="detailsBox">
++          <vbox id="updateBox">
++#ifdef MOZ_UPDATER
++            <deck id="updateDeck" orient="vertical">
++              <hbox id="checkForUpdates" align="center">
++                <button id="checkForUpdatesButton" align="start"
++                        label="&update.checkForUpdatesButton.label;"
++                        accesskey="&update.checkForUpdatesButton.accesskey;"
++                        oncommand="gAppUpdater.checkForUpdates();"/>
++                <spacer flex="1"/>
++              </hbox>
++              <hbox id="downloadAndInstall" align="center">
++                <button id="downloadAndInstallButton" align="start"
++                        oncommand="gAppUpdater.doUpdate();"/>
++                        <!-- label and accesskey will be filled by JS -->
++                <spacer flex="1"/>
++              </hbox>
++              <hbox id="apply" align="center">
++                <button id="updateButton" align="start"
++                        label="&update.updateButton.label2;"
++                        accesskey="&update.updateButton.accesskey;"
++                        oncommand="gAppUpdater.buttonRestartAfterDownload();"/>
++                <spacer flex="1"/>
++              </hbox>
++              <hbox id="applyBillboard" align="center">
++                <button id="applyButtonBillboard" align="start"
++                        label="&update.applyButtonBillboard.label;"
++                        accesskey="&update.applyButtonBillboard.accesskey;"
++                        oncommand="gAppUpdater.buttonApplyBillboard();"/>
++                <spacer flex="1"/>
++              </hbox>
++              <hbox id="checkingForUpdates" align="center">
++                <image class="update-throbber"/><label>&update.checkingForUpdates;</label>
++              </hbox>
++              <hbox id="downloading" align="center">
++                <image class="update-throbber"/><label>&update.downloading.start;</label><label id="downloadStatus"/><label>&update.downloading.end;</label>
++              </hbox>
++              <hbox id="applying" align="center">
++                <image class="update-throbber"/><label>&update.applying;</label>
++              </hbox>
++              <hbox id="downloadFailed" align="center">
++                <label>&update.failed.start;</label><label id="failedLink" class="text-link">&update.failed.linkText;</label><label>&update.failed.end;</label>
++              </hbox>
++              <hbox id="adminDisabled" align="center">
++                <label>&update.adminDisabled;</label>
++              </hbox>
++              <hbox id="noUpdatesFound" align="center">
++                <label>&update.noUpdatesFound;</label>
++              </hbox>
++              <hbox id="otherInstanceHandlingUpdates" align="center">
++                <label>&update.otherInstanceHandlingUpdates;</label>
++              </hbox>
++              <hbox id="manualUpdate" align="center">
++                <label>&update.manual.start;</label><label id="manualLink" class="text-link"/><label>&update.manual.end;</label>
++              </hbox>
++              <hbox id="unsupportedSystem" align="center">
++                <label>&update.unsupported.start;</label><label id="unsupportedLink" class="text-link">&update.unsupported.linkText;</label><label>&update.unsupported.end;</label>
++              </hbox>
++            </deck>
++#endif
++      <description class="text-blurb" id="projectDesc">
++        &project.start;
++        &project.tpoLink;&project.end;
++      </description>
++      <description class="text-blurb" id="helpDesc">
++       &help.donate;
++       <textbox flex="1" class="plain" readonly="true" size="36"
++           value="&help.donateLink;" />
++      </description>
++      <description class="text-blurb" id="getInvolvedLinkDesc">
++       &help.getInvolved;
++       <textbox flex="1" class="plain" readonly="true" size="36"
++           value="&help.getInvolvedLink;" />
++      </description>
++  </vbox>
++
++#ifdef MOZ_UPDATER
++          <description class="text-blurb" id="currentChannelText">
++            &channel.description.start;<label id="currentChannel"/>&channel.description.end;
++          </description>
++#endif
++          <vbox id="experimental" hidden="true">
++            <description class="text-blurb" id="warningDesc">
++              &warningDesc.version;
++#ifdef MOZ_TELEMETRY_ON_BY_DEFAULT
++              &warningDesc.telemetryDesc;
++#endif
++            </description>
++            <description class="text-blurb" id="communityExperimentalDesc">
++              &community.exp.start;<label class="text-link" href="http://www.mozilla.org/">&community.exp.mozillaLink;</label>&community.exp.middle;<label class="text-link" href="about:credits">&community.exp.creditsLink;</label>&community.exp.end;
++            </description>
++          </vbox>
++          <description class="text-blurb" id="communityDesc">
++            &community.start2;<label class="text-link" href="http://www.mozilla.org/">&community.mozillaLink;</label>&community.middle2;<label class="text-link" href="about:credits">&community.creditsLink;</label>&community.end3;
++          </description>
++          <description class="text-blurb" id="contributeDesc">
++              &helpus.start;<label class="text-link" href="https://sendto.mozilla.org/page/contribute/Give-Now?source=mozillaorg_default_footer&ref=firefox_about&utm_campaign=firefox_about&tm_source=firefox&tm_medium=referral&utm_content=20140929_FireFoxAbout">&helpus.donateLink;</label>&helpus.middle;<label class="text-link" href="http://www.mozilla.org/contribute/">&helpus.getInvolvedLink;</label>&helpus.end;
++          </description>
+         </vbox>
+-        <description id="copyright" flex="1">&copyrightText2;</description>
+-        <separator/>
+-        <textbox id="userAgentField" readonly="true" class="plain"
+-                 tabindex="5" multiline="true"/>
+-      </vbox>
+-
+-      <vbox flex="1" id="creditsBox">
+-        <iframe id="creditsIframe" flex="1"/>
+       </vbox>
+-    </deck>
++    </hbox>
++    <vbox id="bottomBox">
++      <hbox pack="center">
++        <label class="text-link bottom-link" href="about:license">&bottomLinks.license;</label>
++        <label class="text-link bottom-link" href="about:rights">&bottomLinks.rights;</label>
++        <label class="text-link bottom-link" href="https://www.mozilla.org/privacy/">&bottomLinks.privacy;</label>
++      </hbox>
++      <description id="trademark"></description>
++    </vbox>
++    <description id="trademarkTor" insertafter="trademark">
++      &tor.TrademarkStatement;
++    </description>
++
++  </vbox>
++  
++  <keyset>
++    <key keycode="VK_ESCAPE" oncommand="window.close();"/>
++  </keyset>
+ 
+-    <separator class="groove" id="groove"/>
+-
+-</dialog>
++#ifdef XP_MACOSX
++#include browserMountPoints.inc
++#endif
++</window>
+diff --git a/im/content/browserMountPoints.inc b/im/content/browserMountPoints.inc
+new file mode 100644
+index 000000000..e4315b04a
+--- /dev/null
++++ b/im/content/browserMountPoints.inc
+@@ -0,0 +1,12 @@
++<stringbundleset id="stringbundleset"/>
++
++<commandset id="mainCommandSet"/>
++<commandset id="baseMenuCommandSet"/>
++<commandset id="placesCommands"/>
++
++<broadcasterset id="mainBroadcasterSet"/>
++
++<keyset id="mainKeyset"/>
++<keyset id="baseMenuKeyset"/>
++
++<menubar id="main-menubar"/>
+\ No newline at end of file
+diff --git a/im/content/jar.mn b/im/content/jar.mn
+index 20ea9dce7..b3d9e492f 100644
+--- a/im/content/jar.mn
++++ b/im/content/jar.mn
+@@ -10,7 +10,8 @@ instantbird.jar:
+ #endif
+ 	content/instantbird/aboutDialog.css
+ *	content/instantbird/aboutDialog.xul
+-	content/instantbird/aboutPanel.xml
++*	content/instantbird/aboutDialog.js
++*	content/instantbird/aboutDialog-appUpdater.js
+ 	content/instantbird/account.js
+ 	content/instantbird/accounts.css
+ 	content/instantbird/accounts.js
+diff --git a/im/locales/en-US/chrome/instantbird/aboutDialog.dtd b/im/locales/en-US/chrome/instantbird/aboutDialog.dtd
+index ecd8d9d24..187cf5c3e 100644
+--- a/im/locales/en-US/chrome/instantbird/aboutDialog.dtd
++++ b/im/locales/en-US/chrome/instantbird/aboutDialog.dtd
+@@ -1,10 +1,129 @@
+-<!ENTITY aboutDialog.title      "About &brandFullName;">
+-<!ENTITY credits.label          "Credits">
+-<!ENTITY credits.accesskey      "C">
+-<!ENTITY aboutLink.label        "< About &brandShortName;">
+-<!ENTITY aboutLink.accesskey    "A">
+-<!ENTITY aboutVersion           "version">
+-<!ENTITY geckoVersion           "Gecko">
+-<!ENTITY libpurpleVersion       "libpurple">
+-<!-- Use the ©rightYear; entity to place the current year. -->
+-<!ENTITY copyrightText2         "©2007-©rightYear; Contributors. This program is free software; you can redistribute it and/or modify it under the terms of the GNU GPL license version 2.0 or later.">
++<!-- This Source Code Form is subject to the terms of the Mozilla Public
++   - License, v. 2.0. If a copy of the MPL was not distributed with this
++   - file, You can obtain one at http://mozilla.org/MPL/2.0/.  -->
++<!ENTITY aboutDialog.title          "About &brandFullName;">
++
++<!-- LOCALIZATION NOTE (update.checkForUpdatesButton.*, update.updateButton.*, update.applyButtonBillboard.*):
++# Only one button is present at a time.
++# The button when displayed is located directly under the Firefox version in
++# the about dialog (see bug 596813 for screenshots).
++-->
++<!ENTITY update.checkForUpdatesButton.label       "Check for updates">
++<!ENTITY update.checkForUpdatesButton.accesskey   "C">
++<!ENTITY update.updateButton.label2                "Restart &brandShortName; to Update">
++<!ENTITY update.updateButton.accesskey            "R">
++<!ENTITY update.applyButtonBillboard.label        "Apply Update…">
++<!ENTITY update.applyButtonBillboard.accesskey    "A">
++
++
++<!-- LOCALIZATION NOTE (warningDesc.version): This is a warning about the experimental nature of Nightly and Aurora builds. It is only shown in those versions. -->
++<!ENTITY warningDesc.version        "&brandShortName; is experimental and may be unstable.">
++<!-- LOCALIZATION NOTE (warningDesc.telemetryDesc): This is a notification that Nightly/Aurora builds automatically send Telemetry data back to Mozilla. It is only shown in those versions. "It" refers to brandShortName. -->
++<!ENTITY warningDesc.telemetryDesc  "It automatically sends information about performance, hardware, usage and customizations back to &vendorShortName; to help make &brandShortName; better.">
++
++<!-- LOCALIZATION NOTE (community.exp.*) This paragraph is shown in "experimental" builds, i.e. Nightly and Aurora builds, instead of the other "community.*" strings below. -->
++<!ENTITY community.exp.start        "">
++<!-- LOCALIZATION NOTE (community.exp.mozillaLink): This is a link title that links to http://www.mozilla.org/. -->
++<!ENTITY community.exp.mozillaLink  "&vendorShortName;">
++<!ENTITY community.exp.middle       " is a ">
++<!-- LOCALIZATION NOTE (community.exp.creditslink): This is a link title that links to about:credits. -->
++<!ENTITY community.exp.creditsLink  "global community">
++<!ENTITY community.exp.end          " working together to keep the Web open, public and accessible to all.">
++
++<!ENTITY community.start2           "&brandShortName; is designed by ">
++<!-- LOCALIZATION NOTE (community.mozillaLink): This is a link title that links to http://www.mozilla.org/. -->
++<!ENTITY community.mozillaLink      "&vendorShortName;">
++<!ENTITY community.middle2          ", a ">
++<!-- LOCALIZATION NOTE (community.creditsLink): This is a link title that links to about:credits. -->
++<!ENTITY community.creditsLink      "global community">
++<!ENTITY community.end3             " working together to keep the Web open, public and accessible to all.">
++
++<!ENTITY helpus.start               "Want to help? ">
++<!-- LOCALIZATION NOTE (helpus.donateLink): This is a link title that links to https://sendto.mozilla.org/page/contribute/Give-Now?source=mozillaorg_default_footer&ref=firefox_about&utm_campaign=firefox_about&utm_source=firefox&utm_medium=referral&utm_content=20140929_FireFoxAbout. -->
++<!ENTITY helpus.donateLink          "Make a donation">
++<!ENTITY helpus.middle              " or ">
++<!-- LOCALIZATION NOTE (helpus.getInvolvedLink): This is a link title that links to http://www.mozilla.org/contribute/. -->
++<!ENTITY helpus.getInvolvedLink     "get involved!">
++<!ENTITY helpus.end                 "">
++
++<!-- LOCALIZATION NOTE (bottomLinks.license): This is a link title that links to about:license. -->
++<!ENTITY bottomLinks.license        "Licensing Information">
++
++<!-- LOCALIZATION NOTE (bottomLinks.rights): This is a link title that links to about:rights. -->
++<!ENTITY bottomLinks.rights         "End-User Rights">
++
++<!-- LOCALIZATION NOTE (bottomLinks.privacy): This is a link title that links to https://www.mozilla.org/legal/privacy/. -->
++<!ENTITY bottomLinks.privacy        "Privacy Policy">
++
++<!-- LOCALIZATION NOTE (update.checkingForUpdates): try to make the localized text short (see bug 596813 for screenshots). -->
++<!ENTITY update.checkingForUpdates  "Checking for updates…">
++<!-- LOCALIZATION NOTE (update.noUpdatesFound): try to make the localized text short (see bug 596813 for screenshots). -->
++<!ENTITY update.noUpdatesFound      "&brandShortName; is up to date">
++<!-- LOCALIZATION NOTE (update.adminDisabled): try to make the localized text short (see bug 596813 for screenshots). -->
++<!ENTITY update.adminDisabled       "Updates disabled by your system administrator">
++<!-- LOCALIZATION NOTE (update.otherInstanceHandlingUpdates): try to make the localized text short -->
++<!ENTITY update.otherInstanceHandlingUpdates "&brandShortName; is being updated by another instance">
++
++<!-- LOCALIZATION NOTE (update.failed.start,update.failed.linkText,update.failed.end):
++     update.failed.start, update.failed.linkText, and update.failed.end all go into
++     one line with linkText being wrapped in an anchor that links to a site to download
++     the latest version of Firefox (e.g. http://www.firefox.com). As this is all in
++     one line, try to make the localized text short (see bug 596813 for screenshots). -->
++<!ENTITY update.failed.start        "Update failed. ">
++<!ENTITY update.failed.linkText     "Download the latest version">
++<!ENTITY update.failed.end          "">
++
++<!-- LOCALIZATION NOTE (update.manual.start,update.manual.end): update.manual.start and update.manual.end
++     all go into one line and have an anchor in between with text that is the same as the link to a site
++     to download the latest version of Firefox (e.g. http://www.firefox.com). As this is all in one line,
++     try to make the localized text short (see bug 596813 for screenshots). -->
++<!ENTITY update.manual.start        "Updates available at ">
++<!ENTITY update.manual.end          "">
++
++<!-- LOCALIZATION NOTE (update.unsupported.start,update.unsupported.linkText,update.unsupported.end):
++     update.unsupported.start, update.unsupported.linkText, and
++     update.unsupported.end all go into one line with linkText being wrapped in
++     an anchor that links to a site to provide additional information regarding
++     why the system is no longer supported. As this is all in one line, try to
++     make the localized text short (see bug 843497 for screenshots). -->
++<!ENTITY update.unsupported.start    "You can not perform further updates on this system. ">
++<!ENTITY update.unsupported.linkText "Learn more">
++<!ENTITY update.unsupported.end      "">
++
++<!-- LOCALIZATION NOTE (update.downloading.start,update.downloading.end): update.downloading.start and 
++     update.downloading.end all go into one line, with the amount downloaded inserted in between. As this
++     is all in one line, try to make the localized text short (see bug 596813 for screenshots). The — is
++     the "em dash" (long dash).
++     example: Downloading update — 111 KB of 13 MB -->
++<!ENTITY update.downloading.start   "Downloading update — ">
++<!ENTITY update.downloading.end     "">
++
++<!ENTITY update.applying            "Applying update…">
++
++<!-- LOCALIZATION NOTE (channel.description.start,channel.description.end): channel.description.start and
++     channel.description.end create one sentence, with the current channel label inserted in between.
++     example: You are currently on the _Stable_ update channel. -->
++<!ENTITY channel.description.start  "You are currently on the ">
++<!ENTITY channel.description.end    " update channel. ">
++
++<!ENTITY project.start           "&brandShortName; is developed by">
++<!-- LOCALIZATION NOTE (project.tpoLink): This is a link title that links to https://www.torproject.org -->
++<!ENTITY project.tpoLink         "the &vendorShortName;">
++<!ENTITY project.end             ", a nonprofit working to defend your privacy and freedom online.">
++
++<!ENTITY help.start              "Want to help? ">
++<!-- LOCALIZATION NOTE (help.donate): This is a link title that links to https://www.torproject.org/donate/donate.html.en -->
++<!ENTITY help.donate             "Donate:">
++<!ENTITY help.donateLink         "https://www.torproject.org/donate">
++<!ENTITY help.or                 " or ">
++<!-- LOCALIZATION NOTE (help.getInvolvedLink): This is a link title that links to https://www.torproject.org/getinvolved/volunteer.html.en -->
++<!ENTITY help.getInvolved        "Get Involved:">
++<!ENTITY help.getInvolvedLink    "https://www.torproject.org/volunteer">
++<!ENTITY help.end                "!">
++<!-- LOCALIZATION NOTE (bottom.questions): This is a link title that links to https://www.torproject.org/docs/trademark-faq.html.en -->
++<!ENTITY bottomLinks.questions   "Questions?">
++<!-- LOCALIZATION NOTE (bottom.questions): This is a link title that links to https://www.torproject.org/getinvolved/relays -->
++<!ENTITY bottomLinks.grow        "Help the Tor Network Grow!">
++<!-- LOCALIZATION NOTE (bottom.questions): This is a link title that links to about:license -->
++<!ENTITY bottomLinks.license  "Licensing Information">
++<!ENTITY tor.TrademarkStatement   "'Tor' and the 'Onion Logo' are registered trademarks of the Tor Project, Inc.">
+diff --git a/im/locales/en-US/updater/updater.ini b/im/locales/en-US/updater/updater.ini
+index 15ec569c1..4a2d35d8a 100644
+--- a/im/locales/en-US/updater/updater.ini
++++ b/im/locales/en-US/updater/updater.ini
+@@ -5,4 +5,4 @@
+ ; This file is in the UTF-8 encoding
+ [Strings]
+ Title=Software Update
+-Info=Instantbird is installing your updates and will start in a few moments…
++Info=Tor Messenger is installing your updates and will start in a few moments…
+-- 
+2.11.0
+
diff --git a/projects/instantbird/0010-Remove-search-from-UI.patch b/projects/instantbird/0010-Remove-search-from-UI.patch
deleted file mode 100644
index dd777d6..0000000
--- a/projects/instantbird/0010-Remove-search-from-UI.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From bf059fabc88ff728d65d226fb6cb158e0d8e3759 Mon Sep 17 00:00:00 2001
-From: Sukhbir Singh <sukhbir at torproject.org>
-Date: Mon, 10 Oct 2016 18:47:48 -0700
-Subject: [PATCH 10/27] Remove search from UI
-
----
- im/content/nsContextMenu.js         | 18 +-----------------
- im/content/preferences/advanced.xul | 11 -----------
- 2 files changed, 1 insertion(+), 28 deletions(-)
-
-diff --git a/im/content/nsContextMenu.js b/im/content/nsContextMenu.js
-index 5261b793f..f667793be 100644
---- a/im/content/nsContextMenu.js
-+++ b/im/content/nsContextMenu.js
-@@ -468,23 +468,7 @@ nsContextMenu.prototype = {
-     if (selectedText.length > 15)
-       selectedText = selectedText.substr(0,15) + this.ellipsis;
- 
--    var engine = Services.search.defaultEngine;
--    if (!engine)
--      return false;
--
--    // format "Search <engine> for <selection>" string to show in menu
--    var bundle = document.getElementById("bundle_instantbird");
--    var menuLabel = bundle.getFormattedString("contextMenuSearchText",
--                                              [engine.name,
--                                               selectedText]);
--    document.getElementById("context-searchselect").label = menuLabel;
--    document.getElementById("context-searchselect").accessKey =
--      bundle.getString("contextMenuSearchText.accesskey");
--    menuLabel = bundle.getFormattedString("contextMenuSearchWith",
--                                          [selectedText]);
--    document.getElementById("context-searchselect-with").label = menuLabel;
--
--    return true;
-+    return false;
-   },
- 
-   // Returns true if anything is selected.
-diff --git a/im/content/preferences/advanced.xul b/im/content/preferences/advanced.xul
-index fad67c190..cfe2405ea 100644
---- a/im/content/preferences/advanced.xul
-+++ b/im/content/preferences/advanced.xul
-@@ -143,17 +143,6 @@
-                       preference="layout.spellcheckDefault"/>
-           </groupbox>
- 
--          <!-- Search engines -->
--          <groupbox id="searchEnginesGroup" orient="horizontal" align="center">
--            <caption label="&searchEnginesGroup.label;"/>
--
--            <description control="manageSearchEnginesButton"
--                         flex="1">&searchEnginesDesc.label;</description>
--            <button id="manageSearchEnginesButton" label="&searchEngines.label;"
--                    accesskey="&searchEngines.accesskey;"
--                    oncommand="gAdvancedPane.showSearchEngineManager();"/>
--          </groupbox>
--
-           <!-- Advanced Configuration -->
-           <groupbox>
-             <caption label="&configEditDesc.label;"/>
--- 
-2.11.0
-
diff --git a/projects/instantbird/0011-Account-picture.patch b/projects/instantbird/0011-Account-picture.patch
new file mode 100644
index 0000000..f89bd00
--- /dev/null
+++ b/projects/instantbird/0011-Account-picture.patch
@@ -0,0 +1,26 @@
+From 25cc9f7781966e98788b6b5cd04e51cbdd03c962 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir at torproject.org>
+Date: Mon, 10 Oct 2016 19:24:09 -0700
+Subject: [PATCH 11/26] Account picture
+
+---
+ im/content/blist.xul | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/im/content/blist.xul b/im/content/blist.xul
+index b90fddadb..f29a48b99 100644
+--- a/im/content/blist.xul
++++ b/im/content/blist.xul
+@@ -114,8 +114,7 @@
+       <stack id="statusImageStack">
+         <!-- The box around the user icon is a workaround for bug 955673. -->
+         <box id="userIconHolder">
+-          <image id="userIcon" role="button" popup="changeUserIconPanel"
+-                 aria-label="&userIcon.label;" tooltiptext="&userIcon.label;"/>
++          <image id="userIcon" role="button"/>
+         </box>
+         <panel id="changeUserIconPanel"
+                type="arrow" align="center"
+-- 
+2.11.0
+
diff --git a/projects/instantbird/0011-Add-Tor-Messenger-branding.patch b/projects/instantbird/0011-Add-Tor-Messenger-branding.patch
deleted file mode 100644
index bc2056e..0000000
--- a/projects/instantbird/0011-Add-Tor-Messenger-branding.patch
+++ /dev/null
@@ -1,5134 +0,0 @@
-From 72f56373a20dd93e1976dd953e9a9c77076b7275 Mon Sep 17 00:00:00 2001
-From: Sukhbir Singh <sukhbir at torproject.org>
-Date: Mon, 10 Oct 2016 18:56:27 -0700
-Subject: [PATCH 11/27] Add Tor Messenger branding
-
----
- im/app/macbuild/Contents/Info.plist.in             |   2 +-
- im/branding/messenger/Makefile.in                  |  49 ++
- im/branding/messenger/background.png               | Bin 0 -> 1143 bytes
- im/branding/messenger/branding.nsi                 |  13 +
- im/branding/messenger/configure.sh                 |   5 +
- im/branding/messenger/content/about-credits.png    | Bin 0 -> 15182 bytes
- im/branding/messenger/content/about-footer.png     | Bin 0 -> 764 bytes
- im/branding/messenger/content/about-logo.png       | Bin 0 -> 6681 bytes
- im/branding/messenger/content/about-logo at 2x.png    | Bin 0 -> 13886 bytes
- im/branding/messenger/content/about-wordmark.png   | Bin 0 -> 3754 bytes
- im/branding/messenger/content/about.png            | Bin 0 -> 9880 bytes
- im/branding/messenger/content/aboutDialog.css      |  48 ++
- im/branding/messenger/content/icon64.png           | Bin 0 -> 6661 bytes
- im/branding/messenger/default16.png                | Bin 0 -> 932 bytes
- im/branding/messenger/disk.icns                    | Bin 0 -> 43113 bytes
- im/branding/messenger/dsstore                      | Bin 0 -> 12292 bytes
- im/branding/messenger/gtk/blistWindow.png          | Bin 0 -> 1003 bytes
- im/branding/messenger/gtk/blistWindow16.png        | Bin 0 -> 576 bytes
- im/branding/messenger/gtk/blistWindow48.png        | Bin 0 -> 2089 bytes
- im/branding/messenger/gtk/convWindow.png           | Bin 0 -> 1126 bytes
- im/branding/messenger/gtk/convWindow16.png         | Bin 0 -> 637 bytes
- im/branding/messenger/gtk/convWindow48.png         | Bin 0 -> 1563 bytes
- im/branding/messenger/gtk/default.png              | Bin 0 -> 867 bytes
- im/branding/messenger/gtk/default16.png            | Bin 0 -> 520 bytes
- im/branding/messenger/gtk/default48.png            | Bin 0 -> 1178 bytes
- im/branding/messenger/instantbird.icns             | Bin 0 -> 21624 bytes
- im/branding/messenger/instantbird.ico              | Bin 0 -> 7262 bytes
- im/branding/messenger/jar.mn                       |  14 +
- im/branding/messenger/locales/en-US/brand.dtd      |  10 +
- .../messenger/locales/en-US/brand.properties       |   7 +
- im/branding/messenger/locales/jar.mn               |  10 +
- im/branding/messenger/locales/moz.build            |   8 +
- im/branding/messenger/moz.build                    |   8 +
- im/branding/messenger/mozicon128.png               | Bin 0 -> 16878 bytes
- im/branding/messenger/mozicon16.xpm                | 193 +++++++
- im/branding/messenger/mozicon50.xpm                | 314 +++++++++++
- im/branding/messenger/windows/blistWindow.ico      | Bin 0 -> 9662 bytes
- im/branding/messenger/windows/convWindow.ico       | Bin 0 -> 10058 bytes
- im/branding/messenger/windows/default.ico          | Bin 0 -> 7262 bytes
- im/branding/messenger/wizHeader.bmp                | Bin 0 -> 25818 bytes
- im/branding/messenger/wizHeaderRTL.bmp             | Bin 0 -> 25818 bytes
- im/branding/messenger/wizWatermark.bmp             | Bin 0 -> 154542 bytes
- im/content/aboutDialog-appUpdater.js               | 576 +++++++++++++++++++++
- im/content/aboutDialog.css                         | 105 ++--
- im/content/aboutDialog.js                          |  80 +++
- im/content/aboutDialog.xul                         | 257 +++++----
- im/content/browserMountPoints.inc                  |  12 +
- im/content/jar.mn                                  |   3 +-
- .../en-US/chrome/instantbird/aboutDialog.dtd       | 139 ++++-
- im/locales/en-US/updater/updater.ini               |   2 +-
- 50 files changed, 1695 insertions(+), 160 deletions(-)
- create mode 100644 im/branding/messenger/Makefile.in
- create mode 100644 im/branding/messenger/background.png
- create mode 100755 im/branding/messenger/branding.nsi
- create mode 100644 im/branding/messenger/configure.sh
- create mode 100755 im/branding/messenger/content/about-credits.png
- create mode 100644 im/branding/messenger/content/about-footer.png
- create mode 100644 im/branding/messenger/content/about-logo.png
- create mode 100644 im/branding/messenger/content/about-logo at 2x.png
- create mode 100644 im/branding/messenger/content/about-wordmark.png
- create mode 100644 im/branding/messenger/content/about.png
- create mode 100644 im/branding/messenger/content/aboutDialog.css
- create mode 100644 im/branding/messenger/content/icon64.png
- create mode 100644 im/branding/messenger/default16.png
- create mode 100644 im/branding/messenger/disk.icns
- create mode 100755 im/branding/messenger/dsstore
- create mode 100644 im/branding/messenger/gtk/blistWindow.png
- create mode 100644 im/branding/messenger/gtk/blistWindow16.png
- create mode 100644 im/branding/messenger/gtk/blistWindow48.png
- create mode 100644 im/branding/messenger/gtk/convWindow.png
- create mode 100644 im/branding/messenger/gtk/convWindow16.png
- create mode 100644 im/branding/messenger/gtk/convWindow48.png
- create mode 100644 im/branding/messenger/gtk/default.png
- create mode 100644 im/branding/messenger/gtk/default16.png
- create mode 100644 im/branding/messenger/gtk/default48.png
- create mode 100644 im/branding/messenger/instantbird.icns
- create mode 100644 im/branding/messenger/instantbird.ico
- create mode 100644 im/branding/messenger/jar.mn
- create mode 100644 im/branding/messenger/locales/en-US/brand.dtd
- create mode 100644 im/branding/messenger/locales/en-US/brand.properties
- create mode 100755 im/branding/messenger/locales/jar.mn
- create mode 100644 im/branding/messenger/locales/moz.build
- create mode 100644 im/branding/messenger/moz.build
- create mode 100644 im/branding/messenger/mozicon128.png
- create mode 100644 im/branding/messenger/mozicon16.xpm
- create mode 100644 im/branding/messenger/mozicon50.xpm
- create mode 100644 im/branding/messenger/windows/blistWindow.ico
- create mode 100644 im/branding/messenger/windows/convWindow.ico
- create mode 100644 im/branding/messenger/windows/default.ico
- create mode 100644 im/branding/messenger/wizHeader.bmp
- create mode 100644 im/branding/messenger/wizHeaderRTL.bmp
- create mode 100644 im/branding/messenger/wizWatermark.bmp
- create mode 100644 im/content/aboutDialog-appUpdater.js
- create mode 100644 im/content/aboutDialog.js
- create mode 100644 im/content/browserMountPoints.inc
-
-diff --git a/im/app/macbuild/Contents/Info.plist.in b/im/app/macbuild/Contents/Info.plist.in
-index 615e4e6b8..ac61e6134 100644
---- a/im/app/macbuild/Contents/Info.plist.in
-+++ b/im/app/macbuild/Contents/Info.plist.in
-@@ -11,7 +11,7 @@
- 	<key>CFBundleIconFile</key>
- 	<string>instantbird.icns</string>
- 	<key>CFBundleIdentifier</key>
--	<string>org.instantbird</string>
-+	<string>org.mozilla.tor messenger</string>
- 	<key>CFBundleInfoDictionaryVersion</key>
- 	<string>6.0</string>
- 	<key>CFBundleName</key>
-diff --git a/im/branding/messenger/Makefile.in b/im/branding/messenger/Makefile.in
-new file mode 100644
-index 000000000..b4309568e
---- /dev/null
-+++ b/im/branding/messenger/Makefile.in
-@@ -0,0 +1,49 @@
-+# This Source Code Form is subject to the terms of the Mozilla Public
-+# License, v. 2.0. If a copy of the MPL was not distributed with this
-+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-+
-+# Branding Makefile for nightlies/unofficial branding
-+
-+include $(topsrcdir)/config/rules.mk
-+
-+export::
-+	$(NSINSTALL) -D $(DIST)/branding
-+ifeq ($(OS_ARCH),WINNT)
-+	cp $(srcdir)/instantbird.ico   $(DIST)/branding/instantbird.ico
-+	cp $(srcdir)/instantbird.ico   $(DIST)/branding/app.ico
-+	cp $(srcdir)/branding.nsi      $(DIST)/branding/branding.nsi
-+	cp $(srcdir)/wizHeader.bmp     $(DIST)/branding/wizHeader.bmp
-+	cp $(srcdir)/wizHeaderRTL.bmp  $(DIST)/branding/wizHeaderRTL.bmp
-+	cp $(srcdir)/wizWatermark.bmp  $(DIST)/branding/wizWatermark.bmp
-+endif
-+ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
-+	cp $(srcdir)/instantbird.icns  $(DIST)/branding/instantbird.icns
-+	cp $(srcdir)/dsstore           $(DIST)/branding/dsstore
-+	cp $(srcdir)/background.png    $(DIST)/branding/background.png
-+	cp $(srcdir)/disk.icns         $(DIST)/branding/disk.icns
-+#	cp $(srcdir)/license.r         $(DIST)/branding/license.r
-+endif
-+ifdef MOZ_WIDGET_GTK
-+	cp $(srcdir)/mozicon128.png    $(DIST)/branding/mozicon128.png
-+	cp $(srcdir)/mozicon16.xpm     $(DIST)/branding/mozicon16.xpm
-+	cp $(srcdir)/mozicon50.xpm     $(DIST)/branding/mozicon50.xpm
-+	cp $(srcdir)/default16.png     $(DIST)/branding/default16.png
-+endif
-+
-+# Now sort out the branding specific icons
-+ifeq ($(OS_ARCH),WINNT)
-+	cp $(srcdir)/windows/blistWindow.ico $(DIST)/branding/blistWindow.ico
-+	cp $(srcdir)/windows/convWindow.ico  $(DIST)/branding/convWindow.ico
-+	cp $(srcdir)/windows/default.ico     $(DIST)/branding/default.ico
-+endif
-+ifdef MOZ_WIDGET_GTK
-+	cp $(srcdir)/gtk/blistWindow.png    $(DIST)/branding/blistWindow.png
-+	cp $(srcdir)/gtk/blistWindow16.png  $(DIST)/branding/blistWindow16.png
-+	cp $(srcdir)/gtk/blistWindow48.png  $(DIST)/branding/blistWindow48.png
-+	cp $(srcdir)/gtk/convWindow.png     $(DIST)/branding/convWindow.png
-+	cp $(srcdir)/gtk/convWindow16.png   $(DIST)/branding/convWindow16.png
-+	cp $(srcdir)/gtk/convWindow48.png   $(DIST)/branding/convWindow48.png
-+	cp $(srcdir)/gtk/default.png        $(DIST)/branding/default.png
-+	cp $(srcdir)/gtk/default16.png      $(DIST)/branding/default16.png
-+	cp $(srcdir)/gtk/default48.png      $(DIST)/branding/default48.png
-+endif
-diff --git a/im/branding/messenger/background.png b/im/branding/messenger/background.png
-new file mode 100644
-index 0000000000000000000000000000000000000000..e52f31d051010215470ae91fc84a6d29d8645efa
-GIT binary patch
-literal 1143
-zcmeAS at N?(olHy`uVBq!ia0y~yV4MKNIvh+uk)*3dQyCao>^xl at Ln`LHxx&cHz`$`p
-zA^rckS&yY#68IF7*cF^29NIQC at FX%y9%3?TVNK!SJ|Q4BK~YD+nS2RZb^!_u=wWAI
-z`2Qd1T27!B8W#Lte_QYcM=NU%2lovDu?>nk3C<A*fKKL3WRyO{WY#jk5-g*RrBPgr
-nhAgd8IdLJ|3(S81|1&c<eez%YX0_TEAeX_@)z4*}Q$iB}lQ?mb
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/branding.nsi b/im/branding/messenger/branding.nsi
-new file mode 100755
-index 000000000..4683827fa
---- /dev/null
-+++ b/im/branding/messenger/branding.nsi
-@@ -0,0 +1,13 @@
-+# This Source Code Form is subject to the terms of the Mozilla Public
-+# License, v. 2.0. If a copy of the MPL was not distributed with this
-+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-+
-+# NSIS defines for nightly builds.
-+
-+# BrandFullNameInternal is used for some registry and file system values that
-+# should not contain release that may be in the BrandFullName (e.g. Beta 1, etc.)
-+!define BrandFullNameInternal "Tor Messenger"
-+!define CompanyName           "Tor Project"
-+!define URLInfoAbout          "https://www.torproject.org"
-+!define URLUpdateInfo         "https://www.torproject.org"
-+
-diff --git a/im/branding/messenger/configure.sh b/im/branding/messenger/configure.sh
-new file mode 100644
-index 000000000..7e580518b
---- /dev/null
-+++ b/im/branding/messenger/configure.sh
-@@ -0,0 +1,5 @@
-+# This Source Code Form is subject to the terms of the Mozilla Public
-+# License, v. 2.0. If a copy of the MPL was not distributed with this
-+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-+
-+MOZ_APP_DISPLAYNAME="Tor Messenger"
-diff --git a/im/branding/messenger/content/about-credits.png b/im/branding/messenger/content/about-credits.png
-new file mode 100755
-index 0000000000000000000000000000000000000000..5df30c77fd5f82a1de8fe54f7ddb00bf48006669
-GIT binary patch
-literal 15182
-zcmX9_1yozl)5Qty?k+`(JH=gE+ at -ina4RkaeuV<XrNtpo++B)8DefAILyFt?_<uPs
-z56I!X&F;+HxjS<=PD?`(3!NMt4h{}WSxN3a92~qf at Ov-_1-Q>5wz&X5ki2A+bwI!?
-z2=p-)_#4e#$<Pb<|Ap5#ybNo$AMhcWx4eP(2RB=9UrSFLIA331E(cd9FKbJ88!k6b
-zyX;eOayU3zIAytaI(|7Po&G^N`u;ahoy|)mC+Qr9m&9kr*As^BN(lTM%IHz)GRF4#
-zmt9fKC&qsETZNxw3ad<&R6ofqrQ*xT2(r*&F#hzQWYMr1u47oKvl&UL3Z4&?n4)R6
-z{W0^Fe9%*HQYasm8EAW|dpADS?FBh9Q513C43nn+q9a#zgl8p at to~r4d1LXT9lmyl
-zQ+TGt;lX|%^l6LaDcEX4_~#&;w~tSq7j$wvr2B95*;%%*hORDG+W|eHeC9=7-4X{X
-z4mD%;gvJA;x*97?hh3gMjh+<K^LojSq?@Gg<<8gJdwONX_<D&1U0yqWK>#zN(P;rc
-zP7dx|Jb8WHEQv<yxo$N<a)m~h{>#@QyN9^EAgg6)eD?6K9Hbt;BH=GXWXbv`-X6vW
-zbZ{JF+nIKGY)jmD91>iF=o9QA!NI|lBA!T7Fx$uH#h=!LCm-LAw1JP9Pc2O%FYm;k
-zo}T!qLz!7kND8{T^1MYSdV1i>b>h86O)sA^70?Uh-s6Su&a`U{co*{iX3 at qiU|oz8
-z{I(}ly!5x|KeP#w9=rVD^dL#|I&)LM(L1c~|1=^k+};0!Kp<qM8)|>%=6(iT9pc~U
-zZk})T*P|a~mXwx4iCSIZpNKl!<SxnSem^h<91i^BCY-L)h7;$EwUe`xh}piCVIjm-
-z_*Pg*hfO0X?$RC2T2&cAg7SFt*E?%#%aU at K%@yj|>c1AMu0HXZ%hSRlY-?-FKlkV=
-z(mM=)#02!N0UAe!EY~>8nui!hl4tlazH|nGH7|l5Zp!B7bgka!X1yaw2F`S0FN(xW
-zxLT2vlvG-quxN&LtJaN|b8P$97lu;s`hw_tIHnX4p0{gddX7V9=n(9lSq7Uah6dWj
-zkc_L_EksN#tckX>ct_z%6tkS*41ZpJew~hWwYAL+y+8W*D2yrkVxK-Ot!2>XY&T6K
-z*i3x at 1+_rN;uuc6%x>;=3v%H@=?C2q{=N<ZN~FwbbgFD2K!~O0*g&Qx=>g^`6VG=P
-zf}GC0wRW_r_yG0oP8t1z!20FuyRqx<dnk4r at 8+1BB$}P`RSqm8aX%*|y{AIZg?Gc|
-z^KroNF5R5TVBtJ%#$G~BR~p5oWZ%#w8jXZw&olKgpNgFk%ISlNV-jWUq^<RzK|akj
-zrk%XWr1=f6!f3-Yl$5sdF8kL^wkjOe at Yd4gyYyrXb5+WK-<y+P!b{oDdneBKOs6x-
-zcOgt^^vGKDY!Qc9d&5@<Gut;6X?++A6K!sRfnpNhu{pItWrU`i7c;GA430gD+>ve)
-z7^q|aeuZYEMafi|w59|}YHDiYEIFqea42vPGh|P^6%-UaA<YDF0+YO`s at uTejMM@X
-zPQ9xi`o`I?)y4&c(g1<`TPzo}7g)ORzaKs27W4`OVL161QZ6y(BfPy19A+Kglo(|g
-z at eAA9$XA+FZD%ksG2Q<i%%oWVK>VsSTF|nGj4MsbOX!6($g7=0DTAZAQu_V-cj3Ki
-z7G%}!kOe(`3w6$83OM#(8rnp+osG3Wsh>-!?rkz!VoUCJex_n at s+B+>Nk4z`qM)*H
-zG!RP1{lJWON;^S7^xI<B at j`-=2t;RD5_HKQ;p1|~xv!h%mvn+KBaNlHfBbRzV5E<l
-z-+ at FeiE=}QGF$z)xbOxTTSs3%W33d3zrw=8BBfE*TDkYpt!+JUu4Tl8FQq^BG(H)V
-zW0Fx*b9qp~<uY{P65Gf17cG_IO~pd`1jaVK^n2Rp`?eP!lR_K6v!Y{RVetzHXzS_<
-zK&9jm5fK-C?xc0ZsqNO<z=M~@uO_ai>)00Gs4EjSD<c;W0_7#-oeaitvxP{^1{tqJ
-zBv~4Wv32fMIsRJW5p3R1$K~A|)$67r`!w8cp-Hn?<DuW;ILBU5Q4xP;x?lqYdn${j
-zMr8qF2xo6smt<CU_E??}C3d~*nkY84I4f0w+*=Ctw2W9!hO0pr&Xr{PpsNe<<jKiN
-zvSg98s87oBraH*;bF#bqGO1&go52)Y82a~++TSMq`V at s)Wpa-_G&_|wHFmQl>Kw*R
-z&O<vKPDurGKODk(Ewn_X<38#UB3jC6AGb1KnX#e;;8GHppmNS85IB`IH#a*^bdki+
-z&Vvdsf)2ybjme)>co=5YH3lQE(DWBY(5Lb*Yvx3Z3<vJgn2EF3^Yb~(;^e}mX?yBy
-z#)Lh#kupEOys(mDYKXZCl9QAFfKy at IJ1@FA_?|{Y1?~sivvqTHrT-mF6quQr(Y_{K
-zi3l#WP>ql(K at IunXD#84**k(9d&#AKU+v!couP}gOZeDrrAFqR_uA!?ullS(cZfu^
-zB`$W1gPR*m{?rs1Ql=Us{ulo+d}WaiEzZxAyc9ob-F|ejhP7Z@?INwMt$9&rGzJeh
-z7p|Y7AhO=>)%KxKk`)&bW~%V$80hW at ov&FySt-d$1}4AgE6RzasaR&&&djJ+TYNtv
-z_)P>tGH7<CYBhlv9Jw=><T0d<D4_yK(w{It)j2CHgF_dttTUGHv55)RBbI|#P&1Fz
-zTe#oWFJL<LwZp-jG!@<|E~u=nTXq`^9C`R~8o>ALWEsfVZ6PYolC(2DGt&#?l>N`o
-z;b$PbL%}J9&`>E;Q`1-Y^z at 6Hj}Hk$Uj6vykS$cX*@Stpf_za*Yw72c;l`Kh>NnMh
-z1{Bd=6i=>4u_F2Hp$<AxkAjVG5qs(AR^}+tu>a~T#!dX7-!w|esHm7S)wqu1hRZ7}
-zQ%x=6eo$)EVHJ{l5sR|YBJg(ehxq(wBB<y>O8&jeLZ?rQI`1R~3yk|s$Kg#?|B(E2
-z_VowTef9!(W{`a?<5qKKt*KNLi;a4$mE-8c=M#+by?g8AbYn?YK7BKquiWPqY~cmW
-zAXYB;Ifk+TB!S-hk6**c)3E`#OR(M4tC6P3X%F{;7g~x>k<=a6H8wjDYYwvMwERsh
-zJ_}7oQ(&3ce;+9o_=9;DRS89tK_!Tphkv7beo_)sh(Sgzws7xG#t8S9foG(_syrTo
-z{Kc>m(V$dWZ8hjq- at r{4J&3hy+995_duW`V4S?88#AY9&q3PaHoauhdmEP at S4Sfr6
-z;@L6#p!d_$!rZ&Luj5GtC`U(6T(GS#3n6{=MYpG(bvvB6al3K38di*ZR7Gl$=}P-O
-z<%R+^Pf at s(WIn3l#3KbX)87`r5`JA9`9k6ZSa`zSXhsACGdl|uNgoPbLgHS1Wc*XC
-z;AWJQmRB0*%)T%-%LA(NQpj8ef@*5WH0_5a_o7gj$NNx!yQ0YXkKTh)XWPQwiFd_K
-zlX4BWY1`h&?hxdH*U%x_<j<4cJm7w_tPkp4TqNyJr-9=gdN8cmR at BS?n;R-R@>Bbl
-zK}g%En(1H|`kRWN41Z_L``_H=qobJvunrN}g9hqrDr4_)5HH;hR-YZ<SEq!h`k-Pm
-zh#A^-s%lA#s(E$K<tFHX;aFQiKIwGX{;LKxFm>ePdB<H$=NrT44**>JK#*&o=3a^y
-zoYxJJq9Y~C)av{|R)%$FrBfh+U4qI|qHmv1FbuPE{%7;FL|H$G+Sg`o4>lz7E`9o!
-zxzI<snF)|GZ&7u6Ue)Ib2U@@~<+#2V{$A(>Q2*KayaUp3IrpMX_ at 25SG@Zfa36zPM
-z=iX<2W at bUxv`SjAgz6 at yM<;OUQ;Kno06 at OlAS6e(6Y|9g-D6w;=F?3UaTXuJO-Wlm
-z*6a$yqsFMTSEF}DREi`Pa%$dMM`+&k9#Hbh at egu;3ouK~H#eXP_`48XtW-KXSi!wl
-zrt>KMIzvwc?bT(014QoewgjmEkN0ferivi#D#y23F$Cqm%WA{Taj)(^bbSvj|L7uR
-zSIf5V>wooD>Tlq6AJdyBM?MjXfcg;0LVw$Ob>h!`eij_W*$ae&OaB49V;r&hq^=Hu
-zHIfy*;HZtsCRbFkKos<|XW%&t;piv`ek{*+;onDc6t57Y at uGu&aKD15`d!*B7c6fF
-zjGt8a#)edF62FD)`qAQW)2*M^rHt*>awHgVL_?0gmBitO+w+TZ-=NlEaC{lZXx``O
-zu-~cL2+Y%`tjTiZLYkJ8)g_U=qB5)vI%}inSg2u#eZ=uD?V;+P-{J0iIlgRekKWv%
-zxh^gE#Qk;dos_+&b}Eg$hK`y3KcZf+se+;+86_oSt_C9P=$`mLAc`|tPJh4Ay4etY
-zxPgc{-EbV;YOl at -6z8J~ggT$LK1Z=>Ikr9Xx9(W~r_#$QrZP;Me-uu09C>5<J|G7o
-zV?FNXzu@~-RwVTE#axz!3#r0j at 0arbg$qIHUrLZh{sMDkj|Zjrl&tnwL-|_n9TK`+
-zl|SduTdv)PCV~j}qsh$nMx1Uqoa5}L#s5$ycsFv*R*$DtT|ZCc#6GE5k`6UA%I-(J
-z(%GOH%p9f+3(Am!UF#`W{9d+BV at I>F<bHcs37dd80sP`B+=J#_nzlwvA))v!|JO>c
-z&@ryE<o>1EjJI6xJ``{r3u*7 at SCNhOY7xJ$u`p5>4+*H0REGbmWQJgNq$hmOqgHWi
-z;vOb#h-y$^y~s_cE5t;^OnpwGupH_b0*huzo$N&n?8zcr>pZ;K7?PEGMuw{>*=h~x
-zjdl}92o0p-sIEL-jSp+tYHo^@Iu-tUv*PY*wR)jO076nx+0m4rMEasMN!TmAz73mh
-z^Gyo^#zKbAIl2M6gAlI%1EoJ3$cj3fA)%tA`PX1))LT4!2tWSuCrj#X;H5unjGGmG
-zvkfNnv&;q$XRV29_EXI|&I|OUiz0^`KG<qi3q;CG6b*a6wJa9EHAhc<>EeqsWm;w)
-z269hEZ2h)l<okPqtYbKgn!POPt*CcVRn<IKQnI>>S~!V6FQMO7DfPFWOOdQoRqWSp
-zp=VoDFIzQQjd8tV!*#b0FVFN&lZH4w2H29JIL9ZtWWU(`tnQz5F7qo`|3p6aVfvti
-zT(@lgC9!1Hz2nnaW`@0=q5~Mu<@>ll+l?lX^Non-roVRaPt$~@&)Yvgpb|Cx37kd1
-zWUs9-!ks5dN=%c=I06<|9EC+)&VQ$Uy-%?_gaEEh(!+DC0VLlSw3p;|{*2*fvAN3@
-z{r<du0|b%Kl>bmD$WewN3s&l2Ed6If^7+SBX2WJ?f4Cn~x&S+elTKO9dyRIjei{3W
-zSNCz)gmj=Z#I;>TZN}gt=<2 at lp>Ha!4OQyLixNF6c2P#qTL9^R_jfoIx7JxCG_cjZ
-zk-6J!-{e0(XC&PG_)8$=JJ!(SRqj@`r`r5P(Oa8;y8u?Hg at s8M@cj3|f#&_vTICFH
-z(OXCMp79%@4^C2s%be;qTdfS?V!nQlyOtTb+ at Sktc(bfP0-2nqz^_2)iBQSt`c-EX
-zQ3n%#GpNx6 at mjz27V*Rumn!(#HOV9#A>a at zt#xBh^IL_z{j&}7&8a8Zgc at jaD52?G
-zQ|iI at b5EqOQz`<A&$?WTpda<oq}fDimj^+<-^&I<ZTBn#neJlCcsH89bf`w56lyek
-z83x87L-_5FE0vPpLg)-OB`3C*wKcQW<}8sBwN=_S{;8weMo}s+AM>DF!r0N47At~D
-zJGkgkB~KG$i8v}ioM;fZ4bIt{iuKm1AWid(vJP<UQu>{K9lAG4j+K0h$;Rv{5zRo9
-zB^N=xS43Lz729P-7EiB{N~l?Ta_O5<-m=*$R9E3?P#ZJvSc6IXnSh at Jlc;auHlF)J
-z;cH>Y8FF%kF52aii+Oz`pMfhM=Nkx=^6o{TD#5Dx`i_84(PHCqy}ABn1S%YIa4^7^
-zecs2LOp at e3(1-4nURLFx8ymepUjkGX81d;+M`$ByaX|$R#XF!qehr^bOewQ+NLDQ_
-z8HmN$TDo&Z7&)5t5>Zf8{vqeV{8GW<D6B;T=v$s$kA=zi7wy|8ZoApt&uDR37meOg
-zs1QWRhr0P%7sJ?#DG#d1qjQ!}SO_HGA#LXd2S;Lu=WCWkk3}GQgnt^tclJO{hvU;(
-zdzyLSOzkDFplzeZ1d8~TzcYl*REv|L64wN-kM$c2+NN#$ZlWxHhyRTwQ+qCUt?c=A
-z7nqP30yzqo06og~F)%}R#J0ZXHyRiIh!aRGq5bKMl<HuQr27^bpy%$wYLfZfT*)Hl
-zI-6CF8OvIKHUIc*HL*yX25JzNHvf&DG!NRcetb56;-!5or|FXg)wFbmz9c-3_ at 5!s
-z;-X(3tt-Z3<8IN3<M3td$htkeS<aV0lIH*6zO$zw?^+dxdtM#LX`*j|g!%k(7W9ex
-z<zm=l2vP3kdDB<q<`UKetA+Vfci-r*KJ2tFUG!j61_rFF@&Bl8(zQ{~RuC751(#K*
-zfWhFw8w2Ur)sLdZ9W;Da_^ch8<nEz7{x+`7YYQG#kw2Y9oSfmgVB_LluMjn{w>r8H
-zKc~w+joY36ym>92cr&XlvSoiZu8h1cUS7-x_pqq5p>7;<@|S<PFa4<NmoL22LUPR9
-zExs8OVofMK>^TU&p1=C3rlPwJmdET3TfeHVUnqn;%|5{0W+aDvc?sDbE(3X+?u{OC
-zLF1d9ZM-dFQQZRn3v^qX{M1P>_Mh!#*PB&Xk*aFv=)GWKaiZghf#thlcCwf3&&LR=
-zj2Mw~bwon%lS>@@^7QdR{v%jX->u0_9TEfc30D7k)yO?Uf`;cFH_OEgLe~S_A0fwo
-zATC>-^d|fhFC&3 at J-icSH`SG at mr-s{RK5S1H#=GAoR3KerYSh#+^EUfuis8KPp@{w
-z3U%F3A<2aNxZ7MuT)p|;&K#-lM{ANY$LspovvOB+Vh$bdekKmRB{?gyycqaLNLNs~
-zVg2BmeI{jb at rRCN_FCTUl7C=i+`s!S$n16Xk!jOZc+dN+j~@@u5dTwRoCfCtrJ`BM
-z8;oH}YJb~pR0xGA&2wq;MPBmb7C(v596WIo4)yWw)cQGmRR?kpx7aByCHCY2As#i(
-zMtel}%P%Ps(?9z}qQ*k$ILCg}j|;*694lwf>l at 7p?i_u2rFlEop-+-HFT1XAha^Jh
-zvv#fwg#5U97<tA)xr^85CNZVH;$zqO5`8sIXY|>eR2n?|2JJd_V=B2>au(}H(PgDq
-zHL1>ZBYMtRC6 at X%yDcA#IU+^%wIfvw=ZXk&`Jb-}LvK~rVI-ki+vfv>!$PSPIYCl=
-znM-WMO&jhL{*M<gfx#Xxb~s`UG~6Ey;f2 at Ftd@4xHk_L9RflGDqV`JynmQjikr+Za
-zpFc=EJsy~cZYI=2iOgBtFs9`3sG(*pdEF0vF)d!hq30u^_g<6TeiDa%aw|Stt^L?i
-zL9|m;Vs(@Ul$IQ65I>2n3`uFaFG?y}x<u-;!ewp+q7QJosYCE<o=k at 9J=0s;V3h9F
-zo%ZIH=bhn>qtMO->FICofqY1k%wq54{g|w+vgm_mvbPCY@}bGkkJa8jIh$K2nh56y
-zW(kLWu|rvzQBTuxanRN4b~kFNeAS&Iqc)&OwjEvRzZv5Tf8Jm76xRIIYg|@YgRrHs
-z`tX%G5~Gia at K4KrTSCh|Cv<kfD?b0}mhQCc$>Vo9WnS2%Ys};+zk(^%1<?ef<2I6R
-z#(#&z=CWD(mu8~UOCOC3N{&RcO0?HH!cP>DWI*CmVox4D7fmG-1%;y|d8xwzx4rt^
-zVn==(&eosu#CRo3%ZrY?qE3=S?}Muh&lbi!C4hib7L*DOn()~ArECtD7}mSzwx;Lp
-z%^to#WCUrsAn)Vt_H*FMhGyqK_{8m4cN~ee^Zjcd#==sT{P)H8e70SxKj!5=AS=r$
-zVaf&vlc&K6XRX^mJuj6^!@vU at TDh1}zE%EHl$yqHKvp)P)y^W0 at b#OQl{k=RmCVe~
-z4 at D?${qcJj9)&NhtG(FfP^9;C)BR|A-`<7?k&vwH&s(H+>&x~#YxU8FBa(kN_-4)b
-z_s`Vk2+^R^u}~G$&iwj}35?S_b?T`%o!$KsW<Retk=;7J`n}cL-X#{$Nv%rq*h|zW
-z$=}M$UsWA`P9mc+?<Jb#isjn+ZxZWlbri?#jx_)7IMA at W5G(_ViBXn#;%Cql|1`G{
-zQ&GV*@j{`*n1cLn0gTyi@%MMJF!d^!KNjkbgzyQOV2KG!bd2PILI2JqFZ5xzTfL<z
-zbLgK6eLvT_pM$;bhd0zhgb-O5aO70*UrkWdBdyX#?Xc|BH>R8UkRW=c`jcp<p|vcb
-z5o8%JYpRUSCoDOF5GI2uf}p387ml-A=7hp?+XMFYviRZov4wLt^A}p7jmLM84o|C`
-zY4uX&leMvP0!@p2QGpAb_zD$N)@)~tH6tS<5E8=i3E1C~KOAy|L5vB%*v4zXk^QoH
-zg7edNcs+h#+$&f4F3zZYTEq+WgI=}Cz_8SX2H{}0-ve*9M9d at aNFi@B!Bf}MELQHD
-z^(GgSA1Z4mvcW_ba*-})LDm=kd5>4K$NrC*R=dqPJJ}o+d}q))9~Zv-`#)!woiEQA
-zO)e`vw<p^r??0a|^`9qEEg~Ya#=la#a4S-jXv<o^3#;FM`ET;8=#LID4iTL2$tm>J
-zs;ciAH6JM;E@>yD=nF&jRolE-khD{=4>$hNFq4oa$MqLQec~zD0E~I~-sGCHF24Rf
-zSIZ%O_k)<Mj=uc#Z=GQ#w<VR1fTH`usqRqCnF-zPTjuL*eEv*1FIBAk$KAvrm~rSN
-zQ$`h6$m!>#w{?L+{bIiVziLb92(LB5x0#q^6d at wD_V19jv<bPEaOv%D=l7?(`d6>M
-z2SSfW+pZ(w4zrBf&M4V<qt4F7*KcAn>Rnb)dNeh<-0YIBtqImPZi04kg1=;a)fZlB
-z6!^m&D=%wuxv!cqEPma?75xxnma_9kblA`~xXPd_b}Hn0Z8ZpnDgw>18Js%VvSbUZ
-z8)^EFlMo#b6Gh}^)eBGNzX at 9re&XG-c6+lcc&Ou6!D!Tx%peUcG~^=YN3`OYf_JVm
-zA5((|JjcpOE at S+MwYg!*YoGZl2b3OfIggR?MkoXt?n083kZ+umCA2ic1~STWY(2=r
-zn86AapY<>~ef}%EN44=4<S}yn^&va1(JA}xGGk*{zw16^zS;@?BYlH&9j8485&{we
-z{G`N<Nl!kNRTgu%GIy_lh8uEyc}~5kQgE8oJ6~_V&u5P?PMh|cbw<=Ohr@=alFpkF
-z4D(OY($M<+V4+5E at zg&>nkS3QpY3tHUH4f?0*%Uo=5^(M$GOdqze(1YD9uN{Z4-XU
-zL3LW-hg~=4YpScOB?0AMj5x><QpCHgtgQH*uymU*zC?Kq`h^b5;c?X^>?VPh4Wzht
-zOE_nC8+q4;?KP*2sKT6}xBli+xs75XnORw+#@wbKg1Wu0-a`CV(rkuKnTKu(#fgP<
-zeqK$GkR+c;c*L{N1iCJJw=CJl5nfj!X at ahgMf#vpFJ7)KTdG0NFey8GR!*RHVyJ{J
-z02k3qn=R-<pR2(T*~70Mki(8GmWXjEOyT4`X?{c^c_rRUB6;UB?(8}QsTN}crA!$g
-zKVC^{P at YlX6zFgTA#;pvEp!JI-aZG1!dO^k#t&|7;|~S at Fxwlqew)`-jfb}E%*T{~
-zpd3jxGSG!3|9H0$SVqUgP1lg3)IB0~(7DLvo$?E=&SL|9+z)z$PjJze?m%y at KKQ{0
-z at ZS;#{N&-KnkvgLLUL;L`;yvGCUtCT!)OV;ycyPtfp?P=zUSSNkJk>f%gj^BRAd at 3
-zUz(S$(C%mjFI7&LYH&l--0ZTEqLUMqYWg2M%t<c18<&l-bHBBRAtrT`2Z+$b at vSYI
-ztv&jm1?I(olc>jAEfP2}>a{WH7oJ9epN3Q$11%flRubYlTU#;t&`+p&dxIo_rNK26
-z<dqAYmV*_{Yyc3*5MZL9#q{U+uKTmb_ib*{&dtrS#)n5tTHno?5G=)%aH!ESo9g<_
-z%JYUiZnDbsR7?5Aj at 2yoEQ2|jygo_T?d#5SuIwGmgd|a)aNn6|TWDJoRjVG_XET0w
-zak(0>qI-tUQw;{cY;teJl(4<pytGCwXkI7(<7|{u>jNt9kiu_2$go87OV&-W1v4+F
-zT-qA`4GWSt80-8IHVm*5pS*xW9*FTFwywI(T$Zh1PUq*V>}60iCUt8lcYN8$JMTET
-z_q;$Yd2MYXj)2AQ<zYk9&W<Hp$gQNYF-_}N^6Gq&<P?!WFh;;yOx|cM)B-!K$tK};
-z-&aaT`a^=uW#5+B{k`JB8C7Ao+t&}B3^|9em2<5C$xid48QRRx<_X<xkSsB5fQ<~M
-z{A at 4ZtG4Cx2cMs#xjs!wh~L(mBTm<rWf`B|^Rurr4hwly*%(nepV at A7ab2H?O+G)F
-zeoovgS^Hkp6JJkUzja((wNdxg-kaW$8tre;zFR0gu<NgzCLDs3EyUF~1ru#N?hBET
-zkpWGpEcZp48ZkVBkxxJQk5ZOICiO)0bEt~HuUPS)cplr+Y`oN<-u0kD*gdqil>Tel
-zORzWYD%&*}^CUf>pdwK;XVkn(<nd$I&5;z!48Mi%c;F7nxA;Yx-y{e=p3GevNjz(A
-zp&OCcciq|&%kKf3+&@J7U&cL|cwab1LV4fv4|PG4>dsm<t|dZ0%c2I><}O9hRI5 at f
-zx?jH+%<cRvr`vGrKRsPm8UJ3NXm4bL(#oEP37Cv0Gbt5Sab;x!A}aQI-c3i00msnc
-zT&3YpE9Cg?7#Gc4@!rHMsy`^Ur&(QuNmoXzmt)#Jn&8&EeVjT+U4l(tB3Qcmr1!6V
-zm&<gC=fh2ZzOk^Q0L(mcSd at nep(Z7b#rfCn`v89Gy~*qLxIua%v98SPmCys>jr&ne
-z|9}`89mDpnG{C}(sy&i{aB$?^uUdecV{Hv at tgpeg^124ACjHBaF3ys^B8^uB^4bEr
-zh0J(`U7{-VqS{K^H81yp$7?HW|C<Srz$5!D508$3#Nf5q87OoYl&8ilD}D-{)Ljs|
-zOh{#Wu5Cn>H6^8~Yhe4epJthN@@uP&+Wc{w>Ty`;8B=yaix7m0)%PwUORi<NrDN|u
-zA*#9(_4S5f^QQu3S!*J!MBTyQZZFt%5gbIqE;m1#FJdSA_;H`ze at -WRGo^Bp3w`s`
-z)38YGi!dLaW~5<V!>9D70Hcig+24Aav|8*oBL=be6|4dyJQeTTG=9x|e*(Tc+Ap9H
-z=&1mT>5r75>)Ya4X>zd!n%6+nSsUoBaI8>+klY!t#HZc7OlQlH+pj6OV`t~wc=`7|
-zca@|zZj(`O&to=BuD at wXvk*>~$H%BhHd8K;40#Ouom=2gp$5ipNL^K~b%3wH9ao(T
-z7lEMxhzUlAESE55j5Q8<4GcD}xj3FT`a-j99ba}7ndzI`ATu35()T at nI+-p@>#92s
-z*~La9{$XbLqbm<OsIS at dUUBJWb9EA0^PW|=d3lQ;x61?+R9a1v0Lg)=@0vVwDqW`9
-zdt+nc9AXj>(!s$L{+u|u?EWfCHJrMxy(!^lYrlVF*!8t*I=8u;vGJ3taE1y`0YL&%
-zS$qsy8GF;o?=^`?mxmqqCY$=R@~6jtE6uYPeU^tLbJNp0VrTTF>=tcY at nINTrenI@
-zUR(=Lr}8H5BaV92E|%IK1PagP at M7JyN(IRZTP1tz2Iu(ahT;^%?QPi4ynS&l(rQ-s
-z^as&Uih*8*9sVr;2oy#s=JPoM73aOKt~?JZBXPoAy$F9|kmS_X*WTauNiADkO5xrd
-zRd`tC-Z|&;;G0wIrcO)5pKRD}U5u%CT&*7kgx3A=R5RvNC$j!sCDFpsA?3y-dEIc{
-z)WZr{p2EiB2g_pr%4^suIb);pM;6w(!rmJ#A1X65l<f%EKAyH~fW_55nC29#&+#v?
-zlqJQWp(a|LbhqB#PppWnZi%S{|9$@o{+WF|n4YbaK&HZuX?=NqfS1y&1 at spO2<o$p
-zZbp<N3Wh}L1b_C0n!$ouj#wzelp2Y`i%ny&hxV3hb>mUdA1X88w7oGBk3piN#parX
-z_4O|)XQ=nle*e01SA&ma7t<%|h!W6H{;{!f&SH at JL1dXzS@3_CB_Z3FCDr|)Q#MXL
-zJ9oslEGmR+6MV4~_Hhmiy<3(5Nu#0gPKv4m8WK-tfOt(oc`+jZFmd1gh3Dw#2ttXF
-z`>stWe*r~@!h~gZ{3J)0{m4zLE!0=gm*e+wQIqyYvZ*5?*xvpXCo%Jz4;MFPPusDk
-zd7zt;IzxS9g_nD at Q5$PuVCVj)&jWc$ElEP``l6m at b*j9JE-T|ts*+sE*Sf54Yj`+h
-z9FT-rEuunEVtQh1T%HE2-AC`+h0xZR at 43$gP8LgV8{}k4dX)gH4|^OO9u}3B#thSh
-z<|Kzc?)+I;s1LgHoQIfV^jz!=tCo~=qCr~<%k6q?<NskT1>Ky&Q!YqtluA8uakV?2
-zIONuMhkkx}>JIJsX&n-;qW*hRv&OAh at NdR=GgWUM;&<`uaoo~qmXas7_&#}Kp>v4T
-z;?NSbI)~0>D7*gGCmWHDzv}t2x`c#t=5OS+AH7L!9{G at w!H=C4?0$K)X`@7EpTeZl
-zUwi7FDB8M2D@}lx0?3vZcq)=aC8nUOOH`- at 0(^JRlL^APheBG9rKd29;feFJRzbMM
-zedp6~Qttnd@!!8&j4q+MnA_<@7af+*aVi2?eJS#mTubj|y<}r`hAjQYr+mddI`SXR
-z)(2~7LWpJc9ZZdqOSHb+eliz3SCk5<5<WffM_3?efyC_i2{$FUv>T*H*ob^9NwiTn
-zWLX6Ff?orP8#T&8i4lKmMv-O^*0Jr3H|$XYHbu?FrADvbS`GJ(B3VEsCCwzo39>!Y
-zhI9q+Me_!>{ZbQuJePEB`x{D1eVsrH^!v~47Mk&~rh=#ekHhv{Z)2b5PPP^cf2PBr
-zv+!dbBuGAi=85@!8O!7_*3)F=xp at NI8!+E(!xX~>Yog1<K;`xTzDH3U=@)}YEk-pS
-zN=96CD<n*BS;e^_{pi<L^6vQT%8IJ5uaJa<#N))qBNlhpE&b7a^>;v#aU8DfR&`<%
-z9OV7(w6{T`E7(pd;(HfG+wHdQW53;o1gEwiGYZOwN7%xt<#1BO;M6>4!sYsg!#kh_
-z<ilK|GHx)mrLUQ5b%SBOJ02INDNMO}?`zW29&(0{{{g>|1%L+=-!+nwU{|2zcr7J0
-z20rU9{D(31Mj at Yt`<W|}1u*xerxqysTZu9&;r7pA>VB{(kPkjdTg*2`h{1TtBm7hD
-z|7J}67La1CJ98%<Cdv`!jdfTC=wN)^u**hQhGxhmF*eP0f>0T{iN7n6TN`WK(V{_m
-zR7HjTG6$FYC|?u;xm}||t9x*cfkCm`uf7JPq at ByhuANnXsH>-8LYkcb9wzzhq+J%a
-z)ZGXH9HUcZ>;mIR$y<Q))to*u>8<Z}xR5-Ao2b>}%?{vb0x^GChl`2At4=Uh2RJ}O
-zbMx%dk}}|*va+&(C~V?)u<qY+7JCev*u&C%22wN!4hYWq;}(ZZ55TlIjC2M^(-LP-
-zTf0NQP6h1?hTPBQ4)Qh_80-WuG}c=B*Y0*ej;sucAxFf69h4#XEgEA*xOO$@c**wv
-zu*ANl>$69SB&5Ajjhg0nacvzW>5(%PplQ9E^*)y9Sqzh6zB?ue^t)K{;c7p{B5e~K
-zxr at WUkOg|DyL;dNgV`ApCy;ROZ^h6I at lO;HV8-<G#iz%pC~_$uA;ejL`)JAMg}qmk
-z<0V at wBPNW~>+H4h&%xUyz7m6_l3*v^QH<$j(rwu at 69upuVZNOsESZEfT6?Cmtil{p
-zSw6WLe#MKgo!dnhC<DsR=Zd`Rn5f=q1X=5%K?2TJL~gRGy}K7jdeEds?iPC)#670I
-zI|q;L$yt9<p49xxXs-I&wPVKY at 2TV97z1!0*r5d8oHF6ZxnJ%oFE20Knu<)y?zl^i
-zq-aH#?T-il6frQNp|$h(zA^U8vw%*@n)nX}480e5jjk40(wgwK9RKyDmt)HXRwELo
-z``Xg?hA6I1+;9^vpjcxwEKD?LuA(#BfKT^X(fdB86tu<dlRCB3z)`-JlrM!Q4GzZA
-z?}S!^HjgX0Y at IE>5yXhXlO9rRelk9_ffd`$*0zLL?JF0mG(ksbV*w{lQ7Jw+Jq4sW
-z84w7U<o!&t=iwhV at hR(*<wg$ku8!ji_`yAwt6YB4S&Xnr61q*rl?VTyV^Rx6L+lFC
-zeBbuv{2^ICCeKXX_g6F>d<MgpzBeEk^q`Ey9sGE9dBaQhE>o at KcKr$|aCug|%lGrl
-zzsQ4_K9swh&}3D;CXXYG8?Q}iRBLMo-0+9)K#G;_hx+a3Pg-G`&%+yD6K7_8%8w?m
-zYP^hW3!c~=;X#NS{TGX2>~1lkw{K;<y!d)8+~>Kzm)cWK>dxSg;?9<oPK`HLJ0!TD
-z8>FkPGo((EsE(jwrd3YXY!A6y{n5Qs?oZ3XVMQ;Nnk4xKv=v8pcb+;V-8urRrhnt^
-z_F;K!Yv-<8E%?dA63i*D!!knUf`hSIos&$s#zrTc${fqKdff8lL7$FV#66+?poN{B
-zYGb&q%I<Tj&AzlBX-bS<DI*_+{V#ubZV#XpH#h6w{m$t6A@%fcmR<U7=5E~>*P9g=
-zqz$yL#%tEAp}#LdF(0ruI-VFaI}#9_4XJhxF)HHZ_cIuT2`VaxzpvKQMfQMABXJGV
-z1vp(w!j90cDV1QArHaZn!HSC=L1<EEel5Z!zW;uCw6#A-gRqa6$8IE_&J6D2*v0fa
-zttnoh``rwr{PCunmwS3lKzRzl)XF?@|Mw?<|7zpVNLB?Oe#l2pPD)~j8%yW3hV4&y
-z<uMerJZenfkrPWJCEx7(TP*OnwY5a2M{lm8jw1qcSOf!7ST-dOkkN?1H5izQOF<{Y
-zEN})LRZ(K-2*PG5FCR6f6q6`X=?+A_zq$o)n=9cY6D6D1+X$FHK10ilbrR_#zqKA$
-z$kB^f8>AQK2z$sJ{rx)=5D?J7lIKT%dsP!Ep@$oe!POGBzrQas^#QjxK*FoU&A*rR
-zGeNkNet_gQDo={%?P&6&4S#mJpqJgS><*q;GwCiVCFTBfp@#T^Wf_$4<t{FCPv>TU
-zUI(lW4!Q`;e}^a2z`goinK4BL5bn*lwYB}r%cJfrEmiE^OE=!ek-W7ae2l#SN_(+`
-zwvZ5UGFgwM^n)J)!h+DQ8r0}v%C1X>jb?#H&izS}P!YC1G2R`9G?m$qO;Eba7b<1g
-zN%nKD^@(Bv6fG*^AdC`FHk!d#R8}gN&MJuJV*i+R*l9b0c!`RN{`;<&jN-Cly8tnD
-z26hmW7t*M?sKa{h9v#_NTTySSUyP(dyiA=oRzr&7_*PGCHk88dNZXc@|L$;L{h{|<
-z4<RsdxVxM<`bfWRq7an0-R5*>!Ac)67`d&z9g#&N2juPT9oc<9SHm^=@hy2z3X^Kf
-zK~Vy`<i`Cu8&`a;^ww4OnxL>FY|aC<rL6dixwp7h%8I^$YkjRtHt|V}C>e$7jz6{U
-zBh=-%Wg$c2HU9L0MvaV%OZ69x(uhno=Ec?3;|^Hv+40l*O;@u4sL&e>el6$$n>lvT
-z4U9XK_h$bI4J2E!?v1H*>Sa<g67S5el+?(u#6za1b?2)cceI9iqoWmCpQl_4Dg;M@
-zr8 at qXp;SKT>njRoW7*U%X>n!L3%M-sngpISE?=LlP{0FA2a1w$UaT!Ff`P^6R<qGP
-zz>o4phkr at 5{Tg{ER^or(b*3gz6RuarTTF}+CsFE(ED7~cK)O>ZvRVL9=<b}fwY4=@
-z_Jo3GYfjqOUey?P_bMP^)Ac!BZ3S6ubOi&ux=GQ>I?wBV*U0vv`HP|3gg-|$&H1+j
-z<0;#uo1eE?zO at Nn)Xk%Wx5?P)bKAMCy^3x91#m$~_Rh}yUadKqQ&5IXwV}@Y!^-5u
-z#6*XOo3k3k#d<rOUW@;VRWtOwHBxDBN*6r*|ADH9rZYR9GKjR7QS&Sx-QH*Tb-WQb
-zBqialU at my$P5Cz+(D!s0l~q&}{rovI4u$DS<~MVU)ve#pH&c&(eCuduXP1Z at o-5{C
-zRKf1z;zE==E59={Zdiqpx0`bwhiq)On^yb>Uc=aGHhY<gxY*QcOWT;JU$|2Kl?pf(
-zm6x++PeCV~1)Xf_4aG9XL>A0LpSpk|GD~(~U|?z<^x}3W**c54Qojar+re#+ at E4qF
-zf+wLSBk?4IUc=bLN4GtAsmDhs#tDwHS~jp0--g0>HNBAIj~sor8B5<&o8{-ES>acQ
-zQl0q?^EGdTJfuHAKeN*zX-eKPmN at 9~+dz71Np?>EDNN#k>)3CXCrBEO<1!gOSy&9I
-zOnJ4-yy(8>f8Ae~dt<P4o6H at 9q#Xmdz?BuB4d0F6?DqC{3b?%BYeTi!-98NNocdiI
-zc$_rTeHD!W0TW6|87+~g<#2AH5{WH1>k)(U9(BCV_ZI}SL+Gz0xJCvjD%$0O^|&&|
-z_5iEdtTZ_orU#!iE}Vw!eo+*pk_hldlLi#iKvm)mq{V8Ij3M=}rz6?;Kr8=0`ow!D
-zC-htgb>SXAdcDJI+gKD$pAa<&=;VI_o<@NE3%ag;YvdSf;CSN(Jb9(55qvZ+ at kyH2
-z_k6Qg7cMt97tnwKIHMp=U32>=g11}vh%!&M=8Og|jJ+db at +<zON!;_%d#Iy($z<zK
-z<GWX}UX2y~7Z6Z-n_Ozjtp}cKnC`IR^V|WO<P%UIqY-wu_>L<B=&5#-#7->$mRx0^
-z9g@~uPU)ULol(8tH*M+oC(7{iliFKDxbJa`<J<aiZ@#|z*S#_$eopA~9ob5gSBb;E
-z`YgZc!i3vu%M3uWtfwSyR_~fzP+eB`zbH}{0vsWMyUTChhTYD}V4zj1JBlcPCL3`W
-z#CE-k+9~tZ=hOFkwWw_Q$M^@dS6!gln}Hn<uCCkd9G4Zt1#o?n3)E#rFoVm~kr_Yk
-zL*VuClBl4d9*+BF5B&YZLn{z6%FL;-wn at C^IEaY^1>&$_ at l6MN0=pV<j{&_X?~Zj-
-zxqChO_x~Jt02M-%9DQ$^zF8)o%txx>5u(UxSjXxeG(R*nFz`VHkmfqUfdL)#ifenK
-z*OWwtdbZ%i7?vohxOL5D?d(8nF9Ux?zujq}8A35O&s(R+<`j{>R~dE<oz+iLw}9E~
-zw at Eu6omVuB)6=LnCLu<R>;%cffdBw;fhk#zg|XXxPPR9DBTRgjY#JIG#*d8Hio_jV
-ze;88iI`8oCGKEIxIfm?3$FU2|q;R=AL^k8=v%UgFq9rK`5N5&q*DG$CnI)M5>U`E&
-zwnH8{&HxD)Bt*{@_1yhc41iSiW{sflf~oIM&pj2c&VTQVW)3<a3p;Z&PV==!QoR9B
-z!fltM3JEM?J#zF$%x5*Llt5zzSd}aa*A_a8<Y7gcfP=z&HRjYNjyK<r0z?VXZS<-P
-zc*TW<Tk4vdZ>+}Zwl_28M177)fhBwHXdgsK^l46HIJMF{l*lQ*!QD<{YZMScr%Z?`
-z6&B}ZI;(kf#{J&_-zsamL at BUi6kR*7=A(lorLsmoI_m1Gv&E;VFsE97QQGx0H{bAQ
-zU|^t##BFm~IbQr3(HVFH$hV1spfH$O?nI^xZwMR{{@6HEa#gQ#L|@*~f$?@v1&Qaa
-zY`~bDzTdoq=l?8$)8x9Al{ma({c at Z9VsPZYUgnV1*yNHdlEin|=2}rwV#`RL*u?|P
-zNFZaZ5#eLKq0jMR at 2sZO#QsF~5-?y#<h1Nw*~%~N<}V81SY4xqF=7thi8$V#aKxOv
-z8x~ul?h*A&7d)#txyxnii7bH&XTcRX9Yg_{SW$WHl&G6l6IU>Mn&=e&#L&nvG6KAy
-z%klv5XsCpO0d2XhK`~{i?vdi&cp|~`g#OJ|K$q*<%PLNsLWGTNM2ihU(f at FUk5GPQ
-zWqJ893U^K#YiAo(ConGq$?@{;@luB!3~|U(|BzH%TpR_QE~@j~8})DPL!cY9YF(bd
-zZ_F3QSdnO=N=^=Op at FNYIIom#*6{YXQwg|UH5}A at l{I#RIN00A%732`rISm<En*GX
-zN#bFPR5D7R15RxCxJu@`*?JahOD}-+ASSQpi|m2)-LgIYaa$$bc8 at S2Eu><O5GEzd
-zR{pu4#cdr&nx1Sgue6I#qSFS2#K4t3M~>c~>i5P*z8)dd%Hra;8L&hYcgSCv3<J;?
-zbd-qifSzWUW6W{n<68>PR+DU~|2w#04|_Ma($3CYdwvxsr#GtU9EFXIjoU>SY<PvH
-z4Ko at PmQ()*wIt-J`pdZAVX1n;?aZWHbksRTjK5Vhcm at 0BFf0l|q~CwNt8t5#!D~N?
-zSO=LSV-b~UQ5fr%j^ovsz0w`B5 at lk^yleoPt&N$%VJP#ehJ8Y+b$E|rQ1!1~iA<)r
-zj!C at z-ZSVfFa|D`#oFYdNfiyrJDd)&e;N%L3jw}!G5lSwv^0agJyJM1yeR|eGzf_w
-zA(|No&^s3^z;oz^Jzia!I1<oiwLtxWJ+ie-Y)cU<FP+>fcuh_)+Y}%V>6s;l81*+6
-zKyyJrKw#ELS9dN4jIN91!6chPsH+ms7=poy4LM2yYHaERv;2RB^Y%-VxmH_>UWrKa
-ze<Lyn{$@d|XhS->i5PTNGO at 8mtRA!o111aV2I+Gt6SmpTE3UOJVj5)cI0`D*x7@!;
-z(}r1+0zLT at Ko5~_GqG4yp&Z=vQ5hk9ppXe0k>UK-3**N3RTKP3>@{y_hwQQf at h}xC
-zVO9AJ>u7--;Z4DSQCcc0 at M!5HV>c5lkw5`?8Nc>CCrTUyjnZ{b+Fbv@#COy-+zb#0
-z<w>(_DJrsX4g*9B9LftyZ20MrAV+L6tns+4G6jBl6`;Zj8GFAxNLUgsJaV{9YymJU
-zx$q*^09930nT4y!9bpeTIknk_SX_EDTq#{$h8_465bk?ICQxJ;Ev~1jkkyJ$wabd~
-zN)rL(NP%iN&M(gnM8{7Tse%mA)+Ti8XsxI)YJ=Ee^(#4LrK2MuFaV_$%wOnq&VXU)
-z<fwT*i9Ziu6Z~S2PvPtkO-cn$))YG!8EJpDRG(Ea3%Zd10FWGdwj$Q}- at kw3{{~Bl
-za7E(L7C9Krps~llCzP0ig-6}Q7m?;cqX^}Bfh!WX0=G|#P#zIeUR!4YjF<=gn+GKW
-z?qR^Gn#zg_zI6_HZA!XG)Rr*R#hn$OLNq!xd2Q#Q8NN>)K<tHQm1HLE5Xx(Tc#nlA
-z-ObI-_0;es0K|;@s6Z&MeROoh&}+dn(sG1IA76yTf>DUu*W()*UBvos3I>dbDUFCJ
-zO+_*wBWIY))>g%;LPvPa7QY>k2L<lvbjKcw_Q`H5GN5danGd>+w2_8AgfhFsrsks5
-z$v8CPemrj?zwwT901o_RJg$h<5ikNS=%_6ZP6kNcMDl3m6^@(9807Iqkwdu_ap&cL
-z(p3VyiZ at 9}ehoJ?Siu at zQL&r{ZAIRq2zA4tQ&XRHrjzS^+7q9mfUg6pZ+9LfhR?09
-zBqZhTts$<&RDwg6Eo(f!x9I{9A?M;#)BNgQrVGHG^E13-mL4g_#|jJ%VQG17 at dfZ&
-zpRh$Qd_bO^Q<iNz#ObKb709WBzQIet-pflcL;qUje-DlV4*R+6ji%in9F$p-D*WR4
-z9M0+}1JYdpPr$_IVB%N>w2?c*#B0m9-wL3 at Nn+3blQ8jFes#b!qlX6v?r at qMVScat
-zi_wm9Fki{U8JZUeLEsS;tw4!*_cQe6IUFutIWY>iweE)Lb)6oYE<@o@{NBy#>eY_|
-QXJ6rz<u&9WG8W<g2ZjpLi~s-t
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/content/about-footer.png b/im/branding/messenger/content/about-footer.png
-new file mode 100644
-index 0000000000000000000000000000000000000000..94d9124a3500e9b495b89a6a20d92085f53444d8
-GIT binary patch
-literal 764
-zcmeAS at N?(olHy`uVBq!ia0y~yVAKJ!jX2nV<g;tfw15;#x}&cn1H<|g=B!;Wfqcml
-z*NBqf{Irtt#G+IN$CUh}R0Yr6#Prml)Wnp^!jq{s3=B+to-U3d6}OW9{Qqx%SVMw!
-zae at dBD}#W8&tgXdF1Ldk5?Txj4Q||P0zte9j0}t>Q3<_GKwcXU1IL1kOxYqmKwb)i
-z14FM^1W<ENlOi(%Q^uA9QedMbfkrK6y#_Y;1VaOZl<o$Qp{&kq3 at ifN0>=Gp5KA?H
-za!HMkz_w^ee8FR<LO|kCD=8kZRSSV0K(T58Q+KY31jGhL29^sM+(_=*hGg}M14;6{
-zZD8vHfMIEJ>kyKAb*bfBCea9)#Rnnb$OZCKG;$ENnt}t^2;H-{RAmrhhwK)djzp2b
-z5!x3r8gbZ%5~1E2 at c6+QdKX@VenpCEWPhM|5Gf7l1lWK*%i1gliWVGBVPmjhWLYoC
-T<2 at aid>K4l{an^LB{Ts5l2O&#
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/content/about-logo.png b/im/branding/messenger/content/about-logo.png
-new file mode 100644
-index 0000000000000000000000000000000000000000..c6e4c49370087bf5bdafb3ff801d77163db29d54
-GIT binary patch
-literal 6681
-zcmbVRWmFVQ)Lxneq>&Ek1_5CaSVB6ayG2TBDd`qbQlz_^rO~AqkdRioOKR!PWk25U
-z*Z2FIbMM?UbDsHg at 0^)?p69F9Tcu}sG<X02;F*fDyv|dE|L3^aPqWUFGtN`M^psQ4
-z!+jcoxbMF_t$`3_V^078?czU2YsA1!eA=Y;QZVw;b+hyGvG%Y9`1ttnJGwe~+E_zu
-z`Q1G1vyLQbo-nB@^0Ioq*@w%15W3l*wbSF;0BragvvRbU!YOe at 1dcMG&_VSFtLhb^
-zZbO;Xnk$v(N7AK<Y083z=%1t1j<4-23!vz#jf2-w+#Y_LPJG10O at 9z|vqIG|#mWFy
-zg~W}ZuVS*qn963t%U#GKu3V5^sNb^i+Pz+Z^2ncKv54#a;AJFX9q(|%|HG>3n6z;O
-zNhPa5=h9XUdC{Z9UZj;|6!vt5x?25A$!JBG+~h-HRBNOUs1JvsIK`L?6bs}F3XVz+
-z6#qC8c^3+AaXmz~N(c|yBUr}qg1<2O{i*|g3(E_F?-u6H9p)B!D!k{f^pvp+eT##~
-zLI73LBdpv7%YUpuh|Z?DEJs!xTAIK!a5sniMA7a}8;PjskH1cT*<39cq%WLeQjdFG
-z6U!B)??CQVbT`)T%iDZfuh67GZ%|VQgmh=}#a`<k<y3l577_ts02~My!92%_6UB<B
-z*|FF#k2syTjCPAFS$;v7k(%FuF0<r873v#PiuM3G3Dz>f*gmMevQ77Rc4k9?UeBne
-z3bWi)O%884O5Uhu=nZ_g+-69&49ns?^6uQe!!qa++*(99SWJ=!s68yLYwSg~_fTpx
-zV5=6!b0v6vIf*6`$UW_tMQJ?yU5+vIgCq-ZnT5aoVF)EuXo=CUK(Dz%W};9*>78q7
-zk>nizI at _6A8+fwGmrP!=BoOwvxDV5C%dJDZY5Oj8+!tj(N#+geeaTF^Mj1B}t#Xh+
-zj>Hq>M)=mSl*#{#>P)(mJ(P==rytS!=Z!ukM!^d>)}+W~g|&T9C^B5 at BVVxuYmX{v
-z<0O4;R}Y=mIAsGrS^|g^>0`XH7;WRKj(#$B6<zn1N2n-Su*o2|!&?vmAz=;Sk}=5F
-zn=IAOPdi)Qk+c;N+A;ZQe?`z_u)|grZkSoFj}DZR$=4$-R`1VOs|wf<R(IbgfhVdg
-zearFZO67t0oN=!ioCX(&k*+EkD5P22hvY_}*6cwI at zy;&x!k6{LE&ThN!&u^l&QAT
-z+1G5fP}K6sd&6bai#kb!5ig70T3H7IslqQ3<H3%mmw3m%<0#*WpR7QiV4Dt+ODS`z
-z>PRbm#)9(@C`Gp6evP$uu08NBQr(Dx?08>0PWy`_8iICtRewD%l(sOw?^80)jzmGD
-z+NorL7!dD*9W64~LhG3YZ9>?-94~e}*~1YoE2*k`;y2Fdvm~l!O at -V_s45h{ZEcYB
-zfA5R&LD!2r^<;N~wBt9XQ68ll4lcT5-g5So*~g?~KHO3r^E|`e1t2swU;%3ZIY)k>
-z8I`aqwXg{%@1TV-iSmm(C`HV}j{HO&UR?18bfrg6daDzcH?HuZ0HM)+nl#~oZL*j=
-zBU%78KlOYM@^?q?H-M+(QR%)=r^6{aJ9Jj9I9BlsIhi6|=;h?Uz$|x*U9H&YB2Xu2
-zJ5Xm!f)rxK=jp`%g#RJ?r*5lh=uV<eLqs-!Pd30M7W<raHsNRGqR5f7iRtg)NrlKe
-z{pt^1hRhGb-*6k3)SGf5gQBcZBo2<#F^A`gg&;Jsx8c-ccw%qyGWEp~O)O_OXO&Zn
-z?D#-FG(={$8{S!t;IO)(Q&z(<@qrYk{g@)XhVQ$V=|X6B8f2xK5#dYwnv2k$G^eU|
-ze_br9+Sp3vAkPEw3F%kn2JElftOpq8>J1&GDZNGh#PnJ9>%m+^)fw`1?>RNs_9&)T
-zq%-DVe>4{+WU6hG at 6m^jvv at hk%1lzA5?15g4^HDzC53dZ8C*-?EVGt|;&O0fLqE#m
-zhnO=jTCRR}%ji);m_P<Mi#eCT++qmK)Uho-6Vyu)(|xd~<yWPZNVa)!k;PMmMCFe1
-z(Wn6Q-+MRSC*WC%)g!%b!3Rq?w9;Cy+X`b@$AKfQBuC}s+;^FyB6 at d>h6eZJwoXop
-zr1_om$N>FZ(fUKLK%G<CpWHhVMbYmthvMY5Cd&Rp+1uC{YliBNj{VfSef#5Q7NP!J
-z5J1$K at MzG)4utM$*Zn<GPFqA5J)p4KNPDwGa_O1vD>OvbGKc=H at e@40k^W>1d+X%1
-zPOUST;<?Nyy7ePnAq=*>wZ>~|kz*#E9rvE^KwqO?Gvbj3_p()XC}MOmS!1!g&DE}H
-zgm1GSH_x~_mX_AzIW7m?Y!&s`zfR+?Fjow+KJTp1-}7 at 8t?@Z}G&9z<n>zp{t8SM%
-zm=2_ez8M*;(&96&6=gywF||YcHD-T?<lUBGBvfKOMa*SuoT9U5`|#v%tsE+A$?viH
-z9$C=oHwP5_Jm(XtN#rB3hd_LurAfY~@hqb(_5NKkIaE2D+=26kSMNsAJn6o#pu?LA
-zL1W_+v+D+&X%jjcbicU_P at VmfTNm&z-3Ol+iU(DhDn;ne%s at Dk#GZ*a<<*oeksyID
-z^dHUd*Qc>fZ_j^6Nvuz=a{h*}>(|OGF;?3B&}H;MC+}bG(n|+VUE9Cgf9qgmpCx&_
-zI|#f<vm_geS6d6aW4|U63e?<2WNu7{qrji9A1mvE8yjrfe(UsX-hV at 22~fo1Uv;d#
-zyp+whqO02s#f7<lq5O6qVfa_i058vyeOsv<2(8&)zVc<`m<;gyj6gtaQ`;EIe}iD^
-zoDX(64Z}C-`3L)lpKIRkf{B*Rza0=_cb9z at 1cMBSS>@URq(DyYFnQoF{Br^E=$JJh
-z2HXOhoU_f8R~9Bx--I9W_Oq62E6#dHiiSoO*ta6+OVy~sSgm8-Esc;G`qvWSQf-d$
-z_<bc>ueonjlDF5Ci@?d`y*7Dds-ygRC4^&ty^cujFLIFOVTFG^d^iMM1`A58&p#S<
-zarq1|R}#^?Ow5ozWa0bdn^O*PTTK~pGSZ7wcuc3`t>fpt0?({LQ>IrsB04yWFw31h
-z9 at W29dn+6c=VF{}FD%i;1RU`;<$j76ZqeSm--HQ%Ac*ZmQ{^d)FLg^Az)x5rs_B-e
-z_}5J_U13T1kSSt5cYi#v=1e&7mb3PO{iouGTX42GR$0OuABHPIK6QBdX?H at FjZLsy
-zE+Ns9ZQVM%vyt)EviOAB-?6UmLOWGd)elk~C)=${6%Q78ZvzP!Uv(!2-5TGb`M0jk
-z$=;Mx$A{1b)|l1r$Uti0RJQIDDvcqIZ1BctmW>DZkA;ZE#bchGu`J#fQk_H`M7{AE
-zkPV2de){@J2Yz0a_>Gx$c6phNOQT2S^!otAJnG%~CQ>VlqI;&@g9A)2D1AT#mrCJG
-zF!o26p$;iqQ9ldF`^9>3hXsYv>-Ev*wG4?f>9ZI`yUXkMCcrg`K)!%evx-f+_F3{n
-zYPSX)!UNo3|3*-nJ-^yz&p?0`N~t?2hO;>*avR!@2!)aE|9m9O1URkOS5syG2z1eP
-z2vWH7`a$v01$gy1TNE!k*MemduRuFcde~hK7QS$L_AE%CNWuaA=H(6$J~%kuJ7A6a
-zHgHCea0l^{rd!HbOcUwN2h&LbqORn9NP4cVgBt6L;J<XY>T&M;-<@E}1dH9DVv0J8
-zHgAQo1z2AjIMi=O)lPiGyK;V(`AK^&gz9asXc8vjozZFnQGQLLHhSJml8Nr3ZSa9i
-ztAzD<)NO$AWYf_Y6R?%}E;th`*l14Csb%QnvNMWCCIgX<Dv&)g{Sj$-D>2@?;_~Nk
-z{Y*g!c>hDz9<x`2h~XJK&)92Qbg_ZwmdF#h2Gjb=ffDHmJdpRF8brz*vR0HB;3vG;
-zt_O)M=LruGUL=6>2_RN|E^Q*RF?N^P(Qh3zVL?IPrRv-yikaINk`vnX>LzjTh4yNY
-zrAPRKuY4l!HA2%wwb6tG_Fp={#5(lW;bUvRW{1p#r~^Z+E$CI**C$9=vO4z>!v#oo
-z86BGx3 at K^70n?tG+VkB<2f|Gj6(0^dd_SwdD{mAtac#?nVYg>EchEJ$M;CTx5Z%VJ
-zv at 2oAoxJZ>-1{<3Y_Vs(9ye6!Mm#$1JC=_DUBG;h9qF1cXfriXdKb&lcDx>A-MeuA
-zC~VTcArEcCY`&V23GHJ0F_)IxGU97e&xD5v?99ei(~T$_?-Vz<;nlr_ntsRS+3LLp
-zKszV-uxD{$`h9IzOrZ2#Cm+jnMbWx9{mVZZCXrleC@@^5=6%qK+TuJUQ`+8y$+q^I
-zc0HimXjd at 3Tp+$Q2M{~_aozfvuei<q4VCxn;^Uu1lW-D1jl=v!24Gx_G^(>LfpDOO
-z|NIc8C$xKJl`*+YJq825NgKu&=%SpkM`zuzyF-2YbBxM1#}XpXc at a3?>9!rXsT{tc
-z`M7G2o_zbO(b5^jp?Otm2pXfMZTBci4tu>Rv(bRE<k`!BVUZ9nZoQz>j^CiI>6t6>
-z|L;hAkMcD~QW8^8&qrT;C8Jf(CAgU)gPCO8ZlkJ&ksH^(;lZXNje+4%${tv;op=Ga
-zCMKir6{%Uf!t06c#$d)~)<mMopC)@>BI}+z^o-E_`n}L%=FCZy3^0}+7vN%ecx4d$
-zB@!Yc)|3jT2*Sih;3r?cG%XrFzgk*oRV|zfq~3a}Pjn(S@)}F7A-FfdOJUb((ByM+
-zN|u0)b7a^U1ak3|{Mz`;6;k002pyHgLN3m~wn9vD@(cm{jhlm?RCI|viged`0A at z}
-z4lgT&{35}Sk4 at u>=8efIEQ2NVcz<R%gmDdbjh6bYkawXJ`afYY?4rgMjWZKnj!YAb
-zQ4L`<x|c$DUVkx_KS6GqM$$z_Cz@}omI9L!7giMtucIk|cU^eJxry_}bYXkC8qV`V
-zeA?JW16cwb+dWOc6-7Ia&H?~}GU(2=?-;F$o#vs&jLwc3+pUnzYDlVGj$cxR1;*Lf
-zbizdzU>py8lK54SJ(i+Bp?L at WRu0oOo8Alw?0pdbEP8OhSj9;5-c>8}S!B<HDNaaS
-z3N8CGId2Dzs_|x|yWPk5GB;3~|1|;!M;$=1B1{5=A7ojLa0ZYMdMCMt)5^gPZog*U
-zMs(SIdEDx}huIb1z=3Q2vrQQdiuwLw^-$AZR(NuT;MmA-hdkG8OkD!#o64TyAStjF
-z`jkNfW8WMNe`9HPG4P7>o6{0#1V-Qg7PnTN#Hf8 at ZrfCKxE)M6!f+8?L*<N(wq#!P
-zBSedki$6mAyueEjwl&s;)gSk=SvVQxZ5=!O3LENQdH3-OqxHRWWSv9JZ_;Y7FJw*E
-z_M;K7jNlt2H&2+v^K>WRm(t+5RnG_xnGuvU6$46FN|VZo_a54vtPkf)kqwZ(=n98-
-z<dNDGVNnFP6n>^hN=ZAQPx1f5tpitSo6~>7$ZM0xevvf8)>k5U{xRL%6x1PcuOm!U
-zN+mf9(SQ7qzcc9+R8=#kDuO|!kA2ObsC6V_ajZIQeFuejV!9xQH8KFx=cCAO3Q_)A
-zl~)88nN6fjTX$7JYpRQCN63y`78?5(44eMmY}Isev36QhB$q%W&XH()uWqN*oZ4U2
-zP!39W0BoB-6Nv8?g>}X6Ztw-u(7SZx)1s3Vf|qkB%za)V@?=ox<ucC=bb;o0y4xc8
-zs+x!SA%c6BSIDmCFZX(2+2_{OIpy_MEfbRLxzq$g`xAe5yp5BSpnmLj%VK7fc+PA|
-z4j{PTr-}a(8RxcJ0xqv9_XX>#DYlf)+}d>2AE>TAL=&4es3&7`G_h at UceVI4=o3dN
-zrCPVM6vH(Q3`%B7ZWk_~AL5aQdZ^)vo}uiW?kuO2AZj|`(<c)Ww&U1Xu<_Z-_)pFG
-z#4-izoAJnyfB at O3m!s(*Vu8?bIZod29{CepJvzx;B5=h6nX6!KPMLoD;)g0_CxfI|
-z_FT`TimuCdM_m|l>10fx?2s#0>t*&W3>Nyv#^E?DL;btfhK>7fukZ at in+i2Dtoz`T
-zO%SD`iONY!Uzic^T<^|(&e;a0q=!Jk(mu(0Mv9|BFjY at bf__~6G1DDXeO1gX>qqxz
-zz6gOj`YjT8>&#PAv>s5<#G1Sj+*~*mpv8*hNu at qEO`f_AotU*U7NI=4PbL-?G_JJm
-zkF7YF+mWk!;EVUS{9Sz3OH7*o<8vePgG%Y~@Mm#htG+ky-nSC)1jvU6BT)$9?N*SP
-z#`^xS)8Nhb-``Bqf`@2Njxtp!woc|EAdA)I%yrm0Cg^!xmgUAwFFx{q at 2Y@aS<nng
-zM9t(wmTcenTc-XpgV}!-^kZ&s)84C(dH3&=xbXTBO##!d03y6+n+v+*1eeG+ssNnS
-zt)2(h#xfi-7pRlLM at Fj&viHNW-{0MM#R($&Ct|?lF at BmCucls_KY=5a698#y<XB>(
-zt{ujHK1IYsL(iTQkDQA55H8hgapIyj<lEN3cfKWJ)#A>=gaMa|c6U9o>*ODL{+;$j
-zN9C89&z*E`%ttoFWr|X#>M4lU%L*_j)RrTVRxsKj5ZaXcF{5iiDTpxeR>k*5)>^-#
-z!F&JY2yQY<BW(clOq>TlM4V{lni%K!3)9jLOQLy{-%jS$7p>ExOhEp022kyf$GAs7
-zOx}oDSJyc(EQzrF?NrQ#8yZacRy8zt$AY7|b-I2_Jy(r_ at xFG)Ls;s3bd5?5EB&L~
-zNhVn;2di3G@?xVtA?a*w7`k^C6+_saZL}mjAECS$Z=jZ;QdP5ZZ>~E4cYg(PXv%5k
-zd14Zbme;rZ8DIG{KWTlGJ?JKR#T at 8on{wUg>;@`g|E7$1#Qm&cuVMW{@=j3luCC56
-z=4{&(0?ErL3Qu{JgUe%J;8&Y9=c@?JA8dGlJ{p=Baq(7v%C)#TT%2fE5%<5*5zye_
-zXj&VjG~ic-zS5UjxNP~4h-z6xmj}fzRIgb0+VhFH8N>$?bU2D8DV~YL!%eLny>Hs2
-zwC7WzOBjOQy=YTUO}Zk<Z<e&cc>Dr=0AOK3P#sU!%@}xXVQZ6A=ab-pD0bnF+`T-~
-zLwqg!;2>tMwE$dOUl#CNdSr~AZ~Qdh2*A{zYo-K05EIgAnV5Wv|Ja;n*r=xM_x8G^
-z^Hz_qKtyqpkv!qw!(~X4{90;OM4qNed?(&Lk&Gs(zwX3Bsh1a?x%p7b+kjt#6ORAU
-zBq|*wb_Gw(cmfS4dMZsk+c5~ev1XT?+3;a8>(hBox2C<JAOxJze&WVWwLCK!P(hZ5
-zOKw56x!)>hEqfB6{erwd1=?mc9`+4v23zrZw_=!Tn3?spUD}aNX0LqCynLaVURaMf
-zDqLHzbzHbiJu9i_D1xP?$Wp9u+|~3S>N1k8MJ~;POxd&RJ|e|Z&v*Q^L)uJx8TG5#
-zTG>-RecKra#B-djKONE)lz5#HX6HgUoUatxs;G!I{o>cVIOpgye4Jxx0^5Tct_ZO(
-zx@!inFK;;bcqTB<26&uwwr8?w3uSqJ6g8+Ha`HIgViMl;<kgz}LyAo9srCr%iiak+
-zEusuc- at drZd%e){^n|tN{rj*LB^wWrwj9TlJ;1XtFu??4BWb$^Py-7kUQguTYi#w<
-zaCDyxg!c at pn<iSS at -D)Y{_)(hBLR1Nkf9Zgj43Kg`VNj}W%tY7Y&?)+h4`jBT49B@
-zWod+Z5YEvJzTTO5Ts8Ei^h&9EL~OmHyYI8x2662GNp at oLe=5<hd2ck8KQszdgp@<y
-zX-;($7<Ns!x#A16ZXMwZr-N_c65%zZm$L+3NLWq1Ri`q-J#v-gJ;|-47nJc>l$-I0
-z;O7YbCYlbM7M{>Fc;D6RN&V9E^fCbRTQTkQ3hG_SwN!}r;l_nsVGVR|8P6H3v%?=>
-zx1;!+li89OhEs=3|6IP=-d>n{ed&cFye(bj?yUTS6z at rT(YOAhou%?JL+{RO3d$xc
-z`SIuGiLpMa at r&N~GNmZNctA~rrA~EQP)eT9)s4VI*AD2zk6#X##w2o?kH6md;#eA1
-z9M=M!h;(O1KseW7YY&R4-2Oa%--$~}nHb92isffH0<tMv1KQI<E~UooyONitb{K<4
-z`@{WmH(g$7S+J%AGkH5vZ~j_l<38h(PeYFh`&+(=Q2RleUl&@l at yYegR@@~0<M4HI
-z{ocHN(Ox`VGk6?L=ljt1iIV2Ji=JVL&SU1PY0p<@7ZB}-w7+;OPH-oHw>NAgeth7X
-zQbKSwss;T#tex(P!Sj?<Av<=!yXttjihk$8(Bhu|KEghNCoPfh>Kn$LIv~-SC}d<$
-zRr=e4iKMbCwy5Q!?=m)fYyF(0eh8S`Gsrp&w^6HKo*Y48h9jMr-%+kb)MsX|EA)F2
-zYTv&4cvd?<-pAE=ex}o*J$tYn^%AMFVsN*9v*$k)vw<}kbXqFW`PR^#9rv}dHQnxe
-zSw*K4^VFny^+0ntwca?>U%YJN*^xQ2vIm{ntuOl^obLJH8mW1&nmDOi)cA#=ViSK0
-z`xA${=~H>LKN;AC)6P~{MK^1C?#tGjSrt?qP?ES2Pi`B at Kg&xyOWS*GKK6lQMOSS^
-z6XzXPjU#%6Z-hq3ZdDzjrD4mBcZ&$@#jKRc8;%KTZ at L+_pll3f%jG-)1OGr&pBc>G
-z#&{mmSM#X!j65Z^4Jw0fx(D5dQz(W0{X0iW;qoJ8<^LmP{2%p0Xb*)Ex|&hQsr=mW
-QNyY)FD7=-gk+TZ_9|IdT#sB~S
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/content/about-logo at 2x.png b/im/branding/messenger/content/about-logo at 2x.png
-new file mode 100644
-index 0000000000000000000000000000000000000000..99d626ef66ac6183e1c348306d7ba30970db7038
-GIT binary patch
-literal 13886
-zcmdUWg;yI-xORXdKfEnYkU}Z$POuhtEAGXMYj7wODO%j2xLa`xR@~i5a3@%C`O@$H
-z6Zg(JdvbOsBRlijJnyqVRF!3LFv&0h0054htfV>sfE4)e!azejDHv$zMEtyR{UrAp
-z15tc2%)=4)|2fI(x&i<w`~NPa1|M}>#6wayDIGTrM at u)bsfz^w3<k5=IM}+HnL1gp
-zIl5S7oC=cx0Mr0E$&a5sGf&pQslWxl-3NGena`WRkGN47uVjO$|3l`cPNjQOV9m*Z
-z-=)(%z3lR{Vcq2J-g{yCt2X55h}kyFeo1?}p|Frqjgmw5OT46d0ZCV&q%0s6 at P=A;
-zTOf7S(EXGORr=kiV%Uu4lYh2VcK4{8c1P-|U}u>|@i@}!|Al3U?~+2?y!ljbf&h)Y
-zsF@>s*D1klfP|Z$lDM9%YEDp(vma2|C1ApW57?N3ca)M^3ynLV1+IgA{a!JU3804s
-z_Tsi83vB+vs$&bsBL~Kq9dX&^&@Sq-;GW*yez{KF7=Dh#XN<!PoQ--gE~+gLJNTHG
-z5fW*oho5OWp7n-YW3)x1s|Z;mFcV(UOMv79bci(taa`lCu+ at 3Car^Xb?$0IHwtM#i
-z(R|U9?(>kTHRoF5rZ!Cc9kw at Jf2=8D*(JM<Vw)5N&&bBi9>t+}0IFf0gs#;l*JXX(
-zk$2BMMR>;Duc1hEKA!;vG(!B-_ylCT&0pLoEiXC1l;gYKKq>e3+X}Ta-O}7E+nFoj
-zbxJ(MIY+57O>mQVBPM|Q at 0IML2Ei2DNLHimnn)ZX0Jo}yu?_BkmQ at 9>Yk81>XJfUF
-z!KH1=<PIpcAQ&?cdt^a7At%*VV5LtjLy!%;NGMcREePVwcB=Jx6U2*6wBTkSodZ`@
-zM@(q@`>C#y0#!>0(VrBM)dHD8_qoittUVL*k at NM>G#@UHDKm-_;5CK(qXyDXaErT0
-zzO+<}g4qBeF1V#TNjx8JpsodH!Z5`bd7eTAUQo!Fsi6KE7Yti#_|QrHdp|gI4Pc;n
-zAF3;F6M?I>xr)+4?F&l|3Hb{_k#jEr%;xGZaF-R57@@3g1NludPeBQ at i6UrX9x*<^
-zDV15nL_;Qkd!DNZcO^axT at AUj!MB(T3v0A*1Kn%-QJWw!f6f&@^!N)kq`{h%1y0(i
-zAiTGWF0KZlMvjbW_Q+ZS5l!y(wM$?!#%QwdQ3nPSikRJDv-=7=bbVbxo8V+tm<80v
-z{B~BrTzs!iv5xxoeSdK`+f|m#;WW1ZxSTwybHSMu-8U>QR}D$F^q=rFF+T=!i-v5`
-zim!t|ypGrXO!de42q_O9(3lkj7kBYx0x-G`xZ+$Ia6S|4ilQi9XUS~8 at -Ur07=_H$
-z{yNKqb6kvk2B^c(RXB<!fxgRvqG3zIP%lYo7^#)7{Z(p-#*EPdE at 2?qb;q6nh-Fta
-zxCM&T|1eIgjuytz#{275TY>oZ7&z6t7+KW}a*V;IlhXFV<5UcVKW{<yH>1bd4B*+}
-zpl9ExGIckMEQQQ at Wu~5w?^O=BRp%ZI8!=GX0N=){aV#16Q+aDxnF4B8UE4f29n<c!
-zNb}40R<D9=(l+Pom))REsI^P$p(@f at 0b=!8ho3~ppZJD0w`t<{dyZE=8axh9dwAUA
-zCRi{5H0N8`0 at UyaUgo;Fs1a*d5c-$wF;e%6xYfjf6j6QA!8?k>`uG+&G6^>{7r;b=
-zGU;5=QyCB9LQQ{5;;4nJL1IYn1Rl-MJAcI7O38CtpPh7nx`K*1|JUXhHiS$Vh}rU_
-zJ3hGM5)kg1BgOpnN1_J*I3yV>(s-(GbGihOxCGYbW~ADN6oeWVY+i4zYD-5)zZmt(
-z$Vj99QiMR#A3d=GdSNeUAMOzA$d26z+UjIACRsZKDJ&yecW2qUF7!J;@~0Qe{GmdR
-z-DbIMpXZ?zA`E=vR<#Ml>gjx+_WPscV<Zmb?RK76yM?HaZ&;~26M%NICB0VqR*X|L
-zY<`}wR0 at 5pg?*s<kMYqy^#w(dRw)2`hQhWd<6E^2gffo6=~NJ_2Wr$<Q?m?C)GI*d
-zkZh{nnVk#?u&S8_6TK!)rm=k4CyO*b{-^gG4U(v^_lW%+*C&5Y?tVem^V at qJ_u8c$
-z^SW(hB~t91qEM>@kl96HOUC9#<o9-<4^kH{n<n6ZlfRGWpgZahRrA$A5<uIlA+!y8
-zF}DneaoBw`L}|t!1Jzq6S~~(os4xNG&U<=A18k4bt_NSM*KrXpXwc&^serSCyQ^E=
-ztzgV9P=yW!+rX`mUaC|<cKe$@*9V1>5i0k%>h??kU{>cqk0XHUZ<dr~JHzHNJD%#}
-zwABjZEv^QuyD>m$VY`ZR6&z>-sT(}|!+C`#4h_t2n%F;5ft*q~5k#sobit-#KTR<Z
-znb!QQ5IHrtcxr0gi67wSYxkjoKeoPe+`jxdA$TEZZ4KLBn4God;r*n*&BHI4P9D80
-zeMOwiHSWoUogd4ZHE{%~`z)~r5rI1A-mp)uweyxX;l;RtVy;NmI-Cjyrq)noyrZ&>
-z2D*O1ztdYvs}tx&apnWf^h`#r&D^kt7V at KtK0q0FNUlk*ZAX?P#I7j{rVoDuR{vtZ
-zjl4V4a$SXi6gnc!_D at 4l!eB7d{X-9+upLlfpM>RJS=$T8iv-kfO>sgZM${kca|xAJ
-z9znm`cDkO6w(n#2T?+RLD@|-=24vY@*zax<l5qQ3mGTFp3OEhc-UQZyJI&xo0<%eO
-z1A}d-XlDAR7q3Xf<`G>LDJhRL6qNbvF-YbN9%7oiYXY<?aGq($pOLKv4uT8ct6}@x
-zfILokJx*MY*YHF-AR2`kr1deOLvKx&-<utp5BxcoR at DyZGiu-6H1Qh9>#2hTC+Zuv
-zyHk37Uwy9KfC>)m`C1K?JtHl)pnIISA1|i>HwMx~oU17AgcZ|%W>P3-*ePaY`l<{&
-zbdh$h)pFcxLq85PUZVbTrF(0Q4d-ZH1}C#HO4r!pwb!nk-z%HJKcXKFpO0gIh~`%o
-z>vLZIyfs^j{|cgEA-!9LW!?&Kt1 at kjYeQdcfz+9I=dvwc3)w+;7F$3EyK&3O6TLPX
-z8&Mijq{Y1 at M9?2xUCv?TQKD<kq<)b6M5a2#sP3nj++cpa9Pl>qSY-cSYcE#PLfQj9
-zf0j`JilQ7e4SLe#C8A%O+0JTLaWRogJ0Mv`uDc6p?T1HubYqlRav?=$>=ke~^9pcf
-zUH1N(E<?JZYjno+I%+%5g-<^?VwtFaL#c^{46)&ZvKFUw#<hI6>;exFaA4`C$%5!W
-zvVDyg`PJVC-1l>Qt*DmSNLES<Y26$Ym|xl$D=#rDb}c+`+sy1w%VE!x;N<$nfWh<4
-z<bo-<lAmKy;>aTBkZyNN9YXf}iseF#!dOqNnV$#2KR1RYk at k<@V_Sw8gZmxt$JLK8
-zQ9a#3?e%krMTOcF6zNX$x{b4>a-+DUbL>c>;fOX=upVAfm<y;I15N|d`m=jC>`6v^
-ztx7H0u7&vQL$!^9zfdUFQt!+y0<0#!x73;TG|%#rC%qx{b<ownQi6UAWtywr#>+Mt
-zHF3T5gONdXzp4Ry%d2}Qa>CXgcw~)-&6dr#f?N}9(OR+YQUo#|@^?<ojc;+e2ul6#
-z{)Gzx`0HU?PmsFVbcnyFDVCk*kj*`6X)0&_M*C8~m#e=Q*@^dF=EGLZb at MKIe!*|V
-z-WM#9_4-W3y|e)jgWSm}*d3*2IArH|wqdJFPE%ge3UzRvhTe_ml6=- at V~A^}>>;N3
-zo-|p7SUXnp6gXM0_T{J9(+5wla?5#wfFOXSN?7A%bZsSMX7&|gppKa9+Z<nX!R*h3
-zfz{O?#JYPxfp~Z0>R1TLu2=)CfXg;gmS5{|MY(MVo2}|VZQ5ON{hRVx??d6#1M%s|
-zlS^{eRv}GDRF_$OO(<bNTmLx432OB^>~SF!B6beFqX+*WlH03`#(fYZxLunGGthN0
-z%eFVb`3zxvZruvd=N+8dYoufz<0(G^_C|xGE~At04Uy}tIjM{q8Cs#>pI~_ at q-KO{
-zsARgntbuWj at 9$0LCK5u8iNSQ07hcV0ncH8Sv#N9_ZP}VFb$vESp&!>jU!uZd8aAvl
-zw{raU&fdkCZjID@?J%o>fud!->Unzeu%cV6;(~}ujy=$b3|rmat at xsUBYXJ^Z4m;y
-z+nvhHZoG+cJPx8?c>nZ7qs!x!=PcD`c36<^5IQ_wvxk1sHzMZs4*kihR1IADRX_|g
-zk3O)KOvb5zJlkMv at xB%Qo<`Gz1FYqe+ni0*4nAAlpWjE}AMHN+e#EN_5X#x&iR`iZ
-zrh%|$Watx)-;!)8P~C52vux}F6^KY&tsa!sHJex+BSm+(#m5K(^Ua<DFby_93JpMk
-z<J%>T{?n(!)3|%Sr_aq7U(Bu;pmJq>e*RwikNl8pBUe<DzQeN|4*vyk%-3);ox1K?
-zhkWUq at OH+WFa<XGU6Qik5Sxhc<K>u;zMQ*7FQq4MxX#<>^x%NMS@~qR6ro|-J?kh!
-zhs1)(GezCJDSFq$zxh4dsJ|XHhx3<p9+5dOEI&RD_A!4`>|7nE<8~Kq>9;ZRk4vz&
-z3uGoHt+TpSR at cSNE@JdH9uP(=Z-LgNgFxBv$ISDO=6EO?2vsXU$h~Kw+0*6W#cR?C
-zh9K=m32pvN(J>6$ygnwe;F(GiMV)gT?Kx10?I!jwSEXBt;0(XLk^+8 at UI`Te)@C-Y
-zPiFcX_vI!%i|N*lOg%8|@|KE%8>snS`WYA-ate|u6hJ383M!r#qWBw`$Uxjf7#Za{
-zagkN<1y_)G3~pV_q#@$X3IJDq(E@&-Kr-{)ElKRA5x!5{A{<+0RM&E~qF+D@>H^1K
-zxSma3giN82mfT{zb`<#<EBvXdjj?@!I-%il(zJQcbYNTrk`Qh_0YN$Ici0-8q0YI?
-zDr(2Jv|lwv*Y at qz^qm%P{Of9LdnOgE;Cs>;zrKhHe);2EG6H at Rcf8!N;Jk+t^F#`i
-zx3>&fZ)x2KihvhSg9MU63p>Pp&h2jobxxE+Jw>l8?jNMe=yJl2syN0+m;Z2%i|nOu
-z^(6tx^!~E_lA(OJu-4TPYH_&Zf;<1%Q|nSmWc#|bNFa1<<yXs8D%TV^or^2O5|z2)
-zHq at s=y{*KXcyfInb{RTWeeKWuFYHZ<nd>~uk}MDvM31d at snE-*&1bJ;_o&*;l(&bJ
-zp~9}M1bb@~D~|~W&R|<HDNXmvG&Ht+U2n?`lE-_<SutL!)XA$4c>~9JH`dUoN_Rz>
-zOLe|eiR~^zX25T}*oh at -0U^i)=<k?55lB47O#B22N>8=rkcT>|d?NZjB;$GI%7)$|
-zyiFEAp$iO6MMW6i8{@C9*5PhUc<59|){)PZt1Feu)y1w#r`p&z;tki at HX+EXFAT@4
-z30V at +^`ysP-~37TgS)@wQ$48)EW at -V@Wmmo$ufTBz9vhLk1g8WesJf=uoz1hL8)qC
-z;g&MdW((i-cS8yrZkZ~J>S?j!Wqlfd%71x?8OhiAj!vn$Wz6b~?I$w1kmY*{5B|2k
-zoT|bYlYq=Kc{3tbN6q*udTde{Q?LJhj{CeSMMl#nAgHRX=eKHjG2zyk%Da2KomFd1
-zf7UG9Aa=6r;<-ib!amN&eXE!Sk6Yz<!w{tX)1Y<QN!Rx_26fZLw&D`pQC~yU%uL*D
-zU5coaT*p~FU+B^pkmEu&9xaG*99S06n4g*N#wSRjsu)dxE#{7Dc~`cyN&Cnm4~Fs*
-zjJ2?h!FK{K0*rva1-YDz7-s$5skQjKe)PlHSmWPDR%VQmfWDmwgKgc?sC^C{jNonQ
-zM83I`hZk=ea3$4AKP1Wou)9$NR!K~PzYnW;$G@?Z<DW`(=I}t~nH!r9Pg?NLoiaN2
-zv1MitKZ*Dk#U`8S6aLd53-99|;%~D#+oBEQwf+fkf`j=5l&~9moPZb3`_Y{gULLv-
-zlhs$&<J*Zp=G^D{hSU=nZ~h=W!LW;6Ngl#bEuXCjJR8#8sNt~NeUr(V=RA}pK!cqj
-z2{fbMdm~(ZlP_&l2FBZ>_r%E-w?P1h_GJP4bohI^HZL!IH^)-)QXQmbTg~1(HGC17
-z=n5e|b<nlIsb4dnbY_7RkY45v{rbJ%gSvmdp6TZ7_Hh?anY9kt#aSF)*LUZGjt?e_
-zmv7r5h>iSs>2N%&7C9yv!Xc8w<S!D2XInX?=Tv1qfa8 at c;0ZAnWX4=yMf)Odr2Cdp
-zh?yj&8~O2;^LGF5Wa9L=O;|=-CvQ8dyuL^U4PDK@^EL at YGQ#SCg=k}(N)Y!D<GSF!
-z)fCPq(9RC(<(=tg5oAtv!>ljzZ#Q($<il}j{V>-nq0R0XNtE>aTSTTXTHhI-tn(J$
-z&>!`$k17=p9Cqsf_7`N_6U{Ang6q&x?O)WzN7sF!eURFTj~Q_V^Gdik`!Wb|XkfHJ
-zv0w*eF{i;`3nLwCU%mag+ixS_1P$d)<VH)0zE_mzS<>s}P4tYf*d0~h38YyCoO+7P
-zxq7vTG3_iNn$F`tQgXB+lr7m0okFE*KKHox%7aRz=P`uswCE!=F28yKt;1+w2Ue^i
-z=>6b_PD&bl1lLJ2=9u0~X#lLga7Cv+J-9g3rRQPzw at x!i(+Ajz9Kb^=*+1ZP#xTqj
-z-^jW&ULRh{y-ooiodnC|$iqM8U~Rsb6-=<&BJCewiXjzvd_PGy7Qh9{!^v}3^JtDe
-z35|?$u#XbmKrRf7n=3~0mdZ&@9gVbeYmiRw2R-Tfo-ZwJfub6_Cz at lB;F!Jao2)!O
-z0rUrOZ{(2)luc>oCoe)GrTpNyhRp%R^x7crX|K93Y{clats9MYs4$-iXFew{gk~r?
-zdOTUT2XI~PmS at 1Cwc~SZ;+521ftu)On`c=QNm#mQRSMmBIqRS<4!6DcBU%6#=TrWY
-z3rw?}-~Mmip?|l4$Nm&XdO3=HEPr!5(Hrdo4Xf$OOXk`Zz;sxn#gi3;M=shpH*yw?
-zfUK<VY#yCjG4`7JVD^f&&(P=>7{G1`qphi2;TNSKy3e}oINH6pZ}B<&z at 070s`Hy`
-zr{M8kqQyjAk8!s^2g^#?@8bEQ%RaW0V4sA1|LDDx=k;xx^V5Z+2k~F at h3Fx;$$oo#
-zz53un7St|v at 2!QZju`DjH|G?Apar9#lZ=Fb$gZiXu9KlBl)t_v_5N>x%FvH$u4bIK
-za~s0B+sKnG at s?3|$*oymU2(H at EZn^cW}qpnKsW17_<Qy87@&Mn;=Y10tqzges|n#0
-zNPoAWK40cQiUA;~|4fhC{fMZeRfP0j*AW-4qI~%<Be<$mX6*#vb5z{*DwAQfr(Fjx
-za4P~2gB92S<F~4%D<yn;CMRf6#xh5!vge6~``zHAAbPdEvI9m%Q{7Ht<J*=mqV1+7
-zcx<Hr-=){E=F&v_+n>|JqF=`8{GLFK^H8eV!~uxmkWb0_x|od}^C;)G)RqDhV6Sq7
-z^@D|mSV4VRY^v)}-+HjSHyQhmtF^I9f{94hM<H}u{|!)IjbXsieXjdR%4Y!b^up8S
-zebtrbRa`{=Hr{p3?s**7!D$fd#KHnbZe?}vhT9r&X<8klntT`qF+y#mnCkGQ-{P%$
-z7SA)Mo!`_!l at Vhbg!b&P|DF+fyt`<O(Uw0{fXnp{Dy*^ChS%;{HU};N#<TP31xE}=
-znl0W7yHP3ci~{44{W^x0EI!jq!9rMVm_0pqR4I8kktY);4CRN3{Ghik^7P(hXnQ6r
-zk?9jMOx4x&y7YOJyZB at z-^cX*ib;gRKsRkF+<(nu$(@m$Vwk1x4X8FrvZ0$Gshti8
-zUCR%d0y6K`_`j%J{syRBMPrb+*pWMAJqg*UQIBNeFm+9U5ft at _(eT>7#KUpHnyM61
-z6<l+v31wt*obXR6J9uY at u_jK-1TZ#Mq8#X>^{QgmZ?t$IDLfMA`jHZj_u$d}Z4ILF
-zc|Dm&iI8G|K8w;@64iv}E<}7pHv33|fKH<2cUdQUi=51#Vt%8s=S{9sJ?5_Cp0)+f
-zQ%O8hHKcG><+=Tw6Hr2=fG)wn*>a>@+}rb^mg7!hJfI6u_!!jp6Sa24(6a|U%Dg;u
-zj6#=Etg$0*?KFo%KY<$%r^g|XiY+<#n+Jyu%m#r;icxJynSj>^v-bv$+I;CtqN;-b
-zPQjTDTs#9B(P`UjnMKeO$CvKt at 9zdN18I3tf0dKRnAaF{#l(wh$LZC(G814S-ll)N
-zgYj^eYgixP;FGQuH6xu}(rN at f0DZJLUd9bUf-*|RRO)=svS~FD!tSFvUfx5@(hvq5
-z$a-V4i292$B?oH&YEtQC2KH872ra87zP75bk at EnqW~?$KOEG at c?)P_`J72J+@<0j?
-zzCE74_`I-=&F0hWYU{V^#dwf1R~N|Bz<kF6US)gOFh&VC{Ms6Ti7GI?1(Nb|r&1P`
-zoc`4WYGKIaeNgA=^R}z<wE|dn%h8jR5&Ga+I$kubt at zR7lV-E5=dLf{bugys^?v~$
-zp8N9!sfn}kG6$ZBrKT$oN=&cdh%lx{O1}El$)E9-;8bNqH*m?>$3D~$0Hn|PQm+LR
-zNUZFA=>Yj6I!o&y1=c%Ji%3=aqEdIMyP{2I<vzcZV94O!E5GC7S_?DbFzZc at y(-!Q
-z%&7IVQK#gw{W>**{x`e_TQ^^)imMlD9smbj$SXX2**QcO@|NiS&nl&y&c^Fo=%%W-
-zgYav?qF_=Vyql|nZL)l`i*tXT3gntEZ at tuA-Y%NFBSlL`4f%9kyp(iIjtKe^qcTY&
-zP7~dbkUk>LyD at jcrVjh5<fT%6q~7 at yawFC#aS8jwlkOGINYkz|mQ-T{_t!O;;_qmT
-zvw4!V8H#q21O;)P5-awHCY7SbKXS4r^z>OU0Om8YxdTh~K_Bl*9%O#!@tdJ at _tn>P
-zM<c4D#|{Kh82U?_KRc_dy+YADlj6$L8J%ZoEEPlvA65mBC{B at z>lvjcsBW?ACKO_I
-zmofs_jJ=V<$<$qkXt~XH(Ydb%Xponf0HtZREFXmDo5C~!J;<eA2QCAT at FEq?{KzGR
-zr(tzsRS7+zzOk646pjjH{O<)t5;UWQg*-VrTCKk&*AokG+}QR&-S|r;2dKZC-Mlfy
-zMOoQL<^GV~o4x*K*HNr7GY;H?`RSm-LItq_rTc~xAxk8v1Xf#;(%Y=MUJ7CFUeTti
-zLL=9?2m<rfohg1X@@^$b9x8k#8%vNKn+nLYL!~BM6OWF at x7?2Y5KpIj*JfvTm1Q!x
-zdZ7^O2NQjyd-sme)h at kzUk#!WKIpSEJ>!%;xj2QeDNFC_%x>DF%|!xdD}uRO`@qPr
-zy{ZW)1al at AIT6*-y&cZ&Ingll(d*<lMd{K9*y07dJmv*}`WU$p at wd!YNYuO|LQ#%N
-zBUta%se<syxLqu>leq!G_bh<70}sm7H1JujWm8f?HU$NwuBDi*Cx#hA at r2I+$*;pD
-zvu+ugI&9xL84tcRQnNux18J4VNX7plpLfddXdJ(e4Srlo{Bh8d^R6fgp()Af$N&zT
-zAowd9<e!e;cdxLsgmY~){OCzS8NAOu#mM||BJH&0Ov{ezOP2(82;|z%6a45Iax^{^
-z7a1PxY4TCQ!+PP!Ul|;jSykM#_;{JQW5WwpzDE%NxKq>PUm|<$5BFisGjN<XfTC!Z
-z2Q at 3RDVJB!RAQX-0FBL at 5G5Ixi-^OtXZ}07OF&v34#E`GV0F!DYiz&TlDCcNF10zV
-zemnGQsQ6A<RkT=1L8Ch8q3?&k(Dc!wzRayK`?xSK?~^-C8n-t~l>A8Q-MduxBKRwb
-zJr)KyDFBdMh0Jjob%nk3X6OxfD&HD7;)0Z0=s-(3axg+nY-&Pgo<(RyC~wbedJ#~p
-za+&q1;5jM>nU%4{^ecm<3cV7TtMlSK1b9OUATdR98t>rwE&M#19ha at G^d8H_OJD~Z
-z$~erdv?kUyp?n?qnlR7+-wrr*>6`B5?Lm}>FBd#x`7sp{iTUcu(9;G^_jH at l`;3OC
-z|0&`OA(ov|RSoo|98cc>g~<Am at RRmi9<x2VTI!~^24HNJaG_G`0 at q`Fz`B*KFd+0l
-z$=}tr|0!o2AZ%X9yG;H8aD=H-JH+jEb>^`t?J0qC^Q=3HQnra=T58 at Kws@|O7&8+}
-zWTPx;+_V;N6_$q{UUI)9n`GYN*6H!W?f!K)gk6+_qcjFdNQ9yyob%{8OqEi5n6&FY
-zPIRGoiTf9wQj)=YI^_&hv;I3}HUDBo-Va6A$6~5c==naO7hSK311F_aVy{|6Ly!!3
-z*frUUWXCc*J}9OlJgtR+XBGTa?-pz-W<-D^aUiA{z+!JjAG08H at 0+ummBm6tOH-KP
-zjixv>X&?sYv1#Yzws_%pJw448Z7hg8ANMRu+<SO~h5+ at 1u<#k@>bXr04-jr>oDM6{
-zjhB#Za6s%|(8L4?^=U->(QO@=g&H1}7<YB2GUT)saL+g-lP=(CdGMHfGn(j$hF@@j
-z4TzV at V$aU0nr2hS3IY`6puFW49&06KNr!{_&PXNT&)?o)iMtvYpkgQf#>pAa3OU8X
-zCk^$b9TlR|<Mv2_`-};_Eh?(EXCPvQ*bAsIlmb>)mDzs|Pl*Fa4AxK8-F=$E+4Bd4
-zb`4T1mqcReQiA)43v1MzR>8lQ#GvI at 2UD3o&D-{#Jnr$FR-teLng;u6o>akw!9sJ!
-zKk6*4T?qIeF_X0OiC#bDAyjIoZWV>KP{$OO+175Ffq2J2-M#KoZVg_%=WxU(8*o&!
-zuObKogw_AJ01M!V*Gs&$%-$x=DoiZ^#eFtW6t|>SiX6RkSj4rECpZ$jcku^@mH+Po
-zGZ75zD!pS2^+f`b>j at cz%T12Q>YB<D)jRa?%@Cn=j}!_2EGa=dD!`w%P)ynCyY9BJ
-z>c)C=i(9oH0VNxHJ5nbZVJ3U2Jlo1lT*@qan4&wq5OD2lO#uffxkuZETw`f0-3D)k
-zQQ2A{0v^3&Wc=NHDr9HD#vKjUw+8Oc^3Yc_bR^uAh;_R9i%yy`d}r?R&cH|NLNMvm
-z!=Y>rqJ`6l?=_%&xRw=anf2eE?FLEdTh at HjdErzqHlBuC<*k98NES^65y-&S2r+?n
-z%+-*E0o?+Q*YgiO at X{x<!|hqfJ4xlTTEPPZ=7|*L at HeYJXNlY7R2QO=X#Pj$MYSIp
-z77iL|V1)(&s at i~tct1yN?1H%W-akE>(cdd?Ei7s^e|7f8yTbPI-|E?aR&P{mM4p`L
-zw=_{|Y1~`cS9AJXnB15Kkcug_P;~hdaE(mDUn<&vl_SfBzF>@s!$`S9kns=zu`4w6
-zVKpPhhpnDitYurxs01qz&)ykF6eN>IWn=<RCPc*qHy7GSIdojoI8E)m1ITxe3xl1n
-zI at Fsq=8;vgH&?!uWUgG<Kd+h}TF2E7^7k;#m^y$m1>5}DPbnvM?E6Q#eTx~?V34yV
-z4@^48BB1X2)p^LV)0wPblP*@3jyVEL1Y^c+VYv=XJy%?soPJ96{pz>&hxaq_SP0g%
-z*f2b;5G${3xHk8~1Bvdr6Vq;{ybIRK9Q|W!+Gm(y$?T&`@BCGrse`^ty)pX?U(_F6
-zs~$Si{b~0_;!&raMXkHo*Xem}2Y5Hg2_q1DL^>E&M0fUtzTs46B^u9zb;)6AH+|L=
-zQ{9=-DE$?Y4M-mu>XG{C16q!-$Ox=EwgOOGlJHo)=$)R-2km}n_WHs3Aw;83UWjy3
-zSm<Cn&7CrHAsKrM$S)WDqKXiD-?OJ7Js2agAhCaLCV7P{yQy7Y09OyRn9ESnDB3|T
-zqU$DLbN}QrOZs;|3u!r&3#~s&q1Elv-<{aS?f?3f6ymvWXI*{k^8L<;cUH~&l*6?u
-z{tE#3mZ-1XoWKw;=EgAbH-4j#r#7axSiMOu%zow2XNUcxZ{I|RXNGjQE^vlk`;Sb;
-z?y7w~8?iW)-0G*B{CSgAfE~3K++ux7&%SLU$gkhhq-PhP1mn^N^v8z8`gbAFQ5o$f
-zIL|?f?f0SL_9u7X#{gq>?E6;4*%<Bqo%{jy7PV}Vv9+DND1XCy9DgHlhV~!Cba58U
-z3(i#@{aeTbO3vuw2yJ_<oD2+x{BGxGu*7^9HII9oIx>;!l><p7NV16u6FzY);-R1n
-z?eUA{(frBYEx-xd9u!#s-1$yV^7C}A?eEo1qQ<?^peN^V7o%Mh4Gg9N*GqM(|FGA-
-zH at _SamvhyeZB=7Ei#v*X at W*_>otG#MF*ZFtIgK~_5uwTgeDb}5_H}PV+0cLlvDs38
-zUJIo7vJ2 at 6^Z;rKJ~mMwB;dsw+2QnTKeRlqP??I_oXy#5kXvRVEf^)2`cU70A$~F{
-z<TE<|sKz}1Jr+g#v$q%o2fIgw(zU&|t$k&VG;nZoR0ONaz^>F_`rI?qHDGm$GN4d>
-zrTUhEqW8Ie`k at 3h8pmntjoJDV0%@Kl=C<wxtb^qm$pTEqK5lkaY~wN+0g at XC1F(gS
-z4xVO%y5cS9*c}&G@@VGpUk&|nC^Z~Ezx6f%`uzr8K4r=#^&hMdm&U63iE}Ls#*eUc
-zD2)CnK!ixX`^)BPDHYCV=oFEjwbKu!@<=-CTE4(r2i|K<=H1c2SOdJuR$HBd<02)#
-zWWUMO<gug&N*xHty(O>5=LV3wA;Hr-r)Ir}a at 2%=@)5_uuGu;oUh~uA?ZM8%C2)Mi
-zq6ULxr&`s}x^mH1)L&a)JWNj&=9Y~s2lqBmw8<jbf43Tk$Q2OW2^)Yz&LMr$KU?H1
-z0Zv4h<T=gXxnk*rA!W~G=&tAXvr`R${At}mUQRP_%o2(A at JSp0GmDP(2aKnmg5(g1
-zXsZ#Tq{e=@lV$^8J8~mw_WU+=rl_ZS-8`+`noj*cOSzN@)=uQNzuPIp&Q012Z^g<w
-zR?61dtrp{jgpoW`LWK={TAX(o&;BqCm`s6b;+A<V2 at L#5Gll4Sal}k&co`(AIt%mf
-zM-H at ZLJtIt@?y^ZEY+DT6KqWtn+#;%vqjLr-A{FgmOJi_6?Z*^{dR*2n^<D59~Qml
-zFuM$o(%ulBw0}Ke$I+AN9b4$R%!n>t5JY449to2 at v9$>;XXCR(5P9U1NOE+SwRDbb
-zZ#0<!&ID|^F%K`X1K8skDBQ~Y**YhlJG{^zlEO9SY&j!D^L=V!0L$wn3#>@!Wm>Mc
-zp*W|)>?4)2f-9GS+X$ad%ly>L5hza9T`|qtpka~I#`lQ_AMK^l^y7IX#PxF}K%luu
-z??Jw<uBi8FCTfpQaNhnZOS-^?jQrQrr>)1j?!%*H*o2;5e!z`I at 5~{gW4Sz1vnyfU
-z7c)!V>m<|`gNrcdYnJA}ZB=YV!O8cgXoxIcA2I2e5 at hCchCSIRu~@4wE(#<;JP9)p
-ztA}oGQDq*HZGSlf^>dd~h~4Ho?*~d_$+aqp;Sd=oo^w78H1)P at qBGalZ^>#F0|ctH
-zUS0-S9r%fwx at lv{Z^U5xf}5bY!LxsF^Lx_5U-9KXAYTt2n`7+Puc<P9^ei5 at EA`B`
-z=;D`Ol6y>c-E=PegC{-heSROCYVq*(Hp at XYWLu)`l|tQ(8u9gH7VNj6C>~oEjXg|=
-z#9{enwd~$uDAs6Rj<&bh-=bpl(^mBP3K#5oNyjfX_3zCaqijP^FQWvx2M_<)OUxaO
-zI_&G{Jf<OXq3Y*s)ODM0a9-Fu)$(B)RKdm_ea-NJvp-ugqBs<U6CYx at cPBywxu=v~
-zCdmcbY;5%H`JPonkYP2pSE41Ep=h`JV`sT|WO$;;vBHM}>e}UOvaG3mOU?W3+cec=
-z{(yU+$K~|(CM_g5Q&!5j43YS0s^(oqkE-1E-?n$g#(Tl0^jWP9h=ub=6tn%hYJFy6
-z^}eEf5_mYfxZYGjq<GUJvXOw+V@(nj{hbm2q5!h0wq;M}x~&1co?YVH)Lg87b^Q;~
-zH(9 at m+}ai$4s<^IPJ(~tmRKW&hbO1rzjO#%H9C*m3HXwnKKxf<xV3+BohAQ1KMLg=
-zmV-fS$yq&|K|*s1*(9|npajWmpoc!WcOZqde7;}!KJ|QAE4*Cvp;^}Q1S9|KUY`iZ
-z;S7<7XVL;d{$eO~6(%i1uyaTaR*9UP$*-<@f at 9xXp+4NqK5&W96xI-DG8+Yq<Sn-j
-z*)kwnNH^@Vp)44bo+#KLXb3V6-(y#;?E)w$9~teI_xDfEvlQQJYJr&75z&hg^rLj%
-z7t}8C%a?*b2!e!_D2_?{W5m{vq_a(|N%ui8S6upam-xH;#cIP(DR639&2C$OGAeb*
-z?kLypsQmNOu+~6=3Mo5eTc8;)^ZtkA8_R$u=a1)?4IG88j7;hP|Fc(SXt|YdR+10X
-zczaWMQMwju$+bjLCpuw^b>uXx#*BY$CcCXbL`0n at AX&lB1pw^&@7fvV7eSZmYQ at SS
-z7F0+ac^G`caGjgX+8x4yZyiFQpRF}Hi^=XROrnP%*_O`*ak!a=TRc_o>w55aa~wy-
-zsJiwKL#?!XvDgJXjyZ6tT$(@UkVLj;^x9Js2b7qJRwI}Y%7lyn&RPdRIc;VB#_~;X
-z16;-E^4rI)z7z^_J~I6#q3hF-Z=#)~Qu1e6&jyc6DiidsX4}I?00fsbvBdgvxWiB`
-zwjZt8DcgBN*weMOlmcYBg;ispVYa6%;K{*=c_<W5#s|xMV5c}ahaz}QjEMXJ!cu*_
-z6dUo$^p?LkA8+c<W%E3 at 7%10|hWHN at lseU5dAm1KKX+KN?dz-?dG>>U$}{;OIsH1I
-zGMDXd=-F&EZy5m-g?1wY4_$zwU)*lQ!PWU~<gMN?+1L+_2@!2z4l2L<1Y&94IuFOf
-z#22za1g~<MXFGw{yjaoq5(F2`J*Em=7nL#YoLa#1Lz!HF at 1H36&x at H5&@f;Np<$^q
-zeEQt)6&pl-u=~~Sdl6cG=@gwY|9fM8zE1?b!@P%3`81@=ht1!Ox7DMEW&{elSY27R
-zX_O$#B-acY_}napQZ)R;LRhPMYXus)Re+C;4SAaRvc0ZJ67hOFrYb&bVo6_tly5u1
-zD{(YFAjewFQD_yFc>#MTfVQD)gAf0E&Y_N~=Qud|E0Zl!_|}=w-)99@@1v5AjV$O~
-zhGsbDL)esAo>;4?a^|<WhOpvQL-E7s*KwaY7RfT6yerujjc`7;@NEM_o!wg+>1ov8
-z;oe%V5*VsZM2jV!W5Z78a4s?OY<8Bj!)04Y?S7a&80aP2Rn-5^LL#UvSrU^f&?0oY
-z-jiv~yPUi2th7UbAbQVgl3!!Fv$2ED>PFbeR`)>)m5d{#;#TzUoHPX+>1fnHgk`yQ
-zcG`S&OCozQV at 6bQFhftn2a?S6X=vyoa3I_|;m;E)20ac?)33U^n1OZHKl(pMhJ*X_
-z$Ac!=tLw;HrOOl-0JAUbG|wb<;Qj!82uCa7umD`9Kgr;Kl;6T)kcNiKz%ccpE}8Qj
-zy2=sO+LqAtnT|M6t+HjLi#LTfDtr(hhs+lgllL;^%-QA}CRZMh75J_HB~rG502 at LW
-zHuci*NV9%M@!>?C4S)-dW_yW{4e28R3laO7dXZ-!xR4R?m|gZNGhZi-syJw9;IC1#
-zcJst^=liiBz2-`C2(*?8GNEa0>h-$RHW=+CH1gR_w~g#sp0W14k#2UNN03IHLWbiZ
-z87snAlPX{*=`#R$&fAKlC^>Axz9@#f8yWC0gf;Z2*WU020rgk?Rs0d*;V;-5F5BUJ
-zG<r-G1B`(@kZaE%j*A_n&Pd^TXJl at -Vg`P={&r4ile?g(aQa|@)A#iOIuL5T1CXK!
-zxfk)znTuG7S#;sR+8$o%8;{X^a+r^8DtYTFJ+ at G0OPz=nL1`$(cuV!$0qEqIenW1e
-zEua<Y`1T&SidXTAu at ych{gNd*-+!t4_~xu|-2E<cv;{X)A9u9MTQ6?-2T+)xtMeE<
-zwU%RF3<Ldaw at 0uhuiZzfEwx&D3s&``{R7xqZ)PqJNDtqF;?uBlP#{iwhmSoZ3*XLP
-zJMDdDsg#vkifq0OK)<^+P8r{GhuUl}N`D4?B0k&~o5B<RUYnQ8-}=z2?Nl&}!)DK3
-zfjW=;@^@TwG=im>v at QdC9erD24I+!`PWsq2>d;~F@!XU<`gOHCBE^7YpfONw#~$-A
-zrZbfhc}hMW_w2-K_=g$)h4rinYB*Ma)<bT#Wf^?*Z7ONGdeDggQ+OK){ld}eb7ygd
-zps7mmAFBzEn}REFz<?R1pT%05l~Ys^jv}9C_G>rh1VrteI)X_>F9+E{tEf%Tg!A6_
-z`6TH+_56E6*|!n>r^QnU9FAgwchps_KKG63S4FBbC&4x_)6T!i2c7A0SM at owa;$@k
-zyi?|oO{6(7RwbN)t65Z0r~WYb(h(>jYW1uwFrtr6$1?2Y=F6(gXvBxS2M34Z1 at Nz2
-z+17|WM*#F6X>DSdJ;Kl}i at R+ertWqkE{{**_v*Bp0T;4BC4D1$rx{~CS7}G$f#hVV
-z+Xl!?r+v!Z-=_}hndzG8dTB>c7J@&X{ubEP8#TmYk>o!clKcJ+6!H3I<2c*k-Te?s
-zz(gR~(=n-*#Q*TK9s->Shc#G5y8Om<rhqax#XGW{KnLTIQbA%P`~IC;S8XyrJi_n4
-z74(T!@i|CR^>w389 at K!)n|)*3 at h5MNcH|nSfLhdZ?j%eNQ%8z}w*LJpv$agk*nj>n
-zg0-cub_+ACZ54+3YY1FbU;Y=dFqwE>wW`};&9L0f#m%>|{<^N`vl*uDNNG|E>K-+V
-zW=`z=5&Z(*zp`Vl!k7*&m_%O*zZ$~GS2J_P8tsd8_TcRQGN}|`V<r7A#Z02MOQi-D
-z*A<~6d^X1~Q`hI;`-8ui2{6urGa?3=+aGwEdLl~^79NU<>MIT`UVk*&)BEr?j9A|!
-z(%Ip4KQd55q(3nMLjqS1Hcx<gt!i?f(8pQfzh6n~%X=G7;^OmMDPv8xMn(xpXHK;$
-zXvI18shfhU<{LYMt9BCyT`rx^rM at jm;kIF{0;$ikDv3VVVKL-vncz1YV-p>7*0}d^
-zcwbLdf4xT)Y<ZW1R39^BNVfI0^c;?MimKK8Z6Ar^Kzjkf`u^lhf0obR2|n_cj%M0r
-z4>$A`{gxH!y0;-fY$n8nO^1bo=89uS??H}<s(-L)V$aDSdUK||lp>txQ7tHIPv(N;
-zr1iEg08&1+5a(|%cly)c7UNJ~NP8N%eYw}lA&P!1?6kL;8p8Q@;FXHAt(K^Yw&;Kd
-z_st{hmxz8;P!4haW+dJV;fiN at 61ap}MxOTyIq;JAC4fK1hvQT=KSz1UR!axH!UsNq
-zNO;W``SxNHOL7}-TfQP1b!$$8Sq3Vh6nz$PLPeEMbo>RPa-qgvyC(6;4G8=jjM8mc
-zw>ck*yh3@)jJEC{O6Faf`OXlf`NT$#{Bpxz-bm7aFb3AVK*~%K?q49?>F?*qdp93A
-zgyZb5C+UmXZ{C{~fvVx`5D_egw$&vaOfJDCx4wue%>+R2#tj5v00FpPJOIR094U`J
-zaDQ(~|6x|j{ic+Mhy1be+AwJk;j2Ahl?h**DXBV=PVI;G|C)<?bP?YxEV)%#+ND}W
-zF>?qtJ~9BX49sBGg7aJX40rk%5}CcYeYnJJJ-O|@fB8SW&9bR=8A^XgIkggxX=rkY
-z>K{>?#~yWhB{EWEE+Yd9+ZfBYXZ=Ly!Xm)}a29j~XymigsG}$^mq8n{8Pzyfc at qb+
-z1Ihee$C0^Ca|beDR-2kfcmDr-j|(>H0jJP_vMJ)%azAnnPz086Ouk-8NviLEM}>_y
-zD8{aFS_OSZ^cU|!&jNV8(E#6n3 at D#+jK~M^H2e;iZOy7dAg(=ArAc%9k>Rs(?4U6i
-i1I_=1vbpqvH|z8$)kZMoi1^kEASb0PS at p>z=>GwBVb%Ho
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/content/about-wordmark.png b/im/branding/messenger/content/about-wordmark.png
-new file mode 100644
-index 0000000000000000000000000000000000000000..52923b6cf08acd09bf329142cab8066a8fbe4794
-GIT binary patch
-literal 3754
-zcmZu!c{~#iA09IdA&ur*ku!Jhb2itIGr8qzYwk0W#H`$Ri;{k3u2t$M$6TdR$gvQ~
-zeUwnFxyc-F at 1O7I^L{^{=lgu0=db6V?;lUPy{*M5E)gyO0C36 at W$Fk3uqgh$FLAQ}
-z-AiLj7ylAl6w=a(^Y7f at yq@+~gTqm7Q2+pN<-cHQjCTzBYYIo3xkg_J!$imWMxp_+
-zv9Zblp+QmpzTs%)u*e%vejA7Y0KBr6rU<87CG at 9p1jrY`)OR?rWDfg1whu|15uy?4
-zY99>A`FNQOl9aiby+gT-h&1&5F!oz}8OfA~i$vl~Z_ehvh;XovKxA=}`STH;79X-y
-zc}$M?Z(5IxT-|y8>*`JIc81ts{_p1=|K5Hc`Zkuqm}O0UzYwk?#{2&$r=WtB%%Nqu
-z;Q9{KT at hZQF)r}5A3&5Z^XCE0vcPut?@HN=Z$VGkm9 at u1_2*rE&iQ!wi0d(AqL1DH
-z48WIZcg_|HQ6;Fp)LE*Kuzrww4;l0is0zT%69VHaf%q!6i~=nn`-j(kZftAUb?9{F
-zHtL5<4V_)dx@$7Ta85m at TuJ(h9DgISAMr6_aZ57X7dIFNxXr%S#_G!ZhQ)wakv2yZ
-z!1f+Iuqn{U$rpN=bW9x_y6^kM$_E<$Y)}i%Vhe0fizqorVl;t5*(t2Q0iQri%OUl;
-zwJPB}B8)%OZGL|p))~1lmOVfbOX*_Bh~P>#Ou$<G`@S4CG<N><JdWSLw`bLN6bNM-
-z1&sKO57ybGg-o#~0(k-5z#FWLrI32*aMgqOL%w}r?ErNb_Hkk~1!`yH9e<}?_Mk1{
-zcYT-w(E~FjPwiPLtL at Ni5{dg!aiTx7ey<;AOXZ+G1y3-FUMCg~YSkz0g2m5iOu1!Y
-zoU5Wau7OgZ!5+Ahg)M51M2;Fjx9KS>rHvB`?F at w~b9^$dFJidX-p~tL!-dY4t(0Lp
-z7pR_#+xS~t<K07{t{A`^cZ;2OL*Gi#5p}yloE8UL0XeaFyHN}|A7LjjP+mYN>j9Cw
-zn_x!8Vbh!WZ+*HkwVL-G&WYuW$m+$$?5J!rr;h11Zuc-Q)xf5T at HaG^1uhfEG+Eo@
-zEGAqw at 26KFp_c1x#cuHXg&8U#m-`zU0 at ABqT6j>VVEYmaetcR1r?S{>&zIEqZAxeK
-zWFg);NbDj$g`Zz2xmviKlqx5tV3{dI^~R|u at yd%aklXy+-)rhFo7Fczc$p(79_X;*
-z4;kvztyys*NiU=q(qSCa)*G027DV)nwOa6-<iZE<w)c-ceROIscB`2K at Hm>^c$x{Q
-zR-hTyMJTAy4~K-?@QAuNwEI3 at c36AiBHgN+JhpIzvq@-A<n8i2bj2FH*(3_kjNQxU
-zxBaYR?2K8~OcW=$`yHrWLTgzTUuh<BrA<innz;`RC*X|lJLVmXhF+sJhN)WHjD3s(
-z*cQP%sXz?rG+3N&EB_JPvSCN`md5-Xbw3mzLqV?WYvteEj4gv4poM~+%L&^Ykg$|5
-zz*|$vPu;M+1iKrApFs`LS#RZEy$?hp)<x|Nl)*WsIl9V&Bpy#)y_y!|IY+M6CiWN(
-zJyI~z8sd4x_6YyE-f~1R;PaTI?Ays3Q)^+`r)jDxvc>H3MIBfSYfPP;12%VCH6rdD
-zHnq^U<()MLWVx<G>|4-Fl4JhXNqycKSW at zo)-%je0)NpT6x=!I4rjC?<$WOT^HNW_
-zEJ`$&?krIqelA=)QVzkxes_6e#)?2=)g_mq2J3Eq()zMLs8Pp at 1{H at gGRGzz0@59a
-z&MqHLEgFQ>3+NWNK8hJ*DU~>leFZ$c<UhyWpT9(gK-mp|1}QVCtGQ{hUOzTr3sO>*
-zrs6}CN4zhz-K~E6)rJHSuKvO+XVnjPEm+9Dx!UIT8m&*zqhIxTqN=@i3vwqn%6A80
-zt1DVfUZ2pioCU>neX8>X6(lU`)l{Oyn!(5Fu4mc@##KN@$j+~D$6NAZ4+H0ItSQct
-zai+R;Abal`#RYyspk{>gAE)w5{BVa#u%O(r(?>UiPO7FLsNgLoO at _zsD6;mELGq=C
-zS~_R;H5m1`2{?o4<Rdhy%j;s6v1MkcP>6H6 at S9WZop2$qzG${z84I<x79vk|)QSsH
-zHL+GaqVKx(>DTO<s}s)%?Cfw)4&fP+KXz-<m{W__Aj>+V$uC{x5B0CHdRpE&as;aC
-zSDkvI0Z5ei=kR>#C#rxoW!980Kk_<<&$UV3AijC?%w2N<rL^&ko!2C!Y5H82bgRs&
-ztB=42epkyCU+3856IS(bFgW at O+$KETre#Cby=s?o{a>zlwb$&)L8{gdkEz=Y;$t>)
-zupeC_4VU$Spn)w-gFg+3&bPG<9q|1X7vj$@q|>7VJSUUawD+Flg18TS-i6%U29Mm-
-z5(bu}E~++><~O at L<4{XJ7tB4=e`kiNPh9{ZY>E+kN5eMrX26Rv1N6J9T$L|-4%WVM
-zFiCI8!gXy9-CMu-nZc>7bV}6`WuKqc5M#lYr+_;lO$-|lBunkWdpO`#Wq`!QQ8ynB
-z$XxN0*M at xH$jp4D?Duz~#Y;0vUSH4)$<v9|sg<!w)zq11uF6e6M~h`t^Q at 2m%c|5x
-z+LihHE{BglIy9PS2SH>=QJmjv+0S^n9ZL>pxSins3`Fy;TI<Ci(+j-v9!!8~0F2}Y
-z=G4NM at ocQF0hrdlXWV~?$IX>rOxAM(F!>j(QeH{8zg=ME+UwwYFD)md3+~nLyB}bB
-zW at i?ks9zx$%^^d)d|aWbKlW`-ue$<pD<Uad*@(HzJHGdYmFdY}Yv(N6P}DKL_48ir
-zV0ACq<sn$f{sjT~>`#<jXuR;1=Skk at W%psfQqfGrxS-%~Bm5`kGCNah=GqbzPfsBV
-z=^^$Ti_}64{qc at il@Snat*1N+esQnA0psfNz4TYYxfAyfXNT&jFAfs5HE!~>8R!bq
-z9D^^xEFqWcTsSZ}-Zet<TKgG0^)D!7(*V6<Tte_qsI|STkD at ziHl@!e#iOni;y>Kj
-zrr^F*)umD4(RbrYgJ<K6?+3!fEft1KxvQ6Wv2W=;v19g)wgxfh<s=5aRpJ%m?1?jM
-zu8FNZ*H5uZ5lQzA-ePkXDCWGt!O|qFn&P(svMS_ZgPGb&+ghX`2M||55Axo(cGe|4
-z(I^8Pat>hbQ`VmctfhN71i9Y!-Q|CRbG}Y1I2C{f<F~bBo{jxrnM<W(bnw@&vt^Ud
-zH5PR%SPS-L(NI1-T}z?!Xh at A+vbj_X^q!w*<$z*z!d`Ck$;CdGHQ|TD*qxEAzd7w6
-zr>B4C?1S7lJo^Cl)j>ElR0hsYEEKLJzO_p3AIh{S at DsEWBbek?Zw)g}R|<4u=;#(z
-zVd=@@9X;!QUl7_-Ph at -rvYz0I@SN7ug3ltC7qyqp$SctWQ9+H>(jKLxpNYpjWNyq+
-zmkn8>rBGSxnc2iExyNg<`P1L0Oo3eT8u6vZ?z{?QP4hhUK%Ae`wHkFD^U2H9HcKyU
-zjU~rb>jvQ%?=DKxl3TS&zB7%zkzigmdN0TUqZTX_3KR9#OaeDK5VPczQX8QsK2wxi
-z9HWRyF?i*U=jWeAf+^rzbC2+~BVR_e6y!?0GWwR~q8?d0uVOMIPe0TmM%KPS{@xQB
-zE at mU>XXXu#8%q)j- at B(KhPSYum<Qv5YaETm^6aH$(TAaNr7lE3uzU<Q1S#y|ftaOX
-zk7qxiSENNLa at BPYIfk>sPxzSwru4eZFQMc|(^l8M$<W+8iC>+M9xrKYqh3T858hqP
-z>!Uz=1M4Cu&Q&hCRKdkAVEmQuoFZ}4y!-x$Y|JT_RG!*JpRtVMwGvtk<T?^i at jg!{
-zxQJF{KNcBfWj>L~4$!NSM}g^Pf`Lh~^3VAUAP-j!auOAadvITsvWK-aQHc-qj~#!;
-z|LAhs9PK(CkZq-~IcIgKc at Z)<)v0#C|66IKk~)R at l{Y0KFL&h*{FslP{jgE4VUuP8
-zw at Gajs*F7%BOAT#NY3>p`GAqk+w*qL=0!Z&sGHN;TMQcqq0rl}*{@UCoJ8`^#dGz8
-zKl+|+6%I2`?rSbdpTrc277 at 1wWq6W*As8n0jvm6(k>6q}dY>mniwjYK)H$U|eeV5S
-zvv|wAHbnyw!S%w;so2%w0<;s4sF#E6kb+@*A|yRMH!C9Rfqnjgf?6;nQ*ZR{5^3Na
-z{#B~^=<PU-jRMKLk9Qr>x~)BY$=l*W*i(rfmqmlrV}55D7B9w$&rrqlb_0<Sss112
-z8nWIduXoJC$h1vi4Zh|Z0Z8>)1=o{Hd8%Tmg{WoI at g^rIo{JINvBt8i!Ie15|5Al{
-zjcjaqSvKF%SL5+~yqcKv1xI7P3-0rO3?XwO0a5l~_0vi$?)jlR2~J}Y)k8uvQf;DZ
-zBfQeKFyq8IVnMlkgHyZEO}J_tllF<6vW}fseIxFto0m|!z&Y?jTp9Vey9IU0Kk{VP
-zxc|ARL-6L0p$kezBldI6FKseQSJxR35i`xZ;-4kGlGtwErK88n);^1`^k`e6|LuHt
-z+PkD_CFKW9Dq{UM-PK81YBuf-j<xkZ)>Msjly~JBQstXxlG9rD$KGh*-3+$;*fQCc
-zpN|TO^GtcUS9?acqlPX?aR=Q0W?<;hvBfpoxT|Ku1g6QhdfL==b*d2OBANV5&s><~
-z`{8j63B6H`GMHgeI-(#V)2^am;UXCI7T*u?VT*SPhM_sY6hZ;T-^GciL at D5zMPd?q
-zMN+x)+UU#SY+b_-MhQb*=t(P#{vvs+KG^N{8SfuQEK7FNO6ompDWPf3C}=BN<3~4W
-zlp;|y)_ZiO9N0QxWD&?H!XC53;4xCi)+S$xF#4Zu)B3hbH9G#)o?-g#?k}rtO4UCr
-zdx5zyp_^pdj$)@~`7~esC0)3Y>DM?T4vbN*yFe3YcTx5K*0BFIa~zjXct=DJZnCLD
-R|Mp6NrJ1eiE2K~Ie*nv{{Ivi8
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/content/about.png b/im/branding/messenger/content/about.png
-new file mode 100644
-index 0000000000000000000000000000000000000000..5d7f5797038d8c2727457cc4512401a3404ecc5c
-GIT binary patch
-literal 9880
-zcmZvCWmHt(_xB7#haeKt3P^W%Bdv7DfON|s9YZ52B^}ZY5<|lP(k(HBln6+J#LztR
-z{k?hK{O?-#-gEEz?0wEYd#`hLoX?u?ln8JsaRC4Tfr_$%HUI#WLA8HjW1^lwc^@X!
-z3mqb-qKl2X0<f*4QQtW3%0>_r9`WA|lw-;ELH(rgR5bL|akKUGw)C(8czb(uIk-AO
-zK3KZjaJhNdWgkmW0syZ7Dhjf?J~>CLz8Ta5nH!rH*7^n($;QYCBDq&G*k(0k(Nv$u
-zpdlDEJAC}Gp+WPylQW;iW^c<*+7F3|G^aj@!G6J)E1b_DMnXKlUU at Rap%ec_^IWfy
-zs$%26O0<`q-LI`>=c{7tLHh1HR5bF at w|DGU4aY at u%V56_CzAU=9wn*~s{k!OT8noY
-zcyX1}-;*fKcEvBS_DTF+E$<QP0t%wpJzaJkaBB3%Hu(e|ffyRgT2a*b^2Sx5WsRel
-zH%q>k4u=GfWyD&HKuzk+ne at GNEhFBUj}Kc-3qx!*gLg4!xPq7$_64vhxqm4#jcV*t
-znpqkw%_{6&&ufI*#4Z<pVZuymEfm7h;n=g3m(vH-C;rFkN)-;2fia<<DF-7~VNE1=
-z)78KQ#~K6igbwGreA7T3&`5nYlWHuA#y3Dz5Qo_-l5n at +(gCgx)?7Sd`|^yWD$TZH
-zp)*6>m)l%8HrG;El|&c^YIE4O8+}AUByQF_(EW3lb)tg0Tbdllu}1qA!{S^(Z*3Nj
-zX@=S>R^ek3z|fY`!lwR(H#Z_iEd-A>pVqva7_MgDHQfKSB}m|m-62aKKnxg@*{Z_V
-z*E?pO8OP#6`)%1$ab3|2mn+ff$w$CfEL+}&%cFrmx8I3Y-V(akostF at 36O(a7hTva
-z*)?y?h4-Xi>9`jvq96{Ydb|@ekK|1|lz;xgritM%C_n8k-_Gf at u-w;EF&-uZ4ACeN
-zL<TO$X~t(5806urc`Tasvh0Cn*%!eKU48%F0PCX#xys&c-W#Oevhna8UMc9}Wpz*w
-z-R=GIgN3iY)G{On#A<G7zhz^-`jq-e%=7B-3LB7YA5>;_oVcr at R*loaTgbx*AWMo$
-z=lKEou>N+h4j^dRqI98L<TDNFJTd2wzqAy7`$q{4{M_F3U9N}Ky4*n>=%L>=aadW^
-z;aKB#tp<@ddiNjZEgCr5bw(sbzfBk*{g$8p at G3f|>D&C#+0`6jtwgLm3S*7pqfEvX
-zn_EWn^u#hZSHD94uWTcbWIfa1<bmrD7Co*4z+ZG*2W#5=?9%ApO<E5Y^^?6@)4;QB
-z;5v+q?jE7yks+*gcbh)t2OBQBJlAgy?fzt+^3=H0s1mXIaz-2n3bZ#J;o0u+E^OsP
-zG2E~>j64Z6_6r*r!|4ESANP`ek4^J3P&<vK#o$lds&zCy4$yGgb0%T9DKh+5=3VaW
-z;1P@)AbJQRiP at EPq7rCvFkVT$@vbVZnFz3OQfAcKHHgO~#(~so6V-{_>t)t`jISza
-zr*w2GC{@)m0W}L|Ejub|kZxb#26AX^J{(=@EYf+&|4<s;-PTi}Oy?)tew6L4u3t&U
-zTaN;1WIbraJYWgj5%zV5)%V~`_cr%yP1liO&iB^$^4J$xO#>!2#Pllbej!u6$i|(N
-zxo|pO_pwZ*Ydtq<{n>>+;l}z+os+Ys{u8tFdd1RrtY<<Ybl`$9eGW`{OxCxAh&amH
-zm!j0azt@|jefKK4{@3YuQd>_&kJ7mA7A_JG_mO~QzvY7yRX{xmb~NX_f}`;!k7Z4Z
-z$Fm+Mx=4xbEupY%LpkfGyR5wmH|5b9cNG8!bT^LyR at UQ>6~i65`gN_Tsc#TzIi^1W
-zqZwH3A4 at -gXK1<qG8||vn&=uTEcR`x>FanLtZ2G;u(k|Chf92V<|P3zrSURpcXEu3
-zKk1D`f~Tb7xwZ-rREP*(2FrWHf$swp`032e-Xos~4pH)=Rv8|`c&EQg9e2uFZ&>Gd
-z{$1603sS8!C(G6e*MhbN;eS%Vf9kFL_NtnfHO!j8lqUVIDsv>WRRzTY-J at W(+%nQi
-zsY4i`3D)0EP=7@;@w%;Gf406iCWRRu{&C=Ak7h5Xg+GK$;M9E4<ufr3R1{_EG^2sW
-znehYip9*mFyDNOXV>7$y8+0h5MwnSkb9714hfJuqbJ;V?!We)&YRH;WnAkQK+T^oF
-zny4(xZOVyuf^Ery=czvUOu5*z at AP#e+bhcbhGr at tyF&Gn<N68_=x`2!+Sj$qtBUZP
-z`epa>fs1R#(<QC{I_OLN%=Ux!TadidQw|0JHGUO_)@vY-ym1k&>E>G4??ImZ_r9mM
-zloOTBwklcmRi(JL8V2ej3mofsIlpg~AJ>?<a%GgTo0THb;rNoRd{^={m(r11NdJ|M
-z5}PdfH&T{uB=MBrM7){stMR^h40N5B`sZu04P!*l&;xlugteY^^I2G-wJpsA<|ZXZ
-zJ*<DT6b%wUDNJyOS>02HLF1=~d(5XYAcB&D7;rb;Dj{XW>c*={W!-h+8cF`uF?r;b
-z6X_m)by)0VXfFs9xKeyNA8~G1nn&31v-}GnWALGlx1fO at Mtu=puzwNY<5IFymn_%F
-z()Mh;(m-8`7p_VwuH$owSZL&g8#Blf7nW*KKu)mvu4(K;qsU+P)<yeDbvBrur;`iP
-ze1@{k$GJEA*D>mGO58+T6 at HBHPYaC-t90up^EnpOQ1$x4Lh<QgGZ~@>1~IB0)J-^@
-zx)GMb?7sjO!v;&@bZhUJco?H^*G#dv>!w4Ps7NDFDtMoRRTOGu@@r>vqSY4D4MWR_
-zWcZCcVd~an93V7*q5hs=Vr=Zqby{Tty2MR&W+e&KksN8@!D=e<FZQtXqs^gd$tA?_
-zan+uHn`@@Cx!0ES%9mA{X`CSmsvBjLa_GB5?sJ{I_EC(kHq($gR$jujTVGdB@%q61
-zypSXZQfc-3EJPQ%bi?1-0jj7#t%-+y9G_ylfXl}(^CQbFW}I2Rzd50CnO?>};+$S^
-zq%{vI-DAP3bQ&+JB&&2RD9yhKs?fxp6xHB86FJa3nxR?yj5i6+zswpnea?u+MqAn6
-zHsW^*GB?tq?B!kpMm>{(ybz!ZPaP2bye!<?+&tz;zAfVt{MW#acE0&Fr`p)`rg@;=
-zFGh=I`|`@TRs0G!lbSbZG1uE9)q{c;IyA=}_HP%f?Y1cmZ~e~JPSreRW~D^x$&Cpk
-zR<jZz?BEUXOA!)Btnk&WwE@%XKQ{|0wJ at inT$UTqIfEp;e>umk at DQ`dTd2Qbet`VG
-zDKg9-Je81$gvZ3Ehj)ojFwjQH_FE2PL+HL|6iZy6<DFV?HMK{!s<I-<PNke`BC)^F
-zzB;}3a9mF7z<B9cm2lJ{m?*7ds-l*H^FsaVsL9{gDP;=|?d9=IZL>2}$Giw at OE;Y0
-z&hShXmL)FVsSS7KU70-=$?vy1Jy3=>){(qFJx{I=#Ov(B^$OH%?<Euy{<sc0c_bC8
-z<*cQ3*5Q|ES=_hPCGAcKoG{*dPIN;H{=iTxHfcr}*P=I+Z!zus2-n}sJeOQ-o;TgU
-zwaL+Ohl5{=l2umryMF$7r9M#nqMCF)r~Gu#Tsq=m!I9-d(g{#(sGa-+?{&?(vKD$z
-z=|lbFrx$=R(d!V3AHH^i&MUgqUB?4e0$4``ESFX4BKa_Vzs%SGz+BAKB3nmSzq&7u
-zP6J4&$A$KD0oe&Tutwv(_rt+-z^h-dV(rtP+WvK*nrm^Vi1apPEI4YjM<3XRjavNk
-zgHp)*O*hdk^jLPk)hh%Eb(03UorclW?**EaRE-eURAL84^=Xsr0sao;_{x;THy~-J
-zJ86FM3D;Pz*v=lDGj`yE{lcga;VXFNo!TaNecg3+jXEB_v7UfARWr+~!)-S(<f6`?
-zn=l*EOS`0dhFvpZ+tkWgob<cY*05zpfA5w}CHYI&Fedy?U#F at m_lOfoi)}Y2oEc8w
-z*7ptD;@{PqG$?^ne+Os1M?9=KcaN8lvo6E7<PRU&62LIUV;7(&H2Qe3(u;gd#(8nS
-zY#dtCLUKdvY()N!NMa5 at n{yR!ZuG7=H+js!8uY5X(Is_x%~D7JH#t32!%enOa?wvM
-zbK!K&FXiyHy<2VL`CfUN*pO<k4MziTTFC?lN(IYkE|8t+#tAyA>76&?3ZR2k6Lupy
-zUDDg=4DE3z?M>yAYT~$DlklP5(n at KeepEI+RPL?`HQBLFHwG1FlKl207v>yPN1g8+
-ze_i3S*By9}jsOhB>whz{+%wzwV>z#r{+j3k`K!}|lJc#w0#04)KN;gfuYGimQcd&d
-zDF8G_ at 0+xa7iiF7ElPYiCN&xr(RnEQ2=;crJX*7}OYW4*)xOpqGhhT2yj{Y9iiaIM
-z94%U1trA5v2CBKg7-|+mqT!iysdEKXY_lf=iE0v?wGNNFddKBm#7Ugp-mqz_EYgf0
-zy8;f^oVG#y87`Tl3MgKYNfBJLi24&59!a=a!)Sk&q<H9o(aHD5l9}Pbx2EiG(!VKV
-z%1mPrLMJ#kFzOejGI{p$!fCqgFw;Z9tcqU`66{*jlE*YrtmH at oX3uvPz<$AZ-Vu$1
-zBC1zM*rj<pWa7bUHSD;LK#N+GnBVKsYnuf#?t-J9VQOm>H#cK8YCw18`{X2X&2&)m
-z>F9#Mir?_mG2Peyp02g^b$=}d?|<h5u9PSXfmniw0eFnjdoNsSn6Pp0LT?LHjD1#p
-zeuBmgQDmF_$^Zj+NvFR_1&*Ub&WBB!@}>xccV>(&K(~pseb^B2f=~hn8lr-cD%wu3
-zf6XVTs{O&5B at 3uYE(I9G3(^W?RQoKTNT at 5*mga&kLq&JG&6WlH($^#7=)@?NmSPA{
-zDPd!KWy=7#O~6mHVMzvR>Rf9S-^~wu;cx#?ovO|bdEo4_CH`FFh07(4vJ at 8F?qpag
-zCEFWPo27CJa8Cm8p~h6OX-c~5^grGx`Wupf?<v|mK3^`-#zMAaTmV4#@?6B2P)Vrj
-zsQxW#y0k{+=;>cdDVTe27kEK)_gGisDP6ZO8z$d=+h!{SPPZf{dXFpb0l$V>79Alr
-z+j*R$;}Nm9RS|My`Y4tBbZm_GP$Iyyl`5z&t0cRfU#hbk$98v74}Gf!7?(pK>Q*O&
-zM&k#-hgw3aWU>^2>O7Zm(u0%pa=300X`y4fj3DsXw;$rrv<r+OBR@;LJ4^z?Qsk}(
-zk8507p?7d)UQ11?X(?)?()`(8n))yjF)w^wa*3s{^_=E7MWOo- at y+};s{OHiXgRqk
-zLz3 at tDAFAY`P{%Rukz9KrFU|P9))B^Kyt1J%>~3umCGWD07~g{WIn>m%tC?B`dqb_
-zmsv(n2B-KfzD`^{-)-zWzsC<kxLkH9T&;(BgPxa0^97n($W}(4#ZyS{yeK55B$RZl
-zRx%CAnPv{7rvh|c&G8lV>)*`2*ZKi!FD71seBg1ls_#81PvRN;=}NPVNL*xX>r at m1
-zaEXKo!Iy2^HPUcG3$Jzc`ahP*^Z>qg1S<DdJ1nRodxPP|d;eQ8G`Uwe0!LMNc!q^D
-z|IQX{y5Ez$Ko1kRK{sKS1{gLK0NJauN6m^s1^+JbgvPwhG6MbFM+6m5*x1IwLo-7d
-zjgu`^kInA;x>ekv9nNItlk_wICrrO59K+QoryrUFbDxEri1t`8<du3q&wi`j=#aJ3
-zfATG3XLGi}M>tb1{~7t~mVlz+&XvK+Vs=45_H_q_Eq at Z=Cu=ip<noZdP2`6>^zm$w
-zh&YB%P+q*Zonk8B%o%-O40;9i at EP`^NdS at O;OI5T{SX at p3F!y-kw8XFD1JX{Q;LUD
-zq|^kR9{t35a?K`9?HI;_tFD`%H!aqdS#X;A(Oz*y&~uSRJy+^inYBDT>(y{Ro`43q
-zZyJs6KUmaUB#PPbM^h_G0nFEA*q4L2iNM!H0~mI!)NPbp*xMOnzdkbe{_uOr%akz@
-zcdM<3lRlvZ^S?i7roISvXhv=D746WXoTr1W^_L1}LvfK1JJ!5ljUt;RzlGm=OdrOe
-zveP}2=)G3Nbx<`sd9&a#Qr2#}WWVSDWdQolq;mH{YoAet=B4bM_irD2CxcE{<uyZr
-zM*)nksX3JVw8jhLN7c7dy1A>UWwCOO-*@F_xUGi)v$HMEBUyWE4>0!6XgJVZl6`V?
-zk$lJH5zXg1ot>Sn{-NJr#^qZ-=GsTW$n4#OpWZde7ZN0o-0!=aLH3M|R&UDr68D!+
-z-?}xD)<MU1!0a=!2CN36!mEW6>t2dluYmQlQb()OhHdK at gIIdI#V-nA#%JT~S*d9k
-z)e)q1e2K at R^36hB{klH`E+wX=?4|Yv#S(nWC+psgA9hj2ravm2WjVGUO1$I~iKbI{
-zINZPevkzd42`3KTBh}whMM6~1vkMMZ+mssr`r4l`2==e#*3YX_BG&YNSpJR!A8@=0
-zJ0MA)6e_xhvCf&KiOswFf at -duVk7B0BB*OEvAX<ad!BoCF+{S}wrVaAq-T9djI82%
-z#&iwDDVZlAzQ<KV1Cuw}rSyI5M(-^nr86zd at UF1>{ZSUd(NIDnpdJ}J1#A6rgnjD|
-zp-N^CtK?*31b7v#t8fCJMQVAE3+h-;W|yF;O>s5M){$}b04Ph#U%9=K{9d~DqylbM
-zjP9Ih|CmshQQJ%h&KhUP^~`DG2->k(^e>2xie}jPaprCtMo;_Kk at oW4xJuwHSw!5e
-zF=|e!;=O}-;|K^UQC=RL>VRZyeY)7X&EMY9Y2z?+bV2{?9<_EYWL|Gpgve*&`D@@Q
-z_WpgniF?Ktyy>%hp9sH$-`Qln2?=KcpH7<XJ3JfzuwuE1d|}S-Os8243Mh%=ouX$a
-zDJ)xxI<g!yAd!Wo+KujInQ<J4VtxWSQZ$%^_}h*$AmNGZq+7L at X-c2b;k9B`Wns^3
-zwdJ4LPH2v2;3i7qaCa4`F!s4>-B1WA at H(|0Q3vfgTp-EDzX%w}qJoo%(89L+BMn9T
-z9dn#?vtpmWT81$7lzLc;nI}F~VR=6K)?j!SpW<peI1(AgV?y+1bNz^$9?zh)PUg%E
-zt!#D%7#x81m20NSD1+YQm|ZsVnRbrQgz3M?_Yc;OadR#Gu8OJ3fWx`g$e_yARjgF&
-zQSGCCr!j#kDZ-UC?qBN19)!>`1o=oFr}2Y*ko-Pfzw6sMR1m~mHZQ3pUP5sXXQU8$
-z5E$4i>%}s$oYBc at cKRm&4})C1W_mpfvGE{r7^#qi4u7|-2Z<5m)*~CF#>jt)le??;
-zEU`VaT5Q5e=Cjv!7EArjf4={)9<lnRJQ=X4;`D^3XX}lg3Mvz1dFKSM=s&0ujI{`h
-zr~2;EqiJnZr|)=tf15hrRiWrd3<&uzXC<%ktb;~K6nDRjb-yh0$t{TRYhC!|fuMNH
-zZvLFE^}C{V#vP0AV7BZ&SG7460J;PsSN;dFd>oY%ZPZY&kZb6?TVH8>mRSc$)H8>s
-zYN_VU=S@$U7&`qbt*@otp}m5#J>CSv;-wcPo?$6W={WzwH(3ko?N`^1ER~P>s;^;!
-zwe8U%pv;>3czo~oq+}_q5TJne3gGw-n-vh7b<h{SHQujD7jzkD?-KQuOv9<8u!MA3
-zTp*8dWHR-7BsDWDML82(vC+ at LR_k;{SrI3%XNn3yM^$|sGE1BBm1@%T57Me!GsGp^
-zI8fQFM3l#Wzp9;pDf#-)E0uUCBuH?&uJoWl>k*_JJI1|Qrtfa&q`03g{7zBdo&4J{
-zmJH$(L+}kd?)zTbbpwkGY5q%3RMxC3b}s%YFSYO1LQ7kl<&(c+wy;eIdQTzw4ecu)
-z at k7k$e+8DARk_ at gxv%}bQ)85ofZ(3c&u}fv7Wvdp7fM%Slaq<$_*hl7Vt*)ajws(1
-z`@iW>eQCEU<yEFI>JrwUD91_b)?Z7T824Cfxx>a4w9 at YyH*97N+Tf&&(#v6=eNrG>
-zp81vXuPeCwN_UO0gO@%SwQrYISC%7|>8QQL6;wpRwY{B~FSjse7b(3yC~PVS0UVDe
-zSbqo9XVJTwdX{^`pKO$V_8deS2}G<?YWd6%K+8oH$t;PD&+xM%MsQDNViIC-5`O0Y
-z{ENX7x}GG|9so{y`(Wh~xX-%urL$9!4<Phk{za7i&}*9WuNf*3qoYyf!uYyYcym>p
-z_MLymPb!8T`k~L!Syack1~J-$_<Vz$$Q{K(rAN^jl7Z7l(G&mrS04F*5;dE>3}I_Y
-z>V%A!#HYlk^HB!+>X!j0xT)=E86l=@yW5)lbt2ujlfN=64EkJSvCUEL)w7@*6Eq)V
-z2eS5B<X^p6(JxN21_)*YP*uo at Fqcj7Ry(=<L<9>LAjZnA(aOMV<lAU#&?Y$LJUiXM
-zFZdS0O}__bKslkB2cke-o%#YqHbz+ksPiu54oDjyDW&3HfhTJQ$RWUI at yso$EKN2`
-zOOx=ZpMRQoA#L4uQ%mkzr0|#C`^IzK(XmSBSn8GQH=p<H=KTn~kM~$)bB!x<G!*{!
-z6kCA^Ni~Pbx$;Jt_r=jqJA at LI4vt*vMh{Ml26`pwUQJ?nNaikS$tUhZ7WI+B9EDme
-z!=tuc&BYA_P$J&SQr$Ok>F?gQ<FUF>Xv_0f!i|t^{CIYxXM9#kT3)F at 3QL$QDPo|i
-z!q%iyn|sgRn|3Mtg6v`UNh-ii&(F8eI|&b3Fv%@*wOdHww`Yog)1J~|(MsQU4Q|h|
-z3Ja;+-I8E2-SMdOl7N+cIFB;5|L(IHvu)jm8O8}er22hA0-q{+vwi(H`}&jKq2&#m
-zUZ53RL2?0RsLUZZ9;FC&g+YixN6^#eJU%jobjWc?TK~>3N86E_2lM69&C6#PE6P&9
-zLkKE_M<mA#i4r9qtnv=ru^^AGgdPSbAJ+CO8Be4hb;P8^G!}Sc?n#awUQyAS_YraL
-z9Mhi*fN3c6<h~QF`;VjJeO&BUds#@cFF^WfbpD~a?9M?Ev8VXScvB=M^-45ct#77s
-z0O84!6Q;ubUD{|wYNVLHkGO&sT-ldf<C))k(w~=i)ur_2 at 8$9S>>}QwqHR(%F=+*$
-zJYe#qWQtw(eKdBAE<hpB8K4lFNA#RL6R>zKrnI^D9sYv&BAkfm8z95ee*S39UB!tJ
-zRTGLHj-3<8h}Mz`+ZJ1f3UeY*g(9P>!MN+ifNGq>vgduF$|ran;n6}kP!u*9z!DzK
-z at xNxwxC9*g=a-<K=LNX at hCj3AW!NS at W-4=qvlu<)UKDkbM<4`VAEwY2)Vm1q;J=I+
-zxoe?XjM+0={)3h#Q?>1<fRh4XaTX!J7I5diXszhL;sE8L2Vqbg<$CZ>uh{BK1M*Jp
-zkv4E)C_iudH8}M23V)wSPC at w_cL+1ud!&{vQt8F1^xj?n^`n4I0B+;I?JM&HgG<dk
-zB0gLW+#Py#;|IJ3i8^U__EY8puEg6OU_eRKNekMMZz}s}2D*$Eb|ViJC&74899~Ei
-zFY>rS5bZjMd+2KW7roXMBOoS#07zTRV-i0Je0&{s-VK_&@Tlexsw4JN29Vs`GP&z!
-zZPfwOJ*Dh$Pj%q$&+oHCWQ|~!o>?D$f=J{pSk`5~1ZB|byY1E$>;j|fkXk1bk~t}^
-zM2xFjNm4<W&n;1~n+%QHkl5@!U%>BYV4bXUuBq>m2T+U*+F~@vkg09Muh9S;C_P=*
-z#2ARbYkSE&!MFG%QxNQzzO)#fdDrqK@%XNpJ{?X^@E?k~R2264;vgDPCaMpl&bBdm
-z#Htq_gDCt^L5=ri*3ROj)Z~$q&0syp^5zHqH0&hO|ETu(Mw%`@x<Y7eyj$?@oMIIz
-zP%8eH#I?E*je;Ls=W#60d>w#9Tz^5ANlG+xNQgh&`qiCqGF(U_7Q2gk_WD02YO~bh
-zWG~ZpuB!!xU_cWO$0Q=7FDN!=0a+h#udTR;-hvE at MUk1NRE!Ej|4l6i!^7a;r|1!!
-z#d*L6 at Ml^1?WepWVtR&TBE3KIAZfJ6qV%ng>RDA~(D at 8!UW4Sv$Mr at yJBD)+k=#W&
-z5snt=>5$au$i;U$k=k^>pEVe3U(VihD3E*LaQrLbJ#ay68@&^Emn0rnfTDVnTg1ze
-zy_HS!gn at P~xzZ!B<50?Hxr3hbE*bJ24K#y~U+3X-e4pcb?N`$03dNom0n24=u at 7@*
-z$Kd5es)UPSG}d~*WKtV at rw+ZxD;>(%gQb;C-)*Q+ at wwCg-&NKBRa)tBt=}l0)DBgL
-z`-o3 at xT2GRPCV}(IWy8;E?raGzF$2y9j}ayg+68+v5+!p^{Q?VT6Y(2nT`+sk>}~C
-z*_&*5#1*h=5Jc{<!{hJ|L=Wk%eH<TFc&N(UCK__ygJH|R7KhGDL6DH5>+30`*bXw4
-zYvPF&-ZH|4 at syI$6+_qoxRxWFQnM2BTE>=$8fj)xuy^gR)|rUv>tua at u(>Gd`!#Se
-z6HY&#?Wo-Hfs5(#-VDBb$6`l(DssxHKDbj$Vym)3lkwo~f49-eJo~onOliYFGzVdD
-zN&~nTKMhP!Zz~a->Uwb=GM^m_J at BwMF%SlpAw8U5@({eRrURDl7^M at 5b`Z=m3^O|%
-z8f9G8!q7Gb;BFyV_<46oc<{mYqUQ#00)Bzy4M|rp&##o;o4^~=Q^}1(jwv;AKoxJu
-zCsoYtdv0~Y at 60d|*x-RzQVA!NOhqW;BCpr9;m^MD#y7O)k`A$rD)@S`kz7bVSo>Z4
-z-c=y^wcW;SMw5Qv4Tx!Da=bowNjn1;l-t)O<%a2swKlxbwmx+Ku5l at SF;YGQ?CUgq
-z#NtE at nDr-V6&r$7iP2%<B61RqpiANmnFFHUfMCRt|LzB_Z-lm5lT#twHfQ(FA{mEV
-zJ^ko~0R;Vrnn>r!DP%}g$a}Ja<A5X3f|cugY&=FlDI%n8Q<5hNQrCw*9TN)s%g_iV
-zZ;;qkTMfqt05Ea>I}4zg(5XINk`sT?Rp(awtcQv2hv{#W^{(l`1C8>|nZfV!F3Cn4
-zGwwS3P(kP308e_rIYb0WtUfimFsKs-E#;V+kttk3Vy2j#oYaG4Y at Y32mK*@aq%FO^
-zjtwnY=U4bK^UzQE;n`4KNjcNMM+5uuj%V+7a!gSX91fc1wMV%8jJg8#LqxdekDl&^
-zk0!dQUWB_ChqbNySmkY7L$WvOuOtpQQoZ_m=!{^DfUAii(|<PSOr0TXEioLa<WMz;
-zNS%L&2j{M(x~l(*>%gITdaRho!K$1W<iS}iN5#bO6_AG?nY?-t<&g2YS?Gb5|4qqV
-zxvNFq->WBb=typ&b0?IdqREA>o*JU|+N3B138_XNh~^pCGlSeBR---Mpy*G~hEkSJ
-zs(|N_&72{bzwYriDF1aJu8qdgce%B4(oK4P+*dEHK at PD5b`5ursi)YR-Y4I=`WF(y
-zT&L5Ec0(Y4?*@D%GwWWBTp&+o&fhHg!zIR3GwyiKfd*DzPilI9jZggmj^_-F at w`Y1
-zR44S}EJY at 1aI?+kkDLTp_w}RSa)YGD3OSoe9{E;ZH|A^2o;M6Qn?~J;TZ=Eg;X at TA
-zA;Ewk<y*kZA@$6qBw61g=u^7oDjsh~`6VNU#Pm)1K(&D+2E at XRgNa2dyzN56+d|D-
-zY8OZSy_5Ft2O(QpGhBYj;v at zv?PpcvzwP{BjT4!EWY<*V(e_L|7Cbs%JSYGvyAW$3
-zmamM+wq(H!wbP=#z{>;{)CQ61)Q8^cnXZ>^N!DX$C9d>Nb<zOOHh8tx|M03Ge^dfD
-z-~~i<J^h*bdk>rR6FsZ1(ULJnTnn={L0Az_neFYQkc!7N{QP|SMy=~Qu#`aia+Hzm
-z&(&OO@>c(UZ#G70yQN9adt0d*t50tv4xR_1%67R?JTIL5sW!W){n;5k=HvF#1g+L|
-zg)KwfU}8LO_ex at 8H_YQUUSEW)-hQ%6HiD(vj$_GK9PbR{9C%wJnyMvmtM{+ENSIE|
-z5;E~_ItOkQnJLgmCUq{l<-piG6HCucAq@?L*O;YPX^BD`v2gEmS1ni9{^IFT#xxVW
-z9hi(o7VkM*hZJt$-miHfb)J)3AHwsFK=jr=tJOk09O%*+FEW4d%Kgx9{C2*;`rqKO
-zD~L(c`=Mi3dopMoKC(eQIbp!h1ep+|knm<^I<a6?LCgMf*%N}2t?LQ?OXuL&6YKyz
-z8h&F(oAG?LmR%WT;TmAMgx#HkAa(AFx{a=M_fXI7pm+-B=U-I-<7>v_1n0Hs;1uXQ
-zu!RB9W5!RHf3Taf(zS8CjjjTE3RR(ACMWkFd+y>(*oelMzScGziVpwPIXaY*vlgwQ
-zPFWn5A*=$6JU_b$aZ57!Ik9OiMKchYmh18oar3lRdd)G&Sjs8b!`wI)kc5Q;ZS#dD
-zn&)saWy;j5)p}f#k4Ia=Fi+3WD}zgSSt$ZVGZ~PgILkE|hcnaufB<a%;QBd^KJ_YM
-zGSpZnq|{$k3>K>dvxN&uBxEM*qz#A~pmBe?TVvZ`Y&g)E1i-#LsYV4H{iyb9`?6+`
-z<~*d%Ey_^-mNYss)5(GT943PXmU at gfD)ZIb?Frkl)Lwd`%6wzy0=I5?MA9a##u>R~
-zkL0v%@rd3A<rwkT+!>7j8uLWnbSI9mKs+LC%oS}{@E5(9ZF6Du3QTgluFq|k$GrOd
-z8#x9$&*<QB)KX(fT at 7a$BU8NNlOH87Q-#3#-oIvz7E-81^FNZ<T6;L#i4G9Gf-^?6
-z;z2|^Thn(1KD<2+4%y>f8%SF5Z_gMX%g0!-yfVRAaaAV_=E-z(VrxKUgS<~Xtgrsm
-zCTH}1Nxx&+1^G>?wB#RpYaKXPY^3w1t0F#x77TKjs9E`4oA5|}?*0m|87M|%#TsF3
-zTKRpAI#>zI3`%xw@&_$Fsjnh2%(J&|zzf_Ka<|1mEFRfY_3?##d0slqXLJv>UoWQf
-zYOkywG0AOaV8?f8$Sc3U6LldvyhumXVXyyx5X*Y=38c9%^r8M*a~*Yx44|U;PN7x~
-H9QywNYWoZa
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/content/aboutDialog.css b/im/branding/messenger/content/aboutDialog.css
-new file mode 100644
-index 000000000..9a3c04eb3
---- /dev/null
-+++ b/im/branding/messenger/content/aboutDialog.css
-@@ -0,0 +1,48 @@
-+/* This Source Code Form is subject to the terms of the Mozilla Public
-+ * License, v. 2.0. If a copy of the MPL was not distributed with this
-+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-+
-+#clientBox {
-+  background-color: #F7F7F7;
-+  color: #222222;
-+}
-+
-+#leftBox {
-+  background-image: url("chrome://branding/content/about-logo.png");
-+  background-position: right top;
-+  background-repeat: no-repeat;
-+  background-size: 180px;
-+  /* min-width and min-height create room for the logo */
-+  min-width: 210px;
-+  min-height: 210px;
-+  margin-top: 20px;
-+  -moz-margin-start: 30px;
-+}
-+
-+
-+ at media (min-resolution: 2dppx) {
-+  #leftBox {
-+    background-image: url("chrome://branding/content/about-logo@2x.png");
-+  }
-+}
-+
-+#rightBox {
-+  margin-left: 30px;
-+  margin-right: 30px;
-+}
-+
-+#updateDeck > hbox > label:not([class="text-link"]) {
-+  color: #909090;
-+}
-+
-+#trademark {
-+  display: none;
-+}
-+
-+#contributeDesc {
-+  display: none;
-+}
-+
-+#communityDesc {
-+  display: none;
-+}
-diff --git a/im/branding/messenger/content/icon64.png b/im/branding/messenger/content/icon64.png
-new file mode 100644
-index 0000000000000000000000000000000000000000..37a25b24f28233b6812f9e2e03ce73400ef18bfc
-GIT binary patch
-literal 6661
-zcmV+g8v5mlP)<h;3K|Lk000e1NJLTq002M$002M;1^@s6s%dfF00004b3#c}2nYxW
-zd<bNS00009a7bBm0008?0008?0f4QnRR9108FWQhbW?9;ba!ELWdL_~cP?peYja~^
-zaAhuUa%Y?FJQ at H18G=bfK~#90<(qkQT-BBCf9Kv?bE!(Dl4Ok~*^({c2^%nA2W*Hj
-zVF>ORLT8{EVulbiBzYw1c6UNv2*HGIAV5M$@*shP5D3KJ(9i^$(FEHV&lAQVxh!jz
-zN-EWK>kjArQBr9(#v$~2>+QAny1IkzJ>Pfs*?XUJb_ppZ|3ArAAqu--X*(=ygJsJ9
-zbb~$)5klM`gm_X2 at m(QA`Ploq5F#eTie at 3!0|$UF16zS*NGboHR$xtSZLPfj{`=*s
-zRjXt;9PV>EonHckloAV;XJC6Tywe01YyoxT|7)LUSAEPPg!tB}r=I#R>2#W!ni|T>
-z%b7oae(>IV?|pRtyZe^v4WiEhmjKs>q<kg>)Q)|}C*=c#5GrsQFi+F8%7TJ|YM??<
-zl!|0BS(?dY;y^2Kc<|T?GyyM4DZ3|l->TWOXaDSb-}@dv{NWF|=9+7$uC6AV&7$i%
-z<<H&B^tYQc%~8imOS0MBleX*cNq`W-4}8Y&_g`38Sa_b->n-$py|~?O0Q&p;X=!O;
-zU|`@#ud#u at 0?z>Jq?G%G5MQaOsd at 0$TW=MqREmB3_OW*DT5h}THdIxmB>6UrUcaAf
-z+ZXZZf4}yyVHj6QDa{Gn`1c?{2r<j!@%%6p3Y{Mghn;@Ef7~;MVX$r6HcWHEb{$C$
-zg+igKJMOqc*tSi3dpqsz?QGk&4MkD7 at x~j`GHp0|IyvO3<lcMlmC<PQnshq-pqv2g
-z#~KBM5S4zv|JMx-4cq6<o42C2w$@otP=F9(+_MJ{9y}KC0M#p3t{ervqoV^M1iN<a
-z;_0WKCZ&Yw3`|1^!KIg8DqJqtorQ&kvnP7l$3lP*BH(a1ZmX%OIWTwb+$+N2usRmB
-z5MmS&nM~%GzIDP0Cop5ij8Wi+j;3ky*kg}z-+lLyPNxCz`~94G=9z(XI(@wmVw}_e
-zn+Xs?%nSqq+vd%ix4NpT%B?6$9_&OtKXk3Owsykz1p)ySW%6cSbkRi<f^TncCz(tF
-zuxZmKZn@<aqR}V-kw^r~vg+&V>Wap`@7TlOD&f+8&a%?d(%;wB)fG(EXdwg>`I*Ul
-zkJsy^zP_Hewl+FCI<Rd!f6wRhVVdR<!4FASR~NV6emhlFRix8toKENVL?SWndq+pW
-zY7qpgkxWHl8a7ow-a}<oP0bgos;WNJipG*4gqU;)bai!6R#rwN5}~ZDjNQ9;lg(y<
-zoOK)x_>t1m(jwh%_k(3+Wsf&EH;)UalM}F72w*mFE-(*ppx^?M|NBkKA3jvGq^hcF
-z6sWN>7WB}$l#;Hlt_eS at C`!K9olYl}m6bF#H35)JCiB3L20UPSz219 at ii)0SZf at Qp
-zrL at OBFrI)M at DqS@fH??!KoSTb=zeq;;fJHuODe0641Of&L?VIT at 6Vric6QR=-#_YE
-zpU+1i5Fne)(%;{Y+wDdO!N?FAkH^`$b0<>DqX92{KHpv8aQN|PG`juh at _^N%0=No@
-z01XH_fB|3zf~I#`DLD5DaY1$CeBtqUjtE}Ybq*amL{Co-hG8&c#tceIN=PP??A^N;
-zUDttJkC&B|QBhGrDwU$Arzh_qv)L at sXq29wp8R_?O~dJQl1inH1RelYRkvD}b*hvy
-zJJ~bC1gsWQf$M-G1T)Fang)RRK=e=?`K_1vhbQ*pnm&CxrKP1nu2)j26roUvAyNQ(
-zdV1KiXV0jQc|0C6narr6F=x&kJRVQp^Kad{6|dKeX__PwiAkO1(Tb|751OWV)nxaz
-zLGS@!72pMC0Bt}V2m|hcEUA~8xu`vX3!t#D5CGe at X=!O87K;%Ig(xa2qNJn*hr=<d
-z*M?*$Hjk9UhYyoZr<pZt7Rh81UDxy0 at o|V{SyyVBw%Ihz2PV2d<O99{_<#@sjT`|W
-z2_T5Q*~0vciNCTSXY#tP)6vmEXJ=>Lo5x}?g25mThl5lqMQ3N{Q8lo)w-<mdTege}
-zc^{|Pw*6zL)A at Kdn~jaVr?Fa;k~4FF0$|uX3GAeS*4)o*fKOGyTZbh(cI=q&L!F(S
-zq*5sc1_nN|>HfXI14t<Yz at 5O#vG){U?uc_YFw#ylhvPI#nadaz0hi7OZIZ}8)bkUW
-z`v0^ThH;74>unf&T_HE-ha^MJ4*<|IfJ|Eyhup&tl>6cH4LLGCDe?Jylcv at mL7awR
-z+&%W91`G#UL5iH?17PD}PV_rrS|M!j1ar_z7e}Bn0KeG*J)b~lH#RornkNK%_wN0$
-z_&=$bruiAK*SjE<O1(XFO(AFYIg#`Zp8JvpuC5f3L-Cx+&nX3ML<iIr!oMwoiyL!R
-z at o`BY5TK%>0-w*9zm`s?8Jc9(*Vm7__Yp<0ZTs4h7c^jG%(2NWMMd`YU`kL78}|0V
-z at ue_l3he9vbI`xJH8`^-r|<W{_6~@~;ZPjX$28T4>gsCzem_-JRkXIY($mvJCX>m7
-zb~>FD7Z)G16<DUZbdKL&?oK8J(5?Z^K+T9}T9KUGo+LkYjO*}0U#{2Zl)|nqFvd9T
-zy26|SNT55FBV$Mp#UW*Ucmw0{cs~8DsHmX4ynIwdky4IxvJP@)>juI;4~1?QE&;-p
-z*rthPn%I^NQX&*lW2RFrcFy`6h6q?P`~?ilrmMum>_h!IFaU=Kz?M)Sf|JUjxgXk+
-z3_mbJ1W at A5>4{~-*ZVS%FmgnsO-LJ%8go<}F>1U)GzBz8q6vwLjVdIXlKa~VdU$<v
-z0d7EMbi4sSm30vs=ggq~xLP8$WmHs#@j5}nLL-YXGDtnevroUp1HX7taXK|U)|;r)
-z$gRANk^?cM*MSlV!od-9mbL_BEocnG^iXc>zaNACqfFci-8nsyC`yXr;)#=}k(RJY
-z&thbBKJ(=Z`1ZZuClK^u>nUV5h165ndK#&xkh+1LHIRnRBM-gE+O?aw>iTopv-JaB
-zd|`XN!W!90ZrtakB|)e?36TH<T%#M&lZI^_FpvemBj+0$!#RKOafof(`T75m#OYO8
-za?xjKKitVh4a<1`w|_z!Ix?&0jw968)7<srCwcDqt*pA~0?uA?98+sbTpo{e=1 at xW
-z#>kf^vLf()A0)Fds~9|v(H~D5ITAkT14}}w7Z#Mm>=Fojazo&6k$5~lZozbHW;rFK
-zkxlEY`Qv?j;ae-YXZ2lNzx+B{4m1w}&mavQJ(=X at fB6kNcSX7WTgzE|ay=fGgR-(h
-zoK9`_5CI#3JnaUW-?m}*;CyCI2{_f!jg&yk0BmlD?m?dvi^G9KaB>CI1i^KTR$<#V
-zu~>|BIz6d1Oe<B{zkM&^pqI<Pb}|3)<em770$jH2Iv&3735;}#f!-K5U4K8Zz63Yi
-zbOEOvUxU+;15#QV#Io#2u8C`8hSg#-un54Esuv7&GZzBql;m_|GBhN*346LBoq=_m
-zRFY|nk^;e^dPyVzu?+O4p*I7Wj}RKAlne|E5DJARoLAJ93jTXTC+YrvT$)W|eFguz
-z=4-sVWG;{X>?vM&=5-XHw7ihZulzI(H6<t`(pObg0OZI%dSi$H!yZnK`ZCbem&*o^
-zFNIy*InW~|k%s3st5i13;J}W3{Qey`VSk#2GAMHA6mp)vCk4Ga#4{5HkWu1xyKy*1
-zkG~- at yly48x)g1psyd7`GI$+=bI(43xyP09heuu@(U;(hU-}f&DvKDKMO&7Q5W*Oq
-z)~t~Sfjv?pOo>ZT6o#}lsnDGf_??0irU(M=;d{EF at RzMB(~h6bH}1U|Rnz$XBX{xB
-z*Ic~SqR^dDkmT}spF<D{3g(pxw!N>h at jWM<{R(2lw??X}s-u?Jg%J6BZdcBf)A9Zh
-zjxRUv%R?SkUA>g6ulh7~RpY?}7>0!q7-Q#ke-Z*qfaTB}sEV4`_xm-v(+Vz4aC|8g
-zdlh;I6xMAN6jepI=lS2 at bUBeyviO`u{L}xslBYMj*wd}DsY7FbpGr?g!H@#e7VL~l
-zc7KrN^?hERddtPu4^#%yInYCDnkI%}Af+5fgb)JF=^zy!$O9iqf&-h<(BvtzX<A4y
-zN4u#tvX#~1Er-fiq~`RFbwCID6;h^6O~9tB%jVA;;I!pSx%r_x at OhnJ<d(baOoGd<
-z|3}{6zMI$H*~qeal3qP$`T$Ms7K)}(KdXU-OBZtbd8hN|hyKW)*S<udUu9aUL0yHw
-z>&ndoLZQ%vAT+0g^uWMi_{-4O)kAA at E3F6HXlskn*51cJB11B%lT7NQ(mI)pK_;Cg
-zlg`?zA`;^_M^}r$Z{Kx)pgG-PJu`8Jv-5z#h68ZZJ>O@=$`we{K$-?SHt*!xW!JF2
-z<$0uKpr=w?cj343nr)ogIBaZBZM2zt#@WnXyny?@aVt-3`6FdzA at pQ|_0PS|x<{X5
-z%ZA-dt#C4Ls!hYx at TlFQp*G*WHcnYtm}D|dcSkRVZlF3eq(dW(Ku2JUoJukLci+GO
-zg#`t_2&Ym%7$2zC$oR|iU5C$|sfNWQlm2j#ip#BW=J}^#XOejW$fgD at APJU%!_IR1
-z{omxO3%^U~P?pAsiUfN5;G8cnr}4x_p1A8l?)$fUxb+wRibF`wIC}w0&YVlEvx{dQ
-zdx^&$d6Adi%}`ojLAcn5Q<%6F3%6?HoZ_OzP-stCWD9~=g(~(Dw$+AYpue92pKpIp
-zAkZ=4(|>wb?oHWFR7IW8IaQZBs18eh@~t&F0y0TtCV|YR5mF*E3G7S)JCh{nRk{71
-zukzMDNqeuPBPJ0-;gmBM5Dt1d_mcB@<(XI5y?H0n%;q)dcX8<zOL^*<@AAbJC)2j0
-ziCr6-*w*Ucon$$0#w$^3XFypQS+5toUR0M0hr at A19h_F1s;b7K(WpHk0U1ktur?aR
-z>2gg-fTAdzHcRD|b+54PjZJy5QcoiRJChtm%+#tNt5;vhe{D8-eXn5Y=Rbp{NTiYF
-z{EN?`Xi5>kzWevX1Q^3axHQSdpFf2sp7<s!zpwz_+k?J!GiEG?s;bzw{h^>os+1B{
-zRg*v$OtL%d at p%5SC7NKjQ8g(6ey_^HnGV+6bQjq~9H}Rf*_;!UdJeojXcbr{ixxF-
-z-e(uk-Id{ro36-%ED8BI>!LH+ at X9;%v~|J=E0AUutX$IJbf_#}eiFBQ|MU2SNo>Og
-zQk|Xj_V#`x0tPoqqemnl5D4tjb-i^<vYbxCHz^78r at JweasKeDr*l at 2&E>?me(w=}
-z`_Nx_<F#EJJlKsnm_DXbSr(mh8j)!gBLEt#_`*`WJ`Ybn_7c*_f;ptQ1%%et7>_*i
-z8kb%6Q*OTbal8d?yrBSH=`@<AeI!jJ5_mkG-3%`MPnfMoqtR}U$FshFAn}hIw3(dm
-z+>T3~c-i`_6Wu)W%m3uli)T>iSGnSAXA|p=v;X~e-gt8#ZHIeFr?X6%5~Q;;&M#kj
-zXq1UdBTGeTfF<Xh%%7ipjms`u%%Klj*}3gKcJ7R_YiE?cz9jQbtmE7jCo^|$4Zrx=
-z3&<$}+-^6PWlh+wi6os)V_BBz^?G*zop6L2p~Aw#uM`v%JhWuV5<I<oI468~(ii{b
-z?Ieo7lpo)58Kz~E$r_|G1{vKXr5kj0$65RMTeP(F@$hTEp{U3=oU~+f$M^O(v+7H?
-zp{lvaGi}-ws%uIpj}&v<tSZWi0~8nfXm5>i?W+GncIIq23Xkt{x$?_tJ9q9R7K<G!
-zE-wBy at OU&DoqT&d5D2{9(a{l0r_-UdXDYiB3FZVQuI5^HlAlLkYUlUAe}hXdIUR at Q
-zqQE=6kZ at dW32q5bKDCh*b1!7s=g#2r>n at _AB9ym;sTCov{Q7cS4ycI~6Yx3ldtCUv
-zPTbDnW<L7ZdSpo{4wq}9rsT!v^HESxfTn3kDT&A9#9}erZucHw$58diktVDMRaJdv
-z at 7}#v%$hZem%FD>;Ix_Q9ltB9DT2=}F5uzE*E3^A1q&9`jeF+g1$AuS)<n~LE%d#&
-zg{v=E&-?|ATzbuCnO;8yVH;d<_8c5oC_<p?1~0z2V=({ErM}6e&MPnPLanKV!7a6X
-zqAvspflyUk9uEZ$2a0Ltq7u;D+>BuunQ%C~9ym1At|OMoRaRD>*4Nkf><K5F5Og>k
-zXhO20tc6O~#G3(4Z941T9N^~<e3kO@;q*0?(z*MtXW75EnUxom<M(KomSpFF0XFVS
-zQBWA<(yuIK{+!{OgN}}VzVxM^05JE|xp=&8;{8c7X&uY5(K8v0tbt{in1+FAm{_KT
-zWtvEPJSL$C6jik}RY|Cd=#x^$)9LINk4Qiy5-EzsVrxR7&@~MW4Je9&Q?a?Q^dKdU
-ziA!AG+Ld5`yTZ>O_$n@!gN+;C<IewhhK6bni;s8XbvtmmU87RlXlsJkcO*y|8kbyp
-z2A?{uk;5&$Tz>ganYZL*dRjZUd)=>y)Kv}+86$th8gp)Du?(GTIzu*<!bqpdW-?^c
-z84O*gqoa>CYt|BvrvVmzXrW{z5;?uMxA)1~+S<~Zn%wHSM=@DZ(nO&)@myi;YkdT#
-zRN!=KY<cGZpF6#X+6w2W(ict5g(W$-DqtEWhuQ{MzdKELT(b16c|82^t32 at bS{}Xa
-z=WKgr18W}rcTPHe{)E7XLh7h<(?D8AKA&i5>ES!y`5m+8)$-1!1F2YVV(HP8$?eiK
-z?cx3V_oM4Nnx<hWZl3F_Cnenz<_F794{>1MK?XWnSao43wG~c){C(3j$r at Q~Y3HZ5
-zs-`lf*u{m5gRJ<JkGEcZ2Y at +q8@TERH?a7kWqjjv*YVV^o*3WjmN5u^Sg}Tf-?#5D
-zH{SSb7A={{KYV^6nyT1v6m^2pXfzfG1pc6D+N+y3ZOWCHYZ at 8h;ragQB&8cgD5KQn
-zP`T!FWn6Gt5pJh8?!F=vkdR4dNT<?dG8r=I3<7~76s8opIQ{qn094zep}vYQfBm1h
-z_{K}P>pORI=Rf}hOV^Qk;Mq~YN0NbMvT4%+zVn^mvHaqNEIVgD$4xEC<2%|y$?e6(
-z#dqqu{=w$WoAV163A{Yhe;lo55TS at s>ToFIu1%zf-1K(rb!*U(S%wal$+YSzTzJ`M
-zS^2%IdG at jY;-9bl0oi0K2XwHvhb?26jOU-<%8!2ZCoa8uDNB~jWJaVIB^NowQ4<i2
-zMlE1tadGkOU0q$hyLRo$r<RuD=A~pKJM~J$1U-GMYT3E)W*fuKu5wBt=dW1I*KWCn
-z-COr_)5;%_8W<RKe#QtgvKW~Rcir_Y4?g%ZSKoLp3s0HO)QZrksQFPWfM_(@rK;-d
-z;c)n#ci(+Cvv1$Nyd@~A$~Ha1tEm~7LYr{;>Z7V<4LWCYv`H5Sy_~h|ByRZOm9!o1
-z;+re)V4$}@Zw1mcXm9D_h8rHF`Cu2<eS0|z=1--nG&ly4_-F(SlJKt6>HN=dIDGGp
-z9XpbL{p()=@<bfAi+L_NmwxFxD)T>*ns#m-P*vo(@g49uIPKKqxZ&nY(X&~;e$Cy)
-zx?)JvV8i;|Tzl;=X_#5f<zG9S1#@bcQZ&*2y#%n1>GuMWNMxaDn#+26dae%!gC%F3
-zbrxQ4zOV#MSS)ZgF-_|{=3Sx<J7YY*Db7m=*5$_c1o2-_r`fTmiQnG;EZyxf7M?nt
-z7hl}L7q2*jIdf~MuL|Rsq at HKRihob__oq%erfTtMH2RjNY0sCImfoIBCJ(Gzw~o%v
-z&b(hhb at 8^@$P3vMIV?+#(E`91 at QnvQ!pl2^<oM}jTz&nyOq*WDj-64i`}T4cojRT4
-zYD*>s50J?i8W8`RelZe>M2-Va at 9*!wB#}rgibNvX!i5XRt>T811aq`zDwN)%e)r37
-zcd@(6%kN&e2WgE-ZiWaMB*!+gG#&1tH=bg8bumHzhipLuOPAgvrIdlcX-_vAjqZ&^
-zBJp4_81wu6?{sx_Er0y+$EP(mHi}bDIVE4{5GTl+*71bxIJ31TrigLndgCNxDHH^K
-zdB>Lb^wx;5H%Np)GOe<RNLeA8`r$^M$rud!faKr2sU3|*4 at V-AKdY+RR#a5fY#7FZ
-z=H}+J_V3?cR##U?U0ofuwY4~%PWlM3-VRYL`lwS5Q!cvE#Ka34X-gvz^o`2)CL)6o
-z1>i>m9w3?2(KI#l*Q_Z&mR<d5G at 1d{M<S7T9S+9_;c$3IHk&=Mt*z~(rlzJU(==Vx
-z)z#G3*Hc+piSF~!>zRX!q?BGNMJJ`A7Z14!mTlV%WNfT#jOU+x8K*<Rp$VLtf>RSX
-zHE^ilawxc54xCO6mrKLtavZs#gOW<=sH&QRzr(M_B9RC{6}jrusX(o1n)T^)dS*JE
-zE;minV_B9^6a~NEkKgad=kt-xX0bB^1Vw^USC-zG0Lz6#D3%JAux(3Pwvd*kTBbE2
-zQbiHA+wIJHy)H8laLYizD+&v}YB1<?27_L;pukN*frtM76puXe+QC;7ncBbW?*=20
-zNC21y%mm7T;z2DkO*3p+R?xC6uWj2dA%s*_HLI#>LesPXAw)m9vfUWaO|Fz at 8*p&S
-zp+gCB^^FCC8u+lIrYVJ*riO(OK_FmR_U<=z<GfGgm!pwLL<}~#94G^(06}t9sg6Mf
-zumA%{0ewIR5FI?GhL*8DPWi-sIy+VdNm0oy%W34?vN@=BG#dRx8uoty-->+5A3!F=
-P00000NkvXXu0mjfAMoz!
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/default16.png b/im/branding/messenger/default16.png
-new file mode 100644
-index 0000000000000000000000000000000000000000..09dcf2a708548e619042d9fdbbc75ed7ad338052
-GIT binary patch
-literal 932
-zcmV;V16%xwP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
-zd<bNS00009a7bBm0002J0002J0UcV#`Tzg`8FWQhbW?9;ba!ELWdL_~cP?peYja~^
-zaAhuUa%Y?FJQ at H110hL7K~y-6jg!w$Ty+%1Ki|iDGehSM^NSfQogzO31zRntqD~c?
-zxG*u0YN8PrlE!KvF)U16;L^muz_?I1E^L~*XhM|6#0K3!Q|b>$DnTS*VJKl*XC5=d
-z49u4|@47Hfy3oX%oaE*#&P~oeM~Mjkca&0QZ*T9^et!G2TiHV88r0Ok3ADAfy%h`w
-zM_kwKTVG#~d!DxmEDj9~b=PXO{^8Td`S9b*ukI8IR}hgpK6uvd>Fevekxr*2olZ-4
-zceel%jYb8K(a})}27?lbL?oF^&WH#~CTRpl%7>hI`TLFwd;XSityaTv9CEoFKA#WU
-zw%Od=L at 9;V8l}{JI2>+u9A_7qWK1TxH2oUuiHI$Jzh7dpm;eHZ&*!V}_rtQRPelX+
-z=-Me0Dj(7@{^%ZEp(?vhzV3(C8r!x>rBe9){yOiu?pTLX51GK$n#1$ODhwWnt|%0$
-zuw8<Z{`*|AC4 at g<@#ET2Vl63-9gR at UWm#F;xNZUqI~Da_*e|R(P_Bikc?JWm4)@C7
-z0S)Rdv0#jBBFXDxuW;k)cXal*;d*Y+0OtQZFdM33q0I!XFTR879Avv3;+K3o>-4ix
-zv=J0Xi~|<u<|&s;%q{%E%39V^BEra%EtiJd58l`)HgWdN3sjsOi?j0tx}TuQba|||
-zh07POv394(t=$8(2q;CdSe!KgZsvklHoYW0$tvG|@g<q%Rq{n)VBldQjf$UsxJhq&
-z6orQ!i_x4&5Rb<(3}Z@(2udmI^r at 5i^L^TGHcDjnAD~*P(BwPhu)#(fL6%nYq#o%+
-z?^p1&rs(9^THU%`k8&s!I&<ckr)P&!yF?G}5)YdgN}-fu`qu`|jla#$Gqa3O470uR
-zJ6~O#p-`wS8~^;ZR4UCaE&ulUH+N#>!aZ0%KbFtJv`mgP26+6`gAAQ}ijUs^gsW56
-znV5J9(`?Y@{Uyp|GGmEEVmg~W_VtO5HU?WY?TvfXyecd63xoqM=SQETxjBSs8hD;~
-z|J6oB<OQwuyM|$$Y{K1$8^%V$l-mK*2q>juO3|dXd+#sm*JcX;?-SDi0000<MNUMn
-GLSTYp0<*CI
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/disk.icns b/im/branding/messenger/disk.icns
-new file mode 100644
-index 0000000000000000000000000000000000000000..327a662f196a293449b0851869ed7699a4ce9ded
-GIT binary patch
-literal 43113
-zcmeHw2UrtL7w#q at By^OfprWWK#YT~4rz0q$(xgal78HA9lTZ~@q)M?MDj*%{NJo$=
-zf*^_%dqG87Xi4rYh=LN-U-7y3x!*ttJ7?xSQ_h^7op)!~&SH-f1V!4}S?rR9AO<`Q
-z3FJO<Umy68$Aw|hh`jep=mFn7y*(qLZ!|%l7}NuS&;#`#-()flk9>=bl_Ocm14Go-
-zm;u6oE|U72To)ihC~-o}Pz;UwZiw=3Xc(?{G{0^y)Wg9M6B9$FQYqAK8jUcV|C_uA
-zV&X7OrcptLR`AnJ>q8RsjOOp_>EV!CZ|a#$ZGA_j#I&|jhs2NsqZR1uf$;LC3Z_=3
-zR-RTSRzwNBu_TgzR89tR)Ad%Co=6f?6BBW{C5ZfMelbvS6H`-hNlPnZ6H8M|6Qaj(
-z2}kn-Wj!WVmLQvnt~ir%4241&K=PAE3fR{R{vR+=FwrxX#G4rFgNhCfx6oKQdC1g6
-z-o(U2(!^L-&)CFdOap`F0by`Z-c%m^n&?X6 at p{Hc+?Ngj)dQh-kYFNjDkX1>lGKxv
-zWI`I?O9PI`A+f<hV|jUbeLP-Ll1UPge`&zs#zYQv2Zx9rL}N)~06<0}Mk)xJ=S%46
-z6%*@4jzDLBlY{1=6Lg0gV7M<POfiBlHfnvt- at pV%e!=&!ybq}SYLg?DIr8^Q2aPn(
-zg!sb^q)WGWBMsQsJ6r(7^v48n2<nQIAINow2!kMiKVN^rA-Q)1zqgk#G&D4b{EYpL
-z=^v5zf%*Wb;a{<_q328c_R|d`_VY)7)fG3*haePw2!aGbM{^8+F!wq7IGQ**WcoNd
-z)((LWm7_yhf}=we#&xJ~$904o<2n}1!F6av<2tlA;95mJaIKu{aIK8txK;>4KA4F<
-zc_6-!MtlAmd=UBAg5$u at 1)mO%i9dZHe%wb898d5W0&(L$Yr!$S50W4H66`FTKs!Kc
-zt+-Z9;q#KNg2H=T1x`i21(-ZS9t!!nOre1RDL5oJv=;fHj{R|_B0p=X5Cm{!k at lnk
-zuPXNCr*~u^1FP)S?I-KvdWHv9Uk^?%h5{TK7)l^Dtq&*FOnnF3*Wl=}JmQbQcoQ4;
-zG-SxsL=JcW6C(M`v9YP7o}@7)Mr_!VfK(>HiAah|N(>(Z572LHA}=n<AwF!#h?$dh
-z`z6TYV#6c<tJ#BpfFT1X`6VEJd`!zA4TK!`62683#PG?w- at +G9g;e89u-gTS0pTkN
-z5Fht}OMU@?K|vv5m%=Vx4Zn8n#?8p6xNAzT&<we><|j{@p0>8OJ$wG*<*T=E- at X6P
-z{-M{K!v*5nUen*(OYZ9*80_oqqf%3H20rz{G*rO?62yhxS>My~xwESy*-4R!Rocmc
-zczuvSLsf|Z8N=>oa#vSRv$?#242qLw{d at +Ek3iNW4`eK-Ui5Vjv}-P1$<4(nz>Y&f
-zc2ppHtpQ~0UT+5m2GgWa%%J~JXbc3Q<ALn+b`r$R8~m|<ur(&wL|TBAk!!9vmVKV;
-zV^El0TOgbl-8DE+eJLR+#P8ghb5}1r=Dfe24Aam9M=(T)UnI46aNt%(m?xYS?Hzb6
-z=2BDii#!UjN_QNP$`$rg$TzMA)!jaK#^d^#s|2sTJC6V<C77KEaVl30Qu;{Oed=yE
-z`erq~KeHNM2pt8;)JQHOgxb~sQ#jy&n1I~t*FT0v$0$h4%Y}myrwbAx9_uz5jhd|)
-z5fvMM^?J5z$jvKZzQ>XFD-j_;ycnm~;B47%Y#9 at koSvO>CAqk_Ga>dR5Z6i*AT+b<
-z2LcWASkvYv;STOb|DBW at _n*}QVXF!da`<%;Y3y~n20rQe`8UYjRV|&bs(|p_79ixk
-z)<dGPeGJ^b$>OBrmAL4b<g|N0)@1=?^OMQ0G?t#Gdu7dJ%FtlnCo-r?-+nX<p+)nC
-z{AlPw0v3i)a at GDcG{u({hOjDSkDH%7g`0>^p(gicOw0QaP8ed{T==s6?Yocd9iKZo
-zyFI%w-9xwdVTi$~kxHZZ((rc|f}V5gqz=Lqc*qreIH*+MerdHUAP9TrRrS*rVw+1V
-z)aKH{QvaZSHSj}(mIfakSpT#kPTxRpdt6iLa-e%}+Y^h`nrAm+HKo0t7YYLfDv#eh
-zEk9euSY2K9{L at 8H5)6Lb9w*lWZu=o8cputvr(iDh_ssoHVfH7`aub{TLI3gQ-udFL
-z869(fecNB2j=A?|M(h-zWA5ZQ4;^*!nQV+0E<sTgBd=TyD9ot24`dwJxOJPliqZyE
-z1HFxrWrr?|Gxu6U{f$bi4Yb#*Z8LVtJCW!&&fGh8XloY-ZrNaaMBQkUgVuV}@#b!#
-zyYaS1)b8+%EYsybn)@kzBSUW|mzuptk1vyw``+9)m>L~Cq;KJ(cj7GJh{LvCP~>su
-zzTMi`(r%aak+8_RyQfaH0r5C<H?b$|#vOhU>~ZjN9AdTK%pFswtG5T<k2~_H{8DUA
-zQXUYFH+K!q&6=?LsS`xEOd$Kg+=m7S$nSgp-#7Q&`&|#X0&^$)eRD6E#N2nCA8+m*
-zb at BAf{mCH}QF`VM>rTf`VD4Dp-Fxh1T_7CSoW&^YG|5p@#{$nja7qXWa5MN6&RpDb
-za at 5S35U-xVg+fi^C7 at W@c((-T9&#LK<!@)=1+E{P&!)G9Z_W~JnPuC at Tlp#up3 at cw
-zbX?956(_Lr<MViznQA#)*|bGx$&XepKaXEcZSL}IYi$l%@6c5H!OGPZ3(gZ-C}coz
-zy?kc-*4FQ>Tvv*)2)8xmpxI{o1Eu4v960sun<d1=bRv8l4mcmq`N7InS1yvZu{Y5-
-z*pc>swUw^|P92`esqY!%)L#@V1WsM~$(yJ5fK$JZIQ1al)ERJVckg#10V8+YM{q>%
-zF`bhO**PJT8FV2#1j(kRCZ}a(<>VDrCkld-k^aZ7u7*n<w=ch at d|VAq3A at Py{?4*<
-zx#zIt()x8kCU~$}l?7sCfea}_RuIJKOSu#22RnNN#66)MfgsjM>W!$xz#D-CrxKbM
-z3gXG8oxPTqlpiQ1T}!))h2~b#5(&|_BNLm8i)go5pd~Fd%J~y%sn5zDH`4BML95%r
-zdA>66Qo)1T$Fv3kNUMX^H$duV>!Y>JhxFS&edzey)!7MmV+Y<XgB*K3Xp9}}phHjX
-z?Ok>;TkU_M2&v}=_yq)z{1`)$7eNfXJTNzj3(doYo}{h;_XbDm+S}kVzOGMQ7ce1p
-zHTY83Hml7_tJiNl=~6yY*MS{-JanD(t#q@#)ODZHIqv`)@#Qt6bv3lGHoKS;5dF2T
-zW{!46VUd~N>gw;EoRf9$H|vTUt*hJbRP;jWa7Bf7_hcL#*QW*242)yzS;7lL#!NG;
-zO$$cqN#>WgSg5jK^O}?|_0*rc)80X4Og&eM%wO#6V-x(fo~kPr1 at 3VS`&Lgs=jep!
-zykD;8!DggSztl4);A=g(-H`4?*&RSkc#8otoA-e*+NNe^um!>FjOlqRg2h>D&s~H)
-zSVzY_Hl{ie5YE8ppm)fnurR_Um&>H9a5#Jo6%j$aPP_?6Vxpp=qY1Z&v6#5H_;@%0
-zm6!-8xg-;B<5E(RBmA6AHLgO8k_M!R+u8YW0jjVNE`p0uckjX_a4B>TE`!T46&010
-za22Y$8om$LpdLIR)Dr4Y4<8chNe%ELmqyZK#>VoTcpq!!%Mea-<FTvB*+ms_6*Qb2
-zdH{pe5J(I+pdLLUHWD7gPl#ZGh-z*owGdlTZEd7y#OLq}+{@OQyclmo$x9GU-o!UP
-zr>Lq9u7MvAYl(I6Lt;G<=pr@}zvU*jkXi|CF3)hU+Mm^Ag&$D91mV{oxSm~9*6{ib
-z at h$w0 at SfNXe;|A$enNG05I++-QC(fcZbA<VT;G$4eW?EaGXuE6!M^s|+a8-PK};Jx
-zqSFd1n%;l-K%6KKkxW4H5C#Z?sG%VO#f5sB#z^gLDhxA{41;inXCqRJDxbE0%}Ye|
-z5xR*Z`iAoozvVpx^7b_s#q5?0h47Mk9 at o>0t6C>6?0CgQ3W at 3sGWWOMjdj`-3R--d
-z=gq8=`_EudXt;y$`Fp+a*dh~X=#GjscaVSJd1>4sl~9ODa{Jln?9!U&AHP)^2IU at Z
-zr}3%@6vp19>#qi=RG5Yxd{dEC)Pf)lzA8&PqJ&h#@Ip+^z1mkF3Ev7bzQMmX9^)G|
-zB|CYW2QUrO-_g;Jv?S$iMT)a3sF2)F|M=Xpy4Qr!ej6zc40`QL4-iLsfVE3b#VjX|
-zAV&l)6*LN#(q5JBt_kY2+9o(Lzr5k?rymMJA`5oqoZ6|ebOsv=zhJ{o=i-4O3WeIW
-z*eO6EDE{X4$IsrKqhYBZYckJn35A%~?g~pTtbFwT(})EjB^mBen9TD0ZrF|m!Ykwz
-zmQ6#sK+~ACgDb1$tzypUDqOyK_k)3T=UIUBxi;H(8z|5Qrz<H%Rgc>{Mmy+By8xV5
-zL=Ev}atiYDaxyqihy%}UaLxOWsrb6<aWUtWkMw|QQM>AMf(<~+s2mMXE3SU}kvOiC
-zVKV0U5?MKdJVs7Vf%^=^A?E9S&_r!H+p>^Lf!- at a2E9P*_B7^SF_jE~aB76>8723d
-zKN7wT2)GwZ?mWjYwb}(hD9l0;z~wZG1aY$L@;P9vx at -m(Vs!NLx7*x|0Fj>*T(^`A
-zhL|NaU2kTU*0g^5JW?8 at MtHCQKrYu3S+k0uK$J(xts+8b{47=?gq!8(WTdi`kAVPT
-zS6Uk=77cwF0Fid<f`JWgITL-StoB(4DAY(B<9f;c{nsU>SGg(><RKX%#DHEbCCmmx
-zj3UQ&C at tZ`kU$LQ;WjFQGtgQR>!=b8EO7g|*xd5Em!oxqdzgFs2Zx3R&d--uP#~-#
-zDq!U06+}r8>l`_mC1BlPsi~qkFWLpdVBG5ak?IXTFHJbC6by!yk#Br{#lu(daDmvt
-zQc&N(5HJ<;=~=536kJxJ6y#t9)JjkxHYPNSsH_|h1Tm}==Rv^m7oH3vV|4IU`R$Xc
-z!4QkQSzuB at W&NAZPQ(Raz(U~wJcOrE`h5ie*lOY`oQ&8U-es#-fzuKmJ7Wc_gtVL#
-zH at MDb=fSu_Xz^+aFiOhX%2XFE(DJKoLX(TC9=#g|o7U4iFi1g4Hk81~1Hi=A!K=B~
-z&IQXMtTVaL5Q<AePC<Zc(M%T5uMox^LaiM_z}{D9oY at STe$AfCsm1pnw<Ep^3u+0#
-zz!f-UDAx#@yLy#0nn^-o)jAee2#?|xTCj!>g+`r&Ao-ColI61%wA6+J;prtcO&^Kf
-za1Zam;Lvbk>Ms~Ui{%$FfC-h*T5+ at ogq}7X<qJVJ$f)S3%L&p4IhBuJ&n$iL^b-tB
-z2h%@@XvR^<A%TZkm at otg!y>wr=_-UqLAl5v=&a8TGXe!xC*I61t8Mw*4KgwGf)!ej
-z3rnf=3%sBj3!wzMkY4O=%#Sdaya?g7+ at o{K>)JX&T2ya8JOqKnj4vw#0)oyhjfEg{
-zBysPPqDULbAYeT at -m!U=51)4tdeFVSpodsMqYhlDP4o>23{Ve(7?>9?TEyrLLHQ%b
-zTYPKJsvs~B^nBtAs_I{M_w>NMDDoiEe3YSzfXwO$|A2sy1G91H^AHmQ0~%snEF&Yr
-z=mnNchR+ at SttIgXl!G7^N#lT|qUwfM-C&U#CPM%LEEHYy4=pXd3J at -a9bP||o7oFu
-z!AVKZXJVW!BQ3K8bq2zq?)CM7`5|!SWyvR0K}qB-f^Qe!Z+r`22xJIUfR93b?;GHM
-z<9=DBA3zEY^*&;~b=?wvoIAvfUoIoFWZ at zyNl6hR#KwSQ<>H#o$-y~|Ys)ED1Qi%>
-z3P~dfI8(bzsU<a!-y@(X#Bk9RY7-#<8&zGM9_$MTEDyXG9O8f4`Jl~KwRN(~776mP
-zGt8HkTfI(ESzS|Im``Z-jQMLVU9aAXOG?WwwwIOa at t|Rc-c+Wa)(isHv-fI7X>HR7
-zA{o;MMi at -N4A!MzfCCuAt7<Fa{rpJ*gg_3z3qI%1dV8Jrbo0M_^=den-!MgQl#q{Z
-zdi(xUC)|qz6~3f&VM7G~ro6wOd0qzrJ`|BvR at d~AK!*EJ2r$Fb!s?rT06FB|!@9fS
-z{^tVF{-L)>F}$}D9i(;E#?yud`uoVeJ)f?w at _4-`oazq1KGtLh>Vh^<J9+a?`NQVV
-zWH51HM$Q;R#n<YJ!u;U?CjXTC59_kSLjwK10#JSt#2CI?w_*dO?gXwkt?KP3_x84j
-z$$Pa71)l5yfWY)~Lkxkfsk=nyR at S$6f>RpY&jbMbQv%Z(?t~BmSp35CYZ~jK6R%$M
-z^FI^7a4kAICI-I6ow)i6^}(SHq`Kb0H)q!Pw{`br*t|f_zn%5@;bxM75N at +)Y<^Wk
-zTQ{MPy}utUjZ!FGQ303kHe>`60@(b5Vhg-CCO*iHy%Ol_=MjMM54{>gxW%2Uy?2P#
-zk!rEYzwGG7D=)e`d#i0K5!mj=g6r0j0bp2cJr`ei|Iv#c(2mIb2aJmLt3iI(D<7r@
-z_!9y+g7&Ulp`6|Hpfor6df<hCK-U0N;7uYZu&r|Uz+nHgD+Y at CQ7^kYJG&bkvk>H-
-zC&kgbRs{gJukV*sT+{fn7qkIkU_Kbi&q6K+21M1><z5U33JTq|{On45&FsgI8fvTV
-z-MQ==792zjL|uv{#;_$Gl6g1KPbPOh2#SBz1$Sb)nh!@K;N+(zar>15z_2t4N-3#*
-z{05vyhy(B-hEjhq7``|+wxO>0GJsxstwE~7Y4i1rs)mO8NBdS8oD2>PzIZX{G9ivF
-zHa3YM(K66S?&<DoZzpx4U!4d+u=`p|la8r?f-6{srIpq_e%l9%O$5;QFNYCAX2mx&
-zlwIB-9y-t@)%ZrwG%PeSv;4_=DK*7a7N<ku5Y&wugm_$%mvq$turd<xx9E>2&mp*A
-z0N;kyK~t}BxRO!!u<3mt0?RN&sknKC7&bTlVTQr#R0^$8>M^Za-SKi*Xc$Rquj;!T
-z+f|x-eS$+{2?^ZE0jq9ze0bM*=Zc$?t>I?nRgz2O&m-7_FTs3o6Tnv77m-z7|MX)&
-z3}&H>;DkXfjJ`^|BzM(oz0p$|h4N6kkusR9cJj*Q2yM+arBgK8>rg`#T{tW{Ha_9@
-z6)i(6l_kQ97K;ea7n(PB?u=PM?FjtPo2m@&EdjunAGw)R+0gt6LB|1mrcy6n4<}w-
-ze$7KUi3X^&`!bD#{XGGjJj1Wa1`m3!zDFCPQLBhL8_W(9JkFigT`4LwZ;rqWK0d+>
-z%uH7PRL|j|obA6I6kYXHbZ*t7mQK(pc%<M|nj0yS7%qD4hOKe)(7-^2+~a|s{`Ql)
-zfvys*l-hN6Jp*L&0PV5wPFbln8x+-)774(!UFI+da?DQ|LVU!B2Vg=43cb-aw%~qa
-zYZn2yToi=@Q_&YCuahD~ZUid^^z at TU6dL=wyZc+MEj5j(lukFf1R5YQyL*S8MmVlp
-zt){6cI?r8*VZk)fG=R!T{Zy9+=2-p^PTMQKsOIsr9vGRY5-E&SY9;%==<9?Vi?820
-zzP^s!o4>YYu&1-LzfON~4p?d|U$bx6);c?TXz!yp$|x!<b{EDjTF9wTGz|Q?p&-Ii
-z(hp*l-0qW9T>JP18JzaOB?y7a at LEjGEsl6|QDo$1+rF->l~E0!sFXpPg?{JY;J^oh
-zQqf>{S2uZZ;I5~UiiE^cQ4cYUFzd!TPf*;h#-b>PRes>~vm+p-q^{{z-!LeVitR9y
-zunLGFMlHPMFB{*Rr=_jB(dfv<%kmijv!7hJ)(!OC`vO0MjaIO$)LL=RrI^KRmQ4s|
-z&y%|`j!J$I^QxU8Y4_ at z-t;5oBvBdr1Lx^DMaGbB3E8W at Yt2c%=6!s($p({8h|leN
-zeM~FjtkL at Qri2@X&E`_F?h=eEq+}MddA~t0$xllYj;Q!Scm?ar8RZR6-wq(xKsXvT
-zPI$AfdjctT-gUK;LmeF-UOs*hwNAT$HUw^s=*?NR*8I3%TwX)_=NieCt};w3SFTdm
-z*5K!l?L$EOTFa78sRPh8yRKzdK5A|U?1Kxqu3;?SutwiFG=UU{@mIV#K<woFe8*m9
-zOXfgdZ||$5)ROua9dH+_|A?DBlbq64-R-(c_*I$6<xBtb@>I8tpyo<WH*%^PTRwm>
-z-~zZRT<0!Powb%X5{U5(u_rXk$%M`sT_1L<+bL{L=<MqJ__^y-acpAJ?Pz&fd3llo
-z%X)1+T|FHU%&~`5%J9kkWo7yqZ9j-f<!Dsi{l~2x6i|5*4L1<AQch7}e+)5kc2bnN
-z<+C0D*1S_YvEYt}re@?@z_h$Quvh|M!mHs`umT&nzL1q)y+&4Hi^CxTW!N*ksm}7<
-z2AV(}jwz^l+}a6%U1_*CTNkcVUVAE at m?W8US=+Uv`$Md%NnCbrUSUy~sn(U2Pw$S&
-zD8~=b`a3_oZhP{u`d(2^dQ$9-tD%8D4sueTk#qaInma*yeh^O6J-(>6=~*|4>PBPg
-zygF~Ws+y8V(rrTWtn{;**B>2JbWgpVl$o2CS6FbxXye6drvq;CUT>*j4uEj)z?1aj
-z`uh7HnrxAM0h)r+UYi?cBIyg^bi9-9)-^rvAyPePm}U(&Wmpq^AvG0FVNFdxs<mOq
-z&CJx4l+1KEU#K8IGt5X!*{#KIm185g4(JDGcyLPY>Fx&2Rl36 at V&ek@`QyX<aC6BE
-z;9RGBA*Hnb=}R(!>Pch%bdzh|Chg6-!RhI68a5+wFCi_Hl(sNCH$N{sJu^E<(Y62e
-zWo5mReq`eC6}Hf1NAd&XJ4ok!ZYaEAxB3D&8SMy4D{E+e)la2*(U=<@u at c+1ZZQo@
-z&4kl2898?{+|r>8Li(J{6uV=Cw0F0*C?<3va}lJVU0t2|CI(5*U+un*Kz25QX{Yi9
-zFfB6+&8TQ>c{2d6d|7%5G#J<G>uxo at kdp0_F()(G{y;yK@*&M+<)x3na))6$atsYq
-zntR@!@J4XDn at Zvjs(>o5vb~xO?DajkDqwvXwPc!>k%6v}M^bjyxy(6PDSLL4DT9=c
-z1rAad-h$I%cURB5gw4j8PrJL{dmln at dYkVholpWe8+KpM0rrXDuu&g+3Cz(k-eF+q
-z9GjheHfv6H>OPwu%D})-N5$cl?$3I=yZYLKmF(^`fqwW9W`+QfTfux&9RRIA5S3rk
-z)cTQfp2pT!vX6VN_D)k{gCjSxbG+}&$VuIA(Tg~Z!Ol98+{vb%{svgdxwyFp?nHlz
-z*^B`7J*!Of)B-?CCt?bK`F*1L(AYb29QbBwnVFmI*mpTQFZWCiUvBDNv!OxYeaL-X
-zPtLD(dT`Hvqi^}kZbB!zBYgt`H1M)2!)Gf1QYXb1*FAmq831um-{tHR;8U}-vE1q4
-zpOlw>I+r&ub=OYX0OE9d$=$6Xs#dys*Q(pQNS&z6RS3 at D>-*UOx&TMhGpVG$`FR)B
-zm&Wln?}!lBIukoPD+ at RxvmoCik10RR-i!ud$h~k6zWc=uUCV at r9{~)yJ8iuO4M!b(
-z`yeNDholdL*EyGRuc75d57m#x`L at ty8M}y<<t}?`hx2iFiVEEFxeL;4t!W5Q517Gp
-zb-&Eae$vtH(uwK4t<?=mH1xhM|Ej4txGIs<^GhplY<)$h`qQSjmtEAJ$sxVne(!FZ
-z!+~+x#YKgr0<OX|vt0md1PV;zUO(^ba_z+QB^kU1P?V4L1vhNu&qH`|ql+1pj{#I5
-zjk~Kh;iNn#&w4%c-FqDl`p0J$+$}DG3t5ZOcN|1&2n at 0dOxjRg-R_;3{v?Y=1nJYG
-z;;7y00g}AgrR=IFZEyO6XhM{h+;BTFb}lhBL(AQJ51zl7nq630T2h+5?P%{Ouv88%
-znTTX?*#)k>y5TO&z-`+~q{%-&E{Snk1F+WHh3DRHdiHi8m?qU-mlkX#Gn0i=MAg8^
-z$i$8mb}KG1B|+8X+O?=SK&$7Ml$BRj)jWLkq~+PmH|?J~DOtM<5VWqQ(u8A*0Bz0Q
-z8~G2OK6^hHN|R`>PQB!AymAIBj%m8U0&$6 at vdVhaOC?uGN=wVgE6B^qty-t3vE9V(
-z0PGbMk(gb1(>fc$>S-=ZhSdR<;-Tomy5{E}D3 at r<KiB0%2e{g5uUoNDfQN&dUvR<l
-z4SIV|oVgg0lAD!yGtAfXl#{LTRt;6<4eM5~k~hdhkjSkSsqP4p%89t*`j+P(DOYH`
-zl=cU?i4hmiyAe(vJAM*&KYQ_dLSb9KHx1YGuBE;rFZVf;weML~#<@)(t2!~Uq at nf2
-zXKDnEqx)^s{i3YQw6yd)We?lh2d{yI{V(rl`Rjm$nx}7<HMYL&q(+0g8HT`L9ChGT
-zO-`^r|2bfeK56BT+g^239}in;ZSG|g!Ltw(ziwbgWz)0QJtOh&9~NA*S`Oj`cZ6nF
-zKYjj&Onm~n{X;|1O?z1oz0~|lZcX#^w|&FWpBnGp+6SWXGIkO9wJk5+^*4dUpC6aT
-zA6WxpWgR06>snsCA0ScdK{-2{?j<>|KMOIhIT%w^_q63XSRQEX!SxM%dU7w>RTX4d
-ze>}FJI3qSPnh<j~_H5kE_|pma_ at u17yG6;K8bGc at ycHD|d?ld(E+Q2Z?h;E#rKo%N
-zNM$bNaD{87YZbBD<GxP~t~5I-@<!~r&7iy*XTn1gito359=oaxjjpzyro>ZmgT0TU
-zula9h at rGCp{I4byRo8=Sd~mV){kp0PH3L-QQ)SX+D_$>%mD%KcM0#mW;~OOHm$mAz
-zOQ$4i7E<B*J2&>s^MaV!_0B|Pm)AXcj|>FlVscEvY>=?Ku`u$$axaK!#`g2E;F9xc
-zJ4iRY`i)#;46kI9s7OLEb&EYF0ul-v2P72SZ)o{6s+u^GkVtVIE at to3(j?*vF9<JU
-z8<KMOL1SCT7eL|w2>~QgPE(TrAi1S1<+L;?qNwAQ^m}zpFFJdBNn{czB5A;7kT8@*
-z!BG(-PQS1kfUP(h0S5i^_uX)>C)u;lr9XRsv9I%4RaT%1kjfHo6*s<Y?*`c#DL8WH
-zhZl9ZVcI~j-aGxlv$r2R`vL}h`p@>ACwn5!v+Lvgmyb&#3>eQq_)V8eo;-W;{MqxM
-z7opFCo_Vz4pFMlt_M|-4lJzu%XEcqgYJA*KS4*e~eh^w4_`szG|Dd+Mv7s_~FW+g1
-zk;(3MRb9<}V)Y~NVZ498rZV*i|7nN;YnN1h- at E!Q_%KwJr#kVTfzYOLC8R3f>V*5g
-z)ubv+Nwf(wSftq=Sybs(#ZVOG=R$ztVrLj;Ah`HN6}eV1R2E#>$^eq6gcp>%R$+>Q
-zZ1k!%F?u#ZMJ`pC%DhkwF9@?CEDy*~k+!v(DBDO7Uy&Q6>;++^{O*)hR+6ev7xaNd
-z{{pcJTUl9t$4>#|S>l~}&$SW-YXONC>{5v-%R09b#Lsm}FLkYC^fuDlVQOw!W`(ub
-zX{>MTjU>qM6axunoJcMK32yAQ*|qQB;j$yxLr#0_9B+aIrD-k;y&wio$N1t3mr86=
-z at X=!@;X<MdiIGS+b^K^Z5vh`)qBP}%07!&3j4CWAR=}0m;#(JvpFDNX8F%XB at e47<
-zpu82B;y7DoZwMplpIvsQBEQnJ%B=!ZmVH6~ELiU|iz<N2{VEbFT`D}P075yYFw$z;
-zIlyw--pna=E5BQTs;VGWxs@~A%fGREwhzR}x#e_pW^Tc`qI1PJi#!U61=zgoSZ_T(
-zUx*PkL&@rhi>LeP0M9cXUhZygL{~Qwk%%QZJE#a?0>Qc>1M?NObY>I|?FCUL`1y}@
-z`;T=S^`?K!x>Y*cjjZ(i53C!<7uF5j(^;lJZKh53 at YUP@z`C)0Vclq-LR92^TK|l7
-zQ`n=Uk=OZGShq_$n;QR|b&CqJ(z5?!*6oU~|NqadTYFR8d8t2V-Cma8j*7f)vEYwc
-zw~r4JuU)!)`HHdNpR#ToJs<BUUb+;1CG at 5#|LQ+x-CkuzUJQ!~xfExQ=KV9)ZAMSe
-zi^Q0q(1dXRct`QyXWeG@^mHc0T=9=h2nu&s7DN3O?Z#dZb1N`BF5WjpQ%#nU`PXPS
-zw)WWADBsA~_=~$#RF#D$rQJAst7Btt21Ldux|*wk^&j5JXg9Xr-h!Ce8-X|CZ)sa@
-zQ-M_>p<kojxXGEfVx#;c5>Kk?n{QH4Rn?GX$Dk&s-2}$cZs1xuH6}LhVo>~cRSi>9
-zO<0vtT|-uogBklB at 8$)eOM8*qvL>Y6U@}Kn{;k-!Yv=tyAvT+vZU&WLQrA$FTfRt;
-zhZWGT%=i^DGE0RQuauG&^@h+ACe{engk&48r!qP=HqPIPpo-PDFxOWHSiEX#>guZN
-zSII12BqYesH=Tn82Q64BBL~Z4SFM)iLo>n<+st+5r`$a}PJ8)CW1y~y$u{P`zPcy?
-ze$7%(8PrwN%+hSDs*0;BtD35cva*t*;)V_D*KQ&hz=k{qCUa0szO~QV+FDzl)Zect
-zb>Ot-$fZZMF*PQD8;!h-%#fNhs+(9^8f&VYQ$?$28Ig>6jdn^vi`jw)JKJBjG(M;-
-z*vqsdUEY%})yCAG9vc^PNXyblgP at 92*=}xSVW6dPRu!eZooLJluHiRB$*$9+)1E(j
-zQdgblz-W?KYHrv?pJywGi;uQZ)3r8GC#W*3Xzj4Dw$$3DsjlLs%CK$64r623h}#V7
-zK`q-h-7w{0{T%}q+uM0XE^^Jt36~zt)*2TdVW_&%*h*iGpvtDAreh?_vB}avM^jZr
-z#X}XNqNQU at Fyc0!xv{6`S(u!l-DTC8PAPdg1tC%e2rM0%4IW at 6-%beKqOP*Z%u-KP
-zg`moz2KHUyx7%8n8gAdDs;sK!s)|z6CmM0 at 6z6->{`y(TaWT%tCvNBF<m82~i9w+0
-z@@zG+zMAT)s at hhTJJf+aX)cBiqLo<mZLO^>%}ot8l(jU}iE60LCPZVlowAt5*Uz5R
-zS4Qt9rR2gnnA~XPKm>eZo{e#E at I$J*=0;dUV5_y2iIxVyK2r<b(VV7jU~X+~Wh25k
-zTY94=tbtP3CYZ9Bn3%1H?!9>0aKEf5GlP_aPSkKgz$YZy2!jlLbtkkp5j1CQx3)Id
-zoDGrs8lj4&MS`0&bqvkyn4y`|7#FP7f;CZkdW4-!=IT&V>!aGryZMA%LLNF(;{XCp
-zk86A9s;f=Zn!DX*D<A8%!J#VXZf7d5xb~(^o8_U+d~G+^GIK9c-l%0lFypq^g1t~%
-zRuFS$m(Dur#dElsQ7D#S>`Az`^E<W>H_zL$7AN(9*4up-Rq*zu&opUm?XCQCT6uTS
-z`tBbU;}MYEx)V0XTI%zP%kU8(W)v2SV`5>$b9lW*N<InIMl#YNZds<YmMygZ^N07@
-zm^)x$eizT$ty>ugefyXbJ6^tRi_#V1lGvzcV5qx<o1JwUHy^(Mksl+#E|B&Urfrix
-zY3t(c3zwI*zj~2`&3OEvwr~^w#x+m_xn$a!mbS<B^^GxROL&Cj)zmapMLd3mWy1su
-zn`|R&7u}|-h2P)O+7yYq{h++GJYH%cmqdTp3tQ~jSM?7nOH1xWIm*viu;y2JHZ0)T
-zIJWAObQc+}WJ`Wj7shhCx;Q_l_{st(y6e-s+Z;-bbyfF@@^bRa(+=^nE?xZ_ESu7H
-zL!$m70|Rck+KLOPqc^h4?%jQ`Y{{FB_Sf}BoMH84cMA$j?q1lwcsgqK@?T}yB)9AA
-zAQ~>*p}{~X^P4q$I`1MSD+kQAPaobqZ;s&5e{#Pn?d(orUa4)mjH{RY0?UT&4;0$E
-z)xgC_NQ^rz!N=p6`KHz4?2^wuynWHqRI-KtkkMi`R&kw^0kJFi<bRoD)7H^3AsNrp
-zo2FiR=T2sF^z{?0^P at k#X>Dq#4Pa(jw$aYjKQc2X3|jtMB%9$zeN&PNMuXGoE-8n@
-zb0ve&#g at j}>N{u8hejr6!?~DZC2j?mUuD at C5tdC+-I%nK!9;duU?CxgH#b9Wx+tT7
-zM at 3n2PEKx?&(V{o;6qqJSPT|tTe at 6UW4o^Imc^K3b-zHft<&B~G!ru4F at HsTeok&q
-zwD=6`{ks*p_>N}W$;nGu2W}F_<5`%QnD8);oskjCfWb1cF>@|f-fA|44BWv<h&IJ-
-z=0pog>utPSvhy;JPM>GC+tJa<X`2x5u3K5D$~eA|0ZQkamio$qjKs(*LFe4zBm3;k
-zjb*UVM|wmXZiHx4F(6q=*sAdCk66pP!P?5g-f`bPr+wQ6d8|TK8SZ7;-9qjH_Y1s!
-z-q!r&(ZiamihCu+S49OGo`TuPq(mFa*qUI)YHb4+zUS<)x3;pfw}tl$IqkRCnZv_w
-z-$r23DEZX>=4IPcu&7p3dGBsvey-o5B}Zo7Lx3md*_cLnHtj8Dwgeljo%zyLHg-fC
-zVcXq~`}gg(vvb&lw;{js<`a#3_3BwO0$Wvfx3D1RoT!M$HIYPQ`ZO`m#x%mS>1?;K
-zh3&AmcDr}k*%IwwTa-QcGsoUq*s!<nMX>O6pC`bU0cv?^Q9-V^=wkQViE at Dm?4(@V
-zc71a at 2Os-64%UmdeD3+&7O at h2q~<Yb%JS0Uf;*>$MNTK=r>GrAa3<o~SiW#=`UYn9
-zyUshz*<~Z9{-N_j`_ot@$gZTe8lV)Xoe)@ZHa<5m&0r at 2GZEFs_=ReNcc9Ge&+nSE
-z+ji;tH=o|Udf9k;3uZ at F<-Ow4IBQP13vqclxfymU2+X8Jn~AZx{q8;9yJzgNU8eA=
-z{q>91mWS!aIIZ~7(g<)84~fr%bI at 5wmLfnC5p8T=iME{<_Ivhv?cv*NyF~WGn-^`(
-zj~_kAwqsj=HE`uj>#HewgdB9X3qOK05zof{jc2p4LVz53?8Icc0nC$z+6R@{2lyoB
-z2_K2b$R*{V+*lEm$yqiV8~Z)`_V4%D$FtvFOr{61dSIUArCBG0rCg)301P^h#6g#3
-z<M_(5IoR3naoq3ZzMtF4UUXFlGI|~$U0#@a&L{3pu1gN4z*zvW;B-hf_OB${p5424
-z?cL|@#C5=4WWxsprn&-HPHtXm@||4Q98A%v#ccp)LV|7D7=mrz-o2naPJ{zoPEH3L
-zgg3r>+)#TT^m_rA3FhXx=U|FYN!>?)CgRt)#`0@>oDLi~bm;IQ_%Q2{y$d!sR#ldl
-z0k=>@C<Ge=^7G+5;Fa&f^23za&j~hDb1VDZ4i5GXRx_6#J9?7f>T%{QxI64(aM;y|
-zn}B$`ot~9*&wXtg(s#c=uq~BYv2 at 9DNhUliJGe)YZw4O^H`ny(Gv|v*uhZ1GbUf*C
-z(Mc`=!TJS)jfa2UVku?Ay~o^rf+G{6!_K=LaWK_UkrSUkPjI%t%o)>{$0JC;Nw9Uk
-zY$(r7h-*T!{ztI=N3adw8~7i=_P-Krw&Mu4{RqKk^7{mv&d&(8^>hd}NniQ|o4D8i
-zO0XTLPq2}Gg<v~AOt2YDPO#ZbK(P79(IeO_hY2>D8*~UZZO<PGHm~i&1RI~C<zW|3
-z7Z2Fe-vjbI<L>3==1O#dNUlU80ZTk(KTNY>0L{kg!WP5|m^Q}$n704+xBajgZ~V;=
-z|1oV}@5>n7-?nO(qWWKA+AeZQJ^pj1?Uwn>KWEx*o_7iSQ>N|m|HJ#+o)^ZQlKyk1
-ztuFkqiIJY{A2V&;uM+ldQ`b<}Svl{|nYP!ld)3snwUmsP^RM}1rmX=sUZ-lQsA??=
-z@%=H=_F#|Y8fAygG5`$q+xy!9)An(nm6oiHgMubl^}+rg)8=DkA+K#`C!xUzK`54A
-zW7?RW+gh7Q8{62+^CeEUxs9ne+S<lY&dAnbdGaLN+L(KL&so_RD(Kr<;x7Nvel|QA
-zwzM&k*=D~I>|&i{4;$}zGOhcFm5trHRW|G)<9Dt7j6K7B@;0}&+qML3OlDzPAtSqV
-zk%-L7mEtInPjWJ*>~q9UYa82 at JYf*)!j;m}QW7hcFIzMn4IWR##=CNhwY{yCrG>=;
-zG(9#9*VmV1Vq;^w^%4ZJ6KC?xn86432jiSm3vx13lWv7yyl`5LS&5l0>4nX50J*^q
-zbQB{GiI<m$mjjy5;!;<ZmmYs3)Yp9@<LcwW9&}kQZ0iYY8|$T)5#78n4>vayvY$gd
-zAT25Ca)7%A!`ee`8}#UtTG+F;wibdY(4B1D+`LGBUg%I`lrp=j*VQn$H8|y?Fv(yA
-zJqn8n*(p|HZEM1XJ`K$B0)%E{;UxeJ+`8)Wj8jYaHtm;~rgao{CfEp1&R1c(ooscP
-z(VhUs7i=J&Mg$;iT;K-$#2_O<R)MVm!<n#q34LaYIDm^b*JQ+iXL-RW at Ei^>T|_}v
-zXa&d>g+ZfHXc7vA=Ogj5OhYASB}In^9NDOUl;Dhk_pO+mkZN&S%g8{$pb=aQGa5RQ
-z23=bZ0Z1YWY{^6sF(@<>VFt{{%ne;jiMbZ+<8kT)$r*iEYEmkyCsu+PN5Bd&pwSqx
-zwR3-cCKQt<2q+r{fXo2#utQh|0v5%|Nu0^V2c1p05$1b_<m>{YPe at P7L)EKrFcZNt
-zGAJ*b_oMnaDB`X!I|Bj7hJ}>4bG at XQ@mNM2BQJ at 6I&>gB=<HEbH5t(bv$)xDXcWu-
-z;nimP8@|lAnMrsNMrhgX#;WpgRA|QS{frEFJQKsrg6W!dWs#-}rehhnXV0EBOF)2e
-zzSuOtL1C~sJo7JcP>%epB$lO2D7OdqigE+d{_#=aTd_D67HDssDc+|bH8tkcx>+nU
-zMV2oWT|AqYgYB0nC}bZQ&0{vF3+p1Z at QvJz6fXwvh_DcEc}8YtD81$;yF^k#<kd at I
-z#}ozm7O&OP-1w^uREWTAHWK?{HfTped^C)84Zh&*eP{s=BU)R2XB&fKVt9z(Sx=9B
-z8p1rk%0Cgn_A!P^PFW5P5~naT{&d9U19-v(PZI3nzz6wM+|Bi2k-B~<;G8GHnc#73
-zGdtUF at lWeS*h$lbr=!F|{cKU&98bBsxq1sODlEy%j8bDg6y|f<h2-jDF3Zn~{tfy`
-zm3KOcYXK+P*xPzK7b}OrQYAIWvm`(3cI+vZwP6>$j+w5T!676ok6-gE>=WZakkD3X
-zE^ZQ!5HrV#LuN)g8>B^M<3+QJvQy$C16EDfSu23Y&z9M0bwKFX>8C~7o96S7_~!BA
-zmb;xgb at IsmJzMd!y$UiCqQgV?;P7)LR1GZmop828{T}^fBtMIfGy^l8Maz}s%xkm&
-zGwW#V^{_y9b2B@~Bd465VbW5r-=v>Zmd|pTiD8>=MI<=$!Y73B9O&uR0Y0Y*r{I%j
-zTefY}-HiE;eM0{d`=q#hHc5bCCT`wA0_-fde>U?%(Zw_H?Azc|&hRmCPXHjFnDICq
-zAfB)c!1<uiIA$E{LdBnxPf9AwW)o*g&Yr=z@)Uex3k!>&u!yLb*c?_?Ri~53mg2eH
-z8X7ALGlpFk@%VlR3#09u)fLw)#Ly?7 at FV1t`m#C1*%E*m*W4q*z$-X=)&dbxQ85vI
-zCKg58MVn1=#@W?n#d+Cj$??(GuZ9Nso;~g6vTGI(hCcg*L$-NoYHnOg6l9${my?4L
-zKYQL>LBRz=1hIJ{^Z4;Bj7H#Qk~KGq^RiMCV<N9zy6AuYj2p?>f`5)S=Oo+{{tNe{
-zwUjsyD<sIyHBX2%k3m>OOjH;anmrRTtSdUiHUDg8T4HQu#N}XrA1`;3v*|2>9lHf4
-zVV=J1 at Y<%eeEvLG2%hgQ1kEQ1&6z(Br(IKX=aeA(f!KHe7ZTv(<>3OG%n~p>dRX}9
-zl#`y0tgw*J{5cDR at M`51CF!nWXp^fqu7m_$@b++ZHkv75e28##`A;b)L%nq(^Up7s
-zvv5B1y1S(XxrwJ&LfZaeK^M+?x*gv-eU9lt7(S*zmvUkm-Q8uhLv`u-g>!@#u*&5Z
-z-N{IeKC=d+<mrFzwC5ou7Gd*)1ZVg-xCdr<C4G{;T_$Fmr4|XFUBtJLO)@7hBPAjB
-znwJVz_N15RUP%^dTg2+oC$)cpakA1=5MAW8m`_BQZAE at oN<z%dh|trTOiTA#FW^+#
-zbp$3jqfhD6Wt_(B?6TgeEFrS^v<R>0BKD=lBlZ;H at 3w_w9`8);-6vp at Gs=)I=fpm`
-zv&+`jUU$th5l>MbF#uCEVn6{Gyb0U+=Ns%h2~f}keE{>*ja?4AY&Xd-6BTt6;}&1c
-zDUlN!6>%j50C~6^-)Vl}6zt-RA#UfT&pA!|#yRbAw9r&oAtvS`&b35 at du0ZK6bSm=
-z1@!n4XV}#lL)tc%F73oMhIZP2z<$eW>1AT##3h_!d<wU3hKB|DojdJH0KOA;cgDDE
-z6Q#>K%^%A;?LEBTNMp6^ils}JEn6~k^^K4q{|jf&c({;=;PJIEgR_h7ieF=#jLogh
-zbv8&X6BAiDeZG;Qk+JDcGc$8bD{C7&2SC{!ICS**NoThmGQY?;EnFclxqy$I2{(>$
-zn#Ly}IA2UcUUB1ABO5J=UuK*H=8MXx{Kq)`x25a9EnWZDZt1cd$2jff0gRJj?D#ER
-zJCH41+BYZL(zO|3oD{E4xTPyZ73{KF6Y}Ght_@&I*9xBr87E&kkVo|N4~)}UDG)yw
-zroW}jT@)nXJ3^mvA|Q+t$F9k at bR8XLoOCB=oGcN>X}RyXEnVkj0OQ1LG{Kgxot$7x
-z7mxW5jMH^H0kEZuL(47d`z>8Dr*(LIAuNh_t*I02;p*ptBDtI)c at f<RL~t5)J%x2X
-zYNg0OvZ;&d3hM>tYfN;>rd_hT9l)cy at Zh<M5a*e)JHsLOPVOD#7YX@!nurVuTf4v;
-zEPf0*Tq9!0b at b`!<G<U#ydeP<JU)K(s0Tdn6bXz8qcP*Z2RDz%*^0);j~-DiM&!H?
-zM`OPG2G1!)!u*%t#g87I9g$0Pj7EI-9RZ#m27=Pa`y9R#g2RmA)`RqheiRMIlyeT}
-z-$h4Edpc`a4xZaLad;;(EDxGkN~3klBXVpEJ^8?J53=OblT&vh`FZN-$!UiW`Ml?J
-z<z9$<`6s&at7stK at Z(eVM>C`$4X8`6`DnD^2Bh13w2=m++k7<Idtia+&{1tae)q0}
-zAg0tG<40qL^uVhn?v5V)_)WEeAhxU@<40pCCIFvq_t0nq+MxSj<oz!bhiBk at Eey+p
-zt7|3<4+?FkgJnjJWh$BzhK+0H;z0YNnK-9S9M~CAkkhaqK!J`>f7bT283|8cRtST9
-zC%=`cUke<MHA8DquGnvK+6f3^DHwBn0fM;4j>?;8Xzq(K@@zb`Z0xA3=7iRd9c69&
-z&^GYo>965~Fl7Jr0Q}P{1rf#`52->SV~=S&(U->^TSJF>!MlRKg#J(J5dRh(?a`pC
-z&VFFH9oCJEXi(d+0mmo0bjgw>OF>vRE+8 at Ag>mxHgRyA<5I|ZYE&!gp_)CF7I;7_L
-z>v7 at Dn>QoJBi|#3qmhUR{6F$F{Qq#;QSnH|*Dvd%RhWK7Ki;8bY)_19)jv9*zC8`h
-z_h$iZ at cxgqOqRL#B;cTa5(LU8L-<44bD5uLhai=)!{iUu{g8dY at u&Lt4E&Jm??q69
-zkrTwE!G-?W;m^xKjs2McphM_;=Rem^D`1<n@?dUs>n~`b4^cfjg`-yt)=AE8^kIKl
-z@<foH;xF;sRlkh&za)IM^e6fSpZqVdzntge+MnoO^6Hnd{+EQkTYsW|?Z^KG_LuYY
-z+x|rVw&8b`{W9L~CL96}1D-V4_Wv&AZ>6XD{lozhrqca^=Y>a4?f}t#Q|kU`v~1Q%
-zo1ZayiuG4b?f_Y{f2%uxKk?(q9pDtZKk#tV$sOSAhTpH!Z{_$fd<jd}2E^!Hy8o7v
-zNfP&fE3ip|{D(>M{tZ!|`6SvQNE^JtZc4+ at sY&&lkG&|Hih at wUW7H=Jr>55Z0S6cf
-zp3P1_oST|UpD`_&KG|g;!_6sne>7UfWY=KK>0?SdHUBourr-L|^vbDGItKNn_$2yg
-zKN^#AYW|(n0ZzI5qtPaHfO1pq{=l=G%qD67DR+P1eU{FX=r@~c_eY~m>Hw$Q{Q(Df
-za}o!5ddl4&jg~awlG|{nFhoqb`=imy=sQ4s($tLkai|Yx&^5s6W#dv#&B5~#l3}7k
-z%%sl@{JpZglbT5NaGVHz=Hc(@?;a*eCM<*0yT7M~E>fTIgu0PPP4Le6DGx)(=;}9~
-zdiMt$Ah_Y0PB=Ezvp=M9sS$J?;F*8m{w8sN|HS=G;sF1N`=in5I>3M8{=hrk={dle
-zV;QWe8;9 at dIlzD7{s4=Nkb4saiMLZ%=`qM;{fU%=IQ7mksiyAV!2@*k8_*}N|7K|@
-z?sW7Y82p=R=weZ?&~bq7|HS>#Xz>%TK{8zV2eUt<Rql at 5rty6*FvinuvcD^M!27-G
-z;bYE8Zany_1!xnVP(NSoU)4e%?Cr!3P`HhLmcJ_L(wMORQvb&N(P-r1x7+?uhK*f+
-zwU+e3h9-7^|H%D;8KB1xbw?upk^2KPz^fBFK(~M7{%Eu~<Tjn}13L5{xj!1MkmGyh
-z;20N2-(vo<q-G)q$Wi#0wa|xaT{uDgd28rr_{)+v5)<fO*z%XP(1+_(nLxk98~Pdk
-zvV^RU`mq42pZ~HJ`f!6zKk7&6|C`w#QYwnak1R0iz*OFNGrldTmwt4BXpev9{%Ev>
-zA4w2~OaILM(P%}}e=q>%#PMx3rAM{=-|I(l6;G+g@!+i at Kj`QGSF=B)ByU%KKLF4o
-zt>cS0rAJ+wKj>fiuV#Np#rh1tAAo4psl4y+`^Fq}#Ev%r6vpV^xj!%i^8|Myj}0j7
-zzJKTbfc_As at ATvT1@-Z*8xq;a8z7o_YVSMzrg`MQLcWo$4x at d5W>5G&$&?<y792kS
-z7<lMzT9}e at bV!dI04S{BRNr_qz8Zb1;|2f<yZqm*eT|l4$O=E!08u!Nf3fsGsvQi#
-zlT2gvqw!|{X6@^13H+GH4gfUssed^8K?;$;%J9ttp%_>K{^9Hg(VstUi~*t;*#Fhq
-z7or;pb^N$7^~X*hyP0Gp#nk?7oj+y(pm2Qu?&5ExUhT`q3;;Bq_upOoj_7Y&IA#E#
-z at m#m3wz+>mub<2EZ2+S2+~NP&{>%7TzMX-9evf~wKb?=|n*%^Ib36ZI{}VrBj03_j
-zb6fq(=@;<-en9`|<OA%N<=OF%&p&Q6$JL)l{a-D<j*Nt%y<_yFFwDGb>2Iq1VeI^c
-zhyk;iY~Sn;=$9J1TkkI at _z6U}_ILV4{_Xs)dF5FB49q+W!3)U$U7&`G%wYXC1H~|L
-z3$6QC><?1QW*uSPvHk}?O>p^+>VH=M=X<1uxS7A%9~#FwOKh!G{#4)mJW|2F`v;Yl
-z3r@$6IsahU_=IKDO<XdY+rg`cr!stOyL;YhlY$682Y7Pbr~?GgisqWTbj>Cs at YZY(
-zFYmKI3*HljpJf7aZ?7}(A at Iom4J(9rSsA}hz)>g$Jjcw1lIyh$%xrh<adZUlOqqfJ
-zaQE)Ev)HjkNoKLYG^TIe524Ulmgxe*6021=>lzrDOkFTC)YVa6CoL+-&4$B#ZGNDi
-z0msHYTX>nw8bwugjR`kb|Bc9v8mda`<W?*e<Yi}K_}2YkPd6IN#LhEozQ{7km9p|v
-z7i3pTEf-rjhnJIijP)T_h-P49X6NFYHE*HtVv(r}i-i{o&6&x~&WvL~eQSQ8ABDnT
-z at ht4%;fOQ&`30sb at bk~)<C)IEipP#?{o!E<Y+(4cW9;l4oKqDz*xA`wnDLB=_Hor8
-jZUGc{q9%CAB at Tz5ssON&r{#gCihi$sxC#Eh{PTYRP<hO*
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/dsstore b/im/branding/messenger/dsstore
-new file mode 100755
-index 0000000000000000000000000000000000000000..f5079c58c35136c16e717389f0efb550e14db991
-GIT binary patch
-literal 12292
-zcmeI0O=}cO6o%h65tYQzYa)JJ(7}ZYGTn)|YPc}O5fd&!A;g{FboXS^H#1$sbk8WR
-z2JYtWE(nVHA2eIHV*Y_kb?L(2;6mT}7-x*}19Tze6jOC->YP)3>Z$Ikt_I*O^pbht
-zIDq}kS{|Nau|v{&oxezXT#NSe=noaKc9?&vP9s7H2mv7=1cZPP_}vI_&(>-GSN46Y
-zl~M=@fn7;JuMcHrEvrrrtTamp3v&dZoMf{}tn&b1e9BH%og7$cT-m2RJ$TO5b4Lu%
-zx>H})=9E<@2Uc2lc-9 at ByRzp_D4w}G{mRB%jv^L=ltN%f0`}})UTUd0YJGNofB3;9
-z<K at 9$`1 at +jSxjG#iv?gJ171x~Pwmp>8`mPGTKeha-?iK6+^6m~yoPsgVls`hz6-%v
-z<hNTYYqI6-(5Jtiud6OQIA>eZxT#z(!|xCJX{UD at _lKI3tY5+)Q&}TYMVoq??7CoW
-z3)?TIsbWhfjSJha9)cMNSCgrwEHCO=5vAS4b}=fqHqW;gFJLcQW=c^#-e`7JFH8K6
-z8NkTy2Wzuio5vmxZ8c@!pj*#|t(fvh*U at V#32bdnFH`@AsXu*xmvy^*&Tuh3I~IO8
-z<{OT>G2xbQ3ME9SBgO`r=t7}~3<-R6D4RIMuR&8-Vm(JeyNqRol$HsO;Ll*J^I%)&
-zn89ptL$!MCMjng>gjqX0mi$dG*W)xRRK8wbtbH1=tvpwAFG(7>|Lo4`bTlKCIe*^2
-z=r^*;>Wbg4$9~e*_s+M|gXk|kb4jD$O_F at Wl0H!0<}{h4d0`1ZS7%;OYYAK09%(QZ
-z+<)>v{#$F}*qhhb_wHXno#0q*jSnSU%^Tf3Tx+RrTF=6!O0%_YBaC`!E6Mv=sG@%=
-zV?zq{b;GfS9miNg6{ksmr`f1rj<Yt;e37|9n+jI3!g|}xug at 84n;AXHdw<!q>7EMC
-zd5(2%v5Tm2PFGCefeSovfd|9DgKdEaI`H6of%9JQ0^leqmGm91Gt;53+*v-O>!9=b
-zLWG<2cx2Wg>kUu#e}hp9A at H*V^xn;MT)zWc;T|L30Spf*gut#M;7!(6Y6~2)+graF
-zJm1;)t^nL()=Aq9tTZkxw25vvuiccx7k1rNcDkyQ11qUvk`Dm}gA_tQ2nYcoAOwVf
-Z5D)@FKnMr{As_^VfDjM at Lg1GY_y}e49k~Di
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/gtk/blistWindow.png b/im/branding/messenger/gtk/blistWindow.png
-new file mode 100644
-index 0000000000000000000000000000000000000000..093a44c49f8cb3134bd712538e3fd48b4d50ea6e
-GIT binary patch
-literal 1003
-zcmV<H0~Gv;P)<h;3K|Lk000e1NJLTq001BW001Ef1^@s6xF)Gl00009a7bBm000XU
-z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?19(Y9
-zK~#9!tXNHG6G0Sylf-D$+MkF*sThA^d$9>xF!<M03Y7|)Lp>?l-aS-`_j>hWdlB{0
-zsz<H%>d7dyf?7 at DB{ZlJL!e at sNU7CmS>M~8q`RBl$!?Mdk7YKq^L_KZnfGSGBuN6h
-z_T;^*1s_4(>)6nde+9c^F{=a+G=dNEF#2ATZa>kZ=(9*>x*-G*co-k!0#Fc;nIIP_
-zV at d#lNn)Bs0P3@^=)*`NYV at N+Aa}F@;J}r8!Ii8|fOmX`-VBYkDI*e^5OCQ)=sRVX
-z0Dj~FcD4d|(Koy6A~K?0pk)GlYo*mQ|MCsBdo4ln at 5a~eO#nUJ47$5&CP0fbj3i?E
-z5KQR7pTE+AlTmwqL4tP)sa68b9BX3@;Ou?)xT@|&AR<d70sa&#-{*1wiz$FiM)-Lz
-zVp2W<7k at FX{*~grvMQbiDM4#v-yWq+fOqdpu)Ms{r>za(;t+#Cx8V?k87_q&q8Yqs
-zP0L(fDudsi)Pj>y`yP^tCrnlFIk*&>E!VW&8Ub%Blb<y6wKem84<DI^GveU6U1Lq#
-z6c-uohW6dc?DaF(8<C at RVPHXrK~<A&pqB{;J<-GDeDG_{np&xpp$a}C&|>rpC7q!`
-zR-pv72Tn8S+^@8^daM!X=rEj6&?WkaNL-3Ac~_JcCdsZHSXu3&FnEyUA-{1>a9Cka
-zL<m?9UNYKhB0JNkkT5Go1*p?#pI^DmDnO`xZjjuR;7bYt<>U+Mx0Hk^$z+!#S^ivJ
-zy9T_nB1}#~r8N=?A&~&%Sx}N=PO^K%Yox#)FE}H-{K}w-qy*`V_1U-Y0yx~o${Eq7
-zU3c+=2h3sa|CqEtg4<m^Z3`?am*Z=9oU!C5>!%+|LR5}B4=CG|WT$;@lx!#rCgF%<
-zNmjPu;%7K$6`bOK7L!!*H^%L$lIKNfI3<%(l2GWFvLL<Qa`{&dB>iJf$tw8yeg<=M
-zSi)y&J`cdDldv*#Ykh~BK-A at eEx6y0IvAKHr@rG1-oB|1TxFBr=hsK|XF at tOPKmx6
-zyCJT8b_ at wHO(x`r#gS^2t&vtCH<3Ukz)T6hzc!%NRanYqA!+AkMCXLr2HX$m6g+Bn
-zS2Qg~{3=C<)th{fTI>OpT+v0<((Rbv8HTx6OIUHP+%y8G8+JW62#@+df;4yA{}KEb
-ZU;usYPgZ|=XGQ=3002ovPDHLkV1h<i#x4K=
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/gtk/blistWindow16.png b/im/branding/messenger/gtk/blistWindow16.png
-new file mode 100644
-index 0000000000000000000000000000000000000000..fe889085c49b13f1f90a31a7adf3f706e4181ec4
-GIT binary patch
-literal 576
-zcmV-G0>Ax<P)<h;3K|Lk000e1NJLTq000mG000pP1^@s6)UPbW00009a7bBm000XU
-z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?0nJH7
-zK~#9!gjC-vLva-Ue7RN&ZER6&nIwC$Ny>x#c=JG^=1t;1SYEvP5AcQuc~qm8;>82r
-zC_mPuFlmZqvWcl_)Ymz8*KBvYoI2m{x%ZsUr|<cE at 3}%s3B7HcDpuMC$UC%GA$DKq
-zS5#js@(Bp&qHTeE1f}hO+)qTIA_4+WX<!Tfw`n3-%MlQmkGsb&u5N+UyF^31ApetO
-zj7Wkaa8l0wa&MNcU5VJ!Z^dArK(o`3;Fa8^(85QzJinj-%yxb$i9jH*A#r#Fn9abr
-zPr&O@)7+}RjF!>A&bhrKv9}MT(?Bu_EU!o;61ns!6ZCUruK^nB3c>Aef$K;yX(E{m
-zy-I#!uwNj0UnruZ5s2tWY_-2}nV!A65-Qka%03Sd3ADCmW7c4DLcnIr`;h1sLa{i!
-z$6;9{qNxJ#xPdN at Fp}s_IlI8+QAm3A83wnt0GSV=3dvgV37igUoCqBbwJb;kGFl4k
-zb_r~*OH#jZR>I-z&2U at 2Jz`bKd}67)L!jP{*_;klz}%cvug=I=*hoaq<j;biw)vle
-z`9*06PQBsbF^(IaQ2jLWOz at C28HuJ%W3c2n>xkH`nn$(&K~P`&Ex-Uq0;zA9+4Nih
-O0000<MNUMnLSTYHI|Xk5
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/gtk/blistWindow48.png b/im/branding/messenger/gtk/blistWindow48.png
-new file mode 100644
-index 0000000000000000000000000000000000000000..3a14f1d68536c0098d47381bc1a5ce329041b481
-GIT binary patch
-literal 2089
-zcmV+^2-f$BP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00004b3#c}2nYxW
-zd<bNS00009a7bBm000XU000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdL_~cP?peYja~^
-zaAhuUa%Y?FJQ at H12c}6xK~!jg#hPhsRM!>9f9Jk8w#UYfF*Xi(jBRYQ#KJKJVjv|z
-zNh5U=CA3N-+7MD2+DJ{SHtCmss47)zCGx3K)lhIzLYmf17ZkNo6DdkUmpG{nUf8jX
-zZE%boyv__>=Dm0OVQd!9_GWC-|F?PXoOAzo&OOV$_X+cWqi0I*wQc<w(Nc>zt3Z|u
-zEYh$5Kp>!D5OgP6ofl{jlXv!2bzPh5*pjN^OXrFf*_N?KYxxGSKE>hxi#W$j(|&dD
-z>fXVWEF`ONxTVNvD9>|R>u&*>sSFwgLC}Xy$9Z9I&DGvy6kSi?P~$p};raL(5&0R@
-zOXDu!23igVGtHkrTiHJ8M#0qt>RQTHB2GPU|D5Q#gw`}W+IZ~gn$C-fWK|-8x|WjN
-zh||a?L>@qd8bjHQb!{cP63ND$KwWF;lL&v{?k$;k$VT&8U0dn5;|ax_z>(I{1E7xr
-z=DbsL4+E`#UDvkkyRihK#z1)4P!AY)jaqWBHS(4H)m_JDzlfN?ku$yuv5h7mCz_?+
-zUXzO#J at gNlOpFU@X_~w|o8`+xR8)je38N}y1QfDiUv<~{+aKOBfj^$9O7q)+4~Y`6
-zp%9!nkx5Ta>=l)pYqMj=I5|1ae371wQ`S^|?Sb`8p_vDF{9k at M_yeMlcWij;t*p4@
-z0Y*j)-uQbKfk4UyJ`vU$>DRw^`-7V!z0~Y0vXpTF$eOLy)RaMMYntm(3h%Y~{O5vm
-zAsP<>%VfoY`?~w!HV at c_`8-j`heE>HGoGYI=)Y#r*B9Sg+JT{d&9yF#e>f at g3rvgW
-zW_}2S8#60p_7J7F>AY<6-n+ at SJge`UVq@(@#PhKs&A(oEIM?VfahsEJ^M#s+6dN8<
-zq@^b`A2dBy$==nyg9^a5j6KoF1B{KPmPtoPBGb{OX3e1=+njpuPVxXF*ER3{#is5j
-z7DN3yk at +kuWPS~%m(X-e92K^mB=c!Fv-El{IQ;on7E=@P$qn^ues|C&IF?`%qMraz
-zht8HP0oKKm%gRbEC1x$SMZmG)Z@;y%EqA(OgPOPN6O5~6!{N5FLS<NNCr($ov?w(f
-z+^%=N$zgaPIsMZO4*rq2B4VJoDbZ3JPbw$dp}05{Pb31FUWd|>TRQD6$$L>d(AgGW
-zPitqR3h!a#qqcUEjEsbV1%L=_esB`gyd^(2m|9^Qxt?fDS*buO5*f<Qc6j*V8+g6(
-z4H^m_+&muXG39RZv!PVNiB~Eh*Nw4)0-K#X1FTv(g=bb>6VVhGTYT|L0V-ESF1Ngb
-z)I6|oaRLD$*CdI}ir1^zw0VNs+6e}S490H=X&JCE*CstZ_P<=QR&nY?a&e#xC|{GH
-zwbf*&v{_L`*duOHSuHFs76z`kUrL|artrG>YZVZ1Z8b%Rf?Wp;(!K7MQvOn5+in*f
-zfZ$gel53?>M1GO*_zw-T6GWV^LfG>ogLJP8qnZ(8=XdV;0!VqXgr=roazcS<443Uv
-zPM%P+RbhIB;3(Xf_PrADRSH{o8GLq+L3)Pkp#Q)`tMiC{B$kBM;f>0*K7;-NgV9lg
-zkx_L=uVX04%yL+?$R<DEp|H at Rpuk3=@JROxTXqUtb}B+4m<&Q at b~vt*hrVD6G-!Bs
-z_N%cmMSHu4jt&ojK>TcAJK*;#{C-7O7eG4ROif8~h{_cq^7EqyyvG9`S4lhug!koe
-zTUnvfP9M|#(Ab!wxjCKAP7|%?XKU#5S=7`_CY8BdKs%zA2tZwH>4%^<T)O0;p&<jy
-znjhk(sadwn!soMCy3|To$&-OV!&BAWo5FQKoMR`OGB&idB;E?SK~9cM^_nTl$}CJz
-zB<b-W3=e3=gPPD}I4-hsgoTAfRQXtNG{<22)a~`-Ssg>eb3cIdW@^^2o1nbhLgW_l
-z>mO-4PHTG3IrMfCbF(4}a`VHfv}Bc{yjoarPt?^A^rTt!HzzPS<are4=3bxA;?rBk
-z at lJQGp$Ry7!lCWo4*fmuY-<OG2g2TI`;UzhD63LbZ&9pXFUU+T(Y!cwAz}gux_B=1
-z%gRD*-8zm)m_);y4)4EVGd{-}?`Y^a?a*=B;h#mq_T7pVYn5M_^1_Ua37|ES>Sa at 2
-zp3Rnr!sPwKaQsD!o{RGrtTVXYt9k90HpMHPw(dU9&Ar-m5OV?;5wu$Bvv+t*?K(SG
-zRZU?i7!Sa)Uxbq0Iwp%N7xiYv)T_X5ATrS>I^2zgH(#-7eEY7QiAF$+eD!i;@1G({
-z?Eb2&?Fdf-NmZQ-CqFsz0HXDy5aWX5n`^rND(GjDF*w(NO#%53=Z5B~>Ym?#>;qh$
-z=KOz<F!vm3E&Z~fUk0+{$u<1LLC at nVavVL`eOA|BKBvz{doP-<j*}nNyGou%Px&ex
-z!>9+=&L73NIH?W$vHew7+Y<@8x)9p8_Uff8gWV5kt-lZW=S(j)ZlL9-*~WrRZpcFl
-zpBfxGTe8HkcwXRXqTDB>h#+uC8FDb$4?yPhu}3ImJ}&Te;DHouX at L(kyrK>J_xr1^
-z4yD3lUK;<GTgn$(%HFQEvk_z!PzDrm>&z(td<<L$eO^R0n2zzz6Zdz_xo-atr at __;
-Tj-n}$00000NkvXXu0mjfBt!I9
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/gtk/convWindow.png b/im/branding/messenger/gtk/convWindow.png
-new file mode 100644
-index 0000000000000000000000000000000000000000..b550c92d33106cbb5ce9373ad6380b716dbb199d
-GIT binary patch
-literal 1126
-zcmV-s1eyDZP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800009a7bBm000XU
-z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?1M^8l
-zK~#9!v{y}ROi>j6o(@s<Q#1sn6Veiqwi=1SVy2CiSj at sgLa0bcSZIj_3si)Kpc3rR
-zArkQuwP+I}Oc#EN at TR)aK}vsUDASgxYF+2NzW4fO`rf=ZukA at r=FYt{_k8#KeCJ+C
-z2mvQ@>y;;yK7y(ilIA4*q>EH04U<-HDC(D;>?_#;Aj4kzI6}G=smVwF9|5Uy4S<ZZ
-z;lmi2)RC51dBhZe>TY&r0Y*o<R1j6R0LXZuYJ8e;zOxgEGyqLef#1J at XmoIX#tdNQ
-zOdxw6ke4T+AU`RPZHXY_0H`OIjS1F7hH7esZqQEB(}9v=R!JG#fk*_vC-?K1PkHl}
-zz_WUHK4;@QcSy*~H4R5V%LyF-884-e%bM{sl>*W~FE*~*>I%S<*I_(<RfjE`CHQ>9
-z6O#Z0c;GR(zEWEaT@`3;1J)GfVE^_*t^l082nE2++XC6y5^3DBpAXETP&{BfJ;%KA
-ztiWhWE`_0dk2H)Y2!Pk4eks#tBatEF%W?~Gtn9Qaqt|OgxLy-d#+<+$)`X<Y;ffol
-zGM!%U?E0~gmR8g0AbTKS^{2+DjNtAPjG+V=fY)kuO_3jW&OLOQghxp$^zW0*Il=Ey
-zJDV<Cw;Jhu`utJZ$ZZ*F!fcsP1-dYROyh)arKB()OLtE!ZX+w<a!V%b*GZOZp2P{}
-zb-fDm3LJ%C*6K9NHQ!2 at 5m6ifS)*T#2Q+aSf;8GCV=6G2G(BTze(DrpDK)2WKY*<1
-z)&OG0iD-0)2U<Qi$0d at P;jB5pk|G+LIAMVF<r`LkDFkdqzJ$dK<H^XQw%)^L9^e-1
-z^GQku%MC&&6s6hFhVvHz6EmD8WzR3*(Nlr;4xo6Io)fZ0#rm<2pAd>s?(4>UFy0F~
-zz5>r11&(iji2OzVl&a&({iCRlR%jr$X-OE;?tBLiNJ%$fPz_B2y?=mr?U9trv*UX+
-z-hO}*in+5<t$Bdi at R8F^F5M95`#UlUoSlW1YX=4vC?24$6ebXL#%f3=n(@=S+=bxE
-zy$W>3(4NQx+!0@=ve~^CA;|CRQUVZpH%M&#{pgJYz*i*lLOBi3*lofk#aYcc at P%S(
-zB|m$+ at V?FRebQ`oE3UG8gm4mZN!f*<fxNT#f at L=?esF3aJdBFT6Qu+K$v|)hb3LEG
-zyBCuuPD|>6Boa&dG9nOVcHwwQ<it$pQp(8#mE){d$rF4 at U9LW@Oogd+Q*e-8Cycj!
-z88O!wi6iLfajJTQd7{)VH at NBa^-*@UiH`0b$gysmBW<OV>Y2E9Uz%5YWz&2>a{4?^
-s025H}5ru|$%4%kZ$$QOC_xmrv00?oW3{)JdtN;K207*qoM6N<$f-q+VE&u=k
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/gtk/convWindow16.png b/im/branding/messenger/gtk/convWindow16.png
-new file mode 100644
-index 0000000000000000000000000000000000000000..b00685591157aa0ae7ed8e5f928ec75d78d67bc1
-GIT binary patch
-literal 637
-zcmV- at 0)qXCP)<h;3K|Lk000e1NJLTq000pH000pP1^@s6J8eh$00009a7bBm000XU
-z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?0t!h)
-zK~#9!oRrT?8$lGuznjFMr$)q!L~2{CH#Y<imLBxbgIFO7Lg`8Gy$E`gR{wxj{R at ma
-z74?v-P;@I)BUOo1TZ at fG6QhBe#!?B2GQPLYG}(27;Dg7^+su64&xt04fRoIwdwjG6
-zq?zmuUM5jSG&_VY_tP>!s at u+<l8&<yFz*PFo};8~>c?~%sHp*}s&2vh2^6(JB*0+r
-zu^2GFAdo&R-eQQ}47}{rOsJF|1yYc3p at 6=zae>zz at 5-f))hz?h+85#X|BtAFQ*#lZ
-zfs8)8cPF{H0LCT+$RW!ESvz>tW;u3q at OiMUEF^WD#FzEYNKvhxHkzNf2_vqOHr_`b
-zawZ;SF*&vZ(^IMZ{g=n)PTbrd9POJ$uJ>Dx6d|gO_H?!q8<?J-fVUE;Ankpn!R59M
-z+svAq+Y}mpE0D_pjTF(z3Cw+UEl~FeaN90<E67=khNi~^4PI&<IbfkKngLxeMwH1?
-z6hCyl34L%Z#@yE_9AqL11Ob<XoVK=FCo_{3cUJY=w%9aV%)>$z<~C1SLiTDnE94PR
-zSPQ-J%P`mMpM4zX5La`;d4&no&O at gTbH2IXJ_Mdv3musoEj5i>ub4pHw1nj};+!UQ
-zX-(kguB{syQgp4JwxgfkUyV5Z74T#1mg-aA_fpvYz9Wpup{tK<zZi7$a|sY6dM&^J
-X2WQK{e}VKq00000NkvXXu0mjfp?Mj=
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/gtk/convWindow48.png b/im/branding/messenger/gtk/convWindow48.png
-new file mode 100644
-index 0000000000000000000000000000000000000000..c7591490a3cf3254306b6fc387173ace69428289
-GIT binary patch
-literal 1563
-zcmV+$2ITpPP)<h;3K|Lk000e1NJLTq001!n001!v1^@s6bDTjO00009a7bBm000XU
-z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?1*l0x
-zK~#9!)LL(B6J;2GZmT160z**T>|D`I`LveB#EBnP2*v~wY~nB^>NYhoMnB*re$W^<
-z_)1917o#R<H#H#+BAAQ>HPG?_X9ChzKZp}(ZTYL~y0`>0hv)O$y;ttu-d*3jUW-1-
-zo9ngj-95ke`S*L?t0c=Zcr6Ei at P#dY%JlavX1so$R4oWpIDiLII)WpFqf_9r1dce4
-z!w4#Q+d!c5LwKOkSEUYF95EbG1XQdG2&Vj~;EFqyeROZ9V1z+1w~2YM@|9$c0f~AF
-zf~`K?bUD;dj*z>GSfxP#0ImKfbp}B4GzC9CKU9?^7=S^$8_diAOiu&k at -pNvspo})
-zaZXnkKyx!dho3%6 at Nk!7_X^u(F-s730B+m>NTmRdpHLNdDg-Fl4ba;w49FIUDF_5W
-z*=NM;g2|&YDz5_ZLdZ(no{_-suQ)ZufD|i&Kmb&<zT_w7^8n+Yx?6b>*|M32R592Q
-zM8p;Z0%#>_zz6Zv6u`tG*|XKRv&yTlNQ%4J$S|LNc at SlBkV*r5_>ns2t(Qk|yyv;{
-zr_LrI^7=;Qv;Tg8cixsN#YaHzRt;P+8{{(&xllcY+;!rh?K77%#!wQU?(--=d;Bw_
-z3!OR}hdukfS3GysNNi6aH4Fy9E_3a`MUQHXSaBz2g^T)GzhLf<?yIjA`1ly!Ve3}A
-z5X7k75<~oqsi|@R+qVqD_RWKyEBw=R3f_$l8@{6gO76UJrR8NB5iNlzOIu_KUOMgz
-z!1{H4b+ZNmu>sLZl!OYPkGWEipTScH&37r2)WQ;`l%_!5VCzz}_(>n@%7o;=<d`!4
-zLlV~9DIj{q6Fq(CPT`tlCzp%Ur-3llii!?TF$h4dik%q<zrP|4Q8KG#KOsQKYAQrM
-z1Q~8XnmE%~G;4T>FHy0(UDEp)z`zTV$kYu!tB#E-X7eE<<?d(;zyod0_XmEvl7-xr
-zj3X;->z9P*`|NH+RWqH|6+0|+Zen83{@pls3C|}BRA91YJ$BZv*wkAFo|lxa&x!b0
-z|IlgH1o8dDfumyz33TI5igjB6mfelVI{_N;$t}xn&H3jh{&p8W6S>^E3lan{u`Fp4
-z2VuG;Vn#d2ubucd2`Rhc9)Pty08LA5T%r+R9vAK01sZBXAt2prC1_u5eI3${IDtsA
-z?GX+{^_huQy**&Byq#q7G-PPM7gNxB36{2$P04DOh?{K+ at bRGSPy~bO4h2~%m6DaC
-z8P6i+SG9Q)Czr2dqckbQ)+Z%cwZia|visp9b70jojR(Ere6T6scT1%XaHc at ORqN$`
-zSC?ntsS(ct{#qdeUwt#i1BvUKqQiQZqSYl3PO}8b#T>w~lPZ{R_uljjMEZOJ-h6)}
-zG~EI4Ttw1>ehqbZnh6Xb9PZE=Tg&fc!-Kt&UoWe4ec^B9T4!X~@VJyPw5N<n6`{)g
-zR>~}T5VaDr#!JsiFCvH-U$LWByMDp}c+ChP_>gy9;QU{6aQ;%VWQ`9#moxo6<+Ou9
-zyituc{+u_S?|tpK=P_YLJG7!vWFY=`;^V4cjJ;5C<p)cVHo)~;=bLsm)&)d^Me{x9
-z=4S1yrFt5m#DA=|_Cu_YIF65xzmS!{b5keAzupbw$Al<*3hy1Vvjni08Lr|3^LIV0
-z5EW{QSbS&~2wP-L2f!l_sx at P$MK-ad7PDE=sjd2xif>Qdy4LBm45xprnI(>(J4I~W
-z$;7p2Z^{vecofOu)=j4L*|SYEVM}mU83GsYv&ps6Kg%#P>sZ+=%R*);e;ryQ=@<k9
-z(#nF~adrP=mZ*tJPZk!`KEV*6KKOod5w0@#jcZC`y=i5sKcXY5!}xpD6$lf{M9exv
-z2P;h^E++aHA|0Rrf*7qD1P3V0d^N<fM}XUaNa(sT8gZ}w`}D5>0|2EURzt&&-P8a8
-N002ovPDHLkV1iKg)G7b~
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/gtk/default.png b/im/branding/messenger/gtk/default.png
-new file mode 100644
-index 0000000000000000000000000000000000000000..fae92d073092cf16936d9917e8ddefbb92c223d7
-GIT binary patch
-literal 867
-zcmV-p1DyPcP)<h;3K|Lk000e1NJLTq001BW000;W1^@s6n^XTZ00009a7bBm000XU
-z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?0`N&h
-zK~#9!tX4~F6HyfYZr*)qlSairODJNyu(7Bcb<qfl;38z<&V_X$xU=23cH!Rm3(Qt3
-zlDZa*xF`rptG2W#O*9$}YSUC|lbAT3o0$nWGk5Z84jks at GL!E+ at 52;DK|AvJjU!AC
-zU580e8eS=oE(@BtdaAPB>VH`?0t6bQ$6eAW=|OZZFG%A=B;FAL0_GORNUx(e@`-eo
-zh$LGQAaHJNTxM~p4E)Li*_?vXUpjB8_bwOU_X0zM3?p9kY#|Sb#GEAo0-vSFL*rK)
-zn?Nd~ApNC1bB6|i;3yE9WVN#-EKxl_>I7uq*&OhENx|>k?tOn|iZsNG*Na3TS|^|-
-z+p_3(ZZ!wDl4=Fm`=g%icA#&-ngkC^<RXLH)o?veBw{*&xR`KO;N=pK%K*DO>e(m<
-zd}INs_fT6Tc-aQ+CnEQPqU*W4pFT5#XVbvv4?vNuu2$uimiB-hO3VT!YX2bM6fE8=
-z(s%!Wu|Pc>9 at 3mmYb<qnyKV;0d<1 at eYd`KqGGcR;Kn=O`Ze6V;L86>M(3p6l<bSBz
-zsc<iGuNj4xu^=<H7B8T%)qMr<Trq_**XUuJtcH!*-b)$rvgQN=M|uY)s|LTX;pYk`
-z(9oYJ##v9mJ><ziu<>qU+~nb;O&bse(F0SH-2=Pa!00jHc!(O5L%4SW=T4i9i|MZ<
-z#71<UUM!cDT0^pOE$@6{ez>TrJ^k{I$iX9*Or4MqrnF8VX&k*5&Z?6wwWdg|^dD`{
-zBZ0%f<rx$BineD!ClHo>9HLN+-C<aGqF{|0OR3mdIC$%oBsB*Q>(j6)0WQNdo^IYy
-zW4H7Qc)zN^NgnVC8D85B@)GOK;EUQ~QeV~B!fQLv)zp46o_9~#{J3?EiGycOwwl?R
-zSYObVhr&Krv3cI^t at c8Pws4A|32mcISZu`8%@$N at G~0b{Y%qpL^dI+IZp9RWv{nTT
-tplz(_)7pBDuisI<eWmiU8yEc-U;wC;5=tFXE+zl~002ovPDHLkV1f~Ki825H
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/gtk/default16.png b/im/branding/messenger/gtk/default16.png
-new file mode 100644
-index 0000000000000000000000000000000000000000..b436a77b5256d665852dac863b0925d615fb5dbc
-GIT binary patch
-literal 520
-zcmV+j0{8uiP)<h;3K|Lk000e1NJLTq000mG000aK1^@s6Yv(<I00009a7bBm000XU
-z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?0hLKa
-zK~#9!d{RwILQxPsH|=Sul~D=Ohg4v+kO()m(N=9+w9lX5PpE%T|Dd+j!rB&8V79R+
-zp at k4q6oRElnS?LpHS at 05_k`-eyqSCNoHOsvTwxdn6b^5kL*x=<Yh*EW<Bsf{Y<qpN
-z`KUI95+HJt+$PyzLkB8VpiHLg27&<rpBM0XI$}E{lI#c&d6(jiS{=yd4CD*=6~QrJ
-zIVv#XH<uSA5*G*8jyNsOxZ3fF0sR|jHG%3I at cAKQ?*QN at vgVRPD@y|5X*1k%(#QOj
-zOjeS==r0QQL~L1=>m*cq0VZZiXcV}l+|amyOGBcE&be_YzRKjMd^g#S=LhMz5ch~M
-z)uRrz-u7Vwf5PFgVoj5t1<a8|=I}50{(J at 1Ow~y4L5e33jR at 50269(2$xR~*hOEkc
-z9*evh6G}J90wJ~H?goZ|bjCorBD-$~cb;<y?@XpK-m*a4o-`k3>r_CoMB_b`kFEWX
-zj at o4N>PldbuR at zCdQ_qI9{UBi3;i>b(7YbxXgd3pleQQ95nuq_*Ms-&nRs~s0000<
-KMNUMnLSTa0qT@~g
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/gtk/default48.png b/im/branding/messenger/gtk/default48.png
-new file mode 100644
-index 0000000000000000000000000000000000000000..8381428f20e3bdfd3cdedfa63efa369c0eeb4b80
-GIT binary patch
-literal 1178
-zcmV;L1ZDe)P)<h;3K|Lk000e1NJLTq001xm001Ni1^@s6&qcWk00009a7bBm000XU
-z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?1Sd&E
-zK~#9!)LBhW6JZdZ-9iER5<f5!kPl5DD$pPo^#C4BJeeN6)4$-=i}(-V4=8#tCYlI%
-zglLITE`WuI0S!<^Fg1cuAe8d4&UD`mrTfly`>`cXGTC%@yF1U!GxN^8t7w`AnaHb&
-zypwqFpmvHQ{jNi;mE1lejsesls{dZwULceAE9n40qsc%ost>glGLv=Geo_R}?<fE?
-zoV?tP+5yf8f$2l-K`_Cr0my;jGU=svB9OJT0SJEgpmxFW2t~waMJ*Np8t)O at tWEZo
-zjV*vbs{kv1HCPVm=azpTy~mvoaHax}Zv9wwPC>N|<SByi*#>~d`-JDqxhL*K0cPh(
-zH8ebZ7uQt-)YmA`*pT$rNvd>-lrjMj#y_z#{NuP5Gd`PAS`5(Mk`#yu#1R03Hh#|Y
-zQ!@Z#QyN5fog+N~xpm!=UIPfgYXTq=HX!3XdHvm}2Em`X%ibH;6liH;FW*NHJ&6FQ
-zOg at wuKR9fU=lgpAVZ1LI0oV*5z2?dTC^`X9jIk{#vj>9cMA2ZXlZV!d7yz-dF39d2
-z9MVh`B~i%O&?3NA*q&i77eGZNR-^M+l?tryB>+rb#43|2e)u at fTNxkS0hpTxn4h+9
-zd at NG?SayE_%uMLOt%RscWm+O#M0*whQHK(ilWlzHx5?BDmq`fo>g$wFKTbZ3v37V>
-zK_64%Qo?f8hKwh#lP9ww5qw^7mcLH6Fj4TTqV+Y&!Xoee#kuSmZwN(_XvK-K!Y8hS
-zD$DOEpRkcFXG*6PfQ?P5LtE99J+<y!?WdxUs;Kav3k#sMB=^P?7W3CmS4bDM5mn5l
-zk}grnIe at A<`FU!^ncgU<iqXx)?D`tLvC5UyT;f}d#)|+2Zt10dgF=388FyN!m1wwv
-zt;Jd1`|Zv0euySD1Aug7qp&qMImdVMdQ+Qqb9bjh;k+N~M)TqTNGGtH*w#j)_6Hd9
-zBz2zKlC^>ibr)hsT9&+tGZ?^d|GNPoX*(U?*wG|L%~!}`E+9JCZI at YEA#Lv7R${X=
-zhYjiDkB<O|9W_>HxS&D&@iWcQoS at d3h8c!7#xUcTO=JPPyKJxD0E}XryBW at 21ga|a
-znK;Q#g=u%f7--1*Deo<O{sQpUufYQ5$4(?O0PW2>01J79#&;*4G$_=WPPngLCe>g1
-z1M^~O8G-C-kdKMFvYIeo>_WQRFP58I1^{oS+`Uk(D+ZNqhiSG>Q3izZ?Dk?t5pYmw
-z8@@X}Sy=$wL?#I%g>X%PZOyjD2O3Z_{Q|Ymj^XhU=uBd?Y2QBX`vCpdW5WSb$<K#_
-zQ{}LPC39$X4SMlCQ>i{fc{%RtgTvkDv_3W at e5C<6{8AI21KOu)tq2#Xh^oTy`UZ?V
-sf3W{P)5sBkfY^~s>kG+o%Rd1I0QP0BQ%`-CG5`Po07*qoM6N<$g47Tg^Z)<=
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/instantbird.icns b/im/branding/messenger/instantbird.icns
-new file mode 100644
-index 0000000000000000000000000000000000000000..0843171076ce097029359a04103f98c0f74bc4d6
-GIT binary patch
-literal 21624
-zcmeHO3v`p!mfq+5DTsP!&GHgJ5m9{L6S<;;;U)BMDTwkM6hT1b3i2$b<t>oD=p#+i
-zrfJ#$Ev2Qe{Ar<3YI(oPv-v~0isR_LqqF9&J9nH}y6%h)>b=tWP8v$nrlmj=*R0h5
-z{rCR%KKt8epJzh4WZ}vfqJLbsBzD*fM7`f9yc%!vCyVZ`tW=yXMR6%kr$OoIg6MRX
-zI=>=KV;Qhqg}W*WKPB#Tx(Xq?oE~D0&I*O9&J(%zE42R<@e0LRqcCUVQDRQlVMzOH
-zi5Xlc6>?S+H at IA<73OkQ5vy>X2UdZWZXk{2M2-dkr3CY35upf3k#etd*LHiB#bmZ*
-z+jkTdDO9nGs3cG6S!z$zFMR9uh*Y`f_-S(%uS?tE+=2Ex(ca}yGzCe^XGG-4nyA^a
-zrs8c%9+5Lgk(}1(X$7(rIeY!~TsUt7YFD^*`D>*zpSd>Ajy~j4w!%x|XI993eoDCw
-zy|a@|;RVrARWhHvxy*{(cH1aR;f1kL2W0-*hSE$xPAgdzUbZ&spv<PE3B-^Agjr`C
-zmDz&)424`4uw^K$blC}+MQzDcOhh}OZ<~2qX20ESQK&K<)vzcmA?l3GrskRv#F2(Z
-zFl{(5vk7L4l1l8j(*(oHJo(=6F}jyt7&>I=&|$+zj?0r-WU?7FDI^*$b;x1iBZfRa
-zpiin+^T42|UmCkjreqU3os5X^i_MXx at E0HNXVpr520k}B2hGjGycNx9i(Td;2KRMn
-z`M?*#vq7Dk4pS0QA-L_4Hkl27IA6>AJv$cSv|?dQB$!I4XUR<WaG{ppKO{U$re!82
-z0h7c9hvin8kA1RFv6emfGAwDLO+4CAjulP%muuNm;hE at mS-KLBGQd0^>hpaREgSes
-zrc9fF7z~)lcxFI<wo=RbkIInQq+%mx1uUY?Z!=_iYOj{v4+|y0;DW(vR9Mk?i%ie#
-zLz`D1%z?#eAT-zl?WJlhdnDW}vxpr=g*!;#3!uKz?|_z`gTofUPHIFL=OnXCPt<5x
-zpD_>?19yq=v>n>WS}i?^=Txt^K#kCztktr<V<D8GIaL5nfO7vqEe*r70J@;tXp(8v
-zAuSCCmV4cC4Zs%x4g{DbKo`6>0UQeOL4Y}Ff**k?3Fz}c2LR0zu7cj=0|%KfxaD47
-z0q^p`&*C{f9lj!gsp(AtMgUx5R3w+TY_wRw$n{~wML9XvE1Xk&=x_v%C<NRnU{?03
-z5#Ff66Y!o7CX|?*@LwtLkF;!nsDm+GX at c4I$TZ+6<^!Wq?dc-7GMJ8IQmhb`1DGqL
-zQT`MWO3W3uD=HN at hHH=*#kWkDDwwUC1c;&SI|S1qG6#h4rV3c*r@&IBWsi==j9CYR
-zD-rWV1e%l#%N~sT%b0%iM3R`n<igUij^7HCOUwH{F#@xB8m2rZei_zfYD5w&<yxul
-zqc4oZ#GkaIX~AF-8zK^6%Fy!u1NvCBntqQwGd$c5j~ugt_2z;{Qe=YHqxWEWoNm~&
-zPd at taLj(Hvf9Rn>Pdq(z_~>min+#v7f_Ec!kBo`&UT+#)A+tAjiiJ;3;5pOde7H+y
-zi%Ttvu?a6(Z1CYunMZCETSk at GI&6v*|Ei3{XmGjAW;?JCIgNxpZ`YEc0>r)-wE?>l
-zRism{!qyM604$N&lKf0~n#h5PzkHAhV3Eut-p$DpyVm~gKo>q{1X?JwS-CdFj6UWo
-zeCsRsr+7h%&O&nw?NX#&Z$H;JsTs_m-HKGWRQF)K4-zyPM0?7VFyp*YkM~7HiWXUB
-zB72w8tK6FQ;i^S*roK8p0sHoAGbUqQM`M&+HCC!ssMN4K4y#9iVk~TQ!l#J=wGowG
-z*Hh8NWk;Gf0NR;DIG4PQw~ABA(X1v4Rh$mj?FrbOcR<g<9<Mledt32nMKL(@5fi6G
-zX*{tKXJM0Jnc^zII9gHG6k<DFI{}+yDPqQ~@Its_a4IY$ITcXCk|s+NXU-g3Ok&?q
-zDv)Fq4yTPtvL<5ktog5(QwnfrMLvb?_a4b+rPoGTo;Y>Z+__UGVx1mO^4iPjK8Lfy
-zg`naHS6r?NXZ)10`;l}a_`burEz-S893D5j419i*%R(b%QP>5K>h`!3)LtG4Zv4G;
-z<tvgJfjLy}Q7?Z=>}-7zM337;yixTiD!WvNyF$Z0m3iE!h&%^X!cF0*%G~Z+6zn8~
-zhH40BAe^m&!v&SjR*(m7<;2_|Lc>z}1bPv4ccFT(yYATG+Uot))rStBI9sIBW!w+k
-zd1}v#hm{@Xq>VAD`kt|yldT1NPXOIXRKHEtoOam_F*$n8>g2rr7aS^ia6NG6sFJ(J
-zvAIAm#UvFT&js-|%29cZeM709$L&06SIM1=lx!+LUmov*n{kiZrcxaS%#)?^(~dP&
-zdj4Tay%kBG$J}#URemOK^#MKKP<YX*(iL10RDQ8w^+7$`v==}lZU`!?i94!i=_fN)
-z+z&2isO&=a2|Zg=nyH#_*1Ih#I~I3Z&&=m6$P*U?4-n_-GkUi9Fc3Eu`6WCH&+FOR
-zYKw|(;<y>b%gxu{vwYDzbLY&OJ!k&AOQQ4iEVja|QUh)WFxwpZun!i`njA4ARi_y<
-zamIpZhn~e$m_UII=n5S3a`e)wcU~WzrQ?xrF3mynYO}f(oq|t^UC$R!8R>v&?y77M
-zA2zAjA}^a%b|}`SXYY>B*YPnkqakj-U{Y~2K(7p0dbTL4P{&8l`XEbB*(Nms1C40e
-zRy~WJR-$9!?*ZSNuF at s!-u3A!I}($LHsi{5Y}yBqHeEC#KiE9*Ndqu at grZ~PS7hp`
-z*oc}p8gSKc!{-2yH!5{(+|mp^TYmvaJ&u(Iw6bLAY5HCr8?yvLdAbT14cOV$7Cp_}
-zhZZX!Bwxp=1lodX9YtACo#RH8yK&B`ly26u<)aVi=uOy50DEvZKvmb9^)$Ig$3`xL
-zU_}S$EVz$BSyHQ`sd#P{pa<YyDAQ`;x)MS?01>ww@|c4<nuq7<H1tS-MJ6;qq at yVS
-zkERJO(S9e;cYuxuS_{<e4N?qr4$yF*N05=|94P>21C#-t6rgCo-v>@Kp=b5puvY-r
-z`QSJ3+~Vz+NMUn&Q-no8ZK4MPv<eW(Mj>o at vumXfT`1z7F{%=72BO0C>x^(m6(++y
-z&0AnGin#*)NXO)8z<ZH^+aM;(@t8E=sN~q?DD at W6iw5t-K*f~@mIIh9%TW8ubhT+Z
-zu(~y=z^ip^;!2EFlG|$#b9J}CF|s4y!d!?w0?vzQ0t<7erNC6BW3Mj5d?^s~6icIS
-zeKOEJIyT`w%*#{+qWVO_nyZQ33WH0>M@@boQ+e|lSlmg31-mCE36^r5G-}dZG3VDG
-z2X8&ridd?pF^Mo{pex}SI?d<_GZ%hfhszPOiiPGzYgcT7*P-`Ree|MvZ%&;Q6&XHu
-zTx8_L$<t>qT)IuqK7=pTdG7@(JFq6+>rGQD^epidEbdgXi5%Gy=fhokX1!=pjRHMy
-zHTY1cp2rqpGod<c7*}kn<XopmRy4I7)jF05cRMz#EH8xZZgnA2BRB2 at D$Ac>fnTwn
-z$7G$fs<;whwq;H*0V at J#I)aVNgG+&XyUOcRCK`bkBDJG7)l558UjE*g6fZ;$8+N!|
-zs&qPj#;7D8B--Liph|U?cgDs0z)UYlm&(+zJqhnl8ijb|5b0!6h1#pWrmD!1k-T}`
-z>I7`T8w?*}B|FfuFK{1F>4M>09M+7$%qngJJ{dF6a~4~&=LTS>lRje#jK^^m at Ttk5
-z$4$VeCBo?5MyGsgoH*Go>}b{vFki{1Y~QrP`2%ilQ!jbXf1E}s#E+|<eBdUe8<!YU
-zh$%ytEyORXo^62B^wRqHgczLuBJ^cD at j8ziXH8L(UK8_Sl5suGe^}g?^Th#ZReKfb
-z_3Jh#q at -_J;XV7kwleDJcGr8{s_Hg)AbLFYB?be|eorE%;&)^aUJW?=Rd>UkpZzw{
-zgh^bZ*(zx?8ZK%6NRp(HG&vIEVV at DxXm-IWNe#rpc)3 at +K&*#mpHxST^BRdX$B4oX
-zOH9KL(MhN^bOt~7p(#HHp^~VFD&dV0za*8RCI6jNOr$ABd>$u$6iY>vFM*nK$;6q&
-z3(yK at d)N+XyHK}F#Pi4@?S`}+VeFDqz&R4$+u>&=fE)z0N!2`C%7&CB)pDDZMK<X$
-z&ysNU)MQF0cqXD|P^NT>TP56Zq1W*YiNbISYcizs+zcArzr!-53)})3OADA=$URcL
-zvIjCwT&Y3$YOp2X`8#fswvtKu1W(f7O$VM=@DInN^r^tYut90krO$Xe?0DM)$s~#A
-zKYI~uggw%w&#%jPehxeKP3a5B21=KH?|c3MPqA4`f8a)xs#(&Y3&4aCJpTeC1f%q&
-zSAeMr at wRIjK+_z+7b;zXfJRMx*ZD=vrc6vtS#o3?)|7oyZ_qD}H*QV6g(Rx-Dbm4(
-zAk2)qm{ALh^f7vcTZKkc%#4a<NSE+T#&~$VPb(^ImazL_Brqx(TzxQVLN-!X(@1I3
-zDI4R6q0f-SpxLEk7)m4vS<F`H5JuZXJEV^U%*~ioRl+;Vt6)k&6*6vSnnFyQEGdIZ
-zB*i;1GRY|-6eF~is!(1o<zuw7FrhP%7d9Ks2}tP at HX1zBKx?N{kWvsZ*DEDU*jRuh
-zN!U>EjE7GiiNvTBYMita6Owo$?Ut;(5FHm&4C{{POBPNVd_dMiOu<azlEk-3M$Q;7
-z at s5aKz+%dgl7VTQlnS>3;$adh6fdAXv=tDRm?loTi*pUKmo#BD(BrWzHQytO0S-Ti
-zC^y?MzM$BbS1cnMdlz-Tx+~CKf$j=)SD?EB-4*DrK&LA3>*rrv5|@(gD0dyMb{05H
-zDQjkrdbmfYn%<ccdvr#^zR&)*G0^MUpU&pK|MER|M$kd)UXf|1{}PDU5BvGE;&&hF
-zAj<8T*s!%nuKMwGsC;Id@~hh;3fSry!xtUW1u|aUKkx2<!EO~CxZ&eK at jHQin-`Av
-zQg`+mR`}OWFtzLQdGwtWfxmvH-N>Cae4Wz&HY>p2{<5<q9r|50-FG_~M5rA`y%ppC
-z7<%1m215?s3c*c%|Ml%#nu%d+f4phPTXZ;d3!BoAt}FeGEdR2olO+gCxT7U^gR!-A
-z at WIZ^g5F14x9c+fKf`aHz;C|nGP<^b{<`*N3C#Y!ZL6+CiaK728 at rM#V5}n at ZOCf_
-zHtAaMbo(cBeAhCy6Rqy=+L;6??KJ3W_}sk#6IjsIJnhEYgAYO5yheBVmfJ3WBR)cI
-z{d(l<_T9VOa&1m)`nx{qa*~b$UVXk*0?8eD2f@}5=9j?GpMt>AVaN?F`8B~fa66=L
-z{Nb4v39RYZHz?M+8~pc%a_%>GW<qlU>zlDq3g at o#-}8%fzp?Rp0e*?m7ll6CQ~>t-
-zP*%Mq*HCW)V_QNYmGQrpc-ceB*^=zf;v8iE))ES>JQDoRgqG5eO`O9^{E*NpC&9lf
-zw3L2qS8)ou{g4nVPZRqt#FTz?Z_s^ydZ?Av^mM2x{rD{OvY#GmrGQ3<n$nNYNn`x<
-zP%C at sH=(BV<13>_{q#^P`J at dsr5|51_3+a}t*jsl@&_&*_vm$^+x>LC<G`J?4kW7V
-zq-!wTzQIS5q59M#Q2zUH{x1w<2oZ)~Iiz7B;tE9b1o$=o9mo<A>|@Xq9SR9oAd)p+
-z{!M{Qp}>CX=jDGP6kLHg3cd71ztH=?zYX^Brv*wb_}DHVJw0_T_+)Jvn!AtRKWS?X
-zK7udtUVlvuK3f}xuUdQz&+6NlgAH68f4%eK86NT(fM1Jh`MMbF{<eyLrA76TM~@J{
-z3H-0eT6Ug7{U+q6asKpVXjPsdtBYFE)2Sd6`iK9pHT~T`_&WquySAz|Jw*kT&_DRK
-z<!$IG)!!wU+K=<v(ueRPps!yEK>zoD3ucd7#&!q%62!EYF2R%?Jp=Tf$QDe_8?pa=
-zT0nN9f4bolM9JCSw}2i9B58BzFQeM&Jki_DPC*mCS=+%cTI2_f)))9khqm3$!|+vb
-z`M<XZTy)JDJr-2 at KO27C%oJEy)DHi(Gpn9jP<v-zMLIXPM_|$xXjveBkPq<s^nR!E
-zcJD^tZh5=~O?x8yk2d at uZ~0BByQ0!B-}?RZkD2&vrxULst>{~k`y%w4V{hpEDRI at k
-zx_2k2y)LU-^8Z}t*K_|Ezmhjqe(`fl_W<&>Z_g(_>EEtnZGUr+pX;JqmOXH at yI)*j
-z+;j0y0mkE}Z$7WxJUs9T6F8PYHNI~&cZ&Q*n6QUN&Y1b$qL{UDYnRTS5%CYYr#sl-
-zZZvBv>Ac;)Vi?rc6cS`(BYJ+j-;nKs43k#=g5+J0e|L!P3UpVXy8_)6=&nF_1^)k4
-G;Qs)bIk at Kl
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/instantbird.ico b/im/branding/messenger/instantbird.ico
-new file mode 100644
-index 0000000000000000000000000000000000000000..51fed13f752340320417fa83145ad7896b2af839
-GIT binary patch
-literal 7262
-zcmds6O=}ZD7+z-&JvJ9buwq0J1<@dgC>A3MRs<=6f`SsMs92C7NH3Ny_<{IE6hRQw
-zf_m~2FP;P!FM1L36N0}W#~#%2c{VfYY%;Txq?>}KJb7nlciwrPci#EfCJ5Hxue3G5
-zcQKfn2!eG%5NroZz!boG*C+h(p#dxc(^AUdUxVT<VTqQy9!Lw?6o4`iDb!)(6h1xu
-zA|6)0i`wN_JiB^J+&w#)N376C1<?FW>(qkhi$E11&n95DvzI?TmEy*cH0Gv$i+ksO
-ziboe;i6=9=hS7t*$;IC1a=q44!?TS(p6~T%<8SJDeRBzZ7lHDiI?$%S7%uDS<>$NS
-z<Ns#P^cfGLL+Li#=U*O-zwV#;S at 4Yqo|y)8o8j!o$1;3zLyBj!QoO86asPZ8x6h<=
-z-^?AB)A2Vsw8$?@12qoC|LuYlGm}yro{(by+BPoj%jVh5TVK2RYb}vSL!)mE(K#uO
-zZC>WAxzi5IALA7w$2=SsT^i7?=4mU#&o897u-DF8YZ#Wl9*5`GWcck}mX4}T1Gq<-
-z{NK;F^WyZ*(ekH`x#LN!GWev{SUku4Z at Hcqh)HMf@$o;oO^Q=HkYB}Ku<iLhQp{q`
-z=y+$?@WUO~IB>o1tV<|YoZPvVn0@&8>pb$=qZ`{=Oy8Dr#+>NPXK=4u`P<g)y!dN<
-z<qg?$p1EY74=p_pz}=cVVtzUud&Vbk{#pm~$`b#i4mn_rZ+qV=TJO~#*!_))KXtg)
-zF83HLf_vG<KQ(8~xQvoN=Y-jpQ4SGL3(wfepZmYjzEd70e~y8zPu98jXM6nrSN_aV
-zJ?HYaT#NFG|C1TFFXn09-0AP^ZfBp4y{v)!FIwh><nzv0Tsa`c!S(rS;C}6jJ?g`+
-zuWj?U&OHG9n>`w^XYd^2^qHpyj_38VyD#KI55M;NN=5OHtoQYq%@r4(V;HxU<Pz62
-zmw#37h&?qWXCPR64nbq`9_8_$>^p<#VD9mZ*T*@|k at w`DdKbX8eGHgKzIQ*Zk2%0|
-z0At#H{yedzUGLgswGY$sUBLcc%kxfApMO*i6;RhZ57?d>veqNB&z#C3a at WC~^;MI*
-zE~CB#P at BCi=R?+<&VxJ7j2UNU@=Dem&AHp+e#OaOkA?X at lLu$|AaD2kijHRk+>$xl
-z&D*?I8r<Wcba0IOo*OQmTpRto$-gh|S_hsl0rvUOonPErc;3bttMh-KZobSro~byG
-zcoy^juR+J0HnrAhjy{Wa1-1oDU#nSW4ov%a`tHL=8HiU|M-BaXbKS??yuS)M7;o}U
-zt?ed<Jj(PBRDlMt(tILk=IDy^WEgGew*WA|BA^b$KohX(;yt1URDsekeVT0!;Q~j{
-zU`#g0Xrn(taEKN^n2jqNDjUGY{2^^Y*-grhciAy at 9V)w~?GHc1C4M^=t|I!wCrZBi
-xw1%IU?Qoq~^w;Dy`fn+_L<@euXu%iqATXem<V(hAjthwfW3)=YlyS&-`~^IDi|7CV
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/jar.mn b/im/branding/messenger/jar.mn
-new file mode 100644
-index 000000000..929e7c998
---- /dev/null
-+++ b/im/branding/messenger/jar.mn
-@@ -0,0 +1,14 @@
-+# This Source Code Form is subject to the terms of the Mozilla Public
-+# License, v. 2.0. If a copy of the MPL was not distributed with this
-+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-+
-+instantbird.jar:
-+% content branding %content/branding/
-+	content/branding/about-credits.png	(content/about-credits.png)
-+	content/branding/about-footer.png	(content/about-footer.png)
-+	content/branding/about.png		(content/about.png)
-+	content/branding/icon64.png		(content/icon64.png)
-+	content/branding/aboutDialog.css	(content/aboutDialog.css)
-+	content/branding/about-logo.png		(content/about-logo.png)
-+	content/branding/about-logo at 2x.png	(content/about-logo at 2x.png)
-+	content/branding/about-wordmark.png	(content/about-wordmark.png)
-diff --git a/im/branding/messenger/locales/en-US/brand.dtd b/im/branding/messenger/locales/en-US/brand.dtd
-new file mode 100644
-index 000000000..4dc69f244
---- /dev/null
-+++ b/im/branding/messenger/locales/en-US/brand.dtd
-@@ -0,0 +1,10 @@
-+<!-- This Source Code Form is subject to the terms of the Mozilla Public
-+   - License, v. 2.0. If a copy of the MPL was not distributed with this
-+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-+
-+<!-- nightly branding -->
-+
-+<!ENTITY  brandShortName        "Tor Messenger">
-+<!ENTITY  brandFullName         "Tor Messenger - Beta">
-+<!ENTITY  brandMotto            "'Cause geeks can also do magic!">
-+<!ENTITY  vendorShortName       "Tor Project">
-diff --git a/im/branding/messenger/locales/en-US/brand.properties b/im/branding/messenger/locales/en-US/brand.properties
-new file mode 100644
-index 000000000..c09000fdb
---- /dev/null
-+++ b/im/branding/messenger/locales/en-US/brand.properties
-@@ -0,0 +1,7 @@
-+# This Source Code Form is subject to the terms of the Mozilla Public
-+# License, v. 2.0. If a copy of the MPL was not distributed with this
-+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-+
-+brandShortName=Tor Messenger
-+brandFullName=Tor Messenger - Beta
-+vendorShortName=Tor Project
-diff --git a/im/branding/messenger/locales/jar.mn b/im/branding/messenger/locales/jar.mn
-new file mode 100755
-index 000000000..4fb707f30
---- /dev/null
-+++ b/im/branding/messenger/locales/jar.mn
-@@ -0,0 +1,10 @@
-+#filter substitution
-+# This Source Code Form is subject to the terms of the Mozilla Public
-+# License, v. 2.0. If a copy of the MPL was not distributed with this
-+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-+
-+
-+ at AB_CD@.jar:
-+% locale branding @AB_CD@ %locale/@AB_CD@/branding/
-+	locale/@AB_CD@/branding/brand.dtd		(%brand.dtd)
-+	locale/@AB_CD@/branding/brand.properties	(%brand.properties)
-diff --git a/im/branding/messenger/locales/moz.build b/im/branding/messenger/locales/moz.build
-new file mode 100644
-index 000000000..e59008d87
---- /dev/null
-+++ b/im/branding/messenger/locales/moz.build
-@@ -0,0 +1,8 @@
-+# vim: set filetype=python:
-+# This Source Code Form is subject to the terms of the Mozilla Public
-+# License, v. 2.0. If a copy of the MPL was not distributed with this
-+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-+
-+JAR_MANIFESTS += ['jar.mn']
-+
-+DEFINES['MOZ_DISTRIBUTION_ID_UNQUOTED'] = CONFIG['MOZ_DISTRIBUTION_ID']
-diff --git a/im/branding/messenger/moz.build b/im/branding/messenger/moz.build
-new file mode 100644
-index 000000000..bd8ad850b
---- /dev/null
-+++ b/im/branding/messenger/moz.build
-@@ -0,0 +1,8 @@
-+# vim: set filetype=python:
-+# This Source Code Form is subject to the terms of the Mozilla Public
-+# License, v. 2.0. If a copy of the MPL was not distributed with this
-+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-+
-+DIRS += ['locales']
-+
-+JAR_MANIFESTS += ['jar.mn']
-diff --git a/im/branding/messenger/mozicon128.png b/im/branding/messenger/mozicon128.png
-new file mode 100644
-index 0000000000000000000000000000000000000000..5f94a95e5048b89b1957d2d86ebf22c43ec4b899
-GIT binary patch
-literal 16878
-zcmXtA1yCH%(>>hX-QAs_!QDN$bHRhVLxAA!!QI_0aKSCOySw{$zkk(tRdZW=ceUFy
-z)6 at O7=e>(mRhB_PBt!%N04Q>@lIq}N;C~Gs7W_UaVmbysK)Z;`X~KhFzVH at 5!RH80
-zvU)B60L;;U4Pus-Xczn;fvc3RtA?YMtB2_iOMr)m2P at FQ*2Ub^$&%IahjrG45Fr3S
-z4v>=+)AY<f%kj!K(8_r1J>1ZLoi&_))$X>qJPS1mh8~Cw{3(fHp at BVwfj3PsE;z|w
-zNJYN&mwys at HyH6}8Ts!9DR&A4Ie59hqyop9iAJ+N9&Xi-8 at C_Ml@*npm96oBp4#4z
-zY!$7|?u%Q&DX&SF+*@Lb;yuTwPq<!;0u#U_aiGh~w(EJf|L at -IKW3fi5A@jr at Q0Gy
-z#9J0$l`eTdr2`)^LeXyn=K@)`Xnw=71NN{r-Ad70_zj36;-HuS9+MYAcg=ZFxvxYJ
-z8+7R6LWl;4^v6o!=w{Ic^k~>PIPZ$^7*ONaKhd!Uazjsp90AS869QL+SJuq=y&rlE
-z_h){eR#07!=;CWAzSSiq;aZj281T at Z=go_{o$f3Nvd|QNcuVJ=n+pmG7E#GWvg6e=
-z+YgDv`IVlkP+Mv91z`S|dJuoGpa!JV?f0cWet^x;ho|U)T|;piMB#H<woEg{hYdGH
-zj~?<os|P*3Uk0c!rf_O$y=%$IjV!LLtaKD7OTR$oac?<bF}ji?ysBTF^9yMT2h%_Q
-zR&?##blM>geS&oIFf=3qh~zmg`DaZGS7=qX-A)Q- at Hyt1;Scl3#F6 at qUOp~PxFB^_
-zVQxbB!)OBF>i&IZn=z1O|GL_Cg!Y^QUxfS0cz%9<&Fe6SKS$Zf?|!}ul$w at y8{_C3
-zqQKe?J;$x0jDjlkxW;@<2eGM0c0<m-O0z$O#F=TD`1Cmdk1gI7l+jn^nt=)paO`-R
-z%~K{vl$^CBe_w_<gLwdS2GKHD-jE1Q;q<9M1qHU9x2)E!o{wj6MNDMz&24VRfp$lH
-zHo%sb!N0V%9P7C4bDRJQ#MjOfZWa>U`z@|NsUbqqU4j~e8Uu&E#-NLXja+l!<IO@*
-znp4%{dCicewz0LPN|41?+QAJ+-vQKNc#?V=$uA3ySa)K3_U->**nGe6xPE;{Mn(N`
-zQeJv<kmY!DoA;TW<<J2fzwOm_i6;;?Ar7y7i0+4b`w&f8I(MLuywjDv`h*7G8Dfj7
-zuf0#Nq9V0(-9d;Htvyftr|F>_!}0NPes_0HPft(zn)=Wz<y;Wc+*BP|G_q|VU2$@~
-z(9|=<7GFih_sy4u*0QQ93n!;|S!!_!38+Tvse@(fJj?yj6!0im|5LIx&q|*G@?gcy
-z*KYN0`c6<;eolq-Z&i$rjtYzaT+)1lxzbrfLKj~OiVmy{iavAiEG#SgxwB)|Wpr7#
-zEAugF!#!GK*eP4APPcOn8z>V57noL*T!Ox%xW&-tbz0rp;QM at 2b;VU&Tpad#(HS>8
-ztA5dbNQx~r@&K<WVXgHfO&kIHB|CF0iEi`H7+dc^ZNR%Nw$!qLp58Np(i|!uA0J(b
-zcyO-(l`1 at k4!kqlbO~_fQb9q1&DPG&m07PLw4<Y=Yd|HB at 9fiw-?tzXEmi57fjI^p
-zS9}fa4Z+F(fGcl==}ne8xPYG7pe>$CCiV*K?g98fnqa7leOK=jFRz(Wh<;#c&T#u-
-zZZt5HuDP`}KxXltvX3_f?!9sbApSEc(2+6f2ap{fduV6~8yB~L9yfySRj?@e?(wnF
-z<!}<~sp;9d9|q59H-_&3$DbN=#KE}NUzml3#lUq&%D`jYO^+qM_NZeLE#OHaGc!}M
-zcQYVn>d@!mZvs{KkHqev$8K13 at odIW&rz$!ZVvmErZ`r^4$blGFG(is={Wu`ZEDTF
-z%)~;TSCYaP>1E~R+jDszccBAul9c}z7Ito*J#R+nyuc0AU4tGB9z|lMxnx=Dn<=p4
-zq@<*L8KO2GeoX~;gplG-q4>|mii!#m*I79_HEr$iiVCb8zKf5A1#MV3xVXbYWq75z
-zw*6H7X*WOdZR-y<R#xdb?u*{f4+J??b at c(T^TYr%8&_6WYg<>(VH9Wk0yZ(e!sjDU
-ze2^~TAj7ihcX at I&H#cJ;`v2j%!4#7p$(M+T-JMfL)iH2}0ee9broWXwH{p;&D^>Ac
-zKOEWK$Ll3oYleRN4;tmtBuz%Q{1PC|T&aqOk~C6REj)RsE`*(PyMYHUFR%B(ct*(B
-z{wShr1Ea{Hci{&c3k%7DYqkwEB*di1>lp)r=&dkej8$!;)dZpc(;!)*;=!XRFjLyx
-zoT>yk88u|K-%-;^K=??8b%_L7WczL}{xi+i*7lIqs4M*|Ir~Dr2Ib)2-ILQ(ppA_u
-zXi7-WcaMsUB12JG at 98<S92_!kCmj8gNCe&Yx^-4Oej_6zGtarL>+9(7nQ~p_Vts{I
-zgX$^*uAB at HORE_g3e#*WYcT;NDHG(#^uK)@Z34~>yH3TzMGW at O7AwR>UvV9so$clN
-zTx|EeUKF;rdMx!^TwILnlulT=yuSOp6<BQv-$Nr(h(N9#x_5 at S9E|rLyON%|4cn8^
-zt%#Doyu3IG<c#MCrUeB-eEar|_M9i1!yNY7^Q{d*6px74&SZBuhMSw4J>bLF+s9|Q
-z%Zuyl?C$j$yOM?iH71t!l}8?+GK?&2H2Bhm=PFK0N at _fv!(3k4NJKFVT7x39q9Qpt
-znLM=b@^Sa^l>i@~oETN5OpcI{Q2FN-SG at Y{zkiY%8XE3d>ka|4$F409^<Xp1DQmYP
-zsrtTS{JBZdfuzx;kQZUN{@9HUeZk5G|5$<^Tfm_;+fFGj3Ijhzdb!aWZLUOV3=?#C
-zJF~PT>*2wtq at -lNF=y47!@hkObnM>wS=rQdCpXCcf*C2P<Ky!hN|g$V15`>Ouu~b9
-zP%()2qv_hm7k%Z6{Ma4)xBe`kP^yxrtf!~9p%AlZr$oJVEgQegHx!gt6)*ig)`VS_
-zn-J`RG?!ik5WPqPDlfi0f>BXX3y2in*iv8CHa0dC1b({;b#Xyf;ficQ^_741@~$MK
-z7o!N{Ni~9}cg|V3>>6(9<YRBl&!?!pqBEbijQz5}D at q!7NT`q`uBC+|B{e7$$@K`1
-zxkZ(g(UO!LCtcvHdPqDu_ilckgVQyidbuW>)85tg;QH6^oFU>Gbba6R0WrGbd2#cL
-z|Im{u8Kl_(#1Qfc|EO%_kCE59gIq4WbHY{aNpNs*3R!)a{ocw6-8*U;eI73u@)l=j
-z#TioyIywlm?4NYO-~x;-_U9pAAI=LK8g4=njNv&{RaLL5zmnHUEZ#e4X~iwswK$M}
-zS;puu$1rKOfo6r1ucqsR4UJERsD^h3keaZ at 16tB)4{F_iEIcmEsp at GcXlZHnkZ~4+
-z{t7!%y5&VnM4)0s#}Jl~!PG8-zr*o)ID=r8s4Fdv`1tU*n#zqC+{SnJH8nLgf^>Cr
-zo7vciO}>$Y at 1;YB_nkYvzu-bH)Sqh_ghM4hGEL+W4H*HOK at TYc%dF_AhOP-o at tdqa
-z>nn1Zn0mw(d>z?VIqhVd9|;$fC6A_#j>-p~GDHb*c5Y4rJda&nzM3pB;Kb9^+NyHm
-zozb5 at Fd!a^4i1_wYr8!5XNzsNi>wuum2s^rAcxl8y?gIR#;Doyith?wPel8z!b5K1
-z3!Z1lCv+zfiQVxq-D@{O?Oz6Xsrh^)ax~MwsFAOHxk}$IaS73omvjX>X)jq~n;%Nm
-z8NdnW=;ETJwH0rUyK!+$rYSWw^^C)u0v#Sa*6}fuJW5y$H0q-qd0Z*-F+k|x{p=ZT
-z6pBC2SR!936WW>z3wOcuag_(o4t~TTSEgN_f%D=}A~84`X<}d4p~Q%nVzo{otf&}Z
-zR_cQ3mc5h1UpIH&e0YNxSn%vDE%%S$@OOt|dD5Y at R|T}~-T8@`b?X3~>#@L0yXA&3
-zaOi2VTMjne<BLK<L at X;S>)UqP`qAF7+S%E;-0Db1Lqqd#aS=@r#H|E|c{V^G!EHx-
-z at 6fTUa>a87rFv#bPKtc-O$3$-<TFp-_ica(+Boc2$YAf^uwtThP=7<`lF1pQrsGCL
-zpowF40=mPvKCfD6eCxtZZ!rMmxY08+Gh%LT_eC#9yI+1_MnXGwUBmX9#A`B236WZ#
-zE>xQ%mUne!|Ch3PCD`$)(czu$j%KQcMA_NDs;Hp(`T1dePev|ErW1bx at D8&3?>q71
-z(qTrHyV=j;D+SIEK>1=+)tQ?VUA01F7&}0fK#+e4{CYw=nhBMSCug>qw_Cx=%uMXY
-zL;+m_Y;ZYLHekggAtBMT6(r*nCp?BCLzv?}K06!#s6Bm22We|*SvD(CV-n!1r`EFo
-z1Ox<*j*jpjdoE#$k|_)q$@-$=vN><GT2BdBec4oF`u=>sbpaYj{z1Ki^aD)sH2RXu
-zjU)u+ub}ObtdHq}>UEhb9kQ~rjxR5#E~apd4nD^}c7wop!z7b-Vq(H>v&T=DC`XYt
-z&I@^aJrtOUw_?|#AGg1 at O=!}r3yVBNh4ht^>fK&c!rmVi=6H7{p{_7#I!FW;;CVKP
-zHjY<C5Iq$BT;E@@Z)j);h5}$fHvook46Lk^7ndg|0yW}5Tie3wYL?eus1Z<L&s6IO
-zV3~G%Uqy}B4U?p-cV;|9!RWg=sV1!NCB7=w`b at xhg-%^WqpmLsYRM0q;}S&r(J>lT
-zVA6`lF~E-eO<(_u>(O+XyQcg|0+o!aR*GJum71nzGEN&XGjwpf{H=$9f-t7R at 6{bM
-z@{h691Q|qU&8aA2m^c}7#GrYr7gc;E1S{yr4zgGxuuYHvg^zPJ^v}nSpGiBg%gZqi
-zMB~T<8x9Ii1cl|jy?HGyEzYZ!b;H|W=*cby?j3vW*u7^zx6;n_6GG=lWH>Ohw5hpy
-z9eRyx*@YRrYK!|4)qG$?svh%dXC`8~Nn+I7YOQrWFanVXnIQrHjdjBmw66ahI9hFA
-zd)6)6{n@?lWlVW95?j1?#Kpz^=mF<j^$N~H2;76^QZuF0WZe(}sswQpa<$ebmyU6B
-z)k)Ui4oI8al`SHZWw=YJrw3y&-jhm at -Fr}_ceUpy&UNBur)q-ndhm*ehsFrk|7idD
-zNOyf=<!wifR$~mvWth-<CfZ;?9&9V<?0khv`l2mI6!2U?%@vz_y*3m=q9z}0U{0ob
-z7CyxSdA}so6EIjW775yI4Hu^Xg~CDJ{)M*R6UT(3#-uY3#p8Q4{o`g}B=}1vm_V$p
-zz&SDQgO3;wKit{W*m%>X(*YWrJl!MiYl+_nB$L+weU;$AT2K>%u0H!mjEF9Z&J+wt
-z5b51#v!JMmTJZ2Ie9+=4iAVC4VIXddv?FSm_^zgsLU&v>Ej349m{g!?iGc>%ez!9t
-zDieDtd>1dhvxE%yWeR}5d1V&1*B9v_?sDS2GPne|d>uMEDj$k&lL?-mv(?tiHgDEa
-zNW(?Z+09K+vL*Hf4#Zsy0H?p&=3f&1*arCDT!`0A)nBOKYY=3Ocf$3RgQ81AZa#k+
-z#tZ()7!iR?g{o?4aj%-&Kv^o7IYQZ8hQz|?`vH)Pa*2yBsq>IV(Cgg#+QDlJd624`
-zw=0I>w9Vb-M!?JfcP^Zl%PEqrOlMT<F`h6Ajy5VPDn^(2bH_z3Ef0n{v8hOgi)^Xt
-z2XQ@?W{}9_KTG1qP-pCgM-??t3BpO#Y~*|p*9ga1C#|(&rDMoM8qpmDp+p3*<kzwC
-zZXF7L{|<yf!e#fkFi;jarY=#+3SSj|5#!oLcm^Y4adY!s4!GVfELnyzA8+qT at Cxv%
-zW`ki$Ir9Ab)_~ZD>hwEJjYIv_hr%2kHix~@<_9(4YGr%P`)L7qm6Eh+{4Kw!iJOUE
-zON)V#(QKp3D>*gQtZ}*Fm3EZZtaWvhtB^fGwhB@@4rERc1UGUBJNfkoc9~28c^Qzb
-zsFAIoKE+IaX&#0yMQ?z~MIZOGMp;&g(<23)z49+3!yx5+59!jPy%!dpPtI<n?{%2T
-z5Fa>`&aJMFeZ0TQ(0CCeNU4?8)Ex8$LDB7SKvdS&n9ZLk?qda-;amH3c1#+7x8&8B
-zjj&&%w^SS)W&c8&sH;~Q@^vWJK at HOU&)R8SDG}kE(${<_+?4(Y<)2C%Bymb4lu&^V
-z;x24w=k>A}7a>bUpsrYw?(S~A?Sq!<3_u$A>5&)}lrA|UY;9sPp4 at FNKJ>jX=h%!6
-zD+0}3N(}3_Ec&h#o!l`c;rsm0>O;Vk?N|J<dBNOSVMyo%dQ`22I2U3=jxl;WStjB%
-z*k}b)4?Nf2kRV>ApkuL0i|M?;!jNgwu!nxv$Zx_}xBM{&Elo|Ty1M)hC}d0=TC5M3
-zo1zDy*g-V9*2>r430WbEhE1R0^N}d(mbuSRQ99Qdd9$L{OJ>%Ezp6~t1^x@`yCrNL
-z!>$~{AP-oo2_yYI6&g4tEtW8bd8f-S1dtmfMAZ(Z>GGmU4b1eeUhx&$^3b(>f!9d|
-zipwB- at 8HV8CQj#t21&kf0qx_c`_rM-IyyV)X!a7~)eGPwX{ousGpUO2yS6+|uP%g3
-zj8X(4K~VXiA8+3jG*F6jeJ{^3k|@iMQk9^g*@qym2%ac0(SUJBu_Lq*4^9w25tx-N
-z?k!zvGbIB*>^lM~Gn6*JQy at P-XA$H90C2F0nhNM#kPAq}wMrs{&9c+FLKf30UgTS$
-ztv=P?ybFHQFLaO6rq8k!&)d-;pXw!*+-DG8_s(GzH#HIQuqZ0Yo_12Iam*xRta81E
-zO73x|t-lM1F3%3imX^=$7g<TOG&d5K<!Gs#k9&VFjVLRx9XPMIhG9S<DKCY|+Tgu2
-zgp-gVgq{7@|1TkYGH=mtyQVYu>!Q;4?+WQ$qJJ_)yCJCHodC9$k=N6kxEPGGXBAqV
-z9(zbwBVvw_EyT^=d%4yT>MN&pp>rHOJ3-$4mpGw-v<b%DeurocUH))BM`RSr+cWqV
-z9#tIn at b8mhiw2{7ABU^_>t9G$tNOSgdE-kUq`%dbh}^BS_pvuXg2vIs4qMSa!#>|P
-zMX6}UzgHcMo=z2<JLw#-#wdi<S+2YvTpI_4k>t##JnKoZ(&tIe{<1-AY0^L8#T#Pf
-zFNQop>U$75zKIFrC`^m(pLFVo_*^O_^~_db?Mh$#e9LU6V3Jj+<76>FR=Ap-u0B7Q
-z76Bq77?(6geN4sW?riw5Z0EU-BG){xeSt<?^EFX3JXqj03BTuV9pl})@<hvJ53M$j
-z4=()T{-+7RPdC%7L|AuUHqX2#j*-e`1B3~EyWFHO*T^)dwH}S|Z59oQG8?-*K*7G6
-zsr5ySSRL9fVK)}|)Ofp{Z=GIWfG9CV;3?(R-;6oyp+JeRxd)0LjX<~hy|%txc$@<G
-zch_Ki&rWc#Uktbx($w`Z$U$UU2?`)*>onItS6RO=E{W7vE9zi_X?N%NisrFAD+j-O
-zxa2cv?@cqLsGj?L@(2CkU}tAvoA>$E{p)yN+Xw6Tcz0auu<@n;lI!!X7$9^zP4 at iM
-z745atBQtwqOjdDx++ujZ4aKPdAB|n#Prv!}YJBx}yNWJ;wH?Q@`-YaM*mr2=ZirAp
-zS+}ei+;10GBJ`-`*q1qzg+~&yQ0F{a_wvHY;+p4Iwkb+*_s3KtYhDBY8Pz^&-p at cA
-zc>np170%V=!;WlDPczOxKvw$z^)Cgv`$wl~gT=F%$YZzu^SFI0Iz5Zo at 7BCkhZj~p
-z|0ATc&E|mFbALx`HskK&055Y5tjv-hL#5gcZ+FsBNbBRsIE8zfuQxYU8tf5()-itV
-zkJqjvCFFKYpPlJMb1aygR5gCR^x2!6?q!iZk;yPhW|f at +^)VKM<3_vEN5XpDUmram
-z2w_5`kRmuV at 8+2;m&H|8=}EW~JL3wIJ7oS3j at k7m2G~-jr!V#f9tS9Imn4q~KczwT
-zkNT)?PIEDzgB!vu{D$r#_hGl`y=}P-ztfKArG60y|5X7X1rVI}zhYtUd3U1T^_#?c
-z)Q&^ldv#BkQzbSb|0&scd%w29T(AoP0;}1n;CmkVd)RY->Nh6L*>e58Gd_5gM2GbC
-zw~dvYdk{7uw23m2mcUU^&YZw8{-8GQJ|rv4Fbb(TeY=V1-Cnuv86WQL%4l8R>|`3p
-z6aA!$B|aW7-Z}_pGnO6vg;*i~_D|<vsyST&aBuvvZyf%RearSP^jUk0&*AhtOMLxD
-za#+;FzEVlzF`4Zbtx;hM0_`n;;X&>Et|>Xt>kfLMFCIM=>TEMFtl3e2m58bOpkx54
-z|IWmK+ihIwS}+)xNxg%h2*f1$RZupX+>lLj!F_xpXXdfezSp797 at jMEm5lSu0PmU6
-z?Muqq8gj5cap(GQeYP90ebvu<z?L08mQRV2!)LTPRL%F99Q1)-YzgE0pn#|T&FHIy
-zR{ZEry>QyL6J2d at 58BqbFYlW%{x?^2fJDI&t-D(&DXHSO3SV#38A3!BD(9}hzkOx#
-zQ)%HJ^~L?|gwK at XBt+^7DiBS90<QDcP{sg4MCLeSYwQ<H(A2vi0e*=XH=&f)JO>D3
-zSllquWXj)WrN{B_z*LzBP+bd`{HRf5OCaKzZffWH_2bV&Oy|>W-oo{Zam)2{7Hj{p
-zYWurjue1umzlF3P6Ni&Shc294nu<Xl1>By?cq!vDfl9g>e;RTTBnt4=zqbg9p|D_#
-zZ5pT0W&^BXSUeo3IG#R|Xoa2#yK=bTBq2q;VC3Ia`M8zPm4XoCw2%?HosXg<JkHjg
-z*%_h|Cnz~_lCi(7P|osw^=S*6z1ec2i!I-s#y;TIRNwJX*Ste$sal`JLaWMet<3A}
-zc|ARAwwkKk9#zQ!<5v at RdjyBWKNkNYe6L4lFuM(DgBD%*2-N9IB1?Y0rRr*2UJ=&9
-zr|S#VGx3t~o{?hqfJFBKR8FqQY=3+Ff+nh{%huq6x(Z^{HE at 8b$d%19?V``W-f~6G
-znOpI-Nk7%j9IpHDPuLtPSf0=Jnl$TqaLh9sYNyLDdR<pYo!C2>%2f*59O?pECSi&M
-z)>zxhd}rpHG!9J32vCe<r_NM`Hv5ITx#2K2p}$r4FPf5BY3m>PnrJ&=gPZ6XzfF#@
-zs5RlCkq3e3$FO0WAL*z>%GqXp++}T0zzh2l$oVTmh6Amg>S=3}n2NzPNks0_9&8|O
-z$XXz}$?UpBg#A&r&F9xxv`zerYXy%_Y=-h$WYwK!HKz%ATo!wi&x=7{Crhd at 5jw8#
-zQEH{=CP4gMARutnlBw>?Z7qWua%3uk7w+g0WtfRh8hHhp<t?tbst$QN4zv{Vrbxrt
-z7v!vmZ*1jNCBbAOw=TZ at 6#93YpI7FPG-9Z3{g1ggXO|j3i-voxO8B|O+81whxSzI<
-zmFiB}|7bi1j9DNdPZ_Z$*XN00j85M!MHu<GnmGNPa@>1(j8S{{i_ at _5mtYuE$sInn
-zo+xHMveYiKkROQHR_gPNT?5sZ`~rq6!ez)-k%_?0p&$qfz#u71m|lNck~-Pcb?Wbt
-zAUb?c=xQ14un|+E_<TNNqpvLgsuZDGj48)>TKT*|^*Mq!^^UDn&G69#lRB>I^gR(X
-z4afd$fwpEvA5Balt*97j;XFAR2k~SS#?2CPvkl{}FhPeXmMVJu8a3-L>X<ZD0>|5%
-zw~=TsH_9j!Ym{G#4d{q?L at tdh92U@K=nlySMGwhPRXnDq<+k=MAu*U_oe at Do_r2Yf
-z!F6B&Gg5)bh-*WD+{-ySGI{Hvqy2CsPmOPt^HFQUOpP%^yabc^t<P8c^C%BusY|7y
-z7Y8$ZVEgAlmJCjdYZ)<trfmA)WsZK!p~aVY%oT6yQ;!Uxx5R#PTcwtZv^!9GGVHY5
-z`gh3Lt}*>r(9_)P#|1dsIy_D!_<vA%I1bB7j+*24NCnz~A(d-NX^@x(Vm>@F1C4v9
-zpLhz<B8;P3xwZ>nd8eg6SRE^GeWk%YV&uh;7PD^I-uH6m)9Qi&sbO~H{2N_ih^+8X
-zm`?T-k8wL;U|I`->jO&nQyDA&Qtg#==V%LRO2|86w{sA~+=w!D*E+9(0<-X|=BR}B
-zO~s_hNVqU<uh+;{y$*^yS>n;~QZE;7v|hQjPe&wZ=NTr~#rI;Yt~lbWdBPDq3j6F-
-zE!rF`@hW2dAp0^cz#&adJGwOJ6eq}3e$J|Om5zrqmDAKGZS*WKfd{#t6Wba){cUS1
-zQCOx5uDq;rrzIl52EjPfBvW?o>j=;mGbCiGi?s;ow96+t*53{1xqrOqX_eGpfkQ}o
-z=(H|aHu#&>hM<YDS0?FB23(YgEP$`D=0V?>|6>vm3VN(Iy&bE)-GfrO+PTc562LDm
-zRGF=xFj-d)$<RV{`K}d(BwZyGMNJq}KrinO%yRvf(}n)Cio<5iCh+f8+xf at zQ;!sU
-zpr_E#Orf7-Awt0n^^8rhF0&kS>bOJW2iZ&R7g|E4>GhnPb5RHg=B{kc=bshuhVqf?
-zR(Y<yi^+AJGUnd-V)a}(yS0WlqEke!MY~iwM&7KSuA3xJh+W!OAwaA74OvLfY{pq`
-zjM=Tc&)duP>qPC1jrKfi-XjC=OcHxy>$TskOTN?IK`v=52UWJBqXBDADrakLF+6CZ
-zBhP7hQ*x!OJC~O)glzBIFu5Q18g{;3SPX^@yT3<bLuhHjf``AQ5NI*BWb+-m@;83?
-znW(!5S~Zd`%mM~i{isrQY;57GBUXS2WX1ckaMdy$HumTF#l;aD^)CY&p!D at ViZ#}l
-z7#;70GD`PqZWf}i7^6jSlGJszI#k<Sy1fdAXjwER&=V!s#h2@&DaJjxMM3|PwAu4A
-zE>JUQqwqUqemJ4)Z8bb7K&46SPUgLXgV1*E+|2UWt>Z~{??2v)G7IV5?0})6aif->
-z!~4<8?H5WPuUVp7<IyT0D-CCUyX at W*yUETwWP!M*+i|LZgX2wMP*At2fHw`><4M(e
-zK3Ao*CAe7HOD9Yn#Pk1L01z(zCC#s|;ec0n(ye?lQR%UM?by&&;Fo`5KDIgz#(v`I
-z;wFfdbi50Xp*2`4#nYPiU;B=I`*LONwB7s$i>w&e?!L|F=h^ZTmp2oInGjfGS%Qco
-z(;g6Wy#~FpaNM-kKCXnhbGh+=)N?!=ibxxEO at Z91e^h<aqNL`i>(`2Bx#?M0wjMs8
-z1&n)MjF&eP&2}C7;STmZ!d)M;kR=sE(X+jlpO*|!MO at z*-D`Z3S|sd+?h4`BFPL<!
-zo6$<d)PNK^>z)L8UE7!scB^AtaXo)s0=#2#Yy4Zt*q4^=*c-oDjxb+&YG_kd`QDqQ
-zSM~{zn{PRI`N8QMP4&WK>kiCo at i=l|!+epmU)$VN5lR`z2g1#pT;XipJMj}|oN40h
-zKKjh(7z+%QP2NE(ntvbu+k_aC2$>TrlGLtnz+pXOr|^6BZ^gUf#MHl=HC+!Ta?Xqv
-zjPTeT!P->)-dlp6TeQapV4U)FEoY;*tA5>Kyjyh`nSr>RB?3OI3oak$XA at 1={Rz=p
-zz$4q!RSFp;`ju5=y1vz9x#huUduH$J3&`tzzxr*vm960+#r{mhqVBLRs8_PEV?)~B
-z4bTd!Jl{uwoGsr`CM_V#Ej&hF4S^0hwB0w&T at W5r1H}I#&I`Kcwz3-?A=fbFQL+VP
-z!kYB$%?*{h-`fcCHILp-GQ at -HOd>{I-aQdGPAk5GaovQ6?J{}$1(mF3&tJwGn!So}
-zzh>gU#MhUb1?Gy6CV(=tT|O{TFFNC218%UV9F<kKoYhE)y`9wuCS4Dj8nq4MX;jNP
-zl96gUL(gmNt(;8a^ER$Edi-D08tiXWA8n618BLy}yqG_?>^3&s;^8iQ!gY+6<Tq#F
-z{bZ=lY!{q)xPQl{%a9l2u$*Zk6GsJM$g8SaN;nHtBecMw?kUmvbPbSmLW8T1GIb5T
-z_!{m0@^eigy_@!loYl`)pq($340C0*b^IQS6CUVsl2zZT>8j~<g)>+eJg7=r^AW!c
-z*DtiF1YAHWi`r6zL#Wimap9AlkdhvAN77aO+O+n&%dYzRZiLr(IAt<(yfEHIckxLD
-z_sDz5Ej1|W63vZVqQrKnzuBH?EaZuFXzYYpQ4w$FSQ at Y{0Nd)&PmKRn4I6uikd-$~
-zUUTJ`!+<(F%!U*#s$zC=QHC=^QfnSdos+=};>_L0_S=&NRp8+E(&j>*g<%BUDi(k0
-zj}=I`sKC?^mNk#Vsc?if%!6qUt_T1k>@5E2683;>{YzFFm#sF=Oxs?ZtvP;)RB+CO
-z_IX~b9Y%2q%^>tQ4Xpt$9mAih*vRW!GMgXHM%!^R;U_2Lt^T{}q`q4UzI%yD^~;)=
-z=Q78Jt+5|`8+}KoV~OM%oPSiYVFuZi)33C&CX|ZvT=|Jfbn^oalHs at 9JJFCRcBV-G
-z at n`<9h7&LO7WKw>TdIe_f%d-W$Y0k8)SRGYv7zFT1faOse6r6L&Hj<yncfoI>`vUF
-zBqQmjopO+6M^8EvwhLp;=|1VIT4bS;&08HA|8mc)2LuK!e!L05ZKA3~K~s&WY8(C4
-z>G8(s^**ZfecK&#7O<xl6gbjrjom;Yn)dMyABOz_&wlf{Ysh(Gtd`75j!HeSU6;)b
-zF|h3fDa#Nw`)^USFX`M8e!^}1o5`{PoqN_-mE$$H(*TnaOs_0J2G{<#Aw?wrwkwy`
-zd^!eH at 2A#)PRLG)-E%62+;4b|YvUqlc!qv*Mi2{{I4%b=I#!qWe?q2^y>_J0t*Xx3
-z=^1Zs!q~DwU^<0XO^-JWX<UefHQoB@!c3#TaCuFQ>40d$iLuta-Gc_0Wl?M!;GTM-
-zY4 at wG1gKA$051cl#7lh=mjNIx9cXCR{x_P6BItF}Iu)}3>5V8{ihzzk7%EEbdAejk
-zF`lh8!q;=H78=;%VEbyxXAs-lm(+^uW9V)*VQ=#Cb_@`@KZ>R{zs`T~r$k|gMMPXP
-z2zb{Mdb^r1aGOUA4Ybg~TR&Z#`&<Asl=xkb&_^t8Lca(8az1wAcQ*$H+T9In!lS$K
-z6BAJ-z+Zc2LwPg6sneLFx+~s!+$hpnid8b*8G8tQHMV|acVoS$mac(CA3h><EE>Lx
-zsTC?r2#c<Y9Cwe%QSpC1skdzgs_NmI426|KvQOh}50x(N^L<Do24ok_st;u8XFksa
-z2oGM8`S>m6m#iuo8<Ul5o`fPAFWxKOARb?Pw)|(0hdCp(?2~Vgz53|W))x7QMPl_2
-zUcZ<6WymPXwk>S7D9HD2jE~bA<G5MK5)sKjyj;H!VZqGE;s_NwLTou|*Gx3su~7rx
-z^J452=waL<)2&B--5)Ey!NuBvyXL+A4&xUlEx)djBT(I(H~rY0_ER3On)Urh8mH_i
-zaFr78m&+K})n}KNy#`i470-3F?#oJmIYst?<BiHR)^eI^$q-sv9*++Xtn$>DZR-$5
-z7kR at pLEWI_>q_pj`l^|sm2-|<FEbXhjw=gX=87qAD3{KlR=>m6z<m{ZhHEUu6m&!!
-ztO^!dO$|kRdxW4qRpb?}sV+H3M{F&P_Jadk(B*8gXr(-op8th<?%O<}yPa27iLfbQ
-zNlKjd`>@TtC_DOY7+wpQgQ4wyPDtp|vdnWZUTNAdhhq1wH*S4((9_nI!>|T{tAq?q
-zvM{v;Oe1-%hbE(-W0@{OKu3)z%vYuV-nh)`=H|u{B}ob1(Kdau)m>d5i7Lo7_wL)j
-z6*?16E^3_GdTkXRSGoLT%!HifW?*`B*@#dnIkh3nk$JUoJeP|Ly?42 at 5zXS|LFr6g
-zJZ+Ly)A+OE<^#e1xQnN%rjd(UODGY4tgg9r(BzVObtq#*ogsT2vDrPY^RaF2r4?Yk
-z2v}_;GXp(H*lm&?oVTtv?4Ctcu-hu*+~O{Bd5E#NN5u48K#;CD!v_Wf=cdi;8Cc8%
-znEw_X!htigVEwP&i!~m+lFVlMoqKO%@XlgePi3XTNL5p_agLb19Z~Z|`Qgo?W}8!c
-z9$fDEwuy@%n&=gzj$!ivrflEfs7u6Q{lzIkQFnD(?1PcO>g$osWij}qUp8BodU7%+
-zV!3 at T^N=xgt3$tLjOotT0)4iqrzLc#baMY5ueI)AWbye;3C~o+^mAj-Zqq&Rd^K~q
-zXBYk4evr!$5rWG~d$z4C)+_q-$}^ijihRpO&EV+3ddi_c8B>Uq^4JYQ+4ZDt{D*f`
-zfn>MQr91Pkqwc^|IVSmus{k4>v!$}K($*m$Kom at -z{bYCSxaE7`9b=pT-iPz{&#_{
-z`LP`yk^7M6)d$`e+kIk2M#%9B7HK|3vq<dvP-W)ag6YGerhh7wJiaiq;QkcacN5#6
-z?mw6EVnzPZbDkmiH&sERf8- at H7Hp)Q-5R=Ryf(09lFerH3H9w;N2HWY(yH+mt)`BA
-zS$^_!^a+D3pO{f=PNF!P6pRD6R(>VZfQxO*H at cK$3%pv9T<B?Tl-5-+D}g*i5uDl5
-zl;n27fd!G`1<XZc54hDtU<V-c6UU}`dwU-|JUpm_DN*Q<I(3QGt8nd2Cr2Fbfpd61
-z%bS at 6jXH;uf_YmPowZV0INVzOhwfW0Xn73Z(-S?z at guQ0dZTwJ9lg8BDmPyr^nIS!
-zyL-0>m{|MH8<e7;5fh(XY%_RE!%GY!Y`i;h09i^@nmXcIW$6{F96W9`*s$RP3naWL
-ziGdLXkZ7!+tHqb2!c(~t<hoTgdHL`XbrQHGJKi_{0Qc^}@qusQrWQ%+?dumYx&xP{
-zf1-BG*@(Zuisw&r8!qCtG&jF at w6rYr*vu5zK^8mlj}ySifHyzx?Q{Xc at 35i)6<LzA
-zd*)>N!<+Bx&l)|$;V4RPHy>$B%`WuoLA8Bj5w#uhaRDzo*>d>9b?8<3Wkfli%#)4*
-zkBE*nn^H=K4D<PBqfCf at a|rf-EM55!d#<~8v4ZIHt=ak0x3Kb_AZBbJi(7DMrUsTZ
-z!sd?u?Elzy;-BWW*9 at PXoK()t%KGAYMP5<ypsB6xPqc(!2OlvwxKd+2Vz5*STv1b+
-z<MjY9{L_nz;mg*ASVnsKt>PMLtqW?J2L@&IKl1rMMu0FvH{xh<LJhggjg|bTRbCn$
-z!wjX0yU7|Q&U;RLwhMOqk)n1*y=(&#pYQslJ&zdL{x)Cop6;Z^4Y~akmA0m#$5JOO
-zUaEc+nf^w|z-gMY2c5br3ShrR((z)((4zAaeUl1H={q9%U027RRmVu>NfD0Q{R^~9
-zoit*1pbjS9;%awp%EZF4hnQ0W*thPz$xe at t^%j<w<-EMUkjBB4&P8f+=i1cnj8+VK
-zHkW(2ScPX->F({Out2T3Es~X0GnsxHOfPo;Nou*FPt?qAI`Vko454<ss&`%O+5XqK
-zS+ghi7jvfw4zoiU$JMCI7_YZI$~{RKSzqh-+f-=XNc~)e0pGQ7POuNrV?)6-R&8GV
-z+z|H0VP|U0{Qpspg3!euU*7}z6ZK?zXe>(BpaG%c`RMGO)z#;(q;b|8J44asm6e5+
-zl}w!#){(;fbQP%PcpAMu(EhK!e6OfO<z?_rm)&`ThgmiQ=9ABuAGe};2iG7z^1x^n
-zHp`(M@{#0`ET0!IOBX&8;nZ+O1|+9t9H!^1;<0OQ;$Odp$TFhQwyw5WFWPpmt0cyL
-zIP5F>%Q>E&9hE+tM7SA{v;TWITmhKb1V>WS-L|2_Yr$wu_~XKc;6`fV%v(v=5Jr^*
-zRTS6|hScLH^o#M at uSkMfgZn@1Sy@>>80v@=-s2Eyg|s2D0gY4%f2D+lg+IA{9_$V#
-za|9X9-E(Z?6-Hx;HB==ifj4ua?$hhFjjqSs4!ye-rh2Ty;_`e?8zgbJ14yfC*!^^q
-zm0Lx6gIJAnCW}GvwRRT;$94Pk&h2N}9^2|757!#yHHgSVdx!l!e$~F<VGs#7zGwZa
-zHm!sOHLcl<b);5whFP*4ZV4|<EvfnReyUz0NDKMjXcP3EEi5ctcCKF#MB}oI3MzT$
-zwx%^k-_+g-V+i<Yyxql-P;1cUz3l;g9~!OWeBN?}S- at 0iEMk5q>`tZaOr**T4N>=C
-znaI7rGyH6h7iOm$5Q=k%gnBK$xQm93!5NJ=Z0_A2DoA|(+jN61IRX1a%wJsE_xrgO
-z6$ktNY2bInmg{G9BCj*fvd?a^e1 at 3frvt~<S4xs(sUu}}sSBKU>Y?jxvOR^wC{vq0
-z;%H?5B(*0Al|*In$$L!+${DXi-FbFz$oTm9^v*0SNCSc3fmwubmkz;RaZ7#byfL;U
-z#)h*qXrSz)VspKomZ;^l)uv(69w%@!pv=FGHtza+>EDVvmkj;JE8=byU!ndJS^COT
-z$g9vDCisLCPsdPo!mCu$%gq)o%N?c8;oM=NdVQk7lI!W88<Px1|9Cm~P>Q8%OVjP)
-zrpQFFM%vXin~{C97^k_)UZe+i#AV|SrOd??O3GM36*tPAMdFi5w(dBk0yANwEM^>5
-z98DxhgBp{;$k!P}KgB?tg^@1CH+_8jY(z#(>|0q}Y}r$Ds+cF at _ixN-(>PXzD}6uX
-z1v1!$XsyYu*wf8c)Wi4ESv()}yKO`ww4D#rxS at w|f5KquTw#4bsMs31zTB$i3mBr<
-zWb#I3>%r4A{BRi|KvmAUv|QJRvRfiBeSh(*GVXQ6#u(35#5R7p4A?Ji-5ALier-Qh
-z_>{lBXnkJkt(C?wBi_zh{(G4Jd#OIuk#hgYoa>cGYU_IGx=qs}AE_wdAN at X-ik-zR
-z(d+H!okxST13fk)j1?_rqz0I?<iN(jP!9(QK}aZFD^3^K7$TFtpZj7aralm&LRNe%
-zn|*RZdC~m{8;bt6M>lo-2a6~H6I;q at 11>nbzUZf<nX46I)<i1G>LmX6g`o(tQleBc
-za!fwm&gwj+PFT63MkR}%@v|sBcg3%Or+#BnT8x<M=zxxhbs}cR%?1~h{Z6!vn8iav
-z-We$?X>_`>{q~^xXGp7CV3H~5;O||}tI<|JT=hQ{B$Wy}Qk8npO~P82+NjS40|d4S
-zEju{+oVtJkzZnA!lTOW_V`BSeq^+txQ>*q8<zU^ly$z85G0C)E-S5<g2cwl$mKb#d
-zo83Ytg))X_edk9nIx`#kC~?k=Kj%N<vgSa^wDr2kbL<4ah`L&;^I`<4sOLr!4kxRv
-zK&WFgO(m}=?w1=XoC$l|f)|!^jSFKnSz4g=xHq`@W*muul;NdjU&X{<Yk3m%8FBCn
-zaeT;0mjRz~Lbv0%0A>9zX=r|T*rYGZNM}p#=(EtCGDeY3{B~y5O#cXwVabxz-SNZw
-zAI?{AV_lG>wu^hveRhKwKxl1-j5 at jcQA${LtM2g+4<gy_VMwWP&pRN-a)#y|WSHkE
-zKGzUU&XjdgyM>dV;Myhc!OZC_|0k4KkGB*KnSpNLdWl6C+Sa3wUY!Z9Lu*K-c0g`p
-zZ3lkff$)Uy!7p2{Tehrl&9*P!!mNA8nzr`;T2aMa6`LBmSYRc&!4^M(0^Z!TpU67)
-zELgkFplmA4+}vEQVr8hnkD+u<n(#9_kFR8q7Ct_LU`FO&qTl4$VQH_n%S33(8PF*-
-zsH}QwztHO}V&iI!^d{i&uz#12Cf8s^4^3-ySW^9(#x1vq@)S~LOd)iSovL>3Zy at J0
-z)|==G-)?tYQx-%zPzIg<aGJR%GoRO~5u-=+Tle!lo at KiQy?(NXi=|V&IcxcfWSR2k
-zbM`ZIcdI$H at 2A-<UGY{_I6d=}HtuA at EOCbozo?&4(W;WxO4+RhLe?&JvL?um$4D0*
-zo~<-TgNY=;{ci-+#sp<B6zTh;y*~$Zb-BkB42zS*HwAs}BsmidKMm%Z&MffO|6Us%
-zI175NGb$XuEcJ+<YjC*QcC?mo_Bs=GK6XvOv5ABP2gboUd at __vCa(6}2xod+9$xl5
-z>p>F)6>GJP>x{`PoEaqk!v0XTP`9;3`*b=DA^x%!GY8xqRmmIq^<|#_oUrj!-sxbZ
-z(#2qyYL2wT{WlLj^2dTzBTrVz$Z!nNj2jqzTzxN!J+E(Iuni9UTpE}jW(+q4Q~B5x
-z&DBANoDzf*+8q_L2jf+RMP-5QV+Xfkt3AI!j=<=Mk3)|&?{!hE806Twb0UhhJGa|a
-z<iW6BM`I?w^*gRuVlZIxaCuk4V>egkAx+C^N3qn~jyppkoBA2*KC2|ArZzK$Ek*E4
-zy3lT=iNSAIh)o^dh^*>hK1kI&|E4##*Yr!_zEeItkh8ld at gxfKyY-^;T#hk~t`&>#
-z-HJ=?ZJ0u at vX0N<(z*yxdD7}H#s`t(*<mH$XK-$=nEV)G+cp!PItgQb-)T{O4|i5H
-zIaw?bxY$vL+61WP&9XNZ6YH-9EU&DLrn2Y{qZq7ZF<UBqDyo<55?WtoB|?o^3VjQU
-zV2lQqF_kt|gtBcu(^Qn|jj{H0S7!9SE`47aupbO#x^;WKSwjACq#G#uagCx~`+-w$
-zli2a1F7mpM#K3s1VQ^&Setrb4PUXi9;-O_AMty{;?!y3k&BEcWFwFG7e}BO607N5J
-zsn(bGLPWrw1Jdfw`$_4d#~zzvq^;SPO)&oiCF1Zl88iOPj-}P}$%M$bZ6}X^$<;<S
-z-P|2XW(oQD6AK|n at WL~j>}^Zss6%eIi?HUk^Y;41Kok4<hBh*M#%jVDO&%#?uo{Tj
-z^dHr*|J=P7whl~`1S>y={p$TnqD4`;e`r2-AAa|5PzubL2Rv8bLDpt at aY=Xzqt^7^
-z6Q<S(Aq2*@I5>2ite!3Vo4h#~lR9oEP_3`s4dpe^l32C)4iVS9jW6>P^NR0>{nJ(y
-zv3-n;k{1eXh8#%%v&=UIawhEoS-kd?#HewV2#HI2SQ&#o79&2jCv@}B_*mbL9ZF-K
-z8^t|^P(}QAW%v&p<{*yFNw=8tdP1rl&j=i_{!&0W72O`r>v*{A#)y^x0|ebWhxZq=
-zCnH3Ah?O+bjSRUR5^YS9aXiK0!4K_8y3qW{q0!ON0l?PPtfJ&9!_L%hpT}4Q$nvtP
-zXqDZRBSm#$<LFOMY+*j8W^NGszi^~~rW)yjg^0b2BVLu0TMegdlJvp-vcGBrKH%&;
-z at 2fcsh88|cYHoMQL_w`R_e8L8SjjrjZP%&MdQGkZyh^6vo#vr14P)Qu&>@=A^Ps^#
-zQ;I+NiHV7M%jXZR#mRPSZ3)%-t;+nBG<MjxrTs9j_#cl3N9{Bjilu{E*i4(7_>8_q
-z)+$)R!{LZgh{C=m`{Fh4ql{<nM3ItF^L(3Q3RCuzt6WFNCx at rTy?GI2{wNHlBXA`y
-zyDWGbMg)IOTet$epQ$-R_5acX65NAwru*)k_}8SqA<;)Q^j1}!(Xpo43ih?wul^_6
-z>wD73a=JcT@@=7&ShyLwgo7*sK?{lSQQEen6}ODQi{!b$0XeBO<t>2_F1QOWgVkxf
-z_wCbeA&#HBY+g5!_k*Fme)?Q_pKG5DmI_>8e#$ZqnZ>+Tskz5e8T}1MYmZ&Bhog|i
-z86KCg at L4F^A57GU)w<MD6eu|Gv|K)V3Y|iL^AjkO$Mz>^celqW)WoMDoTuJPa(pBr
-zJcs^I5)cyG6I3?~a=s{vLrKA#Rn?L#>-k00>-<HE1}42^??RAt+XJl^vSg&NSAT2*
-zyz(b&Amrtdo(3lHoNvk-RdM>qRXLh*!n|1CuhF9|L)>1spW1^#QvAdYN^!)H=*X}E
-zwH4osdV4>sz;dJgNV;4TuntXA`yj4w<hMTVm8&lY(m7lP&{jf`Q)~TNnz9<g*Z)$G
-zaE=Ydvo6vs6nGUDpgY9oe at BN(CNvuGdBpJXc9wOvYCR#R>#7b#*5mtywG}FDaCltx
-zI^FaL%hZWoP;&$BG8pzRSiC~k4`x~t*s#*mdp5MSJ(+50!4=NXtBAgHJN7&u{DH+M
-zbfhl5*0kd|m)`c7MfpX?yyNwLp{DI^6rvhyN}NdxQJXaUf{BP^u;z3dks-_mty^QL
-zrS<d|lzM%As=f0=ke=a=J-~aJ1BtB43lVU${trL^W=glH(p#8JD9g1Qu+BNOdVoa{
-ze%uMNp&OpNC}7o&ZoL^y(AN)`I8OY&vFH&P%}T>;i_JKhu8`u9(w~x}fWFhm1B{QW
-znzf at Ut6}=A{@o at Hk8cE>kF7r at P^@pC25YY$E~tEOUK-0PSj5zz-Ebh}p+I$zAb1Pz
-zzy~9A0J!HKMRM_w>J=5kVA<R&7|TzQ;^XTstgKWB-Tb9u{?_!9Mj=(PjZ}rHSSX3v
-zD%Cw*n&sCp2b`QTVWcZt-=WJPK{mm93Xw|_8_3GZCb<2+_zWmADpM;IBPkR%2pj}1
-zrV}vc-hC&>qQD%PboO<G2Y^FDr$oMLA~!;yBv=dbZ~q6+<K10$mVB{1uj9sekKgNm
-z9lyW7-!+<&v`kY|Xw;h&IwyCNf30IK1QA`k{!9lQPVSE7SrD7#2BInjeYvOU at +*sW
-zAV2cpsP3>CMH2r7qakm`5e at jh0_&;rzdKUptJ<(>dr(KE1k-*qG9taWycD%JF)=yr
-z>kHg1FU>7zXh;NiRaIYK at PcQTf4OLChh?S@`5u05o at z-h#%HpgJmCVy^ZjC%yF?Uw
-zIv;*);F9F027lNHdy*J)=D0f)$z?IvmxP0tuo1&x<&pqDU*10;;y{g+rKN{ey37mH
-zv$K at oNd@l~?(Ze3SgkYxca8WWb4a9xJ7d0mpXaq=jJS?ws4?e5HH+ki at U4mL^wYqf
-zn;N>t6+u3Q_+yl;9`TqCASj9%gvW(|4Fp$mslbXunWT}urjL)0{cBGl*SjON>wg+5
-zU^#HQXn+W~$~tgPy86zbW|KP4O*F4bZ#b?wkQ`MGR}?EbjJ9>(F|v9t7|!wT0Y$YM
-z;F*UG2<Jh_kc9R7nz!z72^J5ama3PpfUlioUa#w?q7rvA%2a!GQdz66qXPmfX>4q4
-z at cCw2m2l^*uy-*yDkSN&M%97~KGS^>GT5DK7rhLI?>1R}-9hxd{shFwa5|ubi3=ku
-z0WV-X?0NOA!JtFTaFGcP78ZAC_Zrr4asBo2()#n`ou3%><m3dbWXuPvn+FEoBns5l
-z&XOn|2q?0t%QXecFiDbs=9(gD{t8QWu%Zk1<m?Va0Nq8L1+Ia+LPS6YxRgPOj|LZ7
-zK at BJ!fj?&FrUR9g<^-UE`b>Y5lg6nK5ff+Q#DSQwB17$`a)r;98{q(XQ!+|QC}2G#
-zbck4RKRM~tmA at +{-Ne6XX4^Ws9K;#1jH7~hh%U-Z9YM)(Bg)T@>bxDcyPZ1Qr88b)
-zRFo{k#*fx={xe4RPLxiiek+~&Rn4=^sKFYOR@<d>3DD{}?^(trDoX8Qq+iz%MjQkI
-z3i-w*^nan}F<d-fq{?%U^EbXNsW>`4ShshsT<Q{$%!wW&T}p!)nQ6hPmndH>1O)|k
-zw$`4MBj{mOd+5Xu4-E;nb<M%Uy+yU;Y?fP{A;n at gCPSS89V7UJJPcX24-ob}*~YHy
-zARMhJcY5>E$>zzI74gl%*B?(L52<&PQ6x_byy3EZ`2mUNpJ%JMBPs0(u}z|k;=_l5
-z7zVusCohKufG-mDJ62)a;zFjvj~=SPij)kiIfVf$B^Bp<LAlscU)zy(oQLWd<VQ;?
-zI3g;f&!RZXWXq8lirJO8-WjkN!s69&)GK7m5g2&-All~kLz(SP!G^p$yooHb?+^?8
-z8)~tK!?+qlQTIpuh=PxgR;AyAjGCpPdSiyb_wLWwVMi_`PmzZKE91T{y43<RQ5lMr
-z<jXTk%H<if7>X$+&YuVX00 at o${udyW9Y=~I6g?bWTnC$`m|h;dp$d^TvEbOa+<_w%
-z$(iiTm8k(+hr9$4{%cve$_wiqNJJOS6*djq$93aH<B1);76u84iAV$e;V5VwU%`$X
-zx?MYbQ$cyOWAB5Gwr>f|wyku>DkA1;s<3Njm5sg*-%-{>HV`_y{`sC1o{ZeI!gWUi
-zU18m{GSn8D3u!WoHH>f-jV~%ij=xK;yTeHBEc#7>e2ZZmZCGG$eBgTs{>Ik9>d+Xk
-z9n)(Bvp(E!B{nPH2wW+Sjy^m1TU4u at z90V=kN|K01E)|}q5 at UGW*g%gdJaG;g~5!U
-z<B6(p5K0_`5-~j_HC1kYI?VjE1MKnCH}5w6Rr(kJa at BPmfDvN&G?`l$u=J<qTNkia
-zZ4l%D9D$RLGd(gq*T(|zNctfekloJ^Uj_p5zwZDsJmTqZ at h;E;U0=<9q^|<tU-!BK
-X7r#1Y+t^fI00000NkvXXu0mjfaq#|@
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/mozicon16.xpm b/im/branding/messenger/mozicon16.xpm
-new file mode 100644
-index 000000000..3434739f6
---- /dev/null
-+++ b/im/branding/messenger/mozicon16.xpm
-@@ -0,0 +1,193 @@
-+/* This Source Code Form is subject to the terms of the Mozilla Public
-+ * License, v. 2.0. If a copy of the MPL was not distributed with this
-+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-+
-+/* XPM */
-+static char *instantbird___[] = {
-+/* columns rows colors chars-per-pixel */
-+"16 16 167 2",
-+"   c black",
-+".  c #020100",
-+"X  c #030101",
-+"o  c #020202",
-+"O  c gray1",
-+"+  c gray2",
-+"@  c #060606",
-+"#  c #070707",
-+"$  c #0B0B0B",
-+"%  c #0C0C0C",
-+"&  c #15100C",
-+"*  c #101010",
-+"=  c #111111",
-+"-  c gray7",
-+";  c #151515",
-+":  c gray9",
-+">  c gray11",
-+",  c gray12",
-+"<  c #2A1400",
-+"1  c #301E18",
-+"2  c #212020",
-+"3  c gray13",
-+"4  c #232323",
-+"5  c #272121",
-+"6  c gray14",
-+"7  c #252525",
-+"8  c gray15",
-+"9  c gray16",
-+"0  c #2F2F2F",
-+"q  c #33302D",
-+"w  c gray20",
-+"e  c #343434",
-+"r  c #353535",
-+"t  c gray22",
-+"y  c #3A3A3A",
-+"u  c #46120C",
-+"i  c #501F15",
-+"p  c #521E14",
-+"a  c #4D261A",
-+"s  c #562217",
-+"d  c #572318",
-+"f  c #582418",
-+"g  c #693200",
-+"h  c #6A3200",
-+"j  c #773800",
-+"k  c #7D3B00",
-+"l  c #7A3C0F",
-+"z  c #512E20",
-+"x  c #5B2F28",
-+"c  c #423122",
-+"v  c #553127",
-+"b  c #543A24",
-+"n  c #543129",
-+"m  c #663520",
-+"M  c #6E3E27",
-+"N  c #613628",
-+"B  c #723E29",
-+"V  c #7F4919",
-+"C  c #6F432B",
-+"Z  c #7C4222",
-+"A  c #794523",
-+"S  c #74402B",
-+"D  c #76422C",
-+"F  c #75452E",
-+"G  c #78472F",
-+"H  c #63453C",
-+"J  c #6F483A",
-+"K  c #764430",
-+"L  c #744731",
-+"P  c #754A31",
-+"I  c #754B32",
-+"U  c #774B35",
-+"Y  c #774C37",
-+"T  c #794834",
-+"R  c #474544",
-+"E  c #464646",
-+"W  c #494949",
-+"Q  c #4B4B4B",
-+"!  c #5B5047",
-+"~  c gray37",
-+"^  c #714E40",
-+"/  c #77574A",
-+"(  c #7E5E4C",
-+")  c #8D440F",
-+"_  c #914500",
-+"`  c #964700",
-+"'  c #984700",
-+"]  c #9B4900",
-+"[  c #994A03",
-+"{  c #93470D",
-+"}  c #924C0E",
-+"|  c #8A4211",
-+" . c #85461C",
-+".. c #924B15",
-+"X. c #A04C00",
-+"o. c #A34F05",
-+"O. c #A95000",
-+"+. c #AA5000",
-+"@. c #AD5200",
-+"#. c #A4540E",
-+"$. c #BB5800",
-+"%. c #A75711",
-+"&. c #AB5C15",
-+"*. c #AA5C16",
-+"=. c #A75C1A",
-+"-. c #A4591E",
-+";. c #B15E14",
-+":. c #834928",
-+">. c #914F23",
-+",. c #865121",
-+"<. c #865224",
-+"1. c #8C522F",
-+"2. c #935A27",
-+"3. c #814D33",
-+"4. c #8A5332",
-+"5. c #8B5635",
-+"6. c #83563A",
-+"7. c #86543A",
-+"8. c #8D593C",
-+"9. c #936134",
-+"0. c #B76822",
-+"q. c #B96923",
-+"w. c #BA6A24",
-+"e. c #BF6D24",
-+"r. c #BC6E29",
-+"t. c #BE6F28",
-+"y. c #B97335",
-+"u. c #8E6147",
-+"i. c #8A634F",
-+"p. c #8B644F",
-+"a. c #9B6746",
-+"s. c #916844",
-+"d. c #996A41",
-+"f. c #9E6947",
-+"g. c #967156",
-+"h. c #A06C48",
-+"j. c #B07C53",
-+"k. c #967C66",
-+"l. c #937B69",
-+"z. c #A17F65",
-+"x. c #B18866",
-+"c. c #BB926C",
-+"v. c #A78B74",
-+"b. c #E79146",
-+"n. c #FFA759",
-+"m. c #C59F79",
-+"M. c #D6A26D",
-+"N. c #C5A37F",
-+"B. c #CFA87C",
-+"V. c #D4A775",
-+"C. c #D8A976",
-+"Z. c #F8AC67",
-+"A. c #FFB36F",
-+"S. c #EAB67A",
-+"D. c #EEBA7D",
-+"F. c #F2BE7F",
-+"G. c #FFB97A",
-+"H. c #FFBA7D",
-+"J. c #FFBB7E",
-+"K. c #BDA68B",
-+"L. c #C6AC8D",
-+"P. c #D6B286",
-+"I. c #C9B190",
-+"U. c #FFC490",
-+"Y. c #F2D09C",
-+"T. c #ECD6AA",
-+"R. c None",
-+/* pixels */
-+"R.R.R.R.R.R.R.R.R.R.R.R.9 R.R.R.",
-+"R.R.R.R.R.R.8 4 O O + Q W k.R.R.",
-+"R.R.R.R.9 y y 7   =   ~ $ * : R.",
-+"R.G.Z.c t r 6 = : 4 + @   o R.R.",
-+"J.n.;.& # -     @           @ R.",
-+"A.b.O.k < .       % > #     X R.",
-+"H.e.] $.X._ j h g V ,.z H ( U i ",
-+"U.%.+.' ) | @.' ` [ &.C L.u.j.P ",
-+"R.} o...v.p.{ m L l *.A g.6.I a ",
-+"R.b #. .N.c.5.l.z.B.Y n 5 2 3 = ",
-+"R., <.&.Z f.T I.x.a.h.v w r e R.",
-+"R.R.q 2.=.4.:.>.1.7.x / ^ J N u ",
-+"R.R.R.R 9.-.0.q.w.M K.i.Y.C.3.B ",
-+"R.R.R.> E s.r.t.t.G T.P.K 8.D.D ",
-+"R.R.R.R.R.0 ! d.y.F m.V.M.S.F.S ",
-+"R.R.R.R.R.R.R.; : 1 R.R.s d f p "
-+};
-diff --git a/im/branding/messenger/mozicon50.xpm b/im/branding/messenger/mozicon50.xpm
-new file mode 100644
-index 000000000..76e799c60
---- /dev/null
-+++ b/im/branding/messenger/mozicon50.xpm
-@@ -0,0 +1,314 @@
-+/* This Source Code Form is subject to the terms of the Mozilla Public
-+ * License, v. 2.0. If a copy of the MPL was not distributed with this
-+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-+
-+/* XPM */
-+static char *instantbird___[] = {
-+/* columns rows colors chars-per-pixel */
-+"48 48 256 2",
-+"   c #000000",
-+".  c #0C0503",
-+"X  c #0B0B0B",
-+"o  c #1A0902",
-+"O  c #141414",
-+"+  c #1B1B1B",
-+"@  c #1F1515",
-+"#  c #1C1108",
-+"$  c #2A0B0A",
-+"%  c #350201",
-+"&  c #3D0B07",
-+"*  c #380907",
-+"=  c #371B03",
-+"-  c #381A00",
-+";  c #3E140F",
-+":  c #231815",
-+">  c #381613",
-+",  c #372414",
-+"<  c #242424",
-+"1  c #2C2C2C",
-+"2  c #3A2B2B",
-+"3  c #392828",
-+"4  c #353535",
-+"5  c #3A3A3A",
-+"6  c #3E3535",
-+"7  c #420E0A",
-+"8  c #44120D",
-+"9  c #4A160F",
-+"0  c #541C0E",
-+"q  c #451511",
-+"w  c #481711",
-+"e  c #4D1B14",
-+"r  c #461814",
-+"t  c #501D13",
-+"y  c #4F270F",
-+"u  c #552800",
-+"i  c #5A200C",
-+"p  c #4B231D",
-+"a  c #492018",
-+"s  c #542115",
-+"d  c #582312",
-+"f  c #53241B",
-+"g  c #592519",
-+"h  c #5B2B1E",
-+"j  c #572A1D",
-+"k  c #64280A",
-+"l  c #702B01",
-+"z  c #693200",
-+"x  c #753302",
-+"c  c #7A3808",
-+"v  c #632B13",
-+"b  c #632B18",
-+"n  c #6C3416",
-+"m  c #783817",
-+"M  c #452A28",
-+"N  c #562C23",
-+"B  c #5B2D23",
-+"V  c #5A332A",
-+"C  c #4B3E3E",
-+"Z  c #643323",
-+"A  c #6B3A27",
-+"S  c #61362A",
-+"D  c #6C3D2A",
-+"F  c #693624",
-+"G  c #723E2A",
-+"H  c #653D33",
-+"J  c #534239",
-+"K  c #6F412E",
-+"L  c #73462D",
-+"P  c #79522F",
-+"I  c #634C38",
-+"U  c #7C4A33",
-+"Y  c #744C3A",
-+"T  c #784A37",
-+"R  c #6E5137",
-+"E  c #7C513C",
-+"W  c #454545",
-+"Q  c #4C4C4C",
-+"!  c #484040",
-+"~  c #514646",
-+"^  c #545353",
-+"/  c #5A5A5A",
-+"(  c #5A524A",
-+")  c #734F43",
-+"_  c #775545",
-+"`  c #696159",
-+"'  c #646464",
-+"]  c #6B6B6A",
-+"[  c #727272",
-+"{  c #7C726A",
-+"}  c #8C0000",
-+"|  c #AE0000",
-+" . c #813C01",
-+".. c #833907",
-+"X. c #E20000",
-+"o. c #F80000",
-+"O. c #DA2D04",
-+"+. c #8C4303",
-+"@. c #964700",
-+"#. c #974801",
-+"$. c #9B4B02",
-+"%. c #9D4F09",
-+"&. c #90480D",
-+"*. c #9F5009",
-+"=. c #8C4918",
-+"-. c #954C14",
-+";. c #8E531E",
-+":. c #93541B",
-+">. c #9D551B",
-+",. c #9D581A",
-+"<. c #A44E01",
-+"1. c #A14601",
-+"2. c #AD5403",
-+"3. c #A3530C",
-+"4. c #A55105",
-+"5. c #B35400",
-+"6. c #BD5900",
-+"7. c #B85700",
-+"8. c #A65710",
-+"9. c #AB5C15",
-+"0. c #A55A17",
-+"q. c #AF6019",
-+"w. c #B2631C",
-+"e. c #8B563A",
-+"r. c #8C5A3C",
-+"t. c #855535",
-+"y. c #925E3E",
-+"u. c #915E31",
-+"i. c #8D6037",
-+"p. c #97623F",
-+"a. c #AC662B",
-+"s. c #B66721",
-+"d. c #B76925",
-+"f. c #BA6B24",
-+"g. c #BE6F28",
-+"h. c #B56728",
-+"j. c #A76D38",
-+"k. c #B77337",
-+"l. c #C35D00",
-+"z. c #C95F00",
-+"x. c #CD6100",
-+"c. c #D26300",
-+"v. c #D36B0F",
-+"b. c #D66D10",
-+"n. c #C1722B",
-+"m. c #815640",
-+"M. c #8F5D41",
-+"N. c #835E4C",
-+"B. c #865C44",
-+"V. c #8D654D",
-+"C. c #936444",
-+"Z. c #9B6D4A",
-+"A. c #9A6746",
-+"S. c #856B57",
-+"D. c #946E53",
-+"F. c #977455",
-+"G. c #8C7057",
-+"H. c #A26E49",
-+"J. c #A8754C",
-+"K. c #AA7B54",
-+"L. c #B37F55",
-+"P. c #987866",
-+"I. c #EF8323",
-+"U. c #FF993E",
-+"Y. c #FF973C",
-+"T. c #B2865A",
-+"R. c #B7875A",
-+"E. c #9D8570",
-+"W. c #9E856D",
-+"Q. c #A5846A",
-+"!. c #B88C64",
-+"~. c #A78D76",
-+"^. c #B1987E",
-+"/. c #D68A48",
-+"(. c #C78C58",
-+"). c #FF9C41",
-+"_. c #F39641",
-+"`. c #EB9A52",
-+"'. c #FFA14D",
-+"]. c #FFA555",
-+"[. c #FCA659",
-+"{. c #FFA95B",
-+"}. c #C08F60",
-+"|. c #C49262",
-+" X c #CB9C69",
-+".X c #C99968",
-+"XX c #D29F6A",
-+"oX c #C29D76",
-+"OX c #CFA36D",
-+"+X c #D5A46D",
-+"@X c #DAA66F",
-+"#X c #CCA377",
-+"$X c #DDAB73",
-+"%X c #D3A776",
-+"&X c #DDB07C",
-+"*X c #FEAC63",
-+"=X c #FFB069",
-+"-X c #E2B177",
-+";X c #E7B57A",
-+":X c #E8B77B",
-+">X c #EEBA7D",
-+",X c #FFB573",
-+"<X c #F2BE7F",
-+"1X c #FFB97B",
-+"2X c #E8A467",
-+"3X c #8B8B8B",
-+"4X c #868686",
-+"5X c #959595",
-+"6X c #9F9F9F",
-+"7X c #AE9A83",
-+"8X c #B9A186",
-+"9X c #B8A991",
-+"0X c #BDB398",
-+"qX c #AAAAAA",
-+"wX c gray63",
-+"eX c gray69",
-+"rX c #C4A886",
-+"tX c #D6AF82",
-+"yX c #D8B88A",
-+"uX c #D7BE95",
-+"iX c #C7B998",
-+"pX c #E8BC82",
-+"aX c #F6BE82",
-+"sX c #CBBEA3",
-+"dX c #DBC29B",
-+"fX c #EFC68F",
-+"gX c #F2C284",
-+"hX c #F3C68A",
-+"jX c #FFC38D",
-+"kX c #F8C68C",
-+"lX c #E7C694",
-+"zX c #F4CC93",
-+"xX c #F5CF98",
-+"cX c #FFC490",
-+"vX c #F5D29C",
-+"bX c #DAC9A7",
-+"nX c #DCD2B5",
-+"mX c #EDD9AE",
-+"MX c #F6D6A2",
-+"NX c #F7D9A6",
-+"BX c #F7DBA9",
-+"VX c #F8DEAD",
-+"CX c #E3DCBE",
-+"ZX c #E8CFA3",
-+"AX c #F9E3B3",
-+"SX c #FAE6B8",
-+"DX c #FAE9BD",
-+"FX c #F3E3BA",
-+"GX c #F7EBC3",
-+"HX c #FBEEC4",
-+"JX c #F4EFCB",
-+"KX c #FCF0C7",
-+"LX c #FCF3CC",
-+"PX c #FBF7D3",
-+"IX c #E8E6C6",
-+"UX c None",
-+/* pixels */
-+"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX| } ",
-+"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX+ + UXUXUXUXo.X.UXUXUX",
-+"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX4 ' eX[ X UXo.UXUXUXUXUX",
-+"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXX + + O           UXUXUXUXUX5 6X5 qXqXE.O.UXUXUXUXUXUX",
-+"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX+ 1 4 5 5 +                   UX1 wX3XQ / qX(.P.X UXUXUXUXUX",
-+"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXO < 5 5 5 5 5 1                     X 5X3X] Q O [ 6X5X' . UXUXUXUX",
-+"UXUXUXUXUXUXUXUXUXUXUXUXUXUX< 5 5 5 5 5 5 5 1                     / 3X] Q 1 X   ^ 5X3XO UXUXUXUX",
-+"UXUXUXUXUXUXUXUXUXUXUXUXX 4 5 5 5 5 5 5 5 5 5         + X         4X] Q 1 X       < Q O UXUXUXUX",
-+"UXUXUXUXUXUXUXUXUX1X2X: 5 5 5 5 5 5 5 5 5 5 5         O 4 1     O ] Q 1 X             O UXUXUXUX",
-+"UXUXUXUXUXjX=X{.].`., 5 5 5 5 5 5 5 5 5 5 5 <         X 1 4 +   X W 1 X             O UXUXUXUXUX",
-+"UXUXUXjX=X'.].'.[.y 5 5 5 5 5 5 5 4 + < 5 4       O < < 4 4 +     O X             X UXUXUXUXUXUX",
-+"UXUXjX*XY.*X).*X:.  5 5 1 4 5 5 5       X .     < 4 4 X + X                         UXUXUXUXUXUX",
-+"UXcX*X).*X*XU.n.z X 5 4 X   + 5 1               X O +                                 UXUXUXUXUX",
-+"UX=X].'.=X'._.#. .. O       O 1 X                                                       UXUXUXUX",
-+"jX=X'.].=X].v. at .@.u                                                                     UXUXUXUX",
-+"1X=X].'.=X`.x.$. at .@.-                                         O X                         UXUXUX",
-+",X=X*XY.=Xq.5.l.#. at .@.z o                                   X 4 4 +                       UXUXUX",
-+",X=X=XU.].#. at .l.l.#. at .@. at .z - o                       1 4 + . 4 4 4 X                     . UXUX",
-+"aX=X=X{.I.#. at .$.x.l.$. at .@. at .@. at .@.x u - o .           < 4 4 4 4 4 4 X   . o > > p N N N j s % UX",
-+"jX=X=X=Xb.5. at .@.$.z.c.5. at .@. at .@. at .@. at .@. at .@. at .@.+. .x c ;.:.:.>.,.0.y % ) 9XbXFXSXVXvXzX$Xg L 9 ",
-+"UX=X=X=X2.c.$. at .@.#.7.c.z.<. at .@. at .@. at .@. at .@. at .@. at .@. at .#.9.9.9.9.9.9.n N N P.GXDXVXMXzX+Xs K.|.e ",
-+"UX1X=X=X#.7.x.$. at .@. at .$.l.c.z.2.$. at .@. at .@. at .@. at .@. at .@. at .%.9.9.9.9.9.-.V IXS.N rXNXxX.Xs T.>XXX8 ",
-+"UXUX=X*X$. at .l.x.$. at .@. at .@.<...k c.6.<. at .@. at .@. at .@. at .@. at .@.$.8.9.9.9.9.p LXGXrXS T L.g !.<X<X$X7 ",
-+"UXUX,X`.$. at .$.x.x.<. at .@. at .l w * c c.c.c.6.2.$. at .@. at .@. at .@.$.9.9.9.9.9.a HXSXVXlXD.F .X<X<X<X-X7 ",
-+"UXUXjX/.%.$.$.<.c.c.<.$.x e sXH _ c 5.l.c.c.1.d x @.$.$.$.*.9.9.9.9.9.e FXVXMXzXhX-X<X<X<X<X>X8 ",
-+"UXUXUX/.3.$.$.$.4.x.c.l e CXnXH GXZ  .$.%.2.k 8 N.j v c $.$.3.w.q.q.q.a dXNXxXhX<X<X;X+X|.L.H.8 ",
-+"UXUXUX!.3.%.%.%.%.3.k _ JXLXbXS SXZXs +.%.%.r 7X) KXuXB.e v &.w.w.w.w.f Y D f 8 * * * * $ $ o UX",
-+"UXUXUXUX=.3.3.3.3.3.v 8XKXDXdXS BXMXtX0 %..._ JXN bXAXVXvX!.f p J I R V 3 : @ + + + + + + O X UX",
-+"UXUXUXUX, 0.3.3.3.3.%.t mXAXyXB vXzXhXR.i d nXLXW.Y VXMXvXzXgX(.h M ! Q 4 < < < < < < < < O X UX",
-+"UXUXUXUXO P 8.8.8.8.8.c m.MXtXB hXgX<X<Xy.N LXHXmXe uXvXzXgX<X<X<XA.% M 1 < < < < < < < < X O UX",
-+"UXUXUXUXO ! ;.9.9.9.9.8.0 #X%X7 G y.K..XM.7XHXDXAXD.E zXhX<XXXC.s A 8 4 1 1 1 1 1 1 1 1 1 . UXUX",
-+"UXUXUXUXUX< ( 0.9.9.9.9.-.d :XOXR.Z.t.D q GXDXAXBXlXq A.A e F C. X}.a 4 4 4 4 4 4 4 4 5 < X UXUX",
-+"UXUXUXUXUXX ^ I 9.9.9.9.9.m e.<X<X<X>X XZ B rXVXMXxXF.C.T.+X-X>X<XF 2 5 5 5 5 5 5 Q ^ Q O O UXUX",
-+"UXUXUXUXUXO 4 W L w.w.w.w.q.v R.<X<X<X<Xe.v m b !.hXpX<X<XZ.M.C.r.r 3 3 3 3 2 2 C ~ ~ 6 . UXUXUX",
-+"UXUXUXUXUXUXO 5 W P w.w.w.w.9.0 +X<X$XF m g.n.g.=.n H.>X<Xf q ~.9X8X^.~.Q.P.D.V.B.m.T K A b % UX",
-+"UXUXUXUXUXUXO + Q Q t.w.w.w.w.>.d H.d >.w.w.g.n.n.g.=.b p.e 9XN sXLXHXDXAXVXNXvXxXzXhXaX at Xg h UX",
-+"UXUXUXUXUXUXUXX 1 Q Q u.s.s.s.s.=.m s.s.s.s.s.g.n.n.f.s.=.8 PX0XN 8XDXAXVXNXvXxXzXhXgX|.e Z.A.UX",
-+"UXUXUXUXUXUXUXUXX 5 ^ ^ i.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.w PXKXiXV Q.VXNXvXxXzXhXgXJ.9 K.;XA.UX",
-+"UXUXUXUXUXUXUXUX+ X Q / / _ d.f.f.f.f.f.f.f.f.f.f.f.f.f.f.w LXHXDXuXH V.vXvXzXhXaXe.t T.:X<Xy.UX",
-+"UXUXUXUXUXUXUXUXUXO X Q / / ` a.g.g.g.g.g.g.g.g.g.g.g.g.f.w HXDXAXVXuXY T fXhX:XA A |.>X<X<Xe.UX",
-+"UXUXUXUXUXUXUXUXUXUX+ X W ' ' ` j.g.g.g.g.g.g.g.g.g.g.g.f.e DXSXVXBXMXyXB.Z  Xg r.+X<X<X<X<Xt.UX",
-+"UXUXUXUXUXUXUXUXUXUXUX+ X 5 ' ' ' S.j.n.n.n.n.n.n.n.n.n.d.f SXAXBXMXvXzXpXC.t K.$X<X<X<X<X<XU UX",
-+"UXUXUXUXUXUXUXUXUXUXUXUX+ X O Q ] ] ] S.k.n.n.n.n.n.n.n.h.N AXBXMXvXzXhXgX;X X:X<X<X<X<X<X<XL UX",
-+"UXUXUXUXUXUXUXUXUXUXUXUXUXUX+ X + Q ] ] ] G.k.n.n.n.n.n.h.V BXMXvXzXhXgX<X<X<X<X<X<X<X<X<X<XD UX",
-+"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX+ X X < Q ' [ { G.J.k.n.a.f oX#X%X&X;X>X<X<X<X<X<X<X<X<X<X<XF UX",
-+"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX+ + X X . X O + O # = $ > > ; 8 7 & & & 7 8 e g Z G U e.9 UX",
-+"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX+ + + + + + + + UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-+"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX"
-+};
-diff --git a/im/branding/messenger/windows/blistWindow.ico b/im/branding/messenger/windows/blistWindow.ico
-new file mode 100644
-index 0000000000000000000000000000000000000000..83dfe4415cbff4b4a642bd9d1dfa3c8e28b92999
-GIT binary patch
-literal 9662
-zcmd6sdu$X%7{HhK!2e7%LG9k{?e(thU3*mmSTPm~fg%v)AxJ4fAP8tc9)$vJL0hN@
-z1xgE4p!Du)n at 9*E1dUX{M?s+S?%f47K@<KrzIY_44WHk)x4XSt=Js~Cca7IfXCL3p
-z{Jw8yzWHXB;|Ad0;K3aJ7rBF395;yLI1eU##LdG*&(ryHh1v&+kzk1s4m3EzfeuVR
-zVfqcz-*TdBde%WQBuiz|$&{>a{>Qc_9bx}F$n-s?`<TFF!ZN`wEVIOR-Ty?g_EPoU
-z at k8@7$h`yGy<?JBPd}=wUcBD=bgDQXsOQ_7hlP-TIks~vh1^=5?uwy6P2TlGk3P_T
-zA0F7QwPqpn)iiQz^|*p#%H0QKwWt{OPcdS1`__eE-?AWO$@angd;IJ%Z5cx|*D})(
-zSBVOl;6e-s<{|sPM(mz3JR7i`{!AwmU`vmMaBz_kZbjz*#P5g%rXp95!e%7T82em*
-z+Me1vz_LHh8|3}V2y?8AZOx2+<>!Yvrz`yVWrgc89rBfpIP9%2`NOkwHW*ErUu};1
-zj`K~BF=1$b>2L(u2dMlj3Qr<GSV_6HlfcovKdQs&M&L_FrBw&MwCJ2TN_<RVr#!!G
-z#0e|xN*T|tH^33{M|J4-gS~D6WEAD4R1bbq0odEtQX99l>-4i_g?@#_YVNI{3F5`3
-zs16hhUEBxu?Tdh)`l59`hPlBuw-^NfD(qv~K2&!ouszoP-rC6%^H+|rG=5_B^{p!g
-z_mN5vmA;T;I^oN at s4j1g2Yz&ZVtt->Nppx_IvMOAE(77aoxS#mj}Pxq{HW+4L;_2*
-zKU&gfenpqu>WSb!Tmj;hW_J5sO&}br1^a<2u(z%T;oy3397jKJWglBUo;@lP at -J5S
-zah<(LzR>+?1^8BvN|_#1muL4Ja38G#@j}elV)2-M7VIK^XQbsRWLM*N=h+7EG|dHH
-z3dWPtA2c^Izuscpw#Ib1PwZkSSQ@(yDc7V2jj6nM$6M+TnhQDm7C`1Vb*bi7>%(zB
-z1LN(T3NtguxtMu+J7gU!2lA77=<oB(N5<>4stEGln;@-u*&nX}X-(72VP at Sl-p}A1
-zz1E^KG365U2kk{MoiI~ImA$+doL#%k%{k-{F6;q&?L6RLDd_b>=qLG^MPT2v9DSoH
-zU5?{k at Mo1Nfu5;)FC5(n8DsS0JicV4p5N5=(+y;!vjOe%l-~;-b-)*Tdu^_>SKwbQ
-z00;I{Qm#ngSCpYMj^wg^k- at c-pEBGKyRrwOc-8>dJxlyJ-^d at jKCcGXsZAhW(zlh+
-zzSb1Gq(gxl92nCk(Si64j~`lt$S3Bn86D?;Xsz(>C<SNdHfDRavT5e|aeUdE%b4}4
-zIz`9NFY3L{7$JN6s*2;dmGw!@(T`HxpskOeJ=z*S`YCN)n)@3@{HOC=Bls%E>a#2R
-z2kZ;?7d3J1+Gbhfw{4gcSC59B-W^Z6eqo<@aBQeHRycL?ysB{^UhR$DD4ta2rJ0;!
-zPzJO5jMgvo|FiUDoaY)$u`7CJ9j#Q`v19yhhFg-wSlV%>QLTf;Naw)O^UU7(O)KX<
-zwAvCs#eiyE=&#J~jcwRxYI*j&l;SsvK~e5fBH8TL#g_QJTc*dgZ~vqkGG53s)DQf)
-z!62O76<1!%hq2oQVyB-F2`<yVSMIahms;cB_Tc&>v{wNCl1Enue&R3?PO<&4!X)QQ
-zqVyaWJ<AW=)x4MVcO6 at 2i9e@hA=7?BX9L();(9PLH%<@!<so3-G#?z7_A<+9*y8q&
-zqzBH0MvaVAkBBj at uiX5e%yr^@eGZH%$j-uNo4|qRF08h7p4BV1S8`i-8;|nLZxT5s
-z=Rj`VG_yQr<ZqMDQMhAs+y_ at Mbw>Y at yZJRk<H%Q84C48O=LTjt*|HITc`S46HGTI$
-z{%)oYIF7sxvvhUH-S7&~zLQy=?E}rqULAV5`H@&=?RB#ATUW<MX`e{@TRJoHRg3}e
-z*4Hua!LzY$Q+p?~?6<{mD}7c?`or_BX=p=J=jUm(IqBI$-+_{X#|WVOTWMx8Y=1gm
-zi$ODdY3BP;nsn_EBZ0RK12Y8Wv2;64e0qIwi at pOfkW4>vh5|Xr&-P2H at hkCqg#6bs
-zyZ2|C2GuD*eoOv-ozA|HzF)g<>>8+p(x+E^sKqA78q9df;yAlQdl8BO`UGd9FvWaw
-z+?p`<PNoZ;dy{X8J<B(NkTOyFo<sXM+KbBjX*?GT{*L_rM3Zza?X^jU&WyF+fULp*
-z+#CqNaca7U`x(0blj8<b-pO$fQC@>BP)-fum%saR-XrH&3<Wu^Q_gEB$59-Y$Gq>P
-z_joV8$NIE6y-ww?hALyU(@D=6TsP at C@}n6z?(yDS($m3llHNtK9jax!pmE4f11Rs5
-Q?WWjKu`9ikQq=DM0qh`X{r~^~
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/windows/convWindow.ico b/im/branding/messenger/windows/convWindow.ico
-new file mode 100644
-index 0000000000000000000000000000000000000000..a22977ca8e9d1f0ad31da2508341a0aca8c11093
-GIT binary patch
-literal 10058
-zcmd5?O^X~w7_O~8>@j;$Jn0Y*Q4rh>3Mz!`svr`?CCGw^GEq at 9s6zq<(U1;VL4qH<
-zU{FDfilP#P at ggW5nxN=KS??Yi`~!RRpq9^5(=}6DUHwr#wH+tC`*wXl&-+nT-9(55
-z{99QO_&X4H91`MsA;c{ZREZ}ctgrehr9=!#e!a2^Ng-oM2FW4H64p_+AVbI?#=7&)
-zQD7lv8*9ijd8Q$J<f;3XAVWyn6+hNnD%RbF4#BIEAKp{R=Vz6C`za;gcw7O;UU~U}
-zUr;xOj3CPfBc2UzwwW;_(;lLMnK2NK{mQ127dFh=Avy=<%))JtopNl$0k~=V3=(Gd
-zZ?}~^yKb)=>v^{gZqo<2mm$HnmzU4P!t0x7Z16Q{VDA(=^4;h4x@(tCsSr81`Irx{
-zudY=t6!^nphp{%kI9(Gq3i_S@?vv@*iX1TQLrh$ICUlJ-j8pQ=gJzu|{OlaSVW*A*
-za4>&^<Dd8w?mx4=Z at -@_&q!bi-+zkz%H%;$JXU?a0Dk6hcn%m2&bh_-i1o|<_}%qu
-zi36~AkD>n$hjbnvaI70kA^U1m-@|V`)5Z_o^4N~OzH%CSA8a;6oC+f>&+7v--rido
-z!?9%h>en+r;0(ojnZZwu^4MU|`pef<a{0Axxjn}j2P~DpX-?AzKYwPh4KP6aVh?`C
-z#y9UMdG~cn-g~2xqlcRLeE+^mz*}AzPUOYO{g`J~EIIK7&VS<P{e2d{`p$v!s#P~_
-z*Z9f9h|TB6Pc<*{lgAFt`k21dkKR7>eT;LjjGtKb-4EKkAIWE7OB+*{=VLc3dGg5o
-zTyX9rS3jEC*RpxeSRxmzZr1P3=jP`?-bZdw^7yUYxZr&+!8?c-UlC6Qhs at i@<b-Aa
-zgU1i6wUg_?!g1QC_anbHZc}o2r;<<Kwbwr{ttt8H!}^Tjz01nmS`NU at T*$o~z|+l%
-z^B-QU+&AhPIIeA6CYMe(VRqZe!L6H?-JIxy1Gxt7>(v~v_qcwTJC>}ttn~}_z=V5W
-zjeV^)a`4|V;M3Z5+T!WjkLOZ*4w<j7-us>PyT(#ouCOip?WeN6+WUfj at N;-%r8IA^
-z9ALkec`*Qo)awVw2aGH3tK<<|PHetVvX_oy++BRw>^itnpggqe%=0zP1!KQv4*Kp2
-z%=ATxua5)m#n_E4+h2Xq)ekBCQ21iU<>9-_^_~yS=iRc!p_CK8eW`ChB)rpmVx*|k
-z_dSb4IiC1FVB+#x=qK)}!_T&999cX*b~#JTWAo^9U*bEJi^nMs40fZ at UiJliY2P<`
-z%ZFDsn(%KK+^z<Xk}r797+>_l0cWdYZ at 0|5(UObZl-UL;-=BDQ;=Aa6=LK`1`K~uI
-zc&juxtV3MxlkWtc`$sfh&F2|0jjM3G_2`>=d4QY#b`jGjv_0M#tJbsXcko;pLoNrF
-z(Z8G<#y|8o<EyJ*XanA at oA(~Wjq$zg!`W0<%fs;DIYd6#OY~ms`&Pp}n%_wnFYR&9
-zjo<KV#l!H4uNgm`>~HWJjd_L;`qS8^4?V_uLGf?!R%y&PfMh-Jpshw#IAYXee)=Te
-zCoWr<H>&OHI2T-E_=WaJ`^4_@!rFs^59613+T==xe#9LmUtLTw%D}c-A*H)!jP;bt
-z7nMo{jx}-aALze?So{-u7yoN3fzAq at 78*({rsCg1|4og47^XFcv21i+lrx`RNJYwe
-zS5Ioupj)Hp$xOw1m{*srbu+9&99jc^&a%<qtN9!#cp80EDm4G2g+0!}UK~ezW|)pT
-Xhq<U>paaw}+)-+kEllhVFQWV(oC5s(
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/windows/default.ico b/im/branding/messenger/windows/default.ico
-new file mode 100644
-index 0000000000000000000000000000000000000000..51fed13f752340320417fa83145ad7896b2af839
-GIT binary patch
-literal 7262
-zcmds6O=}ZD7+z-&JvJ9buwq0J1<@dgC>A3MRs<=6f`SsMs92C7NH3Ny_<{IE6hRQw
-zf_m~2FP;P!FM1L36N0}W#~#%2c{VfYY%;Txq?>}KJb7nlciwrPci#EfCJ5Hxue3G5
-zcQKfn2!eG%5NroZz!boG*C+h(p#dxc(^AUdUxVT<VTqQy9!Lw?6o4`iDb!)(6h1xu
-zA|6)0i`wN_JiB^J+&w#)N376C1<?FW>(qkhi$E11&n95DvzI?TmEy*cH0Gv$i+ksO
-ziboe;i6=9=hS7t*$;IC1a=q44!?TS(p6~T%<8SJDeRBzZ7lHDiI?$%S7%uDS<>$NS
-z<Ns#P^cfGLL+Li#=U*O-zwV#;S at 4Yqo|y)8o8j!o$1;3zLyBj!QoO86asPZ8x6h<=
-z-^?AB)A2Vsw8$?@12qoC|LuYlGm}yro{(by+BPoj%jVh5TVK2RYb}vSL!)mE(K#uO
-zZC>WAxzi5IALA7w$2=SsT^i7?=4mU#&o897u-DF8YZ#Wl9*5`GWcck}mX4}T1Gq<-
-z{NK;F^WyZ*(ekH`x#LN!GWev{SUku4Z at Hcqh)HMf@$o;oO^Q=HkYB}Ku<iLhQp{q`
-z=y+$?@WUO~IB>o1tV<|YoZPvVn0@&8>pb$=qZ`{=Oy8Dr#+>NPXK=4u`P<g)y!dN<
-z<qg?$p1EY74=p_pz}=cVVtzUud&Vbk{#pm~$`b#i4mn_rZ+qV=TJO~#*!_))KXtg)
-zF83HLf_vG<KQ(8~xQvoN=Y-jpQ4SGL3(wfepZmYjzEd70e~y8zPu98jXM6nrSN_aV
-zJ?HYaT#NFG|C1TFFXn09-0AP^ZfBp4y{v)!FIwh><nzv0Tsa`c!S(rS;C}6jJ?g`+
-zuWj?U&OHG9n>`w^XYd^2^qHpyj_38VyD#KI55M;NN=5OHtoQYq%@r4(V;HxU<Pz62
-zmw#37h&?qWXCPR64nbq`9_8_$>^p<#VD9mZ*T*@|k at w`DdKbX8eGHgKzIQ*Zk2%0|
-z0At#H{yedzUGLgswGY$sUBLcc%kxfApMO*i6;RhZ57?d>veqNB&z#C3a at WC~^;MI*
-zE~CB#P at BCi=R?+<&VxJ7j2UNU@=Dem&AHp+e#OaOkA?X at lLu$|AaD2kijHRk+>$xl
-z&D*?I8r<Wcba0IOo*OQmTpRto$-gh|S_hsl0rvUOonPErc;3bttMh-KZobSro~byG
-zcoy^juR+J0HnrAhjy{Wa1-1oDU#nSW4ov%a`tHL=8HiU|M-BaXbKS??yuS)M7;o}U
-zt?ed<Jj(PBRDlMt(tILk=IDy^WEgGew*WA|BA^b$KohX(;yt1URDsekeVT0!;Q~j{
-zU`#g0Xrn(taEKN^n2jqNDjUGY{2^^Y*-grhciAy at 9V)w~?GHc1C4M^=t|I!wCrZBi
-xw1%IU?Qoq~^w;Dy`fn+_L<@euXu%iqATXem<V(hAjthwfW3)=YlyS&-`~^IDi|7CV
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/wizHeader.bmp b/im/branding/messenger/wizHeader.bmp
-new file mode 100644
-index 0000000000000000000000000000000000000000..7fbaa640c6e7d06647f2f665f415c516b30d2bf3
-GIT binary patch
-literal 25818
-zcmeI42|QHm`@oOns_YELo at J0FvV|7141>YgBO&{iC8?yOq;A at z&<%+wDWZkMEiDqa
-z<+lIocDt1}?LtL${?E)|90ot#-~E4nzdoPye%?8rdCoiI at q9h+{vHeZ-5`XOjNqyc
-zuWWdkz>5nZ!xcgH!u{I<*o&or3reIP+yex|9~>Z<PcS4H{`emFfBOqQeE4wh-o5kZ
-z&)3%0R#sM)mzS57mBF>Ty1JpEp{1qe@#DvzK7AVF at BjAgTSrINlPB%BZ$Iem{eu4#
-z5r=qh{1fuqw{L+Du-dwHtFN!GnVFfkwzh(Tg1ET2u&^+hOjcG_*3&mIok?Xdd}Cr(
-zBqe36S(CGQ^WL<y{3T1W!o%0ko43NzanWq^Fr8`hlqjxbX*-gntvHz`r|e46_7xPi
-zc=YHw-co`g-W&g!{QUWI2)Xs^*W1|G$jHd>^Yd$IY0aKJ+uq*Z)6+9xL7;C`vUSJ?
-z-N0Q6ffYjHR?1U-v}c7I+AW#wnQjxj-7$8L$MOoFwY7em8-sIxi`sKDzWmQ+$6ll~
-zyifVHgPjem7T>$~2yZFD5buq at D?_zeUthm^_39~8rU(iO>gnmZySvB4#KgwNM#Uz$
-z#_yQ3s9bOH>8Xp)u`^lGC9U%MuHU=2U+UW2+_~=ThgGKrK(UE&3Wm1Ju3!HHZz;hL
-z?~T7D- at 0`xCnsn6^yv_I5Oom|5z(v^5gqFko2{47pq+4*GfS#?q#eAx=hnwx0ON06
-zo0>b*aTt?oUU1UGG)4|9TU&48EhQM at z44tg^fS($JsTb#4)hER41$7!03f8Wh-jyU
-znbYFyv=*HiDT`CQ)5<RHyZZ^lnAMLFKqXY%w~xyU&ud;$_nMQWk<;pP=dR){B^ctp
-z at jY^HZ!ffd(AGgu#m&tvxG#m!BR1&99M_0DJ$e>V^<PtRw&KBOz*u;b8I6E(<Au&8
-z6?b%LO9jPg^4k8s8ON6%eKG{2vD^B(lP!2l35IxYj9LEr_3M!%N1)x4mX`MR_6}gB
-z`3pi#B8$~yejQ5|R1Zlhs5|=j^PxXKm9jAAUg=6cctvAogqlfIQq4=pg#CgNG{=NJ
-z at dxhUG0vR3`B2pvyrl#~yf?-yLk~tnLqknX&Bw=Q9xJ){E!2*zRE at 45V;0hkNZNk5
-z?pe<f7RJ4|I#UibDe3r{I<NZqe8<`|AAp<x)^mI!)+X+2BX_s1Y<P!}H22FYDQm!6
-zN-)HGV{G!JOP8ors+^phSAVkhOID4jQHiV at dlu4;Ub?mX^s8RLSb6_L%HDbzWfw+N
-zcJ9^gZLM7yO`T~hj4>s5#V5N_riX{*oLzD94Pdkk&duL*9B(PX5bupK$Zc(HVPRp=
-z1~M27Xa-%~Jf{0^QI0tAy;)c{c5z0 at g?C?SAH83ZUnL=HANg}d$-h4CzR?YpY9 at xU
-zkr|E4j=rE6N6BjV25hNIKJn5fq9AuyHQrK!A>JGRPKJ(XZf-90LLm;Fot>SW8M^*E
-z6vJxRSs|c8L^lSmYz-zr1&eiY05xbP2UYRQdBm+PY<&7=S=K%Y8N0QmXR054K6w9A
-z$(@e{{TMeuG_o*4MQZA?fh5oHURP}sS+F&$9B(PX5buqDCttsQT}MY}+O%nQ%w(_Q
-zvr#_y=s*rSBB<nJ;FKmnb|TX at PYyi}x8O>NI;k1oh-Jl~YKfW2;uIhCS+QYB+ZX?w
-zCnfK&`}ECIFMDgB_EbOoTz>!4UKYljD_vV#IsxMv7Dfn2r^Iq$vV*o|{JIUrcuNU}
-zcyEj<fBEtyEiDb2K?p)fI-Y5AK}Yae)F8pYIUSsxQ1Os5BbKBYDj!e*0I>*E4Lu??
-zYlY0z5RcSjFnvZ1%Tv*CQ=Z~hd#CNU&aaK_pKAW<D8Kcpu=Qzn<6j$V at 1|DVSXy#9
-zW><4a)|vSk4PI+%+*7Lc>8S`}ux9OUyrl#~yf;RbZ{EDAqM~ALZ9QksoT)BJG7GBk
-znPi<Iqq$&ZeP8bpNHUTtgyh^PAx9KE3dp(<N`?^&GS7k@%k)M21VydL3eGYrZenCx
-zlB6|R##&02DlJcyQJ~6BrphT&l~nCiHR$SEbTth-5t5#U7A<M{j`i#JT)1!zZz;hL
-z?~PIAl#~=rO-+~x)v}K!`&HmGiIFEH?Yy|+5gQQ*&=;BRk}fD_t!o*dQhp8QMWMHu
-zc=&#F at l}|KS&o}ci`)N)keI~`jx=l5EEg9S4-XIcr4|+ze0+Q`EyQUf!I0A@!)e~X
-ze{W)9LZ{Pb(dSG0mP^h*#Lf~vWqgv3!8xtKZFz0`lB!2ADvvI at LYW?-Z5&w8^Z+Jf
-zpr^9yT6bnkry)IwU&LC)Fx1#>jYE7vcz$zY)kCOSHO*pG)nLwbm;`gMG#U*igkbe5
-zF)@+TI)WjmPlnT6y?S-><jIaM9%PSQB%cHLEHEwJ&}ALavkJ*FVx+3gh>}!thsiRs
-ziWgaq{_BgLV{JXq;Vi!WG5z at 63H-C;if;sNZ>EOlYnUw(lXccGi?fd_ at LqR}BxPx2
-zWCR_ik&=><5)^>{rXdCr42L*mgtr+P8HR?26xVdox%=^1n7&g$(qZL^mrytIPMU2W
-zx7UBmS?JSXm8znS|GK^P4KI3OGUmV^pQ!WGDEfh$FLq+nFi-{t4Zaztv at DlEhjaW-
-zCTeQBu;e&Wf|((xPOn`X)EI)j1j7-a4N*f?rcaL$_ADKe1r>e5x7NYTO8TjGK4D7?
-z9d?b~|HnjO>&a>^=iYod`MjsF^^t&xMdX&69haGN+w2ho6o!UW-!7S7*xbZ~I(6z)
-z)sYi0+_r7o5ZefbLmV>PTiErYX)s&TyF|dP7 at sH2NY$DdRSJ_UH$P at Izv36M0ywY?
-z2v}hKT~xt+((H5rl2vKboind{ed4x=N!b?P>de2+Trh-zU+SrjxU%~O4k;oM)>Cz@
-zXf!)$_e at Pqq0$~HiHL~63fB-D35G))GThsD at 7_sLlY~4<_+0i3WT$)~DSFAJHf-&o
-z at b@=@VpiCK?#8ALWuu5m`iW3 at qME<&!i>7V+Qp at 5iCITrl>&zF(7#!J;FhlSVnLFX
-z>NIC#r*I>eSUuMz8ivklYBNYAMM+6HSP|h&z|hgrafpos!yyhC?rqE6mjG}Qqi}*#
-z0XzRh&E^%f3RseR`sHV+Dl6{26DC>jzsFqDwV0Q|ryh)z<h9%^PPUFu&r_W`x8X%k
-z+09pht4gFOo&quqUc)4kcNu<=NmgNK&j?r1^B0z|;o&u%z-P)YWGo=8&o8LW$FIi6
-zr#x|@JcTm7wzdgxCczNzjS=L;L+$*oML*H=*qO((iaYoQ_uNywl1|ztLG_Q{o@{$B
-zDnUKo))Sdg!7uOmlfy1n;d~y~0|MeUqT*Km at tOLTF@j`=iCU377MtKMuVcQLcbRm+
-zVJZJgEQ>2Rq#e2n!3_PL)u%fW4n2e(EX>d_mQ~ot7F!18ntE+8a9ANuw#8dYFvNRf
-zIQjAul#%-k{LO8*6U*Z~k8uUx92a<*+p&n-Hk(_{hoUp@)Z>>VvQ19SWdSKVw{7k?
-zx5{zz8pj1)gOWVDOD77L3rq<bXS$mGB_IGm_8=1z#H4L^w>*PU2uzk{T<C;$6*{gf
-z>)&FXB=%KW!5MEU!4U5a4*A<RbX7g-z2_Z-4VP^WGdq_d!8eeA-?$uh_i1dhd1Srx
-zW(5lfnTg6eaWRe{K{uFXuwq^(xa<qKY_j_bV_(9$0z(PkgZL~WNv(OpT)lwZ88EMt
-zQuEl{Z?jk0;pDnkY=9uhC^GPt5)AR);E?aMqv40qpz<DwL&PQ<vEPjZUPb&{5j)mf
-z&|uj*Yl5s7_ju!R4u_ZkeVY*XYQ(;<?=HL8U;(~Ud|o*|OUT$ZzUqZJfzsO_;&N-{
-z)V-7qLPezLjAbSGxj9)S7rdneL%cUQ<h)iU!_bPa(4j$Wa}mFb%uLH01jn%ynSTNC
-zzl2y9A)a*zeb1n~gSoM9O?2KZ;<XQgkj+rcrC>6}@nXl9eV6~VnY)4{Z6CI&1{%i5
-zf~%r3j<l$q%Z@$6qLHXeIY5o1`0yExu4XcX3`2Xw`xN5WjL>$mIUo*&$h<Sm!1HfG
-zTq+UUoddT<K!+6ofb1%i%}`{<GUGXct9KrdRdjR=NH4wdmfbMIbb*ATySe`+n2b%X
-zd#$4GiMN at EL%cTz%fH_50|*QyLr)<=*O}1RaNLhFH4CmFu7?quoB=(%z{mp3*0C9~
-zLy=#}RY+uxy3X8^b2rYu`2tJA?1pjuxetj|Pvo at xrZZB4b~IVp#p5j{7~;J#Sl)SY
-zfT7aLr-<i?eo#5c+<GQJ(9nMASN6A!1L$@jX6eX`WW*>Q(F;ek{Sb9`M8$zul{UpD
-zOx-q0jTS?p#i`gWR<>WNL{AozHxm^%Bg;~CjeT7M*Cb|EY^Z3-J>Qnq)V}fj+q6bl
-z6nUj)x=>2hD<XOm-co`g-W!AErL}zweGj18TY9<d`f>T3MiyK}9QO{TN8N$USb=E!
-zBMKIXC<Pfmq5rJ)pr3H`36>uq!6Z7&j=~iZZ1EUBetds99t05>&m%1?rYA0AMv|T*
-zA~{EpWG*0PCQ7D~WgT`G9>rTqFvNQUC%^wV5QOHxpe}n+sPvf7+^U8GwA_qn%tb_0
-z5bmG)A&mA at R#p}ODk>`S^76uxAPb=(tT%CSagFvd*1go!RGf`{BEgW;CoD}@Pang;
-zL#S~!Q#M(31#w`FE$ICbNX<eNZN`X>%?DVqaREtS2xm25uN=F;NCJH7;lqcV_7V&^
-zeZtaw{f0(VG0}PMLv0F}Lh!*}p81W4M@?T9YQ7E;lpo38W7G=>2#`pmNs}gxr9A8+
-z7}i*V;jnIDDK|7S(K!{NjJ- at DtP+)4 at oHe?PSO~Q<Nv8LJUl!P9y}P<Sc2iOZec0w
-z?lIAMl%mvprVwxtHQfG9(4AG0YWjdv*;OKdg31sMX~O~1e+t@=?}1}gBUwr?9LX~%
-z+Vd4%c at hmegig;!Lo3nX3REW(rDZ;3)}?}S(3HUjCOBx%Y~8rHU}X<_D$uflJjDI%
-zw@`EbJ;*{rLU7D~Bufc~BYB3U|LZLpe++dkL9JM!IBO^BS&G83P=urbT}s$YICJJq
-z7%Rxj%fmiGEWuF>HZ;5dJx|yuV{B{;K!(IHz8I&>&CPw{#EDVNBp8n39M-KT9cW5D
-z>Q;(c=cE1yQS)6;seaRNPlH8vj3HozgaHHrHp5_j6xfEQtE&seFf5={S67Ev6%!M~
-zA{Mrcj~h1*yE}2>L{55`29EiUZX>~PbpNpKLLc?wBQ*IW>Q;ifm!ghEs84B+l8FnT
-zz++^w?7Kjv3b$Z$3<MrT9h;A&q$KQX!s=o8_=E|}c>oyQLzF^1vx~6>`0UP|JKNja
-zM=_INIEr%y-};84m!6>8n$Yk{)UO=%De6!)vV|rQj}DW89+rS1BsglyW&#4l9uR{M
-z!Xyo*hdLHc!ofgsSd73tGc)tqvuA_N8F)u99Pq_=NU)@F?HPLb_b!^9y}rIa5F0`d
-zG#Eg*0vtR;U;<G}p-`|Ogj-PME?l^96pVm9DJiMDyL(s at 35LVEWz0%An4gf40Ov6J
-zBCr1k8zAiPhmgZFgs$n3K|Sn5ggwZ^Vw8}OSg>FL>_>$El#yywg5j8PjZ(0#t`6Wq
-zyy3$S!w3vvf)vkiSQ(yZ!-)|Z%&e at e?c2A<$HzmI!r{4LZ6Fv9>z40VLO>Q36+yH>
-z!UrKRggy4da>FZOc$t@%$HoXXE$kyLE-nToV1)LwwY7C5qX>p0dFF5FVMlmjVIdqf
-zgJA?TdH at g-bWLF}i6 at 4aVZJmZBm@Q!Q011ClmJGkJOLU!WHF(j!FKWQa7+ODG^3b9
-zFdW4>|G_Qje^gafg@%R#0SHS#3K*el0<$=xqN31#T3J~wUAnZnxf#y*W4{NY4j$IG
-zZ{I#xON5YyCold|w4dMom8QW#2=Y;EAsCM0oPYFIS6A25r%&POQloq;)SSQ^&Kbi4
-zi~uH_ISz<S)i6PmlfQO%_o3$eIKhz9C;wH=s#U8XN}&e>)hRr=7HoOnfi7SERZXp9
-z>(=*eZJ#-<BN%e}<iD+fXBZtldK8|gi8ti+>u>AVzq7EorK{Tz9et{!W8eYA1Vg-|
-fegwI@`%7KjLxSOtz-sI^5^*?oU;VF^M3Daj@(2r_
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/wizHeaderRTL.bmp b/im/branding/messenger/wizHeaderRTL.bmp
-new file mode 100644
-index 0000000000000000000000000000000000000000..2c882095562c025edf6b2db2de264f586fea16cf
-GIT binary patch
-literal 25818
-zcmeI42Uru!_P`hHA{|0+0#Ze)VxdY)Na!FPX;MW&6cm*!DxxSL(kv(-h=2$ppr{C9
-z at 6UeKzls%6FFvIxSoWQ;umpkJ<=y-L-g{p%-(i{To@{pJmosx_=1fd!j{=b1G!u@>
-z at RtRDv*C{e5rrdy6vFif+}L052{@qa^gmt$Y=-~i0O9f34A~6(YM`sD>&cTRmo8m8
-zdGcgMMMYUzSxHF=93c;9;QZ64PeF%Zef|9Tv!kQy&71cRA3pEw{6g?uEUWg{?69Mw
-z<L1qq04gIR!`Ih${`~oxnwoNQav~xke0+RxguJGv)?5P%Ds at 44_^R00%?SyaDJg}C
-ziTh$>Gs40)dwa**+C>|gglOq_D=0aOic^F|$wH!560-L4Y94|j<ff(@EDMKV!T()`
-zA3uJqudh!_OS7}H15jLCT+^maGcYh9lgZA`&c42WKH)2^f;Q{;@09aDBs|qlQqfU;
-zUa+oZ^gO5a7Jl1l5qVB4%iPx2`fNQDkaZ<&-<_z^r?J&<*Vg|t{`6;DjNP}MJb9U5
-zQCL=O^bEVZyU(9LpOTWIqoc#k&8?xK0T?49B9<;)8nJYlOVoC==n|didX44haFNvt
-z2v4oubGs|^dS}Yzj-+$#>ly|?;lze!jJ&oVJ=(;wa0nKBlnkFed$xc7erPkn at Mg`L
-z6&xJAxHp9_UgEekO?TOe>CtD0iiCDZSn`pA`(Jir7%z2fV!#-8{M|3+hr=}S%Pc89
-zMX)F=t2P>j*REZQi;IJfPF-CcdcV-#6cQTd7?G?SbxeI((?~+nSsId9a`5q23}XgZ
-zV=u<v8a~G!ePy$}ARw~=NaE=5jCs)RJ$bb(3x{CA2{UYJYV!8>hQ^ahr3UsV`;hh8
-z5ml;@jm$-8W=z1EeTScQ1IGOOUv}N<0*u=(b*w)6%+PBK4~a~Yb#h54Us2hN)59`W
-z;d$G$DhL*ZWz~o=Y-ngOGc)7o=kN7bzy^JNd;<(acPTG9O+<wBS9wQg)V%5ejKz=o
-zFs`qCq;DH1sp7f3;-!1y32s44^PtQnMR(%sKj9>)kwqJ~9b{QJ1Pe}p;l+y=O-xKA
-zB_&;5T|Ik~i%+mtXvwt2rwEGBoYk)3DJS3dRKM&7j0YZmNvgS{X|h;tUihYl4~b{n
-z0b1zZ+kB$b85S`?IcL|LY{M|xt|(i(v4CJvSXS-N7(ROR$ji%1P*4yo5Ew$Dcr8;7
-zJ*p6Pg189H`^_ad>CA_3fU&B%E4k{jl8%p&({I@~I(A&^+<LKNV-p=C7^IAbpQNhS
-z!qmFeb?@Pf<Lb(oHG5bV4#9#mW%%jSr*-SrVSS(zJvq<w*(e`!Tt2jJR3dD&-qA1N
-z;-~NREnUfnPRl4cxkhG#HRj#>vhyEZ=~o9Zt~t at BMOiB(W#^uBbXD!!1qrp0F<AtQ
-z!m?^i8J3rq^YZc<8ymw25YkNVEpoxfaFJb9&9Avc%A*)RgJqzB#atXPR5$}_Jj#ox
-zZmTbT=twH85tp at zPOCinqWjR(uYhsi-L9NojL8=|HuPE}n4e|nULIkx)7nz!_#>f9
-z(^wV`!Ge#>@cHxS=H}+g%F2}9q`M$qI<T5i1ZFH&pC8LBVNWt%FB?<?mt+>zD2AU@
-zi#mhJ)Zki@$p%4rcXhK^n%8d|c9)1sQqs!LHNO8=*V04B_~dI5hVf?S_N$$Y7(J3s
-z at sKFmlvTb#n+X<$Wz|MzxOeYf2?+ at p&RbYm=sK>D3OLFrLM9t!bwk02Tvhu{o0h<@
-z;3ef*0)~fKpmJE9nCS))RbSfj5@;S>*40QW*h$FHN-y2N-tpt?hwkIgKbJrFkbk`;
-zyQz8W at ki?`?yWj-V`=W?pp0`q$@Q)qjyuO!8F-{39D3gVi7X3;V8KUV`10jTeSLjX
-zQ&aFrwQ1oJew7k_M{pt8<nT#4#2#(Iyhk{CZ*Alex0m-Rlk+$rrWYxt;qSij7(Pny
-z+;W;nz)VESMpD5^Si)M6WG*UUE+%O%E^R3xV<9PPAth%ar$|;(qbaL{Sd&C&%E%c;
-zMW<{^%B!opNU$g at t2P2dm{60Ek#To-*R)(H=2I@}a~KzrYay2i4Tb_ZK*+4F`(Wyy
-z%`0RvO)oGu??UDcx|_1P=5=_%jb(=(gLi@}uR8XgN6<`Pf6m;&Y2Lhfwzjq|E-v5z
-zTUl96o;(>=uUHn#s0uzD!=9cV at IhfvZ(-{$>Ty8CyPQ#`NV_`3RrYdwA5--*s_bDz
-z;Vn(87->bvtdsXDn(4#8+&f(`Xs`%Ko5XD*r{zD>KAs%0D=?=i`tXyrr#>2arOL_A
-zh3VFz306J;ppA`<l#~>FgT8(HHmcIFrt)wM!JAQ4RkgEskaS8H at +f5#?m6+YIw3Gc
-zO<ufH-zh=GAVN&h6{c83<ri at Cn;vWabnJCc`O~k3zkf+T*TOGK_S;s!Xy<iGM1h8R
-ztdNwwqJF4FNS0rEBcJg6*|TSBjhs|eRA5Q#)vH&miDgu!9*$vERTVH)w_hdTc92o{
-z9rGp$SS~Mp3=H{1DA0I%B{xKtJi*#Y9m?vEwR=y$`&RR^yX?tV&y~4?;?^mb+p%dF
-zOvgXtk}ho>uLx!06hnChU6?y(k|s=;P*+zss?xBg@^B1cJwn^em4CqjzQMw+8e|i`
-z3mVDf^Pl-dDba_Y<GtL<>Q+7pJ05<M#<yLkTECV3-X^JF?--GteUm=7jSu`le`QUp
-zvCsC&+(x>3WLSZOmE(~TOwUF}MzSWBQI&cKLx^RWZ%Gw*%j0(1&nT14wvl8V3LkXB
-z<Vw!Xb^$TUy5p}loo$EpBQQ%Do#4rOD|w}D6Z4LrZTr3=y=?r%xjQem?7d50_XYnZ
-zq49Ifk=KTvDf}dJwdv-TmayPYHZn4j9XXLmBuh)nQI&=@m4`6=`t|EHY7D<?F_%L=
-zgXD2bIHXlwgLaZWY5ky6NSu<|)IwhgyxgJhv}v+RFep#di`6$>bnab;s*aaOWM;*)
-zZWzMD^8NbSW&@W*a7X1e>}Jsx&9q;l;~1kp*G*a3Kv-CwM3NF0mk=M4goTB5b#=kP
-zVofr{OFe|)i}xME?gzjEC))1CWxVyC2?Ewu?(0sy>4c`T`uP`<r1hSw?+PA#@s2O!
-zl6IYFlS@~o?wZ6kcXR#`K at p4NFWM^}e~#F8WUA)EDI&Cq+R*|F3h at ypWJt=cN;-Z@
-zGyMg`DdQ&0o-lb17w>FtK5cGZjVatJTwL;8T(TsRN=ZrGj~_pX7l;KlhcL`&>V$4^
-zf=%vt+8#{CIUO1kc$?Gb@^~pXNkyls`>)Qt?-r4=F1`0*W9j87qBi5nS$&!g#k{hP
-z0>WnY3lj`&V|hfZxm1J48EuBEa6`DQxNoJ{!U{};6`Uf|kAan at UFq0xrhP@_tHA85
-zFhk=IR{_h0u!29&Em at Zq&nIZ!-rmWAWQZ4eFvI4LXh2yvSkxHGPE0tRDmVh~at7QU
-zV|QQ-C5KZXP)LGW-`pxDZN0bQ9-kO>jA<IDV>zeCX- at xta0K4tn3DoMA+Pd6&ROwe
-z$T|3Z03Zx9VWI#ZY6{8OZLYjt^gDg&0{k8<N(x^&#JweDE#J1bPs9tvf|`RFre6St
-zJ<zjpSY^}2W<L^e8v!^rg?(qNvN`4bWt5$TL at Y?scAQoPNWdK=@Gf2aZg9Ar;-D3A
-zm}lV1cm^1fybdvnfE2ap#%mZ%LXb_?jm{1At(1t}Hqm);$69fKkWtkQXl?z21<4RE
-zG6TbR9cbtgH0baTsBgqF3!&^r7G6XAZX(ot`b!2GuK;^*bjO+OL;~(2K9>=f8icx^
-zQDJC)to1Ho&oV~g7qMu3*IoO%=itN6)x{T-W(7(pxeH3#S%hY<tbT)IRM!uF_39n*
-z0<oYb1H+1YXh<bppr#SaY{c^%;(G(3<_!WuEkHcaBL24#(_F;;G-6XY=qdwe#`Dk_
-zf}_g_P}rlCPtf>k`;W>8Z=6E6 at QYY^tSU;q^f{*d8BF;YdM3vld4XY6((--#mTia3
-zzMB0EzyCm29P48UYfOmCv0i}t22fA{T0Onx^u2~SRUzcv1D8fXhbe$VgEyf#MnP)2
-zv^+Jv?6`vZ0z;b>`>wUX^c>bPuB>j6nc=5ry9Op#0V4$MGkbpawSj$4w_5rDf*mR?
-zyNCqdLF`HfC^?kVZO{J};#`A}a|X^crH85Ux)k9IA%kJ$(G23^Hjq)U%dR?q{^NI8
-z5{8Zu!WN-p+;YAhRzXw at mZ}*?E-t*SpyJBr#JmRj?eOs30fyRJ+7QpC0Z`7>^nMRo
-zPB29#&`gq$xoePF(TH{^qOlNBaX}Pl9CBvL7K at av!j#AnisVQI%5r(@*s0VwAq7i8
-zk`YPVOkKx~=D9j5`QWC~3t3IiGcL5IoNr4!^9kmDbZryFr at 5I}L at +M_`)WVKZD;!!
-z`j?|Kwxbgqd)*o!=2A;<KkcE19OTx}Um7MLGXfAfOGHow89$|eU-6*-5EKpzOfzTB
-z)YH?OK7BeIA;C21q)C(d^~NH|lrdvPc?4z%i5mz at m<ouR at CqAq3mWqZ&li`Xt&GcN
-zQ(|5N{S2dO`WRa6L#_6r5LH2^1kEV`v at 0C|Xr7K}_#r~7$XFagKaAo2!+aS4goPwn
-zgy7-f!5G2}+PHD!hEpGO4#LWrKRf#>Rs;PEqig95gDOzn4Em9};{`(AMITrU0L(;`
-z9FcL82h}ry7o41&n3kBB7{*XQK!CvekjBPFHYFl8(9baL1f8Kz8EUw*&mgDxHX!Z|
-zeHLhzMsG0xT7vcy%o3tiiQESEq7r$0whq)lKf~OsbaXC7D0yEWL#0ih5Ziv&RN9b8
-z#s7^uXU?2q^C4IR{S2?a?z2OqU40C}vk~__LbpS`rDMmA!<$3^HF4s^sZ*yy0RP_z
-zjqz3x*Glm5*=kS&{S1HpM7K7fAxBXCEEHT*ut}|S)PB!LnD9izbYX1|LKWrZ<;RQ}
-z1C<T!p|-X*1jLLT3tr{$30h9*_c%B>hQB=WS#WnAKYq-HL%at18Nxf>cc824Q1=oP
-zOfk3uwa7(n3edR;w-9MVa48{@5W)wgrKKTo80bL&8YKADgkfPol#H618ej(n;LK>l
-z!|F4h%*n|i{`hQ7r~w9s at T#o~O*(_R6{DuRQNME3co*tfg6fAA3J3^d3;`n~3?Li<
-z6y~D<SQs$?VT{K3@#7T~6o4VN77y+y1gYUh3r#U2G{(G-j}IHmXlr0FL+stRThPQt
-z)Tsz{E<$PfsC)6x8MaZ-crs$dU}8r=1eQ6cH%*x`FxUqp1Y8g)iVgE&ybrjbb)7L|
-z2JB{JM2F?UT$7TL*zt&e2Se;0_gm4N%V=otfWxb}TZ<e3^D9F!!Wk at K4B=-oet`q+
-zDlmliVtpxuk3%FknCP$=K_@;wzPY)1wB=xB{o(BJm-^`HLGQJq)%U;oEeZidKnyd#
-zet7i%7(h6JK{ED!(5ONjFhr~3!$L62sHi9=7{O3sulR=#AAWfZ_REoKfB-|rx2C73
-zD=8^4(qjaOF=U)agKZPw4>4LM{3uFta`Lbkfir9sU$SHg^s6skykPuXcAiNMjFKVT
-z>B^NW5cUbyg^|Q95CaI~#y=fTz-Err)YM-v!bZn!+qPw9W^UZL5gOjkPIep=6KsPn
-zjh-R)_S)K7i139OF`OZ^qL6?sV_V8-fp{Ja6 at DZP#|Y~g at O3CCD9Fvt1%_}#__4l0
-z56OPPv<CiNhHz5|`#gO3Fsv at XvII8d2ZrFRK#zyx`XvMHD(q&0-wA_3Nq&AlU<?lr
-zS5#Dlt#XO^)w7rVpSQPPSXda-CuU##wFdqIL;O~-!wi1l5`M3ZMx%kd10D=Ev<H9y
-z4H`+<iweEm>C>n2y=X8U3bc!hi{ZFq$BsjX4&@gXiTb_}o_74pm#_Gp*%=}=@OLmA
-z`Z*Br|K`mbI1asppMgD1uuB{^%v4ubL*ogZB-O#&!2Y|x|Btq|pST)3^QSfN|HJT4
-zKNeFcEiJ`{i_nW^XVcf~d%mHmsXwPp>sY(?pN}3f`w9^J2v$)0k1~V`e)#YqbgF;+
-zF(~@5v-4+0#%BuUv6@;#KtTP=m+UxiX5YpCG(%?324>mwqp9ijn>U}CtFidi|89mX
-S4u at dz*$fF*)PJ!Wg8U1LdkXge
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/branding/messenger/wizWatermark.bmp b/im/branding/messenger/wizWatermark.bmp
-new file mode 100644
-index 0000000000000000000000000000000000000000..03352038cfaf2532ee6cc997680807a3abcd5d5b
-GIT binary patch
-literal 154542
-zcmeI51$-387soFi0)YS_1W5?4#UnUD10+F$dvOWw?(P~ONP at d-+;A=4mbMfqRA`G+
-zpymJn-OXh(*`3|nlY~HSKTDXM+q<24-yM7N=1skT{hcgT>cb2FO5xvD{Ht!EQdy{6
-z5mKqf;`2L>D$PGlgu*{|c6LRJ7WMV@?bfZ^i1a!Jj~w4=)Uw8-c2*r7TVeF+bU5==
-z9jQ`P6`a29W^TIqX5-B_8*aQ=fBjA9^*8IjQJ-tCy;*bhb;#A%tFOFXb>;QS%db~n
-zdcES(>*W_;FT419>4jHI&c9lW^W3XN=Uy#5`)a|NSM$%jns at r;T%1WS=On(Io%nKA
-z!poTnFK5KRoDuh8dfba?u`i~^zL*k|R;LthYisL5g$mWGRjX5{PQ!)`8=g+bh+ZRR
-zwip>&Yt)enqmt5rFZ&4Bnv(>eaapCo at J+Ygs&U^)Tijrs*0=?%ot&J!y}jGEZ98Ph
-z5Fk#sqxbM>fg?A1kB(%8pU&X|4d#kjm#Ew$46J#$QMARS8%5jT(w)}032S?M`|{<>
-zw{PD*-Qbc3^&2*^<%qS_N1aG#tlY=B`!5r-cJ*i(e*3Lb+^ESft66JtUwB0;bJXPG
-z%6yKfGEY<7Xo&s&{Ra;ooSu{i4j<Qg#42?~oh}Wr!lx8zvtG<PYj)qwx8G9SXt)KH
-zxw>exZMQt`v#Hx|ux4?i;f{Z)uF2D;?H-zrNAS>5?S?O{J92-8QHkY8C1td;Sm$kG
-z)`$ta at zOBd%Sl%)b?HVwEmc=79dV}%>S0}n&#gaVSH)2Y8I3QSo|3%|a#=5rf4Jq&
-z+Z5cIZn?tJtsFPH<=UP(Q at YVDpK7{pd782wICONY;j6tzo at 7OuVZ&vEPjOk#I&cH5
-z#kesFV+UfSGRG)PI}l5*%rg#d^taRE=rMF!;}Kgcj*QQ+WW@>lYGk5H<tfHJc4NZU
-zyK2^Qxapw#+8Z_QE1GdP#jP21FQb(??Wd7(_vx4Fakr*2Pt($kUYQAx;K9S%4qaSh
-z#9_$ob3Co=YKmD8TzGifw{HpV&7#U&U9^ds#dNr55j9Kd%G`Jzi>W~O9z3qu at C}tm
-zMt_coX_{?wG!nD!GA?}kw{H!=4V9W&tCqTSV-%(xh{=|2sMOS2HHzC5DmCL-cOE*s
-z?ub3*M}3wBnNlW!EO}dsSvT*yY{z&1sBz!byL2nZ4Grr2)Rj5Wpqdc(Aj6Nr?T5^*
-z{@GU70?OnvTcM6(*1m0~g0&bo2Ho0mH&vM5P%F$sQ&;902e$#Jg9i<6H*|r|h+|xF
-zeb$jVO7;@7u2OHv&hOQ%`M7Usv}zQ$W_~0EH|>^_%ABgy$ovSIB4H}?G%el1`Wyp;
-z2L}ya<T?C!xe*Cp<e96&U@`0B6}s;F{vU#SyQnfJMO&>zH63nr%h{fJ%5)gfsu|jL
-zD?~jYcu313ORJ7J`9&h8nablmM$Fp9EnxS(e+<B_eD+g40ZL1E^6aM;H`TEiJ^MLO
-z*U at j_;K0GlD-VyL0{Maiu63r1S=%|(+H>!pw8otdlif0?K{;T^%1R at mzF@e5tQBay
-zK+GC3+ipD<;?|79*q%9^9}!gM%1gI$+=fku at mU842Mu0WW%wz9D8Beh_rO(L)**@a
-z_x$jW4&1a`o>3>e2Z)XigJyUQJ^aOE<z~<$D3r^3-odMTfBXlyQIn^t%mt;}M7Yyv
-zvYSQSb>R3~!*+9pkVztov=8I5p0FWy-;e*u;D!cOt3+jRb0 at n~nX)9S)cCdyCY}8p
-zvFE$~nxn^n5%q?Imm3~mHglgvC8n^4E;+par+22p&9!adPKPZr5$++|Z}wOo(Yya3
-zzri724Ufs>lu7oBb>G7+*ZpVjKJe2!Ep9a2n#z0^8HiCGOY;1PcseY7CcD*UsG`a4
-z$<fb(!!H9g&Wgh#%#^7FO7!NNEA*Va<-q-S#^C-Wliiad|LVW~ECG$bG at IrCBv7jV
-zac;TpJSy}cSl?F{ZG%g93hvYjbKzw7CAEcl%4GNXWTQmZ$Xvl>_rz0w^jVuoK_gIR
-zSe*H!5-2q&g3G$?pcRLHekX$)8q}Sl%A7mdtu<wl$E}ZT19!4}+_5LUL*iJ_X4aH)
-zav+w=x_Pe!habE%6>hF=19v(srF2sbD$kTffP3tb2fbEB3qXIp^i*;l&81r_0SoJD
-zV%&b6XC8U*?(om4aHCtU?wQlBTJrpecsfjAmndb*!o|(CZQxFa5!;3_2Y=|bGP382
-zh#ojKT{8Uby6|YhGM&t<1ro5buPtU>FKFVChwqHRoj#M at BX{5Gy)qJKuayxLcgI=#
-zo!wg?Q-YkDFKrwfh*{TYI`Sx3KYWLp+~Cr!#+_!9-Ln&4jM#Cl&#K7YI2qinC+~1{
-zZcK7idT6ZqWF=smvx%5>mAb*l9=(^r4V9X>GUrZqn;bW$KIbGp8 at A;_zmUkjt0P(5
-zfg?BAXRAZA!)DVQh6L<gnp5G>KsldY#~-~n6>b<dh;19V(_w16M1d*GdCh8H+EqLA
-zYEJxLLpCM#4~fLtZ*>apMtzrC+otM!nE47MkR^X>ikJq9SLl4=m-i{SQIl)B<=UP(
-z9dwh at EtnrsY|6sLEx)pRcFb>sH^dKE6Gd24+%?<Jw6GM~x|bRfV?J34WOeUA5z~Ns
-ziPm7P5I1M`^Sggwax9+gR#>{FaL<bTW$^l#;I&Z$*F>?nEBkSr1|TnNHqBv3AX|}c
-z6fq6tb at M;@Si at Rb>E_ at zdiGOLna?=+)8NqPLF=M|aVF#LyYgg7pFT9%f`FN?Kmyr$
-zrld~JjZQszFN6Ca(W)_(d74gkPdobUkkF{X>!P%*HMsjMJ?2)LQz=p6f}EN!oyrcN
-z!l8jIS!+i;d4KA0YTOUsse9(hZMSmV#!PlEzxZnMf$KxpM}akq`|J4!oZSLwg2e&*
-ztaZ$A1ro?vVTf2z7M5O-zrGjXMz{P}+T&&?yH{L%F>%l3VH=``;$(1lp1#8|cSCWq
-zX-rn91_L)-739=>nY-#JDk3&;{J|?lxHZ#Z3THnRnz9hwD=z#!e#hAn8>5DAjAC)O
-z8MEF#Yb`dZf^d#JO@?o~4Gn6^!O`ZEm4LI)c!8|Q<$-ViRI^r6y7j at WW2vvk#TLw#
-zmY;h%Zd>BWO;KRY;`Z;q)XK((n_v=|yI}J%d%q`3ec5c9!;nCpnp3!<+j;eusNX(F
-z;YP!qs_i!6WcT$q%TE6~c1!%IuxPMmao6oI&B8)Bh-MS-TBOay!#~rN-DbW53FNIi
-zlNA>YZ$9@^^lu-uxSw#^ZsoZ3n(SVh at NjH+%;@mw(P7bA+$h=`BCGlhr)lE`+{$#B
-zcJc|k_EV5k^QCLU`CQR$KJ!D&?;lv)7=^JtbD}|2Sh^MBUKo9E?B?jP;n8EjIvMw{
-z&{L(ndvX&=Ba2q<H7oj$1*s>yOALxKpR5G(`7NOmV*^{x{TTcE2RYn~!d&6(XNoBc
-zH91c9+knL*^H1Iyw<UTUSTneXgdB4#)s{_|I9#U2p!o at ZY2B%vRr|&yrJK#BISdKp
-z_g^lS9%8nf|1tItHEYx2<}UROyZL&~(W?`-#*7DR2KRs^`<)B=bCX9SD>WRo=*+WJ
-zivg2yoB0YPP#|C>l^Yw_cHyVEryrznL#3wGsxhV8u*vSQ8!u)aI6rY~3{Dnz&sp0X
-zbJb^)Bo0?=F?H$rmr|xI#e*ZwCo6#hfvd$bM9lV!KgB=&5ch`(aLY_~Z at Tu^jD2S&
-zZHvLl;_f(Zot*>6Zx5T)dYu-ea)l~d$j at fe9EJo6v{=ImkcM|$`YGYh4=nCzQCCfQ
-z>E`0zc=eCzyA!5tkD0t(&6?mw(QYwtv6ZzqO$j&9tlw&#lig;%0tpms#b3S$)`@?9
-z;N$-Fy;h}`JU^mv_ET-jl04ZRdhzk}UGY<Q#!lT4!{TnxVX8`Y5RD;rn^EDgOVsJc
-zT#!@qrCSik11*ZuuFLlm|N7VDxXJA2+A}{*-x)g%pf%?d4em+XqP-dq<(6U^X=&-z
-zZQ5RiUhB<p1rl&;vyn=Y4eY*hKMAb=`WHo8T)LrSi88cwuZp`nV^=KB6x=&vCTxx<
-z?e#UA0CCvL+NbY=W6+?cTKg%zNr51z=1cc>{AIa&ul{`c?|=2heVk|8KxaSq{qS~q
-z<To?-#Ln2QW=(OAS%2KUWE(MDHpbSj#*o#qWKRk%?i4rX$$L^18yI0eSqZqe4`)S6
-z!~4E at aOUrSS={KSrRu6_G^pazEromEz1K at mUY@-tcGjL)7WeR#`<?SQrO)LCvSh0>
-zHtei+xlr=_NUGA!TiMNK(;S8b+&f}R9N`Wxh}n1j!P#g3D#49 at nzpM(2i?D at ZBW_C
-z?mgc<Uv%u;oV~Gg_QbNd2h7{*n6n-?0W>n3Q at ts>uW=Xhvy<J_Hzr-kZ{{nIK%q`M
-zs8rd&fg2CcKL6JwxcA)obK&8nx%*=0;AC)jpSad8OAYp+;&4tEzu8CbsErbDy;Y8z
-zEaWdb;FS4fCE(t9r&z*>Ie7EoIk0~I?-^d{hDwd9S?K%-w{-8k at nqq_`1$)|=k1SG
-z;|6OD?l!>-t*mqmqVp6CSQPPtcy*YdGUt|V;AXRF4nqQky6)z(K6LBh`4|7{i(6pZ
-zu<hyt0vfDY+>JU+<UW**EKs!diUjoz1!BJqU at gWi_F8Y|E0BOk_r0uyY54H1M;BiF
-ztHq6?{Y>3Y({|P9D2$YD(fkN8RNH*v-lBtX3lGLEI1ooz<L{ikG2V at W=~JWvh0Aqb
-zd+t~2*IEv@^vZ5QPR*AdU+?D%{K)NJF24Lv32w}f2xdP|J$|?0^sU8*;uhg#aL?Ki
-zQO2_?_i=1wsj59UUHMbH)Hm5H3wI$ucV##A+hB$(kU-&{e3vQ5?mh-<18|@E<!xx(
-z)g_1H7UQJ255!FkKjvPd70Z+xu2d&@^NnW;Z5z}zId78!va(x{Q}bov-bc7HKmP6G
-zORqGnd8Ipvs9BiGoRscUk6x{fy148}{L;g5Ebj4Z_BrSC<35Outlw_h&hK8c-t)u@
-z`ME2*)mwk2uFQeENdJ at Ola)Z>-bYz!)9{J!o?L$YpI*36{QNBB)Y;`n<H4H6J#^ug
-zY&m at CFLMK!(damGokG72oR!@?uk~y;&0$EOaNlEG;h+5e$(7gtU4E4s_j66pJh`g|
-z4XRp+swv&ae)wbciKG?B;=!85-FtF~t$lUwBWR?xO|@Z5k5KP<;+5U}(#>1yn^L;3
-zn#;AgT022y&IV51`}OLZ{{*<vEk7^9jroy7cOR`jk+AYuJWdvO`$6+8MN4Jbryz`7
-z9cS%2M}004XNh9m+=cwymE9C~#xKjzYr(n|mO==mPindI#SuTKSu4T4 at A{7bz500k
-zs^e<b6t`c8aRRL3OP2!vtD?V6anr#p24p9@(N$9yZ9P|Z7w&f=W1hf at 1xN6C%Wfco
-zOAt@%1Y1~fR#HU$`0KT|8rHnh4IK;4Gk<^Bb@@)n$%GKFW^gY*9P87tznH8brdavT
-zTdq8zivh(8`8i8{^;y}S)^bz+`=rd0`!O7V7eSUX4W|Qc3u{h$8vWC6- at N@#2KSl2
-z-fcg3eeKDFHDH~L8%2BZzKAkaItj3fFTLsy+5g>ht(%VIwV#S`D_+^HoJAVliE;|(
-zOSJqVAVrzt#tmtd81l20Hk=8FnESt9|L0>0?$@c>?$b}-Y)QJj?o<L!7Wdrk$K8u@
-z_WTmCZq{|yu?PQ1&3>xeZl*Hllx}6X(^P0We;f at lr3{n^D?H)k1oeQ<-`Dqsf*rPI
-zE5Tn<5&Phe8~=P1;KnEnJ at cgBUv7>+9~zOc4kuVA<DR-<pR+4xBR>{2##TKiY%tYA
-ze(uU{^_~<Og}J`cFzx+PMOYzmavOdGH3J%V)cgh~&#lw;Y$bbhdu0So99X~mD8?QC
-z<gc)p(;K1^)<-6=xW_Enk~KTWEglQn#<u$SHOIx%VQMElg2jM}{WfrMli5#?zQ@!5
-zM7^ySO@%j;x?SJw6zsIav2<SxOC9rx2 at jv%eE$)+QM764j(PCwrs%|tQ3+tp;vO(%
-zm5p60e^V at C5{6B}(nA-?Vn8u&fo+4j;r?0e=vYvhbN8f>!mY1ljK3eHPa!)4ZbQYc
-zJcVwZcR7|Bpp!B|llbWAt at j^qqG%`Mj=1-8Saias=mfCV;*M08?vBB8EG)dlaM_rA
-z?g5+6rdkZB2)A)7y9>16qFgv8xs$Zf25?mJ6@@8Omt|1qjjdQBY&hwcr?)?RB)G5t
-z^WU-C--pL0hQ}nZxYtL<H)%J9{T4S|s#2E&cYhPxHV7uW(N&XL`<YU at spne-n-n0w
-zPE|*__c~mt&$0A5(~dRtEjqJMpu at IorF7TWVn#`ipWgZK5xB3v{cz~o&CLK!&Sc!7
-zCu4o;OZuClKUmXmSj3~3YNJG+DT{L4T(9-q=`cFkP10cF)WkJ#H99tENp*@#;SKmT
-z2p=70{6*DDzlE at p5~}Y#=$@fa)2E07sKK(8?4z>OQM;-I!dqu?=E<LT{{494&AS7a
-zuWpS?+!C9};tn|yQKqt-zbPW;&O?_cJbj<Cpg^-2P%zmI!v<p8KwWG}m2Ty@$z(Tu
-z-;lvvUSrA)j{_qJ3UV`sJHC#d63Yvg=T!bgA;x}cOqle;+1H6ahy?Pt+nlvTFD}89
-z>}zaCt!=COw4R$KJI9jq+;4whd-;0L`3qa)6V)e!d)eNjZbbqGKP9-d&r);7rc+!~
-z7O`!Enl-zSpIQ4!wQ5vhF5Z)ZTe^W;kfdzx9g6fg;NJTvPRJ1bC=%B9FJ2gYU2xK0
-zLqPD6F_+{m;-)ZPn at w4Z^-x0D%DP(Bz!}5${5U1%1($Wqy$8F`oZFs|xGh1;n&6%j
-zwl|jx#|<?r*!+b8x1PDHwn5ccE=f&xr}fHiHc2FGowZ(G|5XqjN*@q_8dr?+kzCgJ
-zHBd&8C%<eAU-Dfv{rEL*O7aD5aDcZ-UTrMMGJKa+YBFi)j_*O4oLtr$jz{iHNZOH*
-z#NwW~EZiZRoWChN%geWa<o!PdhH6~g+=cwywVw+8Heh~)o&6MKTzhHZ>Et=4c(8hx
-zA2hgJVd{(oR(u!DsA)?vp^Udhin42~^$s3gR4O?KK_r`?T)yGBL7VST%39Wr97BT8
-zW2bf|Cb75&O<iFl>u(BA=`?8Z`DY(45K|V>>?fV<X4j91OE(uccOgG_sV~LNXRT?x
-z9Nar#4<pDHohzMWWo|H4DJGQh7w-=mV(}AQTdvDeNcSuQvWyzLa<eIew|y(1OfKzt
-ztT!Bw*qM|>ad!@$DerFzR{b+K9%pSEq$aylx at u{>kl#|){@li~e&P1v5HHH6TdyMq
-zoMdVPbWC`nfe at r5Z(xYMo9=EfD5Lk~)newbo%gtu<yr3n>m*d;iA~$`oi@{g<Lc(W
-z{md;Tlig%7pcuDyAwOL%B)zg*a<ZFj4w$^-3?{n=Y`pGKu at _CGIDm>SZ|!Lyg>od2
-zu+Gc00F7FLeXdKuYWo81#K{)N*x1*s)^`4gz4v7(YguQjEB^Y%6A at s&H8!qVJvnjV
-zi=MUn#yxy0GyBOkWibXfG^k2uKS}PI4c%gG$C=2ZS#~Vi4aT&rkhx(}wc;bZ80a{e
-zuq at M`qBV?5vz7Mwbu3&Z>9=#JU90obQ3oFCq)cwG%bK!B29*F<Z#)@Ux}uKvs?)%Q
-z*Is|13UhVQmbPt3>6uHf>{hQBQc${;;HKF}0e2}P=QztId&9iV*K!e)NLq?XmyFUe
-zZ2%Q`o~Fy~T!SbDnLrjtU*E4+jye38W>ZOk%X&fh?t&i8WS(VbUw!t5!(@I$JRO$G
-zP%U}=h<e44Xmyyvh5X#fZu!#9=6%A+r)bM$vV&;?r)m=m_B<>;f!nl9*<Zt3go>h2
-z at 1yzs7TY@O&{~l6XU*BLVc*bk$9`ios4$FrKr95u9Gt>VZ*wi!bobetT7|i0I!uh4
-zOm=Inj+1e7*M1s<n=a(1W~kI_y*T?FW}R|yl2Z<3DcrR{_x*qi1gNN?%0O9z+KQ!P
-zsxYbu{Br)TdvbV<v&yE!yBCps_B>7eg2N`9_(PmEg)z1cI)=;?F$q+u+3WP<Kkxqg
-zktod7^CL#%<}T#NT$p$|O!;ItH~S;@{8Xe$UqO!8OMBN=#rqyL6;PSqDc<vd<5z<$
-zY&ZsBY<fu8DWAXp at a+>L{^Vv#d8A&fJNBP@``w3c|NGxvoFd%pWVg0k&KjA^mTu*^
-z6;5_bN+9}q!+z^A4i$@(#9+ at dfRMqY??))Y?CH at yJbMX6>P at 64cfl4d#_X9C`L|?t
-zl67KAZm`Xws9f9FR+}Aq;NJiK_x;EJefRNyYTW;Rq`0rY{rBq2cbA^MJ^$zHGrzw~
-zeDZhPqd%kW{}J)SZ^yrTa^&`-LpL7mzjlAm<sWul_<q}&Z#O61*%)_oL-dVxk=H^_
-zTv>Va(z3(n7w<p2a8J^_oe8tI#m?LuGi_7U<n^Z}tUWPq_0cgakBnS;aM<GgL+0-d
-zp1W(nteyR)Z|gl}OOJ_R-N$e0I%a*Rk?T4PThn&%sy4wZTlHVoqR$ffy!Tmi31XDO
-zZJpJ(NT;p(GSzYa(3pb$E4Z6vag&j+M90>X4q^9p`HblGsY2GacGYv`Y3P)zo at 0)>
-zSsiO<aj1zHIGuwZDsECgd8AGuj6eQ66p2#lgvq6Q%Qb9yG&o#x;HkWIXV~P>VT?yo
-z0-aTHpWtqb6LhBEfEzFpm&)&F9j{On^?R?8nn!@LC4Zv at 1|!B7i}yN&T{f)j6xEzo
-zHq|OOofI5)W2!#YvchbV+iYZ24WBP=<w9sP<%o>FB~SH<2H-B-achoJeH2=JVX$1M
-z^Ww1wf1VNla(dj0X|dXADdkyEc&C{)1l4Qxg>1Pb>)4!M1(zNYql|crTk};8ZtWG8
-zk(~Mb1BZr9i~0k5l#m_03GS(BgIng6R+!+7d7Hvlo!&Nd=RFzqTDBrx(d<HHEp_5k
-z*Lt(L`wnyE<5s#;=NU)lCB1-W`?=WsH|ZtCtuESeFVX at x=0~`R`P?HZMCE~TM}I5k
-z#o3&Wh$4$?Q1L!T#H@?;KJ4r@)+&pf_K6A;U9Yk=1`P~JT73SMb}xf7udvZG-I4~S
-zo7Ute$DJ`*TUb=Jw5)1nRn^AE)7IA0&d$@`-ZM)UPX`CjtXVxB9lf$=_s)^S+sVm0
-zXHM^2xx91d_Rf>X$Hm1bZ(bi)SD$?Oe3T<*@0=X<%u`yMYU|`zwEJEy?!nP+E!Q{}
-z at 1d|!hMcQ4pFCmr?PbYcG#6|3dd4;-*tbH9J5gP_XR^3W-cO5ujyz((J}KfaC}$>~
-zdJ09{c$~+7hu(GU(O<_Nc>*>2m_xseKJ*J_RYvW9FmnITBlrCbH53e)hVTAy*sdQi
-za|&~pA=|$nvh6#}l at Ho-2X+ydcW}(j at t)!0;$5|BEl<x{US74ly=(dS)T&;+c8waf
-zYu2n?t5$8394tY7!%YT-qZ3XGBO9=GsO#1u#JSpd%$Tt8GGT}8zJ5KI&W(IXe4fMi
-z8jE`&wxnTjYin`_x4w!0g!c!G;J8Lanf39hSt~6MBeUFbPNYK3gA8To{Qm97Y+io$
-zPdMCz2R60a^UJSOZD+vL<fL at 74L2%t+Hj9Pcz<BnrC~d7k3RJC#8ZZ=#Ele-{MS)k
-z<jl{R!6{hKCoNIel24VAPkXLBXV075mw`(^Dp|GHz@;Zczj;M{BNMmh#Kk>znu^Uz
-z*oIrCpVoI>Qjg^k^z5}NrvHX>L$=)*x&Mdp$A6s?{ai_o(&3&KV>ur4tgJjywA1b|
-zK3|v#ZP0ry{FYOKIs>-$HR`sWHuJy@?Z)mJuUsr{x}yQX4c6*Sh>}ZpO2eJpEhqi7
-zaYr8ZSdjvn5>E-Nh{Ve<X!F(Kd%hie<k6(azl_hmVZVURKyEkAx@<Q$pBia)7?xCg
-z3#sk0Ahx341nz9F6mIAI%{q+Qu;%>l>V+qF-ojZEaAU=&z?~+o$;oE!Y{QLiIooj0
-z!H7G#pEfA$LQi?tOpzxqK<|+FftxN4-FbV=p$C(rOfz+&P^3W<IZpG?&Gtz%+6oiK
-z-qt(hqEFBq8KnvrbQ!N+BUYW-e&-ELSgBu4;xd=GN7my0Mzf;<({KZ~l78BhQ@{0I
-z8QE)PgpQ&u!p)ZYe(TSGJBqw%CsSDI(J&t2QkY{y<?ilXJ#7y9Xq|!J&A01xTal|^
-zb1q7$NL1Gi+D%(@{3fxE*afpjjRPMRx3(rvF5T-0?yIj!>0X(-pGIr)1<6|nl78Co
-z9p8X;m$?VpOxe+6`Kc6wGH|6o>bWv%z{c~#cHJ3w^l{p?@@=Pb{N`C(SM~O;mKL;i
-zBF2ER at xV>_OLml^DHWfmK(lV+Hg3K4hhV{x)?X7`d}ub2q%}Ep^}sgV at S7^=r!7g{
-zPa`AlnX!NN3yJQtDzaQ%^{(_#XuA|{RjTH|>TPHE4_n`5!4YH7_goo`dLB*u_!EX$
-zG|5Rg`nhW{j-uGz-K$y}9C9g%c>(Q#0e$SRs`VMaF5=KnZ;9zLyaA-(#xmi1|FF2(
-zh8wsA4L7>w{C=87!Gb|I>8Fj^d#m5-$ev4&^9O(yp4sy>_Ndssa?`O5dM|4`b(g{D
-zd##QQ4!=BN at Anf<{w^;%g`dLWOI%o>8T0b;G5H}#60(3^%7{JC^IS(IhOSG6h9ks@
-z;l|k6*J#pl`s%3Lbdflg9ce8a8QiQV)$P<n@@-K+P2)P19dUE|X&MC!wB-XsWBZ3h
-z*6lopn=o-CUJ2J?ZOYUcT(jexz)_pJFFk1heFz6qLgOxwp}v>-OLEq#6e{H9ZR!I9
-z&!IbRLI2QqZ6X>eah5yHIjD1v58n2APujHq?o%u#)vg*&UPg*#N30<$796n+x3Hg<
-zyp4raKaHzknRMjdfHhHIou`m~eF^#wAcF-<cdQyXAz;J?1Gx7NiBm&A`is7l$^9K?
-zN6?hefQ?O6Pfru$7Q+?CeAPg53-yXM`b^&x8TI5HHCaz_-=uNobL8PW7B}&(NpWkJ
-zl_i&MG6YjM+{u->WIye~E2>}_x+!tsnyA)e`TJ^7=_w4@*i|oBrlV)z#DEbSzh0_e
-zAJ0JO(a&=g;Jl at U3ZW)9<sl|3j_El2fVC~h$gps!HpCYM*(n&fwHB?(rJFbeV3&ud
-zG~AliMr^|k?>&Nk8r+`i=%<~3H6!9d at VcnrwNYhi=yn3B5I4O|!@ZMd^GSgt_2Ulc
-zP}V6g>FE8^hthzpZPltM+@?FkWW_P4#*0+pdw83 at HJV*dN<27G7Z7a2jeZ*O+LVG@
-z&wg5pf+cwrhN3-c+qpsOqWUa5%6%KD+>8&{*w=6?+u5 at PxNlNk-U)Q|z)f~04zp%l
-zBR3BZQ^FRI?Y`thtMOaw_gY#tV0>}!J{Y;!$r{ENFW)g`kplJz{`~`sTfJRuvNIoX
-zKaJMpv~;6rQ%5eT^l7|)8Wb$^<9{0x8Z~%bRPFZDxHMghwR0)lT52+m`xPaTkV!GG
-zK9EwkMaKjJl)6Mm4kcX%dX)f9791Q<v`uz28?vr?yP0KuhZHQ+$<ev7g)Z;bVo}W5
-z8bff?nw;X+tDlBNqe2A>t3DO!)6h?wu;=QK^-;i`D<6MT!r+b9X2!pqbn1_u%aa-p
-z*jTRKXtgd#fwKj1Hn}mVOgt)dtJ8Hs=Xr;vC=22N9n)|VBc2LMdjAdIa34{ojLBGY
-ze_yZ25*0d;^`vm(l!E)$_i*3D_S23&d}mBQEmgy<8FVi>`{%F?QA5{9wH_79O>o{K
-zZMX(YurcVmFb<ZnrE3q*kymax9`|RtkyyrFpmax+nhrDf3E=WCS43j$Gv;urrK5!^
-za2m=ydDPW7cvms{;HF&P$hq5Mfm^SBS}FyL{{1v4Sf(AhIecRjaF_JrhzMC|(tjPD
-z=9V#7f=NlIxlwhyuPjk*kiJTOv7lf*mA6QcSBpt)rtIWXPOX^jvnBzW*h!joNfIhk
-z&sMEkw{6?Db?esk>({Sr#34?t0Wl>}v^5(;8{AJ*D_9tPnzrFio(L1`(^g%2J~Aw3
-z#Kx$8OAlhHg*eTS`M3i=sO{7AG+2VkQ1j8d%QqbB=*+Pc5<f^LCRYJ}XzE&y-K-nB
-zrkIa9a32c~#Xsof)dZ}`QMYbggK3L@*|3;-JK|W}Y6mY&KTX?kEAFSU4L1hef{8E;
-zy62qyZsevYu&x=z-<_~%<z94}+hBtwn1}ff+g8?h6jt~eCKmE7XlN at n8Pj&^Zk^CE
-zz7s#l*|}z$<RdUJu#%yN_?N{oSbGjV9$t0d9;=!T*<#5vODI{fGjaXF?WeH~H at qba
-z8g7ij1o|}je%jiruf}an7!?*hVq;`>XFi3t<9Dei!ZhZHv?fPCjWt*j^p4~&VH4P7
-z at aEFBhG9v9SVW3qEIjiSZ(F;|ysir+d+!}*?dN*1@$+i|+Nj1`wrp9^&_j?&JP3>R
-z&~jC8J0B)+-Ipf8Hc}vjD*jUi-y)aucf?UAPQreg#t|RwmJ9l6+7UOSKBaD&NM$b2
-zr!9)TKRP^mbXauIu$A1Dz!-H_)Ng8YM9sXXi4Du6pZ8sN1-*JmNiRDMnp6zcOH}KR
-z2{>*sFY3wh$5OIneSpT%v}w}{h8~zMM;!%66K$s*8yI#|$+A|oXxyS*s$yrdmuSj}
-z`;QOATbE#kxImwls-Kp+;l{kDU?L1I?kDd)I|i)7ql;DSLIubMD%2Z6r at 3iOPD{5;
-zKTYsf>%4?HF|^qg{U#b#*mJn}K?&b}#$FaWbn<LoNZ8)qJ19ua8pgwhqOPDbJKP&8
-zHJvO at 4`LSVj00}A;f7;Xw&6bY_`N{EBG#wzC&H5ZX)De=9=ADqY<P6Pg?rHf<0hl$
-zf|F|dG at fBOHCQ4m!c4UQ5M=}wS<r`Mb>g=v+;oyi=ro|*sMljL6j=nivpZ)UbhT<t
-zgMxz4F)MHA!9}Sv5|-`UW~Fqc&S%KZl1#T;;D}GqPh)3BNM)X)Pt&+q6!g<(9=tSe
-zOEhp-ZKO6!5TCF!Uwr17)*SKNE52d5rr`!|ldl<pWl{GfiEul^HTV~&mW{E?TDwf`
-z!Ocg9)$Tl(jVEDO*IIsleui>Ze@`b?sT(RZ8ZS-{VixX-7wihnDp*jN%lFd+6JctD
-zCCw%^q~Q*|{B*+BnDJYphpjyd>n3gjY6i_%eo?!QfY#&!gC*?(z%*MCrWRWC^BybC
-zR%<iQ0Cf%Oc5&9Q#;0uAN?#dqNTJjjkN$}`J&37Pv$xipu4ZRRfr16Dx`@N%RQ<H%
-z?Wo`<Ib~*qr(l_X;`+p`F~D7~J--n_0)}rqM-9ul21~TzMz>sBlc&vkPb$OSA(v{j
-zUuZz}E|75EycNqCanSS_5GYi>hafTJGA#ZU#VzQkQB^q_Zs2BTMsyl1g<XF(d3)@n
-zZ877+Be5|G_tCiv1gMt?F%x05;id*ld<9Dy<A!+Ak%OHuR}sq1i#XEOwn|we4g(O=
-zue6(fT$~=nG;TA2x at gm@pC)gxv at GWC<n1wF-MrsI?sE|tIB*SFA|$pnUX*%8nA)&B
-zA=Lsvny<7D4A^wTtK}@N$2_Tg(RdG!@&?m3CSO<%V9#^s2&LuWJCA`|+i>gbrztR4
-z+J5Kt^xX+lcEkX;Yaz~JC`iNBzUHF%U+FYA*I<b%SWvp@%m^8UnY^DSFIz16ga#vD
-z at eY)ul0fd<o=uuG2?z*i(4YZKO;MwlQGCd!NB&dp$_0|(E<=~8_Y$SJHCsXp6)gJn
-z(?XJdoVqi1>W-MM6V^$|q)ywJYp=Z_E5cB^X-&S2F<6pPu*^u)ewwVI0=!jV`HVtm
-z4%kw;Y16<K$p>abN-I9(Y07*GcUUsXbIjoz_xJ at IFtWG>{WRqUOS|vAopa#yG_c+o
-zTf8F2>Js!}kTC1$cPaL1V#9J~MHotVx~<%oks<pLmU2TEC*xs^zTsbe)u1_ZV69&%
-zWe58><zXmJxic~}JqQe+zfJ2~HMw-_)lXv$mNs5|G-Frn^j)#R3wKHBPb&EiU4K2r
-zK8 at Doq;v~bgz4y~$reN9QZnF9c=6IXFwdU78iTrdvu4edp)O at WdeEPAE8C65$_*Fr
-zXnywDd+JITJ6sstPg{8O{EXePz+Kr_(s#$$@Uzs?7^PcaST4UJ>=X9WsQgir%lieT
-zLbkQ_YTVc#6JBVwaX>>}LfJu|r96P0Q0Q~z19P`V(LGHB{j?MXi^lpim4fBbdrXc{
-zecI+Lk7w_Row+A=Oz077iTyPSm+LH;_f$9B%mP69ei}RCPXB&dzx7v3Rv#=cN%E<U
-zjaSK%zD=7305mzk8cjAjX|OHU30yg1awlB)DoGW&r at VKM3(4+P*@hdHxqLs3od{cc
-z;^Le=v9tEX`nHyIpEzLAF?Io<*kDPoep=djSQ1DZ%OPO`r^NmZ%kYaAuj}X6OjDHk
-ze}KEV>>+r%{3Xn^q--)R>^MHRL3~r}H^8l~$qnkKZNKsB+<mcg_Qp=z7UAH?e*|1`
-zgx!3dGViJ9%KcB$PlL}KRF6`^WJ?qLs1zwur*UIB%7i^Cb9BjNXv at Q8KOMaFuGGw(
-zjavu%Dr49b(r|;8V=lh at kJjXv84*r|Y34np^l2+jU782h`(j)4nN5FF5a={ETrlq`
-zSO6&BPZO-%$Dlh+JuG3}D_ls)IB=%9!|=+(qjrM^P5ea%`eWP!D|w4bA1qCoFnpTj
-z at n}tx!3M0HnmD!!!)am5aoK8V<#p`NV{A~x;$|&auwAT_!P4&Azt7(vi*xp#nB1<M
-z=>R0d!Lja!D}S<v<${J=-+r3FV9A6EmeB_vRd2UIW}r%?ifIma_uBRAb0`z+T+oQD
-zSFfHl>Y_4yQ$C7*F4cKJ)t#+bNcJ{caoU#bM^noN`cDc)(WVWzSf3`<Pg@;zWr2ou
-zyCITFQU9KcI0j4N6=BK!w3LQB*?$`Km1jbOr4-R=hHvnPR;TN7B`)YOqAXCLX5G4t
-zrD)2>W74yT^dU$U_Y#}nu<TO8mR?zX=Mm8O3+UW#hFj5=DVtn~8g5QMO=GaM at 9rOq
-z4#q7!5I1jMOr8Q9>q;cU%F26H!UK7OB|$$;e&xQ5hb69LbVgzUI~)f|wS6g))J(*?
-zy4I*u$4{Q7{HJ96B}H3jYFke}EJzZ)L>o;(lYmV at zWarZQCBE#g$kCnF;^EIiUaPB
-z!<Wz}3Ies7k7q57xduyu1%OIc?wiCDCR`n2%%ac$)y1Voty;pe3~&Y<(2f_DIOJLP
-zU3*z- at wH8nuN_-&5u6Ub^8`4^Wy|g}=x&2-!!7KmB^xXq`u^#X!*Pobp<Ku2b>lD1
-zKu=(K)c1UYCGpDr>u-qqG^L+*N$oCApidL@(*y=f^0K0zf-)vGvb*q?9SP*)?2P_Y
-zL*+~{@gaW{D^|=y;-D!M2jE~cheU#{oSQqg3KxJTmzLQ%PN%bGuXFb48{k$q+&cSd
-zzkOJr at XgZ0alqYm^fG~P=p|h4z=%cOU`fzVlUK07KFvsjB{(L9m8Qb7oHJ)NZ|?^3
-z;1qs}W||z08#gW_eZb>7x2p+7sQXu6Q^B$UONV;d0 at iUsBhs!MUj;OK({b!aMr(3X
-zx&;arOpc(RcJ#-;mK}*-2G)mS^Ly~8FKukAhn{&TFjx|-+=oLgR>1;odCJU)W<^*^
-zKaDpLhRKms`ZU>zu;B1pFf3Hk$A%<x<nZzItgn!x!rKUIUteEo)P=MLv?41zY$MC^
-zO$l51IMiR9EoigUnYHO^?taA88VtmyMc9ul1-Gc5Mkd0-lCCd58V}q(#_`R+k(j`q
-z^K}|530Cf7(4DHECY}i6d03*jr7VpxTLD9HZl^RwXvsE^j*i|{s-&WvTp~^Lf1NsY
-z+@%lJ%|7wq3Nu<Pa1f`H#MpaJlA=uGt at 3b8Ua`B)se8Yww;E({i~DIOfBt*rvG^6o
-z;(@zh5sqgGB*Q*y?JZY+g%OKhhUEeUi`K)EVFpVvFW_ss)%XLhiY*PYW%I6B(N`f+
-zRK*4#SkdVwaX at t-Fwf||B%W&z3?bW=>Q8~n1neYqXoF{LWVZ<xG~A at 0w&m;%u*TVU
-za){LX)?w%>@yh+Z8e2rQue|TIo4K<J79}h9Q}xrN4VK0qecZ6`I^`?-&@NZ5>}xPP
-z`o%_y4;ZTy<Q;T;L5L6E at ts3<zS*92zP8zd!etQCkFo}as(9OKdz1*$?i8%qdrr_#
-z1M8?q&sU#FSan>@x=;y at YgW+Dp0oa*JAbniVF!LvTc66W2n#pJ!;-*YX~fR&ss+vA
-zyHHE6rP=q>#ihEpcYO-W_<%y%nE67hEvC&bfth;hcdSomQ%l3>T{{G>&)O<n;b~of
-zZ$`B>;TwuOrQz00j-a2m{ld+V6A7!2#}AmkmOfe#=rt*f>>w#v04U#2OPLwb$HNje
-zSn9v#T)Dc#l}uG2wa{=DC;(@{^%bI_w>8v#G^*dYSsmX-@;Aa14eNmNiw<pe&b*qF
-z_`IagK!IS%rG-t+ERB{aq)cwJuf|{B*S7bZZ{GfQO|vUB+i+w1 at 0iEW)|^ZT!FeK~
-za4G(l$Iyx&{_!PN2?<t&>Dy0}SFpf7jkvI0aOOpqSw{;gFw7u=!pvi#LN)8uX-M&L
-z0*xCt at bj<Nq-EV^?P at jaTr;po_2zxOTLgQy8eS!6Or<sxE3}<nuHBq6?H88rw7f*8
-zkYZgn6zR6vqx%l`9{b#Ssdp%b;|^<UPweiIFCS()YL+iw*T<(`{rV~V!5V{h5$gQV
-z1`~yF^&pAekS#pzYRqtG8K&Rad?R-%#L>z3@{4!CO*axHr5i)A?dPtqJ(&R9gJ-Yj
-zzH*2hGJiMMu$(nm(l*@8%6+juP0&wEQLtzX%h7Ppi~FO+u&`YD{H0PNh=;96v0}A+
-z>ou(3q<NiY9jXWP at M<0mb`{!8E!%#6sm`m4b=|1pwO_oQw7xN1-vUUFy}ehiTt04Y
-zHA<GORk332ym{U7r9Q|D+;VuhAo29l_N$@#QBHm<tc&o6=j%_N$L_JTCMWu|m|y-{
-z7m={;R041pDa|j``8}GSeDsz$)DkQJ6d0DLC|ET8G{K56`F`4%tygQdo{6qLm4JM}
-zDod?wWx6{xnU_6qRkl`P`M*9$c7E5Fpz`~nFqBUc{nWyuij7T0d;7B4vXyjlDvEcw
-z&yq-~?LMvDyBG!<-?Fd6S%8LQbRE1HtiMT(d;8g|p^*u|Jzy$^=bROJh#VhsluUEW
-z7%VC2r>PYzA`eT86Mt_%Zkt;vem8 at gBul3zcAgWmwhVJ>w>@{qT{v^J-Ik~G9_7>w
-zyHm=#lAB02a_si&QVYf{b2iHoxIRmZO$MJ9Svk9tdlYYV<K0I!ZcW3D$~@-b?;D~L
-z)`Rt_xcr6q)n<{>?V^9xdcriVhow=Q&ieRIkW%}zvZ7(jJT2_1PlH&XCqzLu44Hx7
-z>T!rBL*IZ?UjB5Ug?$}+zm*14CSSBJ)t{T5<9B{$ac at 6+X=79ZaQ7Ish<iUG7wk@?
-z)7<ig<?;#^47!OvZF$1uHpADu7UGZW_{p&Fw94PkuI_x2JJeli3c5g#L*g at kw|)Gy
-zNmPcqZ?^KWt2 at s~(D=H2L;l3~*hSlKzWYdU$3A$nDLMhH*PV#TotHCjg4EV(Izp{J
-z{X?xS7p&YDF94M9r)|FVdgR)eDh-BV?pwDUr~oa!tv$NhH(1KbBv*%>2A0j9>h848
-zQw$n0`Md1aBiS_lQUME3Tkpwiri=+&=Hk at J)f)`F_5LGpU;pR7?WZq<#UucChyMJ5
-z05%ZcbL}BrM<8XeL`Pw)3u|^FY(?DtRs&b%a^=@!QUbKFscv1okG<b2u at Lfh-KUcm
-zxq(Z~u*iI!c1k7HfOzY2gYBDdG}UQSp5u?&#<tp}zh41&%>75<v57d>9F25zs>@An
-zk1=bg%N;Ti#yV<9)lcJjSlapR%VEopm#^7h-!2VWG3zpe?3=COiUJk5VX%z+mTUWM
-zTqzA-6We#ek-&Z{t2P>yzgQb3TY_2@?#|7c!I5 at NR;zgXFs|GibK{>6J5Qh6tYO`v
-z+XQYF^0^1Z{`wl~Q;J(?ST6Rkl)Q3(dBoj-o(rH;<^Hl{q=lzt-XL4=N%nyoWO5BV
-z93!boeI0!OnKN%2{^)pF{3Ehqih7~bH*Z3&yqa<N+x|-<TMS<B9Wb#_xvqjyq at _zM
-z`3%bBUFIW8SB?Q{o1QacfBboCT;i6v#8n4Q*k|E8#F)D^TD_E8*@`ftPuq3-&%yKe
-zma5!clBPuCr7p-N``I;GCX*NP5$bc7E_<b586Pjh+9hZsH(#rgo~Xx?sWrevM?_b&
-z(JxwLZ*13eja}ddlb_ZVI6H>8<ZH4s>Gan4MBr{5#Hr_zFrWGZl^86MZu#LKUW^Ml
-z;nR2+%ou2<6a~};xwVbgWV?X%3iFO}v<!|k{m7*yU#YnE!XHHEPqtJbGxcPZliHjT
-zdz at W-O{4+SU)zSu6y{Xl+iV-~d*gF9?A(@+xODd+?kX)r?!EG(VBS+~Sbpl!o9UZl
-zd|QmQm-Tbbg>I3hu64=&24tKJtJ9RJ)Q{(B&Yu<9aP==Nh!Ef=tI>(02^iO at g<$1l
-zTYIj)1ogU~t5j**Yx4Gl#9Ds*F?hG3OT`mmwBe5X{oR5+NliLT$(F;H%TX>81=%&o
-z#(R?Tf-KG~I^j|{(lp-LpRZR8yYZZ=4%mj9#SP;b8_$X2yqGY?w&hmKVjQ5w%eI~$
-zzK1(e=<Mp3^xI3pL>N|to&Nj7>f at JM_MGD+;f7QWF=iV{L2k6%_}rn%&e#1wnquYt
-zxO3AL+&pf(`$jv(lWb*2=66`@S*tRGYy;Mt{%js*)8>G6=UA(rS1kM9wrI3PoI+48
-zU7?*g9x*UP6ikGL$KUKYXo*XHMTWS--&7am*4EyWZT&+{m{ZK&a&ee260eis%<adq
-zmWL#XBRFD;BdE#gDkl@>-8Nu at P0()ZjuBR0U$E?R3y4$BuP>=Al+MmnuF;E5gzdTX
-zeb3RW+=}R<$z;0O7Fm3)O7*vCxXh&4Oeq?Ab<zaX47<$Lkh9#$+NK(euZS6~05_Sb
-zCpEc^f2gr%i*45Jk6Cp)ZQ1*VWuMzpr^<z2gau{L%F1is#cz+_eh at r$eX+8Nz9RSq
-z^<{EFwrRG`*xV({2h~2t)EILKeh?E|hEX%@TRH2`7v~py&0tLgF|;ESxJ2hKXt)I_
-zS9%#3X5HqXRp&U%p4X({3gRs)&k!e49OLTNtX$Qu;&_EI77i%L15l8aW+WM<{QYR1
-zUAyf^<&5b|!JUXPjGAHJ%IV9QDaK+|Oxcs=PU at A6$=e|bM%;pw>$q&W&8ovmOHxHk
-z7hwTq?Pb6Lg}e;8&C=U4UmLW at HvT3n$W#=l{{fnyK>#L{^dkhEJMA`%n#{NG6sa>u
-zt?6R<WY5_^ZCVL;++ at q?)cY9H5jUG`sjzj+9abG9EPGt$LsSU8*A0~oXMwgj<$A<e
-zcv|FXX;pEgjo&J%#2X)v(X at aI_@bpImI;E7#FtXk42yU493z%bPM5}N)5>J4X{m<W
-zy4gDZ=^tv{YL`{VD9fH#)g3KUoEGjJkN4t~>y829+<}%~4YO{zf}eP)Oc at l<w#bG7
-zGU2zfmK!9Nk8{4JtUGS0hFd5r|4^%-J(itfEPJ6LHVtC>I~LVB;{|cbWnwIxnpu_^
-zY~5g~Fxdt{RPrNa9L<(i6M{3~r?M37A(oF@@z%sbgBZz6HQZKB*Q!r7;=PugV=a4K
-zx9EK<t<KgF;&dvBfv(=N)Br2rh1%4TG^fj7RMZ9#!B?PION-OCKwGiI%6j*rE1qN;
-zZp+sDEj!0s^tzE&d{e(UDu)K*q)NqDI5xH{-q)(m{Pagmp9tfV48__y7iTqk^(G_K
-zTWQ>X2h&QKhC6)_)2FD450N6PjkoZ!aBhx@`jeDmikJq_4NJR1YCyrabl~X!{W{H{
-z3*2NHZb~7Y0=}Vq);2XP^0&9FG{&mYN-F1!5WqY&Dc1&YNrSKK<*Fas4O*f0{`cTr
-zs+wFh;!Y>Tv?lL#CKYRkdKMntExe~#`h{3FS(DLDyliQ}OLset7mRy4x8+PLK%RZ3
-zZYJh-#Ia{eKTR{@rbDpwX5IUiDrbNyXETeE{VZ$E&1i51=|M;Rld#4^xvX;q at +YrH
-zEk8_l(@?Kxly11wk9GG87VRS}Tkf)Kk`arrfHJ)_32QDm10tPx6CWtov$iLw7d>fw
-z_R2Kes@^x#@a%EbqGPN@(0+?%8!Y at nKF1S^6aj7n7 at 6uT*?9_5uwHrcx^|O026swL
-zp4 at Po9yEq;T~1rHJ!%oS<#U89NHbPxnTnLo-@$t&e`c%7QILZ5){76Yq>*fcCDU-5
-zinT at eixwRsEL!ZcXtGWquFv`s(^xtgneYaA)(&NZK~{Vo`SCg3<W8pHR`t4R_}Sx{
-zs#BaQXuqoI236zLU*w5dEn`s1v(xue`=Xp>&aj)s;s~r at B}*D*8g4^CcRR0YdrTFu
-zMb$Xui{#5 at 3d1fC0d9S{q{aQV1vthV&iR_CH>myXgLY3tvO6uW;a1AJ_YGCov#K_S
-zRn0cBqR0$kTC~#wpI*Od&08E-{Hu;yzucPLG-MiXU94}Yx+JNB4yu}cv9+|$*A at K@
-zXvIlQt`{1U-^^8z)(IFzm$|XN2*eFHpLNgcs?PDMR{K;<LUoEFGu(jTb_T$`o4Ycu
-z(~#w45i41rF4J(QVvW95$5>U%Ju1JonSr2Qc?51U{xW%KRrrIsBv$u~TfRS0vx}vA
-zRikXft!CZhs;Wbjs>M!~-x|HLpV at Byw77HBn<pM^A!gOFi)0ZiaYsNFER!{Ef)TeW
-zaC>IxPMhkrgoYf&@RM}Qr4%WL?>xbdIlwKb$;BgXQwbsS{0<DoKS at 8$zBtEP&pu1d
-zv(G-zEmQ=!1tadv!^ng=#iD at pFWNSFIg4M4m2J;@VwZ2YO(=mc^`~HUjIxZ87tJ79
-zYoE at zE$un(_38zVB+Hh`R(J9ZH%-4eAdmnwX2b%V*4S9ANA4lzn#L>aNE>sTl$Aoa
-zVaqO&{jlJ8KehJ>Is~H)w;+S&OCkZ3T+#<4K<VF{?RU`b8I3dsqQdVwHD1Q;gil<#
-zU%QJ6*~n4?x4Pke{N4;#AORF-0Hqwo0r5Make4yHIaZs at WgU9*BHcwrrs0P7iLkSG
-z1v$;+muQ#8D8;zNF~)FI@?D3re0Sdw_nu&(I&n%M)o|~>^LW+CGuRg?lfz}RkM*`<
-zh{|J>AT#(L+k)-I<=Wn%rrM{g#zD6lx2WNc{N+Vh(l=!D6zrA5W;Qd2Y1djgT)~|N
-zb5!z0E60Xn))jodhM!Nh$7cB6r`u|18t&77y+3gCr!}XN$c7pOcV^~G^KLw7!d(e9
-zL+<Igle;HW=ir4JKc8xk&BWyh at g@}Y at M(C$MY72P**|5)(bzWqX4Cv;+5kpUf)Z-*
-zr6C-3*_h!sbNYvf3pHZqhaXRN>#D_l{@FkKuiYV@*w>y?Z?b?5HO8;p;ZaiKe*X)#
-z9a8w}Qac2L`3k<67Pzz5=6mHmdHeqD4<CV>cx;Zk|I6n1GivYLkqM!iO%_%hifY(;
-zRLVXAnV7W+OEgQ|<hZj|<oI=T%u)C5zaQ`X`w_S={{3>_rE75E8>aEj4cu_NKV;V0
-z+<8;C@|l%2JY%qcOc*vfYx~08#C3S}`u)HA_`h54|Bbr$<F@#uEgBcT;TrGUOLiag
-ztkYBc6 at _)(7j_$FqCv!jd<8#cTHMw-I4<=2ja_-^>7V=0Uxe?+Z5p?(zzt9A-G<H0
-zl2yW2Nv15<@|rOLI0G(C$XZGhK6&|;T}eqh6O(o%Bmp<P_|Dn5yI5I{OXrjVp7~gt
-zYJ?^K4wwpej(Qx2X27?4|530exWgl313Qg{Yq%7wyd?u)SmmrFJL$G;$0WGz%5c_t
-zIOXyspz(M7qEMIojdf5~Rn3AO$1+*DrdB2LrP3synuN7wZq9}&Rcdqt<#mTo)M(I0
-zCuQ8wFlg-2yH7G3Yijyy5}G=H#7Nw^JM2_hdW&hc={c$Q=mlA`)e?Ush{4{(A;-=W
-zRe7djjrmHQbWD4Lk*w|OaXig}W_F2va9Gfo85uHT<HcwHP*r)RVx2y{GQrzo3~tM^
-zx?Bly`(Uc74O)zfy!V)FZb((-nTj=QJ0u{Ic9#aTMsuTbX~7m%CE-HFT817weMh4^
-zB{L&*(lb-Bh6Ag#V=D8 at hT(>;US(TN314y#_CgvuJ at nSwci;Z^Kd4VxRXM?(d04{`
-zR0c<yeq<PHn at 0TY9=P=D1q_S(@t1r5`yWo|PJx at K%5Q3BM#vm@=3$-w9W(a*(HA$W
-zAXP=a#|#1Mf`tRu9Zn#W$=~laxbFftQ<GzkJM*xHnKvu^bPnsw8ooO$3bqko<z5!_
-z2=Hq?2DSIvL-BDxJ=Ws>_`mNoH93nr^RP}&EeiKV(hE1bkyhC_#{XR0Y-G0Vb*j|p
-z*=fMs86o?2CSAYs>=kXezZ}+$R;ubRR$+^T+A~x&C#$NBRe6n2RUM?N)K68uhpJp>
-zN3UMRn~heV{$q+Y8&k}GT(N-h#R4W2Ri6`!22L&-IHgG7)FREN6=^=bu=<=)xW&xE
-zEoXbQnC;PWu1BkRg<8%l)M~zas|D_ at 7P<#5at~VU7PQ1IXsKK4Wd&QWD9~<gzV at 5)
-zcHHLDg+GI)7wc>-H(6MCvJedm<44?!wrJ2|<bX*TW}P+qA$8}ds*O`s309T=T2;1_
-zs&rdbiI%FO%~XXOs@&_U3RYL;tEzITpmHvw%2`a6y^tzfK2?_7D!c3|YkQT2l}gu<
-zH*a1qqYqCdhnH6s?;4e>*Q;2wN%`8%%hhR9wqEDb4SSYs)W5jj(4tL87xtg%(R_w`
-z%lQR^mKJCmlCS-SydAf?bl%Or3{H&}8wOYITj`?@$2N<#r>ne2sY_Yej;dk-YJ9F$
-zRJn?)vbw5lvZ_=Tx>y<edH($Qy}iASq^$(C%so|Qk1Af(D*4o{P`y$4S^*_J{R<SR
-znk!e;ELq^>s)`&z33UqRD<)vQN>y)xs>URh=TKFJp6c>g#7|YQhRUV9Du;)<=vmns
-z%gGeqFIcdk at vQNx$e`5ukt}NdhXo20&=dp*mC9MAa#N{Fs8kg>9F-7P&bt00bsbxw
-zm#Rc_HOkzjRgMK!b~#iQmZm_F=D$&>P$9539=A at Q@;C5_YGPeoU9)7#0=VVMm8)F2
-za`EEDbL7Y&Ar~8!D!WSMs!|nJsmdrV_#D=&RCQ*nyoRgFby1g4w30arX{uR?$9^W!
-zrAwDK3F|Z}+Qo_$GeVGP0kf!7xmBuyDphfnssg{@qf=C4qPnLFtf+O-dRpS0`O*$+
-zYilqftTSfOMkzL_(5+P}N0lnCO68$amDX1K3VN_6O~WVnF at P>xwk!p0lF}_-QOkeI
-zt;SJlJ34|++8v)qQ)^8Avt`RxsZu2Y=!{vk at eZJ&$(1XYG5O83-?g-~M0pW|&X`4;
-zmUpNEGA%NLGY+9ifkwQ+W9_0vi`v`UqiHBoq=<ZVE%hnI$_-Skh*6dK&`$z%oFzrv
-z0Nfa-(?n#?o?VKj&Uh|m8i}TdKE)hRA^{XYDas^XhBfMh^5x45ZYW$B<JpwM!os3L
-zg$g>ca&Mqmxq;ldF at Q23dPtyDsZ#Q+ at u`3&y+kbylo<BX7@$W7K=63H5?quzBe{ra
-zq>arNIPw*U&a{_bef5>Wtg~i?mR^0hySoE7+ECCZG3;MN>clE_10^d6lq^}2eS|rz
-zL;@(4I$28<ZM4Po5qa|Dv9q(Imx6!^t8r8v`SRrx*B*i=nlHr?K&xjkYiV7y at HuEH
-zq)M)Qyr4LfOY`_zC|_mQR#?yGm7*Gz;Z7T61WJ at Bp;tE;N;!F^GM|cZqd%!EbLP8*
-z5};EaGN5TS4mo3{N%#}Gu2J#I(3Jm3%-US8b;(=ub5zChl<_HWczAfow8)abu2P|G
-z1uuD^GM@@q<F!HOU*>V<kK`qQ8DTDNAV78P?CgxHUj7$kKE>Bj?aR>A`4Pp9u0HMj
-z%RJHik-P*jg at hgybmI^#24d)+quXYDcNf2aPPj=}qeOGZbn^K!f0}L*fDV>+>U5T0
-zsT-<Pse%^7);2>}YNea#KCcI%uMT|1utp^Vi$~0%d|nyPgsFuk2?cFfHICjwCY0M}
-zmu2*pQTMW}4Zv-l;P@=K6D^G~tnsQC-#Pp&Wc39kl5MOBbgAAKHy-`EFF**HBnvQO
-z6O?P^)i~OEv(Dr*dQV`nFU1-k;XpT=TcXh=GlTw&KqIM`d=#_BJP4g2gVGfWb{01j
-zFBoK*o9WLBG*XN18454O4RsuM+5*}z at P(C{lateDmq&AgsRW<~0Y_-PXj!HonFD4C
-zm?dDAfLQ`&3792dmVj9TW(k-jV3vSc0%i%AC193-SpsGWm?dDAfLQ`&3792dmVj9T
-zW(k-jV3vSc0%i%AC193-SpsGWm?dDAfLQ`&3792dmVj9TW(k-jV1NW*Vhwk%u+hb0
-zC^t7Z7Z(>eOfbd+h5>0Xe<gh+fRz+*D&iwL;2Z<~j$m(ZfET0mNxAtc21o#oI<dk+
-zL^~xyYW;-)&oY1IlS=^Wp-_rb=<-5Xj`7LUX-<F=34kVAWGs3GQ?7R)2L}fp;gmS6
-zku<M`R3hq6dk@*6qgwKTb&ff6<`g6e3#n4LN`%awg#<#&XqSM9BALut`#)f!*Ucss
-zRkQ@*lxVYGI96gAFpPER0?_ml&gh7HC{*Am>?u$sLgqEF8IUhc5=P3DEH{7_9BZ86
-zRYn4Ds%UtRq`zzqWHbq&h2<h<BU9m&z0mABn$faoPLEassG{MffF&yq%i>M-VVN at 6
-zR8;anFWtPShNN`T<pWf_V!mulDx9(xcx|NAr_jHVT^Hd51KKvdJj17p7&62|F!F`B
-zJq&)Kmxkje at o32SRHDnx!WD#N at d`iWZjyr630-}GmuYBO;l~D at 0jbx+_<VgvzkuE^
-zL<ecsV2<k5t79gD<^o&Z;2khti2?T`=zs|*lS?5^*=zV6qG>|_FDifvC<`u88$f{r
-zA4i!}wT at REdyoMu16dnHB;D@@3NBpY!1NO<VZ*{`yW!;<Bw6B0hFTOp3NK9?NrO(%
-z0`6p29Wu}}EEk{Mw;*#dWfB9j*o~d!2xUQox;li65 at eEWqHxg>H|lmgf})fUAkBiV
-zm;BzE0?O<qUNE#-nW1h+(U1a-c)*1yh{_rhOoTQ5vYSpC4;_6c;*uA<<PqajV8U&J
-zhawlKoLPd(!}uZ&4DG-80XynFdDet4npX-M0Z1|}sy-#EQB=GF&=|HOdCK7m?j)?q
-zU+C_>U^P2z1Eg59aK&NNdjgpoe~AK)?jK%1^Z>z>TgE|(#evoY11nPA1rQZpvaAtC
-zkNq?C`z_zwM3V=IhOvfN(z=a<W{iuQ)tKSMAonOFE51#@np~nkVEn6_&c9HzW=*`P
-zD1$KE5<eOZpA=}si_5Yg23;xfZ<;U$?-I9Xj#5vaf^j0)r3LGBc#};iDDqP*O2`eR
-z0O}FQ5EFvfFcdv%_69*%KvsN-R?_&fwtSX>Ra~^$cMQG6G-A!R6!MA8AfF2G>2)cF
-zD~?I)zALID0c#Xw!DtJkHrykwoE64!>u^L0o{~X;$|OTCxa`ehtlSuJuUIBAhJA!N
-z4i+~ww}Rh6H3f|y4%AxE@<A_z+5lnPNw&C^ht6e<8c*<)jDN}E(<{s+%Z*HHf6FLe
-z=yDL;Xf^b$TJa{}ZIQvvWesIQ#)m6Np<aC1o4HuIkx(xS9%}MSD086t1}_8NEA&k8
-zsz|Zsf<|Ooj3`Ym7Qqj)_>_maOl2ZbXPQcDDo8)QMDa9W*o%P%z)68dycBDJrky4u
-zBL|f8W$%>1D)kXs#tbC~Sfj~T-Q)$}vQCHbMOw&;C8#_s1ynxXB=cX!3jxI+nlzcR
-z%zngWjeec+$w>cSP|la$DGyZUQ^@Vpj#Hp9Ak8{UQ$EaP&E3N#{n_dJL`qP3K!&Ey
-zkHiBaeG_ch{ph?Ysj<b}#jH&@V{2Gm4E~mK#N<w$H05uA;ei2NWrK4^zlg!Ln4^*y
-zF>Ar91p0`KA4pHu#KPp0bkd-zg>D=j2IVa^-UKmd6zWgg3>ouA>BU;U%<BA<8jO8H
-zaRIlI;!N%lv&M|7G1C6D-%WqkAkNM?rgQeua2w3}vo6$-vvSrti>>?(q)?N;u;)o<
-z#O&iR6`~Ngpj>~#SCmb^!C{50<vA+(lx2-Dce>o*T<G;h)WZg_rgP$YJu5 at qoIb1t
-zpmF(0$_VtdnCCJKbXrfur^8#Jgtd}lD}RreH6|9*A$RN}FxG?ZoI=pJja1;UHIg^e
-zVjq#g!#Y{ZLsasq7&KziQ>lV!5g=1encRtH{fnVYUP5`+N>J*&hs)Zu2IMjY3Z~0?
-zji~_|_7$H*;Ukj^lYAt at S|>y$H*i5CGTl_lP~9jm(HK?1R_zODnz`@Br(&(I^$0id
-zN+MB#Lt};+OiWe7zyS7>T=Zz2F?;n1l{`xFV&pwitd*2mo%cu;Y6#rOWE=2xvKWvH
-M8kRGe!I94Y0Z~OtP5=M^
-
-literal 0
-HcmV?d00001
-
-diff --git a/im/content/aboutDialog-appUpdater.js b/im/content/aboutDialog-appUpdater.js
-new file mode 100644
-index 000000000..f223f061e
---- /dev/null
-+++ b/im/content/aboutDialog-appUpdater.js
-@@ -0,0 +1,576 @@
-+/* This Source Code Form is subject to the terms of the Mozilla Public
-+ * License, v. 2.0. If a copy of the MPL was not distributed with this
-+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-+
-+// Note: this file is included in aboutDialog.xul if MOZ_UPDATER is defined.
-+
-+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-+Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
-+Components.utils.import("resource://gre/modules/AddonManager.jsm");
-+
-+XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
-+                                  "resource://gre/modules/UpdateUtils.jsm");
-+
-+var gAppUpdater;
-+
-+function onUnload(aEvent) {
-+  if (gAppUpdater.isChecking)
-+    gAppUpdater.checker.stopChecking(Components.interfaces.nsIUpdateChecker.CURRENT_CHECK);
-+  // Safe to call even when there isn't a download in progress.
-+  gAppUpdater.removeDownloadListener();
-+  gAppUpdater = null;
-+}
-+
-+
-+function appUpdater()
-+{
-+  this.updateDeck = document.getElementById("updateDeck");
-+
-+  // Hide the update deck when there is already an update window open to avoid
-+  // syncing issues between them.
-+  if (Services.wm.getMostRecentWindow("Update:Wizard")) {
-+    this.updateDeck.hidden = true;
-+    return;
-+  }
-+
-+  XPCOMUtils.defineLazyServiceGetter(this, "aus",
-+                                     "@mozilla.org/updates/update-service;1",
-+                                     "nsIApplicationUpdateService");
-+  XPCOMUtils.defineLazyServiceGetter(this, "checker",
-+                                     "@mozilla.org/updates/update-checker;1",
-+                                     "nsIUpdateChecker");
-+  XPCOMUtils.defineLazyServiceGetter(this, "um",
-+                                     "@mozilla.org/updates/update-manager;1",
-+                                     "nsIUpdateManager");
-+
-+  this.bundle = Services.strings.
-+                createBundle("chrome://browser/locale/browser.properties");
-+
-+  let manualURL = Services.urlFormatter.formatURLPref("app.update.url.manual");
-+  let manualLink = document.getElementById("manualLink");
-+  manualLink.value = manualURL;
-+  manualLink.href = manualURL;
-+  document.getElementById("failedLink").href = manualURL;
-+
-+  if (this.updateDisabledAndLocked) {
-+    this.selectPanel("adminDisabled");
-+    return;
-+  }
-+
-+  if (this.isPending || this.isApplied) {
-+    this.selectPanel("apply");
-+    return;
-+  }
-+
-+  if (this.aus.isOtherInstanceHandlingUpdates) {
-+    this.selectPanel("otherInstanceHandlingUpdates");
-+    return;
-+  }
-+
-+  if (this.isDownloading) {
-+    this.startDownload();
-+    // selectPanel("downloading") is called from setupDownloadingUI().
-+    return;
-+  }
-+
-+  // Honor the "Never check for updates" option by not only disabling background
-+  // update checks, but also in the About dialog, by presenting a
-+  // "Check for updates" button.
-+  // If updates are found, the user is then asked if he wants to "Update to <version>".
-+  if (!this.updateEnabled) {
-+    this.selectPanel("checkForUpdates");
-+    return;
-+  }
-+
-+  // That leaves the options
-+  // "Check for updates, but let me choose whether to install them", and
-+  // "Automatically install updates".
-+  // In both cases, we check for updates without asking.
-+  // In the "let me choose" case, we ask before downloading though, in onCheckComplete.
-+  this.checkForUpdates();
-+}
-+
-+appUpdater.prototype =
-+{
-+  // true when there is an update check in progress.
-+  isChecking: false,
-+
-+  // true when there is an update already staged / ready to be applied.
-+  get isPending() {
-+    if (this.update) {
-+      return this.update.state == "pending" ||
-+             this.update.state == "pending-service";
-+    }
-+    return this.um.activeUpdate &&
-+           (this.um.activeUpdate.state == "pending" ||
-+            this.um.activeUpdate.state == "pending-service");
-+  },
-+
-+  // true when there is an update already installed in the background.
-+  get isApplied() {
-+    if (this.update)
-+      return this.update.state == "applied" ||
-+             this.update.state == "applied-service";
-+    return this.um.activeUpdate &&
-+           (this.um.activeUpdate.state == "applied" ||
-+            this.um.activeUpdate.state == "applied-service");
-+  },
-+
-+  // true when there is an update download in progress.
-+  get isDownloading() {
-+    if (this.update)
-+      return this.update.state == "downloading";
-+    return this.um.activeUpdate &&
-+           this.um.activeUpdate.state == "downloading";
-+  },
-+
-+  // true when updating is disabled by an administrator.
-+  get updateDisabledAndLocked() {
-+    return !this.updateEnabled &&
-+           Services.prefs.prefIsLocked("app.update.enabled");
-+  },
-+
-+  // true when updating is enabled.
-+  get updateEnabled() {
-+    try {
-+      return Services.prefs.getBoolPref("app.update.enabled");
-+    }
-+    catch (e) { }
-+    return true; // Firefox default is true
-+  },
-+
-+  // true when updating in background is enabled.
-+  get backgroundUpdateEnabled() {
-+    return this.updateEnabled &&
-+           gAppUpdater.aus.canStageUpdates;
-+  },
-+
-+  // true when updating is automatic.
-+  get updateAuto() {
-+    try {
-+      return Services.prefs.getBoolPref("app.update.auto");
-+    }
-+    catch (e) { }
-+    return true; // Firefox default is true
-+  },
-+
-+  /**
-+   * Sets the panel of the updateDeck.
-+   *
-+   * @param  aChildID
-+   *         The id of the deck's child to select, e.g. "apply".
-+   */
-+  selectPanel: function(aChildID) {
-+    let panel = document.getElementById(aChildID);
-+
-+    let button = panel.querySelector("button");
-+    if (button) {
-+      if (aChildID == "downloadAndInstall") {
-+        let updateVersion = gAppUpdater.update.displayVersion;
-+        button.label = this.bundle.formatStringFromName("update.downloadAndInstallButton.label", [updateVersion], 1);
-+        button.accessKey = this.bundle.GetStringFromName("update.downloadAndInstallButton.accesskey");
-+      }
-+      this.updateDeck.selectedPanel = panel;
-+      if (!document.commandDispatcher.focusedElement || // don't steal the focus
-+          document.commandDispatcher.focusedElement.localName == "button") // except from the other buttons
-+        button.focus();
-+
-+    } else {
-+      this.updateDeck.selectedPanel = panel;
-+    }
-+  },
-+
-+  /**
-+   * Check for updates
-+   */
-+  checkForUpdates: function() {
-+    this.selectPanel("checkingForUpdates");
-+    this.isChecking = true;
-+    this.checker.checkForUpdates(this.updateCheckListener, true);
-+    // after checking, onCheckComplete() is called
-+  },
-+
-+  /**
-+   * Check for addon compat, or start the download right away
-+   */
-+  doUpdate: function() {
-+    // skip the compatibility check if the update doesn't provide appVersion,
-+    // or the appVersion is unchanged, e.g. nightly update
-+#ifdef TOR_BROWSER_UPDATE
-+    let pkgVersion = TOR_BROWSER_VERSION;
-+#else
-+    let pkgVersion = Services.appinfo.version;
-+#endif
-+    if (!this.update.appVersion ||
-+        Services.vc.compare(gAppUpdater.update.appVersion, pkgVersion) == 0) {
-+      this.startDownload();
-+    } else {
-+      this.checkAddonCompatibility();
-+    }
-+  },
-+
-+  /**
-+   * Handles oncommand for the "Restart to Update" button
-+   * which is presented after the download has been downloaded.
-+   */
-+  buttonRestartAfterDownload: function() {
-+    if (!this.isPending && !this.isApplied)
-+      return;
-+
-+      // Notify all windows that an application quit has been requested.
-+      let cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"].
-+                       createInstance(Components.interfaces.nsISupportsPRBool);
-+      Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
-+
-+      // Something aborted the quit process.
-+      if (cancelQuit.data)
-+        return;
-+
-+      let appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"].
-+                       getService(Components.interfaces.nsIAppStartup);
-+
-+      // If already in safe mode restart in safe mode (bug 327119)
-+      if (Services.appinfo.inSafeMode) {
-+        appStartup.restartInSafeMode(Components.interfaces.nsIAppStartup.eAttemptQuit);
-+        return;
-+      }
-+
-+      appStartup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit |
-+                      Components.interfaces.nsIAppStartup.eRestart);
-+    },
-+
-+  /**
-+   * Handles oncommand for the "Apply Update…" button
-+   * which is presented if we need to show the billboard or license.
-+   */
-+  buttonApplyBillboard: function() {
-+    const URI_UPDATE_PROMPT_DIALOG = "chrome://mozapps/content/update/updates.xul";
-+    var ary = null;
-+    ary = Components.classes["@mozilla.org/supports-array;1"].
-+          createInstance(Components.interfaces.nsISupportsArray);
-+    ary.AppendElement(this.update);
-+    var openFeatures = "chrome,centerscreen,dialog=no,resizable=no,titlebar,toolbar=no";
-+    Services.ww.openWindow(null, URI_UPDATE_PROMPT_DIALOG, "", openFeatures, ary);
-+    window.close(); // close the "About" window; updates.xul takes over.
-+  },
-+
-+  /**
-+   * Implements nsIUpdateCheckListener. The methods implemented by
-+   * nsIUpdateCheckListener are in a different scope from nsIIncrementalDownload
-+   * to make it clear which are used by each interface.
-+   */
-+  updateCheckListener: {
-+    /**
-+     * See nsIUpdateService.idl
-+     */
-+    onCheckComplete: function(aRequest, aUpdates, aUpdateCount) {
-+      gAppUpdater.isChecking = false;
-+      gAppUpdater.update = gAppUpdater.aus.
-+                           selectUpdate(aUpdates, aUpdates.length);
-+      if (!gAppUpdater.update) {
-+        gAppUpdater.selectPanel("noUpdatesFound");
-+        return;
-+      }
-+
-+      if (gAppUpdater.update.unsupported) {
-+        if (gAppUpdater.update.detailsURL) {
-+          let unsupportedLink = document.getElementById("unsupportedLink");
-+          unsupportedLink.href = gAppUpdater.update.detailsURL;
-+        }
-+        gAppUpdater.selectPanel("unsupportedSystem");
-+        return;
-+      }
-+
-+      if (!gAppUpdater.aus.canApplyUpdates) {
-+        gAppUpdater.selectPanel("manualUpdate");
-+        return;
-+      }
-+
-+      // Firefox no longer displays a license for updates and the licenseURL
-+      // check is just in case a distibution does.
-+      if (gAppUpdater.update.billboardURL || gAppUpdater.update.licenseURL) {
-+        gAppUpdater.selectPanel("applyBillboard");
-+        return;
-+      }
-+
-+      if (gAppUpdater.updateAuto) // automatically download and install
-+        gAppUpdater.doUpdate();
-+      else // ask
-+        gAppUpdater.selectPanel("downloadAndInstall");
-+    },
-+
-+    /**
-+     * See nsIUpdateService.idl
-+     */
-+    onError: function(aRequest, aUpdate) {
-+      // Errors in the update check are treated as no updates found. If the
-+      // update check fails repeatedly without a success the user will be
-+      // notified with the normal app update user interface so this is safe.
-+      gAppUpdater.isChecking = false;
-+      gAppUpdater.selectPanel("noUpdatesFound");
-+    },
-+
-+    /**
-+     * See nsISupports.idl
-+     */
-+    QueryInterface: function(aIID) {
-+      if (!aIID.equals(Components.interfaces.nsIUpdateCheckListener) &&
-+          !aIID.equals(Components.interfaces.nsISupports))
-+        throw Components.results.NS_ERROR_NO_INTERFACE;
-+      return this;
-+    }
-+  },
-+
-+  /**
-+   * Checks the compatibility of add-ons for the application update.
-+   */
-+  checkAddonCompatibility: function() {
-+    try {
-+      var hotfixID = Services.prefs.getCharPref(PREF_EM_HOTFIX_ID);
-+    }
-+    catch (e) { }
-+
-+    var self = this;
-+    AddonManager.getAllAddons(function(aAddons) {
-+      self.addons = [];
-+      self.addonsCheckedCount = 0;
-+      aAddons.forEach(function(aAddon) {
-+        // Protect against code that overrides the add-ons manager and doesn't
-+        // implement the isCompatibleWith or the findUpdates method.
-+        if (!("isCompatibleWith" in aAddon) || !("findUpdates" in aAddon)) {
-+          let errMsg = "Add-on doesn't implement either the isCompatibleWith " +
-+                       "or the findUpdates method!";
-+          if (aAddon.id)
-+            errMsg += " Add-on ID: " + aAddon.id;
-+          Components.utils.reportError(errMsg);
-+          return;
-+        }
-+
-+        // If an add-on isn't appDisabled and isn't userDisabled then it is
-+        // either active now or the user expects it to be active after the
-+        // restart. If that is the case and the add-on is not installed by the
-+        // application and is not compatible with the new application version
-+        // then the user should be warned that the add-on will become
-+        // incompatible. If an addon's type equals plugin it is skipped since
-+        // checking plugins compatibility information isn't supported and
-+        // getting the scope property of a plugin breaks in some environments
-+        // (see bug 566787). The hotfix add-on is also ignored as it shouldn't
-+        // block the user from upgrading.
-+        try {
-+#ifdef TOR_BROWSER_UPDATE
-+          let compatVersion = self.update.platformVersion;
-+#else
-+          let compatVersion = self.update.appVersion;
-+#endif
-+          if (aAddon.type != "plugin" && aAddon.id != hotfixID &&
-+              !aAddon.appDisabled && !aAddon.userDisabled &&
-+              aAddon.scope != AddonManager.SCOPE_APPLICATION &&
-+              aAddon.isCompatible &&
-+              !aAddon.isCompatibleWith(compatVersion,
-+                                       self.update.platformVersion))
-+            self.addons.push(aAddon);
-+        }
-+        catch (e) {
-+          Components.utils.reportError(e);
-+        }
-+      });
-+      self.addonsTotalCount = self.addons.length;
-+      if (self.addonsTotalCount == 0) {
-+        self.startDownload();
-+        return;
-+      }
-+
-+      self.checkAddonsForUpdates();
-+    });
-+  },
-+
-+  /**
-+   * Checks if there are updates for add-ons that are incompatible with the
-+   * application update.
-+   */
-+  checkAddonsForUpdates: function() {
-+    this.addons.forEach(function(aAddon) {
-+#ifdef TOR_BROWSER_UPDATE
-+      let compatVersion = this.update.platformVersion;
-+#else
-+      let compatVersion = this.update.appVersion;
-+#endif
-+      aAddon.findUpdates(this, AddonManager.UPDATE_WHEN_NEW_APP_DETECTED,
-+                         compatVersion,
-+                         this.update.platformVersion);
-+    }, this);
-+  },
-+
-+  /**
-+   * See XPIProvider.jsm
-+   */
-+  onCompatibilityUpdateAvailable: function(aAddon) {
-+    for (var i = 0; i < this.addons.length; ++i) {
-+      if (this.addons[i].id == aAddon.id) {
-+        this.addons.splice(i, 1);
-+        break;
-+      }
-+    }
-+  },
-+
-+  /**
-+   * See XPIProvider.jsm
-+   */
-+  onUpdateAvailable: function(aAddon, aInstall) {
-+#ifdef TOR_BROWSER_UPDATE
-+    let compatVersion = this.update.platformVersion;
-+#else
-+    let compatVersion = this.update.appVersion;
-+#endif
-+    if (!Services.blocklist.isAddonBlocklisted(aAddon,
-+                                               compatVersion,
-+                                               this.update.platformVersion)) {
-+      // Compatibility or new version updates mean the same thing here.
-+      this.onCompatibilityUpdateAvailable(aAddon);
-+    }
-+  },
-+
-+  /**
-+   * See XPIProvider.jsm
-+   */
-+  onUpdateFinished: function(aAddon) {
-+    ++this.addonsCheckedCount;
-+
-+    if (this.addonsCheckedCount < this.addonsTotalCount)
-+      return;
-+
-+    if (this.addons.length == 0) {
-+      // Compatibility updates or new version updates were found for all add-ons
-+      this.startDownload();
-+      return;
-+    }
-+
-+    this.selectPanel("applyBillboard");
-+  },
-+
-+  /**
-+   * Starts the download of an update mar.
-+   */
-+  startDownload: function() {
-+    if (!this.update)
-+      this.update = this.um.activeUpdate;
-+    this.update.QueryInterface(Components.interfaces.nsIWritablePropertyBag);
-+    this.update.setProperty("foregroundDownload", "true");
-+
-+    this.aus.pauseDownload();
-+    let state = this.aus.downloadUpdate(this.update, false);
-+    if (state == "failed") {
-+      this.selectPanel("downloadFailed");
-+      return;
-+    }
-+
-+    this.setupDownloadingUI();
-+  },
-+
-+  /**
-+   * Switches to the UI responsible for tracking the download.
-+   */
-+  setupDownloadingUI: function() {
-+    this.downloadStatus = document.getElementById("downloadStatus");
-+    this.downloadStatus.value =
-+      DownloadUtils.getTransferTotal(0, this.update.selectedPatch.size);
-+    this.selectPanel("downloading");
-+    this.aus.addDownloadListener(this);
-+  },
-+
-+  removeDownloadListener: function() {
-+    if (this.aus) {
-+      this.aus.removeDownloadListener(this);
-+    }
-+  },
-+
-+  /**
-+   * See nsIRequestObserver.idl
-+   */
-+  onStartRequest: function(aRequest, aContext) {
-+  },
-+
-+  /**
-+   * See nsIRequestObserver.idl
-+   */
-+  onStopRequest: function(aRequest, aContext, aStatusCode) {
-+    switch (aStatusCode) {
-+    case Components.results.NS_ERROR_UNEXPECTED:
-+      if (this.update.selectedPatch.state == "download-failed" &&
-+          (this.update.isCompleteUpdate || this.update.patchCount != 2)) {
-+        // Verification error of complete patch, informational text is held in
-+        // the update object.
-+        this.removeDownloadListener();
-+        this.selectPanel("downloadFailed");
-+        break;
-+      }
-+      // Verification failed for a partial patch, complete patch is now
-+      // downloading so return early and do NOT remove the download listener!
-+      break;
-+    case Components.results.NS_BINDING_ABORTED:
-+      // Do not remove UI listener since the user may resume downloading again.
-+      break;
-+    case Components.results.NS_OK:
-+      this.removeDownloadListener();
-+      if (this.backgroundUpdateEnabled) {
-+        this.selectPanel("applying");
-+        let update = this.um.activeUpdate;
-+        let self = this;
-+        Services.obs.addObserver(function (aSubject, aTopic, aData) {
-+          // Update the UI when the background updater is finished
-+          let status = aData;
-+          if (status == "applied" || status == "applied-service" ||
-+              status == "pending" || status == "pending-service") {
-+            // If the update is successfully applied, or if the updater has
-+            // fallen back to non-staged updates, show the "Restart to Update"
-+            // button.
-+            self.selectPanel("apply");
-+          } else if (status == "failed") {
-+            // Background update has failed, let's show the UI responsible for
-+            // prompting the user to update manually.
-+            self.selectPanel("downloadFailed");
-+          } else if (status == "downloading") {
-+            // We've fallen back to downloading the full update because the
-+            // partial update failed to get staged in the background.
-+            // Therefore we need to keep our observer.
-+            self.setupDownloadingUI();
-+            return;
-+          }
-+          Services.obs.removeObserver(arguments.callee, "update-staged");
-+        }, "update-staged", false);
-+      } else {
-+        this.selectPanel("apply");
-+      }
-+      break;
-+    default:
-+      this.removeDownloadListener();
-+      this.selectPanel("downloadFailed");
-+      break;
-+    }
-+  },
-+
-+  /**
-+   * See nsIProgressEventSink.idl
-+   */
-+  onStatus: function(aRequest, aContext, aStatus, aStatusArg) {
-+  },
-+
-+  /**
-+   * See nsIProgressEventSink.idl
-+   */
-+  onProgress: function(aRequest, aContext, aProgress, aProgressMax) {
-+    this.downloadStatus.value =
-+      DownloadUtils.getTransferTotal(aProgress, aProgressMax);
-+  },
-+
-+  /**
-+   * See nsISupports.idl
-+   */
-+  QueryInterface: function(aIID) {
-+    if (!aIID.equals(Components.interfaces.nsIProgressEventSink) &&
-+        !aIID.equals(Components.interfaces.nsIRequestObserver) &&
-+        !aIID.equals(Components.interfaces.nsISupports))
-+      throw Components.results.NS_ERROR_NO_INTERFACE;
-+    return this;
-+  }
-+};
-diff --git a/im/content/aboutDialog.css b/im/content/aboutDialog.css
-index 25070608b..a065c8e88 100644
---- a/im/content/aboutDialog.css
-+++ b/im/content/aboutDialog.css
-@@ -1,66 +1,91 @@
-+/* This Source Code Form is subject to the terms of the Mozilla Public
-+ * License, v. 2.0. If a copy of the MPL was not distributed with this
-+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-+
- #aboutDialog {
--  padding: 0px 0px 10px 0px;
-+  width: 620px;
- }
- 
--#modes {
--  min-height: 380px;
-+#rightBox {
-+  background-image: url("chrome://branding/content/about-wordmark.png");
-+  background-position: left top;
-+  background-repeat: no-repeat;
-+  /* padding-top creates room for the wordmark */
-+  padding-top: 38px;
-+  margin-top:20px;
- }
- 
--#clientBox {
--  background-color: #FFFFFF;
--  background-image: url("chrome://branding/content/about.png");
--  background-repeat: no-repeat;
--  padding-top: 220px;
--  color: #000000;
-+#rightBox:-moz-locale-dir(rtl) {
-+  background-position: 100% 0;
- }
- 
--#versionWrapper {
--  margin: 0px 0px 3px 20px;
-+#bottomBox > hbox:not(#newBottom) {
-+  display: none;
- }
- 
--#versionField {
--  background-color: #FFFFFF;
--  -moz-appearance: none;
--  border: none;
-+#version {
-   font-weight: bold;
--  color: #909090;
-+  margin-top: 10px;
-+  -moz-margin-start: 0;
-+  -moz-user-select: text;
-+  -moz-user-focus: normal;
-+  cursor: text;
- }
- 
--#geckoVersionField,
--#libpurpleVersionField {
--  background-color: #FFFFFF;
--  -moz-appearance: none;
--  border: none;
--  color: #909090;
--  padding-top: 3px !important;
--  padding-left: 10px !important;
-+#version:-moz-locale-dir(rtl) {
-+  direction: ltr;
-+  text-align: right;
-+  margin-right: 0;
- }
- 
--#copyright {
--  margin: 10px 20px 3px 20px;
-+#distribution,
-+#distributionId {
-+  display: none;
-+  margin-top: 0;
-+  margin-bottom: 0;
- }
- 
--#userAgentField {
--  margin: 0px 0px 3px 20px !important;
--  background-color: #FFFFFF;
--  -moz-appearance: none;
--  border: none;
-+.text-blurb {
-+  margin-bottom: 10px;
-+  -moz-margin-start: 0;
-+  -moz-padding-start: 0;
- }
- 
--#groove {
--  margin-top: 0px;
-+#updateButton,
-+#updateDeck > hbox > label {
-+  -moz-margin-start: 0;
-+  -moz-padding-start: 0;
- }
- 
--#creditsIframe {
--   cursor: default;
--   -moz-user-select: none;
-+.update-throbber {
-+  width: 16px;
-+  min-height: 16px;
-+  -moz-margin-end: 3px;
-+  list-style-image: url("chrome://global/skin/icons/loading_16.png");
- }
- 
--button[dlgtype="extra2"] {
--  margin-left: 13px;
-+.text-link,
-+.text-link:focus {
-+  margin: 0px;
-+  padding: 0px;
- }
- 
--button[dlgtype="accept"] {
--  margin-right: 13px;
-+.bottom-link,
-+.bottom-link:focus {
-+  text-align: center;
-+  margin: 0 40px;
- }
- 
-+#currentChannel {
-+  margin: 0;
-+  padding: 0;
-+  font-weight: bold;
-+}
-+
-+#trademarkTor {
-+  font-size: xx-small;
-+  text-align: center;
-+  color: #999999;
-+  margin-top: 10px;
-+  margin-bottom: 10px;
-+}
-diff --git a/im/content/aboutDialog.js b/im/content/aboutDialog.js
-new file mode 100644
-index 000000000..e265f239c
---- /dev/null
-+++ b/im/content/aboutDialog.js
-@@ -0,0 +1,80 @@
-+/* This Source Code Form is subject to the terms of the Mozilla Public
-+ * License, v. 2.0. If a copy of the MPL was not distributed with this
-+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-+
-+// Services = object with smart getters for common XPCOM services
-+Components.utils.import("resource://gre/modules/Services.jsm");
-+Components.utils.import("resource://gre/modules/AppConstants.jsm");
-+
-+const PREF_EM_HOTFIX_ID = "extensions.hotfix.id";
-+
-+#ifdef TOR_BROWSER_VERSION
-+# Add double-quotes back on (stripped by JarMaker.py).
-+#expand const TOR_BROWSER_VERSION = "__TOR_BROWSER_VERSION__";
-+#endif
-+
-+function init(aEvent)
-+{
-+  if (aEvent.target != document)
-+    return;
-+
-+  try {
-+    var distroId = Services.prefs.getCharPref("distribution.id");
-+    if (distroId) {
-+      var distroVersion = Services.prefs.getCharPref("distribution.version");
-+
-+      var distroIdField = document.getElementById("distributionId");
-+      distroIdField.value = distroId + " - " + distroVersion;
-+      distroIdField.style.display = "block";
-+
-+      try {
-+        // This is in its own try catch due to bug 895473 and bug 900925.
-+        var distroAbout = Services.prefs.getComplexValue("distribution.about",
-+          Components.interfaces.nsISupportsString);
-+        var distroField = document.getElementById("distribution");
-+        distroField.value = distroAbout;
-+        distroField.style.display = "block";
-+      }
-+      catch (ex) {
-+        // Pref is unset
-+        Components.utils.reportError(ex);
-+      }
-+    }
-+  }
-+  catch (e) {
-+    // Pref is unset
-+  }
-+
-+  // Include the build ID and display warning if this is an "a#" (nightly or aurora) build
-+  let version = Services.appinfo.version;
-+  if (/a\d+$/.test(version)) {
-+    document.getElementById("experimental").hidden = false;
-+    document.getElementById("communityDesc").hidden = true;
-+  }
-+
-+#ifdef TOR_BROWSER_VERSION
-+  let versionElem = document.getElementById("version");
-+  if (versionElem) {
-+    versionElem.textContent = TOR_BROWSER_VERSION +
-+                              " (based on Instantbird " +
-+                              version + ")";
-+  }
-+#endif
-+
-+  if (AppConstants.MOZ_UPDATER) {
-+    gAppUpdater = new appUpdater();
-+
-+    let defaults = Services.prefs.getDefaultBranch("");
-+    let channelLabel = document.getElementById("currentChannel");
-+    let currentChannelText = document.getElementById("currentChannelText");
-+    channelLabel.value = UpdateUtils.UpdateChannel;
-+    if (/^release($|\-)/.test(channelLabel.value))
-+        currentChannelText.hidden = true;
-+  }
-+
-+  if (AppConstants.platform == "macosx") {
-+    // it may not be sized at this point, and we need its width to calculate its position
-+    window.sizeToContent();
-+    window.moveTo((screen.availWidth / 2) - (window.outerWidth / 2), screen.availHeight / 5);
-+  }
-+}
-diff --git a/im/content/aboutDialog.xul b/im/content/aboutDialog.xul
-index aa3b80ec9..ba924b9ad 100644
---- a/im/content/aboutDialog.xul
-+++ b/im/content/aboutDialog.xul
-@@ -1,130 +1,173 @@
- <?xml version="1.0"?> <!-- -*- Mode: HTML -*- -->
-+
- # This Source Code Form is subject to the terms of the Mozilla Public
- # License, v. 2.0. If a copy of the MPL was not distributed with this
- # file, You can obtain one at http://mozilla.org/MPL/2.0/.
- 
- <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
- <?xml-stylesheet href="chrome://instantbird/content/aboutDialog.css" type="text/css"?>
--#ifdef XP_MACOSX
--<?xul-overlay href="chrome://instantbird/content/menus.xul"?>
--#endif
-+<?xml-stylesheet href="chrome://branding/content/aboutDialog.css" type="text/css"?>
- 
- <!DOCTYPE window [
- <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
- %brandDTD;
- <!ENTITY % aboutDialogDTD SYSTEM "chrome://instantbird/locale/aboutDialog.dtd" >
- %aboutDialogDTD;
--<!ENTITY copyrightYear "2015">
-+]>
-+
- #ifdef XP_MACOSX
-- <!ENTITY % instantbirdDTD SYSTEM "chrome://instantbird/locale/instantbird.dtd">
-- %instantbirdDTD;
-+<?xul-overlay href="chrome://instantbird/content/macBrowserOverlay.xul"?>
- #endif
--]>
- 
--<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-+<window xmlns:html="http://www.w3.org/1999/xhtml"
-+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-         id="aboutDialog"
--        windowtype="Messenger:About"
--        buttons="accept,extra2"
--        onload="onLoad();"
--        title="&aboutDialog.title;" creditslabel="&credits.label;" creditsaccesskey="&credits.accesskey;"
--        aboutlabel="&aboutLink.label;" aboutaccesskey="&aboutLink.accesskey;" versionlabel="&aboutVersion;"
--        style="width: 299px; height: 330px;">
--
-+        windowtype="Browser:About"
-+        onload="init(event);"
-+#ifdef MOZ_UPDATER
-+        onunload="onUnload(event);"
-+#endif
- #ifdef XP_MACOSX
--#include menus.xul.inc
-+        inwindowmenu="false"
-+#else
-+        title="&aboutDialog.title;"
- #endif
-+        role="dialog"
-+        aria-describedby="version distribution distributionId communityDesc contributeDesc trademark"
-+        >
- 
--    <script type="application/x-javascript">
--      <![CDATA[
--        var gSelectedPage;
--
--        function onLoad() {
--          var xai = Components.classes["@mozilla.org/xre/app-info;1"]
--                              .getService(Components.interfaces.nsIXULAppInfo);
--
--          var versionField = document.getElementById("versionField");
--          versionField.value = versionField.value + xai.version
--                             + ' (' + xai.appBuildID + ')';
--
--          versionField = document.getElementById("geckoVersionField");
--          versionField.value = versionField.value + xai.platformVersion
--                             + ' (' + xai.platformBuildID + ')';
--
--          versionField = document.getElementById("libpurpleVersionField");
--          if ("@instantbird.org/libpurple/core;1" in Components.classes) {
--            var pcs = Components.classes["@instantbird.org/libpurple/core;1"]
--                                .getService(Components.interfaces.purpleICoreService);
--            versionField.value = versionField.value + pcs.version;
--          }
--          else {
--            versionField.hidden = true;
--          }
--
--          versionField = document.getElementById("userAgentField");
--          versionField.value = navigator.userAgent;
--
--          var button = document.documentElement.getButton("extra2");
--          button.setAttribute("label", document.documentElement.getAttribute("creditslabel"));
--          button.setAttribute("accesskey", document.documentElement.getAttribute("creditsaccesskey"));
--          gSelectedPage = 0;
--          button.addEventListener("command", switchPage);
--          document.documentElement.getButton("accept").focus();
--        }
--
--        function uninit(aEvent)
--        {
--          if (aEvent.target != document)
--            return;
--          var iframe = document.getElementById("creditsIframe");
--          iframe.setAttribute("src", "");
--        }
--
--        function switchPage(aEvent)
--        {
--          var button = aEvent.target;
--          if (button.localName != "button")
--            return;
--
--          var iframe = document.getElementById("creditsIframe");
--          if (gSelectedPage == 0) {
--            iframe.setAttribute("src", "chrome://instantbird/content/credits.xhtml");
--            button.setAttribute("label", document.documentElement.getAttribute("aboutlabel"));
--            button.setAttribute("accesskey", document.documentElement.getAttribute("aboutaccesskey"));
--            gSelectedPage = 1;
--          }
--          else {
--            iframe.setAttribute("src", "");
--            button.setAttribute("label", document.documentElement.getAttribute("creditslabel"));
--            button.setAttribute("accesskey", document.documentElement.getAttribute("creditsaccesskey"));
--            gSelectedPage = 0;
--          }
--          var modes = document.getElementById("modes");
--          modes.setAttribute("selectedIndex", gSelectedPage);
--        }
--      ]]>
--    </script>
--
--    <deck id="modes" flex="1">
--      <vbox flex="1" id="clientBox">
--        <vbox id="versionWrapper" flex="1">
--          <textbox id="versionField" readonly="true" class="plain" tabindex="2"
--                   value="&aboutVersion; "/>
--          <textbox id="geckoVersionField" readonly="true" class="plain"
--                   tabindex="3" value="&geckoVersion; "/>
--          <textbox id="libpurpleVersionField" readonly="true" class="plain"
--                   tabindex="4" value="&libpurpleVersion; "/>
-+  <script type="application/javascript" src="chrome://instantbird/content/aboutDialog.js"/>
-+#ifdef MOZ_UPDATER
-+  <script type="application/javascript" src="chrome://instantbird/content/aboutDialog-appUpdater.js"/>
-+#endif
-+  <vbox id="aboutDialogContainer">
-+    <hbox id="clientBox">
-+      <vbox id="leftBox" flex="1"/>
-+      <vbox id="rightBox" flex="1">
-+#expand <label id="version">__MOZ_APP_VERSION_DISPLAY__</label>
-+        <label id="distribution" class="text-blurb"/>
-+        <label id="distributionId" class="text-blurb"/>
-+
-+        <vbox id="detailsBox">
-+          <vbox id="updateBox">
-+#ifdef MOZ_UPDATER
-+            <deck id="updateDeck" orient="vertical">
-+              <hbox id="checkForUpdates" align="center">
-+                <button id="checkForUpdatesButton" align="start"
-+                        label="&update.checkForUpdatesButton.label;"
-+                        accesskey="&update.checkForUpdatesButton.accesskey;"
-+                        oncommand="gAppUpdater.checkForUpdates();"/>
-+                <spacer flex="1"/>
-+              </hbox>
-+              <hbox id="downloadAndInstall" align="center">
-+                <button id="downloadAndInstallButton" align="start"
-+                        oncommand="gAppUpdater.doUpdate();"/>
-+                        <!-- label and accesskey will be filled by JS -->
-+                <spacer flex="1"/>
-+              </hbox>
-+              <hbox id="apply" align="center">
-+                <button id="updateButton" align="start"
-+                        label="&update.updateButton.label2;"
-+                        accesskey="&update.updateButton.accesskey;"
-+                        oncommand="gAppUpdater.buttonRestartAfterDownload();"/>
-+                <spacer flex="1"/>
-+              </hbox>
-+              <hbox id="applyBillboard" align="center">
-+                <button id="applyButtonBillboard" align="start"
-+                        label="&update.applyButtonBillboard.label;"
-+                        accesskey="&update.applyButtonBillboard.accesskey;"
-+                        oncommand="gAppUpdater.buttonApplyBillboard();"/>
-+                <spacer flex="1"/>
-+              </hbox>
-+              <hbox id="checkingForUpdates" align="center">
-+                <image class="update-throbber"/><label>&update.checkingForUpdates;</label>
-+              </hbox>
-+              <hbox id="downloading" align="center">
-+                <image class="update-throbber"/><label>&update.downloading.start;</label><label id="downloadStatus"/><label>&update.downloading.end;</label>
-+              </hbox>
-+              <hbox id="applying" align="center">
-+                <image class="update-throbber"/><label>&update.applying;</label>
-+              </hbox>
-+              <hbox id="downloadFailed" align="center">
-+                <label>&update.failed.start;</label><label id="failedLink" class="text-link">&update.failed.linkText;</label><label>&update.failed.end;</label>
-+              </hbox>
-+              <hbox id="adminDisabled" align="center">
-+                <label>&update.adminDisabled;</label>
-+              </hbox>
-+              <hbox id="noUpdatesFound" align="center">
-+                <label>&update.noUpdatesFound;</label>
-+              </hbox>
-+              <hbox id="otherInstanceHandlingUpdates" align="center">
-+                <label>&update.otherInstanceHandlingUpdates;</label>
-+              </hbox>
-+              <hbox id="manualUpdate" align="center">
-+                <label>&update.manual.start;</label><label id="manualLink" class="text-link"/><label>&update.manual.end;</label>
-+              </hbox>
-+              <hbox id="unsupportedSystem" align="center">
-+                <label>&update.unsupported.start;</label><label id="unsupportedLink" class="text-link">&update.unsupported.linkText;</label><label>&update.unsupported.end;</label>
-+              </hbox>
-+            </deck>
-+#endif
-+      <description class="text-blurb" id="projectDesc">
-+        &project.start;
-+        &project.tpoLink;&project.end;
-+      </description>
-+      <description class="text-blurb" id="helpDesc">
-+       &help.donate;
-+       <textbox flex="1" class="plain" readonly="true" size="36"
-+           value="&help.donateLink;" />
-+      </description>
-+      <description class="text-blurb" id="getInvolvedLinkDesc">
-+       &help.getInvolved;
-+       <textbox flex="1" class="plain" readonly="true" size="36"
-+           value="&help.getInvolvedLink;" />
-+      </description>
-+  </vbox>
-+
-+#ifdef MOZ_UPDATER
-+          <description class="text-blurb" id="currentChannelText">
-+            &channel.description.start;<label id="currentChannel"/>&channel.description.end;
-+          </description>
-+#endif
-+          <vbox id="experimental" hidden="true">
-+            <description class="text-blurb" id="warningDesc">
-+              &warningDesc.version;
-+#ifdef MOZ_TELEMETRY_ON_BY_DEFAULT
-+              &warningDesc.telemetryDesc;
-+#endif
-+            </description>
-+            <description class="text-blurb" id="communityExperimentalDesc">
-+              &community.exp.start;<label class="text-link" href="http://www.mozilla.org/">&community.exp.mozillaLink;</label>&community.exp.middle;<label class="text-link" href="about:credits">&community.exp.creditsLink;</label>&community.exp.end;
-+            </description>
-+          </vbox>
-+          <description class="text-blurb" id="communityDesc">
-+            &community.start2;<label class="text-link" href="http://www.mozilla.org/">&community.mozillaLink;</label>&community.middle2;<label class="text-link" href="about:credits">&community.creditsLink;</label>&community.end3;
-+          </description>
-+          <description class="text-blurb" id="contributeDesc">
-+              &helpus.start;<label class="text-link" href="https://sendto.mozilla.org/page/contribute/Give-Now?source=mozillaorg_default_footer&ref=firefox_about&utm_campaign=firefox_about&tm_source=firefox&tm_medium=referral&utm_content=20140929_FireFoxAbout">&helpus.donateLink;</label>&helpus.middle;<label class="text-link" href="http://www.mozilla.org/contribute/">&helpus.getInvolvedLink;</label>&helpus.end;
-+          </description>
-         </vbox>
--        <description id="copyright" flex="1">&copyrightText2;</description>
--        <separator/>
--        <textbox id="userAgentField" readonly="true" class="plain"
--                 tabindex="5" multiline="true"/>
--      </vbox>
--
--      <vbox flex="1" id="creditsBox">
--        <iframe id="creditsIframe" flex="1"/>
-       </vbox>
--    </deck>
-+    </hbox>
-+    <vbox id="bottomBox">
-+      <hbox pack="center">
-+        <label class="text-link bottom-link" href="about:license">&bottomLinks.license;</label>
-+        <label class="text-link bottom-link" href="about:rights">&bottomLinks.rights;</label>
-+        <label class="text-link bottom-link" href="https://www.mozilla.org/privacy/">&bottomLinks.privacy;</label>
-+      </hbox>
-+      <description id="trademark"></description>
-+    </vbox>
-+    <description id="trademarkTor" insertafter="trademark">
-+      &tor.TrademarkStatement;
-+    </description>
-+
-+  </vbox>
-+  
-+  <keyset>
-+    <key keycode="VK_ESCAPE" oncommand="window.close();"/>
-+  </keyset>
- 
--    <separator class="groove" id="groove"/>
--
--</dialog>
-+#ifdef XP_MACOSX
-+#include browserMountPoints.inc
-+#endif
-+</window>
-diff --git a/im/content/browserMountPoints.inc b/im/content/browserMountPoints.inc
-new file mode 100644
-index 000000000..e4315b04a
---- /dev/null
-+++ b/im/content/browserMountPoints.inc
-@@ -0,0 +1,12 @@
-+<stringbundleset id="stringbundleset"/>
-+
-+<commandset id="mainCommandSet"/>
-+<commandset id="baseMenuCommandSet"/>
-+<commandset id="placesCommands"/>
-+
-+<broadcasterset id="mainBroadcasterSet"/>
-+
-+<keyset id="mainKeyset"/>
-+<keyset id="baseMenuKeyset"/>
-+
-+<menubar id="main-menubar"/>
-\ No newline at end of file
-diff --git a/im/content/jar.mn b/im/content/jar.mn
-index 20ea9dce7..b3d9e492f 100644
---- a/im/content/jar.mn
-+++ b/im/content/jar.mn
-@@ -10,7 +10,8 @@ instantbird.jar:
- #endif
- 	content/instantbird/aboutDialog.css
- *	content/instantbird/aboutDialog.xul
--	content/instantbird/aboutPanel.xml
-+*	content/instantbird/aboutDialog.js
-+*	content/instantbird/aboutDialog-appUpdater.js
- 	content/instantbird/account.js
- 	content/instantbird/accounts.css
- 	content/instantbird/accounts.js
-diff --git a/im/locales/en-US/chrome/instantbird/aboutDialog.dtd b/im/locales/en-US/chrome/instantbird/aboutDialog.dtd
-index ecd8d9d24..187cf5c3e 100644
---- a/im/locales/en-US/chrome/instantbird/aboutDialog.dtd
-+++ b/im/locales/en-US/chrome/instantbird/aboutDialog.dtd
-@@ -1,10 +1,129 @@
--<!ENTITY aboutDialog.title      "About &brandFullName;">
--<!ENTITY credits.label          "Credits">
--<!ENTITY credits.accesskey      "C">
--<!ENTITY aboutLink.label        "< About &brandShortName;">
--<!ENTITY aboutLink.accesskey    "A">
--<!ENTITY aboutVersion           "version">
--<!ENTITY geckoVersion           "Gecko">
--<!ENTITY libpurpleVersion       "libpurple">
--<!-- Use the ©rightYear; entity to place the current year. -->
--<!ENTITY copyrightText2         "©2007-©rightYear; Contributors. This program is free software; you can redistribute it and/or modify it under the terms of the GNU GPL license version 2.0 or later.">
-+<!-- This Source Code Form is subject to the terms of the Mozilla Public
-+   - License, v. 2.0. If a copy of the MPL was not distributed with this
-+   - file, You can obtain one at http://mozilla.org/MPL/2.0/.  -->
-+<!ENTITY aboutDialog.title          "About &brandFullName;">
-+
-+<!-- LOCALIZATION NOTE (update.checkForUpdatesButton.*, update.updateButton.*, update.applyButtonBillboard.*):
-+# Only one button is present at a time.
-+# The button when displayed is located directly under the Firefox version in
-+# the about dialog (see bug 596813 for screenshots).
-+-->
-+<!ENTITY update.checkForUpdatesButton.label       "Check for updates">
-+<!ENTITY update.checkForUpdatesButton.accesskey   "C">
-+<!ENTITY update.updateButton.label2                "Restart &brandShortName; to Update">
-+<!ENTITY update.updateButton.accesskey            "R">
-+<!ENTITY update.applyButtonBillboard.label        "Apply Update…">
-+<!ENTITY update.applyButtonBillboard.accesskey    "A">
-+
-+
-+<!-- LOCALIZATION NOTE (warningDesc.version): This is a warning about the experimental nature of Nightly and Aurora builds. It is only shown in those versions. -->
-+<!ENTITY warningDesc.version        "&brandShortName; is experimental and may be unstable.">
-+<!-- LOCALIZATION NOTE (warningDesc.telemetryDesc): This is a notification that Nightly/Aurora builds automatically send Telemetry data back to Mozilla. It is only shown in those versions. "It" refers to brandShortName. -->
-+<!ENTITY warningDesc.telemetryDesc  "It automatically sends information about performance, hardware, usage and customizations back to &vendorShortName; to help make &brandShortName; better.">
-+
-+<!-- LOCALIZATION NOTE (community.exp.*) This paragraph is shown in "experimental" builds, i.e. Nightly and Aurora builds, instead of the other "community.*" strings below. -->
-+<!ENTITY community.exp.start        "">
-+<!-- LOCALIZATION NOTE (community.exp.mozillaLink): This is a link title that links to http://www.mozilla.org/. -->
-+<!ENTITY community.exp.mozillaLink  "&vendorShortName;">
-+<!ENTITY community.exp.middle       " is a ">
-+<!-- LOCALIZATION NOTE (community.exp.creditslink): This is a link title that links to about:credits. -->
-+<!ENTITY community.exp.creditsLink  "global community">
-+<!ENTITY community.exp.end          " working together to keep the Web open, public and accessible to all.">
-+
-+<!ENTITY community.start2           "&brandShortName; is designed by ">
-+<!-- LOCALIZATION NOTE (community.mozillaLink): This is a link title that links to http://www.mozilla.org/. -->
-+<!ENTITY community.mozillaLink      "&vendorShortName;">
-+<!ENTITY community.middle2          ", a ">
-+<!-- LOCALIZATION NOTE (community.creditsLink): This is a link title that links to about:credits. -->
-+<!ENTITY community.creditsLink      "global community">
-+<!ENTITY community.end3             " working together to keep the Web open, public and accessible to all.">
-+
-+<!ENTITY helpus.start               "Want to help? ">
-+<!-- LOCALIZATION NOTE (helpus.donateLink): This is a link title that links to https://sendto.mozilla.org/page/contribute/Give-Now?source=mozillaorg_default_footer&ref=firefox_about&utm_campaign=firefox_about&utm_source=firefox&utm_medium=referral&utm_content=20140929_FireFoxAbout. -->
-+<!ENTITY helpus.donateLink          "Make a donation">
-+<!ENTITY helpus.middle              " or ">
-+<!-- LOCALIZATION NOTE (helpus.getInvolvedLink): This is a link title that links to http://www.mozilla.org/contribute/. -->
-+<!ENTITY helpus.getInvolvedLink     "get involved!">
-+<!ENTITY helpus.end                 "">
-+
-+<!-- LOCALIZATION NOTE (bottomLinks.license): This is a link title that links to about:license. -->
-+<!ENTITY bottomLinks.license        "Licensing Information">
-+
-+<!-- LOCALIZATION NOTE (bottomLinks.rights): This is a link title that links to about:rights. -->
-+<!ENTITY bottomLinks.rights         "End-User Rights">
-+
-+<!-- LOCALIZATION NOTE (bottomLinks.privacy): This is a link title that links to https://www.mozilla.org/legal/privacy/. -->
-+<!ENTITY bottomLinks.privacy        "Privacy Policy">
-+
-+<!-- LOCALIZATION NOTE (update.checkingForUpdates): try to make the localized text short (see bug 596813 for screenshots). -->
-+<!ENTITY update.checkingForUpdates  "Checking for updates…">
-+<!-- LOCALIZATION NOTE (update.noUpdatesFound): try to make the localized text short (see bug 596813 for screenshots). -->
-+<!ENTITY update.noUpdatesFound      "&brandShortName; is up to date">
-+<!-- LOCALIZATION NOTE (update.adminDisabled): try to make the localized text short (see bug 596813 for screenshots). -->
-+<!ENTITY update.adminDisabled       "Updates disabled by your system administrator">
-+<!-- LOCALIZATION NOTE (update.otherInstanceHandlingUpdates): try to make the localized text short -->
-+<!ENTITY update.otherInstanceHandlingUpdates "&brandShortName; is being updated by another instance">
-+
-+<!-- LOCALIZATION NOTE (update.failed.start,update.failed.linkText,update.failed.end):
-+     update.failed.start, update.failed.linkText, and update.failed.end all go into
-+     one line with linkText being wrapped in an anchor that links to a site to download
-+     the latest version of Firefox (e.g. http://www.firefox.com). As this is all in
-+     one line, try to make the localized text short (see bug 596813 for screenshots). -->
-+<!ENTITY update.failed.start        "Update failed. ">
-+<!ENTITY update.failed.linkText     "Download the latest version">
-+<!ENTITY update.failed.end          "">
-+
-+<!-- LOCALIZATION NOTE (update.manual.start,update.manual.end): update.manual.start and update.manual.end
-+     all go into one line and have an anchor in between with text that is the same as the link to a site
-+     to download the latest version of Firefox (e.g. http://www.firefox.com). As this is all in one line,
-+     try to make the localized text short (see bug 596813 for screenshots). -->
-+<!ENTITY update.manual.start        "Updates available at ">
-+<!ENTITY update.manual.end          "">
-+
-+<!-- LOCALIZATION NOTE (update.unsupported.start,update.unsupported.linkText,update.unsupported.end):
-+     update.unsupported.start, update.unsupported.linkText, and
-+     update.unsupported.end all go into one line with linkText being wrapped in
-+     an anchor that links to a site to provide additional information regarding
-+     why the system is no longer supported. As this is all in one line, try to
-+     make the localized text short (see bug 843497 for screenshots). -->
-+<!ENTITY update.unsupported.start    "You can not perform further updates on this system. ">
-+<!ENTITY update.unsupported.linkText "Learn more">
-+<!ENTITY update.unsupported.end      "">
-+
-+<!-- LOCALIZATION NOTE (update.downloading.start,update.downloading.end): update.downloading.start and 
-+     update.downloading.end all go into one line, with the amount downloaded inserted in between. As this
-+     is all in one line, try to make the localized text short (see bug 596813 for screenshots). The — is
-+     the "em dash" (long dash).
-+     example: Downloading update — 111 KB of 13 MB -->
-+<!ENTITY update.downloading.start   "Downloading update — ">
-+<!ENTITY update.downloading.end     "">
-+
-+<!ENTITY update.applying            "Applying update…">
-+
-+<!-- LOCALIZATION NOTE (channel.description.start,channel.description.end): channel.description.start and
-+     channel.description.end create one sentence, with the current channel label inserted in between.
-+     example: You are currently on the _Stable_ update channel. -->
-+<!ENTITY channel.description.start  "You are currently on the ">
-+<!ENTITY channel.description.end    " update channel. ">
-+
-+<!ENTITY project.start           "&brandShortName; is developed by">
-+<!-- LOCALIZATION NOTE (project.tpoLink): This is a link title that links to https://www.torproject.org -->
-+<!ENTITY project.tpoLink         "the &vendorShortName;">
-+<!ENTITY project.end             ", a nonprofit working to defend your privacy and freedom online.">
-+
-+<!ENTITY help.start              "Want to help? ">
-+<!-- LOCALIZATION NOTE (help.donate): This is a link title that links to https://www.torproject.org/donate/donate.html.en -->
-+<!ENTITY help.donate             "Donate:">
-+<!ENTITY help.donateLink         "https://www.torproject.org/donate">
-+<!ENTITY help.or                 " or ">
-+<!-- LOCALIZATION NOTE (help.getInvolvedLink): This is a link title that links to https://www.torproject.org/getinvolved/volunteer.html.en -->
-+<!ENTITY help.getInvolved        "Get Involved:">
-+<!ENTITY help.getInvolvedLink    "https://www.torproject.org/volunteer">
-+<!ENTITY help.end                "!">
-+<!-- LOCALIZATION NOTE (bottom.questions): This is a link title that links to https://www.torproject.org/docs/trademark-faq.html.en -->
-+<!ENTITY bottomLinks.questions   "Questions?">
-+<!-- LOCALIZATION NOTE (bottom.questions): This is a link title that links to https://www.torproject.org/getinvolved/relays -->
-+<!ENTITY bottomLinks.grow        "Help the Tor Network Grow!">
-+<!-- LOCALIZATION NOTE (bottom.questions): This is a link title that links to about:license -->
-+<!ENTITY bottomLinks.license  "Licensing Information">
-+<!ENTITY tor.TrademarkStatement   "'Tor' and the 'Onion Logo' are registered trademarks of the Tor Project, Inc.">
-diff --git a/im/locales/en-US/updater/updater.ini b/im/locales/en-US/updater/updater.ini
-index 15ec569c1..4a2d35d8a 100644
---- a/im/locales/en-US/updater/updater.ini
-+++ b/im/locales/en-US/updater/updater.ini
-@@ -5,4 +5,4 @@
- ; This file is in the UTF-8 encoding
- [Strings]
- Title=Software Update
--Info=Instantbird is installing your updates and will start in a few moments…
-+Info=Tor Messenger is installing your updates and will start in a few moments…
--- 
-2.11.0
-
diff --git a/projects/instantbird/0012-Account-picture.patch b/projects/instantbird/0012-Account-picture.patch
deleted file mode 100644
index 1205946..0000000
--- a/projects/instantbird/0012-Account-picture.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 4247688327fc2d92c05197bfc8f7a0877c8b31a4 Mon Sep 17 00:00:00 2001
-From: Sukhbir Singh <sukhbir at torproject.org>
-Date: Mon, 10 Oct 2016 19:24:09 -0700
-Subject: [PATCH 12/27] Account picture
-
----
- im/content/blist.xul | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
-diff --git a/im/content/blist.xul b/im/content/blist.xul
-index b90fddadb..f29a48b99 100644
---- a/im/content/blist.xul
-+++ b/im/content/blist.xul
-@@ -114,8 +114,7 @@
-       <stack id="statusImageStack">
-         <!-- The box around the user icon is a workaround for bug 955673. -->
-         <box id="userIconHolder">
--          <image id="userIcon" role="button" popup="changeUserIconPanel"
--                 aria-label="&userIcon.label;" tooltiptext="&userIcon.label;"/>
-+          <image id="userIcon" role="button"/>
-         </box>
-         <panel id="changeUserIconPanel"
-                type="arrow" align="center"
--- 
-2.11.0
-
diff --git a/projects/instantbird/0012-Modify-protocol-defaults.patch b/projects/instantbird/0012-Modify-protocol-defaults.patch
new file mode 100644
index 0000000..f18c794
--- /dev/null
+++ b/projects/instantbird/0012-Modify-protocol-defaults.patch
@@ -0,0 +1,48 @@
+From 9a17214a4da6b331941d472510cee846ec112979 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir at torproject.org>
+Date: Mon, 10 Oct 2016 19:25:34 -0700
+Subject: [PATCH 12/26] Modify protocol defaults
+
+ * Top protocols
+
+ * Hide get protocols
+---
+ im/content/accountWizard.xul                                 | 2 +-
+ im/locales/en-US/chrome/instantbird/accountWizard.properties | 4 +++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/im/content/accountWizard.xul b/im/content/accountWizard.xul
+index 759f42b38..a3069061a 100644
+--- a/im/content/accountWizard.xul
++++ b/im/content/accountWizard.xul
+@@ -50,7 +50,7 @@
+     <listbox flex="1" id="protolist"
+              ondblclick="document.getElementById('accountWizard').advance();"/>
+     <hbox pack="end">
+-      <label id="getMoreProtocols" class="text-link" value="&accountProtocolGetMore.label;"
++      <label id="getMoreProtocols" class="text-link" value=""
+              onclick="if (event.button == 0) { accountWizard.openURL(this.getAttribute('getMoreURL')); }"/>
+     </hbox>
+   </wizardpage>
+diff --git a/im/locales/en-US/chrome/instantbird/accountWizard.properties b/im/locales/en-US/chrome/instantbird/accountWizard.properties
+index d552a232b..7d371bd21 100644
+--- a/im/locales/en-US/chrome/instantbird/accountWizard.properties
++++ b/im/locales/en-US/chrome/instantbird/accountWizard.properties
+@@ -8,11 +8,13 @@
+ # Exceeding 4 protocols may cause scrolling. A list of the
+ # available protocols can be found at
+ #     https://wiki.instantbird.org/Protocol_Identifiers
+-topProtocol.list=prpl-gtalk,prpl-twitter,prpl-aim,prpl-yahoo,prpl-irc
++topProtocol.list=prpl-irc,prpl-jabber,prpl-twitter,prpl-gtalk
+ 
+ # LOCALIZATION NOTE
+ # These are the descriptions of the top protocols specified above.
+ # A description should be provided for each protocol ID listed above.
++topProtocol.prpl-irc.description=Connect to your favourite IRC network
++topProtocol.prpl-jabber.description=Chat with friends using XMPP
+ topProtocol.prpl-gtalk.description=Talk to your Gmail contacts
+ topProtocol.prpl-twitter.description=Stay up to date with your Twitter timeline
+ topProtocol.prpl-aim.description=Chat with your buddies on AOL Instant Messenger
+-- 
+2.11.0
+
diff --git a/projects/instantbird/0013-Modify-IRC-defaults.patch b/projects/instantbird/0013-Modify-IRC-defaults.patch
new file mode 100644
index 0000000..66b4cd4
--- /dev/null
+++ b/projects/instantbird/0013-Modify-IRC-defaults.patch
@@ -0,0 +1,65 @@
+From 08da489af04a8077148865d4671e88e01162a413 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir at torproject.org>
+Date: Mon, 10 Oct 2016 19:31:58 -0700
+Subject: [PATCH 13/26] Modify IRC defaults
+
+ * ctcp ping
+
+ * ctcp time
+
+ * irc default server
+---
+ chat/protocols/irc/irc.js      |  2 +-
+ chat/protocols/irc/ircCTCP.jsm | 16 ++--------------
+ 2 files changed, 3 insertions(+), 15 deletions(-)
+
+diff --git a/chat/protocols/irc/irc.js b/chat/protocols/irc/irc.js
+index 35165e9a9..c2167a5ec 100644
+--- a/chat/protocols/irc/irc.js
++++ b/chat/protocols/irc/irc.js
+@@ -1931,7 +1931,7 @@ ircProtocol.prototype = {
+ 
+   usernameSplits: [
+     {get label() { return _("options.server"); }, separator: "@",
+-     defaultValue: "chat.freenode.net", reverse: true}
++     defaultValue: "", reverse: true}
+   ],
+ 
+   options: {
+diff --git a/chat/protocols/irc/ircCTCP.jsm b/chat/protocols/irc/ircCTCP.jsm
+index 28eb374f4..120be10ee 100644
+--- a/chat/protocols/irc/ircCTCP.jsm
++++ b/chat/protocols/irc/ircCTCP.jsm
+@@ -167,19 +167,7 @@ var ctcpBase = {
+     },
+ 
+     // Used to measure the delay of the IRC network between clients.
+-    "PING": function(aMessage) {
+-      // PING timestamp
+-      if (aMessage.command == "PRIVMSG") {
+-        // Received PING request, send PING response.
+-        this.LOG("Received PING request from " + aMessage.origin +
+-                 ". Sending PING response: \"" + aMessage.ctcp.param + "\".");
+-        this.sendCTCPMessage(aMessage.origin, true, "PING",
+-                             aMessage.ctcp.param);
+-        return true;
+-      }
+-      else
+-        return this.handlePingReply(aMessage.origin, aMessage.ctcp.param);
+-    },
++    // "PING": function(aMessage) {
+ 
+     // These are commented out since CLIENTINFO automatically returns the
+     // supported CTCP parameters and this is not supported.
+@@ -195,7 +183,7 @@ var ctcpBase = {
+       if (aMessage.command == "PRIVMSG") {
+         // TIME
+         // Received a TIME request, send a human readable response.
+-        let now = (new Date()).toString();
++        let now = (new Date()).toUTCString();
+         this.LOG("Received TIME request from " + aMessage.origin +
+                  ". Sending TIME response: \"" + now + "\".");
+         this.sendCTCPMessage(aMessage.origin, true, "TIME", ":" + now);
+-- 
+2.11.0
+
diff --git a/projects/instantbird/0013-Modify-protocol-defaults.patch b/projects/instantbird/0013-Modify-protocol-defaults.patch
deleted file mode 100644
index f4a4bf4..0000000
--- a/projects/instantbird/0013-Modify-protocol-defaults.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From e5e4d83560b705e54b64c547b3d0159e559c4c92 Mon Sep 17 00:00:00 2001
-From: Sukhbir Singh <sukhbir at torproject.org>
-Date: Mon, 10 Oct 2016 19:25:34 -0700
-Subject: [PATCH 13/27] Modify protocol defaults
-
- * Top protocols
-
- * Hide get protocols
----
- im/content/accountWizard.xul                                 | 2 +-
- im/locales/en-US/chrome/instantbird/accountWizard.properties | 4 +++-
- 2 files changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/im/content/accountWizard.xul b/im/content/accountWizard.xul
-index 759f42b38..a3069061a 100644
---- a/im/content/accountWizard.xul
-+++ b/im/content/accountWizard.xul
-@@ -50,7 +50,7 @@
-     <listbox flex="1" id="protolist"
-              ondblclick="document.getElementById('accountWizard').advance();"/>
-     <hbox pack="end">
--      <label id="getMoreProtocols" class="text-link" value="&accountProtocolGetMore.label;"
-+      <label id="getMoreProtocols" class="text-link" value=""
-              onclick="if (event.button == 0) { accountWizard.openURL(this.getAttribute('getMoreURL')); }"/>
-     </hbox>
-   </wizardpage>
-diff --git a/im/locales/en-US/chrome/instantbird/accountWizard.properties b/im/locales/en-US/chrome/instantbird/accountWizard.properties
-index d552a232b..7d371bd21 100644
---- a/im/locales/en-US/chrome/instantbird/accountWizard.properties
-+++ b/im/locales/en-US/chrome/instantbird/accountWizard.properties
-@@ -8,11 +8,13 @@
- # Exceeding 4 protocols may cause scrolling. A list of the
- # available protocols can be found at
- #     https://wiki.instantbird.org/Protocol_Identifiers
--topProtocol.list=prpl-gtalk,prpl-twitter,prpl-aim,prpl-yahoo,prpl-irc
-+topProtocol.list=prpl-irc,prpl-jabber,prpl-twitter,prpl-gtalk
- 
- # LOCALIZATION NOTE
- # These are the descriptions of the top protocols specified above.
- # A description should be provided for each protocol ID listed above.
-+topProtocol.prpl-irc.description=Connect to your favourite IRC network
-+topProtocol.prpl-jabber.description=Chat with friends using XMPP
- topProtocol.prpl-gtalk.description=Talk to your Gmail contacts
- topProtocol.prpl-twitter.description=Stay up to date with your Twitter timeline
- topProtocol.prpl-aim.description=Chat with your buddies on AOL Instant Messenger
--- 
-2.11.0
-
diff --git a/projects/instantbird/0014-Modify-IRC-defaults.patch b/projects/instantbird/0014-Modify-IRC-defaults.patch
deleted file mode 100644
index 96cedfb..0000000
--- a/projects/instantbird/0014-Modify-IRC-defaults.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 469c5845459bd9427c0020cb616e1ef4e26ac4c3 Mon Sep 17 00:00:00 2001
-From: Sukhbir Singh <sukhbir at torproject.org>
-Date: Mon, 10 Oct 2016 19:31:58 -0700
-Subject: [PATCH 14/27] Modify IRC defaults
-
- * ctcp ping
-
- * ctcp time
-
- * irc default server
----
- chat/protocols/irc/irc.js      |  2 +-
- chat/protocols/irc/ircCTCP.jsm | 16 ++--------------
- 2 files changed, 3 insertions(+), 15 deletions(-)
-
-diff --git a/chat/protocols/irc/irc.js b/chat/protocols/irc/irc.js
-index 35165e9a9..c2167a5ec 100644
---- a/chat/protocols/irc/irc.js
-+++ b/chat/protocols/irc/irc.js
-@@ -1931,7 +1931,7 @@ ircProtocol.prototype = {
- 
-   usernameSplits: [
-     {get label() { return _("options.server"); }, separator: "@",
--     defaultValue: "chat.freenode.net", reverse: true}
-+     defaultValue: "", reverse: true}
-   ],
- 
-   options: {
-diff --git a/chat/protocols/irc/ircCTCP.jsm b/chat/protocols/irc/ircCTCP.jsm
-index 28eb374f4..120be10ee 100644
---- a/chat/protocols/irc/ircCTCP.jsm
-+++ b/chat/protocols/irc/ircCTCP.jsm
-@@ -167,19 +167,7 @@ var ctcpBase = {
-     },
- 
-     // Used to measure the delay of the IRC network between clients.
--    "PING": function(aMessage) {
--      // PING timestamp
--      if (aMessage.command == "PRIVMSG") {
--        // Received PING request, send PING response.
--        this.LOG("Received PING request from " + aMessage.origin +
--                 ". Sending PING response: \"" + aMessage.ctcp.param + "\".");
--        this.sendCTCPMessage(aMessage.origin, true, "PING",
--                             aMessage.ctcp.param);
--        return true;
--      }
--      else
--        return this.handlePingReply(aMessage.origin, aMessage.ctcp.param);
--    },
-+    // "PING": function(aMessage) {
- 
-     // These are commented out since CLIENTINFO automatically returns the
-     // supported CTCP parameters and this is not supported.
-@@ -195,7 +183,7 @@ var ctcpBase = {
-       if (aMessage.command == "PRIVMSG") {
-         // TIME
-         // Received a TIME request, send a human readable response.
--        let now = (new Date()).toString();
-+        let now = (new Date()).toUTCString();
-         this.LOG("Received TIME request from " + aMessage.origin +
-                  ". Sending TIME response: \"" + now + "\".");
-         this.sendCTCPMessage(aMessage.origin, true, "TIME", ":" + now);
--- 
-2.11.0
-
diff --git a/projects/instantbird/0014-Modify-themes.patch b/projects/instantbird/0014-Modify-themes.patch
new file mode 100644
index 0000000..25594e8
--- /dev/null
+++ b/projects/instantbird/0014-Modify-themes.patch
@@ -0,0 +1,78 @@
+From d65e732c91cb71fa6383ac314a5544b4045e9a01 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir at torproject.org>
+Date: Mon, 10 Oct 2016 19:36:38 -0700
+Subject: [PATCH 14/26] Modify themes
+
+ * theme extension updateh
+
+ * themes remove links
+---
+ .../{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf    |  2 ++
+ im/content/preferences/themes.js                          | 15 ---------------
+ im/content/preferences/themes.xul                         |  4 ----
+ 3 files changed, 2 insertions(+), 19 deletions(-)
+
+diff --git a/im/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf b/im/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
+index a7e38bba4..c5c781a97 100644
+--- a/im/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
++++ b/im/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
+@@ -26,6 +26,8 @@
+     <!-- Front End MetaData -->
+     <em:name>Instantbird (default)</em:name>
+     <em:description>The default theme.</em:description>
++    <em:updateURL>data:text/plain,</em:updateURL>
++    <em:updateKey>-</em:updateKey>
+ 
+     <!-- EXTENSION AUTHORS!
+          DO NOT COPY THIS PROPERTY INTO YOUR INSTALL RDF FILES
+diff --git a/im/content/preferences/themes.js b/im/content/preferences/themes.js
+index 5c5d594cb..4a9d6afd0 100644
+--- a/im/content/preferences/themes.js
++++ b/im/content/preferences/themes.js
+@@ -31,21 +31,6 @@ var gThemePane = {
+       default:
+         return;
+     }
+-
+-    var getMore = document.getElementById("getMore" + aType);
+-    var showGetMore = false;
+-    const nsIPrefBranch2 = Components.interfaces.nsIPrefBranch2;
+-    if (Services.prefs.getPrefType(prefURL) != nsIPrefBranch2.PREF_INVALID) {
+-      try {
+-        var getMoreURL = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
+-                                   .getService(Components.interfaces.nsIURLFormatter)
+-                                   .formatURLPref(prefURL);
+-        getMore.setAttribute("getMoreURL", getMoreURL);
+-        showGetMore = getMoreURL != "about:blank";
+-      }
+-      catch (e) { }
+-    }
+-    getMore.hidden = !showGetMore;
+   },
+ 
+   /* Create the drop down list for emoticons and messagestyles;
+diff --git a/im/content/preferences/themes.xul b/im/content/preferences/themes.xul
+index 454e36696..18ba1f95c 100644
+--- a/im/content/preferences/themes.xul
++++ b/im/content/preferences/themes.xul
+@@ -65,8 +65,6 @@
+               </menupopup>
+             </menulist>
+             <separator orient="vertical" class="thin"/>
+-            <label id="getMoreMessageStyles" class="text-link" value="&messageStyleGetMore.label;"
+-                   onclick="if (event.button == 0) { gThemePane.openURL(this.getAttribute('getMoreURL')); }"/>
+           </hbox>
+           <separator class="thin"/>
+           <label value="&messageStylePreview.label;"/>
+@@ -115,8 +113,6 @@
+               </menupopup>
+             </menulist>
+             <separator orient="vertical" class="thin"/>
+-            <label id="getMoreEmoticons" class="text-link" value="&emoticonsGetMore.label;"
+-                   onclick="if (event.button == 0) { gThemePane.openURL(this.getAttribute('getMoreURL')); }"/>
+           </hbox>
+           <separator class="thin"/>
+           <description>&emoticonsPreview.description;</description>
+-- 
+2.11.0
+
diff --git a/projects/instantbird/0015-Modify-XMPP-defaults.patch b/projects/instantbird/0015-Modify-XMPP-defaults.patch
new file mode 100644
index 0000000..039d9a3
--- /dev/null
+++ b/projects/instantbird/0015-Modify-XMPP-defaults.patch
@@ -0,0 +1,48 @@
+From 0ee19d29c6d38d5f945ec65e60c42f2f86bb679b Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir at torproject.org>
+Date: Mon, 10 Oct 2016 19:38:49 -0700
+Subject: [PATCH 15/26] Modify XMPP defaults
+
+ * xmpp-default-domain
+
+ * xmpp-gtalk-resource
+---
+ chat/protocols/gtalk/gtalk.js | 2 +-
+ chat/protocols/xmpp/xmpp.js   | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/chat/protocols/gtalk/gtalk.js b/chat/protocols/gtalk/gtalk.js
+index 8bce0c9b4..642f4561d 100644
+--- a/chat/protocols/gtalk/gtalk.js
++++ b/chat/protocols/gtalk/gtalk.js
+@@ -96,7 +96,7 @@ GTalkProtocol.prototype = {
+   getAccount: function(aImAccount) { return new GTalkAccount(this, aImAccount); },
+   options: {
+     resource: {get label() { return _("options.resource"); },
+-               get default() { return XMPPDefaultResource; }}
++               default: "Instantbird"},
+   },
+   get chatHasTopic() { return true; },
+   classID: Components.ID("{38a224c1-6748-49a9-8ab2-efc362b1000d}")
+diff --git a/chat/protocols/xmpp/xmpp.js b/chat/protocols/xmpp/xmpp.js
+index 265445a18..a5635cae3 100644
+--- a/chat/protocols/xmpp/xmpp.js
++++ b/chat/protocols/xmpp/xmpp.js
+@@ -31,12 +31,12 @@ XMPPProtocol.prototype = {
+ 
+   usernameSplits: [
+     {get label() { return _("options.domain"); }, separator: "@",
+-     defaultValue: "jabber.org", reverse: true}
++     defaultValue: "", reverse: true}
+   ],
+ 
+   options: {
+     resource: {get label() { return _("options.resource"); },
+-               get default() { return XMPPDefaultResource; }},
++               default: "Instantbird"},
+     priority: {get label() { return _("options.priority"); }, default: 0},
+     connection_security: {
+       get label() { return _("options.connectionSecurity"); },
+-- 
+2.11.0
+
diff --git a/projects/instantbird/0015-Modify-themes.patch b/projects/instantbird/0015-Modify-themes.patch
deleted file mode 100644
index 5edd9be..0000000
--- a/projects/instantbird/0015-Modify-themes.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From 0b72c7881c1dfc220fd3b8be2a502b34c4763c15 Mon Sep 17 00:00:00 2001
-From: Sukhbir Singh <sukhbir at torproject.org>
-Date: Mon, 10 Oct 2016 19:36:38 -0700
-Subject: [PATCH 15/27] Modify themes
-
- * theme extension updateh
-
- * themes remove links
----
- .../{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf    |  2 ++
- im/content/preferences/themes.js                          | 15 ---------------
- im/content/preferences/themes.xul                         |  4 ----
- 3 files changed, 2 insertions(+), 19 deletions(-)
-
-diff --git a/im/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf b/im/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
-index a7e38bba4..c5c781a97 100644
---- a/im/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
-+++ b/im/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
-@@ -26,6 +26,8 @@
-     <!-- Front End MetaData -->
-     <em:name>Instantbird (default)</em:name>
-     <em:description>The default theme.</em:description>
-+    <em:updateURL>data:text/plain,</em:updateURL>
-+    <em:updateKey>-</em:updateKey>
- 
-     <!-- EXTENSION AUTHORS!
-          DO NOT COPY THIS PROPERTY INTO YOUR INSTALL RDF FILES
-diff --git a/im/content/preferences/themes.js b/im/content/preferences/themes.js
-index 5c5d594cb..4a9d6afd0 100644
---- a/im/content/preferences/themes.js
-+++ b/im/content/preferences/themes.js
-@@ -31,21 +31,6 @@ var gThemePane = {
-       default:
-         return;
-     }
--
--    var getMore = document.getElementById("getMore" + aType);
--    var showGetMore = false;
--    const nsIPrefBranch2 = Components.interfaces.nsIPrefBranch2;
--    if (Services.prefs.getPrefType(prefURL) != nsIPrefBranch2.PREF_INVALID) {
--      try {
--        var getMoreURL = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
--                                   .getService(Components.interfaces.nsIURLFormatter)
--                                   .formatURLPref(prefURL);
--        getMore.setAttribute("getMoreURL", getMoreURL);
--        showGetMore = getMoreURL != "about:blank";
--      }
--      catch (e) { }
--    }
--    getMore.hidden = !showGetMore;
-   },
- 
-   /* Create the drop down list for emoticons and messagestyles;
-diff --git a/im/content/preferences/themes.xul b/im/content/preferences/themes.xul
-index 454e36696..18ba1f95c 100644
---- a/im/content/preferences/themes.xul
-+++ b/im/content/preferences/themes.xul
-@@ -65,8 +65,6 @@
-               </menupopup>
-             </menulist>
-             <separator orient="vertical" class="thin"/>
--            <label id="getMoreMessageStyles" class="text-link" value="&messageStyleGetMore.label;"
--                   onclick="if (event.button == 0) { gThemePane.openURL(this.getAttribute('getMoreURL')); }"/>
-           </hbox>
-           <separator class="thin"/>
-           <label value="&messageStylePreview.label;"/>
-@@ -115,8 +113,6 @@
-               </menupopup>
-             </menulist>
-             <separator orient="vertical" class="thin"/>
--            <label id="getMoreEmoticons" class="text-link" value="&emoticonsGetMore.label;"
--                   onclick="if (event.button == 0) { gThemePane.openURL(this.getAttribute('getMoreURL')); }"/>
-           </hbox>
-           <separator class="thin"/>
-           <description>&emoticonsPreview.description;</description>
--- 
-2.11.0
-
diff --git a/projects/instantbird/0016-Modify-XMPP-defaults.patch b/projects/instantbird/0016-Modify-XMPP-defaults.patch
deleted file mode 100644
index 9f1a760..0000000
--- a/projects/instantbird/0016-Modify-XMPP-defaults.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 365390f7a795255a6d5c8f1a4e27f44f9b24aeb8 Mon Sep 17 00:00:00 2001
-From: Sukhbir Singh <sukhbir at torproject.org>
-Date: Mon, 10 Oct 2016 19:38:49 -0700
-Subject: [PATCH 16/27] Modify XMPP defaults
-
- * xmpp-default-domain
-
- * xmpp-gtalk-resource
----
- chat/protocols/gtalk/gtalk.js | 2 +-
- chat/protocols/xmpp/xmpp.js   | 4 ++--
- 2 files changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/chat/protocols/gtalk/gtalk.js b/chat/protocols/gtalk/gtalk.js
-index 8bce0c9b4..642f4561d 100644
---- a/chat/protocols/gtalk/gtalk.js
-+++ b/chat/protocols/gtalk/gtalk.js
-@@ -96,7 +96,7 @@ GTalkProtocol.prototype = {
-   getAccount: function(aImAccount) { return new GTalkAccount(this, aImAccount); },
-   options: {
-     resource: {get label() { return _("options.resource"); },
--               get default() { return XMPPDefaultResource; }}
-+               default: "Instantbird"},
-   },
-   get chatHasTopic() { return true; },
-   classID: Components.ID("{38a224c1-6748-49a9-8ab2-efc362b1000d}")
-diff --git a/chat/protocols/xmpp/xmpp.js b/chat/protocols/xmpp/xmpp.js
-index 265445a18..a5635cae3 100644
---- a/chat/protocols/xmpp/xmpp.js
-+++ b/chat/protocols/xmpp/xmpp.js
-@@ -31,12 +31,12 @@ XMPPProtocol.prototype = {
- 
-   usernameSplits: [
-     {get label() { return _("options.domain"); }, separator: "@",
--     defaultValue: "jabber.org", reverse: true}
-+     defaultValue: "", reverse: true}
-   ],
- 
-   options: {
-     resource: {get label() { return _("options.resource"); },
--               get default() { return XMPPDefaultResource; }},
-+               default: "Instantbird"},
-     priority: {get label() { return _("options.priority"); }, default: 0},
-     connection_security: {
-       get label() { return _("options.connectionSecurity"); },
--- 
-2.11.0
-
diff --git a/projects/instantbird/0016-Remove-logging-UI.patch b/projects/instantbird/0016-Remove-logging-UI.patch
new file mode 100644
index 0000000..e547d03
--- /dev/null
+++ b/projects/instantbird/0016-Remove-logging-UI.patch
@@ -0,0 +1,43 @@
+From 1486a399e93f612eb41a2ce3a54d6642ec940c8f Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir at torproject.org>
+Date: Mon, 10 Oct 2016 19:50:48 -0700
+Subject: [PATCH 16/26] Remove logging UI
+
+---
+ im/content/preferences/privacy.xul | 20 --------------------
+ 1 file changed, 20 deletions(-)
+
+diff --git a/im/content/preferences/privacy.xul b/im/content/preferences/privacy.xul
+index 7c9db1cdd..2d7b2701e 100644
+--- a/im/content/preferences/privacy.xul
++++ b/im/content/preferences/privacy.xul
+@@ -66,26 +66,6 @@
+                 preference="purple.conversations.im.send_typing"/>
+     </groupbox>
+ 
+-    <!-- Logs -->
+-    <groupbox id="logsGroup">
+-      <caption label="&logsGroup.label;"/>
+-      <checkbox id="logConversations" label="&logConversations.label;"
+-                accesskey="&logConversations.accesskey;"
+-                preference="purple.logging.log_ims"
+-                onsynctopreference="document.getElementById('purple.logging.log_chats').value = this.checked;"/>
+-      <checkbox id="logSystem" label="&logSystem.label;"
+-                accesskey="&logSystem.accesskey;"
+-                preference="purple.logging.log_system"/>
+-      <separator class="thin"/>
+-      <hbox align="center">
+-        <description control="openLogFolder"
+-                     flex="1">&logShowFolder.description;</description>
+-        <button id="openLogFolder" label="&logShowFolderButton.label;"
+-                accesskey="&logShowFolderButton.accesskey;"
+-                oncommand="gPrivacyPane.openLogFolder();"/>
+-      </hbox>
+-    </groupbox>
+-
+     <!-- Passwords -->
+     <groupbox id="passwordsGroup" orient="vertical">
+       <caption label="&passwords.label;"/>
+-- 
+2.11.0
+
diff --git a/projects/instantbird/0017-Cert-override.patch b/projects/instantbird/0017-Cert-override.patch
new file mode 100644
index 0000000..2a8de75
--- /dev/null
+++ b/projects/instantbird/0017-Cert-override.patch
@@ -0,0 +1,64 @@
+From ef9f118d22410cc5d051740a83f774387c4bbf8d Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir at torproject.org>
+Date: Mon, 10 Oct 2016 19:56:46 -0700
+Subject: [PATCH 17/26] Cert override
+
+---
+ im/app/profile/cert_override.txt | 3 +++
+ im/app/profile/moz.build         | 1 +
+ im/installer/Makefile.in         | 4 +++-
+ im/installer/package-manifest.in | 1 +
+ 4 files changed, 8 insertions(+), 1 deletion(-)
+ create mode 100644 im/app/profile/cert_override.txt
+
+diff --git a/im/app/profile/cert_override.txt b/im/app/profile/cert_override.txt
+new file mode 100644
+index 000000000..4e616f6cf
+--- /dev/null
++++ b/im/app/profile/cert_override.txt
+@@ -0,0 +1,3 @@
++# PSM Certificate Override Settings file
++# This is a generated file!  Do not edit.
++jabber.ccc.de:5222	OID.2.16.840.1.101.3.4.2.1	59:2F:46:18:35:27:AB:40:83:88:82:AB:4C:B4:AE:F4:E2:CF:91:60:74:AB:01:F9:BC:24:39:31:CA:5C:4E:D1	U	AAAAAAAAAAAAAAADAAAAexFL3TB5MRAwDgYDVQQKEwdSb290IENBMR4wHAYDVQQL  ExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNBIENlcnQgU2lnbmlu  ZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRAY2FjZXJ0Lm9yZw==
+diff --git a/im/app/profile/moz.build b/im/app/profile/moz.build
+index 46bc16bd1..b7d4ebd4b 100644
+--- a/im/app/profile/moz.build
++++ b/im/app/profile/moz.build
+@@ -9,6 +9,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3', 'mac', 'cocoa'):
+     DEFINES['HAVE_SHELL_SERVICE'] = 1
+ 
+ FINAL_TARGET_FILES.defaults.profile += [
++    'cert_override.txt',
+     'localstore.rdf',
+     'mimeTypes.rdf',
+ ]
+diff --git a/im/installer/Makefile.in b/im/installer/Makefile.in
+index 25dd67617..5f06e784c 100644
+--- a/im/installer/Makefile.in
++++ b/im/installer/Makefile.in
+@@ -109,7 +109,9 @@ MOZ_PKG_MAC_ICON=branding/disk.icns
+ MOZ_PKG_MAC_EXTRA=--symlink "/Applications:/ "
+ endif
+ 
+-NON_OMNIJAR_FILES =
++NON_OMNIJAR_FILES = \
++       defaults/profile/cert_override.txt \
++       $(NULL)
+ 
+ INSTALL_SDK = 1
+ 
+diff --git a/im/installer/package-manifest.in b/im/installer/package-manifest.in
+index 1174b3dfd..3e35a2e1b 100644
+--- a/im/installer/package-manifest.in
++++ b/im/installer/package-manifest.in
+@@ -160,6 +160,7 @@
+ @RESPATH@/defaults/profile/localstore.rdf
+ @RESPATH@/defaults/profile/prefs.js
+ @RESPATH@/defaults/profile/mimeTypes.rdf
++ at RESPATH@/defaults/profile/cert_override.txt
+ 
+ #ifdef XP_MACOSX
+ @RESPATH@/components/ibDockBadge.js
+-- 
+2.11.0
+
diff --git a/projects/instantbird/0017-Remove-logging-UI.patch b/projects/instantbird/0017-Remove-logging-UI.patch
deleted file mode 100644
index 481fd27..0000000
--- a/projects/instantbird/0017-Remove-logging-UI.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From b7da961febb3d93eb7a056394f61683ba64d3b1c Mon Sep 17 00:00:00 2001
-From: Sukhbir Singh <sukhbir at torproject.org>
-Date: Mon, 10 Oct 2016 19:50:48 -0700
-Subject: [PATCH 17/27] Remove logging UI
-
----
- im/content/preferences/privacy.xul | 20 --------------------
- 1 file changed, 20 deletions(-)
-
-diff --git a/im/content/preferences/privacy.xul b/im/content/preferences/privacy.xul
-index 7c9db1cdd..2d7b2701e 100644
---- a/im/content/preferences/privacy.xul
-+++ b/im/content/preferences/privacy.xul
-@@ -66,26 +66,6 @@
-                 preference="purple.conversations.im.send_typing"/>
-     </groupbox>
- 
--    <!-- Logs -->
--    <groupbox id="logsGroup">
--      <caption label="&logsGroup.label;"/>
--      <checkbox id="logConversations" label="&logConversations.label;"
--                accesskey="&logConversations.accesskey;"
--                preference="purple.logging.log_ims"
--                onsynctopreference="document.getElementById('purple.logging.log_chats').value = this.checked;"/>
--      <checkbox id="logSystem" label="&logSystem.label;"
--                accesskey="&logSystem.accesskey;"
--                preference="purple.logging.log_system"/>
--      <separator class="thin"/>
--      <hbox align="center">
--        <description control="openLogFolder"
--                     flex="1">&logShowFolder.description;</description>
--        <button id="openLogFolder" label="&logShowFolderButton.label;"
--                accesskey="&logShowFolderButton.accesskey;"
--                oncommand="gPrivacyPane.openLogFolder();"/>
--      </hbox>
--    </groupbox>
--
-     <!-- Passwords -->
-     <groupbox id="passwordsGroup" orient="vertical">
-       <caption label="&passwords.label;"/>
--- 
-2.11.0
-
diff --git a/projects/instantbird/0018-Cert-override.patch b/projects/instantbird/0018-Cert-override.patch
deleted file mode 100644
index 63155f0..0000000
--- a/projects/instantbird/0018-Cert-override.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From aebafcab4731aaf8aad4d36ee08b1f205af8e449 Mon Sep 17 00:00:00 2001
-From: Sukhbir Singh <sukhbir at torproject.org>
-Date: Mon, 10 Oct 2016 19:56:46 -0700
-Subject: [PATCH 18/27] Cert override
-
----
- im/app/profile/cert_override.txt | 3 +++
- im/app/profile/moz.build         | 1 +
- im/installer/Makefile.in         | 4 +++-
- im/installer/package-manifest.in | 1 +
- 4 files changed, 8 insertions(+), 1 deletion(-)
- create mode 100644 im/app/profile/cert_override.txt
-
-diff --git a/im/app/profile/cert_override.txt b/im/app/profile/cert_override.txt
-new file mode 100644
-index 000000000..4e616f6cf
---- /dev/null
-+++ b/im/app/profile/cert_override.txt
-@@ -0,0 +1,3 @@
-+# PSM Certificate Override Settings file
-+# This is a generated file!  Do not edit.
-+jabber.ccc.de:5222	OID.2.16.840.1.101.3.4.2.1	59:2F:46:18:35:27:AB:40:83:88:82:AB:4C:B4:AE:F4:E2:CF:91:60:74:AB:01:F9:BC:24:39:31:CA:5C:4E:D1	U	AAAAAAAAAAAAAAADAAAAexFL3TB5MRAwDgYDVQQKEwdSb290IENBMR4wHAYDVQQL  ExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNBIENlcnQgU2lnbmlu  ZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRAY2FjZXJ0Lm9yZw==
-diff --git a/im/app/profile/moz.build b/im/app/profile/moz.build
-index 46bc16bd1..b7d4ebd4b 100644
---- a/im/app/profile/moz.build
-+++ b/im/app/profile/moz.build
-@@ -9,6 +9,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3', 'mac', 'cocoa'):
-     DEFINES['HAVE_SHELL_SERVICE'] = 1
- 
- FINAL_TARGET_FILES.defaults.profile += [
-+    'cert_override.txt',
-     'localstore.rdf',
-     'mimeTypes.rdf',
- ]
-diff --git a/im/installer/Makefile.in b/im/installer/Makefile.in
-index 25dd67617..5f06e784c 100644
---- a/im/installer/Makefile.in
-+++ b/im/installer/Makefile.in
-@@ -109,7 +109,9 @@ MOZ_PKG_MAC_ICON=branding/disk.icns
- MOZ_PKG_MAC_EXTRA=--symlink "/Applications:/ "
- endif
- 
--NON_OMNIJAR_FILES =
-+NON_OMNIJAR_FILES = \
-+       defaults/profile/cert_override.txt \
-+       $(NULL)
- 
- INSTALL_SDK = 1
- 
-diff --git a/im/installer/package-manifest.in b/im/installer/package-manifest.in
-index 1174b3dfd..3e35a2e1b 100644
---- a/im/installer/package-manifest.in
-+++ b/im/installer/package-manifest.in
-@@ -160,6 +160,7 @@
- @RESPATH@/defaults/profile/localstore.rdf
- @RESPATH@/defaults/profile/prefs.js
- @RESPATH@/defaults/profile/mimeTypes.rdf
-+ at RESPATH@/defaults/profile/cert_override.txt
- 
- #ifdef XP_MACOSX
- @RESPATH@/components/ibDockBadge.js
--- 
-2.11.0
-
diff --git a/projects/instantbird/0018-Display-all-traffic-over-Tor.patch b/projects/instantbird/0018-Display-all-traffic-over-Tor.patch
new file mode 100644
index 0000000..4b38188
--- /dev/null
+++ b/projects/instantbird/0018-Display-all-traffic-over-Tor.patch
@@ -0,0 +1,38 @@
+From a8afc6259faa65ef53b61ece6c4f954c5c0f89b1 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir at torproject.org>
+Date: Mon, 10 Oct 2016 19:58:31 -0700
+Subject: [PATCH 18/26] Display all traffic over Tor
+
+---
+ im/content/accountWizard.xul                          | 2 ++
+ im/locales/en-US/chrome/instantbird/accountWizard.dtd | 1 +
+ 2 files changed, 3 insertions(+)
+
+diff --git a/im/content/accountWizard.xul b/im/content/accountWizard.xul
+index a3069061a..3c3a4179b 100644
+--- a/im/content/accountWizard.xul
++++ b/im/content/accountWizard.xul
+@@ -39,6 +39,8 @@
+         <description class="top-proto-description" value="&accountProtocolShowMore.description;"/>
+       </richlistitem>
+     </richlistbox>
++    <separator class="thin"/>
++    <description>&accountProtocolInfo.label3;</description>
+   </wizardpage>
+ 
+   <wizardpage id="accountprotocol" pageid="accountprotocol" next="accountusername"
+diff --git a/im/locales/en-US/chrome/instantbird/accountWizard.dtd b/im/locales/en-US/chrome/instantbird/accountWizard.dtd
+index c46fb2f95..6b49c84fa 100644
+--- a/im/locales/en-US/chrome/instantbird/accountWizard.dtd
++++ b/im/locales/en-US/chrome/instantbird/accountWizard.dtd
+@@ -6,6 +6,7 @@
+ 
+ <!ENTITY accountProtocolTitle.label   "Protocol">
+ <!ENTITY accountProtocolInfo.label2   "Please choose the protocol of your IM account.">
++<!ENTITY accountProtocolInfo.label3   "All traffic will be routed over the Tor network.">
+ <!ENTITY accountProtocolGetMore.label "Get more…">
+ <!ENTITY accountProtocolShowMore.label  "Show all protocols">
+ <!ENTITY accountProtocolShowMore.description  "Choose from the full list of protocols">
+-- 
+2.11.0
+
diff --git a/projects/instantbird/0019-Display-all-traffic-over-Tor.patch b/projects/instantbird/0019-Display-all-traffic-over-Tor.patch
deleted file mode 100644
index 8eeda8f..0000000
--- a/projects/instantbird/0019-Display-all-traffic-over-Tor.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 1bdd9493ad25fbaf63afdd6d26dd3f43a169932a Mon Sep 17 00:00:00 2001
-From: Sukhbir Singh <sukhbir at torproject.org>
-Date: Mon, 10 Oct 2016 19:58:31 -0700
-Subject: [PATCH 19/27] Display all traffic over Tor
-
----
- im/content/accountWizard.xul                          | 2 ++
- im/locales/en-US/chrome/instantbird/accountWizard.dtd | 1 +
- 2 files changed, 3 insertions(+)
-
-diff --git a/im/content/accountWizard.xul b/im/content/accountWizard.xul
-index a3069061a..3c3a4179b 100644
---- a/im/content/accountWizard.xul
-+++ b/im/content/accountWizard.xul
-@@ -39,6 +39,8 @@
-         <description class="top-proto-description" value="&accountProtocolShowMore.description;"/>
-       </richlistitem>
-     </richlistbox>
-+    <separator class="thin"/>
-+    <description>&accountProtocolInfo.label3;</description>
-   </wizardpage>
- 
-   <wizardpage id="accountprotocol" pageid="accountprotocol" next="accountusername"
-diff --git a/im/locales/en-US/chrome/instantbird/accountWizard.dtd b/im/locales/en-US/chrome/instantbird/accountWizard.dtd
-index c46fb2f95..6b49c84fa 100644
---- a/im/locales/en-US/chrome/instantbird/accountWizard.dtd
-+++ b/im/locales/en-US/chrome/instantbird/accountWizard.dtd
-@@ -6,6 +6,7 @@
- 
- <!ENTITY accountProtocolTitle.label   "Protocol">
- <!ENTITY accountProtocolInfo.label2   "Please choose the protocol of your IM account.">
-+<!ENTITY accountProtocolInfo.label3   "All traffic will be routed over the Tor network.">
- <!ENTITY accountProtocolGetMore.label "Get more…">
- <!ENTITY accountProtocolShowMore.label  "Show all protocols">
- <!ENTITY accountProtocolShowMore.description  "Choose from the full list of protocols">
--- 
-2.11.0
-
diff --git a/projects/instantbird/0019-Trac-17480-Content-sink.patch b/projects/instantbird/0019-Trac-17480-Content-sink.patch
new file mode 100644
index 0000000..f08a374
--- /dev/null
+++ b/projects/instantbird/0019-Trac-17480-Content-sink.patch
@@ -0,0 +1,111 @@
+From 4cbffef65c77ae2fa4ecf480a5b38c79200a898f Mon Sep 17 00:00:00 2001
+From: Arlo Breault <arlolra at gmail.com>
+Date: Wed, 5 Oct 2016 11:09:25 -0700
+Subject: [PATCH 19/26] Trac 17480: Content sink
+
+---
+ chat/modules/imContentSink.jsm     | 33 ++++++---------------------------
+ im/content/preferences/content.xul |  2 +-
+ 2 files changed, 7 insertions(+), 28 deletions(-)
+
+diff --git a/chat/modules/imContentSink.jsm b/chat/modules/imContentSink.jsm
+index abd95fc71..fa32442e4 100644
+--- a/chat/modules/imContentSink.jsm
++++ b/chat/modules/imContentSink.jsm
+@@ -42,7 +42,7 @@ this.EXPORTED_SYMBOLS = [
+  *  See the 3 examples of rulesets below.
+  */
+ 
+-var kAllowedURLs = aValue => /^(https?|ftp|mailto):/.test(aValue);
++var kAllowedURLs = aValue => /^(https?|mailto):/.test(aValue);
+ var kAllowedMozClasses =
+   aClassName => aClassName == "moz-txt-underscore" ||
+                 aClassName == "moz-txt-tag" ||
+@@ -60,11 +60,6 @@ var kStrictMode = {
+   attrs: { },
+ 
+   tags: {
+-    'a': {
+-      'title': true,
+-      'href': kAllowedURLs,
+-      'class': kAllowedAnchorClasses
+-    },
+     'br': true,
+     'p': true
+   },
+@@ -74,12 +69,9 @@ var kStrictMode = {
+ 
+ // standard mode allows basic formattings (bold, italic, underlined)
+ var kStandardMode = {
+-  attrs: {
+-    'style': true
+-  },
++  attrs: { },
+ 
+   tags: {
+-    'div': true,
+     'a': {
+       'title': true,
+       'href': kAllowedURLs,
+@@ -90,24 +82,11 @@ var kStandardMode = {
+     'b': true,
+     'i': true,
+     'u': true,
+-    'span': {
+-      'class': kAllowedMozClasses
+-    },
+     'br': true,
+-    'code': true,
+-    'ul': true,
+-    'li': true,
+-    'ol': true,
+-    'cite': true,
+-    'blockquote': true,
+     'p': true
+   },
+ 
+-  styles: {
+-    'font-style': true,
+-    'font-weight': true,
+-    'text-decoration-line': true
+-  }
++  styles: { }
+ };
+ 
+ // permissive mode allows about anything that isn't going to mess up the chat window
+@@ -162,7 +141,7 @@ var kPermissiveMode = {
+ };
+ 
+ var kModePref = "messenger.options.filterMode";
+-var kModes = [kStrictMode, kStandardMode, kPermissiveMode];
++var kModes = [kStrictMode, kStandardMode];
+ 
+ var gGlobalRuleset = null;
+ 
+@@ -188,8 +167,8 @@ var styleObserver = {
+ function getModePref()
+ {
+   let baseNum = Services.prefs.getIntPref(kModePref);
+-  if (baseNum < 0 || baseNum > 2)
+-    baseNum = 1;
++  if (baseNum < 0 || baseNum > 1)
++    baseNum = 0;
+ 
+   return kModes[baseNum];
+ }
+diff --git a/im/content/preferences/content.xul b/im/content/preferences/content.xul
+index 3b8ccfa2b..ba41da76a 100644
+--- a/im/content/preferences/content.xul
++++ b/im/content/preferences/content.xul
+@@ -35,7 +35,7 @@
+       <label control="filterLevel" accesskey="&filterLevel.accesskey;">&filterLevel.label;</label>
+       <menulist id="filterLevel" preference="messenger.options.filterMode">
+         <menupopup>
+-          <menuitem value="2" label="&filterLevelAll;"/>
++          <!-- <menuitem value="2" label="&filterLevelAll;"/> -->
+           <menuitem value="1" label="&filterLevelBasic;"/>
+           <menuitem value="0" label="&filterLevelNone;"/>
+         </menupopup>
+-- 
+2.11.0
+
diff --git a/projects/instantbird/0020-SASL-ECDSA-NIST256P-CHALLENGE.patch b/projects/instantbird/0020-SASL-ECDSA-NIST256P-CHALLENGE.patch
new file mode 100644
index 0000000..385a63d
--- /dev/null
+++ b/projects/instantbird/0020-SASL-ECDSA-NIST256P-CHALLENGE.patch
@@ -0,0 +1,8919 @@
+From e5d30254bb7da7ac6286b8f3e5f062072c170d9d Mon Sep 17 00:00:00 2001
+From: Arlo Breault <arlolra at gmail.com>
+Date: Sun, 2 Oct 2016 08:46:55 -0700
+Subject: [PATCH 20/26] SASL ECDSA-NIST256P-CHALLENGE
+
+---
+ chat/components/src/imAccounts.js |    1 +
+ chat/protocols/irc/elliptic.jsm   | 8748 +++++++++++++++++++++++++++++++++++++
+ chat/protocols/irc/ircSASL.jsm    |   87 +-
+ chat/protocols/irc/moz.build      |    1 +
+ 4 files changed, 8823 insertions(+), 14 deletions(-)
+ create mode 100644 chat/protocols/irc/elliptic.jsm
+
+diff --git a/chat/components/src/imAccounts.js b/chat/components/src/imAccounts.js
+index 5bfea57f2..da8525ffd 100644
+--- a/chat/components/src/imAccounts.js
++++ b/chat/components/src/imAccounts.js
+@@ -193,6 +193,7 @@ function imAccount(aKey, aName, aPrplId)
+ 
+ imAccount.prototype = {
+   __proto__: ClassInfo(["imIAccount", "prplIAccount"], "im account object"),
++  get wrappedJSObject() { return this; },
+ 
+   name: "",
+   id: "",
+diff --git a/chat/protocols/irc/elliptic.jsm b/chat/protocols/irc/elliptic.jsm
+new file mode 100644
+index 000000000..bccab018c
+--- /dev/null
++++ b/chat/protocols/irc/elliptic.jsm
+@@ -0,0 +1,8748 @@
++/* This software is licensed under the MIT License.
++ *
++ * Copyright Fedor Indutny, 2014.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this software and associated documentation files (the "Software"), to deal
++ * in the Software without restriction, including without limitation the rights
++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
++ * copies of the Software, and to permit persons to whom the Software is
++ * furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
++ * SOFTWARE.
++ */
++
++this.EXPORTED_SYMBOLS = ["elliptic"];
++
++var window = {};
++
++// The code below is imported from indutny's elliptic.js.  The original version
++// of this file can be found at
++// https://github.com/indutny/elliptic/blob/master/dist/elliptic.js
++
++(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.elliptic = 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<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
++(function (module, exports) {
++  'use strict';
++
++  // Utils
++  function assert (val, msg) {
++    if (!val) throw new Error(msg || 'Assertion failed');
++  }
++
++  // Could use `inherits` module, but don't want to move from single file
++  // architecture yet.
++  function inherits (ctor, superCtor) {
++    ctor.super_ = superCtor;
++    var TempCtor = function () {};
++    TempCtor.prototype = superCtor.prototype;
++    ctor.prototype = new TempCtor();
++    ctor.prototype.constructor = ctor;
++  }
++
++  // BN
++
++  function BN (number, base, endian) {
++    if (BN.isBN(number)) {
++      return number;
++    }
++
++    this.negative = 0;
++    this.words = null;
++    this.length = 0;
++
++    // Reduction context
++    this.red = null;
++
++    if (number !== null) {
++      if (base === 'le' || base === 'be') {
++        endian = base;
++        base = 10;
++      }
++
++      this._init(number || 0, base || 10, endian || 'be');
++    }
++  }
++  if (typeof module === 'object') {
++    module.exports = BN;
++  } else {
++    exports.BN = BN;
++  }
++
++  BN.BN = BN;
++  BN.wordSize = 26;
++
++  var Buffer;
++  try {
++    Buffer = require('buf' + 'fer').Buffer;
++  } catch (e) {
++  }
++
++  BN.isBN = function isBN (num) {
++    if (num instanceof BN) {
++      return true;
++    }
++
++    return num !== null && typeof num === 'object' &&
++      num.constructor.wordSize === BN.wordSize && Array.isArray(num.words);
++  };
++
++  BN.max = function max (left, right) {
++    if (left.cmp(right) > 0) return left;
++    return right;
++  };
++
++  BN.min = function min (left, right) {
++    if (left.cmp(right) < 0) return left;
++    return right;
++  };
++
++  BN.prototype._init = function init (number, base, endian) {
++    if (typeof number === 'number') {
++      return this._initNumber(number, base, endian);
++    }
++
++    if (typeof number === 'object') {
++      return this._initArray(number, base, endian);
++    }
++
++    if (base === 'hex') {
++      base = 16;
++    }
++    assert(base === (base | 0) && base >= 2 && base <= 36);
++
++    number = number.toString().replace(/\s+/g, '');
++    var start = 0;
++    if (number[0] === '-') {
++      start++;
++    }
++
++    if (base === 16) {
++      this._parseHex(number, start);
++    } else {
++      this._parseBase(number, base, start);
++    }
++
++    if (number[0] === '-') {
++      this.negative = 1;
++    }
++
++    this.strip();
++
++    if (endian !== 'le') return;
++
++    this._initArray(this.toArray(), base, endian);
++  };
++
++  BN.prototype._initNumber = function _initNumber (number, base, endian) {
++    if (number < 0) {
++      this.negative = 1;
++      number = -number;
++    }
++    if (number < 0x4000000) {
++      this.words = [ number & 0x3ffffff ];
++      this.length = 1;
++    } else if (number < 0x10000000000000) {
++      this.words = [
++        number & 0x3ffffff,
++        (number / 0x4000000) & 0x3ffffff
++      ];
++      this.length = 2;
++    } else {
++      assert(number < 0x20000000000000); // 2 ^ 53 (unsafe)
++      this.words = [
++        number & 0x3ffffff,
++        (number / 0x4000000) & 0x3ffffff,
++        1
++      ];
++      this.length = 3;
++    }
++
++    if (endian !== 'le') return;
++
++    // Reverse the bytes
++    this._initArray(this.toArray(), base, endian);
++  };
++
++  BN.prototype._initArray = function _initArray (number, base, endian) {
++    // Perhaps a Uint8Array
++    assert(typeof number.length === 'number');
++    if (number.length <= 0) {
++      this.words = [ 0 ];
++      this.length = 1;
++      return this;
++    }
++
++    this.length = Math.ceil(number.length / 3);
++    this.words = new Array(this.length);
++    for (var i = 0; i < this.length; i++) {
++      this.words[i] = 0;
++    }
++
++    var j, w;
++    var off = 0;
++    if (endian === 'be') {
++      for (i = number.length - 1, j = 0; i >= 0; i -= 3) {
++        w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16);
++        this.words[j] |= (w << off) & 0x3ffffff;
++        this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
++        off += 24;
++        if (off >= 26) {
++          off -= 26;
++          j++;
++        }
++      }
++    } else if (endian === 'le') {
++      for (i = 0, j = 0; i < number.length; i += 3) {
++        w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16);
++        this.words[j] |= (w << off) & 0x3ffffff;
++        this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
++        off += 24;
++        if (off >= 26) {
++          off -= 26;
++          j++;
++        }
++      }
++    }
++    return this.strip();
++  };
++
++  function parseHex (str, start, end) {
++    var r = 0;
++    var len = Math.min(str.length, end);
++    for (var i = start; i < len; i++) {
++      var c = str.charCodeAt(i) - 48;
++
++      r <<= 4;
++
++      // 'a' - 'f'
++      if (c >= 49 && c <= 54) {
++        r |= c - 49 + 0xa;
++
++      // 'A' - 'F'
++      } else if (c >= 17 && c <= 22) {
++        r |= c - 17 + 0xa;
++
++      // '0' - '9'
++      } else {
++        r |= c & 0xf;
++      }
++    }
++    return r;
++  }
++
++  BN.prototype._parseHex = function _parseHex (number, start) {
++    // Create possibly bigger array to ensure that it fits the number
++    this.length = Math.ceil((number.length - start) / 6);
++    this.words = new Array(this.length);
++    for (var i = 0; i < this.length; i++) {
++      this.words[i] = 0;
++    }
++
++    var j, w;
++    // Scan 24-bit chunks and add them to the number
++    var off = 0;
++    for (i = number.length - 6, j = 0; i >= start; i -= 6) {
++      w = parseHex(number, i, i + 6);
++      this.words[j] |= (w << off) & 0x3ffffff;
++      // NOTE: `0x3fffff` is intentional here, 26bits max shift + 24bit hex limb
++      this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
++      off += 24;
++      if (off >= 26) {
++        off -= 26;
++        j++;
++      }
++    }
++    if (i + 6 !== start) {
++      w = parseHex(number, start, i + 6);
++      this.words[j] |= (w << off) & 0x3ffffff;
++      this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
++    }
++    this.strip();
++  };
++
++  function parseBase (str, start, end, mul) {
++    var r = 0;
++    var len = Math.min(str.length, end);
++    for (var i = start; i < len; i++) {
++      var c = str.charCodeAt(i) - 48;
++
++      r *= mul;
++
++      // 'a'
++      if (c >= 49) {
++        r += c - 49 + 0xa;
++
++      // 'A'
++      } else if (c >= 17) {
++        r += c - 17 + 0xa;
++
++      // '0' - '9'
++      } else {
++        r += c;
++      }
++    }
++    return r;
++  }
++
++  BN.prototype._parseBase = function _parseBase (number, base, start) {
++    // Initialize as zero
++    this.words = [ 0 ];
++    this.length = 1;
++
++    // Find length of limb in base
++    for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) {
++      limbLen++;
++    }
++    limbLen--;
++    limbPow = (limbPow / base) | 0;
++
++    var total = number.length - start;
++    var mod = total % limbLen;
++    var end = Math.min(total, total - mod) + start;
++
++    var word = 0;
++    for (var i = start; i < end; i += limbLen) {
++      word = parseBase(number, i, i + limbLen, base);
++
++      this.imuln(limbPow);
++      if (this.words[0] + word < 0x4000000) {
++        this.words[0] += word;
++      } else {
++        this._iaddn(word);
++      }
++    }
++
++    if (mod !== 0) {
++      var pow = 1;
++      word = parseBase(number, i, number.length, base);
++
++      for (i = 0; i < mod; i++) {
++        pow *= base;
++      }
++
++      this.imuln(pow);
++      if (this.words[0] + word < 0x4000000) {
++        this.words[0] += word;
++      } else {
++        this._iaddn(word);
++      }
++    }
++  };
++
++  BN.prototype.copy = function copy (dest) {
++    dest.words = new Array(this.length);
++    for (var i = 0; i < this.length; i++) {
++      dest.words[i] = this.words[i];
++    }
++    dest.length = this.length;
++    dest.negative = this.negative;
++    dest.red = this.red;
++  };
++
++  BN.prototype.clone = function clone () {
++    var r = new BN(null);
++    this.copy(r);
++    return r;
++  };
++
++  BN.prototype._expand = function _expand (size) {
++    while (this.length < size) {
++      this.words[this.length++] = 0;
++    }
++    return this;
++  };
++
++  // Remove leading `0` from `this`
++  BN.prototype.strip = function strip () {
++    while (this.length > 1 && this.words[this.length - 1] === 0) {
++      this.length--;
++    }
++    return this._normSign();
++  };
++
++  BN.prototype._normSign = function _normSign () {
++    // -0 = 0
++    if (this.length === 1 && this.words[0] === 0) {
++      this.negative = 0;
++    }
++    return this;
++  };
++
++  BN.prototype.inspect = function inspect () {
++    return (this.red ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>';
++  };
++
++  /*
++
++  var zeros = [];
++  var groupSizes = [];
++  var groupBases = [];
++
++  var s = '';
++  var i = -1;
++  while (++i < BN.wordSize) {
++    zeros[i] = s;
++    s += '0';
++  }
++  groupSizes[0] = 0;
++  groupSizes[1] = 0;
++  groupBases[0] = 0;
++  groupBases[1] = 0;
++  var base = 2 - 1;
++  while (++base < 36 + 1) {
++    var groupSize = 0;
++    var groupBase = 1;
++    while (groupBase < (1 << BN.wordSize) / base) {
++      groupBase *= base;
++      groupSize += 1;
++    }
++    groupSizes[base] = groupSize;
++    groupBases[base] = groupBase;
++  }
++
++  */
++
++  var zeros = [
++    '',
++    '0',
++    '00',
++    '000',
++    '0000',
++    '00000',
++    '000000',
++    '0000000',
++    '00000000',
++    '000000000',
++    '0000000000',
++    '00000000000',
++    '000000000000',
++    '0000000000000',
++    '00000000000000',
++    '000000000000000',
++    '0000000000000000',
++    '00000000000000000',
++    '000000000000000000',
++    '0000000000000000000',
++    '00000000000000000000',
++    '000000000000000000000',
++    '0000000000000000000000',
++    '00000000000000000000000',
++    '000000000000000000000000',
++    '0000000000000000000000000'
++  ];
++
++  var groupSizes = [
++    0, 0,
++    25, 16, 12, 11, 10, 9, 8,
++    8, 7, 7, 7, 7, 6, 6,
++    6, 6, 6, 6, 6, 5, 5,
++    5, 5, 5, 5, 5, 5, 5,
++    5, 5, 5, 5, 5, 5, 5
++  ];
++
++  var groupBases = [
++    0, 0,
++    33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216,
++    43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625,
++    16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632,
++    6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149,
++    24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176
++  ];
++
++  BN.prototype.toString = function toString (base, padding) {
++    base = base || 10;
++    padding = padding | 0 || 1;
++
++    var out;
++    if (base === 16 || base === 'hex') {
++      out = '';
++      var off = 0;
++      var carry = 0;
++      for (var i = 0; i < this.length; i++) {
++        var w = this.words[i];
++        var word = (((w << off) | carry) & 0xffffff).toString(16);
++        carry = (w >>> (24 - off)) & 0xffffff;
++        if (carry !== 0 || i !== this.length - 1) {
++          out = zeros[6 - word.length] + word + out;
++        } else {
++          out = word + out;
++        }
++        off += 2;
++        if (off >= 26) {
++          off -= 26;
++          i--;
++        }
++      }
++      if (carry !== 0) {
++        out = carry.toString(16) + out;
++      }
++      while (out.length % padding !== 0) {
++        out = '0' + out;
++      }
++      if (this.negative !== 0) {
++        out = '-' + out;
++      }
++      return out;
++    }
++
++    if (base === (base | 0) && base >= 2 && base <= 36) {
++      // var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base));
++      var groupSize = groupSizes[base];
++      // var groupBase = Math.pow(base, groupSize);
++      var groupBase = groupBases[base];
++      out = '';
++      var c = this.clone();
++      c.negative = 0;
++      while (!c.isZero()) {
++        var r = c.modn(groupBase).toString(base);
++        c = c.idivn(groupBase);
++
++        if (!c.isZero()) {
++          out = zeros[groupSize - r.length] + r + out;
++        } else {
++          out = r + out;
++        }
++      }
++      if (this.isZero()) {
++        out = '0' + out;
++      }
++      while (out.length % padding !== 0) {
++        out = '0' + out;
++      }
++      if (this.negative !== 0) {
++        out = '-' + out;
++      }
++      return out;
++    }
++
++    assert(false, 'Base should be between 2 and 36');
++  };
++
++  BN.prototype.toNumber = function toNumber () {
++    var ret = this.words[0];
++    if (this.length === 2) {
++      ret += this.words[1] * 0x4000000;
++    } else if (this.length === 3 && this.words[2] === 0x01) {
++      // NOTE: at this stage it is known that the top bit is set
++      ret += 0x10000000000000 + (this.words[1] * 0x4000000);
++    } else if (this.length > 2) {
++      assert(false, 'Number can only safely store up to 53 bits');
++    }
++    return (this.negative !== 0) ? -ret : ret;
++  };
++
++  BN.prototype.toJSON = function toJSON () {
++    return this.toString(16);
++  };
++
++  BN.prototype.toBuffer = function toBuffer (endian, length) {
++    assert(typeof Buffer !== 'undefined');
++    return this.toArrayLike(Buffer, endian, length);
++  };
++
++  BN.prototype.toArray = function toArray (endian, length) {
++    return this.toArrayLike(Array, endian, length);
++  };
++
++  BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) {
++    var byteLength = this.byteLength();
++    var reqLength = length || Math.max(1, byteLength);
++    assert(byteLength <= reqLength, 'byte array longer than desired length');
++    assert(reqLength > 0, 'Requested array length <= 0');
++
++    this.strip();
++    var littleEndian = endian === 'le';
++    var res = new ArrayType(reqLength);
++
++    var b, i;
++    var q = this.clone();
++    if (!littleEndian) {
++      // Assume big-endian
++      for (i = 0; i < reqLength - byteLength; i++) {
++        res[i] = 0;
++      }
++
++      for (i = 0; !q.isZero(); i++) {
++        b = q.andln(0xff);
++        q.iushrn(8);
++
++        res[reqLength - i - 1] = b;
++      }
++    } else {
++      for (i = 0; !q.isZero(); i++) {
++        b = q.andln(0xff);
++        q.iushrn(8);
++
++        res[i] = b;
++      }
++
++      for (; i < reqLength; i++) {
++        res[i] = 0;
++      }
++    }
++
++    return res;
++  };
++
++  if (Math.clz32) {
++    BN.prototype._countBits = function _countBits (w) {
++      return 32 - Math.clz32(w);
++    };
++  } else {
++    BN.prototype._countBits = function _countBits (w) {
++      var t = w;
++      var r = 0;
++      if (t >= 0x1000) {
++        r += 13;
++        t >>>= 13;
++      }
++      if (t >= 0x40) {
++        r += 7;
++        t >>>= 7;
++      }
++      if (t >= 0x8) {
++        r += 4;
++        t >>>= 4;
++      }
++      if (t >= 0x02) {
++        r += 2;
++        t >>>= 2;
++      }
++      return r + t;
++    };
++  }
++
++  BN.prototype._zeroBits = function _zeroBits (w) {
++    // Short-cut
++    if (w === 0) return 26;
++
++    var t = w;
++    var r = 0;
++    if ((t & 0x1fff) === 0) {
++      r += 13;
++      t >>>= 13;
++    }
++    if ((t & 0x7f) === 0) {
++      r += 7;
++      t >>>= 7;
++    }
++    if ((t & 0xf) === 0) {
++      r += 4;
++      t >>>= 4;
++    }
++    if ((t & 0x3) === 0) {
++      r += 2;
++      t >>>= 2;
++    }
++    if ((t & 0x1) === 0) {
++      r++;
++    }
++    return r;
++  };
++
++  // Return number of used bits in a BN
++  BN.prototype.bitLength = function bitLength () {
++    var w = this.words[this.length - 1];
++    var hi = this._countBits(w);
++    return (this.length - 1) * 26 + hi;
++  };
++
++  function toBitArray (num) {
++    var w = new Array(num.bitLength());
++
++    for (var bit = 0; bit < w.length; bit++) {
++      var off = (bit / 26) | 0;
++      var wbit = bit % 26;
++
++      w[bit] = (num.words[off] & (1 << wbit)) >>> wbit;
++    }
++
++    return w;
++  }
++
++  // Number of trailing zero bits
++  BN.prototype.zeroBits = function zeroBits () {
++    if (this.isZero()) return 0;
++
++    var r = 0;
++    for (var i = 0; i < this.length; i++) {
++      var b = this._zeroBits(this.words[i]);
++      r += b;
++      if (b !== 26) break;
++    }
++    return r;
++  };
++
++  BN.prototype.byteLength = function byteLength () {
++    return Math.ceil(this.bitLength() / 8);
++  };
++
++  BN.prototype.toTwos = function toTwos (width) {
++    if (this.negative !== 0) {
++      return this.abs().inotn(width).iaddn(1);
++    }
++    return this.clone();
++  };
++
++  BN.prototype.fromTwos = function fromTwos (width) {
++    if (this.testn(width - 1)) {
++      return this.notn(width).iaddn(1).ineg();
++    }
++    return this.clone();
++  };
++
++  BN.prototype.isNeg = function isNeg () {
++    return this.negative !== 0;
++  };
++
++  // Return negative clone of `this`
++  BN.prototype.neg = function neg () {
++    return this.clone().ineg();
++  };
++
++  BN.prototype.ineg = function ineg () {
++    if (!this.isZero()) {
++      this.negative ^= 1;
++    }
++
++    return this;
++  };
++
++  // Or `num` with `this` in-place
++  BN.prototype.iuor = function iuor (num) {
++    while (this.length < num.length) {
++      this.words[this.length++] = 0;
++    }
++
++    for (var i = 0; i < num.length; i++) {
++      this.words[i] = this.words[i] | num.words[i];
++    }
++
++    return this.strip();
++  };
++
++  BN.prototype.ior = function ior (num) {
++    assert((this.negative | num.negative) === 0);
++    return this.iuor(num);
++  };
++
++  // Or `num` with `this`
++  BN.prototype.or = function or (num) {
++    if (this.length > num.length) return this.clone().ior(num);
++    return num.clone().ior(this);
++  };
++
++  BN.prototype.uor = function uor (num) {
++    if (this.length > num.length) return this.clone().iuor(num);
++    return num.clone().iuor(this);
++  };
++
++  // And `num` with `this` in-place
++  BN.prototype.iuand = function iuand (num) {
++    // b = min-length(num, this)
++    var b;
++    if (this.length > num.length) {
++      b = num;
++    } else {
++      b = this;
++    }
++
++    for (var i = 0; i < b.length; i++) {
++      this.words[i] = this.words[i] & num.words[i];
++    }
++
++    this.length = b.length;
++
++    return this.strip();
++  };
++
++  BN.prototype.iand = function iand (num) {
++    assert((this.negative | num.negative) === 0);
++    return this.iuand(num);
++  };
++
++  // And `num` with `this`
++  BN.prototype.and = function and (num) {
++    if (this.length > num.length) return this.clone().iand(num);
++    return num.clone().iand(this);
++  };
++
++  BN.prototype.uand = function uand (num) {
++    if (this.length > num.length) return this.clone().iuand(num);
++    return num.clone().iuand(this);
++  };
++
++  // Xor `num` with `this` in-place
++  BN.prototype.iuxor = function iuxor (num) {
++    // a.length > b.length
++    var a;
++    var b;
++    if (this.length > num.length) {
++      a = this;
++      b = num;
++    } else {
++      a = num;
++      b = this;
++    }
++
++    for (var i = 0; i < b.length; i++) {
++      this.words[i] = a.words[i] ^ b.words[i];
++    }
++
++    if (this !== a) {
++      for (; i < a.length; i++) {
++        this.words[i] = a.words[i];
++      }
++    }
++
++    this.length = a.length;
++
++    return this.strip();
++  };
++
++  BN.prototype.ixor = function ixor (num) {
++    assert((this.negative | num.negative) === 0);
++    return this.iuxor(num);
++  };
++
++  // Xor `num` with `this`
++  BN.prototype.xor = function xor (num) {
++    if (this.length > num.length) return this.clone().ixor(num);
++    return num.clone().ixor(this);
++  };
++
++  BN.prototype.uxor = function uxor (num) {
++    if (this.length > num.length) return this.clone().iuxor(num);
++    return num.clone().iuxor(this);
++  };
++
++  // Not ``this`` with ``width`` bitwidth
++  BN.prototype.inotn = function inotn (width) {
++    assert(typeof width === 'number' && width >= 0);
++
++    var bytesNeeded = Math.ceil(width / 26) | 0;
++    var bitsLeft = width % 26;
++
++    // Extend the buffer with leading zeroes
++    this._expand(bytesNeeded);
++
++    if (bitsLeft > 0) {
++      bytesNeeded--;
++    }
++
++    // Handle complete words
++    for (var i = 0; i < bytesNeeded; i++) {
++      this.words[i] = ~this.words[i] & 0x3ffffff;
++    }
++
++    // Handle the residue
++    if (bitsLeft > 0) {
++      this.words[i] = ~this.words[i] & (0x3ffffff >> (26 - bitsLeft));
++    }
++
++    // And remove leading zeroes
++    return this.strip();
++  };
++
++  BN.prototype.notn = function notn (width) {
++    return this.clone().inotn(width);
++  };
++
++  // Set `bit` of `this`
++  BN.prototype.setn = function setn (bit, val) {
++    assert(typeof bit === 'number' && bit >= 0);
++
++    var off = (bit / 26) | 0;
++    var wbit = bit % 26;
++
++    this._expand(off + 1);
++
++    if (val) {
++      this.words[off] = this.words[off] | (1 << wbit);
++    } else {
++      this.words[off] = this.words[off] & ~(1 << wbit);
++    }
++
++    return this.strip();
++  };
++
++  // Add `num` to `this` in-place
++  BN.prototype.iadd = function iadd (num) {
++    var r;
++
++    // negative + positive
++    if (this.negative !== 0 && num.negative === 0) {
++      this.negative = 0;
++      r = this.isub(num);
++      this.negative ^= 1;
++      return this._normSign();
++
++    // positive + negative
++    } else if (this.negative === 0 && num.negative !== 0) {
++      num.negative = 0;
++      r = this.isub(num);
++      num.negative = 1;
++      return r._normSign();
++    }
++
++    // a.length > b.length
++    var a, b;
++    if (this.length > num.length) {
++      a = this;
++      b = num;
++    } else {
++      a = num;
++      b = this;
++    }
++
++    var carry = 0;
++    for (var i = 0; i < b.length; i++) {
++      r = (a.words[i] | 0) + (b.words[i] | 0) + carry;
++      this.words[i] = r & 0x3ffffff;
++      carry = r >>> 26;
++    }
++    for (; carry !== 0 && i < a.length; i++) {
++      r = (a.words[i] | 0) + carry;
++      this.words[i] = r & 0x3ffffff;
++      carry = r >>> 26;
++    }
++
++    this.length = a.length;
++    if (carry !== 0) {
++      this.words[this.length] = carry;
++      this.length++;
++    // Copy the rest of the words
++    } else if (a !== this) {
++      for (; i < a.length; i++) {
++        this.words[i] = a.words[i];
++      }
++    }
++
++    return this;
++  };
++
++  // Add `num` to `this`
++  BN.prototype.add = function add (num) {
++    var res;
++    if (num.negative !== 0 && this.negative === 0) {
++      num.negative = 0;
++      res = this.sub(num);
++      num.negative ^= 1;
++      return res;
++    } else if (num.negative === 0 && this.negative !== 0) {
++      this.negative = 0;
++      res = num.sub(this);
++      this.negative = 1;
++      return res;
++    }
++
++    if (this.length > num.length) return this.clone().iadd(num);
++
++    return num.clone().iadd(this);
++  };
++
++  // Subtract `num` from `this` in-place
++  BN.prototype.isub = function isub (num) {
++    // this - (-num) = this + num
++    if (num.negative !== 0) {
++      num.negative = 0;
++      var r = this.iadd(num);
++      num.negative = 1;
++      return r._normSign();
++
++    // -this - num = -(this + num)
++    } else if (this.negative !== 0) {
++      this.negative = 0;
++      this.iadd(num);
++      this.negative = 1;
++      return this._normSign();
++    }
++
++    // At this point both numbers are positive
++    var cmp = this.cmp(num);
++
++    // Optimization - zeroify
++    if (cmp === 0) {
++      this.negative = 0;
++      this.length = 1;
++      this.words[0] = 0;
++      return this;
++    }
++
++    // a > b
++    var a, b;
++    if (cmp > 0) {
++      a = this;
++      b = num;
++    } else {
++      a = num;
++      b = this;
++    }
++
++    var carry = 0;
++    for (var i = 0; i < b.length; i++) {
++      r = (a.words[i] | 0) - (b.words[i] | 0) + carry;
++      carry = r >> 26;
++      this.words[i] = r & 0x3ffffff;
++    }
++    for (; carry !== 0 && i < a.length; i++) {
++      r = (a.words[i] | 0) + carry;
++      carry = r >> 26;
++      this.words[i] = r & 0x3ffffff;
++    }
++
++    // Copy rest of the words
++    if (carry === 0 && i < a.length && a !== this) {
++      for (; i < a.length; i++) {
++        this.words[i] = a.words[i];
++      }
++    }
++
++    this.length = Math.max(this.length, i);
++
++    if (a !== this) {
++      this.negative = 1;
++    }
++
++    return this.strip();
++  };
++
++  // Subtract `num` from `this`
++  BN.prototype.sub = function sub (num) {
++    return this.clone().isub(num);
++  };
++
++  function smallMulTo (self, num, out) {
++    out.negative = num.negative ^ self.negative;
++    var len = (self.length + num.length) | 0;
++    out.length = len;
++    len = (len - 1) | 0;
++
++    // Peel one iteration (compiler can't do it, because of code complexity)
++    var a = self.words[0] | 0;
++    var b = num.words[0] | 0;
++    var r = a * b;
++
++    var lo = r & 0x3ffffff;
++    var carry = (r / 0x4000000) | 0;
++    out.words[0] = lo;
++
++    for (var k = 1; k < len; k++) {
++      // Sum all words with the same `i + j = k` and accumulate `ncarry`,
++      // note that ncarry could be >= 0x3ffffff
++      var ncarry = carry >>> 26;
++      var rword = carry & 0x3ffffff;
++      var maxJ = Math.min(k, num.length - 1);
++      for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
++        var i = (k - j) | 0;
++        a = self.words[i] | 0;
++        b = num.words[j] | 0;
++        r = a * b + rword;
++        ncarry += (r / 0x4000000) | 0;
++        rword = r & 0x3ffffff;
++      }
++      out.words[k] = rword | 0;
++      carry = ncarry | 0;
++    }
++    if (carry !== 0) {
++      out.words[k] = carry | 0;
++    } else {
++      out.length--;
++    }
++
++    return out.strip();
++  }
++
++  // TODO(indutny): it may be reasonable to omit it for users who don't need
++  // to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit
++  // multiplication (like elliptic secp256k1).
++  var comb10MulTo = function comb10MulTo (self, num, out) {
++    var a = self.words;
++    var b = num.words;
++    var o = out.words;
++    var c = 0;
++    var lo;
++    var mid;
++    var hi;
++    var a0 = a[0] | 0;
++    var al0 = a0 & 0x1fff;
++    var ah0 = a0 >>> 13;
++    var a1 = a[1] | 0;
++    var al1 = a1 & 0x1fff;
++    var ah1 = a1 >>> 13;
++    var a2 = a[2] | 0;
++    var al2 = a2 & 0x1fff;
++    var ah2 = a2 >>> 13;
++    var a3 = a[3] | 0;
++    var al3 = a3 & 0x1fff;
++    var ah3 = a3 >>> 13;
++    var a4 = a[4] | 0;
++    var al4 = a4 & 0x1fff;
++    var ah4 = a4 >>> 13;
++    var a5 = a[5] | 0;
++    var al5 = a5 & 0x1fff;
++    var ah5 = a5 >>> 13;
++    var a6 = a[6] | 0;
++    var al6 = a6 & 0x1fff;
++    var ah6 = a6 >>> 13;
++    var a7 = a[7] | 0;
++    var al7 = a7 & 0x1fff;
++    var ah7 = a7 >>> 13;
++    var a8 = a[8] | 0;
++    var al8 = a8 & 0x1fff;
++    var ah8 = a8 >>> 13;
++    var a9 = a[9] | 0;
++    var al9 = a9 & 0x1fff;
++    var ah9 = a9 >>> 13;
++    var b0 = b[0] | 0;
++    var bl0 = b0 & 0x1fff;
++    var bh0 = b0 >>> 13;
++    var b1 = b[1] | 0;
++    var bl1 = b1 & 0x1fff;
++    var bh1 = b1 >>> 13;
++    var b2 = b[2] | 0;
++    var bl2 = b2 & 0x1fff;
++    var bh2 = b2 >>> 13;
++    var b3 = b[3] | 0;
++    var bl3 = b3 & 0x1fff;
++    var bh3 = b3 >>> 13;
++    var b4 = b[4] | 0;
++    var bl4 = b4 & 0x1fff;
++    var bh4 = b4 >>> 13;
++    var b5 = b[5] | 0;
++    var bl5 = b5 & 0x1fff;
++    var bh5 = b5 >>> 13;
++    var b6 = b[6] | 0;
++    var bl6 = b6 & 0x1fff;
++    var bh6 = b6 >>> 13;
++    var b7 = b[7] | 0;
++    var bl7 = b7 & 0x1fff;
++    var bh7 = b7 >>> 13;
++    var b8 = b[8] | 0;
++    var bl8 = b8 & 0x1fff;
++    var bh8 = b8 >>> 13;
++    var b9 = b[9] | 0;
++    var bl9 = b9 & 0x1fff;
++    var bh9 = b9 >>> 13;
++
++    out.negative = self.negative ^ num.negative;
++    out.length = 19;
++    /* k = 0 */
++    lo = Math.imul(al0, bl0);
++    mid = Math.imul(al0, bh0);
++    mid = (mid + Math.imul(ah0, bl0)) | 0;
++    hi = Math.imul(ah0, bh0);
++    var w0 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
++    c = (((hi + (mid >>> 13)) | 0) + (w0 >>> 26)) | 0;
++    w0 &= 0x3ffffff;
++    /* k = 1 */
++    lo = Math.imul(al1, bl0);
++    mid = Math.imul(al1, bh0);
++    mid = (mid + Math.imul(ah1, bl0)) | 0;
++    hi = Math.imul(ah1, bh0);
++    lo = (lo + Math.imul(al0, bl1)) | 0;
++    mid = (mid + Math.imul(al0, bh1)) | 0;
++    mid = (mid + Math.imul(ah0, bl1)) | 0;
++    hi = (hi + Math.imul(ah0, bh1)) | 0;
++    var w1 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
++    c = (((hi + (mid >>> 13)) | 0) + (w1 >>> 26)) | 0;
++    w1 &= 0x3ffffff;
++    /* k = 2 */
++    lo = Math.imul(al2, bl0);
++    mid = Math.imul(al2, bh0);
++    mid = (mid + Math.imul(ah2, bl0)) | 0;
++    hi = Math.imul(ah2, bh0);
++    lo = (lo + Math.imul(al1, bl1)) | 0;
++    mid = (mid + Math.imul(al1, bh1)) | 0;
++    mid = (mid + Math.imul(ah1, bl1)) | 0;
++    hi = (hi + Math.imul(ah1, bh1)) | 0;
++    lo = (lo + Math.imul(al0, bl2)) | 0;
++    mid = (mid + Math.imul(al0, bh2)) | 0;
++    mid = (mid + Math.imul(ah0, bl2)) | 0;
++    hi = (hi + Math.imul(ah0, bh2)) | 0;
++    var w2 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
++    c = (((hi + (mid >>> 13)) | 0) + (w2 >>> 26)) | 0;
++    w2 &= 0x3ffffff;
++    /* k = 3 */
++    lo = Math.imul(al3, bl0);
++    mid = Math.imul(al3, bh0);
++    mid = (mid + Math.imul(ah3, bl0)) | 0;
++    hi = Math.imul(ah3, bh0);
++    lo = (lo + Math.imul(al2, bl1)) | 0;
++    mid = (mid + Math.imul(al2, bh1)) | 0;
++    mid = (mid + Math.imul(ah2, bl1)) | 0;
++    hi = (hi + Math.imul(ah2, bh1)) | 0;
++    lo = (lo + Math.imul(al1, bl2)) | 0;
++    mid = (mid + Math.imul(al1, bh2)) | 0;
++    mid = (mid + Math.imul(ah1, bl2)) | 0;
++    hi = (hi + Math.imul(ah1, bh2)) | 0;
++    lo = (lo + Math.imul(al0, bl3)) | 0;
++    mid = (mid + Math.imul(al0, bh3)) | 0;
++    mid = (mid + Math.imul(ah0, bl3)) | 0;
++    hi = (hi + Math.imul(ah0, bh3)) | 0;
++    var w3 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
++    c = (((hi + (mid >>> 13)) | 0) + (w3 >>> 26)) | 0;
++    w3 &= 0x3ffffff;
++    /* k = 4 */
++    lo = Math.imul(al4, bl0);
++    mid = Math.imul(al4, bh0);
++    mid = (mid + Math.imul(ah4, bl0)) | 0;
++    hi = Math.imul(ah4, bh0);
++    lo = (lo + Math.imul(al3, bl1)) | 0;
++    mid = (mid + Math.imul(al3, bh1)) | 0;
++    mid = (mid + Math.imul(ah3, bl1)) | 0;
++    hi = (hi + Math.imul(ah3, bh1)) | 0;
++    lo = (lo + Math.imul(al2, bl2)) | 0;
++    mid = (mid + Math.imul(al2, bh2)) | 0;
++    mid = (mid + Math.imul(ah2, bl2)) | 0;
++    hi = (hi + Math.imul(ah2, bh2)) | 0;
++    lo = (lo + Math.imul(al1, bl3)) | 0;
++    mid = (mid + Math.imul(al1, bh3)) | 0;
++    mid = (mid + Math.imul(ah1, bl3)) | 0;
++    hi = (hi + Math.imul(ah1, bh3)) | 0;
++    lo = (lo + Math.imul(al0, bl4)) | 0;
++    mid = (mid + Math.imul(al0, bh4)) | 0;
++    mid = (mid + Math.imul(ah0, bl4)) | 0;
++    hi = (hi + Math.imul(ah0, bh4)) | 0;
++    var w4 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
++    c = (((hi + (mid >>> 13)) | 0) + (w4 >>> 26)) | 0;
++    w4 &= 0x3ffffff;
++    /* k = 5 */
++    lo = Math.imul(al5, bl0);
++    mid = Math.imul(al5, bh0);
++    mid = (mid + Math.imul(ah5, bl0)) | 0;
++    hi = Math.imul(ah5, bh0);
++    lo = (lo + Math.imul(al4, bl1)) | 0;
++    mid = (mid + Math.imul(al4, bh1)) | 0;
++    mid = (mid + Math.imul(ah4, bl1)) | 0;
++    hi = (hi + Math.imul(ah4, bh1)) | 0;
++    lo = (lo + Math.imul(al3, bl2)) | 0;
++    mid = (mid + Math.imul(al3, bh2)) | 0;
++    mid = (mid + Math.imul(ah3, bl2)) | 0;
++    hi = (hi + Math.imul(ah3, bh2)) | 0;
++    lo = (lo + Math.imul(al2, bl3)) | 0;
++    mid = (mid + Math.imul(al2, bh3)) | 0;
++    mid = (mid + Math.imul(ah2, bl3)) | 0;
++    hi = (hi + Math.imul(ah2, bh3)) | 0;
++    lo = (lo + Math.imul(al1, bl4)) | 0;
++    mid = (mid + Math.imul(al1, bh4)) | 0;
++    mid = (mid + Math.imul(ah1, bl4)) | 0;
++    hi = (hi + Math.imul(ah1, bh4)) | 0;
++    lo = (lo + Math.imul(al0, bl5)) | 0;
++    mid = (mid + Math.imul(al0, bh5)) | 0;
++    mid = (mid + Math.imul(ah0, bl5)) | 0;
++    hi = (hi + Math.imul(ah0, bh5)) | 0;
++    var w5 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
++    c = (((hi + (mid >>> 13)) | 0) + (w5 >>> 26)) | 0;
++    w5 &= 0x3ffffff;
++    /* k = 6 */
++    lo = Math.imul(al6, bl0);
++    mid = Math.imul(al6, bh0);
++    mid = (mid + Math.imul(ah6, bl0)) | 0;
++    hi = Math.imul(ah6, bh0);
++    lo = (lo + Math.imul(al5, bl1)) | 0;
++    mid = (mid + Math.imul(al5, bh1)) | 0;
++    mid = (mid + Math.imul(ah5, bl1)) | 0;
++    hi = (hi + Math.imul(ah5, bh1)) | 0;
++    lo = (lo + Math.imul(al4, bl2)) | 0;
++    mid = (mid + Math.imul(al4, bh2)) | 0;
++    mid = (mid + Math.imul(ah4, bl2)) | 0;
++    hi = (hi + Math.imul(ah4, bh2)) | 0;
++    lo = (lo + Math.imul(al3, bl3)) | 0;
++    mid = (mid + Math.imul(al3, bh3)) | 0;
++    mid = (mid + Math.imul(ah3, bl3)) | 0;
++    hi = (hi + Math.imul(ah3, bh3)) | 0;
++    lo = (lo + Math.imul(al2, bl4)) | 0;
++    mid = (mid + Math.imul(al2, bh4)) | 0;
++    mid = (mid + Math.imul(ah2, bl4)) | 0;
++    hi = (hi + Math.imul(ah2, bh4)) | 0;
++    lo = (lo + Math.imul(al1, bl5)) | 0;
++    mid = (mid + Math.imul(al1, bh5)) | 0;
++    mid = (mid + Math.imul(ah1, bl5)) | 0;
++    hi = (hi + Math.imul(ah1, bh5)) | 0;
++    lo = (lo + Math.imul(al0, bl6)) | 0;
++    mid = (mid + Math.imul(al0, bh6)) | 0;
++    mid = (mid + Math.imul(ah0, bl6)) | 0;
++    hi = (hi + Math.imul(ah0, bh6)) | 0;
++    var w6 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
++    c = (((hi + (mid >>> 13)) | 0) + (w6 >>> 26)) | 0;
++    w6 &= 0x3ffffff;
++    /* k = 7 */
++    lo = Math.imul(al7, bl0);
++    mid = Math.imul(al7, bh0);
++    mid = (mid + Math.imul(ah7, bl0)) | 0;
++    hi = Math.imul(ah7, bh0);
++    lo = (lo + Math.imul(al6, bl1)) | 0;
++    mid = (mid + Math.imul(al6, bh1)) | 0;
++    mid = (mid + Math.imul(ah6, bl1)) | 0;
++    hi = (hi + Math.imul(ah6, bh1)) | 0;
++    lo = (lo + Math.imul(al5, bl2)) | 0;
++    mid = (mid + Math.imul(al5, bh2)) | 0;
++    mid = (mid + Math.imul(ah5, bl2)) | 0;
++    hi = (hi + Math.imul(ah5, bh2)) | 0;
++    lo = (lo + Math.imul(al4, bl3)) | 0;
++    mid = (mid + Math.imul(al4, bh3)) | 0;
++    mid = (mid + Math.imul(ah4, bl3)) | 0;
++    hi = (hi + Math.imul(ah4, bh3)) | 0;
++    lo = (lo + Math.imul(al3, bl4)) | 0;
++    mid = (mid + Math.imul(al3, bh4)) | 0;
++    mid = (mid + Math.imul(ah3, bl4)) | 0;
++    hi = (hi + Math.imul(ah3, bh4)) | 0;
++    lo = (lo + Math.imul(al2, bl5)) | 0;
++    mid = (mid + Math.imul(al2, bh5)) | 0;
++    mid = (mid + Math.imul(ah2, bl5)) | 0;
++    hi = (hi + Math.imul(ah2, bh5)) | 0;
++    lo = (lo + Math.imul(al1, bl6)) | 0;
++    mid = (mid + Math.imul(al1, bh6)) | 0;
++    mid = (mid + Math.imul(ah1, bl6)) | 0;
++    hi = (hi + Math.imul(ah1, bh6)) | 0;
++    lo = (lo + Math.imul(al0, bl7)) | 0;
++    mid = (mid + Math.imul(al0, bh7)) | 0;
++    mid = (mid + Math.imul(ah0, bl7)) | 0;
++    hi = (hi + Math.imul(ah0, bh7)) | 0;
++    var w7 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
++    c = (((hi + (mid >>> 13)) | 0) + (w7 >>> 26)) | 0;
++    w7 &= 0x3ffffff;
++    /* k = 8 */
++    lo = Math.imul(al8, bl0);
++    mid = Math.imul(al8, bh0);
++    mid = (mid + Math.imul(ah8, bl0)) | 0;
++    hi = Math.imul(ah8, bh0);
++    lo = (lo + Math.imul(al7, bl1)) | 0;
++    mid = (mid + Math.imul(al7, bh1)) | 0;
++    mid = (mid + Math.imul(ah7, bl1)) | 0;
++    hi = (hi + Math.imul(ah7, bh1)) | 0;
++    lo = (lo + Math.imul(al6, bl2)) | 0;
++    mid = (mid + Math.imul(al6, bh2)) | 0;
++    mid = (mid + Math.imul(ah6, bl2)) | 0;
++    hi = (hi + Math.imul(ah6, bh2)) | 0;
++    lo = (lo + Math.imul(al5, bl3)) | 0;
++    mid = (mid + Math.imul(al5, bh3)) | 0;
++    mid = (mid + Math.imul(ah5, bl3)) | 0;
++    hi = (hi + Math.imul(ah5, bh3)) | 0;
++    lo = (lo + Math.imul(al4, bl4)) | 0;
++    mid = (mid + Math.imul(al4, bh4)) | 0;
++    mid = (mid + Math.imul(ah4, bl4)) | 0;
++    hi = (hi + Math.imul(ah4, bh4)) | 0;
++    lo = (lo + Math.imul(al3, bl5)) | 0;
++    mid = (mid + Math.imul(al3, bh5)) | 0;
++    mid = (mid + Math.imul(ah3, bl5)) | 0;
++    hi = (hi + Math.imul(ah3, bh5)) | 0;
++    lo = (lo + Math.imul(al2, bl6)) | 0;
++    mid = (mid + Math.imul(al2, bh6)) | 0;
++    mid = (mid + Math.imul(ah2, bl6)) | 0;
++    hi = (hi + Math.imul(ah2, bh6)) | 0;
++    lo = (lo + Math.imul(al1, bl7)) | 0;
++    mid = (mid + Math.imul(al1, bh7)) | 0;
++    mid = (mid + Math.imul(ah1, bl7)) | 0;
++    hi = (hi + Math.imul(ah1, bh7)) | 0;
++    lo = (lo + Math.imul(al0, bl8)) | 0;
++    mid = (mid + Math.imul(al0, bh8)) | 0;
++    mid = (mid + Math.imul(ah0, bl8)) | 0;
++    hi = (hi + Math.imul(ah0, bh8)) | 0;
++    var w8 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
++    c = (((hi + (mid >>> 13)) | 0) + (w8 >>> 26)) | 0;
++    w8 &= 0x3ffffff;
++    /* k = 9 */
++    lo = Math.imul(al9, bl0);
++    mid = Math.imul(al9, bh0);
++    mid = (mid + Math.imul(ah9, bl0)) | 0;
++    hi = Math.imul(ah9, bh0);
++    lo = (lo + Math.imul(al8, bl1)) | 0;
++    mid = (mid + Math.imul(al8, bh1)) | 0;
++    mid = (mid + Math.imul(ah8, bl1)) | 0;
++    hi = (hi + Math.imul(ah8, bh1)) | 0;
++    lo = (lo + Math.imul(al7, bl2)) | 0;
++    mid = (mid + Math.imul(al7, bh2)) | 0;
++    mid = (mid + Math.imul(ah7, bl2)) | 0;
++    hi = (hi + Math.imul(ah7, bh2)) | 0;
++    lo = (lo + Math.imul(al6, bl3)) | 0;
++    mid = (mid + Math.imul(al6, bh3)) | 0;
++    mid = (mid + Math.imul(ah6, bl3)) | 0;
++    hi = (hi + Math.imul(ah6, bh3)) | 0;
++    lo = (lo + Math.imul(al5, bl4)) | 0;
++    mid = (mid + Math.imul(al5, bh4)) | 0;
++    mid = (mid + Math.imul(ah5, bl4)) | 0;
++    hi = (hi + Math.imul(ah5, bh4)) | 0;
++    lo = (lo + Math.imul(al4, bl5)) | 0;
++    mid = (mid + Math.imul(al4, bh5)) | 0;
++    mid = (mid + Math.imul(ah4, bl5)) | 0;
++    hi = (hi + Math.imul(ah4, bh5)) | 0;
++    lo = (lo + Math.imul(al3, bl6)) | 0;
++    mid = (mid + Math.imul(al3, bh6)) | 0;
++    mid = (mid + Math.imul(ah3, bl6)) | 0;
++    hi = (hi + Math.imul(ah3, bh6)) | 0;
++    lo = (lo + Math.imul(al2, bl7)) | 0;
++    mid = (mid + Math.imul(al2, bh7)) | 0;
++    mid = (mid + Math.imul(ah2, bl7)) | 0;
++    hi = (hi + Math.imul(ah2, bh7)) | 0;
++    lo = (lo + Math.imul(al1, bl8)) | 0;
++    mid = (mid + Math.imul(al1, bh8)) | 0;
++    mid = (mid + Math.imul(ah1, bl8)) | 0;
++    hi = (hi + Math.imul(ah1, bh8)) | 0;
++    lo = (lo + Math.imul(al0, bl9)) | 0;
++    mid = (mid + Math.imul(al0, bh9)) | 0;
++    mid = (mid + Math.imul(ah0, bl9)) | 0;
++    hi = (hi + Math.imul(ah0, bh9)) | 0;
++    var w9 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
++    c = (((hi + (mid >>> 13)) | 0) + (w9 >>> 26)) | 0;
++    w9 &= 0x3ffffff;
++    /* k = 10 */
++    lo = Math.imul(al9, bl1);
++    mid = Math.imul(al9, bh1);
++    mid = (mid + Math.imul(ah9, bl1)) | 0;
++    hi = Math.imul(ah9, bh1);
++    lo = (lo + Math.imul(al8, bl2)) | 0;
++    mid = (mid + Math.imul(al8, bh2)) | 0;
++    mid = (mid + Math.imul(ah8, bl2)) | 0;
++    hi = (hi + Math.imul(ah8, bh2)) | 0;
++    lo = (lo + Math.imul(al7, bl3)) | 0;
++    mid = (mid + Math.imul(al7, bh3)) | 0;
++    mid = (mid + Math.imul(ah7, bl3)) | 0;
++    hi = (hi + Math.imul(ah7, bh3)) | 0;
++    lo = (lo + Math.imul(al6, bl4)) | 0;
++    mid = (mid + Math.imul(al6, bh4)) | 0;
++    mid = (mid + Math.imul(ah6, bl4)) | 0;
++    hi = (hi + Math.imul(ah6, bh4)) | 0;
++    lo = (lo + Math.imul(al5, bl5)) | 0;
++    mid = (mid + Math.imul(al5, bh5)) | 0;
++    mid = (mid + Math.imul(ah5, bl5)) | 0;
++    hi = (hi + Math.imul(ah5, bh5)) | 0;
++    lo = (lo + Math.imul(al4, bl6)) | 0;
++    mid = (mid + Math.imul(al4, bh6)) | 0;
++    mid = (mid + Math.imul(ah4, bl6)) | 0;
++    hi = (hi + Math.imul(ah4, bh6)) | 0;
++    lo = (lo + Math.imul(al3, bl7)) | 0;
++    mid = (mid + Math.imul(al3, bh7)) | 0;
++    mid = (mid + Math.imul(ah3, bl7)) | 0;
++    hi = (hi + Math.imul(ah3, bh7)) | 0;
++    lo = (lo + Math.imul(al2, bl8)) | 0;
++    mid = (mid + Math.imul(al2, bh8)) | 0;
++    mid = (mid + Math.imul(ah2, bl8)) | 0;
++    hi = (hi + Math.imul(ah2, bh8)) | 0;
++    lo = (lo + Math.imul(al1, bl9)) | 0;
++    mid = (mid + Math.imul(al1, bh9)) | 0;
++    mid = (mid + Math.imul(ah1, bl9)) | 0;
++    hi = (hi + Math.imul(ah1, bh9)) | 0;
++    var w10 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
++    c = (((hi + (mid >>> 13)) | 0) + (w10 >>> 26)) | 0;
++    w10 &= 0x3ffffff;
++    /* k = 11 */
++    lo = Math.imul(al9, bl2);
++    mid = Math.imul(al9, bh2);
++    mid = (mid + Math.imul(ah9, bl2)) | 0;
++    hi = Math.imul(ah9, bh2);
++    lo = (lo + Math.imul(al8, bl3)) | 0;
++    mid = (mid + Math.imul(al8, bh3)) | 0;
++    mid = (mid + Math.imul(ah8, bl3)) | 0;
++    hi = (hi + Math.imul(ah8, bh3)) | 0;
++    lo = (lo + Math.imul(al7, bl4)) | 0;
++    mid = (mid + Math.imul(al7, bh4)) | 0;
++    mid = (mid + Math.imul(ah7, bl4)) | 0;
++    hi = (hi + Math.imul(ah7, bh4)) | 0;
++    lo = (lo + Math.imul(al6, bl5)) | 0;
++    mid = (mid + Math.imul(al6, bh5)) | 0;
++    mid = (mid + Math.imul(ah6, bl5)) | 0;
++    hi = (hi + Math.imul(ah6, bh5)) | 0;
++    lo = (lo + Math.imul(al5, bl6)) | 0;
++    mid = (mid + Math.imul(al5, bh6)) | 0;
++    mid = (mid + Math.imul(ah5, bl6)) | 0;
++    hi = (hi + Math.imul(ah5, bh6)) | 0;
++    lo = (lo + Math.imul(al4, bl7)) | 0;
++    mid = (mid + Math.imul(al4, bh7)) | 0;
++    mid = (mid + Math.imul(ah4, bl7)) | 0;
++    hi = (hi + Math.imul(ah4, bh7)) | 0;
++    lo = (lo + Math.imul(al3, bl8)) | 0;
++    mid = (mid + Math.imul(al3, bh8)) | 0;
++    mid = (mid + Math.imul(ah3, bl8)) | 0;
++    hi = (hi + Math.imul(ah3, bh8)) | 0;
++    lo = (lo + Math.imul(al2, bl9)) | 0;
++    mid = (mid + Math.imul(al2, bh9)) | 0;
++    mid = (mid + Math.imul(ah2, bl9)) | 0;
++    hi = (hi + Math.imul(ah2, bh9)) | 0;
++    var w11 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
++    c = (((hi + (mid >>> 13)) | 0) + (w11 >>> 26)) | 0;
++    w11 &= 0x3ffffff;
++    /* k = 12 */
++    lo = Math.imul(al9, bl3);
++    mid = Math.imul(al9, bh3);
++    mid = (mid + Math.imul(ah9, bl3)) | 0;
++    hi = Math.imul(ah9, bh3);
++    lo = (lo + Math.imul(al8, bl4)) | 0;
++    mid = (mid + Math.imul(al8, bh4)) | 0;
++    mid = (mid + Math.imul(ah8, bl4)) | 0;
++    hi = (hi + Math.imul(ah8, bh4)) | 0;
++    lo = (lo + Math.imul(al7, bl5)) | 0;
++    mid = (mid + Math.imul(al7, bh5)) | 0;
++    mid = (mid + Math.imul(ah7, bl5)) | 0;
++    hi = (hi + Math.imul(ah7, bh5)) | 0;
++    lo = (lo + Math.imul(al6, bl6)) | 0;
++    mid = (mid + Math.imul(al6, bh6)) | 0;
++    mid = (mid + Math.imul(ah6, bl6)) | 0;
++    hi = (hi + Math.imul(ah6, bh6)) | 0;
++    lo = (lo + Math.imul(al5, bl7)) | 0;
++    mid = (mid + Math.imul(al5, bh7)) | 0;
++    mid = (mid + Math.imul(ah5, bl7)) | 0;
++    hi = (hi + Math.imul(ah5, bh7)) | 0;
++    lo = (lo + Math.imul(al4, bl8)) | 0;
++    mid = (mid + Math.imul(al4, bh8)) | 0;
++    mid = (mid + Math.imul(ah4, bl8)) | 0;
++    hi = (hi + Math.imul(ah4, bh8)) | 0;
++    lo = (lo + Math.imul(al3, bl9)) | 0;
++    mid = (mid + Math.imul(al3, bh9)) | 0;
++    mid = (mid + Math.imul(ah3, bl9)) | 0;
++    hi = (hi + Math.imul(ah3, bh9)) | 0;
++    var w12 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
++    c = (((hi + (mid >>> 13)) | 0) + (w12 >>> 26)) | 0;
++    w12 &= 0x3ffffff;
++    /* k = 13 */
++    lo = Math.imul(al9, bl4);
++    mid = Math.imul(al9, bh4);
++    mid = (mid + Math.imul(ah9, bl4)) | 0;
++    hi = Math.imul(ah9, bh4);
++    lo = (lo + Math.imul(al8, bl5)) | 0;
++    mid = (mid + Math.imul(al8, bh5)) | 0;
++    mid = (mid + Math.imul(ah8, bl5)) | 0;
++    hi = (hi + Math.imul(ah8, bh5)) | 0;
++    lo = (lo + Math.imul(al7, bl6)) | 0;
++    mid = (mid + Math.imul(al7, bh6)) | 0;
++    mid = (mid + Math.imul(ah7, bl6)) | 0;
++    hi = (hi + Math.imul(ah7, bh6)) | 0;
++    lo = (lo + Math.imul(al6, bl7)) | 0;
++    mid = (mid + Math.imul(al6, bh7)) | 0;
++    mid = (mid + Math.imul(ah6, bl7)) | 0;
++    hi = (hi + Math.imul(ah6, bh7)) | 0;
++    lo = (lo + Math.imul(al5, bl8)) | 0;
++    mid = (mid + Math.imul(al5, bh8)) | 0;
++    mid = (mid + Math.imul(ah5, bl8)) | 0;
++    hi = (hi + Math.imul(ah5, bh8)) | 0;
++    lo = (lo + Math.imul(al4, bl9)) | 0;
++    mid = (mid + Math.imul(al4, bh9)) | 0;
++    mid = (mid + Math.imul(ah4, bl9)) | 0;
++    hi = (hi + Math.imul(ah4, bh9)) | 0;
++    var w13 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
++    c = (((hi + (mid >>> 13)) | 0) + (w13 >>> 26)) | 0;
++    w13 &= 0x3ffffff;
++    /* k = 14 */
++    lo = Math.imul(al9, bl5);
++    mid = Math.imul(al9, bh5);
++    mid = (mid + Math.imul(ah9, bl5)) | 0;
++    hi = Math.imul(ah9, bh5);
++    lo = (lo + Math.imul(al8, bl6)) | 0;
++    mid = (mid + Math.imul(al8, bh6)) | 0;
++    mid = (mid + Math.imul(ah8, bl6)) | 0;
++    hi = (hi + Math.imul(ah8, bh6)) | 0;
++    lo = (lo + Math.imul(al7, bl7)) | 0;
++    mid = (mid + Math.imul(al7, bh7)) | 0;
++    mid = (mid + Math.imul(ah7, bl7)) | 0;
++    hi = (hi + Math.imul(ah7, bh7)) | 0;
++    lo = (lo + Math.imul(al6, bl8)) | 0;
++    mid = (mid + Math.imul(al6, bh8)) | 0;
++    mid = (mid + Math.imul(ah6, bl8)) | 0;
++    hi = (hi + Math.imul(ah6, bh8)) | 0;
++    lo = (lo + Math.imul(al5, bl9)) | 0;
++    mid = (mid + Math.imul(al5, bh9)) | 0;
++    mid = (mid + Math.imul(ah5, bl9)) | 0;
++    hi = (hi + Math.imul(ah5, bh9)) | 0;
++    var w14 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
++    c = (((hi + (mid >>> 13)) | 0) + (w14 >>> 26)) | 0;
++    w14 &= 0x3ffffff;
++    /* k = 15 */
++    lo = Math.imul(al9, bl6);
++    mid = Math.imul(al9, bh6);
++    mid = (mid + Math.imul(ah9, bl6)) | 0;
++    hi = Math.imul(ah9, bh6);
++    lo = (lo + Math.imul(al8, bl7)) | 0;
++    mid = (mid + Math.imul(al8, bh7)) | 0;
++    mid = (mid + Math.imul(ah8, bl7)) | 0;
++    hi = (hi + Math.imul(ah8, bh7)) | 0;
++    lo = (lo + Math.imul(al7, bl8)) | 0;
++    mid = (mid + Math.imul(al7, bh8)) | 0;
++    mid = (mid + Math.imul(ah7, bl8)) | 0;
++    hi = (hi + Math.imul(ah7, bh8)) | 0;
++    lo = (lo + Math.imul(al6, bl9)) | 0;
++    mid = (mid + Math.imul(al6, bh9)) | 0;
++    mid = (mid + Math.imul(ah6, bl9)) | 0;
++    hi = (hi + Math.imul(ah6, bh9)) | 0;
++    var w15 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
++    c = (((hi + (mid >>> 13)) | 0) + (w15 >>> 26)) | 0;
++    w15 &= 0x3ffffff;
++    /* k = 16 */
++    lo = Math.imul(al9, bl7);
++    mid = Math.imul(al9, bh7);
++    mid = (mid + Math.imul(ah9, bl7)) | 0;
++    hi = Math.imul(ah9, bh7);
++    lo = (lo + Math.imul(al8, bl8)) | 0;
++    mid = (mid + Math.imul(al8, bh8)) | 0;
++    mid = (mid + Math.imul(ah8, bl8)) | 0;
++    hi = (hi + Math.imul(ah8, bh8)) | 0;
++    lo = (lo + Math.imul(al7, bl9)) | 0;
++    mid = (mid + Math.imul(al7, bh9)) | 0;
++    mid = (mid + Math.imul(ah7, bl9)) | 0;
++    hi = (hi + Math.imul(ah7, bh9)) | 0;
++    var w16 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
++    c = (((hi + (mid >>> 13)) | 0) + (w16 >>> 26)) | 0;
++    w16 &= 0x3ffffff;
++    /* k = 17 */
++    lo = Math.imul(al9, bl8);
++    mid = Math.imul(al9, bh8);
++    mid = (mid + Math.imul(ah9, bl8)) | 0;
++    hi = Math.imul(ah9, bh8);
++    lo = (lo + Math.imul(al8, bl9)) | 0;
++    mid = (mid + Math.imul(al8, bh9)) | 0;
++    mid = (mid + Math.imul(ah8, bl9)) | 0;
++    hi = (hi + Math.imul(ah8, bh9)) | 0;
++    var w17 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
++    c = (((hi + (mid >>> 13)) | 0) + (w17 >>> 26)) | 0;
++    w17 &= 0x3ffffff;
++    /* k = 18 */
++    lo = Math.imul(al9, bl9);
++    mid = Math.imul(al9, bh9);
++    mid = (mid + Math.imul(ah9, bl9)) | 0;
++    hi = Math.imul(ah9, bh9);
++    var w18 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
++    c = (((hi + (mid >>> 13)) | 0) + (w18 >>> 26)) | 0;
++    w18 &= 0x3ffffff;
++    o[0] = w0;
++    o[1] = w1;
++    o[2] = w2;
++    o[3] = w3;
++    o[4] = w4;
++    o[5] = w5;
++    o[6] = w6;
++    o[7] = w7;
++    o[8] = w8;
++    o[9] = w9;
++    o[10] = w10;
++    o[11] = w11;
++    o[12] = w12;
++    o[13] = w13;
++    o[14] = w14;
++    o[15] = w15;
++    o[16] = w16;
++    o[17] = w17;
++    o[18] = w18;
++    if (c !== 0) {
++      o[19] = c;
++      out.length++;
++    }
++    return out;
++  };
++
++  // Polyfill comb
++  if (!Math.imul) {
++    comb10MulTo = smallMulTo;
++  }
++
++  function bigMulTo (self, num, out) {
++    out.negative = num.negative ^ self.negative;
++    out.length = self.length + num.length;
++
++    var carry = 0;
++    var hncarry = 0;
++    for (var k = 0; k < out.length - 1; k++) {
++      // Sum all words with the same `i + j = k` and accumulate `ncarry`,
++      // note that ncarry could be >= 0x3ffffff
++      var ncarry = hncarry;
++      hncarry = 0;
++      var rword = carry & 0x3ffffff;
++      var maxJ = Math.min(k, num.length - 1);
++      for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
++        var i = k - j;
++        var a = self.words[i] | 0;
++        var b = num.words[j] | 0;
++        var r = a * b;
++
++        var lo = r & 0x3ffffff;
++        ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0;
++        lo = (lo + rword) | 0;
++        rword = lo & 0x3ffffff;
++        ncarry = (ncarry + (lo >>> 26)) | 0;
++
++        hncarry += ncarry >>> 26;
++        ncarry &= 0x3ffffff;
++      }
++      out.words[k] = rword;
++      carry = ncarry;
++      ncarry = hncarry;
++    }
++    if (carry !== 0) {
++      out.words[k] = carry;
++    } else {
++      out.length--;
++    }
++
++    return out.strip();
++  }
++
++  function jumboMulTo (self, num, out) {
++    var fftm = new FFTM();
++    return fftm.mulp(self, num, out);
++  }
++
++  BN.prototype.mulTo = function mulTo (num, out) {
++    var res;
++    var len = this.length + num.length;
++    if (this.length === 10 && num.length === 10) {
++      res = comb10MulTo(this, num, out);
++    } else if (len < 63) {
++      res = smallMulTo(this, num, out);
++    } else if (len < 1024) {
++      res = bigMulTo(this, num, out);
++    } else {
++      res = jumboMulTo(this, num, out);
++    }
++
++    return res;
++  };
++
++  // Cooley-Tukey algorithm for FFT
++  // slightly revisited to rely on looping instead of recursion
++
++  function FFTM (x, y) {
++    this.x = x;
++    this.y = y;
++  }
++
++  FFTM.prototype.makeRBT = function makeRBT (N) {
++    var t = new Array(N);
++    var l = BN.prototype._countBits(N) - 1;
++    for (var i = 0; i < N; i++) {
++      t[i] = this.revBin(i, l, N);
++    }
++
++    return t;
++  };
++
++  // Returns binary-reversed representation of `x`
++  FFTM.prototype.revBin = function revBin (x, l, N) {
++    if (x === 0 || x === N - 1) return x;
++
++    var rb = 0;
++    for (var i = 0; i < l; i++) {
++      rb |= (x & 1) << (l - i - 1);
++      x >>= 1;
++    }
++
++    return rb;
++  };
++
++  // Performs "tweedling" phase, therefore 'emulating'
++  // behaviour of the recursive algorithm
++  FFTM.prototype.permute = function permute (rbt, rws, iws, rtws, itws, N) {
++    for (var i = 0; i < N; i++) {
++      rtws[i] = rws[rbt[i]];
++      itws[i] = iws[rbt[i]];
++    }
++  };
++
++  FFTM.prototype.transform = function transform (rws, iws, rtws, itws, N, rbt) {
++    this.permute(rbt, rws, iws, rtws, itws, N);
++
++    for (var s = 1; s < N; s <<= 1) {
++      var l = s << 1;
++
++      var rtwdf = Math.cos(2 * Math.PI / l);
++      var itwdf = Math.sin(2 * Math.PI / l);
++
++      for (var p = 0; p < N; p += l) {
++        var rtwdf_ = rtwdf;
++        var itwdf_ = itwdf;
++
++        for (var j = 0; j < s; j++) {
++          var re = rtws[p + j];
++          var ie = itws[p + j];
++
++          var ro = rtws[p + j + s];
++          var io = itws[p + j + s];
++
++          var rx = rtwdf_ * ro - itwdf_ * io;
++
++          io = rtwdf_ * io + itwdf_ * ro;
++          ro = rx;
++
++          rtws[p + j] = re + ro;
++          itws[p + j] = ie + io;
++
++          rtws[p + j + s] = re - ro;
++          itws[p + j + s] = ie - io;
++
++          /* jshint maxdepth : false */
++          if (j !== l) {
++            rx = rtwdf * rtwdf_ - itwdf * itwdf_;
++
++            itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_;
++            rtwdf_ = rx;
++          }
++        }
++      }
++    }
++  };
++
++  FFTM.prototype.guessLen13b = function guessLen13b (n, m) {
++    var N = Math.max(m, n) | 1;
++    var odd = N & 1;
++    var i = 0;
++    for (N = N / 2 | 0; N; N = N >>> 1) {
++      i++;
++    }
++
++    return 1 << i + 1 + odd;
++  };
++
++  FFTM.prototype.conjugate = function conjugate (rws, iws, N) {
++    if (N <= 1) return;
++
++    for (var i = 0; i < N / 2; i++) {
++      var t = rws[i];
++
++      rws[i] = rws[N - i - 1];
++      rws[N - i - 1] = t;
++
++      t = iws[i];
++
++      iws[i] = -iws[N - i - 1];
++      iws[N - i - 1] = -t;
++    }
++  };
++
++  FFTM.prototype.normalize13b = function normalize13b (ws, N) {
++    var carry = 0;
++    for (var i = 0; i < N / 2; i++) {
++      var w = Math.round(ws[2 * i + 1] / N) * 0x2000 +
++        Math.round(ws[2 * i] / N) +
++        carry;
++
++      ws[i] = w & 0x3ffffff;
++
++      if (w < 0x4000000) {
++        carry = 0;
++      } else {
++        carry = w / 0x4000000 | 0;
++      }
++    }
++
++    return ws;
++  };
++
++  FFTM.prototype.convert13b = function convert13b (ws, len, rws, N) {
++    var carry = 0;
++    for (var i = 0; i < len; i++) {
++      carry = carry + (ws[i] | 0);
++
++      rws[2 * i] = carry & 0x1fff; carry = carry >>> 13;
++      rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13;
++    }
++
++    // Pad with zeroes
++    for (i = 2 * len; i < N; ++i) {
++      rws[i] = 0;
++    }
++
++    assert(carry === 0);
++    assert((carry & ~0x1fff) === 0);
++  };
++
++  FFTM.prototype.stub = function stub (N) {
++    var ph = new Array(N);
++    for (var i = 0; i < N; i++) {
++      ph[i] = 0;
++    }
++
++    return ph;
++  };
++
++  FFTM.prototype.mulp = function mulp (x, y, out) {
++    var N = 2 * this.guessLen13b(x.length, y.length);
++
++    var rbt = this.makeRBT(N);
++
++    var _ = this.stub(N);
++
++    var rws = new Array(N);
++    var rwst = new Array(N);
++    var iwst = new Array(N);
++
++    var nrws = new Array(N);
++    var nrwst = new Array(N);
++    var niwst = new Array(N);
++
++    var rmws = out.words;
++    rmws.length = N;
++
++    this.convert13b(x.words, x.length, rws, N);
++    this.convert13b(y.words, y.length, nrws, N);
++
++    this.transform(rws, _, rwst, iwst, N, rbt);
++    this.transform(nrws, _, nrwst, niwst, N, rbt);
++
++    for (var i = 0; i < N; i++) {
++      var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i];
++      iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i];
++      rwst[i] = rx;
++    }
++
++    this.conjugate(rwst, iwst, N);
++    this.transform(rwst, iwst, rmws, _, N, rbt);
++    this.conjugate(rmws, _, N);
++    this.normalize13b(rmws, N);
++
++    out.negative = x.negative ^ y.negative;
++    out.length = x.length + y.length;
++    return out.strip();
++  };
++
++  // Multiply `this` by `num`
++  BN.prototype.mul = function mul (num) {
++    var out = new BN(null);
++    out.words = new Array(this.length + num.length);
++    return this.mulTo(num, out);
++  };
++
++  // Multiply employing FFT
++  BN.prototype.mulf = function mulf (num) {
++    var out = new BN(null);
++    out.words = new Array(this.length + num.length);
++    return jumboMulTo(this, num, out);
++  };
++
++  // In-place Multiplication
++  BN.prototype.imul = function imul (num) {
++    return this.clone().mulTo(num, this);
++  };
++
++  BN.prototype.imuln = function imuln (num) {
++    assert(typeof num === 'number');
++    assert(num < 0x4000000);
++
++    // Carry
++    var carry = 0;
++    for (var i = 0; i < this.length; i++) {
++      var w = (this.words[i] | 0) * num;
++      var lo = (w & 0x3ffffff) + (carry & 0x3ffffff);
++      carry >>= 26;
++      carry += (w / 0x4000000) | 0;
++      // NOTE: lo is 27bit maximum
++      carry += lo >>> 26;
++      this.words[i] = lo & 0x3ffffff;
++    }
++
++    if (carry !== 0) {
++      this.words[i] = carry;
++      this.length++;
++    }
++
++    return this;
++  };
++
++  BN.prototype.muln = function muln (num) {
++    return this.clone().imuln(num);
++  };
++
++  // `this` * `this`
++  BN.prototype.sqr = function sqr () {
++    return this.mul(this);
++  };
++
++  // `this` * `this` in-place
++  BN.prototype.isqr = function isqr () {
++    return this.imul(this.clone());
++  };
++
++  // Math.pow(`this`, `num`)
++  BN.prototype.pow = function pow (num) {
++    var w = toBitArray(num);
++    if (w.length === 0) return new BN(1);
++
++    // Skip leading zeroes
++    var res = this;
++    for (var i = 0; i < w.length; i++, res = res.sqr()) {
++      if (w[i] !== 0) break;
++    }
++
++    if (++i < w.length) {
++      for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) {
++        if (w[i] === 0) continue;
++
++        res = res.mul(q);
++      }
++    }
++
++    return res;
++  };
++
++  // Shift-left in-place
++  BN.prototype.iushln = function iushln (bits) {
++    assert(typeof bits === 'number' && bits >= 0);
++    var r = bits % 26;
++    var s = (bits - r) / 26;
++    var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r);
++    var i;
++
++    if (r !== 0) {
++      var carry = 0;
++
++      for (i = 0; i < this.length; i++) {
++        var newCarry = this.words[i] & carryMask;
++        var c = ((this.words[i] | 0) - newCarry) << r;
++        this.words[i] = c | carry;
++        carry = newCarry >>> (26 - r);
++      }
++
++      if (carry) {
++        this.words[i] = carry;
++        this.length++;
++      }
++    }
++
++    if (s !== 0) {
++      for (i = this.length - 1; i >= 0; i--) {
++        this.words[i + s] = this.words[i];
++      }
++
++      for (i = 0; i < s; i++) {
++        this.words[i] = 0;
++      }
++
++      this.length += s;
++    }
++
++    return this.strip();
++  };
++
++  BN.prototype.ishln = function ishln (bits) {
++    // TODO(indutny): implement me
++    assert(this.negative === 0);
++    return this.iushln(bits);
++  };
++
++  // Shift-right in-place
++  // NOTE: `hint` is a lowest bit before trailing zeroes
++  // NOTE: if `extended` is present - it will be filled with destroyed bits
++  BN.prototype.iushrn = function iushrn (bits, hint, extended) {
++    assert(typeof bits === 'number' && bits >= 0);
++    var h;
++    if (hint) {
++      h = (hint - (hint % 26)) / 26;
++    } else {
++      h = 0;
++    }
++
++    var r = bits % 26;
++    var s = Math.min((bits - r) / 26, this.length);
++    var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
++    var maskedWords = extended;
++
++    h -= s;
++    h = Math.max(0, h);
++
++    // Extended mode, copy masked part
++    if (maskedWords) {
++      for (var i = 0; i < s; i++) {
++        maskedWords.words[i] = this.words[i];
++      }
++      maskedWords.length = s;
++    }
++
++    if (s === 0) {
++      // No-op, we should not move anything at all
++    } else if (this.length > s) {
++      this.length -= s;
++      for (i = 0; i < this.length; i++) {
++        this.words[i] = this.words[i + s];
++      }
++    } else {
++      this.words[0] = 0;
++      this.length = 1;
++    }
++
++    var carry = 0;
++    for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) {
++      var word = this.words[i] | 0;
++      this.words[i] = (carry << (26 - r)) | (word >>> r);
++      carry = word & mask;
++    }
++
++    // Push carried bits as a mask
++    if (maskedWords && carry !== 0) {
++      maskedWords.words[maskedWords.length++] = carry;
++    }
++
++    if (this.length === 0) {
++      this.words[0] = 0;
++      this.length = 1;
++    }
++
++    return this.strip();
++  };
++
++  BN.prototype.ishrn = function ishrn (bits, hint, extended) {
++    // TODO(indutny): implement me
++    assert(this.negative === 0);
++    return this.iushrn(bits, hint, extended);
++  };
++
++  // Shift-left
++  BN.prototype.shln = function shln (bits) {
++    return this.clone().ishln(bits);
++  };
++
++  BN.prototype.ushln = function ushln (bits) {
++    return this.clone().iushln(bits);
++  };
++
++  // Shift-right
++  BN.prototype.shrn = function shrn (bits) {
++    return this.clone().ishrn(bits);
++  };
++
++  BN.prototype.ushrn = function ushrn (bits) {
++    return this.clone().iushrn(bits);
++  };
++
++  // Test if n bit is set
++  BN.prototype.testn = function testn (bit) {
++    assert(typeof bit === 'number' && bit >= 0);
++    var r = bit % 26;
++    var s = (bit - r) / 26;
++    var q = 1 << r;
++
++    // Fast case: bit is much higher than all existing words
++    if (this.length <= s) return false;
++
++    // Check bit and return
++    var w = this.words[s];
++
++    return !!(w & q);
++  };
++
++  // Return only lowers bits of number (in-place)
++  BN.prototype.imaskn = function imaskn (bits) {
++    assert(typeof bits === 'number' && bits >= 0);
++    var r = bits % 26;
++    var s = (bits - r) / 26;
++
++    assert(this.negative === 0, 'imaskn works only with positive numbers');
++
++    if (this.length <= s) {
++      return this;
++    }
++
++    if (r !== 0) {
++      s++;
++    }
++    this.length = Math.min(s, this.length);
++
++    if (r !== 0) {
++      var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
++      this.words[this.length - 1] &= mask;
++    }
++
++    return this.strip();
++  };
++
++  // Return only lowers bits of number
++  BN.prototype.maskn = function maskn (bits) {
++    return this.clone().imaskn(bits);
++  };
++
++  // Add plain number `num` to `this`
++  BN.prototype.iaddn = function iaddn (num) {
++    assert(typeof num === 'number');
++    assert(num < 0x4000000);
++    if (num < 0) return this.isubn(-num);
++
++    // Possible sign change
++    if (this.negative !== 0) {
++      if (this.length === 1 && (this.words[0] | 0) < num) {
++        this.words[0] = num - (this.words[0] | 0);
++        this.negative = 0;
++        return this;
++      }
++
++      this.negative = 0;
++      this.isubn(num);
++      this.negative = 1;
++      return this;
++    }
++
++    // Add without checks
++    return this._iaddn(num);
++  };
++
++  BN.prototype._iaddn = function _iaddn (num) {
++    this.words[0] += num;
++
++    // Carry
++    for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) {
++      this.words[i] -= 0x4000000;
++      if (i === this.length - 1) {
++        this.words[i + 1] = 1;
++      } else {
++        this.words[i + 1]++;
++      }
++    }
++    this.length = Math.max(this.length, i + 1);
++
++    return this;
++  };
++
++  // Subtract plain number `num` from `this`
++  BN.prototype.isubn = function isubn (num) {
++    assert(typeof num === 'number');
++    assert(num < 0x4000000);
++    if (num < 0) return this.iaddn(-num);
++
++    if (this.negative !== 0) {
++      this.negative = 0;
++      this.iaddn(num);
++      this.negative = 1;
++      return this;
++    }
++
++    this.words[0] -= num;
++
++    if (this.length === 1 && this.words[0] < 0) {
++      this.words[0] = -this.words[0];
++      this.negative = 1;
++    } else {
++      // Carry
++      for (var i = 0; i < this.length && this.words[i] < 0; i++) {
++        this.words[i] += 0x4000000;
++        this.words[i + 1] -= 1;
++      }
++    }
++
++    return this.strip();
++  };
++
++  BN.prototype.addn = function addn (num) {
++    return this.clone().iaddn(num);
++  };
++
++  BN.prototype.subn = function subn (num) {
++    return this.clone().isubn(num);
++  };
++
++  BN.prototype.iabs = function iabs () {
++    this.negative = 0;
++
++    return this;
++  };
++
++  BN.prototype.abs = function abs () {
++    return this.clone().iabs();
++  };
++
++  BN.prototype._ishlnsubmul = function _ishlnsubmul (num, mul, shift) {
++    var len = num.length + shift;
++    var i;
++
++    this._expand(len);
++
++    var w;
++    var carry = 0;
++    for (i = 0; i < num.length; i++) {
++      w = (this.words[i + shift] | 0) + carry;
++      var right = (num.words[i] | 0) * mul;
++      w -= right & 0x3ffffff;
++      carry = (w >> 26) - ((right / 0x4000000) | 0);
++      this.words[i + shift] = w & 0x3ffffff;
++    }
++    for (; i < this.length - shift; i++) {
++      w = (this.words[i + shift] | 0) + carry;
++      carry = w >> 26;
++      this.words[i + shift] = w & 0x3ffffff;
++    }
++
++    if (carry === 0) return this.strip();
++
++    // Subtraction overflow
++    assert(carry === -1);
++    carry = 0;
++    for (i = 0; i < this.length; i++) {
++      w = -(this.words[i] | 0) + carry;
++      carry = w >> 26;
++      this.words[i] = w & 0x3ffffff;
++    }
++    this.negative = 1;
++
++    return this.strip();
++  };
++
++  BN.prototype._wordDiv = function _wordDiv (num, mode) {
++    var shift = this.length - num.length;
++
++    var a = this.clone();
++    var b = num;
++
++    // Normalize
++    var bhi = b.words[b.length - 1] | 0;
++    var bhiBits = this._countBits(bhi);
++    shift = 26 - bhiBits;
++    if (shift !== 0) {
++      b = b.ushln(shift);
++      a.iushln(shift);
++      bhi = b.words[b.length - 1] | 0;
++    }
++
++    // Initialize quotient
++    var m = a.length - b.length;
++    var q;
++
++    if (mode !== 'mod') {
++      q = new BN(null);
++      q.length = m + 1;
++      q.words = new Array(q.length);
++      for (var i = 0; i < q.length; i++) {
++        q.words[i] = 0;
++      }
++    }
++
++    var diff = a.clone()._ishlnsubmul(b, 1, m);
++    if (diff.negative === 0) {
++      a = diff;
++      if (q) {
++        q.words[m] = 1;
++      }
++    }
++
++    for (var j = m - 1; j >= 0; j--) {
++      var qj = (a.words[b.length + j] | 0) * 0x4000000 +
++        (a.words[b.length + j - 1] | 0);
++
++      // NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max
++      // (0x7ffffff)
++      qj = Math.min((qj / bhi) | 0, 0x3ffffff);
++
++      a._ishlnsubmul(b, qj, j);
++      while (a.negative !== 0) {
++        qj--;
++        a.negative = 0;
++        a._ishlnsubmul(b, 1, j);
++        if (!a.isZero()) {
++          a.negative ^= 1;
++        }
++      }
++      if (q) {
++        q.words[j] = qj;
++      }
++    }
++    if (q) {
++      q.strip();
++    }
++    a.strip();
++
++    // Denormalize
++    if (mode !== 'div' && shift !== 0) {
++      a.iushrn(shift);
++    }
++
++    return {
++      div: q || null,
++      mod: a
++    };
++  };
++
++  // NOTE: 1) `mode` can be set to `mod` to request mod only,
++  //       to `div` to request div only, or be absent to
++  //       request both div & mod
++  //       2) `positive` is true if unsigned mod is requested
++  BN.prototype.divmod = function divmod (num, mode, positive) {
++    assert(!num.isZero());
++
++    if (this.isZero()) {
++      return {
++        div: new BN(0),
++        mod: new BN(0)
++      };
++    }
++
++    var div, mod, res;
++    if (this.negative !== 0 && num.negative === 0) {
++      res = this.neg().divmod(num, mode);
++
++      if (mode !== 'mod') {
++        div = res.div.neg();
++      }
++
++      if (mode !== 'div') {
++        mod = res.mod.neg();
++        if (positive && mod.negative !== 0) {
++          mod.iadd(num);
++        }
++      }
++
++      return {
++        div: div,
++        mod: mod
++      };
++    }
++
++    if (this.negative === 0 && num.negative !== 0) {
++      res = this.divmod(num.neg(), mode);
++
++      if (mode !== 'mod') {
++        div = res.div.neg();
++      }
++
++      return {
++        div: div,
++        mod: res.mod
++      };
++    }
++
++    if ((this.negative & num.negative) !== 0) {
++      res = this.neg().divmod(num.neg(), mode);
++
++      if (mode !== 'div') {
++        mod = res.mod.neg();
++        if (positive && mod.negative !== 0) {
++          mod.isub(num);
++        }
++      }
++
++      return {
++        div: res.div,
++        mod: mod
++      };
++    }
++
++    // Both numbers are positive at this point
++
++    // Strip both numbers to approximate shift value
++    if (num.length > this.length || this.cmp(num) < 0) {
++      return {
++        div: new BN(0),
++        mod: this
++      };
++    }
++
++    // Very short reduction
++    if (num.length === 1) {
++      if (mode === 'div') {
++        return {
++          div: this.divn(num.words[0]),
++          mod: null
++        };
++      }
++
++      if (mode === 'mod') {
++        return {
++          div: null,
++          mod: new BN(this.modn(num.words[0]))
++        };
++      }
++
++      return {
++        div: this.divn(num.words[0]),
++        mod: new BN(this.modn(num.words[0]))
++      };
++    }
++
++    return this._wordDiv(num, mode);
++  };
++
++  // Find `this` / `num`
++  BN.prototype.div = function div (num) {
++    return this.divmod(num, 'div', false).div;
++  };
++
++  // Find `this` % `num`
++  BN.prototype.mod = function mod (num) {
++    return this.divmod(num, 'mod', false).mod;
++  };
++
++  BN.prototype.umod = function umod (num) {
++    return this.divmod(num, 'mod', true).mod;
++  };
++
++  // Find Round(`this` / `num`)
++  BN.prototype.divRound = function divRound (num) {
++    var dm = this.divmod(num);
++
++    // Fast case - exact division
++    if (dm.mod.isZero()) return dm.div;
++
++    var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod;
++
++    var half = num.ushrn(1);
++    var r2 = num.andln(1);
++    var cmp = mod.cmp(half);
++
++    // Round down
++    if (cmp < 0 || r2 === 1 && cmp === 0) return dm.div;
++
++    // Round up
++    return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1);
++  };
++
++  BN.prototype.modn = function modn (num) {
++    assert(num <= 0x3ffffff);
++    var p = (1 << 26) % num;
++
++    var acc = 0;
++    for (var i = this.length - 1; i >= 0; i--) {
++      acc = (p * acc + (this.words[i] | 0)) % num;
++    }
++
++    return acc;
++  };
++
++  // In-place division by number
++  BN.prototype.idivn = function idivn (num) {
++    assert(num <= 0x3ffffff);
++
++    var carry = 0;
++    for (var i = this.length - 1; i >= 0; i--) {
++      var w = (this.words[i] | 0) + carry * 0x4000000;
++      this.words[i] = (w / num) | 0;
++      carry = w % num;
++    }
++
++    return this.strip();
++  };
++
++  BN.prototype.divn = function divn (num) {
++    return this.clone().idivn(num);
++  };
++
++  BN.prototype.egcd = function egcd (p) {
++    assert(p.negative === 0);
++    assert(!p.isZero());
++
++    var x = this;
++    var y = p.clone();
++
++    if (x.negative !== 0) {
++      x = x.umod(p);
++    } else {
++      x = x.clone();
++    }
++
++    // A * x + B * y = x
++    var A = new BN(1);
++    var B = new BN(0);
++
++    // C * x + D * y = y
++    var C = new BN(0);
++    var D = new BN(1);
++
++    var g = 0;
++
++    while (x.isEven() && y.isEven()) {
++      x.iushrn(1);
++      y.iushrn(1);
++      ++g;
++    }
++
++    var yp = y.clone();
++    var xp = x.clone();
++
++    while (!x.isZero()) {
++      for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
++      if (i > 0) {
++        x.iushrn(i);
++        while (i-- > 0) {
++          if (A.isOdd() || B.isOdd()) {
++            A.iadd(yp);
++            B.isub(xp);
++          }
++
++          A.iushrn(1);
++          B.iushrn(1);
++        }
++      }
++
++      for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
++      if (j > 0) {
++        y.iushrn(j);
++        while (j-- > 0) {
++          if (C.isOdd() || D.isOdd()) {
++            C.iadd(yp);
++            D.isub(xp);
++          }
++
++          C.iushrn(1);
++          D.iushrn(1);
++        }
++      }
++
++      if (x.cmp(y) >= 0) {
++        x.isub(y);
++        A.isub(C);
++        B.isub(D);
++      } else {
++        y.isub(x);
++        C.isub(A);
++        D.isub(B);
++      }
++    }
++
++    return {
++      a: C,
++      b: D,
++      gcd: y.iushln(g)
++    };
++  };
++
++  // This is reduced incarnation of the binary EEA
++  // above, designated to invert members of the
++  // _prime_ fields F(p) at a maximal speed
++  BN.prototype._invmp = function _invmp (p) {
++    assert(p.negative === 0);
++    assert(!p.isZero());
++
++    var a = this;
++    var b = p.clone();
++
++    if (a.negative !== 0) {
++      a = a.umod(p);
++    } else {
++      a = a.clone();
++    }
++
++    var x1 = new BN(1);
++    var x2 = new BN(0);
++
++    var delta = b.clone();
++
++    while (a.cmpn(1) > 0 && b.cmpn(1) > 0) {
++      for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
++      if (i > 0) {
++        a.iushrn(i);
++        while (i-- > 0) {
++          if (x1.isOdd()) {
++            x1.iadd(delta);
++          }
++
++          x1.iushrn(1);
++        }
++      }
++
++      for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
++      if (j > 0) {
++        b.iushrn(j);
++        while (j-- > 0) {
++          if (x2.isOdd()) {
++            x2.iadd(delta);
++          }
++
++          x2.iushrn(1);
++        }
++      }
++
++      if (a.cmp(b) >= 0) {
++        a.isub(b);
++        x1.isub(x2);
++      } else {
++        b.isub(a);
++        x2.isub(x1);
++      }
++    }
++
++    var res;
++    if (a.cmpn(1) === 0) {
++      res = x1;
++    } else {
++      res = x2;
++    }
++
++    if (res.cmpn(0) < 0) {
++      res.iadd(p);
++    }
++
++    return res;
++  };
++
++  BN.prototype.gcd = function gcd (num) {
++    if (this.isZero()) return num.abs();
++    if (num.isZero()) return this.abs();
++
++    var a = this.clone();
++    var b = num.clone();
++    a.negative = 0;
++    b.negative = 0;
++
++    // Remove common factor of two
++    for (var shift = 0; a.isEven() && b.isEven(); shift++) {
++      a.iushrn(1);
++      b.iushrn(1);
++    }
++
++    do {
++      while (a.isEven()) {
++        a.iushrn(1);
++      }
++      while (b.isEven()) {
++        b.iushrn(1);
++      }
++
++      var r = a.cmp(b);
++      if (r < 0) {
++        // Swap `a` and `b` to make `a` always bigger than `b`
++        var t = a;
++        a = b;
++        b = t;
++      } else if (r === 0 || b.cmpn(1) === 0) {
++        break;
++      }
++
++      a.isub(b);
++    } while (true);
++
++    return b.iushln(shift);
++  };
++
++  // Invert number in the field F(num)
++  BN.prototype.invm = function invm (num) {
++    return this.egcd(num).a.umod(num);
++  };
++
++  BN.prototype.isEven = function isEven () {
++    return (this.words[0] & 1) === 0;
++  };
++
++  BN.prototype.isOdd = function isOdd () {
++    return (this.words[0] & 1) === 1;
++  };
++
++  // And first word and num
++  BN.prototype.andln = function andln (num) {
++    return this.words[0] & num;
++  };
++
++  // Increment at the bit position in-line
++  BN.prototype.bincn = function bincn (bit) {
++    assert(typeof bit === 'number');
++    var r = bit % 26;
++    var s = (bit - r) / 26;
++    var q = 1 << r;
++
++    // Fast case: bit is much higher than all existing words
++    if (this.length <= s) {
++      this._expand(s + 1);
++      this.words[s] |= q;
++      return this;
++    }
++
++    // Add bit and propagate, if needed
++    var carry = q;
++    for (var i = s; carry !== 0 && i < this.length; i++) {
++      var w = this.words[i] | 0;
++      w += carry;
++      carry = w >>> 26;
++      w &= 0x3ffffff;
++      this.words[i] = w;
++    }
++    if (carry !== 0) {
++      this.words[i] = carry;
++      this.length++;
++    }
++    return this;
++  };
++
++  BN.prototype.isZero = function isZero () {
++    return this.length === 1 && this.words[0] === 0;
++  };
++
++  BN.prototype.cmpn = function cmpn (num) {
++    var negative = num < 0;
++
++    if (this.negative !== 0 && !negative) return -1;
++    if (this.negative === 0 && negative) return 1;
++
++    this.strip();
++
++    var res;
++    if (this.length > 1) {
++      res = 1;
++    } else {
++      if (negative) {
++        num = -num;
++      }
++
++      assert(num <= 0x3ffffff, 'Number is too big');
++
++      var w = this.words[0] | 0;
++      res = w === num ? 0 : w < num ? -1 : 1;
++    }
++    if (this.negative !== 0) return -res | 0;
++    return res;
++  };
++
++  // Compare two numbers and return:
++  // 1 - if `this` > `num`
++  // 0 - if `this` == `num`
++  // -1 - if `this` < `num`
++  BN.prototype.cmp = function cmp (num) {
++    if (this.negative !== 0 && num.negative === 0) return -1;
++    if (this.negative === 0 && num.negative !== 0) return 1;
++
++    var res = this.ucmp(num);
++    if (this.negative !== 0) return -res | 0;
++    return res;
++  };
++
++  // Unsigned comparison
++  BN.prototype.ucmp = function ucmp (num) {
++    // At this point both numbers have the same sign
++    if (this.length > num.length) return 1;
++    if (this.length < num.length) return -1;
++
++    var res = 0;
++    for (var i = this.length - 1; i >= 0; i--) {
++      var a = this.words[i] | 0;
++      var b = num.words[i] | 0;
++
++      if (a === b) continue;
++      if (a < b) {
++        res = -1;
++      } else if (a > b) {
++        res = 1;
++      }
++      break;
++    }
++    return res;
++  };
++
++  BN.prototype.gtn = function gtn (num) {
++    return this.cmpn(num) === 1;
++  };
++
++  BN.prototype.gt = function gt (num) {
++    return this.cmp(num) === 1;
++  };
++
++  BN.prototype.gten = function gten (num) {
++    return this.cmpn(num) >= 0;
++  };
++
++  BN.prototype.gte = function gte (num) {
++    return this.cmp(num) >= 0;
++  };
++
++  BN.prototype.ltn = function ltn (num) {
++    return this.cmpn(num) === -1;
++  };
++
++  BN.prototype.lt = function lt (num) {
++    return this.cmp(num) === -1;
++  };
++
++  BN.prototype.lten = function lten (num) {
++    return this.cmpn(num) <= 0;
++  };
++
++  BN.prototype.lte = function lte (num) {
++    return this.cmp(num) <= 0;
++  };
++
++  BN.prototype.eqn = function eqn (num) {
++    return this.cmpn(num) === 0;
++  };
++
++  BN.prototype.eq = function eq (num) {
++    return this.cmp(num) === 0;
++  };
++
++  //
++  // A reduce context, could be using montgomery or something better, depending
++  // on the `m` itself.
++  //
++  BN.red = function red (num) {
++    return new Red(num);
++  };
++
++  BN.prototype.toRed = function toRed (ctx) {
++    assert(!this.red, 'Already a number in reduction context');
++    assert(this.negative === 0, 'red works only with positives');
++    return ctx.convertTo(this)._forceRed(ctx);
++  };
++
++  BN.prototype.fromRed = function fromRed () {
++    assert(this.red, 'fromRed works only with numbers in reduction context');
++    return this.red.convertFrom(this);
++  };
++
++  BN.prototype._forceRed = function _forceRed (ctx) {
++    this.red = ctx;
++    return this;
++  };
++
++  BN.prototype.forceRed = function forceRed (ctx) {
++    assert(!this.red, 'Already a number in reduction context');
++    return this._forceRed(ctx);
++  };
++
++  BN.prototype.redAdd = function redAdd (num) {
++    assert(this.red, 'redAdd works only with red numbers');
++    return this.red.add(this, num);
++  };
++
++  BN.prototype.redIAdd = function redIAdd (num) {
++    assert(this.red, 'redIAdd works only with red numbers');
++    return this.red.iadd(this, num);
++  };
++
++  BN.prototype.redSub = function redSub (num) {
++    assert(this.red, 'redSub works only with red numbers');
++    return this.red.sub(this, num);
++  };
++
++  BN.prototype.redISub = function redISub (num) {
++    assert(this.red, 'redISub works only with red numbers');
++    return this.red.isub(this, num);
++  };
++
++  BN.prototype.redShl = function redShl (num) {
++    assert(this.red, 'redShl works only with red numbers');
++    return this.red.shl(this, num);
++  };
++
++  BN.prototype.redMul = function redMul (num) {
++    assert(this.red, 'redMul works only with red numbers');
++    this.red._verify2(this, num);
++    return this.red.mul(this, num);
++  };
++
++  BN.prototype.redIMul = function redIMul (num) {
++    assert(this.red, 'redMul works only with red numbers');
++    this.red._verify2(this, num);
++    return this.red.imul(this, num);
++  };
++
++  BN.prototype.redSqr = function redSqr () {
++    assert(this.red, 'redSqr works only with red numbers');
++    this.red._verify1(this);
++    return this.red.sqr(this);
++  };
++
++  BN.prototype.redISqr = function redISqr () {
++    assert(this.red, 'redISqr works only with red numbers');
++    this.red._verify1(this);
++    return this.red.isqr(this);
++  };
++
++  // Square root over p
++  BN.prototype.redSqrt = function redSqrt () {
++    assert(this.red, 'redSqrt works only with red numbers');
++    this.red._verify1(this);
++    return this.red.sqrt(this);
++  };
++
++  BN.prototype.redInvm = function redInvm () {
++    assert(this.red, 'redInvm works only with red numbers');
++    this.red._verify1(this);
++    return this.red.invm(this);
++  };
++
++  // Return negative clone of `this` % `red modulo`
++  BN.prototype.redNeg = function redNeg () {
++    assert(this.red, 'redNeg works only with red numbers');
++    this.red._verify1(this);
++    return this.red.neg(this);
++  };
++
++  BN.prototype.redPow = function redPow (num) {
++    assert(this.red && !num.red, 'redPow(normalNum)');
++    this.red._verify1(this);
++    return this.red.pow(this, num);
++  };
++
++  // Prime numbers with efficient reduction
++  var primes = {
++    k256: null,
++    p224: null,
++    p192: null,
++    p25519: null
++  };
++
++  // Pseudo-Mersenne prime
++  function MPrime (name, p) {
++    // P = 2 ^ N - K
++    this.name = name;
++    this.p = new BN(p, 16);
++    this.n = this.p.bitLength();
++    this.k = new BN(1).iushln(this.n).isub(this.p);
++
++    this.tmp = this._tmp();
++  }
++
++  MPrime.prototype._tmp = function _tmp () {
++    var tmp = new BN(null);
++    tmp.words = new Array(Math.ceil(this.n / 13));
++    return tmp;
++  };
++
++  MPrime.prototype.ireduce = function ireduce (num) {
++    // Assumes that `num` is less than `P^2`
++    // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P)
++    var r = num;
++    var rlen;
++
++    do {
++      this.split(r, this.tmp);
++      r = this.imulK(r);
++      r = r.iadd(this.tmp);
++      rlen = r.bitLength();
++    } while (rlen > this.n);
++
++    var cmp = rlen < this.n ? -1 : r.ucmp(this.p);
++    if (cmp === 0) {
++      r.words[0] = 0;
++      r.length = 1;
++    } else if (cmp > 0) {
++      r.isub(this.p);
++    } else {
++      r.strip();
++    }
++
++    return r;
++  };
++
++  MPrime.prototype.split = function split (input, out) {
++    input.iushrn(this.n, 0, out);
++  };
++
++  MPrime.prototype.imulK = function imulK (num) {
++    return num.imul(this.k);
++  };
++
++  function K256 () {
++    MPrime.call(
++      this,
++      'k256',
++      'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f');
++  }
++  inherits(K256, MPrime);
++
++  K256.prototype.split = function split (input, output) {
++    // 256 = 9 * 26 + 22
++    var mask = 0x3fffff;
++
++    var outLen = Math.min(input.length, 9);
++    for (var i = 0; i < outLen; i++) {
++      output.words[i] = input.words[i];
++    }
++    output.length = outLen;
++
++    if (input.length <= 9) {
++      input.words[0] = 0;
++      input.length = 1;
++      return;
++    }
++
++    // Shift by 9 limbs
++    var prev = input.words[9];
++    output.words[output.length++] = prev & mask;
++
++    for (i = 10; i < input.length; i++) {
++      var next = input.words[i] | 0;
++      input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22);
++      prev = next;
++    }
++    prev >>>= 22;
++    input.words[i - 10] = prev;
++    if (prev === 0 && input.length > 10) {
++      input.length -= 10;
++    } else {
++      input.length -= 9;
++    }
++  };
++
++  K256.prototype.imulK = function imulK (num) {
++    // K = 0x1000003d1 = [ 0x40, 0x3d1 ]
++    num.words[num.length] = 0;
++    num.words[num.length + 1] = 0;
++    num.length += 2;
++
++    // bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390
++    var lo = 0;
++    for (var i = 0; i < num.length; i++) {
++      var w = num.words[i] | 0;
++      lo += w * 0x3d1;
++      num.words[i] = lo & 0x3ffffff;
++      lo = w * 0x40 + ((lo / 0x4000000) | 0);
++    }
++
++    // Fast length reduction
++    if (num.words[num.length - 1] === 0) {
++      num.length--;
++      if (num.words[num.length - 1] === 0) {
++        num.length--;
++      }
++    }
++    return num;
++  };
++
++  function P224 () {
++    MPrime.call(
++      this,
++      'p224',
++      'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001');
++  }
++  inherits(P224, MPrime);
++
++  function P192 () {
++    MPrime.call(
++      this,
++      'p192',
++      'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff');
++  }
++  inherits(P192, MPrime);
++
++  function P25519 () {
++    // 2 ^ 255 - 19
++    MPrime.call(
++      this,
++      '25519',
++      '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed');
++  }
++  inherits(P25519, MPrime);
++
++  P25519.prototype.imulK = function imulK (num) {
++    // K = 0x13
++    var carry = 0;
++    for (var i = 0; i < num.length; i++) {
++      var hi = (num.words[i] | 0) * 0x13 + carry;
++      var lo = hi & 0x3ffffff;
++      hi >>>= 26;
++
++      num.words[i] = lo;
++      carry = hi;
++    }
++    if (carry !== 0) {
++      num.words[num.length++] = carry;
++    }
++    return num;
++  };
++
++  // Exported mostly for testing purposes, use plain name instead
++  BN._prime = function prime (name) {
++    // Cached version of prime
++    if (primes[name]) return primes[name];
++
++    var prime;
++    if (name === 'k256') {
++      prime = new K256();
++    } else if (name === 'p224') {
++      prime = new P224();
++    } else if (name === 'p192') {
++      prime = new P192();
++    } else if (name === 'p25519') {
++      prime = new P25519();
++    } else {
++      throw new Error('Unknown prime ' + name);
++    }
++    primes[name] = prime;
++
++    return prime;
++  };
++
++  //
++  // Base reduction engine
++  //
++  function Red (m) {
++    if (typeof m === 'string') {
++      var prime = BN._prime(m);
++      this.m = prime.p;
++      this.prime = prime;
++    } else {
++      assert(m.gtn(1), 'modulus must be greater than 1');
++      this.m = m;
++      this.prime = null;
++    }
++  }
++
++  Red.prototype._verify1 = function _verify1 (a) {
++    assert(a.negative === 0, 'red works only with positives');
++    assert(a.red, 'red works only with red numbers');
++  };
++
++  Red.prototype._verify2 = function _verify2 (a, b) {
++    assert((a.negative | b.negative) === 0, 'red works only with positives');
++    assert(a.red && a.red === b.red,
++      'red works only with red numbers');
++  };
++
++  Red.prototype.imod = function imod (a) {
++    if (this.prime) return this.prime.ireduce(a)._forceRed(this);
++    return a.umod(this.m)._forceRed(this);
++  };
++
++  Red.prototype.neg = function neg (a) {
++    if (a.isZero()) {
++      return a.clone();
++    }
++
++    return this.m.sub(a)._forceRed(this);
++  };
++
++  Red.prototype.add = function add (a, b) {
++    this._verify2(a, b);
++
++    var res = a.add(b);
++    if (res.cmp(this.m) >= 0) {
++      res.isub(this.m);
++    }
++    return res._forceRed(this);
++  };
++
++  Red.prototype.iadd = function iadd (a, b) {
++    this._verify2(a, b);
++
++    var res = a.iadd(b);
++    if (res.cmp(this.m) >= 0) {
++      res.isub(this.m);
++    }
++    return res;
++  };
++
++  Red.prototype.sub = function sub (a, b) {
++    this._verify2(a, b);
++
++    var res = a.sub(b);
++    if (res.cmpn(0) < 0) {
++      res.iadd(this.m);
++    }
++    return res._forceRed(this);
++  };
++
++  Red.prototype.isub = function isub (a, b) {
++    this._verify2(a, b);
++
++    var res = a.isub(b);
++    if (res.cmpn(0) < 0) {
++      res.iadd(this.m);
++    }
++    return res;
++  };
++
++  Red.prototype.shl = function shl (a, num) {
++    this._verify1(a);
++    return this.imod(a.ushln(num));
++  };
++
++  Red.prototype.imul = function imul (a, b) {
++    this._verify2(a, b);
++    return this.imod(a.imul(b));
++  };
++
++  Red.prototype.mul = function mul (a, b) {
++    this._verify2(a, b);
++    return this.imod(a.mul(b));
++  };
++
++  Red.prototype.isqr = function isqr (a) {
++    return this.imul(a, a.clone());
++  };
++
++  Red.prototype.sqr = function sqr (a) {
++    return this.mul(a, a);
++  };
++
++  Red.prototype.sqrt = function sqrt (a) {
++    if (a.isZero()) return a.clone();
++
++    var mod3 = this.m.andln(3);
++    assert(mod3 % 2 === 1);
++
++    // Fast case
++    if (mod3 === 3) {
++      var pow = this.m.add(new BN(1)).iushrn(2);
++      return this.pow(a, pow);
++    }
++
++    // Tonelli-Shanks algorithm (Totally unoptimized and slow)
++    //
++    // Find Q and S, that Q * 2 ^ S = (P - 1)
++    var q = this.m.subn(1);
++    var s = 0;
++    while (!q.isZero() && q.andln(1) === 0) {
++      s++;
++      q.iushrn(1);
++    }
++    assert(!q.isZero());
++
++    var one = new BN(1).toRed(this);
++    var nOne = one.redNeg();
++
++    // Find quadratic non-residue
++    // NOTE: Max is such because of generalized Riemann hypothesis.
++    var lpow = this.m.subn(1).iushrn(1);
++    var z = this.m.bitLength();
++    z = new BN(2 * z * z).toRed(this);
++
++    while (this.pow(z, lpow).cmp(nOne) !== 0) {
++      z.redIAdd(nOne);
++    }
++
++    var c = this.pow(z, q);
++    var r = this.pow(a, q.addn(1).iushrn(1));
++    var t = this.pow(a, q);
++    var m = s;
++    while (t.cmp(one) !== 0) {
++      var tmp = t;
++      for (var i = 0; tmp.cmp(one) !== 0; i++) {
++        tmp = tmp.redSqr();
++      }
++      assert(i < m);
++      var b = this.pow(c, new BN(1).iushln(m - i - 1));
++
++      r = r.redMul(b);
++      c = b.redSqr();
++      t = t.redMul(c);
++      m = i;
++    }
++
++    return r;
++  };
++
++  Red.prototype.invm = function invm (a) {
++    var inv = a._invmp(this.m);
++    if (inv.negative !== 0) {
++      inv.negative = 0;
++      return this.imod(inv).redNeg();
++    } else {
++      return this.imod(inv);
++    }
++  };
++
++  Red.prototype.pow = function pow (a, num) {
++    if (num.isZero()) return new BN(1);
++    if (num.cmpn(1) === 0) return a.clone();
++
++    var windowSize = 4;
++    var wnd = new Array(1 << windowSize);
++    wnd[0] = new BN(1).toRed(this);
++    wnd[1] = a;
++    for (var i = 2; i < wnd.length; i++) {
++      wnd[i] = this.mul(wnd[i - 1], a);
++    }
++
++    var res = wnd[0];
++    var current = 0;
++    var currentLen = 0;
++    var start = num.bitLength() % 26;
++    if (start === 0) {
++      start = 26;
++    }
++
++    for (i = num.length - 1; i >= 0; i--) {
++      var word = num.words[i];
++      for (var j = start - 1; j >= 0; j--) {
++        var bit = (word >> j) & 1;
++        if (res !== wnd[0]) {
++          res = this.sqr(res);
++        }
++
++        if (bit === 0 && current === 0) {
++          currentLen = 0;
++          continue;
++        }
++
++        current <<= 1;
++        current |= bit;
++        currentLen++;
++        if (currentLen !== windowSize && (i !== 0 || j !== 0)) continue;
++
++        res = this.mul(res, wnd[current]);
++        currentLen = 0;
++        current = 0;
++      }
++      start = 26;
++    }
++
++    return res;
++  };
++
++  Red.prototype.convertTo = function convertTo (num) {
++    var r = num.umod(this.m);
++
++    return r === num ? r.clone() : r;
++  };
++
++  Red.prototype.convertFrom = function convertFrom (num) {
++    var res = num.clone();
++    res.red = null;
++    return res;
++  };
++
++  //
++  // Montgomery method engine
++  //
++
++  BN.mont = function mont (num) {
++    return new Mont(num);
++  };
++
++  function Mont (m) {
++    Red.call(this, m);
++
++    this.shift = this.m.bitLength();
++    if (this.shift % 26 !== 0) {
++      this.shift += 26 - (this.shift % 26);
++    }
++
++    this.r = new BN(1).iushln(this.shift);
++    this.r2 = this.imod(this.r.sqr());
++    this.rinv = this.r._invmp(this.m);
++
++    this.minv = this.rinv.mul(this.r).isubn(1).div(this.m);
++    this.minv = this.minv.umod(this.r);
++    this.minv = this.r.sub(this.minv);
++  }
++  inherits(Mont, Red);
++
++  Mont.prototype.convertTo = function convertTo (num) {
++    return this.imod(num.ushln(this.shift));
++  };
++
++  Mont.prototype.convertFrom = function convertFrom (num) {
++    var r = this.imod(num.mul(this.rinv));
++    r.red = null;
++    return r;
++  };
++
++  Mont.prototype.imul = function imul (a, b) {
++    if (a.isZero() || b.isZero()) {
++      a.words[0] = 0;
++      a.length = 1;
++      return a;
++    }
++
++    var t = a.imul(b);
++    var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
++    var u = t.isub(c).iushrn(this.shift);
++    var res = u;
++
++    if (u.cmp(this.m) >= 0) {
++      res = u.isub(this.m);
++    } else if (u.cmpn(0) < 0) {
++      res = u.iadd(this.m);
++    }
++
++    return res._forceRed(this);
++  };
++
++  Mont.prototype.mul = function mul (a, b) {
++    if (a.isZero() || b.isZero()) return new BN(0)._forceRed(this);
++
++    var t = a.mul(b);
++    var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
++    var u = t.isub(c).iushrn(this.shift);
++    var res = u;
++    if (u.cmp(this.m) >= 0) {
++      res = u.isub(this.m);
++    } else if (u.cmpn(0) < 0) {
++      res = u.iadd(this.m);
++    }
++
++    return res._forceRed(this);
++  };
++
++  Mont.prototype.invm = function invm (a) {
++    // (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R
++    var res = this.imod(a._invmp(this.m).mul(this.r2));
++    return res._forceRed(this);
++  };
++})(typeof module === 'undefined' || module, this);
++
++},{}],2:[function(require,module,exports){
++'use strict';
++
++var elliptic = exports;
++
++elliptic.version = require('../package.json').version;
++elliptic.utils = require('./elliptic/utils');
++elliptic.rand = require('brorand');
++elliptic.hmacDRBG = require('./elliptic/hmac-drbg');
++elliptic.curve = require('./elliptic/curve');
++elliptic.curves = require('./elliptic/curves');
++
++// Protocols
++elliptic.ec = require('./elliptic/ec');
++elliptic.eddsa = require('./elliptic/eddsa');
++
++},{"../package.json":26,"./elliptic/curve":5,"./elliptic/curves":8,"./elliptic/ec":9,"./elliptic/eddsa":12,"./elliptic/hmac-drbg":15,"./elliptic/utils":17,"brorand":18}],3:[function(require,module,exports){
++'use strict';
++
++var BN = require('bn.js');
++var elliptic = require('../../elliptic');
++var utils = elliptic.utils;
++var getNAF = utils.getNAF;
++var getJSF = utils.getJSF;
++var assert = utils.assert;
++
++function BaseCurve(type, conf) {
++  this.type = type;
++  this.p = new BN(conf.p, 16);
++
++  // Use Montgomery, when there is no fast reduction for the prime
++  this.red = conf.prime ? BN.red(conf.prime) : BN.mont(this.p);
++
++  // Useful for many curves
++  this.zero = new BN(0).toRed(this.red);
++  this.one = new BN(1).toRed(this.red);
++  this.two = new BN(2).toRed(this.red);
++
++  // Curve configuration, optional
++  this.n = conf.n && new BN(conf.n, 16);
++  this.g = conf.g && this.pointFromJSON(conf.g, conf.gRed);
++
++  // Temporary arrays
++  this._wnafT1 = new Array(4);
++  this._wnafT2 = new Array(4);
++  this._wnafT3 = new Array(4);
++  this._wnafT4 = new Array(4);
++
++  // Generalized Greg Maxwell's trick
++  var adjustCount = this.n && this.p.div(this.n);
++  if (!adjustCount || adjustCount.cmpn(100) > 0) {
++    this.redN = null;
++  } else {
++    this._maxwellTrick = true;
++    this.redN = this.n.toRed(this.red);
++  }
++}
++module.exports = BaseCurve;
++
++BaseCurve.prototype.point = function point() {
++  throw new Error('Not implemented');
++};
++
++BaseCurve.prototype.validate = function validate() {
++  throw new Error('Not implemented');
++};
++
++BaseCurve.prototype._fixedNafMul = function _fixedNafMul(p, k) {
++  assert(p.precomputed);
++  var doubles = p._getDoubles();
++
++  var naf = getNAF(k, 1);
++  var I = (1 << (doubles.step + 1)) - (doubles.step % 2 === 0 ? 2 : 1);
++  I /= 3;
++
++  // Translate into more windowed form
++  var repr = [];
++  for (var j = 0; j < naf.length; j += doubles.step) {
++    var nafW = 0;
++    for (var k = j + doubles.step - 1; k >= j; k--)
++      nafW = (nafW << 1) + naf[k];
++    repr.push(nafW);
++  }
++
++  var a = this.jpoint(null, null, null);
++  var b = this.jpoint(null, null, null);
++  for (var i = I; i > 0; i--) {
++    for (var j = 0; j < repr.length; j++) {
++      var nafW = repr[j];
++      if (nafW === i)
++        b = b.mixedAdd(doubles.points[j]);
++      else if (nafW === -i)
++        b = b.mixedAdd(doubles.points[j].neg());
++    }
++    a = a.add(b);
++  }
++  return a.toP();
++};
++
++BaseCurve.prototype._wnafMul = function _wnafMul(p, k) {
++  var w = 4;
++
++  // Precompute window
++  var nafPoints = p._getNAFPoints(w);
++  w = nafPoints.wnd;
++  var wnd = nafPoints.points;
++
++  // Get NAF form
++  var naf = getNAF(k, w);
++
++  // Add `this`*(N+1) for every w-NAF index
++  var acc = this.jpoint(null, null, null);
++  for (var i = naf.length - 1; i >= 0; i--) {
++    // Count zeroes
++    for (var k = 0; i >= 0 && naf[i] === 0; i--)
++      k++;
++    if (i >= 0)
++      k++;
++    acc = acc.dblp(k);
++
++    if (i < 0)
++      break;
++    var z = naf[i];
++    assert(z !== 0);
++    if (p.type === 'affine') {
++      // J +- P
++      if (z > 0)
++        acc = acc.mixedAdd(wnd[(z - 1) >> 1]);
++      else
++        acc = acc.mixedAdd(wnd[(-z - 1) >> 1].neg());
++    } else {
++      // J +- J
++      if (z > 0)
++        acc = acc.add(wnd[(z - 1) >> 1]);
++      else
++        acc = acc.add(wnd[(-z - 1) >> 1].neg());
++    }
++  }
++  return p.type === 'affine' ? acc.toP() : acc;
++};
++
++BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW,
++                                                       points,
++                                                       coeffs,
++                                                       len,
++                                                       jacobianResult) {
++  var wndWidth = this._wnafT1;
++  var wnd = this._wnafT2;
++  var naf = this._wnafT3;
++
++  // Fill all arrays
++  var max = 0;
++  for (var i = 0; i < len; i++) {
++    var p = points[i];
++    var nafPoints = p._getNAFPoints(defW);
++    wndWidth[i] = nafPoints.wnd;
++    wnd[i] = nafPoints.points;
++  }
++
++  // Comb small window NAFs
++  for (var i = len - 1; i >= 1; i -= 2) {
++    var a = i - 1;
++    var b = i;
++    if (wndWidth[a] !== 1 || wndWidth[b] !== 1) {
++      naf[a] = getNAF(coeffs[a], wndWidth[a]);
++      naf[b] = getNAF(coeffs[b], wndWidth[b]);
++      max = Math.max(naf[a].length, max);
++      max = Math.max(naf[b].length, max);
++      continue;
++    }
++
++    var comb = [
++      points[a], /* 1 */
++      null, /* 3 */
++      null, /* 5 */
++      points[b] /* 7 */
++    ];
++
++    // Try to avoid Projective points, if possible
++    if (points[a].y.cmp(points[b].y) === 0) {
++      comb[1] = points[a].add(points[b]);
++      comb[2] = points[a].toJ().mixedAdd(points[b].neg());
++    } else if (points[a].y.cmp(points[b].y.redNeg()) === 0) {
++      comb[1] = points[a].toJ().mixedAdd(points[b]);
++      comb[2] = points[a].add(points[b].neg());
++    } else {
++      comb[1] = points[a].toJ().mixedAdd(points[b]);
++      comb[2] = points[a].toJ().mixedAdd(points[b].neg());
++    }
++
++    var index = [
++      -3, /* -1 -1 */
++      -1, /* -1 0 */
++      -5, /* -1 1 */
++      -7, /* 0 -1 */
++      0, /* 0 0 */
++      7, /* 0 1 */
++      5, /* 1 -1 */
++      1, /* 1 0 */
++      3  /* 1 1 */
++    ];
++
++    var jsf = getJSF(coeffs[a], coeffs[b]);
++    max = Math.max(jsf[0].length, max);
++    naf[a] = new Array(max);
++    naf[b] = new Array(max);
++    for (var j = 0; j < max; j++) {
++      var ja = jsf[0][j] | 0;
++      var jb = jsf[1][j] | 0;
++
++      naf[a][j] = index[(ja + 1) * 3 + (jb + 1)];
++      naf[b][j] = 0;
++      wnd[a] = comb;
++    }
++  }
++
++  var acc = this.jpoint(null, null, null);
++  var tmp = this._wnafT4;
++  for (var i = max; i >= 0; i--) {
++    var k = 0;
++
++    while (i >= 0) {
++      var zero = true;
++      for (var j = 0; j < len; j++) {
++        tmp[j] = naf[j][i] | 0;
++        if (tmp[j] !== 0)
++          zero = false;
++      }
++      if (!zero)
++        break;
++      k++;
++      i--;
++    }
++    if (i >= 0)
++      k++;
++    acc = acc.dblp(k);
++    if (i < 0)
++      break;
++
++    for (var j = 0; j < len; j++) {
++      var z = tmp[j];
++      var p;
++      if (z === 0)
++        continue;
++      else if (z > 0)
++        p = wnd[j][(z - 1) >> 1];
++      else if (z < 0)
++        p = wnd[j][(-z - 1) >> 1].neg();
++
++      if (p.type === 'affine')
++        acc = acc.mixedAdd(p);
++      else
++        acc = acc.add(p);
++    }
++  }
++  // Zeroify references
++  for (var i = 0; i < len; i++)
++    wnd[i] = null;
++
++  if (jacobianResult)
++    return acc;
++  else
++    return acc.toP();
++};
++
++function BasePoint(curve, type) {
++  this.curve = curve;
++  this.type = type;
++  this.precomputed = null;
++}
++BaseCurve.BasePoint = BasePoint;
++
++BasePoint.prototype.eq = function eq(/*other*/) {
++  throw new Error('Not implemented');
++};
++
++BasePoint.prototype.validate = function validate() {
++  return this.curve.validate(this);
++};
++
++BaseCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
++  bytes = utils.toArray(bytes, enc);
++
++  var len = this.p.byteLength();
++
++  // uncompressed, hybrid-odd, hybrid-even
++  if ((bytes[0] === 0x04 || bytes[0] === 0x06 || bytes[0] === 0x07) &&
++      bytes.length - 1 === 2 * len) {
++    if (bytes[0] === 0x06)
++      assert(bytes[bytes.length - 1] % 2 === 0);
++    else if (bytes[0] === 0x07)
++      assert(bytes[bytes.length - 1] % 2 === 1);
++
++    var res =  this.point(bytes.slice(1, 1 + len),
++                          bytes.slice(1 + len, 1 + 2 * len));
++
++    return res;
++  } else if ((bytes[0] === 0x02 || bytes[0] === 0x03) &&
++              bytes.length - 1 === len) {
++    return this.pointFromX(bytes.slice(1, 1 + len), bytes[0] === 0x03);
++  }
++  throw new Error('Unknown point format');
++};
++
++BasePoint.prototype.encodeCompressed = function encodeCompressed(enc) {
++  return this.encode(enc, true);
++};
++
++BasePoint.prototype._encode = function _encode(compact) {
++  var len = this.curve.p.byteLength();
++  var x = this.getX().toArray('be', len);
++
++  if (compact)
++    return [ this.getY().isEven() ? 0x02 : 0x03 ].concat(x);
++
++  return [ 0x04 ].concat(x, this.getY().toArray('be', len)) ;
++};
++
++BasePoint.prototype.encode = function encode(enc, compact) {
++  return utils.encode(this._encode(compact), enc);
++};
++
++BasePoint.prototype.precompute = function precompute(power) {
++  if (this.precomputed)
++    return this;
++
++  var precomputed = {
++    doubles: null,
++    naf: null,
++    beta: null
++  };
++  precomputed.naf = this._getNAFPoints(8);
++  precomputed.doubles = this._getDoubles(4, power);
++  precomputed.beta = this._getBeta();
++  this.precomputed = precomputed;
++
++  return this;
++};
++
++BasePoint.prototype._hasDoubles = function _hasDoubles(k) {
++  if (!this.precomputed)
++    return false;
++
++  var doubles = this.precomputed.doubles;
++  if (!doubles)
++    return false;
++
++  return doubles.points.length >= Math.ceil((k.bitLength() + 1) / doubles.step);
++};
++
++BasePoint.prototype._getDoubles = function _getDoubles(step, power) {
++  if (this.precomputed && this.precomputed.doubles)
++    return this.precomputed.doubles;
++
++  var doubles = [ this ];
++  var acc = this;
++  for (var i = 0; i < power; i += step) {
++    for (var j = 0; j < step; j++)
++      acc = acc.dbl();
++    doubles.push(acc);
++  }
++  return {
++    step: step,
++    points: doubles
++  };
++};
++
++BasePoint.prototype._getNAFPoints = function _getNAFPoints(wnd) {
++  if (this.precomputed && this.precomputed.naf)
++    return this.precomputed.naf;
++
++  var res = [ this ];
++  var max = (1 << wnd) - 1;
++  var dbl = max === 1 ? null : this.dbl();
++  for (var i = 1; i < max; i++)
++    res[i] = res[i - 1].add(dbl);
++  return {
++    wnd: wnd,
++    points: res
++  };
++};
++
++BasePoint.prototype._getBeta = function _getBeta() {
++  return null;
++};
++
++BasePoint.prototype.dblp = function dblp(k) {
++  var r = this;
++  for (var i = 0; i < k; i++)
++    r = r.dbl();
++  return r;
++};
++
++},{"../../elliptic":2,"bn.js":1}],4:[function(require,module,exports){
++'use strict';
++
++var curve = require('../curve');
++var elliptic = require('../../elliptic');
++var BN = require('bn.js');
++var inherits = require('inherits');
++var Base = curve.base;
++
++var assert = elliptic.utils.assert;
++
++function EdwardsCurve(conf) {
++  // NOTE: Important as we are creating point in Base.call()
++  this.twisted = (conf.a | 0) !== 1;
++  this.mOneA = this.twisted && (conf.a | 0) === -1;
++  this.extended = this.mOneA;
++
++  Base.call(this, 'edwards', conf);
++
++  this.a = new BN(conf.a, 16).umod(this.red.m);
++  this.a = this.a.toRed(this.red);
++  this.c = new BN(conf.c, 16).toRed(this.red);
++  this.c2 = this.c.redSqr();
++  this.d = new BN(conf.d, 16).toRed(this.red);
++  this.dd = this.d.redAdd(this.d);
++
++  assert(!this.twisted || this.c.fromRed().cmpn(1) === 0);
++  this.oneC = (conf.c | 0) === 1;
++}
++inherits(EdwardsCurve, Base);
++module.exports = EdwardsCurve;
++
++EdwardsCurve.prototype._mulA = function _mulA(num) {
++  if (this.mOneA)
++    return num.redNeg();
++  else
++    return this.a.redMul(num);
++};
++
++EdwardsCurve.prototype._mulC = function _mulC(num) {
++  if (this.oneC)
++    return num;
++  else
++    return this.c.redMul(num);
++};
++
++// Just for compatibility with Short curve
++EdwardsCurve.prototype.jpoint = function jpoint(x, y, z, t) {
++  return this.point(x, y, z, t);
++};
++
++EdwardsCurve.prototype.pointFromX = function pointFromX(x, odd) {
++  x = new BN(x, 16);
++  if (!x.red)
++    x = x.toRed(this.red);
++
++  var x2 = x.redSqr();
++  var rhs = this.c2.redSub(this.a.redMul(x2));
++  var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2));
++
++  var y2 = rhs.redMul(lhs.redInvm());
++  var y = y2.redSqrt();
++  if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
++    throw new Error('invalid point');
++
++  var isOdd = y.fromRed().isOdd();
++  if (odd && !isOdd || !odd && isOdd)
++    y = y.redNeg();
++
++  return this.point(x, y);
++};
++
++EdwardsCurve.prototype.pointFromY = function pointFromY(y, odd) {
++  y = new BN(y, 16);
++  if (!y.red)
++    y = y.toRed(this.red);
++
++  // x^2 = (y^2 - 1) / (d y^2 + 1)
++  var y2 = y.redSqr();
++  var lhs = y2.redSub(this.one);
++  var rhs = y2.redMul(this.d).redAdd(this.one);
++  var x2 = lhs.redMul(rhs.redInvm());
++
++  if (x2.cmp(this.zero) === 0) {
++    if (odd)
++      throw new Error('invalid point');
++    else
++      return this.point(this.zero, y);
++  }
++
++  var x = x2.redSqrt();
++  if (x.redSqr().redSub(x2).cmp(this.zero) !== 0)
++    throw new Error('invalid point');
++
++  if (x.isOdd() !== odd)
++    x = x.redNeg();
++
++  return this.point(x, y);
++};
++
++EdwardsCurve.prototype.validate = function validate(point) {
++  if (point.isInfinity())
++    return true;
++
++  // Curve: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2)
++  point.normalize();
++
++  var x2 = point.x.redSqr();
++  var y2 = point.y.redSqr();
++  var lhs = x2.redMul(this.a).redAdd(y2);
++  var rhs = this.c2.redMul(this.one.redAdd(this.d.redMul(x2).redMul(y2)));
++
++  return lhs.cmp(rhs) === 0;
++};
++
++function Point(curve, x, y, z, t) {
++  Base.BasePoint.call(this, curve, 'projective');
++  if (x === null && y === null && z === null) {
++    this.x = this.curve.zero;
++    this.y = this.curve.one;
++    this.z = this.curve.one;
++    this.t = this.curve.zero;
++    this.zOne = true;
++  } else {
++    this.x = new BN(x, 16);
++    this.y = new BN(y, 16);
++    this.z = z ? new BN(z, 16) : this.curve.one;
++    this.t = t && new BN(t, 16);
++    if (!this.x.red)
++      this.x = this.x.toRed(this.curve.red);
++    if (!this.y.red)
++      this.y = this.y.toRed(this.curve.red);
++    if (!this.z.red)
++      this.z = this.z.toRed(this.curve.red);
++    if (this.t && !this.t.red)
++      this.t = this.t.toRed(this.curve.red);
++    this.zOne = this.z === this.curve.one;
++
++    // Use extended coordinates
++    if (this.curve.extended && !this.t) {
++      this.t = this.x.redMul(this.y);
++      if (!this.zOne)
++        this.t = this.t.redMul(this.z.redInvm());
++    }
++  }
++}
++inherits(Point, Base.BasePoint);
++
++EdwardsCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
++  return Point.fromJSON(this, obj);
++};
++
++EdwardsCurve.prototype.point = function point(x, y, z, t) {
++  return new Point(this, x, y, z, t);
++};
++
++Point.fromJSON = function fromJSON(curve, obj) {
++  return new Point(curve, obj[0], obj[1], obj[2]);
++};
++
++Point.prototype.inspect = function inspect() {
++  if (this.isInfinity())
++    return '<EC Point Infinity>';
++  return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
++      ' y: ' + this.y.fromRed().toString(16, 2) +
++      ' z: ' + this.z.fromRed().toString(16, 2) + '>';
++};
++
++Point.prototype.isInfinity = function isInfinity() {
++  // XXX This code assumes that zero is always zero in red
++  return this.x.cmpn(0) === 0 &&
++         this.y.cmp(this.z) === 0;
++};
++
++Point.prototype._extDbl = function _extDbl() {
++  // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
++  //     #doubling-dbl-2008-hwcd
++  // 4M + 4S
++
++  // A = X1^2
++  var a = this.x.redSqr();
++  // B = Y1^2
++  var b = this.y.redSqr();
++  // C = 2 * Z1^2
++  var c = this.z.redSqr();
++  c = c.redIAdd(c);
++  // D = a * A
++  var d = this.curve._mulA(a);
++  // E = (X1 + Y1)^2 - A - B
++  var e = this.x.redAdd(this.y).redSqr().redISub(a).redISub(b);
++  // G = D + B
++  var g = d.redAdd(b);
++  // F = G - C
++  var f = g.redSub(c);
++  // H = D - B
++  var h = d.redSub(b);
++  // X3 = E * F
++  var nx = e.redMul(f);
++  // Y3 = G * H
++  var ny = g.redMul(h);
++  // T3 = E * H
++  var nt = e.redMul(h);
++  // Z3 = F * G
++  var nz = f.redMul(g);
++  return this.curve.point(nx, ny, nz, nt);
++};
++
++Point.prototype._projDbl = function _projDbl() {
++  // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
++  //     #doubling-dbl-2008-bbjlp
++  //     #doubling-dbl-2007-bl
++  // and others
++  // Generally 3M + 4S or 2M + 4S
++
++  // B = (X1 + Y1)^2
++  var b = this.x.redAdd(this.y).redSqr();
++  // C = X1^2
++  var c = this.x.redSqr();
++  // D = Y1^2
++  var d = this.y.redSqr();
++
++  var nx;
++  var ny;
++  var nz;
++  if (this.curve.twisted) {
++    // E = a * C
++    var e = this.curve._mulA(c);
++    // F = E + D
++    var f = e.redAdd(d);
++    if (this.zOne) {
++      // X3 = (B - C - D) * (F - 2)
++      nx = b.redSub(c).redSub(d).redMul(f.redSub(this.curve.two));
++      // Y3 = F * (E - D)
++      ny = f.redMul(e.redSub(d));
++      // Z3 = F^2 - 2 * F
++      nz = f.redSqr().redSub(f).redSub(f);
++    } else {
++      // H = Z1^2
++      var h = this.z.redSqr();
++      // J = F - 2 * H
++      var j = f.redSub(h).redISub(h);
++      // X3 = (B-C-D)*J
++      nx = b.redSub(c).redISub(d).redMul(j);
++      // Y3 = F * (E - D)
++      ny = f.redMul(e.redSub(d));
++      // Z3 = F * J
++      nz = f.redMul(j);
++    }
++  } else {
++    // E = C + D
++    var e = c.redAdd(d);
++    // H = (c * Z1)^2
++    var h = this.curve._mulC(this.c.redMul(this.z)).redSqr();
++    // J = E - 2 * H
++    var j = e.redSub(h).redSub(h);
++    // X3 = c * (B - E) * J
++    nx = this.curve._mulC(b.redISub(e)).redMul(j);
++    // Y3 = c * E * (C - D)
++    ny = this.curve._mulC(e).redMul(c.redISub(d));
++    // Z3 = E * J
++    nz = e.redMul(j);
++  }
++  return this.curve.point(nx, ny, nz);
++};
++
++Point.prototype.dbl = function dbl() {
++  if (this.isInfinity())
++    return this;
++
++  // Double in extended coordinates
++  if (this.curve.extended)
++    return this._extDbl();
++  else
++    return this._projDbl();
++};
++
++Point.prototype._extAdd = function _extAdd(p) {
++  // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
++  //     #addition-add-2008-hwcd-3
++  // 8M
++
++  // A = (Y1 - X1) * (Y2 - X2)
++  var a = this.y.redSub(this.x).redMul(p.y.redSub(p.x));
++  // B = (Y1 + X1) * (Y2 + X2)
++  var b = this.y.redAdd(this.x).redMul(p.y.redAdd(p.x));
++  // C = T1 * k * T2
++  var c = this.t.redMul(this.curve.dd).redMul(p.t);
++  // D = Z1 * 2 * Z2
++  var d = this.z.redMul(p.z.redAdd(p.z));
++  // E = B - A
++  var e = b.redSub(a);
++  // F = D - C
++  var f = d.redSub(c);
++  // G = D + C
++  var g = d.redAdd(c);
++  // H = B + A
++  var h = b.redAdd(a);
++  // X3 = E * F
++  var nx = e.redMul(f);
++  // Y3 = G * H
++  var ny = g.redMul(h);
++  // T3 = E * H
++  var nt = e.redMul(h);
++  // Z3 = F * G
++  var nz = f.redMul(g);
++  return this.curve.point(nx, ny, nz, nt);
++};
++
++Point.prototype._projAdd = function _projAdd(p) {
++  // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
++  //     #addition-add-2008-bbjlp
++  //     #addition-add-2007-bl
++  // 10M + 1S
++
++  // A = Z1 * Z2
++  var a = this.z.redMul(p.z);
++  // B = A^2
++  var b = a.redSqr();
++  // C = X1 * X2
++  var c = this.x.redMul(p.x);
++  // D = Y1 * Y2
++  var d = this.y.redMul(p.y);
++  // E = d * C * D
++  var e = this.curve.d.redMul(c).redMul(d);
++  // F = B - E
++  var f = b.redSub(e);
++  // G = B + E
++  var g = b.redAdd(e);
++  // X3 = A * F * ((X1 + Y1) * (X2 + Y2) - C - D)
++  var tmp = this.x.redAdd(this.y).redMul(p.x.redAdd(p.y)).redISub(c).redISub(d);
++  var nx = a.redMul(f).redMul(tmp);
++  var ny;
++  var nz;
++  if (this.curve.twisted) {
++    // Y3 = A * G * (D - a * C)
++    ny = a.redMul(g).redMul(d.redSub(this.curve._mulA(c)));
++    // Z3 = F * G
++    nz = f.redMul(g);
++  } else {
++    // Y3 = A * G * (D - C)
++    ny = a.redMul(g).redMul(d.redSub(c));
++    // Z3 = c * F * G
++    nz = this.curve._mulC(f).redMul(g);
++  }
++  return this.curve.point(nx, ny, nz);
++};
++
++Point.prototype.add = function add(p) {
++  if (this.isInfinity())
++    return p;
++  if (p.isInfinity())
++    return this;
++
++  if (this.curve.extended)
++    return this._extAdd(p);
++  else
++    return this._projAdd(p);
++};
++
++Point.prototype.mul = function mul(k) {
++  if (this._hasDoubles(k))
++    return this.curve._fixedNafMul(this, k);
++  else
++    return this.curve._wnafMul(this, k);
++};
++
++Point.prototype.mulAdd = function mulAdd(k1, p, k2) {
++  return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, false);
++};
++
++Point.prototype.jmulAdd = function jmulAdd(k1, p, k2) {
++  return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, true);
++};
++
++Point.prototype.normalize = function normalize() {
++  if (this.zOne)
++    return this;
++
++  // Normalize coordinates
++  var zi = this.z.redInvm();
++  this.x = this.x.redMul(zi);
++  this.y = this.y.redMul(zi);
++  if (this.t)
++    this.t = this.t.redMul(zi);
++  this.z = this.curve.one;
++  this.zOne = true;
++  return this;
++};
++
++Point.prototype.neg = function neg() {
++  return this.curve.point(this.x.redNeg(),
++                          this.y,
++                          this.z,
++                          this.t && this.t.redNeg());
++};
++
++Point.prototype.getX = function getX() {
++  this.normalize();
++  return this.x.fromRed();
++};
++
++Point.prototype.getY = function getY() {
++  this.normalize();
++  return this.y.fromRed();
++};
++
++Point.prototype.eq = function eq(other) {
++  return this === other ||
++         this.getX().cmp(other.getX()) === 0 &&
++         this.getY().cmp(other.getY()) === 0;
++};
++
++Point.prototype.eqXToP = function eqXToP(x) {
++  var rx = x.toRed(this.curve.red).redMul(this.z);
++  if (this.x.cmp(rx) === 0)
++    return true;
++
++  var xc = x.clone();
++  var t = this.curve.redN.redMul(this.z);
++  for (;;) {
++    xc.iadd(this.curve.n);
++    if (xc.cmp(this.curve.p) >= 0)
++      return false;
++
++    rx.redIAdd(t);
++    if (this.x.cmp(rx) === 0)
++      return true;
++  }
++  return false;
++};
++
++// Compatibility with BaseCurve
++Point.prototype.toP = Point.prototype.normalize;
++Point.prototype.mixedAdd = Point.prototype.add;
++
++},{"../../elliptic":2,"../curve":5,"bn.js":1,"inherits":25}],5:[function(require,module,exports){
++'use strict';
++
++var curve = exports;
++
++curve.base = require('./base');
++curve.short = require('./short');
++curve.mont = require('./mont');
++curve.edwards = require('./edwards');
++
++},{"./base":3,"./edwards":4,"./mont":6,"./short":7}],6:[function(require,module,exports){
++'use strict';
++
++var curve = require('../curve');
++var BN = require('bn.js');
++var inherits = require('inherits');
++var Base = curve.base;
++
++var elliptic = require('../../elliptic');
++var utils = elliptic.utils;
++
++function MontCurve(conf) {
++  Base.call(this, 'mont', conf);
++
++  this.a = new BN(conf.a, 16).toRed(this.red);
++  this.b = new BN(conf.b, 16).toRed(this.red);
++  this.i4 = new BN(4).toRed(this.red).redInvm();
++  this.two = new BN(2).toRed(this.red);
++  this.a24 = this.i4.redMul(this.a.redAdd(this.two));
++}
++inherits(MontCurve, Base);
++module.exports = MontCurve;
++
++MontCurve.prototype.validate = function validate(point) {
++  var x = point.normalize().x;
++  var x2 = x.redSqr();
++  var rhs = x2.redMul(x).redAdd(x2.redMul(this.a)).redAdd(x);
++  var y = rhs.redSqrt();
++
++  return y.redSqr().cmp(rhs) === 0;
++};
++
++function Point(curve, x, z) {
++  Base.BasePoint.call(this, curve, 'projective');
++  if (x === null && z === null) {
++    this.x = this.curve.one;
++    this.z = this.curve.zero;
++  } else {
++    this.x = new BN(x, 16);
++    this.z = new BN(z, 16);
++    if (!this.x.red)
++      this.x = this.x.toRed(this.curve.red);
++    if (!this.z.red)
++      this.z = this.z.toRed(this.curve.red);
++  }
++}
++inherits(Point, Base.BasePoint);
++
++MontCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
++  return this.point(utils.toArray(bytes, enc), 1);
++};
++
++MontCurve.prototype.point = function point(x, z) {
++  return new Point(this, x, z);
++};
++
++MontCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
++  return Point.fromJSON(this, obj);
++};
++
++Point.prototype.precompute = function precompute() {
++  // No-op
++};
++
++Point.prototype._encode = function _encode() {
++  return this.getX().toArray('be', this.curve.p.byteLength());
++};
++
++Point.fromJSON = function fromJSON(curve, obj) {
++  return new Point(curve, obj[0], obj[1] || curve.one);
++};
++
++Point.prototype.inspect = function inspect() {
++  if (this.isInfinity())
++    return '<EC Point Infinity>';
++  return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
++      ' z: ' + this.z.fromRed().toString(16, 2) + '>';
++};
++
++Point.prototype.isInfinity = function isInfinity() {
++  // XXX This code assumes that zero is always zero in red
++  return this.z.cmpn(0) === 0;
++};
++
++Point.prototype.dbl = function dbl() {
++  // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-dbl-1987-m-3
++  // 2M + 2S + 4A
++
++  // A = X1 + Z1
++  var a = this.x.redAdd(this.z);
++  // AA = A^2
++  var aa = a.redSqr();
++  // B = X1 - Z1
++  var b = this.x.redSub(this.z);
++  // BB = B^2
++  var bb = b.redSqr();
++  // C = AA - BB
++  var c = aa.redSub(bb);
++  // X3 = AA * BB
++  var nx = aa.redMul(bb);
++  // Z3 = C * (BB + A24 * C)
++  var nz = c.redMul(bb.redAdd(this.curve.a24.redMul(c)));
++  return this.curve.point(nx, nz);
++};
++
++Point.prototype.add = function add() {
++  throw new Error('Not supported on Montgomery curve');
++};
++
++Point.prototype.diffAdd = function diffAdd(p, diff) {
++  // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#diffadd-dadd-1987-m-3
++  // 4M + 2S + 6A
++
++  // A = X2 + Z2
++  var a = this.x.redAdd(this.z);
++  // B = X2 - Z2
++  var b = this.x.redSub(this.z);
++  // C = X3 + Z3
++  var c = p.x.redAdd(p.z);
++  // D = X3 - Z3
++  var d = p.x.redSub(p.z);
++  // DA = D * A
++  var da = d.redMul(a);
++  // CB = C * B
++  var cb = c.redMul(b);
++  // X5 = Z1 * (DA + CB)^2
++  var nx = diff.z.redMul(da.redAdd(cb).redSqr());
++  // Z5 = X1 * (DA - CB)^2
++  var nz = diff.x.redMul(da.redISub(cb).redSqr());
++  return this.curve.point(nx, nz);
++};
++
++Point.prototype.mul = function mul(k) {
++  var t = k.clone();
++  var a = this; // (N / 2) * Q + Q
++  var b = this.curve.point(null, null); // (N / 2) * Q
++  var c = this; // Q
++
++  for (var bits = []; t.cmpn(0) !== 0; t.iushrn(1))
++    bits.push(t.andln(1));
++
++  for (var i = bits.length - 1; i >= 0; i--) {
++    if (bits[i] === 0) {
++      // N * Q + Q = ((N / 2) * Q + Q)) + (N / 2) * Q
++      a = a.diffAdd(b, c);
++      // N * Q = 2 * ((N / 2) * Q + Q))
++      b = b.dbl();
++    } else {
++      // N * Q = ((N / 2) * Q + Q) + ((N / 2) * Q)
++      b = a.diffAdd(b, c);
++      // N * Q + Q = 2 * ((N / 2) * Q + Q)
++      a = a.dbl();
++    }
++  }
++  return b;
++};
++
++Point.prototype.mulAdd = function mulAdd() {
++  throw new Error('Not supported on Montgomery curve');
++};
++
++Point.prototype.jumlAdd = function jumlAdd() {
++  throw new Error('Not supported on Montgomery curve');
++};
++
++Point.prototype.eq = function eq(other) {
++  return this.getX().cmp(other.getX()) === 0;
++};
++
++Point.prototype.normalize = function normalize() {
++  this.x = this.x.redMul(this.z.redInvm());
++  this.z = this.curve.one;
++  return this;
++};
++
++Point.prototype.getX = function getX() {
++  // Normalize coordinates
++  this.normalize();
++
++  return this.x.fromRed();
++};
++
++},{"../../elliptic":2,"../curve":5,"bn.js":1,"inherits":25}],7:[function(require,module,exports){
++'use strict';
++
++var curve = require('../curve');
++var elliptic = require('../../elliptic');
++var BN = require('bn.js');
++var inherits = require('inherits');
++var Base = curve.base;
++
++var assert = elliptic.utils.assert;
++
++function ShortCurve(conf) {
++  Base.call(this, 'short', conf);
++
++  this.a = new BN(conf.a, 16).toRed(this.red);
++  this.b = new BN(conf.b, 16).toRed(this.red);
++  this.tinv = this.two.redInvm();
++
++  this.zeroA = this.a.fromRed().cmpn(0) === 0;
++  this.threeA = this.a.fromRed().sub(this.p).cmpn(-3) === 0;
++
++  // If the curve is endomorphic, precalculate beta and lambda
++  this.endo = this._getEndomorphism(conf);
++  this._endoWnafT1 = new Array(4);
++  this._endoWnafT2 = new Array(4);
++}
++inherits(ShortCurve, Base);
++module.exports = ShortCurve;
++
++ShortCurve.prototype._getEndomorphism = function _getEndomorphism(conf) {
++  // No efficient endomorphism
++  if (!this.zeroA || !this.g || !this.n || this.p.modn(3) !== 1)
++    return;
++
++  // Compute beta and lambda, that lambda * P = (beta * Px; Py)
++  var beta;
++  var lambda;
++  if (conf.beta) {
++    beta = new BN(conf.beta, 16).toRed(this.red);
++  } else {
++    var betas = this._getEndoRoots(this.p);
++    // Choose the smallest beta
++    beta = betas[0].cmp(betas[1]) < 0 ? betas[0] : betas[1];
++    beta = beta.toRed(this.red);
++  }
++  if (conf.lambda) {
++    lambda = new BN(conf.lambda, 16);
++  } else {
++    // Choose the lambda that is matching selected beta
++    var lambdas = this._getEndoRoots(this.n);
++    if (this.g.mul(lambdas[0]).x.cmp(this.g.x.redMul(beta)) === 0) {
++      lambda = lambdas[0];
++    } else {
++      lambda = lambdas[1];
++      assert(this.g.mul(lambda).x.cmp(this.g.x.redMul(beta)) === 0);
++    }
++  }
++
++  // Get basis vectors, used for balanced length-two representation
++  var basis;
++  if (conf.basis) {
++    basis = conf.basis.map(function(vec) {
++      return {
++        a: new BN(vec.a, 16),
++        b: new BN(vec.b, 16)
++      };
++    });
++  } else {
++    basis = this._getEndoBasis(lambda);
++  }
++
++  return {
++    beta: beta,
++    lambda: lambda,
++    basis: basis
++  };
++};
++
++ShortCurve.prototype._getEndoRoots = function _getEndoRoots(num) {
++  // Find roots of for x^2 + x + 1 in F
++  // Root = (-1 +- Sqrt(-3)) / 2
++  //
++  var red = num === this.p ? this.red : BN.mont(num);
++  var tinv = new BN(2).toRed(red).redInvm();
++  var ntinv = tinv.redNeg();
++
++  var s = new BN(3).toRed(red).redNeg().redSqrt().redMul(tinv);
++
++  var l1 = ntinv.redAdd(s).fromRed();
++  var l2 = ntinv.redSub(s).fromRed();
++  return [ l1, l2 ];
++};
++
++ShortCurve.prototype._getEndoBasis = function _getEndoBasis(lambda) {
++  // aprxSqrt >= sqrt(this.n)
++  var aprxSqrt = this.n.ushrn(Math.floor(this.n.bitLength() / 2));
++
++  // 3.74
++  // Run EGCD, until r(L + 1) < aprxSqrt
++  var u = lambda;
++  var v = this.n.clone();
++  var x1 = new BN(1);
++  var y1 = new BN(0);
++  var x2 = new BN(0);
++  var y2 = new BN(1);
++
++  // NOTE: all vectors are roots of: a + b * lambda = 0 (mod n)
++  var a0;
++  var b0;
++  // First vector
++  var a1;
++  var b1;
++  // Second vector
++  var a2;
++  var b2;
++
++  var prevR;
++  var i = 0;
++  var r;
++  var x;
++  while (u.cmpn(0) !== 0) {
++    var q = v.div(u);
++    r = v.sub(q.mul(u));
++    x = x2.sub(q.mul(x1));
++    var y = y2.sub(q.mul(y1));
++
++    if (!a1 && r.cmp(aprxSqrt) < 0) {
++      a0 = prevR.neg();
++      b0 = x1;
++      a1 = r.neg();
++      b1 = x;
++    } else if (a1 && ++i === 2) {
++      break;
++    }
++    prevR = r;
++
++    v = u;
++    u = r;
++    x2 = x1;
++    x1 = x;
++    y2 = y1;
++    y1 = y;
++  }
++  a2 = r.neg();
++  b2 = x;
++
++  var len1 = a1.sqr().add(b1.sqr());
++  var len2 = a2.sqr().add(b2.sqr());
++  if (len2.cmp(len1) >= 0) {
++    a2 = a0;
++    b2 = b0;
++  }
++
++  // Normalize signs
++  if (a1.negative) {
++    a1 = a1.neg();
++    b1 = b1.neg();
++  }
++  if (a2.negative) {
++    a2 = a2.neg();
++    b2 = b2.neg();
++  }
++
++  return [
++    { a: a1, b: b1 },
++    { a: a2, b: b2 }
++  ];
++};
++
++ShortCurve.prototype._endoSplit = function _endoSplit(k) {
++  var basis = this.endo.basis;
++  var v1 = basis[0];
++  var v2 = basis[1];
++
++  var c1 = v2.b.mul(k).divRound(this.n);
++  var c2 = v1.b.neg().mul(k).divRound(this.n);
++
++  var p1 = c1.mul(v1.a);
++  var p2 = c2.mul(v2.a);
++  var q1 = c1.mul(v1.b);
++  var q2 = c2.mul(v2.b);
++
++  // Calculate answer
++  var k1 = k.sub(p1).sub(p2);
++  var k2 = q1.add(q2).neg();
++  return { k1: k1, k2: k2 };
++};
++
++ShortCurve.prototype.pointFromX = function pointFromX(x, odd) {
++  x = new BN(x, 16);
++  if (!x.red)
++    x = x.toRed(this.red);
++
++  var y2 = x.redSqr().redMul(x).redIAdd(x.redMul(this.a)).redIAdd(this.b);
++  var y = y2.redSqrt();
++  if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
++    throw new Error('invalid point');
++
++  // XXX Is there any way to tell if the number is odd without converting it
++  // to non-red form?
++  var isOdd = y.fromRed().isOdd();
++  if (odd && !isOdd || !odd && isOdd)
++    y = y.redNeg();
++
++  return this.point(x, y);
++};
++
++ShortCurve.prototype.validate = function validate(point) {
++  if (point.inf)
++    return true;
++
++  var x = point.x;
++  var y = point.y;
++
++  var ax = this.a.redMul(x);
++  var rhs = x.redSqr().redMul(x).redIAdd(ax).redIAdd(this.b);
++  return y.redSqr().redISub(rhs).cmpn(0) === 0;
++};
++
++ShortCurve.prototype._endoWnafMulAdd =
++    function _endoWnafMulAdd(points, coeffs, jacobianResult) {
++  var npoints = this._endoWnafT1;
++  var ncoeffs = this._endoWnafT2;
++  for (var i = 0; i < points.length; i++) {
++    var split = this._endoSplit(coeffs[i]);
++    var p = points[i];
++    var beta = p._getBeta();
++
++    if (split.k1.negative) {
++      split.k1.ineg();
++      p = p.neg(true);
++    }
++    if (split.k2.negative) {
++      split.k2.ineg();
++      beta = beta.neg(true);
++    }
++
++    npoints[i * 2] = p;
++    npoints[i * 2 + 1] = beta;
++    ncoeffs[i * 2] = split.k1;
++    ncoeffs[i * 2 + 1] = split.k2;
++  }
++  var res = this._wnafMulAdd(1, npoints, ncoeffs, i * 2, jacobianResult);
++
++  // Clean-up references to points and coefficients
++  for (var j = 0; j < i * 2; j++) {
++    npoints[j] = null;
++    ncoeffs[j] = null;
++  }
++  return res;
++};
++
++function Point(curve, x, y, isRed) {
++  Base.BasePoint.call(this, curve, 'affine');
++  if (x === null && y === null) {
++    this.x = null;
++    this.y = null;
++    this.inf = true;
++  } else {
++    this.x = new BN(x, 16);
++    this.y = new BN(y, 16);
++    // Force redgomery representation when loading from JSON
++    if (isRed) {
++      this.x.forceRed(this.curve.red);
++      this.y.forceRed(this.curve.red);
++    }
++    if (!this.x.red)
++      this.x = this.x.toRed(this.curve.red);
++    if (!this.y.red)
++      this.y = this.y.toRed(this.curve.red);
++    this.inf = false;
++  }
++}
++inherits(Point, Base.BasePoint);
++
++ShortCurve.prototype.point = function point(x, y, isRed) {
++  return new Point(this, x, y, isRed);
++};
++
++ShortCurve.prototype.pointFromJSON = function pointFromJSON(obj, red) {
++  return Point.fromJSON(this, obj, red);
++};
++
++Point.prototype._getBeta = function _getBeta() {
++  if (!this.curve.endo)
++    return;
++
++  var pre = this.precomputed;
++  if (pre && pre.beta)
++    return pre.beta;
++
++  var beta = this.curve.point(this.x.redMul(this.curve.endo.beta), this.y);
++  if (pre) {
++    var curve = this.curve;
++    var endoMul = function(p) {
++      return curve.point(p.x.redMul(curve.endo.beta), p.y);
++    };
++    pre.beta = beta;
++    beta.precomputed = {
++      beta: null,
++      naf: pre.naf && {
++        wnd: pre.naf.wnd,
++        points: pre.naf.points.map(endoMul)
++      },
++      doubles: pre.doubles && {
++        step: pre.doubles.step,
++        points: pre.doubles.points.map(endoMul)
++      }
++    };
++  }
++  return beta;
++};
++
++Point.prototype.toJSON = function toJSON() {
++  if (!this.precomputed)
++    return [ this.x, this.y ];
++
++  return [ this.x, this.y, this.precomputed && {
++    doubles: this.precomputed.doubles && {
++      step: this.precomputed.doubles.step,
++      points: this.precomputed.doubles.points.slice(1)
++    },
++    naf: this.precomputed.naf && {
++      wnd: this.precomputed.naf.wnd,
++      points: this.precomputed.naf.points.slice(1)
++    }
++  } ];
++};
++
++Point.fromJSON = function fromJSON(curve, obj, red) {
++  if (typeof obj === 'string')
++    obj = JSON.parse(obj);
++  var res = curve.point(obj[0], obj[1], red);
++  if (!obj[2])
++    return res;
++
++  function obj2point(obj) {
++    return curve.point(obj[0], obj[1], red);
++  }
++
++  var pre = obj[2];
++  res.precomputed = {
++    beta: null,
++    doubles: pre.doubles && {
++      step: pre.doubles.step,
++      points: [ res ].concat(pre.doubles.points.map(obj2point))
++    },
++    naf: pre.naf && {
++      wnd: pre.naf.wnd,
++      points: [ res ].concat(pre.naf.points.map(obj2point))
++    }
++  };
++  return res;
++};
++
++Point.prototype.inspect = function inspect() {
++  if (this.isInfinity())
++    return '<EC Point Infinity>';
++  return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
++      ' y: ' + this.y.fromRed().toString(16, 2) + '>';
++};
++
++Point.prototype.isInfinity = function isInfinity() {
++  return this.inf;
++};
++
++Point.prototype.add = function add(p) {
++  // O + P = P
++  if (this.inf)
++    return p;
++
++  // P + O = P
++  if (p.inf)
++    return this;
++
++  // P + P = 2P
++  if (this.eq(p))
++    return this.dbl();
++
++  // P + (-P) = O
++  if (this.neg().eq(p))
++    return this.curve.point(null, null);
++
++  // P + Q = O
++  if (this.x.cmp(p.x) === 0)
++    return this.curve.point(null, null);
++
++  var c = this.y.redSub(p.y);
++  if (c.cmpn(0) !== 0)
++    c = c.redMul(this.x.redSub(p.x).redInvm());
++  var nx = c.redSqr().redISub(this.x).redISub(p.x);
++  var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
++  return this.curve.point(nx, ny);
++};
++
++Point.prototype.dbl = function dbl() {
++  if (this.inf)
++    return this;
++
++  // 2P = O
++  var ys1 = this.y.redAdd(this.y);
++  if (ys1.cmpn(0) === 0)
++    return this.curve.point(null, null);
++
++  var a = this.curve.a;
++
++  var x2 = this.x.redSqr();
++  var dyinv = ys1.redInvm();
++  var c = x2.redAdd(x2).redIAdd(x2).redIAdd(a).redMul(dyinv);
++
++  var nx = c.redSqr().redISub(this.x.redAdd(this.x));
++  var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
++  return this.curve.point(nx, ny);
++};
++
++Point.prototype.getX = function getX() {
++  return this.x.fromRed();
++};
++
++Point.prototype.getY = function getY() {
++  return this.y.fromRed();
++};
++
++Point.prototype.mul = function mul(k) {
++  k = new BN(k, 16);
++
++  if (this._hasDoubles(k))
++    return this.curve._fixedNafMul(this, k);
++  else if (this.curve.endo)
++    return this.curve._endoWnafMulAdd([ this ], [ k ]);
++  else
++    return this.curve._wnafMul(this, k);
++};
++
++Point.prototype.mulAdd = function mulAdd(k1, p2, k2) {
++  var points = [ this, p2 ];
++  var coeffs = [ k1, k2 ];
++  if (this.curve.endo)
++    return this.curve._endoWnafMulAdd(points, coeffs);
++  else
++    return this.curve._wnafMulAdd(1, points, coeffs, 2);
++};
++
++Point.prototype.jmulAdd = function jmulAdd(k1, p2, k2) {
++  var points = [ this, p2 ];
++  var coeffs = [ k1, k2 ];
++  if (this.curve.endo)
++    return this.curve._endoWnafMulAdd(points, coeffs, true);
++  else
++    return this.curve._wnafMulAdd(1, points, coeffs, 2, true);
++};
++
++Point.prototype.eq = function eq(p) {
++  return this === p ||
++         this.inf === p.inf &&
++             (this.inf || this.x.cmp(p.x) === 0 && this.y.cmp(p.y) === 0);
++};
++
++Point.prototype.neg = function neg(_precompute) {
++  if (this.inf)
++    return this;
++
++  var res = this.curve.point(this.x, this.y.redNeg());
++  if (_precompute && this.precomputed) {
++    var pre = this.precomputed;
++    var negate = function(p) {
++      return p.neg();
++    };
++    res.precomputed = {
++      naf: pre.naf && {
++        wnd: pre.naf.wnd,
++        points: pre.naf.points.map(negate)
++      },
++      doubles: pre.doubles && {
++        step: pre.doubles.step,
++        points: pre.doubles.points.map(negate)
++      }
++    };
++  }
++  return res;
++};
++
++Point.prototype.toJ = function toJ() {
++  if (this.inf)
++    return this.curve.jpoint(null, null, null);
++
++  var res = this.curve.jpoint(this.x, this.y, this.curve.one);
++  return res;
++};
++
++function JPoint(curve, x, y, z) {
++  Base.BasePoint.call(this, curve, 'jacobian');
++  if (x === null && y === null && z === null) {
++    this.x = this.curve.one;
++    this.y = this.curve.one;
++    this.z = new BN(0);
++  } else {
++    this.x = new BN(x, 16);
++    this.y = new BN(y, 16);
++    this.z = new BN(z, 16);
++  }
++  if (!this.x.red)
++    this.x = this.x.toRed(this.curve.red);
++  if (!this.y.red)
++    this.y = this.y.toRed(this.curve.red);
++  if (!this.z.red)
++    this.z = this.z.toRed(this.curve.red);
++
++  this.zOne = this.z === this.curve.one;
++}
++inherits(JPoint, Base.BasePoint);
++
++ShortCurve.prototype.jpoint = function jpoint(x, y, z) {
++  return new JPoint(this, x, y, z);
++};
++
++JPoint.prototype.toP = function toP() {
++  if (this.isInfinity())
++    return this.curve.point(null, null);
++
++  var zinv = this.z.redInvm();
++  var zinv2 = zinv.redSqr();
++  var ax = this.x.redMul(zinv2);
++  var ay = this.y.redMul(zinv2).redMul(zinv);
++
++  return this.curve.point(ax, ay);
++};
++
++JPoint.prototype.neg = function neg() {
++  return this.curve.jpoint(this.x, this.y.redNeg(), this.z);
++};
++
++JPoint.prototype.add = function add(p) {
++  // O + P = P
++  if (this.isInfinity())
++    return p;
++
++  // P + O = P
++  if (p.isInfinity())
++    return this;
++
++  // 12M + 4S + 7A
++  var pz2 = p.z.redSqr();
++  var z2 = this.z.redSqr();
++  var u1 = this.x.redMul(pz2);
++  var u2 = p.x.redMul(z2);
++  var s1 = this.y.redMul(pz2.redMul(p.z));
++  var s2 = p.y.redMul(z2.redMul(this.z));
++
++  var h = u1.redSub(u2);
++  var r = s1.redSub(s2);
++  if (h.cmpn(0) === 0) {
++    if (r.cmpn(0) !== 0)
++      return this.curve.jpoint(null, null, null);
++    else
++      return this.dbl();
++  }
++
++  var h2 = h.redSqr();
++  var h3 = h2.redMul(h);
++  var v = u1.redMul(h2);
++
++  var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);
++  var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));
++  var nz = this.z.redMul(p.z).redMul(h);
++
++  return this.curve.jpoint(nx, ny, nz);
++};
++
++JPoint.prototype.mixedAdd = function mixedAdd(p) {
++  // O + P = P
++  if (this.isInfinity())
++    return p.toJ();
++
++  // P + O = P
++  if (p.isInfinity())
++    return this;
++
++  // 8M + 3S + 7A
++  var z2 = this.z.redSqr();
++  var u1 = this.x;
++  var u2 = p.x.redMul(z2);
++  var s1 = this.y;
++  var s2 = p.y.redMul(z2).redMul(this.z);
++
++  var h = u1.redSub(u2);
++  var r = s1.redSub(s2);
++  if (h.cmpn(0) === 0) {
++    if (r.cmpn(0) !== 0)
++      return this.curve.jpoint(null, null, null);
++    else
++      return this.dbl();
++  }
++
++  var h2 = h.redSqr();
++  var h3 = h2.redMul(h);
++  var v = u1.redMul(h2);
++
++  var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);
++  var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));
++  var nz = this.z.redMul(h);
++
++  return this.curve.jpoint(nx, ny, nz);
++};
++
++JPoint.prototype.dblp = function dblp(pow) {
++  if (pow === 0)
++    return this;
++  if (this.isInfinity())
++    return this;
++  if (!pow)
++    return this.dbl();
++
++  if (this.curve.zeroA || this.curve.threeA) {
++    var r = this;
++    for (var i = 0; i < pow; i++)
++      r = r.dbl();
++    return r;
++  }
++
++  // 1M + 2S + 1A + N * (4S + 5M + 8A)
++  // N = 1 => 6M + 6S + 9A
++  var a = this.curve.a;
++  var tinv = this.curve.tinv;
++
++  var jx = this.x;
++  var jy = this.y;
++  var jz = this.z;
++  var jz4 = jz.redSqr().redSqr();
++
++  // Reuse results
++  var jyd = jy.redAdd(jy);
++  for (var i = 0; i < pow; i++) {
++    var jx2 = jx.redSqr();
++    var jyd2 = jyd.redSqr();
++    var jyd4 = jyd2.redSqr();
++    var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));
++
++    var t1 = jx.redMul(jyd2);
++    var nx = c.redSqr().redISub(t1.redAdd(t1));
++    var t2 = t1.redISub(nx);
++    var dny = c.redMul(t2);
++    dny = dny.redIAdd(dny).redISub(jyd4);
++    var nz = jyd.redMul(jz);
++    if (i + 1 < pow)
++      jz4 = jz4.redMul(jyd4);
++
++    jx = nx;
++    jz = nz;
++    jyd = dny;
++  }
++
++  return this.curve.jpoint(jx, jyd.redMul(tinv), jz);
++};
++
++JPoint.prototype.dbl = function dbl() {
++  if (this.isInfinity())
++    return this;
++
++  if (this.curve.zeroA)
++    return this._zeroDbl();
++  else if (this.curve.threeA)
++    return this._threeDbl();
++  else
++    return this._dbl();
++};
++
++JPoint.prototype._zeroDbl = function _zeroDbl() {
++  var nx;
++  var ny;
++  var nz;
++  // Z = 1
++  if (this.zOne) {
++    // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
++    //     #doubling-mdbl-2007-bl
++    // 1M + 5S + 14A
++
++    // XX = X1^2
++    var xx = this.x.redSqr();
++    // YY = Y1^2
++    var yy = this.y.redSqr();
++    // YYYY = YY^2
++    var yyyy = yy.redSqr();
++    // S = 2 * ((X1 + YY)^2 - XX - YYYY)
++    var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
++    s = s.redIAdd(s);
++    // M = 3 * XX + a; a = 0
++    var m = xx.redAdd(xx).redIAdd(xx);
++    // T = M ^ 2 - 2*S
++    var t = m.redSqr().redISub(s).redISub(s);
++
++    // 8 * YYYY
++    var yyyy8 = yyyy.redIAdd(yyyy);
++    yyyy8 = yyyy8.redIAdd(yyyy8);
++    yyyy8 = yyyy8.redIAdd(yyyy8);
++
++    // X3 = T
++    nx = t;
++    // Y3 = M * (S - T) - 8 * YYYY
++    ny = m.redMul(s.redISub(t)).redISub(yyyy8);
++    // Z3 = 2*Y1
++    nz = this.y.redAdd(this.y);
++  } else {
++    // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
++    //     #doubling-dbl-2009-l
++    // 2M + 5S + 13A
++
++    // A = X1^2
++    var a = this.x.redSqr();
++    // B = Y1^2
++    var b = this.y.redSqr();
++    // C = B^2
++    var c = b.redSqr();
++    // D = 2 * ((X1 + B)^2 - A - C)
++    var d = this.x.redAdd(b).redSqr().redISub(a).redISub(c);
++    d = d.redIAdd(d);
++    // E = 3 * A
++    var e = a.redAdd(a).redIAdd(a);
++    // F = E^2
++    var f = e.redSqr();
++
++    // 8 * C
++    var c8 = c.redIAdd(c);
++    c8 = c8.redIAdd(c8);
++    c8 = c8.redIAdd(c8);
++
++    // X3 = F - 2 * D
++    nx = f.redISub(d).redISub(d);
++    // Y3 = E * (D - X3) - 8 * C
++    ny = e.redMul(d.redISub(nx)).redISub(c8);
++    // Z3 = 2 * Y1 * Z1
++    nz = this.y.redMul(this.z);
++    nz = nz.redIAdd(nz);
++  }
++
++  return this.curve.jpoint(nx, ny, nz);
++};
++
++JPoint.prototype._threeDbl = function _threeDbl() {
++  var nx;
++  var ny;
++  var nz;
++  // Z = 1
++  if (this.zOne) {
++    // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html
++    //     #doubling-mdbl-2007-bl
++    // 1M + 5S + 15A
++
++    // XX = X1^2
++    var xx = this.x.redSqr();
++    // YY = Y1^2
++    var yy = this.y.redSqr();
++    // YYYY = YY^2
++    var yyyy = yy.redSqr();
++    // S = 2 * ((X1 + YY)^2 - XX - YYYY)
++    var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
++    s = s.redIAdd(s);
++    // M = 3 * XX + a
++    var m = xx.redAdd(xx).redIAdd(xx).redIAdd(this.curve.a);
++    // T = M^2 - 2 * S
++    var t = m.redSqr().redISub(s).redISub(s);
++    // X3 = T
++    nx = t;
++    // Y3 = M * (S - T) - 8 * YYYY
++    var yyyy8 = yyyy.redIAdd(yyyy);
++    yyyy8 = yyyy8.redIAdd(yyyy8);
++    yyyy8 = yyyy8.redIAdd(yyyy8);
++    ny = m.redMul(s.redISub(t)).redISub(yyyy8);
++    // Z3 = 2 * Y1
++    nz = this.y.redAdd(this.y);
++  } else {
++    // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
++    // 3M + 5S
++
++    // delta = Z1^2
++    var delta = this.z.redSqr();
++    // gamma = Y1^2
++    var gamma = this.y.redSqr();
++    // beta = X1 * gamma
++    var beta = this.x.redMul(gamma);
++    // alpha = 3 * (X1 - delta) * (X1 + delta)
++    var alpha = this.x.redSub(delta).redMul(this.x.redAdd(delta));
++    alpha = alpha.redAdd(alpha).redIAdd(alpha);
++    // X3 = alpha^2 - 8 * beta
++    var beta4 = beta.redIAdd(beta);
++    beta4 = beta4.redIAdd(beta4);
++    var beta8 = beta4.redAdd(beta4);
++    nx = alpha.redSqr().redISub(beta8);
++    // Z3 = (Y1 + Z1)^2 - gamma - delta
++    nz = this.y.redAdd(this.z).redSqr().redISub(gamma).redISub(delta);
++    // Y3 = alpha * (4 * beta - X3) - 8 * gamma^2
++    var ggamma8 = gamma.redSqr();
++    ggamma8 = ggamma8.redIAdd(ggamma8);
++    ggamma8 = ggamma8.redIAdd(ggamma8);
++    ggamma8 = ggamma8.redIAdd(ggamma8);
++    ny = alpha.redMul(beta4.redISub(nx)).redISub(ggamma8);
++  }
++
++  return this.curve.jpoint(nx, ny, nz);
++};
++
++JPoint.prototype._dbl = function _dbl() {
++  var a = this.curve.a;
++
++  // 4M + 6S + 10A
++  var jx = this.x;
++  var jy = this.y;
++  var jz = this.z;
++  var jz4 = jz.redSqr().redSqr();
++
++  var jx2 = jx.redSqr();
++  var jy2 = jy.redSqr();
++
++  var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));
++
++  var jxd4 = jx.redAdd(jx);
++  jxd4 = jxd4.redIAdd(jxd4);
++  var t1 = jxd4.redMul(jy2);
++  var nx = c.redSqr().redISub(t1.redAdd(t1));
++  var t2 = t1.redISub(nx);
++
++  var jyd8 = jy2.redSqr();
++  jyd8 = jyd8.redIAdd(jyd8);
++  jyd8 = jyd8.redIAdd(jyd8);
++  jyd8 = jyd8.redIAdd(jyd8);
++  var ny = c.redMul(t2).redISub(jyd8);
++  var nz = jy.redAdd(jy).redMul(jz);
++
++  return this.curve.jpoint(nx, ny, nz);
++};
++
++JPoint.prototype.trpl = function trpl() {
++  if (!this.curve.zeroA)
++    return this.dbl().add(this);
++
++  // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#tripling-tpl-2007-bl
++  // 5M + 10S + ...
++
++  // XX = X1^2
++  var xx = this.x.redSqr();
++  // YY = Y1^2
++  var yy = this.y.redSqr();
++  // ZZ = Z1^2
++  var zz = this.z.redSqr();
++  // YYYY = YY^2
++  var yyyy = yy.redSqr();
++  // M = 3 * XX + a * ZZ2; a = 0
++  var m = xx.redAdd(xx).redIAdd(xx);
++  // MM = M^2
++  var mm = m.redSqr();
++  // E = 6 * ((X1 + YY)^2 - XX - YYYY) - MM
++  var e = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
++  e = e.redIAdd(e);
++  e = e.redAdd(e).redIAdd(e);
++  e = e.redISub(mm);
++  // EE = E^2
++  var ee = e.redSqr();
++  // T = 16*YYYY
++  var t = yyyy.redIAdd(yyyy);
++  t = t.redIAdd(t);
++  t = t.redIAdd(t);
++  t = t.redIAdd(t);
++  // U = (M + E)^2 - MM - EE - T
++  var u = m.redIAdd(e).redSqr().redISub(mm).redISub(ee).redISub(t);
++  // X3 = 4 * (X1 * EE - 4 * YY * U)
++  var yyu4 = yy.redMul(u);
++  yyu4 = yyu4.redIAdd(yyu4);
++  yyu4 = yyu4.redIAdd(yyu4);
++  var nx = this.x.redMul(ee).redISub(yyu4);
++  nx = nx.redIAdd(nx);
++  nx = nx.redIAdd(nx);
++  // Y3 = 8 * Y1 * (U * (T - U) - E * EE)
++  var ny = this.y.redMul(u.redMul(t.redISub(u)).redISub(e.redMul(ee)));
++  ny = ny.redIAdd(ny);
++  ny = ny.redIAdd(ny);
++  ny = ny.redIAdd(ny);
++  // Z3 = (Z1 + E)^2 - ZZ - EE
++  var nz = this.z.redAdd(e).redSqr().redISub(zz).redISub(ee);
++
++  return this.curve.jpoint(nx, ny, nz);
++};
++
++JPoint.prototype.mul = function mul(k, kbase) {
++  k = new BN(k, kbase);
++
++  return this.curve._wnafMul(this, k);
++};
++
++JPoint.prototype.eq = function eq(p) {
++  if (p.type === 'affine')
++    return this.eq(p.toJ());
++
++  if (this === p)
++    return true;
++
++  // x1 * z2^2 == x2 * z1^2
++  var z2 = this.z.redSqr();
++  var pz2 = p.z.redSqr();
++  if (this.x.redMul(pz2).redISub(p.x.redMul(z2)).cmpn(0) !== 0)
++    return false;
++
++  // y1 * z2^3 == y2 * z1^3
++  var z3 = z2.redMul(this.z);
++  var pz3 = pz2.redMul(p.z);
++  return this.y.redMul(pz3).redISub(p.y.redMul(z3)).cmpn(0) === 0;
++};
++
++JPoint.prototype.eqXToP = function eqXToP(x) {
++  var zs = this.z.redSqr();
++  var rx = x.toRed(this.curve.red).redMul(zs);
++  if (this.x.cmp(rx) === 0)
++    return true;
++
++  var xc = x.clone();
++  var t = this.curve.redN.redMul(zs);
++  for (;;) {
++    xc.iadd(this.curve.n);
++    if (xc.cmp(this.curve.p) >= 0)
++      return false;
++
++    rx.redIAdd(t);
++    if (this.x.cmp(rx) === 0)
++      return true;
++  }
++  return false;
++};
++
++JPoint.prototype.inspect = function inspect() {
++  if (this.isInfinity())
++    return '<EC JPoint Infinity>';
++  return '<EC JPoint x: ' + this.x.toString(16, 2) +
++      ' y: ' + this.y.toString(16, 2) +
++      ' z: ' + this.z.toString(16, 2) + '>';
++};
++
++JPoint.prototype.isInfinity = function isInfinity() {
++  // XXX This code assumes that zero is always zero in red
++  return this.z.cmpn(0) === 0;
++};
++
++},{"../../elliptic":2,"../curve":5,"bn.js":1,"inherits":25}],8:[function(require,module,exports){
++'use strict';
++
++var curves = exports;
++
++var hash = require('hash.js');
++var elliptic = require('../elliptic');
++
++var assert = elliptic.utils.assert;
++
++function PresetCurve(options) {
++  if (options.type === 'short')
++    this.curve = new elliptic.curve.short(options);
++  else if (options.type === 'edwards')
++    this.curve = new elliptic.curve.edwards(options);
++  else
++    this.curve = new elliptic.curve.mont(options);
++  this.g = this.curve.g;
++  this.n = this.curve.n;
++  this.hash = options.hash;
++
++  assert(this.g.validate(), 'Invalid curve');
++  assert(this.g.mul(this.n).isInfinity(), 'Invalid curve, G*N != O');
++}
++curves.PresetCurve = PresetCurve;
++
++function defineCurve(name, options) {
++  Object.defineProperty(curves, name, {
++    configurable: true,
++    enumerable: true,
++    get: function() {
++      var curve = new PresetCurve(options);
++      Object.defineProperty(curves, name, {
++        configurable: true,
++        enumerable: true,
++        value: curve
++      });
++      return curve;
++    }
++  });
++}
++
++defineCurve('p192', {
++  type: 'short',
++  prime: 'p192',
++  p: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff',
++  a: 'ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc',
++  b: '64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1',
++  n: 'ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831',
++  hash: hash.sha256,
++  gRed: false,
++  g: [
++    '188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012',
++    '07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811'
++  ]
++});
++
++defineCurve('p224', {
++  type: 'short',
++  prime: 'p224',
++  p: 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001',
++  a: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe',
++  b: 'b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4',
++  n: 'ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d',
++  hash: hash.sha256,
++  gRed: false,
++  g: [
++    'b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21',
++    'bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34'
++  ]
++});
++
++defineCurve('p256', {
++  type: 'short',
++  prime: null,
++  p: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff',
++  a: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc',
++  b: '5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b',
++  n: 'ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551',
++  hash: hash.sha256,
++  gRed: false,
++  g: [
++    '6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296',
++    '4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5'
++  ]
++});
++
++defineCurve('p384', {
++  type: 'short',
++  prime: null,
++  p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
++     'fffffffe ffffffff 00000000 00000000 ffffffff',
++  a: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
++     'fffffffe ffffffff 00000000 00000000 fffffffc',
++  b: 'b3312fa7 e23ee7e4 988e056b e3f82d19 181d9c6e fe814112 0314088f ' +
++     '5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef',
++  n: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff c7634d81 ' +
++     'f4372ddf 581a0db2 48b0a77a ecec196a ccc52973',
++  hash: hash.sha384,
++  gRed: false,
++  g: [
++    'aa87ca22 be8b0537 8eb1c71e f320ad74 6e1d3b62 8ba79b98 59f741e0 82542a38 ' +
++    '5502f25d bf55296c 3a545e38 72760ab7',
++    '3617de4a 96262c6f 5d9e98bf 9292dc29 f8f41dbd 289a147c e9da3113 b5f0b8c0 ' +
++    '0a60b1ce 1d7e819d 7a431d7c 90ea0e5f'
++  ]
++});
++
++defineCurve('p521', {
++  type: 'short',
++  prime: null,
++  p: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
++     'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
++     'ffffffff ffffffff ffffffff ffffffff ffffffff',
++  a: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
++     'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
++     'ffffffff ffffffff ffffffff ffffffff fffffffc',
++  b: '00000051 953eb961 8e1c9a1f 929a21a0 b68540ee a2da725b ' +
++     '99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd ' +
++     '3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00',
++  n: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
++     'ffffffff ffffffff fffffffa 51868783 bf2f966b 7fcc0148 ' +
++     'f709a5d0 3bb5c9b8 899c47ae bb6fb71e 91386409',
++  hash: hash.sha512,
++  gRed: false,
++  g: [
++    '000000c6 858e06b7 0404e9cd 9e3ecb66 2395b442 9c648139 ' +
++    '053fb521 f828af60 6b4d3dba a14b5e77 efe75928 fe1dc127 ' +
++    'a2ffa8de 3348b3c1 856a429b f97e7e31 c2e5bd66',
++    '00000118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9 98f54449 ' +
++    '579b4468 17afbd17 273e662c 97ee7299 5ef42640 c550b901 ' +
++    '3fad0761 353c7086 a272c240 88be9476 9fd16650'
++  ]
++});
++
++defineCurve('curve25519', {
++  type: 'mont',
++  prime: 'p25519',
++  p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',
++  a: '76d06',
++  b: '0',
++  n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',
++  hash: hash.sha256,
++  gRed: false,
++  g: [
++    '9'
++  ]
++});
++
++defineCurve('ed25519', {
++  type: 'edwards',
++  prime: 'p25519',
++  p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',
++  a: '-1',
++  c: '1',
++  // -121665 * (121666^(-1)) (mod P)
++  d: '52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3',
++  n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',
++  hash: hash.sha256,
++  gRed: false,
++  g: [
++    '216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a',
++
++    // 4/5
++    '6666666666666666666666666666666666666666666666666666666666666658'
++  ]
++});
++
++var pre;
++try {
++  pre = require('./precomputed/secp256k1');
++} catch (e) {
++  pre = undefined;
++}
++
++defineCurve('secp256k1', {
++  type: 'short',
++  prime: 'k256',
++  p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f',
++  a: '0',
++  b: '7',
++  n: 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141',
++  h: '1',
++  hash: hash.sha256,
++
++  // Precomputed endomorphism
++  beta: '7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee',
++  lambda: '5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72',
++  basis: [
++    {
++      a: '3086d221a7d46bcde86c90e49284eb15',
++      b: '-e4437ed6010e88286f547fa90abfe4c3'
++    },
++    {
++      a: '114ca50f7a8e2f3f657c1108d9d44cfd8',
++      b: '3086d221a7d46bcde86c90e49284eb15'
++    }
++  ],
++
++  gRed: false,
++  g: [
++    '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
++    '483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8',
++    pre
++  ]
++});
++
++},{"../elliptic":2,"./precomputed/secp256k1":16,"hash.js":19}],9:[function(require,module,exports){
++'use strict';
++
++var BN = require('bn.js');
++var elliptic = require('../../elliptic');
++var utils = elliptic.utils;
++var assert = utils.assert;
++
++var KeyPair = require('./key');
++var Signature = require('./signature');
++
++function EC(options) {
++  if (!(this instanceof EC))
++    return new EC(options);
++
++  // Shortcut `elliptic.ec(curve-name)`
++  if (typeof options === 'string') {
++    assert(elliptic.curves.hasOwnProperty(options), 'Unknown curve ' + options);
++
++    options = elliptic.curves[options];
++  }
++
++  // Shortcut for `elliptic.ec(elliptic.curves.curveName)`
++  if (options instanceof elliptic.curves.PresetCurve)
++    options = { curve: options };
++
++  this.curve = options.curve.curve;
++  this.n = this.curve.n;
++  this.nh = this.n.ushrn(1);
++  this.g = this.curve.g;
++
++  // Point on curve
++  this.g = options.curve.g;
++  this.g.precompute(options.curve.n.bitLength() + 1);
++
++  // Hash for function for DRBG
++  this.hash = options.hash || options.curve.hash;
++}
++module.exports = EC;
++
++EC.prototype.keyPair = function keyPair(options) {
++  return new KeyPair(this, options);
++};
++
++EC.prototype.keyFromPrivate = function keyFromPrivate(priv, enc) {
++  return KeyPair.fromPrivate(this, priv, enc);
++};
++
++EC.prototype.keyFromPublic = function keyFromPublic(pub, enc) {
++  return KeyPair.fromPublic(this, pub, enc);
++};
++
++EC.prototype.genKeyPair = function genKeyPair(options) {
++  if (!options)
++    options = {};
++
++  // Instantiate Hmac_DRBG
++  var drbg = new elliptic.hmacDRBG({
++    hash: this.hash,
++    pers: options.pers,
++    entropy: options.entropy || elliptic.rand(this.hash.hmacStrength),
++    nonce: this.n.toArray()
++  });
++
++  var bytes = this.n.byteLength();
++  var ns2 = this.n.sub(new BN(2));
++  do {
++    var priv = new BN(drbg.generate(bytes));
++    if (priv.cmp(ns2) > 0)
++      continue;
++
++    priv.iaddn(1);
++    return this.keyFromPrivate(priv);
++  } while (true);
++};
++
++EC.prototype._truncateToN = function truncateToN(msg, truncOnly) {
++  var delta = msg.byteLength() * 8 - this.n.bitLength();
++  if (delta > 0)
++    msg = msg.ushrn(delta);
++  if (!truncOnly && msg.cmp(this.n) >= 0)
++    return msg.sub(this.n);
++  else
++    return msg;
++};
++
++EC.prototype.sign = function sign(msg, key, enc, options) {
++  if (typeof enc === 'object') {
++    options = enc;
++    enc = null;
++  }
++  if (!options)
++    options = {};
++
++  key = this.keyFromPrivate(key, enc);
++  msg = this._truncateToN(new BN(msg, 16));
++
++  // Zero-extend key to provide enough entropy
++  var bytes = this.n.byteLength();
++  var bkey = key.getPrivate().toArray('be', bytes);
++
++  // Zero-extend nonce to have the same byte size as N
++  var nonce = msg.toArray('be', bytes);
++
++  // Instantiate Hmac_DRBG
++  var drbg = new elliptic.hmacDRBG({
++    hash: this.hash,
++    entropy: bkey,
++    nonce: nonce,
++    pers: options.pers,
++    persEnc: options.persEnc
++  });
++
++  // Number of bytes to generate
++  var ns1 = this.n.sub(new BN(1));
++
++  for (var iter = 0; true; iter++) {
++    var k = options.k ?
++        options.k(iter) :
++        new BN(drbg.generate(this.n.byteLength()));
++    k = this._truncateToN(k, true);
++    if (k.cmpn(1) <= 0 || k.cmp(ns1) >= 0)
++      continue;
++
++    var kp = this.g.mul(k);
++    if (kp.isInfinity())
++      continue;
++
++    var kpX = kp.getX();
++    var r = kpX.umod(this.n);
++    if (r.cmpn(0) === 0)
++      continue;
++
++    var s = k.invm(this.n).mul(r.mul(key.getPrivate()).iadd(msg));
++    s = s.umod(this.n);
++    if (s.cmpn(0) === 0)
++      continue;
++
++    var recoveryParam = (kp.getY().isOdd() ? 1 : 0) |
++                        (kpX.cmp(r) !== 0 ? 2 : 0);
++
++    // Use complement of `s`, if it is > `n / 2`
++    if (options.canonical && s.cmp(this.nh) > 0) {
++      s = this.n.sub(s);
++      recoveryParam ^= 1;
++    }
++
++    return new Signature({ r: r, s: s, recoveryParam: recoveryParam });
++  }
++};
++
++EC.prototype.verify = function verify(msg, signature, key, enc) {
++  msg = this._truncateToN(new BN(msg, 16));
++  key = this.keyFromPublic(key, enc);
++  signature = new Signature(signature, 'hex');
++
++  // Perform primitive values validation
++  var r = signature.r;
++  var s = signature.s;
++  if (r.cmpn(1) < 0 || r.cmp(this.n) >= 0)
++    return false;
++  if (s.cmpn(1) < 0 || s.cmp(this.n) >= 0)
++    return false;
++
++  // Validate signature
++  var sinv = s.invm(this.n);
++  var u1 = sinv.mul(msg).umod(this.n);
++  var u2 = sinv.mul(r).umod(this.n);
++
++  if (!this.curve._maxwellTrick) {
++    var p = this.g.mulAdd(u1, key.getPublic(), u2);
++    if (p.isInfinity())
++      return false;
++
++    return p.getX().umod(this.n).cmp(r) === 0;
++  }
++
++  // NOTE: Greg Maxwell's trick, inspired by:
++  // https://git.io/vad3K
++
++  var p = this.g.jmulAdd(u1, key.getPublic(), u2);
++  if (p.isInfinity())
++    return false;
++
++  // Compare `p.x` of Jacobian point with `r`,
++  // this will do `p.x == r * p.z^2` instead of multiplying `p.x` by the
++  // inverse of `p.z^2`
++  return p.eqXToP(r);
++};
++
++EC.prototype.recoverPubKey = function(msg, signature, j, enc) {
++  assert((3 & j) === j, 'The recovery param is more than two bits');
++  signature = new Signature(signature, enc);
++
++  var n = this.n;
++  var e = new BN(msg);
++  var r = signature.r;
++  var s = signature.s;
++
++  // A set LSB signifies that the y-coordinate is odd
++  var isYOdd = j & 1;
++  var isSecondKey = j >> 1;
++  if (r.cmp(this.curve.p.umod(this.curve.n)) >= 0 && isSecondKey)
++    throw new Error('Unable to find sencond key candinate');
++
++  // 1.1. Let x = r + jn.
++  if (isSecondKey)
++    r = this.curve.pointFromX(r.add(this.curve.n), isYOdd);
++  else
++    r = this.curve.pointFromX(r, isYOdd);
++
++  var rInv = signature.r.invm(n);
++  var s1 = n.sub(e).mul(rInv).umod(n);
++  var s2 = s.mul(rInv).umod(n);
++
++  // 1.6.1 Compute Q = r^-1 (sR -  eG)
++  //               Q = r^-1 (sR + -eG)
++  return this.g.mulAdd(s1, r, s2);
++};
++
++EC.prototype.getKeyRecoveryParam = function(e, signature, Q, enc) {
++  signature = new Signature(signature, enc);
++  if (signature.recoveryParam !== null)
++    return signature.recoveryParam;
++
++  for (var i = 0; i < 4; i++) {
++    var Qprime;
++    try {
++      Qprime = this.recoverPubKey(e, signature, i);
++    } catch (e) {
++      continue;
++    }
++
++    if (Qprime.eq(Q))
++      return i;
++  }
++  throw new Error('Unable to find valid recovery factor');
++};
++
++},{"../../elliptic":2,"./key":10,"./signature":11,"bn.js":1}],10:[function(require,module,exports){
++'use strict';
++
++var BN = require('bn.js');
++
++function KeyPair(ec, options) {
++  this.ec = ec;
++  this.priv = null;
++  this.pub = null;
++
++  // KeyPair(ec, { priv: ..., pub: ... })
++  if (options.priv)
++    this._importPrivate(options.priv, options.privEnc);
++  if (options.pub)
++    this._importPublic(options.pub, options.pubEnc);
++}
++module.exports = KeyPair;
++
++KeyPair.fromPublic = function fromPublic(ec, pub, enc) {
++  if (pub instanceof KeyPair)
++    return pub;
++
++  return new KeyPair(ec, {
++    pub: pub,
++    pubEnc: enc
++  });
++};
++
++KeyPair.fromPrivate = function fromPrivate(ec, priv, enc) {
++  if (priv instanceof KeyPair)
++    return priv;
++
++  return new KeyPair(ec, {
++    priv: priv,
++    privEnc: enc
++  });
++};
++
++KeyPair.prototype.validate = function validate() {
++  var pub = this.getPublic();
++
++  if (pub.isInfinity())
++    return { result: false, reason: 'Invalid public key' };
++  if (!pub.validate())
++    return { result: false, reason: 'Public key is not a point' };
++  if (!pub.mul(this.ec.curve.n).isInfinity())
++    return { result: false, reason: 'Public key * N != O' };
++
++  return { result: true, reason: null };
++};
++
++KeyPair.prototype.getPublic = function getPublic(compact, enc) {
++  // compact is optional argument
++  if (typeof compact === 'string') {
++    enc = compact;
++    compact = null;
++  }
++
++  if (!this.pub)
++    this.pub = this.ec.g.mul(this.priv);
++
++  if (!enc)
++    return this.pub;
++
++  return this.pub.encode(enc, compact);
++};
++
++KeyPair.prototype.getPrivate = function getPrivate(enc) {
++  if (enc === 'hex')
++    return this.priv.toString(16, 2);
++  else
++    return this.priv;
++};
++
++KeyPair.prototype._importPrivate = function _importPrivate(key, enc) {
++  this.priv = new BN(key, enc || 16);
++
++  // Ensure that the priv won't be bigger than n, otherwise we may fail
++  // in fixed multiplication method
++  this.priv = this.priv.umod(this.ec.curve.n);
++};
++
++KeyPair.prototype._importPublic = function _importPublic(key, enc) {
++  if (key.x || key.y) {
++    this.pub = this.ec.curve.point(key.x, key.y);
++    return;
++  }
++  this.pub = this.ec.curve.decodePoint(key, enc);
++};
++
++// ECDH
++KeyPair.prototype.derive = function derive(pub) {
++  return pub.mul(this.priv).getX();
++};
++
++// ECDSA
++KeyPair.prototype.sign = function sign(msg, enc, options) {
++  return this.ec.sign(msg, this, enc, options);
++};
++
++KeyPair.prototype.verify = function verify(msg, signature) {
++  return this.ec.verify(msg, signature, this);
++};
++
++KeyPair.prototype.inspect = function inspect() {
++  return '<Key priv: ' + (this.priv && this.priv.toString(16, 2)) +
++         ' pub: ' + (this.pub && this.pub.inspect()) + ' >';
++};
++
++},{"bn.js":1}],11:[function(require,module,exports){
++'use strict';
++
++var BN = require('bn.js');
++
++var elliptic = require('../../elliptic');
++var utils = elliptic.utils;
++var assert = utils.assert;
++
++function Signature(options, enc) {
++  if (options instanceof Signature)
++    return options;
++
++  if (this._importDER(options, enc))
++    return;
++
++  assert(options.r && options.s, 'Signature without r or s');
++  this.r = new BN(options.r, 16);
++  this.s = new BN(options.s, 16);
++  if (options.recoveryParam === undefined)
++    this.recoveryParam = null;
++  else
++    this.recoveryParam = options.recoveryParam;
++}
++module.exports = Signature;
++
++function Position() {
++  this.place = 0;
++}
++
++function getLength(buf, p) {
++  var initial = buf[p.place++];
++  if (!(initial & 0x80)) {
++    return initial;
++  }
++  var octetLen = initial & 0xf;
++  var val = 0;
++  for (var i = 0, off = p.place; i < octetLen; i++, off++) {
++    val <<= 8;
++    val |= buf[off];
++  }
++  p.place = off;
++  return val;
++}
++
++function rmPadding(buf) {
++  var i = 0;
++  var len = buf.length - 1;
++  while (!buf[i] && !(buf[i + 1] & 0x80) && i < len) {
++    i++;
++  }
++  if (i === 0) {
++    return buf;
++  }
++  return buf.slice(i);
++}
++
++Signature.prototype._importDER = function _importDER(data, enc) {
++  data = utils.toArray(data, enc);
++  var p = new Position();
++  if (data[p.place++] !== 0x30) {
++    return false;
++  }
++  var len = getLength(data, p);
++  if ((len + p.place) !== data.length) {
++    return false;
++  }
++  if (data[p.place++] !== 0x02) {
++    return false;
++  }
++  var rlen = getLength(data, p);
++  var r = data.slice(p.place, rlen + p.place);
++  p.place += rlen;
++  if (data[p.place++] !== 0x02) {
++    return false;
++  }
++  var slen = getLength(data, p);
++  if (data.length !== slen + p.place) {
++    return false;
++  }
++  var s = data.slice(p.place, slen + p.place);
++  if (r[0] === 0 && (r[1] & 0x80)) {
++    r = r.slice(1);
++  }
++  if (s[0] === 0 && (s[1] & 0x80)) {
++    s = s.slice(1);
++  }
++
++  this.r = new BN(r);
++  this.s = new BN(s);
++  this.recoveryParam = null;
++
++  return true;
++};
++
++function constructLength(arr, len) {
++  if (len < 0x80) {
++    arr.push(len);
++    return;
++  }
++  var octets = 1 + (Math.log(len) / Math.LN2 >>> 3);
++  arr.push(octets | 0x80);
++  while (--octets) {
++    arr.push((len >>> (octets << 3)) & 0xff);
++  }
++  arr.push(len);
++}
++
++Signature.prototype.toDER = function toDER(enc) {
++  var r = this.r.toArray();
++  var s = this.s.toArray();
++
++  // Pad values
++  if (r[0] & 0x80)
++    r = [ 0 ].concat(r);
++  // Pad values
++  if (s[0] & 0x80)
++    s = [ 0 ].concat(s);
++
++  r = rmPadding(r);
++  s = rmPadding(s);
++
++  while (!s[0] && !(s[1] & 0x80)) {
++    s = s.slice(1);
++  }
++  var arr = [ 0x02 ];
++  constructLength(arr, r.length);
++  arr = arr.concat(r);
++  arr.push(0x02);
++  constructLength(arr, s.length);
++  var backHalf = arr.concat(s);
++  var res = [ 0x30 ];
++  constructLength(res, backHalf.length);
++  res = res.concat(backHalf);
++  return utils.encode(res, enc);
++};
++
++},{"../../elliptic":2,"bn.js":1}],12:[function(require,module,exports){
++'use strict';
++
++var hash = require('hash.js');
++var elliptic = require('../../elliptic');
++var utils = elliptic.utils;
++var assert = utils.assert;
++var parseBytes = utils.parseBytes;
++var KeyPair = require('./key');
++var Signature = require('./signature');
++
++function EDDSA(curve) {
++  assert(curve === 'ed25519', 'only tested with ed25519 so far');
++
++  if (!(this instanceof EDDSA))
++    return new EDDSA(curve);
++
++  var curve = elliptic.curves[curve].curve;
++  this.curve = curve;
++  this.g = curve.g;
++  this.g.precompute(curve.n.bitLength() + 1);
++
++  this.pointClass = curve.point().constructor;
++  this.encodingLength = Math.ceil(curve.n.bitLength() / 8);
++  this.hash = hash.sha512;
++}
++
++module.exports = EDDSA;
++
++/**
++* @param {Array|String} message - message bytes
++* @param {Array|String|KeyPair} secret - secret bytes or a keypair
++* @returns {Signature} - signature
++*/
++EDDSA.prototype.sign = function sign(message, secret) {
++  message = parseBytes(message);
++  var key = this.keyFromSecret(secret);
++  var r = this.hashInt(key.messagePrefix(), message);
++  var R = this.g.mul(r);
++  var Rencoded = this.encodePoint(R);
++  var s_ = this.hashInt(Rencoded, key.pubBytes(), message)
++               .mul(key.priv());
++  var S = r.add(s_).umod(this.curve.n);
++  return this.makeSignature({ R: R, S: S, Rencoded: Rencoded });
++};
++
++/**
++* @param {Array} message - message bytes
++* @param {Array|String|Signature} sig - sig bytes
++* @param {Array|String|Point|KeyPair} pub - public key
++* @returns {Boolean} - true if public key matches sig of message
++*/
++EDDSA.prototype.verify = function verify(message, sig, pub) {
++  message = parseBytes(message);
++  sig = this.makeSignature(sig);
++  var key = this.keyFromPublic(pub);
++  var h = this.hashInt(sig.Rencoded(), key.pubBytes(), message);
++  var SG = this.g.mul(sig.S());
++  var RplusAh = sig.R().add(key.pub().mul(h));
++  return RplusAh.eq(SG);
++};
++
++EDDSA.prototype.hashInt = function hashInt() {
++  var hash = this.hash();
++  for (var i = 0; i < arguments.length; i++)
++    hash.update(arguments[i]);
++  return utils.intFromLE(hash.digest()).umod(this.curve.n);
++};
++
++EDDSA.prototype.keyFromPublic = function keyFromPublic(pub) {
++  return KeyPair.fromPublic(this, pub);
++};
++
++EDDSA.prototype.keyFromSecret = function keyFromSecret(secret) {
++  return KeyPair.fromSecret(this, secret);
++};
++
++EDDSA.prototype.makeSignature = function makeSignature(sig) {
++  if (sig instanceof Signature)
++    return sig;
++  return new Signature(this, sig);
++};
++
++/**
++* * https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03#section-5.2
++*
++* EDDSA defines methods for encoding and decoding points and integers. These are
++* helper convenience methods, that pass along to utility functions implied
++* parameters.
++*
++*/
++EDDSA.prototype.encodePoint = function encodePoint(point) {
++  var enc = point.getY().toArray('le', this.encodingLength);
++  enc[this.encodingLength - 1] |= point.getX().isOdd() ? 0x80 : 0;
++  return enc;
++};
++
++EDDSA.prototype.decodePoint = function decodePoint(bytes) {
++  bytes = utils.parseBytes(bytes);
++
++  var lastIx = bytes.length - 1;
++  var normed = bytes.slice(0, lastIx).concat(bytes[lastIx] & ~0x80);
++  var xIsOdd = (bytes[lastIx] & 0x80) !== 0;
++
++  var y = utils.intFromLE(normed);
++  return this.curve.pointFromY(y, xIsOdd);
++};
++
++EDDSA.prototype.encodeInt = function encodeInt(num) {
++  return num.toArray('le', this.encodingLength);
++};
++
++EDDSA.prototype.decodeInt = function decodeInt(bytes) {
++  return utils.intFromLE(bytes);
++};
++
++EDDSA.prototype.isPoint = function isPoint(val) {
++  return val instanceof this.pointClass;
++};
++
++},{"../../elliptic":2,"./key":13,"./signature":14,"hash.js":19}],13:[function(require,module,exports){
++'use strict';
++
++var elliptic = require('../../elliptic');
++var utils = elliptic.utils;
++var assert = utils.assert;
++var parseBytes = utils.parseBytes;
++var cachedProperty = utils.cachedProperty;
++
++/**
++* @param {EDDSA} eddsa - instance
++* @param {Object} params - public/private key parameters
++*
++* @param {Array<Byte>} [params.secret] - secret seed bytes
++* @param {Point} [params.pub] - public key point (aka `A` in eddsa terms)
++* @param {Array<Byte>} [params.pub] - public key point encoded as bytes
++*
++*/
++function KeyPair(eddsa, params) {
++  this.eddsa = eddsa;
++  this._secret = parseBytes(params.secret);
++  if (eddsa.isPoint(params.pub))
++    this._pub = params.pub;
++  else
++    this._pubBytes = parseBytes(params.pub);
++}
++
++KeyPair.fromPublic = function fromPublic(eddsa, pub) {
++  if (pub instanceof KeyPair)
++    return pub;
++  return new KeyPair(eddsa, { pub: pub });
++};
++
++KeyPair.fromSecret = function fromSecret(eddsa, secret) {
++  if (secret instanceof KeyPair)
++    return secret;
++  return new KeyPair(eddsa, { secret: secret });
++};
++
++KeyPair.prototype.secret = function secret() {
++  return this._secret;
++};
++
++cachedProperty(KeyPair, 'pubBytes', function pubBytes() {
++  return this.eddsa.encodePoint(this.pub());
++});
++
++cachedProperty(KeyPair, 'pub', function pub() {
++  if (this._pubBytes)
++    return this.eddsa.decodePoint(this._pubBytes);
++  return this.eddsa.g.mul(this.priv());
++});
++
++cachedProperty(KeyPair, 'privBytes', function privBytes() {
++  var eddsa = this.eddsa;
++  var hash = this.hash();
++  var lastIx = eddsa.encodingLength - 1;
++
++  var a = hash.slice(0, eddsa.encodingLength);
++  a[0] &= 248;
++  a[lastIx] &= 127;
++  a[lastIx] |= 64;
++
++  return a;
++});
++
++cachedProperty(KeyPair, 'priv', function priv() {
++  return this.eddsa.decodeInt(this.privBytes());
++});
++
++cachedProperty(KeyPair, 'hash', function hash() {
++  return this.eddsa.hash().update(this.secret()).digest();
++});
++
++cachedProperty(KeyPair, 'messagePrefix', function messagePrefix() {
++  return this.hash().slice(this.eddsa.encodingLength);
++});
++
++KeyPair.prototype.sign = function sign(message) {
++  assert(this._secret, 'KeyPair can only verify');
++  return this.eddsa.sign(message, this);
++};
++
++KeyPair.prototype.verify = function verify(message, sig) {
++  return this.eddsa.verify(message, sig, this);
++};
++
++KeyPair.prototype.getSecret = function getSecret(enc) {
++  assert(this._secret, 'KeyPair is public only');
++  return utils.encode(this.secret(), enc);
++};
++
++KeyPair.prototype.getPublic = function getPublic(enc) {
++  return utils.encode(this.pubBytes(), enc);
++};
++
++module.exports = KeyPair;
++
++},{"../../elliptic":2}],14:[function(require,module,exports){
++'use strict';
++
++var BN = require('bn.js');
++var elliptic = require('../../elliptic');
++var utils = elliptic.utils;
++var assert = utils.assert;
++var cachedProperty = utils.cachedProperty;
++var parseBytes = utils.parseBytes;
++
++/**
++* @param {EDDSA} eddsa - eddsa instance
++* @param {Array<Bytes>|Object} sig -
++* @param {Array<Bytes>|Point} [sig.R] - R point as Point or bytes
++* @param {Array<Bytes>|bn} [sig.S] - S scalar as bn or bytes
++* @param {Array<Bytes>} [sig.Rencoded] - R point encoded
++* @param {Array<Bytes>} [sig.Sencoded] - S scalar encoded
++*/
++function Signature(eddsa, sig) {
++  this.eddsa = eddsa;
++
++  if (typeof sig !== 'object')
++    sig = parseBytes(sig);
++
++  if (Array.isArray(sig)) {
++    sig = {
++      R: sig.slice(0, eddsa.encodingLength),
++      S: sig.slice(eddsa.encodingLength)
++    };
++  }
++
++  assert(sig.R && sig.S, 'Signature without R or S');
++
++  if (eddsa.isPoint(sig.R))
++    this._R = sig.R;
++  if (sig.S instanceof BN)
++    this._S = sig.S;
++
++  this._Rencoded = Array.isArray(sig.R) ? sig.R : sig.Rencoded;
++  this._Sencoded = Array.isArray(sig.S) ? sig.S : sig.Sencoded;
++}
++
++cachedProperty(Signature, 'S', function S() {
++  return this.eddsa.decodeInt(this.Sencoded());
++});
++
++cachedProperty(Signature, 'R', function R() {
++  return this.eddsa.decodePoint(this.Rencoded());
++});
++
++cachedProperty(Signature, 'Rencoded', function Rencoded() {
++  return this.eddsa.encodePoint(this.R());
++});
++
++cachedProperty(Signature, 'Sencoded', function Sencoded() {
++  return this.eddsa.encodeInt(this.S());
++});
++
++Signature.prototype.toBytes = function toBytes() {
++  return this.Rencoded().concat(this.Sencoded());
++};
++
++Signature.prototype.toHex = function toHex() {
++  return utils.encode(this.toBytes(), 'hex').toUpperCase();
++};
++
++module.exports = Signature;
++
++},{"../../elliptic":2,"bn.js":1}],15:[function(require,module,exports){
++'use strict';
++
++var hash = require('hash.js');
++var elliptic = require('../elliptic');
++var utils = elliptic.utils;
++var assert = utils.assert;
++
++function HmacDRBG(options) {
++  if (!(this instanceof HmacDRBG))
++    return new HmacDRBG(options);
++  this.hash = options.hash;
++  this.predResist = !!options.predResist;
++
++  this.outLen = this.hash.outSize;
++  this.minEntropy = options.minEntropy || this.hash.hmacStrength;
++
++  this.reseed = null;
++  this.reseedInterval = null;
++  this.K = null;
++  this.V = null;
++
++  var entropy = utils.toArray(options.entropy, options.entropyEnc);
++  var nonce = utils.toArray(options.nonce, options.nonceEnc);
++  var pers = utils.toArray(options.pers, options.persEnc);
++  assert(entropy.length >= (this.minEntropy / 8),
++         'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');
++  this._init(entropy, nonce, pers);
++}
++module.exports = HmacDRBG;
++
++HmacDRBG.prototype._init = function init(entropy, nonce, pers) {
++  var seed = entropy.concat(nonce).concat(pers);
++
++  this.K = new Array(this.outLen / 8);
++  this.V = new Array(this.outLen / 8);
++  for (var i = 0; i < this.V.length; i++) {
++    this.K[i] = 0x00;
++    this.V[i] = 0x01;
++  }
++
++  this._update(seed);
++  this.reseed = 1;
++  this.reseedInterval = 0x1000000000000;  // 2^48
++};
++
++HmacDRBG.prototype._hmac = function hmac() {
++  return new hash.hmac(this.hash, this.K);
++};
++
++HmacDRBG.prototype._update = function update(seed) {
++  var kmac = this._hmac()
++                 .update(this.V)
++                 .update([ 0x00 ]);
++  if (seed)
++    kmac = kmac.update(seed);
++  this.K = kmac.digest();
++  this.V = this._hmac().update(this.V).digest();
++  if (!seed)
++    return;
++
++  this.K = this._hmac()
++               .update(this.V)
++               .update([ 0x01 ])
++               .update(seed)
++               .digest();
++  this.V = this._hmac().update(this.V).digest();
++};
++
++HmacDRBG.prototype.reseed = function reseed(entropy, entropyEnc, add, addEnc) {
++  // Optional entropy enc
++  if (typeof entropyEnc !== 'string') {
++    addEnc = add;
++    add = entropyEnc;
++    entropyEnc = null;
++  }
++
++  entropy = utils.toBuffer(entropy, entropyEnc);
++  add = utils.toBuffer(add, addEnc);
++
++  assert(entropy.length >= (this.minEntropy / 8),
++         'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');
++
++  this._update(entropy.concat(add || []));
++  this.reseed = 1;
++};
++
++HmacDRBG.prototype.generate = function generate(len, enc, add, addEnc) {
++  if (this.reseed > this.reseedInterval)
++    throw new Error('Reseed is required');
++
++  // Optional encoding
++  if (typeof enc !== 'string') {
++    addEnc = add;
++    add = enc;
++    enc = null;
++  }
++
++  // Optional additional data
++  if (add) {
++    add = utils.toArray(add, addEnc);
++    this._update(add);
++  }
++
++  var temp = [];
++  while (temp.length < len) {
++    this.V = this._hmac().update(this.V).digest();
++    temp = temp.concat(this.V);
++  }
++
++  var res = temp.slice(0, len);
++  this._update(add);
++  this.reseed++;
++  return utils.encode(res, enc);
++};
++
++},{"../elliptic":2,"hash.js":19}],16:[function(require,module,exports){
++module.exports = {
++  doubles: {
++    step: 4,
++    points: [
++      [
++        'e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a',
++        'f7e3507399e595929db99f34f57937101296891e44d23f0be1f32cce69616821'
++      ],
++      [
++        '8282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508',
++        '11f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf'
++      ],
++      [
++        '175e159f728b865a72f99cc6c6fc846de0b93833fd2222ed73fce5b551e5b739',
++        'd3506e0d9e3c79eba4ef97a51ff71f5eacb5955add24345c6efa6ffee9fed695'
++      ],
++      [
++        '363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640',
++        '4e273adfc732221953b445397f3363145b9a89008199ecb62003c7f3bee9de9'
++      ],
++      [
++        '8b4b5f165df3c2be8c6244b5b745638843e4a781a15bcd1b69f79a55dffdf80c',
++        '4aad0a6f68d308b4b3fbd7813ab0da04f9e336546162ee56b3eff0c65fd4fd36'
++      ],
++      [
++        '723cbaa6e5db996d6bf771c00bd548c7b700dbffa6c0e77bcb6115925232fcda',
++        '96e867b5595cc498a921137488824d6e2660a0653779494801dc069d9eb39f5f'
++      ],
++      [
++        'eebfa4d493bebf98ba5feec812c2d3b50947961237a919839a533eca0e7dd7fa',
++        '5d9a8ca3970ef0f269ee7edaf178089d9ae4cdc3a711f712ddfd4fdae1de8999'
++      ],
++      [
++        '100f44da696e71672791d0a09b7bde459f1215a29b3c03bfefd7835b39a48db0',
++        'cdd9e13192a00b772ec8f3300c090666b7ff4a18ff5195ac0fbd5cd62bc65a09'
++      ],
++      [
++        'e1031be262c7ed1b1dc9227a4a04c017a77f8d4464f3b3852c8acde6e534fd2d',
++        '9d7061928940405e6bb6a4176597535af292dd419e1ced79a44f18f29456a00d'
++      ],
++      [
++        'feea6cae46d55b530ac2839f143bd7ec5cf8b266a41d6af52d5e688d9094696d',
++        'e57c6b6c97dce1bab06e4e12bf3ecd5c981c8957cc41442d3155debf18090088'
++      ],
++      [
++        'da67a91d91049cdcb367be4be6ffca3cfeed657d808583de33fa978bc1ec6cb1',
++        '9bacaa35481642bc41f463f7ec9780e5dec7adc508f740a17e9ea8e27a68be1d'
++      ],
++      [
++        '53904faa0b334cdda6e000935ef22151ec08d0f7bb11069f57545ccc1a37b7c0',
++        '5bc087d0bc80106d88c9eccac20d3c1c13999981e14434699dcb096b022771c8'
++      ],
++      [
++        '8e7bcd0bd35983a7719cca7764ca906779b53a043a9b8bcaeff959f43ad86047',
++        '10b7770b2a3da4b3940310420ca9514579e88e2e47fd68b3ea10047e8460372a'
++      ],
++      [
++        '385eed34c1cdff21e6d0818689b81bde71a7f4f18397e6690a841e1599c43862',
++        '283bebc3e8ea23f56701de19e9ebf4576b304eec2086dc8cc0458fe5542e5453'
++      ],
++      [
++        '6f9d9b803ecf191637c73a4413dfa180fddf84a5947fbc9c606ed86c3fac3a7',
++        '7c80c68e603059ba69b8e2a30e45c4d47ea4dd2f5c281002d86890603a842160'
++      ],
++      [
++        '3322d401243c4e2582a2147c104d6ecbf774d163db0f5e5313b7e0e742d0e6bd',
++        '56e70797e9664ef5bfb019bc4ddaf9b72805f63ea2873af624f3a2e96c28b2a0'
++      ],
++      [
++        '85672c7d2de0b7da2bd1770d89665868741b3f9af7643397721d74d28134ab83',
++        '7c481b9b5b43b2eb6374049bfa62c2e5e77f17fcc5298f44c8e3094f790313a6'
++      ],
++      [
++        '948bf809b1988a46b06c9f1919413b10f9226c60f668832ffd959af60c82a0a',
++        '53a562856dcb6646dc6b74c5d1c3418c6d4dff08c97cd2bed4cb7f88d8c8e589'
++      ],
++      [
++        '6260ce7f461801c34f067ce0f02873a8f1b0e44dfc69752accecd819f38fd8e8',
++        'bc2da82b6fa5b571a7f09049776a1ef7ecd292238051c198c1a84e95b2b4ae17'
++      ],
++      [
++        'e5037de0afc1d8d43d8348414bbf4103043ec8f575bfdc432953cc8d2037fa2d',
++        '4571534baa94d3b5f9f98d09fb990bddbd5f5b03ec481f10e0e5dc841d755bda'
++      ],
++      [
++        'e06372b0f4a207adf5ea905e8f1771b4e7e8dbd1c6a6c5b725866a0ae4fce725',
++        '7a908974bce18cfe12a27bb2ad5a488cd7484a7787104870b27034f94eee31dd'
++      ],
++      [
++        '213c7a715cd5d45358d0bbf9dc0ce02204b10bdde2a3f58540ad6908d0559754',
++        '4b6dad0b5ae462507013ad06245ba190bb4850f5f36a7eeddff2c27534b458f2'
++      ],
++      [
++        '4e7c272a7af4b34e8dbb9352a5419a87e2838c70adc62cddf0cc3a3b08fbd53c',
++        '17749c766c9d0b18e16fd09f6def681b530b9614bff7dd33e0b3941817dcaae6'
++      ],
++      [
++        'fea74e3dbe778b1b10f238ad61686aa5c76e3db2be43057632427e2840fb27b6',
++        '6e0568db9b0b13297cf674deccb6af93126b596b973f7b77701d3db7f23cb96f'
++      ],
++      [
++        '76e64113f677cf0e10a2570d599968d31544e179b760432952c02a4417bdde39',
++        'c90ddf8dee4e95cf577066d70681f0d35e2a33d2b56d2032b4b1752d1901ac01'
++      ],
++      [
++        'c738c56b03b2abe1e8281baa743f8f9a8f7cc643df26cbee3ab150242bcbb891',
++        '893fb578951ad2537f718f2eacbfbbbb82314eef7880cfe917e735d9699a84c3'
++      ],
++      [
++        'd895626548b65b81e264c7637c972877d1d72e5f3a925014372e9f6588f6c14b',
++        'febfaa38f2bc7eae728ec60818c340eb03428d632bb067e179363ed75d7d991f'
++      ],
++      [
++        'b8da94032a957518eb0f6433571e8761ceffc73693e84edd49150a564f676e03',
++        '2804dfa44805a1e4d7c99cc9762808b092cc584d95ff3b511488e4e74efdf6e7'
++      ],
++      [
++        'e80fea14441fb33a7d8adab9475d7fab2019effb5156a792f1a11778e3c0df5d',
++        'eed1de7f638e00771e89768ca3ca94472d155e80af322ea9fcb4291b6ac9ec78'
++      ],
++      [
++        'a301697bdfcd704313ba48e51d567543f2a182031efd6915ddc07bbcc4e16070',
++        '7370f91cfb67e4f5081809fa25d40f9b1735dbf7c0a11a130c0d1a041e177ea1'
++      ],
++      [
++        '90ad85b389d6b936463f9d0512678de208cc330b11307fffab7ac63e3fb04ed4',
++        'e507a3620a38261affdcbd9427222b839aefabe1582894d991d4d48cb6ef150'
++      ],
++      [
++        '8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da',
++        '662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82'
++      ],
++      [
++        'e4f3fb0176af85d65ff99ff9198c36091f48e86503681e3e6686fd5053231e11',
++        '1e63633ad0ef4f1c1661a6d0ea02b7286cc7e74ec951d1c9822c38576feb73bc'
++      ],
++      [
++        '8c00fa9b18ebf331eb961537a45a4266c7034f2f0d4e1d0716fb6eae20eae29e',
++        'efa47267fea521a1a9dc343a3736c974c2fadafa81e36c54e7d2a4c66702414b'
++      ],
++      [
++        'e7a26ce69dd4829f3e10cec0a9e98ed3143d084f308b92c0997fddfc60cb3e41',
++        '2a758e300fa7984b471b006a1aafbb18d0a6b2c0420e83e20e8a9421cf2cfd51'
++      ],
++      [
++        'b6459e0ee3662ec8d23540c223bcbdc571cbcb967d79424f3cf29eb3de6b80ef',
++        '67c876d06f3e06de1dadf16e5661db3c4b3ae6d48e35b2ff30bf0b61a71ba45'
++      ],
++      [
++        'd68a80c8280bb840793234aa118f06231d6f1fc67e73c5a5deda0f5b496943e8',
++        'db8ba9fff4b586d00c4b1f9177b0e28b5b0e7b8f7845295a294c84266b133120'
++      ],
++      [
++        '324aed7df65c804252dc0270907a30b09612aeb973449cea4095980fc28d3d5d',
++        '648a365774b61f2ff130c0c35aec1f4f19213b0c7e332843967224af96ab7c84'
++      ],
++      [
++        '4df9c14919cde61f6d51dfdbe5fee5dceec4143ba8d1ca888e8bd373fd054c96',
++        '35ec51092d8728050974c23a1d85d4b5d506cdc288490192ebac06cad10d5d'
++      ],
++      [
++        '9c3919a84a474870faed8a9c1cc66021523489054d7f0308cbfc99c8ac1f98cd',
++        'ddb84f0f4a4ddd57584f044bf260e641905326f76c64c8e6be7e5e03d4fc599d'
++      ],
++      [
++        '6057170b1dd12fdf8de05f281d8e06bb91e1493a8b91d4cc5a21382120a959e5',
++        '9a1af0b26a6a4807add9a2daf71df262465152bc3ee24c65e899be932385a2a8'
++      ],
++      [
++        'a576df8e23a08411421439a4518da31880cef0fba7d4df12b1a6973eecb94266',
++        '40a6bf20e76640b2c92b97afe58cd82c432e10a7f514d9f3ee8be11ae1b28ec8'
++      ],
++      [
++        '7778a78c28dec3e30a05fe9629de8c38bb30d1f5cf9a3a208f763889be58ad71',
++        '34626d9ab5a5b22ff7098e12f2ff580087b38411ff24ac563b513fc1fd9f43ac'
++      ],
++      [
++        '928955ee637a84463729fd30e7afd2ed5f96274e5ad7e5cb09eda9c06d903ac',
++        'c25621003d3f42a827b78a13093a95eeac3d26efa8a8d83fc5180e935bcd091f'
++      ],
++      [
++        '85d0fef3ec6db109399064f3a0e3b2855645b4a907ad354527aae75163d82751',
++        '1f03648413a38c0be29d496e582cf5663e8751e96877331582c237a24eb1f962'
++      ],
++      [
++        'ff2b0dce97eece97c1c9b6041798b85dfdfb6d8882da20308f5404824526087e',
++        '493d13fef524ba188af4c4dc54d07936c7b7ed6fb90e2ceb2c951e01f0c29907'
++      ],
++      [
++        '827fbbe4b1e880ea9ed2b2e6301b212b57f1ee148cd6dd28780e5e2cf856e241',
++        'c60f9c923c727b0b71bef2c67d1d12687ff7a63186903166d605b68baec293ec'
++      ],
++      [
++        'eaa649f21f51bdbae7be4ae34ce6e5217a58fdce7f47f9aa7f3b58fa2120e2b3',
++        'be3279ed5bbbb03ac69a80f89879aa5a01a6b965f13f7e59d47a5305ba5ad93d'
++      ],
++      [
++        'e4a42d43c5cf169d9391df6decf42ee541b6d8f0c9a137401e23632dda34d24f',
++        '4d9f92e716d1c73526fc99ccfb8ad34ce886eedfa8d8e4f13a7f7131deba9414'
++      ],
++      [
++        '1ec80fef360cbdd954160fadab352b6b92b53576a88fea4947173b9d4300bf19',
++        'aeefe93756b5340d2f3a4958a7abbf5e0146e77f6295a07b671cdc1cc107cefd'
++      ],
++      [
++        '146a778c04670c2f91b00af4680dfa8bce3490717d58ba889ddb5928366642be',
++        'b318e0ec3354028add669827f9d4b2870aaa971d2f7e5ed1d0b297483d83efd0'
++      ],
++      [
++        'fa50c0f61d22e5f07e3acebb1aa07b128d0012209a28b9776d76a8793180eef9',
++        '6b84c6922397eba9b72cd2872281a68a5e683293a57a213b38cd8d7d3f4f2811'
++      ],
++      [
++        'da1d61d0ca721a11b1a5bf6b7d88e8421a288ab5d5bba5220e53d32b5f067ec2',
++        '8157f55a7c99306c79c0766161c91e2966a73899d279b48a655fba0f1ad836f1'
++      ],
++      [
++        'a8e282ff0c9706907215ff98e8fd416615311de0446f1e062a73b0610d064e13',
++        '7f97355b8db81c09abfb7f3c5b2515888b679a3e50dd6bd6cef7c73111f4cc0c'
++      ],
++      [
++        '174a53b9c9a285872d39e56e6913cab15d59b1fa512508c022f382de8319497c',
++        'ccc9dc37abfc9c1657b4155f2c47f9e6646b3a1d8cb9854383da13ac079afa73'
++      ],
++      [
++        '959396981943785c3d3e57edf5018cdbe039e730e4918b3d884fdff09475b7ba',
++        '2e7e552888c331dd8ba0386a4b9cd6849c653f64c8709385e9b8abf87524f2fd'
++      ],
++      [
++        'd2a63a50ae401e56d645a1153b109a8fcca0a43d561fba2dbb51340c9d82b151',
++        'e82d86fb6443fcb7565aee58b2948220a70f750af484ca52d4142174dcf89405'
++      ],
++      [
++        '64587e2335471eb890ee7896d7cfdc866bacbdbd3839317b3436f9b45617e073',
++        'd99fcdd5bf6902e2ae96dd6447c299a185b90a39133aeab358299e5e9faf6589'
++      ],
++      [
++        '8481bde0e4e4d885b3a546d3e549de042f0aa6cea250e7fd358d6c86dd45e458',
++        '38ee7b8cba5404dd84a25bf39cecb2ca900a79c42b262e556d64b1b59779057e'
++      ],
++      [
++        '13464a57a78102aa62b6979ae817f4637ffcfed3c4b1ce30bcd6303f6caf666b',
++        '69be159004614580ef7e433453ccb0ca48f300a81d0942e13f495a907f6ecc27'
++      ],
++      [
++        'bc4a9df5b713fe2e9aef430bcc1dc97a0cd9ccede2f28588cada3a0d2d83f366',
++        'd3a81ca6e785c06383937adf4b798caa6e8a9fbfa547b16d758d666581f33c1'
++      ],
++      [
++        '8c28a97bf8298bc0d23d8c749452a32e694b65e30a9472a3954ab30fe5324caa',
++        '40a30463a3305193378fedf31f7cc0eb7ae784f0451cb9459e71dc73cbef9482'
++      ],
++      [
++        '8ea9666139527a8c1dd94ce4f071fd23c8b350c5a4bb33748c4ba111faccae0',
++        '620efabbc8ee2782e24e7c0cfb95c5d735b783be9cf0f8e955af34a30e62b945'
++      ],
++      [
++        'dd3625faef5ba06074669716bbd3788d89bdde815959968092f76cc4eb9a9787',
++        '7a188fa3520e30d461da2501045731ca941461982883395937f68d00c644a573'
++      ],
++      [
++        'f710d79d9eb962297e4f6232b40e8f7feb2bc63814614d692c12de752408221e',
++        'ea98e67232d3b3295d3b535532115ccac8612c721851617526ae47a9c77bfc82'
++      ]
++    ]
++  },
++  naf: {
++    wnd: 7,
++    points: [
++      [
++        'f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9',
++        '388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672'
++      ],
++      [
++        '2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4',
++        'd8ac222636e5e3d6d4dba9dda6c9c426f788271bab0d6840dca87d3aa6ac62d6'
++      ],
++      [
++        '5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc',
++        '6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da'
++      ],
++      [
++        'acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe',
++        'cc338921b0a7d9fd64380971763b61e9add888a4375f8e0f05cc262ac64f9c37'
++      ],
++      [
++        '774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb',
++        'd984a032eb6b5e190243dd56d7b7b365372db1e2dff9d6a8301d74c9c953c61b'
++      ],
++      [
++        'f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8',
++        'ab0902e8d880a89758212eb65cdaf473a1a06da521fa91f29b5cb52db03ed81'
++      ],
++      [
++        'd7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e',
++        '581e2872a86c72a683842ec228cc6defea40af2bd896d3a5c504dc9ff6a26b58'
++      ],
++      [
++        'defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34',
++        '4211ab0694635168e997b0ead2a93daeced1f4a04a95c0f6cfb199f69e56eb77'
++      ],
++      [
++        '2b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6c',
++        '85e89bc037945d93b343083b5a1c86131a01f60c50269763b570c854e5c09b7a'
++      ],
++      [
++        '352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5',
++        '321eb4075348f534d59c18259dda3e1f4a1b3b2e71b1039c67bd3d8bcf81998c'
++      ],
++      [
++        '2fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f',
++        '2de1068295dd865b64569335bd5dd80181d70ecfc882648423ba76b532b7d67'
++      ],
++      [
++        '9248279b09b4d68dab21a9b066edda83263c3d84e09572e269ca0cd7f5453714',
++        '73016f7bf234aade5d1aa71bdea2b1ff3fc0de2a887912ffe54a32ce97cb3402'
++      ],
++      [
++        'daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729',
++        'a69dce4a7d6c98e8d4a1aca87ef8d7003f83c230f3afa726ab40e52290be1c55'
++      ],
++      [
++        'c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db',
++        '2119a460ce326cdc76c45926c982fdac0e106e861edf61c5a039063f0e0e6482'
++      ],
++      [
++        '6a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4',
++        'e022cf42c2bd4a708b3f5126f16a24ad8b33ba48d0423b6efd5e6348100d8a82'
++      ],
++      [
++        '1697ffa6fd9de627c077e3d2fe541084ce13300b0bec1146f95ae57f0d0bd6a5',
++        'b9c398f186806f5d27561506e4557433a2cf15009e498ae7adee9d63d01b2396'
++      ],
++      [
++        '605bdb019981718b986d0f07e834cb0d9deb8360ffb7f61df982345ef27a7479',
++        '2972d2de4f8d20681a78d93ec96fe23c26bfae84fb14db43b01e1e9056b8c49'
++      ],
++      [
++        '62d14dab4150bf497402fdc45a215e10dcb01c354959b10cfe31c7e9d87ff33d',
++        '80fc06bd8cc5b01098088a1950eed0db01aa132967ab472235f5642483b25eaf'
++      ],
++      [
++        '80c60ad0040f27dade5b4b06c408e56b2c50e9f56b9b8b425e555c2f86308b6f',
++        '1c38303f1cc5c30f26e66bad7fe72f70a65eed4cbe7024eb1aa01f56430bd57a'
++      ],
++      [
++        '7a9375ad6167ad54aa74c6348cc54d344cc5dc9487d847049d5eabb0fa03c8fb',
++        'd0e3fa9eca8726909559e0d79269046bdc59ea10c70ce2b02d499ec224dc7f7'
++      ],
++      [
++        'd528ecd9b696b54c907a9ed045447a79bb408ec39b68df504bb51f459bc3ffc9',
++        'eecf41253136e5f99966f21881fd656ebc4345405c520dbc063465b521409933'
++      ],
++      [
++        '49370a4b5f43412ea25f514e8ecdad05266115e4a7ecb1387231808f8b45963',
++        '758f3f41afd6ed428b3081b0512fd62a54c3f3afbb5b6764b653052a12949c9a'
++      ],
++      [
++        '77f230936ee88cbbd73df930d64702ef881d811e0e1498e2f1c13eb1fc345d74',
++        '958ef42a7886b6400a08266e9ba1b37896c95330d97077cbbe8eb3c7671c60d6'
++      ],
++      [
++        'f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530',
++        'e0dedc9b3b2f8dad4da1f32dec2531df9eb5fbeb0598e4fd1a117dba703a3c37'
++      ],
++      [
++        '463b3d9f662621fb1b4be8fbbe2520125a216cdfc9dae3debcba4850c690d45b',
++        '5ed430d78c296c3543114306dd8622d7c622e27c970a1de31cb377b01af7307e'
++      ],
++      [
++        'f16f804244e46e2a09232d4aff3b59976b98fac14328a2d1a32496b49998f247',
++        'cedabd9b82203f7e13d206fcdf4e33d92a6c53c26e5cce26d6579962c4e31df6'
++      ],
++      [
++        'caf754272dc84563b0352b7a14311af55d245315ace27c65369e15f7151d41d1',
++        'cb474660ef35f5f2a41b643fa5e460575f4fa9b7962232a5c32f908318a04476'
++      ],
++      [
++        '2600ca4b282cb986f85d0f1709979d8b44a09c07cb86d7c124497bc86f082120',
++        '4119b88753c15bd6a693b03fcddbb45d5ac6be74ab5f0ef44b0be9475a7e4b40'
++      ],
++      [
++        '7635ca72d7e8432c338ec53cd12220bc01c48685e24f7dc8c602a7746998e435',
++        '91b649609489d613d1d5e590f78e6d74ecfc061d57048bad9e76f302c5b9c61'
++      ],
++      [
++        '754e3239f325570cdbbf4a87deee8a66b7f2b33479d468fbc1a50743bf56cc18',
++        '673fb86e5bda30fb3cd0ed304ea49a023ee33d0197a695d0c5d98093c536683'
++      ],
++      [
++        'e3e6bd1071a1e96aff57859c82d570f0330800661d1c952f9fe2694691d9b9e8',
++        '59c9e0bba394e76f40c0aa58379a3cb6a5a2283993e90c4167002af4920e37f5'
++      ],
++      [
++        '186b483d056a033826ae73d88f732985c4ccb1f32ba35f4b4cc47fdcf04aa6eb',
++        '3b952d32c67cf77e2e17446e204180ab21fb8090895138b4a4a797f86e80888b'
++      ],
++      [
++        'df9d70a6b9876ce544c98561f4be4f725442e6d2b737d9c91a8321724ce0963f',
++        '55eb2dafd84d6ccd5f862b785dc39d4ab157222720ef9da217b8c45cf2ba2417'
++      ],
++      [
++        '5edd5cc23c51e87a497ca815d5dce0f8ab52554f849ed8995de64c5f34ce7143',
++        'efae9c8dbc14130661e8cec030c89ad0c13c66c0d17a2905cdc706ab7399a868'
++      ],
++      [
++        '290798c2b6476830da12fe02287e9e777aa3fba1c355b17a722d362f84614fba',
++        'e38da76dcd440621988d00bcf79af25d5b29c094db2a23146d003afd41943e7a'
++      ],
++      [
++        'af3c423a95d9f5b3054754efa150ac39cd29552fe360257362dfdecef4053b45',
++        'f98a3fd831eb2b749a93b0e6f35cfb40c8cd5aa667a15581bc2feded498fd9c6'
++      ],
++      [
++        '766dbb24d134e745cccaa28c99bf274906bb66b26dcf98df8d2fed50d884249a',
++        '744b1152eacbe5e38dcc887980da38b897584a65fa06cedd2c924f97cbac5996'
++      ],
++      [
++        '59dbf46f8c94759ba21277c33784f41645f7b44f6c596a58ce92e666191abe3e',
++        'c534ad44175fbc300f4ea6ce648309a042ce739a7919798cd85e216c4a307f6e'
++      ],
++      [
++        'f13ada95103c4537305e691e74e9a4a8dd647e711a95e73cb62dc6018cfd87b8',
++        'e13817b44ee14de663bf4bc808341f326949e21a6a75c2570778419bdaf5733d'
++      ],
++      [
++        '7754b4fa0e8aced06d4167a2c59cca4cda1869c06ebadfb6488550015a88522c',
++        '30e93e864e669d82224b967c3020b8fa8d1e4e350b6cbcc537a48b57841163a2'
++      ],
++      [
++        '948dcadf5990e048aa3874d46abef9d701858f95de8041d2a6828c99e2262519',
++        'e491a42537f6e597d5d28a3224b1bc25df9154efbd2ef1d2cbba2cae5347d57e'
++      ],
++      [
++        '7962414450c76c1689c7b48f8202ec37fb224cf5ac0bfa1570328a8a3d7c77ab',
++        '100b610ec4ffb4760d5c1fc133ef6f6b12507a051f04ac5760afa5b29db83437'
++      ],
++      [
++        '3514087834964b54b15b160644d915485a16977225b8847bb0dd085137ec47ca',
++        'ef0afbb2056205448e1652c48e8127fc6039e77c15c2378b7e7d15a0de293311'
++      ],
++      [
++        'd3cc30ad6b483e4bc79ce2c9dd8bc54993e947eb8df787b442943d3f7b527eaf',
++        '8b378a22d827278d89c5e9be8f9508ae3c2ad46290358630afb34db04eede0a4'
++      ],
++      [
++        '1624d84780732860ce1c78fcbfefe08b2b29823db913f6493975ba0ff4847610',
++        '68651cf9b6da903e0914448c6cd9d4ca896878f5282be4c8cc06e2a404078575'
++      ],
++      [
++        '733ce80da955a8a26902c95633e62a985192474b5af207da6df7b4fd5fc61cd4',
++        'f5435a2bd2badf7d485a4d8b8db9fcce3e1ef8e0201e4578c54673bc1dc5ea1d'
++      ],
++      [
++        '15d9441254945064cf1a1c33bbd3b49f8966c5092171e699ef258dfab81c045c',
++        'd56eb30b69463e7234f5137b73b84177434800bacebfc685fc37bbe9efe4070d'
++      ],
++      [
++        'a1d0fcf2ec9de675b612136e5ce70d271c21417c9d2b8aaaac138599d0717940',
++        'edd77f50bcb5a3cab2e90737309667f2641462a54070f3d519212d39c197a629'
++      ],
++      [
++        'e22fbe15c0af8ccc5780c0735f84dbe9a790badee8245c06c7ca37331cb36980',
++        'a855babad5cd60c88b430a69f53a1a7a38289154964799be43d06d77d31da06'
++      ],
++      [
++        '311091dd9860e8e20ee13473c1155f5f69635e394704eaa74009452246cfa9b3',
++        '66db656f87d1f04fffd1f04788c06830871ec5a64feee685bd80f0b1286d8374'
++      ],
++      [
++        '34c1fd04d301be89b31c0442d3e6ac24883928b45a9340781867d4232ec2dbdf',
++        '9414685e97b1b5954bd46f730174136d57f1ceeb487443dc5321857ba73abee'
++      ],
++      [
++        'f219ea5d6b54701c1c14de5b557eb42a8d13f3abbcd08affcc2a5e6b049b8d63',
++        '4cb95957e83d40b0f73af4544cccf6b1f4b08d3c07b27fb8d8c2962a400766d1'
++      ],
++      [
++        'd7b8740f74a8fbaab1f683db8f45de26543a5490bca627087236912469a0b448',
++        'fa77968128d9c92ee1010f337ad4717eff15db5ed3c049b3411e0315eaa4593b'
++      ],
++      [
++        '32d31c222f8f6f0ef86f7c98d3a3335ead5bcd32abdd94289fe4d3091aa824bf',
++        '5f3032f5892156e39ccd3d7915b9e1da2e6dac9e6f26e961118d14b8462e1661'
++      ],
++      [
++        '7461f371914ab32671045a155d9831ea8793d77cd59592c4340f86cbc18347b5',
++        '8ec0ba238b96bec0cbdddcae0aa442542eee1ff50c986ea6b39847b3cc092ff6'
++      ],
++      [
++        'ee079adb1df1860074356a25aa38206a6d716b2c3e67453d287698bad7b2b2d6',
++        '8dc2412aafe3be5c4c5f37e0ecc5f9f6a446989af04c4e25ebaac479ec1c8c1e'
++      ],
++      [
++        '16ec93e447ec83f0467b18302ee620f7e65de331874c9dc72bfd8616ba9da6b5',
++        '5e4631150e62fb40d0e8c2a7ca5804a39d58186a50e497139626778e25b0674d'
++      ],
++      [
++        'eaa5f980c245f6f038978290afa70b6bd8855897f98b6aa485b96065d537bd99',
++        'f65f5d3e292c2e0819a528391c994624d784869d7e6ea67fb18041024edc07dc'
++      ],
++      [
++        '78c9407544ac132692ee1910a02439958ae04877151342ea96c4b6b35a49f51',
++        'f3e0319169eb9b85d5404795539a5e68fa1fbd583c064d2462b675f194a3ddb4'
++      ],
++      [
++        '494f4be219a1a77016dcd838431aea0001cdc8ae7a6fc688726578d9702857a5',
++        '42242a969283a5f339ba7f075e36ba2af925ce30d767ed6e55f4b031880d562c'
++      ],
++      [
++        'a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5',
++        '204b5d6f84822c307e4b4a7140737aec23fc63b65b35f86a10026dbd2d864e6b'
++      ],
++      [
++        'c41916365abb2b5d09192f5f2dbeafec208f020f12570a184dbadc3e58595997',
++        '4f14351d0087efa49d245b328984989d5caf9450f34bfc0ed16e96b58fa9913'
++      ],
++      [
++        '841d6063a586fa475a724604da03bc5b92a2e0d2e0a36acfe4c73a5514742881',
++        '73867f59c0659e81904f9a1c7543698e62562d6744c169ce7a36de01a8d6154'
++      ],
++      [
++        '5e95bb399a6971d376026947f89bde2f282b33810928be4ded112ac4d70e20d5',
++        '39f23f366809085beebfc71181313775a99c9aed7d8ba38b161384c746012865'
++      ],
++      [
++        '36e4641a53948fd476c39f8a99fd974e5ec07564b5315d8bf99471bca0ef2f66',
++        'd2424b1b1abe4eb8164227b085c9aa9456ea13493fd563e06fd51cf5694c78fc'
++      ],
++      [
++        '336581ea7bfbbb290c191a2f507a41cf5643842170e914faeab27c2c579f726',
++        'ead12168595fe1be99252129b6e56b3391f7ab1410cd1e0ef3dcdcabd2fda224'
++      ],
++      [
++        '8ab89816dadfd6b6a1f2634fcf00ec8403781025ed6890c4849742706bd43ede',
++        '6fdcef09f2f6d0a044e654aef624136f503d459c3e89845858a47a9129cdd24e'
++      ],
++      [
++        '1e33f1a746c9c5778133344d9299fcaa20b0938e8acff2544bb40284b8c5fb94',
++        '60660257dd11b3aa9c8ed618d24edff2306d320f1d03010e33a7d2057f3b3b6'
++      ],
++      [
++        '85b7c1dcb3cec1b7ee7f30ded79dd20a0ed1f4cc18cbcfcfa410361fd8f08f31',
++        '3d98a9cdd026dd43f39048f25a8847f4fcafad1895d7a633c6fed3c35e999511'
++      ],
++      [
++        '29df9fbd8d9e46509275f4b125d6d45d7fbe9a3b878a7af872a2800661ac5f51',
++        'b4c4fe99c775a606e2d8862179139ffda61dc861c019e55cd2876eb2a27d84b'
++      ],
++      [
++        'a0b1cae06b0a847a3fea6e671aaf8adfdfe58ca2f768105c8082b2e449fce252',
++        'ae434102edde0958ec4b19d917a6a28e6b72da1834aff0e650f049503a296cf2'
++      ],
++      [
++        '4e8ceafb9b3e9a136dc7ff67e840295b499dfb3b2133e4ba113f2e4c0e121e5',
++        'cf2174118c8b6d7a4b48f6d534ce5c79422c086a63460502b827ce62a326683c'
++      ],
++      [
++        'd24a44e047e19b6f5afb81c7ca2f69080a5076689a010919f42725c2b789a33b',
++        '6fb8d5591b466f8fc63db50f1c0f1c69013f996887b8244d2cdec417afea8fa3'
++      ],
++      [
++        'ea01606a7a6c9cdd249fdfcfacb99584001edd28abbab77b5104e98e8e3b35d4',
++        '322af4908c7312b0cfbfe369f7a7b3cdb7d4494bc2823700cfd652188a3ea98d'
++      ],
++      [
++        'af8addbf2b661c8a6c6328655eb96651252007d8c5ea31be4ad196de8ce2131f',
++        '6749e67c029b85f52a034eafd096836b2520818680e26ac8f3dfbcdb71749700'
++      ],
++      [
++        'e3ae1974566ca06cc516d47e0fb165a674a3dabcfca15e722f0e3450f45889',
++        '2aeabe7e4531510116217f07bf4d07300de97e4874f81f533420a72eeb0bd6a4'
++      ],
++      [
++        '591ee355313d99721cf6993ffed1e3e301993ff3ed258802075ea8ced397e246',
++        'b0ea558a113c30bea60fc4775460c7901ff0b053d25ca2bdeee98f1a4be5d196'
++      ],
++      [
++        '11396d55fda54c49f19aa97318d8da61fa8584e47b084945077cf03255b52984',
++        '998c74a8cd45ac01289d5833a7beb4744ff536b01b257be4c5767bea93ea57a4'
++      ],
++      [
++        '3c5d2a1ba39c5a1790000738c9e0c40b8dcdfd5468754b6405540157e017aa7a',
++        'b2284279995a34e2f9d4de7396fc18b80f9b8b9fdd270f6661f79ca4c81bd257'
++      ],
++      [
++        'cc8704b8a60a0defa3a99a7299f2e9c3fbc395afb04ac078425ef8a1793cc030',
++        'bdd46039feed17881d1e0862db347f8cf395b74fc4bcdc4e940b74e3ac1f1b13'
++      ],
++      [
++        'c533e4f7ea8555aacd9777ac5cad29b97dd4defccc53ee7ea204119b2889b197',
++        '6f0a256bc5efdf429a2fb6242f1a43a2d9b925bb4a4b3a26bb8e0f45eb596096'
++      ],
++      [
++        'c14f8f2ccb27d6f109f6d08d03cc96a69ba8c34eec07bbcf566d48e33da6593',
++        'c359d6923bb398f7fd4473e16fe1c28475b740dd098075e6c0e8649113dc3a38'
++      ],
++      [
++        'a6cbc3046bc6a450bac24789fa17115a4c9739ed75f8f21ce441f72e0b90e6ef',
++        '21ae7f4680e889bb130619e2c0f95a360ceb573c70603139862afd617fa9b9f'
++      ],
++      [
++        '347d6d9a02c48927ebfb86c1359b1caf130a3c0267d11ce6344b39f99d43cc38',
++        '60ea7f61a353524d1c987f6ecec92f086d565ab687870cb12689ff1e31c74448'
++      ],
++      [
++        'da6545d2181db8d983f7dcb375ef5866d47c67b1bf31c8cf855ef7437b72656a',
++        '49b96715ab6878a79e78f07ce5680c5d6673051b4935bd897fea824b77dc208a'
++      ],
++      [
++        'c40747cc9d012cb1a13b8148309c6de7ec25d6945d657146b9d5994b8feb1111',
++        '5ca560753be2a12fc6de6caf2cb489565db936156b9514e1bb5e83037e0fa2d4'
++      ],
++      [
++        '4e42c8ec82c99798ccf3a610be870e78338c7f713348bd34c8203ef4037f3502',
++        '7571d74ee5e0fb92a7a8b33a07783341a5492144cc54bcc40a94473693606437'
++      ],
++      [
++        '3775ab7089bc6af823aba2e1af70b236d251cadb0c86743287522a1b3b0dedea',
++        'be52d107bcfa09d8bcb9736a828cfa7fac8db17bf7a76a2c42ad961409018cf7'
++      ],
++      [
++        'cee31cbf7e34ec379d94fb814d3d775ad954595d1314ba8846959e3e82f74e26',
++        '8fd64a14c06b589c26b947ae2bcf6bfa0149ef0be14ed4d80f448a01c43b1c6d'
++      ],
++      [
++        'b4f9eaea09b6917619f6ea6a4eb5464efddb58fd45b1ebefcdc1a01d08b47986',
++        '39e5c9925b5a54b07433a4f18c61726f8bb131c012ca542eb24a8ac07200682a'
++      ],
++      [
++        'd4263dfc3d2df923a0179a48966d30ce84e2515afc3dccc1b77907792ebcc60e',
++        '62dfaf07a0f78feb30e30d6295853ce189e127760ad6cf7fae164e122a208d54'
++      ],
++      [
++        '48457524820fa65a4f8d35eb6930857c0032acc0a4a2de422233eeda897612c4',
++        '25a748ab367979d98733c38a1fa1c2e7dc6cc07db2d60a9ae7a76aaa49bd0f77'
++      ],
++      [
++        'dfeeef1881101f2cb11644f3a2afdfc2045e19919152923f367a1767c11cceda',
++        'ecfb7056cf1de042f9420bab396793c0c390bde74b4bbdff16a83ae09a9a7517'
++      ],
++      [
++        '6d7ef6b17543f8373c573f44e1f389835d89bcbc6062ced36c82df83b8fae859',
++        'cd450ec335438986dfefa10c57fea9bcc521a0959b2d80bbf74b190dca712d10'
++      ],
++      [
++        'e75605d59102a5a2684500d3b991f2e3f3c88b93225547035af25af66e04541f',
++        'f5c54754a8f71ee540b9b48728473e314f729ac5308b06938360990e2bfad125'
++      ],
++      [
++        'eb98660f4c4dfaa06a2be453d5020bc99a0c2e60abe388457dd43fefb1ed620c',
++        '6cb9a8876d9cb8520609af3add26cd20a0a7cd8a9411131ce85f44100099223e'
++      ],
++      [
++        '13e87b027d8514d35939f2e6892b19922154596941888336dc3563e3b8dba942',
++        'fef5a3c68059a6dec5d624114bf1e91aac2b9da568d6abeb2570d55646b8adf1'
++      ],
++      [
++        'ee163026e9fd6fe017c38f06a5be6fc125424b371ce2708e7bf4491691e5764a',
++        '1acb250f255dd61c43d94ccc670d0f58f49ae3fa15b96623e5430da0ad6c62b2'
++      ],
++      [
++        'b268f5ef9ad51e4d78de3a750c2dc89b1e626d43505867999932e5db33af3d80',
++        '5f310d4b3c99b9ebb19f77d41c1dee018cf0d34fd4191614003e945a1216e423'
++      ],
++      [
++        'ff07f3118a9df035e9fad85eb6c7bfe42b02f01ca99ceea3bf7ffdba93c4750d',
++        '438136d603e858a3a5c440c38eccbaddc1d2942114e2eddd4740d098ced1f0d8'
++      ],
++      [
++        '8d8b9855c7c052a34146fd20ffb658bea4b9f69e0d825ebec16e8c3ce2b526a1',
++        'cdb559eedc2d79f926baf44fb84ea4d44bcf50fee51d7ceb30e2e7f463036758'
++      ],
++      [
++        '52db0b5384dfbf05bfa9d472d7ae26dfe4b851ceca91b1eba54263180da32b63',
++        'c3b997d050ee5d423ebaf66a6db9f57b3180c902875679de924b69d84a7b375'
++      ],
++      [
++        'e62f9490d3d51da6395efd24e80919cc7d0f29c3f3fa48c6fff543becbd43352',
++        '6d89ad7ba4876b0b22c2ca280c682862f342c8591f1daf5170e07bfd9ccafa7d'
++      ],
++      [
++        '7f30ea2476b399b4957509c88f77d0191afa2ff5cb7b14fd6d8e7d65aaab1193',
++        'ca5ef7d4b231c94c3b15389a5f6311e9daff7bb67b103e9880ef4bff637acaec'
++      ],
++      [
++        '5098ff1e1d9f14fb46a210fada6c903fef0fb7b4a1dd1d9ac60a0361800b7a00',
++        '9731141d81fc8f8084d37c6e7542006b3ee1b40d60dfe5362a5b132fd17ddc0'
++      ],
++      [
++        '32b78c7de9ee512a72895be6b9cbefa6e2f3c4ccce445c96b9f2c81e2778ad58',
++        'ee1849f513df71e32efc3896ee28260c73bb80547ae2275ba497237794c8753c'
++      ],
++      [
++        'e2cb74fddc8e9fbcd076eef2a7c72b0ce37d50f08269dfc074b581550547a4f7',
++        'd3aa2ed71c9dd2247a62df062736eb0baddea9e36122d2be8641abcb005cc4a4'
++      ],
++      [
++        '8438447566d4d7bedadc299496ab357426009a35f235cb141be0d99cd10ae3a8',
++        'c4e1020916980a4da5d01ac5e6ad330734ef0d7906631c4f2390426b2edd791f'
++      ],
++      [
++        '4162d488b89402039b584c6fc6c308870587d9c46f660b878ab65c82c711d67e',
++        '67163e903236289f776f22c25fb8a3afc1732f2b84b4e95dbda47ae5a0852649'
++      ],
++      [
++        '3fad3fa84caf0f34f0f89bfd2dcf54fc175d767aec3e50684f3ba4a4bf5f683d',
++        'cd1bc7cb6cc407bb2f0ca647c718a730cf71872e7d0d2a53fa20efcdfe61826'
++      ],
++      [
++        '674f2600a3007a00568c1a7ce05d0816c1fb84bf1370798f1c69532faeb1a86b',
++        '299d21f9413f33b3edf43b257004580b70db57da0b182259e09eecc69e0d38a5'
++      ],
++      [
++        'd32f4da54ade74abb81b815ad1fb3b263d82d6c692714bcff87d29bd5ee9f08f',
++        'f9429e738b8e53b968e99016c059707782e14f4535359d582fc416910b3eea87'
++      ],
++      [
++        '30e4e670435385556e593657135845d36fbb6931f72b08cb1ed954f1e3ce3ff6',
++        '462f9bce619898638499350113bbc9b10a878d35da70740dc695a559eb88db7b'
++      ],
++      [
++        'be2062003c51cc3004682904330e4dee7f3dcd10b01e580bf1971b04d4cad297',
++        '62188bc49d61e5428573d48a74e1c655b1c61090905682a0d5558ed72dccb9bc'
++      ],
++      [
++        '93144423ace3451ed29e0fb9ac2af211cb6e84a601df5993c419859fff5df04a',
++        '7c10dfb164c3425f5c71a3f9d7992038f1065224f72bb9d1d902a6d13037b47c'
++      ],
++      [
++        'b015f8044f5fcbdcf21ca26d6c34fb8197829205c7b7d2a7cb66418c157b112c',
++        'ab8c1e086d04e813744a655b2df8d5f83b3cdc6faa3088c1d3aea1454e3a1d5f'
++      ],
++      [
++        'd5e9e1da649d97d89e4868117a465a3a4f8a18de57a140d36b3f2af341a21b52',
++        '4cb04437f391ed73111a13cc1d4dd0db1693465c2240480d8955e8592f27447a'
++      ],
++      [
++        'd3ae41047dd7ca065dbf8ed77b992439983005cd72e16d6f996a5316d36966bb',
++        'bd1aeb21ad22ebb22a10f0303417c6d964f8cdd7df0aca614b10dc14d125ac46'
++      ],
++      [
++        '463e2763d885f958fc66cdd22800f0a487197d0a82e377b49f80af87c897b065',
++        'bfefacdb0e5d0fd7df3a311a94de062b26b80c61fbc97508b79992671ef7ca7f'
++      ],
++      [
++        '7985fdfd127c0567c6f53ec1bb63ec3158e597c40bfe747c83cddfc910641917',
++        '603c12daf3d9862ef2b25fe1de289aed24ed291e0ec6708703a5bd567f32ed03'
++      ],
++      [
++        '74a1ad6b5f76e39db2dd249410eac7f99e74c59cb83d2d0ed5ff1543da7703e9',
++        'cc6157ef18c9c63cd6193d83631bbea0093e0968942e8c33d5737fd790e0db08'
++      ],
++      [
++        '30682a50703375f602d416664ba19b7fc9bab42c72747463a71d0896b22f6da3',
++        '553e04f6b018b4fa6c8f39e7f311d3176290d0e0f19ca73f17714d9977a22ff8'
++      ],
++      [
++        '9e2158f0d7c0d5f26c3791efefa79597654e7a2b2464f52b1ee6c1347769ef57',
++        '712fcdd1b9053f09003a3481fa7762e9ffd7c8ef35a38509e2fbf2629008373'
++      ],
++      [
++        '176e26989a43c9cfeba4029c202538c28172e566e3c4fce7322857f3be327d66',
++        'ed8cc9d04b29eb877d270b4878dc43c19aefd31f4eee09ee7b47834c1fa4b1c3'
++      ],
++      [
++        '75d46efea3771e6e68abb89a13ad747ecf1892393dfc4f1b7004788c50374da8',
++        '9852390a99507679fd0b86fd2b39a868d7efc22151346e1a3ca4726586a6bed8'
++      ],
++      [
++        '809a20c67d64900ffb698c4c825f6d5f2310fb0451c869345b7319f645605721',
++        '9e994980d9917e22b76b061927fa04143d096ccc54963e6a5ebfa5f3f8e286c1'
++      ],
++      [
++        '1b38903a43f7f114ed4500b4eac7083fdefece1cf29c63528d563446f972c180',
++        '4036edc931a60ae889353f77fd53de4a2708b26b6f5da72ad3394119daf408f9'
++      ]
++    ]
++  }
++};
++
++},{}],17:[function(require,module,exports){
++'use strict';
++
++var utils = exports;
++var BN = require('bn.js');
++
++utils.assert = function assert(val, msg) {
++  if (!val)
++    throw new Error(msg || 'Assertion failed');
++};
++
++function toArray(msg, enc) {
++  if (Array.isArray(msg))
++    return msg.slice();
++  if (!msg)
++    return [];
++  var res = [];
++  if (typeof msg !== 'string') {
++    for (var i = 0; i < msg.length; i++)
++      res[i] = msg[i] | 0;
++    return res;
++  }
++  if (!enc) {
++    for (var i = 0; i < msg.length; i++) {
++      var c = msg.charCodeAt(i);
++      var hi = c >> 8;
++      var lo = c & 0xff;
++      if (hi)
++        res.push(hi, lo);
++      else
++        res.push(lo);
++    }
++  } else if (enc === 'hex') {
++    msg = msg.replace(/[^a-z0-9]+/ig, '');
++    if (msg.length % 2 !== 0)
++      msg = '0' + msg;
++    for (var i = 0; i < msg.length; i += 2)
++      res.push(parseInt(msg[i] + msg[i + 1], 16));
++  }
++  return res;
++}
++utils.toArray = toArray;
++
++function zero2(word) {
++  if (word.length === 1)
++    return '0' + word;
++  else
++    return word;
++}
++utils.zero2 = zero2;
++
++function toHex(msg) {
++  var res = '';
++  for (var i = 0; i < msg.length; i++)
++    res += zero2(msg[i].toString(16));
++  return res;
++}
++utils.toHex = toHex;
++
++utils.encode = function encode(arr, enc) {
++  if (enc === 'hex')
++    return toHex(arr);
++  else
++    return arr;
++};
++
++// Represent num in a w-NAF form
++function getNAF(num, w) {
++  var naf = [];
++  var ws = 1 << (w + 1);
++  var k = num.clone();
++  while (k.cmpn(1) >= 0) {
++    var z;
++    if (k.isOdd()) {
++      var mod = k.andln(ws - 1);
++      if (mod > (ws >> 1) - 1)
++        z = (ws >> 1) - mod;
++      else
++        z = mod;
++      k.isubn(z);
++    } else {
++      z = 0;
++    }
++    naf.push(z);
++
++    // Optimization, shift by word if possible
++    var shift = (k.cmpn(0) !== 0 && k.andln(ws - 1) === 0) ? (w + 1) : 1;
++    for (var i = 1; i < shift; i++)
++      naf.push(0);
++    k.iushrn(shift);
++  }
++
++  return naf;
++}
++utils.getNAF = getNAF;
++
++// Represent k1, k2 in a Joint Sparse Form
++function getJSF(k1, k2) {
++  var jsf = [
++    [],
++    []
++  ];
++
++  k1 = k1.clone();
++  k2 = k2.clone();
++  var d1 = 0;
++  var d2 = 0;
++  while (k1.cmpn(-d1) > 0 || k2.cmpn(-d2) > 0) {
++
++    // First phase
++    var m14 = (k1.andln(3) + d1) & 3;
++    var m24 = (k2.andln(3) + d2) & 3;
++    if (m14 === 3)
++      m14 = -1;
++    if (m24 === 3)
++      m24 = -1;
++    var u1;
++    if ((m14 & 1) === 0) {
++      u1 = 0;
++    } else {
++      var m8 = (k1.andln(7) + d1) & 7;
++      if ((m8 === 3 || m8 === 5) && m24 === 2)
++        u1 = -m14;
++      else
++        u1 = m14;
++    }
++    jsf[0].push(u1);
++
++    var u2;
++    if ((m24 & 1) === 0) {
++      u2 = 0;
++    } else {
++      var m8 = (k2.andln(7) + d2) & 7;
++      if ((m8 === 3 || m8 === 5) && m14 === 2)
++        u2 = -m24;
++      else
++        u2 = m24;
++    }
++    jsf[1].push(u2);
++
++    // Second phase
++    if (2 * d1 === u1 + 1)
++      d1 = 1 - d1;
++    if (2 * d2 === u2 + 1)
++      d2 = 1 - d2;
++    k1.iushrn(1);
++    k2.iushrn(1);
++  }
++
++  return jsf;
++}
++utils.getJSF = getJSF;
++
++function cachedProperty(obj, name, computer) {
++  var key = '_' + name;
++  obj.prototype[name] = function cachedProperty() {
++    return this[key] !== undefined ? this[key] :
++           this[key] = computer.call(this);
++  };
++}
++utils.cachedProperty = cachedProperty;
++
++function parseBytes(bytes) {
++  return typeof bytes === 'string' ? utils.toArray(bytes, 'hex') :
++                                     bytes;
++}
++utils.parseBytes = parseBytes;
++
++function intFromLE(bytes) {
++  return new BN(bytes, 'hex', 'le');
++}
++utils.intFromLE = intFromLE;
++
++
++},{"bn.js":1}],18:[function(require,module,exports){
++var r;
++
++module.exports = function rand(len) {
++  if (!r)
++    r = new Rand(null);
++
++  return r.generate(len);
++};
++
++function Rand(rand) {
++  this.rand = rand;
++}
++module.exports.Rand = Rand;
++
++Rand.prototype.generate = function generate(len) {
++  return this._rand(len);
++};
++
++if (typeof window === 'object') {
++  if (window.crypto && window.crypto.getRandomValues) {
++    // Modern browsers
++    Rand.prototype._rand = function _rand(n) {
++      var arr = new Uint8Array(n);
++      window.crypto.getRandomValues(arr);
++      return arr;
++    };
++  } else if (window.msCrypto && window.msCrypto.getRandomValues) {
++    // IE
++    Rand.prototype._rand = function _rand(n) {
++      var arr = new Uint8Array(n);
++      window.msCrypto.getRandomValues(arr);
++      return arr;
++    };
++  } else {
++    // Old junk
++    Rand.prototype._rand = function() {
++      throw new Error('Not implemented yet');
++    };
++  }
++} else {
++  // Node.js or Web worker
++  try {
++    var crypto = require('cry' + 'pto');
++
++    Rand.prototype._rand = function _rand(n) {
++      return crypto.randomBytes(n);
++    };
++  } catch (e) {
++    // Emulate crypto API using randy
++    Rand.prototype._rand = function _rand(n) {
++      var res = new Uint8Array(n);
++      for (var i = 0; i < res.length; i++)
++        res[i] = this.rand.getByte();
++      return res;
++    };
++  }
++}
++
++},{}],19:[function(require,module,exports){
++var hash = exports;
++
++hash.utils = require('./hash/utils');
++hash.common = require('./hash/common');
++hash.sha = require('./hash/sha');
++hash.ripemd = require('./hash/ripemd');
++hash.hmac = require('./hash/hmac');
++
++// Proxy hash functions to the main object
++hash.sha1 = hash.sha.sha1;
++hash.sha256 = hash.sha.sha256;
++hash.sha224 = hash.sha.sha224;
++hash.sha384 = hash.sha.sha384;
++hash.sha512 = hash.sha.sha512;
++hash.ripemd160 = hash.ripemd.ripemd160;
++
++},{"./hash/common":20,"./hash/hmac":21,"./hash/ripemd":22,"./hash/sha":23,"./hash/utils":24}],20:[function(require,module,exports){
++var hash = require('../hash');
++var utils = hash.utils;
++var assert = utils.assert;
++
++function BlockHash() {
++  this.pending = null;
++  this.pendingTotal = 0;
++  this.blockSize = this.constructor.blockSize;
++  this.outSize = this.constructor.outSize;
++  this.hmacStrength = this.constructor.hmacStrength;
++  this.padLength = this.constructor.padLength / 8;
++  this.endian = 'big';
++
++  this._delta8 = this.blockSize / 8;
++  this._delta32 = this.blockSize / 32;
++}
++exports.BlockHash = BlockHash;
++
++BlockHash.prototype.update = function update(msg, enc) {
++  // Convert message to array, pad it, and join into 32bit blocks
++  msg = utils.toArray(msg, enc);
++  if (!this.pending)
++    this.pending = msg;
++  else
++    this.pending = this.pending.concat(msg);
++  this.pendingTotal += msg.length;
++
++  // Enough data, try updating
++  if (this.pending.length >= this._delta8) {
++    msg = this.pending;
++
++    // Process pending data in blocks
++    var r = msg.length % this._delta8;
++    this.pending = msg.slice(msg.length - r, msg.length);
++    if (this.pending.length === 0)
++      this.pending = null;
++
++    msg = utils.join32(msg, 0, msg.length - r, this.endian);
++    for (var i = 0; i < msg.length; i += this._delta32)
++      this._update(msg, i, i + this._delta32);
++  }
++
++  return this;
++};
++
++BlockHash.prototype.digest = function digest(enc) {
++  this.update(this._pad());
++  assert(this.pending === null);
++
++  return this._digest(enc);
++};
++
++BlockHash.prototype._pad = function pad() {
++  var len = this.pendingTotal;
++  var bytes = this._delta8;
++  var k = bytes - ((len + this.padLength) % bytes);
++  var res = new Array(k + this.padLength);
++  res[0] = 0x80;
++  for (var i = 1; i < k; i++)
++    res[i] = 0;
++
++  // Append length
++  len <<= 3;
++  if (this.endian === 'big') {
++    for (var t = 8; t < this.padLength; t++)
++      res[i++] = 0;
++
++    res[i++] = 0;
++    res[i++] = 0;
++    res[i++] = 0;
++    res[i++] = 0;
++    res[i++] = (len >>> 24) & 0xff;
++    res[i++] = (len >>> 16) & 0xff;
++    res[i++] = (len >>> 8) & 0xff;
++    res[i++] = len & 0xff;
++  } else {
++    res[i++] = len & 0xff;
++    res[i++] = (len >>> 8) & 0xff;
++    res[i++] = (len >>> 16) & 0xff;
++    res[i++] = (len >>> 24) & 0xff;
++    res[i++] = 0;
++    res[i++] = 0;
++    res[i++] = 0;
++    res[i++] = 0;
++
++    for (var t = 8; t < this.padLength; t++)
++      res[i++] = 0;
++  }
++
++  return res;
++};
++
++},{"../hash":19}],21:[function(require,module,exports){
++var hmac = exports;
++
++var hash = require('../hash');
++var utils = hash.utils;
++var assert = utils.assert;
++
++function Hmac(hash, key, enc) {
++  if (!(this instanceof Hmac))
++    return new Hmac(hash, key, enc);
++  this.Hash = hash;
++  this.blockSize = hash.blockSize / 8;
++  this.outSize = hash.outSize / 8;
++  this.inner = null;
++  this.outer = null;
++
++  this._init(utils.toArray(key, enc));
++}
++module.exports = Hmac;
++
++Hmac.prototype._init = function init(key) {
++  // Shorten key, if needed
++  if (key.length > this.blockSize)
++    key = new this.Hash().update(key).digest();
++  assert(key.length <= this.blockSize);
++
++  // Add padding to key
++  for (var i = key.length; i < this.blockSize; i++)
++    key.push(0);
++
++  for (var i = 0; i < key.length; i++)
++    key[i] ^= 0x36;
++  this.inner = new this.Hash().update(key);
++
++  // 0x36 ^ 0x5c = 0x6a
++  for (var i = 0; i < key.length; i++)
++    key[i] ^= 0x6a;
++  this.outer = new this.Hash().update(key);
++};
++
++Hmac.prototype.update = function update(msg, enc) {
++  this.inner.update(msg, enc);
++  return this;
++};
++
++Hmac.prototype.digest = function digest(enc) {
++  this.outer.update(this.inner.digest());
++  return this.outer.digest(enc);
++};
++
++},{"../hash":19}],22:[function(require,module,exports){
++var hash = require('../hash');
++var utils = hash.utils;
++
++var rotl32 = utils.rotl32;
++var sum32 = utils.sum32;
++var sum32_3 = utils.sum32_3;
++var sum32_4 = utils.sum32_4;
++var BlockHash = hash.common.BlockHash;
++
++function RIPEMD160() {
++  if (!(this instanceof RIPEMD160))
++    return new RIPEMD160();
++
++  BlockHash.call(this);
++
++  this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ];
++  this.endian = 'little';
++}
++utils.inherits(RIPEMD160, BlockHash);
++exports.ripemd160 = RIPEMD160;
++
++RIPEMD160.blockSize = 512;
++RIPEMD160.outSize = 160;
++RIPEMD160.hmacStrength = 192;
++RIPEMD160.padLength = 64;
++
++RIPEMD160.prototype._update = function update(msg, start) {
++  var A = this.h[0];
++  var B = this.h[1];
++  var C = this.h[2];
++  var D = this.h[3];
++  var E = this.h[4];
++  var Ah = A;
++  var Bh = B;
++  var Ch = C;
++  var Dh = D;
++  var Eh = E;
++  for (var j = 0; j < 80; j++) {
++    var T = sum32(
++      rotl32(
++        sum32_4(A, f(j, B, C, D), msg[r[j] + start], K(j)),
++        s[j]),
++      E);
++    A = E;
++    E = D;
++    D = rotl32(C, 10);
++    C = B;
++    B = T;
++    T = sum32(
++      rotl32(
++        sum32_4(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)),
++        sh[j]),
++      Eh);
++    Ah = Eh;
++    Eh = Dh;
++    Dh = rotl32(Ch, 10);
++    Ch = Bh;
++    Bh = T;
++  }
++  T = sum32_3(this.h[1], C, Dh);
++  this.h[1] = sum32_3(this.h[2], D, Eh);
++  this.h[2] = sum32_3(this.h[3], E, Ah);
++  this.h[3] = sum32_3(this.h[4], A, Bh);
++  this.h[4] = sum32_3(this.h[0], B, Ch);
++  this.h[0] = T;
++};
++
++RIPEMD160.prototype._digest = function digest(enc) {
++  if (enc === 'hex')
++    return utils.toHex32(this.h, 'little');
++  else
++    return utils.split32(this.h, 'little');
++};
++
++function f(j, x, y, z) {
++  if (j <= 15)
++    return x ^ y ^ z;
++  else if (j <= 31)
++    return (x & y) | ((~x) & z);
++  else if (j <= 47)
++    return (x | (~y)) ^ z;
++  else if (j <= 63)
++    return (x & z) | (y & (~z));
++  else
++    return x ^ (y | (~z));
++}
++
++function K(j) {
++  if (j <= 15)
++    return 0x00000000;
++  else if (j <= 31)
++    return 0x5a827999;
++  else if (j <= 47)
++    return 0x6ed9eba1;
++  else if (j <= 63)
++    return 0x8f1bbcdc;
++  else
++    return 0xa953fd4e;
++}
++
++function Kh(j) {
++  if (j <= 15)
++    return 0x50a28be6;
++  else if (j <= 31)
++    return 0x5c4dd124;
++  else if (j <= 47)
++    return 0x6d703ef3;
++  else if (j <= 63)
++    return 0x7a6d76e9;
++  else
++    return 0x00000000;
++}
++
++var r = [
++  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
++  7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
++  3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
++  1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
++  4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
++];
++
++var rh = [
++  5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
++  6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
++  15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
++  8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
++  12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
++];
++
++var s = [
++  11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
++  7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
++  11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
++  11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
++  9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
++];
++
++var sh = [
++  8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
++  9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
++  9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
++  15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
++  8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
++];
++
++},{"../hash":19}],23:[function(require,module,exports){
++var hash = require('../hash');
++var utils = hash.utils;
++var assert = utils.assert;
++
++var rotr32 = utils.rotr32;
++var rotl32 = utils.rotl32;
++var sum32 = utils.sum32;
++var sum32_4 = utils.sum32_4;
++var sum32_5 = utils.sum32_5;
++var rotr64_hi = utils.rotr64_hi;
++var rotr64_lo = utils.rotr64_lo;
++var shr64_hi = utils.shr64_hi;
++var shr64_lo = utils.shr64_lo;
++var sum64 = utils.sum64;
++var sum64_hi = utils.sum64_hi;
++var sum64_lo = utils.sum64_lo;
++var sum64_4_hi = utils.sum64_4_hi;
++var sum64_4_lo = utils.sum64_4_lo;
++var sum64_5_hi = utils.sum64_5_hi;
++var sum64_5_lo = utils.sum64_5_lo;
++var BlockHash = hash.common.BlockHash;
++
++var sha256_K = [
++  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
++  0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
++  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
++  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
++  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
++  0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
++  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
++  0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
++  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
++  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
++  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
++  0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
++  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
++  0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
++  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
++  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
++];
++
++var sha512_K = [
++  0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,
++  0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,
++  0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,
++  0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,
++  0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,
++  0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,
++  0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,
++  0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,
++  0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,
++  0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,
++  0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,
++  0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,
++  0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,
++  0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,
++  0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,
++  0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,
++  0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,
++  0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,
++  0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,
++  0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,
++  0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,
++  0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,
++  0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,
++  0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,
++  0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,
++  0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,
++  0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,
++  0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,
++  0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,
++  0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,
++  0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,
++  0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,
++  0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,
++  0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,
++  0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,
++  0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,
++  0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,
++  0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,
++  0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,
++  0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817
++];
++
++var sha1_K = [
++  0x5A827999, 0x6ED9EBA1,
++  0x8F1BBCDC, 0xCA62C1D6
++];
++
++function SHA256() {
++  if (!(this instanceof SHA256))
++    return new SHA256();
++
++  BlockHash.call(this);
++  this.h = [ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
++             0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ];
++  this.k = sha256_K;
++  this.W = new Array(64);
++}
++utils.inherits(SHA256, BlockHash);
++exports.sha256 = SHA256;
++
++SHA256.blockSize = 512;
++SHA256.outSize = 256;
++SHA256.hmacStrength = 192;
++SHA256.padLength = 64;
++
++SHA256.prototype._update = function _update(msg, start) {
++  var W = this.W;
++
++  for (var i = 0; i < 16; i++)
++    W[i] = msg[start + i];
++  for (; i < W.length; i++)
++    W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]);
++
++  var a = this.h[0];
++  var b = this.h[1];
++  var c = this.h[2];
++  var d = this.h[3];
++  var e = this.h[4];
++  var f = this.h[5];
++  var g = this.h[6];
++  var h = this.h[7];
++
++  assert(this.k.length === W.length);
++  for (var i = 0; i < W.length; i++) {
++    var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]);
++    var T2 = sum32(s0_256(a), maj32(a, b, c));
++    h = g;
++    g = f;
++    f = e;
++    e = sum32(d, T1);
++    d = c;
++    c = b;
++    b = a;
++    a = sum32(T1, T2);
++  }
++
++  this.h[0] = sum32(this.h[0], a);
++  this.h[1] = sum32(this.h[1], b);
++  this.h[2] = sum32(this.h[2], c);
++  this.h[3] = sum32(this.h[3], d);
++  this.h[4] = sum32(this.h[4], e);
++  this.h[5] = sum32(this.h[5], f);
++  this.h[6] = sum32(this.h[6], g);
++  this.h[7] = sum32(this.h[7], h);
++};
++
++SHA256.prototype._digest = function digest(enc) {
++  if (enc === 'hex')
++    return utils.toHex32(this.h, 'big');
++  else
++    return utils.split32(this.h, 'big');
++};
++
++function SHA224() {
++  if (!(this instanceof SHA224))
++    return new SHA224();
++
++  SHA256.call(this);
++  this.h = [ 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
++             0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ];
++}
++utils.inherits(SHA224, SHA256);
++exports.sha224 = SHA224;
++
++SHA224.blockSize = 512;
++SHA224.outSize = 224;
++SHA224.hmacStrength = 192;
++SHA224.padLength = 64;
++
++SHA224.prototype._digest = function digest(enc) {
++  // Just truncate output
++  if (enc === 'hex')
++    return utils.toHex32(this.h.slice(0, 7), 'big');
++  else
++    return utils.split32(this.h.slice(0, 7), 'big');
++};
++
++function SHA512() {
++  if (!(this instanceof SHA512))
++    return new SHA512();
++
++  BlockHash.call(this);
++  this.h = [ 0x6a09e667, 0xf3bcc908,
++             0xbb67ae85, 0x84caa73b,
++             0x3c6ef372, 0xfe94f82b,
++             0xa54ff53a, 0x5f1d36f1,
++             0x510e527f, 0xade682d1,
++             0x9b05688c, 0x2b3e6c1f,
++             0x1f83d9ab, 0xfb41bd6b,
++             0x5be0cd19, 0x137e2179 ];
++  this.k = sha512_K;
++  this.W = new Array(160);
++}
++utils.inherits(SHA512, BlockHash);
++exports.sha512 = SHA512;
++
++SHA512.blockSize = 1024;
++SHA512.outSize = 512;
++SHA512.hmacStrength = 192;
++SHA512.padLength = 128;
++
++SHA512.prototype._prepareBlock = function _prepareBlock(msg, start) {
++  var W = this.W;
++
++  // 32 x 32bit words
++  for (var i = 0; i < 32; i++)
++    W[i] = msg[start + i];
++  for (; i < W.length; i += 2) {
++    var c0_hi = g1_512_hi(W[i - 4], W[i - 3]);  // i - 2
++    var c0_lo = g1_512_lo(W[i - 4], W[i - 3]);
++    var c1_hi = W[i - 14];  // i - 7
++    var c1_lo = W[i - 13];
++    var c2_hi = g0_512_hi(W[i - 30], W[i - 29]);  // i - 15
++    var c2_lo = g0_512_lo(W[i - 30], W[i - 29]);
++    var c3_hi = W[i - 32];  // i - 16
++    var c3_lo = W[i - 31];
++
++    W[i] = sum64_4_hi(c0_hi, c0_lo,
++                      c1_hi, c1_lo,
++                      c2_hi, c2_lo,
++                      c3_hi, c3_lo);
++    W[i + 1] = sum64_4_lo(c0_hi, c0_lo,
++                          c1_hi, c1_lo,
++                          c2_hi, c2_lo,
++                          c3_hi, c3_lo);
++  }
++};
++
++SHA512.prototype._update = function _update(msg, start) {
++  this._prepareBlock(msg, start);
++
++  var W = this.W;
++
++  var ah = this.h[0];
++  var al = this.h[1];
++  var bh = this.h[2];
++  var bl = this.h[3];
++  var ch = this.h[4];
++  var cl = this.h[5];
++  var dh = this.h[6];
++  var dl = this.h[7];
++  var eh = this.h[8];
++  var el = this.h[9];
++  var fh = this.h[10];
++  var fl = this.h[11];
++  var gh = this.h[12];
++  var gl = this.h[13];
++  var hh = this.h[14];
++  var hl = this.h[15];
++
++  assert(this.k.length === W.length);
++  for (var i = 0; i < W.length; i += 2) {
++    var c0_hi = hh;
++    var c0_lo = hl;
++    var c1_hi = s1_512_hi(eh, el);
++    var c1_lo = s1_512_lo(eh, el);
++    var c2_hi = ch64_hi(eh, el, fh, fl, gh, gl);
++    var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl);
++    var c3_hi = this.k[i];
++    var c3_lo = this.k[i + 1];
++    var c4_hi = W[i];
++    var c4_lo = W[i + 1];
++
++    var T1_hi = sum64_5_hi(c0_hi, c0_lo,
++                           c1_hi, c1_lo,
++                           c2_hi, c2_lo,
++                           c3_hi, c3_lo,
++                           c4_hi, c4_lo);
++    var T1_lo = sum64_5_lo(c0_hi, c0_lo,
++                           c1_hi, c1_lo,
++                           c2_hi, c2_lo,
++                           c3_hi, c3_lo,
++                           c4_hi, c4_lo);
++
++    var c0_hi = s0_512_hi(ah, al);
++    var c0_lo = s0_512_lo(ah, al);
++    var c1_hi = maj64_hi(ah, al, bh, bl, ch, cl);
++    var c1_lo = maj64_lo(ah, al, bh, bl, ch, cl);
++
++    var T2_hi = sum64_hi(c0_hi, c0_lo, c1_hi, c1_lo);
++    var T2_lo = sum64_lo(c0_hi, c0_lo, c1_hi, c1_lo);
++
++    hh = gh;
++    hl = gl;
++
++    gh = fh;
++    gl = fl;
++
++    fh = eh;
++    fl = el;
++
++    eh = sum64_hi(dh, dl, T1_hi, T1_lo);
++    el = sum64_lo(dl, dl, T1_hi, T1_lo);
++
++    dh = ch;
++    dl = cl;
++
++    ch = bh;
++    cl = bl;
++
++    bh = ah;
++    bl = al;
++
++    ah = sum64_hi(T1_hi, T1_lo, T2_hi, T2_lo);
++    al = sum64_lo(T1_hi, T1_lo, T2_hi, T2_lo);
++  }
++
++  sum64(this.h, 0, ah, al);
++  sum64(this.h, 2, bh, bl);
++  sum64(this.h, 4, ch, cl);
++  sum64(this.h, 6, dh, dl);
++  sum64(this.h, 8, eh, el);
++  sum64(this.h, 10, fh, fl);
++  sum64(this.h, 12, gh, gl);
++  sum64(this.h, 14, hh, hl);
++};
++
++SHA512.prototype._digest = function digest(enc) {
++  if (enc === 'hex')
++    return utils.toHex32(this.h, 'big');
++  else
++    return utils.split32(this.h, 'big');
++};
++
++function SHA384() {
++  if (!(this instanceof SHA384))
++    return new SHA384();
++
++  SHA512.call(this);
++  this.h = [ 0xcbbb9d5d, 0xc1059ed8,
++             0x629a292a, 0x367cd507,
++             0x9159015a, 0x3070dd17,
++             0x152fecd8, 0xf70e5939,
++             0x67332667, 0xffc00b31,
++             0x8eb44a87, 0x68581511,
++             0xdb0c2e0d, 0x64f98fa7,
++             0x47b5481d, 0xbefa4fa4 ];
++}
++utils.inherits(SHA384, SHA512);
++exports.sha384 = SHA384;
++
++SHA384.blockSize = 1024;
++SHA384.outSize = 384;
++SHA384.hmacStrength = 192;
++SHA384.padLength = 128;
++
++SHA384.prototype._digest = function digest(enc) {
++  if (enc === 'hex')
++    return utils.toHex32(this.h.slice(0, 12), 'big');
++  else
++    return utils.split32(this.h.slice(0, 12), 'big');
++};
++
++function SHA1() {
++  if (!(this instanceof SHA1))
++    return new SHA1();
++
++  BlockHash.call(this);
++  this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe,
++             0x10325476, 0xc3d2e1f0 ];
++  this.W = new Array(80);
++}
++
++utils.inherits(SHA1, BlockHash);
++exports.sha1 = SHA1;
++
++SHA1.blockSize = 512;
++SHA1.outSize = 160;
++SHA1.hmacStrength = 80;
++SHA1.padLength = 64;
++
++SHA1.prototype._update = function _update(msg, start) {
++  var W = this.W;
++
++  for (var i = 0; i < 16; i++)
++    W[i] = msg[start + i];
++
++  for(; i < W.length; i++)
++    W[i] = rotl32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
++
++  var a = this.h[0];
++  var b = this.h[1];
++  var c = this.h[2];
++  var d = this.h[3];
++  var e = this.h[4];
++
++  for (var i = 0; i < W.length; i++) {
++    var s = ~~(i / 20);
++    var t = sum32_5(rotl32(a, 5), ft_1(s, b, c, d), e, W[i], sha1_K[s]);
++    e = d;
++    d = c;
++    c = rotl32(b, 30);
++    b = a;
++    a = t;
++  }
++
++  this.h[0] = sum32(this.h[0], a);
++  this.h[1] = sum32(this.h[1], b);
++  this.h[2] = sum32(this.h[2], c);
++  this.h[3] = sum32(this.h[3], d);
++  this.h[4] = sum32(this.h[4], e);
++};
++
++SHA1.prototype._digest = function digest(enc) {
++  if (enc === 'hex')
++    return utils.toHex32(this.h, 'big');
++  else
++    return utils.split32(this.h, 'big');
++};
++
++function ch32(x, y, z) {
++  return (x & y) ^ ((~x) & z);
++}
++
++function maj32(x, y, z) {
++  return (x & y) ^ (x & z) ^ (y & z);
++}
++
++function p32(x, y, z) {
++  return x ^ y ^ z;
++}
++
++function s0_256(x) {
++  return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22);
++}
++
++function s1_256(x) {
++  return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25);
++}
++
++function g0_256(x) {
++  return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3);
++}
++
++function g1_256(x) {
++  return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10);
++}
++
++function ft_1(s, x, y, z) {
++  if (s === 0)
++    return ch32(x, y, z);
++  if (s === 1 || s === 3)
++    return p32(x, y, z);
++  if (s === 2)
++    return maj32(x, y, z);
++}
++
++function ch64_hi(xh, xl, yh, yl, zh, zl) {
++  var r = (xh & yh) ^ ((~xh) & zh);
++  if (r < 0)
++    r += 0x100000000;
++  return r;
++}
++
++function ch64_lo(xh, xl, yh, yl, zh, zl) {
++  var r = (xl & yl) ^ ((~xl) & zl);
++  if (r < 0)
++    r += 0x100000000;
++  return r;
++}
++
++function maj64_hi(xh, xl, yh, yl, zh, zl) {
++  var r = (xh & yh) ^ (xh & zh) ^ (yh & zh);
++  if (r < 0)
++    r += 0x100000000;
++  return r;
++}
++
++function maj64_lo(xh, xl, yh, yl, zh, zl) {
++  var r = (xl & yl) ^ (xl & zl) ^ (yl & zl);
++  if (r < 0)
++    r += 0x100000000;
++  return r;
++}
++
++function s0_512_hi(xh, xl) {
++  var c0_hi = rotr64_hi(xh, xl, 28);
++  var c1_hi = rotr64_hi(xl, xh, 2);  // 34
++  var c2_hi = rotr64_hi(xl, xh, 7);  // 39
++
++  var r = c0_hi ^ c1_hi ^ c2_hi;
++  if (r < 0)
++    r += 0x100000000;
++  return r;
++}
++
++function s0_512_lo(xh, xl) {
++  var c0_lo = rotr64_lo(xh, xl, 28);
++  var c1_lo = rotr64_lo(xl, xh, 2);  // 34
++  var c2_lo = rotr64_lo(xl, xh, 7);  // 39
++
++  var r = c0_lo ^ c1_lo ^ c2_lo;
++  if (r < 0)
++    r += 0x100000000;
++  return r;
++}
++
++function s1_512_hi(xh, xl) {
++  var c0_hi = rotr64_hi(xh, xl, 14);
++  var c1_hi = rotr64_hi(xh, xl, 18);
++  var c2_hi = rotr64_hi(xl, xh, 9);  // 41
++
++  var r = c0_hi ^ c1_hi ^ c2_hi;
++  if (r < 0)
++    r += 0x100000000;
++  return r;
++}
++
++function s1_512_lo(xh, xl) {
++  var c0_lo = rotr64_lo(xh, xl, 14);
++  var c1_lo = rotr64_lo(xh, xl, 18);
++  var c2_lo = rotr64_lo(xl, xh, 9);  // 41
++
++  var r = c0_lo ^ c1_lo ^ c2_lo;
++  if (r < 0)
++    r += 0x100000000;
++  return r;
++}
++
++function g0_512_hi(xh, xl) {
++  var c0_hi = rotr64_hi(xh, xl, 1);
++  var c1_hi = rotr64_hi(xh, xl, 8);
++  var c2_hi = shr64_hi(xh, xl, 7);
++
++  var r = c0_hi ^ c1_hi ^ c2_hi;
++  if (r < 0)
++    r += 0x100000000;
++  return r;
++}
++
++function g0_512_lo(xh, xl) {
++  var c0_lo = rotr64_lo(xh, xl, 1);
++  var c1_lo = rotr64_lo(xh, xl, 8);
++  var c2_lo = shr64_lo(xh, xl, 7);
++
++  var r = c0_lo ^ c1_lo ^ c2_lo;
++  if (r < 0)
++    r += 0x100000000;
++  return r;
++}
++
++function g1_512_hi(xh, xl) {
++  var c0_hi = rotr64_hi(xh, xl, 19);
++  var c1_hi = rotr64_hi(xl, xh, 29);  // 61
++  var c2_hi = shr64_hi(xh, xl, 6);
++
++  var r = c0_hi ^ c1_hi ^ c2_hi;
++  if (r < 0)
++    r += 0x100000000;
++  return r;
++}
++
++function g1_512_lo(xh, xl) {
++  var c0_lo = rotr64_lo(xh, xl, 19);
++  var c1_lo = rotr64_lo(xl, xh, 29);  // 61
++  var c2_lo = shr64_lo(xh, xl, 6);
++
++  var r = c0_lo ^ c1_lo ^ c2_lo;
++  if (r < 0)
++    r += 0x100000000;
++  return r;
++}
++
++},{"../hash":19}],24:[function(require,module,exports){
++var utils = exports;
++var inherits = require('inherits');
++
++function toArray(msg, enc) {
++  if (Array.isArray(msg))
++    return msg.slice();
++  if (!msg)
++    return [];
++  var res = [];
++  if (typeof msg === 'string') {
++    if (!enc) {
++      for (var i = 0; i < msg.length; i++) {
++        var c = msg.charCodeAt(i);
++        var hi = c >> 8;
++        var lo = c & 0xff;
++        if (hi)
++          res.push(hi, lo);
++        else
++          res.push(lo);
++      }
++    } else if (enc === 'hex') {
++      msg = msg.replace(/[^a-z0-9]+/ig, '');
++      if (msg.length % 2 !== 0)
++        msg = '0' + msg;
++      for (var i = 0; i < msg.length; i += 2)
++        res.push(parseInt(msg[i] + msg[i + 1], 16));
++    }
++  } else {
++    for (var i = 0; i < msg.length; i++)
++      res[i] = msg[i] | 0;
++  }
++  return res;
++}
++utils.toArray = toArray;
++
++function toHex(msg) {
++  var res = '';
++  for (var i = 0; i < msg.length; i++)
++    res += zero2(msg[i].toString(16));
++  return res;
++}
++utils.toHex = toHex;
++
++function htonl(w) {
++  var res = (w >>> 24) |
++            ((w >>> 8) & 0xff00) |
++            ((w << 8) & 0xff0000) |
++            ((w & 0xff) << 24);
++  return res >>> 0;
++}
++utils.htonl = htonl;
++
++function toHex32(msg, endian) {
++  var res = '';
++  for (var i = 0; i < msg.length; i++) {
++    var w = msg[i];
++    if (endian === 'little')
++      w = htonl(w);
++    res += zero8(w.toString(16));
++  }
++  return res;
++}
++utils.toHex32 = toHex32;
++
++function zero2(word) {
++  if (word.length === 1)
++    return '0' + word;
++  else
++    return word;
++}
++utils.zero2 = zero2;
++
++function zero8(word) {
++  if (word.length === 7)
++    return '0' + word;
++  else if (word.length === 6)
++    return '00' + word;
++  else if (word.length === 5)
++    return '000' + word;
++  else if (word.length === 4)
++    return '0000' + word;
++  else if (word.length === 3)
++    return '00000' + word;
++  else if (word.length === 2)
++    return '000000' + word;
++  else if (word.length === 1)
++    return '0000000' + word;
++  else
++    return word;
++}
++utils.zero8 = zero8;
++
++function join32(msg, start, end, endian) {
++  var len = end - start;
++  assert(len % 4 === 0);
++  var res = new Array(len / 4);
++  for (var i = 0, k = start; i < res.length; i++, k += 4) {
++    var w;
++    if (endian === 'big')
++      w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3];
++    else
++      w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k];
++    res[i] = w >>> 0;
++  }
++  return res;
++}
++utils.join32 = join32;
++
++function split32(msg, endian) {
++  var res = new Array(msg.length * 4);
++  for (var i = 0, k = 0; i < msg.length; i++, k += 4) {
++    var m = msg[i];
++    if (endian === 'big') {
++      res[k] = m >>> 24;
++      res[k + 1] = (m >>> 16) & 0xff;
++      res[k + 2] = (m >>> 8) & 0xff;
++      res[k + 3] = m & 0xff;
++    } else {
++      res[k + 3] = m >>> 24;
++      res[k + 2] = (m >>> 16) & 0xff;
++      res[k + 1] = (m >>> 8) & 0xff;
++      res[k] = m & 0xff;
++    }
++  }
++  return res;
++}
++utils.split32 = split32;
++
++function rotr32(w, b) {
++  return (w >>> b) | (w << (32 - b));
++}
++utils.rotr32 = rotr32;
++
++function rotl32(w, b) {
++  return (w << b) | (w >>> (32 - b));
++}
++utils.rotl32 = rotl32;
++
++function sum32(a, b) {
++  return (a + b) >>> 0;
++}
++utils.sum32 = sum32;
++
++function sum32_3(a, b, c) {
++  return (a + b + c) >>> 0;
++}
++utils.sum32_3 = sum32_3;
++
++function sum32_4(a, b, c, d) {
++  return (a + b + c + d) >>> 0;
++}
++utils.sum32_4 = sum32_4;
++
++function sum32_5(a, b, c, d, e) {
++  return (a + b + c + d + e) >>> 0;
++}
++utils.sum32_5 = sum32_5;
++
++function assert(cond, msg) {
++  if (!cond)
++    throw new Error(msg || 'Assertion failed');
++}
++utils.assert = assert;
++
++utils.inherits = inherits;
++
++function sum64(buf, pos, ah, al) {
++  var bh = buf[pos];
++  var bl = buf[pos + 1];
++
++  var lo = (al + bl) >>> 0;
++  var hi = (lo < al ? 1 : 0) + ah + bh;
++  buf[pos] = hi >>> 0;
++  buf[pos + 1] = lo;
++}
++exports.sum64 = sum64;
++
++function sum64_hi(ah, al, bh, bl) {
++  var lo = (al + bl) >>> 0;
++  var hi = (lo < al ? 1 : 0) + ah + bh;
++  return hi >>> 0;
++};
++exports.sum64_hi = sum64_hi;
++
++function sum64_lo(ah, al, bh, bl) {
++  var lo = al + bl;
++  return lo >>> 0;
++};
++exports.sum64_lo = sum64_lo;
++
++function sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) {
++  var carry = 0;
++  var lo = al;
++  lo = (lo + bl) >>> 0;
++  carry += lo < al ? 1 : 0;
++  lo = (lo + cl) >>> 0;
++  carry += lo < cl ? 1 : 0;
++  lo = (lo + dl) >>> 0;
++  carry += lo < dl ? 1 : 0;
++
++  var hi = ah + bh + ch + dh + carry;
++  return hi >>> 0;
++};
++exports.sum64_4_hi = sum64_4_hi;
++
++function sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) {
++  var lo = al + bl + cl + dl;
++  return lo >>> 0;
++};
++exports.sum64_4_lo = sum64_4_lo;
++
++function sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
++  var carry = 0;
++  var lo = al;
++  lo = (lo + bl) >>> 0;
++  carry += lo < al ? 1 : 0;
++  lo = (lo + cl) >>> 0;
++  carry += lo < cl ? 1 : 0;
++  lo = (lo + dl) >>> 0;
++  carry += lo < dl ? 1 : 0;
++  lo = (lo + el) >>> 0;
++  carry += lo < el ? 1 : 0;
++
++  var hi = ah + bh + ch + dh + eh + carry;
++  return hi >>> 0;
++};
++exports.sum64_5_hi = sum64_5_hi;
++
++function sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
++  var lo = al + bl + cl + dl + el;
++
++  return lo >>> 0;
++};
++exports.sum64_5_lo = sum64_5_lo;
++
++function rotr64_hi(ah, al, num) {
++  var r = (al << (32 - num)) | (ah >>> num);
++  return r >>> 0;
++};
++exports.rotr64_hi = rotr64_hi;
++
++function rotr64_lo(ah, al, num) {
++  var r = (ah << (32 - num)) | (al >>> num);
++  return r >>> 0;
++};
++exports.rotr64_lo = rotr64_lo;
++
++function shr64_hi(ah, al, num) {
++  return ah >>> num;
++};
++exports.shr64_hi = shr64_hi;
++
++function shr64_lo(ah, al, num) {
++  var r = (ah << (32 - num)) | (al >>> num);
++  return r >>> 0;
++};
++exports.shr64_lo = shr64_lo;
++
++},{"inherits":25}],25:[function(require,module,exports){
++if (typeof Object.create === 'function') {
++  // implementation from standard node.js 'util' module
++  module.exports = function inherits(ctor, superCtor) {
++    ctor.super_ = superCtor
++    ctor.prototype = Object.create(superCtor.prototype, {
++      constructor: {
++        value: ctor,
++        enumerable: false,
++        writable: true,
++        configurable: true
++      }
++    });
++  };
++} else {
++  // old school shim for old browsers
++  module.exports = function inherits(ctor, superCtor) {
++    ctor.super_ = superCtor
++    var TempCtor = function () {}
++    TempCtor.prototype = superCtor.prototype
++    ctor.prototype = new TempCtor()
++    ctor.prototype.constructor = ctor
++  }
++}
++
++},{}],26:[function(require,module,exports){
++module.exports={
++  "name": "elliptic",
++  "version": "6.3.2",
++  "description": "EC cryptography",
++  "main": "lib/elliptic.js",
++  "files": [
++    "lib"
++  ],
++  "scripts": {
++    "jscs": "jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/index.js",
++    "jshint": "jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/index.js",
++    "lint": "npm run jscs && npm run jshint",
++    "unit": "istanbul test _mocha --reporter=spec test/index.js",
++    "test": "npm run lint && npm run unit",
++    "version": "grunt dist && git add dist/"
++  },
++  "repository": {
++    "type": "git",
++    "url": "git at github.com:indutny/elliptic"
++  },
++  "keywords": [
++    "EC",
++    "Elliptic",
++    "curve",
++    "Cryptography"
++  ],
++  "author": "Fedor Indutny <fedor at indutny.com>",
++  "license": "MIT",
++  "bugs": {
++    "url": "https://github.com/indutny/elliptic/issues"
++  },
++  "homepage": "https://github.com/indutny/elliptic",
++  "devDependencies": {
++    "brfs": "^1.4.3",
++    "coveralls": "^2.11.3",
++    "grunt": "^0.4.5",
++    "grunt-browserify": "^5.0.0",
++    "grunt-contrib-connect": "^1.0.0",
++    "grunt-contrib-copy": "^1.0.0",
++    "grunt-contrib-uglify": "^1.0.1",
++    "grunt-mocha-istanbul": "^3.0.1",
++    "grunt-saucelabs": "^8.6.2",
++    "istanbul": "^0.4.2",
++    "jscs": "^2.9.0",
++    "jshint": "^2.6.0",
++    "mocha": "^2.1.0"
++  },
++  "dependencies": {
++    "bn.js": "^4.4.0",
++    "brorand": "^1.0.1",
++    "hash.js": "^1.0.0",
++    "inherits": "^2.0.1"
++  }
++}
++
++},{}]},{},[2])(2)
++});
++
++// End of the imported code from elliptic.js.
++
++// Create the exported symbol for the JavaScript module.
++var elliptic = window.elliptic;
+\ No newline at end of file
+diff --git a/chat/protocols/irc/ircSASL.jsm b/chat/protocols/irc/ircSASL.jsm
+index 561f055e0..8a2bd70aa 100644
+--- a/chat/protocols/irc/ircSASL.jsm
++++ b/chat/protocols/irc/ircSASL.jsm
+@@ -14,6 +14,43 @@ var Cu = Components.utils;
+ 
+ Cu.import("resource:///modules/ircHandlers.jsm");
+ Cu.import("resource:///modules/ircUtils.jsm");
++Cu.import("resource:///modules/elliptic.jsm");
++
++/**
++
++  ECDSA-NIST256P-CHALLENGE
++
++  Paste the following code snippit in the Firefox web console to generate a
++  private key (logged as hex string) and the irc command to execute to set
++  the public key on the server.
++
++  crypto.subtle.generateKey({ name: "ECDSA", namedCurve: "P-256" }, true, ["sign"])
++  .then((kp) => {
++    crypto.subtle.exportKey("jwk", kp.privateKey).then((o) => {
++      // convert from base64url to hex string
++      let d = o.d;
++      let padLen = (4 - (d.length % 4)) % 4;
++      d = d.padEnd(d.length + padLen, "=")
++           .replace(/\-/g, "+")
++           .replace(/_/g, "/");
++      let str = atob(d);
++      let a = Array.prototype.map.call(str, (x) => x.charCodeAt(0));
++      let h = a.reduce((prev, next) => prev + next.toString(16), "");
++      console.log(h);
++    });
++    crypto.subtle.exportKey("raw", kp.publicKey).then((ab) => {
++      let v = new Uint8Array(ab);
++      let u = v.slice(0, 33);  // +1 here for the compressed point
++      u[0] = 2 + (v[v.length - 1] & 1);
++      let s = String.fromCharCode.apply(null, u);
++      console.log("/msg nickserv set property pubkey", btoa(s));
++    });
++  });
++
++  Then, copy the private key to the preference `messenger.account.accountN.ecdsa`
++  in the config editor.
++
++*/
+ 
+ var ircSASL = {
+   name: "SASL AUTHENTICATE",
+@@ -22,23 +59,41 @@ var ircSASL = {
+ 
+   commands: {
+     "AUTHENTICATE": function(aMessage) {
+-      // Expect an empty response, if something different is received abort.
+-      if (aMessage.params[0] != "+") {
++      let ecdsa = this.imAccount.wrappedJSObject.prefBranch.getCharPref("ecdsa");
++      let hasECDSA = !!ecdsa.length;
++
++      if (aMessage.params[0] === "+") {
++        // An authentication identity, authorization identity and password are
++        // used, separated by null.
++        let data = [this._requestedNickname, this._requestedNickname];
++        if (!hasECDSA) data.push(this.imAccount.password);
++        // btoa for Unicode, see https://developer.mozilla.org/en-US/docs/DOM/window.btoa
++        let base64Data = btoa(unescape(encodeURIComponent(data.join("\0"))));
++        this.sendMessage("AUTHENTICATE", base64Data);
++        return true;
++      } else if (hasECDSA) {
++        let challenge = aMessage.params[0];
++
++        let EC = elliptic.ec;
++        let ec = new EC('p256');
++        let key = ec.keyFromPrivate(ecdsa, 'hex');
++
++        let str = atob(challenge);
++        let arr = Array.prototype.map.call(str, (x) => x.charCodeAt(0));
++
++        let signature = key.sign(arr);
++        let der = String.fromCharCode.apply(null, signature.toDER());
++        let response = btoa(der);
++
++        this.sendMessage("AUTHENTICATE", response);
++        return true;
++      } else {
++        // Expect an empty response, if something different is received abort.
+         this.sendMessage("AUTHENTICATE", "*");
+         this.WARN("Aborting SASL authentication, unexpected message " +
+                   "received:\n" + aMessage.rawMessage);
+         return true;
+       }
+-
+-      // An authentication identity, authorization identity and password are
+-      // used, separated by null.
+-      let data = [this._requestedNickname, this._requestedNickname,
+-                  this.imAccount.password].join("\0");
+-      // btoa for Unicode, see https://developer.mozilla.org/en-US/docs/DOM/window.btoa
+-      let base64Data = btoa(unescape(encodeURIComponent(data)));
+-      this.sendMessage("AUTHENTICATE", base64Data,
+-                       "AUTHENTICATE <base64 encoded nick, user and password not logged>");
+-      return true;
+     },
+ 
+     "900": function(aMessage) {
+@@ -130,7 +185,10 @@ var capSASL = {
+ 
+   commands: {
+     "sasl": function(aMessage) {
+-      if (aMessage.cap.subcommand == "LS" && this.imAccount.password) {
++      let ecdsa = this.imAccount.wrappedJSObject.prefBranch.getCharPref("ecdsa");
++      let hasECDSA = !!ecdsa.length;
++
++      if (aMessage.cap.subcommand == "LS" && (this.imAccount.password || hasECDSA)) {
+         // If it supports SASL, let the server know we're requiring SASL.
+         this.sendMessage("CAP", ["REQ", "sasl"]);
+         this.addCAP("sasl");
+@@ -138,7 +196,8 @@ var capSASL = {
+       else if (aMessage.cap.subcommand == "ACK") {
+         // The server acknowledges our choice to use SASL, send the first
+         // message.
+-        this.sendMessage("AUTHENTICATE", "PLAIN");
++        this.sendMessage("AUTHENTICATE",
++          hasECDSA ? "ECDSA-NIST256P-CHALLENGE" : "PLAIN");
+       }
+ 
+       return true;
+diff --git a/chat/protocols/irc/moz.build b/chat/protocols/irc/moz.build
+index bc2539687..e46815dfe 100644
+--- a/chat/protocols/irc/moz.build
++++ b/chat/protocols/irc/moz.build
+@@ -11,6 +11,7 @@ EXTRA_COMPONENTS += [
+ ]
+ 
+ EXTRA_JS_MODULES += [
++    'elliptic.jsm',
+     'ircBase.jsm',
+     'ircCAP.jsm',
+     'ircCommands.jsm',
+-- 
+2.11.0
+
diff --git a/projects/instantbird/0020-Trac-17480-Content-sink.patch b/projects/instantbird/0020-Trac-17480-Content-sink.patch
deleted file mode 100644
index 08c3b6b..0000000
--- a/projects/instantbird/0020-Trac-17480-Content-sink.patch
+++ /dev/null
@@ -1,111 +0,0 @@
-From 23de5560f17e825ff1c1f9595c8ac92eca45017d Mon Sep 17 00:00:00 2001
-From: Arlo Breault <arlolra at gmail.com>
-Date: Wed, 5 Oct 2016 11:09:25 -0700
-Subject: [PATCH 20/27] Trac 17480: Content sink
-
----
- chat/modules/imContentSink.jsm     | 33 ++++++---------------------------
- im/content/preferences/content.xul |  2 +-
- 2 files changed, 7 insertions(+), 28 deletions(-)
-
-diff --git a/chat/modules/imContentSink.jsm b/chat/modules/imContentSink.jsm
-index abd95fc71..fa32442e4 100644
---- a/chat/modules/imContentSink.jsm
-+++ b/chat/modules/imContentSink.jsm
-@@ -42,7 +42,7 @@ this.EXPORTED_SYMBOLS = [
-  *  See the 3 examples of rulesets below.
-  */
- 
--var kAllowedURLs = aValue => /^(https?|ftp|mailto):/.test(aValue);
-+var kAllowedURLs = aValue => /^(https?|mailto):/.test(aValue);
- var kAllowedMozClasses =
-   aClassName => aClassName == "moz-txt-underscore" ||
-                 aClassName == "moz-txt-tag" ||
-@@ -60,11 +60,6 @@ var kStrictMode = {
-   attrs: { },
- 
-   tags: {
--    'a': {
--      'title': true,
--      'href': kAllowedURLs,
--      'class': kAllowedAnchorClasses
--    },
-     'br': true,
-     'p': true
-   },
-@@ -74,12 +69,9 @@ var kStrictMode = {
- 
- // standard mode allows basic formattings (bold, italic, underlined)
- var kStandardMode = {
--  attrs: {
--    'style': true
--  },
-+  attrs: { },
- 
-   tags: {
--    'div': true,
-     'a': {
-       'title': true,
-       'href': kAllowedURLs,
-@@ -90,24 +82,11 @@ var kStandardMode = {
-     'b': true,
-     'i': true,
-     'u': true,
--    'span': {
--      'class': kAllowedMozClasses
--    },
-     'br': true,
--    'code': true,
--    'ul': true,
--    'li': true,
--    'ol': true,
--    'cite': true,
--    'blockquote': true,
-     'p': true
-   },
- 
--  styles: {
--    'font-style': true,
--    'font-weight': true,
--    'text-decoration-line': true
--  }
-+  styles: { }
- };
- 
- // permissive mode allows about anything that isn't going to mess up the chat window
-@@ -162,7 +141,7 @@ var kPermissiveMode = {
- };
- 
- var kModePref = "messenger.options.filterMode";
--var kModes = [kStrictMode, kStandardMode, kPermissiveMode];
-+var kModes = [kStrictMode, kStandardMode];
- 
- var gGlobalRuleset = null;
- 
-@@ -188,8 +167,8 @@ var styleObserver = {
- function getModePref()
- {
-   let baseNum = Services.prefs.getIntPref(kModePref);
--  if (baseNum < 0 || baseNum > 2)
--    baseNum = 1;
-+  if (baseNum < 0 || baseNum > 1)
-+    baseNum = 0;
- 
-   return kModes[baseNum];
- }
-diff --git a/im/content/preferences/content.xul b/im/content/preferences/content.xul
-index 3b8ccfa2b..ba41da76a 100644
---- a/im/content/preferences/content.xul
-+++ b/im/content/preferences/content.xul
-@@ -35,7 +35,7 @@
-       <label control="filterLevel" accesskey="&filterLevel.accesskey;">&filterLevel.label;</label>
-       <menulist id="filterLevel" preference="messenger.options.filterMode">
-         <menupopup>
--          <menuitem value="2" label="&filterLevelAll;"/>
-+          <!-- <menuitem value="2" label="&filterLevelAll;"/> -->
-           <menuitem value="1" label="&filterLevelBasic;"/>
-           <menuitem value="0" label="&filterLevelNone;"/>
-         </menupopup>
--- 
-2.11.0
-
diff --git a/projects/instantbird/0021-Bug-1313137-msg-is-not-defined-error-in-irc.js-chang.patch b/projects/instantbird/0021-Bug-1313137-msg-is-not-defined-error-in-irc.js-chang.patch
new file mode 100644
index 0000000..7ba6a0d
--- /dev/null
+++ b/projects/instantbird/0021-Bug-1313137-msg-is-not-defined-error-in-irc.js-chang.patch
@@ -0,0 +1,29 @@
+From f11d397c27deb2f34b069e4c6c952793fc67657c Mon Sep 17 00:00:00 2001
+From: aleth <aleth at instantbird.org>
+Date: Wed, 26 Oct 2016 20:16:58 +0200
+Subject: [PATCH 21/26] Bug 1313137 - "msg is not defined" error in
+ irc.js:changeBuddyNick. r=clokep
+
+--HG--
+extra : rebase_source : 5752a69059ecd48b947809ef12de177ccab8528f
+---
+ chat/protocols/irc/irc.js | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/chat/protocols/irc/irc.js b/chat/protocols/irc/irc.js
+index c2167a5ec..b58c2c2eb 100644
+--- a/chat/protocols/irc/irc.js
++++ b/chat/protocols/irc/irc.js
+@@ -1289,7 +1289,8 @@ ircAccount.prototype = {
+       this.conversations.set(aNewNick, conversation);
+ 
+       conversation.updateNick(aNewNick);
+-      conversation.writeMessage(aOldNick, msg, {system: true});
++      conversation.writeMessage(aOldNick, _conv("nickSet", aOldNick, aNewNick),
++                                {system: true});
+     }
+   },
+ 
+-- 
+2.11.0
+
diff --git a/projects/instantbird/0021-SASL-ECDSA-NIST256P-CHALLENGE.patch b/projects/instantbird/0021-SASL-ECDSA-NIST256P-CHALLENGE.patch
deleted file mode 100644
index e7fd09f..0000000
--- a/projects/instantbird/0021-SASL-ECDSA-NIST256P-CHALLENGE.patch
+++ /dev/null
@@ -1,8919 +0,0 @@
-From b9d9eccfeb4d08804a02b7d09576f14526c90ff0 Mon Sep 17 00:00:00 2001
-From: Arlo Breault <arlolra at gmail.com>
-Date: Sun, 2 Oct 2016 08:46:55 -0700
-Subject: [PATCH 21/27] SASL ECDSA-NIST256P-CHALLENGE
-
----
- chat/components/src/imAccounts.js |    1 +
- chat/protocols/irc/elliptic.jsm   | 8748 +++++++++++++++++++++++++++++++++++++
- chat/protocols/irc/ircSASL.jsm    |   87 +-
- chat/protocols/irc/moz.build      |    1 +
- 4 files changed, 8823 insertions(+), 14 deletions(-)
- create mode 100644 chat/protocols/irc/elliptic.jsm
-
-diff --git a/chat/components/src/imAccounts.js b/chat/components/src/imAccounts.js
-index 5bfea57f2..da8525ffd 100644
---- a/chat/components/src/imAccounts.js
-+++ b/chat/components/src/imAccounts.js
-@@ -193,6 +193,7 @@ function imAccount(aKey, aName, aPrplId)
- 
- imAccount.prototype = {
-   __proto__: ClassInfo(["imIAccount", "prplIAccount"], "im account object"),
-+  get wrappedJSObject() { return this; },
- 
-   name: "",
-   id: "",
-diff --git a/chat/protocols/irc/elliptic.jsm b/chat/protocols/irc/elliptic.jsm
-new file mode 100644
-index 000000000..bccab018c
---- /dev/null
-+++ b/chat/protocols/irc/elliptic.jsm
-@@ -0,0 +1,8748 @@
-+/* This software is licensed under the MIT License.
-+ *
-+ * Copyright Fedor Indutny, 2014.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a copy
-+ * of this software and associated documentation files (the "Software"), to deal
-+ * in the Software without restriction, including without limitation the rights
-+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-+ * copies of the Software, and to permit persons to whom the Software is
-+ * furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-+ * SOFTWARE.
-+ */
-+
-+this.EXPORTED_SYMBOLS = ["elliptic"];
-+
-+var window = {};
-+
-+// The code below is imported from indutny's elliptic.js.  The original version
-+// of this file can be found at
-+// https://github.com/indutny/elliptic/blob/master/dist/elliptic.js
-+
-+(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.elliptic = 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<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
-+(function (module, exports) {
-+  'use strict';
-+
-+  // Utils
-+  function assert (val, msg) {
-+    if (!val) throw new Error(msg || 'Assertion failed');
-+  }
-+
-+  // Could use `inherits` module, but don't want to move from single file
-+  // architecture yet.
-+  function inherits (ctor, superCtor) {
-+    ctor.super_ = superCtor;
-+    var TempCtor = function () {};
-+    TempCtor.prototype = superCtor.prototype;
-+    ctor.prototype = new TempCtor();
-+    ctor.prototype.constructor = ctor;
-+  }
-+
-+  // BN
-+
-+  function BN (number, base, endian) {
-+    if (BN.isBN(number)) {
-+      return number;
-+    }
-+
-+    this.negative = 0;
-+    this.words = null;
-+    this.length = 0;
-+
-+    // Reduction context
-+    this.red = null;
-+
-+    if (number !== null) {
-+      if (base === 'le' || base === 'be') {
-+        endian = base;
-+        base = 10;
-+      }
-+
-+      this._init(number || 0, base || 10, endian || 'be');
-+    }
-+  }
-+  if (typeof module === 'object') {
-+    module.exports = BN;
-+  } else {
-+    exports.BN = BN;
-+  }
-+
-+  BN.BN = BN;
-+  BN.wordSize = 26;
-+
-+  var Buffer;
-+  try {
-+    Buffer = require('buf' + 'fer').Buffer;
-+  } catch (e) {
-+  }
-+
-+  BN.isBN = function isBN (num) {
-+    if (num instanceof BN) {
-+      return true;
-+    }
-+
-+    return num !== null && typeof num === 'object' &&
-+      num.constructor.wordSize === BN.wordSize && Array.isArray(num.words);
-+  };
-+
-+  BN.max = function max (left, right) {
-+    if (left.cmp(right) > 0) return left;
-+    return right;
-+  };
-+
-+  BN.min = function min (left, right) {
-+    if (left.cmp(right) < 0) return left;
-+    return right;
-+  };
-+
-+  BN.prototype._init = function init (number, base, endian) {
-+    if (typeof number === 'number') {
-+      return this._initNumber(number, base, endian);
-+    }
-+
-+    if (typeof number === 'object') {
-+      return this._initArray(number, base, endian);
-+    }
-+
-+    if (base === 'hex') {
-+      base = 16;
-+    }
-+    assert(base === (base | 0) && base >= 2 && base <= 36);
-+
-+    number = number.toString().replace(/\s+/g, '');
-+    var start = 0;
-+    if (number[0] === '-') {
-+      start++;
-+    }
-+
-+    if (base === 16) {
-+      this._parseHex(number, start);
-+    } else {
-+      this._parseBase(number, base, start);
-+    }
-+
-+    if (number[0] === '-') {
-+      this.negative = 1;
-+    }
-+
-+    this.strip();
-+
-+    if (endian !== 'le') return;
-+
-+    this._initArray(this.toArray(), base, endian);
-+  };
-+
-+  BN.prototype._initNumber = function _initNumber (number, base, endian) {
-+    if (number < 0) {
-+      this.negative = 1;
-+      number = -number;
-+    }
-+    if (number < 0x4000000) {
-+      this.words = [ number & 0x3ffffff ];
-+      this.length = 1;
-+    } else if (number < 0x10000000000000) {
-+      this.words = [
-+        number & 0x3ffffff,
-+        (number / 0x4000000) & 0x3ffffff
-+      ];
-+      this.length = 2;
-+    } else {
-+      assert(number < 0x20000000000000); // 2 ^ 53 (unsafe)
-+      this.words = [
-+        number & 0x3ffffff,
-+        (number / 0x4000000) & 0x3ffffff,
-+        1
-+      ];
-+      this.length = 3;
-+    }
-+
-+    if (endian !== 'le') return;
-+
-+    // Reverse the bytes
-+    this._initArray(this.toArray(), base, endian);
-+  };
-+
-+  BN.prototype._initArray = function _initArray (number, base, endian) {
-+    // Perhaps a Uint8Array
-+    assert(typeof number.length === 'number');
-+    if (number.length <= 0) {
-+      this.words = [ 0 ];
-+      this.length = 1;
-+      return this;
-+    }
-+
-+    this.length = Math.ceil(number.length / 3);
-+    this.words = new Array(this.length);
-+    for (var i = 0; i < this.length; i++) {
-+      this.words[i] = 0;
-+    }
-+
-+    var j, w;
-+    var off = 0;
-+    if (endian === 'be') {
-+      for (i = number.length - 1, j = 0; i >= 0; i -= 3) {
-+        w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16);
-+        this.words[j] |= (w << off) & 0x3ffffff;
-+        this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
-+        off += 24;
-+        if (off >= 26) {
-+          off -= 26;
-+          j++;
-+        }
-+      }
-+    } else if (endian === 'le') {
-+      for (i = 0, j = 0; i < number.length; i += 3) {
-+        w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16);
-+        this.words[j] |= (w << off) & 0x3ffffff;
-+        this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
-+        off += 24;
-+        if (off >= 26) {
-+          off -= 26;
-+          j++;
-+        }
-+      }
-+    }
-+    return this.strip();
-+  };
-+
-+  function parseHex (str, start, end) {
-+    var r = 0;
-+    var len = Math.min(str.length, end);
-+    for (var i = start; i < len; i++) {
-+      var c = str.charCodeAt(i) - 48;
-+
-+      r <<= 4;
-+
-+      // 'a' - 'f'
-+      if (c >= 49 && c <= 54) {
-+        r |= c - 49 + 0xa;
-+
-+      // 'A' - 'F'
-+      } else if (c >= 17 && c <= 22) {
-+        r |= c - 17 + 0xa;
-+
-+      // '0' - '9'
-+      } else {
-+        r |= c & 0xf;
-+      }
-+    }
-+    return r;
-+  }
-+
-+  BN.prototype._parseHex = function _parseHex (number, start) {
-+    // Create possibly bigger array to ensure that it fits the number
-+    this.length = Math.ceil((number.length - start) / 6);
-+    this.words = new Array(this.length);
-+    for (var i = 0; i < this.length; i++) {
-+      this.words[i] = 0;
-+    }
-+
-+    var j, w;
-+    // Scan 24-bit chunks and add them to the number
-+    var off = 0;
-+    for (i = number.length - 6, j = 0; i >= start; i -= 6) {
-+      w = parseHex(number, i, i + 6);
-+      this.words[j] |= (w << off) & 0x3ffffff;
-+      // NOTE: `0x3fffff` is intentional here, 26bits max shift + 24bit hex limb
-+      this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
-+      off += 24;
-+      if (off >= 26) {
-+        off -= 26;
-+        j++;
-+      }
-+    }
-+    if (i + 6 !== start) {
-+      w = parseHex(number, start, i + 6);
-+      this.words[j] |= (w << off) & 0x3ffffff;
-+      this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
-+    }
-+    this.strip();
-+  };
-+
-+  function parseBase (str, start, end, mul) {
-+    var r = 0;
-+    var len = Math.min(str.length, end);
-+    for (var i = start; i < len; i++) {
-+      var c = str.charCodeAt(i) - 48;
-+
-+      r *= mul;
-+
-+      // 'a'
-+      if (c >= 49) {
-+        r += c - 49 + 0xa;
-+
-+      // 'A'
-+      } else if (c >= 17) {
-+        r += c - 17 + 0xa;
-+
-+      // '0' - '9'
-+      } else {
-+        r += c;
-+      }
-+    }
-+    return r;
-+  }
-+
-+  BN.prototype._parseBase = function _parseBase (number, base, start) {
-+    // Initialize as zero
-+    this.words = [ 0 ];
-+    this.length = 1;
-+
-+    // Find length of limb in base
-+    for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) {
-+      limbLen++;
-+    }
-+    limbLen--;
-+    limbPow = (limbPow / base) | 0;
-+
-+    var total = number.length - start;
-+    var mod = total % limbLen;
-+    var end = Math.min(total, total - mod) + start;
-+
-+    var word = 0;
-+    for (var i = start; i < end; i += limbLen) {
-+      word = parseBase(number, i, i + limbLen, base);
-+
-+      this.imuln(limbPow);
-+      if (this.words[0] + word < 0x4000000) {
-+        this.words[0] += word;
-+      } else {
-+        this._iaddn(word);
-+      }
-+    }
-+
-+    if (mod !== 0) {
-+      var pow = 1;
-+      word = parseBase(number, i, number.length, base);
-+
-+      for (i = 0; i < mod; i++) {
-+        pow *= base;
-+      }
-+
-+      this.imuln(pow);
-+      if (this.words[0] + word < 0x4000000) {
-+        this.words[0] += word;
-+      } else {
-+        this._iaddn(word);
-+      }
-+    }
-+  };
-+
-+  BN.prototype.copy = function copy (dest) {
-+    dest.words = new Array(this.length);
-+    for (var i = 0; i < this.length; i++) {
-+      dest.words[i] = this.words[i];
-+    }
-+    dest.length = this.length;
-+    dest.negative = this.negative;
-+    dest.red = this.red;
-+  };
-+
-+  BN.prototype.clone = function clone () {
-+    var r = new BN(null);
-+    this.copy(r);
-+    return r;
-+  };
-+
-+  BN.prototype._expand = function _expand (size) {
-+    while (this.length < size) {
-+      this.words[this.length++] = 0;
-+    }
-+    return this;
-+  };
-+
-+  // Remove leading `0` from `this`
-+  BN.prototype.strip = function strip () {
-+    while (this.length > 1 && this.words[this.length - 1] === 0) {
-+      this.length--;
-+    }
-+    return this._normSign();
-+  };
-+
-+  BN.prototype._normSign = function _normSign () {
-+    // -0 = 0
-+    if (this.length === 1 && this.words[0] === 0) {
-+      this.negative = 0;
-+    }
-+    return this;
-+  };
-+
-+  BN.prototype.inspect = function inspect () {
-+    return (this.red ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>';
-+  };
-+
-+  /*
-+
-+  var zeros = [];
-+  var groupSizes = [];
-+  var groupBases = [];
-+
-+  var s = '';
-+  var i = -1;
-+  while (++i < BN.wordSize) {
-+    zeros[i] = s;
-+    s += '0';
-+  }
-+  groupSizes[0] = 0;
-+  groupSizes[1] = 0;
-+  groupBases[0] = 0;
-+  groupBases[1] = 0;
-+  var base = 2 - 1;
-+  while (++base < 36 + 1) {
-+    var groupSize = 0;
-+    var groupBase = 1;
-+    while (groupBase < (1 << BN.wordSize) / base) {
-+      groupBase *= base;
-+      groupSize += 1;
-+    }
-+    groupSizes[base] = groupSize;
-+    groupBases[base] = groupBase;
-+  }
-+
-+  */
-+
-+  var zeros = [
-+    '',
-+    '0',
-+    '00',
-+    '000',
-+    '0000',
-+    '00000',
-+    '000000',
-+    '0000000',
-+    '00000000',
-+    '000000000',
-+    '0000000000',
-+    '00000000000',
-+    '000000000000',
-+    '0000000000000',
-+    '00000000000000',
-+    '000000000000000',
-+    '0000000000000000',
-+    '00000000000000000',
-+    '000000000000000000',
-+    '0000000000000000000',
-+    '00000000000000000000',
-+    '000000000000000000000',
-+    '0000000000000000000000',
-+    '00000000000000000000000',
-+    '000000000000000000000000',
-+    '0000000000000000000000000'
-+  ];
-+
-+  var groupSizes = [
-+    0, 0,
-+    25, 16, 12, 11, 10, 9, 8,
-+    8, 7, 7, 7, 7, 6, 6,
-+    6, 6, 6, 6, 6, 5, 5,
-+    5, 5, 5, 5, 5, 5, 5,
-+    5, 5, 5, 5, 5, 5, 5
-+  ];
-+
-+  var groupBases = [
-+    0, 0,
-+    33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216,
-+    43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625,
-+    16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632,
-+    6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149,
-+    24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176
-+  ];
-+
-+  BN.prototype.toString = function toString (base, padding) {
-+    base = base || 10;
-+    padding = padding | 0 || 1;
-+
-+    var out;
-+    if (base === 16 || base === 'hex') {
-+      out = '';
-+      var off = 0;
-+      var carry = 0;
-+      for (var i = 0; i < this.length; i++) {
-+        var w = this.words[i];
-+        var word = (((w << off) | carry) & 0xffffff).toString(16);
-+        carry = (w >>> (24 - off)) & 0xffffff;
-+        if (carry !== 0 || i !== this.length - 1) {
-+          out = zeros[6 - word.length] + word + out;
-+        } else {
-+          out = word + out;
-+        }
-+        off += 2;
-+        if (off >= 26) {
-+          off -= 26;
-+          i--;
-+        }
-+      }
-+      if (carry !== 0) {
-+        out = carry.toString(16) + out;
-+      }
-+      while (out.length % padding !== 0) {
-+        out = '0' + out;
-+      }
-+      if (this.negative !== 0) {
-+        out = '-' + out;
-+      }
-+      return out;
-+    }
-+
-+    if (base === (base | 0) && base >= 2 && base <= 36) {
-+      // var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base));
-+      var groupSize = groupSizes[base];
-+      // var groupBase = Math.pow(base, groupSize);
-+      var groupBase = groupBases[base];
-+      out = '';
-+      var c = this.clone();
-+      c.negative = 0;
-+      while (!c.isZero()) {
-+        var r = c.modn(groupBase).toString(base);
-+        c = c.idivn(groupBase);
-+
-+        if (!c.isZero()) {
-+          out = zeros[groupSize - r.length] + r + out;
-+        } else {
-+          out = r + out;
-+        }
-+      }
-+      if (this.isZero()) {
-+        out = '0' + out;
-+      }
-+      while (out.length % padding !== 0) {
-+        out = '0' + out;
-+      }
-+      if (this.negative !== 0) {
-+        out = '-' + out;
-+      }
-+      return out;
-+    }
-+
-+    assert(false, 'Base should be between 2 and 36');
-+  };
-+
-+  BN.prototype.toNumber = function toNumber () {
-+    var ret = this.words[0];
-+    if (this.length === 2) {
-+      ret += this.words[1] * 0x4000000;
-+    } else if (this.length === 3 && this.words[2] === 0x01) {
-+      // NOTE: at this stage it is known that the top bit is set
-+      ret += 0x10000000000000 + (this.words[1] * 0x4000000);
-+    } else if (this.length > 2) {
-+      assert(false, 'Number can only safely store up to 53 bits');
-+    }
-+    return (this.negative !== 0) ? -ret : ret;
-+  };
-+
-+  BN.prototype.toJSON = function toJSON () {
-+    return this.toString(16);
-+  };
-+
-+  BN.prototype.toBuffer = function toBuffer (endian, length) {
-+    assert(typeof Buffer !== 'undefined');
-+    return this.toArrayLike(Buffer, endian, length);
-+  };
-+
-+  BN.prototype.toArray = function toArray (endian, length) {
-+    return this.toArrayLike(Array, endian, length);
-+  };
-+
-+  BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) {
-+    var byteLength = this.byteLength();
-+    var reqLength = length || Math.max(1, byteLength);
-+    assert(byteLength <= reqLength, 'byte array longer than desired length');
-+    assert(reqLength > 0, 'Requested array length <= 0');
-+
-+    this.strip();
-+    var littleEndian = endian === 'le';
-+    var res = new ArrayType(reqLength);
-+
-+    var b, i;
-+    var q = this.clone();
-+    if (!littleEndian) {
-+      // Assume big-endian
-+      for (i = 0; i < reqLength - byteLength; i++) {
-+        res[i] = 0;
-+      }
-+
-+      for (i = 0; !q.isZero(); i++) {
-+        b = q.andln(0xff);
-+        q.iushrn(8);
-+
-+        res[reqLength - i - 1] = b;
-+      }
-+    } else {
-+      for (i = 0; !q.isZero(); i++) {
-+        b = q.andln(0xff);
-+        q.iushrn(8);
-+
-+        res[i] = b;
-+      }
-+
-+      for (; i < reqLength; i++) {
-+        res[i] = 0;
-+      }
-+    }
-+
-+    return res;
-+  };
-+
-+  if (Math.clz32) {
-+    BN.prototype._countBits = function _countBits (w) {
-+      return 32 - Math.clz32(w);
-+    };
-+  } else {
-+    BN.prototype._countBits = function _countBits (w) {
-+      var t = w;
-+      var r = 0;
-+      if (t >= 0x1000) {
-+        r += 13;
-+        t >>>= 13;
-+      }
-+      if (t >= 0x40) {
-+        r += 7;
-+        t >>>= 7;
-+      }
-+      if (t >= 0x8) {
-+        r += 4;
-+        t >>>= 4;
-+      }
-+      if (t >= 0x02) {
-+        r += 2;
-+        t >>>= 2;
-+      }
-+      return r + t;
-+    };
-+  }
-+
-+  BN.prototype._zeroBits = function _zeroBits (w) {
-+    // Short-cut
-+    if (w === 0) return 26;
-+
-+    var t = w;
-+    var r = 0;
-+    if ((t & 0x1fff) === 0) {
-+      r += 13;
-+      t >>>= 13;
-+    }
-+    if ((t & 0x7f) === 0) {
-+      r += 7;
-+      t >>>= 7;
-+    }
-+    if ((t & 0xf) === 0) {
-+      r += 4;
-+      t >>>= 4;
-+    }
-+    if ((t & 0x3) === 0) {
-+      r += 2;
-+      t >>>= 2;
-+    }
-+    if ((t & 0x1) === 0) {
-+      r++;
-+    }
-+    return r;
-+  };
-+
-+  // Return number of used bits in a BN
-+  BN.prototype.bitLength = function bitLength () {
-+    var w = this.words[this.length - 1];
-+    var hi = this._countBits(w);
-+    return (this.length - 1) * 26 + hi;
-+  };
-+
-+  function toBitArray (num) {
-+    var w = new Array(num.bitLength());
-+
-+    for (var bit = 0; bit < w.length; bit++) {
-+      var off = (bit / 26) | 0;
-+      var wbit = bit % 26;
-+
-+      w[bit] = (num.words[off] & (1 << wbit)) >>> wbit;
-+    }
-+
-+    return w;
-+  }
-+
-+  // Number of trailing zero bits
-+  BN.prototype.zeroBits = function zeroBits () {
-+    if (this.isZero()) return 0;
-+
-+    var r = 0;
-+    for (var i = 0; i < this.length; i++) {
-+      var b = this._zeroBits(this.words[i]);
-+      r += b;
-+      if (b !== 26) break;
-+    }
-+    return r;
-+  };
-+
-+  BN.prototype.byteLength = function byteLength () {
-+    return Math.ceil(this.bitLength() / 8);
-+  };
-+
-+  BN.prototype.toTwos = function toTwos (width) {
-+    if (this.negative !== 0) {
-+      return this.abs().inotn(width).iaddn(1);
-+    }
-+    return this.clone();
-+  };
-+
-+  BN.prototype.fromTwos = function fromTwos (width) {
-+    if (this.testn(width - 1)) {
-+      return this.notn(width).iaddn(1).ineg();
-+    }
-+    return this.clone();
-+  };
-+
-+  BN.prototype.isNeg = function isNeg () {
-+    return this.negative !== 0;
-+  };
-+
-+  // Return negative clone of `this`
-+  BN.prototype.neg = function neg () {
-+    return this.clone().ineg();
-+  };
-+
-+  BN.prototype.ineg = function ineg () {
-+    if (!this.isZero()) {
-+      this.negative ^= 1;
-+    }
-+
-+    return this;
-+  };
-+
-+  // Or `num` with `this` in-place
-+  BN.prototype.iuor = function iuor (num) {
-+    while (this.length < num.length) {
-+      this.words[this.length++] = 0;
-+    }
-+
-+    for (var i = 0; i < num.length; i++) {
-+      this.words[i] = this.words[i] | num.words[i];
-+    }
-+
-+    return this.strip();
-+  };
-+
-+  BN.prototype.ior = function ior (num) {
-+    assert((this.negative | num.negative) === 0);
-+    return this.iuor(num);
-+  };
-+
-+  // Or `num` with `this`
-+  BN.prototype.or = function or (num) {
-+    if (this.length > num.length) return this.clone().ior(num);
-+    return num.clone().ior(this);
-+  };
-+
-+  BN.prototype.uor = function uor (num) {
-+    if (this.length > num.length) return this.clone().iuor(num);
-+    return num.clone().iuor(this);
-+  };
-+
-+  // And `num` with `this` in-place
-+  BN.prototype.iuand = function iuand (num) {
-+    // b = min-length(num, this)
-+    var b;
-+    if (this.length > num.length) {
-+      b = num;
-+    } else {
-+      b = this;
-+    }
-+
-+    for (var i = 0; i < b.length; i++) {
-+      this.words[i] = this.words[i] & num.words[i];
-+    }
-+
-+    this.length = b.length;
-+
-+    return this.strip();
-+  };
-+
-+  BN.prototype.iand = function iand (num) {
-+    assert((this.negative | num.negative) === 0);
-+    return this.iuand(num);
-+  };
-+
-+  // And `num` with `this`
-+  BN.prototype.and = function and (num) {
-+    if (this.length > num.length) return this.clone().iand(num);
-+    return num.clone().iand(this);
-+  };
-+
-+  BN.prototype.uand = function uand (num) {
-+    if (this.length > num.length) return this.clone().iuand(num);
-+    return num.clone().iuand(this);
-+  };
-+
-+  // Xor `num` with `this` in-place
-+  BN.prototype.iuxor = function iuxor (num) {
-+    // a.length > b.length
-+    var a;
-+    var b;
-+    if (this.length > num.length) {
-+      a = this;
-+      b = num;
-+    } else {
-+      a = num;
-+      b = this;
-+    }
-+
-+    for (var i = 0; i < b.length; i++) {
-+      this.words[i] = a.words[i] ^ b.words[i];
-+    }
-+
-+    if (this !== a) {
-+      for (; i < a.length; i++) {
-+        this.words[i] = a.words[i];
-+      }
-+    }
-+
-+    this.length = a.length;
-+
-+    return this.strip();
-+  };
-+
-+  BN.prototype.ixor = function ixor (num) {
-+    assert((this.negative | num.negative) === 0);
-+    return this.iuxor(num);
-+  };
-+
-+  // Xor `num` with `this`
-+  BN.prototype.xor = function xor (num) {
-+    if (this.length > num.length) return this.clone().ixor(num);
-+    return num.clone().ixor(this);
-+  };
-+
-+  BN.prototype.uxor = function uxor (num) {
-+    if (this.length > num.length) return this.clone().iuxor(num);
-+    return num.clone().iuxor(this);
-+  };
-+
-+  // Not ``this`` with ``width`` bitwidth
-+  BN.prototype.inotn = function inotn (width) {
-+    assert(typeof width === 'number' && width >= 0);
-+
-+    var bytesNeeded = Math.ceil(width / 26) | 0;
-+    var bitsLeft = width % 26;
-+
-+    // Extend the buffer with leading zeroes
-+    this._expand(bytesNeeded);
-+
-+    if (bitsLeft > 0) {
-+      bytesNeeded--;
-+    }
-+
-+    // Handle complete words
-+    for (var i = 0; i < bytesNeeded; i++) {
-+      this.words[i] = ~this.words[i] & 0x3ffffff;
-+    }
-+
-+    // Handle the residue
-+    if (bitsLeft > 0) {
-+      this.words[i] = ~this.words[i] & (0x3ffffff >> (26 - bitsLeft));
-+    }
-+
-+    // And remove leading zeroes
-+    return this.strip();
-+  };
-+
-+  BN.prototype.notn = function notn (width) {
-+    return this.clone().inotn(width);
-+  };
-+
-+  // Set `bit` of `this`
-+  BN.prototype.setn = function setn (bit, val) {
-+    assert(typeof bit === 'number' && bit >= 0);
-+
-+    var off = (bit / 26) | 0;
-+    var wbit = bit % 26;
-+
-+    this._expand(off + 1);
-+
-+    if (val) {
-+      this.words[off] = this.words[off] | (1 << wbit);
-+    } else {
-+      this.words[off] = this.words[off] & ~(1 << wbit);
-+    }
-+
-+    return this.strip();
-+  };
-+
-+  // Add `num` to `this` in-place
-+  BN.prototype.iadd = function iadd (num) {
-+    var r;
-+
-+    // negative + positive
-+    if (this.negative !== 0 && num.negative === 0) {
-+      this.negative = 0;
-+      r = this.isub(num);
-+      this.negative ^= 1;
-+      return this._normSign();
-+
-+    // positive + negative
-+    } else if (this.negative === 0 && num.negative !== 0) {
-+      num.negative = 0;
-+      r = this.isub(num);
-+      num.negative = 1;
-+      return r._normSign();
-+    }
-+
-+    // a.length > b.length
-+    var a, b;
-+    if (this.length > num.length) {
-+      a = this;
-+      b = num;
-+    } else {
-+      a = num;
-+      b = this;
-+    }
-+
-+    var carry = 0;
-+    for (var i = 0; i < b.length; i++) {
-+      r = (a.words[i] | 0) + (b.words[i] | 0) + carry;
-+      this.words[i] = r & 0x3ffffff;
-+      carry = r >>> 26;
-+    }
-+    for (; carry !== 0 && i < a.length; i++) {
-+      r = (a.words[i] | 0) + carry;
-+      this.words[i] = r & 0x3ffffff;
-+      carry = r >>> 26;
-+    }
-+
-+    this.length = a.length;
-+    if (carry !== 0) {
-+      this.words[this.length] = carry;
-+      this.length++;
-+    // Copy the rest of the words
-+    } else if (a !== this) {
-+      for (; i < a.length; i++) {
-+        this.words[i] = a.words[i];
-+      }
-+    }
-+
-+    return this;
-+  };
-+
-+  // Add `num` to `this`
-+  BN.prototype.add = function add (num) {
-+    var res;
-+    if (num.negative !== 0 && this.negative === 0) {
-+      num.negative = 0;
-+      res = this.sub(num);
-+      num.negative ^= 1;
-+      return res;
-+    } else if (num.negative === 0 && this.negative !== 0) {
-+      this.negative = 0;
-+      res = num.sub(this);
-+      this.negative = 1;
-+      return res;
-+    }
-+
-+    if (this.length > num.length) return this.clone().iadd(num);
-+
-+    return num.clone().iadd(this);
-+  };
-+
-+  // Subtract `num` from `this` in-place
-+  BN.prototype.isub = function isub (num) {
-+    // this - (-num) = this + num
-+    if (num.negative !== 0) {
-+      num.negative = 0;
-+      var r = this.iadd(num);
-+      num.negative = 1;
-+      return r._normSign();
-+
-+    // -this - num = -(this + num)
-+    } else if (this.negative !== 0) {
-+      this.negative = 0;
-+      this.iadd(num);
-+      this.negative = 1;
-+      return this._normSign();
-+    }
-+
-+    // At this point both numbers are positive
-+    var cmp = this.cmp(num);
-+
-+    // Optimization - zeroify
-+    if (cmp === 0) {
-+      this.negative = 0;
-+      this.length = 1;
-+      this.words[0] = 0;
-+      return this;
-+    }
-+
-+    // a > b
-+    var a, b;
-+    if (cmp > 0) {
-+      a = this;
-+      b = num;
-+    } else {
-+      a = num;
-+      b = this;
-+    }
-+
-+    var carry = 0;
-+    for (var i = 0; i < b.length; i++) {
-+      r = (a.words[i] | 0) - (b.words[i] | 0) + carry;
-+      carry = r >> 26;
-+      this.words[i] = r & 0x3ffffff;
-+    }
-+    for (; carry !== 0 && i < a.length; i++) {
-+      r = (a.words[i] | 0) + carry;
-+      carry = r >> 26;
-+      this.words[i] = r & 0x3ffffff;
-+    }
-+
-+    // Copy rest of the words
-+    if (carry === 0 && i < a.length && a !== this) {
-+      for (; i < a.length; i++) {
-+        this.words[i] = a.words[i];
-+      }
-+    }
-+
-+    this.length = Math.max(this.length, i);
-+
-+    if (a !== this) {
-+      this.negative = 1;
-+    }
-+
-+    return this.strip();
-+  };
-+
-+  // Subtract `num` from `this`
-+  BN.prototype.sub = function sub (num) {
-+    return this.clone().isub(num);
-+  };
-+
-+  function smallMulTo (self, num, out) {
-+    out.negative = num.negative ^ self.negative;
-+    var len = (self.length + num.length) | 0;
-+    out.length = len;
-+    len = (len - 1) | 0;
-+
-+    // Peel one iteration (compiler can't do it, because of code complexity)
-+    var a = self.words[0] | 0;
-+    var b = num.words[0] | 0;
-+    var r = a * b;
-+
-+    var lo = r & 0x3ffffff;
-+    var carry = (r / 0x4000000) | 0;
-+    out.words[0] = lo;
-+
-+    for (var k = 1; k < len; k++) {
-+      // Sum all words with the same `i + j = k` and accumulate `ncarry`,
-+      // note that ncarry could be >= 0x3ffffff
-+      var ncarry = carry >>> 26;
-+      var rword = carry & 0x3ffffff;
-+      var maxJ = Math.min(k, num.length - 1);
-+      for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
-+        var i = (k - j) | 0;
-+        a = self.words[i] | 0;
-+        b = num.words[j] | 0;
-+        r = a * b + rword;
-+        ncarry += (r / 0x4000000) | 0;
-+        rword = r & 0x3ffffff;
-+      }
-+      out.words[k] = rword | 0;
-+      carry = ncarry | 0;
-+    }
-+    if (carry !== 0) {
-+      out.words[k] = carry | 0;
-+    } else {
-+      out.length--;
-+    }
-+
-+    return out.strip();
-+  }
-+
-+  // TODO(indutny): it may be reasonable to omit it for users who don't need
-+  // to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit
-+  // multiplication (like elliptic secp256k1).
-+  var comb10MulTo = function comb10MulTo (self, num, out) {
-+    var a = self.words;
-+    var b = num.words;
-+    var o = out.words;
-+    var c = 0;
-+    var lo;
-+    var mid;
-+    var hi;
-+    var a0 = a[0] | 0;
-+    var al0 = a0 & 0x1fff;
-+    var ah0 = a0 >>> 13;
-+    var a1 = a[1] | 0;
-+    var al1 = a1 & 0x1fff;
-+    var ah1 = a1 >>> 13;
-+    var a2 = a[2] | 0;
-+    var al2 = a2 & 0x1fff;
-+    var ah2 = a2 >>> 13;
-+    var a3 = a[3] | 0;
-+    var al3 = a3 & 0x1fff;
-+    var ah3 = a3 >>> 13;
-+    var a4 = a[4] | 0;
-+    var al4 = a4 & 0x1fff;
-+    var ah4 = a4 >>> 13;
-+    var a5 = a[5] | 0;
-+    var al5 = a5 & 0x1fff;
-+    var ah5 = a5 >>> 13;
-+    var a6 = a[6] | 0;
-+    var al6 = a6 & 0x1fff;
-+    var ah6 = a6 >>> 13;
-+    var a7 = a[7] | 0;
-+    var al7 = a7 & 0x1fff;
-+    var ah7 = a7 >>> 13;
-+    var a8 = a[8] | 0;
-+    var al8 = a8 & 0x1fff;
-+    var ah8 = a8 >>> 13;
-+    var a9 = a[9] | 0;
-+    var al9 = a9 & 0x1fff;
-+    var ah9 = a9 >>> 13;
-+    var b0 = b[0] | 0;
-+    var bl0 = b0 & 0x1fff;
-+    var bh0 = b0 >>> 13;
-+    var b1 = b[1] | 0;
-+    var bl1 = b1 & 0x1fff;
-+    var bh1 = b1 >>> 13;
-+    var b2 = b[2] | 0;
-+    var bl2 = b2 & 0x1fff;
-+    var bh2 = b2 >>> 13;
-+    var b3 = b[3] | 0;
-+    var bl3 = b3 & 0x1fff;
-+    var bh3 = b3 >>> 13;
-+    var b4 = b[4] | 0;
-+    var bl4 = b4 & 0x1fff;
-+    var bh4 = b4 >>> 13;
-+    var b5 = b[5] | 0;
-+    var bl5 = b5 & 0x1fff;
-+    var bh5 = b5 >>> 13;
-+    var b6 = b[6] | 0;
-+    var bl6 = b6 & 0x1fff;
-+    var bh6 = b6 >>> 13;
-+    var b7 = b[7] | 0;
-+    var bl7 = b7 & 0x1fff;
-+    var bh7 = b7 >>> 13;
-+    var b8 = b[8] | 0;
-+    var bl8 = b8 & 0x1fff;
-+    var bh8 = b8 >>> 13;
-+    var b9 = b[9] | 0;
-+    var bl9 = b9 & 0x1fff;
-+    var bh9 = b9 >>> 13;
-+
-+    out.negative = self.negative ^ num.negative;
-+    out.length = 19;
-+    /* k = 0 */
-+    lo = Math.imul(al0, bl0);
-+    mid = Math.imul(al0, bh0);
-+    mid = (mid + Math.imul(ah0, bl0)) | 0;
-+    hi = Math.imul(ah0, bh0);
-+    var w0 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
-+    c = (((hi + (mid >>> 13)) | 0) + (w0 >>> 26)) | 0;
-+    w0 &= 0x3ffffff;
-+    /* k = 1 */
-+    lo = Math.imul(al1, bl0);
-+    mid = Math.imul(al1, bh0);
-+    mid = (mid + Math.imul(ah1, bl0)) | 0;
-+    hi = Math.imul(ah1, bh0);
-+    lo = (lo + Math.imul(al0, bl1)) | 0;
-+    mid = (mid + Math.imul(al0, bh1)) | 0;
-+    mid = (mid + Math.imul(ah0, bl1)) | 0;
-+    hi = (hi + Math.imul(ah0, bh1)) | 0;
-+    var w1 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
-+    c = (((hi + (mid >>> 13)) | 0) + (w1 >>> 26)) | 0;
-+    w1 &= 0x3ffffff;
-+    /* k = 2 */
-+    lo = Math.imul(al2, bl0);
-+    mid = Math.imul(al2, bh0);
-+    mid = (mid + Math.imul(ah2, bl0)) | 0;
-+    hi = Math.imul(ah2, bh0);
-+    lo = (lo + Math.imul(al1, bl1)) | 0;
-+    mid = (mid + Math.imul(al1, bh1)) | 0;
-+    mid = (mid + Math.imul(ah1, bl1)) | 0;
-+    hi = (hi + Math.imul(ah1, bh1)) | 0;
-+    lo = (lo + Math.imul(al0, bl2)) | 0;
-+    mid = (mid + Math.imul(al0, bh2)) | 0;
-+    mid = (mid + Math.imul(ah0, bl2)) | 0;
-+    hi = (hi + Math.imul(ah0, bh2)) | 0;
-+    var w2 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
-+    c = (((hi + (mid >>> 13)) | 0) + (w2 >>> 26)) | 0;
-+    w2 &= 0x3ffffff;
-+    /* k = 3 */
-+    lo = Math.imul(al3, bl0);
-+    mid = Math.imul(al3, bh0);
-+    mid = (mid + Math.imul(ah3, bl0)) | 0;
-+    hi = Math.imul(ah3, bh0);
-+    lo = (lo + Math.imul(al2, bl1)) | 0;
-+    mid = (mid + Math.imul(al2, bh1)) | 0;
-+    mid = (mid + Math.imul(ah2, bl1)) | 0;
-+    hi = (hi + Math.imul(ah2, bh1)) | 0;
-+    lo = (lo + Math.imul(al1, bl2)) | 0;
-+    mid = (mid + Math.imul(al1, bh2)) | 0;
-+    mid = (mid + Math.imul(ah1, bl2)) | 0;
-+    hi = (hi + Math.imul(ah1, bh2)) | 0;
-+    lo = (lo + Math.imul(al0, bl3)) | 0;
-+    mid = (mid + Math.imul(al0, bh3)) | 0;
-+    mid = (mid + Math.imul(ah0, bl3)) | 0;
-+    hi = (hi + Math.imul(ah0, bh3)) | 0;
-+    var w3 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
-+    c = (((hi + (mid >>> 13)) | 0) + (w3 >>> 26)) | 0;
-+    w3 &= 0x3ffffff;
-+    /* k = 4 */
-+    lo = Math.imul(al4, bl0);
-+    mid = Math.imul(al4, bh0);
-+    mid = (mid + Math.imul(ah4, bl0)) | 0;
-+    hi = Math.imul(ah4, bh0);
-+    lo = (lo + Math.imul(al3, bl1)) | 0;
-+    mid = (mid + Math.imul(al3, bh1)) | 0;
-+    mid = (mid + Math.imul(ah3, bl1)) | 0;
-+    hi = (hi + Math.imul(ah3, bh1)) | 0;
-+    lo = (lo + Math.imul(al2, bl2)) | 0;
-+    mid = (mid + Math.imul(al2, bh2)) | 0;
-+    mid = (mid + Math.imul(ah2, bl2)) | 0;
-+    hi = (hi + Math.imul(ah2, bh2)) | 0;
-+    lo = (lo + Math.imul(al1, bl3)) | 0;
-+    mid = (mid + Math.imul(al1, bh3)) | 0;
-+    mid = (mid + Math.imul(ah1, bl3)) | 0;
-+    hi = (hi + Math.imul(ah1, bh3)) | 0;
-+    lo = (lo + Math.imul(al0, bl4)) | 0;
-+    mid = (mid + Math.imul(al0, bh4)) | 0;
-+    mid = (mid + Math.imul(ah0, bl4)) | 0;
-+    hi = (hi + Math.imul(ah0, bh4)) | 0;
-+    var w4 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
-+    c = (((hi + (mid >>> 13)) | 0) + (w4 >>> 26)) | 0;
-+    w4 &= 0x3ffffff;
-+    /* k = 5 */
-+    lo = Math.imul(al5, bl0);
-+    mid = Math.imul(al5, bh0);
-+    mid = (mid + Math.imul(ah5, bl0)) | 0;
-+    hi = Math.imul(ah5, bh0);
-+    lo = (lo + Math.imul(al4, bl1)) | 0;
-+    mid = (mid + Math.imul(al4, bh1)) | 0;
-+    mid = (mid + Math.imul(ah4, bl1)) | 0;
-+    hi = (hi + Math.imul(ah4, bh1)) | 0;
-+    lo = (lo + Math.imul(al3, bl2)) | 0;
-+    mid = (mid + Math.imul(al3, bh2)) | 0;
-+    mid = (mid + Math.imul(ah3, bl2)) | 0;
-+    hi = (hi + Math.imul(ah3, bh2)) | 0;
-+    lo = (lo + Math.imul(al2, bl3)) | 0;
-+    mid = (mid + Math.imul(al2, bh3)) | 0;
-+    mid = (mid + Math.imul(ah2, bl3)) | 0;
-+    hi = (hi + Math.imul(ah2, bh3)) | 0;
-+    lo = (lo + Math.imul(al1, bl4)) | 0;
-+    mid = (mid + Math.imul(al1, bh4)) | 0;
-+    mid = (mid + Math.imul(ah1, bl4)) | 0;
-+    hi = (hi + Math.imul(ah1, bh4)) | 0;
-+    lo = (lo + Math.imul(al0, bl5)) | 0;
-+    mid = (mid + Math.imul(al0, bh5)) | 0;
-+    mid = (mid + Math.imul(ah0, bl5)) | 0;
-+    hi = (hi + Math.imul(ah0, bh5)) | 0;
-+    var w5 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
-+    c = (((hi + (mid >>> 13)) | 0) + (w5 >>> 26)) | 0;
-+    w5 &= 0x3ffffff;
-+    /* k = 6 */
-+    lo = Math.imul(al6, bl0);
-+    mid = Math.imul(al6, bh0);
-+    mid = (mid + Math.imul(ah6, bl0)) | 0;
-+    hi = Math.imul(ah6, bh0);
-+    lo = (lo + Math.imul(al5, bl1)) | 0;
-+    mid = (mid + Math.imul(al5, bh1)) | 0;
-+    mid = (mid + Math.imul(ah5, bl1)) | 0;
-+    hi = (hi + Math.imul(ah5, bh1)) | 0;
-+    lo = (lo + Math.imul(al4, bl2)) | 0;
-+    mid = (mid + Math.imul(al4, bh2)) | 0;
-+    mid = (mid + Math.imul(ah4, bl2)) | 0;
-+    hi = (hi + Math.imul(ah4, bh2)) | 0;
-+    lo = (lo + Math.imul(al3, bl3)) | 0;
-+    mid = (mid + Math.imul(al3, bh3)) | 0;
-+    mid = (mid + Math.imul(ah3, bl3)) | 0;
-+    hi = (hi + Math.imul(ah3, bh3)) | 0;
-+    lo = (lo + Math.imul(al2, bl4)) | 0;
-+    mid = (mid + Math.imul(al2, bh4)) | 0;
-+    mid = (mid + Math.imul(ah2, bl4)) | 0;
-+    hi = (hi + Math.imul(ah2, bh4)) | 0;
-+    lo = (lo + Math.imul(al1, bl5)) | 0;
-+    mid = (mid + Math.imul(al1, bh5)) | 0;
-+    mid = (mid + Math.imul(ah1, bl5)) | 0;
-+    hi = (hi + Math.imul(ah1, bh5)) | 0;
-+    lo = (lo + Math.imul(al0, bl6)) | 0;
-+    mid = (mid + Math.imul(al0, bh6)) | 0;
-+    mid = (mid + Math.imul(ah0, bl6)) | 0;
-+    hi = (hi + Math.imul(ah0, bh6)) | 0;
-+    var w6 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
-+    c = (((hi + (mid >>> 13)) | 0) + (w6 >>> 26)) | 0;
-+    w6 &= 0x3ffffff;
-+    /* k = 7 */
-+    lo = Math.imul(al7, bl0);
-+    mid = Math.imul(al7, bh0);
-+    mid = (mid + Math.imul(ah7, bl0)) | 0;
-+    hi = Math.imul(ah7, bh0);
-+    lo = (lo + Math.imul(al6, bl1)) | 0;
-+    mid = (mid + Math.imul(al6, bh1)) | 0;
-+    mid = (mid + Math.imul(ah6, bl1)) | 0;
-+    hi = (hi + Math.imul(ah6, bh1)) | 0;
-+    lo = (lo + Math.imul(al5, bl2)) | 0;
-+    mid = (mid + Math.imul(al5, bh2)) | 0;
-+    mid = (mid + Math.imul(ah5, bl2)) | 0;
-+    hi = (hi + Math.imul(ah5, bh2)) | 0;
-+    lo = (lo + Math.imul(al4, bl3)) | 0;
-+    mid = (mid + Math.imul(al4, bh3)) | 0;
-+    mid = (mid + Math.imul(ah4, bl3)) | 0;
-+    hi = (hi + Math.imul(ah4, bh3)) | 0;
-+    lo = (lo + Math.imul(al3, bl4)) | 0;
-+    mid = (mid + Math.imul(al3, bh4)) | 0;
-+    mid = (mid + Math.imul(ah3, bl4)) | 0;
-+    hi = (hi + Math.imul(ah3, bh4)) | 0;
-+    lo = (lo + Math.imul(al2, bl5)) | 0;
-+    mid = (mid + Math.imul(al2, bh5)) | 0;
-+    mid = (mid + Math.imul(ah2, bl5)) | 0;
-+    hi = (hi + Math.imul(ah2, bh5)) | 0;
-+    lo = (lo + Math.imul(al1, bl6)) | 0;
-+    mid = (mid + Math.imul(al1, bh6)) | 0;
-+    mid = (mid + Math.imul(ah1, bl6)) | 0;
-+    hi = (hi + Math.imul(ah1, bh6)) | 0;
-+    lo = (lo + Math.imul(al0, bl7)) | 0;
-+    mid = (mid + Math.imul(al0, bh7)) | 0;
-+    mid = (mid + Math.imul(ah0, bl7)) | 0;
-+    hi = (hi + Math.imul(ah0, bh7)) | 0;
-+    var w7 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
-+    c = (((hi + (mid >>> 13)) | 0) + (w7 >>> 26)) | 0;
-+    w7 &= 0x3ffffff;
-+    /* k = 8 */
-+    lo = Math.imul(al8, bl0);
-+    mid = Math.imul(al8, bh0);
-+    mid = (mid + Math.imul(ah8, bl0)) | 0;
-+    hi = Math.imul(ah8, bh0);
-+    lo = (lo + Math.imul(al7, bl1)) | 0;
-+    mid = (mid + Math.imul(al7, bh1)) | 0;
-+    mid = (mid + Math.imul(ah7, bl1)) | 0;
-+    hi = (hi + Math.imul(ah7, bh1)) | 0;
-+    lo = (lo + Math.imul(al6, bl2)) | 0;
-+    mid = (mid + Math.imul(al6, bh2)) | 0;
-+    mid = (mid + Math.imul(ah6, bl2)) | 0;
-+    hi = (hi + Math.imul(ah6, bh2)) | 0;
-+    lo = (lo + Math.imul(al5, bl3)) | 0;
-+    mid = (mid + Math.imul(al5, bh3)) | 0;
-+    mid = (mid + Math.imul(ah5, bl3)) | 0;
-+    hi = (hi + Math.imul(ah5, bh3)) | 0;
-+    lo = (lo + Math.imul(al4, bl4)) | 0;
-+    mid = (mid + Math.imul(al4, bh4)) | 0;
-+    mid = (mid + Math.imul(ah4, bl4)) | 0;
-+    hi = (hi + Math.imul(ah4, bh4)) | 0;
-+    lo = (lo + Math.imul(al3, bl5)) | 0;
-+    mid = (mid + Math.imul(al3, bh5)) | 0;
-+    mid = (mid + Math.imul(ah3, bl5)) | 0;
-+    hi = (hi + Math.imul(ah3, bh5)) | 0;
-+    lo = (lo + Math.imul(al2, bl6)) | 0;
-+    mid = (mid + Math.imul(al2, bh6)) | 0;
-+    mid = (mid + Math.imul(ah2, bl6)) | 0;
-+    hi = (hi + Math.imul(ah2, bh6)) | 0;
-+    lo = (lo + Math.imul(al1, bl7)) | 0;
-+    mid = (mid + Math.imul(al1, bh7)) | 0;
-+    mid = (mid + Math.imul(ah1, bl7)) | 0;
-+    hi = (hi + Math.imul(ah1, bh7)) | 0;
-+    lo = (lo + Math.imul(al0, bl8)) | 0;
-+    mid = (mid + Math.imul(al0, bh8)) | 0;
-+    mid = (mid + Math.imul(ah0, bl8)) | 0;
-+    hi = (hi + Math.imul(ah0, bh8)) | 0;
-+    var w8 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
-+    c = (((hi + (mid >>> 13)) | 0) + (w8 >>> 26)) | 0;
-+    w8 &= 0x3ffffff;
-+    /* k = 9 */
-+    lo = Math.imul(al9, bl0);
-+    mid = Math.imul(al9, bh0);
-+    mid = (mid + Math.imul(ah9, bl0)) | 0;
-+    hi = Math.imul(ah9, bh0);
-+    lo = (lo + Math.imul(al8, bl1)) | 0;
-+    mid = (mid + Math.imul(al8, bh1)) | 0;
-+    mid = (mid + Math.imul(ah8, bl1)) | 0;
-+    hi = (hi + Math.imul(ah8, bh1)) | 0;
-+    lo = (lo + Math.imul(al7, bl2)) | 0;
-+    mid = (mid + Math.imul(al7, bh2)) | 0;
-+    mid = (mid + Math.imul(ah7, bl2)) | 0;
-+    hi = (hi + Math.imul(ah7, bh2)) | 0;
-+    lo = (lo + Math.imul(al6, bl3)) | 0;
-+    mid = (mid + Math.imul(al6, bh3)) | 0;
-+    mid = (mid + Math.imul(ah6, bl3)) | 0;
-+    hi = (hi + Math.imul(ah6, bh3)) | 0;
-+    lo = (lo + Math.imul(al5, bl4)) | 0;
-+    mid = (mid + Math.imul(al5, bh4)) | 0;
-+    mid = (mid + Math.imul(ah5, bl4)) | 0;
-+    hi = (hi + Math.imul(ah5, bh4)) | 0;
-+    lo = (lo + Math.imul(al4, bl5)) | 0;
-+    mid = (mid + Math.imul(al4, bh5)) | 0;
-+    mid = (mid + Math.imul(ah4, bl5)) | 0;
-+    hi = (hi + Math.imul(ah4, bh5)) | 0;
-+    lo = (lo + Math.imul(al3, bl6)) | 0;
-+    mid = (mid + Math.imul(al3, bh6)) | 0;
-+    mid = (mid + Math.imul(ah3, bl6)) | 0;
-+    hi = (hi + Math.imul(ah3, bh6)) | 0;
-+    lo = (lo + Math.imul(al2, bl7)) | 0;
-+    mid = (mid + Math.imul(al2, bh7)) | 0;
-+    mid = (mid + Math.imul(ah2, bl7)) | 0;
-+    hi = (hi + Math.imul(ah2, bh7)) | 0;
-+    lo = (lo + Math.imul(al1, bl8)) | 0;
-+    mid = (mid + Math.imul(al1, bh8)) | 0;
-+    mid = (mid + Math.imul(ah1, bl8)) | 0;
-+    hi = (hi + Math.imul(ah1, bh8)) | 0;
-+    lo = (lo + Math.imul(al0, bl9)) | 0;
-+    mid = (mid + Math.imul(al0, bh9)) | 0;
-+    mid = (mid + Math.imul(ah0, bl9)) | 0;
-+    hi = (hi + Math.imul(ah0, bh9)) | 0;
-+    var w9 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
-+    c = (((hi + (mid >>> 13)) | 0) + (w9 >>> 26)) | 0;
-+    w9 &= 0x3ffffff;
-+    /* k = 10 */
-+    lo = Math.imul(al9, bl1);
-+    mid = Math.imul(al9, bh1);
-+    mid = (mid + Math.imul(ah9, bl1)) | 0;
-+    hi = Math.imul(ah9, bh1);
-+    lo = (lo + Math.imul(al8, bl2)) | 0;
-+    mid = (mid + Math.imul(al8, bh2)) | 0;
-+    mid = (mid + Math.imul(ah8, bl2)) | 0;
-+    hi = (hi + Math.imul(ah8, bh2)) | 0;
-+    lo = (lo + Math.imul(al7, bl3)) | 0;
-+    mid = (mid + Math.imul(al7, bh3)) | 0;
-+    mid = (mid + Math.imul(ah7, bl3)) | 0;
-+    hi = (hi + Math.imul(ah7, bh3)) | 0;
-+    lo = (lo + Math.imul(al6, bl4)) | 0;
-+    mid = (mid + Math.imul(al6, bh4)) | 0;
-+    mid = (mid + Math.imul(ah6, bl4)) | 0;
-+    hi = (hi + Math.imul(ah6, bh4)) | 0;
-+    lo = (lo + Math.imul(al5, bl5)) | 0;
-+    mid = (mid + Math.imul(al5, bh5)) | 0;
-+    mid = (mid + Math.imul(ah5, bl5)) | 0;
-+    hi = (hi + Math.imul(ah5, bh5)) | 0;
-+    lo = (lo + Math.imul(al4, bl6)) | 0;
-+    mid = (mid + Math.imul(al4, bh6)) | 0;
-+    mid = (mid + Math.imul(ah4, bl6)) | 0;
-+    hi = (hi + Math.imul(ah4, bh6)) | 0;
-+    lo = (lo + Math.imul(al3, bl7)) | 0;
-+    mid = (mid + Math.imul(al3, bh7)) | 0;
-+    mid = (mid + Math.imul(ah3, bl7)) | 0;
-+    hi = (hi + Math.imul(ah3, bh7)) | 0;
-+    lo = (lo + Math.imul(al2, bl8)) | 0;
-+    mid = (mid + Math.imul(al2, bh8)) | 0;
-+    mid = (mid + Math.imul(ah2, bl8)) | 0;
-+    hi = (hi + Math.imul(ah2, bh8)) | 0;
-+    lo = (lo + Math.imul(al1, bl9)) | 0;
-+    mid = (mid + Math.imul(al1, bh9)) | 0;
-+    mid = (mid + Math.imul(ah1, bl9)) | 0;
-+    hi = (hi + Math.imul(ah1, bh9)) | 0;
-+    var w10 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
-+    c = (((hi + (mid >>> 13)) | 0) + (w10 >>> 26)) | 0;
-+    w10 &= 0x3ffffff;
-+    /* k = 11 */
-+    lo = Math.imul(al9, bl2);
-+    mid = Math.imul(al9, bh2);
-+    mid = (mid + Math.imul(ah9, bl2)) | 0;
-+    hi = Math.imul(ah9, bh2);
-+    lo = (lo + Math.imul(al8, bl3)) | 0;
-+    mid = (mid + Math.imul(al8, bh3)) | 0;
-+    mid = (mid + Math.imul(ah8, bl3)) | 0;
-+    hi = (hi + Math.imul(ah8, bh3)) | 0;
-+    lo = (lo + Math.imul(al7, bl4)) | 0;
-+    mid = (mid + Math.imul(al7, bh4)) | 0;
-+    mid = (mid + Math.imul(ah7, bl4)) | 0;
-+    hi = (hi + Math.imul(ah7, bh4)) | 0;
-+    lo = (lo + Math.imul(al6, bl5)) | 0;
-+    mid = (mid + Math.imul(al6, bh5)) | 0;
-+    mid = (mid + Math.imul(ah6, bl5)) | 0;
-+    hi = (hi + Math.imul(ah6, bh5)) | 0;
-+    lo = (lo + Math.imul(al5, bl6)) | 0;
-+    mid = (mid + Math.imul(al5, bh6)) | 0;
-+    mid = (mid + Math.imul(ah5, bl6)) | 0;
-+    hi = (hi + Math.imul(ah5, bh6)) | 0;
-+    lo = (lo + Math.imul(al4, bl7)) | 0;
-+    mid = (mid + Math.imul(al4, bh7)) | 0;
-+    mid = (mid + Math.imul(ah4, bl7)) | 0;
-+    hi = (hi + Math.imul(ah4, bh7)) | 0;
-+    lo = (lo + Math.imul(al3, bl8)) | 0;
-+    mid = (mid + Math.imul(al3, bh8)) | 0;
-+    mid = (mid + Math.imul(ah3, bl8)) | 0;
-+    hi = (hi + Math.imul(ah3, bh8)) | 0;
-+    lo = (lo + Math.imul(al2, bl9)) | 0;
-+    mid = (mid + Math.imul(al2, bh9)) | 0;
-+    mid = (mid + Math.imul(ah2, bl9)) | 0;
-+    hi = (hi + Math.imul(ah2, bh9)) | 0;
-+    var w11 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
-+    c = (((hi + (mid >>> 13)) | 0) + (w11 >>> 26)) | 0;
-+    w11 &= 0x3ffffff;
-+    /* k = 12 */
-+    lo = Math.imul(al9, bl3);
-+    mid = Math.imul(al9, bh3);
-+    mid = (mid + Math.imul(ah9, bl3)) | 0;
-+    hi = Math.imul(ah9, bh3);
-+    lo = (lo + Math.imul(al8, bl4)) | 0;
-+    mid = (mid + Math.imul(al8, bh4)) | 0;
-+    mid = (mid + Math.imul(ah8, bl4)) | 0;
-+    hi = (hi + Math.imul(ah8, bh4)) | 0;
-+    lo = (lo + Math.imul(al7, bl5)) | 0;
-+    mid = (mid + Math.imul(al7, bh5)) | 0;
-+    mid = (mid + Math.imul(ah7, bl5)) | 0;
-+    hi = (hi + Math.imul(ah7, bh5)) | 0;
-+    lo = (lo + Math.imul(al6, bl6)) | 0;
-+    mid = (mid + Math.imul(al6, bh6)) | 0;
-+    mid = (mid + Math.imul(ah6, bl6)) | 0;
-+    hi = (hi + Math.imul(ah6, bh6)) | 0;
-+    lo = (lo + Math.imul(al5, bl7)) | 0;
-+    mid = (mid + Math.imul(al5, bh7)) | 0;
-+    mid = (mid + Math.imul(ah5, bl7)) | 0;
-+    hi = (hi + Math.imul(ah5, bh7)) | 0;
-+    lo = (lo + Math.imul(al4, bl8)) | 0;
-+    mid = (mid + Math.imul(al4, bh8)) | 0;
-+    mid = (mid + Math.imul(ah4, bl8)) | 0;
-+    hi = (hi + Math.imul(ah4, bh8)) | 0;
-+    lo = (lo + Math.imul(al3, bl9)) | 0;
-+    mid = (mid + Math.imul(al3, bh9)) | 0;
-+    mid = (mid + Math.imul(ah3, bl9)) | 0;
-+    hi = (hi + Math.imul(ah3, bh9)) | 0;
-+    var w12 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
-+    c = (((hi + (mid >>> 13)) | 0) + (w12 >>> 26)) | 0;
-+    w12 &= 0x3ffffff;
-+    /* k = 13 */
-+    lo = Math.imul(al9, bl4);
-+    mid = Math.imul(al9, bh4);
-+    mid = (mid + Math.imul(ah9, bl4)) | 0;
-+    hi = Math.imul(ah9, bh4);
-+    lo = (lo + Math.imul(al8, bl5)) | 0;
-+    mid = (mid + Math.imul(al8, bh5)) | 0;
-+    mid = (mid + Math.imul(ah8, bl5)) | 0;
-+    hi = (hi + Math.imul(ah8, bh5)) | 0;
-+    lo = (lo + Math.imul(al7, bl6)) | 0;
-+    mid = (mid + Math.imul(al7, bh6)) | 0;
-+    mid = (mid + Math.imul(ah7, bl6)) | 0;
-+    hi = (hi + Math.imul(ah7, bh6)) | 0;
-+    lo = (lo + Math.imul(al6, bl7)) | 0;
-+    mid = (mid + Math.imul(al6, bh7)) | 0;
-+    mid = (mid + Math.imul(ah6, bl7)) | 0;
-+    hi = (hi + Math.imul(ah6, bh7)) | 0;
-+    lo = (lo + Math.imul(al5, bl8)) | 0;
-+    mid = (mid + Math.imul(al5, bh8)) | 0;
-+    mid = (mid + Math.imul(ah5, bl8)) | 0;
-+    hi = (hi + Math.imul(ah5, bh8)) | 0;
-+    lo = (lo + Math.imul(al4, bl9)) | 0;
-+    mid = (mid + Math.imul(al4, bh9)) | 0;
-+    mid = (mid + Math.imul(ah4, bl9)) | 0;
-+    hi = (hi + Math.imul(ah4, bh9)) | 0;
-+    var w13 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
-+    c = (((hi + (mid >>> 13)) | 0) + (w13 >>> 26)) | 0;
-+    w13 &= 0x3ffffff;
-+    /* k = 14 */
-+    lo = Math.imul(al9, bl5);
-+    mid = Math.imul(al9, bh5);
-+    mid = (mid + Math.imul(ah9, bl5)) | 0;
-+    hi = Math.imul(ah9, bh5);
-+    lo = (lo + Math.imul(al8, bl6)) | 0;
-+    mid = (mid + Math.imul(al8, bh6)) | 0;
-+    mid = (mid + Math.imul(ah8, bl6)) | 0;
-+    hi = (hi + Math.imul(ah8, bh6)) | 0;
-+    lo = (lo + Math.imul(al7, bl7)) | 0;
-+    mid = (mid + Math.imul(al7, bh7)) | 0;
-+    mid = (mid + Math.imul(ah7, bl7)) | 0;
-+    hi = (hi + Math.imul(ah7, bh7)) | 0;
-+    lo = (lo + Math.imul(al6, bl8)) | 0;
-+    mid = (mid + Math.imul(al6, bh8)) | 0;
-+    mid = (mid + Math.imul(ah6, bl8)) | 0;
-+    hi = (hi + Math.imul(ah6, bh8)) | 0;
-+    lo = (lo + Math.imul(al5, bl9)) | 0;
-+    mid = (mid + Math.imul(al5, bh9)) | 0;
-+    mid = (mid + Math.imul(ah5, bl9)) | 0;
-+    hi = (hi + Math.imul(ah5, bh9)) | 0;
-+    var w14 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
-+    c = (((hi + (mid >>> 13)) | 0) + (w14 >>> 26)) | 0;
-+    w14 &= 0x3ffffff;
-+    /* k = 15 */
-+    lo = Math.imul(al9, bl6);
-+    mid = Math.imul(al9, bh6);
-+    mid = (mid + Math.imul(ah9, bl6)) | 0;
-+    hi = Math.imul(ah9, bh6);
-+    lo = (lo + Math.imul(al8, bl7)) | 0;
-+    mid = (mid + Math.imul(al8, bh7)) | 0;
-+    mid = (mid + Math.imul(ah8, bl7)) | 0;
-+    hi = (hi + Math.imul(ah8, bh7)) | 0;
-+    lo = (lo + Math.imul(al7, bl8)) | 0;
-+    mid = (mid + Math.imul(al7, bh8)) | 0;
-+    mid = (mid + Math.imul(ah7, bl8)) | 0;
-+    hi = (hi + Math.imul(ah7, bh8)) | 0;
-+    lo = (lo + Math.imul(al6, bl9)) | 0;
-+    mid = (mid + Math.imul(al6, bh9)) | 0;
-+    mid = (mid + Math.imul(ah6, bl9)) | 0;
-+    hi = (hi + Math.imul(ah6, bh9)) | 0;
-+    var w15 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
-+    c = (((hi + (mid >>> 13)) | 0) + (w15 >>> 26)) | 0;
-+    w15 &= 0x3ffffff;
-+    /* k = 16 */
-+    lo = Math.imul(al9, bl7);
-+    mid = Math.imul(al9, bh7);
-+    mid = (mid + Math.imul(ah9, bl7)) | 0;
-+    hi = Math.imul(ah9, bh7);
-+    lo = (lo + Math.imul(al8, bl8)) | 0;
-+    mid = (mid + Math.imul(al8, bh8)) | 0;
-+    mid = (mid + Math.imul(ah8, bl8)) | 0;
-+    hi = (hi + Math.imul(ah8, bh8)) | 0;
-+    lo = (lo + Math.imul(al7, bl9)) | 0;
-+    mid = (mid + Math.imul(al7, bh9)) | 0;
-+    mid = (mid + Math.imul(ah7, bl9)) | 0;
-+    hi = (hi + Math.imul(ah7, bh9)) | 0;
-+    var w16 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
-+    c = (((hi + (mid >>> 13)) | 0) + (w16 >>> 26)) | 0;
-+    w16 &= 0x3ffffff;
-+    /* k = 17 */
-+    lo = Math.imul(al9, bl8);
-+    mid = Math.imul(al9, bh8);
-+    mid = (mid + Math.imul(ah9, bl8)) | 0;
-+    hi = Math.imul(ah9, bh8);
-+    lo = (lo + Math.imul(al8, bl9)) | 0;
-+    mid = (mid + Math.imul(al8, bh9)) | 0;
-+    mid = (mid + Math.imul(ah8, bl9)) | 0;
-+    hi = (hi + Math.imul(ah8, bh9)) | 0;
-+    var w17 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
-+    c = (((hi + (mid >>> 13)) | 0) + (w17 >>> 26)) | 0;
-+    w17 &= 0x3ffffff;
-+    /* k = 18 */
-+    lo = Math.imul(al9, bl9);
-+    mid = Math.imul(al9, bh9);
-+    mid = (mid + Math.imul(ah9, bl9)) | 0;
-+    hi = Math.imul(ah9, bh9);
-+    var w18 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
-+    c = (((hi + (mid >>> 13)) | 0) + (w18 >>> 26)) | 0;
-+    w18 &= 0x3ffffff;
-+    o[0] = w0;
-+    o[1] = w1;
-+    o[2] = w2;
-+    o[3] = w3;
-+    o[4] = w4;
-+    o[5] = w5;
-+    o[6] = w6;
-+    o[7] = w7;
-+    o[8] = w8;
-+    o[9] = w9;
-+    o[10] = w10;
-+    o[11] = w11;
-+    o[12] = w12;
-+    o[13] = w13;
-+    o[14] = w14;
-+    o[15] = w15;
-+    o[16] = w16;
-+    o[17] = w17;
-+    o[18] = w18;
-+    if (c !== 0) {
-+      o[19] = c;
-+      out.length++;
-+    }
-+    return out;
-+  };
-+
-+  // Polyfill comb
-+  if (!Math.imul) {
-+    comb10MulTo = smallMulTo;
-+  }
-+
-+  function bigMulTo (self, num, out) {
-+    out.negative = num.negative ^ self.negative;
-+    out.length = self.length + num.length;
-+
-+    var carry = 0;
-+    var hncarry = 0;
-+    for (var k = 0; k < out.length - 1; k++) {
-+      // Sum all words with the same `i + j = k` and accumulate `ncarry`,
-+      // note that ncarry could be >= 0x3ffffff
-+      var ncarry = hncarry;
-+      hncarry = 0;
-+      var rword = carry & 0x3ffffff;
-+      var maxJ = Math.min(k, num.length - 1);
-+      for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
-+        var i = k - j;
-+        var a = self.words[i] | 0;
-+        var b = num.words[j] | 0;
-+        var r = a * b;
-+
-+        var lo = r & 0x3ffffff;
-+        ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0;
-+        lo = (lo + rword) | 0;
-+        rword = lo & 0x3ffffff;
-+        ncarry = (ncarry + (lo >>> 26)) | 0;
-+
-+        hncarry += ncarry >>> 26;
-+        ncarry &= 0x3ffffff;
-+      }
-+      out.words[k] = rword;
-+      carry = ncarry;
-+      ncarry = hncarry;
-+    }
-+    if (carry !== 0) {
-+      out.words[k] = carry;
-+    } else {
-+      out.length--;
-+    }
-+
-+    return out.strip();
-+  }
-+
-+  function jumboMulTo (self, num, out) {
-+    var fftm = new FFTM();
-+    return fftm.mulp(self, num, out);
-+  }
-+
-+  BN.prototype.mulTo = function mulTo (num, out) {
-+    var res;
-+    var len = this.length + num.length;
-+    if (this.length === 10 && num.length === 10) {
-+      res = comb10MulTo(this, num, out);
-+    } else if (len < 63) {
-+      res = smallMulTo(this, num, out);
-+    } else if (len < 1024) {
-+      res = bigMulTo(this, num, out);
-+    } else {
-+      res = jumboMulTo(this, num, out);
-+    }
-+
-+    return res;
-+  };
-+
-+  // Cooley-Tukey algorithm for FFT
-+  // slightly revisited to rely on looping instead of recursion
-+
-+  function FFTM (x, y) {
-+    this.x = x;
-+    this.y = y;
-+  }
-+
-+  FFTM.prototype.makeRBT = function makeRBT (N) {
-+    var t = new Array(N);
-+    var l = BN.prototype._countBits(N) - 1;
-+    for (var i = 0; i < N; i++) {
-+      t[i] = this.revBin(i, l, N);
-+    }
-+
-+    return t;
-+  };
-+
-+  // Returns binary-reversed representation of `x`
-+  FFTM.prototype.revBin = function revBin (x, l, N) {
-+    if (x === 0 || x === N - 1) return x;
-+
-+    var rb = 0;
-+    for (var i = 0; i < l; i++) {
-+      rb |= (x & 1) << (l - i - 1);
-+      x >>= 1;
-+    }
-+
-+    return rb;
-+  };
-+
-+  // Performs "tweedling" phase, therefore 'emulating'
-+  // behaviour of the recursive algorithm
-+  FFTM.prototype.permute = function permute (rbt, rws, iws, rtws, itws, N) {
-+    for (var i = 0; i < N; i++) {
-+      rtws[i] = rws[rbt[i]];
-+      itws[i] = iws[rbt[i]];
-+    }
-+  };
-+
-+  FFTM.prototype.transform = function transform (rws, iws, rtws, itws, N, rbt) {
-+    this.permute(rbt, rws, iws, rtws, itws, N);
-+
-+    for (var s = 1; s < N; s <<= 1) {
-+      var l = s << 1;
-+
-+      var rtwdf = Math.cos(2 * Math.PI / l);
-+      var itwdf = Math.sin(2 * Math.PI / l);
-+
-+      for (var p = 0; p < N; p += l) {
-+        var rtwdf_ = rtwdf;
-+        var itwdf_ = itwdf;
-+
-+        for (var j = 0; j < s; j++) {
-+          var re = rtws[p + j];
-+          var ie = itws[p + j];
-+
-+          var ro = rtws[p + j + s];
-+          var io = itws[p + j + s];
-+
-+          var rx = rtwdf_ * ro - itwdf_ * io;
-+
-+          io = rtwdf_ * io + itwdf_ * ro;
-+          ro = rx;
-+
-+          rtws[p + j] = re + ro;
-+          itws[p + j] = ie + io;
-+
-+          rtws[p + j + s] = re - ro;
-+          itws[p + j + s] = ie - io;
-+
-+          /* jshint maxdepth : false */
-+          if (j !== l) {
-+            rx = rtwdf * rtwdf_ - itwdf * itwdf_;
-+
-+            itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_;
-+            rtwdf_ = rx;
-+          }
-+        }
-+      }
-+    }
-+  };
-+
-+  FFTM.prototype.guessLen13b = function guessLen13b (n, m) {
-+    var N = Math.max(m, n) | 1;
-+    var odd = N & 1;
-+    var i = 0;
-+    for (N = N / 2 | 0; N; N = N >>> 1) {
-+      i++;
-+    }
-+
-+    return 1 << i + 1 + odd;
-+  };
-+
-+  FFTM.prototype.conjugate = function conjugate (rws, iws, N) {
-+    if (N <= 1) return;
-+
-+    for (var i = 0; i < N / 2; i++) {
-+      var t = rws[i];
-+
-+      rws[i] = rws[N - i - 1];
-+      rws[N - i - 1] = t;
-+
-+      t = iws[i];
-+
-+      iws[i] = -iws[N - i - 1];
-+      iws[N - i - 1] = -t;
-+    }
-+  };
-+
-+  FFTM.prototype.normalize13b = function normalize13b (ws, N) {
-+    var carry = 0;
-+    for (var i = 0; i < N / 2; i++) {
-+      var w = Math.round(ws[2 * i + 1] / N) * 0x2000 +
-+        Math.round(ws[2 * i] / N) +
-+        carry;
-+
-+      ws[i] = w & 0x3ffffff;
-+
-+      if (w < 0x4000000) {
-+        carry = 0;
-+      } else {
-+        carry = w / 0x4000000 | 0;
-+      }
-+    }
-+
-+    return ws;
-+  };
-+
-+  FFTM.prototype.convert13b = function convert13b (ws, len, rws, N) {
-+    var carry = 0;
-+    for (var i = 0; i < len; i++) {
-+      carry = carry + (ws[i] | 0);
-+
-+      rws[2 * i] = carry & 0x1fff; carry = carry >>> 13;
-+      rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13;
-+    }
-+
-+    // Pad with zeroes
-+    for (i = 2 * len; i < N; ++i) {
-+      rws[i] = 0;
-+    }
-+
-+    assert(carry === 0);
-+    assert((carry & ~0x1fff) === 0);
-+  };
-+
-+  FFTM.prototype.stub = function stub (N) {
-+    var ph = new Array(N);
-+    for (var i = 0; i < N; i++) {
-+      ph[i] = 0;
-+    }
-+
-+    return ph;
-+  };
-+
-+  FFTM.prototype.mulp = function mulp (x, y, out) {
-+    var N = 2 * this.guessLen13b(x.length, y.length);
-+
-+    var rbt = this.makeRBT(N);
-+
-+    var _ = this.stub(N);
-+
-+    var rws = new Array(N);
-+    var rwst = new Array(N);
-+    var iwst = new Array(N);
-+
-+    var nrws = new Array(N);
-+    var nrwst = new Array(N);
-+    var niwst = new Array(N);
-+
-+    var rmws = out.words;
-+    rmws.length = N;
-+
-+    this.convert13b(x.words, x.length, rws, N);
-+    this.convert13b(y.words, y.length, nrws, N);
-+
-+    this.transform(rws, _, rwst, iwst, N, rbt);
-+    this.transform(nrws, _, nrwst, niwst, N, rbt);
-+
-+    for (var i = 0; i < N; i++) {
-+      var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i];
-+      iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i];
-+      rwst[i] = rx;
-+    }
-+
-+    this.conjugate(rwst, iwst, N);
-+    this.transform(rwst, iwst, rmws, _, N, rbt);
-+    this.conjugate(rmws, _, N);
-+    this.normalize13b(rmws, N);
-+
-+    out.negative = x.negative ^ y.negative;
-+    out.length = x.length + y.length;
-+    return out.strip();
-+  };
-+
-+  // Multiply `this` by `num`
-+  BN.prototype.mul = function mul (num) {
-+    var out = new BN(null);
-+    out.words = new Array(this.length + num.length);
-+    return this.mulTo(num, out);
-+  };
-+
-+  // Multiply employing FFT
-+  BN.prototype.mulf = function mulf (num) {
-+    var out = new BN(null);
-+    out.words = new Array(this.length + num.length);
-+    return jumboMulTo(this, num, out);
-+  };
-+
-+  // In-place Multiplication
-+  BN.prototype.imul = function imul (num) {
-+    return this.clone().mulTo(num, this);
-+  };
-+
-+  BN.prototype.imuln = function imuln (num) {
-+    assert(typeof num === 'number');
-+    assert(num < 0x4000000);
-+
-+    // Carry
-+    var carry = 0;
-+    for (var i = 0; i < this.length; i++) {
-+      var w = (this.words[i] | 0) * num;
-+      var lo = (w & 0x3ffffff) + (carry & 0x3ffffff);
-+      carry >>= 26;
-+      carry += (w / 0x4000000) | 0;
-+      // NOTE: lo is 27bit maximum
-+      carry += lo >>> 26;
-+      this.words[i] = lo & 0x3ffffff;
-+    }
-+
-+    if (carry !== 0) {
-+      this.words[i] = carry;
-+      this.length++;
-+    }
-+
-+    return this;
-+  };
-+
-+  BN.prototype.muln = function muln (num) {
-+    return this.clone().imuln(num);
-+  };
-+
-+  // `this` * `this`
-+  BN.prototype.sqr = function sqr () {
-+    return this.mul(this);
-+  };
-+
-+  // `this` * `this` in-place
-+  BN.prototype.isqr = function isqr () {
-+    return this.imul(this.clone());
-+  };
-+
-+  // Math.pow(`this`, `num`)
-+  BN.prototype.pow = function pow (num) {
-+    var w = toBitArray(num);
-+    if (w.length === 0) return new BN(1);
-+
-+    // Skip leading zeroes
-+    var res = this;
-+    for (var i = 0; i < w.length; i++, res = res.sqr()) {
-+      if (w[i] !== 0) break;
-+    }
-+
-+    if (++i < w.length) {
-+      for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) {
-+        if (w[i] === 0) continue;
-+
-+        res = res.mul(q);
-+      }
-+    }
-+
-+    return res;
-+  };
-+
-+  // Shift-left in-place
-+  BN.prototype.iushln = function iushln (bits) {
-+    assert(typeof bits === 'number' && bits >= 0);
-+    var r = bits % 26;
-+    var s = (bits - r) / 26;
-+    var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r);
-+    var i;
-+
-+    if (r !== 0) {
-+      var carry = 0;
-+
-+      for (i = 0; i < this.length; i++) {
-+        var newCarry = this.words[i] & carryMask;
-+        var c = ((this.words[i] | 0) - newCarry) << r;
-+        this.words[i] = c | carry;
-+        carry = newCarry >>> (26 - r);
-+      }
-+
-+      if (carry) {
-+        this.words[i] = carry;
-+        this.length++;
-+      }
-+    }
-+
-+    if (s !== 0) {
-+      for (i = this.length - 1; i >= 0; i--) {
-+        this.words[i + s] = this.words[i];
-+      }
-+
-+      for (i = 0; i < s; i++) {
-+        this.words[i] = 0;
-+      }
-+
-+      this.length += s;
-+    }
-+
-+    return this.strip();
-+  };
-+
-+  BN.prototype.ishln = function ishln (bits) {
-+    // TODO(indutny): implement me
-+    assert(this.negative === 0);
-+    return this.iushln(bits);
-+  };
-+
-+  // Shift-right in-place
-+  // NOTE: `hint` is a lowest bit before trailing zeroes
-+  // NOTE: if `extended` is present - it will be filled with destroyed bits
-+  BN.prototype.iushrn = function iushrn (bits, hint, extended) {
-+    assert(typeof bits === 'number' && bits >= 0);
-+    var h;
-+    if (hint) {
-+      h = (hint - (hint % 26)) / 26;
-+    } else {
-+      h = 0;
-+    }
-+
-+    var r = bits % 26;
-+    var s = Math.min((bits - r) / 26, this.length);
-+    var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
-+    var maskedWords = extended;
-+
-+    h -= s;
-+    h = Math.max(0, h);
-+
-+    // Extended mode, copy masked part
-+    if (maskedWords) {
-+      for (var i = 0; i < s; i++) {
-+        maskedWords.words[i] = this.words[i];
-+      }
-+      maskedWords.length = s;
-+    }
-+
-+    if (s === 0) {
-+      // No-op, we should not move anything at all
-+    } else if (this.length > s) {
-+      this.length -= s;
-+      for (i = 0; i < this.length; i++) {
-+        this.words[i] = this.words[i + s];
-+      }
-+    } else {
-+      this.words[0] = 0;
-+      this.length = 1;
-+    }
-+
-+    var carry = 0;
-+    for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) {
-+      var word = this.words[i] | 0;
-+      this.words[i] = (carry << (26 - r)) | (word >>> r);
-+      carry = word & mask;
-+    }
-+
-+    // Push carried bits as a mask
-+    if (maskedWords && carry !== 0) {
-+      maskedWords.words[maskedWords.length++] = carry;
-+    }
-+
-+    if (this.length === 0) {
-+      this.words[0] = 0;
-+      this.length = 1;
-+    }
-+
-+    return this.strip();
-+  };
-+
-+  BN.prototype.ishrn = function ishrn (bits, hint, extended) {
-+    // TODO(indutny): implement me
-+    assert(this.negative === 0);
-+    return this.iushrn(bits, hint, extended);
-+  };
-+
-+  // Shift-left
-+  BN.prototype.shln = function shln (bits) {
-+    return this.clone().ishln(bits);
-+  };
-+
-+  BN.prototype.ushln = function ushln (bits) {
-+    return this.clone().iushln(bits);
-+  };
-+
-+  // Shift-right
-+  BN.prototype.shrn = function shrn (bits) {
-+    return this.clone().ishrn(bits);
-+  };
-+
-+  BN.prototype.ushrn = function ushrn (bits) {
-+    return this.clone().iushrn(bits);
-+  };
-+
-+  // Test if n bit is set
-+  BN.prototype.testn = function testn (bit) {
-+    assert(typeof bit === 'number' && bit >= 0);
-+    var r = bit % 26;
-+    var s = (bit - r) / 26;
-+    var q = 1 << r;
-+
-+    // Fast case: bit is much higher than all existing words
-+    if (this.length <= s) return false;
-+
-+    // Check bit and return
-+    var w = this.words[s];
-+
-+    return !!(w & q);
-+  };
-+
-+  // Return only lowers bits of number (in-place)
-+  BN.prototype.imaskn = function imaskn (bits) {
-+    assert(typeof bits === 'number' && bits >= 0);
-+    var r = bits % 26;
-+    var s = (bits - r) / 26;
-+
-+    assert(this.negative === 0, 'imaskn works only with positive numbers');
-+
-+    if (this.length <= s) {
-+      return this;
-+    }
-+
-+    if (r !== 0) {
-+      s++;
-+    }
-+    this.length = Math.min(s, this.length);
-+
-+    if (r !== 0) {
-+      var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
-+      this.words[this.length - 1] &= mask;
-+    }
-+
-+    return this.strip();
-+  };
-+
-+  // Return only lowers bits of number
-+  BN.prototype.maskn = function maskn (bits) {
-+    return this.clone().imaskn(bits);
-+  };
-+
-+  // Add plain number `num` to `this`
-+  BN.prototype.iaddn = function iaddn (num) {
-+    assert(typeof num === 'number');
-+    assert(num < 0x4000000);
-+    if (num < 0) return this.isubn(-num);
-+
-+    // Possible sign change
-+    if (this.negative !== 0) {
-+      if (this.length === 1 && (this.words[0] | 0) < num) {
-+        this.words[0] = num - (this.words[0] | 0);
-+        this.negative = 0;
-+        return this;
-+      }
-+
-+      this.negative = 0;
-+      this.isubn(num);
-+      this.negative = 1;
-+      return this;
-+    }
-+
-+    // Add without checks
-+    return this._iaddn(num);
-+  };
-+
-+  BN.prototype._iaddn = function _iaddn (num) {
-+    this.words[0] += num;
-+
-+    // Carry
-+    for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) {
-+      this.words[i] -= 0x4000000;
-+      if (i === this.length - 1) {
-+        this.words[i + 1] = 1;
-+      } else {
-+        this.words[i + 1]++;
-+      }
-+    }
-+    this.length = Math.max(this.length, i + 1);
-+
-+    return this;
-+  };
-+
-+  // Subtract plain number `num` from `this`
-+  BN.prototype.isubn = function isubn (num) {
-+    assert(typeof num === 'number');
-+    assert(num < 0x4000000);
-+    if (num < 0) return this.iaddn(-num);
-+
-+    if (this.negative !== 0) {
-+      this.negative = 0;
-+      this.iaddn(num);
-+      this.negative = 1;
-+      return this;
-+    }
-+
-+    this.words[0] -= num;
-+
-+    if (this.length === 1 && this.words[0] < 0) {
-+      this.words[0] = -this.words[0];
-+      this.negative = 1;
-+    } else {
-+      // Carry
-+      for (var i = 0; i < this.length && this.words[i] < 0; i++) {
-+        this.words[i] += 0x4000000;
-+        this.words[i + 1] -= 1;
-+      }
-+    }
-+
-+    return this.strip();
-+  };
-+
-+  BN.prototype.addn = function addn (num) {
-+    return this.clone().iaddn(num);
-+  };
-+
-+  BN.prototype.subn = function subn (num) {
-+    return this.clone().isubn(num);
-+  };
-+
-+  BN.prototype.iabs = function iabs () {
-+    this.negative = 0;
-+
-+    return this;
-+  };
-+
-+  BN.prototype.abs = function abs () {
-+    return this.clone().iabs();
-+  };
-+
-+  BN.prototype._ishlnsubmul = function _ishlnsubmul (num, mul, shift) {
-+    var len = num.length + shift;
-+    var i;
-+
-+    this._expand(len);
-+
-+    var w;
-+    var carry = 0;
-+    for (i = 0; i < num.length; i++) {
-+      w = (this.words[i + shift] | 0) + carry;
-+      var right = (num.words[i] | 0) * mul;
-+      w -= right & 0x3ffffff;
-+      carry = (w >> 26) - ((right / 0x4000000) | 0);
-+      this.words[i + shift] = w & 0x3ffffff;
-+    }
-+    for (; i < this.length - shift; i++) {
-+      w = (this.words[i + shift] | 0) + carry;
-+      carry = w >> 26;
-+      this.words[i + shift] = w & 0x3ffffff;
-+    }
-+
-+    if (carry === 0) return this.strip();
-+
-+    // Subtraction overflow
-+    assert(carry === -1);
-+    carry = 0;
-+    for (i = 0; i < this.length; i++) {
-+      w = -(this.words[i] | 0) + carry;
-+      carry = w >> 26;
-+      this.words[i] = w & 0x3ffffff;
-+    }
-+    this.negative = 1;
-+
-+    return this.strip();
-+  };
-+
-+  BN.prototype._wordDiv = function _wordDiv (num, mode) {
-+    var shift = this.length - num.length;
-+
-+    var a = this.clone();
-+    var b = num;
-+
-+    // Normalize
-+    var bhi = b.words[b.length - 1] | 0;
-+    var bhiBits = this._countBits(bhi);
-+    shift = 26 - bhiBits;
-+    if (shift !== 0) {
-+      b = b.ushln(shift);
-+      a.iushln(shift);
-+      bhi = b.words[b.length - 1] | 0;
-+    }
-+
-+    // Initialize quotient
-+    var m = a.length - b.length;
-+    var q;
-+
-+    if (mode !== 'mod') {
-+      q = new BN(null);
-+      q.length = m + 1;
-+      q.words = new Array(q.length);
-+      for (var i = 0; i < q.length; i++) {
-+        q.words[i] = 0;
-+      }
-+    }
-+
-+    var diff = a.clone()._ishlnsubmul(b, 1, m);
-+    if (diff.negative === 0) {
-+      a = diff;
-+      if (q) {
-+        q.words[m] = 1;
-+      }
-+    }
-+
-+    for (var j = m - 1; j >= 0; j--) {
-+      var qj = (a.words[b.length + j] | 0) * 0x4000000 +
-+        (a.words[b.length + j - 1] | 0);
-+
-+      // NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max
-+      // (0x7ffffff)
-+      qj = Math.min((qj / bhi) | 0, 0x3ffffff);
-+
-+      a._ishlnsubmul(b, qj, j);
-+      while (a.negative !== 0) {
-+        qj--;
-+        a.negative = 0;
-+        a._ishlnsubmul(b, 1, j);
-+        if (!a.isZero()) {
-+          a.negative ^= 1;
-+        }
-+      }
-+      if (q) {
-+        q.words[j] = qj;
-+      }
-+    }
-+    if (q) {
-+      q.strip();
-+    }
-+    a.strip();
-+
-+    // Denormalize
-+    if (mode !== 'div' && shift !== 0) {
-+      a.iushrn(shift);
-+    }
-+
-+    return {
-+      div: q || null,
-+      mod: a
-+    };
-+  };
-+
-+  // NOTE: 1) `mode` can be set to `mod` to request mod only,
-+  //       to `div` to request div only, or be absent to
-+  //       request both div & mod
-+  //       2) `positive` is true if unsigned mod is requested
-+  BN.prototype.divmod = function divmod (num, mode, positive) {
-+    assert(!num.isZero());
-+
-+    if (this.isZero()) {
-+      return {
-+        div: new BN(0),
-+        mod: new BN(0)
-+      };
-+    }
-+
-+    var div, mod, res;
-+    if (this.negative !== 0 && num.negative === 0) {
-+      res = this.neg().divmod(num, mode);
-+
-+      if (mode !== 'mod') {
-+        div = res.div.neg();
-+      }
-+
-+      if (mode !== 'div') {
-+        mod = res.mod.neg();
-+        if (positive && mod.negative !== 0) {
-+          mod.iadd(num);
-+        }
-+      }
-+
-+      return {
-+        div: div,
-+        mod: mod
-+      };
-+    }
-+
-+    if (this.negative === 0 && num.negative !== 0) {
-+      res = this.divmod(num.neg(), mode);
-+
-+      if (mode !== 'mod') {
-+        div = res.div.neg();
-+      }
-+
-+      return {
-+        div: div,
-+        mod: res.mod
-+      };
-+    }
-+
-+    if ((this.negative & num.negative) !== 0) {
-+      res = this.neg().divmod(num.neg(), mode);
-+
-+      if (mode !== 'div') {
-+        mod = res.mod.neg();
-+        if (positive && mod.negative !== 0) {
-+          mod.isub(num);
-+        }
-+      }
-+
-+      return {
-+        div: res.div,
-+        mod: mod
-+      };
-+    }
-+
-+    // Both numbers are positive at this point
-+
-+    // Strip both numbers to approximate shift value
-+    if (num.length > this.length || this.cmp(num) < 0) {
-+      return {
-+        div: new BN(0),
-+        mod: this
-+      };
-+    }
-+
-+    // Very short reduction
-+    if (num.length === 1) {
-+      if (mode === 'div') {
-+        return {
-+          div: this.divn(num.words[0]),
-+          mod: null
-+        };
-+      }
-+
-+      if (mode === 'mod') {
-+        return {
-+          div: null,
-+          mod: new BN(this.modn(num.words[0]))
-+        };
-+      }
-+
-+      return {
-+        div: this.divn(num.words[0]),
-+        mod: new BN(this.modn(num.words[0]))
-+      };
-+    }
-+
-+    return this._wordDiv(num, mode);
-+  };
-+
-+  // Find `this` / `num`
-+  BN.prototype.div = function div (num) {
-+    return this.divmod(num, 'div', false).div;
-+  };
-+
-+  // Find `this` % `num`
-+  BN.prototype.mod = function mod (num) {
-+    return this.divmod(num, 'mod', false).mod;
-+  };
-+
-+  BN.prototype.umod = function umod (num) {
-+    return this.divmod(num, 'mod', true).mod;
-+  };
-+
-+  // Find Round(`this` / `num`)
-+  BN.prototype.divRound = function divRound (num) {
-+    var dm = this.divmod(num);
-+
-+    // Fast case - exact division
-+    if (dm.mod.isZero()) return dm.div;
-+
-+    var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod;
-+
-+    var half = num.ushrn(1);
-+    var r2 = num.andln(1);
-+    var cmp = mod.cmp(half);
-+
-+    // Round down
-+    if (cmp < 0 || r2 === 1 && cmp === 0) return dm.div;
-+
-+    // Round up
-+    return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1);
-+  };
-+
-+  BN.prototype.modn = function modn (num) {
-+    assert(num <= 0x3ffffff);
-+    var p = (1 << 26) % num;
-+
-+    var acc = 0;
-+    for (var i = this.length - 1; i >= 0; i--) {
-+      acc = (p * acc + (this.words[i] | 0)) % num;
-+    }
-+
-+    return acc;
-+  };
-+
-+  // In-place division by number
-+  BN.prototype.idivn = function idivn (num) {
-+    assert(num <= 0x3ffffff);
-+
-+    var carry = 0;
-+    for (var i = this.length - 1; i >= 0; i--) {
-+      var w = (this.words[i] | 0) + carry * 0x4000000;
-+      this.words[i] = (w / num) | 0;
-+      carry = w % num;
-+    }
-+
-+    return this.strip();
-+  };
-+
-+  BN.prototype.divn = function divn (num) {
-+    return this.clone().idivn(num);
-+  };
-+
-+  BN.prototype.egcd = function egcd (p) {
-+    assert(p.negative === 0);
-+    assert(!p.isZero());
-+
-+    var x = this;
-+    var y = p.clone();
-+
-+    if (x.negative !== 0) {
-+      x = x.umod(p);
-+    } else {
-+      x = x.clone();
-+    }
-+
-+    // A * x + B * y = x
-+    var A = new BN(1);
-+    var B = new BN(0);
-+
-+    // C * x + D * y = y
-+    var C = new BN(0);
-+    var D = new BN(1);
-+
-+    var g = 0;
-+
-+    while (x.isEven() && y.isEven()) {
-+      x.iushrn(1);
-+      y.iushrn(1);
-+      ++g;
-+    }
-+
-+    var yp = y.clone();
-+    var xp = x.clone();
-+
-+    while (!x.isZero()) {
-+      for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
-+      if (i > 0) {
-+        x.iushrn(i);
-+        while (i-- > 0) {
-+          if (A.isOdd() || B.isOdd()) {
-+            A.iadd(yp);
-+            B.isub(xp);
-+          }
-+
-+          A.iushrn(1);
-+          B.iushrn(1);
-+        }
-+      }
-+
-+      for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
-+      if (j > 0) {
-+        y.iushrn(j);
-+        while (j-- > 0) {
-+          if (C.isOdd() || D.isOdd()) {
-+            C.iadd(yp);
-+            D.isub(xp);
-+          }
-+
-+          C.iushrn(1);
-+          D.iushrn(1);
-+        }
-+      }
-+
-+      if (x.cmp(y) >= 0) {
-+        x.isub(y);
-+        A.isub(C);
-+        B.isub(D);
-+      } else {
-+        y.isub(x);
-+        C.isub(A);
-+        D.isub(B);
-+      }
-+    }
-+
-+    return {
-+      a: C,
-+      b: D,
-+      gcd: y.iushln(g)
-+    };
-+  };
-+
-+  // This is reduced incarnation of the binary EEA
-+  // above, designated to invert members of the
-+  // _prime_ fields F(p) at a maximal speed
-+  BN.prototype._invmp = function _invmp (p) {
-+    assert(p.negative === 0);
-+    assert(!p.isZero());
-+
-+    var a = this;
-+    var b = p.clone();
-+
-+    if (a.negative !== 0) {
-+      a = a.umod(p);
-+    } else {
-+      a = a.clone();
-+    }
-+
-+    var x1 = new BN(1);
-+    var x2 = new BN(0);
-+
-+    var delta = b.clone();
-+
-+    while (a.cmpn(1) > 0 && b.cmpn(1) > 0) {
-+      for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
-+      if (i > 0) {
-+        a.iushrn(i);
-+        while (i-- > 0) {
-+          if (x1.isOdd()) {
-+            x1.iadd(delta);
-+          }
-+
-+          x1.iushrn(1);
-+        }
-+      }
-+
-+      for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
-+      if (j > 0) {
-+        b.iushrn(j);
-+        while (j-- > 0) {
-+          if (x2.isOdd()) {
-+            x2.iadd(delta);
-+          }
-+
-+          x2.iushrn(1);
-+        }
-+      }
-+
-+      if (a.cmp(b) >= 0) {
-+        a.isub(b);
-+        x1.isub(x2);
-+      } else {
-+        b.isub(a);
-+        x2.isub(x1);
-+      }
-+    }
-+
-+    var res;
-+    if (a.cmpn(1) === 0) {
-+      res = x1;
-+    } else {
-+      res = x2;
-+    }
-+
-+    if (res.cmpn(0) < 0) {
-+      res.iadd(p);
-+    }
-+
-+    return res;
-+  };
-+
-+  BN.prototype.gcd = function gcd (num) {
-+    if (this.isZero()) return num.abs();
-+    if (num.isZero()) return this.abs();
-+
-+    var a = this.clone();
-+    var b = num.clone();
-+    a.negative = 0;
-+    b.negative = 0;
-+
-+    // Remove common factor of two
-+    for (var shift = 0; a.isEven() && b.isEven(); shift++) {
-+      a.iushrn(1);
-+      b.iushrn(1);
-+    }
-+
-+    do {
-+      while (a.isEven()) {
-+        a.iushrn(1);
-+      }
-+      while (b.isEven()) {
-+        b.iushrn(1);
-+      }
-+
-+      var r = a.cmp(b);
-+      if (r < 0) {
-+        // Swap `a` and `b` to make `a` always bigger than `b`
-+        var t = a;
-+        a = b;
-+        b = t;
-+      } else if (r === 0 || b.cmpn(1) === 0) {
-+        break;
-+      }
-+
-+      a.isub(b);
-+    } while (true);
-+
-+    return b.iushln(shift);
-+  };
-+
-+  // Invert number in the field F(num)
-+  BN.prototype.invm = function invm (num) {
-+    return this.egcd(num).a.umod(num);
-+  };
-+
-+  BN.prototype.isEven = function isEven () {
-+    return (this.words[0] & 1) === 0;
-+  };
-+
-+  BN.prototype.isOdd = function isOdd () {
-+    return (this.words[0] & 1) === 1;
-+  };
-+
-+  // And first word and num
-+  BN.prototype.andln = function andln (num) {
-+    return this.words[0] & num;
-+  };
-+
-+  // Increment at the bit position in-line
-+  BN.prototype.bincn = function bincn (bit) {
-+    assert(typeof bit === 'number');
-+    var r = bit % 26;
-+    var s = (bit - r) / 26;
-+    var q = 1 << r;
-+
-+    // Fast case: bit is much higher than all existing words
-+    if (this.length <= s) {
-+      this._expand(s + 1);
-+      this.words[s] |= q;
-+      return this;
-+    }
-+
-+    // Add bit and propagate, if needed
-+    var carry = q;
-+    for (var i = s; carry !== 0 && i < this.length; i++) {
-+      var w = this.words[i] | 0;
-+      w += carry;
-+      carry = w >>> 26;
-+      w &= 0x3ffffff;
-+      this.words[i] = w;
-+    }
-+    if (carry !== 0) {
-+      this.words[i] = carry;
-+      this.length++;
-+    }
-+    return this;
-+  };
-+
-+  BN.prototype.isZero = function isZero () {
-+    return this.length === 1 && this.words[0] === 0;
-+  };
-+
-+  BN.prototype.cmpn = function cmpn (num) {
-+    var negative = num < 0;
-+
-+    if (this.negative !== 0 && !negative) return -1;
-+    if (this.negative === 0 && negative) return 1;
-+
-+    this.strip();
-+
-+    var res;
-+    if (this.length > 1) {
-+      res = 1;
-+    } else {
-+      if (negative) {
-+        num = -num;
-+      }
-+
-+      assert(num <= 0x3ffffff, 'Number is too big');
-+
-+      var w = this.words[0] | 0;
-+      res = w === num ? 0 : w < num ? -1 : 1;
-+    }
-+    if (this.negative !== 0) return -res | 0;
-+    return res;
-+  };
-+
-+  // Compare two numbers and return:
-+  // 1 - if `this` > `num`
-+  // 0 - if `this` == `num`
-+  // -1 - if `this` < `num`
-+  BN.prototype.cmp = function cmp (num) {
-+    if (this.negative !== 0 && num.negative === 0) return -1;
-+    if (this.negative === 0 && num.negative !== 0) return 1;
-+
-+    var res = this.ucmp(num);
-+    if (this.negative !== 0) return -res | 0;
-+    return res;
-+  };
-+
-+  // Unsigned comparison
-+  BN.prototype.ucmp = function ucmp (num) {
-+    // At this point both numbers have the same sign
-+    if (this.length > num.length) return 1;
-+    if (this.length < num.length) return -1;
-+
-+    var res = 0;
-+    for (var i = this.length - 1; i >= 0; i--) {
-+      var a = this.words[i] | 0;
-+      var b = num.words[i] | 0;
-+
-+      if (a === b) continue;
-+      if (a < b) {
-+        res = -1;
-+      } else if (a > b) {
-+        res = 1;
-+      }
-+      break;
-+    }
-+    return res;
-+  };
-+
-+  BN.prototype.gtn = function gtn (num) {
-+    return this.cmpn(num) === 1;
-+  };
-+
-+  BN.prototype.gt = function gt (num) {
-+    return this.cmp(num) === 1;
-+  };
-+
-+  BN.prototype.gten = function gten (num) {
-+    return this.cmpn(num) >= 0;
-+  };
-+
-+  BN.prototype.gte = function gte (num) {
-+    return this.cmp(num) >= 0;
-+  };
-+
-+  BN.prototype.ltn = function ltn (num) {
-+    return this.cmpn(num) === -1;
-+  };
-+
-+  BN.prototype.lt = function lt (num) {
-+    return this.cmp(num) === -1;
-+  };
-+
-+  BN.prototype.lten = function lten (num) {
-+    return this.cmpn(num) <= 0;
-+  };
-+
-+  BN.prototype.lte = function lte (num) {
-+    return this.cmp(num) <= 0;
-+  };
-+
-+  BN.prototype.eqn = function eqn (num) {
-+    return this.cmpn(num) === 0;
-+  };
-+
-+  BN.prototype.eq = function eq (num) {
-+    return this.cmp(num) === 0;
-+  };
-+
-+  //
-+  // A reduce context, could be using montgomery or something better, depending
-+  // on the `m` itself.
-+  //
-+  BN.red = function red (num) {
-+    return new Red(num);
-+  };
-+
-+  BN.prototype.toRed = function toRed (ctx) {
-+    assert(!this.red, 'Already a number in reduction context');
-+    assert(this.negative === 0, 'red works only with positives');
-+    return ctx.convertTo(this)._forceRed(ctx);
-+  };
-+
-+  BN.prototype.fromRed = function fromRed () {
-+    assert(this.red, 'fromRed works only with numbers in reduction context');
-+    return this.red.convertFrom(this);
-+  };
-+
-+  BN.prototype._forceRed = function _forceRed (ctx) {
-+    this.red = ctx;
-+    return this;
-+  };
-+
-+  BN.prototype.forceRed = function forceRed (ctx) {
-+    assert(!this.red, 'Already a number in reduction context');
-+    return this._forceRed(ctx);
-+  };
-+
-+  BN.prototype.redAdd = function redAdd (num) {
-+    assert(this.red, 'redAdd works only with red numbers');
-+    return this.red.add(this, num);
-+  };
-+
-+  BN.prototype.redIAdd = function redIAdd (num) {
-+    assert(this.red, 'redIAdd works only with red numbers');
-+    return this.red.iadd(this, num);
-+  };
-+
-+  BN.prototype.redSub = function redSub (num) {
-+    assert(this.red, 'redSub works only with red numbers');
-+    return this.red.sub(this, num);
-+  };
-+
-+  BN.prototype.redISub = function redISub (num) {
-+    assert(this.red, 'redISub works only with red numbers');
-+    return this.red.isub(this, num);
-+  };
-+
-+  BN.prototype.redShl = function redShl (num) {
-+    assert(this.red, 'redShl works only with red numbers');
-+    return this.red.shl(this, num);
-+  };
-+
-+  BN.prototype.redMul = function redMul (num) {
-+    assert(this.red, 'redMul works only with red numbers');
-+    this.red._verify2(this, num);
-+    return this.red.mul(this, num);
-+  };
-+
-+  BN.prototype.redIMul = function redIMul (num) {
-+    assert(this.red, 'redMul works only with red numbers');
-+    this.red._verify2(this, num);
-+    return this.red.imul(this, num);
-+  };
-+
-+  BN.prototype.redSqr = function redSqr () {
-+    assert(this.red, 'redSqr works only with red numbers');
-+    this.red._verify1(this);
-+    return this.red.sqr(this);
-+  };
-+
-+  BN.prototype.redISqr = function redISqr () {
-+    assert(this.red, 'redISqr works only with red numbers');
-+    this.red._verify1(this);
-+    return this.red.isqr(this);
-+  };
-+
-+  // Square root over p
-+  BN.prototype.redSqrt = function redSqrt () {
-+    assert(this.red, 'redSqrt works only with red numbers');
-+    this.red._verify1(this);
-+    return this.red.sqrt(this);
-+  };
-+
-+  BN.prototype.redInvm = function redInvm () {
-+    assert(this.red, 'redInvm works only with red numbers');
-+    this.red._verify1(this);
-+    return this.red.invm(this);
-+  };
-+
-+  // Return negative clone of `this` % `red modulo`
-+  BN.prototype.redNeg = function redNeg () {
-+    assert(this.red, 'redNeg works only with red numbers');
-+    this.red._verify1(this);
-+    return this.red.neg(this);
-+  };
-+
-+  BN.prototype.redPow = function redPow (num) {
-+    assert(this.red && !num.red, 'redPow(normalNum)');
-+    this.red._verify1(this);
-+    return this.red.pow(this, num);
-+  };
-+
-+  // Prime numbers with efficient reduction
-+  var primes = {
-+    k256: null,
-+    p224: null,
-+    p192: null,
-+    p25519: null
-+  };
-+
-+  // Pseudo-Mersenne prime
-+  function MPrime (name, p) {
-+    // P = 2 ^ N - K
-+    this.name = name;
-+    this.p = new BN(p, 16);
-+    this.n = this.p.bitLength();
-+    this.k = new BN(1).iushln(this.n).isub(this.p);
-+
-+    this.tmp = this._tmp();
-+  }
-+
-+  MPrime.prototype._tmp = function _tmp () {
-+    var tmp = new BN(null);
-+    tmp.words = new Array(Math.ceil(this.n / 13));
-+    return tmp;
-+  };
-+
-+  MPrime.prototype.ireduce = function ireduce (num) {
-+    // Assumes that `num` is less than `P^2`
-+    // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P)
-+    var r = num;
-+    var rlen;
-+
-+    do {
-+      this.split(r, this.tmp);
-+      r = this.imulK(r);
-+      r = r.iadd(this.tmp);
-+      rlen = r.bitLength();
-+    } while (rlen > this.n);
-+
-+    var cmp = rlen < this.n ? -1 : r.ucmp(this.p);
-+    if (cmp === 0) {
-+      r.words[0] = 0;
-+      r.length = 1;
-+    } else if (cmp > 0) {
-+      r.isub(this.p);
-+    } else {
-+      r.strip();
-+    }
-+
-+    return r;
-+  };
-+
-+  MPrime.prototype.split = function split (input, out) {
-+    input.iushrn(this.n, 0, out);
-+  };
-+
-+  MPrime.prototype.imulK = function imulK (num) {
-+    return num.imul(this.k);
-+  };
-+
-+  function K256 () {
-+    MPrime.call(
-+      this,
-+      'k256',
-+      'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f');
-+  }
-+  inherits(K256, MPrime);
-+
-+  K256.prototype.split = function split (input, output) {
-+    // 256 = 9 * 26 + 22
-+    var mask = 0x3fffff;
-+
-+    var outLen = Math.min(input.length, 9);
-+    for (var i = 0; i < outLen; i++) {
-+      output.words[i] = input.words[i];
-+    }
-+    output.length = outLen;
-+
-+    if (input.length <= 9) {
-+      input.words[0] = 0;
-+      input.length = 1;
-+      return;
-+    }
-+
-+    // Shift by 9 limbs
-+    var prev = input.words[9];
-+    output.words[output.length++] = prev & mask;
-+
-+    for (i = 10; i < input.length; i++) {
-+      var next = input.words[i] | 0;
-+      input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22);
-+      prev = next;
-+    }
-+    prev >>>= 22;
-+    input.words[i - 10] = prev;
-+    if (prev === 0 && input.length > 10) {
-+      input.length -= 10;
-+    } else {
-+      input.length -= 9;
-+    }
-+  };
-+
-+  K256.prototype.imulK = function imulK (num) {
-+    // K = 0x1000003d1 = [ 0x40, 0x3d1 ]
-+    num.words[num.length] = 0;
-+    num.words[num.length + 1] = 0;
-+    num.length += 2;
-+
-+    // bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390
-+    var lo = 0;
-+    for (var i = 0; i < num.length; i++) {
-+      var w = num.words[i] | 0;
-+      lo += w * 0x3d1;
-+      num.words[i] = lo & 0x3ffffff;
-+      lo = w * 0x40 + ((lo / 0x4000000) | 0);
-+    }
-+
-+    // Fast length reduction
-+    if (num.words[num.length - 1] === 0) {
-+      num.length--;
-+      if (num.words[num.length - 1] === 0) {
-+        num.length--;
-+      }
-+    }
-+    return num;
-+  };
-+
-+  function P224 () {
-+    MPrime.call(
-+      this,
-+      'p224',
-+      'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001');
-+  }
-+  inherits(P224, MPrime);
-+
-+  function P192 () {
-+    MPrime.call(
-+      this,
-+      'p192',
-+      'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff');
-+  }
-+  inherits(P192, MPrime);
-+
-+  function P25519 () {
-+    // 2 ^ 255 - 19
-+    MPrime.call(
-+      this,
-+      '25519',
-+      '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed');
-+  }
-+  inherits(P25519, MPrime);
-+
-+  P25519.prototype.imulK = function imulK (num) {
-+    // K = 0x13
-+    var carry = 0;
-+    for (var i = 0; i < num.length; i++) {
-+      var hi = (num.words[i] | 0) * 0x13 + carry;
-+      var lo = hi & 0x3ffffff;
-+      hi >>>= 26;
-+
-+      num.words[i] = lo;
-+      carry = hi;
-+    }
-+    if (carry !== 0) {
-+      num.words[num.length++] = carry;
-+    }
-+    return num;
-+  };
-+
-+  // Exported mostly for testing purposes, use plain name instead
-+  BN._prime = function prime (name) {
-+    // Cached version of prime
-+    if (primes[name]) return primes[name];
-+
-+    var prime;
-+    if (name === 'k256') {
-+      prime = new K256();
-+    } else if (name === 'p224') {
-+      prime = new P224();
-+    } else if (name === 'p192') {
-+      prime = new P192();
-+    } else if (name === 'p25519') {
-+      prime = new P25519();
-+    } else {
-+      throw new Error('Unknown prime ' + name);
-+    }
-+    primes[name] = prime;
-+
-+    return prime;
-+  };
-+
-+  //
-+  // Base reduction engine
-+  //
-+  function Red (m) {
-+    if (typeof m === 'string') {
-+      var prime = BN._prime(m);
-+      this.m = prime.p;
-+      this.prime = prime;
-+    } else {
-+      assert(m.gtn(1), 'modulus must be greater than 1');
-+      this.m = m;
-+      this.prime = null;
-+    }
-+  }
-+
-+  Red.prototype._verify1 = function _verify1 (a) {
-+    assert(a.negative === 0, 'red works only with positives');
-+    assert(a.red, 'red works only with red numbers');
-+  };
-+
-+  Red.prototype._verify2 = function _verify2 (a, b) {
-+    assert((a.negative | b.negative) === 0, 'red works only with positives');
-+    assert(a.red && a.red === b.red,
-+      'red works only with red numbers');
-+  };
-+
-+  Red.prototype.imod = function imod (a) {
-+    if (this.prime) return this.prime.ireduce(a)._forceRed(this);
-+    return a.umod(this.m)._forceRed(this);
-+  };
-+
-+  Red.prototype.neg = function neg (a) {
-+    if (a.isZero()) {
-+      return a.clone();
-+    }
-+
-+    return this.m.sub(a)._forceRed(this);
-+  };
-+
-+  Red.prototype.add = function add (a, b) {
-+    this._verify2(a, b);
-+
-+    var res = a.add(b);
-+    if (res.cmp(this.m) >= 0) {
-+      res.isub(this.m);
-+    }
-+    return res._forceRed(this);
-+  };
-+
-+  Red.prototype.iadd = function iadd (a, b) {
-+    this._verify2(a, b);
-+
-+    var res = a.iadd(b);
-+    if (res.cmp(this.m) >= 0) {
-+      res.isub(this.m);
-+    }
-+    return res;
-+  };
-+
-+  Red.prototype.sub = function sub (a, b) {
-+    this._verify2(a, b);
-+
-+    var res = a.sub(b);
-+    if (res.cmpn(0) < 0) {
-+      res.iadd(this.m);
-+    }
-+    return res._forceRed(this);
-+  };
-+
-+  Red.prototype.isub = function isub (a, b) {
-+    this._verify2(a, b);
-+
-+    var res = a.isub(b);
-+    if (res.cmpn(0) < 0) {
-+      res.iadd(this.m);
-+    }
-+    return res;
-+  };
-+
-+  Red.prototype.shl = function shl (a, num) {
-+    this._verify1(a);
-+    return this.imod(a.ushln(num));
-+  };
-+
-+  Red.prototype.imul = function imul (a, b) {
-+    this._verify2(a, b);
-+    return this.imod(a.imul(b));
-+  };
-+
-+  Red.prototype.mul = function mul (a, b) {
-+    this._verify2(a, b);
-+    return this.imod(a.mul(b));
-+  };
-+
-+  Red.prototype.isqr = function isqr (a) {
-+    return this.imul(a, a.clone());
-+  };
-+
-+  Red.prototype.sqr = function sqr (a) {
-+    return this.mul(a, a);
-+  };
-+
-+  Red.prototype.sqrt = function sqrt (a) {
-+    if (a.isZero()) return a.clone();
-+
-+    var mod3 = this.m.andln(3);
-+    assert(mod3 % 2 === 1);
-+
-+    // Fast case
-+    if (mod3 === 3) {
-+      var pow = this.m.add(new BN(1)).iushrn(2);
-+      return this.pow(a, pow);
-+    }
-+
-+    // Tonelli-Shanks algorithm (Totally unoptimized and slow)
-+    //
-+    // Find Q and S, that Q * 2 ^ S = (P - 1)
-+    var q = this.m.subn(1);
-+    var s = 0;
-+    while (!q.isZero() && q.andln(1) === 0) {
-+      s++;
-+      q.iushrn(1);
-+    }
-+    assert(!q.isZero());
-+
-+    var one = new BN(1).toRed(this);
-+    var nOne = one.redNeg();
-+
-+    // Find quadratic non-residue
-+    // NOTE: Max is such because of generalized Riemann hypothesis.
-+    var lpow = this.m.subn(1).iushrn(1);
-+    var z = this.m.bitLength();
-+    z = new BN(2 * z * z).toRed(this);
-+
-+    while (this.pow(z, lpow).cmp(nOne) !== 0) {
-+      z.redIAdd(nOne);
-+    }
-+
-+    var c = this.pow(z, q);
-+    var r = this.pow(a, q.addn(1).iushrn(1));
-+    var t = this.pow(a, q);
-+    var m = s;
-+    while (t.cmp(one) !== 0) {
-+      var tmp = t;
-+      for (var i = 0; tmp.cmp(one) !== 0; i++) {
-+        tmp = tmp.redSqr();
-+      }
-+      assert(i < m);
-+      var b = this.pow(c, new BN(1).iushln(m - i - 1));
-+
-+      r = r.redMul(b);
-+      c = b.redSqr();
-+      t = t.redMul(c);
-+      m = i;
-+    }
-+
-+    return r;
-+  };
-+
-+  Red.prototype.invm = function invm (a) {
-+    var inv = a._invmp(this.m);
-+    if (inv.negative !== 0) {
-+      inv.negative = 0;
-+      return this.imod(inv).redNeg();
-+    } else {
-+      return this.imod(inv);
-+    }
-+  };
-+
-+  Red.prototype.pow = function pow (a, num) {
-+    if (num.isZero()) return new BN(1);
-+    if (num.cmpn(1) === 0) return a.clone();
-+
-+    var windowSize = 4;
-+    var wnd = new Array(1 << windowSize);
-+    wnd[0] = new BN(1).toRed(this);
-+    wnd[1] = a;
-+    for (var i = 2; i < wnd.length; i++) {
-+      wnd[i] = this.mul(wnd[i - 1], a);
-+    }
-+
-+    var res = wnd[0];
-+    var current = 0;
-+    var currentLen = 0;
-+    var start = num.bitLength() % 26;
-+    if (start === 0) {
-+      start = 26;
-+    }
-+
-+    for (i = num.length - 1; i >= 0; i--) {
-+      var word = num.words[i];
-+      for (var j = start - 1; j >= 0; j--) {
-+        var bit = (word >> j) & 1;
-+        if (res !== wnd[0]) {
-+          res = this.sqr(res);
-+        }
-+
-+        if (bit === 0 && current === 0) {
-+          currentLen = 0;
-+          continue;
-+        }
-+
-+        current <<= 1;
-+        current |= bit;
-+        currentLen++;
-+        if (currentLen !== windowSize && (i !== 0 || j !== 0)) continue;
-+
-+        res = this.mul(res, wnd[current]);
-+        currentLen = 0;
-+        current = 0;
-+      }
-+      start = 26;
-+    }
-+
-+    return res;
-+  };
-+
-+  Red.prototype.convertTo = function convertTo (num) {
-+    var r = num.umod(this.m);
-+
-+    return r === num ? r.clone() : r;
-+  };
-+
-+  Red.prototype.convertFrom = function convertFrom (num) {
-+    var res = num.clone();
-+    res.red = null;
-+    return res;
-+  };
-+
-+  //
-+  // Montgomery method engine
-+  //
-+
-+  BN.mont = function mont (num) {
-+    return new Mont(num);
-+  };
-+
-+  function Mont (m) {
-+    Red.call(this, m);
-+
-+    this.shift = this.m.bitLength();
-+    if (this.shift % 26 !== 0) {
-+      this.shift += 26 - (this.shift % 26);
-+    }
-+
-+    this.r = new BN(1).iushln(this.shift);
-+    this.r2 = this.imod(this.r.sqr());
-+    this.rinv = this.r._invmp(this.m);
-+
-+    this.minv = this.rinv.mul(this.r).isubn(1).div(this.m);
-+    this.minv = this.minv.umod(this.r);
-+    this.minv = this.r.sub(this.minv);
-+  }
-+  inherits(Mont, Red);
-+
-+  Mont.prototype.convertTo = function convertTo (num) {
-+    return this.imod(num.ushln(this.shift));
-+  };
-+
-+  Mont.prototype.convertFrom = function convertFrom (num) {
-+    var r = this.imod(num.mul(this.rinv));
-+    r.red = null;
-+    return r;
-+  };
-+
-+  Mont.prototype.imul = function imul (a, b) {
-+    if (a.isZero() || b.isZero()) {
-+      a.words[0] = 0;
-+      a.length = 1;
-+      return a;
-+    }
-+
-+    var t = a.imul(b);
-+    var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
-+    var u = t.isub(c).iushrn(this.shift);
-+    var res = u;
-+
-+    if (u.cmp(this.m) >= 0) {
-+      res = u.isub(this.m);
-+    } else if (u.cmpn(0) < 0) {
-+      res = u.iadd(this.m);
-+    }
-+
-+    return res._forceRed(this);
-+  };
-+
-+  Mont.prototype.mul = function mul (a, b) {
-+    if (a.isZero() || b.isZero()) return new BN(0)._forceRed(this);
-+
-+    var t = a.mul(b);
-+    var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
-+    var u = t.isub(c).iushrn(this.shift);
-+    var res = u;
-+    if (u.cmp(this.m) >= 0) {
-+      res = u.isub(this.m);
-+    } else if (u.cmpn(0) < 0) {
-+      res = u.iadd(this.m);
-+    }
-+
-+    return res._forceRed(this);
-+  };
-+
-+  Mont.prototype.invm = function invm (a) {
-+    // (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R
-+    var res = this.imod(a._invmp(this.m).mul(this.r2));
-+    return res._forceRed(this);
-+  };
-+})(typeof module === 'undefined' || module, this);
-+
-+},{}],2:[function(require,module,exports){
-+'use strict';
-+
-+var elliptic = exports;
-+
-+elliptic.version = require('../package.json').version;
-+elliptic.utils = require('./elliptic/utils');
-+elliptic.rand = require('brorand');
-+elliptic.hmacDRBG = require('./elliptic/hmac-drbg');
-+elliptic.curve = require('./elliptic/curve');
-+elliptic.curves = require('./elliptic/curves');
-+
-+// Protocols
-+elliptic.ec = require('./elliptic/ec');
-+elliptic.eddsa = require('./elliptic/eddsa');
-+
-+},{"../package.json":26,"./elliptic/curve":5,"./elliptic/curves":8,"./elliptic/ec":9,"./elliptic/eddsa":12,"./elliptic/hmac-drbg":15,"./elliptic/utils":17,"brorand":18}],3:[function(require,module,exports){
-+'use strict';
-+
-+var BN = require('bn.js');
-+var elliptic = require('../../elliptic');
-+var utils = elliptic.utils;
-+var getNAF = utils.getNAF;
-+var getJSF = utils.getJSF;
-+var assert = utils.assert;
-+
-+function BaseCurve(type, conf) {
-+  this.type = type;
-+  this.p = new BN(conf.p, 16);
-+
-+  // Use Montgomery, when there is no fast reduction for the prime
-+  this.red = conf.prime ? BN.red(conf.prime) : BN.mont(this.p);
-+
-+  // Useful for many curves
-+  this.zero = new BN(0).toRed(this.red);
-+  this.one = new BN(1).toRed(this.red);
-+  this.two = new BN(2).toRed(this.red);
-+
-+  // Curve configuration, optional
-+  this.n = conf.n && new BN(conf.n, 16);
-+  this.g = conf.g && this.pointFromJSON(conf.g, conf.gRed);
-+
-+  // Temporary arrays
-+  this._wnafT1 = new Array(4);
-+  this._wnafT2 = new Array(4);
-+  this._wnafT3 = new Array(4);
-+  this._wnafT4 = new Array(4);
-+
-+  // Generalized Greg Maxwell's trick
-+  var adjustCount = this.n && this.p.div(this.n);
-+  if (!adjustCount || adjustCount.cmpn(100) > 0) {
-+    this.redN = null;
-+  } else {
-+    this._maxwellTrick = true;
-+    this.redN = this.n.toRed(this.red);
-+  }
-+}
-+module.exports = BaseCurve;
-+
-+BaseCurve.prototype.point = function point() {
-+  throw new Error('Not implemented');
-+};
-+
-+BaseCurve.prototype.validate = function validate() {
-+  throw new Error('Not implemented');
-+};
-+
-+BaseCurve.prototype._fixedNafMul = function _fixedNafMul(p, k) {
-+  assert(p.precomputed);
-+  var doubles = p._getDoubles();
-+
-+  var naf = getNAF(k, 1);
-+  var I = (1 << (doubles.step + 1)) - (doubles.step % 2 === 0 ? 2 : 1);
-+  I /= 3;
-+
-+  // Translate into more windowed form
-+  var repr = [];
-+  for (var j = 0; j < naf.length; j += doubles.step) {
-+    var nafW = 0;
-+    for (var k = j + doubles.step - 1; k >= j; k--)
-+      nafW = (nafW << 1) + naf[k];
-+    repr.push(nafW);
-+  }
-+
-+  var a = this.jpoint(null, null, null);
-+  var b = this.jpoint(null, null, null);
-+  for (var i = I; i > 0; i--) {
-+    for (var j = 0; j < repr.length; j++) {
-+      var nafW = repr[j];
-+      if (nafW === i)
-+        b = b.mixedAdd(doubles.points[j]);
-+      else if (nafW === -i)
-+        b = b.mixedAdd(doubles.points[j].neg());
-+    }
-+    a = a.add(b);
-+  }
-+  return a.toP();
-+};
-+
-+BaseCurve.prototype._wnafMul = function _wnafMul(p, k) {
-+  var w = 4;
-+
-+  // Precompute window
-+  var nafPoints = p._getNAFPoints(w);
-+  w = nafPoints.wnd;
-+  var wnd = nafPoints.points;
-+
-+  // Get NAF form
-+  var naf = getNAF(k, w);
-+
-+  // Add `this`*(N+1) for every w-NAF index
-+  var acc = this.jpoint(null, null, null);
-+  for (var i = naf.length - 1; i >= 0; i--) {
-+    // Count zeroes
-+    for (var k = 0; i >= 0 && naf[i] === 0; i--)
-+      k++;
-+    if (i >= 0)
-+      k++;
-+    acc = acc.dblp(k);
-+
-+    if (i < 0)
-+      break;
-+    var z = naf[i];
-+    assert(z !== 0);
-+    if (p.type === 'affine') {
-+      // J +- P
-+      if (z > 0)
-+        acc = acc.mixedAdd(wnd[(z - 1) >> 1]);
-+      else
-+        acc = acc.mixedAdd(wnd[(-z - 1) >> 1].neg());
-+    } else {
-+      // J +- J
-+      if (z > 0)
-+        acc = acc.add(wnd[(z - 1) >> 1]);
-+      else
-+        acc = acc.add(wnd[(-z - 1) >> 1].neg());
-+    }
-+  }
-+  return p.type === 'affine' ? acc.toP() : acc;
-+};
-+
-+BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW,
-+                                                       points,
-+                                                       coeffs,
-+                                                       len,
-+                                                       jacobianResult) {
-+  var wndWidth = this._wnafT1;
-+  var wnd = this._wnafT2;
-+  var naf = this._wnafT3;
-+
-+  // Fill all arrays
-+  var max = 0;
-+  for (var i = 0; i < len; i++) {
-+    var p = points[i];
-+    var nafPoints = p._getNAFPoints(defW);
-+    wndWidth[i] = nafPoints.wnd;
-+    wnd[i] = nafPoints.points;
-+  }
-+
-+  // Comb small window NAFs
-+  for (var i = len - 1; i >= 1; i -= 2) {
-+    var a = i - 1;
-+    var b = i;
-+    if (wndWidth[a] !== 1 || wndWidth[b] !== 1) {
-+      naf[a] = getNAF(coeffs[a], wndWidth[a]);
-+      naf[b] = getNAF(coeffs[b], wndWidth[b]);
-+      max = Math.max(naf[a].length, max);
-+      max = Math.max(naf[b].length, max);
-+      continue;
-+    }
-+
-+    var comb = [
-+      points[a], /* 1 */
-+      null, /* 3 */
-+      null, /* 5 */
-+      points[b] /* 7 */
-+    ];
-+
-+    // Try to avoid Projective points, if possible
-+    if (points[a].y.cmp(points[b].y) === 0) {
-+      comb[1] = points[a].add(points[b]);
-+      comb[2] = points[a].toJ().mixedAdd(points[b].neg());
-+    } else if (points[a].y.cmp(points[b].y.redNeg()) === 0) {
-+      comb[1] = points[a].toJ().mixedAdd(points[b]);
-+      comb[2] = points[a].add(points[b].neg());
-+    } else {
-+      comb[1] = points[a].toJ().mixedAdd(points[b]);
-+      comb[2] = points[a].toJ().mixedAdd(points[b].neg());
-+    }
-+
-+    var index = [
-+      -3, /* -1 -1 */
-+      -1, /* -1 0 */
-+      -5, /* -1 1 */
-+      -7, /* 0 -1 */
-+      0, /* 0 0 */
-+      7, /* 0 1 */
-+      5, /* 1 -1 */
-+      1, /* 1 0 */
-+      3  /* 1 1 */
-+    ];
-+
-+    var jsf = getJSF(coeffs[a], coeffs[b]);
-+    max = Math.max(jsf[0].length, max);
-+    naf[a] = new Array(max);
-+    naf[b] = new Array(max);
-+    for (var j = 0; j < max; j++) {
-+      var ja = jsf[0][j] | 0;
-+      var jb = jsf[1][j] | 0;
-+
-+      naf[a][j] = index[(ja + 1) * 3 + (jb + 1)];
-+      naf[b][j] = 0;
-+      wnd[a] = comb;
-+    }
-+  }
-+
-+  var acc = this.jpoint(null, null, null);
-+  var tmp = this._wnafT4;
-+  for (var i = max; i >= 0; i--) {
-+    var k = 0;
-+
-+    while (i >= 0) {
-+      var zero = true;
-+      for (var j = 0; j < len; j++) {
-+        tmp[j] = naf[j][i] | 0;
-+        if (tmp[j] !== 0)
-+          zero = false;
-+      }
-+      if (!zero)
-+        break;
-+      k++;
-+      i--;
-+    }
-+    if (i >= 0)
-+      k++;
-+    acc = acc.dblp(k);
-+    if (i < 0)
-+      break;
-+
-+    for (var j = 0; j < len; j++) {
-+      var z = tmp[j];
-+      var p;
-+      if (z === 0)
-+        continue;
-+      else if (z > 0)
-+        p = wnd[j][(z - 1) >> 1];
-+      else if (z < 0)
-+        p = wnd[j][(-z - 1) >> 1].neg();
-+
-+      if (p.type === 'affine')
-+        acc = acc.mixedAdd(p);
-+      else
-+        acc = acc.add(p);
-+    }
-+  }
-+  // Zeroify references
-+  for (var i = 0; i < len; i++)
-+    wnd[i] = null;
-+
-+  if (jacobianResult)
-+    return acc;
-+  else
-+    return acc.toP();
-+};
-+
-+function BasePoint(curve, type) {
-+  this.curve = curve;
-+  this.type = type;
-+  this.precomputed = null;
-+}
-+BaseCurve.BasePoint = BasePoint;
-+
-+BasePoint.prototype.eq = function eq(/*other*/) {
-+  throw new Error('Not implemented');
-+};
-+
-+BasePoint.prototype.validate = function validate() {
-+  return this.curve.validate(this);
-+};
-+
-+BaseCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
-+  bytes = utils.toArray(bytes, enc);
-+
-+  var len = this.p.byteLength();
-+
-+  // uncompressed, hybrid-odd, hybrid-even
-+  if ((bytes[0] === 0x04 || bytes[0] === 0x06 || bytes[0] === 0x07) &&
-+      bytes.length - 1 === 2 * len) {
-+    if (bytes[0] === 0x06)
-+      assert(bytes[bytes.length - 1] % 2 === 0);
-+    else if (bytes[0] === 0x07)
-+      assert(bytes[bytes.length - 1] % 2 === 1);
-+
-+    var res =  this.point(bytes.slice(1, 1 + len),
-+                          bytes.slice(1 + len, 1 + 2 * len));
-+
-+    return res;
-+  } else if ((bytes[0] === 0x02 || bytes[0] === 0x03) &&
-+              bytes.length - 1 === len) {
-+    return this.pointFromX(bytes.slice(1, 1 + len), bytes[0] === 0x03);
-+  }
-+  throw new Error('Unknown point format');
-+};
-+
-+BasePoint.prototype.encodeCompressed = function encodeCompressed(enc) {
-+  return this.encode(enc, true);
-+};
-+
-+BasePoint.prototype._encode = function _encode(compact) {
-+  var len = this.curve.p.byteLength();
-+  var x = this.getX().toArray('be', len);
-+
-+  if (compact)
-+    return [ this.getY().isEven() ? 0x02 : 0x03 ].concat(x);
-+
-+  return [ 0x04 ].concat(x, this.getY().toArray('be', len)) ;
-+};
-+
-+BasePoint.prototype.encode = function encode(enc, compact) {
-+  return utils.encode(this._encode(compact), enc);
-+};
-+
-+BasePoint.prototype.precompute = function precompute(power) {
-+  if (this.precomputed)
-+    return this;
-+
-+  var precomputed = {
-+    doubles: null,
-+    naf: null,
-+    beta: null
-+  };
-+  precomputed.naf = this._getNAFPoints(8);
-+  precomputed.doubles = this._getDoubles(4, power);
-+  precomputed.beta = this._getBeta();
-+  this.precomputed = precomputed;
-+
-+  return this;
-+};
-+
-+BasePoint.prototype._hasDoubles = function _hasDoubles(k) {
-+  if (!this.precomputed)
-+    return false;
-+
-+  var doubles = this.precomputed.doubles;
-+  if (!doubles)
-+    return false;
-+
-+  return doubles.points.length >= Math.ceil((k.bitLength() + 1) / doubles.step);
-+};
-+
-+BasePoint.prototype._getDoubles = function _getDoubles(step, power) {
-+  if (this.precomputed && this.precomputed.doubles)
-+    return this.precomputed.doubles;
-+
-+  var doubles = [ this ];
-+  var acc = this;
-+  for (var i = 0; i < power; i += step) {
-+    for (var j = 0; j < step; j++)
-+      acc = acc.dbl();
-+    doubles.push(acc);
-+  }
-+  return {
-+    step: step,
-+    points: doubles
-+  };
-+};
-+
-+BasePoint.prototype._getNAFPoints = function _getNAFPoints(wnd) {
-+  if (this.precomputed && this.precomputed.naf)
-+    return this.precomputed.naf;
-+
-+  var res = [ this ];
-+  var max = (1 << wnd) - 1;
-+  var dbl = max === 1 ? null : this.dbl();
-+  for (var i = 1; i < max; i++)
-+    res[i] = res[i - 1].add(dbl);
-+  return {
-+    wnd: wnd,
-+    points: res
-+  };
-+};
-+
-+BasePoint.prototype._getBeta = function _getBeta() {
-+  return null;
-+};
-+
-+BasePoint.prototype.dblp = function dblp(k) {
-+  var r = this;
-+  for (var i = 0; i < k; i++)
-+    r = r.dbl();
-+  return r;
-+};
-+
-+},{"../../elliptic":2,"bn.js":1}],4:[function(require,module,exports){
-+'use strict';
-+
-+var curve = require('../curve');
-+var elliptic = require('../../elliptic');
-+var BN = require('bn.js');
-+var inherits = require('inherits');
-+var Base = curve.base;
-+
-+var assert = elliptic.utils.assert;
-+
-+function EdwardsCurve(conf) {
-+  // NOTE: Important as we are creating point in Base.call()
-+  this.twisted = (conf.a | 0) !== 1;
-+  this.mOneA = this.twisted && (conf.a | 0) === -1;
-+  this.extended = this.mOneA;
-+
-+  Base.call(this, 'edwards', conf);
-+
-+  this.a = new BN(conf.a, 16).umod(this.red.m);
-+  this.a = this.a.toRed(this.red);
-+  this.c = new BN(conf.c, 16).toRed(this.red);
-+  this.c2 = this.c.redSqr();
-+  this.d = new BN(conf.d, 16).toRed(this.red);
-+  this.dd = this.d.redAdd(this.d);
-+
-+  assert(!this.twisted || this.c.fromRed().cmpn(1) === 0);
-+  this.oneC = (conf.c | 0) === 1;
-+}
-+inherits(EdwardsCurve, Base);
-+module.exports = EdwardsCurve;
-+
-+EdwardsCurve.prototype._mulA = function _mulA(num) {
-+  if (this.mOneA)
-+    return num.redNeg();
-+  else
-+    return this.a.redMul(num);
-+};
-+
-+EdwardsCurve.prototype._mulC = function _mulC(num) {
-+  if (this.oneC)
-+    return num;
-+  else
-+    return this.c.redMul(num);
-+};
-+
-+// Just for compatibility with Short curve
-+EdwardsCurve.prototype.jpoint = function jpoint(x, y, z, t) {
-+  return this.point(x, y, z, t);
-+};
-+
-+EdwardsCurve.prototype.pointFromX = function pointFromX(x, odd) {
-+  x = new BN(x, 16);
-+  if (!x.red)
-+    x = x.toRed(this.red);
-+
-+  var x2 = x.redSqr();
-+  var rhs = this.c2.redSub(this.a.redMul(x2));
-+  var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2));
-+
-+  var y2 = rhs.redMul(lhs.redInvm());
-+  var y = y2.redSqrt();
-+  if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
-+    throw new Error('invalid point');
-+
-+  var isOdd = y.fromRed().isOdd();
-+  if (odd && !isOdd || !odd && isOdd)
-+    y = y.redNeg();
-+
-+  return this.point(x, y);
-+};
-+
-+EdwardsCurve.prototype.pointFromY = function pointFromY(y, odd) {
-+  y = new BN(y, 16);
-+  if (!y.red)
-+    y = y.toRed(this.red);
-+
-+  // x^2 = (y^2 - 1) / (d y^2 + 1)
-+  var y2 = y.redSqr();
-+  var lhs = y2.redSub(this.one);
-+  var rhs = y2.redMul(this.d).redAdd(this.one);
-+  var x2 = lhs.redMul(rhs.redInvm());
-+
-+  if (x2.cmp(this.zero) === 0) {
-+    if (odd)
-+      throw new Error('invalid point');
-+    else
-+      return this.point(this.zero, y);
-+  }
-+
-+  var x = x2.redSqrt();
-+  if (x.redSqr().redSub(x2).cmp(this.zero) !== 0)
-+    throw new Error('invalid point');
-+
-+  if (x.isOdd() !== odd)
-+    x = x.redNeg();
-+
-+  return this.point(x, y);
-+};
-+
-+EdwardsCurve.prototype.validate = function validate(point) {
-+  if (point.isInfinity())
-+    return true;
-+
-+  // Curve: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2)
-+  point.normalize();
-+
-+  var x2 = point.x.redSqr();
-+  var y2 = point.y.redSqr();
-+  var lhs = x2.redMul(this.a).redAdd(y2);
-+  var rhs = this.c2.redMul(this.one.redAdd(this.d.redMul(x2).redMul(y2)));
-+
-+  return lhs.cmp(rhs) === 0;
-+};
-+
-+function Point(curve, x, y, z, t) {
-+  Base.BasePoint.call(this, curve, 'projective');
-+  if (x === null && y === null && z === null) {
-+    this.x = this.curve.zero;
-+    this.y = this.curve.one;
-+    this.z = this.curve.one;
-+    this.t = this.curve.zero;
-+    this.zOne = true;
-+  } else {
-+    this.x = new BN(x, 16);
-+    this.y = new BN(y, 16);
-+    this.z = z ? new BN(z, 16) : this.curve.one;
-+    this.t = t && new BN(t, 16);
-+    if (!this.x.red)
-+      this.x = this.x.toRed(this.curve.red);
-+    if (!this.y.red)
-+      this.y = this.y.toRed(this.curve.red);
-+    if (!this.z.red)
-+      this.z = this.z.toRed(this.curve.red);
-+    if (this.t && !this.t.red)
-+      this.t = this.t.toRed(this.curve.red);
-+    this.zOne = this.z === this.curve.one;
-+
-+    // Use extended coordinates
-+    if (this.curve.extended && !this.t) {
-+      this.t = this.x.redMul(this.y);
-+      if (!this.zOne)
-+        this.t = this.t.redMul(this.z.redInvm());
-+    }
-+  }
-+}
-+inherits(Point, Base.BasePoint);
-+
-+EdwardsCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
-+  return Point.fromJSON(this, obj);
-+};
-+
-+EdwardsCurve.prototype.point = function point(x, y, z, t) {
-+  return new Point(this, x, y, z, t);
-+};
-+
-+Point.fromJSON = function fromJSON(curve, obj) {
-+  return new Point(curve, obj[0], obj[1], obj[2]);
-+};
-+
-+Point.prototype.inspect = function inspect() {
-+  if (this.isInfinity())
-+    return '<EC Point Infinity>';
-+  return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
-+      ' y: ' + this.y.fromRed().toString(16, 2) +
-+      ' z: ' + this.z.fromRed().toString(16, 2) + '>';
-+};
-+
-+Point.prototype.isInfinity = function isInfinity() {
-+  // XXX This code assumes that zero is always zero in red
-+  return this.x.cmpn(0) === 0 &&
-+         this.y.cmp(this.z) === 0;
-+};
-+
-+Point.prototype._extDbl = function _extDbl() {
-+  // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
-+  //     #doubling-dbl-2008-hwcd
-+  // 4M + 4S
-+
-+  // A = X1^2
-+  var a = this.x.redSqr();
-+  // B = Y1^2
-+  var b = this.y.redSqr();
-+  // C = 2 * Z1^2
-+  var c = this.z.redSqr();
-+  c = c.redIAdd(c);
-+  // D = a * A
-+  var d = this.curve._mulA(a);
-+  // E = (X1 + Y1)^2 - A - B
-+  var e = this.x.redAdd(this.y).redSqr().redISub(a).redISub(b);
-+  // G = D + B
-+  var g = d.redAdd(b);
-+  // F = G - C
-+  var f = g.redSub(c);
-+  // H = D - B
-+  var h = d.redSub(b);
-+  // X3 = E * F
-+  var nx = e.redMul(f);
-+  // Y3 = G * H
-+  var ny = g.redMul(h);
-+  // T3 = E * H
-+  var nt = e.redMul(h);
-+  // Z3 = F * G
-+  var nz = f.redMul(g);
-+  return this.curve.point(nx, ny, nz, nt);
-+};
-+
-+Point.prototype._projDbl = function _projDbl() {
-+  // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
-+  //     #doubling-dbl-2008-bbjlp
-+  //     #doubling-dbl-2007-bl
-+  // and others
-+  // Generally 3M + 4S or 2M + 4S
-+
-+  // B = (X1 + Y1)^2
-+  var b = this.x.redAdd(this.y).redSqr();
-+  // C = X1^2
-+  var c = this.x.redSqr();
-+  // D = Y1^2
-+  var d = this.y.redSqr();
-+
-+  var nx;
-+  var ny;
-+  var nz;
-+  if (this.curve.twisted) {
-+    // E = a * C
-+    var e = this.curve._mulA(c);
-+    // F = E + D
-+    var f = e.redAdd(d);
-+    if (this.zOne) {
-+      // X3 = (B - C - D) * (F - 2)
-+      nx = b.redSub(c).redSub(d).redMul(f.redSub(this.curve.two));
-+      // Y3 = F * (E - D)
-+      ny = f.redMul(e.redSub(d));
-+      // Z3 = F^2 - 2 * F
-+      nz = f.redSqr().redSub(f).redSub(f);
-+    } else {
-+      // H = Z1^2
-+      var h = this.z.redSqr();
-+      // J = F - 2 * H
-+      var j = f.redSub(h).redISub(h);
-+      // X3 = (B-C-D)*J
-+      nx = b.redSub(c).redISub(d).redMul(j);
-+      // Y3 = F * (E - D)
-+      ny = f.redMul(e.redSub(d));
-+      // Z3 = F * J
-+      nz = f.redMul(j);
-+    }
-+  } else {
-+    // E = C + D
-+    var e = c.redAdd(d);
-+    // H = (c * Z1)^2
-+    var h = this.curve._mulC(this.c.redMul(this.z)).redSqr();
-+    // J = E - 2 * H
-+    var j = e.redSub(h).redSub(h);
-+    // X3 = c * (B - E) * J
-+    nx = this.curve._mulC(b.redISub(e)).redMul(j);
-+    // Y3 = c * E * (C - D)
-+    ny = this.curve._mulC(e).redMul(c.redISub(d));
-+    // Z3 = E * J
-+    nz = e.redMul(j);
-+  }
-+  return this.curve.point(nx, ny, nz);
-+};
-+
-+Point.prototype.dbl = function dbl() {
-+  if (this.isInfinity())
-+    return this;
-+
-+  // Double in extended coordinates
-+  if (this.curve.extended)
-+    return this._extDbl();
-+  else
-+    return this._projDbl();
-+};
-+
-+Point.prototype._extAdd = function _extAdd(p) {
-+  // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
-+  //     #addition-add-2008-hwcd-3
-+  // 8M
-+
-+  // A = (Y1 - X1) * (Y2 - X2)
-+  var a = this.y.redSub(this.x).redMul(p.y.redSub(p.x));
-+  // B = (Y1 + X1) * (Y2 + X2)
-+  var b = this.y.redAdd(this.x).redMul(p.y.redAdd(p.x));
-+  // C = T1 * k * T2
-+  var c = this.t.redMul(this.curve.dd).redMul(p.t);
-+  // D = Z1 * 2 * Z2
-+  var d = this.z.redMul(p.z.redAdd(p.z));
-+  // E = B - A
-+  var e = b.redSub(a);
-+  // F = D - C
-+  var f = d.redSub(c);
-+  // G = D + C
-+  var g = d.redAdd(c);
-+  // H = B + A
-+  var h = b.redAdd(a);
-+  // X3 = E * F
-+  var nx = e.redMul(f);
-+  // Y3 = G * H
-+  var ny = g.redMul(h);
-+  // T3 = E * H
-+  var nt = e.redMul(h);
-+  // Z3 = F * G
-+  var nz = f.redMul(g);
-+  return this.curve.point(nx, ny, nz, nt);
-+};
-+
-+Point.prototype._projAdd = function _projAdd(p) {
-+  // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
-+  //     #addition-add-2008-bbjlp
-+  //     #addition-add-2007-bl
-+  // 10M + 1S
-+
-+  // A = Z1 * Z2
-+  var a = this.z.redMul(p.z);
-+  // B = A^2
-+  var b = a.redSqr();
-+  // C = X1 * X2
-+  var c = this.x.redMul(p.x);
-+  // D = Y1 * Y2
-+  var d = this.y.redMul(p.y);
-+  // E = d * C * D
-+  var e = this.curve.d.redMul(c).redMul(d);
-+  // F = B - E
-+  var f = b.redSub(e);
-+  // G = B + E
-+  var g = b.redAdd(e);
-+  // X3 = A * F * ((X1 + Y1) * (X2 + Y2) - C - D)
-+  var tmp = this.x.redAdd(this.y).redMul(p.x.redAdd(p.y)).redISub(c).redISub(d);
-+  var nx = a.redMul(f).redMul(tmp);
-+  var ny;
-+  var nz;
-+  if (this.curve.twisted) {
-+    // Y3 = A * G * (D - a * C)
-+    ny = a.redMul(g).redMul(d.redSub(this.curve._mulA(c)));
-+    // Z3 = F * G
-+    nz = f.redMul(g);
-+  } else {
-+    // Y3 = A * G * (D - C)
-+    ny = a.redMul(g).redMul(d.redSub(c));
-+    // Z3 = c * F * G
-+    nz = this.curve._mulC(f).redMul(g);
-+  }
-+  return this.curve.point(nx, ny, nz);
-+};
-+
-+Point.prototype.add = function add(p) {
-+  if (this.isInfinity())
-+    return p;
-+  if (p.isInfinity())
-+    return this;
-+
-+  if (this.curve.extended)
-+    return this._extAdd(p);
-+  else
-+    return this._projAdd(p);
-+};
-+
-+Point.prototype.mul = function mul(k) {
-+  if (this._hasDoubles(k))
-+    return this.curve._fixedNafMul(this, k);
-+  else
-+    return this.curve._wnafMul(this, k);
-+};
-+
-+Point.prototype.mulAdd = function mulAdd(k1, p, k2) {
-+  return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, false);
-+};
-+
-+Point.prototype.jmulAdd = function jmulAdd(k1, p, k2) {
-+  return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, true);
-+};
-+
-+Point.prototype.normalize = function normalize() {
-+  if (this.zOne)
-+    return this;
-+
-+  // Normalize coordinates
-+  var zi = this.z.redInvm();
-+  this.x = this.x.redMul(zi);
-+  this.y = this.y.redMul(zi);
-+  if (this.t)
-+    this.t = this.t.redMul(zi);
-+  this.z = this.curve.one;
-+  this.zOne = true;
-+  return this;
-+};
-+
-+Point.prototype.neg = function neg() {
-+  return this.curve.point(this.x.redNeg(),
-+                          this.y,
-+                          this.z,
-+                          this.t && this.t.redNeg());
-+};
-+
-+Point.prototype.getX = function getX() {
-+  this.normalize();
-+  return this.x.fromRed();
-+};
-+
-+Point.prototype.getY = function getY() {
-+  this.normalize();
-+  return this.y.fromRed();
-+};
-+
-+Point.prototype.eq = function eq(other) {
-+  return this === other ||
-+         this.getX().cmp(other.getX()) === 0 &&
-+         this.getY().cmp(other.getY()) === 0;
-+};
-+
-+Point.prototype.eqXToP = function eqXToP(x) {
-+  var rx = x.toRed(this.curve.red).redMul(this.z);
-+  if (this.x.cmp(rx) === 0)
-+    return true;
-+
-+  var xc = x.clone();
-+  var t = this.curve.redN.redMul(this.z);
-+  for (;;) {
-+    xc.iadd(this.curve.n);
-+    if (xc.cmp(this.curve.p) >= 0)
-+      return false;
-+
-+    rx.redIAdd(t);
-+    if (this.x.cmp(rx) === 0)
-+      return true;
-+  }
-+  return false;
-+};
-+
-+// Compatibility with BaseCurve
-+Point.prototype.toP = Point.prototype.normalize;
-+Point.prototype.mixedAdd = Point.prototype.add;
-+
-+},{"../../elliptic":2,"../curve":5,"bn.js":1,"inherits":25}],5:[function(require,module,exports){
-+'use strict';
-+
-+var curve = exports;
-+
-+curve.base = require('./base');
-+curve.short = require('./short');
-+curve.mont = require('./mont');
-+curve.edwards = require('./edwards');
-+
-+},{"./base":3,"./edwards":4,"./mont":6,"./short":7}],6:[function(require,module,exports){
-+'use strict';
-+
-+var curve = require('../curve');
-+var BN = require('bn.js');
-+var inherits = require('inherits');
-+var Base = curve.base;
-+
-+var elliptic = require('../../elliptic');
-+var utils = elliptic.utils;
-+
-+function MontCurve(conf) {
-+  Base.call(this, 'mont', conf);
-+
-+  this.a = new BN(conf.a, 16).toRed(this.red);
-+  this.b = new BN(conf.b, 16).toRed(this.red);
-+  this.i4 = new BN(4).toRed(this.red).redInvm();
-+  this.two = new BN(2).toRed(this.red);
-+  this.a24 = this.i4.redMul(this.a.redAdd(this.two));
-+}
-+inherits(MontCurve, Base);
-+module.exports = MontCurve;
-+
-+MontCurve.prototype.validate = function validate(point) {
-+  var x = point.normalize().x;
-+  var x2 = x.redSqr();
-+  var rhs = x2.redMul(x).redAdd(x2.redMul(this.a)).redAdd(x);
-+  var y = rhs.redSqrt();
-+
-+  return y.redSqr().cmp(rhs) === 0;
-+};
-+
-+function Point(curve, x, z) {
-+  Base.BasePoint.call(this, curve, 'projective');
-+  if (x === null && z === null) {
-+    this.x = this.curve.one;
-+    this.z = this.curve.zero;
-+  } else {
-+    this.x = new BN(x, 16);
-+    this.z = new BN(z, 16);
-+    if (!this.x.red)
-+      this.x = this.x.toRed(this.curve.red);
-+    if (!this.z.red)
-+      this.z = this.z.toRed(this.curve.red);
-+  }
-+}
-+inherits(Point, Base.BasePoint);
-+
-+MontCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
-+  return this.point(utils.toArray(bytes, enc), 1);
-+};
-+
-+MontCurve.prototype.point = function point(x, z) {
-+  return new Point(this, x, z);
-+};
-+
-+MontCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
-+  return Point.fromJSON(this, obj);
-+};
-+
-+Point.prototype.precompute = function precompute() {
-+  // No-op
-+};
-+
-+Point.prototype._encode = function _encode() {
-+  return this.getX().toArray('be', this.curve.p.byteLength());
-+};
-+
-+Point.fromJSON = function fromJSON(curve, obj) {
-+  return new Point(curve, obj[0], obj[1] || curve.one);
-+};
-+
-+Point.prototype.inspect = function inspect() {
-+  if (this.isInfinity())
-+    return '<EC Point Infinity>';
-+  return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
-+      ' z: ' + this.z.fromRed().toString(16, 2) + '>';
-+};
-+
-+Point.prototype.isInfinity = function isInfinity() {
-+  // XXX This code assumes that zero is always zero in red
-+  return this.z.cmpn(0) === 0;
-+};
-+
-+Point.prototype.dbl = function dbl() {
-+  // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-dbl-1987-m-3
-+  // 2M + 2S + 4A
-+
-+  // A = X1 + Z1
-+  var a = this.x.redAdd(this.z);
-+  // AA = A^2
-+  var aa = a.redSqr();
-+  // B = X1 - Z1
-+  var b = this.x.redSub(this.z);
-+  // BB = B^2
-+  var bb = b.redSqr();
-+  // C = AA - BB
-+  var c = aa.redSub(bb);
-+  // X3 = AA * BB
-+  var nx = aa.redMul(bb);
-+  // Z3 = C * (BB + A24 * C)
-+  var nz = c.redMul(bb.redAdd(this.curve.a24.redMul(c)));
-+  return this.curve.point(nx, nz);
-+};
-+
-+Point.prototype.add = function add() {
-+  throw new Error('Not supported on Montgomery curve');
-+};
-+
-+Point.prototype.diffAdd = function diffAdd(p, diff) {
-+  // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#diffadd-dadd-1987-m-3
-+  // 4M + 2S + 6A
-+
-+  // A = X2 + Z2
-+  var a = this.x.redAdd(this.z);
-+  // B = X2 - Z2
-+  var b = this.x.redSub(this.z);
-+  // C = X3 + Z3
-+  var c = p.x.redAdd(p.z);
-+  // D = X3 - Z3
-+  var d = p.x.redSub(p.z);
-+  // DA = D * A
-+  var da = d.redMul(a);
-+  // CB = C * B
-+  var cb = c.redMul(b);
-+  // X5 = Z1 * (DA + CB)^2
-+  var nx = diff.z.redMul(da.redAdd(cb).redSqr());
-+  // Z5 = X1 * (DA - CB)^2
-+  var nz = diff.x.redMul(da.redISub(cb).redSqr());
-+  return this.curve.point(nx, nz);
-+};
-+
-+Point.prototype.mul = function mul(k) {
-+  var t = k.clone();
-+  var a = this; // (N / 2) * Q + Q
-+  var b = this.curve.point(null, null); // (N / 2) * Q
-+  var c = this; // Q
-+
-+  for (var bits = []; t.cmpn(0) !== 0; t.iushrn(1))
-+    bits.push(t.andln(1));
-+
-+  for (var i = bits.length - 1; i >= 0; i--) {
-+    if (bits[i] === 0) {
-+      // N * Q + Q = ((N / 2) * Q + Q)) + (N / 2) * Q
-+      a = a.diffAdd(b, c);
-+      // N * Q = 2 * ((N / 2) * Q + Q))
-+      b = b.dbl();
-+    } else {
-+      // N * Q = ((N / 2) * Q + Q) + ((N / 2) * Q)
-+      b = a.diffAdd(b, c);
-+      // N * Q + Q = 2 * ((N / 2) * Q + Q)
-+      a = a.dbl();
-+    }
-+  }
-+  return b;
-+};
-+
-+Point.prototype.mulAdd = function mulAdd() {
-+  throw new Error('Not supported on Montgomery curve');
-+};
-+
-+Point.prototype.jumlAdd = function jumlAdd() {
-+  throw new Error('Not supported on Montgomery curve');
-+};
-+
-+Point.prototype.eq = function eq(other) {
-+  return this.getX().cmp(other.getX()) === 0;
-+};
-+
-+Point.prototype.normalize = function normalize() {
-+  this.x = this.x.redMul(this.z.redInvm());
-+  this.z = this.curve.one;
-+  return this;
-+};
-+
-+Point.prototype.getX = function getX() {
-+  // Normalize coordinates
-+  this.normalize();
-+
-+  return this.x.fromRed();
-+};
-+
-+},{"../../elliptic":2,"../curve":5,"bn.js":1,"inherits":25}],7:[function(require,module,exports){
-+'use strict';
-+
-+var curve = require('../curve');
-+var elliptic = require('../../elliptic');
-+var BN = require('bn.js');
-+var inherits = require('inherits');
-+var Base = curve.base;
-+
-+var assert = elliptic.utils.assert;
-+
-+function ShortCurve(conf) {
-+  Base.call(this, 'short', conf);
-+
-+  this.a = new BN(conf.a, 16).toRed(this.red);
-+  this.b = new BN(conf.b, 16).toRed(this.red);
-+  this.tinv = this.two.redInvm();
-+
-+  this.zeroA = this.a.fromRed().cmpn(0) === 0;
-+  this.threeA = this.a.fromRed().sub(this.p).cmpn(-3) === 0;
-+
-+  // If the curve is endomorphic, precalculate beta and lambda
-+  this.endo = this._getEndomorphism(conf);
-+  this._endoWnafT1 = new Array(4);
-+  this._endoWnafT2 = new Array(4);
-+}
-+inherits(ShortCurve, Base);
-+module.exports = ShortCurve;
-+
-+ShortCurve.prototype._getEndomorphism = function _getEndomorphism(conf) {
-+  // No efficient endomorphism
-+  if (!this.zeroA || !this.g || !this.n || this.p.modn(3) !== 1)
-+    return;
-+
-+  // Compute beta and lambda, that lambda * P = (beta * Px; Py)
-+  var beta;
-+  var lambda;
-+  if (conf.beta) {
-+    beta = new BN(conf.beta, 16).toRed(this.red);
-+  } else {
-+    var betas = this._getEndoRoots(this.p);
-+    // Choose the smallest beta
-+    beta = betas[0].cmp(betas[1]) < 0 ? betas[0] : betas[1];
-+    beta = beta.toRed(this.red);
-+  }
-+  if (conf.lambda) {
-+    lambda = new BN(conf.lambda, 16);
-+  } else {
-+    // Choose the lambda that is matching selected beta
-+    var lambdas = this._getEndoRoots(this.n);
-+    if (this.g.mul(lambdas[0]).x.cmp(this.g.x.redMul(beta)) === 0) {
-+      lambda = lambdas[0];
-+    } else {
-+      lambda = lambdas[1];
-+      assert(this.g.mul(lambda).x.cmp(this.g.x.redMul(beta)) === 0);
-+    }
-+  }
-+
-+  // Get basis vectors, used for balanced length-two representation
-+  var basis;
-+  if (conf.basis) {
-+    basis = conf.basis.map(function(vec) {
-+      return {
-+        a: new BN(vec.a, 16),
-+        b: new BN(vec.b, 16)
-+      };
-+    });
-+  } else {
-+    basis = this._getEndoBasis(lambda);
-+  }
-+
-+  return {
-+    beta: beta,
-+    lambda: lambda,
-+    basis: basis
-+  };
-+};
-+
-+ShortCurve.prototype._getEndoRoots = function _getEndoRoots(num) {
-+  // Find roots of for x^2 + x + 1 in F
-+  // Root = (-1 +- Sqrt(-3)) / 2
-+  //
-+  var red = num === this.p ? this.red : BN.mont(num);
-+  var tinv = new BN(2).toRed(red).redInvm();
-+  var ntinv = tinv.redNeg();
-+
-+  var s = new BN(3).toRed(red).redNeg().redSqrt().redMul(tinv);
-+
-+  var l1 = ntinv.redAdd(s).fromRed();
-+  var l2 = ntinv.redSub(s).fromRed();
-+  return [ l1, l2 ];
-+};
-+
-+ShortCurve.prototype._getEndoBasis = function _getEndoBasis(lambda) {
-+  // aprxSqrt >= sqrt(this.n)
-+  var aprxSqrt = this.n.ushrn(Math.floor(this.n.bitLength() / 2));
-+
-+  // 3.74
-+  // Run EGCD, until r(L + 1) < aprxSqrt
-+  var u = lambda;
-+  var v = this.n.clone();
-+  var x1 = new BN(1);
-+  var y1 = new BN(0);
-+  var x2 = new BN(0);
-+  var y2 = new BN(1);
-+
-+  // NOTE: all vectors are roots of: a + b * lambda = 0 (mod n)
-+  var a0;
-+  var b0;
-+  // First vector
-+  var a1;
-+  var b1;
-+  // Second vector
-+  var a2;
-+  var b2;
-+
-+  var prevR;
-+  var i = 0;
-+  var r;
-+  var x;
-+  while (u.cmpn(0) !== 0) {
-+    var q = v.div(u);
-+    r = v.sub(q.mul(u));
-+    x = x2.sub(q.mul(x1));
-+    var y = y2.sub(q.mul(y1));
-+
-+    if (!a1 && r.cmp(aprxSqrt) < 0) {
-+      a0 = prevR.neg();
-+      b0 = x1;
-+      a1 = r.neg();
-+      b1 = x;
-+    } else if (a1 && ++i === 2) {
-+      break;
-+    }
-+    prevR = r;
-+
-+    v = u;
-+    u = r;
-+    x2 = x1;
-+    x1 = x;
-+    y2 = y1;
-+    y1 = y;
-+  }
-+  a2 = r.neg();
-+  b2 = x;
-+
-+  var len1 = a1.sqr().add(b1.sqr());
-+  var len2 = a2.sqr().add(b2.sqr());
-+  if (len2.cmp(len1) >= 0) {
-+    a2 = a0;
-+    b2 = b0;
-+  }
-+
-+  // Normalize signs
-+  if (a1.negative) {
-+    a1 = a1.neg();
-+    b1 = b1.neg();
-+  }
-+  if (a2.negative) {
-+    a2 = a2.neg();
-+    b2 = b2.neg();
-+  }
-+
-+  return [
-+    { a: a1, b: b1 },
-+    { a: a2, b: b2 }
-+  ];
-+};
-+
-+ShortCurve.prototype._endoSplit = function _endoSplit(k) {
-+  var basis = this.endo.basis;
-+  var v1 = basis[0];
-+  var v2 = basis[1];
-+
-+  var c1 = v2.b.mul(k).divRound(this.n);
-+  var c2 = v1.b.neg().mul(k).divRound(this.n);
-+
-+  var p1 = c1.mul(v1.a);
-+  var p2 = c2.mul(v2.a);
-+  var q1 = c1.mul(v1.b);
-+  var q2 = c2.mul(v2.b);
-+
-+  // Calculate answer
-+  var k1 = k.sub(p1).sub(p2);
-+  var k2 = q1.add(q2).neg();
-+  return { k1: k1, k2: k2 };
-+};
-+
-+ShortCurve.prototype.pointFromX = function pointFromX(x, odd) {
-+  x = new BN(x, 16);
-+  if (!x.red)
-+    x = x.toRed(this.red);
-+
-+  var y2 = x.redSqr().redMul(x).redIAdd(x.redMul(this.a)).redIAdd(this.b);
-+  var y = y2.redSqrt();
-+  if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
-+    throw new Error('invalid point');
-+
-+  // XXX Is there any way to tell if the number is odd without converting it
-+  // to non-red form?
-+  var isOdd = y.fromRed().isOdd();
-+  if (odd && !isOdd || !odd && isOdd)
-+    y = y.redNeg();
-+
-+  return this.point(x, y);
-+};
-+
-+ShortCurve.prototype.validate = function validate(point) {
-+  if (point.inf)
-+    return true;
-+
-+  var x = point.x;
-+  var y = point.y;
-+
-+  var ax = this.a.redMul(x);
-+  var rhs = x.redSqr().redMul(x).redIAdd(ax).redIAdd(this.b);
-+  return y.redSqr().redISub(rhs).cmpn(0) === 0;
-+};
-+
-+ShortCurve.prototype._endoWnafMulAdd =
-+    function _endoWnafMulAdd(points, coeffs, jacobianResult) {
-+  var npoints = this._endoWnafT1;
-+  var ncoeffs = this._endoWnafT2;
-+  for (var i = 0; i < points.length; i++) {
-+    var split = this._endoSplit(coeffs[i]);
-+    var p = points[i];
-+    var beta = p._getBeta();
-+
-+    if (split.k1.negative) {
-+      split.k1.ineg();
-+      p = p.neg(true);
-+    }
-+    if (split.k2.negative) {
-+      split.k2.ineg();
-+      beta = beta.neg(true);
-+    }
-+
-+    npoints[i * 2] = p;
-+    npoints[i * 2 + 1] = beta;
-+    ncoeffs[i * 2] = split.k1;
-+    ncoeffs[i * 2 + 1] = split.k2;
-+  }
-+  var res = this._wnafMulAdd(1, npoints, ncoeffs, i * 2, jacobianResult);
-+
-+  // Clean-up references to points and coefficients
-+  for (var j = 0; j < i * 2; j++) {
-+    npoints[j] = null;
-+    ncoeffs[j] = null;
-+  }
-+  return res;
-+};
-+
-+function Point(curve, x, y, isRed) {
-+  Base.BasePoint.call(this, curve, 'affine');
-+  if (x === null && y === null) {
-+    this.x = null;
-+    this.y = null;
-+    this.inf = true;
-+  } else {
-+    this.x = new BN(x, 16);
-+    this.y = new BN(y, 16);
-+    // Force redgomery representation when loading from JSON
-+    if (isRed) {
-+      this.x.forceRed(this.curve.red);
-+      this.y.forceRed(this.curve.red);
-+    }
-+    if (!this.x.red)
-+      this.x = this.x.toRed(this.curve.red);
-+    if (!this.y.red)
-+      this.y = this.y.toRed(this.curve.red);
-+    this.inf = false;
-+  }
-+}
-+inherits(Point, Base.BasePoint);
-+
-+ShortCurve.prototype.point = function point(x, y, isRed) {
-+  return new Point(this, x, y, isRed);
-+};
-+
-+ShortCurve.prototype.pointFromJSON = function pointFromJSON(obj, red) {
-+  return Point.fromJSON(this, obj, red);
-+};
-+
-+Point.prototype._getBeta = function _getBeta() {
-+  if (!this.curve.endo)
-+    return;
-+
-+  var pre = this.precomputed;
-+  if (pre && pre.beta)
-+    return pre.beta;
-+
-+  var beta = this.curve.point(this.x.redMul(this.curve.endo.beta), this.y);
-+  if (pre) {
-+    var curve = this.curve;
-+    var endoMul = function(p) {
-+      return curve.point(p.x.redMul(curve.endo.beta), p.y);
-+    };
-+    pre.beta = beta;
-+    beta.precomputed = {
-+      beta: null,
-+      naf: pre.naf && {
-+        wnd: pre.naf.wnd,
-+        points: pre.naf.points.map(endoMul)
-+      },
-+      doubles: pre.doubles && {
-+        step: pre.doubles.step,
-+        points: pre.doubles.points.map(endoMul)
-+      }
-+    };
-+  }
-+  return beta;
-+};
-+
-+Point.prototype.toJSON = function toJSON() {
-+  if (!this.precomputed)
-+    return [ this.x, this.y ];
-+
-+  return [ this.x, this.y, this.precomputed && {
-+    doubles: this.precomputed.doubles && {
-+      step: this.precomputed.doubles.step,
-+      points: this.precomputed.doubles.points.slice(1)
-+    },
-+    naf: this.precomputed.naf && {
-+      wnd: this.precomputed.naf.wnd,
-+      points: this.precomputed.naf.points.slice(1)
-+    }
-+  } ];
-+};
-+
-+Point.fromJSON = function fromJSON(curve, obj, red) {
-+  if (typeof obj === 'string')
-+    obj = JSON.parse(obj);
-+  var res = curve.point(obj[0], obj[1], red);
-+  if (!obj[2])
-+    return res;
-+
-+  function obj2point(obj) {
-+    return curve.point(obj[0], obj[1], red);
-+  }
-+
-+  var pre = obj[2];
-+  res.precomputed = {
-+    beta: null,
-+    doubles: pre.doubles && {
-+      step: pre.doubles.step,
-+      points: [ res ].concat(pre.doubles.points.map(obj2point))
-+    },
-+    naf: pre.naf && {
-+      wnd: pre.naf.wnd,
-+      points: [ res ].concat(pre.naf.points.map(obj2point))
-+    }
-+  };
-+  return res;
-+};
-+
-+Point.prototype.inspect = function inspect() {
-+  if (this.isInfinity())
-+    return '<EC Point Infinity>';
-+  return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
-+      ' y: ' + this.y.fromRed().toString(16, 2) + '>';
-+};
-+
-+Point.prototype.isInfinity = function isInfinity() {
-+  return this.inf;
-+};
-+
-+Point.prototype.add = function add(p) {
-+  // O + P = P
-+  if (this.inf)
-+    return p;
-+
-+  // P + O = P
-+  if (p.inf)
-+    return this;
-+
-+  // P + P = 2P
-+  if (this.eq(p))
-+    return this.dbl();
-+
-+  // P + (-P) = O
-+  if (this.neg().eq(p))
-+    return this.curve.point(null, null);
-+
-+  // P + Q = O
-+  if (this.x.cmp(p.x) === 0)
-+    return this.curve.point(null, null);
-+
-+  var c = this.y.redSub(p.y);
-+  if (c.cmpn(0) !== 0)
-+    c = c.redMul(this.x.redSub(p.x).redInvm());
-+  var nx = c.redSqr().redISub(this.x).redISub(p.x);
-+  var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
-+  return this.curve.point(nx, ny);
-+};
-+
-+Point.prototype.dbl = function dbl() {
-+  if (this.inf)
-+    return this;
-+
-+  // 2P = O
-+  var ys1 = this.y.redAdd(this.y);
-+  if (ys1.cmpn(0) === 0)
-+    return this.curve.point(null, null);
-+
-+  var a = this.curve.a;
-+
-+  var x2 = this.x.redSqr();
-+  var dyinv = ys1.redInvm();
-+  var c = x2.redAdd(x2).redIAdd(x2).redIAdd(a).redMul(dyinv);
-+
-+  var nx = c.redSqr().redISub(this.x.redAdd(this.x));
-+  var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
-+  return this.curve.point(nx, ny);
-+};
-+
-+Point.prototype.getX = function getX() {
-+  return this.x.fromRed();
-+};
-+
-+Point.prototype.getY = function getY() {
-+  return this.y.fromRed();
-+};
-+
-+Point.prototype.mul = function mul(k) {
-+  k = new BN(k, 16);
-+
-+  if (this._hasDoubles(k))
-+    return this.curve._fixedNafMul(this, k);
-+  else if (this.curve.endo)
-+    return this.curve._endoWnafMulAdd([ this ], [ k ]);
-+  else
-+    return this.curve._wnafMul(this, k);
-+};
-+
-+Point.prototype.mulAdd = function mulAdd(k1, p2, k2) {
-+  var points = [ this, p2 ];
-+  var coeffs = [ k1, k2 ];
-+  if (this.curve.endo)
-+    return this.curve._endoWnafMulAdd(points, coeffs);
-+  else
-+    return this.curve._wnafMulAdd(1, points, coeffs, 2);
-+};
-+
-+Point.prototype.jmulAdd = function jmulAdd(k1, p2, k2) {
-+  var points = [ this, p2 ];
-+  var coeffs = [ k1, k2 ];
-+  if (this.curve.endo)
-+    return this.curve._endoWnafMulAdd(points, coeffs, true);
-+  else
-+    return this.curve._wnafMulAdd(1, points, coeffs, 2, true);
-+};
-+
-+Point.prototype.eq = function eq(p) {
-+  return this === p ||
-+         this.inf === p.inf &&
-+             (this.inf || this.x.cmp(p.x) === 0 && this.y.cmp(p.y) === 0);
-+};
-+
-+Point.prototype.neg = function neg(_precompute) {
-+  if (this.inf)
-+    return this;
-+
-+  var res = this.curve.point(this.x, this.y.redNeg());
-+  if (_precompute && this.precomputed) {
-+    var pre = this.precomputed;
-+    var negate = function(p) {
-+      return p.neg();
-+    };
-+    res.precomputed = {
-+      naf: pre.naf && {
-+        wnd: pre.naf.wnd,
-+        points: pre.naf.points.map(negate)
-+      },
-+      doubles: pre.doubles && {
-+        step: pre.doubles.step,
-+        points: pre.doubles.points.map(negate)
-+      }
-+    };
-+  }
-+  return res;
-+};
-+
-+Point.prototype.toJ = function toJ() {
-+  if (this.inf)
-+    return this.curve.jpoint(null, null, null);
-+
-+  var res = this.curve.jpoint(this.x, this.y, this.curve.one);
-+  return res;
-+};
-+
-+function JPoint(curve, x, y, z) {
-+  Base.BasePoint.call(this, curve, 'jacobian');
-+  if (x === null && y === null && z === null) {
-+    this.x = this.curve.one;
-+    this.y = this.curve.one;
-+    this.z = new BN(0);
-+  } else {
-+    this.x = new BN(x, 16);
-+    this.y = new BN(y, 16);
-+    this.z = new BN(z, 16);
-+  }
-+  if (!this.x.red)
-+    this.x = this.x.toRed(this.curve.red);
-+  if (!this.y.red)
-+    this.y = this.y.toRed(this.curve.red);
-+  if (!this.z.red)
-+    this.z = this.z.toRed(this.curve.red);
-+
-+  this.zOne = this.z === this.curve.one;
-+}
-+inherits(JPoint, Base.BasePoint);
-+
-+ShortCurve.prototype.jpoint = function jpoint(x, y, z) {
-+  return new JPoint(this, x, y, z);
-+};
-+
-+JPoint.prototype.toP = function toP() {
-+  if (this.isInfinity())
-+    return this.curve.point(null, null);
-+
-+  var zinv = this.z.redInvm();
-+  var zinv2 = zinv.redSqr();
-+  var ax = this.x.redMul(zinv2);
-+  var ay = this.y.redMul(zinv2).redMul(zinv);
-+
-+  return this.curve.point(ax, ay);
-+};
-+
-+JPoint.prototype.neg = function neg() {
-+  return this.curve.jpoint(this.x, this.y.redNeg(), this.z);
-+};
-+
-+JPoint.prototype.add = function add(p) {
-+  // O + P = P
-+  if (this.isInfinity())
-+    return p;
-+
-+  // P + O = P
-+  if (p.isInfinity())
-+    return this;
-+
-+  // 12M + 4S + 7A
-+  var pz2 = p.z.redSqr();
-+  var z2 = this.z.redSqr();
-+  var u1 = this.x.redMul(pz2);
-+  var u2 = p.x.redMul(z2);
-+  var s1 = this.y.redMul(pz2.redMul(p.z));
-+  var s2 = p.y.redMul(z2.redMul(this.z));
-+
-+  var h = u1.redSub(u2);
-+  var r = s1.redSub(s2);
-+  if (h.cmpn(0) === 0) {
-+    if (r.cmpn(0) !== 0)
-+      return this.curve.jpoint(null, null, null);
-+    else
-+      return this.dbl();
-+  }
-+
-+  var h2 = h.redSqr();
-+  var h3 = h2.redMul(h);
-+  var v = u1.redMul(h2);
-+
-+  var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);
-+  var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));
-+  var nz = this.z.redMul(p.z).redMul(h);
-+
-+  return this.curve.jpoint(nx, ny, nz);
-+};
-+
-+JPoint.prototype.mixedAdd = function mixedAdd(p) {
-+  // O + P = P
-+  if (this.isInfinity())
-+    return p.toJ();
-+
-+  // P + O = P
-+  if (p.isInfinity())
-+    return this;
-+
-+  // 8M + 3S + 7A
-+  var z2 = this.z.redSqr();
-+  var u1 = this.x;
-+  var u2 = p.x.redMul(z2);
-+  var s1 = this.y;
-+  var s2 = p.y.redMul(z2).redMul(this.z);
-+
-+  var h = u1.redSub(u2);
-+  var r = s1.redSub(s2);
-+  if (h.cmpn(0) === 0) {
-+    if (r.cmpn(0) !== 0)
-+      return this.curve.jpoint(null, null, null);
-+    else
-+      return this.dbl();
-+  }
-+
-+  var h2 = h.redSqr();
-+  var h3 = h2.redMul(h);
-+  var v = u1.redMul(h2);
-+
-+  var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);
-+  var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));
-+  var nz = this.z.redMul(h);
-+
-+  return this.curve.jpoint(nx, ny, nz);
-+};
-+
-+JPoint.prototype.dblp = function dblp(pow) {
-+  if (pow === 0)
-+    return this;
-+  if (this.isInfinity())
-+    return this;
-+  if (!pow)
-+    return this.dbl();
-+
-+  if (this.curve.zeroA || this.curve.threeA) {
-+    var r = this;
-+    for (var i = 0; i < pow; i++)
-+      r = r.dbl();
-+    return r;
-+  }
-+
-+  // 1M + 2S + 1A + N * (4S + 5M + 8A)
-+  // N = 1 => 6M + 6S + 9A
-+  var a = this.curve.a;
-+  var tinv = this.curve.tinv;
-+
-+  var jx = this.x;
-+  var jy = this.y;
-+  var jz = this.z;
-+  var jz4 = jz.redSqr().redSqr();
-+
-+  // Reuse results
-+  var jyd = jy.redAdd(jy);
-+  for (var i = 0; i < pow; i++) {
-+    var jx2 = jx.redSqr();
-+    var jyd2 = jyd.redSqr();
-+    var jyd4 = jyd2.redSqr();
-+    var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));
-+
-+    var t1 = jx.redMul(jyd2);
-+    var nx = c.redSqr().redISub(t1.redAdd(t1));
-+    var t2 = t1.redISub(nx);
-+    var dny = c.redMul(t2);
-+    dny = dny.redIAdd(dny).redISub(jyd4);
-+    var nz = jyd.redMul(jz);
-+    if (i + 1 < pow)
-+      jz4 = jz4.redMul(jyd4);
-+
-+    jx = nx;
-+    jz = nz;
-+    jyd = dny;
-+  }
-+
-+  return this.curve.jpoint(jx, jyd.redMul(tinv), jz);
-+};
-+
-+JPoint.prototype.dbl = function dbl() {
-+  if (this.isInfinity())
-+    return this;
-+
-+  if (this.curve.zeroA)
-+    return this._zeroDbl();
-+  else if (this.curve.threeA)
-+    return this._threeDbl();
-+  else
-+    return this._dbl();
-+};
-+
-+JPoint.prototype._zeroDbl = function _zeroDbl() {
-+  var nx;
-+  var ny;
-+  var nz;
-+  // Z = 1
-+  if (this.zOne) {
-+    // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
-+    //     #doubling-mdbl-2007-bl
-+    // 1M + 5S + 14A
-+
-+    // XX = X1^2
-+    var xx = this.x.redSqr();
-+    // YY = Y1^2
-+    var yy = this.y.redSqr();
-+    // YYYY = YY^2
-+    var yyyy = yy.redSqr();
-+    // S = 2 * ((X1 + YY)^2 - XX - YYYY)
-+    var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
-+    s = s.redIAdd(s);
-+    // M = 3 * XX + a; a = 0
-+    var m = xx.redAdd(xx).redIAdd(xx);
-+    // T = M ^ 2 - 2*S
-+    var t = m.redSqr().redISub(s).redISub(s);
-+
-+    // 8 * YYYY
-+    var yyyy8 = yyyy.redIAdd(yyyy);
-+    yyyy8 = yyyy8.redIAdd(yyyy8);
-+    yyyy8 = yyyy8.redIAdd(yyyy8);
-+
-+    // X3 = T
-+    nx = t;
-+    // Y3 = M * (S - T) - 8 * YYYY
-+    ny = m.redMul(s.redISub(t)).redISub(yyyy8);
-+    // Z3 = 2*Y1
-+    nz = this.y.redAdd(this.y);
-+  } else {
-+    // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
-+    //     #doubling-dbl-2009-l
-+    // 2M + 5S + 13A
-+
-+    // A = X1^2
-+    var a = this.x.redSqr();
-+    // B = Y1^2
-+    var b = this.y.redSqr();
-+    // C = B^2
-+    var c = b.redSqr();
-+    // D = 2 * ((X1 + B)^2 - A - C)
-+    var d = this.x.redAdd(b).redSqr().redISub(a).redISub(c);
-+    d = d.redIAdd(d);
-+    // E = 3 * A
-+    var e = a.redAdd(a).redIAdd(a);
-+    // F = E^2
-+    var f = e.redSqr();
-+
-+    // 8 * C
-+    var c8 = c.redIAdd(c);
-+    c8 = c8.redIAdd(c8);
-+    c8 = c8.redIAdd(c8);
-+
-+    // X3 = F - 2 * D
-+    nx = f.redISub(d).redISub(d);
-+    // Y3 = E * (D - X3) - 8 * C
-+    ny = e.redMul(d.redISub(nx)).redISub(c8);
-+    // Z3 = 2 * Y1 * Z1
-+    nz = this.y.redMul(this.z);
-+    nz = nz.redIAdd(nz);
-+  }
-+
-+  return this.curve.jpoint(nx, ny, nz);
-+};
-+
-+JPoint.prototype._threeDbl = function _threeDbl() {
-+  var nx;
-+  var ny;
-+  var nz;
-+  // Z = 1
-+  if (this.zOne) {
-+    // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html
-+    //     #doubling-mdbl-2007-bl
-+    // 1M + 5S + 15A
-+
-+    // XX = X1^2
-+    var xx = this.x.redSqr();
-+    // YY = Y1^2
-+    var yy = this.y.redSqr();
-+    // YYYY = YY^2
-+    var yyyy = yy.redSqr();
-+    // S = 2 * ((X1 + YY)^2 - XX - YYYY)
-+    var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
-+    s = s.redIAdd(s);
-+    // M = 3 * XX + a
-+    var m = xx.redAdd(xx).redIAdd(xx).redIAdd(this.curve.a);
-+    // T = M^2 - 2 * S
-+    var t = m.redSqr().redISub(s).redISub(s);
-+    // X3 = T
-+    nx = t;
-+    // Y3 = M * (S - T) - 8 * YYYY
-+    var yyyy8 = yyyy.redIAdd(yyyy);
-+    yyyy8 = yyyy8.redIAdd(yyyy8);
-+    yyyy8 = yyyy8.redIAdd(yyyy8);
-+    ny = m.redMul(s.redISub(t)).redISub(yyyy8);
-+    // Z3 = 2 * Y1
-+    nz = this.y.redAdd(this.y);
-+  } else {
-+    // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
-+    // 3M + 5S
-+
-+    // delta = Z1^2
-+    var delta = this.z.redSqr();
-+    // gamma = Y1^2
-+    var gamma = this.y.redSqr();
-+    // beta = X1 * gamma
-+    var beta = this.x.redMul(gamma);
-+    // alpha = 3 * (X1 - delta) * (X1 + delta)
-+    var alpha = this.x.redSub(delta).redMul(this.x.redAdd(delta));
-+    alpha = alpha.redAdd(alpha).redIAdd(alpha);
-+    // X3 = alpha^2 - 8 * beta
-+    var beta4 = beta.redIAdd(beta);
-+    beta4 = beta4.redIAdd(beta4);
-+    var beta8 = beta4.redAdd(beta4);
-+    nx = alpha.redSqr().redISub(beta8);
-+    // Z3 = (Y1 + Z1)^2 - gamma - delta
-+    nz = this.y.redAdd(this.z).redSqr().redISub(gamma).redISub(delta);
-+    // Y3 = alpha * (4 * beta - X3) - 8 * gamma^2
-+    var ggamma8 = gamma.redSqr();
-+    ggamma8 = ggamma8.redIAdd(ggamma8);
-+    ggamma8 = ggamma8.redIAdd(ggamma8);
-+    ggamma8 = ggamma8.redIAdd(ggamma8);
-+    ny = alpha.redMul(beta4.redISub(nx)).redISub(ggamma8);
-+  }
-+
-+  return this.curve.jpoint(nx, ny, nz);
-+};
-+
-+JPoint.prototype._dbl = function _dbl() {
-+  var a = this.curve.a;
-+
-+  // 4M + 6S + 10A
-+  var jx = this.x;
-+  var jy = this.y;
-+  var jz = this.z;
-+  var jz4 = jz.redSqr().redSqr();
-+
-+  var jx2 = jx.redSqr();
-+  var jy2 = jy.redSqr();
-+
-+  var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));
-+
-+  var jxd4 = jx.redAdd(jx);
-+  jxd4 = jxd4.redIAdd(jxd4);
-+  var t1 = jxd4.redMul(jy2);
-+  var nx = c.redSqr().redISub(t1.redAdd(t1));
-+  var t2 = t1.redISub(nx);
-+
-+  var jyd8 = jy2.redSqr();
-+  jyd8 = jyd8.redIAdd(jyd8);
-+  jyd8 = jyd8.redIAdd(jyd8);
-+  jyd8 = jyd8.redIAdd(jyd8);
-+  var ny = c.redMul(t2).redISub(jyd8);
-+  var nz = jy.redAdd(jy).redMul(jz);
-+
-+  return this.curve.jpoint(nx, ny, nz);
-+};
-+
-+JPoint.prototype.trpl = function trpl() {
-+  if (!this.curve.zeroA)
-+    return this.dbl().add(this);
-+
-+  // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#tripling-tpl-2007-bl
-+  // 5M + 10S + ...
-+
-+  // XX = X1^2
-+  var xx = this.x.redSqr();
-+  // YY = Y1^2
-+  var yy = this.y.redSqr();
-+  // ZZ = Z1^2
-+  var zz = this.z.redSqr();
-+  // YYYY = YY^2
-+  var yyyy = yy.redSqr();
-+  // M = 3 * XX + a * ZZ2; a = 0
-+  var m = xx.redAdd(xx).redIAdd(xx);
-+  // MM = M^2
-+  var mm = m.redSqr();
-+  // E = 6 * ((X1 + YY)^2 - XX - YYYY) - MM
-+  var e = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
-+  e = e.redIAdd(e);
-+  e = e.redAdd(e).redIAdd(e);
-+  e = e.redISub(mm);
-+  // EE = E^2
-+  var ee = e.redSqr();
-+  // T = 16*YYYY
-+  var t = yyyy.redIAdd(yyyy);
-+  t = t.redIAdd(t);
-+  t = t.redIAdd(t);
-+  t = t.redIAdd(t);
-+  // U = (M + E)^2 - MM - EE - T
-+  var u = m.redIAdd(e).redSqr().redISub(mm).redISub(ee).redISub(t);
-+  // X3 = 4 * (X1 * EE - 4 * YY * U)
-+  var yyu4 = yy.redMul(u);
-+  yyu4 = yyu4.redIAdd(yyu4);
-+  yyu4 = yyu4.redIAdd(yyu4);
-+  var nx = this.x.redMul(ee).redISub(yyu4);
-+  nx = nx.redIAdd(nx);
-+  nx = nx.redIAdd(nx);
-+  // Y3 = 8 * Y1 * (U * (T - U) - E * EE)
-+  var ny = this.y.redMul(u.redMul(t.redISub(u)).redISub(e.redMul(ee)));
-+  ny = ny.redIAdd(ny);
-+  ny = ny.redIAdd(ny);
-+  ny = ny.redIAdd(ny);
-+  // Z3 = (Z1 + E)^2 - ZZ - EE
-+  var nz = this.z.redAdd(e).redSqr().redISub(zz).redISub(ee);
-+
-+  return this.curve.jpoint(nx, ny, nz);
-+};
-+
-+JPoint.prototype.mul = function mul(k, kbase) {
-+  k = new BN(k, kbase);
-+
-+  return this.curve._wnafMul(this, k);
-+};
-+
-+JPoint.prototype.eq = function eq(p) {
-+  if (p.type === 'affine')
-+    return this.eq(p.toJ());
-+
-+  if (this === p)
-+    return true;
-+
-+  // x1 * z2^2 == x2 * z1^2
-+  var z2 = this.z.redSqr();
-+  var pz2 = p.z.redSqr();
-+  if (this.x.redMul(pz2).redISub(p.x.redMul(z2)).cmpn(0) !== 0)
-+    return false;
-+
-+  // y1 * z2^3 == y2 * z1^3
-+  var z3 = z2.redMul(this.z);
-+  var pz3 = pz2.redMul(p.z);
-+  return this.y.redMul(pz3).redISub(p.y.redMul(z3)).cmpn(0) === 0;
-+};
-+
-+JPoint.prototype.eqXToP = function eqXToP(x) {
-+  var zs = this.z.redSqr();
-+  var rx = x.toRed(this.curve.red).redMul(zs);
-+  if (this.x.cmp(rx) === 0)
-+    return true;
-+
-+  var xc = x.clone();
-+  var t = this.curve.redN.redMul(zs);
-+  for (;;) {
-+    xc.iadd(this.curve.n);
-+    if (xc.cmp(this.curve.p) >= 0)
-+      return false;
-+
-+    rx.redIAdd(t);
-+    if (this.x.cmp(rx) === 0)
-+      return true;
-+  }
-+  return false;
-+};
-+
-+JPoint.prototype.inspect = function inspect() {
-+  if (this.isInfinity())
-+    return '<EC JPoint Infinity>';
-+  return '<EC JPoint x: ' + this.x.toString(16, 2) +
-+      ' y: ' + this.y.toString(16, 2) +
-+      ' z: ' + this.z.toString(16, 2) + '>';
-+};
-+
-+JPoint.prototype.isInfinity = function isInfinity() {
-+  // XXX This code assumes that zero is always zero in red
-+  return this.z.cmpn(0) === 0;
-+};
-+
-+},{"../../elliptic":2,"../curve":5,"bn.js":1,"inherits":25}],8:[function(require,module,exports){
-+'use strict';
-+
-+var curves = exports;
-+
-+var hash = require('hash.js');
-+var elliptic = require('../elliptic');
-+
-+var assert = elliptic.utils.assert;
-+
-+function PresetCurve(options) {
-+  if (options.type === 'short')
-+    this.curve = new elliptic.curve.short(options);
-+  else if (options.type === 'edwards')
-+    this.curve = new elliptic.curve.edwards(options);
-+  else
-+    this.curve = new elliptic.curve.mont(options);
-+  this.g = this.curve.g;
-+  this.n = this.curve.n;
-+  this.hash = options.hash;
-+
-+  assert(this.g.validate(), 'Invalid curve');
-+  assert(this.g.mul(this.n).isInfinity(), 'Invalid curve, G*N != O');
-+}
-+curves.PresetCurve = PresetCurve;
-+
-+function defineCurve(name, options) {
-+  Object.defineProperty(curves, name, {
-+    configurable: true,
-+    enumerable: true,
-+    get: function() {
-+      var curve = new PresetCurve(options);
-+      Object.defineProperty(curves, name, {
-+        configurable: true,
-+        enumerable: true,
-+        value: curve
-+      });
-+      return curve;
-+    }
-+  });
-+}
-+
-+defineCurve('p192', {
-+  type: 'short',
-+  prime: 'p192',
-+  p: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff',
-+  a: 'ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc',
-+  b: '64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1',
-+  n: 'ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831',
-+  hash: hash.sha256,
-+  gRed: false,
-+  g: [
-+    '188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012',
-+    '07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811'
-+  ]
-+});
-+
-+defineCurve('p224', {
-+  type: 'short',
-+  prime: 'p224',
-+  p: 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001',
-+  a: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe',
-+  b: 'b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4',
-+  n: 'ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d',
-+  hash: hash.sha256,
-+  gRed: false,
-+  g: [
-+    'b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21',
-+    'bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34'
-+  ]
-+});
-+
-+defineCurve('p256', {
-+  type: 'short',
-+  prime: null,
-+  p: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff',
-+  a: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc',
-+  b: '5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b',
-+  n: 'ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551',
-+  hash: hash.sha256,
-+  gRed: false,
-+  g: [
-+    '6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296',
-+    '4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5'
-+  ]
-+});
-+
-+defineCurve('p384', {
-+  type: 'short',
-+  prime: null,
-+  p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
-+     'fffffffe ffffffff 00000000 00000000 ffffffff',
-+  a: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
-+     'fffffffe ffffffff 00000000 00000000 fffffffc',
-+  b: 'b3312fa7 e23ee7e4 988e056b e3f82d19 181d9c6e fe814112 0314088f ' +
-+     '5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef',
-+  n: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff c7634d81 ' +
-+     'f4372ddf 581a0db2 48b0a77a ecec196a ccc52973',
-+  hash: hash.sha384,
-+  gRed: false,
-+  g: [
-+    'aa87ca22 be8b0537 8eb1c71e f320ad74 6e1d3b62 8ba79b98 59f741e0 82542a38 ' +
-+    '5502f25d bf55296c 3a545e38 72760ab7',
-+    '3617de4a 96262c6f 5d9e98bf 9292dc29 f8f41dbd 289a147c e9da3113 b5f0b8c0 ' +
-+    '0a60b1ce 1d7e819d 7a431d7c 90ea0e5f'
-+  ]
-+});
-+
-+defineCurve('p521', {
-+  type: 'short',
-+  prime: null,
-+  p: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
-+     'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
-+     'ffffffff ffffffff ffffffff ffffffff ffffffff',
-+  a: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
-+     'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
-+     'ffffffff ffffffff ffffffff ffffffff fffffffc',
-+  b: '00000051 953eb961 8e1c9a1f 929a21a0 b68540ee a2da725b ' +
-+     '99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd ' +
-+     '3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00',
-+  n: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
-+     'ffffffff ffffffff fffffffa 51868783 bf2f966b 7fcc0148 ' +
-+     'f709a5d0 3bb5c9b8 899c47ae bb6fb71e 91386409',
-+  hash: hash.sha512,
-+  gRed: false,
-+  g: [
-+    '000000c6 858e06b7 0404e9cd 9e3ecb66 2395b442 9c648139 ' +
-+    '053fb521 f828af60 6b4d3dba a14b5e77 efe75928 fe1dc127 ' +
-+    'a2ffa8de 3348b3c1 856a429b f97e7e31 c2e5bd66',
-+    '00000118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9 98f54449 ' +
-+    '579b4468 17afbd17 273e662c 97ee7299 5ef42640 c550b901 ' +
-+    '3fad0761 353c7086 a272c240 88be9476 9fd16650'
-+  ]
-+});
-+
-+defineCurve('curve25519', {
-+  type: 'mont',
-+  prime: 'p25519',
-+  p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',
-+  a: '76d06',
-+  b: '0',
-+  n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',
-+  hash: hash.sha256,
-+  gRed: false,
-+  g: [
-+    '9'
-+  ]
-+});
-+
-+defineCurve('ed25519', {
-+  type: 'edwards',
-+  prime: 'p25519',
-+  p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',
-+  a: '-1',
-+  c: '1',
-+  // -121665 * (121666^(-1)) (mod P)
-+  d: '52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3',
-+  n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',
-+  hash: hash.sha256,
-+  gRed: false,
-+  g: [
-+    '216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a',
-+
-+    // 4/5
-+    '6666666666666666666666666666666666666666666666666666666666666658'
-+  ]
-+});
-+
-+var pre;
-+try {
-+  pre = require('./precomputed/secp256k1');
-+} catch (e) {
-+  pre = undefined;
-+}
-+
-+defineCurve('secp256k1', {
-+  type: 'short',
-+  prime: 'k256',
-+  p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f',
-+  a: '0',
-+  b: '7',
-+  n: 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141',
-+  h: '1',
-+  hash: hash.sha256,
-+
-+  // Precomputed endomorphism
-+  beta: '7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee',
-+  lambda: '5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72',
-+  basis: [
-+    {
-+      a: '3086d221a7d46bcde86c90e49284eb15',
-+      b: '-e4437ed6010e88286f547fa90abfe4c3'
-+    },
-+    {
-+      a: '114ca50f7a8e2f3f657c1108d9d44cfd8',
-+      b: '3086d221a7d46bcde86c90e49284eb15'
-+    }
-+  ],
-+
-+  gRed: false,
-+  g: [
-+    '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
-+    '483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8',
-+    pre
-+  ]
-+});
-+
-+},{"../elliptic":2,"./precomputed/secp256k1":16,"hash.js":19}],9:[function(require,module,exports){
-+'use strict';
-+
-+var BN = require('bn.js');
-+var elliptic = require('../../elliptic');
-+var utils = elliptic.utils;
-+var assert = utils.assert;
-+
-+var KeyPair = require('./key');
-+var Signature = require('./signature');
-+
-+function EC(options) {
-+  if (!(this instanceof EC))
-+    return new EC(options);
-+
-+  // Shortcut `elliptic.ec(curve-name)`
-+  if (typeof options === 'string') {
-+    assert(elliptic.curves.hasOwnProperty(options), 'Unknown curve ' + options);
-+
-+    options = elliptic.curves[options];
-+  }
-+
-+  // Shortcut for `elliptic.ec(elliptic.curves.curveName)`
-+  if (options instanceof elliptic.curves.PresetCurve)
-+    options = { curve: options };
-+
-+  this.curve = options.curve.curve;
-+  this.n = this.curve.n;
-+  this.nh = this.n.ushrn(1);
-+  this.g = this.curve.g;
-+
-+  // Point on curve
-+  this.g = options.curve.g;
-+  this.g.precompute(options.curve.n.bitLength() + 1);
-+
-+  // Hash for function for DRBG
-+  this.hash = options.hash || options.curve.hash;
-+}
-+module.exports = EC;
-+
-+EC.prototype.keyPair = function keyPair(options) {
-+  return new KeyPair(this, options);
-+};
-+
-+EC.prototype.keyFromPrivate = function keyFromPrivate(priv, enc) {
-+  return KeyPair.fromPrivate(this, priv, enc);
-+};
-+
-+EC.prototype.keyFromPublic = function keyFromPublic(pub, enc) {
-+  return KeyPair.fromPublic(this, pub, enc);
-+};
-+
-+EC.prototype.genKeyPair = function genKeyPair(options) {
-+  if (!options)
-+    options = {};
-+
-+  // Instantiate Hmac_DRBG
-+  var drbg = new elliptic.hmacDRBG({
-+    hash: this.hash,
-+    pers: options.pers,
-+    entropy: options.entropy || elliptic.rand(this.hash.hmacStrength),
-+    nonce: this.n.toArray()
-+  });
-+
-+  var bytes = this.n.byteLength();
-+  var ns2 = this.n.sub(new BN(2));
-+  do {
-+    var priv = new BN(drbg.generate(bytes));
-+    if (priv.cmp(ns2) > 0)
-+      continue;
-+
-+    priv.iaddn(1);
-+    return this.keyFromPrivate(priv);
-+  } while (true);
-+};
-+
-+EC.prototype._truncateToN = function truncateToN(msg, truncOnly) {
-+  var delta = msg.byteLength() * 8 - this.n.bitLength();
-+  if (delta > 0)
-+    msg = msg.ushrn(delta);
-+  if (!truncOnly && msg.cmp(this.n) >= 0)
-+    return msg.sub(this.n);
-+  else
-+    return msg;
-+};
-+
-+EC.prototype.sign = function sign(msg, key, enc, options) {
-+  if (typeof enc === 'object') {
-+    options = enc;
-+    enc = null;
-+  }
-+  if (!options)
-+    options = {};
-+
-+  key = this.keyFromPrivate(key, enc);
-+  msg = this._truncateToN(new BN(msg, 16));
-+
-+  // Zero-extend key to provide enough entropy
-+  var bytes = this.n.byteLength();
-+  var bkey = key.getPrivate().toArray('be', bytes);
-+
-+  // Zero-extend nonce to have the same byte size as N
-+  var nonce = msg.toArray('be', bytes);
-+
-+  // Instantiate Hmac_DRBG
-+  var drbg = new elliptic.hmacDRBG({
-+    hash: this.hash,
-+    entropy: bkey,
-+    nonce: nonce,
-+    pers: options.pers,
-+    persEnc: options.persEnc
-+  });
-+
-+  // Number of bytes to generate
-+  var ns1 = this.n.sub(new BN(1));
-+
-+  for (var iter = 0; true; iter++) {
-+    var k = options.k ?
-+        options.k(iter) :
-+        new BN(drbg.generate(this.n.byteLength()));
-+    k = this._truncateToN(k, true);
-+    if (k.cmpn(1) <= 0 || k.cmp(ns1) >= 0)
-+      continue;
-+
-+    var kp = this.g.mul(k);
-+    if (kp.isInfinity())
-+      continue;
-+
-+    var kpX = kp.getX();
-+    var r = kpX.umod(this.n);
-+    if (r.cmpn(0) === 0)
-+      continue;
-+
-+    var s = k.invm(this.n).mul(r.mul(key.getPrivate()).iadd(msg));
-+    s = s.umod(this.n);
-+    if (s.cmpn(0) === 0)
-+      continue;
-+
-+    var recoveryParam = (kp.getY().isOdd() ? 1 : 0) |
-+                        (kpX.cmp(r) !== 0 ? 2 : 0);
-+
-+    // Use complement of `s`, if it is > `n / 2`
-+    if (options.canonical && s.cmp(this.nh) > 0) {
-+      s = this.n.sub(s);
-+      recoveryParam ^= 1;
-+    }
-+
-+    return new Signature({ r: r, s: s, recoveryParam: recoveryParam });
-+  }
-+};
-+
-+EC.prototype.verify = function verify(msg, signature, key, enc) {
-+  msg = this._truncateToN(new BN(msg, 16));
-+  key = this.keyFromPublic(key, enc);
-+  signature = new Signature(signature, 'hex');
-+
-+  // Perform primitive values validation
-+  var r = signature.r;
-+  var s = signature.s;
-+  if (r.cmpn(1) < 0 || r.cmp(this.n) >= 0)
-+    return false;
-+  if (s.cmpn(1) < 0 || s.cmp(this.n) >= 0)
-+    return false;
-+
-+  // Validate signature
-+  var sinv = s.invm(this.n);
-+  var u1 = sinv.mul(msg).umod(this.n);
-+  var u2 = sinv.mul(r).umod(this.n);
-+
-+  if (!this.curve._maxwellTrick) {
-+    var p = this.g.mulAdd(u1, key.getPublic(), u2);
-+    if (p.isInfinity())
-+      return false;
-+
-+    return p.getX().umod(this.n).cmp(r) === 0;
-+  }
-+
-+  // NOTE: Greg Maxwell's trick, inspired by:
-+  // https://git.io/vad3K
-+
-+  var p = this.g.jmulAdd(u1, key.getPublic(), u2);
-+  if (p.isInfinity())
-+    return false;
-+
-+  // Compare `p.x` of Jacobian point with `r`,
-+  // this will do `p.x == r * p.z^2` instead of multiplying `p.x` by the
-+  // inverse of `p.z^2`
-+  return p.eqXToP(r);
-+};
-+
-+EC.prototype.recoverPubKey = function(msg, signature, j, enc) {
-+  assert((3 & j) === j, 'The recovery param is more than two bits');
-+  signature = new Signature(signature, enc);
-+
-+  var n = this.n;
-+  var e = new BN(msg);
-+  var r = signature.r;
-+  var s = signature.s;
-+
-+  // A set LSB signifies that the y-coordinate is odd
-+  var isYOdd = j & 1;
-+  var isSecondKey = j >> 1;
-+  if (r.cmp(this.curve.p.umod(this.curve.n)) >= 0 && isSecondKey)
-+    throw new Error('Unable to find sencond key candinate');
-+
-+  // 1.1. Let x = r + jn.
-+  if (isSecondKey)
-+    r = this.curve.pointFromX(r.add(this.curve.n), isYOdd);
-+  else
-+    r = this.curve.pointFromX(r, isYOdd);
-+
-+  var rInv = signature.r.invm(n);
-+  var s1 = n.sub(e).mul(rInv).umod(n);
-+  var s2 = s.mul(rInv).umod(n);
-+
-+  // 1.6.1 Compute Q = r^-1 (sR -  eG)
-+  //               Q = r^-1 (sR + -eG)
-+  return this.g.mulAdd(s1, r, s2);
-+};
-+
-+EC.prototype.getKeyRecoveryParam = function(e, signature, Q, enc) {
-+  signature = new Signature(signature, enc);
-+  if (signature.recoveryParam !== null)
-+    return signature.recoveryParam;
-+
-+  for (var i = 0; i < 4; i++) {
-+    var Qprime;
-+    try {
-+      Qprime = this.recoverPubKey(e, signature, i);
-+    } catch (e) {
-+      continue;
-+    }
-+
-+    if (Qprime.eq(Q))
-+      return i;
-+  }
-+  throw new Error('Unable to find valid recovery factor');
-+};
-+
-+},{"../../elliptic":2,"./key":10,"./signature":11,"bn.js":1}],10:[function(require,module,exports){
-+'use strict';
-+
-+var BN = require('bn.js');
-+
-+function KeyPair(ec, options) {
-+  this.ec = ec;
-+  this.priv = null;
-+  this.pub = null;
-+
-+  // KeyPair(ec, { priv: ..., pub: ... })
-+  if (options.priv)
-+    this._importPrivate(options.priv, options.privEnc);
-+  if (options.pub)
-+    this._importPublic(options.pub, options.pubEnc);
-+}
-+module.exports = KeyPair;
-+
-+KeyPair.fromPublic = function fromPublic(ec, pub, enc) {
-+  if (pub instanceof KeyPair)
-+    return pub;
-+
-+  return new KeyPair(ec, {
-+    pub: pub,
-+    pubEnc: enc
-+  });
-+};
-+
-+KeyPair.fromPrivate = function fromPrivate(ec, priv, enc) {
-+  if (priv instanceof KeyPair)
-+    return priv;
-+
-+  return new KeyPair(ec, {
-+    priv: priv,
-+    privEnc: enc
-+  });
-+};
-+
-+KeyPair.prototype.validate = function validate() {
-+  var pub = this.getPublic();
-+
-+  if (pub.isInfinity())
-+    return { result: false, reason: 'Invalid public key' };
-+  if (!pub.validate())
-+    return { result: false, reason: 'Public key is not a point' };
-+  if (!pub.mul(this.ec.curve.n).isInfinity())
-+    return { result: false, reason: 'Public key * N != O' };
-+
-+  return { result: true, reason: null };
-+};
-+
-+KeyPair.prototype.getPublic = function getPublic(compact, enc) {
-+  // compact is optional argument
-+  if (typeof compact === 'string') {
-+    enc = compact;
-+    compact = null;
-+  }
-+
-+  if (!this.pub)
-+    this.pub = this.ec.g.mul(this.priv);
-+
-+  if (!enc)
-+    return this.pub;
-+
-+  return this.pub.encode(enc, compact);
-+};
-+
-+KeyPair.prototype.getPrivate = function getPrivate(enc) {
-+  if (enc === 'hex')
-+    return this.priv.toString(16, 2);
-+  else
-+    return this.priv;
-+};
-+
-+KeyPair.prototype._importPrivate = function _importPrivate(key, enc) {
-+  this.priv = new BN(key, enc || 16);
-+
-+  // Ensure that the priv won't be bigger than n, otherwise we may fail
-+  // in fixed multiplication method
-+  this.priv = this.priv.umod(this.ec.curve.n);
-+};
-+
-+KeyPair.prototype._importPublic = function _importPublic(key, enc) {
-+  if (key.x || key.y) {
-+    this.pub = this.ec.curve.point(key.x, key.y);
-+    return;
-+  }
-+  this.pub = this.ec.curve.decodePoint(key, enc);
-+};
-+
-+// ECDH
-+KeyPair.prototype.derive = function derive(pub) {
-+  return pub.mul(this.priv).getX();
-+};
-+
-+// ECDSA
-+KeyPair.prototype.sign = function sign(msg, enc, options) {
-+  return this.ec.sign(msg, this, enc, options);
-+};
-+
-+KeyPair.prototype.verify = function verify(msg, signature) {
-+  return this.ec.verify(msg, signature, this);
-+};
-+
-+KeyPair.prototype.inspect = function inspect() {
-+  return '<Key priv: ' + (this.priv && this.priv.toString(16, 2)) +
-+         ' pub: ' + (this.pub && this.pub.inspect()) + ' >';
-+};
-+
-+},{"bn.js":1}],11:[function(require,module,exports){
-+'use strict';
-+
-+var BN = require('bn.js');
-+
-+var elliptic = require('../../elliptic');
-+var utils = elliptic.utils;
-+var assert = utils.assert;
-+
-+function Signature(options, enc) {
-+  if (options instanceof Signature)
-+    return options;
-+
-+  if (this._importDER(options, enc))
-+    return;
-+
-+  assert(options.r && options.s, 'Signature without r or s');
-+  this.r = new BN(options.r, 16);
-+  this.s = new BN(options.s, 16);
-+  if (options.recoveryParam === undefined)
-+    this.recoveryParam = null;
-+  else
-+    this.recoveryParam = options.recoveryParam;
-+}
-+module.exports = Signature;
-+
-+function Position() {
-+  this.place = 0;
-+}
-+
-+function getLength(buf, p) {
-+  var initial = buf[p.place++];
-+  if (!(initial & 0x80)) {
-+    return initial;
-+  }
-+  var octetLen = initial & 0xf;
-+  var val = 0;
-+  for (var i = 0, off = p.place; i < octetLen; i++, off++) {
-+    val <<= 8;
-+    val |= buf[off];
-+  }
-+  p.place = off;
-+  return val;
-+}
-+
-+function rmPadding(buf) {
-+  var i = 0;
-+  var len = buf.length - 1;
-+  while (!buf[i] && !(buf[i + 1] & 0x80) && i < len) {
-+    i++;
-+  }
-+  if (i === 0) {
-+    return buf;
-+  }
-+  return buf.slice(i);
-+}
-+
-+Signature.prototype._importDER = function _importDER(data, enc) {
-+  data = utils.toArray(data, enc);
-+  var p = new Position();
-+  if (data[p.place++] !== 0x30) {
-+    return false;
-+  }
-+  var len = getLength(data, p);
-+  if ((len + p.place) !== data.length) {
-+    return false;
-+  }
-+  if (data[p.place++] !== 0x02) {
-+    return false;
-+  }
-+  var rlen = getLength(data, p);
-+  var r = data.slice(p.place, rlen + p.place);
-+  p.place += rlen;
-+  if (data[p.place++] !== 0x02) {
-+    return false;
-+  }
-+  var slen = getLength(data, p);
-+  if (data.length !== slen + p.place) {
-+    return false;
-+  }
-+  var s = data.slice(p.place, slen + p.place);
-+  if (r[0] === 0 && (r[1] & 0x80)) {
-+    r = r.slice(1);
-+  }
-+  if (s[0] === 0 && (s[1] & 0x80)) {
-+    s = s.slice(1);
-+  }
-+
-+  this.r = new BN(r);
-+  this.s = new BN(s);
-+  this.recoveryParam = null;
-+
-+  return true;
-+};
-+
-+function constructLength(arr, len) {
-+  if (len < 0x80) {
-+    arr.push(len);
-+    return;
-+  }
-+  var octets = 1 + (Math.log(len) / Math.LN2 >>> 3);
-+  arr.push(octets | 0x80);
-+  while (--octets) {
-+    arr.push((len >>> (octets << 3)) & 0xff);
-+  }
-+  arr.push(len);
-+}
-+
-+Signature.prototype.toDER = function toDER(enc) {
-+  var r = this.r.toArray();
-+  var s = this.s.toArray();
-+
-+  // Pad values
-+  if (r[0] & 0x80)
-+    r = [ 0 ].concat(r);
-+  // Pad values
-+  if (s[0] & 0x80)
-+    s = [ 0 ].concat(s);
-+
-+  r = rmPadding(r);
-+  s = rmPadding(s);
-+
-+  while (!s[0] && !(s[1] & 0x80)) {
-+    s = s.slice(1);
-+  }
-+  var arr = [ 0x02 ];
-+  constructLength(arr, r.length);
-+  arr = arr.concat(r);
-+  arr.push(0x02);
-+  constructLength(arr, s.length);
-+  var backHalf = arr.concat(s);
-+  var res = [ 0x30 ];
-+  constructLength(res, backHalf.length);
-+  res = res.concat(backHalf);
-+  return utils.encode(res, enc);
-+};
-+
-+},{"../../elliptic":2,"bn.js":1}],12:[function(require,module,exports){
-+'use strict';
-+
-+var hash = require('hash.js');
-+var elliptic = require('../../elliptic');
-+var utils = elliptic.utils;
-+var assert = utils.assert;
-+var parseBytes = utils.parseBytes;
-+var KeyPair = require('./key');
-+var Signature = require('./signature');
-+
-+function EDDSA(curve) {
-+  assert(curve === 'ed25519', 'only tested with ed25519 so far');
-+
-+  if (!(this instanceof EDDSA))
-+    return new EDDSA(curve);
-+
-+  var curve = elliptic.curves[curve].curve;
-+  this.curve = curve;
-+  this.g = curve.g;
-+  this.g.precompute(curve.n.bitLength() + 1);
-+
-+  this.pointClass = curve.point().constructor;
-+  this.encodingLength = Math.ceil(curve.n.bitLength() / 8);
-+  this.hash = hash.sha512;
-+}
-+
-+module.exports = EDDSA;
-+
-+/**
-+* @param {Array|String} message - message bytes
-+* @param {Array|String|KeyPair} secret - secret bytes or a keypair
-+* @returns {Signature} - signature
-+*/
-+EDDSA.prototype.sign = function sign(message, secret) {
-+  message = parseBytes(message);
-+  var key = this.keyFromSecret(secret);
-+  var r = this.hashInt(key.messagePrefix(), message);
-+  var R = this.g.mul(r);
-+  var Rencoded = this.encodePoint(R);
-+  var s_ = this.hashInt(Rencoded, key.pubBytes(), message)
-+               .mul(key.priv());
-+  var S = r.add(s_).umod(this.curve.n);
-+  return this.makeSignature({ R: R, S: S, Rencoded: Rencoded });
-+};
-+
-+/**
-+* @param {Array} message - message bytes
-+* @param {Array|String|Signature} sig - sig bytes
-+* @param {Array|String|Point|KeyPair} pub - public key
-+* @returns {Boolean} - true if public key matches sig of message
-+*/
-+EDDSA.prototype.verify = function verify(message, sig, pub) {
-+  message = parseBytes(message);
-+  sig = this.makeSignature(sig);
-+  var key = this.keyFromPublic(pub);
-+  var h = this.hashInt(sig.Rencoded(), key.pubBytes(), message);
-+  var SG = this.g.mul(sig.S());
-+  var RplusAh = sig.R().add(key.pub().mul(h));
-+  return RplusAh.eq(SG);
-+};
-+
-+EDDSA.prototype.hashInt = function hashInt() {
-+  var hash = this.hash();
-+  for (var i = 0; i < arguments.length; i++)
-+    hash.update(arguments[i]);
-+  return utils.intFromLE(hash.digest()).umod(this.curve.n);
-+};
-+
-+EDDSA.prototype.keyFromPublic = function keyFromPublic(pub) {
-+  return KeyPair.fromPublic(this, pub);
-+};
-+
-+EDDSA.prototype.keyFromSecret = function keyFromSecret(secret) {
-+  return KeyPair.fromSecret(this, secret);
-+};
-+
-+EDDSA.prototype.makeSignature = function makeSignature(sig) {
-+  if (sig instanceof Signature)
-+    return sig;
-+  return new Signature(this, sig);
-+};
-+
-+/**
-+* * https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03#section-5.2
-+*
-+* EDDSA defines methods for encoding and decoding points and integers. These are
-+* helper convenience methods, that pass along to utility functions implied
-+* parameters.
-+*
-+*/
-+EDDSA.prototype.encodePoint = function encodePoint(point) {
-+  var enc = point.getY().toArray('le', this.encodingLength);
-+  enc[this.encodingLength - 1] |= point.getX().isOdd() ? 0x80 : 0;
-+  return enc;
-+};
-+
-+EDDSA.prototype.decodePoint = function decodePoint(bytes) {
-+  bytes = utils.parseBytes(bytes);
-+
-+  var lastIx = bytes.length - 1;
-+  var normed = bytes.slice(0, lastIx).concat(bytes[lastIx] & ~0x80);
-+  var xIsOdd = (bytes[lastIx] & 0x80) !== 0;
-+
-+  var y = utils.intFromLE(normed);
-+  return this.curve.pointFromY(y, xIsOdd);
-+};
-+
-+EDDSA.prototype.encodeInt = function encodeInt(num) {
-+  return num.toArray('le', this.encodingLength);
-+};
-+
-+EDDSA.prototype.decodeInt = function decodeInt(bytes) {
-+  return utils.intFromLE(bytes);
-+};
-+
-+EDDSA.prototype.isPoint = function isPoint(val) {
-+  return val instanceof this.pointClass;
-+};
-+
-+},{"../../elliptic":2,"./key":13,"./signature":14,"hash.js":19}],13:[function(require,module,exports){
-+'use strict';
-+
-+var elliptic = require('../../elliptic');
-+var utils = elliptic.utils;
-+var assert = utils.assert;
-+var parseBytes = utils.parseBytes;
-+var cachedProperty = utils.cachedProperty;
-+
-+/**
-+* @param {EDDSA} eddsa - instance
-+* @param {Object} params - public/private key parameters
-+*
-+* @param {Array<Byte>} [params.secret] - secret seed bytes
-+* @param {Point} [params.pub] - public key point (aka `A` in eddsa terms)
-+* @param {Array<Byte>} [params.pub] - public key point encoded as bytes
-+*
-+*/
-+function KeyPair(eddsa, params) {
-+  this.eddsa = eddsa;
-+  this._secret = parseBytes(params.secret);
-+  if (eddsa.isPoint(params.pub))
-+    this._pub = params.pub;
-+  else
-+    this._pubBytes = parseBytes(params.pub);
-+}
-+
-+KeyPair.fromPublic = function fromPublic(eddsa, pub) {
-+  if (pub instanceof KeyPair)
-+    return pub;
-+  return new KeyPair(eddsa, { pub: pub });
-+};
-+
-+KeyPair.fromSecret = function fromSecret(eddsa, secret) {
-+  if (secret instanceof KeyPair)
-+    return secret;
-+  return new KeyPair(eddsa, { secret: secret });
-+};
-+
-+KeyPair.prototype.secret = function secret() {
-+  return this._secret;
-+};
-+
-+cachedProperty(KeyPair, 'pubBytes', function pubBytes() {
-+  return this.eddsa.encodePoint(this.pub());
-+});
-+
-+cachedProperty(KeyPair, 'pub', function pub() {
-+  if (this._pubBytes)
-+    return this.eddsa.decodePoint(this._pubBytes);
-+  return this.eddsa.g.mul(this.priv());
-+});
-+
-+cachedProperty(KeyPair, 'privBytes', function privBytes() {
-+  var eddsa = this.eddsa;
-+  var hash = this.hash();
-+  var lastIx = eddsa.encodingLength - 1;
-+
-+  var a = hash.slice(0, eddsa.encodingLength);
-+  a[0] &= 248;
-+  a[lastIx] &= 127;
-+  a[lastIx] |= 64;
-+
-+  return a;
-+});
-+
-+cachedProperty(KeyPair, 'priv', function priv() {
-+  return this.eddsa.decodeInt(this.privBytes());
-+});
-+
-+cachedProperty(KeyPair, 'hash', function hash() {
-+  return this.eddsa.hash().update(this.secret()).digest();
-+});
-+
-+cachedProperty(KeyPair, 'messagePrefix', function messagePrefix() {
-+  return this.hash().slice(this.eddsa.encodingLength);
-+});
-+
-+KeyPair.prototype.sign = function sign(message) {
-+  assert(this._secret, 'KeyPair can only verify');
-+  return this.eddsa.sign(message, this);
-+};
-+
-+KeyPair.prototype.verify = function verify(message, sig) {
-+  return this.eddsa.verify(message, sig, this);
-+};
-+
-+KeyPair.prototype.getSecret = function getSecret(enc) {
-+  assert(this._secret, 'KeyPair is public only');
-+  return utils.encode(this.secret(), enc);
-+};
-+
-+KeyPair.prototype.getPublic = function getPublic(enc) {
-+  return utils.encode(this.pubBytes(), enc);
-+};
-+
-+module.exports = KeyPair;
-+
-+},{"../../elliptic":2}],14:[function(require,module,exports){
-+'use strict';
-+
-+var BN = require('bn.js');
-+var elliptic = require('../../elliptic');
-+var utils = elliptic.utils;
-+var assert = utils.assert;
-+var cachedProperty = utils.cachedProperty;
-+var parseBytes = utils.parseBytes;
-+
-+/**
-+* @param {EDDSA} eddsa - eddsa instance
-+* @param {Array<Bytes>|Object} sig -
-+* @param {Array<Bytes>|Point} [sig.R] - R point as Point or bytes
-+* @param {Array<Bytes>|bn} [sig.S] - S scalar as bn or bytes
-+* @param {Array<Bytes>} [sig.Rencoded] - R point encoded
-+* @param {Array<Bytes>} [sig.Sencoded] - S scalar encoded
-+*/
-+function Signature(eddsa, sig) {
-+  this.eddsa = eddsa;
-+
-+  if (typeof sig !== 'object')
-+    sig = parseBytes(sig);
-+
-+  if (Array.isArray(sig)) {
-+    sig = {
-+      R: sig.slice(0, eddsa.encodingLength),
-+      S: sig.slice(eddsa.encodingLength)
-+    };
-+  }
-+
-+  assert(sig.R && sig.S, 'Signature without R or S');
-+
-+  if (eddsa.isPoint(sig.R))
-+    this._R = sig.R;
-+  if (sig.S instanceof BN)
-+    this._S = sig.S;
-+
-+  this._Rencoded = Array.isArray(sig.R) ? sig.R : sig.Rencoded;
-+  this._Sencoded = Array.isArray(sig.S) ? sig.S : sig.Sencoded;
-+}
-+
-+cachedProperty(Signature, 'S', function S() {
-+  return this.eddsa.decodeInt(this.Sencoded());
-+});
-+
-+cachedProperty(Signature, 'R', function R() {
-+  return this.eddsa.decodePoint(this.Rencoded());
-+});
-+
-+cachedProperty(Signature, 'Rencoded', function Rencoded() {
-+  return this.eddsa.encodePoint(this.R());
-+});
-+
-+cachedProperty(Signature, 'Sencoded', function Sencoded() {
-+  return this.eddsa.encodeInt(this.S());
-+});
-+
-+Signature.prototype.toBytes = function toBytes() {
-+  return this.Rencoded().concat(this.Sencoded());
-+};
-+
-+Signature.prototype.toHex = function toHex() {
-+  return utils.encode(this.toBytes(), 'hex').toUpperCase();
-+};
-+
-+module.exports = Signature;
-+
-+},{"../../elliptic":2,"bn.js":1}],15:[function(require,module,exports){
-+'use strict';
-+
-+var hash = require('hash.js');
-+var elliptic = require('../elliptic');
-+var utils = elliptic.utils;
-+var assert = utils.assert;
-+
-+function HmacDRBG(options) {
-+  if (!(this instanceof HmacDRBG))
-+    return new HmacDRBG(options);
-+  this.hash = options.hash;
-+  this.predResist = !!options.predResist;
-+
-+  this.outLen = this.hash.outSize;
-+  this.minEntropy = options.minEntropy || this.hash.hmacStrength;
-+
-+  this.reseed = null;
-+  this.reseedInterval = null;
-+  this.K = null;
-+  this.V = null;
-+
-+  var entropy = utils.toArray(options.entropy, options.entropyEnc);
-+  var nonce = utils.toArray(options.nonce, options.nonceEnc);
-+  var pers = utils.toArray(options.pers, options.persEnc);
-+  assert(entropy.length >= (this.minEntropy / 8),
-+         'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');
-+  this._init(entropy, nonce, pers);
-+}
-+module.exports = HmacDRBG;
-+
-+HmacDRBG.prototype._init = function init(entropy, nonce, pers) {
-+  var seed = entropy.concat(nonce).concat(pers);
-+
-+  this.K = new Array(this.outLen / 8);
-+  this.V = new Array(this.outLen / 8);
-+  for (var i = 0; i < this.V.length; i++) {
-+    this.K[i] = 0x00;
-+    this.V[i] = 0x01;
-+  }
-+
-+  this._update(seed);
-+  this.reseed = 1;
-+  this.reseedInterval = 0x1000000000000;  // 2^48
-+};
-+
-+HmacDRBG.prototype._hmac = function hmac() {
-+  return new hash.hmac(this.hash, this.K);
-+};
-+
-+HmacDRBG.prototype._update = function update(seed) {
-+  var kmac = this._hmac()
-+                 .update(this.V)
-+                 .update([ 0x00 ]);
-+  if (seed)
-+    kmac = kmac.update(seed);
-+  this.K = kmac.digest();
-+  this.V = this._hmac().update(this.V).digest();
-+  if (!seed)
-+    return;
-+
-+  this.K = this._hmac()
-+               .update(this.V)
-+               .update([ 0x01 ])
-+               .update(seed)
-+               .digest();
-+  this.V = this._hmac().update(this.V).digest();
-+};
-+
-+HmacDRBG.prototype.reseed = function reseed(entropy, entropyEnc, add, addEnc) {
-+  // Optional entropy enc
-+  if (typeof entropyEnc !== 'string') {
-+    addEnc = add;
-+    add = entropyEnc;
-+    entropyEnc = null;
-+  }
-+
-+  entropy = utils.toBuffer(entropy, entropyEnc);
-+  add = utils.toBuffer(add, addEnc);
-+
-+  assert(entropy.length >= (this.minEntropy / 8),
-+         'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');
-+
-+  this._update(entropy.concat(add || []));
-+  this.reseed = 1;
-+};
-+
-+HmacDRBG.prototype.generate = function generate(len, enc, add, addEnc) {
-+  if (this.reseed > this.reseedInterval)
-+    throw new Error('Reseed is required');
-+
-+  // Optional encoding
-+  if (typeof enc !== 'string') {
-+    addEnc = add;
-+    add = enc;
-+    enc = null;
-+  }
-+
-+  // Optional additional data
-+  if (add) {
-+    add = utils.toArray(add, addEnc);
-+    this._update(add);
-+  }
-+
-+  var temp = [];
-+  while (temp.length < len) {
-+    this.V = this._hmac().update(this.V).digest();
-+    temp = temp.concat(this.V);
-+  }
-+
-+  var res = temp.slice(0, len);
-+  this._update(add);
-+  this.reseed++;
-+  return utils.encode(res, enc);
-+};
-+
-+},{"../elliptic":2,"hash.js":19}],16:[function(require,module,exports){
-+module.exports = {
-+  doubles: {
-+    step: 4,
-+    points: [
-+      [
-+        'e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a',
-+        'f7e3507399e595929db99f34f57937101296891e44d23f0be1f32cce69616821'
-+      ],
-+      [
-+        '8282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508',
-+        '11f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf'
-+      ],
-+      [
-+        '175e159f728b865a72f99cc6c6fc846de0b93833fd2222ed73fce5b551e5b739',
-+        'd3506e0d9e3c79eba4ef97a51ff71f5eacb5955add24345c6efa6ffee9fed695'
-+      ],
-+      [
-+        '363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640',
-+        '4e273adfc732221953b445397f3363145b9a89008199ecb62003c7f3bee9de9'
-+      ],
-+      [
-+        '8b4b5f165df3c2be8c6244b5b745638843e4a781a15bcd1b69f79a55dffdf80c',
-+        '4aad0a6f68d308b4b3fbd7813ab0da04f9e336546162ee56b3eff0c65fd4fd36'
-+      ],
-+      [
-+        '723cbaa6e5db996d6bf771c00bd548c7b700dbffa6c0e77bcb6115925232fcda',
-+        '96e867b5595cc498a921137488824d6e2660a0653779494801dc069d9eb39f5f'
-+      ],
-+      [
-+        'eebfa4d493bebf98ba5feec812c2d3b50947961237a919839a533eca0e7dd7fa',
-+        '5d9a8ca3970ef0f269ee7edaf178089d9ae4cdc3a711f712ddfd4fdae1de8999'
-+      ],
-+      [
-+        '100f44da696e71672791d0a09b7bde459f1215a29b3c03bfefd7835b39a48db0',
-+        'cdd9e13192a00b772ec8f3300c090666b7ff4a18ff5195ac0fbd5cd62bc65a09'
-+      ],
-+      [
-+        'e1031be262c7ed1b1dc9227a4a04c017a77f8d4464f3b3852c8acde6e534fd2d',
-+        '9d7061928940405e6bb6a4176597535af292dd419e1ced79a44f18f29456a00d'
-+      ],
-+      [
-+        'feea6cae46d55b530ac2839f143bd7ec5cf8b266a41d6af52d5e688d9094696d',
-+        'e57c6b6c97dce1bab06e4e12bf3ecd5c981c8957cc41442d3155debf18090088'
-+      ],
-+      [
-+        'da67a91d91049cdcb367be4be6ffca3cfeed657d808583de33fa978bc1ec6cb1',
-+        '9bacaa35481642bc41f463f7ec9780e5dec7adc508f740a17e9ea8e27a68be1d'
-+      ],
-+      [
-+        '53904faa0b334cdda6e000935ef22151ec08d0f7bb11069f57545ccc1a37b7c0',
-+        '5bc087d0bc80106d88c9eccac20d3c1c13999981e14434699dcb096b022771c8'
-+      ],
-+      [
-+        '8e7bcd0bd35983a7719cca7764ca906779b53a043a9b8bcaeff959f43ad86047',
-+        '10b7770b2a3da4b3940310420ca9514579e88e2e47fd68b3ea10047e8460372a'
-+      ],
-+      [
-+        '385eed34c1cdff21e6d0818689b81bde71a7f4f18397e6690a841e1599c43862',
-+        '283bebc3e8ea23f56701de19e9ebf4576b304eec2086dc8cc0458fe5542e5453'
-+      ],
-+      [
-+        '6f9d9b803ecf191637c73a4413dfa180fddf84a5947fbc9c606ed86c3fac3a7',
-+        '7c80c68e603059ba69b8e2a30e45c4d47ea4dd2f5c281002d86890603a842160'
-+      ],
-+      [
-+        '3322d401243c4e2582a2147c104d6ecbf774d163db0f5e5313b7e0e742d0e6bd',
-+        '56e70797e9664ef5bfb019bc4ddaf9b72805f63ea2873af624f3a2e96c28b2a0'
-+      ],
-+      [
-+        '85672c7d2de0b7da2bd1770d89665868741b3f9af7643397721d74d28134ab83',
-+        '7c481b9b5b43b2eb6374049bfa62c2e5e77f17fcc5298f44c8e3094f790313a6'
-+      ],
-+      [
-+        '948bf809b1988a46b06c9f1919413b10f9226c60f668832ffd959af60c82a0a',
-+        '53a562856dcb6646dc6b74c5d1c3418c6d4dff08c97cd2bed4cb7f88d8c8e589'
-+      ],
-+      [
-+        '6260ce7f461801c34f067ce0f02873a8f1b0e44dfc69752accecd819f38fd8e8',
-+        'bc2da82b6fa5b571a7f09049776a1ef7ecd292238051c198c1a84e95b2b4ae17'
-+      ],
-+      [
-+        'e5037de0afc1d8d43d8348414bbf4103043ec8f575bfdc432953cc8d2037fa2d',
-+        '4571534baa94d3b5f9f98d09fb990bddbd5f5b03ec481f10e0e5dc841d755bda'
-+      ],
-+      [
-+        'e06372b0f4a207adf5ea905e8f1771b4e7e8dbd1c6a6c5b725866a0ae4fce725',
-+        '7a908974bce18cfe12a27bb2ad5a488cd7484a7787104870b27034f94eee31dd'
-+      ],
-+      [
-+        '213c7a715cd5d45358d0bbf9dc0ce02204b10bdde2a3f58540ad6908d0559754',
-+        '4b6dad0b5ae462507013ad06245ba190bb4850f5f36a7eeddff2c27534b458f2'
-+      ],
-+      [
-+        '4e7c272a7af4b34e8dbb9352a5419a87e2838c70adc62cddf0cc3a3b08fbd53c',
-+        '17749c766c9d0b18e16fd09f6def681b530b9614bff7dd33e0b3941817dcaae6'
-+      ],
-+      [
-+        'fea74e3dbe778b1b10f238ad61686aa5c76e3db2be43057632427e2840fb27b6',
-+        '6e0568db9b0b13297cf674deccb6af93126b596b973f7b77701d3db7f23cb96f'
-+      ],
-+      [
-+        '76e64113f677cf0e10a2570d599968d31544e179b760432952c02a4417bdde39',
-+        'c90ddf8dee4e95cf577066d70681f0d35e2a33d2b56d2032b4b1752d1901ac01'
-+      ],
-+      [
-+        'c738c56b03b2abe1e8281baa743f8f9a8f7cc643df26cbee3ab150242bcbb891',
-+        '893fb578951ad2537f718f2eacbfbbbb82314eef7880cfe917e735d9699a84c3'
-+      ],
-+      [
-+        'd895626548b65b81e264c7637c972877d1d72e5f3a925014372e9f6588f6c14b',
-+        'febfaa38f2bc7eae728ec60818c340eb03428d632bb067e179363ed75d7d991f'
-+      ],
-+      [
-+        'b8da94032a957518eb0f6433571e8761ceffc73693e84edd49150a564f676e03',
-+        '2804dfa44805a1e4d7c99cc9762808b092cc584d95ff3b511488e4e74efdf6e7'
-+      ],
-+      [
-+        'e80fea14441fb33a7d8adab9475d7fab2019effb5156a792f1a11778e3c0df5d',
-+        'eed1de7f638e00771e89768ca3ca94472d155e80af322ea9fcb4291b6ac9ec78'
-+      ],
-+      [
-+        'a301697bdfcd704313ba48e51d567543f2a182031efd6915ddc07bbcc4e16070',
-+        '7370f91cfb67e4f5081809fa25d40f9b1735dbf7c0a11a130c0d1a041e177ea1'
-+      ],
-+      [
-+        '90ad85b389d6b936463f9d0512678de208cc330b11307fffab7ac63e3fb04ed4',
-+        'e507a3620a38261affdcbd9427222b839aefabe1582894d991d4d48cb6ef150'
-+      ],
-+      [
-+        '8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da',
-+        '662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82'
-+      ],
-+      [
-+        'e4f3fb0176af85d65ff99ff9198c36091f48e86503681e3e6686fd5053231e11',
-+        '1e63633ad0ef4f1c1661a6d0ea02b7286cc7e74ec951d1c9822c38576feb73bc'
-+      ],
-+      [
-+        '8c00fa9b18ebf331eb961537a45a4266c7034f2f0d4e1d0716fb6eae20eae29e',
-+        'efa47267fea521a1a9dc343a3736c974c2fadafa81e36c54e7d2a4c66702414b'
-+      ],
-+      [
-+        'e7a26ce69dd4829f3e10cec0a9e98ed3143d084f308b92c0997fddfc60cb3e41',
-+        '2a758e300fa7984b471b006a1aafbb18d0a6b2c0420e83e20e8a9421cf2cfd51'
-+      ],
-+      [
-+        'b6459e0ee3662ec8d23540c223bcbdc571cbcb967d79424f3cf29eb3de6b80ef',
-+        '67c876d06f3e06de1dadf16e5661db3c4b3ae6d48e35b2ff30bf0b61a71ba45'
-+      ],
-+      [
-+        'd68a80c8280bb840793234aa118f06231d6f1fc67e73c5a5deda0f5b496943e8',
-+        'db8ba9fff4b586d00c4b1f9177b0e28b5b0e7b8f7845295a294c84266b133120'
-+      ],
-+      [
-+        '324aed7df65c804252dc0270907a30b09612aeb973449cea4095980fc28d3d5d',
-+        '648a365774b61f2ff130c0c35aec1f4f19213b0c7e332843967224af96ab7c84'
-+      ],
-+      [
-+        '4df9c14919cde61f6d51dfdbe5fee5dceec4143ba8d1ca888e8bd373fd054c96',
-+        '35ec51092d8728050974c23a1d85d4b5d506cdc288490192ebac06cad10d5d'
-+      ],
-+      [
-+        '9c3919a84a474870faed8a9c1cc66021523489054d7f0308cbfc99c8ac1f98cd',
-+        'ddb84f0f4a4ddd57584f044bf260e641905326f76c64c8e6be7e5e03d4fc599d'
-+      ],
-+      [
-+        '6057170b1dd12fdf8de05f281d8e06bb91e1493a8b91d4cc5a21382120a959e5',
-+        '9a1af0b26a6a4807add9a2daf71df262465152bc3ee24c65e899be932385a2a8'
-+      ],
-+      [
-+        'a576df8e23a08411421439a4518da31880cef0fba7d4df12b1a6973eecb94266',
-+        '40a6bf20e76640b2c92b97afe58cd82c432e10a7f514d9f3ee8be11ae1b28ec8'
-+      ],
-+      [
-+        '7778a78c28dec3e30a05fe9629de8c38bb30d1f5cf9a3a208f763889be58ad71',
-+        '34626d9ab5a5b22ff7098e12f2ff580087b38411ff24ac563b513fc1fd9f43ac'
-+      ],
-+      [
-+        '928955ee637a84463729fd30e7afd2ed5f96274e5ad7e5cb09eda9c06d903ac',
-+        'c25621003d3f42a827b78a13093a95eeac3d26efa8a8d83fc5180e935bcd091f'
-+      ],
-+      [
-+        '85d0fef3ec6db109399064f3a0e3b2855645b4a907ad354527aae75163d82751',
-+        '1f03648413a38c0be29d496e582cf5663e8751e96877331582c237a24eb1f962'
-+      ],
-+      [
-+        'ff2b0dce97eece97c1c9b6041798b85dfdfb6d8882da20308f5404824526087e',
-+        '493d13fef524ba188af4c4dc54d07936c7b7ed6fb90e2ceb2c951e01f0c29907'
-+      ],
-+      [
-+        '827fbbe4b1e880ea9ed2b2e6301b212b57f1ee148cd6dd28780e5e2cf856e241',
-+        'c60f9c923c727b0b71bef2c67d1d12687ff7a63186903166d605b68baec293ec'
-+      ],
-+      [
-+        'eaa649f21f51bdbae7be4ae34ce6e5217a58fdce7f47f9aa7f3b58fa2120e2b3',
-+        'be3279ed5bbbb03ac69a80f89879aa5a01a6b965f13f7e59d47a5305ba5ad93d'
-+      ],
-+      [
-+        'e4a42d43c5cf169d9391df6decf42ee541b6d8f0c9a137401e23632dda34d24f',
-+        '4d9f92e716d1c73526fc99ccfb8ad34ce886eedfa8d8e4f13a7f7131deba9414'
-+      ],
-+      [
-+        '1ec80fef360cbdd954160fadab352b6b92b53576a88fea4947173b9d4300bf19',
-+        'aeefe93756b5340d2f3a4958a7abbf5e0146e77f6295a07b671cdc1cc107cefd'
-+      ],
-+      [
-+        '146a778c04670c2f91b00af4680dfa8bce3490717d58ba889ddb5928366642be',
-+        'b318e0ec3354028add669827f9d4b2870aaa971d2f7e5ed1d0b297483d83efd0'
-+      ],
-+      [
-+        'fa50c0f61d22e5f07e3acebb1aa07b128d0012209a28b9776d76a8793180eef9',
-+        '6b84c6922397eba9b72cd2872281a68a5e683293a57a213b38cd8d7d3f4f2811'
-+      ],
-+      [
-+        'da1d61d0ca721a11b1a5bf6b7d88e8421a288ab5d5bba5220e53d32b5f067ec2',
-+        '8157f55a7c99306c79c0766161c91e2966a73899d279b48a655fba0f1ad836f1'
-+      ],
-+      [
-+        'a8e282ff0c9706907215ff98e8fd416615311de0446f1e062a73b0610d064e13',
-+        '7f97355b8db81c09abfb7f3c5b2515888b679a3e50dd6bd6cef7c73111f4cc0c'
-+      ],
-+      [
-+        '174a53b9c9a285872d39e56e6913cab15d59b1fa512508c022f382de8319497c',
-+        'ccc9dc37abfc9c1657b4155f2c47f9e6646b3a1d8cb9854383da13ac079afa73'
-+      ],
-+      [
-+        '959396981943785c3d3e57edf5018cdbe039e730e4918b3d884fdff09475b7ba',
-+        '2e7e552888c331dd8ba0386a4b9cd6849c653f64c8709385e9b8abf87524f2fd'
-+      ],
-+      [
-+        'd2a63a50ae401e56d645a1153b109a8fcca0a43d561fba2dbb51340c9d82b151',
-+        'e82d86fb6443fcb7565aee58b2948220a70f750af484ca52d4142174dcf89405'
-+      ],
-+      [
-+        '64587e2335471eb890ee7896d7cfdc866bacbdbd3839317b3436f9b45617e073',
-+        'd99fcdd5bf6902e2ae96dd6447c299a185b90a39133aeab358299e5e9faf6589'
-+      ],
-+      [
-+        '8481bde0e4e4d885b3a546d3e549de042f0aa6cea250e7fd358d6c86dd45e458',
-+        '38ee7b8cba5404dd84a25bf39cecb2ca900a79c42b262e556d64b1b59779057e'
-+      ],
-+      [
-+        '13464a57a78102aa62b6979ae817f4637ffcfed3c4b1ce30bcd6303f6caf666b',
-+        '69be159004614580ef7e433453ccb0ca48f300a81d0942e13f495a907f6ecc27'
-+      ],
-+      [
-+        'bc4a9df5b713fe2e9aef430bcc1dc97a0cd9ccede2f28588cada3a0d2d83f366',
-+        'd3a81ca6e785c06383937adf4b798caa6e8a9fbfa547b16d758d666581f33c1'
-+      ],
-+      [
-+        '8c28a97bf8298bc0d23d8c749452a32e694b65e30a9472a3954ab30fe5324caa',
-+        '40a30463a3305193378fedf31f7cc0eb7ae784f0451cb9459e71dc73cbef9482'
-+      ],
-+      [
-+        '8ea9666139527a8c1dd94ce4f071fd23c8b350c5a4bb33748c4ba111faccae0',
-+        '620efabbc8ee2782e24e7c0cfb95c5d735b783be9cf0f8e955af34a30e62b945'
-+      ],
-+      [
-+        'dd3625faef5ba06074669716bbd3788d89bdde815959968092f76cc4eb9a9787',
-+        '7a188fa3520e30d461da2501045731ca941461982883395937f68d00c644a573'
-+      ],
-+      [
-+        'f710d79d9eb962297e4f6232b40e8f7feb2bc63814614d692c12de752408221e',
-+        'ea98e67232d3b3295d3b535532115ccac8612c721851617526ae47a9c77bfc82'
-+      ]
-+    ]
-+  },
-+  naf: {
-+    wnd: 7,
-+    points: [
-+      [
-+        'f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9',
-+        '388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672'
-+      ],
-+      [
-+        '2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4',
-+        'd8ac222636e5e3d6d4dba9dda6c9c426f788271bab0d6840dca87d3aa6ac62d6'
-+      ],
-+      [
-+        '5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc',
-+        '6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da'
-+      ],
-+      [
-+        'acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe',
-+        'cc338921b0a7d9fd64380971763b61e9add888a4375f8e0f05cc262ac64f9c37'
-+      ],
-+      [
-+        '774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb',
-+        'd984a032eb6b5e190243dd56d7b7b365372db1e2dff9d6a8301d74c9c953c61b'
-+      ],
-+      [
-+        'f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8',
-+        'ab0902e8d880a89758212eb65cdaf473a1a06da521fa91f29b5cb52db03ed81'
-+      ],
-+      [
-+        'd7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e',
-+        '581e2872a86c72a683842ec228cc6defea40af2bd896d3a5c504dc9ff6a26b58'
-+      ],
-+      [
-+        'defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34',
-+        '4211ab0694635168e997b0ead2a93daeced1f4a04a95c0f6cfb199f69e56eb77'
-+      ],
-+      [
-+        '2b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6c',
-+        '85e89bc037945d93b343083b5a1c86131a01f60c50269763b570c854e5c09b7a'
-+      ],
-+      [
-+        '352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5',
-+        '321eb4075348f534d59c18259dda3e1f4a1b3b2e71b1039c67bd3d8bcf81998c'
-+      ],
-+      [
-+        '2fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f',
-+        '2de1068295dd865b64569335bd5dd80181d70ecfc882648423ba76b532b7d67'
-+      ],
-+      [
-+        '9248279b09b4d68dab21a9b066edda83263c3d84e09572e269ca0cd7f5453714',
-+        '73016f7bf234aade5d1aa71bdea2b1ff3fc0de2a887912ffe54a32ce97cb3402'
-+      ],
-+      [
-+        'daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729',
-+        'a69dce4a7d6c98e8d4a1aca87ef8d7003f83c230f3afa726ab40e52290be1c55'
-+      ],
-+      [
-+        'c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db',
-+        '2119a460ce326cdc76c45926c982fdac0e106e861edf61c5a039063f0e0e6482'
-+      ],
-+      [
-+        '6a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4',
-+        'e022cf42c2bd4a708b3f5126f16a24ad8b33ba48d0423b6efd5e6348100d8a82'
-+      ],
-+      [
-+        '1697ffa6fd9de627c077e3d2fe541084ce13300b0bec1146f95ae57f0d0bd6a5',
-+        'b9c398f186806f5d27561506e4557433a2cf15009e498ae7adee9d63d01b2396'
-+      ],
-+      [
-+        '605bdb019981718b986d0f07e834cb0d9deb8360ffb7f61df982345ef27a7479',
-+        '2972d2de4f8d20681a78d93ec96fe23c26bfae84fb14db43b01e1e9056b8c49'
-+      ],
-+      [
-+        '62d14dab4150bf497402fdc45a215e10dcb01c354959b10cfe31c7e9d87ff33d',
-+        '80fc06bd8cc5b01098088a1950eed0db01aa132967ab472235f5642483b25eaf'
-+      ],
-+      [
-+        '80c60ad0040f27dade5b4b06c408e56b2c50e9f56b9b8b425e555c2f86308b6f',
-+        '1c38303f1cc5c30f26e66bad7fe72f70a65eed4cbe7024eb1aa01f56430bd57a'
-+      ],
-+      [
-+        '7a9375ad6167ad54aa74c6348cc54d344cc5dc9487d847049d5eabb0fa03c8fb',
-+        'd0e3fa9eca8726909559e0d79269046bdc59ea10c70ce2b02d499ec224dc7f7'
-+      ],
-+      [
-+        'd528ecd9b696b54c907a9ed045447a79bb408ec39b68df504bb51f459bc3ffc9',
-+        'eecf41253136e5f99966f21881fd656ebc4345405c520dbc063465b521409933'
-+      ],
-+      [
-+        '49370a4b5f43412ea25f514e8ecdad05266115e4a7ecb1387231808f8b45963',
-+        '758f3f41afd6ed428b3081b0512fd62a54c3f3afbb5b6764b653052a12949c9a'
-+      ],
-+      [
-+        '77f230936ee88cbbd73df930d64702ef881d811e0e1498e2f1c13eb1fc345d74',
-+        '958ef42a7886b6400a08266e9ba1b37896c95330d97077cbbe8eb3c7671c60d6'
-+      ],
-+      [
-+        'f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530',
-+        'e0dedc9b3b2f8dad4da1f32dec2531df9eb5fbeb0598e4fd1a117dba703a3c37'
-+      ],
-+      [
-+        '463b3d9f662621fb1b4be8fbbe2520125a216cdfc9dae3debcba4850c690d45b',
-+        '5ed430d78c296c3543114306dd8622d7c622e27c970a1de31cb377b01af7307e'
-+      ],
-+      [
-+        'f16f804244e46e2a09232d4aff3b59976b98fac14328a2d1a32496b49998f247',
-+        'cedabd9b82203f7e13d206fcdf4e33d92a6c53c26e5cce26d6579962c4e31df6'
-+      ],
-+      [
-+        'caf754272dc84563b0352b7a14311af55d245315ace27c65369e15f7151d41d1',
-+        'cb474660ef35f5f2a41b643fa5e460575f4fa9b7962232a5c32f908318a04476'
-+      ],
-+      [
-+        '2600ca4b282cb986f85d0f1709979d8b44a09c07cb86d7c124497bc86f082120',
-+        '4119b88753c15bd6a693b03fcddbb45d5ac6be74ab5f0ef44b0be9475a7e4b40'
-+      ],
-+      [
-+        '7635ca72d7e8432c338ec53cd12220bc01c48685e24f7dc8c602a7746998e435',
-+        '91b649609489d613d1d5e590f78e6d74ecfc061d57048bad9e76f302c5b9c61'
-+      ],
-+      [
-+        '754e3239f325570cdbbf4a87deee8a66b7f2b33479d468fbc1a50743bf56cc18',
-+        '673fb86e5bda30fb3cd0ed304ea49a023ee33d0197a695d0c5d98093c536683'
-+      ],
-+      [
-+        'e3e6bd1071a1e96aff57859c82d570f0330800661d1c952f9fe2694691d9b9e8',
-+        '59c9e0bba394e76f40c0aa58379a3cb6a5a2283993e90c4167002af4920e37f5'
-+      ],
-+      [
-+        '186b483d056a033826ae73d88f732985c4ccb1f32ba35f4b4cc47fdcf04aa6eb',
-+        '3b952d32c67cf77e2e17446e204180ab21fb8090895138b4a4a797f86e80888b'
-+      ],
-+      [
-+        'df9d70a6b9876ce544c98561f4be4f725442e6d2b737d9c91a8321724ce0963f',
-+        '55eb2dafd84d6ccd5f862b785dc39d4ab157222720ef9da217b8c45cf2ba2417'
-+      ],
-+      [
-+        '5edd5cc23c51e87a497ca815d5dce0f8ab52554f849ed8995de64c5f34ce7143',
-+        'efae9c8dbc14130661e8cec030c89ad0c13c66c0d17a2905cdc706ab7399a868'
-+      ],
-+      [
-+        '290798c2b6476830da12fe02287e9e777aa3fba1c355b17a722d362f84614fba',
-+        'e38da76dcd440621988d00bcf79af25d5b29c094db2a23146d003afd41943e7a'
-+      ],
-+      [
-+        'af3c423a95d9f5b3054754efa150ac39cd29552fe360257362dfdecef4053b45',
-+        'f98a3fd831eb2b749a93b0e6f35cfb40c8cd5aa667a15581bc2feded498fd9c6'
-+      ],
-+      [
-+        '766dbb24d134e745cccaa28c99bf274906bb66b26dcf98df8d2fed50d884249a',
-+        '744b1152eacbe5e38dcc887980da38b897584a65fa06cedd2c924f97cbac5996'
-+      ],
-+      [
-+        '59dbf46f8c94759ba21277c33784f41645f7b44f6c596a58ce92e666191abe3e',
-+        'c534ad44175fbc300f4ea6ce648309a042ce739a7919798cd85e216c4a307f6e'
-+      ],
-+      [
-+        'f13ada95103c4537305e691e74e9a4a8dd647e711a95e73cb62dc6018cfd87b8',
-+        'e13817b44ee14de663bf4bc808341f326949e21a6a75c2570778419bdaf5733d'
-+      ],
-+      [
-+        '7754b4fa0e8aced06d4167a2c59cca4cda1869c06ebadfb6488550015a88522c',
-+        '30e93e864e669d82224b967c3020b8fa8d1e4e350b6cbcc537a48b57841163a2'
-+      ],
-+      [
-+        '948dcadf5990e048aa3874d46abef9d701858f95de8041d2a6828c99e2262519',
-+        'e491a42537f6e597d5d28a3224b1bc25df9154efbd2ef1d2cbba2cae5347d57e'
-+      ],
-+      [
-+        '7962414450c76c1689c7b48f8202ec37fb224cf5ac0bfa1570328a8a3d7c77ab',
-+        '100b610ec4ffb4760d5c1fc133ef6f6b12507a051f04ac5760afa5b29db83437'
-+      ],
-+      [
-+        '3514087834964b54b15b160644d915485a16977225b8847bb0dd085137ec47ca',
-+        'ef0afbb2056205448e1652c48e8127fc6039e77c15c2378b7e7d15a0de293311'
-+      ],
-+      [
-+        'd3cc30ad6b483e4bc79ce2c9dd8bc54993e947eb8df787b442943d3f7b527eaf',
-+        '8b378a22d827278d89c5e9be8f9508ae3c2ad46290358630afb34db04eede0a4'
-+      ],
-+      [
-+        '1624d84780732860ce1c78fcbfefe08b2b29823db913f6493975ba0ff4847610',
-+        '68651cf9b6da903e0914448c6cd9d4ca896878f5282be4c8cc06e2a404078575'
-+      ],
-+      [
-+        '733ce80da955a8a26902c95633e62a985192474b5af207da6df7b4fd5fc61cd4',
-+        'f5435a2bd2badf7d485a4d8b8db9fcce3e1ef8e0201e4578c54673bc1dc5ea1d'
-+      ],
-+      [
-+        '15d9441254945064cf1a1c33bbd3b49f8966c5092171e699ef258dfab81c045c',
-+        'd56eb30b69463e7234f5137b73b84177434800bacebfc685fc37bbe9efe4070d'
-+      ],
-+      [
-+        'a1d0fcf2ec9de675b612136e5ce70d271c21417c9d2b8aaaac138599d0717940',
-+        'edd77f50bcb5a3cab2e90737309667f2641462a54070f3d519212d39c197a629'
-+      ],
-+      [
-+        'e22fbe15c0af8ccc5780c0735f84dbe9a790badee8245c06c7ca37331cb36980',
-+        'a855babad5cd60c88b430a69f53a1a7a38289154964799be43d06d77d31da06'
-+      ],
-+      [
-+        '311091dd9860e8e20ee13473c1155f5f69635e394704eaa74009452246cfa9b3',
-+        '66db656f87d1f04fffd1f04788c06830871ec5a64feee685bd80f0b1286d8374'
-+      ],
-+      [
-+        '34c1fd04d301be89b31c0442d3e6ac24883928b45a9340781867d4232ec2dbdf',
-+        '9414685e97b1b5954bd46f730174136d57f1ceeb487443dc5321857ba73abee'
-+      ],
-+      [
-+        'f219ea5d6b54701c1c14de5b557eb42a8d13f3abbcd08affcc2a5e6b049b8d63',
-+        '4cb95957e83d40b0f73af4544cccf6b1f4b08d3c07b27fb8d8c2962a400766d1'
-+      ],
-+      [
-+        'd7b8740f74a8fbaab1f683db8f45de26543a5490bca627087236912469a0b448',
-+        'fa77968128d9c92ee1010f337ad4717eff15db5ed3c049b3411e0315eaa4593b'
-+      ],
-+      [
-+        '32d31c222f8f6f0ef86f7c98d3a3335ead5bcd32abdd94289fe4d3091aa824bf',
-+        '5f3032f5892156e39ccd3d7915b9e1da2e6dac9e6f26e961118d14b8462e1661'
-+      ],
-+      [
-+        '7461f371914ab32671045a155d9831ea8793d77cd59592c4340f86cbc18347b5',
-+        '8ec0ba238b96bec0cbdddcae0aa442542eee1ff50c986ea6b39847b3cc092ff6'
-+      ],
-+      [
-+        'ee079adb1df1860074356a25aa38206a6d716b2c3e67453d287698bad7b2b2d6',
-+        '8dc2412aafe3be5c4c5f37e0ecc5f9f6a446989af04c4e25ebaac479ec1c8c1e'
-+      ],
-+      [
-+        '16ec93e447ec83f0467b18302ee620f7e65de331874c9dc72bfd8616ba9da6b5',
-+        '5e4631150e62fb40d0e8c2a7ca5804a39d58186a50e497139626778e25b0674d'
-+      ],
-+      [
-+        'eaa5f980c245f6f038978290afa70b6bd8855897f98b6aa485b96065d537bd99',
-+        'f65f5d3e292c2e0819a528391c994624d784869d7e6ea67fb18041024edc07dc'
-+      ],
-+      [
-+        '78c9407544ac132692ee1910a02439958ae04877151342ea96c4b6b35a49f51',
-+        'f3e0319169eb9b85d5404795539a5e68fa1fbd583c064d2462b675f194a3ddb4'
-+      ],
-+      [
-+        '494f4be219a1a77016dcd838431aea0001cdc8ae7a6fc688726578d9702857a5',
-+        '42242a969283a5f339ba7f075e36ba2af925ce30d767ed6e55f4b031880d562c'
-+      ],
-+      [
-+        'a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5',
-+        '204b5d6f84822c307e4b4a7140737aec23fc63b65b35f86a10026dbd2d864e6b'
-+      ],
-+      [
-+        'c41916365abb2b5d09192f5f2dbeafec208f020f12570a184dbadc3e58595997',
-+        '4f14351d0087efa49d245b328984989d5caf9450f34bfc0ed16e96b58fa9913'
-+      ],
-+      [
-+        '841d6063a586fa475a724604da03bc5b92a2e0d2e0a36acfe4c73a5514742881',
-+        '73867f59c0659e81904f9a1c7543698e62562d6744c169ce7a36de01a8d6154'
-+      ],
-+      [
-+        '5e95bb399a6971d376026947f89bde2f282b33810928be4ded112ac4d70e20d5',
-+        '39f23f366809085beebfc71181313775a99c9aed7d8ba38b161384c746012865'
-+      ],
-+      [
-+        '36e4641a53948fd476c39f8a99fd974e5ec07564b5315d8bf99471bca0ef2f66',
-+        'd2424b1b1abe4eb8164227b085c9aa9456ea13493fd563e06fd51cf5694c78fc'
-+      ],
-+      [
-+        '336581ea7bfbbb290c191a2f507a41cf5643842170e914faeab27c2c579f726',
-+        'ead12168595fe1be99252129b6e56b3391f7ab1410cd1e0ef3dcdcabd2fda224'
-+      ],
-+      [
-+        '8ab89816dadfd6b6a1f2634fcf00ec8403781025ed6890c4849742706bd43ede',
-+        '6fdcef09f2f6d0a044e654aef624136f503d459c3e89845858a47a9129cdd24e'
-+      ],
-+      [
-+        '1e33f1a746c9c5778133344d9299fcaa20b0938e8acff2544bb40284b8c5fb94',
-+        '60660257dd11b3aa9c8ed618d24edff2306d320f1d03010e33a7d2057f3b3b6'
-+      ],
-+      [
-+        '85b7c1dcb3cec1b7ee7f30ded79dd20a0ed1f4cc18cbcfcfa410361fd8f08f31',
-+        '3d98a9cdd026dd43f39048f25a8847f4fcafad1895d7a633c6fed3c35e999511'
-+      ],
-+      [
-+        '29df9fbd8d9e46509275f4b125d6d45d7fbe9a3b878a7af872a2800661ac5f51',
-+        'b4c4fe99c775a606e2d8862179139ffda61dc861c019e55cd2876eb2a27d84b'
-+      ],
-+      [
-+        'a0b1cae06b0a847a3fea6e671aaf8adfdfe58ca2f768105c8082b2e449fce252',
-+        'ae434102edde0958ec4b19d917a6a28e6b72da1834aff0e650f049503a296cf2'
-+      ],
-+      [
-+        '4e8ceafb9b3e9a136dc7ff67e840295b499dfb3b2133e4ba113f2e4c0e121e5',
-+        'cf2174118c8b6d7a4b48f6d534ce5c79422c086a63460502b827ce62a326683c'
-+      ],
-+      [
-+        'd24a44e047e19b6f5afb81c7ca2f69080a5076689a010919f42725c2b789a33b',
-+        '6fb8d5591b466f8fc63db50f1c0f1c69013f996887b8244d2cdec417afea8fa3'
-+      ],
-+      [
-+        'ea01606a7a6c9cdd249fdfcfacb99584001edd28abbab77b5104e98e8e3b35d4',
-+        '322af4908c7312b0cfbfe369f7a7b3cdb7d4494bc2823700cfd652188a3ea98d'
-+      ],
-+      [
-+        'af8addbf2b661c8a6c6328655eb96651252007d8c5ea31be4ad196de8ce2131f',
-+        '6749e67c029b85f52a034eafd096836b2520818680e26ac8f3dfbcdb71749700'
-+      ],
-+      [
-+        'e3ae1974566ca06cc516d47e0fb165a674a3dabcfca15e722f0e3450f45889',
-+        '2aeabe7e4531510116217f07bf4d07300de97e4874f81f533420a72eeb0bd6a4'
-+      ],
-+      [
-+        '591ee355313d99721cf6993ffed1e3e301993ff3ed258802075ea8ced397e246',
-+        'b0ea558a113c30bea60fc4775460c7901ff0b053d25ca2bdeee98f1a4be5d196'
-+      ],
-+      [
-+        '11396d55fda54c49f19aa97318d8da61fa8584e47b084945077cf03255b52984',
-+        '998c74a8cd45ac01289d5833a7beb4744ff536b01b257be4c5767bea93ea57a4'
-+      ],
-+      [
-+        '3c5d2a1ba39c5a1790000738c9e0c40b8dcdfd5468754b6405540157e017aa7a',
-+        'b2284279995a34e2f9d4de7396fc18b80f9b8b9fdd270f6661f79ca4c81bd257'
-+      ],
-+      [
-+        'cc8704b8a60a0defa3a99a7299f2e9c3fbc395afb04ac078425ef8a1793cc030',
-+        'bdd46039feed17881d1e0862db347f8cf395b74fc4bcdc4e940b74e3ac1f1b13'
-+      ],
-+      [
-+        'c533e4f7ea8555aacd9777ac5cad29b97dd4defccc53ee7ea204119b2889b197',
-+        '6f0a256bc5efdf429a2fb6242f1a43a2d9b925bb4a4b3a26bb8e0f45eb596096'
-+      ],
-+      [
-+        'c14f8f2ccb27d6f109f6d08d03cc96a69ba8c34eec07bbcf566d48e33da6593',
-+        'c359d6923bb398f7fd4473e16fe1c28475b740dd098075e6c0e8649113dc3a38'
-+      ],
-+      [
-+        'a6cbc3046bc6a450bac24789fa17115a4c9739ed75f8f21ce441f72e0b90e6ef',
-+        '21ae7f4680e889bb130619e2c0f95a360ceb573c70603139862afd617fa9b9f'
-+      ],
-+      [
-+        '347d6d9a02c48927ebfb86c1359b1caf130a3c0267d11ce6344b39f99d43cc38',
-+        '60ea7f61a353524d1c987f6ecec92f086d565ab687870cb12689ff1e31c74448'
-+      ],
-+      [
-+        'da6545d2181db8d983f7dcb375ef5866d47c67b1bf31c8cf855ef7437b72656a',
-+        '49b96715ab6878a79e78f07ce5680c5d6673051b4935bd897fea824b77dc208a'
-+      ],
-+      [
-+        'c40747cc9d012cb1a13b8148309c6de7ec25d6945d657146b9d5994b8feb1111',
-+        '5ca560753be2a12fc6de6caf2cb489565db936156b9514e1bb5e83037e0fa2d4'
-+      ],
-+      [
-+        '4e42c8ec82c99798ccf3a610be870e78338c7f713348bd34c8203ef4037f3502',
-+        '7571d74ee5e0fb92a7a8b33a07783341a5492144cc54bcc40a94473693606437'
-+      ],
-+      [
-+        '3775ab7089bc6af823aba2e1af70b236d251cadb0c86743287522a1b3b0dedea',
-+        'be52d107bcfa09d8bcb9736a828cfa7fac8db17bf7a76a2c42ad961409018cf7'
-+      ],
-+      [
-+        'cee31cbf7e34ec379d94fb814d3d775ad954595d1314ba8846959e3e82f74e26',
-+        '8fd64a14c06b589c26b947ae2bcf6bfa0149ef0be14ed4d80f448a01c43b1c6d'
-+      ],
-+      [
-+        'b4f9eaea09b6917619f6ea6a4eb5464efddb58fd45b1ebefcdc1a01d08b47986',
-+        '39e5c9925b5a54b07433a4f18c61726f8bb131c012ca542eb24a8ac07200682a'
-+      ],
-+      [
-+        'd4263dfc3d2df923a0179a48966d30ce84e2515afc3dccc1b77907792ebcc60e',
-+        '62dfaf07a0f78feb30e30d6295853ce189e127760ad6cf7fae164e122a208d54'
-+      ],
-+      [
-+        '48457524820fa65a4f8d35eb6930857c0032acc0a4a2de422233eeda897612c4',
-+        '25a748ab367979d98733c38a1fa1c2e7dc6cc07db2d60a9ae7a76aaa49bd0f77'
-+      ],
-+      [
-+        'dfeeef1881101f2cb11644f3a2afdfc2045e19919152923f367a1767c11cceda',
-+        'ecfb7056cf1de042f9420bab396793c0c390bde74b4bbdff16a83ae09a9a7517'
-+      ],
-+      [
-+        '6d7ef6b17543f8373c573f44e1f389835d89bcbc6062ced36c82df83b8fae859',
-+        'cd450ec335438986dfefa10c57fea9bcc521a0959b2d80bbf74b190dca712d10'
-+      ],
-+      [
-+        'e75605d59102a5a2684500d3b991f2e3f3c88b93225547035af25af66e04541f',
-+        'f5c54754a8f71ee540b9b48728473e314f729ac5308b06938360990e2bfad125'
-+      ],
-+      [
-+        'eb98660f4c4dfaa06a2be453d5020bc99a0c2e60abe388457dd43fefb1ed620c',
-+        '6cb9a8876d9cb8520609af3add26cd20a0a7cd8a9411131ce85f44100099223e'
-+      ],
-+      [
-+        '13e87b027d8514d35939f2e6892b19922154596941888336dc3563e3b8dba942',
-+        'fef5a3c68059a6dec5d624114bf1e91aac2b9da568d6abeb2570d55646b8adf1'
-+      ],
-+      [
-+        'ee163026e9fd6fe017c38f06a5be6fc125424b371ce2708e7bf4491691e5764a',
-+        '1acb250f255dd61c43d94ccc670d0f58f49ae3fa15b96623e5430da0ad6c62b2'
-+      ],
-+      [
-+        'b268f5ef9ad51e4d78de3a750c2dc89b1e626d43505867999932e5db33af3d80',
-+        '5f310d4b3c99b9ebb19f77d41c1dee018cf0d34fd4191614003e945a1216e423'
-+      ],
-+      [
-+        'ff07f3118a9df035e9fad85eb6c7bfe42b02f01ca99ceea3bf7ffdba93c4750d',
-+        '438136d603e858a3a5c440c38eccbaddc1d2942114e2eddd4740d098ced1f0d8'
-+      ],
-+      [
-+        '8d8b9855c7c052a34146fd20ffb658bea4b9f69e0d825ebec16e8c3ce2b526a1',
-+        'cdb559eedc2d79f926baf44fb84ea4d44bcf50fee51d7ceb30e2e7f463036758'
-+      ],
-+      [
-+        '52db0b5384dfbf05bfa9d472d7ae26dfe4b851ceca91b1eba54263180da32b63',
-+        'c3b997d050ee5d423ebaf66a6db9f57b3180c902875679de924b69d84a7b375'
-+      ],
-+      [
-+        'e62f9490d3d51da6395efd24e80919cc7d0f29c3f3fa48c6fff543becbd43352',
-+        '6d89ad7ba4876b0b22c2ca280c682862f342c8591f1daf5170e07bfd9ccafa7d'
-+      ],
-+      [
-+        '7f30ea2476b399b4957509c88f77d0191afa2ff5cb7b14fd6d8e7d65aaab1193',
-+        'ca5ef7d4b231c94c3b15389a5f6311e9daff7bb67b103e9880ef4bff637acaec'
-+      ],
-+      [
-+        '5098ff1e1d9f14fb46a210fada6c903fef0fb7b4a1dd1d9ac60a0361800b7a00',
-+        '9731141d81fc8f8084d37c6e7542006b3ee1b40d60dfe5362a5b132fd17ddc0'
-+      ],
-+      [
-+        '32b78c7de9ee512a72895be6b9cbefa6e2f3c4ccce445c96b9f2c81e2778ad58',
-+        'ee1849f513df71e32efc3896ee28260c73bb80547ae2275ba497237794c8753c'
-+      ],
-+      [
-+        'e2cb74fddc8e9fbcd076eef2a7c72b0ce37d50f08269dfc074b581550547a4f7',
-+        'd3aa2ed71c9dd2247a62df062736eb0baddea9e36122d2be8641abcb005cc4a4'
-+      ],
-+      [
-+        '8438447566d4d7bedadc299496ab357426009a35f235cb141be0d99cd10ae3a8',
-+        'c4e1020916980a4da5d01ac5e6ad330734ef0d7906631c4f2390426b2edd791f'
-+      ],
-+      [
-+        '4162d488b89402039b584c6fc6c308870587d9c46f660b878ab65c82c711d67e',
-+        '67163e903236289f776f22c25fb8a3afc1732f2b84b4e95dbda47ae5a0852649'
-+      ],
-+      [
-+        '3fad3fa84caf0f34f0f89bfd2dcf54fc175d767aec3e50684f3ba4a4bf5f683d',
-+        'cd1bc7cb6cc407bb2f0ca647c718a730cf71872e7d0d2a53fa20efcdfe61826'
-+      ],
-+      [
-+        '674f2600a3007a00568c1a7ce05d0816c1fb84bf1370798f1c69532faeb1a86b',
-+        '299d21f9413f33b3edf43b257004580b70db57da0b182259e09eecc69e0d38a5'
-+      ],
-+      [
-+        'd32f4da54ade74abb81b815ad1fb3b263d82d6c692714bcff87d29bd5ee9f08f',
-+        'f9429e738b8e53b968e99016c059707782e14f4535359d582fc416910b3eea87'
-+      ],
-+      [
-+        '30e4e670435385556e593657135845d36fbb6931f72b08cb1ed954f1e3ce3ff6',
-+        '462f9bce619898638499350113bbc9b10a878d35da70740dc695a559eb88db7b'
-+      ],
-+      [
-+        'be2062003c51cc3004682904330e4dee7f3dcd10b01e580bf1971b04d4cad297',
-+        '62188bc49d61e5428573d48a74e1c655b1c61090905682a0d5558ed72dccb9bc'
-+      ],
-+      [
-+        '93144423ace3451ed29e0fb9ac2af211cb6e84a601df5993c419859fff5df04a',
-+        '7c10dfb164c3425f5c71a3f9d7992038f1065224f72bb9d1d902a6d13037b47c'
-+      ],
-+      [
-+        'b015f8044f5fcbdcf21ca26d6c34fb8197829205c7b7d2a7cb66418c157b112c',
-+        'ab8c1e086d04e813744a655b2df8d5f83b3cdc6faa3088c1d3aea1454e3a1d5f'
-+      ],
-+      [
-+        'd5e9e1da649d97d89e4868117a465a3a4f8a18de57a140d36b3f2af341a21b52',
-+        '4cb04437f391ed73111a13cc1d4dd0db1693465c2240480d8955e8592f27447a'
-+      ],
-+      [
-+        'd3ae41047dd7ca065dbf8ed77b992439983005cd72e16d6f996a5316d36966bb',
-+        'bd1aeb21ad22ebb22a10f0303417c6d964f8cdd7df0aca614b10dc14d125ac46'
-+      ],
-+      [
-+        '463e2763d885f958fc66cdd22800f0a487197d0a82e377b49f80af87c897b065',
-+        'bfefacdb0e5d0fd7df3a311a94de062b26b80c61fbc97508b79992671ef7ca7f'
-+      ],
-+      [
-+        '7985fdfd127c0567c6f53ec1bb63ec3158e597c40bfe747c83cddfc910641917',
-+        '603c12daf3d9862ef2b25fe1de289aed24ed291e0ec6708703a5bd567f32ed03'
-+      ],
-+      [
-+        '74a1ad6b5f76e39db2dd249410eac7f99e74c59cb83d2d0ed5ff1543da7703e9',
-+        'cc6157ef18c9c63cd6193d83631bbea0093e0968942e8c33d5737fd790e0db08'
-+      ],
-+      [
-+        '30682a50703375f602d416664ba19b7fc9bab42c72747463a71d0896b22f6da3',
-+        '553e04f6b018b4fa6c8f39e7f311d3176290d0e0f19ca73f17714d9977a22ff8'
-+      ],
-+      [
-+        '9e2158f0d7c0d5f26c3791efefa79597654e7a2b2464f52b1ee6c1347769ef57',
-+        '712fcdd1b9053f09003a3481fa7762e9ffd7c8ef35a38509e2fbf2629008373'
-+      ],
-+      [
-+        '176e26989a43c9cfeba4029c202538c28172e566e3c4fce7322857f3be327d66',
-+        'ed8cc9d04b29eb877d270b4878dc43c19aefd31f4eee09ee7b47834c1fa4b1c3'
-+      ],
-+      [
-+        '75d46efea3771e6e68abb89a13ad747ecf1892393dfc4f1b7004788c50374da8',
-+        '9852390a99507679fd0b86fd2b39a868d7efc22151346e1a3ca4726586a6bed8'
-+      ],
-+      [
-+        '809a20c67d64900ffb698c4c825f6d5f2310fb0451c869345b7319f645605721',
-+        '9e994980d9917e22b76b061927fa04143d096ccc54963e6a5ebfa5f3f8e286c1'
-+      ],
-+      [
-+        '1b38903a43f7f114ed4500b4eac7083fdefece1cf29c63528d563446f972c180',
-+        '4036edc931a60ae889353f77fd53de4a2708b26b6f5da72ad3394119daf408f9'
-+      ]
-+    ]
-+  }
-+};
-+
-+},{}],17:[function(require,module,exports){
-+'use strict';
-+
-+var utils = exports;
-+var BN = require('bn.js');
-+
-+utils.assert = function assert(val, msg) {
-+  if (!val)
-+    throw new Error(msg || 'Assertion failed');
-+};
-+
-+function toArray(msg, enc) {
-+  if (Array.isArray(msg))
-+    return msg.slice();
-+  if (!msg)
-+    return [];
-+  var res = [];
-+  if (typeof msg !== 'string') {
-+    for (var i = 0; i < msg.length; i++)
-+      res[i] = msg[i] | 0;
-+    return res;
-+  }
-+  if (!enc) {
-+    for (var i = 0; i < msg.length; i++) {
-+      var c = msg.charCodeAt(i);
-+      var hi = c >> 8;
-+      var lo = c & 0xff;
-+      if (hi)
-+        res.push(hi, lo);
-+      else
-+        res.push(lo);
-+    }
-+  } else if (enc === 'hex') {
-+    msg = msg.replace(/[^a-z0-9]+/ig, '');
-+    if (msg.length % 2 !== 0)
-+      msg = '0' + msg;
-+    for (var i = 0; i < msg.length; i += 2)
-+      res.push(parseInt(msg[i] + msg[i + 1], 16));
-+  }
-+  return res;
-+}
-+utils.toArray = toArray;
-+
-+function zero2(word) {
-+  if (word.length === 1)
-+    return '0' + word;
-+  else
-+    return word;
-+}
-+utils.zero2 = zero2;
-+
-+function toHex(msg) {
-+  var res = '';
-+  for (var i = 0; i < msg.length; i++)
-+    res += zero2(msg[i].toString(16));
-+  return res;
-+}
-+utils.toHex = toHex;
-+
-+utils.encode = function encode(arr, enc) {
-+  if (enc === 'hex')
-+    return toHex(arr);
-+  else
-+    return arr;
-+};
-+
-+// Represent num in a w-NAF form
-+function getNAF(num, w) {
-+  var naf = [];
-+  var ws = 1 << (w + 1);
-+  var k = num.clone();
-+  while (k.cmpn(1) >= 0) {
-+    var z;
-+    if (k.isOdd()) {
-+      var mod = k.andln(ws - 1);
-+      if (mod > (ws >> 1) - 1)
-+        z = (ws >> 1) - mod;
-+      else
-+        z = mod;
-+      k.isubn(z);
-+    } else {
-+      z = 0;
-+    }
-+    naf.push(z);
-+
-+    // Optimization, shift by word if possible
-+    var shift = (k.cmpn(0) !== 0 && k.andln(ws - 1) === 0) ? (w + 1) : 1;
-+    for (var i = 1; i < shift; i++)
-+      naf.push(0);
-+    k.iushrn(shift);
-+  }
-+
-+  return naf;
-+}
-+utils.getNAF = getNAF;
-+
-+// Represent k1, k2 in a Joint Sparse Form
-+function getJSF(k1, k2) {
-+  var jsf = [
-+    [],
-+    []
-+  ];
-+
-+  k1 = k1.clone();
-+  k2 = k2.clone();
-+  var d1 = 0;
-+  var d2 = 0;
-+  while (k1.cmpn(-d1) > 0 || k2.cmpn(-d2) > 0) {
-+
-+    // First phase
-+    var m14 = (k1.andln(3) + d1) & 3;
-+    var m24 = (k2.andln(3) + d2) & 3;
-+    if (m14 === 3)
-+      m14 = -1;
-+    if (m24 === 3)
-+      m24 = -1;
-+    var u1;
-+    if ((m14 & 1) === 0) {
-+      u1 = 0;
-+    } else {
-+      var m8 = (k1.andln(7) + d1) & 7;
-+      if ((m8 === 3 || m8 === 5) && m24 === 2)
-+        u1 = -m14;
-+      else
-+        u1 = m14;
-+    }
-+    jsf[0].push(u1);
-+
-+    var u2;
-+    if ((m24 & 1) === 0) {
-+      u2 = 0;
-+    } else {
-+      var m8 = (k2.andln(7) + d2) & 7;
-+      if ((m8 === 3 || m8 === 5) && m14 === 2)
-+        u2 = -m24;
-+      else
-+        u2 = m24;
-+    }
-+    jsf[1].push(u2);
-+
-+    // Second phase
-+    if (2 * d1 === u1 + 1)
-+      d1 = 1 - d1;
-+    if (2 * d2 === u2 + 1)
-+      d2 = 1 - d2;
-+    k1.iushrn(1);
-+    k2.iushrn(1);
-+  }
-+
-+  return jsf;
-+}
-+utils.getJSF = getJSF;
-+
-+function cachedProperty(obj, name, computer) {
-+  var key = '_' + name;
-+  obj.prototype[name] = function cachedProperty() {
-+    return this[key] !== undefined ? this[key] :
-+           this[key] = computer.call(this);
-+  };
-+}
-+utils.cachedProperty = cachedProperty;
-+
-+function parseBytes(bytes) {
-+  return typeof bytes === 'string' ? utils.toArray(bytes, 'hex') :
-+                                     bytes;
-+}
-+utils.parseBytes = parseBytes;
-+
-+function intFromLE(bytes) {
-+  return new BN(bytes, 'hex', 'le');
-+}
-+utils.intFromLE = intFromLE;
-+
-+
-+},{"bn.js":1}],18:[function(require,module,exports){
-+var r;
-+
-+module.exports = function rand(len) {
-+  if (!r)
-+    r = new Rand(null);
-+
-+  return r.generate(len);
-+};
-+
-+function Rand(rand) {
-+  this.rand = rand;
-+}
-+module.exports.Rand = Rand;
-+
-+Rand.prototype.generate = function generate(len) {
-+  return this._rand(len);
-+};
-+
-+if (typeof window === 'object') {
-+  if (window.crypto && window.crypto.getRandomValues) {
-+    // Modern browsers
-+    Rand.prototype._rand = function _rand(n) {
-+      var arr = new Uint8Array(n);
-+      window.crypto.getRandomValues(arr);
-+      return arr;
-+    };
-+  } else if (window.msCrypto && window.msCrypto.getRandomValues) {
-+    // IE
-+    Rand.prototype._rand = function _rand(n) {
-+      var arr = new Uint8Array(n);
-+      window.msCrypto.getRandomValues(arr);
-+      return arr;
-+    };
-+  } else {
-+    // Old junk
-+    Rand.prototype._rand = function() {
-+      throw new Error('Not implemented yet');
-+    };
-+  }
-+} else {
-+  // Node.js or Web worker
-+  try {
-+    var crypto = require('cry' + 'pto');
-+
-+    Rand.prototype._rand = function _rand(n) {
-+      return crypto.randomBytes(n);
-+    };
-+  } catch (e) {
-+    // Emulate crypto API using randy
-+    Rand.prototype._rand = function _rand(n) {
-+      var res = new Uint8Array(n);
-+      for (var i = 0; i < res.length; i++)
-+        res[i] = this.rand.getByte();
-+      return res;
-+    };
-+  }
-+}
-+
-+},{}],19:[function(require,module,exports){
-+var hash = exports;
-+
-+hash.utils = require('./hash/utils');
-+hash.common = require('./hash/common');
-+hash.sha = require('./hash/sha');
-+hash.ripemd = require('./hash/ripemd');
-+hash.hmac = require('./hash/hmac');
-+
-+// Proxy hash functions to the main object
-+hash.sha1 = hash.sha.sha1;
-+hash.sha256 = hash.sha.sha256;
-+hash.sha224 = hash.sha.sha224;
-+hash.sha384 = hash.sha.sha384;
-+hash.sha512 = hash.sha.sha512;
-+hash.ripemd160 = hash.ripemd.ripemd160;
-+
-+},{"./hash/common":20,"./hash/hmac":21,"./hash/ripemd":22,"./hash/sha":23,"./hash/utils":24}],20:[function(require,module,exports){
-+var hash = require('../hash');
-+var utils = hash.utils;
-+var assert = utils.assert;
-+
-+function BlockHash() {
-+  this.pending = null;
-+  this.pendingTotal = 0;
-+  this.blockSize = this.constructor.blockSize;
-+  this.outSize = this.constructor.outSize;
-+  this.hmacStrength = this.constructor.hmacStrength;
-+  this.padLength = this.constructor.padLength / 8;
-+  this.endian = 'big';
-+
-+  this._delta8 = this.blockSize / 8;
-+  this._delta32 = this.blockSize / 32;
-+}
-+exports.BlockHash = BlockHash;
-+
-+BlockHash.prototype.update = function update(msg, enc) {
-+  // Convert message to array, pad it, and join into 32bit blocks
-+  msg = utils.toArray(msg, enc);
-+  if (!this.pending)
-+    this.pending = msg;
-+  else
-+    this.pending = this.pending.concat(msg);
-+  this.pendingTotal += msg.length;
-+
-+  // Enough data, try updating
-+  if (this.pending.length >= this._delta8) {
-+    msg = this.pending;
-+
-+    // Process pending data in blocks
-+    var r = msg.length % this._delta8;
-+    this.pending = msg.slice(msg.length - r, msg.length);
-+    if (this.pending.length === 0)
-+      this.pending = null;
-+
-+    msg = utils.join32(msg, 0, msg.length - r, this.endian);
-+    for (var i = 0; i < msg.length; i += this._delta32)
-+      this._update(msg, i, i + this._delta32);
-+  }
-+
-+  return this;
-+};
-+
-+BlockHash.prototype.digest = function digest(enc) {
-+  this.update(this._pad());
-+  assert(this.pending === null);
-+
-+  return this._digest(enc);
-+};
-+
-+BlockHash.prototype._pad = function pad() {
-+  var len = this.pendingTotal;
-+  var bytes = this._delta8;
-+  var k = bytes - ((len + this.padLength) % bytes);
-+  var res = new Array(k + this.padLength);
-+  res[0] = 0x80;
-+  for (var i = 1; i < k; i++)
-+    res[i] = 0;
-+
-+  // Append length
-+  len <<= 3;
-+  if (this.endian === 'big') {
-+    for (var t = 8; t < this.padLength; t++)
-+      res[i++] = 0;
-+
-+    res[i++] = 0;
-+    res[i++] = 0;
-+    res[i++] = 0;
-+    res[i++] = 0;
-+    res[i++] = (len >>> 24) & 0xff;
-+    res[i++] = (len >>> 16) & 0xff;
-+    res[i++] = (len >>> 8) & 0xff;
-+    res[i++] = len & 0xff;
-+  } else {
-+    res[i++] = len & 0xff;
-+    res[i++] = (len >>> 8) & 0xff;
-+    res[i++] = (len >>> 16) & 0xff;
-+    res[i++] = (len >>> 24) & 0xff;
-+    res[i++] = 0;
-+    res[i++] = 0;
-+    res[i++] = 0;
-+    res[i++] = 0;
-+
-+    for (var t = 8; t < this.padLength; t++)
-+      res[i++] = 0;
-+  }
-+
-+  return res;
-+};
-+
-+},{"../hash":19}],21:[function(require,module,exports){
-+var hmac = exports;
-+
-+var hash = require('../hash');
-+var utils = hash.utils;
-+var assert = utils.assert;
-+
-+function Hmac(hash, key, enc) {
-+  if (!(this instanceof Hmac))
-+    return new Hmac(hash, key, enc);
-+  this.Hash = hash;
-+  this.blockSize = hash.blockSize / 8;
-+  this.outSize = hash.outSize / 8;
-+  this.inner = null;
-+  this.outer = null;
-+
-+  this._init(utils.toArray(key, enc));
-+}
-+module.exports = Hmac;
-+
-+Hmac.prototype._init = function init(key) {
-+  // Shorten key, if needed
-+  if (key.length > this.blockSize)
-+    key = new this.Hash().update(key).digest();
-+  assert(key.length <= this.blockSize);
-+
-+  // Add padding to key
-+  for (var i = key.length; i < this.blockSize; i++)
-+    key.push(0);
-+
-+  for (var i = 0; i < key.length; i++)
-+    key[i] ^= 0x36;
-+  this.inner = new this.Hash().update(key);
-+
-+  // 0x36 ^ 0x5c = 0x6a
-+  for (var i = 0; i < key.length; i++)
-+    key[i] ^= 0x6a;
-+  this.outer = new this.Hash().update(key);
-+};
-+
-+Hmac.prototype.update = function update(msg, enc) {
-+  this.inner.update(msg, enc);
-+  return this;
-+};
-+
-+Hmac.prototype.digest = function digest(enc) {
-+  this.outer.update(this.inner.digest());
-+  return this.outer.digest(enc);
-+};
-+
-+},{"../hash":19}],22:[function(require,module,exports){
-+var hash = require('../hash');
-+var utils = hash.utils;
-+
-+var rotl32 = utils.rotl32;
-+var sum32 = utils.sum32;
-+var sum32_3 = utils.sum32_3;
-+var sum32_4 = utils.sum32_4;
-+var BlockHash = hash.common.BlockHash;
-+
-+function RIPEMD160() {
-+  if (!(this instanceof RIPEMD160))
-+    return new RIPEMD160();
-+
-+  BlockHash.call(this);
-+
-+  this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ];
-+  this.endian = 'little';
-+}
-+utils.inherits(RIPEMD160, BlockHash);
-+exports.ripemd160 = RIPEMD160;
-+
-+RIPEMD160.blockSize = 512;
-+RIPEMD160.outSize = 160;
-+RIPEMD160.hmacStrength = 192;
-+RIPEMD160.padLength = 64;
-+
-+RIPEMD160.prototype._update = function update(msg, start) {
-+  var A = this.h[0];
-+  var B = this.h[1];
-+  var C = this.h[2];
-+  var D = this.h[3];
-+  var E = this.h[4];
-+  var Ah = A;
-+  var Bh = B;
-+  var Ch = C;
-+  var Dh = D;
-+  var Eh = E;
-+  for (var j = 0; j < 80; j++) {
-+    var T = sum32(
-+      rotl32(
-+        sum32_4(A, f(j, B, C, D), msg[r[j] + start], K(j)),
-+        s[j]),
-+      E);
-+    A = E;
-+    E = D;
-+    D = rotl32(C, 10);
-+    C = B;
-+    B = T;
-+    T = sum32(
-+      rotl32(
-+        sum32_4(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)),
-+        sh[j]),
-+      Eh);
-+    Ah = Eh;
-+    Eh = Dh;
-+    Dh = rotl32(Ch, 10);
-+    Ch = Bh;
-+    Bh = T;
-+  }
-+  T = sum32_3(this.h[1], C, Dh);
-+  this.h[1] = sum32_3(this.h[2], D, Eh);
-+  this.h[2] = sum32_3(this.h[3], E, Ah);
-+  this.h[3] = sum32_3(this.h[4], A, Bh);
-+  this.h[4] = sum32_3(this.h[0], B, Ch);
-+  this.h[0] = T;
-+};
-+
-+RIPEMD160.prototype._digest = function digest(enc) {
-+  if (enc === 'hex')
-+    return utils.toHex32(this.h, 'little');
-+  else
-+    return utils.split32(this.h, 'little');
-+};
-+
-+function f(j, x, y, z) {
-+  if (j <= 15)
-+    return x ^ y ^ z;
-+  else if (j <= 31)
-+    return (x & y) | ((~x) & z);
-+  else if (j <= 47)
-+    return (x | (~y)) ^ z;
-+  else if (j <= 63)
-+    return (x & z) | (y & (~z));
-+  else
-+    return x ^ (y | (~z));
-+}
-+
-+function K(j) {
-+  if (j <= 15)
-+    return 0x00000000;
-+  else if (j <= 31)
-+    return 0x5a827999;
-+  else if (j <= 47)
-+    return 0x6ed9eba1;
-+  else if (j <= 63)
-+    return 0x8f1bbcdc;
-+  else
-+    return 0xa953fd4e;
-+}
-+
-+function Kh(j) {
-+  if (j <= 15)
-+    return 0x50a28be6;
-+  else if (j <= 31)
-+    return 0x5c4dd124;
-+  else if (j <= 47)
-+    return 0x6d703ef3;
-+  else if (j <= 63)
-+    return 0x7a6d76e9;
-+  else
-+    return 0x00000000;
-+}
-+
-+var r = [
-+  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
-+  7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
-+  3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
-+  1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
-+  4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
-+];
-+
-+var rh = [
-+  5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
-+  6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
-+  15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
-+  8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
-+  12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
-+];
-+
-+var s = [
-+  11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
-+  7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
-+  11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
-+  11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
-+  9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
-+];
-+
-+var sh = [
-+  8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
-+  9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
-+  9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
-+  15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
-+  8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
-+];
-+
-+},{"../hash":19}],23:[function(require,module,exports){
-+var hash = require('../hash');
-+var utils = hash.utils;
-+var assert = utils.assert;
-+
-+var rotr32 = utils.rotr32;
-+var rotl32 = utils.rotl32;
-+var sum32 = utils.sum32;
-+var sum32_4 = utils.sum32_4;
-+var sum32_5 = utils.sum32_5;
-+var rotr64_hi = utils.rotr64_hi;
-+var rotr64_lo = utils.rotr64_lo;
-+var shr64_hi = utils.shr64_hi;
-+var shr64_lo = utils.shr64_lo;
-+var sum64 = utils.sum64;
-+var sum64_hi = utils.sum64_hi;
-+var sum64_lo = utils.sum64_lo;
-+var sum64_4_hi = utils.sum64_4_hi;
-+var sum64_4_lo = utils.sum64_4_lo;
-+var sum64_5_hi = utils.sum64_5_hi;
-+var sum64_5_lo = utils.sum64_5_lo;
-+var BlockHash = hash.common.BlockHash;
-+
-+var sha256_K = [
-+  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
-+  0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
-+  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
-+  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
-+  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
-+  0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
-+  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
-+  0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
-+  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
-+  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
-+  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
-+  0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
-+  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
-+  0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
-+  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
-+  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
-+];
-+
-+var sha512_K = [
-+  0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,
-+  0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,
-+  0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,
-+  0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,
-+  0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,
-+  0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,
-+  0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,
-+  0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,
-+  0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,
-+  0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,
-+  0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,
-+  0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,
-+  0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,
-+  0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,
-+  0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,
-+  0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,
-+  0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,
-+  0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,
-+  0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,
-+  0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,
-+  0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,
-+  0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,
-+  0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,
-+  0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,
-+  0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,
-+  0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,
-+  0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,
-+  0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,
-+  0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,
-+  0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,
-+  0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,
-+  0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,
-+  0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,
-+  0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,
-+  0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,
-+  0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,
-+  0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,
-+  0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,
-+  0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,
-+  0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817
-+];
-+
-+var sha1_K = [
-+  0x5A827999, 0x6ED9EBA1,
-+  0x8F1BBCDC, 0xCA62C1D6
-+];
-+
-+function SHA256() {
-+  if (!(this instanceof SHA256))
-+    return new SHA256();
-+
-+  BlockHash.call(this);
-+  this.h = [ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
-+             0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ];
-+  this.k = sha256_K;
-+  this.W = new Array(64);
-+}
-+utils.inherits(SHA256, BlockHash);
-+exports.sha256 = SHA256;
-+
-+SHA256.blockSize = 512;
-+SHA256.outSize = 256;
-+SHA256.hmacStrength = 192;
-+SHA256.padLength = 64;
-+
-+SHA256.prototype._update = function _update(msg, start) {
-+  var W = this.W;
-+
-+  for (var i = 0; i < 16; i++)
-+    W[i] = msg[start + i];
-+  for (; i < W.length; i++)
-+    W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]);
-+
-+  var a = this.h[0];
-+  var b = this.h[1];
-+  var c = this.h[2];
-+  var d = this.h[3];
-+  var e = this.h[4];
-+  var f = this.h[5];
-+  var g = this.h[6];
-+  var h = this.h[7];
-+
-+  assert(this.k.length === W.length);
-+  for (var i = 0; i < W.length; i++) {
-+    var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]);
-+    var T2 = sum32(s0_256(a), maj32(a, b, c));
-+    h = g;
-+    g = f;
-+    f = e;
-+    e = sum32(d, T1);
-+    d = c;
-+    c = b;
-+    b = a;
-+    a = sum32(T1, T2);
-+  }
-+
-+  this.h[0] = sum32(this.h[0], a);
-+  this.h[1] = sum32(this.h[1], b);
-+  this.h[2] = sum32(this.h[2], c);
-+  this.h[3] = sum32(this.h[3], d);
-+  this.h[4] = sum32(this.h[4], e);
-+  this.h[5] = sum32(this.h[5], f);
-+  this.h[6] = sum32(this.h[6], g);
-+  this.h[7] = sum32(this.h[7], h);
-+};
-+
-+SHA256.prototype._digest = function digest(enc) {
-+  if (enc === 'hex')
-+    return utils.toHex32(this.h, 'big');
-+  else
-+    return utils.split32(this.h, 'big');
-+};
-+
-+function SHA224() {
-+  if (!(this instanceof SHA224))
-+    return new SHA224();
-+
-+  SHA256.call(this);
-+  this.h = [ 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
-+             0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ];
-+}
-+utils.inherits(SHA224, SHA256);
-+exports.sha224 = SHA224;
-+
-+SHA224.blockSize = 512;
-+SHA224.outSize = 224;
-+SHA224.hmacStrength = 192;
-+SHA224.padLength = 64;
-+
-+SHA224.prototype._digest = function digest(enc) {
-+  // Just truncate output
-+  if (enc === 'hex')
-+    return utils.toHex32(this.h.slice(0, 7), 'big');
-+  else
-+    return utils.split32(this.h.slice(0, 7), 'big');
-+};
-+
-+function SHA512() {
-+  if (!(this instanceof SHA512))
-+    return new SHA512();
-+
-+  BlockHash.call(this);
-+  this.h = [ 0x6a09e667, 0xf3bcc908,
-+             0xbb67ae85, 0x84caa73b,
-+             0x3c6ef372, 0xfe94f82b,
-+             0xa54ff53a, 0x5f1d36f1,
-+             0x510e527f, 0xade682d1,
-+             0x9b05688c, 0x2b3e6c1f,
-+             0x1f83d9ab, 0xfb41bd6b,
-+             0x5be0cd19, 0x137e2179 ];
-+  this.k = sha512_K;
-+  this.W = new Array(160);
-+}
-+utils.inherits(SHA512, BlockHash);
-+exports.sha512 = SHA512;
-+
-+SHA512.blockSize = 1024;
-+SHA512.outSize = 512;
-+SHA512.hmacStrength = 192;
-+SHA512.padLength = 128;
-+
-+SHA512.prototype._prepareBlock = function _prepareBlock(msg, start) {
-+  var W = this.W;
-+
-+  // 32 x 32bit words
-+  for (var i = 0; i < 32; i++)
-+    W[i] = msg[start + i];
-+  for (; i < W.length; i += 2) {
-+    var c0_hi = g1_512_hi(W[i - 4], W[i - 3]);  // i - 2
-+    var c0_lo = g1_512_lo(W[i - 4], W[i - 3]);
-+    var c1_hi = W[i - 14];  // i - 7
-+    var c1_lo = W[i - 13];
-+    var c2_hi = g0_512_hi(W[i - 30], W[i - 29]);  // i - 15
-+    var c2_lo = g0_512_lo(W[i - 30], W[i - 29]);
-+    var c3_hi = W[i - 32];  // i - 16
-+    var c3_lo = W[i - 31];
-+
-+    W[i] = sum64_4_hi(c0_hi, c0_lo,
-+                      c1_hi, c1_lo,
-+                      c2_hi, c2_lo,
-+                      c3_hi, c3_lo);
-+    W[i + 1] = sum64_4_lo(c0_hi, c0_lo,
-+                          c1_hi, c1_lo,
-+                          c2_hi, c2_lo,
-+                          c3_hi, c3_lo);
-+  }
-+};
-+
-+SHA512.prototype._update = function _update(msg, start) {
-+  this._prepareBlock(msg, start);
-+
-+  var W = this.W;
-+
-+  var ah = this.h[0];
-+  var al = this.h[1];
-+  var bh = this.h[2];
-+  var bl = this.h[3];
-+  var ch = this.h[4];
-+  var cl = this.h[5];
-+  var dh = this.h[6];
-+  var dl = this.h[7];
-+  var eh = this.h[8];
-+  var el = this.h[9];
-+  var fh = this.h[10];
-+  var fl = this.h[11];
-+  var gh = this.h[12];
-+  var gl = this.h[13];
-+  var hh = this.h[14];
-+  var hl = this.h[15];
-+
-+  assert(this.k.length === W.length);
-+  for (var i = 0; i < W.length; i += 2) {
-+    var c0_hi = hh;
-+    var c0_lo = hl;
-+    var c1_hi = s1_512_hi(eh, el);
-+    var c1_lo = s1_512_lo(eh, el);
-+    var c2_hi = ch64_hi(eh, el, fh, fl, gh, gl);
-+    var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl);
-+    var c3_hi = this.k[i];
-+    var c3_lo = this.k[i + 1];
-+    var c4_hi = W[i];
-+    var c4_lo = W[i + 1];
-+
-+    var T1_hi = sum64_5_hi(c0_hi, c0_lo,
-+                           c1_hi, c1_lo,
-+                           c2_hi, c2_lo,
-+                           c3_hi, c3_lo,
-+                           c4_hi, c4_lo);
-+    var T1_lo = sum64_5_lo(c0_hi, c0_lo,
-+                           c1_hi, c1_lo,
-+                           c2_hi, c2_lo,
-+                           c3_hi, c3_lo,
-+                           c4_hi, c4_lo);
-+
-+    var c0_hi = s0_512_hi(ah, al);
-+    var c0_lo = s0_512_lo(ah, al);
-+    var c1_hi = maj64_hi(ah, al, bh, bl, ch, cl);
-+    var c1_lo = maj64_lo(ah, al, bh, bl, ch, cl);
-+
-+    var T2_hi = sum64_hi(c0_hi, c0_lo, c1_hi, c1_lo);
-+    var T2_lo = sum64_lo(c0_hi, c0_lo, c1_hi, c1_lo);
-+
-+    hh = gh;
-+    hl = gl;
-+
-+    gh = fh;
-+    gl = fl;
-+
-+    fh = eh;
-+    fl = el;
-+
-+    eh = sum64_hi(dh, dl, T1_hi, T1_lo);
-+    el = sum64_lo(dl, dl, T1_hi, T1_lo);
-+
-+    dh = ch;
-+    dl = cl;
-+
-+    ch = bh;
-+    cl = bl;
-+
-+    bh = ah;
-+    bl = al;
-+
-+    ah = sum64_hi(T1_hi, T1_lo, T2_hi, T2_lo);
-+    al = sum64_lo(T1_hi, T1_lo, T2_hi, T2_lo);
-+  }
-+
-+  sum64(this.h, 0, ah, al);
-+  sum64(this.h, 2, bh, bl);
-+  sum64(this.h, 4, ch, cl);
-+  sum64(this.h, 6, dh, dl);
-+  sum64(this.h, 8, eh, el);
-+  sum64(this.h, 10, fh, fl);
-+  sum64(this.h, 12, gh, gl);
-+  sum64(this.h, 14, hh, hl);
-+};
-+
-+SHA512.prototype._digest = function digest(enc) {
-+  if (enc === 'hex')
-+    return utils.toHex32(this.h, 'big');
-+  else
-+    return utils.split32(this.h, 'big');
-+};
-+
-+function SHA384() {
-+  if (!(this instanceof SHA384))
-+    return new SHA384();
-+
-+  SHA512.call(this);
-+  this.h = [ 0xcbbb9d5d, 0xc1059ed8,
-+             0x629a292a, 0x367cd507,
-+             0x9159015a, 0x3070dd17,
-+             0x152fecd8, 0xf70e5939,
-+             0x67332667, 0xffc00b31,
-+             0x8eb44a87, 0x68581511,
-+             0xdb0c2e0d, 0x64f98fa7,
-+             0x47b5481d, 0xbefa4fa4 ];
-+}
-+utils.inherits(SHA384, SHA512);
-+exports.sha384 = SHA384;
-+
-+SHA384.blockSize = 1024;
-+SHA384.outSize = 384;
-+SHA384.hmacStrength = 192;
-+SHA384.padLength = 128;
-+
-+SHA384.prototype._digest = function digest(enc) {
-+  if (enc === 'hex')
-+    return utils.toHex32(this.h.slice(0, 12), 'big');
-+  else
-+    return utils.split32(this.h.slice(0, 12), 'big');
-+};
-+
-+function SHA1() {
-+  if (!(this instanceof SHA1))
-+    return new SHA1();
-+
-+  BlockHash.call(this);
-+  this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe,
-+             0x10325476, 0xc3d2e1f0 ];
-+  this.W = new Array(80);
-+}
-+
-+utils.inherits(SHA1, BlockHash);
-+exports.sha1 = SHA1;
-+
-+SHA1.blockSize = 512;
-+SHA1.outSize = 160;
-+SHA1.hmacStrength = 80;
-+SHA1.padLength = 64;
-+
-+SHA1.prototype._update = function _update(msg, start) {
-+  var W = this.W;
-+
-+  for (var i = 0; i < 16; i++)
-+    W[i] = msg[start + i];
-+
-+  for(; i < W.length; i++)
-+    W[i] = rotl32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
-+
-+  var a = this.h[0];
-+  var b = this.h[1];
-+  var c = this.h[2];
-+  var d = this.h[3];
-+  var e = this.h[4];
-+
-+  for (var i = 0; i < W.length; i++) {
-+    var s = ~~(i / 20);
-+    var t = sum32_5(rotl32(a, 5), ft_1(s, b, c, d), e, W[i], sha1_K[s]);
-+    e = d;
-+    d = c;
-+    c = rotl32(b, 30);
-+    b = a;
-+    a = t;
-+  }
-+
-+  this.h[0] = sum32(this.h[0], a);
-+  this.h[1] = sum32(this.h[1], b);
-+  this.h[2] = sum32(this.h[2], c);
-+  this.h[3] = sum32(this.h[3], d);
-+  this.h[4] = sum32(this.h[4], e);
-+};
-+
-+SHA1.prototype._digest = function digest(enc) {
-+  if (enc === 'hex')
-+    return utils.toHex32(this.h, 'big');
-+  else
-+    return utils.split32(this.h, 'big');
-+};
-+
-+function ch32(x, y, z) {
-+  return (x & y) ^ ((~x) & z);
-+}
-+
-+function maj32(x, y, z) {
-+  return (x & y) ^ (x & z) ^ (y & z);
-+}
-+
-+function p32(x, y, z) {
-+  return x ^ y ^ z;
-+}
-+
-+function s0_256(x) {
-+  return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22);
-+}
-+
-+function s1_256(x) {
-+  return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25);
-+}
-+
-+function g0_256(x) {
-+  return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3);
-+}
-+
-+function g1_256(x) {
-+  return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10);
-+}
-+
-+function ft_1(s, x, y, z) {
-+  if (s === 0)
-+    return ch32(x, y, z);
-+  if (s === 1 || s === 3)
-+    return p32(x, y, z);
-+  if (s === 2)
-+    return maj32(x, y, z);
-+}
-+
-+function ch64_hi(xh, xl, yh, yl, zh, zl) {
-+  var r = (xh & yh) ^ ((~xh) & zh);
-+  if (r < 0)
-+    r += 0x100000000;
-+  return r;
-+}
-+
-+function ch64_lo(xh, xl, yh, yl, zh, zl) {
-+  var r = (xl & yl) ^ ((~xl) & zl);
-+  if (r < 0)
-+    r += 0x100000000;
-+  return r;
-+}
-+
-+function maj64_hi(xh, xl, yh, yl, zh, zl) {
-+  var r = (xh & yh) ^ (xh & zh) ^ (yh & zh);
-+  if (r < 0)
-+    r += 0x100000000;
-+  return r;
-+}
-+
-+function maj64_lo(xh, xl, yh, yl, zh, zl) {
-+  var r = (xl & yl) ^ (xl & zl) ^ (yl & zl);
-+  if (r < 0)
-+    r += 0x100000000;
-+  return r;
-+}
-+
-+function s0_512_hi(xh, xl) {
-+  var c0_hi = rotr64_hi(xh, xl, 28);
-+  var c1_hi = rotr64_hi(xl, xh, 2);  // 34
-+  var c2_hi = rotr64_hi(xl, xh, 7);  // 39
-+
-+  var r = c0_hi ^ c1_hi ^ c2_hi;
-+  if (r < 0)
-+    r += 0x100000000;
-+  return r;
-+}
-+
-+function s0_512_lo(xh, xl) {
-+  var c0_lo = rotr64_lo(xh, xl, 28);
-+  var c1_lo = rotr64_lo(xl, xh, 2);  // 34
-+  var c2_lo = rotr64_lo(xl, xh, 7);  // 39
-+
-+  var r = c0_lo ^ c1_lo ^ c2_lo;
-+  if (r < 0)
-+    r += 0x100000000;
-+  return r;
-+}
-+
-+function s1_512_hi(xh, xl) {
-+  var c0_hi = rotr64_hi(xh, xl, 14);
-+  var c1_hi = rotr64_hi(xh, xl, 18);
-+  var c2_hi = rotr64_hi(xl, xh, 9);  // 41
-+
-+  var r = c0_hi ^ c1_hi ^ c2_hi;
-+  if (r < 0)
-+    r += 0x100000000;
-+  return r;
-+}
-+
-+function s1_512_lo(xh, xl) {
-+  var c0_lo = rotr64_lo(xh, xl, 14);
-+  var c1_lo = rotr64_lo(xh, xl, 18);
-+  var c2_lo = rotr64_lo(xl, xh, 9);  // 41
-+
-+  var r = c0_lo ^ c1_lo ^ c2_lo;
-+  if (r < 0)
-+    r += 0x100000000;
-+  return r;
-+}
-+
-+function g0_512_hi(xh, xl) {
-+  var c0_hi = rotr64_hi(xh, xl, 1);
-+  var c1_hi = rotr64_hi(xh, xl, 8);
-+  var c2_hi = shr64_hi(xh, xl, 7);
-+
-+  var r = c0_hi ^ c1_hi ^ c2_hi;
-+  if (r < 0)
-+    r += 0x100000000;
-+  return r;
-+}
-+
-+function g0_512_lo(xh, xl) {
-+  var c0_lo = rotr64_lo(xh, xl, 1);
-+  var c1_lo = rotr64_lo(xh, xl, 8);
-+  var c2_lo = shr64_lo(xh, xl, 7);
-+
-+  var r = c0_lo ^ c1_lo ^ c2_lo;
-+  if (r < 0)
-+    r += 0x100000000;
-+  return r;
-+}
-+
-+function g1_512_hi(xh, xl) {
-+  var c0_hi = rotr64_hi(xh, xl, 19);
-+  var c1_hi = rotr64_hi(xl, xh, 29);  // 61
-+  var c2_hi = shr64_hi(xh, xl, 6);
-+
-+  var r = c0_hi ^ c1_hi ^ c2_hi;
-+  if (r < 0)
-+    r += 0x100000000;
-+  return r;
-+}
-+
-+function g1_512_lo(xh, xl) {
-+  var c0_lo = rotr64_lo(xh, xl, 19);
-+  var c1_lo = rotr64_lo(xl, xh, 29);  // 61
-+  var c2_lo = shr64_lo(xh, xl, 6);
-+
-+  var r = c0_lo ^ c1_lo ^ c2_lo;
-+  if (r < 0)
-+    r += 0x100000000;
-+  return r;
-+}
-+
-+},{"../hash":19}],24:[function(require,module,exports){
-+var utils = exports;
-+var inherits = require('inherits');
-+
-+function toArray(msg, enc) {
-+  if (Array.isArray(msg))
-+    return msg.slice();
-+  if (!msg)
-+    return [];
-+  var res = [];
-+  if (typeof msg === 'string') {
-+    if (!enc) {
-+      for (var i = 0; i < msg.length; i++) {
-+        var c = msg.charCodeAt(i);
-+        var hi = c >> 8;
-+        var lo = c & 0xff;
-+        if (hi)
-+          res.push(hi, lo);
-+        else
-+          res.push(lo);
-+      }
-+    } else if (enc === 'hex') {
-+      msg = msg.replace(/[^a-z0-9]+/ig, '');
-+      if (msg.length % 2 !== 0)
-+        msg = '0' + msg;
-+      for (var i = 0; i < msg.length; i += 2)
-+        res.push(parseInt(msg[i] + msg[i + 1], 16));
-+    }
-+  } else {
-+    for (var i = 0; i < msg.length; i++)
-+      res[i] = msg[i] | 0;
-+  }
-+  return res;
-+}
-+utils.toArray = toArray;
-+
-+function toHex(msg) {
-+  var res = '';
-+  for (var i = 0; i < msg.length; i++)
-+    res += zero2(msg[i].toString(16));
-+  return res;
-+}
-+utils.toHex = toHex;
-+
-+function htonl(w) {
-+  var res = (w >>> 24) |
-+            ((w >>> 8) & 0xff00) |
-+            ((w << 8) & 0xff0000) |
-+            ((w & 0xff) << 24);
-+  return res >>> 0;
-+}
-+utils.htonl = htonl;
-+
-+function toHex32(msg, endian) {
-+  var res = '';
-+  for (var i = 0; i < msg.length; i++) {
-+    var w = msg[i];
-+    if (endian === 'little')
-+      w = htonl(w);
-+    res += zero8(w.toString(16));
-+  }
-+  return res;
-+}
-+utils.toHex32 = toHex32;
-+
-+function zero2(word) {
-+  if (word.length === 1)
-+    return '0' + word;
-+  else
-+    return word;
-+}
-+utils.zero2 = zero2;
-+
-+function zero8(word) {
-+  if (word.length === 7)
-+    return '0' + word;
-+  else if (word.length === 6)
-+    return '00' + word;
-+  else if (word.length === 5)
-+    return '000' + word;
-+  else if (word.length === 4)
-+    return '0000' + word;
-+  else if (word.length === 3)
-+    return '00000' + word;
-+  else if (word.length === 2)
-+    return '000000' + word;
-+  else if (word.length === 1)
-+    return '0000000' + word;
-+  else
-+    return word;
-+}
-+utils.zero8 = zero8;
-+
-+function join32(msg, start, end, endian) {
-+  var len = end - start;
-+  assert(len % 4 === 0);
-+  var res = new Array(len / 4);
-+  for (var i = 0, k = start; i < res.length; i++, k += 4) {
-+    var w;
-+    if (endian === 'big')
-+      w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3];
-+    else
-+      w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k];
-+    res[i] = w >>> 0;
-+  }
-+  return res;
-+}
-+utils.join32 = join32;
-+
-+function split32(msg, endian) {
-+  var res = new Array(msg.length * 4);
-+  for (var i = 0, k = 0; i < msg.length; i++, k += 4) {
-+    var m = msg[i];
-+    if (endian === 'big') {
-+      res[k] = m >>> 24;
-+      res[k + 1] = (m >>> 16) & 0xff;
-+      res[k + 2] = (m >>> 8) & 0xff;
-+      res[k + 3] = m & 0xff;
-+    } else {
-+      res[k + 3] = m >>> 24;
-+      res[k + 2] = (m >>> 16) & 0xff;
-+      res[k + 1] = (m >>> 8) & 0xff;
-+      res[k] = m & 0xff;
-+    }
-+  }
-+  return res;
-+}
-+utils.split32 = split32;
-+
-+function rotr32(w, b) {
-+  return (w >>> b) | (w << (32 - b));
-+}
-+utils.rotr32 = rotr32;
-+
-+function rotl32(w, b) {
-+  return (w << b) | (w >>> (32 - b));
-+}
-+utils.rotl32 = rotl32;
-+
-+function sum32(a, b) {
-+  return (a + b) >>> 0;
-+}
-+utils.sum32 = sum32;
-+
-+function sum32_3(a, b, c) {
-+  return (a + b + c) >>> 0;
-+}
-+utils.sum32_3 = sum32_3;
-+
-+function sum32_4(a, b, c, d) {
-+  return (a + b + c + d) >>> 0;
-+}
-+utils.sum32_4 = sum32_4;
-+
-+function sum32_5(a, b, c, d, e) {
-+  return (a + b + c + d + e) >>> 0;
-+}
-+utils.sum32_5 = sum32_5;
-+
-+function assert(cond, msg) {
-+  if (!cond)
-+    throw new Error(msg || 'Assertion failed');
-+}
-+utils.assert = assert;
-+
-+utils.inherits = inherits;
-+
-+function sum64(buf, pos, ah, al) {
-+  var bh = buf[pos];
-+  var bl = buf[pos + 1];
-+
-+  var lo = (al + bl) >>> 0;
-+  var hi = (lo < al ? 1 : 0) + ah + bh;
-+  buf[pos] = hi >>> 0;
-+  buf[pos + 1] = lo;
-+}
-+exports.sum64 = sum64;
-+
-+function sum64_hi(ah, al, bh, bl) {
-+  var lo = (al + bl) >>> 0;
-+  var hi = (lo < al ? 1 : 0) + ah + bh;
-+  return hi >>> 0;
-+};
-+exports.sum64_hi = sum64_hi;
-+
-+function sum64_lo(ah, al, bh, bl) {
-+  var lo = al + bl;
-+  return lo >>> 0;
-+};
-+exports.sum64_lo = sum64_lo;
-+
-+function sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) {
-+  var carry = 0;
-+  var lo = al;
-+  lo = (lo + bl) >>> 0;
-+  carry += lo < al ? 1 : 0;
-+  lo = (lo + cl) >>> 0;
-+  carry += lo < cl ? 1 : 0;
-+  lo = (lo + dl) >>> 0;
-+  carry += lo < dl ? 1 : 0;
-+
-+  var hi = ah + bh + ch + dh + carry;
-+  return hi >>> 0;
-+};
-+exports.sum64_4_hi = sum64_4_hi;
-+
-+function sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) {
-+  var lo = al + bl + cl + dl;
-+  return lo >>> 0;
-+};
-+exports.sum64_4_lo = sum64_4_lo;
-+
-+function sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
-+  var carry = 0;
-+  var lo = al;
-+  lo = (lo + bl) >>> 0;
-+  carry += lo < al ? 1 : 0;
-+  lo = (lo + cl) >>> 0;
-+  carry += lo < cl ? 1 : 0;
-+  lo = (lo + dl) >>> 0;
-+  carry += lo < dl ? 1 : 0;
-+  lo = (lo + el) >>> 0;
-+  carry += lo < el ? 1 : 0;
-+
-+  var hi = ah + bh + ch + dh + eh + carry;
-+  return hi >>> 0;
-+};
-+exports.sum64_5_hi = sum64_5_hi;
-+
-+function sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
-+  var lo = al + bl + cl + dl + el;
-+
-+  return lo >>> 0;
-+};
-+exports.sum64_5_lo = sum64_5_lo;
-+
-+function rotr64_hi(ah, al, num) {
-+  var r = (al << (32 - num)) | (ah >>> num);
-+  return r >>> 0;
-+};
-+exports.rotr64_hi = rotr64_hi;
-+
-+function rotr64_lo(ah, al, num) {
-+  var r = (ah << (32 - num)) | (al >>> num);
-+  return r >>> 0;
-+};
-+exports.rotr64_lo = rotr64_lo;
-+
-+function shr64_hi(ah, al, num) {
-+  return ah >>> num;
-+};
-+exports.shr64_hi = shr64_hi;
-+
-+function shr64_lo(ah, al, num) {
-+  var r = (ah << (32 - num)) | (al >>> num);
-+  return r >>> 0;
-+};
-+exports.shr64_lo = shr64_lo;
-+
-+},{"inherits":25}],25:[function(require,module,exports){
-+if (typeof Object.create === 'function') {
-+  // implementation from standard node.js 'util' module
-+  module.exports = function inherits(ctor, superCtor) {
-+    ctor.super_ = superCtor
-+    ctor.prototype = Object.create(superCtor.prototype, {
-+      constructor: {
-+        value: ctor,
-+        enumerable: false,
-+        writable: true,
-+        configurable: true
-+      }
-+    });
-+  };
-+} else {
-+  // old school shim for old browsers
-+  module.exports = function inherits(ctor, superCtor) {
-+    ctor.super_ = superCtor
-+    var TempCtor = function () {}
-+    TempCtor.prototype = superCtor.prototype
-+    ctor.prototype = new TempCtor()
-+    ctor.prototype.constructor = ctor
-+  }
-+}
-+
-+},{}],26:[function(require,module,exports){
-+module.exports={
-+  "name": "elliptic",
-+  "version": "6.3.2",
-+  "description": "EC cryptography",
-+  "main": "lib/elliptic.js",
-+  "files": [
-+    "lib"
-+  ],
-+  "scripts": {
-+    "jscs": "jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/index.js",
-+    "jshint": "jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/index.js",
-+    "lint": "npm run jscs && npm run jshint",
-+    "unit": "istanbul test _mocha --reporter=spec test/index.js",
-+    "test": "npm run lint && npm run unit",
-+    "version": "grunt dist && git add dist/"
-+  },
-+  "repository": {
-+    "type": "git",
-+    "url": "git at github.com:indutny/elliptic"
-+  },
-+  "keywords": [
-+    "EC",
-+    "Elliptic",
-+    "curve",
-+    "Cryptography"
-+  ],
-+  "author": "Fedor Indutny <fedor at indutny.com>",
-+  "license": "MIT",
-+  "bugs": {
-+    "url": "https://github.com/indutny/elliptic/issues"
-+  },
-+  "homepage": "https://github.com/indutny/elliptic",
-+  "devDependencies": {
-+    "brfs": "^1.4.3",
-+    "coveralls": "^2.11.3",
-+    "grunt": "^0.4.5",
-+    "grunt-browserify": "^5.0.0",
-+    "grunt-contrib-connect": "^1.0.0",
-+    "grunt-contrib-copy": "^1.0.0",
-+    "grunt-contrib-uglify": "^1.0.1",
-+    "grunt-mocha-istanbul": "^3.0.1",
-+    "grunt-saucelabs": "^8.6.2",
-+    "istanbul": "^0.4.2",
-+    "jscs": "^2.9.0",
-+    "jshint": "^2.6.0",
-+    "mocha": "^2.1.0"
-+  },
-+  "dependencies": {
-+    "bn.js": "^4.4.0",
-+    "brorand": "^1.0.1",
-+    "hash.js": "^1.0.0",
-+    "inherits": "^2.0.1"
-+  }
-+}
-+
-+},{}]},{},[2])(2)
-+});
-+
-+// End of the imported code from elliptic.js.
-+
-+// Create the exported symbol for the JavaScript module.
-+var elliptic = window.elliptic;
-\ No newline at end of file
-diff --git a/chat/protocols/irc/ircSASL.jsm b/chat/protocols/irc/ircSASL.jsm
-index 561f055e0..8a2bd70aa 100644
---- a/chat/protocols/irc/ircSASL.jsm
-+++ b/chat/protocols/irc/ircSASL.jsm
-@@ -14,6 +14,43 @@ var Cu = Components.utils;
- 
- Cu.import("resource:///modules/ircHandlers.jsm");
- Cu.import("resource:///modules/ircUtils.jsm");
-+Cu.import("resource:///modules/elliptic.jsm");
-+
-+/**
-+
-+  ECDSA-NIST256P-CHALLENGE
-+
-+  Paste the following code snippit in the Firefox web console to generate a
-+  private key (logged as hex string) and the irc command to execute to set
-+  the public key on the server.
-+
-+  crypto.subtle.generateKey({ name: "ECDSA", namedCurve: "P-256" }, true, ["sign"])
-+  .then((kp) => {
-+    crypto.subtle.exportKey("jwk", kp.privateKey).then((o) => {
-+      // convert from base64url to hex string
-+      let d = o.d;
-+      let padLen = (4 - (d.length % 4)) % 4;
-+      d = d.padEnd(d.length + padLen, "=")
-+           .replace(/\-/g, "+")
-+           .replace(/_/g, "/");
-+      let str = atob(d);
-+      let a = Array.prototype.map.call(str, (x) => x.charCodeAt(0));
-+      let h = a.reduce((prev, next) => prev + next.toString(16), "");
-+      console.log(h);
-+    });
-+    crypto.subtle.exportKey("raw", kp.publicKey).then((ab) => {
-+      let v = new Uint8Array(ab);
-+      let u = v.slice(0, 33);  // +1 here for the compressed point
-+      u[0] = 2 + (v[v.length - 1] & 1);
-+      let s = String.fromCharCode.apply(null, u);
-+      console.log("/msg nickserv set property pubkey", btoa(s));
-+    });
-+  });
-+
-+  Then, copy the private key to the preference `messenger.account.accountN.ecdsa`
-+  in the config editor.
-+
-+*/
- 
- var ircSASL = {
-   name: "SASL AUTHENTICATE",
-@@ -22,23 +59,41 @@ var ircSASL = {
- 
-   commands: {
-     "AUTHENTICATE": function(aMessage) {
--      // Expect an empty response, if something different is received abort.
--      if (aMessage.params[0] != "+") {
-+      let ecdsa = this.imAccount.wrappedJSObject.prefBranch.getCharPref("ecdsa");
-+      let hasECDSA = !!ecdsa.length;
-+
-+      if (aMessage.params[0] === "+") {
-+        // An authentication identity, authorization identity and password are
-+        // used, separated by null.
-+        let data = [this._requestedNickname, this._requestedNickname];
-+        if (!hasECDSA) data.push(this.imAccount.password);
-+        // btoa for Unicode, see https://developer.mozilla.org/en-US/docs/DOM/window.btoa
-+        let base64Data = btoa(unescape(encodeURIComponent(data.join("\0"))));
-+        this.sendMessage("AUTHENTICATE", base64Data);
-+        return true;
-+      } else if (hasECDSA) {
-+        let challenge = aMessage.params[0];
-+
-+        let EC = elliptic.ec;
-+        let ec = new EC('p256');
-+        let key = ec.keyFromPrivate(ecdsa, 'hex');
-+
-+        let str = atob(challenge);
-+        let arr = Array.prototype.map.call(str, (x) => x.charCodeAt(0));
-+
-+        let signature = key.sign(arr);
-+        let der = String.fromCharCode.apply(null, signature.toDER());
-+        let response = btoa(der);
-+
-+        this.sendMessage("AUTHENTICATE", response);
-+        return true;
-+      } else {
-+        // Expect an empty response, if something different is received abort.
-         this.sendMessage("AUTHENTICATE", "*");
-         this.WARN("Aborting SASL authentication, unexpected message " +
-                   "received:\n" + aMessage.rawMessage);
-         return true;
-       }
--
--      // An authentication identity, authorization identity and password are
--      // used, separated by null.
--      let data = [this._requestedNickname, this._requestedNickname,
--                  this.imAccount.password].join("\0");
--      // btoa for Unicode, see https://developer.mozilla.org/en-US/docs/DOM/window.btoa
--      let base64Data = btoa(unescape(encodeURIComponent(data)));
--      this.sendMessage("AUTHENTICATE", base64Data,
--                       "AUTHENTICATE <base64 encoded nick, user and password not logged>");
--      return true;
-     },
- 
-     "900": function(aMessage) {
-@@ -130,7 +185,10 @@ var capSASL = {
- 
-   commands: {
-     "sasl": function(aMessage) {
--      if (aMessage.cap.subcommand == "LS" && this.imAccount.password) {
-+      let ecdsa = this.imAccount.wrappedJSObject.prefBranch.getCharPref("ecdsa");
-+      let hasECDSA = !!ecdsa.length;
-+
-+      if (aMessage.cap.subcommand == "LS" && (this.imAccount.password || hasECDSA)) {
-         // If it supports SASL, let the server know we're requiring SASL.
-         this.sendMessage("CAP", ["REQ", "sasl"]);
-         this.addCAP("sasl");
-@@ -138,7 +196,8 @@ var capSASL = {
-       else if (aMessage.cap.subcommand == "ACK") {
-         // The server acknowledges our choice to use SASL, send the first
-         // message.
--        this.sendMessage("AUTHENTICATE", "PLAIN");
-+        this.sendMessage("AUTHENTICATE",
-+          hasECDSA ? "ECDSA-NIST256P-CHALLENGE" : "PLAIN");
-       }
- 
-       return true;
-diff --git a/chat/protocols/irc/moz.build b/chat/protocols/irc/moz.build
-index bc2539687..e46815dfe 100644
---- a/chat/protocols/irc/moz.build
-+++ b/chat/protocols/irc/moz.build
-@@ -11,6 +11,7 @@ EXTRA_COMPONENTS += [
- ]
- 
- EXTRA_JS_MODULES += [
-+    'elliptic.jsm',
-     'ircBase.jsm',
-     'ircCAP.jsm',
-     'ircCommands.jsm',
--- 
-2.11.0
-
diff --git a/projects/instantbird/0022-Bug-1313137-msg-is-not-defined-error-in-irc.js-chang.patch b/projects/instantbird/0022-Bug-1313137-msg-is-not-defined-error-in-irc.js-chang.patch
deleted file mode 100644
index 3aeac23..0000000
--- a/projects/instantbird/0022-Bug-1313137-msg-is-not-defined-error-in-irc.js-chang.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 64ee29ad8a94480af037f35ade04810ca0e1031d Mon Sep 17 00:00:00 2001
-From: aleth <aleth at instantbird.org>
-Date: Wed, 26 Oct 2016 20:16:58 +0200
-Subject: [PATCH 22/27] Bug 1313137 - "msg is not defined" error in
- irc.js:changeBuddyNick. r=clokep
-
---HG--
-extra : rebase_source : 5752a69059ecd48b947809ef12de177ccab8528f
----
- chat/protocols/irc/irc.js | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/chat/protocols/irc/irc.js b/chat/protocols/irc/irc.js
-index c2167a5ec..b58c2c2eb 100644
---- a/chat/protocols/irc/irc.js
-+++ b/chat/protocols/irc/irc.js
-@@ -1289,7 +1289,8 @@ ircAccount.prototype = {
-       this.conversations.set(aNewNick, conversation);
- 
-       conversation.updateNick(aNewNick);
--      conversation.writeMessage(aOldNick, msg, {system: true});
-+      conversation.writeMessage(aOldNick, _conv("nickSet", aOldNick, aNewNick),
-+                                {system: true});
-     }
-   },
- 
--- 
-2.11.0
-
diff --git a/projects/instantbird/0022-Bug-954368-Contact-list-entries-should-adapt-their-h.patch b/projects/instantbird/0022-Bug-954368-Contact-list-entries-should-adapt-their-h.patch
new file mode 100644
index 0000000..6fa776c
--- /dev/null
+++ b/projects/instantbird/0022-Bug-954368-Contact-list-entries-should-adapt-their-h.patch
@@ -0,0 +1,322 @@
+From 10c0e491625782ea5c2a99bfacbafa8a65406094 Mon Sep 17 00:00:00 2001
+From: aleth <aleth at instantbird.org>
+Date: Thu, 12 May 2016 15:10:43 +0200
+Subject: [PATCH 22/26] Bug 954368 - Contact list entries should adapt their
+ height to the actual font size. r=florian
+
+--HG--
+extra : rebase_source : 9820f3a68794f98260f3ac406772da6d176d02ec
+---
+ chat/themes/imtooltip.css                          |  1 +
+ im/content/blist.css                               | 38 ++++++++++++---
+ im/content/blist.js                                |  7 +++
+ im/content/blist.xul                               |  4 ++
+ im/content/contact.xml                             | 57 +++++++++++-----------
+ im/content/conv.xml                                | 10 ++--
+ .../en-US/chrome/instantbird/instantbird.dtd       |  6 +++
+ im/themes/blist.css                                | 22 ++++-----
+ 8 files changed, 92 insertions(+), 53 deletions(-)
+
+diff --git a/chat/themes/imtooltip.css b/chat/themes/imtooltip.css
+index c4525beb5..630da3983 100644
+--- a/chat/themes/imtooltip.css
++++ b/chat/themes/imtooltip.css
+@@ -31,6 +31,7 @@
+ 
+ .tooltipBuddies {
+   margin-left: -3px;
++  --blist-item-height: 20px; /* 16px icon plus padding */
+ }
+ 
+ .tooltipDisplayName {
+diff --git a/im/content/blist.css b/im/content/blist.css
+index d47e4f356..15b61b103 100644
+--- a/im/content/blist.css
++++ b/im/content/blist.css
+@@ -30,15 +30,28 @@ group {
+   -moz-box-align: center;
+ }
+ 
+-/* The height is required for the animation to work. The skin can
+- * specify an additionnal min-height value if there are things of
+- * constant size (icons + padding) */
+-contact,
+-buddy,
++/* The height is required for the animation to work. */
+ group {
+   height: 1em;
+ }
+ 
++conv,
++contact,
++buddy {
++  /* Variable set from blist.js. This is necessary as CSS transitions don't
++     work with height: auto.
++     Usually 16+2+2px for the protocol icon, padding top and bottom. */
++  height: var(--blist-item-height);
++}
++
++contact[open],
++contact[aliasing],
++#buddylistbox:focus > contact[selected] {
++  /* This is fine because height transitions in this state are on the
++     buddies, and there is no transition on selection (it's instant). */
++  height: auto;
++}
++
+ /* Possible values of the |state| attribute:
+  - not set: the binding is not initialized yet,
+  - showing: during the expand animation,
+@@ -51,23 +64,24 @@ contact:not([state]),
+ buddy:not([state]) {
+   height: 0;
+ }
++
+ contact[state="showing"],
+ buddy[state="showing"] {
+   /* Should match the transition effect for contact/buddy collapsing so
+      that reordering doesn't make the whole list jump. */
+-  -moz-transition: height .2s ease-in;
++  transition: height .2s ease-in;
+ }
+ 
+ contact[state="fading"] {
+   opacity: 0;
+-  -moz-transition: opacity .4s ease-in 1s;
++  transition: opacity .4s ease-in 1s;
+ }
+ 
+ contact[state="collapsing"],
+ buddy[state="collapsing"],
+ group[collapsing="true"] {
+   height: 0;
+-  -moz-transition: height .2s ease-in;
++  transition: height .2s ease-in;
+ }
+ 
+ contact[state="collapsing"] *,
+@@ -78,6 +92,14 @@ group[collapsing="true"] * {
+   display: none;
+ }
+ 
++#dummyContact {
++  height: auto;
++}
++
++#dummylistbox {
++  visibility: hidden;
++}
++
+ tooltip[type="im"] {
+   -moz-binding: url("chrome://chat/content/imtooltip.xml#tooltip");
+ }
+diff --git a/im/content/blist.js b/im/content/blist.js
+index 9ec10e25c..ce76ffcd7 100644
+--- a/im/content/blist.js
++++ b/im/content/blist.js
+@@ -820,6 +820,13 @@ var buddyList = {
+               .setAttribute("checked", "true");
+     }
+ 
++    // Find the correct height of a contact list item. This can vary depending
++    // on the platform font and font size.
++    let dummyContact = document.getElementById("dummyContact");
++    let contactHeight = dummyContact.getBoundingClientRect().height;
++    document.getElementById("buddyListMsg")
++            .style.setProperty("--blist-item-height", contactHeight + "px");
++
+     let blistBox = document.getElementById("buddylistbox");
+     blistBox.removeGroup = function(aGroupElt) {
+       let index = buddyList._displayedGroups.indexOf(aGroupElt);
+diff --git a/im/content/blist.xul b/im/content/blist.xul
+index f29a48b99..71ee2c9ef 100644
+--- a/im/content/blist.xul
++++ b/im/content/blist.xul
+@@ -224,6 +224,10 @@
+                  onfocus="buddyList.buddylistboxFocus();"
+                  onselect="buddyList.listboxSelect(event);"
+                  tooltip="imTooltip"/>
++    <richlistbox id="dummylistbox">
++      <contact id="dummyContact" displayname="&dummyContact.label;"
++               state="visible" status="unknown"/>
++    </richlistbox>
+     <spacer id="listSpacer" flex="1"
+             onclick='document.getElementById("buddylistbox").focus();'/>
+   </notificationbox>
+diff --git a/im/content/contact.xml b/im/content/contact.xml
+index 5fc36dd6e..f2b464182 100644
+--- a/im/content/contact.xml
++++ b/im/content/contact.xml
+@@ -16,11 +16,11 @@
+ 
+   <binding id="contact" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
+     <content>
+-      <xul:stack class="prplBuddyIcon" mousethrough="always">
+-        <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/>
+-        <xul:image class="statusIcon" xbl:inherits="status"/>
+-      </xul:stack>
+-      <xul:hbox flex="1" class="contact-hbox" mousethrough="always">
++      <xul:hbox flex="1" class="contact-hbox" mousethrough="always" align="center">
++        <xul:stack class="prplBuddyIcon" mousethrough="always">
++          <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/>
++          <xul:image class="statusIcon" xbl:inherits="status"/>
++        </xul:stack>
+         <xul:label crop="end" flex="1" mousethrough="always"
+                    anonid="displayname" class="contactDisplayName blistDisplayName"
+                    xbl:inherits="value=displayname,status"/>
+@@ -529,30 +529,29 @@
+ 
+   <binding id="contact-big" extends="chrome://instantbird/content/contact.xml#contact">
+     <content>
+-      <xul:hbox flex="1" mousethrough="always">
+-        <xul:stack class="prplBuddyIcon" mousethrough="always">
+-          <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/>
+-          <xul:image class="statusIcon" xbl:inherits="status"/>
+-        </xul:stack>
+-        <xul:vbox flex="1" class="contact-vbox" mousethrough="always">
+-          <xul:hbox class="contact-hbox" mousethrough="always">
+-            <xul:label crop="end" flex="1" mousethrough="always"
+-                       anonid="displayname" class="contactDisplayName blistDisplayName"
+-                       xbl:inherits="value=displayname,status"/>
+-            <xul:button anonid="startChatBubble" class="startChatBubble"
+-                        tooltiptext="&openConversationCmd.label;"/>
+-          </xul:hbox>
+-          <xul:hbox class="contact-hbox" mousethrough="always">
+-            <xul:label crop="end" flex="1" mousethrough="always"
+-                       anonid="statusText" class="contactStatusText"
+-                       xbl:inherits="value=statusText"/>
+-            <xul:button anonid="expander" class="expander-down"
+-                        tooltiptextexpand="&expandContactTooltip;"
+-                        tooltiptextcollapse="&collapseContactTooltip;"
+-                        tooltiptext="&expandContactTooltip;"/>
+-          </xul:hbox>
+-        </xul:vbox>
+-      </xul:hbox>
++      <xul:vbox flex="1" class="contact-vbox" mousethrough="always">
++        <xul:hbox flex="1" class="contact-hbox" mousethrough="always" align="center">
++          <xul:stack class="prplBuddyIcon" mousethrough="always">
++            <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/>
++            <xul:image class="statusIcon" xbl:inherits="status"/>
++          </xul:stack>
++          <xul:label crop="end" flex="1" mousethrough="always"
++                     anonid="displayname" class="contactDisplayName blistDisplayName"
++                     xbl:inherits="value=displayname,status"/>
++          <xul:button anonid="startChatBubble" class="startChatBubble"
++                      tooltiptext="&openConversationCmd.label;"/>
++        </xul:hbox>
++
++        <xul:hbox flex="1" class="contact-hbox" mousethrough="always" align="center">
++          <xul:label crop="end" flex="1" mousethrough="always"
++                     anonid="statusText" class="contactStatusText contactIconSpace"
++                     xbl:inherits="value=statusText"/>
++          <xul:button anonid="expander" class="expander-down"
++                      tooltiptextexpand="&expandContactTooltip;"
++                      tooltiptextcollapse="&collapseContactTooltip;"
++                      tooltiptext="&expandContactTooltip;"/>
++        </xul:hbox>
++      </xul:vbox>
+       <xul:vbox anonid="contactBuddies" class="contactBuddies">
+         <children/>
+       </xul:vbox>
+diff --git a/im/content/conv.xml b/im/content/conv.xml
+index 96a33af64..c41da6fb4 100644
+--- a/im/content/conv.xml
++++ b/im/content/conv.xml
+@@ -16,11 +16,11 @@
+ 
+   <binding id="conv" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
+     <content>
+-      <xul:stack class="prplBuddyIcon" mousethrough="always">
+-        <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/>
+-        <xul:image class="statusIcon" xbl:inherits="status"/>
+-      </xul:stack>
+-      <xul:hbox flex="1" class="conv-hbox" mousethrough="always">
++      <xul:hbox flex="1" class="conv-hbox" mousethrough="always" align="center">
++        <xul:stack class="prplBuddyIcon" mousethrough="always">
++          <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/>
++          <xul:image class="statusIcon" xbl:inherits="status"/>
++        </xul:stack>
+         <xul:label crop="end" flex="1" mousethrough="always"
+                    anonid="displayname" class="convDisplayName blistDisplayName"
+                    xbl:inherits="value=displayname,status"/>
+diff --git a/im/locales/en-US/chrome/instantbird/instantbird.dtd b/im/locales/en-US/chrome/instantbird/instantbird.dtd
+index 80b894862..fce965bb1 100644
+--- a/im/locales/en-US/chrome/instantbird/instantbird.dtd
++++ b/im/locales/en-US/chrome/instantbird/instantbird.dtd
+@@ -95,6 +95,12 @@
+ <!ENTITY userIcon.label                "Change your icon">
+ <!ENTITY contactsHeader.label          "Contacts">
+ <!ENTITY convsHeader.label             "Conversations on hold">
++<!-- LOCALIZATION NOTE (dummyContact.label):
++     This string is not displayed anywhere, but it is used to calculate
++     the height of an item in the contact list. Therefore you should
++     set it to a string which contains characters that cover all
++     vertical sizes that occur in your language. -->
++<!ENTITY dummyContact.label            "SgFyWp">
+ 
+ <!ENTITY openConversationCmd.label     "Start a conversation">
+ <!ENTITY openConversationCmd.accesskey "c">
+diff --git a/im/themes/blist.css b/im/themes/blist.css
+index 992267405..c033b51bc 100644
+--- a/im/themes/blist.css
++++ b/im/themes/blist.css
+@@ -100,14 +100,7 @@ group {
+   padding: 0 2px;
+ }
+ 
+-conv,
+-contact,
+-buddy {
+-  height: 20px; /* 16+2+2px for the protocol icon, padding top and bottom */
+-}
+-
+ /* The vertical padding directly on the binding would not be animated. */
+-.prplBuddyIcon,
+ group>* {
+   padding-top: 2px;
+   padding-bottom: 2px;
+@@ -153,21 +146,28 @@ contact[droptarget] > buddy[dummy] {
+   margin: 0;
+ }
+ 
++.contactDisplayName,
+ .buddyDisplayName {
+   -moz-margin-start: 2px;
+ }
+ 
++/* Used for the second line of a contact-big to add space on the left
++   where the .prplBuddyIcon sits on the first line. */
++.contactIconSpace {
++  /* .prplBuddyIcon width+margins (16+3+3) + .contactStatusText margin (2) */
++  margin-inline-start: 24px;
++}
++
+ .contact-hbox,
+ .conv-hbox {
+   margin: 2px 0;
+-  -moz-margin-start: 2px;
+   min-height: 16px;
+   overflow-x: hidden;
+ }
+ 
+ /* Avoid a strange jumping bug when hovering and the startChatBubble appears */
+ .contact-vbox {
+-  min-height: 40px;
++  min-height: calc(var(--blist-item-height) * 2);
+ }
+ 
+ .hideGroupButton,
+@@ -240,8 +240,8 @@ contact[droptarget] > buddy[dummy] {
+ .startChatBubble,
+ .expander-up,
+ .expander-down {
+-  width: 16px;
+-  height: 16px;
++  max-width: 16px;
++  max-height: 16px;
+   min-height: 16px;
+   min-width: 16px;
+ }
+-- 
+2.11.0
+
diff --git a/projects/instantbird/0023-Bug-1187281-Only-show-close-button-on-Windows.patch b/projects/instantbird/0023-Bug-1187281-Only-show-close-button-on-Windows.patch
new file mode 100644
index 0000000..15fb272
--- /dev/null
+++ b/projects/instantbird/0023-Bug-1187281-Only-show-close-button-on-Windows.patch
@@ -0,0 +1,25 @@
+From df5943c2501769059a5ada93a5352f27f99f764b Mon Sep 17 00:00:00 2001
+From: Arlo Breault <arlolra at gmail.com>
+Date: Sat, 5 Nov 2016 14:55:20 -0700
+Subject: [PATCH 23/26] Bug 1187281 - Only show "close" button on Windows
+
+---
+ im/content/accounts.xul | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/im/content/accounts.xul b/im/content/accounts.xul
+index f3f1c6bbb..d683562cb 100644
+--- a/im/content/accounts.xul
++++ b/im/content/accounts.xul
+@@ -142,6 +142,8 @@
+   <windowdragbox id="bottombuttons" align="center">
+     <button id="newaccount" command="cmd_new"/>
+     <spacer flex="1"/>
++#ifdef XP_WIN
+     <button id="close" command="cmd_close"/>
++#endif
+   </windowdragbox>
+ </window>
+-- 
+2.11.0
+
diff --git a/projects/instantbird/0023-Bug-954368-Contact-list-entries-should-adapt-their-h.patch b/projects/instantbird/0023-Bug-954368-Contact-list-entries-should-adapt-their-h.patch
deleted file mode 100644
index 970e181..0000000
--- a/projects/instantbird/0023-Bug-954368-Contact-list-entries-should-adapt-their-h.patch
+++ /dev/null
@@ -1,322 +0,0 @@
-From a9a6176b88f5c1d55a82058181c2c2f0684743ff Mon Sep 17 00:00:00 2001
-From: aleth <aleth at instantbird.org>
-Date: Thu, 12 May 2016 15:10:43 +0200
-Subject: [PATCH 23/27] Bug 954368 - Contact list entries should adapt their
- height to the actual font size. r=florian
-
---HG--
-extra : rebase_source : 9820f3a68794f98260f3ac406772da6d176d02ec
----
- chat/themes/imtooltip.css                          |  1 +
- im/content/blist.css                               | 38 ++++++++++++---
- im/content/blist.js                                |  7 +++
- im/content/blist.xul                               |  4 ++
- im/content/contact.xml                             | 57 +++++++++++-----------
- im/content/conv.xml                                | 10 ++--
- .../en-US/chrome/instantbird/instantbird.dtd       |  6 +++
- im/themes/blist.css                                | 22 ++++-----
- 8 files changed, 92 insertions(+), 53 deletions(-)
-
-diff --git a/chat/themes/imtooltip.css b/chat/themes/imtooltip.css
-index c4525beb5..630da3983 100644
---- a/chat/themes/imtooltip.css
-+++ b/chat/themes/imtooltip.css
-@@ -31,6 +31,7 @@
- 
- .tooltipBuddies {
-   margin-left: -3px;
-+  --blist-item-height: 20px; /* 16px icon plus padding */
- }
- 
- .tooltipDisplayName {
-diff --git a/im/content/blist.css b/im/content/blist.css
-index d47e4f356..15b61b103 100644
---- a/im/content/blist.css
-+++ b/im/content/blist.css
-@@ -30,15 +30,28 @@ group {
-   -moz-box-align: center;
- }
- 
--/* The height is required for the animation to work. The skin can
-- * specify an additionnal min-height value if there are things of
-- * constant size (icons + padding) */
--contact,
--buddy,
-+/* The height is required for the animation to work. */
- group {
-   height: 1em;
- }
- 
-+conv,
-+contact,
-+buddy {
-+  /* Variable set from blist.js. This is necessary as CSS transitions don't
-+     work with height: auto.
-+     Usually 16+2+2px for the protocol icon, padding top and bottom. */
-+  height: var(--blist-item-height);
-+}
-+
-+contact[open],
-+contact[aliasing],
-+#buddylistbox:focus > contact[selected] {
-+  /* This is fine because height transitions in this state are on the
-+     buddies, and there is no transition on selection (it's instant). */
-+  height: auto;
-+}
-+
- /* Possible values of the |state| attribute:
-  - not set: the binding is not initialized yet,
-  - showing: during the expand animation,
-@@ -51,23 +64,24 @@ contact:not([state]),
- buddy:not([state]) {
-   height: 0;
- }
-+
- contact[state="showing"],
- buddy[state="showing"] {
-   /* Should match the transition effect for contact/buddy collapsing so
-      that reordering doesn't make the whole list jump. */
--  -moz-transition: height .2s ease-in;
-+  transition: height .2s ease-in;
- }
- 
- contact[state="fading"] {
-   opacity: 0;
--  -moz-transition: opacity .4s ease-in 1s;
-+  transition: opacity .4s ease-in 1s;
- }
- 
- contact[state="collapsing"],
- buddy[state="collapsing"],
- group[collapsing="true"] {
-   height: 0;
--  -moz-transition: height .2s ease-in;
-+  transition: height .2s ease-in;
- }
- 
- contact[state="collapsing"] *,
-@@ -78,6 +92,14 @@ group[collapsing="true"] * {
-   display: none;
- }
- 
-+#dummyContact {
-+  height: auto;
-+}
-+
-+#dummylistbox {
-+  visibility: hidden;
-+}
-+
- tooltip[type="im"] {
-   -moz-binding: url("chrome://chat/content/imtooltip.xml#tooltip");
- }
-diff --git a/im/content/blist.js b/im/content/blist.js
-index 9ec10e25c..ce76ffcd7 100644
---- a/im/content/blist.js
-+++ b/im/content/blist.js
-@@ -820,6 +820,13 @@ var buddyList = {
-               .setAttribute("checked", "true");
-     }
- 
-+    // Find the correct height of a contact list item. This can vary depending
-+    // on the platform font and font size.
-+    let dummyContact = document.getElementById("dummyContact");
-+    let contactHeight = dummyContact.getBoundingClientRect().height;
-+    document.getElementById("buddyListMsg")
-+            .style.setProperty("--blist-item-height", contactHeight + "px");
-+
-     let blistBox = document.getElementById("buddylistbox");
-     blistBox.removeGroup = function(aGroupElt) {
-       let index = buddyList._displayedGroups.indexOf(aGroupElt);
-diff --git a/im/content/blist.xul b/im/content/blist.xul
-index f29a48b99..71ee2c9ef 100644
---- a/im/content/blist.xul
-+++ b/im/content/blist.xul
-@@ -224,6 +224,10 @@
-                  onfocus="buddyList.buddylistboxFocus();"
-                  onselect="buddyList.listboxSelect(event);"
-                  tooltip="imTooltip"/>
-+    <richlistbox id="dummylistbox">
-+      <contact id="dummyContact" displayname="&dummyContact.label;"
-+               state="visible" status="unknown"/>
-+    </richlistbox>
-     <spacer id="listSpacer" flex="1"
-             onclick='document.getElementById("buddylistbox").focus();'/>
-   </notificationbox>
-diff --git a/im/content/contact.xml b/im/content/contact.xml
-index 5fc36dd6e..f2b464182 100644
---- a/im/content/contact.xml
-+++ b/im/content/contact.xml
-@@ -16,11 +16,11 @@
- 
-   <binding id="contact" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
-     <content>
--      <xul:stack class="prplBuddyIcon" mousethrough="always">
--        <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/>
--        <xul:image class="statusIcon" xbl:inherits="status"/>
--      </xul:stack>
--      <xul:hbox flex="1" class="contact-hbox" mousethrough="always">
-+      <xul:hbox flex="1" class="contact-hbox" mousethrough="always" align="center">
-+        <xul:stack class="prplBuddyIcon" mousethrough="always">
-+          <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/>
-+          <xul:image class="statusIcon" xbl:inherits="status"/>
-+        </xul:stack>
-         <xul:label crop="end" flex="1" mousethrough="always"
-                    anonid="displayname" class="contactDisplayName blistDisplayName"
-                    xbl:inherits="value=displayname,status"/>
-@@ -529,30 +529,29 @@
- 
-   <binding id="contact-big" extends="chrome://instantbird/content/contact.xml#contact">
-     <content>
--      <xul:hbox flex="1" mousethrough="always">
--        <xul:stack class="prplBuddyIcon" mousethrough="always">
--          <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/>
--          <xul:image class="statusIcon" xbl:inherits="status"/>
--        </xul:stack>
--        <xul:vbox flex="1" class="contact-vbox" mousethrough="always">
--          <xul:hbox class="contact-hbox" mousethrough="always">
--            <xul:label crop="end" flex="1" mousethrough="always"
--                       anonid="displayname" class="contactDisplayName blistDisplayName"
--                       xbl:inherits="value=displayname,status"/>
--            <xul:button anonid="startChatBubble" class="startChatBubble"
--                        tooltiptext="&openConversationCmd.label;"/>
--          </xul:hbox>
--          <xul:hbox class="contact-hbox" mousethrough="always">
--            <xul:label crop="end" flex="1" mousethrough="always"
--                       anonid="statusText" class="contactStatusText"
--                       xbl:inherits="value=statusText"/>
--            <xul:button anonid="expander" class="expander-down"
--                        tooltiptextexpand="&expandContactTooltip;"
--                        tooltiptextcollapse="&collapseContactTooltip;"
--                        tooltiptext="&expandContactTooltip;"/>
--          </xul:hbox>
--        </xul:vbox>
--      </xul:hbox>
-+      <xul:vbox flex="1" class="contact-vbox" mousethrough="always">
-+        <xul:hbox flex="1" class="contact-hbox" mousethrough="always" align="center">
-+          <xul:stack class="prplBuddyIcon" mousethrough="always">
-+            <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/>
-+            <xul:image class="statusIcon" xbl:inherits="status"/>
-+          </xul:stack>
-+          <xul:label crop="end" flex="1" mousethrough="always"
-+                     anonid="displayname" class="contactDisplayName blistDisplayName"
-+                     xbl:inherits="value=displayname,status"/>
-+          <xul:button anonid="startChatBubble" class="startChatBubble"
-+                      tooltiptext="&openConversationCmd.label;"/>
-+        </xul:hbox>
-+
-+        <xul:hbox flex="1" class="contact-hbox" mousethrough="always" align="center">
-+          <xul:label crop="end" flex="1" mousethrough="always"
-+                     anonid="statusText" class="contactStatusText contactIconSpace"
-+                     xbl:inherits="value=statusText"/>
-+          <xul:button anonid="expander" class="expander-down"
-+                      tooltiptextexpand="&expandContactTooltip;"
-+                      tooltiptextcollapse="&collapseContactTooltip;"
-+                      tooltiptext="&expandContactTooltip;"/>
-+        </xul:hbox>
-+      </xul:vbox>
-       <xul:vbox anonid="contactBuddies" class="contactBuddies">
-         <children/>
-       </xul:vbox>
-diff --git a/im/content/conv.xml b/im/content/conv.xml
-index 96a33af64..c41da6fb4 100644
---- a/im/content/conv.xml
-+++ b/im/content/conv.xml
-@@ -16,11 +16,11 @@
- 
-   <binding id="conv" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
-     <content>
--      <xul:stack class="prplBuddyIcon" mousethrough="always">
--        <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/>
--        <xul:image class="statusIcon" xbl:inherits="status"/>
--      </xul:stack>
--      <xul:hbox flex="1" class="conv-hbox" mousethrough="always">
-+      <xul:hbox flex="1" class="conv-hbox" mousethrough="always" align="center">
-+        <xul:stack class="prplBuddyIcon" mousethrough="always">
-+          <xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/>
-+          <xul:image class="statusIcon" xbl:inherits="status"/>
-+        </xul:stack>
-         <xul:label crop="end" flex="1" mousethrough="always"
-                    anonid="displayname" class="convDisplayName blistDisplayName"
-                    xbl:inherits="value=displayname,status"/>
-diff --git a/im/locales/en-US/chrome/instantbird/instantbird.dtd b/im/locales/en-US/chrome/instantbird/instantbird.dtd
-index 80b894862..fce965bb1 100644
---- a/im/locales/en-US/chrome/instantbird/instantbird.dtd
-+++ b/im/locales/en-US/chrome/instantbird/instantbird.dtd
-@@ -95,6 +95,12 @@
- <!ENTITY userIcon.label                "Change your icon">
- <!ENTITY contactsHeader.label          "Contacts">
- <!ENTITY convsHeader.label             "Conversations on hold">
-+<!-- LOCALIZATION NOTE (dummyContact.label):
-+     This string is not displayed anywhere, but it is used to calculate
-+     the height of an item in the contact list. Therefore you should
-+     set it to a string which contains characters that cover all
-+     vertical sizes that occur in your language. -->
-+<!ENTITY dummyContact.label            "SgFyWp">
- 
- <!ENTITY openConversationCmd.label     "Start a conversation">
- <!ENTITY openConversationCmd.accesskey "c">
-diff --git a/im/themes/blist.css b/im/themes/blist.css
-index 992267405..c033b51bc 100644
---- a/im/themes/blist.css
-+++ b/im/themes/blist.css
-@@ -100,14 +100,7 @@ group {
-   padding: 0 2px;
- }
- 
--conv,
--contact,
--buddy {
--  height: 20px; /* 16+2+2px for the protocol icon, padding top and bottom */
--}
--
- /* The vertical padding directly on the binding would not be animated. */
--.prplBuddyIcon,
- group>* {
-   padding-top: 2px;
-   padding-bottom: 2px;
-@@ -153,21 +146,28 @@ contact[droptarget] > buddy[dummy] {
-   margin: 0;
- }
- 
-+.contactDisplayName,
- .buddyDisplayName {
-   -moz-margin-start: 2px;
- }
- 
-+/* Used for the second line of a contact-big to add space on the left
-+   where the .prplBuddyIcon sits on the first line. */
-+.contactIconSpace {
-+  /* .prplBuddyIcon width+margins (16+3+3) + .contactStatusText margin (2) */
-+  margin-inline-start: 24px;
-+}
-+
- .contact-hbox,
- .conv-hbox {
-   margin: 2px 0;
--  -moz-margin-start: 2px;
-   min-height: 16px;
-   overflow-x: hidden;
- }
- 
- /* Avoid a strange jumping bug when hovering and the startChatBubble appears */
- .contact-vbox {
--  min-height: 40px;
-+  min-height: calc(var(--blist-item-height) * 2);
- }
- 
- .hideGroupButton,
-@@ -240,8 +240,8 @@ contact[droptarget] > buddy[dummy] {
- .startChatBubble,
- .expander-up,
- .expander-down {
--  width: 16px;
--  height: 16px;
-+  max-width: 16px;
-+  max-height: 16px;
-   min-height: 16px;
-   min-width: 16px;
- }
--- 
-2.11.0
-
diff --git a/projects/instantbird/0024-Bug-1187281-Only-show-close-button-on-Windows.patch b/projects/instantbird/0024-Bug-1187281-Only-show-close-button-on-Windows.patch
deleted file mode 100644
index 4c2516c..0000000
--- a/projects/instantbird/0024-Bug-1187281-Only-show-close-button-on-Windows.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From c8130e504c68957e03541d522429bad31c5c5d21 Mon Sep 17 00:00:00 2001
-From: Arlo Breault <arlolra at gmail.com>
-Date: Sat, 5 Nov 2016 14:55:20 -0700
-Subject: [PATCH 24/27] Bug 1187281 - Only show "close" button on Windows
-
----
- im/content/accounts.xul | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/im/content/accounts.xul b/im/content/accounts.xul
-index f3f1c6bbb..d683562cb 100644
---- a/im/content/accounts.xul
-+++ b/im/content/accounts.xul
-@@ -142,6 +142,8 @@
-   <windowdragbox id="bottombuttons" align="center">
-     <button id="newaccount" command="cmd_new"/>
-     <spacer flex="1"/>
-+#ifdef XP_WIN
-     <button id="close" command="cmd_close"/>
-+#endif
-   </windowdragbox>
- </window>
--- 
-2.11.0
-
diff --git a/projects/instantbird/0024-Bug-1316000-Remove-old-Yahoo-Messenger-support.-r-al.patch b/projects/instantbird/0024-Bug-1316000-Remove-old-Yahoo-Messenger-support.-r-al.patch
new file mode 100644
index 0000000..0a5fbb4
--- /dev/null
+++ b/projects/instantbird/0024-Bug-1316000-Remove-old-Yahoo-Messenger-support.-r-al.patch
@@ -0,0 +1,2398 @@
+From 300fcb344de6111a6f96ebda90fe8f70a8534e00 Mon Sep 17 00:00:00 2001
+From: Patrick Cloke <clokep at gmail.com>
+Date: Wed, 9 Nov 2016 09:03:49 -0800
+Subject: [PATCH 24/26] Bug 1316000 - Remove old Yahoo! Messenger support.
+ r=aleth
+
+---
+ chat/chat-prefs.js                                 |    2 +
+ chat/locales/en-US/facebook.properties             |    3 +-
+ chat/locales/en-US/yahoo.properties                |   34 +-
+ chat/protocols/facebook/facebook.js                |   13 +-
+ chat/protocols/yahoo/moz.build                     |    6 -
+ chat/protocols/yahoo/test/test_yahooAccount.js     |   98 --
+ chat/protocols/yahoo/test/test_yahooLoginHelper.js |   89 --
+ chat/protocols/yahoo/test/test_yahoopacket.js      |  217 ----
+ chat/protocols/yahoo/test/xpcshell.ini             |    7 -
+ chat/protocols/yahoo/yahoo-session.jsm             | 1156 --------------------
+ chat/protocols/yahoo/yahoo.js                      |  552 +---------
+ im/content/conversation.xml                        |    3 +-
+ .../chrome/instantbird/accountWizard.properties    |    3 +-
+ im/test/xpcshell.ini                               |    1 -
+ mail/components/im/content/imconversation.xml      |    3 +-
+ 15 files changed, 18 insertions(+), 2169 deletions(-)
+ delete mode 100644 chat/protocols/yahoo/test/test_yahooAccount.js
+ delete mode 100644 chat/protocols/yahoo/test/test_yahooLoginHelper.js
+ delete mode 100644 chat/protocols/yahoo/test/test_yahoopacket.js
+ delete mode 100644 chat/protocols/yahoo/test/xpcshell.ini
+ delete mode 100644 chat/protocols/yahoo/yahoo-session.jsm
+
+diff --git a/chat/chat-prefs.js b/chat/chat-prefs.js
+index fb769163d..60b9c1e8c 100644
+--- a/chat/chat-prefs.js
++++ b/chat/chat-prefs.js
+@@ -84,6 +84,8 @@ pref("chat.irc.automaticList", true);
+ pref("chat.prpls.prpl-skype.disable", true);
+ // Disable Facebook as the XMPP gateway no longer exists.
+ pref("chat.prpls.prpl-facebook.disable", true);
++// Disable Yahoo Messenger as legacy Yahoo was shut down.
++pref("chat.prpls.prpl-yahoo.disable", true);
+ 
+ // loglevel is the minimum severity level that a libpurple message
+ // must have to be reported in the Error Console.
+diff --git a/chat/locales/en-US/facebook.properties b/chat/locales/en-US/facebook.properties
+index aaf7cdc9c..2e00cbcb2 100644
+--- a/chat/locales/en-US/facebook.properties
++++ b/chat/locales/en-US/facebook.properties
+@@ -2,6 +2,5 @@
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ 
+-connection.error.useUsernameNotEmailAddress=Please use your Facebook username, not an email address
+-
+ facebook.chat.name=Facebook Chat
++facebook.disabled=Facebook Chat is no longer supported due to Facebook disabling their XMPP gateway.
+diff --git a/chat/locales/en-US/yahoo.properties b/chat/locales/en-US/yahoo.properties
+index 727faa6ee..89ee0093c 100644
+--- a/chat/locales/en-US/yahoo.properties
++++ b/chat/locales/en-US/yahoo.properties
+@@ -2,36 +2,4 @@
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ 
+-login.error.badCredentials=Username or password is incorrect.
+-login.error.accountLockedFailed=Account locked due to too many failed login attempts.
+-login.error.accountLockedGeneral=Account locked due to too many login attempts.
+-login.error.accountDeactivated=Account has been deactivated.
+-login.error.usernameNotExist=The username does not exist.
+-# The %S will be an error code returned by the server.
+-login.error.unknown=Unknown error: %S
+-network.error.http=HTTP connection error.
+-
+-conference.invite.message=Join my conference.
+-
+-# Some options are commented out because they aren't used. We do the same thing
+-# to their description strings.
+-options.pagerPort=Port
+-options.transferHost=File transfer server
+-options.transferPort=File transfer port
+-options.chatEncoding=Encoding
+-options.ignoreInvites=Ignore conference invitations
+-
+-# In this message, %S is replaced with the username of the user who left.
+-system.message.conferenceLogoff=%S has left the conference.
+-system.message.conferenceLogon=%S has joined the conference.
+-
+-# LOCALZIATION NOTE (command.*):
+-#   These are the help messages for each command, the %S is the command name
+-#   Each command first gives the parameter it accepts and then a description of
+-#   the command.
+-command.help.invite2=%S <user1>[,<user2>,...] [<invite message>]: invite one or more users into this conference chat.
+-command.help.conference=%S: Create a new conference room in which you can later invite other users.
+-
+-# LOCALIZATION NOTE (command.feedback.invite):
+-#   %S is the user, or comma separated list of users, invited to the conference.
+-command.feedback.invite=You have invited %S to the conference.
++yahoo.disabled=Yahoo Messenger is no longer supported due to Yahoo disabling their legacy protocol.
+diff --git a/chat/protocols/facebook/facebook.js b/chat/protocols/facebook/facebook.js
+index 7b5b3b86e..9d90eacdb 100644
+--- a/chat/protocols/facebook/facebook.js
++++ b/chat/protocols/facebook/facebook.js
+@@ -6,33 +6,26 @@ var {interfaces: Ci, utils: Cu} = Components;
+ 
+ Cu.import("resource:///modules/imXPCOMUtils.jsm");
+ Cu.import("resource:///modules/jsProtoHelper.jsm");
+-Cu.import("resource:///modules/xmpp.jsm");
+-Cu.import("resource:///modules/xmpp-session.jsm");
+ 
+ XPCOMUtils.defineLazyGetter(this, "_", () =>
+   l10nHelper("chrome://chat/locale/facebook.properties")
+ );
+-XPCOMUtils.defineLazyGetter(this, "_irc", () =>
+-  l10nHelper("chrome://chat/locale/irc.properties")
+-);
+ 
+ function FacebookAccount(aProtoInstance, aImAccount) {
+   this._init(aProtoInstance, aImAccount);
+ }
+ FacebookAccount.prototype = {
+-  __proto__: XMPPAccountPrototype,
+-  get canJoinChat() { return false; },
++  __proto__: GenericAccountPrototype,
+   connect: function() {
+     this.WARN("As Facebook deprecated its XMPP gateway, it is currently not " +
+               "possible to connect to Facebook Chat. See bug 1141674.");
+     this.reportDisconnecting(Ci.prplIAccount.ERROR_OTHER_ERROR,
+-                             _irc("error.unavailable", _("facebook.chat.name")));
++                             _("facebook.disabled"));
+     this.reportDisconnected();
+   }
+ };
+ 
+-function FacebookProtocol() {
+-}
++function FacebookProtocol() {}
+ FacebookProtocol.prototype = {
+   __proto__: GenericProtocolPrototype,
+   get normalizedName() { return "facebook"; },
+diff --git a/chat/protocols/yahoo/moz.build b/chat/protocols/yahoo/moz.build
+index f14434732..ea378535a 100644
+--- a/chat/protocols/yahoo/moz.build
++++ b/chat/protocols/yahoo/moz.build
+@@ -3,15 +3,9 @@
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ 
+-XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell.ini']
+-
+ EXTRA_COMPONENTS += [
+     'yahoo.js',
+     'yahoo.manifest',
+ ]
+ 
+-EXTRA_JS_MODULES += [
+-    'yahoo-session.jsm',
+-]
+-
+ JAR_MANIFESTS += ['jar.mn']
+diff --git a/chat/protocols/yahoo/test/test_yahooAccount.js b/chat/protocols/yahoo/test/test_yahooAccount.js
+deleted file mode 100644
+index 51df00bb9..000000000
+--- a/chat/protocols/yahoo/test/test_yahooAccount.js
++++ /dev/null
+@@ -1,98 +0,0 @@
+-/* Any copyright is dedicated to the Public Domain.
+- * http://creativecommons.org/publicdomain/zero/1.0/ */
+-
+-Components.utils.import("resource://gre/modules/Services.jsm");
+-var yahoo = {};
+-Services.scriptloader.loadSubScript("resource:///components/yahoo.js", yahoo);
+-
+-function run_test()
+-{
+-  add_test(test_cleanUsername);
+-  add_test(test_fixFontSize);
+-  run_next_test();
+-}
+-
+-// Test the stripping of @yahoo.* domains from usernames.
+-function test_cleanUsername()
+-{
+-  // These are just a few of the many possible domains.
+-  let domains = ["yahoo.com.ar", "yahoo.com.au", "yahoo.com", "yahoo.co.jp",
+-                 "yahoo.it", "yahoo.cn", "yahoo.co.in"];
+-  let userId = "user";
+-
+-  // We must provide a mimimal fake implementation of a protocol object, to keep
+-  // the YahooAccount constructor happy.
+-  let fakeProtocol = {
+-    id: "fake-proto",
+-    options: {
+-      local_charset: "UTF-8"
+-    },
+-    _getOptionDefault: function(aOption) { return this.options[aOption]; }
+-  };
+-  let fakeImAccount = {};
+-
+-  for each(let domain in domains) {
+-    fakeImAccount.name = userId + "@" + domain;
+-    let yahooAccount = new yahoo.YahooAccount(fakeProtocol, fakeImAccount);
+-    do_check_eq(userId, yahooAccount.cleanUsername);
+-  }
+-  run_next_test();
+-}
+-
+-// Test the _fixFontSize() method and ensure that it correctly fixes font sizes
+-// in <font> tags while keeping any mention of size= in conversation untouched.
+-function test_fixFontSize()
+-{
+-  // This is an array of two-element arrays. Each inner two-element array
+-  // contains a message with a badly formed font size as the first element,
+-  // and a message with a well-formed font size as the second element. We test
+-  // to ensure that the badly formed message is converted to the well-formed
+-  // one.
+-  let testMessages = [
+-    // Single font tag.
+-    ["<font face=\"Arial\" size=\"12\">Test message 1",
+-     "<font face=\"Arial\" size=\"3\">Test message 1"],
+-    // Single font tag with size="<digit>" in innner message.
+-    ["<font face=\"Arial\" size=\"9\">size=\"30\" is a big size.</font>",
+-     "<font face=\"Arial\" size=\"2\">size=\"30\" is a big size.</font>"],
+-    // Single font tag with no face attribute.
+-    ["<font size=\"12\">This message has no font face attribute.",
+-     "<font size=\"3\">This message has no font face attribute."],
+-    // Single font tag with no size attribute.
+-    ["<font face=\"Arial\">This message has no font size attribute.",
+-     "<font face=\"Arial\">This message has no font size attribute."],
+-    // Single font tag with rearranged attribute order.
+-    ["<font size=\"9\" face=\"Arial\">size=\"30\" is a big size.</font>",
+-     "<font size=\"2\" face=\"Arial\">size=\"30\" is a big size.</font>"],
+-    // Multiple font tags.
+-    ["<font face=\"Arial\" size=\"12\">Hello. <font face=\"Consolas\" size=\"40\">World",
+-     "<font face=\"Arial\" size=\"3\">Hello. <font face=\"Consolas\" size=\"7\">World"]
+-  ];
+-
+-  let fakeProtocol = {
+-    id: "fake-proto",
+-    options: {
+-      local_charset: "UTF-8"
+-    },
+-    _getOptionDefault: function(aOption) { return this.options[aOption]; }
+-  };
+-  let fakeImAccount = {name: "test-user"};
+-  // We create a fake conversation object so we can obtain the cleaned up
+-  // message from the conv.writeMessage() call.
+-  let messagePair;
+-  let fakeConversation = {
+-    writeMessage: function(aName, aMessage, aProperties) {
+-      do_check_eq(aMessage, messagePair[1]); // Compare to the good message.
+-    },
+-    updateTyping: function(aStatus, aName) { }
+-  };
+-
+-  let yahooAccount = new yahoo.YahooAccount(fakeProtocol, fakeImAccount);
+-  yahooAccount._conversations.set("test-user", fakeConversation);
+-  for each(let pair in testMessages) {
+-    messagePair = pair;
+-    // Send in the badly formed message.
+-    yahooAccount.receiveMessage("test-user", messagePair[0]);
+-  }
+-  run_next_test();
+-}
+diff --git a/chat/protocols/yahoo/test/test_yahooLoginHelper.js b/chat/protocols/yahoo/test/test_yahooLoginHelper.js
+deleted file mode 100644
+index e4d8bc1b8..000000000
+--- a/chat/protocols/yahoo/test/test_yahooLoginHelper.js
++++ /dev/null
+@@ -1,89 +0,0 @@
+-/* Any copyright is dedicated to the Public Domain.
+- * http://creativecommons.org/publicdomain/zero/1.0/ */
+-
+-Components.utils.import("resource:///modules/ArrayBufferUtils.jsm");
+-Components.utils.import("resource://gre/modules/Services.jsm");
+-Components.utils.import("resource:///modules/yahoo-session.jsm");
+-var yahoo = {};
+-Services.scriptloader.loadSubScript("resource:///modules/yahoo-session.jsm", yahoo);
+-
+-// Preset test values.
+-var kUsername = "testUser";
+-var kPassword = "instantbird";
+-var kPagerIp = "123.456.78.9";
+-var kCrumb = "MG-Z/jNG+Q==";
+-var kChallengeString = "AEF08DBAC33F9EEDABCFEA==";
+-var kYCookie = "OTJmMTQyOTU1ZGQ4MDA3Y2I2ODljMTU5";
+-var kTCookie = "NTdlZmIzY2Q4ODI3ZTc3NTIxYTk1MDhm";
+-var kToken = "MThmMzg3OWM3ODcxMW";
+-
+-var kPagerAddressResponse = "COLO_CAPACITY=1\r\nCS_IP_ADDRESS=" + kPagerIp;
+-var kTokenResponse = "0\r\n" + kToken + "\r\npartnerid=dummyValue";
+-var kCookieResponse = "0\r\ncrumb=" + kCrumb + "\r\nY=" + kYCookie +
+-                        "\r\nT=" + kTCookie + "\r\ncookievalidfor=86400";
+-
+-/* In each test, we override the function that would normally be called next in
+- * the login process. We do this so that we can intercept the login process,
+- * preventing calls to real Yahoo! servers, and do equality testing. */
+-function run_test()
+-{
+-  add_test(test_pagerAddress);
+-  add_test(test_challengeString);
+-  add_test(test_loginToken);
+-  add_test(test_cookies);
+-  run_next_test();
+-}
+-
+-function test_pagerAddress()
+-{
+-  let helper = new yahoo.YahooLoginHelper({}, {});
+-
+-  helper._getChallengeString = function() {
+-    do_check_eq(kPagerIp, helper._session.pagerAddress);
+-    run_next_test();
+-  };
+-
+-  helper._onPagerAddressResponse(kPagerAddressResponse, null);
+-}
+-
+-function test_challengeString()
+-{
+-  let helper = new yahoo.YahooLoginHelper({}, {});
+-
+-  helper._getLoginToken = function() {
+-    do_check_eq(kChallengeString, helper._challengeString);
+-    run_next_test();
+-  };
+-
+-  let response = new yahoo.YahooPacket(yahoo.kPacketType.AuthResponse, 0, 0);
+-  response.addValue(1, helper._username);
+-  response.addValue(94, kChallengeString);
+-  response.addValue(13, 0);
+-  helper._onChallengeStringResponse(response.toArrayBuffer());
+-}
+-
+-function test_loginToken()
+-{
+-  let helper = new yahoo.YahooLoginHelper({}, {});
+-
+-  helper._getCookies = function() {
+-    do_check_eq(kToken, helper._loginToken);
+-    run_next_test();
+-  };
+-
+-  helper._onLoginTokenResponse(kTokenResponse, null);
+-}
+-
+-function test_cookies()
+-{
+-  let helper = new yahoo.YahooLoginHelper({}, {});
+-
+-  helper._sendPagerAuthResponse = function() {
+-    do_check_eq(kCrumb, helper._crumb);
+-    do_check_eq(kYCookie, helper._session.yCookie);
+-    do_check_eq(kTCookie, helper._session.tCookie);
+-    run_next_test();
+-  };
+-
+-  helper._onLoginCookiesResponse(kCookieResponse, null);
+-}
+diff --git a/chat/protocols/yahoo/test/test_yahoopacket.js b/chat/protocols/yahoo/test/test_yahoopacket.js
+deleted file mode 100644
+index 7908c4429..000000000
+--- a/chat/protocols/yahoo/test/test_yahoopacket.js
++++ /dev/null
+@@ -1,217 +0,0 @@
+-/* Any copyright is dedicated to the Public Domain.
+- * http://creativecommons.org/publicdomain/zero/1.0/ */
+-
+-Components.utils.import("resource:///modules/ArrayBufferUtils.jsm");
+-Components.utils.import("resource://gre/modules/Services.jsm");
+-Components.utils.import("resource:///modules/yahoo-session.jsm");
+-var yahoo = {};
+-Services.scriptloader.loadSubScript("resource:///modules/yahoo-session.jsm", yahoo);
+-
+-var kPacketIdBytes = StringToBytes(yahoo.kPacketIdentfier);
+-var kHelloKey = 1;
+-var kHelloValue = "Hello";
+-var kWorldKey = 20;
+-var kWorldValue = "World";
+-var kNumberKey = 4;
+-var kNumberValue = 32;
+-var kParamsKey = 60;
+-var kParam1Value = "param1";
+-var kParam2Value = "param2";
+-var kPacketDataString = "1\xC0\x80Hello\xC0\x8020\xC0\x80World\xC0\x80" +
+-                          "4\xC0\x8032\xC0\x8060\xC0\x80param1\xC0\x80" +
+-                          "60\xC0\x80param2\xC0\x80";
+-
+-function run_test()
+-{
+-  add_test(test_headerCreation);
+-  add_test(test_fullPacketCreation);
+-  add_test(test_packetDecoding);
+-  add_test(test_extractPackets);
+-  add_test(test_malformedPacketExtraction);
+-
+-  run_next_test();
+-}
+-
+-function test_headerCreation()
+-{
+-  let packetLength = 0;
+-  // Random numbers.
+-  let serviceNumber = 0x57;
+-  let status = 0x04;
+-  let sessionId = 0x57842390;
+-
+-  let packet = new yahoo.YahooPacket(serviceNumber, status, sessionId);
+-  let buf = packet.toArrayBuffer();
+-  let view = new DataView(buf);
+-
+-  // Ensure that the first 4 bytes contain the YMSG identifier.
+-  for (let i = 0; i < kPacketIdBytes.length; ++i)
+-    do_check_eq(kPacketIdBytes[i], view.getUint8(i));
+-
+-  do_check_eq(yahoo.kProtocolVersion, view.getUint16(4));
+-  do_check_eq(yahoo.kVendorId, view.getUint16(6));
+-  do_check_eq(packetLength, view.getUint16(8));
+-  do_check_eq(serviceNumber, view.getUint16(10));
+-  do_check_eq(status, view.getUint32(12));
+-  do_check_eq(sessionId, view.getUint32(16));
+-
+-  run_next_test();
+-}
+-
+-function test_fullPacketCreation()
+-{
+-  packetLength = kPacketDataString.length;
+-  // Random numbers.
+-  let serviceNumber = 0x55;
+-  let status = 0x02;
+-  let sessionId = 0x12567800;
+-
+-  let packet = new yahoo.YahooPacket(serviceNumber, status, sessionId);
+-  packet.addValue(kHelloKey, kHelloValue);
+-  packet.addValue(kWorldKey, kWorldValue);
+-  packet.addValue(kNumberKey, kNumberValue);
+-  packet.addValues(kParamsKey, [kParam1Value, kParam2Value]);
+-  let buf = packet.toArrayBuffer();
+-  let view = new DataView(buf);
+-
+-  // Header check.
+-
+-  // Ensure that the first 4 bytes contain the YMSG identifier.
+-  for (let i = 0; i < kPacketIdBytes.length; ++i)
+-    do_check_eq(kPacketIdBytes[i], view.getUint8(i));
+-
+-  do_check_eq(yahoo.kProtocolVersion, view.getUint16(4));
+-  do_check_eq(yahoo.kVendorId, view.getUint16(6));
+-  do_check_eq(packetLength, view.getUint16(8));
+-  do_check_eq(serviceNumber, view.getUint16(10));
+-  do_check_eq(status, view.getUint32(12));
+-  do_check_eq(sessionId, view.getUint32(16));
+-
+-  // Packet data check.
+-  let dataBytes = StringToBytes(kPacketDataString);
+-  for (let i = 0; i < dataBytes.length; ++i)
+-    do_check_eq(dataBytes[i], view.getUint8(yahoo.kPacketHeaderSize + i));
+-  run_next_test()
+-}
+-
+-function test_packetDecoding()
+-{
+-  let packetLength = kPacketDataString.length;
+-  // Random numbers.
+-  let serviceNumber = 0x20;
+-  let status = 0x06;
+-  let sessionId = 0x13319AB2;
+-
+-  let buf = new ArrayBuffer(yahoo.kPacketHeaderSize + packetLength);
+-  let view = new DataView(buf);
+-
+-  for (let i = 0; i < kPacketIdBytes.length; ++i)
+-    view.setUint8(i, kPacketIdBytes[i]);
+-
+-  view.setUint16(4, yahoo.kProtocolVersion);
+-  view.setUint16(6, yahoo.kVendorId);
+-  view.setUint16(8, packetLength);
+-  view.setUint16(10, serviceNumber);
+-  view.setUint32(12, status);
+-  view.setUint32(16, sessionId);
+-
+-  let dataBuf = BytesToArrayBuffer(StringToBytes(kPacketDataString));
+-  copyBytes(buf, dataBuf, 20);
+-
+-  // Now we decode and test.
+-  let packet = new yahoo.YahooPacket();
+-  packet.fromArrayBuffer(buf);
+-
+-  // Test header information.
+-  do_check_eq(serviceNumber, packet.service);
+-  do_check_eq(status, packet.status);
+-  do_check_eq(sessionId, packet.sessionId);
+-
+-  // Test the getting of single packet data values.
+-  do_check_eq(kHelloValue, packet.getValue(kHelloKey));
+-  do_check_eq(kWorldValue, packet.getValue(kWorldKey));
+-  do_check_eq(kNumberValue, packet.getValue(kNumberKey));
+-
+-  // Test the getting of multiple values with a single key.
+-  let multiValue = packet.getValues(kParamsKey);
+-  do_check_eq(2, multiValue.length);
+-  do_check_eq(kParam1Value, multiValue[0]);
+-  do_check_eq(kParam2Value, multiValue[1]);
+-
+-  // Test if certain keys are non-existant.
+-  do_check_true(packet.hasKey(kHelloKey));
+-  do_check_false(packet.hasKey(500)); // There is no key 500.
+-
+-  run_next_test();
+-}
+-
+-function test_extractPackets()
+-{
+-  // Some constants for each packet.
+-  const kP1Service = 0x47;
+-  const kP1Status = 0;
+-  const kP1SessionId = 0x12345678;
+-  // Used for testing packet verification.
+-  const kP1FuzzerKey = 42;
+-  const kP1FuzzerValue = "I am using the YMSG protocol!";
+-
+-  const kP2Service = 0x57;
+-  const kP2Status = 5;
+-  const kP2SessionId = 0x87654321;
+-
+-  // First, create two packets and obtain their buffers.
+-  let packet1 = new yahoo.YahooPacket(kP1Service, kP1Status, kP1SessionId);
+-  packet1.addValue(kHelloKey, kHelloValue);
+-  packet1.addValue(kP1FuzzerKey, kP1FuzzerValue);
+-  let packet1Buffer = packet1.toArrayBuffer();
+-
+-  let packet2 = new yahoo.YahooPacket(kP2Service, kP2Status, kP2SessionId);
+-  packet2.addValue(kWorldKey, kWorldValue);
+-  let packet2Buffer = packet2.toArrayBuffer();
+-
+-  // Create one full buffer with both packets inside.
+-  let fullBuffer = new ArrayBuffer(packet1Buffer.byteLength +
+-                                   packet2Buffer.byteLength);
+-  copyBytes(fullBuffer, packet1Buffer);
+-  copyBytes(fullBuffer, packet2Buffer, packet1Buffer.byteLength);
+-
+-  // Now, run the packets through the extractPackets() method.
+-  let [extractedPackets, bytesHandled] =
+-      yahoo.YahooPacket.extractPackets(fullBuffer);
+-  do_check_eq(2, extractedPackets.length);
+-
+-  // Packet 1 checks.
+-  let p1 = extractedPackets[0];
+-  do_check_eq(kP1Service, p1.service);
+-  do_check_eq(kP1Status, p1.status);
+-  do_check_eq(kP1SessionId, p1.sessionId);
+-  do_check_true(p1.hasKey(kHelloKey));
+-  do_check_eq(kHelloValue, p1.getValue(kHelloKey));
+-
+-  // Packet 2 checks.
+-  let p2 = extractedPackets[1];
+-  do_check_eq(kP2Service, p2.service);
+-  do_check_eq(kP2Status, p2.status);
+-  do_check_eq(kP2SessionId, p2.sessionId);
+-  do_check_true(p2.hasKey(kWorldKey));
+-  do_check_eq(kWorldValue, p2.getValue(kWorldKey));
+-
+-  // Check if all the bytes were handled.
+-  do_check_eq(fullBuffer.byteLength, bytesHandled);
+-
+-  run_next_test();
+-}
+-
+-function test_malformedPacketExtraction()
+-{
+-  const kInvalidPacketData = "MSYG1\xC0\x80Hello\xC0\x8020\xC0\x80World\xC0\x80";
+-  let buffer = BytesToArrayBuffer(StringToBytes(kInvalidPacketData));
+-  let malformed = false;
+-  try {
+-    yahoo.YahooPacket.extractPackets(buffer);
+-  } catch(e) {
+-    malformed = true;
+-  }
+-  do_check_true(malformed);
+-  run_next_test();
+-}
+diff --git a/chat/protocols/yahoo/test/xpcshell.ini b/chat/protocols/yahoo/test/xpcshell.ini
+deleted file mode 100644
+index f4b464e61..000000000
+--- a/chat/protocols/yahoo/test/xpcshell.ini
++++ /dev/null
+@@ -1,7 +0,0 @@
+-[DEFAULT]
+-head =
+-tail =
+-
+-[test_yahooAccount.js]
+-[test_yahooLoginHelper.js]
+-[test_yahoopacket.js]
+diff --git a/chat/protocols/yahoo/yahoo-session.jsm b/chat/protocols/yahoo/yahoo-session.jsm
+deleted file mode 100644
+index cc9612036..000000000
+--- a/chat/protocols/yahoo/yahoo-session.jsm
++++ /dev/null
+@@ -1,1156 +0,0 @@
+-/* This Source Code Form is subject to the terms of the Mozilla Public
+- * License, v. 2.0. If a copy of the MPL was not distributed with this
+- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+-
+-this.EXPORTED_SYMBOLS = ["YahooSession"];
+-
+-var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+-
+-Cu.import("resource://gre/modules/FileUtils.jsm");
+-Cu.import("resource://gre/modules/Http.jsm");
+-Cu.import("resource://gre/modules/NetUtil.jsm");
+-Cu.import("resource:///modules/ArrayBufferUtils.jsm");
+-Cu.import("resource:///modules/imServices.jsm");
+-Cu.import("resource:///modules/imXPCOMUtils.jsm");
+-Cu.import("resource:///modules/socket.jsm");
+-
+-XPCOMUtils.defineLazyGetter(this, "_", () =>
+-  l10nHelper("chrome://chat/locale/yahoo.properties")
+-);
+-
+-XPCOMUtils.defineLazyServiceGetter(this, "imgTools",
+-                                   "@mozilla.org/image/tools;1", "imgITools");
+-
+-var kProtocolVersion = 16;
+-var kVendorId = 0;
+-
+-var kPacketDataDelimiter = "\xC0\x80";
+-var kPacketIdentifier = "YMSG";
+-var kPacketHeaderSize = 20;
+-var kProfileIconWidth = 96;
+-
+-// These constants are used by the icon uploading code since the Yahoo! file
+-// transfer server is used for user icon uploads.
+-var kFileTransferHost = "filetransfer.msg.yahoo.com";
+-var kFileTransferPort = 80;
+-
+-var kPacketType = {
+-  // Sent by a client when logging off of the Yahoo! network.
+-  Logoff:         0x02,
+-  // Sent by a client when a message is sent to a buddy.
+-  Message:        0x06,
+-  // Sent to the pager server once per hour.
+-  Ping:           0x12,
+-  // Used for inviting others to a conference.
+-  ConfInvite:     0x18,
+-  // Used as a notification when you or someone else joins a conference room.
+-  ConfLogon:      0x19,
+-  // Used as a notification when you or someone else leaves a conference room.
+-  ConfLogoff:     0x1b,
+-  // This is sent by the client when additional users are invited to the
+-  // conference, but it can be sent as the first invite as well.
+-  ConfAddInvite:  0x1c,
+-  // Broadcast to all users in a conference room when someone posts a message.
+-  ConfMessage:    0x1d,
+-  // Used for typing notifications.
+-  Notify:         0x4b,
+-  // These two are used during initial authentication with the pager server.
+-  AuthResponse:   0x54,
+-  Auth:           0x57,
+-  // Buddy list controls.
+-  AddBuddy:       0x83,
+-  RemoveBuddy:    0x84,
+-  // This is sent when you reject a Yahoo! user's buddy request.
+-  BuddyReqReject: 0x86,
+-  // Sent to the server once every minute, telling it here are still alive.
+-  KeepAlive:      0x8A,
+-  // This is sent when we request a buddy icon.
+-  Picture:        0xbe,
+-  // This is sent after a profile picture has been successfully uploaded.
+-  PictureUpload:  0xc2,
+-  // This is sent whenever a buddy changes their status.
+-  StatusUpdate:   0xc6,
+-  // This is sent when we update our icon.
+-  AvatarUpdate:   0xc7,
+-  // This is sent when someone wishes to become your buddy.
+-  BuddyAuth:      0xd6,
+-  // Holds the initial status of all buddies when a user first logs in.
+-  StatusInitial:  0xf0,
+-  // Contains the buddy list sent from the server.
+-  List:           0xf1,
+-  // Sent back to the pager server after each received message. Sending this
+-  // prevents echoed messages when chatting with the official Yahoo! client.
+-  MessageAck:     0xfb
+-};
+-
+-var kPacketStatuses = {
+-  ServerAck: 0x1,
+-  Typing: 0x16
+-};
+-
+-// Each Yahoo! error code is mapped to a two-element array. The first element
+-// contains the last part of the name of its localized string. This is appended
+-// to "login.error." to obtain the string. The second element is the
+-// Instantbird error that is given to the error handler.
+-var kLoginStatusErrors = {
+-  "1212" : ["badCredentials",
+-            Ci.prplIAccount.ERROR_AUTHENTICATION_FAILED],
+-  "1213" : ["accountLockedFailed",
+-            Ci.prplIAccount.ERROR_AUTHENTICATION_FAILED],
+-  "1218" : ["accountDeactivated",
+-            Ci.prplIAccount.ERROR_AUTHENTICATION_FAILED],
+-  "1235" : ["usernameNotExist",
+-            Ci.prplIAccount.ERROR_INVALID_USERNAME],
+-  "1236" : ["accountLockedGeneral",
+-            Ci.prplIAccount.ERROR_AUTHENTICATION_FAILED]
+-};
+-
+-// These are the status codes that buddies can send us.
+-var kBuddyStatuses = {
+-  // Available.
+-  "0"   : Ci.imIStatusInfo.STATUS_AVAILABLE,
+-  // Be right back.
+-  "1"   : Ci.imIStatusInfo.STATUS_AWAY,
+-  // Busy.
+-  "2"   : Ci.imIStatusInfo.STATUS_UNAVAILABLE,
+-    // Not at home.
+-  "3"   : Ci.imIStatusInfo.STATUS_AWAY,
+-  // Not at desk.
+-  "4"   : Ci.imIStatusInfo.STATUS_AWAY,
+-  // Not in office.
+-  "5"   : Ci.imIStatusInfo.STATUS_AWAY,
+-  // On phone.
+-  "6"   : Ci.imIStatusInfo.STATUS_AWAY,
+-  // On vacation.
+-  "7"   : Ci.imIStatusInfo.STATUS_AWAY,
+-  // Out to lunch.
+-  "8"   : Ci.imIStatusInfo.STATUS_AWAY,
+-  // Stepped out.
+-  "9"   : Ci.imIStatusInfo.STATUS_AWAY,
+-    // Invisible.
+-  "12"  : Ci.imIStatusInfo.STATUS_INVISIBLE,
+-  // Custom status.
+-  "99"  : Ci.imIStatusInfo.STATUS_AWAY,
+-  // Idle.
+-  "999" : Ci.imIStatusInfo.STATUS_IDLE
+-};
+-
+-/* The purpose of the YahooSession object is to serve as a gateway between the
+- * protocol plug-in and the Yahoo! Messenger servers. Anytime an object outside
+- * of this file wishes to communicate with the servers, it should do it through
+- * one of the methods provided by YahooSession. By centralizing such network
+- * access, we can easily catch errors, and ensure that communication is handled
+- * correctly. */
+-function YahooSession(aAccount)
+-{
+-  this._account = aAccount;
+-  this.binaryMode = true;
+-}
+-YahooSession.prototype = {
+-  __proto__: Socket,
+-  _account: null,
+-  _socket: null,
+-  _username: null,
+-  // This is the IPv4 address to the pager server which is the gateway into the
+-  // Yahoo! Messenger network.
+-  pagerAddress: null,
+-  // The session ID is obtained during the login process and is maintained
+-  // throughout the session. This helps the pager server identify the client.
+-  sessionId: null,
+-  // The T and Y cookies obtained by the YahooLoginHelper during login.
+-  tCookie: null,
+-  yCookie: null,
+-
+-  // Public methods.
+-  login: function() {
+-    this._account.reportConnecting();
+-    new YahooLoginHelper(this).login(this._account);
+-  },
+-
+-  sendPacket: function(aPacket) {
+-    this.sendBinaryData(aPacket.toArrayBuffer(), aPacket.toString());
+-  },
+-
+-  addBuddyToServer: function(aBuddy) {
+-    let packet = new YahooPacket(kPacketType.AddBuddy, 0, this.sessionId);
+-    // We leave this invite message empty. Any message placed here will
+-    // annoyingly be sent to the invitee when they accept the invite.
+-    packet.addValue(14, "");
+-    packet.addValue(65, aBuddy.tag.name);
+-    packet.addValue(97, "1"); // UTF-8 encoding.
+-    packet.addValue(1, this._account.cleanUsername);
+-    // The purpose of these two values are unknown.
+-    packet.addValue(302, "319");
+-    packet.addValue(300, "319");
+-    packet.addValue(7, aBuddy.userName);
+-    // The purpose of these three values are also unknown.
+-    packet.addValue(334, "0");
+-    packet.addValue(301, "319");
+-    packet.addValue(303, "319");
+-    this.sendPacket(packet);
+-  },
+-
+-  removeBuddyFromServer: function(aBuddy) {
+-    let packet = new YahooPacket(kPacketType.RemoveBuddy, 0, this.sessionId);
+-    packet.addValue(1, this._account.cleanUsername);
+-    packet.addValue(7, aBuddy.userName);
+-    packet.addValue(65, aBuddy.tag.name);
+-    this.sendPacket(packet);
+-  },
+-
+-  setStatus: function(aStatus, aMessage) {
+-    let packet = new YahooPacket(kPacketType.StatusUpdate, 0, this.sessionId);
+-
+-    // When a custom status message is used, key 10 is set to 99, and key 97
+-    // is set to 1. Otherwise, key 10 is set to our current status code.
+-    if (aMessage && aMessage.length > 0) {
+-      packet.addValue(10, "99");
+-      packet.addValue(97, "1");
+-    } else {
+-      let statusCode;
+-      switch(aStatus) {
+-        // Available
+-        case Ci.imIStatusInfo.STATUS_AVAILABLE:
+-        case Ci.imIStatusInfo.STATUS_MOBILE:
+-          statusCode = "0";
+-          break;
+-        // Away
+-        case Ci.imIStatusInfo.STATUS_AWAY:
+-          statusCode = "1";
+-          break;
+-        // Busy
+-        case Ci.imIStatusInfo.STATUS_UNAVAILABLE:
+-          statusCode = "2";
+-          break;
+-        // Invisible
+-        case Ci.imIStatusInfo.STATUS_INVISIBLE:
+-          statusCode = "12";
+-          break;
+-        // Idle
+-        case Ci.imIStatusInfo.STATUS_IDLE:
+-          statusCode = "999";
+-          break;
+-      }
+-      packet.addValue(10, statusCode);
+-    }
+-
+-    // Key 19 is always set as the status messgae, even when the message is
+-    // empty. If key 10 is set to 99, the message is used.
+-    packet.addValue(19, aMessage);
+-
+-    // Key 47 is always set to either 0, if we are available, or 1, if we are
+-    // not available. The value is used by the server if key 10 is set to 99.
+-    // Otherwise, the value of key 10 is used to determine our status.
+-    packet.addValue(47, (aStatus == Ci.imIStatusInfo.STATUS_AVAILABLE) ?
+-                    "0" : "1");
+-    this.sendPacket(packet);
+-  },
+-
+-  sendChatMessage: function(aName, aMessage) {
+-    let packet = new YahooPacket(kPacketType.Message, 0, this.sessionId);
+-    // XXX Key 0 is the user ID, and key 1 is the active ID. We need to find
+-    // the difference between these two. Alias maybe?
+-    packet.addValue(0, this._account.cleanUsername);
+-    packet.addValue(1, this._account.cleanUsername);
+-    packet.addValue(5, aName);
+-    packet.addValue(14, aMessage);
+-    this.sendPacket(packet);
+-  },
+-
+-  sendConferenceMessage: function(aRecipients, aRoom, aMessage) {
+-    let packet = new YahooPacket(kPacketType.ConfMessage, 0, this.sessionId);
+-    packet.addValue(1, this._account.cleanUsername);
+-    packet.addValues(53, aRecipients);
+-    packet.addValue(57, aRoom);
+-    packet.addValue(14, aMessage);
+-    packet.addValue(97, "1"); // Use UTF-8 encoding.
+-    this.sendPacket(packet);
+-  },
+-
+-  sendTypingStatus: function(aBuddyName, aIsTyping) {
+-    let packet = new YahooPacket(kPacketType.Notify, kPacketStatuses.Typing,
+-                                 this.sessionId);
+-    packet.addValue(1, this._account.cleanUsername);
+-    packet.addValue(5, aBuddyName);
+-    packet.addValue(13, aIsTyping ? "1" : "0");
+-    packet.addValue(14, " "); // Key 14 contains a single space.
+-    packet.addValue(49, "TYPING");
+-    this.sendPacket(packet);
+-  },
+-
+-  acceptConferenceInvite: function(aOwner, aRoom, aParticipants) {
+-    let packet = new YahooPacket(kPacketType.ConfLogon, 0, this.sessionId);
+-    packet.addValue(1, this._account.cleanUsername);
+-    packet.addValue(57, aRoom);
+-    packet.addValues(3, aParticipants);
+-    this.sendPacket(packet);
+-  },
+-
+-  createConference: function(aRoom) {
+-    let packet = new YahooPacket(kPacketType.ConfLogon, 0, this.sessionId);
+-    packet.addValue(1, this._account.cleanUsername);
+-    packet.addValue(3, this._account.cleanUsername);
+-    packet.addValue(57, aRoom);
+-    this.sendPacket(packet);
+-  },
+-
+-  inviteToConference: function(aInvitees, aRoom, aParticipants, aMessage) {
+-    let packet = new YahooPacket(kPacketType.ConfAddInvite, 0, this.sessionId);
+-    packet.addValue(1, this._account.cleanUsername);
+-    packet.addValues(51, aInvitees);
+-    packet.addValues(53, aParticipants);
+-    packet.addValue(57, aRoom);
+-    packet.addValue(58, aMessage);
+-    packet.addValue(13, "0");
+-    this.sendPacket(packet);
+-  },
+-
+-  sendConferenceLogoff: function(aName, aParticipants, aRoom) {
+-    let packet = new YahooPacket(kPacketType.ConfLogoff, 0, this.sessionId);
+-    packet.addValue(1, aName);
+-    packet.addValues(3, aParticipants);
+-    packet.addValue(57, aRoom);
+-    this.sendPacket(packet);
+-  },
+-
+-  setProfileIcon: function(aFileName) {
+-    // If we have an empty filename, remove the icon from the server.
+-    if (!aFileName) {
+-      let packet = new YahooPacket(kPacketType.AvatarUpdate, 0, this.sessionId);
+-      packet.addValue(3, this._account.cleanUsername);
+-      packet.addValue(213, 0);
+-      this.sendPacket(packet);
+-      return;
+-    }
+-    // Try to get a handle to the icon file.
+-    let file = FileUtils.getFile("ProfD", [aFileName]);
+-    let type = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService)
+-                                        .getTypeFromFile(file);
+-    NetUtil.asyncFetch({
+-        uri: NetUtil.newURI(file),
+-        contentPolicyType: Ci.nsIContentPolicy.TYPE_IMAGE,
+-        securityFlags: Ci.nsILoadInfo.SEC_NORMAL,
+-        loadUsingSystemPrincipal: true
+-      }, (aStream, aStatus) => {
+-        if (!Components.isSuccessCode(aStatus)) {
+-          throw "Could not access icon file.";
+-          return;
+-        }
+-        let image = imgTools.decodeImage(aStream, type);
+-        let uploader = new YahooProfileIconUploader(this._account, this,
+-                                                    aFileName, image);
+-        uploader.uploadIcon();
+-      });
+-  },
+-
+-  requestBuddyIcon: function(aName) {
+-    let packet = new YahooPacket(kPacketType.Picture, 0, this.sessionId);
+-    packet.addValue(1, this._account.cleanUsername);
+-    packet.addValue(5, aName); // The name of the buddy.
+-    packet.addValue(13, "1"); // "1" means we wish to request an icon.
+-    this.sendPacket(packet);
+-  },
+-
+-  acceptBuddyRequest: function(aRequest) {
+-    let packet = new YahooPacket(kPacketType.BuddyAuth, 0, this.sessionId);
+-    packet.addValue(1, this._account.cleanUsername);
+-    packet.addValue(5, aRequest.userName);
+-    // Misc. Unknown flags.
+-    packet.addValue(13, 1);
+-    packet.addValue(334, 0);
+-    this.sendPacket(packet);
+-
+-    // If someone wants to add us as a buddy, place them under the default
+-    // tag. Also, we make sure that the buddy doesn't already exist in the
+-    // list in case of a server acknowledgement.
+-    if (!this._account.hasBuddy(aRequest.userName))
+-      this._account.addBuddy(Services.tags.defaultTag, aRequest.userName);
+-  },
+-
+-  denyBuddyRequest: function(aRequest) {
+-    let packet = new YahooPacket(kPacketType.BuddyReqReject, 0, this.sessionId);
+-    packet.addValue(1, this._account.cleanUsername);
+-    packet.addValue(7, aRequest.userName);
+-    packet.addValue(14, "");
+-    this.sendPacket(packet);
+-  },
+-
+-  sendKeepAlive: function() {
+-    let packet = new YahooPacket(kPacketType.KeepAlive, 0, this.sessionId);
+-    packet.addValue(0, this._account.cleanUsername);
+-    this.sendBinaryData(packet.toArrayBuffer());
+-  },
+-
+-  sendPing: function() {
+-    let packet = new YahooPacket(kPacketType.Ping, 0, this.sessionId);
+-    this.sendBinaryData(packet.toArrayBuffer());
+-  },
+-
+-  // Callbacks.
+-  onLoginComplete: function() {
+-    this._account.reportConnected();
+-    this._account.onLoginComplete();
+-  },
+-
+-  onSessionError: function(aError, aMessage) {
+-    this._account.reportDisconnecting(aError, aMessage);
+-    if (!this.disconnected)
+-      this.disconnect();
+-    this._account.reportDisconnected();
+-  },
+-
+-  // Private methods.
+-
+-  // Socket Event Callbacks.
+-  LOG: function(aString) { return this._account.LOG(aString); },
+-
+-  DEBUG: function(aString) { return this._account.DEBUG(aString); },
+-
+-  onConnection: function() {
+-    // We send an authentication request packet as soon as we connect to the
+-    // pager server.
+-    let packet = new YahooPacket(kPacketType.Auth, 0, 0);
+-    packet.addValue(1, this._account.cleanUsername);
+-    this.sendPacket(packet);
+-  },
+-
+-  onConnectionTimedOut: function() {
+-    this.onSessionError(Ci.prplIAccount.NETWORK_ERROR, "");
+-  },
+-
+-  onConnectionReset: function() {
+-    this.onSessionError(Ci.prplIAccount.NETWORK_ERROR, "");
+-  },
+-
+-  // Called when the other end has closed the connection.
+-  onConnectionClosed: function() {
+-    if (!this._account.connected)
+-      return;
+-    this._account.reportDisconnecting(Ci.prplIAccount.NO_ERROR, "");
+-    this._account.reportDisconnected();
+-  },
+-
+-  onBinaryDataReceived: function(aData) {
+-    let packets;
+-    let bytesHandled;
+-    try {
+-      [packets, bytesHandled] = YahooPacket.extractPackets(aData);
+-    } catch(e) {
+-      this._account.ERROR(e);
+-      this.onSessionError(Ci.prplIAccount.NETWORK_ERROR, "");
+-      return 0;
+-    }
+-
+-    for each (let packet in packets) {
+-      this._account.LOG("Received Packet:\n" + packet.toString());
+-      if (YahooPacketHandler.hasOwnProperty(packet.service)) {
+-        try {
+-          YahooPacketHandler[packet.service].call(this._account, packet);
+-        } catch(e) {
+-          this._account.ERROR(e);
+-        }
+-      } else {
+-        this._account.WARN("No handler for Yahoo! packet " +
+-                           packet.service.toString(16) + ".");
+-      }
+-    }
+-    return bytesHandled;
+-  }
+-};
+-
+-/* The purpose of YahooLoginHelper is to separate the complicated login logic
+- * from the YahooSession object. Logging in on Yahoo!'s network is the most
+- * complicated stage of a session due to the authentication system that is
+- * employed. The login steps are listed below.
+- *
+- * 1) Get the address of a "pager" server. This pager will be our gateway to
+- *    the network.
+- *
+- * 2) Obtain the challenge string from the pager. This string is used to help
+- *    create the base64 response string needed for the final step.
+- *
+- * 3) Obtain a token from the login server via HTTP.
+- *
+- * 4) Obtain the login crumb, Y-Cookie, and T-Cookie from the login server via
+- *    HTTP. These will also be used in the final response packet to the pager.
+- *
+- * 5) Create the base64 response string from the MD5 hash of the crumb and
+- *    challenge string, and build a packet containing the username, password,
+- *    response string, version numbers, crumb, and cookies, sending it to the
+- *    pager for a final authenticatcation.
+- *
+- * If all goes well after the 5th step, the user is considered logged in. */
+-function YahooLoginHelper(aSession)
+-{
+-  this._session = aSession;
+-}
+-YahooLoginHelper.prototype = {
+-  // YahooSession object passed in constructor.
+-  _session: null,
+-  // YahooAccount object passed to login().
+-  _account: null,
+-  // The username, stripped of any @yahoo.com or @yahoo.co.jp suffix.
+-  _username: null,
+-  // The authentication challenge string sent from the Yahoo!'s login server.
+-  _challengeString: null,
+-  // The authentication token sent from Yahoo!'s login server.
+-  _loginToken: null,
+-  // Crumb sent from Yahoo!'s login server, and used in the final authentication
+-  // request to the pager server.
+-  _crumb: null,
+-
+-  // Public methods.
+-  login: function(aAccount) {
+-    this._account = aAccount;
+-    this._getPagerAddress();
+-  },
+-
+-  // Private methods.
+-  _getPagerAddress: function() {
+-    let options = {
+-      onLoad: this._onPagerAddressResponse.bind(this),
+-      onError: this._onHttpError.bind(this)
+-    }
+-    httpRequest(this._account._protocol.pagerRequestUrl, options);
+-  },
+-
+-  _getChallengeString: function() {
+-    let port = this._account.getInt("port");
+-    this._session.connect(this._session.pagerAddress, port);
+-    // We want to handle a challenge string when the server responds.
+-    this._session.onBinaryDataReceived =
+-      this._onChallengeStringResponse.bind(this);
+-  },
+-
+-  _getLoginToken: function() {
+-    // TODO - Simplify this using map and join.
+-    let url = this._account._protocol.loginTokenGetUrl;
+-    url += "?src=ymsgr&";
+-    url += "login=" + percentEncode(this._account.cleanUsername) + "&";
+-    url += "passwd=" + percentEncode(this._account.imAccount.password) + "&";
+-    url += "chal=" + percentEncode(this._challengeString);
+-
+-    let options = {
+-      onLoad: this._onLoginTokenResponse.bind(this),
+-      onError: this._onHttpError.bind(this)
+-    }
+-    httpRequest(url, options);
+-  },
+-
+-  _getCookies: function() {
+-    // TODO - Simplify this using map and join.
+-    let url = this._account._protocol.loginTokenLoginUrl;
+-    url += "?src=ymsgr&";
+-    url += "token=" + this._loginToken;
+-
+-    let options = {
+-      onLoad: this._onLoginCookiesResponse.bind(this),
+-      onError: this._onHttpError.bind(this)
+-    }
+-    httpRequest(url, options);
+-  },
+-
+-  _sendPagerAuthResponse: function() {
+-    let response = this._calculatePagerResponse();
+-    let packet = new YahooPacket(kPacketType.AuthResponse, 0,
+-                                 this._session.sessionId);
+-    // Build the key/value pairs.
+-    packet.addValue(1, this._account.cleanUsername);
+-    packet.addValue(0, this._account.cleanUsername);
+-    packet.addValue(277, this._session.yCookie);
+-    packet.addValue(278, this._session.tCookie);
+-    packet.addValue(307, response);
+-    packet.addValue(244, this._account.protocol.buildId);
+-    packet.addValue(2, this._account.cleanUsername);
+-    packet.addValue(2, "1");
+-    packet.addValue(98, "us");
+-    this._session.sendPacket(packet);
+-    // We want to handle a final login confirmation packet when the server
+-    // responds.
+-    this._session.onBinaryDataReceived = this._onFinalLoginResponse.bind(this);
+-  },
+-
+-  _calculatePagerResponse: function() {
+-    let hasher = Cc["@mozilla.org/security/hash;1"]
+-                   .createInstance(Ci.nsICryptoHash);
+-    hasher.init(hasher.MD5);
+-
+-    let crypt = this._crumb + this._challengeString;
+-    let cryptData = StringToBytes(crypt);
+-    hasher.update(cryptData, cryptData.length);
+-
+-    // The protocol requires replacing + with ., / with _, and = with - within
+-    // the base64 response string.
+-    return btoa(hasher.finish(false)).replace(/\+/g, ".").replace(/\//g, "_")
+-                                     .replace(/=/g, "-");
+-  },
+-
+-  _handleLoginError: function(aErrorCode) {
+-    let errorInfo = kLoginStatusErrors[aErrorCode];
+-    let errorMessage;
+-    let error;
+-
+-    // If we find information on the error code we received, we will use that
+-    // information. If the error wasn't found in our error table, just throw a
+-    // generic error with the code included.
+-    if (errorInfo) {
+-      errorMessage = _("login.error." + errorInfo[0]);
+-      error = errorInfo[1];
+-    } else {
+-      errorMessage = _("login.error.unknown", aErrorCode);
+-      error = Ci.prplIAccount.ERROR_OTHER_ERROR;
+-      // We also throw a console error because we didn't expect
+-      // this error code.
+-      this._account.ERROR("Received unknown error from pager server. Code: " +
+-                          aErrorCode);
+-    }
+-    this._session.onSessionError(error, errorMessage);
+-  },
+-
+-  _onHttpError: function(aError, aStatusText, aXHR) {
+-    this._session.onSessionError(Ci.prplIAccount.NETWORK_ERROR,
+-                                 _("network.error.http"));
+-  },
+-
+-  // HTTP Response Callbacks.
+-  _onPagerAddressResponse: function(aResponse, aXHR) {
+-    this._session.pagerAddress =
+-      aResponse.substring(aResponse.lastIndexOf("=") + 1);
+-    this._getChallengeString();
+-  },
+-
+-  _onLoginTokenResponse: function(aResponse, aXHR) {
+-    let responseParams = aResponse.split("\r\n");
+-    // Status code "0" means success.
+-    let statusCode = responseParams[0];
+-    if (statusCode != "0") {
+-      this._handleLoginError(statusCode);
+-      return;
+-    }
+-
+-    this._loginToken = responseParams[1].replace("ymsgr=", "");
+-    this._getCookies();
+-  },
+-
+-  _onLoginCookiesResponse: function(aResponse, aXHR) {
+-    let responseParams = aResponse.split("\r\n");
+-    // Status code "0" means success.
+-    let statusCode = responseParams[0];
+-    if (statusCode != "0") {
+-      this._handleLoginError(statusCode);
+-      return;
+-    }
+-
+-    this._crumb = responseParams[1].replace("crumb=", "");
+-    // Remove the "Y=" bit.
+-    this._session.yCookie = responseParams[2].substring(2);
+-    // Remove the "T=" bit.
+-    this._session.tCookie = responseParams[3].substring(2);
+-    this._sendPagerAuthResponse();
+-  },
+-
+-  // TCP Response Callbacks.
+-  _onChallengeStringResponse: function(aData) {
+-    let packet = new YahooPacket();
+-    packet.fromArrayBuffer(aData);
+-    // The value of the challenge string is associated with key 94.
+-    this._challengeString = packet.getValue(94);
+-    this._session.sessionId = packet.sessionId;
+-    this._getLoginToken();
+-  },
+-
+-  _onFinalLoginResponse: function(aData) {
+-    this._session.onLoginComplete();
+-    // We need to restore data handling to the YahooSession object since our
+-    // login steps are complete.
+-    this._session.onBinaryDataReceived =
+-      YahooSession.prototype.onBinaryDataReceived.bind(this._session);
+-  }
+-};
+-
+-/* The YahooPacket class represents a single Yahoo! Messenger data packet.
+- * Using this class allows you to easily create packets, stuff them with
+- * required data, and convert them to/from ArrayBuffer objects. */
+-function YahooPacket(aService, aStatus, aSessionId)
+-{
+-  this.service = aService;
+-  this.status = aStatus;
+-  this.sessionId = aSessionId;
+-  this.keyValuePairs = [];
+-}
+-YahooPacket.prototype = {
+-  service: null,
+-  status: null,
+-  sessionId: null,
+-  keyValuePairs: null,
+-
+-  // Public methods.
+-
+-  // Add a single key/value pair.
+-  addValue: function(aKey, aValue) {
+-    let pair = {
+-      key: aKey.toString(), // The server handles keys as ASCII number values.
+-      value: aValue
+-    };
+-
+-    this.keyValuePairs.push(pair);
+-  },
+-
+-  // Add multiple key/value pairs with the same key but different values
+-  // stored in an array.
+-  addValues: function(aKey, aValues) {
+-    for each (let value in aValues)
+-      this.addValue(aKey, value);
+-  },
+-
+-  // This method returns the first value found with the given key.
+-  getValue: function(aKey) {
+-    for (let i = 0; i < this.keyValuePairs.length; ++i) {
+-      let pair = this.keyValuePairs[i];
+-      // The server handles keys as ASCII number values.
+-      if (pair.key == aKey.toString())
+-        return pair.value;
+-    }
+-
+-    // Throw an error if the key wasn't found.
+-    throw "Required key " + aKey + " wasn't found. Packet Service: " +
+-          this.service.toString(16);
+-  },
+-
+-  // This method returns all of the values found with the given key. In some
+-  // packets, one key is associated with multiple values. If that is the case,
+-  // use this method to retrieve all of them instead of just the first one.
+-  getValues: function(aKey) {
+-    let values = [];
+-    for (let i = 0; i < this.keyValuePairs.length; ++i) {
+-      let pair = this.keyValuePairs[i];
+-      // The server handles keys as ASCII number values.
+-      if (pair.key == aKey.toString())
+-        values.push(pair.value);
+-    }
+-
+-    // Throw an error if no keys were found.
+-    if (values.length == 0) {
+-      throw "Required key " + aKey + " wasn't found. Packet Service: " +
+-            this.service.toString(16);
+-    }
+-    return values;
+-  },
+-
+-  hasKey: function(aKey) {
+-    for (let i = 0; i < this.keyValuePairs.length; ++i) {
+-      // The server handles keys as ASCII number values.
+-      if (this.keyValuePairs[i].key == aKey.toString())
+-        return true;
+-    }
+-    return false;
+-  },
+-
+-  toArrayBuffer: function() {
+-    let dataString = "";
+-    for (let i = 0; i < this.keyValuePairs.length; ++i) {
+-      let pair = this.keyValuePairs[i];
+-      dataString += pair.key + kPacketDataDelimiter;
+-      dataString += pair.value + kPacketDataDelimiter;
+-    }
+-
+-    let packetLength = dataString.length;
+-    let buffer = new ArrayBuffer(kPacketHeaderSize + packetLength);
+-
+-    // Build header.
+-    let view = new DataView(buffer);
+-    let idBytes = StringToBytes(kPacketIdentifier);
+-    view.setUint8(0, idBytes[0]);
+-    view.setUint8(1, idBytes[1]);
+-    view.setUint8(2, idBytes[2]);
+-    view.setUint8(3, idBytes[3]);
+-    view.setUint16(4, kProtocolVersion);
+-    view.setUint16(6, 0); // Vendor ID
+-    view.setUint16(8, packetLength);
+-    view.setUint16(10, this.service);
+-    view.setUint32(12, this.status);
+-    view.setUint32(16, this.sessionId);
+-
+-    // Copy in data.
+-    copyBytes(buffer, BytesToArrayBuffer(StringToBytes(dataString)), kPacketHeaderSize);
+-
+-    return buffer;
+-  },
+-
+-  fromArrayBuffer: function(aBuffer) {
+-    let view = new DataView(aBuffer);
+-    this.length = view.getUint16(8) + kPacketHeaderSize;
+-    this.service = view.getUint16(10);
+-    this.status = view.getUint32(12);
+-    this.sessionId = view.getUint32(16);
+-
+-    let dataString = ArrayBufferToString(aBuffer).substring(kPacketHeaderSize);
+-    let delimitedData = dataString.split(kPacketDataDelimiter);
+-    // Since the data should also end with a trailing delmiter, split() will
+-    // add an empty element at the end. We need to pop this element off.
+-    delimitedData.pop();
+-
+-    // If we don't have an even number of delimitedData elements, that means
+-    // we are either missing a key or a value.
+-    if (delimitedData.length % 2 != 0) {
+-      throw "Odd number of data elements. Either a key or value is missing. "
+-            "Num of elements: " + delimitedData.length;
+-    }
+-
+-    for (let i = 0; i < delimitedData.length; i += 2) {
+-      let key = delimitedData[i];
+-      let value = delimitedData[i + 1];
+-      if (key && value) {
+-        let pair = {
+-          key: key,
+-          value: value
+-        };
+-        this.keyValuePairs.push(pair);
+-      }
+-    }
+-  },
+-
+-  toString: function() {
+-    // First, add packet header information.
+-    let s = "Service: 0x" + this.service.toString(16) + "\n";
+-    s += "Status: 0x" + this.status.toString(16) + "\n";
+-    s += "Session ID: 0x" + this.sessionId.toString(16);
+-    // Now we add the packet data, if there is some.
+-    if (this.keyValuePairs.length) {
+-      // Add two preceding newlines for space to make reading easier.
+-      s += "\n\nPacket Key-Value Data:\n";
+-      for each (let pair in this.keyValuePairs)
+-        s += pair.key + ":\t" + pair.value + "\n";
+-    }
+-    return s;
+-  }
+-};
+-YahooPacket.extractPackets = function(aData, aOnNetworkError) {
+-  let packets = [];
+-  let bytesHandled = 0;
+-
+-  while (aData.byteLength >= kPacketHeaderSize) {
+-    if (ArrayBufferToString(aData.slice(0, kPacketIdentifier.length)) !=
+-        kPacketIdentifier) {
+-      throw "Malformed packet received. Packet content: " +
+-            ArrayBufferToHexString(aData);
+-    }
+-
+-    let packetView = new DataView(aData);
+-    let packetLength = packetView.getUint16(8) + kPacketHeaderSize;
+-    // Don't process half packets.
+-    if (packetLength > aData.byteLength)
+-      break;
+-    let packet = new YahooPacket();
+-    packet.fromArrayBuffer(aData.slice(0, packetLength));
+-    packets.push(packet);
+-    bytesHandled += packetLength;
+-    aData = aData.slice(packetLength);
+-  }
+-  return [packets, bytesHandled];
+-}
+-
+-/* In YahooPacketHandler, each handler function is assosiated with a packet
+- * service number. You can use the kPacketType enumeration to understand
+- * what kind of packet each number is linked to.
+- *
+- * Keep in mind too that "this" in each function will be bound to a
+- * YahooAccount object, since they are all invoked using call(). */
+-var YahooPacketHandler = {
+-  // Buddy logoff.
+-  0x02: function(aPacket) {
+-    let name = aPacket.getValue(7);
+-    this.setBuddyStatus(name, Ci.imIStatusInfo.STATUS_OFFLINE, "");
+-  },
+-
+-  // Incoming chat message.
+-  0x06: function(aPacket) {
+-    let from = aPacket.getValue(4);
+-    let to = aPacket.getValue(5);
+-    let message = aPacket.getValue(14);
+-    this.receiveMessage(from, message);
+-
+-    // The official Yahoo! Messenger desktop client requires message ACKs to be
+-    // sent back to the server. The web client doesn't require this. A good
+-    // indication of when an ACK is required is when key 429 is sent, which
+-    // contains the ID of the message. When a message is sent from the official
+-    // desktop client, and no ACK is sent back, the message is resent seconds
+-    // later.
+-    if (aPacket.hasKey(429)) {
+-      let messageId = aPacket.getValue(429);
+-      let packet = new YahooPacket(kPacketType.MessageAck, 0, aPacket.sessionId);
+-      // Some keys have an unknown purpose, so we set a constant value.
+-      packet.addValue(1, to);
+-      packet.addValue(5, from);
+-      packet.addValue(302, "430");
+-      packet.addValue(430, messageId);
+-      packet.addValue(303, 430);
+-      packet.addValue(450, 0);
+-      this._session.sendPacket(packet);
+-    }
+-  },
+-
+-  // New mail notification.
+-  // TODO: Implement this handler when mail notifications are handled in the
+-  // base code.
+-  0x0b: function(aPacket) {},
+-
+-  // Server ping.
+-  // TODO: Add support for ping replies.
+-  0x12: function(aPacket) {},
+-
+-  // Conference invitation.
+-  0x18: function(aPacket) {
+-    let owner = aPacket.getValue(50);
+-    let roomName = aPacket.getValue(57);
+-    let participants = aPacket.getValues(53);
+-    // The owner is also a participant.
+-    participants.push(owner);
+-    let message = aPacket.getValue(58);
+-    this.receiveConferenceInvite(owner, roomName, participants, message);
+-  },
+-
+-  // Conference logon.
+-  0x19: function(aPacket) {
+-    let userName = aPacket.getValue(53);
+-    let room = aPacket.getValue(57);
+-    this.receiveConferenceLogon(room, userName);
+-  },
+-
+-  // Conference logoff
+-  0x1b: function(aPacket) {
+-    let userName = aPacket.getValue(56);
+-    let roomName = aPacket.getValue(57);
+-    this.receiveConferenceLogoff(roomName, userName);
+-  },
+-
+-  // Conference additional invitation. NOTE: Since this packet has the same
+-  // structure as the normal conference invite (packet 0x18), we simply
+-  // reuse that handler.
+-  0x1c: function(aPacket) { return YahooPacketHandler[0x18].call(this, aPacket); },
+-
+-  // Conference message.
+-  0x1d: function(aPacket) {
+-    let from = aPacket.getValue(3);
+-    let room = aPacket.getValue(57);
+-    let message = aPacket.getValue(14);
+-    this.receiveConferenceMessage(from, room, message);
+-  },
+-
+-  // Typing notification.
+-  0x4b: function(aPacket) {
+-    let name = aPacket.getValue(4);
+-    let isTyping = (aPacket.getValue(13) == "1");
+-    this.receiveTypingNotification(name, isTyping);
+-  },
+-
+-  // Legacy Yahoo! buddy list. Packet 0xf1 has replaced this.
+-  0x55: function(aPacket) {},
+-
+-  // Authentication acknowledgement. We can ignore this since we are known
+-  // to be authenticated if we are receiving other packets anyway.
+-  0x57: function(aPacket) {},
+-
+-  // AddBuddy ack packets can be ignored. They do not depend on whether or not
+-  // the buddy accepted the invite.
+-  0x83: function(aPacket) {},
+-
+-  // RemoveBuddy ack packets let us know when we should actually remove the
+-  // buddy from the list, keeping us in sync with the server.
+-  0x84: function(aPacket) {
+-   let buddy = this.getBuddy(aPacket.getValue(7));
+-   // The buddy is off the server, so remove it locally.
+-   this.removeBuddy(buddy, false);
+-  },
+-
+-  // Picture upload.
+-  0xc2: function(aPacket) {
+-    let onlineBuddies = this.getOnlineBuddies();
+-    // Send a notification to each online buddy that your icon has changed.
+-    // Those offline will automatically pick up the change when they log in.
+-    for each (let buddy in onlineBuddies) {
+-      let packet = new YahooPacket(kPacketType.AvatarUpdate, 0,
+-                                   this._session.sessionId);
+-      packet.addValue(3, buddy.userName);
+-      packet.addValue(213, 2); // A value of 2 means we are using an icon.
+-      this._session.sendPacket(packet);
+-    }
+-  },
+-
+-  // Buddy icon checksum.
+-  // TODO - Make use of the icon checksum to allow icon caching.
+-  0xbd: function(aPacket) {
+-    // Extract the checksum from the URL parameter chksum.
+-    let buddyName = aPacket.getValue(4);
+-    let url = aPacket.getValue(20);
+-    let parameter = "chksum=";
+-    // The "chksum" parameter is the only parameter in the URL.
+-    let checksum = url.substring(url.indexOf(parameter) + parameter.length);
+-
+-    let buddy = this.getBuddy(buddyName);
+-    // We only download the new icon if no older checksum exists, or if the
+-    // older checksum differs, indicating an updated icon.
+-    if (buddy && buddy.iconChecksum !== checksum) {
+-      buddy.buddyIconFilename = url;
+-      buddy.iconChecksum = checksum;
+-    }
+-  },
+-
+-  // Buddy icon request reply. This can be handled in the same way as a buddy
+-  // icon checksum packet, so we simply reuse the handler.
+-  0xbe: function (aPacket) { return YahooPacketHandler[0xbd].call(this, aPacket); },
+-
+-  // Buddy status update.
+-  0xc6: function (aPacket) {
+-    let name = aPacket.getValue(7);
+-    // If the user is mobile, use the mobile status.
+-    let status = aPacket.hasKey(60) ? Ci.imIStatusInfo.STATUS_MOBILE :
+-                                      kBuddyStatuses[aPacket.getValue(10)];
+-
+-    let message = aPacket.hasKey(19) ? aPacket.getValue(19) : "";
+-    this.setBuddyStatus(name, status, message);
+-  },
+-
+-  // Buddy avatar (icon) update.
+-  0xc7: function(aPacket) {
+-    // Strangely, in some non-official clients, when someone updates their
+-    // profile icon we are sent two avatar update packets: one with a default
+-    // status containing little information, and another with a Server Ack
+-    // status containing the info we need. So we only accept packets with a
+-    // Server Ack status to prevent errors.
+-    if (aPacket.status != kPacketStatuses.ServerAck)
+-      return;
+-    // Key 4 contains the name of the buddy who updated their icon.
+-    this._session.requestBuddyIcon(aPacket.getValue(4));
+-  },
+-
+-  // Buddy authorization request.
+-  0xd6: function(aPacket) {
+-    // Whenever we authorize someone to be our buddy, the server will send an
+-    // acknowledgement packet. We ignore the ack to prevent the auth request
+-    // from showing again.
+-    if (aPacket.status == kPacketStatuses.ServerAck)
+-      return;
+-
+-    let session = this._session;
+-    let userName = aPacket.getValue(4);
+-    this.addBuddyRequest(userName, session.acceptBuddyRequest.bind(session),
+-                         session.denyBuddyRequest.bind(session));
+-  },
+-
+-  // XXX: What does this packet do?
+-  0xef: function(aPacket) {},
+-
+-  // Initial user status.
+-  0xf0: function (aPacket) {
+-    // Return early if we find no buddy names.
+-    if (!aPacket.hasKey(7))
+-      return;
+-
+-    // The key/value pairs are in order as sent by the server. So we must
+-    // iterate though them to find out information about each buddy. Each
+-    // buddy section starts with key 7.
+-    let currentBuddy;
+-    for (let i = 0; i < aPacket.keyValuePairs.length; ++i) {
+-      let {key: key, value: value} = aPacket.keyValuePairs[i];
+-
+-      if (key == 7) { // Buddy name.
+-        currentBuddyName = value;
+-        this._session.requestBuddyIcon(currentBuddyName);
+-      } else if (key == 10) // Buddy status.
+-        this.setBuddyStatus(currentBuddyName, kBuddyStatuses[value]);
+-      else if (key == 19) // Buddy status message.
+-        this.setBuddyStatus(currentBuddyName, undefined, value);
+-      else if (key == 60) // Mobile status.
+-        this.setBuddyStatus(currentBuddyName, Ci.imIStatus.STATUS_MOBILE);
+-    }
+-  },
+-
+-  // Friends and groups list.
+-  0xf1: function(aPacket) {
+-    let tagName = "";
+-    for each (let pair in aPacket.keyValuePairs) {
+-      if (pair.key == "65")
+-        tagName = pair.value;
+-      else if (pair.key == "7") {
+-        let buddyName = pair.value;
+-        this.addBuddyFromServer(Services.tags.createTag(tagName), buddyName);
+-      }
+-    }
+-  }
+-};
+-
+-/* The YahooProfileIconUploader class is specifically designed to set a profile
+- * image on a Yahoo! Messenger account. The reason this functionality is split
+- * into a separate class is because of the complexity of the operation. Because
+- * of special protocol requirements, it is easier to use raw TCP communication
+- * instead of the httpRequest() method. */
+-function YahooProfileIconUploader(aAccount, aSession, aFileName, aImage)
+-{
+-  this._account = aAccount;
+-  this._session = aSession;
+-  this._fileName = aFileName;
+-  this._image = aImage;
+-}
+-YahooProfileIconUploader.prototype = {
+-  __proto__: Socket,
+-  _account: null,
+-  _session: null,
+-  _fileName: null,
+-  _image: null,
+-  _host: null,
+-  _port: null,
+-
+-  uploadIcon: function() {
+-    // Connect to the file transfer server, and the onConnection callback
+-    // will do the rest.
+-    this.connect(kFileTransferHost, kFileTransferPort);
+-  },
+-
+-  // Socket callbacks.
+-  onConnection: function() {
+-    // Scale the image down, and make it a PNG. Icon widths are constant, but
+-    // their height varies depending on the aspect ratio of the original image.
+-    let aspectRatio = this._image.width / this._image.height;
+-    let scaledHeight = kProfileIconWidth / aspectRatio;
+-    let scaledImage = imgTools.encodeScaledImage(this._image, "image/png",
+-                                                 kProfileIconWidth,
+-                                                 scaledHeight);
+-    let imageData = NetUtil.readInputStreamToString(scaledImage,
+-                                                    scaledImage.available());
+-
+-    // Build the Yahoo packet.
+-    let packet = new YahooPacket(kPacketType.Picture, 0, this.sessionId);
+-    packet.addValue(1, this._account.cleanUsername);
+-    // TODO - Look into how expiration time works for profile icons, and its
+-    // purpose. We aren't sure if this refers to seconds, days, years, etc.
+-    packet.addValue(38, "604800"); // Expiration time.
+-    packet.addValue(0, this._account.cleanUsername);
+-    packet.addValue(28, imageData.length); // Picture size in bytes.
+-    packet.addValue(27, this._fileName); // Picture filename.
+-    packet.addValue(14, ""); // Null string.
+-    let packetBuffer = packet.toArrayBuffer();
+-
+-    // Build the request header.
+-    let headers = [
+-      ["User-Agent", "Mozilla/5.0"],
+-      ["Cookie", "T=" + this._session.tCookie + "; Y=" + this._session.yCookie],
+-      ["Host", kFileTransferHost + ":" + kFileTransferPort],
+-      ["Content-Length", packetBuffer.byteLength + 4 + imageData.length],
+-      ["Cache-Control", "no-cache"],
+-    ];
+-    let headerString = "POST /notifyft HTTP/1.1\r\n";
+-    headers.forEach(function(header) {
+-      headerString += header[0] + ": " + header[1] + "\r\n";
+-    });
+-
+-    // The POST request uses a special delimeter between the end of the included
+-    // Yahoo binary packet, and the image data.
+-    let requestPacketEnd = "29" + kPacketDataDelimiter;
+-    // Build the complete POST request data.
+-    let requestData = headerString + "\r\n" +
+-                      ArrayBufferToString(packetBuffer) + requestPacketEnd +
+-                      imageData;
+-    this.sendData(requestData);
+-  }
+-};
+diff --git a/chat/protocols/yahoo/yahoo.js b/chat/protocols/yahoo/yahoo.js
+index 8beadb504..86a258969 100644
+--- a/chat/protocols/yahoo/yahoo.js
++++ b/chat/protocols/yahoo/yahoo.js
+@@ -2,575 +2,39 @@
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+-var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
++var {interfaces: Ci, utils: Cu} = Components;
+ 
+-Cu.import("resource:///modules/imServices.jsm");
+ Cu.import("resource:///modules/imXPCOMUtils.jsm");
+ Cu.import("resource:///modules/jsProtoHelper.jsm");
+-Cu.import("resource:///modules/yahoo-session.jsm");
+ 
+ XPCOMUtils.defineLazyGetter(this, "_", () =>
+   l10nHelper("chrome://chat/locale/yahoo.properties")
+ );
+ 
+-// These timeouts are in milliseconds.
+-var kKeepAliveTimeout = 60 * 1000; // One minute.
+-var kPingTimeout = 3600 * 1000; // One hour.
+-
+-function YahooConversation(aAccount, aName)
+-{
+-  this._buddyUserName = aName;
+-  this._account = aAccount;
+-  this.buddy = aAccount.getBuddy(aName);
+-  this._init(aAccount);
+-}
+-YahooConversation.prototype = {
+-  __proto__: GenericConvIMPrototype,
+-  _account: null,
+-  _buddyUserName: null,
+-  _typingTimer: null,
+-
+-  close: function() {
+-    this._account.deleteConversation(this._buddyUserName);
+-    GenericConvChatPrototype.close.call(this);
+-  },
+-
+-  sendMsg: function (aMsg) {
+-    // Deliver the message, then write it to the window.
+-    this._account._session.sendChatMessage(this._buddyUserName,
+-                                           this._account.encodeMessage(aMsg));
+-    this.finishedComposing();
+-    this.writeMessage(this._account.cleanUsername, aMsg,
+-                      {outgoing: true, _alias: this._account.imAccount.alias});
+-  },
+-
+-  sendTyping: function(aString) {
+-    if (aString.length) {
+-      if (!this._typingTimer)
+-        this._account._session.sendTypingStatus(this._buddyUserName, true);
+-      this._refreshTypingTimer();
+-    }
+-    return Ci.prplIConversation.NO_TYPING_LIMIT;
+-  },
+-
+-  finishedComposing: function() {
+-    this._account._session.sendTypingStatus(this._buddyUserName, false);
+-    this._cancelTypingTimer();
+-  },
+-
+-  _refreshTypingTimer: function() {
+-    this._cancelTypingTimer();
+-    this._typingTimer = setTimeout(this.finishedComposing.bind(this), 10000);
+-  },
+-
+-  _cancelTypingTimer: function() {
+-    if (!this._typingTimer)
+-      return;
+-    clearTimeout(this._typingTimer);
+-    delete this._typingTimer
+-    this._typingTimer = null;
+-  },
+-
+-  get name() { return this._buddyUserName; }
+-};
+-
+-function YahooConference(aAccount, aRoom, aOwner)
+-{
+-  this._account = aAccount;
+-  this._roomName = aRoom;
+-  this._owner = aOwner;
+-  this._init(aAccount, aRoom, aAccount.cleanUsername);
+-}
+-YahooConference.prototype = {
+-  __proto__: GenericConvChatPrototype,
+-  _account: null,
+-  _roomName: null,
+-  _owner: null,
+-
+-  close: function() {
+-    this.reportLogoff();
+-    this._account.deleteConference(this._roomName);
+-    GenericConvChatPrototype.close.call(this);
+-  },
+-
+-  reportLogoff: function() {
+-    if (this.left)
+-      return;
+-    this._account._session.sendConferenceLogoff(this._account.cleanUsername,
+-                                                this.getParticipantNames(),
+-                                                this._roomName);
+-    this.left = true;
+-  },
+-
+-  sendMsg: function(aMsg) {
+-    this._account._session.sendConferenceMessage(this.getParticipantNames(),
+-                                                 this._roomName,
+-                                                 this._account.encodeMessage(aMsg));
+-  },
+-
+-  addParticipant: function(aName) {
+-    // In case we receive multiple conference logon packets, prevent adding
+-    // duplicate buddies.
+-    if (this._participants.get(aName))
+-      return;
+-    let buddy = new YahooConferenceBuddy(aName, this);
+-    this._participants.set(aName, buddy);
+-    this.notifyObservers(new nsSimpleEnumerator([buddy]), "chat-buddy-add");
+-    this.writeMessage(this._roomName,
+-                      _("system.message.conferenceLogon", aName),
+-                      {system: true});
+-  },
+-
+-  getParticipantNames: function() { return [for (p of this._participants.values()) p.name]; }
+-};
+-
+-function YahooConferenceBuddy(aName, aConference)
+-{
+-  this._name = aName;
+-  this._conference = aConference;
+-}
+-YahooConferenceBuddy.prototype = {
+-  __proto__: GenericConvChatBuddyPrototype,
+-  _conference: null,
+-
+-  get founder() { return this._conference._owner == this._name; }
+-};
+-
+-function YahooAccountBuddy(aAccount, aBuddy, aTag, aUserName)
+-{
+-  this._init(aAccount, aBuddy, aTag, aUserName);
+-}
+-YahooAccountBuddy.prototype = {
+-  __proto__: GenericAccountBuddyPrototype,
+-  iconChecksum: null,
+-
+-  // This removes the buddy locally, and from the Yahoo! servers.
+-  remove: function() { return this._account.removeBuddy(this, true); },
+-  // This removes the buddy locally, but keeps him on the servers.
+-  removeLocal: function() { return this._account.removeBuddy(this, false); },
+-  createConversation: function() { return this._account.createConversation(this.userName); }
+-}
+-
+ function YahooAccount(aProtoInstance, aImAccount)
+ {
+   this._init(aProtoInstance, aImAccount);
+-  this._buddies = new Map();
+-  this._conversations = new Map();
+-  this._conferences = new Map();
+-  this._protocol = aProtoInstance;
+-  this._converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
+-      .createInstance(Ci.nsIScriptableUnicodeConverter);
+-  this._converter.charset = this.getString("local_charset") || "UTF-8";
+-
+-  // The username stripped of any @yahoo.* domain.
+-  this.cleanUsername = this.name.replace(/@yahoo\..+$/, "");
+ }
+ YahooAccount.prototype = {
+   __proto__: GenericAccountPrototype,
+-  // YahooSession object passed in constructor.
+-  _session: null,
+-  // A Map holding the list of buddies associated with their usernames.
+-  _buddies: null,
+-  // A Map holding the list of open buddy conversations associated with the
+-  // username of the buddy.
+-  _conversations: null,
+-  // A Map holding the list of open conference rooms associated with the room
+-  // name.
+-  _conferences: null,
+-  // YahooProtocol object passed in the constructor.
+-  _protocol: null,
+-  // An nsIScriptableUnicodeConverter used to convert incoming/outgoing chat
+-  // messages to the correct charset.
+-  _converter: null,
+-  // This is simply incremented by one everytime a new conference room is
+-  // created. It is appened to the end of the room name when a new room is
+-  // created, ensuring name uniqueness.
+-  _roomsCreated: 0,
+-  // The username stripped of any @yahoo.* domain.
+-  cleanUsername: null,
+-  // The timers used to send keepalive and ping packets to the server to ensrue
+-  // the server that the user is still connected.
+-  _keepAliveTimer: null,
+-  _pingTimer: null,
+ 
+   connect: function() {
+-    this._session = new YahooSession(this);
+-    this._session.login(this.imAccount.name, this.imAccount.password);
+-  },
+-
+-  disconnect: function(aSilent) {
+-    // Log out of all of the conferences the user is in.
+-    for (let conf of this._conferences)
+-      conf[1].reportLogoff();
+-
+-    if (this.connected) {
+-      this.reportDisconnecting(Ci.prplIAccount.NO_ERROR, "");
+-      if (this._session.isConnected)
+-        this._session.disconnect();
+-      this.reportDisconnected();
+-    }
+-    // buddy[1] is the actual object.
+-    for (let buddy of this._buddies)
+-      buddy[1].setStatus(Ci.imIStatusInfo.STATUS_UNKNOWN, "");
+-
+-    // Clear and delete the timers to avoid memory leaks.
+-    if (this._keepAliveTimer) {
+-      this._keepAliveTimer.cancel();
+-      delete this._keepAliveTimer;
+-    }
+-
+-    if (this._pingTimer) {
+-      this._pingTimer.cancel();
+-      delete this._pingTimer;
+-    }
+-  },
+-
+-  observe: function(aSubject, aTopic, aData) {
+-    if (aTopic == "status-changed")
+-      this._session.setStatus(aSubject.statusType, aData);
+-    else if (aTopic == "user-icon-changed")
+-      this._session.setProfileIcon(aData);
+-  },
+-
+-  remove: function() {
+-    for each(let conv in this._conversations)
+-      conv.close();
+-    delete this._conversations;
+-    for (let buddy of this._buddies)
+-      buddy[1].removeLocal(); // buddy[1] is the actual object.
+-  },
+-
+-  unInit: function() {
+-    this.disconnect(true);
+-    delete this.imAccount;
+-  },
+-
+-  createConversation: function(aName) {
+-    let conv = new YahooConversation(this, aName);
+-    this._conversations.set(aName, conv);
+-    return conv;
+-  },
+-
+-  deleteConversation: function(aName) {
+-    if (this._conversations.has(aName))
+-      this._conversations.delete(aName);
+-  },
+-
+-  receiveConferenceInvite: function(aOwner, aRoom, aParticipants, aMessage) {
+-    // Do nothing if we wish to ignore invites.
+-    if (!Services.prefs.getIntPref("messenger.conversations.autoAcceptChatInvitations") ||
+-        this.getBool("ignore_invites"))
+-      return;
+-
+-    let conf = new YahooConference(this, aRoom, aOwner);
+-    this._conferences.set(aRoom, conf);
+-
+-    for each (let participant in aParticipants)
+-      conf.addParticipant(participant);
+-
+-    // Add ourselves to the conference room as well.
+-    conf.addParticipant(this.imAccount.name);
+-
+-    this._session.acceptConferenceInvite(aOwner, aRoom,
+-                                         conf.getParticipantNames());
+-  },
+-
+-  receiveConferenceLogon: function(aRoom, aUsername) {
+-    if (!this._conferences.has(aRoom))
+-      return;
+-    let conf = this._conferences.get(aRoom);
+-    conf.addParticipant(aUsername);
+-  },
+-
+-  receiveConferenceLogoff: function(aRoom, aUsername) {
+-    if (!this._conferences.has(aRoom))
+-      return;
+-    let conf = this._conferences.get(aRoom);
+-    conf.removeParticipant(aUsername);
+-    conf.writeMessage(this._roomName,
+-                      _("system.message.conferenceLogoff", aName),
+-                      {system: true});
+-  },
+-
+-  deleteConference: function(aName) {
+-    if (this._conferences.has(aName))
+-      this._conferences.delete(aName);
+-  },
+-
+-  // Called when the user adds or authorizes a new contact.
+-  addBuddy: function(aTag, aName) {
+-    let buddy = new YahooAccountBuddy(this, null, aTag, aName);
+-    this._buddies.set(buddy.userName, buddy);
+-    this._session.addBuddyToServer(buddy);
+-    Services.contacts.accountBuddyAdded(buddy);
+-  },
+-
+-  hasBuddy: function(aName) {
+-    return this._buddies.has(aName);
+-  },
+-
+-  // Called for each buddy that is sent in a list packet from Yahoo! on login.
+-  addBuddyFromServer: function(aTag, aName) {
+-    let buddy;
+-    if (this._buddies.has(aName))
+-      buddy = this._buddies.get(aName);
+-    else {
+-      buddy = new YahooAccountBuddy(this, null, aTag, aName);
+-      Services.contacts.accountBuddyAdded(buddy);
+-      this._buddies.set(aName, buddy);
+-    }
+-
+-    // Set all new buddies as offline because a following status packet will
+-    // tell their status if they are online.
+-    buddy.setStatus(Ci.imIStatusInfo.STATUS_OFFLINE, "");
+-
+-    // Request the buddy's picture.
+-    this._session.requestBuddyIcon(aName);
+-  },
+-
+-  // Called when a user removes a contact from within Instantbird.
+-  removeBuddy: function(aBuddy, aRemoveFromServer) {
+-    if (aRemoveFromServer) {
+-      // We will remove the buddy locally when we get a server ack packet.
+-      this._session.removeBuddyFromServer(aBuddy);
+-      return;
+-    }
+-
+-    this._buddies.delete(aBuddy.userName);
+-    Services.contacts.accountBuddyRemoved(aBuddy);
+-  },
+-
+-  loadBuddy: function(aBuddy, aTag) {
+-    let buddy = new YahooAccountBuddy(this, aBuddy, aTag);
+-    this._buddies.set(buddy.userName, buddy);
+-
+-    return buddy;
+-  },
+-
+-  // Both the status and message can be defined, or only one can be defined.
+-  // When defining just the message, set aStatus to undefined.
+-  setBuddyStatus: function(aName, aStatus, aMessage) {
+-    if (!this._buddies.has(aName))
+-      return;
+-    let buddy = this._buddies.get(aName);
+-    // If the message is set as undefined, use the existing message.
+-    if (aMessage === undefined)
+-      aMessage = buddy.statusText;
+-    // If the status is undefined, use the existing status.
+-    if (aStatus === undefined)
+-      aStatus = buddy.statusType;
+-    buddy.setStatus(aStatus, aMessage);
+-  },
+-
+-  getBuddy: function(aName) {
+-    if (this._buddies.has(aName))
+-      return this._buddies.get(aName);
+-    return null;
+-  },
+-
+-  getOnlineBuddies: function() {
+-    let onlineBuddies = [];
+-    for (let buddy of this._buddies) {
+-      if (buddy[1].statusType != Ci.imIStatusInfo.STATUS_OFFLINE)
+-        onlineBuddies.push(buddy[1]);
+-    }
+-    return onlineBuddies;
+-  },
+-
+-  receiveMessage: function(aName, aMessage) {
+-    let conv;
+-    // Check if we have an existing converstaion open with this user. If not,
+-    // create one and add it to the list.
+-    if (!this._conversations.has(aName))
+-      conv = this.createConversation(aName);
+-    else
+-      conv = this._conversations.get(aName);
+-
+-    // Certain Yahoo clients, such as the official web client, sends formatted
+-    // messages, but the size value is the actual pt size, not the 1 - 7 size
+-    // expected from the HTML <font> tag. We replace it with the correct size.
+-    let message = this.decodeMessage(aMessage)
+-                      .replace(/(<font[^>]+)size=\"(\d+)\"/g, this._fixFontSize);
+-
+-    conv.writeMessage(aName, message, {incoming: true});
+-    conv.updateTyping(Ci.prplIConvIM.NOT_TYPING, conv.name);
+-  },
+-
+-  receiveConferenceMessage: function(aName, aRoom, aMessage) {
+-    if (!this._conferences.has(aRoom))
+-      return;
+-
+-    this._conferences.get(aRoom).writeMessage(aName,
+-                                              this.decodeMessage(aMessage),
+-                                              {incoming: true});
+-  },
+-
+-  receiveTypingNotification: function(aName, aIsTyping) {
+-    if (!this._conversations.has(aName))
+-      return;
+-
+-    let conv = this._conversations.get(aName);
+-    if (aIsTyping)
+-      conv.updateTyping(Ci.prplIConvIM.TYPING, conv.name);
+-    else
+-      conv.updateTyping(Ci.prplIConvIM.NOT_TYPING, conv.name);
+-  },
+-
+-  encodeMessage: function(aMessage) {
+-    // Try to perform a convertion from JavaScript UTF-16 into the charset
+-    // specified in the options. If the conversion fails, just leave
+-    // the message as it is.
+-    let encodedMsg;
+-    try {
+-      encodedMsg = this._converter.ConvertFromUnicode(aMessage);
+-    } catch (e) {
+-      encodedMsg = aMessage;
+-      this.WARN("Could not encode UTF-16 message into " +
+-                this._converter.charset + ". Message: " + aMessage);
+-    }
+-    return encodedMsg;
+-  },
+-
+-  decodeMessage: function(aMessage) {
+-    // Try to perform a convertion from the charset specified in the options
+-    // to JavaScript UTF-16. If the conversion fails, just leave the message
+-    // as it is.
+-    let decodedMsg;
+-    try {
+-      decodedMsg = this._converter.ConvertToUnicode(aMessage);
+-    } catch (e) {
+-      decodedMsg = aMessage;
+-      this.WARN("Could not decode " + this._converter.charset +
+-                " message into UTF-16. Message: " + aMessage);
+-    }
+-    return decodedMsg;
+-  },
+-
+-  get canJoinChat() { return true; },
+-  chatRoomFields: {},
+-  joinChat: function(aComponents) {
+-    // Use _roomsCreated to append a unique number to the room name.
+-    let roomName = this.cleanUsername + "-" + ++this._roomsCreated;
+-    let conf = new YahooConference(this, roomName, this.cleanUsername);
+-    this._conferences.set(roomName, conf);
+-    this._session.createConference(roomName);
+-  },
+-
+-  // Callbacks.
+-  onLoginComplete: function() {
+-    // Now that we are connected, get ready to start to sending pings and
+-    // keepalive packets.
+-    this._keepAliveTimer = Cc["@mozilla.org/timer;1"]
+-                             .createInstance(Ci.nsITimer);
+-    this._pingTimer = Cc["@mozilla.org/timer;1"]
+-                        .createInstance(Ci.nsITimer);
+-
+-    // We use slack timers since we don't need millisecond precision when
+-    // sending the keepalive and ping packets.
+-    let s = this._session;
+-    this._keepAliveTimer
+-        .initWithCallback(s.sendKeepAlive.bind(s), kKeepAliveTimeout,
+-                          this._keepAliveTimer.TYPE_REPEATING_SLACK);
+-
+-    this._pingTimer
+-        .initWithCallback(s.sendPing.bind(s), kPingTimeout,
+-                          this._pingTimer.TYPE_REPEATING_SLACK);
+-
+-  },
+-
+-  // Private methods.
+-
+-  // This method is used to fix font sizes given by formatted messages. This
+-  // method is designed to be used as a method for a string replace() call.
+-  _fixFontSize: function(aMatch, aTagAttributes, aFontSize, aOffset, aString) {
+-    // Approximate the font size.
+-    let newSize;
+-    if (aFontSize <= 8)
+-      newSize = "1";
+-    else if (aFontSize <= 10)
+-      newSize = "2";
+-    else if (aFontSize <= 12)
+-      newSize = "3";
+-    else if (aFontSize <= 14)
+-      newSize = "4";
+-    else if (aFontSize <= 20)
+-      newSize = "5";
+-    else if (aFontSize <= 30)
+-      newSize = "6";
+-    else if (aFontSize <= 40)
+-      newSize = "7";
+-    else // If we get some gigantic size, just default to the standard 3 size.
+-      newSize = "3";
+-
+-    let sizeAttribute = "size=\"" + newSize + "\"";
+-    // We keep any preceding attributes, but replace the size attribute.
+-    return aTagAttributes + sizeAttribute;
++    this.WARN("The legacy versions of Yahoo Messenger was disabled on August " +
++              "5, 2016. It is currently not possible to connect to Yahoo " +
++              "Messenger. See bug 1316000");
++    this.reportDisconnecting(Ci.prplIAccount.ERROR_OTHER_ERROR,
++                             _("yahoo.disabled"));
++    this.reportDisconnected();
+   }
+ };
+ 
+-function YahooProtocol() {
+-  this.registerCommands();
+-}
++function YahooProtocol() {}
+ YahooProtocol.prototype = {
+   __proto__: GenericProtocolPrototype,
+-  // Protocol specific connection parameters.
+-  pagerRequestUrl: "http://scsa.msg.yahoo.com/capacity",
+-  loginTokenGetUrl: "https://login.yahoo.com/config/pwtoken_get",
+-  loginTokenLoginUrl: "https://login.yahoo.com/config/pwtoken_login",
+-  buildId: "4194239",
+ 
+   get id() { return "prpl-yahoo"; },
+   get name() { return "Yahoo"; },
+   get iconBaseURI() { return "chrome://prpl-yahoo/skin/"; },
+-  options: {
+-    port: {get label() { return _("options.pagerPort"); }, default: 5050},
+-    local_charset: {get label() { return _("options.chatEncoding"); }, default: "UTF-8"},
+-    ignore_invites: {get label() { return _("options.ignoreInvites"); }, default: false}
+-  },
+-  commands: [
+-    {
+-      name: "invite",
+-      get helpString() { return _("command.help.invite2", "invite"); },
+-      usageContext: Ci.imICommand.CMD_CONTEXT_ALL,
+-      run: function(aMsg, aConv) {
+-        if (aMsg.trim().length == 0)
+-          return false;
+-
+-        let splitPosition = aMsg.indexOf(" "); // Split at first space.
+-        let invitees;
+-        let message;
+-
+-        // If we have an invite message.
+-        if (splitPosition > 0) {
+-          invitees = aMsg.substring(0, splitPosition).split(",");
+-          message = aMsg.substring(splitPosition);
+-        } else {
+-          invitees = aMsg.split(",");
+-          message = _("conference.invite.message"); // Use default message.
+-        }
+-
+-        let conf = aConv.wrappedJSObject;
+-        conf._account._session.inviteToConference(invitees, conf._roomName,
+-                                                  conf.getParticipantNames(),
+-                                                  message);
+-        conf.writeMessage(conf._roomName,
+-                          _("command.feedback.invite", invitees.join(", ")),
+-                          {system: true, noLog: true});
+-        conf._account.LOG("Sending conference invite to " + invitees);
+-        return true;
+-      },
+-    },
+-
+-    {
+-      name: "conference",
+-      get helpString() { return _("command.help.conference", "conference"); },
+-      usageContext: Ci.imICommand.CMD_CONTEXT_CHAT,
+-      run: function(aMsg, aConv) {
+-        aConv.account.joinChat(null);
+-        return true;
+-      }
+-    }
+-  ],
+   getAccount: function(aImAccount) { return new YahooAccount(this, aImAccount); },
+   classID: Components.ID("{50ea817e-5d79-4657-91ae-aa0a52bdb98c}")
+ };
+diff --git a/im/content/conversation.xml b/im/content/conversation.xml
+index 6f00c8d39..c93dab00f 100644
+--- a/im/content/conversation.xml
++++ b/im/content/conversation.xml
+@@ -342,8 +342,7 @@
+                   msg = "<font face=\"" + style.fontFamily + "\">" + msg + "</font>";
+                 // MSN doesn't support font size info in messages...
+               }
+-              else if (proto == "prpl-aim" || proto == "prpl-icq" ||
+-                       proto == "prpl-yahoo" || proto == "prpl-yahoojp") {
++              else if (proto == "prpl-aim" || proto == "prpl-icq") {
+                 let styleAttributes = ""
+                 if ("color" in style)
+                   styleAttributes += " color=\"" + style.color + "\"";
+diff --git a/im/locales/en-US/chrome/instantbird/accountWizard.properties b/im/locales/en-US/chrome/instantbird/accountWizard.properties
+index 7d371bd21..1d6fd48e1 100644
+--- a/im/locales/en-US/chrome/instantbird/accountWizard.properties
++++ b/im/locales/en-US/chrome/instantbird/accountWizard.properties
+@@ -14,9 +14,8 @@ topProtocol.list=prpl-irc,prpl-jabber,prpl-twitter,prpl-gtalk
+ # These are the descriptions of the top protocols specified above.
+ # A description should be provided for each protocol ID listed above.
+ topProtocol.prpl-irc.description=Connect to your favourite IRC network
+-topProtocol.prpl-jabber.description=Chat with friends using XMPP
+ topProtocol.prpl-gtalk.description=Talk to your Gmail contacts
+ topProtocol.prpl-twitter.description=Stay up to date with your Twitter timeline
+ topProtocol.prpl-aim.description=Chat with your buddies on AOL Instant Messenger
+-topProtocol.prpl-yahoo.description=Chat with friends using Yahoo! Messenger
+ topProtocol.prpl-irc.description=Join IRC channels
++topProtocol.prpl-jabber.description=Chat using the open Jabber/XMPP protocol
+diff --git a/im/test/xpcshell.ini b/im/test/xpcshell.ini
+index 5f7dd70fc..578122a2a 100644
+--- a/im/test/xpcshell.ini
++++ b/im/test/xpcshell.ini
+@@ -6,5 +6,4 @@
+ [include:chat/components/src/test/xpcshell.ini]
+ [include:chat/protocols/irc/test/xpcshell.ini]
+ [include:chat/protocols/skype/test/xpcshell.ini]
+-[include:chat/protocols/yahoo/test/xpcshell.ini]
+ #[include:extensions/purple/purplexpcom/src/test/xpcshell.ini]
+diff --git a/mail/components/im/content/imconversation.xml b/mail/components/im/content/imconversation.xml
+index 16c665ab4..a4b9fc638 100644
+--- a/mail/components/im/content/imconversation.xml
++++ b/mail/components/im/content/imconversation.xml
+@@ -285,8 +285,7 @@
+                 msg = "<font face=\"" + style.fontFamily + "\">" + msg + "</font>";
+               // MSN doesn't support font size info in messages...
+             }
+-            else if (proto == "prpl-aim" || proto == "prpl-icq" ||
+-                     proto == "prpl-yahoo" || proto == "prpl-yahoojp") {
++            else if (proto == "prpl-aim" || proto == "prpl-icq") {
+               let styleAttributes = ""
+               if ("color" in style)
+                 styleAttributes += " color=\"" + style.color + "\"";
+-- 
+2.11.0
+
diff --git a/projects/instantbird/0025-Bug-1316000-Remove-old-Yahoo-Messenger-support.-r-al.patch b/projects/instantbird/0025-Bug-1316000-Remove-old-Yahoo-Messenger-support.-r-al.patch
deleted file mode 100644
index 1722403..0000000
--- a/projects/instantbird/0025-Bug-1316000-Remove-old-Yahoo-Messenger-support.-r-al.patch
+++ /dev/null
@@ -1,2398 +0,0 @@
-From 28b6432939ad61eacfe8c1e9559b3d5382298947 Mon Sep 17 00:00:00 2001
-From: Patrick Cloke <clokep at gmail.com>
-Date: Wed, 9 Nov 2016 09:03:49 -0800
-Subject: [PATCH 25/27] Bug 1316000 - Remove old Yahoo! Messenger support.
- r=aleth
-
----
- chat/chat-prefs.js                                 |    2 +
- chat/locales/en-US/facebook.properties             |    3 +-
- chat/locales/en-US/yahoo.properties                |   34 +-
- chat/protocols/facebook/facebook.js                |   13 +-
- chat/protocols/yahoo/moz.build                     |    6 -
- chat/protocols/yahoo/test/test_yahooAccount.js     |   98 --
- chat/protocols/yahoo/test/test_yahooLoginHelper.js |   89 --
- chat/protocols/yahoo/test/test_yahoopacket.js      |  217 ----
- chat/protocols/yahoo/test/xpcshell.ini             |    7 -
- chat/protocols/yahoo/yahoo-session.jsm             | 1156 --------------------
- chat/protocols/yahoo/yahoo.js                      |  552 +---------
- im/content/conversation.xml                        |    3 +-
- .../chrome/instantbird/accountWizard.properties    |    3 +-
- im/test/xpcshell.ini                               |    1 -
- mail/components/im/content/imconversation.xml      |    3 +-
- 15 files changed, 18 insertions(+), 2169 deletions(-)
- delete mode 100644 chat/protocols/yahoo/test/test_yahooAccount.js
- delete mode 100644 chat/protocols/yahoo/test/test_yahooLoginHelper.js
- delete mode 100644 chat/protocols/yahoo/test/test_yahoopacket.js
- delete mode 100644 chat/protocols/yahoo/test/xpcshell.ini
- delete mode 100644 chat/protocols/yahoo/yahoo-session.jsm
-
-diff --git a/chat/chat-prefs.js b/chat/chat-prefs.js
-index fb769163d..60b9c1e8c 100644
---- a/chat/chat-prefs.js
-+++ b/chat/chat-prefs.js
-@@ -84,6 +84,8 @@ pref("chat.irc.automaticList", true);
- pref("chat.prpls.prpl-skype.disable", true);
- // Disable Facebook as the XMPP gateway no longer exists.
- pref("chat.prpls.prpl-facebook.disable", true);
-+// Disable Yahoo Messenger as legacy Yahoo was shut down.
-+pref("chat.prpls.prpl-yahoo.disable", true);
- 
- // loglevel is the minimum severity level that a libpurple message
- // must have to be reported in the Error Console.
-diff --git a/chat/locales/en-US/facebook.properties b/chat/locales/en-US/facebook.properties
-index aaf7cdc9c..2e00cbcb2 100644
---- a/chat/locales/en-US/facebook.properties
-+++ b/chat/locales/en-US/facebook.properties
-@@ -2,6 +2,5 @@
- # License, v. 2.0. If a copy of the MPL was not distributed with this
- # file, You can obtain one at http://mozilla.org/MPL/2.0/.
- 
--connection.error.useUsernameNotEmailAddress=Please use your Facebook username, not an email address
--
- facebook.chat.name=Facebook Chat
-+facebook.disabled=Facebook Chat is no longer supported due to Facebook disabling their XMPP gateway.
-diff --git a/chat/locales/en-US/yahoo.properties b/chat/locales/en-US/yahoo.properties
-index 727faa6ee..89ee0093c 100644
---- a/chat/locales/en-US/yahoo.properties
-+++ b/chat/locales/en-US/yahoo.properties
-@@ -2,36 +2,4 @@
- # License, v. 2.0. If a copy of the MPL was not distributed with this
- # file, You can obtain one at http://mozilla.org/MPL/2.0/.
- 
--login.error.badCredentials=Username or password is incorrect.
--login.error.accountLockedFailed=Account locked due to too many failed login attempts.
--login.error.accountLockedGeneral=Account locked due to too many login attempts.
--login.error.accountDeactivated=Account has been deactivated.
--login.error.usernameNotExist=The username does not exist.
--# The %S will be an error code returned by the server.
--login.error.unknown=Unknown error: %S
--network.error.http=HTTP connection error.
--
--conference.invite.message=Join my conference.
--
--# Some options are commented out because they aren't used. We do the same thing
--# to their description strings.
--options.pagerPort=Port
--options.transferHost=File transfer server
--options.transferPort=File transfer port
--options.chatEncoding=Encoding
--options.ignoreInvites=Ignore conference invitations
--
--# In this message, %S is replaced with the username of the user who left.
--system.message.conferenceLogoff=%S has left the conference.
--system.message.conferenceLogon=%S has joined the conference.
--
--# LOCALZIATION NOTE (command.*):
--#   These are the help messages for each command, the %S is the command name
--#   Each command first gives the parameter it accepts and then a description of
--#   the command.
--command.help.invite2=%S <user1>[,<user2>,...] [<invite message>]: invite one or more users into this conference chat.
--command.help.conference=%S: Create a new conference room in which you can later invite other users.
--
--# LOCALIZATION NOTE (command.feedback.invite):
--#   %S is the user, or comma separated list of users, invited to the conference.
--command.feedback.invite=You have invited %S to the conference.
-+yahoo.disabled=Yahoo Messenger is no longer supported due to Yahoo disabling their legacy protocol.
-diff --git a/chat/protocols/facebook/facebook.js b/chat/protocols/facebook/facebook.js
-index 7b5b3b86e..9d90eacdb 100644
---- a/chat/protocols/facebook/facebook.js
-+++ b/chat/protocols/facebook/facebook.js
-@@ -6,33 +6,26 @@ var {interfaces: Ci, utils: Cu} = Components;
- 
- Cu.import("resource:///modules/imXPCOMUtils.jsm");
- Cu.import("resource:///modules/jsProtoHelper.jsm");
--Cu.import("resource:///modules/xmpp.jsm");
--Cu.import("resource:///modules/xmpp-session.jsm");
- 
- XPCOMUtils.defineLazyGetter(this, "_", () =>
-   l10nHelper("chrome://chat/locale/facebook.properties")
- );
--XPCOMUtils.defineLazyGetter(this, "_irc", () =>
--  l10nHelper("chrome://chat/locale/irc.properties")
--);
- 
- function FacebookAccount(aProtoInstance, aImAccount) {
-   this._init(aProtoInstance, aImAccount);
- }
- FacebookAccount.prototype = {
--  __proto__: XMPPAccountPrototype,
--  get canJoinChat() { return false; },
-+  __proto__: GenericAccountPrototype,
-   connect: function() {
-     this.WARN("As Facebook deprecated its XMPP gateway, it is currently not " +
-               "possible to connect to Facebook Chat. See bug 1141674.");
-     this.reportDisconnecting(Ci.prplIAccount.ERROR_OTHER_ERROR,
--                             _irc("error.unavailable", _("facebook.chat.name")));
-+                             _("facebook.disabled"));
-     this.reportDisconnected();
-   }
- };
- 
--function FacebookProtocol() {
--}
-+function FacebookProtocol() {}
- FacebookProtocol.prototype = {
-   __proto__: GenericProtocolPrototype,
-   get normalizedName() { return "facebook"; },
-diff --git a/chat/protocols/yahoo/moz.build b/chat/protocols/yahoo/moz.build
-index f14434732..ea378535a 100644
---- a/chat/protocols/yahoo/moz.build
-+++ b/chat/protocols/yahoo/moz.build
-@@ -3,15 +3,9 @@
- # License, v. 2.0. If a copy of the MPL was not distributed with this
- # file, You can obtain one at http://mozilla.org/MPL/2.0/.
- 
--XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell.ini']
--
- EXTRA_COMPONENTS += [
-     'yahoo.js',
-     'yahoo.manifest',
- ]
- 
--EXTRA_JS_MODULES += [
--    'yahoo-session.jsm',
--]
--
- JAR_MANIFESTS += ['jar.mn']
-diff --git a/chat/protocols/yahoo/test/test_yahooAccount.js b/chat/protocols/yahoo/test/test_yahooAccount.js
-deleted file mode 100644
-index 51df00bb9..000000000
---- a/chat/protocols/yahoo/test/test_yahooAccount.js
-+++ /dev/null
-@@ -1,98 +0,0 @@
--/* Any copyright is dedicated to the Public Domain.
-- * http://creativecommons.org/publicdomain/zero/1.0/ */
--
--Components.utils.import("resource://gre/modules/Services.jsm");
--var yahoo = {};
--Services.scriptloader.loadSubScript("resource:///components/yahoo.js", yahoo);
--
--function run_test()
--{
--  add_test(test_cleanUsername);
--  add_test(test_fixFontSize);
--  run_next_test();
--}
--
--// Test the stripping of @yahoo.* domains from usernames.
--function test_cleanUsername()
--{
--  // These are just a few of the many possible domains.
--  let domains = ["yahoo.com.ar", "yahoo.com.au", "yahoo.com", "yahoo.co.jp",
--                 "yahoo.it", "yahoo.cn", "yahoo.co.in"];
--  let userId = "user";
--
--  // We must provide a mimimal fake implementation of a protocol object, to keep
--  // the YahooAccount constructor happy.
--  let fakeProtocol = {
--    id: "fake-proto",
--    options: {
--      local_charset: "UTF-8"
--    },
--    _getOptionDefault: function(aOption) { return this.options[aOption]; }
--  };
--  let fakeImAccount = {};
--
--  for each(let domain in domains) {
--    fakeImAccount.name = userId + "@" + domain;
--    let yahooAccount = new yahoo.YahooAccount(fakeProtocol, fakeImAccount);
--    do_check_eq(userId, yahooAccount.cleanUsername);
--  }
--  run_next_test();
--}
--
--// Test the _fixFontSize() method and ensure that it correctly fixes font sizes
--// in <font> tags while keeping any mention of size= in conversation untouched.
--function test_fixFontSize()
--{
--  // This is an array of two-element arrays. Each inner two-element array
--  // contains a message with a badly formed font size as the first element,
--  // and a message with a well-formed font size as the second element. We test
--  // to ensure that the badly formed message is converted to the well-formed
--  // one.
--  let testMessages = [
--    // Single font tag.
--    ["<font face=\"Arial\" size=\"12\">Test message 1",
--     "<font face=\"Arial\" size=\"3\">Test message 1"],
--    // Single font tag with size="<digit>" in innner message.
--    ["<font face=\"Arial\" size=\"9\">size=\"30\" is a big size.</font>",
--     "<font face=\"Arial\" size=\"2\">size=\"30\" is a big size.</font>"],
--    // Single font tag with no face attribute.
--    ["<font size=\"12\">This message has no font face attribute.",
--     "<font size=\"3\">This message has no font face attribute."],
--    // Single font tag with no size attribute.
--    ["<font face=\"Arial\">This message has no font size attribute.",
--     "<font face=\"Arial\">This message has no font size attribute."],
--    // Single font tag with rearranged attribute order.
--    ["<font size=\"9\" face=\"Arial\">size=\"30\" is a big size.</font>",
--     "<font size=\"2\" face=\"Arial\">size=\"30\" is a big size.</font>"],
--    // Multiple font tags.
--    ["<font face=\"Arial\" size=\"12\">Hello. <font face=\"Consolas\" size=\"40\">World",
--     "<font face=\"Arial\" size=\"3\">Hello. <font face=\"Consolas\" size=\"7\">World"]
--  ];
--
--  let fakeProtocol = {
--    id: "fake-proto",
--    options: {
--      local_charset: "UTF-8"
--    },
--    _getOptionDefault: function(aOption) { return this.options[aOption]; }
--  };
--  let fakeImAccount = {name: "test-user"};
--  // We create a fake conversation object so we can obtain the cleaned up
--  // message from the conv.writeMessage() call.
--  let messagePair;
--  let fakeConversation = {
--    writeMessage: function(aName, aMessage, aProperties) {
--      do_check_eq(aMessage, messagePair[1]); // Compare to the good message.
--    },
--    updateTyping: function(aStatus, aName) { }
--  };
--
--  let yahooAccount = new yahoo.YahooAccount(fakeProtocol, fakeImAccount);
--  yahooAccount._conversations.set("test-user", fakeConversation);
--  for each(let pair in testMessages) {
--    messagePair = pair;
--    // Send in the badly formed message.
--    yahooAccount.receiveMessage("test-user", messagePair[0]);
--  }
--  run_next_test();
--}
-diff --git a/chat/protocols/yahoo/test/test_yahooLoginHelper.js b/chat/protocols/yahoo/test/test_yahooLoginHelper.js
-deleted file mode 100644
-index e4d8bc1b8..000000000
---- a/chat/protocols/yahoo/test/test_yahooLoginHelper.js
-+++ /dev/null
-@@ -1,89 +0,0 @@
--/* Any copyright is dedicated to the Public Domain.
-- * http://creativecommons.org/publicdomain/zero/1.0/ */
--
--Components.utils.import("resource:///modules/ArrayBufferUtils.jsm");
--Components.utils.import("resource://gre/modules/Services.jsm");
--Components.utils.import("resource:///modules/yahoo-session.jsm");
--var yahoo = {};
--Services.scriptloader.loadSubScript("resource:///modules/yahoo-session.jsm", yahoo);
--
--// Preset test values.
--var kUsername = "testUser";
--var kPassword = "instantbird";
--var kPagerIp = "123.456.78.9";
--var kCrumb = "MG-Z/jNG+Q==";
--var kChallengeString = "AEF08DBAC33F9EEDABCFEA==";
--var kYCookie = "OTJmMTQyOTU1ZGQ4MDA3Y2I2ODljMTU5";
--var kTCookie = "NTdlZmIzY2Q4ODI3ZTc3NTIxYTk1MDhm";
--var kToken = "MThmMzg3OWM3ODcxMW";
--
--var kPagerAddressResponse = "COLO_CAPACITY=1\r\nCS_IP_ADDRESS=" + kPagerIp;
--var kTokenResponse = "0\r\n" + kToken + "\r\npartnerid=dummyValue";
--var kCookieResponse = "0\r\ncrumb=" + kCrumb + "\r\nY=" + kYCookie +
--                        "\r\nT=" + kTCookie + "\r\ncookievalidfor=86400";
--
--/* In each test, we override the function that would normally be called next in
-- * the login process. We do this so that we can intercept the login process,
-- * preventing calls to real Yahoo! servers, and do equality testing. */
--function run_test()
--{
--  add_test(test_pagerAddress);
--  add_test(test_challengeString);
--  add_test(test_loginToken);
--  add_test(test_cookies);
--  run_next_test();
--}
--
--function test_pagerAddress()
--{
--  let helper = new yahoo.YahooLoginHelper({}, {});
--
--  helper._getChallengeString = function() {
--    do_check_eq(kPagerIp, helper._session.pagerAddress);
--    run_next_test();
--  };
--
--  helper._onPagerAddressResponse(kPagerAddressResponse, null);
--}
--
--function test_challengeString()
--{
--  let helper = new yahoo.YahooLoginHelper({}, {});
--
--  helper._getLoginToken = function() {
--    do_check_eq(kChallengeString, helper._challengeString);
--    run_next_test();
--  };
--
--  let response = new yahoo.YahooPacket(yahoo.kPacketType.AuthResponse, 0, 0);
--  response.addValue(1, helper._username);
--  response.addValue(94, kChallengeString);
--  response.addValue(13, 0);
--  helper._onChallengeStringResponse(response.toArrayBuffer());
--}
--
--function test_loginToken()
--{
--  let helper = new yahoo.YahooLoginHelper({}, {});
--
--  helper._getCookies = function() {
--    do_check_eq(kToken, helper._loginToken);
--    run_next_test();
--  };
--
--  helper._onLoginTokenResponse(kTokenResponse, null);
--}
--
--function test_cookies()
--{
--  let helper = new yahoo.YahooLoginHelper({}, {});
--
--  helper._sendPagerAuthResponse = function() {
--    do_check_eq(kCrumb, helper._crumb);
--    do_check_eq(kYCookie, helper._session.yCookie);
--    do_check_eq(kTCookie, helper._session.tCookie);
--    run_next_test();
--  };
--
--  helper._onLoginCookiesResponse(kCookieResponse, null);
--}
-diff --git a/chat/protocols/yahoo/test/test_yahoopacket.js b/chat/protocols/yahoo/test/test_yahoopacket.js
-deleted file mode 100644
-index 7908c4429..000000000
---- a/chat/protocols/yahoo/test/test_yahoopacket.js
-+++ /dev/null
-@@ -1,217 +0,0 @@
--/* Any copyright is dedicated to the Public Domain.
-- * http://creativecommons.org/publicdomain/zero/1.0/ */
--
--Components.utils.import("resource:///modules/ArrayBufferUtils.jsm");
--Components.utils.import("resource://gre/modules/Services.jsm");
--Components.utils.import("resource:///modules/yahoo-session.jsm");
--var yahoo = {};
--Services.scriptloader.loadSubScript("resource:///modules/yahoo-session.jsm", yahoo);
--
--var kPacketIdBytes = StringToBytes(yahoo.kPacketIdentfier);
--var kHelloKey = 1;
--var kHelloValue = "Hello";
--var kWorldKey = 20;
--var kWorldValue = "World";
--var kNumberKey = 4;
--var kNumberValue = 32;
--var kParamsKey = 60;
--var kParam1Value = "param1";
--var kParam2Value = "param2";
--var kPacketDataString = "1\xC0\x80Hello\xC0\x8020\xC0\x80World\xC0\x80" +
--                          "4\xC0\x8032\xC0\x8060\xC0\x80param1\xC0\x80" +
--                          "60\xC0\x80param2\xC0\x80";
--
--function run_test()
--{
--  add_test(test_headerCreation);
--  add_test(test_fullPacketCreation);
--  add_test(test_packetDecoding);
--  add_test(test_extractPackets);
--  add_test(test_malformedPacketExtraction);
--
--  run_next_test();
--}
--
--function test_headerCreation()
--{
--  let packetLength = 0;
--  // Random numbers.
--  let serviceNumber = 0x57;
--  let status = 0x04;
--  let sessionId = 0x57842390;
--
--  let packet = new yahoo.YahooPacket(serviceNumber, status, sessionId);
--  let buf = packet.toArrayBuffer();
--  let view = new DataView(buf);
--
--  // Ensure that the first 4 bytes contain the YMSG identifier.
--  for (let i = 0; i < kPacketIdBytes.length; ++i)
--    do_check_eq(kPacketIdBytes[i], view.getUint8(i));
--
--  do_check_eq(yahoo.kProtocolVersion, view.getUint16(4));
--  do_check_eq(yahoo.kVendorId, view.getUint16(6));
--  do_check_eq(packetLength, view.getUint16(8));
--  do_check_eq(serviceNumber, view.getUint16(10));
--  do_check_eq(status, view.getUint32(12));
--  do_check_eq(sessionId, view.getUint32(16));
--
--  run_next_test();
--}
--
--function test_fullPacketCreation()
--{
--  packetLength = kPacketDataString.length;
--  // Random numbers.
--  let serviceNumber = 0x55;
--  let status = 0x02;
--  let sessionId = 0x12567800;
--
--  let packet = new yahoo.YahooPacket(serviceNumber, status, sessionId);
--  packet.addValue(kHelloKey, kHelloValue);
--  packet.addValue(kWorldKey, kWorldValue);
--  packet.addValue(kNumberKey, kNumberValue);
--  packet.addValues(kParamsKey, [kParam1Value, kParam2Value]);
--  let buf = packet.toArrayBuffer();
--  let view = new DataView(buf);
--
--  // Header check.
--
--  // Ensure that the first 4 bytes contain the YMSG identifier.
--  for (let i = 0; i < kPacketIdBytes.length; ++i)
--    do_check_eq(kPacketIdBytes[i], view.getUint8(i));
--
--  do_check_eq(yahoo.kProtocolVersion, view.getUint16(4));
--  do_check_eq(yahoo.kVendorId, view.getUint16(6));
--  do_check_eq(packetLength, view.getUint16(8));
--  do_check_eq(serviceNumber, view.getUint16(10));
--  do_check_eq(status, view.getUint32(12));
--  do_check_eq(sessionId, view.getUint32(16));
--
--  // Packet data check.
--  let dataBytes = StringToBytes(kPacketDataString);
--  for (let i = 0; i < dataBytes.length; ++i)
--    do_check_eq(dataBytes[i], view.getUint8(yahoo.kPacketHeaderSize + i));
--  run_next_test()
--}
--
--function test_packetDecoding()
--{
--  let packetLength = kPacketDataString.length;
--  // Random numbers.
--  let serviceNumber = 0x20;
--  let status = 0x06;
--  let sessionId = 0x13319AB2;
--
--  let buf = new ArrayBuffer(yahoo.kPacketHeaderSize + packetLength);
--  let view = new DataView(buf);
--
--  for (let i = 0; i < kPacketIdBytes.length; ++i)
--    view.setUint8(i, kPacketIdBytes[i]);
--
--  view.setUint16(4, yahoo.kProtocolVersion);
--  view.setUint16(6, yahoo.kVendorId);
--  view.setUint16(8, packetLength);
--  view.setUint16(10, serviceNumber);
--  view.setUint32(12, status);
--  view.setUint32(16, sessionId);
--
--  let dataBuf = BytesToArrayBuffer(StringToBytes(kPacketDataString));
--  copyBytes(buf, dataBuf, 20);
--
--  // Now we decode and test.
--  let packet = new yahoo.YahooPacket();
--  packet.fromArrayBuffer(buf);
--
--  // Test header information.
--  do_check_eq(serviceNumber, packet.service);
--  do_check_eq(status, packet.status);
--  do_check_eq(sessionId, packet.sessionId);
--
--  // Test the getting of single packet data values.
--  do_check_eq(kHelloValue, packet.getValue(kHelloKey));
--  do_check_eq(kWorldValue, packet.getValue(kWorldKey));
--  do_check_eq(kNumberValue, packet.getValue(kNumberKey));
--
--  // Test the getting of multiple values with a single key.
--  let multiValue = packet.getValues(kParamsKey);
--  do_check_eq(2, multiValue.length);
--  do_check_eq(kParam1Value, multiValue[0]);
--  do_check_eq(kParam2Value, multiValue[1]);
--
--  // Test if certain keys are non-existant.
--  do_check_true(packet.hasKey(kHelloKey));
--  do_check_false(packet.hasKey(500)); // There is no key 500.
--
--  run_next_test();
--}
--
--function test_extractPackets()
--{
--  // Some constants for each packet.
--  const kP1Service = 0x47;
--  const kP1Status = 0;
--  const kP1SessionId = 0x12345678;
--  // Used for testing packet verification.
--  const kP1FuzzerKey = 42;
--  const kP1FuzzerValue = "I am using the YMSG protocol!";
--
--  const kP2Service = 0x57;
--  const kP2Status = 5;
--  const kP2SessionId = 0x87654321;
--
--  // First, create two packets and obtain their buffers.
--  let packet1 = new yahoo.YahooPacket(kP1Service, kP1Status, kP1SessionId);
--  packet1.addValue(kHelloKey, kHelloValue);
--  packet1.addValue(kP1FuzzerKey, kP1FuzzerValue);
--  let packet1Buffer = packet1.toArrayBuffer();
--
--  let packet2 = new yahoo.YahooPacket(kP2Service, kP2Status, kP2SessionId);
--  packet2.addValue(kWorldKey, kWorldValue);
--  let packet2Buffer = packet2.toArrayBuffer();
--
--  // Create one full buffer with both packets inside.
--  let fullBuffer = new ArrayBuffer(packet1Buffer.byteLength +
--                                   packet2Buffer.byteLength);
--  copyBytes(fullBuffer, packet1Buffer);
--  copyBytes(fullBuffer, packet2Buffer, packet1Buffer.byteLength);
--
--  // Now, run the packets through the extractPackets() method.
--  let [extractedPackets, bytesHandled] =
--      yahoo.YahooPacket.extractPackets(fullBuffer);
--  do_check_eq(2, extractedPackets.length);
--
--  // Packet 1 checks.
--  let p1 = extractedPackets[0];
--  do_check_eq(kP1Service, p1.service);
--  do_check_eq(kP1Status, p1.status);
--  do_check_eq(kP1SessionId, p1.sessionId);
--  do_check_true(p1.hasKey(kHelloKey));
--  do_check_eq(kHelloValue, p1.getValue(kHelloKey));
--
--  // Packet 2 checks.
--  let p2 = extractedPackets[1];
--  do_check_eq(kP2Service, p2.service);
--  do_check_eq(kP2Status, p2.status);
--  do_check_eq(kP2SessionId, p2.sessionId);
--  do_check_true(p2.hasKey(kWorldKey));
--  do_check_eq(kWorldValue, p2.getValue(kWorldKey));
--
--  // Check if all the bytes were handled.
--  do_check_eq(fullBuffer.byteLength, bytesHandled);
--
--  run_next_test();
--}
--
--function test_malformedPacketExtraction()
--{
--  const kInvalidPacketData = "MSYG1\xC0\x80Hello\xC0\x8020\xC0\x80World\xC0\x80";
--  let buffer = BytesToArrayBuffer(StringToBytes(kInvalidPacketData));
--  let malformed = false;
--  try {
--    yahoo.YahooPacket.extractPackets(buffer);
--  } catch(e) {
--    malformed = true;
--  }
--  do_check_true(malformed);
--  run_next_test();
--}
-diff --git a/chat/protocols/yahoo/test/xpcshell.ini b/chat/protocols/yahoo/test/xpcshell.ini
-deleted file mode 100644
-index f4b464e61..000000000
---- a/chat/protocols/yahoo/test/xpcshell.ini
-+++ /dev/null
-@@ -1,7 +0,0 @@
--[DEFAULT]
--head =
--tail =
--
--[test_yahooAccount.js]
--[test_yahooLoginHelper.js]
--[test_yahoopacket.js]
-diff --git a/chat/protocols/yahoo/yahoo-session.jsm b/chat/protocols/yahoo/yahoo-session.jsm
-deleted file mode 100644
-index cc9612036..000000000
---- a/chat/protocols/yahoo/yahoo-session.jsm
-+++ /dev/null
-@@ -1,1156 +0,0 @@
--/* This Source Code Form is subject to the terms of the Mozilla Public
-- * License, v. 2.0. If a copy of the MPL was not distributed with this
-- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
--
--this.EXPORTED_SYMBOLS = ["YahooSession"];
--
--var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
--
--Cu.import("resource://gre/modules/FileUtils.jsm");
--Cu.import("resource://gre/modules/Http.jsm");
--Cu.import("resource://gre/modules/NetUtil.jsm");
--Cu.import("resource:///modules/ArrayBufferUtils.jsm");
--Cu.import("resource:///modules/imServices.jsm");
--Cu.import("resource:///modules/imXPCOMUtils.jsm");
--Cu.import("resource:///modules/socket.jsm");
--
--XPCOMUtils.defineLazyGetter(this, "_", () =>
--  l10nHelper("chrome://chat/locale/yahoo.properties")
--);
--
--XPCOMUtils.defineLazyServiceGetter(this, "imgTools",
--                                   "@mozilla.org/image/tools;1", "imgITools");
--
--var kProtocolVersion = 16;
--var kVendorId = 0;
--
--var kPacketDataDelimiter = "\xC0\x80";
--var kPacketIdentifier = "YMSG";
--var kPacketHeaderSize = 20;
--var kProfileIconWidth = 96;
--
--// These constants are used by the icon uploading code since the Yahoo! file
--// transfer server is used for user icon uploads.
--var kFileTransferHost = "filetransfer.msg.yahoo.com";
--var kFileTransferPort = 80;
--
--var kPacketType = {
--  // Sent by a client when logging off of the Yahoo! network.
--  Logoff:         0x02,
--  // Sent by a client when a message is sent to a buddy.
--  Message:        0x06,
--  // Sent to the pager server once per hour.
--  Ping:           0x12,
--  // Used for inviting others to a conference.
--  ConfInvite:     0x18,
--  // Used as a notification when you or someone else joins a conference room.
--  ConfLogon:      0x19,
--  // Used as a notification when you or someone else leaves a conference room.
--  ConfLogoff:     0x1b,
--  // This is sent by the client when additional users are invited to the
--  // conference, but it can be sent as the first invite as well.
--  ConfAddInvite:  0x1c,
--  // Broadcast to all users in a conference room when someone posts a message.
--  ConfMessage:    0x1d,
--  // Used for typing notifications.
--  Notify:         0x4b,
--  // These two are used during initial authentication with the pager server.
--  AuthResponse:   0x54,
--  Auth:           0x57,
--  // Buddy list controls.
--  AddBuddy:       0x83,
--  RemoveBuddy:    0x84,
--  // This is sent when you reject a Yahoo! user's buddy request.
--  BuddyReqReject: 0x86,
--  // Sent to the server once every minute, telling it here are still alive.
--  KeepAlive:      0x8A,
--  // This is sent when we request a buddy icon.
--  Picture:        0xbe,
--  // This is sent after a profile picture has been successfully uploaded.
--  PictureUpload:  0xc2,
--  // This is sent whenever a buddy changes their status.
--  StatusUpdate:   0xc6,
--  // This is sent when we update our icon.
--  AvatarUpdate:   0xc7,
--  // This is sent when someone wishes to become your buddy.
--  BuddyAuth:      0xd6,
--  // Holds the initial status of all buddies when a user first logs in.
--  StatusInitial:  0xf0,
--  // Contains the buddy list sent from the server.
--  List:           0xf1,
--  // Sent back to the pager server after each received message. Sending this
--  // prevents echoed messages when chatting with the official Yahoo! client.
--  MessageAck:     0xfb
--};
--
--var kPacketStatuses = {
--  ServerAck: 0x1,
--  Typing: 0x16
--};
--
--// Each Yahoo! error code is mapped to a two-element array. The first element
--// contains the last part of the name of its localized string. This is appended
--// to "login.error." to obtain the string. The second element is the
--// Instantbird error that is given to the error handler.
--var kLoginStatusErrors = {
--  "1212" : ["badCredentials",
--            Ci.prplIAccount.ERROR_AUTHENTICATION_FAILED],
--  "1213" : ["accountLockedFailed",
--            Ci.prplIAccount.ERROR_AUTHENTICATION_FAILED],
--  "1218" : ["accountDeactivated",
--            Ci.prplIAccount.ERROR_AUTHENTICATION_FAILED],
--  "1235" : ["usernameNotExist",
--            Ci.prplIAccount.ERROR_INVALID_USERNAME],
--  "1236" : ["accountLockedGeneral",
--            Ci.prplIAccount.ERROR_AUTHENTICATION_FAILED]
--};
--
--// These are the status codes that buddies can send us.
--var kBuddyStatuses = {
--  // Available.
--  "0"   : Ci.imIStatusInfo.STATUS_AVAILABLE,
--  // Be right back.
--  "1"   : Ci.imIStatusInfo.STATUS_AWAY,
--  // Busy.
--  "2"   : Ci.imIStatusInfo.STATUS_UNAVAILABLE,
--    // Not at home.
--  "3"   : Ci.imIStatusInfo.STATUS_AWAY,
--  // Not at desk.
--  "4"   : Ci.imIStatusInfo.STATUS_AWAY,
--  // Not in office.
--  "5"   : Ci.imIStatusInfo.STATUS_AWAY,
--  // On phone.
--  "6"   : Ci.imIStatusInfo.STATUS_AWAY,
--  // On vacation.
--  "7"   : Ci.imIStatusInfo.STATUS_AWAY,
--  // Out to lunch.
--  "8"   : Ci.imIStatusInfo.STATUS_AWAY,
--  // Stepped out.
--  "9"   : Ci.imIStatusInfo.STATUS_AWAY,
--    // Invisible.
--  "12"  : Ci.imIStatusInfo.STATUS_INVISIBLE,
--  // Custom status.
--  "99"  : Ci.imIStatusInfo.STATUS_AWAY,
--  // Idle.
--  "999" : Ci.imIStatusInfo.STATUS_IDLE
--};
--
--/* The purpose of the YahooSession object is to serve as a gateway between the
-- * protocol plug-in and the Yahoo! Messenger servers. Anytime an object outside
-- * of this file wishes to communicate with the servers, it should do it through
-- * one of the methods provided by YahooSession. By centralizing such network
-- * access, we can easily catch errors, and ensure that communication is handled
-- * correctly. */
--function YahooSession(aAccount)
--{
--  this._account = aAccount;
--  this.binaryMode = true;
--}
--YahooSession.prototype = {
--  __proto__: Socket,
--  _account: null,
--  _socket: null,
--  _username: null,
--  // This is the IPv4 address to the pager server which is the gateway into the
--  // Yahoo! Messenger network.
--  pagerAddress: null,
--  // The session ID is obtained during the login process and is maintained
--  // throughout the session. This helps the pager server identify the client.
--  sessionId: null,
--  // The T and Y cookies obtained by the YahooLoginHelper during login.
--  tCookie: null,
--  yCookie: null,
--
--  // Public methods.
--  login: function() {
--    this._account.reportConnecting();
--    new YahooLoginHelper(this).login(this._account);
--  },
--
--  sendPacket: function(aPacket) {
--    this.sendBinaryData(aPacket.toArrayBuffer(), aPacket.toString());
--  },
--
--  addBuddyToServer: function(aBuddy) {
--    let packet = new YahooPacket(kPacketType.AddBuddy, 0, this.sessionId);
--    // We leave this invite message empty. Any message placed here will
--    // annoyingly be sent to the invitee when they accept the invite.
--    packet.addValue(14, "");
--    packet.addValue(65, aBuddy.tag.name);
--    packet.addValue(97, "1"); // UTF-8 encoding.
--    packet.addValue(1, this._account.cleanUsername);
--    // The purpose of these two values are unknown.
--    packet.addValue(302, "319");
--    packet.addValue(300, "319");
--    packet.addValue(7, aBuddy.userName);
--    // The purpose of these three values are also unknown.
--    packet.addValue(334, "0");
--    packet.addValue(301, "319");
--    packet.addValue(303, "319");
--    this.sendPacket(packet);
--  },
--
--  removeBuddyFromServer: function(aBuddy) {
--    let packet = new YahooPacket(kPacketType.RemoveBuddy, 0, this.sessionId);
--    packet.addValue(1, this._account.cleanUsername);
--    packet.addValue(7, aBuddy.userName);
--    packet.addValue(65, aBuddy.tag.name);
--    this.sendPacket(packet);
--  },
--
--  setStatus: function(aStatus, aMessage) {
--    let packet = new YahooPacket(kPacketType.StatusUpdate, 0, this.sessionId);
--
--    // When a custom status message is used, key 10 is set to 99, and key 97
--    // is set to 1. Otherwise, key 10 is set to our current status code.
--    if (aMessage && aMessage.length > 0) {
--      packet.addValue(10, "99");
--      packet.addValue(97, "1");
--    } else {
--      let statusCode;
--      switch(aStatus) {
--        // Available
--        case Ci.imIStatusInfo.STATUS_AVAILABLE:
--        case Ci.imIStatusInfo.STATUS_MOBILE:
--          statusCode = "0";
--          break;
--        // Away
--        case Ci.imIStatusInfo.STATUS_AWAY:
--          statusCode = "1";
--          break;
--        // Busy
--        case Ci.imIStatusInfo.STATUS_UNAVAILABLE:
--          statusCode = "2";
--          break;
--        // Invisible
--        case Ci.imIStatusInfo.STATUS_INVISIBLE:
--          statusCode = "12";
--          break;
--        // Idle
--        case Ci.imIStatusInfo.STATUS_IDLE:
--          statusCode = "999";
--          break;
--      }
--      packet.addValue(10, statusCode);
--    }
--
--    // Key 19 is always set as the status messgae, even when the message is
--    // empty. If key 10 is set to 99, the message is used.
--    packet.addValue(19, aMessage);
--
--    // Key 47 is always set to either 0, if we are available, or 1, if we are
--    // not available. The value is used by the server if key 10 is set to 99.
--    // Otherwise, the value of key 10 is used to determine our status.
--    packet.addValue(47, (aStatus == Ci.imIStatusInfo.STATUS_AVAILABLE) ?
--                    "0" : "1");
--    this.sendPacket(packet);
--  },
--
--  sendChatMessage: function(aName, aMessage) {
--    let packet = new YahooPacket(kPacketType.Message, 0, this.sessionId);
--    // XXX Key 0 is the user ID, and key 1 is the active ID. We need to find
--    // the difference between these two. Alias maybe?
--    packet.addValue(0, this._account.cleanUsername);
--    packet.addValue(1, this._account.cleanUsername);
--    packet.addValue(5, aName);
--    packet.addValue(14, aMessage);
--    this.sendPacket(packet);
--  },
--
--  sendConferenceMessage: function(aRecipients, aRoom, aMessage) {
--    let packet = new YahooPacket(kPacketType.ConfMessage, 0, this.sessionId);
--    packet.addValue(1, this._account.cleanUsername);
--    packet.addValues(53, aRecipients);
--    packet.addValue(57, aRoom);
--    packet.addValue(14, aMessage);
--    packet.addValue(97, "1"); // Use UTF-8 encoding.
--    this.sendPacket(packet);
--  },
--
--  sendTypingStatus: function(aBuddyName, aIsTyping) {
--    let packet = new YahooPacket(kPacketType.Notify, kPacketStatuses.Typing,
--                                 this.sessionId);
--    packet.addValue(1, this._account.cleanUsername);
--    packet.addValue(5, aBuddyName);
--    packet.addValue(13, aIsTyping ? "1" : "0");
--    packet.addValue(14, " "); // Key 14 contains a single space.
--    packet.addValue(49, "TYPING");
--    this.sendPacket(packet);
--  },
--
--  acceptConferenceInvite: function(aOwner, aRoom, aParticipants) {
--    let packet = new YahooPacket(kPacketType.ConfLogon, 0, this.sessionId);
--    packet.addValue(1, this._account.cleanUsername);
--    packet.addValue(57, aRoom);
--    packet.addValues(3, aParticipants);
--    this.sendPacket(packet);
--  },
--
--  createConference: function(aRoom) {
--    let packet = new YahooPacket(kPacketType.ConfLogon, 0, this.sessionId);
--    packet.addValue(1, this._account.cleanUsername);
--    packet.addValue(3, this._account.cleanUsername);
--    packet.addValue(57, aRoom);
--    this.sendPacket(packet);
--  },
--
--  inviteToConference: function(aInvitees, aRoom, aParticipants, aMessage) {
--    let packet = new YahooPacket(kPacketType.ConfAddInvite, 0, this.sessionId);
--    packet.addValue(1, this._account.cleanUsername);
--    packet.addValues(51, aInvitees);
--    packet.addValues(53, aParticipants);
--    packet.addValue(57, aRoom);
--    packet.addValue(58, aMessage);
--    packet.addValue(13, "0");
--    this.sendPacket(packet);
--  },
--
--  sendConferenceLogoff: function(aName, aParticipants, aRoom) {
--    let packet = new YahooPacket(kPacketType.ConfLogoff, 0, this.sessionId);
--    packet.addValue(1, aName);
--    packet.addValues(3, aParticipants);
--    packet.addValue(57, aRoom);
--    this.sendPacket(packet);
--  },
--
--  setProfileIcon: function(aFileName) {
--    // If we have an empty filename, remove the icon from the server.
--    if (!aFileName) {
--      let packet = new YahooPacket(kPacketType.AvatarUpdate, 0, this.sessionId);
--      packet.addValue(3, this._account.cleanUsername);
--      packet.addValue(213, 0);
--      this.sendPacket(packet);
--      return;
--    }
--    // Try to get a handle to the icon file.
--    let file = FileUtils.getFile("ProfD", [aFileName]);
--    let type = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService)
--                                        .getTypeFromFile(file);
--    NetUtil.asyncFetch({
--        uri: NetUtil.newURI(file),
--        contentPolicyType: Ci.nsIContentPolicy.TYPE_IMAGE,
--        securityFlags: Ci.nsILoadInfo.SEC_NORMAL,
--        loadUsingSystemPrincipal: true
--      }, (aStream, aStatus) => {
--        if (!Components.isSuccessCode(aStatus)) {
--          throw "Could not access icon file.";
--          return;
--        }
--        let image = imgTools.decodeImage(aStream, type);
--        let uploader = new YahooProfileIconUploader(this._account, this,
--                                                    aFileName, image);
--        uploader.uploadIcon();
--      });
--  },
--
--  requestBuddyIcon: function(aName) {
--    let packet = new YahooPacket(kPacketType.Picture, 0, this.sessionId);
--    packet.addValue(1, this._account.cleanUsername);
--    packet.addValue(5, aName); // The name of the buddy.
--    packet.addValue(13, "1"); // "1" means we wish to request an icon.
--    this.sendPacket(packet);
--  },
--
--  acceptBuddyRequest: function(aRequest) {
--    let packet = new YahooPacket(kPacketType.BuddyAuth, 0, this.sessionId);
--    packet.addValue(1, this._account.cleanUsername);
--    packet.addValue(5, aRequest.userName);
--    // Misc. Unknown flags.
--    packet.addValue(13, 1);
--    packet.addValue(334, 0);
--    this.sendPacket(packet);
--
--    // If someone wants to add us as a buddy, place them under the default
--    // tag. Also, we make sure that the buddy doesn't already exist in the
--    // list in case of a server acknowledgement.
--    if (!this._account.hasBuddy(aRequest.userName))
--      this._account.addBuddy(Services.tags.defaultTag, aRequest.userName);
--  },
--
--  denyBuddyRequest: function(aRequest) {
--    let packet = new YahooPacket(kPacketType.BuddyReqReject, 0, this.sessionId);
--    packet.addValue(1, this._account.cleanUsername);
--    packet.addValue(7, aRequest.userName);
--    packet.addValue(14, "");
--    this.sendPacket(packet);
--  },
--
--  sendKeepAlive: function() {
--    let packet = new YahooPacket(kPacketType.KeepAlive, 0, this.sessionId);
--    packet.addValue(0, this._account.cleanUsername);
--    this.sendBinaryData(packet.toArrayBuffer());
--  },
--
--  sendPing: function() {
--    let packet = new YahooPacket(kPacketType.Ping, 0, this.sessionId);
--    this.sendBinaryData(packet.toArrayBuffer());
--  },
--
--  // Callbacks.
--  onLoginComplete: function() {
--    this._account.reportConnected();
--    this._account.onLoginComplete();
--  },
--
--  onSessionError: function(aError, aMessage) {
--    this._account.reportDisconnecting(aError, aMessage);
--    if (!this.disconnected)
--      this.disconnect();
--    this._account.reportDisconnected();
--  },
--
--  // Private methods.
--
--  // Socket Event Callbacks.
--  LOG: function(aString) { return this._account.LOG(aString); },
--
--  DEBUG: function(aString) { return this._account.DEBUG(aString); },
--
--  onConnection: function() {
--    // We send an authentication request packet as soon as we connect to the
--    // pager server.
--    let packet = new YahooPacket(kPacketType.Auth, 0, 0);
--    packet.addValue(1, this._account.cleanUsername);
--    this.sendPacket(packet);
--  },
--
--  onConnectionTimedOut: function() {
--    this.onSessionError(Ci.prplIAccount.NETWORK_ERROR, "");
--  },
--
--  onConnectionReset: function() {
--    this.onSessionError(Ci.prplIAccount.NETWORK_ERROR, "");
--  },
--
--  // Called when the other end has closed the connection.
--  onConnectionClosed: function() {
--    if (!this._account.connected)
--      return;
--    this._account.reportDisconnecting(Ci.prplIAccount.NO_ERROR, "");
--    this._account.reportDisconnected();
--  },
--
--  onBinaryDataReceived: function(aData) {
--    let packets;
--    let bytesHandled;
--    try {
--      [packets, bytesHandled] = YahooPacket.extractPackets(aData);
--    } catch(e) {
--      this._account.ERROR(e);
--      this.onSessionError(Ci.prplIAccount.NETWORK_ERROR, "");
--      return 0;
--    }
--
--    for each (let packet in packets) {
--      this._account.LOG("Received Packet:\n" + packet.toString());
--      if (YahooPacketHandler.hasOwnProperty(packet.service)) {
--        try {
--          YahooPacketHandler[packet.service].call(this._account, packet);
--        } catch(e) {
--          this._account.ERROR(e);
--        }
--      } else {
--        this._account.WARN("No handler for Yahoo! packet " +
--                           packet.service.toString(16) + ".");
--      }
--    }
--    return bytesHandled;
--  }
--};
--
--/* The purpose of YahooLoginHelper is to separate the complicated login logic
-- * from the YahooSession object. Logging in on Yahoo!'s network is the most
-- * complicated stage of a session due to the authentication system that is
-- * employed. The login steps are listed below.
-- *
-- * 1) Get the address of a "pager" server. This pager will be our gateway to
-- *    the network.
-- *
-- * 2) Obtain the challenge string from the pager. This string is used to help
-- *    create the base64 response string needed for the final step.
-- *
-- * 3) Obtain a token from the login server via HTTP.
-- *
-- * 4) Obtain the login crumb, Y-Cookie, and T-Cookie from the login server via
-- *    HTTP. These will also be used in the final response packet to the pager.
-- *
-- * 5) Create the base64 response string from the MD5 hash of the crumb and
-- *    challenge string, and build a packet containing the username, password,
-- *    response string, version numbers, crumb, and cookies, sending it to the
-- *    pager for a final authenticatcation.
-- *
-- * If all goes well after the 5th step, the user is considered logged in. */
--function YahooLoginHelper(aSession)
--{
--  this._session = aSession;
--}
--YahooLoginHelper.prototype = {
--  // YahooSession object passed in constructor.
--  _session: null,
--  // YahooAccount object passed to login().
--  _account: null,
--  // The username, stripped of any @yahoo.com or @yahoo.co.jp suffix.
--  _username: null,
--  // The authentication challenge string sent from the Yahoo!'s login server.
--  _challengeString: null,
--  // The authentication token sent from Yahoo!'s login server.
--  _loginToken: null,
--  // Crumb sent from Yahoo!'s login server, and used in the final authentication
--  // request to the pager server.
--  _crumb: null,
--
--  // Public methods.
--  login: function(aAccount) {
--    this._account = aAccount;
--    this._getPagerAddress();
--  },
--
--  // Private methods.
--  _getPagerAddress: function() {
--    let options = {
--      onLoad: this._onPagerAddressResponse.bind(this),
--      onError: this._onHttpError.bind(this)
--    }
--    httpRequest(this._account._protocol.pagerRequestUrl, options);
--  },
--
--  _getChallengeString: function() {
--    let port = this._account.getInt("port");
--    this._session.connect(this._session.pagerAddress, port);
--    // We want to handle a challenge string when the server responds.
--    this._session.onBinaryDataReceived =
--      this._onChallengeStringResponse.bind(this);
--  },
--
--  _getLoginToken: function() {
--    // TODO - Simplify this using map and join.
--    let url = this._account._protocol.loginTokenGetUrl;
--    url += "?src=ymsgr&";
--    url += "login=" + percentEncode(this._account.cleanUsername) + "&";
--    url += "passwd=" + percentEncode(this._account.imAccount.password) + "&";
--    url += "chal=" + percentEncode(this._challengeString);
--
--    let options = {
--      onLoad: this._onLoginTokenResponse.bind(this),
--      onError: this._onHttpError.bind(this)
--    }
--    httpRequest(url, options);
--  },
--
--  _getCookies: function() {
--    // TODO - Simplify this using map and join.
--    let url = this._account._protocol.loginTokenLoginUrl;
--    url += "?src=ymsgr&";
--    url += "token=" + this._loginToken;
--
--    let options = {
--      onLoad: this._onLoginCookiesResponse.bind(this),
--      onError: this._onHttpError.bind(this)
--    }
--    httpRequest(url, options);
--  },
--
--  _sendPagerAuthResponse: function() {
--    let response = this._calculatePagerResponse();
--    let packet = new YahooPacket(kPacketType.AuthResponse, 0,
--                                 this._session.sessionId);
--    // Build the key/value pairs.
--    packet.addValue(1, this._account.cleanUsername);
--    packet.addValue(0, this._account.cleanUsername);
--    packet.addValue(277, this._session.yCookie);
--    packet.addValue(278, this._session.tCookie);
--    packet.addValue(307, response);
--    packet.addValue(244, this._account.protocol.buildId);
--    packet.addValue(2, this._account.cleanUsername);
--    packet.addValue(2, "1");
--    packet.addValue(98, "us");
--    this._session.sendPacket(packet);
--    // We want to handle a final login confirmation packet when the server
--    // responds.
--    this._session.onBinaryDataReceived = this._onFinalLoginResponse.bind(this);
--  },
--
--  _calculatePagerResponse: function() {
--    let hasher = Cc["@mozilla.org/security/hash;1"]
--                   .createInstance(Ci.nsICryptoHash);
--    hasher.init(hasher.MD5);
--
--    let crypt = this._crumb + this._challengeString;
--    let cryptData = StringToBytes(crypt);
--    hasher.update(cryptData, cryptData.length);
--
--    // The protocol requires replacing + with ., / with _, and = with - within
--    // the base64 response string.
--    return btoa(hasher.finish(false)).replace(/\+/g, ".").replace(/\//g, "_")
--                                     .replace(/=/g, "-");
--  },
--
--  _handleLoginError: function(aErrorCode) {
--    let errorInfo = kLoginStatusErrors[aErrorCode];
--    let errorMessage;
--    let error;
--
--    // If we find information on the error code we received, we will use that
--    // information. If the error wasn't found in our error table, just throw a
--    // generic error with the code included.
--    if (errorInfo) {
--      errorMessage = _("login.error." + errorInfo[0]);
--      error = errorInfo[1];
--    } else {
--      errorMessage = _("login.error.unknown", aErrorCode);
--      error = Ci.prplIAccount.ERROR_OTHER_ERROR;
--      // We also throw a console error because we didn't expect
--      // this error code.
--      this._account.ERROR("Received unknown error from pager server. Code: " +
--                          aErrorCode);
--    }
--    this._session.onSessionError(error, errorMessage);
--  },
--
--  _onHttpError: function(aError, aStatusText, aXHR) {
--    this._session.onSessionError(Ci.prplIAccount.NETWORK_ERROR,
--                                 _("network.error.http"));
--  },
--
--  // HTTP Response Callbacks.
--  _onPagerAddressResponse: function(aResponse, aXHR) {
--    this._session.pagerAddress =
--      aResponse.substring(aResponse.lastIndexOf("=") + 1);
--    this._getChallengeString();
--  },
--
--  _onLoginTokenResponse: function(aResponse, aXHR) {
--    let responseParams = aResponse.split("\r\n");
--    // Status code "0" means success.
--    let statusCode = responseParams[0];
--    if (statusCode != "0") {
--      this._handleLoginError(statusCode);
--      return;
--    }
--
--    this._loginToken = responseParams[1].replace("ymsgr=", "");
--    this._getCookies();
--  },
--
--  _onLoginCookiesResponse: function(aResponse, aXHR) {
--    let responseParams = aResponse.split("\r\n");
--    // Status code "0" means success.
--    let statusCode = responseParams[0];
--    if (statusCode != "0") {
--      this._handleLoginError(statusCode);
--      return;
--    }
--
--    this._crumb = responseParams[1].replace("crumb=", "");
--    // Remove the "Y=" bit.
--    this._session.yCookie = responseParams[2].substring(2);
--    // Remove the "T=" bit.
--    this._session.tCookie = responseParams[3].substring(2);
--    this._sendPagerAuthResponse();
--  },
--
--  // TCP Response Callbacks.
--  _onChallengeStringResponse: function(aData) {
--    let packet = new YahooPacket();
--    packet.fromArrayBuffer(aData);
--    // The value of the challenge string is associated with key 94.
--    this._challengeString = packet.getValue(94);
--    this._session.sessionId = packet.sessionId;
--    this._getLoginToken();
--  },
--
--  _onFinalLoginResponse: function(aData) {
--    this._session.onLoginComplete();
--    // We need to restore data handling to the YahooSession object since our
--    // login steps are complete.
--    this._session.onBinaryDataReceived =
--      YahooSession.prototype.onBinaryDataReceived.bind(this._session);
--  }
--};
--
--/* The YahooPacket class represents a single Yahoo! Messenger data packet.
-- * Using this class allows you to easily create packets, stuff them with
-- * required data, and convert them to/from ArrayBuffer objects. */
--function YahooPacket(aService, aStatus, aSessionId)
--{
--  this.service = aService;
--  this.status = aStatus;
--  this.sessionId = aSessionId;
--  this.keyValuePairs = [];
--}
--YahooPacket.prototype = {
--  service: null,
--  status: null,
--  sessionId: null,
--  keyValuePairs: null,
--
--  // Public methods.
--
--  // Add a single key/value pair.
--  addValue: function(aKey, aValue) {
--    let pair = {
--      key: aKey.toString(), // The server handles keys as ASCII number values.
--      value: aValue
--    };
--
--    this.keyValuePairs.push(pair);
--  },
--
--  // Add multiple key/value pairs with the same key but different values
--  // stored in an array.
--  addValues: function(aKey, aValues) {
--    for each (let value in aValues)
--      this.addValue(aKey, value);
--  },
--
--  // This method returns the first value found with the given key.
--  getValue: function(aKey) {
--    for (let i = 0; i < this.keyValuePairs.length; ++i) {
--      let pair = this.keyValuePairs[i];
--      // The server handles keys as ASCII number values.
--      if (pair.key == aKey.toString())
--        return pair.value;
--    }
--
--    // Throw an error if the key wasn't found.
--    throw "Required key " + aKey + " wasn't found. Packet Service: " +
--          this.service.toString(16);
--  },
--
--  // This method returns all of the values found with the given key. In some
--  // packets, one key is associated with multiple values. If that is the case,
--  // use this method to retrieve all of them instead of just the first one.
--  getValues: function(aKey) {
--    let values = [];
--    for (let i = 0; i < this.keyValuePairs.length; ++i) {
--      let pair = this.keyValuePairs[i];
--      // The server handles keys as ASCII number values.
--      if (pair.key == aKey.toString())
--        values.push(pair.value);
--    }
--
--    // Throw an error if no keys were found.
--    if (values.length == 0) {
--      throw "Required key " + aKey + " wasn't found. Packet Service: " +
--            this.service.toString(16);
--    }
--    return values;
--  },
--
--  hasKey: function(aKey) {
--    for (let i = 0; i < this.keyValuePairs.length; ++i) {
--      // The server handles keys as ASCII number values.
--      if (this.keyValuePairs[i].key == aKey.toString())
--        return true;
--    }
--    return false;
--  },
--
--  toArrayBuffer: function() {
--    let dataString = "";
--    for (let i = 0; i < this.keyValuePairs.length; ++i) {
--      let pair = this.keyValuePairs[i];
--      dataString += pair.key + kPacketDataDelimiter;
--      dataString += pair.value + kPacketDataDelimiter;
--    }
--
--    let packetLength = dataString.length;
--    let buffer = new ArrayBuffer(kPacketHeaderSize + packetLength);
--
--    // Build header.
--    let view = new DataView(buffer);
--    let idBytes = StringToBytes(kPacketIdentifier);
--    view.setUint8(0, idBytes[0]);
--    view.setUint8(1, idBytes[1]);
--    view.setUint8(2, idBytes[2]);
--    view.setUint8(3, idBytes[3]);
--    view.setUint16(4, kProtocolVersion);
--    view.setUint16(6, 0); // Vendor ID
--    view.setUint16(8, packetLength);
--    view.setUint16(10, this.service);
--    view.setUint32(12, this.status);
--    view.setUint32(16, this.sessionId);
--
--    // Copy in data.
--    copyBytes(buffer, BytesToArrayBuffer(StringToBytes(dataString)), kPacketHeaderSize);
--
--    return buffer;
--  },
--
--  fromArrayBuffer: function(aBuffer) {
--    let view = new DataView(aBuffer);
--    this.length = view.getUint16(8) + kPacketHeaderSize;
--    this.service = view.getUint16(10);
--    this.status = view.getUint32(12);
--    this.sessionId = view.getUint32(16);
--
--    let dataString = ArrayBufferToString(aBuffer).substring(kPacketHeaderSize);
--    let delimitedData = dataString.split(kPacketDataDelimiter);
--    // Since the data should also end with a trailing delmiter, split() will
--    // add an empty element at the end. We need to pop this element off.
--    delimitedData.pop();
--
--    // If we don't have an even number of delimitedData elements, that means
--    // we are either missing a key or a value.
--    if (delimitedData.length % 2 != 0) {
--      throw "Odd number of data elements. Either a key or value is missing. "
--            "Num of elements: " + delimitedData.length;
--    }
--
--    for (let i = 0; i < delimitedData.length; i += 2) {
--      let key = delimitedData[i];
--      let value = delimitedData[i + 1];
--      if (key && value) {
--        let pair = {
--          key: key,
--          value: value
--        };
--        this.keyValuePairs.push(pair);
--      }
--    }
--  },
--
--  toString: function() {
--    // First, add packet header information.
--    let s = "Service: 0x" + this.service.toString(16) + "\n";
--    s += "Status: 0x" + this.status.toString(16) + "\n";
--    s += "Session ID: 0x" + this.sessionId.toString(16);
--    // Now we add the packet data, if there is some.
--    if (this.keyValuePairs.length) {
--      // Add two preceding newlines for space to make reading easier.
--      s += "\n\nPacket Key-Value Data:\n";
--      for each (let pair in this.keyValuePairs)
--        s += pair.key + ":\t" + pair.value + "\n";
--    }
--    return s;
--  }
--};
--YahooPacket.extractPackets = function(aData, aOnNetworkError) {
--  let packets = [];
--  let bytesHandled = 0;
--
--  while (aData.byteLength >= kPacketHeaderSize) {
--    if (ArrayBufferToString(aData.slice(0, kPacketIdentifier.length)) !=
--        kPacketIdentifier) {
--      throw "Malformed packet received. Packet content: " +
--            ArrayBufferToHexString(aData);
--    }
--
--    let packetView = new DataView(aData);
--    let packetLength = packetView.getUint16(8) + kPacketHeaderSize;
--    // Don't process half packets.
--    if (packetLength > aData.byteLength)
--      break;
--    let packet = new YahooPacket();
--    packet.fromArrayBuffer(aData.slice(0, packetLength));
--    packets.push(packet);
--    bytesHandled += packetLength;
--    aData = aData.slice(packetLength);
--  }
--  return [packets, bytesHandled];
--}
--
--/* In YahooPacketHandler, each handler function is assosiated with a packet
-- * service number. You can use the kPacketType enumeration to understand
-- * what kind of packet each number is linked to.
-- *
-- * Keep in mind too that "this" in each function will be bound to a
-- * YahooAccount object, since they are all invoked using call(). */
--var YahooPacketHandler = {
--  // Buddy logoff.
--  0x02: function(aPacket) {
--    let name = aPacket.getValue(7);
--    this.setBuddyStatus(name, Ci.imIStatusInfo.STATUS_OFFLINE, "");
--  },
--
--  // Incoming chat message.
--  0x06: function(aPacket) {
--    let from = aPacket.getValue(4);
--    let to = aPacket.getValue(5);
--    let message = aPacket.getValue(14);
--    this.receiveMessage(from, message);
--
--    // The official Yahoo! Messenger desktop client requires message ACKs to be
--    // sent back to the server. The web client doesn't require this. A good
--    // indication of when an ACK is required is when key 429 is sent, which
--    // contains the ID of the message. When a message is sent from the official
--    // desktop client, and no ACK is sent back, the message is resent seconds
--    // later.
--    if (aPacket.hasKey(429)) {
--      let messageId = aPacket.getValue(429);
--      let packet = new YahooPacket(kPacketType.MessageAck, 0, aPacket.sessionId);
--      // Some keys have an unknown purpose, so we set a constant value.
--      packet.addValue(1, to);
--      packet.addValue(5, from);
--      packet.addValue(302, "430");
--      packet.addValue(430, messageId);
--      packet.addValue(303, 430);
--      packet.addValue(450, 0);
--      this._session.sendPacket(packet);
--    }
--  },
--
--  // New mail notification.
--  // TODO: Implement this handler when mail notifications are handled in the
--  // base code.
--  0x0b: function(aPacket) {},
--
--  // Server ping.
--  // TODO: Add support for ping replies.
--  0x12: function(aPacket) {},
--
--  // Conference invitation.
--  0x18: function(aPacket) {
--    let owner = aPacket.getValue(50);
--    let roomName = aPacket.getValue(57);
--    let participants = aPacket.getValues(53);
--    // The owner is also a participant.
--    participants.push(owner);
--    let message = aPacket.getValue(58);
--    this.receiveConferenceInvite(owner, roomName, participants, message);
--  },
--
--  // Conference logon.
--  0x19: function(aPacket) {
--    let userName = aPacket.getValue(53);
--    let room = aPacket.getValue(57);
--    this.receiveConferenceLogon(room, userName);
--  },
--
--  // Conference logoff
--  0x1b: function(aPacket) {
--    let userName = aPacket.getValue(56);
--    let roomName = aPacket.getValue(57);
--    this.receiveConferenceLogoff(roomName, userName);
--  },
--
--  // Conference additional invitation. NOTE: Since this packet has the same
--  // structure as the normal conference invite (packet 0x18), we simply
--  // reuse that handler.
--  0x1c: function(aPacket) { return YahooPacketHandler[0x18].call(this, aPacket); },
--
--  // Conference message.
--  0x1d: function(aPacket) {
--    let from = aPacket.getValue(3);
--    let room = aPacket.getValue(57);
--    let message = aPacket.getValue(14);
--    this.receiveConferenceMessage(from, room, message);
--  },
--
--  // Typing notification.
--  0x4b: function(aPacket) {
--    let name = aPacket.getValue(4);
--    let isTyping = (aPacket.getValue(13) == "1");
--    this.receiveTypingNotification(name, isTyping);
--  },
--
--  // Legacy Yahoo! buddy list. Packet 0xf1 has replaced this.
--  0x55: function(aPacket) {},
--
--  // Authentication acknowledgement. We can ignore this since we are known
--  // to be authenticated if we are receiving other packets anyway.
--  0x57: function(aPacket) {},
--
--  // AddBuddy ack packets can be ignored. They do not depend on whether or not
--  // the buddy accepted the invite.
--  0x83: function(aPacket) {},
--
--  // RemoveBuddy ack packets let us know when we should actually remove the
--  // buddy from the list, keeping us in sync with the server.
--  0x84: function(aPacket) {
--   let buddy = this.getBuddy(aPacket.getValue(7));
--   // The buddy is off the server, so remove it locally.
--   this.removeBuddy(buddy, false);
--  },
--
--  // Picture upload.
--  0xc2: function(aPacket) {
--    let onlineBuddies = this.getOnlineBuddies();
--    // Send a notification to each online buddy that your icon has changed.
--    // Those offline will automatically pick up the change when they log in.
--    for each (let buddy in onlineBuddies) {
--      let packet = new YahooPacket(kPacketType.AvatarUpdate, 0,
--                                   this._session.sessionId);
--      packet.addValue(3, buddy.userName);
--      packet.addValue(213, 2); // A value of 2 means we are using an icon.
--      this._session.sendPacket(packet);
--    }
--  },
--
--  // Buddy icon checksum.
--  // TODO - Make use of the icon checksum to allow icon caching.
--  0xbd: function(aPacket) {
--    // Extract the checksum from the URL parameter chksum.
--    let buddyName = aPacket.getValue(4);
--    let url = aPacket.getValue(20);
--    let parameter = "chksum=";
--    // The "chksum" parameter is the only parameter in the URL.
--    let checksum = url.substring(url.indexOf(parameter) + parameter.length);
--
--    let buddy = this.getBuddy(buddyName);
--    // We only download the new icon if no older checksum exists, or if the
--    // older checksum differs, indicating an updated icon.
--    if (buddy && buddy.iconChecksum !== checksum) {
--      buddy.buddyIconFilename = url;
--      buddy.iconChecksum = checksum;
--    }
--  },
--
--  // Buddy icon request reply. This can be handled in the same way as a buddy
--  // icon checksum packet, so we simply reuse the handler.
--  0xbe: function (aPacket) { return YahooPacketHandler[0xbd].call(this, aPacket); },
--
--  // Buddy status update.
--  0xc6: function (aPacket) {
--    let name = aPacket.getValue(7);
--    // If the user is mobile, use the mobile status.
--    let status = aPacket.hasKey(60) ? Ci.imIStatusInfo.STATUS_MOBILE :
--                                      kBuddyStatuses[aPacket.getValue(10)];
--
--    let message = aPacket.hasKey(19) ? aPacket.getValue(19) : "";
--    this.setBuddyStatus(name, status, message);
--  },
--
--  // Buddy avatar (icon) update.
--  0xc7: function(aPacket) {
--    // Strangely, in some non-official clients, when someone updates their
--    // profile icon we are sent two avatar update packets: one with a default
--    // status containing little information, and another with a Server Ack
--    // status containing the info we need. So we only accept packets with a
--    // Server Ack status to prevent errors.
--    if (aPacket.status != kPacketStatuses.ServerAck)
--      return;
--    // Key 4 contains the name of the buddy who updated their icon.
--    this._session.requestBuddyIcon(aPacket.getValue(4));
--  },
--
--  // Buddy authorization request.
--  0xd6: function(aPacket) {
--    // Whenever we authorize someone to be our buddy, the server will send an
--    // acknowledgement packet. We ignore the ack to prevent the auth request
--    // from showing again.
--    if (aPacket.status == kPacketStatuses.ServerAck)
--      return;
--
--    let session = this._session;
--    let userName = aPacket.getValue(4);
--    this.addBuddyRequest(userName, session.acceptBuddyRequest.bind(session),
--                         session.denyBuddyRequest.bind(session));
--  },
--
--  // XXX: What does this packet do?
--  0xef: function(aPacket) {},
--
--  // Initial user status.
--  0xf0: function (aPacket) {
--    // Return early if we find no buddy names.
--    if (!aPacket.hasKey(7))
--      return;
--
--    // The key/value pairs are in order as sent by the server. So we must
--    // iterate though them to find out information about each buddy. Each
--    // buddy section starts with key 7.
--    let currentBuddy;
--    for (let i = 0; i < aPacket.keyValuePairs.length; ++i) {
--      let {key: key, value: value} = aPacket.keyValuePairs[i];
--
--      if (key == 7) { // Buddy name.
--        currentBuddyName = value;
--        this._session.requestBuddyIcon(currentBuddyName);
--      } else if (key == 10) // Buddy status.
--        this.setBuddyStatus(currentBuddyName, kBuddyStatuses[value]);
--      else if (key == 19) // Buddy status message.
--        this.setBuddyStatus(currentBuddyName, undefined, value);
--      else if (key == 60) // Mobile status.
--        this.setBuddyStatus(currentBuddyName, Ci.imIStatus.STATUS_MOBILE);
--    }
--  },
--
--  // Friends and groups list.
--  0xf1: function(aPacket) {
--    let tagName = "";
--    for each (let pair in aPacket.keyValuePairs) {
--      if (pair.key == "65")
--        tagName = pair.value;
--      else if (pair.key == "7") {
--        let buddyName = pair.value;
--        this.addBuddyFromServer(Services.tags.createTag(tagName), buddyName);
--      }
--    }
--  }
--};
--
--/* The YahooProfileIconUploader class is specifically designed to set a profile
-- * image on a Yahoo! Messenger account. The reason this functionality is split
-- * into a separate class is because of the complexity of the operation. Because
-- * of special protocol requirements, it is easier to use raw TCP communication
-- * instead of the httpRequest() method. */
--function YahooProfileIconUploader(aAccount, aSession, aFileName, aImage)
--{
--  this._account = aAccount;
--  this._session = aSession;
--  this._fileName = aFileName;
--  this._image = aImage;
--}
--YahooProfileIconUploader.prototype = {
--  __proto__: Socket,
--  _account: null,
--  _session: null,
--  _fileName: null,
--  _image: null,
--  _host: null,
--  _port: null,
--
--  uploadIcon: function() {
--    // Connect to the file transfer server, and the onConnection callback
--    // will do the rest.
--    this.connect(kFileTransferHost, kFileTransferPort);
--  },
--
--  // Socket callbacks.
--  onConnection: function() {
--    // Scale the image down, and make it a PNG. Icon widths are constant, but
--    // their height varies depending on the aspect ratio of the original image.
--    let aspectRatio = this._image.width / this._image.height;
--    let scaledHeight = kProfileIconWidth / aspectRatio;
--    let scaledImage = imgTools.encodeScaledImage(this._image, "image/png",
--                                                 kProfileIconWidth,
--                                                 scaledHeight);
--    let imageData = NetUtil.readInputStreamToString(scaledImage,
--                                                    scaledImage.available());
--
--    // Build the Yahoo packet.
--    let packet = new YahooPacket(kPacketType.Picture, 0, this.sessionId);
--    packet.addValue(1, this._account.cleanUsername);
--    // TODO - Look into how expiration time works for profile icons, and its
--    // purpose. We aren't sure if this refers to seconds, days, years, etc.
--    packet.addValue(38, "604800"); // Expiration time.
--    packet.addValue(0, this._account.cleanUsername);
--    packet.addValue(28, imageData.length); // Picture size in bytes.
--    packet.addValue(27, this._fileName); // Picture filename.
--    packet.addValue(14, ""); // Null string.
--    let packetBuffer = packet.toArrayBuffer();
--
--    // Build the request header.
--    let headers = [
--      ["User-Agent", "Mozilla/5.0"],
--      ["Cookie", "T=" + this._session.tCookie + "; Y=" + this._session.yCookie],
--      ["Host", kFileTransferHost + ":" + kFileTransferPort],
--      ["Content-Length", packetBuffer.byteLength + 4 + imageData.length],
--      ["Cache-Control", "no-cache"],
--    ];
--    let headerString = "POST /notifyft HTTP/1.1\r\n";
--    headers.forEach(function(header) {
--      headerString += header[0] + ": " + header[1] + "\r\n";
--    });
--
--    // The POST request uses a special delimeter between the end of the included
--    // Yahoo binary packet, and the image data.
--    let requestPacketEnd = "29" + kPacketDataDelimiter;
--    // Build the complete POST request data.
--    let requestData = headerString + "\r\n" +
--                      ArrayBufferToString(packetBuffer) + requestPacketEnd +
--                      imageData;
--    this.sendData(requestData);
--  }
--};
-diff --git a/chat/protocols/yahoo/yahoo.js b/chat/protocols/yahoo/yahoo.js
-index 8beadb504..86a258969 100644
---- a/chat/protocols/yahoo/yahoo.js
-+++ b/chat/protocols/yahoo/yahoo.js
-@@ -2,575 +2,39 @@
-  * License, v. 2.0. If a copy of the MPL was not distributed with this
-  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- 
--var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
-+var {interfaces: Ci, utils: Cu} = Components;
- 
--Cu.import("resource:///modules/imServices.jsm");
- Cu.import("resource:///modules/imXPCOMUtils.jsm");
- Cu.import("resource:///modules/jsProtoHelper.jsm");
--Cu.import("resource:///modules/yahoo-session.jsm");
- 
- XPCOMUtils.defineLazyGetter(this, "_", () =>
-   l10nHelper("chrome://chat/locale/yahoo.properties")
- );
- 
--// These timeouts are in milliseconds.
--var kKeepAliveTimeout = 60 * 1000; // One minute.
--var kPingTimeout = 3600 * 1000; // One hour.
--
--function YahooConversation(aAccount, aName)
--{
--  this._buddyUserName = aName;
--  this._account = aAccount;
--  this.buddy = aAccount.getBuddy(aName);
--  this._init(aAccount);
--}
--YahooConversation.prototype = {
--  __proto__: GenericConvIMPrototype,
--  _account: null,
--  _buddyUserName: null,
--  _typingTimer: null,
--
--  close: function() {
--    this._account.deleteConversation(this._buddyUserName);
--    GenericConvChatPrototype.close.call(this);
--  },
--
--  sendMsg: function (aMsg) {
--    // Deliver the message, then write it to the window.
--    this._account._session.sendChatMessage(this._buddyUserName,
--                                           this._account.encodeMessage(aMsg));
--    this.finishedComposing();
--    this.writeMessage(this._account.cleanUsername, aMsg,
--                      {outgoing: true, _alias: this._account.imAccount.alias});
--  },
--
--  sendTyping: function(aString) {
--    if (aString.length) {
--      if (!this._typingTimer)
--        this._account._session.sendTypingStatus(this._buddyUserName, true);
--      this._refreshTypingTimer();
--    }
--    return Ci.prplIConversation.NO_TYPING_LIMIT;
--  },
--
--  finishedComposing: function() {
--    this._account._session.sendTypingStatus(this._buddyUserName, false);
--    this._cancelTypingTimer();
--  },
--
--  _refreshTypingTimer: function() {
--    this._cancelTypingTimer();
--    this._typingTimer = setTimeout(this.finishedComposing.bind(this), 10000);
--  },
--
--  _cancelTypingTimer: function() {
--    if (!this._typingTimer)
--      return;
--    clearTimeout(this._typingTimer);
--    delete this._typingTimer
--    this._typingTimer = null;
--  },
--
--  get name() { return this._buddyUserName; }
--};
--
--function YahooConference(aAccount, aRoom, aOwner)
--{
--  this._account = aAccount;
--  this._roomName = aRoom;
--  this._owner = aOwner;
--  this._init(aAccount, aRoom, aAccount.cleanUsername);
--}
--YahooConference.prototype = {
--  __proto__: GenericConvChatPrototype,
--  _account: null,
--  _roomName: null,
--  _owner: null,
--
--  close: function() {
--    this.reportLogoff();
--    this._account.deleteConference(this._roomName);
--    GenericConvChatPrototype.close.call(this);
--  },
--
--  reportLogoff: function() {
--    if (this.left)
--      return;
--    this._account._session.sendConferenceLogoff(this._account.cleanUsername,
--                                                this.getParticipantNames(),
--                                                this._roomName);
--    this.left = true;
--  },
--
--  sendMsg: function(aMsg) {
--    this._account._session.sendConferenceMessage(this.getParticipantNames(),
--                                                 this._roomName,
--                                                 this._account.encodeMessage(aMsg));
--  },
--
--  addParticipant: function(aName) {
--    // In case we receive multiple conference logon packets, prevent adding
--    // duplicate buddies.
--    if (this._participants.get(aName))
--      return;
--    let buddy = new YahooConferenceBuddy(aName, this);
--    this._participants.set(aName, buddy);
--    this.notifyObservers(new nsSimpleEnumerator([buddy]), "chat-buddy-add");
--    this.writeMessage(this._roomName,
--                      _("system.message.conferenceLogon", aName),
--                      {system: true});
--  },
--
--  getParticipantNames: function() { return [for (p of this._participants.values()) p.name]; }
--};
--
--function YahooConferenceBuddy(aName, aConference)
--{
--  this._name = aName;
--  this._conference = aConference;
--}
--YahooConferenceBuddy.prototype = {
--  __proto__: GenericConvChatBuddyPrototype,
--  _conference: null,
--
--  get founder() { return this._conference._owner == this._name; }
--};
--
--function YahooAccountBuddy(aAccount, aBuddy, aTag, aUserName)
--{
--  this._init(aAccount, aBuddy, aTag, aUserName);
--}
--YahooAccountBuddy.prototype = {
--  __proto__: GenericAccountBuddyPrototype,
--  iconChecksum: null,
--
--  // This removes the buddy locally, and from the Yahoo! servers.
--  remove: function() { return this._account.removeBuddy(this, true); },
--  // This removes the buddy locally, but keeps him on the servers.
--  removeLocal: function() { return this._account.removeBuddy(this, false); },
--  createConversation: function() { return this._account.createConversation(this.userName); }
--}
--
- function YahooAccount(aProtoInstance, aImAccount)
- {
-   this._init(aProtoInstance, aImAccount);
--  this._buddies = new Map();
--  this._conversations = new Map();
--  this._conferences = new Map();
--  this._protocol = aProtoInstance;
--  this._converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
--      .createInstance(Ci.nsIScriptableUnicodeConverter);
--  this._converter.charset = this.getString("local_charset") || "UTF-8";
--
--  // The username stripped of any @yahoo.* domain.
--  this.cleanUsername = this.name.replace(/@yahoo\..+$/, "");
- }
- YahooAccount.prototype = {
-   __proto__: GenericAccountPrototype,
--  // YahooSession object passed in constructor.
--  _session: null,
--  // A Map holding the list of buddies associated with their usernames.
--  _buddies: null,
--  // A Map holding the list of open buddy conversations associated with the
--  // username of the buddy.
--  _conversations: null,
--  // A Map holding the list of open conference rooms associated with the room
--  // name.
--  _conferences: null,
--  // YahooProtocol object passed in the constructor.
--  _protocol: null,
--  // An nsIScriptableUnicodeConverter used to convert incoming/outgoing chat
--  // messages to the correct charset.
--  _converter: null,
--  // This is simply incremented by one everytime a new conference room is
--  // created. It is appened to the end of the room name when a new room is
--  // created, ensuring name uniqueness.
--  _roomsCreated: 0,
--  // The username stripped of any @yahoo.* domain.
--  cleanUsername: null,
--  // The timers used to send keepalive and ping packets to the server to ensrue
--  // the server that the user is still connected.
--  _keepAliveTimer: null,
--  _pingTimer: null,
- 
-   connect: function() {
--    this._session = new YahooSession(this);
--    this._session.login(this.imAccount.name, this.imAccount.password);
--  },
--
--  disconnect: function(aSilent) {
--    // Log out of all of the conferences the user is in.
--    for (let conf of this._conferences)
--      conf[1].reportLogoff();
--
--    if (this.connected) {
--      this.reportDisconnecting(Ci.prplIAccount.NO_ERROR, "");
--      if (this._session.isConnected)
--        this._session.disconnect();
--      this.reportDisconnected();
--    }
--    // buddy[1] is the actual object.
--    for (let buddy of this._buddies)
--      buddy[1].setStatus(Ci.imIStatusInfo.STATUS_UNKNOWN, "");
--
--    // Clear and delete the timers to avoid memory leaks.
--    if (this._keepAliveTimer) {
--      this._keepAliveTimer.cancel();
--      delete this._keepAliveTimer;
--    }
--
--    if (this._pingTimer) {
--      this._pingTimer.cancel();
--      delete this._pingTimer;
--    }
--  },
--
--  observe: function(aSubject, aTopic, aData) {
--    if (aTopic == "status-changed")
--      this._session.setStatus(aSubject.statusType, aData);
--    else if (aTopic == "user-icon-changed")
--      this._session.setProfileIcon(aData);
--  },
--
--  remove: function() {
--    for each(let conv in this._conversations)
--      conv.close();
--    delete this._conversations;
--    for (let buddy of this._buddies)
--      buddy[1].removeLocal(); // buddy[1] is the actual object.
--  },
--
--  unInit: function() {
--    this.disconnect(true);
--    delete this.imAccount;
--  },
--
--  createConversation: function(aName) {
--    let conv = new YahooConversation(this, aName);
--    this._conversations.set(aName, conv);
--    return conv;
--  },
--
--  deleteConversation: function(aName) {
--    if (this._conversations.has(aName))
--      this._conversations.delete(aName);
--  },
--
--  receiveConferenceInvite: function(aOwner, aRoom, aParticipants, aMessage) {
--    // Do nothing if we wish to ignore invites.
--    if (!Services.prefs.getIntPref("messenger.conversations.autoAcceptChatInvitations") ||
--        this.getBool("ignore_invites"))
--      return;
--
--    let conf = new YahooConference(this, aRoom, aOwner);
--    this._conferences.set(aRoom, conf);
--
--    for each (let participant in aParticipants)
--      conf.addParticipant(participant);
--
--    // Add ourselves to the conference room as well.
--    conf.addParticipant(this.imAccount.name);
--
--    this._session.acceptConferenceInvite(aOwner, aRoom,
--                                         conf.getParticipantNames());
--  },
--
--  receiveConferenceLogon: function(aRoom, aUsername) {
--    if (!this._conferences.has(aRoom))
--      return;
--    let conf = this._conferences.get(aRoom);
--    conf.addParticipant(aUsername);
--  },
--
--  receiveConferenceLogoff: function(aRoom, aUsername) {
--    if (!this._conferences.has(aRoom))
--      return;
--    let conf = this._conferences.get(aRoom);
--    conf.removeParticipant(aUsername);
--    conf.writeMessage(this._roomName,
--                      _("system.message.conferenceLogoff", aName),
--                      {system: true});
--  },
--
--  deleteConference: function(aName) {
--    if (this._conferences.has(aName))
--      this._conferences.delete(aName);
--  },
--
--  // Called when the user adds or authorizes a new contact.
--  addBuddy: function(aTag, aName) {
--    let buddy = new YahooAccountBuddy(this, null, aTag, aName);
--    this._buddies.set(buddy.userName, buddy);
--    this._session.addBuddyToServer(buddy);
--    Services.contacts.accountBuddyAdded(buddy);
--  },
--
--  hasBuddy: function(aName) {
--    return this._buddies.has(aName);
--  },
--
--  // Called for each buddy that is sent in a list packet from Yahoo! on login.
--  addBuddyFromServer: function(aTag, aName) {
--    let buddy;
--    if (this._buddies.has(aName))
--      buddy = this._buddies.get(aName);
--    else {
--      buddy = new YahooAccountBuddy(this, null, aTag, aName);
--      Services.contacts.accountBuddyAdded(buddy);
--      this._buddies.set(aName, buddy);
--    }
--
--    // Set all new buddies as offline because a following status packet will
--    // tell their status if they are online.
--    buddy.setStatus(Ci.imIStatusInfo.STATUS_OFFLINE, "");
--
--    // Request the buddy's picture.
--    this._session.requestBuddyIcon(aName);
--  },
--
--  // Called when a user removes a contact from within Instantbird.
--  removeBuddy: function(aBuddy, aRemoveFromServer) {
--    if (aRemoveFromServer) {
--      // We will remove the buddy locally when we get a server ack packet.
--      this._session.removeBuddyFromServer(aBuddy);
--      return;
--    }
--
--    this._buddies.delete(aBuddy.userName);
--    Services.contacts.accountBuddyRemoved(aBuddy);
--  },
--
--  loadBuddy: function(aBuddy, aTag) {
--    let buddy = new YahooAccountBuddy(this, aBuddy, aTag);
--    this._buddies.set(buddy.userName, buddy);
--
--    return buddy;
--  },
--
--  // Both the status and message can be defined, or only one can be defined.
--  // When defining just the message, set aStatus to undefined.
--  setBuddyStatus: function(aName, aStatus, aMessage) {
--    if (!this._buddies.has(aName))
--      return;
--    let buddy = this._buddies.get(aName);
--    // If the message is set as undefined, use the existing message.
--    if (aMessage === undefined)
--      aMessage = buddy.statusText;
--    // If the status is undefined, use the existing status.
--    if (aStatus === undefined)
--      aStatus = buddy.statusType;
--    buddy.setStatus(aStatus, aMessage);
--  },
--
--  getBuddy: function(aName) {
--    if (this._buddies.has(aName))
--      return this._buddies.get(aName);
--    return null;
--  },
--
--  getOnlineBuddies: function() {
--    let onlineBuddies = [];
--    for (let buddy of this._buddies) {
--      if (buddy[1].statusType != Ci.imIStatusInfo.STATUS_OFFLINE)
--        onlineBuddies.push(buddy[1]);
--    }
--    return onlineBuddies;
--  },
--
--  receiveMessage: function(aName, aMessage) {
--    let conv;
--    // Check if we have an existing converstaion open with this user. If not,
--    // create one and add it to the list.
--    if (!this._conversations.has(aName))
--      conv = this.createConversation(aName);
--    else
--      conv = this._conversations.get(aName);
--
--    // Certain Yahoo clients, such as the official web client, sends formatted
--    // messages, but the size value is the actual pt size, not the 1 - 7 size
--    // expected from the HTML <font> tag. We replace it with the correct size.
--    let message = this.decodeMessage(aMessage)
--                      .replace(/(<font[^>]+)size=\"(\d+)\"/g, this._fixFontSize);
--
--    conv.writeMessage(aName, message, {incoming: true});
--    conv.updateTyping(Ci.prplIConvIM.NOT_TYPING, conv.name);
--  },
--
--  receiveConferenceMessage: function(aName, aRoom, aMessage) {
--    if (!this._conferences.has(aRoom))
--      return;
--
--    this._conferences.get(aRoom).writeMessage(aName,
--                                              this.decodeMessage(aMessage),
--                                              {incoming: true});
--  },
--
--  receiveTypingNotification: function(aName, aIsTyping) {
--    if (!this._conversations.has(aName))
--      return;
--
--    let conv = this._conversations.get(aName);
--    if (aIsTyping)
--      conv.updateTyping(Ci.prplIConvIM.TYPING, conv.name);
--    else
--      conv.updateTyping(Ci.prplIConvIM.NOT_TYPING, conv.name);
--  },
--
--  encodeMessage: function(aMessage) {
--    // Try to perform a convertion from JavaScript UTF-16 into the charset
--    // specified in the options. If the conversion fails, just leave
--    // the message as it is.
--    let encodedMsg;
--    try {
--      encodedMsg = this._converter.ConvertFromUnicode(aMessage);
--    } catch (e) {
--      encodedMsg = aMessage;
--      this.WARN("Could not encode UTF-16 message into " +
--                this._converter.charset + ". Message: " + aMessage);
--    }
--    return encodedMsg;
--  },
--
--  decodeMessage: function(aMessage) {
--    // Try to perform a convertion from the charset specified in the options
--    // to JavaScript UTF-16. If the conversion fails, just leave the message
--    // as it is.
--    let decodedMsg;
--    try {
--      decodedMsg = this._converter.ConvertToUnicode(aMessage);
--    } catch (e) {
--      decodedMsg = aMessage;
--      this.WARN("Could not decode " + this._converter.charset +
--                " message into UTF-16. Message: " + aMessage);
--    }
--    return decodedMsg;
--  },
--
--  get canJoinChat() { return true; },
--  chatRoomFields: {},
--  joinChat: function(aComponents) {
--    // Use _roomsCreated to append a unique number to the room name.
--    let roomName = this.cleanUsername + "-" + ++this._roomsCreated;
--    let conf = new YahooConference(this, roomName, this.cleanUsername);
--    this._conferences.set(roomName, conf);
--    this._session.createConference(roomName);
--  },
--
--  // Callbacks.
--  onLoginComplete: function() {
--    // Now that we are connected, get ready to start to sending pings and
--    // keepalive packets.
--    this._keepAliveTimer = Cc["@mozilla.org/timer;1"]
--                             .createInstance(Ci.nsITimer);
--    this._pingTimer = Cc["@mozilla.org/timer;1"]
--                        .createInstance(Ci.nsITimer);
--
--    // We use slack timers since we don't need millisecond precision when
--    // sending the keepalive and ping packets.
--    let s = this._session;
--    this._keepAliveTimer
--        .initWithCallback(s.sendKeepAlive.bind(s), kKeepAliveTimeout,
--                          this._keepAliveTimer.TYPE_REPEATING_SLACK);
--
--    this._pingTimer
--        .initWithCallback(s.sendPing.bind(s), kPingTimeout,
--                          this._pingTimer.TYPE_REPEATING_SLACK);
--
--  },
--
--  // Private methods.
--
--  // This method is used to fix font sizes given by formatted messages. This
--  // method is designed to be used as a method for a string replace() call.
--  _fixFontSize: function(aMatch, aTagAttributes, aFontSize, aOffset, aString) {
--    // Approximate the font size.
--    let newSize;
--    if (aFontSize <= 8)
--      newSize = "1";
--    else if (aFontSize <= 10)
--      newSize = "2";
--    else if (aFontSize <= 12)
--      newSize = "3";
--    else if (aFontSize <= 14)
--      newSize = "4";
--    else if (aFontSize <= 20)
--      newSize = "5";
--    else if (aFontSize <= 30)
--      newSize = "6";
--    else if (aFontSize <= 40)
--      newSize = "7";
--    else // If we get some gigantic size, just default to the standard 3 size.
--      newSize = "3";
--
--    let sizeAttribute = "size=\"" + newSize + "\"";
--    // We keep any preceding attributes, but replace the size attribute.
--    return aTagAttributes + sizeAttribute;
-+    this.WARN("The legacy versions of Yahoo Messenger was disabled on August " +
-+              "5, 2016. It is currently not possible to connect to Yahoo " +
-+              "Messenger. See bug 1316000");
-+    this.reportDisconnecting(Ci.prplIAccount.ERROR_OTHER_ERROR,
-+                             _("yahoo.disabled"));
-+    this.reportDisconnected();
-   }
- };
- 
--function YahooProtocol() {
--  this.registerCommands();
--}
-+function YahooProtocol() {}
- YahooProtocol.prototype = {
-   __proto__: GenericProtocolPrototype,
--  // Protocol specific connection parameters.
--  pagerRequestUrl: "http://scsa.msg.yahoo.com/capacity",
--  loginTokenGetUrl: "https://login.yahoo.com/config/pwtoken_get",
--  loginTokenLoginUrl: "https://login.yahoo.com/config/pwtoken_login",
--  buildId: "4194239",
- 
-   get id() { return "prpl-yahoo"; },
-   get name() { return "Yahoo"; },
-   get iconBaseURI() { return "chrome://prpl-yahoo/skin/"; },
--  options: {
--    port: {get label() { return _("options.pagerPort"); }, default: 5050},
--    local_charset: {get label() { return _("options.chatEncoding"); }, default: "UTF-8"},
--    ignore_invites: {get label() { return _("options.ignoreInvites"); }, default: false}
--  },
--  commands: [
--    {
--      name: "invite",
--      get helpString() { return _("command.help.invite2", "invite"); },
--      usageContext: Ci.imICommand.CMD_CONTEXT_ALL,
--      run: function(aMsg, aConv) {
--        if (aMsg.trim().length == 0)
--          return false;
--
--        let splitPosition = aMsg.indexOf(" "); // Split at first space.
--        let invitees;
--        let message;
--
--        // If we have an invite message.
--        if (splitPosition > 0) {
--          invitees = aMsg.substring(0, splitPosition).split(",");
--          message = aMsg.substring(splitPosition);
--        } else {
--          invitees = aMsg.split(",");
--          message = _("conference.invite.message"); // Use default message.
--        }
--
--        let conf = aConv.wrappedJSObject;
--        conf._account._session.inviteToConference(invitees, conf._roomName,
--                                                  conf.getParticipantNames(),
--                                                  message);
--        conf.writeMessage(conf._roomName,
--                          _("command.feedback.invite", invitees.join(", ")),
--                          {system: true, noLog: true});
--        conf._account.LOG("Sending conference invite to " + invitees);
--        return true;
--      },
--    },
--
--    {
--      name: "conference",
--      get helpString() { return _("command.help.conference", "conference"); },
--      usageContext: Ci.imICommand.CMD_CONTEXT_CHAT,
--      run: function(aMsg, aConv) {
--        aConv.account.joinChat(null);
--        return true;
--      }
--    }
--  ],
-   getAccount: function(aImAccount) { return new YahooAccount(this, aImAccount); },
-   classID: Components.ID("{50ea817e-5d79-4657-91ae-aa0a52bdb98c}")
- };
-diff --git a/im/content/conversation.xml b/im/content/conversation.xml
-index 6f00c8d39..c93dab00f 100644
---- a/im/content/conversation.xml
-+++ b/im/content/conversation.xml
-@@ -342,8 +342,7 @@
-                   msg = "<font face=\"" + style.fontFamily + "\">" + msg + "</font>";
-                 // MSN doesn't support font size info in messages...
-               }
--              else if (proto == "prpl-aim" || proto == "prpl-icq" ||
--                       proto == "prpl-yahoo" || proto == "prpl-yahoojp") {
-+              else if (proto == "prpl-aim" || proto == "prpl-icq") {
-                 let styleAttributes = ""
-                 if ("color" in style)
-                   styleAttributes += " color=\"" + style.color + "\"";
-diff --git a/im/locales/en-US/chrome/instantbird/accountWizard.properties b/im/locales/en-US/chrome/instantbird/accountWizard.properties
-index 7d371bd21..1d6fd48e1 100644
---- a/im/locales/en-US/chrome/instantbird/accountWizard.properties
-+++ b/im/locales/en-US/chrome/instantbird/accountWizard.properties
-@@ -14,9 +14,8 @@ topProtocol.list=prpl-irc,prpl-jabber,prpl-twitter,prpl-gtalk
- # These are the descriptions of the top protocols specified above.
- # A description should be provided for each protocol ID listed above.
- topProtocol.prpl-irc.description=Connect to your favourite IRC network
--topProtocol.prpl-jabber.description=Chat with friends using XMPP
- topProtocol.prpl-gtalk.description=Talk to your Gmail contacts
- topProtocol.prpl-twitter.description=Stay up to date with your Twitter timeline
- topProtocol.prpl-aim.description=Chat with your buddies on AOL Instant Messenger
--topProtocol.prpl-yahoo.description=Chat with friends using Yahoo! Messenger
- topProtocol.prpl-irc.description=Join IRC channels
-+topProtocol.prpl-jabber.description=Chat using the open Jabber/XMPP protocol
-diff --git a/im/test/xpcshell.ini b/im/test/xpcshell.ini
-index 5f7dd70fc..578122a2a 100644
---- a/im/test/xpcshell.ini
-+++ b/im/test/xpcshell.ini
-@@ -6,5 +6,4 @@
- [include:chat/components/src/test/xpcshell.ini]
- [include:chat/protocols/irc/test/xpcshell.ini]
- [include:chat/protocols/skype/test/xpcshell.ini]
--[include:chat/protocols/yahoo/test/xpcshell.ini]
- #[include:extensions/purple/purplexpcom/src/test/xpcshell.ini]
-diff --git a/mail/components/im/content/imconversation.xml b/mail/components/im/content/imconversation.xml
-index 16c665ab4..a4b9fc638 100644
---- a/mail/components/im/content/imconversation.xml
-+++ b/mail/components/im/content/imconversation.xml
-@@ -285,8 +285,7 @@
-                 msg = "<font face=\"" + style.fontFamily + "\">" + msg + "</font>";
-               // MSN doesn't support font size info in messages...
-             }
--            else if (proto == "prpl-aim" || proto == "prpl-icq" ||
--                     proto == "prpl-yahoo" || proto == "prpl-yahoojp") {
-+            else if (proto == "prpl-aim" || proto == "prpl-icq") {
-               let styleAttributes = ""
-               if ("color" in style)
-                 styleAttributes += " color=\"" + style.color + "\"";
--- 
-2.11.0
-
diff --git a/projects/instantbird/0025-Bug-1321641-Use-built-in-functions-instead-of-an-svg.patch b/projects/instantbird/0025-Bug-1321641-Use-built-in-functions-instead-of-an-svg.patch
new file mode 100644
index 0000000..0a7172b
--- /dev/null
+++ b/projects/instantbird/0025-Bug-1321641-Use-built-in-functions-instead-of-an-svg.patch
@@ -0,0 +1,57 @@
+From 4b7b7f09dab1b90af3073304d8bcfa529ac1183b Mon Sep 17 00:00:00 2001
+From: Arlo Breault <arlolra at gmail.com>
+Date: Thu, 1 Dec 2016 13:25:42 -0800
+Subject: [PATCH 25/26] Bug 1321641 - Use built-in functions instead of an svg
+ for bubbles filter
+
+---
+ im/themes/jar.mn                       |  1 -
+ im/themes/messages/bubbles/bubbles.svg | 10 ----------
+ im/themes/messages/bubbles/main.css    |  2 +-
+ 3 files changed, 1 insertion(+), 12 deletions(-)
+ delete mode 100644 im/themes/messages/bubbles/bubbles.svg
+
+diff --git a/im/themes/jar.mn b/im/themes/jar.mn
+index e422619d4..e39f5dcd8 100644
+--- a/im/themes/jar.mn
++++ b/im/themes/jar.mn
+@@ -268,7 +268,6 @@ instantbird.jar:
+ 	skin/classic/instantbird/messages/bubbles/Bitmaps/minus.png             (messages/bubbles/Bitmaps/minus.png)
+ 	skin/classic/instantbird/messages/bubbles/Bitmaps/plus-hover.png        (messages/bubbles/Bitmaps/plus-hover.png)
+ 	skin/classic/instantbird/messages/bubbles/Bitmaps/plus.png              (messages/bubbles/Bitmaps/plus.png)
+-	skin/classic/instantbird/messages/bubbles/bubbles.svg                   (messages/bubbles/bubbles.svg)
+ 	skin/classic/instantbird/messages/bubbles/Footer.html                   (messages/bubbles/Footer.html)
+ 	skin/classic/instantbird/messages/bubbles/Incoming/Content.html         (messages/bubbles/Incoming/Content.html)
+ 	skin/classic/instantbird/messages/bubbles/Incoming/Context.html         (messages/bubbles/Incoming/Context.html)
+diff --git a/im/themes/messages/bubbles/bubbles.svg b/im/themes/messages/bubbles/bubbles.svg
+deleted file mode 100644
+index 963521eca..000000000
+--- a/im/themes/messages/bubbles/bubbles.svg
++++ /dev/null
+@@ -1,10 +0,0 @@
+-<?xml version="1.0"?>
+-<!-- This Source Code Form is subject to the terms of the Mozilla Public
+-   - License, v. 2.0. If a copy of the MPL was not distributed with this
+-   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+-
+-<svg xmlns="http://www.w3.org/2000/svg">
+-  <filter id="desaturate">
+-    <feColorMatrix type="saturate" values="0.4"/>
+-  </filter>
+-</svg>
+diff --git a/im/themes/messages/bubbles/main.css b/im/themes/messages/bubbles/main.css
+index 15ba97346..4488c30bb 100644
+--- a/im/themes/messages/bubbles/main.css
++++ b/im/themes/messages/bubbles/main.css
+@@ -40,7 +40,7 @@ p {
+ }
+ 
+ .bubble.context:not(:hover) {
+-  filter: url("bubbles.svg#desaturate");
++  filter: saturate(40%);
+ }
+ 
+ .indicator {
+-- 
+2.11.0
+
diff --git a/projects/instantbird/0026-Bug-1321420-Add-a-pref-to-disable-JavaScript-in-brow.patch b/projects/instantbird/0026-Bug-1321420-Add-a-pref-to-disable-JavaScript-in-brow.patch
new file mode 100644
index 0000000..2f6a82e
--- /dev/null
+++ b/projects/instantbird/0026-Bug-1321420-Add-a-pref-to-disable-JavaScript-in-brow.patch
@@ -0,0 +1,52 @@
+From f076a0ffdaa9b69dad2c04b706f5a8daf8e8314d Mon Sep 17 00:00:00 2001
+From: Arlo Breault <arlolra at gmail.com>
+Date: Thu, 1 Dec 2016 14:34:51 -0800
+Subject: [PATCH 26/26] Bug 1321420 - Add a pref to disable JavaScript in
+ browser requests
+
+---
+ chat/chat-prefs.js             | 2 ++
+ chat/content/browserRequest.js | 7 +++++++
+ 2 files changed, 9 insertions(+)
+
+diff --git a/chat/chat-prefs.js b/chat/chat-prefs.js
+index 60b9c1e8c..90a212e5c 100644
+--- a/chat/chat-prefs.js
++++ b/chat/chat-prefs.js
+@@ -86,6 +86,8 @@ pref("chat.prpls.prpl-skype.disable", true);
+ pref("chat.prpls.prpl-facebook.disable", true);
+ // Disable Yahoo Messenger as legacy Yahoo was shut down.
+ pref("chat.prpls.prpl-yahoo.disable", true);
++// Disable JavaScript in browser requests.
++pref("chat.browserRequest.disableJavascript", false);
+ 
+ // loglevel is the minimum severity level that a libpurple message
+ // must have to be reported in the Error Console.
+diff --git a/chat/content/browserRequest.js b/chat/content/browserRequest.js
+index c52c8c637..0069219fa 100644
+--- a/chat/content/browserRequest.js
++++ b/chat/content/browserRequest.js
+@@ -2,6 +2,8 @@
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
++Components.utils.import("resource:///modules/imServices.jsm");
++
+ var wpl = Components.interfaces.nsIWebProgressListener;
+ 
+ var reporterListener = {
+@@ -133,6 +135,11 @@ function loadRequestedUrl()
+     account.protocol.iconBaseURI + "icon48.png";
+ 
+   let browser = document.getElementById("requestFrame");
++  browser.docShell.allowPlugins = false;
++
++  if (Services.prefs.getBoolPref("chat.browserRequest.disableJavascript"))
++    browser.docShell.allowJavascript = false;
++
+   browser.addProgressListener(reporterListener,
+                               Components.interfaces.nsIWebProgress.NOTIFY_ALL);
+   let url = request.url;
+-- 
+2.11.0
+
diff --git a/projects/instantbird/0026-Bug-1321641-Use-built-in-functions-instead-of-an-svg.patch b/projects/instantbird/0026-Bug-1321641-Use-built-in-functions-instead-of-an-svg.patch
deleted file mode 100644
index 1beef80..0000000
--- a/projects/instantbird/0026-Bug-1321641-Use-built-in-functions-instead-of-an-svg.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From b8b4eee34d1e88ffc0100c2c3f8e91a8afba1f01 Mon Sep 17 00:00:00 2001
-From: Arlo Breault <arlolra at gmail.com>
-Date: Thu, 1 Dec 2016 13:25:42 -0800
-Subject: [PATCH 26/27] Bug 1321641 - Use built-in functions instead of an svg
- for bubbles filter
-
----
- im/themes/jar.mn                       |  1 -
- im/themes/messages/bubbles/bubbles.svg | 10 ----------
- im/themes/messages/bubbles/main.css    |  2 +-
- 3 files changed, 1 insertion(+), 12 deletions(-)
- delete mode 100644 im/themes/messages/bubbles/bubbles.svg
-
-diff --git a/im/themes/jar.mn b/im/themes/jar.mn
-index e422619d4..e39f5dcd8 100644
---- a/im/themes/jar.mn
-+++ b/im/themes/jar.mn
-@@ -268,7 +268,6 @@ instantbird.jar:
- 	skin/classic/instantbird/messages/bubbles/Bitmaps/minus.png             (messages/bubbles/Bitmaps/minus.png)
- 	skin/classic/instantbird/messages/bubbles/Bitmaps/plus-hover.png        (messages/bubbles/Bitmaps/plus-hover.png)
- 	skin/classic/instantbird/messages/bubbles/Bitmaps/plus.png              (messages/bubbles/Bitmaps/plus.png)
--	skin/classic/instantbird/messages/bubbles/bubbles.svg                   (messages/bubbles/bubbles.svg)
- 	skin/classic/instantbird/messages/bubbles/Footer.html                   (messages/bubbles/Footer.html)
- 	skin/classic/instantbird/messages/bubbles/Incoming/Content.html         (messages/bubbles/Incoming/Content.html)
- 	skin/classic/instantbird/messages/bubbles/Incoming/Context.html         (messages/bubbles/Incoming/Context.html)
-diff --git a/im/themes/messages/bubbles/bubbles.svg b/im/themes/messages/bubbles/bubbles.svg
-deleted file mode 100644
-index 963521eca..000000000
---- a/im/themes/messages/bubbles/bubbles.svg
-+++ /dev/null
-@@ -1,10 +0,0 @@
--<?xml version="1.0"?>
--<!-- This Source Code Form is subject to the terms of the Mozilla Public
--   - License, v. 2.0. If a copy of the MPL was not distributed with this
--   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
--
--<svg xmlns="http://www.w3.org/2000/svg">
--  <filter id="desaturate">
--    <feColorMatrix type="saturate" values="0.4"/>
--  </filter>
--</svg>
-diff --git a/im/themes/messages/bubbles/main.css b/im/themes/messages/bubbles/main.css
-index 15ba97346..4488c30bb 100644
---- a/im/themes/messages/bubbles/main.css
-+++ b/im/themes/messages/bubbles/main.css
-@@ -40,7 +40,7 @@ p {
- }
- 
- .bubble.context:not(:hover) {
--  filter: url("bubbles.svg#desaturate");
-+  filter: saturate(40%);
- }
- 
- .indicator {
--- 
-2.11.0
-
diff --git a/projects/instantbird/0027-Bug-1321420-Add-a-pref-to-disable-JavaScript-in-brow.patch b/projects/instantbird/0027-Bug-1321420-Add-a-pref-to-disable-JavaScript-in-brow.patch
deleted file mode 100644
index 23fa129..0000000
--- a/projects/instantbird/0027-Bug-1321420-Add-a-pref-to-disable-JavaScript-in-brow.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 0e9e3c12e782b4c4f010115b9115775b7e829f3f Mon Sep 17 00:00:00 2001
-From: Arlo Breault <arlolra at gmail.com>
-Date: Thu, 1 Dec 2016 14:34:51 -0800
-Subject: [PATCH 27/27] Bug 1321420 - Add a pref to disable JavaScript in
- browser requests
-
----
- chat/chat-prefs.js             | 2 ++
- chat/content/browserRequest.js | 7 +++++++
- 2 files changed, 9 insertions(+)
-
-diff --git a/chat/chat-prefs.js b/chat/chat-prefs.js
-index 60b9c1e8c..90a212e5c 100644
---- a/chat/chat-prefs.js
-+++ b/chat/chat-prefs.js
-@@ -86,6 +86,8 @@ pref("chat.prpls.prpl-skype.disable", true);
- pref("chat.prpls.prpl-facebook.disable", true);
- // Disable Yahoo Messenger as legacy Yahoo was shut down.
- pref("chat.prpls.prpl-yahoo.disable", true);
-+// Disable JavaScript in browser requests.
-+pref("chat.browserRequest.disableJavascript", false);
- 
- // loglevel is the minimum severity level that a libpurple message
- // must have to be reported in the Error Console.
-diff --git a/chat/content/browserRequest.js b/chat/content/browserRequest.js
-index c52c8c637..0069219fa 100644
---- a/chat/content/browserRequest.js
-+++ b/chat/content/browserRequest.js
-@@ -2,6 +2,8 @@
-  * License, v. 2.0. If a copy of the MPL was not distributed with this
-  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- 
-+Components.utils.import("resource:///modules/imServices.jsm");
-+
- var wpl = Components.interfaces.nsIWebProgressListener;
- 
- var reporterListener = {
-@@ -133,6 +135,11 @@ function loadRequestedUrl()
-     account.protocol.iconBaseURI + "icon48.png";
- 
-   let browser = document.getElementById("requestFrame");
-+  browser.docShell.allowPlugins = false;
-+
-+  if (Services.prefs.getBoolPref("chat.browserRequest.disableJavascript"))
-+    browser.docShell.allowJavascript = false;
-+
-   browser.addProgressListener(reporterListener,
-                               Components.interfaces.nsIWebProgress.NOTIFY_ALL);
-   let url = request.url;
--- 
-2.11.0
-
diff --git a/projects/instantbird/config b/projects/instantbird/config
index 2e4ded1..13859d7 100644
--- a/projects/instantbird/config
+++ b/projects/instantbird/config
@@ -69,26 +69,25 @@ input_files:
   - filename: 0005-Trac-13312-OTR-over-Twitter-DMs.patch
   - filename: 0006-Bug-1218193-Fix-tab-strip-background-colour-on-OS-X..patch
   - filename: 0007-Bug-1246431-XMPP-createConversation-should-handle-in.patch
-  - filename: 0008-Bug-1298574-Set-_userVCard-own-property-when-downloa.patch
-  - filename: 0009-XMPP-in-band-registration.patch
-  - filename: 0010-Remove-search-from-UI.patch
-  - filename: 0011-Add-Tor-Messenger-branding.patch
-  - filename: 0012-Account-picture.patch
-  - filename: 0013-Modify-protocol-defaults.patch
-  - filename: 0014-Modify-IRC-defaults.patch
-  - filename: 0015-Modify-themes.patch
-  - filename: 0016-Modify-XMPP-defaults.patch
-  - filename: 0017-Remove-logging-UI.patch
-  - filename: 0018-Cert-override.patch
-  - filename: 0019-Display-all-traffic-over-Tor.patch
-  - filename: 0020-Trac-17480-Content-sink.patch
-  - filename: 0021-SASL-ECDSA-NIST256P-CHALLENGE.patch
-  - filename: 0022-Bug-1313137-msg-is-not-defined-error-in-irc.js-chang.patch
-  - filename: 0023-Bug-954368-Contact-list-entries-should-adapt-their-h.patch
-  - filename: 0024-Bug-1187281-Only-show-close-button-on-Windows.patch
-  - filename: 0025-Bug-1316000-Remove-old-Yahoo-Messenger-support.-r-al.patch
-  - filename: 0026-Bug-1321641-Use-built-in-functions-instead-of-an-svg.patch
-  - filename: 0027-Bug-1321420-Add-a-pref-to-disable-JavaScript-in-brow.patch
+  - filename: 0008-XMPP-in-band-registration.patch
+  - filename: 0009-Remove-search-from-UI.patch
+  - filename: 0010-Add-Tor-Messenger-branding.patch
+  - filename: 0011-Account-picture.patch
+  - filename: 0012-Modify-protocol-defaults.patch
+  - filename: 0013-Modify-IRC-defaults.patch
+  - filename: 0014-Modify-themes.patch
+  - filename: 0015-Modify-XMPP-defaults.patch
+  - filename: 0016-Remove-logging-UI.patch
+  - filename: 0017-Cert-override.patch
+  - filename: 0018-Display-all-traffic-over-Tor.patch
+  - filename: 0019-Trac-17480-Content-sink.patch
+  - filename: 0020-SASL-ECDSA-NIST256P-CHALLENGE.patch
+  - filename: 0021-Bug-1313137-msg-is-not-defined-error-in-irc.js-chang.patch
+  - filename: 0022-Bug-954368-Contact-list-entries-should-adapt-their-h.patch
+  - filename: 0023-Bug-1187281-Only-show-close-button-on-Windows.patch
+  - filename: 0024-Bug-1316000-Remove-old-Yahoo-Messenger-support.-r-al.patch
+  - filename: 0025-Bug-1321641-Use-built-in-functions-instead-of-an-svg.patch
+  - filename: 0026-Bug-1321420-Add-a-pref-to-disable-JavaScript-in-brow.patch
   - filename: mozconfig-common
   - filename: 'mozconfig-[% c("var/osname") %]'
     name: mozconfig
diff --git a/projects/mozilla/0001-Trac-19910-Prevents-STARTTLS-in-XMPP.patch b/projects/mozilla/0001-Trac-19910-Prevents-STARTTLS-in-XMPP.patch
index d4faed1..d107480 100644
--- a/projects/mozilla/0001-Trac-19910-Prevents-STARTTLS-in-XMPP.patch
+++ b/projects/mozilla/0001-Trac-19910-Prevents-STARTTLS-in-XMPP.patch
@@ -1,4 +1,4 @@
-From d107a09da25db93e19b8512c29205de2aa0387c1 Mon Sep 17 00:00:00 2001
+From 8b9d71382cdf988c17dc20c38d2f9062a0643748 Mon Sep 17 00:00:00 2001
 From: Arlo Breault <arlolra at gmail.com>
 Date: Mon, 10 Oct 2016 10:52:52 -0700
 Subject: [PATCH 1/7] Trac 19910: Prevents STARTTLS in XMPP
diff --git a/projects/mozilla/0002-Trac-16475-Block-flash-too.patch b/projects/mozilla/0002-Trac-16475-Block-flash-too.patch
index 2f0ab05..cef65eb 100644
--- a/projects/mozilla/0002-Trac-16475-Block-flash-too.patch
+++ b/projects/mozilla/0002-Trac-16475-Block-flash-too.patch
@@ -1,4 +1,4 @@
-From 6c422054720f3ec350854c5560c36061b6146149 Mon Sep 17 00:00:00 2001
+From 37767eb8aaaa39fec605b9c636a9e529af84901a Mon Sep 17 00:00:00 2001
 From: Arlo Breault <arlolra at gmail.com>
 Date: Thu, 6 Oct 2016 20:13:35 -0700
 Subject: [PATCH 2/7] Trac 16475: Block flash too
diff --git a/projects/mozilla/0003-Trac-20206-Avoid-the-need-to-download-the-font-Osaka.patch b/projects/mozilla/0003-Trac-20206-Avoid-the-need-to-download-the-font-Osaka.patch
index faa24fa..2e42dc3 100644
--- a/projects/mozilla/0003-Trac-20206-Avoid-the-need-to-download-the-font-Osaka.patch
+++ b/projects/mozilla/0003-Trac-20206-Avoid-the-need-to-download-the-font-Osaka.patch
@@ -1,4 +1,4 @@
-From f3465153bc87a2e9c57d0fe8e796d4a09bcc0e24 Mon Sep 17 00:00:00 2001
+From 7faec6186979e8d6dca736f27949db09d07b0056 Mon Sep 17 00:00:00 2001
 From: Jonathan Kew <jkew at mozilla.com>
 Date: Sun, 9 Oct 2016 09:18:37 -0700
 Subject: [PATCH 3/7] Trac 20206: Avoid the need to download the font Osaka
@@ -44,7 +44,7 @@ index eb7a7889ae6a..5c63e698726a 100644
              LOG_FONTLIST(("(fontlist-singleface) family name: %s, key: %s\n",
                            NS_ConvertUTF16toUTF8(familyName).get(),
 diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
-index e855cdbcb949..2891c804601d 100644
+index e3d98b13c6de..fc8ca9d14656 100644
 --- a/modules/libpref/init/all.js
 +++ b/modules/libpref/init/all.js
 @@ -3577,9 +3577,9 @@ pref("font.name.monospace.x-math", "Courier");
diff --git a/projects/mozilla/0004-Trac-18331-Update-OS-X-toolchain-to-work-with-ESR-45.patch b/projects/mozilla/0004-Trac-18331-Update-OS-X-toolchain-to-work-with-ESR-45.patch
index 1e7c83b..d2c084a 100644
--- a/projects/mozilla/0004-Trac-18331-Update-OS-X-toolchain-to-work-with-ESR-45.patch
+++ b/projects/mozilla/0004-Trac-18331-Update-OS-X-toolchain-to-work-with-ESR-45.patch
@@ -1,4 +1,4 @@
-From 0f7fcd0b4dba93f3e652838f9d9f988e9e8b8726 Mon Sep 17 00:00:00 2001
+From 527afa8ed730a3287b0ae13f8e48acacb7addc4d Mon Sep 17 00:00:00 2001
 From: Arlo Breault <arlolra at gmail.com>
 Date: Wed, 23 Mar 2016 19:52:07 -0700
 Subject: [PATCH 4/7] Trac 18331: Update OS X toolchain to work with ESR 45
diff --git a/projects/mozilla/0005-OSX-package-as-tar.bz2.patch b/projects/mozilla/0005-OSX-package-as-tar.bz2.patch
index 2c24d45..ce2fbb1 100644
--- a/projects/mozilla/0005-OSX-package-as-tar.bz2.patch
+++ b/projects/mozilla/0005-OSX-package-as-tar.bz2.patch
@@ -1,4 +1,4 @@
-From 4c88cc660df421c77335f0d5fb73ea97430ed441 Mon Sep 17 00:00:00 2001
+From 9ba71cc32503f29cfb07204ffcdd2c2703ed0e92 Mon Sep 17 00:00:00 2001
 From: Nicolas Vigier <boklm at torproject.org>
 Date: Thu, 25 Jun 2015 12:18:43 +0200
 Subject: [PATCH 5/7] OSX: package as tar.bz2
diff --git a/projects/mozilla/0006-Updater-fixups-for-TM.patch b/projects/mozilla/0006-Updater-fixups-for-TM.patch
index a8b017a..8a413fd 100644
--- a/projects/mozilla/0006-Updater-fixups-for-TM.patch
+++ b/projects/mozilla/0006-Updater-fixups-for-TM.patch
@@ -1,4 +1,4 @@
-From 08e87872bdf1b8b4fb643682cf33005ba335ba9b Mon Sep 17 00:00:00 2001
+From 102bcac5d81791ced5f245d4cbb6c8a13c10c5a2 Mon Sep 17 00:00:00 2001
 From: Arlo Breault <arlolra at gmail.com>
 Date: Sun, 9 Oct 2016 09:34:38 -0700
 Subject: [PATCH 6/7] Updater fixups for TM
diff --git a/projects/mozilla/0007-Permit-storing-exceptions-even-w-inPrivateBrowsingMo.patch b/projects/mozilla/0007-Permit-storing-exceptions-even-w-inPrivateBrowsingMo.patch
index da802fa..5c9c443 100644
--- a/projects/mozilla/0007-Permit-storing-exceptions-even-w-inPrivateBrowsingMo.patch
+++ b/projects/mozilla/0007-Permit-storing-exceptions-even-w-inPrivateBrowsingMo.patch
@@ -1,4 +1,4 @@
-From 57e056fd04d9e6b49ef84217dce3702959c1a9b3 Mon Sep 17 00:00:00 2001
+From 20c5a6360e15709ca1d7d053fea164a115cbc59e Mon Sep 17 00:00:00 2001
 From: Arlo Breault <arlolra at gmail.com>
 Date: Sat, 3 Dec 2016 10:01:52 -0800
 Subject: [PATCH 7/7] Permit storing exceptions even w/ inPrivateBrowsingMode
diff --git a/projects/mozilla/config b/projects/mozilla/config
index e936de2..a948ce4 100644
--- a/projects/mozilla/config
+++ b/projects/mozilla/config
@@ -1,5 +1,5 @@
 # vim: filetype=yaml sw=2
-version: tor-browser-45.6.0esr-6.0-1-build1
+version: tor-browser-45.7.0esr-6.5-1-build1
 filename: 'mozilla-[% c("version") %]-[% c("var/osname") %]-[% c("var/build_id") %].tar.gz'
 git_url: https://git.torproject.org/tor-browser.git
 git_hash: '[% c("version") %]'
diff --git a/projects/tor-browser/config b/projects/tor-browser/config
index c0337b9..6e6174c 100644
--- a/projects/tor-browser/config
+++ b/projects/tor-browser/config
@@ -1,5 +1,5 @@
 # vim: filetype=yaml sw=2
-version: 6.0.8
+version: 6.5
 filename: 'tor-browser-[% c("version") %]-[% c("var/osname") %].[% c("var/extension") %]'
 
 input_files:
diff --git a/projects/tor-launcher/0001-Bug-19432-Remove-special-handling-for-Instantbird-Th.patch b/projects/tor-launcher/0001-Bug-19432-Remove-special-handling-for-Instantbird-Th.patch
deleted file mode 100644
index 366cde0..0000000
--- a/projects/tor-launcher/0001-Bug-19432-Remove-special-handling-for-Instantbird-Th.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 985b87cb1c6e6e0d70adb9279232423bd105eb4f Mon Sep 17 00:00:00 2001
-From: Kathy Brade <brade at pearlcrescent.com>
-Date: Fri, 24 Jun 2016 12:04:39 -0400
-Subject: [PATCH 1/2] Bug 19432: Remove special handling for
- Instantbird/Thunderbird
-
-These applications now use the same directory structure as Tor Browser.
----
- src/components/tl-process.js | 39 +++++++++++++--------------------------
- 1 file changed, 13 insertions(+), 26 deletions(-)
-
-diff --git a/src/components/tl-process.js b/src/components/tl-process.js
-index ba50310..4f9928a 100644
---- a/src/components/tl-process.js
-+++ b/src/components/tl-process.js
-@@ -32,8 +32,6 @@ TorProcessService.prototype =
-   kContractID : "@torproject.org/torlauncher-process-service;1",
-   kServiceName : "Tor Launcher Process Service",
-   kClassID: Components.ID("{FE7B4CAF-BCF4-4848-8BFF-EFA66C9AFDA1}"),
--  kThunderbirdID: "{3550f703-e582-4d05-9a08-453d09bdfdc6}",
--  kInstantbirdID: "{33cb9019-c295-46dd-be21-8c4936574bee}",
-   kTorLauncherExtPath: "tor-launcher at torproject.org", // This could vary.
- 
-   kPrefPromptAtStartup: "extensions.torlauncher.prompt_at_startup",
-@@ -868,30 +866,19 @@ TorProcessService.prototype =
-                     .getService(Ci.nsIProperties).get("CurProcD", Ci.nsIFile);
-       let appInfo = Cc["@mozilla.org/xre/app-info;1"]
-                       .getService(Ci.nsIXULAppInfo);
--      if ((appInfo.ID == this.kThunderbirdID) ||
--          (appInfo.ID == this.kInstantbirdID))
--      {
--        // For TorBirdy and Tor Messenger the Tor Launcher extension
--        // directory is returned.
--        topDir.append("extensions");
--        topDir.append(this.kTorLauncherExtPath);
--      }
--      else  // Tor Browser
--      {
--        // On Linux and Windows, we want to return the Browser/ directory.
--        // Because topDir ("CurProcD") points to Browser/browser on those
--        // platforms, we need to go up one level.
--        // On Mac OS, we want to return the TorBrowser.app/ directory.
--        // Because topDir points to Contents/Resources/browser on Mac OS,
--        // we need to go up 3 levels.
--        let tbbBrowserDepth = (TorLauncherUtil.isMac) ? 3 : 1;
--        while (tbbBrowserDepth > 0)
--        {
--          let didRemove = (topDir.leafName != ".");
--          topDir = topDir.parent;
--          if (didRemove)
--            tbbBrowserDepth--;
--        }
-+      // On Linux and Windows, we want to return the Browser/ directory.
-+      // Because topDir ("CurProcD") points to Browser/browser on those
-+      // platforms, we need to go up one level.
-+      // On Mac OS, we want to return the TorBrowser.app/ directory.
-+      // Because topDir points to Contents/Resources/browser on Mac OS,
-+      // we need to go up 3 levels.
-+      let tbbBrowserDepth = (TorLauncherUtil.isMac) ? 3 : 1;
-+      while (tbbBrowserDepth > 0)
-+      {
-+        let didRemove = (topDir.leafName != ".");
-+        topDir = topDir.parent;
-+        if (didRemove)
-+          tbbBrowserDepth--;
-       }
- 
-       this.mAppDir = topDir;
--- 
-2.10.2
-
diff --git a/projects/tor-launcher/0002-Bug-19568-Set-CurProcD-for-Thunderbird-Instantbird.patch b/projects/tor-launcher/0002-Bug-19568-Set-CurProcD-for-Thunderbird-Instantbird.patch
deleted file mode 100644
index 0e45ae1..0000000
--- a/projects/tor-launcher/0002-Bug-19568-Set-CurProcD-for-Thunderbird-Instantbird.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 44c1cc246e8736e88906c74058f2c582aa6178ed Mon Sep 17 00:00:00 2001
-From: Sukhbir Singh <sukhbir at torproject.org>
-Date: Mon, 4 Jul 2016 11:59:34 -0400
-Subject: [PATCH 2/2] Bug 19568: Set CurProcD for Thunderbird/Instantbird
-
-For Thunderbird/Instantbird, the CurProcD (topDir) is not browser/,
-so we need to iterate one level less than Firefox.
----
- src/components/tl-process.js | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
-diff --git a/src/components/tl-process.js b/src/components/tl-process.js
-index 4f9928a..8e42feb 100644
---- a/src/components/tl-process.js
-+++ b/src/components/tl-process.js
-@@ -31,6 +31,8 @@ TorProcessService.prototype =
- {
-   kContractID : "@torproject.org/torlauncher-process-service;1",
-   kServiceName : "Tor Launcher Process Service",
-+  kThunderbirdID: "{3550f703-e582-4d05-9a08-453d09bdfdc6}",
-+  kInstantbirdID: "{33cb9019-c295-46dd-be21-8c4936574bee}",
-   kClassID: Components.ID("{FE7B4CAF-BCF4-4848-8BFF-EFA66C9AFDA1}"),
-   kTorLauncherExtPath: "tor-launcher at torproject.org", // This could vary.
- 
-@@ -873,6 +875,14 @@ TorProcessService.prototype =
-       // Because topDir points to Contents/Resources/browser on Mac OS,
-       // we need to go up 3 levels.
-       let tbbBrowserDepth = (TorLauncherUtil.isMac) ? 3 : 1;
-+      if ((appInfo.ID == this.kThunderbirdID) ||
-+          (appInfo.ID == this.kInstantbirdID))
-+      {
-+        // On Thunderbird/Instantbird, the topDir is the root dir and not
-+        // browser/, so we need to iterate one level less than Firefox.
-+        --tbbBrowserDepth;
-+      }
-+
-       while (tbbBrowserDepth > 0)
-       {
-         let didRemove = (topDir.leafName != ".");
--- 
-2.10.2
-
diff --git a/projects/tor-launcher/build b/projects/tor-launcher/build
index 1f51756..8735d33 100644
--- a/projects/tor-launcher/build
+++ b/projects/tor-launcher/build
@@ -2,8 +2,6 @@
 set -e
 tar xvf [% project %]-[% c('version') %].tar.gz
 cd [% project %]-[% c('version') %]
-patch -p1 < ../0001-Bug-19432-Remove-special-handling-for-Instantbird-Th.patch
-patch -p1 < ../0002-Bug-19568-Set-CurProcD-for-Thunderbird-Instantbird.patch
 [% IF c("var/tor_control_port") -%]
 patch -p1 < ../controlport.patch
 [% END -%]
diff --git a/projects/tor-launcher/config b/projects/tor-launcher/config
index e0a1248..f018c0b 100644
--- a/projects/tor-launcher/config
+++ b/projects/tor-launcher/config
@@ -1,13 +1,11 @@
 # vim: filetype=yaml sw=2
-version: 0.2.9.4
+version: 0.2.10.3
 git_url: https://git.torproject.org/tor-launcher.git
 git_hash: '[% c("version") %]'
 gpg_keyring: gk.gpg
 tag_gpg_id: 1
 filename: "[% project %]-[% c('version') %]-[% c('var/build_id') %].xpi"
 input_files:
-  - filename: 0001-Bug-19432-Remove-special-handling-for-Instantbird-Th.patch
-  - filename: 0002-Bug-19568-Set-CurProcD-for-Thunderbird-Instantbird.patch
   - filename: torbirdy.png
   - filename: messenger.png
   - filename: default48.png
diff --git a/rbm.conf b/rbm.conf
index 300465f..1d41b47 100644
--- a/rbm.conf
+++ b/rbm.conf
@@ -6,7 +6,7 @@ output_dir: "out/[% project %]"
 pkg_type: build
 
 var:
-  tormessenger_version: '0.3.0b3'
+  tormessenger_version: '0.4.0b1'
   copyright_year: '2016'
   build_id: '[% sha256(c("var/build_id_txt")).substr(0, 6) %]'
   build_id_txt: |
diff --git a/tools/update-responses/config.yml b/tools/update-responses/config.yml
index d504f85..9e09f57 100644
--- a/tools/update-responses/config.yml
+++ b/tools/update-responses/config.yml
@@ -18,7 +18,7 @@ build_targets:
         - WINNT_x86-gcc3-x64
     osx64: Darwin_x86_64-gcc3
 channels:
-    release: 0.3.0b3
+    release: 0.4.0b1
 versions:
     0.3.0b1:
         platformVersion: 45.5.0



More information about the tor-commits mailing list