[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [tor-messenger-build/master] Move patches to comm-esr45 fork
commit 490f935191fe5edabc7cab58f1d68bc6dbae2408
Author: Arlo Breault <arlolra@xxxxxxxxx>
Date: Sun Oct 9 21:28:13 2016 -0700
Move patches to comm-esr45 fork
---
.../0001-Set-Tor-Messenger-preferences.patch | 198 +
...0002-Trac-16489-Prevent-account-autologin.patch | 121 +
...Support-Special-Characters-input-prompt-o.patch | 78 +
...Better-error-reporting-for-failed-outgoin.patch | 67 +
.../0005-Trac-13312-OTR-over-Twitter-DMs.patch | 1006 ++++
...-Fix-tab-strip-background-colour-on-OS-X..patch | 26 +
...-XMPP-createConversation-should-handle-in.patch | 26 +
...-Set-_userVCard-own-property-when-downloa.patch | 39 +
.../0009-XMPP-in-band-registration.patch | 396 ++
.../instantbird/0010-Remove-search-from-UI.patch | 64 +
.../0011-Add-Tor-Messenger-branding.patch | 5133 ++++++++++++++++++++
projects/instantbird/0012-Account-picture.patch | 26 +
.../0013-Modify-protocol-defaults.patch | 48 +
.../instantbird/0014-Modify-IRC-defaults.patch | 65 +
projects/instantbird/0015-Modify-themes.patch | 78 +
.../instantbird/0016-Modify-XMPP-defaults.patch | 48 +
projects/instantbird/0017-Remove-logging-UI.patch | 43 +
projects/instantbird/0018-Cert-override.patch | 64 +
.../0019-Display-all-traffic-over-Tor.patch | 38 +
.../instantbird/0020-Trac-17480-Content-sink.patch | 101 +
projects/instantbird/about-logo.png | Bin 6681 -> 0 bytes
projects/instantbird/about-logo@xxxxxx | Bin 13886 -> 0 bytes
projects/instantbird/about-wordmark.png | Bin 3754 -> 0 bytes
projects/instantbird/aboutDialog-appUpdater.js | 576 ---
projects/instantbird/aboutDialog-jar.patch | 15 -
projects/instantbird/aboutDialog.css | 91 -
projects/instantbird/aboutDialog.dtd | 129 -
projects/instantbird/aboutDialog.js | 79 -
projects/instantbird/aboutDialog.xul | 173 -
projects/instantbird/account-picture.patch | 13 -
projects/instantbird/branding-aboutDialog.css | 48 -
projects/instantbird/branding/about.png | Bin 9880 -> 0 bytes
projects/instantbird/branding/blistWindow.ico | Bin 9662 -> 0 bytes
projects/instantbird/branding/blistWindow.png | Bin 1003 -> 0 bytes
projects/instantbird/branding/blistWindow16.png | Bin 576 -> 0 bytes
projects/instantbird/branding/blistWindow48.png | Bin 2089 -> 0 bytes
projects/instantbird/branding/convWindow.ico | Bin 10058 -> 0 bytes
projects/instantbird/branding/convWindow.png | Bin 1126 -> 0 bytes
projects/instantbird/branding/convWindow16.png | Bin 637 -> 0 bytes
projects/instantbird/branding/convWindow48.png | Bin 1563 -> 0 bytes
projects/instantbird/branding/default.ico | Bin 7262 -> 0 bytes
projects/instantbird/branding/default.png | Bin 867 -> 0 bytes
projects/instantbird/branding/default16.png | Bin 520 -> 0 bytes
projects/instantbird/branding/default48.png | Bin 1178 -> 0 bytes
projects/instantbird/branding/instantbird.icns | Bin 21624 -> 0 bytes
projects/instantbird/branding/instantbird.ico | Bin 7262 -> 0 bytes
projects/instantbird/branding/jar.patch | 11 -
projects/instantbird/branding/name.patch | 46 -
projects/instantbird/branding/osx.patch | 9 -
projects/instantbird/browserMountPoints.inc | 12 -
projects/instantbird/bug-1218193.patch | 31 -
projects/instantbird/bug-1246431.patch | 31 -
projects/instantbird/bug-1298574.patch | 47 -
projects/instantbird/build | 53 +-
projects/instantbird/cert-installer.patch | 36 -
projects/instantbird/cert_override.txt | 3 -
projects/instantbird/config | 86 +-
projects/instantbird/ctcp-ping.patch | 24 -
projects/instantbird/ctcp-time.patch | 12 -
projects/instantbird/disable-links.patch | 102 -
projects/instantbird/hide-get-protocols.patch | 12 -
projects/instantbird/irc-default-server.patch | 12 -
projects/instantbird/log-preferences-xul.patch | 30 -
projects/instantbird/preferences.patch | 196 -
projects/instantbird/search-context-menu.patch | 28 -
projects/instantbird/search-preferences-xul.patch | 21 -
projects/instantbird/show-traffic-tor.patch | 23 -
projects/instantbird/theme-extension-update.patch | 12 -
projects/instantbird/themes-remove-links.patch | 46 -
projects/instantbird/top-protocols.patch | 18 -
projects/instantbird/trac-13312.patch | 1414 ------
projects/instantbird/trac-16489.patch | 108 -
projects/instantbird/trac-17494.patch | 83 -
projects/instantbird/trac-17896.patch | 67 -
projects/instantbird/trac-20207.patch | 27 -
projects/instantbird/updater-text.patch | 9 -
projects/instantbird/xmpp-default-domain.patch | 12 -
projects/instantbird/xmpp-gtalk-resource.patch | 24 -
.../instantbird/xmpp-inband-registration.patch | 188 -
projects/instantbird/xmpp-onion-js.patch | 89 -
projects/instantbird/xmpp-onion-locale.patch | 10 -
projects/instantbird/xmpp-onion-xul.patch | 23 -
projects/instantbird/xmppRegister.js | 142 -
projects/instantbird/xmppRegister.xul | 27 -
84 files changed, 7701 insertions(+), 4212 deletions(-)
diff --git a/projects/instantbird/0001-Set-Tor-Messenger-preferences.patch b/projects/instantbird/0001-Set-Tor-Messenger-preferences.patch
new file mode 100644
index 0000000..96f3f5b
--- /dev/null
+++ b/projects/instantbird/0001-Set-Tor-Messenger-preferences.patch
@@ -0,0 +1,198 @@
+From 81e0dfcc4197e987a8c64cce36b3cda48e84fe54 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir@xxxxxxxxxxxxxx>
+Date: Mon, 10 Oct 2016 19:48:41 -0700
+Subject: [PATCH 01/20] Set Tor Messenger preferences
+
+---
+ im/app/profile/all-instantbird.js | 107 +++++++++++++++++++++++++++++++-------
+ 1 file changed, 87 insertions(+), 20 deletions(-)
+
+diff --git a/im/app/profile/all-instantbird.js b/im/app/profile/all-instantbird.js
+index b7a3970..86f0559 100644
+--- a/im/app/profile/all-instantbird.js
++++ b/im/app/profile/all-instantbird.js
+@@ -28,7 +28,7 @@ pref("general.autoScroll", true);
+ // 0 = spellcheck nothing
+ // 1 = check multi-line controls [default]
+ // 2 = check multi/single line controls
+-pref("layout.spellcheckDefault", 1);
++pref("layout.spellcheckDefault", 0);
+
+ pref("messenger.accounts.convertOldPasswords", true);
+ pref("messenger.accounts.promptOnDelete", true);
+@@ -66,7 +66,7 @@ pref("extensions.mintrayr.singleClickRestore", false);
+
+ // Whether message related sounds should be played at all. If this is enabled
+ // then the more specific prefs are checked as well.
+-pref("messenger.options.playSounds.message", true);
++pref("messenger.options.playSounds.message", false);
+ // Specifies whether each message event should trigger a sound for incoming
+ // and outgoing messages, or when your nickname is mentioned in a chat.
+ pref("messenger.options.playSounds.outgoing", true);
+@@ -142,26 +142,28 @@ pref("app.update.staging.enabled", true);
+
+ // Update service URL:
+ // You do not need to use all the %VAR% parameters. Use what you need, %PRODUCT%,%VERSION%,%BUILD_ID%,%CHANNEL% for example
+-pref("app.update.url", "https://update.instantbird.org/1/%PRODUCT%/%VERSION%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/update.xml");
++pref("app.update.url", "https://aus2.torproject.org/tormessenger/update_2/%CHANNEL%/%BUILD_TARGET%/%VERSION%/%LOCALE%");
++
++#ifdef XP_WIN
++// For now, disable staged updates on Windows (see #18292).
++pref("app.update.staging.enabled", false);
++#endif
+
+ // URL user can browse to manually if for some reason all update installation
+ // attempts fail.
+-pref("app.update.url.manual", "http://www.instantbird.com/download.html");
++pref("app.update.url.manual", "https://www.torproject.org");
+
+ // A default value for the "More information about this update" link
+ // supplied in the "An update is available" page of the update wizard.
+-pref("app.update.url.details", "http://www.instantbird.com/");
+-
+-// User-settable override to app.update.url for testing purposes.
+-//pref("app.update.url.override", "");
++pref("app.update.url.details", "https://trac.torproject.org/projects/tor/wiki/doc/TorMessenger");
+
+ // Interval: Time between checks for a new version (in seconds)
+ // default=1 day
+-pref("app.update.interval", 86400);
++pref("app.update.interval", 43200);
+
+ // Interval: Time before prompting the user to download a new version that
+ // is available (in seconds) default=1 day
+-pref("app.update.nagTimer.download", 86400);
++pref("app.update.nagTimer.download", 3600);
+
+ // Interval: Time before prompting the user to restart to install the latest
+ // download (in seconds) default=30 minutes
+@@ -202,7 +204,7 @@ pref("browser.search.order.1", "chrome://instantbird/locale/regio
+ pref("browser.search.order.2", "chrome://instantbird/locale/region.properties");
+
+ // send ping to the server to update
+-pref("browser.search.update", true);
++pref("browser.search.update", false);
+
+ // disable logging for the search service update system by default
+ pref("browser.search.update.log", false);
+@@ -222,7 +224,7 @@ pref("extensions.ignoreMTimeChanges", false);
+ pref("extensions.logging.enabled", false);
+ pref("general.skins.selectedSkin", "classic/1.0");
+
+-pref("extensions.update.enabled", true);
++pref("extensions.update.enabled", false);
+ pref("extensions.update.interval", 86400);
+ pref("extensions.update.url", "https://addons.instantbird.org/services/update.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%");
+ pref("extensions.update.autoUpdateDefault", true);
+@@ -245,9 +247,9 @@ pref("extensions.getMoreEmoticonsURL", "https://add-ons.instantbird.org/%LOCALE%
+ pref("extensions.getMoreProtocolsURL", "https://add-ons.instantbird.org/%LOCALE%/%APP%/%VERSION%/protocols/");
+
+ // suppress external-load warning for standard browser schemes
+-pref("network.protocol-handler.warn-external.http", false);
+-pref("network.protocol-handler.warn-external.https", false);
+-pref("network.protocol-handler.warn-external.ftp", false);
++pref("network.protocol-handler.warn-external.http", true);
++pref("network.protocol-handler.warn-external.https", true);
++pref("network.protocol-handler.warn-external.ftp", true);
+
+ // don't load links inside Instantbird
+ pref("network.protocol-handler.expose-all", false);
+@@ -262,10 +264,10 @@ pref("network.protocol-handler.expose.https", true);
+ pref("network.protocol-handler.expose.javascript", true);
+
+ // 0-Accept, 1-dontAcceptForeign, 2-dontUse
+-pref("network.cookie.cookieBehavior", 0);
++pref("network.cookie.cookieBehavior", 1);
+
+ // The breakpad report server to link to in about:crashes
+-pref("breakpad.reportURL", "http://crash-stats.instantbird.com/report/index/");
++pref("breakpad.reportURL", "https://crash-stats.instantbird.com/report/index/");
+
+ // We have an Error Console menu item by default so let's display chrome errors
+ pref("javascript.options.showInConsole", true);
+@@ -300,14 +302,79 @@ pref("browser.tabs.tabClipWidth", 140);
+ // 3 at the end of the tabstrip
+ pref("browser.tabs.closeButtons", 1);
+
+-#expand pref("chat.irc.defaultQuitMessage", "Instantbird __APP_VERSION__ -- http://www.instantbird.com");
++#expand pref("chat.irc.defaultQuitMessage", "");
+
+ pref("chat.twitter.consumerKey", "TSuyS1ieRAkB3qWv8yyEw");
+ pref("chat.twitter.consumerSecret", "DKtKaSf5a7pBNhdBsSZHTnI5Y03hRlPFYWmb4xXBlkU");
+
+ // Comma separated list of prpl ids that should use libpurple even if there is
+ // a JS implementation. This is used to land JS-prpls pref'ed off in nightlies.
+-pref("chat.prpls.forcePurple", "prpl-jabber");
++pref("chat.prpls.forcePurple", "");
+
+ // Whether to parse log files for conversation statistics.
+-pref("statsService.parseLogsForStats", true);
++pref("statsService.parseLogsForStats", false);
++
++/* Tor Messenger */
++// Logging
++// Disable all logging
++pref("purple.logging.log_chats", false);
++pref("purple.logging.log_ims", false);
++pref("purple.logging.log_system", false);
++
++// Network
++// Use a manual proxy configuration
++pref("network.proxy.type", 1);
++// Empty the "no proxy" setting
++pref("network.proxy.no_proxies_on", "");
++// Configure Instantbird to use the SOCKS5 proxy
++pref("network.proxy.socks", "127.0.0.1");
++pref("network.proxy.socks_port", 9152);
++pref("network.proxy.socks_version", 5);
++// Set DNS proxying through SOCKS5
++pref("network.proxy.socks_remote_dns", true);
++// Disable DNS prefetching
++pref("network.dns.disablePrefetch", true);
++// Disable SPDY
++pref("network.http.spdy.enabled", false);
++// Set the user-agent to Instantbird stable
++pref("general.useragent.override", "Mozilla/5.0 (Windows NT 6.1; rv:25.0) Gecko/20100101 Instantbird/1.5");
++
++// Security
++// Disable SSLv3 by setting the minimum supported protocol to TLS 1.0.
++pref("security.tls.version.min", 1);
++// We use the certdb. Necessary for the TB patch,
++// "Bug 14716: HTTP Basic Authentication prompt only displayed once"
++pref("security.nocertdb", false);
++// Disable geolocation
++pref("geo.enabled", false);
++
++// Do not report idle status or the away message
++pref("messenger.status.awayWhenIdle", false);
++pref("messenger.status.defaultIdleAwayMessage", "");
++pref("messenger.status.reportIdle", false);
++// Do not send the message format (fonts, colors)
++pref("messenger.conversations.sendFormat", false);
++// Disable text formatting (remove the tags)
++pref("messenger.options.filterMode", 0);
++// Disable typing notifications
++pref("purple.conversations.im.send_typing", false);
++
++// Browser
++// Disable caching
++pref("browser.cache.disk.enable", false);
++pref("browser.cache.offline.enable", false);
++
++// Media
++// Disable WebRTC
++pref("media.peerconnection.enabled", false);
++// Disable "Take Picture" functionality that accesses the webcam
++pref("media.navigator.video.enabled", false);
++// Disable hardware acceleration
++pref("gfx.direct2d.disabled", true);
++pref("layers.acceleration.disabled", true);
++
++// Other Updates
++pref("app.update.promptWaitTime", 3600);
++
++// Put conversations on hold so that OTR disconnect is not sent. See #20208.
++pref("messenger.conversations.holdByDefault", true);
+--
+2.10.1
+
diff --git a/projects/instantbird/0002-Trac-16489-Prevent-account-autologin.patch b/projects/instantbird/0002-Trac-16489-Prevent-account-autologin.patch
new file mode 100644
index 0000000..b3e386e
--- /dev/null
+++ b/projects/instantbird/0002-Trac-16489-Prevent-account-autologin.patch
@@ -0,0 +1,121 @@
+From 9cb6308cee43524e5b9368d6fc2f0b862dde0a3e Mon Sep 17 00:00:00 2001
+From: Arlo Breault <arlolra@xxxxxxxxx>
+Date: Mon, 16 Nov 2015 20:37:53 -0800
+Subject: [PATCH 02/20] Trac 16489: Prevent account autologin
+
+---
+ chat/components/src/imAccounts.js | 2 +-
+ im/content/account.xml | 4 ----
+ im/content/accountWizard.js | 11 +----------
+ im/content/accountWizard.xul | 2 --
+ im/content/preferences/main.xul | 18 ------------------
+ 5 files changed, 2 insertions(+), 35 deletions(-)
+
+diff --git a/chat/components/src/imAccounts.js b/chat/components/src/imAccounts.js
+index c13c610..5bfea57 100644
+--- a/chat/components/src/imAccounts.js
++++ b/chat/components/src/imAccounts.js
+@@ -588,7 +588,7 @@ imAccount.prototype = {
+ },
+
+ get autoLogin() {
+- let autoLogin = true;
++ let autoLogin = false;
+ try {
+ autoLogin = this.prefBranch.getBoolPref(kPrefAccountAutoLogin);
+ } catch (e) { }
+diff --git a/im/content/account.xml b/im/content/account.xml
+index e063318..78195b7 100644
+--- a/im/content/account.xml
++++ b/im/content/account.xml
+@@ -41,10 +41,6 @@
+ accesskey="&certmgr.addException.accesskey;"/>
+ <xul:spacer flex="1"/>
+ </xul:vbox>
+- <xul:checkbox label="&account.autoSignOn.label;" dir="reverse"
+- xbl:inherits="checked=autologin" class="autoSignOn"
+- accesskey="&account.autoSignOn.accesskey;"
+- oncommand="gAccountManager.autologin()"/>
+ </xul:hbox>
+ <xul:hbox flex="1" class="account-buttons" anonid="buttons"
+ xbl:inherits="autologin"/>
+diff --git a/im/content/accountWizard.js b/im/content/accountWizard.js
+index 73707c9..ed3b8f0 100644
+--- a/im/content/accountWizard.js
++++ b/im/content/accountWizard.js
+@@ -442,22 +442,13 @@ var accountWizard = {
+ throw "unknown type";
+ }
+ }
+- let autologin = this.getValue("connectAutomatically");
+- acc.autoLogin = autologin;
++ acc.autoLogin = false;
+
+ if (this.proto.usePurpleProxy)
+ acc.proxyInfo = this.proxy;
+
+ acc.save();
+
+- try {
+- if (autologin)
+- acc.connect();
+- } catch (e) {
+- // If the connection fails (for example if we are currently in
+- // offline mode), we still want to close the account wizard
+- }
+-
+ if (window.opener) {
+ let am = window.opener.gAccountManager;
+ if (am)
+diff --git a/im/content/accountWizard.xul b/im/content/accountWizard.xul
+index 5fa5b82..9eb5352 100644
+--- a/im/content/accountWizard.xul
++++ b/im/content/accountWizard.xul
+@@ -137,8 +137,6 @@
+ </columns>
+ <rows id="summaryRows"/>
+ </grid>
+- <separator/>
+- <checkbox id="connectAutomatically" label= "&accountSummary.connectAutomatically.label;" checked="true"/>
+ </wizardpage>
+
+ </wizard>
+diff --git a/im/content/preferences/main.xul b/im/content/preferences/main.xul
+index e5f7fb6..5e0024d 100644
+--- a/im/content/preferences/main.xul
++++ b/im/content/preferences/main.xul
+@@ -20,7 +20,6 @@
+ <script type="application/javascript" src="chrome://instantbird/content/preferences/main.js"/>
+
+ <preferences id="mainPreferences">
+- <preference id="messenger.startup.action" name="messenger.startup.action" type="int"/>
+ <preference id="messenger.options.playSounds.blist" name="messenger.options.playSounds.blist" type="bool"/>
+ <preference id="messenger.options.playSounds.message" name="messenger.options.playSounds.message" type="bool"/>
+ <preference id="messenger.options.getAttentionOnNewMessages" name="messenger.options.getAttentionOnNewMessages" type="bool"/>
+@@ -33,23 +32,6 @@
+ <preference id="messenger.options.notifyOfNewMessages" name="messenger.options.notifyOfNewMessages" type="bool"/>
+ </preferences>
+
+- <!-- Startup -->
+- <groupbox id="startupGroup">
+- <caption label="&startup.label;"/>
+-
+- <hbox align="center">
+- <label value="&startupAction.label;" accesskey="&startupAction.accesskey;"
+- control="messengerStartupAction"/>
+- <menulist id="messengerStartupAction" preference="messenger.startup.action">
+- <menupopup>
+- <menuitem label="&startupOffline.label;" value="0"/>
+- <menuitem label="&startupConnectAuto.label;" value="1"/>
+- </menupopup>
+- </menulist>
+- </hbox>
+- </groupbox>
+-
+-
+ <groupbox id="accountsMgrGroup" orient="horizontal" align="center">
+ <caption label="&accountsMgr.label;"/>
+
+--
+2.10.1
+
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
new file mode 100644
index 0000000..df362aa
--- /dev/null
+++ b/projects/instantbird/0003-Trac-17896-Support-Special-Characters-input-prompt-o.patch
@@ -0,0 +1,78 @@
+From ae27272d58c8f3654ba23b1329f07f0dc8fe5a10 Mon Sep 17 00:00:00 2001
+From: aleth <aleth@xxxxxxxxxxxxxxx>
+Date: Sat, 30 Jan 2016 20:56:38 +0100
+Subject: [PATCH 03/20] 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
+
+ Adding an edit menu also enables the emoji panel and dictation.
+---
+ im/content/instantbird.xul | 23 ++++++++++++++++++++++-
+ im/content/menus.xul | 2 +-
+ im/content/menus.xul.inc | 2 ++
+ 3 files changed, 25 insertions(+), 2 deletions(-)
+
+diff --git a/im/content/instantbird.xul b/im/content/instantbird.xul
+index 15a3f98..d208921 100644
+--- a/im/content/instantbird.xul
++++ b/im/content/instantbird.xul
+@@ -48,7 +48,28 @@
+ <script type="application/javascript" src="chrome://instantbird/content/nsContextMenu.js"/>
+
+ #ifdef XP_MACOSX
+-#include menus.xul.inc
++# As menus.xul.inc, but with an Edit menu.
++ <commandset id="maincommandset"/>
++ <keyset id="mainkeyset"/>
++ <menubar id="blistMenubar">
++ <menu id="menu_edit">
++ <menupopup id="menu_editpopup">
++ <menuitem id="menu_undo"/>
++ <menuitem id="menu_redo"/>
++ <menuseparator/>
++ <menuitem id="menu_cut"/>
++ <menuitem id="menu_copy"/>
++ <menuitem id="menu_paste"/>
++ <menuitem id="menu_delete"/>
++ <menuseparator/>
++ <menuitem id="menu_selectAll"/>
++ <menuseparator/>
++ <menuitem id="menu_find"/>
++ <menuitem id="menu_findAgain"/>
++ </menupopup>
++ </menu>
++ </menubar>
++ <popupset id="mainPopupSet"/>
+ #endif
+
+ <commandset id="conversationsCommands">
+diff --git a/im/content/menus.xul b/im/content/menus.xul
+index 0889ce8..894ef13 100644
+--- a/im/content/menus.xul
++++ b/im/content/menus.xul
+@@ -43,7 +43,7 @@
+ </keyset>
+
+ <menubar id="blistMenubar">
+- <menu label="&file.menu;" id="fileMenu" accesskey="&file.accesskey;">
++ <menu label="&file.menu;" id="fileMenu" accesskey="&file.accesskey;" insertbefore="menu_edit">
+ <menupopup id="fileMenuPopup" onpopupshowing="menus.updateFileMenuitems();">
+ <menuitem id="addBuddyMenuItem" label="&addContact;" command="cmd_addbuddy" key="addBuddykey" accesskey="&addContact.accesskey;"/>
+ <menuitem id="newTabMenuItem" label="&newtab;" command="cmd_newtab" key="newtabkey" accesskey="&newtab.accesskey;"/>
+diff --git a/im/content/menus.xul.inc b/im/content/menus.xul.inc
+index 30aeb1f..14fc9e8 100644
+--- a/im/content/menus.xul.inc
++++ b/im/content/menus.xul.inc
+@@ -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/.
+
++# Note instantbird.xul contains a modified copy of this file that
++# should be kept in sync.
+ <commandset id="maincommandset"/>
+ <keyset id="mainkeyset"/>
+ <menubar id="blistMenubar"/>
+--
+2.10.1
+
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
new file mode 100644
index 0000000..4c3501d
--- /dev/null
+++ b/projects/instantbird/0004-Trac-17494-Better-error-reporting-for-failed-outgoin.patch
@@ -0,0 +1,67 @@
+From 13ffc7769be983fbd7668ad40f716683351b249f Mon Sep 17 00:00:00 2001
+From: Arlo Breault <arlolra@xxxxxxxxx>
+Date: Tue, 2 Feb 2016 16:04:51 -0800
+Subject: [PATCH 04/20] Trac 17494: Better error reporting for failed outgoing
+ messages
+
+ * Bug 1245325 - Better error reporting for failed outgoing messages. r=clokep
+---
+ chat/locales/en-US/xmpp.properties | 6 ++++--
+ chat/protocols/xmpp/xmpp.jsm | 17 ++++++++++++-----
+ 2 files changed, 16 insertions(+), 7 deletions(-)
+
+diff --git a/chat/locales/en-US/xmpp.properties b/chat/locales/en-US/xmpp.properties
+index 7f824e5..293ab01 100644
+--- a/chat/locales/en-US/xmpp.properties
++++ b/chat/locales/en-US/xmpp.properties
+@@ -66,7 +66,10 @@ conversation.error.sendFailedAsNotInRoom=Message could not be sent to %1$S as yo
+ # %2$S is the text of the message that wasn't delivered.
+ conversation.error.sendFailedAsRecipientNotInRoom=Message could not be sent to %1$S as the recipient is no longer in the room: %2$S
+ # These are displayed in a conversation as a system error message.
+-conversation.error.remoteServerNotFound=Could not reach the recipient's server
++conversation.error.remoteServerNotFound=Could not reach the recipient's server.
++conversation.error.unknownSendError=An unknown error occurred on sending this message.
++# %S is the name of the message recipient.
++conversation.error.sendServiceUnavailable=It is not possible to send messages to %S at this time.
+ # %S is the nick of participant that is not in room.
+ conversation.error.nickNotInRoom=%S is not in the room.
+ conversation.error.banCommandAnonymousRoom=You can't ban participants from anonymous rooms. Try /kick instead.
+@@ -80,7 +83,6 @@ conversation.error.failedJIDNotFound=Could not reach %S.
+ # %S is the jid that is invalid.
+ conversation.error.invalidJID=%S is an invalid jid (Jabber identifiers must be of the form user@domain).
+ conversation.error.commandFailedNotInRoom=You have to rejoin the room to be able to use this command.
+-conversation.error.unknownError=Unknown error
+
+ # 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 67cab77..0022be3 100644
+--- a/chat/protocols/xmpp/xmpp.jsm
++++ b/chat/protocols/xmpp/xmpp.jsm
+@@ -679,11 +679,18 @@ var XMPPConversationPrototype = {
+ let muc = this._account._mucs.get(norm);
+
+ if (!aMsg) {
+- // Failed outgoing message unknown.
+- if (error.condition == "remote-server-not-found")
+- aMsg = _("conversation.error.remoteServerNotFound");
+- else
+- aMsg = _("conversation.error.unknownError");
++ // Failed outgoing message.
++ switch (error.condition) {
++ case "remote-server-not-found":
++ aMsg = _("conversation.error.remoteServerNotFound");
++ break;
++ case "service-unavailable":
++ aMsg = _("conversation.error.sendServiceUnavailable", this.shortName);
++ break;
++ default:
++ aMsg = _("conversation.error.unknownSendError");
++ break;
++ }
+ }
+ else if (this._isMucParticipant && muc && !muc.left &&
+ error.condition == "item-not-found") {
+--
+2.10.1
+
diff --git a/projects/instantbird/0005-Trac-13312-OTR-over-Twitter-DMs.patch b/projects/instantbird/0005-Trac-13312-OTR-over-Twitter-DMs.patch
new file mode 100644
index 0000000..0743dde
--- /dev/null
+++ b/projects/instantbird/0005-Trac-13312-OTR-over-Twitter-DMs.patch
@@ -0,0 +1,1006 @@
+From ea824468b2e4084a40863c934cc0ce72ac2d7076 Mon Sep 17 00:00:00 2001
+From: Arlo Breault <arlolra@xxxxxxxxx>
+Date: Tue, 15 Mar 2016 17:40:42 -0700
+Subject: [PATCH 05/20] Trac 13312: OTR over Twitter DMs
+
+---
+ chat/components/src/imConversations.js | 4 +-
+ chat/modules/jsProtoHelper.jsm | 1 +
+ chat/protocols/twitter/twitter-text.jsm | 267 +++++++++++----------
+ chat/protocols/twitter/twitter.js | 406 ++++++++++++++++----------------
+ 4 files changed, 355 insertions(+), 323 deletions(-)
+
+diff --git a/chat/components/src/imConversations.js b/chat/components/src/imConversations.js
+index 6fc5d0d..5187212 100644
+--- a/chat/components/src/imConversations.js
++++ b/chat/components/src/imConversations.js
+@@ -30,6 +30,7 @@ function imMessage(aPrplMessage) {
+ }
+ imMessage.prototype = {
+ __proto__: ClassInfo(["imIMessage", "prplIMessage"], "IM Message"),
++ get wrappedJSObject() { return this; },
+ cancelled: false,
+ color: "",
+ _displayMessage: null,
+@@ -414,7 +415,8 @@ UIConversation.prototype = {
+ this.notifyObservers(aSubject, "received-message");
+ if (aSubject.cancelled)
+ return;
+- aSubject.conversation.prepareForDisplaying(aSubject);
++ if (!aSubject.system)
++ aSubject.conversation.prepareForDisplaying(aSubject);
+
+ this._messages.push(aSubject);
+ ++this._unreadMessageCount;
+diff --git a/chat/modules/jsProtoHelper.jsm b/chat/modules/jsProtoHelper.jsm
+index 42bd9f6..69af716 100644
+--- a/chat/modules/jsProtoHelper.jsm
++++ b/chat/modules/jsProtoHelper.jsm
+@@ -381,6 +381,7 @@ AccountBuddy.prototype = GenericAccountBuddyPrototype;
+
+ var GenericMessagePrototype = {
+ __proto__: ClassInfo("prplIMessage", "generic message object"),
++ get wrappedJSObject() { return this; },
+
+ _lastId: 0,
+ _init: function (aWho, aMessage, aObject) {
+diff --git a/chat/protocols/twitter/twitter-text.jsm b/chat/protocols/twitter/twitter-text.jsm
+index 1940fd2..a8f8370 100644
+--- a/chat/protocols/twitter/twitter-text.jsm
++++ b/chat/protocols/twitter/twitter-text.jsm
+@@ -19,7 +19,7 @@ var window = {};
+
+ // The code below is imported from Twitter's JavaScript utility for parsing
+ // tweets. The original version of this file can be found at
+-// https://github.com/twitter/twitter-text-js/blob/master/twitter-text.js
++// https://github.com/twitter/twitter-text/blob/master/js/twitter-text.js
+
+ (function() {
+ if (typeof twttr === "undefined" || twttr === null) {
+@@ -125,80 +125,6 @@ var window = {};
+ twttr.txt.regexen.rtl_chars = /[\u0600-\u06FF]|[\u0750-\u077F]|[\u0590-\u05FF]|[\uFE70-\uFEFF]/mg;
+ twttr.txt.regexen.non_bmp_code_pairs = /[\uD800-\uDBFF][\uDC00-\uDFFF]/mg;
+
+- var nonLatinHashtagChars = [];
+- // Cyrillic
+- addCharsToCharClass(nonLatinHashtagChars, 0x0400, 0x04ff); // Cyrillic
+- addCharsToCharClass(nonLatinHashtagChars, 0x0500, 0x0527); // Cyrillic Supplement
+- addCharsToCharClass(nonLatinHashtagChars, 0x2de0, 0x2dff); // Cyrillic Extended A
+- addCharsToCharClass(nonLatinHashtagChars, 0xa640, 0xa69f); // Cyrillic Extended B
+- // Hebrew
+- addCharsToCharClass(nonLatinHashtagChars, 0x0591, 0x05bf); // Hebrew
+- addCharsToCharClass(nonLatinHashtagChars, 0x05c1, 0x05c2);
+- addCharsToCharClass(nonLatinHashtagChars, 0x05c4, 0x05c5);
+- addCharsToCharClass(nonLatinHashtagChars, 0x05c7, 0x05c7);
+- addCharsToCharClass(nonLatinHashtagChars, 0x05d0, 0x05ea);
+- addCharsToCharClass(nonLatinHashtagChars, 0x05f0, 0x05f4);
+- addCharsToCharClass(nonLatinHashtagChars, 0xfb12, 0xfb28); // Hebrew Presentation Forms
+- addCharsToCharClass(nonLatinHashtagChars, 0xfb2a, 0xfb36);
+- addCharsToCharClass(nonLatinHashtagChars, 0xfb38, 0xfb3c);
+- addCharsToCharClass(nonLatinHashtagChars, 0xfb3e, 0xfb3e);
+- addCharsToCharClass(nonLatinHashtagChars, 0xfb40, 0xfb41);
+- addCharsToCharClass(nonLatinHashtagChars, 0xfb43, 0xfb44);
+- addCharsToCharClass(nonLatinHashtagChars, 0xfb46, 0xfb4f);
+- // Arabic
+- addCharsToCharClass(nonLatinHashtagChars, 0x0610, 0x061a); // Arabic
+- addCharsToCharClass(nonLatinHashtagChars, 0x0620, 0x065f);
+- addCharsToCharClass(nonLatinHashtagChars, 0x066e, 0x06d3);
+- addCharsToCharClass(nonLatinHashtagChars, 0x06d5, 0x06dc);
+- addCharsToCharClass(nonLatinHashtagChars, 0x06de, 0x06e8);
+- addCharsToCharClass(nonLatinHashtagChars, 0x06ea, 0x06ef);
+- addCharsToCharClass(nonLatinHashtagChars, 0x06fa, 0x06fc);
+- addCharsToCharClass(nonLatinHashtagChars, 0x06ff, 0x06ff);
+- addCharsToCharClass(nonLatinHashtagChars, 0x0750, 0x077f); // Arabic Supplement
+- addCharsToCharClass(nonLatinHashtagChars, 0x08a0, 0x08a0); // Arabic Extended A
+- addCharsToCharClass(nonLatinHashtagChars, 0x08a2, 0x08ac);
+- addCharsToCharClass(nonLatinHashtagChars, 0x08e4, 0x08fe);
+- addCharsToCharClass(nonLatinHashtagChars, 0xfb50, 0xfbb1); // Arabic Pres. Forms A
+- addCharsToCharClass(nonLatinHashtagChars, 0xfbd3, 0xfd3d);
+- addCharsToCharClass(nonLatinHashtagChars, 0xfd50, 0xfd8f);
+- addCharsToCharClass(nonLatinHashtagChars, 0xfd92, 0xfdc7);
+- addCharsToCharClass(nonLatinHashtagChars, 0xfdf0, 0xfdfb);
+- addCharsToCharClass(nonLatinHashtagChars, 0xfe70, 0xfe74); // Arabic Pres. Forms B
+- addCharsToCharClass(nonLatinHashtagChars, 0xfe76, 0xfefc);
+- addCharsToCharClass(nonLatinHashtagChars, 0x200c, 0x200c); // Zero-Width Non-Joiner
+- // Thai
+- addCharsToCharClass(nonLatinHashtagChars, 0x0e01, 0x0e3a);
+- addCharsToCharClass(nonLatinHashtagChars, 0x0e40, 0x0e4e);
+- // Hangul (Korean)
+- addCharsToCharClass(nonLatinHashtagChars, 0x1100, 0x11ff); // Hangul Jamo
+- addCharsToCharClass(nonLatinHashtagChars, 0x3130, 0x3185); // Hangul Compatibility Jamo
+- addCharsToCharClass(nonLatinHashtagChars, 0xA960, 0xA97F); // Hangul Jamo Extended-A
+- addCharsToCharClass(nonLatinHashtagChars, 0xAC00, 0xD7AF); // Hangul Syllables
+- addCharsToCharClass(nonLatinHashtagChars, 0xD7B0, 0xD7FF); // Hangul Jamo Extended-B
+- addCharsToCharClass(nonLatinHashtagChars, 0xFFA1, 0xFFDC); // half-width Hangul
+- // Japanese and Chinese
+- addCharsToCharClass(nonLatinHashtagChars, 0x30A1, 0x30FA); // Katakana (full-width)
+- addCharsToCharClass(nonLatinHashtagChars, 0x30FC, 0x30FE); // Katakana Chouon and iteration marks (full-width)
+- addCharsToCharClass(nonLatinHashtagChars, 0xFF66, 0xFF9F); // Katakana (half-width)
+- addCharsToCharClass(nonLatinHashtagChars, 0xFF70, 0xFF70); // Katakana Chouon (half-width)
+- addCharsToCharClass(nonLatinHashtagChars, 0xFF10, 0xFF19); // \
+- addCharsToCharClass(nonLatinHashtagChars, 0xFF21, 0xFF3A); // - Latin (full-width)
+- addCharsToCharClass(nonLatinHashtagChars, 0xFF41, 0xFF5A); // /
+- addCharsToCharClass(nonLatinHashtagChars, 0x3041, 0x3096); // Hiragana
+- addCharsToCharClass(nonLatinHashtagChars, 0x3099, 0x309E); // Hiragana voicing and iteration mark
+- addCharsToCharClass(nonLatinHashtagChars, 0x3400, 0x4DBF); // Kanji (CJK Extension A)
+- addCharsToCharClass(nonLatinHashtagChars, 0x4E00, 0x9FFF); // Kanji (Unified)
+- // -- Disabled as it breaks the Regex.
+- //addCharsToCharClass(nonLatinHashtagChars, 0x20000, 0x2A6DF); // Kanji (CJK Extension B)
+- addCharsToCharClass(nonLatinHashtagChars, 0x2A700, 0x2B73F); // Kanji (CJK Extension C)
+- addCharsToCharClass(nonLatinHashtagChars, 0x2B740, 0x2B81F); // Kanji (CJK Extension D)
+- addCharsToCharClass(nonLatinHashtagChars, 0x2F800, 0x2FA1F); // Kanji (CJK supplement)
+- addCharsToCharClass(nonLatinHashtagChars, 0x3003, 0x3003); // Kanji iteration mark
+- addCharsToCharClass(nonLatinHashtagChars, 0x3005, 0x3005); // Kanji iteration mark
+- addCharsToCharClass(nonLatinHashtagChars, 0x303B, 0x303B); // Han iteration mark
+-
+- twttr.txt.regexen.nonLatinHashtagChars = regexSupplant(nonLatinHashtagChars.join(""));
+-
+ var latinAccentChars = [];
+ // Latin accented characters (subtracted 0xD7 from the range, it's a confusable multiplication sign. Looks like "x")
+ addCharsToCharClass(latinAccentChars, 0x00c0, 0x00d6);
+@@ -225,16 +151,20 @@ var window = {};
+ addCharsToCharClass(latinAccentChars, 0x1e00, 0x1eff);
+ twttr.txt.regexen.latinAccentChars = regexSupplant(latinAccentChars.join(""));
+
+- // A hashtag must contain characters, numbers and underscores, but not all numbers.
++ var unicodeLettersAndMarks = "A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0
B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8
-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u
2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\u
FB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C03\u0C3E-\u0C44
\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u192B\u1930-\u193B\u19B0-\u19C0\u19C8\u19C9\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099
\u309A\uA66F-\uA672\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2D";
++ var unicodeNumbers = "0-9\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE6-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29\u1040-\u1049\u1090-\u1099\u17E0-\u17E9\u1810-\u1819\u1946-\u194F\u19D0-\u19D9\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\uA620-\uA629\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19";
++ var hashtagSpecialChars = "_\u200c\u200d\ua67e\u05be\u05f3\u05f4\uff5e\u301c\u309b\u309c\u30a0\u30fb\u3003\u0f0b\u0f0c\u00b7";
++
++ // A hashtag must contain at least one unicode letter or mark, as well as numbers, underscores, and select special characters.
+ twttr.txt.regexen.hashSigns = /[#ï¼?]/;
+- twttr.txt.regexen.hashtagAlpha = regexSupplant(/[a-z_#{latinAccentChars}#{nonLatinHashtagChars}]/i);
+- twttr.txt.regexen.hashtagAlphaNumeric = regexSupplant(/[a-z0-9_#{latinAccentChars}#{nonLatinHashtagChars}]/i);
++ twttr.txt.regexen.hashtagAlpha = new RegExp("[" + unicodeLettersAndMarks + "]");
++ twttr.txt.regexen.hashtagAlphaNumeric = new RegExp("[" + unicodeLettersAndMarks + unicodeNumbers + hashtagSpecialChars + "]");
+ twttr.txt.regexen.endHashtagMatch = regexSupplant(/^(?:#{hashSigns}|:\/\/)/);
+- twttr.txt.regexen.hashtagBoundary = regexSupplant(/(?:^|$|[^&a-z0-9_#{latinAccentChars}#{nonLatinHashtagChars}])/);
+- twttr.txt.regexen.validHashtag = regexSupplant(/(#{hashtagBoundary})(#{hashSigns})(#{hashtagAlphaNumeric}*#{hashtagAlpha}#{hashtagAlphaNumeric}*)/gi);
++ twttr.txt.regexen.hashtagBoundary = new RegExp("(?:^|$|[^&" + unicodeLettersAndMarks + unicodeNumbers + hashtagSpecialChars + "])");
++ twttr.txt.regexen.validHashtag = regexSupplant(/(#{hashtagBoundary})(#{hashSigns})(?!\ufe0f|\u20e3)(#{hashtagAlphaNumeric}*#{hashtagAlpha}#{hashtagAlphaNumeric}*)/gi);
+
+ // Mention related regex collection
+- twttr.txt.regexen.validMentionPrecedingChars = /(?:^|[^a-zA-Z0-9_!#$%&*@ï¼ ]|RT:?)/;
++ twttr.txt.regexen.validMentionPrecedingChars = /(?:^|[^a-zA-Z0-9_!#$%&*@ï¼ ]|(?:^|[^a-zA-Z0-9_+~.-])(?:rt|RT|rT|Rt):?)/;
+ twttr.txt.regexen.atSigns = /[@ï¼ ]/;
+ twttr.txt.regexen.validMentionOrList = regexSupplant(
+ '(#{validMentionPrecedingChars})' + // $1: Preceding character
+@@ -252,30 +182,110 @@ var window = {};
+ twttr.txt.regexen.validDomainChars = regexSupplant(/[^#{invalidDomainChars}]/);
+ twttr.txt.regexen.validSubdomain = regexSupplant(/(?:(?:#{validDomainChars}(?:[_-]|#{validDomainChars})*)?#{validDomainChars}\.)/);
+ twttr.txt.regexen.validDomainName = regexSupplant(/(?:(?:#{validDomainChars}(?:-|#{validDomainChars})*)?#{validDomainChars}\.)/);
+- twttr.txt.regexen.validGTLD = regexSupplant(/(?:(?:aero|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|xxx)(?=[^0-9a-zA-Z]|$))/);
++ twttr.txt.regexen.validGTLD = regexSupplant(RegExp(
++ '(?:(?:' +
++ 'abb|abbott|abogado|academy|accenture|accountant|accountants|aco|active|actor|ads|adult|aeg|aero|' +
++ 'afl|agency|aig|airforce|airtel|allfinanz|alsace|amsterdam|android|apartments|app|aquarelle|' +
++ 'archi|army|arpa|asia|associates|attorney|auction|audio|auto|autos|axa|azure|band|bank|bar|' +
++ 'barcelona|barclaycard|barclays|bargains|bauhaus|bayern|bbc|bbva|bcn|beer|bentley|berlin|best|' +
++ 'bet|bharti|bible|bid|bike|bing|bingo|bio|biz|black|blackfriday|bloomberg|blue|bmw|bnl|' +
++ 'bnpparibas|boats|bond|boo|boots|boutique|bradesco|bridgestone|broker|brother|brussels|budapest|' +
++ 'build|builders|business|buzz|bzh|cab|cafe|cal|camera|camp|cancerresearch|canon|capetown|capital|' +
++ 'caravan|cards|care|career|careers|cars|cartier|casa|cash|casino|cat|catering|cba|cbn|ceb|center|' +
++ 'ceo|cern|cfa|cfd|chanel|channel|chat|cheap|chloe|christmas|chrome|church|cisco|citic|city|' +
++ 'claims|cleaning|click|clinic|clothing|cloud|club|coach|codes|coffee|college|cologne|com|' +
++ 'commbank|community|company|computer|condos|construction|consulting|contractors|cooking|cool|' +
++ 'coop|corsica|country|coupons|courses|credit|creditcard|cricket|crown|crs|cruises|cuisinella|' +
++ 'cymru|cyou|dabur|dad|dance|date|dating|datsun|day|dclk|deals|degree|delivery|delta|democrat|' +
++ 'dental|dentist|desi|design|dev|diamonds|diet|digital|direct|directory|discount|dnp|docs|dog|' +
++ 'doha|domains|doosan|download|drive|durban|dvag|earth|eat|edu|education|email|emerck|energy|' +
++ 'engineer|engineering|enterprises|epson|equipment|erni|esq|estate|eurovision|eus|events|everbank|' +
++ 'exchange|expert|exposed|express|fage|fail|faith|family|fan|fans|farm|fashion|feedback|film|' +
++ 'finance|financial|firmdale|fish|fishing|fit|fitness|flights|florist|flowers|flsmidth|fly|foo|' +
++ 'football|forex|forsale|forum|foundation|frl|frogans|fund|furniture|futbol|fyi|gal|gallery|game|' +
++ 'garden|gbiz|gdn|gent|genting|ggee|gift|gifts|gives|giving|glass|gle|global|globo|gmail|gmo|gmx|' +
++ 'gold|goldpoint|golf|goo|goog|google|gop|gov|graphics|gratis|green|gripe|group|guge|guide|' +
++ 'guitars|guru|hamburg|hangout|haus|healthcare|help|here|hermes|hiphop|hitachi|hiv|hockey|' +
++ 'holdings|holiday|homedepot|homes|honda|horse|host|hosting|hoteles|hotmail|house|how|hsbc|ibm|' +
++ 'icbc|ice|icu|ifm|iinet|immo|immobilien|industries|infiniti|info|ing|ink|institute|insure|int|' +
++ 'international|investments|ipiranga|irish|ist|istanbul|itau|iwc|java|jcb|jetzt|jewelry|jlc|jll|' +
++ 'jobs|joburg|jprs|juegos|kaufen|kddi|kim|kitchen|kiwi|koeln|komatsu|krd|kred|kyoto|lacaixa|' +
++ 'lancaster|land|lasalle|lat|latrobe|law|lawyer|lds|lease|leclerc|legal|lexus|lgbt|liaison|lidl|' +
++ 'life|lighting|limited|limo|link|live|lixil|loan|loans|lol|london|lotte|lotto|love|ltda|lupin|' +
++ 'luxe|luxury|madrid|maif|maison|man|management|mango|market|marketing|markets|marriott|mba|media|' +
++ 'meet|melbourne|meme|memorial|men|menu|miami|microsoft|mil|mini|mma|mobi|moda|moe|mom|monash|' +
++ 'money|montblanc|mormon|mortgage|moscow|motorcycles|mov|movie|movistar|mtn|mtpc|museum|nadex|' +
++ 'nagoya|name|navy|nec|net|netbank|network|neustar|new|news|nexus|ngo|nhk|nico|ninja|nissan|nokia|' +
++ 'nra|nrw|ntt|nyc|office|okinawa|omega|one|ong|onl|online|ooo|oracle|orange|org|organic|osaka|' +
++ 'otsuka|ovh|page|panerai|paris|partners|parts|party|pet|pharmacy|philips|photo|photography|' +
++ 'photos|physio|piaget|pics|pictet|pictures|pink|pizza|place|play|plumbing|plus|pohl|poker|porn|' +
++ 'post|praxi|press|pro|prod|productions|prof|properties|property|pub|qpon|quebec|racing|realtor|' +
++ 'realty|recipes|red|redstone|rehab|reise|reisen|reit|ren|rent|rentals|repair|report|republican|' +
++ 'rest|restaurant|review|reviews|rich|ricoh|rio|rip|rocks|rodeo|rsvp|ruhr|run|ryukyu|saarland|' +
++ 'sakura|sale|samsung|sandvik|sandvikcoromant|sanofi|sap|sarl|saxo|sca|scb|schmidt|scholarships|' +
++ 'school|schule|schwarz|science|scor|scot|seat|seek|sener|services|sew|sex|sexy|shiksha|shoes|' +
++ 'show|shriram|singles|site|ski|sky|skype|sncf|soccer|social|software|sohu|solar|solutions|sony|' +
++ 'soy|space|spiegel|spreadbetting|srl|starhub|statoil|studio|study|style|sucks|supplies|supply|' +
++ 'support|surf|surgery|suzuki|swatch|swiss|sydney|systems|taipei|tatamotors|tatar|tattoo|tax|taxi|' +
++ 'team|tech|technology|tel|telefonica|temasek|tennis|thd|theater|tickets|tienda|tips|tires|tirol|' +
++ 'today|tokyo|tools|top|toray|toshiba|tours|town|toyota|toys|trade|trading|training|travel|trust|' +
++ 'tui|ubs|university|uno|uol|vacations|vegas|ventures|vermögensberater|vermögensberatung|' +
++ 'versicherung|vet|viajes|video|villas|vin|vision|vista|vistaprint|vlaanderen|vodka|vote|voting|' +
++ 'voto|voyage|wales|walter|wang|watch|webcam|website|wed|wedding|weir|whoswho|wien|wiki|' +
++ 'williamhill|win|windows|wine|wme|work|works|world|wtc|wtf|xbox|xerox|xin|xperia|xxx|xyz|yachts|' +
++ 'yandex|yodobashi|yoga|yokohama|youtube|zip|zone|zuerich|деÑ?и|ком|моÑ?ква|онлайн|оÑ?г|Ñ?Ñ?Ñ?|Ñ?айÑ?|ק×?×?|' +
++ 'بازار|شبÙ?Ø©|Ù?Ù?Ù?|Ù?Ù?Ù?ع|à¤?à¥?म|नà¥?à¤?|सà¤?à¤?ठन|à¸?à¸à¸¡|ã?¿ã??ã?ª|ã?°ã?¼ã?°ã?«|ã?³ã? |ä¸?ç??|ä¸ä¿¡|ä¸æ??ç½?|ä¼?ä¸?|ä½?å±±|ä¿¡æ?¯|å?¥åº·|å?«å?¦|å?¬å?¸|å?¬ç??|å??å??|å??åº?|å??æ ?|å?¨çº¿|大æ?¿|' +
++ '娱ä¹?|å·¥è¡?|广ä¸?|æ??å??|æ??ç?±ä½ |æ??æ?º|æ?¿å?¡|æ?¿åº?|æ?°é?»|æ?¶å°?|æ?ºæ??|淡马é?¡|游æ??|ç?¹ç??|移å?¨|ç»?ç»?æ?ºæ??|ç½?å??|ç½?åº?|ç½?ç»?|è°·æ?|é??å?¢|é£?å?©æµ¦|é¤?å??|ë?·ë?·|ë?·ì»´|ì?¼ì?±|onion' +
++ ')(?=[^0-9a-zA-Z@]|$))'));
+ twttr.txt.regexen.validCCTLD = regexSupplant(RegExp(
+- "(?:(?:ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|" +
+- "ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|" +
+- "ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|" +
+- "ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|" +
+- "na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|" +
+- "sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|" +
+- "ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw)(?=[^0-9a-zA-Z]|$))"));
++ '(?:(?:' +
++ 'ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bl|bm|bn|bo|bq|' +
++ 'br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|' +
++ 'ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|' +
++ 'gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|' +
++ 'la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mf|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|' +
++ 'my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|' +
++ 'rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|' +
++ 'tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw|ελ|' +
++ 'бел|мкд|мон|Ñ?Ñ?|Ñ?Ñ?б|Ñ?кÑ?|Ò?аз|Õ°Õ¡Õµ|اÙ?اردÙ?|اÙ?جزائر|اÙ?سعÙ?دÙ?Ø©|اÙ?Ù?غرب|اÙ?ارات|اÛ?راÙ?|بھارت|تÙ?Ù?س|سÙ?داÙ?|' +
++ 'سÙ?رÙ?Ø©|عراÙ?|عÙ?اÙ?|Ù?Ù?سطÙ?Ù?|Ù?طر|Ù?صر|Ù?Ù?Ù?سÙ?ا|پاکستاÙ?|à¤à¤¾à¤°à¤¤|বাà¦?লা|à¦à¦¾à¦°à¦¤|à¨à¨¾à¨°à¨¤|àªàª¾àª°àª¤|à®?நà¯?தியா|à®?லà®?à¯?à®?à¯?|' +
++ 'à®?ிà®?à¯?à®?பà¯?பà¯?à®°à¯?|à°à°¾à°°à°¤à±?|ලà¶?à¶?à·?|à¹?à¸?ย|á??á??|ä¸å?½|ä¸å??|å?°æ¹¾|å?°ç?£|æ?°å? å?¡|æ¾³é??|é¦?港|í??êµ' +
++ ')(?=[^0-9a-zA-Z@]|$))'));
+ twttr.txt.regexen.validPunycode = regexSupplant(/(?:xn--[0-9a-z]+)/);
++ twttr.txt.regexen.validSpecialCCTLD = regexSupplant(RegExp(
++ '(?:(?:co|tv)(?=[^0-9a-zA-Z@]|$))'));
+ twttr.txt.regexen.validDomain = regexSupplant(/(?:#{validSubdomain}*#{validDomainName}(?:#{validGTLD}|#{validCCTLD}|#{validPunycode}))/);
+ twttr.txt.regexen.validAsciiDomain = regexSupplant(/(?:(?:[\-a-z0-9#{latinAccentChars}]+)\.)+(?:#{validGTLD}|#{validCCTLD}|#{validPunycode})/gi);
+- twttr.txt.regexen.invalidShortDomain = regexSupplant(/^#{validDomainName}#{validCCTLD}$/);
++ twttr.txt.regexen.invalidShortDomain = regexSupplant(/^#{validDomainName}#{validCCTLD}$/i);
++ twttr.txt.regexen.validSpecialShortDomain = regexSupplant(/^#{validDomainName}#{validSpecialCCTLD}$/i);
+
+ twttr.txt.regexen.validPortNumber = regexSupplant(/[0-9]+/);
+
+- twttr.txt.regexen.validGeneralUrlPathChars = regexSupplant(/[a-z0-9!\*';:=\+,\.\$\/%#\[\]\-_~@|&#{latinAccentChars}]/i);
+- // Allow URL paths to contain balanced parens
++ twttr.txt.regexen.cyrillicLettersAndMarks = regexSupplant("\u0400-\u04FF");
++ twttr.txt.regexen.validGeneralUrlPathChars = regexSupplant(/[a-z#{cyrillicLettersAndMarks}0-9!\*';:=\+,\.\$\/%#\[\]\-_~@\|&#{latinAccentChars}]/i);
++ // Allow URL paths to contain up to two nested levels of balanced parens
+ // 1. Used in Wikipedia URLs like /Primer_(film)
+ // 2. Used in IIS sessions like /S(dfd346)/
+- twttr.txt.regexen.validUrlBalancedParens = regexSupplant(/\(#{validGeneralUrlPathChars}+\)/i);
++ // 3. Used in Rdio URLs like /track/We_Up_(Album_Version_(Edited))/
++ twttr.txt.regexen.validUrlBalancedParens = regexSupplant(
++ '\\(' +
++ '(?:' +
++ '#{validGeneralUrlPathChars}+' +
++ '|' +
++ // allow one nested level of balanced parentheses
++ '(?:' +
++ '#{validGeneralUrlPathChars}*' +
++ '\\(' +
++ '#{validGeneralUrlPathChars}+' +
++ '\\)' +
++ '#{validGeneralUrlPathChars}*' +
++ ')' +
++ ')' +
++ '\\)'
++ , 'i');
+ // Valid end-of-path chracters (so /foo. does not gobble the period).
+ // 1. Allow =&# for empty URL parameters and other URL-join artifacts
+- twttr.txt.regexen.validUrlPathEndingChars = regexSupplant(/[\+\-a-z0-9=_#\/#{latinAccentChars}]|(?:#{validUrlBalancedParens})/i);
++ twttr.txt.regexen.validUrlPathEndingChars = regexSupplant(/[\+\-a-z#{cyrillicLettersAndMarks}0-9=_#\/#{latinAccentChars}]|(?:#{validUrlBalancedParens})/i);
+ // Allow @ in a url, but only in the middle. Catch things like http://example.com/@user/
+ twttr.txt.regexen.validUrlPath = regexSupplant('(?:' +
+ '(?:' +
+@@ -309,7 +319,7 @@ var window = {};
+ twttr.txt.regexen.validCashtag = regexSupplant('(^|#{spaces})(\\$)(#{cashtag})(?=$|\\s|[#{punct}])', 'gi');
+
+ // These URL validation pattern strings are based on the ABNF from RFC 3986
+- twttr.txt.regexen.validateUrlUnreserved = /[a-z0-9\-._~]/i;
++ twttr.txt.regexen.validateUrlUnreserved = /[a-z\u0400-\u04FF0-9\-._~]/i;
+ twttr.txt.regexen.validateUrlPctEncoded = /(?:%[0-9a-f]{2})/i;
+ twttr.txt.regexen.validateUrlSubDelims = /[!$&'()*+,;=]/i;
+ twttr.txt.regexen.validateUrlPchar = regexSupplant('(?:' +
+@@ -478,7 +488,7 @@ var window = {};
+ attrs.href = options.hashtagUrlBase + hashtag;
+ attrs.title = "#" + hashtag;
+ attrs["class"] = options.hashtagClass;
+- if (hashtag[0].match(twttr.txt.regexen.rtl_chars)){
++ if (hashtag.charAt(0).match(twttr.txt.regexen.rtl_chars)){
+ attrs["class"] += " rtl";
+ }
+ if (options.targetBlank) {
+@@ -683,22 +693,34 @@ var window = {};
+ };
+
+ twttr.txt.autoLinkWithJSON = function(text, json, options) {
++ // map JSON entity to twitter-text entity
++ if (json.user_mentions) {
++ for (var i = 0; i < json.user_mentions.length; i++) {
++ // this is a @mention
++ json.user_mentions[i].screenName = json.user_mentions[i].screen_name;
++ }
++ }
++
++ if (json.hashtags) {
++ for (var i = 0; i < json.hashtags.length; i++) {
++ // this is a #hashtag
++ json.hashtags[i].hashtag = json.hashtags[i].text;
++ }
++ }
++
++ if (json.symbols) {
++ for (var i = 0; i < json.symbols.length; i++) {
++ // this is a $CASH tag
++ json.symbols[i].cashtag = json.symbols[i].text;
++ }
++ }
++
+ // concatenate all entities
+ var entities = [];
+ for (var key in json) {
+ entities = entities.concat(json[key]);
+ }
+- // map JSON entity to twitter-text entity
+- for (var i = 0; i < entities.length; i++) {
+- entity = entities[i];
+- if (entity.screen_name) {
+- // this is @mention
+- entity.screenName = entity.screen_name;
+- } else if (entity.text) {
+- // this is #hashtag
+- entity.hashtag = entity.text;
+- }
+- }
++
+ // modify indices to UTF-16
+ twttr.txt.modifyIndicesFromUnicodeToUTF16(text, entities);
+
+@@ -861,7 +883,6 @@ var window = {};
+ if (!options) {
+ options = {extractUrlsWithoutProtocol: true};
+ }
+-
+ if (!text || (options.extractUrlsWithoutProtocol ? !text.match(/\./) : !text.match(/:/))) {
+ return [];
+ }
+@@ -881,7 +902,6 @@ var window = {};
+ continue;
+ }
+ var lastUrl = null,
+- lastUrlInvalidMatch = false,
+ asciiEndPosition = 0;
+ domain.replace(twttr.txt.regexen.validAsciiDomain, function(asciiDomain) {
+ var asciiStartPosition = domain.indexOf(asciiDomain, asciiEndPosition);
+@@ -890,8 +910,9 @@ var window = {};
+ url: asciiDomain,
+ indices: [startPosition + asciiStartPosition, startPosition + asciiEndPosition]
+ };
+- lastUrlInvalidMatch = asciiDomain.match(twttr.txt.regexen.invalidShortDomain);
+- if (!lastUrlInvalidMatch) {
++ if (path
++ || asciiDomain.match(twttr.txt.regexen.validSpecialShortDomain)
++ || !asciiDomain.match(twttr.txt.regexen.invalidShortDomain)) {
+ urls.push(lastUrl);
+ }
+ });
+@@ -903,9 +924,6 @@ var window = {};
+
+ // lastUrl only contains domain. Need to add path and query if they exist.
+ if (path) {
+- if (lastUrlInvalidMatch) {
+- urls.push(lastUrl);
+- }
+ lastUrl.url = url.replace(domain, lastUrl.url);
+ lastUrl.indices[1] = endPosition;
+ }
+@@ -1199,7 +1217,7 @@ var window = {};
+ options = {
+ // These come from https://api.twitter.com/1/help/configuration.json
+ // described by https://dev.twitter.com/docs/api/1/get/help/configuration
+- short_url_length: 22,
++ short_url_length: 23,
+ short_url_length_https: 23
+ };
+ }
+@@ -1208,11 +1226,11 @@ var window = {};
+ twttr.txt.modifyIndicesFromUTF16ToUnicode(text, urlsWithIndices);
+
+ for (var i = 0; i < urlsWithIndices.length; i++) {
+- // Subtract the length of the original URL
++ // Subtract the length of the original URL
+ textLength += urlsWithIndices[i].indices[0] - urlsWithIndices[i].indices[1];
+
+ // Add 23 characters for URL starting with https://
+- // Otherwise add 22 characters
++ // http:// URLs still use https://t.co so they are 23 characters as well
+ if (urlsWithIndices[i].url.toLowerCase().match(twttr.txt.regexen.urlHasHttps)) {
+ textLength += options.short_url_length_https;
+ } else {
+@@ -1242,12 +1260,19 @@ var window = {};
+ return "too_long";
+ }
+
++ if (twttr.txt.hasInvalidCharacters(text)) {
++ return "invalid_characters";
++ }
++
++ return false;
++ };
++
++ twttr.txt.hasInvalidCharacters = function(text) {
+ for (var i = 0; i < INVALID_CHARACTERS.length; i++) {
+ if (text.indexOf(INVALID_CHARACTERS[i]) >= 0) {
+- return "invalid_characters";
++ return true;
+ }
+ }
+-
+ return false;
+ };
+
+@@ -1339,6 +1364,10 @@ var window = {};
+ module.exports = twttr.txt;
+ }
+
++ if (typeof define == 'function' && define.amd) {
++ define([], twttr.txt);
++ }
++
+ if (typeof window != 'undefined') {
+ if (window.twttr) {
+ for (var prop in twttr) {
+diff --git a/chat/protocols/twitter/twitter.js b/chat/protocols/twitter/twitter.js
+index fac9c56..af5e4d5 100644
+--- a/chat/protocols/twitter/twitter.js
++++ b/chat/protocols/twitter/twitter.js
+@@ -36,8 +36,11 @@ ChatBuddy.prototype = {
+ set buddyIconFilename(aName) {
+ // Prevent accidental removal of the getter.
+ throw("Don't set chatBuddy.buddyIconFilename directly for Twitter.");
++ },
++ createConversation: function() {
++ return this._account.createConversation(this._name);
+ }
+-}
++};
+
+ function Tweet(aTweet, aWho, aMessage, aObject)
+ {
+@@ -51,7 +54,12 @@ Tweet.prototype = {
+ let account = this.conversation._account;
+ let actions = [];
+
+- if (account.connected) {
++ if (!this.conversation.isChat) {
++ if (aCount)
++ aCount.value = actions.length;
++ return actions;
++ }
++ else if (account.connected) {
+ actions.push(
+ new Action(_("action.reply"), function() {
+ this.conversation.startReply(this._tweet);
+@@ -123,13 +131,109 @@ Action.prototype = {
+ get run() { return this._action.bind(this._tweet); }
+ };
+
+-function Conversation(aAccount)
++// Properties / methods shared by both DirectMessageConversation and
++// TimelineConversation.
++var GenericTwitterConversation = {
++ getTweetLength: function (aString) {
++ // Use the Twitter library to calculate the length.
++ return twttr.txt.getTweetLength(aString, this._account.config);
++ },
++ systemMessage: function(aMessage, aIsError, aDate) {
++ let flags = {system: true};
++ if (aIsError)
++ flags.error = true;
++ if (aDate)
++ flags.time = aDate;
++ this.writeMessage("twitter.com", aMessage, flags);
++ },
++ onSentCallback: function(aMsg, aData) {
++ // The conversation may have been unitialized in the time it takes for
++ // the async callback to fire. Use `_observers` as a proxy for uninit'd.
++ if (!Array.isArray(this._observers))
++ return;
++
++ let tweet = JSON.parse(aData);
++ // The OTR extension requires that the protocol not modify the message
++ // (see the notes at `imIOutgoingMessage`). That's the contract we made.
++ // Unfortunately, Twitter trims tweets and substitutes links.
++ tweet.text = aMsg;
++ this.displayMessages([tweet]);
++ },
++ prepareForDisplaying: function(aMsg) {
++ let text = aMsg.displayMessage;
++ let tweet = aMsg.wrappedJSObject.prplMessage.wrappedJSObject._tweet;
++
++ // Handle retweets: retweeted_status contains the object for the original
++ // tweet that is being retweeted.
++ // If the retweet prefix ("RT @<username>: ") causes the tweet to be over
++ // 140 characters, ellipses will be added. In this case, we want to get
++ // the FULL text from the original tweet and update the entities to match.
++ // Note: the truncated flag is not always set correctly by twitter, so we
++ // always make use of the original tweet.
++ if ("retweeted_status" in tweet) {
++ let retweet = tweet["retweeted_status"];
++ // We're going to take portions of the retweeted status and replace parts
++ // of the original tweet, the retweeted status prepends the original
++ // status with "RT @<username>: ", we need to keep the prefix.
++ // Note: this doesn't play nice with extensions that may have altered
++ // `text` to this point, but at least OTR doesn't act on `isChat`.
++ let offset = text.indexOf(": ") + 2;
++ text = text.slice(0, offset) + retweet.text;
++ }
++
++ // Pass in the url entities so the t.co links are replaced.
++ aMsg.displayMessage = twttr.txt.autoLink(text, {
++ urlEntities: tweet.entities.urls.map(function(u) {
++ var o = Object.assign(u);
++ // But remove the indices so they apply in the face of modifications.
++ delete o.indices;
++ return o;
++ })
++ });
++
++ GenericConversationPrototype.prepareForDisplaying.apply(this, arguments);
++ },
++ displayTweet: function(aTweet, aUser) {
++ let name = aUser.screen_name;
++
++ let flags = name == this.nick ? {outgoing: true} : {incoming: true};
++ flags.time = Math.round(new Date(aTweet.created_at) / 1000);
++ flags._iconURL = aUser.profile_image_url;
++ if (aTweet.delayed)
++ flags.delayed = true;
++ if (aTweet.entities && aTweet.entities.user_mentions &&
++ Array.isArray(aTweet.entities.user_mentions) &&
++ aTweet.entities.user_mentions.some(mention => mention.screen_name == this.nick))
++ flags.containsNick = true;
++
++ (new Tweet(aTweet, name, aTweet.text, flags)).conversation = this;
++ },
++ _parseError: function(aData) {
++ let error = "";
++ try {
++ let data = JSON.parse(aData);
++ if ("error" in data)
++ error = data.error;
++ else if ("errors" in data)
++ error = data.errors[0].message;
++ if (error)
++ error = "(" + error + ")";
++ } catch(e) {}
++ return error;
++ }
++};
++
++function TimelineConversation(aAccount)
+ {
+ this._init(aAccount);
+ this._ensureParticipantExists(aAccount.name);
+ // We need the screen names for the IDs in _friends, but _userInfo is
+ // indexed by name, so we build an ID -> name map.
+- let names = new Map([userInfo.id_str, name] for ([name, userInfo] of aAccount._userInfo));
++ let entries = [];
++ for (let [name, userInfo] of aAccount._userInfo) {
++ entries.push([userInfo.id_str, name]);
++ }
++ let names = new Map(entries);
+ for (let id_str of aAccount._friends)
+ this._ensureParticipantExists(names.get(id_str));
+
+@@ -140,7 +244,7 @@ function Conversation(aAccount)
+ this.setTopic(userInfo.description, aAccount.name, true);
+ }
+ }
+-Conversation.prototype = {
++TimelineConversation.prototype = {
+ __proto__: GenericConvChatPrototype,
+ unInit: function() {
+ delete this._account._timeline;
+@@ -170,22 +274,18 @@ Conversation.prototype = {
+ _("replyingToStatusText", aTweet.text));
+ },
+ reTweet: function(aTweet) {
+- this._account.reTweet(aTweet, this.onSentCallback,
+- function(aException, aData) {
++ this._account.reTweet(aTweet, null, function(aException, aData) {
+ this.systemMessage(_("error.retweet", this._parseError(aData),
+ aTweet.text), true);
+ }, this);
+ },
+- getTweetLength: function (aString) {
+- // Use the Twitter library to calculate the length.
+- return twttr.txt.getTweetLength(aString, this._account.config);
+- },
+- sendMsg: function (aMsg) {
++ sendMsg: function(aMsg) {
+ if (this.getTweetLength(aMsg) > kMaxMessageLength) {
+ this.systemMessage(_("error.tooLong"), true);
+ throw Cr.NS_ERROR_INVALID_ARG;
+ }
+- this._account.tweet(aMsg, this.inReplyToStatusId, this.onSentCallback,
++ this._account.tweet(aMsg, this.inReplyToStatusId,
++ this.onSentCallback.bind(this, aMsg),
+ function(aException, aData) {
+ let error = this._parseError(aData);
+ this.systemMessage(_("error.general", error, aMsg), true);
+@@ -200,163 +300,30 @@ Conversation.prototype = {
+ }
+ return kMaxMessageLength - this.getTweetLength(aString);
+ },
+- systemMessage: function(aMessage, aIsError, aDate) {
+- let flags = {system: true};
+- if (aIsError)
+- flags.error = true;
+- if (aDate)
+- flags.time = aDate;
+- this.writeMessage("twitter.com", aMessage, flags);
+- },
+- onSentCallback: function(aData) {
+- let tweet = JSON.parse(aData);
+- if (tweet.user.screen_name != this._account.name)
+- throw "Wrong screen_name... Uh?";
+- this._account.displayMessages([tweet]);
+- },
+- _parseError: function(aData) {
+- let error = "";
+- try {
+- let data = JSON.parse(aData);
+- if ("error" in data)
+- error = data.error;
+- else if ("errors" in data)
+- error = data.errors[0].message;
+- if (error)
+- error = "(" + error + ")";
+- } catch(e) {}
+- return error;
+- },
+- parseTweet: function(aTweet) {
+- let text = aTweet.text;
+- let entities = {};
+- // Handle retweets: retweeted_status contains the object for the original
+- // tweet that is being retweeted.
+- // If the retweet prefix ("RT @<username>: ") causes the tweet to be over
+- // 140 characters, ellipses will be added. In this case, we want to get
+- // the FULL text from the original tweet and update the entities to match.
+- // Note: the truncated flag is not always set correctly by twitter, so we
+- // always make use of the original tweet.
+- if ("retweeted_status" in aTweet) {
+- let retweet = aTweet["retweeted_status"];
+- // We're going to take portions of the retweeted status and replace parts
+- // of the original tweet, the retweeted status prepends the original
+- // status with "RT @<username>: ", we need to keep the prefix.
+- let offset = text.indexOf(": ") + 2;
+- text = text.slice(0, offset) + retweet.text;
+-
+- // Keep any entities that refer to the prefix (we can refer directly to
+- // aTweet for these since they are not edited).
+- if ("entities" in aTweet) {
+- for (let type in aTweet.entities) {
+- let filteredEntities =
+- aTweet.entities[type].filter(e => e.indices[0] < offset);
+- if (filteredEntities.length)
+- entities[type] = filteredEntities;
+- }
+- }
++ displayMessages: function(aMessages) {
++ let account = this._account;
++ let lastMsgId = account._lastMsgId;
++ for (let tweet of aMessages) {
++ if (!("user" in tweet) || !("text" in tweet) || !("id_str" in tweet) ||
++ account._knownMessageIds.has(tweet.id_str))
++ continue;
++ let id = tweet.id_str;
++ // Update the last known message.
++ // Compare the length of the ids first, and then the text.
++ // This avoids converting tweet ids into rounded numbers.
++ if (id.length > lastMsgId.length ||
++ (id.length == lastMsgId.length && id > lastMsgId))
++ lastMsgId = id;
++ account._knownMessageIds.add(id);
++ account.setUserInfo(tweet.user);
+
+- // Add the entities from the retweet (a copy of these must be made since
+- // they will be edited and we do not wish to change aTweet).
+- if ("entities" in retweet) {
+- for (let type in retweet.entities) {
+- if (!(type in entities))
+- entities[type] = [];
+-
+- // Append the entities from the original status.
+- entities[type] = entities[type].concat(
+- retweet.entities[type].map(function(aEntity) {
+- let entity = Object.create(aEntity);
+- // Add the offset to the indices to account for the prefix.
+- entity.indices = entity.indices.map(i => i + offset);
+- return entity;
+- })
+- );
+- }
+- }
+- } else {
+- // For non-retweets, we just want to use the entities that are given.
+- if ("entities" in aTweet)
+- entities = aTweet.entities;
++ this._ensureParticipantExists(tweet.user.screen_name);
++ this.displayTweet(tweet, tweet.user);
+ }
+-
+- if (Object.keys(entities).length) {
+- /* entArray is an array of entities ready to be replaced in the tweet,
+- * each entity contains:
+- * - start: the start index of the entity inside the tweet,
+- * - end: the end index of the entity inside the tweet,
+- * - str: the string that should be replaced inside the tweet,
+- * - href: the url (href attribute) of the created link tag,
+- * - [optional] text: the text to display for the link,
+- * The original string (str) will be used if this is not set.
+- * - [optional] title: the title attribute for the link.
+- */
+- let entArray = [];
+- if ("hashtags" in entities && Array.isArray(entities.hashtags)) {
+- entArray = entArray.concat(entities.hashtags.map(h => ({
+- start: h.indices[0],
+- end: h.indices[1],
+- str: "#" + h.text,
+- href: "https://twitter.com/#!/search?q=%23" + h.text})));
+- }
+- if ("urls" in entities && Array.isArray(entities.urls)) {
+- entArray = entArray.concat(entities.urls.map(u => ({
+- start: u.indices[0],
+- end: u.indices[1],
+- str: u.url,
+- text: u.display_url || u.url,
+- href: u.expanded_url || u.url})));
+- }
+- if ("user_mentions" in entities &&
+- Array.isArray(entities.user_mentions)) {
+- entArray = entArray.concat(entities.user_mentions.map(um => ({
+- start: um.indices[0],
+- end: um.indices[1],
+- str: "@" + um.screen_name,
+- text: '@<span class="ib-person">' + um.screen_name + "</span>",
+- title: um.name,
+- href: "https://twitter.com/" + um.screen_name})));
+- }
+- entArray.sort((a, b) => a.start - b.start);
+- let offset = 0;
+- for each (let entity in entArray) {
+- let str = text.substring(offset + entity.start, offset + entity.end);
+- if (str[0] == "\uFF20") // ï¼ - unicode character similar to @
+- str = "@" + str.substring(1);
+- if (str[0] == "\uFF03") // ï¼? - unicode character similar to #
+- str = "#" + str.substring(1);
+- if (str.toLowerCase() != entity.str.toLowerCase())
+- continue;
+-
+- let html = "<a href=\"" + entity.href + "\"";
+- if ("title" in entity)
+- html += " title=\"" + entity.title + "\"";
+- html += ">" + ("text" in entity ? entity.text : entity.str) + "</a>";
+- text = text.slice(0, offset + entity.start) + html +
+- text.slice(offset + entity.end);
+- offset += html.length - (entity.end - entity.start);
+- }
++ if (lastMsgId != account._lastMsgId) {
++ account._lastMsgId = lastMsgId;
++ account.prefs.setCharPref("lastMessageId", account._lastMsgId);
+ }
+-
+- return text;
+- },
+- displayTweet: function(aTweet) {
+- let name = aTweet.user.screen_name;
+- this._ensureParticipantExists(name);
+- let text = this.parseTweet(aTweet);
+-
+- let flags =
+- name == this._account.name ? {outgoing: true} : {incoming: true};
+- flags.time = Math.round(new Date(aTweet.created_at) / 1000);
+- flags._iconURL = aTweet.user.profile_image_url;
+- if (aTweet.delayed)
+- flags.delayed = true;
+- if (aTweet.entities && aTweet.entities.user_mentions &&
+- Array.isArray(aTweet.entities.user_mentions) &&
+- aTweet.entities.user_mentions.some(mention => mention.screen_name == this.nick))
+- flags.containsNick = true;
+-
+- (new Tweet(aTweet, name, text, flags)).conversation = this;
+ },
+ _ensureParticipantExists: function(aNick) {
+ if (this._participants.has(aNick))
+@@ -378,6 +345,41 @@ Conversation.prototype = {
+ this._account.setUserDescription(aTopic);
+ }
+ };
++Object.assign(TimelineConversation.prototype, GenericTwitterConversation);
++
++function DirectMessageConversation(aAccount, aName)
++{
++ this._init(aAccount, aName);
++}
++DirectMessageConversation.prototype = {
++ __proto__: GenericConvIMPrototype,
++ sendMsg: function(aMsg) {
++ this._account.directMessage(aMsg, this.name,
++ this.onSentCallback.bind(this, aMsg),
++ function(aException, aData) {
++ let error = this._parseError(aData);
++ this.systemMessage(_("error.general", error, aMsg), true);
++ }, this);
++ },
++ displayMessages: function(aMessages) {
++ let account = this._account;
++ for (let tweet of aMessages) {
++ if (!("sender" in tweet) || !("recipient" in tweet) ||
++ !("text" in tweet) || !("id_str" in tweet))
++ continue;
++ account.setUserInfo(tweet.sender);
++ account.setUserInfo(tweet.recipient);
++ this.displayTweet(tweet, tweet.sender);
++ }
++ },
++ unInit: function() {
++ this._account.removeConversation(this.name);
++ GenericConvIMPrototype.unInit.call(this);
++ },
++ get nick() { return this._account.name; },
++ set nick(aNick) {}
++}
++Object.assign(DirectMessageConversation.prototype, GenericTwitterConversation);
+
+ function Account(aProtocol, aImAccount)
+ {
+@@ -385,15 +387,12 @@ function Account(aProtocol, aImAccount)
+ this._knownMessageIds = new Set();
+ this._userInfo = new Map();
+ this._friends = new Set();
++ // Contains just `DirectMessageConversation`s
++ this._conversations = new Map();
+ }
+ Account.prototype = {
+ __proto__: GenericAccountPrototype,
+
+- // The correct normalization for twitter would be just toLowerCase().
+- // Unfortunately, for backwards compatibility we retain this normalization,
+- // which can cause edge cases for usernames with underscores.
+- normalize: aString => aString.replace(/[^a-z0-9]/gi, "").toLowerCase(),
+-
+ consumerKey: Services.prefs.getCharPref("chat.twitter.consumerKey"),
+ consumerSecret: Services.prefs.getCharPref("chat.twitter.consumerSecret"),
+ completionURI: "http://oauthcallback.local/",
+@@ -512,7 +511,7 @@ Account.prototype = {
+ hmac.init(hmac.SHA1,
+ keyFactory.keyFromString(Ci.nsIKeyObject.HMAC, signatureKey));
+ // No UTF-8 encoding, special chars are already escaped.
+- let bytes = [b.charCodeAt() for each (b in signatureBase)];
++ let bytes = [...signatureBase].map(b => b.charCodeAt());
+ hmac.update(bytes, bytes.length);
+ let signature = hmac.finish(true);
+
+@@ -555,6 +554,11 @@ Account.prototype = {
+ let url = "1.1/statuses/destroy/" + aTweet.id_str + ".json";
+ this.signAndSend(url, null, [], aOnSent, aOnError, aThis);
+ },
++ directMessage: function(aMsg, aName, aOnSent, aOnError, aThis) {
++ let POSTData = [["text", aMsg], ["screen_name", aName]];
++ this.signAndSend("1.1/direct_messages/new.json", null, POSTData, aOnSent,
++ aOnError, aThis);
++ },
+
+ _friends: null,
+ follow: function(aUserName) {
+@@ -617,29 +621,7 @@ Account.prototype = {
+ }
+ },
+
+- get timeline() { return this._timeline || (this._timeline = new Conversation(this)); },
+- displayMessages: function(aMessages) {
+- let lastMsgId = this._lastMsgId;
+- for each (let tweet in aMessages) {
+- if (!("user" in tweet) || !("text" in tweet) || !("id_str" in tweet) ||
+- this._knownMessageIds.has(tweet.id_str))
+- continue;
+- let id = tweet.id_str;
+- // Update the last known message.
+- // Compare the length of the ids first, and then the text.
+- // This avoids converting tweet ids into rounded numbers.
+- if (id.length > lastMsgId.length ||
+- (id.length == lastMsgId.length && id > lastMsgId))
+- lastMsgId = id;
+- this._knownMessageIds.add(id);
+- this.setUserInfo(tweet.user);
+- this.timeline.displayTweet(tweet);
+- }
+- if (lastMsgId != this._lastMsgId) {
+- this._lastMsgId = lastMsgId;
+- this.prefs.setCharPref("lastMessageId", this._lastMsgId);
+- }
+- },
++ get timeline() { return this._timeline || (this._timeline = new TimelineConversation(this)); },
+
+ onTimelineError: function(aError, aResponseText, aRequest) {
+ this.ERROR(aError);
+@@ -687,7 +669,7 @@ Account.prototype = {
+
+ this._timelineBuffer.sort(this.sortByDate);
+ this._timelineBuffer.forEach(aTweet => aTweet.delayed = true);
+- this.displayMessages(this._timelineBuffer);
++ this.timeline.displayMessages(this._timelineBuffer);
+
+ // Fetch userInfo for the user if we don't already have it.
+ this.requestBuddyInfo(this.name);
+@@ -739,7 +721,7 @@ Account.prototype = {
+ this.DEBUG("Received data: " + newText);
+ let messages = newText.split(/\r\n?/);
+ this._pendingData = messages.pop();
+- for each (let message in messages) {
++ for (let message of messages) {
+ if (!message.trim())
+ continue;
+ let msg;
+@@ -749,13 +731,18 @@ Account.prototype = {
+ this.ERROR(e + " while parsing " + message);
+ continue;
+ }
+- if ("text" in msg)
+- this.displayMessages([msg]);
++ if ("direct_message" in msg) {
++ let dm = msg["direct_message"];
++ if (dm.sender_screen_name !== this.name) // These are displayed on send.
++ this.getConversation(dm.sender_screen_name).displayMessages([dm]);
++ }
++ else if ("text" in msg)
++ this.timeline.displayMessages([msg]);
+ else if ("friends" in msg) {
+ // Filter out the IDs that info has already been received from (e.g. a
+ // tweet has been received as part of the timeline request).
+ let userInfoIds = new Set();
+- for each (let userInfo in this._userInfo)
++ for (let userInfo of this._userInfo.values())
+ userInfoIds.add(userInfo.id_str);
+ let ids = msg.friends.filter(
+ aId => !userInfoIds.has(aId.toString()));
+@@ -951,7 +938,7 @@ Account.prototype = {
+ cleanUp: function() {
+ this.finishAuthorizationRequest();
+ if (this._pendingRequests.length != 0) {
+- for each (let request in this._pendingRequests)
++ for (let request of this._pendingRequests)
+ request.abort();
+ delete this._pendingRequests;
+ }
+@@ -1088,7 +1075,7 @@ Account.prototype = {
+ // create the participant.
+ onLookupReceived: function(aData) {
+ let users = JSON.parse(aData);
+- for each (let user in users) {
++ for (let user of users) {
+ this.setUserInfo(user);
+ this.timeline._ensureParticipantExists(user.screen_name);
+ }
+@@ -1103,6 +1090,19 @@ Account.prototype = {
+ joinChat: function(aComponents) {
+ // The 'timeline' getter opens a timeline conversation if none exists.
+ this.timeline;
++ },
++
++ getConversation: function(aName) {
++ if (!this._conversations.has(aName))
++ this._conversations.set(aName, new DirectMessageConversation(this, aName));
++ return this._conversations.get(aName);
++ },
++ removeConversation: function(aName) {
++ if (this._conversations.has(aName))
++ this._conversations.delete(aName);
++ },
++ createConversation: function(aName) {
++ return this.getConversation(aName);
+ }
+ };
+
+--
+2.10.1
+
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
new file mode 100644
index 0000000..2634d9d
--- /dev/null
+++ b/projects/instantbird/0006-Bug-1218193-Fix-tab-strip-background-colour-on-OS-X..patch
@@ -0,0 +1,26 @@
+From 820516967b23c191fda8c33b74260808838acb7d Mon Sep 17 00:00:00 2001
+From: Nihanth Subramanya <nhnt11@xxxxxxxxx>
+Date: Sun, 9 Oct 2016 21:53:04 -0700
+Subject: [PATCH 06/20] Bug 1218193 - Fix tab strip background colour on OS X.
+ r=aleth
+
+---
+ im/themes/tabbrowser-pinstripe/tabbrowser.css | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/im/themes/tabbrowser-pinstripe/tabbrowser.css b/im/themes/tabbrowser-pinstripe/tabbrowser.css
+index 76c5094..2915450 100644
+--- a/im/themes/tabbrowser-pinstripe/tabbrowser.css
++++ b/im/themes/tabbrowser-pinstripe/tabbrowser.css
+@@ -208,7 +208,7 @@ statusbarpanel#statusbar-display {
+ }
+
+ .tabbrowser-strip {
+- -moz-appearance: -moz-mac-unified-toolbar;
++ -moz-appearance: toolbar;
+ height: 26px;
+ background-repeat: repeat-x;
+ }
+--
+2.10.1
+
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
new file mode 100644
index 0000000..c80e60d
--- /dev/null
+++ b/projects/instantbird/0007-Bug-1246431-XMPP-createConversation-should-handle-in.patch
@@ -0,0 +1,26 @@
+From f05bcdd1b1554e5acf3ce5ac95de62d2f2341361 Mon Sep 17 00:00:00 2001
+From: Arlo Breault <arlolra@xxxxxxxxx>
+Date: Sun, 9 Oct 2016 21:57:07 -0700
+Subject: [PATCH 07/20] Bug 1246431 - XMPP createConversation should handle
+ incoming messages from the server properly. r=aleth
+
+---
+ chat/protocols/xmpp/xmpp.jsm | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/chat/protocols/xmpp/xmpp.jsm b/chat/protocols/xmpp/xmpp.jsm
+index 0022be3..4420a1d 100644
+--- a/chat/protocols/xmpp/xmpp.jsm
++++ b/chat/protocols/xmpp/xmpp.jsm
+@@ -2108,7 +2108,7 @@ var XMPPAccountPrototype = {
+
+ // Checking that the aName can be parsed and is not broken.
+ let jid = this._parseJID(convName);
+- if (!jid || !jid.node || (isMucParticipant && !jid.resource)) {
++ if (!jid || !jid.domain || (isMucParticipant && (!jid.node || !jid.resource))) {
+ this.ERROR("Could not create conversation as jid is broken: " + convName);
+ throw "Invalid JID";
+ }
+--
+2.10.1
+
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
new file mode 100644
index 0000000..ab5aef1
--- /dev/null
+++ b/projects/instantbird/0008-Bug-1298574-Set-_userVCard-own-property-when-downloa.patch
@@ -0,0 +1,39 @@
+From 4fff3e33c39807680dab5961e6577fa128237921 Mon Sep 17 00:00:00 2001
+From: Arlo Breault <arlolra@xxxxxxxxx>
+Date: Sun, 28 Aug 2016 08:57:41 -0700
+Subject: [PATCH 08/20] 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 4420a1d..71f7770 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.10.1
+
diff --git a/projects/instantbird/0009-XMPP-in-band-registration.patch b/projects/instantbird/0009-XMPP-in-band-registration.patch
new file mode 100644
index 0000000..1912917
--- /dev/null
+++ b/projects/instantbird/0009-XMPP-in-band-registration.patch
@@ -0,0 +1,396 @@
+From b773d4ee2dc099c684840cc1aef6984572e3dd8d Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir@xxxxxxxxxxxxxx>
+Date: Mon, 10 Oct 2016 18:42:25 -0700
+Subject: [PATCH 09/20] 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 293ab01..237d20c 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 24618ee..246ec2b 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 ed3b8f0..7c26d0d 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 9eb5352..759f42b 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="®isterXMPP.label;" hidden="true" />
+ </wizardpage>
+
+ <wizardpage id="accountpassword" pageid="accountpassword" next="accountadvanced"
+diff --git a/im/content/jar.mn b/im/content/jar.mn
+index 98d9a09..20ea9dc 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 0000000..52852f0
+--- /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 0000000..e2bd367
+--- /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 43d0f19..c46fb2f 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.10.1
+
diff --git a/projects/instantbird/0010-Remove-search-from-UI.patch b/projects/instantbird/0010-Remove-search-from-UI.patch
new file mode 100644
index 0000000..434ab0f
--- /dev/null
+++ b/projects/instantbird/0010-Remove-search-from-UI.patch
@@ -0,0 +1,64 @@
+From 43116629bf42352a656ae1b77b2774d2898b1905 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir@xxxxxxxxxxxxxx>
+Date: Mon, 10 Oct 2016 18:47:48 -0700
+Subject: [PATCH 10/20] 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 5261b79..f667793 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 fad67c1..cfe2405 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.10.1
+
diff --git a/projects/instantbird/0011-Add-Tor-Messenger-branding.patch b/projects/instantbird/0011-Add-Tor-Messenger-branding.patch
new file mode 100644
index 0000000..1ec97fa
--- /dev/null
+++ b/projects/instantbird/0011-Add-Tor-Messenger-branding.patch
@@ -0,0 +1,5133 @@
+From 321249d5df13876ec3eca14d764e05d11ba5f353 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir@xxxxxxxxxxxxxx>
+Date: Mon, 10 Oct 2016 18:56:27 -0700
+Subject: [PATCH 11/20] 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@xxxxxx | 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 | 79 +++
+ 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, 1694 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@xxxxxx
+ 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 615e4e6..ac61e61 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 0000000..b430956
+--- /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@N?(olHy`uVBq!ia0y~yV4MKNIvh+uk)*3dQyCao>^xl@Ln`LHxx&cHz`$`p
+zA^rckS&yY#68IF7*cF^29NIQC@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 0000000..4683827
+--- /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 0000000..7e58051
+--- /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
+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
+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@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@dBD}#W8&tgXdF1Ldk5?Txj4Q||P0zte9j0}t>Q3<_GKwcXU1IL1kOxYqmKwb)i
+z14FM^1W<ENlOi(%Q^uA9QedMbfkrK6y#_Y;1VaOZl<o$Qp{&kq3@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@c6+QdKX@VenpCEWPhM|5Gf7l1lWK*%i1gliWVGBVPmjhWLYoC
+T<2@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
+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
+QNyY)FD7=-gk+TZ_9|IdT#sB~S
+
+literal 0
+HcmV?d00001
+
+diff --git a/im/branding/messenger/content/about-logo@xxxxxx b/im/branding/messenger/content/about-logo@xxxxxx
+new file mode 100644
+index 0000000000000000000000000000000000000000..99d626ef66ac6183e1c348306d7ba30970db7038
+GIT binary patch
+literal 13886
+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
+
+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
+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
+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
+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
+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 0000000..9a3c04e
+--- /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;
++}
++
++
++@media (min-resolution: 2dppx) {
++ #leftBox {
++ background-image: url("chrome://branding/content/about-logo@xxxxxx");
++ }
++}
++
++#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
+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
+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@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@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@g<@#ET2Vl63-9gR@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@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
+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
+
+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@ByRzp_D4w}G{mRB%jv^L=ltN%f0`}})UTUd0YJGNofB3;9
+z<K@9$`1@+jSxjG#iv?gJ171x~Pwmp>8`mPGTKeha-?iK6+^6m~yoPsgVls`hz6-%v
+z<hNTYYqI6-(5Jtiud6OQIA>eZxT#z(!|xCJX{UD@_lKI3tY5+)Q&}TYMVoq??7CoW
+z3)?TIsbWhfjSJha9)cMNSCgrwEHCO=5vAS4b}=fqHqW;gFJLcQW=c^#-e`7JFH8K6
+z8NkTy2Wzuio5vmxZ8c@!pj*#|t(fvh*U@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@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@84n;AXHdw<!q>7EMC
+zd5(2%v5Tm2PFGCefeSovfd|9DgKdEaI`H6of%9JQ0^leqmGm91Gt;53+*v-O>!9=b
+zLWG<2cx2Wg>kUu#e}hp9A@H*V^xn;MT)zWc;T|L30Spf*gut#M;7!(6Y6~2)+graF
+zJm1;)t^nL()=Aq9tTZkxw25vvuiccx7k1rNcDkyQ11qUvk`Dm}gA_tQ2nYcoAOwVf
+Z5D)@FKnMr{As_^VfDjM@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@DB{ZlJL!e@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@d#lNn)Bs0P3@^=)*`NYV@N+Aa}F@;J}r8!Ii8|fOmX`-VBYkDI*e^5OCQ)=sRVX
+z0Dj~FcD4d|(Koy6A~K?0pk)GlYo*mQ|MCsBdo4ln@5a~eO#nUJ47$5&CP0fbj3i?E
+z5KQR7pTE+AlTmwqL4tP)sa68b9BX3@;Ou?)xT@|&AR<d70sa&#-{*1wiz$FiM)-Lz
+zVp2W<7k@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@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@eEx6y0IvAKHr@rG1-oB|1TxFBr=hsK|XF@tOPKmx6
+zyCJT8b_@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@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@Fp}s_IlI8+QAm3A83wnt0GSV=3dvgV37igUoCqBbwJb;kGFl4k
+zb_r~*OH#jZR>I-z&2U@2Jz`bKd}67)L!jP{*_;klz}%cvug=I=*hoaq<j;biw)vle
+z`9*06PQBsbF^(IaQ2jLWOz@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
+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
+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@sgLa0bcSZIj_3si)Kpc3rR
+zArkQuwP+I}Oc#EN@TR)aK}vsUDASgxYF+2NzW4fO`rf=ZukA@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@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@5m6ifS)*T#2Q+aSf;8GCV=6G2G(BTze(DrpDK)2WKY*<1
+z)&OG0iD-0)2U<Qi$0d@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@R8F^F5M95`#UlUoSlW1YX=4vC?24$6ebXL#%f3=n(@=S+=bxE
+zy$W>3(4NQx+!0@=ve~^CA;|CRQUVZpH%M&#{pgJYz*i*lLOBi3*lofk#aYcc@P%S(
+zB|m$+@V?FRebQ`oE3UG8gm4mZN!f*<fxNT#f@L=?esF3aJdBFT6Qu+K$v|)hb3LEG
+zyBCuuPD|>6Boa&dG9nOVcHwwQ<it$pQp(8#mE){d$rF4@U9LW@Oogd+Q*e-8Cycj!
+z88O!wi6iLfajJTQd7{)VH@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-@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@ma
+z74?v-P;@I)BUOo1TZ@fG6QhBe#!?B2GQPLYG}(27;Dg7^+su64&xt04fRoIwdwjG6
+zq?zmuUM5jSG&_VY_tP>!s@u+<l8&<yFz*PFo};8~>c?~%sHp*}s&2vh2^6(JB*0+r
+zu^2GFAdo&R-eQQ}47}{rOsJF|1yYc3p@6=zae>zz@5-f))hz?h+85#X|BtAFQ*#lZ
+zfs8)8cPF{H0LCT+$RW!ESvz>tW;u3q@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@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
+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
+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@GL!E+@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@3mmYb<qnyKV;0d<1@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@c8Pws4A|32mcISZu`8%@$N@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@k4q6oRElnS?LpHS@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@cAKQ?*QN@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@1Ow~y4L5e33jR@50269(2$xR~*hOEkc
+z9*evh6G}J90wJ~H?goZ|bjCorBD-$~cb;<y?@XpK-m*a4o-`k3>r_CoMB_b`kFEWX
+zj@o4N>PldbuR@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@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@wuKR9fU=lgpAVZ1LI0oV*5z2?dTC^`X9jIk{#vj>9cMA2ZXlZV!d7yz-dF39d2
+z9MVh`B~i%O&?3NA*q&i77eGZNR-^M+l?tryB>+rb#43|2e)u@fTNxkS0hpTxn4h+9
+zd@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@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@YEA#Lv7R${X=
+zhYjiDkB<O|9W_>HxS&D&@iWcQoS@d3h8c!7#xUcTO=JPPyKJxD0E}XryBW@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@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
+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
+G;Qs)bIk@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@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@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@w`DdKbX8eGHgKzIQ*Zk2%0|
+z0At#H{yedzUGLgswGY$sUBLcc%kxfApMO*i6;RhZ57?d>veqNB&z#C3a@WC~^;MI*
+zE~CB#P@BCi=R?+<&VxJ7j2UNU@=Dem&AHp+e#OaOkA?X@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@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 0000000..929e7c9
+--- /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@xxxxxx (content/about-logo@xxxxxx)
++ 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 0000000..4dc69f2
+--- /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 0000000..c09000f
+--- /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 0000000..4fb707f
+--- /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/.
++
++
++@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 0000000..e59008d
+--- /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 0000000..bd8ad85
+--- /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
+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
+zsFAIoKE+IaX�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
+zaeT;0mjRz~Lbv0%0A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
+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 0000000..3434739
+--- /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 0000000..76e799c
+--- /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.@.@.u UXUXUXUX",
++"1X=X].'.=X`.x.$.@.@.- O X UXUXUX",
++",X=X*XY.=Xq.5.l.#.@.@.z o X 4 4 + UXUXUX",
++",X=X=XU.].#.@.l.l.#.@.@.@.z - o 1 4 + . 4 4 4 X . UXUX",
++"aX=X=X{.I.#.@.$.x.l.$.@.@.@.@.@.@.x u - o . < 4 4 4 4 4 4 X . o > > p N N N j s % UX",
++"jX=X=X=Xb.5.@.@.$.z.c.5.@.@.@.@.@.@.@.@.@.@.@.@.+. .x c ;.:.:.>.,.0.y % ) 9XbXFXSXVXvXzX$Xg L 9 ",
++"UX=X=X=X2.c.$.@.@.#.7.c.z.<.@.@.@.@.@.@.@.@.@.@.@.@.@.#.9.9.9.9.9.9.n N N P.GXDXVXMXzX+Xs K.|.e ",
++"UX1X=X=X#.7.x.$.@.@.@.$.l.c.z.2.$.@.@.@.@.@.@.@.@.@.@.@.%.9.9.9.9.9.-.V IXS.N rXNXxX.Xs T.>XXX8 ",
++"UXUX=X*X$.@.l.x.$.@.@.@.@.<...k c.6.<.@.@.@.@.@.@.@.@.@.@.$.8.9.9.9.9.p LXGXrXS T L.g !.<X<X$X7 ",
++"UXUX,X`.$.@.$.x.x.<.@.@.@.l w * c c.c.c.6.2.$.@.@.@.@.@.@.$.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@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
+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
+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@9s6zq<(U1;VL4qH<
+zU{FDfilP#P@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@-@_&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@i@<b-Aa
+zgU1i6wUg_?!g1QC_anbHZc}o2r;<<Kwbwr{ttt8H!}^Tjz01nmS`NU@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@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@UiJliY2P<`
+z%ZFDsn(%KK+^z<Xk}r797+>_l0cWdYZ@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@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@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@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@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@w`DdKbX8eGHgKzIQ*Zk2%0|
+z0At#H{yedzUGLgswGY$sUBLcc%kxfApMO*i6;RhZ57?d>veqNB&z#C3a@WC~^;MI*
+zE~CB#P@BCi=R?+<&VxJ7j2UNU@=Dem&AHp+e#OaOkA?X@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@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
+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
+
+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
+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%0D=?=i`tXyrr#>2arOL_A
+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
+S4u@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
+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
+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 0000000..f223f06
+--- /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 2507060..a065c8e 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 0000000..b3ae0de
+--- /dev/null
++++ b/im/content/aboutDialog.js
+@@ -0,0 +1,79 @@
++/* 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 Nightly)";
++ }
++#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 aa3b80e..ba924b9 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">©rightText2;</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 0000000..e4315b0
+--- /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 20ea9dc..b3d9e49 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 ecd8d9d..187cf5c 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 15ec569..4a2d35d 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.10.1
+
diff --git a/projects/instantbird/0012-Account-picture.patch b/projects/instantbird/0012-Account-picture.patch
new file mode 100644
index 0000000..1ba2aa3
--- /dev/null
+++ b/projects/instantbird/0012-Account-picture.patch
@@ -0,0 +1,26 @@
+From 378d544200db0ef0c4800117826a988f54f88c88 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir@xxxxxxxxxxxxxx>
+Date: Mon, 10 Oct 2016 19:24:09 -0700
+Subject: [PATCH 12/20] 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 b90fdda..f29a48b 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.10.1
+
diff --git a/projects/instantbird/0013-Modify-protocol-defaults.patch b/projects/instantbird/0013-Modify-protocol-defaults.patch
new file mode 100644
index 0000000..9f4870e
--- /dev/null
+++ b/projects/instantbird/0013-Modify-protocol-defaults.patch
@@ -0,0 +1,48 @@
+From db0abd7e21663ed4cf92495bf7502b02c882c007 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir@xxxxxxxxxxxxxx>
+Date: Mon, 10 Oct 2016 19:25:34 -0700
+Subject: [PATCH 13/20] 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 759f42b..a306906 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 d552a23..7d371bd 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.10.1
+
diff --git a/projects/instantbird/0014-Modify-IRC-defaults.patch b/projects/instantbird/0014-Modify-IRC-defaults.patch
new file mode 100644
index 0000000..5d010db
--- /dev/null
+++ b/projects/instantbird/0014-Modify-IRC-defaults.patch
@@ -0,0 +1,65 @@
+From f5c55c3d901d8d2174da47078d85622ca6885f9c Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir@xxxxxxxxxxxxxx>
+Date: Mon, 10 Oct 2016 19:31:58 -0700
+Subject: [PATCH 14/20] 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 35165e9..c2167a5 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 28eb374..120be10 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.10.1
+
diff --git a/projects/instantbird/0015-Modify-themes.patch b/projects/instantbird/0015-Modify-themes.patch
new file mode 100644
index 0000000..451eb9d
--- /dev/null
+++ b/projects/instantbird/0015-Modify-themes.patch
@@ -0,0 +1,78 @@
+From 278bce580b808cc6881a3ba5cacee69b8ecb7a13 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir@xxxxxxxxxxxxxx>
+Date: Mon, 10 Oct 2016 19:36:38 -0700
+Subject: [PATCH 15/20] 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 a7e38bb..c5c781a 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 5c5d594..4a9d6af 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 454e366..18ba1f9 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.10.1
+
diff --git a/projects/instantbird/0016-Modify-XMPP-defaults.patch b/projects/instantbird/0016-Modify-XMPP-defaults.patch
new file mode 100644
index 0000000..ac58b3a
--- /dev/null
+++ b/projects/instantbird/0016-Modify-XMPP-defaults.patch
@@ -0,0 +1,48 @@
+From 4199685bb157c9248701353d1da77d43b507f45c Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir@xxxxxxxxxxxxxx>
+Date: Mon, 10 Oct 2016 19:38:49 -0700
+Subject: [PATCH 16/20] 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 8bce0c9..642f456 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 265445a..a5635ca 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.10.1
+
diff --git a/projects/instantbird/0017-Remove-logging-UI.patch b/projects/instantbird/0017-Remove-logging-UI.patch
new file mode 100644
index 0000000..a217b9b
--- /dev/null
+++ b/projects/instantbird/0017-Remove-logging-UI.patch
@@ -0,0 +1,43 @@
+From e2f35f7b0b8eba6fcfeee629e6bc37f50c9ee153 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir@xxxxxxxxxxxxxx>
+Date: Mon, 10 Oct 2016 19:50:48 -0700
+Subject: [PATCH 17/20] 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 7c9db1c..2d7b270 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.10.1
+
diff --git a/projects/instantbird/0018-Cert-override.patch b/projects/instantbird/0018-Cert-override.patch
new file mode 100644
index 0000000..e995a9d
--- /dev/null
+++ b/projects/instantbird/0018-Cert-override.patch
@@ -0,0 +1,64 @@
+From d97d6ee26187ae8c682a5b25a8772741fae19be2 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir@xxxxxxxxxxxxxx>
+Date: Mon, 10 Oct 2016 19:56:46 -0700
+Subject: [PATCH 18/20] 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 0000000..4e616f6
+--- /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 46bc16b..b7d4ebd 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 25dd676..5f06e78 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 1174b3d..3e35a2e 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
++@RESPATH@/defaults/profile/cert_override.txt
+
+ #ifdef XP_MACOSX
+ @RESPATH@/components/ibDockBadge.js
+--
+2.10.1
+
diff --git a/projects/instantbird/0019-Display-all-traffic-over-Tor.patch b/projects/instantbird/0019-Display-all-traffic-over-Tor.patch
new file mode 100644
index 0000000..ef68228
--- /dev/null
+++ b/projects/instantbird/0019-Display-all-traffic-over-Tor.patch
@@ -0,0 +1,38 @@
+From 21ee6198dcd40ce7af5e0baa44c0740114dcfaf4 Mon Sep 17 00:00:00 2001
+From: Sukhbir Singh <sukhbir@xxxxxxxxxxxxxx>
+Date: Mon, 10 Oct 2016 19:58:31 -0700
+Subject: [PATCH 19/20] 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 a306906..3c3a417 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 c46fb2f..6b49c84 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.10.1
+
diff --git a/projects/instantbird/0020-Trac-17480-Content-sink.patch b/projects/instantbird/0020-Trac-17480-Content-sink.patch
new file mode 100644
index 0000000..8279ed5
--- /dev/null
+++ b/projects/instantbird/0020-Trac-17480-Content-sink.patch
@@ -0,0 +1,101 @@
+From fe0c48901086991eb1ba35b1ee391284547cb4dd Mon Sep 17 00:00:00 2001
+From: Arlo Breault <arlolra@xxxxxxxxx>
+Date: Wed, 5 Oct 2016 11:09:25 -0700
+Subject: [PATCH 20/20] Trac 17480: Content sink
+
+---
+ chat/modules/imContentSink.jsm | 30 +++++-------------------------
+ im/content/preferences/content.xul | 2 +-
+ 2 files changed, 6 insertions(+), 26 deletions(-)
+
+diff --git a/chat/modules/imContentSink.jsm b/chat/modules/imContentSink.jsm
+index ee067af..534f1ef 100644
+--- a/chat/modules/imContentSink.jsm
++++ b/chat/modules/imContentSink.jsm
+@@ -59,10 +59,6 @@ var kStrictMode = {
+ attrs: { },
+
+ tags: {
+- 'a': {
+- 'title': true,
+- 'href': kAllowedURLs
+- },
+ 'br': true,
+ 'p': true
+ },
+@@ -72,12 +68,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
+@@ -87,24 +80,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
+@@ -158,7 +138,7 @@ var kPermissiveMode = {
+ };
+
+ var kModePref = "messenger.options.filterMode";
+-var kModes = [kStrictMode, kStandardMode, kPermissiveMode];
++var kModes = [kStrictMode, kStandardMode];
+
+ var gGlobalRuleset = null;
+
+@@ -184,8 +164,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 3b8ccfa..ba41da7 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.10.1
+
diff --git a/projects/instantbird/about-logo.png b/projects/instantbird/about-logo.png
deleted file mode 100644
index c6e4c49..0000000
Binary files a/projects/instantbird/about-logo.png and /dev/null differ
diff --git a/projects/instantbird/about-logo@xxxxxx b/projects/instantbird/about-logo@xxxxxx
deleted file mode 100644
index 99d626e..0000000
Binary files a/projects/instantbird/about-logo@xxxxxx and /dev/null differ
diff --git a/projects/instantbird/about-wordmark.png b/projects/instantbird/about-wordmark.png
deleted file mode 100644
index 52923b6..0000000
Binary files a/projects/instantbird/about-wordmark.png and /dev/null differ
diff --git a/projects/instantbird/aboutDialog-appUpdater.js b/projects/instantbird/aboutDialog-appUpdater.js
deleted file mode 100644
index f223f06..0000000
--- a/projects/instantbird/aboutDialog-appUpdater.js
+++ /dev/null
@@ -1,576 +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/. */
-
-// 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/projects/instantbird/aboutDialog-jar.patch b/projects/instantbird/aboutDialog-jar.patch
deleted file mode 100644
index 96a1498..0000000
--- a/projects/instantbird/aboutDialog-jar.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-diff --git a/im/content/jar.mn b/im/content/jar.mn
---- a/im/content/jar.mn
-+++ b/im/content/jar.mn
-@@ -9,8 +9,9 @@
- % overlay chrome://mozapps/content/update/updates.xul chrome://instantbird/content/softwareUpdateOverlay.xul
- #endif
- content/instantbird/aboutDialog.css
--* content/instantbird/aboutDialog.xul
-- content/instantbird/aboutPanel.xml
-+* content/instantbird/aboutDialog.xul
-+* content/instantbird/aboutDialog.js
-+* content/instantbird/aboutDialog-appUpdater.js
- content/instantbird/account.js
- content/instantbird/accounts.css
- content/instantbird/accounts.js
diff --git a/projects/instantbird/aboutDialog.css b/projects/instantbird/aboutDialog.css
deleted file mode 100644
index a065c8e..0000000
--- a/projects/instantbird/aboutDialog.css
+++ /dev/null
@@ -1,91 +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/. */
-
-#aboutDialog {
- width: 620px;
-}
-
-#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;
-}
-
-#rightBox:-moz-locale-dir(rtl) {
- background-position: 100% 0;
-}
-
-#bottomBox > hbox:not(#newBottom) {
- display: none;
-}
-
-#version {
- font-weight: bold;
- margin-top: 10px;
- -moz-margin-start: 0;
- -moz-user-select: text;
- -moz-user-focus: normal;
- cursor: text;
-}
-
-#version:-moz-locale-dir(rtl) {
- direction: ltr;
- text-align: right;
- margin-right: 0;
-}
-
-#distribution,
-#distributionId {
- display: none;
- margin-top: 0;
- margin-bottom: 0;
-}
-
-.text-blurb {
- margin-bottom: 10px;
- -moz-margin-start: 0;
- -moz-padding-start: 0;
-}
-
-#updateButton,
-#updateDeck > hbox > label {
- -moz-margin-start: 0;
- -moz-padding-start: 0;
-}
-
-.update-throbber {
- width: 16px;
- min-height: 16px;
- -moz-margin-end: 3px;
- list-style-image: url("chrome://global/skin/icons/loading_16.png");
-}
-
-.text-link,
-.text-link:focus {
- margin: 0px;
- padding: 0px;
-}
-
-.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/projects/instantbird/aboutDialog.dtd b/projects/instantbird/aboutDialog.dtd
deleted file mode 100644
index 187cf5c..0000000
--- a/projects/instantbird/aboutDialog.dtd
+++ /dev/null
@@ -1,129 +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/. -->
-<!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/projects/instantbird/aboutDialog.js b/projects/instantbird/aboutDialog.js
deleted file mode 100644
index b3ae0de..0000000
--- a/projects/instantbird/aboutDialog.js
+++ /dev/null
@@ -1,79 +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/. */
-
-// 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 Nightly)";
- }
-#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/projects/instantbird/aboutDialog.xul b/projects/instantbird/aboutDialog.xul
deleted file mode 100644
index ba924b9..0000000
--- a/projects/instantbird/aboutDialog.xul
+++ /dev/null
@@ -1,173 +0,0 @@
-<?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"?>
-<?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;
-]>
-
-#ifdef XP_MACOSX
-<?xul-overlay href="chrome://instantbird/content/macBrowserOverlay.xul"?>
-#endif
-
-<window xmlns:html="http://www.w3.org/1999/xhtml"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- id="aboutDialog"
- windowtype="Browser:About"
- onload="init(event);"
-#ifdef MOZ_UPDATER
- onunload="onUnload(event);"
-#endif
-#ifdef XP_MACOSX
- inwindowmenu="false"
-#else
- title="&aboutDialog.title;"
-#endif
- role="dialog"
- aria-describedby="version distribution distributionId communityDesc contributeDesc trademark"
- >
-
- <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>
- </vbox>
- </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>
-
-#ifdef XP_MACOSX
-#include browserMountPoints.inc
-#endif
-</window>
diff --git a/projects/instantbird/account-picture.patch b/projects/instantbird/account-picture.patch
deleted file mode 100644
index 77274d1..0000000
--- a/projects/instantbird/account-picture.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/im/content/blist.xul b/im/content/blist.xul
---- 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"
diff --git a/projects/instantbird/branding-aboutDialog.css b/projects/instantbird/branding-aboutDialog.css
deleted file mode 100644
index 9a3c04e..0000000
--- a/projects/instantbird/branding-aboutDialog.css
+++ /dev/null
@@ -1,48 +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/. */
-
-#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;
-}
-
-
-@media (min-resolution: 2dppx) {
- #leftBox {
- background-image: url("chrome://branding/content/about-logo@xxxxxx");
- }
-}
-
-#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/projects/instantbird/branding/about.png b/projects/instantbird/branding/about.png
deleted file mode 100644
index 5d7f579..0000000
Binary files a/projects/instantbird/branding/about.png and /dev/null differ
diff --git a/projects/instantbird/branding/blistWindow.ico b/projects/instantbird/branding/blistWindow.ico
deleted file mode 100644
index 83dfe44..0000000
Binary files a/projects/instantbird/branding/blistWindow.ico and /dev/null differ
diff --git a/projects/instantbird/branding/blistWindow.png b/projects/instantbird/branding/blistWindow.png
deleted file mode 100644
index 093a44c..0000000
Binary files a/projects/instantbird/branding/blistWindow.png and /dev/null differ
diff --git a/projects/instantbird/branding/blistWindow16.png b/projects/instantbird/branding/blistWindow16.png
deleted file mode 100644
index fe88908..0000000
Binary files a/projects/instantbird/branding/blistWindow16.png and /dev/null differ
diff --git a/projects/instantbird/branding/blistWindow48.png b/projects/instantbird/branding/blistWindow48.png
deleted file mode 100644
index 3a14f1d..0000000
Binary files a/projects/instantbird/branding/blistWindow48.png and /dev/null differ
diff --git a/projects/instantbird/branding/convWindow.ico b/projects/instantbird/branding/convWindow.ico
deleted file mode 100644
index a22977c..0000000
Binary files a/projects/instantbird/branding/convWindow.ico and /dev/null differ
diff --git a/projects/instantbird/branding/convWindow.png b/projects/instantbird/branding/convWindow.png
deleted file mode 100644
index b550c92..0000000
Binary files a/projects/instantbird/branding/convWindow.png and /dev/null differ
diff --git a/projects/instantbird/branding/convWindow16.png b/projects/instantbird/branding/convWindow16.png
deleted file mode 100644
index b006855..0000000
Binary files a/projects/instantbird/branding/convWindow16.png and /dev/null differ
diff --git a/projects/instantbird/branding/convWindow48.png b/projects/instantbird/branding/convWindow48.png
deleted file mode 100644
index c759149..0000000
Binary files a/projects/instantbird/branding/convWindow48.png and /dev/null differ
diff --git a/projects/instantbird/branding/default.ico b/projects/instantbird/branding/default.ico
deleted file mode 100644
index 51fed13..0000000
Binary files a/projects/instantbird/branding/default.ico and /dev/null differ
diff --git a/projects/instantbird/branding/default.png b/projects/instantbird/branding/default.png
deleted file mode 100644
index fae92d0..0000000
Binary files a/projects/instantbird/branding/default.png and /dev/null differ
diff --git a/projects/instantbird/branding/default16.png b/projects/instantbird/branding/default16.png
deleted file mode 100644
index b436a77..0000000
Binary files a/projects/instantbird/branding/default16.png and /dev/null differ
diff --git a/projects/instantbird/branding/default48.png b/projects/instantbird/branding/default48.png
deleted file mode 100644
index 8381428..0000000
Binary files a/projects/instantbird/branding/default48.png and /dev/null differ
diff --git a/projects/instantbird/branding/instantbird.icns b/projects/instantbird/branding/instantbird.icns
deleted file mode 100644
index 0843171..0000000
Binary files a/projects/instantbird/branding/instantbird.icns and /dev/null differ
diff --git a/projects/instantbird/branding/instantbird.ico b/projects/instantbird/branding/instantbird.ico
deleted file mode 100644
index 51fed13..0000000
Binary files a/projects/instantbird/branding/instantbird.ico and /dev/null differ
diff --git a/projects/instantbird/branding/jar.patch b/projects/instantbird/branding/jar.patch
deleted file mode 100644
index a9648c7..0000000
--- a/projects/instantbird/branding/jar.patch
+++ /dev/null
@@ -1,11 +0,0 @@
-diff --git a/im/branding/messenger/jar.mn b/im/branding/messenger/jar.mn
---- a/im/branding/messenger/jar.mn
-+++ b/im/branding/messenger/jar.mn
-@@ -8,3 +8,7 @@
- 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@xxxxxx (content/about-logo@xxxxxx)
-+ content/branding/about-wordmark.png (content/about-wordmark.png)
diff --git a/projects/instantbird/branding/name.patch b/projects/instantbird/branding/name.patch
deleted file mode 100644
index 57d3d94..0000000
--- a/projects/instantbird/branding/name.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-diff --git a/im/branding/messenger/branding.nsi b/im/branding/messenger/branding.nsi
-index e5b5348..276722b 100755
---- a/im/branding/messenger/branding.nsi
-+++ b/im/branding/messenger/branding.nsi
-@@ -6,8 +6,8 @@
-
- # 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 "Instantbird"
--!define CompanyName "Instantbird"
--!define URLInfoAbout "http://www.instantbird.com/"
--!define URLUpdateInfo "http://www.instantbird.com/"
-+!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/locales/en-US/brand.dtd b/im/branding/messenger/locales/en-US/brand.dtd
-index c569ebb..2d6a5d8 100644
---- a/im/branding/messenger/locales/en-US/brand.dtd
-+++ b/im/branding/messenger/locales/en-US/brand.dtd
-@@ -4,7 +4,7 @@
-
- <!-- nightly branding -->
-
--<!ENTITY brandShortName "Instantbird">
--<!ENTITY brandFullName "Instantbird - Nightly">
-+<!ENTITY brandShortName "Tor Messenger">
-+<!ENTITY brandFullName "Tor Messenger - Beta">
- <!ENTITY brandMotto "'Cause geeks can also do magic!">
--<!ENTITY vendorShortName "Instantbird">
-+<!ENTITY vendorShortName "Tor Project">
-diff --git a/im/branding/messenger/locales/en-US/brand.properties b/im/branding/messenger/locales/en-US/brand.properties
-index f949ced..93528a3 100644
---- a/im/branding/messenger/locales/en-US/brand.properties
-+++ b/im/branding/messenger/locales/en-US/brand.properties
-@@ -2,6 +2,6 @@
- # 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=Instantbird
--brandFullName=Instantbird - Nightly
--vendorShortName=Instantbird
-+brandShortName=Tor Messenger
-+brandFullName=Tor Messenger - Beta
-+vendorShortName=Tor Project
diff --git a/projects/instantbird/branding/osx.patch b/projects/instantbird/branding/osx.patch
deleted file mode 100644
index 196d671..0000000
--- a/projects/instantbird/branding/osx.patch
+++ /dev/null
@@ -1,9 +0,0 @@
-diff --git a/im/branding/messenger/configure.sh b/im/branding/messenger/configure.sh
---- a/im/branding/messenger/configure.sh
-+++ b/im/branding/messenger/configure.sh
-@@ -2,4 +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/.
-
--MOZ_APP_DISPLAYNAME=Instantbird
-+MOZ_APP_DISPLAYNAME="Tor Messenger"
diff --git a/projects/instantbird/browserMountPoints.inc b/projects/instantbird/browserMountPoints.inc
deleted file mode 100644
index e4315b0..0000000
--- a/projects/instantbird/browserMountPoints.inc
+++ /dev/null
@@ -1,12 +0,0 @@
-<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/projects/instantbird/bug-1218193.patch b/projects/instantbird/bug-1218193.patch
deleted file mode 100644
index c540301..0000000
--- a/projects/instantbird/bug-1218193.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-
-# HG changeset patch
-# User Nihanth Subramanya <nhnt11@xxxxxxxxx>
-# Date 1456270075 28800
-# Node ID 07b10276713c5f9cd891ea6e5b944d985c3f2fc2
-# Parent 599fd18da6c144abcc9b7feec4ee30b92e9d7bfc
-Bug 1218193 - Fix tab strip background colour on OS X. r=aleth
-
-diff --git a/im/themes/tabbrowser-pinstripe/tabbrowser.css b/im/themes/tabbrowser-pinstripe/tabbrowser.css
---- a/im/themes/tabbrowser-pinstripe/tabbrowser.css
-+++ b/im/themes/tabbrowser-pinstripe/tabbrowser.css
-@@ -203,17 +203,17 @@ statusbarpanel#statusbar-display {
- }
-
- .tabbrowser-tab:-moz-lwtheme {
- color: inherit;
- text-shadow: inherit;
- }
-
- .tabbrowser-strip {
-- -moz-appearance: -moz-mac-unified-toolbar;
-+ -moz-appearance: toolbar;
- height: 26px;
- background-repeat: repeat-x;
- }
-
- .tabbrowser-strip:not(:-moz-lwtheme) {
- background-color: -moz-mac-chrome-active;
- }
-
-
diff --git a/projects/instantbird/bug-1246431.patch b/projects/instantbird/bug-1246431.patch
deleted file mode 100644
index 649e5c2..0000000
--- a/projects/instantbird/bug-1246431.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-
-# HG changeset patch
-# User Arlo Breault <arlolra@xxxxxxxxx>
-# Date 1454792228 28800
-# Node ID 1759abefc9195a9110c89822fcaf051cd05b0132
-# Parent 27b50a06b9b2b977b31f0777ae8f3ea355cc1130
-Bug 1246431 - XMPP createConversation should handle incoming messages from the server properly. r=aleth
-
-diff --git a/chat/protocols/xmpp/xmpp.jsm b/chat/protocols/xmpp/xmpp.jsm
---- a/chat/protocols/xmpp/xmpp.jsm
-+++ b/chat/protocols/xmpp/xmpp.jsm
-@@ -2096,17 +2096,17 @@ var XMPPAccountPrototype = {
- // Checks if conversation is with a participant of a MUC we are in. We do
- // not want to strip the resource as it is of the form room@domain/nick.
- let isMucParticipant = this._mucs.has(convName);
- if (isMucParticipant)
- convName = this.normalizeFullJid(aName);
-
- // Checking that the aName can be parsed and is not broken.
- let jid = this._parseJID(convName);
-- if (!jid || !jid.node || (isMucParticipant && !jid.resource)) {
-+ if (!jid || !jid.domain || (isMucParticipant && (!jid.node || !jid.resource))) {
- this.ERROR("Could not create conversation as jid is broken: " + convName);
- throw "Invalid JID";
- }
-
- if (!this._conv.has(convName)) {
- this._conv.set(convName,
- new this._conversationConstructor(this, convName,
- isMucParticipant));
-
diff --git a/projects/instantbird/bug-1298574.patch b/projects/instantbird/bug-1298574.patch
deleted file mode 100644
index b0a4ae2..0000000
--- a/projects/instantbird/bug-1298574.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-# HG changeset patch
-# User Arlo Breault <arlolra@xxxxxxxxx>
-# Date 1472399861 25200
-# Sun Aug 28 08:57:41 2016 -0700
-# Branch THUNDERBIRD4530_2016082513_RELBRANCH
-# Node ID 69baf6e1ea1e4c8f4ddf719bff6b542869a99a23
-# Parent f4a50139b69d93674a2fa55b51ab843a66d3fae2
-Bug 1298574 - Set _userVCard own property when downloading vCard fails. r=aleth
- * This prevents an infinite req / res cycle.
-
---HG--
-extra : amend_source : fb94df25b6157ec06dcf8f57b66a484aee243a28
-
-diff --git a/chat/protocols/xmpp/xmpp.jsm b/chat/protocols/xmpp/xmpp.jsm
---- a/chat/protocols/xmpp/xmpp.jsm
-+++ b/chat/protocols/xmpp/xmpp.jsm
-@@ -2231,16 +2231,30 @@ var XMPPAccountPrototype = {
- if (this._userVCard) {
- let binval = this._userVCard.getElement(["PHOTO", "BINVAL"]);
- if (binval && binval.children.length) {
- binval = binval.children[0];
- binval.text = binval.text.replace(/[^A-Za-z0-9\+\/\=]/g, "")
- .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();
- },
-
- _cachingUserIcon: false,
- _cacheUserIcon: function() {
- if (this._cachingUserIcon)
- return;
-
diff --git a/projects/instantbird/build b/projects/instantbird/build
index c67ddc5..9b808bc 100644
--- a/projects/instantbird/build
+++ b/projects/instantbird/build
@@ -1,90 +1,67 @@
#!/bin/sh
set -e
rootdir=$(pwd)
+
export SHELL=/bin/sh
export HOME=$rootdir
export MOZ_BUILD_DATE=$(date -d @[% c('timestamp') %] +%Y%m%d%H%M%S)
export SOURCE_DATE_EPOCH=[% c('timestamp') %]
+
[% IF c('var/osx') -%]
[% pc('gcc', 'var/setup', { compiler_tarfile => c('input_files_by_name/gcchost') }) %]
ln -s /var/tmp/dist/gcc/bin/gcc /var/tmp/dist/gcc/bin/cc
[% END -%]
+
[% pc(c('var/compiler'), 'var/setup', { compiler_tarfile => c('input_files_by_name/' _ c('var/compiler')) }) %]
+
mkdir -p /var/tmp/dist
cd /var/tmp/dist
+
[% IF c("var/linux") -%]
tar xf $rootdir/[% c('input_files_by_name/python') %]
export PATH="/var/tmp/dist/python/bin:$PATH"
tar xf $rootdir/[% c('input_files_by_name/binutils') %]
export PATH="/var/tmp/dist/binutils/bin:$PATH"
[% END -%]
+
# LD_BIND_NOW needed to avoid this error:
# undefined symbol: _ZNSt14error_categoryD2Ev
export LD_BIND_NOW=1
+
[% IF c("var/osname") == "linux-i686" -%]
export LDFLAGS=-m32
export CFLAGS=-m32
export CC='gcc -m32'
[% END -%]
+
[% IF c("var/linux") -%]
mkdir -p /var/tmp/dist/yasm/bin
ln -s /usr/bin/yasm-1 /var/tmp/dist/yasm/bin/yasm
export PATH="/var/tmp/dist/yasm/bin:$PATH"
[% END -%]
+
cd $rootdir
mkdir /var/tmp/build
tar -C /var/tmp/build -xf [% project %]-[% c('version') %].tar.[% c('compress_tar') %]
+
mkdir moz
cd moz
tar xf $rootdir/[% c('input_files_by_name/mozilla') %]
mv mozilla-* /var/tmp/build/[% project %]-[% c('version') %]/mozilla
-cd /var/tmp/build/[% project %]-[% c('version') %]
-mkdir im/branding/messenger
-cp -R im/branding/nightly/* im/branding/messenger/
+cd /var/tmp/build/[% project %]-[% c('version') %]
for patch in $(ls -1 $rootdir/*.patch | sort)
do
- patch -p1 < $patch
-done
-for patch in $(ls -1 $rootdir/branding/*.patch | sort)
-do
- patch -p1 < $patch
+ git apply -p1 < $patch
done
-[% IF c("var/osx") -%]
-cp $rootdir/cert_override.txt im/app/profile
-cp $rootdir/browserMountPoints.inc im/content/
-[% END -%]
-
-cp $rootdir/xmppRegister* im/content/
-
-cp $rootdir/branding/default*.png im/branding/messenger/gtk/
-cp $rootdir/branding/convWindow*.png im/branding/messenger/gtk/
-cp $rootdir/branding/blistWindow*.png im/branding/messenger/gtk/
-
-cp $rootdir/branding/blistWindow.ico im/branding/messenger/windows/
-cp $rootdir/branding/convWindow.ico im/branding/messenger/windows/
-cp $rootdir/branding/default.ico im/branding/messenger/windows/
-
-cp $rootdir/branding/instantbird.ico im/branding/messenger/
-cp $rootdir/branding/instantbird.icns im/branding/messenger/
-
-cp $rootdir/about-logo.png im/branding/messenger/content/
-cp $rootdir/about-logo@xxxxxx im/branding/messenger/content/
-cp $rootdir/about-wordmark.png im/branding/messenger/content/
-
-cp $rootdir/branding-aboutDialog.css im/branding/messenger/content/aboutDialog.css
-
-rm im/content/aboutDialog*
-
-cp $rootdir/aboutDialog* im/content/
-cp $rootdir/aboutDialog.dtd im/locales/en-US/chrome/instantbird/aboutDialog.dtd
-
echo '[% c("var/tormessenger_version") %]' > im/config/version.txt
cp $rootdir/[% c('input_files_by_name/mozconfig') %] .mozconfig
echo ac_add_options --with-tor-browser-version='[% c("var/tormessenger_version") %]' >> .mozconfig
-./mozilla/mach build || ./mozilla/mach build
+
+./mozilla/mach build
./mozilla/mach package
+
mv obj-*/dist/instantbird-*.[% c('var/archive_suffix') %] [% dest_dir _ '/' _ c('filename') %]
diff --git a/projects/instantbird/cert-installer.patch b/projects/instantbird/cert-installer.patch
deleted file mode 100644
index b514b9f..0000000
--- a/projects/instantbird/cert-installer.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-diff --git a/im/app/profile/moz.build b/im/app/profile/moz.build
---- a/im/app/profile/moz.build
-+++ b/im/app/profile/moz.build
-@@ -9,6 +9,7 @@
- DEFINES['HAVE_SHELL_SERVICE'] = 1
-
- FINAL_TARGET_FILES.defaults.profile += [
-+ 'cert_override.txt',
- 'localstore.rdf',
- 'mimeTypes.rdf',
- ]
-diff --git a/im/installer/package-manifest.in b/im/installer/package-manifest.in
---- 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
-+@RESPATH@/defaults/profile/cert_override.txt
-
- #ifdef XP_MACOSX
- @RESPATH@/components/ibDockBadge.js
-diff --git a/im/installer/Makefile.in b/im/installer/Makefile.in
---- a/im/installer/Makefile.in
-+++ b/im/installer/Makefile.in
-@@ -109,7 +109,9 @@
- 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/projects/instantbird/cert_override.txt b/projects/instantbird/cert_override.txt
deleted file mode 100644
index 4e616f6..0000000
--- a/projects/instantbird/cert_override.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-# 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/projects/instantbird/config b/projects/instantbird/config
index 58c1f85..03b89ae 100644
--- a/projects/instantbird/config
+++ b/projects/instantbird/config
@@ -17,6 +17,7 @@ var:
- imagemagick
- ccache
- yasm
+ - git-core
targets:
windows-i686:
var:
@@ -57,71 +58,26 @@ targets:
- rsync
- sqlite3
input_files:
- - filename: preferences.patch
- - filename: irc-default-server.patch
- - filename: top-protocols.patch
- - filename: disable-links.patch
- - filename: account-picture.patch
- - filename: show-traffic-tor.patch
- - filename: hide-get-protocols.patch
- - filename: ctcp-time.patch
- - filename: ctcp-ping.patch
- - filename: xmpp-inband-registration.patch
- - filename: xmpp-default-domain.patch
- - filename: xmppRegister.js
- - filename: xmppRegister.xul
- - filename: xmpp-gtalk-resource.patch
- - filename: bug-1298574.patch
- - filename: bug-1246431.patch
- - filename: trac-16489.patch
- - filename: trac-17896.patch
- - filename: trac-17494.patch
- - filename: trac-13312.patch
- - filename: search-context-menu.patch
- - filename: search-preferences-xul.patch
- - filename: log-preferences-xul.patch
- - filename: themes-remove-links.patch
- - filename: theme-extension-update.patch
- - filename: branding/blistWindow.png
- - filename: branding/blistWindow16.png
- - filename: branding/blistWindow48.png
- - filename: branding/convWindow.png
- - filename: branding/convWindow16.png
- - filename: branding/convWindow48.png
- - filename: branding/default.png
- - filename: branding/default16.png
- - filename: branding/default48.png
- - filename: branding/blistWindow.ico
- - filename: branding/convWindow.ico
- - filename: branding/default.ico
- - filename: branding/instantbird.ico
- - filename: branding/name.patch
- - filename: branding/instantbird.icns
- - filename: branding/jar.patch
- - filename: branding/about.png
- - filename: aboutDialog.xul
- - filename: aboutDialog.js
- - filename: aboutDialog-appUpdater.js
- - filename: aboutDialog-jar.patch
- - filename: aboutDialog.css
- - filename: aboutDialog.dtd
- - filename: about-logo.png
- - filename: about-logo@xxxxxx
- - filename: about-wordmark.png
- - filename: branding-aboutDialog.css
- - filename: updater-text.patch
- - filename: trac-20207.patch
- enable: '[% c("var/osx") %]'
- - filename: branding/osx.patch
- enable: '[% c("var/osx") %]'
- - filename: bug-1218193.patch
- enable: '[% c("var/osx") %]'
- - filename: cert-installer.patch
- enable: '[% c("var/osx") %]'
- - filename: cert_override.txt
- enable: '[% c("var/osx") %]'
- - filename: browserMountPoints.inc
- enable: '[% c("var/osx") %]'
+ - filename: 0001-Set-Tor-Messenger-preferences.patch
+ - filename: 0002-Trac-16489-Prevent-account-autologin.patch
+ - filename: 0003-Trac-17896-Support-Special-Characters-input-prompt-o.patch
+ - filename: 0004-Trac-17494-Better-error-reporting-for-failed-outgoin.patch
+ - 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: 'mozconfig-[% c("var/osname") %]'
name: mozconfig
- name: mozilla
diff --git a/projects/instantbird/ctcp-ping.patch b/projects/instantbird/ctcp-ping.patch
deleted file mode 100644
index 9bc452f..0000000
--- a/projects/instantbird/ctcp-ping.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-diff --git a/chat/protocols/irc/ircCTCP.jsm b/chat/protocols/irc/ircCTCP.jsm
---- a/chat/protocols/irc/ircCTCP.jsm
-+++ b/chat/protocols/irc/ircCTCP.jsm
-@@ -167,19 +167,7 @@
- },
-
- // 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.
diff --git a/projects/instantbird/ctcp-time.patch b/projects/instantbird/ctcp-time.patch
deleted file mode 100644
index 4336592..0000000
--- a/projects/instantbird/ctcp-time.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff --git a/chat/protocols/irc/ircCTCP.jsm b/chat/protocols/irc/ircCTCP.jsm
---- a/chat/protocols/irc/ircCTCP.jsm
-+++ b/chat/protocols/irc/ircCTCP.jsm
-@@ -195,7 +195,7 @@
- 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);
diff --git a/projects/instantbird/disable-links.patch b/projects/instantbird/disable-links.patch
deleted file mode 100644
index 1b559e6..0000000
--- a/projects/instantbird/disable-links.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-From f4b2401ec1f431ea9b90ac0c86106714a94cc3bc Mon Sep 17 00:00:00 2001
-From: Arlo Breault <arlolra@xxxxxxxxx>
-Date: Wed, 5 Oct 2016 11:09:25 -0700
-Subject: [PATCH] A patch for trac 17480
-
- * url linkification
----
- chat/modules/imContentSink.jsm | 30 +++++-------------------------
- im/content/preferences/content.xul | 2 +-
- 2 files changed, 6 insertions(+), 26 deletions(-)
-
-diff --git a/chat/modules/imContentSink.jsm b/chat/modules/imContentSink.jsm
-index e03c5bb..895ab88 100644
---- a/chat/modules/imContentSink.jsm
-+++ b/chat/modules/imContentSink.jsm
-@@ -59,10 +59,6 @@ var kStrictMode = {
- attrs: { },
-
- tags: {
-- 'a': {
-- 'title': true,
-- 'href': kAllowedURLs
-- },
- 'br': true,
- 'p': true
- },
-@@ -72,12 +68,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
-@@ -87,24 +80,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
-@@ -158,7 +138,7 @@ var kPermissiveMode = {
- };
-
- var kModePref = "messenger.options.filterMode";
--var kModes = [kStrictMode, kStandardMode, kPermissiveMode];
-+var kModes = [kStrictMode, kStandardMode];
-
- var gGlobalRuleset = null;
-
-@@ -184,8 +164,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 3b8ccfa..ba41da7 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.10.1
-
diff --git a/projects/instantbird/hide-get-protocols.patch b/projects/instantbird/hide-get-protocols.patch
deleted file mode 100644
index 0a06be1..0000000
--- a/projects/instantbird/hide-get-protocols.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff --git a/im/content/accountWizard.xul b/im/content/accountWizard.xul
---- 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/projects/instantbird/irc-default-server.patch b/projects/instantbird/irc-default-server.patch
deleted file mode 100644
index f05a3ff..0000000
--- a/projects/instantbird/irc-default-server.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff --git a/chat/protocols/irc/irc.js b/chat/protocols/irc/irc.js
---- a/chat/protocols/irc/irc.js
-+++ b/chat/protocols/irc/irc.js
-@@ -1931,7 +1931,7 @@
-
- usernameSplits: [
- {get label() { return _("options.server"); }, separator: "@",
-- defaultValue: "chat.freenode.net", reverse: true}
-+ defaultValue: "", reverse: true}
- ],
-
- options: {
diff --git a/projects/instantbird/log-preferences-xul.patch b/projects/instantbird/log-preferences-xul.patch
deleted file mode 100644
index 2c8f6a2..0000000
--- a/projects/instantbird/log-preferences-xul.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-diff --git a/im/content/preferences/privacy.xul b/im/content/preferences/privacy.xul
---- 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;"/>
diff --git a/projects/instantbird/preferences.patch b/projects/instantbird/preferences.patch
deleted file mode 100644
index 2815c79..0000000
--- a/projects/instantbird/preferences.patch
+++ /dev/null
@@ -1,196 +0,0 @@
-diff --git a/im/app/profile/all-instantbird.js b/im/app/profile/all-instantbird.js
---- a/im/app/profile/all-instantbird.js
-+++ b/im/app/profile/all-instantbird.js
-@@ -28,7 +28,7 @@
- // 0 = spellcheck nothing
- // 1 = check multi-line controls [default]
- // 2 = check multi/single line controls
--pref("layout.spellcheckDefault", 1);
-+pref("layout.spellcheckDefault", 0);
-
- pref("messenger.accounts.convertOldPasswords", true);
- pref("messenger.accounts.promptOnDelete", true);
-@@ -66,18 +66,18 @@
-
- // Whether message related sounds should be played at all. If this is enabled
- // then the more specific prefs are checked as well.
--pref("messenger.options.playSounds.message", true);
-+pref("messenger.options.playSounds.message", false);
- // Specifies whether each message event should trigger a sound for incoming
- // and outgoing messages, or when your nickname is mentioned in a chat.
- pref("messenger.options.playSounds.outgoing", true);
- pref("messenger.options.playSounds.incoming", true);
- pref("messenger.options.playSounds.alert", true);
- // Whether contact list related sounds should be played at all. If this is
- // enabled then the more specific prefs are checked as well.
- pref("messenger.options.playSounds.blist", false);
- // Specifies whether sounds should be played on login/logout events.
- pref("messenger.options.playSounds.login", true);
- pref("messenger.options.playSounds.logout", true);
-
- pref("font.default.x-western", "sans-serif");
- pref("font.default.x-unicode", "sans-serif");
-@@ -142,26 +142,28 @@
-
- // Update service URL:
- // You do not need to use all the %VAR% parameters. Use what you need, %PRODUCT%,%VERSION%,%BUILD_ID%,%CHANNEL% for example
--pref("app.update.url", "https://update.instantbird.org/1/%PRODUCT%/%VERSION%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/update.xml");
-+pref("app.update.url", "https://aus2.torproject.org/tormessenger/update_2/%CHANNEL%/%BUILD_TARGET%/%VERSION%/%LOCALE%");
-+
-+#ifdef XP_WIN
-+// For now, disable staged updates on Windows (see #18292).
-+pref("app.update.staging.enabled", false);
-+#endif
-
- // URL user can browse to manually if for some reason all update installation
- // attempts fail.
--pref("app.update.url.manual", "http://www.instantbird.com/download.html");
-+pref("app.update.url.manual", "https://www.torproject.org");
-
- // A default value for the "More information about this update" link
- // supplied in the "An update is available" page of the update wizard.
--pref("app.update.url.details", "http://www.instantbird.com/");
--
--// User-settable override to app.update.url for testing purposes.
--//pref("app.update.url.override", "");
-+pref("app.update.url.details", "https://trac.torproject.org/projects/tor/wiki/doc/TorMessenger");
-
- // Interval: Time between checks for a new version (in seconds)
- // default=1 day
--pref("app.update.interval", 86400);
-+pref("app.update.interval", 43200);
-
- // Interval: Time before prompting the user to download a new version that
- // is available (in seconds) default=1 day
--pref("app.update.nagTimer.download", 86400);
-+pref("app.update.nagTimer.download", 3600);
-
- // Interval: Time before prompting the user to restart to install the latest
- // download (in seconds) default=30 minutes
-@@ -202,7 +204,7 @@
- pref("browser.search.order.2", "chrome://instantbird/locale/region.properties");
-
- // send ping to the server to update
--pref("browser.search.update", true);
-+pref("browser.search.update", false);
-
- // disable logging for the search service update system by default
- pref("browser.search.update.log", false);
-@@ -222,7 +224,7 @@
- pref("extensions.logging.enabled", false);
- pref("general.skins.selectedSkin", "classic/1.0");
-
--pref("extensions.update.enabled", true);
-+pref("extensions.update.enabled", false);
- pref("extensions.update.interval", 86400);
- pref("extensions.update.url", "https://addons.instantbird.org/services/update.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%");
- pref("extensions.update.autoUpdateDefault", true);
-@@ -245,9 +247,9 @@
- pref("extensions.getMoreProtocolsURL", "https://add-ons.instantbird.org/%LOCALE%/%APP%/%VERSION%/protocols/");
-
- // suppress external-load warning for standard browser schemes
--pref("network.protocol-handler.warn-external.http", false);
--pref("network.protocol-handler.warn-external.https", false);
--pref("network.protocol-handler.warn-external.ftp", false);
-+pref("network.protocol-handler.warn-external.http", true);
-+pref("network.protocol-handler.warn-external.https", true);
-+pref("network.protocol-handler.warn-external.ftp", true);
-
- // don't load links inside Instantbird
- pref("network.protocol-handler.expose-all", false);
-@@ -262,10 +264,10 @@
- pref("network.protocol-handler.expose.javascript", true);
-
- // 0-Accept, 1-dontAcceptForeign, 2-dontUse
--pref("network.cookie.cookieBehavior", 0);
-+pref("network.cookie.cookieBehavior", 1);
-
- // The breakpad report server to link to in about:crashes
--pref("breakpad.reportURL", "http://crash-stats.instantbird.com/report/index/");
-+pref("breakpad.reportURL", "https://crash-stats.instantbird.com/report/index/");
-
- // We have an Error Console menu item by default so let's display chrome errors
- pref("javascript.options.showInConsole", true);
-@@ -300,14 +302,76 @@
- // 3 at the end of the tabstrip
- pref("browser.tabs.closeButtons", 1);
-
--#expand pref("chat.irc.defaultQuitMessage", "Instantbird __APP_VERSION__ -- http://www.instantbird.com");
-+#expand pref("chat.irc.defaultQuitMessage", "");
-
- pref("chat.twitter.consumerKey", "TSuyS1ieRAkB3qWv8yyEw");
- pref("chat.twitter.consumerSecret", "DKtKaSf5a7pBNhdBsSZHTnI5Y03hRlPFYWmb4xXBlkU");
-
- // Comma separated list of prpl ids that should use libpurple even if there is
- // a JS implementation. This is used to land JS-prpls pref'ed off in nightlies.
--pref("chat.prpls.forcePurple", "prpl-jabber");
-+pref("chat.prpls.forcePurple", "");
-
- // Whether to parse log files for conversation statistics.
--pref("statsService.parseLogsForStats", true);
-+pref("statsService.parseLogsForStats", false);
-+
-+/* Tor Messenger */
-+// Logging
-+// Disable all logging
-+pref("purple.logging.log_chats", false);
-+pref("purple.logging.log_ims", false);
-+pref("purple.logging.log_system", false);
-+
-+// Network
-+// Use a manual proxy configuration
-+pref("network.proxy.type", 1);
-+// Empty the "no proxy" setting
-+pref("network.proxy.no_proxies_on", "");
-+// Configure Instantbird to use the SOCKS5 proxy
-+pref("network.proxy.socks", "127.0.0.1");
-+pref("network.proxy.socks_port", 9152);
-+pref("network.proxy.socks_version", 5);
-+// Set DNS proxying through SOCKS5
-+pref("network.proxy.socks_remote_dns", true);
-+// Disable DNS prefetching
-+pref("network.dns.disablePrefetch", true);
-+// Disable SPDY
-+pref("network.http.spdy.enabled", false);
-+// Set the user-agent to Instantbird stable
-+pref("general.useragent.override", "Mozilla/5.0 (Windows NT 6.1; rv:25.0) Gecko/20100101 Instantbird/1.5");
-+
-+// Security
-+// Disable SSLv3 by setting the minimum supported protocol to TLS 1.0.
-+pref("security.tls.version.min", 1);
-+// We use the certdb. Necessary for the TB patch,
-+// "Bug 14716: HTTP Basic Authentication prompt only displayed once"
-+pref("security.nocertdb", false);
-+// Disable geolocation
-+pref("geo.enabled", false);
-+
-+// Do not report idle status or the away message
-+pref("messenger.status.awayWhenIdle", false);
-+pref("messenger.status.defaultIdleAwayMessage", "");
-+pref("messenger.status.reportIdle", false);
-+// Do not send the message format (fonts, colors)
-+pref("messenger.conversations.sendFormat", false);
-+// Disable text formatting (remove the tags)
-+pref("messenger.options.filterMode", 0);
-+// Disable typing notifications
-+pref("purple.conversations.im.send_typing", false);
-+
-+// Browser
-+// Disable caching
-+pref("browser.cache.disk.enable", false);
-+pref("browser.cache.offline.enable", false);
-+
-+// Media
-+// Disable WebRTC
-+pref("media.peerconnection.enabled", false);
-+// Disable "Take Picture" functionality that accesses the webcam
-+pref("media.navigator.video.enabled", false);
-+// Disable hardware acceleration
-+pref("gfx.direct2d.disabled", true);
-+pref("layers.acceleration.disabled", true);
-+
-+// Other Updates
-+pref("app.update.promptWaitTime", 3600);
-+
-+// Put conversations on hold so that OTR disconnect is not sent. See #20208.
-+pref("messenger.conversations.holdByDefault", true);
diff --git a/projects/instantbird/search-context-menu.patch b/projects/instantbird/search-context-menu.patch
deleted file mode 100644
index a27d323..0000000
--- a/projects/instantbird/search-context-menu.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-diff --git a/im/content/nsContextMenu.js b/im/content/nsContextMenu.js
---- a/im/content/nsContextMenu.js
-+++ b/im/content/nsContextMenu.js
-@@ -468,23 +468,7 @@
- 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/projects/instantbird/search-preferences-xul.patch b/projects/instantbird/search-preferences-xul.patch
deleted file mode 100644
index a6b2a31..0000000
--- a/projects/instantbird/search-preferences-xul.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-diff --git a/im/content/preferences/advanced.xul b/im/content/preferences/advanced.xul
---- 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;"/>
diff --git a/projects/instantbird/show-traffic-tor.patch b/projects/instantbird/show-traffic-tor.patch
deleted file mode 100644
index ae55305..0000000
--- a/projects/instantbird/show-traffic-tor.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-diff --git a/im/content/accountWizard.xul b/im/content/accountWizard.xul
---- 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
---- 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">
diff --git a/projects/instantbird/theme-extension-update.patch b/projects/instantbird/theme-extension-update.patch
deleted file mode 100644
index a1585a8..0000000
--- a/projects/instantbird/theme-extension-update.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-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
---- 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/projects/instantbird/themes-remove-links.patch b/projects/instantbird/themes-remove-links.patch
deleted file mode 100644
index 8ef25d7..0000000
--- a/projects/instantbird/themes-remove-links.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-diff --git a/im/content/preferences/themes.js b/im/content/preferences/themes.js
---- a/im/content/preferences/themes.js
-+++ b/im/content/preferences/themes.js
-@@ -31,21 +31,6 @@
- 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
---- 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>
diff --git a/projects/instantbird/top-protocols.patch b/projects/instantbird/top-protocols.patch
deleted file mode 100644
index eb7c8f3..0000000
--- a/projects/instantbird/top-protocols.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-diff --git a/im/locales/en-US/chrome/instantbird/accountWizard.properties b/im/locales/en-US/chrome/instantbird/accountWizard.properties
---- 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
diff --git a/projects/instantbird/trac-13312.patch b/projects/instantbird/trac-13312.patch
deleted file mode 100644
index c3ea75f..0000000
--- a/projects/instantbird/trac-13312.patch
+++ /dev/null
@@ -1,1414 +0,0 @@
-# HG changeset patch
-# User Arlo Breault <arlolra@xxxxxxxxx>
-# Date 1458088842 25200
-# Tue Mar 15 17:40:42 2016 -0700
-# Branch THUNDERBIRD4530_2016082513_RELBRANCH
-# Node ID 64dd542b1c7d0e62b43dc0d5a57a3ff034b514da
-# Parent 69baf6e1ea1e4c8f4ddf719bff6b542869a99a23
-Changes to twitter.js upstream
-
-diff --git a/chat/protocols/twitter/twitter.js b/chat/protocols/twitter/twitter.js
---- a/chat/protocols/twitter/twitter.js
-+++ b/chat/protocols/twitter/twitter.js
-@@ -124,17 +124,21 @@ Action.prototype = {
- };
-
- function Conversation(aAccount)
- {
- this._init(aAccount);
- this._ensureParticipantExists(aAccount.name);
- // We need the screen names for the IDs in _friends, but _userInfo is
- // indexed by name, so we build an ID -> name map.
-- let names = new Map([userInfo.id_str, name] for ([name, userInfo] of aAccount._userInfo));
-+ let entries = [];
-+ for (let [name, userInfo] of aAccount._userInfo) {
-+ entries.push([userInfo.id_str, name]);
-+ }
-+ let names = new Map(entries);
- for (let id_str of aAccount._friends)
- this._ensureParticipantExists(names.get(id_str));
-
- // If the user's info has already been received, update the timeline topic.
- if (aAccount._userInfo.has(aAccount.name)) {
- let userInfo = aAccount._userInfo.get(aAccount.name);
- if ("description" in userInfo)
- this.setTopic(userInfo.description, aAccount.name, true);
-@@ -314,17 +318,17 @@ Conversation.prototype = {
- end: um.indices[1],
- str: "@" + um.screen_name,
- text: '@<span class="ib-person">' + um.screen_name + "</span>",
- title: um.name,
- href: "https://twitter.com/" + um.screen_name})));
- }
- entArray.sort((a, b) => a.start - b.start);
- let offset = 0;
-- for each (let entity in entArray) {
-+ for (let entity of entArray) {
- let str = text.substring(offset + entity.start, offset + entity.end);
- if (str[0] == "\uFF20") // ï¼ - unicode character similar to @
- str = "@" + str.substring(1);
- if (str[0] == "\uFF03") // ï¼? - unicode character similar to #
- str = "#" + str.substring(1);
- if (str.toLowerCase() != entity.str.toLowerCase())
- continue;
-
-@@ -507,17 +511,17 @@ Account.prototype = {
-
- let keyFactory = Cc["@mozilla.org/security/keyobjectfactory;1"]
- .getService(Ci.nsIKeyObjectFactory);
- let hmac =
- Cc["@mozilla.org/security/hmac;1"].createInstance(Ci.nsICryptoHMAC);
- hmac.init(hmac.SHA1,
- keyFactory.keyFromString(Ci.nsIKeyObject.HMAC, signatureKey));
- // No UTF-8 encoding, special chars are already escaped.
-- let bytes = [b.charCodeAt() for each (b in signatureBase)];
-+ let bytes = [...signatureBase].map(b => b.charCodeAt());
- hmac.update(bytes, bytes.length);
- let signature = hmac.finish(true);
-
- params.push(["oauth_signature", encodeURIComponent(signature)]);
-
- let authorization =
- "OAuth " + params.map(p => p[0] + "=\"" + p[1] + "\"").join(", ");
-
-@@ -615,17 +619,17 @@ Account.prototype = {
- this.signAndSend(url, null, null, this.onTimelineReceived,
- this.onTimelineError, this, null));
- }
- },
-
- get timeline() { return this._timeline || (this._timeline = new Conversation(this)); },
- displayMessages: function(aMessages) {
- let lastMsgId = this._lastMsgId;
-- for each (let tweet in aMessages) {
-+ for (let tweet of aMessages) {
- if (!("user" in tweet) || !("text" in tweet) || !("id_str" in tweet) ||
- this._knownMessageIds.has(tweet.id_str))
- continue;
- let id = tweet.id_str;
- // Update the last known message.
- // Compare the length of the ids first, and then the text.
- // This avoids converting tweet ids into rounded numbers.
- if (id.length > lastMsgId.length ||
-@@ -734,33 +738,33 @@ Account.prototype = {
- this.gotDisconnected(Ci.prplIAccount.ERROR_NETWORK_ERROR, "timeout");
- },
- onDataAvailable: function(aRequest) {
- this.resetStreamTimeout();
- let newText = this._pendingData + aRequest.target.response;
- this.DEBUG("Received data: " + newText);
- let messages = newText.split(/\r\n?/);
- this._pendingData = messages.pop();
-- for each (let message in messages) {
-+ for (let message of messages) {
- if (!message.trim())
- continue;
- let msg;
- try {
- msg = JSON.parse(message);
- } catch (e) {
- this.ERROR(e + " while parsing " + message);
- continue;
- }
- if ("text" in msg)
- this.displayMessages([msg]);
- else if ("friends" in msg) {
- // Filter out the IDs that info has already been received from (e.g. a
- // tweet has been received as part of the timeline request).
- let userInfoIds = new Set();
-- for each (let userInfo in this._userInfo)
-+ for (let userInfo of this._userInfo.values())
- userInfoIds.add(userInfo.id_str);
- let ids = msg.friends.filter(
- aId => !userInfoIds.has(aId.toString()));
-
- while (ids.length) {
- // Take the first 100 elements, turn them into a comma separated list.
- this.signAndSend("1.1/users/lookup.json", null,
- [["user_id", ids.slice(0, 99).join(",")]],
-@@ -946,17 +950,17 @@ Account.prototype = {
- this.name + " -> " + aAuthResult.screen_name);
- this.__defineGetter__("name", () => aAuthResult.screen_name);
- return true;
- },
-
- cleanUp: function() {
- this.finishAuthorizationRequest();
- if (this._pendingRequests.length != 0) {
-- for each (let request in this._pendingRequests)
-+ for (let request of this._pendingRequests)
- request.abort();
- delete this._pendingRequests;
- }
- if (this._streamTimeout) {
- clearTimeout(this._streamTimeout);
- delete this._streamTimeout;
- // Remove the preference observer that is added when the user stream is
- // opened. (This needs to be removed even if an error occurs, in which
-@@ -1083,17 +1087,17 @@ Account.prototype = {
- Services.obs.notifyObservers(new nsSimpleEnumerator(tooltipInfo),
- "user-info-received", aBuddyName);
- },
-
- // Handle the full user info for each received friend. Set the user info and
- // create the participant.
- onLookupReceived: function(aData) {
- let users = JSON.parse(aData);
-- for each (let user in users) {
-+ for (let user of users) {
- this.setUserInfo(user);
- this.timeline._ensureParticipantExists(user.screen_name);
- }
- },
-
- onConfigReceived: function(aData) {
- this.config = JSON.parse(aData);
- },
-# HG changeset patch
-# User Arlo Breault <arlolra@xxxxxxxxx>
-# Date 1458087696 25200
-# Tue Mar 15 17:21:36 2016 -0700
-# Branch THUNDERBIRD4530_2016082513_RELBRANCH
-# Node ID 9f2addccb7a8d4875746abd96f6beba38ef0f398
-# Parent 64dd542b1c7d0e62b43dc0d5a57a3ff034b514da
-Update twitter-text.jsm
-
-diff --git a/chat/protocols/twitter/twitter-text.jsm b/chat/protocols/twitter/twitter-text.jsm
---- a/chat/protocols/twitter/twitter-text.jsm
-+++ b/chat/protocols/twitter/twitter-text.jsm
-@@ -14,17 +14,17 @@
- */
-
- this.EXPORTED_SYMBOLS = ["twttr"];
-
- var window = {};
-
- // The code below is imported from Twitter's JavaScript utility for parsing
- // tweets. The original version of this file can be found at
--// https://github.com/twitter/twitter-text-js/blob/master/twitter-text.js
-+// https://github.com/twitter/twitter-text/blob/master/js/twitter-text.js
-
- (function() {
- if (typeof twttr === "undefined" || twttr === null) {
- var twttr = {};
- }
-
- twttr.txt = {};
- twttr.txt.regexen = {};
-@@ -120,90 +120,16 @@ var window = {};
-
- twttr.txt.regexen.spaces_group = regexSupplant(UNICODE_SPACES.join(""));
- twttr.txt.regexen.spaces = regexSupplant("[" + UNICODE_SPACES.join("") + "]");
- twttr.txt.regexen.invalid_chars_group = regexSupplant(INVALID_CHARS.join(""));
- twttr.txt.regexen.punct = /\!'#%&'\(\)*\+,\\\-\.\/:;<=>\?@\[\]\^_{|}~\$/;
- twttr.txt.regexen.rtl_chars = /[\u0600-\u06FF]|[\u0750-\u077F]|[\u0590-\u05FF]|[\uFE70-\uFEFF]/mg;
- twttr.txt.regexen.non_bmp_code_pairs = /[\uD800-\uDBFF][\uDC00-\uDFFF]/mg;
-
-- var nonLatinHashtagChars = [];
-- // Cyrillic
-- addCharsToCharClass(nonLatinHashtagChars, 0x0400, 0x04ff); // Cyrillic
-- addCharsToCharClass(nonLatinHashtagChars, 0x0500, 0x0527); // Cyrillic Supplement
-- addCharsToCharClass(nonLatinHashtagChars, 0x2de0, 0x2dff); // Cyrillic Extended A
-- addCharsToCharClass(nonLatinHashtagChars, 0xa640, 0xa69f); // Cyrillic Extended B
-- // Hebrew
-- addCharsToCharClass(nonLatinHashtagChars, 0x0591, 0x05bf); // Hebrew
-- addCharsToCharClass(nonLatinHashtagChars, 0x05c1, 0x05c2);
-- addCharsToCharClass(nonLatinHashtagChars, 0x05c4, 0x05c5);
-- addCharsToCharClass(nonLatinHashtagChars, 0x05c7, 0x05c7);
-- addCharsToCharClass(nonLatinHashtagChars, 0x05d0, 0x05ea);
-- addCharsToCharClass(nonLatinHashtagChars, 0x05f0, 0x05f4);
-- addCharsToCharClass(nonLatinHashtagChars, 0xfb12, 0xfb28); // Hebrew Presentation Forms
-- addCharsToCharClass(nonLatinHashtagChars, 0xfb2a, 0xfb36);
-- addCharsToCharClass(nonLatinHashtagChars, 0xfb38, 0xfb3c);
-- addCharsToCharClass(nonLatinHashtagChars, 0xfb3e, 0xfb3e);
-- addCharsToCharClass(nonLatinHashtagChars, 0xfb40, 0xfb41);
-- addCharsToCharClass(nonLatinHashtagChars, 0xfb43, 0xfb44);
-- addCharsToCharClass(nonLatinHashtagChars, 0xfb46, 0xfb4f);
-- // Arabic
-- addCharsToCharClass(nonLatinHashtagChars, 0x0610, 0x061a); // Arabic
-- addCharsToCharClass(nonLatinHashtagChars, 0x0620, 0x065f);
-- addCharsToCharClass(nonLatinHashtagChars, 0x066e, 0x06d3);
-- addCharsToCharClass(nonLatinHashtagChars, 0x06d5, 0x06dc);
-- addCharsToCharClass(nonLatinHashtagChars, 0x06de, 0x06e8);
-- addCharsToCharClass(nonLatinHashtagChars, 0x06ea, 0x06ef);
-- addCharsToCharClass(nonLatinHashtagChars, 0x06fa, 0x06fc);
-- addCharsToCharClass(nonLatinHashtagChars, 0x06ff, 0x06ff);
-- addCharsToCharClass(nonLatinHashtagChars, 0x0750, 0x077f); // Arabic Supplement
-- addCharsToCharClass(nonLatinHashtagChars, 0x08a0, 0x08a0); // Arabic Extended A
-- addCharsToCharClass(nonLatinHashtagChars, 0x08a2, 0x08ac);
-- addCharsToCharClass(nonLatinHashtagChars, 0x08e4, 0x08fe);
-- addCharsToCharClass(nonLatinHashtagChars, 0xfb50, 0xfbb1); // Arabic Pres. Forms A
-- addCharsToCharClass(nonLatinHashtagChars, 0xfbd3, 0xfd3d);
-- addCharsToCharClass(nonLatinHashtagChars, 0xfd50, 0xfd8f);
-- addCharsToCharClass(nonLatinHashtagChars, 0xfd92, 0xfdc7);
-- addCharsToCharClass(nonLatinHashtagChars, 0xfdf0, 0xfdfb);
-- addCharsToCharClass(nonLatinHashtagChars, 0xfe70, 0xfe74); // Arabic Pres. Forms B
-- addCharsToCharClass(nonLatinHashtagChars, 0xfe76, 0xfefc);
-- addCharsToCharClass(nonLatinHashtagChars, 0x200c, 0x200c); // Zero-Width Non-Joiner
-- // Thai
-- addCharsToCharClass(nonLatinHashtagChars, 0x0e01, 0x0e3a);
-- addCharsToCharClass(nonLatinHashtagChars, 0x0e40, 0x0e4e);
-- // Hangul (Korean)
-- addCharsToCharClass(nonLatinHashtagChars, 0x1100, 0x11ff); // Hangul Jamo
-- addCharsToCharClass(nonLatinHashtagChars, 0x3130, 0x3185); // Hangul Compatibility Jamo
-- addCharsToCharClass(nonLatinHashtagChars, 0xA960, 0xA97F); // Hangul Jamo Extended-A
-- addCharsToCharClass(nonLatinHashtagChars, 0xAC00, 0xD7AF); // Hangul Syllables
-- addCharsToCharClass(nonLatinHashtagChars, 0xD7B0, 0xD7FF); // Hangul Jamo Extended-B
-- addCharsToCharClass(nonLatinHashtagChars, 0xFFA1, 0xFFDC); // half-width Hangul
-- // Japanese and Chinese
-- addCharsToCharClass(nonLatinHashtagChars, 0x30A1, 0x30FA); // Katakana (full-width)
-- addCharsToCharClass(nonLatinHashtagChars, 0x30FC, 0x30FE); // Katakana Chouon and iteration marks (full-width)
-- addCharsToCharClass(nonLatinHashtagChars, 0xFF66, 0xFF9F); // Katakana (half-width)
-- addCharsToCharClass(nonLatinHashtagChars, 0xFF70, 0xFF70); // Katakana Chouon (half-width)
-- addCharsToCharClass(nonLatinHashtagChars, 0xFF10, 0xFF19); // \
-- addCharsToCharClass(nonLatinHashtagChars, 0xFF21, 0xFF3A); // - Latin (full-width)
-- addCharsToCharClass(nonLatinHashtagChars, 0xFF41, 0xFF5A); // /
-- addCharsToCharClass(nonLatinHashtagChars, 0x3041, 0x3096); // Hiragana
-- addCharsToCharClass(nonLatinHashtagChars, 0x3099, 0x309E); // Hiragana voicing and iteration mark
-- addCharsToCharClass(nonLatinHashtagChars, 0x3400, 0x4DBF); // Kanji (CJK Extension A)
-- addCharsToCharClass(nonLatinHashtagChars, 0x4E00, 0x9FFF); // Kanji (Unified)
-- // -- Disabled as it breaks the Regex.
-- //addCharsToCharClass(nonLatinHashtagChars, 0x20000, 0x2A6DF); // Kanji (CJK Extension B)
-- addCharsToCharClass(nonLatinHashtagChars, 0x2A700, 0x2B73F); // Kanji (CJK Extension C)
-- addCharsToCharClass(nonLatinHashtagChars, 0x2B740, 0x2B81F); // Kanji (CJK Extension D)
-- addCharsToCharClass(nonLatinHashtagChars, 0x2F800, 0x2FA1F); // Kanji (CJK supplement)
-- addCharsToCharClass(nonLatinHashtagChars, 0x3003, 0x3003); // Kanji iteration mark
-- addCharsToCharClass(nonLatinHashtagChars, 0x3005, 0x3005); // Kanji iteration mark
-- addCharsToCharClass(nonLatinHashtagChars, 0x303B, 0x303B); // Han iteration mark
--
-- twttr.txt.regexen.nonLatinHashtagChars = regexSupplant(nonLatinHashtagChars.join(""));
--
- var latinAccentChars = [];
- // Latin accented characters (subtracted 0xD7 from the range, it's a confusable multiplication sign. Looks like "x")
- addCharsToCharClass(latinAccentChars, 0x00c0, 0x00d6);
- addCharsToCharClass(latinAccentChars, 0x00d8, 0x00f6);
- addCharsToCharClass(latinAccentChars, 0x00f8, 0x00ff);
- // Latin Extended A and B
- addCharsToCharClass(latinAccentChars, 0x0100, 0x024f);
- // assorted IPA Extensions
-@@ -220,26 +146,30 @@ var window = {};
- // Okina for Hawaiian (it *is* a letter character)
- addCharsToCharClass(latinAccentChars, 0x02bb, 0x02bb);
- // Combining diacritics
- addCharsToCharClass(latinAccentChars, 0x0300, 0x036f);
- // Latin Extended Additional
- addCharsToCharClass(latinAccentChars, 0x1e00, 0x1eff);
- twttr.txt.regexen.latinAccentChars = regexSupplant(latinAccentChars.join(""));
-
-- // A hashtag must contain characters, numbers and underscores, but not all numbers.
-+ var unicodeLettersAndMarks = "A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0
B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8
-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u
2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\u
FB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C03\u0C3E-\u0C44
\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u192B\u1930-\u193B\u19B0-\u19C0\u19C8\u19C9\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099
\u309A\uA66F-\uA672\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2D";
-+ var unicodeNumbers = "0-9\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE6-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29\u1040-\u1049\u1090-\u1099\u17E0-\u17E9\u1810-\u1819\u1946-\u194F\u19D0-\u19D9\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\uA620-\uA629\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19";
-+ var hashtagSpecialChars = "_\u200c\u200d\ua67e\u05be\u05f3\u05f4\uff5e\u301c\u309b\u309c\u30a0\u30fb\u3003\u0f0b\u0f0c\u00b7";
-+
-+ // A hashtag must contain at least one unicode letter or mark, as well as numbers, underscores, and select special characters.
- twttr.txt.regexen.hashSigns = /[#ï¼?]/;
-- twttr.txt.regexen.hashtagAlpha = regexSupplant(/[a-z_#{latinAccentChars}#{nonLatinHashtagChars}]/i);
-- twttr.txt.regexen.hashtagAlphaNumeric = regexSupplant(/[a-z0-9_#{latinAccentChars}#{nonLatinHashtagChars}]/i);
-+ twttr.txt.regexen.hashtagAlpha = new RegExp("[" + unicodeLettersAndMarks + "]");
-+ twttr.txt.regexen.hashtagAlphaNumeric = new RegExp("[" + unicodeLettersAndMarks + unicodeNumbers + hashtagSpecialChars + "]");
- twttr.txt.regexen.endHashtagMatch = regexSupplant(/^(?:#{hashSigns}|:\/\/)/);
-- twttr.txt.regexen.hashtagBoundary = regexSupplant(/(?:^|$|[^&a-z0-9_#{latinAccentChars}#{nonLatinHashtagChars}])/);
-- twttr.txt.regexen.validHashtag = regexSupplant(/(#{hashtagBoundary})(#{hashSigns})(#{hashtagAlphaNumeric}*#{hashtagAlpha}#{hashtagAlphaNumeric}*)/gi);
-+ twttr.txt.regexen.hashtagBoundary = new RegExp("(?:^|$|[^&" + unicodeLettersAndMarks + unicodeNumbers + hashtagSpecialChars + "])");
-+ twttr.txt.regexen.validHashtag = regexSupplant(/(#{hashtagBoundary})(#{hashSigns})(?!\ufe0f|\u20e3)(#{hashtagAlphaNumeric}*#{hashtagAlpha}#{hashtagAlphaNumeric}*)/gi);
-
- // Mention related regex collection
-- twttr.txt.regexen.validMentionPrecedingChars = /(?:^|[^a-zA-Z0-9_!#$%&*@ï¼ ]|RT:?)/;
-+ twttr.txt.regexen.validMentionPrecedingChars = /(?:^|[^a-zA-Z0-9_!#$%&*@ï¼ ]|(?:^|[^a-zA-Z0-9_+~.-])(?:rt|RT|rT|Rt):?)/;
- twttr.txt.regexen.atSigns = /[@ï¼ ]/;
- twttr.txt.regexen.validMentionOrList = regexSupplant(
- '(#{validMentionPrecedingChars})' + // $1: Preceding character
- '(#{atSigns})' + // $2: At mark
- '([a-zA-Z0-9_]{1,20})' + // $3: Screen name
- '(\/[a-zA-Z][a-zA-Z0-9_\-]{0,24})?' // $4: List (optional)
- , 'g');
- twttr.txt.regexen.validReply = regexSupplant(/^(?:#{spaces})*#{atSigns}([a-zA-Z0-9_]{1,20})/);
-@@ -247,40 +177,120 @@ var window = {};
-
- // URL related regex collection
- twttr.txt.regexen.validUrlPrecedingChars = regexSupplant(/(?:[^A-Za-z0-9@ï¼ $#ï¼?#{invalid_chars_group}]|^)/);
- twttr.txt.regexen.invalidUrlWithoutProtocolPrecedingChars = /[-_.\/]$/;
- twttr.txt.regexen.invalidDomainChars = stringSupplant("#{punct}#{spaces_group}#{invalid_chars_group}", twttr.txt.regexen);
- twttr.txt.regexen.validDomainChars = regexSupplant(/[^#{invalidDomainChars}]/);
- twttr.txt.regexen.validSubdomain = regexSupplant(/(?:(?:#{validDomainChars}(?:[_-]|#{validDomainChars})*)?#{validDomainChars}\.)/);
- twttr.txt.regexen.validDomainName = regexSupplant(/(?:(?:#{validDomainChars}(?:-|#{validDomainChars})*)?#{validDomainChars}\.)/);
-- twttr.txt.regexen.validGTLD = regexSupplant(/(?:(?:aero|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|xxx)(?=[^0-9a-zA-Z]|$))/);
-+ twttr.txt.regexen.validGTLD = regexSupplant(RegExp(
-+ '(?:(?:' +
-+ 'abb|abbott|abogado|academy|accenture|accountant|accountants|aco|active|actor|ads|adult|aeg|aero|' +
-+ 'afl|agency|aig|airforce|airtel|allfinanz|alsace|amsterdam|android|apartments|app|aquarelle|' +
-+ 'archi|army|arpa|asia|associates|attorney|auction|audio|auto|autos|axa|azure|band|bank|bar|' +
-+ 'barcelona|barclaycard|barclays|bargains|bauhaus|bayern|bbc|bbva|bcn|beer|bentley|berlin|best|' +
-+ 'bet|bharti|bible|bid|bike|bing|bingo|bio|biz|black|blackfriday|bloomberg|blue|bmw|bnl|' +
-+ 'bnpparibas|boats|bond|boo|boots|boutique|bradesco|bridgestone|broker|brother|brussels|budapest|' +
-+ 'build|builders|business|buzz|bzh|cab|cafe|cal|camera|camp|cancerresearch|canon|capetown|capital|' +
-+ 'caravan|cards|care|career|careers|cars|cartier|casa|cash|casino|cat|catering|cba|cbn|ceb|center|' +
-+ 'ceo|cern|cfa|cfd|chanel|channel|chat|cheap|chloe|christmas|chrome|church|cisco|citic|city|' +
-+ 'claims|cleaning|click|clinic|clothing|cloud|club|coach|codes|coffee|college|cologne|com|' +
-+ 'commbank|community|company|computer|condos|construction|consulting|contractors|cooking|cool|' +
-+ 'coop|corsica|country|coupons|courses|credit|creditcard|cricket|crown|crs|cruises|cuisinella|' +
-+ 'cymru|cyou|dabur|dad|dance|date|dating|datsun|day|dclk|deals|degree|delivery|delta|democrat|' +
-+ 'dental|dentist|desi|design|dev|diamonds|diet|digital|direct|directory|discount|dnp|docs|dog|' +
-+ 'doha|domains|doosan|download|drive|durban|dvag|earth|eat|edu|education|email|emerck|energy|' +
-+ 'engineer|engineering|enterprises|epson|equipment|erni|esq|estate|eurovision|eus|events|everbank|' +
-+ 'exchange|expert|exposed|express|fage|fail|faith|family|fan|fans|farm|fashion|feedback|film|' +
-+ 'finance|financial|firmdale|fish|fishing|fit|fitness|flights|florist|flowers|flsmidth|fly|foo|' +
-+ 'football|forex|forsale|forum|foundation|frl|frogans|fund|furniture|futbol|fyi|gal|gallery|game|' +
-+ 'garden|gbiz|gdn|gent|genting|ggee|gift|gifts|gives|giving|glass|gle|global|globo|gmail|gmo|gmx|' +
-+ 'gold|goldpoint|golf|goo|goog|google|gop|gov|graphics|gratis|green|gripe|group|guge|guide|' +
-+ 'guitars|guru|hamburg|hangout|haus|healthcare|help|here|hermes|hiphop|hitachi|hiv|hockey|' +
-+ 'holdings|holiday|homedepot|homes|honda|horse|host|hosting|hoteles|hotmail|house|how|hsbc|ibm|' +
-+ 'icbc|ice|icu|ifm|iinet|immo|immobilien|industries|infiniti|info|ing|ink|institute|insure|int|' +
-+ 'international|investments|ipiranga|irish|ist|istanbul|itau|iwc|java|jcb|jetzt|jewelry|jlc|jll|' +
-+ 'jobs|joburg|jprs|juegos|kaufen|kddi|kim|kitchen|kiwi|koeln|komatsu|krd|kred|kyoto|lacaixa|' +
-+ 'lancaster|land|lasalle|lat|latrobe|law|lawyer|lds|lease|leclerc|legal|lexus|lgbt|liaison|lidl|' +
-+ 'life|lighting|limited|limo|link|live|lixil|loan|loans|lol|london|lotte|lotto|love|ltda|lupin|' +
-+ 'luxe|luxury|madrid|maif|maison|man|management|mango|market|marketing|markets|marriott|mba|media|' +
-+ 'meet|melbourne|meme|memorial|men|menu|miami|microsoft|mil|mini|mma|mobi|moda|moe|mom|monash|' +
-+ 'money|montblanc|mormon|mortgage|moscow|motorcycles|mov|movie|movistar|mtn|mtpc|museum|nadex|' +
-+ 'nagoya|name|navy|nec|net|netbank|network|neustar|new|news|nexus|ngo|nhk|nico|ninja|nissan|nokia|' +
-+ 'nra|nrw|ntt|nyc|office|okinawa|omega|one|ong|onl|online|ooo|oracle|orange|org|organic|osaka|' +
-+ 'otsuka|ovh|page|panerai|paris|partners|parts|party|pet|pharmacy|philips|photo|photography|' +
-+ 'photos|physio|piaget|pics|pictet|pictures|pink|pizza|place|play|plumbing|plus|pohl|poker|porn|' +
-+ 'post|praxi|press|pro|prod|productions|prof|properties|property|pub|qpon|quebec|racing|realtor|' +
-+ 'realty|recipes|red|redstone|rehab|reise|reisen|reit|ren|rent|rentals|repair|report|republican|' +
-+ 'rest|restaurant|review|reviews|rich|ricoh|rio|rip|rocks|rodeo|rsvp|ruhr|run|ryukyu|saarland|' +
-+ 'sakura|sale|samsung|sandvik|sandvikcoromant|sanofi|sap|sarl|saxo|sca|scb|schmidt|scholarships|' +
-+ 'school|schule|schwarz|science|scor|scot|seat|seek|sener|services|sew|sex|sexy|shiksha|shoes|' +
-+ 'show|shriram|singles|site|ski|sky|skype|sncf|soccer|social|software|sohu|solar|solutions|sony|' +
-+ 'soy|space|spiegel|spreadbetting|srl|starhub|statoil|studio|study|style|sucks|supplies|supply|' +
-+ 'support|surf|surgery|suzuki|swatch|swiss|sydney|systems|taipei|tatamotors|tatar|tattoo|tax|taxi|' +
-+ 'team|tech|technology|tel|telefonica|temasek|tennis|thd|theater|tickets|tienda|tips|tires|tirol|' +
-+ 'today|tokyo|tools|top|toray|toshiba|tours|town|toyota|toys|trade|trading|training|travel|trust|' +
-+ 'tui|ubs|university|uno|uol|vacations|vegas|ventures|vermögensberater|vermögensberatung|' +
-+ 'versicherung|vet|viajes|video|villas|vin|vision|vista|vistaprint|vlaanderen|vodka|vote|voting|' +
-+ 'voto|voyage|wales|walter|wang|watch|webcam|website|wed|wedding|weir|whoswho|wien|wiki|' +
-+ 'williamhill|win|windows|wine|wme|work|works|world|wtc|wtf|xbox|xerox|xin|xperia|xxx|xyz|yachts|' +
-+ 'yandex|yodobashi|yoga|yokohama|youtube|zip|zone|zuerich|деÑ?и|ком|моÑ?ква|онлайн|оÑ?г|Ñ?Ñ?Ñ?|Ñ?айÑ?|ק×?×?|' +
-+ 'بازار|شبÙ?Ø©|Ù?Ù?Ù?|Ù?Ù?Ù?ع|à¤?à¥?म|नà¥?à¤?|सà¤?à¤?ठन|à¸?à¸à¸¡|ã?¿ã??ã?ª|ã?°ã?¼ã?°ã?«|ã?³ã? |ä¸?ç??|ä¸ä¿¡|ä¸æ??ç½?|ä¼?ä¸?|ä½?å±±|ä¿¡æ?¯|å?¥åº·|å?«å?¦|å?¬å?¸|å?¬ç??|å??å??|å??åº?|å??æ ?|å?¨çº¿|大æ?¿|' +
-+ '娱ä¹?|å·¥è¡?|广ä¸?|æ??å??|æ??ç?±ä½ |æ??æ?º|æ?¿å?¡|æ?¿åº?|æ?°é?»|æ?¶å°?|æ?ºæ??|淡马é?¡|游æ??|ç?¹ç??|移å?¨|ç»?ç»?æ?ºæ??|ç½?å??|ç½?åº?|ç½?ç»?|è°·æ?|é??å?¢|é£?å?©æµ¦|é¤?å??|ë?·ë?·|ë?·ì»´|ì?¼ì?±|onion' +
-+ ')(?=[^0-9a-zA-Z@]|$))'));
- twttr.txt.regexen.validCCTLD = regexSupplant(RegExp(
-- "(?:(?:ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|" +
-- "ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|" +
-- "ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|" +
-- "ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|" +
-- "na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|" +
-- "sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|" +
-- "ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw)(?=[^0-9a-zA-Z]|$))"));
-+ '(?:(?:' +
-+ 'ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bl|bm|bn|bo|bq|' +
-+ 'br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|' +
-+ 'ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|' +
-+ 'gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|' +
-+ 'la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mf|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|' +
-+ 'my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|' +
-+ 'rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|' +
-+ 'tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw|ελ|' +
-+ 'бел|мкд|мон|Ñ?Ñ?|Ñ?Ñ?б|Ñ?кÑ?|Ò?аз|Õ°Õ¡Õµ|اÙ?اردÙ?|اÙ?جزائر|اÙ?سعÙ?دÙ?Ø©|اÙ?Ù?غرب|اÙ?ارات|اÛ?راÙ?|بھارت|تÙ?Ù?س|سÙ?داÙ?|' +
-+ 'سÙ?رÙ?Ø©|عراÙ?|عÙ?اÙ?|Ù?Ù?سطÙ?Ù?|Ù?طر|Ù?صر|Ù?Ù?Ù?سÙ?ا|پاکستاÙ?|à¤à¤¾à¤°à¤¤|বাà¦?লা|à¦à¦¾à¦°à¦¤|à¨à¨¾à¨°à¨¤|àªàª¾àª°àª¤|à®?நà¯?தியா|à®?லà®?à¯?à®?à¯?|' +
-+ 'à®?ிà®?à¯?à®?பà¯?பà¯?à®°à¯?|à°à°¾à°°à°¤à±?|ලà¶?à¶?à·?|à¹?à¸?ย|á??á??|ä¸å?½|ä¸å??|å?°æ¹¾|å?°ç?£|æ?°å? å?¡|æ¾³é??|é¦?港|í??êµ' +
-+ ')(?=[^0-9a-zA-Z@]|$))'));
- twttr.txt.regexen.validPunycode = regexSupplant(/(?:xn--[0-9a-z]+)/);
-+ twttr.txt.regexen.validSpecialCCTLD = regexSupplant(RegExp(
-+ '(?:(?:co|tv)(?=[^0-9a-zA-Z@]|$))'));
- twttr.txt.regexen.validDomain = regexSupplant(/(?:#{validSubdomain}*#{validDomainName}(?:#{validGTLD}|#{validCCTLD}|#{validPunycode}))/);
- twttr.txt.regexen.validAsciiDomain = regexSupplant(/(?:(?:[\-a-z0-9#{latinAccentChars}]+)\.)+(?:#{validGTLD}|#{validCCTLD}|#{validPunycode})/gi);
-- twttr.txt.regexen.invalidShortDomain = regexSupplant(/^#{validDomainName}#{validCCTLD}$/);
-+ twttr.txt.regexen.invalidShortDomain = regexSupplant(/^#{validDomainName}#{validCCTLD}$/i);
-+ twttr.txt.regexen.validSpecialShortDomain = regexSupplant(/^#{validDomainName}#{validSpecialCCTLD}$/i);
-
- twttr.txt.regexen.validPortNumber = regexSupplant(/[0-9]+/);
-
-- twttr.txt.regexen.validGeneralUrlPathChars = regexSupplant(/[a-z0-9!\*';:=\+,\.\$\/%#\[\]\-_~@|&#{latinAccentChars}]/i);
-- // Allow URL paths to contain balanced parens
-+ twttr.txt.regexen.cyrillicLettersAndMarks = regexSupplant("\u0400-\u04FF");
-+ twttr.txt.regexen.validGeneralUrlPathChars = regexSupplant(/[a-z#{cyrillicLettersAndMarks}0-9!\*';:=\+,\.\$\/%#\[\]\-_~@\|&#{latinAccentChars}]/i);
-+ // Allow URL paths to contain up to two nested levels of balanced parens
- // 1. Used in Wikipedia URLs like /Primer_(film)
- // 2. Used in IIS sessions like /S(dfd346)/
-- twttr.txt.regexen.validUrlBalancedParens = regexSupplant(/\(#{validGeneralUrlPathChars}+\)/i);
-+ // 3. Used in Rdio URLs like /track/We_Up_(Album_Version_(Edited))/
-+ twttr.txt.regexen.validUrlBalancedParens = regexSupplant(
-+ '\\(' +
-+ '(?:' +
-+ '#{validGeneralUrlPathChars}+' +
-+ '|' +
-+ // allow one nested level of balanced parentheses
-+ '(?:' +
-+ '#{validGeneralUrlPathChars}*' +
-+ '\\(' +
-+ '#{validGeneralUrlPathChars}+' +
-+ '\\)' +
-+ '#{validGeneralUrlPathChars}*' +
-+ ')' +
-+ ')' +
-+ '\\)'
-+ , 'i');
- // Valid end-of-path chracters (so /foo. does not gobble the period).
- // 1. Allow =&# for empty URL parameters and other URL-join artifacts
-- twttr.txt.regexen.validUrlPathEndingChars = regexSupplant(/[\+\-a-z0-9=_#\/#{latinAccentChars}]|(?:#{validUrlBalancedParens})/i);
-+ twttr.txt.regexen.validUrlPathEndingChars = regexSupplant(/[\+\-a-z#{cyrillicLettersAndMarks}0-9=_#\/#{latinAccentChars}]|(?:#{validUrlBalancedParens})/i);
- // Allow @ in a url, but only in the middle. Catch things like http://example.com/@user/
- twttr.txt.regexen.validUrlPath = regexSupplant('(?:' +
- '(?:' +
- '#{validGeneralUrlPathChars}*' +
- '(?:#{validUrlBalancedParens}#{validGeneralUrlPathChars}*)*' +
- '#{validUrlPathEndingChars}'+
- ')|(?:@#{validGeneralUrlPathChars}+\/)'+
- ')', 'i');
-@@ -304,17 +314,17 @@ var window = {};
- twttr.txt.regexen.urlHasProtocol = /^https?:\/\//i;
- twttr.txt.regexen.urlHasHttps = /^https:\/\//i;
-
- // cashtag related regex
- twttr.txt.regexen.cashtag = /[a-z]{1,6}(?:[._][a-z]{1,2})?/i;
- twttr.txt.regexen.validCashtag = regexSupplant('(^|#{spaces})(\\$)(#{cashtag})(?=$|\\s|[#{punct}])', 'gi');
-
- // These URL validation pattern strings are based on the ABNF from RFC 3986
-- twttr.txt.regexen.validateUrlUnreserved = /[a-z0-9\-._~]/i;
-+ twttr.txt.regexen.validateUrlUnreserved = /[a-z\u0400-\u04FF0-9\-._~]/i;
- twttr.txt.regexen.validateUrlPctEncoded = /(?:%[0-9a-f]{2})/i;
- twttr.txt.regexen.validateUrlSubDelims = /[!$&'()*+,;=]/i;
- twttr.txt.regexen.validateUrlPchar = regexSupplant('(?:' +
- '#{validateUrlUnreserved}|' +
- '#{validateUrlPctEncoded}|' +
- '#{validateUrlSubDelims}|' +
- '[:|@]' +
- ')', 'i');
-@@ -473,17 +483,17 @@ var window = {};
-
- twttr.txt.linkToHashtag = function(entity, text, options) {
- var hash = text.substring(entity.indices[0], entity.indices[0] + 1);
- var hashtag = twttr.txt.htmlEscape(entity.hashtag);
- var attrs = clone(options.htmlAttrs || {});
- attrs.href = options.hashtagUrlBase + hashtag;
- attrs.title = "#" + hashtag;
- attrs["class"] = options.hashtagClass;
-- if (hashtag[0].match(twttr.txt.regexen.rtl_chars)){
-+ if (hashtag.charAt(0).match(twttr.txt.regexen.rtl_chars)){
- attrs["class"] += " rtl";
- }
- if (options.targetBlank) {
- attrs.target = '_blank';
- }
-
- return twttr.txt.linkToTextWithSymbol(entity, hash, hashtag, attrs, options);
- };
-@@ -678,32 +688,44 @@ var window = {};
- }
- beginIndex = entity.indices[1];
- }
- result += nonEntity(text.substring(beginIndex, text.length));
- return result;
- };
-
- twttr.txt.autoLinkWithJSON = function(text, json, options) {
-+ // map JSON entity to twitter-text entity
-+ if (json.user_mentions) {
-+ for (var i = 0; i < json.user_mentions.length; i++) {
-+ // this is a @mention
-+ json.user_mentions[i].screenName = json.user_mentions[i].screen_name;
-+ }
-+ }
-+
-+ if (json.hashtags) {
-+ for (var i = 0; i < json.hashtags.length; i++) {
-+ // this is a #hashtag
-+ json.hashtags[i].hashtag = json.hashtags[i].text;
-+ }
-+ }
-+
-+ if (json.symbols) {
-+ for (var i = 0; i < json.symbols.length; i++) {
-+ // this is a $CASH tag
-+ json.symbols[i].cashtag = json.symbols[i].text;
-+ }
-+ }
-+
- // concatenate all entities
- var entities = [];
- for (var key in json) {
- entities = entities.concat(json[key]);
- }
-- // map JSON entity to twitter-text entity
-- for (var i = 0; i < entities.length; i++) {
-- entity = entities[i];
-- if (entity.screen_name) {
-- // this is @mention
-- entity.screenName = entity.screen_name;
-- } else if (entity.text) {
-- // this is #hashtag
-- entity.hashtag = entity.text;
-- }
-- }
-+
- // modify indices to UTF-16
- twttr.txt.modifyIndicesFromUnicodeToUTF16(text, entities);
-
- return twttr.txt.autoLinkEntities(text, entities, options);
- };
-
- twttr.txt.extractHtmlAttrsFromOptions = function(options) {
- var htmlAttrs = {};
-@@ -856,17 +878,16 @@ var window = {};
-
- return urlsOnly;
- };
-
- twttr.txt.extractUrlsWithIndices = function(text, options) {
- if (!options) {
- options = {extractUrlsWithoutProtocol: true};
- }
--
- if (!text || (options.extractUrlsWithoutProtocol ? !text.match(/\./) : !text.match(/:/))) {
- return [];
- }
-
- var urls = [];
-
- while (twttr.txt.regexen.extractUrl.exec(text)) {
- var before = RegExp.$2, url = RegExp.$3, protocol = RegExp.$4, domain = RegExp.$5, path = RegExp.$7;
-@@ -876,41 +897,38 @@ var window = {};
- // if protocol is missing and domain contains non-ASCII characters,
- // extract ASCII-only domains.
- if (!protocol) {
- if (!options.extractUrlsWithoutProtocol
- || before.match(twttr.txt.regexen.invalidUrlWithoutProtocolPrecedingChars)) {
- continue;
- }
- var lastUrl = null,
-- lastUrlInvalidMatch = false,
- asciiEndPosition = 0;
- domain.replace(twttr.txt.regexen.validAsciiDomain, function(asciiDomain) {
- var asciiStartPosition = domain.indexOf(asciiDomain, asciiEndPosition);
- asciiEndPosition = asciiStartPosition + asciiDomain.length;
- lastUrl = {
- url: asciiDomain,
- indices: [startPosition + asciiStartPosition, startPosition + asciiEndPosition]
- };
-- lastUrlInvalidMatch = asciiDomain.match(twttr.txt.regexen.invalidShortDomain);
-- if (!lastUrlInvalidMatch) {
-+ if (path
-+ || asciiDomain.match(twttr.txt.regexen.validSpecialShortDomain)
-+ || !asciiDomain.match(twttr.txt.regexen.invalidShortDomain)) {
- urls.push(lastUrl);
- }
- });
-
- // no ASCII-only domain found. Skip the entire URL.
- if (lastUrl == null) {
- continue;
- }
-
- // lastUrl only contains domain. Need to add path and query if they exist.
- if (path) {
-- if (lastUrlInvalidMatch) {
-- urls.push(lastUrl);
-- }
- lastUrl.url = url.replace(domain, lastUrl.url);
- lastUrl.indices[1] = endPosition;
- }
- } else {
- // In the case of t.co URLs, don't allow additional path characters.
- if (url.match(twttr.txt.regexen.validTcoUrl)) {
- url = RegExp.lastMatch;
- endPosition = startPosition + url.length;
-@@ -1194,30 +1212,30 @@ var window = {};
-
- // Returns the length of Tweet text with consideration to t.co URL replacement
- // and chars outside the basic multilingual plane that use 2 UTF16 code points
- twttr.txt.getTweetLength = function(text, options) {
- if (!options) {
- options = {
- // These come from https://api.twitter.com/1/help/configuration.json
- // described by https://dev.twitter.com/docs/api/1/get/help/configuration
-- short_url_length: 22,
-+ short_url_length: 23,
- short_url_length_https: 23
- };
- }
- var textLength = twttr.txt.getUnicodeTextLength(text),
- urlsWithIndices = twttr.txt.extractUrlsWithIndices(text);
- twttr.txt.modifyIndicesFromUTF16ToUnicode(text, urlsWithIndices);
-
- for (var i = 0; i < urlsWithIndices.length; i++) {
-- // Subtract the length of the original URL
-+ // Subtract the length of the original URL
- textLength += urlsWithIndices[i].indices[0] - urlsWithIndices[i].indices[1];
-
- // Add 23 characters for URL starting with https://
-- // Otherwise add 22 characters
-+ // http:// URLs still use https://t.co so they are 23 characters as well
- if (urlsWithIndices[i].url.toLowerCase().match(twttr.txt.regexen.urlHasHttps)) {
- textLength += options.short_url_length_https;
- } else {
- textLength += options.short_url_length;
- }
- }
-
- return textLength;
-@@ -1237,22 +1255,29 @@ var window = {};
- return "empty";
- }
-
- // Determine max length independent of URL length
- if (twttr.txt.getTweetLength(text) > MAX_LENGTH) {
- return "too_long";
- }
-
-+ if (twttr.txt.hasInvalidCharacters(text)) {
-+ return "invalid_characters";
-+ }
-+
-+ return false;
-+ };
-+
-+ twttr.txt.hasInvalidCharacters = function(text) {
- for (var i = 0; i < INVALID_CHARACTERS.length; i++) {
- if (text.indexOf(INVALID_CHARACTERS[i]) >= 0) {
-- return "invalid_characters";
-+ return true;
- }
- }
--
- return false;
- };
-
- twttr.txt.isValidTweetText = function(text) {
- return !twttr.txt.isInvalidTweet(text);
- };
-
- twttr.txt.isValidUsername = function(username) {
-@@ -1334,16 +1359,20 @@ var window = {};
- // RegExp["$&"] is the text of the last match
- return (!string || (string.match(regex) && RegExp["$&"] === string));
- }
-
- if (typeof module != 'undefined' && module.exports) {
- module.exports = twttr.txt;
- }
-
-+ if (typeof define == 'function' && define.amd) {
-+ define([], twttr.txt);
-+ }
-+
- if (typeof window != 'undefined') {
- if (window.twttr) {
- for (var prop in twttr) {
- window.twttr[prop] = twttr[prop];
- }
- } else {
- window.twttr = twttr;
- }
-# HG changeset patch
-# User Arlo Breault <arlolra@xxxxxxxxx>
-# Date 1458087794 25200
-# Tue Mar 15 17:23:14 2016 -0700
-# Branch THUNDERBIRD4530_2016082513_RELBRANCH
-# Node ID f1a6121c96fc353621c823b5d2757805fb65b721
-# Parent 9f2addccb7a8d4875746abd96f6beba38ef0f398
-Bug 955642 - Handle Twitter direct messages (DMs)
-
-diff --git a/chat/components/src/imConversations.js b/chat/components/src/imConversations.js
---- a/chat/components/src/imConversations.js
-+++ b/chat/components/src/imConversations.js
-@@ -25,16 +25,17 @@ OutgoingMessage.prototype = {
- action: false
- };
-
- function imMessage(aPrplMessage) {
- this.prplMessage = aPrplMessage;
- }
- imMessage.prototype = {
- __proto__: ClassInfo(["imIMessage", "prplIMessage"], "IM Message"),
-+ get wrappedJSObject() { return this; },
- cancelled: false,
- color: "",
- _displayMessage: null,
-
- get displayMessage() {
- // Explicitly test for null so that blank messages don't fall back to
- // the original. Especially problematic in encryption extensions like OTR.
- return this._displayMessage !== null ?
-@@ -409,17 +410,18 @@ UIConversation.prototype = {
- this._observers = this._observers.filter(o => o !== aObserver);
- },
- notifyObservers: function(aSubject, aTopic, aData) {
- if (aTopic == "new-text") {
- aSubject = new imMessage(aSubject);
- this.notifyObservers(aSubject, "received-message");
- if (aSubject.cancelled)
- return;
-- aSubject.conversation.prepareForDisplaying(aSubject);
-+ if (!aSubject.system)
-+ aSubject.conversation.prepareForDisplaying(aSubject);
-
- this._messages.push(aSubject);
- ++this._unreadMessageCount;
- if (aSubject.incoming && !aSubject.system) {
- ++this._unreadIncomingMessageCount;
- if (!this.isChat || aSubject.containsNick)
- ++this._unreadTargetedMessageCount;
- }
-diff --git a/chat/modules/jsProtoHelper.jsm b/chat/modules/jsProtoHelper.jsm
---- a/chat/modules/jsProtoHelper.jsm
-+++ b/chat/modules/jsProtoHelper.jsm
-@@ -376,16 +376,17 @@ var GenericAccountBuddyPrototype = {
- // aUserName is required only if aBuddy is null, i.e., we are adding a buddy.
- function AccountBuddy(aAccount, aBuddy, aTag, aUserName) {
- this._init(aAccount, aBuddy, aTag, aUserName);
- }
- AccountBuddy.prototype = GenericAccountBuddyPrototype;
-
- var GenericMessagePrototype = {
- __proto__: ClassInfo("prplIMessage", "generic message object"),
-+ get wrappedJSObject() { return this; },
-
- _lastId: 0,
- _init: function (aWho, aMessage, aObject) {
- this.id = ++GenericMessagePrototype._lastId;
- this.time = Math.round(new Date() / 1000);
- this.who = aWho;
- this.message = aMessage;
- this.originalMessage = aMessage;
-diff --git a/chat/protocols/twitter/twitter.js b/chat/protocols/twitter/twitter.js
---- a/chat/protocols/twitter/twitter.js
-+++ b/chat/protocols/twitter/twitter.js
-@@ -31,32 +31,40 @@ ChatBuddy.prototype = {
- let userInfo = this._account._userInfo.get(this.name);
- if (userInfo)
- return userInfo.profile_image_url;
- return undefined;
- },
- set buddyIconFilename(aName) {
- // Prevent accidental removal of the getter.
- throw("Don't set chatBuddy.buddyIconFilename directly for Twitter.");
-+ },
-+ createConversation: function() {
-+ return this._account.createConversation(this._name);
- }
--}
-+};
-
- function Tweet(aTweet, aWho, aMessage, aObject)
- {
- this._tweet = aTweet;
- this._init(aWho, aMessage, aObject);
- }
- Tweet.prototype = {
- __proto__: GenericMessagePrototype,
- _deleted: false,
- getActions: function(aCount) {
- let account = this.conversation._account;
- let actions = [];
-
-- if (account.connected) {
-+ if (!this.conversation.isChat) {
-+ if (aCount)
-+ aCount.value = actions.length;
-+ return actions;
-+ }
-+ else if (account.connected) {
- actions.push(
- new Action(_("action.reply"), function() {
- this.conversation.startReply(this._tweet);
- }, this)
- );
- if (this.incoming) {
- actions.push(
- new Action(_("action.retweet"), function() {
-@@ -118,17 +126,109 @@ function Action(aLabel, aAction, aTweet)
- this._action = aAction;
- this._tweet = aTweet;
- }
- Action.prototype = {
- __proto__: ClassInfo("prplIMessageAction", "generic message action object"),
- get run() { return this._action.bind(this._tweet); }
- };
-
--function Conversation(aAccount)
-+// Properties / methods shared by both DirectMessageConversation and
-+// TimelineConversation.
-+var GenericTwitterConversation = {
-+ getTweetLength: function (aString) {
-+ // Use the Twitter library to calculate the length.
-+ return twttr.txt.getTweetLength(aString, this._account.config);
-+ },
-+ systemMessage: function(aMessage, aIsError, aDate) {
-+ let flags = {system: true};
-+ if (aIsError)
-+ flags.error = true;
-+ if (aDate)
-+ flags.time = aDate;
-+ this.writeMessage("twitter.com", aMessage, flags);
-+ },
-+ onSentCallback: function(aMsg, aData) {
-+ // The conversation may have been unitialized in the time it takes for
-+ // the async callback to fire. Use `_observers` as a proxy for uninit'd.
-+ if (!Array.isArray(this._observers))
-+ return;
-+
-+ let tweet = JSON.parse(aData);
-+ // The OTR extension requires that the protocol not modify the message
-+ // (see the notes at `imIOutgoingMessage`). That's the contract we made.
-+ // Unfortunately, Twitter trims tweets and substitutes links.
-+ tweet.text = aMsg;
-+ this.displayMessages([tweet]);
-+ },
-+ prepareForDisplaying: function(aMsg) {
-+ let text = aMsg.displayMessage;
-+ let tweet = aMsg.wrappedJSObject.prplMessage.wrappedJSObject._tweet;
-+
-+ // Handle retweets: retweeted_status contains the object for the original
-+ // tweet that is being retweeted.
-+ // If the retweet prefix ("RT @<username>: ") causes the tweet to be over
-+ // 140 characters, ellipses will be added. In this case, we want to get
-+ // the FULL text from the original tweet and update the entities to match.
-+ // Note: the truncated flag is not always set correctly by twitter, so we
-+ // always make use of the original tweet.
-+ if ("retweeted_status" in tweet) {
-+ let retweet = tweet["retweeted_status"];
-+ // We're going to take portions of the retweeted status and replace parts
-+ // of the original tweet, the retweeted status prepends the original
-+ // status with "RT @<username>: ", we need to keep the prefix.
-+ // Note: this doesn't play nice with extensions that may have altered
-+ // `text` to this point, but at least OTR doesn't act on `isChat`.
-+ let offset = text.indexOf(": ") + 2;
-+ text = text.slice(0, offset) + retweet.text;
-+ }
-+
-+ // Pass in the url entities so the t.co links are replaced.
-+ aMsg.displayMessage = twttr.txt.autoLink(text, {
-+ urlEntities: tweet.entities.urls.map(function(u) {
-+ var o = Object.assign(u);
-+ // But remove the indices so they apply in the face of modifications.
-+ delete o.indices;
-+ return o;
-+ })
-+ });
-+
-+ GenericConversationPrototype.prepareForDisplaying.apply(this, arguments);
-+ },
-+ displayTweet: function(aTweet, aUser) {
-+ let name = aUser.screen_name;
-+
-+ let flags = name == this.nick ? {outgoing: true} : {incoming: true};
-+ flags.time = Math.round(new Date(aTweet.created_at) / 1000);
-+ flags._iconURL = aUser.profile_image_url;
-+ if (aTweet.delayed)
-+ flags.delayed = true;
-+ if (aTweet.entities && aTweet.entities.user_mentions &&
-+ Array.isArray(aTweet.entities.user_mentions) &&
-+ aTweet.entities.user_mentions.some(mention => mention.screen_name == this.nick))
-+ flags.containsNick = true;
-+
-+ (new Tweet(aTweet, name, aTweet.text, flags)).conversation = this;
-+ },
-+ _parseError: function(aData) {
-+ let error = "";
-+ try {
-+ let data = JSON.parse(aData);
-+ if ("error" in data)
-+ error = data.error;
-+ else if ("errors" in data)
-+ error = data.errors[0].message;
-+ if (error)
-+ error = "(" + error + ")";
-+ } catch(e) {}
-+ return error;
-+ }
-+};
-+
-+function TimelineConversation(aAccount)
- {
- this._init(aAccount);
- this._ensureParticipantExists(aAccount.name);
- // We need the screen names for the IDs in _friends, but _userInfo is
- // indexed by name, so we build an ID -> name map.
- let entries = [];
- for (let [name, userInfo] of aAccount._userInfo) {
- entries.push([userInfo.id_str, name]);
-@@ -139,17 +239,17 @@ function Conversation(aAccount)
-
- // If the user's info has already been received, update the timeline topic.
- if (aAccount._userInfo.has(aAccount.name)) {
- let userInfo = aAccount._userInfo.get(aAccount.name);
- if ("description" in userInfo)
- this.setTopic(userInfo.description, aAccount.name, true);
- }
- }
--Conversation.prototype = {
-+TimelineConversation.prototype = {
- __proto__: GenericConvChatPrototype,
- unInit: function() {
- delete this._account._timeline;
- GenericConvChatPrototype.unInit.call(this);
- },
- inReplyToStatusId: null,
- startReply: function(aTweet) {
- this.inReplyToStatusId = aTweet.id_str;
-@@ -169,203 +269,66 @@ Conversation.prototype = {
- .map(aNick => "@" + aNick)
- .join(" ") + " ";
-
- this.notifyObservers(null, "replying-to-prompt", prompt);
- this.notifyObservers(null, "status-text-changed",
- _("replyingToStatusText", aTweet.text));
- },
- reTweet: function(aTweet) {
-- this._account.reTweet(aTweet, this.onSentCallback,
-- function(aException, aData) {
-+ this._account.reTweet(aTweet, null, function(aException, aData) {
- this.systemMessage(_("error.retweet", this._parseError(aData),
- aTweet.text), true);
- }, this);
- },
-- getTweetLength: function (aString) {
-- // Use the Twitter library to calculate the length.
-- return twttr.txt.getTweetLength(aString, this._account.config);
-- },
-- sendMsg: function (aMsg) {
-+ sendMsg: function(aMsg) {
- if (this.getTweetLength(aMsg) > kMaxMessageLength) {
- this.systemMessage(_("error.tooLong"), true);
- throw Cr.NS_ERROR_INVALID_ARG;
- }
-- this._account.tweet(aMsg, this.inReplyToStatusId, this.onSentCallback,
-+ this._account.tweet(aMsg, this.inReplyToStatusId,
-+ this.onSentCallback.bind(this, aMsg),
- function(aException, aData) {
- let error = this._parseError(aData);
- this.systemMessage(_("error.general", error, aMsg), true);
- }, this);
- this.sendTyping("");
- },
- sendTyping: function(aString) {
- if (aString.length == 0 && this.inReplyToStatusId) {
- delete this.inReplyToStatusId;
- this.notifyObservers(null, "status-text-changed", "");
- return kMaxMessageLength;
- }
- return kMaxMessageLength - this.getTweetLength(aString);
- },
-- systemMessage: function(aMessage, aIsError, aDate) {
-- let flags = {system: true};
-- if (aIsError)
-- flags.error = true;
-- if (aDate)
-- flags.time = aDate;
-- this.writeMessage("twitter.com", aMessage, flags);
-- },
-- onSentCallback: function(aData) {
-- let tweet = JSON.parse(aData);
-- if (tweet.user.screen_name != this._account.name)
-- throw "Wrong screen_name... Uh?";
-- this._account.displayMessages([tweet]);
-- },
-- _parseError: function(aData) {
-- let error = "";
-- try {
-- let data = JSON.parse(aData);
-- if ("error" in data)
-- error = data.error;
-- else if ("errors" in data)
-- error = data.errors[0].message;
-- if (error)
-- error = "(" + error + ")";
-- } catch(e) {}
-- return error;
-- },
-- parseTweet: function(aTweet) {
-- let text = aTweet.text;
-- let entities = {};
-- // Handle retweets: retweeted_status contains the object for the original
-- // tweet that is being retweeted.
-- // If the retweet prefix ("RT @<username>: ") causes the tweet to be over
-- // 140 characters, ellipses will be added. In this case, we want to get
-- // the FULL text from the original tweet and update the entities to match.
-- // Note: the truncated flag is not always set correctly by twitter, so we
-- // always make use of the original tweet.
-- if ("retweeted_status" in aTweet) {
-- let retweet = aTweet["retweeted_status"];
-- // We're going to take portions of the retweeted status and replace parts
-- // of the original tweet, the retweeted status prepends the original
-- // status with "RT @<username>: ", we need to keep the prefix.
-- let offset = text.indexOf(": ") + 2;
-- text = text.slice(0, offset) + retweet.text;
--
-- // Keep any entities that refer to the prefix (we can refer directly to
-- // aTweet for these since they are not edited).
-- if ("entities" in aTweet) {
-- for (let type in aTweet.entities) {
-- let filteredEntities =
-- aTweet.entities[type].filter(e => e.indices[0] < offset);
-- if (filteredEntities.length)
-- entities[type] = filteredEntities;
-- }
-- }
--
-- // Add the entities from the retweet (a copy of these must be made since
-- // they will be edited and we do not wish to change aTweet).
-- if ("entities" in retweet) {
-- for (let type in retweet.entities) {
-- if (!(type in entities))
-- entities[type] = [];
-+ displayMessages: function(aMessages) {
-+ let account = this._account;
-+ let lastMsgId = account._lastMsgId;
-+ for (let tweet of aMessages) {
-+ if (!("user" in tweet) || !("text" in tweet) || !("id_str" in tweet) ||
-+ account._knownMessageIds.has(tweet.id_str))
-+ continue;
-+ let id = tweet.id_str;
-+ // Update the last known message.
-+ // Compare the length of the ids first, and then the text.
-+ // This avoids converting tweet ids into rounded numbers.
-+ if (id.length > lastMsgId.length ||
-+ (id.length == lastMsgId.length && id > lastMsgId))
-+ lastMsgId = id;
-+ account._knownMessageIds.add(id);
-+ account.setUserInfo(tweet.user);
-
-- // Append the entities from the original status.
-- entities[type] = entities[type].concat(
-- retweet.entities[type].map(function(aEntity) {
-- let entity = Object.create(aEntity);
-- // Add the offset to the indices to account for the prefix.
-- entity.indices = entity.indices.map(i => i + offset);
-- return entity;
-- })
-- );
-- }
-- }
-- } else {
-- // For non-retweets, we just want to use the entities that are given.
-- if ("entities" in aTweet)
-- entities = aTweet.entities;
-+ this._ensureParticipantExists(tweet.user.screen_name);
-+ this.displayTweet(tweet, tweet.user);
- }
--
-- if (Object.keys(entities).length) {
-- /* entArray is an array of entities ready to be replaced in the tweet,
-- * each entity contains:
-- * - start: the start index of the entity inside the tweet,
-- * - end: the end index of the entity inside the tweet,
-- * - str: the string that should be replaced inside the tweet,
-- * - href: the url (href attribute) of the created link tag,
-- * - [optional] text: the text to display for the link,
-- * The original string (str) will be used if this is not set.
-- * - [optional] title: the title attribute for the link.
-- */
-- let entArray = [];
-- if ("hashtags" in entities && Array.isArray(entities.hashtags)) {
-- entArray = entArray.concat(entities.hashtags.map(h => ({
-- start: h.indices[0],
-- end: h.indices[1],
-- str: "#" + h.text,
-- href: "https://twitter.com/#!/search?q=%23" + h.text})));
-- }
-- if ("urls" in entities && Array.isArray(entities.urls)) {
-- entArray = entArray.concat(entities.urls.map(u => ({
-- start: u.indices[0],
-- end: u.indices[1],
-- str: u.url,
-- text: u.display_url || u.url,
-- href: u.expanded_url || u.url})));
-- }
-- if ("user_mentions" in entities &&
-- Array.isArray(entities.user_mentions)) {
-- entArray = entArray.concat(entities.user_mentions.map(um => ({
-- start: um.indices[0],
-- end: um.indices[1],
-- str: "@" + um.screen_name,
-- text: '@<span class="ib-person">' + um.screen_name + "</span>",
-- title: um.name,
-- href: "https://twitter.com/" + um.screen_name})));
-- }
-- entArray.sort((a, b) => a.start - b.start);
-- let offset = 0;
-- for (let entity of entArray) {
-- let str = text.substring(offset + entity.start, offset + entity.end);
-- if (str[0] == "\uFF20") // ï¼ - unicode character similar to @
-- str = "@" + str.substring(1);
-- if (str[0] == "\uFF03") // ï¼? - unicode character similar to #
-- str = "#" + str.substring(1);
-- if (str.toLowerCase() != entity.str.toLowerCase())
-- continue;
--
-- let html = "<a href=\"" + entity.href + "\"";
-- if ("title" in entity)
-- html += " title=\"" + entity.title + "\"";
-- html += ">" + ("text" in entity ? entity.text : entity.str) + "</a>";
-- text = text.slice(0, offset + entity.start) + html +
-- text.slice(offset + entity.end);
-- offset += html.length - (entity.end - entity.start);
-- }
-+ if (lastMsgId != account._lastMsgId) {
-+ account._lastMsgId = lastMsgId;
-+ account.prefs.setCharPref("lastMessageId", account._lastMsgId);
- }
--
-- return text;
-- },
-- displayTweet: function(aTweet) {
-- let name = aTweet.user.screen_name;
-- this._ensureParticipantExists(name);
-- let text = this.parseTweet(aTweet);
--
-- let flags =
-- name == this._account.name ? {outgoing: true} : {incoming: true};
-- flags.time = Math.round(new Date(aTweet.created_at) / 1000);
-- flags._iconURL = aTweet.user.profile_image_url;
-- if (aTweet.delayed)
-- flags.delayed = true;
-- if (aTweet.entities && aTweet.entities.user_mentions &&
-- Array.isArray(aTweet.entities.user_mentions) &&
-- aTweet.entities.user_mentions.some(mention => mention.screen_name == this.nick))
-- flags.containsNick = true;
--
-- (new Tweet(aTweet, name, text, flags)).conversation = this;
- },
- _ensureParticipantExists: function(aNick) {
- if (this._participants.has(aNick))
- return;
-
- let chatBuddy = new ChatBuddy(aNick, this._account);
- this._participants.set(aNick, chatBuddy);
- this.notifyObservers(new nsSimpleEnumerator([chatBuddy]),
-@@ -377,23 +340,60 @@ Conversation.prototype = {
- set nick(aNick) {},
- get topicSettable() { return this.nick == this._account.name; },
- get topic() { return this._topic; }, // can't add a setter without redefining the getter
- set topic(aTopic) {
- if (this.topicSettable)
- this._account.setUserDescription(aTopic);
- }
- };
-+Object.assign(TimelineConversation.prototype, GenericTwitterConversation);
-+
-+function DirectMessageConversation(aAccount, aName)
-+{
-+ this._init(aAccount, aName);
-+}
-+DirectMessageConversation.prototype = {
-+ __proto__: GenericConvIMPrototype,
-+ sendMsg: function(aMsg) {
-+ this._account.directMessage(aMsg, this.name,
-+ this.onSentCallback.bind(this, aMsg),
-+ function(aException, aData) {
-+ let error = this._parseError(aData);
-+ this.systemMessage(_("error.general", error, aMsg), true);
-+ }, this);
-+ },
-+ displayMessages: function(aMessages) {
-+ let account = this._account;
-+ for (let tweet of aMessages) {
-+ if (!("sender" in tweet) || !("recipient" in tweet) ||
-+ !("text" in tweet) || !("id_str" in tweet))
-+ continue;
-+ account.setUserInfo(tweet.sender);
-+ account.setUserInfo(tweet.recipient);
-+ this.displayTweet(tweet, tweet.sender);
-+ }
-+ },
-+ unInit: function() {
-+ this._account.removeConversation(this.name);
-+ GenericConvIMPrototype.unInit.call(this);
-+ },
-+ get nick() { return this._account.name; },
-+ set nick(aNick) {}
-+}
-+Object.assign(DirectMessageConversation.prototype, GenericTwitterConversation);
-
- function Account(aProtocol, aImAccount)
- {
- this._init(aProtocol, aImAccount);
- this._knownMessageIds = new Set();
- this._userInfo = new Map();
- this._friends = new Set();
-+ // Contains just `DirectMessageConversation`s
-+ this._conversations = new Map();
- }
- Account.prototype = {
- __proto__: GenericAccountPrototype,
-
- // The correct normalization for twitter would be just toLowerCase().
- // Unfortunately, for backwards compatibility we retain this normalization,
- // which can cause edge cases for usernames with underscores.
- normalize: aString => aString.replace(/[^a-z0-9]/gi, "").toLowerCase(),
-@@ -554,16 +554,21 @@ Account.prototype = {
- reTweet: function(aTweet, aOnSent, aOnError, aThis) {
- let url = "1.1/statuses/retweet/" + aTweet.id_str + ".json";
- this.signAndSend(url, null, [], aOnSent, aOnError, aThis);
- },
- destroy: function(aTweet, aOnSent, aOnError, aThis) {
- let url = "1.1/statuses/destroy/" + aTweet.id_str + ".json";
- this.signAndSend(url, null, [], aOnSent, aOnError, aThis);
- },
-+ directMessage: function(aMsg, aName, aOnSent, aOnError, aThis) {
-+ let POSTData = [["text", aMsg], ["screen_name", aName]];
-+ this.signAndSend("1.1/direct_messages/new.json", null, POSTData, aOnSent,
-+ aOnError, aThis);
-+ },
-
- _friends: null,
- follow: function(aUserName) {
- this.signAndSend("1.1/friendships/create.json", null,
- [["screen_name", aUserName]]);
- },
- stopFollowing: function(aUserName) {
- // friendships/destroy will return the user in case of success.
-@@ -616,39 +621,17 @@ Account.prototype = {
- getParams = "?q=" + trackQuery + lastMsgParam + "&count=100";
- let url = "1.1/search/tweets.json" + getParams;
- this._pendingRequests.push(
- this.signAndSend(url, null, null, this.onTimelineReceived,
- this.onTimelineError, this, null));
- }
- },
-
-- get timeline() { return this._timeline || (this._timeline = new Conversation(this)); },
-- displayMessages: function(aMessages) {
-- let lastMsgId = this._lastMsgId;
-- for (let tweet of aMessages) {
-- if (!("user" in tweet) || !("text" in tweet) || !("id_str" in tweet) ||
-- this._knownMessageIds.has(tweet.id_str))
-- continue;
-- let id = tweet.id_str;
-- // Update the last known message.
-- // Compare the length of the ids first, and then the text.
-- // This avoids converting tweet ids into rounded numbers.
-- if (id.length > lastMsgId.length ||
-- (id.length == lastMsgId.length && id > lastMsgId))
-- lastMsgId = id;
-- this._knownMessageIds.add(id);
-- this.setUserInfo(tweet.user);
-- this.timeline.displayTweet(tweet);
-- }
-- if (lastMsgId != this._lastMsgId) {
-- this._lastMsgId = lastMsgId;
-- this.prefs.setCharPref("lastMessageId", this._lastMsgId);
-- }
-- },
-+ get timeline() { return this._timeline || (this._timeline = new TimelineConversation(this)); },
-
- onTimelineError: function(aError, aResponseText, aRequest) {
- this.ERROR(aError);
- if (aRequest.status == 401)
- ++this._timelineAuthError;
- this._doneWithTimelineRequest(aRequest);
- },
-
-@@ -686,17 +669,17 @@ Account.prototype = {
- this.reportConnected();
-
- // If the conversation already exists, notify it we are back online.
- if (this._timeline)
- this._timeline.notifyObservers(this._timeline, "update-buddy-status");
-
- this._timelineBuffer.sort(this.sortByDate);
- this._timelineBuffer.forEach(aTweet => aTweet.delayed = true);
-- this.displayMessages(this._timelineBuffer);
-+ this.timeline.displayMessages(this._timelineBuffer);
-
- // Fetch userInfo for the user if we don't already have it.
- this.requestBuddyInfo(this.name);
-
- // Reset in case we get disconnected
- delete this._timelineBuffer;
- delete this._pendingRequests;
-
-@@ -748,18 +731,23 @@ Account.prototype = {
- continue;
- let msg;
- try {
- msg = JSON.parse(message);
- } catch (e) {
- this.ERROR(e + " while parsing " + message);
- continue;
- }
-- if ("text" in msg)
-- this.displayMessages([msg]);
-+ if ("direct_message" in msg) {
-+ let dm = msg["direct_message"];
-+ if (dm.sender_screen_name !== this.name) // These are displayed on send.
-+ this.getConversation(dm.sender_screen_name).displayMessages([dm]);
-+ }
-+ else if ("text" in msg)
-+ this.timeline.displayMessages([msg]);
- else if ("friends" in msg) {
- // Filter out the IDs that info has already been received from (e.g. a
- // tweet has been received as part of the timeline request).
- let userInfoIds = new Set();
- for (let userInfo of this._userInfo.values())
- userInfoIds.add(userInfo.id_str);
- let ids = msg.friends.filter(
- aId => !userInfoIds.has(aId.toString()));
-@@ -1102,16 +1090,29 @@ Account.prototype = {
- this.config = JSON.parse(aData);
- },
-
- // Allow us to reopen the timeline via the join chat menu.
- get canJoinChat() { return true; },
- joinChat: function(aComponents) {
- // The 'timeline' getter opens a timeline conversation if none exists.
- this.timeline;
-+ },
-+
-+ getConversation: function(aName) {
-+ if (!this._conversations.has(aName))
-+ this._conversations.set(aName, new DirectMessageConversation(this, aName));
-+ return this._conversations.get(aName);
-+ },
-+ removeConversation: function(aName) {
-+ if (this._conversations.has(aName))
-+ this._conversations.delete(aName);
-+ },
-+ createConversation: function(aName) {
-+ return this.getConversation(aName);
- }
- };
-
- // Shortcut to get the JavaScript account object.
- function getAccount(aConv) { return aConv.wrappedJSObject._account; }
-
- function TwitterProtocol() {
- this.registerCommands();
-# HG changeset patch
-# User Arlo Breault <arlolra@xxxxxxxxx>
-# Date 1472492642 25200
-# Mon Aug 29 10:44:02 2016 -0700
-# Branch THUNDERBIRD4530_2016082513_RELBRANCH
-# Node ID 600363f6a85a72e0ef6ccf104b6bc5c8b4f9a0c0
-# Parent f1a6121c96fc353621c823b5d2757805fb65b721
-Remove backwards compat. normalize in twitter prpl
-
- * Just use .toLowerCase()
-
-diff --git a/chat/protocols/twitter/twitter.js b/chat/protocols/twitter/twitter.js
---- a/chat/protocols/twitter/twitter.js
-+++ b/chat/protocols/twitter/twitter.js
-@@ -388,21 +388,16 @@ function Account(aProtocol, aImAccount)
- this._userInfo = new Map();
- this._friends = new Set();
- // Contains just `DirectMessageConversation`s
- this._conversations = new Map();
- }
- Account.prototype = {
- __proto__: GenericAccountPrototype,
-
-- // The correct normalization for twitter would be just toLowerCase().
-- // Unfortunately, for backwards compatibility we retain this normalization,
-- // which can cause edge cases for usernames with underscores.
-- normalize: aString => aString.replace(/[^a-z0-9]/gi, "").toLowerCase(),
--
- consumerKey: Services.prefs.getCharPref("chat.twitter.consumerKey"),
- consumerSecret: Services.prefs.getCharPref("chat.twitter.consumerSecret"),
- completionURI: "http://oauthcallback.local/",
- baseURI: "https://api.twitter.com/",
- _lastMsgId: "",
-
- // Use this to keep track of the pending timeline requests. We attempt to fetch
- // home_timeline, @ mentions and tracked keywords (i.e. 3 timelines)
diff --git a/projects/instantbird/trac-16489.patch b/projects/instantbird/trac-16489.patch
deleted file mode 100644
index 4d58846..0000000
--- a/projects/instantbird/trac-16489.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-# HG changeset patch
-# User Arlo Breault <arlolra@xxxxxxxxx>
-# Date 1447735073 28800
-# Mon Nov 16 20:37:53 2015 -0800
-# Node ID dd2cd9b18e3a356e227d02beec052f8591509cec
-# Parent 073468887b0faecb810a6e4463a2806924fead81
-trac 16489 - autologin
-
-diff --git a/chat/components/src/imAccounts.js b/chat/components/src/imAccounts.js
---- a/chat/components/src/imAccounts.js
-+++ b/chat/components/src/imAccounts.js
-@@ -588,7 +588,7 @@
- },
-
- get autoLogin() {
-- let autoLogin = true;
-+ let autoLogin = false;
- try {
- autoLogin = this.prefBranch.getBoolPref(kPrefAccountAutoLogin);
- } catch (e) { }
-diff --git a/im/content/account.xml b/im/content/account.xml
---- a/im/content/account.xml
-+++ b/im/content/account.xml
-@@ -41,10 +41,6 @@
- accesskey="&certmgr.addException.accesskey;"/>
- <xul:spacer flex="1"/>
- </xul:vbox>
-- <xul:checkbox label="&account.autoSignOn.label;" dir="reverse"
-- xbl:inherits="checked=autologin" class="autoSignOn"
-- accesskey="&account.autoSignOn.accesskey;"
-- oncommand="gAccountManager.autologin()"/>
- </xul:hbox>
- <xul:hbox flex="1" class="account-buttons" anonid="buttons"
- xbl:inherits="autologin"/>
-diff --git a/im/content/accountWizard.js b/im/content/accountWizard.js
---- a/im/content/accountWizard.js
-+++ b/im/content/accountWizard.js
-@@ -442,22 +442,13 @@
- throw "unknown type";
- }
- }
-- let autologin = this.getValue("connectAutomatically");
-- acc.autoLogin = autologin;
-+ acc.autoLogin = false;
-
- if (this.proto.usePurpleProxy)
- acc.proxyInfo = this.proxy;
-
- acc.save();
-
-- try {
-- if (autologin)
-- acc.connect();
-- } catch (e) {
-- // If the connection fails (for example if we are currently in
-- // offline mode), we still want to close the account wizard
-- }
--
- if (window.opener) {
- let am = window.opener.gAccountManager;
- if (am)
-diff --git a/im/content/accountWizard.xul b/im/content/accountWizard.xul
---- a/im/content/accountWizard.xul
-+++ b/im/content/accountWizard.xul
-@@ -137,8 +137,6 @@
- </columns>
- <rows id="summaryRows"/>
- </grid>
-- <separator/>
-- <checkbox id="connectAutomatically" label= "&accountSummary.connectAutomatically.label;" checked="true"/>
- </wizardpage>
-
- </wizard>
-diff --git a/im/content/preferences/main.xul b/im/content/preferences/main.xul
---- a/im/content/preferences/main.xul
-+++ b/im/content/preferences/main.xul
-@@ -20,7 +20,6 @@
- <script type="application/javascript" src="chrome://instantbird/content/preferences/main.js"/>
-
- <preferences id="mainPreferences">
-- <preference id="messenger.startup.action" name="messenger.startup.action" type="int"/>
- <preference id="messenger.options.playSounds.blist" name="messenger.options.playSounds.blist" type="bool"/>
- <preference id="messenger.options.playSounds.message" name="messenger.options.playSounds.message" type="bool"/>
- <preference id="messenger.options.getAttentionOnNewMessages" name="messenger.options.getAttentionOnNewMessages" type="bool"/>
-@@ -33,23 +32,6 @@
- <preference id="messenger.options.notifyOfNewMessages" name="messenger.options.notifyOfNewMessages" type="bool"/>
- </preferences>
-
-- <!-- Startup -->
-- <groupbox id="startupGroup">
-- <caption label="&startup.label;"/>
--
-- <hbox align="center">
-- <label value="&startupAction.label;" accesskey="&startupAction.accesskey;"
-- control="messengerStartupAction"/>
-- <menulist id="messengerStartupAction" preference="messenger.startup.action">
-- <menupopup>
-- <menuitem label="&startupOffline.label;" value="0"/>
-- <menuitem label="&startupConnectAuto.label;" value="1"/>
-- </menupopup>
-- </menulist>
-- </hbox>
-- </groupbox>
--
--
- <groupbox id="accountsMgrGroup" orient="horizontal" align="center">
- <caption label="&accountsMgr.label;"/>
-
diff --git a/projects/instantbird/trac-17494.patch b/projects/instantbird/trac-17494.patch
deleted file mode 100644
index fcd7703..0000000
--- a/projects/instantbird/trac-17494.patch
+++ /dev/null
@@ -1,83 +0,0 @@
-# HG changeset patch
-# User Arlo Breault <arlolra@xxxxxxxxx>
-# Date 1454457891 28800
-# Node ID 4cfc2a04ebe02f53d789c7c27f8c3cd2a40b6483
-# Parent 19694424a48639d4f9ca458e3e891292e0c2ae1e
-Bug 1245325 - Better error reporting for failed outgoing messages. r=clokep
-
-diff --git a/chat/locales/en-US/xmpp.properties b/chat/locales/en-US/xmpp.properties
---- a/chat/locales/en-US/xmpp.properties
-+++ b/chat/locales/en-US/xmpp.properties
-@@ -61,31 +61,33 @@ conversation.error.changeTopicFailedNotA
- # %2$S is the text of the message that wasn't delivered.
- conversation.error.sendFailedAsNotInRoom=Message could not be sent to %1$S as you are no longer in the room: %2$S
- # This is displayed in a conversation as an error message when the user sends
- # a message to a room that the recipient is not in.
- # %1$S is the jid of the recipient.
- # %2$S is the text of the message that wasn't delivered.
- conversation.error.sendFailedAsRecipientNotInRoom=Message could not be sent to %1$S as the recipient is no longer in the room: %2$S
- # These are displayed in a conversation as a system error message.
--conversation.error.remoteServerNotFound=Could not reach the recipient's server
-+conversation.error.remoteServerNotFound=Could not reach the recipient's server.
-+conversation.error.unknownSendError=An unknown error occurred on sending this message.
-+# %S is the name of the message recipient.
-+conversation.error.sendServiceUnavailable=It is not possible to send messages to %S at this time.
- # %S is the nick of participant that is not in room.
- conversation.error.nickNotInRoom=%S is not in the room.
- conversation.error.banCommandAnonymousRoom=You can't ban participants from anonymous rooms. Try /kick instead.
- conversation.error.banKickCommandNotAllowed=You don't have the required privileges to remove this participant from the room.
- conversation.error.banKickCommandConflict=Sorry, you can't remove yourself from the room.
- conversation.error.changeNickFailedConflict=Could not change your nick to %S as this nick is already in use.
- conversation.error.changeNickFailedNotAcceptable=Could not change your nick to %S as nicks are locked down in this room.
- conversation.error.inviteFailedForbidden=You don't have the required privileges to invite users to this room.
- # %S is the jid of user that is invited.
- conversation.error.failedJIDNotFound=Could not reach %S.
- # %S is the jid that is invalid.
- conversation.error.invalidJID=%S is an invalid jid (Jabber identifiers must be of the form user@domain).
- conversation.error.commandFailedNotInRoom=You have to rejoin the room to be able to use this command.
--conversation.error.unknownError=Unknown error
-
- # LOCALIZATION NOTE (tooltip.*):
- # These are the titles of lines of information that will appear in
- # the tooltip showing details about a contact or conversation.
- # LOCALIZATION NOTE (tooltip.status):
- # %S will be replaced by the XMPP resource identifier
- tooltip.status=Status (%S)
- tooltip.statusNoResource=Status
-diff --git a/chat/protocols/xmpp/xmpp.jsm b/chat/protocols/xmpp/xmpp.jsm
---- a/chat/protocols/xmpp/xmpp.jsm
-+++ b/chat/protocols/xmpp/xmpp.jsm
-@@ -674,21 +674,28 @@ var XMPPConversationPrototype = {
- this._targetResource = this._account._parseJID(from).resource;
- let flags = {};
- let error = this._account.parseError(aStanza);
- if (error) {
- let norm = this._account.normalize(from);
- let muc = this._account._mucs.get(norm);
-
- if (!aMsg) {
-- // Failed outgoing message unknown.
-- if (error.condition == "remote-server-not-found")
-- aMsg = _("conversation.error.remoteServerNotFound");
-- else
-- aMsg = _("conversation.error.unknownError");
-+ // Failed outgoing message.
-+ switch (error.condition) {
-+ case "remote-server-not-found":
-+ aMsg = _("conversation.error.remoteServerNotFound");
-+ break;
-+ case "service-unavailable":
-+ aMsg = _("conversation.error.sendServiceUnavailable", this.shortName);
-+ break;
-+ default:
-+ aMsg = _("conversation.error.unknownSendError");
-+ break;
-+ }
- }
- else if (this._isMucParticipant && muc && !muc.left &&
- error.condition == "item-not-found") {
- // XEP-0045 (7.5): MUC private messages.
- // If we try to send to participant not in a room we are in.
- aMsg = _("conversation.error.sendFailedAsRecipientNotInRoom",
- this._targetResource, aMsg);
- }
diff --git a/projects/instantbird/trac-17896.patch b/projects/instantbird/trac-17896.patch
deleted file mode 100644
index ebef6e4..0000000
--- a/projects/instantbird/trac-17896.patch
+++ /dev/null
@@ -1,67 +0,0 @@
-# HG changeset patch
-# User aleth <aleth@xxxxxxxxxxxxxxx>
-# Date 1454183798 -3600
-# Sat Jan 30 20:56:38 2016 +0100
-# Node ID 6eac77f5536560efd9028d80faa8df716d20907a
-# Parent bd360247708a91a220b79303b4c0f59be61520f9
-Bug 1151784 - Add Edit menu to the conversation window on OS X. r=nhnt11,florian
-
-Adding an edit menu also enables the emoji panel and dictation.
-
-diff --git a/im/content/instantbird.xul b/im/content/instantbird.xul
---- a/im/content/instantbird.xul
-+++ b/im/content/instantbird.xul
-@@ -48,7 +48,28 @@
- <script type="application/javascript" src="chrome://instantbird/content/nsContextMenu.js"/>
-
- #ifdef XP_MACOSX
--#include menus.xul.inc
-+# As menus.xul.inc, but with an Edit menu.
-+ <commandset id="maincommandset"/>
-+ <keyset id="mainkeyset"/>
-+ <menubar id="blistMenubar">
-+ <menu id="menu_edit">
-+ <menupopup id="menu_editpopup">
-+ <menuitem id="menu_undo"/>
-+ <menuitem id="menu_redo"/>
-+ <menuseparator/>
-+ <menuitem id="menu_cut"/>
-+ <menuitem id="menu_copy"/>
-+ <menuitem id="menu_paste"/>
-+ <menuitem id="menu_delete"/>
-+ <menuseparator/>
-+ <menuitem id="menu_selectAll"/>
-+ <menuseparator/>
-+ <menuitem id="menu_find"/>
-+ <menuitem id="menu_findAgain"/>
-+ </menupopup>
-+ </menu>
-+ </menubar>
-+ <popupset id="mainPopupSet"/>
- #endif
-
- <commandset id="conversationsCommands">
-diff --git a/im/content/menus.xul b/im/content/menus.xul
---- a/im/content/menus.xul
-+++ b/im/content/menus.xul
-@@ -43,7 +43,7 @@
- </keyset>
-
- <menubar id="blistMenubar">
-- <menu label="&file.menu;" id="fileMenu" accesskey="&file.accesskey;">
-+ <menu label="&file.menu;" id="fileMenu" accesskey="&file.accesskey;" insertbefore="menu_edit">
- <menupopup id="fileMenuPopup" onpopupshowing="menus.updateFileMenuitems();">
- <menuitem id="addBuddyMenuItem" label="&addContact;" command="cmd_addbuddy" key="addBuddykey" accesskey="&addContact.accesskey;"/>
- <menuitem id="newTabMenuItem" label="&newtab;" command="cmd_newtab" key="newtabkey" accesskey="&newtab.accesskey;"/>
-diff --git a/im/content/menus.xul.inc b/im/content/menus.xul.inc
---- a/im/content/menus.xul.inc
-+++ b/im/content/menus.xul.inc
-@@ -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/.
-
-+# Note instantbird.xul contains a modified copy of this file that
-+# should be kept in sync.
- <commandset id="maincommandset"/>
- <keyset id="mainkeyset"/>
- <menubar id="blistMenubar"/>
diff --git a/projects/instantbird/trac-20207.patch b/projects/instantbird/trac-20207.patch
deleted file mode 100644
index b7720b9..0000000
--- a/projects/instantbird/trac-20207.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From c57457ede9853527f529fd4dd1337ede51f4f312 Mon Sep 17 00:00:00 2001
-From: Vu Quoc Huy <huyvq.c633@xxxxxxxxx>
-Date: Tue, 11 Oct 2016 10:30:40 +0700
-Subject: [PATCH] Change CFBundleIdentifier to prevent notification sharing on
- macOS
-
-* Resolve ticket #20207
----
- im/app/macbuild/Contents/Info.plist.in | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/im/app/macbuild/Contents/Info.plist.in b/im/app/macbuild/Contents/Info.plist.in
-index dc048c0..78a5305 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>
---
-2.7.4
-
diff --git a/projects/instantbird/updater-text.patch b/projects/instantbird/updater-text.patch
deleted file mode 100644
index d571511..0000000
--- a/projects/instantbird/updater-text.patch
+++ /dev/null
@@ -1,9 +0,0 @@
-diff --git a/im/locales/en-US/updater/updater.ini b/im/locales/en-US/updater/updater.ini
---- 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â?¦
diff --git a/projects/instantbird/xmpp-default-domain.patch b/projects/instantbird/xmpp-default-domain.patch
deleted file mode 100644
index 38bf703..0000000
--- a/projects/instantbird/xmpp-default-domain.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff --git a/chat/protocols/xmpp/xmpp.js b/chat/protocols/xmpp/xmpp.js
---- a/chat/protocols/xmpp/xmpp.js
-+++ b/chat/protocols/xmpp/xmpp.js
-@@ -31,7 +31,7 @@
-
- usernameSplits: [
- {get label() { return _("options.domain"); }, separator: "@",
-- defaultValue: "jabber.org", reverse: true}
-+ defaultValue: "", reverse: true}
- ],
-
- options: {
diff --git a/projects/instantbird/xmpp-gtalk-resource.patch b/projects/instantbird/xmpp-gtalk-resource.patch
deleted file mode 100644
index a09d538..0000000
--- a/projects/instantbird/xmpp-gtalk-resource.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-diff --git a/chat/protocols/gtalk/gtalk.js b/chat/protocols/gtalk/gtalk.js
---- a/chat/protocols/gtalk/gtalk.js
-+++ b/chat/protocols/gtalk/gtalk.js
-@@ -96,7 +96,7 @@
- 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
---- a/chat/protocols/xmpp/xmpp.js
-+++ b/chat/protocols/xmpp/xmpp.js
-@@ -36,7 +36,7 @@
-
- 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"); },
diff --git a/projects/instantbird/xmpp-inband-registration.patch b/projects/instantbird/xmpp-inband-registration.patch
deleted file mode 100644
index c471346..0000000
--- a/projects/instantbird/xmpp-inband-registration.patch
+++ /dev/null
@@ -1,188 +0,0 @@
-diff --git a/chat/locales/en-US/xmpp.properties b/chat/locales/en-US/xmpp.properties
---- a/chat/locales/en-US/xmpp.properties
-+++ b/chat/locales/en-US/xmpp.properties
-@@ -13,6 +13,9 @@
- 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.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
---- a/chat/protocols/xmpp/xmpp-session.jsm
-+++ b/chat/protocols/xmpp/xmpp-session.jsm
-@@ -11,6 +11,8 @@
- 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 @@
- Stanza.node("ping", Stanza.NS.ping)),
- this.cancelDisconnectTimer, this);
- },
-+ nodes: {},
- _lastReceiveTime: 0,
- _lastSendTime: 0,
- checkPingTimer(aJustSentSomething = false) {
-@@ -271,6 +274,69 @@
- 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 @@
- 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
---- a/im/content/accountWizard.js
-+++ b/im/content/accountWizard.js
-@@ -119,6 +119,12 @@
- 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 @@
- 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
---- 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="®isterXMPP.label;" hidden="true" />
- </wizardpage>
-
- <wizardpage id="accountpassword" pageid="accountpassword" next="accountadvanced"
-diff --git a/im/content/jar.mn b/im/content/jar.mn
---- a/im/content/jar.mn
-+++ b/im/content/jar.mn
-@@ -61,6 +61,8 @@
- * 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/locales/en-US/chrome/instantbird/accountWizard.dtd b/im/locales/en-US/chrome/instantbird/accountWizard.dtd
---- 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">
diff --git a/projects/instantbird/xmpp-onion-js.patch b/projects/instantbird/xmpp-onion-js.patch
deleted file mode 100644
index 03652ee..0000000
--- a/projects/instantbird/xmpp-onion-js.patch
+++ /dev/null
@@ -1,89 +0,0 @@
-diff --git a/im/content/accountWizard.js b/im/content/accountWizard.js
---- a/im/content/accountWizard.js
-+++ b/im/content/accountWizard.js
-@@ -7,6 +7,14 @@
-
- const PREF_EXTENSIONS_GETMOREPROTOCOLSURL = "extensions.getMoreProtocolsURL";
-
-+// Borrowed and inspired by xmpp-client.
-+const kServerOnions = {
-+ "riseup.net": "4cjw6cwpeaeppfqz.onion",
-+ "jabber.ccc.de": "okj7xc6j2szr2y75.onion",
-+ "jabber.otr.im": "5rgdtlawqkcplz75.onion",
-+ "jabber.calyxinstitute.org": "ijeeynrc6x2uy5ob.onion",
-+}
-+
- var accountWizard = {
- onload: function aw_onload() {
- let topProtoList = document.getElementById("topprotolist");
-@@ -105,6 +113,21 @@
- return textbox;
- },
-
-+ insertOnionAddress: function aw_insertOnionAddress() {
-+ // Currently, we only use onion addresses for XMPP.
-+ if (this.proto.id == "prpl-jabber") {
-+ // If the value of the domain is one for which there exists a
-+ // hidden service, replace the address with the onion address.
-+ this.jabberDomain = document.getElementById("username-split-0");
-+ if (this.jabberDomain.value in kServerOnions) {
-+ this.onionAddress = kServerOnions[this.jabberDomain.value];
-+ }
-+ else {
-+ this.onionAddress = "";
-+ }
-+ }
-+ },
-+
- showUsernamePage: function aw_showUsernamePage() {
- let proto = this.proto.id;
- if ("userNameBoxes" in this && this.userNameProto == proto) {
-@@ -160,11 +183,20 @@
- document.getElementById("accountusername").next = next;
- },
-
-+ setOnionAddress: function aw_setOnionAddress() {
-+ if (this.proto.id == "prpl-jabber") {
-+ document.getElementById("prpl-jabber-server").value = this.onionAddress;
-+ }
-+ },
-+
- showAdvanced: function aw_showAdvanced() {
- // ensure we don't destroy user data if it's not necessary
- let id = this.proto.id;
-- if ("protoSpecOptId" in this && this.protoSpecOptId == id)
-+ if ("protoSpecOptId" in this && this.protoSpecOptId == id) {
-+ // But we should still set the onion address, if it exists.
-+ this.setOnionAddress();
- return;
-+ }
- this.protoSpecOptId = id;
-
- /* FIXME
-@@ -172,6 +204,7 @@
- !this.proto.newMailNotification;
- */
- this.populateProtoSpecificBox();
-+ this.setOnionAddress();
-
- let proxyVisible = this.proto.usePurpleProxy;
- if (proxyVisible) {
-@@ -405,7 +438,17 @@
- for (let i = 0; i < this.prefs.length; ++i) {
- let opt = this.prefs[i];
- let label = bundle.getFormattedString("accountColon", [opt.opt.label]);
-- rows.appendChild(this.createSummaryRow(label, opt.value));
-+ // Only append the label for the "Server" field.
-+ if (this.onionAddress == opt.value) {
-+ let wizardBundle = document.getElementById("topProtocolsBundle");
-+ let onionLabel = wizardBundle.getFormattedString("onionAddress.label",
-+ [this.jabberDomain.value]);
-+ rows.appendChild(this.createSummaryRow(label, opt.value));
-+ rows.appendChild(this.createSummaryRow("", onionLabel));
-+ }
-+ else {
-+ rows.appendChild(this.createSummaryRow(label, opt.value));
-+ }
- }
- },
-
diff --git a/projects/instantbird/xmpp-onion-locale.patch b/projects/instantbird/xmpp-onion-locale.patch
deleted file mode 100644
index 3744907..0000000
--- a/projects/instantbird/xmpp-onion-locale.patch
+++ /dev/null
@@ -1,10 +0,0 @@
-diff --git a/im/locales/en-US/chrome/instantbird/accountWizard.properties b/im/locales/en-US/chrome/instantbird/accountWizard.properties
-index 77dd6dd..8fa4c4f 100644
---- a/im/locales/en-US/chrome/instantbird/accountWizard.properties
-+++ b/im/locales/en-US/chrome/instantbird/accountWizard.properties
-@@ -19,3 +19,5 @@ 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-msn.description=Microsoft Windows Live Messenger (formerly MSN)
- topProtocol.prpl-yahoo.description=Chat with friends using Yahoo! Messenger
-+
-+onionAddress.label=(Secure connection to %S)
diff --git a/projects/instantbird/xmpp-onion-xul.patch b/projects/instantbird/xmpp-onion-xul.patch
deleted file mode 100644
index 5707435..0000000
--- a/projects/instantbird/xmpp-onion-xul.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-diff --git a/im/content/accountWizard.xul b/im/content/accountWizard.xul
-index 5fa5b82..89f88fe 100644
---- a/im/content/accountWizard.xul
-+++ b/im/content/accountWizard.xul
-@@ -59,7 +59,8 @@
- label="&accountUsernameTitle.label;"
- onpageshow="accountWizard.showUsernamePage();"
- onpagehide="accountWizard.hideUsernamePage();"
-- onpagerewound="return accountWizard.rewindFromUsernamePage();">
-+ onpagerewound="return accountWizard.rewindFromUsernamePage();"
-+ onpageadvanced="return accountWizard.insertOnionAddress();">
- <description id="usernameInfo"/>
- <separator/>
- <vbox id="userNameBox"/>
-@@ -98,7 +99,7 @@
- <checkbox id="newMailNotification"
- label="&accountAdvanced.newMailNotification.label;" hidden="true"/>
-
-- <groupbox id="protoSpecificGroupbox" class="collapsable" closed="true"
-+ <groupbox id="protoSpecificGroupbox" class="collapsable" closed="false"
- onkeypress="accountWizard.onGroupboxKeypress(event)">
- <caption id="protoSpecificCaption"
- onclick="accountWizard.toggleGroupbox('protoSpecificGroupbox')"/>
diff --git a/projects/instantbird/xmppRegister.js b/projects/instantbird/xmppRegister.js
deleted file mode 100644
index 3b43ffb..0000000
--- a/projects/instantbird/xmppRegister.js
+++ /dev/null
@@ -1,142 +0,0 @@
-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/projects/instantbird/xmppRegister.xul b/projects/instantbird/xmppRegister.xul
deleted file mode 100644
index e2bd367..0000000
--- a/projects/instantbird/xmppRegister.xul
+++ /dev/null
@@ -1,27 +0,0 @@
-<?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>
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits