Apache Rewrite Cheatsheet

November 28, 2006 | 15 Comments

Introduction

Ok, so its not a sheet...its a blog post. Regardless, I often find myself on the hunt for Apache Rewrite flags and I've found a nice one at Ilovejackdaniels.

Before diving into the cheat sheet, its important to know how RewriteRules work (order of processing and whatnot). I've prettied up the image from Apache.org as pictures tell 1,000 words (click for a larger version):

rewrite

The order of rules in the ruleset is important because the rewriting engine processes them in a special (and not very obvious) order. The rule is this: The rewriting engine loops through the ruleset rule by rule (RewriteRule directives) and when a particular rule matches it optionally loops through existing corresponding conditions (RewriteCond directives). For historical reasons the conditions are given first, and so the control flow is a little bit long-winded. --Apache.org

Now that we've gotten that taken care of, lets move on to the cheat sheet. Ilovejackdaniels did the cheat sheet as a PDF and, frankly, I find PDFs annoying. So here's the contents:

Regular Expression Syntax

^ Start of string
$ End of string
. Any single character
(a|b) a or b
(...) Group section
[abc] Item in range (a or b or c)
[^abc] Not in range (not a or b or c)
a? Zero or one of a
a* Zero or more of a
a+ One or more of a
a{3} Exactly 3 of a
a{3,} 3 or more of a
a{3,6} Between 3 and 6 of a
!(pattern) "Not" prefix. Apply rule when URL does not match pattern

RewriteRule FLAGS

I'm going to go a little deeper in this list than what the cheat sheet does as I tend to need a little more of a description on what each flag does (all descriptions are lifted without remorse from Apache.org)...not just the short definition.

R[=code] Redirect to new URL, with optional code (see below). Prefix Substitution with http://thishost[:thisport]/ (which makes the new URL a URI) to force a external redirection. If no code is given a HTTP response of 302 (MOVED TEMPORARILY) is used. If you want to use other response codes in the range 300-400 just specify them as a number or use one of the following symbolic names: temp (default), permanent, seeother. Use it for rules which should canonicalize the URL and give it back to the client, e.g., translate ``/~'' into ``/u/'' or always append a slash to /u/user, etc.

Note: When you use this flag, make sure that the substitution field is a valid URL! If not, you are redirecting to an invalid location! And remember that this flag itself only prefixes the URL with http://thishost[:thisport]/, rewriting continues. Usually you also want to stop and do the redirection immediately. To stop the rewriting you also have to provide the 'L' flag.

F Forbidden (sends 403 header) This forces the current URL to be forbidden, i.e., it immediately sends back a HTTP response of 403 (FORBIDDEN). Use this flag in conjunction with appropriate RewriteConds to conditionally block some URLs.
G Gone (no longer exists) This forces the current URL to be gone, i.e., it immediately sends back a HTTP response of 410 (GONE). Use this flag to mark pages which no longer exist as gone.
P Proxy This flag forces the substitution part to be internally forced as a proxy request and immediately (i.e., rewriting rule processing stops here) put through the proxy module. You have to make sure that the substitution string is a valid URI (e.g., typically starting with http://hostname) which can be handled by the Apache proxy module. If not you get an error from the proxy module. Use this flag to achieve a more powerful implementation of the ProxyPass directive, to map some remote stuff into the namespace of the local server.

Notice: To use this functionality make sure you have the proxy module compiled into your Apache server program. If you don't know please check whether mod_proxy.c is part of the ``httpd -l'' output. If yes, this functionality is available to mod_rewrite. If not, then you first have to rebuild the ``httpd'' program with mod_proxy enabled.

L Last Rule Stop the rewriting process here and don't apply any more rewriting rules. This corresponds to the Perl last command or the break command from the C language. Use this flag to prevent the currently rewritten URL from being rewritten further by following rules. For example, use it to rewrite the root-path URL ('/') to a real one, e.g., '/e/www/'.
N Next (i.e. restart rules) Re-run the rewriting process (starting again with the first rewriting rule). Here the URL to match is again not the original URL but the URL from the last rewriting rule. This corresponds to the Perl next command or the continue command from the C language. Use this flag to restart the rewriting process, i.e., to immediately go to the top of the loop.

But be careful not to create an infinite loop!

C Chain This flag chains the current rule with the next rule (which itself can be chained with the following rule, etc.). This has the following effect: if a rule matches, then processing continues as usual, i.e., the flag has no effect. If the rule does not match, then all following chained rules are skipped. For instance, use it to remove the ``.www'' part inside a per-directory rule set when you let an external redirect happen (where the ``.www'' part should not to occur!).
T=mime-type Set Mime Type Force the MIME-type of the target file to be MIME-type. For instance, this can be used to simulate the mod_alias directive ScriptAlias which internally forces all files inside the mapped directory to have a MIME type of ``application/x-httpd-cgi''.
NS Skip if internal sub-request This flag forces the rewriting engine to skip a rewriting rule if the current request is an internal sub-request. For instance, sub-requests occur internally in Apache when mod_include tries to find out information about possible directory default files (index.xxx). On sub-requests it is not always useful and even sometimes causes a failure to if the complete set of rules are applied. Use this flag to exclude some rules.

Use the following rule for your decision: whenever you prefix some URLs with CGI-scripts to force them to be processed by the CGI-script, the chance is high that you will run into problems (or even overhead) on sub-requests. In these cases, use this flag.

NC Case insensitive This makes the Pattern case-insensitive, i.e., there is no difference between 'A-Z' and 'a-z' when Pattern is matched against the current URL.
QSA Append query string This flag forces the rewriting engine to append a query string part in the substitution string to the existing one instead of replacing it. Use this when you want to add more data to the query string via a rewrite rule.
NE Do not escape output This flag keeps mod_rewrite from applying the usual URI escaping rules to the result of a rewrite. Ordinarily, special characters (such as '%', '$', ';', and so on) will be escaped into their hexcode equivalents ('%25', '%24', and '%3B', respectively); this flag prevents this from being done. This allows percent symbols to appear in the output, as in

RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE]

