Bug 954054 - Basic Jump List support on Windows 7, r=florian.
authorPatrick Cloke <clokep@gmail.com>
Tue, 31 May 2011 02:36:53 +0200
changeset 18255 3f1bd40bc29f8e5e8e6aaa2bc690f9bd700c9474
parent 18254 23c63dae968a177332ddbfd1383c2720a6b23ad7
child 18256 15ea03e050692d37d2fb525624551a9a092db6ec
push idunknown
push userunknown
push dateunknown
reviewersflorian
bugs954054
Bug 954054 - Basic Jump List support on Windows 7, r=florian.
im/app/splash.rc
im/components/Makefile.in
im/components/ibStatusCommandLineHandler.js
im/components/ibStatusCommandLineHandler.manifest
im/installer/package-manifest.in
im/locales/en-US/chrome/instantbird/winjumplist.properties
im/locales/jar.mn
im/modules/Makefile.in
im/modules/ibCore.jsm
im/modules/ibWinJumpList.jsm
im/themes/available-16.ico
im/themes/away-16.ico
im/themes/offline-16.ico
--- a/im/app/splash.rc
+++ b/im/app/splash.rc
@@ -16,16 +16,18 @@
  *
  * The Initial Developer of the Original Code is
  * Netscape Communications Corporation.
  * Portions created by the Initial Developer are Copyright (C) 1998
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Bill Law       law@netscape.com
+ *   Florian Qu├Ęze <florian@instantbird.org>
+ *   Patrick Cloke <clokep@gmail.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -33,26 +35,29 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #include <windows.h>
 #include "nsNativeAppSupportWin.h"
 
-1 24 "instantbird.exe.manifest" 
+1 24 "instantbird.exe.manifest"
 
 #define IDI_APPICON 1
 #define IDI_DOCUMENT 2
 #ifndef IDI_APPLICATION
 #define IDI_APPLICATION 32512
 #endif
 
 // Program icon.
 IDI_APPICON  ICON  INSTANTBIRD_ICO
+2  ICON  "../themes/available-16.ico"
+3  ICON  "../themes/away-16.ico"
+4  ICON  "../themes/offline-16.ico"
 IDI_APPLICATION ICON INSTANTBIRD_ICO
 
 STRINGTABLE DISCARDABLE
 BEGIN
 #ifdef DEBUG
     IDS_STARTMENU_APPNAME,              "@MOZ_APP_DISPLAYNAME@ Debug"
 #else
     IDS_STARTMENU_APPNAME,              "@MOZ_APP_DISPLAYNAME@"
--- a/im/components/Makefile.in
+++ b/im/components/Makefile.in
@@ -14,16 +14,17 @@
 # The Original Code is the Mozilla Browser code.
 #
 # The Initial Developer of the Original Code is
 #   Florian QUEZE <florian@instantbird.org>
 # Portions created by the Initial Developer are Copyright (C) 2008
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
+#   Patrick Cloke <clokep@gmail.com>
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either the GNU General Public License Version 2 or later (the "GPL"), or
 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
@@ -46,16 +47,17 @@ DIRS = mintrayr
 endif
 
 MODULE		= instantbird
 
 XPIDLSRCS	= ibILogger.idl
 
 EXTRA_COMPONENTS = \
 	ibCommandLineHandler.manifest \
+	ibStatusCommandLineHandler.js ibStatusCommandLineHandler.manifest \
 	logger.manifest \
 	smileProtocolHandler.js smileProtocolHandler.manifest \
 	$(NULL)
 
 EXTRA_PP_COMPONENTS = \
 	ibCommandLineHandler.js \
 	logger.js \
 	$(NULL)
