diff --git a/PlistExplorer b/PlistExplorer deleted file mode 100755 index 58491b0..0000000 Binary files a/PlistExplorer and /dev/null differ diff --git a/add-to-reading-list b/add-to-reading-list deleted file mode 100755 index 72e1319..0000000 --- a/add-to-reading-list +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -TITLE="$1" -URL="$2" - -if [[ "$TITLE" != "" ]] && [[ "$URL" != "" ]]; then - osascript -e "tell application \"Safari\" to add reading list item \"${URL}\" with title \"${TITLE}\"" -else - echo "usage: `basename $0` <url>" - exit 1 -fi diff --git a/bsh b/bsh deleted file mode 100755 index e0ea057..0000000 --- a/bsh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -java -jar $HOME/apps/bsh-2.0b4.jar diff --git a/chrome-to-reading-list b/chrome-to-reading-list deleted file mode 100755 index 98a5f8e..0000000 --- a/chrome-to-reading-list +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -AS_GET_TITLE=' - tell application "Google Chrome" - set frontIndex to active tab index of front window - get title of tab frontIndex of front window - end tell -' - -AS_GET_URL=' - tell application "Google Chrome" - set frontIndex to active tab index of front window - get URL of tab frontIndex of front window - end tell -' - -TITLE=`osascript - <<<"$AS_GET_TITLE"` -URL=`osascript - <<<"$AS_GET_URL"` - -~/bin/add-to-reading-list "$TITLE" "$URL" diff --git a/closure b/closure deleted file mode 100755 index 4b3dbe0..0000000 --- a/closure +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -java -jar $(dirname $0)/compiler.jar "$@" diff --git a/compiler.jar b/compiler.jar deleted file mode 100644 index 694808c..0000000 Binary files a/compiler.jar and /dev/null differ diff --git a/composer b/composer deleted file mode 100755 index f4aa6be..0000000 --- a/composer +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -php $(dirname "$0")/composer.phar "$@" diff --git a/composer.phar b/composer.phar deleted file mode 100755 index 52d5fa2..0000000 Binary files a/composer.phar and /dev/null differ diff --git a/configurize b/configurize deleted file mode 100755 index 5edf12d..0000000 --- a/configurize +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh - -CONFIG="$HOME/config" - -NUMFILES=$# -while [ $# -gt 0 ]; do - FILE="$1" - shift - NEWFILE="${FILE#.}" - echo " * Configurizing $NEWFILE ..." - mv "$FILE" "$CONFIG/$NEWFILE" - ln -s "$CONFIG/$NEWFILE" "$FILE" - pushd "$CONFIG" - git add "$NEWFILE" - git commit -m "[NEW] Configurized '$NEWFILE'" - popd -done - -echo " * $NUMFILES new files/directories" - -echo " * Pushing configs to remote repository ... " -pushd "$CONFIG" -git push origin master -popd - -echo " * Done" diff --git a/convert-mkv-to-mp4.sh b/convert-mkv-to-mp4.sh deleted file mode 100755 index 87f62a0..0000000 --- a/convert-mkv-to-mp4.sh +++ /dev/null @@ -1,112 +0,0 @@ -#!/bin/bash -# -# convert-mkv-to-mp4.sh -# -# Copyright (c) 2014 Don Melton -# - -about() { - cat <<EOF -$program 1.0 of July 9, 2014 -Copyright (c) 2013-2014 Don Melton -EOF - exit 0 -} - -usage() { - cat <<EOF -Convert Matroska video file into MP4 format without transcoding. - -Usage: $program [OPTION]... [FILE] - - --help display this help and exit - --version output version information and exit - -Requires \`ffprobe\`, \`ffmpeg\` and \`mp4track\` executables in \$PATH. -Output is written to current working directory. -EOF - exit 0 -} - -syntax_error() { - echo "$program: $1" >&2 - echo "Try \`$program --help\` for more information." >&2 - exit 1 -} - -die() { - echo "$program: $1" >&2 - exit ${2:-1} -} - -readonly program="$(basename "$0")" - -case $1 in - --help) - usage - ;; - --version) - about - ;; -esac - -readonly input="$1" - -if [ ! "$input" ]; then - syntax_error 'too few arguments' -fi - -if [ ! -f "$input" ]; then - die "input file not found: $input" -fi - -readonly output="$(basename "$input" | sed 's/\.[^.]*$//').mp4" - -if [ -e "$output" ]; then - die "output file already exists: $output" -fi - -for tool in ffprobe ffmpeg mp4track; do - - if ! $(which $tool >/dev/null); then - die "executable not in \$PATH: $tool" - fi -done - -readonly container="$(ffprobe -show_format "$input" 2>/dev/null | sed -n '/^format_name=/p' | sed 's/^.*=//;s/,.*$//')" - -if [ "$container" != 'matroska' ]; then - die "input file not Matroska format: $input" -fi - -readonly track1="$(ffprobe -show_streams -select_streams a:0 "$input" 2>/dev/null | sed -n '/^codec_name=/p' | sed 's/^.*=//;s/,.*$//')" -readonly track2="$(ffprobe -show_streams -select_streams a:1 "$input" 2>/dev/null | sed -n '/^codec_name=/p' | sed 's/^.*=//;s/,.*$//')" - -adjust_defaults='' - -if [ "$track1" == 'ac3' ] && [ "$track2" == 'aac' ]; then - map_options='-map 0:2 -map 0:1' - adjust_defaults='true' - -elif [ "$track1" == 'aac' ]; then - map_options='-map 0:1' -else - die "input file does not contain compatible audio tracks: $input" -fi - -echo "Converting: $input" >&2 - -time { - ffmpeg \ - -i "$input" \ - -map 0:0 \ - $map_options \ - -c copy \ - "$output" \ - || exit 1 - - if [ "$adjust_defaults" ]; then - mp4track --track-index 1 --enabled true "$output" && - mp4track --track-index 2 --enabled false "$output" || exit 1 - fi -} diff --git a/deretina b/deretina deleted file mode 100755 index db37e34..0000000 --- a/deretina +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/zsh - -set -e # bail on errors - -TWOX_IMG_PATH="$1" -ONEX_IMG_PATH="${TWOX_IMG_PATH%.png}@1x.png" -convert -resize "50%" "$TWOX_IMG_PATH" "$ONEX_IMG_PATH" \ No newline at end of file diff --git a/desktop-icons b/desktop-icons deleted file mode 100755 index 8894e72..0000000 --- a/desktop-icons +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -# Toggle the visibility of Desktop icons. - -# Desktop icons are visible if the CreateDesktop setting is missing or -# if it exists and is set to 1, true, yes, or on (case insensitive). -# Desktop icons are hidden if the CreateDesktop setting exists and -# is set to any value other than 1, true, yes, or on. - -# The $icons variable is the value of CreateDesktop if it exists or is -# the empty string if it doesn't. - -icons=`defaults read com.apple.finder CreateDesktop 2> /dev/null` - -shopt -s nocasematch -case "$icons" in - "" | "1" | "true" | "yes" | "on" ) - defaults write com.apple.finder CreateDesktop 0 && killall Finder;; - * ) - defaults write com.apple.finder CreateDesktop 1 && killall Finder;; -esac diff --git a/domainr b/domainr deleted file mode 100755 index 25a6ba7..0000000 --- a/domainr +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/python - -from sys import argv -from httplib import HTTPConnection - -import json - -def main(args): - for arg in args: - print "Looking up domains for %s..." % arg - - con = HTTPConnection('domai.nr') - req = con.request('GET', '/api/json/search?q=%s' % arg) - res = con.getresponse() - - if res.status == 200: - data = res.read() - sites = json.loads(data) - - for s in sites['results']: - print "\t%s - %s" % (s['domain'], s['availability']) - else: - print "Uh oh, you got a %s %s. What the dilly?" % (res.status, res.reason) - -if __name__ == "__main__": - main(argv[1:]) diff --git a/drop b/drop deleted file mode 100755 index bae4af2..0000000 --- a/drop +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -[[ x"$1" = x ]] && cp -R . ~/Dropbox/${PWD##*/} || cp -R "$@" ~/Dropbox/ diff --git a/dropbox b/dropbox deleted file mode 100755 index a06e0df..0000000 --- a/dropbox +++ /dev/null @@ -1,1388 +0,0 @@ -#!/usr/bin/python -# -# Copyright (c) Dropbox, Inc. -# -# dropbox -# Dropbox frontend script -# This file is part of nautilus-dropbox 1.6.0. -# -# nautilus-dropbox is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# nautilus-dropbox is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with nautilus-dropbox. If not, see <http://www.gnu.org/licenses/>. -# - -import errno -import locale -import optparse -import os -import platform -import shutil -import socket -import StringIO -import subprocess -import sys -import tarfile -import tempfile -import threading -import thread -import time -import traceback -import urllib2 - -try: - import gpgme -except ImportError: - gpgme = None - -from contextlib import closing, contextmanager -from posixpath import curdir, sep, pardir, join, abspath, commonprefix - -INFO = u"Dropbox is the easiest way to share and store your files online. Want to learn more? Head to" -LINK = u"https://www.dropbox.com/" -WARNING = u"In order to use Dropbox, you must download the proprietary daemon." -GPG_WARNING = u"Note: python-gpgme is not installed, we will not be able to verify binary signatures." -ERROR_CONNECTING = u"Trouble connecting to Dropbox servers. Maybe your internet connection is down, or you need to set your http_proxy environment variable." -ERROR_SIGNATURE = u"Downloaded binary does not match Dropbox signature, aborting install." - -DOWNLOAD_LOCATION_FMT = "https://www.dropbox.com/download?plat=%s" -SIGNATURE_LOCATION_FMT = "https://www.dropbox.com/download?plat=%s&signature=1" - -DOWNLOADING = u"Downloading Dropbox... %d%%" -UNPACKING = u"Unpacking Dropbox... %d%%" - -PARENT_DIR = os.path.expanduser("~") -DROPBOXD_PATH = "%s/.dropbox-dist/dropboxd" % PARENT_DIR -DESKTOP_FILE = u"/usr/share/applications/dropbox.desktop" - -enc = locale.getpreferredencoding() - -# Available from https://linux.dropbox.com/fedora/rpm-public-key.asc -DROPBOX_PUBLIC_KEY = """ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: SKS 1.1.0 - -mQENBEt0ibEBCACv4hZRPqwtpU6z8+BB5YZU1a3yjEvg2W68+a6hEwxtCa2U++4dzQ+7EqaU -q5ybQnwtbDdpFpsOi9x31J+PCpufPUfIG694/0rlEpmzl2GWzY8NqfdBFGGm/SPSSwvKbeNc -FMRLu5neo7W9kwvfMbGjHmvUbzBUVpCVKD0OEEf1q/Ii0Qcekx9CMoLvWq7ZwNHEbNnij7ec -nvwNlE2MxNsOSJj+hwZGK+tM19kuYGSKw4b5mR8IyThlgiSLIfpSBh1n2KX+TDdk9GR+57TY -vlRu6nTPu98P05IlrrCP+KF0hYZYOaMvQs9Rmc09tc/eoQlN0kkaBWw9Rv/dvLVc0aUXABEB -AAG0MURyb3Bib3ggQXV0b21hdGljIFNpZ25pbmcgS2V5IDxsaW51eEBkcm9wYm94LmNvbT6J -ATYEEwECACAFAkt0ibECGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRD8kYszUESRLi/z -B/wMscEa15rS+0mIpsORknD7kawKwyda+LHdtZc0hD/73QGFINR2P23UTol/R4nyAFEuYNsF -0C4IAD6y4pL49eZ72IktPrr4H27Q9eXhNZfJhD7BvQMBx75L0F5gSQwuC7GdYNlwSlCD0AAh -Qbi70VBwzeIgITBkMQcJIhLvllYo/AKD7Gv9huy4RLaIoSeofp+2Q0zUHNPl/7zymOqu+5Ox -e1ltuJT/kd/8hU+N5WNxJTSaOK0sF1/wWFM6rWd6XQUP03VyNosAevX5tBo++iD1WY2/lFVU -JkvAvge2WFk3c6tAwZT/tKxspFy4M/tNbDKeyvr685XKJw9ei6GcOGHD -=5rWG ------END PGP PUBLIC KEY BLOCK----- -""" - -# Futures - -def methodcaller(name, *args, **kwargs): - def caller(obj): - return getattr(obj, name)(*args, **kwargs) - return caller - -def relpath(path, start=curdir): - """Return a relative version of a path""" - - if not path: - raise ValueError("no path specified") - - if type(start) is unicode: - start_list = unicode_abspath(start).split(sep) - else: - start_list = abspath(start).split(sep) - - if type(path) is unicode: - path_list = unicode_abspath(path).split(sep) - else: - path_list = abspath(path).split(sep) - - # Work out how much of the filepath is shared by start and path. - i = len(commonprefix([start_list, path_list])) - - rel_list = [pardir] * (len(start_list)-i) + path_list[i:] - if not rel_list: - return curdir - return join(*rel_list) - -# End Futures - - -def console_print(st=u"", f=sys.stdout, linebreak=True): - global enc - assert type(st) is unicode - f.write(st.encode(enc)) - if linebreak: f.write(os.linesep) - -def console_flush(f=sys.stdout): - f.flush() - -def yes_no_question(question): - while True: - console_print(question, linebreak=False) - console_print(u" [y/n] ", linebreak=False) - console_flush() - text = raw_input() - if text.lower().startswith("y"): - return True - elif text.lower().startswith("n"): - return False - else: - console_print(u"Sorry, I didn't understand that. Please type yes or no.") - -def plat(): - if sys.platform.lower().startswith('linux'): - arch = platform.machine() - if (arch[0] == 'i' and - arch[1].isdigit() and - arch[2:4] == '86'): - plat = "x86" - elif arch == 'x86_64': - plat = arch - else: - FatalVisibleError("Platform not supported") - return "lnx.%s" % plat - else: - FatalVisibleError("Platform not supported") - -def is_dropbox_running(): - pidfile = os.path.expanduser("~/.dropbox/dropbox.pid") - - try: - with open(pidfile, "r") as f: - pid = int(f.read()) - with open("/proc/%d/cmdline" % pid, "r") as f: - cmdline = f.read().lower() - except: - cmdline = "" - - return "dropbox" in cmdline - -def unicode_abspath(path): - global enc - assert type(path) is unicode - # shouldn't pass unicode to this craphead, it appends with os.getcwd() which is always a str - return os.path.abspath(path.encode(sys.getfilesystemencoding())).decode(sys.getfilesystemencoding()) - -@contextmanager -def gpgme_context(keys): - gpg_conf_contents = '' - _gpghome = tempfile.mkdtemp(prefix='tmp.gpghome') - - try: - os.environ['GNUPGHOME'] = _gpghome - fp = open(os.path.join(_gpghome, 'gpg.conf'), 'wb') - fp.write(gpg_conf_contents) - fp.close() - ctx = gpgme.Context() - - loaded = [] - for key_file in keys: - result = ctx.import_(key_file) - key = ctx.get_key(result.imports[0][0]) - loaded.append(key) - - ctx.signers = loaded - - yield ctx - finally: - del os.environ['GNUPGHOME'] - shutil.rmtree(_gpghome, ignore_errors=True) - -class SignatureVerifyError(Exception): - pass - -def verify_signature(key_file, sig_file, plain_file): - with gpgme_context([key_file]) as ctx: - sigs = ctx.verify(sig_file, plain_file, None) - return sigs[0].status == None - -def download_file_chunk(url, buf): - opener = urllib2.build_opener() - opener.addheaders = [('User-Agent', "DropboxLinuxDownloader/1.6.0")] - sock = opener.open(url) - - size = int(sock.info()['content-length']) - bufsize = max(size / 200, 4096) - progress = 0 - - with closing(sock) as f: - yield (0, True) - while True: - try: - chunk = f.read(bufsize) - progress += len(chunk) - buf.write(chunk) - yield (float(progress)/size, True) - if progress == size: - break - except OSError, e: - if hasattr(e, 'errno') and e.errno == errno.EAGAIN: - # nothing left to read - yield (float(progress)/size, False) - else: - raise - -class DownloadState(object): - def __init__(self): - self.local_file = StringIO.StringIO() - - def copy_data(self): - return download_file_chunk(DOWNLOAD_LOCATION_FMT % plat(), self.local_file) - - def unpack(self): - # download signature - signature = StringIO.StringIO() - for _ in download_file_chunk(SIGNATURE_LOCATION_FMT % plat(), signature): - pass - signature.seek(0) - self.local_file.seek(0) - - if gpgme: - if not verify_signature(StringIO.StringIO(DROPBOX_PUBLIC_KEY), signature, self.local_file): - raise SignatureVerifyError() - - self.local_file.seek(0) - archive = tarfile.open(fileobj=self.local_file, mode='r:gz') - total_members = len(archive.getmembers()) - for i, member in enumerate(archive.getmembers()): - archive.extract(member, PARENT_DIR) - yield member.name, i, total_members - archive.close() - - def cancel(self): - if not self.local_file.closed: - self.local_file.close() - -def load_serialized_images(): - global box_logo_pixbuf, window_icon - import gtk - box_logo_pixbuf = gtk.gdk.pixbuf_new_from_data('\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x08\x00\\\x9ef\x00\\\x9ej\x00\\\x9e\x04\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9eZ\x00[\x9er\x00\\\x9e\x14\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e8\x00Y\x9c\xc2\x00X\x9b\xff\x00X\x9b\xff\x00[\x9d\xaa\x00\\\x9e\r\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x02\x00\\\x9e\x8e\x00Y\x9b\xff\x00Y\x9b\xff\x00Y\x9b\xd5\x00\\\x9eM\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x12\x00[\x9d\x8b\x00U\x99\xfa\x0fe\xa5\xff]\xa2\xd3\xffM\x95\xc9\xff\x00X\x9b\xff\x00Y\x9c\xc9\x00\\\x9e\x1e\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x0f\x00[\x9d\xb1\x00V\x99\xff4\x85\xc1\xffZ\xa3\xda\xff\x17m\xab\xff\x00V\x99\xff\x00Z\x9d\xa2\x00\\\x9e \x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\\\x00W\x9a\xde\x00Y\x9c\xff:\x87\xbf\xff\x83\xbf\xeb\xff\x98\xce\xf6\xff\x9b\xd0\xf6\xffa\xa3\xd3\xff\x05]\x9e\xff\x00X\x9b\xda\x00\\\x9e/\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x1c\x00Z\x9c\xc5\x01Y\x9b\xff?\x90\xca\xff|\xc1\xf4\xff\x82\xc4\xf6\xff}\xbf\xf0\xffD\x90\xc8\xff\x05]\x9e\xff\x00V\x9a\xed\x00\\\x9es\x00\\\x9e\x07\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e4\x00Z\x9c\xba\x00V\x99\xff\x1dq\xae\xffd\xaa\xdd\xff\x8e\xc9\xf5\xff\x8e\xc7\xf3\xff\x8f\xc7\xf1\xff\x92\xc9\xf1\xff\xa1\xd2\xf6\xffw\xb3\xde\xff\x0fd\xa3\xff\x00V\x9a\xed\x00\\\x9eL\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e4\x00X\x9b\xdd\x05^\x9f\xffM\x9d\xd6\xffy\xc1\xf6\xffw\xbe\xf2\xffz\xbe\xf1\xff\x80\xc1\xf2\xff\x89\xc8\xf6\xffq\xb3\xe3\xff*z\xb5\xff\x00W\x9a\xff\x00X\x9b\xcd\x00\\\x9eG\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x0e\x00[\x9d\x86\x00V\x99\xfa\x0cc\xa4\xffK\x96\xce\xff\x81\xc2\xf2\xff\x89\xc7\xf5\xff\x87\xc4\xf1\xff\x8b\xc5\xf1\xff\x8f\xc7\xf1\xff\x92\xc9\xf1\xff\x97\xcb\xf1\xff\xa4\xd3\xf6\xff\x85\xbb\xe4\xff\x18k\xa8\xff\x00U\x99\xfc\x00\\\x9en\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9eS\x00W\x9a\xf1\x0bb\xa3\xffT\xa3\xdd\xffv\xc0\xf7\xffr\xbb\xf1\xffv\xbd\xf1\xffz\xbe\xf1\xff~\xc0\xf1\xff\x81\xc2\xf1\xff\x8a\xc7\xf4\xff\x8f\xc9\xf4\xff`\xa3\xd5\xff\x15i\xa8\xff\x00U\x98\xff\x00[\x9d\x9c\x00\\\x9e\x1a\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9eU\x00X\x9b\xd9\x00Z\x9c\xff1\x83\xbf\xffp\xb6\xea\xff\x84\xc5\xf6\xff\x80\xc2\xf2\xff\x83\xc2\xf1\xff\x87\xc4\xf1\xff\x8b\xc5\xf1\xff\x8f\xc7\xf1\xff\x92\xc9\xf1\xff\x97\xcb\xf1\xff\x9b\xcc\xf1\xff\xa6\xd3\xf5\xff\x96\xc7\xeb\xff*y\xb2\xff\x00T\x98\xff\x00\\\x9e\x90\x00\\\x9e\x02\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9eu\x00V\x99\xfe\x14k\xac\xff\\\xac\xe6\xffr\xbd\xf6\xffo\xba\xf1\xffr\xbb\xf1\xffv\xbd\xf1\xffz\xbe\xf1\xff~\xc0\xf1\xff\x81\xc2\xf1\xff\x85\xc3\xf1\xff\x8b\xc5\xf1\xff\x95\xcc\xf6\xff\x8c\xc5\xee\xffH\x90\xc5\xff\x04]\x9e\xff\x00V\x9a\xe7\x00\\\x9ej\x00\\\x9e\x03\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e.\x00Z\x9c\xb3\x00V\x99\xff\x17m\xad\xffV\xa3\xdc\xff{\xc2\xf6\xff|\xbf\xf3\xff|\xbf\xf1\xff\x7f\xc1\xf1\xff\x83\xc2\xf1\xff\x87\xc4\xf1\xff\x8b\xc5\xf1\xff\x8f\xc7\xf1\xff\x92\xc9\xf1\xff\x97\xcb\xf1\xff\x9b\xcc\xf1\xff\x9e\xcd\xf1\xff\xa6\xd3\xf4\xff\xa4\xd1\xf1\xff@\x88\xbd\xff\x00U\x99\xff\x00[\x9d\xb0\x00\\\x9e\x0c\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x02\x00[\x9d\x97\x00V\x98\xff\x1fv\xb6\xffa\xb1\xed\xffl\xbb\xf4\xffl\xb8\xf1\xffo\xba\xf1\xffr\xbb\xf1\xffv\xbd\xf1\xffz\xbe\xf1\xff~\xc0\xf1\xff\x81\xc2\xf1\xff\x85\xc3\xf1\xff\x8a\xc5\xf1\xff\x8d\xc6\xf1\xff\x93\xcb\xf2\xff\x9e\xd1\xf6\xff|\xb7\xe1\xff(w\xb2\xff\x00U\x99\xff\x00Y\x9c\xc6\x00\\\x9e?\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x0b\x00[\x9e\x86\x00V\x99\xf6\ta\xa2\xff=\x8f\xcc\xffm\xb9\xf1\xffu\xbf\xf5\xfft\xbc\xf1\xffy\xbd\xf1\xff|\xbf\xf1\xff\x7f\xc1\xf1\xff\x83\xc2\xf1\xff\x87\xc4\xf1\xff\x8b\xc5\xf1\xff\x8f\xc7\xf1\xff\x92\xc9\xf1\xff\x97\xcb\xf1\xff\x9b\xcc\xf1\xff\x9e\xcd\xf1\xff\xa1\xcf\xf1\xff\xa8\xd3\xf3\xff\xae\xd8\xf4\xffX\x99\xc9\xff\x00X\x9b\xff\x00Y\x9c\xc2\x00\\\x9e\x1b\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\r\x00[\x9d\xab\x00W\x99\xff,\x82\xc1\xffe\xb5\xf2\xffh\xb7\xf3\xffh\xb7\xf1\xffl\xb8\xf1\xffo\xba\xf1\xffr\xbb\xf1\xffv\xbd\xf1\xffz\xbe\xf1\xff~\xc0\xf1\xff\x81\xc2\xf1\xff\x85\xc3\xf1\xff\x8a\xc5\xf1\xff\x8d\xc6\xf1\xff\x90\xc9\xf1\xff\x95\xca\xf1\xff\x9f\xd1\xf5\xff\xa0\xcf\xf3\xffe\xa3\xd1\xff\x12f\xa5\xff\x00U\x98\xff\x00[\x9d\x9b\x00\\\x9e\x16\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9eN\x00Y\x9b\xd3\x00Y\x9c\xff\'}\xbc\xff]\xad\xe8\xffp\xbe\xf6\xffn\xba\xf2\xffp\xba\xf1\xfft\xbc\xf1\xffy\xbd\xf1\xff|\xbf\xf1\xff\x7f\xc1\xf1\xff\x83\xc2\xf1\xff\x87\xc4\xf1\xff\x8b\xc5\xf1\xff\x8f\xc7\xf1\xff\x92\xc9\xf1\xff\x97\xcb\xf1\xff\x9b\xcc\xf1\xff\x9e\xcd\xf1\xff\xa1\xcf\xf1\xff\xa5\xd1\xf1\xff\xa9\xd4\xf2\xff\xb5\xdb\xf6\xffq\xaa\xd4\xff\x04[\x9e\xff\x00X\x9b\xdc\x00\\\x9e>\x00\\\x9e0\x00Z\x9c\xc9\x00Z\x9b\xff8\x8d\xcd\xffe\xb7\xf5\xffc\xb4\xf2\xffe\xb5\xf1\xffh\xb7\xf1\xffl\xb8\xf1\xffo\xba\xf1\xffr\xbb\xf1\xffv\xbd\xf1\xffz\xbe\xf1\xff~\xc0\xf1\xff\x81\xc2\xf1\xff\x85\xc3\xf1\xff\x8a\xc5\xf1\xff\x8d\xc6\xf1\xff\x90\xc9\xf1\xff\x95\xca\xf1\xff\x99\xcc\xf1\xff\x9d\xce\xf2\xff\xa9\xd5\xf6\xff\x99\xc9\xec\xffI\x8e\xc1\xff\x03[\x9d\xff\x00V\x9a\xe1\x00\\\x9ea\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e(\x00[\x9d\xab\x00V\x98\xff\x13j\xab\xffK\x9e\xdc\xffi\xb9\xf6\xffj\xb8\xf3\xffj\xb8\xf1\xffm\xb9\xf1\xffp\xba\xf1\xfft\xbc\xf1\xffy\xbd\xf1\xff|\xbf\xf1\xff\x7f\xc1\xf1\xff\x83\xc2\xf1\xff\x87\xc4\xf1\xff\x8b\xc5\xf1\xff\x8f\xc7\xf1\xff\x92\xc9\xf1\xff\x97\xcb\xf1\xff\x9b\xcc\xf1\xff\x9e\xcd\xf1\xff\xa1\xcf\xf1\xff\xa5\xd1\xf1\xff\xa7\xd3\xf1\xff\xaa\xd4\xf1\xff\xb9\xdc\xf6\xff\x80\xb5\xda\xff\rb\xa2\xff\x00W\x9a\xff\x00Y\x9b\xfe\x04]\x9f\xff>\x94\xd4\xffd\xb6\xf6\xff`\xb3\xf1\xffb\xb3\xf1\xffe\xb5\xf1\xffh\xb7\xf1\xffl\xb8\xf1\xffo\xba\xf1\xffr\xbb\xf1\xffv\xbd\xf1\xffz\xbe\xf1\xff~\xc0\xf1\xff\x81\xc2\xf1\xff\x85\xc3\xf1\xff\x8a\xc5\xf1\xff\x8d\xc6\xf1\xff\x90\xc9\xf1\xff\x95\xca\xf1\xff\x99\xcc\xf1\xff\x9c\xcd\xf1\xff\x9f\xce\xf1\xff\xa6\xd2\xf3\xff\xb0\xd9\xf6\xff\x87\xbb\xe0\xff\'u\xaf\xff\x00T\x98\xff\x00Y\x9c\xbd\x00\\\x9e7\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x08\x00\\\x9e~\x00W\x99\xf2\x05^\x9f\xff3\x89\xc9\xff^\xb1\xf0\xffe\xb7\xf5\xffd\xb4\xf1\xffg\xb6\xf1\xffj\xb8\xf1\xffm\xb9\xf1\xffp\xba\xf1\xfft\xbc\xf1\xffy\xbd\xf1\xff|\xbf\xf1\xff\x7f\xc1\xf1\xff\x83\xc2\xf1\xff\x87\xc4\xf1\xff\x8b\xc5\xf1\xff\x8f\xc7\xf1\xff\x92\xc9\xf1\xff\x97\xcb\xf1\xff\x9b\xcc\xf1\xff\x9e\xcd\xf1\xff\xa1\xcf\xf1\xff\xa5\xd1\xf1\xff\xa7\xd3\xf1\xff\xaa\xd4\xf1\xff\xad\xd4\xf1\xff\xbb\xdd\xf6\xff\x96\xc3\xe4\xff\x18i\xa7\xff\x01]\xa2\xffH\x9e\xde\xffa\xb6\xf6\xff^\xb1\xf1\xff`\xb3\xf1\xffb\xb3\xf1\xffe\xb5\xf1\xffh\xb7\xf1\xffl\xb8\xf1\xffo\xba\xf1\xffr\xbb\xf1\xffv\xbd\xf1\xffz\xbe\xf1\xff~\xc0\xf1\xff\x81\xc2\xf1\xff\x85\xc3\xf1\xff\x8a\xc5\xf1\xff\x8d\xc6\xf1\xff\x90\xc9\xf1\xff\x95\xca\xf1\xff\x99\xcc\xf1\xff\x9c\xcd\xf1\xff\x9f\xce\xf1\xff\xa3\xd0\xf1\xff\xa6\xd2\xf1\xff\xb0\xd8\xf5\xff\xad\xd5\xf1\xfff\xa2\xce\xff\rb\xa2\xff\x00U\x99\xfb\x00\\\x9e\x92\x00\\\x9e\x11\x00\\\x9e\x9b\x02\\\x9e\xff\x1ct\xb5\xffM\xa3\xe3\xffb\xb7\xf6\xff`\xb3\xf2\xffa\xb3\xf1\xffd\xb4\xf1\xffg\xb6\xf1\xffj\xb8\xf1\xffm\xb9\xf1\xffp\xba\xf1\xfft\xbc\xf1\xffy\xbd\xf1\xff|\xbf\xf1\xff\x7f\xc1\xf1\xff\x83\xc2\xf1\xff\x87\xc4\xf1\xff\x8b\xc5\xf1\xff\x8f\xc7\xf1\xff\x92\xc9\xf1\xff\x97\xcb\xf1\xff\x9b\xcc\xf1\xff\x9e\xcd\xf1\xff\xa1\xcf\xf1\xff\xa5\xd1\xf1\xff\xa7\xd3\xf1\xff\xaa\xd4\xf1\xff\xad\xd4\xf1\xff\xae\xd5\xf1\xff\xb7\xdb\xf4\xff\xaa\xcf\xe8\xffm\xb3\xe6\xffX\xb2\xf4\xffX\xae\xf1\xff^\xb1\xf1\xff`\xb3\xf1\xffb\xb3\xf1\xffe\xb5\xf1\xffh\xb7\xf1\xffl\xb8\xf1\xffo\xba\xf1\xffr\xbb\xf1\xffv\xbd\xf1\xffz\xbe\xf1\xff~\xc0\xf1\xff\x81\xc2\xf1\xff\x85\xc3\xf1\xff\x8a\xc5\xf1\xff\x8d\xc6\xf1\xff\x90\xc9\xf1\xff\x95\xca\xf1\xff\x99\xcc\xf1\xff\x9c\xcd\xf1\xff\x9f\xce\xf1\xff\xa3\xd0\xf1\xff\xa6\xd2\xf1\xff\xa9\xd3\xf1\xff\xae\xd5\xf2\xff\xba\xdd\xf7\xff\x9b\xc7\xe6\xff<\x83\xb8\xff\x06^\x9f\xff\x00[\x9d\xb6\x00Z\x9c\xdd\x0cd\xa6\xffR\xa9\xe9\xffb\xb7\xf8\xff\\\xb1\xf1\xff_\xb2\xf1\xffa\xb3\xf1\xffd\xb4\xf1\xffg\xb6\xf1\xffj\xb8\xf1\xffm\xb9\xf1\xffp\xba\xf1\xfft\xbc\xf1\xffy\xbd\xf1\xff|\xbf\xf1\xff\x7f\xc1\xf1\xff\x83\xc2\xf1\xff\x87\xc4\xf1\xff\x8b\xc5\xf1\xff\x8f\xc7\xf1\xff\x92\xc9\xf1\xff\x97\xcb\xf1\xff\x9b\xcc\xf1\xff\x9e\xcd\xf1\xff\xa1\xcf\xf1\xff\xa5\xd1\xf1\xff\xa7\xd3\xf1\xff\xaa\xd4\xf1\xff\xaa\xd2\xf0\xff\xb2\xd7\xf1\xff\xce\xe5\xf6\xff\xe9\xf5\xfd\xff\xd0\xeb\xfe\xff\xa1\xd2\xf7\xffg\xb6\xf2\xffW\xad\xf0\xff_\xb2\xf1\xffb\xb3\xf1\xffe\xb5\xf1\xffh\xb7\xf1\xffl\xb8\xf1\xffo\xba\xf1\xffr\xbb\xf1\xffv\xbd\xf1\xffz\xbe\xf1\xff~\xc0\xf1\xff\x81\xc2\xf1\xff\x85\xc3\xf1\xff\x8a\xc5\xf1\xff\x8d\xc6\xf1\xff\x90\xc9\xf1\xff\x95\xca\xf1\xff\x99\xcc\xf1\xff\x9c\xcd\xf1\xff\x9f\xce\xf1\xff\xa3\xd0\xf1\xff\xa6\xd2\xf1\xff\xa9\xd3\xf1\xff\xac\xd4\xf1\xff\xae\xd4\xf1\xff\xbf\xe0\xf7\xff\xac\xd2\xee\xff\x1eo\xaa\xff\x00X\x9b\xeb\x00\\\x9eR\x00Y\x9b\xf6\x0ce\xa6\xffH\x9e\xde\xffb\xb6\xf6\xff_\xb2\xf1\xffa\xb3\xf1\xffd\xb4\xf1\xffg\xb6\xf1\xffj\xb8\xf1\xffm\xb9\xf1\xffp\xba\xf1\xfft\xbc\xf1\xffy\xbd\xf1\xff|\xbf\xf1\xff\x7f\xc1\xf1\xff\x83\xc2\xf1\xff\x87\xc4\xf1\xff\x8b\xc5\xf1\xff\x8f\xc7\xf1\xff\x92\xc9\xf1\xff\x97\xcb\xf1\xff\x9b\xcc\xf1\xff\x9e\xcd\xf1\xff\xa1\xcf\xf1\xff\xa5\xd1\xf1\xff\xa5\xd2\xf1\xff\xa8\xd2\xf0\xff\xbe\xdd\xf4\xff\xdd\xee\xfa\xff\xe9\xf3\xfc\xff\xe4\xf2\xfb\xff\xca\xe7\xfb\xff\xce\xe8\xfb\xff\xc3\xe2\xfa\xff\x89\xc6\xf5\xff]\xb1\xf1\xff]\xb1\xf0\xffe\xb5\xf1\xffh\xb7\xf1\xffl\xb8\xf1\xffo\xba\xf1\xffr\xbb\xf1\xffv\xbd\xf1\xffz\xbe\xf1\xff~\xc0\xf1\xff\x81\xc2\xf1\xff\x85\xc3\xf1\xff\x8a\xc5\xf1\xff\x8d\xc6\xf1\xff\x90\xc9\xf1\xff\x95\xca\xf1\xff\x99\xcc\xf1\xff\x9c\xcd\xf1\xff\x9f\xce\xf1\xff\xa3\xd0\xf1\xff\xa6\xd2\xf1\xff\xa9\xd3\xf1\xff\xac\xd4\xf1\xff\xba\xdd\xf6\xff\x93\xc1\xe3\xff\x1fo\xaa\xff\x00W\x9b\xff\x00\\\x9eo\x00\\\x9e\x00\x00\\\x9e;\x00Y\x9b\xdf\x03\\\x9e\xff;\x90\xd0\xffd\xb6\xf5\xffb\xb4\xf2\xffd\xb4\xf1\xffg\xb6\xf1\xffj\xb8\xf1\xffm\xb9\xf1\xffp\xba\xf1\xfft\xbc\xf1\xffy\xbd\xf1\xff|\xbf\xf1\xff\x7f\xc1\xf1\xff\x83\xc2\xf1\xff\x87\xc4\xf1\xff\x8b\xc5\xf1\xff\x8f\xc7\xf1\xff\x92\xc9\xf1\xff\x97\xcb\xf1\xff\x9b\xcc\xf1\xff\x9e\xcd\xf1\xff\xa0\xcf\xf1\xff\xa1\xcf\xf0\xff\xae\xd6\xf2\xff\xcf\xe6\xf8\xff\xe4\xf2\xfb\xff\xe5\xf2\xfb\xff\xe5\xf1\xfb\xff\xe4\xf2\xfb\xff\xca\xe7\xfb\xff\xc8\xe5\xfb\xff\xcb\xe7\xfb\xff\xd1\xe9\xfb\xff\xb3\xda\xf9\xffx\xbe\xf3\xff^\xb1\xf0\xfff\xb6\xf1\xffl\xb8\xf1\xffo\xba\xf1\xffr\xbb\xf1\xffv\xbd\xf1\xffz\xbe\xf1\xff~\xc0\xf1\xff\x81\xc2\xf1\xff\x85\xc3\xf1\xff\x8a\xc5\xf1\xff\x8d\xc6\xf1\xff\x90\xc9\xf1\xff\x95\xca\xf1\xff\x99\xcc\xf1\xff\x9c\xcd\xf1\xff\x9f\xce\xf1\xff\xa3\xd0\xf1\xff\xa6\xd2\xf1\xff\xaa\xd4\xf2\xff\xb7\xdb\xf6\xffx\xaf\xd6\xff\x0b`\xa1\xff\x00V\x9a\xed\x00\\\x9eR\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x1c\x00Z\x9c\xbe\x00X\x99\xff-\x83\xc2\xffe\xb6\xf3\xfff\xb6\xf3\xffg\xb6\xf1\xffj\xb8\xf1\xffm\xb9\xf1\xffp\xba\xf1\xfft\xbc\xf1\xffy\xbd\xf1\xff|\xbf\xf1\xff\x7f\xc1\xf1\xff\x83\xc2\xf1\xff\x87\xc4\xf1\xff\x8b\xc5\xf1\xff\x8f\xc7\xf1\xff\x92\xc9\xf1\xff\x97\xcb\xf1\xff\x9b\xcc\xf1\xff\x9b\xcc\xf0\xff\xa1\xcf\xf1\xff\xbf\xde\xf6\xff\xdc\xee\xfa\xff\xe3\xf1\xfb\xff\xe2\xf1\xfb\xff\xe3\xf1\xfb\xff\xe5\xf1\xfb\xff\xe4\xf2\xfb\xff\xca\xe7\xfb\xff\xc8\xe5\xfb\xff\xc9\xe6\xfb\xff\xcb\xe6\xfb\xff\xd2\xe8\xfb\xff\xd0\xe9\xfb\xff\xa2\xd2\xf7\xffm\xb9\xf1\xffe\xb5\xf0\xffo\xba\xf1\xffr\xbb\xf1\xffv\xbd\xf1\xffz\xbe\xf1\xff~\xc0\xf1\xff\x81\xc2\xf1\xff\x85\xc3\xf1\xff\x8a\xc5\xf1\xff\x8d\xc6\xf1\xff\x90\xc9\xf1\xff\x95\xca\xf1\xff\x99\xcc\xf1\xff\x9c\xcd\xf1\xff\x9f\xce\xf1\xff\xa3\xd0\xf1\xff\xa9\xd4\xf2\xff\xb1\xd9\xf5\xff[\x9b\xc9\xff\x00X\x9b\xff\x00Y\x9c\xd3\x00\\\x9e-\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x06\x00[\x9d\x96\x00V\x99\xff"x\xb8\xffa\xb1\xee\xffk\xba\xf4\xffj\xb8\xf1\xffm\xb9\xf1\xffp\xba\xf1\xfft\xbc\xf1\xffy\xbd\xf1\xff|\xbf\xf1\xff\x7f\xc1\xf1\xff\x83\xc2\xf1\xff\x87\xc4\xf1\xff\x8b\xc5\xf1\xff\x8f\xc7\xf1\xff\x92\xc9\xf1\xff\x96\xca\xf1\xff\x97\xca\xf0\xff\xac\xd5\xf3\xff\xd0\xe7\xf9\xff\xe0\xef\xfb\xff\xdf\xef\xfb\xff\xe0\xf0\xfb\xff\xe2\xf1\xfb\xff\xe3\xf1\xfb\xff\xe5\xf1\xfb\xff\xe4\xf2\xfb\xff\xca\xe7\xfb\xff\xc8\xe5\xfb\xff\xc9\xe6\xfb\xff\xcb\xe6\xfb\xff\xcd\xe6\xfb\xff\xd0\xea\xfb\xff\xd8\xec\xfb\xff\xc8\xe5\xfa\xff\x8f\xc9\xf4\xffi\xb7\xf0\xffo\xb9\xf1\xffv\xbd\xf1\xffz\xbe\xf1\xff~\xc0\xf1\xff\x81\xc2\xf1\xff\x85\xc3\xf1\xff\x8a\xc5\xf1\xff\x8d\xc6\xf1\xff\x90\xc9\xf1\xff\x95\xca\xf1\xff\x99\xcc\xf1\xff\x9c\xcd\xf1\xff\x9f\xce\xf1\xff\xa8\xd4\xf4\xff\xa6\xd2\xf1\xffE\x8c\xbf\xff\x00U\x99\xff\x00Z\x9d\xaf\x00\\\x9e\x12\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9en\x00V\x98\xfe\x14k\xac\xffY\xaa\xe5\xffp\xbd\xf6\xffm\xb9\xf1\xffp\xba\xf1\xfft\xbc\xf1\xffy\xbd\xf1\xff|\xbf\xf1\xff\x7f\xc1\xf1\xff\x83\xc2\xf1\xff\x87\xc4\xf1\xff\x8b\xc5\xf1\xff\x8f\xc7\xf1\xff\x8e\xc7\xf0\xff\x9a\xcc\xf1\xff\xbd\xde\xf7\xff\xd8\xec\xfb\xff\xdc\xed\xfb\xff\xdc\xed\xfb\xff\xde\xef\xfb\xff\xe0\xf0\xfb\xff\xe2\xf1\xfb\xff\xe3\xf1\xfb\xff\xe5\xf1\xfb\xff\xe4\xf2\xfb\xff\xca\xe7\xfb\xff\xc8\xe5\xfb\xff\xc9\xe6\xfb\xff\xcb\xe6\xfb\xff\xcd\xe6\xfb\xff\xcf\xe9\xfb\xff\xd1\xe9\xfb\xff\xd6\xec\xfb\xff\xda\xed\xfb\xff\xb6\xdc\xf8\xff\x80\xc1\xf2\xffo\xb9\xf0\xffy\xbd\xf1\xff~\xc0\xf1\xff\x81\xc2\xf1\xff\x85\xc3\xf1\xff\x8a\xc5\xf1\xff\x8d\xc6\xf1\xff\x90\xc9\xf1\xff\x95\xca\xf1\xff\x99\xcc\xf1\xff\x9c\xcd\xf1\xff\xa7\xd4\xf5\xff\x95\xc7\xea\xff+y\xb2\xff\x00T\x98\xff\x00[\x9e\x88\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9eQ\x00W\x9a\xee\x08a\xa2\xffL\x9d\xd8\xfft\xbf\xf6\xffq\xbb\xf2\xfft\xbc\xf1\xffy\xbd\xf1\xff|\xbf\xf1\xff\x7f\xc1\xf1\xff\x83\xc2\xf1\xff\x87\xc4\xf1\xff\x88\xc4\xf1\xff\x8d\xc6\xf0\xff\xaa\xd5\xf4\xff\xcd\xe7\xfa\xff\xd8\xed\xfb\xff\xd7\xec\xfb\xff\xda\xec\xfb\xff\xdc\xed\xfb\xff\xde\xef\xfb\xff\xe0\xf0\xfb\xff\xe2\xf1\xfb\xff\xe3\xf1\xfb\xff\xe5\xf1\xfb\xff\xe4\xf2\xfb\xff\xca\xe7\xfb\xff\xc8\xe5\xfb\xff\xc9\xe6\xfb\xff\xcb\xe6\xfb\xff\xcd\xe6\xfb\xff\xcf\xe9\xfb\xff\xd1\xe9\xfb\xff\xd3\xea\xfb\xff\xd5\xeb\xfb\xff\xdd\xef\xfc\xff\xd7\xeb\xfb\xff\xa6\xd4\xf5\xff{\xbe\xf1\xffy\xbd\xf1\xff\x81\xc2\xf1\xff\x85\xc3\xf1\xff\x8a\xc5\xf1\xff\x8d\xc6\xf1\xff\x90\xc9\xf1\xff\x95\xca\xf1\xff\x99\xcc\xf1\xff\xa6\xd4\xf6\xff~\xb6\xdf\xff\x15h\xa7\xff\x00U\x99\xf9\x00\\\x9ek\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e-\x00Y\x9c\xd2\x01Y\x9c\xff<\x8e\xca\xffu\xbe\xf4\xffv\xbe\xf2\xffy\xbd\xf1\xff|\xbf\xf1\xff\x7f\xc1\xf1\xff\x82\xc1\xf1\xff\x83\xc1\xf0\xff\x97\xcb\xf3\xff\xbe\xe0\xf8\xff\xd4\xeb\xfb\xff\xd5\xeb\xfb\xff\xd5\xeb\xfb\xff\xd7\xec\xfb\xff\xda\xec\xfb\xff\xdc\xed\xfb\xff\xde\xef\xfb\xff\xe0\xf0\xfb\xff\xe2\xf1\xfb\xff\xe3\xf1\xfb\xff\xe5\xf1\xfb\xff\xe4\xf2\xfb\xff\xca\xe7\xfb\xff\xc8\xe5\xfb\xff\xc9\xe6\xfb\xff\xcb\xe6\xfb\xff\xcd\xe6\xfb\xff\xcf\xe9\xfb\xff\xd1\xe9\xfb\xff\xd3\xea\xfb\xff\xd5\xeb\xfb\xff\xd7\xec\xfb\xff\xdc\xee\xfb\xff\xe3\xf0\xfc\xff\xcd\xe7\xf9\xff\x98\xcc\xf3\xff|\xbf\xf0\xff\x82\xc2\xf1\xff\x8a\xc5\xf1\xff\x8d\xc6\xf1\xff\x90\xc9\xf1\xff\x96\xcb\xf2\xff\xa1\xd2\xf5\xffc\xa3\xd2\xff\x06]\x9f\xff\x00W\x9b\xe5\x00\\\x9eC\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x12\x00[\x9d\xaf\x00V\x98\xff.\x81\xbe\xffv\xbd\xf2\xff|\xc0\xf4\xff|\xbf\xf1\xff{\xbf\xf0\xff\x83\xc2\xf1\xff\xaa\xd5\xf6\xff\xcc\xe6\xfb\xff\xd1\xea\xfb\xff\xd1\xe9\xfb\xff\xd3\xea\xfb\xff\xd5\xeb\xfb\xff\xd7\xec\xfb\xff\xda\xec\xfb\xff\xdc\xed\xfb\xff\xde\xef\xfb\xff\xe0\xf0\xfb\xff\xe2\xf1\xfb\xff\xe3\xf1\xfb\xff\xe5\xf1\xfb\xff\xe4\xf2\xfb\xff\xca\xe7\xfb\xff\xc8\xe5\xfb\xff\xc9\xe6\xfb\xff\xcb\xe6\xfb\xff\xcd\xe6\xfb\xff\xcf\xe9\xfb\xff\xd1\xe9\xfb\xff\xd3\xea\xfb\xff\xd5\xeb\xfb\xff\xd7\xec\xfb\xff\xda\xed\xfb\xff\xdc\xed\xfb\xff\xe2\xf1\xfb\xff\xe3\xf2\xfb\xff\xbe\xdf\xf7\xff\x8b\xc6\xf1\xff\x84\xc2\xf0\xff\x8c\xc5\xf1\xff\x94\xcb\xf3\xff\x9b\xcf\xf4\xffK\x92\xc6\xff\x00W\x9a\xff\x00Y\x9c\xc7\x00\\\x9e#\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x8c\x00V\x98\xfd u\xb3\xffn\xb4\xe8\xff~\xc0\xf3\xff\x94\xca\xf4\xff\xbe\xe0\xf9\xff\xcf\xe8\xfb\xff\xcd\xe6\xfb\xff\xce\xe9\xfb\xff\xd1\xe9\xfb\xff\xd3\xea\xfb\xff\xd5\xeb\xfb\xff\xd7\xec\xfb\xff\xda\xec\xfb\xff\xdc\xed\xfb\xff\xde\xef\xfb\xff\xe0\xf0\xfb\xff\xe2\xf1\xfb\xff\xe3\xf1\xfb\xff\xe5\xf1\xfb\xff\xe4\xf2\xfb\xff\xca\xe7\xfb\xff\xc8\xe5\xfb\xff\xc9\xe6\xfb\xff\xcb\xe6\xfb\xff\xcd\xe6\xfb\xff\xcf\xe9\xfb\xff\xd1\xe9\xfb\xff\xd3\xea\xfb\xff\xd5\xeb\xfb\xff\xd7\xec\xfb\xff\xda\xed\xfb\xff\xdc\xed\xfb\xff\xde\xef\xfb\xff\xe1\xf0\xfb\xff\xe8\xf3\xfb\xff\xdb\xed\xfa\xff\xac\xd5\xf4\xff\x8f\xc7\xf2\xff\x89\xc3\xed\xff6\x83\xbb\xff\x00U\x99\xff\x00[\x9d\xa9\x00\\\x9e\n\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x07\x00\\\x9e\xf1\x00Q\x95\xff\x18p\xb0\xff\x98\xcd\xf5\xff\xd4\xeb\xfd\xff\xce\xe8\xfb\xff\xcb\xe6\xfb\xff\xcc\xe6\xfb\xff\xce\xe9\xfb\xff\xd1\xe9\xfb\xff\xd3\xea\xfb\xff\xd5\xeb\xfb\xff\xd7\xec\xfb\xff\xda\xec\xfb\xff\xdc\xed\xfb\xff\xde\xef\xfb\xff\xe0\xf0\xfb\xff\xe2\xf1\xfb\xff\xe3\xf1\xfb\xff\xe5\xf1\xfb\xff\xe4\xf2\xfb\xff\xca\xe7\xfb\xff\xc8\xe5\xfb\xff\xc9\xe6\xfb\xff\xcb\xe6\xfb\xff\xcd\xe6\xfb\xff\xcf\xe9\xfb\xff\xd1\xe9\xfb\xff\xd3\xea\xfb\xff\xd5\xeb\xfb\xff\xd7\xec\xfb\xff\xda\xed\xfb\xff\xdc\xed\xfb\xff\xde\xef\xfb\xff\xe0\xf0\xfb\xff\xe2\xf1\xfb\xff\xe6\xf3\xfb\xff\xf2\xf8\xfd\xff\xc9\xe5\xf9\xff1\x81\xba\xff\x00O\x94\xff\x00\\\x9e\xff\x00\\\x9e\'\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e}\x00V\x99\xfc\x1ap\xae\xffc\xad\xe4\xffM\xa8\xef\xff\x83\xc2\xf3\xff\xc6\xe4\xfb\xff\xd1\xe9\xfc\xff\xcc\xe6\xfb\xff\xce\xe9\xfb\xff\xd1\xe9\xfb\xff\xd3\xea\xfb\xff\xd5\xeb\xfb\xff\xd7\xec\xfb\xff\xda\xec\xfb\xff\xdc\xed\xfb\xff\xde\xef\xfb\xff\xe0\xf0\xfb\xff\xe2\xf1\xfb\xff\xe3\xf1\xfb\xff\xe5\xf1\xfb\xff\xe4\xf2\xfb\xff\xca\xe7\xfb\xff\xc8\xe5\xfb\xff\xc9\xe6\xfb\xff\xcb\xe6\xfb\xff\xcd\xe6\xfb\xff\xcf\xe9\xfb\xff\xd1\xe9\xfb\xff\xd3\xea\xfb\xff\xd5\xeb\xfb\xff\xd7\xec\xfb\xff\xda\xed\xfb\xff\xdc\xed\xfb\xff\xde\xef\xfb\xff\xe0\xf0\xfb\xff\xe7\xf4\xfc\xff\xe7\xf3\xfb\xff\xb6\xd8\xf4\xff{\xbc\xee\xff\x7f\xbd\xe9\xff/}\xb7\xff\x00U\x99\xff\x00[\x9d\x9d\x00\\\x9e\x06\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x0b\x00[\x9d\xa2\x00U\x98\xff\'{\xb9\xffs\xbb\xef\xff{\xc0\xf4\xff@\xa1\xed\xff3\x99\xeb\xffW\xac\xee\xff\xa7\xd4\xf7\xff\xd3\xe9\xfc\xff\xd1\xeb\xfb\xff\xd1\xe9\xfb\xff\xd3\xea\xfb\xff\xd5\xeb\xfb\xff\xd7\xec\xfb\xff\xda\xec\xfb\xff\xdc\xed\xfb\xff\xde\xef\xfb\xff\xe0\xf0\xfb\xff\xe2\xf1\xfb\xff\xe3\xf1\xfb\xff\xe5\xf1\xfb\xff\xe4\xf2\xfb\xff\xca\xe7\xfb\xff\xc8\xe5\xfb\xff\xc9\xe6\xfb\xff\xcb\xe6\xfb\xff\xcd\xe6\xfb\xff\xcf\xe9\xfb\xff\xd1\xe9\xfb\xff\xd3\xea\xfb\xff\xd5\xeb\xfb\xff\xd7\xec\xfb\xff\xda\xed\xfb\xff\xdc\xed\xfb\xff\xe0\xf0\xfb\xff\xea\xf5\xfc\xff\xcc\xe5\xf8\xff~\xbe\xee\xffX\xaa\xe9\xffc\xb0\xe9\xff\x92\xca\xf3\xff\x9a\xcd\xf3\xffC\x8d\xc2\xff\x00U\x99\xff\x00Z\x9c\xbd\x00\\\x9e\x1c\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e%\x00Z\x9c\xc9\x00X\x9b\xff6\x8a\xc6\xffs\xbd\xf3\xffw\xbe\xf3\xffv\xbc\xf1\xffC\xa2\xed\xff<\x9e\xec\xff>\x9f\xeb\xffE\xa2\xeb\xff}\xbf\xf1\xff\xc3\xe3\xfa\xff\xd8\xed\xfc\xff\xd4\xeb\xfb\xff\xd5\xeb\xfb\xff\xd7\xec\xfb\xff\xda\xec\xfb\xff\xdc\xed\xfb\xff\xde\xef\xfb\xff\xe0\xf0\xfb\xff\xe2\xf1\xfb\xff\xe3\xf1\xfb\xff\xe5\xf1\xfb\xff\xe4\xf2\xfb\xff\xca\xe7\xfb\xff\xc8\xe5\xfb\xff\xc9\xe6\xfb\xff\xcb\xe6\xfb\xff\xcd\xe6\xfb\xff\xcf\xe9\xfb\xff\xd1\xe9\xfb\xff\xd3\xea\xfb\xff\xd5\xeb\xfb\xff\xd7\xec\xfb\xff\xdb\xed\xfb\xff\xe4\xf1\xfc\xff\xda\xed\xfb\xff\x97\xca\xf2\xffV\xa9\xea\xffS\xa7\xe9\xff_\xad\xea\xffg\xb2\xea\xff\x8d\xc7\xf1\xff\x97\xcc\xf2\xff\xa1\xd1\xf5\xff\\\x9e\xcf\xff\x03[\x9d\xff\x00X\x9b\xdf\x00\\\x9e<\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9eH\x00X\x9a\xe8\x06_\xa0\xffH\x99\xd5\xffs\xbf\xf6\xffq\xbb\xf2\xffu\xbc\xf1\xffv\xbc\xf1\xffC\xa2\xed\xff<\x9e\xec\xffC\xa2\xec\xffH\xa4\xec\xffG\xa4\xeb\xff\\\xad\xed\xff\x9e\xcf\xf5\xff\xd4\xea\xfb\xff\xda\xee\xfc\xff\xd7\xec\xfb\xff\xda\xec\xfb\xff\xdc\xed\xfb\xff\xde\xef\xfb\xff\xe0\xf0\xfb\xff\xe2\xf1\xfb\xff\xe3\xf1\xfb\xff\xe5\xf1\xfb\xff\xe4\xf2\xfb\xff\xca\xe7\xfb\xff\xc8\xe5\xfb\xff\xc9\xe6\xfb\xff\xcb\xe6\xfb\xff\xcd\xe6\xfb\xff\xcf\xe9\xfb\xff\xd1\xe9\xfb\xff\xd3\xea\xfb\xff\xd5\xeb\xfb\xff\xdd\xef\xfc\xff\xe1\xf0\xfc\xff\xac\xd5\xf5\xff\\\xad\xec\xffB\xa0\xe9\xffQ\xa7\xea\xffZ\xab\xea\xff_\xad\xea\xffg\xb2\xea\xff\x8d\xc7\xf1\xff\x95\xca\xf1\xff\x9a\xcc\xf1\xff\xa6\xd4\xf6\xffy\xb2\xdd\xff\x11f\xa5\xff\x00V\x99\xf6\x00\\\x9ed\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9ef\x00V\x99\xfc\x11h\xa9\xffV\xa7\xe2\xffp\xbd\xf6\xffl\xb9\xf1\xffp\xba\xf1\xffu\xbc\xf1\xffv\xbc\xf1\xffC\xa2\xed\xff<\x9e\xec\xffC\xa2\xec\xffI\xa4\xec\xffO\xa8\xec\xffR\xa9\xec\xffS\xa9\xeb\xffx\xbb\xef\xff\xba\xdd\xf7\xff\xdd\xef\xfc\xff\xdc\xed\xfb\xff\xdc\xed\xfb\xff\xde\xef\xfb\xff\xe0\xf0\xfb\xff\xe2\xf1\xfb\xff\xe3\xf1\xfb\xff\xe5\xf1\xfb\xff\xe4\xf2\xfb\xff\xca\xe7\xfb\xff\xc8\xe5\xfb\xff\xc9\xe6\xfb\xff\xcb\xe6\xfb\xff\xcd\xe6\xfb\xff\xcf\xe9\xfb\xff\xd1\xe9\xfb\xff\xd5\xeb\xfb\xff\xdf\xf0\xfc\xff\xc1\xe1\xf9\xffk\xb5\xef\xff8\x9b\xe9\xff@\xa0\xe9\xffL\xa5\xea\xffS\xa8\xea\xffZ\xab\xea\xff_\xad\xea\xffg\xb2\xea\xff\x8d\xc7\xf1\xff\x95\xca\xf1\xff\x99\xcc\xf1\xff\x9c\xcd\xf1\xff\xa8\xd5\xf5\xff\x91\xc4\xe8\xff\'u\xb0\xff\x00T\x98\xff\x00\\\x9e\x83\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x04\x00[\x9d\x90\x00W\x98\xff\x1fv\xb6\xff_\xaf\xec\xffk\xba\xf5\xffi\xb8\xf1\xffl\xb9\xf1\xffp\xba\xf1\xffu\xbc\xf1\xffv\xbc\xf1\xffC\xa2\xed\xff<\x9e\xec\xffC\xa2\xec\xffI\xa4\xec\xffO\xa8\xec\xffU\xaa\xec\xff[\xad\xec\xff\\\xad\xeb\xffc\xb1\xeb\xff\x99\xcc\xf2\xff\xd4\xe9\xfa\xff\xe2\xf0\xfc\xff\xdf\xef\xfb\xff\xe0\xf0\xfb\xff\xe2\xf1\xfb\xff\xe3\xf1\xfb\xff\xe5\xf1\xfb\xff\xe4\xf2\xfb\xff\xca\xe7\xfb\xff\xc8\xe5\xfb\xff\xc9\xe6\xfb\xff\xcb\xe6\xfb\xff\xcd\xe6\xfb\xff\xcf\xe9\xfb\xff\xd9\xed\xfc\xff\xd4\xea\xfb\xff\x87\xc4\xf3\xff6\x9b\xea\xff/\x98\xe9\xff>\x9f\xea\xffF\xa3\xea\xffL\xa5\xea\xffS\xa8\xea\xffZ\xab\xea\xff_\xad\xea\xffg\xb2\xea\xff\x8d\xc7\xf1\xff\x95\xca\xf1\xff\x99\xcc\xf1\xff\x9c\xcd\xf1\xff\x9f\xce\xf1\xff\xa9\xd4\xf4\xff\xa5\xd1\xf0\xffB\x89\xbd\xff\x00U\x99\xff\x00[\x9d\xab\x00\\\x9e\x10\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x19\x00Z\x9d\xb9\x00W\x99\xff*\x81\xc0\xffc\xb5\xf2\xfff\xb6\xf3\xfff\xb6\xf1\xffi\xb8\xf1\xffl\xb9\xf1\xffp\xba\xf1\xffu\xbc\xf1\xffv\xbc\xf1\xffC\xa2\xed\xff<\x9e\xec\xffC\xa2\xec\xffI\xa4\xec\xffO\xa8\xec\xffU\xaa\xec\xff[\xad\xec\xffa\xb0\xec\xffe\xb2\xec\xfff\xb2\xeb\xff}\xbd\xed\xff\xb8\xda\xf5\xff\xe1\xf0\xfb\xff\xe4\xf2\xfc\xff\xe2\xf1\xfb\xff\xe3\xf1\xfb\xff\xe5\xf1\xfb\xff\xe3\xf2\xfb\xff\xc8\xe6\xfb\xff\xc8\xe5\xfb\xff\xc9\xe6\xfb\xff\xcb\xe6\xfb\xff\xd2\xe8\xfb\xff\xd8\xee\xfc\xff\xa5\xd2\xf7\xffG\xa2\xed\xff!\x90\xe9\xff0\x98\xea\xff9\x9d\xea\xff?\x9f\xea\xffF\xa3\xea\xffL\xa5\xea\xffS\xa8\xea\xffZ\xab\xea\xff_\xad\xea\xffg\xb2\xea\xff\x8d\xc7\xf1\xff\x95\xca\xf1\xff\x99\xcc\xf1\xff\x9c\xcd\xf1\xff\x9f\xce\xf1\xff\xa3\xd0\xf1\xff\xa9\xd4\xf2\xff\xb0\xd9\xf5\xffX\x99\xc8\xff\x00W\x9b\xff\x00Y\x9c\xd1\x00\\\x9e,\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e9\x00Y\x9b\xdc\x03\\\x9d\xff9\x8f\xce\xffd\xb6\xf5\xffb\xb4\xf2\xffc\xb4\xf1\xfff\xb6\xf1\xffi\xb8\xf1\xffl\xb9\xf1\xffp\xba\xf1\xffu\xbc\xf1\xffv\xbc\xf1\xffC\xa2\xed\xff<\x9e\xec\xffC\xa2\xec\xffI\xa4\xec\xffO\xa8\xec\xffU\xaa\xec\xff[\xad\xec\xffa\xb0\xec\xfff\xb2\xec\xffm\xb5\xec\xffp\xb7\xeb\xfft\xb7\xeb\xff\x97\xc9\xf0\xff\xcf\xe7\xf8\xff\xe7\xf4\xfc\xff\xe4\xf2\xfb\xff\xe3\xf0\xfb\xff\xe9\xf4\xfb\xff\xd6\xec\xfc\xff\xc5\xe3\xfb\xff\xca\xe6\xfb\xff\xd7\xec\xfc\xff\xbb\xdd\xf9\xff]\xaf\xf0\xff\x1b\x8d\xe9\xff\x1f\x8e\xe9\xff,\x96\xea\xff3\x99\xea\xff9\x9d\xea\xff?\x9f\xea\xffF\xa3\xea\xffL\xa5\xea\xffS\xa8\xea\xffZ\xab\xea\xff_\xad\xea\xffg\xb2\xea\xff\x8d\xc7\xf1\xff\x95\xca\xf1\xff\x99\xcc\xf1\xff\x9c\xcd\xf1\xff\x9f\xce\xf1\xff\xa3\xd0\xf1\xff\xa6\xd2\xf1\xff\xaa\xd4\xf2\xff\xb7\xdb\xf6\xffv\xae\xd6\xff\n`\xa0\xff\x00W\x9a\xed\x00\\\x9eQ\x00\\\x9e\x00\x00\\\x9eP\x00Y\x9b\xf5\x0cd\xa6\xffF\x9c\xdc\xffb\xb6\xf6\xff_\xb2\xf1\xffa\xb3\xf1\xffc\xb4\xf1\xfff\xb6\xf1\xffi\xb8\xf1\xffl\xb9\xf1\xffp\xba\xf1\xffu\xbc\xf1\xffv\xbc\xf1\xffC\xa2\xed\xff<\x9e\xec\xffC\xa2\xec\xffI\xa4\xec\xffO\xa8\xec\xffU\xaa\xec\xff[\xad\xec\xffa\xb0\xec\xfff\xb2\xec\xffm\xb5\xec\xffs\xb8\xec\xffy\xba\xec\xffy\xba\xeb\xff\x83\xbf\xec\xff\xb0\xd6\xf2\xff\xe1\xf0\xfa\xff\xf5\xfa\xfe\xff\xfe\xff\xff\xff\xff\xff\xff\xff\xf1\xf8\xfe\xff\xd2\xe9\xfb\xffz\xbd\xf4\xff \x90\xeb\xff\x10\x87\xe9\xff \x8e\xea\xff&\x92\xea\xff,\x96\xea\xff3\x99\xea\xff9\x9d\xea\xff?\x9f\xea\xffF\xa3\xea\xffL\xa5\xea\xffS\xa8\xea\xffZ\xab\xea\xff_\xad\xea\xffg\xb2\xea\xff\x8d\xc7\xf1\xff\x95\xca\xf1\xff\x99\xcc\xf1\xff\x9c\xcd\xf1\xff\x9f\xce\xf1\xff\xa3\xd0\xf1\xff\xa6\xd2\xf1\xff\xa9\xd3\xf1\xff\xac\xd4\xf1\xff\xba\xdd\xf6\xff\x93\xc1\xe3\xff\x1eo\xaa\xff\x00X\x9b\xff\x00\\\x9ep\x00Z\x9c\xd6\x0bc\xa4\xffQ\xa7\xe7\xffb\xb8\xf9\xff\\\xb1\xf1\xff_\xb2\xf1\xffa\xb3\xf1\xffc\xb4\xf1\xfff\xb6\xf1\xffi\xb8\xf1\xffl\xb9\xf1\xffp\xba\xf1\xffu\xbc\xf1\xffv\xbc\xf1\xffC\xa2\xed\xff<\x9e\xec\xffC\xa2\xec\xffI\xa4\xec\xffO\xa8\xec\xffU\xaa\xec\xff[\xad\xec\xffa\xb0\xec\xfff\xb2\xec\xffm\xb5\xec\xffs\xb8\xec\xffy\xba\xec\xff~\xbd\xec\xff\x82\xbe\xec\xff\x84\xbf\xeb\xff\xa1\xce\xef\xff\xdf\xee\xf9\xff\xff\xff\xff\xff\xff\xff\xff\xff\xce\xe7\xfb\xffJ\xa5\xee\xff\x08\x83\xe9\xff\x12\x89\xea\xff\x1b\x8d\xea\xff!\x8f\xea\xff&\x92\xea\xff,\x96\xea\xff3\x99\xea\xff9\x9d\xea\xff?\x9f\xea\xffF\xa3\xea\xffL\xa5\xea\xffS\xa8\xea\xffZ\xab\xea\xff_\xad\xea\xffg\xb2\xea\xff\x8d\xc7\xf1\xff\x95\xca\xf1\xff\x99\xcc\xf1\xff\x9c\xcd\xf1\xff\x9f\xce\xf1\xff\xa3\xd0\xf1\xff\xa6\xd2\xf1\xff\xa9\xd3\xf1\xff\xac\xd4\xf1\xff\xae\xd5\xf1\xff\xbf\xe0\xf7\xff\xab\xd2\xed\xff\x1en\xaa\xff\x00X\x9b\xeb\x00[\x9d\x90\x02\\\x9e\xff\x1bs\xb4\xffM\xa2\xe2\xffb\xb7\xf6\xff`\xb3\xf2\xffa\xb3\xf1\xffc\xb4\xf1\xfff\xb6\xf1\xffi\xb8\xf1\xffl\xb9\xf1\xffp\xba\xf1\xffu\xbc\xf1\xffv\xbc\xf1\xffC\xa2\xed\xff<\x9e\xec\xffC\xa2\xec\xffI\xa4\xec\xffO\xa8\xec\xffU\xaa\xec\xff[\xad\xec\xffa\xb0\xec\xfff\xb2\xec\xffm\xb5\xec\xffs\xb8\xec\xffy\xba\xec\xff\x7f\xbd\xec\xff\x89\xc1\xed\xff\x92\xc6\xed\xff\x93\xc7\xed\xff\x95\xc7\xec\xff\xc0\xde\xf3\xff\x7f\xbf\xf4\xff\x0f\x87\xe9\xff\r\x87\xe9\xff\x1c\x8e\xea\xff\x1d\x8e\xea\xff\x1d\x8e\xea\xff \x8f\xea\xff&\x92\xea\xff,\x96\xea\xff3\x99\xea\xff9\x9d\xea\xff?\x9f\xea\xffF\xa3\xea\xffL\xa5\xea\xffS\xa8\xea\xffZ\xab\xea\xff_\xad\xea\xffg\xb2\xea\xff\x8d\xc7\xf1\xff\x95\xca\xf1\xff\x99\xcc\xf1\xff\x9c\xcd\xf1\xff\x9f\xce\xf1\xff\xa3\xd0\xf1\xff\xa6\xd2\xf1\xff\xa9\xd3\xf1\xff\xad\xd5\xf2\xff\xba\xdd\xf6\xff\x9b\xc7\xe7\xff=\x84\xb9\xff\x05]\x9f\xff\x00[\x9d\xb1\x00\\\x9e\x03\x00\\\x9ey\x00X\x9a\xf3\x05^\x9f\xff6\x8c\xcc\xff`\xb3\xf2\xffe\xb7\xf5\xffc\xb4\xf1\xfff\xb6\xf1\xffi\xb8\xf1\xffl\xb9\xf1\xffp\xba\xf1\xffu\xbc\xf1\xffv\xbc\xf1\xffC\xa2\xed\xff<\x9e\xec\xffC\xa2\xec\xffI\xa4\xec\xffO\xa8\xec\xffU\xaa\xec\xff[\xad\xec\xffa\xb0\xec\xfff\xb2\xec\xffm\xb5\xec\xffr\xb8\xec\xff|\xbb\xec\xff\x87\xc1\xed\xff\x8e\xc4\xed\xff\x92\xc6\xed\xff\x94\xc7\xed\xff\x9d\xcb\xed\xff\xb7\xd9\xf3\xffP\xaa\xf0\xff\x18\x8c\xea\xff\x13\x89\xea\xff\x1b\x8e\xea\xff \x90\xea\xff$\x92\xea\xff$\x91\xea\xff&\x92\xea\xff,\x96\xea\xff3\x99\xea\xff9\x9d\xea\xff?\x9f\xea\xffF\xa3\xea\xffL\xa5\xea\xffS\xa8\xea\xffZ\xab\xea\xff_\xad\xea\xffg\xb2\xea\xff\x8d\xc7\xf1\xff\x95\xca\xf1\xff\x99\xcc\xf1\xff\x9c\xcd\xf1\xff\x9f\xce\xf1\xff\xa3\xd0\xf1\xff\xa6\xd2\xf1\xff\xaf\xd7\xf4\xff\xb1\xd8\xf4\xffn\xa8\xd2\xff\x0ec\xa2\xff\x00U\x99\xfd\x00\\\x9e\x91\x00\\\x9e\r\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e)\x00Z\x9c\xb2\x00V\x99\xff\x18o\xb0\xffR\xa4\xe2\xffj\xb9\xf6\xffg\xb7\xf2\xffi\xb8\xf1\xffl\xb9\xf1\xffp\xba\xf1\xffu\xbc\xf1\xffv\xbc\xf1\xffC\xa2\xed\xff<\x9e\xec\xffC\xa2\xec\xffI\xa4\xec\xffO\xa8\xec\xffU\xaa\xec\xff[\xad\xec\xffa\xb0\xec\xffe\xb2\xec\xffm\xb5\xec\xffz\xbb\xed\xff\x84\xc0\xed\xff\x89\xc2\xed\xff\x8d\xc4\xed\xff\x8f\xc4\xec\xff\x9c\xcc\xee\xff\xc5\xe1\xf5\xff\xca\xe4\xf7\xffi\xb7\xf2\xffS\xac\xf0\xff(\x94\xeb\xff\x16\x8b\xea\xff \x90\xea\xff$\x92\xea\xff*\x95\xea\xff,\x96\xea\xff-\x97\xea\xff2\x99\xea\xff9\x9d\xea\xff?\x9f\xea\xffF\xa3\xea\xffL\xa5\xea\xffS\xa8\xea\xffZ\xab\xea\xff_\xad\xea\xffg\xb2\xea\xff\x8d\xc7\xf1\xff\x95\xca\xf1\xff\x99\xcc\xf1\xff\x9c\xcd\xf1\xff\x9f\xce\xf1\xff\xa5\xd1\xf2\xff\xb1\xd9\xf6\xff\x94\xc4\xe7\xff2}\xb5\xff\x00U\x99\xff\x00Y\x9c\xc6\x00\\\x9e;\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e[\x00X\x9a\xe1\x04]\x9e\xff3\x87\xc5\xffd\xb4\xef\xffo\xbd\xf5\xffl\xb9\xf1\xffp\xba\xf1\xffu\xbc\xf1\xffv\xbc\xf1\xffC\xa2\xed\xff<\x9e\xec\xffC\xa2\xec\xffI\xa4\xec\xffO\xa8\xec\xffU\xaa\xec\xffZ\xad\xec\xff`\xaf\xec\xffj\xb5\xec\xffx\xba\xed\xff\x80\xbe\xed\xff\x83\xc0\xed\xff\x89\xc2\xed\xff\x8a\xc2\xec\xff\x9b\xcb\xef\xff\xc4\xe0\xf6\xff\xd0\xe7\xf7\xff\xc8\xe3\xf7\xffe\xb5\xf2\xff[\xb0\xf1\xff^\xb1\xf1\xff2\x9a\xec\xff\x1b\x8d\xea\xff#\x92\xea\xff)\x95\xea\xff/\x98\xea\xff4\x9a\xea\xff6\x9b\xea\xff9\x9c\xea\xff?\x9f\xea\xffF\xa3\xea\xffL\xa5\xea\xffS\xa8\xea\xffZ\xab\xea\xff_\xad\xea\xffg\xb2\xea\xff\x8d\xc7\xf1\xff\x95\xca\xf1\xff\x99\xcc\xf1\xff\x9c\xcd\xf1\xff\xa6\xd3\xf5\xff\xa4\xd1\xf2\xff^\x9e\xcc\xff\x0b`\xa1\xff\x00V\x99\xef\x00\\\x9er\x00\\\x9e\x04\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x17\x00[\x9d\xa0\x00V\x98\xff\x12i\xaa\xffM\x9e\xd9\xffr\xbe\xf5\xffs\xbc\xf3\xffu\xbc\xf1\xffv\xbc\xf1\xffC\xa2\xed\xff<\x9e\xec\xffC\xa2\xec\xffI\xa4\xec\xffO\xa8\xec\xffT\xa9\xec\xff\\\xad\xec\xffi\xb4\xed\xffs\xba\xed\xffy\xbb\xed\xff\x7f\xbe\xed\xff\x83\xc0\xed\xff\x85\xc0\xec\xff\x9e\xcd\xf0\xff\xc3\xe1\xf7\xff\xcb\xe4\xf7\xff\xcd\xe6\xf7\xff\xc8\xe3\xf7\xffe\xb5\xf2\xffY\xaf\xf1\xffa\xb3\xf1\xfff\xb5\xf1\xffA\xa2\xed\xff \x90\xea\xff(\x94\xea\xff.\x98\xea\xff4\x9a\xea\xff;\x9d\xea\xff?\x9f\xea\xffA\xa0\xea\xffE\xa2\xea\xffL\xa5\xea\xffS\xa8\xea\xffZ\xab\xea\xff_\xad\xea\xffg\xb2\xea\xff\x8d\xc7\xf1\xff\x95\xca\xf1\xff\x9c\xce\xf3\xff\xa5\xd4\xf6\xff~\xb6\xdf\xff%t\xaf\xff\x00U\x99\xff\x00Z\x9c\xb6\x00\\\x9e&\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9eI\x00X\x9b\xd3\x00X\x9b\xff)}\xbb\xffg\xb2\xea\xff|\xc2\xf6\xffv\xbc\xf1\xffC\xa2\xed\xff<\x9e\xec\xffC\xa2\xec\xffH\xa4\xec\xffO\xa7\xec\xff[\xae\xec\xffh\xb3\xed\xffn\xb7\xed\xffs\xba\xed\xffy\xbb\xed\xff~\xbd\xed\xff\x80\xbf\xec\xff\xa1\xcf\xf1\xff\xc3\xe1\xf7\xff\xc6\xe3\xf7\xff\xc9\xe3\xf7\xff\xcd\xe6\xf7\xff\xc8\xe3\xf7\xffe\xb5\xf2\xffY\xaf\xf1\xff_\xb2\xf1\xffe\xb5\xf1\xffm\xb9\xf1\xffQ\xaa\xee\xff)\x94\xea\xff,\x97\xea\xff4\x9a\xea\xff:\x9d\xea\xffA\xa0\xea\xffG\xa3\xea\xffJ\xa5\xea\xffM\xa5\xea\xffS\xa8\xea\xffZ\xab\xea\xff_\xad\xea\xffg\xb2\xea\xff\x8d\xc7\xf1\xff\x9d\xd0\xf6\xff\x93\xc7\xed\xffF\x8d\xc2\xff\x02Z\x9d\xff\x00W\x9a\xe4\x00\\\x9e`\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\n\x00\\\x9e\x81\x00V\x99\xf6\x0cc\xa4\xffM\x9a\xd3\xffz\xbf\xf3\xffD\xa3\xee\xff;\x9e\xec\xffB\xa2\xec\xffM\xa6\xec\xff[\xae\xed\xffd\xb2\xed\xffh\xb4\xed\xffm\xb6\xed\xffs\xba\xed\xffw\xba\xed\xff~\xbd\xed\xff\xa5\xd2\xf3\xff\xc1\xe0\xf7\xff\xc2\xe0\xf7\xff\xc5\xe2\xf7\xff\xc9\xe3\xf7\xff\xcd\xe6\xf7\xff\xc8\xe3\xf7\xffe\xb5\xf2\xffY\xaf\xf1\xff_\xb2\xf1\xffd\xb4\xf1\xffi\xb7\xf1\xffs\xbb\xf1\xffa\xb2\xef\xff3\x9a\xeb\xff0\x98\xea\xff:\x9d\xea\xffA\xa0\xea\xffG\xa3\xea\xffM\xa6\xea\xffR\xa8\xea\xffV\xa9\xea\xffZ\xab\xea\xff_\xad\xea\xffg\xb2\xeb\xff\x94\xcc\xf5\xffn\xad\xda\xff\x18k\xa9\xff\x00T\x98\xff\x00[\x9d\x9b\x00\\\x9e\x18\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e/\x00Y\x9c\xbd\x00W\x99\xff%z\xb7\xffB\xa0\xea\xff;\x9e\xec\xffK\xa6\xed\xffY\xad\xed\xff_\xaf\xed\xffc\xb2\xed\xffh\xb4\xed\xffm\xb6\xed\xffp\xb8\xec\xff}\xbd\xee\xff\xa8\xd4\xf4\xff\xbe\xdf\xf8\xff\xbd\xde\xf7\xff\xc2\xe0\xf7\xff\xc5\xe2\xf7\xff\xc9\xe3\xf7\xff\xcd\xe6\xf7\xff\xc8\xe3\xf7\xffe\xb5\xf2\xffY\xaf\xf1\xff_\xb2\xf1\xffd\xb4\xf1\xffi\xb7\xf1\xffn\xb9\xf1\xffx\xbe\xf1\xffq\xb9\xf0\xff@\xa0\xeb\xff5\x9b\xea\xffA\xa0\xea\xffG\xa3\xea\xffM\xa6\xea\xffS\xa9\xea\xffZ\xab\xea\xff]\xae\xea\xff]\xac\xea\xffk\xb3\xeb\xff:\x87\xbf\xff\x00X\x9a\xff\x00X\x9b\xd1\x00\\\x9eD\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x03\x00[\x9d\xb6\x00[\x9e\xffi\xb2\xe8\xffq\xbc\xf4\xffT\xaa\xed\xffV\xaa\xed\xff^\xaf\xed\xffc\xb2\xed\xffh\xb4\xed\xffj\xb5\xec\xffz\xbd\xee\xff\xa9\xd5\xf5\xff\xb9\xdd\xf8\xff\xba\xdd\xf7\xff\xbd\xde\xf7\xff\xc2\xe0\xf7\xff\xc5\xe2\xf7\xff\xc9\xe3\xf7\xff\xcd\xe6\xf7\xff\xc8\xe3\xf7\xffe\xb5\xf2\xffY\xaf\xf1\xff_\xb2\xf1\xffd\xb4\xf1\xffi\xb7\xf1\xffn\xb9\xf1\xfft\xbc\xf1\xff~\xbf\xf1\xff|\xbe\xf0\xffM\xa6\xeb\xff;\x9d\xea\xffG\xa3\xea\xffM\xa6\xea\xffS\xa9\xea\xffW\xaa\xea\xff]\xae\xea\xff\x84\xc1\xee\xff\x9c\xc9\xea\xff\ta\xa1\xff\x00Y\x9b\xcd\x00\\\x9e\x0e\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00[\x9d\x8c\x04_\xa1\xff~\xbc\xea\xff\x9c\xd2\xfa\xff\x8a\xc7\xf5\xffg\xb4\xef\xffY\xad\xec\xffa\xb1\xed\xffd\xb2\xec\xff|\xbe\xef\xff\xa9\xd4\xf6\xff\xb3\xda\xf7\xff\xb6\xdb\xf7\xff\xba\xdd\xf7\xff\xbd\xde\xf7\xff\xc2\xe0\xf7\xff\xc5\xe2\xf7\xff\xc9\xe3\xf7\xff\xcd\xe6\xf7\xff\xc8\xe3\xf7\xffe\xb5\xf2\xffY\xaf\xf1\xff_\xb2\xf1\xffd\xb4\xf1\xffi\xb7\xf1\xffn\xb9\xf1\xfft\xbc\xf1\xff{\xbe\xf1\xff\x83\xc2\xf1\xff\x88\xc4\xf1\xff^\xae\xed\xffB\xa0\xea\xffK\xa5\xea\xffN\xa6\xea\xffd\xb0\xeb\xff\x97\xca\xef\xff\xb7\xda\xf3\xff\xa9\xd0\xeb\xff\x0ef\xa4\xff\x00Z\x9c\xa7\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00[\x9d\x92\x04_\xa1\xff\x82\xbf\xee\xff\x98\xd0\xfb\xff\x99\xce\xf7\xff\x9a\xce\xf7\xff\x81\xc1\xf2\xffd\xb2\xed\xff~\xbf\xf0\xff\xa8\xd5\xf7\xff\xae\xd8\xf7\xff\xb1\xd9\xf7\xff\xb6\xdb\xf7\xff\xba\xdd\xf7\xff\xbd\xde\xf7\xff\xc2\xe0\xf7\xff\xc5\xe2\xf7\xff\xc9\xe3\xf7\xff\xcd\xe6\xf7\xff\xc8\xe3\xf7\xffe\xb5\xf2\xffY\xaf\xf1\xff_\xb2\xf1\xffd\xb4\xf1\xffi\xb7\xf1\xffn\xb9\xf1\xfft\xbc\xf1\xff{\xbe\xf1\xff\x81\xc1\xf1\xff\x89\xc5\xf1\xff\x91\xc9\xf1\xffo\xb7\xed\xffN\xa6\xea\xffu\xb9\xed\xff\xa3\xd0\xf0\xff\xaf\xd6\xf1\xff\xb5\xda\xf4\xff\xaf\xd5\xef\xff\x0ef\xa4\xff\x00Z\x9c\xaa\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9em\x01[\x9d\xffT\x9c\xd1\xff\x98\xd0\xfb\xff\x9b\xd1\xfa\xff\x99\xce\xf7\xff\x9f\xd2\xf7\xff\x9a\xcf\xf6\xff\xa4\xd4\xf7\xff\xa9\xd6\xf7\xff\xac\xd7\xf7\xff\xb1\xd9\xf7\xff\xb6\xdb\xf7\xff\xba\xdd\xf7\xff\xbd\xde\xf7\xff\xc2\xe0\xf7\xff\xc5\xe2\xf7\xff\xc9\xe3\xf7\xff\xcd\xe6\xf7\xff\xc8\xe3\xf7\xffe\xb5\xf2\xffY\xaf\xf1\xff_\xb2\xf1\xffd\xb4\xf1\xffi\xb7\xf1\xffn\xb9\xf1\xfft\xbc\xf1\xff{\xbe\xf1\xff\x81\xc1\xf1\xff\x88\xc4\xf1\xff\x8e\xc7\xf1\xff\x96\xcb\xf1\xff\x93\xc8\xf0\xff\xa3\xd0\xf1\xff\xa7\xd3\xf1\xff\xb3\xd9\xf5\xff\xae\xd4\xf0\xffZ\x98\xc7\xff\x03\\\x9d\xff\x00[\x9d{\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x16\x00[\x9d\xcd\x00W\x99\xff*z\xb6\xff\x85\xc0\xec\xff\xa3\xd6\xfd\xff\x9d\xd1\xf8\xff\xa0\xd3\xf7\xff\xa4\xd4\xf7\xff\xa8\xd5\xf7\xff\xac\xd7\xf7\xff\xb1\xd9\xf7\xff\xb6\xdb\xf7\xff\xba\xdd\xf7\xff\xbd\xde\xf7\xff\xc2\xe0\xf7\xff\xc5\xe2\xf7\xff\xc9\xe3\xf7\xff\xcd\xe6\xf7\xff\xc8\xe3\xf7\xffe\xb5\xf2\xffY\xaf\xf1\xff_\xb2\xf1\xffd\xb4\xf1\xffi\xb7\xf1\xffn\xb9\xf1\xfft\xbc\xf1\xff{\xbe\xf1\xff\x81\xc1\xf1\xff\x88\xc4\xf1\xff\x8e\xc7\xf1\xff\x94\xca\xf1\xff\x9c\xcd\xf1\xff\xa3\xd1\xf2\xff\xb1\xd9\xf6\xff\x87\xba\xdf\xff!p\xac\xff\x00T\x99\xff\x00[\x9e\xb9\x00\\\x9e\x13\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x0b\x00\\\x9e\x81\x00V\x99\xf5\na\xa2\xff\\\x9f\xd2\xff\xa0\xd3\xf9\xff\xa6\xd7\xfb\xff\xa4\xd4\xf7\xff\xa8\xd5\xf7\xff\xac\xd7\xf7\xff\xb1\xd9\xf7\xff\xb6\xdb\xf7\xff\xba\xdd\xf7\xff\xbd\xde\xf7\xff\xc2\xe0\xf7\xff\xc5\xe2\xf7\xff\xc9\xe3\xf7\xff\xcd\xe6\xf7\xff\xc8\xe3\xf7\xffe\xb5\xf2\xffY\xaf\xf1\xff_\xb2\xf1\xffd\xb4\xf1\xffi\xb7\xf1\xffn\xb9\xf1\xfft\xbc\xf1\xff{\xbe\xf1\xff\x81\xc1\xf1\xff\x88\xc4\xf1\xff\x8e\xc7\xf1\xff\x94\xca\xf1\xff\xa3\xd2\xf5\xff\x9e\xcd\xf0\xffQ\x95\xc6\xff\x03[\x9d\xff\x00W\x9a\xe9\x00\\\x9ei\x00\\\x9e\x01\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e.\x00Z\x9c\xb6\x00U\x99\xff(x\xb3\xff\x81\xbc\xe6\xff\xae\xdb\xfc\xff\xab\xd7\xf9\xff\xac\xd7\xf7\xff\xb1\xd9\xf7\xff\xb6\xdb\xf7\xff\xba\xdd\xf7\xff\xbd\xde\xf7\xff\xc2\xe0\xf7\xff\xc5\xe2\xf7\xff\xc9\xe3\xf7\xff\xcd\xe6\xf7\xff\xc8\xe3\xf7\xffe\xb5\xf2\xffY\xaf\xf1\xff_\xb2\xf1\xffd\xb4\xf1\xffi\xb7\xf1\xffn\xb9\xf1\xfft\xbc\xf1\xff{\xbe\xf1\xff\x81\xc1\xf1\xff\x88\xc4\xf1\xff\x92\xca\xf3\xff\x9c\xd0\xf5\xffr\xae\xda\xff\x1dn\xab\xff\x00U\x99\xff\x00[\x9d\x9f\x00\\\x9e\x1d\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9ed\x00V\x99\xe9\x03[\x9e\xffL\x92\xc6\xff\xa1\xd0\xf3\xff\xb6\xde\xfc\xff\xb2\xda\xf7\xff\xb6\xdb\xf7\xff\xba\xdd\xf7\xff\xbd\xde\xf7\xff\xc2\xe0\xf7\xff\xc5\xe2\xf7\xff\xc9\xe3\xf7\xff\xcd\xe6\xf7\xff\xc8\xe3\xf7\xffe\xb5\xf2\xffY\xaf\xf1\xff_\xb2\xf1\xffd\xb4\xf1\xffi\xb7\xf1\xffn\xb9\xf1\xfft\xbc\xf1\xff{\xbe\xf1\xff\x82\xc2\xf2\xff\x90\xca\xf6\xff\x82\xbe\xe9\xff8\x84\xbc\xff\x00X\x9b\xff\x00W\x9b\xd9\x00\\\x9eO\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x1c\x00[\x9d\x9f\x00T\x98\xff\x18j\xa8\xfft\xaf\xd9\xff\xb8\xde\xfa\xff\xbb\xdf\xfa\xff\xba\xdd\xf7\xff\xbd\xde\xf7\xff\xc2\xe0\xf7\xff\xc5\xe2\xf7\xff\xc9\xe3\xf7\xff\xcd\xe6\xf7\xff\xc8\xe3\xf7\xffe\xb5\xf2\xffY\xaf\xf1\xff_\xb2\xf1\xffd\xb4\xf1\xffi\xb7\xf1\xffn\xb9\xf1\xfft\xbc\xf1\xff\x80\xc2\xf4\xff\x85\xc4\xf3\xffR\x9a\xcf\xff\rc\xa3\xff\x00U\x99\xf9\x00[\x9e\x88\x00\\\x9e\x0f\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9eG\x00X\x9b\xd0\x00V\x9a\xff=\x85\xbb\xff\xa3\xce\xee\xff\xc6\xe5\xfd\xff\xbf\xdf\xf8\xff\xc2\xe0\xf7\xff\xc5\xe2\xf7\xff\xc9\xe3\xf7\xff\xcd\xe6\xf7\xff\xc8\xe3\xf7\xffe\xb5\xf2\xffY\xaf\xf1\xff_\xb2\xf1\xffd\xb4\xf1\xffi\xb7\xf1\xffo\xba\xf2\xff|\xc2\xf6\xffj\xb0\xe4\xff%w\xb4\xff\x00U\x99\xff\x00Z\x9c\xbc\x00\\\x9e3\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x08\x00\\\x9e{\x00T\x99\xf5\rb\xa2\xffk\xa5\xd0\xff\xbe\xdf\xf7\xff\xcb\xe6\xfb\xff\xc5\xe2\xf7\xff\xc9\xe3\xf7\xff\xcd\xe6\xf7\xff\xc8\xe3\xf7\xffe\xb5\xf2\xffY\xaf\xf1\xff_\xb2\xf1\xffd\xb4\xf1\xffn\xbc\xf5\xffm\xb8\xf0\xff=\x8d\xc8\xff\x06^\x9f\xff\x00W\x99\xe9\x00\\\x9ed\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e0\x00Y\x9c\xbc\x00T\x98\xff*v\xb0\xff\x95\xc2\xe2\xff\xd0\xea\xfc\xff\xcd\xe6\xf9\xff\xcd\xe6\xf7\xff\xc8\xe3\xf7\xffe\xb5\xf2\xffY\xaf\xf1\xffa\xb4\xf3\xffj\xb9\xf5\xffN\x9f\xda\xff\x15k\xab\xff\x00V\x98\xff\x00Z\x9d\xa7\x00\\\x9e \x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9ec\x00V\x9a\xe4\x01Y\x9c\xffS\x93\xc2\xff\xbf\xdd\xf2\xff\xd9\xee\xfc\xff\xc9\xe3\xf7\xffe\xb5\xf2\xff^\xb4\xf6\xffZ\xad\xeb\xff(}\xbc\xff\x00Y\x9b\xff\x00X\x9b\xd7\x00\\\x9eO\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x18\x00[\x9d\x9a\x00S\x98\xff\x1cl\xa8\xff\x8d\xb9\xda\xff\xd1\xe9\xfb\xffk\xba\xf5\xff;\x92\xd3\xff\x0cd\xa5\xff\x00V\x99\xf7\x00[\x9d\x85\x00\\\x9e\r\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9eA\x00X\x9b\xd2\x00V\x9a\xff?\x87\xbb\xff&z\xb8\xff\x00W\x99\xff\x00Y\x9c\xc3\x00\\\x9e1\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x0b\x00\\\x9e\x81\x00V\x9a\xf0\x00X\x9a\xf2\x00\\\x9eu\x00\\\x9e\x03\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x0f\x00[\x9et\x00\\\x9ex\x00\\\x9e\x0b\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00\xff\xff\xff\x00', gtk.gdk.COLORSPACE_RGB, True, 8, 64, 64, 256) - window_icon = gtk.gdk.pixbuf_new_from_data('\x00\\\x9e\x00\x00\\\x9e\x00\x00^\xa0\x00\x00V\x99\x00\x00L\x91g\x00N\x93q\x00X\x9c\x00\x00^\x9f\x00\x00]\x9f\x00\x00Y\x9c\x00\x00P\x94o\x00M\x92i\x00V\x99\x00\x00^\xa0\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00^\xa0\x00\x00T\x97\x00\x00F\x8c_1\x81\xba\xff+|\xb6\xff\x00F\x8e?\x00\\\x9e\x00\x00\\\x9e\x00\x00J\x8e;$y\xb6\xff-\x7f\xbc\xff\x00E\x8cb\x00R\x97\x00\x00^\xa0\x00\x00\\\x9e\x00\x00[\x9d\x00\x00I\x8c*\x05X\x9b\xc0P\x9b\xd5\xff\xa7\xdd\xff\xff\xbb\xe5\xff\xff@\x86\xbb\xff\x00>\x89D\x00D\x89B\'{\xbb\xff\x89\xcf\xff\xff\xa2\xdb\xff\xffg\xa6\xd5\xff\x07Y\x9b\xc3\x00C\x8c,\x00[\x9d\x00\x05\\\x9e\x971\x84\xc5\xffk\xbb\xf6\xff\x8e\xd0\xff\xff\x86\xc3\xf0\xff\xa2\xd2\xf5\xff\xc4\xe7\xff\xffP\x90\xc0\xff\x15u\xbf\xfff\xbf\xff\xffx\xc1\xf6\xff\x80\xc0\xf0\xff\xb0\xdf\xff\xff\xa9\xd7\xf6\xff\\\x97\xc5\xff\x0b]\x9e\x98\x08[\x9e\xdcX\xb0\xf0\xff\x84\xd0\xff\xffx\xbc\xf0\xff\x83\xc2\xf0\xff\x88\xc3\xee\xff\xb1\xd7\xf3\xff\xf9\xff\xff\xff\xca\xec\xff\xffm\xba\xf3\xffX\xae\xee\xff{\xbe\xf0\xff\x91\xc7\xf0\xff\xd2\xf2\xff\xff\xa6\xd4\xf0\xff\x11]\x9e\xde\x00T\x96\x00\x00N\x91\x9eD\x98\xd5\xff\x84\xc9\xfc\xff\x85\xc3\xf1\xff\xb7\xdb\xf6\xff\xe9\xf4\xfc\xff\xe9\xf5\xfd\xff\xdb\xee\xfd\xff\xdf\xef\xfc\xff\xa8\xd5\xf6\xff|\xbf\xf1\xff\xa3\xd6\xfc\xffl\xaa\xd6\xff\x00J\x91\xa1\x00Q\x96\x00\x00^\xa0\x00\x00T\x97\x00\x008\x7f\x9eC\x94\xd1\xff\xde\xf6\xff\xff\xf5\xfc\xff\xff\xe0\xef\xfb\xff\xe0\xf0\xfb\xff\xc8\xe5\xfb\xff\xcf\xe7\xfb\xff\xff\xff\xff\xff\xfe\xff\xff\xffV\x9d\xd2\xff\x002\x80\xa2\x00Q\x96\x00\x00_\xa0\x00\x00W\x99\x00\x00I\x8cq9\x89\xc3\xf1Y\xb0\xf2\xffR\xaa\xef\xff\xbc\xde\xf7\xff\xf9\xfc\xfe\xff\xe3\xf2\xfb\xff\xd3\xea\xfc\xff\xf5\xfb\xff\xff\xb7\xdb\xf7\xffd\xb1\xed\xff\x86\xc3\xf2\xffR\x93\xc4\xf3\x00D\x8du\x00T\x99\x00\x06Z\x9d\xb3I\xa0\xe0\xff\x8a\xd2\xff\xffe\xb5\xf2\xff/\x97\xe8\xffK\xa4\xe9\xff\x9c\xcd\xf0\xff\xf6\xf9\xfc\xff\xd6\xec\xfc\xffX\xab\xf0\xff\x15\x8a\xe6\xff9\x9b\xe6\xff\x8c\xc6\xf1\xff\xd1\xf0\xff\xff\x8b\xbe\xe1\xff\x0e\\\x9d\xb6\x07]\x9f\xc1D\x98\xd9\xff\x85\xcd\xff\xffm\xbc\xf9\xff;\x9d\xe9\xff^\xae\xec\xffl\xb3\xe8\xff\xb7\xd9\xf2\xffC\xa2\xef\xff\x00s\xe5\xff3\x99\xea\xffL\xa3\xe7\xff\x96\xce\xf9\xff\xc7\xeb\xff\xff\x81\xb3\xd9\xff\x10_\x9f\xc4\x00X\x9a\x00\x00H\x8bU\x1eq\xad\xeeR\xa8\xe8\xffA\xa4\xf1\xff`\xae\xea\xff\xa9\xd3\xf2\xff\xc8\xe4\xf8\xffh\xb7\xf2\xff@\xa2\xed\xff,\x95\xe8\xffQ\xaa\xef\xff|\xba\xe9\xff*u\xae\xf1\x00A\x8bX\x00V\x9a\x00\x00\\\x9e\x00\x00]\x9f\x00\x00>\x84\x0c"v\xb3\xff\x9b\xdb\xff\xff\x97\xcf\xf8\xff\xce\xe6\xf8\xff\xc5\xe1\xf7\xffe\xb5\xf1\xfft\xbc\xf0\xffu\xbe\xf5\xff\xa9\xde\xff\xff0{\xb0\xff\x00:\x85\x0f\x00]\x9f\x00\x00]\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00Y\x9c\x00\x02S\x97zH\x89\xbf\xff\xb8\xe3\xfd\xff\xe8\xfb\xff\xff\xc2\xdf\xf7\xff`\xb3\xf1\xff\x82\xcb\xff\xff\xa1\xd3\xf7\xffJ\x88\xb8\xff\x00S\x96r\x00Z\x9d\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00]\x9f\x00\x00[\x9d\x00\x00C\x8b*\x08W\x9b\xc5\x8c\xb9\xda\xff\xea\xfd\xff\xff\x80\xcb\xff\xffG\x97\xd4\xff\x03W\x99\xbc\x00E\x8d"\x00[\x9e\x00\x00]\x9f\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00_\xa0\x00\x00Q\x96\x00\x00C\x8di>\x88\xbd\xff,\x7f\xbb\xff\x00G\x8c`\x00T\x98\x00\x00^\xa0\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00_\xa0\x00\x00R\x98\x00\x00I\x92r\x00P\x92n\x00V\x99\x00\x00^\xa0\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00\x00\\\x9e\x00', gtk.gdk.COLORSPACE_RGB, True, 8, 16, 16, 64) - -GUI_AVAILABLE = os.environ.get("DISPLAY", '') - -if GUI_AVAILABLE: - def download(): - import pygtk - pygtk.require("2.0") - import gtk - import gobject - import pango - import webbrowser - - gtk.gdk.threads_init() - - load_serialized_images() - - global FatalVisibleError - def FatalVisibleError(s): - error = gtk.MessageDialog(parent = None, - flags = gtk.DIALOG_MODAL, - type = gtk.MESSAGE_ERROR, - buttons = gtk.BUTTONS_OK, - message_format = s) - error.set_title("Error") - error.run() - gtk.main_quit() - sys.exit(-1) - - class GeneratorTask(object): - def __init__(self, generator, loop_callback, on_done=None, on_exception=None): - self.generator = generator - self.loop_callback = loop_callback - self.on_done = on_done - self.on_exception = on_exception - - def _run(self, *args, **kwargs): - self._stopped = False - try: - for ret in self.generator(*args, **kwargs): - if ret is None: - ret = () - if not isinstance(ret, tuple): - ret = (ret,) - gobject.idle_add(self.loop_callback, *ret) - - if self._stopped: - thread.exit() - except Exception, ex: - print ex - if self.on_exception is not None: - gobject.idle_add(self.on_exception, ex) - else: - if self.on_done is not None: - gobject.idle_add(self.on_done) - - def start(self, *args, **kwargs): - t = threading.Thread(target=self._run, args=args, kwargs=kwargs) - t.setDaemon(True) - t.start() - - def stop(self): - self._stopped = True - - class DownloadDialog(gtk.Dialog): - def handle_delete_event(self, wid, ev, data=None): - self.handle_cancel(wid) - - def handle_dont_show_toggle(self, button, data=None): - reroll_autostart(not button.get_active()) - - def handle_cancel(self, button): - if self.task: - self.task.stop() - if self.download: - self.download.cancel() - gtk.main_quit() - self.user_cancelled = True - - def handle_ok(self, button): - # begin download - self.ok.hide() - self.download = DownloadState() - - self.label.hide() - if self.dont_show_again_align is not None: - self.dont_show_again_align.hide() - self.progress.show() - - def download_progress(progress, status): - if not status: - self.task.stop() - self.update_progress(DOWNLOADING, progress) - - def finished(): - self.update_progress(DOWNLOADING, 1.0) - self.unpack_dropbox() - - def error(ex): - FatalVisibleError(ERROR_CONNECTING) - - self.update_progress(DOWNLOADING, 0) - self.task = GeneratorTask(self.download.copy_data, - download_progress, - finished, error).start() - - def update_progress(self, text, fraction): - self.progress.set_text(text % int(fraction*100)) - self.progress.set_fraction(fraction) - - def unpack_dropbox(self): - def unpack_progress(name, i, total): - self.update_progress(UNPACKING, float(i)/total) - - def finished(): - self.update_progress(UNPACKING, 1.0) - gtk.main_quit() - - def error(ex): - if isinstance(ex, SignatureVerifyError): - FatalVisibleError(ERROR_SIGNATURE) - else: - FatalVisibleError(ERROR_CONNECTING) - - self.task = GeneratorTask(self.download.unpack, - unpack_progress, - finished, error).start() - - def mouse_down(self, widget, event): - if self.hovering: - self.clicked_link = True - - def mouse_up(self, widget, event): - if self.clicked_link: - webbrowser.open(LINK) - self.clicked_link = False - - def label_motion(self, widget, event): - offx, offy = self.label.get_layout_offsets() - layout = self.label.get_layout() - index = layout.xy_to_index(int((offx+event.x)*pango.SCALE), - int((offy+event.y)*pango.SCALE))[0] - link_index = layout.get_text().find(LINK) - if index >= link_index and index < link_index+len(LINK): - self.hovering = True - self.label_box.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2)) - else: - self.hovering = False - self.label_box.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.ARROW)) - - - def __init__(self): - super(DownloadDialog, self).__init__(parent = None, - title = "Dropbox Installation") - - self.download = None - self.hovering = False - self.clicked_link = False - self.user_cancelled = False - - self.ok = ok = gtk.Button(stock=gtk.STOCK_OK) - ok.connect('clicked', self.handle_ok) - self.action_area.add(ok) - ok.show() - - cancel = gtk.Button(stock=gtk.STOCK_CANCEL) - cancel.connect('clicked', self.handle_cancel) - self.action_area.add(cancel) - cancel.show() - - self.connect('delete_event', self.handle_delete_event) - - self.box_logo = gtk.image_new_from_pixbuf(box_logo_pixbuf) - self.box_logo.show() - - self.set_icon(window_icon) - - self.progress = gtk.ProgressBar() - self.progress.set_property('width-request', 300) - - self.label = gtk.Label() - GPG_WARNING_MSG = (u"\n\n" + GPG_WARNING) if not gpgme else u"" - self.label.set_markup('%s <span foreground="#000099" underline="single" weight="bold">%s</span>\n\n%s%s' % (INFO, LINK, WARNING, GPG_WARNING_MSG)) - self.label.set_line_wrap(True) - self.label.set_property('width-request', 300) - self.label.show() - - self.label_box = gtk.EventBox() - self.label_box.add(self.label) - self.label_box.connect("button-release-event", self.mouse_up) - self.label_box.connect("button-press-event", self.mouse_down) - self.label_box.connect("motion-notify-event", self.label_motion) - - self.label_box.show() - def on_realize(widget): - self.label_box.add_events(gtk.gdk.POINTER_MOTION_MASK) - self.label_box.connect("realize", on_realize) - - self.hbox = gtk.HBox(spacing=10) - self.hbox.set_property('border-width',10) - self.hbox.pack_start(self.box_logo, False, False) - self.hbox.pack_start(self.label_box, False, False) - self.hbox.pack_start(self.progress, False, False) - self.hbox.show() - - self.vbox.add(self.hbox) - - self.dont_show_again_align = None - - try: - if can_reroll_autostart(): - dont_show_again = gtk.CheckButton("_Don't show this again") - dont_show_again.connect('toggled', self.handle_dont_show_toggle) - dont_show_again.show() - - self.dont_show_again_align = gtk.Alignment(xalign=1.0, yalign=0.0, xscale=0.0, yscale=0.0) - self.dont_show_again_align.add(dont_show_again) - self.dont_show_again_align.show() - - hbox = gtk.HBox() - hbox.set_property('border-width', 10) - hbox.pack_start(self.dont_show_again_align, True, True) - hbox.show() - - self.vbox.add(hbox) - - self.set_resizable(False) - except: - traceback.print_exc() - - self.ok.grab_focus() - - dialog = DownloadDialog() - dialog.show() - gtk.main() - if dialog.user_cancelled: - raise Exception("user cancelled download!!!") -else: - def download(): - global FatalVisibleError - def FatalVisibleError(s): - console_print(u"\nError: %s" % s, f=sys.stderr) - sys.exit(-1) - - - ESC = "\x1b" - save = ESC+"7" - unsave = ESC+"8" - clear = ESC+"[2J" - erase_to_start = ESC+"[1K" - write = sys.stdout.write - flush = sys.stdout.flush - - last_progress = [None, None] - def setprogress(text, frac): - if last_progress == [text, frac]: - return - if sys.stdout.isatty(): - write(erase_to_start) - write(unsave) - console_print(text % int(100*frac), linebreak=not sys.stdout.isatty()) - if sys.stdout.isatty(): - flush() - last_progress[0], last_progress[1] = text, frac - - console_print() - if sys.stdout.isatty(): - write(save) - flush() - console_print(u"%s %s\n" % (INFO, LINK)) - GPG_WARNING_MSG = (u"\n%s" % GPG_WARNING) if not gpgme else u"" - - if not yes_no_question("%s%s" % (WARNING, GPG_WARNING_MSG)): - return - - download = DownloadState() - - try: - for progress, status in download.copy_data(): - if not status: - break - setprogress(DOWNLOADING, progress) - except Exception: - FatalVisibleError(ERROR_CONNECTING) - else: - setprogress(DOWNLOADING, 1.0) - console_print() - write(save) - - try: - for name, i, total in download.unpack(): - setprogress(UNPACKING, float(i)/total) - except SignatureVerifyError: - FatalVisibleError(ERROR_SIGNATURE) - except Exception: - FatalVisibleError(ERROR_CONNECTING) - else: - setprogress(UNPACKING, 1.0) - - console_print() - -class CommandTicker(threading.Thread): - def __init__(self): - threading.Thread.__init__(self) - self.stop_event = threading.Event() - - def stop(self): - self.stop_event.set() - - def run(self): - ticks = ['[. ]', '[.. ]', '[...]', '[ ..]', '[ .]', '[ ]'] - i = 0 - first = True - while True: - self.stop_event.wait(0.25) - if self.stop_event.isSet(): break - if i == len(ticks): - first = False - i = 0 - if not first: - sys.stderr.write("\r%s\r" % ticks[i]) - sys.stderr.flush() - i += 1 - sys.stderr.flush() - - -class DropboxCommand(object): - class CouldntConnectError(Exception): pass - class BadConnectionError(Exception): pass - class EOFError(Exception): pass - class CommandError(Exception): pass - - def __init__(self, timeout=5): - self.s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - self.s.settimeout(timeout) - try: - self.s.connect(os.path.expanduser(u'~/.dropbox/command_socket')) - except socket.error, e: - raise DropboxCommand.CouldntConnectError() - self.f = self.s.makefile("r+", 4096) - - def close(self): - self.f.close() - self.s.close() - - def __readline(self): - try: - toret = self.f.readline().decode('utf8').rstrip(u"\n") - except socket.error, e: - raise DropboxCommand.BadConnectionError() - if toret == '': - raise DropboxCommand.EOFError() - else: - return toret - - # atttribute doesn't exist, i know what you want - def send_command(self, name, args): - self.f.write(name.encode('utf8')) - self.f.write(u"\n".encode('utf8')) - self.f.writelines((u"\t".join([k] + (list(v) - if hasattr(v, '__iter__') else - [v])) + u"\n").encode('utf8') - for k,v in args.iteritems()) - self.f.write(u"done\n".encode('utf8')) - - self.f.flush() - - # Start a ticker - ticker_thread = CommandTicker() - ticker_thread.start() - - # This is the potentially long-running call. - try: - ok = self.__readline() == u"ok" - except KeyboardInterrupt: - raise DropboxCommand.BadConnectionError("Keyboard interruption detected") - finally: - # Tell the ticker to stop. - ticker_thread.stop() - ticker_thread.join() - - if ok: - toret = {} - for i in range(21): - if i == 20: - raise Exception(u"close this connection!") - - line = self.__readline() - if line == u"done": - break - - argval = line.split(u"\t") - toret[argval[0]] = argval[1:] - - return toret - else: - problems = [] - for i in range(21): - if i == 20: - raise Exception(u"close this connection!") - - line = self.__readline() - if line == u"done": - break - - problems.append(line) - - raise DropboxCommand.CommandError(u"\n".join(problems)) - - # this is the hotness, auto marshalling - def __getattr__(self, name): - try: - return super(DropboxCommand, self).__getattr__(name) - except: - def __spec_command(**kw): - return self.send_command(unicode(name), kw) - self.__setattr__(name, __spec_command) - return __spec_command - -commands = {} -aliases = {} - -def command(meth): - global commands, aliases - assert meth.__doc__, "All commands need properly formatted docstrings (even %r!!)" % meth - if hasattr(meth, 'im_func'): # bound method, if we ever have one - meth = meth.im_func - commands[meth.func_name] = meth - meth_aliases = [unicode(alias) for alias in aliases.iterkeys() if aliases[alias].func_name == meth.func_name] - if meth_aliases: - meth.__doc__ += u"\nAliases: %s" % ",".join(meth_aliases) - return meth - -def alias(name): - def decorator(meth): - global commands, aliases - assert name not in commands, "This alias is the name of a command." - aliases[name] = meth - return meth - return decorator - -def requires_dropbox_running(meth): - def newmeth(*n, **kw): - if is_dropbox_running(): - return meth(*n, **kw) - else: - console_print(u"Dropbox isn't running!") - newmeth.func_name = meth.func_name - newmeth.__doc__ = meth.__doc__ - return newmeth - -def start_dropbox(): - db_path = os.path.expanduser(u"~/.dropbox-dist/dropboxd").encode(sys.getfilesystemencoding()) - if os.access(db_path, os.X_OK): - f = open("/dev/null", "w") - # we don't reap the child because we're gonna die anyway, let init do it - a = subprocess.Popen([db_path], preexec_fn=os.setsid, cwd=os.path.expanduser("~"), - stderr=sys.stderr, stdout=f, close_fds=True) - - # in seconds - interval = 0.5 - wait_for = 60 - for i in xrange(int(wait_for / interval)): - if is_dropbox_running(): - return True - # back off from connect for a while - time.sleep(interval) - - return False - else: - return False - -# Extracted and modified from os.cmd.Cmd -def columnize(list, display_list=None, display_width=None): - if not list: - console_print(u"<empty>") - return - - non_unicode = [i for i in range(len(list)) if not (isinstance(list[i], unicode))] - if non_unicode: - raise TypeError, ("list[i] not a string for i in %s" % - ", ".join(map(unicode, non_unicode))) - - if not display_width: - d = os.popen('stty size', 'r').read().split() - if d: - display_width = int(d[1]) - else: - for item in list: - console_print(item) - return - - if not display_list: - display_list = list - - size = len(list) - if size == 1: - console_print(display_list[0]) - return - - for nrows in range(1, len(list)): - ncols = (size+nrows-1) // nrows - colwidths = [] - totwidth = -2 - for col in range(ncols): - colwidth = 0 - for row in range(nrows): - i = row + nrows*col - if i >= size: - break - x = list[i] - colwidth = max(colwidth, len(x)) - colwidths.append(colwidth) - totwidth += colwidth + 2 - if totwidth > display_width: - break - if totwidth <= display_width: - break - else: - nrows = len(list) - ncols = 1 - colwidths = [0] - lines = [] - for row in range(nrows): - texts = [] - display_texts = [] - for col in range(ncols): - i = row + nrows*col - if i >= size: - x = "" - y = "" - else: - x = list[i] - y = display_list[i] - texts.append(x) - display_texts.append(y) - while texts and not texts[-1]: - del texts[-1] - original_texts = texts[:] - for col in range(len(texts)): - texts[col] = texts[col].ljust(colwidths[col]) - texts[col].replace(original_texts[col], display_texts[col]) - line = u" ".join(texts) - lines.append(line) - for line in lines: - console_print(line) - -@command -@requires_dropbox_running -@alias('stat') -def filestatus(args): - u"""get current sync status of one or more files -dropbox filestatus [-l] [-a] [FILE]... - -Prints the current status of each FILE. - -options: - -l --list prints out information in a format similar to ls. works best when your console supports color :) - -a --all do not ignore entries starting with . -""" - global enc - - oparser = optparse.OptionParser() - oparser.add_option("-l", "--list", action="store_true", dest="list") - oparser.add_option("-a", "--all", action="store_true", dest="all") - (options, args) = oparser.parse_args(args) - - try: - with closing(DropboxCommand()) as dc: - if options.list: - # Listing. - - # Separate directories from files. - if len(args) == 0: - dirs, nondirs = [u"."], [] - else: - dirs, nondirs = [], [] - - for a in args: - try: - (dirs if os.path.isdir(a) else nondirs).append(a.decode(enc)) - except UnicodeDecodeError: - continue - - if len(dirs) == 0 and len(nondirs) == 0: - #TODO: why? - exit(1) - - dirs.sort(key=methodcaller('lower')) - nondirs.sort(key=methodcaller('lower')) - - # Gets a string representation for a path. - def path_to_string(file_path): - if not os.path.exists(file_path): - path = u"%s (File doesn't exist!)" % os.path.basename(file_path) - return (path, path) - try: - status = dc.icon_overlay_file_status(path=file_path).get(u'status', [None])[0] - except DropboxCommand.CommandError, e: - path = u"%s (%s)" % (os.path.basename(file_path), e) - return (path, path) - - env_term = os.environ.get('TERM','') - supports_color = (sys.stderr.isatty() and ( - env_term.startswith('vt') or - env_term.startswith('linux') or - 'xterm' in env_term or - 'color' in env_term - ) - ) - - # TODO: Test when you don't support color. - if not supports_color: - path = os.path.basename(file_path) - return (path, path) - - if status == u"up to date": - init, cleanup = "\x1b[32;1m", "\x1b[0m" - elif status == u"syncing": - init, cleanup = "\x1b[36;1m", "\x1b[0m" - elif status == u"unsyncable": - init, cleanup = "\x1b[41;1m", "\x1b[0m" - elif status == u"selsync": - init, cleanup = "\x1b[37;1m", "\x1b[0m" - else: - init, cleanup = '', '' - - path = os.path.basename(file_path) - return (path, u"%s%s%s" % (init, path, cleanup)) - - # Prints a directory. - def print_directory(name): - clean_paths = [] - formatted_paths = [] - for subname in sorted(os.listdir(name), key=methodcaller('lower')): - if type(subname) != unicode: - continue - - if not options.all and subname[0] == u'.': - continue - - try: - clean, formatted = path_to_string(unicode_abspath(os.path.join(name, subname))) - clean_paths.append(clean) - formatted_paths.append(formatted) - except (UnicodeEncodeError, UnicodeDecodeError), e: - continue - - columnize(clean_paths, formatted_paths) - - try: - if len(dirs) == 1 and len(nondirs) == 0: - print_directory(dirs[0]) - else: - nondir_formatted_paths = [] - nondir_clean_paths = [] - for name in nondirs: - try: - clean, formatted = path_to_string(unicode_abspath(name)) - nondir_clean_paths.append(clean) - nondir_formatted_paths.append(formatted) - except (UnicodeEncodeError, UnicodeDecodeError), e: - continue - - if nondir_clean_paths: - columnize(nondir_clean_paths, nondir_formatted_paths) - - if len(nondirs) == 0: - console_print(dirs[0] + u":") - print_directory(dirs[0]) - dirs = dirs[1:] - - for name in dirs: - console_print() - console_print(name + u":") - print_directory(name) - - except DropboxCommand.EOFError: - console_print(u"Dropbox daemon stopped.") - except DropboxCommand.BadConnectionError, e: - console_print(u"Dropbox isn't responding!") - else: - if len(args) == 0: - args = [name for name in sorted(os.listdir(u"."), key=methodcaller('lower')) if type(name) == unicode] - if len(args) == 0: - # Bail early if there's nothing to list to avoid crashing on indent below - console_print(u"<empty>") - return - indent = max(len(st)+1 for st in args) - for file in args: - - try: - if type(file) is not unicode: - file = file.decode(enc) - fp = unicode_abspath(file) - except (UnicodeEncodeError, UnicodeDecodeError), e: - continue - if not os.path.exists(fp): - console_print(u"%-*s %s" % \ - (indent, file+':', "File doesn't exist")) - continue - - try: - status = dc.icon_overlay_file_status(path=fp).get(u'status', [u'unknown'])[0] - console_print(u"%-*s %s" % (indent, file+':', status)) - except DropboxCommand.CommandError, e: - console_print(u"%-*s %s" % (indent, file+':', e)) - except DropboxCommand.CouldntConnectError, e: - console_print(u"Dropbox isn't running!") - -@command -@requires_dropbox_running -def ls(args): - u"""list directory contents with current sync status -dropbox ls [FILE]... - -This is an alias for filestatus -l -""" - return filestatus(["-l"] + args) - -@command -@requires_dropbox_running -def puburl(args): - u"""get public url of a file in your dropbox -dropbox puburl FILE - -Prints out a public url for FILE. -""" - if len(args) != 1: - console_print(puburl.__doc__,linebreak=False) - return - - try: - with closing(DropboxCommand()) as dc: - try: - console_print(dc.get_public_link(path=unicode_abspath(args[0].decode(sys.getfilesystemencoding()))).get(u'link', [u'No Link'])[0]) - except DropboxCommand.CommandError, e: - console_print(u"Couldn't get public url: " + str(e)) - except DropboxCommand.BadConnectionError, e: - console_print(u"Dropbox isn't responding!") - except DropboxCommand.EOFError: - console_print(u"Dropbox daemon stopped.") - except DropboxCommand.CouldntConnectError, e: - console_print(u"Dropbox isn't running!") - -@command -@requires_dropbox_running -def status(args): - u"""get current status of the dropboxd -dropbox status - -Prints out the current status of the Dropbox daemon. -""" - if len(args) != 0: - console_print(status.__doc__,linebreak=False) - return - - try: - with closing(DropboxCommand()) as dc: - try: - lines = dc.get_dropbox_status()[u'status'] - if len(lines) == 0: - console_print(u'Idle') - else: - for line in lines: - console_print(line) - except KeyError: - console_print(u"Couldn't get status: daemon isn't responding") - except DropboxCommand.CommandError, e: - console_print(u"Couldn't get status: " + str(e)) - except DropboxCommand.BadConnectionError, e: - console_print(u"Dropbox isn't responding!") - except DropboxCommand.EOFError: - console_print(u"Dropbox daemon stopped.") - except DropboxCommand.CouldntConnectError, e: - console_print(u"Dropbox isn't running!") - -@command -def running(argv): - u"""return whether dropbox is running -dropbox running - -Returns 1 if running 0 if not running. -""" - return int(is_dropbox_running()) - -@command -@requires_dropbox_running -def stop(args): - u"""stop dropboxd -dropbox stop - -Stops the dropbox daemon. -""" - try: - with closing(DropboxCommand()) as dc: - try: - dc.tray_action_hard_exit() - except DropboxCommand.BadConnectionError, e: - console_print(u"Dropbox isn't responding!") - except DropboxCommand.EOFError: - console_print(u"Dropbox daemon stopped.") - except DropboxCommand.CouldntConnectError, e: - console_print(u"Dropbox isn't running!") - -#returns true if link is necessary -def grab_link_url_if_necessary(): - try: - with closing(DropboxCommand()) as dc: - try: - link_url = dc.needs_link().get(u"link_url", None) - if link_url is not None: - console_print(u"To link this computer to a dropbox account, visit the following url:\n%s" % link_url[0]) - return True - else: - return False - except DropboxCommand.CommandError, e: - pass - except DropboxCommand.BadConnectionError, e: - console_print(u"Dropbox isn't responding!") - except DropboxCommand.EOFError: - console_print(u"Dropbox daemon stopped.") - except DropboxCommand.CouldntConnectError, e: - console_print(u"Dropbox isn't running!") - -@command -@requires_dropbox_running -def lansync(argv): - u"""enables or disables LAN sync -dropbox lansync [y/n] - -options: - y dropbox will use LAN sync (default) - n dropbox will not use LAN sync -""" - if len(argv) != 1: - console_print(lansync.__doc__, linebreak=False) - return - - s = argv[0].lower() - if s.startswith('y') or s.startswith('-y'): - should_lansync = True - elif s.startswith('n') or s.startswith('-n'): - should_lansync = False - else: - should_lansync = None - - if should_lansync is None: - console_print(lansync.__doc__,linebreak=False) - else: - with closing(DropboxCommand()) as dc: - dc.set_lan_sync(lansync='enabled' if should_lansync else 'disabled') - - -@command -@requires_dropbox_running -def exclude(args): - u"""ignores/excludes a directory from syncing -dropbox exclude [list] -dropbox exclude add [DIRECTORY] [DIRECTORY] ... -dropbox exclude remove [DIRECTORY] [DIRECTORY] ... - -"list" prints a list of directories currently excluded from syncing. -"add" adds one or more directories to the exclusion list, then resynchronizes Dropbox. -"remove" removes one or more directories from the exclusion list, then resynchronizes Dropbox. -With no arguments, executes "list". -Any specified path must be within Dropbox. -""" - if len(args) == 0: - try: - with closing(DropboxCommand()) as dc: - try: - lines = [relpath(path) for path in dc.get_ignore_set()[u'ignore_set']] - lines.sort() - if len(lines) == 0: - console_print(u'No directories are being ignored.') - else: - console_print(u'Excluded: ') - for line in lines: - console_print(unicode(line)) - except KeyError: - console_print(u"Couldn't get ignore set: daemon isn't responding") - except DropboxCommand.CommandError, e: - if e.args[0].startswith(u"No command exists by that name"): - console_print(u"This version of the client does not support this command.") - else: - console_print(u"Couldn't get ignore set: " + str(e)) - except DropboxCommand.BadConnectionError, e: - console_print(u"Dropbox isn't responding!") - except DropboxCommand.EOFError: - console_print(u"Dropbox daemon stopped.") - except DropboxCommand.CouldntConnectError, e: - console_print(u"Dropbox isn't running!") - elif len(args) == 1 and args[0] == u"list": - exclude([]) - elif len(args) >= 2: - sub_command = args[0] - paths = args[1:] - absolute_paths = [unicode_abspath(path.decode(sys.getfilesystemencoding())) for path in paths] - if sub_command == u"add": - try: - with closing(DropboxCommand(timeout=None)) as dc: - try: - result = dc.ignore_set_add(paths=absolute_paths) - if result[u"ignored"]: - console_print(u"Excluded: ") - lines = [relpath(path) for path in result[u"ignored"]] - for line in lines: - console_print(unicode(line)) - except KeyError: - console_print(u"Couldn't add ignore path: daemon isn't responding") - except DropboxCommand.CommandError, e: - if e.args[0].startswith(u"No command exists by that name"): - console_print(u"This version of the client does not support this command.") - else: - console_print(u"Couldn't get ignore set: " + str(e)) - except DropboxCommand.BadConnectionError, e: - console_print(u"Dropbox isn't responding! [%s]" % e) - except DropboxCommand.EOFError: - console_print(u"Dropbox daemon stopped.") - except DropboxCommand.CouldntConnectError, e: - console_print(u"Dropbox isn't running!") - elif sub_command == u"remove": - try: - with closing(DropboxCommand(timeout=None)) as dc: - try: - result = dc.ignore_set_remove(paths=absolute_paths) - if result[u"removed"]: - console_print(u"No longer excluded: ") - lines = [relpath(path) for path in result[u"removed"]] - for line in lines: - console_print(unicode(line)) - except KeyError: - console_print(u"Couldn't remove ignore path: daemon isn't responding") - except DropboxCommand.CommandError, e: - if e.args[0].startswith(u"No command exists by that name"): - console_print(u"This version of the client does not support this command.") - else: - console_print(u"Couldn't get ignore set: " + str(e)) - except DropboxCommand.BadConnectionError, e: - console_print(u"Dropbox isn't responding! [%s]" % e) - except DropboxCommand.EOFError: - console_print(u"Dropbox daemon stopped.") - except DropboxCommand.CouldntConnectError, e: - console_print(u"Dropbox isn't running!") - else: - console_print(exclude.__doc__, linebreak=False) - return - else: - console_print(exclude.__doc__, linebreak=False) - return - -@command -def start(argv): - u"""start dropboxd -dropbox start [-i] - -Starts the dropbox daemon, dropboxd. If dropboxd is already running, this will do nothing. - -options: - -i --install auto install dropboxd if not available on the system -""" - - should_install = "-i" in argv or "--install" in argv - - # first check if dropbox is already running - if is_dropbox_running(): - if not grab_link_url_if_necessary(): - console_print(u"Dropbox is already running!") - return - - console_print(u"Starting Dropbox...", linebreak=False) - console_flush() - if not start_dropbox(): - if not should_install: - console_print() - console_print(u"The Dropbox daemon is not installed!") - console_print(u"Run \"dropbox start -i\" to install the daemon") - return - - # install dropbox!!! - try: - download() - except: - traceback.print_exc() - else: - if GUI_AVAILABLE: - start_dropbox() - console_print(u"Done!") - else: - if start_dropbox(): - if not grab_link_url_if_necessary(): - console_print(u"Done!") - else: - if not grab_link_url_if_necessary(): - console_print(u"Done!") - - -def can_reroll_autostart(): - return u".config" in os.listdir(os.path.expanduser(u'~')) - -def reroll_autostart(should_autostart): - home_dir = os.path.expanduser(u'~') - contents = os.listdir(home_dir) - - # UBUNTU - if u".config" in contents: - autostart_dir = os.path.join(home_dir, u".config", u"autostart") - autostart_link = os.path.join(autostart_dir, u"dropbox.desktop") - if should_autostart: - if os.path.exists(DESKTOP_FILE): - if not os.path.exists(autostart_dir): - os.makedirs(autostart_dir) - shutil.copyfile(DESKTOP_FILE, autostart_link) - elif os.path.exists(autostart_link): - os.remove(autostart_link) - - - -@command -def autostart(argv): - u"""automatically start dropbox at login -dropbox autostart [y/n] - -options: - n dropbox will not start automatically at login - y dropbox will start automatically at login (default) - -Note: May only work on current Ubuntu distributions. -""" - if len(argv) != 1: - console_print(''.join(autostart.__doc__.split('\n', 1)[1:]).decode('ascii')) - return - - s = argv[0].lower() - if s.startswith('y') or s.startswith('-y'): - should_autostart = True - elif s.startswith('n') or s.startswith('-n'): - should_autostart = False - else: - should_autostart = None - - if should_autostart is None: - console_print(autostart.__doc__,linebreak=False) - else: - reroll_autostart(should_autostart) - -@command -def help(argv): - u"""provide help -dropbox help [COMMAND] - -With no arguments, print a list of commands and a short description of each. With a command, print descriptive help on how to use the command. -""" - if not argv: - return usage(argv) - for command in commands: - if command == argv[0]: - console_print(commands[command].__doc__.split('\n', 1)[1].decode('ascii')) - return - for alias in aliases: - if alias == argv[0]: - console_print(aliases[alias].__doc__.split('\n', 1)[1].decode('ascii')) - return - console_print(u"unknown command '%s'" % argv[0], f=sys.stderr) - -def usage(argv): - console_print(u"Dropbox command-line interface\n") - console_print(u"commands:\n") - console_print(u"Note: use dropbox help <command> to view usage for a specific command.\n") - out = [] - for command in commands: - out.append((command, commands[command].__doc__.splitlines()[0])) - spacing = max(len(o[0])+3 for o in out) - for o in out: - console_print(" %-*s%s" % (spacing, o[0], o[1])) - console_print() - -def main(argv): - global commands - - # now we need to find out if one of the commands are in the - # argv list, and if so split the list at the point to - # separate the argv list at that point - cut = None - for i in range(len(argv)): - if argv[i] in commands or argv[i] in aliases: - cut = i - break - - if cut == None: - usage(argv) - os._exit(0) - return - - # lol no options for now - globaloptionparser = optparse.OptionParser() - globaloptionparser.parse_args(argv[0:i]) - - # now dispatch and run - result = None - if argv[i] in commands: - result = commands[argv[i]](argv[i+1:]) - elif argv[i] in aliases: - result = aliases[argv[i]](argv[i+1:]) - - # flush, in case output is rerouted to a file. - console_flush() - - # done - return result - -if __name__ == "__main__": - ret = main(sys.argv) - if ret is not None: - sys.exit(ret) diff --git a/dropbox-remove-icons b/dropbox-remove-icons deleted file mode 100755 index 06ae2bd..0000000 --- a/dropbox-remove-icons +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -file='/Applications/Dropbox.app/Contents/Resources/emblem-dropbox-uptodate.icns' -[ -e "$file" ] && mv -f "$file" "$file.bak" diff --git a/encode b/encode deleted file mode 100755 index 53ed919..0000000 --- a/encode +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/zsh - -source="$1" -dest="$2" -if [[ -e "$dest" ]]; then - # echo "$source -> $dest (skipped, exists)" -else - echo "$source -> $dest" - # echo HandBrakeCLI --preset=\'iPad\' -e x264 --main-feature --markers -i \'$source\' -o \'$dest\' - noglob HandBrakeCLI --preset='iPad' -e x264 --main-feature --markers -i "$source" -o "$dest" >>'/var/log/encode.log' 2>>'/var/log/encode.err' -fi diff --git a/encode-and-add-to-itunes.rb b/encode-and-add-to-itunes.rb deleted file mode 100755 index 7b07f58..0000000 --- a/encode-and-add-to-itunes.rb +++ /dev/null @@ -1,183 +0,0 @@ -#!/usr/bin/env ruby -w - -require 'fileutils' - -ADD_TO_ITUNES_DIR = File.expand_path('~/Music/iTunes/iTunes Media/Automatically Add to iTunes.localized') -MIN_SIZE = 50 * 1024 * 1024 - -def main - root_dir = - if ENV['TR_TORRENT_DIR'] - File.join(ENV['TR_TORRENT_DIR'], ENV['TR_TORRENT_NAME']) - else - ARGV.shift - end - - if File.exists?(root_dir) - puts "* Looking for archives in #{root_dir}..." - extract_archives(root_dir) - - puts "* Encoding files in #{root_dir}..." - encode_and_add_to_itunes(root_dir) - elsif root_dir - puts "file not found: #{root_dir}" - exit 1 - else - puts "error: expected directory in environment variable TR_TORRENT_DIR or as first argument" - exit 2 - end -end - -def extract_archives(dir) - if File.directory?(dir) - Dir.foreach(dir) do |filename| - next if filename == '.' || filename == '..' - _extract_archives(dir, filename) - end - else - _extract_archives(*File.split(dir)) - end -end - -def _extract_archives(dir, filename) - path = File.join(dir, filename) - if File.directory?(path) - extract_archives(path) - elsif filename =~ /\.rar$/ - pwd = Dir.pwd - Dir.chdir(dir) - puts "* Extracting #{filename}..." - `unrar x '#{filename}'` - Dir.chdir(pwd) - end -end - -def encode_and_add_to_itunes(dir) - if File.directory?(dir) - Dir.foreach(dir) do |filename| - next if filename == '.' || filename == '..' - _encode_and_add_to_itunes(dir, filename) - end - else - _encode_and_add_to_itunes(*File.split(dir)) - end -end - -def _encode_and_add_to_itunes(dir, filename) - path = File.join(dir, filename) - if File.directory?(path) - # puts "* Descending into #{path}..." - encode_and_add_to_itunes(path) - else - encoded_path = encode(File.expand_path(dir), filename) - if encoded_path == :noencode - puts "* No encoding required for #{path}, adding to iTunes" - add_to_itunes(path) - elsif encoded_path - puts "* Encoded as #{encoded_path}, adding to iTunes" - add_to_itunes(encoded_path) - File.unlink(encoded_path) - else - # skipped or failed - end - end -end - -def add_to_itunes(path) - FileUtils.cp(path, ADD_TO_ITUNES_DIR) - puts "* Copied #{path} to #{ADD_TO_ITUNES_DIR}" -end - -def encode(dir, filename) - path = File.join(dir, filename) - size = File.stat(path).size - if size < MIN_SIZE - return - end - - ext = File.extname(filename) - encoded_path = - case ext - when '.m4v', '.mp4', '.mp3', '.m4a' - :noencode - when '.mkv' - # fall back to ffmpeg since the MKV conversion can't handle very many audio formats - encode_mkv(dir, filename, ext) || encode_video(dir, filename, ext) - when '.mpg', '.mpeg', '.avi', '.xvid' - encode_video(dir, filename, ext) - else - # puts "* Skipped unknown file type: #{path}" - end - - encoded_path -end - -def encode_mkv(dir, filename, ext) - encoded_filename = encoded_filename(filename, ext) - encoded_path = File.join('/tmp', encoded_filename) - if File.exists?(encoded_path) - # TODO: option to skill all or remove - puts "* Skipping #{filename}, it is already encoded" - encoded_path - else - puts "* Converting MKV to MPEG4: #{filename} -> #{encoded_filename}" - pwd = Dir.pwd - Dir.chdir('/tmp') - path = File.join(dir, filename) - `convert-mkv-to-mp4.sh '#{path}'` - if $?.success? - encoded_path - else - puts "!! Failed to encode #{filename}" - end - end - -ensure - Dir.chdir(pwd) if pwd -end - -def encode_video(dir, filename, ext) - encoded_filename = encoded_filename(filename, ext) - encoded_path = File.join('/tmp', encoded_filename) - if File.exists?(encoded_path) - # TODO: option to skip all or remove - puts "* Skipping #{filename}, it is already encoded" - encoded_path - else - puts "* Converting #{ext.sub('.', '').upcase} to MPEG4 with ffmpeg: #{filename} -> #{encoded_filename}" - pwd = Dir.pwd - Dir.chdir('/tmp') - path = File.join(dir, filename) - `ffmpeg -i '#{path}' -vcodec libx264 -r 24 -acodec libfaac '#{encoded_filename}'` - if $?.success? - encoded_path - else - puts "!! Failed to encode #{filename}" - end - end - -ensure - Dir.chdir(pwd) if pwd -end - -def encoded_filename(filename, ext) - filename.sub(/#{ext}$/, '.mp4') -end - -SIZE_SUFFIXES = %w[bytes KB MB GB TB PB EB] -def human_size(n) - suffix_idx = 0 - while n > 1023 && suffix_idx < SIZE_SUFFIXES.length - 1 - n /= 1024.0 - suffix_idx += 1 - end - suffix = SIZE_SUFFIXES[suffix_idx] - if n - n.to_i < 0.01 - n = n.to_i - else - n = "%0.2f" % n - end - "#{n} #{suffix}" -end - -main if $0 == __FILE__ diff --git a/encode-new-dvds b/encode-new-dvds deleted file mode 100755 index 16cecb8..0000000 --- a/encode-new-dvds +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env ruby - -SourceDir = '/Volumes/Atlas/DVD/Movies' -DestDir = '/Volumes/Atlas/Purchased/Movies' - -def quote(s) - '"' + s.gsub(/(["$`])/, '\\\\\1') + '"' -end - -def files_to_encode - files = Dir[File.join(SourceDir, '*')].inject({}) do |files, source| - basename = File.basename(source) - unless basename == 'scrub.json' || File.exists?(File.join(source, 'noencode')) - outname = basename.sub(/\.dvdmedia$/, '').sub(/Disc/, 'Part') - dest = File.join(DestDir, outname) + '.m4v' - files[source] = dest - end - files - end - - # If only one disc is to be encoded strip the "(Part X of Y)" suffix. - # Otherwise make sure the # of parts matches how many are actually encoded. - sources = files.keys - sources.grep(/^.*\(Disc\s/).each do |source| - prefix = source.match(/^(.*)\(Disc\s/)[1] - parts = sources.select { |source| source[prefix] } - if parts.length == 1 - files[source].sub!(/\s\(Part[^)]+\)/, '') - else - parts.each do |source| - files[source].sub!(/Part (\d) of \d/, "Part \\1 of #{parts.length}") - end - end - end - - files -end - -def main - files_to_encode.each do |source, dest| - if File.exists?(dest) - puts "#{source} -> #{dest} (skipped, exists)" - else - puts "#{source} -> #{dest}" - `encode #{quote(source)} #{quote(dest)}` - end - end -end - -main if $0 == __FILE__ diff --git a/extract-thumbnail-from-video b/extract-thumbnail-from-video deleted file mode 100755 index 306faa0..0000000 --- a/extract-thumbnail-from-video +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env ruby - -video_path = ARGV[0] -thumbnail_path = ARGV[1] -time = ARGV[2] || "00:00:00.000" - -unless video_path && thumbnail_path - $stderr.puts "Usage: #{$0} <video-path> <thumbnail-path> [HH:MM:SS.MMM]" - exit 10 -end - -unless File.exists?(video_path) - $stderr.puts "Input video does not exist: #{video_path}" - exit 20 -end - -if File.exists?(thumbnail_path) - $stderr.puts "Cowardly refusing to overwrite existing file at thumbnail path: #{thumbnail_path}" - exit 30 -end - -`ffmpeg -i '#{video_path}' -ss '#{time}' -vframes 1 '#{thumbnail_path}'` -exit $?.exitstatus diff --git a/find-git-repos.rb b/find-git-repos.rb deleted file mode 100755 index fbedea8..0000000 --- a/find-git-repos.rb +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env ruby - -HomePath = File.expand_path('~') # better way to do this? -ProjectsPath = File.join(HomePath, 'Projects') - -def git_repos_in(path, recurse=true) - dirs = Dir[File.join(path, '*')].select do |path| - File.directory?(path) - end - if recurse - dirs.map do |path| - # add subdirs to the list but ignore subdirs of git repos - [path] + (git_repo?(path) ? [] : git_repos_in(path, true)) - end.flatten - else - dirs - end.select { |path| git_repo?(path) } -end - -def git_dir_in(path) - gitpath = File.join(path, '.git') - File.exists?(gitpath) ? gitpath : nil -end - -alias git_repo? git_dir_in - -git_repos_in(ProjectsPath).each do |path| - puts path -end \ No newline at end of file diff --git a/find-missing-semis.rb b/find-missing-semis.rb deleted file mode 100755 index 4a2eb67..0000000 --- a/find-missing-semis.rb +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env ruby -w - -require 'optparse' - -USAGE_TEXT = "Usage: find-missing-semis.rb [options] <directory>" - -Line = Struct.new(:num, :text) - -def main - options = parse_options - dir = ARGV.first - if File.directory?(dir) - Dir[File.join(dir, '**/*.m')].each do |path| - find_missing_semis(path, options[:fix]) - end - else - puts USAGE_TEXT - exit 1 - end -end - -def parse_options - options = { - fix: false, - } - OptionParser.new do |opts| - opts.banner = USAGE_TEXT - - opts.on("-f", "--[no-]fix", "Insert missing semicolons automatically") do |f| - options[:fix] = f - end - end.parse! - options -end - -def find_missing_semis(path, should_fix = false) - num = 0 - pairs = [] - current_pair = nil - File.readlines(path).each do |text| - num += 1 - line = Line.new(num, text) - if current_pair - current_pair << line - pairs << current_pair - end - current_pair = [line] - end - - missing_semicolon_pairs = pairs.select do |l1, l2| - l1.text =~ /^[-+]/ && l1.text !~ /;$/ && l2.text =~ /^\{/ - end - missing_semicolon_pairs.each do |l1, l2| - puts "Missing semicolon at #{path}:#{l1.num}: #{l1.text}" - if should_fix - l1.text = l1.text.chomp + ";\n" - end - end - if should_fix && missing_semicolon_pairs.length > 0 - lines = pairs.map(&:first) + [pairs.last.last] - text = lines.map(&:text).join - File.open(path, 'w') do |f| - f.print(text) - end - end -end - -main if $0 == __FILE__ diff --git a/fix-android-emulator.sh b/fix-android-emulator.sh deleted file mode 100755 index 51b1a35..0000000 --- a/fix-android-emulator.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -adb kill-server && adb start-server diff --git a/fix-open-with b/fix-open-with deleted file mode 100755 index 2a1bfa3..0000000 --- a/fix-open-with +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -lsregister=/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -$lsregister -kill -r -domain local -domain system -domain user diff --git a/fu-apple.sh b/fu-apple.sh deleted file mode 100755 index 3533a51..0000000 --- a/fu-apple.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -cd /Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Plug-ins/iPhoneOS\ Build\ System\ Support.xcplugin/Contents/MacOS/ -dd if=iPhoneOS\ Build\ System\ Support of=working bs=500 count=255 -printf "\xc3\x26\x00\x00" >> working -dd if=iPhoneOS\ Build\ System\ Support of=working bs=1 skip=127504 seek=127504 -/bin/mv -n iPhoneOS\ Build\ System\ Support iPhoneOS\ Build\ System\ Support.original -/bin/mv working iPhoneOS\ Build\ System\ Support -chmod a+x iPhoneOS\ Build\ System\ Support diff --git a/git-bclean b/git-bclean deleted file mode 100755 index e1929be..0000000 --- a/git-bclean +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -set -e # bail on errors - -BRANCH="${1:-master}" -REMOTE="${2:-origin}" - -git checkout "$BRANCH" -git update "$REMOTE" - -MERGED=$(git branch --merged "$BRANCH" | grep -v " ${BRANCH}\$" | grep -v ' master') -echo "$MERGED" -if [[ $? -eq 0 ]]; then - echo "$MERGED" | xargs git branch -d -else - true -fi diff --git a/git-fixup b/git-fixup deleted file mode 100755 index 90c5c37..0000000 --- a/git-fixup +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -# -# From https://blog.filippo.io/git-fixup-amending-an-older-commit/ - -set -e - -function usage() { - name=$(basename "$0") - echo "Usage: ${name} <commit-ish> [git commit arguments]" >&2 - exit 1 -} - -[[ -z "$1" ]] && usage - -target=$(git rev-parse "$1") -git commit --fixup="$target" "${@:2}" -VISUAL=true EDITOR=true git rebase -i --autostash --autosquash "$target^" diff --git a/git-open-in-github b/git-open-in-github index 9768c88..9b999ea 100755 --- a/git-open-in-github +++ b/git-open-in-github @@ -10,5 +10,4 @@ if [[ -z "$REPO" ]] || [[ -z "$BRANCH" ]]; then echo "usage: $(basename "$0") <remote> <branch (ref)>" exit 1 fi -#open -a "Google Chrome" "https://github.com/${REPO}/compare/${BRANCH}?expand=1" open "https://github.com/${REPO}/compare/${BRANCH}?expand=1" diff --git a/git-pull-request b/git-pull-request deleted file mode 100755 index 6c40dfa..0000000 --- a/git-pull-request +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/env python2.6 - -"""git pull-request - -Automatically check out github pull requests into their own branch -""" -import sys -import getopt -import json -import urllib2 -import os -import re - -def main(): - global repo - - # parse command line options - try: - opts, args = getopt.getopt(sys.argv[1:], "h", ["help"]) - except getopt.error, msg: - print msg - print "for help use --help" - sys.exit(2) - # process options - for o, a in opts: - if o in ("-h", "--help"): - print __doc__ - sys.exit(0) - - # get repo name - origin = os.popen('git remote -v').read() - m = re.search('^origin.*?github\.com.*?[:/]([^/]+/[^/]+)\.git\s*\(fetch\)$',origin,re.MULTILINE) - if(m == None or m.group(1) == ''): - print color_text("Failed to determine repo name from origin",'red',True) - repo = m.group(1) - - # process arguments - if len(args): - ret = fetch(args[0]) - else: - ret = show() - - sys.exit(ret) - -"""Nicely display info about a given pull request -""" -def display(pr): - if(pr['mergeable']): - conflict = '' - else: - conflict = color_text('*HAS CONFLICTS!*','red',True) - - print "%s - %s %s" % (color_text('REQUEST %s' % pr['number'],'green'),pr['title'],conflict) - print " %s" % (color_text(pr['head']['label'],'yellow')) - print " by %s (%s)" % (pr['user']['name'],pr['user']['login']) - print " %s" % (color_text(pr['html_url'],'blue')) - print - - -"""List open pull requests - -Queries the github API for open pull requests in the current repo -""" -def show(): - global repo - - print "loading open pull requests for %s..." % (repo) - print - url = "http://github.com/api/v2/json/pulls/%s/open" % (repo) - req = urllib2.Request(url) - response = urllib2.urlopen(req) - data = response.read() - if (data == ''): - print "failed to speak with github." - return 3 - - data = json.loads(data) - #print json.dumps(data,sort_keys=True, indent=4) - - for pr in data['pulls']: - display(pr) - return 0 - - -def fetch(pullreq): - global repo - - print "loading pull request info for request %s..." % (pullreq) - print - url = "http://github.com/api/v2/json/pulls/%s/%s" % (repo, pullreq) - req = urllib2.Request(url) - response = urllib2.urlopen(req) - data = response.read() - if (data == ''): - print "failed to speak with github." - return 3 - - data = json.loads(data) - #print json.dumps(data,sort_keys=True, indent=4) - pr = data['pull'] - display(pr) - - local = 'pull-request-%s' % (pullreq) - branch = os.popen("git branch|grep '^*'|awk '{print $2}'").read().strip(); - if(branch != pr['base']['ref'] and branch != local): - print color_text("The pull request is based on branch '%s' but you're on '%s' currently" % \ - (pr['base']['ref'], branch),'red',True) - return 4 - - ret = os.system('git branch %s' % (local)); - ret = os.system('git checkout %s' % (local)); - if(ret != 0): - print "Failed to create/switch branch" - return 5 - - print "pulling from %s (%s)" % (pr['head']['repository']['url'], pr['head']['ref']); - - ret = os.system('git pull %s %s' % (pr['head']['repository']['url'], pr['head']['ref'])); - - print - print color_text("done. examine changes and merge into master if good",'green'); - - return 0 - - -"""Return the given text in ANSI colors - -From http://travelingfrontiers.wordpress.com/2010/08/22/how-to-add-colors-to-linux-command-line-output/ -""" -def color_text(text, color_name, bold=False): - colors = ( - 'black', 'red', 'green', 'yellow', - 'blue', 'magenta', 'cyan', 'white' - ) - - if not sys.stdout.isatty(): - return text - - if color_name in colors: - return '\033[{0};{1}m{2}\033[0m'.format( - int(bold), - colors.index(color_name) + 30, - text) - else: - return text - -if __name__ == "__main__": - main() diff --git a/git-push-feature-branch b/git-push-feature-branch deleted file mode 100755 index 0af79e7..0000000 --- a/git-push-feature-branch +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -set -e # bail on errors - -CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) -DEFAULT_REMOTE=$(git config --get branch.${CURRENT_BRANCH}.remote || true) # don't fail -if [[ -z "$DEFAULT_REMOTE" ]]; then - DEFAULT_REMOTE=$(git config --get branch.master.remote) -fi -REMOTE="${1:-$DEFAULT_REMOTE}" -BRANCH="${2:-$CURRENT_BRANCH}" - -git update "$REMOTE" develop -git checkout develop -git merge --no-ff "$BRANCH" -git push -git checkout "$BRANCH" -git push -u "$REMOTE" "$BRANCH" diff --git a/git-remove-merged-branches b/git-remove-merged-branches index a6f98c9..544ed8f 100755 --- a/git-remove-merged-branches +++ b/git-remove-merged-branches @@ -22,4 +22,3 @@ if [[ -n "$MERGED_BRANCHES" ]]; then else echo "No branches to remove" fi - \ No newline at end of file diff --git a/git-restore b/git-restore deleted file mode 100755 index 7908a51..0000000 --- a/git-restore +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -FILENAME="$1" -git checkout $(git rev-list -n1 HEAD -- "$FILENAME")^ "$FILENAME" diff --git a/git-serve b/git-serve deleted file mode 100755 index 02caa83..0000000 --- a/git-serve +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -# Share a read-only git repo real quick -# https://twitter.com/tenderlove/status/579425350590935040 - -PORT=$1 -GIT_DIR=$(git rev-parse --show-toplevel) - -git update-server-info -ruby -run -e httpd -- -p "$PORT" "$GIT_DIR" diff --git a/hide-icons b/hide-icons deleted file mode 100755 index 6c1018b..0000000 --- a/hide-icons +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -defaults write com.apple.finder CreateDesktop false -killall Finder diff --git a/iPhonePNG b/iPhonePNG deleted file mode 100755 index ca511cb..0000000 Binary files a/iPhonePNG and /dev/null differ diff --git a/jpegify b/jpegify deleted file mode 100755 index d86d742..0000000 --- a/jpegify +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/zsh - -set -e # bail on errors - -IMG_PATH="$1" -QUALITY="${2:-95}" -JPEG_IMG_PATH="${IMG_PATH%.*}.jpg" -convert -quality $QUALITY "$IMG_PATH" "$JPEG_IMG_PATH" \ No newline at end of file diff --git a/link-config-files b/link-config-files deleted file mode 100755 index 8095a62..0000000 --- a/link-config-files +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -cd "$HOME" -for FILE in config/*; do - pushd "$HOME" - DOTFILE=".${FILE##*/}" - if [[ -e "$DOTFILE" ]]; then - mkdir original-dot-files >/dev/null 2>/dev/null - echo "Existing file found at $DOTFILE, moving to ~/original-dot-files." - mv "$DOTFILE" original-dot-files/ - fi - ln -s "$FILE" "$DOTFILE" - popd -done diff --git a/linky-notify b/linky-notify deleted file mode 100755 index 5ac457d..0000000 --- a/linky-notify +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/env ruby - -require 'json' -require 'shellwords' -require 'time' - -DEBUG = false - -def log_file - @log_file ||= begin - at_exit { log_file.close } - File.open(File.expand_path('~/linky-notify.log'), 'a') - end -end - -def log(line) - log_file.puts(line) if DEBUG -end - -def munge_invalid_encoding(s) - s.chars.map { |c| c >= "\0" && c <= "\176" ? c : '?' }.join -end - -def force_utf8(s) - if !s.valid_encoding? - log "forcing encoding of #{s[0..30].inspect}" - s = s.force_encoding('UTF-8') - if !s.valid_encoding? - log "munging #{s[0..30].inspect}" - s = munge_invalid_encoding(s) - end - log "s is now #{s[0..30].inspect}" - end - s -end - -def e(s) - Shellwords.escape(force_utf8(s)) -end - -def notify_command(title, url) - notifier = File.expand_path '~/.rbenv/shims/terminal-notifier' - "#{notifier} -title #{e(title)} -message #{e(url)} -open #{e(url)} -actions 'Open' -closeLabel Ignore 2>&1" -end - -def main - dir = ENV['WATCH_DIR'] - created = JSON.parse(force_utf8(ENV['WATCH_CREATED'])) - log "dir = #{dir}" - log "created = #{created.inspect}" - created.each do |filename| - path = File.join(dir, filename) - next if File.directory? path - lines = File.readlines(path).map { |l| force_utf8(l).strip } - title, url = nil, nil - until (title && url) || lines.empty? - line = lines.shift - next if line == '' - - if line =~ /^http/ - url ||= line - else - title ||= line - end - end - title ||= filename.sub(/^[0-9]+-/, '').sub(/\.[^.]+$/, '') - if url - command = notify_command(title, url) - log "[#{Time.now.iso8601}] #{command}" - output = `#{command}` - unless $?.success? - exit 1 - end - archive_dir = File.join(dir, 'Archive') - Dir.mkdir(archive_dir) unless File.exists?(archive_dir) - File.rename(path, File.join(archive_dir, filename)) - else - log "[#{Time.now.iso8601}] Failed to find URL in #{filename}: #{File.read(path)[0..200]}" - end - end -rescue Exception => e - log "#{e.class}: #{e.message}" - log e.backtrace.join("\n") -end - -main if $0 == __FILE__ diff --git a/linky-setup.sh b/linky-setup.sh deleted file mode 100755 index f09f08b..0000000 --- a/linky-setup.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -set -e - -if ! which northwatcher >/dev/null 2>/dev/null; then - npm install -g northwatcher -fi - -if ! which terminal-notifier >/dev/null 2>/dev/null; then - brew install terminal-notifier -fi - -machine_name=$(hostname -s) -mkdir -p $HOME/Dropbox/Apps/Linky/$machine_name/Archive - -cp $HOME/Dropbox/Apps/Linky/net.samhuri.northwatcher.plist $HOME/Library/LaunchAgents - -if [[ ! -e $HOME/.northwatcher ]]; then - echo "+ Dropbox/Apps/Linky/$machine_name ruby /Users/sjs/bin/linky-notify" >$HOME/.northwatcher -fi - -if [[ ! -e /var/log/northwatcher.log ]]; then - echo "Enter your password to create /var/log/northwatcher.log." - sudo touch /var/log/northwatcher.log - sudo chown sjs:staff /var/log/northwatcher.log -fi - -launchctl load $HOME/Library/LaunchAgents/net.samhuri.northwatcher.plist - -echo "* Linky is set up!" diff --git a/ls-comma b/ls-comma deleted file mode 100755 index b83da66..0000000 --- a/ls-comma +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env ruby - -def main - output = `ls #{ARGV.map {|a| "\"#{a}\""}.join(' ')}` - lines = output.split("\n") - i = 0 - most_commas = 0 - number_of_commas = [] - new_lines = lines.map do |line| - if line =~ /^[-dl][-rwxsS]{9}[@+\s]?/ - size = line.split[4] - if size =~ /^\d+$/ - new_size = commaify(size) - new_line = line.sub(size, new_size) - n = new_size.count(',') - number_of_commas << n - most_commas = n if n > most_commas - end - end - unless new_line - number_of_commas << 0 - new_line = line - end - i += 1 - new_line - end - new_lines.each_with_index do |line, i| - if line =~ /^[-dl][-rwxsS]{9}[@+\s]?/ - size = line.split[4] - padded_size = (' ' * (most_commas - number_of_commas[i])) + size - new_lines[i] = line.sub(size, padded_size) - end - end - puts new_lines.join("\n") -end - -def commaify(size) - number_with_delimiter(size) -end - -def number_with_delimiter(n, delimiter = ',') - n.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}") -end - -main if __FILE__ == $0 diff --git a/mac-defaults.sh b/mac-defaults.sh deleted file mode 100755 index fdfe917..0000000 --- a/mac-defaults.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -echo "* Save screenshtots to ~/Dropbox/Pictures/screenshots" -defaults write com.apple.screencapture location ~/Dropbox/Pictures/screenshots - -echo "* Disable shadows on screenshots" -defaults write com.apple.screencapture disable-shadow -bool true - -echo "* Set screenshot name to \"screenshot\"" -defaults write com.apple.screencapture name screenshot - -echo "* Show build duration in Xcode" -defaults write com.apple.dt.Xcode ShowBuildOperationDuration YES - -echo "* Enable text selection in QuickLook" -defaults write com.apple.finder QLEnableTextSelection -bool YES diff --git a/macosver b/macosver deleted file mode 100755 index 6005559..0000000 Binary files a/macosver and /dev/null differ diff --git a/newbox b/newbox deleted file mode 100755 index ffe32df..0000000 --- a/newbox +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env bash - -set -e # bail on errors - -fail() { - echo "error: $@" - exit 1 -} - -function command_exists() { - which "$1" >/dev/null 2>/dev/null -} - -install() { - - if command_exists "$1"; then - return - fi - - # apt (debian / ubuntu) - if command_exists aptitude; then - sudo aptitude install -y "$1" - - # homebrew (os x) - elif command_exists brew; then - brew install "$1" - - # rpm (redhat / centos / fedora) - elif command_exists yum; then - sudo yum install -y "$1" - - # arch - elif command_exists pacman; then - sudo pacman -S "$1" - - else - fail "Don't know how to install $1 on this box. Install $1 and run this again." - fi - -} - -install zsh || fail "Failed to install zsh." -install git || fail "Failed to install git." - -cd ~ -if ! [[ -d config ]]; then - git clone git://github.com/samsonjs/config || fail "cannot clone config repo" -fi - -cd config -./init.sh -cd .. - -echo " * Done!" - -# FIXME figure out how to change the shell semi-interactively (only type in password) -if ! grep `id -u` /etc/passwd | grep zsh; then - #chsh -s `which zsh` - echo " *** Use chsh to change your shell to `which zsh`" -fi - diff --git a/newscript b/newscript deleted file mode 100755 index 34bd5d1..0000000 --- a/newscript +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/sh - -[[ $# -lt 1 ]] && exit 1 - -SCRIPT_DIR=${HOME}/bin - -TYPE=$1 -case "$TYPE" in - -bash) - TYPE=".bash" - SHEBANG="#!/bin/bash" - shift - ;; - -pl) - TYPE=".pl" - SHEBANG="#!/usr/bin/env perl -w\nuse strict;" - shift - ;; - -py) - TYPE=".py" - SHEBANG="#!/usr/bin/env python" - shift - ;; - -rb) - TYPE=".rb" - SHEBANG="#!/usr/bin/env ruby" - shift - ;; - -sh) - TYPE=".sh" - SHEBANG="#!/bin/sh" - shift - ;; - -zsh) - TYPE=".zsh" - SHEBANG="#!/usr/bin/env zsh" - shift - ;; - *) - TYPE="" - ;; -esac - -while [[ -n ${1} ]] ; do - SCRIPT=${SCRIPT_DIR}/${1}${TYPE} - if [[ -n ${TYPE} ]] && [[ ! -e ${SCRIPT} ]]; then - echo "${SHEBANG}" > ${SCRIPT} - chmod +x ${SCRIPT} - elif [[ ! -e ${SCRIPT} ]]; then - touch ${SCRIPT} - chmod +x ${SCRIPT} - elif [[ -w ${SCRIPT} ]] ; then - echo "Script ${SCRIPT} already exists, opening to edit anyways." >&2 - else - echo "Script ${SCRIPT} is not writable, ignoring." >&2 - SCRIPT="" - fi - SCRIPTS="${SCRIPTS} ${SCRIPT}" - shift -done - -${EDITOR} ${SCRIPTS} diff --git a/objcrun b/objcrun deleted file mode 100755 index ded039d..0000000 --- a/objcrun +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env zsh - -if [[ -f "$1" ]]; then - NAME="$(basename ${1%.m})" - BINPATH="/tmp/$NAME" - clang -fobjc-arc -framework Foundation "$1" -o "$BINPATH" && "$BINPATH" -elif [[ ! -z "$1" ]]; then - echo "File not found: $1" - exit 2 -else - echo "Usage: $(basename $0) <filename.m>" - exit 1 -fi diff --git a/occupy-ram b/occupy-ram deleted file mode 100755 index 3c677a8..0000000 --- a/occupy-ram +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env ruby - -def free_pages - `vm_stat`.split(/\n/).grep(/free/).first.scan(/\d+/).first.to_i -end - -mega = 1024 * 1024.0 -a = [] -n = 0 -free = free_pages - -until free < 100_000 - a << '-' * (100 * mega) - n += 100 - free = free_pages - puts "Occupied #{n} MB, #{(4096 * free / mega).round(2)} MB still free" -end -puts 'full, looping forever...' -loop { sleep 1 } diff --git a/osx-defaults b/osx-defaults deleted file mode 100755 index eee4194..0000000 --- a/osx-defaults +++ /dev/null @@ -1,87 +0,0 @@ -#!/bin/sh - -## -# This is script with usefull tips taken from: -# https://github.com/mathiasbynens/dotfiles/blob/master/.osx -# - -echo " * Enable full keyboard access for all controls (e.g. enable Tab in modal dialogs)" -defaults write NSGlobalDomain AppleKeyboardUIMode -int 3 - -echo " * Enable subpixel font rendering on non-Apple LCDs" -defaults write NSGlobalDomain AppleFontSmoothing -int 2 - -echo " * Enable the 2D Dock" -defaults write com.apple.dock no-glass -bool true - -echo " * Automatically hide and show the Dock" -defaults write com.apple.dock autohide -bool true - -# echo " * Make Dock icons of hidden applications translucent" -# defaults write com.apple.dock showhidden -bool true - -echo " * Disable menu bar transparency" -defaults write NSGlobalDomain AppleEnableMenuBarTransparency -bool false - -echo " * Show all filename extensions in Finder" -defaults write NSGlobalDomain AppleShowAllExtensions -bool true - -echo " * Use current directory as default search scope in Finder" -defaults write com.apple.finder FXDefaultSearchScope -string "SCcf" - -echo " * Show Path bar in Finder" -defaults write com.apple.finder ShowPathbar -bool true - -echo " * Show Status bar in Finder" -defaults write com.apple.finder ShowStatusBar -bool true - -echo " * Expand save panel by default" -defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode -bool true - -echo " * Disable the “Are you sure you want to open this application?” dialog" -defaults write com.apple.LaunchServices LSQuarantine -bool false - -echo " * Disable shadow in screenshots" -defaults write com.apple.screencapture disable-shadow -bool true - -echo " * Disable press-and-hold for keys in favor of key repeat" -defaults write NSGlobalDomain ApplePressAndHoldEnabled -bool false - -echo " * Enable AirDrop over Ethernet and on unsupported Macs running Lion" -defaults write com.apple.NetworkBrowser BrowseAllInterfaces -bool true - -echo " * Avoid creating .DS_Store files on network volumes" -defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true - -echo " * Disable the warning when changing a file extension" -defaults write com.apple.finder FXEnableExtensionChangeWarning -bool false - -echo " * Enable snap-to-grid for desktop icons" -/usr/libexec/PlistBuddy -c "Set :DesktopViewSettings:IconViewSettings:arrangeBy grid" ~/Library/Preferences/com.apple.finder.plist - -echo " * Disable the warning before emptying the Trash" -defaults write com.apple.finder WarnOnEmptyTrash -bool false - -echo " * Require password 5 seconds after sleep or screen saver begins" -defaults write com.apple.screensaver askForPassword -int 1 -defaults write com.apple.screensaver askForPasswordDelay -int 5 - -echo " * Enable tap to click (Trackpad)" -defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad Clicking -bool true - -echo " * Enable Safari’s debug menu" -defaults write com.apple.Safari IncludeInternalDebugMenu -bool true - -echo " * Add a context menu item for showing the Web Inspector in web views" -defaults write NSGlobalDomain WebKitDeveloperExtras -bool true - -echo " * Disable the Ping sidebar in iTunes" -defaults write com.apple.iTunes disablePingSidebar -bool true - -echo " * Disable all the other Ping stuff in iTunes" -defaults write com.apple.iTunes disablePing -bool true - -echo -n "Killing affected applications... " -for app in Safari Finder Dock Mail SystemUIServer; do killall "$app" >/dev/null 2>&1; done - -echo "done!" diff --git a/package-code b/package-code deleted file mode 100755 index 6984e81..0000000 --- a/package-code +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -ORIG_DIR=`basename "${PWD}"` -CODE_DIR="${ORIG_DIR}-project" -ZIP_FILE="${CODE_DIR}.zip" - -echo "Zipping project in ${PWD}..." - -pushd .. >/dev/null -cp -a "${ORIG_DIR}" "${CODE_DIR}" -pushd "${CODE_DIR}" >/dev/null -rm -rf .git* **/.git* **/build generated/ -popd >/dev/null -zip -T -r -y "${ZIP_FILE}" "${CODE_DIR}" -rm -rf "${CODE_DIR}" -popd >/dev/null - -echo "done, project is in ${ZIP_FILE}" \ No newline at end of file diff --git a/proj b/proj deleted file mode 100755 index 60cacc5..0000000 --- a/proj +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -bail() { - echo "$@" >&2 - exit 1 -} - -p="$HOME/Projects/$1" -[[ -d "$p" ]] && bail "project exists" -mkdir "$p" -cd "$p" -git init -touch Readme.md -$VISUAL . diff --git a/projekt-seven.sh b/projekt-seven.sh deleted file mode 100755 index 9ccc7fc..0000000 --- a/projekt-seven.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -VOICES=$(say -v '?' | cut -d' ' -f1) -while true; do - VOICE=$(echo "$VOICES" | perl -e 'srand; rand($.) < 1 && ($line = $_) while <>; print $line;') - echo "$VOICE" - say -v "$VOICE" project seven - sleep 0.3 -done diff --git a/publish b/publish deleted file mode 100755 index d8bc6a6..0000000 --- a/publish +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -bail() { - echo fail: $* - exit 1 -} - -# test -if [[ "$1" = "-t" ]]; then - prefix=echo - shift -fi - -[[ "$PUBLISH_HOST" != "" ]] && [[ "$publish_host" = "" ]] && publish_host="$PUBLISH_HOST" -[[ "$PUBLISH_DIR" != "" ]] && [[ "$publish_dir" = "" ]] && publish_dir="$PUBLISH_DIR" - -orig_pwd="$PWD" -if [[ ! -f .publish ]]; then - while ! [[ -f .publish ]]; do - [[ "$PWD" = "/" ]] && bail "no .publish file found" - cd .. - done - subdir="${orig_pwd#$PWD/}" -fi - -source .publish - -cd $orig_pwd -if [[ $# -eq 0 ]]; then - $prefix rsync -aKv * "$publish_host":"${publish_dir}${subdir}" -else - $prefix rsync -aKv "$@" "$publish_host":"${publish_dir}${subdir}" -fi diff --git a/publish-blog.sh b/publish-blog.sh deleted file mode 100755 index ff2d41e..0000000 --- a/publish-blog.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -if [[ -d ~/Projects/web/samhuri.net ]]; then - cd ~/Projects/web/samhuri.net -elif [[ -d ~/samhuri.net ]]; then - cd ~/samhuri.net -else - echo "error: samhuri.net directory not found" - exit 1 -fi - -cd _blog -git clean -fq -git pull -cd .. - -make publish_blog diff --git a/publish-samhuri.net.sh b/publish-samhuri.net.sh deleted file mode 100755 index 0287866..0000000 --- a/publish-samhuri.net.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -if [[ -d ~/Projects/web/samhuri.net ]]; then - cd ~/Projects/web/samhuri.net -elif [[ -d ~/samhuri.net ]]; then - cd ~/samhuri.net -else - echo "error: samhuri.net directory not found" - exit 1 -fi - -cd _blog -git clean -fq -git pull -cd .. - -git clean -fq -git pull - -make publish diff --git a/restart-discussd.sh b/restart-discussd.sh deleted file mode 100755 index 20f86f6..0000000 --- a/restart-discussd.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/zsh - -ps ax | grep 'node discussd' | grep -v grep | awk '{print $1}' | xargs kill -cd ~/discussd -node discussd.js -h 0.0.0.0 -p 8000 >|discussd.log 2>>|discussd.log &! diff --git a/run-command-on-git-revisions b/run-command-on-git-revisions deleted file mode 100755 index b13023c..0000000 --- a/run-command-on-git-revisions +++ /dev/null @@ -1,86 +0,0 @@ -#!/bin/bash -# -# This script runs a given command over a range of Git revisions. Note that it -# will check past revisions out! Exercise caution if there are important -# untracked files in your working tree. -# -# This came from Gary Bernhardt's dotfiles: -# https://github.com/garybernhardt/dotfiles -# -# Example usage: -# $ run-command-on-git-revisions origin/master master 'python runtests.py' - -set -e - -if [[ $1 == -v ]]; then - verbose=1 - shift -fi - -start_ref=$1 -end_ref=$2 -test_command=$3 - -main() { - abort_if_dirty_repo - enforce_usage - run_tests -} - -abort_if_dirty_repo() { - set +e - git diff-index --quiet --cached HEAD - if [[ $? -ne 0 ]]; then - echo "You have staged but not committed changes that would be lost! Aborting." - exit 1 - fi - git diff-files --quiet - if [[ $? -ne 0 ]]; then - echo "You have unstaged changes that would be lost! Aborting." - exit 1 - fi - untracked=$(git ls-files --exclude-standard --others) - if [ -n "$untracked" ]; then - echo "You have untracked files that could be overwritten! Aborting." - exit 1 - fi - set -e -} - -enforce_usage() { - if [ -z "$test_command" ]; then - usage - exit 1 - fi -} - -usage() { - echo "usage: `basename $0` start_ref end_ref test_command" -} - -run_tests() { - revs=`log_command git rev-list --reverse ${start_ref}..${end_ref}` - - for rev in $revs; do - debug "Checking out: $(git log --oneline -1 $rev)" - log_command git checkout --quiet $rev - git log -n1 - log_command $test_command - log_command git reset --hard --quiet - done - log_command git checkout --quiet $end_ref - debug "OK for all revisions!" -} - -log_command() { - debug "=> $*" - eval "$@" -} - -debug() { - if [ $verbose ]; then - echo $* >&2 - fi -} - -main diff --git a/scp-resume.sh b/scp-resume.sh deleted file mode 100755 index 2b83710..0000000 --- a/scp-resume.sh +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/sh -# -# Speed improvements by using blocks by nitro.tm@gmail.com -# -# This script assumes that you have access to the 'dd' utility -# on both the local and remote host. - -# dd transfer blocksize (8192 by default) -blocksize=8192 - -usage() -{ - echo - echo "Usage: `basename $0` -u(pload) \$localfile \$remotefile [\$sshargs]" - echo " `basename $0` -d(ownload) \$remotefile \$localfile [\$sshargs]" - echo - echo " \$remotefile should be in the scp format, i.e.: [user@]host:filename" - echo " \$sshargs are option further ssh options such as a port specification" - echo " (-p 1234) or use of compression (-C)" - echo - echo " -u:" - echo " \$remotefile may be [user@]host: for uploading to your remote home directory" - echo " -d:" - echo " \$localfile may be a period (.) when downloading a remote file to the" - echo " current working directory." - echo - exit 1 -} - -[ -z "$1" -o -z "$2" -o -z "$3" ] && usage - -option=$1 -case $option in - -[uU]*) - localfile=$2 - remote=$3 - shift 3 - sshargs="$*" - - userhost=${remote%:*} - remotefile=${remote#*:} - - if [ ! -f "$localfile" ]; then - echo "!! File not found: $localfile" - usage - fi - if [ x"$userhost" = x"$remote" ]; then usage; fi - if [ x"$remotefile" = x"$remote" -o -z "$remotefile" ]; then remotefile=`basename "$localfile"`; fi - - echo "==>> Getting size of remote file:" - localsize=`ls -l "${localfile}" | awk '{ print $5 }'` - remotesize=`ssh $sshargs "$userhost" "[ -f \"${remotefile}\" ] && ls -l \"${remotefile}\"" | awk '{ print $5 }' ` - - [ -z "$remotesize" ] && remotesize=0 - echo "=> Remote filesize: $remotesize bytes" - - if [ $localsize -eq $remotesize ]; then - echo "=> Local size equals remote size, nothing to transfer." - exit 0; - fi - - remainder=$((remotesize % blocksize)) - restartpoint=$((remotesize - remainder)) - blockstransferred=$((remotesize / blocksize)) - - echo "=> Resuming upload of '$localfile'" - echo " at byte: $restartpoint ($blockstransferred blocks x $blocksize bytes/block)," - echo " will overwrite the trailing $remainder bytes." - - dd bs=$blocksize skip=$blockstransferred "if=${localfile}" | \ - ssh $sshargs "$userhost" "dd bs=$blocksize seek=$blockstransferred of=\"$remotefile\"" - - echo "done." - ;; - -[dD]*) - localfile=$3 - remote=$2 - shift 3 - sshargs="$*" - - userhost=${remote%:*} - remotefile=${remote#*:} - - if [ x"$localfile" = x"." ]; then localfile=`basename "$remotefile"`; fi - if [ ! -f "$localfile" ]; then - localsize=0; - else - localsize=`ls -l "${localfile}" | awk '{ print $5 }'` - fi - [ x"$remotefile" = x"$remote" ] && usage - [ -z "$localsize" ] && localsize=0 - - remainder=$((localsize % blocksize)) - restartpoint=$((localsize - remainder)) - blockstransferred=$((localsize / blocksize)) - - echo "=> Resuming download of '$localfile'" - echo " at byte: $restartpoint ($blockstransferred blocks x $blocksize bytes/block)" - echo " filesize: $localsize; will overwrite the trailing $remainder bytes." - ssh $sshargs "$userhost" "dd bs=$blocksize skip=$blockstransferred \"if=${remotefile}\"" | - dd bs=$blocksize seek=$blockstransferred "of=$localfile" - - ;; - *) - usage - ;; -esac - diff --git a/scrub b/scrub deleted file mode 100755 index ff6c5cf..0000000 --- a/scrub +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env ruby - -require 'json' -require 'optparse' -require 'ostruct' - -class Scrubber - - attr_reader :failures - attr_reader :options - attr_reader :root_dir - attr_reader :status - - def self.scrub(root_dir, options = {}) - new(root_dir, options).scrub - end - - def initialize(root_dir, options = {}) - @failures = [] - @options = options - @root_dir = File.realpath(root_dir) - @status = :ok - end - - def git_repo?(path) - File.exist?(File.join(path, '.git')) - end - - def scrub(dir = @root_dir) - scrub_file = scrub_filename(dir) - if File.exist?(File.join(dir, 'noscrub')) - if File.exists?(scrub_file) - File.unlink(scrub_file) - end - return self - end - - # restore file records if already scrubbed - existing_file_records = file_records(dir) - new_file_records = {} - - # walk the directory - Dir[File.join(dir, '*')].each do |file| - - # skip broken symlinks - next if File.symlink?(file) && !File.exist?(file) - - # descend into subdirectories - if File.directory?(file) - - # ignore git repos as the contents may change and git can fsck itself - scrub(file) unless git_repo?(file) - - # scrub this file - else - basename = File.basename(file) - next if basename == 'scrub.json' - file_record = existing_file_records[basename] || {} - # convert old scrub.json records - if file_record.is_a?(String) - puts ">>> converting #{file} in #{scrub_filename(dir)} to new disk format" if options.verbose - # even out the scrubbing load throughout the month - random_timestamp = Time.now.to_i - (rand(30) * 86400) - file_record = { 'hash' => file_record, 'timestamp' => random_timestamp } - end - last_scrubbed = file_record['timestamp'] || 0 - # skip files scrubbed in the last 30 days, unless --all was given - if !options.all && last_scrubbed >= Time.now.to_i - (30 * 86400) - puts ">>> skipping #{file} as it has been scrubbed recently (#{Time.at(last_scrubbed)})" if options.verbose - new_file_records[basename] = file_record - next - end - relative_filename = file.sub(@root_dir + '/', '') - result, hash = scrub_file(file, file_record['hash']) - case result - when :ok - file_record['hash'] = hash - puts "[ok] #{hash} - #{relative_filename}" if options.verbose - when :new - file_record['hash'] = hash - puts "[new] #{hash} - #{relative_filename}" if options.verbose - when :fail - # no change in scrub.json, just report the new sha - @failures << { - :filename => relative_filename, - :hash => hash, - :expected_hash => file_record['hash'] - } - @status = :fail - puts "[FAIL] #{hash} - #{relative_filename} (previously had sha #{expected_hash})" - end - file_record['timestamp'] = Time.now.to_i - new_file_records[basename] = file_record - end - end - - write_file_records(dir, new_file_records) - self - end - - # Returns - def scrub_file(file, expected_hash) - basename = File.basename(file) - hash = sha1(file) - result = - if hash == expected_hash - result = :ok - elsif expected_hash - result = :fail - else - result = :new - end - [result, hash] - end - - def ok? - @status == :ok - end - - def fail? - @status == :fail - end - - def sha1(filename) - # holy quoting batman! - `shasum "#{filename.gsub(/(\$)/, '\\\\\\1')}"`.split.first - end - - def scrub_filename(dir) - File.join(dir, 'scrub.json') - end - - def file_records(dir) - f = scrub_filename(dir) - if File.exist?(f) - JSON.parse(File.read(f)) - else - {} - end - end - - def write_file_records(dir, records) - return if options.phantom - f = scrub_filename(dir) - if records.size > 0 - File.open(f, 'w') { |f| f.puts(JSON.fast_generate(records)) } - elsif File.exists?(f) - File.unlink(f) - end - end - -end - -def main - options = OpenStruct.new - options.all = false - options.phantom = false - options.verbose = false - - OptionParser.new do |opts| - opts.banner = 'Usage: scrub [options] <root-directory>' - opts.on('-a', '--all', 'Scrub all files no matter when they were last scrubbed.') do - options.all = true - end - opts.on('-h', '--help', 'Show this help') do - puts opts - exit - end - opts.on('-p', '--phantom', 'Do everything except write scrub.json files. Useful for testing.') do - options.phantom = true - end - opts.on('-v', '--verbose', 'Log every file that is checked') do - options.verbose = true - end - end.parse! - - root_dir = ARGV.shift || '.' - unless File.directory?(root_dir) - puts "error: #{root_dir} is not directory" - exit 1 - end - - result = Scrubber.scrub(root_dir, options) - - # TODO print a summary - - # Failures may have been lost in the noise so report them at the - # end as well when -v is given. - if result.fail? && options.verbose - puts - puts "*** Failures:" - # report failures - result.failures.sort do |a,b| - a[:filename] <=> b[:filename] - end.each do |failure| - puts "#{failure[:filename]}: expected #{failure[:expected_hash]}, but got #{failure[:hash]}" - end - exit 1 - end -end - -main if $0 == __FILE__ diff --git a/services-load b/services-load deleted file mode 100755 index fbb013f..0000000 --- a/services-load +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -for svc in $HOME/Library/LaunchAgents/*; do - echo "* Loading $svc" - launchctl load "$svc" -done - -for svc in /Library/LaunchAgents/* /Library/LaunchDaemons/*; do - echo "* Loading $svc" - sudo launchctl load "$svc" -done diff --git a/services-unload b/services-unload deleted file mode 100755 index ebba525..0000000 --- a/services-unload +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -for svc in $HOME/Library/LaunchAgents/*; do - echo "* Unloading $svc" - launchctl unload "$svc" -done - -for svc in /Library/LaunchAgents/* /Library/LaunchDaemons/*; do - echo "* Unloading $svc" - sudo launchctl unload "$svc" -done diff --git a/show-icons b/show-icons deleted file mode 100755 index 02c0480..0000000 --- a/show-icons +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -defaults write com.apple.finder CreateDesktop true -killall Finder diff --git a/sort-redis-keys b/sort-redis-keys deleted file mode 100755 index 4d62b07..0000000 --- a/sort-redis-keys +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/env ruby - -require 'csv' - -def darwin? - @darwin ||= `uname`.strip == 'Darwin' -end - -def mktemp - if darwin? - `mktemp -t $$`.strip - else - `mktemp`.strip - end -end - -def delimit(n, delimiter = ',') - n.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}") -end - -Units = %w[KB MB GB TB] - -def human_size(n) - unit = 'bytes' - units = Units.dup - while n > 1024 && units.length > 0 - n /= 1024.0 - unit = units.shift - end - "#{delimit(n.round(2))} #{unit}" -end - -def analyze_rdb(rdbfile, keyfile) - size = human_size(File.stat(rdbfile).size) - puts "Getting key info for #{rdbfile} (#{size}), this can take a while..." - `rdb -c memory #{rdbfile} > #{keyfile}` - keyfile -end - -def sort_keys(rdbfile) - keyfile = rdbfile.sub('rdb', 'csv') - sortedkeyfile = rdbfile.sub('.rdb', '-sorted.csv') - if !File.exists?(keyfile) - analyze_rdb(rdbfile, keyfile) - end - lines = File.readlines(keyfile) - lines.shift # drop the header - n = lines.length - print "Munging #{delimit(n)} rows..." - rows = [] - while line = lines.shift - row = line.strip.split(',') - size = row[3].to_i - key = row[2].sub(/^"/, '').sub(/"$/, '') - type = row[1] - num_elements = row[5] - len_largest = row[6] - row = [size, key, type, num_elements, len_largest] - rows << row - if rows.length % (n / 50) == 0 - print '.' - end - end - puts - puts "Sorting..." - rows = rows.sort { |a,b| b[0] <=> a[0] } - print "Writing..." - CSV.open(sortedkeyfile, 'wb') do |csv| - # header - csv << %w[size key type num_elements len_largest_element] - while row = rows.shift - csv << row - if rows.length % (n / 50) == 0 - print '.' - end - end - puts - puts "Done." - end -end - -def main - sort_keys(ARGV.shift) -end - -main if $0 == __FILE__ diff --git a/svg-to-ios-pngs.rb b/svg-to-ios-pngs.rb deleted file mode 100755 index 43ec021..0000000 --- a/svg-to-ios-pngs.rb +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env ruby -w - -svg_path = ARGV.shift -png_path = ARGV.shift - -png_test_path = "/tmp/identify.png" -File.unlink(png_test_path) if File.exist?(png_test_path) -puts `inkscape -z -e '#{png_test_path}' -d 72 '#{svg_path}'` -info = `identify '#{png_test_path}'` -File.unlink(png_test_path) if File.exist?(png_test_path) -dimensions = info.split[2] -width, height = dimensions.split('x').map(&:to_i) -if width == 0 || height == 0 - $stderr.puts "Failed to get SVG dimensions" - exit 1 -end - -name = File.basename(svg_path).sub /\.svg$/, '' - -png_2x_path = File.join(png_path, "#{name}@2x.png") -puts `inkscape -z -e '#{png_2x_path}' -w #{2 * width} -h #{2 * height} -d 72 '#{svg_path}'` - -png_3x_path = File.join(png_path, "#{name}@3x.png") -puts `inkscape -z -e '#{png_3x_path}' -w #{3 * width} -h #{3 * height} -d 27 '#{svg_path}'` diff --git a/tarscp b/tarscp deleted file mode 100755 index 6fc5879..0000000 --- a/tarscp +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh -# -# usage: tarscp <host> [remote-dir [local-file ...]] -# -# Uses tar, bzip2, and ssh to transfer files to a remote host. It's -# faster than scp -Cr with many small files. -# -# If no files are specified the current directory is copied to -# remote-dir on host. If remote-dir is not specified the name of the -# current directory is used as the remote directory. -# -# You may want to use gzip instead of bzip2 on slower machines, -# bzip2's runtime can be longer than transfer times with fast -# connections. -# - -usage() { - echo "usage: $(basename $0) <host> [remote-dir [local-file ...]]" - exit 1 -} - -[[ $# < 1 ]] && usage - -HOST="$1"; shift -DIR="$1"; shift - -if [[ "$1" = "" ]]; then - FILES="." - if [[ "$DIR" = "" ]]; then - DIR=$(basename $(dirname $PWD/.)) - fi -else - FILES="$@" -fi - -tar cjf - "$FILES" | ssh "$HOST" "mkdir -p '${DIR}' && tar xjf - -C '${DIR}'" diff --git a/unfuckbootstrap b/unfuckbootstrap deleted file mode 100755 index ba49328..0000000 --- a/unfuckbootstrap +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -launchctl list | grep UIKitApplication | awk '{print $3}' | xargs launchctl remove - diff --git a/upload-to-s3 b/upload-to-s3 deleted file mode 100755 index c6244d5..0000000 --- a/upload-to-s3 +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/zsh - -set -e # bail on errors - -function filesize() { - stat "$1" | cut -d' ' -f8 -} - -ORIG_IMG_PATH="$1" - -# ignore screenshots created by this script or upload-to-s3 -if [[ "$ORIG_IMG_PATH" == *"@1x.png" ]] || [[ "$ORIG_IMG_PATH" == *"@1x.jpg" ]]; then - exit 0 -fi - -BIG_SIZE=$((666 * 1024)) - -WEB_IMG_PATH="$ORIG_IMG_PATH" -ls -lh "$WEB_IMG_PATH" -if [[ $(filesize "$ORIG_IMG_PATH") -gt $BIG_SIZE ]]; then - echo "TOO BIG, DERETINA..." - WEB_IMG_PATH="${ORIG_IMG_PATH%.png}@1x.png" - convert -resize "50%" "$ORIG_IMG_PATH" "$WEB_IMG_PATH" - ls -lh "$WEB_IMG_PATH" - if [[ $(filesize "$WEB_IMG_PATH") -gt $BIG_SIZE ]]; then - echo "STILL TOO BIG, COVERTING TO JPEG" - WEB_IMG_PATH="${ORIG_IMG_PATH%.png}@1x.jpg" - convert -quality 95 -resize "50%" "$ORIG_IMG_PATH" "$WEB_IMG_PATH" - ls -lh "$WEB_IMG_PATH" - fi -fi -FILENAME=$(basename "$WEB_IMG_PATH") -FILENAME="${FILENAME// /_}" -IMG_HOST="static.samhuri.net" -URL="http://${IMG_HOST}/${FILENAME}" -echo -n "$URL" | pbcopy -s3cmd put "$WEB_IMG_PATH" "s3://${IMG_HOST}/${FILENAME}" -echo "$URL" diff --git a/watchit.pl b/watchit.pl deleted file mode 100755 index 367ad85..0000000 --- a/watchit.pl +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/perl -w -use strict; - -sub mail_status { - $date = `date +%Y%m%d-%h:%m`; - open(MAIL, "|/usr/lib/sendmail -t"); - print MAIL "To: $info{to}\n"; - print MAIL "From: $info{from}\n"; - print MAIL "Subject: $info{host} status report for $date\n"; - print MAIL "$info{host} has been up:\n$info{uptime}\n\n"; - print MAIL "memory usage (mb):\n$info{mem}\n\n"; - print MAIL "disk usage:\n$info{disk}\n\n"; - print MAIL "service status:\n$info{services}\n\n"; - close (MAIL); -} - -my ($year, $month, $day) = (`date +%Y`, `date +%m`, `date +%d`); -my $logDir = "/var/log"; -my @logFiles = qw( messages apache2/access_log apache2/error_log ); -my @targetFiles = qw( messages apache_access apache_error ); -my $remoteHost = "home.nofxwiki.net"; -my $remoteDir = "/home/sjs/log/nofxwiki.net/$year/$month"; -my $filePrefix = "$day-"; -my @services = qw( apache2 clamd courier-authlib courier-imapd courier-imapd-ssl iptables mysql spamd sshd ); - -my $file; -my $remoteFile; -for (my $i = 0; $i < @logFiles; $i++) { - $file = $logFiles[$i]; - $remoteFile = $torgetFiles[$i]; - open $file, "tail -f $logDir/$file |" \ - or die "Could not open 'tail -f $file', bailing!\n"; - open "ssh-$file", "| ssh $remoteHost 'cat >> $remoteDir/$remoteFile'" \ - or die "Could not open 'ssh $remoteHost 'cat >> $remoteDir/$remoteFile\n'', bailing!\n"; -} - -my $ticks = 0; -my %info; -while (1) { - foreach my $file (@logFiles) { - while (my $line = <$file>) { - print "ssh-$file" $lines; - } - } - - sleep 300; # 5 minutes - $ticks++; - if ($ticks == 72) { # 360 min = 6 hr - $ticks = 0; - $info{host} = `hostname --fqdn`; - $info{uptime} = `w`; - $info{mem} = `free -m`; - $info{disk} = `df -h`; - - foreach my $svc (@services) { - open SVC, "/etc/init.d/$svc status |"; - @info{services} += <SVC>; - close SVC; - } - &mail_status(%info); - } -} \ No newline at end of file diff --git a/wwdcVideoPDFGet-curlVersion.sh b/wwdcVideoPDFGet-curlVersion.sh deleted file mode 100755 index cd44474..0000000 --- a/wwdcVideoPDFGet-curlVersion.sh +++ /dev/null @@ -1,964 +0,0 @@ -#!/bin/sh - -# Author: Olivier HO-A-CHUCK -# Date: June 27th 2013 (update June 12th 2015) -# Last update: -# - fixed -L for years earlier than 2015 -# - "/Users/${USER}" changed for "${HOME}" for better compliancy with home directory differents than /Users -# - Add wwdc 2015 video download (+ fixed issue with "Managing 3D Assets with Model I/O" session label). -# - fixed issue with names like I/O -# - adding download of ALL sample code (including those to grab on Apple documentation web site) -# - adding check for network connectivity (bash does not handle connectivity error for you) -# - fixing issue with name using comma in title (like ", part 1") - some might download them twice if using an early script - sorry ;( -# -# -# License: Do what you want with it. But notice that this script comes with no warranty and will not be maintained. -# Usage: wwdcVideoGet-curlVersion.sh -# To get 2013 tech-talks content: ./wwdcVideoGet-curlVersion.sh -e tech-talks -# -# TODO: -# - make 2012 videos download possible (it's feasible but more painful than for 2013 and 2014, so time consuming...) -# - wrong password does not give proper error message! -# - display some statistics: total time of download (+ begin and end), total downloaded size of content -# - check available disk space for possible alert (in particular if HD video are getting donwloaded with less than 60 GB of disk space) - -VERSION="1.8.4" -DEFAULT_FORMAT="SD" -DEFAULT_YEAR="2015" -DEFAULT_EVENT="wwdc" -SELECTIVE_SESSION_MODE=false -LIST_MODE=false -VERBOSE=false -LOGIN=false -ITUNES_LOGIN="" -TMP_DIR="/tmp/wwdc-session.tmp" -VIDEO_URL_WWDC="https://developer.apple.com/videos/wwdc" -VIDEO_URL_TECHTALK="https://developer.apple.com/tech-talks/videos/" -SAMPLE_CODE_ROOT_URL="https://developer.apple.com/" - - -doGetWWDCPost2012 () { - - ituneslogin=$1 - itunespassword=$2 - FORMAT=$3 - - if [ ${VERBOSE} == true ]; - then - echo "Sessions to be downloaded: ${SESSION_WANTED}" - echo "Output directory: ${WWDC_DIRNAME}" - fi - - mkdir -p $TMP_DIR - - # Processing Authentifcation - depreciated now (but kept for copy/pasters like me that might need to use this as a snippet for other uses) - if [ -z "${ituneslogin}" ]; - then - # Dynamically get the key value as this can change (it did change for instance when Apple had to turn down their developer Portal for a week) - if [ ${VERBOSE} == true ]; - then - echo "Getting appIDKey..." - fi - key=$(curl -s -L https://developer.apple.com/iphone | grep 'login?&appIdKey=' | sed -e 's/\(.*login?&appIdKey=\)\(.*\)\(&.*\)/\2/' | awk 'NR==1 {print $1}') - if [ ${VERBOSE} == true ]; - then - echo "appIDKey: ${key}" - fi - cookies=(--cookies=on --keep-session-cookies) - - action=$(curl -s 'https://daw.apple.com/cgi-bin/WebObjects/DSAuthWeb.woa/wa/login?appIdKey='"${key}" | grep '\ action=' | awk '{ print $4 }' | cut -f2 -d"=" | sed -e "s/^.*\"\(.*\)\".*$/\1/") - - curl -s --cookie-jar $TMP_DIR/cookies.txt "https://daw.apple.com${action}" -d theAccountName="${ituneslogin}" -d theAccountPW="${itunespassword}" > /dev/null - - curl -s --cookie $TMP_DIR/cookies.txt \ - --cookie-jar $TMP_DIR/cookies.txt \ - ${VIDEO_URL} > $TMP_DIR/video.html - else - curl -silent ${VIDEO_URL} > $TMP_DIR/video.html - fi - - cat ${TMP_DIR}/video.html | sed -e '/class="thumbnail-title/,/<div class="error">/!d' > $TMP_DIR/video-cleaned.html - - if [ -f ${TMP_DIR}/titles.txt ] ; then - rm ${TMP_DIR}/titles.txt - fi - cat ${TMP_DIR}/video-cleaned.html | while read line; do - sessionNum=`echo $line | grep -o -E '<li class="thumbnail-title">(.*)</li><li class="thumbnail-(id|play)">(.*)</li>' | grep -o -E 'Session [0-9]*' | cut -d' ' -f2` - title_array[$sessionNum]=`echo $line | grep -o -E '<li class="thumbnail-title">(.*)</li><li class="thumbnail-(id|play)">(.*)</li>' | cut -d'>' -f2 | sed 's/<\/li$//g'` - echo "$sessionNum,${title_array[$sessionNum]}" >> $TMP_DIR/titles.txt - done - `sed -n '/^,/!p' $TMP_DIR/titles.txt > $TMP_DIR/titles.txt.tmp && mv $TMP_DIR/titles.txt.tmp $TMP_DIR/titles.txt` - - while read line - do - sessionNum=`echo $line | cut -d',' -f1` - sessionTitle=`echo $line | cut -d',' -f2` - title_array[$sessionNum]=${sessionTitle} - done < ${TMP_DIR}/titles.txt - - if [ ${LIST_MODE} == true ]; - then - echo "Available videos:" - echo "-----------------" - cat ${TMP_DIR}/titles.txt | cut -d',' -f1 | while read line; do - echo "${line}: ${title_array[$line]}" - #printf '%s\n' "${title_array[@]}" - done; - exit - fi - - - echo "******* DOWNLOADING PDF FILES ********" - - # PDF - mkdir -p "${WWDC_DIRNAME}"/PDFs - - # do the rm *.download only if files exist - FILES_LIST="$(ls "${WWDC_DIRNAME}"/PDFs/*.download 2>/dev/null)" - if [ -z "$FILES_LIST" ]; then - # echo "Hello, de Lu!" - : - else - echo "Some download was aborted last time you ran this script." - rm "${WWDC_DIRNAME}"/PDFs/*.download - echo "Cleaning non fully downloaded files: OK." - fi - i=0 - cat ${TMP_DIR}/video.html | grep -o -E 'href="(http:\/\/devstreaming.apple.com\/videos\/wwdc\/'${YEAR}'\/[0-9a-zA-Z]*\/[0-9]{1,5}\/([0-9]{1,5}|[0-9]{1,5}_.*)\.pdf\?dl=1+)"' | cut -d'"' -f2 | sed -e 's/_sd_/_/g' -e 's/.mov/.pdf/g' | while read line; do - - filename=`echo ${line} | cut -d'/' -f9 | cut -d'?' -f1` - - session_number=`echo $line | grep -o -E '\/([0-9]+|[0-9]+_.*)\.pdf' | grep -o -E "[0-9]{3,4}"` - if [ ${SELECTIVE_SESSION_MODE} == true ]; - then - if `echo ${SESSION_WANTED} | grep "${session_number}" 1>/dev/null 2>&1` - then - dest_path="${WWDC_DIRNAME}/PDFs/${session_number} - ${title_array[$session_number]}.pdf" - old_dest_path="${WWDC_DIRNAME}/PDFs/${filename}" - if [ -f "${dest_path}" ]; - then - echo "${dest_path} already downloaded (nothing to do!)" - elif [ -f "${old_dest_path}" ]; - then - echo "Rename existing file: ${old_dest_path} => ${dest_path}" - mv "${old_dest_path}" "${dest_path}" - else - echo "downloading PDF for session ${session_number}: $line" - - curl $line > "${dest_path}.download" - - mv "${dest_path}.download" "${dest_path}" - fi - fi - else - dest_path="${WWDC_DIRNAME}/PDFs/${session_number} - ${title_array[$session_number]}.pdf" - old_dest_path="${WWDC_DIRNAME}/PDFs/${filename}" - - if [ -f "${dest_path}" ]; - then - echo "${dest_path} already downloaded (nothing to do!)" - elif [ -f "${old_dest_path}" ]; - then - echo "Rename existing file: ${old_dest_path} => ${dest_path}" - mv "${old_dest_path}" "${dest_path}" - else - echo "downloading PDF for session ${session_number}: $line" - - curl $line > "${dest_path}.download" - - mv "${dest_path}.download" "${dest_path}" - fi - fi - ((i+=1)) - done - - echo "******* DOWNLOADING ${FORMAT} VIDEOS ********" - - # Videos ${FORMAT} - mkdir -p "${WWDC_DIRNAME}"/${FORMAT}-VIDEOs - # do the rm *.download only if files exist - FILES_LIST="$(ls "${WWDC_DIRNAME}"/${FORMAT}-VIDEOs/*.download 2>/dev/null)" - if [ -z "$FILES_LIST" ]; then - #echo "All downloads will go to your Desktop/WWDC-2013 folder!" - : - else - echo "Some download was aborted last time you ran this script." - rm "${WWDC_DIRNAME}"/${FORMAT}-VIDEOs/*.download - echo "Cleaning non fully downloaded files: OK" - fi - - - i=0 - # TODO: / WARNING (for possible future function merge): note that devstreaming url does use hard coded "wwdc" in it, were tech-talks function url is "techtalks" (whithout dash) - - if [ ${YEAR} = "2013" ]; - then - REGEXFILE="[0-9a-zA-Z]*\/[0-9]{1,5}\/[0-9]{1,5}-${FORMAT}\.mov" - elif [ ${YEAR} = "2014" ]; - then - if [ "${FORMAT}" = "HD" ]; - then - LC_FORMAT="hd" - else - LC_FORMAT="sd" - fi - REGEXFILE="[0-9a-zA-Z]*\/[0-9]{1,5}\/[0-9]{1,5}_${LC_FORMAT}_.*\.mov" - else - echo "coucou" - fi - - cat ${TMP_DIR}/video.html | grep -o -E 'href="(http:\/\/devstreaming.apple.com\/videos\/wwdc\/'${YEAR}'/'${REGEXFILE}'\?dl=1+)"' | cut -d'"' -f2 | while read line; do - - #echo $line - filename=`echo ${line} | cut -d'/' -f9 | cut -d'?' -f1` - - session_number=`echo $line | grep -o -i -E '/[0-9]+[_-]'${FORMAT}'[^/]*.mov' | grep -o -E '[0-9]+' | head -1` - if [ ${SELECTIVE_SESSION_MODE} == true ]; - then - if `echo ${SESSION_WANTED} | grep "${session_number}" 1>/dev/null 2>&1` - then - dest_path="${WWDC_DIRNAME}/${FORMAT}-VIDEOs/${session_number} - ${title_array[$session_number]}-${FORMAT}.mov" - old_dest_path="${WWDC_DIRNAME}/${FORMAT}-VIDEOs/${filename}" - if [ -f "${dest_path}" ] - then - echo "${dest_path} already downloaded (nothing to do!)" - elif [ -f "${old_dest_path}" ]; - then - echo "Rename existing file: ${old_dest_path} => ${dest_path}" - mv "${old_dest_path}" "${dest_path}" - else - echo "downloading ${FORMAT} Video for session ${session_number}: $line" - - curl $line > "${dest_path}.download" - - mv "${dest_path}.download" "${dest_path}" - fi - fi - else - dest_path="${WWDC_DIRNAME}/${FORMAT}-VIDEOs/${session_number} - ${title_array[$session_number]}-${FORMAT}.mov" - old_dest_path="${WWDC_DIRNAME}/${FORMAT}-VIDEOs/${filename}" - - if [ -f "${dest_path}" ] - then - echo "${dest_path} already downloaded (nothing to do!)" - elif [ -f "${old_dest_path}" ]; - then - echo "Rename existing file: ${old_dest_path} => ${dest_path}" - mv "${old_dest_path}" "${dest_path}" - else - echo "downloading ${FORMAT} Video for session ${session_number}: $line" - - curl $line > "${dest_path}.download" - - mv "${dest_path}.download" "${dest_path}" - fi - fi - ((i+=1)) - done - - rm -Rf ${TMP_DIR} -} - -#**************************************************************************************# -# TECH TALK # -#**************************************************************************************# -doGetTT2013 () { - - ituneslogin=$1 - itunespassword=$2 - FORMAT=$3 - - if [ ${VERBOSE} == true ]; - then - echo "Sessions to be downloaded: ${SESSION_WANTED}" - echo "Output directory: ${WWDC_DIRNAME}" - fi - - mkdir -p $TMP_DIR - # Dynamically get the key value as this can change (it did change for instance when Apple had to turn down their developer Portal for a week) - if [ ${VERBOSE} == true ]; - then - echo "Getting appIDKey..." - fi - key=$(curl -s -L https://developer.apple.com/iphone | grep 'login?&appIdKey=' | sed -e 's/\(.*login?&appIdKey=\)\(.*\)\(&.*\)/\2/' | awk 'NR==1 {print $1}') - if [ ${VERBOSE} == true ]; - then - echo "appIDKey: ${key}" - fi - cookies=(--cookies=on --keep-session-cookies) - - action=$(curl -s 'https://daw.apple.com/cgi-bin/WebObjects/DSAuthWeb.woa/wa/login?appIdKey='"${key}" | grep '\ action=' | awk '{ print $4 }' | cut -f2 -d"=" | sed -e "s/^.*\"\(.*\)\".*$/\1/") - - curl -s --cookie-jar $TMP_DIR/cookies.txt "https://daw.apple.com${action}" -d theAccountName="${ituneslogin}" -d theAccountPW="${itunespassword}" > /dev/null - - curl -s --cookie $TMP_DIR/cookies.txt \ - --cookie-jar $TMP_DIR/cookies.txt \ - ${VIDEO_URL} > $TMP_DIR/video.html - - cat ${TMP_DIR}/video.html | sed -e '/class="thumbnail-title/,/<div class="error">/!d' > $TMP_DIR/video-cleaned.html - - if [ -f ${TMP_DIR}/titles.txt ] ; then - rm ${TMP_DIR}/titles.txt - fi - cat ${TMP_DIR}/video-cleaned.html | while read line; do - echo $line | grep -o -E '<li class="thumbnail-title">(.*)</li><li class="thumbnail-(id|play)">(.*)</li>' | cut -d'>' -f2 | sed 's/\<\/li$//g' >> $TMP_DIR/titles.txt - done - - while read line - do - title_array+=("$line") - done < ${TMP_DIR}/titles.txt - - - if [ ${LIST_MODE} == true ]; - then - echo "Available videos:" - echo "-----------------" - cat ${TMP_DIR}/titles.txt | cut -d';' -f1 | while read line; do - echo "$line: ${title_array[$line]}" - #printf '%s\n' "${title_array[@]}" - done; - exit - fi - - - echo "******* DOWNLOADING PDF FILES ********" - - # PDF - mkdir -p "${WWDC_DIRNAME}"/PDFs - - # do the rm *.download only if files exist - FILES_LIST="$(ls "${WWDC_DIRNAME}"/PDFs/*.download 2>/dev/null)" - if [ -z "$FILES_LIST" ]; then - #echo "All downloads will go to your Desktop/WWDC-2013 folder!" - : - else - echo "Some download was aborted last time you ran this script." - rm "${WWDC_DIRNAME}"/PDFs/*.download - echo "Cleaning non fully downloaded files: OK." - fi - - i=0 - cat ${TMP_DIR}/video.html | grep -o -E 'href="(http:\/\/devstreaming.apple.com\/videos\/techtalks\/2013/[0-9a-zA-Z_\-]*\/[0-9a-zA-Z_\-]*\.pdf\?dl=1+)"' | cut -d'"' -f2 | while read line; do - session_number=`echo $line | grep -o -E '/[0-9]+_' | grep -o -E [0-9]+` - if [ ${SELECTIVE_SESSION_MODE} == true ]; - then - if `echo ${SESSION_WANTED} | grep "${session_number}" 1>/dev/null 2>&1` - then - dest_path="${WWDC_DIRNAME}/PDFs/${session_number} - ${title_array[$i]}.pdf" - if [ -f "${dest_path}" ] - then - echo "${dest_path} already downloaded (nothing to do!)" - else - echo "downloading PDF for session ${session_number}: $line" - - curl $line > "${dest_path}.download" - - mv "${dest_path}.download" "${dest_path}" - fi - fi - else - dest_path="${WWDC_DIRNAME}/PDFs/${session_number} - ${title_array[$i]}.pdf" - if [ -f "${dest_path}" ] - then - echo "${dest_path} already downloaded (nothing to do!)" - else - echo "downloading PDF for session ${session_number}: $line" - - curl $line > "${dest_path}.download" - - mv "${dest_path}.download" "${dest_path}" - fi - fi - ((i+=1)) - done - - echo "******* DOWNLOADING ${FORMAT} VIDEOS ********" - - # Videos ${FORMAT} - mkdir -p "${WWDC_DIRNAME}"/${FORMAT}-VIDEOs - - # do the rm *.download only if files exist - FILES_LIST="$(ls "${WWDC_DIRNAME}"/${FORMAT}-VIDEOs/*.download 2>/dev/null)" - if [ -z "$FILES_LIST" ]; then - #echo "All downloads will go to your Desktop/WWDC-2013 folder!" - : - else - echo "Some download was aborted last time you ran this script." - rm "${WWDC_DIRNAME}"/${FORMAT}-VIDEOs/*.download - echo "Cleaning non fully downloaded files: OK." - fi - - i=0 - # TODO: This extra if then elif test should not be there (duplicated code), but I don't know so far how to use $FORMAT in the grep -o -E regex! :( - # Word boundaries should help like \<$FORMAT\>, but I'm not sure this is compliant with all grep versions. And I don't want to use egrep (non standard). - # I know even with if then, this can be improved in terms or number of code lines. But hey, I'm a Marketing guys. Sorry for the very quick and dirty bit :((( - if [ ${FORMAT} = "HD" ]; - then - cat ${TMP_DIR}/video.html | grep -o -E 'href="(http:\/\/devstreaming.apple.com\/videos\/techtalks\/2013/[0-9a-zA-Z_]*\/[0-9a-zA-Z_]*-hd\.mov\?dl=1+)"' | cut -d'"' -f2 | while read line; do - session_number=`echo $line | grep -o -E '/[0-9]+_' | grep -o -E [0-9]+` - if [ ${SELECTIVE_SESSION_MODE} == true ]; - then - if `echo ${SESSION_WANTED} | grep "${session_number}" 1>/dev/null 2>&1` - then - dest_path="${WWDC_DIRNAME}/${FORMAT}-VIDEOs/${session_number} - ${title_array[$i]}-${FORMAT}.mov" - if [ -f "${dest_path}" ] - then - echo "${dest_path} already downloaded (nothing to do!)" - else - echo "downloading ${FORMAT} Video for session ${session_number}: $line" - - # little trick to be consistant with upercase HD of wwdc file name types - lineWithUperCaseHD="${line/-HD/-hd}" - curl $lineWithUperCaseHD > "${dest_path}.download" - - mv "${dest_path}.download" "${dest_path}" - fi - fi - else - dest_path="${WWDC_DIRNAME}/${FORMAT}-VIDEOs/${session_number} - ${title_array[$i]}-${FORMAT}.mov" - if [ -f "${dest_path}" ] - then - echo "${dest_path} already downloaded (nothing to do!)" - else - echo "downloading ${FORMAT} Video for session ${session_number}: $line" - - # little trick to be consistant with upercase HD of wwdc file name types - lineWithUperCaseHD="${line/-HD/-hd}" - curl $lineWithUperCaseHD > "${dest_path}.download" - - mv "${dest_path}.download" "${dest_path}" - fi - fi - ((i+=1)) - done - elif [ ${FORMAT} = "SD" ]; - then - cat ${TMP_DIR}/video.html | grep -o -E 'href="(http:\/\/devstreaming.apple.com\/videos\/techtalks\/2013/[0-9a-zA-Z_]*\/[0-9a-zA-Z_]*-sd\.mov\?dl=1+)"' | cut -d'"' -f2 | while read line; do - session_number=`echo $line | grep -o -E '/[0-9]+_' | grep -o -E [0-9]+` - if [ ${SELECTIVE_SESSION_MODE} == true ]; - then - if `echo ${SESSION_WANTED} | grep "${session_number}" 1>/dev/null 2>&1` - then - dest_path="${WWDC_DIRNAME}/${FORMAT}-VIDEOs/${session_number} - ${title_array[$i]}-${FORMAT}.mov" - if [ -f "${dest_path}" ] - then - echo "${dest_path} already downloaded (nothing to do!)" - else - echo "downloading ${FORMAT} Video for session ${session_number}: $line" - - # little trick to be consistant with upercase SD of wwdc file name types - lineWithUperCaseSD="${line/-SD/-sd}" - curl $lineWithUperCaseSD > "${dest_path}.download" - - mv "${dest_path}.download" "${dest_path}" - fi - fi - else - dest_path="${WWDC_DIRNAME}/${FORMAT}-VIDEOs/${session_number} - ${title_array[$i]}-${FORMAT}.mov" - if [ -f "${dest_path}" ] - then - echo "${dest_path} already downloaded (nothing to do!)" - else - echo "downloading ${FORMAT} Video for session ${session_number}: $line" - - # little trick to be consistant with upercase SD of wwdc file name types - lineWithUperCaseSD="${line/-SD/-sd}" - curl $lineWithUperCaseSD > "${dest_path}.download" - - mv "${dest_path}.download" "${dest_path}" - fi - fi - ((i+=1)) - done - fi - - rm -Rf ${TMP_DIR} -} - - - -doGet2012 () { - ituneslogin=$1 - itunespassword=$2 - FORMAT=$3 - #echo "DEBUG: do 2012 (login=${ituneslogin} - password=${itunespassword} - format=${FORMAT})" - TMP_DIR="/tmp/wwdc2012.tmp" - mkdir -p $TMP_DIR - - echo "" - echo "======> SORRY: 2012 VIDEO DOWNLOAD NOT YET IMPLEMENTED! <=======" - echo "" - - rm -Rf ${TMP_DIR} -} - - -#**************************************************************************************# -# WWDC 2015 # -#**************************************************************************************# -doGetWWDC2015 () { - ituneslogin=$1 - itunespassword=$2 - FORMAT=$3 - - if [ ${VERBOSE} == true ]; - then - echo "Sessions to be downloaded: ${SESSION_WANTED}" - echo "Output directory: ${WWDC_DIRNAME}" - fi - - mkdir -p $TMP_DIR - - # Processing Authentifcation - depreciated now (but kept for copy/pasters like me that might need to use this as a snippet for other uses) - if [ -z "${ituneslogin}" ]; - then - # Dynamically get the key value as this can change (it did change for instance when Apple had to turn down their developer Portal for a week) - if [ ${VERBOSE} == true ]; - then - echo "Getting appIDKey..." - fi - key=$(curl -s -L https://developer.apple.com/iphone | grep 'login?&appIdKey=' | sed -e 's/\(.*login?&appIdKey=\)\(.*\)\(&.*\)/\2/' | awk 'NR==1 {print $1}') - if [ ${VERBOSE} == true ]; - then - echo "appIDKey: ${key}" - fi - cookies=(--cookies=on --keep-session-cookies) - - action=$(curl -s 'https://daw.apple.com/cgi-bin/WebObjects/DSAuthWeb.woa/wa/login?appIdKey='"${key}" | grep '\ action=' | awk '{ print $4 }' | cut -f2 -d"=" | sed -e "s/^.*\"\(.*\)\".*$/\1/") - - curl -s --cookie-jar $TMP_DIR/cookies.txt "https://daw.apple.com${action}" -d theAccountName="${ituneslogin}" -d theAccountPW="${itunespassword}" > /dev/null - - curl -s --cookie $TMP_DIR/cookies.txt \ - --cookie-jar $TMP_DIR/cookies.txt \ - ${VIDEO_URL} > $TMP_DIR/video.html - else - curl -silent ${VIDEO_URL} > $TMP_DIR/video.html - fi - - cat ${TMP_DIR}/video.html | sed -e '/class="inner_v_section"/,/<\/section>/!d' > $TMP_DIR/video-cleaned.html - - if [ -f ${TMP_DIR}/titles.txt ] ; then - rm ${TMP_DIR}/titles.txt - fi - cat ${TMP_DIR}/video-cleaned.html | while read line; do - # domain if for future use ... - #domain=`echo $line | grep -o -E '<h6>(.*)</h6>' | cut -d'<' -f2 | cut -d'>' -f2` - sessionNum=`echo $line | grep -o -E '<a(.*)</a>' | cut -d'=' -f3 | cut -d'"' -f1` - title_array[$sessionNum]=`echo $line | grep -o -E '<a(.*)</a>' | cut -d'>' -f2 | cut -d'<' -f1` - echo "$sessionNum;${title_array[$sessionNum]}" >> $TMP_DIR/titles.txt - done - - #`sed -n '/^,/!p' $TMP_DIR/titles.txt > $TMP_DIR/titles.txt.tmp && mv $TMP_DIR/titles.txt.tmp $TMP_DIR/titles.txt` - `sed '/^;/d' $TMP_DIR/titles.txt > $TMP_DIR/titles.txt.tmp && mv $TMP_DIR/titles.txt.tmp $TMP_DIR/titles.txt` - - # escape special char for downloading issues (ex: I/O string) - # Ok this is dirty, but quick ! ;) - mv ${TMP_DIR}/titles.txt ${TMP_DIR}/titles-to-be-escaped.txt - sed -e 's/\//\-/g' ${TMP_DIR}/titles-to-be-escaped.txt > ${TMP_DIR}/titles.txt - mv ${TMP_DIR}/titles.txt ${TMP_DIR}/titles-to-be-escaped.txt - sed -e 's/&/AND/g' ${TMP_DIR}/titles-to-be-escaped.txt > ${TMP_DIR}/titles.txt - - while read line - do - sessionNum=`echo $line | cut -d';' -f1` - sessionTitle=`echo $line | cut -d';' -f2` - title_array[$sessionNum]=${sessionTitle} - done < ${TMP_DIR}/titles.txt - - - - if [ ${LIST_MODE} == true ]; - then - echo "Available videos:" - echo "-----------------" - cat ${TMP_DIR}/titles.txt | cut -d';' -f1 | while read line; do - echo "$line: ${title_array[$line]}" - #printf '%s\n' "${title_array[@]}" - done; - exit - fi - - echo "******* DOWNLOADING ${FORMAT} VIDEOS ********" - - # Videos ${FORMAT} - mkdir -p "${WWDC_DIRNAME}/${FORMAT}-VIDEOs" - # do the rm *.download only if files exist - FILES_LIST="$(ls "${WWDC_DIRNAME}"/${FORMAT}-VIDEOs/*.download 2>/dev/null)" - if [ -z "$FILES_LIST" ]; then - #echo "All downloads will go to your Desktop/WWDC-2013 folder!" - : - else - echo "Some download was aborted last time you ran this script." - rm "${WWDC_DIRNAME}"/${FORMAT}-VIDEOs/*.download - echo "Cleaning non fully downloaded files: OK" - fi - - - # Prepare for SAMPLE-CODE - mkdir -p "${WWDC_DIRNAME}/SAMPLE-CODE" - # do the rm *.download only if files exist - FILES_LIST="$(ls "${WWDC_DIRNAME}"/SAMPLE-CODE/*.download 2>/dev/null)" - if [ -z "$FILES_LIST" ]; then - #echo "Hope you like my code? I know there are lot's of improvment I could make. In particular split in functions ..." - : - else - echo "Some sample code files download was aborted last time you ran this script." - rm "${WWDC_DIRNAME}"/SAMPLE-CODE/*.download - echo "Cleaning non fully downloaded sample code zip files: OK" - fi - - - - i=0 - # TODO: / WARNING (for possible future function merge): note that devstreaming url does use hard coded "wwdc" in it, were tech-talks function url is "techtalks" (whithout dash) - - if [ "${FORMAT}" = "HD" ]; - then - LC_FORMAT="hd" - else - LC_FORMAT="sd" - fi - REGEXFILE="[0-9a-zA-Z]*\/[0-9]{1,5}\/[0-9]{1,5}_${LC_FORMAT}_.*\.mp4" - - # get individuals video pages - cat ${TMP_DIR}/titles.txt | cut -d';' -f1 | while read line; do - curl -silent "${VIDEO_URL}?id=$line" > "${TMP_DIR}/$line-video.html"; - videoURL=`cat ${TMP_DIR}/$line-video.html | grep -o -E 'href="(http:\/\/devstreaming.apple.com\/videos\/wwdc\/'${YEAR}'/'${REGEXFILE}'\?dl=1+)"'| cut -d'"' -f2` - #echo ${line}: ${videoURL} - - # Get sample codes - cat ${TMP_DIR}/$line-video.html | grep -o -E '(class="sample-code"|class="playground")(.*)</a>' | cut -d'"' -f4 > "${TMP_DIR}/${line}-sampleCodeURL.txt" - cat ${TMP_DIR}/$line-video.html | grep -o -E '(class="sample-code"|class="playground")(.*)</a>' | cut -d'>' -f3 | cut -d'<' -f1 > "${TMP_DIR}/${line}-sampleCodeName.txt" - paste -d';' "${TMP_DIR}/${line}-sampleCodeName.txt" "${TMP_DIR}/${line}-sampleCodeURL.txt" > "${TMP_DIR}/${line}-sampleCode.txt" - - # escape special char for downloading issues (ex: I/O string) - # Ok this is dirty, but it need to be quick ! ;) - mv ${TMP_DIR}/${line}-sampleCode.txt ${TMP_DIR}/${line}-sampleCode-to-be-escaped.txt - sed -e 's/I\/O/I\-O/g' ${TMP_DIR}/${line}-sampleCode-to-be-escaped.txt > ${TMP_DIR}/${line}-sampleCode.txt - mv ${TMP_DIR}/${line}-sampleCode.txt ${TMP_DIR}/${line}-sampleCode-to-be-escaped.txt - sed -e 's/&/AND/g' ${TMP_DIR}/${line}-sampleCode-to-be-escaped.txt > ${TMP_DIR}/${line}-sampleCode.txt - - - sampleCodeURL=() - sampleCodeName=() - nb_lines=0 - while read lineURL; do - sampleCodePATHOnLine=`echo ${lineURL} | cut -d';' -f2` - sampleCodeNameOnLine=`echo ${lineURL} | cut -d';' -f1` - replacement=" -" - sampleCodeNameOnLine="${sampleCodeNameOnLine/:/${replacement}}" - if [[ ! ${lineURL} =~ \.zip$ ]]; - then - curl -silent -L "${SAMPLE_CODE_ROOT_URL}/${sampleCodePATHOnLine}/book.json" > "${TMP_DIR}/$line-book.json"; - sampleCodeURL[nb_lines]=`cat "${TMP_DIR}/$line-book.json" | grep -o -E '"sampleCode":".*\.zip"' | cut -d'"' -f4` - sampleCodeName[nb_lines]=${sampleCodeNameOnLine} - sampleCodePATH=${sampleCodePATHOnLine} - #echo " (${nb_lines})${sampleCodeName[nb_lines]}: ${SAMPLE_CODE_ROOT_URL}/${sampleCodePATHOnLine}/${sampleCodeURL[nb_lines]}" - else - sampleCodeURL[nb_lines]=${sampleCodePATHOnLine} - #sampleCodeName[nb_lines]=${lineURL%.*} - sampleCodeName[nb_lines]=${sampleCodeNameOnLine} - sampleCodePATH=${sampleCodeURL[nb_lines]} - #echo "==> Direct zip: ${sampleCodeName[nb_lines]}: ${SAMPLE_CODE_ROOT_URL}/${sampleCodeURL[nb_lines]}/${sampleCodeURL[nb_lines]}" - fi - ((nb_lines+=1)) - done < "${TMP_DIR}/${line}-sampleCode.txt" - - if [ ${SELECTIVE_SESSION_MODE} == true ]; - then - if `echo ${SESSION_WANTED} | grep "${line}" 1>/dev/null 2>&1` - then - # downloading video files - dest_path="${WWDC_DIRNAME}/${FORMAT}-VIDEOs/${line} - ${title_array[$line]}-${FORMAT}.mov" - if [ -f "${dest_path}" ] - then - echo "${dest_path} already downloaded (nothing to do!)" - else - echo "downloading ${FORMAT} Video for session ${line}: ${title_array[$line]}" - curl "${videoURL}" > "${dest_path}.download" - mv "${dest_path}.download" "${dest_path}" - fi - - # downloading sample codes files - for i in "${!sampleCodeURL[@]}"; do - #if [ -n "${sampleCodeURL[$i]}" ]; then - dest_path="${WWDC_DIRNAME}/SAMPLE-CODE/${line} - ${sampleCodeName[$i]}.zip" - if [ -f "${dest_path}" ] - then - echo "${dest_path} already downloaded (nothing to do!)" - else - echo "downloading sample code for session ${line}: ${sampleCodeName[$i]}" - echo "${SAMPLE_CODE_ROOT_URL}/${sampleCodePATH}/${sampleCodeURL[$i]}" - curl -L "${SAMPLE_CODE_ROOT_URL}/${sampleCodePATH}/${sampleCodeURL[$i]}" > "${dest_path}.download" - mv "${dest_path}.download" "${dest_path}" - fi - #fi - done - fi - else - dest_path="${WWDC_DIRNAME}/${FORMAT}-VIDEOs/${line} - ${title_array[$line]}-${FORMAT}.mov" - if [ -f "${dest_path}" ] - then - echo "${dest_path} already downloaded (nothing to do!)" - else - echo "downloading ${FORMAT} Video for session ${line}: ${title_array[$line]}" - curl -L "${videoURL}" > "${dest_path}.download" - mv "${dest_path}.download" "${dest_path}" - fi - - # downloading sample codes files - for i in "${!sampleCodeURL[@]}"; do - #if [ -n "${sampleCodeName[$i]}" ]; then - dest_path="${WWDC_DIRNAME}/SAMPLE-CODE/${line} - ${sampleCodeName[$i]}.zip" - if [ -f "${dest_path}" ] - then - echo "${dest_path} already downloaded (nothing to do!)" - else - echo "downloading sample code for session ${line}: ${sampleCodeName[$i]}" - curl -L "${SAMPLE_CODE_ROOT_URL}/${sampleCodePATH}/${sampleCodeURL[$i]}" > "${dest_path}.download" - mv "${dest_path}.download" "${dest_path}" - fi - #fi - done - fi - ((i+=1)) - - done; - - rm -Rf ${TMP_DIR} -} - -checkNetwork () { - curl -silent -D- -o /dev/null -s http://www.google.com 1>/dev/null 2>&1 - if [[ $? == 0 ]]; then - : - #echo "there is netxork" - else - echo "No network connexion! Man, you're here for a long walk!" - exit 1 - fi -} - -########################################################################################## -####### MAIN ########## -########################################################################################## - -#if [ $# -eq "0" ] -#then -# echo "WWDC videos and PDFs downloader (version ${VERSION})" >&2 -# echo "Usage: `basename $0` [options] <Apple dev login>" -# echo "Please use -h for more options" -# exit 1 -#fi - -ituneslogin=${@: -1} -FORMAT=${DEFAULT_FORMAT} -YEAR=${DEFAULT_YEAR} -EVENT=${DEFAULT_EVENT} - -while getopts ":hl:y:f:s:vLo:e:" opt; do - case $opt in - h) - echo "WWDC Videos and PDFs downloader (version ${VERSION})" >&2 - echo "Author: Olivier HO-A-CHUCK (http://blog.hoachuck.biz)" - echo "" - echo "Usage: `basename $0` [options]" - echo "Try -L option for list of available videos" - echo "" - echo "Options:" - echo " -y <year>: select year (ex: -y 2013). Default year is 2015" >&2 - echo " Possible values for year: 2013, 2014 and 2014" >&2 - echo " For info: year 2012 videos download is not yet available - to be honest, I'm too lazy to do it!" >&2 - echo " -e <event>: select event type between \"wwdc\" and \"tech-talks\"" >&2 - echo " default value is \"wwdc\"" >&2 - echo " -f <format>: select video format type (SD or HD). Default video format is SD" >&2 - echo " -s <comma separated session numbers>: select which sessions you want to download (try -L option for list of avialable videos)" >&2 - echo " -v : verbose mode" >&2 - echo " -o <output path>: path where to download content (default is /Users/${USER}/Documents/WWDC-<selected year|default=2015>)" >&2 - echo " -l [Not needed anymore] <iTunes login>: Give your Developer portal login (so far you don't need to login anymore. If this does change, please use -l option)." >&2 - echo " -L : List available video sessions" >&2 - echo "" >&2 - echo "" - echo "Most common usage:" >&2 - echo " - Download all available SD videos for wwdc 2015:" >&2 - echo " `basename $0`" >&2 - echo "" - echo "Other examples:" >&2 - echo " - Download all PDFs and SD videos for wwdc 2014 if Apple change his mind and ask for login:" >&2 - echo " `basename $0` -y 2014" >&2 - echo " - Download all PDFs and SD videos for tech-talks 2013:" >&2 - echo " `basename $0` -y 2013 -e tech-talks" >&2 - echo " - Download all HD videos for wwdc 2015:" >&2 - echo " `basename $0` -f HD" >&2 - echo " - Download only session 201, 400 and 401 with SD videos for wwdc 2015:" >&2 - echo " `basename $0` -s 201,400,401" >&2 - echo " - Download only session 201 and 400 with HD video for wwdc 2015:" >&2 - echo " `basename $0` -s 201,400 -f HD" >&2 - echo " - Download all HD videos for wwdc 2015 in /Users/${USER}/Desktop/WWDC-2014 using verbose mode:" >&2 - echo " `basename $0` -v -f HD -o /Users/${USER}/Desktop/WWDC-2014" >&2 - echo "" - exit 0; - ;; - l) - ITUNES_LOGIN=${OPTARG} - LOGIN=true - ;; - y) - if [ $OPTARG = "2012" ] || [ $OPTARG = "2013" ] || [ $OPTARG = "2014" ] || [ $OPTARG = "2015" ]; - then - YEAR=$OPTARG - else - echo "Unknown specified year. Using default (${YEAR})!" - fi - ;; - f) - if [ $OPTARG = "SD" ] || [ $OPTARG = "HD" ]; - then - FORMAT=$OPTARG - else - echo "Unknown specified format. Using ${FORMAT} video format!" - fi - ;; - s) - if [ $OPTARG > 0 ]; - then - SESSION_WANTED=$OPTARG - SELECTIVE_SESSION_MODE=true - else - echo "Session number does not look good!" - fi - ;; - v) - echo "Verbose mode on" - VERBOSE=true - ;; - L) - LIST_MODE=true - ;; - o) - WWDC_DIRNAME=${OPTARG} - ;; - e) - if [ $OPTARG = "tech-talks" ] || [ $OPTARG = "wwdc" ] ; - then - EVENT=$OPTARG - else - echo "Unknown event type. Using default (${EVENT})!" - fi - ;; - \?) - echo "Invalid option: -$OPTARG" >&2 - echo "For help, please use: $0 -h" - exit 1 - ;; - :) - echo "Option -$OPTARG requires an argument." >&2 - exit 1 - ;; - esac -done - -WWDC_DIRNAME=${WWDC_DIRNAME:-"${HOME}/Documents/WWDC-${YEAR}"} - -case "${YEAR}" in -"2012") - if [ -z ${ITUNES_LOGIN} ]; - then - read -r -p Login: ituneslogin ; echo - fi - if $LOGIN - then - read -r -s -p Password: itunespassword ; echo - else - echo "" - echo "Using 'no password' mode (this is possible since WWDC 2014 sessions addition => Apple bug ?)!" - echo "try using -l option if download does not work." - echo "" - ituneslogin="<no-login>" - itunespassword="<no-password>" - fi - checkNetwork - doGet2012 ${ituneslogin} ${itunespassword} ${FORMAT} - ;; -"2013") - #if [ -z ${ITUNES_LOGIN} ]; - #then - # read -r -p Login: ituneslogin ; echo - #fi - checkNetwork - - if $LOGIN ; - then - read -r -s -p Password: itunespassword ; echo - else - echo "" - echo "Using 'no password' mode (this is possible since WWDC 2014 sessions addition => Apple bug ?)!" - echo "try using -l option if download does not work." - echo "" - ituneslogin="<no-login>" - itunespassword="<no-password>" - fi - if [ ${EVENT} == "wwdc" ]; - then - VIDEO_URL=${VIDEO_URL_WWDC}/2013/ - doGetWWDCPost2012 ${ituneslogin} ${itunespassword} ${FORMAT} - elif [ ${EVENT} == "tech-talks" ]; - then - VIDEO_URL=${VIDEO_URL_TECHTALK} - doGetTT2013 ${ituneslogin} ${itunespassword} ${FORMAT} - fi - ;; -"2014") - if $LOGIN ; - then - read -r -s -p Password: itunespassword ; echo - else - echo "" - echo "Using 'no password' mode (this is possible since WWDC 2014 sessions addition => Apple bug ?)!" - echo "try using -l option if download does not work." - echo "" - ituneslogin="<no-login>" - itunespassword="<no-password>" - fi - if [ ${EVENT} == "wwdc" ]; - then - VIDEO_URL=${VIDEO_URL_WWDC}/2014/ - doGetWWDCPost2012 ${ituneslogin} ${itunespassword} ${FORMAT} - elif [ ${EVENT} == "tech-talks" ]; - then - #VIDEO_URL=${VIDEO_URL_TECHTALK} - #doGetTT2013 ${ituneslogin} ${itunespassword} ${FORMAT} - echo "No yet available session download other than 'wwdc' for 2014! Sorry man." - fi - ;; -"2015") - checkNetwork - - if $LOGIN ; - then - read -r -s -p Password: itunespassword ; echo - else - echo "" - echo "Using 'no password' mode (this is possible since WWDC 2014 sessions addition)!" - echo "try using -l option if download does not work." - echo "" - ituneslogin="<no-login>" - itunespassword="<no-password>" - fi - - if [ ${EVENT} == "wwdc" ]; - then - VIDEO_URL=${VIDEO_URL_WWDC}/2015/ - doGetWWDC2015 ${ituneslogin} ${itunespassword} ${FORMAT} - elif [ ${EVENT} == "tech-talks" ]; - then - echo "There is no TechTalk sessions available yet for 2015! Sorry for that sir." - fi - ;; -*) - echo "Sorry: can't process requested year. Please choose between \"2012\", \"2013\" , \"2014\" or \"2015\"." - ;; -esac - -exit 0 diff --git a/yarrr.js b/yarrr.js deleted file mode 100755 index 71fdbf3..0000000 --- a/yarrr.js +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env node - -require('batteries').extendNative() - -var fs = require('fs') - , http = require('http') - , join = require('path').join - , notify = require('growl').notify - , Downloads = join(process.env.HOME, 'Downloads') - , created = JSON.parse(process.env.WATCH_CREATED) - , torrents = created.grep(/\.torrent$/i) - , skipped = [] - , _log = [] - , log = function(s) { s = '>>> ' + s; _log.push(s); console.log(s) } - , err = function(s) { s = '!!! ' + s; _log.push(s); console.error(s) } - , writeLog = function() { fs.writeFileSync('/Users/sjs/log/yarrr.log', _log.join('\n')) } - -process.on('uncaughtException', function(e) { - err('error: ' + e) - err('bailing') - process.exit(1) -}) - -torrents.forEach(function(torrent, i) { - log(torrent) - var path = join(Downloads, torrent) - try { - fs.statSync(path) - } - catch (e) { - skipped.push(torrent) - err(path + ' does not exist, skipping') - return - } - var boundary = '48940923YARRRPIRATE3890457293' - , torrentData = fs.readFileSync(path, 'binary') - , torrentSize = torrentData.length - , data = [ '--' + boundary - , 'Content-Disposition: form-data; name="torrent_file"; filename="' + torrent + '"' - , 'Content-Type: application/x-bittorrent' - , '' - , torrentData - , '--' + boundary + '--\r\n' - ].join('\r\n') - , opts = { - method: 'POST', - host: 'h.samhuri.net', - port: 8080, - path: '/gui/?action=add-file', - headers: { 'Authorization': 'Basic YWRtaW46YWRtaW4=' - , 'Content-Type': 'multipart/form-data; boundary=' + boundary - , 'Content-Length': data.length - } - } - , req = http.request(opts, function(res) { - var responseData = '' - res.on('data', function(chunk) { responseData += chunk }) - res.on('end', function() { - if (res.statusCode === 200 && !('error' in JSON.parse(responseData))) { - log('rm ' + path) - fs.unlink(path) - } - else { - err('error ' + res.statusCode) - err(responseData) - } - if (i === torrents.length - 1) { - var n = torrents.length - skipped.length - , s = n === 1 ? '' : 's' - if (n > 0) { - notify(n + ' torrent' + s + ' → µTorrent') - } - //writeLog() - } - }) - }) - log('torrent size: ' + torrentSize) - log('total size: ' + data.length) - req.end(data, 'binary') -}) diff --git a/yui-compressor b/yui-compressor deleted file mode 100755 index 1ab6a8d..0000000 --- a/yui-compressor +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -java -jar ~/bin/yuicompressor-2.4.7.jar "$1" -o "$2" - diff --git a/yuicompressor-2.4.7.jar b/yuicompressor-2.4.7.jar deleted file mode 100644 index c34800c..0000000 Binary files a/yuicompressor-2.4.7.jar and /dev/null differ