which would turn '/foo/zed' into a safe request for '/bar?arg=P1=zed'.

PT Pass through This flag forces the rewriting engine to set the uri field of the internal request_rec structure to the value of the filename field. This flag is just a hack to be able to post-process the output of RewriteRule directives by Alias, ScriptAlias, Redirect, etc. directives from other URI-to-filename translators. A trivial example to show the semantics: If you want to rewrite /abc to /def via the rewriting engine of mod_rewrite and then /def to /ghi with mod_alias:

RewriteRule ^/abc(.*) /def$1 [PT]
Alias /def /ghi

If you omit the PT flag then mod_rewrite will do its job fine, i.e., it rewrites uri=/abc/... to filename=/def/... as a full API-compliant URI-to-filename translator should do. Then mod_alias comes and tries to do a URI-to-filename transition which will not work.

Note: You have to use this flag if you want to intermix directives of different modules which contain URL-to-filename translators. The typical example is the use of mod_alias and mod_rewrite..

S=x Skip next x rules This flag forces the rewriting engine to skip the next num rules in sequence when the current rule matches. Use this to make pseudo if-then-else constructs: The last rule of the then-clause becomes skip=N where N is the number of rules in the else-clause. (This is not the same as the 'chain|C' flag!)
E=var:value Set environment variable "var" to "value" This forces an environment variable named VAR to be set to the value VAL, where VAL can contain regexp backreferences $N and %N which will be expanded. You can use this flag more than once to set more than one variable. The variables can be later dereferenced in many situations, but usually from within XSSI (via ) or CGI (e.g. $ENV{'VAR'}). Additionally you can dereference it in a following RewriteCond pattern via %{ENV:VAR}. Use this to strip but remember information from URLs.

RewriteCond FLAGS

NC Case insensitive
OR Allows a rule to apply if one of a series of conditions are true.

Redirection Header Codes

301 Moved permanently
302 Moved temporarily
403 Forbidden
404 Not found
410 Gone

Server Variables

Format
  %{NAME_OF_VAR}
HTTP Headers
  HTTP_USER_AGENT
  HTTP_REFERER
  HTTP_COOKIE
  HTTP_FORWARDED
  HTTP_HOST
  HTTP_PROXY_CONNECTION
  HTTP_ACCEPT
Request
  REMOTE_ADDR
  REMOTE_HOST
  REMOTE_USER
  REMOTE_IDENT
  REQUEST_METHOD
  SCRIPT_FILENAME
  PATH_INFO
  QUERY_STRING
  AUTH_TYPE
Server
  DOCUMENT_ROOT
  SERVER_ADMIN
  SERVER_NAME
  SERVER_ADDR
  SERVER_PORT
  SERVER_PROTOCOL
  SERVER_SOFTWARE
Time
  TIME_YEAR
  TIME_MON
  TIME_DAY
  TIME_HOUR
  TIME_MIN
  TIME_SEC
  TIME_WDAY
  TIME
Special
  API_VERSION
  THE_REQUEST
  REQUEST_URI
  REQUEST_FILENAME
  IS_SUBREQ

