diff --git a/resources/sprite/apps_blue_2x/conpherence.png b/resources/sprite/apps_blue_2x/conpherence.png new file mode 100644 index 0000000000..09150623ed Binary files /dev/null and b/resources/sprite/apps_blue_2x/conpherence.png differ diff --git a/resources/sprite/apps_blue_4x/conpherence.png b/resources/sprite/apps_blue_4x/conpherence.png new file mode 100644 index 0000000000..6b39d32ac4 Binary files /dev/null and b/resources/sprite/apps_blue_4x/conpherence.png differ diff --git a/resources/sprite/apps_dark_1x/conpherence.png b/resources/sprite/apps_dark_1x/conpherence.png new file mode 100644 index 0000000000..6819b2b261 Binary files /dev/null and b/resources/sprite/apps_dark_1x/conpherence.png differ diff --git a/resources/sprite/apps_dark_2x/conpherence.png b/resources/sprite/apps_dark_2x/conpherence.png new file mode 100644 index 0000000000..2397e6378f Binary files /dev/null and b/resources/sprite/apps_dark_2x/conpherence.png differ diff --git a/resources/sprite/apps_dark_4x/conpherence.png b/resources/sprite/apps_dark_4x/conpherence.png new file mode 100644 index 0000000000..80e1321d6c Binary files /dev/null and b/resources/sprite/apps_dark_4x/conpherence.png differ diff --git a/resources/sprite/apps_glow_2x/conpherence.png b/resources/sprite/apps_glow_2x/conpherence.png new file mode 100644 index 0000000000..8d650d4822 Binary files /dev/null and b/resources/sprite/apps_glow_2x/conpherence.png differ diff --git a/resources/sprite/apps_glow_4x/conpherence.png b/resources/sprite/apps_glow_4x/conpherence.png new file mode 100644 index 0000000000..376ef3141b Binary files /dev/null and b/resources/sprite/apps_glow_4x/conpherence.png differ diff --git a/resources/sprite/apps_lb_2x/conpherence.png b/resources/sprite/apps_lb_2x/conpherence.png new file mode 100644 index 0000000000..4f4ace2658 Binary files /dev/null and b/resources/sprite/apps_lb_2x/conpherence.png differ diff --git a/resources/sprite/apps_lb_4x/conpherence.png b/resources/sprite/apps_lb_4x/conpherence.png new file mode 100644 index 0000000000..a3cc9ef7b9 Binary files /dev/null and b/resources/sprite/apps_lb_4x/conpherence.png differ diff --git a/resources/sprite/manifest/apps-large.json b/resources/sprite/manifest/apps-large.json index f6ecda2aff..d6ee12c218 100644 --- a/resources/sprite/manifest/apps-large.json +++ b/resources/sprite/manifest/apps-large.json @@ -1,771 +1,791 @@ { "version" : 1, "sprites" : { "app-application-blue-large" : { "name" : "app-application-blue-large", "rule" : ".app-application-blue-large, .phabricator-crumb-view:hover .app-application-dark-large", - "hash" : "c8e0319f0c8a3c19bb74391785149424" + "hash" : "80f42a283979cef89577721ca6d9cdef" }, "app-application-dark-large" : { "name" : "app-application-dark-large", "rule" : ".app-application-dark-large", - "hash" : "a5a904b67bdd26c15b8df07b0b0cee1a" + "hash" : "8ab1619bcb768cc1b85106b077d29522" }, "app-application-glow-large" : { "name" : "app-application-glow-large", "rule" : ".app-application-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-application-light-large", - "hash" : "04cd8ab1f4785d33d6c9c829dce35cb6" + "hash" : "26aedaf7940300f18eb0ef59566a0988" }, "app-application-light-large" : { "name" : "app-application-light-large", "rule" : ".app-application-light-large", - "hash" : "8b071cf0efedda7c8c772829d31453ea" + "hash" : "09d4ef0cb36255291693971754ec55ee" }, "app-audit-blue-large" : { "name" : "app-audit-blue-large", "rule" : ".app-audit-blue-large, .phabricator-crumb-view:hover .app-audit-dark-large", - "hash" : "cfb6e6c27d6bf4bbf2e07c8d284948d7" + "hash" : "05941dc7d5ff156c0e899c6345f6833a" }, "app-audit-dark-large" : { "name" : "app-audit-dark-large", "rule" : ".app-audit-dark-large", - "hash" : "0880246fc6aa5d0cec823166af5b388f" + "hash" : "cbf8e6c5a580bd3b5169f30d3cd0ec6a" }, "app-audit-glow-large" : { "name" : "app-audit-glow-large", "rule" : ".app-audit-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-audit-light-large", - "hash" : "2f3896e45a05d55c3a95440dbeac9187" + "hash" : "5ab43e357c123c05a9db85a964b20252" }, "app-audit-light-large" : { "name" : "app-audit-light-large", "rule" : ".app-audit-light-large", - "hash" : "8dd753f716233d2f6edf553df4fde942" + "hash" : "aa853bebb7a315b994f1527247e3b362" }, "app-calendar-blue-large" : { "name" : "app-calendar-blue-large", "rule" : ".app-calendar-blue-large, .phabricator-crumb-view:hover .app-calendar-dark-large", - "hash" : "a05add9fa18df8a98cf2735cf27ec6e1" + "hash" : "9e530feec2926878ee7eaa8a04a8607b" }, "app-calendar-dark-large" : { "name" : "app-calendar-dark-large", "rule" : ".app-calendar-dark-large", - "hash" : "5c98faf324152ec55bad6ac76f77ec00" + "hash" : "65de91c173d169bbf407c9e7cefa9715" }, "app-calendar-glow-large" : { "name" : "app-calendar-glow-large", "rule" : ".app-calendar-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-calendar-light-large", - "hash" : "d1a7c623c5b3d902a389fc2ea8941858" + "hash" : "1dc738045b09476feebe5e705a61b7a9" }, "app-calendar-light-large" : { "name" : "app-calendar-light-large", "rule" : ".app-calendar-light-large", - "hash" : "466b97737778eff91ebd9afabac6e5a6" + "hash" : "043dab56a011f84f5affc2c7c13e3a39" }, "app-conduit-blue-large" : { "name" : "app-conduit-blue-large", "rule" : ".app-conduit-blue-large, .phabricator-crumb-view:hover .app-conduit-dark-large", - "hash" : "ed8208ab196da7da6160edbdb0be118a" + "hash" : "4ab937882a119bacc0206029cbd7919d" }, "app-conduit-dark-large" : { "name" : "app-conduit-dark-large", "rule" : ".app-conduit-dark-large", - "hash" : "bad7559ed9928596c0241d8490e67422" + "hash" : "34de5192c69af7a9cf3941f7b5cb088e" }, "app-conduit-glow-large" : { "name" : "app-conduit-glow-large", "rule" : ".app-conduit-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-conduit-light-large", - "hash" : "072c3ca188a60e9ee08c6eb36b8628c9" + "hash" : "b89b969a7fba76d39c768ac8de19c964" }, "app-conduit-light-large" : { "name" : "app-conduit-light-large", "rule" : ".app-conduit-light-large", - "hash" : "92047e758fac063dfb0608863ee66b7e" + "hash" : "a2fd3cfe6e4e46d589e0e99f52e7f6f0" + }, + "app-conpherence-blue-large" : { + "name" : "app-conpherence-blue-large", + "rule" : ".app-conpherence-blue-large, .phabricator-crumb-view:hover .app-conpherence-dark-large", + "hash" : "efcf3788ac60484d5920b37c1560e565" + }, + "app-conpherence-dark-large" : { + "name" : "app-conpherence-dark-large", + "rule" : ".app-conpherence-dark-large", + "hash" : "2722117e3da8c2dbc478d957fb21ca53" + }, + "app-conpherence-glow-large" : { + "name" : "app-conpherence-glow-large", + "rule" : ".app-conpherence-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-conpherence-light-large", + "hash" : "efa3c29ad40680fca2d62e0b180e709f" + }, + "app-conpherence-light-large" : { + "name" : "app-conpherence-light-large", + "rule" : ".app-conpherence-light-large", + "hash" : "a79e5f0094caf9f012f3e9d7a10f2bac" }, "app-countdown-blue-large" : { "name" : "app-countdown-blue-large", "rule" : ".app-countdown-blue-large, .phabricator-crumb-view:hover .app-countdown-dark-large", - "hash" : "d44b7acae6b6b052ac869f0176b66b89" + "hash" : "a4079b8e55924b7590011b35ba9bfdb0" }, "app-countdown-dark-large" : { "name" : "app-countdown-dark-large", "rule" : ".app-countdown-dark-large", - "hash" : "dc7df8202a5fa7baf17fd446a9b5c4c5" + "hash" : "25547923eb9927ed0c30804fafd471d3" }, "app-countdown-glow-large" : { "name" : "app-countdown-glow-large", "rule" : ".app-countdown-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-countdown-light-large", - "hash" : "3b972002d629a49a4eca9049a9b2c6ae" + "hash" : "472fcd5cf9f292b0d2f9f275541fed18" }, "app-countdown-light-large" : { "name" : "app-countdown-light-large", "rule" : ".app-countdown-light-large", - "hash" : "8f3814f70c1cb0475dd4678cc8937d91" + "hash" : "24bac143e049862bed161d819990cee0" }, "app-daemon-blue-large" : { "name" : "app-daemon-blue-large", "rule" : ".app-daemon-blue-large, .phabricator-crumb-view:hover .app-daemon-dark-large", - "hash" : "c922a7e7ec9467ca48b2a2573904b7ce" + "hash" : "beb6586864ef67a7bd7a9a159b8c2a56" }, "app-daemon-dark-large" : { "name" : "app-daemon-dark-large", "rule" : ".app-daemon-dark-large", - "hash" : "b2e566baac0c579563bd5bd700deb41b" + "hash" : "cf2e12b2967d155c437862bbb9ce2d86" }, "app-daemon-glow-large" : { "name" : "app-daemon-glow-large", "rule" : ".app-daemon-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-daemon-light-large", - "hash" : "1c8e2776b9b984b804f6dca073f101eb" + "hash" : "1728089df503ec805b42e262b196b616" }, "app-daemon-light-large" : { "name" : "app-daemon-light-large", "rule" : ".app-daemon-light-large", - "hash" : "9c778b43f9f7380fc9bd862c097bbaa8" + "hash" : "44328612154fbf1a2f0f6ff28cd23521" }, "app-differential-blue-large" : { "name" : "app-differential-blue-large", "rule" : ".app-differential-blue-large, .phabricator-crumb-view:hover .app-differential-dark-large", - "hash" : "59049df6a30c816ea68d3025da79a091" + "hash" : "9491284c8cbf77df0795bdf9cd16651e" }, "app-differential-dark-large" : { "name" : "app-differential-dark-large", "rule" : ".app-differential-dark-large", - "hash" : "fd1e0f1fa97b00c7409ebfdc56cf4865" + "hash" : "a4b2ac4d4f697896e3abe9e58501fea5" }, "app-differential-glow-large" : { "name" : "app-differential-glow-large", "rule" : ".app-differential-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-differential-light-large", - "hash" : "3997a58a26389e8ede8022fd05cf8b43" + "hash" : "d7e777585cc826becb64042f8bb31fc5" }, "app-differential-light-large" : { "name" : "app-differential-light-large", "rule" : ".app-differential-light-large", - "hash" : "b5c750e09f57a787e89f32820f791c4a" + "hash" : "a763d63d22cac8226d8bd5656221a91b" }, "app-diffusion-blue-large" : { "name" : "app-diffusion-blue-large", "rule" : ".app-diffusion-blue-large, .phabricator-crumb-view:hover .app-diffusion-dark-large", - "hash" : "b982cfacfde43d3267082bca236bc72c" + "hash" : "35e35c07ca1a151c810bb38a90496a2d" }, "app-diffusion-dark-large" : { "name" : "app-diffusion-dark-large", "rule" : ".app-diffusion-dark-large", - "hash" : "2eb71cde4af83347efdee542f4cadd8e" + "hash" : "5b3752babd557f2c9bbc0120bd9a0747" }, "app-diffusion-glow-large" : { "name" : "app-diffusion-glow-large", "rule" : ".app-diffusion-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-diffusion-light-large", - "hash" : "55873c2e30e693e7bde0f4a90045064d" + "hash" : "a5a682fffa03d4cdae9a86b8c79d1a81" }, "app-diffusion-light-large" : { "name" : "app-diffusion-light-large", "rule" : ".app-diffusion-light-large", - "hash" : "6eeb6f6df3ecd1ee923081b2d82f0505" + "hash" : "1f04606fe4f0650982327bf09bf5adc0" }, "app-diviner-blue-large" : { "name" : "app-diviner-blue-large", "rule" : ".app-diviner-blue-large, .phabricator-crumb-view:hover .app-diviner-dark-large", - "hash" : "bda64f504c0c2c34125758bd01c80e05" + "hash" : "97f1242c914315cf773c27bbec964335" }, "app-diviner-dark-large" : { "name" : "app-diviner-dark-large", "rule" : ".app-diviner-dark-large", - "hash" : "786a865464564d66d458557c909a77ea" + "hash" : "c4f0550826f60fcd48d6ebcd340184b4" }, "app-diviner-glow-large" : { "name" : "app-diviner-glow-large", "rule" : ".app-diviner-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-diviner-light-large", - "hash" : "d173b3a659a2a4b5af5890ba70e827d1" + "hash" : "7f7f0e1886036d894a5b22b72872ad06" }, "app-diviner-light-large" : { "name" : "app-diviner-light-large", "rule" : ".app-diviner-light-large", - "hash" : "c515bc52cb560adebce1e84bb5d917ce" + "hash" : "b13413ada716fa7d3449c38b11decd5d" }, "app-drydock-blue-large" : { "name" : "app-drydock-blue-large", "rule" : ".app-drydock-blue-large, .phabricator-crumb-view:hover .app-drydock-dark-large", - "hash" : "ba82e330a78dd60df033560e083601cf" + "hash" : "a63aaba405583e356f00af6bc1dedfad" }, "app-drydock-dark-large" : { "name" : "app-drydock-dark-large", "rule" : ".app-drydock-dark-large", - "hash" : "7a41b9668c77b85b8acf048d9e61c50a" + "hash" : "a97be15640a38db803cc03215968e856" }, "app-drydock-glow-large" : { "name" : "app-drydock-glow-large", "rule" : ".app-drydock-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-drydock-light-large", - "hash" : "f5866c62ecbc94ecacd1563d2780677d" + "hash" : "d7beac10376044ffda0adbe6ed01e645" }, "app-drydock-light-large" : { "name" : "app-drydock-light-large", "rule" : ".app-drydock-light-large", - "hash" : "2c1ce32d5d5291e7d3d3d6e9323a2a65" + "hash" : "712c8fa45f964e0c4cbb69321fd1fded" }, "app-fact-blue-large" : { "name" : "app-fact-blue-large", "rule" : ".app-fact-blue-large, .phabricator-crumb-view:hover .app-fact-dark-large", - "hash" : "1e2b911cb36b0d44384487e348892ccc" + "hash" : "4b07b51e2178f12533c04c55d522d9e5" }, "app-fact-dark-large" : { "name" : "app-fact-dark-large", "rule" : ".app-fact-dark-large", - "hash" : "5fb4a988baad433e9900f1a814b89caa" + "hash" : "6040fe830d8f0868cdb38ee2b8ee16ac" }, "app-fact-glow-large" : { "name" : "app-fact-glow-large", "rule" : ".app-fact-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-fact-light-large", - "hash" : "5bd7e5f2adfa0935ae97270139ec4912" + "hash" : "691ab101af38d4f06421ca0b22e463d9" }, "app-fact-light-large" : { "name" : "app-fact-light-large", "rule" : ".app-fact-light-large", - "hash" : "3bc45d399dad8ec8d55873714c42c1d7" + "hash" : "8253f813361ba065866ee6e6e2077320" }, "app-feed-blue-large" : { "name" : "app-feed-blue-large", "rule" : ".app-feed-blue-large, .phabricator-crumb-view:hover .app-feed-dark-large", - "hash" : "3bcdec795b38002644a8009c927a0acc" + "hash" : "462246f99422c86301b7d4faa67d9488" }, "app-feed-dark-large" : { "name" : "app-feed-dark-large", "rule" : ".app-feed-dark-large", - "hash" : "e83834eccc699399b604069b95465cff" + "hash" : "0eecff752dc5dde55e7feaa52b7ee7d0" }, "app-feed-glow-large" : { "name" : "app-feed-glow-large", "rule" : ".app-feed-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-feed-light-large", - "hash" : "ca2fb9a2cd437b465f5d912a4d26f3e5" + "hash" : "45fe559a997e540933c184ae570a6ddc" }, "app-feed-light-large" : { "name" : "app-feed-light-large", "rule" : ".app-feed-light-large", - "hash" : "e3a8add13539550ddaab62f84b30dd66" + "hash" : "2ec6e12956fe1e1b746261bb3d0a0d36" }, "app-files-blue-large" : { "name" : "app-files-blue-large", "rule" : ".app-files-blue-large, .phabricator-crumb-view:hover .app-files-dark-large", - "hash" : "4505af3a9261a1ee4e00bf1d046286dd" + "hash" : "f9217c49be154a830303285ae64790c8" }, "app-files-dark-large" : { "name" : "app-files-dark-large", "rule" : ".app-files-dark-large", - "hash" : "1d229c79f3b8301ca1ee38ccd9c7c142" + "hash" : "78fb66b9edc99c3694325548582f0506" }, "app-files-glow-large" : { "name" : "app-files-glow-large", "rule" : ".app-files-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-files-light-large", - "hash" : "4bd7617617d0af975282bdd9a399d0ab" + "hash" : "cabf071ace59043fc877f1e962109c83" }, "app-files-light-large" : { "name" : "app-files-light-large", "rule" : ".app-files-light-large", - "hash" : "0d8bf609759312d89e2a4b148f0701d8" + "hash" : "ee5503d0684ea20be40023a29589d322" }, "app-flags-blue-large" : { "name" : "app-flags-blue-large", "rule" : ".app-flags-blue-large, .phabricator-crumb-view:hover .app-flags-dark-large", - "hash" : "a6f52b520f88e4ef60b7a76fb3c2c597" + "hash" : "8bbdefdaba30bf6a020f8515ee33d452" }, "app-flags-dark-large" : { "name" : "app-flags-dark-large", "rule" : ".app-flags-dark-large", - "hash" : "51307234bb3c309b3ea69381e0b72b16" + "hash" : "c6824e1362ec59ccf9ad8f451da466c1" }, "app-flags-glow-large" : { "name" : "app-flags-glow-large", "rule" : ".app-flags-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-flags-light-large", - "hash" : "75c1c107f4e750ef27bf50b4b51b0e00" + "hash" : "e728b1018c62d24efa5d416d138cb671" }, "app-flags-light-large" : { "name" : "app-flags-light-large", "rule" : ".app-flags-light-large", - "hash" : "8c198ba5bcd146595870bab777d4992e" + "hash" : "4a40dc3e18011a8283840e5dfbe14dc9" }, "app-help-blue-large" : { "name" : "app-help-blue-large", "rule" : ".app-help-blue-large, .phabricator-crumb-view:hover .app-help-dark-large", - "hash" : "a74c4f436b2e70c0e06f4224953d064a" + "hash" : "703f8c674cdd22f1314ffe8977acf35b" }, "app-help-dark-large" : { "name" : "app-help-dark-large", "rule" : ".app-help-dark-large", - "hash" : "3cbd366c4b5758e45ef07507c70f68c0" + "hash" : "601aaf7047f9db41baf7e3393b0d7aeb" }, "app-help-glow-large" : { "name" : "app-help-glow-large", "rule" : ".app-help-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-help-light-large", - "hash" : "c795358a116961342b206821a1b8038b" + "hash" : "1a2928f28cbfdcc31f411e7d2dc26447" }, "app-help-light-large" : { "name" : "app-help-light-large", "rule" : ".app-help-light-large", - "hash" : "722eceffe63605b00a5b957b5f40db98" + "hash" : "c17b8e6228f844777177c5070e17dd91" }, "app-herald-blue-large" : { "name" : "app-herald-blue-large", "rule" : ".app-herald-blue-large, .phabricator-crumb-view:hover .app-herald-dark-large", - "hash" : "9edfe47e8f1f2c4f1071f4d8b6ed346d" + "hash" : "4bf9b4b872e7207d66c6e80dcad47b0e" }, "app-herald-dark-large" : { "name" : "app-herald-dark-large", "rule" : ".app-herald-dark-large", - "hash" : "4b7a3ab5e0b6a04224ccb6e520e73d6e" + "hash" : "e19fd614bf5f904603517df957165b22" }, "app-herald-glow-large" : { "name" : "app-herald-glow-large", "rule" : ".app-herald-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-herald-light-large", - "hash" : "22beef0629ee517ba1a2b822ed440d0c" + "hash" : "13ef725e4f2da68211cf9ab17740c723" }, "app-herald-light-large" : { "name" : "app-herald-light-large", "rule" : ".app-herald-light-large", - "hash" : "65bbeb68fd051b77f4871aafe2994f56" + "hash" : "81af2b9899db0b5c877d96016ddfa1a1" }, "app-home-blue-large" : { "name" : "app-home-blue-large", "rule" : ".app-home-blue-large, .phabricator-crumb-view:hover .app-home-dark-large", - "hash" : "7df64082c33dcc3d2263772c0393be70" + "hash" : "7011cb276b9d7d1f042d2f0393a74312" }, "app-home-dark-large" : { "name" : "app-home-dark-large", "rule" : ".app-home-dark-large", - "hash" : "79acb839094adcb3ad94567c054801eb" + "hash" : "6b7f677ad630593900132f6271c41cb4" }, "app-home-glow-large" : { "name" : "app-home-glow-large", "rule" : ".app-home-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-home-light-large", - "hash" : "5af620ae48ba98ee4ee594c32ba761cb" + "hash" : "8b61be58e6a4f0e9e73434c40844260b" }, "app-home-light-large" : { "name" : "app-home-light-large", "rule" : ".app-home-light-large", - "hash" : "181a71639319f3beda59809963384250" + "hash" : "f0740b16cd3746a1234070f1785c03eb" }, "app-logo-blue-large" : { "name" : "app-logo-blue-large", "rule" : ".app-logo-blue-large, .phabricator-crumb-view:hover .app-logo-dark-large", - "hash" : "025f46665b079f5899ec53be09165d09" + "hash" : "64a8124698f9441f50230f3a63364dd7" }, "app-logo-dark-large" : { "name" : "app-logo-dark-large", "rule" : ".app-logo-dark-large", - "hash" : "20524d2868b7b57423aa8dc27b284cac" + "hash" : "8023a60fcba24c3f200214152a62a2c3" }, "app-logo-glow-large" : { "name" : "app-logo-glow-large", "rule" : ".app-logo-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-logo-light-large", - "hash" : "3969545781a17ec856bacec4ed110506" + "hash" : "c742c782b92cc5fecdc1a9747568ad70" }, "app-logo-light-large" : { "name" : "app-logo-light-large", "rule" : ".app-logo-light-large", - "hash" : "bd1b66ffad9ee26019738fc00a7eb343" + "hash" : "52fc06fb90f7ec1c29498069b1a059b2" }, "app-macro-blue-large" : { "name" : "app-macro-blue-large", "rule" : ".app-macro-blue-large, .phabricator-crumb-view:hover .app-macro-dark-large", - "hash" : "a6116a196718bf6cd5337b4c49de710e" + "hash" : "50c14fec9a7f913c8aa4a2793bf2867c" }, "app-macro-dark-large" : { "name" : "app-macro-dark-large", "rule" : ".app-macro-dark-large", - "hash" : "583a495f319fb63f99400b0197832dce" + "hash" : "890cde6b9407d00c6394d446974674ff" }, "app-macro-glow-large" : { "name" : "app-macro-glow-large", "rule" : ".app-macro-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-macro-light-large", - "hash" : "16d2c3aeabb43a51bb5742c67c4b92a1" + "hash" : "a3aaa9ebca64e5659e8c3c4eebdedd7a" }, "app-macro-light-large" : { "name" : "app-macro-light-large", "rule" : ".app-macro-light-large", - "hash" : "b073066348826c93f57ba76f746e5c7e" + "hash" : "7dcba4f0560b9e197849f5540b7ec66d" }, "app-mail-blue-large" : { "name" : "app-mail-blue-large", "rule" : ".app-mail-blue-large, .phabricator-crumb-view:hover .app-mail-dark-large", - "hash" : "192f85bd7a5be296de7acff9bbc9bd1d" + "hash" : "a0a94c194794bb435ea3152ecb2cd42d" }, "app-mail-dark-large" : { "name" : "app-mail-dark-large", "rule" : ".app-mail-dark-large", - "hash" : "4709516a74216e0ba886a30180ad93d4" + "hash" : "1a1437047fd24b9bb2643435185b6f13" }, "app-mail-glow-large" : { "name" : "app-mail-glow-large", "rule" : ".app-mail-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-mail-light-large", - "hash" : "1f0d2be98c3771791db7a9ad20784872" + "hash" : "141548cae4bf8265be9452e583be3504" }, "app-mail-light-large" : { "name" : "app-mail-light-large", "rule" : ".app-mail-light-large", - "hash" : "740ea3d3104365ab7bad981b13d23693" + "hash" : "27aec2b8d5bd1fb7eba00ffbaacf1930" }, "app-maniphest-blue-large" : { "name" : "app-maniphest-blue-large", "rule" : ".app-maniphest-blue-large, .phabricator-crumb-view:hover .app-maniphest-dark-large", - "hash" : "d667667cc5216ff510cb58c359ffc2a4" + "hash" : "619ff6fea2c90a8d70b000ed0ece6e4b" }, "app-maniphest-dark-large" : { "name" : "app-maniphest-dark-large", "rule" : ".app-maniphest-dark-large", - "hash" : "acadb7737b24ecc23e892cdaab7c1fe2" + "hash" : "7a204fc2f4779eff27847bf799652140" }, "app-maniphest-glow-large" : { "name" : "app-maniphest-glow-large", "rule" : ".app-maniphest-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-maniphest-light-large", - "hash" : "8dccd7ba95ddffc4e071e42b69773f5c" + "hash" : "2b67eff9fb01bdf0972749532301e038" }, "app-maniphest-light-large" : { "name" : "app-maniphest-light-large", "rule" : ".app-maniphest-light-large", - "hash" : "0d2c71a1279686c3884c267d98bc36ba" + "hash" : "90ea395741410840b1b4a974f802b06c" }, "app-metamta-blue-large" : { "name" : "app-metamta-blue-large", "rule" : ".app-metamta-blue-large, .phabricator-crumb-view:hover .app-metamta-dark-large", - "hash" : "1757d281dcdbdf221ca2b2e90993dba8" + "hash" : "48af88efc2887cc985f09d5202922df0" }, "app-metamta-dark-large" : { "name" : "app-metamta-dark-large", "rule" : ".app-metamta-dark-large", - "hash" : "c5f3a7468d98ebb977bfb0cc81abd5ee" + "hash" : "bf18a2c7ef31e72dc9ce6695035baf60" }, "app-metamta-glow-large" : { "name" : "app-metamta-glow-large", "rule" : ".app-metamta-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-metamta-light-large", - "hash" : "5f7b115d45e5d3a5a5a730173366f2e4" + "hash" : "74c00295bf0d394e6427593665a271f1" }, "app-metamta-light-large" : { "name" : "app-metamta-light-large", "rule" : ".app-metamta-light-large", - "hash" : "13ce4ca0f223cda37e3af39da8c6e564" + "hash" : "720cc7f66ab36770998aa4fe9ad22785" }, "app-owners-blue-large" : { "name" : "app-owners-blue-large", "rule" : ".app-owners-blue-large, .phabricator-crumb-view:hover .app-owners-dark-large", - "hash" : "585c128af418f94b8fbf18206605ec84" + "hash" : "ee909b2d51a3c52b38c0cca3da8d861d" }, "app-owners-dark-large" : { "name" : "app-owners-dark-large", "rule" : ".app-owners-dark-large", - "hash" : "b09a80f307491acbe56fb16e01956173" + "hash" : "05a6fcc603b5ee346d25b1fb25e7e695" }, "app-owners-glow-large" : { "name" : "app-owners-glow-large", "rule" : ".app-owners-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-owners-light-large", - "hash" : "a63816e6979ec6c222a086b5d72a0b86" + "hash" : "4bcba14ffcdf7ac3c1968ebcc34f7e37" }, "app-owners-light-large" : { "name" : "app-owners-light-large", "rule" : ".app-owners-light-large", - "hash" : "6b06493f46a91584e746e5034be15366" + "hash" : "2d6b3f02f210c73242d91bdb9ef8456c" }, "app-paste-blue-large" : { "name" : "app-paste-blue-large", "rule" : ".app-paste-blue-large, .phabricator-crumb-view:hover .app-paste-dark-large", - "hash" : "4a14c100c5b78282712dd2cc619d72b4" + "hash" : "2ce99237cc2f064f0aa48fb1d147c781" }, "app-paste-dark-large" : { "name" : "app-paste-dark-large", "rule" : ".app-paste-dark-large", - "hash" : "03d3dded4964e60771c8a45549e13973" + "hash" : "f566e3e0c8e6a17b7c2fc4168b079ede" }, "app-paste-glow-large" : { "name" : "app-paste-glow-large", "rule" : ".app-paste-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-paste-light-large", - "hash" : "507192b6a41abdc1a886a144cc315326" + "hash" : "34333bbb31fb3909461cc064ea2f72e9" }, "app-paste-light-large" : { "name" : "app-paste-light-large", "rule" : ".app-paste-light-large", - "hash" : "66f1f8fe7acafaab5f608598589aaa5c" + "hash" : "e77a206e1cbaf1417b4a0b9f3d67380a" }, "app-people-blue-large" : { "name" : "app-people-blue-large", "rule" : ".app-people-blue-large, .phabricator-crumb-view:hover .app-people-dark-large", - "hash" : "ed242e94b2b5698fd90261ca63aef8a6" + "hash" : "37fcac5bc4ad63c37d68da2c77717301" }, "app-people-dark-large" : { "name" : "app-people-dark-large", "rule" : ".app-people-dark-large", - "hash" : "b1748b3a5afacd4f8afcd5ea37352dc7" + "hash" : "01fb27eba95c01d1aadde04ea4513caa" }, "app-people-glow-large" : { "name" : "app-people-glow-large", "rule" : ".app-people-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-people-light-large", - "hash" : "ed1b2d2d27ae8fd07d0e5e1d4002625e" + "hash" : "6d859c1505f5877b86faf34385bbcd59" }, "app-people-light-large" : { "name" : "app-people-light-large", "rule" : ".app-people-light-large", - "hash" : "f6efcbdbcee02f9f37f92774b4b0e4cf" + "hash" : "d1d80fddc9e6295494d12b72b4700dc5" }, "app-phame-blue-large" : { "name" : "app-phame-blue-large", "rule" : ".app-phame-blue-large, .phabricator-crumb-view:hover .app-phame-dark-large", - "hash" : "d448b392b7bc927b9b5522d525fa8c49" + "hash" : "f72bd35227e9ba2157852377e2d87ec4" }, "app-phame-dark-large" : { "name" : "app-phame-dark-large", "rule" : ".app-phame-dark-large", - "hash" : "a7cf2f8ec22cdb675a3bc792c7c1edf6" + "hash" : "7bfe54cf7d885985fb7e06ad0abaf4e9" }, "app-phame-glow-large" : { "name" : "app-phame-glow-large", "rule" : ".app-phame-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-phame-light-large", - "hash" : "4587c25ff8a94fd48a1a0ca2e9fd9f42" + "hash" : "60013586092f2c5eb5ed1f58c7f02a74" }, "app-phame-light-large" : { "name" : "app-phame-light-large", "rule" : ".app-phame-light-large", - "hash" : "265471ec8d3c7ddeb3c269384d22243d" + "hash" : "5266f8774d0470adc65f610c9175a251" }, "app-phid-blue-large" : { "name" : "app-phid-blue-large", "rule" : ".app-phid-blue-large, .phabricator-crumb-view:hover .app-phid-dark-large", - "hash" : "b94bc233e1bcf520c65351b71794c228" + "hash" : "d726ca94608547ff3974a1d49e6b1012" }, "app-phid-dark-large" : { "name" : "app-phid-dark-large", "rule" : ".app-phid-dark-large", - "hash" : "f4dfdcc8e1fde50cfcb7e07376696964" + "hash" : "04af0c932bea8b7c36f6dc954994ea11" }, "app-phid-glow-large" : { "name" : "app-phid-glow-large", "rule" : ".app-phid-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-phid-light-large", - "hash" : "10ec316b409b385e19800048fcb1a79e" + "hash" : "b1e8a6e4ac9ad64d34fbc7560d507e5b" }, "app-phid-light-large" : { "name" : "app-phid-light-large", "rule" : ".app-phid-light-large", - "hash" : "0087c573b07d8badaeadcb8ad560ae9b" + "hash" : "0ba23a08c29e8064fdddee9112c638e3" }, "app-pholio-blue-large" : { "name" : "app-pholio-blue-large", "rule" : ".app-pholio-blue-large, .phabricator-crumb-view:hover .app-pholio-dark-large", - "hash" : "5b8e3f47a49a0dee84c1b7c228884f0c" + "hash" : "08bfdf63411a09e6be88d99128c1e9f8" }, "app-pholio-dark-large" : { "name" : "app-pholio-dark-large", "rule" : ".app-pholio-dark-large", - "hash" : "4a73276e5bcd9cfbb08435ed36051dff" + "hash" : "2a8bfa3870726691766fe3f6cb73df38" }, "app-pholio-glow-large" : { "name" : "app-pholio-glow-large", "rule" : ".app-pholio-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-pholio-light-large", - "hash" : "aca383c3c4fcec4742a11702e3427221" + "hash" : "499b68a80e78ab5f6ebe5ba7470fbb4a" }, "app-pholio-light-large" : { "name" : "app-pholio-light-large", "rule" : ".app-pholio-light-large", - "hash" : "1a3ace478c2b0f9b444005112e17c695" + "hash" : "9a4d4223e6e1d7a77c4545504ea0908c" }, "app-phpast-blue-large" : { "name" : "app-phpast-blue-large", "rule" : ".app-phpast-blue-large, .phabricator-crumb-view:hover .app-phpast-dark-large", - "hash" : "22ba8a058d6b920a909c5f6731f301a0" + "hash" : "a9f4f0a62e5841b2ed669dc02694419d" }, "app-phpast-dark-large" : { "name" : "app-phpast-dark-large", "rule" : ".app-phpast-dark-large", - "hash" : "bdbfd96cb50a8b7450daf82576fcfe95" + "hash" : "1dbc83cc09d722253b634f3308608627" }, "app-phpast-glow-large" : { "name" : "app-phpast-glow-large", "rule" : ".app-phpast-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-phpast-light-large", - "hash" : "ce7433350eeaee95ecf358905ad38029" + "hash" : "e98e4cdc93e51b0d7c1df25c01c75fac" }, "app-phpast-light-large" : { "name" : "app-phpast-light-large", "rule" : ".app-phpast-light-large", - "hash" : "5ebd26eb5e0bc0229db5696020dd9b4a" + "hash" : "c63fb0fe3cc326f1a19e4e59c42a73f7" }, "app-phriction-blue-large" : { "name" : "app-phriction-blue-large", "rule" : ".app-phriction-blue-large, .phabricator-crumb-view:hover .app-phriction-dark-large", - "hash" : "0134e9d694ce72a6d9c554e639a6ed50" + "hash" : "55bbded073e078117369f42e05b5b5c4" }, "app-phriction-dark-large" : { "name" : "app-phriction-dark-large", "rule" : ".app-phriction-dark-large", - "hash" : "e4f3121261bc96e00bb6b94b467582f4" + "hash" : "944c3a520a484580895b287eaaa103b1" }, "app-phriction-glow-large" : { "name" : "app-phriction-glow-large", "rule" : ".app-phriction-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-phriction-light-large", - "hash" : "27612f55aaa40c4178a3a5a46d225947" + "hash" : "84639b5ccba94daf1850a9449131a078" }, "app-phriction-light-large" : { "name" : "app-phriction-light-large", "rule" : ".app-phriction-light-large", - "hash" : "a56dcfca00861938d337cc2f217b33f6" + "hash" : "2ca79fdfd141b0fe00ff8b2e13df73bf" }, "app-ponder-blue-large" : { "name" : "app-ponder-blue-large", "rule" : ".app-ponder-blue-large, .phabricator-crumb-view:hover .app-ponder-dark-large", - "hash" : "1bfc2f6150bd67cc25cbe1fbc9283f9c" + "hash" : "8018fe4ebc1e9af91a8a737e0505aa5d" }, "app-ponder-dark-large" : { "name" : "app-ponder-dark-large", "rule" : ".app-ponder-dark-large", - "hash" : "6efc0b3a74d2cc9eb5de96205613b640" + "hash" : "1da67495789c69621f91800939ea9684" }, "app-ponder-glow-large" : { "name" : "app-ponder-glow-large", "rule" : ".app-ponder-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-ponder-light-large", - "hash" : "9c2a2506e53e6a902976d504dfe94b46" + "hash" : "f73a1b5a6b688c6d3feba14193357147" }, "app-ponder-light-large" : { "name" : "app-ponder-light-large", "rule" : ".app-ponder-light-large", - "hash" : "595895068b10c68b0e05234570a6a268" + "hash" : "eb8b13c3bc35f36b14f33ef1158b71ab" }, "app-power-blue-large" : { "name" : "app-power-blue-large", "rule" : ".app-power-blue-large, .phabricator-crumb-view:hover .app-power-dark-large", - "hash" : "c3e03022f162f986f784b2a43c8784c7" + "hash" : "743499c84546b7b35139eec60bf74c34" }, "app-power-dark-large" : { "name" : "app-power-dark-large", "rule" : ".app-power-dark-large", - "hash" : "52d04564ca2cc7f3a96809e827162f3e" + "hash" : "1a3520a2ec255f5b7f1779ea66153ade" }, "app-power-glow-large" : { "name" : "app-power-glow-large", "rule" : ".app-power-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-power-light-large", - "hash" : "3f7719f0299abef8ba900e79fb6b5015" + "hash" : "3951e012561a0d5d5d2b00711b13fa9c" }, "app-power-light-large" : { "name" : "app-power-light-large", "rule" : ".app-power-light-large", - "hash" : "ffe9f181e6103eab9fc688ab84b07ad1" + "hash" : "52d04bd829dfe7477a9dc2ef916990ab" }, "app-projects-blue-large" : { "name" : "app-projects-blue-large", "rule" : ".app-projects-blue-large, .phabricator-crumb-view:hover .app-projects-dark-large", - "hash" : "494ca64479f68588823e00609496414a" + "hash" : "278113829ca3543b9377030555e04edc" }, "app-projects-dark-large" : { "name" : "app-projects-dark-large", "rule" : ".app-projects-dark-large", - "hash" : "fa85ad644a2e289cb6bea2a67ab534f8" + "hash" : "b6f043db039d4960397f76904a84e9fc" }, "app-projects-glow-large" : { "name" : "app-projects-glow-large", "rule" : ".app-projects-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-projects-light-large", - "hash" : "b28bf212416595b3ba4bfb528dfaf791" + "hash" : "3d1bf3efdbd9ccdbb73fc3a11d5d1265" }, "app-projects-light-large" : { "name" : "app-projects-light-large", "rule" : ".app-projects-light-large", - "hash" : "228db63ac0e80b3cef46903a003a44df" + "hash" : "88c73c7cb50ce7cf9cd8d33ec20c8245" }, "app-repositories-blue-large" : { "name" : "app-repositories-blue-large", "rule" : ".app-repositories-blue-large, .phabricator-crumb-view:hover .app-repositories-dark-large", - "hash" : "a83dd2186f9d92949f19a97f8f777a9c" + "hash" : "0642bf1118210cef9105cc463ec3d36f" }, "app-repositories-dark-large" : { "name" : "app-repositories-dark-large", "rule" : ".app-repositories-dark-large", - "hash" : "30ead88c9f018797a8d5ef2f4e4221fe" + "hash" : "c92eb4e857d74f1ef206ba5b184ad88c" }, "app-repositories-glow-large" : { "name" : "app-repositories-glow-large", "rule" : ".app-repositories-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-repositories-light-large", - "hash" : "44b04cbf1652211fbc2046c7773b4cf2" + "hash" : "7fe40fbb4150dfbc6133c79578fc1494" }, "app-repositories-light-large" : { "name" : "app-repositories-light-large", "rule" : ".app-repositories-light-large", - "hash" : "bcba180d121f9269787509ba7cdd3e48" + "hash" : "446a7eab7b7fc07329bc21a77c438033" }, "app-settings-blue-large" : { "name" : "app-settings-blue-large", "rule" : ".app-settings-blue-large, .phabricator-crumb-view:hover .app-settings-dark-large", - "hash" : "c615df792c7e81b35cfbb78ece39e796" + "hash" : "4d22a7f016509777bb5b55f39198d9d7" }, "app-settings-dark-large" : { "name" : "app-settings-dark-large", "rule" : ".app-settings-dark-large", - "hash" : "6c174857e23a9d169d0cb4079aa14637" + "hash" : "55e0869a51f70cacdd72f2baad4b28ce" }, "app-settings-glow-large" : { "name" : "app-settings-glow-large", "rule" : ".app-settings-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-settings-light-large", - "hash" : "4d8c68dc709d99141a19aad5bc483971" + "hash" : "314ab0f607baa65ff6a684b1ddd4861d" }, "app-settings-light-large" : { "name" : "app-settings-light-large", "rule" : ".app-settings-light-large", - "hash" : "e901b672f2a51ef286369bfea70a7e8d" + "hash" : "41da4708f38fae918af46505e566bd6a" }, "app-setup-blue-large" : { "name" : "app-setup-blue-large", "rule" : ".app-setup-blue-large, .phabricator-crumb-view:hover .app-setup-dark-large", - "hash" : "a2f8f470c3cd928e8c1a6959ff745789" + "hash" : "74d2ba681cdad54b31d53f7c174f5826" }, "app-setup-dark-large" : { "name" : "app-setup-dark-large", "rule" : ".app-setup-dark-large", - "hash" : "3183fafc1dc05b851ba902ace2dfa34d" + "hash" : "89a94fe1ce36351d3ea81f1776fb061a" }, "app-setup-glow-large" : { "name" : "app-setup-glow-large", "rule" : ".app-setup-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-setup-light-large", - "hash" : "d91b7e5480cb4296871b9f1c4c634256" + "hash" : "53942c73b14210f5bf0bfad68bcb4431" }, "app-setup-light-large" : { "name" : "app-setup-light-large", "rule" : ".app-setup-light-large", - "hash" : "419829d244a85f97d67fb45c6febd4e5" + "hash" : "890dd2d7cb1e51992b202dd462d56ba6" }, "app-slowvote-blue-large" : { "name" : "app-slowvote-blue-large", "rule" : ".app-slowvote-blue-large, .phabricator-crumb-view:hover .app-slowvote-dark-large", - "hash" : "941028e7abbe491e2911fb24c4a8edca" + "hash" : "12299956375e7f382217ebf8c1cb8203" }, "app-slowvote-dark-large" : { "name" : "app-slowvote-dark-large", "rule" : ".app-slowvote-dark-large", - "hash" : "6197df3550b652011bc1a8da00005059" + "hash" : "ce57e4a318e4e8d556f713b459e6d798" }, "app-slowvote-glow-large" : { "name" : "app-slowvote-glow-large", "rule" : ".app-slowvote-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-slowvote-light-large", - "hash" : "43783af8df4f99e94f0989ca149264f2" + "hash" : "dcd5be64ded69e0fdfee5364367c9b55" }, "app-slowvote-light-large" : { "name" : "app-slowvote-light-large", "rule" : ".app-slowvote-light-large", - "hash" : "23eb39153b5ac9b5bd91c8b800023d93" + "hash" : "7ac2515f26b194a9fafaa6a27997be2a" }, "app-uiexamples-blue-large" : { "name" : "app-uiexamples-blue-large", "rule" : ".app-uiexamples-blue-large, .phabricator-crumb-view:hover .app-uiexamples-dark-large", - "hash" : "eabac7f7b83c47618a5f72b6f30b6410" + "hash" : "7add7df6b621c4af5322160bc1cd31b2" }, "app-uiexamples-dark-large" : { "name" : "app-uiexamples-dark-large", "rule" : ".app-uiexamples-dark-large", - "hash" : "31c9fb99289cc73aae73f3acad66b449" + "hash" : "d8563a5f06692a313a2eff11235d5d0d" }, "app-uiexamples-glow-large" : { "name" : "app-uiexamples-glow-large", "rule" : ".app-uiexamples-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-uiexamples-light-large", - "hash" : "069e59208dad509a6c3d74d102f08ae8" + "hash" : "0532cdd91b6de17ab194bd29cacfc24f" }, "app-uiexamples-light-large" : { "name" : "app-uiexamples-light-large", "rule" : ".app-uiexamples-light-large", - "hash" : "b384102bcee1b312b2e06abc5f4b27de" + "hash" : "ee40dd0e3168f8e7fb520665a1d50f95" } }, "scales" : [ 1, 2 ], "header" : "\/**\n * @provides sprite-apps-large-css\n * @generated\n *\/\n\n.sprite-apps-large {\n background-image: url(\/rsrc\/image\/sprite-apps-large.png);\n background-repeat: no-repeat;\n}\n\n@media\nonly screen and (min-device-pixel-ratio: 1.5),\nonly screen and (-webkit-min-device-pixel-ratio: 1.5) {\n .sprite-apps-large {\n background-image: url(\/rsrc\/image\/sprite-apps-large-X2.png);\n background-size: {X}px {Y}px;\n }\n}\n", "type" : "standard" } diff --git a/resources/sprite/manifest/apps.json b/resources/sprite/manifest/apps.json index 5d8cb21cba..eb91d4e902 100644 --- a/resources/sprite/manifest/apps.json +++ b/resources/sprite/manifest/apps.json @@ -1,201 +1,206 @@ { "version" : 1, "sprites" : { "app-application-dark" : { "name" : "app-application-dark", "rule" : ".app-application-dark", - "hash" : "89f861c28e97878311885623cff3d314" + "hash" : "60e228106718bf6f3ee5024400d31f24" }, "app-audit-dark" : { "name" : "app-audit-dark", "rule" : ".app-audit-dark", - "hash" : "2c141bc445c4fe62986cd6cff0c29b36" + "hash" : "38339b9cc4e39cbbbea36dcf039873bb" }, "app-calendar-dark" : { "name" : "app-calendar-dark", "rule" : ".app-calendar-dark", - "hash" : "04c61a081986f0d38cf27fc4e18bce40" + "hash" : "756d60566639ad1424444436a95c6a3f" }, "app-conduit-dark" : { "name" : "app-conduit-dark", "rule" : ".app-conduit-dark", - "hash" : "7b410e96c87e7818fb93bdfa2ed9368f" + "hash" : "01fba8ca32f1cfefb3516b45c9d28b40" + }, + "app-conpherence-dark" : { + "name" : "app-conpherence-dark", + "rule" : ".app-conpherence-dark", + "hash" : "dbb6fdd5f082a604b4ef10b7eeedbfa2" }, "app-countdown-dark" : { "name" : "app-countdown-dark", "rule" : ".app-countdown-dark", - "hash" : "8891502317896beea6a5f9ec87eb5e2e" + "hash" : "625f2589ee491aead58aaa5b965a7451" }, "app-daemon-dark" : { "name" : "app-daemon-dark", "rule" : ".app-daemon-dark", - "hash" : "23a9a2927b368e2328dd70f95c5b1a07" + "hash" : "4472be3242150f06ea5bf7b45333c4c5" }, "app-differential-dark" : { "name" : "app-differential-dark", "rule" : ".app-differential-dark", - "hash" : "bb7032f3c17901f242f9bbbcdc9a721c" + "hash" : "508401fe36d9636bdcbdcbcae253c152" }, "app-diffusion-dark" : { "name" : "app-diffusion-dark", "rule" : ".app-diffusion-dark", - "hash" : "46ab6648a6ae04e4fd1a28a9afcc4996" + "hash" : "0a6f8c85079c4a325430197adb05967c" }, "app-diviner-dark" : { "name" : "app-diviner-dark", "rule" : ".app-diviner-dark", - "hash" : "e21a74e866a6fc22a991b8df6efc3ca7" + "hash" : "08872eb1c6bb51b9727290f6fa802633" }, "app-drydock-dark" : { "name" : "app-drydock-dark", "rule" : ".app-drydock-dark", - "hash" : "ed44013d98257a23306bad9c6b24760d" + "hash" : "d50309da57021c676774f9bdc68c5fe7" }, "app-fact-dark" : { "name" : "app-fact-dark", "rule" : ".app-fact-dark", - "hash" : "f373f38e784289b866ab914471c342ec" + "hash" : "0c1be568e1ac05fca814718600190369" }, "app-feed-dark" : { "name" : "app-feed-dark", "rule" : ".app-feed-dark", - "hash" : "c4f1765e70615c6ee4cae6e8135fb969" + "hash" : "830232709eedbe6ce7cdbcebf182c86c" }, "app-files-dark" : { "name" : "app-files-dark", "rule" : ".app-files-dark", - "hash" : "7faf45efa5b9b97e571bc66636ca1a15" + "hash" : "00f5ab7ea3e9367e378cf9f395400ed4" }, "app-flags-dark" : { "name" : "app-flags-dark", "rule" : ".app-flags-dark", - "hash" : "10298f695592714e27f72ef746ffd8a9" + "hash" : "6382f373f7b0e70522d80ce06ef62813" }, "app-help-dark" : { "name" : "app-help-dark", "rule" : ".app-help-dark", - "hash" : "5cf715cc566b98c87958793eebea5f35" + "hash" : "2299a14e27d76fdf66209ef0042cc84f" }, "app-herald-dark" : { "name" : "app-herald-dark", "rule" : ".app-herald-dark", - "hash" : "e3bc39a3dd1d66a0abf4594c608a3846" + "hash" : "b2193b62df3bd4cf5c8de514a07fb6c3" }, "app-home-dark" : { "name" : "app-home-dark", "rule" : ".app-home-dark", - "hash" : "7e01fbdfa526919a2d90d2c29a6c9fa0" + "hash" : "88f020497fcbcf43729aa817695b174f" }, "app-logo-dark" : { "name" : "app-logo-dark", "rule" : ".app-logo-dark", - "hash" : "39701e1282fd120e77b09ed9fcddc686" + "hash" : "02e71ae2421f1949f2ef075c27e052c9" }, "app-macro-dark" : { "name" : "app-macro-dark", "rule" : ".app-macro-dark", - "hash" : "ef89457bcee666ad265de1659b9b8a62" + "hash" : "8e0e72847a8f70eb3f8e60e7fb681c06" }, "app-mail-dark" : { "name" : "app-mail-dark", "rule" : ".app-mail-dark", - "hash" : "4d05a5cd4360052183e91f61967a6c57" + "hash" : "a2a792fddc44be4ae0f1a601380c8449" }, "app-maniphest-dark" : { "name" : "app-maniphest-dark", "rule" : ".app-maniphest-dark", - "hash" : "320da127d7f887e09965a0416d5e44d3" + "hash" : "ea94fc7dbb2267adc33513f78916fe90" }, "app-metamta-dark" : { "name" : "app-metamta-dark", "rule" : ".app-metamta-dark", - "hash" : "51f100c2a7a80149404dbc8b27f595a9" + "hash" : "8abbb6e74d1697f950a01dcd6c8077be" }, "app-owners-dark" : { "name" : "app-owners-dark", "rule" : ".app-owners-dark", - "hash" : "33c064dd3b7fc3f9eb934d0cf84f3af5" + "hash" : "23b948cc1d32a0968785fbfca749dcdf" }, "app-paste-dark" : { "name" : "app-paste-dark", "rule" : ".app-paste-dark", - "hash" : "9482649caa8e5a46d277271092517b12" + "hash" : "9e0c1d1fe03aebcb55a4d19be051e255" }, "app-people-dark" : { "name" : "app-people-dark", "rule" : ".app-people-dark", - "hash" : "67245eafa79367e4e07289549cf34deb" + "hash" : "0b3995fcd043b506a408de6e25ad5292" }, "app-phame-dark" : { "name" : "app-phame-dark", "rule" : ".app-phame-dark", - "hash" : "029d7d48523cc43b0404bf40ccf56f8b" + "hash" : "24ff4d322bce13f1c156ce5361a03a07" }, "app-phid-dark" : { "name" : "app-phid-dark", "rule" : ".app-phid-dark", - "hash" : "2099c2987fe3929ce1d9dec470c7699d" + "hash" : "5a0ac05bbf36a7aeb36753d093c3c9f8" }, "app-pholio-dark" : { "name" : "app-pholio-dark", "rule" : ".app-pholio-dark", - "hash" : "aab47c79d2e03fdcaffb6f41dc1e0f06" + "hash" : "7d3befd1c12dd464a5f5edbef4574a5c" }, "app-phpast-dark" : { "name" : "app-phpast-dark", "rule" : ".app-phpast-dark", - "hash" : "e6db72b398f57d03a400c9c18bd3c412" + "hash" : "de1ad812c7a177c844fcff626b1abebf" }, "app-phriction-dark" : { "name" : "app-phriction-dark", "rule" : ".app-phriction-dark", - "hash" : "8064272206874a324d20d956c8fb10da" + "hash" : "8596da3f375087db6a163c98f0c968ae" }, "app-ponder-dark" : { "name" : "app-ponder-dark", "rule" : ".app-ponder-dark", - "hash" : "abdb353635bed5cfd48a176b4340022f" + "hash" : "232577eb875f383f45cb9dbd9a4e3976" }, "app-power-dark" : { "name" : "app-power-dark", "rule" : ".app-power-dark", - "hash" : "d3e943d1267206963d8f9419629c5581" + "hash" : "e3708b1b4bfdfc614d9cf630943e5bef" }, "app-projects-dark" : { "name" : "app-projects-dark", "rule" : ".app-projects-dark", - "hash" : "6bd7c598e2f2cf0b77918a7b0fa8bd19" + "hash" : "5e799f1e95ecfd33cb67b6e4ac992043" }, "app-repositories-dark" : { "name" : "app-repositories-dark", "rule" : ".app-repositories-dark", - "hash" : "db2823a16dae198145f53e8021170740" + "hash" : "736066962e96df88eacc04d734613a0e" }, "app-settings-dark" : { "name" : "app-settings-dark", "rule" : ".app-settings-dark", - "hash" : "1c84d22b769730d9e8b6fcd3414de72c" + "hash" : "2fadcf918fb084bd3452712f700ae1a0" }, "app-setup-dark" : { "name" : "app-setup-dark", "rule" : ".app-setup-dark", - "hash" : "27db76695d99be0c25368dc9e0932b17" + "hash" : "061b80f3555ade1c36934474b61fe76b" }, "app-slowvote-dark" : { "name" : "app-slowvote-dark", "rule" : ".app-slowvote-dark", - "hash" : "0d5861fab4562ad21242e34f9a29a33e" + "hash" : "e51cc1e6887f2deaff02d9c60aae36e0" }, "app-uiexamples-dark" : { "name" : "app-uiexamples-dark", "rule" : ".app-uiexamples-dark", - "hash" : "6416a3d9d9007673ee558433b80692a1" + "hash" : "dd919fd2c10e7d1e0915f523ac3922ce" } }, "scales" : [ 1, 2 ], "header" : "\/**\n * @provides sprite-apps-css\n * @generated\n *\/\n\n.sprite-apps {\n background-image: url(\/rsrc\/image\/sprite-apps.png);\n background-repeat: no-repeat;\n}\n\n@media\nonly screen and (min-device-pixel-ratio: 1.5),\nonly screen and (-webkit-min-device-pixel-ratio: 1.5) {\n .sprite-apps {\n background-image: url(\/rsrc\/image\/sprite-apps-X2.png);\n background-size: {X}px {Y}px;\n }\n}\n", "type" : "standard" } diff --git a/resources/sprite/manifest/gradient.json b/resources/sprite/manifest/gradient.json index 484ab83f2b..2cb5b6e879 100644 --- a/resources/sprite/manifest/gradient.json +++ b/resources/sprite/manifest/gradient.json @@ -1,75 +1,75 @@ { "version" : 1, "sprites" : { "gradient-black-dark" : { "name" : "gradient-black-dark", "rule" : ".gradient-black-dark, button.black, a.black, a.black:visited", - "hash" : "b9faf8505427bb14a8c51324e13e2f81" + "hash" : "17425d8c9c53672ab2edbd236e6efd7a" }, "gradient-black-light" : { "name" : "gradient-black-light", "rule" : ".gradient-black-light, button.black:active, a.black:active", - "hash" : "812c3375d00ccc93c36c6df2eb565df4" + "hash" : "c4fb2231553d2894fd2c97beaa8bfe39" }, "gradient-blue-dark" : { "name" : "gradient-blue-dark", "rule" : ".gradient-blue-dark, button, a.button, a.button:visited, input.inputsubmit", - "hash" : "adc2d0f7397374936384014c5d78550d" + "hash" : "f467612edcdbf984672287c6086492c4" }, "gradient-blue-light" : { "name" : "gradient-blue-light", "rule" : ".gradient-blue-light, button:active, a.button:active", - "hash" : "91b841067a63e543a4dcd9d41e0a2e5c" + "hash" : "471d47c102def6db46b345310aac5a03" }, "gradient-breadcrumbs" : { "name" : "gradient-breadcrumbs", "rule" : ".gradient-breadcrumbs", - "hash" : "688ab77f50cfbc17ec30d798efb1b39e" + "hash" : "3d0f8634df5bc29eaf2a5a01bae79cf1" }, "gradient-dark-menu-label" : { "name" : "gradient-dark-menu-label", "rule" : ".gradient-dark-menu-label, .phabricator-dark-menu .phabricator-menu-item-type-label", - "hash" : "89a908596142d38fbe61a706694cd321" + "hash" : "e0d4a455142f9c4745d36ad8b7dd3f78" }, "gradient-green-dark" : { "name" : "gradient-green-dark", "rule" : ".gradient-green-dark, button.green, a.green, a.green:visited", - "hash" : "0d19ab593772b6b406c0db309b3a14fb" + "hash" : "a6719fe55b2b0e527ed32985691eab34" }, "gradient-green-light" : { "name" : "gradient-green-light", "rule" : ".gradient-green-light, button.green:active, a.green:active", - "hash" : "71c67916327ec7fc65149ab72c3a2924" + "hash" : "124969cc7805bbd754005bc702e24c54" }, "gradient-grey-dark" : { "name" : "gradient-grey-dark", "rule" : ".gradient-grey-dark, button.grey, input.inputaux, a.grey, a.grey:visited, a.button.disabled, button[disabled], button.disabled", - "hash" : "32651902d28d37dca01cf067072c39c0" + "hash" : "fac28a773098fc62bf571e12b843f71a" }, "gradient-grey-light" : { "name" : "gradient-grey-light", "rule" : ".gradient-grey-light, button.grey:active, a.grey:active, button.grey_active, a.dropdown-open", - "hash" : "c3c9ee1ed6f800a4ac86910b94687877" + "hash" : "83c6128f59fc2e426c912c2f73f5b92b" }, "gradient-menu-hover" : { "name" : "gradient-menu-hover", "rule" : ".gradient-menu-hover, .device-desktop .phabricator-side-menu a.phabricator-menu-item-type-link:hover, .phabricator-filetree a.phabricator-filetree-item:hover", - "hash" : "856380207ac8c5cb6770d44dceb245a8" + "hash" : "e6e064156d66952180e99b00996ffc38" }, "gradient-menu-label" : { "name" : "gradient-menu-label", "rule" : ".gradient-menu-label, .phabricator-side-menu .phabricator-menu-item-type-label", - "hash" : "8ad8352b077ae02820ebbbae26dc669b" + "hash" : "04b9943f5b06c8cb21fe6b96714e6662" }, "gradient-menu-selected" : { "name" : "gradient-menu-selected", "rule" : ".gradient-menu-selected, .phabricator-side-menu .phabricator-menu-item-selected, .device-desktop .phabricator-side-menu a.phabricator-menu-item-selected:hover, .phabricator-nav-local a.phabricator-active-nav-focus", - "hash" : "815bafb94e11c23e1a419ea85dcae113" + "hash" : "9b4b039fba177b90bc26f0e6eece339d" } }, "scales" : [ 1 ], "header" : "\/**\n * @provides sprite-gradient-css\n * @generated\n *\/\n\n.sprite-gradient, button, a.button, a.button:visited, input.inputsubmit, .phabricator-dark-menu .phabricator-menu-item-type-label, .phabricator-side-menu .phabricator-menu-item-type-label, .device-desktop .phabricator-side-menu a.phabricator-menu-item-type-link:hover, .phabricator-side-menu .phabricator-menu-item-selected, .device-desktop .phabricator-side-menu a.phabricator-menu-item-selected:hover, .phabricator-filetree a.phabricator-filetree-item:hover, .phabricator-filetree a.phabricator-active-nav-focus {\n background-image: url(\/rsrc\/image\/sprite-gradient.png);\n background-repeat: repeat-x;\n}\n\n\n", "type" : "repeat-x" } diff --git a/resources/sprite/manifest/icon.json b/resources/sprite/manifest/icon.json index 6352e4ada4..184f84eb34 100644 --- a/resources/sprite/manifest/icon.json +++ b/resources/sprite/manifest/icon.json @@ -1,1016 +1,1016 @@ { "version" : 1, "sprites" : { "action-arrow_left" : { "name" : "action-arrow_left", "rule" : ".action-arrow_left", - "hash" : "439cd6051e6aab63b62d1e47f00ad4a0" + "hash" : "18a72fcb866d409a6273883cc56b4862" }, "action-arrow_left-grey" : { "name" : "action-arrow_left-grey", "rule" : ".action-arrow_left-grey", - "hash" : "a3d0d34ef06a95685bf7a3e05eb97045" + "hash" : "200067f0f3af28260f95632eb17c373a" }, "action-arrow_left-white" : { "name" : "action-arrow_left-white", "rule" : ".action-arrow_left-white, .device-desktop .phabricator-action-view:hover .action-arrow_left", - "hash" : "e113bc929cedac55146edcf6e22f2fe0" + "hash" : "f21ee5fc3b0ad93d1ca18c71e6a62623" }, "action-arrow_right" : { "name" : "action-arrow_right", "rule" : ".action-arrow_right", - "hash" : "06b693491c0594d4e7ff537dbd725a98" + "hash" : "64fb031691e8711ec2922644831a4b05" }, "action-arrow_right-grey" : { "name" : "action-arrow_right-grey", "rule" : ".action-arrow_right-grey", - "hash" : "894f051068f9e206d96576ca6d14fd4f" + "hash" : "7d3a0c9e65b9917ccc5acf3ec1ccad2e" }, "action-arrow_right-white" : { "name" : "action-arrow_right-white", "rule" : ".action-arrow_right-white, .device-desktop .phabricator-action-view:hover .action-arrow_right", - "hash" : "aebf657073a1a85eeb0887cf32db8f08" + "hash" : "b16e8688f68d9f225aae11fa2de98f41" }, "action-attach" : { "name" : "action-attach", "rule" : ".action-attach", - "hash" : "a062d26bbe37abd305998545885fb1c0" + "hash" : "4aeca7c85a2c384c25c0a5d27aa2a41f" }, "action-attach-grey" : { "name" : "action-attach-grey", "rule" : ".action-attach-grey", - "hash" : "09eae1092a9f48ec48b8970be67351b7" + "hash" : "6d528ecda66e9919452cbca77f94d034" }, "action-attach-white" : { "name" : "action-attach-white", "rule" : ".action-attach-white, .device-desktop .phabricator-action-view:hover .action-attach", - "hash" : "1f69f442d87f6e27980229dbedfbf728" + "hash" : "75b0dcbb6f6f297b647266165bd0ac77" }, "action-blame" : { "name" : "action-blame", "rule" : ".action-blame", - "hash" : "81fbaa234aed3a379c403aa0c7f3c7eb" + "hash" : "467a17a711c501b51318b2661d38458c" }, "action-blame-grey" : { "name" : "action-blame-grey", "rule" : ".action-blame-grey", - "hash" : "4b383ffb76ee537ce9b6fadb8d2ee160" + "hash" : "b5def77f42ef0fc2eb8141f54a6c730b" }, "action-blame-white" : { "name" : "action-blame-white", "rule" : ".action-blame-white, .device-desktop .phabricator-action-view:hover .action-blame", - "hash" : "e975ef46298c46530659e12fbd012292" + "hash" : "ef8bcbb695d0af2ef18c7be1fe308641" }, "action-check" : { "name" : "action-check", "rule" : ".action-check", - "hash" : "c8b9c56214fd39a4ba99e07e1fa72e22" + "hash" : "0db35013c33b71355dc33912073d0c28" }, "action-check-grey" : { "name" : "action-check-grey", "rule" : ".action-check-grey", - "hash" : "2375808574c858425660eac59d80e29a" + "hash" : "381b82f1a08592cf1c3f23b3d12c0456" }, "action-check-white" : { "name" : "action-check-white", "rule" : ".action-check-white, .device-desktop .phabricator-action-view:hover .action-check", - "hash" : "803fbc2117621cf946af270cf5bed06b" + "hash" : "be412e3b2d3574bb04721b2f8646b67e" }, "action-comment" : { "name" : "action-comment", "rule" : ".action-comment", - "hash" : "bb9067094e0cb805dc597eb0ebdd94f9" + "hash" : "5cbd81c2469dc95048abf073d977f7e2" }, "action-comment-grey" : { "name" : "action-comment-grey", "rule" : ".action-comment-grey", - "hash" : "8d71bd6c89116ca02aef8ce830514022" + "hash" : "be352ed442c144230f65c0a4c4d56a64" }, "action-comment-white" : { "name" : "action-comment-white", "rule" : ".action-comment-white, .device-desktop .phabricator-action-view:hover .action-comment", - "hash" : "48bfa57a5b06edcf08329b47fc546071" + "hash" : "5f428fb791a23e4a8e2c15f66ff23485" }, "action-computer" : { "name" : "action-computer", "rule" : ".action-computer", - "hash" : "4e25c6822b815a2c29478082012d1237" + "hash" : "ab8e3d101f3f1a8b434d449ef1b9abd3" }, "action-computer-grey" : { "name" : "action-computer-grey", "rule" : ".action-computer-grey", - "hash" : "d2972bca3937fc49e859019c0fd6647f" + "hash" : "6ad695eb4df2f2db3268513307439280" }, "action-computer-white" : { "name" : "action-computer-white", "rule" : ".action-computer-white, .device-desktop .phabricator-action-view:hover .action-computer", - "hash" : "154afcf0ee1539c0d5a273c971a8c6e1" + "hash" : "773aaa54b567fb9de636e3d4be417b3a" }, "action-create" : { "name" : "action-create", "rule" : ".action-create", - "hash" : "5901de6f71af459888d1b277d0726916" + "hash" : "b6f1daca7830bd72f390e7d64630c366" }, "action-create-grey" : { "name" : "action-create-grey", "rule" : ".action-create-grey", - "hash" : "3efad05cb3ac57da962e2bc1c5ff2308" + "hash" : "fa830394fbf05528cd3c655ab0481d0a" }, "action-create-white" : { "name" : "action-create-white", "rule" : ".action-create-white, .device-desktop .phabricator-action-view:hover .action-create", - "hash" : "8e06e0eb1031b008ca4a32eba9934289" + "hash" : "addfa0ab79944ca318ffc57e568bae9c" }, "action-delete" : { "name" : "action-delete", "rule" : ".action-delete", - "hash" : "41bbd0d0d4cb69b2b5423367603187e3" + "hash" : "174c6a08a8a7131cef810e006b5a71e0" }, "action-delete-grey" : { "name" : "action-delete-grey", "rule" : ".action-delete-grey", - "hash" : "244047621dbeefd392c4c7f3059a9e6a" + "hash" : "e541601ce768fb2fa1a941a95ac3a7cf" }, "action-delete-white" : { "name" : "action-delete-white", "rule" : ".action-delete-white, .device-desktop .phabricator-action-view:hover .action-delete", - "hash" : "deb1e03b1aa95a07fa16ee82f9605914" + "hash" : "496e780e0470bce85116baaa3aebdab2" }, "action-disable" : { "name" : "action-disable", "rule" : ".action-disable", - "hash" : "e0db051423597acbf4611467227989f3" + "hash" : "0a0b314012bdaaa307ac70d2581c20b5" }, "action-disable-grey" : { "name" : "action-disable-grey", "rule" : ".action-disable-grey", - "hash" : "301c0440f503fba4c3e1d0adc9f8dad6" + "hash" : "c7741a4579c4e7a1c94dfd029b3e3bb0" }, "action-disable-white" : { "name" : "action-disable-white", "rule" : ".action-disable-white, .device-desktop .phabricator-action-view:hover .action-disable", - "hash" : "cb5ee0cda04760e0568e8245a807754f" + "hash" : "3f456c6f15d4aaccfe85ae73e856ca1c" }, "action-dislike" : { "name" : "action-dislike", "rule" : ".action-dislike", - "hash" : "fbacfb7af00bdbd738039643cdf5bc51" + "hash" : "846820ffc823a4899dde8f8c14203df1" }, "action-dislike-grey" : { "name" : "action-dislike-grey", "rule" : ".action-dislike-grey", - "hash" : "73fcb492401b2b18785857f843e577f0" + "hash" : "1e994ac16acba86dae2f9e94ff0df2c2" }, "action-dislike-white" : { "name" : "action-dislike-white", "rule" : ".action-dislike-white, .device-desktop .phabricator-action-view:hover .action-dislike", - "hash" : "6ea8a6df9208f9a790702d801589be7e" + "hash" : "55d374c8466370c8c5805b8135c3f416" }, "action-download" : { "name" : "action-download", "rule" : ".action-download", - "hash" : "a3edf236a8d30a71b46f5126ac32bd6e" + "hash" : "b4517953cb610ad5af5537ac5526a168" }, "action-download-alt" : { "name" : "action-download-alt", "rule" : ".action-download-alt", - "hash" : "eb4d4a8d850b7404332bd4d36067b00a" + "hash" : "7ea7b578f8da62d7aaf82b1e80f0fa96" }, "action-download-alt-grey" : { "name" : "action-download-alt-grey", "rule" : ".action-download-alt-grey", - "hash" : "e19cba41b19ed423ba72d5ec1447cdca" + "hash" : "6b06b8e24433f7b4690a0bda53441399" }, "action-download-alt-white" : { "name" : "action-download-alt-white", "rule" : ".action-download-alt-white, .device-desktop .phabricator-action-view:hover .action-download-alt", - "hash" : "40bd588c9478a92ba592eadb0cd2255d" + "hash" : "f458b2b153b9fd655bdea9c2c73ed569" }, "action-download-grey" : { "name" : "action-download-grey", "rule" : ".action-download-grey", - "hash" : "35df8e7bea8392edfad0e41ffba56204" + "hash" : "d2502bf6e4c56e8c24f564285a3d0f4e" }, "action-download-white" : { "name" : "action-download-white", "rule" : ".action-download-white, .device-desktop .phabricator-action-view:hover .action-download", - "hash" : "88650982d63c7fe1b0df57f19b73764e" + "hash" : "90ca79835936319d143ea5c3b745744e" }, "action-edit" : { "name" : "action-edit", "rule" : ".action-edit", - "hash" : "37b7c707bb18feb66fbad36cd99f82be" + "hash" : "539f11d58239683c73b275335e1cd5ee" }, "action-edit-grey" : { "name" : "action-edit-grey", "rule" : ".action-edit-grey", - "hash" : "a41905d50572da65d4c7e31c6bd5b9cb" + "hash" : "9ac07dfbc52997775aeaa4fafbf43d12" }, "action-edit-white" : { "name" : "action-edit-white", "rule" : ".action-edit-white, .device-desktop .phabricator-action-view:hover .action-edit", - "hash" : "31a23bb50808f363fb8f92ac1774348a" + "hash" : "cb83ff8b6f93bf367233960142abf744" }, "action-enable" : { "name" : "action-enable", "rule" : ".action-enable", - "hash" : "ac321d05767830df55141e143a412c59" + "hash" : "a0d81348f61019149090e89d2d126a8f" }, "action-enable-grey" : { "name" : "action-enable-grey", "rule" : ".action-enable-grey", - "hash" : "637dcb6c96460ffd8e7dc9bcce105665" + "hash" : "8d6bf1d0333b81cde5cbeb8646316863" }, "action-enable-white" : { "name" : "action-enable-white", "rule" : ".action-enable-white, .device-desktop .phabricator-action-view:hover .action-enable", - "hash" : "3856031f36cf1126c6b375419b872158" + "hash" : "6cbadeb75ede97f58a62b0bafbc7aef5" }, "action-file" : { "name" : "action-file", "rule" : ".action-file", - "hash" : "7ddd35db36264115fb7c0a219f561753" + "hash" : "95de3ed156d8e8008a464fee994a8b7a" }, "action-file-grey" : { "name" : "action-file-grey", "rule" : ".action-file-grey", - "hash" : "d1147f0cd62b48c8fca06cbe923c0330" + "hash" : "bd1b94b5ef4ea93570b5dd11f9b6fc2f" }, "action-file-white" : { "name" : "action-file-white", "rule" : ".action-file-white, .device-desktop .phabricator-action-view:hover .action-file", - "hash" : "bb5434e03f07ba3ab4db4a08c91a5a95" + "hash" : "330b3ff7217edaa7b348c1209eeb5301" }, "action-flag" : { "name" : "action-flag", "rule" : ".action-flag", - "hash" : "da0e4bc0ee0b7ca4f307e347a9fe6f85" + "hash" : "017bbfc781bfa2613ade68fd791d7b66" }, "action-flag-0" : { "name" : "action-flag-0", "rule" : ".action-flag-0", - "hash" : "e3c9d406418889ac7f219dc2e4e3695d" + "hash" : "63ae0ab21e802d2cf11c40cb239718a6" }, "action-flag-0-grey" : { "name" : "action-flag-0-grey", "rule" : ".action-flag-0-grey", - "hash" : "d48a88e9782cfc132799f8df5c828fee" + "hash" : "6a9bb10f146c2adbd5ffc8111ce959c8" }, "action-flag-0-white" : { "name" : "action-flag-0-white", "rule" : ".action-flag-0-white, .device-desktop .phabricator-action-view:hover .action-flag-0", - "hash" : "745431f4973ca195c418544375f56163" + "hash" : "f40d6750653f54ce6099c76294ab5b80" }, "action-flag-1" : { "name" : "action-flag-1", "rule" : ".action-flag-1", - "hash" : "76ec571366cba7f3440fdb1c4b9118be" + "hash" : "7f50971290dff274a11930faeeac076b" }, "action-flag-1-grey" : { "name" : "action-flag-1-grey", "rule" : ".action-flag-1-grey", - "hash" : "d5807977961d63b8c52754077a68b2e0" + "hash" : "eb6af245f22f94b81368ac24a5021cb0" }, "action-flag-1-white" : { "name" : "action-flag-1-white", "rule" : ".action-flag-1-white, .device-desktop .phabricator-action-view:hover .action-flag-1", - "hash" : "b8d0afbab58acf0a573dd28d3ad51de3" + "hash" : "c47bfa96d98672bfe5afa85a0cfbec89" }, "action-flag-2" : { "name" : "action-flag-2", "rule" : ".action-flag-2", - "hash" : "e6d3a4ecf63079d053adae81d45c4f0a" + "hash" : "63a979a0d2de57efdcf5fee2192957e1" }, "action-flag-2-grey" : { "name" : "action-flag-2-grey", "rule" : ".action-flag-2-grey", - "hash" : "516c5a8e041b65aea5ddbdb7542b3d12" + "hash" : "46d028b2ddbc26251b5fcc02ec87ca43" }, "action-flag-2-white" : { "name" : "action-flag-2-white", "rule" : ".action-flag-2-white, .device-desktop .phabricator-action-view:hover .action-flag-2", - "hash" : "7c013e587c0e7522952413749e62bd62" + "hash" : "45b1dda7b8c85546d40789ca83ed481c" }, "action-flag-3" : { "name" : "action-flag-3", "rule" : ".action-flag-3", - "hash" : "4bd5ac1c2c0ed4765000fb49811d2c68" + "hash" : "d95b847797e6ad0ae4e5719085530709" }, "action-flag-3-grey" : { "name" : "action-flag-3-grey", "rule" : ".action-flag-3-grey", - "hash" : "f471dcb2c59b7ce1ac83057e71cd3560" + "hash" : "fab7eca7e7a1e75a68a2f86a9ecb4dfd" }, "action-flag-3-white" : { "name" : "action-flag-3-white", "rule" : ".action-flag-3-white, .device-desktop .phabricator-action-view:hover .action-flag-3", - "hash" : "a8eaacbb09c261565ca05a2672b1fdd8" + "hash" : "42f994d618726c1294ac7206accdac0d" }, "action-flag-4" : { "name" : "action-flag-4", "rule" : ".action-flag-4", - "hash" : "f5e87f3bcd0617174961f25c51c7dcc7" + "hash" : "61d60e39d879436ffaa4bf3489c4be62" }, "action-flag-4-grey" : { "name" : "action-flag-4-grey", "rule" : ".action-flag-4-grey", - "hash" : "a2893da9d76f4765782064035313fb2f" + "hash" : "8dc44ff4d36f6e1e4522fc865923a4df" }, "action-flag-4-white" : { "name" : "action-flag-4-white", "rule" : ".action-flag-4-white, .device-desktop .phabricator-action-view:hover .action-flag-4", - "hash" : "5a1c34e6ccaf9f60e51867e593fe86fe" + "hash" : "e948ac8da0548c252ce32f4ff2503790" }, "action-flag-5" : { "name" : "action-flag-5", "rule" : ".action-flag-5", - "hash" : "1100ba1c1351fe594c66a7d68b4f55ce" + "hash" : "597c19fdaa99572b5d65d30d3cb81c13" }, "action-flag-5-grey" : { "name" : "action-flag-5-grey", "rule" : ".action-flag-5-grey", - "hash" : "ef2bb6c72aadb0945f9f56bf24c14174" + "hash" : "24bf02b161815f07e9bcd9e75ba141f6" }, "action-flag-5-white" : { "name" : "action-flag-5-white", "rule" : ".action-flag-5-white, .device-desktop .phabricator-action-view:hover .action-flag-5", - "hash" : "ab3f27db5a080c3aa094d6d50bece2a4" + "hash" : "55bcef156bbd099ada0c39aa796be663" }, "action-flag-6" : { "name" : "action-flag-6", "rule" : ".action-flag-6", - "hash" : "a37b3211517264f5a51c17c50d77a0df" + "hash" : "490fea784ff63de9edffb1d142db49e0" }, "action-flag-6-grey" : { "name" : "action-flag-6-grey", "rule" : ".action-flag-6-grey", - "hash" : "4dd3537f6f61a4f857149a5dea413652" + "hash" : "5b3c14db2a182eb31f1925829adac556" }, "action-flag-6-white" : { "name" : "action-flag-6-white", "rule" : ".action-flag-6-white, .device-desktop .phabricator-action-view:hover .action-flag-6", - "hash" : "49a663b600316d73c521687c69ef8bdd" + "hash" : "f251c82a144e354d241b977992aca356" }, "action-flag-7" : { "name" : "action-flag-7", "rule" : ".action-flag-7", - "hash" : "5f4d6d3df81afe0745b75f810fb4be33" + "hash" : "02c8e4bcca7b2dfd746e6414f3419130" }, "action-flag-7-grey" : { "name" : "action-flag-7-grey", "rule" : ".action-flag-7-grey", - "hash" : "dc17400b19fe344a664568e51bd4c2c1" + "hash" : "cf0b4c737ab286110e2e1e2f1619e7d1" }, "action-flag-7-white" : { "name" : "action-flag-7-white", "rule" : ".action-flag-7-white, .device-desktop .phabricator-action-view:hover .action-flag-7", - "hash" : "063e08f676e39c26b33c6cac8ae14e15" + "hash" : "bc1a5ec732b7d24e78c4dfd686347a6e" }, "action-flag-ghost" : { "name" : "action-flag-ghost", "rule" : ".action-flag-ghost", - "hash" : "3152fe67fc364d460d607e338237acf4" + "hash" : "45e3a9c7a6436fff77a26ac14fe8a2ff" }, "action-flag-ghost-grey" : { "name" : "action-flag-ghost-grey", "rule" : ".action-flag-ghost-grey", - "hash" : "56c962d3557fee90bcb6216ff9df2b84" + "hash" : "effe2cb0f7bf9d8498de00cb9d2219d5" }, "action-flag-ghost-white" : { "name" : "action-flag-ghost-white", "rule" : ".action-flag-ghost-white, .device-desktop .phabricator-action-view:hover .action-flag-ghost", - "hash" : "583261ed96dbe3452e3e6a0001aea6d8" + "hash" : "330a6db5d35105eb2a40926ac10bf050" }, "action-flag-grey" : { "name" : "action-flag-grey", "rule" : ".action-flag-grey", - "hash" : "2abe4ae06cc54bf6069bac446e5fa439" + "hash" : "19ff6ca97d5a9417711c125342bfd181" }, "action-flag-white" : { "name" : "action-flag-white", "rule" : ".action-flag-white, .device-desktop .phabricator-action-view:hover .action-flag", - "hash" : "3442002f986cb8f7e1f06183927945a3" + "hash" : "c75814a0ab1d5efd93eb04bc91ea1d70" }, "action-folder-open" : { "name" : "action-folder-open", "rule" : ".action-folder-open", - "hash" : "fa3478ecd57fd41a6a16107db86a15e9" + "hash" : "041a997bd0fe3dc0eab6974cab2f4909" }, "action-folder-open-grey" : { "name" : "action-folder-open-grey", "rule" : ".action-folder-open-grey", - "hash" : "dada2fb1cbcb8256f607eae1914219c1" + "hash" : "78861d4d04e344db11e235dfadfaa0b2" }, "action-folder-open-white" : { "name" : "action-folder-open-white", "rule" : ".action-folder-open-white, .device-desktop .phabricator-action-view:hover .action-folder-open", - "hash" : "af7843feb777d7eafc3904fe0a268ed3" + "hash" : "b6c96d025fbd7d9d2f6184ab2b5255c1" }, "action-fork" : { "name" : "action-fork", "rule" : ".action-fork", - "hash" : "15285571cef4f6251aad47c42e5f0f1c" + "hash" : "73872362aa5fa8a715bb2b282e8873a7" }, "action-fork-grey" : { "name" : "action-fork-grey", "rule" : ".action-fork-grey", - "hash" : "aa875e4018c152bed7b37c776d18660e" + "hash" : "80b616de5d415c74e2561cf85cd5563a" }, "action-fork-white" : { "name" : "action-fork-white", "rule" : ".action-fork-white, .device-desktop .phabricator-action-view:hover .action-fork", - "hash" : "a3a53c919c04ae550970ccb5477671d2" + "hash" : "ed9479c691af95386f88076a65d73b19" }, "action-herald" : { "name" : "action-herald", "rule" : ".action-herald", - "hash" : "4084564ec8592cb6c9bf840f8c7eea6a" + "hash" : "75eb507020fcb7dc6890022513648e85" }, "action-herald-grey" : { "name" : "action-herald-grey", "rule" : ".action-herald-grey", - "hash" : "bc9f0fef0b1f75ed4f20cc4359f706f5" + "hash" : "30b633461f095ac3f032eb02398ae67e" }, "action-herald-white" : { "name" : "action-herald-white", "rule" : ".action-herald-white, .device-desktop .phabricator-action-view:hover .action-herald", - "hash" : "7d773778fa6126ac05a4c6f9d85dd20d" + "hash" : "149fd50929e68d6bcf6310d9e4c316b6" }, "action-highlight" : { "name" : "action-highlight", "rule" : ".action-highlight", - "hash" : "25f8142b1c665f623f9eab935bf256ab" + "hash" : "4430cca9eab0cbd85d3ee1b5e1f29ae3" }, "action-highlight-grey" : { "name" : "action-highlight-grey", "rule" : ".action-highlight-grey", - "hash" : "0d4347b151224476548a0dc43f6d1ceb" + "hash" : "47fe828e1b61553326752209a8fba6cb" }, "action-highlight-white" : { "name" : "action-highlight-white", "rule" : ".action-highlight-white, .device-desktop .phabricator-action-view:hover .action-highlight", - "hash" : "d32f9b42dc24f41aa02c18ba5db5d65f" + "hash" : "09a52dfdf893ee63be162f0c180d31fe" }, "action-history" : { "name" : "action-history", "rule" : ".action-history", - "hash" : "69fbd6f3875ceef440a5fdd727162024" + "hash" : "6669ec72a77a09e3e8c8c5fe941810a9" }, "action-history-grey" : { "name" : "action-history-grey", "rule" : ".action-history-grey", - "hash" : "97ed21324d25b236212e33c9bfd4dc0a" + "hash" : "3146a0c0c8698ef95ad74515cc9971ad" }, "action-history-white" : { "name" : "action-history-white", "rule" : ".action-history-white, .device-desktop .phabricator-action-view:hover .action-history", - "hash" : "4ffae3b425eaf5a7aec9757bd9fb97c3" + "hash" : "07490563c7cf4e8194918c3700ca1b57" }, "action-image" : { "name" : "action-image", "rule" : ".action-image", - "hash" : "bfe9f9b16bf54a258c76cf314bb87152" + "hash" : "5f03cd1fa806db2861d93a0fba7deff7" }, "action-image-grey" : { "name" : "action-image-grey", "rule" : ".action-image-grey", - "hash" : "e11788cab503c91d3a39847165181cb8" + "hash" : "32e1008c29447da5fc4a263c1b56ce41" }, "action-image-white" : { "name" : "action-image-white", "rule" : ".action-image-white, .device-desktop .phabricator-action-view:hover .action-image", - "hash" : "de395492a2088e998f48cba698744b0f" + "hash" : "d48be030bf83013fcd3549460f197712" }, "action-like" : { "name" : "action-like", "rule" : ".action-like", - "hash" : "2afed6b1e26578bcbc23f8d1c72221ab" + "hash" : "89d7ac4a8642389bded3af9aa464b06b" }, "action-like-grey" : { "name" : "action-like-grey", "rule" : ".action-like-grey", - "hash" : "8b2baee6c58e57d61c71d48b7e52522b" + "hash" : "262bdae8449eae9ecfb58246a8457f64" }, "action-like-white" : { "name" : "action-like-white", "rule" : ".action-like-white, .device-desktop .phabricator-action-view:hover .action-like", - "hash" : "0b6dd7cb5820d65faefdc2e7a8d75acf" + "hash" : "773b180de4276644cad9688a1f0935ce" }, "action-link" : { "name" : "action-link", "rule" : ".action-link", - "hash" : "0bb7d22b7db2915c787f132bee42a71d" + "hash" : "bbaed885947840548f9b466fd97aef83" }, "action-link-grey" : { "name" : "action-link-grey", "rule" : ".action-link-grey", - "hash" : "0bfe4298307d9bd2e66a43b5d1ee6c00" + "hash" : "c3bd4b5b14e7ed7c522fd148022a9e7b" }, "action-link-white" : { "name" : "action-link-white", "rule" : ".action-link-white, .device-desktop .phabricator-action-view:hover .action-link", - "hash" : "4cc1d11240276baf1864b9209e28d794" + "hash" : "e846157dd9d0119d82b2777052acdb3d" }, "action-lint-info" : { "name" : "action-lint-info", "rule" : ".action-lint-info", - "hash" : "f3588606b991614019f2aba3e5d75867" + "hash" : "324e1d2d947862a69df78e68e4a36b1f" }, "action-lint-info-grey" : { "name" : "action-lint-info-grey", "rule" : ".action-lint-info-grey", - "hash" : "738e607d12f91a7a9bc8f9b2c13052b6" + "hash" : "76eadf42825e50f995b5d8d088ee591f" }, "action-lint-info-white" : { "name" : "action-lint-info-white", "rule" : ".action-lint-info-white, .device-desktop .phabricator-action-view:hover .action-lint-info", - "hash" : "04d9cd9ec75225136ce19ef447ebbd5a" + "hash" : "ef6d4bb883446171a1a1df66b13b2c66" }, "action-lint-ok" : { "name" : "action-lint-ok", "rule" : ".action-lint-ok", - "hash" : "d2dd1f379b71c38233c33c106867593d" + "hash" : "97b66fc1a5474f00bc1fdda6525820d5" }, "action-lint-ok-grey" : { "name" : "action-lint-ok-grey", "rule" : ".action-lint-ok-grey", - "hash" : "e7b4b0ff5593c77ecf8af929960656c1" + "hash" : "eefd06511a24992aef9e486b560c4062" }, "action-lint-ok-white" : { "name" : "action-lint-ok-white", "rule" : ".action-lint-ok-white, .device-desktop .phabricator-action-view:hover .action-lint-ok", - "hash" : "26661c20c9d68c0568e7f8e7b9a79370" + "hash" : "f2720295139147930fb78e962450075d" }, "action-lint-warning" : { "name" : "action-lint-warning", "rule" : ".action-lint-warning", - "hash" : "30f226154af0794c0e05f53129a7a8fc" + "hash" : "d0b1c5f84db953de088056db7fbe1eae" }, "action-lint-warning-grey" : { "name" : "action-lint-warning-grey", "rule" : ".action-lint-warning-grey", - "hash" : "fef17b967a78fba8c6a4f772fc8c7ab2" + "hash" : "f4f73032f5f2310d7731affba2318d5d" }, "action-lint-warning-white" : { "name" : "action-lint-warning-white", "rule" : ".action-lint-warning-white, .device-desktop .phabricator-action-view:hover .action-lint-warning", - "hash" : "acc7c971f83efb5298390bb0ebdbbdb1" + "hash" : "d540c0afe65862f5c32c934f1956ca36" }, "action-lock" : { "name" : "action-lock", "rule" : ".action-lock", - "hash" : "d79fe308c2bca2a15eb4f2b0784eaef6" + "hash" : "7ca88645707cf9cd69ace1e416c0f964" }, "action-lock-grey" : { "name" : "action-lock-grey", "rule" : ".action-lock-grey", - "hash" : "ffa7de98cd41e3db7f9ea284662de41e" + "hash" : "c95e9a3071dc3bc389c235c49a5c5388" }, "action-lock-white" : { "name" : "action-lock-white", "rule" : ".action-lock-white, .device-desktop .phabricator-action-view:hover .action-lock", - "hash" : "323f4e1dc1d38b173bbe290c27ec9bea" + "hash" : "e6f5edd8fdfadab84dd95e5582ac1db1" }, "action-love" : { "name" : "action-love", "rule" : ".action-love", - "hash" : "4b5271c2f7cbf2ae1d904a3cc5f79b09" + "hash" : "9f101bddc6deba2b128bdc7bb45d583a" }, "action-love-grey" : { "name" : "action-love-grey", "rule" : ".action-love-grey", - "hash" : "3b629d11a145bc0eb300d9ee8daaacc6" + "hash" : "615fa9c17fa8a9e0b27846f3c99fdd87" }, "action-love-white" : { "name" : "action-love-white", "rule" : ".action-love-white, .device-desktop .phabricator-action-view:hover .action-love", - "hash" : "25a8f8c240d2fcd12e8ce192c749c9cb" + "hash" : "5f92d9a4565e79b96c956f054ede993a" }, "action-merge" : { "name" : "action-merge", "rule" : ".action-merge", - "hash" : "d1465a199273ca5a7d1914b7827388aa" + "hash" : "0c7cb3934262b3374f5c94e36c826672" }, "action-merge-grey" : { "name" : "action-merge-grey", "rule" : ".action-merge-grey", - "hash" : "b04fa26d964413d9b2efe0354aa22f95" + "hash" : "e8c11bd0a92a273ba5f90fee8bd31fb6" }, "action-merge-white" : { "name" : "action-merge-white", "rule" : ".action-merge-white, .device-desktop .phabricator-action-view:hover .action-merge", - "hash" : "c89d5163d7e237cde54b833356311a1c" + "hash" : "433a26913a0db78eb707edf0dbbf0fdc" }, "action-message" : { "name" : "action-message", "rule" : ".action-message", - "hash" : "b965efb0e7bc88a5f944bfa0476eb652" + "hash" : "c14b8eb1f70855eb801c42c5f04ea5d0" }, "action-message-grey" : { "name" : "action-message-grey", "rule" : ".action-message-grey", - "hash" : "ac4c4a9265d0d4810164907222ff401c" + "hash" : "93574f7b8adadc01b036b2376e7b1eb1" }, "action-message-white" : { "name" : "action-message-white", "rule" : ".action-message-white, .device-desktop .phabricator-action-view:hover .action-message", - "hash" : "7ec19102800f71d08b3d08f31cbbaf02" + "hash" : "3fe1df81d1af648ac1e483e2a081ed62" }, "action-meta-mta" : { "name" : "action-meta-mta", "rule" : ".action-meta-mta", - "hash" : "afbb4a97071268b542634aea2eed9fdb" + "hash" : "3895ce9ea717cc0a1bcc2f93015a5c86" }, "action-meta-mta-grey" : { "name" : "action-meta-mta-grey", "rule" : ".action-meta-mta-grey", - "hash" : "bc939fa46edc09f3e8b31a06cfb18895" + "hash" : "873f04635a614bce012cfc82837b6be1" }, "action-meta-mta-white" : { "name" : "action-meta-mta-white", "rule" : ".action-meta-mta-white, .device-desktop .phabricator-action-view:hover .action-meta-mta", - "hash" : "e1f6ed22db628d691172d7589004ff8f" + "hash" : "8d1edd5f73363a7057474364850abc39" }, "action-move" : { "name" : "action-move", "rule" : ".action-move", - "hash" : "5ee19a8116be04fca2cdb2ca18848aaa" + "hash" : "fa5d4f6c263a4cad009990a3f00c1819" }, "action-move-grey" : { "name" : "action-move-grey", "rule" : ".action-move-grey", - "hash" : "9f856630044d1d87d689b8d381426391" + "hash" : "201db3f4614022b6e57c2168aa9f7298" }, "action-move-white" : { "name" : "action-move-white", "rule" : ".action-move-white, .device-desktop .phabricator-action-view:hover .action-move", - "hash" : "3f81eb8b52850b4910ecf4a8c7667ad5" + "hash" : "d7f6217f85f2cfa45d7e44bd06d3f438" }, "action-new" : { "name" : "action-new", "rule" : ".action-new", - "hash" : "dfbcbf59a5440d9a99b0c18e2010f58e" + "hash" : "62ce1bb9b7c8252f58a37c655b7ed377" }, "action-new-grey" : { "name" : "action-new-grey", "rule" : ".action-new-grey", - "hash" : "fc6c948a0019a8a63e1a36a0c21f60ef" + "hash" : "5d96082b216b783d6256ee3cc755dc87" }, "action-new-white" : { "name" : "action-new-white", "rule" : ".action-new-white, .device-desktop .phabricator-action-view:hover .action-new, .phabricator-application-launch-create:hover .phabricator-application-create-icon.action-new-grey", - "hash" : "99a86e78d0f9bd775e283484b2bba989" + "hash" : "782f8bc8dc883c0637910e5fbc3c6f9f" }, "action-none" : { "name" : "action-none", "rule" : ".action-none", - "hash" : "29ab47e45ff4d1f23786bf0c1fc20414" + "hash" : "5595f8625292cd95d1240ed429dc880c" }, "action-none-grey" : { "name" : "action-none-grey", "rule" : ".action-none-grey", - "hash" : "8d0dec138cc8bbd2da813c24a55ef8f5" + "hash" : "76d2d2e3fff56f21759d03dd5c17331c" }, "action-none-white" : { "name" : "action-none-white", "rule" : ".action-none-white, .device-desktop .phabricator-action-view:hover .action-none", - "hash" : "ee7b57ca9dcc4e87e09fbe2949ec1242" + "hash" : "69ce41011458cfbdabb1a9fb7537d087" }, "action-perflab" : { "name" : "action-perflab", "rule" : ".action-perflab", - "hash" : "233b376e3b9d43082a60ea54afa6bc18" + "hash" : "ec1acf5413f771b1f2782aa759074764" }, "action-perflab-grey" : { "name" : "action-perflab-grey", "rule" : ".action-perflab-grey", - "hash" : "fbd064b66bed85a725cbb4741d0e85b0" + "hash" : "2f7fa40824ccf254322e60e216f1d50e" }, "action-perflab-white" : { "name" : "action-perflab-white", "rule" : ".action-perflab-white, .device-desktop .phabricator-action-view:hover .action-perflab", - "hash" : "9add2d46ea13b938c631ac2a4f376e3d" + "hash" : "aac6b8b9fa044430375ba370243292cb" }, "action-preview" : { "name" : "action-preview", "rule" : ".action-preview", - "hash" : "2eb136352c63e4f0f7632f81d12d635c" + "hash" : "a33cb74fc6e1b9665ac4ff20635babe8" }, "action-preview-grey" : { "name" : "action-preview-grey", "rule" : ".action-preview-grey", - "hash" : "f7c4e6ea75fb0a9f2fe00183112db8ad" + "hash" : "4cfe3a27e5e818ea9f7805a7c1b05fa7" }, "action-preview-white" : { "name" : "action-preview-white", "rule" : ".action-preview-white, .device-desktop .phabricator-action-view:hover .action-preview", - "hash" : "71cac08ba19ee678499a9cbd5c24c6cf" + "hash" : "61523a3b9edc3d0ddfea9f399bae0fe1" }, "action-refresh" : { "name" : "action-refresh", "rule" : ".action-refresh", - "hash" : "171e46e974912cfa0b347d1e96a579c7" + "hash" : "d5d7cf16bfe862d0a101ccf216b76df1" }, "action-refresh-grey" : { "name" : "action-refresh-grey", "rule" : ".action-refresh-grey", - "hash" : "6e102669eb7b6389d7c08c838886841d" + "hash" : "b4838ee697b2a9b70dc6920da7ab3e89" }, "action-refresh-white" : { "name" : "action-refresh-white", "rule" : ".action-refresh-white, .device-desktop .phabricator-action-view:hover .action-refresh", - "hash" : "5a7dad6d45f6b47bc1175a7efa4089a1" + "hash" : "44fa7fc18a847416b9db3858e0b47737" }, "action-remove" : { "name" : "action-remove", "rule" : ".action-remove", - "hash" : "364176fcff78057741963dbf48eecbbd" + "hash" : "4c9dcad5540a611a5e05380d7982a601" }, "action-remove-grey" : { "name" : "action-remove-grey", "rule" : ".action-remove-grey", - "hash" : "b0d190ec2837c0cbdc99428178a8eddf" + "hash" : "dc0b179b0a96dd5c9f387ee41daf77a7" }, "action-remove-white" : { "name" : "action-remove-white", "rule" : ".action-remove-white, .device-desktop .phabricator-action-view:hover .action-remove", - "hash" : "e3646206c14813fca81a35de43722aae" + "hash" : "8c750027adb708e8507a51986081d309" }, "action-search" : { "name" : "action-search", "rule" : ".action-search", - "hash" : "8307439f020b262ab8443edb745ed171" + "hash" : "1340e68f4f2b55c5feee4a0241672c82" }, "action-search-grey" : { "name" : "action-search-grey", "rule" : ".action-search-grey", - "hash" : "c1ce13aab1083b20fb094b56b3deab8a" + "hash" : "a7e598337c9a8a6feb3de62247abb611" }, "action-search-white" : { "name" : "action-search-white", "rule" : ".action-search-white, .device-desktop .phabricator-action-view:hover .action-search", - "hash" : "72098d2091e6297c4253c3e45a365ec4" + "hash" : "91e764bd3ed921153ac66fc56e04b884" }, "action-start-sandcastle" : { "name" : "action-start-sandcastle", "rule" : ".action-start-sandcastle", - "hash" : "afa09dd71e0747c56e64d95e975122c8" + "hash" : "52f245ddeff53c5cf084c27b6e45b152" }, "action-start-sandcastle-grey" : { "name" : "action-start-sandcastle-grey", "rule" : ".action-start-sandcastle-grey", - "hash" : "b0912a9f2a1bcff19ab90f539107864f" + "hash" : "d41cff7a3c898616f75634c8d796cd6c" }, "action-start-sandcastle-white" : { "name" : "action-start-sandcastle-white", "rule" : ".action-start-sandcastle-white, .device-desktop .phabricator-action-view:hover .action-start-sandcastle", - "hash" : "53692026662afaafdcbaa9ab7de7aa0d" + "hash" : "04959e4bcf29b57213e5b49ab6f25aeb" }, "action-subscribe-add" : { "name" : "action-subscribe-add", "rule" : ".action-subscribe-add", - "hash" : "d2100e88f2ffc71c2df1d40049f2bf68" + "hash" : "1b166c23ed6a971d2f93d37147caf622" }, "action-subscribe-add-grey" : { "name" : "action-subscribe-add-grey", "rule" : ".action-subscribe-add-grey", - "hash" : "637094fbed70285b62cbfe9ead4bd480" + "hash" : "2b2fd9749636140f78233bef8e604d56" }, "action-subscribe-add-white" : { "name" : "action-subscribe-add-white", "rule" : ".action-subscribe-add-white, .device-desktop .phabricator-action-view:hover .action-subscribe-add", - "hash" : "75be8cd5e9622834bd6faf0c6d1db271" + "hash" : "2ca899f12f05b03c5c54cbac08d2b74d" }, "action-subscribe-auto" : { "name" : "action-subscribe-auto", "rule" : ".action-subscribe-auto", - "hash" : "95145b14f35005a0ff3224e3076a9388" + "hash" : "a6cd0083b657b924882d830cd4f91bbc" }, "action-subscribe-auto-grey" : { "name" : "action-subscribe-auto-grey", "rule" : ".action-subscribe-auto-grey", - "hash" : "12edd25560b91838642baa3529743733" + "hash" : "77ccbf046a3a39ebf20ba6e58e865438" }, "action-subscribe-auto-white" : { "name" : "action-subscribe-auto-white", "rule" : ".action-subscribe-auto-white, .device-desktop .phabricator-action-view:hover .action-subscribe-auto", - "hash" : "eda2baeaf056a2d5f46184393ec6dbca" + "hash" : "f22920740beb517bb7d33ae91462907d" }, "action-subscribe-delete" : { "name" : "action-subscribe-delete", "rule" : ".action-subscribe-delete", - "hash" : "55a16e4abd9fe661f350b5327aafed88" + "hash" : "e78959e3ed89af610da59e8ef77c799d" }, "action-subscribe-delete-grey" : { "name" : "action-subscribe-delete-grey", "rule" : ".action-subscribe-delete-grey", - "hash" : "c1c033955177120cd6adcb0d68f37e18" + "hash" : "e3e8d142bdd4d1acfebcd03c790ac5b5" }, "action-subscribe-delete-white" : { "name" : "action-subscribe-delete-white", "rule" : ".action-subscribe-delete-white, .device-desktop .phabricator-action-view:hover .action-subscribe-delete", - "hash" : "bc0d60756e5b4c141b801fb384933eab" + "hash" : "1368667fb8b115c95512eda55d7065a5" }, "action-tag" : { "name" : "action-tag", "rule" : ".action-tag", - "hash" : "069a8593574d6f847a3611b23677e667" + "hash" : "2574ffef0cafe758774e358bd6e5cd6a" }, "action-tag-grey" : { "name" : "action-tag-grey", "rule" : ".action-tag-grey", - "hash" : "544d96d3bed359a545f2eaa16687cead" + "hash" : "e8194bcfb48d63a5a8c5ce69a0a3dcc5" }, "action-tag-white" : { "name" : "action-tag-white", "rule" : ".action-tag-white, .device-desktop .phabricator-action-view:hover .action-tag", - "hash" : "e3e509127ef1a452faaa03465dd6f9c1" + "hash" : "2d54a42a650a987ce706c2d935ff33cd" }, "action-transcript" : { "name" : "action-transcript", "rule" : ".action-transcript", - "hash" : "4e76a6b1c51fcfc1b1b1ad0e7f247c3a" + "hash" : "6be4d47abddeb109216f346787face70" }, "action-transcript-grey" : { "name" : "action-transcript-grey", "rule" : ".action-transcript-grey", - "hash" : "313af234ca64b2ecc53dd1c91ce0b1c1" + "hash" : "9ed35e5d39536a4b8dd934039c742447" }, "action-transcript-white" : { "name" : "action-transcript-white", "rule" : ".action-transcript-white, .device-desktop .phabricator-action-view:hover .action-transcript", - "hash" : "39743a3d055fcd5b344eb59092006f16" + "hash" : "7c3df910499b8ddb85c2f53e0d58c0db" }, "action-undo" : { "name" : "action-undo", "rule" : ".action-undo", - "hash" : "7e860a8ec5bb760b0767ecc3114173c7" + "hash" : "f81151e242bb8ae29714bec10cb7c5f1" }, "action-undo-grey" : { "name" : "action-undo-grey", "rule" : ".action-undo-grey", - "hash" : "6c9fdd95e53b4ec05da46cf129e3c6fb" + "hash" : "8d4b0bc147b463011ec00321ba75b17f" }, "action-undo-white" : { "name" : "action-undo-white", "rule" : ".action-undo-white, .device-desktop .phabricator-action-view:hover .action-undo", - "hash" : "8b3fefbad3b5179a6b35b41617e2cef2" + "hash" : "39b777060ce1d1b0c68c550bb63d7146" }, "action-unlock" : { "name" : "action-unlock", "rule" : ".action-unlock", - "hash" : "e2ff544b4c60dcf7545755d96d23b993" + "hash" : "d7cc6ffcda62a90e455d37ca0f07d0dd" }, "action-unlock-grey" : { "name" : "action-unlock-grey", "rule" : ".action-unlock-grey", - "hash" : "d9656d004d5c516a38d75462eadf82f5" + "hash" : "efdc3048fa3a4051a43f43a915e53b0e" }, "action-unlock-white" : { "name" : "action-unlock-white", "rule" : ".action-unlock-white, .device-desktop .phabricator-action-view:hover .action-unlock", - "hash" : "a970eb7a33d2c5c71d2125b0b8e79375" + "hash" : "d0e7aff47724d94167e9bcb11eb5e6aa" }, "action-unmerge" : { "name" : "action-unmerge", "rule" : ".action-unmerge", - "hash" : "48a0128075a15f5145c343f9fe4fba2e" + "hash" : "00d417a336f6e076bb587cd4cef5eb49" }, "action-unmerge-grey" : { "name" : "action-unmerge-grey", "rule" : ".action-unmerge-grey", - "hash" : "9be17dad18c74a10122def1dabbbf1c4" + "hash" : "904a51920678c838b72c934085f339a7" }, "action-unmerge-white" : { "name" : "action-unmerge-white", "rule" : ".action-unmerge-white, .device-desktop .phabricator-action-view:hover .action-unmerge", - "hash" : "5139f358574dcd0ac5cecf412c8115fd" + "hash" : "2e5761de881642c94e641879bbde318f" }, "action-unpublish" : { "name" : "action-unpublish", "rule" : ".action-unpublish", - "hash" : "3e6211c213fec14fe152b5fabcb0f306" + "hash" : "88d21b9ce49b7ac886250df307f756ce" }, "action-unpublish-grey" : { "name" : "action-unpublish-grey", "rule" : ".action-unpublish-grey", - "hash" : "602cdfcfa89b575456aee6eb808accc4" + "hash" : "5c4fe69253100e9ca292348af13b9f3f" }, "action-unpublish-white" : { "name" : "action-unpublish-white", "rule" : ".action-unpublish-white, .device-desktop .phabricator-action-view:hover .action-unpublish", - "hash" : "b8cde193bf30d834fc90ddfd17fe56ea" + "hash" : "f663861c0776cea790d8392e4aa2fc5d" }, "action-upload" : { "name" : "action-upload", "rule" : ".action-upload", - "hash" : "e1ab661b790989b38b07eae365343c36" + "hash" : "bdd10302988fe6d2130f0dfc3b67d281" }, "action-upload-grey" : { "name" : "action-upload-grey", "rule" : ".action-upload-grey", - "hash" : "f03d83d2e4d3ae10661d430aa4f02523" + "hash" : "f376bbbbadefea220ec02ca3ae53d41a" }, "action-upload-white" : { "name" : "action-upload-white", "rule" : ".action-upload-white, .device-desktop .phabricator-action-view:hover .action-upload", - "hash" : "75a3ea84188c4b4b21aa5a656464a8d0" + "hash" : "4b31d9dc6f17bd0cd54c3dcea7a95313" }, "action-warning" : { "name" : "action-warning", "rule" : ".action-warning", - "hash" : "c1544d80d0bb28d7f9925e5ecda1165f" + "hash" : "950ac4ea5e65de41aca0788e6769650f" }, "action-warning-grey" : { "name" : "action-warning-grey", "rule" : ".action-warning-grey", - "hash" : "dccb1f52678bf74fc1eaa6a6e8dcae7a" + "hash" : "180e305268970291f6a38760deea0d4c" }, "action-warning-white" : { "name" : "action-warning-white", "rule" : ".action-warning-white, .device-desktop .phabricator-action-view:hover .action-warning", - "hash" : "57aadd4cf33bf6cb6464d243cd3e5f4d" + "hash" : "4ec3034629bc144886cd7aae5412dce2" }, "action-world" : { "name" : "action-world", "rule" : ".action-world", - "hash" : "374749ade70638672595b8a985341a34" + "hash" : "95ebc5ab6e70ab9d794f0960f2a43559" }, "action-world-grey" : { "name" : "action-world-grey", "rule" : ".action-world-grey", - "hash" : "f5fa565f8dbc81d5ac8d8f128179929b" + "hash" : "969b164f2f5580f9226f293dbcfe50bc" }, "action-world-white" : { "name" : "action-world-white", "rule" : ".action-world-white, .device-desktop .phabricator-action-view:hover .action-world", - "hash" : "b50f9d742377edf4edda3e1e78f1e558" + "hash" : "106ab6c8bc5a685cd0837baaa6c617e4" }, "remarkup-assist-text_b" : { "name" : "remarkup-assist-text_b", "rule" : ".remarkup-assist-b", - "hash" : "12c565d4934f6a777c9524baf75cebb6" + "hash" : "b2e7ba9cba2946a78ac8045d83852ade" }, "remarkup-assist-text_code" : { "name" : "remarkup-assist-text_code", "rule" : ".remarkup-assist-code", - "hash" : "f06f106cb8edb67e8b99d159d704a61a" + "hash" : "c0527e968c770450d4aa7cefe38271b8" }, "remarkup-assist-text_help" : { "name" : "remarkup-assist-text_help", "rule" : ".remarkup-assist-help", - "hash" : "9d54d8224b81de8e3ed7beac0e486257" + "hash" : "e8312c555e5f3935d8e2dcf44147b7f8" }, "remarkup-assist-text_i" : { "name" : "remarkup-assist-text_i", "rule" : ".remarkup-assist-i", - "hash" : "50f83a53f5b094d3d92b619d06fada3c" + "hash" : "19d4c474555d75d0e4739ec7097dbfa4" }, "remarkup-assist-text_image" : { "name" : "remarkup-assist-text_image", "rule" : ".remarkup-assist-image", - "hash" : "c2869e71cc7cb6178598cd41a19ababb" + "hash" : "5a560800fa31b24d18807b430797ac95" }, "remarkup-assist-text_larger" : { "name" : "remarkup-assist-text_larger", "rule" : ".remarkup-assist-larger", - "hash" : "d3165f15a1b3734e4b7088f7b74330ba" + "hash" : "5cd9c8223c99ef3409c82dfaefeebc50" }, "remarkup-assist-text_meme" : { "name" : "remarkup-assist-text_meme", "rule" : ".remarkup-assist-meme", - "hash" : "ed9c4166858ca1caedf5f8e4b8ad587e" + "hash" : "ff98a508db2348b3d46aaf8225b26862" }, "remarkup-assist-text_ol" : { "name" : "remarkup-assist-text_ol", "rule" : ".remarkup-assist-ol", - "hash" : "266b858f5ffc42760fb2e12913a5198a" + "hash" : "a2805d44ca0eac518f99109c4969f450" }, "remarkup-assist-text_table" : { "name" : "remarkup-assist-text_table", "rule" : ".remarkup-assist-table", - "hash" : "5c2961b35460b3b5b7efdd5bc4e318ca" + "hash" : "2ae3fb49af42f07038d77aa5b62862c0" }, "remarkup-assist-text_tag" : { "name" : "remarkup-assist-text_tag", "rule" : ".remarkup-assist-tag", - "hash" : "165bd3a4de8d54cf720db9bc64116d25" + "hash" : "446c23bff9fc7da885ea574f073eaf0f" }, "remarkup-assist-text_tt" : { "name" : "remarkup-assist-text_tt", "rule" : ".remarkup-assist-tt", - "hash" : "c07e6816500c9cd66fa27758cc902195" + "hash" : "77ae74c8a9a02fde5565399409dc5ab3" }, "remarkup-assist-text_ul" : { "name" : "remarkup-assist-text_ul", "rule" : ".remarkup-assist-ul", - "hash" : "26f55c0fcf9148879e3fb058ac319100" + "hash" : "cf3c6b4f809377b7eff9fcef42fc47df" } }, "scales" : [ 1, 2 ], "header" : "\/**\n * @provides sprite-icon-css\n * @generated\n *\/\n\n.sprite-icon {\n background-image: url(\/rsrc\/image\/sprite-icon.png);\n background-repeat: no-repeat;\n}\n\n@media\nonly screen and (min-device-pixel-ratio: 1.5),\nonly screen and (-webkit-min-device-pixel-ratio: 1.5) {\n .sprite-icon {\n background-image: url(\/rsrc\/image\/sprite-icon-X2.png);\n background-size: {X}px {Y}px;\n }\n}\n", "type" : "standard" } diff --git a/resources/sprite/manifest/menu.json b/resources/sprite/manifest/menu.json index ba730a47d7..d4a6bbbe40 100644 --- a/resources/sprite/manifest/menu.json +++ b/resources/sprite/manifest/menu.json @@ -1,56 +1,61 @@ { "version" : 1, "sprites" : { "app" : { "name" : "app", "rule" : ".menu-icon-app", - "hash" : "a389f99d9c00f688e625da71579ee90a" + "hash" : "fc525b5b3e3ecaeda3baccc18ace5a0a" }, "arrow-right" : { "name" : "arrow-right", "rule" : ".phabricator-crumb-divider", - "hash" : "a994209450dc73a80841cdd66bb59925" + "hash" : "50180da0aed206c9db2bc1547c1a158c" }, - "bubble" : { - "name" : "bubble", - "rule" : ".phabricator-main-menu-alert-bubble.alert-unread", - "hash" : "1145ac8a137a2a22517c1945fe22c517" + "conf-hover" : { + "name" : "conf-hover", + "rule" : ".alert-notifications:hover .phabricator-main-menu-message-icon", + "hash" : "febc4135b2821ae2d3f0b06aa295ca0d" + }, + "conf-off" : { + "name" : "conf-off", + "rule" : ".alert-notifications .phabricator-main-menu-message-icon", + "hash" : "dc1b05cb611eaef76a09e8cff698c99d" + }, + "conf-unseen" : { + "name" : "conf-unseen", + "rule" : ".alert-notifications.message-unread .phabricator-main-menu-message-icon", + "hash" : "1f7d54b2b9781099f867b100ebdd6c6a" }, "eye" : { "name" : "eye", "rule" : ".menu-icon-eye", - "hash" : "d598b1acb1933a86eaed3dea3347f7b0" + "hash" : "553eb617c19b74b428558e606ff9b066" }, "logo" : { "name" : "logo", "rule" : ".phabricator-main-menu-logo-image", - "hash" : "c6c7ab165dce13a51ef329928c7c4aba" - }, - "round_bubble" : { - "name" : "round_bubble", - "rule" : ".phabricator-main-menu-alert-bubble", - "hash" : "9be91cc0128997992e9001baf32c8ab8" + "hash" : "6eadea2c3dd2ada989eba22b6769b3eb" }, "seen_have_unread" : { "name" : "seen_have_unread", "rule" : ".alert-notifications:hover .phabricator-main-menu-alert-icon", - "hash" : "a8a7f07caa726d7e61ef3d41f959d94d" + "hash" : "03a02951857811c722732dcfff9d458e" }, "seen_read_all" : { "name" : "seen_read_all", "rule" : ".alert-notifications .phabricator-main-menu-alert-icon", - "hash" : "4fdd4807d0c41bd4179dd43150c7fc44" + "hash" : "f166fc60ed7a7a8ec2f41ab1af2cb3ec" }, "unseen_any" : { "name" : "unseen_any", "rule" : ".alert-notifications.alert-unread .phabricator-main-menu-alert-icon", - "hash" : "50d946952c73028b34e0c3378ca36b17" + "hash" : "a8643b150166a076e81a42e5893a899f" } }, "scales" : [ 1, 2 ], "header" : "\/**\n * @provides sprite-menu-css\n * @generated\n *\/\n\n.sprite-menu {\n background-image: url(\/rsrc\/image\/sprite-menu.png);\n background-repeat: no-repeat;\n}\n\n@media\nonly screen and (min-device-pixel-ratio: 1.5),\nonly screen and (-webkit-min-device-pixel-ratio: 1.5) {\n .sprite-menu {\n background-image: url(\/rsrc\/image\/sprite-menu-X2.png);\n background-size: {X}px {Y}px;\n }\n}\n", "type" : "standard" } diff --git a/resources/sprite/menu_1x/conf-hover.png b/resources/sprite/menu_1x/conf-hover.png new file mode 100644 index 0000000000..a023af58c9 Binary files /dev/null and b/resources/sprite/menu_1x/conf-hover.png differ diff --git a/resources/sprite/menu_1x/conf-off.png b/resources/sprite/menu_1x/conf-off.png new file mode 100644 index 0000000000..34674f597c Binary files /dev/null and b/resources/sprite/menu_1x/conf-off.png differ diff --git a/resources/sprite/menu_1x/conf-unseen.png b/resources/sprite/menu_1x/conf-unseen.png new file mode 100644 index 0000000000..d186116b55 Binary files /dev/null and b/resources/sprite/menu_1x/conf-unseen.png differ diff --git a/resources/sprite/menu_2x/conf-hover.png b/resources/sprite/menu_2x/conf-hover.png new file mode 100644 index 0000000000..58a986cf82 Binary files /dev/null and b/resources/sprite/menu_2x/conf-hover.png differ diff --git a/resources/sprite/menu_2x/conf-off.png b/resources/sprite/menu_2x/conf-off.png new file mode 100644 index 0000000000..f09430c20f Binary files /dev/null and b/resources/sprite/menu_2x/conf-off.png differ diff --git a/resources/sprite/menu_2x/conf-unseen.png b/resources/sprite/menu_2x/conf-unseen.png new file mode 100644 index 0000000000..f35ae10129 Binary files /dev/null and b/resources/sprite/menu_2x/conf-unseen.png differ diff --git a/resources/sql/patches/20130127.altheraldtranscript.sql b/resources/sql/patches/20130127.altheraldtranscript.sql new file mode 100644 index 0000000000..5b59c4d40b --- /dev/null +++ b/resources/sql/patches/20130127.altheraldtranscript.sql @@ -0,0 +1,3 @@ +ALTER TABLE `{$NAMESPACE}_herald`.`herald_transcript` + DROP `psth`; + diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index 30daf8e562..6edcdb0feb 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -1,3715 +1,3723 @@ + 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/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' => '984f8159dfc5bae465aa48a6ee5f00fe', - 'uri' => '/res/984f8159/rsrc/image/sprite-apps-X2.png', + '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' => 'b215a44c77664577d8edf0d2ac9a8cfd', - 'uri' => '/res/b215a44c/rsrc/image/sprite-apps-large-X2.png', + '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' => 'f60b55b3d4a2b87169444d88a9f629c6', - 'uri' => '/res/f60b55b3/rsrc/image/sprite-apps-large.png', + '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' => '7a13551ec085fff5438c621ca5213d8e', - 'uri' => '/res/7a13551e/rsrc/image/sprite-apps.png', + 'hash' => '5e76c53e9f61755e5d3e7befa9d73ae5', + 'uri' => '/res/5e76c53e/rsrc/image/sprite-apps.png', 'disk' => '/rsrc/image/sprite-apps.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' => '11017d94e949aa169361b966716e8729', - 'uri' => '/res/11017d94/rsrc/image/sprite-menu-X2.png', + 'hash' => 'ad544a9287ca73b9e0d3f549834701ee', + 'uri' => '/res/ad544a92/rsrc/image/sprite-menu-X2.png', 'disk' => '/rsrc/image/sprite-menu-X2.png', 'type' => 'png', ), '/rsrc/image/sprite-menu.png' => array( - 'hash' => 'ba0f7d61f49ea50e9c3ff93b160e14c5', - 'uri' => '/res/ba0f7d61/rsrc/image/sprite-menu.png', + 'hash' => '8a6822c29bfa6f33db1c1b8b02b5c6d3', + 'uri' => '/res/8a6822c2/rsrc/image/sprite-menu.png', 'disk' => '/rsrc/image/sprite-menu.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' => 'c32ab9819d4af583f5609bbd3750721a', 'uri' => '/res/c32ab981/rsrc/image/texture/dust_background.jpg', 'disk' => '/rsrc/image/texture/dust_background.jpg', 'type' => 'jpg', ), '/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-calendar-view-css' => array( 'uri' => '/res/87d6e40d/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-crumbs-view-css' => array( 'uri' => '/res/699be12a/rsrc/css/aphront/crumbs-view.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/aphront/crumbs-view.css', ), 'aphront-dark-console-css' => array( 'uri' => '/res/1e1f78d4/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/048ed376/rsrc/css/aphront/error-view.css', + '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/1e191b83/rsrc/css/aphront/form-view.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/aphront/form-view.css', ), 'aphront-headsup-action-list-view-css' => array( 'uri' => '/res/1dce0ad7/rsrc/css/aphront/headsup-action-list-view.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/aphront/headsup-action-list-view.css', ), 'aphront-headsup-view-css' => array( 'uri' => '/res/73874cd2/rsrc/css/aphront/headsup.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/aphront/headsup.css', ), 'aphront-list-filter-view-css' => array( 'uri' => '/res/e783d6e1/rsrc/css/aphront/list-filter-view.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/aphront/list-filter-view.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/789ff5e5/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-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/6f7f64e8/rsrc/css/application/config/config-options.css', + '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/e50e02c8/rsrc/css/application/conpherence/header-pane.css', + 'uri' => '/res/4b8aebd2/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/02b20456/rsrc/css/application/conpherence/menu.css', + '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/799dc191/rsrc/css/application/conpherence/message-pane.css', + 'uri' => '/res/88b1927c/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/8e4757b5/rsrc/css/application/conpherence/update.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/application/conpherence/update.css', ), 'conpherence-widget-pane-css' => array( - 'uri' => '/res/7af40cac/rsrc/css/application/conpherence/widget-pane.css', + 'uri' => '/res/b3e6a558/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/1bc649b7/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/6a28b429/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/f09bc90d/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-drag-and-drop' => array( - 'uri' => '/res/84a67d72/rsrc/js/application/core/behavior-drag-and-drop.js', + 'uri' => '/res/3d809b40/rsrc/js/application/core/behavior-drag-and-drop.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', - 2 => 'phabricator-drag-and-drop-file-upload', + 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/ca54e8b9/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-init' => array( 'uri' => '/res/bd911b43/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/9d21fb86/rsrc/js/application/conpherence/behavior-menu.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', 2 => 'javelin-workflow', 3 => 'javelin-util', 4 => 'javelin-stratcom', 5 => 'javelin-uri', ), 'disk' => '/rsrc/js/application/conpherence/behavior-menu.js', ), 'javelin-behavior-conpherence-widget-pane' => array( 'uri' => '/res/f3e0dbba/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/aa6f8a71/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', 6 => 'javelin-behavior-dark-console-ajax', ), 'disk' => '/rsrc/js/application/core/behavior-dark-console.js', ), 'javelin-behavior-dark-console-ajax' => array( 'uri' => '/res/ac3ab63a/rsrc/js/application/core/behavior-dark-console-ajax.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-behavior', 1 => 'javelin-dom', ), 'disk' => '/rsrc/js/application/core/behavior-dark-console-ajax.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/a7798465/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/71effec4/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 => '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/d3cf5499/rsrc/js/application/diffusion/behavior-line-linker.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-dom', 3 => 'javelin-uri', ), '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-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/5efba371/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-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-home-reveal-tiles' => array( 'uri' => '/res/7230ca0c/rsrc/js/application/core/behavior-home-reveal-tiles.js', 'type' => 'js', 'requires' => array( 0 => 'javelin-behavior', 1 => 'javelin-stratcom', 2 => 'javelin-dom', ), 'disk' => '/rsrc/js/application/core/behavior-home-reveal-tiles.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/cec31f3f/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-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/307a71af/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-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-repository-crossreference' => array( 'uri' => '/res/244c5251/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/2b0e2754/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/2826c532/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/3815b473/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/4f3c705c/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/519c4e1a/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/14e825ce/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', ), '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/8aee0702/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/7320ca6d/rsrc/css/core/buttons.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/core/buttons.css', ), 'phabricator-core-css' => array( 'uri' => '/res/03c97d00/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/bdec7be5/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/88ef478c/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/0be80136/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/a38edb46/rsrc/css/application/base/main-menu-view.css', + 'uri' => '/res/38ec42d4/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/df20ec17/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/d0d0264c/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/1f9c7ebb/rsrc/css/layout/phabricator-object-item-list-view.css', + 'uri' => '/res/2fb97c5c/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/3a24d210/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/6b0a5223/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/cd84ee5a/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/f444d7c9/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/2013e94f/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/87935c75/rsrc/css/layout/phabricator-source-code-view.css', + 'uri' => '/res/9373e769/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/5f013c46/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/d87e1d60/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/d3599152/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/e454c33f/rsrc/css/application/pholio/pholio.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/application/pholio/pholio.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', ), '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/2d8a940e/rsrc/css/sprite-apps.css', + '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/6b528e03/rsrc/css/sprite-apps-large.css', + '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-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/3d9f75af/rsrc/css/sprite-menu.css', + 'uri' => '/res/8e6624b0/rsrc/css/sprite-menu.css', 'type' => 'css', 'requires' => array( ), 'disk' => '/rsrc/css/sprite-menu.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', ), ), array( 'packages' => array( - '8fd19266' => + '023adc14' => 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-crumbs-view-css', 9 => 'aphront-tokenizer-control-css', 10 => 'aphront-typeahead-control-css', 11 => 'aphront-list-filter-view-css', 12 => 'phabricator-directory-css', 13 => 'phabricator-jump-nav', 14 => 'phabricator-remarkup-css', 15 => 'syntax-highlighting-css', 16 => 'aphront-pager-view-css', 17 => 'phabricator-transaction-view-css', 18 => 'aphront-tooltip-css', 19 => 'aphront-headsup-view-css', 20 => 'phabricator-flag-css', 21 => 'aphront-error-view-css', 22 => 'sprite-icon-css', 23 => 'sprite-gradient-css', 24 => 'sprite-menu-css', 25 => 'sprite-apps-large-css', 26 => 'phabricator-main-menu-view', 27 => 'phabricator-notification-css', 28 => 'phabricator-notification-menu-css', 29 => 'lightbox-attachment-css', 30 => 'phabricator-header-view-css', 31 => 'phabricator-form-view-css', 32 => 'phabricator-filetree-view-css', 33 => 'phabricator-nav-view-css', 34 => 'phabricator-side-menu-view-css', 35 => 'phabricator-crumbs-view-css', 36 => 'phabricator-object-item-list-view-css', 37 => 'global-drag-and-drop-css', ), - 'uri' => '/res/pkg/8fd19266/core.pkg.css', + 'uri' => '/res/pkg/023adc14/core.pkg.css', 'type' => 'css', ), '66dca903' => 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-phabricator-active-nav', 27 => 'javelin-behavior-phabricator-nav', 28 => 'javelin-behavior-phabricator-remarkup-assist', 29 => 'phabricator-textareautils', 30 => 'phabricator-file-upload', 31 => 'javelin-behavior-global-drag-and-drop', 32 => 'javelin-behavior-phabricator-home-reveal-tiles', ), 'uri' => '/res/pkg/66dca903/core.pkg.js', 'type' => 'js', ), '8edbada5' => array( 'name' => 'darkconsole.pkg.js', 'symbols' => array( 0 => 'javelin-behavior-dark-console-ajax', 1 => 'javelin-behavior-dark-console', 2 => 'javelin-behavior-error-log', ), 'uri' => '/res/pkg/8edbada5/darkconsole.pkg.js', 'type' => 'js', ), 'ec01d039' => 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 => 'aphront-headsup-action-list-view-css', 11 => 'phabricator-content-source-view-css', 12 => 'differential-local-commits-view-css', 13 => 'inline-comment-summary-css', ), 'uri' => '/res/pkg/ec01d039/differential.pkg.css', 'type' => 'css', ), - 'ac53d36a' => + '310cd201' => 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 => 'differential-inline-comment-editor', 16 => 'javelin-behavior-differential-dropdown-menus', 17 => 'javelin-behavior-differential-toggle-files', 18 => 'javelin-behavior-differential-user-select', ), - 'uri' => '/res/pkg/ac53d36a/differential.pkg.js', + 'uri' => '/res/pkg/310cd201/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', ), 'fbeded59' => 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/fbeded59/javelin.pkg.js', 'type' => 'js', ), 'e30a3fa8' => 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/e30a3fa8/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' => 'e30a3fa8', - 'aphront-crumbs-view-css' => '8fd19266', - 'aphront-dialog-view-css' => '8fd19266', - 'aphront-error-view-css' => '8fd19266', - 'aphront-form-view-css' => '8fd19266', + 'aphront-crumbs-view-css' => '023adc14', + 'aphront-dialog-view-css' => '023adc14', + 'aphront-error-view-css' => '023adc14', + 'aphront-form-view-css' => '023adc14', 'aphront-headsup-action-list-view-css' => 'ec01d039', - 'aphront-headsup-view-css' => '8fd19266', - 'aphront-list-filter-view-css' => '8fd19266', - 'aphront-pager-view-css' => '8fd19266', - 'aphront-panel-view-css' => '8fd19266', - 'aphront-table-view-css' => '8fd19266', - 'aphront-tokenizer-control-css' => '8fd19266', - 'aphront-tooltip-css' => '8fd19266', - 'aphront-typeahead-control-css' => '8fd19266', + 'aphront-headsup-view-css' => '023adc14', + 'aphront-list-filter-view-css' => '023adc14', + 'aphront-pager-view-css' => '023adc14', + 'aphront-panel-view-css' => '023adc14', + 'aphront-table-view-css' => '023adc14', + 'aphront-tokenizer-control-css' => '023adc14', + 'aphront-tooltip-css' => '023adc14', + 'aphront-typeahead-control-css' => '023adc14', 'differential-changeset-view-css' => 'ec01d039', 'differential-core-view-css' => 'ec01d039', - 'differential-inline-comment-editor' => 'ac53d36a', + 'differential-inline-comment-editor' => '310cd201', 'differential-local-commits-view-css' => 'ec01d039', 'differential-results-table-css' => 'ec01d039', 'differential-revision-add-comment-css' => 'ec01d039', 'differential-revision-comment-css' => 'ec01d039', 'differential-revision-comment-list-css' => 'ec01d039', 'differential-revision-history-css' => 'ec01d039', 'differential-revision-list-css' => 'ec01d039', 'differential-table-of-contents-css' => 'ec01d039', 'diffusion-commit-view-css' => 'c8ce2d88', 'diffusion-icons-css' => 'c8ce2d88', - 'global-drag-and-drop-css' => '8fd19266', + 'global-drag-and-drop-css' => '023adc14', 'inline-comment-summary-css' => 'ec01d039', 'javelin-aphlict' => '66dca903', 'javelin-behavior' => 'fbeded59', 'javelin-behavior-aphlict-dropdown' => '66dca903', 'javelin-behavior-aphlict-listen' => '66dca903', 'javelin-behavior-aphront-basic-tokenizer' => '66dca903', - 'javelin-behavior-aphront-drag-and-drop' => 'ac53d36a', - 'javelin-behavior-aphront-drag-and-drop-textarea' => 'ac53d36a', + 'javelin-behavior-aphront-drag-and-drop' => '310cd201', + 'javelin-behavior-aphront-drag-and-drop-textarea' => '310cd201', 'javelin-behavior-aphront-form-disable-on-submit' => '66dca903', 'javelin-behavior-audit-preview' => 'f96657b8', 'javelin-behavior-dark-console' => '8edbada5', 'javelin-behavior-dark-console-ajax' => '8edbada5', 'javelin-behavior-device' => '66dca903', - 'javelin-behavior-differential-accept-with-errors' => 'ac53d36a', - 'javelin-behavior-differential-add-reviewers-and-ccs' => 'ac53d36a', - 'javelin-behavior-differential-comment-jump' => 'ac53d36a', - 'javelin-behavior-differential-diff-radios' => 'ac53d36a', - 'javelin-behavior-differential-dropdown-menus' => 'ac53d36a', - 'javelin-behavior-differential-edit-inline-comments' => 'ac53d36a', - 'javelin-behavior-differential-feedback-preview' => 'ac53d36a', - 'javelin-behavior-differential-keyboard-navigation' => 'ac53d36a', - 'javelin-behavior-differential-populate' => 'ac53d36a', - 'javelin-behavior-differential-show-more' => 'ac53d36a', - 'javelin-behavior-differential-toggle-files' => 'ac53d36a', - 'javelin-behavior-differential-user-select' => 'ac53d36a', + 'javelin-behavior-differential-accept-with-errors' => '310cd201', + 'javelin-behavior-differential-add-reviewers-and-ccs' => '310cd201', + 'javelin-behavior-differential-comment-jump' => '310cd201', + 'javelin-behavior-differential-diff-radios' => '310cd201', + 'javelin-behavior-differential-dropdown-menus' => '310cd201', + 'javelin-behavior-differential-edit-inline-comments' => '310cd201', + 'javelin-behavior-differential-feedback-preview' => '310cd201', + 'javelin-behavior-differential-keyboard-navigation' => '310cd201', + 'javelin-behavior-differential-populate' => '310cd201', + 'javelin-behavior-differential-show-more' => '310cd201', + 'javelin-behavior-differential-toggle-files' => '310cd201', + 'javelin-behavior-differential-user-select' => '310cd201', 'javelin-behavior-diffusion-commit-graph' => 'f96657b8', 'javelin-behavior-diffusion-pull-lastmodified' => 'f96657b8', 'javelin-behavior-error-log' => '8edbada5', 'javelin-behavior-global-drag-and-drop' => '66dca903', 'javelin-behavior-konami' => '66dca903', 'javelin-behavior-lightbox-attachments' => '66dca903', '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' => '66dca903', 'javelin-behavior-phabricator-autofocus' => '66dca903', 'javelin-behavior-phabricator-home-reveal-tiles' => '66dca903', 'javelin-behavior-phabricator-keyboard-shortcuts' => '66dca903', 'javelin-behavior-phabricator-nav' => '66dca903', - 'javelin-behavior-phabricator-object-selector' => 'ac53d36a', + 'javelin-behavior-phabricator-object-selector' => '310cd201', 'javelin-behavior-phabricator-oncopy' => '66dca903', 'javelin-behavior-phabricator-remarkup-assist' => '66dca903', 'javelin-behavior-phabricator-search-typeahead' => '66dca903', 'javelin-behavior-phabricator-tooltips' => '66dca903', 'javelin-behavior-phabricator-watch-anchor' => '66dca903', 'javelin-behavior-refresh-csrf' => '66dca903', - 'javelin-behavior-repository-crossreference' => 'ac53d36a', + 'javelin-behavior-repository-crossreference' => '310cd201', 'javelin-behavior-toggle-class' => '66dca903', 'javelin-behavior-workflow' => '66dca903', 'javelin-dom' => 'fbeded59', 'javelin-event' => 'fbeded59', 'javelin-install' => 'fbeded59', 'javelin-json' => 'fbeded59', 'javelin-mask' => 'fbeded59', 'javelin-request' => 'fbeded59', 'javelin-resource' => 'fbeded59', 'javelin-stratcom' => 'fbeded59', 'javelin-tokenizer' => 'fbeded59', 'javelin-typeahead' => 'fbeded59', 'javelin-typeahead-normalizer' => 'fbeded59', 'javelin-typeahead-ondemand-source' => 'fbeded59', 'javelin-typeahead-preloaded-source' => 'fbeded59', 'javelin-typeahead-source' => 'fbeded59', 'javelin-uri' => 'fbeded59', 'javelin-util' => 'fbeded59', 'javelin-vector' => 'fbeded59', 'javelin-workflow' => 'fbeded59', - 'lightbox-attachment-css' => '8fd19266', + 'lightbox-attachment-css' => '023adc14', 'maniphest-task-summary-css' => 'e30a3fa8', 'maniphest-transaction-detail-css' => 'e30a3fa8', 'phabricator-busy' => '66dca903', 'phabricator-content-source-view-css' => 'ec01d039', - 'phabricator-core-buttons-css' => '8fd19266', - 'phabricator-core-css' => '8fd19266', - 'phabricator-crumbs-view-css' => '8fd19266', - 'phabricator-directory-css' => '8fd19266', - 'phabricator-drag-and-drop-file-upload' => 'ac53d36a', + 'phabricator-core-buttons-css' => '023adc14', + 'phabricator-core-css' => '023adc14', + 'phabricator-crumbs-view-css' => '023adc14', + 'phabricator-directory-css' => '023adc14', + 'phabricator-drag-and-drop-file-upload' => '310cd201', 'phabricator-dropdown-menu' => '66dca903', 'phabricator-file-upload' => '66dca903', - 'phabricator-filetree-view-css' => '8fd19266', - 'phabricator-flag-css' => '8fd19266', - 'phabricator-form-view-css' => '8fd19266', - 'phabricator-header-view-css' => '8fd19266', - 'phabricator-jump-nav' => '8fd19266', + 'phabricator-filetree-view-css' => '023adc14', + 'phabricator-flag-css' => '023adc14', + 'phabricator-form-view-css' => '023adc14', + 'phabricator-header-view-css' => '023adc14', + 'phabricator-jump-nav' => '023adc14', 'phabricator-keyboard-shortcut' => '66dca903', 'phabricator-keyboard-shortcut-manager' => '66dca903', - 'phabricator-main-menu-view' => '8fd19266', + 'phabricator-main-menu-view' => '023adc14', 'phabricator-menu-item' => '66dca903', - 'phabricator-nav-view-css' => '8fd19266', + 'phabricator-nav-view-css' => '023adc14', 'phabricator-notification' => '66dca903', - 'phabricator-notification-css' => '8fd19266', - 'phabricator-notification-menu-css' => '8fd19266', - 'phabricator-object-item-list-view-css' => '8fd19266', + 'phabricator-notification-css' => '023adc14', + 'phabricator-notification-menu-css' => '023adc14', + 'phabricator-object-item-list-view-css' => '023adc14', 'phabricator-object-selector-css' => 'ec01d039', 'phabricator-paste-file-upload' => '66dca903', 'phabricator-prefab' => '66dca903', 'phabricator-project-tag-css' => 'e30a3fa8', - 'phabricator-remarkup-css' => '8fd19266', - 'phabricator-shaped-request' => 'ac53d36a', - 'phabricator-side-menu-view-css' => '8fd19266', - 'phabricator-standard-page-view' => '8fd19266', + 'phabricator-remarkup-css' => '023adc14', + 'phabricator-shaped-request' => '310cd201', + 'phabricator-side-menu-view-css' => '023adc14', + 'phabricator-standard-page-view' => '023adc14', 'phabricator-textareautils' => '66dca903', 'phabricator-tooltip' => '66dca903', - 'phabricator-transaction-view-css' => '8fd19266', - 'phabricator-zindex-css' => '8fd19266', - 'sprite-apps-large-css' => '8fd19266', - 'sprite-gradient-css' => '8fd19266', - 'sprite-icon-css' => '8fd19266', - 'sprite-menu-css' => '8fd19266', - 'syntax-highlighting-css' => '8fd19266', + 'phabricator-transaction-view-css' => '023adc14', + 'phabricator-zindex-css' => '023adc14', + 'sprite-apps-large-css' => '023adc14', + 'sprite-gradient-css' => '023adc14', + 'sprite-icon-css' => '023adc14', + 'sprite-menu-css' => '023adc14', + 'syntax-highlighting-css' => '023adc14', ), )); diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 8cf098bb7c..5090f256e3 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1,2895 +1,2899 @@ 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', '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', 'AphrontCrumbsView' => 'view/layout/AphrontCrumbsView.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', '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', 'AphrontHTMLResponse' => 'aphront/response/AphrontHTMLResponse.php', 'AphrontHTTPSink' => 'aphront/sink/AphrontHTTPSink.php', 'AphrontHTTPSinkTestCase' => 'aphront/sink/__tests__/AphrontHTTPSinkTestCase.php', 'AphrontHeadsupActionListView' => 'view/layout/headsup/AphrontHeadsupActionListView.php', 'AphrontHeadsupActionView' => 'view/layout/headsup/AphrontHeadsupActionView.php', 'AphrontHeadsupView' => 'view/layout/headsup/AphrontHeadsupView.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', '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', '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', 'AphrontTypeaheadTemplateView' => 'view/control/AphrontTypeaheadTemplateView.php', 'AphrontURIMapper' => 'aphront/AphrontURIMapper.php', 'AphrontUsageException' => 'aphront/exception/AphrontUsageException.php', 'AphrontView' => 'view/AphrontView.php', 'AphrontWebpageResponse' => 'aphront/response/AphrontWebpageResponse.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_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_publish_Method' => 'applications/feed/conduit/ConduitAPI_feed_publish_Method.php', 'ConduitAPI_feed_query_Method' => 'applications/feed/conduit/ConduitAPI_feed_query_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_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_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_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_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_info_Method' => 'applications/slowvote/conduit/ConduitAPI_slowvote_info_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', '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', + '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', 'DarkConsoleController' => 'aphront/console/DarkConsoleController.php', 'DarkConsoleCore' => 'aphront/console/DarkConsoleCore.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', 'DifferentialPrimaryPaneView' => 'applications/differential/view/DifferentialPrimaryPaneView.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', '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', 'DiffusionQuery' => 'applications/diffusion/query/DiffusionQuery.php', 'DiffusionRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionRawDiffQuery.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', 'DivinerFileAtomizer' => 'applications/diviner/atomizer/DivinerFileAtomizer.php', 'DivinerGenerateWorkflow' => 'applications/diviner/workflow/DivinerGenerateWorkflow.php', 'DivinerListController' => 'applications/diviner/controller/DivinerListController.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', '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', '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', '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', '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', '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', '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', 'PhabricatorApplicationTransactionNoEffectException' => 'applications/transactions/exception/PhabricatorApplicationTransactionNoEffectException.php', 'PhabricatorApplicationTransactionNoEffectResponse' => 'applications/transactions/response/PhabricatorApplicationTransactionNoEffectResponse.php', 'PhabricatorApplicationTransactionQuery' => 'applications/transactions/query/PhabricatorApplicationTransactionQuery.php', 'PhabricatorApplicationTransactionResponse' => 'applications/transactions/response/PhabricatorApplicationTransactionResponse.php', 'PhabricatorApplicationTransactionView' => 'applications/transactions/view/PhabricatorApplicationTransactionView.php', 'PhabricatorApplicationTransactions' => 'applications/transactions/application/PhabricatorApplicationTransactions.php', 'PhabricatorApplicationUIExamples' => 'applications/uiexample/application/PhabricatorApplicationUIExamples.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', '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', 'PhabricatorChangesetResponse' => 'infrastructure/diff/PhabricatorChangesetResponse.php', 'PhabricatorChatLogChannelListController' => 'applications/chatlog/controller/PhabricatorChatLogChannelListController.php', 'PhabricatorChatLogChannelLogController' => 'applications/chatlog/controller/PhabricatorChatLogChannelLogController.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', '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', 'PhabricatorCountdownViewController' => 'applications/countdown/controller/PhabricatorCountdownViewController.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', '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', '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', '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', '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/irc/PhabricatorIRCBot.php', 'PhabricatorIRCDifferentialNotificationHandler' => 'infrastructure/daemon/irc/handler/PhabricatorIRCDifferentialNotificationHandler.php', 'PhabricatorIRCFeedNotificationHandler' => 'infrastructure/daemon/irc/handler/PhabricatorIRCFeedNotificationHandler.php', 'PhabricatorIRCHandler' => 'infrastructure/daemon/irc/handler/PhabricatorIRCHandler.php', 'PhabricatorIRCLogHandler' => 'infrastructure/daemon/irc/handler/PhabricatorIRCLogHandler.php', 'PhabricatorIRCMacroHandler' => 'infrastructure/daemon/irc/handler/PhabricatorIRCMacroHandler.php', 'PhabricatorIRCMessage' => 'infrastructure/daemon/irc/PhabricatorIRCMessage.php', 'PhabricatorIRCObjectNameHandler' => 'infrastructure/daemon/irc/handler/PhabricatorIRCObjectNameHandler.php', 'PhabricatorIRCProtocolHandler' => 'infrastructure/daemon/irc/handler/PhabricatorIRCProtocolHandler.php', 'PhabricatorIRCSymbolHandler' => 'infrastructure/daemon/irc/handler/PhabricatorIRCSymbolHandler.php', 'PhabricatorIRCWhatsNewHandler' => 'infrastructure/daemon/irc/handler/PhabricatorIRCWhatsNewHandler.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', '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', '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', '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', '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', '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', 'PhabricatorRemarkupRuleCountdown' => 'infrastructure/markup/rule/PhabricatorRemarkupRuleCountdown.php', 'PhabricatorRemarkupRuleDifferential' => 'infrastructure/markup/rule/PhabricatorRemarkupRuleDifferential.php', 'PhabricatorRemarkupRuleDifferentialHandle' => 'infrastructure/markup/rule/handle/PhabricatorRemarkupRuleDifferentialHandle.php', 'PhabricatorRemarkupRuleDiffusion' => 'infrastructure/markup/rule/PhabricatorRemarkupRuleDiffusion.php', 'PhabricatorRemarkupRuleEmbedFile' => 'infrastructure/markup/rule/PhabricatorRemarkupRuleEmbedFile.php', 'PhabricatorRemarkupRuleImageMacro' => 'infrastructure/markup/rule/PhabricatorRemarkupRuleImageMacro.php', 'PhabricatorRemarkupRuleManiphest' => 'infrastructure/markup/rule/PhabricatorRemarkupRuleManiphest.php', 'PhabricatorRemarkupRuleManiphestHandle' => 'infrastructure/markup/rule/handle/PhabricatorRemarkupRuleManiphestHandle.php', 'PhabricatorRemarkupRuleMeme' => 'infrastructure/markup/rule/PhabricatorRemarkupRuleMeme.php', 'PhabricatorRemarkupRuleMention' => 'infrastructure/markup/rule/PhabricatorRemarkupRuleMention.php', 'PhabricatorRemarkupRuleObjectHandle' => 'infrastructure/markup/rule/PhabricatorRemarkupRuleObjectHandle.php', 'PhabricatorRemarkupRuleObjectName' => 'infrastructure/markup/rule/PhabricatorRemarkupRuleObjectName.php', 'PhabricatorRemarkupRulePaste' => 'infrastructure/markup/rule/PhabricatorRemarkupRulePaste.php', 'PhabricatorRemarkupRulePhriction' => 'infrastructure/markup/rule/PhabricatorRemarkupRulePhriction.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', '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', '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', 'PhabricatorSetupCheckStorage' => 'applications/config/check/PhabricatorSetupCheckStorage.php', 'PhabricatorSetupCheckTimezone' => 'applications/config/check/PhabricatorSetupCheckTimezone.php', 'PhabricatorSetupIssue' => 'applications/config/issue/PhabricatorSetupIssue.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/status/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', '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', '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', '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', 'PholioMock' => 'applications/pholio/storage/PholioMock.php', 'PholioMockCommentController' => 'applications/pholio/controller/PholioMockCommentController.php', 'PholioMockEditController' => 'applications/pholio/controller/PholioMockEditController.php', 'PholioMockEditor' => 'applications/pholio/editor/PholioMockEditor.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', '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', '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', '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', 'PhrictionNewController' => 'applications/phriction/controller/PhrictionNewController.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', 'PonderReplyHandler' => 'applications/ponder/PonderReplyHandler.php', 'PonderRuleQuestion' => 'infrastructure/markup/rule/PonderRuleQuestion.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', ), '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', 'phabricator_date' => 'view/viewutils.php', 'phabricator_datetime' => 'view/viewutils.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_render_form_magic' => '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', 'AphrontCSRFException' => 'AphrontException', 'AphrontCalendarEventView' => 'AphrontView', 'AphrontCalendarMonthView' => 'AphrontView', 'AphrontContextBarView' => 'AphrontView', 'AphrontController' => 'Phobject', 'AphrontCrumbsView' => 'AphrontView', 'AphrontCursorPagerView' => 'AphrontView', 'AphrontDefaultApplicationConfiguration' => 'AphrontApplicationConfiguration', 'AphrontDialogResponse' => 'AphrontResponse', 'AphrontDialogView' => 'AphrontView', 'AphrontErrorView' => 'AphrontView', 'AphrontException' => 'Exception', 'AphrontFileResponse' => 'AphrontResponse', 'AphrontFormCheckboxControl' => 'AphrontFormControl', 'AphrontFormControl' => 'AphrontView', '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', 'AphrontHTMLResponse' => 'AphrontResponse', 'AphrontHTTPSinkTestCase' => 'PhabricatorTestCase', 'AphrontHeadsupActionListView' => 'AphrontView', 'AphrontHeadsupActionView' => 'AphrontView', 'AphrontHeadsupView' => 'AphrontView', 'AphrontIsolatedDatabaseConnectionTestCase' => 'PhabricatorTestCase', 'AphrontIsolatedHTTPSink' => 'AphrontHTTPSink', 'AphrontJSONResponse' => 'AphrontResponse', 'AphrontJavelinView' => 'AphrontView', 'AphrontKeyboardShortcutsAvailableView' => 'AphrontView', 'AphrontListFilterView' => 'AphrontView', 'AphrontMiniPanelView' => 'AphrontView', 'AphrontMoreView' => 'AphrontView', 'AphrontMySQLDatabaseConnectionTestCase' => 'PhabricatorTestCase', 'AphrontNullView' => 'AphrontView', 'AphrontPHPHTTPSink' => 'AphrontHTTPSink', 'AphrontPageView' => 'AphrontView', 'AphrontPagerView' => 'AphrontView', 'AphrontPanelView' => 'AphrontView', 'AphrontPlainTextResponse' => 'AphrontResponse', 'AphrontProxyResponse' => 'AphrontResponse', 'AphrontRedirectException' => 'AphrontException', 'AphrontRedirectResponse' => 'AphrontResponse', 'AphrontReloadResponse' => 'AphrontRedirectResponse', 'AphrontRequestFailureView' => 'AphrontView', 'AphrontRequestTestCase' => 'PhabricatorTestCase', 'AphrontSideNavFilterView' => 'AphrontView', 'AphrontTableView' => 'AphrontView', 'AphrontTagView' => 'AphrontView', 'AphrontTokenizerTemplateView' => 'AphrontView', 'AphrontTypeaheadTemplateView' => 'AphrontView', 'AphrontUsageException' => 'AphrontException', 'AphrontView' => 'Phobject', 'AphrontWebpageResponse' => 'AphrontHTMLResponse', '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_findsymbols_Method' => 'ConduitAPIMethod', 'ConduitAPI_diffusion_getcommits_Method' => 'ConduitAPIMethod', 'ConduitAPI_diffusion_getlintmessages_Method' => 'ConduitAPIMethod', 'ConduitAPI_diffusion_getrecentcommitsbypath_Method' => 'ConduitAPIMethod', 'ConduitAPI_feed_publish_Method' => 'ConduitAPIMethod', 'ConduitAPI_feed_query_Method' => 'ConduitAPIMethod', 'ConduitAPI_file_download_Method' => 'ConduitAPIMethod', 'ConduitAPI_file_info_Method' => 'ConduitAPIMethod', 'ConduitAPI_file_upload_Method' => 'ConduitAPIMethod', '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_query_Method' => 'ConduitAPIMethod', '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_getast_Method' => 'ConduitAPIMethod', 'ConduitAPI_phpast_version_Method' => 'ConduitAPIMethod', '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_remarkup_process_Method' => 'ConduitAPIMethod', 'ConduitAPI_repository_Method' => 'ConduitAPIMethod', 'ConduitAPI_repository_create_Method' => 'ConduitAPI_repository_Method', 'ConduitAPI_repository_query_Method' => 'ConduitAPI_repository_Method', 'ConduitAPI_slowvote_info_Method' => 'ConduitAPIMethod', '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', 'ConpherenceListController' => 'ConpherenceController', 'ConpherenceMenuItemView' => 'AphrontTagView', 'ConpherenceNewController' => 'ConpherenceController', 'ConpherenceParticipant' => 'ConpherenceDAO', 'ConpherenceParticipantQuery' => 'PhabricatorOffsetPagedQuery', 'ConpherenceParticipationStatus' => 'ConpherenceConstants', + 'ConpherenceReplyHandler' => 'PhabricatorMailReplyHandler', 'ConpherenceThread' => array( 0 => 'ConpherenceDAO', 1 => 'PhabricatorPolicyInterface', ), 'ConpherenceThreadQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'ConpherenceTransaction' => 'PhabricatorApplicationTransaction', 'ConpherenceTransactionComment' => 'PhabricatorApplicationTransactionComment', 'ConpherenceTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'ConpherenceTransactionType' => 'ConpherenceConstants', 'ConpherenceTransactionView' => 'AphrontView', 'ConpherenceUpdateController' => 'ConpherenceController', 'ConpherenceViewController' => 'ConpherenceController', 'DarkConsoleController' => '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', 'DifferentialManiphestTasksFieldSpecification' => 'DifferentialFieldSpecification', 'DifferentialNewDiffMail' => 'DifferentialReviewRequestMail', 'DifferentialParseRenderTestCase' => 'PhabricatorTestCase', 'DifferentialPathFieldSpecification' => 'DifferentialFieldSpecification', 'DifferentialPrimaryPaneView' => 'AphrontView', 'DifferentialReplyHandler' => 'PhabricatorMailReplyHandler', 'DifferentialResultsTableView' => 'AphrontView', 'DifferentialRevertPlanFieldSpecification' => 'DifferentialFieldSpecification', 'DifferentialReviewRequestMail' => 'DifferentialMail', 'DifferentialReviewedByFieldSpecification' => 'DifferentialFieldSpecification', 'DifferentialReviewerStatsTestCase' => 'PhabricatorTestCase', 'DifferentialReviewersFieldSpecification' => 'DifferentialFieldSpecification', 'DifferentialRevision' => 'DifferentialDAO', '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', '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', 'DiffusionRawDiffQuery' => 'DiffusionQuery', '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', 'DivinerAtomizeWorkflow' => 'DivinerWorkflow', 'DivinerFileAtomizer' => 'DivinerAtomizer', 'DivinerGenerateWorkflow' => 'DivinerWorkflow', 'DivinerListController' => 'PhabricatorController', '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', 'ManiphestAuxiliaryFieldTypeException' => 'Exception', 'ManiphestAuxiliaryFieldValidationException' => 'Exception', 'ManiphestBatchEditController' => 'ManiphestController', 'ManiphestController' => 'PhabricatorController', 'ManiphestDAO' => 'PhabricatorLiskDAO', 'ManiphestDefaultTaskExtensions' => 'ManiphestTaskExtensions', 'ManiphestEdgeEventListener' => 'PhutilEventListener', 'ManiphestExportController' => 'ManiphestController', 'ManiphestReplyHandler' => 'PhabricatorMailReplyHandler', 'ManiphestReportController' => 'ManiphestController', 'ManiphestSavedQuery' => 'ManiphestDAO', 'ManiphestSavedQueryDeleteController' => 'ManiphestController', 'ManiphestSavedQueryEditController' => 'ManiphestController', 'ManiphestSavedQueryListController' => 'ManiphestController', 'ManiphestSearchIndexer' => 'PhabricatorSearchDocumentIndexer', 'ManiphestSubpriorityController' => 'ManiphestController', 'ManiphestTask' => array( 0 => 'ManiphestDAO', 1 => 'PhabricatorMarkupInterface', ), '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', 'PackageModifyMail' => 'PackageMail', 'Phabricator404Controller' => 'PhabricatorController', 'PhabricatorAWSConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorAccessLogConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorActionListExample' => 'PhabricatorUIExample', 'PhabricatorActionListView' => 'AphrontView', 'PhabricatorActionView' => 'AphrontView', 'PhabricatorAllCapsTranslation' => 'PhabricatorTranslation', 'PhabricatorAnchorView' => 'AphrontView', 'PhabricatorApplicationApplications' => 'PhabricatorApplication', 'PhabricatorApplicationAudit' => 'PhabricatorApplication', 'PhabricatorApplicationAuth' => 'PhabricatorApplication', 'PhabricatorApplicationCalendar' => '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', 'PhabricatorApplicationRepositories' => 'PhabricatorApplication', 'PhabricatorApplicationSettings' => 'PhabricatorApplication', 'PhabricatorApplicationSlowvote' => 'PhabricatorApplication', 'PhabricatorApplicationStatusView' => 'AphrontView', 'PhabricatorApplicationSubscriptions' => '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', 'PhabricatorApplicationTransactionView' => 'AphrontView', 'PhabricatorApplicationTransactions' => 'PhabricatorApplication', 'PhabricatorApplicationUIExamples' => 'PhabricatorApplication', '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', 'PhabricatorBuiltinPatchList' => 'PhabricatorSQLPatchList', 'PhabricatorButtonsExample' => 'PhabricatorUIExample', 'PhabricatorCacheDAO' => 'PhabricatorLiskDAO', 'PhabricatorCalendarBrowseController' => 'PhabricatorCalendarController', 'PhabricatorCalendarController' => 'PhabricatorController', 'PhabricatorCalendarDAO' => 'PhabricatorLiskDAO', 'PhabricatorCalendarDeleteStatusController' => 'PhabricatorCalendarController', 'PhabricatorCalendarEditStatusController' => 'PhabricatorCalendarController', 'PhabricatorCalendarHoliday' => 'PhabricatorCalendarDAO', 'PhabricatorCalendarHolidayTestCase' => 'PhabricatorTestCase', 'PhabricatorCalendarViewStatusController' => 'PhabricatorCalendarController', 'PhabricatorChangesetResponse' => 'AphrontProxyResponse', 'PhabricatorChatLogChannelListController' => 'PhabricatorChatLogController', 'PhabricatorChatLogChannelLogController' => 'PhabricatorChatLogController', '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', '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', 'PhabricatorCountdownViewController' => 'PhabricatorCountdownController', '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', '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', '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', ), 'PhabricatorFileInfoController' => 'PhabricatorFileController', 'PhabricatorFileLinkListView' => 'AphrontView', 'PhabricatorFileLinkView' => 'AphrontView', 'PhabricatorFileListController' => 'PhabricatorFileController', 'PhabricatorFileQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorFileShortcutController' => 'PhabricatorFileController', 'PhabricatorFileStorageBlob' => 'PhabricatorFileDAO', 'PhabricatorFileStorageConfigurationException' => 'Exception', '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', 'PhabricatorGitHubConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorGlobalLock' => 'PhutilLock', 'PhabricatorGlobalUploadTargetView' => 'AphrontView', 'PhabricatorGoogleConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorHashTestCase' => 'PhabricatorTestCase', 'PhabricatorHeaderView' => 'AphrontView', 'PhabricatorHelpController' => 'PhabricatorController', 'PhabricatorHelpKeyboardShortcutController' => 'PhabricatorHelpController', 'PhabricatorIRCBot' => 'PhabricatorDaemon', 'PhabricatorIRCDifferentialNotificationHandler' => 'PhabricatorIRCHandler', 'PhabricatorIRCFeedNotificationHandler' => 'PhabricatorIRCHandler', 'PhabricatorIRCLogHandler' => 'PhabricatorIRCHandler', 'PhabricatorIRCMacroHandler' => 'PhabricatorIRCHandler', 'PhabricatorIRCObjectNameHandler' => 'PhabricatorIRCHandler', 'PhabricatorIRCProtocolHandler' => 'PhabricatorIRCHandler', 'PhabricatorIRCSymbolHandler' => 'PhabricatorIRCHandler', 'PhabricatorIRCWhatsNewHandler' => 'PhabricatorIRCHandler', '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', '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', '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', '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', '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', 'PhabricatorRemarkupRuleCountdown' => 'PhutilRemarkupRule', 'PhabricatorRemarkupRuleDifferential' => 'PhabricatorRemarkupRuleObjectName', 'PhabricatorRemarkupRuleDifferentialHandle' => 'PhabricatorRemarkupRuleObjectHandle', 'PhabricatorRemarkupRuleDiffusion' => 'PhabricatorRemarkupRuleObjectName', 'PhabricatorRemarkupRuleEmbedFile' => 'PhutilRemarkupRule', 'PhabricatorRemarkupRuleImageMacro' => 'PhutilRemarkupRule', 'PhabricatorRemarkupRuleManiphest' => 'PhabricatorRemarkupRuleObjectName', 'PhabricatorRemarkupRuleManiphestHandle' => 'PhabricatorRemarkupRuleObjectHandle', 'PhabricatorRemarkupRuleMeme' => 'PhutilRemarkupRule', 'PhabricatorRemarkupRuleMention' => 'PhutilRemarkupRule', 'PhabricatorRemarkupRuleObjectHandle' => 'PhutilRemarkupRule', 'PhabricatorRemarkupRuleObjectName' => 'PhutilRemarkupRule', 'PhabricatorRemarkupRulePaste' => 'PhabricatorRemarkupRuleObjectName', 'PhabricatorRemarkupRulePhriction' => 'PhutilRemarkupRule', 'PhabricatorRemarkupRuleYoutube' => 'PhutilRemarkupRule', 'PhabricatorRepository' => array( 0 => 'PhabricatorRepositoryDAO', 1 => 'PhabricatorPolicyInterface', ), 'PhabricatorRepositoryArcanistProject' => 'PhabricatorRepositoryDAO', 'PhabricatorRepositoryArcanistProjectDeleteController' => 'PhabricatorRepositoryController', 'PhabricatorRepositoryArcanistProjectEditController' => 'PhabricatorRepositoryController', 'PhabricatorRepositoryAuditRequest' => 'PhabricatorRepositoryDAO', 'PhabricatorRepositoryBranch' => 'PhabricatorRepositoryDAO', 'PhabricatorRepositoryCommit' => 'PhabricatorRepositoryDAO', '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', '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', 'PhabricatorSetupCheckInvalidConfig' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckMail' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckMySQL' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckPHPConfig' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckPath' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckStorage' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckTimezone' => 'PhabricatorSetupCheck', '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', 'PhabricatorTestWorker' => 'PhabricatorWorker', 'PhabricatorTimelineCursor' => 'PhabricatorTimelineDAO', 'PhabricatorTimelineDAO' => 'PhabricatorLiskDAO', 'PhabricatorTimelineEvent' => 'PhabricatorTimelineDAO', 'PhabricatorTimelineEventData' => 'PhabricatorTimelineDAO', 'PhabricatorTimelineEventView' => 'AphrontView', 'PhabricatorTimelineExample' => 'PhabricatorUIExample', 'PhabricatorTimelineIterator' => 'Iterator', 'PhabricatorTimelineView' => 'AphrontView', 'PhabricatorTimer' => 'PhabricatorCountdownDAO', 'PhabricatorTransactionView' => 'AphrontView', 'PhabricatorTransformedFile' => 'PhabricatorFileDAO', 'PhabricatorTranslationsConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorTrivialTestCase' => 'PhabricatorTestCase', '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', ), 'PholioMock' => array( 0 => 'PholioDAO', 1 => 'PhabricatorMarkupInterface', 2 => 'PhabricatorPolicyInterface', 3 => 'PhabricatorSubscribableInterface', ), 'PholioMockCommentController' => 'PholioController', 'PholioMockEditController' => 'PholioController', 'PholioMockEditor' => 'PhabricatorApplicationTransactionEditor', 'PholioMockImagesView' => 'AphrontView', 'PholioMockListController' => 'PholioController', 'PholioMockQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PholioMockViewController' => 'PholioController', 'PholioReplyHandler' => 'PhabricatorMailReplyHandler', 'PholioSearchIndexer' => 'PhabricatorSearchDocumentIndexer', 'PholioTransaction' => 'PhabricatorApplicationTransaction', 'PholioTransactionComment' => 'PhabricatorApplicationTransactionComment', 'PholioTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PholioTransactionType' => 'PholioConstants', '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', 'PhrictionDocumentStatus' => 'PhrictionConstants', 'PhrictionDocumentTestCase' => 'PhabricatorTestCase', 'PhrictionEditController' => 'PhrictionController', 'PhrictionHistoryController' => 'PhrictionController', 'PhrictionListController' => 'PhrictionController', 'PhrictionNewController' => 'PhrictionController', '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', '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', 'PonderReplyHandler' => 'PhabricatorMailReplyHandler', 'PonderRuleQuestion' => 'PhabricatorRemarkupRuleObjectName', 'PonderSearchIndexer' => 'PhabricatorSearchDocumentIndexer', 'PonderUserProfileView' => 'AphrontView', 'PonderVotableView' => 'AphrontView', 'PonderVoteEditor' => 'PhabricatorEditor', 'PonderVoteSaveController' => 'PonderController', 'QueryFormattingTestCase' => 'PhabricatorTestCase', ), )); diff --git a/src/applications/auth/controller/PhabricatorAuthController.php b/src/applications/auth/controller/PhabricatorAuthController.php index 60dc5bcbc9..19094da148 100644 --- a/src/applications/auth/controller/PhabricatorAuthController.php +++ b/src/applications/auth/controller/PhabricatorAuthController.php @@ -1,17 +1,17 @@ buildStandardPageView(); - $page->setApplicationName('Login'); + $page->setApplicationName(pht('Login')); $page->setBaseURI('/login/'); $page->setTitle(idx($data, 'title')); $page->appendChild($view); $response = new AphrontWebpageResponse(); return $response->setContent($page->render()); } } diff --git a/src/applications/auth/controller/PhabricatorDisabledUserController.php b/src/applications/auth/controller/PhabricatorDisabledUserController.php index 08647187b5..dcd1e36abc 100644 --- a/src/applications/auth/controller/PhabricatorDisabledUserController.php +++ b/src/applications/auth/controller/PhabricatorDisabledUserController.php @@ -1,28 +1,29 @@ getRequest(); $user = $request->getUser(); if (!$user->getIsDisabled()) { return new Aphront404Response(); } $failure_view = new AphrontRequestFailureView(); - $failure_view->setHeader('Account Disabled'); - $failure_view->appendChild('

Your account has been disabled.

'); + $failure_view->setHeader(pht('Account Disabled')); + $failure_view->appendChild( + '

'.pht('Your account has been disabled.').'

'); return $this->buildStandardPageResponse( $failure_view, array( - 'title' => 'Account Disabled', + 'title' => pht('Account Disabled'), )); } } diff --git a/src/applications/auth/controller/PhabricatorEmailLoginController.php b/src/applications/auth/controller/PhabricatorEmailLoginController.php index bf142ea23e..e6cc6372df 100644 --- a/src/applications/auth/controller/PhabricatorEmailLoginController.php +++ b/src/applications/auth/controller/PhabricatorEmailLoginController.php @@ -1,153 +1,159 @@ getRequest(); if (!PhabricatorEnv::getEnvConfig('auth.password-auth-enabled')) { return new Aphront400Response(); } $e_email = true; $e_captcha = true; $errors = array(); $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business'); if ($request->isFormPost()) { $e_email = null; - $e_captcha = 'Again'; + $e_captcha = pht('Again'); $captcha_ok = AphrontFormRecaptchaControl::processCaptcha($request); if (!$captcha_ok) { - $errors[] = "Captcha response is incorrect, try again."; - $e_captcha = 'Invalid'; + $errors[] = pht("Captcha response is incorrect, try again."); + $e_captcha = pht('Invalid'); } $email = $request->getStr('email'); if (!strlen($email)) { - $errors[] = "You must provide an email address."; - $e_email = 'Required'; + $errors[] = pht("You must provide an email address."); + $e_email = pht('Required'); } if (!$errors) { // NOTE: Don't validate the email unless the captcha is good; this makes // it expensive to fish for valid email addresses while giving the user // a better error if they goof their email. $target_email = id(new PhabricatorUserEmail())->loadOneWhere( 'address = %s', $email); $target_user = null; if ($target_email) { $target_user = id(new PhabricatorUser())->loadOneWhere( 'phid = %s', $target_email->getUserPHID()); } if (!$target_user) { - $errors[] = "There is no account associated with that email address."; - $e_email = "Invalid"; + $errors[] = + pht("There is no account associated with that email address."); + $e_email = pht("Invalid"); } if (!$errors) { $uri = $target_user->getEmailLoginURI($target_email); if ($is_serious) { $body = <<setSubject('[Phabricator] Password Reset'); $mail->addTos( array( $target_user->getPHID(), )); $mail->setBody($body); $mail->saveAndSend(); $view = new AphrontRequestFailureView(); - $view->setHeader('Check Your Email'); + $view->setHeader(pht('Check Your Email')); $view->appendChild( - '

An email has been sent with a link you can use to login.

'); + '

'.pht( + 'An email has been sent with a link you can use to login.' + ).'

'); return $this->buildStandardPageResponse( $view, array( - 'title' => 'Email Sent', + 'title' => pht('Email Sent'), )); } } } $email_auth = new AphrontFormView(); $email_auth ->setAction('/login/email/') ->setUser($request->getUser()) ->appendChild( id(new AphrontFormTextControl()) - ->setLabel('Email') + ->setLabel(pht('Email')) ->setName('email') ->setValue($request->getStr('email')) ->setError($e_email)) ->appendChild( id(new AphrontFormRecaptchaControl()) - ->setLabel('Captcha') + ->setLabel(pht('Captcha')) ->setError($e_captcha)) ->appendChild( id(new AphrontFormSubmitControl()) - ->setValue('Send Email')); + ->setValue(pht('Send Email'))); $error_view = null; if ($errors) { $error_view = new AphrontErrorView(); - $error_view->setTitle('Login Error'); + $error_view->setTitle(pht('Login Error')); $error_view->setErrors($errors); } $panel = new AphrontPanelView(); $panel->setWidth(AphrontPanelView::WIDTH_FORM); - $panel->appendChild('

Forgot Password / Email Login

'); + $panel->appendChild(' +

'.pht('Forgot Password / Email Login').'

'); $panel->appendChild($email_auth); + $panel->setNoBackground(); - return $this->buildStandardPageResponse( + return $this->buildApplicationPage( array( $error_view, $panel, ), array( - 'title' => 'Create New Account', + 'title' => pht('Forgot Password'), + 'device' => true, )); } } diff --git a/src/applications/auth/controller/PhabricatorEmailTokenController.php b/src/applications/auth/controller/PhabricatorEmailTokenController.php index 0f2187ee31..855caa37af 100644 --- a/src/applications/auth/controller/PhabricatorEmailTokenController.php +++ b/src/applications/auth/controller/PhabricatorEmailTokenController.php @@ -1,104 +1,106 @@ token = $data['token']; } public function processRequest() { $request = $this->getRequest(); if (!PhabricatorEnv::getEnvConfig('auth.password-auth-enabled')) { return new Aphront400Response(); } $token = $this->token; $email = $request->getStr('email'); // NOTE: We need to bind verification to **addresses**, not **users**, // because we verify addresses when they're used to login this way, and if // we have a user-based verification you can: // // - Add some address you do not own; // - request a password reset; // - change the URI in the email to the address you don't own; // - login via the email link; and // - get a "verified" address you don't control. $target_email = id(new PhabricatorUserEmail())->loadOneWhere( 'address = %s', $email); $target_user = null; if ($target_email) { $target_user = id(new PhabricatorUser())->loadOneWhere( 'phid = %s', $target_email->getUserPHID()); } if (!$target_email || !$target_user || !$target_user->validateEmailToken($target_email, $token)) { $view = new AphrontRequestFailureView(); - $view->setHeader('Unable to Login'); + $view->setHeader(pht('Unable to Login')); $view->appendChild( - '

The authentication information in the link you clicked is '. + '

'.pht('The authentication information in the link you clicked is '. 'invalid or out of date. Make sure you are copy-and-pasting the '. 'entire link into your browser. You can try again, or request '. - 'a new email.

'); + 'a new email.').'

'); $view->appendChild( '
'. - 'Send Another Email'. + ''. + pht('Send Another Email'). + ''. '
'); return $this->buildStandardPageResponse( $view, array( - 'title' => 'Login Failure', + 'title' => pht('Login Failure'), )); } // Verify email so that clicking the link in the "Welcome" email is good // enough, without requiring users to go through a second round of email // verification. $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $target_email->setIsVerified(1); $target_email->save(); $session_key = $target_user->establishSession('web'); unset($unguarded); $request->setCookie('phusr', $target_user->getUsername()); $request->setCookie('phsid', $session_key); if (PhabricatorEnv::getEnvConfig('account.editable')) { $next = (string)id(new PhutilURI('/settings/panel/password/')) ->setQueryParams( array( 'token' => $token, 'email' => $email, )); } else { $next = '/'; } $uri = new PhutilURI('/login/validate/'); $uri->setQueryParams( array( 'phusr' => $target_user->getUsername(), 'next' => $next, )); return id(new AphrontRedirectResponse()) ->setURI((string)$uri); } } diff --git a/src/applications/auth/controller/PhabricatorLDAPLoginController.php b/src/applications/auth/controller/PhabricatorLDAPLoginController.php index 60595be4eb..4dafe831f7 100644 --- a/src/applications/auth/controller/PhabricatorLDAPLoginController.php +++ b/src/applications/auth/controller/PhabricatorLDAPLoginController.php @@ -1,171 +1,174 @@ provider = new PhabricatorLDAPProvider(); } public function processRequest() { if (!$this->provider->isProviderEnabled()) { return new Aphront400Response(); } $current_user = $this->getRequest()->getUser(); $request = $this->getRequest(); $ldap_username = $request->getCookie('phusr'); if ($request->isFormPost()) { $ldap_username = $request->getStr('username'); try { $envelope = new PhutilOpaqueEnvelope($request->getStr('password')); $this->provider->auth($ldap_username, $envelope); } catch (Exception $e) { $errors[] = $e->getMessage(); } if (empty($errors)) { $ldap_info = $this->retrieveLDAPInfo($this->provider); if ($current_user->getPHID()) { if ($ldap_info->getID()) { $existing_ldap = id(new PhabricatorUserLDAPInfo())->loadOneWhere( 'userID = %d', $current_user->getID()); if ($ldap_info->getUserID() != $current_user->getID() || $existing_ldap) { $dialog = new AphrontDialogView(); $dialog->setUser($current_user); - $dialog->setTitle('Already Linked to Another Account'); + $dialog->setTitle(pht('Already Linked to Another Account')); $dialog->appendChild( - '

The LDAP account you just authorized is already linked to '. - 'another Phabricator account. Before you can link it to a '. - 'different LDAP account, you must unlink the old account.

' + '

'.pht('The LDAP account you just authorized is already '. + 'linked toanother Phabricator account. Before you can link it '. + 'to a different LDAP account, you must unlink the old '. + 'account.').'

' ); $dialog->addCancelButton('/settings/panel/ldap/'); return id(new AphrontDialogResponse())->setDialog($dialog); } else { return id(new AphrontRedirectResponse()) ->setURI('/settings/panel/ldap/'); } } if (!$request->isDialogFormPost()) { $dialog = new AphrontDialogView(); $dialog->setUser($current_user); - $dialog->setTitle('Link LDAP Account'); + $dialog->setTitle(pht('Link LDAP Account')); $dialog->appendChild( - '

Link your LDAP account to your Phabricator account?

'); + '

'. + pht('Link your LDAP account to your Phabricator account?'). + '

'); $dialog->addHiddenInput('username', $request->getStr('username')); $dialog->addHiddenInput('password', $request->getStr('password')); - $dialog->addSubmitButton('Link Accounts'); + $dialog->addSubmitButton(pht('Link Accounts')); $dialog->addCancelButton('/settings/panel/ldap/'); return id(new AphrontDialogResponse())->setDialog($dialog); } $ldap_info->setUserID($current_user->getID()); $this->saveLDAPInfo($ldap_info); return id(new AphrontRedirectResponse()) ->setURI('/settings/panel/ldap/'); } if ($ldap_info->getID()) { $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $known_user = id(new PhabricatorUser())->load( $ldap_info->getUserID()); $session_key = $known_user->establishSession('web'); $this->saveLDAPInfo($ldap_info); $request->setCookie('phusr', $known_user->getUsername()); $request->setCookie('phsid', $session_key); $uri = new PhutilURI('/login/validate/'); $uri->setQueryParams( array( 'phusr' => $known_user->getUsername(), )); return id(new AphrontRedirectResponse())->setURI((string)$uri); } $controller = newv('PhabricatorLDAPRegistrationController', array($this->getRequest())); $controller->setLDAPProvider($this->provider); $controller->setLDAPInfo($ldap_info); return $this->delegateToController($controller); } } $ldap_form = new AphrontFormView(); $ldap_form ->setUser($request->getUser()) ->setAction('/ldap/login/') ->appendChild( id(new AphrontFormTextControl()) - ->setLabel('LDAP username') + ->setLabel(pht('LDAP username')) ->setName('username') ->setValue($ldap_username)) ->appendChild( id(new AphrontFormPasswordControl()) - ->setLabel('Password') + ->setLabel(pht('Password')) ->setName('password')); $ldap_form ->appendChild( id(new AphrontFormSubmitControl()) - ->setValue('Login')); + ->setValue(pht('Login'))); $panel = new AphrontPanelView(); $panel->setWidth(AphrontPanelView::WIDTH_FORM); - $panel->appendChild('

LDAP login

'); + $panel->appendChild('

'.pht('LDAP login').'

'); $panel->appendChild($ldap_form); if (isset($errors) && count($errors) > 0) { $error_view = new AphrontErrorView(); - $error_view->setTitle('Login Failed'); + $error_view->setTitle(pht('Login Failed')); $error_view->setErrors($errors); } return $this->buildStandardPageResponse( array( isset($error_view) ? $error_view : null, $panel, ), array( - 'title' => 'Login', + 'title' => pht('Login'), )); } private function retrieveLDAPInfo(PhabricatorLDAPProvider $provider) { $ldap_info = id(new PhabricatorUserLDAPInfo())->loadOneWhere( 'ldapUsername = %s', $provider->retrieveUsername()); if (!$ldap_info) { $ldap_info = new PhabricatorUserLDAPInfo(); $ldap_info->setLDAPUsername($provider->retrieveUsername()); } return $ldap_info; } private function saveLDAPInfo(PhabricatorUserLDAPInfo $info) { // UNGUARDED WRITES: Logging-in users don't have their CSRF set up yet. $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $info->save(); } } diff --git a/src/applications/auth/controller/PhabricatorLDAPRegistrationController.php b/src/applications/auth/controller/PhabricatorLDAPRegistrationController.php index 1fde2ef450..e52eea2134 100644 --- a/src/applications/auth/controller/PhabricatorLDAPRegistrationController.php +++ b/src/applications/auth/controller/PhabricatorLDAPRegistrationController.php @@ -1,220 +1,220 @@ ldapProvider = $provider; return $this; } public function getLDAProvider() { return $this->ldapProvider; } public function setLDAPInfo($info) { $this->ldapInfo = $info; return $this; } public function getLDAPInfo() { return $this->ldapInfo; } public function processRequest() { $provider = $this->getLDAProvider(); $ldap_info = $this->getLDAPInfo(); $request = $this->getRequest(); $errors = array(); $e_username = true; $e_email = true; $e_realname = true; $user = new PhabricatorUser(); $user->setUsername($provider->retrieveUsername()); $user->setRealname($provider->retrieveUserRealName()); $new_email = $provider->retrieveUserEmail(); if ($new_email) { // If the user's LDAP provider account has an email address but the // email address domain is not allowed by the Phabricator configuration, // we just pretend the provider did not supply an address. // // For instance, if the user uses LDAP Auth and their email address // is "joe@personal.com" but Phabricator is configured to require users // use "@company.com" addresses, we show a prompt below and tell the user // to provide their "@company.com" address. They can still use the LDAP // account to login, they just need to associate their account with an // allowed address. // // If the email address is fine, we just use it and don't prompt the user. if (!PhabricatorUserEmail::isAllowedAddress($new_email)) { $new_email = null; } } $show_email_input = ($new_email === null); if ($request->isFormPost()) { $user->setUsername($request->getStr('username')); $username = $user->getUsername(); if (!strlen($user->getUsername())) { - $e_username = 'Required'; - $errors[] = 'Username is required.'; + $e_username = pht('Required'); + $errors[] = pht('Username is required.'); } else if (!PhabricatorUser::validateUsername($username)) { - $e_username = 'Invalid'; + $e_username = pht('Invalid'); $errors[] = PhabricatorUser::describeValidUsername(); } else { $e_username = null; } if (!$new_email) { $new_email = trim($request->getStr('email')); if (!$new_email) { - $e_email = 'Required'; - $errors[] = 'Email is required.'; + $e_email = pht('Required'); + $errors[] = pht('Email is required.'); } else { $e_email = null; } } if ($new_email) { if (!PhabricatorUserEmail::isAllowedAddress($new_email)) { - $e_email = 'Invalid'; + $e_email = pht('Invalid'); $errors[] = PhabricatorUserEmail::describeAllowedAddresses(); } } if (!strlen($user->getRealName())) { $user->setRealName($request->getStr('realname')); if (!strlen($user->getRealName())) { - $e_realname = 'Required'; - $errors[] = 'Real name is required.'; + $e_realname = pht('Required'); + $errors[] = pht('Real name is required.'); } else { $e_realname = null; } } if (!$errors) { try { // NOTE: We don't verify LDAP email addresses by default because // LDAP providers might associate email addresses with accounts that // haven't actually verified they own them. We could selectively // auto-verify some providers that we trust here, but the stakes for // verifying an email address are high because having a corporate // address at a company is sometimes the key to the castle. $email_obj = id(new PhabricatorUserEmail()) ->setAddress($new_email) ->setIsVerified(0); id(new PhabricatorUserEditor()) ->setActor($user) ->createNewUser($user, $email_obj); $ldap_info->setUserID($user->getID()); $ldap_info->save(); $session_key = $user->establishSession('web'); $request->setCookie('phusr', $user->getUsername()); $request->setCookie('phsid', $session_key); $email_obj->sendVerificationEmail($user); return id(new AphrontRedirectResponse())->setURI('/'); } catch (AphrontQueryDuplicateKeyException $exception) { $same_username = id(new PhabricatorUser())->loadOneWhere( 'userName = %s', $user->getUserName()); $same_email = id(new PhabricatorUserEmail())->loadOneWhere( 'address = %s', $new_email); if ($same_username) { - $e_username = 'Duplicate'; - $errors[] = 'That username or email is not unique.'; + $e_username = pht('Duplicate'); + $errors[] = pht('That username or email is not unique.'); } else if ($same_email) { - $e_email = 'Duplicate'; - $errors[] = 'That email is not unique.'; + $e_email = pht('Duplicate'); + $errors[] = pht('That email is not unique.'); } else { throw $exception; } } } } $error_view = null; if ($errors) { $error_view = new AphrontErrorView(); - $error_view->setTitle('Registration Failed'); + $error_view->setTitle(pht('Registration Failed')); $error_view->setErrors($errors); } // Strip the URI down to the path, because otherwise we'll trigger // external CSRF protection (by having a protocol in the form "action") // and generate a form with no CSRF token. $action_uri = new PhutilURI('/ldap/login/'); $action_path = $action_uri->getPath(); $form = new AphrontFormView(); $form ->setUser($request->getUser()) ->setAction($action_path) ->appendChild( id(new AphrontFormTextControl()) - ->setLabel('Username') + ->setLabel(pht('Username')) ->setName('username') ->setValue($user->getUsername()) ->setError($e_username)); $form->appendChild( id(new AphrontFormPasswordControl()) - ->setLabel('Password') + ->setLabel(pht('Password')) ->setName('password')); if ($show_email_input) { $form->appendChild( id(new AphrontFormTextControl()) - ->setLabel('Email') + ->setLabel(pht('Email')) ->setName('email') ->setValue($request->getStr('email')) ->setError($e_email)); } if ($provider->retrieveUserRealName() === null) { $form->appendChild( id(new AphrontFormTextControl()) - ->setLabel('Real Name') + ->setLabel(pht('Real Name')) ->setName('realname') ->setValue($request->getStr('realname')) ->setError($e_realname)); } $form ->appendChild( id(new AphrontFormSubmitControl()) - ->setValue('Create Account')); + ->setValue(pht('Create Account'))); $panel = new AphrontPanelView(); - $panel->setHeader('Create New Account'); + $panel->setHeader(pht('Create New Account')); $panel->setWidth(AphrontPanelView::WIDTH_FORM); $panel->appendChild($form); return $this->buildStandardPageResponse( array( $error_view, $panel, ), array( - 'title' => 'Create New Account', + 'title' => pht('Create New Account'), )); } } diff --git a/src/applications/auth/controller/PhabricatorLDAPUnlinkController.php b/src/applications/auth/controller/PhabricatorLDAPUnlinkController.php index 180c20ce73..44cad5a398 100644 --- a/src/applications/auth/controller/PhabricatorLDAPUnlinkController.php +++ b/src/applications/auth/controller/PhabricatorLDAPUnlinkController.php @@ -1,36 +1,36 @@ getRequest(); $user = $request->getUser(); $ldap_info = id(new PhabricatorUserLDAPInfo())->loadOneWhere( 'userID = %d', $user->getID()); if (!$ldap_info) { return new Aphront400Response(); } if (!$request->isDialogFormPost()) { $dialog = new AphrontDialogView(); $dialog->setUser($user); - $dialog->setTitle('Really unlink account?'); + $dialog->setTitle(pht('Really unlink account?')); $dialog->appendChild( - '

You will not be able to login using this account '. - 'once you unlink it. Continue?

'); - $dialog->addSubmitButton('Unlink Account'); + '

'.pht('You will not be able to login using this account '. + 'once you unlink it. Continue?').'

'); + $dialog->addSubmitButton(pht('Unlink Account')); $dialog->addCancelButton('/settings/panel/ldap/'); return id(new AphrontDialogResponse())->setDialog($dialog); } $ldap_info->delete(); return id(new AphrontRedirectResponse()) ->setURI('/settings/panel/ldap/'); } } diff --git a/src/applications/auth/controller/PhabricatorLoginController.php b/src/applications/auth/controller/PhabricatorLoginController.php index 6bc87c5aab..c4bda38a77 100644 --- a/src/applications/auth/controller/PhabricatorLoginController.php +++ b/src/applications/auth/controller/PhabricatorLoginController.php @@ -1,306 +1,311 @@ getRequest(); $user = $request->getUser(); if ($user->isLoggedIn()) { // Kick the user out if they're already logged in. return id(new AphrontRedirectResponse())->setURI('/'); } if ($request->isAjax()) { // We end up here if the user clicks a workflow link that they need to // login to use. We give them a dialog saying "You need to login..". if ($request->isDialogFormPost()) { return id(new AphrontRedirectResponse())->setURI( $request->getRequestURI()); } $dialog = new AphrontDialogView(); $dialog->setUser($user); - $dialog->setTitle('Login Required'); - $dialog->appendChild('

You must login to continue.

'); - $dialog->addSubmitButton('Login'); - $dialog->addCancelButton('/', 'Cancel'); + $dialog->setTitle(pht('Login Required')); + $dialog->appendChild('

'.pht('You must login to continue.').'

'); + $dialog->addSubmitButton(pht('Login')); + $dialog->addCancelButton('/', pht('Cancel')); return id(new AphrontDialogResponse())->setDialog($dialog); } if ($request->isConduit()) { // A common source of errors in Conduit client configuration is getting // the request path wrong. The client will end up here, so make some // effort to give them a comprehensible error message. $request_path = $this->getRequest()->getPath(); $conduit_path = '/api/'; $example_path = '/api/conduit.ping'; $message = "ERROR: You are making a Conduit API request to '{$request_path}', ". "but the correct HTTP request path to use in order to access a ". "Conduit method is '{$conduit_path}' (for example, ". "'{$example_path}'). Check your configuration."; return id(new AphrontPlainTextResponse())->setContent($message); } $error_view = null; if ($request->getCookie('phusr') && $request->getCookie('phsid')) { // The session cookie is invalid, so clear it. $request->clearCookie('phusr'); $request->clearCookie('phsid'); $error_view = new AphrontErrorView(); - $error_view->setTitle('Invalid Session'); + $error_view->setTitle(pht('Invalid Session')); $error_view->setErrors(array( - "Your login session is invalid. Try logging in again. If that ". - "doesn't work, clear your browser cookies." + pht("Your login session is invalid. Try logging in again. If that ". + "doesn't work, clear your browser cookies.") )); } $next_uri_path = $this->getRequest()->getPath(); if ($next_uri_path == '/login/') { $next_uri = '/'; } else { $next_uri = $this->getRequest()->getRequestURI(); } if (!$request->isFormPost()) { $request->setCookie('next_uri', $next_uri); } $password_auth = PhabricatorEnv::getEnvConfig('auth.password-auth-enabled'); $username_or_email = $request->getCookie('phusr'); $forms = array(); $errors = array(); if ($password_auth) { $require_captcha = false; $e_captcha = true; if ($request->isFormPost()) { if (AphrontFormRecaptchaControl::isRecaptchaEnabled()) { $failed_attempts = PhabricatorUserLog::loadRecentEventsFromThisIP( PhabricatorUserLog::ACTION_LOGIN_FAILURE, 60 * 15); if (count($failed_attempts) > 5) { $require_captcha = true; if (!AphrontFormRecaptchaControl::processCaptcha($request)) { if (AphrontFormRecaptchaControl::hasCaptchaResponse($request)) { - $e_captcha = 'Invalid'; - $errors[] = 'CAPTCHA was not entered correctly.'; + $e_captcha = pht('Invalid'); + $errors[] = pht('CAPTCHA was not entered correctly.'); } else { - $e_captcha = 'Required'; - $errors[] = 'Too many login failures recently. You must '. - 'submit a CAPTCHA with your login request.'; + $e_captcha = pht('Required'); + $errors[] = pht('Too many login failures recently. You must '. + 'submit a CAPTCHA with your login request.'); } } } } $username_or_email = $request->getStr('username_or_email'); $user = id(new PhabricatorUser())->loadOneWhere( 'username = %s', $username_or_email); if (!$user) { $user = PhabricatorUser::loadOneWithEmailAddress($username_or_email); } if (!$errors) { // Perform username/password tests only if we didn't get rate limited // by the CAPTCHA. $envelope = new PhutilOpaqueEnvelope($request->getStr('password')); if (!$user || !$user->comparePassword($envelope)) { - $errors[] = 'Bad username/password.'; + $errors[] = pht('Bad username/password.'); } } if (!$errors) { $session_key = $user->establishSession('web'); $request->setCookie('phusr', $user->getUsername()); $request->setCookie('phsid', $session_key); $uri = new PhutilURI('/login/validate/'); $uri->setQueryParams( array( 'phusr' => $user->getUsername(), )); return id(new AphrontRedirectResponse()) ->setURI((string)$uri); } else { $log = PhabricatorUserLog::newLog( null, $user, PhabricatorUserLog::ACTION_LOGIN_FAILURE); $log->save(); $request->clearCookie('phusr'); $request->clearCookie('phsid'); } } if ($errors) { $error_view = new AphrontErrorView(); - $error_view->setTitle('Login Failed'); + $error_view->setTitle(pht('Login Failed')); $error_view->setErrors($errors); } $form = new AphrontFormView(); $form ->setUser($request->getUser()) ->setAction('/login/') ->appendChild( id(new AphrontFormTextControl()) - ->setLabel('Username/Email') + ->setLabel(pht('Username/Email')) ->setName('username_or_email') ->setValue($username_or_email)) ->appendChild( id(new AphrontFormPasswordControl()) - ->setLabel('Password') + ->setLabel(pht('Password')) ->setName('password') ->setCaption( ''. - 'Forgot your password? / Email Login')); + pht('Forgot your password? / Email Login').'')); if ($require_captcha) { $form->appendChild( id(new AphrontFormRecaptchaControl()) ->setError($e_captcha)); } $form ->appendChild( id(new AphrontFormSubmitControl()) - ->setValue('Login')); + ->setValue(pht('Login'))); // $panel->setCreateButton('Register New Account', '/login/register/'); $forms['Phabricator Login'] = $form; } $ldap_provider = new PhabricatorLDAPProvider(); if ($ldap_provider->isProviderEnabled()) { $ldap_form = new AphrontFormView(); $ldap_form ->setUser($request->getUser()) ->setAction('/ldap/login/') ->appendChild( id(new AphrontFormTextControl()) - ->setLabel('LDAP username') + ->setLabel(pht('LDAP username')) ->setName('username') ->setValue($username_or_email)) ->appendChild( id(new AphrontFormPasswordControl()) - ->setLabel('Password') + ->setLabel(pht('Password')) ->setName('password')); $ldap_form ->appendChild( id(new AphrontFormSubmitControl()) - ->setValue('Login')); + ->setValue(pht('Login'))); $forms['LDAP Login'] = $ldap_form; } $providers = PhabricatorOAuthProvider::getAllProviders(); foreach ($providers as $provider) { $enabled = $provider->isProviderEnabled(); if (!$enabled) { continue; } $auth_uri = $provider->getAuthURI(); $redirect_uri = $provider->getRedirectURI(); $client_id = $provider->getClientID(); $provider_name = $provider->getProviderName(); $minimum_scope = $provider->getMinimumScope(); $extra_auth = $provider->getExtraAuthParameters(); // TODO: In theory we should use 'state' to prevent CSRF, but the total // effect of the CSRF attack is that an attacker can cause a user to login // to Phabricator if they're already logged into some OAuth provider. This // does not seem like the most severe threat in the world, and generating // CSRF for logged-out users is vaugely tricky. if ($provider->isProviderRegistrationEnabled()) { - $title = "Login or Register with {$provider_name}"; - $body = 'Login or register for Phabricator using your '. - phutil_escape_html($provider_name).' account.'; - $button = "Login or Register with {$provider_name}"; + $title = pht("Login or Register with %s", + phutil_escape_html($provider_name)); + $body = pht('Login or register for Phabricator using your %s account.', + phutil_escape_html($provider_name)); + $button = pht("Login or Register with %s", + phutil_escape_html($provider_name)); } else { - $title = "Login with {$provider_name}"; - $body = 'Login to your existing Phabricator account using your '. - phutil_escape_html($provider_name).' account.

'. - 'You can not use '. - phutil_escape_html($provider_name).' to register a new '. - 'account.'; - $button = "Login with {$provider_name}"; + $title = pht("Login with %s", + phutil_escape_html($provider_name)); + $body = pht('Login to your existing Phabricator account using your '. + '%s account.', phutil_escape_html($provider_name)). + '

'. + ''. + pht('You can not use %s to register a new account.', + phutil_escape_html($provider_name)). + ''; + $button = pht("Log in with %s", phutil_escape_html($provider_name)); } $auth_form = new AphrontFormView(); $auth_form ->setAction($auth_uri) ->addHiddenInput('client_id', $client_id) ->addHiddenInput('redirect_uri', $redirect_uri) ->addHiddenInput('scope', $minimum_scope); foreach ($extra_auth as $key => $value) { $auth_form->addHiddenInput($key, $value); } $auth_form ->setUser($request->getUser()) ->setMethod('GET') ->appendChild( '

'.$body.'

') ->appendChild( id(new AphrontFormSubmitControl()) ->setValue("{$button} \xC2\xBB")); $forms[$title] = $auth_form; } $panel = new AphrontPanelView(); $panel->setWidth(AphrontPanelView::WIDTH_FORM); $panel->setNoBackground(); foreach ($forms as $name => $form) { $panel->appendChild('

'.$name.'

'); $panel->appendChild($form); $panel->appendChild('
'); } $login_message = PhabricatorEnv::getEnvConfig('auth.login-message'); return $this->buildApplicationPage( array( $error_view, $login_message, $panel, ), array( - 'title' => 'Login', + 'title' => pht('Login'), 'device' => true )); } } diff --git a/src/applications/auth/controller/PhabricatorLoginValidateController.php b/src/applications/auth/controller/PhabricatorLoginValidateController.php index 7ddc737011..9423199711 100644 --- a/src/applications/auth/controller/PhabricatorLoginValidateController.php +++ b/src/applications/auth/controller/PhabricatorLoginValidateController.php @@ -1,76 +1,76 @@ getRequest(); $failures = array(); if (!strlen($request->getStr('phusr'))) { throw new Exception( "Login validation is missing expected parameters!"); } $expect_phusr = $request->getStr('phusr'); $actual_phusr = $request->getCookie('phusr'); if ($actual_phusr != $expect_phusr) { if ($actual_phusr) { $cookie_info = "sent back a cookie with the value '{$actual_phusr}'."; } else { $cookie_info = "did not accept the cookie."; } $failures[] = "Attempted to set 'phusr' cookie to '{$expect_phusr}', but your ". "browser {$cookie_info}"; } if (!$failures) { if (!$request->getUser()->getPHID()) { $failures[] = "Cookies were set correctly, but your session ". "isn't valid."; } } if ($failures) { $list = array(); foreach ($failures as $failure) { $list[] = '
  • '.phutil_escape_html($failure).'
  • '; } $list = ''; $view = new AphrontRequestFailureView(); - $view->setHeader('Login Failed'); + $view->setHeader(pht('Login Failed')); $view->appendChild( - '

    Login failed:

    '. + '

    '.pht('Login failed:').'

    '. $list. - '

    Clear your cookies and try again.

    '); + '

    '.pht('Clear your cookies and try again.').'

    '); $view->appendChild( ''); return $this->buildStandardPageResponse( $view, array( - 'title' => 'Login Failed', + 'title' => pht('Login Failed'), )); } $next = nonempty($request->getStr('next'), $request->getCookie('next_uri')); $request->clearCookie('next_uri'); if (!PhabricatorEnv::isValidLocalWebResource($next)) { $next = '/'; } return id(new AphrontRedirectResponse())->setURI($next); } } diff --git a/src/applications/auth/controller/PhabricatorLogoutController.php b/src/applications/auth/controller/PhabricatorLogoutController.php index fc3e9c8dc5..e2cc5410fa 100644 --- a/src/applications/auth/controller/PhabricatorLogoutController.php +++ b/src/applications/auth/controller/PhabricatorLogoutController.php @@ -1,59 +1,59 @@ getRequest(); $user = $request->getUser(); if ($request->isFormPost()) { $log = PhabricatorUserLog::newLog( $user, $user, PhabricatorUserLog::ACTION_LOGOUT); $log->save(); // Destroy the user's session in the database so logout works even if // their cookies have some issues. We'll detect cookie issues when they // try to login again and tell them to clear any junk. $phsid = $request->getCookie('phsid'); if ($phsid) { $user->destroySession($phsid); } $request->clearCookie('phsid'); return id(new AphrontRedirectResponse()) ->setURI('/login/'); } if ($user->getPHID()) { $dialog = id(new AphrontDialogView()) ->setUser($user) - ->setTitle('Log out of Phabricator?') - ->appendChild('

    Are you sure you want to log out?

    ') - ->addSubmitButton('Log Out') + ->setTitle(pht('Log out of Phabricator?')) + ->appendChild('

    '.pht('Are you sure you want to log out?').'

    ') + ->addSubmitButton(pht('Logout')) ->addCancelButton('/'); return id(new AphrontDialogResponse())->setDialog($dialog); } return id(new AphrontRedirectResponse())->setURI('/'); } } diff --git a/src/applications/auth/controller/PhabricatorMustVerifyEmailController.php b/src/applications/auth/controller/PhabricatorMustVerifyEmailController.php index 58655c2e8b..21af745ed2 100644 --- a/src/applications/auth/controller/PhabricatorMustVerifyEmailController.php +++ b/src/applications/auth/controller/PhabricatorMustVerifyEmailController.php @@ -1,74 +1,79 @@ getRequest(); $user = $request->getUser(); $email = $user->loadPrimaryEmail(); if ($email->getIsVerified()) { return id(new AphrontRedirectResponse())->setURI('/'); } $email_address = $email->getAddress(); $sent = null; if ($request->isFormPost()) { $email->sendVerificationEmail($user); $sent = new AphrontErrorView(); $sent->setSeverity(AphrontErrorView::SEVERITY_NOTICE); - $sent->setTitle('Email Sent'); - $sent->appendChild( - '

    Another verification email was sent to '. - phutil_escape_html($email_address).'.

    '); + $sent->setTitle(pht('Email Sent')); + $sent->appendChild('

    '. + pht('Another verification email was sent to %s.', + phutil_escape_html($email_address)).'

    '); } $error_view = new AphrontRequestFailureView(); - $error_view->setHeader('Check Your Email'); + $error_view->setHeader(pht('Check Your Email')); $error_view->appendChild( - '

    You must verify your email address to login. You should have a new '. + '

    '. + pht('You must verify your email address to login. You should have a new '. 'email message from Phabricator with verification instructions in your '. - 'inbox ('.phutil_escape_html($email_address).').

    '); + 'inbox (%s).', phutil_escape_html($email_address)). + '

    '); $error_view->appendChild( - '

    If you did not receive an email, you can click the button below '. - 'to try sending another one.

    '); + '

    '. + pht('If you did not receive an email, you can click the button below '. + 'to try sending another one.'). + '

    '); $error_view->appendChild( '
    '. phabricator_render_form( $user, array( 'action' => '/login/mustverify/', 'method' => 'POST', ), phutil_tag( 'button', array( ), - 'Send Another Email')). + pht('Send Another Email'))). '
    '); - return $this->buildStandardPageResponse( + return $this->buildApplicationPage( array( $sent, $error_view, ), array( - 'title' => 'Must Verify Email', + 'title' => pht('Must Verify Email'), + 'device' => true )); } } diff --git a/src/applications/auth/controller/PhabricatorOAuthLoginController.php b/src/applications/auth/controller/PhabricatorOAuthLoginController.php index 09be7d076e..2a6c9da6e1 100644 --- a/src/applications/auth/controller/PhabricatorOAuthLoginController.php +++ b/src/applications/auth/controller/PhabricatorOAuthLoginController.php @@ -1,339 +1,340 @@ provider = PhabricatorOAuthProvider::newProvider($data['provider']); } public function processRequest() { $current_user = $this->getRequest()->getUser(); $provider = $this->provider; if (!$provider->isProviderEnabled()) { return new Aphront400Response(); } $provider_name = $provider->getProviderName(); $provider_key = $provider->getProviderKey(); $request = $this->getRequest(); if ($request->getStr('error')) { $error_view = id(new PhabricatorOAuthFailureView()) ->setRequest($request); return $this->buildErrorResponse($error_view); } $error_response = $this->retrieveAccessToken($provider); if ($error_response) { return $error_response; } $userinfo_uri = new PhutilURI($provider->getUserInfoURI()); $userinfo_uri->setQueryParam('access_token', $this->accessToken); $userinfo_uri = (string)$userinfo_uri; try { $user_data = HTTPSFuture::loadContent($userinfo_uri); if ($user_data === false) { throw new PhabricatorOAuthProviderException( "Request to '{$userinfo_uri}' failed!"); } $provider->setUserData($user_data); } catch (PhabricatorOAuthProviderException $e) { return $this->buildErrorResponse(new PhabricatorOAuthFailureView(), $e); } $provider->setAccessToken($this->accessToken); $user_id = $provider->retrieveUserID(); $provider_key = $provider->getProviderKey(); $oauth_info = $this->retrieveOAuthInfo($provider); if ($current_user->getPHID()) { if ($oauth_info->getID()) { if ($oauth_info->getUserID() != $current_user->getID()) { $dialog = new AphrontDialogView(); $dialog->setUser($current_user); - $dialog->setTitle('Already Linked to Another Account'); - $dialog->appendChild( - hsprintf( - '

    The %s account you just authorized is already linked to '. + $dialog->setTitle(pht('Already Linked to Another Account')); + $dialog->appendChild('

    '. + pht( + 'The %s account you just authorized is already linked to '. 'another Phabricator account. Before you can associate your %s '. 'account with this Phabriactor account, you must unlink it from '. 'the Phabricator account it is currently linked to.

    ', - $provider_name, - $provider_name)); + phutil_escape_html($provider_name), + phutil_escape_html($provider_name))).'

    '; $dialog->addCancelButton($provider->getSettingsPanelURI()); return id(new AphrontDialogResponse())->setDialog($dialog); } else { $this->saveOAuthInfo($oauth_info); // Refresh token. return id(new AphrontRedirectResponse()) ->setURI($provider->getSettingsPanelURI()); } } $existing_oauth = id(new PhabricatorUserOAuthInfo())->loadOneWhere( 'userID = %d AND oauthProvider = %s', $current_user->getID(), $provider_key); if ($existing_oauth) { $dialog = new AphrontDialogView(); $dialog->setUser($current_user); - $dialog->setTitle('Already Linked to an Account From This Provider'); - $dialog->appendChild( - hsprintf( - '

    The account you are logged in with is already linked to a %s '. + $dialog->setTitle( + pht('Already Linked to an Account From This Provider')); + $dialog->appendChild('

    '. + pht( + 'The account you are logged in with is already linked to a %s '. 'account. Before you can link it to a different %s account, you '. 'must unlink the old account.

    ', - $provider_name, - $provider_name)); + phutil_escape_html($provider_name), + phutil_escape_html($provider_name))).'

    '; $dialog->addCancelButton($provider->getSettingsPanelURI()); return id(new AphrontDialogResponse())->setDialog($dialog); } if (!$request->isDialogFormPost()) { $dialog = new AphrontDialogView(); $dialog->setUser($current_user); - $dialog->setTitle('Link '.$provider_name.' Account'); + $dialog->setTitle(pht('Link %s Account', $provider_name)); $dialog->appendChild( - hsprintf( + pht( '

    Link your %s account to your Phabricator account?

    ', - $provider_name)); + phutil_escape_html($provider_name))); $dialog->addHiddenInput('confirm_token', $provider->getAccessToken()); $dialog->addHiddenInput('expires', $oauth_info->getTokenExpires()); $dialog->addHiddenInput('state', $this->oauthState); $dialog->addHiddenInput('scope', $oauth_info->getTokenScope()); $dialog->addSubmitButton('Link Accounts'); $dialog->addCancelButton($provider->getSettingsPanelURI()); return id(new AphrontDialogResponse())->setDialog($dialog); } $oauth_info->setUserID($current_user->getID()); $this->saveOAuthInfo($oauth_info); return id(new AphrontRedirectResponse()) ->setURI($provider->getSettingsPanelURI()); } // Login with known auth. if ($oauth_info->getID()) { $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $known_user = id(new PhabricatorUser())->load($oauth_info->getUserID()); $request->getApplicationConfiguration()->willAuthenticateUserWithOAuth( $known_user, $oauth_info, $provider); $session_key = $known_user->establishSession('web'); $this->saveOAuthInfo($oauth_info); $request->setCookie('phusr', $known_user->getUsername()); $request->setCookie('phsid', $session_key); $uri = new PhutilURI('/login/validate/'); $uri->setQueryParams( array( 'phusr' => $known_user->getUsername(), )); return id(new AphrontRedirectResponse())->setURI((string)$uri); } $oauth_email = $provider->retrieveUserEmail(); if ($oauth_email) { $known_email = id(new PhabricatorUserEmail()) ->loadOneWhere('address = %s', $oauth_email); if ($known_email) { $dialog = new AphrontDialogView(); $dialog->setUser($current_user); - $dialog->setTitle('Already Linked to Another Account'); - $dialog->appendChild( - hsprintf( - '

    The %s account you just authorized has an email address which '. + $dialog->setTitle(pht('Already Linked to Another Account')); + $dialog->appendChild('

    '. + pht( + 'The %s account you just authorized has an email address which '. 'is already in use by another Phabricator account. To link the '. 'accounts, log in to your Phabricator account and then go to '. - 'Settings.

    ', - $provider_name)); + 'Settings.', + phutil_escape_html($provider_name))).'

    '; $user = id(new PhabricatorUser()) ->loadOneWhere('phid = %s', $known_email->getUserPHID()); $oauth_infos = id(new PhabricatorUserOAuthInfo()) ->loadAllWhere('userID = %d', $user->getID()); if ($oauth_infos) { $providers = array(); foreach ($oauth_infos as $info) { $provider = $info->getOAuthProvider(); $providers[] = PhabricatorOAuthProvider::newProvider($provider) ->getProviderName(); } $dialog->appendChild( - hsprintf( + pht( '

    The account is associated with: %s.

    ', - implode(', ', $providers))); + implode(', ', phutil_escape_html($providers)))); } $dialog->addCancelButton('/login/'); return id(new AphrontDialogResponse())->setDialog($dialog); } } if (!$provider->isProviderRegistrationEnabled()) { $dialog = new AphrontDialogView(); $dialog->setUser($current_user); - $dialog->setTitle('No Account Registration With '.$provider_name); - $dialog->appendChild( - hsprintf( - '

    You can not register a new account using %s; you can only use '. + $dialog->setTitle(pht('No Account Registration with %s', $provider_name)); + $dialog->appendChild('

    '. + pht( + 'You can not register a new account using %s; you can only use '. 'your %s account to log into an existing Phabricator account which '. - 'you have registered through other means.

    ', - $provider_name, - $provider_name)); + 'you have registered through other means.', + phutil_escape_html($provider_name), + phutil_escape_html($provider_name))).'

    '; $dialog->addCancelButton('/login/'); return id(new AphrontDialogResponse())->setDialog($dialog); } $controller = PhabricatorEnv::newObjectFromConfig( 'controller.oauth-registration', array($this->getRequest())); $controller->setOAuthProvider($provider); $controller->setOAuthInfo($oauth_info); $controller->setOAuthState($this->oauthState); return $this->delegateToController($controller); } private function buildErrorResponse(PhabricatorOAuthFailureView $view, Exception $e = null) { $provider = $this->provider; $provider_name = $provider->getProviderName(); $view->setOAuthProvider($provider); if ($e) { $view->setException($e); } return $this->buildStandardPageResponse( $view, array( - 'title' => $provider_name.' Auth Failed', + 'title' => pht('Auth Failed'), )); } private function retrieveAccessToken(PhabricatorOAuthProvider $provider) { $request = $this->getRequest(); $token = $request->getStr('confirm_token'); if ($token) { $this->tokenExpires = $request->getInt('expires'); $this->accessToken = $token; $this->oauthState = $request->getStr('state'); return null; } $client_id = $provider->getClientID(); $client_secret = $provider->getClientSecret(); $redirect_uri = $provider->getRedirectURI(); $auth_uri = $provider->getTokenURI(); $code = $request->getStr('code'); $query_data = array( 'client_id' => $client_id, 'client_secret' => $client_secret, 'redirect_uri' => $redirect_uri, 'code' => $code, ) + $provider->getExtraTokenParameters(); $future = new HTTPSFuture($auth_uri, $query_data); $future->setMethod('POST'); try { list($response) = $future->resolvex(); } catch (Exception $ex) { return $this->buildErrorResponse(new PhabricatorOAuthFailureView()); } $data = $provider->decodeTokenResponse($response); $token = idx($data, 'access_token'); if (!$token) { return $this->buildErrorResponse(new PhabricatorOAuthFailureView()); } $this->tokenExpires = $provider->getTokenExpiryFromArray($data); $this->accessToken = $token; $this->oauthState = $request->getStr('state'); return null; } private function retrieveOAuthInfo(PhabricatorOAuthProvider $provider) { $oauth_info = id(new PhabricatorUserOAuthInfo())->loadOneWhere( 'oauthProvider = %s and oauthUID = %s', $provider->getProviderKey(), $provider->retrieveUserID()); $scope = $this->getRequest()->getStr('scope'); if (!$oauth_info) { $oauth_info = new PhabricatorUserOAuthInfo(); $oauth_info->setOAuthProvider($provider->getProviderKey()); $oauth_info->setOAuthUID($provider->retrieveUserID()); // some providers don't tell you what scope you got, so default // to the minimum Phabricator requires rather than assuming no scope if (!$scope) { $scope = $provider->getMinimumScope(); } } $oauth_info->setAccountURI($provider->retrieveUserAccountURI()); $oauth_info->setAccountName($provider->retrieveUserAccountName()); $oauth_info->setToken($provider->getAccessToken()); $oauth_info->setTokenStatus(PhabricatorUserOAuthInfo::TOKEN_STATUS_GOOD); $oauth_info->setTokenScope($scope); // If we have out-of-date expiration info, just clear it out. Then replace // it with good info if the provider gave it to us. $expires = $oauth_info->getTokenExpires(); if ($expires <= time()) { $expires = null; } if ($this->tokenExpires) { $expires = $this->tokenExpires; } $oauth_info->setTokenExpires($expires); return $oauth_info; } private function saveOAuthInfo(PhabricatorUserOAuthInfo $info) { // UNGUARDED WRITES: Logging-in users don't have their CSRF set up yet. $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $info->save(); } } diff --git a/src/applications/auth/controller/PhabricatorOAuthUnlinkController.php b/src/applications/auth/controller/PhabricatorOAuthUnlinkController.php index 816dae4bba..bff01b251b 100644 --- a/src/applications/auth/controller/PhabricatorOAuthUnlinkController.php +++ b/src/applications/auth/controller/PhabricatorOAuthUnlinkController.php @@ -1,52 +1,52 @@ provider = PhabricatorOAuthProvider::newProvider($data['provider']); } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $provider = $this->provider; if ($provider->isProviderLinkPermanent()) { throw new Exception( - "You may not unlink accounts from this OAuth provider."); + pht("You may not unlink accounts from this OAuth provider.")); } $provider_key = $provider->getProviderKey(); $oauth_info = id(new PhabricatorUserOAuthInfo())->loadOneWhere( 'userID = %d AND oauthProvider = %s', $user->getID(), $provider_key); if (!$oauth_info) { return new Aphront400Response(); } if (!$request->isDialogFormPost()) { $dialog = new AphrontDialogView(); $dialog->setUser($user); - $dialog->setTitle('Really unlink account?'); + $dialog->setTitle(pht('Really unlink account?')); $dialog->appendChild( - '

    You will not be able to login using this account '. - 'once you unlink it. Continue?

    '); - $dialog->addSubmitButton('Unlink Account'); + '

    '.pht('You will not be able to login using this account '. + 'once you unlink it. Continue?').'

    '); + $dialog->addSubmitButton(pht('Unlink Account')); $dialog->addCancelButton($provider->getSettingsPanelURI()); return id(new AphrontDialogResponse())->setDialog($dialog); } $oauth_info->delete(); return id(new AphrontRedirectResponse()) ->setURI($provider->getSettingsPanelURI()); } } diff --git a/src/applications/auth/controller/oauthregistration/PhabricatorOAuthDefaultRegistrationController.php b/src/applications/auth/controller/oauthregistration/PhabricatorOAuthDefaultRegistrationController.php index a88c27fd91..6b81024bf7 100644 --- a/src/applications/auth/controller/oauthregistration/PhabricatorOAuthDefaultRegistrationController.php +++ b/src/applications/auth/controller/oauthregistration/PhabricatorOAuthDefaultRegistrationController.php @@ -1,223 +1,225 @@ getOAuthProvider(); $oauth_info = $this->getOAuthInfo(); $request = $this->getRequest(); $errors = array(); $e_username = true; $e_email = true; $e_realname = true; $user = new PhabricatorUser(); $user->setUsername($provider->retrieveUserAccountName()); $user->setRealName($provider->retrieveUserRealName()); $new_email = $provider->retrieveUserEmail(); if ($new_email) { // If the user's OAuth provider account has an email address but the // email address domain is not allowed by the Phabricator configuration, // we just pretend the provider did not supply an address. // // For instance, if the user uses Google OAuth and their Google address // is "joe@personal.com" but Phabricator is configured to require users // use "@company.com" addresses, we show a prompt below and tell the user // to provide their "@company.com" address. They can still use the OAuth // account to login, they just need to associate their account with an // allowed address. // // If the OAuth address is fine, we just use it and don't prompt the user. if (!PhabricatorUserEmail::isAllowedAddress($new_email)) { $new_email = null; } } $show_email_input = ($new_email === null); if ($request->isFormPost()) { $user->setUsername($request->getStr('username')); $username = $user->getUsername(); if (!strlen($user->getUsername())) { - $e_username = 'Required'; - $errors[] = 'Username is required.'; + $e_username = pht('Required'); + $errors[] = pht('Username is required.'); } else if (!PhabricatorUser::validateUsername($username)) { - $e_username = 'Invalid'; + $e_username = pht('Invalid'); $errors[] = PhabricatorUser::describeValidUsername(); } else { $e_username = null; } if (!$new_email) { $new_email = trim($request->getStr('email')); if (!$new_email) { - $e_email = 'Required'; - $errors[] = 'Email is required.'; + $e_email = pht('Required'); + $errors[] = pht('Email is required.'); } else { $e_email = null; } } if ($new_email) { $email_ok = PhabricatorUserEmail::isAllowedAddress($new_email); if (!$email_ok) { - $e_email = 'Invalid'; + $e_email = pht('Invalid'); $errors[] = PhabricatorUserEmail::describeAllowedAddresses(); } } if (!strlen($user->getRealName())) { $user->setRealName($request->getStr('realname')); if (!strlen($user->getRealName())) { - $e_realname = 'Required'; - $errors[] = 'Real name is required.'; + $e_realname = pht('Required'); + $errors[] = pht('Real name is required.'); } else { $e_realname = null; } } if (!$errors) { $image = $provider->retrieveUserProfileImage(); if ($image) { $file = PhabricatorFile::newFromFileData( $image, array( 'name' => $provider->getProviderKey().'-profile.jpg', 'authorPHID' => $user->getPHID(), )); $xformer = new PhabricatorImageTransformer(); // Resize OAuth image to a reasonable size $small_xformed = $xformer->executeProfileTransform( $file, $width = 50, $min_height = 50, $max_height = 50); $user->setProfileImagePHID($small_xformed->getPHID()); } try { // NOTE: We don't verify OAuth email addresses by default because // OAuth providers might associate email addresses with accounts that // haven't actually verified they own them. We could selectively // auto-verify some providers that we trust here, but the stakes for // verifying an email address are high because having a corporate // address at a company is sometimes the key to the castle. $email_obj = id(new PhabricatorUserEmail()) ->setAddress($new_email) ->setIsVerified(0); id(new PhabricatorUserEditor()) ->setActor($user) ->createNewUser($user, $email_obj); $oauth_info->setUserID($user->getID()); $oauth_info->save(); $session_key = $user->establishSession('web'); $request->setCookie('phusr', $user->getUsername()); $request->setCookie('phsid', $session_key); $email_obj->sendVerificationEmail($user); return id(new AphrontRedirectResponse())->setURI('/'); } catch (AphrontQueryDuplicateKeyException $exception) { $same_username = id(new PhabricatorUser())->loadOneWhere( 'userName = %s', $user->getUserName()); $same_email = id(new PhabricatorUserEmail())->loadOneWhere( 'address = %s', $new_email); if ($same_username) { - $e_username = 'Duplicate'; - $errors[] = 'That username or email is not unique.'; + $e_username = pht('Duplicate'); + $errors[] = pht('That username or email is not unique.'); } else if ($same_email) { - $e_email = 'Duplicate'; - $errors[] = 'That email is not unique.'; + $e_email = pht('Duplicate'); + $errors[] = pht('That email is not unique.'); } else { throw $exception; } } } } $error_view = null; if ($errors) { $error_view = new AphrontErrorView(); - $error_view->setTitle('Registration Failed'); + $error_view->setTitle(pht('Registration Failed')); $error_view->setErrors($errors); } // Strip the URI down to the path, because otherwise we'll trigger // external CSRF protection (by having a protocol in the form "action") // and generate a form with no CSRF token. $action_uri = new PhutilURI($provider->getRedirectURI()); $action_path = $action_uri->getPath(); $form = new AphrontFormView(); $form ->addHiddenInput('confirm_token', $provider->getAccessToken()) ->addHiddenInput('expires', $oauth_info->getTokenExpires()) ->addHiddenInput('state', $this->getOAuthState()) ->setUser($request->getUser()) ->setAction($action_path) ->appendChild( id(new AphrontFormTextControl()) - ->setLabel('Username') + ->setLabel(pht('Username')) ->setName('username') ->setValue($user->getUsername()) ->setError($e_username)); if ($show_email_input) { $form->appendChild( id(new AphrontFormTextControl()) - ->setLabel('Email') + ->setLabel(pht('Email')) ->setName('email') ->setValue($request->getStr('email')) ->setCaption(PhabricatorUserEmail::describeAllowedAddresses()) ->setError($e_email)); } if ($provider->retrieveUserRealName() === null) { $form->appendChild( id(new AphrontFormTextControl()) - ->setLabel('Real Name') + ->setLabel(pht('Real Name')) ->setName('realname') ->setValue($request->getStr('realname')) ->setError($e_realname)); } $form ->appendChild( id(new AphrontFormSubmitControl()) - ->setValue('Create Account')); + ->setValue(pht('Create Account'))); $panel = new AphrontPanelView(); - $panel->setHeader('Create New Account'); + $panel->setHeader(pht('Create New Account')); $panel->setWidth(AphrontPanelView::WIDTH_FORM); $panel->appendChild($form); + $panel->setNoBackground(); - return $this->buildStandardPageResponse( + return $this->buildApplicationPage( array( $error_view, $panel, ), array( - 'title' => 'Create New Account', + 'title' => pht('Create New Account'), + 'device' => true )); } } diff --git a/src/applications/auth/view/PhabricatorOAuthFailureView.php b/src/applications/auth/view/PhabricatorOAuthFailureView.php index 4853410dbd..b8fa2afd2f 100644 --- a/src/applications/auth/view/PhabricatorOAuthFailureView.php +++ b/src/applications/auth/view/PhabricatorOAuthFailureView.php @@ -1,88 +1,88 @@ request = $request; return $this; } public function setOAuthProvider($provider) { $this->provider = $provider; return $this; } public function setException(Exception $e) { $this->exception = $e; return $this; } public function render() { $request = $this->request; $provider = $this->provider; $provider_name = $provider->getProviderName(); $diagnose = null; $view = new AphrontRequestFailureView(); - $view->setHeader($provider_name.' Auth Failed'); + $view->setHeader(pht('%s Auth Failed', $provider_name)); if ($this->request) { $view->appendChild( hsprintf( '

    Description: %s

    ', $request->getStr('error_description'))); $view->appendChild( hsprintf( '

    Error: %s

    ', $request->getStr('error'))); $view->appendChild( hsprintf( '

    Error Reason: %s

    ', $request->getStr('error_reason'))); } else if ($this->exception) { $view->appendChild( hsprintf( '

    Error Details: %s

    ', $this->exception->getMessage())); } else { // TODO: We can probably refine this. $view->appendChild( hsprintf( '

    Unable to authenticate with %s. '. 'There are several reasons this might happen:

    '. ''. '

    You can try again, or login using another method.

    ', $provider_name, $provider_name, $provider_name, $provider_name)); $provider_key = $provider->getProviderKey(); $diagnose = hsprintf( ''. 'Diagnose %s OAuth Problems'. '', $provider_name); } $view->appendChild( '
    '. $diagnose. - 'Continue'. + ''.pht('Continue').''. '
    '); return $view->render(); } } diff --git a/src/applications/config/controller/PhabricatorConfigAllController.php b/src/applications/config/controller/PhabricatorConfigAllController.php index e140ffc9ef..e7b46c7c3c 100644 --- a/src/applications/config/controller/PhabricatorConfigAllController.php +++ b/src/applications/config/controller/PhabricatorConfigAllController.php @@ -1,97 +1,96 @@ getRequest(); $user = $request->getUser(); $rows = array(); $options = PhabricatorApplicationConfigOptions::loadAllOptions(); ksort($options); foreach ($options as $option) { $key = $option->getKey(); if ($option->getMasked()) { $value = ''.pht('Masked').''; } else if ($option->getHidden()) { $value = ''.pht('Hidden').''; } else { $value = PhabricatorEnv::getEnvConfig($key); $value = PhabricatorConfigJSON::prettyPrintJSON($value); $value = phutil_escape_html($value); } $rows[] = array( phutil_tag( 'a', array( 'href' => $this->getApplicationURI('edit/'.$key.'/'), ), $key), $value, ); } $table = id(new AphrontTableView($rows)) ->setDeviceReadyTable(true) ->setColumnClasses( array( '', 'wide', )) ->setHeaders( array( pht('Key'), pht('Value'), )); $title = pht('Current Settings'); $crumbs = $this ->buildApplicationCrumbs() ->addCrumb( id(new PhabricatorCrumbView()) ->setName($title)); $panel = new AphrontPanelView(); $panel->appendChild($table); $panel->setNoBackground(); $phabricator_root = dirname(phutil_get_library_root('phabricator')); $future = id(new ExecFuture('git log --format=%%H -n 1 --')) ->setCWD($phabricator_root); list($err, $stdout) = $future->resolve(); if (!$err) { $display_version = trim($stdout); } else { $display_version = pht('Unknown'); } $version_property_list = id(new PhabricatorPropertyListView()); $version_property_list->addProperty('Version', phutil_escape_html($display_version)); $version_path = $phabricator_root.'/conf/local/VERSION'; if (Filesystem::pathExists($version_path)) { $version_from_file = Filesystem::readFile($version_path); $version_property_list->addProperty('Local Version', phutil_escape_html($version_from_file)); } $nav = $this->buildSideNavView(); $nav->selectFilter('all/'); $nav->setCrumbs($crumbs); $nav->appendChild($version_property_list); $nav->appendChild($panel); - return $this->buildApplicationPage( $nav, array( 'title' => $title, 'device' => true, ) ); } } diff --git a/src/applications/config/controller/PhabricatorConfigGroupController.php b/src/applications/config/controller/PhabricatorConfigGroupController.php index 2f53b30496..2e6ca6f4a4 100644 --- a/src/applications/config/controller/PhabricatorConfigGroupController.php +++ b/src/applications/config/controller/PhabricatorConfigGroupController.php @@ -1,119 +1,120 @@ groupKey = $data['key']; } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $groups = PhabricatorApplicationConfigOptions::loadAll(); $options = idx($groups, $this->groupKey); if (!$options) { return new Aphront404Response(); } $title = pht('%s Configuration', $options->getName()); $header = id(new PhabricatorHeaderView()) ->setHeader($title); $list = $this->buildOptionList($options->getOptions()); $crumbs = $this ->buildApplicationCrumbs() ->addCrumb( id(new PhabricatorCrumbView()) ->setName(pht('Config')) ->setHref($this->getApplicationURI())) ->addCrumb( id(new PhabricatorCrumbView()) ->setName($options->getName()) ->setHref($this->getApplicationURI())); return $this->buildApplicationPage( array( $crumbs, $header, $list, ), array( 'title' => $title, 'device' => true, ) ); } private function buildOptionList(array $options) { assert_instances_of($options, 'PhabricatorConfigOption'); require_celerity_resource('config-options-css'); $db_values = array(); if ($options) { $db_values = id(new PhabricatorConfigEntry())->loadAllWhere( 'configKey IN (%Ls) AND namespace = %s', mpull($options, 'getKey'), 'default'); $db_values = mpull($db_values, null, 'getConfigKey'); } $engine = id(new PhabricatorMarkupEngine()) ->setViewer($this->getRequest()->getUser()); foreach ($options as $option) { $engine->addObject($option, 'summary'); } $engine->process(); $list = new PhabricatorObjectItemListView(); + $list->setStackable(); foreach ($options as $option) { $summary = $engine->getOutput($option, 'summary'); $item = id(new PhabricatorObjectItemView()) ->setHeader($option->getKey()) ->setHref('/config/edit/'.$option->getKey().'/') ->addAttribute($summary); if (!$option->getHidden() && !$option->getMasked()) { $current_value = PhabricatorEnv::getEnvConfig($option->getKey()); $current_value = PhabricatorConfigJSON::prettyPrintJSON( $current_value); $current_value = phutil_tag( 'div', array( 'class' => 'config-options-current-value', ), array( phutil_tag('span', array(), pht('Current Value:')), ' '.$current_value, )); $item->appendChild($current_value); } $db_value = idx($db_values, $option->getKey()); if ($db_value && !$db_value->getIsDeleted()) { $item->addIcon('edit', pht('Customized')); } if ($option->getHidden()) { $item->addIcon('unpublish', pht('Hidden')); } else if ($option->getMasked()) { $item->addIcon('unpublish-grey', pht('Masked')); } else if ($option->getLocked()) { $item->addIcon('lock', pht('Locked')); } $list->addItem($item); } return $list; } } diff --git a/src/applications/config/controller/PhabricatorConfigIssueListController.php b/src/applications/config/controller/PhabricatorConfigIssueListController.php index eb4c9998da..aee0f7a26e 100644 --- a/src/applications/config/controller/PhabricatorConfigIssueListController.php +++ b/src/applications/config/controller/PhabricatorConfigIssueListController.php @@ -1,66 +1,67 @@ getRequest(); $user = $request->getUser(); $nav = $this->buildSideNavView(); $nav->selectFilter('issue/'); $issues = PhabricatorSetupCheck::runAllChecks(); PhabricatorSetupCheck::setOpenSetupIssueCount(count($issues)); $list = $this->buildIssueList($issues); $list->setNoDataString(pht("There are no open setup issues.")); $header = id(new PhabricatorHeaderView()) ->setHeader(pht('Open Phabricator Setup Issues')); $nav->appendChild( array( $header, $list, )); $title = pht('Setup Issues'); $crumbs = $this ->buildApplicationCrumbs($nav) ->addCrumb( id(new PhabricatorCrumbView()) ->setName(pht('Setup')) ->setHref($this->getApplicationURI('issue/'))); $nav->setCrumbs($crumbs); return $this->buildApplicationPage( $nav, array( 'title' => $title, 'device' => true, ) ); } private function buildIssueList(array $issues) { assert_instances_of($issues, 'PhabricatorSetupIssue'); $list = new PhabricatorObjectItemListView(); + $list->setStackable(); foreach ($issues as $issue) { $href = $this->getApplicationURI('/issue/'.$issue->getIssueKey().'/'); $item = id(new PhabricatorObjectItemView()) ->setHeader($issue->getName()) ->setHref($href) ->setBarColor('yellow') ->addIcon('warning', pht('Setup Warning')) ->addAttribute($issue->getSummary()); $list->addItem($item); } return $list; } } diff --git a/src/applications/config/controller/PhabricatorConfigListController.php b/src/applications/config/controller/PhabricatorConfigListController.php index 2513633c32..1561531f42 100644 --- a/src/applications/config/controller/PhabricatorConfigListController.php +++ b/src/applications/config/controller/PhabricatorConfigListController.php @@ -1,61 +1,62 @@ getRequest(); $user = $request->getUser(); $nav = $this->buildSideNavView(); $nav->selectFilter('/'); $groups = PhabricatorApplicationConfigOptions::loadAll(); $list = $this->buildConfigOptionsList($groups); $title = pht('Phabricator Configuration'); $header = id(new PhabricatorHeaderView()) ->setHeader($title); $nav->appendChild( array( $header, $list, )); $crumbs = $this ->buildApplicationCrumbs() ->addCrumb( id(new PhabricatorCrumbView()) ->setName(pht('Config')) ->setHref($this->getApplicationURI())); $nav->setCrumbs($crumbs); return $this->buildApplicationPage( $nav, array( 'title' => $title, 'device' => true, ) ); } private function buildConfigOptionsList(array $groups) { assert_instances_of($groups, 'PhabricatorApplicationConfigOptions'); $list = new PhabricatorObjectItemListView(); + $list->setStackable(); $groups = msort($groups, 'getName'); foreach ($groups as $group) { $item = id(new PhabricatorObjectItemView()) ->setHeader($group->getName()) ->setHref('/config/group/'.$group->getKey().'/') ->addAttribute(phutil_escape_html($group->getDescription())); $list->addItem($item); } return $list; } } diff --git a/src/applications/config/option/PhabricatorMetaMTAConfigOptions.php b/src/applications/config/option/PhabricatorMetaMTAConfigOptions.php index 19437ffffe..452f1ed32f 100644 --- a/src/applications/config/option/PhabricatorMetaMTAConfigOptions.php +++ b/src/applications/config/option/PhabricatorMetaMTAConfigOptions.php @@ -1,337 +1,344 @@ deformat(pht(<<deformat(pht(<<deformat(pht(<<deformat(pht(<<deformat(pht(<<deformat(pht(<<deformat(pht(<<deformat(pht(<<deformat(pht(<<deformat(pht(<<deformat(pht(<<deformat(pht(<<deformat(pht(<<deformat(pht(<<deformat(pht(<<' - `real`: 'George Washington ' - `full`: 'gwashington (George Washington) ' The default is `full`. EODOC )); return array( $this->newOption( 'metamta.default-address', 'string', 'noreply@phabricator.example.com') ->setDescription(pht('Default "From" address.')), $this->newOption( 'metamta.domain', 'string', 'phabricator.example.com') ->setDescription(pht('Domain used to generate Message-IDs.')), $this->newOption( 'metamta.mail-adapter', 'class', 'PhabricatorMailImplementationPHPMailerLiteAdapter') ->setBaseClass('PhabricatorMailImplementationAdapter') ->setSummary(pht('Control how mail is sent.')) ->setDescription($adapter_description), $this->newOption( 'metamta.one-mail-per-recipient', 'bool', true) ->setBoolOptions( array( pht("Send Mail To Each Recipient"), pht("Send Mail To All Recipients"), )) ->setSummary( pht( 'Controls whether Phabricator sends one email with multiple '. 'recipients in the "To:" line, or multiple emails, each with a '. 'single recipient in the "To:" line.')) ->setDescription($one_mail_per_recipient_desc), $this->newOption('metamta.can-send-as-user', 'bool', false) ->setBoolOptions( array( pht("Send as User Taking Action"), pht("Send as Phabricator"), )) ->setSummary( pht( 'Controls whether Phabricator sends email "From" users.')) ->setDescription($send_as_user_desc), + $this->newOption( + 'metamta.reply-handler-domain', + 'string', + 'phabricator.example.com') + ->setDescription(pht( + 'Domain used for reply email addresses. Some applications can '. + 'configure this domain.')), $this->newOption('metamta.reply.show-hints', 'bool', true) ->setBoolOptions( array( pht("Show Reply Handler Hints"), pht("No Reply Handler Hints"), )) ->setSummary(pht('Show hints about Herald rules in email.')) ->setDescription($herald_hints_description), $this->newOption('metamta.herald.show-hints', 'bool', true) ->setBoolOptions( array( pht("Show Herald Hints"), pht("No Herald Hints"), )) ->setSummary(pht('Show hints about reply handler actions in email.')) ->setDescription($reply_hints_description), $this->newOption('metamta.recipients.show-hints', 'bool', true) ->setBoolOptions( array( pht("Show Recipient Hints"), pht("No Recipient Hints"), )) ->setSummary(pht('Show "To:" and "Cc:" footer hints in email.')) ->setDescription($recipient_hints_description), $this->newOption('metamta.precedence-bulk', 'bool', false) ->setBoolOptions( array( pht('Add "Precedence: bulk" Header'), pht('No "Precedence: bulk" Header'), )) ->setSummary(pht('Control the "Precedence: bulk" header.')) ->setDescription($bulk_description), $this->newOption('metamta.re-prefix', 'bool', false) ->setBoolOptions( array( pht('Force "Re:" Subject Prefix'), pht('No "Re:" Subject Prefix'), )) ->setSummary(pht('Control "Re:" subject prefix, for Mail.app.')) ->setDescription($re_prefix_description), $this->newOption('metamta.vary-subjects', 'bool', true) ->setBoolOptions( array( pht('Allow Varied Subjects'), pht('Always Use the Same Thread Subject'), )) ->setSummary(pht('Control subject variance, for some mail clients.')) ->setDescription($vary_subjects_description), $this->newOption('metamta.insecure-auth-with-reply-to', 'bool', false) ->setBoolOptions( array( pht('Allow Insecure Reply-To Auth'), pht('Disallow Reply-To Auth'), )) ->setSummary(pht('Trust "Reply-To" headers for authentication.')) ->setDescription($reply_to_description), $this->newOption('metamta.send-immediately', 'bool', true) ->setBoolOptions( array( pht('Send Immediately (Slow)'), pht('Send Via Daemons (Must Run Daemons)'), )) ->setSummary(pht('Improve performance by sending email via daemons.')) ->setDescription($immediately_description), $this->newOption('metamta.placeholder-to-recipient', 'string', null) ->setSummary(pht('Placeholder for mail with only CCs.')) ->setDescription($placeholder_description), $this->newOption('metamta.public-replies', 'bool', false) ->setBoolOptions( array( pht('Use Public Replies (Less Secure)'), pht('Use Private Replies (More Secure)'), )) ->setSummary( pht( 'Phabricator can use less-secure but mailing list friendly public '. 'reply addresses.')) ->setDescription($public_replies_description), $this->newOption('metamta.single-reply-handler-prefix', 'string', null) ->setSummary( pht('Allow Phabricator to use a single mailbox for all replies.')) ->setDescription($single_description), $this->newOption('metamta.user-address-format', 'enum', 'full') ->setEnumOptions( array( 'short' => 'short', 'real' => 'real', 'full' => 'full', )) ->setSummary(pht('Control how Phabricator renders user names in mail.')) ->setDescription($address_description) ->addExample('gwashington ', 'short') ->addExample('George Washington ', 'real') ->addExample( 'gwashington (George Washington) ', 'full'), ); } } diff --git a/src/applications/conpherence/config/ConpherenceConfigOptions.php b/src/applications/conpherence/config/ConpherenceConfigOptions.php new file mode 100644 index 0000000000..77d2cda2b4 --- /dev/null +++ b/src/applications/conpherence/config/ConpherenceConfigOptions.php @@ -0,0 +1,24 @@ +newOption( + 'metamta.conpherence.subject-prefix', + 'string', + '[Conpherence]') + ->setDescription(pht('Subject prefix for Conpherence mail.')), + ); + } + +} diff --git a/src/applications/conpherence/controller/ConpherenceController.php b/src/applications/conpherence/controller/ConpherenceController.php index 6c537f0006..fbe8e3cd6a 100644 --- a/src/applications/conpherence/controller/ConpherenceController.php +++ b/src/applications/conpherence/controller/ConpherenceController.php @@ -1,223 +1,222 @@ unreadConpherences = $conpherences; return $this; } public function getUnreadConpherences() { return $this->unreadConpherences; } public function setReadConpherences(array $conpherences) { assert_instances_of($conpherences, 'ConpherenceThread'); $this->readConpherences = $conpherences; return $this; } public function getReadConpherences() { return $this->readConpherences; } public function setSelectedConpherencePHID($phid) { $this->selectedConpherencePHID = $phid; return $this; } public function getSelectedConpherencePHID() { return $this->selectedConpherencePHID; } /** * Try for a full set of unread conpherences, and if we fail * load read conpherences. Additional conpherences in either category * are loaded asynchronously. */ public function loadStartingConpherences($current_selection_epoch = null) { $user = $this->getRequest()->getUser(); $read_participant_query = id(new ConpherenceParticipantQuery()) ->withParticipantPHIDs(array($user->getPHID())); $read_status = ConpherenceParticipationStatus::UP_TO_DATE; if ($current_selection_epoch) { $read_one = $read_participant_query ->withParticipationStatus($read_status) ->withDateTouched($current_selection_epoch, '>') ->execute(); $read_two = $read_participant_query ->withDateTouched($current_selection_epoch, '<=') ->execute(); $read = array_merge($read_one, $read_two); } else { $read = $read_participant_query ->withParticipationStatus($read_status) ->execute(); } $unread_status = ConpherenceParticipationStatus::BEHIND; - $unread_participant_query = id(new ConpherenceParticipantQuery()) - ->withParticipantPHIDs(array($user->getPHID())); - $unread = $unread_participant_query + $unread = id(new ConpherenceParticipantQuery()) + ->withParticipantPHIDs(array($user->getPHID())) ->withParticipationStatus($unread_status) ->execute(); $all_participation = $unread + $read; $all_conpherence_phids = array_keys($all_participation); $all_conpherences = id(new ConpherenceThreadQuery()) ->setViewer($user) ->withPHIDs($all_conpherence_phids) ->execute(); $unread_conpherences = array_select_keys( $all_conpherences, array_keys($unread) ); $this->setUnreadConpherences($unread_conpherences); $read_conpherences = array_select_keys( $all_conpherences, array_keys($read) ); $this->setReadConpherences($read_conpherences); if (!$this->getSelectedConpherencePHID()) { $this->setSelectedConpherencePHID(reset($all_conpherence_phids)); } return $this; } public function buildSideNavView($filter = null) { require_celerity_resource('conpherence-menu-css'); $unread_conpherences = $this->getUnreadConpherences(); $read_conpherences = $this->getReadConpherences(); $user = $this->getRequest()->getUser(); $menu = new PhabricatorMenuView(); $nav = AphrontSideNavFilterView::newFromMenu($menu); $nav->addClass('conpherence-menu'); $nav->setMenuID('conpherence-menu'); $nav->addFilter( 'new', pht('New Conpherence'), $this->getApplicationURI('new/') ); $nav->addLabel(pht('Unread')); $nav = $this->addConpherencesToNav($unread_conpherences, $nav); $nav->addLabel(pht('Read')); $nav = $this->addConpherencesToNav($read_conpherences, $nav, true); $nav->selectFilter($filter); return $nav; } private function addConpherencesToNav( array $conpherences, AphrontSideNavFilterView $nav, $read = false) { $user = $this->getRequest()->getUser(); foreach ($conpherences as $conpherence) { $uri = $this->getApplicationURI('view/'.$conpherence->getID().'/'); $data = $conpherence->getDisplayData($user); $title = $data['title']; $subtitle = $data['subtitle']; $unread_count = $data['unread_count']; $epoch = $data['epoch']; $image = $data['image']; $snippet = $data['snippet']; $item = id(new ConpherenceMenuItemView()) ->setUser($user) ->setTitle($title) ->setSubtitle($subtitle) ->setHref($uri) ->setEpoch($epoch) ->setImageURI($image) ->setMessageText($snippet) ->setUnreadCount($unread_count) ->setID($conpherence->getPHID()) ->addSigil('conpherence-menu-click') ->setMetadata(array('id' => $conpherence->getID())); if ($this->getSelectedConpherencePHID() == $conpherence->getPHID()) { $item->addClass('conpherence-selected'); $item->addClass('hide-unread-count'); } $nav->addCustomBlock($item->render()); } if (empty($conpherences) || $read) { $nav->addCustomBlock($this->getNoConpherencesBlock()); } return $nav; } private function getNoConpherencesBlock() { return phutil_tag( 'div', array( 'class' => 'no-conpherences-menu-item' ), pht('No more conpherences.')); } public function buildApplicationMenu() { return $this->buildSideNavView()->getMenu(); } public function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); $crumbs ->addAction( id(new PhabricatorMenuItemView()) ->setName(pht('New Conpherence')) ->setHref($this->getApplicationURI('new/')) ->setIcon('create') ) ->addCrumb( id(new PhabricatorCrumbView()) ->setName(pht('Conpherence')) ); return $crumbs; } protected function initJavelinBehaviors() { Javelin::initBehavior('conpherence-menu', array( 'base_uri' => $this->getApplicationURI(''), 'header' => 'conpherence-header-pane', 'messages' => 'conpherence-messages', 'widgets_pane' => 'conpherence-widget-pane', 'form_pane' => 'conpherence-form', 'fancy_ajax' => (bool) $this->getSelectedConpherencePHID() ) ); Javelin::initBehavior('conpherence-init', array( 'selected_conpherence_id' => $this->getSelectedConpherencePHID(), 'menu_pane' => 'conpherence-menu', 'messages_pane' => 'conpherence-message-pane', 'messages' => 'conpherence-messages', 'widgets_pane' => 'conpherence-widget-pane', 'form_pane' => 'conpherence-form' ) ); } } diff --git a/src/applications/conpherence/controller/ConpherenceListController.php b/src/applications/conpherence/controller/ConpherenceListController.php index 73f845c94c..46bae21db9 100644 --- a/src/applications/conpherence/controller/ConpherenceListController.php +++ b/src/applications/conpherence/controller/ConpherenceListController.php @@ -1,117 +1,113 @@ conpherenceID = $conpherence_id; return $this; } public function getConpherenceID() { return $this->conpherenceID; } public function willProcessRequest(array $data) { $this->setConpherenceID(idx($data, 'id')); } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $title = pht('Conpherence'); $conpherence_id = $this->getConpherenceID(); $current_selection_epoch = null; if ($conpherence_id) { $conpherence = id(new ConpherenceThreadQuery()) ->setViewer($user) ->withIDs(array($conpherence_id)) ->executeOne(); if (!$conpherence) { return new Aphront404Response(); } if ($conpherence->getTitle()) { $title = $conpherence->getTitle(); } $this->setSelectedConpherencePHID($conpherence->getPHID()); - $read_status = ConpherenceParticipationStatus::UP_TO_DATE; $participant = $conpherence->getParticipant($user->getPHID()); - $write_guard = AphrontWriteGuard::beginScopedUnguardedWrites(); - $participant->markUpToDate(); - unset($write_guard); $current_selection_epoch = $participant->getDateTouched(); } $this->loadStartingConpherences($current_selection_epoch); $nav = $this->buildSideNavView(); $main_pane = $this->renderEmptyMainPane(); $nav->appendChild( array( $main_pane, )); return $this->buildApplicationPage( $nav, array( 'title' => $title, 'device' => true, ) ); } private function renderEmptyMainPane() { $this->initJavelinBehaviors(); return phutil_tag( 'div', array( 'id' => 'conpherence-main-pane' ), array( phutil_tag( 'div', array( 'class' => 'conpherence-header-pane', 'id' => 'conpherence-header-pane', ), ''), phutil_tag( 'div', array( 'class' => 'conpherence-widget-pane', 'id' => 'conpherence-widget-pane' ), ''), phutil_tag( 'div', array( 'class' => 'conpherence-message-pane', 'id' => 'conpherence-message-pane' ), array( phutil_tag( 'div', array( 'class' => 'conpherence-messages', 'id' => 'conpherence-messages' ), ''), phutil_tag( 'div', array( 'id' => 'conpherence-form' ), ''), )), )); } } diff --git a/src/applications/conpherence/controller/ConpherenceNewController.php b/src/applications/conpherence/controller/ConpherenceNewController.php index a167304e63..ded3b75f6f 100644 --- a/src/applications/conpherence/controller/ConpherenceNewController.php +++ b/src/applications/conpherence/controller/ConpherenceNewController.php @@ -1,201 +1,201 @@ getRequest(); $user = $request->getUser(); $conpherence = id(new ConpherenceThread()) ->attachParticipants(array()) ->attachFilePHIDs(array()); $title = pht('New Conpherence'); $participants = array(); $message = ''; $files = array(); $errors = array(); $e_participants = null; $e_message = null; // this comes from ajax requests from all over. should be a single phid. $participant_prefill = $request->getStr('participant'); if ($participant_prefill) { $participants[] = $participant_prefill; } if ($request->isFormPost()) { $participants = $request->getArr('participants'); if (empty($participants)) { $e_participants = true; $errors[] = pht('You must specify participants.'); } else { $participants[] = $user->getPHID(); $participants = array_unique($participants); } $message = $request->getStr('message'); if (empty($message)) { $e_message = true; $errors[] = pht('You must write a message.'); } $file_phids = PhabricatorMarkupEngine::extractFilePHIDsFromEmbeddedFiles( array($message) ); if ($file_phids) { $files = id(new PhabricatorFileQuery()) ->setViewer($user) ->withPHIDs($file_phids) ->execute(); } if (!$errors) { $conpherence->openTransaction(); $conpherence->save(); $xactions = array(); $xactions[] = id(new ConpherenceTransaction()) ->setTransactionType(ConpherenceTransactionType::TYPE_PARTICIPANTS) ->setNewValue(array('+' => $participants)); + if ($files) { + $xactions[] = id(new ConpherenceTransaction()) + ->setTransactionType(ConpherenceTransactionType::TYPE_FILES) + ->setNewValue(array('+' => mpull($files, 'getPHID'))); + } $xactions[] = id(new ConpherenceTransaction()) ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) ->attachComment( id(new ConpherenceTransactionComment()) ->setContent($message) ->setConpherencePHID($conpherence->getPHID()) ); - if ($files) { - $xactions[] = id(new ConpherenceTransaction()) - ->setTransactionType(ConpherenceTransactionType::TYPE_FILES) - ->setNewValue(array('+' => mpull($files, 'getPHID'))); - } $content_source = PhabricatorContentSource::newForSource( PhabricatorContentSource::SOURCE_WEB, array( 'ip' => $request->getRemoteAddr() ) ); id(new ConpherenceEditor()) ->setContentSource($content_source) ->setContinueOnNoEffect(true) ->setActor($user) ->applyTransactions($conpherence, $xactions); $conpherence->saveTransaction(); if ($request->isAjax()) { $dialog = id(new AphrontDialogView()) ->setUser($user) ->setTitle('Success') ->addCancelButton('#', 'Okay') ->appendChild( phutil_tag( 'p', array(), pht('Message sent successfully.')) ); $response = id(new AphrontDialogResponse()) ->setDialog($dialog); } else { $uri = $this->getApplicationURI($conpherence->getID()); $response = id(new AphrontRedirectResponse()) ->setURI($uri); } return $response; } } $error_view = null; if ($errors) { $error_view = id(new AphrontErrorView()) ->setTitle(pht('Conpherence Errors')) ->setErrors($errors); } $participant_handles = array(); if ($participants) { $handles = id(new PhabricatorObjectHandleData($participants)) ->setViewer($user) ->loadHandles(); $participant_handles = mpull($handles, 'getFullName', 'getPHID'); } $submit_uri = $this->getApplicationURI('new/'); $cancel_uri = $this->getApplicationURI(); if ($request->isAjax()) { // TODO - we can get a better cancel_uri once we get better at crazy // ajax jonx T2086 if ($participant_prefill) { $handle = $handles[$participant_prefill]; $cancel_uri = $handle->getURI(); } $form = id(new AphrontDialogView()) ->setSubmitURI($submit_uri) ->addSubmitButton() ->setWidth(AphrontDialogView::WIDTH_FORM) ->addCancelButton($cancel_uri); } else { $form = id(new AphrontFormView()) ->setID('conpherence-message-pane') ->setAction($submit_uri); } $form ->setUser($user) ->appendChild( id(new AphrontFormTokenizerControl()) ->setName('participants') ->setValue($participant_handles) ->setUser($user) ->setDatasource('/typeahead/common/users/') ->setLabel(pht('To')) ->setError($e_participants) ) ->appendChild( id(new PhabricatorRemarkupControl()) ->setName('message') ->setValue($message) ->setLabel(pht('Message')) ->setPlaceHolder(pht('Drag and drop to include files...')) ->setError($e_message) ); if ($request->isAjax()) { $form->setTitle($title); return id(new AphrontDialogResponse()) ->setDialog($form); } $form ->appendChild( id(new AphrontFormSubmitControl()) ->setValue(pht('Submit')) ->addCancelButton($cancel_uri) ); $this->loadStartingConpherences(); $this->setSelectedConpherencePHID(null); $this->initJavelinBehaviors(); $nav = $this->buildSideNavView('new'); $header = id(new PhabricatorHeaderView()) ->setHeader($title); $nav->appendChild( array( $header, $error_view, $form, )); return $this->buildApplicationPage( $nav, array( 'title' => $title, 'device' => true, ) ); } } diff --git a/src/applications/conpherence/controller/ConpherenceUpdateController.php b/src/applications/conpherence/controller/ConpherenceUpdateController.php index baa2fc92ef..69e35a5701 100644 --- a/src/applications/conpherence/controller/ConpherenceUpdateController.php +++ b/src/applications/conpherence/controller/ConpherenceUpdateController.php @@ -1,218 +1,187 @@ conpherenceID = $conpherence_id; return $this; } public function getConpherenceID() { return $this->conpherenceID; } public function willProcessRequest(array $data) { $this->setConpherenceID(idx($data, 'id')); } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $conpherence_id = $this->getConpherenceID(); if (!$conpherence_id) { return new Aphront404Response(); } $conpherence = id(new ConpherenceThreadQuery()) ->setViewer($user) ->withIDs(array($conpherence_id)) ->executeOne(); $supported_formats = PhabricatorFile::getTransformableImageFormats(); $updated = false; $error_view = null; - $e_image = null; + $e_file = array(); $errors = array(); if ($request->isFormPost()) { $content_source = PhabricatorContentSource::newForSource( PhabricatorContentSource::SOURCE_WEB, array( 'ip' => $request->getRemoteAddr() )); + $editor = id(new ConpherenceEditor()) + ->setContentSource($content_source) + ->setActor($user); $action = $request->getStr('action'); switch ($action) { case 'message': $message = $request->getStr('text'); - $files = array(); - $file_phids = - PhabricatorMarkupEngine::extractFilePHIDsFromEmbeddedFiles( - array($message) - ); - if ($file_phids) { - $files = id(new PhabricatorFileQuery()) - ->setViewer($user) - ->withPHIDs($file_phids) - ->execute(); - } - $xactions = array(); - if ($files) { - $xactions[] = id(new ConpherenceTransaction()) - ->setTransactionType(ConpherenceTransactionType::TYPE_FILES) - ->setNewValue(array('+' => mpull($files, 'getPHID'))); - } - $xactions[] = id(new ConpherenceTransaction()) - ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) - ->attachComment( - id(new ConpherenceTransactionComment()) - ->setContent($message) - ->setConpherencePHID($conpherence->getPHID()) - ); + $xactions = $editor->generateTransactionsFromText( + $conpherence, + $message + ); $time = time(); $conpherence->openTransaction(); - $xactions = id(new ConpherenceEditor()) - ->setContentSource($content_source) - ->setActor($user) - ->applyTransactions($conpherence, $xactions); + $xactions = $editor->applyTransactions($conpherence, $xactions); $last_xaction = end($xactions); $xaction_phid = $last_xaction->getPHID(); $behind = ConpherenceParticipationStatus::BEHIND; $up_to_date = ConpherenceParticipationStatus::UP_TO_DATE; $participants = $conpherence->getParticipants(); foreach ($participants as $phid => $participant) { if ($phid != $user->getPHID()) { if ($participant->getParticipationStatus() != $behind) { $participant->setBehindTransactionPHID($xaction_phid); } $participant->setParticipationStatus($behind); $participant->setDateTouched($time); } else { $participant->setParticipationStatus($up_to_date); $participant->setDateTouched($time); } $participant->save(); } $updated = $conpherence->saveTransaction(); break; case 'metadata': $xactions = array(); - $default_image = $request->getExists('default_image'); - if ($default_image) { - $image_phid = null; - $xactions[] = id(new ConpherenceTransaction()) - ->setTransactionType(ConpherenceTransactionType::TYPE_PICTURE) - ->setNewValue($image_phid); - } else if (!empty($_FILES['image'])) { - $err = idx($_FILES['image'], 'error'); - if ($err != UPLOAD_ERR_NO_FILE) { - $file = PhabricatorFile::newFromPHPUpload( - $_FILES['image'], - array( - 'authorPHID' => $user->getPHID(), - )); - $okay = $file->isTransformableImage(); - if ($okay) { - $xformer = new PhabricatorImageTransformer(); - $xformed = $xformer->executeThumbTransform( - $file, - $x = 50, - $y = 50); - $image_phid = $xformed->getPHID(); - $xactions[] = id(new ConpherenceTransaction()) - ->setTransactionType(ConpherenceTransactionType::TYPE_PICTURE) - ->setNewValue($image_phid); - } else { - $e_image = pht('Not Supported'); - $errors[] = - pht('This server only supports these image formats: %s.', + $images = $request->getArr('image'); + if ($images) { + // just take the first one + $file_phid = reset($images); + $file = id(new PhabricatorFileQuery()) + ->setViewer($user) + ->withPHIDs(array($file_phid)) + ->executeOne(); + $okay = $file->isTransformableImage(); + if ($okay) { + $xformer = new PhabricatorImageTransformer(); + $xformed = $xformer->executeThumbTransform( + $file, + $x = 50, + $y = 50); + $image_phid = $xformed->getPHID(); + $xactions[] = id(new ConpherenceTransaction()) + ->setTransactionType(ConpherenceTransactionType::TYPE_PICTURE) + ->setNewValue($image_phid); + } else { + $e_file[] = $file; + $errors[] = + pht('This server only supports these image formats: %s.', implode(', ', $supported_formats)); - } } } $title = $request->getStr('title'); if ($title != $conpherence->getTitle()) { $xactions[] = id(new ConpherenceTransaction()) ->setTransactionType(ConpherenceTransactionType::TYPE_TITLE) ->setNewValue($title); } if ($xactions) { $conpherence->openTransaction(); - $xactions = id(new ConpherenceEditor()) - ->setContentSource($content_source) - ->setActor($user) + $xactions = $editor ->setContinueOnNoEffect(true) ->applyTransactions($conpherence, $xactions); $updated = $conpherence->saveTransaction(); } else if (empty($errors)) { $errors[] = pht( 'That was a non-update. Try cancel.' ); } break; default: throw new Exception('Unknown action: '.$action); break; } } if ($updated) { return id(new AphrontRedirectResponse())->setURI( $this->getApplicationURI($conpherence_id.'/') ); } if ($errors) { $error_view = id(new AphrontErrorView()) ->setTitle(pht('Errors editing conpherence.')) + ->setInsideDialogue(true) ->setErrors($errors); } $form = id(new AphrontFormLayoutView()) ->appendChild( id(new AphrontFormTextControl()) ->setLabel(pht('Title')) ->setName('title') ->setValue($conpherence->getTitle()) ) ->appendChild( id(new AphrontFormMarkupControl()) ->setLabel(pht('Image')) ->setValue(phutil_tag( 'img', array( 'src' => $conpherence->loadImageURI(), )) ) ) ->appendChild( - id(new AphrontFormImageControl()) + id(new AphrontFormDragAndDropUploadControl()) ->setLabel(pht('Change Image')) ->setName('image') + ->setValue($e_file) ->setCaption('Supported formats: '.implode(', ', $supported_formats)) - ->setError($e_image) - ); + ); - // TODO -- fix javelin so we can upload files from a workflow require_celerity_resource('conpherence-update-css'); - return $this->buildStandardPageResponse( - array( - $error_view, + return id(new AphrontDialogResponse()) + ->setDialog( id(new AphrontDialogView()) ->setUser($user) ->setTitle(pht('Update Conpherence')) ->setWidth(AphrontDialogView::WIDTH_FORM) ->setSubmitURI($this->getApplicationURI('update/'.$conpherence_id.'/')) ->addHiddenInput('action', 'metadata') + ->appendChild($error_view) ->appendChild($form) ->addSubmitButton() - ->addCancelButton($this->getApplicationURI($conpherence->getID().'/')), - ), - array() - ); + ->addCancelButton($this->getApplicationURI($conpherence->getID().'/')) + ); } } diff --git a/src/applications/conpherence/controller/ConpherenceViewController.php b/src/applications/conpherence/controller/ConpherenceViewController.php index a36e1ab766..9f1b37bd15 100644 --- a/src/applications/conpherence/controller/ConpherenceViewController.php +++ b/src/applications/conpherence/controller/ConpherenceViewController.php @@ -1,295 +1,301 @@ conpherence = $conpherence; return $this; } public function getConpherence() { return $this->conpherence; } public function setConpherenceID($conpherence_id) { $this->conpherenceID = $conpherence_id; return $this; } public function getConpherenceID() { return $this->conpherenceID; } public function willProcessRequest(array $data) { $this->setConpherenceID(idx($data, 'id')); } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $conpherence_id = $this->getConpherenceID(); if (!$conpherence_id) { return new Aphront404Response(); } if (!$request->isAjax()) { return id(new AphrontRedirectResponse()) ->setURI($this->getApplicationURI($conpherence_id.'/')); } $conpherence = id(new ConpherenceThreadQuery()) ->setViewer($user) ->withIDs(array($conpherence_id)) ->needWidgetData(true) ->executeOne(); $this->setConpherence($conpherence); $participant = $conpherence->getParticipant($user->getPHID()); + $transactions = $conpherence->getTransactions(); + $latest_transaction = end($transactions); $write_guard = AphrontWriteGuard::beginScopedUnguardedWrites(); - $participant->markUpToDate(); + $participant->markUpToDate($latest_transaction); unset($write_guard); $header = $this->renderHeaderPaneContent(); $messages = $this->renderMessagePaneContent(); $widgets = $this->renderWidgetPaneContent(); $content = $header + $widgets + $messages; return id(new AphrontAjaxResponse())->setContent($content); } private function renderHeaderPaneContent() { require_celerity_resource('conpherence-header-pane-css'); $user = $this->getRequest()->getUser(); $conpherence = $this->getConpherence(); $display_data = $conpherence->getDisplayData($user); $edit_href = $this->getApplicationURI('update/'.$conpherence->getID().'/'); $header = - phutil_render_tag( + javelin_render_tag( 'a', array( 'class' => 'edit', 'href' => $edit_href, + 'sigil' => 'workflow', ), - pht('edit...') + '' ). phutil_render_tag( 'div', array( 'class' => 'header-image', 'style' => 'background-image: url('.$display_data['image'].');' ), '' ). phutil_render_tag( 'div', array( 'class' => 'title', ), phutil_escape_html($display_data['title']) ). phutil_render_tag( 'div', array( 'class' => 'subtitle', ), phutil_escape_html($display_data['subtitle']) ); return array('header' => $header); } private function renderMessagePaneContent() { require_celerity_resource('conpherence-message-pane-css'); $user = $this->getRequest()->getUser(); $conpherence = $this->getConpherence(); $handles = $conpherence->getHandles(); $rendered_transactions = array(); $transactions = $conpherence->getTransactions(); foreach ($transactions as $transaction) { + if ($transaction->shouldHide()) { + continue; + } $rendered_transactions[] = id(new ConpherenceTransactionView()) ->setUser($user) ->setConpherenceTransaction($transaction) ->setHandles($handles) ->render(); } $transactions = implode(' ', $rendered_transactions); $form = id(new AphrontFormView()) ->setAction($this->getApplicationURI('update/'.$conpherence->getID().'/')) ->setFlexible(true) ->setUser($user) ->addHiddenInput('action', 'message') ->appendChild( id(new PhabricatorRemarkupControl()) ->setUser($user) ->setName('text') ) ->appendChild( id(new AphrontFormSubmitControl()) ->setValue(pht('Pontificate')) )->render(); return array( 'messages' => $transactions, 'form' => $form ); } private function renderWidgetPaneContent() { require_celerity_resource('conpherence-widget-pane-css'); Javelin::initBehavior( 'conpherence-widget-pane', array( 'widgetRegistery' => array( 'widgets-files' => 1, 'widgets-tasks' => 1, 'widgets-calendar' => 1, ) ) ); $conpherence = $this->getConpherence(); $widgets = phutil_render_tag( 'div', array( 'class' => 'widgets-header' ), array( javelin_tag( 'a', array( 'sigil' => 'conpherence-change-widget', 'meta' => array('widget' => 'widgets-files') ), pht('Files') ), ' | ', javelin_tag( 'a', array( 'sigil' => 'conpherence-change-widget', 'meta' => array('widget' => 'widgets-tasks') ), pht('Tasks') ), ' | ', javelin_tag( 'a', array( 'sigil' => 'conpherence-change-widget', 'meta' => array('widget' => 'widgets-calendar') ), pht('Calendar') ), ) ). phutil_render_tag( 'div', array( 'class' => 'widgets-body', 'id' => 'widgets-files', 'style' => 'display: none;' ), $this->renderFilesWidgetPaneContent() ). phutil_render_tag( 'div', array( 'class' => 'widgets-body', 'id' => 'widgets-tasks', ), $this->renderTaskWidgetPaneContent() ). phutil_render_tag( 'div', array( 'class' => 'widgets-body', 'id' => 'widgets-calendar', 'style' => 'display: none;' ), $this->renderCalendarWidgetPaneContent() ); return array('widgets' => $widgets); } private function renderFilesWidgetPaneContent() { $conpherence = $this->getConpherence(); $widget_data = $conpherence->getWidgetData(); $files = $widget_data['files']; $table_data = array(); foreach ($files as $file) { $thumb = $file->getThumb60x45URI(); $table_data[] = array( phutil_render_tag( 'img', array( 'src' => $thumb ), '' ), $file->getName() ); } $header = id(new PhabricatorHeaderView()) ->setHeader(pht('Attached Files')); $table = id(new AphrontTableView($table_data)) ->setNoDataString(pht('No files attached to conpherence.')) ->setHeaders(array('', pht('Name'))) ->setColumnClasses(array('', 'wide')); return $header->render() . $table->render(); } private function renderTaskWidgetPaneContent() { $conpherence = $this->getConpherence(); $widget_data = $conpherence->getWidgetData(); $tasks = $widget_data['tasks']; $priority_map = ManiphestTaskPriority::getTaskPriorityMap(); $handles = $conpherence->getHandles(); $content = array(); foreach ($tasks as $owner_phid => $actual_tasks) { $handle = $handles[$owner_phid]; $content[] = id(new PhabricatorHeaderView()) ->setHeader($handle->getName()) ->render(); $actual_tasks = msort($actual_tasks, 'getPriority'); $actual_tasks = array_reverse($actual_tasks); $data = array(); foreach ($actual_tasks as $task) { $data[] = array( idx($priority_map, $task->getPriority(), pht('???')), phutil_render_tag( 'a', array( 'href' => '/T'.$task->getID() ), phutil_escape_html($task->getTitle()) ) ); } $table = id(new AphrontTableView($data)) ->setNoDataString(pht('No open tasks.')) ->setHeaders(array(pht('Pri'), pht('Title'))) ->setColumnClasses(array('', 'wide')); $content[] = $table->render(); } return implode('', $content); } private function renderCalendarWidgetPaneContent() { $header = id(new PhabricatorHeaderView()) ->setHeader(pht('Calendar')); return $header->render() . 'TODO'; } } diff --git a/src/applications/conpherence/editor/ConpherenceEditor.php b/src/applications/conpherence/editor/ConpherenceEditor.php index 93344d2215..9304e0f14e 100644 --- a/src/applications/conpherence/editor/ConpherenceEditor.php +++ b/src/applications/conpherence/editor/ConpherenceEditor.php @@ -1,175 +1,217 @@ getFilePHIDs(); + $file_phids = array_diff($file_phids, $existing_file_phids); + if ($file_phids) { + $files = id(new PhabricatorFileQuery()) + ->setViewer($this->getActor()) + ->withPHIDs($file_phids) + ->execute(); + } + $xactions = array(); + if ($files) { + $xactions[] = id(new ConpherenceTransaction()) + ->setTransactionType(ConpherenceTransactionType::TYPE_FILES) + ->setNewValue(array('+' => mpull($files, 'getPHID'))); + } + $xactions[] = id(new ConpherenceTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) + ->attachComment( + id(new ConpherenceTransactionComment()) + ->setContent($text) + ->setConpherencePHID($conpherence->getPHID()) + ); + return $xactions; + } + public function getTransactionTypes() { $types = parent::getTransactionTypes(); $types[] = PhabricatorTransactions::TYPE_COMMENT; $types[] = ConpherenceTransactionType::TYPE_TITLE; $types[] = ConpherenceTransactionType::TYPE_PICTURE; $types[] = ConpherenceTransactionType::TYPE_PARTICIPANTS; $types[] = ConpherenceTransactionType::TYPE_FILES; return $types; } protected function getCustomTransactionOldValue( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case ConpherenceTransactionType::TYPE_TITLE: return $object->getTitle(); case ConpherenceTransactionType::TYPE_PICTURE: return $object->getImagePHID(); case ConpherenceTransactionType::TYPE_PARTICIPANTS: return $object->getParticipantPHIDs(); case ConpherenceTransactionType::TYPE_FILES: return $object->getFilePHIDs(); } } protected function getCustomTransactionNewValue( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case ConpherenceTransactionType::TYPE_TITLE: case ConpherenceTransactionType::TYPE_PICTURE: return $xaction->getNewValue(); case ConpherenceTransactionType::TYPE_PARTICIPANTS: case ConpherenceTransactionType::TYPE_FILES: return $this->getPHIDTransactionNewValue($xaction); } } protected function applyCustomInternalTransaction( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case ConpherenceTransactionType::TYPE_TITLE: $object->setTitle($xaction->getNewValue()); break; case ConpherenceTransactionType::TYPE_PICTURE: $object->setImagePHID($xaction->getNewValue()); break; } } /** * For now this only supports adding more files and participants. */ protected function applyCustomExternalTransaction( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case ConpherenceTransactionType::TYPE_FILES: $editor = id(new PhabricatorEdgeEditor()) ->setActor($this->getActor()); $edge_type = PhabricatorEdgeConfig::TYPE_OBJECT_HAS_FILE; foreach ($xaction->getNewValue() as $file_phid) { $editor->addEdge( $object->getPHID(), $edge_type, $file_phid ); } $editor->save(); break; case ConpherenceTransactionType::TYPE_PARTICIPANTS: foreach ($xaction->getNewValue() as $participant) { if ($participant == $this->getActor()->getPHID()) { $status = ConpherenceParticipationStatus::UP_TO_DATE; } else { $status = ConpherenceParticipationStatus::BEHIND; } id(new ConpherenceParticipant()) ->setConpherencePHID($object->getPHID()) ->setParticipantPHID($participant) ->setParticipationStatus($status) ->setDateTouched(time()) ->setBehindTransactionPHID($xaction->getPHID()) ->save(); } break; } } protected function mergeTransactions( PhabricatorApplicationTransaction $u, PhabricatorApplicationTransaction $v) { $type = $u->getTransactionType(); switch ($type) { case ConpherenceTransactionType::TYPE_TITLE: case ConpherenceTransactionType::TYPE_PICTURE: return $v; case ConpherenceTransactionType::TYPE_FILES: case ConpherenceTransactionType::TYPE_PARTICIPANTS: return $this->mergePHIDTransactions($u, $v); } return parent::mergeTransactions($u, $v); } protected function supportsMail() { - return false; + return true; } - /* TODO - protected function buildReplyHandler(PhabricatorLiskDAO $object) { return id(new ConpherenceReplyHandler()) + ->setActor($this->getActor()) ->setMailReceiver($object); } protected function buildMailTemplate(PhabricatorLiskDAO $object) { $id = $object->getID(); $title = $object->getTitle(); + if (!$title) { + $title = pht( + '%s sent you a message.', + $this->getActor()->getUserName() + ); + } $phid = $object->getPHID(); - $original_name = $object->getOriginalName(); return id(new PhabricatorMetaMTAMail()) - ->setSubject("C{$id}: {$title}") - ->addHeader('Thread-Topic', "C{$id}: {$phid}"); + ->setSubject("E{$id}: {$title}") + ->addHeader('Thread-Topic', "E{$id}: {$phid}"); } protected function getMailTo(PhabricatorLiskDAO $object) { $participants = $object->getParticipants(); - $participants[$this->requireActor()->getPHID()] = true; return array_keys($participants); } + protected function getMailCC(PhabricatorLiskDAO $object) { + return array(); + } + protected function buildMailBody( PhabricatorLiskDAO $object, array $xactions) { $body = parent::buildMailBody($object, $xactions); $body->addTextSection( pht('CONPHERENCE DETAIL'), PhabricatorEnv::getProductionURI('/conpherence/'.$object->getID().'/')); return $body; } protected function getMailSubjectPrefix() { return PhabricatorEnv::getEnvConfig('metamta.conpherence.subject-prefix'); } - */ protected function supportsFeed() { return false; } protected function supportsSearch() { return false; } } diff --git a/src/applications/conpherence/mail/ConpherenceReplyHandler.php b/src/applications/conpherence/mail/ConpherenceReplyHandler.php new file mode 100644 index 0000000000..f7de36cb25 --- /dev/null +++ b/src/applications/conpherence/mail/ConpherenceReplyHandler.php @@ -0,0 +1,80 @@ +getDefaultPrivateReplyHandlerEmailAddress($handle, 'E'); + } + + public function getPublicReplyHandlerEmailAddress() { + return $this->getDefaultPublicReplyHandlerEmailAddress('E'); + } + + public function getReplyHandlerInstructions() { + if ($this->supportsReplies()) { + return pht('Reply to comment and attach files.'); + } else { + return null; + } + } + + protected function receiveEmail(PhabricatorMetaMTAReceivedMail $mail) { + $conpherence = $this->getMailReceiver(); + $user = $this->getActor(); + if (!$conpherence->getPHID()) { + $conpherence + ->attachParticipants(array()) + ->attachFilePHIDs(array()); + } else { + $edge_type = PhabricatorEdgeConfig::TYPE_OBJECT_HAS_FILE; + $file_phids = PhabricatorEdgeQuery::loadDestinationPHIDs( + $conpherence->getPHID(), + $edge_type + ); + $conpherence->attachFilePHIDs($file_phids); + $participants = id(new ConpherenceParticipant()) + ->loadAllWhere('conpherencePHID = %s', $conpherence->getPHID()); + $participants = mpull($participants, null, 'getParticipantPHID'); + $conpherence->attachParticipants($participants); + } + + $content_source = PhabricatorContentSource::newForSource( + PhabricatorContentSource::SOURCE_EMAIL, + array( + 'id' => $mail->getID(), + )); + + $editor = id(new ConpherenceEditor()) + ->setActor($user) + ->setContentSource($content_source) + ->setParentMessageID($mail->getMessageID()); + + $body = $mail->getCleanTextBody(); + $body = trim($body); + $file_phids = $mail->getAttachments(); + $body = $this->enhanceBodyWithAttachments( + $body, + $file_phids, + '{F%d}' + ); + $xactions = $editor->generateTransactionsFromText( + $conpherence, + $body + ); + + $editor->applyTransactions($conpherence, $xactions); + + return null; + } + +} diff --git a/src/applications/conpherence/storage/ConpherenceParticipant.php b/src/applications/conpherence/storage/ConpherenceParticipant.php index e21d6204ad..be897c11fe 100644 --- a/src/applications/conpherence/storage/ConpherenceParticipant.php +++ b/src/applications/conpherence/storage/ConpherenceParticipant.php @@ -1,27 +1,28 @@ isUpToDate()) { $this->setParticipationStatus(ConpherenceParticipationStatus::UP_TO_DATE); + $this->setBehindTransactionPHID($xaction->getPHID()); $this->save(); } return $this; } public function isUpToDate() { return $this->getParticipationStatus() == ConpherenceParticipationStatus::UP_TO_DATE; } } diff --git a/src/applications/conpherence/storage/ConpherenceThread.php b/src/applications/conpherence/storage/ConpherenceThread.php index c5c2c4723a..1b80aec1a5 100644 --- a/src/applications/conpherence/storage/ConpherenceThread.php +++ b/src/applications/conpherence/storage/ConpherenceThread.php @@ -1,237 +1,240 @@ true, ) + parent::getConfiguration(); } public function generatePHID() { return PhabricatorPHID::generateNewPHID( PhabricatorPHIDConstants::PHID_TYPE_CONP); } public function save() { if (!$this->getMailKey()) { $this->setMailKey(Filesystem::readRandomCharacters(20)); } return parent::save(); } public function attachParticipants(array $participants) { assert_instances_of($participants, 'ConpherenceParticipant'); $this->participants = $participants; return $this; } public function getParticipants() { if ($this->participants === null) { throw new Exception( 'You must attachParticipants first!' ); } return $this->participants; } public function getParticipant($phid) { $participants = $this->getParticipants(); return $participants[$phid]; } public function getParticipantPHIDs() { $participants = $this->getParticipants(); return array_keys($participants); } public function attachHandles(array $handles) { assert_instances_of($handles, 'PhabricatorObjectHandle'); $this->handles = $handles; return $this; } public function getHandles() { if ($this->handles === null) { throw new Exception( 'You must attachHandles first!' ); } return $this->handles; } public function attachTransactions(array $transactions) { assert_instances_of($transactions, 'ConpherenceTransaction'); $this->transactions = $transactions; return $this; } public function getTransactions() { if ($this->transactions === null) { throw new Exception( 'You must attachTransactions first!' ); } return $this->transactions; } public function attachFilePHIDs(array $file_phids) { $this->filePHIDs = $file_phids; return $this; } public function getFilePHIDs() { if ($this->filePHIDs === null) { throw new Exception( 'You must attachFilePHIDs first!' ); } return $this->filePHIDs; } public function attachWidgetData(array $widget_data) { $this->widgetData = $widget_data; return $this; } public function getWidgetData() { if ($this->widgetData === null) { throw new Exception( 'You must attachWidgetData first!' ); } return $this->widgetData; } public function loadImageURI() { $src_phid = $this->getImagePHID(); if ($src_phid) { $file = id(new PhabricatorFile())->loadOneWhere('phid = %s', $src_phid); if ($file) { return $file->getBestURI(); } } return PhabricatorUser::getDefaultProfileImageURI(); } public function getDisplayData(PhabricatorUser $user) { $transactions = $this->getTransactions(); $latest_transaction = end($transactions); $latest_participant = $latest_transaction->getAuthorPHID(); $handles = $this->getHandles(); $latest_handle = $handles[$latest_participant]; if ($this->getImagePHID()) { $img_src = $this->loadImageURI(); } else { $img_src = $latest_handle->getImageURI(); } $title = $this->getTitle(); if (!$title) { $title = $latest_handle->getName(); unset($handles[$latest_participant]); } unset($handles[$user->getPHID()]); $subtitle = ''; $count = 0; $final = false; foreach ($handles as $handle) { if ($handle->getType() != PhabricatorPHIDConstants::PHID_TYPE_USER) { continue; } if ($subtitle) { if ($final) { $subtitle .= '...'; break; } else { $subtitle .= ', '; } } $subtitle .= $handle->getName(); $count++; $final = $count == 3; } $participants = $this->getParticipants(); $user_participation = $participants[$user->getPHID()]; $unread_count = 0; $max_count = 10; $snippet = null; if (!$user_participation->isUpToDate()) { $behind_transaction_phid = $user_participation->getBehindTransactionPHID(); } else { $behind_transaction_phid = null; } foreach (array_reverse($transactions) as $transaction) { switch ($transaction->getTransactionType()) { case ConpherenceTransactionType::TYPE_PARTICIPANTS: case ConpherenceTransactionType::TYPE_TITLE: case ConpherenceTransactionType::TYPE_PICTURE: continue 2; case PhabricatorTransactions::TYPE_COMMENT: if ($snippet === null) { $snippet = phutil_utf8_shorten( $transaction->getComment()->getContent(), 48 ); } // fallthrough intentionally here case ConpherenceTransactionType::TYPE_FILES: - default: - if ($behind_transaction_phid && - $transaction->getPHID() != $behind_transaction_phid) { - $unread_count++; + if ($behind_transaction_phid) { + $unread_count++; + if ($transaction->getPHID() == $behind_transaction_phid) { + break 2; } + } if ($unread_count > $max_count) { break 2; } break; + default: + continue 2; } if ($snippet && !$behind_transaction_phid) { break; } } if ($unread_count > $max_count) { $unread_count = $max_count.'+'; } return array( 'title' => $title, 'subtitle' => $subtitle, 'unread_count' => $unread_count, 'epoch' => $latest_transaction->getDateCreated(), 'image' => $img_src, 'snippet' => $snippet, ); } /* -( PhabricatorPolicyInterface Implementation )-------------------------- */ public function getCapabilities() { return array( PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT, ); } public function getPolicy($capability) { return PhabricatorPolicies::POLICY_NOONE; } public function hasAutomaticCapability($capability, PhabricatorUser $user) { $participants = $this->getParticipants(); return isset($participants[$user->getPHID()]); } } diff --git a/src/applications/conpherence/storage/ConpherenceTransaction.php b/src/applications/conpherence/storage/ConpherenceTransaction.php index c75ee7cd1f..9b242275c6 100644 --- a/src/applications/conpherence/storage/ConpherenceTransaction.php +++ b/src/applications/conpherence/storage/ConpherenceTransaction.php @@ -1,124 +1,125 @@ getOldValue(); switch ($this->getTransactionType()) { case ConpherenceTransactionType::TYPE_PARTICIPANTS: return ($old === null); case ConpherenceTransactionType::TYPE_TITLE: case ConpherenceTransactionType::TYPE_PICTURE: - case ConpherenceTransactionType::TYPE_FILES: return false; + case ConpherenceTransactionType::TYPE_FILES: + return true; } return parent::shouldHide(); } public function getTitle() { $author_phid = $this->getAuthorPHID(); $old = $this->getOldValue(); $new = $this->getNewValue(); switch ($this->getTransactionType()) { case ConpherenceTransactionType::TYPE_TITLE: if ($old) { $title = pht( '%s renamed this conpherence from "%s" to "%s".', $this->renderHandleLink($author_phid), phutil_escape_html($old), phutil_escape_html($new)); } else { $title = pht( '%s named this conpherence "%s".', $this->renderHandleLink($author_phid), phutil_escape_html($new)); } return $title; case ConpherenceTransactionType::TYPE_FILES: return pht( '%s updated the conpherence files.', $this->renderHandleLink($author_phid)); case ConpherenceTransactionType::TYPE_PICTURE: return pht( '%s updated the conpherence image.', $this->renderHandleLink($author_phid)); case ConpherenceTransactionType::TYPE_PARTICIPANTS: $add = array_diff($new, $old); $rem = array_diff($old, $new); if ($add && $rem) { $title = pht( '%s edited participant(s), added %d: %s; removed %d: %s.', $this->renderHandleLink($author_phid), count($add), $this->renderHandleList($add), count($rem), $this->renderHandleList($rem)); } else if ($add) { $title = pht( '%s added %d participant(s): %s.', $this->renderHandleLink($author_phid), count($add), $this->renderHandleList($add)); } else { $title = pht( '%s removed %d partipant(s): %s.', $this->renderHandleLink($author_phid), count($rem), $this->renderHandleList($rem)); } return $title; break; } return parent::getTitle(); } public function getRequiredHandlePHIDs() { $phids = parent::getRequiredHandlePHIDs(); $old = $this->getOldValue(); $new = $this->getNewValue(); $phids[] = $this->getAuthorPHID(); switch ($this->getTransactionType()) { case ConpherenceTransactionType::TYPE_PICTURE: $phids[] = $new; break; case ConpherenceTransactionType::TYPE_TITLE: break; case ConpherenceTransactionType::TYPE_PARTICIPANTS: case ConpherenceTransactionType::TYPE_FILES: $phids = array_merge($phids, $this->getOldValue()); $phids = array_merge($phids, $this->getNewValue()); break; } return $phids; } } diff --git a/src/applications/differential/editor/DifferentialCommentEditor.php b/src/applications/differential/editor/DifferentialCommentEditor.php index 386a0d9e22..8054b791c5 100644 --- a/src/applications/differential/editor/DifferentialCommentEditor.php +++ b/src/applications/differential/editor/DifferentialCommentEditor.php @@ -1,688 +1,688 @@ revision = $revision; $this->action = $action; } public function setParentMessageID($parent_message_id) { $this->parentMessageID = $parent_message_id; return $this; } public function setMessage($message) { $this->message = $message; return $this; } public function setAttachInlineComments($attach) { $this->attachInlineComments = $attach; return $this; } public function setChangedByCommit($changed_by_commit) { $this->changedByCommit = $changed_by_commit; return $this; } public function getChangedByCommit() { return $this->changedByCommit; } public function setAddedReviewers(array $added_reviewers) { $this->addedReviewers = $added_reviewers; return $this; } public function getAddedReviewers() { return $this->addedReviewers; } public function setRemovedReviewers(array $removeded_reviewers) { $this->removedReviewers = $removeded_reviewers; return $this; } public function getRemovedReviewers() { return $this->removedReviewers; } public function setAddedCCs($added_ccs) { $this->addedCCs = $added_ccs; return $this; } public function getAddedCCs() { return $this->addedCCs; } public function setContentSource(PhabricatorContentSource $content_source) { $this->contentSource = $content_source; return $this; } public function setIsDaemonWorkflow($is_daemon) { $this->isDaemonWorkflow = $is_daemon; return $this; } public function setNoEmail($no_email) { $this->noEmail = $no_email; return $this; } public function save() { $actor = $this->requireActor(); $revision = $this->revision; $action = $this->action; $actor_phid = $actor->getPHID(); $actor_is_author = ($actor_phid == $revision->getAuthorPHID()); $allow_self_accept = PhabricatorEnv::getEnvConfig( 'differential.allow-self-accept'); $always_allow_close = PhabricatorEnv::getEnvConfig( 'differential.always-allow-close'); $allow_reopen = PhabricatorEnv::getEnvConfig( 'differential.allow-reopen'); $revision_status = $revision->getStatus(); $revision->loadRelationships(); $reviewer_phids = $revision->getReviewers(); if ($reviewer_phids) { - $reviewer_phids = array_combine($reviewer_phids, $reviewer_phids); + $reviewer_phids = array_fuse($reviewer_phids); } $metadata = array(); $inline_comments = array(); if ($this->attachInlineComments) { $inline_comments = id(new DifferentialInlineComment())->loadAllWhere( 'authorPHID = %s AND revisionID = %d AND commentID IS NULL', $actor_phid, $revision->getID()); } switch ($action) { case DifferentialAction::ACTION_COMMENT: if (!$this->message && !$inline_comments) { throw new DifferentialActionHasNoEffectException( "You are submitting an empty comment with no action: ". "you must act on the revision or post a comment."); } break; case DifferentialAction::ACTION_RESIGN: if ($actor_is_author) { throw new Exception('You can not resign from your own revision!'); } if (empty($reviewer_phids[$actor_phid])) { throw new DifferentialActionHasNoEffectException( "You can not resign from this revision because you are not ". "a reviewer."); } DifferentialRevisionEditor::alterReviewers( $revision, $reviewer_phids, $rem = array($actor_phid), $add = array(), $actor_phid); break; case DifferentialAction::ACTION_ABANDON: if (!$actor_is_author) { throw new Exception('You can only abandon your own revisions.'); } if ($revision_status == ArcanistDifferentialRevisionStatus::CLOSED) { throw new DifferentialActionHasNoEffectException( "You can not abandon this revision because it has already ". "been closed."); } if ($revision_status == ArcanistDifferentialRevisionStatus::ABANDONED) { throw new DifferentialActionHasNoEffectException( "You can not abandon this revision because it has already ". "been abandoned."); } $revision->setStatus(ArcanistDifferentialRevisionStatus::ABANDONED); break; case DifferentialAction::ACTION_ACCEPT: if ($actor_is_author && !$allow_self_accept) { throw new Exception('You can not accept your own revision.'); } if (($revision_status != ArcanistDifferentialRevisionStatus::NEEDS_REVIEW) && ($revision_status != ArcanistDifferentialRevisionStatus::NEEDS_REVISION)) { switch ($revision_status) { case ArcanistDifferentialRevisionStatus::ACCEPTED: throw new DifferentialActionHasNoEffectException( "You can not accept this revision because someone else ". "already accepted it."); case ArcanistDifferentialRevisionStatus::ABANDONED: throw new DifferentialActionHasNoEffectException( "You can not accept this revision because it has been ". "abandoned."); case ArcanistDifferentialRevisionStatus::CLOSED: throw new DifferentialActionHasNoEffectException( "You can not accept this revision because it has already ". "been closed."); default: throw new Exception( "Unexpected revision state '{$revision_status}'!"); } } $revision ->setStatus(ArcanistDifferentialRevisionStatus::ACCEPTED); if (!isset($reviewer_phids[$actor_phid])) { DifferentialRevisionEditor::alterReviewers( $revision, $reviewer_phids, $rem = array(), $add = array($actor_phid), $actor_phid); } break; case DifferentialAction::ACTION_REQUEST: if (!$actor_is_author) { throw new Exception('You must own a revision to request review.'); } switch ($revision_status) { case ArcanistDifferentialRevisionStatus::ACCEPTED: case ArcanistDifferentialRevisionStatus::NEEDS_REVISION: $revision->setStatus( ArcanistDifferentialRevisionStatus::NEEDS_REVIEW); break; case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW: throw new DifferentialActionHasNoEffectException( "You can not request review of this revision because it has ". "been abandoned."); case ArcanistDifferentialRevisionStatus::ABANDONED: throw new DifferentialActionHasNoEffectException( "You can not request review of this revision because it has ". "been abandoned."); case ArcanistDifferentialRevisionStatus::CLOSED: throw new DifferentialActionHasNoEffectException( "You can not request review of this revision because it has ". "already been closed."); default: throw new Exception( "Unexpected revision state '{$revision_status}'!"); } list($added_reviewers, $ignored) = $this->alterReviewers(); if ($added_reviewers) { $key = DifferentialComment::METADATA_ADDED_REVIEWERS; $metadata[$key] = $added_reviewers; } break; case DifferentialAction::ACTION_REJECT: if ($actor_is_author) { throw new Exception( 'You can not request changes to your own revision.'); } switch ($revision_status) { case ArcanistDifferentialRevisionStatus::ACCEPTED: case ArcanistDifferentialRevisionStatus::NEEDS_REVISION: case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW: // NOTE: We allow you to reject an already-rejected revision // because it doesn't create any ambiguity and avoids a rather // needless dialog. break; case ArcanistDifferentialRevisionStatus::ABANDONED: throw new DifferentialActionHasNoEffectException( "You can not request changes to this revision because it has ". "been abandoned."); case ArcanistDifferentialRevisionStatus::CLOSED: throw new DifferentialActionHasNoEffectException( "You can not request changes to this revision because it has ". "already been closed."); default: throw new Exception( "Unexpected revision state '{$revision_status}'!"); } if (!isset($reviewer_phids[$actor_phid])) { DifferentialRevisionEditor::alterReviewers( $revision, $reviewer_phids, $rem = array(), $add = array($actor_phid), $actor_phid); } $revision ->setStatus(ArcanistDifferentialRevisionStatus::NEEDS_REVISION); break; case DifferentialAction::ACTION_RETHINK: if (!$actor_is_author) { throw new Exception( "You can not plan changes to somebody else's revision"); } switch ($revision_status) { case ArcanistDifferentialRevisionStatus::ACCEPTED: case ArcanistDifferentialRevisionStatus::NEEDS_REVISION: case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW: break; case ArcanistDifferentialRevisionStatus::ABANDONED: throw new DifferentialActionHasNoEffectException( "You can not plan changes to this revision because it has ". "been abandoned."); case ArcanistDifferentialRevisionStatus::CLOSED: throw new DifferentialActionHasNoEffectException( "You can not plan changes to this revision because it has ". "already been closed."); default: throw new Exception( "Unexpected revision state '{$revision_status}'!"); } $revision ->setStatus(ArcanistDifferentialRevisionStatus::NEEDS_REVISION); break; case DifferentialAction::ACTION_RECLAIM: if (!$actor_is_author) { throw new Exception('You can not reclaim a revision you do not own.'); } if ($revision_status != ArcanistDifferentialRevisionStatus::ABANDONED) { throw new DifferentialActionHasNoEffectException( "You can not reclaim this revision because it is not abandoned."); } $revision ->setStatus(ArcanistDifferentialRevisionStatus::NEEDS_REVIEW); break; case DifferentialAction::ACTION_CLOSE: // NOTE: The daemons can mark things closed from any state. We treat // them as completely authoritative. if (!$this->isDaemonWorkflow) { if (!$actor_is_author && !$always_allow_close) { throw new Exception( "You can not mark a revision you don't own as closed."); } $status_closed = ArcanistDifferentialRevisionStatus::CLOSED; $status_accepted = ArcanistDifferentialRevisionStatus::ACCEPTED; if ($revision_status == $status_closed) { throw new DifferentialActionHasNoEffectException( "You can not mark this revision as closed because it has ". "already been marked as closed."); } if ($revision_status != $status_accepted) { throw new DifferentialActionHasNoEffectException( "You can not mark this revision as closed because it is ". "has not been accepted."); } } if (!$revision->getDateCommitted()) { $revision->setDateCommitted(time()); } $revision->setStatus(ArcanistDifferentialRevisionStatus::CLOSED); break; case DifferentialAction::ACTION_REOPEN: if (!$allow_reopen) { throw new Exception( "You cannot reopen a revision when this action is disabled."); } if ($revision_status != ArcanistDifferentialRevisionStatus::CLOSED) { throw new Exception( "You cannot reopen a revision that is not currently closed."); } $revision->setStatus(ArcanistDifferentialRevisionStatus::NEEDS_REVIEW); break; case DifferentialAction::ACTION_ADDREVIEWERS: list($added_reviewers, $ignored) = $this->alterReviewers(); if ($added_reviewers) { $key = DifferentialComment::METADATA_ADDED_REVIEWERS; $metadata[$key] = $added_reviewers; } else { $user_tried_to_add = count($this->getAddedReviewers()); if ($user_tried_to_add == 0) { throw new DifferentialActionHasNoEffectException( "You can not add reviewers, because you did not specify any ". "reviewers."); } else if ($user_tried_to_add == 1) { throw new DifferentialActionHasNoEffectException( "You can not add that reviewer, because they are already an ". "author or reviewer."); } else { throw new DifferentialActionHasNoEffectException( "You can not add those reviewers, because they are all already ". "authors or reviewers."); } } break; case DifferentialAction::ACTION_ADDCCS: $added_ccs = $this->getAddedCCs(); $user_tried_to_add = count($added_ccs); $added_ccs = $this->filterAddedCCs($added_ccs); if ($added_ccs) { foreach ($added_ccs as $cc) { DifferentialRevisionEditor::addCC( $revision, $cc, $actor_phid); } $key = DifferentialComment::METADATA_ADDED_CCS; $metadata[$key] = $added_ccs; } else { if ($user_tried_to_add == 0) { throw new DifferentialActionHasNoEffectException( "You can not add CCs, because you did not specify any ". "CCs."); } else if ($user_tried_to_add == 1) { throw new DifferentialActionHasNoEffectException( "You can not add that CC, because they are already an ". "author, reviewer or CC."); } else { throw new DifferentialActionHasNoEffectException( "You can not add those CCs, because they are all already ". "authors, reviewers or CCs."); } } break; case DifferentialAction::ACTION_CLAIM: if ($actor_is_author) { throw new Exception("You can not commandeer your own revision."); } switch ($revision_status) { case ArcanistDifferentialRevisionStatus::CLOSED: throw new DifferentialActionHasNoEffectException( "You can not commandeer this revision because it has ". "already been closed."); break; } $this->setAddedReviewers(array($revision->getAuthorPHID())); $this->setRemovedReviewers(array($actor_phid)); // NOTE: Set the new author PHID before calling addReviewers(), since it // doesn't permit the author to become a reviewer. $revision->setAuthorPHID($actor_phid); list($added_reviewers, $removed_reviewers) = $this->alterReviewers(); if ($added_reviewers) { $key = DifferentialComment::METADATA_ADDED_REVIEWERS; $metadata[$key] = $added_reviewers; } if ($removed_reviewers) { $key = DifferentialComment::METADATA_REMOVED_REVIEWERS; $metadata[$key] = $removed_reviewers; } break; default: throw new Exception('Unsupported action.'); } // Update information about reviewer in charge. if ($action == DifferentialAction::ACTION_ACCEPT || $action == DifferentialAction::ACTION_REJECT) { $revision->setLastReviewerPHID($actor_phid); } // TODO: Call beginReadLocking() prior to loading the revision. $revision->openTransaction(); // Always save the revision (even if we didn't actually change any of its // properties) so that it jumps to the top of the revision list when sorted // by "updated". Notably, this allows "ping" comments to push it to the // top of the action list. $revision->save(); if ($action != DifferentialAction::ACTION_RESIGN) { DifferentialRevisionEditor::addCC( $revision, $actor_phid, $actor_phid); } $comment = id(new DifferentialComment()) ->setAuthorPHID($actor_phid) ->setRevisionID($revision->getID()) ->setAction($action) ->setContent((string)$this->message) ->setMetadata($metadata); if ($this->contentSource) { $comment->setContentSource($this->contentSource); } $comment->save(); $changesets = array(); if ($inline_comments) { $load_ids = mpull($inline_comments, 'getChangesetID'); if ($load_ids) { $load_ids = array_unique($load_ids); $changesets = id(new DifferentialChangeset())->loadAllWhere( 'id in (%Ld)', $load_ids); } foreach ($inline_comments as $inline) { $inline->setCommentID($comment->getID()); $inline->save(); } } // Find any "@mentions" in the comment blocks. $content_blocks = array($comment->getContent()); foreach ($inline_comments as $inline) { $content_blocks[] = $inline->getContent(); } $mention_ccs = PhabricatorMarkupEngine::extractPHIDsFromMentions( $content_blocks); if ($mention_ccs) { $mention_ccs = $this->filterAddedCCs($mention_ccs); if ($mention_ccs) { $metadata = $comment->getMetadata(); $metacc = idx( $metadata, DifferentialComment::METADATA_ADDED_CCS, array()); foreach ($mention_ccs as $cc_phid) { DifferentialRevisionEditor::addCC( $revision, $cc_phid, $actor_phid); $metacc[] = $cc_phid; } $metadata[DifferentialComment::METADATA_ADDED_CCS] = $metacc; $comment->setMetadata($metadata); $comment->save(); } } $revision->saveTransaction(); $phids = array($actor_phid); $handles = id(new PhabricatorObjectHandleData($phids)) ->loadHandles(); $actor_handle = $handles[$actor_phid]; $xherald_header = HeraldTranscript::loadXHeraldRulesHeader( $revision->getPHID()); $mailed_phids = array(); if (!$this->noEmail) { $mail = id(new DifferentialCommentMail( $revision, $actor_handle, $comment, $changesets, $inline_comments)) ->setExcludeMailRecipientPHIDs($this->getExcludeMailRecipientPHIDs()) ->setToPHIDs( array_merge( $revision->getReviewers(), array($revision->getAuthorPHID()))) ->setCCPHIDs($revision->getCCPHIDs()) ->setChangedByCommit($this->getChangedByCommit()) ->setXHeraldRulesHeader($xherald_header) ->setParentMessageID($this->parentMessageID) ->send(); $mailed_phids = $mail->getRawMail()->buildRecipientList(); } $event_data = array( 'revision_id' => $revision->getID(), 'revision_phid' => $revision->getPHID(), 'revision_name' => $revision->getTitle(), 'revision_author_phid' => $revision->getAuthorPHID(), 'action' => $comment->getAction(), 'feedback_content' => $comment->getContent(), 'actor_phid' => $actor_phid, ); // TODO: Get rid of this id(new PhabricatorTimelineEvent('difx', $event_data)) ->recordEvent(); id(new PhabricatorFeedStoryPublisher()) ->setStoryType('PhabricatorFeedStoryDifferential') ->setStoryData($event_data) ->setStoryTime(time()) ->setStoryAuthorPHID($actor_phid) ->setRelatedPHIDs( array( $revision->getPHID(), $actor_phid, $revision->getAuthorPHID(), )) ->setPrimaryObjectPHID($revision->getPHID()) ->setSubscribedPHIDs( array_merge( array($revision->getAuthorPHID()), $revision->getReviewers(), $revision->getCCPHIDs())) ->setMailRecipientPHIDs($mailed_phids) ->publish(); id(new PhabricatorSearchIndexer()) ->indexDocumentByPHID($revision->getPHID()); return $comment; } private function filterAddedCCs(array $ccs) { $revision = $this->revision; $current_ccs = $revision->getCCPHIDs(); $current_ccs = array_fill_keys($current_ccs, true); $reviewer_phids = $revision->getReviewers(); $reviewer_phids = array_fill_keys($reviewer_phids, true); foreach ($ccs as $key => $cc) { if (isset($current_ccs[$cc])) { unset($ccs[$key]); } if (isset($reviewer_phids[$cc])) { unset($ccs[$key]); } if ($cc == $revision->getAuthorPHID()) { unset($ccs[$key]); } } return $ccs; } private function alterReviewers() { $actor_phid = $this->getActor()->getPHID(); $revision = $this->revision; $added_reviewers = $this->getAddedReviewers(); $removed_reviewers = $this->getRemovedReviewers(); $reviewer_phids = $revision->getReviewers(); $allow_self_accept = PhabricatorEnv::getEnvConfig( 'differential.allow-self-accept'); $reviewer_phids_map = array_fill_keys($reviewer_phids, true); foreach ($added_reviewers as $k => $user_phid) { if (!$allow_self_accept && $user_phid == $revision->getAuthorPHID()) { unset($added_reviewers[$k]); } if (isset($reviewer_phids_map[$user_phid])) { unset($added_reviewers[$k]); } } foreach ($removed_reviewers as $k => $user_phid) { if (!isset($reviewer_phids_map[$user_phid])) { unset($removed_reviewers[$k]); } } $added_reviewers = array_unique($added_reviewers); $removed_reviewers = array_unique($removed_reviewers); if ($added_reviewers) { DifferentialRevisionEditor::alterReviewers( $revision, $reviewer_phids, $removed_reviewers, $added_reviewers, $actor_phid); } return array($added_reviewers, $removed_reviewers); } } diff --git a/src/applications/macro/controller/PhabricatorMacroListController.php b/src/applications/macro/controller/PhabricatorMacroListController.php index 4a7560ec89..0ed1bebc77 100644 --- a/src/applications/macro/controller/PhabricatorMacroListController.php +++ b/src/applications/macro/controller/PhabricatorMacroListController.php @@ -1,165 +1,165 @@ getRequest(); $viewer = $request->getUser(); $macro_table = new PhabricatorFileImageMacro(); $file_table = new PhabricatorFile(); $conn = $macro_table->establishConnection('r'); $where = array(); $join = array(); $join[] = qsprintf($conn, '%T m', $macro_table->getTableName()); $filter = $request->getStr('name'); if (strlen($filter)) { $where[] = qsprintf($conn, 'm.name LIKE %~', $filter); } $authors = $request->getArr('authors'); if ($authors) { $join[] = qsprintf( $conn, '%T f ON m.filePHID = f.phid', $file_table->getTableName()); $where[] = qsprintf($conn, 'f.authorPHID IN (%Ls)', $authors); } $has_search = $where; if ($has_search) { $macros = queryfx_all( $conn, - 'SELECT m.* - FROM '.implode(' JOIN ', $join).' - WHERE '.implode(' AND ', $where)); + 'SELECT m.* FROM %Q WHERE %Q', + implode(' JOIN ', $join), + implode(' AND ', $where)); $macros = $macro_table->loadAllFromArray($macros); $nodata = pht('There are no macros matching the filter.'); } else { $pager = new AphrontPagerView(); $pager->setOffset($request->getInt('page')); $macros = $macro_table->loadAllWhere( '1 = 1 ORDER BY id DESC LIMIT %d, %d', $pager->getOffset(), $pager->getPageSize()); // Get an exact count since the size here is reasonably going to be a few // thousand at most in any reasonable case. $count = queryfx_one( $conn, 'SELECT COUNT(*) N FROM %T', $macro_table->getTableName()); $count = $count['N']; $pager->setCount($count); $pager->setURI($request->getRequestURI(), 'page'); $nodata = pht('There are no image macros yet.'); } if ($authors) { - $author_phids = array_combine($authors, $authors); + $author_phids = array_fuse($authors); } else { $author_phids = array(); } $file_phids = mpull($macros, 'getFilePHID'); $files = array(); if ($file_phids) { $files = $file_table->loadAllWhere( "phid IN (%Ls)", $file_phids); $author_phids += mpull($files, 'getAuthorPHID', 'getAuthorPHID'); } $files_map = mpull($files, null, 'getPHID'); $this->loadHandles($author_phids); $author_handles = array_select_keys($this->getLoadedHandles(), $authors); $filter_form = id(new AphrontFormView()) ->setMethod('GET') ->setUser($request->getUser()) ->appendChild( id(new AphrontFormTextControl()) ->setName('name') ->setLabel(pht('Name')) ->setValue($filter)) ->appendChild( id(new AphrontFormTokenizerControl()) ->setName('authors') ->setLabel(pht('Authors')) ->setDatasource('/typeahead/common/users/') ->setValue(mpull($author_handles, 'getFullName'))) ->appendChild( id(new AphrontFormSubmitControl()) ->setValue(pht('Filter Image Macros'))); $filter_view = new AphrontListFilterView(); $filter_view->appendChild($filter_form); $nav = $this->buildSideNavView( $for_app = false, $has_search); $nav->selectFilter($has_search ? 'search' : '/'); $nav->appendChild($filter_view); $pinboard = new PhabricatorPinboardView(); $pinboard->setNoDataString($nodata); foreach ($macros as $macro) { $file_phid = $macro->getFilePHID(); $file = idx($files_map, $file_phid); $item = new PhabricatorPinboardItemView(); if ($file) { $item->setImageURI($file->getThumb220x165URI()); $item->setImageSize(220, 165); if ($file->getAuthorPHID()) { $author_handle = $this->getHandle($file->getAuthorPHID()); $item->appendChild( 'Created by '.$author_handle->renderLink()); } $datetime = phabricator_date($file->getDateCreated(), $viewer); $item->appendChild( phutil_tag( 'div', array(), pht('Created on %s', $datetime))); } $item->setURI($this->getApplicationURI('/view/'.$macro->getID().'/')); $item->setHeader($macro->getName()); $pinboard->addItem($item); } $nav->appendChild($pinboard); if (!$has_search) { $nav->appendChild($pager); $name = pht('All Macros'); } else { $name = pht('Search'); } $crumbs = $this->buildApplicationCrumbs(); $crumbs->addCrumb( id(new PhabricatorCrumbView()) ->setName($name) ->setHref($request->getRequestURI())); $nav->setCrumbs($crumbs); return $this->buildApplicationPage( $nav, array( 'device' => true, 'title' => pht('Image Macros'), )); } } diff --git a/src/applications/metamta/controller/PhabricatorMetaMTAReceiveController.php b/src/applications/metamta/controller/PhabricatorMetaMTAReceiveController.php index 6afb4b3c17..2ae211e2ad 100644 --- a/src/applications/metamta/controller/PhabricatorMetaMTAReceiveController.php +++ b/src/applications/metamta/controller/PhabricatorMetaMTAReceiveController.php @@ -1,78 +1,84 @@ getRequest(); $user = $request->getUser(); if ($request->isFormPost()) { $receiver = PhabricatorMetaMTAReceivedMail::loadReceiverObject( $request->getStr('obj')); if (!$receiver) { throw new Exception("No such task or revision!"); } $hash = PhabricatorMetaMTAReceivedMail::computeMailHash( $receiver->getMailKey(), $user->getPHID()); $received = new PhabricatorMetaMTAReceivedMail(); $received->setHeaders( array( 'to' => $request->getStr('obj').'+'.$user->getID().'+'.$hash.'@', )); $received->setBodies( array( 'text' => $request->getStr('body'), )); + + // Make up some unique value, since this column isn't nullable. + $received->setMessageIDHash( + PhabricatorHash::digestForIndex( + Filesystem::readRandomBytes(12))); + $received->save(); $received->processReceivedMail(); $phid = $receiver->getPHID(); $handles = $this->loadViewerHandles(array($phid)); $uri = $handles[$phid]->getURI(); return id(new AphrontRedirectResponse())->setURI($uri); } $form = new AphrontFormView(); $form->setUser($request->getUser()); $form->setAction($this->getApplicationURI('/receive/')); $form ->appendChild( '

    This form will simulate '. 'sending mail to an object.

    ') ->appendChild( id(new AphrontFormTextControl()) ->setLabel('To') ->setName('obj') ->setCaption('e.g. D1234 or T1234')) ->appendChild( id(new AphrontFormTextAreaControl()) ->setLabel('Body') ->setName('body')) ->appendChild( id(new AphrontFormSubmitControl()) ->setValue('Receive Mail')); $panel = new AphrontPanelView(); $panel->setHeader('Receive Email'); $panel->appendChild($form); $panel->setWidth(AphrontPanelView::WIDTH_FORM); $nav = $this->buildSideNavView(); $nav->selectFilter('receive'); $nav->appendChild($panel); return $this->buildApplicationPage( $nav, array( 'title' => 'Receive Test', )); } } diff --git a/src/applications/metamta/controller/PhabricatorMetaMTASendGridReceiveController.php b/src/applications/metamta/controller/PhabricatorMetaMTASendGridReceiveController.php index 4b81a3c08b..fbd86a2871 100644 --- a/src/applications/metamta/controller/PhabricatorMetaMTASendGridReceiveController.php +++ b/src/applications/metamta/controller/PhabricatorMetaMTASendGridReceiveController.php @@ -1,66 +1,68 @@ getRequest(); $user = $request->getUser(); $raw_headers = $request->getStr('headers'); $raw_headers = explode("\n", rtrim($raw_headers)); $raw_dict = array(); foreach (array_filter($raw_headers) as $header) { list($name, $value) = explode(':', $header, 2); $raw_dict[$name] = ltrim($value); } $headers = array( 'to' => $request->getStr('to'), 'from' => $request->getStr('from'), 'subject' => $request->getStr('subject'), ) + $raw_dict; $received = new PhabricatorMetaMTAReceivedMail(); $received->setHeaders($headers); $received->setBodies(array( 'text' => $request->getStr('text'), 'html' => $request->getStr('from'), )); + $received->setMessageIDHash( + PhabricatorHash::digestForIndex($received->getMessageID())); $file_phids = array(); foreach ($_FILES as $file_raw) { try { $file = PhabricatorFile::newFromPHPUpload( $file_raw, array( 'authorPHID' => $user->getPHID(), )); $file_phids[] = $file->getPHID(); } catch (Exception $ex) { phlog($ex); } } $received->setAttachments($file_phids); $received->save(); $received->processReceivedMail(); $response = new AphrontWebpageResponse(); $response->setContent("Got it! Thanks, SendGrid!\n"); return $response; } } diff --git a/src/applications/metamta/replyhandler/PhabricatorMailReplyHandler.php b/src/applications/metamta/replyhandler/PhabricatorMailReplyHandler.php index 20d4436073..51784d7b96 100644 --- a/src/applications/metamta/replyhandler/PhabricatorMailReplyHandler.php +++ b/src/applications/metamta/replyhandler/PhabricatorMailReplyHandler.php @@ -1,316 +1,322 @@ validateMailReceiver($mail_receiver); $this->mailReceiver = $mail_receiver; return $this; } final public function getMailReceiver() { return $this->mailReceiver; } final public function setActor(PhabricatorUser $actor) { $this->actor = $actor; return $this; } final public function getActor() { return $this->actor; } final public function setExcludeMailRecipientPHIDs(array $exclude) { $this->excludePHIDs = $exclude; return $this; } final public function getExcludeMailRecipientPHIDs() { return $this->excludePHIDs; } abstract public function validateMailReceiver($mail_receiver); abstract public function getPrivateReplyHandlerEmailAddress( PhabricatorObjectHandle $handle); - abstract public function getReplyHandlerDomain(); + public function getReplyHandlerDomain() { + return PhabricatorEnv::getEnvConfig( + 'metamta.reply-handler-domain' + ); + } abstract public function getReplyHandlerInstructions(); abstract protected function receiveEmail( PhabricatorMetaMTAReceivedMail $mail); public function processEmail(PhabricatorMetaMTAReceivedMail $mail) { $error = $this->sanityCheckEmail($mail); if ($error) { if ($this->shouldSendErrorEmail($mail)) { $this->sendErrorEmail($error, $mail); } return null; } return $this->receiveEmail($mail); } private function sanityCheckEmail(PhabricatorMetaMTAReceivedMail $mail) { $body = $mail->getCleanTextBody(); $attachments = $mail->getAttachments(); if (empty($body) && empty($attachments)) { return 'Empty email body. Email should begin with an !action and / or '. 'text to comment. Inline replies and signatures are ignored.'; } return null; } /** * Only send an error email if the user is talking to just Phabricator. We * can assume if there is only one To address it is a Phabricator address * since this code is running and everything. */ private function shouldSendErrorEmail(PhabricatorMetaMTAReceivedMail $mail) { return (count($mail->getToAddresses()) == 1) && (count($mail->getCCAddresses()) == 0); } private function sendErrorEmail($error, PhabricatorMetaMTAReceivedMail $mail) { $template = new PhabricatorMetaMTAMail(); $template->setSubject('Exception: unable to process your mail request'); $template->setBody($this->buildErrorMailBody($error, $mail)); $template->setRelatedPHID($mail->getRelatedPHID()); $phid = $this->getActor()->getPHID(); $tos = array( $phid => PhabricatorObjectHandleData::loadOneHandle($phid) ); $mails = $this->multiplexMail($template, $tos, array()); foreach ($mails as $email) { $email->saveAndSend(); } return true; } private function buildErrorMailBody($error, PhabricatorMetaMTAReceivedMail $mail) { $original_body = $mail->getRawTextBody(); $main_body = <<addRawSection($main_body); $body->addReplySection($this->getReplyHandlerInstructions()); return $body->render(); } public function supportsPrivateReplies() { return (bool)$this->getReplyHandlerDomain() && !$this->supportsPublicReplies(); } public function supportsPublicReplies() { if (!PhabricatorEnv::getEnvConfig('metamta.public-replies')) { return false; } if (!$this->getReplyHandlerDomain()) { return false; } return (bool)$this->getPublicReplyHandlerEmailAddress(); } final public function supportsReplies() { return $this->supportsPrivateReplies() || $this->supportsPublicReplies(); } public function getPublicReplyHandlerEmailAddress() { return null; } final public function getRecipientsSummary( array $to_handles, array $cc_handles) { assert_instances_of($to_handles, 'PhabricatorObjectHandle'); assert_instances_of($cc_handles, 'PhabricatorObjectHandle'); $body = ''; if (PhabricatorEnv::getEnvConfig('metamta.recipients.show-hints')) { if ($to_handles) { $body .= "To: ".implode(', ', mpull($to_handles, 'getName'))."\n"; } if ($cc_handles) { $body .= "Cc: ".implode(', ', mpull($cc_handles, 'getName'))."\n"; } } return $body; } final public function multiplexMail( PhabricatorMetaMTAMail $mail_template, array $to_handles, array $cc_handles) { assert_instances_of($to_handles, 'PhabricatorObjectHandle'); assert_instances_of($cc_handles, 'PhabricatorObjectHandle'); $result = array(); // If MetaMTA is configured to always multiplex, skip the single-email // case. if (!PhabricatorMetaMTAMail::shouldMultiplexAllMail()) { // If private replies are not supported, simply send one email to all // recipients and CCs. This covers cases where we have no reply handler, // or we have a public reply handler. if (!$this->supportsPrivateReplies()) { $mail = clone $mail_template; $mail->addTos(mpull($to_handles, 'getPHID')); $mail->addCCs(mpull($cc_handles, 'getPHID')); if ($this->supportsPublicReplies()) { $reply_to = $this->getPublicReplyHandlerEmailAddress(); $mail->setReplyTo($reply_to); } $result[] = $mail; return $result; } } $tos = mpull($to_handles, null, 'getPHID'); $ccs = mpull($cc_handles, null, 'getPHID'); // Merge all the recipients together. TODO: We could keep the CCs as real // CCs and send to a "noreply@domain.com" type address, but keep it simple // for now. $recipients = $tos + $ccs; // When multiplexing mail, explicitly include To/Cc information in the // message body and headers. $mail_template = clone $mail_template; $mail_template->addPHIDHeaders('X-Phabricator-To', array_keys($tos)); $mail_template->addPHIDHeaders('X-Phabricator-Cc', array_keys($ccs)); $body = $mail_template->getBody(); $body .= "\n"; $body .= $this->getRecipientsSummary($to_handles, $cc_handles); foreach ($recipients as $phid => $recipient) { $mail = clone $mail_template; if (isset($to_handles[$phid])) { $mail->addTos(array($phid)); } else if (isset($cc_handles[$phid])) { $mail->addCCs(array($phid)); } else { // not good - they should be a to or a cc continue; } $mail->setBody($body); $reply_to = null; if (!$reply_to && $this->supportsPrivateReplies()) { $reply_to = $this->getPrivateReplyHandlerEmailAddress($recipient); } if (!$reply_to && $this->supportsPublicReplies()) { $reply_to = $this->getPublicReplyHandlerEmailAddress(); } if ($reply_to) { $mail->setReplyTo($reply_to); } $result[] = $mail; } return $result; } protected function getDefaultPublicReplyHandlerEmailAddress($prefix) { $receiver = $this->getMailReceiver(); $receiver_id = $receiver->getID(); $domain = $this->getReplyHandlerDomain(); // We compute a hash using the object's own PHID to prevent an attacker // from blindly interacting with objects that they haven't ever received // mail about by just sending to D1@, D2@, etc... $hash = PhabricatorMetaMTAReceivedMail::computeMailHash( $receiver->getMailKey(), $receiver->getPHID()); $address = "{$prefix}{$receiver_id}+public+{$hash}@{$domain}"; return $this->getSingleReplyHandlerPrefix($address); } protected function getSingleReplyHandlerPrefix($address) { $single_handle_prefix = PhabricatorEnv::getEnvConfig( 'metamta.single-reply-handler-prefix'); return ($single_handle_prefix) ? $single_handle_prefix . '+' . $address : $address; } protected function getDefaultPrivateReplyHandlerEmailAddress( PhabricatorObjectHandle $handle, $prefix) { if ($handle->getType() != PhabricatorPHIDConstants::PHID_TYPE_USER) { // You must be a real user to get a private reply handler address. return null; } $receiver = $this->getMailReceiver(); $receiver_id = $receiver->getID(); $user_id = $handle->getAlternateID(); $hash = PhabricatorMetaMTAReceivedMail::computeMailHash( $receiver->getMailKey(), $handle->getPHID()); $domain = $this->getReplyHandlerDomain(); $address = "{$prefix}{$receiver_id}+{$user_id}+{$hash}@{$domain}"; return $this->getSingleReplyHandlerPrefix($address); } - final protected function enhanceBodyWithAttachments($body, - array $attachments) { + final protected function enhanceBodyWithAttachments( + $body, + array $attachments, + $format = '- {F%d, layout=link}') { if (!$attachments) { return $body; } $files = id(new PhabricatorFile()) ->loadAllWhere('phid in (%Ls)', $attachments); // if we have some text then double return before adding our file list if ($body) { $body .= "\n\n"; } foreach ($files as $file) { - $file_str = sprintf('- {F%d, layout=link}', $file->getID()); + $file_str = sprintf($format, $file->getID()); $body .= $file_str."\n"; } return rtrim($body); } } diff --git a/src/applications/metamta/storage/PhabricatorMetaMTAMail.php b/src/applications/metamta/storage/PhabricatorMetaMTAMail.php index 86f02f427e..7b98dd4299 100644 --- a/src/applications/metamta/storage/PhabricatorMetaMTAMail.php +++ b/src/applications/metamta/storage/PhabricatorMetaMTAMail.php @@ -1,921 +1,921 @@ status = self::STATUS_QUEUE; $this->retryCount = 0; $this->nextRetry = time(); $this->parameters = array(); parent::__construct(); } public function getConfiguration() { return array( self::CONFIG_SERIALIZATION => array( 'parameters' => self::SERIALIZATION_JSON, ), ) + parent::getConfiguration(); } protected function setParam($param, $value) { $this->parameters[$param] = $value; return $this; } protected function getParam($param, $default = null) { return idx($this->parameters, $param, $default); } /** * Set tags (@{class:MetaMTANotificationType} constants) which identify the * content of this mail in a general way. These tags are used to allow users * to opt out of receiving certain types of mail, like updates when a task's * projects change. * * @param list List of @{class:MetaMTANotificationType} constants. * @return this */ public function setMailTags(array $tags) { $this->setParam('mailtags', $tags); return $this; } /** * In Gmail, conversations will be broken if you reply to a thread and the * server sends back a response without referencing your Message-ID, even if * it references a Message-ID earlier in the thread. To avoid this, use the * parent email's message ID explicitly if it's available. This overwrites the * "In-Reply-To" and "References" headers we would otherwise generate. This * needs to be set whenever an action is triggered by an email message. See * T251 for more details. * * @param string The "Message-ID" of the email which precedes this one. * @return this */ public function setParentMessageID($id) { $this->setParam('parent-message-id', $id); return $this; } public function getParentMessageID() { return $this->getParam('parent-message-id'); } public function getSubject() { return $this->getParam('subject'); } public function addTos(array $phids) { $phids = array_unique($phids); $this->setParam('to', $phids); return $this; } public function addRawTos(array $raw_email) { $this->setParam('raw-to', $raw_email); return $this; } public function addCCs(array $phids) { $phids = array_unique($phids); $this->setParam('cc', $phids); return $this; } public function setExcludeMailRecipientPHIDs($exclude) { $this->excludePHIDs = $exclude; return $this; } private function getExcludeMailRecipientPHIDs() { return $this->excludePHIDs; } public function getTranslation(array $objects) { $default_translation = PhabricatorEnv::getEnvConfig('translation.provider'); $return = null; $recipients = array_merge( idx($this->parameters, 'to', array()), idx($this->parameters, 'cc', array())); foreach (array_select_keys($objects, $recipients) as $object) { $translation = null; if ($object instanceof PhabricatorUser) { $translation = $object->getTranslation(); } if (!$translation) { $translation = $default_translation; } if ($return && $translation != $return) { return $default_translation; } $return = $translation; } if (!$return) { $return = $default_translation; } return $return; } public function addPHIDHeaders($name, array $phids) { foreach ($phids as $phid) { $this->addHeader($name, '<'.$phid.'>'); } return $this; } public function addHeader($name, $value) { $this->parameters['headers'][] = array($name, $value); return $this; } public function addAttachment(PhabricatorMetaMTAAttachment $attachment) { $this->parameters['attachments'][] = $attachment; return $this; } public function getAttachments() { return $this->getParam('attachments'); } public function setAttachments(array $attachments) { assert_instances_of($attachments, 'PhabricatorMetaMTAAttachment'); $this->setParam('attachments', $attachments); return $this; } public function setFrom($from) { $this->setParam('from', $from); return $this; } public function setReplyTo($reply_to) { $this->setParam('reply-to', $reply_to); return $this; } public function setSubject($subject) { $this->setParam('subject', $subject); return $this; } public function setSubjectPrefix($prefix) { $this->setParam('subject-prefix', $prefix); return $this; } public function setVarySubjectPrefix($prefix) { $this->setParam('vary-subject-prefix', $prefix); return $this; } public function setBody($body) { $this->setParam('body', $body); return $this; } public function getBody() { return $this->getParam('body'); } public function setIsHTML($html) { $this->setParam('is-html', $html); return $this; } public function getSimulatedFailureCount() { return nonempty($this->getParam('simulated-failures'), 0); } public function setSimulatedFailureCount($count) { $this->setParam('simulated-failures', $count); return $this; } public function getWorkerTaskID() { return $this->getParam('worker-task'); } public function setWorkerTaskID($id) { $this->setParam('worker-task', $id); return $this; } /** * Flag that this is an auto-generated bulk message and should have bulk * headers added to it if appropriate. Broadly, this means some flavor of * "Precedence: bulk" or similar, but is implementation and configuration * dependent. * * @param bool True if the mail is automated bulk mail. * @return this */ public function setIsBulk($is_bulk) { $this->setParam('is-bulk', $is_bulk); return $this; } /** * Use this method to set an ID used for message threading. MetaMTA will * set appropriate headers (Message-ID, In-Reply-To, References and * Thread-Index) based on the capabilities of the underlying mailer. * * @param string Unique identifier, appropriate for use in a Message-ID, * In-Reply-To or References headers. * @param bool If true, indicates this is the first message in the thread. * @return this */ public function setThreadID($thread_id, $is_first_message = false) { $this->setParam('thread-id', $thread_id); $this->setParam('is-first-message', $is_first_message); return $this; } /** * Save a newly created mail to the database and attempt to send it * immediately if the server is configured for immediate sends. When * applications generate new mail they should generally use this method to * deliver it. If the server doesn't use immediate sends, this has the same * effect as calling save(): the mail will eventually be delivered by the * MetaMTA daemon. * * @return this */ public function saveAndSend() { $ret = null; if (PhabricatorEnv::getEnvConfig('metamta.send-immediately')) { $ret = $this->sendNow(); } else { $ret = $this->save(); } return $ret; } protected function didWriteData() { parent::didWriteData(); if (!$this->getWorkerTaskID()) { $mailer_task = PhabricatorWorker::scheduleTask( 'PhabricatorMetaMTAWorker', $this->getID()); $this->setWorkerTaskID($mailer_task->getID()); $this->save(); } } public function buildDefaultMailer() { return PhabricatorEnv::newObjectFromConfig('metamta.mail-adapter'); } /** * Attempt to deliver an email immediately, in this process. * * @param bool Try to deliver this email even if it has already been * delivered or is in backoff after a failed delivery attempt. * @param PhabricatorMailImplementationAdapter Use a specific mail adapter, * instead of the default. * * @return void */ public function sendNow( $force_send = false, PhabricatorMailImplementationAdapter $mailer = null) { if ($mailer === null) { $mailer = $this->buildDefaultMailer(); } if (!$force_send) { if ($this->getStatus() != self::STATUS_QUEUE) { throw new Exception("Trying to send an already-sent mail!"); } if (time() < $this->getNextRetry()) { throw new Exception("Trying to send an email before next retry!"); } } try { $params = $this->parameters; $phids = array(); foreach ($params as $key => $value) { switch ($key) { case 'to': $params[$key] = $this->buildToList(); break; case 'cc': $params[$key] = $this->buildCCList(); break; } } foreach ($params as $key => $value) { switch ($key) { case 'from': $value = array($value); /* fallthrough */ case 'to': case 'cc': foreach ($value as $phid) { $type = phid_get_type($phid); $phids[$phid] = $type; } break; } } $this->loadEmailAndNameDataFromPHIDs($phids); $default = PhabricatorEnv::getEnvConfig('metamta.default-address'); if (empty($params['from'])) { $mailer->setFrom($default); } else { $from = $params['from']; if (!PhabricatorEnv::getEnvConfig('metamta.can-send-as-user')) { if (empty($params['reply-to'])) { $params['reply-to'] = $phids[$from]['email']; $params['reply-to-name'] = $phids[$from]['name']; } $mailer->setFrom( $default, $phids[$from]['name']); unset($params['from']); } } $is_first = idx($params, 'is-first-message'); unset($params['is-first-message']); $is_threaded = (bool)idx($params, 'thread-id'); $reply_to_name = idx($params, 'reply-to-name', ''); unset($params['reply-to-name']); $add_cc = array(); $add_to = array(); foreach ($params as $key => $value) { switch ($key) { case 'from': $mailer->setFrom($phids[$from]['email']); break; case 'reply-to': $mailer->addReplyTo($value, $reply_to_name); break; case 'to': $to_emails = $this->filterSendable($value, $phids); if ($to_emails) { $add_to = array_merge($add_to, $to_emails); } break; case 'raw-to': $add_to = array_merge($add_to, $value); break; case 'cc': $cc_emails = $this->filterSendable($value, $phids); if ($cc_emails) { $add_cc = $cc_emails; } break; case 'headers': foreach ($value as $pair) { list($header_key, $header_value) = $pair; // NOTE: If we have \n in a header, SES rejects the email. $header_value = str_replace("\n", " ", $header_value); $mailer->addHeader($header_key, $header_value); } break; case 'attachments': foreach ($value as $attachment) { $mailer->addAttachment( $attachment->getData(), $attachment->getFilename(), $attachment->getMimeType() ); } break; case 'body': $mailer->setBody($value); break; case 'subject': // Only try to use preferences if everything is multiplexed, so we // get consistent behavior. $use_prefs = self::shouldMultiplexAllMail(); $prefs = null; if ($use_prefs) { // If multiplexing is enabled, some recipients will be in "Cc" // rather than "To". We'll move them to "To" later (or supply a // dummy "To") but need to look for the recipient in either the // "To" or "Cc" fields here. $target_phid = head(idx($params, 'to', array())); if (!$target_phid) { $target_phid = head(idx($params, 'cc', array())); } if ($target_phid) { $user = id(new PhabricatorUser())->loadOneWhere( 'phid = %s', $target_phid); if ($user) { $prefs = $user->loadPreferences(); } } } $subject = array(); if ($is_threaded) { $add_re = PhabricatorEnv::getEnvConfig('metamta.re-prefix'); if ($prefs) { $add_re = $prefs->getPreference( PhabricatorUserPreferences::PREFERENCE_RE_PREFIX, $add_re); } if ($add_re) { $subject[] = 'Re:'; } } $subject[] = trim(idx($params, 'subject-prefix')); $vary_prefix = idx($params, 'vary-subject-prefix'); if ($vary_prefix != '') { $use_subject = PhabricatorEnv::getEnvConfig( 'metamta.vary-subjects'); if ($prefs) { $use_subject = $prefs->getPreference( PhabricatorUserPreferences::PREFERENCE_VARY_SUBJECT, $use_subject); } if ($use_subject) { $subject[] = $vary_prefix; } } $subject[] = $value; $mailer->setSubject(implode(' ', array_filter($subject))); break; case 'is-html': if ($value) { $mailer->setIsHTML(true); } break; case 'is-bulk': if ($value) { if (PhabricatorEnv::getEnvConfig('metamta.precedence-bulk')) { $mailer->addHeader('Precedence', 'bulk'); } } break; case 'thread-id': // NOTE: Gmail freaks out about In-Reply-To and References which // aren't in the form ""; this is also required // by RFC 2822, although some clients are more liberal in what they // accept. $domain = PhabricatorEnv::getEnvConfig('metamta.domain'); $value = '<'.$value.'@'.$domain.'>'; if ($is_first && $mailer->supportsMessageIDHeader()) { $mailer->addHeader('Message-ID', $value); } else { $in_reply_to = $value; $references = array($value); $parent_id = $this->getParentMessageID(); if ($parent_id) { $in_reply_to = $parent_id; // By RFC 2822, the most immediate parent should appear last // in the "References" header, so this order is intentional. $references[] = $parent_id; } $references = implode(' ', $references); $mailer->addHeader('In-Reply-To', $in_reply_to); $mailer->addHeader('References', $references); } $thread_index = $this->generateThreadIndex($value, $is_first); $mailer->addHeader('Thread-Index', $thread_index); break; case 'mailtags': // Handled below. break; case 'subject-prefix': case 'vary-subject-prefix': // Handled above. break; default: // Just discard. } } if (!$add_to && !$add_cc) { $this->setStatus(self::STATUS_VOID); $this->setMessage( "Message has no valid recipients: all To/CC are disabled or ". "configured not to receive this mail."); return $this->save(); } $mailer->addHeader('X-Phabricator-Sent-This-Message', 'Yes'); $mailer->addHeader('X-Mail-Transport-Agent', 'MetaMTA'); // Some clients respect this to suppress OOF and other auto-responses. $mailer->addHeader('X-Auto-Response-Suppress', 'All'); // If the message has mailtags, filter out any recipients who don't want // to receive this type of mail. $mailtags = $this->getParam('mailtags'); if ($mailtags) { $tag_header = array(); foreach ($mailtags as $mailtag) { $tag_header[] = '<'.$mailtag.'>'; } $tag_header = implode(', ', $tag_header); $mailer->addHeader('X-Phabricator-Mail-Tags', $tag_header); } // Some mailers require a valid "To:" in order to deliver mail. If we // don't have any "To:", try to fill it in with a placeholder "To:". // If that also fails, move the "Cc:" line to "To:". if (!$add_to) { $placeholder_key = 'metamta.placeholder-to-recipient'; $placeholder = PhabricatorEnv::getEnvConfig($placeholder_key); if ($placeholder !== null) { $add_to = array($placeholder); } else { $add_to = $add_cc; $add_cc = array(); } } $mailer->addTos($add_to); if ($add_cc) { $mailer->addCCs($add_cc); } } catch (Exception $ex) { $this->setStatus(self::STATUS_FAIL); $this->setMessage($ex->getMessage()); return $this->save(); } if ($this->getRetryCount() < $this->getSimulatedFailureCount()) { $ok = false; $error = 'Simulated failure.'; } else { try { $ok = $mailer->send(); $error = null; } catch (Exception $ex) { $ok = false; $error = $ex->getMessage()."\n".$ex->getTraceAsString(); } } if (!$ok) { $this->setMessage($error); if ($this->getRetryCount() > self::MAX_RETRIES) { $this->setStatus(self::STATUS_FAIL); } else { $this->setRetryCount($this->getRetryCount() + 1); $next_retry = time() + ($this->getRetryCount() * self::RETRY_DELAY); $this->setNextRetry($next_retry); } } else { $this->setStatus(self::STATUS_SENT); } return $this->save(); } public static function getReadableStatus($status_code) { static $readable = array( self::STATUS_QUEUE => "Queued for Delivery", self::STATUS_FAIL => "Delivery Failed", self::STATUS_SENT => "Sent", self::STATUS_VOID => "Void", ); $status_code = coalesce($status_code, '?'); return idx($readable, $status_code, $status_code); } private function generateThreadIndex($seed, $is_first_mail) { // When threading, Outlook ignores the 'References' and 'In-Reply-To' // headers that most clients use. Instead, it uses a custom 'Thread-Index' // header. The format of this header is something like this (from // camel-exchange-folder.c in Evolution Exchange): /* A new post to a folder gets a 27-byte-long thread index. (The value * is apparently unique but meaningless.) Each reply to a post gets a * 32-byte-long thread index whose first 27 bytes are the same as the * parent's thread index. Each reply to any of those gets a * 37-byte-long thread index, etc. The Thread-Index header contains a * base64 representation of this value. */ // The specific implementation uses a 27-byte header for the first email // a recipient receives, and a random 5-byte suffix (32 bytes total) // thereafter. This means that all the replies are (incorrectly) siblings, // but it would be very difficult to keep track of the entire tree and this // gets us reasonable client behavior. $base = substr(md5($seed), 0, 27); if (!$is_first_mail) { // Not totally sure, but it seems like outlook orders replies by // thread-index rather than timestamp, so to get these to show up in the // right order we use the time as the last 4 bytes. $base .= ' '.pack('N', time()); } return base64_encode($base); } private function loadEmailAndNameDataFromPHIDs(array &$phids) { $users = array(); $mlsts = array(); // first iteration - group by types to do data fetches foreach ($phids as $phid => $type) { switch ($type) { case PhabricatorPHIDConstants::PHID_TYPE_USER: $users[] = $phid; break; case PhabricatorPHIDConstants::PHID_TYPE_MLST: $mlsts[] = $phid; break; } } $user_emails = array(); if ($users) { $user_emails = id(new PhabricatorUserEmail())->loadAllWhere( 'userPHID IN (%Ls) AND isPrimary = 1', $users); $users = id(new PhabricatorUser())->loadAllWhere( 'phid IN (%Ls)', $users); $user_emails = mpull($user_emails, null, 'getUserPHID'); $users = mpull($users, null, 'getPHID'); } if ($mlsts) { $mlsts = id(new PhabricatorMetaMTAMailingList())->loadAllWhere( 'phid IN (%Ls)', $mlsts); $mlsts = mpull($mlsts, null, 'getPHID'); } // second iteration - create entries for each phid $default = PhabricatorEnv::getEnvConfig('metamta.default-address'); foreach ($phids as $phid => &$value) { $name = ''; $email = $default; $is_mailable = false; switch ($value) { case PhabricatorPHIDConstants::PHID_TYPE_USER: $user = $users[$phid]; if ($user) { $name = $this->getUserName($user); $is_mailable = !$user->getIsDisabled() && !$user->getIsSystemAgent(); } $email = $user_emails[$phid] ? $user_emails[$phid]->getAddress() : $default; break; case PhabricatorPHIDConstants::PHID_TYPE_MLST: $mlst = $mlsts[$phid]; if ($mlst) { $name = $mlst->getName(); $email = $mlst->getEmail(); $is_mailable = true; } break; } $value = array( 'name' => $name, 'email' => $email, 'mailable' => $is_mailable, ); } } /** * Small helper function to make sure we format the username properly as * specified by the `metamta.user-address-format` configuration value. */ private function getUserName($user) { $format = PhabricatorEnv::getEnvConfig('metamta.user-address-format'); switch ($format) { case 'short': $name = $user->getUserName(); break; case 'real': $name = $user->getRealName(); break; case 'full': default: $name = $user->getFullName(); break; } return $name; } private function filterSendable($value, $phids) { $result = array(); foreach ($value as $phid) { if (isset($phids[$phid]) && $phids[$phid]['mailable']) { $result[$phid] = $phids[$phid]['email']; } } return $result; } public static function shouldMultiplexAllMail() { return PhabricatorEnv::getEnvConfig('metamta.one-mail-per-recipient'); } /* -( Managing Recipients )------------------------------------------------ */ /** * Get all of the recipients for this mail, after preference filters are * applied. This list has all objects to whom delivery will be attempted, but * does not exclude recipeints two whom delivery may be impossible. * * @return list A list of all recipients to whom delivery will be * attempted. * @task recipients */ public function buildRecipientList() { return $this->resolveRecipients( array_merge( $this->getRawToPHIDs(), $this->getRawCCPHIDs())); } /** * Filter out duplicate, invalid, or excluded recipients from a PHID list. * * @param list Unfiltered recipients. * @return list Filtered recipients. * * @task recipients */ private function resolveRecipients(array $phids) { if (!$phids) { return array(); } - $phids = array_combine($phids, $phids); + $phids = array_fuse($phids); // Exclude PHIDs explicitly marked for exclusion. We use this to prevent // recipients of an accidental "Reply All" from receiving the followup // mail from Phabricator. $exclude = $this->getExcludeMailRecipientPHIDs(); $exclude = array_fill_keys($exclude, true); $phids = array_diff_key($phids, $exclude); // If the actor is a recipient and has configured their preferences not to // send them mail about their own actions, drop them from the recipient // list. $from = $this->getParam('from'); if (isset($phids[$from])) { $from_user = id(new PhabricatorUser())->loadOneWhere( 'phid = %s', $from); if ($from_user) { $pref_key = PhabricatorUserPreferences::PREFERENCE_NO_SELF_MAIL; $exclude_self = $from_user ->loadPreferences() ->getPreference($pref_key); if ($exclude_self) { unset($phids[$from]); } } } // Exclude all recipients who have set preferences to not receive this type // of email (for example, a user who says they don't want emails about task // CC changes). $tags = $this->getParam('mailtags'); if ($tags && $phids) { $all_prefs = id(new PhabricatorUserPreferences())->loadAllWhere( 'userPHID in (%Ls)', $phids); $all_prefs = mpull($all_prefs, null, 'getUserPHID'); foreach ($phids as $phid) { $prefs = idx($all_prefs, $phid); if (!$prefs) { continue; } $user_mailtags = $prefs->getPreference( PhabricatorUserPreferences::PREFERENCE_MAILTAGS, array()); // The user must have elected to receive mail for at least one // of the mailtags. $send = false; foreach ($tags as $tag) { if (idx($user_mailtags, $tag, true)) { $send = true; break; } } if (!$send) { unset($phids[$phid]); } } } return array_keys($phids); } /** * @task recipients */ private function buildToList() { return $this->resolveRecipients($this->getRawToPHIDs()); } /** * @task recipients */ private function buildCCList() { return $this->resolveRecipients($this->getRawCCPHIDs()); } /** * @task recipients */ private function getRawToPHIDs() { $to = $this->getParam('to', array()); return $this->filterRawPHIDList($to); } /** * @task recipients */ private function getRawCCPHIDs() { $cc = $this->getParam('cc', array()); return $this->filterRawPHIDList($cc); } /** * @task recipients */ private function filterRawPHIDList(array $list) { $list = array_filter($list); $list = array_unique($list); return array_values($list); } } diff --git a/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php b/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php index 6ee4df4a76..ca7dee2acf 100644 --- a/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php +++ b/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php @@ -1,409 +1,398 @@ array( 'headers' => self::SERIALIZATION_JSON, 'bodies' => self::SERIALIZATION_JSON, 'attachments' => self::SERIALIZATION_JSON, ), ) + parent::getConfiguration(); } public function setHeaders(array $headers) { // Normalize headers to lowercase. $normalized = array(); foreach ($headers as $name => $value) { $normalized[strtolower($name)] = $value; } $this->headers = $normalized; return $this; } public function getMessageID() { return idx($this->headers, 'message-id'); } public function getSubject() { return idx($this->headers, 'subject'); } public function getCCAddresses() { return $this->getRawEmailAddresses(idx($this->headers, 'cc')); } public function getToAddresses() { return $this->getRawEmailAddresses(idx($this->headers, 'to')); } private function loadExcludeMailRecipientPHIDs() { $addresses = array_merge( $this->getToAddresses(), $this->getCCAddresses() ); return $this->loadPHIDsFromAddresses($addresses); } final public function loadCCPHIDs() { return $this->loadPHIDsFromAddresses($this->getCCAddresses()); } private function loadPHIDsFromAddresses(array $addresses) { if (empty($addresses)) { return array(); } $users = id(new PhabricatorUserEmail()) ->loadAllWhere('address IN (%Ls)', $addresses); $user_phids = mpull($users, 'getUserPHID'); $mailing_lists = id(new PhabricatorMetaMTAMailingList()) ->loadAllWhere('email in (%Ls)', $addresses); $mailing_list_phids = mpull($mailing_lists, 'getPHID'); return array_merge($user_phids, $mailing_list_phids); } /** * Parses "to" addresses, looking for a public create email address * first and if not found parsing the "to" address for reply handler * information: receiver name, user id, and hash. */ private function getPhabricatorToInformation() { // Only one "public" create address so far $create_task = PhabricatorEnv::getEnvConfig( 'metamta.maniphest.public-create-email'); // For replies, look for an object address with a format like: // D291+291+b0a41ca848d66dcc@example.com $single_handle_prefix = PhabricatorEnv::getEnvConfig( 'metamta.single-reply-handler-prefix'); $prefixPattern = ($single_handle_prefix) ? preg_quote($single_handle_prefix, '/') . '\+' : ''; - $pattern = "/^{$prefixPattern}((?:D|T|C)\d+)\+([\w]+)\+([a-f0-9]{16})@/U"; + $pattern = "/^{$prefixPattern}((?:D|T|C|E)\d+)\+([\w]+)\+([a-f0-9]{16})@/U"; $phabricator_address = null; $receiver_name = null; $user_id = null; $hash = null; foreach ($this->getToAddresses() as $address) { if ($address == $create_task) { $phabricator_address = $address; // it's okay to stop here because we just need to map a create // address to an application and don't need / won't have more // information in these cases. break; } $matches = null; $ok = preg_match( $pattern, $address, $matches); if ($ok) { $phabricator_address = $address; $receiver_name = $matches[1]; $user_id = $matches[2]; $hash = $matches[3]; break; } } return array( $phabricator_address, $receiver_name, $user_id, $hash ); } public function processReceivedMail() { // If Phabricator sent the mail, always drop it immediately. This prevents // loops where, e.g., the public bug address is also a user email address // and creating a bug sends them an email, which loops. $is_phabricator_mail = idx( $this->headers, 'x-phabricator-sent-this-message'); if ($is_phabricator_mail) { $message = "Ignoring email with 'X-Phabricator-Sent-This-Message' ". "header to avoid loops."; return $this->setMessage($message)->save(); } $message_id_hash = $this->getMessageIDHash(); if ($message_id_hash) { $messages = $this->loadAllWhere( 'messageIDHash = %s', $message_id_hash ); $messages_count = count($messages); if ($messages_count > 1) { $first_message = reset($messages); if ($first_message->getID() != $this->getID()) { $message = sprintf( 'Ignoring email with message id hash "%s" that has been seen %d '. 'times, including this message.', $message_id_hash, $messages_count ); return $this->setMessage($message)->save(); } } } list($to, $receiver_name, $user_id, $hash) = $this->getPhabricatorToInformation(); if (!$to) { $raw_to = idx($this->headers, 'to'); return $this->setMessage("Unrecognized 'to' format: {$raw_to}")->save(); } $from = idx($this->headers, 'from'); // TODO -- make this a switch statement / better if / when we add more // public create email addresses! $create_task = PhabricatorEnv::getEnvConfig( 'metamta.maniphest.public-create-email'); if ($create_task && $to == $create_task) { $receiver = new ManiphestTask(); $user = $this->lookupPublicUser(); if ($user) { $this->setAuthorPHID($user->getPHID()); } else { $default_author = PhabricatorEnv::getEnvConfig( 'metamta.maniphest.default-public-author'); if ($default_author) { $user = id(new PhabricatorUser())->loadOneWhere( 'username = %s', $default_author); if ($user) { $receiver->setOriginalEmailSource($from); } else { throw new Exception( "Phabricator is misconfigured, the configuration key ". "'metamta.maniphest.default-public-author' is set to user ". "'{$default_author}' but that user does not exist."); } } else { // TODO: We should probably bounce these since from the user's // perspective their email vanishes into a black hole. return $this->setMessage("Invalid public user '{$from}'.")->save(); } } $receiver->setAuthorPHID($user->getPHID()); $receiver->setPriority(ManiphestTaskPriority::PRIORITY_TRIAGE); $editor = new ManiphestTransactionEditor(); $editor->setActor($user); $handler = $editor->buildReplyHandler($receiver); $handler->setActor($user); $handler->setExcludeMailRecipientPHIDs( $this->loadExcludeMailRecipientPHIDs()); $handler->processEmail($this); $this->setRelatedPHID($receiver->getPHID()); $this->setMessage('OK'); return $this->save(); } if ($user_id == 'public') { if (!PhabricatorEnv::getEnvConfig('metamta.public-replies')) { return $this->setMessage("Public replies not enabled.")->save(); } $user = $this->lookupPublicUser(); if (!$user) { return $this->setMessage("Invalid public user '{$from}'.")->save(); } $use_user_hash = false; } else { $user = id(new PhabricatorUser())->load($user_id); if (!$user) { return $this->setMessage("Invalid private user '{$user_id}'.")->save(); } $use_user_hash = true; } if ($user->getIsDisabled()) { return $this->setMessage("User '{$user_id}' is disabled")->save(); } $this->setAuthorPHID($user->getPHID()); $receiver = self::loadReceiverObject($receiver_name); if (!$receiver) { return $this->setMessage("Invalid object '{$receiver_name}'")->save(); } $this->setRelatedPHID($receiver->getPHID()); if ($use_user_hash) { // This is a private reply-to address, check that the user hash is // correct. $check_phid = $user->getPHID(); } else { // This is a public reply-to address, check that the object hash is // correct. $check_phid = $receiver->getPHID(); } $expect_hash = self::computeMailHash($receiver->getMailKey(), $check_phid); - // See note at computeOldMailHash(). - $old_hash = self::computeOldMailHash($receiver->getMailKey(), $check_phid); - - if ($expect_hash != $hash && $old_hash != $hash) { + if ($expect_hash != $hash) { return $this->setMessage("Invalid mail hash!")->save(); } if ($receiver instanceof ManiphestTask) { $editor = new ManiphestTransactionEditor(); $editor->setActor($user); $handler = $editor->buildReplyHandler($receiver); } else if ($receiver instanceof DifferentialRevision) { $handler = DifferentialMail::newReplyHandlerForRevision($receiver); } else if ($receiver instanceof PhabricatorRepositoryCommit) { $handler = PhabricatorAuditCommentEditor::newReplyHandlerForCommit( $receiver); + } else if ($receiver instanceof ConpherenceThread) { + $handler = id(new ConpherenceReplyHandler()) + ->setMailReceiver($receiver); } $handler->setActor($user); $handler->setExcludeMailRecipientPHIDs( $this->loadExcludeMailRecipientPHIDs()); $handler->processEmail($this); $this->setMessage('OK'); return $this->save(); } public function getCleanTextBody() { $body = idx($this->bodies, 'text'); $parser = new PhabricatorMetaMTAEmailBodyParser(); return $parser->stripTextBody($body); } public function getRawTextBody() { return idx($this->bodies, 'text'); } public static function loadReceiverObject($receiver_name) { if (!$receiver_name) { return null; } $receiver_type = $receiver_name[0]; $receiver_id = substr($receiver_name, 1); $class_obj = null; switch ($receiver_type) { case 'T': $class_obj = new ManiphestTask(); break; case 'D': $class_obj = new DifferentialRevision(); break; case 'C': $class_obj = new PhabricatorRepositoryCommit(); break; + case 'E': + $class_obj = new ConpherenceThread(); + break; default: return null; } return $class_obj->load($receiver_id); } public static function computeMailHash($mail_key, $phid) { $global_mail_key = PhabricatorEnv::getEnvConfig('phabricator.mail-key'); $hash = PhabricatorHash::digest($mail_key.$global_mail_key.$phid); return substr($hash, 0, 16); } - public static function computeOldMailHash($mail_key, $phid) { - - // TODO: Remove this method entirely in a couple of months. We've moved from - // plain sha1 to sha1+hmac to make the codebase more auditable for good uses - // of hash functions, but still accept the old hashes on email replies to - // avoid breaking things. Once we've been sending only hmac hashes for a - // while, remove this and start rejecting old hashes. See T547. - - $global_mail_key = PhabricatorEnv::getEnvConfig('phabricator.mail-key'); - - $hash = sha1($mail_key.$global_mail_key.$phid); - return substr($hash, 0, 16); - } - /** * Strip an email address down to the actual user@domain.tld part if * necessary, since sometimes it will have formatting like * '"Abraham Lincoln" '. */ private function getRawEmailAddress($address) { $matches = null; $ok = preg_match('/<(.*)>/', $address, $matches); if ($ok) { $address = $matches[1]; } return $address; } private function getRawEmailAddresses($addresses) { $raw_addresses = array(); foreach (explode(',', $addresses) as $address) { $raw_addresses[] = $this->getRawEmailAddress($address); } return array_filter($raw_addresses); } private function lookupPublicUser() { $from = idx($this->headers, 'from'); $from = $this->getRawEmailAddress($from); $user = PhabricatorUser::loadOneWithEmailAddress($from); // If Phabricator is configured to allow "Reply-To" authentication, try // the "Reply-To" address if we failed to match the "From" address. $config_key = 'metamta.insecure-auth-with-reply-to'; $allow_reply_to = PhabricatorEnv::getEnvConfig($config_key); if (!$user && $allow_reply_to) { $reply_to = idx($this->headers, 'reply-to'); $reply_to = $this->getRawEmailAddress($reply_to); if ($reply_to) { $user = PhabricatorUser::loadOneWithEmailAddress($reply_to); } } return $user; } } diff --git a/src/applications/phid/handle/PhabricatorObjectHandleData.php b/src/applications/phid/handle/PhabricatorObjectHandleData.php index aad3a4a326..8b216e8f5a 100644 --- a/src/applications/phid/handle/PhabricatorObjectHandleData.php +++ b/src/applications/phid/handle/PhabricatorObjectHandleData.php @@ -1,714 +1,714 @@ phids = array_unique($phids); } public function setViewer(PhabricatorUser $viewer) { $this->viewer = $viewer; return $this; } public static function loadOneHandle($phid, $viewer = null) { $query = new PhabricatorObjectHandleData(array($phid)); if ($viewer) { $query->setViewer($viewer); } $handles = $query->loadHandles(); return $handles[$phid]; } public function loadObjects() { $types = array(); foreach ($this->phids as $phid) { $type = phid_get_type($phid); $types[$type][] = $phid; } $objects = array(); foreach ($types as $type => $phids) { switch ($type) { case PhabricatorPHIDConstants::PHID_TYPE_USER: $user_dao = new PhabricatorUser(); $users = $user_dao->loadAllWhere( 'phid in (%Ls)', $phids); foreach ($users as $user) { $objects[$user->getPHID()] = $user; } break; case PhabricatorPHIDConstants::PHID_TYPE_CMIT: $commit_dao = new PhabricatorRepositoryCommit(); $commits = $commit_dao->loadAllWhere( 'phid IN (%Ls)', $phids); $commit_data = array(); if ($commits) { $data_dao = new PhabricatorRepositoryCommitData(); $commit_data = $data_dao->loadAllWhere( 'commitID IN (%Ld)', mpull($commits, 'getID')); $commit_data = mpull($commit_data, null, 'getCommitID'); } foreach ($commits as $commit) { $data = idx($commit_data, $commit->getID()); if ($data) { $commit->attachCommitData($data); $objects[$commit->getPHID()] = $commit; } else { // If we couldn't load the commit data, just act as though we // couldn't load the object at all so we don't load half an object. } } break; case PhabricatorPHIDConstants::PHID_TYPE_TASK: $task_dao = new ManiphestTask(); $tasks = $task_dao->loadAllWhere( 'phid IN (%Ls)', $phids); foreach ($tasks as $task) { $objects[$task->getPHID()] = $task; } break; case PhabricatorPHIDConstants::PHID_TYPE_CONF: $config_dao = new PhabricatorConfigEntry(); $entries = $config_dao->loadAllWhere( 'phid IN (%Ls)', $phids); foreach ($entries as $entry) { $objects[$entry->getPHID()] = $entry; } break; case PhabricatorPHIDConstants::PHID_TYPE_DREV: $revision_dao = new DifferentialRevision(); $revisions = $revision_dao->loadAllWhere( 'phid IN (%Ls)', $phids); foreach ($revisions as $revision) { $objects[$revision->getPHID()] = $revision; } break; case PhabricatorPHIDConstants::PHID_TYPE_WIKI: $document_dao = new PhrictionDocument(); $documents = $document_dao->loadAllWhere( 'phid IN (%Ls)', $phids); foreach ($documents as $document) { $objects[$document->getPHID()] = $document; } break; case PhabricatorPHIDConstants::PHID_TYPE_QUES: $questions = id(new PonderQuestionQuery()) ->setViewer($this->viewer) ->withPHIDs($phids) ->execute(); foreach ($questions as $question) { $objects[$question->getPHID()] = $question; } break; case PhabricatorPHIDConstants::PHID_TYPE_MOCK: $mocks = id(new PholioMockQuery()) ->setViewer($this->viewer) ->withPHIDs($phids) ->execute(); foreach ($mocks as $mock) { $objects[$mock->getPHID()] = $mock; } break; case PhabricatorPHIDConstants::PHID_TYPE_XACT: $subtypes = array(); foreach ($phids as $phid) { $subtypes[phid_get_subtype($phid)][] = $phid; } $xactions = array(); foreach ($subtypes as $subtype => $subtype_phids) { // TODO: Do this magically. switch ($subtype) { case PhabricatorPHIDConstants::PHID_TYPE_MOCK: $results = id(new PholioTransactionQuery()) ->setViewer($this->viewer) ->withPHIDs($subtype_phids) ->execute(); $xactions += mpull($results, null, 'getPHID'); break; case PhabricatorPHIDConstants::PHID_TYPE_MCRO: $results = id(new PhabricatorMacroTransactionQuery()) ->setViewer($this->viewer) ->withPHIDs($subtype_phids) ->execute(); $xactions += mpull($results, null, 'getPHID'); break; } } foreach ($xactions as $xaction) { $objects[$xaction->getPHID()] = $xaction; } break; case PhabricatorPHIDConstants::PHID_TYPE_MCRO: $macros = id(new PhabricatorFileImageMacro())->loadAllWhere( 'phid IN (%Ls)', $phids); $objects += mpull($macros, null, 'getPHID'); break; } } return $objects; } public function loadHandles() { $types = phid_group_by_type($this->phids); $handles = array(); $external_loaders = PhabricatorEnv::getEnvConfig('phid.external-loaders'); foreach ($types as $type => $phids) { switch ($type) { case PhabricatorPHIDConstants::PHID_TYPE_MAGIC: // Black magic! foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setPHID($phid); $handle->setType($type); switch ($phid) { case ManiphestTaskOwner::OWNER_UP_FOR_GRABS: $handle->setName('Up For Grabs'); $handle->setFullName('upforgrabs (Up For Grabs)'); $handle->setComplete(true); break; case ManiphestTaskOwner::PROJECT_NO_PROJECT: $handle->setName('No Project'); $handle->setFullName('noproject (No Project)'); $handle->setComplete(true); break; default: $handle->setName('Foul Magicks'); break; } $handles[$phid] = $handle; } break; case PhabricatorPHIDConstants::PHID_TYPE_USER: $object = new PhabricatorUser(); $users = $object->loadAllWhere('phid IN (%Ls)', $phids); $users = mpull($users, null, 'getPHID'); $image_phids = mpull($users, 'getProfileImagePHID'); $image_phids = array_unique(array_filter($image_phids)); $images = array(); if ($image_phids) { $images = id(new PhabricatorFile())->loadAllWhere( 'phid IN (%Ls)', $image_phids); $images = mpull($images, 'getBestURI', 'getPHID'); } $statuses = id(new PhabricatorUserStatus())->loadCurrentStatuses( $phids); foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setPHID($phid); $handle->setType($type); if (empty($users[$phid])) { $handle->setName('Unknown User'); } else { $user = $users[$phid]; $handle->setName($user->getUsername()); $handle->setURI('/p/'.$user->getUsername().'/'); $handle->setFullName( $user->getUsername().' ('.$user->getRealName().')'); $handle->setAlternateID($user->getID()); $handle->setComplete(true); if (isset($statuses[$phid])) { $handle->setStatus($statuses[$phid]->getTextStatus()); if ($this->viewer) { $handle->setTitle( $statuses[$phid]->getTerseSummary($this->viewer)); } } $handle->setDisabled($user->getIsDisabled()); $img_uri = idx($images, $user->getProfileImagePHID()); if ($img_uri) { $handle->setImageURI($img_uri); } else { $handle->setImageURI( PhabricatorUser::getDefaultProfileImageURI()); } } $handles[$phid] = $handle; } break; case PhabricatorPHIDConstants::PHID_TYPE_MLST: $object = new PhabricatorMetaMTAMailingList(); $lists = $object->loadAllWhere('phid IN (%Ls)', $phids); $lists = mpull($lists, null, 'getPHID'); foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setPHID($phid); $handle->setType($type); if (empty($lists[$phid])) { $handle->setName('Unknown Mailing List'); } else { $list = $lists[$phid]; $handle->setName($list->getName()); $handle->setURI($list->getURI()); $handle->setFullName($list->getName()); $handle->setComplete(true); } $handles[$phid] = $handle; } break; case PhabricatorPHIDConstants::PHID_TYPE_DREV: $object = new DifferentialRevision(); $revs = $object->loadAllWhere('phid in (%Ls)', $phids); $revs = mpull($revs, null, 'getPHID'); foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setPHID($phid); $handle->setType($type); if (empty($revs[$phid])) { $handle->setName('Unknown Revision'); } else { $rev = $revs[$phid]; $handle->setName($rev->getTitle()); $handle->setURI('/D'.$rev->getID()); $handle->setFullName('D'.$rev->getID().': '.$rev->getTitle()); $handle->setComplete(true); $status = $rev->getStatus(); if (($status == ArcanistDifferentialRevisionStatus::CLOSED) || ($status == ArcanistDifferentialRevisionStatus::ABANDONED)) { $closed = PhabricatorObjectHandleStatus::STATUS_CLOSED; $handle->setStatus($closed); } } $handles[$phid] = $handle; } break; case PhabricatorPHIDConstants::PHID_TYPE_CMIT: $object = new PhabricatorRepositoryCommit(); $commits = $object->loadAllWhere('phid in (%Ls)', $phids); $commits = mpull($commits, null, 'getPHID'); $repository_ids = array(); $callsigns = array(); if ($commits) { $repository_ids = mpull($commits, 'getRepositoryID'); $repositories = id(new PhabricatorRepository())->loadAllWhere( 'id in (%Ld)', array_unique($repository_ids)); $callsigns = mpull($repositories, 'getCallsign'); } foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setPHID($phid); $handle->setType($type); if (empty($commits[$phid]) || !isset($callsigns[$repository_ids[$phid]])) { $handle->setName('Unknown Commit'); } else { $commit = $commits[$phid]; $callsign = $callsigns[$repository_ids[$phid]]; $repository = $repositories[$repository_ids[$phid]]; $commit_identifier = $commit->getCommitIdentifier(); // In case where the repository for the commit was deleted, // we don't have have info about the repository anymore. if ($repository) { $name = $repository->formatCommitName($commit_identifier); $handle->setName($name); } else { $handle->setName('Commit '.'r'.$callsign.$commit_identifier); } $handle->setURI('/r'.$callsign.$commit_identifier); $handle->setFullName('r'.$callsign.$commit_identifier); $handle->setTimestamp($commit->getEpoch()); $handle->setComplete(true); } $handles[$phid] = $handle; } break; case PhabricatorPHIDConstants::PHID_TYPE_TASK: $object = new ManiphestTask(); $tasks = $object->loadAllWhere('phid in (%Ls)', $phids); $tasks = mpull($tasks, null, 'getPHID'); foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setPHID($phid); $handle->setType($type); if (empty($tasks[$phid])) { $handle->setName('Unknown Task'); } else { $task = $tasks[$phid]; $handle->setName($task->getTitle()); $handle->setURI('/T'.$task->getID()); $handle->setFullName('T'.$task->getID().': '.$task->getTitle()); $handle->setComplete(true); $handle->setAlternateID($task->getID()); if ($task->getStatus() != ManiphestTaskStatus::STATUS_OPEN) { $closed = PhabricatorObjectHandleStatus::STATUS_CLOSED; $handle->setStatus($closed); } } $handles[$phid] = $handle; } break; case PhabricatorPHIDConstants::PHID_TYPE_CONF: $object = new PhabricatorConfigEntry(); $entries = $object->loadAllWhere('phid in (%Ls)', $phids); $entries = mpull($entries, null, 'getPHID'); foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setPHID($phid); $handle->setType($type); if (empty($entries[$phid])) { $handle->setName('Unknown Config Entry'); } else { - $entry = $entry[$phid]; + $entry = $entries[$phid]; $handle->setName($entry->getKey()); $handle->setURI('/config/edit/'.$entry->getKey()); $handle->setFullName($entry->getKey()); $handle->setComplete(true); } $handles[$phid] = $handle; } break; case PhabricatorPHIDConstants::PHID_TYPE_FILE: $object = new PhabricatorFile(); $files = $object->loadAllWhere('phid IN (%Ls)', $phids); $files = mpull($files, null, 'getPHID'); foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setPHID($phid); $handle->setType($type); if (empty($files[$phid])) { $handle->setName('Unknown File'); } else { $file = $files[$phid]; $handle->setName($file->getName()); $handle->setURI($file->getBestURI()); $handle->setComplete(true); if ($file->isViewableImage()) { $handle->setImageURI($file->getBestURI()); } } $handles[$phid] = $handle; } break; case PhabricatorPHIDConstants::PHID_TYPE_PROJ: $object = new PhabricatorProject(); if ($this->viewer) { $projects = id(new PhabricatorProjectQuery()) ->setViewer($this->viewer) ->withPHIDs($phids) ->execute(); } else { $projects = $object->loadAllWhere('phid IN (%Ls)', $phids); } $projects = mpull($projects, null, 'getPHID'); foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setPHID($phid); $handle->setType($type); if (empty($projects[$phid])) { $handle->setName('Unknown Project'); } else { $project = $projects[$phid]; $handle->setName($project->getName()); $handle->setURI('/project/view/'.$project->getID().'/'); $handle->setComplete(true); } $handles[$phid] = $handle; } break; case PhabricatorPHIDConstants::PHID_TYPE_REPO: $object = new PhabricatorRepository(); $repositories = $object->loadAllWhere('phid in (%Ls)', $phids); $repositories = mpull($repositories, null, 'getPHID'); foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setPHID($phid); $handle->setType($type); if (empty($repositories[$phid])) { $handle->setName('Unknown Repository'); } else { $repository = $repositories[$phid]; $handle->setName($repository->getCallsign()); $handle->setURI('/diffusion/'.$repository->getCallsign().'/'); $handle->setComplete(true); } $handles[$phid] = $handle; } break; case PhabricatorPHIDConstants::PHID_TYPE_OPKG: $object = new PhabricatorOwnersPackage(); $packages = $object->loadAllWhere('phid in (%Ls)', $phids); $packages = mpull($packages, null, 'getPHID'); foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setPHID($phid); $handle->setType($type); if (empty($packages[$phid])) { $handle->setName('Unknown Package'); } else { $package = $packages[$phid]; $handle->setName($package->getName()); $handle->setURI('/owners/package/'.$package->getID().'/'); $handle->setComplete(true); } $handles[$phid] = $handle; } break; case PhabricatorPHIDConstants::PHID_TYPE_APRJ: $project_dao = new PhabricatorRepositoryArcanistProject(); $projects = $project_dao->loadAllWhere( 'phid IN (%Ls)', $phids); $projects = mpull($projects, null, 'getPHID'); foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setPHID($phid); $handle->setType($type); if (empty($projects[$phid])) { $handle->setName('Unknown Arcanist Project'); } else { $project = $projects[$phid]; $handle->setName($project->getName()); $handle->setComplete(true); } $handles[$phid] = $handle; } break; case PhabricatorPHIDConstants::PHID_TYPE_WIKI: $document_dao = new PhrictionDocument(); $content_dao = new PhrictionContent(); $conn = $document_dao->establishConnection('r'); $documents = queryfx_all( $conn, 'SELECT * FROM %T document JOIN %T content ON document.contentID = content.id WHERE document.phid IN (%Ls)', $document_dao->getTableName(), $content_dao->getTableName(), $phids); $documents = ipull($documents, null, 'phid'); foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setPHID($phid); $handle->setType($type); if (empty($documents[$phid])) { $handle->setName('Unknown Document'); } else { $info = $documents[$phid]; $handle->setName($info['title']); $handle->setURI(PhrictionDocument::getSlugURI($info['slug'])); $handle->setComplete(true); if ($info['status'] != PhrictionDocumentStatus::STATUS_EXISTS) { $closed = PhabricatorObjectHandleStatus::STATUS_CLOSED; $handle->setStatus($closed); } } $handles[$phid] = $handle; } break; case PhabricatorPHIDConstants::PHID_TYPE_QUES: $questions = id(new PonderQuestionQuery()) ->setViewer($this->viewer) ->withPHIDs($phids) ->execute(); $questions = mpull($questions, null, 'getPHID'); foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setPHID($phid); $handle->setType($type); if (empty($questions[$phid])) { $handle->setName('Unknown Ponder Question'); } else { $question = $questions[$phid]; $handle->setName(phutil_utf8_shorten($question->getTitle(), 60)); $handle->setURI(new PhutilURI('/Q' . $question->getID())); $handle->setComplete(true); } $handles[$phid] = $handle; } break; case PhabricatorPHIDConstants::PHID_TYPE_PSTE: $pastes = id(new PhabricatorPasteQuery()) ->withPHIDs($phids) ->setViewer($this->viewer) ->execute(); $pastes = mpull($pastes, null, 'getPHID'); foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setPHID($phid); $handle->setType($type); if (empty($pastes[$phid])) { $handle->setName('Unknown Paste'); } else { $paste = $pastes[$phid]; $handle->setName($paste->getTitle()); $handle->setFullName($paste->getFullName()); $handle->setURI('/P'.$paste->getID()); $handle->setComplete(true); } $handles[$phid] = $handle; } break; case PhabricatorPHIDConstants::PHID_TYPE_BLOG: $blogs = id(new PhameBlogQuery()) ->withPHIDs($phids) ->setViewer($this->viewer) ->execute(); $blogs = mpull($blogs, null, 'getPHID'); foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setPHID($phid); $handle->setType($type); if (empty($blogs[$phid])) { $handle->setName('Unknown Blog'); } else { $blog = $blogs[$phid]; $handle->setName($blog->getName()); $handle->setFullName($blog->getName()); $handle->setURI('/phame/blog/view/'.$blog->getID().'/'); $handle->setComplete(true); } $handles[$phid] = $handle; } break; case PhabricatorPHIDConstants::PHID_TYPE_POST: $posts = id(new PhamePostQuery()) ->withPHIDs($phids) ->setViewer($this->viewer) ->execute(); $posts = mpull($posts, null, 'getPHID'); foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setPHID($phid); $handle->setType($type); if (empty($posts[$phid])) { $handle->setName('Unknown Post'); } else { $post = $posts[$phid]; $handle->setName($post->getTitle()); $handle->setFullName($post->getTitle()); $handle->setURI('/phame/post/view/'.$post->getID().'/'); $handle->setComplete(true); } $handles[$phid] = $handle; } break; case PhabricatorPHIDConstants::PHID_TYPE_MOCK: $mocks = id(new PholioMockQuery()) ->withPHIDs($phids) ->setViewer($this->viewer) ->execute(); $mocks = mpull($mocks, null, 'getPHID'); foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setPHID($phid); $handle->setType($type); if (empty($mocks[$phid])) { $handle->setName('Unknown Mock'); } else { $mock = $mocks[$phid]; $handle->setName($mock->getName()); $handle->setFullName('M'.$mock->getID().': '.$mock->getName()); $handle->setURI('/M'.$mock->getID()); $handle->setComplete(true); } $handles[$phid] = $handle; } break; case PhabricatorPHIDConstants::PHID_TYPE_MCRO: $macros = id(new PhabricatorFileImageMacro())->loadAllWhere( 'phid IN (%Ls)', $phids); $macros = mpull($macros, null, 'getPHID'); foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setPHID($phid); $handle->setType($type); if (empty($macros[$phid])) { $handle->setName('Unknown Macro'); } else { $macro = $macros[$phid]; $handle->setName($macro->getName()); $handle->setFullName('Image Macro "'.$macro->getName().'"'); $handle->setURI('/macro/view/'.$macro->getID().'/'); $handle->setComplete(true); } $handles[$phid] = $handle; } break; default: $loader = null; if (isset($external_loaders[$type])) { $loader = $external_loaders[$type]; } else if (isset($external_loaders['*'])) { $loader = $external_loaders['*']; } if ($loader) { $object = newv($loader, array()); assert_instances_of(array($type => $object), 'ObjectHandleLoader'); $handles += $object->loadHandles($phids); break; } foreach ($phids as $phid) { $handle = new PhabricatorObjectHandle(); $handle->setType($type); $handle->setPHID($phid); $handle->setName('Unknown Object'); $handle->setFullName('An Unknown Object'); $handles[$phid] = $handle; } break; } } return $handles; } } diff --git a/src/applications/pholio/controller/PholioMockListController.php b/src/applications/pholio/controller/PholioMockListController.php index 943eab946a..5c456ec53d 100644 --- a/src/applications/pholio/controller/PholioMockListController.php +++ b/src/applications/pholio/controller/PholioMockListController.php @@ -1,62 +1,64 @@ view = idx($data, 'view'); } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $query = id(new PholioMockQuery()) - ->setViewer($user); + ->setViewer($user) + ->needCoverFiles(true); $nav = $this->buildSideNav(); $filter = $nav->selectFilter('view/'.$this->view, 'view/all'); switch ($filter) { case 'view/all': default: $title = 'All Mocks'; break; } $pager = new AphrontCursorPagerView(); $pager->readFromRequest($request); $mocks = $query->executeWithCursorPager($pager); $board = new PhabricatorPinboardView(); foreach ($mocks as $mock) { $board->addItem( id(new PhabricatorPinboardItemView()) ->setHeader($mock->getName()) - ->setURI('/M'.$mock->getID())); + ->setURI('/M'.$mock->getID()) + ->setImageURI($mock->getCoverFile()->getThumb160x120URI())); } $header = id(new PhabricatorHeaderView()) ->setHeader($title); $content = array( $header, $board, $pager, ); $nav->appendChild($content); return $this->buildApplicationPage( $nav, array( 'title' => $title, )); } } diff --git a/src/applications/pholio/controller/PholioMockViewController.php b/src/applications/pholio/controller/PholioMockViewController.php index b15149ac34..0bf0022fe1 100644 --- a/src/applications/pholio/controller/PholioMockViewController.php +++ b/src/applications/pholio/controller/PholioMockViewController.php @@ -1,192 +1,194 @@ id = $data['id']; } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $mock = id(new PholioMockQuery()) ->setViewer($user) ->withIDs(array($this->id)) + ->needImages(true) + ->needCoverFiles(true) ->executeOne(); if (!$mock) { return new Aphront404Response(); } $xactions = id(new PholioTransactionQuery()) ->setViewer($user) ->withObjectPHIDs(array($mock->getPHID())) ->execute(); $subscribers = PhabricatorSubscribersQuery::loadSubscribersForPHID( $mock->getPHID()); $phids = array(); $phids[] = $mock->getAuthorPHID(); foreach ($subscribers as $subscriber) { $phids[] = $subscriber; } $this->loadHandles($phids); $engine = id(new PhabricatorMarkupEngine()) ->setViewer($user); $engine->addObject($mock, PholioMock::MARKUP_FIELD_DESCRIPTION); foreach ($xactions as $xaction) { if ($xaction->getComment()) { $engine->addObject( $xaction->getComment(), PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT); } } $engine->process(); $title = 'M'.$mock->getID().' '.$mock->getName(); $header = id(new PhabricatorHeaderView()) ->setHeader($title); $actions = $this->buildActionView($mock); $properties = $this->buildPropertyView($mock, $engine, $subscribers); require_celerity_resource('pholio-css'); $output = new PholioMockImagesView(); $output->setMock($mock); $carousel = $output->render(); $xaction_view = id(new PhabricatorApplicationTransactionView()) ->setUser($this->getRequest()->getUser()) ->setTransactions($xactions) ->setMarkupEngine($engine); $add_comment = $this->buildAddCommentView($mock); $content = array( $header, $actions, $properties, $carousel, $xaction_view, $add_comment, ); return $this->buildApplicationPage( $content, array( 'title' => $title, 'device' => true, )); } private function buildActionView(PholioMock $mock) { $user = $this->getRequest()->getUser(); $actions = id(new PhabricatorActionListView()) ->setUser($user) ->setObject($mock); $can_edit = PhabricatorPolicyFilter::hasCapability( $user, $mock, PhabricatorPolicyCapability::CAN_EDIT); $actions->addAction( id(new PhabricatorActionView()) ->setIcon('edit') ->setName(pht('Edit Mock')) ->setHref($this->getApplicationURI('/edit/'.$mock->getID())) ->setDisabled(!$can_edit) ->setWorkflow(!$can_edit)); return $actions; } private function buildPropertyView( PholioMock $mock, PhabricatorMarkupEngine $engine, array $subscribers) { $user = $this->getRequest()->getUser(); $properties = new PhabricatorPropertyListView(); $properties->addProperty( pht('Author'), $this->getHandle($mock->getAuthorPHID())->renderLink()); $properties->addProperty( pht('Created'), phabricator_datetime($mock->getDateCreated(), $user)); $descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions( $user, $mock); $properties->addProperty( pht('Visible To'), $descriptions[PhabricatorPolicyCapability::CAN_VIEW]); if ($subscribers) { $sub_view = array(); foreach ($subscribers as $subscriber) { $sub_view[] = $this->getHandle($subscriber)->renderLink(); } $sub_view = implode(', ', $sub_view); } else { $sub_view = ''.pht('None').''; } $properties->addProperty( pht('Subscribers'), $sub_view); $properties->addTextContent( $engine->getOutput($mock, PholioMock::MARKUP_FIELD_DESCRIPTION)); return $properties; } private function buildAddCommentView(PholioMock $mock) { $user = $this->getRequest()->getUser(); $draft = PhabricatorDraft::newFromUserAndKey($user, $mock->getPHID()); $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business'); $title = $is_serious ? pht('Add Comment') : pht('History Beckons'); $header = id(new PhabricatorHeaderView()) ->setHeader($title); $button_name = $is_serious ? pht('Add Comment') : pht('Answer The Call'); $form = id(new PhabricatorApplicationTransactionCommentView()) ->setUser($user) ->setDraft($draft) ->setSubmitButtonName($button_name) ->setAction($this->getApplicationURI('/comment/'.$mock->getID().'/')); return array( $header, $form, ); } } diff --git a/src/applications/pholio/query/PholioMockQuery.php b/src/applications/pholio/query/PholioMockQuery.php index 5aa6a5911b..bbd56e9f5f 100644 --- a/src/applications/pholio/query/PholioMockQuery.php +++ b/src/applications/pholio/query/PholioMockQuery.php @@ -1,72 +1,130 @@ ids = $ids; return $this; } public function withPHIDs(array $phids) { $this->phids = $phids; return $this; } public function withAuthorPHIDs(array $author_phids) { $this->authorPHIDs = $author_phids; return $this; } public function loadPage() { $table = new PholioMock(); $conn_r = $table->establishConnection('r'); $data = queryfx_all( $conn_r, 'SELECT * FROM %T %Q %Q %Q', $table->getTableName(), $this->buildWhereClause($conn_r), $this->buildOrderClause($conn_r), $this->buildLimitClause($conn_r)); - return $table->loadAllFromArray($data); + $mocks = $table->loadAllFromArray($data); + + if ($mocks && $this->needImages) { + $this->loadImages($mocks); + } + if ($mocks && $this->needCoverFiles) { + $this->loadCoverFiles($mocks); + } + + + return $mocks; } private function buildWhereClause(AphrontDatabaseConnection $conn_r) { $where = array(); $where[] = $this->buildPagingClause($conn_r); if ($this->ids) { $where[] = qsprintf( $conn_r, 'id IN (%Ld)', $this->ids); } if ($this->phids) { $where[] = qsprintf( $conn_r, 'phid IN (%Ls)', $this->phids); } if ($this->authorPHIDs) { $where[] = qsprintf( $conn_r, 'authorPHID in (%Ls)', $this->authorPHIDs); } return $this->formatWhereClause($where); } + public function needCoverFiles($need_cover_files) { + $this->needCoverFiles = $need_cover_files; + return $this; + } + + public function needImages($need_images) { + $this->needImages = $need_images; + return $this; + } + + public function loadImages(array $mocks) { + assert_instances_of($mocks, 'PholioMock'); + + $mock_ids = mpull($mocks, 'getID'); + $all_images = id(new PholioImage())->loadAllWhere( + 'mockID IN (%Ld)', + $mock_ids); + + $file_phids = mpull($all_images, 'getFilePHID'); + $all_files = mpull(id(new PhabricatorFile())->loadAllWhere( + 'phid IN (%Ls)', + $file_phids), null, 'getPHID'); + + foreach ($all_images as $image) { + $image->attachFile($all_files[$image->getFilePHID()]); + } + + $image_groups = mgroup($all_images, 'getMockID'); + + foreach ($mocks as $mock) { + $mock->attachImages($image_groups[$mock->getID()]); + } + } + + public function loadCoverFiles(array $mocks) { + assert_instances_of($mocks, 'PholioMock'); + $cover_file_phids = mpull($mocks, 'getCoverPHID'); + $cover_files = mpull(id(new PhabricatorFile())->loadAllWhere( + 'phid IN (%Ls)', + $cover_file_phids), null, 'getPHID'); + + foreach ($mocks as $mock) { + $mock->attachCoverFile($cover_files[$mock->getCoverPHID()]); + } + } } diff --git a/src/applications/pholio/storage/PholioImage.php b/src/applications/pholio/storage/PholioImage.php index 5525ff45a5..62e1862be1 100644 --- a/src/applications/pholio/storage/PholioImage.php +++ b/src/applications/pholio/storage/PholioImage.php @@ -1,42 +1,55 @@ getMarkupText($field)); return 'M:'.$hash; } public function newMarkupEngine($field) { return PhabricatorMarkupEngine::newMarkupEngine(array()); } public function getMarkupText($field) { return $this->getDescription(); } public function didMarkupText($field, $output, PhutilMarkupEngine $engine) { return $output; } public function shouldUseMarkupCache($field) { return (bool)$this->getID(); } + public function attachFile(PhabricatorFile $file) { + $this->file = $file; + return $this; + } + + public function getFile() { + if ($this->file === null) { + throw new Exception("Call attachFile() before getFile()!"); + } + return $this->file; + } + } diff --git a/src/applications/pholio/storage/PholioMock.php b/src/applications/pholio/storage/PholioMock.php index 177771c95e..986c9685da 100644 --- a/src/applications/pholio/storage/PholioMock.php +++ b/src/applications/pholio/storage/PholioMock.php @@ -1,97 +1,125 @@ true, ) + parent::getConfiguration(); } public function generatePHID() { return PhabricatorPHID::generateNewPHID('MOCK'); } public function save() { if (!$this->getMailKey()) { $this->setMailKey(Filesystem::readRandomCharacters(20)); } return parent::save(); } + public function attachImages(array $images) { + assert_instances_of($images, 'PholioImage'); + $this->images = $images; + return $this; + } + + public function getImages() { + if ($this->images === null) { + throw new Exception("Call attachImages() before getImages()!"); + } + return $this->images; + } + + public function attachCoverFile(PhabricatorFile $file) { + $this->coverFile = $file; + return $this; + } + + public function getCoverFile() { + if ($this->coverFile === null) { + throw new Exception("Call attachCoverFile() before getCoverFile()!"); + } + return $this->coverFile; + } + /* -( PhabricatorSubscribableInterface Implementation )-------------------- */ public function isAutomaticallySubscribed($phid) { return ($this->authorPHID == $phid); } /* -( PhabricatorPolicyInterface Implementation )-------------------------- */ public function getCapabilities() { return array( PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT, ); } public function getPolicy($capability) { switch ($capability) { case PhabricatorPolicyCapability::CAN_VIEW: return $this->getViewPolicy(); case PhabricatorPolicyCapability::CAN_EDIT: return PhabricatorPolicies::POLICY_NOONE; } } public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { return ($viewer->getPHID() == $this->getAuthorPHID()); } /* -( PhabricatorMarkupInterface )----------------------------------------- */ public function getMarkupFieldKey($field) { $hash = PhabricatorHash::digest($this->getMarkupText($field)); return 'M:'.$hash; } public function newMarkupEngine($field) { return PhabricatorMarkupEngine::newMarkupEngine(array()); } public function getMarkupText($field) { return $this->getDescription(); } public function didMarkupText($field, $output, PhutilMarkupEngine $engine) { return $output; } public function shouldUseMarkupCache($field) { return (bool)$this->getID(); } } diff --git a/src/applications/pholio/view/PholioMockImagesView.php b/src/applications/pholio/view/PholioMockImagesView.php index 5658fded90..5b6a28c7fb 100644 --- a/src/applications/pholio/view/PholioMockImagesView.php +++ b/src/applications/pholio/view/PholioMockImagesView.php @@ -1,40 +1,34 @@ mock = $mock; } public function render() { if (!$this->mock) { throw new Exception("Call setMock() before render()!"); } - $image = id(new PholioImage())->loadOneWhere( - "mockid=%d", - $this->mock->getID()); - - $file = id(new PhabricatorFile())->loadOneWhere( - "phid=%s", - $image->getFilePHID()); + $file = head($this->mock->getImages())->getFile(); $image_tag = phutil_tag( 'img', array( 'src' => $file->getBestURI(), 'class' => 'pholio-mock-image', ), ''); return phutil_tag( 'div', array( 'class' => 'pholio-mock-image-container', ), $image_tag); } } diff --git a/src/applications/phortune/control/PhortuneMonthYearExpiryControl.php b/src/applications/phortune/control/PhortuneMonthYearExpiryControl.php index 34aea2791f..a4701aa11c 100644 --- a/src/applications/phortune/control/PhortuneMonthYearExpiryControl.php +++ b/src/applications/phortune/control/PhortuneMonthYearExpiryControl.php @@ -1,91 +1,91 @@ monthValue = $value; return $this; } private function getMonthInputValue() { return $this->monthValue; } private function getCurrentMonth() { return phabricator_format_local_time( time(), $this->getUser(), 'm'); } public function setYearInputValue($value) { $this->yearValue = $value; return $this; } private function getYearInputValue() { return $this->yearValue; } private function getCurrentYear() { return phabricator_format_local_time( time(), $this->getUser(), 'Y'); } protected function getCustomControlClass() { return 'aphront-form-control-text'; } protected function renderInput() { if (!$this->getUser()) { throw new Exception('You must setUser() before render()!'); } // represent months like a credit card does $months = array( '01' => '01', '02' => '02', '03' => '03', '04' => '04', '05' => '05', '06' => '06', '07' => '07', '08' => '08', '09' => '09', '10' => '10', '11' => '11', '12' => '12', ); $current_year = $this->getCurrentYear(); $years = range($current_year, $current_year + 20); - $years = array_combine($years, $years); + $years = array_fuse($years); if ($this->getMonthInputValue()) { $selected_month = $this->getMonthInputValue(); } else { $selected_month = $this->getCurrentMonth(); } $months_sel = AphrontFormSelectControl::renderSelectTag( $selected_month, $months, array( 'sigil' => 'month-input', )); $years_sel = AphrontFormSelectControl::renderSelectTag( $this->getYearInputValue(), $years, array( 'sigil' => 'year-input', )); return self::renderSingleView( array( $months_sel, $years_sel ) ); } } diff --git a/src/applications/phriction/controller/PhrictionDocumentController.php b/src/applications/phriction/controller/PhrictionDocumentController.php index f3c89e9c1c..2e9fe01800 100644 --- a/src/applications/phriction/controller/PhrictionDocumentController.php +++ b/src/applications/phriction/controller/PhrictionDocumentController.php @@ -1,358 +1,369 @@ slug = $data['slug']; } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $slug = PhabricatorSlug::normalize($this->slug); if ($slug != $this->slug) { $uri = PhrictionDocument::getSlugURI($slug); // Canonicalize pages to their one true URI. return id(new AphrontRedirectResponse())->setURI($uri); } require_celerity_resource('phriction-document-css'); $document = id(new PhrictionDocument())->loadOneWhere( 'slug = %s', $slug); $version_note = null; if (!$document) { $document = new PhrictionDocument(); if (PhrictionDocument::isProjectSlug($slug)) { $project = id(new PhabricatorProject())->loadOneWhere( 'phrictionSlug = %s', PhrictionDocument::getProjectSlugIdentifier($slug)); if (!$project) { return new Aphront404Response(); } } $create_uri = '/phriction/edit/?slug='.$slug; $create_sentence = 'You can '. phutil_tag( 'a', array( 'href' => $create_uri, ), 'create a new document'). '.'; $button = phutil_tag( 'a', array( 'href' => $create_uri, 'class' => 'green button', ), 'Create Page'); $page_content = '
    '. 'No content here!
    '. 'No document found at '.phutil_escape_html($slug).'. '. $create_sentence. '
    '; $page_title = 'Page Not Found'; $buttons = $button; } else { $version = $request->getInt('v'); if ($version) { $content = id(new PhrictionContent())->loadOneWhere( 'documentID = %d AND version = %d', $document->getID(), $version); if (!$content) { return new Aphront404Response(); } if ($content->getID() != $document->getContentID()) { $version_note = new AphrontErrorView(); $version_note->setSeverity(AphrontErrorView::SEVERITY_NOTICE); $version_note->setTitle('Older Version'); $version_note->appendChild( 'You are viewing an older version of this document, as it '. 'appeared on '. phabricator_datetime($content->getDateCreated(), $user).'.'); } } else { $content = id(new PhrictionContent())->load($document->getContentID()); } $page_title = $content->getTitle(); $project_phid = null; if (PhrictionDocument::isProjectSlug($slug)) { $project = id(new PhabricatorProject())->loadOneWhere( 'phrictionSlug = %s', PhrictionDocument::getProjectSlugIdentifier($slug)); if ($project) { $project_phid = $project->getPHID(); } } $phids = array_filter( array( $content->getAuthorPHID(), $project_phid, )); $handles = $this->loadViewerHandles($phids); $age = time() - $content->getDateCreated(); $age = floor($age / (60 * 60 * 24)); if ($age < 1) { $when = 'today'; } else if ($age == 1) { $when = 'yesterday'; } else { $when = "{$age} days ago"; } $project_info = null; if ($project_phid) { $project_info = '
    This document is about the project '. $handles[$project_phid]->renderLink().'.'; } $index_link = phutil_tag( 'a', array( 'href' => '/phriction/', ), pht('Document Index')); $byline = ''; $doc_status = $document->getStatus(); if ($doc_status == PhrictionDocumentStatus::STATUS_EXISTS) { $core_content = $content->renderContent($user); } else if ($doc_status == PhrictionDocumentStatus::STATUS_DELETED) { $notice = new AphrontErrorView(); $notice->setSeverity(AphrontErrorView::SEVERITY_NOTICE); $notice->setTitle('Document Deleted'); $notice->appendChild( 'This document has been deleted. You can edit it to put new content '. 'here, or use history to revert to an earlier version.'); $core_content = $notice->render(); } else { throw new Exception("Unknown document status '{$doc_status}'!"); } $page_content = '
    '. $index_link. $byline. $core_content. '
    '; } if ($version_note) { $version_note = $version_note->render(); } $children = $this->renderChildren($slug); $crumbs = $this->buildApplicationCrumbs(); $crumb_views = $this->renderBreadcrumbs($slug); foreach ($crumb_views as $view) { $crumbs->addCrumb($view); } $actions = $this->buildActionView($user, $document); $header = id(new PhabricatorHeaderView()) ->setHeader($page_title); $page = $crumbs->render(). $header->render(). $actions->render(). $version_note. $page_content. $children; return $this->buildApplicationPage( array( $page, ), array( 'title' => $page_title, 'device' => true, )); } private function buildActionView( PhabricatorUser $user, PhrictionDocument $document) { $can_edit = PhabricatorPolicyFilter::hasCapability( $user, $document, PhabricatorPolicyCapability::CAN_EDIT); $slug = PhabricatorSlug::normalize($this->slug); - return id(new PhabricatorActionListView()) + $action_view = id(new PhabricatorActionListView()) ->setUser($user) ->setObject($document) ->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Document')) ->setIcon('edit') - ->setHref('/phriction/edit/'.$document->getID().'/')) - ->addAction( + ->setHref('/phriction/edit/'.$document->getID().'/')); + + if ($document->getStatus() == PhrictionDocumentStatus::STATUS_EXISTS) { + $action_view->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Delete Document')) + ->setIcon('delete') + ->setHref('/phriction/delete/'.$document->getID().'/') + ->setWorkflow(true)); + } + + return + $action_view->addAction( id(new PhabricatorActionView()) - ->setName(pht('View History')) - ->setIcon('history') - ->setHref(PhrictionDocument::getSlugURI($slug, 'history'))); + ->setName(pht('View History')) + ->setIcon('history') + ->setHref(PhrictionDocument::getSlugURI($slug, 'history'))); } private function renderChildren($slug) { $document_dao = new PhrictionDocument(); $content_dao = new PhrictionContent(); $conn = $document_dao->establishConnection('r'); $limit = 50; $d_child = PhabricatorSlug::getDepth($slug) + 1; $d_grandchild = PhabricatorSlug::getDepth($slug) + 2; // Select children and grandchildren. $children = queryfx_all( $conn, 'SELECT d.slug, d.depth, c.title FROM %T d JOIN %T c ON d.contentID = c.id WHERE d.slug LIKE %> AND d.depth IN (%d, %d) AND d.status = %d ORDER BY d.depth, c.title LIMIT %d', $document_dao->getTableName(), $content_dao->getTableName(), ($slug == '/' ? '' : $slug), $d_child, $d_grandchild, PhrictionDocumentStatus::STATUS_EXISTS, $limit); if (!$children) { return; } // We're going to render in one of three modes to try to accommodate // different information scales: // // - If we found fewer than $limit rows, we know we have all the children // and grandchildren and there aren't all that many. We can just render // everything. // - If we found $limit rows but the results included some grandchildren, // we just throw them out and render only the children, as we know we // have them all. // - If we found $limit rows and the results have no grandchildren, we // have a ton of children. Render them and then let the user know that // this is not an exhaustive list. if (count($children) == $limit) { $more_children = true; foreach ($children as $child) { if ($child['depth'] == $d_grandchild) { $more_children = false; } } $show_grandchildren = false; } else { $show_grandchildren = true; $more_children = false; } $grandchildren = array(); foreach ($children as $key => $child) { if ($child['depth'] == $d_child) { continue; } else { unset($children[$key]); if ($show_grandchildren) { $ancestors = PhabricatorSlug::getAncestry($child['slug']); $grandchildren[end($ancestors)][] = $child; } } } // Fill in any missing children. $known_slugs = ipull($children, null, 'slug'); foreach ($grandchildren as $slug => $ignored) { if (empty($known_slugs[$slug])) { $children[] = array( 'slug' => $slug, 'depth' => $d_child, 'title' => PhabricatorSlug::getDefaultTitle($slug), 'empty' => true, ); } } $children = isort($children, 'title'); $list = array(); $list[] = '
      '; foreach ($children as $child) { $list[] = $this->renderChildDocumentLink($child); $grand = idx($grandchildren, $child['slug'], array()); if ($grand) { $list[] = '
        '; foreach ($grand as $grandchild) { $list[] = $this->renderChildDocumentLink($grandchild); } $list[] = '
      '; } } if ($more_children) { $list[] = '
    • More...
    • '; } $list[] = '
    '; $list = implode("\n", $list); return '
    '. '
    Document Hierarchy
    '. $list. '
    '; } private function renderChildDocumentLink(array $info) { $title = nonempty($info['title'], '(Untitled Document)'); $item = phutil_tag( 'a', array( 'href' => PhrictionDocument::getSlugURI($info['slug']), ), $title); if (isset($info['empty'])) { $item = ''.$item.''; } return '
  • '.$item.'
  • '; } } diff --git a/src/applications/phriction/controller/PhrictionEditController.php b/src/applications/phriction/controller/PhrictionEditController.php index 72a6f50c0f..43b8c3824a 100644 --- a/src/applications/phriction/controller/PhrictionEditController.php +++ b/src/applications/phriction/controller/PhrictionEditController.php @@ -1,279 +1,265 @@ id = idx($data, 'id'); } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); if ($this->id) { $document = id(new PhrictionDocument())->load($this->id); if (!$document) { return new Aphront404Response(); } $revert = $request->getInt('revert'); if ($revert) { $content = id(new PhrictionContent())->loadOneWhere( 'documentID = %d AND version = %d', $document->getID(), $revert); if (!$content) { return new Aphront404Response(); } } else { $content = id(new PhrictionContent())->load($document->getContentID()); } } else { $slug = $request->getStr('slug'); $slug = PhabricatorSlug::normalize($slug); if (!$slug) { return new Aphront404Response(); } $document = id(new PhrictionDocument())->loadOneWhere( 'slug = %s', $slug); if ($document) { $content = id(new PhrictionContent())->load($document->getContentID()); } else { if (PhrictionDocument::isProjectSlug($slug)) { $project = id(new PhabricatorProject())->loadOneWhere( 'phrictionSlug = %s', PhrictionDocument::getProjectSlugIdentifier($slug)); if (!$project) { return new Aphront404Response(); } } $document = new PhrictionDocument(); $document->setSlug($slug); $content = new PhrictionContent(); $content->setSlug($slug); $default_title = PhabricatorSlug::getDefaultTitle($slug); $content->setTitle($default_title); } } if ($request->getBool('nodraft')) { $draft = null; $draft_key = null; } else { if ($document->getPHID()) { $draft_key = $document->getPHID().':'.$content->getVersion(); } else { $draft_key = 'phriction:'.$content->getSlug(); } $draft = id(new PhabricatorDraft())->loadOneWhere( 'authorPHID = %s AND draftKey = %s', $user->getPHID(), $draft_key); } require_celerity_resource('phriction-document-css'); $e_title = true; $notes = null; $errors = array(); if ($request->isFormPost()) { $title = $request->getStr('title'); $notes = $request->getStr('description'); if (!strlen($title)) { $e_title = 'Required'; $errors[] = 'Document title is required.'; } else { $e_title = null; } if ($document->getID()) { if ($content->getTitle() == $title && $content->getContent() == $request->getStr('content')) { $dialog = new AphrontDialogView(); $dialog->setUser($user); $dialog->setTitle('No Edits'); $dialog->appendChild( '

    You did not make any changes to the document.

    '); $dialog->addCancelButton($request->getRequestURI()); return id(new AphrontDialogResponse())->setDialog($dialog); } } else if (!strlen($request->getStr('content'))) { // We trigger this only for new pages. For existing pages, deleting // all the content counts as deleting the page. $dialog = new AphrontDialogView(); $dialog->setUser($user); $dialog->setTitle('Empty Page'); $dialog->appendChild( '

    You can not create an empty document.

    '); $dialog->addCancelButton($request->getRequestURI()); return id(new AphrontDialogResponse())->setDialog($dialog); } if (!count($errors)) { $editor = id(PhrictionDocumentEditor::newForSlug($document->getSlug())) ->setActor($user) ->setTitle($title) ->setContent($request->getStr('content')) ->setDescription($notes); $editor->save(); if ($draft) { $draft->delete(); } $uri = PhrictionDocument::getSlugURI($document->getSlug()); return id(new AphrontRedirectResponse())->setURI($uri); } } $error_view = null; if ($errors) { $error_view = id(new AphrontErrorView()) ->setTitle('Form Errors') ->setErrors($errors); } - $delete_button = null; if ($document->getID()) { $panel_header = 'Edit Phriction Document'; $submit_button = 'Save Changes'; - if ($document->getStatus() != PhrictionDocumentStatus::STATUS_DELETED) { - $delete_button = phutil_tag( - 'a', - array( - 'href' => '/phriction/delete/'.$document->getID().'/', - 'class' => 'grey button', - ), - 'Delete Document'); - } } else { $panel_header = 'Create New Phriction Document'; $submit_button = 'Create Document'; } $uri = $document->getSlug(); $uri = PhrictionDocument::getSlugURI($uri); $uri = PhabricatorEnv::getProductionURI($uri); $cancel_uri = PhrictionDocument::getSlugURI($document->getSlug()); if ($draft && strlen($draft->getDraft()) && ($draft->getDraft() != $content->getContent())) { $content_text = $draft->getDraft(); $discard = phutil_tag( 'a', array( 'href' => $request->getRequestURI()->alter('nodraft', true), ), 'discard this draft'); $draft_note = new AphrontErrorView(); $draft_note->setSeverity(AphrontErrorView::SEVERITY_NOTICE); $draft_note->setTitle('Recovered Draft'); $draft_note->appendChild( '

    Showing a saved draft of your edits, you can '.$discard.'.

    '); } else { $content_text = $content->getContent(); $draft_note = null; } $form = id(new AphrontFormView()) ->setUser($user) ->setWorkflow(true) ->setAction($request->getRequestURI()->getPath()) ->addHiddenInput('slug', $document->getSlug()) ->addHiddenInput('nodraft', $request->getBool('nodraft')) ->appendChild( id(new AphrontFormTextControl()) ->setLabel('Title') ->setValue($content->getTitle()) ->setError($e_title) ->setName('title')) ->appendChild( id(new AphrontFormStaticControl()) ->setLabel('URI') ->setValue($uri)) ->appendChild( id(new PhabricatorRemarkupControl()) ->setLabel('Content') ->setValue($content_text) ->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL) ->setName('content') ->setID('document-textarea') ->setUser($user)) ->appendChild( id(new AphrontFormTextControl()) ->setLabel('Edit Notes') ->setValue($notes) ->setError(null) ->setName('description')) ->appendChild( id(new AphrontFormSubmitControl()) ->addCancelButton($cancel_uri) ->setValue($submit_button)); $panel = id(new AphrontPanelView()) ->setWidth(AphrontPanelView::WIDTH_WIDE) ->setHeader($panel_header) ->appendChild($form); - if ($delete_button) { - $panel->addButton($delete_button); - } - $preview_panel = '
    Document Preview
    Loading preview...
    '; Javelin::initBehavior( 'phriction-document-preview', array( 'preview' => 'document-preview', 'textarea' => 'document-textarea', 'uri' => '/phriction/preview/?draftkey='.$draft_key, )); return $this->buildStandardPageResponse( array( $draft_note, $error_view, $panel, $preview_panel, ), array( 'title' => 'Edit Document', )); } } diff --git a/src/applications/settings/panel/PhabricatorSettingsPanelAccount.php b/src/applications/settings/panel/PhabricatorSettingsPanelAccount.php index 1e2d588016..72b58dae2a 100644 --- a/src/applications/settings/panel/PhabricatorSettingsPanelAccount.php +++ b/src/applications/settings/panel/PhabricatorSettingsPanelAccount.php @@ -1,101 +1,101 @@ getUser(); $editable = PhabricatorEnv::getEnvConfig('account.editable'); $e_realname = $editable ? true : null; $errors = array(); if ($request->isFormPost()) { if ($editable) { $user->setRealName($request->getStr('realname')); if (!strlen($user->getRealName())) { $errors[] = 'Real name must be nonempty.'; $e_realname = 'Required'; } } $new_timezone = $request->getStr('timezone'); if (in_array($new_timezone, DateTimeZone::listIdentifiers(), true)) { $user->setTimezoneIdentifier($new_timezone); } else { $errors[] = 'The selected timezone is not a valid timezone.'; } if (!$errors) { $user->save(); return id(new AphrontRedirectResponse()) ->setURI($this->getPanelURI('?saved=true')); } } $notice = null; if (!$errors) { if ($request->getStr('saved')) { $notice = new AphrontErrorView(); $notice->setSeverity(AphrontErrorView::SEVERITY_NOTICE); $notice->setTitle('Changes Saved'); $notice->appendChild('

    Your changes have been saved.

    '); $notice = $notice->render(); } } else { $notice = new AphrontErrorView(); $notice->setTitle('Form Errors'); $notice->setErrors($errors); $notice = $notice->render(); } $timezone_ids = DateTimeZone::listIdentifiers(); - $timezone_id_map = array_combine($timezone_ids, $timezone_ids); + $timezone_id_map = array_fuse($timezone_ids); $form = new AphrontFormView(); $form ->setUser($user) ->appendChild( id(new AphrontFormStaticControl()) ->setLabel('Username') ->setValue($user->getUsername())) ->appendChild( id(new AphrontFormTextControl()) ->setLabel('Real Name') ->setName('realname') ->setError($e_realname) ->setValue($user->getRealName()) ->setDisabled(!$editable)) ->appendChild( id(new AphrontFormSelectControl()) ->setLabel('Timezone') ->setName('timezone') ->setOptions($timezone_id_map) ->setValue($user->getTimezoneIdentifier())) ->appendChild( id(new AphrontFormSubmitControl()) ->setValue('Save')); $panel = new AphrontPanelView(); $panel->setHeader('Account Settings'); $panel->appendChild($form); $panel->setNoBackground(); return array( $notice, $panel, ); } } diff --git a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php index ec717468d3..7a3d07fd77 100644 --- a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php +++ b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php @@ -1,892 +1,906 @@ continueOnNoEffect = $continue; return $this; } public function getContinueOnNoEffect() { return $this->continueOnNoEffect; } + /** + * Not strictly necessary, but reply handlers ideally set this value to + * make email threading work better. + */ + public function setParentMessageID($parent_message_id) { + $this->parentMessageID = $parent_message_id; + return $this; + } + public function getParentMessageID() { + return $this->parentMessageID; + } + protected function getIsNewObject() { return $this->isNewObject; } protected function getMentionedPHIDs() { return $this->mentionedPHIDs; } public function setIsPreview($is_preview) { $this->isPreview = $is_preview; return $this; } public function getIsPreview() { return $this->isPreview; } public function getTransactionTypes() { $types = array(); if ($this->object instanceof PhabricatorSubscribableInterface) { $types[] = PhabricatorTransactions::TYPE_SUBSCRIBERS; } return $types; } private function adjustTransactionValues( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { $old = $this->getTransactionOldValue($object, $xaction); $xaction->setOldValue($old); $new = $this->getTransactionNewValue($object, $xaction); $xaction->setNewValue($new); } private function getTransactionOldValue( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PhabricatorTransactions::TYPE_SUBSCRIBERS: if ($object->getPHID()) { $old_phids = PhabricatorSubscribersQuery::loadSubscribersForPHID( $object->getPHID()); } else { $old_phids = array(); } return array_values($old_phids); case PhabricatorTransactions::TYPE_VIEW_POLICY: return $object->getViewPolicy(); case PhabricatorTransactions::TYPE_EDIT_POLICY: return $object->getEditPolicy(); default: return $this->getCustomTransactionOldValue($object, $xaction); } } private function getTransactionNewValue( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PhabricatorTransactions::TYPE_SUBSCRIBERS: return $this->getPHIDTransactionNewValue($xaction); case PhabricatorTransactions::TYPE_VIEW_POLICY: case PhabricatorTransactions::TYPE_EDIT_POLICY: return $xaction->getNewValue(); default: return $this->getCustomTransactionNewValue($object, $xaction); } } protected function getCustomTransactionOldValue( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { throw new Exception("Capability not supported!"); } protected function getCustomTransactionNewValue( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { throw new Exception("Capability not supported!"); } protected function transactionHasEffect( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PhabricatorTransactions::TYPE_COMMENT: return $xaction->hasComment(); } return ($xaction->getOldValue() !== $xaction->getNewValue()); } private function applyInternalEffects( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PhabricatorTransactions::TYPE_COMMENT: break; case PhabricatorTransactions::TYPE_VIEW_POLICY: $object->setViewPolicy($xaction->getNewValue()); break; case PhabricatorTransactions::TYPE_EDIT_POLICY: $object->setEditPolicy($xaction->getNewValue()); break; default: return $this->applyCustomInternalTransaction($object, $xaction); } } private function applyExternalEffects( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PhabricatorTransactions::TYPE_COMMENT: break; case PhabricatorTransactions::TYPE_SUBSCRIBERS: $subeditor = id(new PhabricatorSubscriptionsEditor()) ->setObject($object) ->setActor($this->requireActor()) ->subscribeExplicit($xaction->getNewValue()) ->save(); break; default: return $this->applyCustomExternalTransaction($object, $xaction); } } protected function applyCustomInternalTransaction( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { throw new Exception("Capability not supported!"); } protected function applyCustomExternalTransaction( PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { throw new Exception("Capability not supported!"); } public function setContentSource(PhabricatorContentSource $content_source) { $this->contentSource = $content_source; return $this; } public function getContentSource() { return $this->contentSource; } final public function applyTransactions( PhabricatorLiskDAO $object, array $xactions) { $this->object = $object; $this->xactions = $xactions; $this->isNewObject = ($object->getPHID() === null); $this->validateEditParameters($object, $xactions); $actor = $this->requireActor(); $mention_xaction = $this->buildMentionTransaction($object, $xactions); if ($mention_xaction) { $xactions[] = $mention_xaction; } $xactions = $this->combineTransactions($xactions); foreach ($xactions as $xaction) { // TODO: This needs to be more sophisticated once we have meta-policies. $xaction->setViewPolicy(PhabricatorPolicies::POLICY_PUBLIC); $xaction->setEditPolicy($actor->getPHID()); $xaction->setAuthorPHID($actor->getPHID()); $xaction->setContentSource($this->getContentSource()); } foreach ($xactions as $xaction) { $this->adjustTransactionValues($object, $xaction); } $xactions = $this->filterTransactions($object, $xactions); if (!$xactions) { return array(); } $xactions = $this->sortTransactions($xactions); if ($this->getIsPreview()) { $this->loadHandles($xactions); return $xactions; } $comment_editor = id(new PhabricatorApplicationTransactionCommentEditor()) ->setActor($actor) ->setContentSource($this->getContentSource()); $object->openTransaction(); foreach ($xactions as $xaction) { $this->applyInternalEffects($object, $xaction); } $object->save(); foreach ($xactions as $xaction) { $xaction->setObjectPHID($object->getPHID()); if ($xaction->getComment()) { $xaction->setPHID($xaction->generatePHID()); $comment_editor->applyEdit($xaction, $xaction->getComment()); } else { $xaction->save(); } } foreach ($xactions as $xaction) { $this->applyExternalEffects($object, $xaction); } $object->saveTransaction(); $this->loadHandles($xactions); $mail = null; if ($this->supportsMail()) { $mail = $this->sendMail($object, $xactions); } if ($this->supportsSearch()) { id(new PhabricatorSearchIndexer()) ->indexDocumentByPHID($object->getPHID()); } if ($this->supportsFeed()) { $mailed = array(); if ($mail) { $mailed = $mail->buildRecipientList(); } $this->publishFeedStory( $object, $xactions, $mailed); } $this->didApplyTransactions($xactions); return $xactions; } protected function didApplyTransactions(array $xactions) { // Hook for subclasses. return; } private function loadHandles(array $xactions) { $phids = array(); foreach ($xactions as $key => $xaction) { $phids[$key] = $xaction->getRequiredHandlePHIDs(); } $handles = array(); $merged = array_mergev($phids); if ($merged) { $handles = id(new PhabricatorObjectHandleData($merged)) ->setViewer($this->requireActor()) ->loadHandles(); } foreach ($xactions as $key => $xaction) { $xaction->setHandles(array_select_keys($handles, $phids[$key])); } } private function validateEditParameters( PhabricatorLiskDAO $object, array $xactions) { if (!$this->getContentSource()) { throw new Exception( "Call setContentSource() before applyTransactions()!"); } // Do a bunch of sanity checks that the incoming transactions are fresh. // They should be unsaved and have only "transactionType" and "newValue" // set. $types = array_fill_keys($this->getTransactionTypes(), true); assert_instances_of($xactions, 'PhabricatorApplicationTransaction'); foreach ($xactions as $xaction) { if ($xaction->getPHID() || $xaction->getID()) { throw new Exception( "You can not apply transactions which already have IDs/PHIDs!"); } if ($xaction->getObjectPHID()) { throw new Exception( "You can not apply transactions which already have objectPHIDs!"); } if ($xaction->getAuthorPHID()) { throw new Exception( "You can not apply transactions which already have authorPHIDs!"); } if ($xaction->getCommentPHID()) { throw new Exception( "You can not apply transactions which already have commentPHIDs!"); } if ($xaction->getCommentVersion() !== 0) { throw new Exception( "You can not apply transactions which already have commentVersions!"); } if ($xaction->getOldValue() !== null) { throw new Exception( "You can not apply transactions which already have oldValue!"); } $type = $xaction->getTransactionType(); if (empty($types[$type])) { throw new Exception("Transaction has unknown type '{$type}'."); } } // The actor must have permission to view and edit the object. $actor = $this->requireActor(); PhabricatorPolicyFilter::requireCapability( $actor, $xaction, PhabricatorPolicyCapability::CAN_VIEW); PhabricatorPolicyFilter::requireCapability( $actor, $xaction, PhabricatorPolicyCapability::CAN_EDIT); } private function buildMentionTransaction( PhabricatorLiskDAO $object, array $xactions) { if (!($object instanceof PhabricatorSubscribableInterface)) { return null; } $texts = array(); foreach ($xactions as $xaction) { $texts[] = $this->getMentionableTextsFromTransaction($xaction); } $texts = array_mergev($texts); $phids = PhabricatorMarkupEngine::extractPHIDsFromMentions($texts); $this->mentionedPHIDs = $phids; if (!$phids) { return null; } if ($object->getPHID()) { // Don't try to subscribe already-subscribed mentions: we want to generate // a dialog about an action having no effect if the user explicitly adds // existing CCs, but not if they merely mention existing subscribers. $current = PhabricatorSubscribersQuery::loadSubscribersForPHID( $object->getPHID()); $phids = array_diff($phids, $current); } if (!$phids) { return null; } $xaction = newv(get_class(head($xactions)), array()); $xaction->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS); $xaction->setNewValue(array('+' => $phids)); return $xaction; } protected function getMentionableTextsFromTransaction( PhabricatorApplicationTransaction $transaction) { $texts = array(); if ($transaction->getComment()) { $texts[] = $transaction->getComment()->getContent(); } return $texts; } protected function mergeTransactions( PhabricatorApplicationTransaction $u, PhabricatorApplicationTransaction $v) { $type = $u->getTransactionType(); switch ($type) { case PhabricatorTransactions::TYPE_SUBSCRIBERS: return $this->mergePHIDTransactions($u, $v); } // By default, do not merge the transactions. return null; } /** * Attempt to combine similar transactions into a smaller number of total * transactions. For example, two transactions which edit the title of an * object can be merged into a single edit. */ private function combineTransactions(array $xactions) { $stray_comments = array(); $result = array(); $types = array(); foreach ($xactions as $key => $xaction) { $type = $xaction->getTransactionType(); if (isset($types[$type])) { foreach ($types[$type] as $other_key) { $merged = $this->mergeTransactions($result[$other_key], $xaction); if ($merged) { $result[$other_key] = $merged; if ($xaction->getComment() && ($xaction->getComment() !== $merged->getComment())) { $stray_comments[] = $xaction->getComment(); } if ($result[$other_key]->getComment() && ($result[$other_key]->getComment() !== $merged->getComment())) { $stray_comments[] = $result[$other_key]->getComment(); } // Move on to the next transaction. continue 2; } } } $result[$key] = $xaction; $types[$type][] = $key; } // If we merged any comments away, restore them. foreach ($stray_comments as $comment) { $xaction = newv(get_class(head($result)), array()); $xaction->setTransactionType(PhabricatorTransactions::TYPE_COMMENT); $xaction->setComment($comment); $result[] = $xaction; } return array_values($result); } protected function mergePHIDTransactions( PhabricatorApplicationTransaction $u, PhabricatorApplicationTransaction $v) { $result = $u->getNewValue(); foreach ($v->getNewValue() as $key => $value) { $result[$key] = array_merge($value, idx($result, $key, array())); } $u->setNewValue($result); return $u; } protected function getPHIDTransactionNewValue( PhabricatorApplicationTransaction $xaction) { - $old = array_combine($xaction->getOldValue(), $xaction->getOldValue()); + $old = array_fuse($xaction->getOldValue()); $new = $xaction->getNewValue(); $new_add = idx($new, '+', array()); unset($new['+']); $new_rem = idx($new, '-', array()); unset($new['-']); $new_set = idx($new, '=', null); if ($new_set !== null) { - $new_set = array_combine($new_set, $new_set); + $new_set = array_fuse($new_set); } unset($new['=']); if ($new) { throw new Exception( "Invalid 'new' value for PHID transaction. Value should contain only ". "keys '+' (add PHIDs), '-' (remove PHIDs) and '=' (set PHIDS)."); } $result = array(); foreach ($old as $phid) { if ($new_set !== null && empty($new_set[$phid])) { continue; } $result[$phid] = $phid; } if ($new_set !== null) { foreach ($new_set as $phid) { $result[$phid] = $phid; } } foreach ($new_add as $phid) { $result[$phid] = $phid; } foreach ($new_rem as $phid) { unset($result[$phid]); } return array_values($result); } protected function sortTransactions(array $xactions) { $head = array(); $tail = array(); // Move bare comments to the end, so the actions preceed them. foreach ($xactions as $xaction) { $type = $xaction->getTransactionType(); if ($type == PhabricatorTransactions::TYPE_COMMENT) { $tail[] = $xaction; } else { $head[] = $xaction; } } return array_values(array_merge($head, $tail)); } protected function filterTransactions( PhabricatorLiskDAO $object, array $xactions) { $type_comment = PhabricatorTransactions::TYPE_COMMENT; $no_effect = array(); $has_comment = false; $any_effect = false; foreach ($xactions as $key => $xaction) { if ($this->transactionHasEffect($object, $xaction)) { if ($xaction->getTransactionType() != $type_comment) { $any_effect = true; } } else { $no_effect[$key] = $xaction; } if ($xaction->hasComment()) { $has_comment = true; } } if (!$no_effect) { return $xactions; } if (!$this->getContinueOnNoEffect() && !$this->getIsPreview()) { throw new PhabricatorApplicationTransactionNoEffectException( $no_effect, $any_effect, $has_comment); } if (!$any_effect && !$has_comment) { // If we only have empty comment transactions, just drop them all. return array(); } foreach ($no_effect as $key => $xaction) { if ($xaction->getComment()) { $xaction->setTransactionType($type_comment); $xaction->setOldValue(null); $xaction->setNewValue(null); } else { unset($xactions[$key]); } } return $xactions; } /* -( Sending Mail )------------------------------------------------------- */ /** * @task mail */ protected function supportsMail() { return false; } /** * @task mail */ protected function sendMail( PhabricatorLiskDAO $object, array $xactions) { $email_to = $this->getMailTo($object); $email_cc = $this->getMailCC($object); $phids = array_merge($email_to, $email_cc); $handles = id(new PhabricatorObjectHandleData($phids)) ->setViewer($this->requireActor()) ->loadHandles(); $template = $this->buildMailTemplate($object); $body = $this->buildMailBody($object, $xactions); $mail_tags = $this->getMailTags($object, $xactions); $action = $this->getStrongestAction($object, $xactions)->getActionName(); $template ->setFrom($this->requireActor()->getPHID()) ->setSubjectPrefix($this->getMailSubjectPrefix()) ->setVarySubjectPrefix('['.$action.']') ->setThreadID($object->getPHID(), $this->getIsNewObject()) ->setRelatedPHID($object->getPHID()) ->setExcludeMailRecipientPHIDs($this->getExcludeMailRecipientPHIDs()) ->setMailTags($mail_tags) ->setIsBulk(true) ->setBody($body->render()); - // TODO - // ->setParentMessageID(...) + if ($this->getParentMessageID()) { + $template->setParentMessageID($this->getParentMessageID()); + } $mails = $this ->buildReplyHandler($object) ->multiplexMail( $template, array_select_keys($handles, $email_to), array_select_keys($handles, $email_cc)); foreach ($mails as $mail) { $mail->saveAndSend(); } $template->addTos($email_to); $template->addCCs($email_cc); return $template; } /** * @task mail */ protected function getStrongestAction( PhabricatorLiskDAO $object, array $xactions) { return last(msort($xactions, 'getActionStrength')); } /** * @task mail */ protected function buildReplyHandler(PhabricatorLiskDAO $object) { throw new Exception("Capability not supported."); } /** * @task mail */ protected function getMailSubjectPrefix() { throw new Exception("Capability not supported."); } /** * @task mail */ protected function getMailTags( PhabricatorLiskDAO $object, array $xactions) { $tags = array(); foreach ($xactions as $xaction) { $tags[] = $xaction->getMailTags(); } return array_mergev($tags); } /** * @task mail */ protected function buildMailTemplate(PhabricatorLiskDAO $object) { throw new Exception("Capability not supported."); } /** * @task mail */ protected function getMailTo(PhabricatorLiskDAO $object) { throw new Exception("Capability not supported."); } /** * @task mail */ protected function getMailCC(PhabricatorLiskDAO $object) { if ($object instanceof PhabricatorSubscribableInterface) { $phid = $object->getPHID(); return PhabricatorSubscribersQuery::loadSubscribersForPHID($phid); } throw new Exception("Capability not supported."); } /** * @task mail */ protected function buildMailBody( PhabricatorLiskDAO $object, array $xactions) { $headers = array(); $comments = array(); foreach ($xactions as $xaction) { $headers[] = id(clone $xaction)->setRenderingTarget('text')->getTitle(); $comment = $xaction->getComment(); if ($comment && strlen($comment->getContent())) { $comments[] = $comment->getContent(); } } $body = new PhabricatorMetaMTAMailBody(); $body->addRawSection(implode("\n", $headers)); foreach ($comments as $comment) { $body->addRawSection($comment); } return $body; } /* -( Publishing Feed Stories )-------------------------------------------- */ /** * @task feed */ protected function supportsFeed() { return false; } /** * @task feed */ protected function getFeedStoryType() { return 'PhabricatorApplicationTransactionFeedStory'; } /** * @task feed */ protected function getFeedRelatedPHIDs( PhabricatorLiskDAO $object, array $xactions) { return array( $object->getPHID(), $this->requireActor()->getPHID(), ); } /** * @task feed */ protected function getFeedNotifyPHIDs( PhabricatorLiskDAO $object, array $xactions) { return array_merge( $this->getMailTo($object), $this->getMailCC($object)); } /** * @task feed */ protected function getFeedStoryData( PhabricatorLiskDAO $object, array $xactions) { $xactions = msort($xactions, 'getActionStrength'); $xactions = array_reverse($xactions); return array( 'objectPHID' => $object->getPHID(), 'transactionPHIDs' => mpull($xactions, 'getPHID'), ); } /** * @task feed */ protected function publishFeedStory( PhabricatorLiskDAO $object, array $xactions, array $mailed_phids) { $related_phids = $this->getFeedRelatedPHIDs($object, $xactions); $subscribed_phids = $this->getFeedNotifyPHIDs($object, $xactions); $story_type = $this->getFeedStoryType(); $story_data = $this->getFeedStoryData($object, $xactions); id(new PhabricatorFeedStoryPublisher()) ->setStoryType($story_type) ->setStoryData($story_data) ->setStoryTime(time()) ->setStoryAuthorPHID($this->requireActor()->getPHID()) ->setRelatedPHIDs($related_phids) ->setPrimaryObjectPHID($object->getPHID()) ->setSubscribedPHIDs($subscribed_phids) ->setMailRecipientPHIDs($mailed_phids) ->publish(); } /* -( Search Index )------------------------------------------------------- */ /** * @task search */ protected function supportsSearch() { return false; } } diff --git a/src/docs/developer/database.diviner b/src/docs/developer/database.diviner index 027bca2db5..59a49d852e 100644 --- a/src/docs/developer/database.diviner +++ b/src/docs/developer/database.diviner @@ -1,170 +1,170 @@ @title Database Schema @group developer This document describes key components of the database schema and should answer questions like how to store new types of data. = Database System = Phabricator uses MySQL with InnoDB engine. The only exception is the `search_documentfield` table which uses MyISAM because MySQL doesn't support fulltext search in InnoDB. Let us know if you need to use other database system: @{article:Give Feedback! Get Support!}. = PHP Drivers = Phabricator supports [[ http://www.php.net/book.mysql | MySQL ]] and [[ http://www.php.net/book.mysqli | MySQLi ]] PHP extensions. Most installations use MySQL but MySQLi should work equally well. = Databases = Each Phabricator application has its own database. The names are prefixed by `phabricator_`. This design has two advantages: * Each database is easier to comprehend and to maintain. * We don't do cross-database joins so each database can live on its own machine which is useful for load-balancing. = Connections = Phabricator specifies if it will use any opened connection just for reading or also for writing. This allows opening write connections to master and read connections to slave in master/slave replication. It is useful for load-balancing. = Tables = Each table name is prefixed by its application. For example, Differential revisions are stored in database `phabricator_differential` and table `differential_revision`. This duplicity allows easy recognition of the table in DarkConsole (see @{article:Using DarkConsole}) and other places. The exception is tables which share the same schema over different databases such as `edge`. We use lower-case table names with words separated by underscores. The reason is that MySQL can be configured (with `lower_case_table_names`) to lower-case the table names anyway. = Column Names = Phabricator uses camelCase names for columns. The main advantage is that they directly map to properties in PHP classes. Don't use MySQL reserved words (such as `order`) for column names. = Data Types = Phabricator uses `int unsigned` columns for storing dates instead of `date` or `datetime`. We don't need to care about time-zones in both MySQL and PHP because of it. The other reason is that PHP internally uses numbers for storing dates. Phabricator uses UTF-8 encoding for storing all text data. We use `utf8_general_ci` collation for free-text and `utf8_bin` for identifiers. We don't use the `enum` data type because each change to the list of possible values requires altering the table (which is slow with big tables). We use numbers (or short strings in some cases) mapped to PHP constants instead. = JSON = Some data don't require structured access - you don't need to filter or order by them. We store these data as text fields in JSON format. This approach has several advantages: * If we decide to add another unstructured field then we don't need to alter the table (which is slow for big tables in MySQL). * Table structure is not cluttered by fields which could be unused most of the time. An example of such usage can be found in column `differential_diffproperty.data`. = Primary Keys = Most tables have auto-increment column named `id`. However creating such column is not required for tables which are not usually directly referenced (such as tables expressing M:N relations). Example of such table is `differential_relationship`. = Indexes = Create all indexes necessary for fast query execution in most cases. Don't create indexes which are not used. You can analyze queries @{article:Using DarkConsole}. = Foreign Keys = We don't use InnoDB's foreign keys because our application is so great that no inconsistencies can arise. It will just slow us down. = PHIDs = Each globally referencable object in Phabricator has its associated PHID (Phabricator ID) which serves as a global identifier. We use PHIDs for referencing data in different databases. We use both autoincrementing IDs and global PHIDs because each is useful in different contexts. Autoincrementing IDs are chronologically ordered and allow us to construct short, human-readable object names (like D2258) and URIs. Global PHIDs allow us to represent relationships between different types of objects in a homogenous way. For example, the concept of "subscribers" is more powerfully done with PHIDs because we could theoretically have users, projects, teams, and more all as "subscribers" of other objects. Using an ID column we would need to add a "type" column to avoid ID collision; using PHIDs does not require this additional column. = Transactions = Transactional code should be written using transactions. Example of such code is inserting multiple records where one doesn't make sense without the other or selecting data later used for update. See chapter in @{class:LiskDAO}. = Advanced Features = We don't use MySQL advanced features such as triggers, stored procedures or events because we like expressing the application logic in PHP more than in SQL. Some of these features (especially triggers) can also cause big confusion. Avoiding these advanced features is also good for supporting other database systems (which we don't support anyway). = Schema Denormalization = Phabricator uses schema denormalization for performance reasons sparingly. Try to avoid it if possible. = Changing the Schema = There are three simple steps to update the schema: # Create a `.sql` file in `resources/sql/patches/`. This file should: - Contain the approprate MySQL commands to update the schema. - Use `${NAMESPACE}` rather than `phabricator` for database names. - Use `COLLATE utf8_bin` for any columns that are to be used as identifiers, such as PHID columns. Otherwise, use `COLLATE utf8_general_ci`. - Name all indexes so it is possible to delete them later. # Edit `src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php` and add your patch to @{method@phabricator:PhabricatorBuiltinPatchList::getPatches}. -# Run `bin/storage/upgrade`. +# Run `bin/storage upgrade`. It is also possible to create more complex patches in PHP for data migration (due to schema changes or otherwise.) However, the schema changes themselves should be done in separate `.sql` files. Order can be guaranteed by editing `src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php` appropriately. See the [[https://secure.phabricator.com/rPb39175342dc5bee0c2246b05fa277e76a7e96ed3 | commit adding policy storage for Paste ]] for a reasonable example of the code changes. = See Also = * @{class:LiskDAO} * @{class:PhabricatorPHID} diff --git a/src/docs/userguide/advanced_configuration.diviner b/src/docs/userguide/advanced_configuration.diviner index 1a40c064d8..e5792ac880 100644 --- a/src/docs/userguide/advanced_configuration.diviner +++ b/src/docs/userguide/advanced_configuration.diviner @@ -1,114 +1,116 @@ @title Configuration User Guide: Advanced Configuration @group userguide Configuring Phabricator for multiple environments. = Overview = Phabricator reads configuration from multiple sources. This document explains the configuration stack and how to set up advanced configuration sources, which may be useful for deployments with multiple environments (e.g., development and production). This is a complicated topic for advanced users. You do not need to understand this topic to install Phabricator. = Configuration Sources = Phabricator supports the following configuration sources, from highest priority to lowest priority: - **Database**: Values are stored in the database and edited from the web UI by administrators. They have the highest priority and override other settings. - **Local**: Values are stored in `conf/local/config.json` and edited by running `bin/config`. - **Config Files**: Values are stored in a config file in `conf/`. The file to use is selected by writing to `conf/local/ENVIRONMENT`, or setting the PHABRICATOR_ENV configuration variable. See below for more information. - **Defaults**: Defaults hard-coded in the Phabricator source, which can not be edited. They have the lowest priority, and all other settings override them. Normally, you install and configure Phabricator by writing enough configuration into the local config to get access to the database configuration (e.g., the MySQL username, password, and hostname), then use the web interface to further configure Phabricator. = Configuration Files = Configuration files provide an alternative to database configuration, and may be appropriate if you want to deploy in multiple environments or create dynamic configuration. Configuration files are more complicated than database configuration, which is why they are not used by default. == Creating a Configuration File == To create a configuration file, first choose a name for the config (like "devserver" or "live"). For the purposes of this section, we'll assume you chose `exampleconfig`. Replace "exampleconfig" with whatever you actually chose in the examples below. First, write an `exampleconfig.conf.php` file here (rename it according to the name you chose): phabricator/conf/custom/exampleconfig.conf.php Its contents should look like this: 'examplevalue', ); For example, to specify MySQL credentials in your config file, you might create a config like this: 'localhost', 'mysql.user' => 'root', 'mysql.pass' => 'hunter2trustno1', ); == Selecting a Configuration File == To select a configuration file, write the name of the file (relative to `phabricator/conf/`) to `phabricator/conf/local/ENVIRONMENT`. For example, to select `phabricator/conf/custom/exampleconfig.conf.php`, you would write "custom/exampleconfig" to `phabrictor/conf/local/ENVIRONMENT`: phabricator/ $ echo custom/exampleconfig > conf/local/ENVIRONMENT phabricator/ $ cat conf/local/ENVIRONMENT custom/exampleconfig phabricator/ $ You can also set the environmental variable `PHABRICATOR_ENV`. This is more involved but may be easier in some deployment environments. Note that this needs to be set in your webserver environment, and also in your shell whenever you run a script: - # Shell - export PHABRICATOR_ENV=custom/exampleconfig +``` +# Shell +export PHABRICATOR_ENV=custom/exampleconfig - # Apache - SetEnv PHABRICATOR_ENV custom/exampleconfig +# Apache +SetEnv PHABRICATOR_ENV custom/exampleconfig - # nginx - fastcgi_param PHABRICATOR_ENV "custom/exampleconfig"; +# nginx +fastcgi_param PHABRICATOR_ENV "custom/exampleconfig"; - # lighttpd - setenv.add-environment = ( - "PHABRICATOR_ENV" => "custom/exampleconfig", - ) +# lighttpd +setenv.add-environment = ( + "PHABRICATOR_ENV" => "custom/exampleconfig", +) +``` After creating and selecting a configuration file, restart your webserver. Any configuration you set should take effect immediately, and your file should be visible in the Config application when examining configuration. = Next Steps = Return to the @{article:Configuration Guide}. diff --git a/src/infrastructure/celerity/CeleritySpriteGenerator.php b/src/infrastructure/celerity/CeleritySpriteGenerator.php index deaffac9c7..c6b2ac23d0 100644 --- a/src/infrastructure/celerity/CeleritySpriteGenerator.php +++ b/src/infrastructure/celerity/CeleritySpriteGenerator.php @@ -1,444 +1,453 @@ getDirectoryList('icons_1x'); $colors = array( '', 'grey', 'white', ); $scales = array( '1x' => 1, '2x' => 2, ); $template = id(new PhutilSprite()) ->setSourceSize(14, 14); $sprites = array(); foreach ($colors as $color) { foreach ($icons as $icon) { $prefix = 'icons_'; if (strlen($color)) { $prefix .= $color.'_'; } $suffix = ''; if (strlen($color)) { $suffix = '-'.$color; } $sprite = id(clone $template) ->setName('action-'.$icon.$suffix); $tcss = array(); $tcss[] = '.action-'.$icon.$suffix; if ($color == 'white') { $tcss[] = '.device-desktop .phabricator-action-view:hover '. '.action-'.$icon; if ($icon == 'new') { // Hover state for the "+" icons on homepage tiles. $tcss[] = '.phabricator-application-launch-create:hover '. '.phabricator-application-create-icon.action-new-grey'; } } $sprite->setTargetCSS(implode(', ', $tcss)); foreach ($scales as $scale_key => $scale) { $path = $this->getPath($prefix.$scale_key.'/'.$icon.'.png'); $sprite->setSourceFile($path, $scale); } $sprites[] = $sprite; } } $remarkup_icons = $this->getDirectoryList('remarkup_1x'); foreach ($remarkup_icons as $icon) { $prefix = 'remarkup_'; // Strip 'text_' from these file names. $class_name = substr($icon, 5); $sprite = id(clone $template) ->setName('remarkup-assist-'.$icon) ->setTargetCSS('.remarkup-assist-'.$class_name); foreach ($scales as $scale_key => $scale) { $path = $this->getPath($prefix.$scale_key.'/'.$icon.'.png'); $sprite->setSourceFile($path, $scale); } $sprites[] = $sprite; } $sheet = $this->buildSheet('icon', true); $sheet->setScales($scales); foreach ($sprites as $sprite) { $sheet->addSprite($sprite); } return $sheet; } public function buildMenuSheet() { $sprites = array(); $sources = array( - 'round_bubble' => array( - 'x' => 26, - 'y' => 26, - 'css' => '.phabricator-main-menu-alert-bubble' - ), - 'bubble' => array( - 'x' => 46, - 'y' => 26, - 'css' => '.phabricator-main-menu-alert-bubble.alert-unread' - ), 'seen_read_all' => array( 'x' => 14, 'y' => 14, 'css' => '.alert-notifications .phabricator-main-menu-alert-icon', ), 'seen_have_unread' => array( 'x' => 14, 'y' => 14, 'css' => '.alert-notifications:hover .phabricator-main-menu-alert-icon', ), 'unseen_any' => array( 'x' => 14, 'y' => 14, 'css' => '.alert-notifications.alert-unread .phabricator-main-menu-alert-icon', ), 'arrow-right' => array( 'x' => 9, 'y' => 31, 'css' => '.phabricator-crumb-divider', ), 'eye' => array( 'x' => 24, 'y' => 20, 'css' => '.menu-icon-eye', ), 'app' => array( 'x' => 24, 'y' => 20, 'css' => '.menu-icon-app', ), 'logo' => array( 'x' => 139, 'y' => 25, 'css' => '.phabricator-main-menu-logo-image', ), + 'conf-off' => array( + 'x' => 14, + 'y' => 14, + 'css' => + '.alert-notifications .phabricator-main-menu-message-icon', + ), + 'conf-hover' => array( + 'x' => 14, + 'y' => 14, + 'css' => + '.alert-notifications:hover .phabricator-main-menu-message-icon', + ), + 'conf-unseen' => array( + 'x' => 14, + 'y' => 14, + 'css' => + '.alert-notifications.message-unread '. + '.phabricator-main-menu-message-icon', + ), ); $scales = array( '1x' => 1, '2x' => 2, ); $template = new PhutilSprite(); foreach ($sources as $name => $spec) { $sprite = id(clone $template) ->setName($name) ->setSourceSize($spec['x'], $spec['y']) ->setTargetCSS($spec['css']); foreach ($scales as $scale_name => $scale) { $path = 'menu_'.$scale_name.'/'.$name.'.png'; $path = $this->getPath($path); $sprite->setSourceFile($path, $scale); } $sprites[] = $sprite; } $sheet = $this->buildSheet('menu', true); $sheet->setScales($scales); foreach ($sprites as $sprite) { $sheet->addSprite($sprite); } return $sheet; } public function buildGradientSheet() { $gradients = $this->getDirectoryList('gradients'); $template = new PhutilSprite(); $unusual_heights = array( 'dark-menu-label' => 25, 'breadcrumbs' => 31, 'menu-hover' => 28, 'menu-label' => 24, 'menu-selected' => 28, ); // Reorder the sprites so less-specific rules generate earlier in the sheet. // Otherwise we end up with blue "a.black" buttons because the blue rules // have the same specificity but appear later. - $gradients = array_combine($gradients, $gradients); + $gradients = array_fuse($gradients); $gradients = array_select_keys( $gradients, array( 'blue-dark', 'blue-light', )) + $gradients; $extra_css = array( 'black-dark' => ', button.black, a.black, a.black:visited', 'black-light' => ', button.black:active, a.black:active', 'blue-dark' => ', button, a.button, a.button:visited, input.inputsubmit', 'blue-light' => ', button:active, a.button:active', 'grey-dark' => ', button.grey, input.inputaux, a.grey, a.grey:visited, '. 'a.button.disabled, button[disabled], button.disabled', 'grey-light' => ', button.grey:active, a.grey:active, '. 'button.grey_active, a.dropdown-open', 'green-dark' => ', button.green, a.green, a.green:visited', 'green-light' => ', button.green:active, a.green:active', 'dark-menu-label' => ', .phabricator-dark-menu .phabricator-menu-item-type-label', 'menu-label' => ', .phabricator-side-menu .phabricator-menu-item-type-label', 'menu-hover' => ', .device-desktop .phabricator-side-menu '. 'a.phabricator-menu-item-type-link:hover, '. '.phabricator-filetree a.phabricator-filetree-item:hover', 'menu-selected' => ', .phabricator-side-menu .phabricator-menu-item-selected, '. '.device-desktop .phabricator-side-menu '. 'a.phabricator-menu-item-selected:hover, '. '.phabricator-nav-local a.phabricator-active-nav-focus', ); $sprites = array(); foreach ($gradients as $gradient) { $path = $this->getPath('gradients/'.$gradient.'.png'); $sprite = id(clone $template) ->setName('gradient-'.$gradient) ->setSourceFile($path) ->setTargetCSS('.gradient-'.$gradient.idx($extra_css, $gradient)); $sprite->setSourceSize(4, idx($unusual_heights, $gradient, 26)); $sprites[] = $sprite; } $sheet = $this->buildSheet( 'gradient', false, PhutilSpriteSheet::TYPE_REPEAT_X, ', button, a.button, a.button:visited, input.inputsubmit, '. '.phabricator-dark-menu .phabricator-menu-item-type-label, '. '.phabricator-side-menu .phabricator-menu-item-type-label, '. '.device-desktop .phabricator-side-menu '. 'a.phabricator-menu-item-type-link:hover, '. '.phabricator-side-menu .phabricator-menu-item-selected, '. '.device-desktop .phabricator-side-menu '. 'a.phabricator-menu-item-selected:hover, '. '.phabricator-filetree a.phabricator-filetree-item:hover, '. '.phabricator-filetree a.phabricator-active-nav-focus'); foreach ($sprites as $sprite) { $sheet->addSprite($sprite); } return $sheet; } public function buildAppsSheet() { return $this->buildAppsSheetVariant(1); } public function buildAppsLargeSheet() { return $this->buildAppsSheetVariant(2); } public function buildAppsXLargeSheet() { return $this->buildAppsSheetVariant(3); } private function buildAppsSheetVariant($variant) { if ($variant == 1) { $scales = array( '1x' => 1, '2x' => 2, ); $variant_name = 'apps'; $variant_short = ''; $size_x = 14; $size_y = 14; $colors = array( 'dark' => 'dark', ); } else if ($variant == 2) { $scales = array( '2x' => 1, '4x' => 2, ); $variant_name = 'apps-large'; $variant_short = '-large'; $size_x = 28; $size_y = 28; $colors = array( 'light' => 'lb', 'dark' => 'dark', 'blue' => 'blue', 'glow' => 'glow', ); } else { $scales = array( '4x' => 1, ); $variant_name = 'apps-xlarge'; $variant_short = '-xlarge'; $size_x = 56; $size_y = 56; $colors = array( 'dark' => 'dark', /* TODO: These are available but not currently used. 'blue' => 'blue', 'light' => 'lb', 'glow' => 'glow', */ ); } $apps = $this->getDirectoryList('apps_dark_1x'); $template = id(new PhutilSprite()) ->setSourceSize($size_x, $size_y); $sprites = array(); foreach ($apps as $app) { foreach ($colors as $color => $color_path) { $css = '.app-'.$app.'-'.$color.$variant_short; if ($color == 'blue' && $variant_name == 'apps-large') { $css .= ', .phabricator-crumb-view:hover .app-'.$app.'-dark-large'; } if ($color == 'glow' && $variant_name == 'apps-large') { $css .= ', .device-desktop .phabricator-dark-menu a:hover '. '.app-'.$app.'-light-large'; } $sprite = id(clone $template) ->setName('app-'.$app.'-'.$color.$variant_short) ->setTargetCSS($css); foreach ($scales as $scale_name => $scale) { $path = $this->getPath( 'apps_'.$color_path.'_'.$scale_name.'/'.$app.'.png'); $sprite->setSourceFile($path, $scale); } $sprites[] = $sprite; } } $sheet = $this->buildSheet($variant_name, count($scales) > 1); $sheet->setScales($scales); foreach ($sprites as $sprite) { $sheet->addSprite($sprite); } return $sheet; } private function getPath($to_path = null) { $root = dirname(phutil_get_library_root('phabricator')); return $root.'/resources/sprite/'.$to_path; } private function getDirectoryList($dir) { $path = $this->getPath($dir); $result = array(); $images = Filesystem::listDirectory($path, $include_hidden = false); foreach ($images as $image) { if (!preg_match('/\.png$/', $image)) { throw new Exception( "Expected file '{$image}' in '{$path}' to be a sprite source ". "ending in '.png'."); } $result[] = substr($image, 0, -4); } return $result; } private function buildSheet( $name, $has_retina, $type = null, $extra_css = '') { $sheet = new PhutilSpriteSheet(); $at = '@'; switch ($type) { case PhutilSpriteSheet::TYPE_STANDARD: default: $type = PhutilSpriteSheet::TYPE_STANDARD; $repeat_rule = 'no-repeat'; break; case PhutilSpriteSheet::TYPE_REPEAT_X: $repeat_rule = 'repeat-x'; break; case PhutilSpriteSheet::TYPE_REPEAT_Y: $repeat_rule = 'repeat-y'; break; } $retina_rules = null; if ($has_retina) { $retina_rules = <<setSheetType($type); $sheet->setCSSHeader(<<data = $data; } final protected function getTaskData() { return $this->data; } final public function executeTask() { $this->doWork(); } final public static function scheduleTask($task_class, $data) { return id(new PhabricatorWorkerActiveTask()) ->setTaskClass($task_class) ->setData($data) ->save(); } /** * Wait for tasks to complete. If tasks are not leased by other workers, they * will be executed in this process while waiting. * * @param list List of queued task IDs to wait for. * @return void */ final public static function waitForTasks(array $task_ids) { $task_table = new PhabricatorWorkerActiveTask(); - $waiting = array_combine($task_ids, $task_ids); + $waiting = array_fuse($task_ids); while ($waiting) { $conn_w = $task_table->establishConnection('w'); // Check if any of the tasks we're waiting on are still queued. If they // are not, we're done waiting. $row = queryfx_one( $conn_w, 'SELECT COUNT(*) N FROM %T WHERE id IN (%Ld)', $task_table->getTableName(), $waiting); if (!$row['N']) { // Nothing is queued anymore. Stop waiting. break; } $tasks = id(new PhabricatorWorkerLeaseQuery()) ->withIDs($waiting) ->setLimit(1) ->execute(); if (!$tasks) { // We were not successful in leasing anything. Sleep for a bit and // see if we have better luck later. sleep(1); continue; } $task = head($tasks)->executeTask(); $ex = $task->getExecutionException(); if ($ex) { throw $ex; } } $tasks = id(new PhabricatorWorkerArchiveTask())->loadAllWhere( 'id IN (%Ld)', $task_ids); foreach ($tasks as $task) { if ($task->getResult() != PhabricatorWorkerArchiveTask::RESULT_SUCCESS) { throw new Exception("Task ".$task->getID()." failed!"); } } } public function renderForDisplay() { $data = PhutilReadableSerializer::printableValue($this->data); $data = phutil_escape_html($data); $data = '
    '.$data.'
    '; return $data; } } diff --git a/src/infrastructure/markup/rule/PhabricatorRemarkupRuleEmbedFile.php b/src/infrastructure/markup/rule/PhabricatorRemarkupRuleEmbedFile.php index 6adc7958f8..42fce61dd5 100644 --- a/src/infrastructure/markup/rule/PhabricatorRemarkupRuleEmbedFile.php +++ b/src/infrastructure/markup/rule/PhabricatorRemarkupRuleEmbedFile.php @@ -1,170 +1,180 @@ load($matches[1]); } if (!$file) { return $matches[0]; } $phid = $file->getPHID(); $engine = $this->getEngine(); $token = $engine->storeText(''); $metadata_key = self::KEY_RULE_EMBED_FILE; $metadata = $engine->getTextMetadata($metadata_key, array()); $bundle = array('token' => $token); $options = array( 'size' => 'thumb', 'layout' => 'left', 'float' => false, 'name' => null, ); if (!empty($matches[2])) { $matches[2] = trim($matches[2], ', '); $parser = new PhutilSimpleOptions(); $options = $parser->parse($matches[2]) + $options; } $file_name = coalesce($options['name'], $file->getName()); $options['name'] = $file_name; $attrs = array(); switch ((string)$options['size']) { case 'full': $attrs['src'] = $file->getBestURI(); $options['image_class'] = null; + $file_data = $file->getMetadata(); + $height = idx($file_data, PhabricatorFile::METADATA_IMAGE_HEIGHT); + if ($height) { + $attrs['height'] = $height; + } + $width = idx($file_data, PhabricatorFile::METADATA_IMAGE_WIDTH); + if ($width) { + $attrs['width'] = $width; + } break; case 'thumb': default: $attrs['src'] = $file->getPreview220URI(); + $attrs['width'] = '220'; $options['image_class'] = 'phabricator-remarkup-embed-image'; break; } $bundle['attrs'] = $attrs; $bundle['options'] = $options; $bundle['meta'] = array( 'phid' => $file->getPHID(), 'viewable' => $file->isViewableImage(), 'uri' => $file->getBestURI(), 'dUri' => $file->getDownloadURI(), 'name' => $options['name'], ); $metadata[$phid][] = $bundle; $engine->setTextMetadata($metadata_key, $metadata); return $token; } public function didMarkupText() { $engine = $this->getEngine(); $metadata_key = self::KEY_RULE_EMBED_FILE; $metadata = $engine->getTextMetadata($metadata_key, array()); if (!$metadata) { return; } $file_phids = array(); foreach ($metadata as $phid => $bundles) { foreach ($bundles as $data) { $options = $data['options']; $meta = $data['meta']; if (!$meta['viewable'] || $options['layout'] == 'link') { $link = id(new PhabricatorFileLinkView()) ->setFilePHID($meta['phid']) ->setFileName($meta['name']) ->setFileDownloadURI($meta['dUri']) ->setFileViewURI($meta['uri']) ->setFileViewable($meta['viewable']); $embed = $link->render(); $engine->overwriteStoredText($data['token'], $embed); continue; } require_celerity_resource('lightbox-attachment-css'); $img = phutil_tag('img', $data['attrs']); $embed = javelin_tag( 'a', array( 'href' => $meta['uri'], 'class' => $options['image_class'], 'sigil' => 'lightboxable', 'mustcapture' => true, 'meta' => $meta, ), $img); $layout_class = null; switch ($options['layout']) { case 'right': case 'center': case 'inline': case 'left': $layout_class = 'phabricator-remarkup-embed-layout-'. $options['layout']; break; default: $layout_class = 'phabricator-remarkup-embed-layout-left'; break; } if ($options['float']) { switch ($options['layout']) { case 'center': case 'inline': break; case 'right': $layout_class .= ' phabricator-remarkup-embed-float-right'; break; case 'left': default: $layout_class .= ' phabricator-remarkup-embed-float-left'; break; } } if ($layout_class) { $embed = phutil_tag( 'div', array( 'class' => $layout_class, ), $embed); } $engine->overwriteStoredText($data['token'], $embed); } $file_phids[] = $phid; } $engine->setTextMetadata(self::KEY_EMBED_FILE_PHIDS, $file_phids); $engine->setTextMetadata($metadata_key, array()); } } diff --git a/src/infrastructure/markup/rule/PhabricatorRemarkupRuleImageMacro.php b/src/infrastructure/markup/rule/PhabricatorRemarkupRuleImageMacro.php index 0216850355..849f537501 100644 --- a/src/infrastructure/markup/rule/PhabricatorRemarkupRuleImageMacro.php +++ b/src/infrastructure/markup/rule/PhabricatorRemarkupRuleImageMacro.php @@ -1,51 +1,62 @@ images === null) { $this->images = array(); $rows = id(new PhabricatorFileImageMacro())->loadAllWhere( 'isDisabled = 0'); foreach ($rows as $row) { $this->images[$row->getName()] = $row->getFilePHID(); } } if (array_key_exists($matches[1], $this->images)) { $phid = $this->images[$matches[1]]; $file = id(new PhabricatorFile())->loadOneWhere('phid = %s', $phid); + $style = null; + $src_uri = null; if ($file) { $src_uri = $file->getBestURI(); - } else { - $src_uri = null; + $file_data = $file->getMetadata(); + $height = idx($file_data,PhabricatorFile::METADATA_IMAGE_HEIGHT); + $width = idx($file_data, PhabricatorFile::METADATA_IMAGE_WIDTH); + if ($height && $width) { + $style = sprintf( + 'height: %dpx; width: %dpx;', + $height, + $width + ); + } } $img = phutil_tag( 'img', array( 'src' => $src_uri, 'alt' => $matches[1], 'title' => $matches[1], + 'style' => $style, )); return $this->getEngine()->storeText($img); } else { return $matches[1]; } } } diff --git a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php index 5344eef6a2..9c1dee01f2 100644 --- a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php +++ b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php @@ -1,1099 +1,1103 @@ 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', ), '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'), ), 'db.config' => array( 'type' => 'db', 'name' => 'config', ), '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'), + ), ); } } diff --git a/src/view/form/AphrontErrorView.php b/src/view/form/AphrontErrorView.php index 0ff078261b..06fa19ceb7 100644 --- a/src/view/form/AphrontErrorView.php +++ b/src/view/form/AphrontErrorView.php @@ -1,93 +1,112 @@ insideDialogue = $inside_dialogue; + return $this; + } + public function getInsideDialogue() { + return $this->insideDialogue; + } public function setTitle($title) { $this->title = $title; return $this; } public function setSeverity($severity) { $this->severity = $severity; return $this; } public function setErrors(array $errors) { $this->errors = $errors; return $this; } public function setID($id) { $this->id = $id; return $this; } + private function getBaseClass() { + if ($this->getInsideDialogue()) { + $class = 'aphront-error-view-dialogue'; + } else { + $class = 'aphront-error-view'; + } + return $class; + } + final public function render() { require_celerity_resource('aphront-error-view-css'); $errors = $this->errors; if ($errors) { $list = array(); foreach ($errors as $error) { $list[] = phutil_tag( 'li', array(), $error); } $list = phutil_tag( 'ul', array( 'class' => 'aphront-error-view-list', ), $list); } else { $list = null; } $title = $this->title; if (strlen($title)) { $title = phutil_tag( 'h1', array( 'class' => 'aphront-error-view-head', ), $title); } else { $title = null; } $this->severity = nonempty($this->severity, self::SEVERITY_ERROR); - $more_classes = array(); - $more_classes[] = 'aphront-error-severity-'.$this->severity; - $more_classes = implode(' ', $more_classes); + $classes = array(); + $classes[] = $this->getBaseClass(); + $classes[] = 'aphront-error-severity-'.$this->severity; + $classes = implode(' ', $classes); return phutil_render_tag( 'div', array( 'id' => $this->id, - 'class' => 'aphront-error-view '.$more_classes, + 'class' => $classes, ), array( $title, phutil_render_tag( 'div', array( 'class' => 'aphront-error-view-body', ), $this->renderChildren(). $list), )); } } diff --git a/src/view/form/control/AphrontFormDateControl.php b/src/view/form/control/AphrontFormDateControl.php index afe989f854..27166c8440 100644 --- a/src/view/form/control/AphrontFormDateControl.php +++ b/src/view/form/control/AphrontFormDateControl.php @@ -1,266 +1,266 @@ initialTime = $time; return $this; } public function readValueFromRequest(AphrontRequest $request) { $user = $this->user; if (!$this->user) { throw new Exception( "Call setUser() before readValueFromRequest()!"); } $user_zone = $user->getTimezoneIdentifier(); $zone = new DateTimeZone($user_zone); $day = $request->getInt($this->getDayInputName()); $month = $request->getInt($this->getMonthInputName()); $year = $request->getInt($this->getYearInputName()); $time = $request->getStr($this->getTimeInputName()); $err = $this->getError(); if ($day || $month || $year || $time) { $this->valueDay = $day; $this->valueMonth = $month; $this->valueYear = $year; $this->valueTime = $time; // Assume invalid. $err = 'Invalid'; try { $date = new DateTime("{$year}-{$month}-{$day} {$time}", $zone); $value = $date->format('U'); } catch (Exception $ex) { $value = null; } if ($value) { $this->setValue($value); $err = null; } else { $this->setValue(null); } } else { // TODO: We could eventually allow these to be customized per install or // per user or both, but let's wait and see. switch ($this->initialTime) { case self::TIME_START_OF_DAY: default: $time = '12:00 AM'; break; case self::TIME_START_OF_BUSINESS: $time = '9:00 AM'; break; case self::TIME_END_OF_BUSINESS: $time = '5:00 PM'; break; case self::TIME_END_OF_DAY: $time = '11:59 PM'; break; } $today = $this->formatTime(time(), 'Y-m-d'); try { $date = new DateTime("{$today} {$time}", $zone); $value = $date->format('U'); } catch (Exception $ex) { $value = null; } if ($value) { $this->setValue($value); } else { $this->setValue(null); } } $this->setError($err); return $this->getValue(); } protected function getCustomControlClass() { return 'aphront-form-control-date'; } public function setValue($epoch) { $result = parent::setValue($epoch); if ($epoch === null) { return; } $readable = $this->formatTime($epoch, 'Y!m!d!g:i A'); $readable = explode('!', $readable, 4); $this->valueYear = $readable[0]; $this->valueMonth = $readable[1]; $this->valueDay = $readable[2]; $this->valueTime = $readable[3]; return $result; } private function getMinYear() { $cur_year = $this->formatTime( time(), 'Y'); $val_year = $this->getYearInputValue(); return min($cur_year, $val_year) - 3; } private function getMaxYear() { $cur_year = $this->formatTime( time(), 'Y'); $val_year = $this->getYearInputValue(); return max($cur_year, $val_year) + 3; } private function getDayInputValue() { return $this->valueDay; } private function getMonthInputValue() { return $this->valueMonth; } private function getYearInputValue() { return $this->valueYear; } private function getTimeInputValue() { return $this->valueTime; } private function formatTime($epoch, $fmt) { return phabricator_format_local_time( $epoch, $this->user, $fmt); } private function getDayInputName() { return $this->getName().'_d'; } private function getMonthInputName() { return $this->getName().'_m'; } private function getYearInputName() { return $this->getName().'_y'; } private function getTimeInputName() { return $this->getName().'_t'; } protected function renderInput() { $min_year = $this->getMinYear(); $max_year = $this->getMaxYear(); $days = range(1, 31); - $days = array_combine($days, $days); + $days = array_fuse($days); $months = array( 1 => 'Jan', 2 => 'Feb', 3 => 'Mar', 4 => 'Apr', 5 => 'May', 6 => 'Jun', 7 => 'Jul', 8 => 'Aug', 9 => 'Sep', 10 => 'Oct', 11 => 'Nov', 12 => 'Dec', ); $years = range($this->getMinYear(), $this->getMaxYear()); - $years = array_combine($years, $years); + $years = array_fuse($years); $days_sel = AphrontFormSelectControl::renderSelectTag( $this->getDayInputValue(), $days, array( 'name' => $this->getDayInputName(), 'sigil' => 'day-input', )); $months_sel = AphrontFormSelectControl::renderSelectTag( $this->getMonthInputValue(), $months, array( 'name' => $this->getMonthInputName(), 'sigil' => 'month-input', )); $years_sel = AphrontFormSelectControl::renderSelectTag( $this->getYearInputValue(), $years, array( 'name' => $this->getYearInputName(), 'sigil' => 'year-input', )); $cal_icon = javelin_tag( 'a', array( 'href' => '#', 'class' => 'calendar-button', 'sigil' => 'calendar-button', ), ''); $time_sel = phutil_tag( 'input', array( 'name' => $this->getTimeInputName(), 'sigil' => 'time-input', 'value' => $this->getTimeInputValue(), 'type' => 'text', 'class' => 'aphront-form-date-time-input', ), ''); Javelin::initBehavior('fancy-datepicker', array()); return javelin_render_tag( 'div', array( 'class' => 'aphront-form-date-container', 'sigil' => 'phabricator-date-control', ), self::renderSingleView( array( $days_sel, $months_sel, $years_sel, $cal_icon, $time_sel, ))); } } diff --git a/src/view/layout/PhabricatorObjectItemListView.php b/src/view/layout/PhabricatorObjectItemListView.php index a145b7ba43..0059f136ff 100644 --- a/src/view/layout/PhabricatorObjectItemListView.php +++ b/src/view/layout/PhabricatorObjectItemListView.php @@ -1,66 +1,78 @@ header = $header; return $this; } public function setPager($pager) { $this->pager = $pager; return $this; } public function setNoDataString($no_data_string) { $this->noDataString = $no_data_string; return $this; } public function addItem(PhabricatorObjectItemView $item) { $this->items[] = $item; return $this; } + public function setStackable() { + $this->stackable = true; + return $this; + } + public function render() { require_celerity_resource('phabricator-object-item-list-view-css'); + $classes = array(); $header = null; if (strlen($this->header)) { $header = phutil_tag( 'h1', array( 'class' => 'phabricator-object-item-list-header', ), $this->header); } if ($this->items) { $items = $this->renderSingleView($this->items); } else { $string = nonempty($this->noDataString, pht('No data.')); $items = id(new AphrontErrorView()) ->setSeverity(AphrontErrorView::SEVERITY_NODATA) ->appendChild(phutil_escape_html($string)) ->render(); } $pager = null; if ($this->pager) { $pager = $this->renderSingleView($this->pager); } + $classes[] = 'phabricator-object-item-list-view'; + if ($this->stackable) { + $classes[] = 'phabricator-object-list-stackable'; + } + return phutil_render_tag( - 'div', + 'ul', array( - 'class' => 'phabricator-object-item-list-view', + 'class' => implode(' ', $classes), ), $header.$items.$pager); } } diff --git a/src/view/layout/PhabricatorObjectItemView.php b/src/view/layout/PhabricatorObjectItemView.php index 662e63a783..fe8940320e 100644 --- a/src/view/layout/PhabricatorObjectItemView.php +++ b/src/view/layout/PhabricatorObjectItemView.php @@ -1,176 +1,176 @@ effect = $effect; return $this; } public function getEffect() { return $this->effect; } public function setObject($object) { $this->object = $object; return $this; } public function getObject() { return $this->object; } public function setHref($href) { $this->href = $href; return $this; } public function getHref() { return $this->href; } public function setHeader($header) { $this->header = $header; return $this; } public function getHeader() { return $this->header; } public function addIcon($icon, $label = null) { $this->icons[] = array( 'icon' => $icon, 'label' => $label, ); return $this; } public function setBarColor($bar_color) { $this->barColor = $bar_color; return $this; } public function getBarColor() { return $this->barColor; } public function addAttribute($attribute) { $this->attributes[] = $attribute; return $this; } public function render() { $header = phutil_tag( 'a', array( 'href' => $this->href, 'class' => 'phabricator-object-item-name', ), $this->header); $icons = null; if ($this->icons) { $icon_list = array(); foreach ($this->icons as $spec) { $icon = $spec['icon']; $icon = phutil_tag( 'span', array( 'class' => 'phabricator-object-item-icon-image '. 'sprite-icon action-'.$icon, ), ''); $label = phutil_tag( 'span', array( 'class' => 'phabricator-object-item-icon-label', ), $spec['label']); $icon_list[] = phutil_tag( 'li', array( 'class' => 'phabricator-object-item-icon', ), array($label, $icon)); } $icons = phutil_tag( 'ul', array( 'class' => 'phabricator-object-item-icons', ), $icon_list); } $attrs = null; if ($this->attributes) { $attrs = array(); $spacer = phutil_tag( 'span', array( 'class' => 'phabricator-object-item-attribute-spacer', ), "\xC2\xB7"); $first = true; foreach ($this->attributes as $attribute) { $attrs[] = phutil_render_tag( 'li', array( 'class' => 'phabricator-object-item-attribute', ), ($first ? null : $spacer).$attribute); $first = false; } $attrs = phutil_tag( 'ul', array( 'class' => 'phabricator-object-item-attributes', ), $attrs); } $classes = array(); $classes[] = 'phabricator-object-item'; if ($this->barColor) { $classes[] = 'phabricator-object-item-bar-color-'.$this->barColor; } switch ($this->effect) { case 'highlighted': $classes[] = 'phabricator-object-item-highlighted'; break; case null: break; default: throw new Exception("Invalid effect!"); } $content = phutil_render_tag( 'div', array( 'class' => 'phabricator-object-item-content', ), $header.$attrs.$this->renderChildren()); return phutil_tag( - 'div', + 'li', array( 'class' => implode(' ', $classes), ), array($icons, $content)); } } diff --git a/src/view/page/menu/PhabricatorMainMenuView.php b/src/view/page/menu/PhabricatorMainMenuView.php index b029e2cc8b..a16e813575 100644 --- a/src/view/page/menu/PhabricatorMainMenuView.php +++ b/src/view/page/menu/PhabricatorMainMenuView.php @@ -1,370 +1,419 @@ applicationMenu = $application_menu; return $this; } public function getApplicationMenu() { return $this->applicationMenu; } public function setController(PhabricatorController $controller) { $this->controller = $controller; return $this; } public function getController() { return $this->controller; } public function setDefaultSearchScope($default_search_scope) { $this->defaultSearchScope = $default_search_scope; return $this; } public function getDefaultSearchScope() { return $this->defaultSearchScope; } public function render() { $user = $this->user; require_celerity_resource('phabricator-main-menu-view'); $header_id = celerity_generate_unique_node_id(); $menus = array(); $alerts = array(); if ($user->isLoggedIn()) { list($menu, $dropdown) = $this->renderNotificationMenu(); $alerts[] = $menu; $menus[] = $dropdown; } $phabricator_menu = $this->renderPhabricatorMenu(); if ($alerts) { $alerts = phutil_render_tag( 'div', array( 'class' => 'phabricator-main-menu-alerts', ), self::renderSingleView($alerts)); } $application_menu = $this->getApplicationMenu(); if ($application_menu) { $application_menu->addClass('phabricator-dark-menu'); $application_menu->addClass('phabricator-application-menu'); } return phutil_render_tag( 'div', array( 'class' => 'phabricator-main-menu', 'id' => $header_id, ), self::renderSingleView( array( $this->renderPhabricatorMenuButton($header_id), $application_menu ? $this->renderApplicationMenuButton($header_id) : null, $this->renderPhabricatorLogo(), $alerts, $phabricator_menu, $application_menu, ))). self::renderSingleView($menus); } private function renderSearch() { $user = $this->user; $result = null; $keyboard_config = array( 'helpURI' => '/help/keyboardshortcut/', ); if ($user->isLoggedIn()) { $search = new PhabricatorMainMenuSearchView(); $search->setUser($user); $search->setScope($this->getDefaultSearchScope()); $result = $search; $pref_shortcut = PhabricatorUserPreferences::PREFERENCE_SEARCH_SHORTCUT; if ($user->loadPreferences()->getPreference($pref_shortcut, true)) { $keyboard_config['searchID'] = $search->getID(); } } Javelin::initBehavior('phabricator-keyboard-shortcuts', $keyboard_config); if ($result) { $result = id(new PhabricatorMenuItemView()) ->addClass('phabricator-main-menu-search') ->appendChild($result); } return $result; } private function renderPhabricatorMenuButton($header_id) { return javelin_tag( 'a', array( 'class' => 'phabricator-main-menu-expand-button '. 'phabricator-expand-core-menu', 'sigil' => 'jx-toggle-class', 'meta' => array( 'map' => array( $header_id => 'phabricator-core-menu-expanded', ), ), ), phutil_tag( 'span', array( 'class' => 'phabricator-menu-button-icon sprite-menu menu-icon-eye', ), '')); } public function renderApplicationMenuButton($header_id) { return javelin_tag( 'a', array( 'class' => 'phabricator-main-menu-expand-button '. 'phabricator-expand-application-menu', 'sigil' => 'jx-toggle-class', 'meta' => array( 'map' => array( $header_id => 'phabricator-application-menu-expanded', ), ), ), phutil_tag( 'span', array( 'class' => 'phabricator-menu-button-icon sprite-menu menu-icon-app', ), '')); } private function renderPhabricatorMenu() { $user = $this->getUser(); $controller = $this->getController(); $applications = PhabricatorApplication::getAllInstalledApplications(); $applications = msort($applications, 'getName'); $core = array(); $more = array(); $actions = array(); require_celerity_resource('sprite-apps-large-css'); $group_core = PhabricatorApplication::GROUP_CORE; foreach ($applications as $application) { if ($application->shouldAppearInLaunchView()) { $icon = $application->getIconName().'-light-large'; $item = id(new PhabricatorMenuItemView()) ->setName($application->getName()) ->setHref($application->getBaseURI()) ->appendChild($this->renderMenuIcon($icon)); if ($application->getApplicationGroup() == $group_core) { $core[] = $item; } else { $more[] = $item; } } $app_actions = $application->buildMainMenuItems($user, $controller); foreach ($app_actions as $action) { $actions[] = $action; } } $view = new PhabricatorMenuView(); $view->addClass('phabricator-dark-menu'); $view->addClass('phabricator-core-menu'); $search = $this->renderSearch(); $view->appendChild($search); $view ->newLabel(pht('Home')) ->addClass('phabricator-core-item-device'); $view->addMenuItem( id(new PhabricatorMenuItemView()) ->addClass('phabricator-core-item-device') ->setName(pht('Phabricator Home')) ->setHref('/') ->appendChild($this->renderMenuIcon('logo-light-large'))); if ($controller && $controller->getCurrentApplication()) { $application = $controller->getCurrentApplication(); $icon = $application->getIconName().'-light-large'; $view->addMenuItem( id(new PhabricatorMenuItemView()) ->addClass('phabricator-core-item-device') ->setName(pht('%s Home', $application->getName())) ->appendChild($this->renderMenuIcon($icon)) ->setHref($controller->getApplicationURI())); } if ($core) { $view->addMenuItem( id(new PhabricatorMenuItemView()) ->addClass('phabricator-core-item-device') ->setType(PhabricatorMenuItemView::TYPE_LABEL) ->setName(pht('Core Applications'))); foreach ($core as $item) { $item->addClass('phabricator-core-item-device'); $view->addMenuItem($item); } } if ($actions) { $actions = msort($actions, 'getSortOrder'); $view->addMenuItem( id(new PhabricatorMenuItemView()) ->addClass('phabricator-core-item-device') ->setType(PhabricatorMenuItemView::TYPE_LABEL) ->setName(pht('Actions'))); foreach ($actions as $action) { $icon = $action->getIcon(); if ($icon) { if ($action->getSelected()) { $action->appendChild($this->renderMenuIcon($icon.'-blue-large')); } else { $action->appendChild($this->renderMenuIcon($icon.'-light-large')); } } $view->addMenuItem($action); } } if ($more) { $view->addMenuItem( id(new PhabricatorMenuItemView()) ->addClass('phabricator-core-item-device') ->setType(PhabricatorMenuItemView::TYPE_LABEL) ->setName(pht('More Applications'))); foreach ($more as $item) { $item->addClass('phabricator-core-item-device'); $view->addMenuItem($item); } } return $view; } private function renderPhabricatorLogo() { return phutil_tag( 'a', array( 'class' => 'phabricator-main-menu-logo', 'href' => '/', ), phutil_tag( 'span', array( 'class' => 'sprite-menu phabricator-main-menu-logo-image', ), '')); } private function renderNotificationMenu() { $user = $this->user; require_celerity_resource('phabricator-notification-css'); require_celerity_resource('phabricator-notification-menu-css'); require_celerity_resource('sprite-menu-css'); + $container_classes = array( + 'sprite-menu', + 'alert-notifications', + ); + + $conpherence = id(new PhabricatorApplicationConpherence())->isBeta(); + $allow_beta = + PhabricatorEnv::getEnvConfig('phabricator.show-beta-applications'); + $message_tag = ''; + + if (!$conpherence || $allow_beta) { + $message_id = celerity_generate_unique_node_id(); + $message_count_id = celerity_generate_unique_node_id(); + + $unread_status = ConpherenceParticipationStatus::BEHIND; + $unread = id(new ConpherenceParticipantQuery()) + ->withParticipantPHIDs(array($user->getPHID())) + ->withParticipationStatus($unread_status) + ->execute(); + $message_count_number = count($unread); + if ($message_count_number > 999) { + $message_count_number = "\xE2\x88\x9E"; + } + + $message_count_tag = phutil_render_tag( + 'span', + array( + 'id' => $message_count_id, + 'class' => 'phabricator-main-menu-message-count' + ), + phutil_escape_html($message_count_number)); + + $message_icon_tag = phutil_render_tag( + 'span', + array( + 'class' => 'sprite-menu phabricator-main-menu-message-icon', + ), + ''); + + if ($message_count_number) { + $container_classes[] = 'message-unread'; + } + + $message_tag = phutil_render_tag( + 'a', + array( + 'href' => '/conpherence/', + 'class' => implode(' ', $container_classes), + 'id' => $message_id, + ), + $message_icon_tag.$message_count_tag); + } + $count_id = celerity_generate_unique_node_id(); $dropdown_id = celerity_generate_unique_node_id(); $bubble_id = celerity_generate_unique_node_id(); $count_number = id(new PhabricatorFeedStoryNotification()) ->countUnread($user); if ($count_number > 999) { $count_number = "\xE2\x88\x9E"; } $count_tag = phutil_tag( 'span', array( 'id' => $count_id, 'class' => 'phabricator-main-menu-alert-count' ), $count_number); $icon_tag = phutil_tag( 'span', array( 'class' => 'sprite-menu phabricator-main-menu-alert-icon', ), ''); - $container_classes = array( - 'phabricator-main-menu-alert-bubble', - 'sprite-menu', - 'alert-notifications', - ); if ($count_number) { $container_classes[] = 'alert-unread'; } $bubble_tag = phutil_tag( 'a', array( 'href' => '/notification/', 'class' => implode(' ', $container_classes), 'id' => $bubble_id, ), array($icon_tag, $count_tag)); Javelin::initBehavior( 'aphlict-dropdown', array( 'bubbleID' => $bubble_id, 'countID' => $count_id, 'dropdownID' => $dropdown_id, )); $notification_dropdown = javelin_tag( 'div', array( 'id' => $dropdown_id, 'class' => 'phabricator-notification-menu', 'sigil' => 'phabricator-notification-menu', 'style' => 'display: none;', ), ''); - return array($bubble_tag, $notification_dropdown); + return array( + $bubble_tag.$message_tag, $notification_dropdown); } private function renderMenuIcon($name) { return phutil_tag( 'span', array( 'class' => 'phabricator-core-menu-icon '. 'sprite-apps-large app-'.$name, ), ''); } } diff --git a/webroot/rsrc/css/aphront/error-view.css b/webroot/rsrc/css/aphront/error-view.css index 23b969bd35..529b4e3efb 100644 --- a/webroot/rsrc/css/aphront/error-view.css +++ b/webroot/rsrc/css/aphront/error-view.css @@ -1,67 +1,74 @@ /** * @provides aphront-error-view-css */ -.aphront-error-view { - margin: 20px; +.aphront-error-view, +.aphront-error-view-dialogue { border-style: solid; border-width: 1px; } +.aphront-error-view { + margin: 20px; +} +.aphront-error-view-dialogue { + margin: 0px 0px 16px 0px; +} + .device-phone .aphront-error-view { margin: 10px; } .aphront-error-view-body { padding: 10px; line-height: 1.6em; } .aphront-error-view-head { padding: 10px 10px 0 10px; font-weight: bold; color: #333333; } .aphront-error-view-list { margin: 0 0 0 20px; list-style: disc; } .aphront-error-severity-error { color: #b94a48; border-color: #eed3d7; background: #f2dede; } .aphront-error-severity-error .aphront-error-view-head { color: #aa0000; } .aphront-error-severity-warning { color: #bc7837; border-color: #ebdcc1; background: #fcf8e3; } .aphront-error-severity-warning .aphront-error-view-head { color: #bc7837; background: #fcf8e3; } .aphront-error-severity-notice { color: #3a87ad; border-color: #a4bdec; background: #dee7f8; } .aphront-error-severity-notice .aphront-error-view-head { color: #3a87ad; background: #dee7f8; } .aphront-error-severity-nodata { border-color: #dfdfdf; background: #f3f3f3; color: #666; } diff --git a/webroot/rsrc/css/application/base/main-menu-view.css b/webroot/rsrc/css/application/base/main-menu-view.css index cea71e0170..6ce50a0004 100644 --- a/webroot/rsrc/css/application/base/main-menu-view.css +++ b/webroot/rsrc/css/application/base/main-menu-view.css @@ -1,452 +1,436 @@ /** * @provides phabricator-main-menu-view */ /* - Main Menu ----------------------------------------------------------------- Main menu at the top of every page that has chrome. It reacts to resolution changes in order to behave reasonably on tablets and phones. */ .phabricator-main-menu { background: #2d3236; background-image: url(/rsrc/image/main_texture.png); background-repeat: repeat-x; position: relative; box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.25); min-height: 44px; } .device-desktop .phabricator-main-menu { height: 44px; } .phabricator-main-menu a:hover { text-decoration: none; } /* - Logo ---------------------------------------------------------------------- The "Phabricator" logo group in the main menu. On tablet and phone devices, this shows a "reveal" button to expand/collapse the rest of the menu. */ .device-desktop .phabricator-main-menu-group-logo { float: left; } .phabricator-main-menu-logo { display: inline-block; - position: relative; - height: 44px; width: 139px; margin-right: 6px; padding-right: 6px; padding-left: 6px; } .phabricator-main-menu-logo:hover { background-color: #3a4247; } .phabricator-main-menu-logo-image { position: absolute; width: 139px; height: 25px; top: 9px; } .device .phabricator-main-menu-logo { display: none; } /* - Expand/Collapse Button ---------------------------------------------------- On phones, the menu switches to a vertical layout and uses a button to expand or collapse the items. */ .phabricator-main-menu-expand-button { position: absolute; top: 7px; display: block; width: 40px; height: 28px; background-color: #22292d; border-radius: 6px; border: 1px solid #111111; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); } .phabricator-menu-button-icon { position: absolute; width: 24px; height: 20px; top: 5px; left: 8px; } .phabricator-expand-core-menu { left: 10px; } .phabricator-expand-application-menu { right: 10px; } .device-desktop .phabricator-main-menu-expand-button { display: none; } .device .phabricator-main-menu-expand-button { display: block; } .phabricator-core-menu-expanded .phabricator-expand-core-menu, .phabricator-application-menu-expanded .phabricator-expand-application-menu { background-color: #55595d; } /* - Search -------------------------------------------------------------------- The main search input in the menu bar. */ .device-desktop .phabricator-main-menu-search { width: 220px; } .phabricator-main-menu-search-container { padding: 10px 0; position: relative; height: 24px; } .phabricator-main-menu-search-target { position: absolute; top: 46px; } .device-desktop .phabricator-main-menu-search-target { width: 320px; margin-left: -150px; } .device .phabricator-main-menu-search-target { width: 100%; margin-left: -25px; } .device-desktop .phabricator-main-menu-search-container { margin: 0 8px 0 50px; } .device .phabricator-main-menu-search-container { margin: 0 18px 0 60px; } .phabricator-main-menu-search input { outline: 0; margin: 0; width: 100%; right: 0; position: absolute; border: 1px solid #333333; border-radius: 12px; background: #555555; height: 12px; line-height: 12px; box-shadow: 0px 1px 1px rgba(128, 128, 128, 0.25); padding: 6px 32px 6px 10px; } .phabricator-main-menu-search input:focus { background: #c9c9c9; } .phabricator-main-menu-search input.jx-typeahead-placeholder { color: #999999; } .phabricator-main-menu-search button { position: absolute; color: transparent; background: transparent 5px 6px url(/rsrc/image/search.png) no-repeat; border: none; outline: none; box-shadow: none; text-shadow: none; min-width: 0; height: 20px; width: 20px; top: 11px; right: 6px; } .phabricator-main-menu-search-target div.jx-typeahead-results { border-radius: 4px; box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.35); border: 1px solid #33393d; } .phabricator-main-menu-search-target div.jx-typeahead-results a.jx-result { border: 0; } .phabricator-main-menu-search-target div.jx-typeahead-results a.focused, .phabricator-main-menu-search-target div.jx-typeahead-results a:hover { background: #3875d7; } .phabricator-main-search-typeahead-result { display: block; padding: 4px 4px 4px 38px; background-position: 4px 4px; background-size: 25px 25px; background-repeat: no-repeat; } .phabricator-main-search-typeahead-result .result-name { display: block; font-weight: bold; color: #444444; } .focused .phabricator-main-search-typeahead-result .result-name, a:hover .phabricator-main-search-typeahead-result .result-name { color: #eeeeee; } .phabricator-main-search-typeahead-result .result-type { color: #888888; } .focused .phabricator-main-search-typeahead-result .result-type, a:hover .phabricator-main-search-typeahead-result .result-type { color: #dddddd; } /* - Alert --------------------------------------------------------------------- Alert menus are like icon menus but don't obey collapse rules. */ -.device-desktop .phabricator-main-menu-alerts { - display: inline-block; -} - .device .phabricator-main-menu-alerts { - position: absolute; - left: 60px; - right: 60px; - top: 10px; - height: 34px; - text-align: center; + margin-left: 60px; } -.phabricator-main-menu-alert-bubble { +.phabricator-main-menu-alerts { display: inline-block; - position: relative; - width: 26px; - height: 26px; - margin-bottom: 9px; -} - -.phabricator-main-menu-alert-bubble.alert-unread { - width: 46px; + border-radius: 15px; + background: rgba(0,0,0,.2); + height: 20px; + padding: 3px 10px; + margin-top: 9px; } -.phabricator-main-menu-alert-icon { - position: absolute; +.phabricator-main-menu-alert-icon, +.phabricator-main-menu-message-icon { width: 14px; height: 14px; - top: 5px; - left: 6px; + display: block; + float: left; + margin: 2px 0 0 0; } -.phabricator-main-menu-alert-count { - position: absolute; +.alert-notifications .phabricator-main-menu-message-icon { + margin: 3px 0 0 8px; +} + +.phabricator-main-menu-alert-count, +.phabricator-main-menu-message-count { font-weight: bold; - line-height: 22px; - top: 1px; - right: 8px; - left: 20px; + line-height: 20px; color: #ffffff; text-align: center; display: none; + float: left; + margin-left: 3px; } -.phabricator-main-menu-alert-item { - width: 26px; - height: 26px; - margin: 9px; - display: block; -} - -.alert-unread .phabricator-main-menu-alert-count { +.alert-unread .phabricator-main-menu-alert-count, +.message-unread .phabricator-main-menu-message-count { display: block; } /* - Dark Menu ----------------------------------------------------------------- Styles shared between the "core" menu (left button on mobile) and "application" menu (right button on mobile). These styles give the menu a white-on-black appearance. */ .device .phabricator-dark-menu, .device .phabricator-dark-menu a.phabricator-menu-item-type-link { color: #fff; } .device .phabricator-dark-menu .phabricator-menu-item-view { display: block; padding: 4px 0; } .device .phabricator-dark-menu .phabricator-menu-item-type-label { text-transform: uppercase; font-size: 11px; background-color: #151719; padding: 0 0 0 12px; height: 24px; } .device .phabricator-dark-menu .phabricator-menu-item-type-spacer { display: none; } .device .phabricator-dark-menu .phabricator-menu-item-type-label .phabricator-menu-item-name { display: block; padding: 6px 0 0; } .device .phabricator-dark-menu .phabricator-menu-item-type-link { border-width: 1px 0; border-style: solid; border-color: #34373b transparent #282c2d; background-image: url(/rsrc/image/texture/dark-menu.png); } /* - Core Menu ----------------------------------------------------------------- Styles unique to the core menu (left button on mobile). */ .phabricator-core-menu-icon { position: absolute; display: block; width: 28px; height: 28px; } .phabricator-core-menu-profile-image { background-size: 28px 28px; } .device .phabricator-core-menu { display: none; } .device .phabricator-core-menu-expanded .phabricator-core-menu { display: block; padding-top: 44px; } .device .phabricator-core-menu .phabricator-menu-item-type-link { font-size: 15px; min-height: 30px; } .device .phabricator-core-menu .phabricator-menu-item-type-link .phabricator-menu-item-name { margin-left: 40px; line-height: 28px; } .device-desktop .phabricator-core-menu { position: absolute; right: 0; top: 0; vertical-align: top; } .device-desktop .phabricator-core-menu .phabricator-menu-item-name { display: none; } .device-desktop .phabricator-core-menu .phabricator-menu-item-view { display: block; float: left; position: relative; min-width: 38px; height: 44px; } .device-desktop .phabricator-core-menu .phabricator-core-item-device { display: none; } .device-desktop .phabricator-core-menu-icon { top: 9px; left: 6px; } .device .phabricator-core-menu-icon { left: 6px; } .device-desktop .phabricator-core-menu .phabricator-core-menu-item-profile { border-width: 0 1px; border-style: solid; border-color: #44494d; margin: 0 8px; } /* - Application Menu ---------------------------------------------------------- Styles unique to the application menu (right button on mobile). */ .device .phabricator-application-menu-expanded .phabricator-application-menu { display: block; padding-top: 44px; } .phabricator-application-menu { display: none; } .phabricator-application-menu .phabricator-menu-item-type-link .phabricator-menu-item-name { padding-left: 12px; } .device .phabricator-application-menu-expanded .phabricator-application-menu { display: block; padding-top: 44px; } diff --git a/webroot/rsrc/css/application/config/config-options.css b/webroot/rsrc/css/application/config/config-options.css index f7ba294c92..e821dc57ef 100644 --- a/webroot/rsrc/css/application/config/config-options.css +++ b/webroot/rsrc/css/application/config/config-options.css @@ -1,47 +1,47 @@ /** * @provides config-options-css */ .config-option-table { width: 100%; border-collapse: collapse; border: 1px solid #cccccc; } .config-option-table th, .config-option-table td { padding: 4px 12px; border: 1px solid #cccccc; } .config-option-table th { background: #e9e9e9; text-align: right; white-space: nowrap; } .config-option-table th em { font-weight: normal; color: #666666; } .config-option-table td { color: #333333; width: 100%; } .config-option-table .column-labels th { font-weight: bold; color: #333333; text-align: center; background: #e0e0e0; } .config-options-current-value { - padding: 0 6px 2px; + padding: 0 10px 8px; white-space: pre-wrap; } .config-options-current-value span { - color: #666666; + color: #777; } diff --git a/webroot/rsrc/css/application/conpherence/header-pane.css b/webroot/rsrc/css/application/conpherence/header-pane.css index 37acd45523..d007091de3 100644 --- a/webroot/rsrc/css/application/conpherence/header-pane.css +++ b/webroot/rsrc/css/application/conpherence/header-pane.css @@ -1,41 +1,50 @@ /** * @provides conpherence-header-pane-css */ +#conpherence-main-pane { + position: relative; +} + .conpherence-header-pane { border-bottom: 1px solid #ccc; background: #fff; - height: 50px; + height: 80px; width: 100%; } .conpherence-header-pane .edit { - position: relative; float: right; margin: 16px 16px 0px 0px; + height: 50px; + width: 50px; + background-image: url('/rsrc/image/actions/edit.png'); } .conpherence-header-pane .header-image { position: absolute; + top: 15px; + left: 15px; height: 50px; width: 50px; } .conpherence-header-pane .title { position: relative; font-size: 16px; - left: 62px; - top: 6px; + font-weight: bold; + left: 77px; + top: 21px; max-width: 80%; overflow-x: auto; } .conpherence-header-pane .subtitle { position: relative; - left: 62px; - top: 6px; + left: 77px; + top: 21px; color: #bfbfbf; max-width: 80%; } diff --git a/webroot/rsrc/css/application/conpherence/menu.css b/webroot/rsrc/css/application/conpherence/menu.css index 07417b8be9..0558de8204 100644 --- a/webroot/rsrc/css/application/conpherence/menu.css +++ b/webroot/rsrc/css/application/conpherence/menu.css @@ -1,121 +1,124 @@ /** * @provides conpherence-menu-css */ .no-conpherences-menu-item { - color: #ffffff; + color: #a1a5a9; border-top: solid 1px #3B3D3E; - padding: 20px 0px 20px 66px; + padding: 20px 0; + margin: 0px auto; + width: 320px; + text-align: center; } .conpherence-menu .phabricator-nav-column-background, .conpherence-menu .phabricator-nav-local { width: 320px; } .conpherence-menu .phabricator-nav-local { top: 44px; bottom: 0px; } .conpherence-menu .phabricator-nav-drag { left: 320px; } .device-desktop .conpherence-menu .phabricator-nav-content { margin-left: 320px !important; } .conpherence-menu .phabricator-menu-view { overflow-x: hidden; overflow-y: auto; margin-bottom: 0; } .conpherence-menu .conpherence-menu-item-view { display: block; height: 70px; width: 100%; overflow: hidden; position: relative; text-decoration: none; border-top: solid 1px #3B3D3E; border-bottom: solid 1px #1C1F21; border-right: 0; border-left: 2px solid transparent; } .conpherence-menu .conpherence-selected { background: rgba(0, 0, 0, .6); border-left: 2px solid #66CCFF; } .conpherence-menu .conpherence-menu-item-view:hover { background-image: url('/rsrc/image/texture/dark-menu-hover.png'); } .conpherence-menu .conpherence-menu-item-view .conpherence-menu-item-image { top: 6px; left: 6px; display: block; position: absolute; width: 50px; height: 50px; border: 4px solid rgb(29, 32, 34); border-radius: 2px; } .conpherence-menu .conpherence-menu-item-view .conpherence-menu-item-title { display: block; margin-top: 12px; margin-left: 70px; text-align: left; font-weight: bold; font-size: 12px; color: #ffffff; text-shadow: 0px 1px 1px #000000; } .conpherence-menu .conpherence-menu-item-view .conpherence-menu-item-subtitle { display: block; color: #bfbfbf; font-size: 11px; margin-top: 2px; margin-left: 70px; font-style: italic; } .conpherence-menu .conpherence-menu-item-view .conpherence-menu-item-message-text { display: block; color: #66CCFF; font-size: 12px; margin-top: 4px; margin-left: 70px; } .conpherence-menu .conpherence-menu-item-view .conpherence-menu-item-unread-count { position: absolute; left: 48px; top: 3px; background: #f00; border-radius: 10px; color: white; font-weight: bold; padding: 1px 6px 2px; border: 1px solid #a00; font-size: 12px; } .conpherence-menu .hide-unread-count .conpherence-menu-item-unread-count, .conpherence-menu .conpherence-selected .conpherence-menu-item-unread-count { display: none; } .conpherence-menu .conpherence-menu-item-view .conpherence-menu-item-date { position: absolute; top: 10px; right: 12px; color: white; font-size: 12px; } diff --git a/webroot/rsrc/css/application/conpherence/message-pane.css b/webroot/rsrc/css/application/conpherence/message-pane.css index 25975815c3..e714b9f37f 100644 --- a/webroot/rsrc/css/application/conpherence/message-pane.css +++ b/webroot/rsrc/css/application/conpherence/message-pane.css @@ -1,95 +1,99 @@ /** * @provides conpherence-message-pane-css */ .conpherence-message-pane { position: fixed; left: 320px; top: 94px; min-width: 320px; width: auto; height: 100%; margin: 0px 320px 0px 0px; } .conpherence-message-pane .conpherence-messages { position: fixed; left: 320px; right: 321px; - top: 94px; - bottom: 225px; + top: 124px; + bottom: 142px; overflow-y: auto; + box-shadow: inset 1px 5px 5px rgba(0,0,0,0.1); } .conpherence-message-pane .phabricator-form-view { border-width: 0; background: none; - height: 224px; + height: 143px; padding: 0; position: fixed; bottom: 0; left: 320px; right: 321px; } .device-tablet .conpherence-message-pane .phabricator-form-view, .device-tablet .conpherence-message-pane .conpherence-messages, .device-tablet .conpherence-message-pane { left: 0px; } .conpherence-message-pane .aphront-form-input { margin: 0; width: 100%; } .conpherence-message-pane .phabricator-transaction-view { - margin: 1em 1.25em 1em 1.25em; - display: block; + margin: 10px 0 10px 15px; } .conpherence-message-pane .phabricator-transaction-detail { border-width: 0; } .conpherence-message-pane .phabricator-transaction-header { background: none; } .conpherence-message-pane .phabricator-transaction-info { background: none; } .conpherence-message-pane .phabricator-transaction-content { background: none; } .conpherence-message-pane .conpherence-edited .phabricator-transaction-content { - font-size: 12px; - padding: 0em 1em 0em 1em; + padding: 0 1em 0 1em; margin-top: -4px; } .conpherence-message-pane .aphront-form-control { padding: 0; } .conpherence-message-pane .aphront-form-control-submit { margin-right: 8px; } .conpherence-message-pane .remarkup-assist-bar { border-width: 1px 0 0; border-color: #CCC; + border-bottom: transparent; } .conpherence-message-pane .remarkup-assist-textarea { - border-width: 1px 0 1px 0; - border-color: #CCC; + border-width: 0 0 1px 0; + border-color: #e7e7e7; } .conpherence-message-pane .remarkup-assist-textarea:focus { outline: none; } +.conpherence-message-pane .aphront-form-input textarea { + padding: 6px; + height: 6em; +} diff --git a/webroot/rsrc/css/application/conpherence/widget-pane.css b/webroot/rsrc/css/application/conpherence/widget-pane.css index 9c5a3c0c8f..224adc2db5 100644 --- a/webroot/rsrc/css/application/conpherence/widget-pane.css +++ b/webroot/rsrc/css/application/conpherence/widget-pane.css @@ -1,19 +1,20 @@ /** * @provides conpherence-widget-pane-css */ .conpherence-widget-pane { position: fixed; right: 0px; - top: 94px; + top: 125px; width: 320px; height: 100%; border-width: 0 0 0 1px; border-color: #CCC; border-style: solid; + background: url('/rsrc/image/texture/dust_background.jpg'); } .conpherence-widget-pane .aphront-form-input { margin: 0; width: 100%; } diff --git a/webroot/rsrc/css/layout/phabricator-object-item-list-view.css b/webroot/rsrc/css/layout/phabricator-object-item-list-view.css index 25c01eabb6..adc8c3ee8a 100644 --- a/webroot/rsrc/css/layout/phabricator-object-item-list-view.css +++ b/webroot/rsrc/css/layout/phabricator-object-item-list-view.css @@ -1,179 +1,188 @@ /** * @provides phabricator-object-item-list-view-css */ .phabricator-object-item-list-view { padding: 8px 6px; background: #f4f5f6; } +.phabricator-object-item-list-view.phabricator-object-list-stackable .phabricator-object-item { + margin: -1px 0 0 0; +} + .device-desktop .phabricator-object-item-list-view { padding: 20px; } .phabricator-object-item { background: #ffffff; border-style: solid; - border-color: #d7d7d7 #e4e3e4 #bcbcbd #d7d7d7; + border-color: #c0c5d1; border-width: 1px 1px 1px 3px; - margin: 3px 0; + margin: 5px 0; overflow: hidden; box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.10); } +.phabricator-object-list-stackable .phabricator-object-item { + border-width: 1px; +} + .device-desktop .phabricator-object-item { margin: 0 0 5px 0; } .phabricator-object-item-name { display: block; - padding: 4px 8px 4px; + padding: 8px 10px 2px; font-weight: bold; + font-size: 14px; } .phabricator-object-item-content { overflow: hidden; } /* - Attribute List ------------------------------------------------------------ Object attributes, commonly used to render created date, etc. */ .phabricator-object-item-attributes { - padding: 0px 8px 4px; + padding: 0px 10px 8px; } .phabricator-object-item-attribute { display: inline; - color: #555555; - font-size: 11px; + color: #777; + font-size: 13px; } .phabricator-object-item-attribute-spacer { padding: 0 4px; } /* - Icons --------------------------------------------------------------------- Icons, which show object state. On mobile, they are rendered without labels to save space. */ .phabricator-object-item-icons { float: right; - padding: 2px 4px 0; + padding: 10px 10px 0; } /* NOTE: The main content is an "overflow: hidden" div which we give a right margin so it doesn't overlap the icons. The margin is slightly larger than the width + padding of the icon div, so the icons have some space even if the content is wider than available space. */ .device-desktop .phabricator-object-item-icons { width: 120px; } .device-desktop .phabricator-object-item-content { margin-right: 132px; } .device .phabricator-object-item-icons { width: 18px; } .device .phabricator-object-item-content { margin-right: 30px; } .device .phabricator-object-item-icon-label { display: none; vertical-align: middle; } .phabricator-object-item-icon { position: relative; font-size: 11px; color: #666666; text-align: right; white-space: nowrap; overflow: hidden; min-height: 18px; line-height: 18px; } .device-desktop .phabricator-object-item-icon { padding-right: 22px; } .phabricator-object-item-icon-image { position: absolute; right: 2px; top: 2px; width: 14px; height: 14px; } /* - Bar Colors ---------------------------------------------------------------- Colors for the left-hand border bars, used to indicate object status or other attributes. */ .phabricator-object-item-bar-color-red { border-left-color: #cc0000; } .phabricator-object-item-bar-color-orange { border-left-color: #cc7300; } .phabricator-object-item-bar-color-yellow { border-left-color: #ccc000; } .phabricator-object-item-bar-color-green { border-left-color: #009b2d; } .phabricator-object-item-bar-color-sky { border-left-color: #6498cf; } .phabricator-object-item-bar-color-blue { border-left-color: #00659a; } .phabricator-object-item-bar-color-indigo { border-left-color: #3a00cc; } .phabricator-object-item-bar-color-violet { border-left-color: #67009b; } .phabricator-object-item-bar-color-grey { border-left-color: #999999; } .phabricator-object-item-bar-color-black { border-left-color: #333333; } /* - Effects ------------------------------------------------------------------- Effects like highlighted items. */ .phabricator-object-item-highlighted { background: #ffff88; } diff --git a/webroot/rsrc/css/layout/phabricator-source-code-view.css b/webroot/rsrc/css/layout/phabricator-source-code-view.css index f12e248c2b..fcd4058225 100644 --- a/webroot/rsrc/css/layout/phabricator-source-code-view.css +++ b/webroot/rsrc/css/layout/phabricator-source-code-view.css @@ -1,45 +1,45 @@ /** * @provides phabricator-source-code-view-css */ .phabricator-source-code-container { overflow-x: auto; overflow-y: hidden; } .phabricator-source-code { white-space: pre-wrap; padding: 2px 8px 1px; } .phabricator-source-line { text-align: right; padding: 2px 6px 1px 12px; border-right: 1px solid #dbdbdb; font-weight: bold; color: #555555; /* When the user selects rows of source, don't visibly select the line numbers beside them. We use JS to strip the line numbers out when the user copies the text. */ -moz-user-select: -moz-none; -khtml-user-select: none; -webkit-user-select: none; -ms-user-select: none; user-select: none; } .phabricator-source-code-summary { - margin-bottom: 4px; + padding-bottom: 8px; } /* If a Paste has enormously long lines, truncate them in the summary on the list page. They'll be fully visible on the Paste itself. */ .phabricator-source-code-summary .phabricator-source-code-container { overflow-x: hidden; } .phabricator-source-code-summary .phabricator-source-code { white-space: nowrap; } diff --git a/webroot/rsrc/css/sprite-apps-large.css b/webroot/rsrc/css/sprite-apps-large.css index 62746eca15..6d35b7d401 100644 --- a/webroot/rsrc/css/sprite-apps-large.css +++ b/webroot/rsrc/css/sprite-apps-large.css @@ -1,627 +1,643 @@ /** * @provides sprite-apps-large-css * @generated */ .sprite-apps-large { background-image: url(/rsrc/image/sprite-apps-large.png); background-repeat: no-repeat; } @media only screen and (min-device-pixel-ratio: 1.5), only screen and (-webkit-min-device-pixel-ratio: 1.5) { .sprite-apps-large { background-image: url(/rsrc/image/sprite-apps-large-X2.png); background-size: 348px 377px; } } .app-application-light-large { background-position: 0px 0px; } .app-application-dark-large { background-position: -29px 0px; } .app-application-blue-large, .phabricator-crumb-view:hover .app-application-dark-large { background-position: -58px 0px; } .app-application-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-application-light-large { background-position: -87px 0px; } .app-audit-light-large { background-position: -116px 0px; } .app-audit-dark-large { background-position: -145px 0px; } .app-audit-blue-large, .phabricator-crumb-view:hover .app-audit-dark-large { background-position: -174px 0px; } .app-audit-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-audit-light-large { background-position: -203px 0px; } .app-calendar-light-large { background-position: -232px 0px; } .app-calendar-dark-large { background-position: -261px 0px; } .app-calendar-blue-large, .phabricator-crumb-view:hover .app-calendar-dark-large { background-position: -290px 0px; } .app-calendar-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-calendar-light-large { background-position: -319px 0px; } .app-conduit-light-large { background-position: 0px -29px; } .app-conduit-dark-large { background-position: -29px -29px; } .app-conduit-blue-large, .phabricator-crumb-view:hover .app-conduit-dark-large { background-position: -58px -29px; } .app-conduit-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-conduit-light-large { background-position: -87px -29px; } -.app-countdown-light-large { +.app-conpherence-light-large { background-position: -116px -29px; } -.app-countdown-dark-large { +.app-conpherence-dark-large { background-position: -145px -29px; } -.app-countdown-blue-large, .phabricator-crumb-view:hover .app-countdown-dark-large { +.app-conpherence-blue-large, .phabricator-crumb-view:hover .app-conpherence-dark-large { background-position: -174px -29px; } -.app-countdown-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-countdown-light-large { +.app-conpherence-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-conpherence-light-large { background-position: -203px -29px; } -.app-daemon-light-large { +.app-countdown-light-large { background-position: -232px -29px; } -.app-daemon-dark-large { +.app-countdown-dark-large { background-position: -261px -29px; } -.app-daemon-blue-large, .phabricator-crumb-view:hover .app-daemon-dark-large { +.app-countdown-blue-large, .phabricator-crumb-view:hover .app-countdown-dark-large { background-position: -290px -29px; } -.app-daemon-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-daemon-light-large { +.app-countdown-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-countdown-light-large { background-position: -319px -29px; } -.app-differential-light-large { +.app-daemon-light-large { background-position: 0px -58px; } -.app-differential-dark-large { +.app-daemon-dark-large { background-position: -29px -58px; } -.app-differential-blue-large, .phabricator-crumb-view:hover .app-differential-dark-large { +.app-daemon-blue-large, .phabricator-crumb-view:hover .app-daemon-dark-large { background-position: -58px -58px; } -.app-differential-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-differential-light-large { +.app-daemon-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-daemon-light-large { background-position: -87px -58px; } -.app-diffusion-light-large { +.app-differential-light-large { background-position: -116px -58px; } -.app-diffusion-dark-large { +.app-differential-dark-large { background-position: -145px -58px; } -.app-diffusion-blue-large, .phabricator-crumb-view:hover .app-diffusion-dark-large { +.app-differential-blue-large, .phabricator-crumb-view:hover .app-differential-dark-large { background-position: -174px -58px; } -.app-diffusion-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-diffusion-light-large { +.app-differential-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-differential-light-large { background-position: -203px -58px; } -.app-diviner-light-large { +.app-diffusion-light-large { background-position: -232px -58px; } -.app-diviner-dark-large { +.app-diffusion-dark-large { background-position: -261px -58px; } -.app-diviner-blue-large, .phabricator-crumb-view:hover .app-diviner-dark-large { +.app-diffusion-blue-large, .phabricator-crumb-view:hover .app-diffusion-dark-large { background-position: -290px -58px; } -.app-diviner-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-diviner-light-large { +.app-diffusion-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-diffusion-light-large { background-position: -319px -58px; } -.app-drydock-light-large { +.app-diviner-light-large { background-position: 0px -87px; } -.app-drydock-dark-large { +.app-diviner-dark-large { background-position: -29px -87px; } -.app-drydock-blue-large, .phabricator-crumb-view:hover .app-drydock-dark-large { +.app-diviner-blue-large, .phabricator-crumb-view:hover .app-diviner-dark-large { background-position: -58px -87px; } -.app-drydock-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-drydock-light-large { +.app-diviner-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-diviner-light-large { background-position: -87px -87px; } -.app-fact-light-large { +.app-drydock-light-large { background-position: -116px -87px; } -.app-fact-dark-large { +.app-drydock-dark-large { background-position: -145px -87px; } -.app-fact-blue-large, .phabricator-crumb-view:hover .app-fact-dark-large { +.app-drydock-blue-large, .phabricator-crumb-view:hover .app-drydock-dark-large { background-position: -174px -87px; } -.app-fact-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-fact-light-large { +.app-drydock-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-drydock-light-large { background-position: -203px -87px; } -.app-feed-light-large { +.app-fact-light-large { background-position: -232px -87px; } -.app-feed-dark-large { +.app-fact-dark-large { background-position: -261px -87px; } -.app-feed-blue-large, .phabricator-crumb-view:hover .app-feed-dark-large { +.app-fact-blue-large, .phabricator-crumb-view:hover .app-fact-dark-large { background-position: -290px -87px; } -.app-feed-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-feed-light-large { +.app-fact-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-fact-light-large { background-position: -319px -87px; } -.app-files-light-large { +.app-feed-light-large { background-position: 0px -116px; } -.app-files-dark-large { +.app-feed-dark-large { background-position: -29px -116px; } -.app-files-blue-large, .phabricator-crumb-view:hover .app-files-dark-large { +.app-feed-blue-large, .phabricator-crumb-view:hover .app-feed-dark-large { background-position: -58px -116px; } -.app-files-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-files-light-large { +.app-feed-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-feed-light-large { background-position: -87px -116px; } -.app-flags-light-large { +.app-files-light-large { background-position: -116px -116px; } -.app-flags-dark-large { +.app-files-dark-large { background-position: -145px -116px; } -.app-flags-blue-large, .phabricator-crumb-view:hover .app-flags-dark-large { +.app-files-blue-large, .phabricator-crumb-view:hover .app-files-dark-large { background-position: -174px -116px; } -.app-flags-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-flags-light-large { +.app-files-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-files-light-large { background-position: -203px -116px; } -.app-help-light-large { +.app-flags-light-large { background-position: -232px -116px; } -.app-help-dark-large { +.app-flags-dark-large { background-position: -261px -116px; } -.app-help-blue-large, .phabricator-crumb-view:hover .app-help-dark-large { +.app-flags-blue-large, .phabricator-crumb-view:hover .app-flags-dark-large { background-position: -290px -116px; } -.app-help-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-help-light-large { +.app-flags-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-flags-light-large { background-position: -319px -116px; } -.app-herald-light-large { +.app-help-light-large { background-position: 0px -145px; } -.app-herald-dark-large { +.app-help-dark-large { background-position: -29px -145px; } -.app-herald-blue-large, .phabricator-crumb-view:hover .app-herald-dark-large { +.app-help-blue-large, .phabricator-crumb-view:hover .app-help-dark-large { background-position: -58px -145px; } -.app-herald-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-herald-light-large { +.app-help-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-help-light-large { background-position: -87px -145px; } -.app-home-light-large { +.app-herald-light-large { background-position: -116px -145px; } -.app-home-dark-large { +.app-herald-dark-large { background-position: -145px -145px; } -.app-home-blue-large, .phabricator-crumb-view:hover .app-home-dark-large { +.app-herald-blue-large, .phabricator-crumb-view:hover .app-herald-dark-large { background-position: -174px -145px; } -.app-home-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-home-light-large { +.app-herald-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-herald-light-large { background-position: -203px -145px; } -.app-logo-light-large { +.app-home-light-large { background-position: -232px -145px; } -.app-logo-dark-large { +.app-home-dark-large { background-position: -261px -145px; } -.app-logo-blue-large, .phabricator-crumb-view:hover .app-logo-dark-large { +.app-home-blue-large, .phabricator-crumb-view:hover .app-home-dark-large { background-position: -290px -145px; } -.app-logo-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-logo-light-large { +.app-home-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-home-light-large { background-position: -319px -145px; } -.app-macro-light-large { +.app-logo-light-large { background-position: 0px -174px; } -.app-macro-dark-large { +.app-logo-dark-large { background-position: -29px -174px; } -.app-macro-blue-large, .phabricator-crumb-view:hover .app-macro-dark-large { +.app-logo-blue-large, .phabricator-crumb-view:hover .app-logo-dark-large { background-position: -58px -174px; } -.app-macro-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-macro-light-large { +.app-logo-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-logo-light-large { background-position: -87px -174px; } -.app-mail-light-large { +.app-macro-light-large { background-position: -116px -174px; } -.app-mail-dark-large { +.app-macro-dark-large { background-position: -145px -174px; } -.app-mail-blue-large, .phabricator-crumb-view:hover .app-mail-dark-large { +.app-macro-blue-large, .phabricator-crumb-view:hover .app-macro-dark-large { background-position: -174px -174px; } -.app-mail-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-mail-light-large { +.app-macro-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-macro-light-large { background-position: -203px -174px; } -.app-maniphest-light-large { +.app-mail-light-large { background-position: -232px -174px; } -.app-maniphest-dark-large { +.app-mail-dark-large { background-position: -261px -174px; } -.app-maniphest-blue-large, .phabricator-crumb-view:hover .app-maniphest-dark-large { +.app-mail-blue-large, .phabricator-crumb-view:hover .app-mail-dark-large { background-position: -290px -174px; } -.app-maniphest-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-maniphest-light-large { +.app-mail-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-mail-light-large { background-position: -319px -174px; } -.app-metamta-light-large { +.app-maniphest-light-large { background-position: 0px -203px; } -.app-metamta-dark-large { +.app-maniphest-dark-large { background-position: -29px -203px; } -.app-metamta-blue-large, .phabricator-crumb-view:hover .app-metamta-dark-large { +.app-maniphest-blue-large, .phabricator-crumb-view:hover .app-maniphest-dark-large { background-position: -58px -203px; } -.app-metamta-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-metamta-light-large { +.app-maniphest-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-maniphest-light-large { background-position: -87px -203px; } -.app-owners-light-large { +.app-metamta-light-large { background-position: -116px -203px; } -.app-owners-dark-large { +.app-metamta-dark-large { background-position: -145px -203px; } -.app-owners-blue-large, .phabricator-crumb-view:hover .app-owners-dark-large { +.app-metamta-blue-large, .phabricator-crumb-view:hover .app-metamta-dark-large { background-position: -174px -203px; } -.app-owners-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-owners-light-large { +.app-metamta-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-metamta-light-large { background-position: -203px -203px; } -.app-paste-light-large { +.app-owners-light-large { background-position: -232px -203px; } -.app-paste-dark-large { +.app-owners-dark-large { background-position: -261px -203px; } -.app-paste-blue-large, .phabricator-crumb-view:hover .app-paste-dark-large { +.app-owners-blue-large, .phabricator-crumb-view:hover .app-owners-dark-large { background-position: -290px -203px; } -.app-paste-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-paste-light-large { +.app-owners-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-owners-light-large { background-position: -319px -203px; } -.app-people-light-large { +.app-paste-light-large { background-position: 0px -232px; } -.app-people-dark-large { +.app-paste-dark-large { background-position: -29px -232px; } -.app-people-blue-large, .phabricator-crumb-view:hover .app-people-dark-large { +.app-paste-blue-large, .phabricator-crumb-view:hover .app-paste-dark-large { background-position: -58px -232px; } -.app-people-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-people-light-large { +.app-paste-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-paste-light-large { background-position: -87px -232px; } -.app-phame-light-large { +.app-people-light-large { background-position: -116px -232px; } -.app-phame-dark-large { +.app-people-dark-large { background-position: -145px -232px; } -.app-phame-blue-large, .phabricator-crumb-view:hover .app-phame-dark-large { +.app-people-blue-large, .phabricator-crumb-view:hover .app-people-dark-large { background-position: -174px -232px; } -.app-phame-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-phame-light-large { +.app-people-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-people-light-large { background-position: -203px -232px; } -.app-phid-light-large { +.app-phame-light-large { background-position: -232px -232px; } -.app-phid-dark-large { +.app-phame-dark-large { background-position: -261px -232px; } -.app-phid-blue-large, .phabricator-crumb-view:hover .app-phid-dark-large { +.app-phame-blue-large, .phabricator-crumb-view:hover .app-phame-dark-large { background-position: -290px -232px; } -.app-phid-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-phid-light-large { +.app-phame-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-phame-light-large { background-position: -319px -232px; } -.app-pholio-light-large { +.app-phid-light-large { background-position: 0px -261px; } -.app-pholio-dark-large { +.app-phid-dark-large { background-position: -29px -261px; } -.app-pholio-blue-large, .phabricator-crumb-view:hover .app-pholio-dark-large { +.app-phid-blue-large, .phabricator-crumb-view:hover .app-phid-dark-large { background-position: -58px -261px; } -.app-pholio-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-pholio-light-large { +.app-phid-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-phid-light-large { background-position: -87px -261px; } -.app-phpast-light-large { +.app-pholio-light-large { background-position: -116px -261px; } -.app-phpast-dark-large { +.app-pholio-dark-large { background-position: -145px -261px; } -.app-phpast-blue-large, .phabricator-crumb-view:hover .app-phpast-dark-large { +.app-pholio-blue-large, .phabricator-crumb-view:hover .app-pholio-dark-large { background-position: -174px -261px; } -.app-phpast-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-phpast-light-large { +.app-pholio-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-pholio-light-large { background-position: -203px -261px; } -.app-phriction-light-large { +.app-phpast-light-large { background-position: -232px -261px; } -.app-phriction-dark-large { +.app-phpast-dark-large { background-position: -261px -261px; } -.app-phriction-blue-large, .phabricator-crumb-view:hover .app-phriction-dark-large { +.app-phpast-blue-large, .phabricator-crumb-view:hover .app-phpast-dark-large { background-position: -290px -261px; } -.app-phriction-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-phriction-light-large { +.app-phpast-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-phpast-light-large { background-position: -319px -261px; } -.app-ponder-light-large { +.app-phriction-light-large { background-position: 0px -290px; } -.app-ponder-dark-large { +.app-phriction-dark-large { background-position: -29px -290px; } -.app-ponder-blue-large, .phabricator-crumb-view:hover .app-ponder-dark-large { +.app-phriction-blue-large, .phabricator-crumb-view:hover .app-phriction-dark-large { background-position: -58px -290px; } -.app-ponder-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-ponder-light-large { +.app-phriction-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-phriction-light-large { background-position: -87px -290px; } -.app-power-light-large { +.app-ponder-light-large { background-position: -116px -290px; } -.app-power-dark-large { +.app-ponder-dark-large { background-position: -145px -290px; } -.app-power-blue-large, .phabricator-crumb-view:hover .app-power-dark-large { +.app-ponder-blue-large, .phabricator-crumb-view:hover .app-ponder-dark-large { background-position: -174px -290px; } -.app-power-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-power-light-large { +.app-ponder-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-ponder-light-large { background-position: -203px -290px; } -.app-projects-light-large { +.app-power-light-large { background-position: -232px -290px; } -.app-projects-dark-large { +.app-power-dark-large { background-position: -261px -290px; } -.app-projects-blue-large, .phabricator-crumb-view:hover .app-projects-dark-large { +.app-power-blue-large, .phabricator-crumb-view:hover .app-power-dark-large { background-position: -290px -290px; } -.app-projects-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-projects-light-large { +.app-power-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-power-light-large { background-position: -319px -290px; } -.app-repositories-light-large { +.app-projects-light-large { background-position: 0px -319px; } -.app-repositories-dark-large { +.app-projects-dark-large { background-position: -29px -319px; } -.app-repositories-blue-large, .phabricator-crumb-view:hover .app-repositories-dark-large { +.app-projects-blue-large, .phabricator-crumb-view:hover .app-projects-dark-large { background-position: -58px -319px; } -.app-repositories-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-repositories-light-large { +.app-projects-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-projects-light-large { background-position: -87px -319px; } -.app-settings-light-large { +.app-repositories-light-large { background-position: -116px -319px; } -.app-settings-dark-large { +.app-repositories-dark-large { background-position: -145px -319px; } -.app-settings-blue-large, .phabricator-crumb-view:hover .app-settings-dark-large { +.app-repositories-blue-large, .phabricator-crumb-view:hover .app-repositories-dark-large { background-position: -174px -319px; } -.app-settings-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-settings-light-large { +.app-repositories-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-repositories-light-large { background-position: -203px -319px; } -.app-setup-light-large { +.app-settings-light-large { background-position: -232px -319px; } -.app-setup-dark-large { +.app-settings-dark-large { background-position: -261px -319px; } -.app-setup-blue-large, .phabricator-crumb-view:hover .app-setup-dark-large { +.app-settings-blue-large, .phabricator-crumb-view:hover .app-settings-dark-large { background-position: -290px -319px; } -.app-setup-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-setup-light-large { +.app-settings-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-settings-light-large { background-position: -319px -319px; } -.app-slowvote-light-large { +.app-setup-light-large { background-position: 0px -348px; } -.app-slowvote-dark-large { +.app-setup-dark-large { background-position: -29px -348px; } -.app-slowvote-blue-large, .phabricator-crumb-view:hover .app-slowvote-dark-large { +.app-setup-blue-large, .phabricator-crumb-view:hover .app-setup-dark-large { background-position: -58px -348px; } -.app-slowvote-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-slowvote-light-large { +.app-setup-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-setup-light-large { background-position: -87px -348px; } -.app-uiexamples-light-large { +.app-slowvote-light-large { background-position: -116px -348px; } -.app-uiexamples-dark-large { +.app-slowvote-dark-large { background-position: -145px -348px; } -.app-uiexamples-blue-large, .phabricator-crumb-view:hover .app-uiexamples-dark-large { +.app-slowvote-blue-large, .phabricator-crumb-view:hover .app-slowvote-dark-large { background-position: -174px -348px; } -.app-uiexamples-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-uiexamples-light-large { +.app-slowvote-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-slowvote-light-large { background-position: -203px -348px; } + +.app-uiexamples-light-large { + background-position: -232px -348px; +} + +.app-uiexamples-dark-large { + background-position: -261px -348px; +} + +.app-uiexamples-blue-large, .phabricator-crumb-view:hover .app-uiexamples-dark-large { + background-position: -290px -348px; +} + +.app-uiexamples-glow-large, .device-desktop .phabricator-dark-menu a:hover .app-uiexamples-light-large { + background-position: -319px -348px; +} diff --git a/webroot/rsrc/css/sprite-apps.css b/webroot/rsrc/css/sprite-apps.css index 3d113f1703..2ed08533c2 100644 --- a/webroot/rsrc/css/sprite-apps.css +++ b/webroot/rsrc/css/sprite-apps.css @@ -1,171 +1,175 @@ /** * @provides sprite-apps-css * @generated */ .sprite-apps { background-image: url(/rsrc/image/sprite-apps.png); background-repeat: no-repeat; } @media only screen and (min-device-pixel-ratio: 1.5), only screen and (-webkit-min-device-pixel-ratio: 1.5) { .sprite-apps { background-image: url(/rsrc/image/sprite-apps-X2.png); background-size: 90px 105px; } } .app-application-dark { background-position: 0px 0px; } .app-audit-dark { background-position: -15px 0px; } .app-calendar-dark { background-position: -30px 0px; } .app-conduit-dark { background-position: -45px 0px; } -.app-countdown-dark { +.app-conpherence-dark { background-position: -60px 0px; } -.app-daemon-dark { +.app-countdown-dark { background-position: -75px 0px; } -.app-differential-dark { +.app-daemon-dark { background-position: 0px -15px; } -.app-diffusion-dark { +.app-differential-dark { background-position: -15px -15px; } -.app-diviner-dark { +.app-diffusion-dark { background-position: -30px -15px; } -.app-drydock-dark { +.app-diviner-dark { background-position: -45px -15px; } -.app-fact-dark { +.app-drydock-dark { background-position: -60px -15px; } -.app-feed-dark { +.app-fact-dark { background-position: -75px -15px; } -.app-files-dark { +.app-feed-dark { background-position: 0px -30px; } -.app-flags-dark { +.app-files-dark { background-position: -15px -30px; } -.app-help-dark { +.app-flags-dark { background-position: -30px -30px; } -.app-herald-dark { +.app-help-dark { background-position: -45px -30px; } -.app-home-dark { +.app-herald-dark { background-position: -60px -30px; } -.app-logo-dark { +.app-home-dark { background-position: -75px -30px; } -.app-macro-dark { +.app-logo-dark { background-position: 0px -45px; } -.app-mail-dark { +.app-macro-dark { background-position: -15px -45px; } -.app-maniphest-dark { +.app-mail-dark { background-position: -30px -45px; } -.app-metamta-dark { +.app-maniphest-dark { background-position: -45px -45px; } -.app-owners-dark { +.app-metamta-dark { background-position: -60px -45px; } -.app-paste-dark { +.app-owners-dark { background-position: -75px -45px; } -.app-people-dark { +.app-paste-dark { background-position: 0px -60px; } -.app-phame-dark { +.app-people-dark { background-position: -15px -60px; } -.app-phid-dark { +.app-phame-dark { background-position: -30px -60px; } -.app-pholio-dark { +.app-phid-dark { background-position: -45px -60px; } -.app-phpast-dark { +.app-pholio-dark { background-position: -60px -60px; } -.app-phriction-dark { +.app-phpast-dark { background-position: -75px -60px; } -.app-ponder-dark { +.app-phriction-dark { background-position: 0px -75px; } -.app-power-dark { +.app-ponder-dark { background-position: -15px -75px; } -.app-projects-dark { +.app-power-dark { background-position: -30px -75px; } -.app-repositories-dark { +.app-projects-dark { background-position: -45px -75px; } -.app-settings-dark { +.app-repositories-dark { background-position: -60px -75px; } -.app-setup-dark { +.app-settings-dark { background-position: -75px -75px; } -.app-slowvote-dark { +.app-setup-dark { background-position: 0px -90px; } -.app-uiexamples-dark { +.app-slowvote-dark { background-position: -15px -90px; } + +.app-uiexamples-dark { + background-position: -30px -90px; +} diff --git a/webroot/rsrc/css/sprite-menu.css b/webroot/rsrc/css/sprite-menu.css index dfa3a84e16..367081901b 100644 --- a/webroot/rsrc/css/sprite-menu.css +++ b/webroot/rsrc/css/sprite-menu.css @@ -1,55 +1,59 @@ /** * @provides sprite-menu-css * @generated */ .sprite-menu { background-image: url(/rsrc/image/sprite-menu.png); background-repeat: no-repeat; } @media only screen and (min-device-pixel-ratio: 1.5), only screen and (-webkit-min-device-pixel-ratio: 1.5) { .sprite-menu { background-image: url(/rsrc/image/sprite-menu-X2.png); - background-size: 140px 127px; + background-size: 140px 88px; } } -.phabricator-main-menu-alert-bubble { - background-position: 0px -68px; -} - -.phabricator-main-menu-alert-bubble.alert-unread { - background-position: 0px -41px; -} - .alert-notifications .phabricator-main-menu-alert-icon { background-position: 0px 0px; } .alert-notifications:hover .phabricator-main-menu-alert-icon { background-position: -15px 0px; } .alert-notifications.alert-unread .phabricator-main-menu-alert-icon { - background-position: -27px -68px; + background-position: -30px 0px; } .phabricator-crumb-divider { - background-position: 0px -95px; + background-position: 0px -56px; } .menu-icon-eye { - background-position: -47px -41px; + background-position: -10px -56px; } .menu-icon-app { - background-position: -42px -68px; + background-position: -35px -56px; } .phabricator-main-menu-logo-image { + background-position: 0px -30px; +} + +.alert-notifications .phabricator-main-menu-message-icon { background-position: 0px -15px; } + +.alert-notifications:hover .phabricator-main-menu-message-icon { + background-position: -15px -15px; +} + +.alert-notifications.message-unread .phabricator-main-menu-message-icon { + background-position: -30px -15px; +} diff --git a/webroot/rsrc/image/actions/edit.png b/webroot/rsrc/image/actions/edit.png new file mode 100644 index 0000000000..b12c39f62c Binary files /dev/null and b/webroot/rsrc/image/actions/edit.png differ diff --git a/webroot/rsrc/image/sprite-apps-X2.png b/webroot/rsrc/image/sprite-apps-X2.png index 9c55c92c98..5557ad7d11 100644 Binary files a/webroot/rsrc/image/sprite-apps-X2.png and b/webroot/rsrc/image/sprite-apps-X2.png differ diff --git a/webroot/rsrc/image/sprite-apps-large-X2.png b/webroot/rsrc/image/sprite-apps-large-X2.png index 6502108978..9893a221f7 100644 Binary files a/webroot/rsrc/image/sprite-apps-large-X2.png and b/webroot/rsrc/image/sprite-apps-large-X2.png differ diff --git a/webroot/rsrc/image/sprite-apps-large.png b/webroot/rsrc/image/sprite-apps-large.png index 7b1dd2180d..e3fd9c766a 100644 Binary files a/webroot/rsrc/image/sprite-apps-large.png and b/webroot/rsrc/image/sprite-apps-large.png differ diff --git a/webroot/rsrc/image/sprite-apps.png b/webroot/rsrc/image/sprite-apps.png index f652203bc1..d941c561f5 100644 Binary files a/webroot/rsrc/image/sprite-apps.png and b/webroot/rsrc/image/sprite-apps.png differ diff --git a/webroot/rsrc/image/sprite-menu-X2.png b/webroot/rsrc/image/sprite-menu-X2.png index dde32caa00..7152466947 100644 Binary files a/webroot/rsrc/image/sprite-menu-X2.png and b/webroot/rsrc/image/sprite-menu-X2.png differ diff --git a/webroot/rsrc/image/sprite-menu.png b/webroot/rsrc/image/sprite-menu.png index dc89ff9ecf..4eb96afad6 100644 Binary files a/webroot/rsrc/image/sprite-menu.png and b/webroot/rsrc/image/sprite-menu.png differ diff --git a/webroot/rsrc/js/application/core/behavior-drag-and-drop.js b/webroot/rsrc/js/application/core/behavior-drag-and-drop.js index 4e115e1826..c5e8432910 100644 --- a/webroot/rsrc/js/application/core/behavior-drag-and-drop.js +++ b/webroot/rsrc/js/application/core/behavior-drag-and-drop.js @@ -1,103 +1,112 @@ /** * @provides javelin-behavior-aphront-drag-and-drop * @requires javelin-behavior * javelin-dom + * phabricator-file-upload * phabricator-drag-and-drop-file-upload */ JX.behavior('aphront-drag-and-drop', function(config) { // The control renders hidden by default; if we don't have support for // drag-and-drop just leave it hidden. if (!JX.PhabricatorDragAndDropFileUpload.isSupported()) { return; } // Show the control, since we have browser support. JX.$(config.control).style.display = ''; - var files = config.value || {}; + var files = {}; + if (config.value) { + for (var k in config.value) { + var file = config.value[k]; + files[k] = new JX.PhabricatorFileUpload() + .setPHID(file.phid) + .setMarkup(file.html); + } + } var pending = 0; var list = JX.$(config.list); var drop = new JX.PhabricatorDragAndDropFileUpload(JX.$(config.list)) .setURI(config.uri); drop.listen('didBeginDrag', function(e) { JX.DOM.alterClass(list, config.activatedClass, true); }); drop.listen('didEndDrag', function(e) { JX.DOM.alterClass(list, config.activatedClass, false); }); drop.listen('willUpload', function(f) { pending++; redraw(); }); drop.listen('didUpload', function(f) { files[f.getPHID()] = f; // This redraws "Upload complete!" pending--; redraw(true); // This redraws the instructions. setTimeout(redraw, 1000); }); drop.start(); redraw(); JX.DOM.listen( list, 'click', 'aphront-attached-file-view-remove', function(e) { e.kill(); delete files[e.getTarget().getAttribute('ref')]; redraw(); }); function redraw(completed) { var items = []; for (var k in files) { var file = files[k]; items.push(JX.$N('div', {}, JX.$H(file.getMarkup()))); items.push(JX.$N( 'input', { type: "hidden", name: config.name + "[" + file.getPHID() + "]", value: file.getPHID() })); } var status; var extra = ''; if (!pending) { if (completed) { status = JX.$H('Upload complete!'); } else { arrow = String.fromCharCode(0x21EA); status = JX.$H( arrow + ' Drag and Drop files here to upload them.'); extra = ' drag-and-drop-file-target'; } } else { status = JX.$H( 'Uploading ' + parseInt(pending, 10) + ' files...'); } status = JX.$N( 'div', {className: 'drag-and-drop-instructions' + extra}, status); items.push(status); JX.DOM.setContent(list, items); } });