diff --git a/.gitignore b/.gitignore index 4e3a12e5e9..3b552e4a35 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,8 @@ # Places for users to add custom resources. /resources/cows/custom/* /resources/figlet/custom/* + +# Peast +/support/peast/peast*.tar.gz +/support/peast/peast*.zip +/support/peast/lib/* diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 913be922f2..4d40341f6b 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -8,14 +8,14 @@ return array( 'names' => array( 'conpherence.pkg.css' => 'b2d6f4b8', - 'conpherence.pkg.js' => '020aebcf', + 'conpherence.pkg.js' => 'b9c54e6f', 'core.pkg.css' => 'dac75b15', - 'core.pkg.js' => '83c66b30', - 'dark-console.pkg.js' => '187792c2', + 'core.pkg.js' => '206c9549', + 'dark-console.pkg.js' => '40bfef42', 'differential.pkg.css' => '0dac8831', - 'differential.pkg.js' => '46fcb3af', + 'differential.pkg.js' => '69da62a0', 'diffusion.pkg.css' => '91e57dc1', - 'diffusion.pkg.js' => 'd06aa1f7', + 'diffusion.pkg.js' => '3fba0510', 'maniphest.pkg.css' => '31ad4266', 'maniphest.pkg.js' => 'f17ec1b3', 'rsrc/audio/basic/alert.mp3' => '17889334', @@ -180,72 +180,72 @@ return array( 'rsrc/css/sprite-login.css' => '0abdf921', 'rsrc/css/sprite-tokens.css' => '330edc9e', 'rsrc/css/syntax/syntax-default.css' => 'c0307dc6', - 'rsrc/externals/d3/d3.min.js' => 'e97b4b78', + 'rsrc/externals/d3/d3.min.js' => 'dae76c10', 'rsrc/externals/font/fontawesome/fontawesome-webfont.woff2' => '351fd46a', 'rsrc/externals/font/lato/lato-bold.woff2' => '389fcdb1', 'rsrc/externals/font/lato/lato-bolditalic.woff2' => 'bc7d1274', 'rsrc/externals/font/lato/lato-italic.woff2' => 'fffc0d8c', 'rsrc/externals/font/lato/lato-regular.woff2' => '8f846797', - 'rsrc/externals/javelin/core/Event.js' => '1dbe260d', - 'rsrc/externals/javelin/core/Stratcom.js' => '0889b835', + 'rsrc/externals/javelin/core/Event.js' => '38bc5a44', + 'rsrc/externals/javelin/core/Stratcom.js' => '86e7c900', 'rsrc/externals/javelin/core/__tests__/event-stop-and-kill.js' => '048472d2', 'rsrc/externals/javelin/core/__tests__/install.js' => '14a7e671', 'rsrc/externals/javelin/core/__tests__/stratcom.js' => 'a28464bb', 'rsrc/externals/javelin/core/__tests__/util.js' => 'e29a4354', - 'rsrc/externals/javelin/core/init.js' => '98e6504a', + 'rsrc/externals/javelin/core/init.js' => '1767ee66', 'rsrc/externals/javelin/core/init_node.js' => '16961339', 'rsrc/externals/javelin/core/install.js' => '5902260c', - 'rsrc/externals/javelin/core/util.js' => '472cda1c', + 'rsrc/externals/javelin/core/util.js' => '32a82ac2', 'rsrc/externals/javelin/docs/Base.js' => '5a401d7d', 'rsrc/externals/javelin/docs/onload.js' => 'ee58fb62', - 'rsrc/externals/javelin/ext/fx/Color.js' => '78f811c9', - 'rsrc/externals/javelin/ext/fx/FX.js' => '34450586', - 'rsrc/externals/javelin/ext/reactor/core/DynVal.js' => '202a2e85', - 'rsrc/externals/javelin/ext/reactor/core/Reactor.js' => '1c850a26', - 'rsrc/externals/javelin/ext/reactor/core/ReactorNode.js' => '72960bc1', - 'rsrc/externals/javelin/ext/reactor/core/ReactorNodeCalmer.js' => '225bbb98', - 'rsrc/externals/javelin/ext/reactor/dom/RDOM.js' => '6cfa0008', - 'rsrc/externals/javelin/ext/view/HTMLView.js' => 'f8c4e135', - 'rsrc/externals/javelin/ext/view/View.js' => '289bf236', - 'rsrc/externals/javelin/ext/view/ViewInterpreter.js' => '876506b6', - 'rsrc/externals/javelin/ext/view/ViewPlaceholder.js' => 'a9942052', - 'rsrc/externals/javelin/ext/view/ViewRenderer.js' => '9aae2b66', - 'rsrc/externals/javelin/ext/view/ViewVisitor.js' => '308f9fe4', + 'rsrc/externals/javelin/ext/fx/Color.js' => '36576292', + 'rsrc/externals/javelin/ext/fx/FX.js' => '0a9fdbb9', + 'rsrc/externals/javelin/ext/reactor/core/DynVal.js' => 'e47745d1', + 'rsrc/externals/javelin/ext/reactor/core/Reactor.js' => '93ec1300', + 'rsrc/externals/javelin/ext/reactor/core/ReactorNode.js' => '9af9ca69', + 'rsrc/externals/javelin/ext/reactor/core/ReactorNodeCalmer.js' => '7a7abb10', + 'rsrc/externals/javelin/ext/reactor/dom/RDOM.js' => 'eac68b41', + 'rsrc/externals/javelin/ext/view/HTMLView.js' => '122e6e60', + 'rsrc/externals/javelin/ext/view/View.js' => 'f2977446', + 'rsrc/externals/javelin/ext/view/ViewInterpreter.js' => '339f5c61', + 'rsrc/externals/javelin/ext/view/ViewPlaceholder.js' => '7bdf6903', + 'rsrc/externals/javelin/ext/view/ViewRenderer.js' => 'a2a6143c', + 'rsrc/externals/javelin/ext/view/ViewVisitor.js' => '8b0e0928', 'rsrc/externals/javelin/ext/view/__tests__/HTMLView.js' => '6e50a13f', 'rsrc/externals/javelin/ext/view/__tests__/View.js' => 'd284be5d', 'rsrc/externals/javelin/ext/view/__tests__/ViewInterpreter.js' => 'a9f35511', 'rsrc/externals/javelin/ext/view/__tests__/ViewRenderer.js' => '3a1b81f6', - 'rsrc/externals/javelin/lib/Cookie.js' => '05d290ef', - 'rsrc/externals/javelin/lib/DOM.js' => '3c6f9405', - 'rsrc/externals/javelin/lib/History.js' => '030b4f7a', - 'rsrc/externals/javelin/lib/JSON.js' => '541f81c3', - 'rsrc/externals/javelin/lib/Leader.js' => '0d2490ce', - 'rsrc/externals/javelin/lib/Mask.js' => '7c4d8998', - 'rsrc/externals/javelin/lib/Quicksand.js' => 'd3799cb4', - 'rsrc/externals/javelin/lib/Request.js' => '84e6891f', - 'rsrc/externals/javelin/lib/Resource.js' => '20514cc2', - 'rsrc/externals/javelin/lib/Routable.js' => '6a18c42e', - 'rsrc/externals/javelin/lib/Router.js' => '32755edb', - 'rsrc/externals/javelin/lib/Scrollbar.js' => 'a43ae2ae', - 'rsrc/externals/javelin/lib/Sound.js' => 'd4cc2d2a', - 'rsrc/externals/javelin/lib/URI.js' => '1fcfd5c0', - 'rsrc/externals/javelin/lib/Vector.js' => 'e9c80beb', - 'rsrc/externals/javelin/lib/WebSocket.js' => 'fdc13e4e', - 'rsrc/externals/javelin/lib/Workflow.js' => 'cc1553f3', + 'rsrc/externals/javelin/lib/Cookie.js' => '05b28aa2', + 'rsrc/externals/javelin/lib/DOM.js' => '7d83258e', + 'rsrc/externals/javelin/lib/History.js' => '533a88ab', + 'rsrc/externals/javelin/lib/JSON.js' => '4e373d4b', + 'rsrc/externals/javelin/lib/Leader.js' => '467214de', + 'rsrc/externals/javelin/lib/Mask.js' => '5ce5c490', + 'rsrc/externals/javelin/lib/Quicksand.js' => '904b29cd', + 'rsrc/externals/javelin/lib/Request.js' => '4e3567dd', + 'rsrc/externals/javelin/lib/Resource.js' => '699676a1', + 'rsrc/externals/javelin/lib/Routable.js' => '45f4ef11', + 'rsrc/externals/javelin/lib/Router.js' => '8841c560', + 'rsrc/externals/javelin/lib/Scrollbar.js' => '70743772', + 'rsrc/externals/javelin/lib/Sound.js' => '755f30a4', + 'rsrc/externals/javelin/lib/URI.js' => '5ab77007', + 'rsrc/externals/javelin/lib/Vector.js' => '4b8bc989', + 'rsrc/externals/javelin/lib/WebSocket.js' => 'd9979d19', + 'rsrc/externals/javelin/lib/Workflow.js' => '0c69620e', 'rsrc/externals/javelin/lib/__tests__/Cookie.js' => 'ca686f71', 'rsrc/externals/javelin/lib/__tests__/DOM.js' => '4566e249', 'rsrc/externals/javelin/lib/__tests__/JSON.js' => '710377ae', 'rsrc/externals/javelin/lib/__tests__/URI.js' => '6fff0c2b', 'rsrc/externals/javelin/lib/__tests__/behavior.js' => '8426ebeb', 'rsrc/externals/javelin/lib/behavior.js' => '1b6acc2a', - 'rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js' => '89a1ae3a', - 'rsrc/externals/javelin/lib/control/typeahead/Typeahead.js' => '0507519c', - 'rsrc/externals/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js' => 'a241536a', - 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js' => '22ee68a5', - 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js' => '23387297', - 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js' => '5a79f6c3', - 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js' => '8badee71', - 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadStaticSource.js' => '80bff3af', + 'rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js' => '6691be26', + 'rsrc/externals/javelin/lib/control/typeahead/Typeahead.js' => '6bb4873a', + 'rsrc/externals/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js' => '9a68421a', + 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js' => 'ce39158d', + 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js' => '63598f73', + 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js' => '8d038327', + 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js' => '670c0b8a', + 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadStaticSource.js' => 'b6bafedf', 'rsrc/favicons/favicon-16x16.png' => '4c51a03a', 'rsrc/favicons/mask-icon.svg' => 'db699fe1', 'rsrc/image/avatar.png' => '0d17c6c4', @@ -290,181 +290,181 @@ return array( 'rsrc/image/sprite-login.png' => '6c73e3ca', 'rsrc/image/sprite-tokens-X2.png' => '5ddc639b', 'rsrc/image/sprite-tokens.png' => '15f84535', - 'rsrc/js/application/aphlict/Aphlict.js' => '022516b4', + 'rsrc/js/application/aphlict/Aphlict.js' => '7e93c8d6', 'rsrc/js/application/aphlict/behavior-aphlict-dropdown.js' => 'e9a2940f', - 'rsrc/js/application/aphlict/behavior-aphlict-listen.js' => '4e61fa88', - 'rsrc/js/application/aphlict/behavior-aphlict-status.js' => 'c3703a16', - 'rsrc/js/application/aphlict/behavior-desktop-notifications-control.js' => '070679fe', - 'rsrc/js/application/calendar/behavior-day-view.js' => '727a5a61', - 'rsrc/js/application/calendar/behavior-event-all-day.js' => '0b1bc990', - 'rsrc/js/application/calendar/behavior-month-view.js' => '158c64e0', + 'rsrc/js/application/aphlict/behavior-aphlict-listen.js' => 'a4859af5', + 'rsrc/js/application/aphlict/behavior-aphlict-status.js' => 'da402bda', + 'rsrc/js/application/aphlict/behavior-desktop-notifications-control.js' => '9e3e8389', + 'rsrc/js/application/calendar/behavior-day-view.js' => '1a6b7115', + 'rsrc/js/application/calendar/behavior-event-all-day.js' => 'a64672b5', + 'rsrc/js/application/calendar/behavior-month-view.js' => 'e5e044e8', 'rsrc/js/application/config/behavior-reorder-fields.js' => '2539f834', - 'rsrc/js/application/conpherence/ConpherenceThreadManager.js' => 'aec8e38c', - 'rsrc/js/application/conpherence/behavior-conpherence-search.js' => '91befbcc', - 'rsrc/js/application/conpherence/behavior-durable-column.js' => 'fa6f30b2', - 'rsrc/js/application/conpherence/behavior-menu.js' => '8c2ed2bf', - 'rsrc/js/application/conpherence/behavior-participant-pane.js' => '43ba89a2', - 'rsrc/js/application/conpherence/behavior-pontificate.js' => '4ae58b5a', + 'rsrc/js/application/conpherence/ConpherenceThreadManager.js' => '3b255926', + 'rsrc/js/application/conpherence/behavior-conpherence-search.js' => 'afe38d96', + 'rsrc/js/application/conpherence/behavior-durable-column.js' => 'a2d381d8', + 'rsrc/js/application/conpherence/behavior-menu.js' => '299e50bd', + 'rsrc/js/application/conpherence/behavior-participant-pane.js' => '1fabcc80', + 'rsrc/js/application/conpherence/behavior-pontificate.js' => '0946ebd6', 'rsrc/js/application/conpherence/behavior-quicksand-blacklist.js' => '5a6f6a06', - 'rsrc/js/application/conpherence/behavior-toggle-widget.js' => '8f959ad0', + 'rsrc/js/application/conpherence/behavior-toggle-widget.js' => '194194c0', 'rsrc/js/application/countdown/timer.js' => '6a162524', 'rsrc/js/application/daemon/behavior-bulk-job-reload.js' => '3829a3cf', 'rsrc/js/application/dashboard/behavior-dashboard-async-panel.js' => '9c01e364', 'rsrc/js/application/dashboard/behavior-dashboard-move-panels.js' => 'a2ab19be', 'rsrc/js/application/dashboard/behavior-dashboard-query-panel-select.js' => '1e413dc9', 'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => '0116d3e8', - 'rsrc/js/application/diff/DiffChangeset.js' => 'd7d3ba75', - 'rsrc/js/application/diff/DiffChangesetList.js' => 'cc2c5de5', - 'rsrc/js/application/diff/DiffInline.js' => '9c775532', - 'rsrc/js/application/diff/DiffInlineContentState.js' => 'aa51efb4', - 'rsrc/js/application/diff/DiffPathView.js' => '8207abf9', - 'rsrc/js/application/diff/DiffTreeView.js' => '5d83623b', + 'rsrc/js/application/diff/DiffChangeset.js' => '83560c3e', + 'rsrc/js/application/diff/DiffChangesetList.js' => '3bc5d0a2', + 'rsrc/js/application/diff/DiffInline.js' => '7fb61bce', + 'rsrc/js/application/diff/DiffInlineContentState.js' => '09b25d79', + 'rsrc/js/application/diff/DiffPathView.js' => '06c422f5', + 'rsrc/js/application/diff/DiffTreeView.js' => '284cdce8', 'rsrc/js/application/differential/behavior-diff-radios.js' => '925fe8cd', - 'rsrc/js/application/differential/behavior-populate.js' => 'b86ef6c2', - 'rsrc/js/application/diffusion/DiffusionLocateFileSource.js' => '6c798a10', - 'rsrc/js/application/diffusion/ExternalEditorLinkEngine.js' => '48a8641f', + 'rsrc/js/application/differential/behavior-populate.js' => 'fabc70ac', + 'rsrc/js/application/diffusion/DiffusionLocateFileSource.js' => 'c2129f37', + 'rsrc/js/application/diffusion/ExternalEditorLinkEngine.js' => '0597e99e', 'rsrc/js/application/diffusion/behavior-audit-preview.js' => 'b7b73831', 'rsrc/js/application/diffusion/behavior-commit-branches.js' => '4b671572', - 'rsrc/js/application/diffusion/behavior-commit-graph.js' => '56d8091e', + 'rsrc/js/application/diffusion/behavior-commit-graph.js' => '9bc1dd14', 'rsrc/js/application/diffusion/behavior-locate-file.js' => '4c77f259', 'rsrc/js/application/diffusion/behavior-pull-lastmodified.js' => 'c715c123', 'rsrc/js/application/doorkeeper/behavior-doorkeeper-tag.js' => '6a85bc5a', 'rsrc/js/application/drydock/drydock-live-operation-status.js' => '47a0728b', - 'rsrc/js/application/fact/Chart.js' => 'ce6f8e3d', - 'rsrc/js/application/fact/ChartCurtainView.js' => '86954222', - 'rsrc/js/application/fact/ChartFunctionLabel.js' => '81de1dab', - 'rsrc/js/application/files/behavior-document-engine.js' => '243d6c22', + 'rsrc/js/application/fact/Chart.js' => '71779eee', + 'rsrc/js/application/fact/ChartCurtainView.js' => '52837786', + 'rsrc/js/application/fact/ChartFunctionLabel.js' => 'b04c258c', + 'rsrc/js/application/files/behavior-document-engine.js' => '9d02b360', 'rsrc/js/application/files/behavior-icon-composer.js' => '38a6cedb', 'rsrc/js/application/files/behavior-launch-icon-composer.js' => 'a17b84f1', - 'rsrc/js/application/harbormaster/behavior-harbormaster-log.js' => 'b347a301', - 'rsrc/js/application/herald/HeraldRuleEditor.js' => '2633bef7', - 'rsrc/js/application/herald/PathTypeahead.js' => 'ad486db3', + 'rsrc/js/application/harbormaster/behavior-harbormaster-log.js' => 'd3115244', + 'rsrc/js/application/herald/HeraldRuleEditor.js' => '459fbefc', + 'rsrc/js/application/herald/PathTypeahead.js' => '66ed7808', 'rsrc/js/application/herald/herald-rule-editor.js' => '0922e81d', 'rsrc/js/application/maniphest/behavior-batch-selector.js' => '1f5c3cb3', - 'rsrc/js/application/maniphest/behavior-line-chart.js' => 'ad258e28', + 'rsrc/js/application/maniphest/behavior-line-chart.js' => 'c3ea5759', 'rsrc/js/application/maniphest/behavior-list-edit.js' => 'c687e867', - 'rsrc/js/application/owners/OwnersPathEditor.js' => '2a8b62d9', + 'rsrc/js/application/owners/OwnersPathEditor.js' => 'e44abfd6', 'rsrc/js/application/owners/owners-path-editor.js' => 'ff688a7a', 'rsrc/js/application/passphrase/passphrase-credential-control.js' => '48fe33d0', - 'rsrc/js/application/pholio/behavior-pholio-mock-edit.js' => '3eed1f2b', - 'rsrc/js/application/pholio/behavior-pholio-mock-view.js' => '5aa1544e', + 'rsrc/js/application/pholio/behavior-pholio-mock-edit.js' => 'e10d1263', + 'rsrc/js/application/pholio/behavior-pholio-mock-view.js' => 'e9592389', 'rsrc/js/application/phortune/behavior-stripe-payment-form.js' => '02cb4398', 'rsrc/js/application/phortune/behavior-test-payment-form.js' => '4a7fb02b', - 'rsrc/js/application/phortune/phortune-credit-card-form.js' => 'd12d214f', - 'rsrc/js/application/policy/behavior-policy-control.js' => '0eaa33a9', + 'rsrc/js/application/phortune/phortune-credit-card-form.js' => '58883f56', + 'rsrc/js/application/policy/behavior-policy-control.js' => '274f48cf', 'rsrc/js/application/policy/behavior-policy-rule-editor.js' => '9347f172', - 'rsrc/js/application/projects/WorkboardBoard.js' => 'b46d88c5', - 'rsrc/js/application/projects/WorkboardCard.js' => '0392a5d8', - 'rsrc/js/application/projects/WorkboardCardTemplate.js' => '84f82dad', - 'rsrc/js/application/projects/WorkboardColumn.js' => 'c3d24e63', - 'rsrc/js/application/projects/WorkboardController.js' => '7474d31f', - 'rsrc/js/application/projects/WorkboardDropEffect.js' => '8e0aa661', - 'rsrc/js/application/projects/WorkboardHeader.js' => '111bfd2d', - 'rsrc/js/application/projects/WorkboardHeaderTemplate.js' => 'ebe83a6b', - 'rsrc/js/application/projects/WorkboardOrderTemplate.js' => '03e8891f', - 'rsrc/js/application/projects/behavior-project-boards.js' => '58cb6a88', + 'rsrc/js/application/projects/WorkboardBoard.js' => 'a4fd3b57', + 'rsrc/js/application/projects/WorkboardCard.js' => 'b82fc780', + 'rsrc/js/application/projects/WorkboardCardTemplate.js' => 'e63ab0ec', + 'rsrc/js/application/projects/WorkboardColumn.js' => 'c74a690a', + 'rsrc/js/application/projects/WorkboardController.js' => '78148921', + 'rsrc/js/application/projects/WorkboardDropEffect.js' => 'e342e2b4', + 'rsrc/js/application/projects/WorkboardHeader.js' => '5a59fb82', + 'rsrc/js/application/projects/WorkboardHeaderTemplate.js' => '02a2c910', + 'rsrc/js/application/projects/WorkboardOrderTemplate.js' => 'f9d95e77', + 'rsrc/js/application/projects/behavior-project-boards.js' => 'b852b68e', 'rsrc/js/application/projects/behavior-project-create.js' => '34c53422', 'rsrc/js/application/projects/behavior-reorder-columns.js' => '8ac32fd9', - 'rsrc/js/application/repository/repository-crossreference.js' => '44d48cd1', + 'rsrc/js/application/repository/repository-crossreference.js' => 'f5bba944', 'rsrc/js/application/search/behavior-reorder-profile-menu-items.js' => 'e5bdb730', 'rsrc/js/application/search/behavior-reorder-queries.js' => 'b86f297f', - 'rsrc/js/application/transactions/behavior-comment-actions.js' => '4dffaeb2', - 'rsrc/js/application/transactions/behavior-reorder-configs.js' => '4842f137', - 'rsrc/js/application/transactions/behavior-reorder-fields.js' => '0ad8d31f', - 'rsrc/js/application/transactions/behavior-show-older-transactions.js' => '8b5c7d65', + 'rsrc/js/application/transactions/behavior-comment-actions.js' => '19124eb6', + 'rsrc/js/application/transactions/behavior-reorder-configs.js' => '636c1d6d', + 'rsrc/js/application/transactions/behavior-reorder-fields.js' => '0235b35d', + 'rsrc/js/application/transactions/behavior-show-older-transactions.js' => '02d0d179', 'rsrc/js/application/transactions/behavior-transaction-comment-form.js' => '2bdadf1a', 'rsrc/js/application/transactions/behavior-transaction-list.js' => '9cec214e', - 'rsrc/js/application/trigger/TriggerRule.js' => '41b7b4f6', - 'rsrc/js/application/trigger/TriggerRuleControl.js' => '5faf27b9', - 'rsrc/js/application/trigger/TriggerRuleEditor.js' => 'b49fd60c', - 'rsrc/js/application/trigger/TriggerRuleType.js' => '4feea7d3', - 'rsrc/js/application/trigger/trigger-rule-editor.js' => '398fdf13', + 'rsrc/js/application/trigger/TriggerRule.js' => 'a9747130', + 'rsrc/js/application/trigger/TriggerRuleControl.js' => '199300af', + 'rsrc/js/application/trigger/TriggerRuleEditor.js' => '516b27db', + 'rsrc/js/application/trigger/TriggerRuleType.js' => 'e6bc2ced', + 'rsrc/js/application/trigger/trigger-rule-editor.js' => '89cfe5ef', 'rsrc/js/application/typeahead/behavior-typeahead-browse.js' => '70245195', - 'rsrc/js/application/typeahead/behavior-typeahead-search.js' => '7b139193', + 'rsrc/js/application/typeahead/behavior-typeahead-search.js' => '5ec2a4b0', 'rsrc/js/application/uiexample/gesture-example.js' => '242dedd0', 'rsrc/js/application/uiexample/notification-example.js' => '29819b75', - 'rsrc/js/core/Busy.js' => '5202e831', - 'rsrc/js/core/DragAndDropFileUpload.js' => '4370900d', - 'rsrc/js/core/DraggableList.js' => '0169e425', - 'rsrc/js/core/Favicon.js' => '7930776a', - 'rsrc/js/core/FileUpload.js' => '331676ea', - 'rsrc/js/core/Hovercard.js' => '6199f752', - 'rsrc/js/core/HovercardList.js' => 'de4b4919', - 'rsrc/js/core/KeyboardShortcut.js' => '1a844c06', - 'rsrc/js/core/KeyboardShortcutManager.js' => '81debc48', - 'rsrc/js/core/MultirowRowManager.js' => '5b54c823', - 'rsrc/js/core/Notification.js' => 'a9b91e3f', - 'rsrc/js/core/Prefab.js' => '5793d835', - 'rsrc/js/core/RemarkupMetadata.js' => 'e40c4991', - 'rsrc/js/core/ShapedRequest.js' => '995f5102', - 'rsrc/js/core/TextAreaUtils.js' => 'f340a484', - 'rsrc/js/core/Title.js' => '43bc9360', - 'rsrc/js/core/ToolTip.js' => '83754533', + 'rsrc/js/core/Busy.js' => 'ec0c35b0', + 'rsrc/js/core/DragAndDropFileUpload.js' => '184e5354', + 'rsrc/js/core/DraggableList.js' => '0092408f', + 'rsrc/js/core/Favicon.js' => '6be35145', + 'rsrc/js/core/FileUpload.js' => 'bcb07115', + 'rsrc/js/core/Hovercard.js' => 'b4afcd89', + 'rsrc/js/core/HovercardList.js' => 'c5a9b42b', + 'rsrc/js/core/KeyboardShortcut.js' => 'beca9a7a', + 'rsrc/js/core/KeyboardShortcutManager.js' => '4c65e1f0', + 'rsrc/js/core/MultirowRowManager.js' => '037c04be', + 'rsrc/js/core/Notification.js' => 'cf6b743b', + 'rsrc/js/core/Prefab.js' => '8673c75c', + 'rsrc/js/core/RemarkupMetadata.js' => 'fe7cdb3b', + 'rsrc/js/core/ShapedRequest.js' => 'bdc40a6b', + 'rsrc/js/core/TextAreaUtils.js' => '9cde5660', + 'rsrc/js/core/Title.js' => 'c6d00cb9', + 'rsrc/js/core/ToolTip.js' => '09ff9853', 'rsrc/js/core/behavior-audio-source.js' => '6e815b50', 'rsrc/js/core/behavior-autofocus.js' => '65bb0011', 'rsrc/js/core/behavior-badge-view.js' => '92cdd7b6', 'rsrc/js/core/behavior-bulk-editor.js' => 'aa6d2308', 'rsrc/js/core/behavior-choose-control.js' => '04f8a1e3', 'rsrc/js/core/behavior-copy.js' => '96b63a02', - 'rsrc/js/core/behavior-detect-timezone.js' => '78bc5d94', - 'rsrc/js/core/behavior-device.js' => 'ac2b1e01', + 'rsrc/js/core/behavior-detect-timezone.js' => '4321459b', + 'rsrc/js/core/behavior-device.js' => 'f941cb00', 'rsrc/js/core/behavior-drag-and-drop-textarea.js' => '6bc7ccf7', - 'rsrc/js/core/behavior-fancy-datepicker.js' => 'b545d0a0', + 'rsrc/js/core/behavior-fancy-datepicker.js' => '7aa2cf57', 'rsrc/js/core/behavior-form.js' => 'c60fb44a', 'rsrc/js/core/behavior-gesture.js' => 'b58d1a2a', - 'rsrc/js/core/behavior-global-drag-and-drop.js' => '1cab0e9a', - 'rsrc/js/core/behavior-high-security-warning.js' => 'dae2d55b', + 'rsrc/js/core/behavior-global-drag-and-drop.js' => 'b7bd4fb1', + 'rsrc/js/core/behavior-high-security-warning.js' => '8261d229', 'rsrc/js/core/behavior-history-install.js' => '6a1583a8', - 'rsrc/js/core/behavior-hovercard.js' => '0a4b35f2', + 'rsrc/js/core/behavior-hovercard.js' => 'f29b7914', 'rsrc/js/core/behavior-keyboard-pager.js' => '1325b731', - 'rsrc/js/core/behavior-keyboard-shortcuts.js' => '42c44e8b', - 'rsrc/js/core/behavior-lightbox-attachments.js' => '14c7ab36', - 'rsrc/js/core/behavior-line-linker.js' => '8cbbcfc5', - 'rsrc/js/core/behavior-linked-container.js' => '74446546', + 'rsrc/js/core/behavior-keyboard-shortcuts.js' => '408a69dd', + 'rsrc/js/core/behavior-lightbox-attachments.js' => '978a8ed3', + 'rsrc/js/core/behavior-line-linker.js' => 'ab273e9d', + 'rsrc/js/core/behavior-linked-container.js' => '861b6cde', 'rsrc/js/core/behavior-more.js' => '506aa3f4', 'rsrc/js/core/behavior-object-selector.js' => '98ef467f', - 'rsrc/js/core/behavior-oncopy.js' => 'da8f5259', - 'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => 'daceb29a', + 'rsrc/js/core/behavior-oncopy.js' => 'd336267a', + 'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => '957ff438', 'rsrc/js/core/behavior-read-only-warning.js' => 'b9109f8f', 'rsrc/js/core/behavior-redirect.js' => '407ee861', - 'rsrc/js/core/behavior-refresh-csrf.js' => '46116c01', - 'rsrc/js/core/behavior-remarkup-load-image.js' => '202bfa3f', - 'rsrc/js/core/behavior-remarkup-preview.js' => 'd8a86cfb', + 'rsrc/js/core/behavior-refresh-csrf.js' => '345119db', + 'rsrc/js/core/behavior-remarkup-load-image.js' => 'c51e6aa0', + 'rsrc/js/core/behavior-remarkup-preview.js' => '05a2b50b', 'rsrc/js/core/behavior-reorder-applications.js' => 'aa371860', 'rsrc/js/core/behavior-reveal-content.js' => 'b105a3a6', - 'rsrc/js/core/behavior-scrollbar.js' => '92388bae', - 'rsrc/js/core/behavior-search-typeahead.js' => 'f782e983', + 'rsrc/js/core/behavior-scrollbar.js' => '19830cb0', + 'rsrc/js/core/behavior-search-typeahead.js' => '4f888644', 'rsrc/js/core/behavior-select-content.js' => 'c538cbfc', 'rsrc/js/core/behavior-select-on-click.js' => '66365ee2', - 'rsrc/js/core/behavior-setup-check-https.js' => '01384686', - 'rsrc/js/core/behavior-time-typeahead.js' => '5803b9e7', + 'rsrc/js/core/behavior-setup-check-https.js' => 'adb0a739', + 'rsrc/js/core/behavior-time-typeahead.js' => 'cd00e3d4', 'rsrc/js/core/behavior-toggle-class.js' => '32db8374', 'rsrc/js/core/behavior-tokenizer.js' => '3b4899b0', - 'rsrc/js/core/behavior-tooltip.js' => '73ecc1f8', - 'rsrc/js/core/behavior-user-menu.js' => '60cd9241', + 'rsrc/js/core/behavior-tooltip.js' => '1e25ede7', + 'rsrc/js/core/behavior-user-menu.js' => '808d36b2', 'rsrc/js/core/behavior-watch-anchor.js' => 'a77e2cbd', 'rsrc/js/core/behavior-workflow.js' => '9623adc1', - 'rsrc/js/core/darkconsole/DarkLog.js' => '3b869402', - 'rsrc/js/core/darkconsole/DarkMessage.js' => '26cd4b73', - 'rsrc/js/core/darkconsole/behavior-dark-console.js' => '457f4d16', - 'rsrc/js/core/phtize.js' => '2f1db1ed', + 'rsrc/js/core/darkconsole/DarkLog.js' => 'd8a27e0d', + 'rsrc/js/core/darkconsole/DarkMessage.js' => 'ef0160d8', + 'rsrc/js/core/darkconsole/behavior-dark-console.js' => '4794450e', + 'rsrc/js/core/phtize.js' => '4c2bf506', 'rsrc/js/phui/behavior-phui-dropdown-menu.js' => '5cf0501a', - 'rsrc/js/phui/behavior-phui-file-upload.js' => 'e150bd50', - 'rsrc/js/phui/behavior-phui-selectable-list.js' => 'b26a41e4', + 'rsrc/js/phui/behavior-phui-file-upload.js' => '7032764f', + 'rsrc/js/phui/behavior-phui-selectable-list.js' => '7e9921c8', 'rsrc/js/phui/behavior-phui-submenu.js' => 'b5e9bff9', 'rsrc/js/phui/behavior-phui-tab-group.js' => '242aa08b', - 'rsrc/js/phui/behavior-phui-timer-control.js' => 'f84bcbf4', - 'rsrc/js/phuix/PHUIXActionListView.js' => 'c68f183f', - 'rsrc/js/phuix/PHUIXActionView.js' => 'a8f573a9', - 'rsrc/js/phuix/PHUIXAutocomplete.js' => 'cf26eaab', - 'rsrc/js/phuix/PHUIXButtonView.js' => '55a24e84', - 'rsrc/js/phuix/PHUIXDropdownMenu.js' => 'b557770a', - 'rsrc/js/phuix/PHUIXExample.js' => 'c2c500a7', - 'rsrc/js/phuix/PHUIXFormControl.js' => '38c1f3fb', - 'rsrc/js/phuix/PHUIXFormationColumnView.js' => '4bcc1f78', - 'rsrc/js/phuix/PHUIXFormationFlankView.js' => '6648270a', - 'rsrc/js/phuix/PHUIXFormationView.js' => 'cef53b3e', - 'rsrc/js/phuix/PHUIXIconView.js' => 'a5257c4e', + 'rsrc/js/phui/behavior-phui-timer-control.js' => '7f949794', + 'rsrc/js/phuix/PHUIXActionListView.js' => '88d218bb', + 'rsrc/js/phuix/PHUIXActionView.js' => '0de4371d', + 'rsrc/js/phuix/PHUIXAutocomplete.js' => '81e8557b', + 'rsrc/js/phuix/PHUIXButtonView.js' => '5313610a', + 'rsrc/js/phuix/PHUIXDropdownMenu.js' => '1bd02b2b', + 'rsrc/js/phuix/PHUIXExample.js' => '222f5d96', + 'rsrc/js/phuix/PHUIXFormControl.js' => 'f27ca8c5', + 'rsrc/js/phuix/PHUIXFormationColumnView.js' => '145fb979', + 'rsrc/js/phuix/PHUIXFormationFlankView.js' => '8b1a7268', + 'rsrc/js/phuix/PHUIXFormationView.js' => 'c967b0e7', + 'rsrc/js/phuix/PHUIXIconView.js' => '2c393e31', ), 'symbols' => array( 'almanac-css' => '2e050f4f', @@ -489,9 +489,9 @@ return array( 'conpherence-message-pane-css' => '6c5bfa9d', 'conpherence-notification-css' => '85c48def', 'conpherence-participant-pane-css' => '69e0058a', - 'conpherence-thread-manager' => 'aec8e38c', + 'conpherence-thread-manager' => '3b255926', 'conpherence-transaction-css' => '3a3f5e7e', - 'd3' => 'e97b4b78', + 'd3' => 'dae76c10', 'diff-tree-view-css' => '9bd306c2', 'differential-changeset-view-css' => '0e0a956c', 'differential-core-view-css' => '7300a73e', @@ -512,14 +512,14 @@ return array( 'global-drag-and-drop-css' => '1d2713a4', 'harbormaster-css' => '9346e08b', 'herald-css' => '648d39e2', - 'herald-rule-editor' => '2633bef7', + 'herald-rule-editor' => '459fbefc', 'herald-test-css' => '7e7bbdae', 'inline-comment-summary-css' => '81eb368d', - 'javelin-aphlict' => '022516b4', + 'javelin-aphlict' => '7e93c8d6', 'javelin-behavior' => '1b6acc2a', 'javelin-behavior-aphlict-dropdown' => 'e9a2940f', - 'javelin-behavior-aphlict-listen' => '4e61fa88', - 'javelin-behavior-aphlict-status' => 'c3703a16', + 'javelin-behavior-aphlict-listen' => 'a4859af5', + 'javelin-behavior-aphlict-status' => 'da402bda', 'javelin-behavior-aphront-basic-tokenizer' => '3b4899b0', 'javelin-behavior-aphront-drag-and-drop-textarea' => '6bc7ccf7', 'javelin-behavior-aphront-form-disable-on-submit' => 'c60fb44a', @@ -529,48 +529,48 @@ return array( 'javelin-behavior-badge-view' => '92cdd7b6', 'javelin-behavior-bulk-editor' => 'aa6d2308', 'javelin-behavior-bulk-job-reload' => '3829a3cf', - 'javelin-behavior-calendar-month-view' => '158c64e0', + 'javelin-behavior-calendar-month-view' => 'e5e044e8', 'javelin-behavior-choose-control' => '04f8a1e3', - 'javelin-behavior-comment-actions' => '4dffaeb2', + 'javelin-behavior-comment-actions' => '19124eb6', 'javelin-behavior-config-reorder-fields' => '2539f834', - 'javelin-behavior-conpherence-menu' => '8c2ed2bf', - 'javelin-behavior-conpherence-participant-pane' => '43ba89a2', - 'javelin-behavior-conpherence-pontificate' => '4ae58b5a', - 'javelin-behavior-conpherence-search' => '91befbcc', + 'javelin-behavior-conpherence-menu' => '299e50bd', + 'javelin-behavior-conpherence-participant-pane' => '1fabcc80', + 'javelin-behavior-conpherence-pontificate' => '0946ebd6', + 'javelin-behavior-conpherence-search' => 'afe38d96', 'javelin-behavior-countdown-timer' => '6a162524', - 'javelin-behavior-dark-console' => '457f4d16', + 'javelin-behavior-dark-console' => '4794450e', 'javelin-behavior-dashboard-async-panel' => '9c01e364', 'javelin-behavior-dashboard-move-panels' => 'a2ab19be', 'javelin-behavior-dashboard-query-panel-select' => '1e413dc9', 'javelin-behavior-dashboard-tab-panel' => '0116d3e8', - 'javelin-behavior-day-view' => '727a5a61', - 'javelin-behavior-desktop-notifications-control' => '070679fe', - 'javelin-behavior-detect-timezone' => '78bc5d94', - 'javelin-behavior-device' => 'ac2b1e01', + 'javelin-behavior-day-view' => '1a6b7115', + 'javelin-behavior-desktop-notifications-control' => '9e3e8389', + 'javelin-behavior-detect-timezone' => '4321459b', + 'javelin-behavior-device' => 'f941cb00', 'javelin-behavior-differential-diff-radios' => '925fe8cd', - 'javelin-behavior-differential-populate' => 'b86ef6c2', + 'javelin-behavior-differential-populate' => 'fabc70ac', 'javelin-behavior-diffusion-commit-branches' => '4b671572', - 'javelin-behavior-diffusion-commit-graph' => '56d8091e', + 'javelin-behavior-diffusion-commit-graph' => '9bc1dd14', 'javelin-behavior-diffusion-locate-file' => '4c77f259', 'javelin-behavior-diffusion-pull-lastmodified' => 'c715c123', - 'javelin-behavior-document-engine' => '243d6c22', + 'javelin-behavior-document-engine' => '9d02b360', 'javelin-behavior-doorkeeper-tag' => '6a85bc5a', 'javelin-behavior-drydock-live-operation-status' => '47a0728b', - 'javelin-behavior-durable-column' => 'fa6f30b2', - 'javelin-behavior-editengine-reorder-configs' => '4842f137', - 'javelin-behavior-editengine-reorder-fields' => '0ad8d31f', - 'javelin-behavior-event-all-day' => '0b1bc990', - 'javelin-behavior-fancy-datepicker' => 'b545d0a0', - 'javelin-behavior-global-drag-and-drop' => '1cab0e9a', - 'javelin-behavior-harbormaster-log' => 'b347a301', + 'javelin-behavior-durable-column' => 'a2d381d8', + 'javelin-behavior-editengine-reorder-configs' => '636c1d6d', + 'javelin-behavior-editengine-reorder-fields' => '0235b35d', + 'javelin-behavior-event-all-day' => 'a64672b5', + 'javelin-behavior-fancy-datepicker' => '7aa2cf57', + 'javelin-behavior-global-drag-and-drop' => 'b7bd4fb1', + 'javelin-behavior-harbormaster-log' => 'd3115244', 'javelin-behavior-herald-rule-editor' => '0922e81d', - 'javelin-behavior-high-security-warning' => 'dae2d55b', + 'javelin-behavior-high-security-warning' => '8261d229', 'javelin-behavior-history-install' => '6a1583a8', 'javelin-behavior-icon-composer' => '38a6cedb', 'javelin-behavior-launch-icon-composer' => 'a17b84f1', - 'javelin-behavior-lightbox-attachments' => '14c7ab36', - 'javelin-behavior-line-chart' => 'ad258e28', - 'javelin-behavior-linked-container' => '74446546', + 'javelin-behavior-lightbox-attachments' => '978a8ed3', + 'javelin-behavior-line-chart' => 'c3ea5759', + 'javelin-behavior-linked-container' => '861b6cde', 'javelin-behavior-maniphest-batch-selector' => '1f5c3cb3', 'javelin-behavior-maniphest-list-editor' => 'c687e867', 'javelin-behavior-owners-path-editor' => 'ff688a7a', @@ -580,170 +580,170 @@ return array( 'javelin-behavior-phabricator-gesture' => 'b58d1a2a', 'javelin-behavior-phabricator-gesture-example' => '242dedd0', 'javelin-behavior-phabricator-keyboard-pager' => '1325b731', - 'javelin-behavior-phabricator-keyboard-shortcuts' => '42c44e8b', - 'javelin-behavior-phabricator-line-linker' => '8cbbcfc5', + 'javelin-behavior-phabricator-keyboard-shortcuts' => '408a69dd', + 'javelin-behavior-phabricator-line-linker' => 'ab273e9d', 'javelin-behavior-phabricator-notification-example' => '29819b75', 'javelin-behavior-phabricator-object-selector' => '98ef467f', - 'javelin-behavior-phabricator-oncopy' => 'da8f5259', - 'javelin-behavior-phabricator-remarkup-assist' => 'daceb29a', + 'javelin-behavior-phabricator-oncopy' => 'd336267a', + 'javelin-behavior-phabricator-remarkup-assist' => '957ff438', 'javelin-behavior-phabricator-reveal-content' => 'b105a3a6', - 'javelin-behavior-phabricator-search-typeahead' => 'f782e983', - 'javelin-behavior-phabricator-show-older-transactions' => '8b5c7d65', - 'javelin-behavior-phabricator-tooltips' => '73ecc1f8', + 'javelin-behavior-phabricator-search-typeahead' => '4f888644', + 'javelin-behavior-phabricator-show-older-transactions' => '02d0d179', + 'javelin-behavior-phabricator-tooltips' => '1e25ede7', 'javelin-behavior-phabricator-transaction-comment-form' => '2bdadf1a', 'javelin-behavior-phabricator-transaction-list' => '9cec214e', 'javelin-behavior-phabricator-watch-anchor' => 'a77e2cbd', - 'javelin-behavior-pholio-mock-edit' => '3eed1f2b', - 'javelin-behavior-pholio-mock-view' => '5aa1544e', + 'javelin-behavior-pholio-mock-edit' => 'e10d1263', + 'javelin-behavior-pholio-mock-view' => 'e9592389', 'javelin-behavior-phui-dropdown-menu' => '5cf0501a', - 'javelin-behavior-phui-file-upload' => 'e150bd50', - 'javelin-behavior-phui-hovercards' => '0a4b35f2', - 'javelin-behavior-phui-selectable-list' => 'b26a41e4', + 'javelin-behavior-phui-file-upload' => '7032764f', + 'javelin-behavior-phui-hovercards' => 'f29b7914', + 'javelin-behavior-phui-selectable-list' => '7e9921c8', 'javelin-behavior-phui-submenu' => 'b5e9bff9', 'javelin-behavior-phui-tab-group' => '242aa08b', - 'javelin-behavior-phui-timer-control' => 'f84bcbf4', - 'javelin-behavior-phuix-example' => 'c2c500a7', - 'javelin-behavior-policy-control' => '0eaa33a9', + 'javelin-behavior-phui-timer-control' => '7f949794', + 'javelin-behavior-phuix-example' => '222f5d96', + 'javelin-behavior-policy-control' => '274f48cf', 'javelin-behavior-policy-rule-editor' => '9347f172', - 'javelin-behavior-project-boards' => '58cb6a88', + 'javelin-behavior-project-boards' => 'b852b68e', 'javelin-behavior-project-create' => '34c53422', 'javelin-behavior-quicksand-blacklist' => '5a6f6a06', 'javelin-behavior-read-only-warning' => 'b9109f8f', 'javelin-behavior-redirect' => '407ee861', - 'javelin-behavior-refresh-csrf' => '46116c01', - 'javelin-behavior-remarkup-load-image' => '202bfa3f', - 'javelin-behavior-remarkup-preview' => 'd8a86cfb', + 'javelin-behavior-refresh-csrf' => '345119db', + 'javelin-behavior-remarkup-load-image' => 'c51e6aa0', + 'javelin-behavior-remarkup-preview' => '05a2b50b', 'javelin-behavior-reorder-applications' => 'aa371860', 'javelin-behavior-reorder-columns' => '8ac32fd9', 'javelin-behavior-reorder-profile-menu-items' => 'e5bdb730', - 'javelin-behavior-repository-crossreference' => '44d48cd1', - 'javelin-behavior-scrollbar' => '92388bae', + 'javelin-behavior-repository-crossreference' => 'f5bba944', + 'javelin-behavior-scrollbar' => '19830cb0', 'javelin-behavior-search-reorder-queries' => 'b86f297f', 'javelin-behavior-select-content' => 'c538cbfc', 'javelin-behavior-select-on-click' => '66365ee2', - 'javelin-behavior-setup-check-https' => '01384686', + 'javelin-behavior-setup-check-https' => 'adb0a739', 'javelin-behavior-stripe-payment-form' => '02cb4398', 'javelin-behavior-test-payment-form' => '4a7fb02b', - 'javelin-behavior-time-typeahead' => '5803b9e7', + 'javelin-behavior-time-typeahead' => 'cd00e3d4', 'javelin-behavior-toggle-class' => '32db8374', - 'javelin-behavior-toggle-widget' => '8f959ad0', - 'javelin-behavior-trigger-rule-editor' => '398fdf13', + 'javelin-behavior-toggle-widget' => '194194c0', + 'javelin-behavior-trigger-rule-editor' => '89cfe5ef', 'javelin-behavior-typeahead-browse' => '70245195', - 'javelin-behavior-typeahead-search' => '7b139193', - 'javelin-behavior-user-menu' => '60cd9241', - 'javelin-behavior-view-placeholder' => 'a9942052', + 'javelin-behavior-typeahead-search' => '5ec2a4b0', + 'javelin-behavior-user-menu' => '808d36b2', + 'javelin-behavior-view-placeholder' => '7bdf6903', 'javelin-behavior-workflow' => '9623adc1', - 'javelin-chart' => 'ce6f8e3d', - 'javelin-chart-curtain-view' => '86954222', - 'javelin-chart-function-label' => '81de1dab', - 'javelin-color' => '78f811c9', - 'javelin-cookie' => '05d290ef', - 'javelin-diffusion-locate-file-source' => '6c798a10', - 'javelin-dom' => '3c6f9405', - 'javelin-dynval' => '202a2e85', - 'javelin-event' => '1dbe260d', - 'javelin-external-editor-link-engine' => '48a8641f', - 'javelin-fx' => '34450586', - 'javelin-history' => '030b4f7a', + 'javelin-chart' => '71779eee', + 'javelin-chart-curtain-view' => '52837786', + 'javelin-chart-function-label' => 'b04c258c', + 'javelin-color' => '36576292', + 'javelin-cookie' => '05b28aa2', + 'javelin-diffusion-locate-file-source' => 'c2129f37', + 'javelin-dom' => '7d83258e', + 'javelin-dynval' => 'e47745d1', + 'javelin-event' => '38bc5a44', + 'javelin-external-editor-link-engine' => '0597e99e', + 'javelin-fx' => '0a9fdbb9', + 'javelin-history' => '533a88ab', 'javelin-install' => '5902260c', - 'javelin-json' => '541f81c3', - 'javelin-leader' => '0d2490ce', - 'javelin-magical-init' => '98e6504a', - 'javelin-mask' => '7c4d8998', - 'javelin-quicksand' => 'd3799cb4', - 'javelin-reactor' => '1c850a26', - 'javelin-reactor-dom' => '6cfa0008', - 'javelin-reactor-node-calmer' => '225bbb98', - 'javelin-reactornode' => '72960bc1', - 'javelin-request' => '84e6891f', - 'javelin-resource' => '20514cc2', - 'javelin-routable' => '6a18c42e', - 'javelin-router' => '32755edb', - 'javelin-scrollbar' => 'a43ae2ae', - 'javelin-sound' => 'd4cc2d2a', - 'javelin-stratcom' => '0889b835', - 'javelin-tokenizer' => '89a1ae3a', - 'javelin-typeahead' => '0507519c', - 'javelin-typeahead-composite-source' => '22ee68a5', - 'javelin-typeahead-normalizer' => 'a241536a', - 'javelin-typeahead-ondemand-source' => '23387297', - 'javelin-typeahead-preloaded-source' => '5a79f6c3', - 'javelin-typeahead-source' => '8badee71', - 'javelin-typeahead-static-source' => '80bff3af', - 'javelin-uri' => '1fcfd5c0', - 'javelin-util' => '472cda1c', - 'javelin-vector' => 'e9c80beb', - 'javelin-view' => '289bf236', - 'javelin-view-html' => 'f8c4e135', - 'javelin-view-interpreter' => '876506b6', - 'javelin-view-renderer' => '9aae2b66', - 'javelin-view-visitor' => '308f9fe4', - 'javelin-websocket' => 'fdc13e4e', - 'javelin-workboard-board' => 'b46d88c5', - 'javelin-workboard-card' => '0392a5d8', - 'javelin-workboard-card-template' => '84f82dad', - 'javelin-workboard-column' => 'c3d24e63', - 'javelin-workboard-controller' => '7474d31f', - 'javelin-workboard-drop-effect' => '8e0aa661', - 'javelin-workboard-header' => '111bfd2d', - 'javelin-workboard-header-template' => 'ebe83a6b', - 'javelin-workboard-order-template' => '03e8891f', - 'javelin-workflow' => 'cc1553f3', + 'javelin-json' => '4e373d4b', + 'javelin-leader' => '467214de', + 'javelin-magical-init' => '1767ee66', + 'javelin-mask' => '5ce5c490', + 'javelin-quicksand' => '904b29cd', + 'javelin-reactor' => '93ec1300', + 'javelin-reactor-dom' => 'eac68b41', + 'javelin-reactor-node-calmer' => '7a7abb10', + 'javelin-reactornode' => '9af9ca69', + 'javelin-request' => '4e3567dd', + 'javelin-resource' => '699676a1', + 'javelin-routable' => '45f4ef11', + 'javelin-router' => '8841c560', + 'javelin-scrollbar' => '70743772', + 'javelin-sound' => '755f30a4', + 'javelin-stratcom' => '86e7c900', + 'javelin-tokenizer' => '6691be26', + 'javelin-typeahead' => '6bb4873a', + 'javelin-typeahead-composite-source' => 'ce39158d', + 'javelin-typeahead-normalizer' => '9a68421a', + 'javelin-typeahead-ondemand-source' => '63598f73', + 'javelin-typeahead-preloaded-source' => '8d038327', + 'javelin-typeahead-source' => '670c0b8a', + 'javelin-typeahead-static-source' => 'b6bafedf', + 'javelin-uri' => '5ab77007', + 'javelin-util' => '32a82ac2', + 'javelin-vector' => '4b8bc989', + 'javelin-view' => 'f2977446', + 'javelin-view-html' => '122e6e60', + 'javelin-view-interpreter' => '339f5c61', + 'javelin-view-renderer' => 'a2a6143c', + 'javelin-view-visitor' => '8b0e0928', + 'javelin-websocket' => 'd9979d19', + 'javelin-workboard-board' => 'a4fd3b57', + 'javelin-workboard-card' => 'b82fc780', + 'javelin-workboard-card-template' => 'e63ab0ec', + 'javelin-workboard-column' => 'c74a690a', + 'javelin-workboard-controller' => '78148921', + 'javelin-workboard-drop-effect' => 'e342e2b4', + 'javelin-workboard-header' => '5a59fb82', + 'javelin-workboard-header-template' => '02a2c910', + 'javelin-workboard-order-template' => 'f9d95e77', + 'javelin-workflow' => '0c69620e', 'maniphest-report-css' => '3d53188b', 'maniphest-task-summary-css' => 'dc5d8e1f', - 'multirow-row-manager' => '5b54c823', - 'owners-path-editor' => '2a8b62d9', + 'multirow-row-manager' => '037c04be', + 'owners-path-editor' => 'e44abfd6', 'owners-path-editor-css' => 'fa7c13ef', 'paste-css' => 'b37bcd38', - 'path-typeahead' => 'ad486db3', + 'path-typeahead' => '66ed7808', 'people-picture-menu-item-css' => 'fe8e07cf', 'people-profile-css' => 'd1cb9c2e', 'phabricator-action-list-view-css' => 'b46ef6bd', - 'phabricator-busy' => '5202e831', + 'phabricator-busy' => 'ec0c35b0', 'phabricator-content-source-view-css' => 'cdf0d579', 'phabricator-core-css' => '37f19649', 'phabricator-countdown-css' => '0aaf8a98', - 'phabricator-darklog' => '3b869402', - 'phabricator-darkmessage' => '26cd4b73', + 'phabricator-darklog' => 'd8a27e0d', + 'phabricator-darkmessage' => 'ef0160d8', 'phabricator-dashboard-css' => '5a205b9d', - 'phabricator-diff-changeset' => 'd7d3ba75', - 'phabricator-diff-changeset-list' => 'cc2c5de5', - 'phabricator-diff-inline' => '9c775532', - 'phabricator-diff-inline-content-state' => 'aa51efb4', - 'phabricator-diff-path-view' => '8207abf9', - 'phabricator-diff-tree-view' => '5d83623b', - 'phabricator-drag-and-drop-file-upload' => '4370900d', - 'phabricator-draggable-list' => '0169e425', + 'phabricator-diff-changeset' => '83560c3e', + 'phabricator-diff-changeset-list' => '3bc5d0a2', + 'phabricator-diff-inline' => '7fb61bce', + 'phabricator-diff-inline-content-state' => '09b25d79', + 'phabricator-diff-path-view' => '06c422f5', + 'phabricator-diff-tree-view' => '284cdce8', + 'phabricator-drag-and-drop-file-upload' => '184e5354', + 'phabricator-draggable-list' => '0092408f', 'phabricator-fatal-config-template-css' => '20babf50', - 'phabricator-favicon' => '7930776a', - 'phabricator-file-upload' => '331676ea', + 'phabricator-favicon' => '6be35145', + 'phabricator-file-upload' => 'bcb07115', 'phabricator-flag-css' => '64dacab2', - 'phabricator-keyboard-shortcut' => '1a844c06', - 'phabricator-keyboard-shortcut-manager' => '81debc48', + 'phabricator-keyboard-shortcut' => 'beca9a7a', + 'phabricator-keyboard-shortcut-manager' => '4c65e1f0', 'phabricator-main-menu-view' => 'b748c1de', - 'phabricator-notification' => 'a9b91e3f', + 'phabricator-notification' => 'cf6b743b', 'phabricator-notification-css' => '30240bd2', 'phabricator-notification-menu-css' => '90e445b9', 'phabricator-object-selector-css' => '80622c84', - 'phabricator-phtize' => '2f1db1ed', - 'phabricator-prefab' => '5793d835', + 'phabricator-phtize' => '4c2bf506', + 'phabricator-prefab' => '8673c75c', 'phabricator-remarkup-css' => '64bb2ced', - 'phabricator-remarkup-metadata' => 'e40c4991', + 'phabricator-remarkup-metadata' => 'fe7cdb3b', 'phabricator-search-results-css' => '9ea70ace', - 'phabricator-shaped-request' => '995f5102', + 'phabricator-shaped-request' => 'bdc40a6b', 'phabricator-slowvote-css' => '0f219c39', 'phabricator-source-code-view-css' => 'e994d13f', 'phabricator-standard-page-view' => 'e811b6f6', - 'phabricator-textareautils' => 'f340a484', - 'phabricator-title' => '43bc9360', - 'phabricator-tooltip' => '83754533', + 'phabricator-textareautils' => '9cde5660', + 'phabricator-title' => 'c6d00cb9', + 'phabricator-tooltip' => '09ff9853', 'phabricator-ui-example-css' => '69d6682f', 'phabricator-zindex-css' => '56fbe5ba', 'phame-css' => '209125c7', 'pholio-css' => 'f0cd31a4', 'pholio-edit-css' => 'ea13cd28', 'pholio-inline-comments-css' => '722b48c2', - 'phortune-credit-card-form' => 'd12d214f', + 'phortune-credit-card-form' => '58883f56', 'phortune-credit-card-form-css' => '3b9868a8', 'phortune-css' => '508a1a5e', 'phortune-invoice-css' => '4436b241', @@ -779,8 +779,8 @@ return array( 'phui-formation-view-css' => 'b172a0b3', 'phui-head-thing-view-css' => 'd7f293df', 'phui-header-view-css' => '521ef411', - 'phui-hovercard' => '6199f752', - 'phui-hovercard-list' => 'de4b4919', + 'phui-hovercard' => 'b4afcd89', + 'phui-hovercard-list' => 'c5a9b42b', 'phui-hovercard-view-css' => '7ffb4e0c', 'phui-icon-set-selector-css' => '19e0253b', 'phui-icon-view-css' => 'e790b94e', @@ -814,16 +814,16 @@ return array( 'phui-workboard-view-css' => '269c93f8', 'phui-workcard-view-css' => 'a6c585d5', 'phui-workpanel-view-css' => 'c44f95c7', - 'phuix-action-list-view' => 'c68f183f', - 'phuix-action-view' => 'a8f573a9', - 'phuix-autocomplete' => 'cf26eaab', - 'phuix-button-view' => '55a24e84', - 'phuix-dropdown-menu' => 'b557770a', - 'phuix-form-control-view' => '38c1f3fb', - 'phuix-formation-column-view' => '4bcc1f78', - 'phuix-formation-flank-view' => '6648270a', - 'phuix-formation-view' => 'cef53b3e', - 'phuix-icon-view' => 'a5257c4e', + 'phuix-action-list-view' => '88d218bb', + 'phuix-action-view' => '0de4371d', + 'phuix-autocomplete' => '81e8557b', + 'phuix-button-view' => '5313610a', + 'phuix-dropdown-menu' => '1bd02b2b', + 'phuix-form-control-view' => 'f27ca8c5', + 'phuix-formation-column-view' => '145fb979', + 'phuix-formation-flank-view' => '8b1a7268', + 'phuix-formation-view' => 'c967b0e7', + 'phuix-icon-view' => '2c393e31', 'policy-css' => 'ceb56a08', 'policy-edit-css' => '8794e2ed', 'policy-transaction-detail-css' => 'c02b8384', @@ -837,55 +837,58 @@ return array( 'syntax-default-css' => 'c0307dc6', 'syntax-highlighting-css' => '548567f6', 'tokens-css' => 'cba3965f', - 'trigger-rule' => '41b7b4f6', - 'trigger-rule-control' => '5faf27b9', - 'trigger-rule-editor' => 'b49fd60c', - 'trigger-rule-type' => '4feea7d3', + 'trigger-rule' => 'a9747130', + 'trigger-rule-control' => '199300af', + 'trigger-rule-editor' => '516b27db', + 'trigger-rule-type' => 'e6bc2ced', 'typeahead-browse-css' => 'b7ed02d2', 'unhandled-exception-css' => '9ecfc00d', ), 'requires' => array( + '0092408f' => array( + 'javelin-install', + 'javelin-dom', + 'javelin-stratcom', + 'javelin-util', + 'javelin-vector', + 'javelin-magical-init', + 'phabricator-tooltip', + ), '0116d3e8' => array( 'javelin-behavior', 'javelin-dom', 'javelin-stratcom', ), - '01384686' => array( + '0235b35d' => array( 'javelin-behavior', - 'javelin-uri', - 'phabricator-notification', - ), - '0169e425' => array( - 'javelin-install', - 'javelin-dom', 'javelin-stratcom', - 'javelin-util', - 'javelin-vector', - 'javelin-magical-init', + 'javelin-dom', + 'phabricator-draggable-list', ), - '022516b4' => array( + '02a2c910' => array( 'javelin-install', - 'javelin-util', - 'javelin-websocket', - 'javelin-leader', - 'javelin-json', + 'javelin-dom', ), '02cb4398' => array( 'javelin-behavior', 'javelin-dom', 'phortune-credit-card-form', ), - '030b4f7a' => array( + '02d0d179' => array( + 'javelin-behavior', 'javelin-stratcom', - 'javelin-install', - 'javelin-uri', + 'javelin-dom', + 'javelin-json', + 'javelin-router', 'javelin-util', + 'javelin-workflow', + 'phabricator-keyboard-shortcut', ), - '0392a5d8' => array( - 'javelin-install', - ), - '03e8891f' => array( + '037c04be' => array( 'javelin-install', + 'javelin-stratcom', + 'javelin-dom', + 'javelin-util', ), '04f8a1e3' => array( 'javelin-behavior', @@ -893,103 +896,153 @@ return array( 'javelin-dom', 'javelin-workflow', ), - '0507519c' => array( + '0597e99e' => array( 'javelin-install', + ), + '05a2b50b' => array( + 'javelin-behavior', + 'javelin-behavior-device', 'javelin-dom', - 'javelin-vector', 'javelin-util', + 'phabricator-shaped-request', ), - '05d290ef' => array( + '05b28aa2' => array( 'javelin-install', 'javelin-util', ), - '070679fe' => array( - 'javelin-behavior', - 'javelin-stratcom', + '06c422f5' => array( 'javelin-dom', - 'javelin-uri', - 'phabricator-notification', - ), - '0889b835' => array( 'javelin-install', - 'javelin-event', 'javelin-util', - 'javelin-magical-init', + 'phuix-icon-view', ), '0922e81d' => array( 'herald-rule-editor', 'javelin-behavior', ), - '0a4b35f2' => array( + '0946ebd6' => array( 'javelin-behavior', - 'javelin-behavior-device', 'javelin-stratcom', + 'conpherence-thread-manager', + ), + '09b25d79' => array( + 'javelin-dom', + 'javelin-install', + ), + '09ff9853' => array( + 'javelin-install', + 'javelin-util', + 'javelin-dom', 'javelin-vector', - 'phui-hovercard', - 'phui-hovercard-list', ), - '0ad8d31f' => array( - 'javelin-behavior', + '0a9fdbb9' => array( + 'javelin-color', + 'javelin-install', + 'javelin-util', + ), + '0c69620e' => array( 'javelin-stratcom', - 'javelin-workflow', + 'javelin-request', 'javelin-dom', - 'phabricator-draggable-list', + 'javelin-vector', + 'javelin-install', + 'javelin-util', + 'javelin-mask', + 'javelin-uri', + 'javelin-routable', ), - '0d2490ce' => array( + '0de4371d' => array( 'javelin-install', + 'javelin-dom', + 'javelin-stratcom', + 'javelin-util', ), '0e0a956c' => array( 'phui-inline-comment-view-css', ), - '0eaa33a9' => array( - 'javelin-behavior', + '122e6e60' => array( + 'javelin-install', 'javelin-dom', + 'javelin-view-visitor', 'javelin-util', - 'phuix-dropdown-menu', - 'phuix-action-list-view', - 'phuix-action-view', - 'javelin-workflow', - 'phuix-icon-view', - ), - '111bfd2d' => array( - 'javelin-install', ), '1325b731' => array( 'javelin-behavior', 'javelin-uri', 'phabricator-keyboard-shortcut', ), - '14c7ab36' => array( - 'javelin-behavior', - 'javelin-stratcom', + '145fb979' => array( + 'javelin-install', 'javelin-dom', - 'javelin-mask', + 'javelin-vector', 'javelin-util', - 'phuix-icon-view', - 'phabricator-busy', + 'javelin-stratcom', + 'javelin-request', ), - '1a844c06' => array( + '184e5354' => array( 'javelin-install', 'javelin-util', - 'phabricator-keyboard-shortcut-manager', + 'javelin-request', + 'javelin-dom', + 'javelin-stratcom', + 'javelin-uri', + 'javelin-workflow', + 'phabricator-file-upload', ), - '1b6acc2a' => array( - 'javelin-magical-init', + '19124eb6' => array( + 'javelin-behavior', + 'javelin-behavior-device', + 'javelin-dom', + 'javelin-json', + 'javelin-request', + 'javelin-stratcom', 'javelin-util', + 'javelin-vector', + 'phuix-form-control-view', + 'phuix-icon-view', + 'phabricator-shaped-request', + ), + '194194c0' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-request', + 'javelin-stratcom', + 'javelin-behavior-device', ), - '1c850a26' => array( + '19830cb0' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-scrollbar', + ), + '199300af' => array( + 'phuix-form-control-view', 'javelin-install', 'javelin-util', ), - '1cab0e9a' => array( + '1a6b7115' => array( 'javelin-behavior', 'javelin-dom', + 'javelin-stratcom', 'javelin-uri', - 'javelin-mask', - 'phabricator-drag-and-drop-file-upload', + 'javelin-vector', + 'javelin-workflow', + 'phuix-icon-view', ), - '1dbe260d' => array( + '1b6acc2a' => array( + 'javelin-magical-init', + 'javelin-util', + ), + '1bd02b2b' => array( 'javelin-install', + 'javelin-util', + 'javelin-dom', + 'javelin-vector', + 'javelin-stratcom', + ), + '1e25ede7' => array( + 'javelin-behavior', + 'javelin-stratcom', + 'phabricator-tooltip', ), '1e413dc9' => array( 'javelin-behavior', @@ -1001,41 +1054,22 @@ return array( 'javelin-stratcom', 'javelin-util', ), - '1fcfd5c0' => array( - 'javelin-install', - 'javelin-util', - 'javelin-stratcom', - ), - '202a2e85' => array( - 'javelin-install', - 'javelin-reactornode', - 'javelin-util', - 'javelin-reactor', - ), - '202bfa3f' => array( + '1fabcc80' => array( 'javelin-behavior', - 'javelin-request', - ), - '20514cc2' => array( + 'javelin-dom', + 'javelin-stratcom', + 'javelin-workflow', 'javelin-util', 'javelin-uri', - 'javelin-install', - ), - '225bbb98' => array( - 'javelin-install', - 'javelin-reactor', - 'javelin-util', - ), - '22ee68a5' => array( - 'javelin-install', - 'javelin-typeahead-source', - 'javelin-util', + 'phabricator-notification', + 'conpherence-thread-manager', ), - 23387297 => array( - 'javelin-install', + '222f5d96' => array( + 'javelin-behavior', + 'javelin-dom', 'javelin-util', - 'javelin-request', - 'javelin-typeahead-source', + 'phuix-button-view', + 'phuix-icon-view', ), '242aa08b' => array( 'javelin-behavior', @@ -1048,11 +1082,6 @@ return array( 'javelin-vector', 'javelin-dom', ), - '243d6c22' => array( - 'javelin-behavior', - 'javelin-dom', - 'javelin-stratcom', - ), '2539f834' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1060,32 +1089,38 @@ return array( 'javelin-json', 'phabricator-draggable-list', ), - '2633bef7' => array( - 'multirow-row-manager', - 'javelin-install', - 'javelin-util', + '274f48cf' => array( + 'javelin-behavior', 'javelin-dom', - 'javelin-stratcom', - 'javelin-json', - 'phabricator-prefab', + 'javelin-uri', + 'javelin-util', + 'phuix-dropdown-menu', + 'phuix-action-list-view', + 'phuix-action-view', + 'javelin-workflow', + 'phuix-icon-view', ), - '289bf236' => array( + '284cdce8' => array( + 'javelin-dom', 'javelin-install', - 'javelin-util', + 'phabricator-diff-path-view', ), '29819b75' => array( 'phabricator-notification', 'javelin-stratcom', 'javelin-behavior', ), - '2a8b62d9' => array( - 'multirow-row-manager', - 'javelin-install', - 'path-typeahead', + '299e50bd' => array( + 'javelin-behavior', 'javelin-dom', 'javelin-util', - 'phabricator-prefab', - 'phuix-form-control-view', + 'javelin-stratcom', + 'javelin-workflow', + 'javelin-behavior-device', + 'javelin-history', + 'javelin-scrollbar', + 'phabricator-title', + 'conpherence-thread-manager', ), '2bdadf1a' => array( 'javelin-behavior', @@ -1094,31 +1129,28 @@ return array( 'javelin-request', 'phabricator-shaped-request', ), - '2f1db1ed' => array( - 'javelin-util', - ), - '308f9fe4' => array( - 'javelin-install', - 'javelin-util', - ), - '32755edb' => array( + '2c393e31' => array( 'javelin-install', - 'javelin-util', + 'javelin-dom', ), '32db8374' => array( 'javelin-behavior', 'javelin-stratcom', 'javelin-dom', ), - '331676ea' => array( + '339f5c61' => array( + 'javelin-view', 'javelin-install', 'javelin-dom', - 'phabricator-notification', ), - 34450586 => array( - 'javelin-color', - 'javelin-install', + '345119db' => array( + 'javelin-request', + 'javelin-behavior', + 'javelin-dom', + 'javelin-router', + 'javelin-uri', 'javelin-util', + 'phabricator-busy', ), '34c53422' => array( 'javelin-behavior', @@ -1126,6 +1158,9 @@ return array( 'javelin-stratcom', 'javelin-workflow', ), + 36576292 => array( + 'javelin-install', + ), '3829a3cf' => array( 'javelin-behavior', 'javelin-uri', @@ -1135,76 +1170,88 @@ return array( 'javelin-dom', 'javelin-stratcom', ), - '38c1f3fb' => array( + '38bc5a44' => array( 'javelin-install', - 'javelin-dom', ), - '398fdf13' => array( - 'javelin-behavior', - 'trigger-rule-editor', - 'trigger-rule', - 'trigger-rule-type', + '3b255926' => array( + 'javelin-dom', + 'javelin-util', + 'javelin-stratcom', + 'javelin-install', + 'javelin-aphlict', + 'javelin-workflow', + 'javelin-leader', + 'phabricator-shaped-request', ), '3b4899b0' => array( 'javelin-behavior', 'phabricator-prefab', ), - '3c6f9405' => array( - 'javelin-magical-init', + '3bc5d0a2' => array( 'javelin-install', + 'javelin-behavior-device', + 'javelin-dom', + 'javelin-external-editor-link-engine', + 'javelin-magical-init', + 'javelin-stratcom', + 'javelin-uri', 'javelin-util', 'javelin-vector', - 'javelin-stratcom', - ), - '3eed1f2b' => array( - 'javelin-behavior', - 'javelin-stratcom', - 'javelin-dom', 'javelin-workflow', - 'javelin-quicksand', - 'phabricator-phtize', - 'phabricator-drag-and-drop-file-upload', - 'phabricator-draggable-list', + 'phuix-action-view', + 'phuix-action-list-view', + 'phuix-button-view', + 'phuix-dropdown-menu', + 'phuix-icon-view', + 'phabricator-diff-changeset', + 'phabricator-diff-tree-view', + 'phabricator-keyboard-shortcut', + 'phabricator-notification', ), '407ee861' => array( 'javelin-behavior', 'javelin-uri', ), - '42c44e8b' => array( + '408a69dd' => array( 'javelin-behavior', 'javelin-workflow', 'javelin-json', 'javelin-dom', 'phabricator-keyboard-shortcut', + 'phabricator-phtize', ), - '4370900d' => array( - 'javelin-install', + '4321459b' => array( + 'javelin-behavior', + 'javelin-uri', 'javelin-util', 'javelin-request', - 'javelin-dom', - 'javelin-uri', - 'phabricator-file-upload', - ), - '43ba89a2' => array( - 'javelin-behavior', - 'javelin-dom', 'javelin-stratcom', 'javelin-workflow', - 'javelin-util', 'phabricator-notification', - 'conpherence-thread-manager', ), - '43bc9360' => array( + '459fbefc' => array( + 'multirow-row-manager', 'javelin-install', - ), - '44d48cd1' => array( - 'javelin-behavior', + 'javelin-util', 'javelin-dom', 'javelin-stratcom', - 'javelin-uri', + 'javelin-json', + 'phabricator-prefab', + ), + '45f4ef11' => array( + 'javelin-install', + ), + '467214de' => array( + 'javelin-install', + 'javelin-json', + 'javelin-stratcom', + 'javelin-util', ), - '457f4d16' => array( + '4794450e' => array( 'javelin-behavior', + 'javelin-aphlict', + 'javelin-leader', + 'javelin-json', 'javelin-stratcom', 'javelin-util', 'javelin-dom', @@ -1213,29 +1260,11 @@ return array( 'phabricator-darklog', 'phabricator-darkmessage', ), - '46116c01' => array( - 'javelin-request', - 'javelin-behavior', - 'javelin-dom', - 'javelin-router', - 'javelin-util', - 'phabricator-busy', - ), '47a0728b' => array( 'javelin-behavior', 'javelin-dom', 'javelin-request', ), - '4842f137' => array( - 'javelin-behavior', - 'javelin-stratcom', - 'javelin-workflow', - 'javelin-dom', - 'phabricator-draggable-list', - ), - '48a8641f' => array( - 'javelin-install', - ), '48fe33d0' => array( 'javelin-behavior', 'javelin-dom', @@ -1252,23 +1281,25 @@ return array( 'javelin-dom', 'phortune-credit-card-form', ), - '4ae58b5a' => array( - 'javelin-behavior', - 'javelin-dom', - 'javelin-util', - 'javelin-workflow', - 'javelin-stratcom', - 'conpherence-thread-manager', - ), '4b671572' => array( 'javelin-behavior', 'javelin-dom', 'javelin-util', 'javelin-request', ), - '4bcc1f78' => array( + '4b8bc989' => array( + 'javelin-install', + 'javelin-event', + ), + '4c2bf506' => array( + 'javelin-util', + ), + '4c65e1f0' => array( 'javelin-install', + 'javelin-util', + 'javelin-stratcom', 'javelin-dom', + 'javelin-vector', ), '4c77f259' => array( 'javelin-behavior', @@ -1277,120 +1308,93 @@ return array( 'javelin-typeahead', 'javelin-uri', ), - '4dffaeb2' => array( - 'javelin-behavior', + '4e3567dd' => array( + 'javelin-install', 'javelin-stratcom', - 'javelin-workflow', + 'javelin-util', + 'javelin-behavior', + 'javelin-json', 'javelin-dom', - 'phuix-form-control-view', - 'phuix-icon-view', - 'javelin-behavior-phabricator-gesture', + 'javelin-resource', + 'javelin-routable', + ), + '4e373d4b' => array( + 'javelin-install', ), - '4e61fa88' => array( + '4f888644' => array( 'javelin-behavior', - 'javelin-aphlict', - 'javelin-stratcom', + 'javelin-typeahead-ondemand-source', + 'javelin-typeahead', + 'javelin-dom', 'javelin-request', 'javelin-uri', - 'javelin-dom', - 'javelin-json', - 'javelin-router', 'javelin-util', - 'javelin-leader', - 'javelin-sound', - 'phabricator-notification', - ), - '4feea7d3' => array( - 'trigger-rule-control', + 'javelin-stratcom', + 'phabricator-prefab', + 'phuix-action-view', + 'phuix-action-list-view', + 'phuix-dropdown-menu', + 'phuix-icon-view', ), '506aa3f4' => array( 'javelin-behavior', 'javelin-stratcom', 'javelin-dom', ), - '5202e831' => array( + '516b27db' => array( + 'multirow-row-manager', + 'trigger-rule', 'javelin-install', 'javelin-dom', - 'javelin-fx', + 'javelin-util', + 'javelin-json', ), - '541f81c3' => array( + 52837786 => array( 'javelin-install', + 'javelin-dom', + 'phuix-icon-view', ), - '548567f6' => array( - 'syntax-default-css', - ), - '55a24e84' => array( + '5313610a' => array( 'javelin-install', 'javelin-dom', + 'phuix-icon-view', ), - '56d8091e' => array( - 'javelin-behavior', - 'javelin-dom', + '533a88ab' => array( 'javelin-stratcom', - ), - '5793d835' => array( 'javelin-install', - 'javelin-util', - 'javelin-dom', - 'javelin-typeahead', - 'javelin-tokenizer', - 'javelin-typeahead-preloaded-source', - 'javelin-typeahead-ondemand-source', - 'javelin-dom', - 'javelin-stratcom', + 'javelin-uri', 'javelin-util', ), - '5803b9e7' => array( - 'javelin-behavior', - 'javelin-util', - 'javelin-dom', - 'javelin-stratcom', - 'javelin-vector', - 'javelin-typeahead-static-source', + '548567f6' => array( + 'syntax-default-css', ), - '58cb6a88' => array( - 'javelin-behavior', + '58883f56' => array( + 'javelin-install', 'javelin-dom', - 'javelin-util', - 'javelin-vector', - 'javelin-stratcom', + 'javelin-json', 'javelin-workflow', - 'javelin-workboard-controller', - 'javelin-workboard-drop-effect', + 'javelin-util', ), '5902260c' => array( 'javelin-util', 'javelin-magical-init', ), + '5a59fb82' => array( + 'javelin-install', + 'javelin-stratcom', + ), '5a6f6a06' => array( 'javelin-behavior', 'javelin-quicksand', ), - '5a79f6c3' => array( + '5ab77007' => array( 'javelin-install', 'javelin-util', - 'javelin-request', - 'javelin-typeahead-source', - ), - '5aa1544e' => array( - 'javelin-behavior', - 'javelin-util', 'javelin-stratcom', - 'javelin-dom', - 'javelin-vector', - 'javelin-magical-init', - 'javelin-request', - 'javelin-history', - 'javelin-workflow', - 'javelin-mask', - 'javelin-behavior-device', - 'phabricator-keyboard-shortcut', ), - '5b54c823' => array( + '5ce5c490' => array( 'javelin-install', - 'javelin-stratcom', 'javelin-dom', - 'javelin-util', ), '5cf0501a' => array( 'javelin-behavior', @@ -1398,21 +1402,23 @@ return array( 'javelin-dom', 'phuix-dropdown-menu', ), - '5d83623b' => array( + '5ec2a4b0' => array( + 'javelin-behavior', + 'javelin-workflow', 'javelin-dom', + 'javelin-util', ), - '5faf27b9' => array( - 'phuix-form-control-view', + '63598f73' => array( + 'javelin-install', + 'javelin-util', + 'javelin-request', + 'javelin-typeahead-source', ), - '60cd9241' => array( + '636c1d6d' => array( 'javelin-behavior', - ), - '6199f752' => array( - 'javelin-install', + 'javelin-stratcom', 'javelin-dom', - 'javelin-vector', - 'javelin-request', - 'javelin-uri', + 'phabricator-draggable-list', ), '65bb0011' => array( 'javelin-behavior', @@ -1423,9 +1429,31 @@ return array( 'javelin-stratcom', 'javelin-dom', ), - '6648270a' => array( + '6691be26' => array( + 'javelin-dom', + 'javelin-util', + 'javelin-stratcom', + 'javelin-install', + 'javelin-workflow', + ), + '66ed7808' => array( + 'javelin-install', + 'javelin-typeahead', + 'javelin-dom', + 'javelin-request', + 'javelin-typeahead-ondemand-source', + 'javelin-util', + ), + '670c0b8a' => array( 'javelin-install', + 'javelin-util', 'javelin-dom', + 'javelin-typeahead-normalizer', + ), + '699676a1' => array( + 'javelin-util', + 'javelin-uri', + 'javelin-install', ), '6a1583a8' => array( 'javelin-behavior', @@ -1435,9 +1463,6 @@ return array( 'javelin-behavior', 'javelin-dom', ), - '6a18c42e' => array( - 'javelin-install', - ), '6a85bc5a' => array( 'javelin-behavior', 'javelin-dom', @@ -1445,6 +1470,12 @@ return array( 'javelin-workflow', 'javelin-magical-init', ), + '6bb4873a' => array( + 'javelin-install', + 'javelin-dom', + 'javelin-vector', + 'javelin-util', + ), '6bc7ccf7' => array( 'javelin-behavior', 'javelin-dom', @@ -1452,19 +1483,9 @@ return array( 'phabricator-textareautils', 'phabricator-remarkup-metadata', ), - '6c798a10' => array( + '6be35145' => array( 'javelin-install', 'javelin-dom', - 'javelin-typeahead-preloaded-source', - 'javelin-util', - ), - '6cfa0008' => array( - 'javelin-dom', - 'javelin-dynval', - 'javelin-reactor', - 'javelin-reactornode', - 'javelin-install', - 'javelin-util', ), '6e815b50' => array( 'javelin-behavior', @@ -1478,26 +1499,38 @@ return array( 'javelin-workflow', 'javelin-dom', ), - '727a5a61' => array( - 'phuix-icon-view', + '7032764f' => array( + 'javelin-behavior', + 'javelin-util', + 'javelin-workflow', + 'javelin-dom', + 'phabricator-drag-and-drop-file-upload', ), - '72960bc1' => array( + 70743772 => array( 'javelin-install', - 'javelin-reactor', + 'javelin-dom', + 'javelin-magical-init', + 'javelin-stratcom', 'javelin-util', - 'javelin-reactor-node-calmer', + 'javelin-vector', ), - '73ecc1f8' => array( - 'javelin-behavior', + '71779eee' => array( + 'javelin-install', 'javelin-behavior-device', + 'javelin-chart-curtain-view', + 'javelin-chart-function-label', + 'javelin-dom', 'javelin-stratcom', - 'phabricator-tooltip', + 'javelin-util', + 'javelin-vector', + 'phui-chart-css', ), - 74446546 => array( - 'javelin-behavior', + '755f30a4' => array( + 'javelin-install', + 'javelin-util', 'javelin-dom', ), - '7474d31f' => array( + 78148921 => array( 'javelin-install', 'javelin-dom', 'javelin-util', @@ -1506,79 +1539,152 @@ return array( 'javelin-workflow', 'phabricator-drag-and-drop-file-upload', 'javelin-workboard-board', + 'javelin-behavior-device', + ), + '7a7abb10' => array( + 'javelin-install', + 'javelin-reactor', + 'javelin-util', ), - '78bc5d94' => array( + '7aa2cf57' => array( 'javelin-behavior', - 'javelin-uri', - 'phabricator-notification', + 'javelin-behavior-device', + 'javelin-mask', + 'javelin-util', + 'javelin-dom', + 'javelin-stratcom', + 'javelin-vector', + 'phabricator-phtize', + ), + '7bdf6903' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-view-renderer', + 'javelin-install', ), - '78f811c9' => array( + '7d83258e' => array( + 'javelin-magical-init', 'javelin-install', + 'javelin-util', + 'javelin-vector', + 'javelin-stratcom', ), - '7930776a' => array( + '7e93c8d6' => array( 'javelin-install', + 'javelin-util', + 'javelin-websocket', + 'javelin-leader', + 'javelin-json', + ), + '7e9921c8' => array( + 'javelin-behavior', + 'javelin-stratcom', + 'javelin-util', + 'javelin-dom', + ), + '7ef6de30' => array( + 'aphront-typeahead-control-css', + 'phui-tag-view-css', + ), + '7f949794' => array( + 'javelin-behavior', + 'javelin-request', + 'javelin-dom', + ), + '7fb61bce' => array( 'javelin-dom', + 'javelin-install', + 'javelin-request', + 'javelin-stratcom', + 'javelin-util', + 'javelin-workflow', + 'phabricator-diff-inline-content-state', + 'phabricator-shaped-request', + 'phabricator-textareautils', + 'phuix-action-view', + 'phuix-action-list-view', + 'phuix-button-view', + 'phuix-dropdown-menu', + ), + '80622c84' => array( + 'aphront-dialog-view-css', ), - '7b139193' => array( + '808d36b2' => array( 'javelin-behavior', - 'javelin-stratcom', - 'javelin-workflow', 'javelin-dom', + 'javelin-stratcom', + 'phuix-dropdown-menu', ), - '7c4d8998' => array( + '81e8557b' => array( 'javelin-install', + 'javelin-behavior-device', 'javelin-dom', + 'javelin-stratcom', + 'javelin-typeahead-ondemand-source', + 'javelin-util', + 'javelin-vector', + 'phuix-icon-view', + 'phabricator-prefab', + 'phabricator-textareautils', ), - '7ef6de30' => array( - 'aphront-typeahead-control-css', - 'phui-tag-view-css', - ), - '80622c84' => array( - 'aphront-dialog-view-css', - ), - '80bff3af' => array( - 'javelin-install', - 'javelin-typeahead-source', + '8261d229' => array( + 'javelin-behavior', + 'javelin-stratcom', + 'javelin-uri', + 'phabricator-notification', ), - '81debc48' => array( - 'javelin-install', + '83560c3e' => array( + 'javelin-dom', 'javelin-util', 'javelin-stratcom', - 'javelin-dom', + 'javelin-install', + 'javelin-workflow', + 'javelin-router', + 'javelin-behavior-device', 'javelin-vector', + 'phabricator-diff-inline', + 'phabricator-diff-path-view', + 'phuix-button-view', + 'javelin-magical-init', ), - '8207abf9' => array( + '861b6cde' => array( + 'javelin-behavior', 'javelin-dom', + 'javelin-stratcom', ), - 83754533 => array( + '8673c75c' => array( 'javelin-install', 'javelin-util', 'javelin-dom', - 'javelin-vector', + 'javelin-typeahead', + 'javelin-tokenizer', + 'javelin-typeahead-normalizer', + 'javelin-typeahead-preloaded-source', + 'javelin-typeahead-ondemand-source', + 'javelin-dom', + 'javelin-stratcom', ), - '84e6891f' => array( + '86e7c900' => array( 'javelin-install', - 'javelin-stratcom', + 'javelin-event', 'javelin-util', + 'javelin-magical-init', 'javelin-behavior', - 'javelin-json', - 'javelin-dom', - 'javelin-resource', - 'javelin-routable', ), - '84f82dad' => array( + '8841c560' => array( 'javelin-install', + 'javelin-util', ), - '876506b6' => array( - 'javelin-view', + '88d218bb' => array( 'javelin-install', 'javelin-dom', ), - '89a1ae3a' => array( + '89cfe5ef' => array( + 'javelin-behavior', 'javelin-dom', - 'javelin-util', - 'javelin-stratcom', - 'javelin-install', + 'trigger-rule-editor', + 'trigger-rule', + 'trigger-rule-type', ), '8ac32fd9' => array( 'javelin-behavior', @@ -1587,64 +1693,32 @@ return array( 'javelin-dom', 'phabricator-draggable-list', ), - '8b5c7d65' => array( - 'javelin-behavior', - 'javelin-stratcom', - 'javelin-dom', - 'phabricator-busy', - ), - '8badee71' => array( + '8b0e0928' => array( 'javelin-install', 'javelin-util', - 'javelin-dom', - 'javelin-typeahead-normalizer', ), - '8c2ed2bf' => array( - 'javelin-behavior', - 'javelin-dom', - 'javelin-util', - 'javelin-stratcom', - 'javelin-workflow', - 'javelin-behavior-device', - 'javelin-history', + '8b1a7268' => array( + 'javelin-install', 'javelin-vector', - 'javelin-scrollbar', - 'phabricator-title', - 'phabricator-shaped-request', - 'conpherence-thread-manager', - ), - '8cbbcfc5' => array( - 'javelin-behavior', - 'javelin-stratcom', - 'javelin-dom', - 'javelin-history', - 'javelin-external-editor-link-engine', ), - '8e0aa661' => array( + '8d038327' => array( 'javelin-install', - 'javelin-dom', + 'javelin-util', + 'javelin-request', + 'javelin-typeahead-source', ), - '8f959ad0' => array( - 'javelin-behavior', + '904b29cd' => array( + 'javelin-install', 'javelin-dom', + 'javelin-history', + 'javelin-stratcom', + 'javelin-uri', 'javelin-util', 'javelin-workflow', - 'javelin-stratcom', ), 90721212 => array( 'phui-fontkit-css', ), - '91befbcc' => array( - 'javelin-behavior', - 'javelin-dom', - 'javelin-util', - 'javelin-workflow', - 'javelin-stratcom', - ), - '92388bae' => array( - 'javelin-behavior', - 'javelin-scrollbar', - ), '925fe8cd' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1663,6 +1737,24 @@ return array( 'phabricator-prefab', 'javelin-json', ), + '93ec1300' => array( + 'javelin-install', + 'javelin-util', + ), + '957ff438' => array( + 'javelin-behavior', + 'javelin-stratcom', + 'javelin-dom', + 'phabricator-file-upload', + 'phabricator-keyboard-shortcut', + 'phabricator-phtize', + 'phabricator-textareautils', + 'phabricator-remarkup-metadata', + 'javelin-workflow', + 'javelin-vector', + 'phuix-autocomplete', + 'javelin-mask', + ), '9623adc1' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1676,33 +1768,49 @@ return array( 'javelin-stratcom', 'phabricator-notification', ), + '978a8ed3' => array( + 'javelin-behavior', + 'javelin-stratcom', + 'javelin-dom', + 'javelin-mask', + 'javelin-util', + 'javelin-workflow', + 'phuix-icon-view', + 'phabricator-busy', + ), '98ef467f' => array( 'javelin-behavior', 'javelin-dom', 'javelin-request', 'javelin-util', ), - '995f5102' => array( + '9a68421a' => array( 'javelin-install', - 'javelin-util', - 'javelin-request', - 'javelin-router', ), - '9aae2b66' => array( + '9af9ca69' => array( 'javelin-install', + 'javelin-reactor', 'javelin-util', + 'javelin-reactor-node-calmer', ), '9b03a61f' => array( 'phui-oi-list-view-css', ), + '9bc1dd14' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-stratcom', + 'javelin-vector', + ), '9c01e364' => array( 'javelin-behavior', 'javelin-dom', 'javelin-workflow', ), - '9c775532' => array( + '9cde5660' => array( + 'javelin-install', 'javelin-dom', - 'phabricator-diff-inline-content-state', + 'javelin-vector', ), '9cec214e' => array( 'javelin-behavior', @@ -1712,13 +1820,34 @@ return array( 'javelin-uri', 'phabricator-textareautils', ), + '9d02b360' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-history', + 'javelin-request', + 'javelin-stratcom', + 'javelin-uri', + 'javelin-util', + 'javelin-workflow', + 'phuix-action-list-view', + 'phuix-action-view', + 'phuix-dropdown-menu', + 'phabricator-tooltip', + ), + '9e3e8389' => array( + 'javelin-behavior', + 'javelin-stratcom', + 'javelin-dom', + 'phabricator-notification', + ), 'a17b84f1' => array( 'javelin-behavior', 'javelin-dom', 'javelin-workflow', ), - 'a241536a' => array( + 'a2a6143c' => array( 'javelin-install', + 'javelin-util', ), 'a2ab19be' => array( 'javelin-behavior', @@ -1728,43 +1857,64 @@ return array( 'javelin-workflow', 'phabricator-draggable-list', ), - 'a43ae2ae' => array( - 'javelin-install', + 'a2d381d8' => array( + 'javelin-behavior', 'javelin-dom', 'javelin-stratcom', - 'javelin-vector', + 'javelin-scrollbar', + 'javelin-quicksand', + 'javelin-uri', + 'javelin-request', + 'conpherence-thread-manager', + 'phabricator-title', + ), + 'a4859af5' => array( + 'javelin-behavior', + 'javelin-aphlict', + 'javelin-stratcom', + 'javelin-request', + 'javelin-uri', + 'javelin-dom', + 'javelin-router', + 'javelin-leader', + 'javelin-sound', + 'phabricator-notification', ), 'a4aa75c4' => array( 'phui-button-css', 'phui-button-simple-css', ), - 'a5257c4e' => array( + 'a4fd3b57' => array( 'javelin-install', 'javelin-dom', - ), - 'a77e2cbd' => array( - 'javelin-behavior', + 'javelin-util', 'javelin-stratcom', - 'javelin-dom', + 'javelin-workflow', + 'javelin-sound', + 'javelin-json', 'javelin-vector', + 'javelin-request', + 'phabricator-draggable-list', + 'javelin-workboard-column', + 'javelin-workboard-header-template', + 'javelin-workboard-card-template', + 'javelin-workboard-order-template', + 'phabricator-keyboard-shortcut', ), - 'a8f573a9' => array( - 'javelin-install', + 'a64672b5' => array( + 'javelin-behavior', 'javelin-dom', - 'javelin-util', ), - 'a9942052' => array( + 'a77e2cbd' => array( 'javelin-behavior', + 'javelin-stratcom', 'javelin-dom', - 'javelin-view-renderer', - 'javelin-install', + 'javelin-vector', ), - 'a9b91e3f' => array( + 'a9747130' => array( 'javelin-install', 'javelin-dom', - 'javelin-stratcom', 'javelin-util', - 'phabricator-notification-css', ), 'a9da7b2a' => array( 'phui-button-css', @@ -1776,9 +1926,6 @@ return array( 'javelin-dom', 'phabricator-draggable-list', ), - 'aa51efb4' => array( - 'javelin-dom', - ), 'aa6d2308' => array( 'javelin-behavior', 'javelin-dom', @@ -1787,82 +1934,43 @@ return array( 'javelin-json', 'phuix-form-control-view', ), - 'ac2b1e01' => array( + 'ab273e9d' => array( 'javelin-behavior', 'javelin-stratcom', 'javelin-dom', + 'javelin-history', + 'javelin-external-editor-link-engine', + 'javelin-uri', 'javelin-vector', - 'javelin-install', - ), - 'ad258e28' => array( - 'javelin-behavior', - 'javelin-dom', - 'javelin-chart', - ), - 'ad486db3' => array( - 'javelin-install', - 'javelin-typeahead', - 'javelin-dom', - 'javelin-request', - 'javelin-typeahead-ondemand-source', - 'javelin-util', - ), - 'aec8e38c' => array( - 'javelin-dom', - 'javelin-util', - 'javelin-stratcom', - 'javelin-install', - 'javelin-aphlict', - 'javelin-workflow', - 'javelin-router', - 'javelin-behavior-device', - 'javelin-vector', - ), - 'b105a3a6' => array( - 'javelin-behavior', - 'javelin-stratcom', - 'javelin-dom', - ), - 'b26a41e4' => array( - 'javelin-behavior', - 'javelin-stratcom', - 'javelin-dom', + 'phabricator-keyboard-shortcut', ), - 'b347a301' => array( + 'adb0a739' => array( 'javelin-behavior', - ), - 'b46d88c5' => array( - 'javelin-install', 'javelin-dom', - 'javelin-util', - 'javelin-stratcom', - 'javelin-workflow', - 'phabricator-draggable-list', - 'javelin-workboard-column', - 'javelin-workboard-header-template', - 'javelin-workboard-card-template', - 'javelin-workboard-order-template', + 'javelin-uri', + 'phabricator-notification', ), - 'b49fd60c' => array( - 'multirow-row-manager', - 'trigger-rule', + 'afe38d96' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-request', + 'javelin-stratcom', + 'javelin-uri', ), - 'b517bfa0' => array( - 'phui-oi-list-view-css', + 'b04c258c' => array( + 'javelin-install', ), - 'b545d0a0' => array( + 'b105a3a6' => array( 'javelin-behavior', - 'javelin-util', - 'javelin-dom', 'javelin-stratcom', - 'javelin-vector', + 'javelin-dom', ), - 'b557770a' => array( + 'b4afcd89' => array( 'javelin-install', - 'javelin-util', 'javelin-dom', - 'javelin-vector', - 'javelin-stratcom', + ), + 'b517bfa0' => array( + 'phui-oi-list-view-css', ), 'b58d1a2a' => array( 'javelin-behavior', @@ -1877,6 +1985,10 @@ return array( 'javelin-stratcom', 'javelin-dom', ), + 'b6bafedf' => array( + 'javelin-install', + 'javelin-typeahead-source', + ), 'b748c1de' => array( 'phui-theme-css', ), @@ -1886,14 +1998,29 @@ return array( 'javelin-util', 'phabricator-shaped-request', ), - 'b86ef6c2' => array( + 'b7bd4fb1' => array( 'javelin-behavior', 'javelin-dom', + 'javelin-uri', + 'javelin-mask', 'javelin-stratcom', - 'phabricator-tooltip', - 'phabricator-diff-changeset-list', - 'phabricator-diff-changeset', - 'phuix-formation-view', + 'javelin-workflow', + 'phabricator-drag-and-drop-file-upload', + ), + 'b82fc780' => array( + 'javelin-install', + 'javelin-dom', + 'javelin-stratcom', + ), + 'b852b68e' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-quicksand', + 'javelin-sound', + 'javelin-stratcom', + 'javelin-workboard-controller', + 'javelin-workboard-drop-effect', + 'phuix-dropdown-menu', ), 'b86f297f' => array( 'javelin-behavior', @@ -1907,30 +2034,57 @@ return array( 'javelin-uri', 'phabricator-notification', ), - 'c2c500a7' => array( + 'bcb07115' => array( 'javelin-install', 'javelin-dom', - 'phuix-button-view', + 'phabricator-notification', ), - 'c3703a16' => array( - 'javelin-behavior', - 'javelin-aphlict', - 'phabricator-phtize', - 'javelin-dom', + 'bdc40a6b' => array( + 'javelin-install', + 'javelin-util', + 'javelin-request', + 'javelin-router', ), - 'c3d24e63' => array( + 'beca9a7a' => array( 'javelin-install', - 'javelin-workboard-card', - 'javelin-workboard-header', + 'javelin-util', + 'phabricator-keyboard-shortcut-manager', + ), + 'c2129f37' => array( + 'javelin-install', + 'javelin-dom', + 'javelin-typeahead-preloaded-source', + 'javelin-util', + ), + 'c3ea5759' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-chart', + 'javelin-request', ), 'c44f95c7' => array( 'phui-workcard-view-css', ), + 'c51e6aa0' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-request', + ), 'c538cbfc' => array( 'javelin-behavior', 'javelin-stratcom', 'javelin-dom', ), + 'c5a9b42b' => array( + 'javelin-install', + 'javelin-dom', + 'javelin-vector', + 'javelin-request', + 'javelin-uri', + 'javelin-util', + 'javelin-json', + 'phui-hovercard', + ), 'c60fb44a' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1944,9 +2098,8 @@ return array( 'javelin-fx', 'javelin-util', ), - 'c68f183f' => array( + 'c6d00cb9' => array( 'javelin-install', - 'javelin-dom', ), 'c715c123' => array( 'javelin-behavior', @@ -1955,122 +2108,142 @@ return array( 'javelin-workflow', 'javelin-json', ), - 'cc1553f3' => array( - 'javelin-stratcom', - 'javelin-request', - 'javelin-dom', - 'javelin-vector', + 'c74a690a' => array( 'javelin-install', + 'javelin-dom', + 'javelin-stratcom', 'javelin-util', - 'javelin-mask', - 'javelin-uri', - 'javelin-routable', - ), - 'cc2c5de5' => array( - 'javelin-install', - 'phuix-button-view', - 'phabricator-diff-tree-view', - ), - 'ce6f8e3d' => array( - 'phui-chart-css', - 'd3', - 'javelin-chart-curtain-view', - 'javelin-chart-function-label', + 'javelin-workboard-card', + 'javelin-workboard-header', ), - 'cef53b3e' => array( + 'c967b0e7' => array( 'javelin-install', 'javelin-dom', + 'javelin-magical-init', + 'javelin-util', + 'javelin-stratcom', + 'javelin-vector', 'phuix-formation-column-view', 'phuix-formation-flank-view', ), - 'cf26eaab' => array( - 'javelin-install', + 'cd00e3d4' => array( + 'javelin-behavior', 'javelin-dom', - 'phuix-icon-view', - 'phabricator-prefab', + 'javelin-typeahead', + 'javelin-typeahead-static-source', ), - 'd12d214f' => array( + 'ce39158d' => array( 'javelin-install', - 'javelin-dom', - 'javelin-json', - 'javelin-workflow', + 'javelin-typeahead-source', 'javelin-util', ), - 'd3799cb4' => array( - 'javelin-install', - ), - 'd4cc2d2a' => array( + 'cf6b743b' => array( 'javelin-install', - ), - 'd7d3ba75' => array( 'javelin-dom', + 'javelin-stratcom', 'javelin-util', + 'javelin-uri', + 'phabricator-notification-css', + ), + 'd3115244' => array( + 'javelin-behavior', + 'javelin-dom', 'javelin-stratcom', - 'javelin-install', - 'javelin-workflow', - 'javelin-router', - 'javelin-behavior-device', 'javelin-vector', - 'phabricator-diff-inline', - 'phabricator-diff-path-view', - 'phuix-button-view', - 'javelin-external-editor-link-engine', + 'javelin-uri', + 'javelin-request', ), - 'd8a86cfb' => array( + 'd336267a' => array( 'javelin-behavior', 'javelin-dom', + 'javelin-magical-init', + 'javelin-stratcom', + 'javelin-util', + ), + 'd8a27e0d' => array( + 'javelin-install', + ), + 'd9979d19' => array( + 'javelin-install', 'javelin-util', - 'phabricator-shaped-request', ), 'da15d3dc' => array( 'phui-oi-list-view-css', ), - 'da8f5259' => array( + 'da402bda' => array( 'javelin-behavior', + 'javelin-aphlict', + 'phabricator-phtize', 'javelin-dom', + 'phuix-icon-view', ), - 'daceb29a' => array( + 'e10d1263' => array( 'javelin-behavior', 'javelin-stratcom', 'javelin-dom', - 'phabricator-phtize', - 'phabricator-textareautils', - 'phabricator-remarkup-metadata', 'javelin-workflow', - 'javelin-vector', - 'phuix-autocomplete', - 'javelin-mask', + 'javelin-quicksand', + 'phabricator-phtize', + 'phabricator-drag-and-drop-file-upload', + 'phabricator-draggable-list', + 'phabricator-file-upload', ), - 'dae2d55b' => array( - 'javelin-behavior', - 'javelin-uri', - 'phabricator-notification', + 'e342e2b4' => array( + 'javelin-install', + 'javelin-dom', + 'phuix-icon-view', ), - 'de4b4919' => array( + 'e44abfd6' => array( + 'multirow-row-manager', 'javelin-install', + 'path-typeahead', 'javelin-dom', - 'javelin-vector', - 'javelin-request', - 'javelin-uri', - 'phui-hovercard', + 'javelin-util', + 'phabricator-prefab', + 'phuix-form-control-view', + ), + 'e47745d1' => array( + 'javelin-install', + 'javelin-reactornode', + 'javelin-util', + 'javelin-reactor', ), - 'e150bd50' => array( + 'e5bdb730' => array( 'javelin-behavior', 'javelin-stratcom', + 'javelin-workflow', 'javelin-dom', - 'phuix-dropdown-menu', + 'phabricator-draggable-list', + ), + 'e5e044e8' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-magical-init', + 'javelin-stratcom', + 'javelin-uri', ), - 'e40c4991' => array( + 'e63ab0ec' => array( 'javelin-install', 'javelin-dom', - 'javelin-json', ), - 'e5bdb730' => array( + 'e6bc2ced' => array( + 'trigger-rule-control', + 'javelin-install', + ), + 'e9592389' => array( 'javelin-behavior', + 'javelin-util', 'javelin-stratcom', - 'javelin-workflow', 'javelin-dom', - 'phabricator-draggable-list', + 'javelin-vector', + 'javelin-magical-init', + 'javelin-request', + 'javelin-history', + 'javelin-workflow', + 'javelin-mask', + 'javelin-behavior-device', + 'javelin-quicksand', + 'phabricator-keyboard-shortcut', ), 'e9a2940f' => array( 'javelin-behavior', @@ -2083,58 +2256,76 @@ return array( 'phabricator-title', 'phabricator-favicon', ), - 'e9c80beb' => array( + 'eac68b41' => array( + 'javelin-dom', + 'javelin-dynval', + 'javelin-reactor', + 'javelin-reactornode', 'javelin-install', - 'javelin-event', + 'javelin-util', ), - 'ebe83a6b' => array( + 'ec0c35b0' => array( 'javelin-install', + 'javelin-dom', + 'javelin-fx', ), 'ec4e31c0' => array( 'phui-timeline-view-css', ), - 'f340a484' => array( - 'javelin-install', + 'ef0160d8' => array( 'javelin-dom', - 'javelin-vector', + 'javelin-install', ), - 'f782e983' => array( - 'javelin-behavior', - 'javelin-typeahead-ondemand-source', - 'javelin-typeahead', + 'f27ca8c5' => array( + 'javelin-install', 'javelin-dom', - 'javelin-uri', 'javelin-util', - 'javelin-stratcom', 'phabricator-prefab', - 'phuix-icon-view', ), - 'f84bcbf4' => array( + 'f2977446' => array( + 'javelin-install', + 'javelin-util', + ), + 'f29b7914' => array( 'javelin-behavior', + 'javelin-behavior-device', 'javelin-stratcom', - 'javelin-dom', + 'phui-hovercard-list', ), - 'f8c4e135' => array( - 'javelin-install', + 'f5bba944' => array( + 'javelin-behavior', 'javelin-dom', - 'javelin-view-visitor', + 'javelin-stratcom', + 'javelin-uri', 'javelin-util', ), - 'fa6f30b2' => array( + 'f941cb00' => array( 'javelin-behavior', - 'javelin-dom', 'javelin-stratcom', - 'javelin-behavior-device', - 'javelin-scrollbar', - 'javelin-quicksand', - 'phabricator-keyboard-shortcut', - 'conpherence-thread-manager', + 'javelin-dom', + 'javelin-vector', + 'javelin-install', + ), + 'f9d95e77' => array( + 'javelin-install', ), 'fa74cc35' => array( 'phui-oi-list-view-css', ), - 'fdc13e4e' => array( + 'fabc70ac' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-quicksand', + 'javelin-stratcom', + 'phabricator-tooltip', + 'phabricator-phtize', + 'phabricator-diff-changeset-list', + 'phuix-formation-view', + ), + 'fe7cdb3b' => array( 'javelin-install', + 'javelin-dom', + 'javelin-json', ), 'ff688a7a' => array( 'owners-path-editor', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 0bede17d76..5fdf388831 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1726,6 +1726,8 @@ phutil_register_library_map(array( 'HeraldWebhookViewController' => 'applications/herald/controller/HeraldWebhookViewController.php', 'HeraldWebhookWorker' => 'applications/herald/worker/HeraldWebhookWorker.php', 'Javelin' => 'infrastructure/javelin/Javelin.php', + 'JavelinCelerityTestResources' => 'infrastructure/lint/linter/__tests__/JavelinCelerityTestResources.php', + 'JavelinPeastLibrary' => 'infrastructure/javelin/JavelinPeastLibrary.php', 'LegalpadController' => 'applications/legalpad/controller/LegalpadController.php', 'LegalpadCreateDocumentsCapability' => 'applications/legalpad/capability/LegalpadCreateDocumentsCapability.php', 'LegalpadDAO' => 'applications/legalpad/storage/LegalpadDAO.php', @@ -3676,6 +3678,7 @@ phutil_register_library_map(array( 'PhabricatorJSONDocumentEngine' => 'applications/files/document/PhabricatorJSONDocumentEngine.php', 'PhabricatorJSONExportFormat' => 'infrastructure/export/format/PhabricatorJSONExportFormat.php', 'PhabricatorJavelinLinter' => 'infrastructure/lint/linter/PhabricatorJavelinLinter.php', + 'PhabricatorJavelinLinterTestCase' => 'infrastructure/lint/linter/__tests__/PhabricatorJavelinLinterTestCase.php', 'PhabricatorJiraIssueHasObjectEdgeType' => 'applications/doorkeeper/edge/PhabricatorJiraIssueHasObjectEdgeType.php', 'PhabricatorJupyterDocumentEngine' => 'applications/files/document/PhabricatorJupyterDocumentEngine.php', 'PhabricatorKeyValueDatabaseCache' => 'applications/cache/PhabricatorKeyValueDatabaseCache.php', @@ -7959,6 +7962,8 @@ phutil_register_library_map(array( 'HeraldWebhookViewController' => 'HeraldWebhookController', 'HeraldWebhookWorker' => 'PhabricatorWorker', 'Javelin' => 'Phobject', + 'JavelinCelerityTestResources' => 'CelerityResourcesOnDisk', + 'JavelinPeastLibrary' => 'Phobject', 'LegalpadController' => 'PhabricatorController', 'LegalpadCreateDocumentsCapability' => 'PhabricatorPolicyCapability', 'LegalpadDAO' => 'PhabricatorLiskDAO', @@ -10209,6 +10214,7 @@ phutil_register_library_map(array( 'PhabricatorJSONDocumentEngine' => 'PhabricatorTextDocumentEngine', 'PhabricatorJSONExportFormat' => 'PhabricatorExportFormat', 'PhabricatorJavelinLinter' => 'ArcanistLinter', + 'PhabricatorJavelinLinterTestCase' => 'ArcanistLinterTestCase', 'PhabricatorJiraIssueHasObjectEdgeType' => 'PhabricatorEdgeType', 'PhabricatorJupyterDocumentEngine' => 'PhabricatorDocumentEngine', 'PhabricatorKeyValueDatabaseCache' => 'PhutilKeyValueCache', diff --git a/src/infrastructure/javelin/JavelinPeastLibrary.php b/src/infrastructure/javelin/JavelinPeastLibrary.php new file mode 100644 index 0000000000..5f2b39eec6 --- /dev/null +++ b/src/infrastructure/javelin/JavelinPeastLibrary.php @@ -0,0 +1,224 @@ +setDownloadPath($path) + ->resolvex(); + + $actual_md5 = md5_file($path); + + if (!in_array($actual_md5, self::$hashes, true)) { + $expected = implode(', ', self::$hashes); + + throw new Exception( + "Peast hash does not match: expected any of {$expected}". + ", got {$actual_md5}."); + } + + return $path; + } + + public static function build() { + $root = phutil_get_library_root('phorge'); + $path = Filesystem::resolvePath($root.'/../support/peast'); + $target = self::getPath(); + $version = self::EXPECTED_VERSION; + + if (extension_loaded('zip')) { + $download_path = self::downloadPeast($path, '.zip'); + + $zip = new ZipArchive(); + $result = $zip->open($download_path); + if (!$result) { + throw new Exception( + pht( + 'Opening %s failed! %s.', + $download_path, + $result === false ? 'Unknown Error' : (string)$result)); + } + + $zip->extractTo($target); + + // Renames fail if the target directory exists. + Filesystem::remove("{$target}/Peast"); + + Filesystem::rename( + "{$target}/peast-{$version}/lib/Peast", + "{$target}/Peast"); + + Filesystem::remove("{$target}/peast-{$version}"); + } else if ( + extension_loaded('phar') && + extension_loaded('zlib')) { + + $download_path = self::downloadPeast($path, '.tar.gz'); + + id(new PharData($download_path))->extractTo($target, null, true); + + // Renames fail if the target directory exists. + Filesystem::remove("{$target}/Peast"); + + Filesystem::rename( + "{$target}/peast-{$version}/lib/Peast", + "{$target}/Peast"); + + Filesystem::remove("{$target}/peast-{$version}"); + } else if (Filesystem::binaryExists('git')) { + execx( + 'git clone --single-branch --depth 1 --branch %s %s %s', + 'v'.self::EXPECTED_VERSION, + self::REPO, + $path.'/git'); + + // Renames fail if the target directory exists. + Filesystem::remove("{$path}/Peast"); + + Filesystem::rename( + "{$path}/git/lib/Peast", + "{$path}/Peast"); + + Filesystem::remove($path.'/git'); + } else { + throw new Exception( + pht('No viable means to download Peast is available.')); + } + + Filesystem::writeFile($target.'/version', $version); + } + + /** + * Returns human-readable instructions for building PHP-parser. + * + * @return string + */ + public static function getBuildInstructions() { + $root = phutil_get_library_root('phorge'); + $script = Filesystem::resolvePath( + $root.'/../support/peast/build-peast.php'); + + return phutil_console_format( + "%s:\n\n \$ %s\n", + pht( + "Your version of '%s' is unbuilt or out of date. Run this ". + "script to build it.", + 'peast'), + $script); + } + + private static function peastAutoloader($classname) { + $lib = self::getPath(); + + if (strncmp($classname, 'Peast', 5)) { + return false; + } + + $path = $lib.'/'.str_replace('\\', '/', $classname).'.php'; + + if (!Filesystem::pathExists($path)) { + return false; + } + + require $path; + + return true; + } + + public static function loadLibrary() { + static $loaded = false; + + if (!$loaded) { + if (!self::isAvailable()) { + try { + self::build(); + } catch (Throwable $ex) { + throw new Exception(self::getBuildInstructions(), 0, $ex); + } + } + + spl_autoload_register('JavelinPeastLibrary::peastAutoloader'); + } + } + + /** + * Returns the path to the Peast library. + * + * @return string + */ + public static function getPath() { + static $path = null; + + if (!$path) { + $root = phutil_get_library_root('phorge'); + $path = Filesystem::resolvePath($root.'/../support/peast/lib'); + } + + return $path; + } + + /** + * Returns the Peast version. + * + * @return string + */ + public static function getVersion() { + if (self::$version === null) { + $lib = self::getPath(); + + if (Filesystem::pathExists($lib.'/version')) { + self::$version = trim(Filesystem::readFile($lib.'/version')); + } + } + + return self::$version; + } + + /** + * Checks if PHP-parser is built and up-to-date. + * + * @return bool + */ + public static function isAvailable() { + $version = self::getVersion(); + return $version === self::EXPECTED_VERSION; + } + +} diff --git a/src/infrastructure/lint/linter/PhabricatorJavelinLinter.php b/src/infrastructure/lint/linter/PhabricatorJavelinLinter.php index cb03b13d27..560cf8c45c 100644 --- a/src/infrastructure/lint/linter/PhabricatorJavelinLinter.php +++ b/src/infrastructure/lint/linter/PhabricatorJavelinLinter.php @@ -1,17 +1,26 @@ symbolsBinary === null) { - list($err, $stdout) = exec_manual('which javelinsymbols'); - $this->symbolsBinary = ($err ? false : rtrim($stdout)); - } - return $this->symbolsBinary; + /** + * @internal Enables overrides for unit tests. + * + * @param bool $unit_tests + * @return $this + */ + public function enableUnitTestOverrides(bool $unit_tests) { + $this->unitTestMode = $unit_tests; + return $this; } public function willLintPaths(array $paths) { - if (!$this->getBinaryPath()) { - return; - } - $root = dirname(phutil_get_library_root('phabricator')); require_once $root.'/scripts/__init_script__.php'; - $futures = array(); - foreach ($paths as $path) { - if ($this->shouldIgnorePath($path)) { - continue; - } - - $future = $this->newSymbolsFuture($path); - $futures[$path] = $future; - } - - foreach (id(new FutureIterator($futures))->limit(8) as $path => $future) { - $this->symbols[$path] = $future->resolvex(); - } + JavelinPeastLibrary::loadLibrary(); } public function getLinterName() { @@ -63,12 +58,6 @@ final class PhabricatorJavelinLinter extends ArcanistLinter { return 'javelin'; } - public function getLintSeverityMap() { - return array( - self::LINT_MISSING_BINARY => ArcanistLintSeverity::SEVERITY_WARNING, - ); - } - public function getLintNameMap() { return array( self::LINT_PRIVATE_ACCESS => @@ -79,8 +68,10 @@ final class PhabricatorJavelinLinter extends ArcanistLinter { pht('Unnecessary Javelin Dependency'), self::LINT_UNKNOWN_DEPENDENCY => pht('Unknown Javelin Dependency'), - self::LINT_MISSING_BINARY => - pht('`%s` Not In Path', 'javelinsymbols'), + self::LINT_UNDOCUMENTED_INSTALL => + pht('Undocumented Install'), + self::LINT_UNINSTALLED_DOCUMENTATION => + pht('Uninstalled Documentation'), ); } @@ -90,9 +81,8 @@ final class PhabricatorJavelinLinter extends ArcanistLinter { public function getCacheVersion() { $version = '0'; - $binary_path = $this->getBinaryPath(); - if ($binary_path) { - $version .= '-'.md5_file($binary_path); + if (JavelinPeastLibrary::isAvailable()) { + $version .= '-'.JavelinPeastLibrary::getVersion(); } return $version; } @@ -106,27 +96,8 @@ final class PhabricatorJavelinLinter extends ArcanistLinter { return; } - if (!$this->symbolsBinary) { - if (!$this->haveWarnedAboutBinary) { - $this->haveWarnedAboutBinary = true; - // TODO: Write build documentation for the Javelin binaries and point - // the user at it. See also https://we.phorge.it/T15123 and - // https://we.phorge.it/T15669 - $this->raiseLintAtLine( - 1, - 0, - self::LINT_MISSING_BINARY, - pht( - "The '%s' binary in the Javelin project is not available in %s, ". - "so the Javelin linter can't run. This isn't a big concern, ". - "but means some Javelin problems can't be automatically detected.", - 'javelinsymbols', - '$PATH')); - } - return; - } - - list($uses, $installs) = $this->getUsedAndInstalledSymbolsForPath($path); + $symbols = $this->getUsedAndInstalledSymbolsForPath($path); + list($uses, $installs, $documented_installs) = $symbols; foreach ($uses as $symbol => $line) { $parts = explode('.', $symbol); foreach ($parts as $part) { @@ -148,6 +119,29 @@ final class PhabricatorJavelinLinter extends ArcanistLinter { } } + $undeclared_installs = array_diff_key($installs, $documented_installs); + foreach ($undeclared_installs as $name => $line) { + $this->raiseLintAtLine( + $line, + 0, + self::LINT_UNDOCUMENTED_INSTALL, + pht( + "This file installs component '%s', but does not document it.", + $name)); + } + + $uninstalled_declares = array_diff_key($documented_installs, $installs); + foreach ($uninstalled_declares as $name => $line) { + $this->raiseLintAtLine( + $line, + 0, + self::LINT_UNINSTALLED_DOCUMENTATION, + pht( + "This file %s component '%s', but does not actually install it.", + '@javelin-installs', + $name)); + } + $external_classes = array(); foreach ($uses as $symbol => $line) { $parts = explode('.', $symbol); @@ -158,7 +152,13 @@ final class PhabricatorJavelinLinter extends ArcanistLinter { } } - $celerity = CelerityResourceMap::getNamedInstance('phabricator'); + if ($this->unitTestMode) { + $resources = id(new JavelinCelerityTestResources()) + ->wrap(new CelerityPhabricatorResources()); + $celerity = new CelerityResourceMap($resources); + } else { + $celerity = CelerityResourceMap::getNamedInstance('phabricator'); + } $path = preg_replace( '@^externals/javelinjs/src/@', @@ -166,7 +166,12 @@ final class PhabricatorJavelinLinter extends ArcanistLinter { $path); $need = $external_classes; - $resource_name = substr($path, strlen('webroot/')); + if (!strncmp($path, 'webroot/', 8)) { + $resource_name = substr($path, strlen('webroot/')); + } else { + $resource_name = $path; + } + $requires = $celerity->getRequiredSymbolsForName($resource_name); if (!$requires) { $requires = array(); @@ -176,7 +181,7 @@ final class PhabricatorJavelinLinter extends ArcanistLinter { $requires_name = $celerity->getResourceNameForSymbol($requires_symbol); if ($requires_name === null) { $this->raiseLintAtLine( - 0, + 1, 0, self::LINT_UNKNOWN_DEPENDENCY, pht( @@ -193,7 +198,7 @@ final class PhabricatorJavelinLinter extends ArcanistLinter { unset($requires[$key]); } else { $symbol_path = 'webroot/'.$requires_name; - list($ignored, $req_install) = $this->getUsedAndInstalledSymbolsForPath( + list($_, $_, $req_install) = $this->getUsedAndInstalledSymbolsForPath( $symbol_path); if (array_intersect_key($req_install, $external_classes)) { $need = array_diff_key($need, $req_install); @@ -215,7 +220,7 @@ final class PhabricatorJavelinLinter extends ArcanistLinter { foreach ($requires as $component) { $this->raiseLintAtLine( - 0, + 1, 0, self::LINT_UNNECESSARY_DEPENDENCY, pht( @@ -227,49 +232,120 @@ final class PhabricatorJavelinLinter extends ArcanistLinter { private function loadSymbols($path) { if (empty($this->symbols[$path])) { - $this->symbols[$path] = $this->newSymbolsFuture($path)->resolvex(); + $this->symbols[$path] = $this->symbolize($path); } return $this->symbols[$path]; } - private function newSymbolsFuture($path) { - $future = new ExecFuture('javelinsymbols # %s', $path); - $future->write($this->getData($path)); - return $future; - } + private function symbolize(string $path): array { + $installs = array(); + $behaviors = array(); + $uses = array(); + + $source = $this->getData($path); + $ast = Peast\Peast::latest($source)->parse(); + $expressions = $ast + ->query('CallExpression, MemberExpression, AssignmentExpression') + ->getIterator(); + + foreach ($expressions as $expression) { + if ($expression instanceof Peast\Syntax\Node\CallExpression) { + $callee = $expression->getCallee(); + if (!($callee instanceof Peast\Syntax\Node\MemberExpression)) { + continue; + } - private function getUsedAndInstalledSymbolsForPath($path) { - list($symbols) = $this->loadSymbols($path); - $symbols = trim($symbols); - - $uses = array(); - $installs = array(); - if (empty($symbols)) { - // This file has no symbols. - return array($uses, $installs); - } + $member_expression = $this->unnestMemberExpression($callee); + $full_name = $callee->render(new Peast\Formatter\Compact()); + } else if ( + $expression instanceof Peast\Syntax\Node\AssignmentExpression) { + + $left = $expression->getLeft(); + if (!($left instanceof Peast\Syntax\Node\MemberExpression)) { + continue; + } - $symbols = explode("\n", trim($symbols)); - foreach ($symbols as $line) { - $matches = null; - if (!preg_match('/^([?+\*])([^:]*):(\d+)$/', $line, $matches)) { - throw new Exception( - pht('Received malformed output from `%s`.', 'javelinsymbols')); + $member_expression = $this->unnestMemberExpression($left); + $full_name = $left->render(new Peast\Formatter\Compact()); + } else { + $member_expression = $expression; + $full_name = $expression->render(new Peast\Formatter\Compact()); } - $type = $matches[1]; - $symbol = $matches[2]; - $line = $matches[3]; - switch ($type) { - case '?': - $uses[$symbol] = $line; - break; - case '+': - $installs['JX.'.$symbol] = $line; - break; + $object = $member_expression->getObject(); + $property = $member_expression->getProperty(); + + if ( + !($object instanceof Peast\Syntax\Node\Identifier) || + !($property instanceof Peast\Syntax\Node\Identifier) || + // Computed means using indexers ([ & ]). We ignore these. + $member_expression->getComputed()) { + continue; + } + + if ($object->getName() !== 'JX') { + continue; + } + + $property_name = $property->getName(); + $start_line = $expression->getLocation()->getStart()->getLine(); + $end_line = $expression->getLocation()->getEnd()->getLine(); + + if ($expression instanceof Peast\Syntax\Node\AssignmentExpression) { + $installs['JX.'.$property_name] = $end_line; + continue; + } + + $uses[$full_name] = $start_line; + + if ( + !($expression instanceof Peast\Syntax\Node\CallExpression) || + ($property_name !== 'install' && $property_name !== 'behavior')) { + continue; + } + + $arguments = $expression->getArguments(); + if ( + !$arguments || + !($arguments[0] instanceof Peast\Syntax\Node\StringLiteral)) { + continue; } + + $name = $arguments[0]->getValue(); + + if ($property_name === 'install') { + $installs['JX.'.$name] = $end_line; + } else { + $behaviors[$name] = $end_line; + } + } + + return array($installs, $behaviors, $uses); + } + + /** + * Unpacks a MemberExpression to its left-most side. + * MemberExpressions are parsed left to right, but that means the first part + * is the furthest in the tree. + * + * @param Peast\Syntax\Node\MemberExpression $expression + * @return Peast\Syntax\Node\MemberExpression + */ + private function unnestMemberExpression( + Peast\Syntax\Node\MemberExpression $expression) { + + $object = $expression->getObject(); + if ($object instanceof Peast\Syntax\Node\MemberExpression) { + return $this->unnestMemberExpression($object); } + return $expression; + } + + private function getUsedAndInstalledSymbolsForPath($path) { + list($installs, $behaviors, $uses) = $this->loadSymbols($path); + $documented_installs = array(); + $contents = $this->getData($path); $matches = null; @@ -277,15 +353,23 @@ final class PhabricatorJavelinLinter extends ArcanistLinter { '/@javelin-installs\W+(\S+)/', $contents, $matches, - PREG_PATTERN_ORDER); + PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE); if ($count) { - foreach ($matches[1] as $symbol) { - $installs[$symbol] = 0; + $engine = $this->getEngine(); + + if ($this->unitTestMode) { + $engine->addFileData($path, $contents); + } + + foreach ($matches[1] as $match) { + list($symbol, $offset) = $match; + list($line) = $engine->getLineAndCharFromOffset($path, $offset); + $documented_installs[$symbol] = $line + 1; } } - return array($uses, $installs); + return array($uses, $installs, $documented_installs); } } diff --git a/src/infrastructure/lint/linter/__tests__/JavelinCelerityTestResources.php b/src/infrastructure/lint/linter/__tests__/JavelinCelerityTestResources.php new file mode 100644 index 0000000000..853f0b2227 --- /dev/null +++ b/src/infrastructure/lint/linter/__tests__/JavelinCelerityTestResources.php @@ -0,0 +1,50 @@ +wrap = $resources; + return $this; + } + + public function getPathToResources() { + return __DIR__.'/javelin/'; + } + + public function getPathToMap() { + return __DIR__.'/map.php'; + } + + public function loadMap() { + $map = parent::loadMap(); + + if (!$this->wrap) { + return $map; + } + + return array_merge_recursive($map, $this->wrap->loadMap()); + } + + public function getName() { + return 'javelinunittest'; + } + + protected function getTextFileSuffixes() { + return array( + 'lint-test', + ); + } + + public function getResourceData($name) { + $data = parent::getResourceData($name); + + list($data) = preg_split('/^~{4,}\n/m', $data, 2); + + return $data; + } + +} diff --git a/src/infrastructure/lint/linter/__tests__/PhabricatorJavelinLinterTestCase.php b/src/infrastructure/lint/linter/__tests__/PhabricatorJavelinLinterTestCase.php new file mode 100644 index 0000000000..6adfcd50a5 --- /dev/null +++ b/src/infrastructure/lint/linter/__tests__/PhabricatorJavelinLinterTestCase.php @@ -0,0 +1,33 @@ +enableUnitTestOverrides(true); + + $phorge_root = Filesystem::resolvePath( + phutil_get_library_root('phorge').'/../').'/'; + $webroot = 'webroot/rsrc/externals/javelin/'; + + $files = id(new FileFinder($phorge_root.$webroot)) + ->excludePath('*/__tests__/*') + ->excludePath('*/docs/*') + ->withSuffix('js') + ->find(); + + foreach ($files as $file) { + $data = Filesystem::readFile($phorge_root.$webroot.$file); + $linter->addData( + $webroot.$file, + $data); + } + + return $linter; + } + + public function testLinter() { + $this->executeTestsInDirectory(__DIR__.'/javelin/'); + } + +} diff --git a/src/infrastructure/lint/linter/__tests__/javelin/missing-dependency.lint-test b/src/infrastructure/lint/linter/__tests__/javelin/missing-dependency.lint-test new file mode 100644 index 0000000000..57320ba5cb --- /dev/null +++ b/src/infrastructure/lint/linter/__tests__/javelin/missing-dependency.lint-test @@ -0,0 +1,22 @@ +/** + * @requires javelin-install + * @provides javelin-test + * + * @javelin-installs JX.Test + * + * @javelin + */ + +JX.install('Test', { + + statics : { + + test: function (wild) { + alert(JX.JSON(wild)); + } + + } + +}); +~~~~~~~~~~ +error:15:0:JAVELIN2 diff --git a/src/infrastructure/lint/linter/__tests__/javelin/private-access.lint-test b/src/infrastructure/lint/linter/__tests__/javelin/private-access.lint-test new file mode 100644 index 0000000000..49ad64a068 --- /dev/null +++ b/src/infrastructure/lint/linter/__tests__/javelin/private-access.lint-test @@ -0,0 +1,23 @@ +/** + * @requires javelin-install + * javelin-history + * @provides javelin-test + * + * @javelin-installs JX.Test + * + * @javelin + */ + +JX.install('Test', { + + statics : { + + test: function (wild) { + JX.History._fire('/', wild); + } + + } + +}); +~~~~~~~~~~ +error:16:0:JAVELIN1 diff --git a/src/infrastructure/lint/linter/__tests__/javelin/undocumented-install.lint-test b/src/infrastructure/lint/linter/__tests__/javelin/undocumented-install.lint-test new file mode 100644 index 0000000000..7c28ff0e66 --- /dev/null +++ b/src/infrastructure/lint/linter/__tests__/javelin/undocumented-install.lint-test @@ -0,0 +1,13 @@ +/** + * @requires javelin-install + * @provides javelin-test + * + * @javelin-installs JX.Test + * + * @javelin + */ + +JX.install('Test', {}); +JX.install('Test2', {}); +~~~~~~~~~~ +error:11:0:JAVELIN6 diff --git a/src/infrastructure/lint/linter/__tests__/javelin/uninstalled-documentation.lint-test b/src/infrastructure/lint/linter/__tests__/javelin/uninstalled-documentation.lint-test new file mode 100644 index 0000000000..693502f92d --- /dev/null +++ b/src/infrastructure/lint/linter/__tests__/javelin/uninstalled-documentation.lint-test @@ -0,0 +1,13 @@ +/** + * @requires javelin-install + * @provides javelin-test + * + * @javelin-installs JX.Test + * @javelin-installs JX.Test2 + * + * @javelin + */ + +JX.install('Test', {}); +~~~~~~~~~~ +error:6:0:JAVELIN7 diff --git a/src/infrastructure/lint/linter/__tests__/javelin/unknown-dependency.lint-test b/src/infrastructure/lint/linter/__tests__/javelin/unknown-dependency.lint-test new file mode 100644 index 0000000000..5acdcd117b --- /dev/null +++ b/src/infrastructure/lint/linter/__tests__/javelin/unknown-dependency.lint-test @@ -0,0 +1,13 @@ +/** + * @requires javelin-install + * javelin-does-not-exist + * @provides javelin-test + * + * @javelin-installs JX.Test + * + * @javelin + */ + +JX.install('Test', {}); +~~~~~~~~~~ +error:1:0:JAVELIN4 diff --git a/src/infrastructure/lint/linter/__tests__/javelin/unnecessary-dependency.lint-test b/src/infrastructure/lint/linter/__tests__/javelin/unnecessary-dependency.lint-test new file mode 100644 index 0000000000..c7bf4a198f --- /dev/null +++ b/src/infrastructure/lint/linter/__tests__/javelin/unnecessary-dependency.lint-test @@ -0,0 +1,13 @@ +/** + * @requires javelin-install + * javelin-workflow + * @provides javelin-test + * + * @javelin-installs JX.Test + * + * @javelin + */ + +JX.install('Test', {}); +~~~~~~~~~~ +error:1:0:JAVELIN3 diff --git a/src/infrastructure/lint/linter/__tests__/map.php b/src/infrastructure/lint/linter/__tests__/map.php new file mode 100644 index 0000000000..d0a99e3017 --- /dev/null +++ b/src/infrastructure/lint/linter/__tests__/map.php @@ -0,0 +1,44 @@ + array( + 'missing-dependency.lint-test' => '3f966f42', + 'private-access.lint-test' => 'fa831308', + 'undocumented-install.lint-test' => 'e575f333', + 'uninstalled-documentation.lint-test' => '9b61fd26', + 'unknown-dependency.lint-test' => 'abc533df', + 'unnecessary-dependency.lint-test' => '1608e0c1', + ), + 'symbols' => array( + 'javelin-test' => 'e575f333', + ), + 'requires' => array( + '1608e0c1' => array( + 'javelin-install', + 'javelin-workflow', + ), + '3f966f42' => array( + 'javelin-install', + ), + '9b61fd26' => array( + 'javelin-install', + ), + 'abc533df' => array( + 'javelin-install', + 'javelin-does-not-exist', + ), + 'e575f333' => array( + 'javelin-install', + ), + 'fa831308' => array( + 'javelin-install', + 'javelin-history', + ), + ), + 'packages' => array(), +); diff --git a/support/peast/build-peast.php b/support/peast/build-peast.php new file mode 100755 index 0000000000..e1169a5045 --- /dev/null +++ b/support/peast/build-peast.php @@ -0,0 +1,9 @@ +#!/usr/bin/env php +