Directives

  RewriteEngine
  RewriteOptions
  RewriteLog
  RewriteLogLevel
  RewriteLock
  RewriteMap
  RewriteBase
  RewriteCond
  RewriteRule

Example Rules

CODE:
  1. # Site has permanently moved to new domain
  2. # domain.com to domain2.com
  3. RewriteCond   %{HTTP_HOST}   ^www.domain.com$   [NC]
  4. RewriteRule   ^(.*)$   http://www.domain2.com/$1   [R=301,L]

CODE:
  1. # Page has moved temporarily
  2. # domain.com/page.html to domain.com/new_page.html
  3. RewriteRule   ^page.html$   new_page.html   [R,NC,L]

CODE:
  1. # Nice looking URLs (no query string)
  2. # domain.com/category-name-1/ to domain.com/categories.php?name=category-name-1
  3. RewriteRule   ^([A-Za-z0-9-]+)/?$   categories.php?name=$1 [L]

CODE:
  1. # Nice looking URLs (no query string) with pagination
  2. # domain.com/articles/title/5 to domain.com/article.php?name=title&page=5
  3. RewriteRule   ^articles/([A-Za-z0-9-]+)/([0-9]+)/?$   article.php?name=$1&page=$2 [L]

CODE:
  1. # Block referrer spam
  2. RewriteCond  %{HTTP_REFERRER}  (weight)  [NC,OR]
  3. RewriteCond  %{HTTP_REFERRER}  (drugs)  [NC]
  4. RewriteRule  .*  -  [F]

In addition to the above, the Apache Rewrite Guide may prove useful!

Firefox Search Plugin for PHP.net

November 3, 2006 | Leave a Comment

php Dan, one of my co-workers, has been tooling around with PHP and easily plopped a PHP search extension into Internet Explorer 7. Well. I don't like IE7 as much as Firefox and sadly there's no super easy way to add a search plugin (if it doesn't exist or you can't find one...like in my case) without coding up the XML.

So, using Mozilla's instructions I whipped up a PHP.net search plugin. Here it is to anyone interested:

