Fix calculation of spritesheet hashes to use relative paths

Summary:
When a user generates sprites, we hash all the inputs to figure out what we actually need to regenerate. Normally (i.e., on my machine), this works fine.

However, part of the hash is the absolute path of all the input images, so my machine hashes in `/Users/epriestley/phabricator/path/to/sprite.png`, and then @chad regens them and gets a hash of `/Users/notchad/phabricator/path/to/sprite.png` instead, or whatever. The hash comes out different so every manifest and sheet gets regenerated.

Instead, hash the //relative// path -- e.g., `path/to/sprite.png`. This keeps the path the same across machines and means that only sprites which have actually changed will regenerate.

See also next diff.

Test Plan:
  - Before this patch: generated sprites in `phabricator/`, then moved `phabricator/` to `phabricator2/` and regenerated. Incorrectly, all sprites were regenerated.  - After this patch: generated sprites in `phabricator/`, then moved `phabricator/` to `phabricator2/` and regenerated. Nothing was regenerated.

Reviewers: chad, btrahan

Reviewed By: chad

CC: aran

Differential Revision: https://secure.phabricator.com/D5964
Add Filesystem::binaryExists()

Summary:
We use `which x` in various places; provide a wrapper which we might some day make work on Windows.

The motivation for this is twofold:

  - I want to commandeer D5670, which will involve another `which`. `which` is yuck.
  - Users hit issues with `svn`, `git`, etc., fairly often. It would be good to do a check after hitting an error in PhabricatorRepository so we can raise a very specific error message about "you do not have git in your webserver path, here is how to fix that".

Test Plan: Ummm... will use in next diff?

Reviewers: btrahan, vrana

Reviewed By: vrana

CC: aran

Differential Revision: https://secure.phabricator.com/D5968
Improve behavior of named anchor links

Summary: Fixes T3220. We currently don't handle `[[ #anchor ]]` very well in remarkup.

Test Plan:
Unit tests.

{F43706}

Reviewers: btrahan, chad

Reviewed By: chad

CC: aran

Maniphest Tasks: T3220

Differential Revision: https://secure.phabricator.com/D5974
Implemented phutil_utf8_is_combining_character().

Summary: Implemented phutil_utf8_is_combining_character(), which returns true if an input character is a combining character.

Test Plan: Unit test: testUTF8IsCombiningCharacter().

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin, AnhNhan

Maniphest Tasks: T2379

Differential Revision: https://secure.phabricator.com/D5981
Implemented phutil_utf8_combined().

Summary: A function which splits a given UTF-8 string into an array of characters without splitting the combined characters.

Test Plan: Unit tests.

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin, AnhNhan

Maniphest Tasks: T2379

Differential Revision: https://secure.phabricator.com/D6011
Provide the ability to set an alter-operation cost to PhutilEditDistanceMatrix

Summary:
In Arcanist, we currently price altering the edit operation so that strings like `(x)` vs `((x))` get analyzed as `isssi` instead of `issis` (that is, the first and last parens are highlighted as "new", rather than the first open and first close paren) which is better for human viewers.

Support this in PhutilEditDistanceMatrix.

Test Plan: Provided an alter cost in `arc` and ran the tests. They pass after this change.

Reviewers: btrahan, Afaque_Hussain

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T2379

Differential Revision: https://secure.phabricator.com/D6013
Provide onboard optimizations for strings with similar prefixes and suffixes in PhutilEditDistanceMatrix

Summary: We can evaluate similar prefixes and suffixes in O(1). Provide this optimization within PhutilEditDistanceMatrix.

Test Plan: Ran unit tests.

Reviewers: btrahan, Afaque_Hussain

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T2379

Differential Revision: https://secure.phabricator.com/D6014
Provide maximum comparison length onboard PhutilEditDistanceMatrix

Summary: After some maximum length, we bail out rather than compute the acutal edit distance because the time and memory complexity grows nonlinearly. Bring this check onboard PhutilEditDistanceMatrix.

Test Plan: Added and ran unit tests.

Reviewers: btrahan, Afaque_Hussain, ivane2004

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T2379

Differential Revision: https://secure.phabricator.com/D6015
Fixing phutil_utf8_shorten().

Summary: Fixed phutil_utf8_shorten() to be combining character aware.

Test Plan: Unit tests. However, I think I may have not added enough test cases.

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin, AnhNhan

Maniphest Tasks: T2379

Differential Revision: https://secure.phabricator.com/D6025