new file mode 100644
--- /dev/null
+++ b/im/components/ibStatusCommandLineHandler.js
@@ -0,0 +1,91 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Instantbird.
+ *
+ * The Initial Developer of the Original Code is
+ * Benedikt Pfeifer <benediktp@ymail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Patrick Cloke <clokep@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const {interfaces: Ci, utils: Cu} = Components;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource:///modules/imServices.jsm");
+
+function StatusCLH() { }
+StatusCLH.prototype = {
+  classDescription: "Instantbird Status Commandline Handler Component",
+  classID:          Components.ID("{9da72063-b727-488d-9b3f-cc12e854ab33}"),
+  contractID:       "@instantbird.org/status/clh;1",
+  QueryInterface:   XPCOMUtils.generateQI([Ci.nsICommandLineHandler]),
+
+  /** nsICommandLineHandler **/
+  handle: function(cmdLine) {
+    let statusIndex = cmdLine.findFlag("status", false);
+    if (statusIndex == -1 || cmdLine.length <= statusIndex + 1)
+      return;
+
+    let requestedStatus;
+    let statusParam = cmdLine.getArgument(statusIndex + 1).toLowerCase();
+    if (statusParam == "available")
+      requestedStatus = Ci.imIStatusInfo.STATUS_AVAILABLE;
+    else if (statusParam == "away")
+      requestedStatus = Ci.imIStatusInfo.STATUS_AWAY;
+    else if (statusParam == "offline")
+      requestedStatus = Ci.imIStatusInfo.STATUS_OFFLINE;
+    else {
+      // Return so other statuses could be handled by an extension.
+      return;
+    }
+
+    // Remove the arguments since they've been handled.
+    cmdLine.removeArguments(statusIndex, statusIndex + 1);
+
+    // We're keeping the old status message here.
+    Services.core.setStatus(requestedStatus,
+                            Services.core.currentStatusMessage);
+
+    // Only perform the default action (i.e. loading the buddy list) if
+    // Instantbird is launched with a status flag.
+    if (cmdLine.state != Ci.nsICommandLine.STATE_INITIAL_LAUNCH)
+      cmdLine.preventDefault = true;
+  },
+
+  // Follow the guidelines in nsICommandLineHandler.idl for the help info
+  // specifically, flag descriptions should start at character 24, and lines
+  // should be wrapped at 72 characters with embedded newlines, and finally, the
+  // string should end with a newline.
+  helpInfo: "  -status <status>     Set the online status.\n" +
+            "                       <status> can be one of\n" +
+            "                       available, away, offline.\n"
+};
+
+var NSGetFactory = XPCOMUtils.generateNSGetFactory([StatusCLH]);
new file mode 100644
--- /dev/null
+++ b/im/components/ibStatusCommandLineHandler.manifest
@@ -0,0 +1,3 @@
+component {9da72063-b727-488d-9b3f-cc12e854ab33} ibStatusCommandLineHandler.js
+contract @instantbird.org/status/clh;1 {9da72063-b727-488d-9b3f-cc12e854ab33}
+category command-line-handler m-status @instantbird.org/status/clh;1
--- a/im/installer/package-manifest.in
+++ b/im/installer/package-manifest.in
@@ -415,16 +415,18 @@
 #else
 @BINPATH@/components/@DLL_PREFIX@trayToolkit@DLL_SUFFIX@
 @BINPATH@/components/trayToolkit.xpt
 @BINPATH@/components/profileMigrator.js
 @BINPATH@/components/profileMigrator.manifest
 #endif
 @BINPATH@/components/ibCommandLineHandler.js
 @BINPATH@/components/ibCommandLineHandler.manifest
+@BINPATH@/components/ibStatusCommandLineHandler.js
+@BINPATH@/components/ibStatusCommandLineHandler.manifest
 @BINPATH@/components/facebookOverrideProtocol.js
 @BINPATH@/components/gtalkOverrideProtocol.js
 @BINPATH@/components/overrideProtocols.manifest
 @BINPATH@/components/twitter.js
 @BINPATH@/components/twitter.manifest
 @BINPATH@/components/smileProtocolHandler.js
 @BINPATH@/components/smileProtocolHandler.manifest
 @BINPATH@/components/logger.js
