Page MenuHomestyx hydra

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/resources/sql/patches/releeph.sql b/resources/sql/patches/releeph.sql
new file mode 100644
index 0000000000..a824357958
--- /dev/null
+++ b/resources/sql/patches/releeph.sql
@@ -0,0 +1,92 @@
+CREATE TABLE {$NAMESPACE}_releeph.`releeph_project` (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `dateCreated` int(10) unsigned NOT NULL,
+ `dateModified` int(10) unsigned NOT NULL,
+ `phid` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `name` varchar(255) NOT NULL,
+ `trunkBranch` varchar(255) NOT NULL,
+ `repositoryID` int(10) unsigned NOT NULL,
+ `repositoryPHID` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `arcanistProjectID` int(10) unsigned NOT NULL,
+ `createdByUserPHID` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `isActive` tinyint(1) NOT NULL DEFAULT '1',
+ `projectID` int(10) unsigned DEFAULT NULL,
+ `details` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `projectName` (`name`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE {$NAMESPACE}_releeph.`releeph_branch` (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `dateCreated` int(10) unsigned NOT NULL,
+ `dateModified` int(10) unsigned NOT NULL,
+ `basename` varchar(64) NOT NULL,
+ `releephProjectID` int(10) unsigned NOT NULL,
+ `createdByUserPHID` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `cutPointCommitIdentifier`
+ varchar(40) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `cutPointCommitPHID`
+ varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `isActive` tinyint(1) NOT NULL DEFAULT '1',
+ `symbolicName` varchar(64) DEFAULT NULL,
+ `details` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `phid` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `name` varchar(128) NOT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `releephProjectID_2` (`releephProjectID`,`basename`),
+ UNIQUE KEY `releephProjectID_name` (`releephProjectID`,`name`),
+ UNIQUE KEY `releephProjectID` (`releephProjectID`,`symbolicName`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE {$NAMESPACE}_releeph.`releeph_request` (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `dateCreated` int(10) unsigned NOT NULL,
+ `dateModified` int(10) unsigned NOT NULL,
+ `phid` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `branchID` int(10) unsigned NOT NULL,
+ `summary` longtext CHARACTER SET utf8 COLLATE utf8_bin,
+ `requestUserPHID` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `requestCommitIdentifier`
+ varchar(40) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `requestCommitPHID`
+ varchar(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
+ `requestCommitOrdinal` int(10) unsigned NOT NULL,
+ `commitIdentifier`
+ varchar(40) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
+ `committedByUserPHID`
+ varchar(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
+ `commitPHID` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
+ `status` tinyint(4) DEFAULT NULL,
+ `pickStatus` tinyint(4) DEFAULT NULL,
+ `details` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `userIntents` longtext CHARACTER SET utf8 COLLATE utf8_bin,
+ `inBranch` tinyint(1) NOT NULL DEFAULT '0',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `phid` (`phid`),
+ UNIQUE KEY `requestIdentifierBranch` (`requestCommitIdentifier`,`branchID`),
+ KEY `branchID` (`branchID`,`requestCommitOrdinal`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE {$NAMESPACE}_releeph.`releeph_requestevent` (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `dateCreated` int(10) unsigned NOT NULL,
+ `dateModified` int(10) unsigned NOT NULL,
+ `releephRequestID` int(10) unsigned NOT NULL,
+ `actorPHID` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
+ `details` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ `type` varchar(32) NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE {$NAMESPACE}_releeph.`releeph_event` (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `dateCreated` int(10) unsigned NOT NULL,
+ `dateModified` int(10) unsigned NOT NULL,
+ `releephProjectID` int(10) unsigned NOT NULL,
+ `releephBranchID` int(10) unsigned DEFAULT NULL,
+ `type` varchar(32) NOT NULL,
+ `epoch` int(10) unsigned DEFAULT NULL,
+ `actorPHID` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
+ `details` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php
index 3f64a695a7..43b2d86a46 100644
--- a/src/__celerity_resource_map__.php
+++ b/src/__celerity_resource_map__.php
@@ -1,3937 +1,4066 @@
<?php
/**
* This file is automatically generated. Use 'celerity_mapper.php' to rebuild
* it.
* @generated
*/
celerity_register_resource_map(array(
'/rsrc/image/actions/edit.png' =>
array(
'hash' => 'ae90914d120ac3838ddc633b480343f3',
'uri' => '/res/ae90914d/rsrc/image/actions/edit.png',
'disk' => '/rsrc/image/actions/edit.png',
'type' => 'png',
),
'/rsrc/image/avatar.png' =>
array(
'hash' => '1c5f255071537f05406adee86717ff27',
'uri' => '/res/1c5f2550/rsrc/image/avatar.png',
'disk' => '/rsrc/image/avatar.png',
'type' => 'png',
),
'/rsrc/image/checker_dark.png' =>
array(
'hash' => '640f795343df76ebe5409aae6187e57f',
'uri' => '/res/640f7953/rsrc/image/checker_dark.png',
'disk' => '/rsrc/image/checker_dark.png',
'type' => 'png',
),
'/rsrc/image/checker_light.png' =>
array(
'hash' => '7f8f3ef8beb0f2cc4cc69efb9e1c3308',
'uri' => '/res/7f8f3ef8/rsrc/image/checker_light.png',
'disk' => '/rsrc/image/checker_light.png',
'type' => 'png',
),
'/rsrc/image/credit_cards.png' =>
array(
'hash' => '681448de424ea159b6ea68af04c046ae',
'uri' => '/res/681448de/rsrc/image/credit_cards.png',
'disk' => '/rsrc/image/credit_cards.png',
'type' => 'png',
),
'/rsrc/image/darkload.gif' =>
array(
'hash' => '3a52cb7145d6e70f461fed21273117f2',
'uri' => '/res/3a52cb71/rsrc/image/darkload.gif',
'disk' => '/rsrc/image/darkload.gif',
'type' => 'gif',
),
'/rsrc/image/divot.png' =>
array(
'hash' => '3be267bd11ea375bf68e808893718e0e',
'uri' => '/res/3be267bd/rsrc/image/divot.png',
'disk' => '/rsrc/image/divot.png',
'type' => 'png',
),
'/rsrc/image/grippy_texture.png' =>
array(
'hash' => 'a8945e12ceeaddd5b491a8d81cfa19c1',
'uri' => '/res/a8945e12/rsrc/image/grippy_texture.png',
'disk' => '/rsrc/image/grippy_texture.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/arrow_branch.png' =>
array(
'hash' => 'f27b67520766e3d971722bcff703f3a8',
'uri' => '/res/f27b6752/rsrc/image/icon/fatcow/arrow_branch.png',
'disk' => '/rsrc/image/icon/fatcow/arrow_branch.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/arrow_merge.png' =>
array(
'hash' => 'c4bd97f3b1257439e2123ef69d2194d0',
'uri' => '/res/c4bd97f3/rsrc/image/icon/fatcow/arrow_merge.png',
'disk' => '/rsrc/image/icon/fatcow/arrow_merge.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/bullet_black.png' =>
array(
'hash' => '718f9c560a13766796f1be7dfaadeeab',
'uri' => '/res/718f9c56/rsrc/image/icon/fatcow/bullet_black.png',
'disk' => '/rsrc/image/icon/fatcow/bullet_black.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/bullet_orange.png' =>
array(
'hash' => 'c3bf91b65baacb27f2af143ab9180119',
'uri' => '/res/c3bf91b6/rsrc/image/icon/fatcow/bullet_orange.png',
'disk' => '/rsrc/image/icon/fatcow/bullet_orange.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/bullet_red.png' =>
array(
'hash' => '00273e4aa6ea3de630295610d6c9560c',
'uri' => '/res/00273e4a/rsrc/image/icon/fatcow/bullet_red.png',
'disk' => '/rsrc/image/icon/fatcow/bullet_red.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/calendar_edit.png' =>
array(
'hash' => 'de249c0f4f37bf5b2c69ff39ec5573fb',
'uri' => '/res/de249c0f/rsrc/image/icon/fatcow/calendar_edit.png',
'disk' => '/rsrc/image/icon/fatcow/calendar_edit.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/document_black.png' =>
array(
'hash' => '44d65a7f05a9c921719deedc160d68f7',
'uri' => '/res/44d65a7f/rsrc/image/icon/fatcow/document_black.png',
'disk' => '/rsrc/image/icon/fatcow/document_black.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/flag_blue.png' =>
array(
'hash' => '75a080492f900fbe489e4b27e403962b',
'uri' => '/res/75a08049/rsrc/image/icon/fatcow/flag_blue.png',
'disk' => '/rsrc/image/icon/fatcow/flag_blue.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/flag_finish.png' =>
array(
'hash' => '4af11fc7fab8e4610cbc3c88a02d4f78',
'uri' => '/res/4af11fc7/rsrc/image/icon/fatcow/flag_finish.png',
'disk' => '/rsrc/image/icon/fatcow/flag_finish.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/flag_ghost.png' =>
array(
'hash' => '14c9f30a37b43f276f27a27a924bf02d',
'uri' => '/res/14c9f30a/rsrc/image/icon/fatcow/flag_ghost.png',
'disk' => '/rsrc/image/icon/fatcow/flag_ghost.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/flag_green.png' =>
array(
'hash' => 'fed01374cd396cb774872762dcc447e1',
'uri' => '/res/fed01374/rsrc/image/icon/fatcow/flag_green.png',
'disk' => '/rsrc/image/icon/fatcow/flag_green.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/flag_orange.png' =>
array(
'hash' => '88008cb8bb99761a37e5a743e2455aeb',
'uri' => '/res/88008cb8/rsrc/image/icon/fatcow/flag_orange.png',
'disk' => '/rsrc/image/icon/fatcow/flag_orange.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/flag_pink.png' =>
array(
'hash' => '2f199f06ffc3dfc81b7561a057e0bc33',
'uri' => '/res/2f199f06/rsrc/image/icon/fatcow/flag_pink.png',
'disk' => '/rsrc/image/icon/fatcow/flag_pink.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/flag_purple.png' =>
array(
'hash' => '16358629dc86c39550b575586eb5df80',
'uri' => '/res/16358629/rsrc/image/icon/fatcow/flag_purple.png',
'disk' => '/rsrc/image/icon/fatcow/flag_purple.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/flag_red.png' =>
array(
'hash' => '210c28b4d93c439a499f5814f5e05772',
'uri' => '/res/210c28b4/rsrc/image/icon/fatcow/flag_red.png',
'disk' => '/rsrc/image/icon/fatcow/flag_red.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/flag_yellow.png' =>
array(
'hash' => 'bdfd73744a80bb80329ae50bc8a5f962',
'uri' => '/res/bdfd7374/rsrc/image/icon/fatcow/flag_yellow.png',
'disk' => '/rsrc/image/icon/fatcow/flag_yellow.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/folder.png' =>
array(
'hash' => '25e46cf9d210dde2242332296f79938c',
'uri' => '/res/25e46cf9/rsrc/image/icon/fatcow/folder.png',
'disk' => '/rsrc/image/icon/fatcow/folder.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/folder_go.png' =>
array(
'hash' => 'ba922ff7959309f51a14cb7ed5124d8b',
'uri' => '/res/ba922ff7/rsrc/image/icon/fatcow/folder_go.png',
'disk' => '/rsrc/image/icon/fatcow/folder_go.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/key_question.png' =>
array(
'hash' => '530a6448a4b91edec091a9292ccfd3d9',
'uri' => '/res/530a6448/rsrc/image/icon/fatcow/key_question.png',
'disk' => '/rsrc/image/icon/fatcow/key_question.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/link.png' =>
array(
'hash' => 'be1bea49b216548433014f3324902928',
'uri' => '/res/be1bea49/rsrc/image/icon/fatcow/link.png',
'disk' => '/rsrc/image/icon/fatcow/link.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/page_white_edit.png' =>
array(
'hash' => 'e7b7e7f2d9730bc80bc5c9eac1f3e36d',
'uri' => '/res/e7b7e7f2/rsrc/image/icon/fatcow/page_white_edit.png',
'disk' => '/rsrc/image/icon/fatcow/page_white_edit.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/page_white_link.png' =>
array(
'hash' => '1cfbad14412bda6c6f132dcc7c8725fd',
'uri' => '/res/1cfbad14/rsrc/image/icon/fatcow/page_white_link.png',
'disk' => '/rsrc/image/icon/fatcow/page_white_link.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/page_white_put.png' =>
array(
'hash' => 'bb7308aa5ac40137a8262da395a267fd',
'uri' => '/res/bb7308aa/rsrc/image/icon/fatcow/page_white_put.png',
'disk' => '/rsrc/image/icon/fatcow/page_white_put.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/page_white_text.png' =>
array(
'hash' => 'e47d590b626f617fb7d1d44e96e8fd11',
'uri' => '/res/e47d590b/rsrc/image/icon/fatcow/page_white_text.png',
'disk' => '/rsrc/image/icon/fatcow/page_white_text.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/source/conduit.png' =>
array(
'hash' => '1cae0656580aa3cd0b54b9d98306b1b9',
'uri' => '/res/1cae0656/rsrc/image/icon/fatcow/source/conduit.png',
'disk' => '/rsrc/image/icon/fatcow/source/conduit.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/source/email.png' =>
array(
'hash' => '93bdb3e168da1ed68f50c42125729d4e',
'uri' => '/res/93bdb3e1/rsrc/image/icon/fatcow/source/email.png',
'disk' => '/rsrc/image/icon/fatcow/source/email.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/source/fax.png' =>
array(
'hash' => 'd7dedf229841f2d041b347afd881596f',
'uri' => '/res/d7dedf22/rsrc/image/icon/fatcow/source/fax.png',
'disk' => '/rsrc/image/icon/fatcow/source/fax.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/source/mobile.png' =>
array(
'hash' => '786e7146d1e7d7318baf76c9d2baad97',
'uri' => '/res/786e7146/rsrc/image/icon/fatcow/source/mobile.png',
'disk' => '/rsrc/image/icon/fatcow/source/mobile.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/source/tablet.png' =>
array(
'hash' => '374cd40e4965be6b2fbdef4059d0ca05',
'uri' => '/res/374cd40e/rsrc/image/icon/fatcow/source/tablet.png',
'disk' => '/rsrc/image/icon/fatcow/source/tablet.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/source/web.png' =>
array(
'hash' => 'f4882a8f5619ba505ca033f72a340635',
'uri' => '/res/f4882a8f/rsrc/image/icon/fatcow/source/web.png',
'disk' => '/rsrc/image/icon/fatcow/source/web.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/thumbnails/default160x120.png' =>
array(
'hash' => '1b52ebd1fe0eee3ed0abfc382991b265',
'uri' => '/res/1b52ebd1/rsrc/image/icon/fatcow/thumbnails/default160x120.png',
'disk' => '/rsrc/image/icon/fatcow/thumbnails/default160x120.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/thumbnails/default60x45.png' =>
array(
'hash' => '048d851d8d1daad4754e891e734c1899',
'uri' => '/res/048d851d/rsrc/image/icon/fatcow/thumbnails/default60x45.png',
'disk' => '/rsrc/image/icon/fatcow/thumbnails/default60x45.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/thumbnails/image160x120.png' =>
array(
'hash' => '434acbd8dbbc2da9f09f6205a396eba1',
'uri' => '/res/434acbd8/rsrc/image/icon/fatcow/thumbnails/image160x120.png',
'disk' => '/rsrc/image/icon/fatcow/thumbnails/image160x120.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/thumbnails/image60x45.png' =>
array(
'hash' => '29f7872dc53588fe0b8f0b330c7ee23a',
'uri' => '/res/29f7872d/rsrc/image/icon/fatcow/thumbnails/image60x45.png',
'disk' => '/rsrc/image/icon/fatcow/thumbnails/image60x45.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/thumbnails/pdf160x120.png' =>
array(
'hash' => '39d2e22541658a3472ba41ae2fa548e5',
'uri' => '/res/39d2e225/rsrc/image/icon/fatcow/thumbnails/pdf160x120.png',
'disk' => '/rsrc/image/icon/fatcow/thumbnails/pdf160x120.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/thumbnails/pdf60x45.png' =>
array(
'hash' => 'b3572e9317cbed5184d12bdfabed2727',
'uri' => '/res/b3572e93/rsrc/image/icon/fatcow/thumbnails/pdf60x45.png',
'disk' => '/rsrc/image/icon/fatcow/thumbnails/pdf60x45.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/thumbnails/zip160x120.png' =>
array(
'hash' => 'e505108688a903b5cfb674707a289bcc',
'uri' => '/res/e5051086/rsrc/image/icon/fatcow/thumbnails/zip160x120.png',
'disk' => '/rsrc/image/icon/fatcow/thumbnails/zip160x120.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/thumbnails/zip60x45.png' =>
array(
'hash' => 'f00716f4e8f7a95e70d43504f06be0a6',
'uri' => '/res/f00716f4/rsrc/image/icon/fatcow/thumbnails/zip60x45.png',
'disk' => '/rsrc/image/icon/fatcow/thumbnails/zip60x45.png',
'type' => 'png',
),
'/rsrc/image/icon/lightbox/close-2.png' =>
array(
'hash' => '72ff3ddcc1ed5d19a715ed6242114b53',
'uri' => '/res/72ff3ddc/rsrc/image/icon/lightbox/close-2.png',
'disk' => '/rsrc/image/icon/lightbox/close-2.png',
'type' => 'png',
),
'/rsrc/image/icon/lightbox/close-hover-2.png' =>
array(
'hash' => '6ad4bd4a7820547a1d9041752546ba16',
'uri' => '/res/6ad4bd4a/rsrc/image/icon/lightbox/close-hover-2.png',
'disk' => '/rsrc/image/icon/lightbox/close-hover-2.png',
'type' => 'png',
),
'/rsrc/image/icon/lightbox/left-arrow-2.png' =>
array(
'hash' => 'd84cbb0d42739f87b8f25b2f1d2f1153',
'uri' => '/res/d84cbb0d/rsrc/image/icon/lightbox/left-arrow-2.png',
'disk' => '/rsrc/image/icon/lightbox/left-arrow-2.png',
'type' => 'png',
),
'/rsrc/image/icon/lightbox/left-arrow-hover-2.png' =>
array(
'hash' => 'cdf05f98fff3f390cd8df0c89894a3e1',
'uri' => '/res/cdf05f98/rsrc/image/icon/lightbox/left-arrow-hover-2.png',
'disk' => '/rsrc/image/icon/lightbox/left-arrow-hover-2.png',
'type' => 'png',
),
'/rsrc/image/icon/lightbox/right-arrow-2.png' =>
array(
'hash' => '52021038cb6995c71f62a804bc2d420d',
'uri' => '/res/52021038/rsrc/image/icon/lightbox/right-arrow-2.png',
'disk' => '/rsrc/image/icon/lightbox/right-arrow-2.png',
'type' => 'png',
),
'/rsrc/image/icon/lightbox/right-arrow-hover-2.png' =>
array(
'hash' => '65d5756b7b9cfcdeb2eb197a9aa6bbd2',
'uri' => '/res/65d5756b/rsrc/image/icon/lightbox/right-arrow-hover-2.png',
'disk' => '/rsrc/image/icon/lightbox/right-arrow-hover-2.png',
'type' => 'png',
),
'/rsrc/image/icon/subscribe.png' =>
array(
'hash' => '5f47a4b17de245af39a4e7a097e40623',
'uri' => '/res/5f47a4b1/rsrc/image/icon/subscribe.png',
'disk' => '/rsrc/image/icon/subscribe.png',
'type' => 'png',
),
'/rsrc/image/icon/tango/attachment.png' =>
array(
'hash' => '776fed2de89803fd8a0ba4b9deede230',
'uri' => '/res/776fed2d/rsrc/image/icon/tango/attachment.png',
'disk' => '/rsrc/image/icon/tango/attachment.png',
'type' => 'png',
),
'/rsrc/image/icon/tango/edit.png' =>
array(
'hash' => 'c0028d99dcf4e9559bbf3c88ce2d8a8d',
'uri' => '/res/c0028d99/rsrc/image/icon/tango/edit.png',
'disk' => '/rsrc/image/icon/tango/edit.png',
'type' => 'png',
),
'/rsrc/image/icon/tango/go-down.png' =>
array(
'hash' => '96862812cbb0445573c264dc057b8300',
'uri' => '/res/96862812/rsrc/image/icon/tango/go-down.png',
'disk' => '/rsrc/image/icon/tango/go-down.png',
'type' => 'png',
),
'/rsrc/image/icon/tango/log.png' =>
array(
'hash' => 'a6f72499bef279ff6807a7dbc5148f1e',
'uri' => '/res/a6f72499/rsrc/image/icon/tango/log.png',
'disk' => '/rsrc/image/icon/tango/log.png',
'type' => 'png',
),
'/rsrc/image/icon/tango/upload.png' =>
array(
'hash' => '8c11b63d6d99db3d7159c5d9a94e3062',
'uri' => '/res/8c11b63d/rsrc/image/icon/tango/upload.png',
'disk' => '/rsrc/image/icon/tango/upload.png',
'type' => 'png',
),
'/rsrc/image/icon/unsubscribe.png' =>
array(
'hash' => '29429ad65aa3af50b072b32087057361',
'uri' => '/res/29429ad6/rsrc/image/icon/unsubscribe.png',
'disk' => '/rsrc/image/icon/unsubscribe.png',
'type' => 'png',
),
'/rsrc/image/loading.gif' =>
array(
'hash' => '664297671941142f37d8c89e717ff2ce',
'uri' => '/res/66429767/rsrc/image/loading.gif',
'disk' => '/rsrc/image/loading.gif',
'type' => 'gif',
),
'/rsrc/image/main_texture.png' =>
array(
'hash' => 'e34d8143384721be73ec9b7532a977ab',
'uri' => '/res/e34d8143/rsrc/image/main_texture.png',
'disk' => '/rsrc/image/main_texture.png',
'type' => 'png',
),
'/rsrc/image/menu_texture.png' =>
array(
'hash' => 'ad020b1529b3a3b3480ca9de1d5f1e40',
'uri' => '/res/ad020b15/rsrc/image/menu_texture.png',
'disk' => '/rsrc/image/menu_texture.png',
'type' => 'png',
),
'/rsrc/image/search.png' =>
array(
'hash' => 'ff7da044e6f923b8f569dec11f97e5e5',
'uri' => '/res/ff7da044/rsrc/image/search.png',
'disk' => '/rsrc/image/search.png',
'type' => 'png',
),
'/rsrc/image/sprite-apps-X2.png' =>
array(
'hash' => '361e64ded74eee1094127c7878c2c385',
'uri' => '/res/361e64de/rsrc/image/sprite-apps-X2.png',
'disk' => '/rsrc/image/sprite-apps-X2.png',
'type' => 'png',
),
'/rsrc/image/sprite-apps-large-X2.png' =>
array(
'hash' => '73507e04b4bd4d1e8e7544f7c424fc0f',
'uri' => '/res/73507e04/rsrc/image/sprite-apps-large-X2.png',
'disk' => '/rsrc/image/sprite-apps-large-X2.png',
'type' => 'png',
),
'/rsrc/image/sprite-apps-large.png' =>
array(
'hash' => '6a5aade6134954171f2f1f8507270632',
'uri' => '/res/6a5aade6/rsrc/image/sprite-apps-large.png',
'disk' => '/rsrc/image/sprite-apps-large.png',
'type' => 'png',
),
'/rsrc/image/sprite-apps-xlarge.png' =>
array(
'hash' => '992d2c278b6a22c0fa874d457a252fbd',
'uri' => '/res/992d2c27/rsrc/image/sprite-apps-xlarge.png',
'disk' => '/rsrc/image/sprite-apps-xlarge.png',
'type' => 'png',
),
'/rsrc/image/sprite-apps.png' =>
array(
'hash' => '5e76c53e9f61755e5d3e7befa9d73ae5',
'uri' => '/res/5e76c53e/rsrc/image/sprite-apps.png',
'disk' => '/rsrc/image/sprite-apps.png',
'type' => 'png',
),
'/rsrc/image/sprite-conpherence-X2.png' =>
array(
'hash' => '5e47868b00933a9afb6c844e464e6b23',
'uri' => '/res/5e47868b/rsrc/image/sprite-conpherence-X2.png',
'disk' => '/rsrc/image/sprite-conpherence-X2.png',
'type' => 'png',
),
'/rsrc/image/sprite-conpherence.png' =>
array(
'hash' => 'ca51f1be25213262d68e626e4cab7f0f',
'uri' => '/res/ca51f1be/rsrc/image/sprite-conpherence.png',
'disk' => '/rsrc/image/sprite-conpherence.png',
'type' => 'png',
),
'/rsrc/image/sprite-docs-X2.png' =>
array(
'hash' => '57d3286ce88133f3ec9240e35f6bb897',
'uri' => '/res/57d3286c/rsrc/image/sprite-docs-X2.png',
'disk' => '/rsrc/image/sprite-docs-X2.png',
'type' => 'png',
),
'/rsrc/image/sprite-docs.png' =>
array(
'hash' => 'b2b089072d6eddd831402a77c02b5736',
'uri' => '/res/b2b08907/rsrc/image/sprite-docs.png',
'disk' => '/rsrc/image/sprite-docs.png',
'type' => 'png',
),
'/rsrc/image/sprite-gradient.png' =>
array(
'hash' => '92aebaab67dcc6baf2ea99294368d895',
'uri' => '/res/92aebaab/rsrc/image/sprite-gradient.png',
'disk' => '/rsrc/image/sprite-gradient.png',
'type' => 'png',
),
'/rsrc/image/sprite-icon-X2.png' =>
array(
'hash' => 'c9fae25bc6221922ce26517e654a18e4',
'uri' => '/res/c9fae25b/rsrc/image/sprite-icon-X2.png',
'disk' => '/rsrc/image/sprite-icon-X2.png',
'type' => 'png',
),
'/rsrc/image/sprite-icon.png' =>
array(
'hash' => 'b690ea69bf5f2abe84d0a6e9ef64b03d',
'uri' => '/res/b690ea69/rsrc/image/sprite-icon.png',
'disk' => '/rsrc/image/sprite-icon.png',
'type' => 'png',
),
'/rsrc/image/sprite-menu-X2.png' =>
array(
'hash' => '9f5cae08146fbe3b7e865b60c64121d1',
'uri' => '/res/9f5cae08/rsrc/image/sprite-menu-X2.png',
'disk' => '/rsrc/image/sprite-menu-X2.png',
'type' => 'png',
),
'/rsrc/image/sprite-menu.png' =>
array(
'hash' => 'cc82b64d031dafa2b2a62cc8effa62f6',
'uri' => '/res/cc82b64d/rsrc/image/sprite-menu.png',
'disk' => '/rsrc/image/sprite-menu.png',
'type' => 'png',
),
'/rsrc/image/sprite-tokens.png' =>
array(
'hash' => '67c46fd75c885b76ecbfe46e71a476cc',
'uri' => '/res/67c46fd7/rsrc/image/sprite-tokens.png',
'disk' => '/rsrc/image/sprite-tokens.png',
'type' => 'png',
),
'/rsrc/image/texture/dark-menu-hover.png' =>
array(
'hash' => 'a214a732644be34872e895b338b5d639',
'uri' => '/res/a214a732/rsrc/image/texture/dark-menu-hover.png',
'disk' => '/rsrc/image/texture/dark-menu-hover.png',
'type' => 'png',
),
'/rsrc/image/texture/dark-menu.png' =>
array(
'hash' => '41ee673a762cec48a154b456ad5ac204',
'uri' => '/res/41ee673a/rsrc/image/texture/dark-menu.png',
'disk' => '/rsrc/image/texture/dark-menu.png',
'type' => 'png',
),
'/rsrc/image/texture/dust_background.jpg' =>
array(
'hash' => '1ff330c03712e08ca2eed006ccc6c1e7',
'uri' => '/res/1ff330c0/rsrc/image/texture/dust_background.jpg',
'disk' => '/rsrc/image/texture/dust_background.jpg',
'type' => 'jpg',
),
'/rsrc/image/texture/pholio-background.gif' =>
array(
'hash' => 'cf4561af116edf393dc583e5119fb412',
'uri' => '/res/cf4561af/rsrc/image/texture/pholio-background.gif',
'disk' => '/rsrc/image/texture/pholio-background.gif',
'type' => 'gif',
),
'/rsrc/image/texture/table_header.png' =>
array(
'hash' => '4ed3f56a30d3749e8f62052b9735a316',
'uri' => '/res/4ed3f56a/rsrc/image/texture/table_header.png',
'disk' => '/rsrc/image/texture/table_header.png',
'type' => 'png',
),
'/rsrc/image/texture/table_header_hover.png' =>
array(
'hash' => 'ea1f71a604e9b4859de1e25751540437',
'uri' => '/res/ea1f71a6/rsrc/image/texture/table_header_hover.png',
'disk' => '/rsrc/image/texture/table_header_hover.png',
'type' => 'png',
),
'/rsrc/image/texture/table_header_tall.png' =>
array(
'hash' => 'b05525601f78d759f1c5e47fd9c1a8aa',
'uri' => '/res/b0552560/rsrc/image/texture/table_header_tall.png',
'disk' => '/rsrc/image/texture/table_header_tall.png',
'type' => 'png',
),
'/rsrc/swf/aphlict.swf' =>
array(
'hash' => '4b9a9d83bebaf254f3790e87b45c1f92',
'uri' => '/res/4b9a9d83/rsrc/swf/aphlict.swf',
'disk' => '/rsrc/swf/aphlict.swf',
'type' => 'swf',
),
'aphront-attached-file-view-css' =>
array(
'uri' => '/res/a6ca5487/rsrc/css/aphront/attached-file-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/attached-file-view.css',
),
'aphront-bars' =>
array(
'uri' => '/res/d7bd9032/rsrc/css/core/aphront-bars.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/core/aphront-bars.css',
),
'aphront-calendar-view-css' =>
array(
'uri' => '/res/73061a31/rsrc/css/aphront/calendar-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/calendar-view.css',
),
'aphront-contextbar-view-css' =>
array(
'uri' => '/res/ecfd5ba9/rsrc/css/aphront/context-bar.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/context-bar.css',
),
'aphront-dark-console-css' =>
array(
'uri' => '/res/0d316573/rsrc/css/aphront/dark-console.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/dark-console.css',
),
'aphront-dialog-view-css' =>
array(
'uri' => '/res/215b3ab1/rsrc/css/aphront/dialog-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/dialog-view.css',
),
'aphront-error-view-css' =>
array(
'uri' => '/res/5f43a7c5/rsrc/css/aphront/error-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/error-view.css',
),
'aphront-form-view-css' =>
array(
'uri' => '/res/ed8c70fa/rsrc/css/aphront/form-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/form-view.css',
),
'aphront-list-filter-view-css' =>
array(
'uri' => '/res/cc6e940e/rsrc/css/aphront/list-filter-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/list-filter-view.css',
),
'aphront-notes' =>
array(
'uri' => '/res/f8f3dcfa/rsrc/css/core/aphront-notes.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/core/aphront-notes.css',
),
'aphront-pager-view-css' =>
array(
'uri' => '/res/43fb79f0/rsrc/css/aphront/pager-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/pager-view.css',
),
'aphront-panel-view-css' =>
array(
'uri' => '/res/3d1420b3/rsrc/css/aphront/panel-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/panel-view.css',
),
'aphront-request-failure-view-css' =>
array(
'uri' => '/res/c9a43002/rsrc/css/aphront/request-failure-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/request-failure-view.css',
),
'aphront-table-view-css' =>
array(
'uri' => '/res/fd33a0f0/rsrc/css/aphront/table-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/table-view.css',
),
'aphront-tokenizer-control-css' =>
array(
'uri' => '/res/207105f0/rsrc/css/aphront/tokenizer.css',
'type' => 'css',
'requires' =>
array(
0 => 'aphront-typeahead-control-css',
),
'disk' => '/rsrc/css/aphront/tokenizer.css',
),
'aphront-tooltip-css' =>
array(
'uri' => '/res/3a7d8e07/rsrc/css/aphront/tooltip.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/tooltip.css',
),
'aphront-two-column-view-css' =>
array(
'uri' => '/res/7afa129f/rsrc/css/aphront/two-column.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/two-column.css',
),
'aphront-typeahead-control-css' =>
array(
'uri' => '/res/ef59c20c/rsrc/css/aphront/typeahead.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/typeahead.css',
),
'config-options-css' =>
array(
'uri' => '/res/e6c21f2f/rsrc/css/application/config/config-options.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/config/config-options.css',
),
'conpherence-header-pane-css' =>
array(
'uri' => '/res/11c32adc/rsrc/css/application/conpherence/header-pane.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/conpherence/header-pane.css',
),
'conpherence-menu-css' =>
array(
'uri' => '/res/0dc6b412/rsrc/css/application/conpherence/menu.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/conpherence/menu.css',
),
'conpherence-message-pane-css' =>
array(
'uri' => '/res/3aa15b9e/rsrc/css/application/conpherence/message-pane.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/conpherence/message-pane.css',
),
'conpherence-update-css' =>
array(
'uri' => '/res/92094ed7/rsrc/css/application/conpherence/update.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/conpherence/update.css',
),
'conpherence-widget-pane-css' =>
array(
'uri' => '/res/f728d1fc/rsrc/css/application/conpherence/widget-pane.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/conpherence/widget-pane.css',
),
'differential-changeset-view-css' =>
array(
'uri' => '/res/ea694162/rsrc/css/application/differential/changeset-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/differential/changeset-view.css',
),
'differential-core-view-css' =>
array(
'uri' => '/res/85fe5117/rsrc/css/application/differential/core.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/differential/core.css',
),
'differential-inline-comment-editor' =>
array(
'uri' => '/res/e0ad34ac/rsrc/js/application/differential/DifferentialInlineCommentEditor.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-dom',
1 => 'javelin-util',
2 => 'javelin-stratcom',
3 => 'javelin-install',
4 => 'javelin-request',
5 => 'javelin-workflow',
),
'disk' => '/rsrc/js/application/differential/DifferentialInlineCommentEditor.js',
),
'differential-local-commits-view-css' =>
array(
'uri' => '/res/224f3703/rsrc/css/application/differential/local-commits-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/differential/local-commits-view.css',
),
'differential-results-table-css' =>
array(
'uri' => '/res/aab3123c/rsrc/css/application/differential/results-table.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/differential/results-table.css',
),
'differential-revision-add-comment-css' =>
array(
'uri' => '/res/849748d3/rsrc/css/application/differential/add-comment.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/differential/add-comment.css',
),
'differential-revision-comment-css' =>
array(
'uri' => '/res/42c222f4/rsrc/css/application/differential/revision-comment.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/differential/revision-comment.css',
),
'differential-revision-comment-list-css' =>
array(
'uri' => '/res/3b31faa3/rsrc/css/application/differential/revision-comment-list.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/differential/revision-comment-list.css',
),
'differential-revision-history-css' =>
array(
'uri' => '/res/d41bc64c/rsrc/css/application/differential/revision-history.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/differential/revision-history.css',
),
'differential-revision-list-css' =>
array(
'uri' => '/res/fe6c4721/rsrc/css/application/differential/revision-list.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/differential/revision-list.css',
),
'differential-table-of-contents-css' =>
array(
'uri' => '/res/4fde8bfc/rsrc/css/application/differential/table-of-contents.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/differential/table-of-contents.css',
),
'diffusion-commit-view-css' =>
array(
'uri' => '/res/b445944e/rsrc/css/application/diffusion/commit-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/diffusion/commit-view.css',
),
'diffusion-icons-css' =>
array(
'uri' => '/res/b93e32c9/rsrc/css/application/diffusion/diffusion-icons.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/diffusion/diffusion-icons.css',
),
'diffusion-source-css' =>
array(
'uri' => '/res/e76bcd50/rsrc/css/application/diffusion/diffusion-source.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/diffusion/diffusion-source.css',
),
'global-drag-and-drop-css' =>
array(
'uri' => '/res/4e24cb65/rsrc/css/application/files/global-drag-and-drop.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/files/global-drag-and-drop.css',
),
'herald-css' =>
array(
'uri' => '/res/2150a55d/rsrc/css/application/herald/herald.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/herald/herald.css',
),
'herald-rule-editor' =>
array(
'uri' => '/res/f35d7e23/rsrc/js/application/herald/HeraldRuleEditor.js',
'type' => 'js',
'requires' =>
array(
0 => 'multirow-row-manager',
1 => 'javelin-install',
2 => 'javelin-typeahead',
3 => 'javelin-util',
4 => 'javelin-dom',
5 => 'javelin-tokenizer',
6 => 'javelin-typeahead-preloaded-source',
7 => 'javelin-stratcom',
8 => 'javelin-json',
9 => 'phabricator-prefab',
),
'disk' => '/rsrc/js/application/herald/HeraldRuleEditor.js',
),
'herald-test-css' =>
array(
'uri' => '/res/c0cd6bdb/rsrc/css/application/herald/herald-test.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/herald/herald-test.css',
),
'inline-comment-summary-css' =>
array(
'uri' => '/res/338704f7/rsrc/css/application/diff/inline-comment-summary.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/diff/inline-comment-summary.css',
),
'javelin-aphlict' =>
array(
'uri' => '/res/c0b9e53f/rsrc/js/application/aphlict/Aphlict.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
),
'disk' => '/rsrc/js/application/aphlict/Aphlict.js',
),
'javelin-behavior' =>
array(
'uri' => '/res/ef4eda09/rsrc/js/javelin/lib/behavior.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-magical-init',
),
'disk' => '/rsrc/js/javelin/lib/behavior.js',
),
'javelin-behavior-aphlict-dropdown' =>
array(
'uri' => '/res/2418f448/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-request',
2 => 'javelin-stratcom',
3 => 'javelin-vector',
4 => 'javelin-dom',
5 => 'javelin-uri',
),
'disk' => '/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js',
),
'javelin-behavior-aphlict-listen' =>
array(
'uri' => '/res/6dde3f43/rsrc/js/application/aphlict/behavior-aphlict-listen.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-aphlict',
2 => 'javelin-stratcom',
3 => 'javelin-request',
4 => 'javelin-uri',
5 => 'javelin-dom',
6 => 'javelin-json',
7 => 'phabricator-notification',
),
'disk' => '/rsrc/js/application/aphlict/behavior-aphlict-listen.js',
),
'javelin-behavior-aphront-basic-tokenizer' =>
array(
'uri' => '/res/cf049052/rsrc/js/application/core/behavior-tokenizer.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'phabricator-prefab',
),
'disk' => '/rsrc/js/application/core/behavior-tokenizer.js',
),
'javelin-behavior-aphront-crop' =>
array(
'uri' => '/res/cda1eace/rsrc/js/application/core/behavior-crop.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-vector',
3 => 'javelin-magical-init',
),
'disk' => '/rsrc/js/application/core/behavior-crop.js',
),
'javelin-behavior-aphront-drag-and-drop' =>
array(
'uri' => '/res/8dd5fd78/rsrc/js/application/core/behavior-drag-and-drop.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'phabricator-file-upload',
3 => 'phabricator-drag-and-drop-file-upload',
),
'disk' => '/rsrc/js/application/core/behavior-drag-and-drop.js',
),
'javelin-behavior-aphront-drag-and-drop-textarea' =>
array(
'uri' => '/res/853e33b9/rsrc/js/application/core/behavior-drag-and-drop-textarea.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'phabricator-drag-and-drop-file-upload',
3 => 'phabricator-paste-file-upload',
4 => 'phabricator-textareautils',
),
'disk' => '/rsrc/js/application/core/behavior-drag-and-drop-textarea.js',
),
'javelin-behavior-aphront-form-disable-on-submit' =>
array(
'uri' => '/res/b5052cd0/rsrc/js/application/core/behavior-form.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/core/behavior-form.js',
),
'javelin-behavior-aphront-more' =>
array(
'uri' => '/res/9ad83c3c/rsrc/js/application/core/behavior-more.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/core/behavior-more.js',
),
'javelin-behavior-audit-preview' =>
array(
'uri' => '/res/3048b073/rsrc/js/application/diffusion/behavior-audit-preview.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'phabricator-shaped-request',
),
'disk' => '/rsrc/js/application/diffusion/behavior-audit-preview.js',
),
'javelin-behavior-conpherence-drag-and-drop-photo' =>
array(
'uri' => '/res/9e3eb1cd/rsrc/js/application/conpherence/behavior-drag-and-drop-photo.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-workflow',
3 => 'phabricator-drag-and-drop-file-upload',
),
'disk' => '/rsrc/js/application/conpherence/behavior-drag-and-drop-photo.js',
),
'javelin-behavior-conpherence-init' =>
array(
'uri' => '/res/700bba2e/rsrc/js/application/conpherence/behavior-init.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/application/conpherence/behavior-init.js',
),
'javelin-behavior-conpherence-menu' =>
array(
'uri' => '/res/cb1a5cf0/rsrc/js/application/conpherence/behavior-menu.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-request',
3 => 'javelin-stratcom',
4 => 'javelin-uri',
5 => 'javelin-util',
6 => 'javelin-workflow',
),
'disk' => '/rsrc/js/application/conpherence/behavior-menu.js',
),
'javelin-behavior-conpherence-pontificate' =>
array(
'uri' => '/res/15263692/rsrc/js/application/conpherence/behavior-pontificate.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-workflow',
),
'disk' => '/rsrc/js/application/conpherence/behavior-pontificate.js',
),
'javelin-behavior-conpherence-widget-pane' =>
array(
'uri' => '/res/43a0fe1b/rsrc/js/application/conpherence/behavior-widget-pane.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/application/conpherence/behavior-widget-pane.js',
),
'javelin-behavior-countdown-timer' =>
array(
'uri' => '/res/7468acb7/rsrc/js/application/countdown/timer.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
),
'disk' => '/rsrc/js/application/countdown/timer.js',
),
'javelin-behavior-dark-console' =>
array(
'uri' => '/res/89aeb6c0/rsrc/js/application/core/behavior-dark-console.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-request',
5 => 'phabricator-keyboard-shortcut',
),
'disk' => '/rsrc/js/application/core/behavior-dark-console.js',
),
'javelin-behavior-device' =>
array(
'uri' => '/res/a10b851b/rsrc/js/application/core/behavior-device.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-vector',
4 => 'javelin-install',
),
'disk' => '/rsrc/js/application/core/behavior-device.js',
),
'javelin-behavior-differential-accept-with-errors' =>
array(
'uri' => '/res/8fea67b3/rsrc/js/application/differential/behavior-accept-with-errors.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/differential/behavior-accept-with-errors.js',
),
'javelin-behavior-differential-add-reviewers-and-ccs' =>
array(
'uri' => '/res/27be3f81/rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'phabricator-prefab',
),
'disk' => '/rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js',
),
'javelin-behavior-differential-comment-jump' =>
array(
'uri' => '/res/b580229b/rsrc/js/application/differential/behavior-comment-jump.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-util',
2 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/differential/behavior-comment-jump.js',
),
'javelin-behavior-differential-diff-radios' =>
array(
'uri' => '/res/004cb66f/rsrc/js/application/differential/behavior-diff-radios.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/differential/behavior-diff-radios.js',
),
'javelin-behavior-differential-dropdown-menus' =>
array(
'uri' => '/res/752f5dfc/rsrc/js/application/differential/behavior-dropdown-menus.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-stratcom',
4 => 'phabricator-dropdown-menu',
5 => 'phabricator-menu-item',
),
'disk' => '/rsrc/js/application/differential/behavior-dropdown-menus.js',
),
'javelin-behavior-differential-edit-inline-comments' =>
array(
'uri' => '/res/70c1f3a3/rsrc/js/application/differential/behavior-edit-inline-comments.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-util',
4 => 'javelin-vector',
5 => 'differential-inline-comment-editor',
),
'disk' => '/rsrc/js/application/differential/behavior-edit-inline-comments.js',
),
'javelin-behavior-differential-feedback-preview' =>
array(
'uri' => '/res/5fbce8db/rsrc/js/application/differential/behavior-comment-preview.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-request',
4 => 'javelin-util',
5 => 'phabricator-shaped-request',
),
'disk' => '/rsrc/js/application/differential/behavior-comment-preview.js',
),
'javelin-behavior-differential-keyboard-navigation' =>
array(
'uri' => '/res/89e93cc9/rsrc/js/application/differential/behavior-keyboard-nav.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'phabricator-keyboard-shortcut',
),
'disk' => '/rsrc/js/application/differential/behavior-keyboard-nav.js',
),
'javelin-behavior-differential-populate' =>
array(
'uri' => '/res/526c2615/rsrc/js/application/differential/behavior-populate.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-workflow',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-stratcom',
5 => 'javelin-behavior-device',
6 => 'javelin-vector',
7 => 'phabricator-tooltip',
),
'disk' => '/rsrc/js/application/differential/behavior-populate.js',
),
'javelin-behavior-differential-show-all-comments' =>
array(
'uri' => '/res/eaa12efc/rsrc/js/application/differential/behavior-show-all-comments.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/differential/behavior-show-all-comments.js',
),
'javelin-behavior-differential-show-field-details' =>
array(
'uri' => '/res/8d57f459/rsrc/js/application/differential/behavior-show-field-details.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/differential/behavior-show-field-details.js',
),
'javelin-behavior-differential-show-more' =>
array(
'uri' => '/res/b9f93090/rsrc/js/application/differential/behavior-show-more.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-workflow',
3 => 'javelin-util',
4 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/application/differential/behavior-show-more.js',
),
'javelin-behavior-differential-toggle-files' =>
array(
'uri' => '/res/ae937207/rsrc/js/application/differential/behavior-toggle-files.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/application/differential/behavior-toggle-files.js',
),
'javelin-behavior-differential-user-select' =>
array(
'uri' => '/res/23c51a5d/rsrc/js/application/differential/behavior-user-select.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/application/differential/behavior-user-select.js',
),
'javelin-behavior-diffusion-commit-branches' =>
array(
'uri' => '/res/1ede335a/rsrc/js/application/diffusion/behavior-commit-branches.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-request',
),
'disk' => '/rsrc/js/application/diffusion/behavior-commit-branches.js',
),
'javelin-behavior-diffusion-commit-graph' =>
array(
'uri' => '/res/62bd2035/rsrc/js/application/diffusion/behavior-commit-graph.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/application/diffusion/behavior-commit-graph.js',
),
'javelin-behavior-diffusion-jump-to' =>
array(
'uri' => '/res/7c42e1ba/rsrc/js/application/diffusion/behavior-jump-to.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-util',
2 => 'javelin-vector',
3 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/diffusion/behavior-jump-to.js',
),
'javelin-behavior-diffusion-line-linker' =>
array(
'uri' => '/res/12866f13/rsrc/js/application/diffusion/behavior-line-linker.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-history',
),
'disk' => '/rsrc/js/application/diffusion/behavior-line-linker.js',
),
'javelin-behavior-diffusion-pull-lastmodified' =>
array(
'uri' => '/res/29fe2790/rsrc/js/application/diffusion/behavior-pull-lastmodified.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-request',
),
'disk' => '/rsrc/js/application/diffusion/behavior-pull-lastmodified.js',
),
'javelin-behavior-error-log' =>
array(
'uri' => '/res/f46289e9/rsrc/js/application/core/behavior-error-log.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/core/behavior-error-log.js',
),
'javelin-behavior-fancy-datepicker' =>
array(
'uri' => '/res/0a1bc610/rsrc/js/application/core/behavior-fancy-datepicker.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-util',
2 => 'javelin-dom',
3 => 'javelin-stratcom',
4 => 'javelin-vector',
),
'disk' => '/rsrc/js/application/core/behavior-fancy-datepicker.js',
),
'javelin-behavior-global-drag-and-drop' =>
array(
'uri' => '/res/73ae3fd1/rsrc/js/application/core/behavior-global-drag-and-drop.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-uri',
3 => 'javelin-mask',
4 => 'phabricator-drag-and-drop-file-upload',
),
'disk' => '/rsrc/js/application/core/behavior-global-drag-and-drop.js',
),
'javelin-behavior-herald-rule-editor' =>
array(
'uri' => '/res/77a0c945/rsrc/js/application/herald/herald-rule-editor.js',
'type' => 'js',
'requires' =>
array(
0 => 'herald-rule-editor',
1 => 'javelin-behavior',
),
'disk' => '/rsrc/js/application/herald/herald-rule-editor.js',
),
'javelin-behavior-history-install' =>
array(
'uri' => '/res/e146a99b/rsrc/js/application/core/behavior-history-install.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-history',
),
'disk' => '/rsrc/js/application/core/behavior-history-install.js',
),
'javelin-behavior-konami' =>
array(
'uri' => '/res/2199602f/rsrc/js/application/core/behavior-konami.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/application/core/behavior-konami.js',
),
'javelin-behavior-lightbox-attachments' =>
array(
'uri' => '/res/08f5e202/rsrc/js/application/core/behavior-lightbox-attachments.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-mask',
4 => 'javelin-util',
5 => 'phabricator-busy',
),
'disk' => '/rsrc/js/application/core/behavior-lightbox-attachments.js',
),
'javelin-behavior-line-chart' =>
array(
'uri' => '/res/1aa5ac88/rsrc/js/application/maniphest/behavior-line-chart.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-vector',
),
'disk' => '/rsrc/js/application/maniphest/behavior-line-chart.js',
),
'javelin-behavior-load-blame' =>
array(
'uri' => '/res/138e2961/rsrc/js/application/diffusion/behavior-load-blame.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-request',
),
'disk' => '/rsrc/js/application/diffusion/behavior-load-blame.js',
),
'javelin-behavior-maniphest-batch-editor' =>
array(
'uri' => '/res/d22661be/rsrc/js/application/maniphest/behavior-batch-editor.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'phabricator-prefab',
4 => 'multirow-row-manager',
5 => 'javelin-json',
),
'disk' => '/rsrc/js/application/maniphest/behavior-batch-editor.js',
),
'javelin-behavior-maniphest-batch-selector' =>
array(
'uri' => '/res/398cf8d7/rsrc/js/application/maniphest/behavior-batch-selector.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/application/maniphest/behavior-batch-selector.js',
),
'javelin-behavior-maniphest-description-preview' =>
array(
'uri' => '/res/8acd6f07/rsrc/js/application/maniphest/behavior-task-preview.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'phabricator-shaped-request',
),
'disk' => '/rsrc/js/application/maniphest/behavior-task-preview.js',
),
'javelin-behavior-maniphest-subpriority-editor' =>
array(
'uri' => '/res/5e02f19a/rsrc/js/application/maniphest/behavior-subpriorityeditor.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-magical-init',
2 => 'javelin-dom',
3 => 'javelin-vector',
4 => 'javelin-stratcom',
5 => 'javelin-workflow',
),
'disk' => '/rsrc/js/application/maniphest/behavior-subpriorityeditor.js',
),
'javelin-behavior-maniphest-transaction-controls' =>
array(
'uri' => '/res/62465554/rsrc/js/application/maniphest/behavior-transaction-controls.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'phabricator-prefab',
),
'disk' => '/rsrc/js/application/maniphest/behavior-transaction-controls.js',
),
'javelin-behavior-maniphest-transaction-expand' =>
array(
'uri' => '/res/966410de/rsrc/js/application/maniphest/behavior-transaction-expand.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-workflow',
3 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/application/maniphest/behavior-transaction-expand.js',
),
'javelin-behavior-maniphest-transaction-preview' =>
array(
'uri' => '/res/855c9f0c/rsrc/js/application/maniphest/behavior-transaction-preview.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-json',
4 => 'javelin-stratcom',
5 => 'phabricator-shaped-request',
),
'disk' => '/rsrc/js/application/maniphest/behavior-transaction-preview.js',
),
'javelin-behavior-owners-path-editor' =>
array(
'uri' => '/res/9cf78ffc/rsrc/js/application/owners/owners-path-editor.js',
'type' => 'js',
'requires' =>
array(
0 => 'owners-path-editor',
1 => 'javelin-behavior',
),
'disk' => '/rsrc/js/application/owners/owners-path-editor.js',
),
'javelin-behavior-phabricator-active-nav' =>
array(
'uri' => '/res/f879d4dd/rsrc/js/application/core/behavior-active-nav.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-vector',
3 => 'javelin-dom',
4 => 'javelin-uri',
),
'disk' => '/rsrc/js/application/core/behavior-active-nav.js',
),
'javelin-behavior-phabricator-autofocus' =>
array(
'uri' => '/res/2946bb89/rsrc/js/application/core/behavior-autofocus.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/core/behavior-autofocus.js',
),
'javelin-behavior-phabricator-file-tree' =>
array(
'uri' => '/res/e9c96597/rsrc/js/application/core/behavior-file-tree.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'phabricator-keyboard-shortcut',
2 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/application/core/behavior-file-tree.js',
),
'javelin-behavior-phabricator-gesture' =>
array(
'uri' => '/res/f186161c/rsrc/js/application/core/behavior-gesture.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-behavior-device',
2 => 'javelin-stratcom',
3 => 'javelin-vector',
4 => 'javelin-dom',
5 => 'javelin-magical-init',
),
'disk' => '/rsrc/js/application/core/behavior-gesture.js',
),
'javelin-behavior-phabricator-gesture-example' =>
array(
'uri' => '/res/da636e19/rsrc/js/application/uiexample/gesture-example.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-stratcom',
1 => 'javelin-behavior',
2 => 'javelin-vector',
3 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/uiexample/gesture-example.js',
),
'javelin-behavior-phabricator-keyboard-pager' =>
array(
'uri' => '/res/56d64eff/rsrc/js/application/core/behavior-keyboard-pager.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-uri',
2 => 'phabricator-keyboard-shortcut',
),
'disk' => '/rsrc/js/application/core/behavior-keyboard-pager.js',
),
'javelin-behavior-phabricator-keyboard-shortcuts' =>
array(
'uri' => '/res/c5eb65cd/rsrc/js/application/core/behavior-keyboard-shortcuts.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-workflow',
2 => 'javelin-json',
3 => 'javelin-dom',
4 => 'phabricator-keyboard-shortcut',
),
'disk' => '/rsrc/js/application/core/behavior-keyboard-shortcuts.js',
),
'javelin-behavior-phabricator-nav' =>
array(
'uri' => '/res/222b9329/rsrc/js/application/core/behavior-phabricator-nav.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-behavior-device',
2 => 'javelin-stratcom',
3 => 'javelin-dom',
4 => 'javelin-magical-init',
5 => 'javelin-vector',
),
'disk' => '/rsrc/js/application/core/behavior-phabricator-nav.js',
),
'javelin-behavior-phabricator-notification-example' =>
array(
'uri' => '/res/a6d51998/rsrc/js/application/uiexample/notification-example.js',
'type' => 'js',
'requires' =>
array(
0 => 'phabricator-notification',
1 => 'javelin-stratcom',
2 => 'javelin-behavior',
3 => 'javelin-uri',
),
'disk' => '/rsrc/js/application/uiexample/notification-example.js',
),
'javelin-behavior-phabricator-object-selector' =>
array(
'uri' => '/res/0c4b0d82/rsrc/js/application/core/behavior-object-selector.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-request',
3 => 'javelin-util',
),
'disk' => '/rsrc/js/application/core/behavior-object-selector.js',
),
'javelin-behavior-phabricator-oncopy' =>
array(
'uri' => '/res/f490b8d1/rsrc/js/application/core/behavior-oncopy.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/core/behavior-oncopy.js',
),
'javelin-behavior-phabricator-remarkup-assist' =>
array(
'uri' => '/res/07406487/rsrc/js/application/core/behavior-phabricator-remarkup-assist.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'phabricator-textareautils',
),
'disk' => '/rsrc/js/application/core/behavior-phabricator-remarkup-assist.js',
),
'javelin-behavior-phabricator-reveal-content' =>
array(
'uri' => '/res/a4fae14a/rsrc/js/application/core/behavior-reveal-content.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/core/behavior-reveal-content.js',
),
'javelin-behavior-phabricator-search-typeahead' =>
array(
'uri' => '/res/046ab274/rsrc/js/application/core/behavior-search-typeahead.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-typeahead-ondemand-source',
2 => 'javelin-typeahead',
3 => 'javelin-dom',
4 => 'javelin-uri',
5 => 'javelin-util',
6 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/application/core/behavior-search-typeahead.js',
),
'javelin-behavior-phabricator-tooltips' =>
array(
'uri' => '/res/e0b344c6/rsrc/js/application/core/behavior-tooltip.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-behavior-device',
2 => 'javelin-stratcom',
3 => 'phabricator-tooltip',
),
'disk' => '/rsrc/js/application/core/behavior-tooltip.js',
),
'javelin-behavior-phabricator-transaction-comment-form' =>
array(
'uri' => '/res/acc3ada1/rsrc/js/application/transactions/behavior-transaction-comment-form.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'phabricator-shaped-request',
),
'disk' => '/rsrc/js/application/transactions/behavior-transaction-comment-form.js',
),
'javelin-behavior-phabricator-transaction-list' =>
array(
'uri' => '/res/f1fbb474/rsrc/js/application/transactions/behavior-transaction-list.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-workflow',
3 => 'javelin-dom',
4 => 'javelin-fx',
),
'disk' => '/rsrc/js/application/transactions/behavior-transaction-list.js',
),
'javelin-behavior-phabricator-watch-anchor' =>
array(
'uri' => '/res/b20b1cc2/rsrc/js/application/core/behavior-watch-anchor.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-vector',
),
'disk' => '/rsrc/js/application/core/behavior-watch-anchor.js',
),
'javelin-behavior-phame-post-preview' =>
array(
'uri' => '/res/ac4c503a/rsrc/js/application/phame/phame-post-preview.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'phabricator-shaped-request',
),
'disk' => '/rsrc/js/application/phame/phame-post-preview.js',
),
'javelin-behavior-pholio-mock-view' =>
array(
- 'uri' => '/res/eefc43b3/rsrc/js/application/pholio/behavior-pholio-mock-view.js',
+ 'uri' => '/res/ecf5f969/rsrc/js/application/pholio/behavior-pholio-mock-view.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-util',
2 => 'javelin-stratcom',
3 => 'javelin-dom',
4 => 'javelin-vector',
5 => 'javelin-magical-init',
6 => 'javelin-request',
7 => 'javelin-history',
8 => 'javelin-workflow',
9 => 'javelin-mask',
10 => 'javelin-behavior-device',
11 => 'phabricator-keyboard-shortcut',
),
'disk' => '/rsrc/js/application/pholio/behavior-pholio-mock-view.js',
),
'javelin-behavior-phriction-document-preview' =>
array(
'uri' => '/res/f1665ecd/rsrc/js/application/phriction/phriction-document-preview.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'phabricator-shaped-request',
),
'disk' => '/rsrc/js/application/phriction/phriction-document-preview.js',
),
'javelin-behavior-ponder-feedback-preview' =>
array(
'uri' => '/res/2e802dd9/rsrc/js/application/ponder/behavior-comment-preview.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'phabricator-shaped-request',
),
'disk' => '/rsrc/js/application/ponder/behavior-comment-preview.js',
),
'javelin-behavior-ponder-votebox' =>
array(
'uri' => '/res/9d091af3/rsrc/js/application/ponder/behavior-votebox.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-stratcom',
4 => 'javelin-request',
),
'disk' => '/rsrc/js/application/ponder/behavior-votebox.js',
),
'javelin-behavior-project-create' =>
array(
'uri' => '/res/e91f3f8f/rsrc/js/application/projects/behavior-project-create.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'javelin-workflow',
),
'disk' => '/rsrc/js/application/projects/behavior-project-create.js',
),
'javelin-behavior-refresh-csrf' =>
array(
'uri' => '/res/6fd76d0f/rsrc/js/application/core/behavior-refresh-csrf.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-request',
1 => 'javelin-behavior',
2 => 'javelin-dom',
3 => 'phabricator-busy',
),
'disk' => '/rsrc/js/application/core/behavior-refresh-csrf.js',
),
+ 'javelin-behavior-releeph-preview-branch' =>
+ array(
+ 'uri' => '/res/a77ebc86/rsrc/js/application/releeph/releeph-preview-branch.js',
+ 'type' => 'js',
+ 'requires' =>
+ array(
+ 0 => 'javelin-behavior',
+ 1 => 'javelin-dom',
+ 2 => 'javelin-stratcom',
+ 3 => 'javelin-uri',
+ 4 => 'javelin-util',
+ ),
+ 'disk' => '/rsrc/js/application/releeph/releeph-preview-branch.js',
+ ),
+ 'javelin-behavior-releeph-request-state-change' =>
+ array(
+ 'uri' => '/res/38f96ba8/rsrc/js/application/releeph/releeph-request-state-change.js',
+ 'type' => 'js',
+ 'requires' =>
+ array(
+ 0 => 'javelin-behavior',
+ 1 => 'javelin-dom',
+ 2 => 'javelin-stratcom',
+ 3 => 'javelin-util',
+ 4 => 'phabricator-keyboard-shortcut',
+ 5 => 'phabricator-notification',
+ ),
+ 'disk' => '/rsrc/js/application/releeph/releeph-request-state-change.js',
+ ),
+ 'javelin-behavior-releeph-request-typeahead' =>
+ array(
+ 'uri' => '/res/b52096e2/rsrc/js/application/releeph/releeph-request-typeahead.js',
+ 'type' => 'js',
+ 'requires' =>
+ array(
+ 0 => 'javelin-behavior',
+ 1 => 'javelin-util',
+ 2 => 'javelin-dom',
+ 3 => 'javelin-typeahead',
+ 4 => 'javelin-tokenizer',
+ 5 => 'javelin-typeahead-preloaded-source',
+ 6 => 'javelin-typeahead-ondemand-source',
+ 7 => 'javelin-dom',
+ 8 => 'javelin-stratcom',
+ 9 => 'javelin-util',
+ ),
+ 'disk' => '/rsrc/js/application/releeph/releeph-request-typeahead.js',
+ ),
'javelin-behavior-repository-crossreference' =>
array(
'uri' => '/res/4b5fab1c/rsrc/js/application/repository/repository-crossreference.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'javelin-uri',
),
'disk' => '/rsrc/js/application/repository/repository-crossreference.js',
),
'javelin-behavior-stripe-payment-form' =>
array(
'uri' => '/res/87c7b043/rsrc/js/application/phortune/behavior-stripe-payment-form.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-json',
3 => 'stripe-core',
),
'disk' => '/rsrc/js/application/phortune/behavior-stripe-payment-form.js',
),
'javelin-behavior-toggle-class' =>
array(
'uri' => '/res/fa818e0f/rsrc/js/application/core/behavior-toggle-class.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/core/behavior-toggle-class.js',
),
'javelin-behavior-view-placeholder' =>
array(
'uri' => '/res/5b89bdf5/rsrc/js/javelin/ext/view/ViewPlaceholder.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-view-renderer',
),
'disk' => '/rsrc/js/javelin/ext/view/ViewPlaceholder.js',
),
'javelin-behavior-workflow' =>
array(
'uri' => '/res/2c99beaf/rsrc/js/application/core/behavior-workflow.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-workflow',
3 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/core/behavior-workflow.js',
),
'javelin-color' =>
array(
'uri' => '/res/b0439fc9/rsrc/js/javelin/ext/fx/Color.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
),
'disk' => '/rsrc/js/javelin/ext/fx/Color.js',
),
'javelin-cookie' =>
array(
'uri' => '/res/a9cddab0/rsrc/js/javelin/lib/Cookie.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
),
'disk' => '/rsrc/js/javelin/lib/Cookie.js',
),
'javelin-dom' =>
array(
'uri' => '/res/459f3c08/rsrc/js/javelin/lib/DOM.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-magical-init',
1 => 'javelin-install',
2 => 'javelin-util',
3 => 'javelin-vector',
4 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/javelin/lib/DOM.js',
),
'javelin-dynval' =>
array(
'uri' => '/res/d89c6f88/rsrc/js/javelin/ext/reactor/core/DynVal.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-reactornode',
2 => 'javelin-util',
3 => 'javelin-reactor',
),
'disk' => '/rsrc/js/javelin/ext/reactor/core/DynVal.js',
),
'javelin-event' =>
array(
'uri' => '/res/69d99d9f/rsrc/js/javelin/core/Event.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
),
'disk' => '/rsrc/js/javelin/core/Event.js',
),
'javelin-fx' =>
array(
'uri' => '/res/30ef0914/rsrc/js/javelin/ext/fx/FX.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-color',
1 => 'javelin-install',
2 => 'javelin-util',
),
'disk' => '/rsrc/js/javelin/ext/fx/FX.js',
),
'javelin-history' =>
array(
'uri' => '/res/9bb36651/rsrc/js/javelin/lib/History.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-stratcom',
1 => 'javelin-install',
2 => 'javelin-uri',
3 => 'javelin-util',
),
'disk' => '/rsrc/js/javelin/lib/History.js',
),
'javelin-install' =>
array(
'uri' => '/res/cab679ff/rsrc/js/javelin/core/install.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-util',
1 => 'javelin-magical-init',
),
'disk' => '/rsrc/js/javelin/core/install.js',
),
'javelin-json' =>
array(
'uri' => '/res/561b8056/rsrc/js/javelin/lib/JSON.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
),
'disk' => '/rsrc/js/javelin/lib/JSON.js',
),
'javelin-magical-init' =>
array(
'uri' => '/res/2f1554da/rsrc/js/javelin/core/init.js',
'type' => 'js',
'requires' =>
array(
),
'disk' => '/rsrc/js/javelin/core/init.js',
),
'javelin-mask' =>
array(
'uri' => '/res/d2a35fff/rsrc/js/javelin/lib/Mask.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
),
'disk' => '/rsrc/js/javelin/lib/Mask.js',
),
'javelin-reactor' =>
array(
'uri' => '/res/dfd87f3c/rsrc/js/javelin/ext/reactor/core/Reactor.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
),
'disk' => '/rsrc/js/javelin/ext/reactor/core/Reactor.js',
),
'javelin-reactor-dom' =>
array(
'uri' => '/res/701b6f39/rsrc/js/javelin/ext/reactor/dom/RDOM.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-dom',
1 => 'javelin-dynval',
2 => 'javelin-reactornode',
3 => 'javelin-install',
4 => 'javelin-util',
),
'disk' => '/rsrc/js/javelin/ext/reactor/dom/RDOM.js',
),
'javelin-reactor-node-calmer' =>
array(
'uri' => '/res/5a35920a/rsrc/js/javelin/ext/reactor/core/ReactorNodeCalmer.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-reactor',
2 => 'javelin-util',
),
'disk' => '/rsrc/js/javelin/ext/reactor/core/ReactorNodeCalmer.js',
),
'javelin-reactornode' =>
array(
'uri' => '/res/f278cc27/rsrc/js/javelin/ext/reactor/core/ReactorNode.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-reactor',
2 => 'javelin-util',
3 => 'javelin-reactor-node-calmer',
),
'disk' => '/rsrc/js/javelin/ext/reactor/core/ReactorNode.js',
),
'javelin-request' =>
array(
'uri' => '/res/e25d75b3/rsrc/js/javelin/lib/Request.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-stratcom',
2 => 'javelin-util',
3 => 'javelin-behavior',
4 => 'javelin-json',
5 => 'javelin-dom',
6 => 'javelin-resource',
),
'disk' => '/rsrc/js/javelin/lib/Request.js',
),
'javelin-resource' =>
array(
'uri' => '/res/d5a3f835/rsrc/js/javelin/lib/Resource.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-magical-init',
1 => 'javelin-stratcom',
2 => 'javelin-util',
3 => 'javelin-uri',
),
'disk' => '/rsrc/js/javelin/lib/Resource.js',
),
'javelin-stratcom' =>
array(
'uri' => '/res/c81f64eb/rsrc/js/javelin/core/Stratcom.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-event',
2 => 'javelin-util',
3 => 'javelin-magical-init',
),
'disk' => '/rsrc/js/javelin/core/Stratcom.js',
),
'javelin-tokenizer' =>
array(
'uri' => '/res/c75c9e12/rsrc/js/javelin/lib/control/tokenizer/Tokenizer.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-dom',
1 => 'javelin-util',
2 => 'javelin-stratcom',
3 => 'javelin-install',
),
'disk' => '/rsrc/js/javelin/lib/control/tokenizer/Tokenizer.js',
),
'javelin-typeahead' =>
array(
'uri' => '/res/dccb789e/rsrc/js/javelin/lib/control/typeahead/Typeahead.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-vector',
3 => 'javelin-util',
),
'disk' => '/rsrc/js/javelin/lib/control/typeahead/Typeahead.js',
),
'javelin-typeahead-composite-source' =>
array(
'uri' => '/res/99705f64/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-typeahead-source',
2 => 'javelin-util',
),
'disk' => '/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js',
),
'javelin-typeahead-normalizer' =>
array(
'uri' => '/res/a9e97c0d/rsrc/js/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
),
'disk' => '/rsrc/js/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js',
),
'javelin-typeahead-ondemand-source' =>
array(
'uri' => '/res/81e531aa/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-stratcom',
3 => 'javelin-request',
4 => 'javelin-typeahead-source',
),
'disk' => '/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js',
),
'javelin-typeahead-preloaded-source' =>
array(
'uri' => '/res/d464efd2/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-stratcom',
3 => 'javelin-request',
4 => 'javelin-typeahead-source',
),
'disk' => '/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js',
),
'javelin-typeahead-source' =>
array(
'uri' => '/res/74b1f091/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadSource.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-dom',
3 => 'javelin-typeahead-normalizer',
),
'disk' => '/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadSource.js',
),
'javelin-typeahead-static-source' =>
array(
'uri' => '/res/c8e247fc/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadStaticSource.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-typeahead-source',
),
'disk' => '/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadStaticSource.js',
),
'javelin-uri' =>
array(
'uri' => '/res/c107d858/rsrc/js/javelin/lib/URI.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/javelin/lib/URI.js',
),
'javelin-util' =>
array(
'uri' => '/res/25786b6c/rsrc/js/javelin/core/util.js',
'type' => 'js',
'requires' =>
array(
),
'disk' => '/rsrc/js/javelin/core/util.js',
),
'javelin-vector' =>
array(
'uri' => '/res/f240bdb3/rsrc/js/javelin/lib/Vector.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-event',
),
'disk' => '/rsrc/js/javelin/lib/Vector.js',
),
'javelin-view' =>
array(
'uri' => '/res/b98657a7/rsrc/js/javelin/ext/view/View.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
),
'disk' => '/rsrc/js/javelin/ext/view/View.js',
),
'javelin-view-html' =>
array(
'uri' => '/res/7e5a2122/rsrc/js/javelin/ext/view/HTMLView.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-view',
),
'disk' => '/rsrc/js/javelin/ext/view/HTMLView.js',
),
'javelin-view-interpreter' =>
array(
'uri' => '/res/17e911ca/rsrc/js/javelin/ext/view/ViewInterpreter.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-view',
1 => 'javelin-install',
),
'disk' => '/rsrc/js/javelin/ext/view/ViewInterpreter.js',
),
'javelin-view-renderer' =>
array(
'uri' => '/res/db4ed5a2/rsrc/js/javelin/ext/view/ViewRenderer.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
),
'disk' => '/rsrc/js/javelin/ext/view/ViewRenderer.js',
),
'javelin-view-visitor' =>
array(
'uri' => '/res/0ef9dc43/rsrc/js/javelin/ext/view/ViewVisitor.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
),
'disk' => '/rsrc/js/javelin/ext/view/ViewVisitor.js',
),
'javelin-workflow' =>
array(
'uri' => '/res/1535e366/rsrc/js/javelin/lib/Workflow.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-stratcom',
1 => 'javelin-request',
2 => 'javelin-dom',
3 => 'javelin-vector',
4 => 'javelin-install',
5 => 'javelin-util',
6 => 'javelin-mask',
7 => 'javelin-uri',
),
'disk' => '/rsrc/js/javelin/lib/Workflow.js',
),
'lightbox-attachment-css' =>
array(
'uri' => '/res/4657e15d/rsrc/css/aphront/lightbox-attachment.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/lightbox-attachment.css',
),
'maniphest-batch-editor' =>
array(
'uri' => '/res/fb15d744/rsrc/css/application/maniphest/batch-editor.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/maniphest/batch-editor.css',
),
'maniphest-report-css' =>
array(
'uri' => '/res/2e633fcf/rsrc/css/application/maniphest/report.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/maniphest/report.css',
),
'maniphest-task-edit-css' =>
array(
'uri' => '/res/68c7863e/rsrc/css/application/maniphest/task-edit.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/maniphest/task-edit.css',
),
'maniphest-task-summary-css' =>
array(
'uri' => '/res/b3930263/rsrc/css/application/maniphest/task-summary.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/maniphest/task-summary.css',
),
'maniphest-transaction-detail-css' =>
array(
'uri' => '/res/fb430d3e/rsrc/css/application/maniphest/transaction-detail.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/maniphest/transaction-detail.css',
),
'multirow-row-manager' =>
array(
'uri' => '/res/0a9b3dee/rsrc/js/application/core/MultirowRowManager.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-util',
),
'disk' => '/rsrc/js/application/core/MultirowRowManager.js',
),
'owners-path-editor' =>
array(
'uri' => '/res/29b68354/rsrc/js/application/owners/OwnersPathEditor.js',
'type' => 'js',
'requires' =>
array(
0 => 'multirow-row-manager',
1 => 'javelin-install',
2 => 'path-typeahead',
3 => 'javelin-dom',
4 => 'javelin-util',
5 => 'phabricator-prefab',
),
'disk' => '/rsrc/js/application/owners/OwnersPathEditor.js',
),
'owners-path-editor-css' =>
array(
'uri' => '/res/4fcaabf6/rsrc/css/application/owners/owners-path-editor.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/owners/owners-path-editor.css',
),
'paste-css' =>
array(
- 'uri' => '/res/5081cf13/rsrc/css/application/paste/paste.css',
+ 'uri' => '/res/044639be/rsrc/css/application/paste/paste.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/paste/paste.css',
),
'path-typeahead' =>
array(
'uri' => '/res/50246fb6/rsrc/js/application/herald/PathTypeahead.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-typeahead',
2 => 'javelin-dom',
3 => 'javelin-request',
4 => 'javelin-typeahead-ondemand-source',
5 => 'javelin-util',
),
'disk' => '/rsrc/js/application/herald/PathTypeahead.js',
),
'phabricator-action-list-view-css' =>
array(
'uri' => '/res/7a67c3b9/rsrc/css/layout/phabricator-action-list-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-action-list-view.css',
),
'phabricator-application-launch-view-css' =>
array(
'uri' => '/res/13c3d7f3/rsrc/css/application/base/phabricator-application-launch-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/base/phabricator-application-launch-view.css',
),
'phabricator-busy' =>
array(
'uri' => '/res/6ec372e1/rsrc/js/application/core/Busy.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/core/Busy.js',
),
'phabricator-chatlog-css' =>
array(
'uri' => '/res/f6631adc/rsrc/css/application/chatlog/chatlog.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/chatlog/chatlog.css',
),
'phabricator-content-source-view-css' =>
array(
'uri' => '/res/8c738a93/rsrc/css/application/contentsource/content-source-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/contentsource/content-source-view.css',
),
'phabricator-core-buttons-css' =>
array(
'uri' => '/res/4e6b94c8/rsrc/css/core/buttons.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/core/buttons.css',
),
'phabricator-core-css' =>
array(
'uri' => '/res/9df0488c/rsrc/css/core/core.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/core/core.css',
),
'phabricator-countdown-css' =>
array(
'uri' => '/res/0f646281/rsrc/css/application/countdown/timer.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/countdown/timer.css',
),
'phabricator-crumbs-view-css' =>
array(
'uri' => '/res/69fdba64/rsrc/css/layout/phabricator-crumbs-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-crumbs-view.css',
),
'phabricator-directory-css' =>
array(
'uri' => '/res/61afca2b/rsrc/css/application/directory/phabricator-directory.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/directory/phabricator-directory.css',
),
'phabricator-drag-and-drop-file-upload' =>
array(
'uri' => '/res/ce71f19a/rsrc/js/application/core/DragAndDropFileUpload.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-request',
3 => 'javelin-dom',
4 => 'javelin-uri',
5 => 'phabricator-file-upload',
),
'disk' => '/rsrc/js/application/core/DragAndDropFileUpload.js',
),
'phabricator-dropdown-menu' =>
array(
'uri' => '/res/2b4aa4d8/rsrc/js/application/core/DropdownMenu.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-dom',
3 => 'javelin-vector',
4 => 'javelin-stratcom',
5 => 'phabricator-menu-item',
),
'disk' => '/rsrc/js/application/core/DropdownMenu.js',
),
'phabricator-fatal-config-template-css' =>
array(
'uri' => '/res/6e1a8d22/rsrc/css/application/config/config-template.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/config/config-template.css',
),
'phabricator-feed-css' =>
array(
'uri' => '/res/94a04b24/rsrc/css/application/feed/feed.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/feed/feed.css',
),
'phabricator-file-upload' =>
array(
'uri' => '/res/2de10295/rsrc/js/application/core/FileUpload.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'phabricator-notification',
),
'disk' => '/rsrc/js/application/core/FileUpload.js',
),
'phabricator-filetree-view-css' =>
array(
'uri' => '/res/c912ed91/rsrc/css/layout/phabricator-filetree-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-filetree-view.css',
),
'phabricator-flag-css' =>
array(
'uri' => '/res/2eee890a/rsrc/css/application/flag/flag.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/flag/flag.css',
),
'phabricator-form-view-css' =>
array(
'uri' => '/res/676b1ad2/rsrc/css/layout/phabricator-form-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-form-view.css',
),
'phabricator-header-view-css' =>
array(
'uri' => '/res/585b771c/rsrc/css/layout/phabricator-header-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-header-view.css',
),
'phabricator-jump-nav' =>
array(
'uri' => '/res/2e0e2211/rsrc/css/application/directory/phabricator-jump-nav.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/directory/phabricator-jump-nav.css',
),
'phabricator-keyboard-shortcut' =>
array(
'uri' => '/res/beed38cd/rsrc/js/application/core/KeyboardShortcut.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'phabricator-keyboard-shortcut-manager',
),
'disk' => '/rsrc/js/application/core/KeyboardShortcut.js',
),
'phabricator-keyboard-shortcut-manager' =>
array(
'uri' => '/res/d0bee7c7/rsrc/js/application/core/KeyboardShortcutManager.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-stratcom',
3 => 'javelin-dom',
4 => 'javelin-vector',
),
'disk' => '/rsrc/js/application/core/KeyboardShortcutManager.js',
),
'phabricator-main-menu-view' =>
array(
'uri' => '/res/c1a73bc2/rsrc/css/application/base/main-menu-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/base/main-menu-view.css',
),
'phabricator-menu-item' =>
array(
'uri' => '/res/32fc2325/rsrc/js/application/core/DropdownMenuItem.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/core/DropdownMenuItem.js',
),
'phabricator-nav-view-css' =>
array(
'uri' => '/res/f3c78a53/rsrc/css/aphront/phabricator-nav-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/phabricator-nav-view.css',
),
'phabricator-notification' =>
array(
'uri' => '/res/ad727561/rsrc/js/application/core/Notification.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'javelin-util',
4 => 'phabricator-notification-css',
),
'disk' => '/rsrc/js/application/core/Notification.js',
),
'phabricator-notification-css' =>
array(
'uri' => '/res/664b9bec/rsrc/css/aphront/notification.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/notification.css',
),
'phabricator-notification-menu-css' =>
array(
'uri' => '/res/b7cc25af/rsrc/css/application/base/notification-menu.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/base/notification-menu.css',
),
'phabricator-object-item-list-view-css' =>
array(
'uri' => '/res/3fed6faf/rsrc/css/layout/phabricator-object-item-list-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-object-item-list-view.css',
),
'phabricator-object-list-view-css' =>
array(
'uri' => '/res/4f183668/rsrc/css/application/projects/phabricator-object-list-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/projects/phabricator-object-list-view.css',
),
'phabricator-object-selector-css' =>
array(
'uri' => '/res/7eb4c705/rsrc/css/application/objectselector/object-selector.css',
'type' => 'css',
'requires' =>
array(
0 => 'aphront-dialog-view-css',
),
'disk' => '/rsrc/css/application/objectselector/object-selector.css',
),
'phabricator-paste-file-upload' =>
array(
'uri' => '/res/b0b8afd8/rsrc/js/application/core/PasteFileUpload.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-request',
3 => 'javelin-dom',
4 => 'javelin-uri',
),
'disk' => '/rsrc/js/application/core/PasteFileUpload.js',
),
'phabricator-pinboard-view-css' =>
array(
'uri' => '/res/61ecd7cf/rsrc/css/layout/phabricator-pinboard-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-pinboard-view.css',
),
'phabricator-prefab' =>
array(
'uri' => '/res/2734e45f/rsrc/js/application/core/Prefab.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-dom',
3 => 'javelin-typeahead',
4 => 'javelin-tokenizer',
5 => 'javelin-typeahead-preloaded-source',
6 => 'javelin-typeahead-ondemand-source',
7 => 'javelin-dom',
8 => 'javelin-stratcom',
9 => 'javelin-util',
),
'disk' => '/rsrc/js/application/core/Prefab.js',
),
'phabricator-profile-css' =>
array(
'uri' => '/res/9869d10b/rsrc/css/application/profile/profile-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/profile/profile-view.css',
),
'phabricator-profile-header-css' =>
array(
'uri' => '/res/4b1cb23b/rsrc/css/application/profile/profile-header-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/profile/profile-header-view.css',
),
'phabricator-project-tag-css' =>
array(
'uri' => '/res/1b5efcb2/rsrc/css/application/projects/project-tag.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/projects/project-tag.css',
),
'phabricator-property-list-view-css' =>
array(
'uri' => '/res/a04cc81d/rsrc/css/layout/phabricator-property-list-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-property-list-view.css',
),
'phabricator-remarkup-css' =>
array(
'uri' => '/res/4265a372/rsrc/css/core/remarkup.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/core/remarkup.css',
),
'phabricator-search-results-css' =>
array(
'uri' => '/res/f8a86e27/rsrc/css/application/search/search-results.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/search/search-results.css',
),
'phabricator-shaped-request' =>
array(
'uri' => '/res/fbdb92db/rsrc/js/application/core/ShapedRequest.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-request',
),
'disk' => '/rsrc/js/application/core/ShapedRequest.js',
),
'phabricator-side-menu-view-css' =>
array(
'uri' => '/res/28a1e092/rsrc/css/layout/phabricator-side-menu-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-side-menu-view.css',
),
'phabricator-slowvote-css' =>
array(
'uri' => '/res/94d20443/rsrc/css/application/slowvote/slowvote.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/slowvote/slowvote.css',
),
'phabricator-source-code-view-css' =>
array(
- 'uri' => '/res/9373e769/rsrc/css/layout/phabricator-source-code-view.css',
+ 'uri' => '/res/979d5280/rsrc/css/layout/phabricator-source-code-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-source-code-view.css',
),
'phabricator-standard-page-view' =>
array(
'uri' => '/res/70fa2da4/rsrc/css/application/base/standard-page-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/base/standard-page-view.css',
),
'phabricator-tag-view-css' =>
array(
'uri' => '/res/e10bf844/rsrc/css/layout/phabricator-tag-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-tag-view.css',
),
'phabricator-textareautils' =>
array(
'uri' => '/res/703614ea/rsrc/js/application/core/TextAreaUtils.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
),
'disk' => '/rsrc/js/application/core/TextAreaUtils.js',
),
'phabricator-timeline-view-css' =>
array(
'uri' => '/res/5517bf1a/rsrc/css/layout/phabricator-timeline-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-timeline-view.css',
),
'phabricator-tooltip' =>
array(
'uri' => '/res/55d76b9b/rsrc/js/application/core/ToolTip.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-dom',
3 => 'javelin-vector',
),
'disk' => '/rsrc/js/application/core/ToolTip.js',
),
'phabricator-transaction-view-css' =>
array(
'uri' => '/res/00be4b1a/rsrc/css/aphront/transaction.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/transaction.css',
),
'phabricator-ui-example-css' =>
array(
'uri' => '/res/376ab671/rsrc/css/application/uiexample/example.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/uiexample/example.css',
),
'phabricator-uiexample-javelin-view' =>
array(
'uri' => '/res/a2ce2cfc/rsrc/js/application/uiexample/JavelinViewExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-view',
2 => 'javelin-util',
3 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/uiexample/JavelinViewExample.js',
),
'phabricator-uiexample-reactor-button' =>
array(
'uri' => '/res/142127f6/rsrc/js/application/uiexample/ReactorButtonExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-view',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorButtonExample.js',
),
'phabricator-uiexample-reactor-checkbox' =>
array(
'uri' => '/res/c75cb9e9/rsrc/js/application/uiexample/ReactorCheckboxExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-view',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorCheckboxExample.js',
),
'phabricator-uiexample-reactor-focus' =>
array(
'uri' => '/res/3cc992eb/rsrc/js/application/uiexample/ReactorFocusExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-view',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorFocusExample.js',
),
'phabricator-uiexample-reactor-input' =>
array(
'uri' => '/res/4953da16/rsrc/js/application/uiexample/ReactorInputExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-view',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-reactor-dom',
5 => 'javelin-view-html',
6 => 'javelin-view-interpreter',
7 => 'javelin-view-renderer',
),
'disk' => '/rsrc/js/application/uiexample/ReactorInputExample.js',
),
'phabricator-uiexample-reactor-mouseover' =>
array(
'uri' => '/res/52a355b6/rsrc/js/application/uiexample/ReactorMouseoverExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-view',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorMouseoverExample.js',
),
'phabricator-uiexample-reactor-radio' =>
array(
'uri' => '/res/ae87f3af/rsrc/js/application/uiexample/ReactorRadioExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-view',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorRadioExample.js',
),
'phabricator-uiexample-reactor-select' =>
array(
'uri' => '/res/23cb448a/rsrc/js/application/uiexample/ReactorSelectExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-view',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorSelectExample.js',
),
'phabricator-uiexample-reactor-sendclass' =>
array(
'uri' => '/res/8cd34264/rsrc/js/application/uiexample/ReactorSendClassExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-view',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorSendClassExample.js',
),
'phabricator-uiexample-reactor-sendproperties' =>
array(
'uri' => '/res/18af54aa/rsrc/js/application/uiexample/ReactorSendPropertiesExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-view',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorSendPropertiesExample.js',
),
'phabricator-zindex-css' =>
array(
'uri' => '/res/fcbf82ad/rsrc/css/core/z-index.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/core/z-index.css',
),
'phame-css' =>
array(
'uri' => '/res/8e3edb71/rsrc/css/application/phame/phame.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/phame/phame.css',
),
'pholio-css' =>
array(
- 'uri' => '/res/bc10bf21/rsrc/css/application/pholio/pholio.css',
+ 'uri' => '/res/b0947e46/rsrc/css/application/pholio/pholio.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/pholio/pholio.css',
),
'pholio-inline-comments-css' =>
array(
'uri' => '/res/8fe0edc7/rsrc/css/application/pholio/pholio-inline-comments.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/pholio/pholio-inline-comments.css',
),
'phriction-document-css' =>
array(
'uri' => '/res/8d09bd7f/rsrc/css/application/phriction/phriction-document-css.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/phriction/phriction-document-css.css',
),
'ponder-comment-table-css' =>
array(
'uri' => '/res/a1bb9056/rsrc/css/application/ponder/comments.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/ponder/comments.css',
),
'ponder-core-view-css' =>
array(
'uri' => '/res/3a2d5e18/rsrc/css/application/ponder/core.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/ponder/core.css',
),
'ponder-feed-view-css' =>
array(
'uri' => '/res/df22bd20/rsrc/css/application/ponder/feed.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/ponder/feed.css',
),
'ponder-post-css' =>
array(
'uri' => '/res/013b9e2c/rsrc/css/application/ponder/post.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/ponder/post.css',
),
'ponder-vote-css' =>
array(
'uri' => '/res/ea8316c2/rsrc/css/application/ponder/vote.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/ponder/vote.css',
),
'raphael-core' =>
array(
'uri' => '/res/3f48575a/rsrc/js/raphael/raphael.js',
'type' => 'js',
'requires' =>
array(
),
'disk' => '/rsrc/js/raphael/raphael.js',
),
'raphael-g' =>
array(
'uri' => '/res/b07e5245/rsrc/js/raphael/g.raphael.js',
'type' => 'js',
'requires' =>
array(
),
'disk' => '/rsrc/js/raphael/g.raphael.js',
),
'raphael-g-line' =>
array(
'uri' => '/res/a59c8556/rsrc/js/raphael/g.raphael.line.js',
'type' => 'js',
'requires' =>
array(
),
'disk' => '/rsrc/js/raphael/g.raphael.line.js',
),
+ 'releeph-branch' =>
+ array(
+ 'uri' => '/res/6ad6420d/rsrc/css/application/releeph/releeph-branch.css',
+ 'type' => 'css',
+ 'requires' =>
+ array(
+ ),
+ 'disk' => '/rsrc/css/application/releeph/releeph-branch.css',
+ ),
+ 'releeph-colors' =>
+ array(
+ 'uri' => '/res/dff4b26a/rsrc/css/application/releeph/releeph-colors.css',
+ 'type' => 'css',
+ 'requires' =>
+ array(
+ ),
+ 'disk' => '/rsrc/css/application/releeph/releeph-colors.css',
+ ),
+ 'releeph-core' =>
+ array(
+ 'uri' => '/res/853f4a73/rsrc/css/application/releeph/releeph-core.css',
+ 'type' => 'css',
+ 'requires' =>
+ array(
+ ),
+ 'disk' => '/rsrc/css/application/releeph/releeph-core.css',
+ ),
+ 'releeph-intents' =>
+ array(
+ 'uri' => '/res/4e73e9dd/rsrc/css/application/releeph/releeph-intents.css',
+ 'type' => 'css',
+ 'requires' =>
+ array(
+ ),
+ 'disk' => '/rsrc/css/application/releeph/releeph-intents.css',
+ ),
+ 'releeph-preview-branch' =>
+ array(
+ 'uri' => '/res/65e5dece/rsrc/css/application/releeph/releeph-preview-branch.css',
+ 'type' => 'css',
+ 'requires' =>
+ array(
+ ),
+ 'disk' => '/rsrc/css/application/releeph/releeph-preview-branch.css',
+ ),
+ 'releeph-project' =>
+ array(
+ 'uri' => '/res/b9376e59/rsrc/css/application/releeph/releeph-project.css',
+ 'type' => 'css',
+ 'requires' =>
+ array(
+ ),
+ 'disk' => '/rsrc/css/application/releeph/releeph-project.css',
+ ),
+ 'releeph-request-differential-create-dialog' =>
+ array(
+ 'uri' => '/res/4df30ce1/rsrc/css/application/releeph/releeph-request-differential-create-dialog.css',
+ 'type' => 'css',
+ 'requires' =>
+ array(
+ ),
+ 'disk' => '/rsrc/css/application/releeph/releeph-request-differential-create-dialog.css',
+ ),
+ 'releeph-request-typeahead-css' =>
+ array(
+ 'uri' => '/res/9c9a1acf/rsrc/css/application/releeph/releeph-request-typeahead.css',
+ 'type' => 'css',
+ 'requires' =>
+ array(
+ ),
+ 'disk' => '/rsrc/css/application/releeph/releeph-request-typeahead.css',
+ ),
+ 'releeph-status' =>
+ array(
+ 'uri' => '/res/588529df/rsrc/css/application/releeph/releeph-status.css',
+ 'type' => 'css',
+ 'requires' =>
+ array(
+ ),
+ 'disk' => '/rsrc/css/application/releeph/releeph-status.css',
+ ),
'setup-issue-css' =>
array(
'uri' => '/res/efbb3673/rsrc/css/application/config/setup-issue.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/config/setup-issue.css',
),
'sprite-apps-css' =>
array(
'uri' => '/res/8de495b4/rsrc/css/sprite-apps.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/sprite-apps.css',
),
'sprite-apps-large-css' =>
array(
'uri' => '/res/174143b7/rsrc/css/sprite-apps-large.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/sprite-apps-large.css',
),
'sprite-apps-xlarge-css' =>
array(
'uri' => '/res/33a8e644/rsrc/css/sprite-apps-xlarge.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/sprite-apps-xlarge.css',
),
'sprite-conpherence-css' =>
array(
'uri' => '/res/f6793453/rsrc/css/sprite-conpherence.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/sprite-conpherence.css',
),
'sprite-docs-css' =>
array(
'uri' => '/res/b32f93bc/rsrc/css/sprite-docs.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/sprite-docs.css',
),
'sprite-gradient-css' =>
array(
'uri' => '/res/e62e7a0f/rsrc/css/sprite-gradient.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/sprite-gradient.css',
),
'sprite-icon-css' =>
array(
'uri' => '/res/e7d63fcf/rsrc/css/sprite-icon.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/sprite-icon.css',
),
'sprite-menu-css' =>
array(
'uri' => '/res/50bb9cc5/rsrc/css/sprite-menu.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/sprite-menu.css',
),
'sprite-tokens-css' =>
array(
'uri' => '/res/9ae0de5b/rsrc/css/sprite-tokens.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/sprite-tokens.css',
),
'stripe-core' =>
array(
'uri' => '/res/3b0f0ad4/rsrc/js/stripe/stripe_core.js',
'type' => 'js',
'requires' =>
array(
),
'disk' => '/rsrc/js/stripe/stripe_core.js',
),
'stripe-payment-form-css' =>
array(
'uri' => '/res/634a6371/rsrc/css/application/phortune/stripe-payment-form.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/phortune/stripe-payment-form.css',
),
'syntax-highlighting-css' =>
array(
'uri' => '/res/cb3b9dc0/rsrc/css/core/syntax.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/core/syntax.css',
),
'tokens-css' =>
array(
'uri' => '/res/6b3c65c7/rsrc/css/application/tokens/tokens.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/tokens/tokens.css',
),
), array(
'packages' =>
array(
'7cb09b8b' =>
array(
'name' => 'core.pkg.css',
'symbols' =>
array(
0 => 'phabricator-core-css',
1 => 'phabricator-zindex-css',
2 => 'phabricator-core-buttons-css',
3 => 'phabricator-standard-page-view',
4 => 'aphront-dialog-view-css',
5 => 'aphront-form-view-css',
6 => 'aphront-panel-view-css',
7 => 'aphront-table-view-css',
8 => 'aphront-tokenizer-control-css',
9 => 'aphront-typeahead-control-css',
10 => 'aphront-list-filter-view-css',
11 => 'phabricator-directory-css',
12 => 'phabricator-jump-nav',
13 => 'phabricator-remarkup-css',
14 => 'syntax-highlighting-css',
15 => 'aphront-pager-view-css',
16 => 'phabricator-transaction-view-css',
17 => 'aphront-tooltip-css',
18 => 'phabricator-flag-css',
19 => 'aphront-error-view-css',
20 => 'sprite-icon-css',
21 => 'sprite-gradient-css',
22 => 'sprite-menu-css',
23 => 'sprite-apps-large-css',
24 => 'phabricator-main-menu-view',
25 => 'phabricator-notification-css',
26 => 'phabricator-notification-menu-css',
27 => 'lightbox-attachment-css',
28 => 'phabricator-header-view-css',
29 => 'phabricator-form-view-css',
30 => 'phabricator-filetree-view-css',
31 => 'phabricator-nav-view-css',
32 => 'phabricator-side-menu-view-css',
33 => 'phabricator-crumbs-view-css',
34 => 'phabricator-object-item-list-view-css',
35 => 'global-drag-and-drop-css',
),
'uri' => '/res/pkg/7cb09b8b/core.pkg.css',
'type' => 'css',
),
'95ceba95' =>
array(
'name' => 'core.pkg.js',
'symbols' =>
array(
0 => 'javelin-behavior-aphront-basic-tokenizer',
1 => 'javelin-behavior-workflow',
2 => 'javelin-behavior-aphront-form-disable-on-submit',
3 => 'phabricator-keyboard-shortcut-manager',
4 => 'phabricator-keyboard-shortcut',
5 => 'javelin-behavior-phabricator-keyboard-shortcuts',
6 => 'javelin-behavior-refresh-csrf',
7 => 'javelin-behavior-phabricator-watch-anchor',
8 => 'javelin-behavior-phabricator-autofocus',
9 => 'phabricator-paste-file-upload',
10 => 'phabricator-menu-item',
11 => 'phabricator-dropdown-menu',
12 => 'javelin-behavior-phabricator-oncopy',
13 => 'phabricator-tooltip',
14 => 'javelin-behavior-phabricator-tooltips',
15 => 'phabricator-prefab',
16 => 'javelin-behavior-device',
17 => 'javelin-behavior-toggle-class',
18 => 'javelin-behavior-lightbox-attachments',
19 => 'phabricator-busy',
20 => 'javelin-aphlict',
21 => 'phabricator-notification',
22 => 'javelin-behavior-aphlict-listen',
23 => 'javelin-behavior-phabricator-search-typeahead',
24 => 'javelin-behavior-konami',
25 => 'javelin-behavior-aphlict-dropdown',
26 => 'javelin-behavior-history-install',
27 => 'javelin-behavior-phabricator-gesture',
28 => 'javelin-behavior-phabricator-active-nav',
29 => 'javelin-behavior-phabricator-nav',
30 => 'javelin-behavior-phabricator-remarkup-assist',
31 => 'phabricator-textareautils',
32 => 'phabricator-file-upload',
33 => 'javelin-behavior-global-drag-and-drop',
34 => 'javelin-behavior-phabricator-reveal-content',
),
'uri' => '/res/pkg/95ceba95/core.pkg.js',
'type' => 'js',
),
'dca4a03d' =>
array(
'name' => 'darkconsole.pkg.js',
'symbols' =>
array(
0 => 'javelin-behavior-dark-console',
1 => 'javelin-behavior-error-log',
),
'uri' => '/res/pkg/dca4a03d/darkconsole.pkg.js',
'type' => 'js',
),
'8aaacd1b' =>
array(
'name' => 'differential.pkg.css',
'symbols' =>
array(
0 => 'differential-core-view-css',
1 => 'differential-changeset-view-css',
2 => 'differential-results-table-css',
3 => 'differential-revision-history-css',
4 => 'differential-revision-list-css',
5 => 'differential-table-of-contents-css',
6 => 'differential-revision-comment-css',
7 => 'differential-revision-add-comment-css',
8 => 'differential-revision-comment-list-css',
9 => 'phabricator-object-selector-css',
10 => 'phabricator-content-source-view-css',
11 => 'differential-local-commits-view-css',
12 => 'inline-comment-summary-css',
),
'uri' => '/res/pkg/8aaacd1b/differential.pkg.css',
'type' => 'css',
),
'322728f3' =>
array(
'name' => 'differential.pkg.js',
'symbols' =>
array(
0 => 'phabricator-drag-and-drop-file-upload',
1 => 'phabricator-shaped-request',
2 => 'javelin-behavior-differential-feedback-preview',
3 => 'javelin-behavior-differential-edit-inline-comments',
4 => 'javelin-behavior-differential-populate',
5 => 'javelin-behavior-differential-show-more',
6 => 'javelin-behavior-differential-diff-radios',
7 => 'javelin-behavior-differential-accept-with-errors',
8 => 'javelin-behavior-differential-comment-jump',
9 => 'javelin-behavior-differential-add-reviewers-and-ccs',
10 => 'javelin-behavior-differential-keyboard-navigation',
11 => 'javelin-behavior-aphront-drag-and-drop',
12 => 'javelin-behavior-aphront-drag-and-drop-textarea',
13 => 'javelin-behavior-phabricator-object-selector',
14 => 'javelin-behavior-repository-crossreference',
15 => 'javelin-behavior-load-blame',
16 => 'differential-inline-comment-editor',
17 => 'javelin-behavior-differential-dropdown-menus',
18 => 'javelin-behavior-differential-toggle-files',
19 => 'javelin-behavior-differential-user-select',
),
'uri' => '/res/pkg/322728f3/differential.pkg.js',
'type' => 'js',
),
'c8ce2d88' =>
array(
'name' => 'diffusion.pkg.css',
'symbols' =>
array(
0 => 'diffusion-commit-view-css',
1 => 'diffusion-icons-css',
),
'uri' => '/res/pkg/c8ce2d88/diffusion.pkg.css',
'type' => 'css',
),
'f96657b8' =>
array(
'name' => 'diffusion.pkg.js',
'symbols' =>
array(
0 => 'javelin-behavior-diffusion-pull-lastmodified',
1 => 'javelin-behavior-diffusion-commit-graph',
2 => 'javelin-behavior-audit-preview',
),
'uri' => '/res/pkg/f96657b8/diffusion.pkg.js',
'type' => 'js',
),
'cd1d650a' =>
array(
'name' => 'javelin.pkg.js',
'symbols' =>
array(
0 => 'javelin-util',
1 => 'javelin-install',
2 => 'javelin-event',
3 => 'javelin-stratcom',
4 => 'javelin-behavior',
5 => 'javelin-resource',
6 => 'javelin-request',
7 => 'javelin-vector',
8 => 'javelin-dom',
9 => 'javelin-json',
10 => 'javelin-uri',
11 => 'javelin-workflow',
12 => 'javelin-mask',
13 => 'javelin-typeahead',
14 => 'javelin-typeahead-normalizer',
15 => 'javelin-typeahead-source',
16 => 'javelin-typeahead-preloaded-source',
17 => 'javelin-typeahead-ondemand-source',
18 => 'javelin-tokenizer',
),
'uri' => '/res/pkg/cd1d650a/javelin.pkg.js',
'type' => 'js',
),
'c41b4907' =>
array(
'name' => 'maniphest.pkg.css',
'symbols' =>
array(
0 => 'maniphest-task-summary-css',
1 => 'maniphest-transaction-detail-css',
2 => 'aphront-attached-file-view-css',
3 => 'phabricator-project-tag-css',
),
'uri' => '/res/pkg/c41b4907/maniphest.pkg.css',
'type' => 'css',
),
'7707de41' =>
array(
'name' => 'maniphest.pkg.js',
'symbols' =>
array(
0 => 'javelin-behavior-maniphest-batch-selector',
1 => 'javelin-behavior-maniphest-transaction-controls',
2 => 'javelin-behavior-maniphest-transaction-preview',
3 => 'javelin-behavior-maniphest-transaction-expand',
4 => 'javelin-behavior-maniphest-subpriority-editor',
),
'uri' => '/res/pkg/7707de41/maniphest.pkg.js',
'type' => 'js',
),
),
'reverse' =>
array(
'aphront-attached-file-view-css' => 'c41b4907',
'aphront-dialog-view-css' => '7cb09b8b',
'aphront-error-view-css' => '7cb09b8b',
'aphront-form-view-css' => '7cb09b8b',
'aphront-list-filter-view-css' => '7cb09b8b',
'aphront-pager-view-css' => '7cb09b8b',
'aphront-panel-view-css' => '7cb09b8b',
'aphront-table-view-css' => '7cb09b8b',
'aphront-tokenizer-control-css' => '7cb09b8b',
'aphront-tooltip-css' => '7cb09b8b',
'aphront-typeahead-control-css' => '7cb09b8b',
'differential-changeset-view-css' => '8aaacd1b',
'differential-core-view-css' => '8aaacd1b',
'differential-inline-comment-editor' => '322728f3',
'differential-local-commits-view-css' => '8aaacd1b',
'differential-results-table-css' => '8aaacd1b',
'differential-revision-add-comment-css' => '8aaacd1b',
'differential-revision-comment-css' => '8aaacd1b',
'differential-revision-comment-list-css' => '8aaacd1b',
'differential-revision-history-css' => '8aaacd1b',
'differential-revision-list-css' => '8aaacd1b',
'differential-table-of-contents-css' => '8aaacd1b',
'diffusion-commit-view-css' => 'c8ce2d88',
'diffusion-icons-css' => 'c8ce2d88',
'global-drag-and-drop-css' => '7cb09b8b',
'inline-comment-summary-css' => '8aaacd1b',
'javelin-aphlict' => '95ceba95',
'javelin-behavior' => 'cd1d650a',
'javelin-behavior-aphlict-dropdown' => '95ceba95',
'javelin-behavior-aphlict-listen' => '95ceba95',
'javelin-behavior-aphront-basic-tokenizer' => '95ceba95',
'javelin-behavior-aphront-drag-and-drop' => '322728f3',
'javelin-behavior-aphront-drag-and-drop-textarea' => '322728f3',
'javelin-behavior-aphront-form-disable-on-submit' => '95ceba95',
'javelin-behavior-audit-preview' => 'f96657b8',
'javelin-behavior-dark-console' => 'dca4a03d',
'javelin-behavior-device' => '95ceba95',
'javelin-behavior-differential-accept-with-errors' => '322728f3',
'javelin-behavior-differential-add-reviewers-and-ccs' => '322728f3',
'javelin-behavior-differential-comment-jump' => '322728f3',
'javelin-behavior-differential-diff-radios' => '322728f3',
'javelin-behavior-differential-dropdown-menus' => '322728f3',
'javelin-behavior-differential-edit-inline-comments' => '322728f3',
'javelin-behavior-differential-feedback-preview' => '322728f3',
'javelin-behavior-differential-keyboard-navigation' => '322728f3',
'javelin-behavior-differential-populate' => '322728f3',
'javelin-behavior-differential-show-more' => '322728f3',
'javelin-behavior-differential-toggle-files' => '322728f3',
'javelin-behavior-differential-user-select' => '322728f3',
'javelin-behavior-diffusion-commit-graph' => 'f96657b8',
'javelin-behavior-diffusion-pull-lastmodified' => 'f96657b8',
'javelin-behavior-error-log' => 'dca4a03d',
'javelin-behavior-global-drag-and-drop' => '95ceba95',
'javelin-behavior-history-install' => '95ceba95',
'javelin-behavior-konami' => '95ceba95',
'javelin-behavior-lightbox-attachments' => '95ceba95',
'javelin-behavior-load-blame' => '322728f3',
'javelin-behavior-maniphest-batch-selector' => '7707de41',
'javelin-behavior-maniphest-subpriority-editor' => '7707de41',
'javelin-behavior-maniphest-transaction-controls' => '7707de41',
'javelin-behavior-maniphest-transaction-expand' => '7707de41',
'javelin-behavior-maniphest-transaction-preview' => '7707de41',
'javelin-behavior-phabricator-active-nav' => '95ceba95',
'javelin-behavior-phabricator-autofocus' => '95ceba95',
'javelin-behavior-phabricator-gesture' => '95ceba95',
'javelin-behavior-phabricator-keyboard-shortcuts' => '95ceba95',
'javelin-behavior-phabricator-nav' => '95ceba95',
'javelin-behavior-phabricator-object-selector' => '322728f3',
'javelin-behavior-phabricator-oncopy' => '95ceba95',
'javelin-behavior-phabricator-remarkup-assist' => '95ceba95',
'javelin-behavior-phabricator-reveal-content' => '95ceba95',
'javelin-behavior-phabricator-search-typeahead' => '95ceba95',
'javelin-behavior-phabricator-tooltips' => '95ceba95',
'javelin-behavior-phabricator-watch-anchor' => '95ceba95',
'javelin-behavior-refresh-csrf' => '95ceba95',
'javelin-behavior-repository-crossreference' => '322728f3',
'javelin-behavior-toggle-class' => '95ceba95',
'javelin-behavior-workflow' => '95ceba95',
'javelin-dom' => 'cd1d650a',
'javelin-event' => 'cd1d650a',
'javelin-install' => 'cd1d650a',
'javelin-json' => 'cd1d650a',
'javelin-mask' => 'cd1d650a',
'javelin-request' => 'cd1d650a',
'javelin-resource' => 'cd1d650a',
'javelin-stratcom' => 'cd1d650a',
'javelin-tokenizer' => 'cd1d650a',
'javelin-typeahead' => 'cd1d650a',
'javelin-typeahead-normalizer' => 'cd1d650a',
'javelin-typeahead-ondemand-source' => 'cd1d650a',
'javelin-typeahead-preloaded-source' => 'cd1d650a',
'javelin-typeahead-source' => 'cd1d650a',
'javelin-uri' => 'cd1d650a',
'javelin-util' => 'cd1d650a',
'javelin-vector' => 'cd1d650a',
'javelin-workflow' => 'cd1d650a',
'lightbox-attachment-css' => '7cb09b8b',
'maniphest-task-summary-css' => 'c41b4907',
'maniphest-transaction-detail-css' => 'c41b4907',
'phabricator-busy' => '95ceba95',
'phabricator-content-source-view-css' => '8aaacd1b',
'phabricator-core-buttons-css' => '7cb09b8b',
'phabricator-core-css' => '7cb09b8b',
'phabricator-crumbs-view-css' => '7cb09b8b',
'phabricator-directory-css' => '7cb09b8b',
'phabricator-drag-and-drop-file-upload' => '322728f3',
'phabricator-dropdown-menu' => '95ceba95',
'phabricator-file-upload' => '95ceba95',
'phabricator-filetree-view-css' => '7cb09b8b',
'phabricator-flag-css' => '7cb09b8b',
'phabricator-form-view-css' => '7cb09b8b',
'phabricator-header-view-css' => '7cb09b8b',
'phabricator-jump-nav' => '7cb09b8b',
'phabricator-keyboard-shortcut' => '95ceba95',
'phabricator-keyboard-shortcut-manager' => '95ceba95',
'phabricator-main-menu-view' => '7cb09b8b',
'phabricator-menu-item' => '95ceba95',
'phabricator-nav-view-css' => '7cb09b8b',
'phabricator-notification' => '95ceba95',
'phabricator-notification-css' => '7cb09b8b',
'phabricator-notification-menu-css' => '7cb09b8b',
'phabricator-object-item-list-view-css' => '7cb09b8b',
'phabricator-object-selector-css' => '8aaacd1b',
'phabricator-paste-file-upload' => '95ceba95',
'phabricator-prefab' => '95ceba95',
'phabricator-project-tag-css' => 'c41b4907',
'phabricator-remarkup-css' => '7cb09b8b',
'phabricator-shaped-request' => '322728f3',
'phabricator-side-menu-view-css' => '7cb09b8b',
'phabricator-standard-page-view' => '7cb09b8b',
'phabricator-textareautils' => '95ceba95',
'phabricator-tooltip' => '95ceba95',
'phabricator-transaction-view-css' => '7cb09b8b',
'phabricator-zindex-css' => '7cb09b8b',
'sprite-apps-large-css' => '7cb09b8b',
'sprite-gradient-css' => '7cb09b8b',
'sprite-icon-css' => '7cb09b8b',
'sprite-menu-css' => '7cb09b8b',
'syntax-highlighting-css' => '7cb09b8b',
),
));
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
index a13b97b6ec..f223749053 100644
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1,3111 +1,3270 @@
<?php
/**
* This file is automatically generated. Use 'arc liberate' to rebuild it.
* @generated
* @phutil-library-version 2
*/
phutil_register_library_map(array(
'__library_version__' => 2,
'class' =>
array(
'Aphront304Response' => 'aphront/response/Aphront304Response.php',
'Aphront400Response' => 'aphront/response/Aphront400Response.php',
'Aphront403Response' => 'aphront/response/Aphront403Response.php',
'Aphront404Response' => 'aphront/response/Aphront404Response.php',
'AphrontAjaxResponse' => 'aphront/response/AphrontAjaxResponse.php',
'AphrontApplicationConfiguration' => 'aphront/configuration/AphrontApplicationConfiguration.php',
'AphrontAttachedFileView' => 'view/control/AphrontAttachedFileView.php',
'AphrontBarView' => 'view/widget/bars/AphrontBarView.php',
'AphrontCSRFException' => 'aphront/exception/AphrontCSRFException.php',
'AphrontCalendarEventView' => 'applications/calendar/view/AphrontCalendarEventView.php',
'AphrontCalendarMonthView' => 'applications/calendar/view/AphrontCalendarMonthView.php',
'AphrontContextBarView' => 'view/layout/AphrontContextBarView.php',
'AphrontController' => 'aphront/AphrontController.php',
'AphrontCursorPagerView' => 'view/control/AphrontCursorPagerView.php',
'AphrontDefaultApplicationConfiguration' => 'aphront/configuration/AphrontDefaultApplicationConfiguration.php',
'AphrontDialogResponse' => 'aphront/response/AphrontDialogResponse.php',
'AphrontDialogView' => 'view/AphrontDialogView.php',
'AphrontErrorView' => 'view/form/AphrontErrorView.php',
'AphrontException' => 'aphront/exception/AphrontException.php',
'AphrontFileResponse' => 'aphront/response/AphrontFileResponse.php',
'AphrontFormCheckboxControl' => 'view/form/control/AphrontFormCheckboxControl.php',
'AphrontFormControl' => 'view/form/control/AphrontFormControl.php',
'AphrontFormCountedToggleButtonsControl' => 'view/form/control/AphrontFormCountedToggleButtonsControl.php',
'AphrontFormCropControl' => 'view/form/control/AphrontFormCropControl.php',
'AphrontFormDateControl' => 'view/form/control/AphrontFormDateControl.php',
'AphrontFormDividerControl' => 'view/form/control/AphrontFormDividerControl.php',
'AphrontFormDragAndDropUploadControl' => 'view/form/control/AphrontFormDragAndDropUploadControl.php',
'AphrontFormFileControl' => 'view/form/control/AphrontFormFileControl.php',
'AphrontFormImageControl' => 'view/form/control/AphrontFormImageControl.php',
'AphrontFormInsetView' => 'view/form/AphrontFormInsetView.php',
'AphrontFormLayoutView' => 'view/form/AphrontFormLayoutView.php',
'AphrontFormMarkupControl' => 'view/form/control/AphrontFormMarkupControl.php',
'AphrontFormPasswordControl' => 'view/form/control/AphrontFormPasswordControl.php',
'AphrontFormPolicyControl' => 'view/form/control/AphrontFormPolicyControl.php',
'AphrontFormRadioButtonControl' => 'view/form/control/AphrontFormRadioButtonControl.php',
'AphrontFormRecaptchaControl' => 'view/form/control/AphrontFormRecaptchaControl.php',
'AphrontFormSelectControl' => 'view/form/control/AphrontFormSelectControl.php',
'AphrontFormStaticControl' => 'view/form/control/AphrontFormStaticControl.php',
'AphrontFormSubmitControl' => 'view/form/control/AphrontFormSubmitControl.php',
'AphrontFormTextAreaControl' => 'view/form/control/AphrontFormTextAreaControl.php',
'AphrontFormTextControl' => 'view/form/control/AphrontFormTextControl.php',
'AphrontFormToggleButtonsControl' => 'view/form/control/AphrontFormToggleButtonsControl.php',
'AphrontFormTokenizerControl' => 'view/form/control/AphrontFormTokenizerControl.php',
'AphrontFormView' => 'view/form/AphrontFormView.php',
'AphrontGlyphBarView' => 'view/widget/bars/AphrontGlyphBarView.php',
'AphrontHTMLResponse' => 'aphront/response/AphrontHTMLResponse.php',
'AphrontHTTPSink' => 'aphront/sink/AphrontHTTPSink.php',
'AphrontHTTPSinkTestCase' => 'aphront/sink/__tests__/AphrontHTTPSinkTestCase.php',
'AphrontIsolatedDatabaseConnectionTestCase' => 'infrastructure/storage/__tests__/AphrontIsolatedDatabaseConnectionTestCase.php',
'AphrontIsolatedHTTPSink' => 'aphront/sink/AphrontIsolatedHTTPSink.php',
'AphrontJSONResponse' => 'aphront/response/AphrontJSONResponse.php',
'AphrontJavelinView' => 'view/AphrontJavelinView.php',
'AphrontKeyboardShortcutsAvailableView' => 'view/widget/AphrontKeyboardShortcutsAvailableView.php',
'AphrontListFilterView' => 'view/layout/AphrontListFilterView.php',
'AphrontMiniPanelView' => 'view/layout/AphrontMiniPanelView.php',
'AphrontMoreView' => 'view/layout/AphrontMoreView.php',
'AphrontMySQLDatabaseConnectionTestCase' => 'infrastructure/storage/__tests__/AphrontMySQLDatabaseConnectionTestCase.php',
'AphrontNoteView' => 'view/widget/AphrontNoteView.php',
'AphrontNullView' => 'view/AphrontNullView.php',
'AphrontPHPHTTPSink' => 'aphront/sink/AphrontPHPHTTPSink.php',
'AphrontPageView' => 'view/page/AphrontPageView.php',
'AphrontPagerView' => 'view/control/AphrontPagerView.php',
'AphrontPanelView' => 'view/layout/AphrontPanelView.php',
'AphrontPlainTextResponse' => 'aphront/response/AphrontPlainTextResponse.php',
'AphrontProgressBarView' => 'view/widget/bars/AphrontProgressBarView.php',
'AphrontProxyResponse' => 'aphront/response/AphrontProxyResponse.php',
'AphrontRedirectException' => 'aphront/exception/AphrontRedirectException.php',
'AphrontRedirectResponse' => 'aphront/response/AphrontRedirectResponse.php',
'AphrontReloadResponse' => 'aphront/response/AphrontReloadResponse.php',
'AphrontRequest' => 'aphront/AphrontRequest.php',
'AphrontRequestFailureView' => 'view/page/AphrontRequestFailureView.php',
'AphrontRequestTestCase' => 'aphront/__tests__/AphrontRequestTestCase.php',
'AphrontResponse' => 'aphront/response/AphrontResponse.php',
'AphrontSideNavFilterView' => 'view/layout/AphrontSideNavFilterView.php',
'AphrontTableView' => 'view/control/AphrontTableView.php',
'AphrontTagView' => 'view/AphrontTagView.php',
'AphrontTokenizerTemplateView' => 'view/control/AphrontTokenizerTemplateView.php',
'AphrontTwoColumnView' => 'view/layout/AphrontTwoColumnView.php',
'AphrontTypeaheadTemplateView' => 'view/control/AphrontTypeaheadTemplateView.php',
'AphrontURIMapper' => 'aphront/AphrontURIMapper.php',
'AphrontUsageException' => 'aphront/exception/AphrontUsageException.php',
'AphrontView' => 'view/AphrontView.php',
'AphrontWebpageResponse' => 'aphront/response/AphrontWebpageResponse.php',
'AuditPeopleMenuEventListener' => 'applications/audit/events/AuditPeopleMenuEventListener.php',
'CelerityAPI' => 'infrastructure/celerity/CelerityAPI.php',
'CelerityPhabricatorResourceController' => 'infrastructure/celerity/CelerityPhabricatorResourceController.php',
'CelerityResourceController' => 'infrastructure/celerity/CelerityResourceController.php',
'CelerityResourceGraph' => 'infrastructure/celerity/CelerityResourceGraph.php',
'CelerityResourceMap' => 'infrastructure/celerity/CelerityResourceMap.php',
'CelerityResourceTransformer' => 'infrastructure/celerity/CelerityResourceTransformer.php',
'CelerityResourceTransformerTestCase' => 'infrastructure/celerity/__tests__/CelerityResourceTransformerTestCase.php',
'CeleritySpriteGenerator' => 'infrastructure/celerity/CeleritySpriteGenerator.php',
'CelerityStaticResourceResponse' => 'infrastructure/celerity/CelerityStaticResourceResponse.php',
'ConduitAPIMethod' => 'applications/conduit/method/ConduitAPIMethod.php',
'ConduitAPIRequest' => 'applications/conduit/protocol/ConduitAPIRequest.php',
'ConduitAPIResponse' => 'applications/conduit/protocol/ConduitAPIResponse.php',
'ConduitAPI_arcanist_Method' => 'applications/arcanist/conduit/ConduitAPI_arcanist_Method.php',
'ConduitAPI_arcanist_projectinfo_Method' => 'applications/arcanist/conduit/ConduitAPI_arcanist_projectinfo_Method.php',
'ConduitAPI_audit_Method' => 'applications/audit/conduit/ConduitAPI_audit_Method.php',
'ConduitAPI_audit_query_Method' => 'applications/audit/conduit/ConduitAPI_audit_query_Method.php',
'ConduitAPI_chatlog_Method' => 'applications/chatlog/conduit/ConduitAPI_chatlog_Method.php',
'ConduitAPI_chatlog_query_Method' => 'applications/chatlog/conduit/ConduitAPI_chatlog_query_Method.php',
'ConduitAPI_chatlog_record_Method' => 'applications/chatlog/conduit/ConduitAPI_chatlog_record_Method.php',
'ConduitAPI_conduit_connect_Method' => 'applications/conduit/method/ConduitAPI_conduit_connect_Method.php',
'ConduitAPI_conduit_getcertificate_Method' => 'applications/conduit/method/ConduitAPI_conduit_getcertificate_Method.php',
'ConduitAPI_conduit_ping_Method' => 'applications/conduit/method/ConduitAPI_conduit_ping_Method.php',
'ConduitAPI_conduit_query_Method' => 'applications/conduit/method/ConduitAPI_conduit_query_Method.php',
'ConduitAPI_daemon_launched_Method' => 'applications/daemon/conduit/ConduitAPI_daemon_launched_Method.php',
'ConduitAPI_daemon_log_Method' => 'applications/daemon/conduit/ConduitAPI_daemon_log_Method.php',
'ConduitAPI_daemon_setstatus_Method' => 'applications/daemon/conduit/ConduitAPI_daemon_setstatus_Method.php',
'ConduitAPI_differential_Method' => 'applications/differential/conduit/ConduitAPI_differential_Method.php',
'ConduitAPI_differential_close_Method' => 'applications/differential/conduit/ConduitAPI_differential_close_Method.php',
'ConduitAPI_differential_createcomment_Method' => 'applications/differential/conduit/ConduitAPI_differential_createcomment_Method.php',
'ConduitAPI_differential_creatediff_Method' => 'applications/differential/conduit/ConduitAPI_differential_creatediff_Method.php',
'ConduitAPI_differential_createinline_Method' => 'applications/differential/conduit/ConduitAPI_differential_createinline_Method.php',
'ConduitAPI_differential_createrawdiff_Method' => 'applications/differential/conduit/ConduitAPI_differential_createrawdiff_Method.php',
'ConduitAPI_differential_createrevision_Method' => 'applications/differential/conduit/ConduitAPI_differential_createrevision_Method.php',
'ConduitAPI_differential_find_Method' => 'applications/differential/conduit/ConduitAPI_differential_find_Method.php',
'ConduitAPI_differential_finishpostponedlinters_Method' => 'applications/differential/conduit/ConduitAPI_differential_finishpostponedlinters_Method.php',
'ConduitAPI_differential_getalldiffs_Method' => 'applications/differential/conduit/ConduitAPI_differential_getalldiffs_Method.php',
'ConduitAPI_differential_getcommitmessage_Method' => 'applications/differential/conduit/ConduitAPI_differential_getcommitmessage_Method.php',
'ConduitAPI_differential_getcommitpaths_Method' => 'applications/differential/conduit/ConduitAPI_differential_getcommitpaths_Method.php',
'ConduitAPI_differential_getdiff_Method' => 'applications/differential/conduit/ConduitAPI_differential_getdiff_Method.php',
'ConduitAPI_differential_getrevision_Method' => 'applications/differential/conduit/ConduitAPI_differential_getrevision_Method.php',
'ConduitAPI_differential_getrevisioncomments_Method' => 'applications/differential/conduit/ConduitAPI_differential_getrevisioncomments_Method.php',
'ConduitAPI_differential_getrevisionfeedback_Method' => 'applications/differential/conduit/ConduitAPI_differential_getrevisionfeedback_Method.php',
'ConduitAPI_differential_markcommitted_Method' => 'applications/differential/conduit/ConduitAPI_differential_markcommitted_Method.php',
'ConduitAPI_differential_parsecommitmessage_Method' => 'applications/differential/conduit/ConduitAPI_differential_parsecommitmessage_Method.php',
'ConduitAPI_differential_query_Method' => 'applications/differential/conduit/ConduitAPI_differential_query_Method.php',
'ConduitAPI_differential_setdiffproperty_Method' => 'applications/differential/conduit/ConduitAPI_differential_setdiffproperty_Method.php',
'ConduitAPI_differential_updaterevision_Method' => 'applications/differential/conduit/ConduitAPI_differential_updaterevision_Method.php',
'ConduitAPI_differential_updateunitresults_Method' => 'applications/differential/conduit/ConduitAPI_differential_updateunitresults_Method.php',
'ConduitAPI_diffusion_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_Method.php',
'ConduitAPI_diffusion_findsymbols_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_findsymbols_Method.php',
'ConduitAPI_diffusion_getcommits_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_getcommits_Method.php',
'ConduitAPI_diffusion_getlintmessages_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_getlintmessages_Method.php',
'ConduitAPI_diffusion_getrecentcommitsbypath_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_getrecentcommitsbypath_Method.php',
'ConduitAPI_feed_Method' => 'applications/feed/conduit/ConduitAPI_feed_Method.php',
'ConduitAPI_feed_publish_Method' => 'applications/feed/conduit/ConduitAPI_feed_publish_Method.php',
'ConduitAPI_feed_query_Method' => 'applications/feed/conduit/ConduitAPI_feed_query_Method.php',
'ConduitAPI_file_Method' => 'applications/files/conduit/ConduitAPI_file_Method.php',
'ConduitAPI_file_download_Method' => 'applications/files/conduit/ConduitAPI_file_download_Method.php',
'ConduitAPI_file_info_Method' => 'applications/files/conduit/ConduitAPI_file_info_Method.php',
'ConduitAPI_file_upload_Method' => 'applications/files/conduit/ConduitAPI_file_upload_Method.php',
'ConduitAPI_file_uploadhash_Method' => 'applications/files/conduit/ConduitAPI_file_uploadhash_Method.php',
'ConduitAPI_flag_Method' => 'applications/flag/conduit/ConduitAPI_flag_Method.php',
'ConduitAPI_flag_delete_Method' => 'applications/flag/conduit/ConduitAPI_flag_delete_Method.php',
'ConduitAPI_flag_edit_Method' => 'applications/flag/conduit/ConduitAPI_flag_edit_Method.php',
'ConduitAPI_flag_query_Method' => 'applications/flag/conduit/ConduitAPI_flag_query_Method.php',
'ConduitAPI_macro_Method' => 'applications/macro/conduit/ConduitAPI_macro_Method.php',
'ConduitAPI_macro_query_Method' => 'applications/macro/conduit/ConduitAPI_macro_query_Method.php',
'ConduitAPI_maniphest_Method' => 'applications/maniphest/conduit/ConduitAPI_maniphest_Method.php',
'ConduitAPI_maniphest_createtask_Method' => 'applications/maniphest/conduit/ConduitAPI_maniphest_createtask_Method.php',
'ConduitAPI_maniphest_find_Method' => 'applications/maniphest/conduit/ConduitAPI_maniphest_find_Method.php',
'ConduitAPI_maniphest_gettasktransactions_Method' => 'applications/maniphest/conduit/ConduitAPI_maniphest_gettasktransactions_Method.php',
'ConduitAPI_maniphest_info_Method' => 'applications/maniphest/conduit/ConduitAPI_maniphest_info_Method.php',
'ConduitAPI_maniphest_query_Method' => 'applications/maniphest/conduit/ConduitAPI_maniphest_query_Method.php',
'ConduitAPI_maniphest_update_Method' => 'applications/maniphest/conduit/ConduitAPI_maniphest_update_Method.php',
'ConduitAPI_owners_Method' => 'applications/owners/conduit/ConduitAPI_owners_Method.php',
'ConduitAPI_owners_query_Method' => 'applications/owners/conduit/ConduitAPI_owners_query_Method.php',
'ConduitAPI_paste_Method' => 'applications/paste/conduit/ConduitAPI_paste_Method.php',
'ConduitAPI_paste_create_Method' => 'applications/paste/conduit/ConduitAPI_paste_create_Method.php',
'ConduitAPI_paste_info_Method' => 'applications/paste/conduit/ConduitAPI_paste_info_Method.php',
'ConduitAPI_paste_query_Method' => 'applications/paste/conduit/ConduitAPI_paste_query_Method.php',
'ConduitAPI_phid_Method' => 'applications/phid/conduit/ConduitAPI_phid_Method.php',
'ConduitAPI_phid_info_Method' => 'applications/phid/conduit/ConduitAPI_phid_info_Method.php',
'ConduitAPI_phid_lookup_Method' => 'applications/phid/conduit/ConduitAPI_phid_lookup_Method.php',
'ConduitAPI_phid_query_Method' => 'applications/phid/conduit/ConduitAPI_phid_query_Method.php',
'ConduitAPI_phpast_Method' => 'applications/phpast/conduit/ConduitAPI_phpast_Method.php',
'ConduitAPI_phpast_getast_Method' => 'applications/phpast/conduit/ConduitAPI_phpast_getast_Method.php',
'ConduitAPI_phpast_version_Method' => 'applications/phpast/conduit/ConduitAPI_phpast_version_Method.php',
'ConduitAPI_phriction_Method' => 'applications/phriction/conduit/ConduitAPI_phriction_Method.php',
'ConduitAPI_phriction_edit_Method' => 'applications/phriction/conduit/ConduitAPI_phriction_edit_Method.php',
'ConduitAPI_phriction_history_Method' => 'applications/phriction/conduit/ConduitAPI_phriction_history_Method.php',
'ConduitAPI_phriction_info_Method' => 'applications/phriction/conduit/ConduitAPI_phriction_info_Method.php',
'ConduitAPI_project_Method' => 'applications/project/conduit/ConduitAPI_project_Method.php',
'ConduitAPI_project_query_Method' => 'applications/project/conduit/ConduitAPI_project_query_Method.php',
+ 'ConduitAPI_releeph_Method' => 'applications/releeph/conduit/ConduitAPI_releeph_Method.php',
+ 'ConduitAPI_releeph_getbranches_Method' => 'applications/releeph/conduit/ConduitAPI_releeph_getbranches_Method.php',
+ 'ConduitAPI_releeph_projectinfo_Method' => 'applications/releeph/conduit/ConduitAPI_releeph_projectinfo_Method.php',
+ 'ConduitAPI_releeph_request_Method' => 'applications/releeph/conduit/ConduitAPI_releeph_request_Method.php',
+ 'ConduitAPI_releephwork_canpush_Method' => 'applications/releeph/conduit/work/ConduitAPI_releephwork_canpush_Method.php',
+ 'ConduitAPI_releephwork_getauthorinfo_Method' => 'applications/releeph/conduit/work/ConduitAPI_releephwork_getauthorinfo_Method.php',
+ 'ConduitAPI_releephwork_getbranch_Method' => 'applications/releeph/conduit/work/ConduitAPI_releephwork_getbranch_Method.php',
+ 'ConduitAPI_releephwork_getbranchcommitmessage_Method' => 'applications/releeph/conduit/work/ConduitAPI_releephwork_getbranchcommitmessage_Method.php',
+ 'ConduitAPI_releephwork_getcommitmessage_Method' => 'applications/releeph/conduit/work/ConduitAPI_releephwork_getcommitmessage_Method.php',
+ 'ConduitAPI_releephwork_getorigcommitmessage_Method' => 'applications/releeph/conduit/work/ConduitAPI_releephwork_getorigcommitmessage_Method.php',
+ 'ConduitAPI_releephwork_nextrequest_Method' => 'applications/releeph/conduit/work/ConduitAPI_releephwork_nextrequest_Method.php',
+ 'ConduitAPI_releephwork_record_Method' => 'applications/releeph/conduit/work/ConduitAPI_releephwork_record_Method.php',
+ 'ConduitAPI_releephwork_recordpickstatus_Method' => 'applications/releeph/conduit/work/ConduitAPI_releephwork_recordpickstatus_Method.php',
'ConduitAPI_remarkup_process_Method' => 'applications/remarkup/conduit/ConduitAPI_remarkup_process_Method.php',
'ConduitAPI_repository_Method' => 'applications/repository/conduit/ConduitAPI_repository_Method.php',
'ConduitAPI_repository_create_Method' => 'applications/repository/conduit/ConduitAPI_repository_create_Method.php',
'ConduitAPI_repository_query_Method' => 'applications/repository/conduit/ConduitAPI_repository_query_Method.php',
'ConduitAPI_slowvote_Method' => 'applications/slowvote/conduit/ConduitAPI_slowvote_Method.php',
'ConduitAPI_slowvote_info_Method' => 'applications/slowvote/conduit/ConduitAPI_slowvote_info_Method.php',
'ConduitAPI_token_Method' => 'applications/tokens/conduit/ConduitAPI_token_Method.php',
'ConduitAPI_token_give_Method' => 'applications/tokens/conduit/ConduitAPI_token_give_Method.php',
'ConduitAPI_token_given_Method' => 'applications/tokens/conduit/ConduitAPI_token_given_Method.php',
'ConduitAPI_token_query_Method' => 'applications/tokens/conduit/ConduitAPI_token_query_Method.php',
'ConduitAPI_user_Method' => 'applications/people/conduit/ConduitAPI_user_Method.php',
'ConduitAPI_user_addstatus_Method' => 'applications/people/conduit/ConduitAPI_user_addstatus_Method.php',
'ConduitAPI_user_disable_Method' => 'applications/people/conduit/ConduitAPI_user_disable_Method.php',
'ConduitAPI_user_enable_Method' => 'applications/people/conduit/ConduitAPI_user_enable_Method.php',
'ConduitAPI_user_find_Method' => 'applications/people/conduit/ConduitAPI_user_find_Method.php',
'ConduitAPI_user_info_Method' => 'applications/people/conduit/ConduitAPI_user_info_Method.php',
'ConduitAPI_user_query_Method' => 'applications/people/conduit/ConduitAPI_user_query_Method.php',
'ConduitAPI_user_removestatus_Method' => 'applications/people/conduit/ConduitAPI_user_removestatus_Method.php',
'ConduitAPI_user_whoami_Method' => 'applications/people/conduit/ConduitAPI_user_whoami_Method.php',
'ConduitCall' => 'applications/conduit/call/ConduitCall.php',
'ConduitCallTestCase' => 'applications/conduit/call/__tests__/ConduitCallTestCase.php',
'ConduitException' => 'applications/conduit/protocol/ConduitException.php',
'ConduitSSHWorkflow' => 'applications/conduit/ssh/ConduitSSHWorkflow.php',
'ConpherenceConfigOptions' => 'applications/conpherence/config/ConpherenceConfigOptions.php',
'ConpherenceConstants' => 'applications/conpherence/constants/ConpherenceConstants.php',
'ConpherenceController' => 'applications/conpherence/controller/ConpherenceController.php',
'ConpherenceDAO' => 'applications/conpherence/storage/ConpherenceDAO.php',
'ConpherenceEditor' => 'applications/conpherence/editor/ConpherenceEditor.php',
'ConpherenceFileWidgetView' => 'applications/conpherence/view/ConpherenceFileWidgetView.php',
'ConpherenceFormDragAndDropUploadControl' => 'applications/conpherence/view/ConpherenceFormDragAndDropUploadControl.php',
'ConpherenceImageData' => 'applications/conpherence/constants/ConpherenceImageData.php',
'ConpherenceListController' => 'applications/conpherence/controller/ConpherenceListController.php',
'ConpherenceMenuItemView' => 'applications/conpherence/view/ConpherenceMenuItemView.php',
'ConpherenceNewController' => 'applications/conpherence/controller/ConpherenceNewController.php',
'ConpherenceParticipant' => 'applications/conpherence/storage/ConpherenceParticipant.php',
'ConpherenceParticipantQuery' => 'applications/conpherence/query/ConpherenceParticipantQuery.php',
'ConpherenceParticipationStatus' => 'applications/conpherence/constants/ConpherenceParticipationStatus.php',
'ConpherencePeopleMenuEventListener' => 'applications/conpherence/events/ConpherencePeopleMenuEventListener.php',
'ConpherencePontificateControl' => 'applications/conpherence/view/ConpherencePontificateControl.php',
'ConpherenceReplyHandler' => 'applications/conpherence/mail/ConpherenceReplyHandler.php',
'ConpherenceThread' => 'applications/conpherence/storage/ConpherenceThread.php',
'ConpherenceThreadQuery' => 'applications/conpherence/query/ConpherenceThreadQuery.php',
'ConpherenceTransaction' => 'applications/conpherence/storage/ConpherenceTransaction.php',
'ConpherenceTransactionComment' => 'applications/conpherence/storage/ConpherenceTransactionComment.php',
'ConpherenceTransactionQuery' => 'applications/conpherence/query/ConpherenceTransactionQuery.php',
'ConpherenceTransactionType' => 'applications/conpherence/constants/ConpherenceTransactionType.php',
'ConpherenceTransactionView' => 'applications/conpherence/view/ConpherenceTransactionView.php',
'ConpherenceUpdateController' => 'applications/conpherence/controller/ConpherenceUpdateController.php',
'ConpherenceViewController' => 'applications/conpherence/controller/ConpherenceViewController.php',
'ConpherenceWidgetController' => 'applications/conpherence/controller/ConpherenceWidgetController.php',
'DarkConsoleController' => 'aphront/console/DarkConsoleController.php',
'DarkConsoleCore' => 'aphront/console/DarkConsoleCore.php',
'DarkConsoleDataController' => 'aphront/console/DarkConsoleDataController.php',
'DarkConsoleErrorLogPlugin' => 'aphront/console/plugin/DarkConsoleErrorLogPlugin.php',
'DarkConsoleErrorLogPluginAPI' => 'aphront/console/plugin/errorlog/DarkConsoleErrorLogPluginAPI.php',
'DarkConsoleEventPlugin' => 'aphront/console/plugin/DarkConsoleEventPlugin.php',
'DarkConsoleEventPluginAPI' => 'aphront/console/plugin/event/DarkConsoleEventPluginAPI.php',
'DarkConsolePlugin' => 'aphront/console/plugin/DarkConsolePlugin.php',
'DarkConsoleRequestPlugin' => 'aphront/console/plugin/DarkConsoleRequestPlugin.php',
'DarkConsoleServicesPlugin' => 'aphront/console/plugin/DarkConsoleServicesPlugin.php',
'DarkConsoleXHProfPlugin' => 'aphront/console/plugin/DarkConsoleXHProfPlugin.php',
'DarkConsoleXHProfPluginAPI' => 'aphront/console/plugin/xhprof/DarkConsoleXHProfPluginAPI.php',
'DatabaseConfigurationProvider' => 'infrastructure/storage/configuration/DatabaseConfigurationProvider.php',
'DefaultDatabaseConfigurationProvider' => 'infrastructure/storage/configuration/DefaultDatabaseConfigurationProvider.php',
'DifferentialAction' => 'applications/differential/constants/DifferentialAction.php',
'DifferentialActionHasNoEffectException' => 'applications/differential/exception/DifferentialActionHasNoEffectException.php',
'DifferentialAddCommentView' => 'applications/differential/view/DifferentialAddCommentView.php',
'DifferentialAffectedPath' => 'applications/differential/storage/DifferentialAffectedPath.php',
'DifferentialApplyPatchFieldSpecification' => 'applications/differential/field/specification/DifferentialApplyPatchFieldSpecification.php',
'DifferentialArcanistProjectFieldSpecification' => 'applications/differential/field/specification/DifferentialArcanistProjectFieldSpecification.php',
'DifferentialAuditorsFieldSpecification' => 'applications/differential/field/specification/DifferentialAuditorsFieldSpecification.php',
'DifferentialAuthorFieldSpecification' => 'applications/differential/field/specification/DifferentialAuthorFieldSpecification.php',
'DifferentialAuxiliaryField' => 'applications/differential/storage/DifferentialAuxiliaryField.php',
'DifferentialBlameRevisionFieldSpecification' => 'applications/differential/field/specification/DifferentialBlameRevisionFieldSpecification.php',
'DifferentialBranchFieldSpecification' => 'applications/differential/field/specification/DifferentialBranchFieldSpecification.php',
'DifferentialCCWelcomeMail' => 'applications/differential/mail/DifferentialCCWelcomeMail.php',
'DifferentialCCsFieldSpecification' => 'applications/differential/field/specification/DifferentialCCsFieldSpecification.php',
'DifferentialChangeType' => 'applications/differential/constants/DifferentialChangeType.php',
'DifferentialChangeset' => 'applications/differential/storage/DifferentialChangeset.php',
'DifferentialChangesetDetailView' => 'applications/differential/view/DifferentialChangesetDetailView.php',
'DifferentialChangesetFileTreeSideNavBuilder' => 'applications/differential/view/DifferentialChangesetFileTreeSideNavBuilder.php',
'DifferentialChangesetHTMLRenderer' => 'applications/differential/render/DifferentialChangesetHTMLRenderer.php',
'DifferentialChangesetListView' => 'applications/differential/view/DifferentialChangesetListView.php',
'DifferentialChangesetOneUpRenderer' => 'applications/differential/render/DifferentialChangesetOneUpRenderer.php',
'DifferentialChangesetOneUpTestRenderer' => 'applications/differential/render/DifferentialChangesetOneUpTestRenderer.php',
'DifferentialChangesetParser' => 'applications/differential/parser/DifferentialChangesetParser.php',
'DifferentialChangesetParserTestCase' => 'applications/differential/parser/__tests__/DifferentialChangesetParserTestCase.php',
'DifferentialChangesetRenderer' => 'applications/differential/render/DifferentialChangesetRenderer.php',
'DifferentialChangesetTestRenderer' => 'applications/differential/render/DifferentialChangesetTestRenderer.php',
'DifferentialChangesetTwoUpRenderer' => 'applications/differential/render/DifferentialChangesetTwoUpRenderer.php',
'DifferentialChangesetTwoUpTestRenderer' => 'applications/differential/render/DifferentialChangesetTwoUpTestRenderer.php',
'DifferentialChangesetViewController' => 'applications/differential/controller/DifferentialChangesetViewController.php',
'DifferentialComment' => 'applications/differential/storage/DifferentialComment.php',
'DifferentialCommentEditor' => 'applications/differential/editor/DifferentialCommentEditor.php',
'DifferentialCommentMail' => 'applications/differential/mail/DifferentialCommentMail.php',
'DifferentialCommentPreviewController' => 'applications/differential/controller/DifferentialCommentPreviewController.php',
'DifferentialCommentSaveController' => 'applications/differential/controller/DifferentialCommentSaveController.php',
'DifferentialCommitsFieldSpecification' => 'applications/differential/field/specification/DifferentialCommitsFieldSpecification.php',
'DifferentialConflictsFieldSpecification' => 'applications/differential/field/specification/DifferentialConflictsFieldSpecification.php',
'DifferentialController' => 'applications/differential/controller/DifferentialController.php',
'DifferentialDAO' => 'applications/differential/storage/DifferentialDAO.php',
'DifferentialDateCreatedFieldSpecification' => 'applications/differential/field/specification/DifferentialDateCreatedFieldSpecification.php',
'DifferentialDateModifiedFieldSpecification' => 'applications/differential/field/specification/DifferentialDateModifiedFieldSpecification.php',
'DifferentialDefaultFieldSelector' => 'applications/differential/field/selector/DifferentialDefaultFieldSelector.php',
'DifferentialDependenciesFieldSpecification' => 'applications/differential/field/specification/DifferentialDependenciesFieldSpecification.php',
'DifferentialDependsOnFieldSpecification' => 'applications/differential/field/specification/DifferentialDependsOnFieldSpecification.php',
'DifferentialDiff' => 'applications/differential/storage/DifferentialDiff.php',
'DifferentialDiffContentMail' => 'applications/differential/mail/DifferentialDiffContentMail.php',
'DifferentialDiffCreateController' => 'applications/differential/controller/DifferentialDiffCreateController.php',
'DifferentialDiffProperty' => 'applications/differential/storage/DifferentialDiffProperty.php',
'DifferentialDiffTableOfContentsView' => 'applications/differential/view/DifferentialDiffTableOfContentsView.php',
'DifferentialDiffTestCase' => 'applications/differential/storage/__tests__/DifferentialDiffTestCase.php',
'DifferentialDiffViewController' => 'applications/differential/controller/DifferentialDiffViewController.php',
'DifferentialException' => 'applications/differential/exception/DifferentialException.php',
'DifferentialExceptionMail' => 'applications/differential/mail/DifferentialExceptionMail.php',
'DifferentialExportPatchFieldSpecification' => 'applications/differential/field/specification/DifferentialExportPatchFieldSpecification.php',
'DifferentialFieldDataNotAvailableException' => 'applications/differential/field/exception/DifferentialFieldDataNotAvailableException.php',
'DifferentialFieldParseException' => 'applications/differential/field/exception/DifferentialFieldParseException.php',
'DifferentialFieldSelector' => 'applications/differential/field/selector/DifferentialFieldSelector.php',
'DifferentialFieldSpecification' => 'applications/differential/field/specification/DifferentialFieldSpecification.php',
'DifferentialFieldSpecificationIncompleteException' => 'applications/differential/field/exception/DifferentialFieldSpecificationIncompleteException.php',
'DifferentialFieldValidationException' => 'applications/differential/field/exception/DifferentialFieldValidationException.php',
'DifferentialFreeformFieldSpecification' => 'applications/differential/field/specification/DifferentialFreeformFieldSpecification.php',
'DifferentialGitSVNIDFieldSpecification' => 'applications/differential/field/specification/DifferentialGitSVNIDFieldSpecification.php',
'DifferentialHostFieldSpecification' => 'applications/differential/field/specification/DifferentialHostFieldSpecification.php',
'DifferentialHunk' => 'applications/differential/storage/DifferentialHunk.php',
'DifferentialHunkParser' => 'applications/differential/parser/DifferentialHunkParser.php',
'DifferentialHunkParserTestCase' => 'applications/differential/parser/__tests__/DifferentialHunkParserTestCase.php',
'DifferentialHunkTestCase' => 'applications/differential/storage/__tests__/DifferentialHunkTestCase.php',
'DifferentialInlineComment' => 'applications/differential/storage/DifferentialInlineComment.php',
'DifferentialInlineCommentEditController' => 'applications/differential/controller/DifferentialInlineCommentEditController.php',
'DifferentialInlineCommentEditView' => 'applications/differential/view/DifferentialInlineCommentEditView.php',
'DifferentialInlineCommentPreviewController' => 'applications/differential/controller/DifferentialInlineCommentPreviewController.php',
'DifferentialInlineCommentView' => 'applications/differential/view/DifferentialInlineCommentView.php',
'DifferentialLinesFieldSpecification' => 'applications/differential/field/specification/DifferentialLinesFieldSpecification.php',
'DifferentialLintFieldSpecification' => 'applications/differential/field/specification/DifferentialLintFieldSpecification.php',
'DifferentialLintStatus' => 'applications/differential/constants/DifferentialLintStatus.php',
'DifferentialLocalCommitsView' => 'applications/differential/view/DifferentialLocalCommitsView.php',
'DifferentialMail' => 'applications/differential/mail/DifferentialMail.php',
'DifferentialMailPhase' => 'applications/differential/constants/DifferentialMailPhase.php',
'DifferentialManiphestTasksFieldSpecification' => 'applications/differential/field/specification/DifferentialManiphestTasksFieldSpecification.php',
'DifferentialNewDiffMail' => 'applications/differential/mail/DifferentialNewDiffMail.php',
'DifferentialParseRenderTestCase' => 'applications/differential/__tests__/DifferentialParseRenderTestCase.php',
'DifferentialPathFieldSpecification' => 'applications/differential/field/specification/DifferentialPathFieldSpecification.php',
'DifferentialPeopleMenuEventListener' => 'applications/differential/events/DifferentialPeopleMenuEventListener.php',
'DifferentialPrimaryPaneView' => 'applications/differential/view/DifferentialPrimaryPaneView.php',
+ 'DifferentialReleephRequestFieldSpecification' => 'applications/releeph/differential/DifferentialReleephRequestFieldSpecification.php',
'DifferentialRemarkupRule' => 'applications/differential/remarkup/DifferentialRemarkupRule.php',
'DifferentialReplyHandler' => 'applications/differential/DifferentialReplyHandler.php',
'DifferentialResultsTableView' => 'applications/differential/view/DifferentialResultsTableView.php',
'DifferentialRevertPlanFieldSpecification' => 'applications/differential/field/specification/DifferentialRevertPlanFieldSpecification.php',
'DifferentialReviewRequestMail' => 'applications/differential/mail/DifferentialReviewRequestMail.php',
'DifferentialReviewedByFieldSpecification' => 'applications/differential/field/specification/DifferentialReviewedByFieldSpecification.php',
'DifferentialReviewerStats' => 'applications/differential/stats/DifferentialReviewerStats.php',
'DifferentialReviewerStatsTestCase' => 'applications/differential/stats/__tests__/DifferentialReviewerStatsTestCase.php',
'DifferentialReviewersFieldSpecification' => 'applications/differential/field/specification/DifferentialReviewersFieldSpecification.php',
'DifferentialRevision' => 'applications/differential/storage/DifferentialRevision.php',
'DifferentialRevisionCommentListView' => 'applications/differential/view/DifferentialRevisionCommentListView.php',
'DifferentialRevisionCommentView' => 'applications/differential/view/DifferentialRevisionCommentView.php',
'DifferentialRevisionControlSystem' => 'applications/differential/constants/DifferentialRevisionControlSystem.php',
'DifferentialRevisionDetailRenderer' => 'applications/differential/controller/DifferentialRevisionDetailRenderer.php',
'DifferentialRevisionDetailView' => 'applications/differential/view/DifferentialRevisionDetailView.php',
'DifferentialRevisionEditController' => 'applications/differential/controller/DifferentialRevisionEditController.php',
'DifferentialRevisionEditor' => 'applications/differential/editor/DifferentialRevisionEditor.php',
'DifferentialRevisionIDFieldParserTestCase' => 'applications/differential/field/specification/__tests__/DifferentialRevisionIDFieldParserTestCase.php',
'DifferentialRevisionIDFieldSpecification' => 'applications/differential/field/specification/DifferentialRevisionIDFieldSpecification.php',
'DifferentialRevisionListController' => 'applications/differential/controller/DifferentialRevisionListController.php',
'DifferentialRevisionListData' => 'applications/differential/data/DifferentialRevisionListData.php',
'DifferentialRevisionListView' => 'applications/differential/view/DifferentialRevisionListView.php',
'DifferentialRevisionQuery' => 'applications/differential/query/DifferentialRevisionQuery.php',
'DifferentialRevisionStatsController' => 'applications/differential/controller/DifferentialRevisionStatsController.php',
'DifferentialRevisionStatsView' => 'applications/differential/view/DifferentialRevisionStatsView.php',
'DifferentialRevisionStatus' => 'applications/differential/constants/DifferentialRevisionStatus.php',
'DifferentialRevisionStatusFieldSpecification' => 'applications/differential/field/specification/DifferentialRevisionStatusFieldSpecification.php',
'DifferentialRevisionUpdateHistoryView' => 'applications/differential/view/DifferentialRevisionUpdateHistoryView.php',
'DifferentialRevisionViewController' => 'applications/differential/controller/DifferentialRevisionViewController.php',
'DifferentialSearchIndexer' => 'applications/differential/search/DifferentialSearchIndexer.php',
'DifferentialSubscribeController' => 'applications/differential/controller/DifferentialSubscribeController.php',
'DifferentialSummaryFieldSpecification' => 'applications/differential/field/specification/DifferentialSummaryFieldSpecification.php',
'DifferentialTasksAttacher' => 'applications/differential/DifferentialTasksAttacher.php',
'DifferentialTestPlanFieldSpecification' => 'applications/differential/field/specification/DifferentialTestPlanFieldSpecification.php',
'DifferentialTitleFieldSpecification' => 'applications/differential/field/specification/DifferentialTitleFieldSpecification.php',
'DifferentialUnitFieldSpecification' => 'applications/differential/field/specification/DifferentialUnitFieldSpecification.php',
'DifferentialUnitStatus' => 'applications/differential/constants/DifferentialUnitStatus.php',
'DifferentialUnitTestResult' => 'applications/differential/constants/DifferentialUnitTestResult.php',
'DiffusionBranchInformation' => 'applications/diffusion/data/DiffusionBranchInformation.php',
'DiffusionBranchQuery' => 'applications/diffusion/query/branch/DiffusionBranchQuery.php',
'DiffusionBranchTableController' => 'applications/diffusion/controller/DiffusionBranchTableController.php',
'DiffusionBranchTableView' => 'applications/diffusion/view/DiffusionBranchTableView.php',
'DiffusionBrowseController' => 'applications/diffusion/controller/DiffusionBrowseController.php',
'DiffusionBrowseFileController' => 'applications/diffusion/controller/DiffusionBrowseFileController.php',
'DiffusionBrowseQuery' => 'applications/diffusion/query/browse/DiffusionBrowseQuery.php',
'DiffusionBrowseTableView' => 'applications/diffusion/view/DiffusionBrowseTableView.php',
'DiffusionChangeController' => 'applications/diffusion/controller/DiffusionChangeController.php',
'DiffusionCommentListView' => 'applications/diffusion/view/DiffusionCommentListView.php',
'DiffusionCommentView' => 'applications/diffusion/view/DiffusionCommentView.php',
'DiffusionCommitBranchesController' => 'applications/diffusion/controller/DiffusionCommitBranchesController.php',
'DiffusionCommitChangeTableView' => 'applications/diffusion/view/DiffusionCommitChangeTableView.php',
'DiffusionCommitController' => 'applications/diffusion/controller/DiffusionCommitController.php',
'DiffusionCommitEditController' => 'applications/diffusion/controller/DiffusionCommitEditController.php',
'DiffusionCommitParentsQuery' => 'applications/diffusion/query/parents/DiffusionCommitParentsQuery.php',
'DiffusionCommitQuery' => 'applications/diffusion/query/DiffusionCommitQuery.php',
'DiffusionCommitTagsController' => 'applications/diffusion/controller/DiffusionCommitTagsController.php',
'DiffusionCommitTagsQuery' => 'applications/diffusion/query/committags/DiffusionCommitTagsQuery.php',
'DiffusionContainsQuery' => 'applications/diffusion/query/contains/DiffusionContainsQuery.php',
'DiffusionController' => 'applications/diffusion/controller/DiffusionController.php',
'DiffusionDiffController' => 'applications/diffusion/controller/DiffusionDiffController.php',
'DiffusionDiffQuery' => 'applications/diffusion/query/diff/DiffusionDiffQuery.php',
'DiffusionEmptyResultView' => 'applications/diffusion/view/DiffusionEmptyResultView.php',
'DiffusionExistsQuery' => 'applications/diffusion/query/exists/DiffusionExistsQuery.php',
'DiffusionExternalController' => 'applications/diffusion/controller/DiffusionExternalController.php',
'DiffusionFileContent' => 'applications/diffusion/data/DiffusionFileContent.php',
'DiffusionFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionFileContentQuery.php',
'DiffusionGitBranchQuery' => 'applications/diffusion/query/branch/DiffusionGitBranchQuery.php',
'DiffusionGitBranchQueryTestCase' => 'applications/diffusion/query/branch/__tests__/DiffusionGitBranchQueryTestCase.php',
'DiffusionGitBrowseQuery' => 'applications/diffusion/query/browse/DiffusionGitBrowseQuery.php',
'DiffusionGitCommitParentsQuery' => 'applications/diffusion/query/parents/DiffusionGitCommitParentsQuery.php',
'DiffusionGitCommitTagsQuery' => 'applications/diffusion/query/committags/DiffusionGitCommitTagsQuery.php',
'DiffusionGitContainsQuery' => 'applications/diffusion/query/contains/DiffusionGitContainsQuery.php',
'DiffusionGitDiffQuery' => 'applications/diffusion/query/diff/DiffusionGitDiffQuery.php',
'DiffusionGitExistsQuery' => 'applications/diffusion/query/exists/DiffusionGitExistsQuery.php',
'DiffusionGitFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionGitFileContentQuery.php',
'DiffusionGitHistoryQuery' => 'applications/diffusion/query/history/DiffusionGitHistoryQuery.php',
'DiffusionGitLastModifiedQuery' => 'applications/diffusion/query/lastmodified/DiffusionGitLastModifiedQuery.php',
'DiffusionGitMergedCommitsQuery' => 'applications/diffusion/query/mergedcommits/DiffusionGitMergedCommitsQuery.php',
'DiffusionGitRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionGitRawDiffQuery.php',
'DiffusionGitRequest' => 'applications/diffusion/request/DiffusionGitRequest.php',
'DiffusionGitTagListQuery' => 'applications/diffusion/query/taglist/DiffusionGitTagListQuery.php',
'DiffusionHistoryController' => 'applications/diffusion/controller/DiffusionHistoryController.php',
'DiffusionHistoryQuery' => 'applications/diffusion/query/history/DiffusionHistoryQuery.php',
'DiffusionHistoryTableView' => 'applications/diffusion/view/DiffusionHistoryTableView.php',
'DiffusionHomeController' => 'applications/diffusion/controller/DiffusionHomeController.php',
'DiffusionInlineCommentController' => 'applications/diffusion/controller/DiffusionInlineCommentController.php',
'DiffusionInlineCommentPreviewController' => 'applications/diffusion/controller/DiffusionInlineCommentPreviewController.php',
'DiffusionLastModifiedController' => 'applications/diffusion/controller/DiffusionLastModifiedController.php',
'DiffusionLastModifiedQuery' => 'applications/diffusion/query/lastmodified/DiffusionLastModifiedQuery.php',
'DiffusionLintController' => 'applications/diffusion/controller/DiffusionLintController.php',
'DiffusionLintDetailsController' => 'applications/diffusion/controller/DiffusionLintDetailsController.php',
'DiffusionLintSaveRunner' => 'applications/diffusion/DiffusionLintSaveRunner.php',
'DiffusionMercurialBranchQuery' => 'applications/diffusion/query/branch/DiffusionMercurialBranchQuery.php',
'DiffusionMercurialBrowseQuery' => 'applications/diffusion/query/browse/DiffusionMercurialBrowseQuery.php',
'DiffusionMercurialCommitParentsQuery' => 'applications/diffusion/query/parents/DiffusionMercurialCommitParentsQuery.php',
'DiffusionMercurialCommitTagsQuery' => 'applications/diffusion/query/committags/DiffusionMercurialCommitTagsQuery.php',
'DiffusionMercurialContainsQuery' => 'applications/diffusion/query/contains/DiffusionMercurialContainsQuery.php',
'DiffusionMercurialDiffQuery' => 'applications/diffusion/query/diff/DiffusionMercurialDiffQuery.php',
'DiffusionMercurialExistsQuery' => 'applications/diffusion/query/exists/DiffusionMercurialExistsQuery.php',
'DiffusionMercurialFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionMercurialFileContentQuery.php',
'DiffusionMercurialHistoryQuery' => 'applications/diffusion/query/history/DiffusionMercurialHistoryQuery.php',
'DiffusionMercurialLastModifiedQuery' => 'applications/diffusion/query/lastmodified/DiffusionMercurialLastModifiedQuery.php',
'DiffusionMercurialMergedCommitsQuery' => 'applications/diffusion/query/mergedcommits/DiffusionMercurialMergedCommitsQuery.php',
'DiffusionMercurialRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionMercurialRawDiffQuery.php',
'DiffusionMercurialRequest' => 'applications/diffusion/request/DiffusionMercurialRequest.php',
'DiffusionMercurialTagListQuery' => 'applications/diffusion/query/taglist/DiffusionMercurialTagListQuery.php',
'DiffusionMergedCommitsQuery' => 'applications/diffusion/query/mergedcommits/DiffusionMergedCommitsQuery.php',
'DiffusionPathChange' => 'applications/diffusion/data/DiffusionPathChange.php',
'DiffusionPathChangeQuery' => 'applications/diffusion/query/pathchange/DiffusionPathChangeQuery.php',
'DiffusionPathCompleteController' => 'applications/diffusion/controller/DiffusionPathCompleteController.php',
'DiffusionPathIDQuery' => 'applications/diffusion/query/pathid/DiffusionPathIDQuery.php',
'DiffusionPathQuery' => 'applications/diffusion/query/DiffusionPathQuery.php',
'DiffusionPathQueryTestCase' => 'applications/diffusion/query/pathid/__tests__/DiffusionPathQueryTestCase.php',
'DiffusionPathValidateController' => 'applications/diffusion/controller/DiffusionPathValidateController.php',
'DiffusionPeopleMenuEventListener' => 'applications/diffusion/events/DiffusionPeopleMenuEventListener.php',
'DiffusionQuery' => 'applications/diffusion/query/DiffusionQuery.php',
'DiffusionRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionRawDiffQuery.php',
'DiffusionRemarkupRule' => 'applications/diffusion/remarkup/DiffusionRemarkupRule.php',
'DiffusionRenameHistoryQuery' => 'applications/diffusion/query/DiffusionRenameHistoryQuery.php',
'DiffusionRepositoryController' => 'applications/diffusion/controller/DiffusionRepositoryController.php',
'DiffusionRepositoryPath' => 'applications/diffusion/data/DiffusionRepositoryPath.php',
'DiffusionRepositoryTag' => 'applications/diffusion/DiffusionRepositoryTag.php',
'DiffusionRequest' => 'applications/diffusion/request/DiffusionRequest.php',
'DiffusionSetupException' => 'applications/diffusion/exception/DiffusionSetupException.php',
'DiffusionSvnBrowseQuery' => 'applications/diffusion/query/browse/DiffusionSvnBrowseQuery.php',
'DiffusionSvnCommitParentsQuery' => 'applications/diffusion/query/parents/DiffusionSvnCommitParentsQuery.php',
'DiffusionSvnCommitTagsQuery' => 'applications/diffusion/query/committags/DiffusionSvnCommitTagsQuery.php',
'DiffusionSvnContainsQuery' => 'applications/diffusion/query/contains/DiffusionSvnContainsQuery.php',
'DiffusionSvnDiffQuery' => 'applications/diffusion/query/diff/DiffusionSvnDiffQuery.php',
'DiffusionSvnExistsQuery' => 'applications/diffusion/query/exists/DiffusionSvnExistsQuery.php',
'DiffusionSvnFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionSvnFileContentQuery.php',
'DiffusionSvnHistoryQuery' => 'applications/diffusion/query/history/DiffusionSvnHistoryQuery.php',
'DiffusionSvnLastModifiedQuery' => 'applications/diffusion/query/lastmodified/DiffusionSvnLastModifiedQuery.php',
'DiffusionSvnMergedCommitsQuery' => 'applications/diffusion/query/mergedcommits/DiffusionSvnMergedCommitsQuery.php',
'DiffusionSvnRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionSvnRawDiffQuery.php',
'DiffusionSvnRequest' => 'applications/diffusion/request/DiffusionSvnRequest.php',
'DiffusionSvnTagListQuery' => 'applications/diffusion/query/taglist/DiffusionSvnTagListQuery.php',
'DiffusionSymbolController' => 'applications/diffusion/controller/DiffusionSymbolController.php',
'DiffusionSymbolQuery' => 'applications/diffusion/query/DiffusionSymbolQuery.php',
'DiffusionTagListController' => 'applications/diffusion/controller/DiffusionTagListController.php',
'DiffusionTagListQuery' => 'applications/diffusion/query/taglist/DiffusionTagListQuery.php',
'DiffusionTagListView' => 'applications/diffusion/view/DiffusionTagListView.php',
'DiffusionURITestCase' => 'applications/diffusion/request/__tests__/DiffusionURITestCase.php',
'DiffusionView' => 'applications/diffusion/view/DiffusionView.php',
'DivinerArticleAtomizer' => 'applications/diviner/atomizer/DivinerArticleAtomizer.php',
'DivinerAtom' => 'applications/diviner/atom/DivinerAtom.php',
'DivinerAtomCache' => 'applications/diviner/cache/DivinerAtomCache.php',
'DivinerAtomRef' => 'applications/diviner/atom/DivinerAtomRef.php',
'DivinerAtomizeWorkflow' => 'applications/diviner/workflow/DivinerAtomizeWorkflow.php',
'DivinerAtomizer' => 'applications/diviner/atomizer/DivinerAtomizer.php',
'DivinerDefaultRenderer' => 'applications/diviner/renderer/DivinerDefaultRenderer.php',
'DivinerDiskCache' => 'applications/diviner/cache/DivinerDiskCache.php',
'DivinerFileAtomizer' => 'applications/diviner/atomizer/DivinerFileAtomizer.php',
'DivinerGenerateWorkflow' => 'applications/diviner/workflow/DivinerGenerateWorkflow.php',
'DivinerListController' => 'applications/diviner/controller/DivinerListController.php',
'DivinerPublishCache' => 'applications/diviner/cache/DivinerPublishCache.php',
'DivinerPublisher' => 'applications/diviner/publisher/DivinerPublisher.php',
'DivinerRemarkupRuleSymbol' => 'applications/diviner/markup/DivinerRemarkupRuleSymbol.php',
'DivinerRenderer' => 'applications/diviner/renderer/DivinerRenderer.php',
'DivinerStaticPublisher' => 'applications/diviner/publisher/DivinerStaticPublisher.php',
'DivinerWorkflow' => 'applications/diviner/workflow/DivinerWorkflow.php',
'DrydockAllocatorWorker' => 'applications/drydock/worker/DrydockAllocatorWorker.php',
'DrydockApacheWebrootInterface' => 'applications/drydock/interface/webroot/DrydockApacheWebrootInterface.php',
'DrydockBlueprint' => 'applications/drydock/blueprint/DrydockBlueprint.php',
'DrydockBlueprintScopeGuard' => 'applications/drydock/util/DrydockBlueprintScopeGuard.php',
'DrydockCommandInterface' => 'applications/drydock/interface/command/DrydockCommandInterface.php',
'DrydockConstants' => 'applications/drydock/constants/DrydockConstants.php',
'DrydockController' => 'applications/drydock/controller/DrydockController.php',
'DrydockDAO' => 'applications/drydock/storage/DrydockDAO.php',
'DrydockInterface' => 'applications/drydock/interface/DrydockInterface.php',
'DrydockLease' => 'applications/drydock/storage/DrydockLease.php',
'DrydockLeaseListController' => 'applications/drydock/controller/DrydockLeaseListController.php',
'DrydockLeaseQuery' => 'applications/drydock/query/DrydockLeaseQuery.php',
'DrydockLeaseReleaseController' => 'applications/drydock/controller/DrydockLeaseReleaseController.php',
'DrydockLeaseStatus' => 'applications/drydock/constants/DrydockLeaseStatus.php',
'DrydockLeaseViewController' => 'applications/drydock/controller/DrydockLeaseViewController.php',
'DrydockLocalCommandInterface' => 'applications/drydock/interface/command/DrydockLocalCommandInterface.php',
'DrydockLocalHostBlueprint' => 'applications/drydock/blueprint/DrydockLocalHostBlueprint.php',
'DrydockLog' => 'applications/drydock/storage/DrydockLog.php',
'DrydockLogController' => 'applications/drydock/controller/DrydockLogController.php',
'DrydockLogQuery' => 'applications/drydock/query/DrydockLogQuery.php',
'DrydockManagementCloseWorkflow' => 'applications/drydock/management/DrydockManagementCloseWorkflow.php',
'DrydockManagementLeaseWorkflow' => 'applications/drydock/management/DrydockManagementLeaseWorkflow.php',
'DrydockManagementReleaseWorkflow' => 'applications/drydock/management/DrydockManagementReleaseWorkflow.php',
'DrydockManagementWaitForLeaseWorkflow' => 'applications/drydock/management/DrydockManagementWaitForLeaseWorkflow.php',
'DrydockManagementWorkflow' => 'applications/drydock/management/DrydockManagementWorkflow.php',
'DrydockResource' => 'applications/drydock/storage/DrydockResource.php',
'DrydockResourceCloseController' => 'applications/drydock/controller/DrydockResourceCloseController.php',
'DrydockResourceListController' => 'applications/drydock/controller/DrydockResourceListController.php',
'DrydockResourceQuery' => 'applications/drydock/query/DrydockResourceQuery.php',
'DrydockResourceStatus' => 'applications/drydock/constants/DrydockResourceStatus.php',
'DrydockResourceViewController' => 'applications/drydock/controller/DrydockResourceViewController.php',
'DrydockSSHCommandInterface' => 'applications/drydock/interface/command/DrydockSSHCommandInterface.php',
'DrydockWebrootInterface' => 'applications/drydock/interface/webroot/DrydockWebrootInterface.php',
'DrydockWorkingCopyBlueprint' => 'applications/drydock/blueprint/DrydockWorkingCopyBlueprint.php',
'FeedPublisherWorker' => 'applications/feed/worker/FeedPublisherWorker.php',
'HarbormasterDAO' => 'applications/harbormaster/storage/HarbormasterDAO.php',
'HarbormasterObject' => 'applications/harbormaster/storage/HarbormasterObject.php',
'HarbormasterRunnerWorker' => 'applications/harbormaster/worker/HarbormasterRunnerWorker.php',
'HarbormasterScratchTable' => 'applications/harbormaster/storage/HarbormasterScratchTable.php',
'HeraldAction' => 'applications/herald/storage/HeraldAction.php',
'HeraldActionConfig' => 'applications/herald/config/HeraldActionConfig.php',
'HeraldApplyTranscript' => 'applications/herald/storage/transcript/HeraldApplyTranscript.php',
'HeraldCommitAdapter' => 'applications/herald/adapter/HeraldCommitAdapter.php',
'HeraldCondition' => 'applications/herald/storage/HeraldCondition.php',
'HeraldConditionConfig' => 'applications/herald/config/HeraldConditionConfig.php',
'HeraldConditionTranscript' => 'applications/herald/storage/transcript/HeraldConditionTranscript.php',
'HeraldContentTypeConfig' => 'applications/herald/config/HeraldContentTypeConfig.php',
'HeraldController' => 'applications/herald/controller/HeraldController.php',
'HeraldDAO' => 'applications/herald/storage/HeraldDAO.php',
'HeraldDeleteController' => 'applications/herald/controller/HeraldDeleteController.php',
'HeraldDifferentialRevisionAdapter' => 'applications/herald/adapter/HeraldDifferentialRevisionAdapter.php',
'HeraldDryRunAdapter' => 'applications/herald/adapter/HeraldDryRunAdapter.php',
'HeraldEditLogQuery' => 'applications/herald/query/HeraldEditLogQuery.php',
'HeraldEffect' => 'applications/herald/engine/HeraldEffect.php',
'HeraldEngine' => 'applications/herald/engine/HeraldEngine.php',
'HeraldFieldConfig' => 'applications/herald/config/HeraldFieldConfig.php',
'HeraldHomeController' => 'applications/herald/controller/HeraldHomeController.php',
'HeraldInvalidConditionException' => 'applications/herald/engine/engine/HeraldInvalidConditionException.php',
'HeraldInvalidFieldException' => 'applications/herald/engine/engine/HeraldInvalidFieldException.php',
'HeraldNewController' => 'applications/herald/controller/HeraldNewController.php',
'HeraldObjectAdapter' => 'applications/herald/adapter/HeraldObjectAdapter.php',
'HeraldObjectTranscript' => 'applications/herald/storage/transcript/HeraldObjectTranscript.php',
'HeraldRecursiveConditionsException' => 'applications/herald/engine/engine/HeraldRecursiveConditionsException.php',
'HeraldRepetitionPolicyConfig' => 'applications/herald/config/HeraldRepetitionPolicyConfig.php',
'HeraldRule' => 'applications/herald/storage/HeraldRule.php',
'HeraldRuleController' => 'applications/herald/controller/HeraldRuleController.php',
'HeraldRuleEdit' => 'applications/herald/storage/HeraldRuleEdit.php',
'HeraldRuleEditHistoryController' => 'applications/herald/controller/HeraldRuleEditHistoryController.php',
'HeraldRuleEditHistoryView' => 'applications/herald/view/HeraldRuleEditHistoryView.php',
'HeraldRuleListView' => 'applications/herald/view/HeraldRuleListView.php',
'HeraldRuleQuery' => 'applications/herald/query/HeraldRuleQuery.php',
'HeraldRuleTranscript' => 'applications/herald/storage/transcript/HeraldRuleTranscript.php',
'HeraldRuleTypeConfig' => 'applications/herald/config/HeraldRuleTypeConfig.php',
'HeraldTestConsoleController' => 'applications/herald/controller/HeraldTestConsoleController.php',
'HeraldTranscript' => 'applications/herald/storage/transcript/HeraldTranscript.php',
'HeraldTranscriptController' => 'applications/herald/controller/HeraldTranscriptController.php',
'HeraldTranscriptListController' => 'applications/herald/controller/HeraldTranscriptListController.php',
'HeraldValueTypeConfig' => 'applications/herald/config/HeraldValueTypeConfig.php',
'Javelin' => 'infrastructure/javelin/Javelin.php',
'JavelinReactorExample' => 'applications/uiexample/examples/JavelinReactorExample.php',
'JavelinUIExample' => 'applications/uiexample/examples/JavelinUIExample.php',
'JavelinViewExample' => 'applications/uiexample/examples/JavelinViewExample.php',
'JavelinViewExampleServerView' => 'applications/uiexample/examples/JavelinViewExampleServerView.php',
'LiskChunkTestCase' => 'infrastructure/storage/lisk/__tests__/LiskChunkTestCase.php',
'LiskDAO' => 'infrastructure/storage/lisk/LiskDAO.php',
'LiskDAOSet' => 'infrastructure/storage/lisk/LiskDAOSet.php',
'LiskDAOTestCase' => 'infrastructure/storage/lisk/__tests__/LiskDAOTestCase.php',
'LiskEphemeralObjectException' => 'infrastructure/storage/lisk/LiskEphemeralObjectException.php',
'LiskFixtureTestCase' => 'infrastructure/storage/lisk/__tests__/LiskFixtureTestCase.php',
'LiskIsolationTestCase' => 'infrastructure/storage/lisk/__tests__/LiskIsolationTestCase.php',
'LiskIsolationTestDAO' => 'infrastructure/storage/lisk/__tests__/LiskIsolationTestDAO.php',
'LiskIsolationTestDAOException' => 'infrastructure/storage/lisk/__tests__/LiskIsolationTestDAOException.php',
'LiskMigrationIterator' => 'infrastructure/storage/lisk/LiskMigrationIterator.php',
'ManiphestAction' => 'applications/maniphest/constants/ManiphestAction.php',
'ManiphestAuxiliaryFieldDefaultSpecification' => 'applications/maniphest/auxiliaryfield/ManiphestAuxiliaryFieldDefaultSpecification.php',
'ManiphestAuxiliaryFieldSpecification' => 'applications/maniphest/auxiliaryfield/ManiphestAuxiliaryFieldSpecification.php',
'ManiphestAuxiliaryFieldTypeException' => 'applications/maniphest/auxiliaryfield/ManiphestAuxiliaryFieldTypeException.php',
'ManiphestAuxiliaryFieldValidationException' => 'applications/maniphest/auxiliaryfield/ManiphestAuxiliaryFieldValidationException.php',
'ManiphestBatchEditController' => 'applications/maniphest/controller/ManiphestBatchEditController.php',
'ManiphestConstants' => 'applications/maniphest/constants/ManiphestConstants.php',
'ManiphestController' => 'applications/maniphest/controller/ManiphestController.php',
'ManiphestDAO' => 'applications/maniphest/storage/ManiphestDAO.php',
'ManiphestDefaultTaskExtensions' => 'applications/maniphest/extensions/ManiphestDefaultTaskExtensions.php',
'ManiphestEdgeEventListener' => 'applications/maniphest/event/ManiphestEdgeEventListener.php',
'ManiphestExportController' => 'applications/maniphest/controller/ManiphestExportController.php',
'ManiphestPeopleMenuEventListener' => 'applications/maniphest/event/ManiphestPeopleMenuEventListener.php',
'ManiphestRemarkupRule' => 'applications/maniphest/remarkup/ManiphestRemarkupRule.php',
'ManiphestReplyHandler' => 'applications/maniphest/ManiphestReplyHandler.php',
'ManiphestReportController' => 'applications/maniphest/controller/ManiphestReportController.php',
'ManiphestSavedQuery' => 'applications/maniphest/storage/ManiphestSavedQuery.php',
'ManiphestSavedQueryDeleteController' => 'applications/maniphest/controller/ManiphestSavedQueryDeleteController.php',
'ManiphestSavedQueryEditController' => 'applications/maniphest/controller/ManiphestSavedQueryEditController.php',
'ManiphestSavedQueryListController' => 'applications/maniphest/controller/ManiphestSavedQueryListController.php',
'ManiphestSearchIndexer' => 'applications/maniphest/search/ManiphestSearchIndexer.php',
'ManiphestSubpriorityController' => 'applications/maniphest/controller/ManiphestSubpriorityController.php',
'ManiphestTask' => 'applications/maniphest/storage/ManiphestTask.php',
'ManiphestTaskAuxiliaryStorage' => 'applications/maniphest/storage/ManiphestTaskAuxiliaryStorage.php',
'ManiphestTaskDescriptionChangeController' => 'applications/maniphest/controller/ManiphestTaskDescriptionChangeController.php',
'ManiphestTaskDescriptionPreviewController' => 'applications/maniphest/controller/ManiphestTaskDescriptionPreviewController.php',
'ManiphestTaskDetailController' => 'applications/maniphest/controller/ManiphestTaskDetailController.php',
'ManiphestTaskEditController' => 'applications/maniphest/controller/ManiphestTaskEditController.php',
'ManiphestTaskExtensions' => 'applications/maniphest/extensions/ManiphestTaskExtensions.php',
'ManiphestTaskListController' => 'applications/maniphest/controller/ManiphestTaskListController.php',
'ManiphestTaskListView' => 'applications/maniphest/view/ManiphestTaskListView.php',
'ManiphestTaskOwner' => 'applications/maniphest/constants/ManiphestTaskOwner.php',
'ManiphestTaskPriority' => 'applications/maniphest/constants/ManiphestTaskPriority.php',
'ManiphestTaskProject' => 'applications/maniphest/storage/ManiphestTaskProject.php',
'ManiphestTaskProjectsView' => 'applications/maniphest/view/ManiphestTaskProjectsView.php',
'ManiphestTaskQuery' => 'applications/maniphest/ManiphestTaskQuery.php',
'ManiphestTaskStatus' => 'applications/maniphest/constants/ManiphestTaskStatus.php',
'ManiphestTaskSubscriber' => 'applications/maniphest/storage/ManiphestTaskSubscriber.php',
'ManiphestTaskSummaryView' => 'applications/maniphest/view/ManiphestTaskSummaryView.php',
'ManiphestTransaction' => 'applications/maniphest/storage/ManiphestTransaction.php',
'ManiphestTransactionDetailView' => 'applications/maniphest/view/ManiphestTransactionDetailView.php',
'ManiphestTransactionEditor' => 'applications/maniphest/editor/ManiphestTransactionEditor.php',
'ManiphestTransactionListView' => 'applications/maniphest/view/ManiphestTransactionListView.php',
'ManiphestTransactionPreviewController' => 'applications/maniphest/controller/ManiphestTransactionPreviewController.php',
'ManiphestTransactionSaveController' => 'applications/maniphest/controller/ManiphestTransactionSaveController.php',
'ManiphestTransactionType' => 'applications/maniphest/constants/ManiphestTransactionType.php',
'ManiphestView' => 'applications/maniphest/view/ManiphestView.php',
'MetaMTAConstants' => 'applications/metamta/constants/MetaMTAConstants.php',
'MetaMTANotificationType' => 'applications/metamta/constants/MetaMTANotificationType.php',
'ObjectHandleLoader' => 'applications/phid/handle/ObjectHandleLoader.php',
'OwnersPackageReplyHandler' => 'applications/owners/OwnersPackageReplyHandler.php',
'PackageCreateMail' => 'applications/owners/mail/PackageCreateMail.php',
'PackageDeleteMail' => 'applications/owners/mail/PackageDeleteMail.php',
'PackageMail' => 'applications/owners/mail/PackageMail.php',
'PackageModifyMail' => 'applications/owners/mail/PackageModifyMail.php',
'PasteEmbedView' => 'applications/paste/view/PasteEmbedView.php',
'Phabricator404Controller' => 'applications/base/controller/Phabricator404Controller.php',
'PhabricatorAWSConfigOptions' => 'applications/config/option/PhabricatorAWSConfigOptions.php',
'PhabricatorAccessLog' => 'infrastructure/PhabricatorAccessLog.php',
'PhabricatorAccessLogConfigOptions' => 'applications/config/option/PhabricatorAccessLogConfigOptions.php',
'PhabricatorActionListExample' => 'applications/uiexample/examples/PhabricatorActionListExample.php',
'PhabricatorActionListView' => 'view/layout/PhabricatorActionListView.php',
'PhabricatorActionView' => 'view/layout/PhabricatorActionView.php',
'PhabricatorAllCapsTranslation' => 'infrastructure/internationalization/PhabricatorAllCapsTranslation.php',
'PhabricatorAnchorView' => 'view/layout/PhabricatorAnchorView.php',
'PhabricatorAphrontBarExample' => 'applications/uiexample/examples/PhabricatorAphrontBarExample.php',
'PhabricatorApplication' => 'applications/base/PhabricatorApplication.php',
'PhabricatorApplicationApplications' => 'applications/meta/application/PhabricatorApplicationApplications.php',
'PhabricatorApplicationAudit' => 'applications/audit/application/PhabricatorApplicationAudit.php',
'PhabricatorApplicationAuth' => 'applications/auth/application/PhabricatorApplicationAuth.php',
'PhabricatorApplicationCalendar' => 'applications/calendar/application/PhabricatorApplicationCalendar.php',
'PhabricatorApplicationChatLog' => 'applications/chatlog/applications/PhabricatorApplicationChatLog.php',
'PhabricatorApplicationConduit' => 'applications/conduit/application/PhabricatorApplicationConduit.php',
'PhabricatorApplicationConfig' => 'applications/config/application/PhabricatorApplicationConfig.php',
'PhabricatorApplicationConfigOptions' => 'applications/config/option/PhabricatorApplicationConfigOptions.php',
'PhabricatorApplicationConpherence' => 'applications/conpherence/application/PhabricatorApplicationConpherence.php',
'PhabricatorApplicationCountdown' => 'applications/countdown/application/PhabricatorApplicationCountdown.php',
'PhabricatorApplicationDaemons' => 'applications/daemon/application/PhabricatorApplicationDaemons.php',
'PhabricatorApplicationDetailViewController' => 'applications/meta/controller/PhabricatorApplicationDetailViewController.php',
'PhabricatorApplicationDifferential' => 'applications/differential/application/PhabricatorApplicationDifferential.php',
'PhabricatorApplicationDiffusion' => 'applications/diffusion/application/PhabricatorApplicationDiffusion.php',
'PhabricatorApplicationDiviner' => 'applications/diviner/application/PhabricatorApplicationDiviner.php',
'PhabricatorApplicationDrydock' => 'applications/drydock/application/PhabricatorApplicationDrydock.php',
'PhabricatorApplicationFact' => 'applications/fact/application/PhabricatorApplicationFact.php',
'PhabricatorApplicationFeed' => 'applications/feed/application/PhabricatorApplicationFeed.php',
'PhabricatorApplicationFiles' => 'applications/files/application/PhabricatorApplicationFiles.php',
'PhabricatorApplicationFlags' => 'applications/flag/application/PhabricatorApplicationFlags.php',
'PhabricatorApplicationHerald' => 'applications/herald/application/PhabricatorApplicationHerald.php',
'PhabricatorApplicationLaunchView' => 'applications/meta/view/PhabricatorApplicationLaunchView.php',
'PhabricatorApplicationMacro' => 'applications/macro/application/PhabricatorApplicationMacro.php',
'PhabricatorApplicationMailingLists' => 'applications/mailinglists/application/PhabricatorApplicationMailingLists.php',
'PhabricatorApplicationManiphest' => 'applications/maniphest/application/PhabricatorApplicationManiphest.php',
'PhabricatorApplicationMetaMTA' => 'applications/metamta/application/PhabricatorApplicationMetaMTA.php',
'PhabricatorApplicationOwners' => 'applications/owners/application/PhabricatorApplicationOwners.php',
'PhabricatorApplicationPHID' => 'applications/phid/application/PhabricatorApplicationPHID.php',
'PhabricatorApplicationPHPAST' => 'applications/phpast/application/PhabricatorApplicationPHPAST.php',
'PhabricatorApplicationPaste' => 'applications/paste/application/PhabricatorApplicationPaste.php',
'PhabricatorApplicationPeople' => 'applications/people/application/PhabricatorApplicationPeople.php',
'PhabricatorApplicationPhame' => 'applications/phame/application/PhabricatorApplicationPhame.php',
'PhabricatorApplicationPholio' => 'applications/pholio/application/PhabricatorApplicationPholio.php',
'PhabricatorApplicationPhriction' => 'applications/phriction/application/PhabricatorApplicationPhriction.php',
'PhabricatorApplicationPonder' => 'applications/ponder/application/PhabricatorApplicationPonder.php',
'PhabricatorApplicationProject' => 'applications/project/application/PhabricatorApplicationProject.php',
+ 'PhabricatorApplicationReleeph' => 'applications/releeph/application/PhabricatorApplicationReleeph.php',
+ 'PhabricatorApplicationReleephConfigOptions' => 'applications/releeph/config/PhabricatorApplicationReleephConfigOptions.php',
'PhabricatorApplicationRepositories' => 'applications/repository/application/PhabricatorApplicationRepositories.php',
'PhabricatorApplicationSettings' => 'applications/settings/application/PhabricatorApplicationSettings.php',
'PhabricatorApplicationSlowvote' => 'applications/slowvote/application/PhabricatorApplicationSlowvote.php',
'PhabricatorApplicationStatusView' => 'applications/meta/view/PhabricatorApplicationStatusView.php',
'PhabricatorApplicationSubscriptions' => 'applications/subscriptions/application/PhabricatorApplicationSubscriptions.php',
'PhabricatorApplicationTokens' => 'applications/tokens/application/PhabricatorApplicationTokens.php',
'PhabricatorApplicationTransaction' => 'applications/transactions/storage/PhabricatorApplicationTransaction.php',
'PhabricatorApplicationTransactionComment' => 'applications/transactions/storage/PhabricatorApplicationTransactionComment.php',
'PhabricatorApplicationTransactionCommentEditController' => 'applications/transactions/controller/PhabricatorApplicationTransactionCommentEditController.php',
'PhabricatorApplicationTransactionCommentEditor' => 'applications/transactions/editor/PhabricatorApplicationTransactionCommentEditor.php',
'PhabricatorApplicationTransactionCommentHistoryController' => 'applications/transactions/controller/PhabricatorApplicationTransactionCommentHistoryController.php',
'PhabricatorApplicationTransactionCommentQuery' => 'applications/transactions/query/PhabricatorApplicationTransactionCommentQuery.php',
'PhabricatorApplicationTransactionCommentView' => 'applications/transactions/view/PhabricatorApplicationTransactionCommentView.php',
'PhabricatorApplicationTransactionController' => 'applications/transactions/controller/PhabricatorApplicationTransactionController.php',
'PhabricatorApplicationTransactionEditor' => 'applications/transactions/editor/PhabricatorApplicationTransactionEditor.php',
'PhabricatorApplicationTransactionFeedStory' => 'applications/transactions/feed/PhabricatorApplicationTransactionFeedStory.php',
'PhabricatorApplicationTransactionInterface' => 'applications/transactions/interface/PhabricatorApplicationTransactionInterface.php',
'PhabricatorApplicationTransactionNoEffectException' => 'applications/transactions/exception/PhabricatorApplicationTransactionNoEffectException.php',
'PhabricatorApplicationTransactionNoEffectResponse' => 'applications/transactions/response/PhabricatorApplicationTransactionNoEffectResponse.php',
'PhabricatorApplicationTransactionQuery' => 'applications/transactions/query/PhabricatorApplicationTransactionQuery.php',
'PhabricatorApplicationTransactionResponse' => 'applications/transactions/response/PhabricatorApplicationTransactionResponse.php',
'PhabricatorApplicationTransactionTextDiffDetailView' => 'applications/transactions/view/PhabricatorApplicationTransactionTextDiffDetailView.php',
'PhabricatorApplicationTransactionView' => 'applications/transactions/view/PhabricatorApplicationTransactionView.php',
'PhabricatorApplicationTransactions' => 'applications/transactions/application/PhabricatorApplicationTransactions.php',
'PhabricatorApplicationUIExamples' => 'applications/uiexample/application/PhabricatorApplicationUIExamples.php',
'PhabricatorApplicationUninstallController' => 'applications/meta/controller/PhabricatorApplicationUninstallController.php',
'PhabricatorApplicationsController' => 'applications/meta/controller/PhabricatorApplicationsController.php',
'PhabricatorApplicationsListController' => 'applications/meta/controller/PhabricatorApplicationsListController.php',
'PhabricatorAuditActionConstants' => 'applications/audit/constants/PhabricatorAuditActionConstants.php',
'PhabricatorAuditAddCommentController' => 'applications/audit/controller/PhabricatorAuditAddCommentController.php',
'PhabricatorAuditComment' => 'applications/audit/storage/PhabricatorAuditComment.php',
'PhabricatorAuditCommentEditor' => 'applications/audit/editor/PhabricatorAuditCommentEditor.php',
'PhabricatorAuditCommitListView' => 'applications/audit/view/PhabricatorAuditCommitListView.php',
'PhabricatorAuditCommitQuery' => 'applications/audit/query/PhabricatorAuditCommitQuery.php',
'PhabricatorAuditCommitStatusConstants' => 'applications/audit/constants/PhabricatorAuditCommitStatusConstants.php',
'PhabricatorAuditController' => 'applications/audit/controller/PhabricatorAuditController.php',
'PhabricatorAuditDAO' => 'applications/audit/storage/PhabricatorAuditDAO.php',
'PhabricatorAuditInlineComment' => 'applications/audit/storage/PhabricatorAuditInlineComment.php',
'PhabricatorAuditListController' => 'applications/audit/controller/PhabricatorAuditListController.php',
'PhabricatorAuditListView' => 'applications/audit/view/PhabricatorAuditListView.php',
'PhabricatorAuditPreviewController' => 'applications/audit/controller/PhabricatorAuditPreviewController.php',
'PhabricatorAuditQuery' => 'applications/audit/query/PhabricatorAuditQuery.php',
'PhabricatorAuditReplyHandler' => 'applications/audit/PhabricatorAuditReplyHandler.php',
'PhabricatorAuditStatusConstants' => 'applications/audit/constants/PhabricatorAuditStatusConstants.php',
'PhabricatorAuthController' => 'applications/auth/controller/PhabricatorAuthController.php',
'PhabricatorAuthenticationConfigOptions' => 'applications/config/option/PhabricatorAuthenticationConfigOptions.php',
'PhabricatorBarePageExample' => 'applications/uiexample/examples/PhabricatorBarePageExample.php',
'PhabricatorBarePageView' => 'view/page/PhabricatorBarePageView.php',
'PhabricatorBaseEnglishTranslation' => 'infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php',
'PhabricatorBaseProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorBaseProtocolAdapter.php',
'PhabricatorBot' => 'infrastructure/daemon/bot/PhabricatorBot.php',
'PhabricatorBotBaseStreamingProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorBotBaseStreamingProtocolAdapter.php',
'PhabricatorBotChannel' => 'infrastructure/daemon/bot/target/PhabricatorBotChannel.php',
'PhabricatorBotDebugLogHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotDebugLogHandler.php',
'PhabricatorBotDifferentialNotificationHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotDifferentialNotificationHandler.php',
'PhabricatorBotFeedNotificationHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotFeedNotificationHandler.php',
'PhabricatorBotFlowdockProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorBotFlowdockProtocolAdapter.php',
'PhabricatorBotHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotHandler.php',
'PhabricatorBotLogHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotLogHandler.php',
'PhabricatorBotMacroHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotMacroHandler.php',
'PhabricatorBotMessage' => 'infrastructure/daemon/bot/PhabricatorBotMessage.php',
'PhabricatorBotObjectNameHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotObjectNameHandler.php',
'PhabricatorBotSymbolHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotSymbolHandler.php',
'PhabricatorBotTarget' => 'infrastructure/daemon/bot/target/PhabricatorBotTarget.php',
'PhabricatorBotUser' => 'infrastructure/daemon/bot/target/PhabricatorBotUser.php',
'PhabricatorBotWhatsNewHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotWhatsNewHandler.php',
'PhabricatorBuiltinPatchList' => 'infrastructure/storage/patch/PhabricatorBuiltinPatchList.php',
'PhabricatorButtonsExample' => 'applications/uiexample/examples/PhabricatorButtonsExample.php',
'PhabricatorCacheDAO' => 'applications/cache/storage/PhabricatorCacheDAO.php',
'PhabricatorCaches' => 'applications/cache/PhabricatorCaches.php',
'PhabricatorCalendarBrowseController' => 'applications/calendar/controller/PhabricatorCalendarBrowseController.php',
'PhabricatorCalendarController' => 'applications/calendar/controller/PhabricatorCalendarController.php',
'PhabricatorCalendarDAO' => 'applications/calendar/storage/PhabricatorCalendarDAO.php',
'PhabricatorCalendarDeleteStatusController' => 'applications/calendar/controller/PhabricatorCalendarDeleteStatusController.php',
'PhabricatorCalendarEditStatusController' => 'applications/calendar/controller/PhabricatorCalendarEditStatusController.php',
'PhabricatorCalendarHoliday' => 'applications/calendar/storage/PhabricatorCalendarHoliday.php',
'PhabricatorCalendarHolidayTestCase' => 'applications/calendar/storage/__tests__/PhabricatorCalendarHolidayTestCase.php',
'PhabricatorCalendarViewStatusController' => 'applications/calendar/controller/PhabricatorCalendarViewStatusController.php',
'PhabricatorCampfireProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorCampfireProtocolAdapter.php',
'PhabricatorChangesetResponse' => 'infrastructure/diff/PhabricatorChangesetResponse.php',
'PhabricatorChatLogChannel' => 'applications/chatlog/storage/PhabricatorChatLogChannel.php',
'PhabricatorChatLogChannelListController' => 'applications/chatlog/controller/PhabricatorChatLogChannelListController.php',
'PhabricatorChatLogChannelLogController' => 'applications/chatlog/controller/PhabricatorChatLogChannelLogController.php',
'PhabricatorChatLogChannelQuery' => 'applications/chatlog/PhabricatorChatLogChannelQuery.php',
'PhabricatorChatLogConstants' => 'applications/chatlog/constants/PhabricatorChatLogConstants.php',
'PhabricatorChatLogController' => 'applications/chatlog/controller/PhabricatorChatLogController.php',
'PhabricatorChatLogDAO' => 'applications/chatlog/storage/PhabricatorChatLogDAO.php',
'PhabricatorChatLogEvent' => 'applications/chatlog/storage/PhabricatorChatLogEvent.php',
'PhabricatorChatLogEventType' => 'applications/chatlog/constants/PhabricatorChatLogEventType.php',
'PhabricatorChatLogQuery' => 'applications/chatlog/PhabricatorChatLogQuery.php',
'PhabricatorConduitAPIController' => 'applications/conduit/controller/PhabricatorConduitAPIController.php',
'PhabricatorConduitCertificateToken' => 'applications/conduit/storage/PhabricatorConduitCertificateToken.php',
'PhabricatorConduitConnectionLog' => 'applications/conduit/storage/PhabricatorConduitConnectionLog.php',
'PhabricatorConduitConsoleController' => 'applications/conduit/controller/PhabricatorConduitConsoleController.php',
'PhabricatorConduitController' => 'applications/conduit/controller/PhabricatorConduitController.php',
'PhabricatorConduitDAO' => 'applications/conduit/storage/PhabricatorConduitDAO.php',
'PhabricatorConduitListController' => 'applications/conduit/controller/PhabricatorConduitListController.php',
'PhabricatorConduitLogController' => 'applications/conduit/controller/PhabricatorConduitLogController.php',
'PhabricatorConduitMethodCallLog' => 'applications/conduit/storage/PhabricatorConduitMethodCallLog.php',
'PhabricatorConduitTokenController' => 'applications/conduit/controller/PhabricatorConduitTokenController.php',
'PhabricatorConfigAllController' => 'applications/config/controller/PhabricatorConfigAllController.php',
'PhabricatorConfigController' => 'applications/config/controller/PhabricatorConfigController.php',
'PhabricatorConfigDatabaseSource' => 'infrastructure/env/PhabricatorConfigDatabaseSource.php',
'PhabricatorConfigDefaultSource' => 'infrastructure/env/PhabricatorConfigDefaultSource.php',
'PhabricatorConfigDictionarySource' => 'infrastructure/env/PhabricatorConfigDictionarySource.php',
'PhabricatorConfigEditController' => 'applications/config/controller/PhabricatorConfigEditController.php',
'PhabricatorConfigEditor' => 'applications/config/editor/PhabricatorConfigEditor.php',
'PhabricatorConfigEntry' => 'applications/config/storage/PhabricatorConfigEntry.php',
'PhabricatorConfigEntryDAO' => 'applications/config/storage/PhabricatorConfigEntryDAO.php',
'PhabricatorConfigFileSource' => 'infrastructure/env/PhabricatorConfigFileSource.php',
'PhabricatorConfigGroupController' => 'applications/config/controller/PhabricatorConfigGroupController.php',
'PhabricatorConfigIgnoreController' => 'applications/config/controller/PhabricatorConfigIgnoreController.php',
'PhabricatorConfigIssueListController' => 'applications/config/controller/PhabricatorConfigIssueListController.php',
'PhabricatorConfigIssueViewController' => 'applications/config/controller/PhabricatorConfigIssueViewController.php',
'PhabricatorConfigJSON' => 'applications/config/json/PhabricatorConfigJSON.php',
'PhabricatorConfigListController' => 'applications/config/controller/PhabricatorConfigListController.php',
'PhabricatorConfigLocalSource' => 'infrastructure/env/PhabricatorConfigLocalSource.php',
'PhabricatorConfigManagementDeleteWorkflow' => 'applications/config/management/PhabricatorConfigManagementDeleteWorkflow.php',
'PhabricatorConfigManagementGetWorkflow' => 'applications/config/management/PhabricatorConfigManagementGetWorkflow.php',
'PhabricatorConfigManagementListWorkflow' => 'applications/config/management/PhabricatorConfigManagementListWorkflow.php',
'PhabricatorConfigManagementSetWorkflow' => 'applications/config/management/PhabricatorConfigManagementSetWorkflow.php',
'PhabricatorConfigManagementWorkflow' => 'applications/config/management/PhabricatorConfigManagementWorkflow.php',
'PhabricatorConfigOption' => 'applications/config/option/PhabricatorConfigOption.php',
'PhabricatorConfigProxySource' => 'infrastructure/env/PhabricatorConfigProxySource.php',
'PhabricatorConfigResponse' => 'applications/config/response/PhabricatorConfigResponse.php',
'PhabricatorConfigSource' => 'infrastructure/env/PhabricatorConfigSource.php',
'PhabricatorConfigStackSource' => 'infrastructure/env/PhabricatorConfigStackSource.php',
'PhabricatorConfigTransaction' => 'applications/config/storage/PhabricatorConfigTransaction.php',
'PhabricatorConfigTransactionQuery' => 'applications/config/query/PhabricatorConfigTransactionQuery.php',
'PhabricatorConfigValidationException' => 'applications/config/exception/PhabricatorConfigValidationException.php',
'PhabricatorContentSource' => 'applications/metamta/contentsource/PhabricatorContentSource.php',
'PhabricatorContentSourceView' => 'applications/metamta/contentsource/PhabricatorContentSourceView.php',
'PhabricatorController' => 'applications/base/controller/PhabricatorController.php',
'PhabricatorCoreConfigOptions' => 'applications/config/option/PhabricatorCoreConfigOptions.php',
'PhabricatorCountdownController' => 'applications/countdown/controller/PhabricatorCountdownController.php',
'PhabricatorCountdownDAO' => 'applications/countdown/storage/PhabricatorCountdownDAO.php',
'PhabricatorCountdownDeleteController' => 'applications/countdown/controller/PhabricatorCountdownDeleteController.php',
'PhabricatorCountdownEditController' => 'applications/countdown/controller/PhabricatorCountdownEditController.php',
'PhabricatorCountdownListController' => 'applications/countdown/controller/PhabricatorCountdownListController.php',
'PhabricatorCountdownRemarkupRule' => 'applications/countdown/remarkup/PhabricatorCountdownRemarkupRule.php',
'PhabricatorCountdownViewController' => 'applications/countdown/controller/PhabricatorCountdownViewController.php',
'PhabricatorCountedToggleButtonsExample' => 'applications/uiexample/examples/PhabricatorCountedToggleButtonsExample.php',
'PhabricatorCrumbView' => 'view/layout/PhabricatorCrumbView.php',
'PhabricatorCrumbsView' => 'view/layout/PhabricatorCrumbsView.php',
'PhabricatorCursorPagedPolicyAwareQuery' => 'infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php',
'PhabricatorDaemon' => 'infrastructure/daemon/PhabricatorDaemon.php',
'PhabricatorDaemonCombinedLogController' => 'applications/daemon/controller/PhabricatorDaemonCombinedLogController.php',
'PhabricatorDaemonConsoleController' => 'applications/daemon/controller/PhabricatorDaemonConsoleController.php',
'PhabricatorDaemonControl' => 'infrastructure/daemon/PhabricatorDaemonControl.php',
'PhabricatorDaemonController' => 'applications/daemon/controller/PhabricatorDaemonController.php',
'PhabricatorDaemonDAO' => 'infrastructure/daemon/storage/PhabricatorDaemonDAO.php',
'PhabricatorDaemonLog' => 'infrastructure/daemon/storage/PhabricatorDaemonLog.php',
'PhabricatorDaemonLogEvent' => 'infrastructure/daemon/storage/PhabricatorDaemonLogEvent.php',
'PhabricatorDaemonLogEventsView' => 'applications/daemon/view/PhabricatorDaemonLogEventsView.php',
'PhabricatorDaemonLogListController' => 'applications/daemon/controller/PhabricatorDaemonLogListController.php',
'PhabricatorDaemonLogListView' => 'applications/daemon/view/PhabricatorDaemonLogListView.php',
'PhabricatorDaemonLogViewController' => 'applications/daemon/controller/PhabricatorDaemonLogViewController.php',
'PhabricatorDaemonReference' => 'infrastructure/daemon/control/PhabricatorDaemonReference.php',
'PhabricatorDebugController' => 'applications/system/PhabricatorDebugController.php',
'PhabricatorDefaultFileStorageEngineSelector' => 'applications/files/engineselector/PhabricatorDefaultFileStorageEngineSelector.php',
'PhabricatorDefaultSearchEngineSelector' => 'applications/search/selector/PhabricatorDefaultSearchEngineSelector.php',
'PhabricatorDeveloperConfigOptions' => 'applications/config/option/PhabricatorDeveloperConfigOptions.php',
'PhabricatorDifferenceEngine' => 'infrastructure/diff/PhabricatorDifferenceEngine.php',
'PhabricatorDifferentialConfigOptions' => 'applications/differential/config/PhabricatorDifferentialConfigOptions.php',
'PhabricatorDiffusionConfigOptions' => 'applications/diffusion/config/PhabricatorDiffusionConfigOptions.php',
'PhabricatorDirectoryController' => 'applications/directory/controller/PhabricatorDirectoryController.php',
'PhabricatorDirectoryMainController' => 'applications/directory/controller/PhabricatorDirectoryMainController.php',
'PhabricatorDisabledUserController' => 'applications/auth/controller/PhabricatorDisabledUserController.php',
'PhabricatorDisqusConfigOptions' => 'applications/config/option/PhabricatorDisqusConfigOptions.php',
'PhabricatorDraft' => 'applications/draft/storage/PhabricatorDraft.php',
'PhabricatorDraftDAO' => 'applications/draft/storage/PhabricatorDraftDAO.php',
'PhabricatorEdgeConfig' => 'infrastructure/edges/constants/PhabricatorEdgeConfig.php',
'PhabricatorEdgeConstants' => 'infrastructure/edges/constants/PhabricatorEdgeConstants.php',
'PhabricatorEdgeCycleException' => 'infrastructure/edges/exception/PhabricatorEdgeCycleException.php',
'PhabricatorEdgeEditor' => 'infrastructure/edges/editor/PhabricatorEdgeEditor.php',
'PhabricatorEdgeGraph' => 'infrastructure/edges/util/PhabricatorEdgeGraph.php',
'PhabricatorEdgeQuery' => 'infrastructure/edges/query/PhabricatorEdgeQuery.php',
'PhabricatorEdgeTestCase' => 'infrastructure/edges/__tests__/PhabricatorEdgeTestCase.php',
'PhabricatorEditor' => 'infrastructure/PhabricatorEditor.php',
'PhabricatorEmailLoginController' => 'applications/auth/controller/PhabricatorEmailLoginController.php',
'PhabricatorEmailTokenController' => 'applications/auth/controller/PhabricatorEmailTokenController.php',
'PhabricatorEmailVerificationController' => 'applications/people/controller/PhabricatorEmailVerificationController.php',
'PhabricatorEmptyQueryException' => 'infrastructure/query/PhabricatorEmptyQueryException.php',
'PhabricatorEnglishTranslation' => 'infrastructure/internationalization/PhabricatorEnglishTranslation.php',
'PhabricatorEnv' => 'infrastructure/env/PhabricatorEnv.php',
'PhabricatorEnvTestCase' => 'infrastructure/env/__tests__/PhabricatorEnvTestCase.php',
'PhabricatorErrorExample' => 'applications/uiexample/examples/PhabricatorErrorExample.php',
'PhabricatorEvent' => 'infrastructure/events/PhabricatorEvent.php',
'PhabricatorEventEngine' => 'infrastructure/events/PhabricatorEventEngine.php',
'PhabricatorEventType' => 'infrastructure/events/constant/PhabricatorEventType.php',
'PhabricatorExampleEventListener' => 'infrastructure/events/PhabricatorExampleEventListener.php',
'PhabricatorExtendingPhabricatorConfigOptions' => 'applications/config/option/PhabricatorExtendingPhabricatorConfigOptions.php',
'PhabricatorFacebookConfigOptions' => 'applications/config/option/PhabricatorFacebookConfigOptions.php',
'PhabricatorFactAggregate' => 'applications/fact/storage/PhabricatorFactAggregate.php',
'PhabricatorFactChartController' => 'applications/fact/controller/PhabricatorFactChartController.php',
'PhabricatorFactController' => 'applications/fact/controller/PhabricatorFactController.php',
'PhabricatorFactCountEngine' => 'applications/fact/engine/PhabricatorFactCountEngine.php',
'PhabricatorFactCursor' => 'applications/fact/storage/PhabricatorFactCursor.php',
'PhabricatorFactDAO' => 'applications/fact/storage/PhabricatorFactDAO.php',
'PhabricatorFactDaemon' => 'applications/fact/daemon/PhabricatorFactDaemon.php',
'PhabricatorFactEngine' => 'applications/fact/engine/PhabricatorFactEngine.php',
'PhabricatorFactHomeController' => 'applications/fact/controller/PhabricatorFactHomeController.php',
'PhabricatorFactLastUpdatedEngine' => 'applications/fact/engine/PhabricatorFactLastUpdatedEngine.php',
'PhabricatorFactManagementAnalyzeWorkflow' => 'applications/fact/management/PhabricatorFactManagementAnalyzeWorkflow.php',
'PhabricatorFactManagementCursorsWorkflow' => 'applications/fact/management/PhabricatorFactManagementCursorsWorkflow.php',
'PhabricatorFactManagementDestroyWorkflow' => 'applications/fact/management/PhabricatorFactManagementDestroyWorkflow.php',
'PhabricatorFactManagementListWorkflow' => 'applications/fact/management/PhabricatorFactManagementListWorkflow.php',
'PhabricatorFactManagementStatusWorkflow' => 'applications/fact/management/PhabricatorFactManagementStatusWorkflow.php',
'PhabricatorFactManagementWorkflow' => 'applications/fact/management/PhabricatorFactManagementWorkflow.php',
'PhabricatorFactRaw' => 'applications/fact/storage/PhabricatorFactRaw.php',
'PhabricatorFactSimpleSpec' => 'applications/fact/spec/PhabricatorFactSimpleSpec.php',
'PhabricatorFactSpec' => 'applications/fact/spec/PhabricatorFactSpec.php',
'PhabricatorFactUpdateIterator' => 'applications/fact/extract/PhabricatorFactUpdateIterator.php',
'PhabricatorFeedBuilder' => 'applications/feed/builder/PhabricatorFeedBuilder.php',
'PhabricatorFeedConfigOptions' => 'applications/feed/config/PhabricatorFeedConfigOptions.php',
'PhabricatorFeedConstants' => 'applications/feed/constants/PhabricatorFeedConstants.php',
'PhabricatorFeedController' => 'applications/feed/controller/PhabricatorFeedController.php',
'PhabricatorFeedDAO' => 'applications/feed/storage/PhabricatorFeedDAO.php',
'PhabricatorFeedMainController' => 'applications/feed/controller/PhabricatorFeedMainController.php',
'PhabricatorFeedPublicStreamController' => 'applications/feed/controller/PhabricatorFeedPublicStreamController.php',
'PhabricatorFeedQuery' => 'applications/feed/PhabricatorFeedQuery.php',
'PhabricatorFeedStory' => 'applications/feed/story/PhabricatorFeedStory.php',
'PhabricatorFeedStoryAggregate' => 'applications/feed/story/PhabricatorFeedStoryAggregate.php',
'PhabricatorFeedStoryAudit' => 'applications/feed/story/PhabricatorFeedStoryAudit.php',
'PhabricatorFeedStoryCommit' => 'applications/feed/story/PhabricatorFeedStoryCommit.php',
'PhabricatorFeedStoryData' => 'applications/feed/storage/PhabricatorFeedStoryData.php',
'PhabricatorFeedStoryDifferential' => 'applications/feed/story/PhabricatorFeedStoryDifferential.php',
'PhabricatorFeedStoryDifferentialAggregate' => 'applications/feed/story/PhabricatorFeedStoryDifferentialAggregate.php',
'PhabricatorFeedStoryManiphest' => 'applications/feed/story/PhabricatorFeedStoryManiphest.php',
'PhabricatorFeedStoryManiphestAggregate' => 'applications/feed/story/PhabricatorFeedStoryManiphestAggregate.php',
'PhabricatorFeedStoryNotification' => 'applications/notification/storage/PhabricatorFeedStoryNotification.php',
'PhabricatorFeedStoryPhriction' => 'applications/feed/story/PhabricatorFeedStoryPhriction.php',
'PhabricatorFeedStoryProject' => 'applications/feed/story/PhabricatorFeedStoryProject.php',
'PhabricatorFeedStoryPublisher' => 'applications/feed/PhabricatorFeedStoryPublisher.php',
'PhabricatorFeedStoryReference' => 'applications/feed/storage/PhabricatorFeedStoryReference.php',
'PhabricatorFeedStoryStatus' => 'applications/feed/story/PhabricatorFeedStoryStatus.php',
'PhabricatorFeedStoryTypeConstants' => 'applications/feed/constants/PhabricatorFeedStoryTypeConstants.php',
'PhabricatorFeedStoryView' => 'applications/feed/view/PhabricatorFeedStoryView.php',
'PhabricatorFeedView' => 'applications/feed/view/PhabricatorFeedView.php',
'PhabricatorFile' => 'applications/files/storage/PhabricatorFile.php',
'PhabricatorFileController' => 'applications/files/controller/PhabricatorFileController.php',
'PhabricatorFileDAO' => 'applications/files/storage/PhabricatorFileDAO.php',
'PhabricatorFileDataController' => 'applications/files/controller/PhabricatorFileDataController.php',
'PhabricatorFileDeleteController' => 'applications/files/controller/PhabricatorFileDeleteController.php',
'PhabricatorFileDropUploadController' => 'applications/files/controller/PhabricatorFileDropUploadController.php',
'PhabricatorFileImageMacro' => 'applications/macro/storage/PhabricatorFileImageMacro.php',
'PhabricatorFileInfoController' => 'applications/files/controller/PhabricatorFileInfoController.php',
'PhabricatorFileLinkListView' => 'view/layout/PhabricatorFileLinkListView.php',
'PhabricatorFileLinkView' => 'view/layout/PhabricatorFileLinkView.php',
'PhabricatorFileListController' => 'applications/files/controller/PhabricatorFileListController.php',
'PhabricatorFileQuery' => 'applications/files/query/PhabricatorFileQuery.php',
'PhabricatorFileShortcutController' => 'applications/files/controller/PhabricatorFileShortcutController.php',
'PhabricatorFileStorageBlob' => 'applications/files/storage/PhabricatorFileStorageBlob.php',
'PhabricatorFileStorageConfigurationException' => 'applications/files/exception/PhabricatorFileStorageConfigurationException.php',
'PhabricatorFileStorageEngine' => 'applications/files/engine/PhabricatorFileStorageEngine.php',
'PhabricatorFileStorageEngineSelector' => 'applications/files/engineselector/PhabricatorFileStorageEngineSelector.php',
'PhabricatorFileTestCase' => 'applications/files/storage/__tests__/PhabricatorFileTestCase.php',
'PhabricatorFileTransformController' => 'applications/files/controller/PhabricatorFileTransformController.php',
'PhabricatorFileUploadController' => 'applications/files/controller/PhabricatorFileUploadController.php',
'PhabricatorFileUploadException' => 'applications/files/exception/PhabricatorFileUploadException.php',
'PhabricatorFilesConfigOptions' => 'applications/files/config/PhabricatorFilesConfigOptions.php',
'PhabricatorFilesManagementEnginesWorkflow' => 'applications/files/management/PhabricatorFilesManagementEnginesWorkflow.php',
'PhabricatorFilesManagementMetadataWorkflow' => 'applications/files/management/PhabricatorFilesManagementMetadataWorkflow.php',
'PhabricatorFilesManagementMigrateWorkflow' => 'applications/files/management/PhabricatorFilesManagementMigrateWorkflow.php',
'PhabricatorFilesManagementWorkflow' => 'applications/files/management/PhabricatorFilesManagementWorkflow.php',
'PhabricatorFlag' => 'applications/flag/storage/PhabricatorFlag.php',
'PhabricatorFlagColor' => 'applications/flag/constants/PhabricatorFlagColor.php',
'PhabricatorFlagConstants' => 'applications/flag/constants/PhabricatorFlagConstants.php',
'PhabricatorFlagController' => 'applications/flag/controller/PhabricatorFlagController.php',
'PhabricatorFlagDAO' => 'applications/flag/storage/PhabricatorFlagDAO.php',
'PhabricatorFlagDeleteController' => 'applications/flag/controller/PhabricatorFlagDeleteController.php',
'PhabricatorFlagEditController' => 'applications/flag/controller/PhabricatorFlagEditController.php',
'PhabricatorFlagListController' => 'applications/flag/controller/PhabricatorFlagListController.php',
'PhabricatorFlagListView' => 'applications/flag/view/PhabricatorFlagListView.php',
'PhabricatorFlagQuery' => 'applications/flag/query/PhabricatorFlagQuery.php',
'PhabricatorFlagsUIEventListener' => 'applications/flag/events/PhabricatorFlagsUIEventListener.php',
'PhabricatorFormExample' => 'applications/uiexample/examples/PhabricatorFormExample.php',
'PhabricatorGarbageCollectorConfigOptions' => 'applications/config/option/PhabricatorGarbageCollectorConfigOptions.php',
'PhabricatorGarbageCollectorDaemon' => 'infrastructure/daemon/PhabricatorGarbageCollectorDaemon.php',
'PhabricatorGestureExample' => 'applications/uiexample/examples/PhabricatorGestureExample.php',
'PhabricatorGitGraphStream' => 'applications/repository/daemon/PhabricatorGitGraphStream.php',
'PhabricatorGitHubConfigOptions' => 'applications/config/option/PhabricatorGitHubConfigOptions.php',
'PhabricatorGlobalLock' => 'infrastructure/util/PhabricatorGlobalLock.php',
'PhabricatorGlobalUploadTargetView' => 'applications/files/view/PhabricatorGlobalUploadTargetView.php',
'PhabricatorGoogleConfigOptions' => 'applications/config/option/PhabricatorGoogleConfigOptions.php',
'PhabricatorHandleObjectSelectorDataView' => 'applications/phid/handle/view/PhabricatorHandleObjectSelectorDataView.php',
'PhabricatorHash' => 'infrastructure/util/PhabricatorHash.php',
'PhabricatorHashTestCase' => 'infrastructure/util/__tests__/PhabricatorHashTestCase.php',
'PhabricatorHeaderView' => 'view/layout/PhabricatorHeaderView.php',
'PhabricatorHelpController' => 'applications/help/controller/PhabricatorHelpController.php',
'PhabricatorHelpKeyboardShortcutController' => 'applications/help/controller/PhabricatorHelpKeyboardShortcutController.php',
'PhabricatorIRCBot' => 'infrastructure/daemon/bot/PhabricatorIRCBot.php',
'PhabricatorIRCProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorIRCProtocolAdapter.php',
'PhabricatorIRCProtocolHandler' => 'infrastructure/daemon/bot/handler/PhabricatorIRCProtocolHandler.php',
'PhabricatorImageTransformer' => 'applications/files/PhabricatorImageTransformer.php',
'PhabricatorInfrastructureTestCase' => 'infrastructure/__tests__/PhabricatorInfrastructureTestCase.php',
'PhabricatorInlineCommentController' => 'infrastructure/diff/PhabricatorInlineCommentController.php',
'PhabricatorInlineCommentInterface' => 'infrastructure/diff/interface/PhabricatorInlineCommentInterface.php',
'PhabricatorInlineCommentPreviewController' => 'infrastructure/diff/PhabricatorInlineCommentPreviewController.php',
'PhabricatorInlineSummaryView' => 'infrastructure/diff/view/PhabricatorInlineSummaryView.php',
'PhabricatorJavelinLinter' => 'infrastructure/lint/linter/PhabricatorJavelinLinter.php',
'PhabricatorJumpNavHandler' => 'applications/search/engine/PhabricatorJumpNavHandler.php',
'PhabricatorKeyValueDatabaseCache' => 'applications/cache/PhabricatorKeyValueDatabaseCache.php',
'PhabricatorLDAPConfigOptions' => 'applications/config/option/PhabricatorLDAPConfigOptions.php',
'PhabricatorLDAPLoginController' => 'applications/auth/controller/PhabricatorLDAPLoginController.php',
'PhabricatorLDAPProvider' => 'applications/auth/ldap/PhabricatorLDAPProvider.php',
'PhabricatorLDAPRegistrationController' => 'applications/auth/controller/PhabricatorLDAPRegistrationController.php',
'PhabricatorLDAPUnknownUserException' => 'applications/auth/ldap/PhabricatorLDAPUnknownUserException.php',
'PhabricatorLDAPUnlinkController' => 'applications/auth/controller/PhabricatorLDAPUnlinkController.php',
'PhabricatorLintEngine' => 'infrastructure/lint/PhabricatorLintEngine.php',
'PhabricatorLiskDAO' => 'infrastructure/storage/lisk/PhabricatorLiskDAO.php',
'PhabricatorLocalDiskFileStorageEngine' => 'applications/files/engine/PhabricatorLocalDiskFileStorageEngine.php',
'PhabricatorLocalTimeTestCase' => 'view/__tests__/PhabricatorLocalTimeTestCase.php',
'PhabricatorLoginController' => 'applications/auth/controller/PhabricatorLoginController.php',
'PhabricatorLoginValidateController' => 'applications/auth/controller/PhabricatorLoginValidateController.php',
'PhabricatorLogoutController' => 'applications/auth/controller/PhabricatorLogoutController.php',
'PhabricatorMacroCommentController' => 'applications/macro/controller/PhabricatorMacroCommentController.php',
'PhabricatorMacroConfigOptions' => 'applications/macro/config/PhabricatorMacroConfigOptions.php',
'PhabricatorMacroController' => 'applications/macro/controller/PhabricatorMacroController.php',
'PhabricatorMacroDisableController' => 'applications/macro/controller/PhabricatorMacroDisableController.php',
'PhabricatorMacroEditController' => 'applications/macro/controller/PhabricatorMacroEditController.php',
'PhabricatorMacroEditor' => 'applications/macro/editor/PhabricatorMacroEditor.php',
'PhabricatorMacroListController' => 'applications/macro/controller/PhabricatorMacroListController.php',
'PhabricatorMacroMemeController' => 'applications/macro/controller/PhabricatorMacroMemeController.php',
'PhabricatorMacroMemeDialogController' => 'applications/macro/controller/PhabricatorMacroMemeDialogController.php',
'PhabricatorMacroReplyHandler' => 'applications/macro/mail/PhabricatorMacroReplyHandler.php',
'PhabricatorMacroTransaction' => 'applications/macro/storage/PhabricatorMacroTransaction.php',
'PhabricatorMacroTransactionComment' => 'applications/macro/storage/PhabricatorMacroTransactionComment.php',
'PhabricatorMacroTransactionQuery' => 'applications/macro/query/PhabricatorMacroTransactionQuery.php',
'PhabricatorMacroTransactionType' => 'applications/macro/constants/PhabricatorMacroTransactionType.php',
'PhabricatorMacroViewController' => 'applications/macro/controller/PhabricatorMacroViewController.php',
'PhabricatorMail' => 'applications/metamta/PhabricatorMail.php',
'PhabricatorMailImplementationAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationAdapter.php',
'PhabricatorMailImplementationAmazonSESAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationAmazonSESAdapter.php',
'PhabricatorMailImplementationPHPMailerAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationPHPMailerAdapter.php',
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationPHPMailerLiteAdapter.php',
'PhabricatorMailImplementationSendGridAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationSendGridAdapter.php',
'PhabricatorMailImplementationTestAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationTestAdapter.php',
'PhabricatorMailReplyHandler' => 'applications/metamta/replyhandler/PhabricatorMailReplyHandler.php',
'PhabricatorMailingListsController' => 'applications/mailinglists/controller/PhabricatorMailingListsController.php',
'PhabricatorMailingListsEditController' => 'applications/mailinglists/controller/PhabricatorMailingListsEditController.php',
'PhabricatorMailingListsListController' => 'applications/mailinglists/controller/PhabricatorMailingListsListController.php',
'PhabricatorMainMenuGroupView' => 'view/page/menu/PhabricatorMainMenuGroupView.php',
'PhabricatorMainMenuIconView' => 'view/page/menu/PhabricatorMainMenuIconView.php',
'PhabricatorMainMenuSearchView' => 'view/page/menu/PhabricatorMainMenuSearchView.php',
'PhabricatorMainMenuView' => 'view/page/menu/PhabricatorMainMenuView.php',
'PhabricatorManiphestConfigOptions' => 'applications/maniphest/config/PhabricatorManiphestConfigOptions.php',
'PhabricatorMarkupCache' => 'applications/cache/storage/PhabricatorMarkupCache.php',
'PhabricatorMarkupEngine' => 'infrastructure/markup/PhabricatorMarkupEngine.php',
'PhabricatorMarkupInterface' => 'infrastructure/markup/PhabricatorMarkupInterface.php',
'PhabricatorMenuItemView' => 'view/layout/PhabricatorMenuItemView.php',
'PhabricatorMenuView' => 'view/layout/PhabricatorMenuView.php',
'PhabricatorMenuViewTestCase' => 'view/layout/__tests__/PhabricatorMenuViewTestCase.php',
'PhabricatorMercurialGraphStream' => 'applications/repository/daemon/PhabricatorMercurialGraphStream.php',
'PhabricatorMetaMTAAttachment' => 'applications/metamta/storage/PhabricatorMetaMTAAttachment.php',
'PhabricatorMetaMTAConfigOptions' => 'applications/config/option/PhabricatorMetaMTAConfigOptions.php',
'PhabricatorMetaMTAController' => 'applications/metamta/controller/PhabricatorMetaMTAController.php',
'PhabricatorMetaMTADAO' => 'applications/metamta/storage/PhabricatorMetaMTADAO.php',
'PhabricatorMetaMTAEmailBodyParser' => 'applications/metamta/PhabricatorMetaMTAEmailBodyParser.php',
'PhabricatorMetaMTAEmailBodyParserTestCase' => 'applications/metamta/__tests__/PhabricatorMetaMTAEmailBodyParserTestCase.php',
'PhabricatorMetaMTAListController' => 'applications/metamta/controller/PhabricatorMetaMTAListController.php',
'PhabricatorMetaMTAMail' => 'applications/metamta/storage/PhabricatorMetaMTAMail.php',
'PhabricatorMetaMTAMailBody' => 'applications/metamta/view/PhabricatorMetaMTAMailBody.php',
'PhabricatorMetaMTAMailBodyTestCase' => 'applications/metamta/view/__tests__/PhabricatorMetaMTAMailBodyTestCase.php',
'PhabricatorMetaMTAMailTestCase' => 'applications/metamta/storage/__tests__/PhabricatorMetaMTAMailTestCase.php',
'PhabricatorMetaMTAMailingList' => 'applications/mailinglists/storage/PhabricatorMetaMTAMailingList.php',
'PhabricatorMetaMTAReceiveController' => 'applications/metamta/controller/PhabricatorMetaMTAReceiveController.php',
'PhabricatorMetaMTAReceivedListController' => 'applications/metamta/controller/PhabricatorMetaMTAReceivedListController.php',
'PhabricatorMetaMTAReceivedMail' => 'applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php',
'PhabricatorMetaMTASendController' => 'applications/metamta/controller/PhabricatorMetaMTASendController.php',
'PhabricatorMetaMTASendGridReceiveController' => 'applications/metamta/controller/PhabricatorMetaMTASendGridReceiveController.php',
'PhabricatorMetaMTAViewController' => 'applications/metamta/controller/PhabricatorMetaMTAViewController.php',
'PhabricatorMetaMTAWorker' => 'applications/metamta/PhabricatorMetaMTAWorker.php',
'PhabricatorMustVerifyEmailController' => 'applications/auth/controller/PhabricatorMustVerifyEmailController.php',
'PhabricatorMySQLConfigOptions' => 'applications/config/option/PhabricatorMySQLConfigOptions.php',
'PhabricatorMySQLFileStorageEngine' => 'applications/files/engine/PhabricatorMySQLFileStorageEngine.php',
'PhabricatorNoteExample' => 'applications/uiexample/examples/PhabricatorNoteExample.php',
'PhabricatorNotificationBuilder' => 'applications/notification/builder/PhabricatorNotificationBuilder.php',
'PhabricatorNotificationClearController' => 'applications/notification/controller/PhabricatorNotificationClearController.php',
'PhabricatorNotificationConfigOptions' => 'applications/config/option/PhabricatorNotificationConfigOptions.php',
'PhabricatorNotificationController' => 'applications/notification/controller/PhabricatorNotificationController.php',
'PhabricatorNotificationIndividualController' => 'applications/notification/controller/PhabricatorNotificationIndividualController.php',
'PhabricatorNotificationListController' => 'applications/notification/controller/PhabricatorNotificationListController.php',
'PhabricatorNotificationPanelController' => 'applications/notification/controller/PhabricatorNotificationPanelController.php',
'PhabricatorNotificationQuery' => 'applications/notification/PhabricatorNotificationQuery.php',
'PhabricatorNotificationStatusController' => 'applications/notification/controller/PhabricatorNotificationStatusController.php',
'PhabricatorOAuthClientAuthorization' => 'applications/oauthserver/storage/PhabricatorOAuthClientAuthorization.php',
'PhabricatorOAuthClientAuthorizationBaseController' => 'applications/oauthserver/controller/clientauthorization/PhabricatorOAuthClientAuthorizationBaseController.php',
'PhabricatorOAuthClientAuthorizationDeleteController' => 'applications/oauthserver/controller/clientauthorization/PhabricatorOAuthClientAuthorizationDeleteController.php',
'PhabricatorOAuthClientAuthorizationEditController' => 'applications/oauthserver/controller/clientauthorization/PhabricatorOAuthClientAuthorizationEditController.php',
'PhabricatorOAuthClientAuthorizationListController' => 'applications/oauthserver/controller/clientauthorization/PhabricatorOAuthClientAuthorizationListController.php',
'PhabricatorOAuthClientAuthorizationQuery' => 'applications/oauthserver/query/PhabricatorOAuthClientAuthorizationQuery.php',
'PhabricatorOAuthClientBaseController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientBaseController.php',
'PhabricatorOAuthClientDeleteController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientDeleteController.php',
'PhabricatorOAuthClientEditController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientEditController.php',
'PhabricatorOAuthClientListController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientListController.php',
'PhabricatorOAuthClientViewController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientViewController.php',
'PhabricatorOAuthDefaultRegistrationController' => 'applications/auth/controller/oauthregistration/PhabricatorOAuthDefaultRegistrationController.php',
'PhabricatorOAuthDiagnosticsController' => 'applications/auth/controller/PhabricatorOAuthDiagnosticsController.php',
'PhabricatorOAuthFailureView' => 'applications/auth/view/PhabricatorOAuthFailureView.php',
'PhabricatorOAuthLoginController' => 'applications/auth/controller/PhabricatorOAuthLoginController.php',
'PhabricatorOAuthProvider' => 'applications/auth/oauth/provider/PhabricatorOAuthProvider.php',
'PhabricatorOAuthProviderDisqus' => 'applications/auth/oauth/provider/PhabricatorOAuthProviderDisqus.php',
'PhabricatorOAuthProviderException' => 'applications/auth/oauth/provider/PhabricatorOAuthProviderException.php',
'PhabricatorOAuthProviderFacebook' => 'applications/auth/oauth/provider/PhabricatorOAuthProviderFacebook.php',
'PhabricatorOAuthProviderGitHub' => 'applications/auth/oauth/provider/PhabricatorOAuthProviderGitHub.php',
'PhabricatorOAuthProviderGoogle' => 'applications/auth/oauth/provider/PhabricatorOAuthProviderGoogle.php',
'PhabricatorOAuthProviderPhabricator' => 'applications/auth/oauth/provider/PhabricatorOAuthProviderPhabricator.php',
'PhabricatorOAuthRegistrationController' => 'applications/auth/controller/oauthregistration/PhabricatorOAuthRegistrationController.php',
'PhabricatorOAuthResponse' => 'applications/oauthserver/PhabricatorOAuthResponse.php',
'PhabricatorOAuthServer' => 'applications/oauthserver/PhabricatorOAuthServer.php',
'PhabricatorOAuthServerAccessToken' => 'applications/oauthserver/storage/PhabricatorOAuthServerAccessToken.php',
'PhabricatorOAuthServerAuthController' => 'applications/oauthserver/controller/PhabricatorOAuthServerAuthController.php',
'PhabricatorOAuthServerAuthorizationCode' => 'applications/oauthserver/storage/PhabricatorOAuthServerAuthorizationCode.php',
'PhabricatorOAuthServerClient' => 'applications/oauthserver/storage/PhabricatorOAuthServerClient.php',
'PhabricatorOAuthServerClientQuery' => 'applications/oauthserver/query/PhabricatorOAuthServerClientQuery.php',
'PhabricatorOAuthServerController' => 'applications/oauthserver/controller/PhabricatorOAuthServerController.php',
'PhabricatorOAuthServerDAO' => 'applications/oauthserver/storage/PhabricatorOAuthServerDAO.php',
'PhabricatorOAuthServerScope' => 'applications/oauthserver/PhabricatorOAuthServerScope.php',
'PhabricatorOAuthServerTestCase' => 'applications/oauthserver/__tests__/PhabricatorOAuthServerTestCase.php',
'PhabricatorOAuthServerTestController' => 'applications/oauthserver/controller/PhabricatorOAuthServerTestController.php',
'PhabricatorOAuthServerTokenController' => 'applications/oauthserver/controller/PhabricatorOAuthServerTokenController.php',
'PhabricatorOAuthUnlinkController' => 'applications/auth/controller/PhabricatorOAuthUnlinkController.php',
'PhabricatorObjectHandle' => 'applications/phid/PhabricatorObjectHandle.php',
'PhabricatorObjectHandleConstants' => 'applications/phid/handle/const/PhabricatorObjectHandleConstants.php',
'PhabricatorObjectHandleData' => 'applications/phid/handle/PhabricatorObjectHandleData.php',
'PhabricatorObjectHandleStatus' => 'applications/phid/handle/const/PhabricatorObjectHandleStatus.php',
'PhabricatorObjectItemListExample' => 'applications/uiexample/examples/PhabricatorObjectItemListExample.php',
'PhabricatorObjectItemListView' => 'view/layout/PhabricatorObjectItemListView.php',
'PhabricatorObjectItemView' => 'view/layout/PhabricatorObjectItemView.php',
'PhabricatorObjectListView' => 'view/control/PhabricatorObjectListView.php',
'PhabricatorObjectSelectorDialog' => 'view/control/PhabricatorObjectSelectorDialog.php',
'PhabricatorOffsetPagedQuery' => 'infrastructure/query/PhabricatorOffsetPagedQuery.php',
'PhabricatorOwnerPathQuery' => 'applications/owners/query/PhabricatorOwnerPathQuery.php',
'PhabricatorOwnersConfigOptions' => 'applications/owners/config/PhabricatorOwnersConfigOptions.php',
'PhabricatorOwnersController' => 'applications/owners/controller/PhabricatorOwnersController.php',
'PhabricatorOwnersDAO' => 'applications/owners/storage/PhabricatorOwnersDAO.php',
'PhabricatorOwnersDeleteController' => 'applications/owners/controller/PhabricatorOwnersDeleteController.php',
'PhabricatorOwnersDetailController' => 'applications/owners/controller/PhabricatorOwnersDetailController.php',
'PhabricatorOwnersEditController' => 'applications/owners/controller/PhabricatorOwnersEditController.php',
'PhabricatorOwnersListController' => 'applications/owners/controller/PhabricatorOwnersListController.php',
'PhabricatorOwnersOwner' => 'applications/owners/storage/PhabricatorOwnersOwner.php',
'PhabricatorOwnersPackage' => 'applications/owners/storage/PhabricatorOwnersPackage.php',
'PhabricatorOwnersPackagePathValidator' => 'applications/repository/worker/commitchangeparser/PhabricatorOwnersPackagePathValidator.php',
'PhabricatorOwnersPackageQuery' => 'applications/owners/query/PhabricatorOwnersPackageQuery.php',
'PhabricatorOwnersPackageTestCase' => 'applications/owners/storage/__tests__/PhabricatorOwnersPackageTestCase.php',
'PhabricatorOwnersPath' => 'applications/owners/storage/PhabricatorOwnersPath.php',
'PhabricatorPHDConfigOptions' => 'applications/config/option/PhabricatorPHDConfigOptions.php',
'PhabricatorPHID' => 'applications/phid/storage/PhabricatorPHID.php',
'PhabricatorPHIDConfigOptions' => 'applications/phid/config/PhabricatorPHIDConfigOptions.php',
'PhabricatorPHIDConstants' => 'applications/phid/PhabricatorPHIDConstants.php',
'PhabricatorPHIDController' => 'applications/phid/controller/PhabricatorPHIDController.php',
'PhabricatorPHIDLookupController' => 'applications/phid/controller/PhabricatorPHIDLookupController.php',
'PhabricatorPHPMailerConfigOptions' => 'applications/config/option/PhabricatorPHPMailerConfigOptions.php',
'PhabricatorPaste' => 'applications/paste/storage/PhabricatorPaste.php',
'PhabricatorPasteController' => 'applications/paste/controller/PhabricatorPasteController.php',
'PhabricatorPasteDAO' => 'applications/paste/storage/PhabricatorPasteDAO.php',
'PhabricatorPasteEditController' => 'applications/paste/controller/PhabricatorPasteEditController.php',
'PhabricatorPasteListController' => 'applications/paste/controller/PhabricatorPasteListController.php',
'PhabricatorPasteQuery' => 'applications/paste/query/PhabricatorPasteQuery.php',
'PhabricatorPasteRemarkupRule' => 'applications/paste/remarkup/PhabricatorPasteRemarkupRule.php',
'PhabricatorPasteViewController' => 'applications/paste/controller/PhabricatorPasteViewController.php',
'PhabricatorPeopleController' => 'applications/people/controller/PhabricatorPeopleController.php',
'PhabricatorPeopleEditController' => 'applications/people/controller/PhabricatorPeopleEditController.php',
'PhabricatorPeopleLdapController' => 'applications/people/controller/PhabricatorPeopleLdapController.php',
'PhabricatorPeopleListController' => 'applications/people/controller/PhabricatorPeopleListController.php',
'PhabricatorPeopleLogsController' => 'applications/people/controller/PhabricatorPeopleLogsController.php',
'PhabricatorPeopleProfileController' => 'applications/people/controller/PhabricatorPeopleProfileController.php',
'PhabricatorPeopleQuery' => 'applications/people/PhabricatorPeopleQuery.php',
'PhabricatorPhabricatorOAuthConfigOptions' => 'applications/config/option/PhabricatorPhabricatorOAuthConfigOptions.php',
'PhabricatorPhameConfigOptions' => 'applications/phame/config/PhabricatorPhameConfigOptions.php',
'PhabricatorPholioConfigOptions' => 'applications/pholio/config/PhabricatorPholioConfigOptions.php',
'PhabricatorPhrictionConfigOptions' => 'applications/phriction/config/PhabricatorPhrictionConfigOptions.php',
'PhabricatorPinboardItemView' => 'view/layout/PhabricatorPinboardItemView.php',
'PhabricatorPinboardView' => 'view/layout/PhabricatorPinboardView.php',
'PhabricatorPolicies' => 'applications/policy/constants/PhabricatorPolicies.php',
'PhabricatorPolicy' => 'applications/policy/filter/PhabricatorPolicy.php',
'PhabricatorPolicyAwareQuery' => 'infrastructure/query/policy/PhabricatorPolicyAwareQuery.php',
'PhabricatorPolicyAwareTestQuery' => 'applications/policy/__tests__/PhabricatorPolicyAwareTestQuery.php',
'PhabricatorPolicyCapability' => 'applications/policy/constants/PhabricatorPolicyCapability.php',
'PhabricatorPolicyConfigOptions' => 'applications/config/option/PhabricatorPolicyConfigOptions.php',
'PhabricatorPolicyConstants' => 'applications/policy/constants/PhabricatorPolicyConstants.php',
'PhabricatorPolicyException' => 'applications/policy/exception/PhabricatorPolicyException.php',
'PhabricatorPolicyFilter' => 'applications/policy/filter/PhabricatorPolicyFilter.php',
'PhabricatorPolicyInterface' => 'applications/policy/interface/PhabricatorPolicyInterface.php',
'PhabricatorPolicyQuery' => 'applications/policy/query/PhabricatorPolicyQuery.php',
'PhabricatorPolicyTestCase' => 'applications/policy/__tests__/PhabricatorPolicyTestCase.php',
'PhabricatorPolicyTestObject' => 'applications/policy/__tests__/PhabricatorPolicyTestObject.php',
'PhabricatorPolicyType' => 'applications/policy/constants/PhabricatorPolicyType.php',
'PhabricatorProfileHeaderView' => 'view/layout/PhabricatorProfileHeaderView.php',
'PhabricatorProject' => 'applications/project/storage/PhabricatorProject.php',
'PhabricatorProjectConstants' => 'applications/project/constants/PhabricatorProjectConstants.php',
'PhabricatorProjectController' => 'applications/project/controller/PhabricatorProjectController.php',
'PhabricatorProjectCreateController' => 'applications/project/controller/PhabricatorProjectCreateController.php',
'PhabricatorProjectDAO' => 'applications/project/storage/PhabricatorProjectDAO.php',
'PhabricatorProjectEditor' => 'applications/project/editor/PhabricatorProjectEditor.php',
'PhabricatorProjectEditorTestCase' => 'applications/project/editor/__tests__/PhabricatorProjectEditorTestCase.php',
'PhabricatorProjectListController' => 'applications/project/controller/PhabricatorProjectListController.php',
'PhabricatorProjectMembersEditController' => 'applications/project/controller/PhabricatorProjectMembersEditController.php',
'PhabricatorProjectNameCollisionException' => 'applications/project/exception/PhabricatorProjectNameCollisionException.php',
'PhabricatorProjectProfile' => 'applications/project/storage/PhabricatorProjectProfile.php',
'PhabricatorProjectProfileController' => 'applications/project/controller/PhabricatorProjectProfileController.php',
'PhabricatorProjectProfileEditController' => 'applications/project/controller/PhabricatorProjectProfileEditController.php',
'PhabricatorProjectQuery' => 'applications/project/query/PhabricatorProjectQuery.php',
'PhabricatorProjectStatus' => 'applications/project/constants/PhabricatorProjectStatus.php',
'PhabricatorProjectTransaction' => 'applications/project/storage/PhabricatorProjectTransaction.php',
'PhabricatorProjectTransactionType' => 'applications/project/constants/PhabricatorProjectTransactionType.php',
'PhabricatorProjectUpdateController' => 'applications/project/controller/PhabricatorProjectUpdateController.php',
'PhabricatorPropertyListExample' => 'applications/uiexample/examples/PhabricatorPropertyListExample.php',
'PhabricatorPropertyListView' => 'view/layout/PhabricatorPropertyListView.php',
'PhabricatorQuery' => 'infrastructure/query/PhabricatorQuery.php',
'PhabricatorRecaptchaConfigOptions' => 'applications/config/option/PhabricatorRecaptchaConfigOptions.php',
'PhabricatorRedirectController' => 'applications/base/controller/PhabricatorRedirectController.php',
'PhabricatorRefreshCSRFController' => 'applications/auth/controller/PhabricatorRefreshCSRFController.php',
'PhabricatorRemarkupControl' => 'view/form/control/PhabricatorRemarkupControl.php',
'PhabricatorRemarkupRuleEmbedFile' => 'applications/files/remarkup/PhabricatorRemarkupRuleEmbedFile.php',
'PhabricatorRemarkupRuleImageMacro' => 'applications/macro/remarkup/PhabricatorRemarkupRuleImageMacro.php',
'PhabricatorRemarkupRuleMeme' => 'applications/macro/remarkup/PhabricatorRemarkupRuleMeme.php',
'PhabricatorRemarkupRuleMention' => 'applications/people/remarkup/PhabricatorRemarkupRuleMention.php',
'PhabricatorRemarkupRuleObject' => 'infrastructure/markup/rule/PhabricatorRemarkupRuleObject.php',
'PhabricatorRemarkupRuleYoutube' => 'infrastructure/markup/rule/PhabricatorRemarkupRuleYoutube.php',
'PhabricatorRepository' => 'applications/repository/storage/PhabricatorRepository.php',
'PhabricatorRepositoryArcanistProject' => 'applications/repository/storage/PhabricatorRepositoryArcanistProject.php',
'PhabricatorRepositoryArcanistProjectDeleteController' => 'applications/repository/controller/PhabricatorRepositoryArcanistProjectDeleteController.php',
'PhabricatorRepositoryArcanistProjectEditController' => 'applications/repository/controller/PhabricatorRepositoryArcanistProjectEditController.php',
'PhabricatorRepositoryAuditRequest' => 'applications/repository/storage/PhabricatorRepositoryAuditRequest.php',
'PhabricatorRepositoryBranch' => 'applications/repository/storage/PhabricatorRepositoryBranch.php',
'PhabricatorRepositoryCommit' => 'applications/repository/storage/PhabricatorRepositoryCommit.php',
'PhabricatorRepositoryCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryCommitChangeParserWorker.php',
'PhabricatorRepositoryCommitData' => 'applications/repository/storage/PhabricatorRepositoryCommitData.php',
'PhabricatorRepositoryCommitHeraldWorker' => 'applications/repository/worker/PhabricatorRepositoryCommitHeraldWorker.php',
'PhabricatorRepositoryCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php',
'PhabricatorRepositoryCommitOwnersWorker' => 'applications/repository/worker/PhabricatorRepositoryCommitOwnersWorker.php',
'PhabricatorRepositoryCommitParserWorker' => 'applications/repository/worker/PhabricatorRepositoryCommitParserWorker.php',
'PhabricatorRepositoryCommitSearchIndexer' => 'applications/repository/search/PhabricatorRepositoryCommitSearchIndexer.php',
'PhabricatorRepositoryConfigOptions' => 'applications/repository/PhabricatorRepositoryConfigOptions.php',
'PhabricatorRepositoryController' => 'applications/repository/controller/PhabricatorRepositoryController.php',
'PhabricatorRepositoryCreateController' => 'applications/repository/controller/PhabricatorRepositoryCreateController.php',
'PhabricatorRepositoryDAO' => 'applications/repository/storage/PhabricatorRepositoryDAO.php',
'PhabricatorRepositoryDeleteController' => 'applications/repository/controller/PhabricatorRepositoryDeleteController.php',
'PhabricatorRepositoryEditController' => 'applications/repository/controller/PhabricatorRepositoryEditController.php',
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryGitCommitChangeParserWorker.php',
'PhabricatorRepositoryGitCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryGitCommitMessageParserWorker.php',
'PhabricatorRepositoryListController' => 'applications/repository/controller/PhabricatorRepositoryListController.php',
'PhabricatorRepositoryManagementDeleteWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementDeleteWorkflow.php',
'PhabricatorRepositoryManagementDiscoverWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementDiscoverWorkflow.php',
'PhabricatorRepositoryManagementListWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementListWorkflow.php',
'PhabricatorRepositoryManagementPullWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementPullWorkflow.php',
'PhabricatorRepositoryManagementWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementWorkflow.php',
'PhabricatorRepositoryMercurialCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryMercurialCommitChangeParserWorker.php',
'PhabricatorRepositoryMercurialCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryMercurialCommitMessageParserWorker.php',
'PhabricatorRepositoryPullLocalDaemon' => 'applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php',
'PhabricatorRepositoryPullLocalDaemonTestCase' => 'applications/repository/daemon/__tests__/PhabricatorRepositoryPullLocalDaemonTestCase.php',
'PhabricatorRepositoryQuery' => 'applications/repository/query/PhabricatorRepositoryQuery.php',
'PhabricatorRepositoryShortcut' => 'applications/repository/storage/PhabricatorRepositoryShortcut.php',
'PhabricatorRepositorySvnCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositorySvnCommitChangeParserWorker.php',
'PhabricatorRepositorySvnCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositorySvnCommitMessageParserWorker.php',
'PhabricatorRepositorySymbol' => 'applications/repository/storage/PhabricatorRepositorySymbol.php',
'PhabricatorRepositoryTestCase' => 'applications/repository/storage/__tests__/PhabricatorRepositoryTestCase.php',
'PhabricatorRepositoryType' => 'applications/repository/constants/PhabricatorRepositoryType.php',
'PhabricatorS3FileStorageEngine' => 'applications/files/engine/PhabricatorS3FileStorageEngine.php',
'PhabricatorSQLPatchList' => 'infrastructure/storage/patch/PhabricatorSQLPatchList.php',
'PhabricatorSSHWorkflow' => 'infrastructure/ssh/PhabricatorSSHWorkflow.php',
'PhabricatorScopedEnv' => 'infrastructure/env/PhabricatorScopedEnv.php',
'PhabricatorSearchAbstractDocument' => 'applications/search/index/PhabricatorSearchAbstractDocument.php',
'PhabricatorSearchAttachController' => 'applications/search/controller/PhabricatorSearchAttachController.php',
'PhabricatorSearchBaseController' => 'applications/search/controller/PhabricatorSearchBaseController.php',
'PhabricatorSearchConfigOptions' => 'applications/search/config/PhabricatorSearchConfigOptions.php',
'PhabricatorSearchController' => 'applications/search/controller/PhabricatorSearchController.php',
'PhabricatorSearchDAO' => 'applications/search/storage/PhabricatorSearchDAO.php',
'PhabricatorSearchDocument' => 'applications/search/storage/document/PhabricatorSearchDocument.php',
'PhabricatorSearchDocumentField' => 'applications/search/storage/document/PhabricatorSearchDocumentField.php',
'PhabricatorSearchDocumentIndexer' => 'applications/search/index/PhabricatorSearchDocumentIndexer.php',
'PhabricatorSearchDocumentRelationship' => 'applications/search/storage/document/PhabricatorSearchDocumentRelationship.php',
'PhabricatorSearchEngine' => 'applications/search/engine/PhabricatorSearchEngine.php',
'PhabricatorSearchEngineElastic' => 'applications/search/engine/PhabricatorSearchEngineElastic.php',
'PhabricatorSearchEngineMySQL' => 'applications/search/engine/PhabricatorSearchEngineMySQL.php',
'PhabricatorSearchEngineSelector' => 'applications/search/selector/PhabricatorSearchEngineSelector.php',
'PhabricatorSearchField' => 'applications/search/constants/PhabricatorSearchField.php',
'PhabricatorSearchIndexer' => 'applications/search/index/PhabricatorSearchIndexer.php',
'PhabricatorSearchManagementIndexWorkflow' => 'applications/search/management/PhabricatorSearchManagementIndexWorkflow.php',
'PhabricatorSearchManagementWorkflow' => 'applications/search/management/PhabricatorSearchManagementWorkflow.php',
'PhabricatorSearchQuery' => 'applications/search/storage/PhabricatorSearchQuery.php',
'PhabricatorSearchRelationship' => 'applications/search/constants/PhabricatorSearchRelationship.php',
'PhabricatorSearchResultView' => 'applications/search/view/PhabricatorSearchResultView.php',
'PhabricatorSearchScope' => 'applications/search/constants/PhabricatorSearchScope.php',
'PhabricatorSearchSelectController' => 'applications/search/controller/PhabricatorSearchSelectController.php',
'PhabricatorSecurityConfigOptions' => 'applications/config/option/PhabricatorSecurityConfigOptions.php',
'PhabricatorSendGridConfigOptions' => 'applications/config/option/PhabricatorSendGridConfigOptions.php',
'PhabricatorSettingsAdjustController' => 'applications/settings/controller/PhabricatorSettingsAdjustController.php',
'PhabricatorSettingsMainController' => 'applications/settings/controller/PhabricatorSettingsMainController.php',
'PhabricatorSettingsPanel' => 'applications/settings/panel/PhabricatorSettingsPanel.php',
'PhabricatorSettingsPanelAccount' => 'applications/settings/panel/PhabricatorSettingsPanelAccount.php',
'PhabricatorSettingsPanelConduit' => 'applications/settings/panel/PhabricatorSettingsPanelConduit.php',
'PhabricatorSettingsPanelDiffPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelDiffPreferences.php',
'PhabricatorSettingsPanelDisplayPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelDisplayPreferences.php',
'PhabricatorSettingsPanelEmailAddresses' => 'applications/settings/panel/PhabricatorSettingsPanelEmailAddresses.php',
'PhabricatorSettingsPanelEmailPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelEmailPreferences.php',
'PhabricatorSettingsPanelHomePreferences' => 'applications/settings/panel/PhabricatorSettingsPanelHomePreferences.php',
'PhabricatorSettingsPanelLDAP' => 'applications/settings/panel/PhabricatorSettingsPanelLDAP.php',
'PhabricatorSettingsPanelOAuth' => 'applications/settings/panel/PhabricatorSettingsPanelOAuth.php',
'PhabricatorSettingsPanelPassword' => 'applications/settings/panel/PhabricatorSettingsPanelPassword.php',
'PhabricatorSettingsPanelProfile' => 'applications/settings/panel/PhabricatorSettingsPanelProfile.php',
'PhabricatorSettingsPanelSSHKeys' => 'applications/settings/panel/PhabricatorSettingsPanelSSHKeys.php',
'PhabricatorSettingsPanelSearchPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelSearchPreferences.php',
'PhabricatorSetupCheck' => 'applications/config/check/PhabricatorSetupCheck.php',
'PhabricatorSetupCheckAPC' => 'applications/config/check/PhabricatorSetupCheckAPC.php',
'PhabricatorSetupCheckBaseURI' => 'applications/config/check/PhabricatorSetupCheckBaseURI.php',
'PhabricatorSetupCheckDatabase' => 'applications/config/check/PhabricatorSetupCheckDatabase.php',
'PhabricatorSetupCheckExtensions' => 'applications/config/check/PhabricatorSetupCheckExtensions.php',
'PhabricatorSetupCheckExtraConfig' => 'applications/config/check/PhabricatorSetupCheckExtraConfig.php',
'PhabricatorSetupCheckFacebook' => 'applications/config/check/PhabricatorSetupCheckFacebook.php',
'PhabricatorSetupCheckGD' => 'applications/config/check/PhabricatorSetupCheckGD.php',
'PhabricatorSetupCheckImagemagick' => 'applications/config/check/PhabricatorSetupCheckImagemagick.php',
'PhabricatorSetupCheckInvalidConfig' => 'applications/config/check/PhabricatorSetupCheckInvalidConfig.php',
'PhabricatorSetupCheckMail' => 'applications/config/check/PhabricatorSetupCheckMail.php',
'PhabricatorSetupCheckMySQL' => 'applications/config/check/PhabricatorSetupCheckMySQL.php',
'PhabricatorSetupCheckPHPConfig' => 'applications/config/check/PhabricatorSetupCheckPHPConfig.php',
'PhabricatorSetupCheckPath' => 'applications/config/check/PhabricatorSetupCheckPath.php',
'PhabricatorSetupCheckPygment' => 'applications/config/check/PhabricatorSetupCheckPygment.php',
'PhabricatorSetupCheckStorage' => 'applications/config/check/PhabricatorSetupCheckStorage.php',
'PhabricatorSetupCheckTimezone' => 'applications/config/check/PhabricatorSetupCheckTimezone.php',
'PhabricatorSetupIssue' => 'applications/config/issue/PhabricatorSetupIssue.php',
'PhabricatorSetupIssueExample' => 'applications/uiexample/examples/PhabricatorSetupIssueExample.php',
'PhabricatorSetupIssueView' => 'applications/config/view/PhabricatorSetupIssueView.php',
'PhabricatorSlowvoteChoice' => 'applications/slowvote/storage/PhabricatorSlowvoteChoice.php',
'PhabricatorSlowvoteComment' => 'applications/slowvote/storage/PhabricatorSlowvoteComment.php',
'PhabricatorSlowvoteController' => 'applications/slowvote/controller/PhabricatorSlowvoteController.php',
'PhabricatorSlowvoteCreateController' => 'applications/slowvote/controller/PhabricatorSlowvoteCreateController.php',
'PhabricatorSlowvoteDAO' => 'applications/slowvote/storage/PhabricatorSlowvoteDAO.php',
'PhabricatorSlowvoteListController' => 'applications/slowvote/controller/PhabricatorSlowvoteListController.php',
'PhabricatorSlowvoteOption' => 'applications/slowvote/storage/PhabricatorSlowvoteOption.php',
'PhabricatorSlowvotePoll' => 'applications/slowvote/storage/PhabricatorSlowvotePoll.php',
'PhabricatorSlowvotePollController' => 'applications/slowvote/controller/PhabricatorSlowvotePollController.php',
'PhabricatorSlug' => 'infrastructure/util/PhabricatorSlug.php',
'PhabricatorSlugTestCase' => 'infrastructure/util/__tests__/PhabricatorSlugTestCase.php',
'PhabricatorSortTableExample' => 'applications/uiexample/examples/PhabricatorSortTableExample.php',
'PhabricatorSourceCodeView' => 'view/layout/PhabricatorSourceCodeView.php',
'PhabricatorStandardPageView' => 'view/page/PhabricatorStandardPageView.php',
'PhabricatorStatusController' => 'applications/system/PhabricatorStatusController.php',
'PhabricatorStorageFixtureScopeGuard' => 'infrastructure/testing/fixture/PhabricatorStorageFixtureScopeGuard.php',
'PhabricatorStorageManagementAPI' => 'infrastructure/storage/management/PhabricatorStorageManagementAPI.php',
'PhabricatorStorageManagementDatabasesWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDatabasesWorkflow.php',
'PhabricatorStorageManagementDestroyWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDestroyWorkflow.php',
'PhabricatorStorageManagementDumpWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDumpWorkflow.php',
'PhabricatorStorageManagementStatusWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementStatusWorkflow.php',
'PhabricatorStorageManagementUpgradeWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementUpgradeWorkflow.php',
'PhabricatorStorageManagementWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementWorkflow.php',
'PhabricatorStoragePatch' => 'infrastructure/storage/management/PhabricatorStoragePatch.php',
'PhabricatorSubscribableInterface' => 'applications/subscriptions/interface/PhabricatorSubscribableInterface.php',
'PhabricatorSubscribersQuery' => 'applications/subscriptions/query/PhabricatorSubscribersQuery.php',
'PhabricatorSubscriptionsEditController' => 'applications/subscriptions/controller/PhabricatorSubscriptionsEditController.php',
'PhabricatorSubscriptionsEditor' => 'applications/subscriptions/editor/PhabricatorSubscriptionsEditor.php',
'PhabricatorSubscriptionsUIEventListener' => 'applications/subscriptions/events/PhabricatorSubscriptionsUIEventListener.php',
'PhabricatorSymbolNameLinter' => 'infrastructure/lint/hook/PhabricatorSymbolNameLinter.php',
'PhabricatorSyntaxHighlighter' => 'infrastructure/markup/PhabricatorSyntaxHighlighter.php',
'PhabricatorSyntaxHighlightingConfigOptions' => 'applications/config/option/PhabricatorSyntaxHighlightingConfigOptions.php',
'PhabricatorTagExample' => 'applications/uiexample/examples/PhabricatorTagExample.php',
'PhabricatorTagView' => 'view/layout/PhabricatorTagView.php',
'PhabricatorTaskmasterDaemon' => 'infrastructure/daemon/workers/PhabricatorTaskmasterDaemon.php',
'PhabricatorTestCase' => 'infrastructure/testing/PhabricatorTestCase.php',
'PhabricatorTestStorageEngine' => 'applications/files/engine/PhabricatorTestStorageEngine.php',
'PhabricatorTestWorker' => 'infrastructure/daemon/workers/__tests__/PhabricatorTestWorker.php',
'PhabricatorTimelineCursor' => 'infrastructure/daemon/timeline/storage/PhabricatorTimelineCursor.php',
'PhabricatorTimelineDAO' => 'infrastructure/daemon/timeline/storage/PhabricatorTimelineDAO.php',
'PhabricatorTimelineEvent' => 'infrastructure/daemon/timeline/storage/PhabricatorTimelineEvent.php',
'PhabricatorTimelineEventData' => 'infrastructure/daemon/timeline/storage/PhabricatorTimelineEventData.php',
'PhabricatorTimelineEventView' => 'view/layout/PhabricatorTimelineEventView.php',
'PhabricatorTimelineExample' => 'applications/uiexample/examples/PhabricatorTimelineExample.php',
'PhabricatorTimelineIterator' => 'infrastructure/daemon/timeline/cursor/PhabricatorTimelineIterator.php',
'PhabricatorTimelineView' => 'view/layout/PhabricatorTimelineView.php',
'PhabricatorTimer' => 'applications/countdown/storage/PhabricatorTimer.php',
'PhabricatorToken' => 'applications/tokens/storage/PhabricatorToken.php',
'PhabricatorTokenController' => 'applications/tokens/controller/PhabricatorTokenController.php',
'PhabricatorTokenCount' => 'applications/tokens/storage/PhabricatorTokenCount.php',
'PhabricatorTokenCountQuery' => 'applications/tokens/query/PhabricatorTokenCountQuery.php',
'PhabricatorTokenDAO' => 'applications/tokens/storage/PhabricatorTokenDAO.php',
'PhabricatorTokenGiveController' => 'applications/tokens/controller/PhabricatorTokenGiveController.php',
'PhabricatorTokenGiven' => 'applications/tokens/storage/PhabricatorTokenGiven.php',
'PhabricatorTokenGivenController' => 'applications/tokens/controller/PhabricatorTokenGivenController.php',
'PhabricatorTokenGivenEditor' => 'applications/tokens/editor/PhabricatorTokenGivenEditor.php',
'PhabricatorTokenGivenFeedStory' => 'applications/tokens/feed/PhabricatorTokenGivenFeedStory.php',
'PhabricatorTokenGivenQuery' => 'applications/tokens/query/PhabricatorTokenGivenQuery.php',
'PhabricatorTokenQuery' => 'applications/tokens/query/PhabricatorTokenQuery.php',
'PhabricatorTokenReceiverInterface' => 'applications/tokens/interface/PhabricatorTokenReceiverInterface.php',
'PhabricatorTokenUIEventListener' => 'applications/tokens/event/PhabricatorTokenUIEventListener.php',
'PhabricatorTransactionView' => 'view/layout/PhabricatorTransactionView.php',
'PhabricatorTransactions' => 'applications/transactions/constants/PhabricatorTransactions.php',
'PhabricatorTransformedFile' => 'applications/files/storage/PhabricatorTransformedFile.php',
'PhabricatorTranslation' => 'infrastructure/internationalization/PhabricatorTranslation.php',
'PhabricatorTranslationsConfigOptions' => 'applications/config/option/PhabricatorTranslationsConfigOptions.php',
'PhabricatorTrivialTestCase' => 'infrastructure/testing/__tests__/PhabricatorTrivialTestCase.php',
'PhabricatorTwoColumnExample' => 'applications/uiexample/examples/PhabricatorTwoColumnExample.php',
'PhabricatorTypeaheadCommonDatasourceController' => 'applications/typeahead/controller/PhabricatorTypeaheadCommonDatasourceController.php',
'PhabricatorTypeaheadDatasourceController' => 'applications/typeahead/controller/PhabricatorTypeaheadDatasourceController.php',
'PhabricatorTypeaheadResult' => 'applications/typeahead/storage/PhabricatorTypeaheadResult.php',
'PhabricatorUIExample' => 'applications/uiexample/examples/PhabricatorUIExample.php',
'PhabricatorUIExampleRenderController' => 'applications/uiexample/controller/PhabricatorUIExampleRenderController.php',
'PhabricatorUIListFilterExample' => 'applications/uiexample/examples/PhabricatorUIListFilterExample.php',
'PhabricatorUINotificationExample' => 'applications/uiexample/examples/PhabricatorUINotificationExample.php',
'PhabricatorUIPagerExample' => 'applications/uiexample/examples/PhabricatorUIPagerExample.php',
'PhabricatorUITooltipExample' => 'applications/uiexample/examples/PhabricatorUITooltipExample.php',
'PhabricatorUnitsTestCase' => 'view/__tests__/PhabricatorUnitsTestCase.php',
'PhabricatorUser' => 'applications/people/storage/PhabricatorUser.php',
'PhabricatorUserDAO' => 'applications/people/storage/PhabricatorUserDAO.php',
'PhabricatorUserEditor' => 'applications/people/PhabricatorUserEditor.php',
'PhabricatorUserEmail' => 'applications/people/storage/PhabricatorUserEmail.php',
'PhabricatorUserLDAPInfo' => 'applications/people/storage/PhabricatorUserLDAPInfo.php',
'PhabricatorUserLog' => 'applications/people/storage/PhabricatorUserLog.php',
'PhabricatorUserOAuthInfo' => 'applications/people/storage/PhabricatorUserOAuthInfo.php',
'PhabricatorUserPreferences' => 'applications/settings/storage/PhabricatorUserPreferences.php',
'PhabricatorUserProfile' => 'applications/people/storage/PhabricatorUserProfile.php',
'PhabricatorUserSSHKey' => 'applications/settings/storage/PhabricatorUserSSHKey.php',
'PhabricatorUserSearchIndexer' => 'applications/people/search/PhabricatorUserSearchIndexer.php',
'PhabricatorUserStatus' => 'applications/people/storage/PhabricatorUserStatus.php',
'PhabricatorUserStatusInvalidEpochException' => 'applications/people/exception/PhabricatorUserStatusInvalidEpochException.php',
'PhabricatorUserStatusOverlapException' => 'applications/people/exception/PhabricatorUserStatusOverlapException.php',
'PhabricatorUserTestCase' => 'applications/people/storage/__tests__/PhabricatorUserTestCase.php',
'PhabricatorWorker' => 'infrastructure/daemon/workers/PhabricatorWorker.php',
'PhabricatorWorkerActiveTask' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerActiveTask.php',
'PhabricatorWorkerArchiveTask' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerArchiveTask.php',
'PhabricatorWorkerDAO' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerDAO.php',
'PhabricatorWorkerLeaseQuery' => 'infrastructure/daemon/workers/query/PhabricatorWorkerLeaseQuery.php',
'PhabricatorWorkerPermanentFailureException' => 'infrastructure/daemon/workers/exception/PhabricatorWorkerPermanentFailureException.php',
'PhabricatorWorkerTask' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerTask.php',
'PhabricatorWorkerTaskData' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerTaskData.php',
'PhabricatorWorkerTaskDetailController' => 'applications/daemon/controller/PhabricatorWorkerTaskDetailController.php',
'PhabricatorWorkerTaskUpdateController' => 'applications/daemon/controller/PhabricatorWorkerTaskUpdateController.php',
'PhabricatorWorkerTestCase' => 'infrastructure/daemon/workers/__tests__/PhabricatorWorkerTestCase.php',
'PhabricatorXHPASTViewController' => 'applications/phpast/controller/PhabricatorXHPASTViewController.php',
'PhabricatorXHPASTViewDAO' => 'applications/phpast/storage/PhabricatorXHPASTViewDAO.php',
'PhabricatorXHPASTViewFrameController' => 'applications/phpast/controller/PhabricatorXHPASTViewFrameController.php',
'PhabricatorXHPASTViewFramesetController' => 'applications/phpast/controller/PhabricatorXHPASTViewFramesetController.php',
'PhabricatorXHPASTViewInputController' => 'applications/phpast/controller/PhabricatorXHPASTViewInputController.php',
'PhabricatorXHPASTViewPanelController' => 'applications/phpast/controller/PhabricatorXHPASTViewPanelController.php',
'PhabricatorXHPASTViewParseTree' => 'applications/phpast/storage/PhabricatorXHPASTViewParseTree.php',
'PhabricatorXHPASTViewRunController' => 'applications/phpast/controller/PhabricatorXHPASTViewRunController.php',
'PhabricatorXHPASTViewStreamController' => 'applications/phpast/controller/PhabricatorXHPASTViewStreamController.php',
'PhabricatorXHPASTViewTreeController' => 'applications/phpast/controller/PhabricatorXHPASTViewTreeController.php',
'PhabricatorXHProfController' => 'applications/xhprof/controller/PhabricatorXHProfController.php',
'PhabricatorXHProfDAO' => 'applications/xhprof/storage/PhabricatorXHProfDAO.php',
'PhabricatorXHProfProfileController' => 'applications/xhprof/controller/PhabricatorXHProfProfileController.php',
'PhabricatorXHProfProfileSymbolView' => 'applications/xhprof/view/PhabricatorXHProfProfileSymbolView.php',
'PhabricatorXHProfProfileTopLevelView' => 'applications/xhprof/view/PhabricatorXHProfProfileTopLevelView.php',
'PhabricatorXHProfProfileView' => 'applications/xhprof/view/PhabricatorXHProfProfileView.php',
'PhabricatorXHProfSample' => 'applications/xhprof/storage/PhabricatorXHProfSample.php',
'PhabricatorXHProfSampleListController' => 'applications/xhprof/controller/PhabricatorXHProfSampleListController.php',
'PhabricatorXHProfSampleListView' => 'applications/xhprof/view/PhabricatorXHProfSampleListView.php',
'PhameBasicBlogSkin' => 'applications/phame/skins/PhameBasicBlogSkin.php',
'PhameBasicTemplateBlogSkin' => 'applications/phame/skins/PhameBasicTemplateBlogSkin.php',
'PhameBlog' => 'applications/phame/storage/PhameBlog.php',
'PhameBlogDeleteController' => 'applications/phame/controller/blog/PhameBlogDeleteController.php',
'PhameBlogEditController' => 'applications/phame/controller/blog/PhameBlogEditController.php',
'PhameBlogFeedController' => 'applications/phame/controller/blog/PhameBlogFeedController.php',
'PhameBlogListController' => 'applications/phame/controller/blog/PhameBlogListController.php',
'PhameBlogLiveController' => 'applications/phame/controller/blog/PhameBlogLiveController.php',
'PhameBlogQuery' => 'applications/phame/query/PhameBlogQuery.php',
'PhameBlogSkin' => 'applications/phame/skins/PhameBlogSkin.php',
'PhameBlogViewController' => 'applications/phame/controller/blog/PhameBlogViewController.php',
'PhameController' => 'applications/phame/controller/PhameController.php',
'PhameDAO' => 'applications/phame/storage/PhameDAO.php',
'PhamePost' => 'applications/phame/storage/PhamePost.php',
'PhamePostDeleteController' => 'applications/phame/controller/post/PhamePostDeleteController.php',
'PhamePostEditController' => 'applications/phame/controller/post/PhamePostEditController.php',
'PhamePostFramedController' => 'applications/phame/controller/post/PhamePostFramedController.php',
'PhamePostListController' => 'applications/phame/controller/post/PhamePostListController.php',
'PhamePostNewController' => 'applications/phame/controller/post/PhamePostNewController.php',
'PhamePostNotLiveController' => 'applications/phame/controller/post/PhamePostNotLiveController.php',
'PhamePostPreviewController' => 'applications/phame/controller/post/PhamePostPreviewController.php',
'PhamePostPublishController' => 'applications/phame/controller/post/PhamePostPublishController.php',
'PhamePostQuery' => 'applications/phame/query/PhamePostQuery.php',
'PhamePostUnpublishController' => 'applications/phame/controller/post/PhamePostUnpublishController.php',
'PhamePostView' => 'applications/phame/view/PhamePostView.php',
'PhamePostViewController' => 'applications/phame/controller/post/PhamePostViewController.php',
'PhameResourceController' => 'applications/phame/controller/PhameResourceController.php',
'PhameSkinSpecification' => 'applications/phame/skins/PhameSkinSpecification.php',
'PholioConstants' => 'applications/pholio/constants/PholioConstants.php',
'PholioController' => 'applications/pholio/controller/PholioController.php',
'PholioDAO' => 'applications/pholio/storage/PholioDAO.php',
'PholioImage' => 'applications/pholio/storage/PholioImage.php',
'PholioInlineCommentEditView' => 'applications/pholio/view/PholioInlineCommentEditView.php',
'PholioInlineCommentSaveView' => 'applications/pholio/view/PholioInlineCommentSaveView.php',
'PholioInlineCommentView' => 'applications/pholio/view/PholioInlineCommentView.php',
'PholioInlineController' => 'applications/pholio/controller/PholioInlineController.php',
'PholioInlineDeleteController' => 'applications/pholio/controller/PholioInlineDeleteController.php',
'PholioInlineEditController' => 'applications/pholio/controller/PholioInlineEditController.php',
'PholioInlineSaveController' => 'applications/pholio/controller/PholioInlineSaveController.php',
'PholioInlineViewController' => 'applications/pholio/controller/PholioInlineViewController.php',
'PholioMock' => 'applications/pholio/storage/PholioMock.php',
'PholioMockCommentController' => 'applications/pholio/controller/PholioMockCommentController.php',
'PholioMockEditController' => 'applications/pholio/controller/PholioMockEditController.php',
'PholioMockEditor' => 'applications/pholio/editor/PholioMockEditor.php',
'PholioMockEmbedView' => 'applications/pholio/view/PholioMockEmbedView.php',
'PholioMockImagesView' => 'applications/pholio/view/PholioMockImagesView.php',
'PholioMockListController' => 'applications/pholio/controller/PholioMockListController.php',
'PholioMockQuery' => 'applications/pholio/query/PholioMockQuery.php',
'PholioMockViewController' => 'applications/pholio/controller/PholioMockViewController.php',
'PholioRemarkupRule' => 'applications/pholio/remarkup/PholioRemarkupRule.php',
'PholioReplyHandler' => 'applications/pholio/mail/PholioReplyHandler.php',
'PholioSearchIndexer' => 'applications/pholio/search/PholioSearchIndexer.php',
'PholioTransaction' => 'applications/pholio/storage/PholioTransaction.php',
'PholioTransactionComment' => 'applications/pholio/storage/PholioTransactionComment.php',
'PholioTransactionQuery' => 'applications/pholio/query/PholioTransactionQuery.php',
'PholioTransactionType' => 'applications/pholio/constants/PholioTransactionType.php',
'PholioTransactionView' => 'applications/pholio/view/PholioTransactionView.php',
'PhortuneMonthYearExpiryControl' => 'applications/phortune/control/PhortuneMonthYearExpiryControl.php',
'PhortuneStripeBaseController' => 'applications/phortune/stripe/controller/PhortuneStripeBaseController.php',
'PhortuneStripePaymentFormView' => 'applications/phortune/stripe/view/PhortuneStripePaymentFormView.php',
'PhortuneStripeTestPaymentFormController' => 'applications/phortune/stripe/controller/PhortuneStripeTestPaymentFormController.php',
'PhrictionActionConstants' => 'applications/phriction/constants/PhrictionActionConstants.php',
'PhrictionChangeType' => 'applications/phriction/constants/PhrictionChangeType.php',
'PhrictionConstants' => 'applications/phriction/constants/PhrictionConstants.php',
'PhrictionContent' => 'applications/phriction/storage/PhrictionContent.php',
'PhrictionController' => 'applications/phriction/controller/PhrictionController.php',
'PhrictionDAO' => 'applications/phriction/storage/PhrictionDAO.php',
'PhrictionDeleteController' => 'applications/phriction/controller/PhrictionDeleteController.php',
'PhrictionDiffController' => 'applications/phriction/controller/PhrictionDiffController.php',
'PhrictionDocument' => 'applications/phriction/storage/PhrictionDocument.php',
'PhrictionDocumentController' => 'applications/phriction/controller/PhrictionDocumentController.php',
'PhrictionDocumentEditor' => 'applications/phriction/editor/PhrictionDocumentEditor.php',
'PhrictionDocumentPreviewController' => 'applications/phriction/controller/PhrictionDocumentPreviewController.php',
'PhrictionDocumentQuery' => 'applications/phriction/query/PhrictionDocumentQuery.php',
'PhrictionDocumentStatus' => 'applications/phriction/constants/PhrictionDocumentStatus.php',
'PhrictionDocumentTestCase' => 'applications/phriction/storage/__tests__/PhrictionDocumentTestCase.php',
'PhrictionEditController' => 'applications/phriction/controller/PhrictionEditController.php',
'PhrictionHistoryController' => 'applications/phriction/controller/PhrictionHistoryController.php',
'PhrictionListController' => 'applications/phriction/controller/PhrictionListController.php',
'PhrictionMoveController' => 'applications/phriction/controller/PhrictionMoveController.php',
'PhrictionNewController' => 'applications/phriction/controller/PhrictionNewController.php',
'PhrictionRemarkupRule' => 'applications/phriction/remarkup/PhrictionRemarkupRule.php',
'PhrictionSearchIndexer' => 'applications/phriction/search/PhrictionSearchIndexer.php',
'PonderAddAnswerView' => 'applications/ponder/view/PonderAddAnswerView.php',
'PonderAddCommentView' => 'applications/ponder/view/PonderAddCommentView.php',
'PonderAnswer' => 'applications/ponder/storage/PonderAnswer.php',
'PonderAnswerEditor' => 'applications/ponder/editor/PonderAnswerEditor.php',
'PonderAnswerListView' => 'applications/ponder/view/PonderAnswerListView.php',
'PonderAnswerPreviewController' => 'applications/ponder/controller/PonderAnswerPreviewController.php',
'PonderAnswerQuery' => 'applications/ponder/query/PonderAnswerQuery.php',
'PonderAnswerSaveController' => 'applications/ponder/controller/PonderAnswerSaveController.php',
'PonderAnswerViewController' => 'applications/ponder/controller/PonderAnswerViewController.php',
'PonderAnsweredMail' => 'applications/ponder/mail/PonderAnsweredMail.php',
'PonderComment' => 'applications/ponder/storage/PonderComment.php',
'PonderCommentEditor' => 'applications/ponder/editor/PonderCommentEditor.php',
'PonderCommentListView' => 'applications/ponder/view/PonderCommentListView.php',
'PonderCommentMail' => 'applications/ponder/mail/PonderCommentMail.php',
'PonderCommentQuery' => 'applications/ponder/query/PonderCommentQuery.php',
'PonderCommentSaveController' => 'applications/ponder/controller/PonderCommentSaveController.php',
'PonderConstants' => 'applications/ponder/PonderConstants.php',
'PonderController' => 'applications/ponder/controller/PonderController.php',
'PonderDAO' => 'applications/ponder/storage/PonderDAO.php',
'PonderFeedController' => 'applications/ponder/controller/PonderFeedController.php',
'PonderMail' => 'applications/ponder/mail/PonderMail.php',
'PonderMentionMail' => 'applications/ponder/mail/PonderMentionMail.php',
'PonderPostBodyView' => 'applications/ponder/view/PonderPostBodyView.php',
'PonderQuestion' => 'applications/ponder/storage/PonderQuestion.php',
'PonderQuestionAskController' => 'applications/ponder/controller/PonderQuestionAskController.php',
'PonderQuestionDetailView' => 'applications/ponder/view/PonderQuestionDetailView.php',
'PonderQuestionEditor' => 'applications/ponder/editor/PonderQuestionEditor.php',
'PonderQuestionPreviewController' => 'applications/ponder/controller/PonderQuestionPreviewController.php',
'PonderQuestionQuery' => 'applications/ponder/query/PonderQuestionQuery.php',
'PonderQuestionSummaryView' => 'applications/ponder/view/PonderQuestionSummaryView.php',
'PonderQuestionViewController' => 'applications/ponder/controller/PonderQuestionViewController.php',
'PonderRemarkupRule' => 'applications/ponder/remarkup/PonderRemarkupRule.php',
'PonderReplyHandler' => 'applications/ponder/PonderReplyHandler.php',
'PonderSearchIndexer' => 'applications/ponder/search/PonderSearchIndexer.php',
'PonderUserProfileView' => 'applications/ponder/view/PonderUserProfileView.php',
'PonderVotableInterface' => 'applications/ponder/storage/PonderVotableInterface.php',
'PonderVotableView' => 'applications/ponder/view/PonderVotableView.php',
'PonderVoteEditor' => 'applications/ponder/editor/PonderVoteEditor.php',
'PonderVoteSaveController' => 'applications/ponder/controller/PonderVoteSaveController.php',
'QueryFormattingTestCase' => 'infrastructure/storage/__tests__/QueryFormattingTestCase.php',
+ 'ReleephActiveProjectListView' => 'applications/releeph/view/project/list/ReleephActiveProjectListView.php',
+ 'ReleephAuthorFieldSpecification' => 'applications/releeph/field/specification/ReleephAuthorFieldSpecification.php',
+ 'ReleephBranch' => 'applications/releeph/storage/ReleephBranch.php',
+ 'ReleephBranchAccessController' => 'applications/releeph/controller/branch/ReleephBranchAccessController.php',
+ 'ReleephBranchBoxView' => 'applications/releeph/view/branch/ReleephBranchBoxView.php',
+ 'ReleephBranchCommitFieldSpecification' => 'applications/releeph/field/specification/ReleephBranchCommitFieldSpecification.php',
+ 'ReleephBranchCreateController' => 'applications/releeph/controller/branch/ReleephBranchCreateController.php',
+ 'ReleephBranchEditController' => 'applications/releeph/controller/branch/ReleephBranchEditController.php',
+ 'ReleephBranchEditor' => 'applications/releeph/editor/ReleephBranchEditor.php',
+ 'ReleephBranchNamePreviewController' => 'applications/releeph/controller/branch/ReleephBranchNamePreviewController.php',
+ 'ReleephBranchPreviewView' => 'applications/releeph/view/branch/ReleephBranchPreviewView.php',
+ 'ReleephBranchTemplate' => 'applications/releeph/view/branch/ReleephBranchTemplate.php',
+ 'ReleephBranchViewController' => 'applications/releeph/controller/branch/ReleephBranchViewController.php',
+ 'ReleephCommitFinder' => 'applications/releeph/commitfinder/ReleephCommitFinder.php',
+ 'ReleephCommitFinderException' => 'applications/releeph/commitfinder/ReleephCommitFinderException.php',
+ 'ReleephCommitMessageFieldSpecification' => 'applications/releeph/field/specification/ReleephCommitMessageFieldSpecification.php',
+ 'ReleephController' => 'applications/releeph/controller/ReleephController.php',
+ 'ReleephDAO' => 'applications/releeph/storage/ReleephDAO.php',
+ 'ReleephDefaultFieldSelector' => 'applications/releeph/field/selector/ReleephDefaultFieldSelector.php',
+ 'ReleephDefaultUserView' => 'applications/releeph/view/user/ReleephDefaultUserView.php',
+ 'ReleephDiffChurnFieldSpecification' => 'applications/releeph/field/specification/ReleephDiffChurnFieldSpecification.php',
+ 'ReleephDiffMessageFieldSpecification' => 'applications/releeph/field/specification/ReleephDiffMessageFieldSpecification.php',
+ 'ReleephDiffSizeFieldSpecification' => 'applications/releeph/field/specification/ReleephDiffSizeFieldSpecification.php',
+ 'ReleephDifferentialRevisionDetailRenderer' => 'applications/releeph/differential/ReleephDifferentialRevisionDetailRenderer.php',
+ 'ReleephEvent' => 'applications/releeph/storage/event/ReleephEvent.php',
+ 'ReleephFieldParseException' => 'applications/releeph/field/exception/ReleephFieldParseException.php',
+ 'ReleephFieldSelector' => 'applications/releeph/field/selector/ReleephFieldSelector.php',
+ 'ReleephFieldSpecification' => 'applications/releeph/field/specification/ReleephFieldSpecification.php',
+ 'ReleephFieldSpecificationIncompleteException' => 'applications/releeph/field/exception/ReleephFieldSpecificationIncompleteException.php',
+ 'ReleephInactiveProjectListView' => 'applications/releeph/view/project/list/ReleephInactiveProjectListView.php',
+ 'ReleephIntentFieldSpecification' => 'applications/releeph/field/specification/ReleephIntentFieldSpecification.php',
+ 'ReleephLevelFieldSpecification' => 'applications/releeph/field/specification/ReleephLevelFieldSpecification.php',
+ 'ReleephObjectHandleLoader' => 'applications/releeph/ReleephObjectHandleLoader.php',
+ 'ReleephOriginalCommitFieldSpecification' => 'applications/releeph/field/specification/ReleephOriginalCommitFieldSpecification.php',
+ 'ReleephPHIDConstants' => 'applications/releeph/ReleephPHIDConstants.php',
+ 'ReleephProject' => 'applications/releeph/storage/ReleephProject.php',
+ 'ReleephProjectActionController' => 'applications/releeph/controller/project/ReleephProjectActionController.php',
+ 'ReleephProjectCreateController' => 'applications/releeph/controller/project/ReleephProjectCreateController.php',
+ 'ReleephProjectEditController' => 'applications/releeph/controller/project/ReleephProjectEditController.php',
+ 'ReleephProjectListController' => 'applications/releeph/controller/project/ReleephProjectListController.php',
+ 'ReleephProjectView' => 'applications/releeph/view/ReleephProjectView.php',
+ 'ReleephProjectViewController' => 'applications/releeph/controller/project/ReleephProjectViewController.php',
+ 'ReleephReasonFieldSpecification' => 'applications/releeph/field/specification/ReleephReasonFieldSpecification.php',
+ 'ReleephRequest' => 'applications/releeph/storage/ReleephRequest.php',
+ 'ReleephRequestActionController' => 'applications/releeph/controller/request/ReleephRequestActionController.php',
+ 'ReleephRequestCreateController' => 'applications/releeph/controller/request/ReleephRequestCreateController.php',
+ 'ReleephRequestDifferentialCreateController' => 'applications/releeph/controller/request/ReleephRequestDifferentialCreateController.php',
+ 'ReleephRequestEditController' => 'applications/releeph/controller/request/ReleephRequestEditController.php',
+ 'ReleephRequestEditor' => 'applications/releeph/editor/ReleephRequestEditor.php',
+ 'ReleephRequestEvent' => 'applications/releeph/storage/request/ReleephRequestEvent.php',
+ 'ReleephRequestEventListView' => 'applications/releeph/view/requestevent/ReleephRequestEventListView.php',
+ 'ReleephRequestException' => 'applications/releeph/storage/request/exception/ReleephRequestException.php',
+ 'ReleephRequestHeaderListView' => 'applications/releeph/view/request/header/ReleephRequestHeaderListView.php',
+ 'ReleephRequestHeaderView' => 'applications/releeph/view/request/header/ReleephRequestHeaderView.php',
+ 'ReleephRequestIntentsView' => 'applications/releeph/view/request/ReleephRequestIntentsView.php',
+ 'ReleephRequestMail' => 'applications/releeph/editor/mail/ReleephRequestMail.php',
+ 'ReleephRequestStatusView' => 'applications/releeph/view/request/ReleephRequestStatusView.php',
+ 'ReleephRequestTypeaheadControl' => 'applications/releeph/view/request/ReleephRequestTypeaheadControl.php',
+ 'ReleephRequestTypeaheadController' => 'applications/releeph/controller/request/ReleephRequestTypeaheadController.php',
+ 'ReleephRequestViewController' => 'applications/releeph/controller/request/ReleephRequestViewController.php',
+ 'ReleephRequestorFieldSpecification' => 'applications/releeph/field/specification/ReleephRequestorFieldSpecification.php',
+ 'ReleephRevisionFieldSpecification' => 'applications/releeph/field/specification/ReleephRevisionFieldSpecification.php',
+ 'ReleephRiskFieldSpecification' => 'applications/releeph/field/specification/ReleephRiskFieldSpecification.php',
+ 'ReleephSeverityFieldSpecification' => 'applications/releeph/field/specification/ReleephSeverityFieldSpecification.php',
+ 'ReleephStatusFieldSpecification' => 'applications/releeph/field/specification/ReleephStatusFieldSpecification.php',
+ 'ReleephSummaryFieldSpecification' => 'applications/releeph/field/specification/ReleephSummaryFieldSpecification.php',
+ 'ReleephUserView' => 'applications/releeph/view/user/ReleephUserView.php',
),
'function' =>
array(
'_phabricator_date_format' => 'view/viewutils.php',
'celerity_generate_unique_node_id' => 'infrastructure/celerity/api.php',
'celerity_get_resource_uri' => 'infrastructure/celerity/api.php',
'celerity_register_resource_map' => 'infrastructure/celerity/map.php',
'javelin_render_tag' => 'infrastructure/javelin/markup.php',
'javelin_tag' => 'infrastructure/javelin/markup.php',
'phabricator_date' => 'view/viewutils.php',
'phabricator_datetime' => 'view/viewutils.php',
'phabricator_form' => 'infrastructure/javelin/markup.php',
'phabricator_format_bytes' => 'view/viewutils.php',
'phabricator_format_local_time' => 'view/viewutils.php',
'phabricator_format_relative_time' => 'view/viewutils.php',
'phabricator_format_relative_time_detailed' => 'view/viewutils.php',
'phabricator_format_units_generic' => 'view/viewutils.php',
'phabricator_on_relative_date' => 'view/viewutils.php',
'phabricator_parse_bytes' => 'view/viewutils.php',
'phabricator_relative_date' => 'view/viewutils.php',
'phabricator_render_form' => 'infrastructure/javelin/markup.php',
'phabricator_time' => 'view/viewutils.php',
'phid_get_subtype' => 'applications/phid/utils.php',
'phid_get_type' => 'applications/phid/utils.php',
'phid_group_by_type' => 'applications/phid/utils.php',
'require_celerity_resource' => 'infrastructure/celerity/api.php',
),
'xmap' =>
array(
'Aphront304Response' => 'AphrontResponse',
'Aphront400Response' => 'AphrontResponse',
'Aphront403Response' => 'AphrontHTMLResponse',
'Aphront404Response' => 'AphrontHTMLResponse',
'AphrontAjaxResponse' => 'AphrontResponse',
'AphrontAttachedFileView' => 'AphrontView',
'AphrontBarView' => 'AphrontView',
'AphrontCSRFException' => 'AphrontException',
'AphrontCalendarEventView' => 'AphrontView',
'AphrontCalendarMonthView' => 'AphrontView',
'AphrontContextBarView' => 'AphrontView',
'AphrontController' => 'Phobject',
'AphrontCursorPagerView' => 'AphrontView',
'AphrontDefaultApplicationConfiguration' => 'AphrontApplicationConfiguration',
'AphrontDialogResponse' => 'AphrontResponse',
'AphrontDialogView' => 'AphrontView',
'AphrontErrorView' => 'AphrontView',
'AphrontException' => 'Exception',
'AphrontFileResponse' => 'AphrontResponse',
'AphrontFormCheckboxControl' => 'AphrontFormControl',
'AphrontFormControl' => 'AphrontView',
'AphrontFormCountedToggleButtonsControl' => 'AphrontFormControl',
'AphrontFormCropControl' => 'AphrontFormControl',
'AphrontFormDateControl' => 'AphrontFormControl',
'AphrontFormDividerControl' => 'AphrontFormControl',
'AphrontFormDragAndDropUploadControl' => 'AphrontFormControl',
'AphrontFormFileControl' => 'AphrontFormControl',
'AphrontFormImageControl' => 'AphrontFormControl',
'AphrontFormInsetView' => 'AphrontView',
'AphrontFormLayoutView' => 'AphrontView',
'AphrontFormMarkupControl' => 'AphrontFormControl',
'AphrontFormPasswordControl' => 'AphrontFormControl',
'AphrontFormPolicyControl' => 'AphrontFormControl',
'AphrontFormRadioButtonControl' => 'AphrontFormControl',
'AphrontFormRecaptchaControl' => 'AphrontFormControl',
'AphrontFormSelectControl' => 'AphrontFormControl',
'AphrontFormStaticControl' => 'AphrontFormControl',
'AphrontFormSubmitControl' => 'AphrontFormControl',
'AphrontFormTextAreaControl' => 'AphrontFormControl',
'AphrontFormTextControl' => 'AphrontFormControl',
'AphrontFormToggleButtonsControl' => 'AphrontFormControl',
'AphrontFormTokenizerControl' => 'AphrontFormControl',
'AphrontFormView' => 'AphrontView',
'AphrontGlyphBarView' => 'AphrontBarView',
'AphrontHTMLResponse' => 'AphrontResponse',
'AphrontHTTPSinkTestCase' => 'PhabricatorTestCase',
'AphrontIsolatedDatabaseConnectionTestCase' => 'PhabricatorTestCase',
'AphrontIsolatedHTTPSink' => 'AphrontHTTPSink',
'AphrontJSONResponse' => 'AphrontResponse',
'AphrontJavelinView' => 'AphrontView',
'AphrontKeyboardShortcutsAvailableView' => 'AphrontView',
'AphrontListFilterView' => 'AphrontView',
'AphrontMiniPanelView' => 'AphrontView',
'AphrontMoreView' => 'AphrontView',
'AphrontMySQLDatabaseConnectionTestCase' => 'PhabricatorTestCase',
'AphrontNoteView' => 'AphrontView',
'AphrontNullView' => 'AphrontView',
'AphrontPHPHTTPSink' => 'AphrontHTTPSink',
'AphrontPageView' => 'AphrontView',
'AphrontPagerView' => 'AphrontView',
'AphrontPanelView' => 'AphrontView',
'AphrontPlainTextResponse' => 'AphrontResponse',
'AphrontProgressBarView' => 'AphrontBarView',
'AphrontProxyResponse' => 'AphrontResponse',
'AphrontRedirectException' => 'AphrontException',
'AphrontRedirectResponse' => 'AphrontResponse',
'AphrontReloadResponse' => 'AphrontRedirectResponse',
'AphrontRequestFailureView' => 'AphrontView',
'AphrontRequestTestCase' => 'PhabricatorTestCase',
'AphrontSideNavFilterView' => 'AphrontView',
'AphrontTableView' => 'AphrontView',
'AphrontTagView' => 'AphrontView',
'AphrontTokenizerTemplateView' => 'AphrontView',
'AphrontTwoColumnView' => 'AphrontView',
'AphrontTypeaheadTemplateView' => 'AphrontView',
'AphrontUsageException' => 'AphrontException',
'AphrontView' =>
array(
0 => 'Phobject',
1 => 'PhutilSafeHTMLProducerInterface',
),
'AphrontWebpageResponse' => 'AphrontHTMLResponse',
'AuditPeopleMenuEventListener' => 'PhutilEventListener',
'CelerityPhabricatorResourceController' => 'CelerityResourceController',
'CelerityResourceController' => 'PhabricatorController',
'CelerityResourceGraph' => 'AbstractDirectedGraph',
'CelerityResourceTransformerTestCase' => 'PhabricatorTestCase',
'ConduitAPI_arcanist_Method' => 'ConduitAPIMethod',
'ConduitAPI_arcanist_projectinfo_Method' => 'ConduitAPI_arcanist_Method',
'ConduitAPI_audit_Method' => 'ConduitAPIMethod',
'ConduitAPI_audit_query_Method' => 'ConduitAPI_audit_Method',
'ConduitAPI_chatlog_Method' => 'ConduitAPIMethod',
'ConduitAPI_chatlog_query_Method' => 'ConduitAPI_chatlog_Method',
'ConduitAPI_chatlog_record_Method' => 'ConduitAPI_chatlog_Method',
'ConduitAPI_conduit_connect_Method' => 'ConduitAPIMethod',
'ConduitAPI_conduit_getcertificate_Method' => 'ConduitAPIMethod',
'ConduitAPI_conduit_ping_Method' => 'ConduitAPIMethod',
'ConduitAPI_conduit_query_Method' => 'ConduitAPIMethod',
'ConduitAPI_daemon_launched_Method' => 'ConduitAPIMethod',
'ConduitAPI_daemon_log_Method' => 'ConduitAPIMethod',
'ConduitAPI_daemon_setstatus_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_close_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_createcomment_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_creatediff_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_createinline_Method' => 'ConduitAPI_differential_Method',
'ConduitAPI_differential_createrawdiff_Method' => 'ConduitAPI_differential_Method',
'ConduitAPI_differential_createrevision_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_find_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_finishpostponedlinters_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getalldiffs_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getcommitmessage_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getcommitpaths_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getdiff_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getrevision_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_getrevisioncomments_Method' => 'ConduitAPI_differential_Method',
'ConduitAPI_differential_getrevisionfeedback_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_markcommitted_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_parsecommitmessage_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_query_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_setdiffproperty_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_updaterevision_Method' => 'ConduitAPIMethod',
'ConduitAPI_differential_updateunitresults_Method' => 'ConduitAPIMethod',
'ConduitAPI_diffusion_Method' => 'ConduitAPIMethod',
'ConduitAPI_diffusion_findsymbols_Method' => 'ConduitAPI_diffusion_Method',
'ConduitAPI_diffusion_getcommits_Method' => 'ConduitAPI_diffusion_Method',
'ConduitAPI_diffusion_getlintmessages_Method' => 'ConduitAPI_diffusion_Method',
'ConduitAPI_diffusion_getrecentcommitsbypath_Method' => 'ConduitAPI_diffusion_Method',
'ConduitAPI_feed_Method' => 'ConduitAPIMethod',
'ConduitAPI_feed_publish_Method' => 'ConduitAPI_feed_Method',
'ConduitAPI_feed_query_Method' => 'ConduitAPI_feed_Method',
'ConduitAPI_file_Method' => 'ConduitAPIMethod',
'ConduitAPI_file_download_Method' => 'ConduitAPI_file_Method',
'ConduitAPI_file_info_Method' => 'ConduitAPI_file_Method',
'ConduitAPI_file_upload_Method' => 'ConduitAPI_file_Method',
'ConduitAPI_file_uploadhash_Method' => 'ConduitAPI_file_Method',
'ConduitAPI_flag_Method' => 'ConduitAPIMethod',
'ConduitAPI_flag_delete_Method' => 'ConduitAPI_flag_Method',
'ConduitAPI_flag_edit_Method' => 'ConduitAPI_flag_Method',
'ConduitAPI_flag_query_Method' => 'ConduitAPI_flag_Method',
'ConduitAPI_macro_Method' => 'ConduitAPIMethod',
'ConduitAPI_macro_query_Method' => 'ConduitAPI_macro_Method',
'ConduitAPI_maniphest_Method' => 'ConduitAPIMethod',
'ConduitAPI_maniphest_createtask_Method' => 'ConduitAPI_maniphest_Method',
'ConduitAPI_maniphest_find_Method' => 'ConduitAPI_maniphest_query_Method',
'ConduitAPI_maniphest_gettasktransactions_Method' => 'ConduitAPI_maniphest_Method',
'ConduitAPI_maniphest_info_Method' => 'ConduitAPI_maniphest_Method',
'ConduitAPI_maniphest_query_Method' => 'ConduitAPI_maniphest_Method',
'ConduitAPI_maniphest_update_Method' => 'ConduitAPI_maniphest_Method',
'ConduitAPI_owners_Method' => 'ConduitAPIMethod',
'ConduitAPI_owners_query_Method' => 'ConduitAPI_owners_Method',
'ConduitAPI_paste_Method' => 'ConduitAPIMethod',
'ConduitAPI_paste_create_Method' => 'ConduitAPI_paste_Method',
'ConduitAPI_paste_info_Method' => 'ConduitAPI_paste_Method',
'ConduitAPI_paste_query_Method' => 'ConduitAPI_paste_Method',
'ConduitAPI_phid_Method' => 'ConduitAPIMethod',
'ConduitAPI_phid_info_Method' => 'ConduitAPI_phid_Method',
'ConduitAPI_phid_lookup_Method' => 'ConduitAPI_phid_Method',
'ConduitAPI_phid_query_Method' => 'ConduitAPI_phid_Method',
'ConduitAPI_phpast_Method' => 'ConduitAPIMethod',
'ConduitAPI_phpast_getast_Method' => 'ConduitAPI_phpast_Method',
'ConduitAPI_phpast_version_Method' => 'ConduitAPI_phpast_Method',
'ConduitAPI_phriction_Method' => 'ConduitAPIMethod',
'ConduitAPI_phriction_edit_Method' => 'ConduitAPI_phriction_Method',
'ConduitAPI_phriction_history_Method' => 'ConduitAPI_phriction_Method',
'ConduitAPI_phriction_info_Method' => 'ConduitAPI_phriction_Method',
'ConduitAPI_project_Method' => 'ConduitAPIMethod',
'ConduitAPI_project_query_Method' => 'ConduitAPI_project_Method',
+ 'ConduitAPI_releeph_Method' => 'ConduitAPIMethod',
+ 'ConduitAPI_releeph_getbranches_Method' => 'ConduitAPI_releeph_Method',
+ 'ConduitAPI_releeph_projectinfo_Method' => 'ConduitAPI_releeph_Method',
+ 'ConduitAPI_releeph_request_Method' => 'ConduitAPI_releeph_Method',
+ 'ConduitAPI_releephwork_canpush_Method' => 'ConduitAPI_releeph_Method',
+ 'ConduitAPI_releephwork_getauthorinfo_Method' => 'ConduitAPI_releeph_Method',
+ 'ConduitAPI_releephwork_getbranch_Method' => 'ConduitAPI_releeph_Method',
+ 'ConduitAPI_releephwork_getbranchcommitmessage_Method' => 'ConduitAPI_releeph_Method',
+ 'ConduitAPI_releephwork_getcommitmessage_Method' => 'ConduitAPI_releeph_Method',
+ 'ConduitAPI_releephwork_getorigcommitmessage_Method' => 'ConduitAPI_releeph_Method',
+ 'ConduitAPI_releephwork_nextrequest_Method' => 'ConduitAPI_releeph_Method',
+ 'ConduitAPI_releephwork_record_Method' => 'ConduitAPI_releeph_Method',
+ 'ConduitAPI_releephwork_recordpickstatus_Method' => 'ConduitAPI_releeph_Method',
'ConduitAPI_remarkup_process_Method' => 'ConduitAPIMethod',
'ConduitAPI_repository_Method' => 'ConduitAPIMethod',
'ConduitAPI_repository_create_Method' => 'ConduitAPI_repository_Method',
'ConduitAPI_repository_query_Method' => 'ConduitAPI_repository_Method',
'ConduitAPI_slowvote_Method' => 'ConduitAPIMethod',
'ConduitAPI_slowvote_info_Method' => 'ConduitAPI_slowvote_Method',
'ConduitAPI_token_Method' => 'ConduitAPIMethod',
'ConduitAPI_token_give_Method' => 'ConduitAPI_token_Method',
'ConduitAPI_token_given_Method' => 'ConduitAPI_token_Method',
'ConduitAPI_token_query_Method' => 'ConduitAPI_token_Method',
'ConduitAPI_user_Method' => 'ConduitAPIMethod',
'ConduitAPI_user_addstatus_Method' => 'ConduitAPI_user_Method',
'ConduitAPI_user_disable_Method' => 'ConduitAPI_user_Method',
'ConduitAPI_user_enable_Method' => 'ConduitAPI_user_Method',
'ConduitAPI_user_find_Method' => 'ConduitAPI_user_Method',
'ConduitAPI_user_info_Method' => 'ConduitAPI_user_Method',
'ConduitAPI_user_query_Method' => 'ConduitAPI_user_Method',
'ConduitAPI_user_removestatus_Method' => 'ConduitAPI_user_Method',
'ConduitAPI_user_whoami_Method' => 'ConduitAPI_user_Method',
'ConduitCallTestCase' => 'PhabricatorTestCase',
'ConduitException' => 'Exception',
'ConduitSSHWorkflow' => 'PhabricatorSSHWorkflow',
'ConpherenceConfigOptions' => 'PhabricatorApplicationConfigOptions',
'ConpherenceController' => 'PhabricatorController',
'ConpherenceDAO' => 'PhabricatorLiskDAO',
'ConpherenceEditor' => 'PhabricatorApplicationTransactionEditor',
'ConpherenceFileWidgetView' => 'AphrontView',
'ConpherenceFormDragAndDropUploadControl' => 'AphrontFormControl',
'ConpherenceImageData' => 'ConpherenceConstants',
'ConpherenceListController' => 'ConpherenceController',
'ConpherenceMenuItemView' => 'AphrontTagView',
'ConpherenceNewController' => 'ConpherenceController',
'ConpherenceParticipant' => 'ConpherenceDAO',
'ConpherenceParticipantQuery' => 'PhabricatorOffsetPagedQuery',
'ConpherenceParticipationStatus' => 'ConpherenceConstants',
'ConpherencePeopleMenuEventListener' => 'PhutilEventListener',
'ConpherencePontificateControl' => 'AphrontFormControl',
'ConpherenceReplyHandler' => 'PhabricatorMailReplyHandler',
'ConpherenceThread' =>
array(
0 => 'ConpherenceDAO',
1 => 'PhabricatorPolicyInterface',
),
'ConpherenceThreadQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'ConpherenceTransaction' => 'PhabricatorApplicationTransaction',
'ConpherenceTransactionComment' => 'PhabricatorApplicationTransactionComment',
'ConpherenceTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'ConpherenceTransactionType' => 'ConpherenceConstants',
'ConpherenceTransactionView' => 'AphrontView',
'ConpherenceUpdateController' => 'ConpherenceController',
'ConpherenceViewController' => 'ConpherenceController',
'ConpherenceWidgetController' => 'ConpherenceController',
'DarkConsoleController' => 'PhabricatorController',
'DarkConsoleDataController' => 'PhabricatorController',
'DarkConsoleErrorLogPlugin' => 'DarkConsolePlugin',
'DarkConsoleEventPlugin' => 'DarkConsolePlugin',
'DarkConsoleEventPluginAPI' => 'PhutilEventListener',
'DarkConsoleRequestPlugin' => 'DarkConsolePlugin',
'DarkConsoleServicesPlugin' => 'DarkConsolePlugin',
'DarkConsoleXHProfPlugin' => 'DarkConsolePlugin',
'DefaultDatabaseConfigurationProvider' => 'DatabaseConfigurationProvider',
'DifferentialActionHasNoEffectException' => 'DifferentialException',
'DifferentialAddCommentView' => 'AphrontView',
'DifferentialAffectedPath' => 'DifferentialDAO',
'DifferentialApplyPatchFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialArcanistProjectFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialAuditorsFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialAuthorFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialAuxiliaryField' => 'DifferentialDAO',
'DifferentialBlameRevisionFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialBranchFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialCCWelcomeMail' => 'DifferentialReviewRequestMail',
'DifferentialCCsFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialChangeset' => 'DifferentialDAO',
'DifferentialChangesetDetailView' => 'AphrontView',
'DifferentialChangesetHTMLRenderer' => 'DifferentialChangesetRenderer',
'DifferentialChangesetListView' => 'AphrontView',
'DifferentialChangesetOneUpRenderer' => 'DifferentialChangesetHTMLRenderer',
'DifferentialChangesetOneUpTestRenderer' => 'DifferentialChangesetTestRenderer',
'DifferentialChangesetParserTestCase' => 'PhabricatorTestCase',
'DifferentialChangesetTestRenderer' => 'DifferentialChangesetRenderer',
'DifferentialChangesetTwoUpRenderer' => 'DifferentialChangesetHTMLRenderer',
'DifferentialChangesetTwoUpTestRenderer' => 'DifferentialChangesetTestRenderer',
'DifferentialChangesetViewController' => 'DifferentialController',
'DifferentialComment' =>
array(
0 => 'DifferentialDAO',
1 => 'PhabricatorMarkupInterface',
),
'DifferentialCommentEditor' => 'PhabricatorEditor',
'DifferentialCommentMail' => 'DifferentialMail',
'DifferentialCommentPreviewController' => 'DifferentialController',
'DifferentialCommentSaveController' => 'DifferentialController',
'DifferentialCommitsFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialConflictsFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialController' => 'PhabricatorController',
'DifferentialDAO' => 'PhabricatorLiskDAO',
'DifferentialDateCreatedFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialDateModifiedFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialDefaultFieldSelector' => 'DifferentialFieldSelector',
'DifferentialDependenciesFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialDependsOnFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialDiff' => 'DifferentialDAO',
'DifferentialDiffContentMail' => 'DifferentialMail',
'DifferentialDiffCreateController' => 'DifferentialController',
'DifferentialDiffProperty' => 'DifferentialDAO',
'DifferentialDiffTableOfContentsView' => 'AphrontView',
'DifferentialDiffTestCase' => 'ArcanistPhutilTestCase',
'DifferentialDiffViewController' => 'DifferentialController',
'DifferentialException' => 'Exception',
'DifferentialExceptionMail' => 'DifferentialMail',
'DifferentialExportPatchFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialFieldDataNotAvailableException' => 'Exception',
'DifferentialFieldParseException' => 'Exception',
'DifferentialFieldSpecificationIncompleteException' => 'Exception',
'DifferentialFieldValidationException' => 'Exception',
'DifferentialFreeformFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialGitSVNIDFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialHostFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialHunk' => 'DifferentialDAO',
'DifferentialHunkParserTestCase' => 'PhabricatorTestCase',
'DifferentialHunkTestCase' => 'ArcanistPhutilTestCase',
'DifferentialInlineComment' =>
array(
0 => 'DifferentialDAO',
1 => 'PhabricatorInlineCommentInterface',
),
'DifferentialInlineCommentEditController' => 'PhabricatorInlineCommentController',
'DifferentialInlineCommentEditView' => 'AphrontView',
'DifferentialInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController',
'DifferentialInlineCommentView' => 'AphrontView',
'DifferentialLinesFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialLintFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialLocalCommitsView' => 'AphrontView',
'DifferentialMail' => 'PhabricatorMail',
'DifferentialManiphestTasksFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialNewDiffMail' => 'DifferentialReviewRequestMail',
'DifferentialParseRenderTestCase' => 'PhabricatorTestCase',
'DifferentialPathFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialPeopleMenuEventListener' => 'PhutilEventListener',
'DifferentialPrimaryPaneView' => 'AphrontView',
+ 'DifferentialReleephRequestFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialRemarkupRule' => 'PhabricatorRemarkupRuleObject',
'DifferentialReplyHandler' => 'PhabricatorMailReplyHandler',
'DifferentialResultsTableView' => 'AphrontView',
'DifferentialRevertPlanFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialReviewRequestMail' => 'DifferentialMail',
'DifferentialReviewedByFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialReviewerStatsTestCase' => 'PhabricatorTestCase',
'DifferentialReviewersFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialRevision' =>
array(
0 => 'DifferentialDAO',
1 => 'PhabricatorTokenReceiverInterface',
2 => 'PhabricatorPolicyInterface',
),
'DifferentialRevisionCommentListView' => 'AphrontView',
'DifferentialRevisionCommentView' => 'AphrontView',
'DifferentialRevisionDetailView' => 'AphrontView',
'DifferentialRevisionEditController' => 'DifferentialController',
'DifferentialRevisionEditor' => 'PhabricatorEditor',
'DifferentialRevisionIDFieldParserTestCase' => 'PhabricatorTestCase',
'DifferentialRevisionIDFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialRevisionListController' => 'DifferentialController',
'DifferentialRevisionListView' => 'AphrontView',
'DifferentialRevisionStatsController' => 'DifferentialController',
'DifferentialRevisionStatsView' => 'AphrontView',
'DifferentialRevisionStatusFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialRevisionUpdateHistoryView' => 'AphrontView',
'DifferentialRevisionViewController' => 'DifferentialController',
'DifferentialSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
'DifferentialSubscribeController' => 'DifferentialController',
'DifferentialSummaryFieldSpecification' => 'DifferentialFreeformFieldSpecification',
'DifferentialTestPlanFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialTitleFieldSpecification' => 'DifferentialFreeformFieldSpecification',
'DifferentialUnitFieldSpecification' => 'DifferentialFieldSpecification',
'DiffusionBranchTableController' => 'DiffusionController',
'DiffusionBranchTableView' => 'DiffusionView',
'DiffusionBrowseController' => 'DiffusionController',
'DiffusionBrowseFileController' => 'DiffusionController',
'DiffusionBrowseTableView' => 'DiffusionView',
'DiffusionChangeController' => 'DiffusionController',
'DiffusionCommentListView' => 'AphrontView',
'DiffusionCommentView' => 'AphrontView',
'DiffusionCommitBranchesController' => 'DiffusionController',
'DiffusionCommitChangeTableView' => 'DiffusionView',
'DiffusionCommitController' => 'DiffusionController',
'DiffusionCommitEditController' => 'DiffusionController',
'DiffusionCommitParentsQuery' => 'DiffusionQuery',
'DiffusionCommitQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'DiffusionCommitTagsController' => 'DiffusionController',
'DiffusionCommitTagsQuery' => 'DiffusionQuery',
'DiffusionContainsQuery' => 'DiffusionQuery',
'DiffusionController' => 'PhabricatorController',
'DiffusionDiffController' => 'DiffusionController',
'DiffusionDiffQuery' => 'DiffusionQuery',
'DiffusionEmptyResultView' => 'DiffusionView',
'DiffusionExistsQuery' => 'DiffusionQuery',
'DiffusionExternalController' => 'DiffusionController',
'DiffusionFileContentQuery' => 'DiffusionQuery',
'DiffusionGitBranchQuery' => 'DiffusionBranchQuery',
'DiffusionGitBranchQueryTestCase' => 'PhabricatorTestCase',
'DiffusionGitBrowseQuery' => 'DiffusionBrowseQuery',
'DiffusionGitCommitParentsQuery' => 'DiffusionCommitParentsQuery',
'DiffusionGitCommitTagsQuery' => 'DiffusionCommitTagsQuery',
'DiffusionGitContainsQuery' => 'DiffusionContainsQuery',
'DiffusionGitDiffQuery' => 'DiffusionDiffQuery',
'DiffusionGitExistsQuery' => 'DiffusionExistsQuery',
'DiffusionGitFileContentQuery' => 'DiffusionFileContentQuery',
'DiffusionGitHistoryQuery' => 'DiffusionHistoryQuery',
'DiffusionGitLastModifiedQuery' => 'DiffusionLastModifiedQuery',
'DiffusionGitMergedCommitsQuery' => 'DiffusionMergedCommitsQuery',
'DiffusionGitRawDiffQuery' => 'DiffusionRawDiffQuery',
'DiffusionGitRequest' => 'DiffusionRequest',
'DiffusionGitTagListQuery' => 'DiffusionTagListQuery',
'DiffusionHistoryController' => 'DiffusionController',
'DiffusionHistoryQuery' => 'DiffusionQuery',
'DiffusionHistoryTableView' => 'DiffusionView',
'DiffusionHomeController' => 'DiffusionController',
'DiffusionInlineCommentController' => 'PhabricatorInlineCommentController',
'DiffusionInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController',
'DiffusionLastModifiedController' => 'DiffusionController',
'DiffusionLastModifiedQuery' => 'DiffusionQuery',
'DiffusionLintController' => 'DiffusionController',
'DiffusionLintDetailsController' => 'DiffusionController',
'DiffusionMercurialBranchQuery' => 'DiffusionBranchQuery',
'DiffusionMercurialBrowseQuery' => 'DiffusionBrowseQuery',
'DiffusionMercurialCommitParentsQuery' => 'DiffusionCommitParentsQuery',
'DiffusionMercurialCommitTagsQuery' => 'DiffusionCommitTagsQuery',
'DiffusionMercurialContainsQuery' => 'DiffusionContainsQuery',
'DiffusionMercurialDiffQuery' => 'DiffusionDiffQuery',
'DiffusionMercurialExistsQuery' => 'DiffusionExistsQuery',
'DiffusionMercurialFileContentQuery' => 'DiffusionFileContentQuery',
'DiffusionMercurialHistoryQuery' => 'DiffusionHistoryQuery',
'DiffusionMercurialLastModifiedQuery' => 'DiffusionLastModifiedQuery',
'DiffusionMercurialMergedCommitsQuery' => 'DiffusionMergedCommitsQuery',
'DiffusionMercurialRawDiffQuery' => 'DiffusionRawDiffQuery',
'DiffusionMercurialRequest' => 'DiffusionRequest',
'DiffusionMercurialTagListQuery' => 'DiffusionTagListQuery',
'DiffusionMergedCommitsQuery' => 'DiffusionQuery',
'DiffusionPathCompleteController' => 'DiffusionController',
'DiffusionPathQueryTestCase' => 'PhabricatorTestCase',
'DiffusionPathValidateController' => 'DiffusionController',
'DiffusionPeopleMenuEventListener' => 'PhutilEventListener',
'DiffusionRawDiffQuery' => 'DiffusionQuery',
'DiffusionRemarkupRule' => 'PhabricatorRemarkupRuleObject',
'DiffusionRepositoryController' => 'DiffusionController',
'DiffusionSetupException' => 'AphrontUsageException',
'DiffusionSvnBrowseQuery' => 'DiffusionBrowseQuery',
'DiffusionSvnCommitParentsQuery' => 'DiffusionCommitParentsQuery',
'DiffusionSvnCommitTagsQuery' => 'DiffusionCommitTagsQuery',
'DiffusionSvnContainsQuery' => 'DiffusionContainsQuery',
'DiffusionSvnDiffQuery' => 'DiffusionDiffQuery',
'DiffusionSvnExistsQuery' => 'DiffusionExistsQuery',
'DiffusionSvnFileContentQuery' => 'DiffusionFileContentQuery',
'DiffusionSvnHistoryQuery' => 'DiffusionHistoryQuery',
'DiffusionSvnLastModifiedQuery' => 'DiffusionLastModifiedQuery',
'DiffusionSvnMergedCommitsQuery' => 'DiffusionMergedCommitsQuery',
'DiffusionSvnRawDiffQuery' => 'DiffusionRawDiffQuery',
'DiffusionSvnRequest' => 'DiffusionRequest',
'DiffusionSvnTagListQuery' => 'DiffusionTagListQuery',
'DiffusionSymbolController' => 'DiffusionController',
'DiffusionSymbolQuery' => 'PhabricatorOffsetPagedQuery',
'DiffusionTagListController' => 'DiffusionController',
'DiffusionTagListQuery' => 'DiffusionQuery',
'DiffusionTagListView' => 'DiffusionView',
'DiffusionURITestCase' => 'ArcanistPhutilTestCase',
'DiffusionView' => 'AphrontView',
'DivinerArticleAtomizer' => 'DivinerAtomizer',
'DivinerAtomCache' => 'DivinerDiskCache',
'DivinerAtomizeWorkflow' => 'DivinerWorkflow',
'DivinerDefaultRenderer' => 'DivinerRenderer',
'DivinerFileAtomizer' => 'DivinerAtomizer',
'DivinerGenerateWorkflow' => 'DivinerWorkflow',
'DivinerListController' => 'PhabricatorController',
'DivinerPublishCache' => 'DivinerDiskCache',
'DivinerRemarkupRuleSymbol' => 'PhutilRemarkupRule',
'DivinerStaticPublisher' => 'DivinerPublisher',
'DivinerWorkflow' => 'PhutilArgumentWorkflow',
'DrydockAllocatorWorker' => 'PhabricatorWorker',
'DrydockApacheWebrootInterface' => 'DrydockWebrootInterface',
'DrydockCommandInterface' => 'DrydockInterface',
'DrydockController' => 'PhabricatorController',
'DrydockDAO' => 'PhabricatorLiskDAO',
'DrydockLease' => 'DrydockDAO',
'DrydockLeaseListController' => 'DrydockController',
'DrydockLeaseQuery' => 'PhabricatorOffsetPagedQuery',
'DrydockLeaseReleaseController' => 'DrydockController',
'DrydockLeaseStatus' => 'DrydockConstants',
'DrydockLeaseViewController' => 'DrydockController',
'DrydockLocalCommandInterface' => 'DrydockCommandInterface',
'DrydockLocalHostBlueprint' => 'DrydockBlueprint',
'DrydockLog' => 'DrydockDAO',
'DrydockLogController' => 'DrydockController',
'DrydockLogQuery' => 'PhabricatorOffsetPagedQuery',
'DrydockManagementCloseWorkflow' => 'DrydockManagementWorkflow',
'DrydockManagementLeaseWorkflow' => 'DrydockManagementWorkflow',
'DrydockManagementReleaseWorkflow' => 'DrydockManagementWorkflow',
'DrydockManagementWaitForLeaseWorkflow' => 'DrydockManagementWorkflow',
'DrydockManagementWorkflow' => 'PhutilArgumentWorkflow',
'DrydockResource' => 'DrydockDAO',
'DrydockResourceCloseController' => 'DrydockController',
'DrydockResourceListController' => 'DrydockController',
'DrydockResourceQuery' => 'PhabricatorOffsetPagedQuery',
'DrydockResourceStatus' => 'DrydockConstants',
'DrydockResourceViewController' => 'DrydockController',
'DrydockSSHCommandInterface' => 'DrydockCommandInterface',
'DrydockWebrootInterface' => 'DrydockInterface',
'DrydockWorkingCopyBlueprint' => 'DrydockBlueprint',
'FeedPublisherWorker' => 'PhabricatorWorker',
'HarbormasterDAO' => 'PhabricatorLiskDAO',
'HarbormasterObject' => 'HarbormasterDAO',
'HarbormasterRunnerWorker' => 'PhabricatorWorker',
'HarbormasterScratchTable' => 'HarbormasterDAO',
'HeraldAction' => 'HeraldDAO',
'HeraldApplyTranscript' => 'HeraldDAO',
'HeraldCommitAdapter' => 'HeraldObjectAdapter',
'HeraldCondition' => 'HeraldDAO',
'HeraldController' => 'PhabricatorController',
'HeraldDAO' => 'PhabricatorLiskDAO',
'HeraldDeleteController' => 'HeraldController',
'HeraldDifferentialRevisionAdapter' => 'HeraldObjectAdapter',
'HeraldDryRunAdapter' => 'HeraldObjectAdapter',
'HeraldEditLogQuery' => 'PhabricatorOffsetPagedQuery',
'HeraldHomeController' => 'HeraldController',
'HeraldInvalidConditionException' => 'Exception',
'HeraldInvalidFieldException' => 'Exception',
'HeraldNewController' => 'HeraldController',
'HeraldRecursiveConditionsException' => 'Exception',
'HeraldRule' => 'HeraldDAO',
'HeraldRuleController' => 'HeraldController',
'HeraldRuleEdit' => 'HeraldDAO',
'HeraldRuleEditHistoryController' => 'HeraldController',
'HeraldRuleEditHistoryView' => 'AphrontView',
'HeraldRuleListView' => 'AphrontView',
'HeraldRuleQuery' => 'PhabricatorOffsetPagedQuery',
'HeraldTestConsoleController' => 'HeraldController',
'HeraldTranscript' => 'HeraldDAO',
'HeraldTranscriptController' => 'HeraldController',
'HeraldTranscriptListController' => 'HeraldController',
'JavelinReactorExample' => 'PhabricatorUIExample',
'JavelinUIExample' => 'PhabricatorUIExample',
'JavelinViewExample' => 'PhabricatorUIExample',
'JavelinViewExampleServerView' => 'AphrontView',
'LiskChunkTestCase' => 'PhabricatorTestCase',
'LiskDAOTestCase' => 'PhabricatorTestCase',
'LiskEphemeralObjectException' => 'Exception',
'LiskFixtureTestCase' => 'PhabricatorTestCase',
'LiskIsolationTestCase' => 'PhabricatorTestCase',
'LiskIsolationTestDAO' => 'LiskDAO',
'LiskIsolationTestDAOException' => 'Exception',
'LiskMigrationIterator' => 'PhutilBufferedIterator',
'ManiphestAction' => 'ManiphestConstants',
'ManiphestAuxiliaryFieldDefaultSpecification' => 'ManiphestAuxiliaryFieldSpecification',
'ManiphestAuxiliaryFieldSpecification' => 'PhabricatorMarkupInterface',
'ManiphestAuxiliaryFieldTypeException' => 'Exception',
'ManiphestAuxiliaryFieldValidationException' => 'Exception',
'ManiphestBatchEditController' => 'ManiphestController',
'ManiphestController' => 'PhabricatorController',
'ManiphestDAO' => 'PhabricatorLiskDAO',
'ManiphestDefaultTaskExtensions' => 'ManiphestTaskExtensions',
'ManiphestEdgeEventListener' => 'PhutilEventListener',
'ManiphestExportController' => 'ManiphestController',
'ManiphestPeopleMenuEventListener' => 'PhutilEventListener',
'ManiphestRemarkupRule' => 'PhabricatorRemarkupRuleObject',
'ManiphestReplyHandler' => 'PhabricatorMailReplyHandler',
'ManiphestReportController' => 'ManiphestController',
'ManiphestSavedQuery' => 'ManiphestDAO',
'ManiphestSavedQueryDeleteController' => 'ManiphestController',
'ManiphestSavedQueryEditController' => 'ManiphestController',
'ManiphestSavedQueryListController' => 'ManiphestController',
'ManiphestSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
'ManiphestSubpriorityController' => 'ManiphestController',
'ManiphestTask' =>
array(
0 => 'ManiphestDAO',
1 => 'PhabricatorMarkupInterface',
2 => 'PhabricatorPolicyInterface',
3 => 'PhabricatorTokenReceiverInterface',
),
'ManiphestTaskAuxiliaryStorage' => 'ManiphestDAO',
'ManiphestTaskDescriptionChangeController' => 'ManiphestController',
'ManiphestTaskDescriptionPreviewController' => 'ManiphestController',
'ManiphestTaskDetailController' => 'ManiphestController',
'ManiphestTaskEditController' => 'ManiphestController',
'ManiphestTaskListController' => 'ManiphestController',
'ManiphestTaskListView' => 'ManiphestView',
'ManiphestTaskOwner' => 'ManiphestConstants',
'ManiphestTaskPriority' => 'ManiphestConstants',
'ManiphestTaskProject' => 'ManiphestDAO',
'ManiphestTaskProjectsView' => 'ManiphestView',
'ManiphestTaskQuery' => 'PhabricatorQuery',
'ManiphestTaskStatus' => 'ManiphestConstants',
'ManiphestTaskSubscriber' => 'ManiphestDAO',
'ManiphestTaskSummaryView' => 'ManiphestView',
'ManiphestTransaction' =>
array(
0 => 'ManiphestDAO',
1 => 'PhabricatorMarkupInterface',
),
'ManiphestTransactionDetailView' => 'ManiphestView',
'ManiphestTransactionEditor' => 'PhabricatorEditor',
'ManiphestTransactionListView' => 'ManiphestView',
'ManiphestTransactionPreviewController' => 'ManiphestController',
'ManiphestTransactionSaveController' => 'ManiphestController',
'ManiphestTransactionType' => 'ManiphestConstants',
'ManiphestView' => 'AphrontView',
'MetaMTANotificationType' => 'MetaMTAConstants',
'OwnersPackageReplyHandler' => 'PhabricatorMailReplyHandler',
'PackageCreateMail' => 'PackageMail',
'PackageDeleteMail' => 'PackageMail',
'PackageMail' => 'PhabricatorMail',
'PackageModifyMail' => 'PackageMail',
'PasteEmbedView' => 'AphrontView',
'Phabricator404Controller' => 'PhabricatorController',
'PhabricatorAWSConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorAccessLogConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorActionListExample' => 'PhabricatorUIExample',
'PhabricatorActionListView' => 'AphrontView',
'PhabricatorActionView' => 'AphrontView',
'PhabricatorAllCapsTranslation' => 'PhabricatorTranslation',
'PhabricatorAnchorView' => 'AphrontView',
'PhabricatorAphrontBarExample' => 'PhabricatorUIExample',
'PhabricatorApplicationApplications' => 'PhabricatorApplication',
'PhabricatorApplicationAudit' => 'PhabricatorApplication',
'PhabricatorApplicationAuth' => 'PhabricatorApplication',
'PhabricatorApplicationCalendar' => 'PhabricatorApplication',
'PhabricatorApplicationChatLog' => 'PhabricatorApplication',
'PhabricatorApplicationConduit' => 'PhabricatorApplication',
'PhabricatorApplicationConfig' => 'PhabricatorApplication',
'PhabricatorApplicationConfigOptions' => 'Phobject',
'PhabricatorApplicationConpherence' => 'PhabricatorApplication',
'PhabricatorApplicationCountdown' => 'PhabricatorApplication',
'PhabricatorApplicationDaemons' => 'PhabricatorApplication',
'PhabricatorApplicationDetailViewController' => 'PhabricatorApplicationsController',
'PhabricatorApplicationDifferential' => 'PhabricatorApplication',
'PhabricatorApplicationDiffusion' => 'PhabricatorApplication',
'PhabricatorApplicationDiviner' => 'PhabricatorApplication',
'PhabricatorApplicationDrydock' => 'PhabricatorApplication',
'PhabricatorApplicationFact' => 'PhabricatorApplication',
'PhabricatorApplicationFeed' => 'PhabricatorApplication',
'PhabricatorApplicationFiles' => 'PhabricatorApplication',
'PhabricatorApplicationFlags' => 'PhabricatorApplication',
'PhabricatorApplicationHerald' => 'PhabricatorApplication',
'PhabricatorApplicationLaunchView' => 'AphrontView',
'PhabricatorApplicationMacro' => 'PhabricatorApplication',
'PhabricatorApplicationMailingLists' => 'PhabricatorApplication',
'PhabricatorApplicationManiphest' => 'PhabricatorApplication',
'PhabricatorApplicationMetaMTA' => 'PhabricatorApplication',
'PhabricatorApplicationOwners' => 'PhabricatorApplication',
'PhabricatorApplicationPHID' => 'PhabricatorApplication',
'PhabricatorApplicationPHPAST' => 'PhabricatorApplication',
'PhabricatorApplicationPaste' => 'PhabricatorApplication',
'PhabricatorApplicationPeople' => 'PhabricatorApplication',
'PhabricatorApplicationPhame' => 'PhabricatorApplication',
'PhabricatorApplicationPholio' => 'PhabricatorApplication',
'PhabricatorApplicationPhriction' => 'PhabricatorApplication',
'PhabricatorApplicationPonder' => 'PhabricatorApplication',
'PhabricatorApplicationProject' => 'PhabricatorApplication',
+ 'PhabricatorApplicationReleeph' => 'PhabricatorApplication',
+ 'PhabricatorApplicationReleephConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorApplicationRepositories' => 'PhabricatorApplication',
'PhabricatorApplicationSettings' => 'PhabricatorApplication',
'PhabricatorApplicationSlowvote' => 'PhabricatorApplication',
'PhabricatorApplicationStatusView' => 'AphrontView',
'PhabricatorApplicationSubscriptions' => 'PhabricatorApplication',
'PhabricatorApplicationTokens' => 'PhabricatorApplication',
'PhabricatorApplicationTransaction' =>
array(
0 => 'PhabricatorLiskDAO',
1 => 'PhabricatorPolicyInterface',
),
'PhabricatorApplicationTransactionComment' =>
array(
0 => 'PhabricatorLiskDAO',
1 => 'PhabricatorMarkupInterface',
2 => 'PhabricatorPolicyInterface',
),
'PhabricatorApplicationTransactionCommentEditController' => 'PhabricatorApplicationTransactionController',
'PhabricatorApplicationTransactionCommentEditor' => 'PhabricatorEditor',
'PhabricatorApplicationTransactionCommentHistoryController' => 'PhabricatorApplicationTransactionController',
'PhabricatorApplicationTransactionCommentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorApplicationTransactionCommentView' => 'AphrontView',
'PhabricatorApplicationTransactionController' => 'PhabricatorController',
'PhabricatorApplicationTransactionEditor' => 'PhabricatorEditor',
'PhabricatorApplicationTransactionFeedStory' => 'PhabricatorFeedStory',
'PhabricatorApplicationTransactionNoEffectException' => 'Exception',
'PhabricatorApplicationTransactionNoEffectResponse' => 'AphrontProxyResponse',
'PhabricatorApplicationTransactionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorApplicationTransactionResponse' => 'AphrontProxyResponse',
'PhabricatorApplicationTransactionTextDiffDetailView' => 'AphrontView',
'PhabricatorApplicationTransactionView' => 'AphrontView',
'PhabricatorApplicationTransactions' => 'PhabricatorApplication',
'PhabricatorApplicationUIExamples' => 'PhabricatorApplication',
'PhabricatorApplicationUninstallController' => 'PhabricatorApplicationsController',
'PhabricatorApplicationsController' => 'PhabricatorController',
'PhabricatorApplicationsListController' => 'PhabricatorApplicationsController',
'PhabricatorAuditAddCommentController' => 'PhabricatorAuditController',
'PhabricatorAuditComment' =>
array(
0 => 'PhabricatorAuditDAO',
1 => 'PhabricatorMarkupInterface',
),
'PhabricatorAuditCommentEditor' => 'PhabricatorEditor',
'PhabricatorAuditCommitListView' => 'AphrontView',
'PhabricatorAuditController' => 'PhabricatorController',
'PhabricatorAuditDAO' => 'PhabricatorLiskDAO',
'PhabricatorAuditInlineComment' =>
array(
0 => 'PhabricatorAuditDAO',
1 => 'PhabricatorInlineCommentInterface',
),
'PhabricatorAuditListController' => 'PhabricatorAuditController',
'PhabricatorAuditListView' => 'AphrontView',
'PhabricatorAuditPreviewController' => 'PhabricatorAuditController',
'PhabricatorAuditReplyHandler' => 'PhabricatorMailReplyHandler',
'PhabricatorAuthController' => 'PhabricatorController',
'PhabricatorAuthenticationConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorBarePageExample' => 'PhabricatorUIExample',
'PhabricatorBarePageView' => 'AphrontPageView',
'PhabricatorBaseEnglishTranslation' => 'PhabricatorTranslation',
'PhabricatorBot' => 'PhabricatorDaemon',
'PhabricatorBotBaseStreamingProtocolAdapter' => 'PhabricatorBaseProtocolAdapter',
'PhabricatorBotChannel' => 'PhabricatorBotTarget',
'PhabricatorBotDebugLogHandler' => 'PhabricatorBotHandler',
'PhabricatorBotDifferentialNotificationHandler' => 'PhabricatorBotHandler',
'PhabricatorBotFeedNotificationHandler' => 'PhabricatorBotHandler',
'PhabricatorBotFlowdockProtocolAdapter' => 'PhabricatorBotBaseStreamingProtocolAdapter',
'PhabricatorBotLogHandler' => 'PhabricatorBotHandler',
'PhabricatorBotMacroHandler' => 'PhabricatorBotHandler',
'PhabricatorBotObjectNameHandler' => 'PhabricatorBotHandler',
'PhabricatorBotSymbolHandler' => 'PhabricatorBotHandler',
'PhabricatorBotUser' => 'PhabricatorBotTarget',
'PhabricatorBotWhatsNewHandler' => 'PhabricatorBotHandler',
'PhabricatorBuiltinPatchList' => 'PhabricatorSQLPatchList',
'PhabricatorButtonsExample' => 'PhabricatorUIExample',
'PhabricatorCacheDAO' => 'PhabricatorLiskDAO',
'PhabricatorCalendarBrowseController' => 'PhabricatorCalendarController',
'PhabricatorCalendarController' => 'PhabricatorController',
'PhabricatorCalendarDAO' => 'PhabricatorLiskDAO',
'PhabricatorCalendarDeleteStatusController' => 'PhabricatorCalendarController',
'PhabricatorCalendarEditStatusController' => 'PhabricatorCalendarController',
'PhabricatorCalendarHoliday' => 'PhabricatorCalendarDAO',
'PhabricatorCalendarHolidayTestCase' => 'PhabricatorTestCase',
'PhabricatorCalendarViewStatusController' => 'PhabricatorCalendarController',
'PhabricatorCampfireProtocolAdapter' => 'PhabricatorBotBaseStreamingProtocolAdapter',
'PhabricatorChangesetResponse' => 'AphrontProxyResponse',
'PhabricatorChatLogChannel' =>
array(
0 => 'PhabricatorChatLogDAO',
1 => 'PhabricatorPolicyInterface',
),
'PhabricatorChatLogChannelListController' => 'PhabricatorChatLogController',
'PhabricatorChatLogChannelLogController' => 'PhabricatorChatLogController',
'PhabricatorChatLogChannelQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorChatLogController' => 'PhabricatorController',
'PhabricatorChatLogDAO' => 'PhabricatorLiskDAO',
'PhabricatorChatLogEvent' =>
array(
0 => 'PhabricatorChatLogDAO',
1 => 'PhabricatorPolicyInterface',
),
'PhabricatorChatLogEventType' => 'PhabricatorChatLogConstants',
'PhabricatorChatLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorConduitAPIController' => 'PhabricatorConduitController',
'PhabricatorConduitCertificateToken' => 'PhabricatorConduitDAO',
'PhabricatorConduitConnectionLog' => 'PhabricatorConduitDAO',
'PhabricatorConduitConsoleController' => 'PhabricatorConduitController',
'PhabricatorConduitController' => 'PhabricatorController',
'PhabricatorConduitDAO' => 'PhabricatorLiskDAO',
'PhabricatorConduitListController' => 'PhabricatorConduitController',
'PhabricatorConduitLogController' => 'PhabricatorConduitController',
'PhabricatorConduitMethodCallLog' => 'PhabricatorConduitDAO',
'PhabricatorConduitTokenController' => 'PhabricatorConduitController',
'PhabricatorConfigAllController' => 'PhabricatorConfigController',
'PhabricatorConfigController' => 'PhabricatorController',
'PhabricatorConfigDatabaseSource' => 'PhabricatorConfigProxySource',
'PhabricatorConfigDefaultSource' => 'PhabricatorConfigProxySource',
'PhabricatorConfigDictionarySource' => 'PhabricatorConfigSource',
'PhabricatorConfigEditController' => 'PhabricatorConfigController',
'PhabricatorConfigEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorConfigEntry' => 'PhabricatorConfigEntryDAO',
'PhabricatorConfigEntryDAO' => 'PhabricatorLiskDAO',
'PhabricatorConfigFileSource' => 'PhabricatorConfigProxySource',
'PhabricatorConfigGroupController' => 'PhabricatorConfigController',
'PhabricatorConfigIgnoreController' => 'PhabricatorApplicationsController',
'PhabricatorConfigIssueListController' => 'PhabricatorConfigController',
'PhabricatorConfigIssueViewController' => 'PhabricatorConfigController',
'PhabricatorConfigListController' => 'PhabricatorConfigController',
'PhabricatorConfigLocalSource' => 'PhabricatorConfigProxySource',
'PhabricatorConfigManagementDeleteWorkflow' => 'PhabricatorConfigManagementWorkflow',
'PhabricatorConfigManagementGetWorkflow' => 'PhabricatorConfigManagementWorkflow',
'PhabricatorConfigManagementListWorkflow' => 'PhabricatorConfigManagementWorkflow',
'PhabricatorConfigManagementSetWorkflow' => 'PhabricatorConfigManagementWorkflow',
'PhabricatorConfigManagementWorkflow' => 'PhutilArgumentWorkflow',
'PhabricatorConfigOption' =>
array(
0 => 'Phobject',
1 => 'PhabricatorMarkupInterface',
),
'PhabricatorConfigProxySource' => 'PhabricatorConfigSource',
'PhabricatorConfigResponse' => 'AphrontHTMLResponse',
'PhabricatorConfigStackSource' => 'PhabricatorConfigSource',
'PhabricatorConfigTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorConfigTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorConfigValidationException' => 'Exception',
'PhabricatorContentSourceView' => 'AphrontView',
'PhabricatorController' => 'AphrontController',
'PhabricatorCoreConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorCountdownController' => 'PhabricatorController',
'PhabricatorCountdownDAO' => 'PhabricatorLiskDAO',
'PhabricatorCountdownDeleteController' => 'PhabricatorCountdownController',
'PhabricatorCountdownEditController' => 'PhabricatorCountdownController',
'PhabricatorCountdownListController' => 'PhabricatorCountdownController',
'PhabricatorCountdownRemarkupRule' => 'PhutilRemarkupRule',
'PhabricatorCountdownViewController' => 'PhabricatorCountdownController',
'PhabricatorCountedToggleButtonsExample' => 'PhabricatorUIExample',
'PhabricatorCrumbView' => 'AphrontView',
'PhabricatorCrumbsView' => 'AphrontView',
'PhabricatorCursorPagedPolicyAwareQuery' => 'PhabricatorPolicyAwareQuery',
'PhabricatorDaemon' => 'PhutilDaemon',
'PhabricatorDaemonCombinedLogController' => 'PhabricatorDaemonController',
'PhabricatorDaemonConsoleController' => 'PhabricatorDaemonController',
'PhabricatorDaemonController' => 'PhabricatorController',
'PhabricatorDaemonDAO' => 'PhabricatorLiskDAO',
'PhabricatorDaemonLog' => 'PhabricatorDaemonDAO',
'PhabricatorDaemonLogEvent' => 'PhabricatorDaemonDAO',
'PhabricatorDaemonLogEventsView' => 'AphrontView',
'PhabricatorDaemonLogListController' => 'PhabricatorDaemonController',
'PhabricatorDaemonLogListView' => 'AphrontView',
'PhabricatorDaemonLogViewController' => 'PhabricatorDaemonController',
'PhabricatorDebugController' => 'PhabricatorController',
'PhabricatorDefaultFileStorageEngineSelector' => 'PhabricatorFileStorageEngineSelector',
'PhabricatorDefaultSearchEngineSelector' => 'PhabricatorSearchEngineSelector',
'PhabricatorDeveloperConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorDifferentialConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorDiffusionConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorDirectoryController' => 'PhabricatorController',
'PhabricatorDirectoryMainController' => 'PhabricatorDirectoryController',
'PhabricatorDisabledUserController' => 'PhabricatorAuthController',
'PhabricatorDisqusConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorDraft' => 'PhabricatorDraftDAO',
'PhabricatorDraftDAO' => 'PhabricatorLiskDAO',
'PhabricatorEdgeConfig' => 'PhabricatorEdgeConstants',
'PhabricatorEdgeCycleException' => 'Exception',
'PhabricatorEdgeEditor' => 'PhabricatorEditor',
'PhabricatorEdgeGraph' => 'AbstractDirectedGraph',
'PhabricatorEdgeQuery' => 'PhabricatorQuery',
'PhabricatorEdgeTestCase' => 'PhabricatorTestCase',
'PhabricatorEditor' => 'Phobject',
'PhabricatorEmailLoginController' => 'PhabricatorAuthController',
'PhabricatorEmailTokenController' => 'PhabricatorAuthController',
'PhabricatorEmailVerificationController' => 'PhabricatorPeopleController',
'PhabricatorEmptyQueryException' => 'Exception',
'PhabricatorEnglishTranslation' => 'PhabricatorBaseEnglishTranslation',
'PhabricatorEnvTestCase' => 'PhabricatorTestCase',
'PhabricatorErrorExample' => 'PhabricatorUIExample',
'PhabricatorEvent' => 'PhutilEvent',
'PhabricatorEventType' => 'PhutilEventType',
'PhabricatorExampleEventListener' => 'PhutilEventListener',
'PhabricatorExtendingPhabricatorConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorFacebookConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorFactAggregate' => 'PhabricatorFactDAO',
'PhabricatorFactChartController' => 'PhabricatorFactController',
'PhabricatorFactController' => 'PhabricatorController',
'PhabricatorFactCountEngine' => 'PhabricatorFactEngine',
'PhabricatorFactCursor' => 'PhabricatorFactDAO',
'PhabricatorFactDAO' => 'PhabricatorLiskDAO',
'PhabricatorFactDaemon' => 'PhabricatorDaemon',
'PhabricatorFactHomeController' => 'PhabricatorFactController',
'PhabricatorFactLastUpdatedEngine' => 'PhabricatorFactEngine',
'PhabricatorFactManagementAnalyzeWorkflow' => 'PhabricatorFactManagementWorkflow',
'PhabricatorFactManagementCursorsWorkflow' => 'PhabricatorFactManagementWorkflow',
'PhabricatorFactManagementDestroyWorkflow' => 'PhabricatorFactManagementWorkflow',
'PhabricatorFactManagementListWorkflow' => 'PhabricatorFactManagementWorkflow',
'PhabricatorFactManagementStatusWorkflow' => 'PhabricatorFactManagementWorkflow',
'PhabricatorFactManagementWorkflow' => 'PhutilArgumentWorkflow',
'PhabricatorFactRaw' => 'PhabricatorFactDAO',
'PhabricatorFactSimpleSpec' => 'PhabricatorFactSpec',
'PhabricatorFactUpdateIterator' => 'PhutilBufferedIterator',
'PhabricatorFeedConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorFeedController' => 'PhabricatorController',
'PhabricatorFeedDAO' => 'PhabricatorLiskDAO',
'PhabricatorFeedMainController' => 'PhabricatorFeedController',
'PhabricatorFeedPublicStreamController' => 'PhabricatorFeedController',
'PhabricatorFeedQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorFeedStory' => 'PhabricatorPolicyInterface',
'PhabricatorFeedStoryAggregate' => 'PhabricatorFeedStory',
'PhabricatorFeedStoryAudit' => 'PhabricatorFeedStory',
'PhabricatorFeedStoryCommit' => 'PhabricatorFeedStory',
'PhabricatorFeedStoryData' => 'PhabricatorFeedDAO',
'PhabricatorFeedStoryDifferential' => 'PhabricatorFeedStory',
'PhabricatorFeedStoryDifferentialAggregate' => 'PhabricatorFeedStoryAggregate',
'PhabricatorFeedStoryManiphest' => 'PhabricatorFeedStory',
'PhabricatorFeedStoryManiphestAggregate' => 'PhabricatorFeedStoryAggregate',
'PhabricatorFeedStoryNotification' => 'PhabricatorFeedDAO',
'PhabricatorFeedStoryPhriction' => 'PhabricatorFeedStory',
'PhabricatorFeedStoryProject' => 'PhabricatorFeedStory',
'PhabricatorFeedStoryReference' => 'PhabricatorFeedDAO',
'PhabricatorFeedStoryStatus' => 'PhabricatorFeedStory',
'PhabricatorFeedStoryTypeConstants' => 'PhabricatorFeedConstants',
'PhabricatorFeedStoryView' => 'PhabricatorFeedView',
'PhabricatorFeedView' => 'AphrontView',
'PhabricatorFile' =>
array(
0 => 'PhabricatorFileDAO',
1 => 'PhabricatorPolicyInterface',
),
'PhabricatorFileController' => 'PhabricatorController',
'PhabricatorFileDAO' => 'PhabricatorLiskDAO',
'PhabricatorFileDataController' => 'PhabricatorFileController',
'PhabricatorFileDeleteController' => 'PhabricatorFileController',
'PhabricatorFileDropUploadController' => 'PhabricatorFileController',
'PhabricatorFileImageMacro' =>
array(
0 => 'PhabricatorFileDAO',
1 => 'PhabricatorSubscribableInterface',
2 => 'PhabricatorApplicationTransactionInterface',
),
'PhabricatorFileInfoController' => 'PhabricatorFileController',
'PhabricatorFileLinkListView' => 'AphrontView',
'PhabricatorFileLinkView' => 'AphrontView',
'PhabricatorFileListController' => 'PhabricatorFileController',
'PhabricatorFileQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorFileShortcutController' => 'PhabricatorFileController',
'PhabricatorFileStorageBlob' => 'PhabricatorFileDAO',
'PhabricatorFileStorageConfigurationException' => 'Exception',
'PhabricatorFileTestCase' => 'PhabricatorTestCase',
'PhabricatorFileTransformController' => 'PhabricatorFileController',
'PhabricatorFileUploadController' => 'PhabricatorFileController',
'PhabricatorFileUploadException' => 'Exception',
'PhabricatorFilesConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorFilesManagementEnginesWorkflow' => 'PhabricatorFilesManagementWorkflow',
'PhabricatorFilesManagementMetadataWorkflow' => 'PhabricatorFilesManagementWorkflow',
'PhabricatorFilesManagementMigrateWorkflow' => 'PhabricatorFilesManagementWorkflow',
'PhabricatorFilesManagementWorkflow' => 'PhutilArgumentWorkflow',
'PhabricatorFlag' => 'PhabricatorFlagDAO',
'PhabricatorFlagColor' => 'PhabricatorFlagConstants',
'PhabricatorFlagController' => 'PhabricatorController',
'PhabricatorFlagDAO' => 'PhabricatorLiskDAO',
'PhabricatorFlagDeleteController' => 'PhabricatorFlagController',
'PhabricatorFlagEditController' => 'PhabricatorFlagController',
'PhabricatorFlagListController' => 'PhabricatorFlagController',
'PhabricatorFlagListView' => 'AphrontView',
'PhabricatorFlagsUIEventListener' => 'PhutilEventListener',
'PhabricatorFormExample' => 'PhabricatorUIExample',
'PhabricatorGarbageCollectorConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorGarbageCollectorDaemon' => 'PhabricatorDaemon',
'PhabricatorGestureExample' => 'PhabricatorUIExample',
'PhabricatorGitHubConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorGlobalLock' => 'PhutilLock',
'PhabricatorGlobalUploadTargetView' => 'AphrontView',
'PhabricatorGoogleConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorHashTestCase' => 'PhabricatorTestCase',
'PhabricatorHeaderView' => 'AphrontView',
'PhabricatorHelpController' => 'PhabricatorController',
'PhabricatorHelpKeyboardShortcutController' => 'PhabricatorHelpController',
'PhabricatorIRCBot' => 'PhabricatorDaemon',
'PhabricatorIRCProtocolAdapter' => 'PhabricatorBaseProtocolAdapter',
'PhabricatorIRCProtocolHandler' => 'PhabricatorBotHandler',
'PhabricatorInfrastructureTestCase' => 'PhabricatorTestCase',
'PhabricatorInlineCommentController' => 'PhabricatorController',
'PhabricatorInlineCommentInterface' => 'PhabricatorMarkupInterface',
'PhabricatorInlineCommentPreviewController' => 'PhabricatorController',
'PhabricatorInlineSummaryView' => 'AphrontView',
'PhabricatorJavelinLinter' => 'ArcanistLinter',
'PhabricatorKeyValueDatabaseCache' => 'PhutilKeyValueCache',
'PhabricatorLDAPConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorLDAPLoginController' => 'PhabricatorAuthController',
'PhabricatorLDAPRegistrationController' => 'PhabricatorAuthController',
'PhabricatorLDAPUnknownUserException' => 'Exception',
'PhabricatorLDAPUnlinkController' => 'PhabricatorAuthController',
'PhabricatorLintEngine' => 'PhutilLintEngine',
'PhabricatorLiskDAO' => 'LiskDAO',
'PhabricatorLocalDiskFileStorageEngine' => 'PhabricatorFileStorageEngine',
'PhabricatorLocalTimeTestCase' => 'PhabricatorTestCase',
'PhabricatorLoginController' => 'PhabricatorAuthController',
'PhabricatorLoginValidateController' => 'PhabricatorAuthController',
'PhabricatorLogoutController' => 'PhabricatorAuthController',
'PhabricatorMacroCommentController' => 'PhabricatorMacroController',
'PhabricatorMacroConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorMacroController' => 'PhabricatorController',
'PhabricatorMacroDisableController' => 'PhabricatorMacroController',
'PhabricatorMacroEditController' => 'PhabricatorMacroController',
'PhabricatorMacroEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorMacroListController' => 'PhabricatorMacroController',
'PhabricatorMacroMemeController' => 'PhabricatorMacroController',
'PhabricatorMacroMemeDialogController' => 'PhabricatorMacroController',
'PhabricatorMacroReplyHandler' => 'PhabricatorMailReplyHandler',
'PhabricatorMacroTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorMacroTransactionComment' => 'PhabricatorApplicationTransactionComment',
'PhabricatorMacroTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorMacroViewController' => 'PhabricatorMacroController',
'PhabricatorMailImplementationAmazonSESAdapter' => 'PhabricatorMailImplementationPHPMailerLiteAdapter',
'PhabricatorMailImplementationPHPMailerAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMailImplementationSendGridAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMailImplementationTestAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMailingListsController' => 'PhabricatorController',
'PhabricatorMailingListsEditController' => 'PhabricatorMailingListsController',
'PhabricatorMailingListsListController' => 'PhabricatorMailingListsController',
'PhabricatorMainMenuGroupView' => 'AphrontView',
'PhabricatorMainMenuIconView' => 'AphrontView',
'PhabricatorMainMenuSearchView' => 'AphrontView',
'PhabricatorMainMenuView' => 'AphrontView',
'PhabricatorManiphestConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorMarkupCache' => 'PhabricatorCacheDAO',
'PhabricatorMenuItemView' => 'AphrontTagView',
'PhabricatorMenuView' => 'AphrontTagView',
'PhabricatorMenuViewTestCase' => 'PhabricatorTestCase',
'PhabricatorMetaMTAConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorMetaMTAController' => 'PhabricatorController',
'PhabricatorMetaMTADAO' => 'PhabricatorLiskDAO',
'PhabricatorMetaMTAEmailBodyParserTestCase' => 'PhabricatorTestCase',
'PhabricatorMetaMTAListController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAMail' => 'PhabricatorMetaMTADAO',
'PhabricatorMetaMTAMailBodyTestCase' => 'PhabricatorTestCase',
'PhabricatorMetaMTAMailTestCase' => 'PhabricatorTestCase',
'PhabricatorMetaMTAMailingList' => 'PhabricatorMetaMTADAO',
'PhabricatorMetaMTAReceiveController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAReceivedListController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAReceivedMail' => 'PhabricatorMetaMTADAO',
'PhabricatorMetaMTASendController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTASendGridReceiveController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAViewController' => 'PhabricatorMetaMTAController',
'PhabricatorMetaMTAWorker' => 'PhabricatorWorker',
'PhabricatorMustVerifyEmailController' => 'PhabricatorAuthController',
'PhabricatorMySQLConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorMySQLFileStorageEngine' => 'PhabricatorFileStorageEngine',
'PhabricatorNoteExample' => 'PhabricatorUIExample',
'PhabricatorNotificationClearController' => 'PhabricatorNotificationController',
'PhabricatorNotificationConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorNotificationController' => 'PhabricatorController',
'PhabricatorNotificationIndividualController' => 'PhabricatorNotificationController',
'PhabricatorNotificationListController' => 'PhabricatorNotificationController',
'PhabricatorNotificationPanelController' => 'PhabricatorNotificationController',
'PhabricatorNotificationQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorNotificationStatusController' => 'PhabricatorNotificationController',
'PhabricatorOAuthClientAuthorization' => 'PhabricatorOAuthServerDAO',
'PhabricatorOAuthClientAuthorizationBaseController' => 'PhabricatorOAuthServerController',
'PhabricatorOAuthClientAuthorizationDeleteController' => 'PhabricatorOAuthClientAuthorizationBaseController',
'PhabricatorOAuthClientAuthorizationEditController' => 'PhabricatorOAuthClientAuthorizationBaseController',
'PhabricatorOAuthClientAuthorizationListController' => 'PhabricatorOAuthClientAuthorizationBaseController',
'PhabricatorOAuthClientAuthorizationQuery' => 'PhabricatorOffsetPagedQuery',
'PhabricatorOAuthClientBaseController' => 'PhabricatorOAuthServerController',
'PhabricatorOAuthClientDeleteController' => 'PhabricatorOAuthClientBaseController',
'PhabricatorOAuthClientEditController' => 'PhabricatorOAuthClientBaseController',
'PhabricatorOAuthClientListController' => 'PhabricatorOAuthClientBaseController',
'PhabricatorOAuthClientViewController' => 'PhabricatorOAuthClientBaseController',
'PhabricatorOAuthDefaultRegistrationController' => 'PhabricatorOAuthRegistrationController',
'PhabricatorOAuthDiagnosticsController' => 'PhabricatorAuthController',
'PhabricatorOAuthFailureView' => 'AphrontView',
'PhabricatorOAuthLoginController' => 'PhabricatorAuthController',
'PhabricatorOAuthProviderDisqus' => 'PhabricatorOAuthProvider',
'PhabricatorOAuthProviderException' => 'Exception',
'PhabricatorOAuthProviderFacebook' => 'PhabricatorOAuthProvider',
'PhabricatorOAuthProviderGitHub' => 'PhabricatorOAuthProvider',
'PhabricatorOAuthProviderGoogle' => 'PhabricatorOAuthProvider',
'PhabricatorOAuthProviderPhabricator' => 'PhabricatorOAuthProvider',
'PhabricatorOAuthRegistrationController' => 'PhabricatorAuthController',
'PhabricatorOAuthResponse' => 'AphrontResponse',
'PhabricatorOAuthServerAccessToken' => 'PhabricatorOAuthServerDAO',
'PhabricatorOAuthServerAuthController' => 'PhabricatorAuthController',
'PhabricatorOAuthServerAuthorizationCode' => 'PhabricatorOAuthServerDAO',
'PhabricatorOAuthServerClient' => 'PhabricatorOAuthServerDAO',
'PhabricatorOAuthServerClientQuery' => 'PhabricatorOffsetPagedQuery',
'PhabricatorOAuthServerController' => 'PhabricatorController',
'PhabricatorOAuthServerDAO' => 'PhabricatorLiskDAO',
'PhabricatorOAuthServerTestCase' => 'PhabricatorTestCase',
'PhabricatorOAuthServerTestController' => 'PhabricatorOAuthServerController',
'PhabricatorOAuthServerTokenController' => 'PhabricatorAuthController',
'PhabricatorOAuthUnlinkController' => 'PhabricatorAuthController',
'PhabricatorObjectHandleStatus' => 'PhabricatorObjectHandleConstants',
'PhabricatorObjectItemListExample' => 'PhabricatorUIExample',
'PhabricatorObjectItemListView' => 'AphrontView',
'PhabricatorObjectItemView' => 'AphrontView',
'PhabricatorObjectListView' => 'AphrontView',
'PhabricatorOffsetPagedQuery' => 'PhabricatorQuery',
'PhabricatorOwnersConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorOwnersController' => 'PhabricatorController',
'PhabricatorOwnersDAO' => 'PhabricatorLiskDAO',
'PhabricatorOwnersDeleteController' => 'PhabricatorOwnersController',
'PhabricatorOwnersDetailController' => 'PhabricatorOwnersController',
'PhabricatorOwnersEditController' => 'PhabricatorOwnersController',
'PhabricatorOwnersListController' => 'PhabricatorOwnersController',
'PhabricatorOwnersOwner' => 'PhabricatorOwnersDAO',
'PhabricatorOwnersPackage' =>
array(
0 => 'PhabricatorOwnersDAO',
1 => 'PhabricatorPolicyInterface',
),
'PhabricatorOwnersPackageQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorOwnersPackageTestCase' => 'PhabricatorTestCase',
'PhabricatorOwnersPath' => 'PhabricatorOwnersDAO',
'PhabricatorPHDConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorPHIDConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorPHIDController' => 'PhabricatorController',
'PhabricatorPHIDLookupController' => 'PhabricatorPHIDController',
'PhabricatorPHPMailerConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorPaste' =>
array(
0 => 'PhabricatorPasteDAO',
1 => 'PhabricatorPolicyInterface',
),
'PhabricatorPasteController' => 'PhabricatorController',
'PhabricatorPasteDAO' => 'PhabricatorLiskDAO',
'PhabricatorPasteEditController' => 'PhabricatorPasteController',
'PhabricatorPasteListController' => 'PhabricatorPasteController',
'PhabricatorPasteQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorPasteRemarkupRule' => 'PhabricatorRemarkupRuleObject',
'PhabricatorPasteViewController' => 'PhabricatorPasteController',
'PhabricatorPeopleController' => 'PhabricatorController',
'PhabricatorPeopleEditController' => 'PhabricatorPeopleController',
'PhabricatorPeopleLdapController' => 'PhabricatorPeopleController',
'PhabricatorPeopleListController' => 'PhabricatorPeopleController',
'PhabricatorPeopleLogsController' => 'PhabricatorPeopleController',
'PhabricatorPeopleProfileController' => 'PhabricatorPeopleController',
'PhabricatorPeopleQuery' => 'PhabricatorOffsetPagedQuery',
'PhabricatorPhabricatorOAuthConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorPhameConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorPholioConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorPhrictionConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorPinboardItemView' => 'AphrontView',
'PhabricatorPinboardView' => 'AphrontView',
'PhabricatorPolicies' => 'PhabricatorPolicyConstants',
'PhabricatorPolicyAwareQuery' => 'PhabricatorOffsetPagedQuery',
'PhabricatorPolicyAwareTestQuery' => 'PhabricatorPolicyAwareQuery',
'PhabricatorPolicyCapability' => 'PhabricatorPolicyConstants',
'PhabricatorPolicyConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorPolicyException' => 'Exception',
'PhabricatorPolicyQuery' => 'PhabricatorQuery',
'PhabricatorPolicyTestCase' => 'PhabricatorTestCase',
'PhabricatorPolicyTestObject' => 'PhabricatorPolicyInterface',
'PhabricatorPolicyType' => 'PhabricatorPolicyConstants',
'PhabricatorProfileHeaderView' => 'AphrontView',
'PhabricatorProject' =>
array(
0 => 'PhabricatorProjectDAO',
1 => 'PhabricatorPolicyInterface',
),
'PhabricatorProjectController' => 'PhabricatorController',
'PhabricatorProjectCreateController' => 'PhabricatorProjectController',
'PhabricatorProjectDAO' => 'PhabricatorLiskDAO',
'PhabricatorProjectEditor' => 'PhabricatorEditor',
'PhabricatorProjectEditorTestCase' => 'PhabricatorTestCase',
'PhabricatorProjectListController' => 'PhabricatorProjectController',
'PhabricatorProjectMembersEditController' => 'PhabricatorProjectController',
'PhabricatorProjectNameCollisionException' => 'Exception',
'PhabricatorProjectProfile' => 'PhabricatorProjectDAO',
'PhabricatorProjectProfileController' => 'PhabricatorProjectController',
'PhabricatorProjectProfileEditController' => 'PhabricatorProjectController',
'PhabricatorProjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorProjectTransaction' => 'PhabricatorProjectDAO',
'PhabricatorProjectTransactionType' => 'PhabricatorProjectConstants',
'PhabricatorProjectUpdateController' => 'PhabricatorProjectController',
'PhabricatorPropertyListExample' => 'PhabricatorUIExample',
'PhabricatorPropertyListView' => 'AphrontView',
'PhabricatorRecaptchaConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorRedirectController' => 'PhabricatorController',
'PhabricatorRefreshCSRFController' => 'PhabricatorAuthController',
'PhabricatorRemarkupControl' => 'AphrontFormTextAreaControl',
'PhabricatorRemarkupRuleEmbedFile' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleImageMacro' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleMeme' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleMention' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleObject' => 'PhutilRemarkupRule',
'PhabricatorRemarkupRuleYoutube' => 'PhutilRemarkupRule',
'PhabricatorRepository' =>
array(
0 => 'PhabricatorRepositoryDAO',
1 => 'PhabricatorPolicyInterface',
),
'PhabricatorRepositoryArcanistProject' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryArcanistProjectDeleteController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryArcanistProjectEditController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryAuditRequest' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryBranch' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryCommit' =>
array(
0 => 'PhabricatorRepositoryDAO',
1 => 'PhabricatorPolicyInterface',
),
'PhabricatorRepositoryCommitChangeParserWorker' => 'PhabricatorRepositoryCommitParserWorker',
'PhabricatorRepositoryCommitData' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryCommitHeraldWorker' => 'PhabricatorRepositoryCommitParserWorker',
'PhabricatorRepositoryCommitMessageParserWorker' => 'PhabricatorRepositoryCommitParserWorker',
'PhabricatorRepositoryCommitOwnersWorker' => 'PhabricatorRepositoryCommitParserWorker',
'PhabricatorRepositoryCommitParserWorker' => 'PhabricatorWorker',
'PhabricatorRepositoryCommitSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhabricatorRepositoryConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorRepositoryController' => 'PhabricatorController',
'PhabricatorRepositoryCreateController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryDAO' => 'PhabricatorLiskDAO',
'PhabricatorRepositoryDeleteController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryEditController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
'PhabricatorRepositoryGitCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
'PhabricatorRepositoryListController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryManagementDeleteWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementDiscoverWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementListWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementPullWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementWorkflow' => 'PhutilArgumentWorkflow',
'PhabricatorRepositoryMercurialCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
'PhabricatorRepositoryMercurialCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
'PhabricatorRepositoryPullLocalDaemon' => 'PhabricatorDaemon',
'PhabricatorRepositoryPullLocalDaemonTestCase' => 'PhabricatorTestCase',
'PhabricatorRepositoryQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorRepositoryShortcut' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositorySvnCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
'PhabricatorRepositorySvnCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
'PhabricatorRepositorySymbol' => 'PhabricatorRepositoryDAO',
'PhabricatorRepositoryTestCase' => 'PhabricatorTestCase',
'PhabricatorS3FileStorageEngine' => 'PhabricatorFileStorageEngine',
'PhabricatorSSHWorkflow' => 'PhutilArgumentWorkflow',
'PhabricatorSearchAttachController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchBaseController' => 'PhabricatorController',
'PhabricatorSearchConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorSearchController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchDAO' => 'PhabricatorLiskDAO',
'PhabricatorSearchDocument' => 'PhabricatorSearchDAO',
'PhabricatorSearchDocumentField' => 'PhabricatorSearchDAO',
'PhabricatorSearchDocumentRelationship' => 'PhabricatorSearchDAO',
'PhabricatorSearchEngineElastic' => 'PhabricatorSearchEngine',
'PhabricatorSearchEngineMySQL' => 'PhabricatorSearchEngine',
'PhabricatorSearchManagementIndexWorkflow' => 'PhabricatorSearchManagementWorkflow',
'PhabricatorSearchManagementWorkflow' => 'PhutilArgumentWorkflow',
'PhabricatorSearchQuery' => 'PhabricatorSearchDAO',
'PhabricatorSearchResultView' => 'AphrontView',
'PhabricatorSearchSelectController' => 'PhabricatorSearchBaseController',
'PhabricatorSecurityConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorSendGridConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorSettingsAdjustController' => 'PhabricatorController',
'PhabricatorSettingsMainController' => 'PhabricatorController',
'PhabricatorSettingsPanelAccount' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelConduit' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelDiffPreferences' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelDisplayPreferences' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelEmailAddresses' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelEmailPreferences' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelHomePreferences' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelLDAP' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelOAuth' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelPassword' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelProfile' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelSSHKeys' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelSearchPreferences' => 'PhabricatorSettingsPanel',
'PhabricatorSetupCheckAPC' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckBaseURI' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckDatabase' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckExtensions' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckExtraConfig' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckFacebook' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckGD' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckImagemagick' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckInvalidConfig' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckMail' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckMySQL' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckPHPConfig' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckPath' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckPygment' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckStorage' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckTimezone' => 'PhabricatorSetupCheck',
'PhabricatorSetupIssueExample' => 'PhabricatorUIExample',
'PhabricatorSetupIssueView' => 'AphrontView',
'PhabricatorSlowvoteChoice' => 'PhabricatorSlowvoteDAO',
'PhabricatorSlowvoteComment' => 'PhabricatorSlowvoteDAO',
'PhabricatorSlowvoteController' => 'PhabricatorController',
'PhabricatorSlowvoteCreateController' => 'PhabricatorSlowvoteController',
'PhabricatorSlowvoteDAO' => 'PhabricatorLiskDAO',
'PhabricatorSlowvoteListController' => 'PhabricatorSlowvoteController',
'PhabricatorSlowvoteOption' => 'PhabricatorSlowvoteDAO',
'PhabricatorSlowvotePoll' => 'PhabricatorSlowvoteDAO',
'PhabricatorSlowvotePollController' => 'PhabricatorSlowvoteController',
'PhabricatorSlugTestCase' => 'PhabricatorTestCase',
'PhabricatorSortTableExample' => 'PhabricatorUIExample',
'PhabricatorSourceCodeView' => 'AphrontView',
'PhabricatorStandardPageView' => 'PhabricatorBarePageView',
'PhabricatorStatusController' => 'PhabricatorController',
'PhabricatorStorageManagementDatabasesWorkflow' => 'PhabricatorStorageManagementWorkflow',
'PhabricatorStorageManagementDestroyWorkflow' => 'PhabricatorStorageManagementWorkflow',
'PhabricatorStorageManagementDumpWorkflow' => 'PhabricatorStorageManagementWorkflow',
'PhabricatorStorageManagementStatusWorkflow' => 'PhabricatorStorageManagementWorkflow',
'PhabricatorStorageManagementUpgradeWorkflow' => 'PhabricatorStorageManagementWorkflow',
'PhabricatorStorageManagementWorkflow' => 'PhutilArgumentWorkflow',
'PhabricatorSubscribersQuery' => 'PhabricatorQuery',
'PhabricatorSubscriptionsEditController' => 'PhabricatorController',
'PhabricatorSubscriptionsEditor' => 'PhabricatorEditor',
'PhabricatorSubscriptionsUIEventListener' => 'PhutilEventListener',
'PhabricatorSymbolNameLinter' => 'ArcanistXHPASTLintNamingHook',
'PhabricatorSyntaxHighlightingConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorTagExample' => 'PhabricatorUIExample',
'PhabricatorTagView' => 'AphrontView',
'PhabricatorTaskmasterDaemon' => 'PhabricatorDaemon',
'PhabricatorTestCase' => 'ArcanistPhutilTestCase',
'PhabricatorTestStorageEngine' => 'PhabricatorFileStorageEngine',
'PhabricatorTestWorker' => 'PhabricatorWorker',
'PhabricatorTimelineCursor' => 'PhabricatorTimelineDAO',
'PhabricatorTimelineDAO' => 'PhabricatorLiskDAO',
'PhabricatorTimelineEvent' => 'PhabricatorTimelineDAO',
'PhabricatorTimelineEventData' => 'PhabricatorTimelineDAO',
'PhabricatorTimelineEventView' => 'AphrontView',
'PhabricatorTimelineExample' => 'PhabricatorUIExample',
'PhabricatorTimelineIterator' => 'Iterator',
'PhabricatorTimelineView' => 'AphrontView',
'PhabricatorTimer' => 'PhabricatorCountdownDAO',
'PhabricatorToken' =>
array(
0 => 'PhabricatorTokenDAO',
1 => 'PhabricatorPolicyInterface',
),
'PhabricatorTokenController' => 'PhabricatorController',
'PhabricatorTokenCount' => 'PhabricatorTokenDAO',
'PhabricatorTokenCountQuery' => 'PhabricatorOffsetPagedQuery',
'PhabricatorTokenDAO' => 'PhabricatorLiskDAO',
'PhabricatorTokenGiveController' => 'PhabricatorTokenController',
'PhabricatorTokenGiven' =>
array(
0 => 'PhabricatorTokenDAO',
1 => 'PhabricatorPolicyInterface',
),
'PhabricatorTokenGivenController' => 'PhabricatorTokenController',
'PhabricatorTokenGivenEditor' => 'PhabricatorEditor',
'PhabricatorTokenGivenFeedStory' => 'PhabricatorFeedStory',
'PhabricatorTokenGivenQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorTokenQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorTokenUIEventListener' => 'PhutilEventListener',
'PhabricatorTransactionView' => 'AphrontView',
'PhabricatorTransformedFile' => 'PhabricatorFileDAO',
'PhabricatorTranslationsConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorTrivialTestCase' => 'PhabricatorTestCase',
'PhabricatorTwoColumnExample' => 'PhabricatorUIExample',
'PhabricatorTypeaheadCommonDatasourceController' => 'PhabricatorTypeaheadDatasourceController',
'PhabricatorTypeaheadDatasourceController' => 'PhabricatorController',
'PhabricatorUIExampleRenderController' => 'PhabricatorController',
'PhabricatorUIListFilterExample' => 'PhabricatorUIExample',
'PhabricatorUINotificationExample' => 'PhabricatorUIExample',
'PhabricatorUIPagerExample' => 'PhabricatorUIExample',
'PhabricatorUITooltipExample' => 'PhabricatorUIExample',
'PhabricatorUnitsTestCase' => 'PhabricatorTestCase',
'PhabricatorUser' =>
array(
0 => 'PhabricatorUserDAO',
1 => 'PhutilPerson',
),
'PhabricatorUserDAO' => 'PhabricatorLiskDAO',
'PhabricatorUserEditor' => 'PhabricatorEditor',
'PhabricatorUserEmail' => 'PhabricatorUserDAO',
'PhabricatorUserLDAPInfo' => 'PhabricatorUserDAO',
'PhabricatorUserLog' => 'PhabricatorUserDAO',
'PhabricatorUserOAuthInfo' => 'PhabricatorUserDAO',
'PhabricatorUserPreferences' => 'PhabricatorUserDAO',
'PhabricatorUserProfile' => 'PhabricatorUserDAO',
'PhabricatorUserSSHKey' => 'PhabricatorUserDAO',
'PhabricatorUserSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
'PhabricatorUserStatus' => 'PhabricatorUserDAO',
'PhabricatorUserStatusInvalidEpochException' => 'Exception',
'PhabricatorUserStatusOverlapException' => 'Exception',
'PhabricatorUserTestCase' => 'PhabricatorTestCase',
'PhabricatorWorkerActiveTask' => 'PhabricatorWorkerTask',
'PhabricatorWorkerArchiveTask' => 'PhabricatorWorkerTask',
'PhabricatorWorkerDAO' => 'PhabricatorLiskDAO',
'PhabricatorWorkerLeaseQuery' => 'PhabricatorQuery',
'PhabricatorWorkerPermanentFailureException' => 'Exception',
'PhabricatorWorkerTask' => 'PhabricatorWorkerDAO',
'PhabricatorWorkerTaskData' => 'PhabricatorWorkerDAO',
'PhabricatorWorkerTaskDetailController' => 'PhabricatorDaemonController',
'PhabricatorWorkerTaskUpdateController' => 'PhabricatorDaemonController',
'PhabricatorWorkerTestCase' => 'PhabricatorTestCase',
'PhabricatorXHPASTViewController' => 'PhabricatorController',
'PhabricatorXHPASTViewDAO' => 'PhabricatorLiskDAO',
'PhabricatorXHPASTViewFrameController' => 'PhabricatorXHPASTViewController',
'PhabricatorXHPASTViewFramesetController' => 'PhabricatorXHPASTViewController',
'PhabricatorXHPASTViewInputController' => 'PhabricatorXHPASTViewPanelController',
'PhabricatorXHPASTViewPanelController' => 'PhabricatorXHPASTViewController',
'PhabricatorXHPASTViewParseTree' => 'PhabricatorXHPASTViewDAO',
'PhabricatorXHPASTViewRunController' => 'PhabricatorXHPASTViewController',
'PhabricatorXHPASTViewStreamController' => 'PhabricatorXHPASTViewPanelController',
'PhabricatorXHPASTViewTreeController' => 'PhabricatorXHPASTViewPanelController',
'PhabricatorXHProfController' => 'PhabricatorController',
'PhabricatorXHProfDAO' => 'PhabricatorLiskDAO',
'PhabricatorXHProfProfileController' => 'PhabricatorXHProfController',
'PhabricatorXHProfProfileSymbolView' => 'PhabricatorXHProfProfileView',
'PhabricatorXHProfProfileTopLevelView' => 'PhabricatorXHProfProfileView',
'PhabricatorXHProfProfileView' => 'AphrontView',
'PhabricatorXHProfSample' => 'PhabricatorXHProfDAO',
'PhabricatorXHProfSampleListController' => 'PhabricatorXHProfController',
'PhabricatorXHProfSampleListView' => 'AphrontView',
'PhameBasicBlogSkin' => 'PhameBlogSkin',
'PhameBasicTemplateBlogSkin' => 'PhameBasicBlogSkin',
'PhameBlog' =>
array(
0 => 'PhameDAO',
1 => 'PhabricatorPolicyInterface',
2 => 'PhabricatorMarkupInterface',
),
'PhameBlogDeleteController' => 'PhameController',
'PhameBlogEditController' => 'PhameController',
'PhameBlogFeedController' => 'PhameController',
'PhameBlogListController' => 'PhameController',
'PhameBlogLiveController' => 'PhameController',
'PhameBlogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhameBlogSkin' => 'PhabricatorController',
'PhameBlogViewController' => 'PhameController',
'PhameController' => 'PhabricatorController',
'PhameDAO' => 'PhabricatorLiskDAO',
'PhamePost' =>
array(
0 => 'PhameDAO',
1 => 'PhabricatorPolicyInterface',
2 => 'PhabricatorMarkupInterface',
),
'PhamePostDeleteController' => 'PhameController',
'PhamePostEditController' => 'PhameController',
'PhamePostFramedController' => 'PhameController',
'PhamePostListController' => 'PhameController',
'PhamePostNewController' => 'PhameController',
'PhamePostNotLiveController' => 'PhameController',
'PhamePostPreviewController' => 'PhameController',
'PhamePostPublishController' => 'PhameController',
'PhamePostQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhamePostUnpublishController' => 'PhameController',
'PhamePostView' => 'AphrontView',
'PhamePostViewController' => 'PhameController',
'PhameResourceController' => 'CelerityResourceController',
'PholioController' => 'PhabricatorController',
'PholioDAO' => 'PhabricatorLiskDAO',
'PholioImage' =>
array(
0 => 'PholioDAO',
1 => 'PhabricatorMarkupInterface',
),
'PholioInlineCommentEditView' => 'AphrontView',
'PholioInlineCommentSaveView' => 'AphrontView',
'PholioInlineCommentView' => 'AphrontView',
'PholioInlineController' => 'PholioController',
'PholioInlineDeleteController' => 'PholioController',
'PholioInlineEditController' => 'PholioController',
'PholioInlineSaveController' => 'PholioController',
'PholioInlineViewController' => 'PholioController',
'PholioMock' =>
array(
0 => 'PholioDAO',
1 => 'PhabricatorMarkupInterface',
2 => 'PhabricatorPolicyInterface',
3 => 'PhabricatorSubscribableInterface',
4 => 'PhabricatorTokenReceiverInterface',
5 => 'PhabricatorApplicationTransactionInterface',
),
'PholioMockCommentController' => 'PholioController',
'PholioMockEditController' => 'PholioController',
'PholioMockEditor' => 'PhabricatorApplicationTransactionEditor',
'PholioMockEmbedView' => 'AphrontView',
'PholioMockImagesView' => 'AphrontView',
'PholioMockListController' => 'PholioController',
'PholioMockQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PholioMockViewController' => 'PholioController',
'PholioRemarkupRule' => 'PhabricatorRemarkupRuleObject',
'PholioReplyHandler' => 'PhabricatorMailReplyHandler',
'PholioSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
'PholioTransaction' => 'PhabricatorApplicationTransaction',
'PholioTransactionComment' => 'PhabricatorApplicationTransactionComment',
'PholioTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PholioTransactionType' => 'PholioConstants',
'PholioTransactionView' => 'PhabricatorApplicationTransactionView',
'PhortuneMonthYearExpiryControl' => 'AphrontFormControl',
'PhortuneStripeBaseController' => 'PhabricatorController',
'PhortuneStripePaymentFormView' => 'AphrontView',
'PhortuneStripeTestPaymentFormController' => 'PhortuneStripeBaseController',
'PhrictionActionConstants' => 'PhrictionConstants',
'PhrictionChangeType' => 'PhrictionConstants',
'PhrictionContent' =>
array(
0 => 'PhrictionDAO',
1 => 'PhabricatorMarkupInterface',
),
'PhrictionController' => 'PhabricatorController',
'PhrictionDAO' => 'PhabricatorLiskDAO',
'PhrictionDeleteController' => 'PhrictionController',
'PhrictionDiffController' => 'PhrictionController',
'PhrictionDocument' =>
array(
0 => 'PhrictionDAO',
1 => 'PhabricatorPolicyInterface',
),
'PhrictionDocumentController' => 'PhrictionController',
'PhrictionDocumentEditor' => 'PhabricatorEditor',
'PhrictionDocumentPreviewController' => 'PhrictionController',
'PhrictionDocumentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhrictionDocumentStatus' => 'PhrictionConstants',
'PhrictionDocumentTestCase' => 'PhabricatorTestCase',
'PhrictionEditController' => 'PhrictionController',
'PhrictionHistoryController' => 'PhrictionController',
'PhrictionListController' => 'PhrictionController',
'PhrictionMoveController' => 'PhrictionController',
'PhrictionNewController' => 'PhrictionController',
'PhrictionRemarkupRule' => 'PhutilRemarkupRule',
'PhrictionSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
'PonderAddAnswerView' => 'AphrontView',
'PonderAddCommentView' => 'AphrontView',
'PonderAnswer' =>
array(
0 => 'PonderDAO',
1 => 'PhabricatorMarkupInterface',
2 => 'PonderVotableInterface',
),
'PonderAnswerEditor' => 'PhabricatorEditor',
'PonderAnswerListView' => 'AphrontView',
'PonderAnswerPreviewController' => 'PonderController',
'PonderAnswerQuery' => 'PhabricatorOffsetPagedQuery',
'PonderAnswerSaveController' => 'PonderController',
'PonderAnswerViewController' => 'PonderController',
'PonderAnsweredMail' => 'PonderMail',
'PonderComment' =>
array(
0 => 'PonderDAO',
1 => 'PhabricatorMarkupInterface',
),
'PonderCommentEditor' => 'PhabricatorEditor',
'PonderCommentListView' => 'AphrontView',
'PonderCommentMail' => 'PonderMail',
'PonderCommentQuery' => 'PhabricatorQuery',
'PonderCommentSaveController' => 'PonderController',
'PonderController' => 'PhabricatorController',
'PonderDAO' => 'PhabricatorLiskDAO',
'PonderFeedController' => 'PonderController',
'PonderMail' => 'PhabricatorMail',
'PonderMentionMail' => 'PonderMail',
'PonderPostBodyView' => 'AphrontView',
'PonderQuestion' =>
array(
0 => 'PonderDAO',
1 => 'PhabricatorMarkupInterface',
2 => 'PonderVotableInterface',
3 => 'PhabricatorSubscribableInterface',
4 => 'PhabricatorPolicyInterface',
),
'PonderQuestionAskController' => 'PonderController',
'PonderQuestionDetailView' => 'AphrontView',
'PonderQuestionEditor' => 'PhabricatorEditor',
'PonderQuestionPreviewController' => 'PonderController',
'PonderQuestionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PonderQuestionSummaryView' => 'AphrontView',
'PonderQuestionViewController' => 'PonderController',
'PonderRemarkupRule' => 'PhabricatorRemarkupRuleObject',
'PonderReplyHandler' => 'PhabricatorMailReplyHandler',
'PonderSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
'PonderUserProfileView' => 'AphrontView',
'PonderVotableView' => 'AphrontView',
'PonderVoteEditor' => 'PhabricatorEditor',
'PonderVoteSaveController' => 'PonderController',
'QueryFormattingTestCase' => 'PhabricatorTestCase',
+ 'ReleephActiveProjectListView' => 'AphrontView',
+ 'ReleephAuthorFieldSpecification' => 'ReleephFieldSpecification',
+ 'ReleephBranch' => 'ReleephDAO',
+ 'ReleephBranchAccessController' => 'ReleephController',
+ 'ReleephBranchBoxView' => 'AphrontView',
+ 'ReleephBranchCommitFieldSpecification' => 'ReleephFieldSpecification',
+ 'ReleephBranchCreateController' => 'ReleephController',
+ 'ReleephBranchEditController' => 'ReleephController',
+ 'ReleephBranchEditor' => 'PhabricatorEditor',
+ 'ReleephBranchNamePreviewController' => 'PhabricatorController',
+ 'ReleephBranchPreviewView' => 'AphrontFormControl',
+ 'ReleephBranchViewController' => 'ReleephController',
+ 'ReleephCommitFinderException' => 'Exception',
+ 'ReleephCommitMessageFieldSpecification' => 'ReleephFieldSpecification',
+ 'ReleephController' => 'PhabricatorController',
+ 'ReleephDAO' => 'PhabricatorLiskDAO',
+ 'ReleephDefaultFieldSelector' => 'ReleephFieldSelector',
+ 'ReleephDefaultUserView' => 'ReleephUserView',
+ 'ReleephDiffChurnFieldSpecification' => 'ReleephFieldSpecification',
+ 'ReleephDiffMessageFieldSpecification' => 'ReleephFieldSpecification',
+ 'ReleephDiffSizeFieldSpecification' => 'ReleephFieldSpecification',
+ 'ReleephEvent' => 'ReleephDAO',
+ 'ReleephFieldParseException' => 'Exception',
+ 'ReleephFieldSpecificationIncompleteException' => 'Exception',
+ 'ReleephInactiveProjectListView' => 'AphrontView',
+ 'ReleephIntentFieldSpecification' => 'ReleephFieldSpecification',
+ 'ReleephLevelFieldSpecification' => 'ReleephFieldSpecification',
+ 'ReleephObjectHandleLoader' => 'ObjectHandleLoader',
+ 'ReleephOriginalCommitFieldSpecification' => 'ReleephFieldSpecification',
+ 'ReleephProject' => 'ReleephDAO',
+ 'ReleephProjectActionController' => 'ReleephController',
+ 'ReleephProjectCreateController' => 'ReleephController',
+ 'ReleephProjectEditController' => 'ReleephController',
+ 'ReleephProjectListController' => 'PhabricatorController',
+ 'ReleephProjectView' => 'AphrontView',
+ 'ReleephProjectViewController' => 'ReleephController',
+ 'ReleephReasonFieldSpecification' => 'ReleephFieldSpecification',
+ 'ReleephRequest' => 'ReleephDAO',
+ 'ReleephRequestActionController' => 'ReleephController',
+ 'ReleephRequestCreateController' => 'ReleephController',
+ 'ReleephRequestDifferentialCreateController' => 'ReleephController',
+ 'ReleephRequestEditController' => 'ReleephController',
+ 'ReleephRequestEditor' => 'PhabricatorEditor',
+ 'ReleephRequestEvent' => 'ReleephDAO',
+ 'ReleephRequestEventListView' => 'AphrontView',
+ 'ReleephRequestException' => 'Exception',
+ 'ReleephRequestHeaderListView' => 'AphrontView',
+ 'ReleephRequestHeaderView' => 'AphrontView',
+ 'ReleephRequestIntentsView' => 'AphrontView',
+ 'ReleephRequestStatusView' => 'AphrontView',
+ 'ReleephRequestTypeaheadControl' => 'AphrontFormControl',
+ 'ReleephRequestTypeaheadController' => 'PhabricatorTypeaheadDatasourceController',
+ 'ReleephRequestViewController' => 'ReleephController',
+ 'ReleephRequestorFieldSpecification' => 'ReleephFieldSpecification',
+ 'ReleephRevisionFieldSpecification' => 'ReleephFieldSpecification',
+ 'ReleephRiskFieldSpecification' => 'ReleephFieldSpecification',
+ 'ReleephSeverityFieldSpecification' => 'ReleephLevelFieldSpecification',
+ 'ReleephStatusFieldSpecification' => 'ReleephFieldSpecification',
+ 'ReleephSummaryFieldSpecification' => 'ReleephFieldSpecification',
+ 'ReleephUserView' => 'AphrontView',
),
));
diff --git a/src/applications/releeph/ReleephObjectHandleLoader.php b/src/applications/releeph/ReleephObjectHandleLoader.php
new file mode 100644
index 0000000000..553ead7a51
--- /dev/null
+++ b/src/applications/releeph/ReleephObjectHandleLoader.php
@@ -0,0 +1,92 @@
+<?php
+
+final class ReleephObjectHandleLoader extends ObjectHandleLoader {
+
+ /**
+ * The intention for phid.external-loaders is for each new 4-char PHID type
+ * to point to a different external loader for that type.
+ *
+ * For brevity, we instead just have this one class that can load any type of
+ * Releeph PHID.
+ */
+
+ public function loadHandles(array $phids) {
+ $types = array();
+
+ foreach ($phids as $phid) {
+ $type = phid_get_type($phid);
+ $types[$type][] = $phid;
+ }
+
+ $handles = array();
+
+ foreach ($types as $type => $phids) {
+ switch ($type) {
+ case ReleephPHIDConstants::PHID_TYPE_RERQ:
+ $object = new ReleephRequest();
+
+ $instances = $object->loadAllWhere('phid in (%Ls)', $phids);
+ $instances = mpull($instances, null, 'getPHID');
+
+ foreach ($phids as $phid) {
+ $instance = $instances[$phid];
+ $handle = new PhabricatorObjectHandle();
+ $handle->setPHID($phid);
+ $handle->setType($type);
+ $handle->setURI('/RQ'.$instance->getID());
+
+ $name = 'RQ'.$instance->getID();
+ $handle->setName($name);
+ $handle->setFullName($name.': '.$instance->getSummaryForDisplay());
+ $handle->setComplete(true);
+
+ $handles[$phid] = $handle;
+ }
+ break;
+
+ case ReleephPHIDConstants::PHID_TYPE_REBR:
+ $object = new ReleephBranch();
+
+ $branches = $object->loadAllWhere('phid IN (%Ls)', $phids);
+ $branches = mpull($branches, null, 'getPHID');
+
+ foreach ($phids as $phid) {
+ $branch = $branches[$phid];
+ $handle = new PhabricatorObjectHandle();
+ $handle->setPHID($phid);
+ $handle->setType($type);
+ $handle->setURI($branch->getURI());
+ $handle->setName($branch->getBasename());
+ $handle->setFullName($branch->getName());
+ $handle->setComplete(true);
+ $handles[$phid] = $handle;
+ }
+ break;
+
+ case ReleephPHIDConstants::PHID_TYPE_REPR:
+ $object = new ReleephProject();
+
+ $instances = $object->loadAllWhere('phid IN (%Ls)', $phids);
+ $instances = mpull($instances, null, 'getPHID');
+
+ foreach ($phids as $phid) {
+ $instance = $instances[$phid];
+ $handle = new PhabricatorObjectHandle();
+ $handle->setPHID($phid);
+ $handle->setType($type);
+ $handle->setURI($instance->getURI());
+ $handle->setName($instance->getName()); // no fullName for proejcts
+ $handle->setComplete(true);
+ $handles[$phid] = $handle;
+ }
+ break;
+
+ default:
+ throw new Exception('unknown type '.$type);
+ }
+ }
+
+ return $handles;
+ }
+
+}
diff --git a/src/applications/releeph/ReleephPHIDConstants.php b/src/applications/releeph/ReleephPHIDConstants.php
new file mode 100644
index 0000000000..6265da6c83
--- /dev/null
+++ b/src/applications/releeph/ReleephPHIDConstants.php
@@ -0,0 +1,9 @@
+<?php
+
+final class ReleephPHIDConstants {
+
+ // Releeph
+ const PHID_TYPE_REPR = 'REPR';
+ const PHID_TYPE_REBR = 'REBR';
+ const PHID_TYPE_RERQ = 'RERQ';
+}
diff --git a/src/applications/releeph/application/PhabricatorApplicationReleeph.php b/src/applications/releeph/application/PhabricatorApplicationReleeph.php
new file mode 100644
index 0000000000..4512ba0d65
--- /dev/null
+++ b/src/applications/releeph/application/PhabricatorApplicationReleeph.php
@@ -0,0 +1,86 @@
+<?php
+
+final class PhabricatorApplicationReleeph extends PhabricatorApplication {
+
+ public function getName() {
+ return 'Releeph';
+ }
+
+ public function getShortDescription() {
+ return 'Release Branches';
+ }
+
+ public function getBaseURI() {
+ return '/releeph/';
+ }
+
+ public function getAutospriteName() {
+ return 'releeph';
+ }
+
+ public function getApplicationGroup() {
+ return self::GROUP_ORGANIZATION;
+ }
+
+ public function isInstalled() {
+ if (PhabricatorEnv::getEnvConfig('releeph.installed')) {
+ return parent::isInstalled();
+ }
+ return false;
+ }
+
+ public function getRoutes() {
+ return array(
+ '/RQ(?P<requestID>[1-9]\d*)' => 'ReleephRequestViewController',
+ '/releeph/' => array(
+ '' => 'ReleephProjectListController',
+ 'project/' => array(
+ '' => 'ReleephProjectListController',
+ 'inactive/' => 'ReleephProjectListController',
+ 'create/' => 'ReleephProjectCreateController',
+ '(?P<projectID>[1-9]\d*)/' => array(
+ '' => 'ReleephProjectViewController',
+ 'closedbranches/' => 'ReleephProjectViewController',
+ 'edit/' => 'ReleephProjectEditController',
+ 'cutbranch/' => 'ReleephBranchCreateController',
+ 'action/(?P<action>.+)/' => 'ReleephProjectActionController',
+ ),
+ ),
+ 'branch/' => array(
+ 'edit/(?P<branchID>[1-9]\d*)/' =>
+ 'ReleephBranchEditController',
+ '(?P<action>close|re-open)/(?P<branchID>[1-9]\d*)/' =>
+ 'ReleephBranchAccessController',
+ 'preview/' => 'ReleephBranchNamePreviewController',
+
+ // Left in, just in case the by-name stuff fails!
+ '(?P<branchID>[^/]+)/' =>
+ 'ReleephBranchViewController',
+ ),
+ 'request/' => array(
+ '(?P<requestID>[1-9]\d*)/' => 'ReleephRequestViewController',
+ 'create/' => 'ReleephRequestCreateController',
+ 'differentialcreate/' => array(
+ 'D(?P<diffRevID>[1-9]\d*)' =>
+ 'ReleephRequestDifferentialCreateController',
+ ),
+ 'edit/(?P<requestID>[1-9]\d*)/' =>
+ 'ReleephRequestEditController',
+ 'action/(?P<action>.+)/(?P<requestID>[1-9]\d*)/' =>
+ 'ReleephRequestActionController',
+ 'typeahead/' =>
+ 'ReleephRequestTypeaheadController',
+ ),
+
+ // Branch navigation made pretty, as it's the most common:
+ '(?P<projectName>[^/]+)/(?P<branchName>[^/]+)/' => array(
+ '' => 'ReleephBranchViewController',
+ 'edit/' => 'ReleephBranchEditController',
+ 'request/' => 'ReleephRequestCreateController',
+ '(?P<action>close|re-open)/' => 'ReleephBranchAccessController',
+ ),
+ )
+ );
+ }
+
+}
diff --git a/src/applications/releeph/commitfinder/ReleephCommitFinder.php b/src/applications/releeph/commitfinder/ReleephCommitFinder.php
new file mode 100644
index 0000000000..3212944419
--- /dev/null
+++ b/src/applications/releeph/commitfinder/ReleephCommitFinder.php
@@ -0,0 +1,74 @@
+<?php
+
+final class ReleephCommitFinder {
+
+ private $releephProject;
+
+ public function setReleephProject(ReleephProject $rp) {
+ $this->releephProject = $rp;
+ return $this;
+ }
+
+ public function fromPartial($partial_string) {
+ // Look for diffs
+ $matches = array();
+ if (preg_match('/^D([1-9]\d*)$/', $partial_string, $matches)) {
+ $diff_id = $matches[1];
+ $diff_rev = id(new DifferentialRevision())->load($diff_id);
+ if (!$diff_rev) {
+ throw new ReleephCommitFinderException(
+ "{$partial_string} does not refer to an existing diff.");
+ }
+ $commit_phids = $diff_rev->loadCommitPHIDs();
+
+ if (!$commit_phids) {
+ throw new ReleephCommitFinderException(
+ "{$partial_string} has no commits associated with it yet.");
+ }
+
+ $commits = id(new PhabricatorRepositoryCommit())->loadAllWhere(
+ 'phid IN (%Ls) ORDER BY epoch ASC',
+ $commit_phids);
+ return head($commits);
+ }
+
+ // Look for a raw commit number, or r<callsign><commit-number>.
+ $repository = $this->releephProject->loadPhabricatorRepository();
+ $dr_data = null;
+ $matches = array();
+ if (preg_match('/^r(?P<callsign>[A-Z]+)(?P<commit>\w+)$/',
+ $partial_string, $matches)) {
+ $callsign = $matches['callsign'];
+ if ($callsign != $repository->getCallsign()) {
+ throw new ReleephCommitFinderException(sprintf(
+ "%s is in a different repository to this Releeph project (%s).",
+ $partial_string,
+ $repository->getCallsign()));
+ } else {
+ $dr_data = $matches;
+ }
+ } else {
+ $dr_data = array(
+ 'callsign' => $repository->getCallsign(),
+ 'commit' => $partial_string
+ );
+ }
+
+ try {
+ $dr = DiffusionRequest::newFromDictionary($dr_data);
+ } catch (Exception $ex) {
+ $message = "No commit matches {$partial_string}: ".$ex->getMessage();
+ throw new ReleephCommitFinderException($message);
+ }
+
+ $phabricator_repository_commit = $dr->loadCommit();
+
+ if (!$phabricator_repository_commit) {
+ throw new ReleephCommitFinderException(
+ "The commit {$partial_string} doesn't exist in this repository.");
+ }
+
+ return $phabricator_repository_commit;
+ }
+
+}
diff --git a/src/applications/releeph/commitfinder/ReleephCommitFinderException.php b/src/applications/releeph/commitfinder/ReleephCommitFinderException.php
new file mode 100644
index 0000000000..8250de5927
--- /dev/null
+++ b/src/applications/releeph/commitfinder/ReleephCommitFinderException.php
@@ -0,0 +1,3 @@
+<?php
+
+final class ReleephCommitFinderException extends Exception {}
diff --git a/src/applications/releeph/conduit/ConduitAPI_releeph_Method.php b/src/applications/releeph/conduit/ConduitAPI_releeph_Method.php
new file mode 100644
index 0000000000..7d5d9aa08b
--- /dev/null
+++ b/src/applications/releeph/conduit/ConduitAPI_releeph_Method.php
@@ -0,0 +1,9 @@
+<?php
+
+abstract class ConduitAPI_releeph_Method extends ConduitAPIMethod {
+
+ public function getApplication() {
+ return PhabricatorApplication::getByClass('PhabricatorApplicationReleeph');
+ }
+
+}
diff --git a/src/applications/releeph/conduit/ConduitAPI_releeph_getbranches_Method.php b/src/applications/releeph/conduit/ConduitAPI_releeph_getbranches_Method.php
new file mode 100644
index 0000000000..d7a76e842c
--- /dev/null
+++ b/src/applications/releeph/conduit/ConduitAPI_releeph_getbranches_Method.php
@@ -0,0 +1,62 @@
+<?php
+
+final class ConduitAPI_releeph_getbranches_Method
+ extends ConduitAPI_releeph_Method {
+
+ public function getMethodDescription() {
+ return "Return information about all active Releeph branches.";
+ }
+
+ public function defineParamTypes() {
+ return array(
+ );
+ }
+
+ public function defineReturnType() {
+ return 'nonempty list<dict<string, wild>>';
+ }
+
+ public function defineErrorTypes() {
+ return array(
+ );
+ }
+
+ protected function execute(ConduitAPIRequest $request) {
+ $results = array();
+
+ $projects = id(new ReleephProject())->loadAllWhere('isActive = 1');
+
+ foreach ($projects as $project) {
+ $repository = $project->loadOneRelative(
+ id(new PhabricatorRepository()),
+ 'id',
+ 'getRepositoryID');
+
+ $branches = $project->loadRelatives(
+ id(new ReleephBranch()),
+ 'releephProjectID',
+ 'getID',
+ 'isActive = 1');
+
+ foreach ($branches as $branch) {
+ $full_branch_name = $branch->getName();
+
+ $cut_point_commit = $branch->loadOneRelative(
+ id(new PhabricatorRepositoryCommit()),
+ 'phid',
+ 'getCutPointCommitPHID');
+
+ $results[] = array(
+ 'project' => $project->getName(),
+ 'repository' => $repository->getCallsign(),
+ 'branch' => $branch->getBasename(),
+ 'fullBranchName' => $full_branch_name,
+ 'symbolicName' => $branch->getSymbolicName(),
+ 'cutPoint' => $branch->getCutPointCommitIdentifier(),
+ );
+ }
+ }
+
+ return $results;
+ }
+}
diff --git a/src/applications/releeph/conduit/ConduitAPI_releeph_projectinfo_Method.php b/src/applications/releeph/conduit/ConduitAPI_releeph_projectinfo_Method.php
new file mode 100644
index 0000000000..950e629530
--- /dev/null
+++ b/src/applications/releeph/conduit/ConduitAPI_releeph_projectinfo_Method.php
@@ -0,0 +1,96 @@
+<?php
+
+final class ConduitAPI_releeph_projectinfo_Method
+ extends ConduitAPI_releeph_Method {
+
+ public function getMethodDescription() {
+ return
+ "Fetch information about all Releeph projects ".
+ "for a given Arcanist project.";
+ }
+
+ public function defineParamTypes() {
+ return array(
+ 'arcProjectName' => 'optional string',
+ );
+ }
+
+ public function defineReturnType() {
+ return 'dict<string, wild>';
+ }
+
+ public function defineErrorTypes() {
+ return array(
+ "ERR_UNKNOWN_ARC" =>
+ "The given Arcanist project name doesn't exist in the ".
+ "installation of Phabricator you are accessing.",
+ );
+ }
+
+ protected function execute(ConduitAPIRequest $request) {
+ $arc_project_name = $request->getValue('arcProjectName');
+ if ($arc_project_name) {
+ $arc_project = id(new PhabricatorRepositoryArcanistProject())
+ ->loadOneWhere('name = %s', $arc_project_name);
+ if (!$arc_project) {
+ throw id(new ConduitException("ERR_UNKNOWN_ARC"))
+ ->setErrorDescription(
+ "Unknown Arcanist project '{$arc_project_name}': ".
+ "are you using the correct Conduit URI?");
+ }
+
+ $releeph_projects = id(new ReleephProject())
+ ->loadAllWhere('arcanistProjectID = %d', $arc_project->getID());
+ } else {
+ $releeph_projects = id(new ReleephProject())->loadAll();
+ }
+
+ $releeph_projects = mfilter($releeph_projects, 'getIsActive');
+
+ $result = array();
+ foreach ($releeph_projects as $releeph_project) {
+ $selector = $releeph_project->getReleephFieldSelector();
+ $fields = $selector->getFieldSpecifications();
+
+ $fields_info = array();
+ foreach ($fields as $field) {
+ $field->setReleephProject($releeph_project);
+ if ($field->isEditable()) {
+ $key = $field->getKeyForConduit();
+ $fields_info[$key] = array(
+ 'class' => get_class($field),
+ 'name' => $field->getName(),
+ 'key' => $key,
+ 'arcHelp' => $field->renderHelpForArcanist(),
+ );
+ }
+ }
+
+ $releeph_branches = mfilter(
+ id(new ReleephBranch())
+ ->loadAllWhere('releephProjectID = %d', $releeph_project->getID()),
+ 'getIsActive');
+
+ $releeph_branches_struct = array();
+ foreach ($releeph_branches as $branch) {
+ $releeph_branches_struct[] = array(
+ 'branchName' => $branch->getName(),
+ 'projectName' => $releeph_project->getName(),
+ 'projectPHID' => $releeph_project->getPHID(),
+ 'branchPHID' => $branch->getPHID(),
+ );
+ }
+
+ $result[] = array(
+ 'projectName' => $releeph_project->getName(),
+ 'projectPHID' => $releeph_project->getPHID(),
+ 'branches' => $releeph_branches_struct,
+ 'fields' => $fields_info,
+ );
+ }
+
+ return $result;
+ }
+
+
+}
diff --git a/src/applications/releeph/conduit/ConduitAPI_releeph_request_Method.php b/src/applications/releeph/conduit/ConduitAPI_releeph_request_Method.php
new file mode 100644
index 0000000000..68b2a3010f
--- /dev/null
+++ b/src/applications/releeph/conduit/ConduitAPI_releeph_request_Method.php
@@ -0,0 +1,130 @@
+<?php
+
+final class ConduitAPI_releeph_request_Method
+ extends ConduitAPI_releeph_Method {
+
+ public function getMethodDescription() {
+ return "Request a commit or diff to be picked to a branch.";
+ }
+
+ public function defineParamTypes() {
+ return array(
+ 'branchPHID' => 'required string',
+ 'things' => 'required string',
+ 'fields' => 'dict<string, string>',
+ );
+ }
+
+ public function defineReturnType() {
+ return 'dict<string, wild>';
+ }
+
+ public function defineErrorTypes() {
+ return array(
+ "ERR_BRANCH" => 'Unknown Releeph branch.',
+ "ERR_FIELD_PARSE" => 'Unable to parse a Releeph field.',
+ );
+ }
+
+ protected function execute(ConduitAPIRequest $request) {
+ $branch_phid = $request->getValue('branchPHID');
+ $releeph_branch = id(new ReleephBranch())
+ ->loadOneWhere('phid = %s', $branch_phid);
+
+ if (!$releeph_branch) {
+ throw id(new ConduitException("ERR_BRANCH"))->setErrorDescription(
+ "No ReleephBranch found with PHID {$branch_phid}!");
+ }
+
+ $releeph_project = $releeph_branch->loadReleephProject();
+
+ // Find the requested commit identifiers
+ $requested_commits = array();
+ $things = $request->getValue('things');
+ $finder = id(new ReleephCommitFinder())
+ ->setReleephProject($releeph_project);
+ foreach ($things as $thing) {
+ try {
+ $requested_commits[$thing] = $finder->fromPartial($thing);
+ } catch (ReleephCommitFinderException $ex) {
+ throw id(new ConduitException('ERR_NO_MATCHES'))
+ ->setErrorDescription($ex->getMessage());
+ }
+ }
+
+ // Find any existing requests that clash on the commit id, for this branch
+ $existing_releeph_requests = id(new ReleephRequest())->loadAllWhere(
+ 'requestCommitPHID IN (%Ls) AND branchID = %d',
+ mpull($requested_commits, 'getPHID'),
+ $releeph_branch->getID());
+ $existing_releeph_requests = mpull(
+ $existing_releeph_requests,
+ null,
+ 'getRequestCommitPHID');
+
+ $selector = $releeph_project->getReleephFieldSelector();
+ $fields = $selector->getFieldSpecifications();
+ foreach ($fields as $field) {
+ $field
+ ->setReleephProject($releeph_project)
+ ->setReleephBranch($releeph_branch);
+ }
+
+ $results = array();
+ foreach ($requested_commits as $thing => $commit) {
+ $phid = $commit->getPHID();
+ $handles = id(new PhabricatorObjectHandleData(array($phid)))
+ ->setViewer($request->getUser())
+ ->loadHandles();
+ $name = id($handles[$phid])->getName();
+
+ $releeph_request = null;
+
+ $existing_releeph_request = idx($existing_releeph_requests, $phid);
+ if ($existing_releeph_request) {
+ $releeph_request = $existing_releeph_request;
+ } else {
+ $releeph_request = new ReleephRequest();
+ foreach ($fields as $field) {
+ if (!$field->isEditable()) {
+ continue;
+ }
+ $field->setReleephRequest($releeph_request);
+ try {
+ $field->setValueFromConduitAPIRequest($request);
+ } catch (ReleephFieldParseException $ex) {
+ throw id(new ConduitException('ERR_FIELD_PARSE'))
+ ->setErrorDescription($ex->getMessage());
+ }
+ }
+ id(new ReleephRequestEditor($releeph_request))
+ ->setActor($request->getUser())
+ ->create($commit, $releeph_branch);
+ }
+
+ $releeph_branch->populateReleephRequestHandles(
+ $request->getUser(),
+ array($releeph_request));
+ $rq_handles = $releeph_request->getHandles();
+ $requestor_phid = $releeph_request->getRequestUserPHID();
+ $requestor = $rq_handles[$requestor_phid]->getName();
+
+ $url = PhabricatorEnv::getProductionURI('/RQ'.$releeph_request->getID());
+
+ $results[$thing] = array(
+ 'thing' => $thing,
+ 'branch' => $releeph_branch->getDisplayNameWithDetail(),
+ 'commitName' => $name,
+ 'commitID' => $commit->getCommitIdentifier(),
+ 'url' => $url,
+ 'requestID' => $releeph_request->getID(),
+ 'requestor' => $requestor,
+ 'requestTime' => $releeph_request->getDateCreated(),
+ 'existing' => $existing_releeph_request !== null,
+ );
+ }
+
+ return $results;
+ }
+
+}
diff --git a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_canpush_Method.php b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_canpush_Method.php
new file mode 100644
index 0000000000..d37bf85297
--- /dev/null
+++ b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_canpush_Method.php
@@ -0,0 +1,39 @@
+<?php
+
+final class ConduitAPI_releephwork_canpush_Method
+ extends ConduitAPI_releeph_Method {
+
+ public function getMethodStatus() {
+ return self::METHOD_STATUS_UNSTABLE;
+ }
+
+ public function getMethodDescription() {
+ return "Return whether the conduit user is allowed to push.";
+ }
+
+ public function defineParamTypes() {
+ return array(
+ 'projectPHID' => 'required string',
+ );
+ }
+
+ public function defineReturnType() {
+ return 'bool';
+ }
+
+ public function defineErrorTypes() {
+ return array();
+ }
+
+ protected function execute(ConduitAPIRequest $request) {
+ $releeph_project = id(new ReleephProject())
+ ->loadOneWhere('phid = %s', $request->getValue('projectPHID'));
+
+ if (!$releeph_project->getPushers()) {
+ return true;
+ } else {
+ $user = $request->getUser();
+ return $releeph_project->isPusher($user);
+ }
+ }
+}
diff --git a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getauthorinfo_Method.php b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getauthorinfo_Method.php
new file mode 100644
index 0000000000..62b594c781
--- /dev/null
+++ b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getauthorinfo_Method.php
@@ -0,0 +1,43 @@
+<?php
+
+final class ConduitAPI_releephwork_getauthorinfo_Method
+ extends ConduitAPI_releeph_Method {
+
+ public function getMethodStatus() {
+ return self::METHOD_STATUS_UNSTABLE;
+ }
+
+ public function getMethodDescription() {
+ return "Return a string to use as the VCS author.";
+ }
+
+ public function defineParamTypes() {
+ return array(
+ 'userPHID' => 'required string',
+ 'vcsType' => 'required string',
+ );
+ }
+
+ public function defineReturnType() {
+ return 'nonempty string';
+ }
+
+ public function defineErrorTypes() {
+ return array();
+ }
+
+ protected function execute(ConduitAPIRequest $request) {
+ $user = id(new PhabricatorUser())
+ ->loadOneWhere('phid = %s', $request->getValue('userPHID'));
+
+ $email = $user->loadPrimaryEmailAddress();
+ if (is_numeric($email)) {
+ $email = $user->getUserName().'@fb.com';
+ }
+
+ return sprintf(
+ '%s <%s>',
+ $user->getRealName(),
+ $email);
+ }
+}
diff --git a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getbranch_Method.php b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getbranch_Method.php
new file mode 100644
index 0000000000..9b9f57e40d
--- /dev/null
+++ b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getbranch_Method.php
@@ -0,0 +1,52 @@
+<?php
+
+final class ConduitAPI_releephwork_getbranch_Method
+ extends ConduitAPI_releeph_Method {
+
+ public function getMethodStatus() {
+ return self::METHOD_STATUS_UNSTABLE;
+ }
+
+ public function getMethodDescription() {
+ return "Return information to help checkout / cut a Releeph branch.";
+ }
+
+ public function defineParamTypes() {
+ return array(
+ 'branchPHID' => 'required string',
+ );
+ }
+
+ public function defineReturnType() {
+ return 'dict<string, wild>';
+ }
+
+ public function defineErrorTypes() {
+ return array();
+ }
+
+ protected function execute(ConduitAPIRequest $request) {
+ $branch = id(new ReleephBranch())
+ ->loadOneWhere('phid = %s', $request->getValue('branchPHID'));
+
+ $cut_phid = $branch->getCutPointCommitPHID();
+ $phids = array($cut_phid);
+ $handles = id(new PhabricatorObjectHandleData($phids))
+ ->setViewer($request->getUser())
+ ->loadHandles();
+
+ $project = $branch->loadReleephProject();
+ $repo = $project->loadPhabricatorRepository();
+
+ return array(
+ 'branchName' => $branch->getName(),
+ 'branchPHID' => $branch->getPHID(),
+ 'vcsType' => $repo->getVersionControlSystem(),
+ 'cutCommitID' => $branch->getCutPointCommitIdentifier(),
+ 'cutCommitName' => $handles[$cut_phid]->getName(),
+ 'creatorPHID' => $branch->getCreatedByUserPHID(),
+ 'trunk' => $project->getTrunkBranch(),
+ );
+ }
+
+}
diff --git a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getbranchcommitmessage_Method.php b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getbranchcommitmessage_Method.php
new file mode 100644
index 0000000000..5549591fc1
--- /dev/null
+++ b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getbranchcommitmessage_Method.php
@@ -0,0 +1,94 @@
+<?php
+
+final class ConduitAPI_releephwork_getbranchcommitmessage_Method
+ extends ConduitAPI_releeph_Method {
+
+ public function getMethodStatus() {
+ return self::METHOD_STATUS_UNSTABLE;
+ }
+
+ public function getMethodDescription() {
+ return "Get a commit message for committing a Releeph branch.";
+ }
+
+ public function defineParamTypes() {
+ return array(
+ 'branchPHID' => 'required string',
+ );
+ }
+
+ public function defineReturnType() {
+ return 'nonempty string';
+ }
+
+ public function defineErrorTypes() {
+ return array();
+ }
+
+ protected function execute(ConduitAPIRequest $request) {
+ $branch = id(new ReleephBranch())
+ ->loadOneWhere('phid = %s', $request->getValue('branchPHID'));
+
+ $project = $branch->loadReleephProject();
+
+ $creator_phid = $branch->getCreatedByUserPHID();
+ $cut_phid = $branch->getCutPointCommitPHID();
+
+ $phids = array(
+ $branch->getPHID(),
+ $project->getPHID(),
+ $creator_phid,
+ $cut_phid,
+ );
+
+ $handles = id(new PhabricatorObjectHandleData($phids))
+ ->setViewer($request->getUser())
+ ->loadHandles();
+
+ $h_branch = $handles[$branch->getPHID()];
+ $h_project = $handles[$project->getPHID()];
+
+ // Not as customizable as a ReleephRequest's commit message. It doesn't
+ // really need to be.
+ $commit_message = array();
+ $commit_message[] = $h_branch->getFullName();
+ $commit_message[] = $h_branch->getURI();
+
+ $commit_message[] = "Cut Point: ".$handles[$cut_phid]->getName();
+
+ $cut_point_pr_commit = id(new PhabricatorRepositoryCommit())
+ ->loadOneWhere('phid = %s', $cut_phid);
+ $cut_point_commit_date = strftime(
+ '%Y-%m-%d %H:%M:%S%z',
+ $cut_point_pr_commit->getEpoch());
+ $commit_message[] = "Cut Point Date: {$cut_point_commit_date}";
+
+ $commit_message[] = "Created By: ".$handles[$creator_phid]->getName();
+
+ $project_uri = $project->getURI();
+ $commit_message[] = "Project: ".$h_project->getName()." ".$project_uri;
+
+ /**
+ * Required for 090-limit_new_branch_creations.sh in
+ * admin/scripts/git/hosting/hooks/update.d (in the E repo):
+ *
+ * http://fburl.com/2372545
+ *
+ * The commit message must have a line saying:
+ *
+ * @new-branch: <branch-name>
+ *
+ */
+ $repo = $project->loadPhabricatorRepository();
+ switch ($repo->getVersionControlSystem()) {
+ case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
+ $commit_message[] = sprintf(
+ '@new-branch: %s',
+ $branch->getName());
+ break;
+ }
+
+ return implode("\n\n", $commit_message);
+ }
+
+}
diff --git a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getcommitmessage_Method.php b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getcommitmessage_Method.php
new file mode 100644
index 0000000000..3241369579
--- /dev/null
+++ b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getcommitmessage_Method.php
@@ -0,0 +1,90 @@
+<?php
+
+final class ConduitAPI_releephwork_getcommitmessage_Method
+ extends ConduitAPI_releeph_Method {
+
+ public function getMethodStatus() {
+ return self::METHOD_STATUS_UNSTABLE;
+ }
+
+ public function getMethodDescription() {
+ return
+ "Get commit message components for building ".
+ "a ReleephRequest commit message.";
+ }
+
+ public function defineParamTypes() {
+ return array(
+ 'requestPHID' => 'required string',
+ 'action' => 'required enum<"pick", "revert">',
+ );
+ }
+
+ public function defineReturnType() {
+ return 'dict<string, string>';
+ }
+
+ public function defineErrorTypes() {
+ return array();
+ }
+
+ protected function execute(ConduitAPIRequest $request) {
+ $releeph_request = id(new ReleephRequest())
+ ->loadOneWhere('phid = %s', $request->getValue('requestPHID'));
+
+ $action = $request->getValue('action');
+
+ $title = $releeph_request->getSummaryForDisplay();
+
+ $commit_message = array();
+
+ $project = $releeph_request->loadReleephProject();
+ $branch = $releeph_request->loadReleephBranch();
+
+ $selector = $project->getReleephFieldSelector();
+ $fields = $selector->getFieldSpecifications();
+ $fields = $selector->sortFieldsForCommitMessage($fields);
+
+ foreach ($fields as $field) {
+ $field
+ ->setUser($request->getUser())
+ ->setReleephProject($project)
+ ->setReleephBranch($branch)
+ ->setReleephRequest($releeph_request);
+
+ $label = null;
+ $value = null;
+
+ switch ($action) {
+ case 'pick':
+ if ($field->shouldAppearOnCommitMessage()) {
+ $label = $field->renderLabelForCommitMessage();
+ $value = $field->renderValueForCommitMessage();
+ }
+ break;
+
+ case 'revert':
+ if ($field->shouldAppearOnRevertMessage()) {
+ $label = $field->renderLabelForRevertMessage();
+ $value = $field->renderValueForRevertMessage();
+ }
+ break;
+ }
+
+ if ($label && $value) {
+ if (strpos($value, "\n") !== false ||
+ substr($value, 0, 2) === ' ') {
+ $commit_message[] = "{$label}:\n{$value}";
+ } else {
+ $commit_message[] = "{$label}: {$value}";
+ }
+ }
+ }
+
+ return array(
+ 'title' => $title,
+ 'body' => implode("\n\n", $commit_message),
+ );
+ }
+
+}
diff --git a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getorigcommitmessage_Method.php b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getorigcommitmessage_Method.php
new file mode 100644
index 0000000000..4c6efe55e2
--- /dev/null
+++ b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getorigcommitmessage_Method.php
@@ -0,0 +1,35 @@
+<?php
+
+final class ConduitAPI_releephwork_getorigcommitmessage_Method
+ extends ConduitAPI_releeph_Method {
+
+ public function getMethodStatus() {
+ return self::METHOD_STATUS_UNSTABLE;
+ }
+
+ public function getMethodDescription() {
+ return "Return the original commit message for the given commit.";
+ }
+
+ public function defineParamTypes() {
+ return array(
+ 'commitPHID' => 'required string',
+ );
+ }
+
+ public function defineReturnType() {
+ return 'nonempty string';
+ }
+
+ public function defineErrorTypes() {
+ return array();
+ }
+
+ protected function execute(ConduitAPIRequest $request) {
+ $commit = id(new PhabricatorRepositoryCommit())
+ ->loadOneWhere('phid = %s', $request->getValue('commitPHID'));
+ $commit_data = $commit->loadCommitData();
+ $commit_message = $commit_data->getCommitMessage();
+ return trim($commit_message);
+ }
+}
diff --git a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_nextrequest_Method.php b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_nextrequest_Method.php
new file mode 100644
index 0000000000..c17dbbdcb3
--- /dev/null
+++ b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_nextrequest_Method.php
@@ -0,0 +1,208 @@
+<?php
+
+final class ConduitAPI_releephwork_nextrequest_Method
+ extends ConduitAPI_releeph_Method {
+
+ private $project;
+ private $branch;
+
+ public function getMethodStatus() {
+ return self::METHOD_STATUS_UNSTABLE;
+ }
+
+ public function getMethodDescription() {
+ return
+ "Return info required to cut a branch, ".
+ "and pick and revert ReleephRequests";
+ }
+
+ public function defineParamTypes() {
+ return array(
+ 'branchPHID' => 'required int',
+ 'seen' => 'required list<string, bool>',
+ );
+ }
+
+ public function defineReturnType() {
+ return '';
+ }
+
+ public function defineErrorTypes() {
+ return array(
+ 'ERR-NOT-PUSHER' =>
+ 'You are not listed as a pusher for thie Releeph project!',
+ );
+ }
+
+ protected function execute(ConduitAPIRequest $request) {
+ $seen = $request->getValue('seen');
+
+ $branch = id(new ReleephBranch())
+ ->loadOneWhere('phid = %s', $request->getValue('branchPHID'));
+
+ $project = $branch->loadReleephProject();
+
+ $needs_pick = array();
+ $needs_revert = array();
+
+ $releeph_requests = $branch->loadReleephRequests($request->getUser());
+
+ foreach ($releeph_requests as $candidate) {
+ $phid = $candidate->getPHID();
+ if (idx($seen, $phid)) {
+ continue;
+ }
+
+ $should = $candidate->shouldBeInBranch();
+ $in = $candidate->getInBranch();
+ if ($should && !$in) {
+ $needs_pick[] = $candidate;
+ }
+ if (!$should && $in) {
+ $needs_revert[] = $candidate;
+ }
+ }
+
+ /**
+ * Sort both needs_pick and needs_revert in ascending commit order, as
+ * discovered by Phabricator (using the `id` column to perform that
+ * ordering).
+ *
+ * This is easy for $needs_pick as the ordinal is stored. It is hard for
+ * reverts, as we have to look that information up.
+ */
+ $needs_pick = msort($needs_pick, 'getRequestCommitOrdinal');
+ $needs_revert = $this->sortReverts($needs_revert);
+
+ /**
+ * Do reverts first in reverse order, then the picks in original-commit
+ * order.
+ *
+ * This seems like the correct thing to do, but there may be a better
+ * algorithm for the releephwork.nextrequest Conduit call that orders
+ * things better.
+ *
+ * We could also button-mash our way through everything that failed (at the
+ * end of the run) to try failed things again.
+ */
+ $releeph_request = null;
+ $action = null;
+ if ($needs_revert) {
+ $releeph_request = last($needs_revert);
+ $action = 'revert';
+ $commit_id = $releeph_request->getCommitIdentifier();
+ $commit_phid = $releeph_request->getCommitPHID();
+ } elseif ($needs_pick) {
+ $releeph_request = head($needs_pick);
+ $action = 'pick';
+ $commit_id = $releeph_request->getRequestCommitIdentifier();
+ $commit_phid = $releeph_request->getRequestCommitPHID();
+ } else {
+ // Return early if there's nothing to do!
+ return array();
+ }
+
+ // Build the response
+ $phids = array();
+ $phids[] = $commit_phid;
+
+ $diff_phid = null;
+ $diff_rev_id = null;
+ $diff_rev = $releeph_request->loadDifferentialRevision();
+ if ($diff_rev) {
+ $diff_phid = $diff_rev->getPHID();
+ $phids[] = $diff_phid;
+ $diff_rev_id = $diff_rev->getID();
+ }
+
+ $phids[] = $releeph_request->getPHID();
+ $handles = id(new PhabricatorObjectHandleData($phids))
+ ->setViewer($request->getUser())
+ ->loadHandles();
+
+ $diff_name = null;
+ if ($diff_rev) {
+ $diff_name = $handles[$diff_phid]->getName();
+ }
+
+ // Calculate the new-author information (if any)
+ $new_author = null;
+ $new_author_phid = null;
+ switch ($project->getDetail('commitWithAuthor')) {
+ case ReleephProject::COMMIT_AUTHOR_NONE:
+ break;
+
+ case ReleephProject::COMMIT_AUTHOR_FROM_DIFF:
+ if ($diff_rev) {
+ $new_author_phid = $diff_rev->getAuthorPHID();
+ } else {
+ $pr_commit = $releeph_request->loadPhabricatorRepositoryCommit();
+ if ($pr_commit) {
+ $new_author_phid = $pr_commit->getAuthorPHID();
+ }
+ }
+ break;
+
+ case ReleephProject::COMMIT_AUTHOR_REQUESTOR:
+ $new_author_phid = $releeph_request->getRequestUserPHID();
+ break;
+ }
+
+ return array(
+ 'requestID' => $releeph_request->getID(),
+ 'requestPHID' => $releeph_request->getPHID(),
+ 'requestName' => $handles[$releeph_request->getPHID()]->getName(),
+ 'requestorPHID' => $releeph_request->getRequestUserPHID(),
+ 'action' => $action,
+ 'diffRevID' => $diff_rev_id,
+ 'diffName' => $diff_name,
+ 'commitIdentifier' => $commit_id,
+ 'commitPHID' => $commit_phid,
+ 'commitName' => $handles[$commit_phid]->getName(),
+ 'needsRevert' => mpull($needs_revert, 'getID'),
+ 'needsPick' => mpull($needs_pick, 'getID'),
+ 'newAuthorPHID' => $new_author_phid,
+ );
+ }
+
+ /**
+ * Sort an array of ReleephRequests, that have been picked into a branch, in
+ * the order in which they were picked to the branch.
+ */
+ private function sortReverts(array $releeph_requests) {
+ if (!$releeph_requests) {
+ return array();
+ }
+
+ // ReleephRequests, keyed by <branch-commit-id>
+ $releeph_requests = mpull($releeph_requests, null, 'getCommitIdentifier');
+
+ $commits = id(new PhabricatorRepositoryCommit())
+ ->loadAllWhere(
+ 'commitIdentifier IN (%Ls)',
+ mpull($releeph_requests, 'getCommitIdentifier'));
+
+ // A map of <branch-commit-id> => <branch-commit-ordinal>
+ $surrogate = mpull($commits, 'getID', 'getCommitIdentifier');
+
+ $unparsed = array();
+ $result = array();
+
+ foreach ($releeph_requests as $commit_id => $releeph_request) {
+ $ordinal = idx($surrogate, $commit_id);
+ if ($ordinal) {
+ $result[$ordinal] = $releeph_request;
+ } else {
+ $unparsed[] = $releeph_request;
+ }
+ }
+
+ // Sort $result in ascending order
+ ksort($result);
+
+ // Unparsed commits we'll just have to guess, based on time
+ $unparsed = msort($unparsed, 'getDateModified');
+
+ return array_merge($result, $unparsed);
+ }
+}
diff --git a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_record_Method.php b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_record_Method.php
new file mode 100644
index 0000000000..0b8bd3a1a8
--- /dev/null
+++ b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_record_Method.php
@@ -0,0 +1,42 @@
+<?php
+
+final class ConduitAPI_releephwork_record_Method
+ extends ConduitAPI_releeph_Method {
+
+ public function getMethodStatus() {
+ return self::METHOD_STATUS_UNSTABLE;
+ }
+
+ public function getMethodDescription() {
+ return "Wrapper to ReleephRequestEditor->recordSuccessfulCommit().";
+ }
+
+ public function defineParamTypes() {
+ return array(
+ 'requestPHID' => 'required string',
+ 'action' => 'required enum<"pick", "revert">',
+ 'commitIdentifier' => 'required string',
+ );
+ }
+
+ public function defineReturnType() {
+ return 'void';
+ }
+
+ public function defineErrorTypes() {
+ return array();
+ }
+
+ protected function execute(ConduitAPIRequest $request) {
+ $action = $request->getValue('action');
+ $new_commit_id = $request->getValue('commitIdentifier');
+
+ $releeph_request = id(new ReleephRequest())
+ ->loadOneWhere('phid = %s', $request->getValue('requestPHID'));
+
+ id(new ReleephRequestEditor($releeph_request))
+ ->setActor($request->getUser())
+ ->recordSuccessfulCommit($action, $new_commit_id);
+ }
+
+}
diff --git a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_recordpickstatus_Method.php b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_recordpickstatus_Method.php
new file mode 100644
index 0000000000..93fbcee068
--- /dev/null
+++ b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_recordpickstatus_Method.php
@@ -0,0 +1,63 @@
+<?php
+
+final class ConduitAPI_releephwork_recordpickstatus_Method
+ extends ConduitAPI_releeph_Method {
+
+ public function getMethodStatus() {
+ return self::METHOD_STATUS_UNSTABLE;
+ }
+
+ public function getMethodDescription() {
+ return "Wrapper to ReleephRequestEditor->changePickStatus().";
+ }
+
+ public function defineParamTypes() {
+ return array(
+ 'requestPHID' => 'required string',
+ 'action' => 'required enum<"pick", "revert">',
+ 'ok' => 'required bool',
+ 'dryRun' => 'optional bool',
+ 'details' => 'optional dict<string, wild>',
+ );
+ }
+
+ public function defineReturnType() {
+ return '';
+ }
+
+ public function defineErrorTypes() {
+ return array();
+ }
+
+ protected function execute(ConduitAPIRequest $request) {
+ $action = $request->getValue('action');
+ $ok = $request->getValue('ok');
+ $dry_run = $request->getValue('dryRun');
+ $details = $request->getValue('details', array());
+
+ switch ($request->getValue('action')) {
+ case 'pick':
+ $pick_status = $ok
+ ? ReleephRequest::PICK_OK
+ : ReleephRequest::PICK_FAILED;
+ break;
+
+ case 'revert':
+ $pick_status = $ok
+ ? ReleephRequest::REVERT_OK
+ : ReleephRequest::REVERT_FAILED;
+ break;
+
+ default:
+ throw new Exception("Unknown action {$action}!");
+ }
+
+ $releeph_request = id(new ReleephRequest())
+ ->loadOneWhere('phid = %s', $request->getValue('requestPHID'));
+
+ id(new ReleephRequestEditor($releeph_request))
+ ->setActor($request->getUser())
+ ->changePickStatus($pick_status, $dry_run, $details);
+ }
+
+}
diff --git a/src/applications/releeph/config/PhabricatorApplicationReleephConfigOptions.php b/src/applications/releeph/config/PhabricatorApplicationReleephConfigOptions.php
new file mode 100644
index 0000000000..75cc322473
--- /dev/null
+++ b/src/applications/releeph/config/PhabricatorApplicationReleephConfigOptions.php
@@ -0,0 +1,64 @@
+<?php
+
+final class PhabricatorApplicationReleephConfigOptions
+ extends PhabricatorApplicationConfigOptions {
+
+ public function getName() {
+ return pht("Releeph");
+ }
+
+ public function getDescription() {
+ return pht("Options for configuring Releeph, the release branch tool.");
+ }
+
+ public function getOptions() {
+ return array(
+ $this->newOption('releeph.installed', 'bool', false)
+ ->setSummary(pht('Enable the Releeph application.'))
+ ->setDescription(
+ pht(
+ "Releeph, a tool for managing release branches, will eventually ".
+ "fit in to the Phabricator suite as a general purpose tool. ".
+ "However Releeph is currently unstable in multiple ways that may ".
+ "not migrate properly for you: the code is still in alpha stage ".
+ "of design, the storage format is likely to change in unexpected ".
+ "ways, and the workflows presented are very specific to a core ".
+ "set of alpha testers at Facebook. For the time being you are ".
+ "strongly discouraged from relying on Releeph being at all ".
+ "stable.")),
+ $this->newOption(
+ 'releeph.field-selector',
+ 'class',
+ 'ReleephDefaultFieldSelector')
+ ->setBaseClass('ReleephFieldSelector')
+ ->setSummary(pht('Field selector class'))
+ ->setDescription(
+ pht(
+ "Control which fields are available when making a new Releeph ".
+ "request, and which are then shown in the Releeph UI.")),
+ $this->newOption(
+ 'releeph.user-view',
+ 'class',
+ 'ReleephDefaultUserView')
+ ->setBaseClass('ReleephUserView')
+ ->setSummary(pht('Extra markup when rendering usernames'))
+ ->setDescription(
+ pht(
+ "A wrapper to render Phabricator users in Releeph, with custom ".
+ "markup. For example, Facebook extends this to render additional ".
+ "information about requestors, to each Releeph project's ".
+ "pushers.")),
+ $this->newOption(
+ 'releeph.default-branch-template',
+ 'string',
+ 'releases/%P/%p-%Y%m%d-%v')
+ ->setDescription(
+ pht(
+ "The default branch template for new branches in unconfigured ".
+ "Releeph projects. This is also configurable on a per-project ".
+ "basis.")),
+ );
+ }
+
+
+}
diff --git a/src/applications/releeph/controller/ReleephController.php b/src/applications/releeph/controller/ReleephController.php
new file mode 100644
index 0000000000..22a8214532
--- /dev/null
+++ b/src/applications/releeph/controller/ReleephController.php
@@ -0,0 +1,122 @@
+<?php
+
+abstract class ReleephController extends PhabricatorController {
+
+ private $releephProject;
+ private $releephBranch;
+ private $releephRequest;
+
+ /**
+ * ReleephController will take care of loading any Releeph* objects
+ * referenced in the URL.
+ */
+ public function willProcessRequest(array $data) {
+ // Project
+ $project = null;
+ $project_id = idx($data, 'projectID');
+ $project_name = idx($data, 'projectName');
+ if ($project_id) {
+ $project = id(new ReleephProject())->load($project_id);
+ if (!$project) {
+ throw new Exception(
+ "ReleephProject with id '{$project_id}' not found!");
+ }
+ } elseif ($project_name) {
+ $project = id(new ReleephProject())
+ ->loadOneWhere('name = %s', $project_name);
+ if (!$project) {
+ throw new Exception(
+ "ReleephProject with name '{$project_name}' not found!");
+ }
+ }
+
+ // Branch
+ $branch = null;
+ $branch_id = idx($data, 'branchID');
+ $branch_name = idx($data, 'branchName');
+ if ($branch_id) {
+ $branch = id(new ReleephBranch())->load($branch_id);
+ if (!$branch) {
+ throw new Exception("Branch with id '{$branch_id}' not found!");
+ }
+ } elseif ($branch_name) {
+ if (!$project) {
+ throw new Exception(
+ "You cannot refer to a branch by name without also referring ".
+ "to a ReleephProject (branch names are only unique in projects).");
+ }
+ $branch = id(new ReleephBranch())->loadOneWhere(
+ 'basename = %s AND releephProjectID = %d',
+ $branch_name,
+ $project->getID());
+ if (!$branch) {
+ throw new Exception(
+ "ReleephBranch with basename '{$branch_name}' not found ".
+ "in project '{$project->getName()}'!");
+ }
+ }
+
+ // Request
+ $request = null;
+ $request_id = idx($data, 'requestID');
+ if ($request_id) {
+ $request = id(new ReleephRequest())->load($request_id);
+ if (!$request) {
+ throw new Exception(
+ "ReleephRequest with id '{$request_id}' not found!");
+ }
+ }
+
+ // Fill in the gaps
+ if ($request && !$branch) {
+ $branch = $request->loadReleephBranch();
+ }
+
+ if ($branch && !$project) {
+ $project = $branch->loadReleephProject();
+ }
+
+ // Set!
+ $this->releephProject = $project;
+ $this->releephBranch = $branch;
+ $this->releephRequest = $request;
+ }
+
+ protected function getReleephProject() {
+ if (!$this->releephProject) {
+ throw new Exception(
+ 'This controller did not load a ReleephProject from the URL $data.');
+ }
+ return $this->releephProject;
+ }
+
+ protected function getReleephBranch() {
+ if (!$this->releephBranch) {
+ throw new Exception(
+ 'This controller did not load a ReleephBranch from the URL $data.');
+ }
+ return $this->releephBranch;
+ }
+
+ protected function getReleephRequest() {
+ if (!$this->releephRequest) {
+ throw new Exception(
+ 'This controller did not load a ReleephRequest from the URL $data.');
+ }
+ return $this->releephRequest;
+ }
+
+ public function buildStandardPageResponse($view, array $data) {
+ $page = $this->buildStandardPageView();
+
+ $page->setApplicationName('Releeph');
+ $page->setBaseURI('/releeph/');
+ $page->setTitle(idx($data, 'title'));
+ $page->setGlyph("\xD3\x82");
+ $page->appendChild($view);
+
+ $response = new AphrontWebpageResponse();
+ return $response->setContent($page->render());
+ }
+
+}
diff --git a/src/applications/releeph/controller/branch/ReleephBranchAccessController.php b/src/applications/releeph/controller/branch/ReleephBranchAccessController.php
new file mode 100644
index 0000000000..bcaf86e964
--- /dev/null
+++ b/src/applications/releeph/controller/branch/ReleephBranchAccessController.php
@@ -0,0 +1,61 @@
+<?php
+
+final class ReleephBranchAccessController extends ReleephController {
+
+ private $action;
+
+ public function willProcessRequest(array $data) {
+ $this->action = $data['action'];
+ parent::willProcessRequest($data);
+ }
+
+ public function processRequest() {
+ $rph_branch = $this->getReleephBranch();
+ $request = $this->getRequest();
+
+ $active_uri = '/releeph/project/'.$rph_branch->getReleephProjectID().'/';
+ $inactive_uri = $active_uri.'inactive/';
+
+ switch ($this->action) {
+ case 'close':
+ $is_active = false;
+ $origin_uri = $active_uri;
+ break;
+
+ case 're-open':
+ $is_active = true;
+ $origin_uri = $inactive_uri;
+ break;
+
+ default:
+ throw new Exception("Unknown action '{$this->action}'!");
+ break;
+ }
+
+ if ($request->isDialogFormPost()) {
+ id(new ReleephBranchEditor())
+ ->setActor($request->getUser())
+ ->setReleephBranch($rph_branch)
+ ->changeBranchAccess($is_active ? 1 : 0);
+ return id(new AphrontRedirectResponse())
+ ->setURI($origin_uri);
+ }
+
+ $button_text = ucfirst($this->action).' Branch';
+ $message = hsprintf(
+ '<p>Really %s the branch <i>%s</i>?</p>',
+ $this->action,
+ $rph_branch->getBasename());
+
+
+ $dialog = new AphrontDialogView();
+ $dialog
+ ->setUser($request->getUser())
+ ->setTitle('Confirm')
+ ->appendChild($message)
+ ->addSubmitButton($button_text)
+ ->addCancelButton($origin_uri);
+
+ return id(new AphrontDialogResponse())->setDialog($dialog);
+ }
+}
diff --git a/src/applications/releeph/controller/branch/ReleephBranchCreateController.php b/src/applications/releeph/controller/branch/ReleephBranchCreateController.php
new file mode 100644
index 0000000000..6031c0388a
--- /dev/null
+++ b/src/applications/releeph/controller/branch/ReleephBranchCreateController.php
@@ -0,0 +1,105 @@
+<?php
+
+final class ReleephBranchCreateController extends ReleephController {
+
+ public function processRequest() {
+ $releeph_project = $this->getReleephProject();
+
+ $request = $this->getRequest();
+
+ $cut_point = $request->getStr('cutPoint');
+ $symbolic_name = $request->getStr('symbolicName');
+
+ if (!$cut_point) {
+ $repository = $releeph_project->loadPhabricatorRepository();
+ switch ($repository->getVersionControlSystem()) {
+ case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
+ break;
+
+ case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
+ $cut_point = $releeph_project->getTrunkBranch();
+ break;
+ }
+ }
+
+ $e_cut = true;
+ $errors = array();
+
+ $branch_date_control = id(new AphrontFormDateControl())
+ ->setUser($request->getUser())
+ ->setName('templateDate')
+ ->setLabel('Date')
+ ->setCaption('The date used for filling out the branch template.')
+ ->setInitialTime(AphrontFormDateControl::TIME_START_OF_DAY);
+ $branch_date = $branch_date_control->readValueFromRequest($request);
+
+ if ($request->isFormPost()) {
+ $cut_commit = null;
+ if (!$cut_point) {
+ $e_cut = 'Required';
+ $errors[] = 'You must give a branch cut point';
+ } else {
+ try {
+ $finder = id(new ReleephCommitFinder())
+ ->setReleephProject($releeph_project);
+ $cut_commit = $finder->fromPartial($cut_point);
+ } catch (Exception $e) {
+ $e_cut = 'Invalid';
+ $errors[] = $e->getMessage();
+ }
+ }
+
+ if (!$errors) {
+ $branch = id(new ReleephBranchEditor())
+ ->setReleephProject($releeph_project)
+ ->setActor($request->getUser())
+ ->newBranchFromCommit(
+ $cut_commit,
+ $branch_date,
+ $symbolic_name);
+
+ return id(new AphrontRedirectResponse())
+ ->setURI($branch->getURI());
+ }
+ }
+
+ $error_view = array();
+ if ($errors) {
+ $error_view = new AphrontErrorView();
+ $error_view->setErrors($errors);
+ $error_view->setTitle('Form Errors');
+ }
+
+ $form = id(new AphrontFormView())
+ ->setUser($request->getUser())
+ ->appendChild(
+ id(new AphrontFormTextControl())
+ ->setLabel('Symbolic name')
+ ->setName('symbolicName')
+ ->setValue($symbolic_name)
+ ->setCaption('Mutable alternate name, for easy reference, '.
+ '(e.g. "LATEST")'))
+ ->appendChild(
+ id(new AphrontFormTextControl())
+ ->setLabel('Cut point')
+ ->setName('cutPoint')
+ ->setValue($cut_point)
+ ->setError($e_cut)
+ ->setCaption(
+ 'A commit ID for your repo type, or a Diffusion ID like "rE123"'))
+ ->appendChild($branch_date_control)
+ ->appendChild(
+ id(new AphrontFormSubmitControl())
+ ->setValue('Cut Branch')
+ ->addCancelButton($releeph_project->getURI()));
+
+ $panel = id(new AphrontPanelView())
+ ->appendChild($form)
+ ->setHeader('Cut Branch')
+ ->setWidth(AphrontPanelView::WIDTH_FORM);
+
+ return $this->buildStandardPageResponse(
+ array($error_view, $panel),
+ array('title' => 'Cut new branch'));
+ }
+}
diff --git a/src/applications/releeph/controller/branch/ReleephBranchEditController.php b/src/applications/releeph/controller/branch/ReleephBranchEditController.php
new file mode 100644
index 0000000000..5501ee3e08
--- /dev/null
+++ b/src/applications/releeph/controller/branch/ReleephBranchEditController.php
@@ -0,0 +1,136 @@
+<?php
+
+final class ReleephBranchEditController extends ReleephController {
+
+ public function processRequest() {
+ $request = $this->getRequest();
+ $releeph_branch = $this->getReleephBranch();
+ $branch_name = $request->getStr(
+ 'branchName',
+ $releeph_branch->getName());
+ $symbolic_name = $request->getStr(
+ 'symbolicName',
+ $releeph_branch->getSymbolicName());
+
+ $e_existing_with_same_branch_name = false;
+ $errors = array();
+
+ if ($request->isFormPost()) {
+ $existing_with_same_branch_name =
+ id(new ReleephBranch())
+ ->loadOneWhere(
+ 'id != %d AND releephProjectID = %d AND name = %s',
+ $releeph_branch->getID(),
+ $releeph_branch->getReleephProjectID(),
+ $branch_name);
+
+ if ($existing_with_same_branch_name) {
+ $errors[] = sprintf(
+ "The branch name %s is currently taken. Please use another name. ",
+ $branch_name);
+ $e_existing_with_same_branch_name = 'Error';
+ }
+
+ if (!$errors) {
+ $existing_with_same_symbolic_name =
+ id(new ReleephBranch())
+ ->loadOneWhere(
+ 'id != %d AND releephProjectID = %d AND symbolicName = %s',
+ $releeph_branch->getID(),
+ $releeph_branch->getReleephProjectID(),
+ $symbolic_name);
+
+ $releeph_branch->openTransaction();
+ $releeph_branch
+ ->setName($branch_name)
+ ->setBasename(last(explode('/', $branch_name)))
+ ->setSymbolicName($symbolic_name);
+
+ if ($existing_with_same_symbolic_name) {
+ $existing_with_same_symbolic_name
+ ->setSymbolicName(null)
+ ->save();
+ }
+
+ $releeph_branch->save();
+ $releeph_branch->saveTransaction();
+
+ return id(new AphrontRedirectResponse())
+ ->setURI('/releeph/project/'.$releeph_branch->getReleephProjectID());
+ }
+ }
+
+ $phids = array();
+
+ $phids[] = $creator_phid = $releeph_branch->getCreatedByUserPHID();
+ $phids[] = $cut_commit_phid = $releeph_branch->getCutPointCommitPHID();
+
+ $handles = id(new PhabricatorObjectHandleData($phids))
+ ->setViewer($request->getUser())
+ ->loadHandles();
+
+ $form = id(new AphrontFormView())
+ ->setUser($request->getUser())
+ ->appendChild(
+ id(new AphrontFormStaticControl())
+ ->setLabel('Branch name')
+ ->setValue($branch_name))
+ ->appendChild(
+ id(new AphrontFormMarkupControl())
+ ->setLabel('Cut point')
+ ->setValue($handles[$cut_commit_phid]->renderLink()))
+ ->appendChild(
+ id(new AphrontFormMarkupControl())
+ ->setLabel('Created by')
+ ->setValue($handles[$creator_phid]->renderLink()))
+ ->appendChild(
+ id(new AphrontFormTextControl)
+ ->setLabel('Symbolic Name')
+ ->setName('symbolicName')
+ ->setValue($symbolic_name)
+ ->setCaption('Mutable alternate name, for easy reference, '.
+ '(e.g. "LATEST")'))
+ ->appendChild(hsprintf(
+ '<br>' .
+ 'In dire situations where the branch name is wrong, ' .
+ 'you can edit it in the database by changing the field below. ' .
+ 'If you do this, it is very important that you change your ' .
+ 'branch\'s name in the VCS to reflect the new name in Releeph, ' .
+ 'otherwise a catastrophe of previously unheard-of magnitude ' .
+ 'will befall your project.'))
+ ->appendChild(
+ id(new AphrontFormTextControl)
+ ->setLabel('New branch name')
+ ->setName('branchName')
+ ->setValue($branch_name)
+ ->setError($e_existing_with_same_branch_name))
+ ->appendChild(
+ id(new AphrontFormSubmitControl())
+ ->addCancelButton($releeph_branch->getURI())
+ ->setValue('Save'));
+
+ $error_view = null;
+ if ($errors) {
+ $error_view = id(new AphrontErrorView())
+ ->setSeverity(AphrontErrorView::SEVERITY_ERROR)
+ ->setErrors($errors)
+ ->setTitle('Errors');
+ }
+
+ $title = hsprintf(
+ 'Edit branch %s',
+ $releeph_branch->getDisplayNameWithDetail());
+
+ $panel = id(new AphrontPanelView())
+ ->setHeader($title)
+ ->appendChild($form)
+ ->setWidth(AphrontPanelView::WIDTH_FORM);
+
+ return $this->buildStandardPageResponse(
+ array(
+ $error_view,
+ $panel,
+ ),
+ array('title' => $title));
+ }
+}
diff --git a/src/applications/releeph/controller/branch/ReleephBranchNamePreviewController.php b/src/applications/releeph/controller/branch/ReleephBranchNamePreviewController.php
new file mode 100644
index 0000000000..5606542bfc
--- /dev/null
+++ b/src/applications/releeph/controller/branch/ReleephBranchNamePreviewController.php
@@ -0,0 +1,46 @@
+<?php
+
+final class ReleephBranchNamePreviewController
+ extends PhabricatorController {
+
+ public function processRequest() {
+ $request = $this->getRequest();
+
+ $is_symbolic = $request->getBool('isSymbolic');
+ $template = $request->getStr('template');
+
+ if (!$is_symbolic && !$template) {
+ $template = ReleephBranchTemplate::getDefaultTemplate();
+ }
+
+ $arc_project_id = $request->getInt('arcProjectID');
+ $fake_commit_handle =
+ ReleephBranchTemplate::getFakeCommitHandleFor($arc_project_id);
+
+ list($name, $errors) = id(new ReleephBranchTemplate())
+ ->setCommitHandle($fake_commit_handle)
+ ->setReleephProjectName($request->getStr('projectName'))
+ ->setSymbolic($is_symbolic)
+ ->interpolate($template);
+
+ $markup = '';
+
+ if ($name) {
+ $markup = phutil_tag(
+ 'div',
+ array('class' => 'name'),
+ $name);
+ }
+
+ if ($errors) {
+ $markup .= phutil_tag(
+ 'div',
+ array('class' => 'error'),
+ head($errors));
+ }
+
+ return id(new AphrontAjaxResponse())
+ ->setContent(array('markup' => $markup));
+ }
+
+}
diff --git a/src/applications/releeph/controller/branch/ReleephBranchViewController.php b/src/applications/releeph/controller/branch/ReleephBranchViewController.php
new file mode 100644
index 0000000000..f01f149874
--- /dev/null
+++ b/src/applications/releeph/controller/branch/ReleephBranchViewController.php
@@ -0,0 +1,94 @@
+<?php
+
+final class ReleephBranchViewController extends ReleephController {
+
+ public function processRequest() {
+ $request = $this->getRequest();
+
+ $releeph_branch = $this->getReleephBranch();
+ $releeph_project = $this->getReleephProject();
+ $all_releeph_requests = $releeph_branch->loadReleephRequests(
+ $request->getUser());
+
+ $selector = $releeph_project->getReleephFieldSelector();
+ $fields = $selector->arrangeFieldsForSelectForm(
+ $selector->getFieldSpecifications());
+
+ $form = id(new AphrontFormView())
+ ->setMethod('GET')
+ ->setUser($request->getUser());
+
+ $filtered_releeph_requests = $all_releeph_requests;
+ foreach ($fields as $field) {
+ $all_releeph_requests_without_this_field = $all_releeph_requests;
+ foreach ($fields as $other_field) {
+ if ($other_field != $field) {
+ $other_field->selectReleephRequestsHook(
+ $request,
+ $all_releeph_requests_without_this_field);
+
+ }
+ }
+
+ $field->appendSelectControlsHook(
+ $form,
+ $request,
+ $all_releeph_requests,
+ $all_releeph_requests_without_this_field);
+
+ $field->selectReleephRequestsHook(
+ $request,
+ $filtered_releeph_requests);
+ }
+
+ $form->appendChild(
+ id(new AphrontFormSubmitControl())
+ ->setValue('Filter'));
+
+ $list = id(new ReleephRequestHeaderListView())
+ ->setOriginType('branch')
+ ->setUser($request->getUser())
+ ->setAphrontRequest($this->getRequest())
+ ->setReleephProject($releeph_project)
+ ->setReleephBranch($releeph_branch)
+ ->setReleephRequests($filtered_releeph_requests);
+
+ $filter = id(new AphrontListFilterView())
+ ->appendChild($form);
+
+ $crumbs = $this->buildApplicationCrumbs()
+ ->addCrumb(
+ id(new PhabricatorCrumbView())
+ ->setName($releeph_project->getName())
+ ->setHref($releeph_project->getURI()))
+ ->addCrumb(
+ id(new PhabricatorCrumbView())
+ ->setName($releeph_branch->getDisplayNameWithDetail())
+ ->setHref($releeph_branch->getURI()));
+
+ // Don't show the request button for inactive (closed) branches
+ if ($releeph_branch->isActive()) {
+ $create_uri = $releeph_branch->getURI('request/');
+ $crumbs->addAction(
+ id(new PhabricatorMenuItemView())
+ ->setHref($create_uri)
+ ->setName('Request Pick')
+ ->setIcon('create'));
+ }
+
+ return $this->buildStandardPageResponse(
+ array(
+ $crumbs,
+ $filter,
+ $list
+ ),
+ array(
+ 'title' =>
+ $releeph_project->getName().
+ ' - '.
+ $releeph_branch->getDisplayName().
+ ' requests'
+ ));
+ }
+
+}
diff --git a/src/applications/releeph/controller/project/ReleephProjectActionController.php b/src/applications/releeph/controller/project/ReleephProjectActionController.php
new file mode 100644
index 0000000000..4e91107ea0
--- /dev/null
+++ b/src/applications/releeph/controller/project/ReleephProjectActionController.php
@@ -0,0 +1,63 @@
+<?php
+
+final class ReleephProjectActionController extends ReleephController {
+
+ private $action;
+
+ public function willProcessRequest(array $data) {
+ parent::willProcessRequest($data);
+ $this->action = $data['action'];
+ }
+
+ public function processRequest() {
+ $request = $this->getRequest();
+
+ $action = $this->action;
+ $rph_project = $this->getReleephProject();
+
+ switch ($action) {
+ case 'deactivate':
+ if ($request->isDialogFormPost()) {
+ $rph_project->deactivate($request->getUser())->save();
+ return id(new AphrontRedirectResponse())->setURI('/releeph');
+ }
+
+ $dialog = id(new AphrontDialogView())
+ ->setUser($request->getUser())
+ ->setTitle('Really deactivate Releeph Project?')
+ ->appendChild(hsprintf(
+ '<p>Really deactivate the Releeph project <i>%s</i>?',
+ $rph_project->getName()))
+ ->appendChild(hsprintf(
+ '<p style="margin-top:1em">It will still exist, but '.
+ 'will be hidden from the list of active projects.</p>'))
+ ->addSubmitButton('Deactivate Releeph Project')
+ ->addCancelButton($request->getRequestURI());
+
+ return id(new AphrontDialogResponse())->setDialog($dialog);
+
+ case 'activate':
+ $rph_project->setIsActive(1)->save();
+ return id(new AphrontRedirectResponse())->setURI('/releeph');
+
+ case 'delete':
+ if ($request->isDialogFormPost()) {
+ $rph_project->delete();
+ return id(new AphrontRedirectResponse())
+ ->setURI('/releeph/project/inactive');
+ }
+
+ $dialog = id(new AphrontDialogView())
+ ->setUser($request->getUser())
+ ->setTitle('Really delete Releeph Project?')
+ ->appendChild(hsprintf(
+ '<p>Really delete the "%s" Releeph project? '.
+ 'This cannot be undone!</p>',
+ $rph_project->getName()))
+ ->addSubmitButton('Delete Releeph Project')
+ ->addCancelButton($request->getRequestURI());
+ return id(new AphrontDialogResponse())->setDialog($dialog);
+
+ }
+ }
+}
diff --git a/src/applications/releeph/controller/project/ReleephProjectCreateController.php b/src/applications/releeph/controller/project/ReleephProjectCreateController.php
new file mode 100644
index 0000000000..2dbfb72c55
--- /dev/null
+++ b/src/applications/releeph/controller/project/ReleephProjectCreateController.php
@@ -0,0 +1,149 @@
+<?php
+
+final class ReleephProjectCreateController extends ReleephController {
+
+ public function processRequest() {
+ $request = $this->getRequest();
+ $name = trim($request->getStr('name'));
+ $trunk_branch = trim($request->getStr('trunkBranch'));
+ $arc_pr_id = $request->getInt('arcPrID');
+
+
+ // Only allow arc projects with repositories. Sort and re-key by ID.
+ $arc_projects = id(new PhabricatorRepositoryArcanistProject())->loadAll();
+ $arc_projects = mpull(
+ msort(
+ mfilter($arc_projects, 'getRepositoryID'),
+ 'getName'),
+ null,
+ 'getID');
+
+ $e_name = true;
+ $e_trunk_branch = true;
+ $errors = array();
+
+ if ($request->isFormPost()) {
+ if (!$name) {
+ $e_name = 'Required';
+ $errors[] =
+ 'Your releeph project should have a simple descriptive name.';
+ }
+
+ if (!$trunk_branch) {
+ $e_trunk_branch = 'Required';
+ $errors[] =
+ 'You must specify which branch you will be picking from.';
+ }
+
+ $all_names = mpull(id(new ReleephProject())->loadAll(), 'getName');
+
+ if (in_array($name, $all_names)) {
+ $errors[] = "Releeph project name {$name} is already taken";
+ }
+
+ $arc_project = $arc_projects[$arc_pr_id];
+ $pr_repository = $arc_project->loadRepository();
+
+ if (!$errors) {
+ $releeph_project = id(new ReleephProject())
+ ->setName($name)
+ ->setTrunkBranch($trunk_branch)
+ ->setRepositoryID($pr_repository->getID())
+ ->setRepositoryPHID($pr_repository->getPHID())
+ ->setArcanistProjectID($arc_project->getID())
+ ->setCreatedByUserPHID($request->getUser()->getPHID())
+ ->setIsActive(1)
+ ->save();
+
+ return id(new AphrontRedirectResponse())->setURI('/releeph/');
+ }
+ }
+
+ $error_view = null;
+ if ($errors) {
+ $error_view = new AphrontErrorView();
+ $error_view->setErrors($errors);
+ $error_view->setTitle('Form Errors');
+ }
+
+ // Make our own optgroup select control
+ $arc_project_choices = array();
+ $pr_repositories = mpull(
+ msort(
+ array_filter(
+ // Some arc-projects don't have repositories
+ mpull($arc_projects, 'loadRepository')),
+ 'getName'),
+ null,
+ 'getID');
+
+ foreach ($pr_repositories as $pr_repo_id => $pr_repository) {
+ $options = array();
+ foreach ($arc_projects as $arc_project) {
+ if ($arc_project->getRepositoryID() == $pr_repo_id) {
+ $options[$arc_project->getID()] = $arc_project->getName();
+ }
+ }
+ $arc_project_choices[$pr_repository->getName()] = $options;
+ }
+
+ $project_name_input = id(new AphrontFormTextControl())
+ ->setLabel('Name')
+ ->setDisableAutocomplete(true)
+ ->setName('name')
+ ->setValue($name)
+ ->setError($e_name)
+ ->setCaption('A name like "Thrift" but not "Thrift releases".');
+
+ $arc_project_input = id(new AphrontFormSelectControl())
+ ->setLabel('Arc Project')
+ ->setName('arcPrID')
+ ->setValue($arc_pr_id)
+ ->setCaption(hsprintf(
+ "If your Arc project isn't listed, associate it with a repository %s",
+ phutil_tag(
+ 'a',
+ array(
+ 'href' => '/repository/',
+ 'target' => '_blank',
+ ),
+ 'here')))
+ ->setOptions($arc_project_choices);
+
+ $branch_name_preview = id(new ReleephBranchPreviewView())
+ ->setLabel('Example Branch')
+ ->addControl('projectName', $project_name_input)
+ ->addControl('arcProjectID', $arc_project_input)
+ ->addStatic('template', '')
+ ->addStatic('isSymbolic', false);
+
+ $form = id(new AphrontFormView())
+ ->setUser($request->getUser())
+ ->appendChild($project_name_input)
+ ->appendChild($arc_project_input)
+ ->appendChild(
+ id(new AphrontFormTextControl())
+ ->setLabel('Trunk')
+ ->setName('trunkBranch')
+ ->setValue($trunk_branch)
+ ->setError($e_trunk_branch)
+ ->setCaption('The development branch, '.
+ 'from which requests will be picked.'))
+ ->appendChild($branch_name_preview)
+ ->appendChild(
+ id(new AphrontFormSubmitControl())
+ ->addCancelButton('/releeph/project/')
+ ->setValue('Create'));
+
+ $panel = id(new AphrontPanelView())
+ ->setHeader('Create Releeph Project')
+ ->appendChild($form)
+ ->setWidth(AphrontPanelView::WIDTH_FORM);
+
+ return $this->buildStandardPageResponse(
+ array($error_view, $panel),
+ array(
+ 'title' => 'Create new Releeph Project'
+ ));
+ }
+}
diff --git a/src/applications/releeph/controller/project/ReleephProjectEditController.php b/src/applications/releeph/controller/project/ReleephProjectEditController.php
new file mode 100644
index 0000000000..1dcb128e61
--- /dev/null
+++ b/src/applications/releeph/controller/project/ReleephProjectEditController.php
@@ -0,0 +1,388 @@
+<?php
+
+final class ReleephProjectEditController extends ReleephController {
+
+ public function processRequest() {
+ $request = $this->getRequest();
+
+ $e_name = true;
+ $e_trunk_branch = true;
+ $e_branch_template = false;
+ $errors = array();
+
+ $project_name = $request->getStr('name',
+ $this->getReleephProject()->getName());
+
+ $phabricator_project_id = $request->getInt('projectID',
+ $this->getReleephProject()->getProjectID());
+ $trunk_branch = $request->getStr('trunkBranch',
+ $this->getReleephProject()->getTrunkBranch());
+ $branch_template = $request->getStr('branchTemplate');
+ if ($branch_template === null) {
+ $branch_template =
+ $this->getReleephProject()->getDetail('branchTemplate');
+ }
+ $pick_failure_instructions = $request->getStr('pickFailureInstructions',
+ $this->getReleephProject()->getDetail('pick_failure_instructions'));
+ $commit_author = $request->getStr('commitWithAuthor',
+ $this->getReleephProject()->getDetail('commitWithAuthor'));
+ $test_paths = $request->getStr('testPaths');
+ if ($test_paths !== null) {
+ $test_paths = array_filter(explode("\n", $test_paths));
+ } else {
+ $test_paths = $this->getReleephProject()->getDetail('testPaths', array());
+ }
+
+ $field_selector = $request->getStr('fieldSelector',
+ get_class($this->getReleephProject()->getReleephFieldSelector()));
+
+ $release_counter = $request->getInt(
+ 'releaseCounter',
+ $this->getReleephProject()->getCurrentReleaseNumber());
+
+ $arc_project_id = $this->getReleephProject()->getArcanistProjectID();
+
+ if ($request->isFormPost()) {
+ $pusher_phids = $request->getArr('pushers');
+
+ if (!$project_name) {
+ $e_name = 'Required';
+ $errors[] =
+ 'Your releeph project should have a simple descriptive name';
+ }
+
+ if (!$trunk_branch) {
+ $e_trunk_branch = 'Required';
+ $errors[] =
+ 'You must specify which branch you will be picking from.';
+ }
+
+ if ($release_counter && !is_int($release_counter)) {
+ $errors[] = "Release counter must be a positive integer!";
+ }
+
+ $other_releeph_projects = id(new ReleephProject())
+ ->loadAllWhere('id <> %d', $this->getReleephProject()->getID());
+ $other_releeph_project_names = mpull($other_releeph_projects,
+ 'getName', 'getID');
+
+ if (in_array($project_name, $other_releeph_project_names)) {
+ $errors[] = "Releeph project name {$project_name} is already taken";
+ }
+
+ foreach ($test_paths as $test_path) {
+ $result = @preg_match($test_path, '');
+ $is_a_valid_regexp = $result !== false;
+ if (!$is_a_valid_regexp) {
+ $errors[] = 'Please provide a valid regular expression: '.
+ "{$test_path} is not valid";
+ }
+ }
+
+ $project = $this->getReleephProject()
+ ->setProjectID($phabricator_project_id)
+ ->setTrunkBranch($trunk_branch)
+ ->setDetail('pushers', $pusher_phids)
+ ->setDetail('pick_failure_instructions', $pick_failure_instructions)
+ ->setDetail('field_selector', $field_selector)
+ ->setDetail('branchTemplate', $branch_template)
+ ->setDetail('commitWithAuthor', $commit_author)
+ ->setDetail('testPaths', $test_paths);
+
+ if ($release_counter) {
+ $project->setDetail('releaseCounter', $release_counter);
+ }
+
+ $fake_commit_handle =
+ ReleephBranchTemplate::getFakeCommitHandleFor($arc_project_id);
+
+ if ($branch_template) {
+ list($branch_name, $template_errors) = id(new ReleephBranchTemplate())
+ ->setCommitHandle($fake_commit_handle)
+ ->setReleephProjectName($project_name)
+ ->interpolate($branch_template);
+
+ if ($template_errors) {
+ $e_branch_template = 'Invalid!';
+ foreach ($template_errors as $template_error) {
+ $errors[] = "Template error: {$template_error}";
+ }
+ }
+ }
+
+ if (!$errors) {
+ $project->save();
+
+ return id(new AphrontRedirectResponse())
+ ->setURI('/releeph/project/');
+ }
+ }
+
+ $error_view = null;
+ if ($errors) {
+ $error_view = new AphrontErrorView();
+ $error_view->setErrors($errors);
+ $error_view->setTitle('Form Errors');
+ }
+
+ $projects = mpull(
+ id(new PhabricatorProject())->loadAll(),
+ 'getName',
+ 'getID');
+
+ $projects[0] = '-'; // no project associated, that's ok
+
+ $pusher_phids = $request->getArr(
+ 'pushers',
+ $this->getReleephProject()->getDetail('pushers', array()));
+
+ $handles = id(new PhabricatorObjectHandleData($pusher_phids))
+ ->setViewer($request->getUser())
+ ->loadHandles();
+
+ $pusher_tokens = array();
+ foreach ($pusher_phids as $phid) {
+ $pusher_tokens[$phid] = $handles[$phid]->getFullName();
+ }
+
+ $basic_inset = id(new AphrontFormInsetView())
+ ->setTitle('Basics')
+ ->appendChild(
+ id(new AphrontFormTextControl())
+ ->setLabel('Name')
+ ->setName('name')
+ ->setValue($project_name)
+ ->setError($e_name)
+ ->setCaption('A name like "Thrift" but not "Thrift releases".'))
+ ->appendChild(
+ id(new AphrontFormStaticControl())
+ ->setLabel('Repository')
+ ->setValue(
+ $this
+ ->getReleephProject()
+ ->loadPhabricatorRepository()
+ ->getName()))
+ ->appendChild(
+ id(new AphrontFormStaticControl())
+ ->setLabel('Arc Project')
+ ->setValue(
+ $this->getReleephProject()->loadArcanistProject()->getName()))
+ ->appendChild(
+ id(new AphrontFormStaticControl())
+ ->setLabel('Releeph Project PHID')
+ ->setValue(
+ $this->getReleephProject()->getPHID()))
+ ->appendChild(
+ id(new AphrontFormSelectControl())
+ ->setLabel('Phabricator Project')
+ ->setValue($phabricator_project_id)
+ ->setName('projectID')
+ ->setOptions($projects))
+ ->appendChild(
+ id(new AphrontFormTextControl())
+ ->setLabel('Trunk')
+ ->setValue($trunk_branch)
+ ->setName('trunkBranch')
+ ->setError($e_trunk_branch))
+ ->appendChild(
+ id(new AphrontFormTextControl())
+ ->setLabel('Release counter')
+ ->setValue($release_counter)
+ ->setName('releaseCounter')
+ ->setCaption(
+ "Used by the command line branch cutter's %N field"))
+ ->appendChild(
+ id(new AphrontFormTextAreaControl())
+ ->setLabel('Pick Instructions')
+ ->setValue($pick_failure_instructions)
+ ->setName('pickFailureInstructions')
+ ->setCaption(
+ "Instructions for pick failures, which will be used " .
+ "in emails generated by failed picks"))
+ ->appendChild(
+ id(new AphrontFormTextAreaControl())
+ ->setLabel('Tests paths')
+ ->setValue(implode("\n", $test_paths))
+ ->setName('testPaths')
+ ->setCaption(
+ 'List of strings that all test files contain in their path '.
+ 'in this project. One string per line. '.
+ 'Examples: \'__tests__\', \'/javatests/\'...'));
+
+ $pushers_inset = id(new AphrontFormInsetView())
+ ->setTitle('Pushers')
+ ->appendChild(
+ 'Pushers are allowed to approve Releeph requests to be committed. '.
+ 'to this project\'s branches. If you leave this blank then anyone '.
+ 'is allowed to approve requests.')
+ ->appendChild(
+ id(new AphrontFormTokenizerControl())
+ ->setLabel('Pushers')
+ ->setName('pushers')
+ ->setDatasource('/typeahead/common/users/')
+ ->setValue($pusher_tokens));
+
+ $field_selector_options = array();
+ $field_selector_symbols = id(new PhutilSymbolLoader())
+ ->setType('class')
+ ->setConcreteOnly(true)
+ ->setAncestorClass('ReleephFieldSelector')
+ ->selectAndLoadSymbols();
+ foreach ($field_selector_symbols as $symbol) {
+ $selector_name = $symbol['name'];
+ $field_selector_options[$selector_name] = $selector_name;
+ }
+
+ $field_selector_blurb = hsprintf(
+ "If you you have additional information to render about Releeph ".
+ "requests, or want to re-arrange the UI, implement a ".
+ "<tt>ReleephFieldSelector</tt> and select it here.");
+
+ $fields_inset = id(new AphrontFormInsetView())
+ ->setTitle('Fields')
+ ->appendChild($field_selector_blurb)
+ ->appendChild(
+ id(new AphrontFormSelectControl())
+ ->setLabel('Selector')
+ ->setName('fieldSelector')
+ ->setValue($field_selector)
+ ->setOptions($field_selector_options));
+
+ $commit_author_inset = $this->buildCommitAuthorInset($commit_author);
+
+ // Build the Template inset
+ $markup_engine = PhabricatorMarkupEngine::newDifferentialMarkupEngine();
+
+ // From DifferentialUnitFieldSpecification...
+ $markup_engine->setConfig('viewer', $request->getUser());
+
+ $help_markup = phutil_tag(
+ 'div',
+ array(
+ 'class' => 'phabricator-remarkup',
+ ),
+ phutil_safe_html(
+ $markup_engine->markupText(ReleephBranchTemplate::getHelpRemarkup())));
+
+ $branch_template_input = id(new AphrontFormTextControl())
+ ->setName('branchTemplate')
+ ->setValue($branch_template)
+ ->setLabel('Template')
+ ->setError($e_branch_template)
+ ->setCaption(
+ "Leave this blank to use your installation's default.");
+
+ $branch_template_preview = id(new ReleephBranchPreviewView())
+ ->setLabel('Preview')
+ ->addControl('template', $branch_template_input)
+ ->addStatic('arcProjectID', $arc_project_id)
+ ->addStatic('isSymbolic', false)
+ ->addStatic('projectName', $this->getReleephProject()->getName());
+
+ $template_inset = id(new AphrontFormInsetView())
+ ->setTitle('Branch Cutting')
+ ->appendChild(
+ 'Provide a pattern for creating new branches.')
+ ->appendChild($branch_template_input)
+ ->appendChild($branch_template_preview)
+ ->appendChild($help_markup);
+
+ // Build the form
+ $form = id(new AphrontFormView())
+ ->setUser($request->getUser())
+ ->appendChild($basic_inset)
+ ->appendChild($pushers_inset)
+ ->appendChild($fields_inset)
+ ->appendChild($commit_author_inset)
+ ->appendChild($template_inset);
+
+ $form
+ ->appendChild(
+ id(new AphrontFormSubmitControl())
+ ->addCancelButton('/releeph/project/')
+ ->setValue('Save'));
+
+ $panel = id(new AphrontPanelView())
+ ->setHeader('Edit Releeph Project')
+ ->appendChild($form)
+ ->setWidth(AphrontPanelView::WIDTH_FORM);
+
+ return $this->buildStandardPageResponse(
+ array($error_view, $panel),
+ array('title' => 'Edit Releeph Project'));
+ }
+
+ private function buildCommitAuthorInset($current) {
+ $vcs_type = $this->getReleephProject()
+ ->loadPhabricatorRepository()
+ ->getVersionControlSystem();
+
+ switch ($vcs_type) {
+ case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
+ case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
+ break;
+
+ case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
+ return;
+ break;
+ }
+
+ $vcs_name = PhabricatorRepositoryType::getNameForRepositoryType($vcs_type);
+
+ $help_markup = hsprintf(<<<EOTEXT
+When your project's release engineers run <tt>arc releeph</tt>, they will be
+listed as the <strong>committer</strong> of the code committed to release
+branches.
+
+%s allows you to specify a separate author when committing code. Some
+tools use the author of a commit (rather than the committer) when they need to
+notify someone about a build or test failure.
+
+Releeph can use one of the following to set the <strong>author</strong> of the
+commits it makes:
+EOTEXT
+ , $vcs_name);
+
+ $trunk = $this->getReleephProject()->getTrunkBranch();
+
+ $options = array(
+ array(
+ 'value' => ReleephProject::COMMIT_AUTHOR_FROM_DIFF,
+ 'label' => 'Original Author',
+ 'caption' =>
+ "The author of the original commit in {$trunk}.",
+ ),
+ array(
+ 'value' => ReleephProject::COMMIT_AUTHOR_REQUESTOR,
+ 'label' => 'Requestor',
+ 'caption' =>
+ "The person who requested that this code go into the release.",
+ ),
+ array(
+ 'value' => ReleephProject::COMMIT_AUTHOR_NONE,
+ 'label' => "None",
+ 'caption' =>
+ "Only record the default committer information.",
+ ),
+ );
+
+ if (!$current) {
+ $current = ReleephProject::COMMIT_AUTHOR_FROM_DIFF;
+ }
+
+ $control = id(new AphrontFormRadioButtonControl())
+ ->setLabel('Author')
+ ->setName('commitWithAuthor')
+ ->setValue($current);
+
+ foreach ($options as $dict) {
+ $control->addButton($dict['value'], $dict['label'], $dict['caption']);
+ }
+
+ return id(new AphrontFormInsetView())
+ ->setTitle('Authors')
+ ->appendChild($help_markup)
+ ->appendChild($control);
+ }
+
+}
diff --git a/src/applications/releeph/controller/project/ReleephProjectListController.php b/src/applications/releeph/controller/project/ReleephProjectListController.php
new file mode 100644
index 0000000000..e00709d086
--- /dev/null
+++ b/src/applications/releeph/controller/project/ReleephProjectListController.php
@@ -0,0 +1,70 @@
+<?php
+
+final class ReleephProjectListController extends PhabricatorController {
+
+ public function processRequest() {
+ $path = $this->getRequest()->getRequestURI()->getPath();
+ $is_active = strpos($path, 'inactive/') === false;
+
+ $releeph_projects = mfilter(
+ id(new ReleephProject())->loadAll(),
+ 'getIsActive',
+ !$is_active);
+ $releeph_projects = msort($releeph_projects, 'getName');
+
+ $releeph_projects_set = new LiskDAOSet();
+ foreach ($releeph_projects as $releeph_project) {
+ $releeph_projects_set->addToSet($releeph_project);
+ }
+
+ $panel = new AphrontPanelView();
+
+ if ($is_active) {
+ $view_inactive_link = phutil_tag(
+ 'a',
+ array(
+ 'href' => '/releeph/project/inactive/',
+ ),
+ 'View inactive projects');
+ $panel
+ ->setHeader(hsprintf(
+ 'Active Releeph Projects &middot; %s', $view_inactive_link))
+ ->appendChild(
+ id(new ReleephActiveProjectListView())
+ ->setUser($this->getRequest()->getUser())
+ ->setReleephProjects($releeph_projects));
+ } else {
+ $view_active_link = phutil_tag(
+ 'a',
+ array(
+ 'href' => '/releeph/project/'
+ ),
+ 'View active projects');
+ $panel
+ ->setHeader(hsprintf(
+ 'Inactive Releeph Projects &middot; %s', $view_active_link))
+ ->appendChild(
+ id(new ReleephInactiveProjectListView())
+ ->setUser($this->getRequest()->getUser())
+ ->setReleephProjects($releeph_projects));
+ }
+
+ if ($is_active) {
+ $create_new_project_button = phutil_tag(
+ 'a',
+ array(
+ 'href' => '/releeph/project/create/',
+ 'class' => 'green button',
+ ),
+ 'Create New Project');
+ $panel->addButton($create_new_project_button);
+ }
+
+ return $this->buildStandardPageResponse(
+ $panel,
+ array(
+ 'title' => 'List Releeph Projects'
+ ));
+ }
+
+}
diff --git a/src/applications/releeph/controller/project/ReleephProjectViewController.php b/src/applications/releeph/controller/project/ReleephProjectViewController.php
new file mode 100644
index 0000000000..2706822468
--- /dev/null
+++ b/src/applications/releeph/controller/project/ReleephProjectViewController.php
@@ -0,0 +1,45 @@
+<?php
+
+final class ReleephProjectViewController extends ReleephController {
+
+ public function processRequest() {
+ // Load all branches
+ $releeph_project = $this->getReleephProject();
+ $releeph_branches = id(new ReleephBranch())
+ ->loadAllWhere('releephProjectID = %d',
+ $releeph_project->getID());
+
+ $path = $this->getRequest()->getRequestURI()->getPath();
+ $is_open_branches = strpos($path, 'closedbranches/') === false;
+
+ $view = id(new ReleephProjectView())
+ ->setShowOpenBranches($is_open_branches)
+ ->setUser($this->getRequest()->getUser())
+ ->setReleephProject($releeph_project)
+ ->setBranches($releeph_branches);
+
+ $crumbs = $this->buildApplicationCrumbs()
+ ->addCrumb(
+ id(new PhabricatorCrumbView())
+ ->setName($releeph_project->getName())
+ ->setHref($releeph_project->getURI()));
+
+ if ($releeph_project->getIsActive()) {
+ $crumbs->addAction(
+ id(new PhabricatorMenuItemView())
+ ->setHref($releeph_project->getURI('cutbranch'))
+ ->setName('Cut New Branch')
+ ->setIcon('create'));
+ }
+
+ return $this->buildStandardPageResponse(
+ array(
+ $crumbs,
+ $view,
+ ),
+ array(
+ 'title' => $releeph_project->getName().' Releeph Project'
+ ));
+ }
+
+}
diff --git a/src/applications/releeph/controller/request/ReleephRequestActionController.php b/src/applications/releeph/controller/request/ReleephRequestActionController.php
new file mode 100644
index 0000000000..f7229cda2e
--- /dev/null
+++ b/src/applications/releeph/controller/request/ReleephRequestActionController.php
@@ -0,0 +1,71 @@
+<?php
+
+final class ReleephRequestActionController extends ReleephController {
+
+ private $action;
+
+ public function willProcessRequest(array $data) {
+ parent::willProcessRequest($data);
+ $this->action = $data['action'];
+ }
+
+ public function processRequest() {
+ $request = $this->getRequest();
+
+ $releeph_branch = $this->getReleephBranch();
+ $releeph_request = $this->getReleephRequest();
+
+ $releeph_branch->populateReleephRequestHandles(
+ $request->getUser(), array($releeph_request));
+
+ $action = $this->action;
+
+ $user = $request->getUser();
+
+ $origin_uri = $releeph_request->loadReleephBranch()->getURI();
+
+ $editor = id(new ReleephRequestEditor($releeph_request))
+ ->setActor($user);
+
+ switch ($action) {
+ case 'want':
+ case 'pass':
+ static $action_map = array(
+ 'want' => ReleephRequest::INTENT_WANT,
+ 'pass' => ReleephRequest::INTENT_PASS);
+ $intent = $action_map[$action];
+ $editor->changeUserIntent($user, $intent);
+ break;
+
+ case 'mark-manually-picked':
+ $editor->markManuallyActioned('pick');
+ break;
+
+ case 'mark-manually-reverted':
+ $editor->markManuallyActioned('revert');
+ break;
+
+ default:
+ throw new Exception("unknown or unimplemented action {$action}");
+ }
+
+ // If we're adding a new user to userIntents, we'll have to re-populate
+ // request handles to load that user's data.
+ //
+ // This is cheap enough to do every time.
+ $this->getReleephBranch()->populateReleephRequestHandles(
+ $user, array($releeph_request));
+
+ $list = id(new ReleephRequestHeaderListView())
+ ->setReleephProject($this->getReleephProject())
+ ->setReleephBranch($this->getReleephBranch())
+ ->setReleephRequests(array($releeph_request))
+ ->setUser($request->getUser())
+ ->setAphrontRequest($this->getRequest())
+ ->setOriginType('request');
+
+ return id(new AphrontAjaxResponse())->setContent(array(
+ 'markup' => head($list->renderInner())
+ ));
+ }
+}
diff --git a/src/applications/releeph/controller/request/ReleephRequestCreateController.php b/src/applications/releeph/controller/request/ReleephRequestCreateController.php
new file mode 100644
index 0000000000..21415fc54a
--- /dev/null
+++ b/src/applications/releeph/controller/request/ReleephRequestCreateController.php
@@ -0,0 +1,165 @@
+<?php
+
+final class ReleephRequestCreateController extends ReleephController {
+
+ const MAX_SUMMARY_LENGTH = 70;
+
+ public function processRequest() {
+ $request = $this->getRequest();
+
+ // We arrived via /releeph/request/create/?branchID=$id
+ $releeph_branch_id = $request->getInt('branchID');
+ if ($releeph_branch_id) {
+ $releeph_branch = id(new ReleephBranch())->load($releeph_branch_id);
+ } else {
+ // We arrived via /releeph/$project/$branch/request.
+ //
+ // If this throws an Exception, then somethind weird happened.
+ $releeph_branch = $this->getReleephBranch();
+ }
+
+ $releeph_project = $releeph_branch->loadReleephProject();
+ $repo = $releeph_project->loadPhabricatorRepository();
+
+ $request_identifier = $request->getStr('requestIdentifierRaw');
+ $e_request_identifier = true;
+
+ $releeph_request = new ReleephRequest();
+
+ $errors = array();
+
+ $selector = $releeph_project->getReleephFieldSelector();
+ $fields = $selector->getFieldSpecifications();
+ foreach ($fields as $field) {
+ $field
+ ->setReleephProject($releeph_project)
+ ->setReleephBranch($releeph_branch)
+ ->setReleephRequest($releeph_request);
+ }
+
+ if ($request->isFormPost()) {
+ foreach ($fields as $field) {
+ if ($field->isEditable()) {
+ try {
+ $field->setValueFromAphrontRequest($request);
+ } catch (ReleephFieldParseException $ex) {
+ $errors[] = $ex->getMessage();
+ }
+ }
+ }
+
+ $pr_commit = null;
+ $finder = id(new ReleephCommitFinder())
+ ->setReleephProject($releeph_project);
+ try {
+ $pr_commit = $finder->fromPartial($request_identifier);
+ } catch (Exception $e) {
+ $e_request_identifier = 'Invalid';
+ $errors[] =
+ "Request {$request_identifier} is probably not a valid commit";
+ $errors[] = $e->getMessage();
+ }
+
+ $pr_commit_data = null;
+ if (!$errors) {
+ $pr_commit_data = $pr_commit->loadCommitData();
+ if (!$pr_commit_data) {
+ $e_request_identifier = 'Not parsed yet';
+ $errors[] = "The requested commit hasn't been parsed yet.";
+ }
+ }
+
+ if (!$errors) {
+ $existing = id(new ReleephRequest())
+ ->loadOneWhere('requestCommitPHID = %s AND branchID = %d',
+ $pr_commit->getPHID(), $releeph_branch->getID());
+
+ if ($existing) {
+ return id(new AphrontRedirectResponse())
+ ->setURI('/releeph/request/edit/'.$existing->getID().
+ '?existing=1');
+ }
+
+ id(new ReleephRequestEditor($releeph_request))
+ ->setActor($request->getUser())
+ ->create($pr_commit, $releeph_branch);
+
+ return id(new AphrontRedirectResponse())
+ ->setURI($releeph_branch->getURI());
+ }
+ }
+
+ $error_view = null;
+ if ($errors) {
+ $error_view = new AphrontErrorView();
+ $error_view->setErrors($errors);
+ $error_view->setTitle('Form Errors');
+ }
+
+ // For the typeahead
+ $branch_cut_point = id(new PhabricatorRepositoryCommit())
+ ->loadOneWhere(
+ 'phid = %s',
+ $releeph_branch->getCutPointCommitPHID());
+
+ // Build the form
+ $form = id(new AphrontFormView())
+ ->setUser($request->getUser());
+
+ $origin = null;
+ $diff_rev_id = $request->getStr('D');
+ if ($diff_rev_id) {
+ $diff_rev = id(new DifferentialRevision())->load($diff_rev_id);
+ $origin = '/D'.$diff_rev->getID();
+ $title = sprintf(
+ 'D%d: %s',
+ $diff_rev_id,
+ $diff_rev->getTitle());
+ $form
+ ->addHiddenInput('requestIdentifierRaw', 'D'.$diff_rev_id)
+ ->appendChild(
+ id(new AphrontFormStaticControl())
+ ->setLabel('Diff')
+ ->setValue($title));
+ } else {
+ $origin = $releeph_branch->getURI();
+ $form->appendChild(
+ id(new ReleephRequestTypeaheadControl())
+ ->setName('requestIdentifierRaw')
+ ->setLabel('Commit ID')
+ ->setRepo($repo)
+ ->setValue($request_identifier)
+ ->setError($e_request_identifier)
+ ->setStartTime($branch_cut_point->getEpoch())
+ ->setCaption(
+ 'Start typing to autocomplete on commit title, '.
+ 'or give a Phabricator commit identifier like rFOO1234'));
+ }
+
+ // Fields
+ foreach ($fields as $field) {
+ if ($field->isEditable()) {
+ $control = $field->renderEditControl($request);
+ $form->appendChild($control);
+ }
+ }
+
+ $form
+ ->appendChild(
+ id(new AphrontFormSubmitControl())
+ ->addCancelButton($origin)
+ ->setValue('Request'));
+
+ $panel = id(new AphrontPanelView())
+ ->setHeader(
+ 'Request for '.
+ $releeph_branch->getDisplayNameWithDetail())
+ ->setWidth(AphrontPanelView::WIDTH_FORM)
+ ->appendChild($form);
+
+ return $this->buildStandardPageResponse(
+ array($error_view, $panel),
+ array('title' => 'Request pick'));
+ }
+
+}
diff --git a/src/applications/releeph/controller/request/ReleephRequestDifferentialCreateController.php b/src/applications/releeph/controller/request/ReleephRequestDifferentialCreateController.php
new file mode 100644
index 0000000000..9da50fa846
--- /dev/null
+++ b/src/applications/releeph/controller/request/ReleephRequestDifferentialCreateController.php
@@ -0,0 +1,99 @@
+<?php
+
+final class ReleephRequestDifferentialCreateController
+ extends ReleephController {
+
+ private $revision;
+
+ public function willProcessRequest($data) {
+ $diff_rev_id = $data['diffRevID'];
+ $diff_rev = id(new DifferentialRevision())->load($diff_rev_id);
+ if (!$diff_rev) {
+ throw new Exception(sprintf('D%d not found!', $diff_rev_id));
+ }
+ $this->revision = $diff_rev;
+ }
+
+ public function processRequest() {
+ $request = $this->getRequest();
+ $user = $request->getUser();
+
+ $arc_project = id(new PhabricatorRepositoryArcanistProject())
+ ->loadOneWhere('phid = %s', $this->revision->getArcanistProjectPHID());
+
+ $projects = id(new ReleephProject())->loadAllWhere(
+ 'arcanistProjectID = %d AND isActive = 1',
+ $arc_project->getID());
+ if (!$projects) {
+ throw new ReleephRequestException(sprintf(
+ "D%d belongs to the '%s' Arcanist project, ".
+ "which is not part of any Releeph project!",
+ $this->revision->getID(),
+ $arc_project->getName()));
+ }
+
+ $branches = id(new ReleephBranch())->loadAllWhere(
+ 'releephProjectID IN (%Ld) AND isActive = 1',
+ mpull($projects, 'getID'));
+ if (!$branches) {
+ throw new ReleephRequestException(sprintf(
+ "D%d could be in the Releeph project(s) %s, ".
+ "but this project / none of these projects have open branches.",
+ $this->revision->getID(),
+ implode(', ', mpull($projects, 'getName'))));
+ }
+
+ if (count($branches) === 1) {
+ return id(new AphrontRedirectResponse())
+ ->setURI($this->buildReleephRequestURI(head($branches)));
+ }
+
+ $projects = msort(
+ mpull($projects, null, 'getID'),
+ 'getName');
+
+ $branch_groups = mgroup($branches, 'getReleephProjectID');
+
+ require_celerity_resource('releeph-request-differential-create-dialog');
+ $dialog = id(new AphrontDialogView())
+ ->setUser($user)
+ ->setTitle('Choose Releeph Branch')
+ ->setClass('releeph-request-differential-create-dialog')
+ ->addCancelButton('/D'.$request->getStr('D'));
+
+ $dialog->appendChild(
+ "This differential revision changes code that is associated ".
+ "with multiple Releeph branches. ".
+ "Please select the branch where you would like this code to be picked.");
+
+ foreach ($branch_groups as $project_id => $branches) {
+ $project = idx($projects, $project_id);
+ $dialog->appendChild(
+ phutil_tag(
+ 'h1',
+ array(),
+ $project->getName()));
+ $branches = msort($branches, 'getBasename');
+ foreach ($branches as $branch) {
+ $uri = $this->buildReleephRequestURI($branch);
+ $dialog->appendChild(
+ phutil_tag(
+ 'a',
+ array(
+ 'href' => $uri,
+ ),
+ $branch->getDisplayNameWithDetail()));
+ }
+ }
+
+ return id(new AphrontDialogResponse)
+ ->setDialog($dialog);
+ }
+
+ private function buildReleephRequestURI(ReleephBranch $branch) {
+ return id(new PhutilURI('/releeph/request/create/'))
+ ->setQueryParam('branchID', $branch->getID())
+ ->setQueryParam('D', $this->revision->getID());
+ }
+
+}
diff --git a/src/applications/releeph/controller/request/ReleephRequestEditController.php b/src/applications/releeph/controller/request/ReleephRequestEditController.php
new file mode 100644
index 0000000000..eefe3bf601
--- /dev/null
+++ b/src/applications/releeph/controller/request/ReleephRequestEditController.php
@@ -0,0 +1,132 @@
+<?php
+
+final class ReleephRequestEditController extends ReleephController {
+
+ public function processRequest() {
+ $request = $this->getRequest();
+
+ $releeph_branch = $this->getReleephBranch();
+ $releeph_request = $this->getReleephRequest();
+
+ $releeph_branch->populateReleephRequestHandles(
+ $request->getUser(), array($releeph_request));
+
+ $phids = array();
+ $phids[] = $releeph_request->getRequestCommitPHID();
+ $phids[] = $releeph_request->getRequestUserPHID();
+ $phids[] = $releeph_request->getCommittedByUserPHID();
+
+ $handles = id(new PhabricatorObjectHandleData($phids))
+ ->setViewer($request->getUser())
+ ->loadHandles();
+
+ $age_string = phabricator_format_relative_time(
+ time() - $releeph_request->getDateCreated());
+
+ // Warn the user if we see this
+ $notice_view = null;
+ if ($request->getInt('existing')) {
+ $notice_messages = array(
+ 'You are editing an existing pick request!',
+ hsprintf(
+ "Requested %s ago by %s",
+ $age_string,
+ $handles[$releeph_request->getRequestUserPHID()]->renderLink())
+ );
+ $notice_view = id(new AphrontErrorView())
+ ->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
+ ->setErrors($notice_messages);
+ }
+
+ // <aidehua> epriestley: Is it common to pass around a referer URL to
+ // return from whence one came? [...]
+ // <epriestley> If you only have two places, maybe consider some parameter
+ // rather than the full URL.
+ switch ($request->getStr('origin')) {
+ case 'request':
+ $origin_uri = '/RQ'.$releeph_request->getID();
+ break;
+
+ case 'branch':
+ default:
+ $origin_uri = $releeph_request->loadReleephBranch()->getURI();
+ break;
+ }
+
+ $errors = array();
+
+ $selector = $this->getReleephProject()->getReleephFieldSelector();
+ $fields = $selector->getFieldSpecifications();
+ foreach ($fields as $field) {
+ $field
+ ->setReleephProject($this->getReleephProject())
+ ->setReleephBranch($this->getReleephBranch())
+ ->setReleephRequest($this->getReleephRequest());
+ }
+
+ if ($request->isFormPost()) {
+ foreach ($fields as $field) {
+ if ($field->isEditable()) {
+ try {
+ $field->setValueFromAphrontRequest($request);
+ } catch (ReleephFieldParseException $ex) {
+ $errors[] = $ex->getMessage();
+ }
+ }
+ }
+
+ if (!$errors) {
+ $releeph_request->save();
+ return id(new AphrontRedirectResponse())->setURI($origin_uri);
+ }
+ }
+
+ /**
+ * Build the rest of the page
+ */
+ $error_view = null;
+ if ($errors) {
+ $error_view = new AphrontErrorView();
+ $error_view->setErrors($errors);
+ $error_view->setTitle('Form Errors');
+ }
+
+ $form = id(new AphrontFormView())
+ ->setUser($request->getUser())
+ ->appendChild(
+ id(new AphrontFormMarkupControl())
+ ->setLabel('Original Commit')
+ ->setValue(
+ $handles[$releeph_request->getRequestCommitPHID()]->renderLink()))
+ ->appendChild(
+ id(new AphrontFormMarkupControl())
+ ->setLabel('Requestor')
+ ->setValue(hsprintf(
+ '%s %s ago',
+ $handles[$releeph_request->getRequestUserPHID()]->renderLink(),
+ $age_string)));
+
+ // Fields
+ foreach ($fields as $field) {
+ if ($field->isEditable()) {
+ $control = $field->renderEditControl($request);
+ $form->appendChild($control);
+ }
+ }
+
+ $form
+ ->appendChild(
+ id(new AphrontFormSubmitControl())
+ ->addCancelButton($origin_uri, 'Cancel')
+ ->setValue('Save'));
+
+ $panel = id(new AphrontPanelView())
+ ->setHeader('Edit Pick Request')
+ ->setWidth(AphrontPanelView::WIDTH_FORM)
+ ->appendChild($form);
+
+ return $this->buildStandardPageResponse(
+ array($notice_view, $error_view, $panel),
+ array('title', 'Edit Pick Request'));
+ }
+}
diff --git a/src/applications/releeph/controller/request/ReleephRequestTypeaheadController.php b/src/applications/releeph/controller/request/ReleephRequestTypeaheadController.php
new file mode 100644
index 0000000000..c86060c4b0
--- /dev/null
+++ b/src/applications/releeph/controller/request/ReleephRequestTypeaheadController.php
@@ -0,0 +1,92 @@
+<?php
+
+final class ReleephRequestTypeaheadController
+ extends PhabricatorTypeaheadDatasourceController {
+
+ public function processRequest() {
+ $request = $this->getRequest();
+
+ $query = $request->getStr('q');
+ $repo_id = $request->getInt('repo');
+ $since = $request->getInt('since');
+ $limit = $request->getInt('limit');
+
+ $now = time();
+ $data = array();
+
+ // Dummy instances used for getting connections, table names, etc.
+ $pr_commit = new PhabricatorRepositoryCommit();
+ $pr_commit_data = new PhabricatorRepositoryCommitData();
+
+ $conn = $pr_commit->establishConnection('r');
+
+ $rows = queryfx_all(
+ $conn,
+ 'SELECT
+ rc.phid as commitPHID,
+ rc.authorPHID,
+ rcd.authorName,
+ SUBSTRING(rcd.commitMessage, 1, 100) AS shortMessage,
+ rc.commitIdentifier,
+ rc.epoch
+ FROM %T rc
+ INNER JOIN %T rcd ON rcd.commitID = rc.id
+ WHERE repositoryID = %d
+ AND rc.epoch >= %d
+ AND (
+ rcd.commitMessage LIKE %~
+ OR
+ rc.commitIdentifier LIKE %~
+ )
+ ORDER BY rc.epoch DESC
+ LIMIT %d',
+ $pr_commit->getTableName(),
+ $pr_commit_data->getTableName(),
+ $repo_id,
+ $since,
+ $query,
+ $query,
+ $limit);
+
+ foreach ($rows as $row) {
+ $full_commit_id = $row['commitIdentifier'];
+ $short_commit_id = substr($full_commit_id, 0, 12);
+ $first_line = $this->getFirstLine($row['shortMessage']);
+ $data[] = array(
+ $full_commit_id,
+ $short_commit_id,
+ $row['authorName'],
+ phabricator_format_relative_time($now - $row['epoch']),
+ $first_line,
+ );
+ }
+
+ return id(new AphrontAjaxResponse())
+ ->setContent($data);
+ }
+
+ /**
+ * Split either at the first new line, or a bunch of dashes.
+ *
+ * Really just a legacy from old Releeph Daemon commit messages where I used
+ * to say:
+ *
+ * Commit of FOO for BAR
+ * ------------
+ * This does X Y Z
+ *
+ */
+ private function getFirstLine($commit_message_fragment) {
+ static $separators = array('-------', "\n");
+ $string = ltrim($commit_message_fragment);
+ $first_line = $string;
+ foreach ($separators as $separator) {
+ if ($pos = strpos($string, $separator)) {
+ $first_line = substr($string, 0, $pos);
+ break;
+ }
+ }
+ return $first_line;
+ }
+
+}
diff --git a/src/applications/releeph/controller/request/ReleephRequestViewController.php b/src/applications/releeph/controller/request/ReleephRequestViewController.php
new file mode 100644
index 0000000000..f0cd2661fe
--- /dev/null
+++ b/src/applications/releeph/controller/request/ReleephRequestViewController.php
@@ -0,0 +1,99 @@
+<?php
+
+final class ReleephRequestViewController extends ReleephController {
+
+ public function processRequest() {
+ $request = $this->getRequest();
+
+ $uri_path = $request->getRequestURI()->getPath();
+ $legacy_prefix = '/releeph/request/';
+ if (strncmp($uri_path, $legacy_prefix, strlen($legacy_prefix)) === 0) {
+ return id(new AphrontRedirectResponse())
+ ->setURI('/RQ'.$this->getReleephRequest()->getID());
+ }
+
+ $releeph_request = $this->getReleephRequest();
+ $releeph_branch = $this->getReleephBranch();
+ $releeph_project = $this->getReleephProject();
+
+ $releeph_branch->populateReleephRequestHandles(
+ $request->getUser(), array($releeph_request));
+
+ $rq_view =
+ id(new ReleephRequestHeaderListView())
+ ->setReleephProject($releeph_project)
+ ->setReleephBranch($releeph_branch)
+ ->setReleephRequests(array($releeph_request))
+ ->setUser($request->getUser())
+ ->setAphrontRequest($this->getRequest())
+ ->setReloadOnStateChange(true)
+ ->setOriginType('request');
+
+ $events = $releeph_request->loadEvents();
+ $phids = array_mergev(mpull($events, 'extractPHIDs'));
+ $handles = id(new PhabricatorObjectHandleData($phids))
+ ->setViewer($request->getUser())
+ ->loadHandles();
+
+ $rq_event_list_view =
+ id(new ReleephRequestEventListView())
+ ->setUser($request->getUser())
+ ->setEvents($events)
+ ->setHandles($handles);
+
+ // Handle comment submit
+ $origin_uri = '/RQ'.$releeph_request->getID();
+ if ($request->isFormPost()) {
+ id(new ReleephRequestEditor($releeph_request))
+ ->setActor($request->getUser())
+ ->addComment($request->getStr('comment'));
+ return id(new AphrontRedirectResponse())->setURI($origin_uri);
+ }
+
+ $form = id(new AphrontFormView())
+ ->setUser($request->getUser())
+ ->appendChild(
+ id(new AphrontFormTextAreaControl())
+ ->setName('comment'))
+ ->appendChild(
+ id(new AphrontFormSubmitControl())
+ ->addCancelButton($origin_uri, 'Cancel')
+ ->setValue("Submit"));
+
+ $rq_comment_form = id(new AphrontPanelView())
+ ->setHeader('Add a comment')
+ ->setWidth(AphrontPanelView::WIDTH_FULL)
+ ->appendChild($form);
+
+ $title = hsprintf("RQ%d: %s",
+ $releeph_request->getID(),
+ $releeph_request->getSummaryForDisplay());
+
+ $crumbs = $this->buildApplicationCrumbs()
+ ->addCrumb(
+ id(new PhabricatorCrumbView())
+ ->setName($releeph_project->getName())
+ ->setHref($releeph_project->getURI()))
+ ->addCrumb(
+ id(new PhabricatorCrumbView())
+ ->setName($releeph_branch->getDisplayNameWithDetail())
+ ->setHref($releeph_branch->getURI()))
+ ->addCrumb(
+ id(new PhabricatorCrumbView())
+ ->setName('RQ'.$releeph_request->getID())
+ ->setHref('/RQ'.$releeph_request->getID()));
+
+ return $this->buildStandardPageResponse(
+ array(
+ $crumbs,
+ array(
+ $rq_view,
+ $rq_event_list_view,
+ $rq_comment_form
+ )
+ ),
+ array(
+ 'title' => $title
+ ));
+ }
+}
diff --git a/src/applications/releeph/differential/DifferentialReleephRequestFieldSpecification.php b/src/applications/releeph/differential/DifferentialReleephRequestFieldSpecification.php
new file mode 100644
index 0000000000..840241747a
--- /dev/null
+++ b/src/applications/releeph/differential/DifferentialReleephRequestFieldSpecification.php
@@ -0,0 +1,348 @@
+<?php
+
+/**
+ * This DifferentialFieldSpecification exists for two reason:
+ *
+ * 1: To parse "Releeph: picks RQ<nn>" headers in commits created by
+ * arc-releeph so that RQs committed by arc-releeph have real
+ * PhabricatorRepositoryCommits associated with them (instaed of just the SHA
+ * of the commit, as seen by the pusher).
+ *
+ * 2: If requestors want to commit directly to their release branch, they can
+ * use this header to (i) indicate on a differential revision that this
+ * differential revision is for the release branch, and (ii) when they land
+ * their diff on to the release branch manually, the ReleephRequest is
+ * automatically updated (instead of having to use the "Mark Manually Picked"
+ * button.)
+ *
+ */
+final class DifferentialReleephRequestFieldSpecification
+ extends DifferentialFieldSpecification {
+
+ const ACTION_PICKS = 'picks';
+ const ACTION_REVERTS = 'reverts';
+
+ private $releephAction;
+ private $releephPHIDs = array();
+
+ public function getStorageKey() {
+ return 'releeph:actions';
+ }
+
+ public function getValueForStorage() {
+ return json_encode(array(
+ 'releephAction' => $this->releephAction,
+ 'releephPHIDs' => $this->releephPHIDs,
+ ));
+ }
+
+ public function setValueFromStorage($json) {
+ if ($json) {
+ $dict = json_decode($json, true);
+ $this->releephAction = idx($dict, 'releephAction');
+ $this->releephPHIDs = idx($dict, 'releephPHIDs');
+ }
+ return $this;
+ }
+
+ public function shouldAppearOnRevisionView() {
+ return true;
+ }
+
+ public function renderLabelForRevisionView() {
+ return 'Releeph';
+ }
+
+ public function getRequiredHandlePHIDs() {
+ return mpull($this->loadReleephRequests(), 'getPHID');
+ }
+
+ public function renderValueForRevisionView() {
+ static $tense = array(
+ self::ACTION_PICKS => array(
+ 'future' => 'Will pick',
+ 'past' => 'Picked',
+ ),
+ self::ACTION_REVERTS => array(
+ 'future' => 'Will revert',
+ 'past' => 'Reverted',
+ ),
+ );
+
+ $releeph_requests = $this->loadReleephRequests();
+ if (!$releeph_requests) {
+ return null;
+ }
+
+ $status = $this->getRevision()->getStatus();
+ if ($status == ArcanistDifferentialRevisionStatus::CLOSED) {
+ $verb = $tense[$this->releephAction]['past'];
+ } else {
+ $verb = $tense[$this->releephAction]['future'];
+ }
+
+ $parts = hsprintf('%s...', $verb);
+ foreach ($releeph_requests as $releeph_request) {
+ $parts->appendHTML(phutil_tag('br'));
+ $parts->appendHTML(
+ $this->getHandle($releeph_request->getPHID())->renderLink());
+ }
+
+ return $parts;
+ }
+
+ public function shouldAppearOnCommitMessage() {
+ return true;
+ }
+
+ public function getCommitMessageKey() {
+ return 'releephActions';
+ }
+
+ public function setValueFromParsedCommitMessage($dict) {
+ $this->releephAction = $dict['releephAction'];
+ $this->releephPHIDs = $dict['releephPHIDs'];
+ return $this;
+ }
+
+ public function renderValueForCommitMessage($is_edit) {
+ $releeph_requests = $this->loadReleephRequests();
+ if (!$releeph_requests) {
+ return null;
+ }
+
+ $parts = array($this->releephAction);
+ foreach ($releeph_requests as $releeph_request) {
+ $parts[] = 'RQ'.$releeph_request->getID();
+ }
+
+ return implode(' ', $parts);
+ }
+
+ /**
+ * Releeph fields should look like:
+ *
+ * Releeph: picks RQ1 RQ2, RQ3
+ * Releeph: reverts RQ1
+ */
+ public function parseValueFromCommitMessage($value) {
+ /**
+ * Releeph commit messages look like this (but with more blank lines,
+ * omitted here):
+ *
+ * Make CaptainHaddock more reasonable
+ * Releeph: picks RQ1
+ * Requested By: edward
+ * Approved By: edward (requestor)
+ * Request Reason: x
+ * Summary: Make the Haddock implementation more reasonable.
+ * Test Plan: none
+ * Reviewers: user1
+ *
+ * Some of these fields are recognized by Differential (e.g. "Requested
+ * By"). They are folded up into the "Releeph" field, parsed by this
+ * class. As such $value includes more than just the first-line:
+ *
+ * "picks RQ1\n\nRequested By: edward\n\nApproved By: edward (requestor)"
+ *
+ * To hack around this, just consider the first line of $value when
+ * determining what Releeph actions the parsed commit is performing.
+ */
+ $first_line = head(array_filter(explode("\n", $value)));
+
+ $tokens = preg_split('/\s*,?\s+/', $first_line);
+ $raw_action = array_shift($tokens);
+ $action = strtolower($raw_action);
+
+ if (!$action) {
+ return null;
+ }
+
+ switch ($action) {
+ case self::ACTION_REVERTS:
+ case self::ACTION_PICKS:
+ break;
+
+ default:
+ throw new DifferentialFieldParseException(
+ "Commit message contains unknown Releeph action '{$raw_action}'!");
+ break;
+ }
+
+ $releeph_requests = array();
+ foreach ($tokens as $token) {
+ $match = array();
+ if (!preg_match('/^(?:RQ)?(\d+)$/i', $token, $match)) {
+ $label = $this->renderLabelForCommitMessage();
+ throw new DifferentialFieldParseException(
+ "Commit message contains unparseable ".
+ "Releeph request token '{$token}'!");
+ }
+
+ $id = (int) $match[1];
+ $releeph_request = id(new ReleephRequest())->load($id);
+
+ if (!$releeph_request) {
+ throw new DifferentialFieldParseException(
+ "Commit message references non existent releeph request: {$value}!");
+ }
+
+ $releeph_requests[] = $releeph_request;
+ }
+
+ if (count($releeph_requests) > 1) {
+ $rqs_seen = array();
+ $groups = array();
+ foreach ($releeph_requests as $releeph_request) {
+ $releeph_branch = $releeph_request->loadReleephBranch();
+ $branch_name = $releeph_branch->getName();
+ $rq_id = 'RQ'.$releeph_request->getID();
+
+ if (idx($rqs_seen, $rq_id)) {
+ throw new DifferentialFieldParseException(
+ "Commit message refers to {$rq_id} multiple times!");
+ }
+ $rqs_seen[$rq_id] = true;
+
+ if (!isset($groups[$branch_name])) {
+ $groups[$branch_name] = array();
+ }
+ $groups[$branch_name][] = $rq_id;
+ }
+
+ if (count($groups) > 1) {
+ $lists = array();
+ foreach ($groups as $branch_name => $rq_ids) {
+ $lists[] = implode(', ', $rq_ids).' in '.$branch_name;
+ }
+ throw new DifferentialFieldParseException(
+ "Commit message references multiple Releeph requests, ".
+ "but the requests are in different branches: ".
+ implode('; ', $lists));
+ }
+ }
+
+ $phids = mpull($releeph_requests, 'getPHID');
+
+ $data = array(
+ 'releephAction' => $action,
+ 'releephPHIDs' => $phids,
+ );
+ return $data;
+ }
+
+ public function renderLabelForCommitMessage() {
+ return 'Releeph';
+ }
+
+ public function shouldAppearOnCommitMessageTemplate() {
+ return false;
+ }
+
+ public function didParseCommit(PhabricatorRepository $repo,
+ PhabricatorRepositoryCommit $commit,
+ PhabricatorRepositoryCommitData $data) {
+
+ $releeph_requests = $this->loadReleephRequests();
+
+ if (!$releeph_requests) {
+ return;
+ }
+
+ $releeph_branch = head($releeph_requests)->loadReleephBranch();
+ if (!$this->isCommitOnBranch($repo, $commit, $releeph_branch)) {
+ return;
+ }
+
+ foreach ($releeph_requests as $releeph_request) {
+ if ($this->releephAction === self::ACTION_PICKS) {
+ $action = 'pick';
+ } else {
+ $action = 'revert';
+ }
+
+ $actor_phid = coalesce(
+ $data->getCommitDetail('committerPHID'),
+ $data->getCommitDetail('authorPHID'));
+
+ $actor = id(new PhabricatorUser())
+ ->loadOneWhere('phid = %s', $actor_phid);
+
+ id(new ReleephRequestEditor($releeph_request))
+ ->setActor($actor)
+ ->discoverCommit($action, $commit, $data);
+ }
+ }
+
+ private function loadReleephRequests() {
+ if (!$this->releephPHIDs) {
+ return array();
+ } else {
+ return id(new ReleephRequest())
+ ->loadAllWhere('phid IN (%Ls)', $this->releephPHIDs);
+ }
+ }
+
+ private function isCommitOnBranch(PhabricatorRepository $repo,
+ PhabricatorRepositoryCommit $commit,
+ ReleephBranch $releeph_branch) {
+
+ switch ($repo->getVersionControlSystem()) {
+ case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
+ list($output) = $repo->execxLocalCommand(
+ 'branch --all --no-color --contains %s',
+ $commit->getCommitIdentifier());
+
+ $remote_prefix = 'remotes/origin/';
+ $branches = array();
+ foreach (array_filter(explode("\n", $output)) as $line) {
+ $tokens = explode(' ', $line);
+ $ref = last($tokens);
+ if (strncmp($ref, $remote_prefix, strlen($remote_prefix)) === 0) {
+ $branch = substr($ref, strlen($remote_prefix));
+ $branches[$branch] = $branch;
+ }
+ }
+
+ return idx($branches, $releeph_branch->getName());
+ break;
+
+ case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
+ $change_query = DiffusionPathChangeQuery::newFromDiffusionRequest(
+ DiffusionRequest::newFromDictionary(array(
+ 'repository' => $repo,
+ 'commit' => $commit->getCommitIdentifier(),
+ )));
+ $path_changes = $change_query->loadChanges();
+ $commit_paths = mpull($path_changes, 'getPath');
+
+ $branch_path = $releeph_branch->getName();
+
+ $in_branch = array();
+ $ex_branch = array();
+ foreach ($commit_paths as $path) {
+ if (strncmp($path, $branch_path, strlen($branch_path)) === 0) {
+ $in_branch[] = $path;
+ } else {
+ $ex_branch[] = $path;
+ }
+ }
+
+ if ($in_branch && $ex_branch) {
+ $error = sprintf(
+ "CONFUSION: commit %s in %s contains %d path change(s) that were ".
+ "part of a Releeph branch, but also has %d path change(s) not ".
+ "part of a Releeph branch!",
+ $commit->getCommitIdentifier(),
+ $repo->getCallsign(),
+ count($in_branch),
+ count($ex_branch));
+ phlog($error);
+ }
+
+ return !empty($in_branch);
+ break;
+ }
+ }
+
+}
diff --git a/src/applications/releeph/differential/ReleephDifferentialRevisionDetailRenderer.php b/src/applications/releeph/differential/ReleephDifferentialRevisionDetailRenderer.php
new file mode 100644
index 0000000000..fbff6983f9
--- /dev/null
+++ b/src/applications/releeph/differential/ReleephDifferentialRevisionDetailRenderer.php
@@ -0,0 +1,39 @@
+<?php
+
+final class ReleephDifferentialRevisionDetailRenderer {
+
+ public static function generateActionLink(DifferentialRevision $revision,
+ DifferentialDiff $diff) {
+
+ $arc_project = $diff->loadArcanistProject(); // 93us
+ if (!$arc_project) {
+ return;
+ }
+
+ $releeph_projects = id(new ReleephProject())->loadAllWhere(
+ 'arcanistProjectID = %d AND isActive = 1',
+ $arc_project->getID());
+
+ if (!$releeph_projects) {
+ return;
+ }
+
+ $releeph_branches = id(new ReleephBranch())->loadAllWhere(
+ 'releephProjectID IN (%Ld) AND isActive = 1',
+ mpull($releeph_projects, 'getID'));
+
+ if (!$releeph_branches) {
+ return;
+ }
+
+ $uri = new PhutilURI(
+ '/releeph/request/differentialcreate/D'.$revision->getID());
+ return array(
+ 'name' => 'Releeph Request',
+ 'sigil' => 'workflow',
+ 'href' => $uri,
+ 'icon' => 'fork',
+ );
+ }
+
+}
diff --git a/src/applications/releeph/editor/ReleephBranchEditor.php b/src/applications/releeph/editor/ReleephBranchEditor.php
new file mode 100644
index 0000000000..d3f679502e
--- /dev/null
+++ b/src/applications/releeph/editor/ReleephBranchEditor.php
@@ -0,0 +1,106 @@
+<?php
+
+final class ReleephBranchEditor extends PhabricatorEditor {
+
+ private $releephProject;
+ private $releephBranch;
+
+ public function setReleephProject(ReleephProject $rp) {
+ $this->releephProject = $rp;
+ return $this;
+ }
+
+ public function setReleephBranch(ReleephBranch $branch) {
+ $this->releephBranch = $branch;
+ return $this;
+ }
+
+ public function newBranchFromCommit(PhabricatorRepositoryCommit $cut_point,
+ $branch_date,
+ $symbolic_name = null) {
+
+ $template = $this->releephProject->getDetail('branchTemplate');
+ if (!$template) {
+ $template = ReleephBranchTemplate::getRequiredDefaultTemplate();
+ }
+
+ $cut_point_handle = head(
+ id(new PhabricatorObjectHandleData(array($cut_point->getPHID())))
+ // We'll assume that whoever found the $cut_point has passed privacy
+ // checks.
+ ->setViewer($this->requireActor())
+ ->loadHandles());
+
+ list($name, $errors) = id(new ReleephBranchTemplate())
+ ->setCommitHandle($cut_point_handle)
+ ->setBranchDate($branch_date)
+ ->setReleephProjectName($this->releephProject->getName())
+ ->interpolate($template);
+
+ $basename = last(explode('/', $name));
+
+ $table = id(new ReleephBranch());
+ $transaction = $table->openTransaction();
+ $branch = id(new ReleephBranch())
+ ->setName($name)
+ ->setBasename($basename)
+ ->setReleephProjectID($this->releephProject->getID())
+ ->setCreatedByUserPHID($this->requireActor()->getPHID())
+ ->setCutPointCommitIdentifier($cut_point->getCommitIdentifier())
+ ->setCutPointCommitPHID($cut_point->getPHID())
+ ->setIsActive(1)
+ ->setDetail('branchDate', $branch_date)
+ ->save();
+
+ /**
+ * Steal the symbolic name from any other branch that has it (in this
+ * project).
+ */
+ if ($symbolic_name) {
+ $others = id(new ReleephBranch())->loadAllWhere(
+ 'releephProjectID = %d',
+ $this->releephProject->getID());
+ foreach ($others as $other) {
+ if ($other->getSymbolicName() == $symbolic_name) {
+ $other
+ ->setSymbolicName(null)
+ ->save();
+ }
+ }
+ $branch
+ ->setSymbolicName($symbolic_name)
+ ->save();
+ }
+
+ id(new ReleephEvent())
+ ->setType(ReleephEvent::TYPE_BRANCH_CREATE)
+ ->setActorPHID($this->requireActor()->getPHID())
+ ->setReleephProjectID($this->releephProject->getID())
+ ->setReleephBranchID($branch->getID())
+ ->save();
+
+ $table->saveTransaction();
+ return $branch;
+ }
+
+ // aka "close" and "reopen"
+ public function changeBranchAccess($is_active) {
+ $branch = $this->releephBranch;
+ $branch->openTransaction();
+
+ $branch
+ ->setIsActive((int)$is_active)
+ ->save();
+
+ id(new ReleephEvent())
+ ->setType(ReleephEvent::TYPE_BRANCH_ACCESS)
+ ->setActorPHID($this->requireActor()->getPHID())
+ ->setReleephProjectID($branch->getReleephProjectID())
+ ->setReleephBranchID($branch->getID())
+ ->setDetail('isActive', $is_active)
+ ->save();
+
+ $branch->saveTransaction();
+ }
+
+}
diff --git a/src/applications/releeph/editor/ReleephRequestEditor.php b/src/applications/releeph/editor/ReleephRequestEditor.php
new file mode 100644
index 0000000000..8cb0945e2f
--- /dev/null
+++ b/src/applications/releeph/editor/ReleephRequestEditor.php
@@ -0,0 +1,408 @@
+<?php
+
+/**
+ * Provide methods for the common ways of creating and mutating a
+ * ReleephRequest, sending email when something interesting happens.
+ *
+ * This class generates ReleephRequestEvents, and each type of event
+ * (ReleephRequestEvent::TYPE_*) corresponds to one of the editor methods.
+ *
+ * The editor methods (except for create() use newEvent() and commit() to save
+ * some code duplication.
+ */
+final class ReleephRequestEditor extends PhabricatorEditor {
+
+ private $releephRequest;
+ private $event;
+ private $silentUpdate;
+
+ public function __construct(ReleephRequest $rq) {
+ $this->releephRequest = $rq;
+ }
+
+ public function setSilentUpdate($silent) {
+ $this->silentUpdate = $silent;
+ return $this;
+ }
+
+
+/* -( ReleephRequest edit methods )---------------------------------------- */
+
+ /**
+ * Request a PhabricatorRepositoryCommit to be committed to the given
+ * ReleephBranch.
+ */
+ public function create(PhabricatorRepositoryCommit $commit,
+ ReleephBranch $branch) {
+
+ // We can't use newEvent() / commit() abstractions, so do what those
+ // helpers do manually.
+ $requestor = $this->requireActor();
+
+ $rq = $this->releephRequest;
+ $rq->openTransaction();
+
+ $rq
+ ->setBranchID($branch->getID())
+ ->setRequestCommitIdentifier($commit->getCommitIdentifier())
+ ->setRequestCommitPHID($commit->getPHID())
+ ->setRequestCommitOrdinal($commit->getID())
+ ->setInBranch(0)
+ ->setRequestUserPHID($requestor->getPHID())
+ ->setUserIntent($requestor, ReleephRequest::INTENT_WANT)
+ ->save();
+
+ $event = id(new ReleephRequestEvent())
+ ->setType(ReleephRequestEvent::TYPE_CREATE)
+ ->setActorPHID($requestor->getPHID())
+ ->setStatusBefore(null)
+ ->setStatusAfter($rq->getStatus())
+ ->setReleephRequestID($rq->getID())
+ ->setDetail('commitPHID', $commit->getPHID())
+ ->save();
+
+ $rq->saveTransaction();
+
+ // Mail
+ if (!$this->silentUpdate) {
+ $project = $this->releephRequest->loadReleephProject();
+ $mail = id(new ReleephRequestMail())
+ ->setReleephRequest($this->releephRequest)
+ ->setReleephProject($project)
+ ->setEvents(array($event))
+ ->setSenderAndRecipientPHID($requestor->getPHID())
+ ->addTos(ReleephRequestMail::ENT_ALL_PUSHERS)
+ ->addCCs(ReleephRequestMail::ENT_REQUESTOR)
+ ->send();
+ }
+ }
+
+ /**
+ * Record whether the PhabricatorUser wants or passes on this request.
+ */
+ public function changeUserIntent(PhabricatorUser $user, $intent) {
+ $project = $this->releephRequest->loadReleephProject();
+ $is_pusher = $project->isPusher($user);
+
+ $event = $this->newEvent()
+ ->setType(ReleephRequestEvent::TYPE_USER_INTENT)
+ ->setDetail('userPHID', $user->getPHID())
+ ->setDetail('wasPusher', $is_pusher)
+ ->setDetail('newIntent', $intent);
+
+ $this->releephRequest
+ ->setUserIntent($user, $intent);
+
+ $this->commit();
+
+ // Mail if this is 'interesting'
+ if (!$this->silentUpdate &&
+ $event->getStatusBefore() != $event->getStatusAfter()) {
+
+ $project = $this->releephRequest->loadReleephProject();
+ $mail = id(new ReleephRequestMail())
+ ->setReleephRequest($this->releephRequest)
+ ->setReleephProject($project)
+ ->setEvents(array($event))
+ ->setSenderAndRecipientPHID($this->requireActor()->getPHID())
+ ->addTos(ReleephRequestMail::ENT_REQUESTOR)
+ ->addCCs(ReleephRequestMail::ENT_INTERESTED_PUSHERS)
+ ->send();
+ }
+ }
+
+ /**
+ * Record the results of someone trying to pick or revert a request in their
+ * local repository, to give advance warning that something doesn't pick or
+ * revert cleanly.
+ */
+ public function changePickStatus($pick_status, $dry_run, $details) {
+ $event = $this->newEvent()
+ ->setType(ReleephRequestEvent::TYPE_PICK_STATUS)
+ ->setDetail('newPickStatus', $pick_status)
+ ->setDetail('commitDetails', $details);
+ $this->releephRequest->setPickStatus($pick_status);
+ $this->commit();
+
+ // Failures should generate an email
+ if (!$this->silentUpdate &&
+ !$dry_run &&
+ ($pick_status == ReleephRequest::PICK_FAILED ||
+ $pick_status == ReleephRequest::REVERT_FAILED)) {
+
+ $project = $this->releephRequest->loadReleephProject();
+ $mail = id(new ReleephRequestMail())
+ ->setReleephRequest($this->releephRequest)
+ ->setReleephProject($project)
+ ->setEvents(array($event))
+ ->setSenderAndRecipientPHID($this->requireActor()->getPHID())
+ ->addTos(ReleephRequestMail::ENT_REQUESTOR)
+ ->addCCs(ReleephRequestMail::ENT_ACTORS)
+ ->addCCs(ReleephRequestMail::ENT_INTERESTED_PUSHERS)
+ ->send();
+ }
+ }
+
+ /**
+ * Record that a request was committed locally, and is about to be pushed to
+ * the remote repository.
+ *
+ * This lets us mark a ReleephRequest as being in a branch in real time so
+ * that no one else tries to pick it.
+ *
+ * When the daemons discover this commit in the repository with
+ * DifferentialReleephRequestFieldSpecification, we'll be able to recrod the
+ * commit's PHID as well. That process is slow though, and
+ * we don't want to wait a whole minute before marking something as cleanly
+ * picked or reverted.
+ */
+ public function recordSuccessfulCommit($action, $new_commit_id) {
+ $table = $this->releephRequest;
+ $table->openTransaction();
+
+ $actor = $this->requireActor();
+
+ $event = id(new ReleephRequestEvent())
+ ->setReleephRequestID($this->releephRequest->getID())
+ ->setActorPHID($actor->getPHID())
+ ->setType(ReleephRequestEvent::TYPE_COMMIT)
+ ->setDetail('action', $action)
+ ->setDetail('newCommitIdentifier', $new_commit_id)
+ ->save();
+
+ switch ($action) {
+ case 'pick':
+ $this->releephRequest
+ ->setInBranch(1)
+ ->setPickStatus(ReleephRequest::PICK_OK)
+ ->setCommitIdentifier($new_commit_id)
+ ->setCommitPHID(null)
+ ->setCommittedByUserPHID($actor->getPHID())
+ ->save();
+ break;
+
+ case 'revert':
+ $this->releephRequest
+ ->setInBranch(0)
+ ->setPickStatus(ReleephRequest::REVERT_OK)
+ ->setCommitIdentifier(null)
+ ->setCommitPHID(null)
+ ->setCommittedByUserPHID(null)
+ ->save();
+ break;
+
+ default:
+ $table->killTransaction();
+ throw new Exception("Unknown action {$action}!");
+ break;
+ }
+
+ $table->saveTransaction();
+
+ // Don't spam people about local commits -- we'll do that with
+ // discoverCommit() instead!
+ }
+
+ /**
+ * Mark this request as picked or reverted based on discovering it in the
+ * branch. We have a PhabricatorRepositoryCommit, so we're able to
+ * setCommitPHID on the ReleephRequest (unlike recordSuccessfulCommit()).
+ */
+ public function discoverCommit(
+ $action,
+ PhabricatorRepositoryCommit $commit,
+ PhabricatorRepositoryCommitData $data) {
+
+ $table = $this->releephRequest;
+ $table->openTransaction();
+ $table->beginWriteLocking();
+
+ $past_events = id(new ReleephRequestEvent())->loadAllWhere(
+ 'releephRequestID = %d AND type = %s',
+ $this->releephRequest->getID(),
+ ReleephRequestEvent::TYPE_DISCOVERY);
+
+ foreach ($past_events as $past_event) {
+ if ($past_event->getDetail('newCommitIdentifier')
+ == $commit->getCommitIdentifier()) {
+
+ // Avoid re-discovery if reparsing!
+ $table->endWriteLocking();
+ $table->killTransaction();
+ return;
+ }
+ }
+
+ $actor = $this->requireActor();
+
+ $event = id(new ReleephRequestEvent())
+ ->setReleephRequestID($this->releephRequest->getID())
+ ->setActorPHID($actor->getPHID())
+ ->setType(ReleephRequestEvent::TYPE_DISCOVERY)
+ ->setDateCreated($commit->getEpoch())
+ ->setDetail('action', $action)
+ ->setDetail('newCommitIdentifier', $commit->getCommitIdentifier())
+ ->setDetail('newCommitPHID', $commit->getPHID())
+ ->setDetail('authorPHID', $data->getCommitDetail('authorPHID'))
+ ->setDetail('committerPHID', $data->getCommitDetail('committerPHID'))
+ ->save();
+
+ switch ($action) {
+ case 'pick':
+ $this->releephRequest
+ ->setInBranch(1)
+ ->setPickStatus(ReleephRequest::PICK_OK)
+ ->setCommitIdentifier($commit->getCommitIdentifier())
+ ->setCommitPHID($commit->getPHID())
+ ->setCommittedByUserPHID($actor->getPHID())
+ ->save();
+ break;
+
+ case 'revert':
+ $this->releephRequest
+ ->setInBranch(0)
+ ->setPickStatus(ReleephRequest::REVERT_OK)
+ ->setCommitIdentifier(null)
+ ->setCommitPHID(null)
+ ->setCommittedByUserPHID(null)
+ ->save();
+ break;
+
+ default:
+ $table->killTransaction();
+ throw new Exception("Unknown action {$action}!");
+ break;
+ }
+
+ $table->endWriteLocking();
+ $table->saveTransaction();
+
+ // Mail
+ if (!$this->silentUpdate) {
+ $project = $this->releephRequest->loadReleephProject();
+ $mail = id(new ReleephRequestMail())
+ ->setReleephRequest($this->releephRequest)
+ ->setReleephProject($project)
+ ->setEvents(array($event))
+ ->setSenderAndRecipientPHID($this->requireActor()->getPHID())
+ ->addTos(ReleephRequestMail::ENT_REQUESTOR)
+ ->addCCs(ReleephRequestMail::ENT_ACTORS)
+ ->addCCs(ReleephRequestMail::ENT_INTERESTED_PUSHERS)
+ ->send();
+ }
+ }
+
+ public function addComment($comment) {
+ $event = $this->newEvent()
+ ->setType(ReleephRequestEvent::TYPE_COMMENT)
+ ->setDetail('comment', $comment);
+ $this->commit();
+
+ // Mail
+ if (!$this->silentUpdate) {
+ $project = $this->releephRequest->loadReleephProject();
+ $mail = id(new ReleephRequestMail())
+ ->setReleephRequest($this->releephRequest)
+ ->setReleephProject($project)
+ ->setEvents(array($event))
+ ->setSenderAndRecipientPHID($this->requireActor()->getPHID())
+ ->addTos(ReleephRequestMail::ENT_REQUESTOR)
+ ->addCCs(ReleephRequestMail::ENT_ACTORS)
+ ->addCCs(ReleephRequestMail::ENT_INTERESTED_PUSHERS)
+ ->send();
+ }
+ }
+
+ public function markManuallyActioned($action) {
+ $event = $this->newEvent()
+ ->setType(ReleephRequestEvent::TYPE_MANUAL_ACTION)
+ ->setDetail('action', $action);
+
+ $actor = $this->requireActor();
+ $project = $this->releephRequest->loadReleephProject();
+ $requestor_phid = $this->releephRequest->getRequestUserPHID();
+ if (!$project->isPusher($actor) &&
+ $actor->getPHID() !== $requestor_phid) {
+
+ throw new Exception(
+ "Only pushers or requestors can mark requests as ".
+ "manually picked or reverted!");
+ }
+
+ switch ($action) {
+ case 'pick':
+ $in_branch = true;
+ $intent = ReleephRequest::INTENT_WANT;
+ break;
+
+ case 'revert':
+ $in_branch = false;
+ $intent = ReleephRequest::INTENT_PASS;
+ break;
+
+ default:
+ throw new Exception("Unknown action {$action}!");
+ break;
+ }
+
+ $this->releephRequest
+ ->setInBranch((int)$in_branch)
+ ->setUserIntent($this->getActor(), $intent);
+
+ $this->commit();
+
+ // Mail
+ if (!$this->silentUpdate) {
+ $project = $this->releephRequest->loadReleephProject();
+ $mail = id(new ReleephRequestMail())
+ ->setReleephRequest($this->releephRequest)
+ ->setReleephProject($project)
+ ->setEvents(array($event))
+ ->setSenderAndRecipientPHID($this->requireActor()->getPHID())
+ ->addTos(ReleephRequestMail::ENT_REQUESTOR)
+ ->addCCs(ReleephRequestMail::ENT_INTERESTED_PUSHERS)
+ ->send();
+ }
+ }
+
+/* -( Implementation )----------------------------------------------------- */
+
+ /**
+ * Create and return a new ReleephRequestEvent bound to the editor's
+ * ReleephRequest, inside a transaction.
+ *
+ * When you call commit(), the event and this editor's ReleephRequest (along
+ * with any changes you made to the ReleephRequest) are saved and the
+ * transaction committed.
+ */
+ private function newEvent() {
+ $actor = $this->requireActor();
+
+ if ($this->event) {
+ throw new Exception("You have already called newEvent()!");
+ }
+ $rq = $this->releephRequest;
+ $rq->openTransaction();
+
+ $this->event = id(new ReleephRequestEvent())
+ ->setReleephRequestID($rq->getID())
+ ->setActorPHID($actor->getPHID())
+ ->setStatusBefore($rq->getStatus());
+
+ return $this->event;
+ }
+
+ private function commit() {
+ if (!$this->event) {
+ throw new Exception("You must call newEvent first!");
+ }
+ $rq = $this->releephRequest;
+ $this->event
+ ->setStatusAfter($rq->getStatus())
+ ->save();
+ $rq->save();
+ $rq->saveTransaction();
+ $this->event = null;
+ }
+
+}
diff --git a/src/applications/releeph/editor/mail/ReleephRequestMail.php b/src/applications/releeph/editor/mail/ReleephRequestMail.php
new file mode 100644
index 0000000000..a06f6f3342
--- /dev/null
+++ b/src/applications/releeph/editor/mail/ReleephRequestMail.php
@@ -0,0 +1,213 @@
+<?php
+
+/**
+ * Build an email that renders a group of events with and appends some standard
+ * Releeph things (a URI for this request, and this branch).
+ *
+ * Also includes some helper stuff for adding groups of people to the To: and
+ * Cc: headers.
+ */
+final class ReleephRequestMail {
+
+ const ENT_REQUESTOR = 'requestor';
+ const ENT_DIFF = 'diff';
+ const ENT_ALL_PUSHERS = 'pushers';
+ const ENT_ACTORS = 'actors';
+ const ENT_INTERESTED_PUSHERS = 'interested-pushers';
+
+ private $sender;
+ private $tos = array();
+ private $ccs = array();
+ private $events;
+ private $releephRequest;
+ private $releephProject;
+
+ public function setReleephRequest(ReleephRequest $rq) {
+ $this->releephRequest = $rq;
+ return $this;
+ }
+
+ public function setReleephProject(ReleephProject $rp) {
+ $this->releephProject = $rp;
+ return $this;
+ }
+
+ public function setEvents(array $events) {
+ assert_instances_of($events, 'ReleephRequestEvent');
+ $this->events = $events;
+ return $this;
+ }
+
+ public function setSenderAndRecipientPHID($sender_phid) {
+ $this->sender = $sender_phid;
+ $this->tos[] = $sender_phid;
+ return $this;
+ }
+
+ public function addTos($entity) {
+ $this->tos = array_merge(
+ $this->tos,
+ $this->getEntityPHIDs($entity));
+ return $this;
+ }
+
+ public function addCcs($entity) {
+ $this->ccs = array_merge(
+ $this->tos,
+ $this->getEntityPHIDs($entity));
+ return $this;
+ }
+
+ public function send() {
+ $this->buildMail()->save();
+ }
+
+ public function buildMail() {
+ return id(new PhabricatorMetaMTAMail())
+ ->setSubject($this->renderSubject())
+ ->setBody($this->buildBody()->render())
+ ->setFrom($this->sender)
+ ->addTos($this->tos)
+ ->addCCs($this->ccs);
+ }
+
+ private function getEntityPHIDs($entity) {
+ $phids = array();
+ switch ($entity) {
+ // The requestor
+ case self::ENT_REQUESTOR:
+ $phids[] = $this->releephRequest->getRequestUserPHID();
+ break;
+
+ // People on the original diff
+ case self::ENT_DIFF:
+ $commit = $this->releephRequest->loadPhabricatorRepositoryCommit();
+ $commit_data = $commit->loadCommitData();
+ if ($commit_data) {
+ $phids[] = $commit_data->getCommitDetail('reviewerPHID');
+ $phids[] = $commit_data->getCommitDetail('authorPHID');
+ }
+ break;
+
+ // All pushers for this project
+ case self::ENT_ALL_PUSHERS:
+ $phids = array_merge(
+ $phids,
+ $this->releephProject->getPushers());
+ break;
+
+ // Pushers who have explicitly wanted or passed on this request
+ case self::ENT_INTERESTED_PUSHERS:
+ $all_pushers = $this->releephProject->getPushers();
+ $intents = $this->releephRequest->getUserIntents();
+ foreach ($all_pushers as $pusher) {
+ if (idx($intents, $pusher)) {
+ $phids[] = $pusher;
+ }
+ }
+ break;
+
+ // Anyone who created our list of events
+ case self::ENT_ACTORS:
+ $phids = array_merge(
+ $phids,
+ mpull($this->events, 'getActorPHID'));
+ break;
+
+ default:
+ throw new Exception(
+ "Unknown entity type {$entity}!");
+ break;
+ }
+
+ return array_filter($phids);
+ }
+
+ private function buildBody() {
+ $body = new PhabricatorMetaMTAMailBody();
+ $rq = $this->releephRequest;
+
+ // Events and comments
+ $phids = array(
+ $rq->getPHID(),
+ );
+ foreach ($this->events as $event) {
+ $phids = array_merge($phids, $event->extractPHIDs());
+ }
+ $handles = id(new PhabricatorObjectHandleData($phids))
+ // By the time we're generating email, we can assume that whichever
+ // entitties are receving the email are authorized to see the loaded
+ // handles!
+ ->setViewer(PhabricatorUser::getOmnipotentUser())
+ ->loadHandles();
+
+ $raw_events = id(new ReleephRequestEventListView())
+ ->setUser(PhabricatorUser::getOmnipotentUser())
+ ->setHandles($handles)
+ ->setEvents($this->events)
+ ->renderForEmail();
+
+ $body->addRawSection($raw_events);
+
+ $project = $rq->loadReleephProject();
+ $branch = $rq->loadReleephBranch();
+
+ /**
+ * If any of the events we are emailing about were TYPE_PICK_STATUS where
+ * the newPickStatus was a pick failure (and/or a revert failure?), include
+ * pick failure instructions.
+ */
+ $pick_failure_events = array();
+ foreach ($this->events as $event) {
+ if ($event->getType() == ReleephRequestEvent::TYPE_PICK_STATUS &&
+ $event->getDetail('newPickStatus') == ReleephRequest::PICK_FAILED) {
+
+ $pick_failure_events[] = $event;
+ }
+ }
+
+ if ($pick_failure_events) {
+ $instructions = $project->getDetail('pick_failure_instructions');
+ if ($instructions) {
+ $body->addTextSection('PICK FAILURE INSTRUCTIONS', $instructions);
+ }
+ }
+
+ // Common stuff at the end
+ $body->addTextSection(
+ 'RELEEPH REQUEST',
+ $handles[$rq->getPHID()]->getFullName()."\n".
+ PhabricatorEnv::getProductionURI('/RQ'.$rq->getID()));
+
+ $project_and_branch = sprintf(
+ '%s - %s',
+ $project->getName(),
+ $branch->getDisplayNameWithDetail());
+
+ $body->addTextSection(
+ 'RELEEPH BRANCH',
+ $project_and_branch."\n".
+ $branch->getURI());
+
+ // But verbose stuff at the *very* end!
+ foreach ($pick_failure_events as $event) {
+ $failure_details = $event->getDetail('commitDetails');
+ if ($failure_details) {
+ $body->addRawSection('PICK FAILURE DETAILS');
+ foreach ($failure_details as $heading => $data) {
+ $body->addTextSection($heading, $data);
+ }
+ }
+ }
+
+ return $body;
+ }
+
+ private function renderSubject() {
+ $rq = $this->releephRequest;
+ $id = $rq->getID();
+ $summary = $rq->getSummaryForDisplay();
+ return "RQ{$id}: {$summary}";
+ }
+
+}
diff --git a/src/applications/releeph/field/exception/ReleephFieldParseException.php b/src/applications/releeph/field/exception/ReleephFieldParseException.php
new file mode 100644
index 0000000000..fcb513df13
--- /dev/null
+++ b/src/applications/releeph/field/exception/ReleephFieldParseException.php
@@ -0,0 +1,12 @@
+<?php
+
+final class ReleephFieldParseException extends Exception {
+
+ public function __construct(ReleephFieldSpecification $field,
+ $message) {
+
+ $name = $field->getName();
+ parent::__construct("{$name}: {$message}");
+ }
+
+}
diff --git a/src/applications/releeph/field/exception/ReleephFieldSpecificationIncompleteException.php b/src/applications/releeph/field/exception/ReleephFieldSpecificationIncompleteException.php
new file mode 100644
index 0000000000..6e67dcf350
--- /dev/null
+++ b/src/applications/releeph/field/exception/ReleephFieldSpecificationIncompleteException.php
@@ -0,0 +1,11 @@
+<?php
+
+final class ReleephFieldSpecificationIncompleteException extends Exception {
+
+ public function __construct(ReleephFieldSpecification $field) {
+ $class = get_class($field);
+ parent::__construct(
+ "Releeph field class {$class} is incompletely implemented.");
+ }
+
+}
diff --git a/src/applications/releeph/field/selector/ReleephDefaultFieldSelector.php b/src/applications/releeph/field/selector/ReleephDefaultFieldSelector.php
new file mode 100644
index 0000000000..26506ef2e9
--- /dev/null
+++ b/src/applications/releeph/field/selector/ReleephDefaultFieldSelector.php
@@ -0,0 +1,73 @@
+<?php
+
+final class ReleephDefaultFieldSelector extends ReleephFieldSelector {
+
+ public function getFieldSpecifications() {
+ return array(
+ new ReleephCommitMessageFieldSpecification(),
+ new ReleephSummaryFieldSpecification(),
+ new ReleephReasonFieldSpecification(),
+ new ReleephAuthorFieldSpecification(),
+ new ReleephRevisionFieldSpecification(),
+ new ReleephRequestorFieldSpecification(),
+ new ReleephSeverityFieldSpecification(),
+ new ReleephOriginalCommitFieldSpecification(),
+ new ReleephDiffMessageFieldSpecification(),
+ new ReleephStatusFieldSpecification(),
+ new ReleephIntentFieldSpecification(),
+ new ReleephBranchCommitFieldSpecification(),
+ new ReleephDiffSizeFieldSpecification(),
+ new ReleephDiffChurnFieldSpecification(),
+ );
+ }
+
+ public function arrangeFieldsForHeaderView(array $fields) {
+ return array(
+ // Top group
+ array(
+ 'left' => self::selectFields($fields, array(
+ 'ReleephAuthorFieldSpecification',
+ 'ReleephRevisionFieldSpecification',
+ 'ReleephOriginalCommitFieldSpecification',
+ 'ReleephDiffSizeFieldSpecification',
+ 'ReleephDiffChurnFieldSpecification',
+ )),
+ 'right' => self::selectFields($fields, array(
+ 'ReleephRequestorFieldSpecification',
+ 'ReleephSeverityFieldSpecification',
+ 'ReleephStatusFieldSpecification',
+ 'ReleephIntentFieldSpecification',
+ 'ReleephBranchCommitFieldSpecification',
+ ))
+ ),
+
+ // Bottom group
+ array(
+ 'left' => self::selectFields($fields, array(
+ 'ReleephDiffMessageFieldSpecification',
+ )),
+ 'right' => self::selectFields($fields, array(
+ 'ReleephReasonFieldSpecification',
+ ))
+ )
+ );
+ }
+
+ public function arrangeFieldsForSelectForm(array $fields) {
+ self::selectFields($fields, array(
+ 'ReleephStatusFieldSpecification',
+ 'ReleephSeverityFieldSpecification',
+ 'ReleephRequestorFieldSpecification',
+ ));
+ }
+
+ public function sortFieldsForCommitMessage(array $fields) {
+ self::selectFields($fields, array(
+ 'ReleephCommitMessageFieldSpecification',
+ 'ReleephRequestorFieldSpecification',
+ 'ReleephIntentFieldSpecification',
+ 'ReleephReasonFieldSpecification',
+ ));
+ }
+
+}
diff --git a/src/applications/releeph/field/selector/ReleephFieldSelector.php b/src/applications/releeph/field/selector/ReleephFieldSelector.php
new file mode 100644
index 0000000000..3c7afe90de
--- /dev/null
+++ b/src/applications/releeph/field/selector/ReleephFieldSelector.php
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * Control the rendering of ReleephRequestHeaderView, and the layout of the
+ * ReleephRequest search dialog (in ReleephBranchViewController.)
+ */
+abstract class ReleephFieldSelector {
+
+ final public function __construct() {
+ // <empty>
+ }
+
+ abstract public function getFieldSpecifications();
+
+ abstract public function arrangeFieldsForHeaderView(array $fields);
+
+ abstract public function arrangeFieldsForSelectForm(array $fields);
+
+ public function sortFieldsForCommitMessage(array $fields) {
+ assert_instances_of($fields, 'ReleephFieldSpecification');
+ return $fields;
+ }
+
+ protected static function selectFields(array $fields, array $classes) {
+ assert_instances_of($fields, 'ReleephFieldSpecification');
+
+ $map = array();
+ foreach ($fields as $field) {
+ $map[get_class($field)] = $field;
+ }
+
+ $result = array();
+ foreach ($classes as $class) {
+ $field = idx($map, $class);
+ if (!$field) {
+ throw new Exception(
+ "Tried to select a in instance of '{$class}' but that field ".
+ "is not configured for this project!");
+ }
+
+ if (idx($result, $class)) {
+ throw new Exception(
+ "You have asked to select the field '{$class}' ".
+ "more than once!");
+ }
+
+ $result[$class] = $field;
+ }
+
+ return $result;
+ }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephAuthorFieldSpecification.php b/src/applications/releeph/field/specification/ReleephAuthorFieldSpecification.php
new file mode 100644
index 0000000000..610ecb2d5c
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephAuthorFieldSpecification.php
@@ -0,0 +1,39 @@
+<?php
+
+final class ReleephAuthorFieldSpecification
+ extends ReleephFieldSpecification {
+
+ private static $authorMap = array();
+
+ public function bulkLoad(array $releeph_requests) {
+ foreach ($releeph_requests as $releeph_request) {
+ $commit = $releeph_request->loadPhabricatorRepositoryCommit();
+ if ($commit) {
+ $author_phid = $commit->getAuthorPHID();
+ self::$authorMap[$releeph_request->getPHID()] = $author_phid;
+ }
+ }
+
+ ReleephUserView::getNewInstance()
+ ->setUser($this->getUser())
+ ->setReleephProject($this->getReleephProject())
+ ->load(self::$authorMap);
+ }
+
+ public function getName() {
+ return 'Author';
+ }
+
+ public function renderValueForHeaderView() {
+ $rr = $this->getReleephRequest();
+ $author_phid = idx(self::$authorMap, $rr->getPHID());
+ if ($author_phid) {
+ return ReleephUserView::getNewInstance()
+ ->setRenderUserPHID($author_phid)
+ ->render();
+ } else {
+ return 'Unknown Author';
+ }
+ }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephBranchCommitFieldSpecification.php b/src/applications/releeph/field/specification/ReleephBranchCommitFieldSpecification.php
new file mode 100644
index 0000000000..4aa2c93f25
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephBranchCommitFieldSpecification.php
@@ -0,0 +1,30 @@
+<?php
+
+final class ReleephBranchCommitFieldSpecification
+ extends ReleephFieldSpecification {
+
+ public function getName() {
+ return 'Commit';
+ }
+
+ public function renderValueForHeaderView() {
+ $rr = $this->getReleephRequest();
+ if (!$rr->getInBranch()) {
+ return null;
+ }
+
+ $c_phid = $rr->getCommitPHID();
+ $c_id = $rr->getCommitIdentifier();
+
+ if ($c_phid) {
+ $handles = $rr->getHandles();
+ $val = $handles[$c_phid]->renderLink();
+ } else if ($c_id) {
+ $val = $c_id;
+ } else {
+ $val = '???';
+ }
+ return $val;
+ }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephCommitMessageFieldSpecification.php b/src/applications/releeph/field/specification/ReleephCommitMessageFieldSpecification.php
new file mode 100644
index 0000000000..3ad528f3c0
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephCommitMessageFieldSpecification.php
@@ -0,0 +1,46 @@
+<?php
+
+final class ReleephCommitMessageFieldSpecification
+ extends ReleephFieldSpecification {
+
+ public function getName() {
+ return '__only_for_commit_message!';
+ }
+
+ public function shouldAppearOnCommitMessage() {
+ return true;
+ }
+
+ public function renderLabelForCommitMessage() {
+ return $this->renderCommonLabel();
+ }
+
+ public function renderValueForCommitMessage() {
+ return $this->renderCommonValue(
+ DifferentialReleephRequestFieldSpecification::ACTION_PICKS);
+ }
+
+ public function shouldAppearOnRevertMessage() {
+ return true;
+ }
+
+ public function renderLabelForRevertMessage() {
+ return $this->renderCommonLabel();
+ }
+
+ public function renderValueForRevertMessage() {
+ return $this->renderCommonValue(
+ DifferentialReleephRequestFieldSpecification::ACTION_REVERTS);
+ }
+
+ private function renderCommonLabel() {
+ return id(new DifferentialReleephRequestFieldSpecification())
+ ->renderLabelForCommitMessage();
+ }
+
+ private function renderCommonValue($action) {
+ $rq = 'RQ'.$this->getReleephRequest()->getID();
+ return "{$action} {$rq}";
+ }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephDiffChurnFieldSpecification.php b/src/applications/releeph/field/specification/ReleephDiffChurnFieldSpecification.php
new file mode 100644
index 0000000000..b8f4310a37
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephDiffChurnFieldSpecification.php
@@ -0,0 +1,77 @@
+<?php
+
+final class ReleephDiffChurnFieldSpecification
+ extends ReleephFieldSpecification {
+
+ const REJECTIONS_WEIGHT = 30;
+ const COMMENTS_WEIGHT = 7;
+ const UPDATES_WEIGHT = 10;
+ const MAX_POINTS = 100;
+
+ public function getName() {
+ return 'Churn';
+ }
+
+ public function renderValueForHeaderView() {
+ $diff_rev = $this->getReleephRequest()->loadDifferentialRevision();
+ if (!$diff_rev) {
+ return null;
+ }
+
+ $diff_rev = $this->getReleephRequest()->loadDifferentialRevision();
+ $comments = $diff_rev->loadRelatives(
+ new DifferentialComment(),
+ 'revisionID');
+
+ $counts = array();
+ foreach ($comments as $comment) {
+ $action = $comment->getAction();
+ if (!isset($counts[$action])) {
+ $counts[$action] = 0;
+ }
+ $counts[$action] += 1;
+ }
+
+ // 'none' action just means a plain comment
+ $comments = idx($counts, 'none', 0);
+ $rejections = idx($counts, 'reject', 0);
+ $updates = idx($counts, 'update', 0);
+
+ $points =
+ self::REJECTIONS_WEIGHT * $rejections +
+ self::COMMENTS_WEIGHT * $comments +
+ self::UPDATES_WEIGHT * $updates;
+
+ if ($points === 0) {
+ $points = 0.15 * self::MAX_POINTS;
+ $blurb = 'Silent diff';
+ } else {
+ $parts = array();
+ if ($rejections) {
+ $parts[] = pht('%d rejection(s)', $rejections);
+ }
+ if ($comments) {
+ $parts[] = pht('%d comment(s)', $comments);
+ }
+ if ($updates) {
+ $parts[] = pht('%d update(s)', $updates);
+ }
+
+ if (count($parts) === 0) {
+ $blurb = '';
+ } else if (count($parts) === 1) {
+ $blurb = head($parts);
+ } else {
+ $last = array_pop($parts);
+ $blurb = implode(', ', $parts).' and '.$last;
+ }
+ }
+
+ return id(new AphrontProgressBarView())
+ ->setValue($points)
+ ->setMax(self::MAX_POINTS)
+ ->setCaption($blurb)
+ ->render();
+ }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephDiffMessageFieldSpecification.php b/src/applications/releeph/field/specification/ReleephDiffMessageFieldSpecification.php
new file mode 100644
index 0000000000..9d87d616c0
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephDiffMessageFieldSpecification.php
@@ -0,0 +1,37 @@
+<?php
+
+final class ReleephDiffMessageFieldSpecification
+ extends ReleephFieldSpecification {
+
+ public function getName() {
+ return 'Message';
+ }
+
+ public function renderLabelForHeaderView() {
+ return null;
+ }
+
+ public function renderValueForHeaderView() {
+ $commit_data = $this
+ ->getReleephRequest()
+ ->loadPhabricatorRepositoryCommitData();
+ if (!$commit_data) {
+ return '';
+ }
+
+ $engine = PhabricatorMarkupEngine::newDifferentialMarkupEngine();
+ $engine->setConfig('viewer', $this->getUser());
+ $markup = phutil_tag(
+ 'div',
+ array(
+ 'class' => 'phabricator-remarkup',
+ ),
+ $engine->markupText($commit_data->getCommitMessage()));
+
+ return id(new AphrontNoteView())
+ ->setTitle('Commit Message')
+ ->appendChild($markup)
+ ->render();
+ }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephDiffSizeFieldSpecification.php b/src/applications/releeph/field/specification/ReleephDiffSizeFieldSpecification.php
new file mode 100644
index 0000000000..586db1b1d0
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephDiffSizeFieldSpecification.php
@@ -0,0 +1,112 @@
+<?php
+
+/**
+ * While this class could take advantage of bulkLoad(), in practice
+ * loadRelatives fixes all that for us.
+ */
+final class ReleephDiffSizeFieldSpecification
+ extends ReleephFieldSpecification {
+
+ const LINES_WEIGHT = 1;
+ const PATHS_WEIGHT = 30;
+ const MAX_POINTS = 1000;
+
+ public function getName() {
+ return 'Size';
+ }
+
+ public function renderValueForHeaderView() {
+ $diff_rev = $this->getReleephRequest()->loadDifferentialRevision();
+ if (!$diff_rev) {
+ return '';
+ }
+
+ $diffs = $diff_rev->loadRelatives(
+ new DifferentialDiff(),
+ 'revisionID',
+ 'getID',
+ 'creationMethod <> "commit"');
+
+ $all_changesets = array();
+ $most_recent_changesets = null;
+ foreach ($diffs as $diff) {
+ $changesets = $diff->loadRelatives(new DifferentialChangeset(), 'diffID');
+ $all_changesets += $changesets;
+ $most_recent_changesets = $changesets;
+ }
+
+ // The score is based on all changesets for all versions of this diff
+ $all_changes = $this->countLinesAndPaths($all_changesets);
+ $points =
+ self::LINES_WEIGHT * $all_changes['code']['lines'] +
+ self::PATHS_WEIGHT * count($all_changes['code']['paths']);
+
+ // The blurb is just based on the most recent version of the diff
+ $mr_changes = $this->countLinesAndPaths($most_recent_changesets);
+
+ $test_tag = '';
+ if ($mr_changes['tests']['paths']) {
+ Javelin::initBehavior('phabricator-tooltips');
+ require_celerity_resource('aphront-tooltip-css');
+
+ $test_blurb =
+ pht('%d line(s)', $mr_changes['tests']['lines']).' and '.
+ pht('%d path(s)', count($mr_changes['tests']['paths'])).
+ " contain changes to test code:\n";
+ foreach ($mr_changes['tests']['paths'] as $mr_test_path) {
+ $test_blurb .= pht("%s\n", $mr_test_path);
+ }
+
+ $test_tag = javelin_tag(
+ 'span',
+ array(
+ 'sigil' => 'has-tooltip',
+ 'meta' => array(
+ 'tip' => $test_blurb,
+ 'align' => 'E',
+ 'size' => 'auto'),
+ 'style' => ''),
+ ' + tests');
+ }
+
+ $blurb = hsprintf("%s%s.",
+ pht('%d line(s)', $mr_changes['code']['lines']).' and '.
+ pht('%d path(s)', count($mr_changes['code']['paths'])).' over '.
+ pht('%d diff(s)', count($diffs)),
+ $test_tag);
+
+ return id(new AphrontProgressBarView())
+ ->setValue($points)
+ ->setMax(self::MAX_POINTS)
+ ->setCaption($blurb)
+ ->render();
+ }
+
+ private function countLinesAndPaths(array $changesets) {
+ assert_instances_of($changesets, 'DifferentialChangeset');
+ $lines = 0;
+ $paths_touched = array();
+ $test_lines = 0;
+ $test_paths_touched = array();
+
+ foreach ($changesets as $ch) {
+ if ($this->getReleephProject()->isTestFile($ch->getFilename())) {
+ $test_lines += $ch->getAddLines() + $ch->getDelLines();
+ $test_paths_touched[] = $ch->getFilename();
+ } else {
+ $lines += $ch->getAddLines() + $ch->getDelLines();
+ $paths_touched[] = $ch->getFilename();
+ }
+ }
+ return array(
+ 'code' => array(
+ 'lines' => $lines,
+ 'paths' => array_unique($paths_touched),
+ ),
+ 'tests' => array(
+ 'lines' => $test_lines,
+ 'paths' => array_unique($test_paths_touched),
+ )
+ );
+ }
+}
diff --git a/src/applications/releeph/field/specification/ReleephFieldSpecification.php b/src/applications/releeph/field/specification/ReleephFieldSpecification.php
new file mode 100644
index 0000000000..992808f12f
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephFieldSpecification.php
@@ -0,0 +1,359 @@
+<?php
+
+abstract class ReleephFieldSpecification {
+
+ abstract public function getName();
+
+/* -( Storage )------------------------------------------------------------ */
+
+ public function getStorageKey() {
+ return null;
+ }
+
+ final public function isEditable() {
+ return $this->getStorageKey() !== null;
+ }
+
+ /**
+ * This will be called many times if you are using **Selecting**. In
+ * particular, for N selecting fields, selectReleephRequests() is called
+ * N-squared times, each time for R ReleephRequests.
+ */
+ final public function getValue() {
+ $key = $this->getRequiredStorageKey();
+ return $this->getReleephRequest()->getDetail($key);
+ }
+
+ final public function setValue($value) {
+ $key = $this->getRequiredStorageKey();
+ return $this->getReleephRequest()->setDetail($key, $value);
+ }
+
+ /**
+ * @throws ReleephFieldParseException, to show an error.
+ */
+ public function validate($value) {
+ return;
+ }
+
+
+/* -( Header View )-------------------------------------------------------- */
+
+ /**
+ * Return a label for use in rendering the fields table. If you return null,
+ * the renderLabelForHeaderView data will span both columns.
+ */
+ public function renderLabelForHeaderView() {
+ return $this->getName();
+ }
+
+ public function renderValueForHeaderView() {
+ $key = $this->getRequiredStorageKey();
+ return $this->getReleephRequest()->getDetail($key);
+ }
+
+
+/* -( Edit View )---------------------------------------------------------- */
+
+ public function renderEditControl(AphrontRequest $request) {
+ throw new ReleephFieldSpecificationIncompleteException($this);
+ }
+
+ public function setValueFromAphrontRequest(AphrontRequest $request) {
+ $data = $request->getRequestData();
+ $value = idx($data, $this->getRequiredStorageKey());
+ $this->validate($value);
+ $this->setValue($value);
+ }
+
+
+/* -( Conduit )------------------------------------------------------------ */
+
+ public function getKeyForConduit() {
+ return $this->getRequiredStorageKey();
+ }
+
+ public function getValueForConduit() {
+ return $this->getValue();
+ }
+
+ public function setValueFromConduitAPIRequest(ConduitAPIRequest $request) {
+ $value = idx(
+ $request->getValue('fields', array()),
+ $this->getRequiredStorageKey());
+ $this->validate($value);
+ $this->setValue($value);
+ }
+
+
+/* -( Arcanist )----------------------------------------------------------- */
+
+ public function renderHelpForArcanist() {
+ return '';
+ }
+
+
+/* -( Context )------------------------------------------------------------ */
+
+ private $releephProject;
+ private $releephBranch;
+ private $releephRequest;
+ private $user;
+
+ final public function setReleephProject(ReleephProject $rp) {
+ $this->releephProject = $rp;
+ return $this;
+ }
+
+ final public function setReleephBranch(ReleephBranch $rb) {
+ $this->releephRequest = $rb;
+ return $this;
+ }
+
+ final public function setReleephRequest(ReleephRequest $rr) {
+ $this->releephRequest = $rr;
+ return $this;
+ }
+
+ final public function setUser(PhabricatorUser $user) {
+ $this->user = $user;
+ return $this;
+ }
+
+ final public function getReleephProject() {
+ return $this->releephProject;
+ }
+
+ final public function getReleephBranch() {
+ return $this->releephBranch;
+ }
+
+ final public function getReleephRequest() {
+ return $this->releephRequest;
+ }
+
+ final public function getUser() {
+ return $this->user;
+ }
+
+
+/* -( Bulk loading )------------------------------------------------------- */
+
+ public function bulkLoad(array $releeph_requests) {
+ }
+
+
+/* -( Selecting )---------------------------------------------------------- */
+
+ /**
+ * Append select controls to the given form.
+ *
+ * You are given:
+ *
+ * - the AphrontFormView to append to;
+ *
+ * - the AphrontRequest, so you can make use of the value currently selected
+ * in the form;
+ *
+ * - $all_releeph_requests: an array of all the ReleephRequests without any
+ * selection based filtering; and
+ *
+ * - $all_releeph_requests_without_this_field: an array of ReleephRequests
+ * that have been selected by all the other select controls on this page.
+ *
+ * The example in ReleephLevelFieldSpecification shows how to use these.
+ * $all_releeph_requests lets you find out all the values of a field in all
+ * ReleephRequests, so you can render controls for every known value.
+ *
+ * $all_releeph_requests_without_this_field lets you count how many
+ * ReleephRequests could be affected by this field's select control, after
+ * all the other fields have made their selections.
+ * ReleephLevelFieldSpecification uses this to render a preview count for
+ * each select button, and disables the button completely (but still renders
+ * it) if it couldn't possibly select anything.
+ */
+ protected function appendSelectControls(
+ AphrontFormView $form,
+ AphrontRequest $request,
+ array $all_releeph_requests,
+ array $all_releeph_requests_without_this_field) {
+
+ return null;
+ }
+
+ /**
+ * Filter the $releeph_requests using the data you set with your form
+ * controls, and which is now available in the provided AphrontRequest.
+ */
+ protected function selectReleephRequests(AphrontRequest $request,
+ array &$releeph_requests) {
+ return null;
+ }
+
+ /**
+ * If you have PHIDs that can be used in an AphrontFormTokenizerControl,
+ * return true here, return the PHIDs in getSelectablePHIDs(), and return the
+ * URL the Tokenizer should use for the form control in
+ * getSelectTokenizerDatasource().
+ *
+ * This is a cheap alternative to implementing appendSelectControls() and
+ * selectReleephRequests() in full.
+ */
+ protected function hasSelectablePHIDs() {
+ return false;
+ }
+
+ protected function getSelectablePHIDs() {
+ throw new ReleephFieldSpecificationIncompleteException($this);
+ }
+
+ protected function getSelectTokenizerDatasource() {
+ throw new ReleephFieldSpecificationIncompleteException($this);
+ }
+
+
+/* -( Commit Messages )---------------------------------------------------- */
+
+ public function shouldAppearOnCommitMessage() {
+ return false;
+ }
+
+ public function renderLabelForCommitMessage() {
+ throw new ReleephFieldSpecificationIncompleteException($this);
+ }
+
+ public function renderValueForCommitMessage() {
+ throw new ReleephFieldSpecificationIncompleteException($this);
+ }
+
+ public function shouldAppearOnRevertMessage() {
+ return false;
+ }
+
+ public function renderLabelForRevertMessage() {
+ return $this->renderLabelForCommitMessage();
+ }
+
+ public function renderValueForRevertMessage() {
+ return $this->renderValueForCommitMessage();
+ }
+
+
+/* -( Implementation )----------------------------------------------------- */
+
+ protected function getRequiredStorageKey() {
+ $key = $this->getStorageKey();
+ if ($key === null) {
+ throw new ReleephFieldSpecificationIncompleteException($this);
+ }
+ if (strpos($key, '.') !== false) {
+ /**
+ * Storage keys are reused for form controls, and periods in form control
+ * names break HTML forms.
+ */
+ throw new Exception(
+ "You can't use '.' in storage keys!");
+ }
+ return $key;
+ }
+
+ /**
+ * The "hook" functions ##appendSelectControlsHook()## and
+ * ##selectReleephRequestsHook()## are used with ##hasSelectablePHIDs()##, to
+ * use the tokenizing helpers if ##hasSelectablePHIDs()## returns true.
+ */
+ public function appendSelectControlsHook(
+ AphrontFormView $form,
+ AphrontRequest $request,
+ array $all_releeph_requests,
+ array $all_releeph_requests_without_this_field) {
+
+ if ($this->hasSelectablePHIDs()) {
+ $this->appendTokenizingSelectControl(
+ $form,
+ $request,
+ $all_releeph_requests,
+ $all_releeph_requests_without_this_field);
+ } else {
+ $this->appendSelectControls(
+ $form,
+ $request,
+ $all_releeph_requests,
+ $all_releeph_requests_without_this_field);
+ }
+ }
+
+ // See above
+ public function selectReleephRequestsHook(AphrontRequest $request,
+ array &$releeph_requests) {
+
+ if ($this->hasSelectablePHIDs()) {
+ $this->selectReleephRequestsFromTokens(
+ $request,
+ $releeph_requests);
+ } else {
+ $this->selectReleephRequests(
+ $request,
+ $releeph_requests);
+ }
+ }
+
+ private function appendTokenizingSelectControl(
+ AphrontFormView $form,
+ AphrontRequest $request,
+ array $all_releeph_requests,
+ array $all_releeph_requests_without_this_field) {
+
+ $key = urlencode(strtolower($this->getName()));
+ $selected_phids = $request->getArr($key);
+ $handles = id(new PhabricatorObjectHandleData($selected_phids))
+ ->setViewer($request->getUser())
+ ->loadHandles();
+
+ $tokens = array();
+ foreach ($selected_phids as $phid) {
+ $tokens[$phid] = $handles[$phid]->getFullName();
+ }
+
+ $datasource = $this->getSelectTokenizerDatasource();
+ $control =
+ id(new AphrontFormTokenizerControl())
+ ->setDatasource($datasource)
+ ->setName($key)
+ ->setLabel($this->getName())
+ ->setValue($tokens);
+
+ $form->appendChild($control);
+ }
+
+ private function selectReleephRequestsFromTokens(AphrontRequest $request,
+ array &$releeph_requests) {
+
+ $key = urlencode(strtolower($this->getName()));
+ $selected_phids = $request->getArr($key);
+ if (!$selected_phids) {
+ return;
+ }
+
+ $selected_phid_lookup = array();
+ foreach ($selected_phids as $phid) {
+ $selected_phid_lookup[$phid] = $phid;
+ }
+
+ $filtered = array();
+ foreach ($releeph_requests as $releeph_request) {
+ $rq_phids = $this
+ ->setReleephRequest($releeph_request)
+ ->getSelectablePHIDs();
+ foreach ($rq_phids as $rq_phid) {
+ if (idx($selected_phid_lookup, $rq_phid)) {
+ $filtered[] = $releeph_request;
+ break;
+ }
+ }
+ }
+
+ $releeph_requests = $filtered;
+ }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephIntentFieldSpecification.php b/src/applications/releeph/field/specification/ReleephIntentFieldSpecification.php
new file mode 100644
index 0000000000..6ba85271c2
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephIntentFieldSpecification.php
@@ -0,0 +1,81 @@
+<?php
+
+final class ReleephIntentFieldSpecification
+ extends ReleephFieldSpecification {
+
+ public function getName() {
+ return 'Intent';
+ }
+
+ public function renderValueForHeaderView() {
+ return id(new ReleephRequestIntentsView())
+ ->setReleephRequest($this->getReleephRequest())
+ ->setReleephProject($this->getReleephProject())
+ ->render();
+ }
+
+ public function shouldAppearOnCommitMessage() {
+ return true;
+ }
+
+ public function shouldAppearOnRevertMessage() {
+ return true;
+ }
+
+ public function renderLabelForCommitMessage() {
+ return "Approved By";
+ }
+
+ public function renderLabelForRevertMessage() {
+ return "Rejected By";
+ }
+
+ public function renderValueForCommitMessage() {
+ return $this->renderIntentsForCommitMessage(ReleephRequest::INTENT_WANT);
+ }
+
+ public function renderValueForRevertMessage() {
+ return $this->renderIntentsForCommitMessage(ReleephRequest::INTENT_PASS);
+ }
+
+ private function renderIntentsForCommitMessage($print_intent) {
+ $intents = $this->getReleephRequest()->getUserIntents();
+
+ $requestor = $this->getReleephRequest()->getRequestUserPHID();
+ $pusher_phids = $this->getReleephProject()->getPushers();
+
+ $phids = array_unique($pusher_phids + array_keys($intents));
+ $handles = id(new PhabricatorObjectHandleData($phids))
+ ->setViewer($this->getUser())
+ ->loadHandles();
+
+ $tokens = array();
+ foreach ($phids as $phid) {
+ $intent = idx($intents, $phid);
+ if ($intent == $print_intent) {
+ $name = $handles[$phid]->getName();
+ $is_pusher = in_array($phid, $pusher_phids);
+ $is_requestor = $phid == $requestor;
+
+ if ($is_pusher) {
+ if ($is_requestor) {
+ $token = "{$name} (pusher and requestor)";
+ } else {
+ $token = "{$name} (pusher)";
+ }
+ } else {
+ if ($is_requestor) {
+ $token = "{$name} (requestor)";
+ } else {
+ $token = $name;
+ }
+ }
+
+ $tokens[] = $token;
+ }
+ }
+
+ return implode(', ', $tokens);
+ }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephLevelFieldSpecification.php b/src/applications/releeph/field/specification/ReleephLevelFieldSpecification.php
new file mode 100644
index 0000000000..e1866d24b5
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephLevelFieldSpecification.php
@@ -0,0 +1,228 @@
+<?php
+
+/**
+ * Provides a convenient field for storing a set of levels that you can use to
+ * filter requests on.
+ *
+ * Levels are rendered with names and descriptions in the edit UI, and are
+ * automatically documented via the "arc request" interface.
+ *
+ * See ReleephSeverityFieldSpecification for an example.
+ */
+abstract class ReleephLevelFieldSpecification
+ extends ReleephFieldSpecification {
+
+ private $error;
+
+ abstract public function getLevels();
+ abstract public function getDefaultLevel();
+ abstract public function getNameForLevel($level);
+ abstract public function getDescriptionForLevel($level);
+
+ /**
+ * Use getCanonicalLevel() to convert old, unsupported levels to new ones.
+ */
+ protected function getCanonicalLevel($misc_level) {
+ return $misc_level;
+ }
+
+ public function getStorageKey() {
+ $class = get_class($this);
+ throw new ReleephFieldSpecificationIncompleteException(
+ $this,
+ "You must implement getStorageKey() for children of {$class}!");
+ }
+
+ public function renderValueForHeaderView() {
+ $raw_level = $this->getValue();
+ $level = $this->getCanonicalLevel($raw_level);
+ return $this->getNameForLevel($level);
+ }
+
+ public function renderEditControl(AphrontRequest $request) {
+ $control_name = $this->getRequiredStorageKey();
+ $all_levels = $this->getLevels();
+
+ $level = $request->getStr($control_name);
+
+ if (!$level) {
+ $level = $this->getCanonicalLevel($this->getValue());
+ }
+
+ if (!$level) {
+ $level = $this->getDefaultLevel();
+ }
+
+ $control = id(new AphrontFormRadioButtonControl())
+ ->setLabel('Level')
+ ->setName($control_name)
+ ->setValue($level);
+
+ if ($this->error) {
+ $control->setError($this->error);
+ } elseif ($this->getDefaultLevel()) {
+ $control->setError(true);
+ }
+
+ foreach ($all_levels as $level) {
+ $name = $this->getNameForLevel($level);
+ $description = $this->getDescriptionForLevel($level);
+ $control->addButton($level, $name, $description);
+ }
+
+ return $control;
+ }
+
+ public function renderHelpForArcanist() {
+ $text = '';
+ $levels = $this->getLevels();
+ $default = $this->getDefaultLevel();
+ foreach ($levels as $level) {
+ $name = $this->getNameForLevel($level);
+ $description = $this->getDescriptionForLevel($level);
+ $default_marker = ' ';
+ if ($level === $default) {
+ $default_marker = '*';
+ }
+ $text .= " {$default_marker} **{$name}**\n";
+ $text .= phutil_console_wrap($description."\n", 8);
+ }
+ return $text;
+ }
+
+ public function validate($value) {
+ if ($value === null) {
+ $this->error = 'Required';
+ $label = $this->getName();
+ throw new ReleephFieldParseException(
+ $this,
+ "You must provide a {$label} level");
+ }
+
+ $levels = $this->getLevels();
+ if (!in_array($value, $levels)) {
+ $label = $this->getName();
+ throw new ReleephFieldParseException(
+ $this,
+ "Level '{$value}' is not a valid {$label} level in this project.");
+ }
+ }
+
+ public function setValueFromConduitAPIRequest(ConduitAPIRequest $request) {
+ $key = $this->getRequiredStorageKey();
+ $label = $this->getName();
+ $name = idx($request->getValue('fields', array()), $key);
+
+ if (!$name) {
+ $level = $this->getDefaultLevel();
+ if (!$level) {
+ throw new ReleephFieldParseException(
+ $this,
+ "No value given for {$label}, ".
+ "and no default is given for this level!");
+ }
+ } else {
+ $level = $this->getLevelByName($name);
+ }
+
+ if (!$level) {
+ throw new ReleephFieldParseException(
+ $this,
+ "Unknown {$label} level name '{$name}'");
+ }
+ $this->setValue($level);
+ }
+
+ private $nameMap = array();
+
+ public function getLevelByName($name) {
+ // Build this once
+ if (!$this->nameMap) {
+ foreach ($this->getLevels() as $level) {
+ $level_name = $this->getNameForLevel($level);
+ $this->nameMap[$level_name] = $level;
+ }
+ }
+ return idx($this->nameMap, $name);
+ }
+
+ protected function appendSelectControls(
+ AphrontFormView $form,
+ AphrontRequest $request,
+ array $all_releeph_requests,
+ array $all_releeph_requests_without_this_field) {
+
+ $buttons = array(null => 'All');
+
+ // Add in known level/names
+ foreach ($this->getLevels() as $level) {
+ $name = $this->getNameForLevel($level);
+ $buttons[$name] = $name;
+ }
+
+ // Add in any names we've seen in the wild, as well.
+ foreach ($all_releeph_requests as $releeph_request) {
+ $raw_level = $this->setReleephRequest($releeph_request)->getValue();
+ if (!$raw_level) {
+ // The ReleephRequest might not have a level set
+ continue;
+ }
+ $level = $this->getCanonicalLevel($raw_level);
+ $name = $this->getNameForLevel($level);
+ $buttons[$name] = $name;
+ }
+
+ $key = $this->getRequiredStorageKey();
+ $current = $request->getStr($key);
+
+ $counters = array(null => count($all_releeph_requests_without_this_field));
+ foreach ($all_releeph_requests_without_this_field as $releeph_request) {
+ $raw_level = $this->setReleephRequest($releeph_request)->getValue();
+ if (!$raw_level) {
+ // The ReleephRequest might not have a level set
+ continue;
+ }
+ $level = $this->getCanonicalLevel($raw_level);
+ $name = $this->getNameForLevel($level);
+
+ if (!isset($counters[$name])) {
+ $counters[$name] = 0;
+ }
+ $counters[$name]++;
+ }
+
+ $control = id(new AphrontFormCountedToggleButtonsControl())
+ ->setLabel($this->getName())
+ ->setValue($current)
+ ->setBaseURI($request->getRequestURI(), $key)
+ ->setButtons($buttons)
+ ->setCounters($counters);
+
+ $form
+ ->appendChild($control)
+ ->addHiddenInput($key, $current);
+ }
+
+ protected function selectReleephRequests(AphrontRequest $request,
+ array &$releeph_requests) {
+ $key = $this->getRequiredStorageKey();
+ $current = $request->getStr($key);
+
+ if (!$current) {
+ return;
+ }
+
+ $filtered = array();
+ foreach ($releeph_requests as $releeph_request) {
+ $raw_level = $this->setReleephRequest($releeph_request)->getValue();
+ $level = $this->getCanonicalLevel($raw_level);
+ $name = $this->getNameForLevel($level);
+ if ($name == $current) {
+ $filtered[] = $releeph_request;
+ }
+ }
+
+ $releeph_requests = $filtered;
+ }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephOriginalCommitFieldSpecification.php b/src/applications/releeph/field/specification/ReleephOriginalCommitFieldSpecification.php
new file mode 100644
index 0000000000..3f4ec6ae1f
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephOriginalCommitFieldSpecification.php
@@ -0,0 +1,16 @@
+<?php
+
+final class ReleephOriginalCommitFieldSpecification
+ extends ReleephFieldSpecification {
+
+ public function getName() {
+ return 'Commit';
+ }
+
+ public function renderValueForHeaderView() {
+ $rr = $this->getReleephRequest();
+ $handles = $rr->getHandles();
+ return $handles[$rr->getRequestCommitPHID()]->renderLink();
+ }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephReasonFieldSpecification.php b/src/applications/releeph/field/specification/ReleephReasonFieldSpecification.php
new file mode 100644
index 0000000000..7b805cd490
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephReasonFieldSpecification.php
@@ -0,0 +1,78 @@
+<?php
+
+final class ReleephReasonFieldSpecification
+ extends ReleephFieldSpecification {
+
+ public function getName() {
+ return 'Reason';
+ }
+
+ public function getStorageKey() {
+ return 'reason';
+ }
+
+ public function renderLabelForHeaderView() {
+ return null;
+ }
+
+ public function renderValueForHeaderView() {
+ $reason = $this->getValue();
+ if (!$reason) {
+ return '';
+ }
+
+ $engine = PhabricatorMarkupEngine::newDifferentialMarkupEngine();
+ $engine->setConfig('viewer', $this->getUser());
+ $markup = phutil_tag(
+ 'div',
+ array(
+ 'class' => 'phabricator-remarkup',
+ ),
+ $engine->markupText($reason));
+
+ return id(new AphrontNoteView())
+ ->setTitle('Reason')
+ ->appendChild($markup)
+ ->render();
+ }
+
+ private $error = true;
+
+ public function renderEditControl(AphrontRequest $request) {
+ $reason = $request->getStr('reason', $this->getValue());
+ return id(new AphrontFormTextAreaControl())
+ ->setLabel('Reason')
+ ->setName('reason')
+ ->setError($this->error)
+ ->setValue($reason);
+ }
+
+ public function validate($reason) {
+ if (!$reason) {
+ $this->error = 'Required';
+ throw new ReleephFieldParseException(
+ $this,
+ "You must give a reason for your request.");
+ }
+ }
+
+ public function renderHelpForArcanist() {
+ $text =
+ "Fully explain why you are requesting this code be included ".
+ "in the next release.\n";
+ return phutil_console_wrap($text, 8);
+ }
+
+ public function shouldAppearOnCommitMessage() {
+ return true;
+ }
+
+ public function renderLabelForCommitMessage() {
+ return 'Request Reason';
+ }
+
+ public function renderValueForCommitMessage() {
+ return $this->getValue();
+ }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephRequestorFieldSpecification.php b/src/applications/releeph/field/specification/ReleephRequestorFieldSpecification.php
new file mode 100644
index 0000000000..aed8b01863
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephRequestorFieldSpecification.php
@@ -0,0 +1,59 @@
+<?php
+
+final class ReleephRequestorFieldSpecification
+ extends ReleephFieldSpecification {
+
+ public function bulkLoad(array $releeph_requests) {
+ $phids = mpull($releeph_requests, 'getRequestUserPHID');
+ ReleephUserView::getNewInstance()
+ ->setUser($this->getUser())
+ ->setReleephProject($this->getReleephProject())
+ ->load($phids);
+ }
+
+ public function getName() {
+ return 'Requestor';
+ }
+
+ public function renderValueForHeaderView() {
+ $phid = $this->getReleephRequest()->getRequestUserPHID();
+ return ReleephUserView::getNewInstance()
+ ->setRenderUserPHID($phid)
+ ->render();
+ }
+
+ public function hasSelectablePHIDs() {
+ return true;
+ }
+
+ public function getSelectTokenizerDatasource() {
+ return '/typeahead/common/users/';
+ }
+
+ public function getSelectablePHIDs() {
+ return array(
+ $this->getReleephRequest()->getRequestUserPHID(),
+ );
+ }
+
+ public function shouldAppearOnCommitMessage() {
+ return true;
+ }
+
+ public function shouldAppearOnRevertMessage() {
+ return true;
+ }
+
+ public function renderLabelForCommitMessage() {
+ return "Requested By";
+ }
+
+ public function renderValueForCommitMessage() {
+ $phid = $this->getReleephRequest()->getRequestUserPHID();
+ $handles = id(new PhabricatorObjectHandleData(array($phid)))
+ ->setViewer($this->getUser())
+ ->loadHandles();
+ return $handles[$phid]->getName();
+ }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephRevisionFieldSpecification.php b/src/applications/releeph/field/specification/ReleephRevisionFieldSpecification.php
new file mode 100644
index 0000000000..80b0d0f99d
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephRevisionFieldSpecification.php
@@ -0,0 +1,37 @@
+<?php
+
+final class ReleephRevisionFieldSpecification
+ extends ReleephFieldSpecification {
+
+ public function getName() {
+ return 'Revision';
+ }
+
+ public function renderValueForHeaderView() {
+ $data = $this
+ ->getReleephRequest()
+ ->loadPhabricatorRepositoryCommitData();
+ if (!$data) {
+ return null;
+ }
+
+ $phid = $data->getCommitDetail('differential.revisionPHID');
+ if (!$phid) {
+ return null;
+ }
+
+ $handles = $this->getReleephRequest()->getHandles();
+ $handle = $handles[$phid];
+ $link = $handle
+ // Hack to remove the strike-through rendering of diff links
+ ->setStatus(null)
+ ->renderLink();
+ return phutil_tag(
+ 'div',
+ array(
+ 'class' => 'releeph-header-text-truncated',
+ ),
+ $link);
+ }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephRiskFieldSpecification.php b/src/applications/releeph/field/specification/ReleephRiskFieldSpecification.php
new file mode 100644
index 0000000000..7ab3a33a18
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephRiskFieldSpecification.php
@@ -0,0 +1,63 @@
+<?php
+
+final class ReleephRiskFieldSpecification
+ extends ReleephFieldSpecification {
+
+ static $defaultRisks = array(
+ 'NONE' => 'Completely safe to pick this request.',
+ 'SOME' => 'There is some risk this could break things, but not much.',
+ 'HIGH' => 'This is pretty risky, but is also very important.',
+ );
+
+ public function getName() {
+ return 'Riskiness';
+ }
+
+ public function getStorageKey() {
+ return 'risk';
+ }
+
+ public function renderLabelForHeaderView() {
+ return 'Riskiness';
+ }
+
+ private $error = true;
+
+ public function renderEditControl(AphrontRequest $request) {
+ $value = $request->getStr('risk', $this->getValue());
+ $buttons = id(new AphrontFormRadioButtonControl())
+ ->setLabel('Riskiness')
+ ->setName('risk')
+ ->setError($this->error)
+ ->setValue($value);
+ foreach (self::$defaultRisks as $value => $description) {
+ $buttons->addButton($value, $value, $description);
+ }
+ return $buttons;
+ }
+
+ public function validate($risk) {
+ if (!$risk) {
+ $this->error = 'Required';
+ throw new ReleephFieldParseException(
+ $this,
+ "No risk was given, which probably means we've changed the set ".
+ "of valid risks since you made this request. Please pick one.");
+ }
+ if (!idx(self::$defaultRisks, $risk)) {
+ throw new ReleephFieldParseException(
+ $this,
+ "Unknown risk '{$risk}'.");
+ }
+ }
+
+ public function renderHelpForArcanist() {
+ $help = '';
+ foreach (self::$defaultRisks as $name => $description) {
+ $help .= " **{$name}**\n";
+ $help .= phutil_console_wrap($description."\n", 8);
+ }
+ return $help;
+ }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephSeverityFieldSpecification.php b/src/applications/releeph/field/specification/ReleephSeverityFieldSpecification.php
new file mode 100644
index 0000000000..9b362cbfd4
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephSeverityFieldSpecification.php
@@ -0,0 +1,46 @@
+<?php
+
+final class ReleephSeverityFieldSpecification
+ extends ReleephLevelFieldSpecification {
+
+ const HOTFIX = 'HOTFIX';
+ const RELEASE = 'RELEASE';
+
+ public function getName() {
+ return 'Severity';
+ }
+
+ public function getStorageKey() {
+ return 'releeph:severity';
+ }
+
+ public function getLevels() {
+ return array(
+ self::HOTFIX,
+ self::RELEASE,
+ );
+ }
+
+ public function getDefaultLevel() {
+ return self::RELEASE;
+ }
+
+ public function getNameForLevel($level) {
+ static $names = array(
+ self::HOTFIX => 'HOTFIX',
+ self::RELEASE => 'RELEASE',
+ );
+ return idx($names, $level, $level);
+ }
+
+ public function getDescriptionForLevel($level) {
+ static $descriptions = array(
+ self::HOTFIX =>
+ 'Needs merging and fixing right now.',
+ self::RELEASE =>
+ 'Required for the currently rolling release.',
+ );
+ return idx($descriptions, $level);
+ }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephStatusFieldSpecification.php b/src/applications/releeph/field/specification/ReleephStatusFieldSpecification.php
new file mode 100644
index 0000000000..202e5aba86
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephStatusFieldSpecification.php
@@ -0,0 +1,89 @@
+<?php
+
+final class ReleephStatusFieldSpecification
+ extends ReleephFieldSpecification {
+
+ public function getName() {
+ return 'Status';
+ }
+
+ public function renderValueForHeaderView() {
+ return id(new ReleephRequestStatusView())
+ ->setReleephRequest($this->getReleephRequest())
+ ->render();
+ }
+
+ private static $filters = array(
+ 'req' => ReleephRequest::STATUS_REQUESTED,
+ 'app' => ReleephRequest::STATUS_NEEDS_PICK,
+ 'rej' => ReleephRequest::STATUS_REJECTED,
+ 'abn' => ReleephRequest::STATUS_ABANDONED,
+ 'mer' => ReleephRequest::STATUS_PICKED,
+ 'rrq' => ReleephRequest::STATUS_NEEDS_REVERT,
+ 'rev' => ReleephRequest::STATUS_REVERTED,
+ );
+
+ protected function appendSelectControls(
+ AphrontFormView $form,
+ AphrontRequest $request,
+ array $all_releeph_requests,
+ array $all_releeph_requests_without_this_field) {
+
+ $filter_names = array(
+ null => 'All',
+ );
+
+ foreach (self::$filters as $code => $status) {
+ $name = ReleephRequest::getStatusDescriptionFor($status);
+ $filter_names[$code] = $name;
+ }
+
+ $key = 'status';
+ $code = $request->getStr($key);
+ $current_status = idx(self::$filters, $code);
+
+ $codes = array_flip(self::$filters);
+
+ $counters = array(null => count($all_releeph_requests_without_this_field));
+ foreach ($all_releeph_requests_without_this_field as $releeph_request) {
+ $this_status = $releeph_request->getStatus();
+ $this_code = idx($codes, $this_status);
+ if (!isset($counters[$this_code])) {
+ $counters[$this_code] = 0;
+ }
+ $counters[$this_code]++;
+ }
+
+ $control = id(new AphrontFormCountedToggleButtonsControl())
+ ->setLabel($this->getName())
+ ->setValue($code)
+ ->setBaseURI($request->getRequestURI(), $key)
+ ->setButtons($filter_names)
+ ->setCounters($counters);
+
+ $form
+ ->appendChild($control)
+ ->addHiddenInput($key, $code);
+ }
+
+ protected function selectReleephRequests(AphrontRequest $request,
+ array &$releeph_requests) {
+
+ $key = 'status';
+ $code = $request->getStr($key);
+ if (!$code) {
+ return;
+ }
+
+ $current_status = idx(self::$filters, $code);
+
+ $filtered = array();
+ foreach ($releeph_requests as $releeph_request) {
+ if ($releeph_request->getStatus() == $current_status) {
+ $filtered[] = $releeph_request;
+ }
+ }
+ $releeph_requests = $filtered;
+ }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephSummaryFieldSpecification.php b/src/applications/releeph/field/specification/ReleephSummaryFieldSpecification.php
new file mode 100644
index 0000000000..7ff398604e
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephSummaryFieldSpecification.php
@@ -0,0 +1,46 @@
+<?php
+
+final class ReleephSummaryFieldSpecification
+ extends ReleephFieldSpecification {
+
+ const MAX_SUMMARY_LENGTH = 60;
+
+ public function getName() {
+ return 'Summary';
+ }
+
+ public function getStorageKey() {
+ return 'summary';
+ }
+
+ private $error = false;
+
+ public function renderEditControl(AphrontRequest $request) {
+ $summary = $request->getStr('summary', $this->getValue());
+ return id(new AphrontFormTextControl())
+ ->setLabel('Summary')
+ ->setName('summary')
+ ->setError($this->error)
+ ->setValue($summary)
+ ->setCaption(
+ 'Leave this blank to use the original commit title');
+ }
+
+ public function renderHelpForArcanist() {
+ $text =
+ "A one-line title summarizing this request. ".
+ "Leave blank to use the original commit title.\n";
+ return phutil_console_wrap($text, 8);
+ }
+
+ public function validate($summary) {
+ if ($summary && strlen($summary) > self::MAX_SUMMARY_LENGTH) {
+ $this->error = 'Too long!';
+ throw new ReleephFieldParseException(
+ $this, sprintf(
+ 'Please keep your summary to under %d characters.',
+ self::MAX_SUMMARY_LENGTH));
+ }
+ }
+
+}
diff --git a/src/applications/releeph/storage/ReleephBranch.php b/src/applications/releeph/storage/ReleephBranch.php
new file mode 100644
index 0000000000..904cb30769
--- /dev/null
+++ b/src/applications/releeph/storage/ReleephBranch.php
@@ -0,0 +1,154 @@
+<?php
+
+final class ReleephBranch extends ReleephDAO {
+
+ protected $phid;
+ protected $releephProjectID;
+ protected $isActive;
+ protected $createdByUserPHID;
+
+ // The immutable name of this branch ('releases/foo-2013.01.24')
+ protected $name;
+ protected $basename;
+
+ // The symbolic name of this branch (LATEST, PRODUCTION, RC, ...)
+ // See SYMBOLIC_NAME_NOTE below
+ protected $symbolicName;
+
+ // Where to cut the branch
+ protected $cutPointCommitIdentifier;
+ protected $cutPointCommitPHID;
+
+ protected $details = array();
+
+ public function getConfiguration() {
+ return array(
+ self::CONFIG_AUX_PHID => true,
+ self::CONFIG_SERIALIZATION => array(
+ 'details' => self::SERIALIZATION_JSON,
+ ),
+ ) + parent::getConfiguration();
+ }
+
+ public function generatePHID() {
+ return PhabricatorPHID::generateNewPHID(
+ ReleephPHIDConstants::PHID_TYPE_REBR);
+ }
+
+ public function getDetail($key, $default = null) {
+ return idx($this->getDetails(), $key, $default);
+ }
+
+ public function setDetail($key, $value) {
+ $this->details[$key] = $value;
+ return $this;
+ }
+
+ public function willWriteData(array &$data) {
+ // If symbolicName is omitted, set it to the basename.
+ //
+ // This means that we can enforce symbolicName as a UNIQUE column in the
+ // DB. We'll interpret symbolicName === basename as meaning "no symbolic
+ // name".
+ //
+ // SYMBOLIC_NAME_NOTE
+ if (!$data['symbolicName']) {
+ $data['symbolicName'] = $data['basename'];
+ }
+ parent::willWriteData($data);
+ }
+
+ public function getSymbolicName() {
+ // See SYMBOLIC_NAME_NOTE above for why this is needed
+ if ($this->symbolicName == $this->getBasename()) {
+ return '';
+ }
+ return $this->symbolicName;
+ }
+
+ public function setSymbolicName($name) {
+ if ($name) {
+ parent::setSymbolicName($name);
+ } else {
+ parent::setSymbolicName($this->getBasename());
+ }
+ return $this;
+ }
+
+ public function getDisplayName() {
+ if ($sn = $this->getSymbolicName()) {
+ return $sn;
+ }
+ return $this->getBasename();
+ }
+
+ public function getDisplayNameWithDetail() {
+ $n = $this->getBasename();
+ if ($sn = $this->getSymbolicName()) {
+ return "{$sn} ({$n})";
+ } else {
+ return $n;
+ }
+ }
+
+ public function getURI($path = null) {
+ $components = array(
+ '/releeph',
+ rawurlencode($this->loadReleephProject()->getName()),
+ rawurlencode($this->getBasename()),
+ $path
+ );
+ return PhabricatorEnv::getProductionURI(implode('/', $components));
+ }
+
+ public function loadReleephProject() {
+ return $this->loadOneRelative(
+ new ReleephProject(),
+ 'id',
+ 'getReleephProjectID');
+ }
+
+ private function loadReleephRequestHandles(PhabricatorUser $user, $reqs) {
+ $phids_to_phetch = array();
+ foreach ($reqs as $rr) {
+ $phids_to_phetch[] = $rr->getRequestCommitPHID();
+ $phids_to_phetch[] = $rr->getRequestUserPHID();
+ $phids_to_phetch[] = $rr->getCommitPHID();
+
+ $intents = $rr->getUserIntents();
+ if ($intents) {
+ foreach ($intents as $user_phid => $intent) {
+ $phids_to_phetch[] = $user_phid;
+ }
+ }
+
+ $request_commit = $rr->loadPhabricatorRepositoryCommit();
+ if ($request_commit) {
+ $phids_to_phetch[] = $request_commit->getAuthorPHID();
+ $phids_to_phetch[] = $rr->loadRequestCommitDiffPHID();
+ }
+ }
+ $handles = id(new PhabricatorObjectHandleData($phids_to_phetch))
+ ->setViewer($user)
+ ->loadHandles();
+ return $handles;
+ }
+
+ public function populateReleephRequestHandles(PhabricatorUser $user, $reqs) {
+ $handles = $this->loadReleephRequestHandles($user, $reqs);
+ foreach ($reqs as $req) {
+ $req->setHandles($handles);
+ }
+ }
+
+ public function loadReleephRequests(PhabricatorUser $user) {
+ $reqs = $this->loadRelatives(new ReleephRequest(), 'branchID');
+ $this->populateReleephRequestHandles($user, $reqs);
+ return $reqs;
+ }
+
+ public function isActive() {
+ return $this->getIsActive();
+ }
+
+}
diff --git a/src/applications/releeph/storage/ReleephDAO.php b/src/applications/releeph/storage/ReleephDAO.php
new file mode 100644
index 0000000000..638e16a73d
--- /dev/null
+++ b/src/applications/releeph/storage/ReleephDAO.php
@@ -0,0 +1,9 @@
+<?php
+
+abstract class ReleephDAO extends PhabricatorLiskDAO {
+
+ public function getApplicationName() {
+ return 'releeph';
+ }
+
+}
diff --git a/src/applications/releeph/storage/ReleephProject.php b/src/applications/releeph/storage/ReleephProject.php
new file mode 100644
index 0000000000..1337340da2
--- /dev/null
+++ b/src/applications/releeph/storage/ReleephProject.php
@@ -0,0 +1,176 @@
+<?php
+
+final class ReleephProject extends ReleephDAO {
+
+ const DEFAULT_BRANCH_NAMESPACE = 'releeph-releases';
+ const SYSTEM_AGENT_USERNAME_PREFIX = 'releeph-agent-';
+
+ const COMMIT_AUTHOR_NONE = 'commit-author-none';
+ const COMMIT_AUTHOR_FROM_DIFF = 'commit-author-is-from-diff';
+ const COMMIT_AUTHOR_REQUESTOR = 'commit-author-is-requestor';
+
+ protected $phid;
+ protected $name;
+
+ // Specifying the place to pick from is a requirement for svn, though not
+ // for git. It's always useful though for reasoning about what revs have
+ // been picked and which haven't.
+ protected $trunkBranch;
+
+ protected $repositoryID;
+ protected $repositoryPHID;
+ protected $isActive;
+ protected $createdByUserPHID;
+ protected $arcanistProjectID;
+ protected $projectID;
+
+ protected $details = array();
+
+ public function getConfiguration() {
+ return array(
+ self::CONFIG_AUX_PHID => true,
+ self::CONFIG_SERIALIZATION => array(
+ 'details' => self::SERIALIZATION_JSON,
+ ),
+ ) + parent::getConfiguration();
+ }
+
+ public function generatePHID() {
+ return PhabricatorPHID::generateNewPHID(
+ ReleephPHIDConstants::PHID_TYPE_REPR);
+ }
+
+ public function getDetail($key, $default = null) {
+ return idx($this->details, $key, $default);
+ }
+
+ public function getURI($path = null) {
+ $components = array(
+ '/releeph/project',
+ $this->getID(),
+ $path
+ );
+ return PhabricatorEnv::getProductionURI(implode('/', $components));
+ }
+
+ public function setDetail($key, $value) {
+ $this->details[$key] = $value;
+ return $this;
+ }
+
+ public function willSaveObject() {
+ // Do this first, to generate the PHID
+ parent::willSaveObject();
+
+ $banned_names = $this->getBannedNames();
+ if (in_array($this->name, $banned_names)) {
+ throw new Exception(sprintf(
+ "The name '%s' is in the list of banned project names!",
+ $this->name,
+ implode(', ', $banned_names)));
+ }
+
+ if (!$this->getDetail('releaseCounter')) {
+ $this->setDetail('releaseCounter', 0);
+ }
+ }
+
+ public function loadPhabricatorProject() {
+ if ($id = $this->getProjectID()) {
+ return id(new PhabricatorProject())->load($id);
+ }
+ return id(new PhabricatorProject())->makeEphemeral(); // dummy
+ }
+
+ public function loadArcanistProject() {
+ return $this->loadOneRelative(
+ new PhabricatorRepositoryArcanistProject(),
+ 'id',
+ 'getArcanistProjectID');
+ }
+
+ public function getPushers() {
+ return $this->getDetail('pushers', array());
+ }
+
+ public function isPusherPHID($phid) {
+ $pusher_phids = $this->getDetail('pushers', array());
+ return in_array($phid, $pusher_phids);
+ }
+
+ public function isPusher(PhabricatorUser $user) {
+ return $this->isPusherPHID($user->getPHID());
+ }
+
+ public function loadPhabricatorRepository() {
+ return $this->loadOneRelative(
+ new PhabricatorRepository(),
+ 'id',
+ 'getRepositoryID');
+ }
+
+ public function getCurrentReleaseNumber() {
+ $current_release_numbers = array();
+
+ // From the project...
+ $current_release_numbers[] = $this->getDetail('releaseCounter', 0);
+
+ // From any branches...
+ $branches = id(new ReleephBranch())->loadAllWhere(
+ 'releephProjectID = %d', $this->getID());
+ if ($branches) {
+ $release_numbers = array();
+ foreach ($branches as $branch) {
+ $current_release_numbers[] = $branch->getDetail('releaseNumber', 0);
+ }
+ }
+
+ return max($current_release_numbers);
+ }
+
+ public function getReleephFieldSelector() {
+ $class = $this->getDetail('field_selector');
+ if (!$class) {
+ $key = 'releeph.field-selector';
+ $class = PhabricatorEnv::getEnvConfig($key);
+ }
+
+ if ($class) {
+ return newv($class, array());
+ } else {
+ return new ReleephDefaultFieldSelector();
+ }
+ }
+
+ /**
+ * Wrapper to setIsActive() that logs who deactivated a project
+ */
+ public function deactivate(PhabricatorUser $actor) {
+ return $this
+ ->setIsActive(0)
+ ->setDetail('last_deactivated_user', $actor->getPHID())
+ ->setDetail('last_deactivated_time', time());
+ }
+
+ // Hide this from the public
+ private function setIsActive($v) {
+ return parent::setIsActive($v);
+ }
+
+ private function getBannedNames() {
+ return array(
+ 'branch', // no one's tried this... yet!
+ );
+ }
+
+ public function isTestFile($filename) {
+ $test_paths = $this->getDetail('testPaths', array());
+
+ foreach ($test_paths as $test_path) {
+ if (preg_match($test_path, $filename)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/applications/releeph/storage/ReleephRequest.php b/src/applications/releeph/storage/ReleephRequest.php
new file mode 100644
index 0000000000..d7bb013048
--- /dev/null
+++ b/src/applications/releeph/storage/ReleephRequest.php
@@ -0,0 +1,309 @@
+<?php
+
+final class ReleephRequest extends ReleephDAO {
+
+ protected $phid;
+ protected $branchID;
+ protected $requestUserPHID;
+ protected $details = array();
+ protected $userIntents = array();
+ protected $inBranch;
+ protected $pickStatus;
+
+ // Information about the thing being requested
+ protected $requestCommitIdentifier;
+ protected $requestCommitPHID;
+ protected $requestCommitOrdinal;
+
+ // Information about the last commit to the releeph branch
+ protected $commitIdentifier;
+ protected $committedByUserPHID;
+ protected $commitPHID;
+
+ // Pre-populated handles that we'll bulk load in ReleephBranch
+ private $handles;
+
+
+/* -( Constants and helper methods )--------------------------------------- */
+
+ const INTENT_WANT = 'want';
+ const INTENT_PASS = 'pass';
+
+ const PICK_PENDING = 1; // old
+ const PICK_FAILED = 2;
+ const PICK_OK = 3;
+ const PICK_MANUAL = 4; // old
+ const REVERT_OK = 5;
+ const REVERT_FAILED = 6;
+
+ const STATUS_REQUESTED = 1;
+ const STATUS_NEEDS_PICK = 2; // aka approved
+ const STATUS_REJECTED = 3;
+ const STATUS_ABANDONED = 4;
+ const STATUS_PICKED = 5;
+ const STATUS_REVERTED = 6;
+ const STATUS_NEEDS_REVERT = 7; // aka revert requested
+
+ public function shouldBeInBranch() {
+ return
+ $this->getPusherIntent() == self::INTENT_WANT &&
+ /**
+ * We use "!= pass" instead of "== want" in case the requestor intent is
+ * not present. In other words, only revert if the requestor explicitly
+ * passed.
+ */
+ $this->getRequestorIntent() != self::INTENT_PASS;
+ }
+
+ /**
+ * Will return INTENT_WANT if any pusher wants this request, and no pusher
+ * passes on this request.
+ */
+ public function getPusherIntent() {
+ $project = $this->loadReleephProject();
+ if (!$project->getPushers()) {
+ return self::INTENT_WANT;
+ }
+
+ $found_pusher_want = false;
+ foreach ($this->userIntents as $phid => $intent) {
+ if ($project->isPusherPHID($phid)) {
+ if ($intent == self::INTENT_PASS) {
+ return self::INTENT_PASS;
+ }
+
+ $found_pusher_want = true;
+ }
+ }
+
+ if ($found_pusher_want) {
+ return self::INTENT_WANT;
+ } else {
+ return null;
+ }
+ }
+
+ public function getRequestorIntent() {
+ return idx($this->userIntents, $this->requestUserPHID);
+ }
+
+ public function getStatus() {
+ return $this->calculateStatus();
+ }
+
+ private function calculateStatus() {
+ if ($this->shouldBeInBranch()) {
+ if ($this->getInBranch()) {
+ return self::STATUS_PICKED;
+ } else {
+ return self::STATUS_NEEDS_PICK;
+ }
+ } else {
+ if ($this->getInBranch()) {
+ return self::STATUS_NEEDS_REVERT;
+ } else {
+ $has_been_in_branch = $this->getCommitIdentifier();
+ // Regardless of why we reverted something, always say reverted if it
+ // was once in the branch.
+ if ($has_been_in_branch) {
+ return self::STATUS_REVERTED;
+ } elseif ($this->getPusherIntent() === ReleephRequest::INTENT_PASS) {
+ // Otherwise, if it has never been in the branch, explicitly say why:
+ return self::STATUS_REJECTED;
+ } elseif ($this->getRequestorIntent() === ReleephRequest::INTENT_WANT) {
+ return self::STATUS_REQUESTED;
+ } else {
+ return self::STATUS_ABANDONED;
+ }
+ }
+ }
+ }
+
+ public static function getStatusDescriptionFor($status) {
+ static $descriptions = array(
+ self::STATUS_REQUESTED => 'Requested',
+ self::STATUS_REJECTED => 'Rejected',
+ self::STATUS_ABANDONED => 'Abandoned',
+ self::STATUS_PICKED => 'Picked',
+ self::STATUS_REVERTED => 'Reverted',
+ self::STATUS_NEEDS_PICK => 'Needs Pick',
+ self::STATUS_NEEDS_REVERT => 'Needs Revert',
+ );
+ return idx($descriptions, $status, '??');
+ }
+
+ public static function getStatusClassSuffixFor($status) {
+ $description = self::getStatusDescriptionFor($status);
+ $class = str_replace(' ', '-', strtolower($description));
+ return $class;
+ }
+
+
+/* -( Lisk mechanics )----------------------------------------------------- */
+
+ public function getConfiguration() {
+ return array(
+ self::CONFIG_AUX_PHID => true,
+ self::CONFIG_SERIALIZATION => array(
+ 'details' => self::SERIALIZATION_JSON,
+ 'userIntents' => self::SERIALIZATION_JSON,
+ ),
+ ) + parent::getConfiguration();
+ }
+
+ public function generatePHID() {
+ return PhabricatorPHID::generateNewPHID(
+ ReleephPHIDConstants::PHID_TYPE_RERQ);
+ }
+
+
+/* -( Helpful accessors )--------------------------------------------------- */
+
+ public function setHandles($handles) {
+ $this->handles = $handles;
+ return $this;
+ }
+
+ public function getHandles() {
+ if (!$this->handles) {
+ throw new Exception(
+ "You must call ReleephBranch::populateReleephRequestHandles() first");
+ }
+ return $this->handles;
+ }
+
+ public function getDetail($key, $default = null) {
+ return idx($this->getDetails(), $key, $default);
+ }
+
+ public function setDetail($key, $value) {
+ $this->details[$key] = $value;
+ return $this;
+ }
+
+ public function getReason() {
+ // Backward compatibility: reason used to be called comments
+ $reason = $this->getDetail('reason');
+ if (!$reason) {
+ return $this->getDetail('comments');
+ }
+ return $reason;
+ }
+
+ public function getSummary() {
+ /**
+ * Instead, you can use:
+ * - getDetail('summary') // the actual user-chosen summary
+ * - getSummaryForDisplay() // falls back to the original commit title
+ *
+ * Or for the fastidious:
+ * - id(new ReleephSummaryFieldSpecification())
+ * ->setReleephRequest($rr)
+ * ->getValue() // programmatic equivalent to getDetail()
+ */
+ throw new Exception(
+ "getSummary() has been deprecated!");
+ }
+
+ /**
+ * Allow a null summary, and fall back to the title of the commit.
+ */
+ public function getSummaryForDisplay() {
+ $summary = $this->getDetail('summary');
+
+ if (!$summary) {
+ $pr_commit_data = $this->loadPhabricatorRepositoryCommitData();
+ if ($pr_commit_data) {
+ $message_lines = explode("\n", $pr_commit_data->getCommitMessage());
+ $message_lines = array_filter($message_lines);
+ $summary = head($message_lines);
+ }
+ }
+
+ if (!$summary) {
+ $summary = '(no summary given and commit message empty or unparsed)';
+ }
+
+ return $summary;
+ }
+
+ public function loadRequestCommitDiffPHID() {
+ $commit_data = $this->loadPhabricatorRepositoryCommitData();
+ if (!$commit_data) {
+ return null;
+ }
+ return $commit_data->getCommitDetail('differential.revisionPHID');
+ }
+
+
+/* -( Loading external objects )------------------------------------------- */
+
+ public function loadReleephBranch() {
+ return $this->loadOneRelative(
+ new ReleephBranch(),
+ 'id',
+ 'getBranchID');
+ }
+
+ public function loadReleephProject() {
+ return $this->loadReleephBranch()->loadReleephProject();
+ }
+
+ public function loadEvents() {
+ return $this->loadRelatives(
+ new ReleephRequestEvent(),
+ 'releephRequestID',
+ 'getID',
+ '(1 = 1) ORDER BY dateCreated, id');
+ }
+
+ public function loadPhabricatorRepositoryCommit() {
+ return $this->loadOneRelative(
+ new PhabricatorRepositoryCommit(),
+ 'phid',
+ 'getRequestCommitPHID');
+ }
+
+ public function loadPhabricatorRepositoryCommitData() {
+ return $this->loadOneRelative(
+ new PhabricatorRepositoryCommitData(),
+ 'commitID',
+ 'getRequestCommitOrdinal');
+ }
+
+ public function loadDifferentialRevision() {
+ return $this->loadOneRelative(
+ new DifferentialRevision(),
+ 'phid',
+ 'loadRequestCommitDiffPHID');
+ }
+
+
+/* -( State change helpers )----------------------------------------------- */
+
+ public function setUserIntent(PhabricatorUser $user, $intent) {
+ $this->userIntents[$user->getPHID()] = $intent;
+ return $this;
+ }
+
+
+/* -( Migrating to status-less ReleephRequests )--------------------------- */
+
+ protected function didReadData() {
+ if ($this->userIntents === null) {
+ $this->userIntents = array();
+ }
+ }
+
+ public function setStatus($value) {
+ throw new Exception('`status` is now deprecated!');
+ }
+
+
+/* -( Make magic Lisk methods private )------------------------------------ */
+
+ private function setUserIntents(array $ar) {
+ return parent::setUserIntents($ar);
+ }
+
+}
diff --git a/src/applications/releeph/storage/event/ReleephEvent.php b/src/applications/releeph/storage/event/ReleephEvent.php
new file mode 100644
index 0000000000..e3333ec4e6
--- /dev/null
+++ b/src/applications/releeph/storage/event/ReleephEvent.php
@@ -0,0 +1,39 @@
+<?php
+
+final class ReleephEvent extends ReleephDAO {
+
+ const TYPE_BRANCH_CREATE = 'branch-create';
+ const TYPE_BRANCH_ACCESS = 'branch-access-change';
+
+ protected $releephProjectID;
+ protected $releephBranchID;
+ protected $type;
+ protected $epoch;
+ protected $actorPHID;
+ protected $details = array();
+
+ public function getConfiguration() {
+ return array(
+ self::CONFIG_SERIALIZATION => array(
+ 'details' => self::SERIALIZATION_JSON,
+ ),
+ ) + parent::getConfiguration();
+ }
+
+ public function getDetail($key, $default = null) {
+ return idx($this->details, $key, $default);
+ }
+
+ public function setDetail($key, $value) {
+ $this->details[$key] = $value;
+ return $this;
+ }
+
+ protected function willSaveObject() {
+ parent::willSaveObject();
+ if (!$this->epoch) {
+ $this->epoch = $this->dateCreated;
+ }
+ }
+
+}
diff --git a/src/applications/releeph/storage/request/ReleephRequestEvent.php b/src/applications/releeph/storage/request/ReleephRequestEvent.php
new file mode 100644
index 0000000000..b427516d46
--- /dev/null
+++ b/src/applications/releeph/storage/request/ReleephRequestEvent.php
@@ -0,0 +1,94 @@
+<?php
+
+final class ReleephRequestEvent extends ReleephDAO {
+
+ const TYPE_CREATE = 'create';
+ const TYPE_STATUS = 'status'; // old events
+ const TYPE_USER_INTENT = 'user-intent';
+ const TYPE_PICK_STATUS = 'pick-status';
+ const TYPE_COMMIT = 'commit';
+ const TYPE_MANUAL_ACTION = 'manual-action';
+ const TYPE_DISCOVERY = 'discovery';
+ const TYPE_COMMENT = 'comment';
+
+ protected $releephRequestID;
+ protected $type;
+ protected $actorPHID;
+ protected $details = array();
+
+ public function getConfiguration() {
+ return array(
+ self::CONFIG_SERIALIZATION => array(
+ 'details' => self::SERIALIZATION_JSON,
+ ),
+ ) + parent::getConfiguration();
+ }
+
+ public function getDetail($key, $default = null) {
+ return idx($this->details, $key, $default);
+ }
+
+ public function setDetail($key, $value) {
+ $this->details[$key] = $value;
+ return $this;
+ }
+
+ private function setDetails(array $details) {
+ throw new Exception('Use setDetail()!');
+ }
+
+ public function setStatusBefore($status) {
+ return $this->setDetail('oldStatus', $status);
+ }
+
+ public function setStatusAfter($status) {
+ return $this->setDetail('newStatus', $status);
+ }
+
+ public function getStatusBefore() {
+ return $this->getDetail('oldStatus');
+ }
+
+ public function getStatusAfter() {
+ return $this->getDetail('newStatus');
+ }
+
+ public function getComment() {
+ return $this->getDetail('comment');
+ }
+
+ public function extractPHIDs() {
+ $phids = array();
+ $phids[] = $this->actorPHID;
+ foreach ($this->details as $key => $value) {
+ if (strpos($key, 'PHID') !== false || strpos($key, 'phid') !== false) {
+ $phids[] = $value;
+ }
+ }
+ return $phids;
+ }
+
+ public function canGroupWith(ReleephRequestEvent $next) {
+ if ($this->getActorPHID() != $next->getActorPHID()) {
+ return false;
+ }
+
+ if ($this->getComment() && $next->getComment()) {
+ return false;
+ }
+
+ // Break the chain if the next event changes the status
+ if ($next->getStatusBefore() != $next->getStatusAfter()) {
+ return false;
+ }
+
+ // Don't group if the next event starts off with a different status to the
+ // one we ended with. This probably shouldn't ever happen.
+ if ($this->getStatusAfter() != $next->getStatusBefore()) {
+ return false;
+ }
+
+ return true;
+ }
+
+}
diff --git a/src/applications/releeph/storage/request/exception/ReleephRequestException.php b/src/applications/releeph/storage/request/exception/ReleephRequestException.php
new file mode 100644
index 0000000000..6f22f8c29a
--- /dev/null
+++ b/src/applications/releeph/storage/request/exception/ReleephRequestException.php
@@ -0,0 +1,3 @@
+<?php
+
+final class ReleephRequestException extends Exception {}
diff --git a/src/applications/releeph/view/ReleephProjectView.php b/src/applications/releeph/view/ReleephProjectView.php
new file mode 100644
index 0000000000..49f17d135d
--- /dev/null
+++ b/src/applications/releeph/view/ReleephProjectView.php
@@ -0,0 +1,155 @@
+<?php
+
+final class ReleephProjectView extends AphrontView {
+
+ private $showOpenBranches = true;
+ private $releephProject;
+ private $releephBranches;
+
+ public function setShowOpenBranches($active) {
+ $this->showOpenBranches = $active;
+ return $this;
+ }
+
+ public function setReleephProject($releeph_project) {
+ $this->releephProject = $releeph_project;
+ return $this;
+ }
+
+ public function setBranches($branches) {
+ $this->releephBranches = $branches;
+ return $this;
+ }
+
+ public function render() {
+ $releeph_project = $this->releephProject;
+
+ if ($this->showOpenBranches) {
+ $releeph_branches = mfilter($this->releephBranches, 'getIsActive');
+ } else {
+ $releeph_branches = mfilter($this->releephBranches, 'getIsActive', true);
+ }
+
+ // Load all relevant PHID handles
+ $phids = array_merge(
+ array(
+ $this->releephProject->getPHID(),
+ $this->releephProject->getRepositoryPHID(),
+ ),
+ mpull($releeph_branches, 'getCreatedByUserPHID'),
+ mpull($releeph_branches, 'getCutPointCommitPHID'),
+ $releeph_project->getPushers());
+ $handles = id(new PhabricatorObjectHandleData($phids))
+ ->setViewer($this->getUser())
+ ->loadHandles();
+
+ // Sort branches, which requires the handles above
+ $releeph_branches = self::sortBranches($releeph_branches, $handles);
+
+ // The header
+ $repository_phid = $releeph_project->getRepositoryPHID();
+
+ $header = hsprintf(
+ '%s in %s repository',
+ $releeph_project->getName(),
+ $handles[$repository_phid]->renderLink());
+
+ if ($this->showOpenBranches) {
+ $view_other_link = phutil_tag(
+ 'a',
+ array(
+ 'href' => $releeph_project->getURI('closedbranches/'),
+ ),
+ 'View closed branches');
+ } else {
+ $view_other_link = phutil_tag(
+ 'a',
+ array(
+ 'href' => $releeph_project->getURI(),
+ ),
+ 'View open branches');
+ }
+
+ $header = hsprintf("%s &middot; %s", $header, $view_other_link);
+
+ // The "create branch" button
+ $create_branch_url = $releeph_project->getURI('cutbranch/');
+
+ // Pushers info
+ $pushers_info = array();
+ $pushers = $releeph_project->getPushers();
+ require_celerity_resource('releeph-project');
+ if ($pushers) {
+ $pushers_info[] = phutil_tag('h2', array(), 'Pushers');
+ foreach ($pushers as $user_phid) {
+ $handle = $handles[$user_phid];
+ $div = phutil_tag(
+ 'div',
+ array(
+ 'class' => 'releeph-pusher',
+ 'style' => 'background-image: url('.$handle->getImageURI().');',
+ ),
+ phutil_tag(
+ 'div',
+ array(
+ 'class' => 'releeph-pusher-body',
+ ),
+ $handles[$user_phid]->renderLink()));
+ $pushers_info[] = $div;
+ }
+
+ $pushers_info[] = hsprintf('<div style="clear: both;"></div>');
+ }
+
+ // Put it all together
+ $panel = id(new AphrontPanelView())
+ ->setHeader($header)
+ ->appendChild(phutil_implode_html('', $pushers_info));
+
+ foreach ($releeph_branches as $ii => $releeph_branch) {
+ $box = id(new ReleephBranchBoxView())
+ ->setUser($this->user)
+ ->setHandles($handles)
+ ->setReleephBranch($releeph_branch)
+ ->setNamed();
+
+ if ($ii === 0) {
+ $box->setLatest();
+ }
+ $panel->appendChild($box);
+ }
+
+ return $panel->render();
+ }
+
+ /**
+ * Sort branches by the point at which they were cut, newest cut points
+ * first.
+ *
+ * If branches share a cut point, sort newest branch first.
+ */
+ private static function sortBranches($branches, $handles) {
+ // Group by commit phid
+ $groups = mgroup($branches, 'getCutPointCommitPHID');
+
+ // Convert commit phid to a commit timestamp
+ $ar = array();
+ foreach ($groups as $cut_phid => $group) {
+ $handle = $handles[$cut_phid];
+ // Pack (timestamp, group-with-this-timestamp) pairs into $ar
+ $ar[] = array(
+ $handle->getTimestamp(),
+ msort($group, 'getDateCreated')
+ );
+ }
+
+ $branches = array();
+ // Sort by timestamp, pull groups, and flatten into one big group
+ foreach (ipull(isort($ar, 0), 1) as $group) {
+ $branches = array_merge($branches, $group);
+ }
+
+ return array_reverse($branches);
+ }
+
+}
diff --git a/src/applications/releeph/view/branch/ReleephBranchBoxView.php b/src/applications/releeph/view/branch/ReleephBranchBoxView.php
new file mode 100644
index 0000000000..54b756d3f8
--- /dev/null
+++ b/src/applications/releeph/view/branch/ReleephBranchBoxView.php
@@ -0,0 +1,225 @@
+<?php
+
+final class ReleephBranchBoxView extends AphrontView {
+
+ private $releephBranch;
+ private $isLatest = false;
+ private $isNamed = false;
+ private $handles;
+
+ public function setReleephBranch(ReleephBranch $br) {
+ $this->releephBranch = $br;
+ return $this;
+ }
+
+ // Primary highlighted branch
+ public function setLatest() {
+ $this->isLatest = true;
+ return $this;
+ }
+
+ // Secondary highlighted branch(es)
+ public function setNamed() {
+ $this->isNamed = true;
+ return $this;
+ }
+
+ public function setHandles($handles) {
+ $this->handles = $handles;
+ return $this;
+ }
+
+ public function render() {
+ $br = $this->releephBranch;
+
+ require_celerity_resource('releeph-branch');
+ return phutil_tag(
+ 'div',
+ array(
+ 'class' => 'releeph-branch-box'.
+ ($this->isNamed ? ' releeph-branch-box-named' : '').
+ ($this->isLatest ? ' releeph-branch-box-latest' : ''),
+ ),
+ array(
+ $this->renderNames(),
+ $this->renderDatesTable(),
+ // "float: right" means the ordering here is weird
+ $this->renderButtons(),
+ $this->renderStatisticsTable(),
+ phutil_tag(
+ 'div',
+ array(
+ 'style' => 'clear:both;',
+ ),
+ '')));
+ }
+
+ private function renderNames() {
+ $br = $this->releephBranch;
+
+ return phutil_tag(
+ 'div',
+ array(
+ 'class' => 'names',
+ ),
+ array(
+ phutil_tag(
+ 'h1',
+ array(),
+ $br->getDisplayName()),
+ phutil_tag(
+ 'h2',
+ array(),
+ $br->getName())));
+ }
+
+ private function renderDatesTable() {
+ $br = $this->releephBranch;
+ $branch_commit_handle = $this->handles[$br->getCutPointCommitPHID()];
+
+ $properties = array();
+ $properties['Created by'] =
+
+ $cut_age = phabricator_format_relative_time(
+ time() - $branch_commit_handle->getTimestamp());
+
+ return phutil_tag(
+ 'div',
+ array(
+ 'class' => 'date-info',
+ ),
+ array(
+ $this->handles[$br->getCreatedByUserPHID()]->renderLink(),
+ phutil_tag('br'),
+ phutil_tag(
+ 'a',
+ array(
+ 'href' => $branch_commit_handle->getURI(),
+ ),
+ $cut_age.' old')));
+ }
+
+ private function renderStatisticsTable() {
+ $statistics = array();
+
+ $requests = $this->releephBranch->loadReleephRequests($this->getUser());
+ foreach ($requests as $request) {
+ $status = $request->getStatus();
+ if (!isset($statistics[$status])) {
+ $statistics[$status] = 0;
+ }
+ $statistics[$status]++;
+ }
+
+ static $col_groups = 3;
+
+ $cells = array();
+ foreach ($statistics as $status => $count) {
+ $description = ReleephRequest::getStatusDescriptionFor($status);
+ $cells[] = phutil_tag('th', array(), $count);
+ $cells[] = phutil_tag('td', array(), $description);
+ }
+
+ $rows = array();
+ while ($cells) {
+ $row_cells = array();
+ for ($ii = 0; $ii < 2 * $col_groups; $ii++) {
+ $row_cells[] = array_shift($cells);
+ }
+ $rows[] = phutil_tag('tr', array(), $row_cells);
+ }
+
+ if (!$rows) {
+ $rows = hsprintf('<tr><th></th><td>%s</td></tr>', 'none');
+ }
+
+ return phutil_tag(
+ 'div',
+ array(
+ 'class' => 'request-statistics',
+ ),
+ phutil_tag(
+ 'table',
+ array(),
+ $rows));
+ }
+
+ private function renderButtons() {
+ $br = $this->releephBranch;
+
+ $buttons = array();
+
+ $buttons[] = phutil_tag(
+ 'a',
+ array(
+ 'class' => 'small grey button',
+ 'href' => $br->getURI(),
+ ),
+ 'View Requests');
+
+ $repo = $br->loadReleephProject()->loadPhabricatorRepository();
+ if (!$repo) {
+ $buttons[] = phutil_tag(
+ 'a',
+ array(
+ 'class' => 'small button disabled',
+ ),
+ "Diffusion \xE2\x86\x97");
+ } else {
+ $diffusion_request = DiffusionRequest::newFromDictionary(array(
+ 'repository' => $repo,
+ ));
+ $diffusion_branch_uri = $diffusion_request->generateURI(array(
+ 'action' => 'branch',
+ 'branch' => $br->getName(),
+ ));
+ $diffusion_button_class = 'small grey button';
+
+ $buttons[] = phutil_tag(
+ 'a',
+ array(
+ 'class' => $diffusion_button_class,
+ 'target' => '_blank',
+ 'href' => $diffusion_branch_uri,
+ ),
+ "Diffusion \xE2\x86\x97");
+ }
+
+ $releeph_project = $br->loadReleephProject();
+ if (!$releeph_project->getPushers() ||
+ $releeph_project->isPusher($this->user)) {
+
+ $buttons[] = phutil_tag(
+ 'a',
+ array(
+ 'class' => 'small blue button',
+ 'href' => $br->getURI('edit/'),
+ ),
+ 'Edit');
+
+ if ($br->isActive()) {
+ $button_text = "Close";
+ $href = $br->getURI('close/');
+ } else {
+ $button_text = "Re-open";
+ $href = $br->getURI('re-open/');
+ }
+ $buttons[] = javelin_tag(
+ 'a',
+ array(
+ 'class' => 'small blue button',
+ 'href' => $href,
+ 'sigil' => 'workflow',
+ ),
+ $button_text);
+ }
+
+ return phutil_tag(
+ 'div',
+ array(
+ 'class' => 'buttons',
+ ),
+ $buttons);
+ }
+
+}
diff --git a/src/applications/releeph/view/branch/ReleephBranchPreviewView.php b/src/applications/releeph/view/branch/ReleephBranchPreviewView.php
new file mode 100644
index 0000000000..8f5f344f69
--- /dev/null
+++ b/src/applications/releeph/view/branch/ReleephBranchPreviewView.php
@@ -0,0 +1,60 @@
+<?php
+
+final class ReleephBranchPreviewView extends AphrontFormControl {
+
+ private $statics = array();
+ private $dynamics = array();
+
+ public function addControl($param_name, AphrontFormControl $control) {
+ $celerity_id = celerity_generate_unique_node_id();
+ $control->setID($celerity_id);
+ $this->dynamics[$param_name] = $celerity_id;
+ return $this;
+ }
+
+ public function addStatic($param_name, $value) {
+ $this->statics[$param_name] = $value;
+ return $this;
+ }
+
+ public function getCustomControlClass() {
+ require_celerity_resource('releeph-preview-branch');
+ return 'releeph-preview-branch';
+ }
+
+ public function renderInput() {
+ static $required_params = array(
+ 'arcProjectID',
+ 'projectName',
+ 'isSymbolic',
+ 'template',
+ );
+
+ $all_params = array_merge($this->statics, $this->dynamics);
+ foreach ($required_params as $param_name) {
+ if (idx($all_params, $param_name) === null) {
+ throw new Exception(
+ "'{$param_name}' is not set as either a static or dynamic!");
+ }
+ }
+
+ $output_id = celerity_generate_unique_node_id();
+
+ Javelin::initBehavior('releeph-preview-branch', array(
+ 'uri' => '/releeph/branch/preview/',
+ 'outputID' => $output_id,
+ 'params' => array(
+ 'static' => $this->statics,
+ 'dynamic' => $this->dynamics,
+ )
+ ));
+
+ return phutil_tag(
+ 'div',
+ array(
+ 'id' => $output_id,
+ ),
+ '');
+ }
+
+}
diff --git a/src/applications/releeph/view/branch/ReleephBranchTemplate.php b/src/applications/releeph/view/branch/ReleephBranchTemplate.php
new file mode 100644
index 0000000000..cef13ee256
--- /dev/null
+++ b/src/applications/releeph/view/branch/ReleephBranchTemplate.php
@@ -0,0 +1,241 @@
+<?php
+
+final class ReleephBranchTemplate {
+
+ const KEY = 'releeph.default-branch-template';
+
+ public static function getDefaultTemplate() {
+ return PhabricatorEnv::getEnvConfig(self::KEY);
+ }
+
+ public static function getRequiredDefaultTemplate() {
+ $template = self::getDefaultTemplate();
+ if (!$template) {
+ throw new Exception(sprintf(
+ "Config setting '%s' must be set, ".
+ "or you must provide a branch-template for each project!",
+ self::KEY));
+ }
+ return $template;
+ }
+
+ public static function getFakeCommitHandleFor($arc_project_id) {
+ $arc_project = id(new PhabricatorRepositoryArcanistProject())
+ ->load($arc_project_id);
+ if (!$arc_project) {
+ throw new Exception(
+ "No Arc project found with id '{$arc_project_id}'!");
+ }
+
+ $repository = $arc_project->loadRepository();
+ return id(new PhabricatorObjectHandle())
+ ->setName($repository->formatCommitName('100000000000'));
+ }
+
+ private $commitHandle;
+ private $branchDate = null;
+ private $projectName;
+ private $isSymbolic;
+
+ public function setCommitHandle(PhabricatorObjectHandle $handle) {
+ $this->commitHandle = $handle;
+ return $this;
+ }
+
+ public function setBranchDate($branch_date) {
+ $this->branchDate = $branch_date;
+ return $this;
+ }
+
+ public function setReleephProjectName($project_name) {
+ $this->projectName = $project_name;
+ return $this;
+ }
+
+ public function setSymbolic($is_symbolic) {
+ $this->isSymbolic = $is_symbolic;
+ return $this;
+ }
+
+ public function interpolate($template) {
+ if (!$this->projectName) {
+ return array('', array());
+ }
+
+ list($name, $name_errors) = $this->interpolateInner(
+ $template,
+ $this->isSymbolic);
+
+ if ($this->isSymbolic) {
+ return array($name, $name_errors);
+ } else {
+ $validate_errors = $this->validateAsBranchName($name);
+ $errors = array_merge($name_errors, $validate_errors);
+ return array($name, $errors);
+ }
+ }
+
+ public static function getHelpRemarkup() {
+ return <<<EOTEXT
+
+==== Interpolations ====
+
+| Code | Meaning
+| ----- | -------
+| `%P` | The name of your project, with spaces changed to "-".
+| `%p` | Like %P, but all lowercase.
+| `%Y` | The four digit year associated with the branch date.
+| `%m` | The two digit month.
+| `%d` | The two digit day.
+| `%v` | The handle of the commit where the branch was cut ("rXYZa4b3c2d1").
+| `%V` | The abbreviated commit id where the branch was cut ("a4b3c2d1").
+| `%..` | Any other sequence interpreted by `strftime()`.
+| `%%` | A literal percent sign.
+
+
+==== Tips for Branch Templates ====
+
+Use a directory to separate your release branches from other branches:
+
+ lang=none
+ releases/%Y-%M-%d-%v
+ => releases/2012-30-16-rHERGE32cd512a52b7
+
+Include a second hierarchy if you share your repository with other projects:
+
+ lang=none
+ releases/%P/%p-release-%Y%m%d-%V
+ => releases/Tintin/tintin-release-20121116-32cd512a52b7
+
+Keep your branch names simple, avoiding strange punctuation, most of which is
+forbidden or escaped anyway:
+
+ lang=none, counterexample
+ releases//..clown-releases..//`date --iso=seconds`-$(sudo halt)
+
+Include the date early in your template, in an order which sorts properly:
+
+ lang=none
+ releases/%Y%m%d-%v
+ => releases/20121116-rHERGE32cd512a52b7 (good!)
+
+ releases/%V-%m.%d.%Y
+ => releases/32cd512a52b7-11.16.2012 (awful!)
+
+
+EOTEXT
+ ;
+ }
+
+ /*
+ * xsprintf() would be useful here, but that's for formatting concrete lists
+ * of things in a certain way...
+ *
+ * animal_printf('%A %A %A', $dog1, $dog2, $dog3);
+ *
+ * ...rather than interpolating percent-control-strings like strftime does.
+ */
+ private function interpolateInner($template, $is_symbolic) {
+ $name = $template;
+ $errors = array();
+
+ $safe_project_name = str_replace(' ', '-', $this->projectName);
+ $short_commit_id = last(
+ preg_split('/r[A-Z]+/', $this->commitHandle->getName()));
+
+ $interpolations = array();
+ for ($ii = 0; $ii < strlen($name); $ii++) {
+ $char = substr($name, $ii, 1);
+ $prev = null;
+ if ($ii > 0) {
+ $prev = substr($name, $ii - 1, 1);
+ }
+ $next = substr($name, $ii + 1, 1);
+ if ($next && $char == '%' && $prev != '%') {
+ $interpolations[$ii] = $next;
+ }
+ }
+
+ $variable_interpolations = array();
+
+ $reverse_interpolations = $interpolations;
+ krsort($reverse_interpolations);
+
+ if ($this->branchDate) {
+ $branch_date = $this->branchDate;
+ } else {
+ $branch_date = $this->commitHandle->getTimestamp();
+ }
+
+ foreach ($reverse_interpolations as $position => $code) {
+ $replacement = null;
+ switch ($code) {
+ case 'v':
+ $replacement = $this->commitHandle->getName();
+ $is_variable = true;
+ break;
+
+ case 'V':
+ $replacement = $short_commit_id;
+ $is_variable = true;
+ break;
+
+ case 'P':
+ $replacement = $safe_project_name;
+ $is_variable = false;
+ break;
+
+ case 'p':
+ $replacement = strtolower($safe_project_name);
+ $is_variable = false;
+ break;
+
+ default:
+ // Format anything else using strftime()
+ $replacement = strftime("%{$code}", $branch_date);
+ $is_variable = true;
+ break;
+ }
+
+ if ($is_variable) {
+ $variable_interpolations[] = $code;
+ }
+ $name = substr_replace($name, $replacement, $position, 2);
+ }
+
+ if (!$is_symbolic && !$variable_interpolations) {
+ $errors[] = "Include additional interpolations that aren't static!";
+ }
+
+ return array($name, $errors);
+ }
+
+ private function validateAsBranchName($name) {
+ $errors = array();
+
+ if (preg_match('{^/}', $name) || preg_match('{/$}', $name)) {
+ $errors[] = "Branches cannot begin or end with '/'";
+ }
+
+ if (preg_match('{//+}', $name)) {
+ $errors[] = "Branches cannot contain multiple consective '/'";
+ }
+
+ $parts = array_filter(explode('/', $name));
+ foreach ($parts as $index => $part) {
+ $part_error = null;
+ if (preg_match('{^\.}', $part) || preg_match('{\.$}', $part)) {
+ $errors[] = "Path components cannot begin or end with '.'";
+ } elseif (preg_match('{^(?!\w)}', $part)) {
+ $errors[] = "Path components must begin with an alphanumeric";
+ } elseif (!preg_match('{^\w ([\w-_%\.]* [\w-_%])?$}x', $part)) {
+ $errors[] =
+ "Path components may only contain alphanumerics ".
+ "or '-', '_', or '.'";
+ }
+ }
+
+ return $errors;
+ }
+
+}
diff --git a/src/applications/releeph/view/project/list/ReleephActiveProjectListView.php b/src/applications/releeph/view/project/list/ReleephActiveProjectListView.php
new file mode 100644
index 0000000000..6b9d533f2b
--- /dev/null
+++ b/src/applications/releeph/view/project/list/ReleephActiveProjectListView.php
@@ -0,0 +1,102 @@
+<?php
+
+final class ReleephActiveProjectListView extends AphrontView {
+
+ private $releephProjects;
+
+ public function setReleephProjects(array $releeph_projects) {
+ $this->releephProjects = $releeph_projects;
+ return $this;
+ }
+
+ public function render() {
+ $rows = array();
+ foreach ($this->releephProjects as $releeph_project) {
+ $project_uri = $releeph_project->getURI();
+
+ $name_link = phutil_tag(
+ 'a',
+ array(
+ 'href' => $project_uri,
+ 'style' => 'font-weight: bold;',
+ ),
+ $releeph_project->getName());
+
+ $edit_button = phutil_tag(
+ 'a',
+ array(
+ 'href' => $releeph_project->getURI('edit/'),
+ 'class' => 'small grey button',
+ ),
+ 'Edit');
+
+ $deactivate_button = javelin_tag(
+ 'a',
+ array(
+ 'href' => $releeph_project->getURI('action/deactivate/'),
+ 'class' => 'small grey button',
+ 'sigil' => 'workflow',
+ ),
+ 'Remove');
+
+ $arc_project = $releeph_project->loadArcanistProject();
+ if ($arc_project) {
+ $arc_project_name = $arc_project->getName();
+ } else {
+ $arc_project_name = phutil_tag(
+ 'i',
+ array(),
+ 'Deleted Arcanist Project');
+ }
+
+ $repo = $releeph_project->loadPhabricatorRepository();
+
+ if ($repo) {
+ $vcs_type =
+ PhabricatorRepositoryType::getNameForRepositoryType(
+ $repo->getVersionControlSystem());
+
+ $rows[] = array(
+ $name_link,
+ $repo->getName(),
+ $arc_project_name,
+ $vcs_type,
+ $edit_button,
+ $deactivate_button,
+ );
+ } else {
+ $rows[] = array(
+ $name_link,
+ phutil_tag('i', array(), 'Deleted Repository'),
+ $arc_project_name,
+ null,
+ null,
+ $deactivate_button,
+ );
+ }
+ }
+
+ $table = new AphrontTableView($rows);
+
+ $table->setHeaders(array(
+ 'Name',
+ 'Repository',
+ 'Arcanist Project',
+ 'Type',
+ '',
+ ''
+ ));
+
+ $table->setColumnClasses(array(
+ null,
+ null,
+ 'wide',
+ null,
+ 'action',
+ 'action'
+ ));
+
+ return $table->render();
+ }
+
+}
diff --git a/src/applications/releeph/view/project/list/ReleephInactiveProjectListView.php b/src/applications/releeph/view/project/list/ReleephInactiveProjectListView.php
new file mode 100644
index 0000000000..765145e207
--- /dev/null
+++ b/src/applications/releeph/view/project/list/ReleephInactiveProjectListView.php
@@ -0,0 +1,112 @@
+<?php
+
+final class ReleephInactiveProjectListView extends AphrontView {
+
+ private $releephProjects;
+
+ public function setReleephProjects(array $releeph_projects) {
+ $this->releephProjects = $releeph_projects;
+ return $this;
+ }
+
+ public function render() {
+ $rows = array();
+
+ $phids = array();
+ foreach ($this->releephProjects as $releeph_project) {
+ $phids[] = $releeph_project->getCreatedByUserPHID();
+ if ($phid = $releeph_project->getDetail('last_deactivated_user')) {
+ $phids[] = $phid;
+ }
+ }
+
+ $handles = id(new PhabricatorObjectHandleData($phids))
+ ->setViewer($this->getUser())
+ ->loadHandles();
+
+ foreach ($this->releephProjects as $releeph_project) {
+ $repository = $releeph_project->loadPhabricatorRepository();
+
+ if (!$repository) {
+ // Ignore projects referring to repositories that have been deleted.
+ continue;
+ }
+
+ $activate_link = javelin_tag(
+ 'a',
+ array(
+ 'href' => $releeph_project->getURI('action/activate/'),
+ 'class' => 'small grey button',
+ 'sigil' => 'workflow',
+ ),
+ 'Revive');
+
+ $delete_link = javelin_tag(
+ 'a',
+ array(
+ 'href' => $releeph_project->getURI('action/delete/'),
+ 'class' => 'small grey button',
+ 'sigil' => 'workflow',
+ ),
+ 'Delete');
+
+ $rows[] = array(
+ $releeph_project->getName(),
+ $repository->getName(),
+ $this->renderCreationInfo($releeph_project, $handles),
+ $this->renderDeletionInfo($releeph_project, $handles),
+ $activate_link,
+ $delete_link,
+ );
+ }
+
+ $table = new AphrontTableView($rows);
+
+ $table->setHeaders(array(
+ 'Name',
+ 'Repository',
+ 'Created',
+ 'Deleted',
+ '',
+ '',
+ ));
+
+ $table->setColumnClasses(array(
+ null,
+ null,
+ null,
+ 'wide',
+ 'action',
+ 'action',
+ ));
+
+ return $table->render();
+ }
+
+ private function renderCreationInfo($releeph_project, $handles) {
+ $creator = $handles[$releeph_project->getCreatedByUserPHID()];
+ $when = $releeph_project->getDateCreated();
+ return hsprintf(
+ '%s by %s',
+ phabricator_relative_date($when, $this->user),
+ $creator->getName());
+ }
+
+ private function renderDeletionInfo($releeph_project, $handles) {
+ $deleted_on = $releeph_project->getDetail('last_deactivated_time');
+
+ $deleted_by_name = null;
+ $deleted_by_phid = $releeph_project->getDetail('last_deactivated_user');
+ if ($deleted_by_phid) {
+ $deleted_by_name = $handles[$deleted_by_phid]->getName();
+ } else {
+ $deleted_by_name = 'unknown';
+ }
+
+ return hsprintf(
+ '%s by %s',
+ phabricator_relative_date($deleted_on, $this->user),
+ $deleted_by_name);
+ }
+
+}
diff --git a/src/applications/releeph/view/request/ReleephRequestIntentsView.php b/src/applications/releeph/view/request/ReleephRequestIntentsView.php
new file mode 100644
index 0000000000..b9c78680ab
--- /dev/null
+++ b/src/applications/releeph/view/request/ReleephRequestIntentsView.php
@@ -0,0 +1,104 @@
+<?php
+
+final class ReleephRequestIntentsView extends AphrontView {
+
+ private $releephRequest;
+ private $releephProject;
+
+ public function setReleephRequest(ReleephRequest $rq) {
+ $this->releephRequest = $rq;
+ return $this;
+ }
+
+ public function setReleephProject(ReleephProject $rp) {
+ $this->releephProject = $rp;
+ return $this;
+ }
+
+ public function render() {
+ require_celerity_resource('releeph-intents');
+
+ return phutil_tag(
+ 'div',
+ array(
+ 'class' => 'releeph-intents',
+ ),
+ array(
+ $this->renderIntentList(ReleephRequest::INTENT_WANT),
+ $this->renderIntentList(ReleephRequest::INTENT_PASS)
+ ));
+ }
+
+ private function renderIntentList($render_intent) {
+ if (!$this->releephProject) {
+ throw new Exception("Must call setReleephProject() first!");
+ }
+
+ $project = $this->releephProject;
+ $request = $this->releephRequest;
+ $handles = $request->getHandles();
+
+ $is_want = $render_intent == ReleephRequest::INTENT_WANT;
+ $should = $request->shouldBeInBranch();
+
+ $pusher_links = array();
+ $user_links = array();
+
+ $intents = $request->getUserIntents();
+ foreach ($intents as $user_phid => $user_intent) {
+ if ($user_intent == $render_intent) {
+ $is_pusher = $project->isPusherPHID($user_phid);
+
+ if ($is_pusher) {
+ $pusher_links[] = phutil_tag(
+ 'span',
+ array(
+ 'class' => 'pusher'
+ ),
+ $handles[$user_phid]->renderLink());
+ } else {
+ $class = 'bystander';
+ if ($request->getRequestUserPHID() == $user_phid) {
+ $class = 'requestor';
+ }
+ $user_links[] = phutil_tag(
+ 'span',
+ array(
+ 'class' => $class,
+ ),
+ $handles[$user_phid]->renderLink());
+ }
+ }
+ }
+
+ // Don't render anything
+ if (!$pusher_links && !$user_links) {
+ return null;
+ }
+
+ $links = array_merge($pusher_links, $user_links);
+ if ($links) {
+ $markup = $links;
+ } else {
+ $markup = array('&nbsp;');
+ }
+
+ // Stick an arrow up front
+ $arrow_class = 'arrow '.$render_intent;
+ array_unshift($markup, phutil_tag(
+ 'div',
+ array(
+ 'class' => $arrow_class,
+ ),
+ ''));
+
+ return phutil_tag(
+ 'div',
+ array(
+ 'class' => 'intents',
+ ),
+ $markup);
+ }
+
+
+}
diff --git a/src/applications/releeph/view/request/ReleephRequestStatusView.php b/src/applications/releeph/view/request/ReleephRequestStatusView.php
new file mode 100644
index 0000000000..4076f037f6
--- /dev/null
+++ b/src/applications/releeph/view/request/ReleephRequestStatusView.php
@@ -0,0 +1,53 @@
+<?php
+
+final class ReleephRequestStatusView extends AphrontView {
+
+ private $releephRequest;
+
+ public function setReleephRequest(ReleephRequest $rq) {
+ $this->releephRequest = $rq;
+ return $this;
+ }
+
+ public function render() {
+ require_celerity_resource('releeph-status');
+
+ $request = $this->releephRequest;
+ $status = $request->getStatus();
+ $pick_status = $request->getPickStatus();
+
+ $description = ReleephRequest::getStatusDescriptionFor($status);
+
+ $warning = null;
+
+ if ($status == ReleephRequest::STATUS_NEEDS_PICK) {
+ if ($pick_status == ReleephRequest::PICK_FAILED) {
+ $warning = 'Last pick failed!';
+ }
+ } elseif ($status == ReleephRequest::STATUS_NEEDS_REVERT) {
+ if ($pick_status == ReleephRequest::REVERT_FAILED) {
+ $warning = 'Last revert failed!';
+ }
+ }
+
+ return phutil_tag(
+ 'div',
+ array(
+ 'class' => 'releeph-status',
+ ),
+ array(
+ phutil_tag(
+ 'div',
+ array(
+ 'class' => 'description',
+ ),
+ $description),
+ phutil_tag(
+ 'div',
+ array(
+ 'class' => 'warning',
+ ),
+ $warning)));
+ }
+
+}
diff --git a/src/applications/releeph/view/request/ReleephRequestTypeaheadControl.php b/src/applications/releeph/view/request/ReleephRequestTypeaheadControl.php
new file mode 100644
index 0000000000..a6f0355fd0
--- /dev/null
+++ b/src/applications/releeph/view/request/ReleephRequestTypeaheadControl.php
@@ -0,0 +1,58 @@
+<?php
+
+final class ReleephRequestTypeaheadControl extends AphrontFormControl {
+
+ private $repo;
+ private $startTime;
+
+ public function setRepo(PhabricatorRepository $repo) {
+ $this->repo = $repo;
+ return $this;
+ }
+
+ public function setStartTime($epoch) {
+ $this->startTime = $epoch;
+ return $this;
+ }
+
+ public function getCustomControlClass() {
+ return 'releeph-request-typeahead';
+ }
+
+ public function renderInput() {
+ $id = celerity_generate_unique_node_id();
+
+ $div = phutil_tag(
+ 'div',
+ array(
+ 'style' => 'position: relative;',
+ 'id' => $id,
+ ),
+ phutil_tag(
+ 'input',
+ array(
+ 'autocomplete' => 'off',
+ 'type' => 'text',
+ 'name' => $this->getName(),
+ ),
+ ''));
+
+ require_celerity_resource('releeph-request-typeahead-css');
+
+ Javelin::initBehavior('releeph-request-typeahead', array(
+ 'id' => $id,
+ 'src' => '/releeph/request/typeahead/',
+ 'placeholder' => 'Type a commit id or first line of commit message...',
+ 'value' => $this->getValue(),
+ 'aux' => array(
+ 'repo' => $this->repo->getID(),
+ 'callsign' => $this->repo->getCallsign(),
+ 'since' => $this->startTime,
+ 'limit' => 16,
+ )
+ ));
+
+ return $div;
+ }
+
+}
diff --git a/src/applications/releeph/view/request/header/ReleephRequestHeaderListView.php b/src/applications/releeph/view/request/header/ReleephRequestHeaderListView.php
new file mode 100644
index 0000000000..98dd9d44b2
--- /dev/null
+++ b/src/applications/releeph/view/request/header/ReleephRequestHeaderListView.php
@@ -0,0 +1,113 @@
+<?php
+
+final class ReleephRequestHeaderListView
+ extends AphrontView {
+
+ private $originType;
+ private $releephProject;
+ private $releephBranch;
+ private $releephRequests;
+ private $aphrontRequest;
+ private $reload = false;
+
+ private $errors = array();
+
+ public function setOriginType($origin) {
+ $this->originType = $origin;
+ return $this;
+ }
+
+ public function setReleephProject(ReleephProject $rp) {
+ $this->releephProject = $rp;
+ return $this;
+ }
+
+ public function setReleephBranch(ReleephBranch $rb) {
+ $this->releephBranch = $rb;
+ return $this;
+ }
+
+ public function setReleephRequests(array $requests) {
+ assert_instances_of($requests, 'ReleephRequest');
+ $this->releephRequests = $requests;
+ return $this;
+ }
+
+ public function setAphrontRequest(AphrontRequest $request) {
+ $this->aphrontRequest = $request;
+ return $this;
+ }
+
+ public function setReloadOnStateChange($bool) {
+ $this->reload = $bool;
+ return $this;
+ }
+
+ public function render() {
+ $views = $this->renderInner();
+ require_celerity_resource('phabricator-notification-css');
+ Javelin::initBehavior('releeph-request-state-change', array(
+ 'reload' => $this->reload,
+ ));
+
+ $error_view = null;
+ if ($this->errors) {
+ $error_view = id(new AphrontErrorView())
+ ->setTitle('Bulk load errors')
+ ->setSeverity(AphrontErrorView::SEVERITY_WARNING)
+ ->setErrors($this->errors)
+ ->render();
+ }
+
+ $list = phutil_tag(
+ 'div',
+ array(
+ 'data-sigil' => 'releeph-request-header-list',
+ ),
+ $views);
+
+ return $this->renderSingleView(array(
+ $error_view,
+ $list));
+ }
+
+ /**
+ * Required for generating markup for ReleephRequestActionController.
+ *
+ * That controller just needs the markup, and doesn't need to start the
+ * javelin behavior.
+ */
+ public function renderInner() {
+ $selector = $this->releephProject->getReleephFieldSelector();
+ $fields = $selector->getFieldSpecifications();
+ foreach ($fields as $field) {
+ $field
+ ->setReleephProject($this->releephProject)
+ ->setReleephBranch($this->releephBranch)
+ ->setUser($this->user);
+ try {
+ $field->bulkLoad($this->releephRequests);
+ } catch (Exception $ex) {
+ $this->errors[] = $ex;
+ }
+ }
+
+ $field_groups = $selector->arrangeFieldsForHeaderView($fields);
+
+ $views = array();
+ foreach ($this->releephRequests as $releeph_request) {
+ $views[] = id(new ReleephRequestHeaderView())
+ ->setUser($this->user)
+ ->setAphrontRequest($this->aphrontRequest)
+ ->setOriginType($this->originType)
+ ->setReleephProject($this->releephProject)
+ ->setReleephBranch($this->releephBranch)
+ ->setReleephRequest($releeph_request)
+ ->setReleephFieldGroups($field_groups)
+ ->render();
+ }
+
+ return $views;
+ }
+
+}
diff --git a/src/applications/releeph/view/request/header/ReleephRequestHeaderView.php b/src/applications/releeph/view/request/header/ReleephRequestHeaderView.php
new file mode 100644
index 0000000000..87753e5b8a
--- /dev/null
+++ b/src/applications/releeph/view/request/header/ReleephRequestHeaderView.php
@@ -0,0 +1,334 @@
+<?php
+
+final class ReleephRequestHeaderView extends AphrontView {
+
+ const THROW_PARAM = '__releeph_throw';
+
+ private $aphrontRequest;
+ private $releephRequest;
+ private $releephBranch;
+ private $releephProject;
+ private $originType;
+ private $fieldGroups;
+
+ public function setAphrontRequest(AphrontRequest $request) {
+ $this->aphrontRequest = $request;
+ return $this;
+ }
+
+ public function setReleephProject(ReleephProject $rp) {
+ $this->releephProject = $rp;
+ return $this;
+ }
+
+ public function setReleephBranch(ReleephBranch $rb) {
+ $this->releephBranch = $rb;
+ return $this;
+ }
+
+ public function setReleephRequest(ReleephRequest $rr) {
+ $this->releephRequest = $rr;
+ return $this;
+ }
+
+ public function setOriginType($origin) {
+ // For the Edit controller
+ $this->originType = $origin;
+ return $this;
+ }
+
+ public function setReleephFieldGroups(array $field_groups) {
+ $this->fieldGroups = $field_groups;
+ return $this;
+ }
+
+ protected function getOrigin() {
+ return $this->originType;
+ }
+
+ public function render() {
+ require_celerity_resource('releeph-core');
+ $all_properties_table = $this->renderFields();
+
+ require_celerity_resource('releeph-colors');
+ $status = $this->releephRequest->getStatus();
+ $rr_div_class =
+ 'releeph-request-header '.
+ 'releeph-request-header-border '.
+ 'releeph-border-color-'.ReleephRequest::getStatusClassSuffixFor($status);
+
+ $hidden_link = phutil_tag(
+ 'a',
+ array(
+ 'href' => '/RQ'.$this->releephRequest->getID(),
+ 'target' => '_blank',
+ 'data-sigil' => 'hidden-link',
+ ),
+ '');
+
+ $focus_char = phutil_tag(
+ 'div',
+ array(
+ 'class' => 'focus-char',
+ 'data-sigil' => 'focus-char',
+ ),
+ "\xE2\x98\x86");
+
+ $rr_div = phutil_tag(
+ 'div',
+ array(
+ 'data-sigil' => 'releeph-request-header',
+ 'class' => $rr_div_class,
+ ),
+ array(
+ phutil_tag(
+ 'div',
+ array(),
+ array(
+ phutil_tag(
+ 'h1',
+ array(),
+ array(
+ $focus_char,
+ $this->renderTitleLink(),
+ $hidden_link
+ )),
+ $all_properties_table,
+ )),
+ phutil_tag(
+ 'div',
+ array(
+ 'class' => 'button-divider',
+ ),
+ $this->renderActionButtonsTable())));
+
+ return $rr_div;
+ }
+
+ private function renderFields() {
+ $field_row_groups = $this->fieldGroups;
+
+ $trs = array();
+ foreach ($field_row_groups as $field_column_group) {
+ $tds = array();
+ foreach ($field_column_group as $side => $fields) {
+ $rows = array();
+ foreach ($fields as $field) {
+ $rows[] = $this->renderOneField($field);
+ }
+ $pane = phutil_tag(
+ 'table',
+ array(
+ 'class' => 'fields',
+ ),
+ $rows);
+ $tds[] = phutil_tag(
+ 'td',
+ array(
+ 'class' => 'side '.$side,
+ ),
+ $pane);
+ }
+ $trs[] = phutil_tag(
+ 'tr',
+ array(),
+ $tds);
+ }
+
+ return phutil_tag(
+ 'table',
+ array(
+ 'class' => 'panes',
+ ),
+ $trs);
+ }
+
+ private function renderOneField(ReleephFieldSpecification $field) {
+ $field
+ ->setUser($this->user)
+ ->setReleephProject($this->releephProject)
+ ->setReleephBranch($this->releephBranch)
+ ->setReleephRequest($this->releephRequest);
+
+ $label = $field->renderLabelForHeaderView();
+ try {
+ $value = $field->renderValueForHeaderView();
+ } catch (Exception $ex) {
+ if ($this->aphrontRequest->getInt(self::THROW_PARAM)) {
+ throw $ex;
+ } else {
+ $value = $this->renderExceptionIcon($ex);
+ }
+ }
+
+ if ($value) {
+ if (!$label) {
+ return phutil_tag(
+ 'tr',
+ array(),
+ phutil_tag('td', array('colspan' => 2), $value));
+ } else {
+ return phutil_tag(
+ 'tr',
+ array(),
+ array(
+ phutil_tag('th', array(), $label),
+ phutil_tag('td', array(), $value)));
+ }
+ }
+ }
+
+ private function renderExceptionIcon(Exception $ex) {
+ Javelin::initBehavior('phabricator-tooltips');
+ require_celerity_resource('aphront-tooltip-css');
+ $throw_uri = $this
+ ->aphrontRequest
+ ->getRequestURI()
+ ->setQueryParam(self::THROW_PARAM, 1);
+
+ $message = $ex->getMessage();
+ if (!$message) {
+ $message = get_class($ex).' with no message.';
+ }
+
+ return javelin_tag(
+ 'a',
+ array(
+ 'class' => 'releeph-field-error',
+ 'sigil' => 'has-tooltip',
+ 'meta' => array(
+ 'tip' => $message,
+ 'size' => 400,
+ 'align' => 'E',
+ ),
+ 'href' => $throw_uri,
+ ),
+ '!!!');
+ }
+
+ private function renderTitleLink() {
+ $rq_id = $this->releephRequest->getID();
+ $summary = $this->releephRequest->getSummaryForDisplay();
+ return phutil_tag(
+ 'a',
+ array(
+ 'href' => '/RQ'.$rq_id,
+ ),
+ hsprintf(
+ 'RQ%d: %s',
+ $rq_id,
+ $summary));
+ }
+
+ private function renderActionButtonsTable() {
+ $left_buttons = array();
+ $right_buttons = array();
+
+ $user_phid = $this->user->getPHID();
+ $is_pusher = $this->releephProject->isPusherPHID($user_phid);
+ $is_requestor = $this->releephRequest->getRequestUserPHID() === $user_phid;
+
+ $current_intent = idx(
+ $this->releephRequest->getUserIntents(),
+ $this->user->getPHID());
+
+ if ($is_pusher) {
+ $left_buttons[] = $this->renderIntentButton(true, 'Approve', 'green');
+ $left_buttons[] = $this->renderIntentButton(false, 'Reject');
+ } else {
+ if ($is_requestor) {
+ $right_buttons[] = $this->renderIntentButton(true, 'Request');
+ $right_buttons[] = $this->renderIntentButton(false, 'Remove');
+ } else {
+ $right_buttons[] = $this->renderIntentButton(true, 'Want');
+ $right_buttons[] = $this->renderIntentButton(false, 'Pass');
+ }
+ }
+
+ // Allow the pusher to mark a request as manually picked or reverted.
+ if ($is_pusher || $is_requestor) {
+ if ($this->releephRequest->getInBranch()) {
+ $left_buttons[] = $this->renderActionButton(
+ 'Mark Manually Reverted',
+ 'mark-manually-reverted');
+ } else {
+ $left_buttons[] = $this->renderActionButton(
+ 'Mark Manually Picked',
+ 'mark-manually-picked');
+ }
+ }
+
+ $right_buttons[] = phutil_tag(
+ 'a',
+ array(
+ 'href' => '/releeph/request/edit/'.$this->releephRequest->getID().
+ '?origin='.$this->originType,
+ 'class' => 'small blue button',
+ ),
+ 'Edit');
+
+ if (!$left_buttons && !$right_buttons) {
+ return;
+ }
+
+ $cells = array();
+ foreach ($left_buttons as $button) {
+ $cells[] = phutil_tag('td', array('align' => 'left'), $button);
+ }
+ $cells[] = phutil_tag('td', array('class' => 'wide'), '');
+ foreach ($right_buttons as $button) {
+ $cells[] = phutil_tag('td', array('align' => 'right'), $button);
+ }
+
+ $table = phutil_tag(
+ 'table',
+ array(
+ 'class' => 'buttons',
+ ),
+ phutil_tag(
+ 'tr',
+ array(),
+ $cells));
+
+ return $table;
+ }
+
+ private function renderIntentButton($want, $name, $class = null) {
+ $current_intent = idx(
+ $this->releephRequest->getUserIntents(),
+ $this->user->getPHID());
+
+ if ($current_intent) {
+ // If this is a "want" button, and they already want it, disable the
+ // button (and vice versa for the "pass" case.)
+ if (($want && $current_intent == ReleephRequest::INTENT_WANT) ||
+ (!$want && $current_intent == ReleephRequest::INTENT_PASS)) {
+
+ $class .= ' disabled';
+ }
+ }
+
+ $action = $want ? 'want' : 'pass';
+ return $this->renderActionButton($name, $action, $class);
+ }
+
+ private function renderActionButton($name, $action, $class=null) {
+ $attributes = array(
+ 'class' => 'small button '.$class,
+ 'sigil' => 'releeph-request-state-change '.$action,
+ 'meta' => null,
+ );
+
+ if ($class != 'disabled') {
+ // NB the trailing slash on $uri is critical, otherwise the URI will
+ // redirect to one with a slash, which will turn our GET into a POST.
+ $attributes['meta'] = sprintf(
+ '/releeph/request/action/%s/%d/',
+ $action,
+ $this->releephRequest->getID());
+ }
+
+ return javelin_tag('a', $attributes, $name);
+ }
+
+}
diff --git a/src/applications/releeph/view/requestevent/ReleephRequestEventListView.php b/src/applications/releeph/view/requestevent/ReleephRequestEventListView.php
new file mode 100644
index 0000000000..ab0bca7d57
--- /dev/null
+++ b/src/applications/releeph/view/requestevent/ReleephRequestEventListView.php
@@ -0,0 +1,266 @@
+<?php
+
+final class ReleephRequestEventListView extends AphrontView {
+
+ private $events;
+ private $handles;
+
+ public function setEvents(array $events) {
+ assert_instances_of($events, 'ReleephRequestEvent');
+ $this->events = $events;
+ return $this;
+ }
+
+ public function setHandles(array $handles) {
+ assert_instances_of($handles, 'PhabricatorObjectHandle');
+ $this->handles = $handles;
+ return $this;
+ }
+
+ public function render() {
+ $views = array();
+
+ $discovered_commits = array();
+ foreach ($this->events as $event) {
+ $commit_id = $event->getDetail('newCommitIdentifier');
+ switch ($event->getType()) {
+ case ReleephRequestEvent::TYPE_DISCOVERY:
+ $discovered_commits[$commit_id] = true;
+ break;
+ }
+ }
+
+ $markup_engine = PhabricatorMarkupEngine::newDifferentialMarkupEngine();
+ $markup_engine->setConfig('viewer', $this->getUser());
+
+ foreach ($this->events as $event) {
+ $description = $this->describeEvent($event);
+ if (!$description) {
+ continue;
+ }
+
+ if ($event->getType() === ReleephRequestEvent::TYPE_COMMIT) {
+ $commit_id = $event->getDetail('newCommitIdentifier');
+ if (idx($discovered_commits, $commit_id)) {
+ continue;
+ }
+ }
+
+ $actor_handle = $this->handles[$event->getActorPHID()];
+ $description = $this->describeEvent($event);
+ $action = phutil_tag(
+ 'div',
+ array(),
+ array(
+ $actor_handle->renderLink(),
+ ' ',
+ $description));
+
+ $view = id(new PhabricatorTransactionView())
+ ->setUser($this->user)
+ ->setImageURI($actor_handle->getImageURI())
+ ->setEpoch($event->getDateCreated())
+ ->setActions(array($action))
+ ->addClass($this->getTransactionClass($event));
+
+ $comment = $this->getEventComment($event);
+ if ($comment) {
+ $markup = phutil_tag(
+ 'div',
+ array(
+ 'class' => 'phabricator-remarkup',
+ ),
+ phutil_safe_html(
+ $markup_engine->markupText($comment)));
+ $view->appendChild($markup);
+ }
+
+ $views[] = $view;
+ }
+
+ return phutil_tag(
+ 'div',
+ array(
+ 'class' => 'releeph-request-event-list',
+ ),
+ $views);
+ }
+
+ public function renderForEmail() {
+ $items = array();
+ foreach ($this->events as $event) {
+ $description = $this->describeEvent($event);
+ if (!$description) {
+ continue;
+ }
+ $actor = $this->handles[$event->getActorPHID()]->getName();
+ $items[] = $actor.' '.$description;
+
+ $comment = $this->getEventComment($event);
+ if ($comment) {
+ $items[] = preg_replace('/^/m', ' ', $comment);
+ }
+ }
+
+ return implode("\n\n", $items);
+ }
+
+ private function describeEvent(ReleephRequestEvent $event) {
+ $type = $event->getType();
+
+ switch ($type) {
+ case ReleephRequestEvent::TYPE_CREATE:
+ return "created this request.";
+ break;
+
+ case ReleephRequestEvent::TYPE_STATUS:
+ $status = $event->getStatusAfter();
+ return sprintf(
+ "updated status to %s.",
+ ReleephRequest::getStatusDescriptionFor($status));
+ break;
+
+ case ReleephRequestEvent::TYPE_USER_INTENT:
+ $intent = $event->getDetail('newIntent');
+ $was_pusher = $event->getDetail('wasPusher');
+ if ($intent == ReleephRequest::INTENT_WANT) {
+ if ($was_pusher) {
+ $verb = "approved";
+ } else {
+ $verb = "wanted";
+ }
+ } else {
+ if ($was_pusher) {
+ $verb = "rejected";
+ } else {
+ $verb = "passed on";
+ }
+ }
+ return "{$verb} this request.";
+ break;
+
+ case ReleephRequestEvent::TYPE_PICK_STATUS:
+ $pick_status = $event->getDetail('newPickStatus');
+ switch ($pick_status) {
+ case ReleephRequest::PICK_FAILED:
+ return "found a conflict when picking.";
+ break;
+
+ case ReleephRequest::REVERT_FAILED:
+ return "found a conflict when reverting.";
+ break;
+
+ case ReleephRequest::PICK_OK:
+ case ReleephRequest::REVERT_OK:
+ // (nothing)
+ break;
+
+ default:
+ return "changed pick-status to {$pick_status}.";
+ break;
+ }
+ break;
+
+ case ReleephRequestEvent::TYPE_MANUAL_ACTION:
+ $action = $event->getDetail('action');
+ return "claimed to have manually {$action}ed this request.";
+ break;
+
+ case ReleephRequestEvent::TYPE_COMMIT:
+ $action = $event->getDetail('action');
+ if ($action) {
+ return "{$action}ed this request.";
+ } else {
+ return "did something with this request.";
+ }
+ break;
+
+ case ReleephRequestEvent::TYPE_DISCOVERY:
+ $action = $event->getDetail('action');
+ if ($action) {
+ return "{$action}ed this request.";
+ } else {
+ // It's unlikely we'll have action-less TYPE_DISCOVERY events, but I
+ // used this during testing and I guess it's a useful safety net.
+ return "discovered this request in the branch.";
+ }
+ break;
+
+ case ReleephRequestEvent::TYPE_COMMENT:
+ return "commented on this request.";
+ break;
+
+ default:
+ return "did event of type {$type}.";
+ break;
+ }
+ }
+
+ private function getEventComment(ReleephRequestEvent $event) {
+ switch ($event->getType()) {
+ case ReleephRequestEvent::TYPE_CREATE:
+ $commit_phid = $event->getDetail('commitPHID');
+ return sprintf(
+ "Commit %s was requested.",
+ $this->handles[$commit_phid]->getName());
+ break;
+
+ case ReleephRequestEvent::TYPE_STATUS:
+ case ReleephRequestEvent::TYPE_USER_INTENT:
+ case ReleephRequestEvent::TYPE_PICK_STATUS:
+ case ReleephRequestEvent::TYPE_MANUAL_ACTION:
+ // no comment!
+ break;
+
+ case ReleephRequestEvent::TYPE_COMMIT:
+ return sprintf(
+ "Closed by commit %s.",
+ $event->getDetail('newCommitIdentifier'));
+ break;
+
+ case ReleephRequestEvent::TYPE_DISCOVERY:
+ $author_phid = $event->getDetail('authorPHID');
+ $commit_phid = $event->getDetail('newCommitPHID');
+ if ($author_phid && $author_phid != $event->getActorPHID()) {
+ return sprintf(
+ "Closed by commit %s (with author set to @%s).",
+ $this->handles[$commit_phid]->getName(),
+ $this->handles[$author_phid]->getName());
+ } else {
+ return sprintf(
+ 'Closed by commit %s.',
+ $this->handles[$commit_phid]->getName());
+ }
+ break;
+
+ case ReleephRequestEvent::TYPE_COMMENT:
+ return $event->getComment();
+ break;
+ }
+ }
+
+ private function getTransactionClass($event) {
+ switch ($event->getType()) {
+ case ReleephRequestEvent::TYPE_COMMIT:
+ case ReleephRequestEvent::TYPE_DISCOVERY:
+ $action = $event->getDetail('action');
+ if ($action == 'pick') {
+ return 'releeph-border-color-picked';
+ } else {
+ return 'releeph-border-color-abandoned';
+ }
+ break;
+
+ case ReleephRequestEvent::TYPE_COMMENT:
+ return 'releeph-border-color-comment';
+ break;
+
+ default:
+ $status_after = $event->getStatusAfter();
+ $class_suffix = ReleephRequest::getStatusClassSuffixFor($status_after);
+ return ' releeph-border-color-'.$class_suffix;
+ break;
+ }
+ }
+
+}
diff --git a/src/applications/releeph/view/user/ReleephDefaultUserView.php b/src/applications/releeph/view/user/ReleephDefaultUserView.php
new file mode 100644
index 0000000000..93819cdad3
--- /dev/null
+++ b/src/applications/releeph/view/user/ReleephDefaultUserView.php
@@ -0,0 +1,9 @@
+<?php
+
+final class ReleephDefaultUserView extends ReleephUserView {
+
+ public function render() {
+ return $this->getHandle()->renderLink();
+ }
+
+}
diff --git a/src/applications/releeph/view/user/ReleephUserView.php b/src/applications/releeph/view/user/ReleephUserView.php
new file mode 100644
index 0000000000..129c846bac
--- /dev/null
+++ b/src/applications/releeph/view/user/ReleephUserView.php
@@ -0,0 +1,74 @@
+<?php
+
+abstract class ReleephUserView extends AphrontView {
+
+ /**
+ * This function should bulk load everything you need to render all the given
+ * user phids.
+ *
+ * Many parts of Releeph load users for rendering. Accordingly, this
+ * function will be called multiple times for each part of the UI that
+ * renders users, so you should accumulate your results on each call.
+ *
+ * You should also implement render() (from AphrontView) to render each
+ * user's PHID.
+ */
+ protected function loadInner(array $phids) {
+ // This is a hook!
+ }
+
+ final public static function getNewInstance() {
+ $key = 'releeph.user-view';
+ $class = PhabricatorEnv::getEnvConfig($key);
+ return newv($class, array());
+ }
+
+ private static $handles = array();
+ private static $seen = array();
+
+ final public function load(array $phids) {
+ $todo = array();
+
+ foreach ($phids as $key => $phid) {
+ if (!idx(self::$seen, $phid)) {
+ $todo[$key] = $phid;
+ self::$seen[$phid] = true;
+ }
+ }
+
+ if ($todo) {
+ self::$handles = array_merge(
+ self::$handles,
+ id(new PhabricatorObjectHandleData($todo))
+ ->setViewer($this->getUser())
+ ->loadHandles());
+ $this->loadInner($todo);
+ }
+ }
+
+ private $phid;
+ private $releephProject;
+
+ final public function setRenderUserPHID($phid) {
+ $this->phid = $phid;
+ return $this;
+ }
+
+ final public function setReleephProject(ReleephProject $project) {
+ $this->releephProject = $project;
+ return $this;
+ }
+
+ final protected function getRenderUserPHID() {
+ return $this->phid;
+ }
+
+ final protected function getReleephProject() {
+ return $this->releephProject;
+ }
+
+ final protected function getHandle() {
+ return self::$handles[$this->phid];
+ }
+
+}
diff --git a/src/infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php b/src/infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php
index 743be93d34..6cf673a379 100644
--- a/src/infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php
+++ b/src/infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php
@@ -1,292 +1,298 @@
<?php
abstract class PhabricatorBaseEnglishTranslation
extends PhabricatorTranslation {
final public function getLanguage() {
return 'en';
}
public function getTranslations() {
return array(
'Differential Revision(s)' => array(
'Differential Revision',
'Differential Revisions',
),
'file(s)' => array('file', 'files'),
'Maniphest Task(s)' => array('Maniphest Task', 'Maniphest Tasks'),
'Please fix these errors and try again.' => array(
'Please fix this error and try again.',
'Please fix these errors and try again.',
),
'%d Error(s)' => array('%d Error', '%d Errors'),
'%d Warning(s)' => array('%d Warning', '%d Warnings'),
'%d Auto-Fix(es)' => array('%d Auto-Fix', '%d Auto-Fixes'),
'%d Advice(s)' => array('%d Advice', '%d Pieces of Advice'),
'%d Detail(s)' => array('%d Detail', '%d Details'),
'(%d line(s))' => array('(%d line)', '(%d lines)'),
'COMMIT(S)' => array('COMMIT', 'COMMITS'),
'%d line(s)' => array('%d line', '%d lines'),
+ '%d path(s)' => array('%d path', '%d paths'),
+ '%d diff(s)' => array('%d diff', '%d diffs'),
'added %d commit(s): %s' => array(
'added commit: %2$s',
'added commits: %2$s',
),
'removed %d commit(s): %s' => array(
'removed commit: %2$s',
'removed commits: %2$s',
),
'changed %d commit(s), added %d: %s; removed %d: %s' =>
'changed commits, added: %3$s; removed: %5$s',
'ATTACHED %d COMMIT(S)' => array(
'ATTACHED COMMIT',
'ATTACHED COMMITS',
),
'added %d dependencie(s): %s' => array(
'added dependency: %2$s',
'added dependencies: %2$s',
),
'added %d dependent task(s): %s' => array(
'added dependent task: %2$s',
'added dependent tasks: %2$s',
),
'removed %d dependencie(s): %s' => array(
'removed dependency: %2$s',
'removed dependencies: %2$s',
),
'removed %d dependent task(s): %s' => array(
'removed dependent task: %2$s',
'removed dependent tasks: %2$s',
),
'changed %d dependencie(s), added %d: %s; removed %d: %s' =>
'changed dependencies, added: %3$s; removed: %5$s',
'changed %d dependent task(s), added %d: %s; removed %d: %s',
'changed dependent tasks, added: %3$s; removed: %5$s',
'DEPENDENT %d TASK(s)' => array(
'DEPENDENT TASK',
'DEPENDENT TASKS',
),
'DEPENDS ON %d TASK(S)' => array(
'DEPENDS ON TASK',
'DEPENDS ON TASKS',
),
'DIFFERENTIAL %d REVISION(S)' => array(
'DIFFERENTIAL REVISION',
'DIFFERENTIAL REVISIONS',
),
'added %d revision(s): %s' => array(
'added revision: %2$s',
'added revisions: %2$s',
),
'removed %d revision(s): %s' => array(
'removed revision: %2$s',
'removed revisions: %2$s',
),
'changed %d revision(s), added %d: %s; removed %d: %s' =>
'changed revisions, added %3$s; removed %5$s',
'There are %d raw fact(s) in storage.' => array(
'There is %d raw fact in storage.',
'There are %d raw facts in storage.',
),
'There are %d aggregate fact(s) in storage.' => array(
'There is %d aggregate fact in storage.',
'There are %d aggregate facts in storage.',
),
'%d Commit(s) Awaiting Audit' => array(
'%d Commit Awaiting Audit',
'%d Commits Awaiting Audit',
),
'%d Problem Commit(s)' => array(
'%d Problem Commit',
'%d Problem Commits',
),
'%d Review(s) Blocking Others' => array(
'%d Review Blocking Others',
'%d Reviews Blocking Others',
),
'%d Review(s) Need Attention' => array(
'%d Review Needs Attention',
'%d Reviews Need Attention',
),
'%d Review(s) Waiting on Others' => array(
'%d Review Waiting on Others',
'%d Reviews Waiting on Others',
),
'%d Flagged Object(s)' => array(
'%d Flagged Object',
'%d Flagged Objects',
),
'%d Unbreak Now Task(s)!' => array(
'%d Unbreak Now Task!',
'%d Unbreak Now Tasks!',
),
'%d Assigned Task(s)' => array(
'%d Assigned Task',
'%d Assigned Tasks',
),
'Show %d Lint Message(s)' => array(
'Show %d Lint Message',
'Show %d Lint Messages',
),
'Hide %d Lint Message(s)' => array(
'Hide %d Lint Message',
'Hide %d Lint Messages',
),
'Switch for %d Lint Message(s)' => array(
'Switch for %d Lint Message',
'Switch for %d Lint Messages',
),
'%d Lint Message(s)' => array(
'%d Lint Message',
'%d Lint Messages',
),
'This is a binary file. It is %s byte(s) in length.' => array(
'This is a binary file. It is %s byte in length.',
'This is a binary file. It is %s bytes in length.',
),
'%d Action(s) Have No Effect' => array(
'Action Has No Effect',
'Actions Have No Effect',
),
'%d Action(s) With No Effect' => array(
'Action With No Effect',
'Actions With No Effect',
),
'%s added %d subscriber(s): %s.' => array(
array(
'%s added a subscriber: %3$s.',
'%s added subscribers: %3$s.',
),
),
'%s removed %d subscriber(s): %s.' => array(
array(
'%s removed a subscriber: %3$s.',
'%s removed subscribers: %3$s.',
),
),
'%s added %d participant(s): %s.' => array(
array(
'%s added a participant: %3$s.',
'%s added participants: %3$s.',
),
),
'%s removed %d participant(s): %s.' => array(
array(
'%s removed a participant: %3$s.',
'%s removed participants: %3$s.',
),
),
'%s Line(s)' => array(
'%s Line',
'%s Lines',
),
"Indexing %d object(s) of type %s." => array(
"Indexing %d object of type %s.",
"Indexing %d object of type %s.",
),
'Run these %d command(s):' => array(
'Run this command:',
'Run these commands:',
),
'Install these %d PHP extension(s):' => array(
'Install this PHP extension:',
'Install these PHP extensions:',
),
'The current Phabricator configuration has these %d value(s):' => array(
'The current Phabricator configuration has this value:',
'The current Phabricator configuration has these values:',
),
'To update these %d value(s), run these command(s) from the command line:'
=> array(
'To update this value, run this command from the command line:',
'To update these values, run these commands from the command line:',
),
'You can update these %d value(s) here:' => array(
'You can update this value here:',
'You can update these values here:',
),
'The current PHP configuration has these %d value(s):' => array(
'The current PHP configuration has this value:',
'The current PHP configuration has these values:',
),
'To update these %d value(s), edit your PHP configuration file.' => array(
'To update this %d value, edit your PHP configuration file.',
'To update these %d values, edit your PHP configuration file.',
),
'To update these %d value(s), edit your PHP configuration file, located '.
'here:' => array(
'To update this value, edit your PHP configuration file, located '.
'here:',
'To update these values, edit your PHP configuration file, located '.
'here:',
),
'PHP also loaded these configuration file(s):' => array(
'PHP also loaded this configuration file:',
'PHP also loaded these configuration files:',
),
'You have %d unresolved setup issue(s)...' => array(
'You have an unresolved setup issue...',
'You have %d unresolved setup issues...',
),
'%s added %d inline comment(s).' => array(
array(
'%s added an inline comment.',
'%s added inline comments.',
),
),
+ '%d comment(s)' => array('%d comment', '%d comments'),
+ '%d rejection(s)' => array('%d rejection', '%d rejections'),
+ '%d update(s)' => array('%d update', '%d updates'),
+
);
}
}
diff --git a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
index 2d4d5ec191..7a3a96fb7e 100644
--- a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
+++ b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
@@ -1,1171 +1,1179 @@
<?php
final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList {
public function getNamespace() {
return 'phabricator';
}
private function getPatchPath($file) {
$root = dirname(phutil_get_library_root('phabricator'));
$path = $root.'/resources/sql/patches/'.$file;
// Make sure it exists.
Filesystem::readFile($path);
return $path;
}
public function getPatches() {
return array(
'db.audit' => array(
'type' => 'db',
'name' => 'audit',
'after' => array( /* First Patch */ ),
),
'db.calendar' => array(
'type' => 'db',
'name' => 'calendar',
),
'db.chatlog' => array(
'type' => 'db',
'name' => 'chatlog',
),
'db.conduit' => array(
'type' => 'db',
'name' => 'conduit',
),
'db.countdown' => array(
'type' => 'db',
'name' => 'countdown',
),
'db.daemon' => array(
'type' => 'db',
'name' => 'daemon',
),
'db.differential' => array(
'type' => 'db',
'name' => 'differential',
),
'db.draft' => array(
'type' => 'db',
'name' => 'draft',
),
'db.drydock' => array(
'type' => 'db',
'name' => 'drydock',
),
'db.feed' => array(
'type' => 'db',
'name' => 'feed',
),
'db.file' => array(
'type' => 'db',
'name' => 'file',
),
'db.flag' => array(
'type' => 'db',
'name' => 'flag',
),
'db.harbormaster' => array(
'type' => 'db',
'name' => 'harbormaster',
),
'db.herald' => array(
'type' => 'db',
'name' => 'herald',
),
'db.maniphest' => array(
'type' => 'db',
'name' => 'maniphest',
),
'db.meta_data' => array(
'type' => 'db',
'name' => 'meta_data',
),
'db.metamta' => array(
'type' => 'db',
'name' => 'metamta',
),
'db.oauth_server' => array(
'type' => 'db',
'name' => 'oauth_server',
),
'db.owners' => array(
'type' => 'db',
'name' => 'owners',
),
'db.pastebin' => array(
'type' => 'db',
'name' => 'pastebin',
),
'db.phame' => array(
'type' => 'db',
'name' => 'phame',
),
'db.phriction' => array(
'type' => 'db',
'name' => 'phriction',
),
'db.project' => array(
'type' => 'db',
'name' => 'project',
),
'db.repository' => array(
'type' => 'db',
'name' => 'repository',
),
'db.search' => array(
'type' => 'db',
'name' => 'search',
),
'db.slowvote' => array(
'type' => 'db',
'name' => 'slowvote',
),
'db.timeline' => array(
'type' => 'db',
'name' => 'timeline',
),
'db.user' => array(
'type' => 'db',
'name' => 'user',
),
'db.worker' => array(
'type' => 'db',
'name' => 'worker',
),
'db.xhpastview' => array(
'type' => 'db',
'name' => 'xhpastview',
),
'db.cache' => array(
'type' => 'db',
'name' => 'cache',
),
'db.fact' => array(
'type' => 'db',
'name' => 'fact',
),
'db.ponder' => array(
'type' => 'db',
'name' => 'ponder',
),
'db.xhprof' => array(
'type' => 'db',
'name' => 'xhprof',
),
'db.pholio' => array(
'type' => 'db',
'name' => 'pholio',
),
'db.conpherence' => array(
'type' => 'db',
'name' => 'conpherence',
),
'db.config' => array(
'type' => 'db',
'name' => 'config',
),
'db.token' => array(
'type' => 'db',
'name' => 'token',
),
+ 'db.releeph' => array(
+ 'type' => 'db',
+ 'name' => 'releeph',
+ ),
'0000.legacy.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('0000.legacy.sql'),
'legacy' => 0,
),
'000.project.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('000.project.sql'),
'legacy' => 0,
),
'001.maniphest_projects.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('001.maniphest_projects.sql'),
'legacy' => 1,
),
'002.oauth.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('002.oauth.sql'),
'legacy' => 2,
),
'003.more_oauth.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('003.more_oauth.sql'),
'legacy' => 3,
),
'004.daemonrepos.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('004.daemonrepos.sql'),
'legacy' => 4,
),
'005.workers.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('005.workers.sql'),
'legacy' => 5,
),
'006.repository.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('006.repository.sql'),
'legacy' => 6,
),
'007.daemonlog.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('007.daemonlog.sql'),
'legacy' => 7,
),
'008.repoopt.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('008.repoopt.sql'),
'legacy' => 8,
),
'009.repo_summary.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('009.repo_summary.sql'),
'legacy' => 9,
),
'010.herald.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('010.herald.sql'),
'legacy' => 10,
),
'011.badcommit.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('011.badcommit.sql'),
'legacy' => 11,
),
'012.dropphidtype.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('012.dropphidtype.sql'),
'legacy' => 12,
),
'013.commitdetail.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('013.commitdetail.sql'),
'legacy' => 13,
),
'014.shortcuts.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('014.shortcuts.sql'),
'legacy' => 14,
),
'015.preferences.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('015.preferences.sql'),
'legacy' => 15,
),
'016.userrealnameindex.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('016.userrealnameindex.sql'),
'legacy' => 16,
),
'017.sessionkeys.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('017.sessionkeys.sql'),
'legacy' => 17,
),
'018.owners.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('018.owners.sql'),
'legacy' => 18,
),
'019.arcprojects.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('019.arcprojects.sql'),
'legacy' => 19,
),
'020.pathcapital.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('020.pathcapital.sql'),
'legacy' => 20,
),
'021.xhpastview.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('021.xhpastview.sql'),
'legacy' => 21,
),
'022.differentialcommit.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('022.differentialcommit.sql'),
'legacy' => 22,
),
'023.dxkeys.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('023.dxkeys.sql'),
'legacy' => 23,
),
'024.mlistkeys.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('024.mlistkeys.sql'),
'legacy' => 24,
),
'025.commentopt.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('025.commentopt.sql'),
'legacy' => 25,
),
'026.diffpropkey.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('026.diffpropkey.sql'),
'legacy' => 26,
),
'027.metamtakeys.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('027.metamtakeys.sql'),
'legacy' => 27,
),
'028.systemagent.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('028.systemagent.sql'),
'legacy' => 28,
),
'029.cursors.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('029.cursors.sql'),
'legacy' => 29,
),
'030.imagemacro.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('030.imagemacro.sql'),
'legacy' => 30,
),
'031.workerrace.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('031.workerrace.sql'),
'legacy' => 31,
),
'032.viewtime.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('032.viewtime.sql'),
'legacy' => 32,
),
'033.privtest.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('033.privtest.sql'),
'legacy' => 33,
),
'034.savedheader.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('034.savedheader.sql'),
'legacy' => 34,
),
'035.proxyimage.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('035.proxyimage.sql'),
'legacy' => 35,
),
'036.mailkey.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('036.mailkey.sql'),
'legacy' => 36,
),
'037.setuptest.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('037.setuptest.sql'),
'legacy' => 37,
),
'038.admin.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('038.admin.sql'),
'legacy' => 38,
),
'039.userlog.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('039.userlog.sql'),
'legacy' => 39,
),
'040.transform.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('040.transform.sql'),
'legacy' => 40,
),
'041.heraldrepetition.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('041.heraldrepetition.sql'),
'legacy' => 41,
),
'042.commentmetadata.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('042.commentmetadata.sql'),
'legacy' => 42,
),
'043.pastebin.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('043.pastebin.sql'),
'legacy' => 43,
),
'044.countdown.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('044.countdown.sql'),
'legacy' => 44,
),
'045.timezone.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('045.timezone.sql'),
'legacy' => 45,
),
'046.conduittoken.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('046.conduittoken.sql'),
'legacy' => 46,
),
'047.projectstatus.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('047.projectstatus.sql'),
'legacy' => 47,
),
'048.relationshipkeys.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('048.relationshipkeys.sql'),
'legacy' => 48,
),
'049.projectowner.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('049.projectowner.sql'),
'legacy' => 49,
),
'050.taskdenormal.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('050.taskdenormal.sql'),
'legacy' => 50,
),
'051.projectfilter.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('051.projectfilter.sql'),
'legacy' => 51,
),
'052.pastelanguage.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('052.pastelanguage.sql'),
'legacy' => 52,
),
'053.feed.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('053.feed.sql'),
'legacy' => 53,
),
'054.subscribers.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('054.subscribers.sql'),
'legacy' => 54,
),
'055.add_author_to_files.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('055.add_author_to_files.sql'),
'legacy' => 55,
),
'056.slowvote.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('056.slowvote.sql'),
'legacy' => 56,
),
'057.parsecache.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('057.parsecache.sql'),
'legacy' => 57,
),
'058.missingkeys.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('058.missingkeys.sql'),
'legacy' => 58,
),
'059.engines.php' => array(
'type' => 'php',
'name' => $this->getPatchPath('059.engines.php'),
'legacy' => 59,
),
'060.phriction.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('060.phriction.sql'),
'legacy' => 60,
),
'061.phrictioncontent.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('061.phrictioncontent.sql'),
'legacy' => 61,
),
'062.phrictionmenu.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('062.phrictionmenu.sql'),
'legacy' => 62,
),
'063.pasteforks.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('063.pasteforks.sql'),
'legacy' => 63,
),
'064.subprojects.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('064.subprojects.sql'),
'legacy' => 64,
),
'065.sshkeys.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('065.sshkeys.sql'),
'legacy' => 65,
),
'066.phrictioncontent.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('066.phrictioncontent.sql'),
'legacy' => 66,
),
'067.preferences.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('067.preferences.sql'),
'legacy' => 67,
),
'068.maniphestauxiliarystorage.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('068.maniphestauxiliarystorage.sql'),
'legacy' => 68,
),
'069.heraldxscript.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('069.heraldxscript.sql'),
'legacy' => 69,
),
'070.differentialaux.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('070.differentialaux.sql'),
'legacy' => 70,
),
'071.contentsource.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('071.contentsource.sql'),
'legacy' => 71,
),
'072.blamerevert.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('072.blamerevert.sql'),
'legacy' => 72,
),
'073.reposymbols.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('073.reposymbols.sql'),
'legacy' => 73,
),
'074.affectedpath.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('074.affectedpath.sql'),
'legacy' => 74,
),
'075.revisionhash.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('075.revisionhash.sql'),
'legacy' => 75,
),
'076.indexedlanguages.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('076.indexedlanguages.sql'),
'legacy' => 76,
),
'077.originalemail.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('077.originalemail.sql'),
'legacy' => 77,
),
'078.nametoken.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('078.nametoken.sql'),
'legacy' => 78,
),
'079.nametokenindex.php' => array(
'type' => 'php',
'name' => $this->getPatchPath('079.nametokenindex.php'),
'legacy' => 79,
),
'080.filekeys.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('080.filekeys.sql'),
'legacy' => 80,
),
'081.filekeys.php' => array(
'type' => 'php',
'name' => $this->getPatchPath('081.filekeys.php'),
'legacy' => 81,
),
'082.xactionkey.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('082.xactionkey.sql'),
'legacy' => 82,
),
'083.dxviewtime.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('083.dxviewtime.sql'),
'legacy' => 83,
),
'084.pasteauthorkey.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('084.pasteauthorkey.sql'),
'legacy' => 84,
),
'085.packagecommitrelationship.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('085.packagecommitrelationship.sql'),
'legacy' => 85,
),
'086.formeraffil.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('086.formeraffil.sql'),
'legacy' => 86,
),
'087.phrictiondelete.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('087.phrictiondelete.sql'),
'legacy' => 87,
),
'088.audit.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('088.audit.sql'),
'legacy' => 88,
),
'089.projectwiki.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('089.projectwiki.sql'),
'legacy' => 89,
),
'090.forceuniqueprojectnames.php' => array(
'type' => 'php',
'name' => $this->getPatchPath('090.forceuniqueprojectnames.php'),
'legacy' => 90,
),
'091.uniqueslugkey.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('091.uniqueslugkey.sql'),
'legacy' => 91,
),
'092.dropgithubnotification.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('092.dropgithubnotification.sql'),
'legacy' => 92,
),
'093.gitremotes.php' => array(
'type' => 'php',
'name' => $this->getPatchPath('093.gitremotes.php'),
'legacy' => 93,
),
'094.phrictioncolumn.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('094.phrictioncolumn.sql'),
'legacy' => 94,
),
'095.directory.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('095.directory.sql'),
'legacy' => 95,
),
'096.filename.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('096.filename.sql'),
'legacy' => 96,
),
'097.heraldruletypes.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('097.heraldruletypes.sql'),
'legacy' => 97,
),
'098.heraldruletypemigration.php' => array(
'type' => 'php',
'name' => $this->getPatchPath('098.heraldruletypemigration.php'),
'legacy' => 98,
),
'099.drydock.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('099.drydock.sql'),
'legacy' => 99,
),
'100.projectxaction.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('100.projectxaction.sql'),
'legacy' => 100,
),
'101.heraldruleapplied.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('101.heraldruleapplied.sql'),
'legacy' => 101,
),
'102.heraldcleanup.php' => array(
'type' => 'php',
'name' => $this->getPatchPath('102.heraldcleanup.php'),
'legacy' => 102,
),
'103.heraldedithistory.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('103.heraldedithistory.sql'),
'legacy' => 103,
),
'104.searchkey.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('104.searchkey.sql'),
'legacy' => 104,
),
'105.mimetype.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('105.mimetype.sql'),
'legacy' => 105,
),
'106.chatlog.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('106.chatlog.sql'),
'legacy' => 106,
),
'107.oauthserver.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('107.oauthserver.sql'),
'legacy' => 107,
),
'108.oauthscope.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('108.oauthscope.sql'),
'legacy' => 108,
),
'109.oauthclientphidkey.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('109.oauthclientphidkey.sql'),
'legacy' => 109,
),
'110.commitaudit.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('110.commitaudit.sql'),
'legacy' => 110,
),
'111.commitauditmigration.php' => array(
'type' => 'php',
'name' => $this->getPatchPath('111.commitauditmigration.php'),
'legacy' => 111,
),
'112.oauthaccesscoderedirecturi.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('112.oauthaccesscoderedirecturi.sql'),
'legacy' => 112,
),
'113.lastreviewer.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('113.lastreviewer.sql'),
'legacy' => 113,
),
'114.auditrequest.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('114.auditrequest.sql'),
'legacy' => 114,
),
'115.prepareutf8.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('115.prepareutf8.sql'),
'legacy' => 115,
),
'116.utf8-backup-first-expect-wait.sql' => array(
'type' => 'sql',
'name' =>
$this->getPatchPath('116.utf8-backup-first-expect-wait.sql'),
'legacy' => 116,
),
'117.repositorydescription.php' => array(
'type' => 'php',
'name' => $this->getPatchPath('117.repositorydescription.php'),
'legacy' => 117,
),
'118.auditinline.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('118.auditinline.sql'),
'legacy' => 118,
),
'119.filehash.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('119.filehash.sql'),
'legacy' => 119,
),
'120.noop.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('120.noop.sql'),
'legacy' => 120,
),
'121.drydocklog.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('121.drydocklog.sql'),
'legacy' => 121,
),
'122.flag.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('122.flag.sql'),
'legacy' => 122,
),
'123.heraldrulelog.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('123.heraldrulelog.sql'),
'legacy' => 123,
),
'124.subpriority.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('124.subpriority.sql'),
'legacy' => 124,
),
'125.ipv6.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('125.ipv6.sql'),
'legacy' => 125,
),
'126.edges.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('126.edges.sql'),
'legacy' => 126,
),
'127.userkeybody.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('127.userkeybody.sql'),
'legacy' => 127,
),
'128.phabricatorcom.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('128.phabricatorcom.sql'),
'legacy' => 128,
),
'129.savedquery.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('129.savedquery.sql'),
'legacy' => 129,
),
'130.denormalrevisionquery.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('130.denormalrevisionquery.sql'),
'legacy' => 130,
),
'131.migraterevisionquery.php' => array(
'type' => 'php',
'name' => $this->getPatchPath('131.migraterevisionquery.php'),
'legacy' => 131,
),
'132.phame.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('132.phame.sql'),
'legacy' => 132,
),
'133.imagemacro.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('133.imagemacro.sql'),
'legacy' => 133,
),
'134.emptysearch.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('134.emptysearch.sql'),
'legacy' => 134,
),
'135.datecommitted.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('135.datecommitted.sql'),
'legacy' => 135,
),
'136.sex.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('136.sex.sql'),
'legacy' => 136,
),
'137.auditmetadata.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('137.auditmetadata.sql'),
'legacy' => 137,
),
'138.notification.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('138.notification.sql'),
),
'holidays.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('holidays.sql'),
),
'userstatus.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('userstatus.sql'),
),
'emailtable.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('emailtable.sql'),
),
'emailtableport.sql' => array(
'type' => 'php',
'name' => $this->getPatchPath('emailtableport.php'),
),
'emailtableremove.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('emailtableremove.sql'),
),
'phiddrop.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('phiddrop.sql'),
),
'testdatabase.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('testdatabase.sql'),
),
'ldapinfo.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('ldapinfo.sql'),
),
'threadtopic.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('threadtopic.sql'),
),
'usertranslation.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('usertranslation.sql'),
),
'differentialbookmarks.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('differentialbookmarks.sql'),
),
'harbormasterobject.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('harbormasterobject.sql'),
),
'markupcache.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('markupcache.sql'),
),
'maniphestxcache.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('maniphestxcache.sql'),
),
'migrate-maniphest-dependencies.php' => array(
'type' => 'php',
'name' => $this->getPatchPath('migrate-maniphest-dependencies.php'),
),
'migrate-differential-dependencies.php' => array(
'type' => 'php',
'name' => $this->getPatchPath(
'migrate-differential-dependencies.php'),
),
'phameblog.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('phameblog.sql'),
),
'migrate-maniphest-revisions.php' => array(
'type' => 'php',
'name' => $this->getPatchPath('migrate-maniphest-revisions.php'),
),
'daemonstatus.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('daemonstatus.sql'),
),
'symbolcontexts.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('symbolcontexts.sql'),
),
'migrate-project-edges.php' => array(
'type' => 'php',
'name' => $this->getPatchPath('migrate-project-edges.php'),
),
'fact-raw.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('fact-raw.sql'),
),
'ponder.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('ponder.sql')
),
'policy-project.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('policy-project.sql'),
),
'daemonstatuskey.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('daemonstatuskey.sql'),
),
'edgetype.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('edgetype.sql'),
),
'ponder-comments.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('ponder-comments.sql'),
),
'pastepolicy.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('pastepolicy.sql'),
),
'xhprof.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('xhprof.sql'),
),
'draft-metadata.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('draft-metadata.sql'),
),
'phamedomain.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('phamedomain.sql'),
),
'ponder-mailkey.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('ponder-mailkey.sql'),
),
'ponder-mailkey-populate.php' => array(
'type' => 'php',
'name' => $this->getPatchPath('ponder-mailkey-populate.php'),
),
'phamepolicy.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('phamepolicy.sql'),
),
'phameoneblog.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('phameoneblog.sql'),
),
'statustxt.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('statustxt.sql'),
),
'daemontaskarchive.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('daemontaskarchive.sql'),
),
'drydocktaskid.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('drydocktaskid.sql'),
),
'drydockresoucetype.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('drydockresourcetype.sql'),
),
'liskcounters.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('liskcounters.sql'),
),
'liskcounters.php' => array(
'type' => 'php',
'name' => $this->getPatchPath('liskcounters.php'),
),
'dropfileproxyimage.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('dropfileproxyimage.sql'),
),
'repository-lint.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('repository-lint.sql'),
),
'liskcounters-task.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('liskcounters-task.sql'),
),
'pholio.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('pholio.sql'),
),
'owners-exclude.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('owners-exclude.sql'),
),
'20121209.pholioxactions.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20121209.pholioxactions.sql'),
),
'20121209.xmacroadd.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20121209.xmacroadd.sql'),
),
'20121209.xmacromigrate.php' => array(
'type' => 'php',
'name' => $this->getPatchPath('20121209.xmacromigrate.php'),
),
'20121209.xmacromigratekey.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20121209.xmacromigratekey.sql'),
),
'20121220.generalcache.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20121220.generalcache.sql'),
),
'20121226.config.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20121226.config.sql'),
),
'20130101.confxaction.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20130101.confxaction.sql'),
),
'20130102.metamtareceivedmailmessageidhash.sql' => array(
'type' => 'sql',
'name' =>
$this->getPatchPath('20130102.metamtareceivedmailmessageidhash.sql'),
),
'20130103.filemetadata.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20130103.filemetadata.sql'),
),
'20130111.conpherence.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20130111.conpherence.sql'),
),
'20130127.altheraldtranscript.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20130127.altheraldtranscript.sql'),
),
'20130201.revisionunsubscribed.php' => array(
'type' => 'php',
'name' => $this->getPatchPath('20130201.revisionunsubscribed.php'),
),
'20130201.revisionunsubscribed.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20130201.revisionunsubscribed.sql'),
),
'20130131.conpherencepics.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20130131.conpherencepics.sql'),
),
'20130214.chatlogchannel.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20130214.chatlogchannel.sql'),
),
'20130214.chatlogchannelid.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20130214.chatlogchannelid.sql'),
),
'20130214.token.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20130214.token.sql'),
),
'20130215.phabricatorfileaddttl.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20130215.phabricatorfileaddttl.sql'),
),
'20130217.cachettl.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20130217.cachettl.sql'),
),
'20130218.updatechannelid.php' => array(
'type' => 'php',
'name' => $this->getPatchPath('20130218.updatechannelid.php'),
),
'20130218.longdaemon.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20130218.longdaemon.sql'),
),
'20130219.commitsummary.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20130219.commitsummary.sql'),
),
'20130219.commitsummarymig.php' => array(
'type' => 'php',
'name' => $this->getPatchPath('20130219.commitsummarymig.php'),
),
'20130222.dropchannel.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20130222.dropchannel.sql'),
),
'20130226.commitkey.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20130226.commitkey.sql'),
),
'20131302.maniphestvalue.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20131302.maniphestvalue.sql'),
),
'20130304.lintauthor.sql' => array(
'type' => 'sql',
'name' => $this->getPatchPath('20130304.lintauthor.sql'),
),
+ 'releeph.sql' => array(
+ 'type' => 'sql',
+ 'name' => $this->getPatchPath('releeph.sql'),
+ ),
);
}
}
diff --git a/webroot/rsrc/css/application/releeph/releeph-branch.css b/webroot/rsrc/css/application/releeph/releeph-branch.css
new file mode 100644
index 0000000000..2bc7c83a74
--- /dev/null
+++ b/webroot/rsrc/css/application/releeph/releeph-branch.css
@@ -0,0 +1,79 @@
+/**
+ * @provides releeph-branch
+ */
+
+.releeph-branch-box {
+ margin-bottom: .5em;
+ padding: .5em .5em .5em;
+
+ border: 2px solid #d5d5d5;
+ /*border-top-color: #D5D5D5;
+ border-right-color: #BBB;
+ border-bottom-color: #A4A4A4;
+ border-left-color: #BBB;*/
+
+ background: #bbb;
+}
+
+/* Types of branch */
+
+.releeph-branch-box-named {
+ background: #ddd;
+}
+
+.releeph-branch-box-latest {
+ background: #ffd;
+}
+
+/* Branch symbolic name and full name */
+
+.releeph-branch-box .names {
+ width: 25em;
+ float: left;
+ margin-bottom: 1em;
+}
+
+.releeph-branch-box .names h1 {
+ font-size: 125%;
+ padding: 0px;
+}
+
+.releeph-branch-box .names h2 {
+ font-weight: normal;
+ font-size: 85%;
+}
+
+/* Date info */
+
+.releeph-branch-box .date-info {
+ width: 10%;
+ float: left;
+ color: #555;
+ margin-bottom: .3em;
+}
+
+/* Statistics table */
+
+.releeph-branch-box .request-statistics {
+ float: right;
+ padding-right: 2em;
+ font-size: 85%;
+}
+
+.releeph-branch-box .request-statistics th {
+ width: 1em;
+ text-align: right;
+ padding-right: .4em;
+ padding-left: .4em;
+}
+
+.releeph-branch-box .request-statistics td {
+ white-space: nowrap;
+ font-style: italic;
+}
+
+/* Buttons */
+
+.releeph-branch-box .buttons {
+ float: right;
+}
diff --git a/webroot/rsrc/css/application/releeph/releeph-colors.css b/webroot/rsrc/css/application/releeph/releeph-colors.css
new file mode 100644
index 0000000000..481ff7031b
--- /dev/null
+++ b/webroot/rsrc/css/application/releeph/releeph-colors.css
@@ -0,0 +1,35 @@
+/**
+ * @provides releeph-colors
+ */
+
+.releeph-border-color-failed {
+ border-color: #d2d;
+}
+
+.releeph-border-color-requested {
+ border-color: #ddd;
+}
+
+.releeph-border-color-comment {
+ border-color: #ddd;
+}
+
+.releeph-border-color-needs-pick {
+ border-color: #096;
+}
+
+.releeph-border-color-rejected {
+ border-color: #d00;
+}
+
+.releeph-border-color-needs-revert {
+ border-color: #d00;
+}
+
+.releeph-border-color-abandoned {
+ border-color: #222;
+}
+
+.releeph-border-color-picked {
+ border-color: #069;
+}
diff --git a/webroot/rsrc/css/application/releeph/releeph-core.css b/webroot/rsrc/css/application/releeph/releeph-core.css
new file mode 100644
index 0000000000..fdeb2810c9
--- /dev/null
+++ b/webroot/rsrc/css/application/releeph/releeph-core.css
@@ -0,0 +1,199 @@
+/**
+ * @provides releeph-core
+ */
+
+.releeph-request-header {
+ margin: .5em 2em 3em;
+
+ /**
+ * Copied from the old .differential-panel, present in commit
+ * f04d8ab1a747dc9719d378d9286088b677ce224c
+ *
+ * (As is the <h1> code below)
+ */
+ max-width: 1120px;
+ border: 1px solid #666622;
+ background: #efefdf;
+ padding: 15px 20px;
+ font-size: 13px;
+}
+
+.releeph-request-header h1 {
+ width: 100%;
+ border-bottom: 1px solid #aaaa99;
+ padding-bottom: 8px;
+ margin-bottom: 8px;
+ position: relative;
+}
+
+.releeph-request-header .focus-char {
+ left: -10px;
+ display: none;
+ float: left;
+ position: absolute;
+ top: 0px;
+ left: -1em;
+
+ font-weight: bold;
+
+ color: #880;
+ font-family: "Hiragino Kaku Gothic Pro", "Osaka", "Zapf Dingbats";
+}
+
+.releeph-request-header.focus .focus-char {
+ display: block;
+}
+
+.releeph-request-header-border {
+ border-width: 1px 10px 1px;
+ border-color: #ddd;
+}
+
+
+/* Laying out properties / fields */
+
+.releeph-request-header table.panes {
+ width: 100%;
+}
+
+.releeph-request-header table.panes td.side {
+ width: 50%;
+ max-width: 1em;
+}
+
+.releeph-request-header table.panes td.side.left {
+ padding-right: 20px;
+ border-right: 3px solid #bbb;
+}
+
+.releeph-request-header table.panes td.side.right {
+ padding-left: 20px;
+}
+
+.releeph-request-header table.panes td.side table.fields {
+ width: 100%;
+}
+
+.releeph-request-header table.panes td.side table.fields tr {
+ vertical-align: middle;
+}
+
+.releeph-request-header table.panes td.side table.fields th {
+ font-weight: bold;
+ text-align: right;
+ padding-right: 1em;
+ white-space: nowrap;
+}
+
+.releeph-request-header table.panes td.side table.fields td {
+ width: 100%; /* wide! */
+ max-width: 1em;
+}
+
+
+/* Buttons */
+
+.releeph-request-header .button-divider {
+ clear: both;
+ margin-top: 1.5em;
+ border-top: 1px solid #bbb;
+}
+
+.releeph-request-header .buttons {
+ width: 100%;
+}
+
+.releeph-request-header .buttons tr {
+ padding: 1em;
+ margin: 3em;
+}
+
+.releeph-request-header .buttons td {
+ padding: 1em .5em 0.2em;
+}
+
+.releeph-request-header .buttons td.wide {
+ width: 100%;
+}
+
+/* Colors: match differential colors */
+
+.releeph-request-comment {
+ border-color: #ddd;
+}
+
+.releeph-request-comment-pusher {
+ background: #8DEE8D;
+ border-color: #096;
+}
+
+.releeph-request-comment-pusher div {
+ background: #8DEE8D;
+}
+
+/* The diff size bar */
+
+.releeph-request-header .diff-bar {
+ border: 0px;
+}
+
+.releeph-request-header .diff-bar div {
+ width: 100px;
+ border: 1px solid;
+ border-top-color: #A4A4A4;
+ border-right-color: #BBB;
+ border-bottom-color: #D5D5D5;
+ border-left-color: #BBB;
+ background: white;
+ float: left;
+ margin-right: 1em;
+}
+
+.releeph-request-header .diff-bar div div {
+ height: 10px;
+}
+
+.releeph-request-header .diff-bar span {
+ color: #555;
+}
+
+/* Rendering pick / commit errors, etc. */
+
+.releeph-request-pick-failed-event h1:before {
+ content: '\2014 ';
+}
+
+.releeph-request-pick-failed-event h1:after {
+ content: ' \2014';
+}
+
+.releeph-request-pick-failed-event h1 {
+ padding: 3px 10px 3px;
+ margin-bottom: 0.5em;
+ background: #ffb;
+ font-size: small;
+}
+
+.releeph-request-pick-failed-event div {
+ font-family: monospace;
+ margin-bottom: 1.5em;
+ padding-left: 1em;
+ width: 70em;
+}
+
+/* History view of request */
+
+.releeph-request-event-list {
+ margin: .5em 2em .5em;
+}
+
+
+/* Shorten long header-text */
+
+.releeph-header-text-truncated {
+ width: 100%;
+ float: left;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
diff --git a/webroot/rsrc/css/application/releeph/releeph-intents.css b/webroot/rsrc/css/application/releeph/releeph-intents.css
new file mode 100644
index 0000000000..9e7691149b
--- /dev/null
+++ b/webroot/rsrc/css/application/releeph/releeph-intents.css
@@ -0,0 +1,37 @@
+/**
+ * @provides releeph-intents
+ */
+
+.releeph-intents .intents {
+ clear: left;
+ width: 100%;
+ margin-top: 3px;
+}
+
+.releeph-intents .arrow {
+ float: left;
+ clear: left;
+ margin-right: 0.4em;
+ padding: 8px;
+ background: transparent 0 0 no-repeat;
+}
+
+.releeph-intents .arrow.want {
+ background-image: url('/rsrc/custom/image/icon/tango/go-next.png');
+}
+
+.releeph-intents .arrow.pass {
+ background-image: url('/rsrc/custom/image/icon/tango/go-previous-gray.png');
+}
+
+.releeph-intents a {
+ margin-right: 0.4em;
+}
+
+.releeph-intents .pusher {
+ font-weight: bold;
+}
+
+.releeph-intents .requestor {
+ font-weight: normal;
+}
diff --git a/webroot/rsrc/css/application/releeph/releeph-preview-branch.css b/webroot/rsrc/css/application/releeph/releeph-preview-branch.css
new file mode 100644
index 0000000000..2bce6632d4
--- /dev/null
+++ b/webroot/rsrc/css/application/releeph/releeph-preview-branch.css
@@ -0,0 +1,29 @@
+/**
+ * @provides releeph-preview-branch
+ */
+
+.releeph-preview-branch {
+ min-height: 4em;
+ position: relative;
+}
+
+.releeph-preview-branch .error {
+ padding-left: 22px;
+ background-repeat: no-repeat;
+ background-size: 16px auto;
+ background-image: url(/rsrc/custom/image/releeph/releeph_warning.png);
+ float: left;
+ position: absolute;
+ top: 2.5em;
+}
+
+.releeph-preview-branch .name {
+ clear: both;
+ float: left;
+ position: absolute;
+ font-family: monospace;
+ font-size: 9pt !important;
+ background: white;
+ top: 0.7em;
+ padding: 2px;
+}
diff --git a/webroot/rsrc/css/application/releeph/releeph-project.css b/webroot/rsrc/css/application/releeph/releeph-project.css
new file mode 100644
index 0000000000..3a14751bdd
--- /dev/null
+++ b/webroot/rsrc/css/application/releeph/releeph-project.css
@@ -0,0 +1,25 @@
+/**
+ * @provides releeph-project
+ */
+
+/**
+ * ...from aphront-transaction.css
+ */
+
+.releeph-pusher {
+ background: 2px 2px no-repeat;
+ margin-top: 1em;
+ margin-bottom: 1.25em;
+ margin-right: 1em;
+ min-height: 50px;
+ padding: 2px 0px;
+
+ background-color: white;
+ border: 2px solid gray;
+ float: left;
+}
+
+.releeph-pusher-body {
+ margin-left: 54px;
+ padding: 1em;
+}
diff --git a/webroot/rsrc/css/application/releeph/releeph-request-differential-create-dialog.css b/webroot/rsrc/css/application/releeph/releeph-request-differential-create-dialog.css
new file mode 100644
index 0000000000..7101f78789
--- /dev/null
+++ b/webroot/rsrc/css/application/releeph/releeph-request-differential-create-dialog.css
@@ -0,0 +1,17 @@
+/**
+ * @provides releeph-request-differential-create-dialog
+ */
+
+.releeph-request-differential-create-dialog h1 {
+ color: gray;
+ font-style: italic;
+ font-size: 16px;
+ margin-top: 0.8em;
+}
+
+.releeph-request-differential-create-dialog a {
+ font-weight: bold;
+ margin-left: 2em;
+ display: block;
+ margin-top: 1em;
+}
diff --git a/webroot/rsrc/css/application/releeph/releeph-request-typeahead.css b/webroot/rsrc/css/application/releeph/releeph-request-typeahead.css
new file mode 100644
index 0000000000..91a81acea6
--- /dev/null
+++ b/webroot/rsrc/css/application/releeph/releeph-request-typeahead.css
@@ -0,0 +1,27 @@
+/**
+ * @provides releeph-request-typeahead-css
+ */
+
+.releeph-request-typeahead .commit-id {
+ color: #aaf; /* blue... */
+ font-family: monospace;
+ font-size: 100%;
+ display: block;
+ float: left;
+}
+
+.releeph-request-typeahead .author-info {
+ color: #080; /* ...and green, for search results! */
+ text-align: right;
+ display: block;
+ float: right;
+ padding-left: 1em;
+}
+
+.releeph-request-typeahead .focused .author-info {
+ color: #8b8;
+}
+
+.releeph-request-typeahead .summary {
+ clear: both;
+}
diff --git a/webroot/rsrc/css/application/releeph/releeph-status.css b/webroot/rsrc/css/application/releeph/releeph-status.css
new file mode 100644
index 0000000000..f41330e977
--- /dev/null
+++ b/webroot/rsrc/css/application/releeph/releeph-status.css
@@ -0,0 +1,26 @@
+/**
+ * @provides releeph-status
+ */
+
+.releeph-status .description {
+ background: #d3d3d3;
+ padding: 2px 6px 3px;
+ margin-right: 4px;
+ margin-bottom: 5px;
+ display: block;
+ float: left;
+ border-radius: 8px;
+ -moz-border-radius: 8px;
+ -webkit-border-radius: 8px;
+ text-decoration: none;
+}
+
+.releeph-status .warning {
+ margin-top: 2px;
+ margin-left: 0.8em;
+ float: left;
+ padding-left: 22px;
+ background-repeat: no-repeat;
+ background-size: 16px auto;
+ background-image: url(/rsrc/custom/image/releeph/releeph_warning.png);
+}
diff --git a/webroot/rsrc/js/application/releeph/releeph-preview-branch.js b/webroot/rsrc/js/application/releeph/releeph-preview-branch.js
new file mode 100644
index 0000000000..76e406bd73
--- /dev/null
+++ b/webroot/rsrc/js/application/releeph/releeph-preview-branch.js
@@ -0,0 +1,49 @@
+/**
+ * @provides javelin-behavior-releeph-preview-branch
+ * @requires javelin-behavior
+ * javelin-dom
+ * javelin-stratcom
+ * javelin-uri
+ * javelin-util
+ */
+
+JX.behavior('releeph-preview-branch', function(config) {
+
+ var uri = JX.$U(config.uri);
+ for (param_name in config.params.static) {
+ var value = config.params.static[param_name];
+ uri.setQueryParam(param_name, value);
+ }
+
+ var output = JX.$(config.outputID);
+
+ var dynamics = config.params.dynamic;
+
+ function renderPreview() {
+ for (param_name in dynamics) {
+ var node_id = dynamics[param_name];
+ var input = JX.$(node_id);
+ uri.setQueryParam(param_name, input.value);
+ }
+ var request = new JX.Request(uri, function(response) {
+ JX.DOM.setContent(output, JX.$H(response.markup));
+ });
+ request.send();
+ }
+
+ renderPreview();
+
+ for (ii in dynamics) {
+ var node_id = dynamics[ii];
+ var input = JX.$(node_id);
+ JX.DOM.listen(
+ input,
+ ['keyup', 'click', 'change'],
+ null,
+ function(e) {
+ renderPreview();
+ }
+ );
+ }
+
+});
diff --git a/webroot/rsrc/js/application/releeph/releeph-request-state-change.js b/webroot/rsrc/js/application/releeph/releeph-request-state-change.js
new file mode 100644
index 0000000000..286d527b84
--- /dev/null
+++ b/webroot/rsrc/js/application/releeph/releeph-request-state-change.js
@@ -0,0 +1,145 @@
+/**
+ * @provides javelin-behavior-releeph-request-state-change
+ * @requires javelin-behavior
+ * javelin-dom
+ * javelin-stratcom
+ * javelin-util
+ * phabricator-keyboard-shortcut
+ * phabricator-notification
+ */
+
+JX.behavior('releeph-request-state-change', function(config) {
+ var root = JX.DOM.find(document, 'div', 'releeph-request-header-list');
+
+ function getRequestHeaderNodes() {
+ return JX.DOM.scry(root, 'div', 'releeph-request-header');
+ }
+
+ /**
+ * Keyboard navigation
+ */
+ var keynav_cursor = -1;
+ var notification = new JX.Notification();
+
+ function keynavJump(manager, delta) {
+ // Calculate this everytime, because the DOM changes.
+ var headers = getRequestHeaderNodes();
+ keynav_cursor += delta;
+
+ if (keynav_cursor < 0) {
+ keynav_cursor = -1;
+ window.scrollTo(0);
+ keynavMarkup();
+ return;
+ }
+
+ if (keynav_cursor >= headers.length) {
+ keynav_cursor = headers.length - 1;
+ }
+
+ var focus = headers[keynav_cursor];
+ manager.scrollTo(focus);
+
+ keynavMarkup();
+ }
+
+ function keynavMarkup() {
+ var headers = getRequestHeaderNodes();
+ for (ii in headers) {
+ JX.DOM.alterClass(headers[ii], 'focus', ii == keynav_cursor);
+ }
+ }
+
+ function keynavAction(manager, action_name) {
+ var headers = getRequestHeaderNodes();
+ var header = headers[keynav_cursor];
+
+ if (keynav_cursor < 0) {
+ return;
+ }
+
+ var sigil = action_name;
+ var button = JX.DOM.find(header, 'a', sigil);
+ if (button) {
+ button.click();
+ }
+ }
+
+ function keynavNavigateToRequestPage() {
+ var headers = getRequestHeaderNodes();
+ var header = headers[keynav_cursor];
+ JX.DOM.find(header, 'a', 'hidden-link').click();
+ }
+
+ new JX.KeyboardShortcut('j', 'Jump to next request.')
+ .setHandler(function(manager) {
+ keynavJump(manager, +1);
+ })
+ .register();
+
+ new JX.KeyboardShortcut('k', 'Jump to previous request.')
+ .setHandler(function(manager) {
+ keynavJump(manager, -1);
+ })
+ .register();
+
+ new JX.KeyboardShortcut('a', 'Approve the selected request.')
+ .setHandler(function(manager) {
+ keynavAction(manager, 'want');
+ })
+ .register();
+
+ new JX.KeyboardShortcut('r', 'Reject the selected request.')
+ .setHandler(function(manager) {
+ keynavAction(manager, 'pass');
+ })
+ .register();
+
+ new JX.KeyboardShortcut('g', "Open selected request's page in a new tab.")
+ .setHandler(function(manager) {
+ keynavNavigateToRequestPage();
+ })
+ .register();
+
+
+ /**
+ * AJAXy state changes for request buttons.
+ */
+ function request_action(node, url) {
+ var request = new JX.Request(url, function(response) {
+ if (config.reload) {
+ window.location.reload();
+ } else {
+ var markup = JX.$H(response.markup);
+ JX.DOM.replace(node, markup);
+ keynavMarkup();
+ }
+ });
+
+ request.send();
+ }
+
+ JX.Stratcom.listen(
+ 'click',
+ 'releeph-request-state-change',
+ function(e) {
+ var button = e.getNode('releeph-request-state-change');
+ var node = e.getNode('releeph-request-header');
+ var url = e.getNodeData('releeph-request-state-change');
+
+ // If this button has no action, or we've already responded to the first
+ // click...
+ if (!url || button.disabled) {
+ return;
+ }
+
+ // There's a race condition here though :(
+
+ JX.DOM.alterClass(button, 'disabled', true);
+ button.disabled = true;
+
+ e.prevent();
+ request_action(node, url);
+ }
+ );
+});
diff --git a/webroot/rsrc/js/application/releeph/releeph-request-typeahead.js b/webroot/rsrc/js/application/releeph/releeph-request-typeahead.js
new file mode 100644
index 0000000000..fd932dd73b
--- /dev/null
+++ b/webroot/rsrc/js/application/releeph/releeph-request-typeahead.js
@@ -0,0 +1,84 @@
+/**
+ * @provides javelin-behavior-releeph-request-typeahead
+ * @requires javelin-behavior
+ * javelin-util
+ * javelin-dom
+ * javelin-typeahead
+ * javelin-tokenizer
+ * javelin-typeahead-preloaded-source
+ * javelin-typeahead-ondemand-source
+ * javelin-dom
+ * javelin-stratcom
+ * javelin-util
+ */
+
+JX.behavior('releeph-request-typeahead', function(config) {
+ var root = JX.$(config.id);
+ var datasource = new JX.TypeaheadOnDemandSource(config.src);
+ var callsign = config.aux.callsign;
+
+ datasource.setAuxiliaryData(config.aux);
+
+ datasource.setTransformer(
+ function(object) {
+ var full_commit_id = object[0];
+ var short_commit_id = object[1];
+ var author = object[2];
+ var ago = object[3];
+ var summary = object[4];
+
+ var callsign_commit_id = 'r' + callsign + short_commit_id;
+
+ var box =
+ JX.$N(
+ 'div',
+ {},
+ [
+ JX.$N(
+ 'div',
+ { className: 'commit-id' },
+ callsign_commit_id
+ ),
+ JX.$N(
+ 'div',
+ { className: 'author-info' },
+ ago + ' ago by ' + author
+ ),
+ JX.$N(
+ 'div',
+ { className: 'summary' },
+ summary
+ ),
+ ]
+ );
+
+ return {
+ name: callsign_commit_id,
+ tokenizable: callsign_commit_id + ' '+ short_commit_id + ' ' + summary,
+ display: box,
+ uri: null,
+ id: full_commit_id
+ };
+ });
+
+ /**
+ * The default normalizer removes useful control characters that would help
+ * out search. For example, I was just trying to search for a commit with
+ * the string "a_file" in the message, which was normalized to "afile".
+ */
+ datasource.setNormalizer(function(query) {
+ return query;
+ });
+
+ datasource.setMaximumResultCount(config.aux.limit);
+
+ var typeahead = new JX.Typeahead(root);
+ typeahead.setDatasource(datasource);
+
+ var placeholder = config.value || config.placeholder;
+ if (placeholder) {
+ typeahead.setPlaceholder(placeholder);
+ }
+
+ typeahead.start();
+});

File Metadata

Mime Type
text/x-diff
Expires
Thu, Nov 13, 7:35 PM (14 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
336515
Default Alt Text
(732 KB)

Event Timeline