XML:
  1. <opensearchdescription xmlns="http://a9.com/-/spec/opensearch/1.1/" xmlns:moz="http://www.mozilla.org/2006/browser/search/">
  2.     <shortname>PHP</shortname>
  3.     <description>PHP.net</description>
  4.     <inputencoding>UTF-8</inputencoding>
  5.     <image width="16" height="16">data:image/jpeg,%FF%D8%FF%E0%00%10JFIF%00%01%02%01%00H%00H%00%00%FF%E1%03%CCExif%00%00MM%00*%00%00%00%08%00%07%01%12%00%03%00%00%00%01%00%01%00%00%01%1A%00%05%00%00%00%01%00%00%00b%01%1B%00%05%00%00%00%01%00%00%00j%01(%00%03%00%00%00%01%00%02%00%00%011%00%02%00%00%00%14%00%00%00r%012%00%02%00%00%00%14%00%00%00%86%87i%00%04%00%00%00%01%00%00%00%9C%00%00%00%C8%00%00%00H%00%00%00%01%00%00%00H%00%00%00%01Adobe%20Photoshop%207.0%002006%3A11%3A03%2015%3A18%3A39%00%00%00%00%03%A0%01%00%03%00%00%00%01%FF%FF%00%00%A0%02%00%04%00%00%00%01%00%00%00%10%A0%03%00%04%00%00%00%01%00%00%00%10%00%00%00%00%00%00%00%06%01%03%00%03%00%00%00%01%00%06%00%00%01%1A%00%05%00%00%00%01%00%00%01%16%01%1B%00%05%00%00%00%01%00%00%01%1E%01(%00%03%00%00%00%01%00%02%00%00%02%01%00%04%00%00%00%01%00%00%01%26%02%02%00%04%00%00%00%01%00%00%02%9E%00%00%00%00%00%00%00H%00%00%00%01%00%00%00H%00%00%00%01%FF%D8%FF%E0%00%10JFIF%00%01%02%01%00H%00H%00%00%FF%ED%00%0CAdobe_CM%00%02%FF%EE%00%0EAdobe%00d%80%00%00%00%01%FF%DB%00%84%00%0C%08%08%08%09%08%0C%09%09%0C%11%0B%0A%0B%11%15%0F%0C%0C%0F%15%18%13%13%15%13%13%18%11%0C%0C%0C%0C%0C%0C%11%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%01%0D%0B%0B%0D%0E%0D%10%0E%0E%10%14%0E%0E%0E%14%14%0E%0E%0E%0E%14%11%0C%0C%0C%0C%0C%11%11%0C%0C%0C%0C%0C%0C%11%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%FF%C0%00%11%08%00%10%00%10%03%01%22%00%02%11%01%03%11%01%FF%DD%00%04%00%01%FF%C4%01%3F%00%00%01%05%01%01%01%01%01%01%00%00%00%00%00%00%00%03%00%01%02%04%05%06%07%08%09%0A%0B%01%00%01%05%01%01%01%01%01%01%00%00%00%00%00%00%00%01%00%02%03%04%05%06%07%08%09%0A%0B%10%00%01%04%01%03%02%04%02%05%07%06%08%05%03%0C3%01%00%02%11%03%04!%121%05AQa%13%22q%812%06%14%91%A1%B1B%23%24%15R%C1b34r%82%D1C%07%25%92S%F0%E1%F1cs5%16%A2%B2%83%26D%93TdE%C2%A3t6%17%D2U%E2e%F2%B3%84%C3%D3u%E3%F3F'%94%A4%85%B4%95%C4%D4%E4%F4%A5%B5%C5%D5%E5%F5Vfv%86%96%A6%B6%C6%D6%E6%F67GWgw%87%97%A7%B7%C7%D7%E7%F7%11%00%02%02%01%02%04%04%03%04%05%06%07%07%06%055%01%00%02%11%03!1%12%04AQaq%22%13%052%81%91%14%A1%B1B%23%C1R%D1%F03%24b%E1r%82%92CS%15cs4%F1%25%06%16%A2%B2%83%07%265%C2%D2D%93T%A3%17dEU6te%E2%F2%B3%84%C3%D3u%E3%F3F%94%A4%85%B4%95%C4%D4%E4%F4%A5%B5%C5%D5%E5%F5Vfv%86%96%A6%B6%C6%D6%E6%F6'7GWgw%87%97%A7%B7%C7%FF%DA%00%0C%03%01%00%02%11%03%11%00%3F%00N%EA%D8%D5%E4%D9%8Fk%2Cg%A6v%8BN%CD%8E!%D5Uf%DF%D2oo%A6%EC%8A%FF%00%9CbG%AB%E2%FD%AA%BCv%B2%C7%8B%1E%2B77a%60s%ADv%1D%7F%9F%BD%CD%B2%E6%FEcT%9F%D2%F0%DE2K%ABa%B3-%E1%F6%D8k%05%C5%AD%7Dv%FA%0F%9F%A7_%E8%B6%7F%DF%14q%FAF%16%3EO%DA%19%5B%09f%EF%B3%B7%D3kE%5B%9Fm%DF%A1%89%DB%FC%F7%A7%EDo%E6%2B%DF%AD%B4%3F%FF%D9%FF%ED%08%86Photoshop%203.0%008BIM%04%25%00%00%00%00%00%10%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%008BIM%03%ED%00%00%00%00%00%10%00H%00%00%00%01%00%01%00H%00%00%00%01%00%018BIM%04%26%00%00%00%00%00%0E%00%00%00%00%00%00%00%00%00%00%3F%80%00%008BIM%04%0D%00%00%00%00%00%04%00%00%00x8BIM%04%19%00%00%00%00%00%04%00%00%00%1E8BIM%03%F3%00%00%00%00%00%09%00%00%00%00%00%00%00%00%01%008BIM%04%0A%00%00%00%00%00%01%00%008BIM'%10%00%00%00%00%00%0A%00%01%00%00%00%00%00%00%00%018BIM%03%F5%00%00%00%00%00H%00%2Fff%00%01%00lff%00%06%00%00%00%00%00%01%00%2Fff%00%01%00%A1%99%9A%00%06%00%00%00%00%00%01%002%00%00%00%01%00Z%00%00%00%06%00%00%00%00%00%01%005%00%00%00%01%00-%00%00%00%06%00%00%00%00%00%018BIM%03%F8%00%00%00%00%00p%00%00%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%03%E8%00%00%00%00%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%03%E8%00%00%00%00%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%03%E8%00%00%00%00%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%03%E8%00%008BIM%04%00%00%00%00%00%00%02%00%018BIM%04%02%00%00%00%00%00%04%00%00%00%008BIM%04%08%00%00%00%00%00%10%00%00%00%01%00%00%02%40%00%00%02%40%00%00%00%008BIM%04%1E%00%00%00%00%00%04%00%00%00%008BIM%04%1A%00%00%00%00%03I%00%00%00%06%00%00%00%00%00%00%00%00%00%00%00%10%00%00%00%10%00%00%00%0A%00U%00n%00t%00i%00t%00l%00e%00d%00-%001%00%00%00%01%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%01%00%00%00%00%00%00%00%00%00%00%00%10%00%00%00%10%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%01%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%10%00%00%00%01%00%00%00%00%00%00null%00%00%00%02%00%00%00%06boundsObjc%00%00%00%01%00%00%00%00%00%00Rct1%00%00%00%04%00%00%00%00Top%20long%00%00%00%00%00%00%00%00Leftlong%00%00%00%00%00%00%00%00Btomlong%00%00%00%10%00%00%00%00Rghtlong%00%00%00%10%00%00%00%06slicesVlLs%00%00%00%01Objc%00%00%00%01%00%00%00%00%00%05slice%00%00%00%12%00%00%00%07sliceIDlong%00%00%00%00%00%00%00%07groupIDlong%00%00%00%00%00%00%00%06originenum%00%00%00%0CESliceOrigin%00%00%00%0DautoGenerated%00%00%00%00Typeenum%00%00%00%0AESliceType%00%00%00%00Img%20%00%00%00%06boundsObjc%00%00%00%01%00%00%00%00%00%00Rct1%00%00%00%04%00%00%00%00Top%20long%00%00%00%00%00%00%00%00Leftlong%00%00%00%00%00%00%00%00Btomlong%00%00%00%10%00%00%00%00Rghtlong%00%00%00%10%00%00%00%03urlTEXT%00%00%00%01%00%00%00%00%00%00nullTEXT%00%00%00%01%00%00%00%00%00%00MsgeTEXT%00%00%00%01%00%00%00%00%00%06altTagTEXT%00%00%00%01%00%00%00%00%00%0EcellTextIsHTMLbool%01%00%00%00%08cellTextTEXT%00%00%00%01%00%00%00%00%00%09horzAlignenum%00%00%00%0FESliceHorzAlign%00%00%00%07default%00%00%00%09vertAlignenum%00%00%00%0FESliceVertAlign%00%00%00%07default%00%00%00%0BbgColorTypeenum%00%00%00%11ESliceBGColorType%00%00%00%00None%00%00%00%09topOutsetlong%00%00%00%00%00%00%00%0AleftOutsetlong%00%00%00%00%00%00%00%0CbottomOutsetlong%00%00%00%00%00%00%00%0BrightOutsetlong%00%00%00%00%008BIM%04%11%00%00%00%00%00%01%01%008BIM%04%14%00%00%00%00%00%04%00%00%00%048BIM%04%0C%00%00%00%00%02%BA%00%00%00%01%00%00%00%10%00%00%00%10%00%00%000%00%00%03%00%00%00%02%9E%00%18%00%01%FF%D8%FF%E0%00%10JFIF%00%01%02%01%00H%00H%00%00%FF%ED%00%0CAdobe_CM%00%02%FF%EE%00%0EAdobe%00d%80%00%00%00%01%FF%DB%00%84%00%0C%08%08%08%09%08%0C%09%09%0C%11%0B%0A%0B%11%15%0F%0C%0C%0F%15%18%13%13%15%13%13%18%11%0C%0C%0C%0C%0C%0C%11%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%01%0D%0B%0B%0D%0E%0D%10%0E%0E%10%14%0E%0E%0E%14%14%0E%0E%0E%0E%14%11%0C%0C%0C%0C%0C%11%11%0C%0C%0C%0C%0C%0C%11%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%0C%FF%C0%00%11%08%00%10%00%10%03%01%22%00%02%11%01%03%11%01%FF%DD%00%04%00%01%FF%C4%01%3F%00%00%01%05%01%01%01%01%01%01%00%00%00%00%00%00%00%03%00%01%02%04%05%06%07%08%09%0A%0B%01%00%01%05%01%01%01%01%01%01%00%00%00%00%00%00%00%01%00%02%03%04%05%06%07%08%09%0A%0B%10%00%01%04%01%03%02%04%02%05%07%06%08%05%03%0C3%01%00%02%11%03%04!%121%05AQa%13%22q%812%06%14%91%A1%B1B%23%24%15R%C1b34r%82%D1C%07%25%92S%F0%E1%F1cs5%16%A2%B2%83%26D%93TdE%C2%A3t6%17%D2U%E2e%F2%B3%84%C3%D3u%E3%F3F'%94%A4%85%B4%95%C4%D4%E4%F4%A5%B5%C5%D5%E5%F5Vfv%86%96%A6%B6%C6%D6%E6%F67GWgw%87%97%A7%B7%C7%D7%E7%F7%11%00%02%02%01%02%04%04%03%04%05%06%07%07%06%055%01%00%02%11%03!1%12%04AQaq%22%13%052%81%91%14%A1%B1B%23%C1R%D1%F03%24b%E1r%82%92CS%15cs4%F1%25%06%16%A2%B2%83%07%265%C2%D2D%93T%A3%17dEU6te%E2%F2%B3%84%C3%D3u%E3%F3F%94%A4%85%B4%95%C4%D4%E4%F4%A5%B5%C5%D5%E5%F5Vfv%86%96%A6%B6%C6%D6%E6%F6'7GWgw%87%97%A7%B7%C7%FF%DA%00%0C%03%01%00%02%11%03%11%00%3F%00N%EA%D8%D5%E4%D9%8Fk%2Cg%A6v%8BN%CD%8E!%D5Uf%DF%D2oo%A6%EC%8A%FF%00%9CbG%AB%E2%FD%AA%BCv%B2%C7%8B%1E%2B77a%60s%ADv%1D%7F%9F%BD%CD%B2%E6%FEcT%9F%D2%F0%DE2K%ABa%B3-%E1%F6%D8k%05%C5%AD%7Dv%FA%0F%9F%A7_%E8%B6%7F%DF%14q%FAF%16%3EO%DA%19%5B%09f%EF%B3%B7%D3kE%5B%9Fm%DF%A1%89%DB%FC%F7%A7%EDo%E6%2B%DF%AD%B4%3F%FF%D98BIM%04!%00%00%00%00%00U%00%00%00%01%01%00%00%00%0F%00A%00d%00o%00b%00e%00%20%00P%00h%00o%00t%00o%00s%00h%00o%00p%00%00%00%13%00A%00d%00o%00b%00e%00%20%00P%00h%00o%00t%00o%00s%00h%00o%00p%00%20%007%00.%000%00%00%00%01%008BIM%04%06%00%00%00%00%00%07%00%08%01%01%00%01%01%00%FF%E1%12Hhttp%3A%2F%2Fns.adobe.com%2Fxap%2F1.0%2F%00%3C%3Fxpacket%20begin%3D'%EF%BB%BF'%20id%3D'W5M0MpCehiHzreSzNTczkc9d'%3F%3E%0A%3C%3Fadobe-xap-filters%20esc%3D%22CR%22%3F%3E%0A%3Cx%3Axapmeta%20xmlns%3Ax%3D'adobe%3Ans%3Ameta%2F'%20x%3Axaptk%3D'XMP%20toolkit%202.8.2-33%2C%20framework%201.5'%3E%0A%3Crdf%3ARDF%20xmlns%3Ardf%3D'http%3A%2F%2Fwww.w3.org%2F1999%2F02%2F22-rdf-syntax-ns%23'%20xmlns%3AiX%3D'http%3A%2F%2Fns.adobe.com%2FiX%2F1.0%2F'%3E%0A%0A%20%3Crdf%3ADescription%20about%3D'uuid%3A662ee06d-6b78-11db-bb16-f420df7fe7bb'%0A%20%20xmlns%3AxapMM%3D'http%3A%2F%2Fns.adobe.com%2Fxap%2F1.0%2Fmm%2F'%3E%0A%20%20%3CxapMM%3ADocumentID%3Eadobe%3Adocid%3Aphotoshop%3Af2ecf595-6b77-11db-bb16-f420df7fe7bb%3C%2FxapMM%3ADocumentID%3E%0A%20%3C%2Frdf%3ADescription%3E%0A%0A%3C%2Frdf%3ARDF%3E%0A%3C%2Fx%3Axapmeta%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%3C%3Fxpacket%20end%3D'w'%3F%3E%FF%EE%00!Adobe%00d%40%00%00%00%01%03%00%10%03%02%03%06%00%00%00%00%00%00%00%00%00%00%00%00%FF%DB%00%84%00%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%01%02%02%02%02%02%02%02%02%02%02%02%03%03%03%03%03%03%03%03%03%03%01%01%01%01%01%01%01%01%01%01%01%02%02%01%02%02%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%03%FF%C2%00%11%08%00%10%00%10%03%01%11%00%02%11%01%03%11%01%FF%C4%00%8B%00%00%03%00%00%00%00%00%00%00%00%00%00%00%00%00%00%02%04%05%01%00%03%01%00%00%00%00%00%00%00%00%00%00%00%00%00%00%01%03%08%10%00%01%03%04%02%03%00%00%00%00%00%00%00%00%00%00%07%03%04%05%00%12%06%08%01%11%02%15%17%11%00%02%03%01%01%00%02%03%01%00%00%00%00%00%00%00%03%06%04%05%07%02%01%15%17%11%12%16%08%12%00%02%02%01%03%01%09%01%00%00%00%00%00%00%00%00%01%02%11%03%12%00!%04Q%201Aq%222%13%05%15%14%FF%DA%00%0C%03%01%01%02%11%03%11%00%00%00-_5%D1~%C4v%7F%FF%DA%00%08%01%02%00%01%05%00%5C%8A%DD%BB%EF%A44%F6%0B%E0%0DVJ%1B%00c%1B)%FF%DA%00%08%01%03%00%01%05%00%B6%AD%AB%AB%9F.%EB%FF%DA%00%08%01%01%00%01%05%00%93%DB%01%AE%3AH_nF%3C%93%26%B5%7C9%3E%86%03%A8%C1A%C1%23%FF%DA%00%08%01%02%02%06%3F%00%E7p%ED%FA%CB%00%A9%CA%ABd%B0%F8%D8%88%DDJ%C6%60%EE%00%D8%C1%3A%AB%89%F9%CEx%CDn%06%C5e%20M%A6%A512C0%1E%D9%80d%EB%EDIz%BF%B3%95%C8%0El)'%E3%CD%5C%D6D%FA%81%C7%CB_%A1%C8%14%DBZdjA%5C%0A%CBX%EE%0A%EF%1B%06%03%BB%C2zk%FF%DA%00%08%01%03%02%06%3F%00%EC%7F%FF%DA%00%08%01%01%01%06%3F%00t%CE%9A%D64e%C1%A7ZsP%17%A9aA%3Acd%B8%2FY%3A%03g%C3t%07%CFX%E9%84%A3g%B2T%CB1nk%EB%E3%C9%80)%5D%04%BE%94%5C%08%8A%99%BDJ%E3%FB%0Cfw%889%E1%B4zO%E0%25%A2P%B0%DF%EE%D7%BF%E7%24%C3L%FD%9E%C4%CBqH%E3%A6R%F2%10J%AC%813%D8%90%E5q%22W%02%E3%82~6%B2X*%A7%19%93zt%A2f%D0%1C%A6%E6%CB%96%F7%D7%8A%D4Z%1Ez%F6%3C%AE%FC%F3gy-%8D6lt%3F%8F7%06%928%A4%E6W%26%24%22%7B%1F%81w%F6E*%A2D%A9k%E5g%FA%92%94Yb%BA%F4%1CL%0D%3A%9E%9B%A6L%1Ey%D49%F60%A9%3A%04%7D%18u%23%F6%0C*%FF%00x%15X%E4%0F%D1%FAo%23%83%FF%D9</image>
  6.     <url type="text/html" method="post" template="http://php.net/search.php">
  7.         <param name="show" value="quickref"/>
  8.         <param name="pattern" value="{searchTerms}"/>
  9.     </url>
  10.     <moz :SearchForm>http://php.net/search.php</moz>
  11. </opensearchdescription>

If you're on a Windows XP box, save the XML as php.xml and plop it in:

CODE:
  1. c:/Documents and Settings/{user}/Application Data/Mozilla/Firefox/Profiles/{something}.default/searchplugins/

If you're on a Mac, place php.xml in:

CODE:
  1. /Users/{user}/Library/Application Support/Firefox/Profiles/{something}.default/searchplugins/

JavaScript Shell

November 3, 2006 | Leave a Comment

While at The Ajax Experience I noticed a tool that a few of the speakers made use of that was missing from my arsenal. The tool? JavaScript Shell.

This little beauty, once you've added the bookmark to your browser allows you to open a JavaScript Shell for any page you happen to be on! The shell lets you enter JavaScript from command-line to manipulate the page, trigger functions, analyze properties, etc. All libraries that the site has loaded are available within the Shell...so, if you use jQuery or some other toolkit, all defined functions and plugins are usable.

Here's some features and pre-defined functions from the JavaScript Shell site

Features

  • You can enter statements and expressions at the same prompt.
  • The result of each non-void statement or expression is shown.
  • User-defined variables.
    • b = document.body
  • User-defined functions.
    • function f() { return 5; }
  • JavaScript error messages are shown in red.
  • Previous statements and expressions are available through Up and Down arrow keys.
  • Tab completion.
  • Multiline input (Shift+Enter to insert a line break).
  • If the shell is opened using a bookmarklet, JavaScript typed into the shell runs in the context of the original window.
  • Works well in Firefox, mostly works in Opera 8 and in IE 6 for Windows.

Built-in functions

  • ans: the result of the previous expression.
  • print(expr): prints expr on its own line.
    • for(i = 0; i < 6; ++i) print(i * i)
  • pr(expr): prints and returns its input, so you can use it to print intermediate results in the middle of an expression.
    • function fact(n) { return n>0 ? pr(n*fact(n-1)) : 1 }
  • blink(node) or Alt+B: makes a node blink for a second.
    • blink(document.links[3])
  • props(obj) or Alt+P: lists the methods and fields of an object.
    • props(document.body)
    • In Firefox, props also shows which properties belong to the object itself and which belong to objects in its prototype chain.

I'm a fan :D

Visual JQuery

November 1, 2006 | Leave a Comment

jquery After my excitement about jQuery since The Ajax Experience, one of my fellow developers at PSU has been checking the toolkit out. In her searches for documentation found Visual jQuery, a nice graphical/textual categorized API for the jQuery toolkit! Its a pretty snazzy learning tool if you aren't already familiar with all the functions jQuery has to offer (found in the jQuery API).

I'll be using Visual jQuery to explore to toolkit and see what it has to offer and using the JQuery API for quick syntax lookup.

Oh, and on a side note, the people over at Visual jQuery have begun a jQuery magazine in pdf format...pretty neat-o.

The Ajax Experience: jQuery Toolkit

November 1, 2006 | 8 Comments

jquery I went to The Ajax Experience with high expectations of catching some great tips regarding development in an Ajax environment. At the same time, I was sure of my previous decision with the use of Prototype and Script.aculo.us was as good as it gets (without diving into the widgetized world...e.g. Dojo). I attended John Resig's presentation on jQuery and I became a convert.

John's presentation was less of a presentation and more of a Q&A Demonstration, which suited me fine. As soon as I knew where to download the code, I popped open my laptop and started fiddling around with the toolkit - passively paying attention to the questions and answers, as they tended to be extremely basic questions...you see, jQuery is pretty darn intuitive.

jQuery's mantra is "Find stuff and do stuff to it"

Yeah, I wasn't converted because jQuery was the first toolkit to support chaining and that it executes it nicely. Nor was I converted because of its extensive plugin library. Nope. My conversion was the effecient findability of elements within the DOM! This is what really makes jQuery ballsy. The toolkit was built with findability in mind using already established standards! jQuery fully supports CSS1, CSS2, CSS3, and basic XPath when hunting for elements. For example:

Lets start with something simple:
Say I wanted to find all elements within the page that had the class: bork and hide them, I'd do:

JavaScript:
  1. $('.bork').hide();

Alright, say I wanted to find all anchor tags with the target set to _blank and add the class whee to it:

JavaScript:
  1. $('a[@target=_blank]').addClass('whee');

Now, lets say I want to find all anchor tags with the target set to _blank and add the class whee to them AND append (opens in a new window) as a sibling to the link itself.

JavaScript:
  1. $('a[@target=_blank]').each(
  2.   function(){
  3.     $(this).addClass('whee');
  4.     $(this).after('(Opens in a new window)');
  5.   }
  6. );

Now, if I knew I was going to use the above a whole lot all over hell's half acre, I could create a jQuery plugin that can be chained! Here's how I'd create that feature and allow for the passing of class name:

JavaScript:
  1. jQuery.fn.opensInNewWindow = function(classname){
  2.     return this.each(
  3.         function(){
  4.                         $(this).addClass(classname);
  5.                         $(this).after('(Opens in a new window)');
  6.         }
  7.     );
  8. };

Now, when I want to put Opens in a new window on a series of elements, I can do so with my newly created plugin:

JavaScript:
  1. $('a[@target=_blank]').opensInNewWindow('whee');
  2.  
  3. //I can do this for ANY element I want even if it isn't a link
  4. $('span.bork').opensInNewWindow('zomg');
  5. $('div#w00t ul.nav').opensInNewWindow('roflcopter');

Now, to make use of the chainability, you can write the plugin more simply than what I did up above. You can do this: (thanks to malsup, a commenter on this article)

JavaScript:
  1. jQuery.fn.opensInNewWindow = function(classname){
  2.     return this.each(
  3.         function(){
  4.       $(this).addClass(classname).after('(Opens in a new window)');
  5.         }
  6.     );
  7. };

Cake walk. As your proficiency in finding objects within a page increases, your code will become shorter.

jQuery currently has a very active community and mailing list (averaging at about 90 posts per day) so if you have questions regarding the toolkit, you can become a member and ask away... In addition, there's a jQuery blog where John posts comparison code showing the difference between jQuery and other available toolkits. (here's a Zebra striping example)

If you are still on the hunt for a JavaScript toolkit for Ajax, DOM manipulation, etc or you find your toolkit of choice too clunky, give jQuery a shot. You'll be pleased with the results.