new file mode 100644
--- /dev/null
+++ b/im/locales/en-US/chrome/instantbird/winjumplist.properties
@@ -0,0 +1,11 @@
+# LOCALIZATION NOTE:
+#   These are the labels that show up for the Jump List items.
+available.label=Available
+away.label=Away
+offline.label=Offline
+
+# LOCALIZATION NOTE:
+#   These are descriptions of what each Jump List item will do.
+available.tooltip=Set status to available.
+away.tooltip=Set status to away
+offline.tooltip=Set status to offline
--- a/im/locales/jar.mn
+++ b/im/locales/jar.mn
@@ -15,21 +15,22 @@
 	locale/@AB_CD@/instantbird/engineManager.properties (%chrome/instantbird/engineManager.properties)
 	locale/@AB_CD@/instantbird/extensions.properties (%chrome/instantbird/extensions.properties)
 	locale/@AB_CD@/instantbird/instantbird.dtd	(%chrome/instantbird/instantbird.dtd)
 	locale/@AB_CD@/instantbird/instantbird.properties (%chrome/instantbird/instantbird.properties)
 	locale/@AB_CD@/instantbird/joinChat.dtd		(%chrome/instantbird/joinChat.dtd)
 	locale/@AB_CD@/instantbird/mintrayr.dtd		(%chrome/instantbird/mintrayr.dtd)
 	locale/@AB_CD@/instantbird/proxies.dtd		(%chrome/instantbird/proxies.dtd)
 	locale/@AB_CD@/instantbird/proxies.properties	(%chrome/instantbird/proxies.properties)
+	locale/@AB_CD@/instantbird/quitDialog.properties	(%chrome/instantbird/quitDialog.properties)
 	locale/@AB_CD@/instantbird/region.properties	(%chrome/instantbird/region.properties)
 	locale/@AB_CD@/instantbird/tabbrowser.dtd	(%chrome/instantbird/tabbrowser.dtd)
 	locale/@AB_CD@/instantbird/tabbrowser.properties	(%chrome/instantbird/tabbrowser.properties)
 	locale/@AB_CD@/instantbird/updates.properties	(%chrome/instantbird/updates.properties)
-	locale/@AB_CD@/instantbird/quitDialog.properties	(%chrome/instantbird/quitDialog.properties)
+	locale/@AB_CD@/instantbird/winjumplist.properties	(%chrome/instantbird/winjumplist.properties)
 	locale/@AB_CD@/instantbird/preferences/advanced.dtd     (%chrome/instantbird/preferences/advanced.dtd)
 	locale/@AB_CD@/instantbird/preferences/applicationManager.dtd        (%chrome/instantbird/preferences/applicationManager.dtd)
 	locale/@AB_CD@/instantbird/preferences/applicationManager.properties (%chrome/instantbird/preferences/applicationManager.properties)
 	locale/@AB_CD@/instantbird/preferences/applications.dtd (%chrome/instantbird/preferences/applications.dtd)
 	locale/@AB_CD@/instantbird/preferences/colors.dtd       (%chrome/instantbird/preferences/colors.dtd)
 	locale/@AB_CD@/instantbird/preferences/connection.dtd   (%chrome/instantbird/preferences/connection.dtd)
 	locale/@AB_CD@/instantbird/preferences/content.dtd      (%chrome/instantbird/preferences/content.dtd)
 	locale/@AB_CD@/instantbird/preferences/main.dtd         (%chrome/instantbird/preferences/main.dtd)
--- a/im/modules/Makefile.in
+++ b/im/modules/Makefile.in
@@ -37,24 +37,28 @@
 DEPTH		= ../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 EXTRA_JS_MODULES = \
-	ibCore.jsm \
 	ibNotifications.jsm \
 	ibSounds.jsm \
 	imContentSink.jsm \
 	imServices.jsm \
 	imSmileys.jsm \
 	$(NULL)
 
 EXTRA_PP_JS_MODULES = \
+	ibCore.jsm \
 	hiddenWindow.jsm \
 	imThemes.jsm \
 	imTextboxUtils.jsm \
 	imWindows.jsm \
 	$(NULL)
 
+ifeq ($(OS_ARCH),WINNT)
+EXTRA_JS_MODULES += ibWinJumpList.jsm
+endif
+
 include $(topsrcdir)/config/rules.mk
--- a/im/modules/ibCore.jsm
+++ b/im/modules/ibCore.jsm
@@ -94,16 +94,26 @@ var Core = {
       this.uninitPurpleCore();
       return false;
     }
 
     Services.conversations.initConversations();
     Conversations.init();
     Notifications.init();
     Sounds.init();
+#ifdef XP_WIN
+    // For windows seven, initialize the jump list module.
+    const WINTASKBAR_CONTRACTID = "@mozilla.org/windows-taskbar;1";
+    if (WINTASKBAR_CONTRACTID in Cc &&
+        Cc[WINTASKBAR_CONTRACTID].getService(Ci.nsIWinTaskbar).available) {
+      let temp = {};
+      Cu.import("resource:///modules/ibWinJumpList.jsm", temp);
+      temp.WinJumpList.init();
+    }
+#endif
 
     this._events.forEach(function (aTopic) {
       Services.obs.addObserver(Core, aTopic, false);
     });
 
     this._showAccountManagerIfNeeded(true);
     return true;
   },
new file mode 100644
--- /dev/null
+++ b/im/modules/ibWinJumpList.jsm
@@ -0,0 +1,181 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Instantbird.
+ *
+ * The Initial Developer of the Original Code is
+ * Patrick Cloke <clokep@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Benedikt Pfeifer <benediktp@ymail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const EXPORTED_SYMBOLS = ["WinJumpList"];
+
+const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource:///modules/imServices.jsm");
+
+XPCOMUtils.defineLazyGetter(this, "bundle", function()
+  Services.strings.createBundle("chrome://instantbird/locale/winjumplist.properties")
+);
+
+var WinJumpList = {
+  winJumpListBuilder: null,
+
+  /*
+    Jumplist entries can be of the following 'type' (required attribute):
+      type: "shortcut"        // nsIJumpListShortcut
+        label: <string>,      //  label shown in the jumplist
+        description: <string> //  longer description, shown in a tooltip
+        parameter: <string>   //  commandline parameter for this action
+        iconIndex: <int>      //  number of icon resource in executable
+        id: <string>          //  Only used to identify a certain element
+                              //   if an extension wants to insert an
+                              //   item at a specific position
+     or
+      type: "separator"       // nsIJumpListSeparator, no way to customize this
+        id: <string>          //  see description of shortcut id
+  */
+  // Default jumplist entries for changing the status.
+  jumplistEntries: [
+    { type: "shortcut",
+      id: "status_available",
+      get label() bundle.GetStringFromName("available.label"),
+      get description() bundle.GetStringFromName("available.tooltip"),
+      parameter: "-status available",
+      iconIndex: 1
+    },
+    { type: "shortcut",
+      id: "status_away",
+      get label() bundle.GetStringFromName("away.label"),
+      get description() bundle.GetStringFromName("away.tooltip"),
+      parameter: "-status away",
+      iconIndex: 2
+    },
+    { type: "shortcut",
+      id: "status_offline",
+      get label() bundle.GetStringFromName("offline.label"),
+      get description() bundle.GetStringFromName("offline.tooltip"),
+      parameter: "-status offline",
+      iconIndex: 3
+    }
+  ],
+
+  // This is called by the Instantbird core and does not need to be re-called by
+  // any other code working with jump lists.
+  init: function WJL_init() {
+    let builder = Cc["@mozilla.org/windows-taskbar;1"]
+                     .getService(Ci.nsIWinTaskbar).createJumpListBuilder();
+    if (!builder || !builder.available)
+      return;
+
+    this.winJumpListBuilder = builder;
+
+    // Set the jump list using the default jumplistEntries.
+    this.set();
+  },
+
+  set: function WJL_set() {
+    // Return early if winJumpListBuilder doesn't exist.
+    if (!this.winJumpListBuilder)
+      return;
+
+    // Remove the current jump list so it can be replaced.
+    this.reset();
+
+    let items = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
+
+    for each (let currentItem in this.jumplistEntries) {
+      let item;
+      if (currentItem.type == "separator")
+        item = this._getSeparatorItem();
+      else if (currentItem.type == "shortcut") {
+        item = this._getHandlerAppItem(currentItem.label,
+                                       currentItem.description,
+                                       currentItem.parameter,
+                                       currentItem.iconIndex);
+      }
+      else if (currentItem.type == "link")
+        item = this._getLinkItem(currentItem.uri, currentItem.uriTitle);
+      else
+        throw "Unknown jumplist item type: " + currentItem.type;
+
+      items.appendElement(item, false);
+    }
+
+    try {
+      // Initialize the array.
+      let items2 = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
+      this.winJumpListBuilder.initListBuild(items2);
+
+      this.winJumpListBuilder.addListToBuild(
+        Ci.nsIJumpListBuilder.JUMPLIST_CATEGORY_TASKS, items);
+
+      // Send the list to Windows
+      this.winJumpListBuilder.commitListBuild();
+    } catch (e) {
+      Cu.reportError(e);
+    }
+  },
+
+  reset: function WJL_reset() {
+    // Remove the jump list.
+    if (this.winJumpListBuilder)
+      this.winJumpListBuilder.deleteActiveList();
+  },
+
+  _getSeparatorItem: function WJL__getSeparatorItem() {
+    return Cc["@mozilla.org/windows-jumplistseparator;1"]
+              .createInstance(Ci.nsIJumpListSeparator);
+  },
+
+  _getHandlerAppItem: function WJL__getHandlerAppItem(aName, aDescription,
+                                                      aArgs, aIconIndex) {
+    var file = Services.dirsvc.get("XCurProcD", Ci.nsILocalFile);
+
+    // XXX where can we grab this from in the build? Do we need to?
+    file.append("instantbird.exe");
+
+    var handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"]
+                        .createInstance(Ci.nsILocalHandlerApp);
+    handlerApp.executable = file;
+    // Handlers default to the leaf name if a name is not specified.
+    if (aName && aName.length != 0)
+      handlerApp.name = aName;
+    handlerApp.detailedDescription = aDescription;
+    handlerApp.appendParameter(aArgs);
+
+    var item = Cc["@mozilla.org/windows-jumplistshortcut;1"]
+                  .createInstance(Ci.nsIJumpListShortcut);
+    item.app = handlerApp;
+    item.iconIndex = aIconIndex;
+    return item;
+  }
+};
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..3af15dba5004965d04dc5a04e1be22ae6c315ce6
GIT binary patch
literal 1150
zc$}q_OH5ip6ov-@6Oo6AfgnapG=lL3K~SR+h-gI7C`Nps#AuAhotrMSN#nYU#%{W5
znsm`slP-u&7hScBrjPh)QCo|ZibWBW`Y5(8{@$xzR0v(PbMxO!=AJV%-<f|dAuQ_2
z$RJd^LB=?QNU5HhQpVW`p}x{@LQEWz&;YQmirgeBO4F3wlmZuWUyP~Z<KuECSd*+M
z{}CUe=OT#Sh>-p|9b7jTtOqQRNfM=FlH|_v?((3VS3>z&iJa9O$d+Zu{E!LZq7Z5G
zX<)x(gWMsYW8>Eq%m|>}(4ypP3DjOS^4Ic_yP6C6vK(0-vmja$fj7?s_dS=HV}jvj
zPqCx=RXwWwRnUFYp=_fJMe9W<SSvu@r#vWD6p(tP5HE?rU*IG4RVu@BRx9NbCF+Cq
zs0-AgdaD}xO+7R|4T{%`QTV0slE-t-BUluG^N>UD;Wk}c!&?KI!_8<2Ho&xPLe2LY
z82kokedjzXuPT9u_lyVTjBHyrv`5;}5^h1`ZX?V)X4D31lk#M*WJB^!0_J?}+jevx
zcEcXAqjj$pO`)c1JQbT2DEF0L<B`wFnS8fp!GeL~0rVX9pz}v3+V<OE4O{=pBYPoZ
z_CKw0YcPB=4A)N=`i}b0b<l<O{Y0Khe`SnE@>s&uPsP2(jrIroG4g8!gV8}akDYKF
zIM5O4fNjrq&a-pLQ|c*2%2Y~}@iXlO#eD_FPscI(dlW+_Ly0^gD=a|^i~%ErGeX4s
znD!(+hilh`vD2{_Pw!E0jK}OXLwrx1;NPo0rdf2eI#`#iaE2(3paaG^Bh*jTpnaO`
N{`~9xrT+l`qd)S(Lel^M
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f41597c05b1b8c4fccdd803620298b849be56028
GIT binary patch
literal 1150
zc$}q_*-9fp6o$(fw+rbIH7FVgYRD)e1`$C-$1RE>1Vuz~#RbO&HxL)Z5L}QTh#=yH
zPvAvv!rbN^`XQQmfu?hpZ>rUfi7_`b)%;CUea@-#ojO%Q6v@Zo5OR3LFS`&f`SnA}
z@irsmU-K=*PrJw)KvA}Yc=bs|r4mwqK9u;F^L@4d;(K7T#ZykFip!-*88{pU<>eYS
zn~D(elxb7I_qU=X@%wctXl;eYMyRic>T0O0gpv|n#z<n?eqFb!D#_?*nt=i6>4DBp
zXlnzn7u;@SE}$sLT+&vI1B=&gkEcQ*oykcE24Q#@dV8U(3)<VkC#gLisH+2~6Dlfn
zi{-6We!t4f3e3&H)D(n55C}kjKXi9PM+daD<nol3n)P^%n6(XuHFkDjeH|7SV0s$D
zVHg`DkEgl$okvkLtUcP>GdMbe-Cfw&faPVForQ@B7$1kBp?n^<+rZl2lM{nT1dfkk
ze;+nC$>SLrfxf;^9<Mj!pIBYhxV?pF6wc1z@DR4QVQsB2Pg7GS|7akf^6&t$7+hY$
z`8hc}OG_{_lgrc4kg1=qtSp|oxzTxigu6SqzJ`m7!aRe6I>p8B`)Bo!&zI!oCC$?l
z+~1SoIX%tgnV(NnQ}fwB+5KzAh{bfCpZS(&aZ#tXHot$f``Ba&235AUG_I};$zjMf
VHCZ!N_J85?^RMUEyaE14e*t^oenbEO
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..135a6d1b2d5696780d83e0cc10f47a576a1e8f79
GIT binary patch
literal 1150
zc$}q_Noyie5XU=^58!Feb8|k%e4M%FC`M)QCWtphLC}DTqKUZS8snD4eT^FTeIYJ*
z^7x;w#vUdv49vWyn#b!`_3Bskf6Xvg>?05`?D)$3xMr9y?CcwB0&az2ztWpwzF#vZ
z1HjdvCK8E+to>xo&D#86?!%h!c>j^_&F$^&UaeNcXf(oVwZd#RL#x$7sZ>HN7Vl}#
z1z)d1p@7flLnsu2-|vUV<AKxZgu~(BVi^nu$mMd--s5vA{`2!QlF1~Vo}Lg6hY<(_
z;Prapa=CDSe-E3@28+eQ$GG8nB@)R#kw_qy%i;C)6{%DTu~-a`kB<ljgIrE-w;K-+
z53t+qxVyXKS-4u6OeWN7HI&O`<nwu?(`hc3cs!11G<udtrBYE2GO8_|^Zx#hx3@P`
zDist81!S{Xyu7@C@;b+(*XzOes9vw5*XyCxYN63+pjxe>SS+6KL?V&jJd^|9-*&r=
z(P)HzzYm%>o6W!S5C^Xf%5y%SV=|dwFc_fI>74LnGMP_2)CXQy6l=9wVX;_XI-O!T
z9HQIpay-O#%tJla>2!Skgff|IPd@AQ8q4Jpv)Swu57mTtN~IFVL-nSf^Li#NXfzt^
zb~|h~8+?3xa6IGj_=JaIkk*cMOq!$^<g?vw&+^dOhrW9+-5+A1{!;&WKjJ0rN~O|^
O_vc^lFZ}`j$9@5VEFlB{